ADN Open CIS
Сообщество программистов Autodesk в СНГ

29/05/2013

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

В другой статье, мой коллега Philippe рассказал о получении точки пересечения между плоскостью и отрезком. В этой статье мы увидим, как получить пересечение любой поверхности и отрезка.

ARX даёт нам класс AcGeCurveSurfInt который позволяет получить точки пересечения между 3D-кривой и поверхностью. Конструктор AcGeCurveSurfInt или метод AcGeCurveSurfInt::Set получает в качестве параметров кривую и поверхность. В качестве поверхности требуется экземпляр класса AcGeSurface. Так что нам потребуется получить объект AcGeSurface на основе объекта AcDbSurface. А для этого в качестве промежуточного объекта нам потребуется объект AcBrBrep.

Ниже приведен небольшой пример. Он просит пользователя выбрать поверхность и получает пересечение отрезка (из   (0,0,0) в (0,0,1)) и поверхности.

Примечание: для использования BREP объектов нужны отдельные .h- и .lib-файлы. Их можно найти в каталоге ObjectARX SDK\utils\brep

Код - C++: [Выделить]
  1. static AcGePoint3dArray Intersect(AcDbSurface* pSurface,AcGeLine3d line)
  2. {  
  3.     AcGePoint3dArray returnPtArray; 
  4.   AcDbBody* pBody = new AcDbBody();
  5.  
  6.   // 2013
  7.   // Acad::ErrorStatus es = pBody->setASMBody(pSurface->ASMBodyCopy());
  8.   // До 2013
  9.    Acad::ErrorStatus es = pBody->setBody(pSurface->body());
  10.  
  11.    // build AcBrBrep
  12.    AcBrBrep* pBrep = new AcBrBrep();
  13.    //
  14.   if(AcBr::eOk == pBrep->set(*pBody))
  15.   {
  16.     AcBrBrepFaceTraverser* pFaceTrav = new AcBrBrepFaceTraverser;
  17.     if(AcBr::eOk == pFaceTrav->setBrep(*pBrep))
  18.     {
  19.        for(pFaceTrav->restart(); !pFaceTrav->done(); pFaceTrav->next())
  20.        {
  21.         AcBrFace face;
  22.  
  23.         if(AcBr::eOk == pFaceTrav->getFace(face))
  24.         {
  25.           double area = 0.0f;
  26.          face.getSurfaceArea(area);
  27.  
  28.          acutPrintf(L"\nПлощадь поверхности: %f", area);
  29.  
  30.         //***** полная поверхность Brep-грани******         
  31.         //AcGeNurbSurface nurbSurface;
  32.         //face.getSurfaceAsNurb(nurbSurface);
  33.         //AcGeCurveSurfInt curveSI;
  34.         ////исходные отрезок и поверхность
  35.         //curveSI.set(line,nurbSurface);
  36.         ////подсчитываем число точек пересечения
  37.         //int count = curveSI.numIntPoints(err_1);
  38.         //    if(err_1 == AcGe::kXXOk && count >0 )
  39.         //    {        
  40.         //        AcGeIntersectError err_2;
  41.         //        for(int index = 0 ;index < count; index ++)
  42.         //        {
  43.         //           AcGePoint3d pt =
  44.         //             curveSI.intPoint(index,err_2);       
  45.         //            returnPtArray.append(pt);
  46.         //        }       
  47.         //       
  48.         //    }
  49.         //**********
  50.  
  51.         //****настоящая поверхность AcDbSurface        
  52.           AcGeExternalBoundedSurface** nurbs = NULL;
  53.           Adesk::UInt32 numNurbs = 0;
  54.           face.getSurfaceAsTrimmedNurbs(numNurbs,nurbs);
  55.           //*****
  56.         for (Adesk::UInt32 i = 0; i < numNurbs; i++)
  57.         {
  58.             AcGeCurveSurfInt curveSI;
  59.             AcGeIntersectError  err_1 = AcGe::kXXOk;           
  60.              // исходные поверхность и отрезок
  61.             curveSI.set(line,*nurbs[i]);
  62.             // подсчитываем количество точек пересечения
  63.             int count = curveSI.numIntPoints(err_1);
  64.             if(err_1 == AcGe::kXXOk && count >0 )
  65.             {
  66.                 AcGeIntersectError err_2;
  67.                 for(int index = 0 ;index < count; index ++)
  68.                 {
  69.                     AcGePoint3d pt =
  70.                         curveSI.intPoint(index,err_2);       
  71.                     returnPtArray.append(pt);
  72.                 }       
  73.             }
  74.             delete nurbs[i];
  75.         }
  76.         // вы обязаны удалить массив поверхностей
  77.         delete[] nurbs;
  78.       }
  79.     }
  80.   }
  81.   delete pFaceTrav;
  82.   }
  83.   delete pBrep;
  84.  
  85.  
  86.   return returnPtArray;
  87.  
  88. }
  89. static void getIntersectPts(void)
  90. {
  91.      ads_name ename;
  92.      ads_point pickpt;
  93.  
  94.      AcDbObjectId objId;
  95.      AcDbObject *pObj;
  96.  
  97.      int rc;
  98.  
  99.      // Выберем поверхность
  100.      rc= acedEntSel(L"\nВыберите Поверхность: ", ename, pickpt);
  101.  
  102.      if(rc != RTNORM)
  103.      {
  104.        if (rc != RTCAN)
  105.          acutPrintf(L"\nОшибка выбора примитива ");
  106.       return;
  107.      }
  108.  
  109.      acdbGetObjectId(objId, ename);
  110.      acdbOpenObject(pObj, objId, AcDb::kForRead);
  111.  
  112.      AcDbSurface* pEntity1 = AcDbSurface::cast(pObj);
  113.  
  114.      if(!pEntity1)
  115.      {
  116.           acutPrintf(L"\nВыбор неправильный...");
  117.           pObj->close();
  118.           return;
  119.      }
  120.      // Вызываем функцию Intersect
  121.      AcGePoint3dArray points =
  122.          Intersect(pEntity1,AcGeLine3d(AcGePoint3d(0,0,0),
  123.          AcGePoint3d(0,0,1)));
  124.      if(points.length() >0)
  125.      {
  126.          // Проходим по всем точкам
  127.      }
  128.  
  129.      pObj->close();
  130.  
  131. }

 

Источник: http://adndevblog.typepad.com/autocad/2013/03/intersection-between-a-surface-and-a-line-using-arx.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=59.0

Опубликовано 29.05.2013
Отредактировано 06.06.2013 в 13:21:58