天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 74|回复: 0

使用 ObjectARX 将 acDb3DSolid 转换为 AcDbPolyFaceMesh

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
使用 ObjectARX 将 acDb3DSolid 转换为 AcDbPolyFaceMesh
问:任务是获取基于 AcDb3DSolid 的 AcDbPolyFaceMesh 网络。如何做到这一点?

答:下面是允许您执行此操作的代码。AcBrMesh2dControl 设置可能存在变化,该设置决定了网络在多大程度上遵循实体的轮廓以及哪些元素将成为该网络的核心。

//-----------------------------------------------------------------------------
//----- acrxEntryPoint.cpp
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "resource.h"

//-----------------------------------------------------------------------------
#define szRDS _RXST("")

//-----------------------------------------------------------------------------
//----- ObjectARX EntryPoint
class CMy3DSolidToPolyMeshApp : public AcRxArxApp {

public:
  CMy3DSolidToPolyMeshApp () : AcRxArxApp () {}

  virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
    AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
    return (retCode) ;
  }

  virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
    AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
    return (retCode) ;
  }

  virtual void RegisterServerComponents () {   }

  static void Rivilis3DSolidToPolyMesh () {

    ads_name en; ads_point p;

    if (acedEntSel(_T("\nВыберите твердое тело: "), en, p) != RTNORM)
      return;

    AcDbObjectId eid;
    if (acdbGetObjectId(eid, en) != Acad::eOk)
      return;

    AcDbObjectPointer<AcDb3dSolid> p3DSolid(eid, AcDb::kForRead);
    if (p3DSolid.openStatus() == Acad::eWrongObjectType) {
      acutPrintf(_T("\nЭто не твердое тело!"));
      return;
    }

    AcDbExtents ext; p3DSolid->getGeomExtents(ext);
    double length = ext.minPoint().distanceTo(ext.maxPoint());

    AcBrBrep brp;

    AcBr::ErrorStatus ebr;
    ebr = brp.set(*p3DSolid);
    if (ebr != AcBr::eOk) {
      acutPrintf(_T("\nОшибка br.set(*p3DSolid) = %d"), ebr);
      return;
    }

    AcBrMesh2dControl mc;
    // Задаём максимальное расстояние между узлами
    // mc.setMaxNodeSpacing( length / 100.0);
    // Задаём максимальное количество элементов в сети.
    // mc.setMaxSubdivisions(100000);
    // Задаём максимальное отклонение точки
    mc.setDistTol(length / 100.0);
    // Задаём тип элементов - только треугольники
    mc.setElementShape(AcBr::kAllTriangles);

    AcBrMesh2dFilter mf;
    const AcBrEntity* meshEnt = (AcBrEntity*)&brp;
    mf.insert(make_pair(meshEnt, mc));
    AcBrMesh2d brepMesh;
    if ((ebr = brepMesh.generate(mf)) != AcBr::eOk) {
      acutPrintf(_T("\n Ошибка в AcBrMesh2d::generate %d"), ebr);
      return;
    }

    AcDbObjectPointer<AcDbPolyFaceMesh> pMesh; pMesh.create();
    pMesh->setDatabaseDefaults();
    pMesh->setColorIndex(2); // Пусть сеть будет желтая
    AcDbBlockTableRecordPointer pBtr(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
    if (pBtr.openStatus() != Acad::eOk)
      return;
    pBtr->appendAcDbEntity(pMesh);

    int v0 = 0, v1 = 0, v2 = 0, v3 = 0;

    int iter = 0;
    AcGePoint3dArray vertexLookup;
    vertexLookup.setPhysicalLength(10000);
    // Чтобы пропустить нулевой элемент
    vertexLookup.append(AcGePoint3d::kOrigin);

    AcBrMesh2dElement2dTraverser meshElemTrav;

    for (ebr = meshElemTrav.setMesh(brepMesh); !meshElemTrav.done(); ebr = meshElemTrav.next()) {
      if (ebr != AcBr::eOk) return;
      AcBrElement2d e;   ebr = meshElemTrav.getElement(e);
      AcBrElement2dNodeTraverser elemNodeTrav;
      for (ebr = elemNodeTrav.setElement(e) ; !elemNodeTrav.done(); elemNodeTrav.next())  {
        AcBrNode n;
        ebr = elemNodeTrav.getNode(n);
        AcGePoint3d p; n.getPoint(p);
        if (!vertexLookup.contains(p)) {
          AcDbObjectPointer<AcDbPolyFaceMeshVertex> pMeshVert;  pMeshVert.create();
          pMeshVert->setPosition(p);
          pMesh->appendVertex(pMeshVert);
          vertexLookup.append(p);
        }
      }
    }

    for (ebr = meshElemTrav.setMesh(brepMesh); !meshElemTrav.done(); ebr = meshElemTrav.next()) {
      if (ebr != AcBr::eOk) return;
      AcBrElement2d e;   ebr = meshElemTrav.getElement(e);
      AcBrElement2dNodeTraverser elemNodeTrav;

      AcGePoint3dArray pts;

      for (ebr = elemNodeTrav.setElement(e) ; !elemNodeTrav.done(); ebr = elemNodeTrav.next())  {
        if (ebr != AcBr::eOk) return;
        AcBrNode n;
        ebr = elemNodeTrav.getNode(n);
        AcGePoint3d p; n.getPoint(p);
        pts.append(p);
      }

      v0 = v1 = v2 = v3 = 0;
      vertexLookup.find(pts[0],v0);
      vertexLookup.find(pts[1],v1);
      vertexLookup.find(pts[2],v2);
      if (pts.length() == 4)   {
        vertexLookup.find(pts[3],v3);
      }

      AcDbFaceRecord *pFaceRecord = new AcDbFaceRecord(v0, v1, v2, v3);
      pMesh->appendFaceRecord(pFaceRecord);
      pFaceRecord->close();
    }
  }
} ;

//-----------------------------------------------------------------------------
IMPLEMENT_ARX_ENTRYPOINT(CMy3DSolidToPolyMeshApp)

ACED_ARXCOMMAND_ENTRY_AUTO(CMy3DSolidToPolyMeshApp, Rivilis, 3DSolidToPolyMesh, 3DSolidToPolyMesh, ACRX_CMD_MODAL, NULL)

 

 

 

 

使用 ObjectARX 将 acDb3DSolid 转换为 AcDbPolyFaceMesh
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 12:32 , Processed in 0.165074 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表