Получение геометрии элемента в локальных координатах

Автор Тема: Получение геометрии элемента в локальных координатах  (Прочитано 4659 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн VladislavАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 210
  • Карма: 0
Добрый день!
Такая задача. Мне нужно получить геометрию элемента в его локальных координатах,
а также отдельно его матрицу трансформации в мировые координаты. Подскажите пожалуйста, как это сделать.
Я же пока что могу получить геометрию только сразу в мировых координатах.
Спасибо за информацию.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я же пока что могу получить геометрию только сразу в мировых координатах.
А как вы получаете в мировых координатах?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн VladislavАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 210
  • Карма: 0
Примерно так
Код - C++ [Выбрать]
  1. //Получаем геометрию элемента
  2.         Options^ pOpts = gcnew Options;
  3.         pOpts->DetailLevel = ViewDetailLevel::Fine;
  4.         pOpts->IncludeNonVisibleObjects = false;
  5.         pGElement = pElement->Geometry[pOpts];
  6.         if (!pGElement) return -1;
  7.         pPars = pElement->Parameters;
  8.         IEnumerator<GeometryObject^>^ pObjEn = pGElement->GetEnumerator();
  9.         pObjEn->Reset();
  10.         GeometryInstance^ pGInst = nullptr;
  11.         Solid^ pSolid = nullptr;
  12.        
  13.         while (pObjEn->MoveNext()) {
  14.                 if (!pGInst) pGInst = dynamic_cast<GeometryInstance^>(pObjEn->Current);
  15.                 pSolid = dynamic_cast<Solid^>(pObjEn->Current);
  16.                 if (pSolid && (pSolid->Faces->Size > 0) && (pSolid->Edges->Size > 0)) ConvertSolidToCSMesh(pSolid, pMesh,false);
  17.         }
  18.         if (pGInst) {
  19.                 pObjEn = pGInst->GetInstanceGeometry()->GetEnumerator();
  20.                 pObjEn->Reset();
  21.                 while (pObjEn->MoveNext()) {
  22.                         pSolid = dynamic_cast<Solid^>(pObjEn->Current);
  23.                         if (pSolid && (pSolid->Faces->Size > 0) && (pSolid->Edges->Size > 0)) ConvertSolidToCSMesh(pSolid, pMesh, false);
  24.                 }
  25.         }
  26.  

Функция получения меша из треугольников
Код - C++ [Выбрать]
  1. //Функция конвертирует Solid в CSMesh
  2. void RvtConverter::ConvertSolidToCSMesh(Solid ^ pSolid, CSMesh ^% pMesh, bool isRebar)
  3. {
  4.         CSVector3 pt1, pt2, pt3;
  5.         if (pMesh == nullptr) {
  6.                 pMesh = gcnew CSMesh;
  7.                 pMesh->Clear();
  8.         }//of if       
  9.        
  10.         FaceArrayIterator^ pFaceIt = pSolid->Faces->ForwardIterator();
  11.         pFaceIt->Reset();
  12.  
  13.         //Цикл по граням   
  14.         while (pFaceIt->MoveNext()) {
  15.                 Face^ pFace = (Face^)(pFaceIt->Current);
  16.                 Mesh^ pRevitMesh = nullptr;
  17.                
  18.                 CSMaterial^     material = nullptr;
  19.                 Material^ pMat = dynamic_cast<Material^>(m_doc->GetElement(pFace->MaterialElementId));
  20.                 if (pMat != nullptr)
  21.                         material = gcnew CSMaterial(pMat->Color->Red, pMat->Color->Green, pMat->Color->Blue, 255-pMat->Transparency*255/100);                                  
  22.                 else
  23.                         material = gcnew CSMaterial(128, 128, 128, 255);                                       
  24.                 pMesh->SetCurrentMaterial(material);
  25.  
  26.                 //Если передан арматурный элемент, уменьшаем густоту сетки триангуляции
  27.                 if (isRebar) pRevitMesh = pFace->Triangulate(0.1);
  28.                 else pRevitMesh = pFace->Triangulate();
  29.                 UV^ uv = gcnew UV(0, 0);
  30.                 XYZ^ pXYZNormal = pFace->ComputeNormal(uv);
  31.                 CSVector3 NormalVec;
  32.                 NormalVec.x = -1 * float(pXYZNormal->X);
  33.                 NormalVec.y = -1 * float(pXYZNormal->Y);
  34.                 NormalVec.z = -1 * float(pXYZNormal->Z);
  35.                
  36.                 for (int i = 0; i < pRevitMesh->NumTriangles; i++) {
  37.                         MeshTriangle^ pTriangle = pRevitMesh->Triangle[i];
  38.                         XYZ^ pVertex = pTriangle->Vertex[0];
  39.                         pt1.x = float(pVertex->X*304.8);
  40.                         pt1.y = float(pVertex->Y*304.8);
  41.                         pt1.z = float(pVertex->Z*304.8);
  42.                         pVertex = pTriangle->Vertex[1];
  43.                         pt2.x = float(pVertex->X*304.8);
  44.                         pt2.y = float(pVertex->Y*304.8);
  45.                         pt2.z = float(pVertex->Z*304.8);
  46.                         pVertex = pTriangle->Vertex[2];
  47.                         pt3.x = float(pVertex->X*304.8);
  48.                         pt3.y = float(pVertex->Y*304.8);
  49.                         pt3.z = float(pVertex->Z*304.8);
  50.                         pMesh->AddTriangleFace(pt3, pt2, pt1, true /*No Normal*/);
  51.                         int LastIndx = pMesh->Index->Count - 1;
  52.                         if (LastIndx >= 2) {
  53.                                 pMesh->Vertices[pMesh->Index[LastIndx]]->SetNormal(NormalVec);
  54.                                 pMesh->Vertices[pMesh->Index[LastIndx - 1]]->SetNormal(NormalVec);
  55.                                 pMesh->Vertices[pMesh->Index[LastIndx - 2]]->SetNormal(NormalVec);
  56.                         }                      
  57.                 }// of for               
  58.         }//of while
  59. }
  60.  
  61.  

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
https://www.revitapidocs.com/2020/99cb4580-9b59-6564-8181-6082f275a869.htm
GeometryInstance.Transform возвращает матрицу преобразования. Попробуй с ней.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Vladislav,
А вообще хотелось бы понимать что имеется в виду под "локальными" координатами и под "мировыми" координатами.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн VladislavАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 210
  • Карма: 0
Под локальными координатами элемента понимаю координаты вершин в его собственной системе координат.
Это равносильно тому, что элемент находится в нуле (в начале координат). При позиционировании элементов в мировой
системе их взаимное расположение становится корректным. Без такого позиционирования все элементы будут "свалены в кучу".

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Это равносильно тому, что элемент находится в нуле (в начале координат).
Какое место этого элемента находится в начале координат? Даже в простейшем случае куба в начале координат может быть любая из вершин, центр тяжести, центр любой из граней, центр любого из ребер и т.д. и т.п.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн VladislavАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 210
  • Карма: 0
А это определено уже в самом элементе, где находится начало его локальной системы координат.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А это определено уже в самом элементе, где находится начало его локальной системы координат.
Кем определено? Смотрим описание класса Solid, с которым работает программа и ищем метод или свойство, которое даёт начало локальной системы координат: https://www.revitapidocs.com/2020/7a3b5ac1-c66d-9f81-a11d-9bcd4e026295.htm
Я не нашел.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн VladislavАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 210
  • Карма: 0
В принципе то, что мене нужно можно получить через GrySymbolGeometry. Но этот метод есть не для всех элементов...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
В принципе то, что мене нужно можно получить через GrySymbolGeometry.
Не нашел такого метода в документации.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
В принципе то, что мене нужно можно получить через GrySymbolGeometry. Но этот метод есть не для всех элементов...
Потому что этот метод применим только к загружаемым семействам - т.е. к тем семействам, которые имеют собственный документ! Вполне себе по аналогии с блоками в автокаде.
А вот экземпляры системных семейств не могут иметь таких координат - для них родительским документом является именно документ, в котором они созданы. Т.е. у них нет и не может быть "локальной системы координат". И тут все вполне логично

P.S. Кстати, и семейство можно сделать настолько косячно, что геометрия семейства будет очень далека от нуля
P.S.S. GrySymbolGeometry возвращает геометрию семейства в исходном виде, без взаимодействия с элементами модели!

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
В принципе то, что мене нужно можно получить через GrySymbolGeometry.
Не нашел такого метода в документации.

Вот он

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр Пекшев aka Modis,
Сравни GrySymbolGeometry и GetSymbolGeometry
Поди догадайся, что Vladislav имел в виду...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Александр Пекшев aka Modis,
Сравни GrySymbolGeometry и GetSymbolGeometry
Поди догадайся, что Vladislav имел в виду...

А я даже и не заметил опечатку ))

Хотелось бы, кстати, узнать зачем автору вопроса нужна геометрия в "локальных координатах"

Оффлайн VladislavАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 210
  • Карма: 0
Коллеги, благодарю за информацию.
Геометрия в локальных координатах необходима в силу специфики задачи.
Я разрабатываю(и дорабатываю) конвертер моделей из Revit в формат нашего продукта.
И там геометрия элементов записывается именно в локальных координатах совместно с матрицей трансформации.

Оффлайн VladislavАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 210
  • Карма: 0
А какие семейства являются системными?


Оффлайн VladislavАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 210
  • Карма: 0
Спасибо.
Еще такой вопрос.
Правильно ли я понял, что матрицу трансформации(позиционирования) в мировые координаты можно получить только
для объектов класса FamilyInstance (метод GetTransform())? И для объектов других классов её просто нет...