Объектная привязка после булевых операций в телах amodeller

Автор Тема: Объектная привязка после булевых операций в телах amodeller  (Прочитано 9716 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Заметил что после любой булевой операции (asubstract, aunion) над телами из примера asdkbodyapp объектная привязка портится, т.е. точки объектной привязки выдаются непредсказуемо и неверно, слетают на другие линии граней и т.п. Причем когда к AsdkBody добавлен subGetOsnapPoints то на любых телах объектная привязка на линиях тел работает корректно.
Как и что нужно добавить в arx для объекта результата булевой операции (custom object AsdkBody) чтобы не слетала объектная привязка? 

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

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

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
После булевой операции объектная привязка начинает работать непредсказуемо, некорректно. Как исправить это не знаю. Прошу помощи. На известном arx примере asdkbodyapp показать решение этой проблемы. Т.е. проверка такая: создать 2 тела, объединить, вычесть и т.п. и проверить затем, чтобы, например, osnap - Ближайшая точка работала на всех гранях такого тела.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Так как в этом примере вообще нет метода subGetOsnapPoints, то вообще не понятно как привязки работают. Так что хочешь или не хочешь, а этот метод реализовать придётся.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
я добавил в Asdkbody.h его:
 
Код - C++ [Выбрать]
  1.                virtual Acad::ErrorStatus subGetOsnapPoints(
  2.                 AcDb::OsnapMode osnapMode,
  3.                 Adesk::GsMarker gsSelectionMark,
  4.                 const AcGePoint3d& pickPoint,
  5.                 const AcGePoint3d& lastPoint,
  6.                 const AcGeMatrix3d& viewXform,
  7.                 AcGePoint3dArray& snapPoints,
  8.                 AcDbIntArray & geomIds
  9.                 ) const;
  10.  
но он не компилируется, выдает ошибку:
Код - C++ [Выбрать]
  1. Link:
  2. 1>     Creating library x64\Release\AsdkBodyObj.lib and object x64\Release\AsdkBodyObj.exp
  3. 1>AsdkBody.obj : error LNK2001: unresolved external symbol "public: virtual enum Acad::ErrorStatus __cdecl AsdkBody::subGetOsnapPoints(enum AcDb::OsnapMode,__int64,class AcGePoint3d const &,class AcGePoint3d const &,class AcGeMatrix3d const &,class AcArray<class AcGePoint3d,class AcArrayMemCopyReallocator<class AcGePoint3d> > &,class AcArray<int,class AcArrayMemCopyReallocator<int> > &)const " (?subGetOsnapPoints@AsdkBody@@UEBA?AW4ErrorStatus@Acad@@W4OsnapMode@AcDb@@_JAEBVAcGePoint3d@@2AEBVAcGeMatrix3d@@AEAV?$AcArray@VAcGePoint3d@@V?$AcArrayMemCopyReallocator@VAcGePoint3d@@@@@@AEAV?$AcArray@HV?$AcArrayMemCopyReallocator@H@@@@@Z)
  4. 1>C:\ObjectARX 2017\utils\amodeler\samples\asdkbodyapp\x64\Release\AsdkBodyObj.dbx : fatal error LNK1120: 1 unresolved externals
  5. 1>
  6. 1>Build FAILED.
  7.  
Это только чтобы показать на примере, что не корректно работает привязка после булевых операций, а как решить проблему я тем более не знаю.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
но он не компилируется, выдает ошибку:
Он компилируется, но не линкуется. А в Asdkbody.cpp ты реализацию этого метода добавил? В Asdkbody.h ты добавил только описание.
Смотри в готовых примерах как это должно быть.
P.S.: У меня привязки не работают не только на булевых операциях, но и даже на простых созданных телах. Что вполне логично.
Без реализации subGetOsnapPoints ничего не будет работать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Виталий 14-02-2017, 07:51:26

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вот такую простейшую реализацию для конточки и ближайшей я сварганил:
Код - C++ [Выбрать]
  1. Acad::ErrorStatus
  2. AsdkBody::subGetOsnapPoints(
  3.   AcDb::OsnapMode     osnapMode,
  4.   Adesk::GsMarker     gsSelectionMark,
  5.   const AcGePoint3d&  pickPoint,
  6.   const AcGePoint3d&  lastPoint,
  7.   const AcGeMatrix3d& viewXform,
  8.   AcGePoint3dArray&   snapPoints,
  9.   AcDbIntArray &   geomIds) const
  10. {
  11.   AcGeVector3d viewDir(viewXform(Z, 0), viewXform(Z, 1), viewXform(Z, 2));
  12.   if (osnapMode == AcDb::OsnapMode::kOsModeNear) {
  13.     AcGePoint3d pNearest(1e+160,1e+160,1e+160);
  14.     double distPrj = 1e+160;
  15.     Face *face = m_3dGeom.faceList();
  16.     for (Face *faceCur = face; faceCur != NULL; faceCur = faceCur->next()) {
  17.       for (int iEdge = 0; iEdge < faceCur->edgeCount(); iEdge++) {
  18.         Edge *edge = faceCur->edge(iEdge);
  19.         Vertex *vertex1 = edge->vertex();
  20.         Edge *edgeNext = edge->next();
  21.         Vertex *vertex2 = face->edge(0)->vertex();
  22.         if (edgeNext != NULL) {
  23.           vertex2 = edgeNext->vertex();
  24.         }
  25.         AcGeLineSeg3d lSeg3d(vertex1->point(), vertex2->point());
  26.         AcGePlane viewPlan(vertex1->point(), viewDir);
  27.         AcGePoint3d pEndPrj = AcGePoint3d(vertex2->point()).project(viewPlan, viewDir);
  28.         AcGeLineSeg3d lsegprj(vertex1->point(), pEndPrj);
  29.         AcGePoint3d pickprj = pickPoint.orthoProject(viewPlan);
  30.         AcGePointOnCurve3d pOn1;
  31.         lsegprj.getClosestPointTo(pickprj, pOn1);
  32.         double distPrjCur = pOn1.point().distanceTo(pickprj);
  33.         if (distPrjCur < distPrj) {
  34.           distPrj = distPrjCur;
  35.           lSeg3d.getProjClosestPointTo(pickPoint, viewDir, pOn1);
  36.           pNearest = pOn1.point();
  37.         }
  38.       }
  39.     }
  40.     snapPoints.append(pNearest);
  41.   } else if (osnapMode == AcDb::OsnapMode::kOsModeEnd) {
  42.     AcGePoint3d pNearest(1e+160,1e+160,1e+160);
  43.     double distPrj = 1e+160;
  44.     Face *face = m_3dGeom.faceList();
  45.     Face *faceCur = face;
  46.     for (Face *faceCur = face; faceCur->next() != NULL; faceCur = faceCur->next()) {
  47.       for (int iEdge = 0; iEdge < faceCur->edgeCount(); iEdge++) {
  48.         Edge *edge = faceCur->edge(iEdge);
  49.         Vertex *vertex1 = edge->vertex();
  50.         Edge *edgeNext = edge->next();
  51.         Vertex *vertex2 = face->edge(0)->vertex();
  52.         if (edgeNext != NULL) {
  53.           vertex2 = edgeNext->vertex();
  54.         }
  55.         AcGePoint3d pStart = vertex1->point();
  56.         AcGePoint3d pEnd = vertex2->point();
  57.         AcGeLineSeg3d lSeg3d(pStart, pEnd);
  58.         AcGePlane viewPlan(pStart, viewDir);
  59.         AcGePoint3d pEndPrj = AcGePoint3d(vertex2->point()).project(viewPlan, viewDir);
  60.         AcGeLineSeg3d lsegprj(pStart, pEndPrj);
  61.         AcGePoint3d pickprj = pickPoint.orthoProject(viewPlan);
  62.         AcGePointOnCurve3d pOn1;
  63.         lsegprj.getClosestPointTo(pickprj, pOn1);
  64.         double distPrjCur = pOn1.point().distanceTo(pickprj);
  65.         if (distPrjCur < distPrj) {
  66.           distPrj = distPrjCur;
  67.           lSeg3d.getProjClosestPointTo(pickPoint, viewDir, pOn1);
  68.           if (pStart.distanceTo(pOn1.point()) < pEnd.distanceTo(pOn1.point())) {
  69.             pNearest = pStart;
  70.           } else {
  71.             pNearest = pEnd;
  72.           }
  73.         }
  74.       }
  75.     }
  76.     snapPoints.append(pNearest);
  77.   }
  78.   return Acad::eOk;
  79. }



Это для затравки. Дальше "допиливай" и "украшай" сам.
Как видишь работает и на объединённых ASDKBODY (там два ABOX и одна ASPHERE)
« Последнее редактирование: 14-02-2017, 10:17:21 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Спасибо!
В старых листингах это было реализовано вот так:
Код - C++ [Выбрать]
  1. Adesk::Boolean bSplFrame = acdbHostApplicationServices()->workingDatabase()->splframe();
  2.  
  3.     int gs_marker = 1;
  4.     for (Face* f = m_3dGeom.faceList(); f != NULL; f = f->next())
  5.     {
  6.         if (f->edgeLoop() == NULL)
  7.             continue;
  8.        
  9.         Edge* e = f->edgeLoop();
  10.         do
  11.         {
  12.             if (e->isEulerEdge())
  13.             {
  14.                 if (e->isBridge() || (e->isApprox() && !bSplFrame) )
  15.                                 {
  16. #ifndef NDEBUG
  17.                                         gs_marker++;
  18. #endif
  19.                                         continue;
  20.                                 }
  21.  
  22.                 if (gs_marker++ == gsSelectionMark)
  23.                 {
  24.                     AcGePoint3d p[2];
  25.                     p[0] = *(AcGePoint3d*)&e->point();
  26.                     p[1] = *(AcGePoint3d*)&e->next()->point();
  27.  
  28.                     switch (osnapMode)
  29.                     {
  30.                     case AcDb::kOsModeEnd:
  31.                         snapPoints.append( p[0] );
  32.                         snapPoints.append( p[1] );
  33.                         break;
  34.  
  35.                     case AcDb::kOsModeMid:
  36.                         snapPoints.append( p[0] + (p[1] - p[0]) / 2.0 );
  37.                         break;
  38.  
  39.                     case AcDb::kOsModeNear:
  40.                                                 {
  41.                                                         AcGePoint3d pt;
  42.                                                         AcGeVector3d viewDir(viewXform(Z, 0), viewXform(Z, 1), viewXform(Z, 2));
  43.                                                         AcGeLineSeg3d lnsg(p[0], p[1]);
  44.                                                         pt = lnsg.projClosestPointTo(pickPoint, viewDir);
  45.                                                         snapPoints.append(pt);
  46.                                                 }
  47.                                                 break;
  48.              
  49.                                         case AcDb::kOsModePerp:
  50.                                                 {
  51.                                                         AcGePoint3d pt;
  52.                                                         AcGeVector3d vec;
  53.                                                         AcGeLine3d line;
  54.                                                         vec = p[1] - p[0];
  55. //                                              vec.normalize();
  56.                                                 line.set(p[0], vec);
  57.                                                 pt = line.closestPointTo(lastPoint);
  58.                                                 snapPoints.append(pt);
  59.                                                 }
  60.                                         break;
  61.  
  62.                                         case AcDb::kOsModeCen:
  63.                                                 {
  64.                                                         double area, volume;
  65.                                                 Point3d centroid, moments, products;
  66.                                                         m_3dGeom.massProperties(area, volume, centroid, moments, products);
  67.                                                         AcGePoint3d pt;
  68.                                                         pt = *(AcGePoint3d*)&centroid;
  69.                                                 snapPoints.append(centroid);
  70.                                                 }
  71.                                                 break;
  72.                                         case AcDb::kOsModeNode:
  73.                                         snapPoints.append( p[0] );
  74.                                                 snapPoints.append( p[1] );
  75.                                 break;
  76.  
  77.                                         case AcDb::kOsModeIns:
  78.                                                 {
  79.                                                         double area, volume;
  80.                                                     Point3d centroid, moments, products;
  81.                                                         m_3dGeom.massProperties(area, volume, centroid, moments, products);
  82.                                                         snapPoints.append(centroid);
  83.                                                 }
  84.                                             break;
  85.                     }
  86.                     return Acad::eOk;
  87.                 }
  88.             }
  89.         } while ((e = e->next()) != f->edgeLoop());
  90.     }
  91.     return Acad::eOk;

Сравнил, с твоим кодом работает, со старым нет, т.е. старый был неверный. Интересно почему, чтобы пришло понимание как доработать остальное.

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Еще один вопрос. А можно ли реализовать объектную привязку выбора грани для Asdkbody как это сделано для 3dsolid Автокада? 

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А можно ли реализовать объектную привязку выбора грани для Asdkbody как это сделано для 3dsolid Автокада?
Теоретически можно. Практически - это переписать весь этот класс заново.
В старых листингах это было реализовано вот так:
Это в каких это "старых листингах"?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ***
  • Сообщений: 125
  • Карма: -1
Раньше давно велись собственные разработки, на старых автокадах работало все корректно. Сейчас хочу использовать для новых идей. В принципе ты мне уже помог.