21/10/2016
Как в ObjectARX выбрать грани 3DSOLID и изменить им цвет
Оказалось, что на такой, казалось бы простой и распространенный вопрос найти примера в интернете не удается. Более того несколько функций, которые я использовал для решения этой задачи входят в состав ObjectARX SDK начиная с версии 2008, но никогда ни в одном примере не фигурировали. Есть готовые примеры как найти выбранную грань 3DSOLID, но они очень громоздки, зависят от ПСК, точки зрения, точки указания и т.д. В этом же примере всё очень просто и лаконично и основывается на функции обычного выбора примитивов acedSSGet:
Код - C++: [Выделить]
- //-----------------------------------------------------------------------------
- //----- acrxEntryPoint.cpp
- //-----------------------------------------------------------------------------
- #include "StdAfx.h"
- #include <acedsubsel.h>
- #include "resource.h"
- //-----------------------------------------------------------------------------
- #define szRDS _RXST("")
- //-----------------------------------------------------------------------------
- //----- ObjectARX EntryPoint
- class CTestSSgetSubentApp : public AcRxArxApp {
- public:
- CTestSSgetSubentApp() : 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 RivilisChangeFaceColor() {
- ads_name ss;
- // Позволяем выбирать только грани
- AcArray<SubentType> subTypes; subTypes.append(kFaceSubentType);
- acedSSSetSubentTypes(subTypes);
- // Просим у пользователя выбрать грани 3DSolid
- resbuf *filter = acutBuildList(RTDXF0, _T("3DSOLID"), 0);
- if (acedSSGet(_T("_:V"), nullptr, nullptr, filter, ss) == RTNORM)
- {
- Adesk::Int32 nEnts = 0;
- Adesk::Int32 nSubs = 0;
- acedSSLength(ss, &nEnts);
- for (int i = 0; i < nEnts; i++)
- {
- acedSSSubentLength(ss, i, &nSubs);
- for (int j = 0; j < nSubs; j++)
- {
- AcDbFullSubentPath path;
- acedSSSubentName(ss, i, j, path);
- AcDbObjectId id = path.objectIds()[0];
- AcDbObjectPointer<AcDb3dSolid> pSolid(id, AcDb::kForWrite);
- if (pSolid.openStatus() == Acad::eOk) {
- // Поменяем цвет выбранной грани на красный
- AcCmColor cm; cm.setColorIndex(1);
- pSolid->setSubentColor(path.subentId(), cm);
- }
- }
- }
- acedSSFree(ss);
- }
- acutRelRb(filter);
- }
- };
- //-----------------------------------------------------------------------------
- IMPLEMENT_ARX_ENTRYPOINT(CTestSSgetSubentApp)
- ACED_ARXCOMMAND_ENTRY_AUTO(CTestSSgetSubentApp, Rivilis, ChangeFaceColor, ChangeFaceColor, ACRX_CMD_MODAL, NULL)
Так выглядит работа команды ChangeFaceColor:
Хотел бы обратить внимание на то, что можно выбирать грани сразу у нескольких 3DSOLID.
Автор: Александр Ривилис
Обсуждение: http://adn-cis.org/forum/index.php?topic=7401
Опубликовано 21.10.2016