]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_OperationPrs.cpp
Salome HOME
Issue #1530 The arcs representation is not fine enough
[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 #include "XGUI_Tools.h"
14
15 #include "ModuleBase_Tools.h"
16 #include "ModuleBase_IModule.h"
17 #include <ModuleBase_IPropertyPanel.h>
18 #include <ModuleBase_ModelWidget.h>
19 #include <ModuleBase_ViewerPrs.h>
20
21 #include <ModelAPI_Events.h>
22 #include <ModelAPI_Result.h>
23 #include <ModelAPI_Attribute.h>
24 #include <ModelAPI_AttributeRefAttr.h>
25 #include <ModelAPI_AttributeReference.h>
26 #include <ModelAPI_AttributeSelection.h>
27 #include <ModelAPI_AttributeSelectionList.h>
28 #include <ModelAPI_AttributeRefList.h>
29 #include <ModelAPI_Validator.h>
30 #include <ModelAPI_Session.h>
31 #include <ModelAPI_ResultCompSolid.h>
32
33 #include <Events_Error.h>
34 #include <Events_Loop.h>
35
36 #include <GeomAPI_IPresentable.h>
37
38 #include <StdPrs_WFDeflectionShape.hxx>
39
40 #include <QList>
41
42 #include <gp_Pnt.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <BRepBuilderAPI_MakeVertex.hxx>
45 #include <BRep_Builder.hxx>
46 #include <TopoDS_Compound.hxx>
47
48 //#define DEBUG_EMPTY_SHAPE
49 //#define DEBUG_OPERATION_PRS
50
51 // multi-rotation/translation operation
52 //#define DEBUG_HIDE_COPY_ATTRIBUTE
53 #ifdef DEBUG_HIDE_COPY_ATTRIBUTE
54 #include <ModelAPI_AttributeBoolean.h>
55 #include <SketchPlugin_SketchEntity.h>
56 #endif
57
58 IMPLEMENT_STANDARD_HANDLE(PartSet_OperationPrs, ViewerData_AISShape);
59 IMPLEMENT_STANDARD_RTTIEXT(PartSet_OperationPrs, ViewerData_AISShape);
60
61 PartSet_OperationPrs::PartSet_OperationPrs(ModuleBase_IWorkshop* theWorkshop)
62 : ViewerData_AISShape(TopoDS_Shape()), myWorkshop(theWorkshop), myUseAISWidth(false)
63 {
64 #ifdef DEBUG_OPERATION_PRS
65   qDebug("PartSet_OperationPrs::PartSet_OperationPrs");
66 #endif
67   myShapeColor = Quantity_Color(1, 1, 1, Quantity_TOC_RGB);
68
69   // first presentation for having correct Compute until presentation with shapes are set
70   gp_Pnt aPnt(0.0, 0.0, 0.0);
71   BRepBuilderAPI_MakeVertex aMaker(aPnt);
72   TopoDS_Vertex aVertex = aMaker.Vertex();
73   myShapeToPrsMap.Bind(aVertex, NULL);
74 }
75
76 bool PartSet_OperationPrs::hasShapes()
77 {
78   return !myShapeToPrsMap.IsEmpty();
79 }
80
81 void PartSet_OperationPrs::setShapeColor(const Quantity_Color& theColor)
82 {
83   myShapeColor = theColor;
84 }
85
86 void PartSet_OperationPrs::useAISWidth()
87 {
88   myUseAISWidth = true;
89 }
90
91 void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
92                                    const Handle(Prs3d_Presentation)& thePresentation, 
93                                    const Standard_Integer theMode)
94 {
95 #ifdef DEBUG_OPERATION_PRS
96   qDebug("PartSet_OperationPrs::Compute -- begin");
97 #endif
98
99   SetColor(myShapeColor);
100   thePresentation->Clear();
101   bool aReadyToDisplay = !myShapeToPrsMap.IsEmpty();
102
103   XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer();
104   Handle(Prs3d_Drawer) aDrawer = Attributes();
105   // create presentations on the base of the shapes
106   BRep_Builder aBuilder;
107   TopoDS_Compound aComp;
108   aBuilder.MakeCompound(aComp);
109   for(NCollection_DataMap<TopoDS_Shape, Handle(AIS_InteractiveObject)>::Iterator anIter(myShapeToPrsMap);
110       anIter.More(); anIter.Next()) {
111     const TopoDS_Shape& aShape = anIter.Key();
112     aBuilder.Add(aComp, aShape);
113     // change deviation coefficient to provide more precise circle
114     // as there is no result, the shape is processed to correct deviation. To be unified
115     ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, aDrawer);
116
117     if (myUseAISWidth) {
118       Handle(AIS_InteractiveObject) anIO = anIter.Value();
119       if (!anIO.IsNull()) {
120         int aWidth = anIO->Width();
121         /// workaround for zero width. Else, there will be a crash
122         if (aWidth == 0) { // width returns of TSolid shape is zero
123           bool isDisplayed = !anIO->GetContext().IsNull();
124           aWidth = PartSet_Tools::getAISDefaultWidth();// default width value
125         }
126         setWidth(aDrawer, aWidth);
127       }
128     }
129     StdPrs_WFDeflectionShape::Add(thePresentation, aShape, aDrawer);
130   }
131   Set(aComp);
132   if (!aReadyToDisplay) {
133     Events_Error::throwException("An empty AIS presentation: PartSet_OperationPrs");
134     std::shared_ptr<Events_Message> aMsg = std::shared_ptr<Events_Message>(
135                 new Events_Message(Events_Loop::eventByName(EVENT_EMPTY_OPERATION_PRESENTATION)));
136     Events_Loop::loop()->send(aMsg);
137   }
138 #ifdef DEBUG_OPERATION_PRS
139   qDebug("PartSet_OperationPrs::Compute -- end");
140 #endif
141 }
142
143 void PartSet_OperationPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
144                                             const Standard_Integer aMode)
145 {
146   // the presentation is not used in the selection
147 }
148
149 NCollection_DataMap<TopoDS_Shape, Handle(AIS_InteractiveObject)>& PartSet_OperationPrs::shapesMap()
150 {
151   return myShapeToPrsMap;
152 }
153
154 bool isSubObject(const ObjectPtr& theObject, const FeaturePtr& theFeature)
155 {
156   bool isSub = false;
157   CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
158   if (aComposite.get())
159     isSub = aComposite->isSub(theObject);
160
161   return isSub;
162 }
163
164 void PartSet_OperationPrs::addValue(const ObjectPtr& theObject, const GeomShapePtr& theShape,
165                                     const FeaturePtr& theFeature, ModuleBase_IWorkshop* theWorkshop,
166                                     QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes)
167 {
168   if (theObject.get()) {
169     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
170     if (aResult.get()) {
171       ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theObject);
172       if (aCompsolidResult.get()) {
173         if (aCompsolidResult->numberOfSubs() > 0) {
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, theWorkshop, theObjectShapes);
179             }
180           }
181           return;
182         }
183       }
184 #ifdef DEBUG_HIDE_COPY_ATTRIBUTE
185       else {
186         FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
187         if (aFeature.get()) {
188           AttributeBooleanPtr aCopyAttr = aFeature->data()->boolean(SketchPlugin_SketchEntity::COPY_ID());
189           if (aCopyAttr.get()) {
190             bool isCopy = aCopyAttr->value();
191             if (isCopy)
192               return;
193           }
194         }
195       }
196 #endif
197     }
198
199     GeomShapePtr aShape = theShape;
200     if (!aShape.get()) {
201       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
202       if (aResult.get())
203         aShape = aResult->shape();
204     }
205     if (!isSubObject(theObject, theFeature))
206       appendShapeIfVisible(theWorkshop, theObject, aShape, theObjectShapes);
207   }
208 }
209
210 void PartSet_OperationPrs::appendShapeIfVisible(ModuleBase_IWorkshop* theWorkshop,
211                               const ObjectPtr& theObject,
212                               GeomShapePtr theGeomShape,
213                               QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes)
214 {
215   XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(theWorkshop)->displayer();
216   if (XGUI_Displayer::isVisible(aDisplayer, theObject)) {
217     if (theGeomShape.get()) {
218       if (theObjectShapes.contains(theObject))
219         theObjectShapes[theObject].append(theGeomShape);
220       else {
221         QList<GeomShapePtr> aShapes;
222         aShapes.append(theGeomShape);
223         theObjectShapes[theObject] = aShapes;
224       }
225     } else {
226   #ifdef DEBUG_EMPTY_SHAPE
227       qDebug(QString("Empty shape in result, result: %1")
228               .arg(ModuleBase_Tools::objectInfo(theObject)).toStdString().c_str());
229   #endif
230     }
231   }
232 }
233
234 void PartSet_OperationPrs::getFeatureShapes(const FeaturePtr& theFeature,
235                                             ModuleBase_IWorkshop* theWorkshop,
236                                             QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes)
237 {
238   theObjectShapes.clear();
239   if (!theFeature.get())
240     return;
241
242   ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
243
244   QList<GeomShapePtr> aShapes;
245   std::list<AttributePtr> anAttributes = theFeature->data()->attributes("");
246   std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
247   for (; anIt != aLast; anIt++) {
248     AttributePtr anAttribute = *anIt;
249     if (!isSelectionAttribute(anAttribute))
250       continue;
251
252     if (!aValidators->isCase(theFeature, anAttribute->id()))
253       continue; // this attribute is not participated in the current case
254
255     std::string anAttrType = anAttribute->attributeType();
256
257     if (anAttrType == ModelAPI_AttributeSelectionList::typeId()) {
258       std::shared_ptr<ModelAPI_AttributeSelectionList> aCurSelList = 
259               std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(anAttribute);
260       for(int i = 0; i < aCurSelList->size(); i++) {
261         std::shared_ptr<ModelAPI_AttributeSelection> aSelAttribute = aCurSelList->value(i);
262         ResultPtr aResult = aSelAttribute->context();
263         GeomShapePtr aShape = aSelAttribute->value();
264         addValue(aResult, aShape, theFeature, theWorkshop, theObjectShapes);
265       }
266     }
267     if (anAttrType == ModelAPI_AttributeRefList::typeId()) {
268       std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
269         std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(anAttribute);
270       for (int i = 0; i < aCurSelList->size(); i++) {
271         ObjectPtr anObject = aCurSelList->object(i);
272         FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
273         // if a feature is stored in the attribute, we should obtain the feature results
274         // e.g. feature rectangle uses parameters feature lines in the attribute
275         if (aFeature.get()) {
276           getResultShapes(aFeature, theWorkshop, theObjectShapes, false);
277         }
278         else {
279           ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
280           if (aResult.get()) {
281             GeomShapePtr aShape = aResult->shape();
282             if (aShape.get())
283               addValue(aResult, aShape, theFeature, theWorkshop, theObjectShapes);
284           }
285         }
286       }
287     }
288     else {
289       ObjectPtr anObject;
290       GeomShapePtr aShape;
291       if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
292         AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
293         if (anAttr->isObject()) {
294           anObject = anAttr->object();
295         }
296         else {
297           AttributePtr anAttribute = anAttr->attr();
298           aShape = PartSet_Tools::findShapeBy2DPoint(anAttribute, theWorkshop);
299           // the distance point is not found if the point is selected in the 2nd time
300           // TODO: after debug, this check can be removed
301           if (!aShape.get())
302             continue;
303           anObject = anAttr->attr()->owner();
304         }
305       }
306       if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
307         AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(anAttribute);
308         anObject = anAttr->context();
309         aShape = anAttr->value();
310       }
311       if (anAttrType == ModelAPI_AttributeReference::typeId()) {
312         AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttribute);
313         anObject = anAttr->value();
314       }
315       addValue(anObject, aShape, theFeature, theWorkshop, theObjectShapes);
316     }
317   }
318 }
319
320 void PartSet_OperationPrs::getResultShapes(const FeaturePtr& theFeature,
321                                            ModuleBase_IWorkshop* theWorkshop,
322                                            QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes,
323                                            const bool theListShouldBeCleared)
324 {
325   if (theListShouldBeCleared)
326     theObjectShapes.clear();
327
328   if (!theFeature.get())
329     return;
330
331   XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(theWorkshop)->displayer();
332
333   std::list<ResultPtr> aFeatureResults = theFeature->results();
334   std::list<ResultPtr>::const_iterator aRIt = aFeatureResults.begin(),
335                                        aRLast = aFeatureResults.end();
336   for (; aRIt != aRLast; aRIt++) {
337     ResultPtr aResult = *aRIt;
338     GeomShapePtr aGeomShape = aResult->shape();
339     appendShapeIfVisible(theWorkshop, aResult, aGeomShape, theObjectShapes);
340   }
341 }
342
343 void PartSet_OperationPrs::getHighlightedShapes(ModuleBase_IWorkshop* theWorkshop,
344                                                 QMap<ObjectPtr, QList<GeomShapePtr> >& theObjectShapes)
345 {
346   theObjectShapes.clear();
347
348   QList<ModuleBase_ViewerPrsPtr> aValues;
349   ModuleBase_IPropertyPanel* aPanel = theWorkshop->propertyPanel();
350   if (aPanel) {
351     ModuleBase_ModelWidget* aWidget = aPanel->activeWidget();
352     if (aWidget) {
353       aWidget->getHighlighted(aValues);
354     }
355   }
356
357   QList<GeomShapePtr> aShapes;
358   QList<ModuleBase_ViewerPrsPtr>::const_iterator anIIt = aValues.begin(),
359                                               aILast = aValues.end();
360   for (; anIIt != aILast; anIIt++) {
361     ModuleBase_ViewerPrsPtr aPrs = *anIIt;
362     ObjectPtr anObject = aPrs->object();
363
364     GeomShapePtr aGeomShape = aPrs->shape();
365     if (!aGeomShape.get() || aGeomShape->isNull()) {
366       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
367       if (aResult.get()) {
368         aGeomShape = aResult->shape();
369       }
370     }
371     appendShapeIfVisible(theWorkshop, anObject, aGeomShape, theObjectShapes);
372   }
373 }
374
375
376 bool PartSet_OperationPrs::isSelectionAttribute(const AttributePtr& theAttribute)
377 {
378   std::string anAttrType = theAttribute->attributeType();
379
380   return anAttrType == ModelAPI_AttributeSelectionList::typeId() ||
381          anAttrType == ModelAPI_AttributeRefList::typeId() ||
382          anAttrType == ModelAPI_AttributeRefAttr::typeId() ||
383          anAttrType == ModelAPI_AttributeSelection::typeId() ||
384          anAttrType == ModelAPI_AttributeReference::typeId();
385 }
386
387 void PartSet_OperationPrs::fillShapeList(const QMap<ObjectPtr, QList<GeomShapePtr> >& theFeatureShapes,
388                             ModuleBase_IWorkshop* theWorkshop,
389                             NCollection_DataMap<TopoDS_Shape, Handle(AIS_InteractiveObject)>& theShapeToPrsMap)
390 {
391   theShapeToPrsMap.Clear();
392
393   XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(theWorkshop)->displayer();
394
395   // create presentations on the base of the shapes
396   QMap<ObjectPtr, QList<GeomShapePtr> >::const_iterator anIt = theFeatureShapes.begin(),
397                                                         aLast = theFeatureShapes.end();
398   for (; anIt != aLast; anIt++) {
399     ObjectPtr anObject = anIt.key();
400     QList<GeomShapePtr> aShapes = anIt.value();
401     QList<GeomShapePtr>::const_iterator aShIt = aShapes.begin(), aShLast = aShapes.end();
402     for (; aShIt != aShLast; aShIt++) {
403       GeomShapePtr aGeomShape = *aShIt;
404       // the shape should not be checked here on empty value because it should be checked in
405       // appendShapeIfVisible() on the step of filling theFeatureShapes list
406       // the reason is to avoid empty AIS object visualized in the viewer
407       //if (!aGeomShape.get()) continue;
408       TopoDS_Shape aShape = aGeomShape.get() ? aGeomShape->impl<TopoDS_Shape>() : TopoDS_Shape();
409       if (aShape.IsNull())
410         continue;
411
412       // change deviation coefficient to provide more precise circle
413       Handle(AIS_InteractiveObject) anIO;
414       AISObjectPtr anAISPtr = aDisplayer->getAISObject(anObject);
415       if (anAISPtr.get())
416         anIO = anAISPtr->impl<Handle(AIS_InteractiveObject)>();
417       theShapeToPrsMap.Bind(aShape, anIO);
418     }
419   }
420 }