Salome HOME
4491b273a64aa0d0c2e105381161c8d810e259a1
[modules/shaper.git] / src / ModuleBase / ModuleBase_ResultPrs.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        ModuleBase_ResultPrs.cpp
4 // Created:     21 October 2014
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "ModuleBase_ResultPrs.h"
8 #include "ModuleBase_Tools.h"
9
10 #include <ModelAPI_Tools.h>
11 #include <ModelAPI_ResultConstruction.h>
12 #include <GeomAPI_PlanarEdges.h>
13
14 #include <Events_Error.h>
15
16 #include <BRep_Builder.hxx>
17 #include <Prs3d_Drawer.hxx>
18 #include <Prs3d.hxx>
19 #include <Prs3d_PointAspect.hxx>
20 #include <Prs3d_IsoAspect.hxx>
21 #include <TopoDS_Builder.hxx>
22 #include <SelectMgr_SequenceOfOwner.hxx>
23 #include <SelectMgr_EntityOwner.hxx>
24 #include <SelectMgr_SelectionManager.hxx>
25 #include <StdPrs_WFDeflectionShape.hxx>
26 #include <StdSelect_BRepSelectionTool.hxx>
27 #include <AIS_InteractiveContext.hxx>
28 #include <AIS_Selection.hxx>
29 #include <TColStd_ListIteratorOfListOfInteger.hxx>
30
31 //#define DEBUG_WIRE
32
33 #ifdef DEBUG_WIRE
34 #include <TopTools_IndexedMapOfShape.hxx>
35 #include <TopExp.hxx>
36 #endif
37
38 IMPLEMENT_STANDARD_HANDLE(ModuleBase_BRepOwner, StdSelect_BRepOwner);
39 IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_BRepOwner, StdSelect_BRepOwner);
40
41 //*******************************************************************************************
42
43 IMPLEMENT_STANDARD_HANDLE(ModuleBase_ResultPrs, ViewerData_AISShape);
44 IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ResultPrs, ViewerData_AISShape);
45
46
47
48
49
50 ModuleBase_ResultPrs::ModuleBase_ResultPrs(ResultPtr theResult)
51   : ViewerData_AISShape(TopoDS_Shape()), myResult(theResult), myIsSketchMode(false)
52 {
53   std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(theResult);
54   std::shared_ptr<GeomAPI_PlanarEdges> aWirePtr = 
55     std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapePtr);
56   if (aWirePtr) {
57     if (aWirePtr->hasPlane() ) {
58       // If this is a wire with plane defined thin it is a sketch-like object
59       // It must have invisible faces
60       myIsSketchMode = true;
61     }
62   }
63   TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
64   Set(aShape);
65   Handle(Prs3d_Drawer) aDrawer = Attributes();
66   if (aDrawer->HasOwnPointAspect()) 
67     aDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_PLUS);
68   else
69     aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_PLUS, Quantity_NOC_YELLOW, 1.));
70
71   // Activate individual repaintng if this is a part of compsolid
72   ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult);
73   SetAutoHilight(aCompSolid.get() == NULL);
74 }
75
76 bool ModuleBase_ResultPrs::isValidShapeType(const TopAbs_ShapeEnum& theBaseType,
77                                             const TopAbs_ShapeEnum& theCheckedType)
78 {
79   bool aValid = theBaseType == theCheckedType;
80   if (!aValid) {
81     // currently this functionality is for all, as we have no separate wire selection mode
82     // lately it should be corrected to have the following check only for sketch presentations
83     aValid = theBaseType == TopAbs_FACE && theCheckedType == TopAbs_WIRE;
84   }
85   return aValid;
86 }
87
88
89 void ModuleBase_ResultPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
90                                    const Handle(Prs3d_Presentation)& thePresentation, 
91                                    const Standard_Integer theMode)
92 {
93   std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(myResult);
94   if (!aShapePtr) {
95     Events_Error::throwException("An empty AIS presentation: ModuleBase_ResultPrs");
96     return;
97   }
98
99   if (myIsSketchMode) {
100     myFacesList.clear();
101     ResultConstructionPtr aConstruction = 
102       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(myResult);
103     if (aConstruction.get()) {
104       int aFacesNum = aConstruction->facesNum();
105       for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) {
106         myFacesList.push_back(aConstruction->face(aFaceIndex));
107       }
108     }
109   }
110   myOriginalShape = aShapePtr->impl<TopoDS_Shape>();
111   if (!myOriginalShape.IsNull()) {
112     Set(myOriginalShape);
113
114     // change deviation coefficient to provide more precise circle
115     ModuleBase_Tools::setDefaultDeviationCoefficient(myOriginalShape, Attributes());
116     AIS_Shape::Compute(thePresentationManager, thePresentation, theMode);
117   }
118   else
119     Events_Error::throwException("An empty AIS presentation: ModuleBase_ResultPrs");
120 }
121
122 #ifdef DEBUG_WIRE
123 void debugInfo(const TopoDS_Shape& theShape, const TopAbs_ShapeEnum theType)
124 {
125   TopTools_IndexedMapOfShape aSubShapes;
126   TopExp::MapShapes (theShape, theType, aSubShapes);
127
128   Standard_Boolean isComesFromDecomposition = !((aSubShapes.Extent() == 1) && (theShape == aSubShapes (1)));
129   int anExtent = aSubShapes.Extent();
130   for (Standard_Integer aShIndex = 1; aShIndex <= aSubShapes.Extent(); ++aShIndex)
131   {
132     const TopoDS_Shape& aSubShape = aSubShapes (aShIndex);
133     int aValue = 0;
134   }
135 }
136 #endif
137
138 void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
139                                             const Standard_Integer aMode)
140 {
141   if (aMode > 8)
142     // In order to avoid using custom selection modes
143     return;
144
145   if (myIsSketchMode) {
146     if (aMode == AIS_Shape::SelectionMode(TopAbs_FACE)) {
147 #ifdef DEBUG_WIRE
148       const TopoDS_Shape& aShape = Shape();
149       debugInfo(aShape, TopAbs_VERTEX); // 24
150       debugInfo(aShape, TopAbs_EDGE); // 12
151       debugInfo(aShape, TopAbs_WIRE); // 0
152       debugInfo(aShape, TopAbs_FACE); // 0
153 #endif
154       BRep_Builder aBuilder;
155       TopoDS_Compound aComp;
156       aBuilder.MakeCompound(aComp);
157       aBuilder.Add(aComp, myOriginalShape);
158       std::list<std::shared_ptr<GeomAPI_Shape>>::const_iterator aIt;
159       for (aIt = myFacesList.cbegin(); aIt != myFacesList.cend(); ++aIt) {
160         TopoDS_Shape aFace = (*aIt)->impl<TopoDS_Shape>();
161         aBuilder.Add(aComp, aFace);
162         // for sketch presentation in the face mode wires should be selectable also
163         // accoring to #1343 Improvement of Extrusion and Revolution operations
164         appendWiresSelection(aSelection, aFace);
165       }
166 #ifdef DEBUG_WIRE
167       debugInfo(aComp, TopAbs_VERTEX); // 24
168       debugInfo(aComp, TopAbs_EDGE); // 12
169       debugInfo(aComp, TopAbs_WIRE); // 4
170       debugInfo(aComp, TopAbs_FACE); // 2
171 #endif
172       Set(aComp);
173     } else
174       Set(myOriginalShape);
175   } 
176   if (aMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) {
177     // Limit selection area only by actual object (Shape)
178     ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult);
179     if (aCompSolid.get()) {
180       std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aCompSolid);
181       if (aShapePtr.get()) {
182         TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
183         int aPriority = StdSelect_BRepSelectionTool::GetStandardPriority(aShape, TopAbs_SHAPE);
184         double aDeflection = Prs3d::GetDeflection(aShape, myDrawer);
185
186         Handle(ModuleBase_BRepOwner) aOwner = new ModuleBase_BRepOwner(aShape, aPriority);
187         StdSelect_BRepSelectionTool::ComputeSensitive(aShape, aOwner, aSelection, 
188           aDeflection, myDrawer->HLRAngle(), 9, 500);
189
190         for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
191           Handle(SelectMgr_EntityOwner) anOwner =
192             Handle(SelectMgr_EntityOwner)::DownCast(aSelection->Sensitive()->BaseSensitive()->OwnerId());
193           anOwner->Set(this);
194         }
195         return;
196       }
197     }
198     //AIS_Shape::ComputeSelection(aSelection, 0);
199   } 
200   AIS_Shape::ComputeSelection(aSelection, aMode);
201 }
202
203
204 bool ModuleBase_ResultPrs::hasCompSolidSelectionMode() const
205 {
206   if (!HasInteractiveContext()) 
207     return false;
208
209   Handle(AIS_InteractiveContext) aContext = GetContext();
210   TColStd_ListOfInteger aModes;
211   aContext->ActivatedModes(this, aModes);
212
213   TColStd_ListIteratorOfListOfInteger aIt(aModes);
214   for (; aIt.More(); aIt.Next()) {
215     if (aIt.Value() == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) 
216       return true;
217   }
218   return false;
219 }
220
221 void ModuleBase_ResultPrs::appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
222                                                 const TopoDS_Shape& theShape)
223 {
224   static TopAbs_ShapeEnum TypOfSel
225           = AIS_Shape::SelectionType(AIS_Shape::SelectionMode(TopAbs_WIRE));
226   // POP protection against crash in low layers
227   Standard_Real aDeflection = Prs3d::GetDeflection(theShape, myDrawer);
228   try {
229     StdSelect_BRepSelectionTool::Load(theSelection,
230                                       this,
231                                       theShape,
232                                       TypOfSel,
233                                       aDeflection,
234                                       myDrawer->HLRAngle(),
235                                       myDrawer->IsAutoTriangulation());
236   } catch ( Standard_Failure ) {
237   }
238 }
239
240 TopoDS_Shape ModuleBase_ResultPrs::getSelectionShape() const
241 {
242   if (hasCompSolidSelectionMode()) {
243     // In case of CompSolid mode use shape from Parent for highlighting
244     ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult);
245     if (aCompSolid.get()) {
246       std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aCompSolid);
247       if (aShapePtr.get()) 
248         return aShapePtr->impl<TopoDS_Shape>();
249     }
250   } 
251   return myOriginalShape;
252 }
253
254
255 void ModuleBase_ResultPrs::HilightSelected(const Handle(PrsMgr_PresentationManager3d)& thePM, 
256                                            const SelectMgr_SequenceOfOwner& theOwners)
257 {
258   Handle(SelectMgr_EntityOwner) anOwner;
259   Handle(ModuleBase_BRepOwner) aCompOwner;
260   for (int i = 1; i <= theOwners.Length(); i++) {
261     anOwner = theOwners.Value(i);
262     aCompOwner = Handle(ModuleBase_BRepOwner)::DownCast(anOwner);
263     if (aCompOwner.IsNull())
264       anOwner->Hilight(thePM);
265     else {
266       TopoDS_Shape aShape = aCompOwner->Shape();
267       Handle( Prs3d_Presentation ) aSelectionPrs = GetSelectPresentation( thePM );
268       aSelectionPrs->Clear();
269
270       StdPrs_WFDeflectionShape::Add(aSelectionPrs, aShape, myDrawer);
271
272       aSelectionPrs->SetDisplayPriority(9);
273       aSelectionPrs->Highlight(Aspect_TOHM_COLOR, aSelectionPrs->HighlightColor());
274       aSelectionPrs->Display();
275       thePM->Highlight(this);
276     }
277   }
278 }
279   
280 void ModuleBase_ResultPrs::HilightOwnerWithColor(const Handle(PrsMgr_PresentationManager3d)& thePM, 
281                                                  const Quantity_NameOfColor theColor, 
282                                                  const Handle(SelectMgr_EntityOwner)& theOwner)
283 {
284   Handle(StdSelect_BRepOwner) aOwner = Handle(StdSelect_BRepOwner)::DownCast(theOwner);
285   if (aOwner.IsNull())
286     return;
287
288   TopoDS_Shape aShape = aOwner->Shape();
289   if (!aShape.IsNull()) {
290     thePM->Color(this, theColor);
291
292     Handle( Prs3d_Presentation ) aHilightPrs = GetHilightPresentation( thePM );
293     aHilightPrs->Clear();
294
295     StdPrs_WFDeflectionShape::Add(aHilightPrs, aShape, myDrawer);
296     aHilightPrs->Highlight(Aspect_TOHM_COLOR, theColor);
297
298     if (thePM->IsImmediateModeOn())
299       thePM->AddToImmediateList(aHilightPrs);
300   }
301 }