Salome HOME
Empty AIS in the viewer: throw c++ exception (to be finalized, currently do nothing)
[modules/shaper.git] / src / PartSet / PartSet_OperationPrs.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        PartSet_OperationPrs.cpp
4 // Created:     01 Jul 2015
5 // Author:      Natalia ERMOLAEVA
6
7 #include "PartSet_OperationPrs.h"
8 #include "PartSet_Tools.h"
9
10 #include "XGUI_Workshop.h"
11 #include "XGUI_ModuleConnector.h"
12 #include "XGUI_Displayer.h"
13
14 #include "ModuleBase_Tools.h"
15 #include "ModuleBase_IModule.h"
16 #include <ModuleBase_IPropertyPanel.h>
17 #include <ModuleBase_ModelWidget.h>
18
19 #include <ModelAPI_Result.h>
20 #include <ModelAPI_Attribute.h>
21 #include <ModelAPI_AttributeRefAttr.h>
22 #include <ModelAPI_AttributeReference.h>
23 #include <ModelAPI_AttributeSelection.h>
24 #include <ModelAPI_AttributeSelectionList.h>
25 #include <ModelAPI_AttributeRefList.h>
26 #include <ModelAPI_Validator.h>
27 #include <ModelAPI_Session.h>
28 #include <ModelAPI_ResultCompSolid.h>
29
30 #include <Events_Error.h>
31
32 #include <GeomAPI_IPresentable.h>
33
34 #include <StdPrs_WFDeflectionShape.hxx>
35
36 #include <QList>
37
38 static const int AIS_DEFAULT_WIDTH = 2;
39
40 IMPLEMENT_STANDARD_HANDLE(PartSet_OperationPrs, ViewerData_AISShape);
41 IMPLEMENT_STANDARD_RTTIEXT(PartSet_OperationPrs, ViewerData_AISShape);
42
43 PartSet_OperationPrs::PartSet_OperationPrs(ModuleBase_IWorkshop* theWorkshop)
44 : ViewerData_AISShape(TopoDS_Shape()), myWorkshop(theWorkshop), myUseAISWidth(false)
45 {
46   myShapeColor = Quantity_Color(1, 1, 1, Quantity_TOC_RGB);
47 }
48
49 bool PartSet_OperationPrs::hasShapes()
50 {
51   return !myFeatureShapes.empty();
52 }
53
54 void PartSet_OperationPrs::setShapeColor(const Quantity_Color& theColor)
55 {
56   myShapeColor = theColor;
57 }
58
59 void PartSet_OperationPrs::useAISWidth()
60 {
61   myUseAISWidth = true;
62 }
63
64 void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
65                                    const Handle(Prs3d_Presentation)& thePresentation, 
66                                    const Standard_Integer theMode)
67 {
68   SetColor(myShapeColor);
69   thePresentation->Clear();
70
71   XGUI_Displayer* aDisplayer = workshop(myWorkshop)->displayer();
72   Handle(Prs3d_Drawer) aDrawer = Attributes();
73
74   // create presentations on the base of the shapes
75   bool anEmptyAIS = true;
76   QMap<ObjectPtr, QList<GeomShapePtr> >::const_iterator anIt = myFeatureShapes.begin(),
77                                                         aLast = myFeatureShapes.end();
78   for (; anIt != aLast; anIt++) {
79     ObjectPtr anObject = anIt.key();
80     if (!isVisible(aDisplayer, anObject))
81       continue;
82     QList<GeomShapePtr> aShapes = anIt.value();
83     QList<GeomShapePtr>::const_iterator aShIt = aShapes.begin(), aShLast = aShapes.end();
84     for (; aShIt != aShLast; aShIt++) {
85       GeomShapePtr aGeomShape = *aShIt;
86       if (!aGeomShape.get())
87         continue;
88       TopoDS_Shape aShape = aGeomShape->impl<TopoDS_Shape>();
89       // change deviation coefficient to provide more precise circle
90       ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, aDrawer);
91
92       if (myUseAISWidth) {
93         AISObjectPtr anAISPtr = aDisplayer->getAISObject(anObject);
94         if (anAISPtr.get()) {
95           Handle(AIS_InteractiveObject) anIO = anAISPtr->impl<Handle(AIS_InteractiveObject)>();
96           if (!anIO.IsNull()) {
97             int aWidth = anIO->Width();
98             /// workaround for zero width. Else, there will be a crash
99             if (aWidth == 0) { // width returns of TSolid shape is zero
100               bool isDisplayed = !anIO->GetContext().IsNull();
101               aWidth = AIS_DEFAULT_WIDTH;// default width value
102             }
103             setWidth(aDrawer, aWidth);
104           }
105         }
106       }
107       StdPrs_WFDeflectionShape::Add(thePresentation, aShape, aDrawer);
108       if (anEmptyAIS)
109         anEmptyAIS = false;
110     }
111   }
112   if (anEmptyAIS)
113     Events_Error::throwException("An empty AIS presentation: PartSet_OperationPrs");
114 }
115
116 void PartSet_OperationPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
117                                             const Standard_Integer aMode)
118 {
119   // the presentation is not used in the selection
120 }
121
122 bool PartSet_OperationPrs::isVisible(XGUI_Displayer* theDisplayer, const ObjectPtr& theObject)
123 {
124   bool aVisible = false;
125   GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
126   ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
127   if (aPrs.get() || aResult.get()) {
128     aVisible = theDisplayer->isVisible(theObject);
129     // compsolid is not visualized in the viewer, but should have presentation when all sub solids are
130     // visible. It is useful for highlight presentation where compsolid shape is selectable
131     if (!aVisible && aResult.get() && aResult->groupName() == ModelAPI_ResultCompSolid::group()) {
132       ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
133       if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids
134         bool anAllSubsVisible = aCompsolidResult->numberOfSubs() > 0;
135         for(int i = 0; i < aCompsolidResult->numberOfSubs() && anAllSubsVisible; i++) {
136           anAllSubsVisible = theDisplayer->isVisible(aCompsolidResult->subResult(i));
137         }
138         aVisible = anAllSubsVisible;
139       }
140     }
141   }
142   else {
143     // check if all results of the feature are visible
144     FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
145     std::list<ResultPtr> aResults = aFeature->results();
146     std::list<ResultPtr>::const_iterator aIt;
147     aVisible = !aResults.empty();
148     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
149       aVisible = aVisible && theDisplayer->isVisible(*aIt);
150     }
151   }
152   return aVisible;
153 }
154
155 bool isSubObject(const ObjectPtr& theObject, const FeaturePtr& theFeature)
156 {
157   bool isSub = false;
158   CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
159   if (aComposite.get())
160     isSub = aComposite->isSub(theObject);
161
162   return isSub;
163 }
164
165 void addValue(const ObjectPtr& theObject, const GeomShapePtr& theShape,
166               const FeaturePtr& theFeature,
167               QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes)
168 {
169   if (theObject.get()) {
170     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
171     if (aResult.get()) {
172       ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theObject);
173       if (aCompsolidResult.get()) {
174         for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) {
175           ResultPtr aSubResult = aCompsolidResult->subResult(i);
176           if (aSubResult.get()) {
177             GeomShapePtr aShape;
178             addValue(aSubResult, aShape, theFeature, theObjectShapes);
179           }
180         }
181         return;
182       }
183     }
184
185
186     GeomShapePtr aShape = theShape;
187     if (!aShape.get()) {
188       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
189       if (aResult.get())
190         aShape = aResult->shape();
191     }
192     if (!isSubObject(theObject, theFeature)) {
193       if (theObjectShapes.contains(theObject))
194         theObjectShapes[theObject].append(aShape);
195       else {
196         QList<GeomShapePtr> aShapes;
197         aShapes.append(aShape);
198         theObjectShapes[theObject] = aShapes;
199       }
200     }
201   }
202 }
203
204 void PartSet_OperationPrs::getFeatureShapes(const FeaturePtr& theFeature,
205                                             ModuleBase_IWorkshop* theWorkshop,
206                                             QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes)
207 {
208   theObjectShapes.clear();
209   if (!theFeature.get())
210     return;
211
212   ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
213
214   QList<GeomShapePtr> aShapes;
215   std::list<AttributePtr> anAttributes = theFeature->data()->attributes("");
216   std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
217   for (; anIt != aLast; anIt++) {
218     AttributePtr anAttribute = *anIt;
219     if (!isSelectionAttribute(anAttribute))
220       continue;
221
222     if (!aValidators->isCase(theFeature, anAttribute->id()))
223       continue; // this attribute is not participated in the current case
224
225     std::string anAttrType = anAttribute->attributeType();
226
227     if (anAttrType == ModelAPI_AttributeSelectionList::typeId()) {
228       std::shared_ptr<ModelAPI_AttributeSelectionList> aCurSelList = 
229               std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(anAttribute);
230       for(int i = 0; i < aCurSelList->size(); i++) {
231         std::shared_ptr<ModelAPI_AttributeSelection> aSelAttribute = aCurSelList->value(i);
232         ResultPtr aResult = aSelAttribute->context();
233         GeomShapePtr aShape = aSelAttribute->value();
234         addValue(aResult, aShape, theFeature, theObjectShapes);
235       }
236     }
237     if (anAttrType == ModelAPI_AttributeRefList::typeId()) {
238       std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
239         std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(anAttribute);
240       for (int i = 0; i < aCurSelList->size(); i++) {
241         GeomShapePtr aShape;
242         addValue(aCurSelList->object(i), aShape, theFeature, theObjectShapes);
243       }
244     }
245     else {
246       ObjectPtr anObject;
247       GeomShapePtr aShape;
248       if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
249         AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
250         if (anAttr->isObject()) {
251           anObject = anAttr->object();
252         }
253         else {
254           aShape = PartSet_Tools::findShapeBy2DPoint(anAttr, theWorkshop);
255           // the distance point is not found if the point is selected in the 2nd time
256           // TODO: after debug, this check can be removed
257           if (!aShape.get())
258             continue;
259           anObject = anAttr->attr()->owner();
260         }
261       }
262       if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
263         AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(anAttribute);
264         anObject = anAttr->context();
265         aShape = anAttr->value();
266       }
267       if (anAttrType == ModelAPI_AttributeReference::typeId()) {
268         AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttribute);
269         anObject = anAttr->value();
270       }
271       addValue(anObject, aShape, theFeature, theObjectShapes);
272     }
273   }
274 }
275
276 void PartSet_OperationPrs::getResultShapes(const FeaturePtr& theFeature,
277                                            ModuleBase_IWorkshop* theWorkshop,
278                                            QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes)
279 {
280   theObjectShapes.clear();
281
282   if (!theFeature.get())
283     return;
284
285   XGUI_Displayer* aDisplayer = workshop(theWorkshop)->displayer();
286
287   std::list<ResultPtr> aFeatureResults = theFeature->results();
288   std::list<ResultPtr>::const_iterator aRIt = aFeatureResults.begin(),
289                                        aRLast = aFeatureResults.end();
290   for (; aRIt != aRLast; aRIt++) {
291     ResultPtr aResult = *aRIt;
292     if (!isVisible(aDisplayer, aResult))
293       continue;
294     GeomShapePtr aGeomShape = aResult->shape();
295     if (!aGeomShape.get())
296       continue;
297
298     if (theObjectShapes.contains(aResult))
299       theObjectShapes[aResult].append(aGeomShape);
300     else {
301       QList<GeomShapePtr> aShapes;
302       aShapes.append(aGeomShape);
303       theObjectShapes[aResult] = aShapes;
304     }
305   }
306 }
307
308 void PartSet_OperationPrs::getHighlightedShapes(ModuleBase_IWorkshop* theWorkshop,
309                                                 QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes)
310 {
311   theObjectShapes.clear();
312
313   QList<ModuleBase_ViewerPrs> aValues;
314   ModuleBase_IPropertyPanel* aPanel = theWorkshop->propertyPanel();
315   if (aPanel) {
316     ModuleBase_ModelWidget* aWidget = aPanel->activeWidget();
317     if (aWidget) {
318       aWidget->getHighlighted(aValues);
319     }
320   }
321
322   QList<GeomShapePtr> aShapes;
323   QList<ModuleBase_ViewerPrs>::const_iterator anIIt = aValues.begin(),
324                                               aILast = aValues.end();
325   for (; anIIt != aILast; anIIt++) {
326     ModuleBase_ViewerPrs aPrs = *anIIt;
327     ObjectPtr anObject = aPrs.object();
328
329     GeomShapePtr aGeomShape;
330
331     TopoDS_Shape aShape = aPrs.shape();
332     if (!aShape.IsNull()) {
333       aGeomShape = GeomShapePtr(new GeomAPI_Shape());
334       aGeomShape->setImpl(new TopoDS_Shape(aShape));
335     }
336     else {
337       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
338       if (aResult.get()) {
339         aGeomShape = aResult->shape();
340       }
341     }
342
343     if (theObjectShapes.contains(anObject))
344       theObjectShapes[anObject].append(aGeomShape);
345     else {
346       QList<GeomShapePtr> aShapes;
347       aShapes.append(aGeomShape);
348       theObjectShapes[anObject] = aShapes;
349     }
350   }
351 }
352
353
354 bool PartSet_OperationPrs::isSelectionAttribute(const AttributePtr& theAttribute)
355 {
356   std::string anAttrType = theAttribute->attributeType();
357
358   return anAttrType == ModelAPI_AttributeSelectionList::typeId() ||
359          anAttrType == ModelAPI_AttributeRefList::typeId() ||
360          anAttrType == ModelAPI_AttributeRefAttr::typeId() ||
361          anAttrType == ModelAPI_AttributeSelection::typeId() ||
362          anAttrType == ModelAPI_AttributeReference::typeId();
363 }
364
365 XGUI_Workshop* PartSet_OperationPrs::workshop(ModuleBase_IWorkshop* theWorkshop)
366 {
367   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);
368   return aConnector->workshop();
369 }