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

10/03/2014

Получение изолиний поверхности (Surface)

Это пример кода получающий изолинии вдоль направлений U и V поверхности. Полученные кривые изолиний добавляются в базу данных чертежа.

Код - C++: [Выделить]
  1. // 1) Включаем поддержку BRep API в StdAfx.h
  2. #define _BREP_SUPPORT_            //- Поддержка BRep API
  3.  
  4. // 2) Код получения изолиний поверхности
  5. Acad::ErrorStatus es;
  6.  
  7. ads_point pt;
  8. ads_name ename;
  9. if (RTNORM != acedEntSel(L"\nВыберите поверхность: ", ename, pt))
  10.     return;
  11.  
  12. AcDbEntity *pEnt = NULL;
  13. AcDbObjectId id;
  14. es = acdbGetObjectId(id, ename);
  15. es = acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite);
  16. AcDbSurface *pSurface = AcDbSurface::cast(pEnt);
  17. if(NULL == pSurface)
  18. {
  19.     acutPrintf(ACRX_T("\nПожалуйста выберите поверхность."));
  20.     return;
  21. }
  22.  
  23. AcDbNurbSurfaceArray nsArray;
  24. es = pSurface->convertToNurbSurface(nsArray);
  25. if(es == Acad::eOk)
  26. {
  27.     if(nsArray.length() == 1)
  28.     {
  29.         AcDbDatabase *pDb
  30.             = acdbHostApplicationServices()->workingDatabase();
  31.  
  32.         AcDbBlockTable *pBlockTable = NULL;
  33.         es = pDb->getBlockTable(pBlockTable, AcDb::kForRead);
  34.  
  35.         AcDbBlockTableRecord *pMS = NULL;
  36.         es = pBlockTable->getAt(
  37.                        ACDB_MODEL_SPACE, pMS, AcDb::kForWrite);
  38.  
  39.         AcDbNurbSurface *pNS = NULL;
  40.         pNS = AcDbNurbSurface::cast(nsArray.at(0));
  41.  
  42.         Adesk::UInt16 uIsoDensity = pSurface->uIsolineDensity();
  43.         Adesk::UInt16 vIsoDensity = pSurface->vIsolineDensity();
  44.  
  45.         AcDbBody* pBody = new AcDbBody();
  46.  
  47.         es = pBody->setASMBody(pSurface->getLockedASMBody());
  48.  
  49.         AcBr::ErrorStatus ebs;
  50.         AcBrBrep* pBrep = new AcBrBrep();
  51.         ebs = pBrep->set(*pBody);
  52.         if(AcBr::eOk == ebs)
  53.         {
  54.             AcBrBrepFaceTraverser* pFaceTrav
  55.                                 = new AcBrBrepFaceTraverser;
  56.             ebs = pFaceTrav->setBrep(*pBrep);
  57.             if(AcBr::eOk == ebs)
  58.             {
  59.                 for(pFaceTrav->restart();
  60.                         !pFaceTrav->done();pFaceTrav->next())
  61.                 {
  62.                     AcBrFace face;
  63.                     ebs = pFaceTrav->getFace(face);
  64.                     if(AcBr::eOk == ebs)
  65.                     {
  66.                         AcGeSurface *pGeSurface;
  67.                         ebs = face.getSurface(pGeSurface);
  68.  
  69.                         Adesk::Boolean isClosedInU
  70.                                   = pGeSurface->isClosedInU();
  71.  
  72.                         Adesk::Boolean isClosedInV
  73.                                   = pGeSurface->isClosedInV();
  74.  
  75.                         int ucMax = uIsoDensity+2;
  76.                         if(isClosedInU)
  77.                             ucMax = uIsoDensity;
  78.  
  79.                         int vcMax = vIsoDensity+2;
  80.                         if(isClosedInV)
  81.                             vcMax = vIsoDensity;
  82.  
  83.                         AcGeInterval intervalU, intervalV;
  84.                         pGeSurface->getEnvelope
  85.                                        (intervalU, intervalV);
  86.  
  87.                         double boundMinU = 0.0,
  88.                                boundMaxU = 0.0,
  89.                                boundMinV = 0.0,
  90.                                boundMaxV = 0.0;
  91.  
  92.                         intervalU.getBounds
  93.                                        (boundMinU, boundMaxU);
  94.  
  95.                         intervalV.getBounds
  96.                                        (boundMinV, boundMaxV);
  97.  
  98.                         double paramIncrU =
  99.                         (boundMaxU - boundMinU) /
  100.                         (isClosedInU ? uIsoDensity :
  101.                                        (uIsoDensity+1));
  102.  
  103.                         double paramIncrV =
  104.                         (boundMaxV - boundMinV) /
  105.                         (isClosedInV ? vIsoDensity :
  106.                                        (vIsoDensity+1));
  107.  
  108.                         double paramU = boundMinU;
  109.                         for(int uc = 0; uc < ucMax; uc++)
  110.                         {
  111.                             double paramV = boundMinV;
  112.                             for(int vc = 0; vc < vcMax; vc++)
  113.                             {
  114.                                 AcArray<AcDbCurve*> uIsoLines;
  115.                                 es = pNS->getIsolineAtU(
  116.                                            paramU, uIsoLines);
  117.  
  118.                                 if(es == Acad::eOk)
  119.                                 {
  120.                                     for(int cnt = 0;
  121.                                         cnt < uIsoLines.length();
  122.                                         cnt++)
  123.                                     {
  124.                                         AcDbCurve *pCurve
  125.                                             = uIsoLines[cnt];
  126.  
  127.                                         pCurve->setColorIndex(1);
  128.  
  129.                                         pMS->appendAcDbEntity
  130.                                                      (pCurve);
  131.  
  132.                                         pCurve->close();
  133.                                     }
  134.                                 }
  135.  
  136.                                 AcArray<AcDbCurve*> vIsoLines;
  137.                                 es = pNS->getIsolineAtV(
  138.                                            paramV, vIsoLines);
  139.  
  140.                                 if(es == Acad::eOk)
  141.                                 {
  142.                                     for(int cnt = 0;
  143.                                         cnt < vIsoLines.length();
  144.                                         cnt++)
  145.                                     {
  146.                                         AcDbCurve *pCurve
  147.                                              = vIsoLines[cnt];
  148.  
  149.                                         pCurve->setColorIndex(1);
  150.  
  151.                                         pMS->appendAcDbEntity
  152.                                                      (pCurve);
  153.  
  154.                                         pCurve->close();
  155.                                     }
  156.                                 }
  157.  
  158.                                 paramV += paramIncrV;
  159.                             }
  160.                             paramU += paramIncrU;
  161.                         }
  162.                     }
  163.                     else
  164.                     {
  165.                         acutPrintf(
  166.                               ACRX_T("\nИзвините, ошибка BRep."));
  167.  
  168.                         break;
  169.                     }
  170.                 }
  171.             }
  172.             else
  173.             {
  174.                 acutPrintf(ACRX_T("\nИзвините, ошибка BRep."));
  175.             }
  176.  
  177.             delete pFaceTrav;
  178.         }
  179.         else
  180.         {
  181.            acutPrintf(ACRX_T("\nИзвините, ошибка BRep."));
  182.         }
  183.  
  184.         delete pBrep;
  185.  
  186.         es = pMS->close();
  187.         es = pBlockTable->close();
  188.     }
  189.     else
  190.     {
  191.         acutPrintf(ACRX_T("\nзвините, но этот код не может пока обработать
  192.                                несколько Nurb-поверхностей."));
  193.     }
  194.  
  195.     // Очистка
  196.     for(int cnt = 0; cnt < nsArray.length(); cnt++)
  197.     {
  198.         AcDbNurbSurface *pNS = NULL;
  199.         pNS = AcDbNurbSurface::cast(nsArray.at(cnt));
  200.         if(pNS != NULL)
  201.         {
  202.             delete pNS;
  203.         }
  204.     }
  205. }
  206. else
  207. {
  208.     acutPrintf(
  209.         ACRX_T("\nНевозможно преобразовать в Nurb-поверхность."));
  210. }
  211.  
  212. pSurface->close();

Это картинка изолиний полученных из поверхности вращения:

 

 

Источник: http://adndevblog.typepad.com/autocad/2014/03/extracting-isolines-from-surface.html

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

Опубликовано 10.03.2014