Конвертация в 3dSolid функция setASMBody

Автор Тема: Конвертация в 3dSolid функция setASMBody  (Прочитано 10427 раз)

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

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Нужна внутренняя конвертация тел Amodeler’a в 3dSolid’ы
Вот код, который работал до objectarx 2012
void *acisBody = createBodyFromTriangles (pts, arrI) ;
   AcDb3dSolid *solid =new AcDb3dSolid;
   solid->setBody (acisBody) ;
вот измененная последняя строка, начиная с 2013
        Acad::ErrorStatus es = solid->setASMBody(acisBody);
Не работает.
Ни в help’ax ни в поисковиках ничего, примеров кода и т.п.  по setASMBody и createBodyFromTriangles  из Amodeler’а нет.
Если кто знает как из AcDbPolyFaceMesh сделать 3dSolid внутри objectarx что тоже подойдет на крайний случай, отзовитесь.

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #1 : 09-03-2016, 19:50:36 »
Ни в help’ax ни в поисковиках ничего, примеров кода и т.п.  по setASMBody и createBodyFromTriangles  из Amodeler’а нет.
createBodyFromTriangles не из Amodeler, а из HlrApi.
Пока могу сказать только одно, что можно конвертировать в AcDbBody:
Код - C++ [Выбрать]
  1.     void *acisBody = createBodyFromTriangles (gePts, indices) ;
  2.     AcDbObjectId id ;
  3.     AcDbBody *pBody = new AcDbBody();
  4.     Acad::ErrorStatus es = pBody->setASMBody(acisBody);
  5.     postToDatabase (NULL, pBody, id) ;
  6.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Виталий 10-03-2016, 16:56:35

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #2 : 09-03-2016, 21:33:52 »
Судя по всему это баг в API - отправлю в ADN DevHelp. Я воспользовался примером из ObjectARX SDK: utils\HlrApi\samples\HlrArxSample, функция asdktest6. В чистом виде она действительно работает в AutoCAD 2012, но не работает в более новых версиях. Я немного поэкспериментировал и получил из неё рабочий код (проверял только в AutoCAD 2016):
Код - C++ [Выбрать]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.cpp
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #include "resource.h"
  6. Acad::ErrorStatus postToDatabase (/*[in]*/AcDbDatabase *pDb /*=NULL*/, AcDbEntity *pEnt, AcDbObjectId &idObj);
  7.  
  8. //-----------------------------------------------------------------------------
  9. #define szRDS _RXST("")
  10.  
  11. //-----------------------------------------------------------------------------
  12. //----- ObjectARX EntryPoint
  13. class CTest3dsolidApp : public AcRxArxApp {
  14.  
  15. public:
  16.   CTest3dsolidApp () : AcRxArxApp () {}
  17.   AcString AsdkHlrApi;
  18.  
  19.   virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
  20.     AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg (pkt) ;
  21.     // Загружаем нужную версию HlrApi
  22.     int ver = acdbHostApplicationServices()->releaseMajorVersion();  
  23.     AsdkHlrApi.format(_T("AsdkHlrApi%d.dbx"),ver);
  24.     acedArxLoad(AsdkHlrApi);
  25.     return (retCode) ;
  26.   }
  27.  
  28.   virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
  29.     AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
  30.     acedArxUnload(AsdkHlrApi);
  31.     return (retCode) ;
  32.   }
  33.  
  34.   virtual void RegisterServerComponents () { }
  35.  
  36.   static void RivilisTestConv () {
  37.  
  38.     int nPoints = 8 ;
  39.     int nTriangles = 12 ;
  40.     int nIndices = 3 * nTriangles ;
  41.  
  42.     double p [] = {
  43.       0, 0, 0,
  44.       1, 0, 0,
  45.       1, 1, 0,
  46.       0, 1, 0,
  47.       0, 0, 1,
  48.       1, 0, 1,
  49.       1, 1, 1,
  50.       0, 1, 1
  51.     } ;
  52.  
  53.     int i [] = {
  54.       0, 1, 5,    0, 5, 4,
  55.       1, 6, 5,    1, 2, 6,
  56.       4, 5, 6,    4, 6, 7,
  57.       7, 0, 4,    7, 3, 0,
  58.       2, 0, 3,    2, 1, 0,
  59.       7, 6, 3,    6, 2, 3
  60.     } ;
  61.  
  62.     AcGeIntArray indices (nIndices) ;
  63.     indices.setLogicalLength (nIndices) ;
  64.     indices.setPhysicalLength (nIndices) ;
  65.     memcpy (indices.asArrayPtr (), i, nIndices * sizeof (int)) ;
  66.  
  67.     AcGePoint3dArray gePts (nPoints) ;
  68.     gePts.setLogicalLength (nPoints) ;
  69.     gePts.setPhysicalLength (nPoints) ;
  70.     memcpy (gePts.asArrayPtr(), p, nPoints * sizeof (AcGePoint3d)) ;
  71.  
  72.     void *acisBody = createBodyFromTriangles (gePts, indices) ;
  73.  
  74.     AcDbObjectId id ;
  75.     // Получаем из треугольников AcDbBody, так как напрямую
  76.     // AcDb3dSolid получить не удаётся.
  77.     AcDbBody *pBody = new AcDbBody();
  78.     Acad::ErrorStatus es = pBody->setASMBody(acisBody);
  79.     // Преобразуем AcDbBody в поверхность AcDbSurface
  80.     AcBrBrep *pBrep = new AcBrBrep();
  81.     AcBr::ErrorStatus ebs = pBrep->set(*pBody);
  82.     AcDbSurface *pSurf = new AcDbSurface() ;
  83.     ebs = pBrep->get(pSurf);
  84.     // Получаем из AcDbSurface AcDb3dSolid
  85.     AcDb3dSolid *pSolid = new AcDb3dSolid();
  86.     es = pSolid->createFrom(pSurf);
  87.     // Добавляем в чертеж.
  88.     es = postToDatabase (NULL, pSolid, id) ;
  89.     delete pBrep;  delete pSurf;  delete pBody;
  90.   }
  91. } ;
  92.  
  93. //-----------------------------------------------------------------------------
  94. IMPLEMENT_ARX_ENTRYPOINT(CTest3dsolidApp)
  95. ACED_ARXCOMMAND_ENTRY_AUTO(CTest3dsolidApp, Rivilis, TestConv, TestConv, ACRX_CMD_MODAL, NULL)
  96.  
  97. Acad::ErrorStatus postToDatabase (/*[in]*/AcDbDatabase *pDb /*=NULL*/, AcDbEntity *pEnt, AcDbObjectId &idObj) {
  98.     assert ( pEnt != NULL ) ;
  99.     if ( pDb == NULL )
  100.       pDb =acdbHostApplicationServices ()->workingDatabase () ;
  101.     Acad::ErrorStatus es ;
  102.     AcDbBlockTable *pBlockTable ;
  103.     if ( (es =pDb->getBlockTable (pBlockTable, AcDb::kForRead)) == Acad::eOk ) {
  104.       AcDbBlockTableRecord *pSpaceRecord ;
  105.       if ( (es =pBlockTable->getAt (ACDB_MODEL_SPACE, pSpaceRecord, AcDb::kForWrite)) == Acad::eOk ) {
  106.         if ( (es =pSpaceRecord->appendAcDbEntity (idObj, pEnt)) == Acad::eOk )
  107.           pEnt->close () ;
  108.         pSpaceRecord->close () ;
  109.       }
  110.       pBlockTable->close () ;
  111.     }
  112.     return (es) ;
  113. }

« Последнее редактирование: 09-03-2016, 22:13:22 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #3 : 09-03-2016, 22:16:39 »
Спасибо! Очень надеюсь на решение проблемы. Нужен именно AcDb3dSolid после применения createBodyFromTriangles.

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #4 : 09-03-2016, 22:22:53 »
Спасибо! Очень надеюсь на решение проблемы. Нужен именно AcDb3dSolid после применения createBodyFromTriangles.

Ты внимательно прочитал то, что я написал, посмотрел код, посмотрел видео? Для кого я это всё делал?  >:(
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #5 : 10-03-2016, 16:56:06 »
Да, работает, спасибо! Только brbrep.h acbr20.lib добавил и еще
Код - C++ [Выбрать]
  1. pSolid->cleanBody();
для убирания ненужных граней.

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #6 : 10-03-2016, 17:18:53 »
В ADN DevHelp отправил. Если они предложат альтернативный вариант (свой я им пока не показывал :) ) - сообщу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #7 : 11-03-2016, 07:38:39 »
Раз уж вообще это возможно, что ты доказал в своем тесте, то думаю ADN спецам нужно сказать еще о приоритете скорости такой конвертации (может хоть на будущее), а то объектов много в Автокаде, крутить из одной топологии в другую и третью уходит время. На конвертации одного более менее серьезного объекта шкала прокрутки требуется. В любом случае их ответ будет интересен.

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #8 : 16-03-2016, 20:09:44 »
Получил сегодня ответ из ADN DevHelp. Баг они воспроизвели. Очень удивлялись, что за четыре года им никто о нём не сообщил и они были не в курсе об этой проблеме. Передали проблему в DevTeam. От себя добавлю, что я бы не расчитывал на исправление в текущих версиях. Да и в релиз 2017 это исправление не попадёт. Так что пользуйся пока моим кодом, если не придумаешь другую альтернативу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #9 : 16-03-2016, 20:48:59 »
Тогда пожалуй твой вариант единственный. Обязательно буду использовать!

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #10 : 17-03-2016, 18:40:30 »
Меня сегодня насмешили сотрудники ADN DevHelp. Вчера я им послал свой метод как обойти ошибку в этой ситуации - нате пользуйтесь на здоровье. На что получил ответ, что они не могут рекомендовать его даже как временную замену, так как (!!!) метод AcDbBody::setASMBody(), как сказано в документации, "For internal use". На мой резонный вопрос о том, что и AcDb3dSolid::setASMBody() тоже "For internal use" я получил ответ, что HlrApi весь построен на недокументированных и "For internal use" методах. Вот так...  :)
Главное, что они уже внесли этот баг в список на исправление.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #11 : 30-03-2016, 12:42:09 »
Нужна универсальная конвертация 3DSOLID в AcDbPolyFaceMesh. Есть пример в C#, но я в нем ничего не понимаю, Понятно лишь, что такое возможно.
вот ссылка: http://adn-cis.org/sozdanie-polyfacemesh-iz-3d-solid.html
Хотелось бы увидеть пример того же самого, но в коде С++ ObjectARX, поскольку функцию нужно внедрить в существующий arx проект. Предыдущее решение - конвертация в 3DSOLID через brep - удалось, теперь фактически стоит обратная задача.

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Конвертация в 3dSolid функция setASMBody
« Ответ #12 : 30-03-2016, 12:56:47 »
Виталий
Один вопрос - одна тема. Так что не ленись и создай отдельную тему.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение