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

01/08/2018

Как сделать вставку точки в разрыв кривой?

Как сделать вставку точки в разрыв кривой?

На форуме мне задали вопрос о том, как можно эмулировать команду  _BREAK и вставлять в разрыв точку? Ниже код, показывающий как используя метод  getSplitCurves можно добиться результата.

Код - C++: [Выделить]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.cpp
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #include "resource.h"
  6.  
  7. //-----------------------------------------------------------------------------
  8. #define szRDS _RXST("")
  9.  
  10. //-----------------------------------------------------------------------------
  11. //----- ObjectARX EntryPoint
  12. class CBreakLineApp : public AcRxArxApp {
  13.  
  14. public:
  15.   CBreakLineApp() : AcRxArxApp() {}
  16.  
  17.   virtual AcRx::AppRetCode On_kInitAppMsg(void *pkt) {
  18.     AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg(pkt);
  19.     return (retCode);
  20.   }
  21.  
  22.   virtual AcRx::AppRetCode On_kUnloadAppMsg(void *pkt) {
  23.     AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg(pkt);
  24.     return (retCode);
  25.   }
  26.  
  27.   virtual void RegisterServerComponents() {    }
  28.  
  29.   //////////////////////////////////////////////////////////////////////////
  30.   //                  Adding entity to Database
  31.   //////////////////////////////////////////////////////////////////////////
  32.   static Acad::ErrorStatus postToDwg(AcDbEntity *pEnt, AcDbDatabase *pDb = NULL, ACHAR *requiredSpace = NULL)
  33.   {
  34.     Acad::ErrorStatus es;
  35.  
  36.     if (pDb == NULL) pDb = acdbCurDwg();
  37.  
  38.     AcDbBlockTableRecordPointer blockTableRecord;
  39.  
  40.     if (requiredSpace)
  41.     {
  42.       es = blockTableRecord.open(requiredSpace, pDb, AcDb::kForWrite);
  43.     }
  44.     else
  45.     {
  46.       es = blockTableRecord.open(pDb->currentSpaceId(), AcDb::kForWrite);
  47.     }
  48.     if (es != Acad::eOk)
  49.       return (es);
  50.     es = blockTableRecord->appendAcDbEntity(pEnt);
  51.     return (es);
  52.   }
  53.  
  54.  
  55.   static void RivilisBreakLine()
  56.   {
  57.     ads_name en;
  58.     AcGePoint3d p;
  59.     Acad::ErrorStatus es = Acad::eOk;
  60.     //////////////////////////////////////////////////////////////////////////
  61.     //                       Расчет длины зазора
  62.     //////////////////////////////////////////////////////////////////////////
  63.     resbuf rb;
  64.     acedGetVar(_ACRX_T("PDSIZE"), &rb);
  65.     double radius = rb.resval.rreal * 0.5;
  66.     // Если PDSIZE = 0, то это 5 процентов от высоты вида
  67.     if (radius < 1e-12 && radius > -1e-12)
  68.       radius = -5.0;
  69.     // Если PDSIZE < 0, то это процент от высоты вида
  70.     if (radius <= 1e-12)
  71.     {
  72.       acedGetVar(_ACRX_T("VIEWSIZE"), &rb);
  73.       radius = -radius * rb.resval.rreal / 100.0;
  74.     }
  75.     //////////////////////////////////////////////////////////////////////////
  76.     if (acedEntSel(L"\nВыберите кривую в точке разрыва: ", en, asDblArray(p)) == RTNORM)
  77.     {
  78.       AcDbObjectId idCurve; acdbGetObjectId(idCurve, en);
  79.       AcDbObjectPointer<AcDbCurve> pCurve(idCurve, AcDb::kForRead);
  80.       if ((es = pCurve.openStatus()) != Acad::eOk)
  81.       {
  82.         acutPrintf(L"\nОшибка открытия кривой: %s", acadErrorStatusText(es));
  83.         return;
  84.       }
  85.       AcGeDoubleArray pts;
  86.       AcGePoint3d pNear = p;  pCurve->getClosestPointTo(p, pNear);
  87.       AcDbPoint *pDbPoint = new AcDbPoint(pNear);
  88.       pDbPoint->setDatabaseDefaults();
  89.       postToDwg(pDbPoint);
  90.       pDbPoint->close();
  91.  
  92.       if (es == Acad::eOk)
  93.       {
  94.         AcDbCircle *pCircle = new AcDbCircle(p, AcGeVector3d::kZAxis, radius);
  95.         AcGePlane plane(p, AcGeVector3d::kZAxis);
  96.         AcGePoint3dArray ptsInts;
  97.         pCurve->intersectWith(pCircle, AcDb::kOnBothOperands, plane, ptsInts);
  98.         delete pCircle;
  99.         if (ptsInts.length() >= 2)
  100.         {
  101.           AcGePoint3d ptFirst = ptsInts[0], ptLast = ptsInts[ptsInts.length() - 1];
  102.           pCurve->getClosestPointTo(ptsInts[0], ptFirst);
  103.           pCurve->getClosestPointTo(ptsInts[ptsInts.length() - 1], ptLast);
  104.           double paramFirst = 0, paramLast = 0;
  105.           pCurve->getParamAtPoint(ptFirst, paramFirst);
  106.           pCurve->getParamAtPoint(ptLast, paramLast);
  107.           if (paramFirst > paramLast)
  108.           {
  109.             pts.append(paramLast);
  110.             pts.append(paramFirst);
  111.           }
  112.           else
  113.           {
  114.             pts.append(paramFirst);
  115.             pts.append(paramLast);
  116.           }
  117.         }
  118.         else
  119.         {
  120.           double param = 0; pCurve->getParamAtPoint(pNear, param);
  121.           pts.append(param);
  122.         }
  123.       }
  124.       else
  125.       {
  126.         double param = 0;
  127.         pCurve->getParamAtPoint(pNear, param);
  128.         pts.append(param);
  129.       }
  130.  
  131.       AcDbVoidPtrArray aSegs;
  132.       if ((es = pCurve->getSplitCurves(pts, aSegs)) != Acad::eOk)
  133.       {
  134.         acutPrintf(L"\npCurve->getSplitCurves: %s", acadErrorStatusText(es));
  135.         return;
  136.       }
  137.       if (aSegs.length() > 1)
  138.       {
  139.         AcDbEntity *pEnt = reinterpret_cast<AcDbEntity *>(aSegs[0]);
  140.         if (postToDwg(pEnt) == Acad::eOk)
  141.           pEnt->close();
  142.         else             
  143.           delete pEnt;
  144.        
  145.         pEnt = reinterpret_cast<AcDbEntity *>(aSegs[aSegs.length() - 1]);
  146.  
  147.         if (postToDwg(pEnt) == Acad::eOk)
  148.           pEnt->close();
  149.         else             
  150.           delete pEnt;
  151.         // Освобождаем память вырезанных сегментов
  152.         for (int i = 1; i < aSegs.length() - 1; i++)
  153.         {
  154.           AcDbEntity *pEnt = reinterpret_cast<AcDbEntity *>(aSegs[i]);
  155.           delete pEnt;
  156.         }
  157.         // Удаляем исходную кривую
  158.         if (pCurve->upgradeOpen() == Acad::eOk)
  159.           pCurve->erase();
  160.       }
  161.     }
  162.   }
  163. };
  164.  
  165. //-----------------------------------------------------------------------------
  166. IMPLEMENT_ARX_ENTRYPOINT(CBreakLineApp)
  167.  
  168. ACED_ARXCOMMAND_ENTRY_AUTO(CBreakLineApp, Rivilis, BreakLine, BreakLine, ACRX_CMD_MODAL, NULL)
  169.  

Так выглядит работа этого кода:

 

Автор: Александр Ривилис

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

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