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

ADN Club => ObjectARX => Тема начата: begiz от 22-02-2017, 10:52:13

Название: работа с Material Browser
Отправлено: begiz от 22-02-2017, 10:52:13
Добрового времени суток.
Возник вопрос можно ли как то обрататывать event связаные с Material Browser.
например Drag'n'Drop и перед применением материала получить объект на который материал закидывается или точку куда кидается.
Цель такая, если материал кидается на неподдерживаемый объект, например HATCH, выдернуть из него контур и сделать поверхность к которой применить материал.
Возможно ли такое?
Название: Re: работа с Material Browser
Отправлено: Александр Ривилис от 22-02-2017, 12:44:54
Возник вопрос можно ли как то обрататывать event связаные с Material Browser.
У него таких событий/реакторов нет. При перетаскивании материала возникает событие команды #MATERIALOPERATION (это видно в событии Document Lock Mode Changed: AcApDocManagerReactor::documentLockModeChanged) и можно получить объект на который бросили в событии AcEdInputContextReactor::endSSGet, а точку при помощи AcEdInputPointMonitor::monitorInputPoint.
Материал, который был выбран и перетаскивается, можно определить по AcDbMaterial, который добавляется в базу:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F102548%2F7842324.7%2F0_14f765_9c411ab2_orig.png&hash=20c94a2831fecb374038d4b4378032d5)
Так что придётся подписаться еще и на события AcDbDatabaseReactor::objectAppended/AcDbDatabaseReactor::objectModified и отследить последний AcDbMaterial.

Название: Re: работа с Material Browser
Отправлено: Александр Ривилис от 22-02-2017, 12:54:34
Кстати, при присвоении материала штриховке (AcDbHatch) она в действительности присваивается (!!!), хотя в Панели свойств (OPM) это нигде не видно:


 
Название: Re: работа с Material Browser
Отправлено: begiz от 22-02-2017, 14:52:19
Спасибо,
решение с реакторами работает как надо, но я чуток сделал по другому, может так правильней?
Код - C++ [Выбрать]
  1. void CSSFiltrR::endSSGet(Acad::PromptStatus returnStatus, int ssgetFlags, AcEdSelectionSetService & service, const AcDbObjectIdArray& selectionSet)
  2. {
  3. //тут stage это флаг из
  4. //void CDocManR::documentLockModeChanged(AcApDocument* pDoc, AcAp::DocLockMode myPreviousMode, AcAp::DocLockMode myCurrentMode, AcAp::DocLockMode currentMode, const ACHAR* //pGlobalCmdName)
  5. //{
  6. //      if(_tcscmp(pGlobalCmdName,_T("#MATERIALOPERATION"))==0)
  7. //      {
  8. //              stage = 1;
  9. //      }
  10. //      AcApDocManagerReactor::documentLockModeChanged(pDoc,myPreviousMode,myCurrentMode,currentMode,pGlobalCmdName);
  11. //}
  12.         if(stage==1)  
  13.         {
  14.                 for(int i = 0; i < selectionSet.length(); i++)
  15.                 {
  16.                         if(selectionSet.at(i).objectClass()->name() == AcDbHatch::desc()->name())
  17.                         {
  18.                                 Acad::ErrorStatus es;
  19.  
  20.                                 CString lr;
  21.                                 int clr = 0;
  22.                                 AcDbObjectPointer<AcDbHatch> pHatch(selectionSet.at(i),AcDb::kForRead);
  23.                                 if(pHatch.openStatus()==Acad::eOk)
  24.                                 {
  25.                                         AcDbRegion * pReg = pHatch->getRegionArea();
  26.                                         lr = pHatch->layer();
  27.                                         clr = pHatch->colorIndex();
  28.                                         pHatch->close();
  29.  
  30.                                         AcDbObjectId surfId;
  31.  
  32.                                         if(pReg!=NULL)
  33.                                         {
  34.                                                 AcDbPlaneSurface * pMainSurf = new AcDbPlaneSurface();
  35.                                                 pMainSurf->setLayer(lr);
  36.                                                 pMainSurf->setColorIndex(clr);
  37.                                                 pMainSurf->createFromRegion(pReg);
  38.                                                 pMainSurf->setMaterial(materialId);
  39.                                                 acDocManager->lockDocument(curDoc());
  40.                                                 surfId = addToDataBase(pMainSurf);
  41.                                                 acDocManager->unlockDocument(curDoc());
  42.                                                 pMainSurf->close();
  43.                                         }
  44.  
  45.                                         ads_name ename;
  46.                                         acdbGetAdsName(ename,surfId);
  47.  
  48.                                         resbuf *pBuf = acutBuildList(RTLB,RTSHORT,0,RTENAME,ename,RTSHORT,0,RTLE,RTNONE);
  49.  
  50.                                         es = service.remove(i);
  51.                                         es = service.add(pBuf);
  52.                        
  53.                                         acutRelRb(pBuf);
  54.                                 }
  55.                         }
  56.                 }
  57.                 stage = 0;
  58.         }
  59.         AcEdSSGetFilter::endSSGet(returnStatus,ssgetFlags,service,selectionSet);
  60. }
  61.  
Название: Re: работа с Material Browser
Отправлено: Александр Ривилис от 22-02-2017, 19:37:56
1. Прочти у меня в подписи по поводу правильного форматирования кода на форуме и соблюдай его.
2. Мне не нравится модификация базы в реакторе endSSGet, но если у тебя этот код работает и не приводит ни к каким проблемам, то можешь его использовать.
3. Обрати внимание, на то, что вчера написал Николай Горлов по поводу AcDbHatch::getRegionArea (http://adn-cis.org/forum/index.php?topic=7647.0) (т.е. если плоскость штриховки не совпадает с плоскостью X0Y МСК (WCS) этот метод возвращает неправильный AcDbRegion и его следует трансформировать).