Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into CEA_2019
[modules/shaper.git] / src / PartSet / PartSet_CustomPrs.cpp
1 // Copyright (C) 2014-2019  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "PartSet_CustomPrs.h"
21 #include "PartSet_Module.h"
22 #include "PartSet_OperationPrs.h"
23 #include "PartSet_OverconstraintListener.h"
24 #include "PartSet_SketcherMgr.h"
25
26 #include <XGUI_ModuleConnector.h>
27 #include <XGUI_Workshop.h>
28 #include <XGUI_Displayer.h>
29
30 #include <ModuleBase_IWorkshop.h>
31 #include <ModuleBase_IViewer.h>
32 #include <ModuleBase_Tools.h>
33
34 #include <ModelAPI_Tools.h>
35 #include <SketchPlugin_Sketch.h>
36
37 #include <Config_PropManager.h>
38 #include <Events_Loop.h>
39 #include <ModelAPI_Events.h>
40
41 #include <AIS_InteractiveContext.hxx>
42 #include <AIS_InteractiveObject.hxx>
43 #include <Prs3d_PointAspect.hxx>
44
45 //#define DO_NOT_VISUALIZE_CUSTOM_PRESENTATION
46
47 PartSet_CustomPrs::PartSet_CustomPrs(ModuleBase_IWorkshop* theWorkshop)
48   : myWorkshop(theWorkshop), myFeature(FeaturePtr()), myPresentationIsEmpty(false),
49   myDisabledMode(-1)
50 {
51   Events_Loop* aLoop = Events_Loop::loop();
52   aLoop->registerListener(this, Events_Loop::eventByName(EVENT_EMPTY_OPERATION_PRESENTATION));
53
54   initPresentation(ModuleBase_IModule::CustomizeArguments);
55   initPresentation(ModuleBase_IModule::CustomizeResults);
56   initPresentation(ModuleBase_IModule::CustomizeHighlightedObjects);
57
58   myIsActive[ModuleBase_IModule::CustomizeArguments] = false;
59   myIsActive[ModuleBase_IModule::CustomizeResults] = false;
60   myIsActive[ModuleBase_IModule::CustomizeHighlightedObjects] = false;
61 }
62
63 bool PartSet_CustomPrs::isActive(const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag)
64 {
65   return myIsActive[theFlag];
66 }
67
68 bool PartSet_CustomPrs::activate(const FeaturePtr& theFeature,
69                                  const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag,
70                                  const bool theUpdateViewer)
71 {
72 #ifdef DO_NOT_VISUALIZE_CUSTOM_PRESENTATION
73   return false;
74 #endif
75   bool isModified = false;
76
77   // Do not call customisation for sketcher and all its sub-objects
78   if (theFeature->getKind() == SketchPlugin_Sketch::ID())
79     return isModified;
80
81   FeaturePtr aParent = ModelAPI_Tools::compositeOwner(theFeature);
82   if (aParent.get()) {
83     std::string aType = aParent->getKind();
84     if (aType == SketchPlugin_Sketch::ID())
85       return isModified;
86   }
87
88   if (theFeature.get()) {
89     myIsActive[theFlag] = true;
90     myFeature = theFeature;
91     displayPresentation(theFlag, theUpdateViewer);
92     isModified = true;
93   }
94   return isModified;
95 }
96
97 bool PartSet_CustomPrs::deactivate(const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag,
98                                    const bool theUpdateViewer)
99 {
100   myIsActive[theFlag] = false;
101   erasePresentation(theFlag, theUpdateViewer);
102   return true;
103 }
104
105 bool PartSet_CustomPrs::displayPresentation(
106                                   const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag,
107                                   const bool theUpdateViewer)
108 {
109   bool isModified = false;
110
111   if (myDisabledMode == theFlag)
112     return isModified;
113
114   // update the AIS objects content
115   AISObjectPtr aPresentation = getPresentation(theFlag, true);
116   Handle(AIS_InteractiveObject) anAISIO = aPresentation->impl<Handle(AIS_InteractiveObject)>();
117   Handle(PartSet_OperationPrs) anOperationPrs = Handle(PartSet_OperationPrs)::DownCast(anAISIO);
118
119   // do nothing if the feature can not be displayed [is moved from presentation, to be checked]
120   if (!myFeature.get())
121     return isModified;
122
123   QMap<ObjectPtr, QList<GeomShapePtr> > aFeatureShapes;
124   switch (theFlag) {
125     case ModuleBase_IModule::CustomizeArguments:
126       PartSet_OperationPrs::getFeatureShapes(myFeature, myWorkshop, aFeatureShapes);
127       break;
128     case ModuleBase_IModule::CustomizeResults:
129       PartSet_OperationPrs::getResultShapes(myFeature, myWorkshop, aFeatureShapes);
130       PartSet_OperationPrs::getPresentationShapes(myFeature, myWorkshop, aFeatureShapes, false);
131       break;
132     case ModuleBase_IModule::CustomizeHighlightedObjects:
133       PartSet_OperationPrs::getHighlightedShapes(myWorkshop, aFeatureShapes);
134       break;
135     default:
136       return isModified;
137   }
138   NCollection_DataMap<TopoDS_Shape, Handle(AIS_InteractiveObject)>& aShapeMap =
139                                                                  anOperationPrs->shapesMap();
140   PartSet_OperationPrs::fillShapeList(aFeatureShapes, myWorkshop, aShapeMap);
141
142   myPresentationIsEmpty = false;
143   // redisplay AIS objects
144   bool aRedisplayed = false;
145   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
146   if (!aContext.IsNull() && !aContext->IsDisplayed(anOperationPrs)) {
147     // when the feature can not be visualized in the module, the operation preview should not
148     // be visualized also
149     if (anOperationPrs->hasShapes() && myWorkshop->module()->canDisplayObject(myFeature)) {
150       // set color here because it can be changed in preferences
151       Quantity_Color aShapeColor = getShapeColor(theFlag);
152       anOperationPrs->setShapeColor(aShapeColor);
153
154       PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
155       XGUI_Workshop* aWorkshop = workshop();
156       aRedisplayed = aWorkshop->displayer()->displayAIS(myPresentations[theFlag],
157                                          false/*load object in selection*/, 0, false);
158       aContext->SetZLayer(anOperationPrs, aModule->getVisualLayerId());
159       isModified = true;
160     }
161   }
162   else {
163     // when the feature can not be visualized in the module, the operation preview should not
164     // be visualized also
165     if (!anOperationPrs->hasShapes() || !myWorkshop->module()->canDisplayObject(myFeature)) {
166       aRedisplayed = erasePresentation(theFlag, false);
167       isModified = true;
168     }
169     else {
170       anOperationPrs->Redisplay();
171       isModified = true;
172       aRedisplayed = true;
173     }
174   }
175   if (myPresentationIsEmpty) {
176     aRedisplayed = erasePresentation(theFlag, false);
177   }
178   if (aRedisplayed && theUpdateViewer)
179     workshop()->displayer()->updateViewer();
180
181   return isModified;
182 }
183
184 bool PartSet_CustomPrs::erasePresentation(
185                           const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag,
186                           const bool theUpdateViewer)
187 {
188   bool isErased = false;
189   XGUI_Workshop* aWorkshop = workshop();
190   if (myPresentations.contains(theFlag))
191     isErased = aWorkshop->displayer()->eraseAIS(myPresentations[theFlag], theUpdateViewer);
192   return isErased;
193 }
194
195 void PartSet_CustomPrs::clearPresentation(
196   const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag)
197 {
198   AISObjectPtr aPresentation = getPresentation(theFlag, false);
199   if (aPresentation.get()) {
200     Handle(AIS_InteractiveObject) anAISIO = aPresentation->impl<Handle(AIS_InteractiveObject)>();
201     Handle(PartSet_OperationPrs) anOperationPrs = Handle(PartSet_OperationPrs)::DownCast(anAISIO);
202
203     anOperationPrs->shapesMap().Clear();
204     if (!anOperationPrs.IsNull())
205       anOperationPrs.Nullify();
206     myPresentations.remove(theFlag);
207   }
208 }
209
210 AISObjectPtr PartSet_CustomPrs::getPresentation(
211                                        const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag,
212                                        const bool theToCreate)
213 {
214   Handle(PartSet_OperationPrs) aPresentation;
215
216   AISObjectPtr anOperationPrs;
217   if (myPresentations.contains(theFlag))
218     anOperationPrs = myPresentations[theFlag];
219
220   if (!anOperationPrs.get() && theToCreate) {
221     initPresentation(theFlag);
222     anOperationPrs = myPresentations[theFlag];
223   }
224
225   return anOperationPrs;
226 }
227
228 bool PartSet_CustomPrs::redisplay(const ObjectPtr& theObject,
229                                   const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag,
230                                   const bool theUpdateViewer)
231 {
232 #ifdef DO_NOT_VISUALIZE_CUSTOM_PRESENTATION
233   return false;
234 #endif
235   bool aRedisplayed = false;
236   if (myIsActive[theFlag])
237     aRedisplayed = displayPresentation(theFlag, theUpdateViewer);
238
239   return aRedisplayed;
240 }
241
242 void PartSet_CustomPrs::clearPrs()
243 {
244   clearPresentation(ModuleBase_IModule::CustomizeArguments);
245   clearPresentation(ModuleBase_IModule::CustomizeResults);
246   clearPresentation(ModuleBase_IModule::CustomizeHighlightedObjects);
247 }
248
249 void PartSet_CustomPrs::processEvent(const std::shared_ptr<Events_Message>& theMessage)
250 {
251   if (theMessage->eventID() == Events_Loop::eventByName(EVENT_EMPTY_OPERATION_PRESENTATION))
252     myPresentationIsEmpty = true; /// store state to analize it after display/erase is finished
253 }
254
255 void PartSet_CustomPrs::initPresentation(
256   const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag)
257 {
258   AISObjectPtr anOperationPrs = AISObjectPtr(new GeomAPI_AISObject());
259   Handle(PartSet_OperationPrs) anAISPrs = new PartSet_OperationPrs(myWorkshop);
260   anOperationPrs->setImpl(new Handle(AIS_InteractiveObject)(anAISPrs));
261   if (theFlag == ModuleBase_IModule::CustomizeArguments ||
262       theFlag == ModuleBase_IModule::CustomizeResults) {
263     anOperationPrs->setPointMarker(5, 2.);
264     anOperationPrs->setWidth((theFlag == ModuleBase_IModule::CustomizeHighlightedObjects)? 2 : 1);
265   }
266   else if (theFlag == ModuleBase_IModule::CustomizeHighlightedObjects)
267     anAISPrs->useAISWidth();
268
269   if (anOperationPrs.get())
270     myPresentations[theFlag] = anOperationPrs;
271 }
272
273 Quantity_Color PartSet_CustomPrs::getShapeColor(
274                                   const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag)
275 {
276   Quantity_Color aColor;
277   switch(theFlag) {
278     case ModuleBase_IModule::CustomizeArguments:
279       aColor = ModuleBase_Tools::color("Visualization", "operation_parameter_color");
280     break;
281     case ModuleBase_IModule::CustomizeResults:
282       aColor = ModuleBase_Tools::color("Visualization", "operation_result_color");
283     break;
284     case ModuleBase_IModule::CustomizeHighlightedObjects:
285       aColor = ModuleBase_Tools::color("Visualization", "operation_highlight_color");
286     break;
287     default:
288     break;
289   }
290   return aColor;
291 }
292
293 XGUI_Workshop* PartSet_CustomPrs::workshop() const
294 {
295   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
296   return aConnector->workshop();
297 }