Пересечение Поверхности и Отрезка с использованием ARX

Автор Тема: Пересечение Поверхности и Отрезка с использованием ARX  (Прочитано 5263 раз)

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

Онлайн Александр РивилисАвтор темы

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

Онлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13858
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Обнаружился неприятный баг, который (судя по всему) был внесен в AutoCAD 2015.
Код приведенный по этой ссылке перестал работать. В результате работы этой строки:
Код - C++ [Выбрать]
  1. int count = curveSI.numIntPoints(err_1);
err_1 всегда равно eXXUnknown. Обнаружил это прискорбный факт Jason Paterson здесь: http://adndevblog.typepad.com/autocad/2013/03/intersection-between-a-surface-and-a-line-using-arx.html#comment-6a0167607c2431970b01bb0791a4cc970d
После небольшого исследования я пришел к выводу, что функция перестала проверять пересечение поверхности с неограниченной кривой (AcGeLine3d - это прямая, AcGeLineSeg3d - это отрезок). Таким образом если заменить в коде  AcGeLine3d на AcGeLineSeg3d - функция работает и в AutoCAD 2015. Результирующий код (я не стал переводить комментарии):

Код - C++ [Выбрать]
  1. // (C) Copyright 2002-2012 by Autodesk, Inc.
  2. //
  3. // Permission to use, copy, modify, and distribute this software in
  4. // object code form for any purpose and without fee is hereby granted,
  5. // provided that the above copyright notice appears in all copies and
  6. // that both that copyright notice and the limited warranty and
  7. // restricted rights notice below appear in all supporting
  8. // documentation.
  9. //
  10. // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
  11. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
  12. // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
  13. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
  14. // UNINTERRUPTED OR ERROR FREE.
  15. //
  16. // Use, duplication, or disclosure by the U.S. Government is subject to
  17. // restrictions set forth in FAR 52.227-19 (Commercial Computer
  18. // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
  19. // (Rights in Technical Data and Computer Software), as applicable.
  20. //
  21.  
  22. //-----------------------------------------------------------------------------
  23. //----- acrxEntryPoint.cpp
  24. //-----------------------------------------------------------------------------
  25. #include "StdAfx.h"
  26. #include "resource.h"
  27.  
  28. //-----------------------------------------------------------------------------
  29. #define szRDS _RXST("")
  30.  
  31.  
  32. static AcGePoint3dArray IntersectRoutine(AcDbSurface *pSurface, AcGeLineSeg3d &line)
  33. {  
  34.   AcGeContext::gTol.setEqualPoint(1.0e-8);
  35.   AcGeContext::gTol.setEqualVector(1.0e-6);
  36.  
  37.   AcGePoint3dArray returnPtArray;
  38.   AcDbBody* pBody = new AcDbBody();
  39.   Acad::ErrorStatus es = pBody->setASMBody(pSurface->ASMBodyCopy(true));
  40.   // build AcBrBrep
  41.   AcBrBrep* pBrep = new AcBrBrep();
  42.   //
  43.   if(AcBr::eOk == pBrep->set(*pBody))
  44.   {
  45.     AcBrBrepFaceTraverser* pFaceTrav = new AcBrBrepFaceTraverser;
  46.     if(AcBr::eOk == pFaceTrav->setBrep(*pBrep))
  47.     {
  48.       for(pFaceTrav->restart();!pFaceTrav->done();pFaceTrav->next())
  49.       {
  50.         AcBrFace face;
  51.         if(AcBr::eOk == pFaceTrav->getFace(face))
  52.         {
  53.           double area = 0.0f;
  54.           face.getSurfaceArea(area);
  55.           acutPrintf(L"\nSurface Area: %f", area);
  56.           //****real surface of the original AcDbSurface        
  57.           AcGeExternalBoundedSurface** nurbs = NULL;
  58.           Adesk::UInt32 numNurbs = 0;
  59.           face.getSurfaceAsTrimmedNurbs(numNurbs,nurbs);
  60.           //*****
  61.           for (Adesk::UInt32 i = 0; i < numNurbs; i++)
  62.           {
  63.             // AcGeCurveSurfInt curveSI(line, *nurbs[i]);
  64.             AcGeCurveSurfInt curveSI;
  65.             AcGeIntersectError  err_1 = AcGe::kXXOk;          
  66.             //input the curve and line
  67.             curveSI.set(line,*nurbs[i]);
  68.             //get the count of intersect points
  69.             int count = curveSI.numIntPoints(err_1); // <- Always err_1 == kXXUnknown if line is AcGeLine3d
  70.             if(err_1 == AcGe::kXXOk && count > 0 )
  71.             {
  72.               AcGeIntersectError err_2  = AcGe::kXXOk;          
  73.               for(int index = 0; index < count; index ++)
  74.               {
  75.                 AcGePoint3d pt = curveSI.intPoint(index,err_2);  
  76.                 if (err_2 == AcGe::kXXOk) {
  77.                   returnPtArray.append(pt);
  78.                 }
  79.               }      
  80.             }
  81.             delete nurbs[i];
  82.           }
  83.           // your responsibility to delete the
  84.           // array of surfaces
  85.           delete[] nurbs;
  86.         }
  87.       }
  88.     }
  89.     delete pFaceTrav;
  90.   }
  91.  
  92.   delete pBrep;
  93.   delete pBody;
  94.  
  95.   return returnPtArray;
  96. }
  97.  
  98. //-----------------------------------------------------------------------------
  99. //----- ObjectARX EntryPoint
  100. class CCurveIntSurfApp : public AcRxArxApp {
  101.  
  102. public:
  103.   CCurveIntSurfApp () : AcRxArxApp () {}
  104.   virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
  105.     // TODO: Load dependencies here
  106.     // You *must* call On_kInitAppMsg here
  107.     AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
  108.     // TODO: Add your initialization code here
  109.     return (retCode) ;
  110.   }
  111.  
  112.   virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
  113.     // TODO: Add your code here
  114.     // You *must* call On_kUnloadAppMsg here
  115.     AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
  116.     // TODO: Unload dependencies here
  117.     return (retCode) ;
  118.   }
  119.  
  120.   virtual void RegisterServerComponents () {
  121.   }
  122.  
  123.   static void CurvIntCurveIntSurf () {
  124.     // Put your command code here
  125.     ads_name ename;
  126.     ads_point pickpt;
  127.     AcDbObjectId objId;
  128.     int rc;
  129.     // select a surface
  130.     rc = acedEntSel(L"\nSelect Surface: ", ename, pickpt);
  131.     if(rc != RTNORM)
  132.     {
  133.       if (rc != RTCAN) acutPrintf(L"\nError selecting entity ");
  134.       return;
  135.     }
  136.  
  137.     ads_point p1,p2;
  138.     if (acedGetPoint(NULL,L"\nPoint 1: ", p1) != RTNORM ||
  139.         acedGetPoint(p1  ,L"\nPoint 2: ", p2) != RTNORM) return;
  140.  
  141.     acdbGetObjectId(objId, ename);
  142.     AcDbEntityPointer pObj(objId, AcDb::kForRead);
  143.     if (pObj.openStatus() == Acad::eOk) {
  144.       AcDbSurface* pEntity1 = AcDbSurface::cast(pObj);
  145.       if (!pEntity1) {
  146.         acutPrintf(L"\nSelection Invalid...");
  147.         return;
  148.       }
  149.       // call Intersect
  150.       AcGePoint3dArray points = IntersectRoutine( pEntity1, AcGeLineSeg3d(asPnt3d(p1), asPnt3d(p2)));
  151.       if(points.length() > 0)
  152.       {
  153.         for (int i = 0; i < points.length(); i++) {
  154.           acutPrintf(L"\nPoint(%d) (%g %g %g)", i, points[i].x, points[i].y, points[i].z);
  155.         }
  156.       }
  157.     }
  158.   }
  159. } ;
  160.  
  161. //-----------------------------------------------------------------------------
  162. IMPLEMENT_ARX_ENTRYPOINT(CCurveIntSurfApp)
  163. ACED_ARXCOMMAND_ENTRY_AUTO(CCurveIntSurfApp, CurvInt, CurveIntSurf, CurveIntSurf, ACRX_CMD_MODAL, NULL)

Чертеж для проверки и полный проект прилагаю.


Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Онлайн Александр РивилисАвтор темы

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