29/05/2013
Получение информации о гранях из AcDbPolyFaceMesh и AcDbPolygonMesh
Вопрос:
Я бы хотел получить информацию о гранях для примитивов полигональных и многогранных сетей. Есть ли пример как это можно сделать?
Ответ:
Следующие примеры кода рисуют отрезки поперёк всех граней выбранных примитивов полигональной и многогранной сетей.
Код - C++: [Выделить]
- static void AEN1ArxAcDbPolyFaceMesh_PolyFace(void)
- {
- int ret;
- ads_name name;
- ads_point pt;
- if (acedEntSel(_T("\nВыберите многогранную сеть: "), name, pt) != RTNORM)
- return;
- AcDbObjectId id;
- if(acdbGetObjectId(id, name) != Acad::eOk)
- return;
- AcDbObjectPointer<AcDbPolyFaceMesh> mesh(id, AcDb::kForRead);
- if (mesh.openStatus() != Acad::eOk)
- return;
- AcArray<AcDbObjectId> vertexIds;
- AcArray<AcDbLine*> lines;
- AcDbObjectIterator * iter = mesh->vertexIterator();
- for (; !iter->done(); iter->step())
- {
- if (iter->objectId().objectClass() ==
- AcDbPolyFaceMeshVertex::desc())
- {
- vertexIds.append(iter->objectId());
- // Вы можете получить здесь положения вершин вместо того, чтобы
- // отбирать ObjectId вершин
- }
- else if (iter->objectId().objectClass() ==
- AcDbFaceRecord::desc())
- {
- // Получаем вершины из записи грани
- AcDbObjectPointer<AcDbFaceRecord>
- face(iter->objectId(), AcDb::kForRead);
- AcGePoint3d pts[4];
- for (Adesk::UInt16 i = 0; i < 4; i++)
- {
- // Индекс вершины начинается с 1, что соответствует 0
- // в списке вершин, так что нам нужно вычесть 1
- // Возвращаемый индекс будет отрицательным, если она скрыта.
- // Так что получим положительное значение, используя abs()
- Adesk::Int16 vertexIndex;
- if (face->getVertexAt(i, vertexIndex) == Acad::eOk)
- {
- AcDbObjectPointer<AcDbPolyFaceMeshVertex>
- vertex(vertexIds[abs(vertexIndex) - 1], AcDb::kForRead);
- pts[i] = vertex->position();
- }
- }
- // Создаём два отрезка перекрещивающих грань для целей тестирования
- AcDbLine * line1 = new AcDbLine(pts[0], pts[2]);
- AcDbLine * line2 = new AcDbLine(pts[1], pts[3]);
- lines.append(line1);
- lines.append(line2);
- }
- }
- delete iter;
- // Добавляем тестовые отрезки в пространство модели
- AcDbDatabase * pDb =
- acdbHostApplicationServices()->workingDatabase();
- AcDbBlockTableRecordPointer
- ms(ACDB_MODEL_SPACE, pDb, AcDb::kForWrite);
- for (int i = 0; i < lines.length(); i++)
- {
- ms->appendAcDbEntity(lines[i]);
- lines[i]->close();
- }
- }
- static void AEN1ArxAcDbPolyFaceMesh_Polygon(void)
- {
- int ret;
- ads_name name;
- ads_point pt;
- if (acedEntSel(_T("\nВыберите полигональную сеть: "), name, pt) != RTNORM)
- return;
- AcDbObjectId id;
- if(acdbGetObjectId(id, name) != Acad::eOk)
- return;
- AcDbObjectPointer<AcDbPolygonMesh> mesh(id, AcDb::kForRead);
- if (mesh.openStatus() != Acad::eOk)
- return;
- Adesk::Int16 M;
- Adesk::Int16 N;
- if (mesh->polyMeshType() == AcDb::kSimpleMesh)
- {
- M = mesh->mSize();
- N = mesh->nSize();
- }
- else
- {
- M = mesh->mSurfaceDensity();
- N = mesh->nSurfaceDensity();
- }
- // Собираем точки
- AcArray<AcGePoint3d> pts;
- AcDbObjectIterator * iter = mesh->vertexIterator();
- Adesk::Int16 m = 0, n = 0;
- for (int i = 0; !iter->done(); iter->step(), i++)
- {
- if (iter->objectId().objectClass() ==
- AcDbPolygonMeshVertex::desc())
- {
- AcDbObjectPointer<AcDbPolygonMeshVertex>
- vertex(iter->objectId(), AcDb::kForRead);
- if (vertex->vertexType() == AcDb::k3dSimpleVertex ||
- vertex->vertexType() == AcDb::k3dFitVertex
- )
- pts.append(vertex->position());
- }
- }
- delete iter;
- // Создаём перекрещивающиеся отрезки
- AcArray<AcDbLine*> lines;
- for (m = 0; m < M - 1; m++)
- for (n = 0; n < N - 1; n++)
- {
- // Индексы вершин грани могут быть легко посчитаны
- // Если верхний левый – m и n, тогда верхний правый -
- // m, n + 1, нижний правый - m + 1, n + 1, и
- // нижний левый - m + 1, n
- AcDbLine * line1 =
- new AcDbLine(
- pts[(m * N) + (n)],
- pts[((m + 1) * N) + (n + 1)]);
- AcDbLine * line2 =
- new AcDbLine(
- pts[((m + 1) * N) + (n)],
- pts[(m * N) + (n + 1)]);
- lines.append(line1);
- lines.append(line2);
- }
- // Добавляем тестовые линии в пространство модели
- AcDbDatabase * pDb = acdbHostApplicationServices()->workingDatabase();
- AcDbBlockTableRecordPointer ms(ACDB_MODEL_SPACE, pDb, AcDb::kForWrite);
- for (int i = 0; i < lines.length(); i++)
- {
- ms->appendAcDbEntity(lines[i]);
- lines[i]->close();
- }
- }
Обсуждение: http://adn-cis.org/forum/index.php?topic=69.0
Опубликовано 29.05.2013
Отредактировано 08.06.2013 в 00:57:52
Отредактировано 08.06.2013 в 00:57:52