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

21/10/2016

Как в ObjectARX выбрать грани 3DSOLID и изменить им цвет

Оказалось, что на такой, казалось бы простой и распространенный вопрос найти примера в интернете не удается. Более того несколько функций, которые я использовал для решения этой задачи входят в состав ObjectARX SDK начиная с версии 2008, но никогда ни в одном примере не фигурировали. Есть готовые примеры как найти выбранную грань 3DSOLID, но они очень громоздки, зависят от ПСК, точки зрения, точки указания и т.д. В этом же примере всё очень просто и лаконично и основывается на функции обычного выбора примитивов acedSSGet:

Код - C++: [Выделить]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.cpp
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #include <acedsubsel.h>
  6. #include "resource.h"
  7.  
  8. //-----------------------------------------------------------------------------
  9. #define szRDS _RXST("")
  10.  
  11. //-----------------------------------------------------------------------------
  12. //----- ObjectARX EntryPoint
  13. class CTestSSgetSubentApp : public AcRxArxApp {
  14.  
  15. public:
  16.   CTestSSgetSubentApp() : 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.   static void RivilisChangeFaceColor() {
  31.     ads_name ss;
  32.     // Позволяем выбирать только грани
  33.     AcArray<SubentType> subTypes; subTypes.append(kFaceSubentType);
  34.     acedSSSetSubentTypes(subTypes);
  35.     // Просим у пользователя выбрать грани 3DSolid
  36.     resbuf *filter = acutBuildList(RTDXF0, _T("3DSOLID"), 0);
  37.     if (acedSSGet(_T("_:V"), nullptr, nullptr, filter, ss) == RTNORM)
  38.     {
  39.       Adesk::Int32 nEnts = 0;
  40.       Adesk::Int32 nSubs = 0;
  41.       acedSSLength(ss, &nEnts);
  42.       for (int i = 0; i < nEnts; i++)
  43.       {
  44.         acedSSSubentLength(ss, i, &nSubs);
  45.         for (int j = 0; j < nSubs; j++)
  46.         {
  47.           AcDbFullSubentPath path;
  48.           acedSSSubentName(ss, i, j, path);
  49.           AcDbObjectId id = path.objectIds()[0];
  50.           AcDbObjectPointer<AcDb3dSolid> pSolid(id, AcDb::kForWrite);
  51.           if (pSolid.openStatus() == Acad::eOk) {
  52.             // Поменяем цвет выбранной грани на красный
  53.             AcCmColor cm; cm.setColorIndex(1);
  54.             pSolid->setSubentColor(path.subentId(), cm);
  55.           }
  56.         }
  57.       }
  58.       acedSSFree(ss);
  59.     }
  60.     acutRelRb(filter);
  61.   }
  62. };
  63.  
  64. //-----------------------------------------------------------------------------
  65. IMPLEMENT_ARX_ENTRYPOINT(CTestSSgetSubentApp)
  66.  
  67. 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