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

09/12/2021

Как создать конус средствами ObjectARX , который можно было бы редактировать

Вопрос: Если создавать конус при помощи команды КОНУС (_CONE), то конус создаётся параметрическим – у него есть ручки и в свойствах этого 3DSOLID видно, что это конус и у него есть параметры (радиусы и высота). Если же я использую для создания конуса метод AcDb3dSolid:: createFrustum, то конус создаётся не параметрическим и его можно только переносить, но не изменять параметрически. Как средствами ObjectARX можно воспроизвести поведение команды Конус.

Ответ: Для этой цели достаточно включить запись истории редактирования 3DSOLID. Ниже приведён полный пример кода, который это проделывает:

Код - C++: [Выделить]
  1.  
  2. //-----------------------------------------------------------------------------
  3. //----- acrxEntryPoint.cpp
  4. //-----------------------------------------------------------------------------
  5. #include "StdAfx.h"
  6. #include "resource.h"
  7.  
  8. //-----------------------------------------------------------------------------
  9. #define szRDS _RXST("")
  10.  
  11. //-----------------------------------------------------------------------------
  12. //----- ObjectARX EntryPoint
  13. class CCreateConeWithHistoryApp : public AcRxArxApp {
  14.  
  15. public:
  16.   CCreateConeWithHistoryApp() : AcRxArxApp() {}
  17.  
  18.   virtual AcRx::AppRetCode On_kInitAppMsg(void* pkt) {
  19.     AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg(pkt);
  20.     return (retCode);
  21.   }
  22.  
  23.   virtual AcRx::AppRetCode On_kUnloadAppMsg(void* pkt) {
  24.     AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg(pkt);
  25.     return (retCode);
  26.   }
  27.  
  28.   virtual void RegisterServerComponents() {  }
  29.  
  30.  
  31.   static void RivilisCreateConeWithHistory()
  32.   {
  33.     AcGePoint3d pCenter, pVertex;
  34.     if (acedGetPoint(NULL, L"\nЦентр основания: ", asDblArray(pCenter)) != RTNORM)
  35.       return;
  36.     if (acedGetPoint(asDblArray(pCenter), L"\nВершина конуса: ", asDblArray(pVertex)) != RTNORM)
  37.       return;
  38.     double radius = 0;
  39.     acedInitGet(RSG_NONEG | RSG_NOZERO, NULL);
  40.     if (acedGetDist(asDblArray(pCenter), L"\nРадиус основания: ", &radius) != RTNORM)
  41.       return;
  42.  
  43.     AcGeMatrix3d matUCS; acedGetCurrentUCS(matUCS);
  44.  
  45.     pCenter = pCenter.transformBy(matUCS);  pVertex = pVertex.transformBy(matUCS);
  46.    
  47.     AcGeVector3d vZnew = (pVertex - pCenter).normal();
  48.     double height = pVertex.distanceTo(pCenter);
  49.     AcGeMatrix3d matTrans; matTrans.setToTranslation(AcGeVector3d::kZAxis * 0.5 * height);
  50.     AcGeVector3d vXnew = vZnew.perpVector().normal();
  51.     AcGeVector3d vYnew = vXnew.crossProduct(vZnew).normal();
  52.  
  53.     AcGeMatrix3d matAlign = AcGeMatrix3d::alignCoordSys(
  54.       AcGePoint3d::kOrigin, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis,
  55.       pCenter, vXnew, vYnew, vZnew);
  56.     AcDbBlockTableRecordPointer pCurSpace(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
  57.     AcDbObjectPointer<AcDb3dSolid> pSol; pSol.create();
  58.    
  59.     // Включаем запись истории, что автоматически позволяет редактировать конус
  60.     pSol->setRecordHistory(true); pSol->setShowHistory(true);
  61.  
  62.     pSol->createFrustum(height, radius, radius, 0.0);
  63.     pSol->transformBy(matAlign*matTrans);
  64.     pCurSpace->appendAcDbEntity(pSol);
  65.   }
  66. };
  67.  
  68. //-----------------------------------------------------------------------------
  69. IMPLEMENT_ARX_ENTRYPOINT(CCreateConeWithHistoryApp)
  70.  
  71. ACED_ARXCOMMAND_ENTRY_AUTO(CCreateConeWithHistoryApp, Rivilis, CreateConeWithHistory, CCWH, ACRX_CMD_MODAL, NULL)
  72.  

Автор: Александр Ривилис
Опубликовано 09.12.2021