ADN Open CIS
Сообщество программистов Autodesk в СНГ

26/01/2015

Просмотр нормалей к граням сети

Недавно я получил чертеж от одного из программистов, который содержал сеть (SubDMesh), созданную при помощи кода, использующего информацию о вершинах и гранях. В таких сетях нормали к граням зависят от порядка вершин, определяющих грани, так что нужно было убедиться, что с нормалями всё в порядке.

В этом случае желательно было увидеть нормали к сети. Следующий код показывает как это сделать:

Код - C++: [Выделить]
  1. Acad::ErrorStatus es;
  2.  
  3.  ads_name name;
  4.  AcGePoint3d pt;
  5.  
  6.  int  ret = acedEntSel(_T("\nВыберите сеть (SubDMesh): " ), name, asDblArray(pt));
  7.  
  8.  if  (ret != RTNORM)
  9.  {
  10.         acutPrintf(_T("\nНичего не выбрано" ));
  11.         return ;
  12.  }
  13.  
  14.  AcDbObjectId id;
  15.  acdbGetObjectId(id, name);
  16.  
  17.  if  (id.objectClass() != AcDbSubDMesh::desc())
  18.  {
  19.         acutPrintf(_T("\nВыбрана не сеть (SubDMesh)" ));
  20.         return ;
  21.  }
  22.  
  23.  AcDbObjectPointer<AcDbSubDMesh> mesh(id, AcDb::kForRead);
  24.  
  25.  AcDbFullSubentPathArray subentPaths;
  26.  es = mesh->getSubentPath(-1, kFaceSubentType, subentPaths);
  27.  
  28.  AcGePoint3dArray vertices;
  29.  es = mesh->getSubDividedVertices(vertices);
  30.  
  31.  AcArray<Adesk::Int32> faceInfo;
  32.  es = mesh->getSubDividedFaceArray(faceInfo);
  33.  
  34.  // Содердимое списка граней имеет вид:
  35.  // [Число вершин в следующей грани],
  36.  // <ИндексВершины1, ИндексВершины2, и т.д.>,
  37.  // т.е. [4], <1, 2, 3, 4>, [3], <1, 2, 3>, и т.д.
  38.  
  39.  AcDbDatabase * pDb =
  40.  acdbHostApplicationServices()->workingDatabase();
  41.  AcDbBlockTableRecordPointer ms(ACDB_MODEL_SPACE, pDb, AcDb::kForWrite);
  42.  
  43.  AcDbVoidPtrArray lineArray;
  44.  int  face = 0;
  45.  int  numVerticesInFace = 0;
  46.  for  (int  i = 0; i < faceInfo.length();  i += numVerticesInFace + 1, face++)
  47.  {
  48.         numVerticesInFace = faceInfo.at(i);
  49.  
  50.         AcGePlane facePlane;
  51.         es = mesh->getFacePlane(subentPaths.at(face).subentId(),  facePlane);
  52.         AcGeBoundBlock3d boundBox;
  53.         for  (int  j = 0; j < numVerticesInFace; j++)
  54.         {
  55.                AcGePoint3d pt1 =
  56.                vertices.at(faceInfo.at(i + j + 1));
  57.                AcGePoint3d pt2 =
  58.                vertices.at(
  59.                faceInfo.at(i + ((j + 1) % numVerticesInFace) + 1));
  60.  
  61.                if (j == 0) 
  62.                     boundBox.set(pt1, pt2);
  63.                else
  64.                {
  65.                        boundBox.extend(pt1);
  66.                        boundBox.extend(pt2);
  67.                }
  68.                               
  69.                // Если требуются еще и ребра
  70.                //AcDbObjectPointer<AcDbLine> line;
  71.                //line.create();
  72.                //line->setStartPoint(pt1);
  73.                //line->setEndPoint(pt2);
  74.                //ms->appendAcDbEntity(line);
  75.         }
  76.  
  77.         AcGePoint3d minPt;
  78.         AcGePoint3d maxPt;
  79.         boundBox.getMinMaxPoints(minPt, maxPt);
  80.         AcGeVector3d normalLen = maxPt - minPt;
  81.  
  82.         AcGeVector3d normal = facePlane.normal();
  83.                                      
  84.         // Стрелка
  85.         AcDbLine *pArrow = new  AcDbLine;
  86.         pArrow->setColorIndex(2);
  87.  
  88.         AcGePoint3d sp = minPt + normalLen * 0.5;
  89.         pArrow->setStartPoint(sp);
  90.  
  91.         AcGePoint3d ep = sp
  92.                + normal.normalize() * normalLen.length();
  93.         pArrow->setEndPoint(ep);
  94.  
  95.         ms->appendAcDbEntity(pArrow);
  96.         pArrow->close();
  97.  
  98.         // Окончание стрелки
  99.         double  arrowLen = normalLen.length() * 0.2;
  100.         AcDb3dSolid *pArrowHead = new  AcDb3dSolid;
  101.         es = pArrowHead->createFrustum(
  102.                arrowLen,
  103.                arrowLen / 3.0,
  104.                arrowLen / 3.0,
  105.                0.0);
  106.                       
  107.         AcGeVector3d zd = (ep - sp).normalize();
  108.         AcGeVector3d yd = zd.perpVector().normalize();
  109.         AcGeVector3d xd = yd.crossProduct(zd).normalize();
  110.         AcGeMatrix3d mat;
  111.         mat.setCoordSystem(ep, xd, yd, zd);
  112.         pArrowHead->transformBy(mat);
  113.                       
  114.         ms->appendAcDbEntity(pArrowHead);
  115.         pArrowHead->close();
  116.  }

 

Вот так выглядят нормали к простому параллелепипеду:

Источник: http://adndevblog.typepad.com/autocad/2015/01/viewing-face-normals-of-a-mesh.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=1799

Опубликовано 26.01.2015
Отредактировано 26.01.2015 в 01:31:53