09/12/2021
Как создать конус средствами ObjectARX , который можно было бы редактировать
Вопрос: Если создавать конус при помощи команды КОНУС (_CONE), то конус создаётся параметрическим – у него есть ручки и в свойствах этого 3DSOLID видно, что это конус и у него есть параметры (радиусы и высота). Если же я использую для создания конуса метод AcDb3dSolid:: createFrustum, то конус создаётся не параметрическим и его можно только переносить, но не изменять параметрически. Как средствами ObjectARX можно воспроизвести поведение команды Конус.
Ответ: Для этой цели достаточно включить запись истории редактирования 3DSOLID. Ниже приведён полный пример кода, который это проделывает:
Код - C++: [Выделить]
- //-----------------------------------------------------------------------------
- //----- acrxEntryPoint.cpp
- //-----------------------------------------------------------------------------
- #include "StdAfx.h"
- #include "resource.h"
- //-----------------------------------------------------------------------------
- #define szRDS _RXST("")
- //-----------------------------------------------------------------------------
- //----- ObjectARX EntryPoint
- class CCreateConeWithHistoryApp : public AcRxArxApp {
- public:
- CCreateConeWithHistoryApp() : AcRxArxApp() {}
- virtual AcRx::AppRetCode On_kInitAppMsg(void* pkt) {
- AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg(pkt);
- return (retCode);
- }
- virtual AcRx::AppRetCode On_kUnloadAppMsg(void* pkt) {
- AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg(pkt);
- return (retCode);
- }
- virtual void RegisterServerComponents() { }
- static void RivilisCreateConeWithHistory()
- {
- AcGePoint3d pCenter, pVertex;
- if (acedGetPoint(NULL, L"\nЦентр основания: ", asDblArray(pCenter)) != RTNORM)
- return;
- if (acedGetPoint(asDblArray(pCenter), L"\nВершина конуса: ", asDblArray(pVertex)) != RTNORM)
- return;
- double radius = 0;
- acedInitGet(RSG_NONEG | RSG_NOZERO, NULL);
- if (acedGetDist(asDblArray(pCenter), L"\nРадиус основания: ", &radius) != RTNORM)
- return;
- AcGeMatrix3d matUCS; acedGetCurrentUCS(matUCS);
- pCenter = pCenter.transformBy(matUCS); pVertex = pVertex.transformBy(matUCS);
- AcGeVector3d vZnew = (pVertex - pCenter).normal();
- double height = pVertex.distanceTo(pCenter);
- AcGeMatrix3d matTrans; matTrans.setToTranslation(AcGeVector3d::kZAxis * 0.5 * height);
- AcGeVector3d vXnew = vZnew.perpVector().normal();
- AcGeVector3d vYnew = vXnew.crossProduct(vZnew).normal();
- AcGeMatrix3d matAlign = AcGeMatrix3d::alignCoordSys(
- AcGePoint3d::kOrigin, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis,
- pCenter, vXnew, vYnew, vZnew);
- AcDbBlockTableRecordPointer pCurSpace(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
- AcDbObjectPointer<AcDb3dSolid> pSol; pSol.create();
- // Включаем запись истории, что автоматически позволяет редактировать конус
- pSol->setRecordHistory(true); pSol->setShowHistory(true);
- pSol->createFrustum(height, radius, radius, 0.0);
- pSol->transformBy(matAlign*matTrans);
- pCurSpace->appendAcDbEntity(pSol);
- }
- };
- //-----------------------------------------------------------------------------
- IMPLEMENT_ARX_ENTRYPOINT(CCreateConeWithHistoryApp)
- ACED_ARXCOMMAND_ENTRY_AUTO(CCreateConeWithHistoryApp, Rivilis, CreateConeWithHistory, CCWH, ACRX_CMD_MODAL, NULL)
Автор: Александр Ривилис
Опубликовано 09.12.2021
Опубликовано 09.12.2021