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