0025695: Visualization, AIS_InteractiveContext - define default HilightMode
[occt.git] / samples / mfc / standard / Common / Primitive / Sample2D_Face.cpp
1 #include "stdafx.h"
2
3 #include "Sample2D_Face.h"
4
5 IMPLEMENT_STANDARD_RTTIEXT(Sample2D_Face,AIS_InteractiveObject)
6
7 Sample2D_Face::Sample2D_Face (const TopoDS_Shape& theFace)
8 :AIS_InteractiveObject()
9 {
10   myshape = theFace;
11   myFORWARDColor  = Quantity_NOC_BLUE1;
12   myREVERSEDColor = Quantity_NOC_YELLOW;
13   myINTERNALColor = Quantity_NOC_RED1;
14   myEXTERNALColor = Quantity_NOC_MAGENTA1;
15   myWidthIndex         = 1;
16   myTypeIndex          = 1;
17
18   myForwardNum=0;
19   myReversedNum=0;
20   myInternalNum=0;
21   myExternalNum=0;
22
23   SetAutoHilight(Standard_False);
24
25   FillData(Standard_True);
26 }
27
28 void Sample2D_Face::DrawMarker(const Handle(Geom2d_TrimmedCurve)& theCurve, const Handle(Prs3d_Presentation)& thePresentation)
29 {
30   Standard_Real aCenterParam = (theCurve->FirstParameter()+theCurve->LastParameter())/2; 
31   gp_Pnt2d p;
32   gp_Vec2d v;
33   theCurve->D1(aCenterParam,p,v);
34   if (v.Magnitude() > gp::Resolution()) 
35   {
36     gp_Vec aDir(v.X(),v.Y(),0.);
37     gp_Pnt aPoint(p.X(),p.Y(),0.);
38     aDir.Normalize();
39     aDir.Reverse();
40     gp_Dir aZ(0,0,1);
41     gp_Pnt aLeft(aPoint.Translated(aDir.Rotated(gp_Ax1(aPoint,aZ), M_PI/6)*5)) ;
42     gp_Pnt aRight(aPoint.Translated(aDir.Rotated(gp_Ax1(aPoint,aZ), M_PI*11/6)*5));
43
44     Handle(Graphic3d_ArrayOfPolylines) anArrow = new Graphic3d_ArrayOfPolylines(3);
45     anArrow->AddVertex(aLeft);
46     anArrow->AddVertex(aPoint);
47     anArrow->AddVertex(aRight);
48
49     Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray(anArrow);
50   }
51 }
52
53 void Sample2D_Face::FillData(Standard_Boolean isSizesRecompute)
54 {
55   if(myshape.IsNull() || myshape.ShapeType()!=TopAbs_FACE) return;
56
57   Standard_Real f,l;
58   TopExp_Explorer ex;
59   TopoDS_Face aFace = TopoDS::Face(myshape);
60
61   //count number of verteces and bounds in primitive arrays
62   if(isSizesRecompute)
63   {
64     mySeq_FORWARD.Clear();
65     mySeq_REVERSED.Clear();
66     mySeq_INTERNAL.Clear();
67     mySeq_EXTERNAL.Clear();
68
69     myshape.Orientation(TopAbs_FORWARD);
70     ex.Init(myshape,TopAbs_EDGE);
71     while (ex.More())
72     {
73       BRepAdaptor_Curve2d aCurveOnEdge(TopoDS::Edge(ex.Current()),aFace);
74       GCPnts_QuasiUniformDeflection anEdgeDistrib(aCurveOnEdge,1.e-2);
75       if(anEdgeDistrib.IsDone())
76         switch (ex.Current().Orientation())
77       {
78         case TopAbs_FORWARD: {
79           myForwardNum+=anEdgeDistrib.NbPoints();
80           myForwardBounds++;
81           break;
82                              }
83         case TopAbs_REVERSED: {
84           myReversedNum+=anEdgeDistrib.NbPoints();
85           myReversedBounds++;
86           break;
87                               }
88         case TopAbs_INTERNAL: {
89           myInternalNum+=anEdgeDistrib.NbPoints();
90           myInternalBounds++;
91           break;
92                               }
93         case TopAbs_EXTERNAL: {
94           myExternalNum+=anEdgeDistrib.NbPoints();
95           myExternalBounds++;
96           break;
97                               }
98         default : break;
99       }//end switch
100       ex.Next();
101     }
102   }
103
104   myForwardArray = new Graphic3d_ArrayOfPolylines(myForwardNum,myForwardBounds);
105   myReversedArray = new Graphic3d_ArrayOfPolylines(myReversedNum, myReversedBounds);
106   myInternalArray = new Graphic3d_ArrayOfPolylines(myInternalNum, myInternalBounds);
107   myExternalArray = new Graphic3d_ArrayOfPolylines(myExternalNum, myExternalBounds);
108
109   //fill primitive arrays
110   ex.Init(myshape,TopAbs_EDGE);
111   while (ex.More()) {
112     const Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface
113       (TopoDS::Edge(ex.Current()),aFace,f,l);
114
115     Handle(Geom2d_TrimmedCurve) aTrimmedCurve = new Geom2d_TrimmedCurve(aCurve,f,l);
116     TopoDS_Edge CurrentEdge= TopoDS::Edge(ex.Current());
117     if(!aTrimmedCurve.IsNull())
118     {
119       Handle(Geom_Curve) aCurve3d = GeomLib::To3d(gp_Ax2(gp_Pnt(0,0,0),gp_Dir(0,0,1)),aTrimmedCurve);
120       BRepAdaptor_Curve2d aCurveOnEdge(CurrentEdge,aFace);
121       GCPnts_QuasiUniformDeflection anEdgeDistrib(aCurveOnEdge,1.e-2);
122       if(anEdgeDistrib.IsDone())
123       {
124         switch (ex.Current().Orientation())
125         {
126         case TopAbs_FORWARD: {
127           myForwardArray->AddBound(anEdgeDistrib.NbPoints());
128           for(Standard_Integer i=1;i<=anEdgeDistrib.NbPoints();++i)
129           {
130             myForwardArray->AddVertex(anEdgeDistrib.Value(i));
131           }
132           if(isSizesRecompute)
133             mySeq_FORWARD.Append(aCurve3d);
134           break;
135                              }
136         case TopAbs_REVERSED: {
137           myReversedArray->AddBound(anEdgeDistrib.NbPoints());
138           for(Standard_Integer i=1;i<=anEdgeDistrib.NbPoints();++i)
139           {
140             myReversedArray->AddVertex(anEdgeDistrib.Value(i));
141           }
142           if(isSizesRecompute)
143             mySeq_REVERSED.Append(aCurve3d);
144           break;
145                               }
146         case TopAbs_INTERNAL: {
147           myInternalArray->AddBound(anEdgeDistrib.NbPoints());
148           for(Standard_Integer i=1;i<=anEdgeDistrib.NbPoints();++i)
149           {
150             myInternalArray->AddVertex(anEdgeDistrib.Value(i));
151           }
152           if(isSizesRecompute)
153             mySeq_INTERNAL.Append(aCurve3d);
154           break;
155                               }
156         case TopAbs_EXTERNAL: {
157           myExternalArray->AddBound(anEdgeDistrib.NbPoints());
158           for(Standard_Integer i=1;i<=anEdgeDistrib.NbPoints();++i)
159           {
160             myExternalArray->AddVertex(anEdgeDistrib.Value(i));
161           }
162           if(isSizesRecompute)
163             mySeq_EXTERNAL.Append(aCurve3d);
164           break;
165                               }
166         default : break;
167         }//end switch
168       }
169     }//end else
170     ex.Next();
171   }
172 }
173
174 void Sample2D_Face::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
175                              const Handle(Prs3d_Presentation)& thePresentation,
176                              const Standard_Integer /*theMode*/)
177 {
178   thePresentation->Clear();
179   myDrawer->SetWireDraw(1);
180
181   if(myshape.IsNull() || myshape.ShapeType()!=TopAbs_FACE) return;
182
183   Handle(Graphic3d_AspectLine3d) aLineAspect_FORWARD =
184     new Graphic3d_AspectLine3d(myFORWARDColor, Aspect_TOL_SOLID,1);
185   Handle(Graphic3d_AspectLine3d) aLineAspect_REVERSED =
186     new Graphic3d_AspectLine3d(myREVERSEDColor, Aspect_TOL_SOLID,1);
187   Handle(Graphic3d_AspectLine3d) aLineAspect_INTERNAL =
188     new Graphic3d_AspectLine3d(myINTERNALColor, Aspect_TOL_SOLID,1);
189   Handle(Graphic3d_AspectLine3d) aLineAspect_EXTERNAL =
190     new Graphic3d_AspectLine3d(myEXTERNALColor, Aspect_TOL_SOLID,1);
191
192   Standard_Real f,l;
193   TopoDS_Face aFace = TopoDS::Face(myshape);
194   //estimating number of verteces in primitive arrays
195   TopExp_Explorer ex(myshape,TopAbs_EDGE);
196   ex.Init(myshape,TopAbs_EDGE);
197   while (ex.More())
198   {
199     const Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface
200       (TopoDS::Edge(ex.Current()),aFace,f,l);
201
202     Handle(Geom2d_TrimmedCurve) aTrimmedCurve = new Geom2d_TrimmedCurve(aCurve,f,l);
203     TopoDS_Edge aCurrentEdge= TopoDS::Edge(ex.Current());
204     //make a 3D curve from 2D trimmed curve to display it
205     Handle(Geom_Curve) aCurve3d = GeomLib::To3d(gp_Ax2(gp_Pnt(0,0,0),gp_Dir(0,0,1)),aTrimmedCurve);
206     //make distribution of points
207     BRepAdaptor_Curve2d aCurveOnEdge(aCurrentEdge,aFace);
208     GCPnts_QuasiUniformDeflection anEdgeDistrib(aCurveOnEdge,1.e-2);
209     if(anEdgeDistrib.IsDone())
210     {
211       switch (ex.Current().Orientation())
212       {
213       case TopAbs_FORWARD: {
214
215         Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect(aLineAspect_FORWARD);  
216         DrawMarker(aTrimmedCurve, thePresentation);
217         break;
218                            }
219       case TopAbs_REVERSED: {
220
221         Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect(aLineAspect_REVERSED);  
222         DrawMarker(aTrimmedCurve, thePresentation);
223         break;
224                             }
225       case TopAbs_INTERNAL: {
226
227         Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect(aLineAspect_INTERNAL);  
228         DrawMarker(aTrimmedCurve, thePresentation);
229
230         mySeq_INTERNAL.Append(aCurve3d);
231         break;
232                             }
233       case TopAbs_EXTERNAL: {
234
235         Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect(aLineAspect_EXTERNAL);  
236         DrawMarker(aTrimmedCurve, thePresentation);
237         break;
238                             }
239       default : break;
240       }//end switch
241     }
242     ex.Next();
243   }
244   //add all primitives to the presentation
245   Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect(aLineAspect_FORWARD);  
246   Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray(myForwardArray);
247
248   Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect(aLineAspect_REVERSED);
249   Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray(myReversedArray);
250
251   Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect(aLineAspect_INTERNAL);
252   Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray(myInternalArray);
253
254   Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect(aLineAspect_EXTERNAL);
255   Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray(myExternalArray);
256 }
257
258 //Method for advanced customizable selection of picked object
259 void Sample2D_Face::HilightSelected 
260 ( const Handle(PrsMgr_PresentationManager3d)& thePM,
261  const SelectMgr_SequenceOfOwner& theOwners)
262 {
263   Handle( Prs3d_Presentation ) aSelectionPrs;
264
265   aSelectionPrs = GetSelectPresentation( thePM );
266
267   Handle(Graphic3d_AspectLine3d) aLineAspect =
268     new Graphic3d_AspectLine3d(Quantity_NOC_ANTIQUEWHITE, Aspect_TOL_SOLID,2);
269   if( HasPresentation() )
270     aSelectionPrs->SetTransformPersistence (Presentation()->TransformPersistence());
271
272   Standard_Integer aLength = theOwners.Length();
273   Handle (SelectMgr_EntityOwner) anOwner;
274
275   aSelectionPrs->Clear();
276   FillData();
277
278   Prs3d_Root::NewGroup ( aSelectionPrs );
279   Handle (Graphic3d_Group) aSelectGroup = Prs3d_Root::CurrentGroup ( aSelectionPrs);
280
281   for(Standard_Integer i=1; i<=aLength; ++i)
282   {
283     anOwner = theOwners.Value(i);
284     //check priority of owner to add primitives in one of array
285     //containing primitives with certain type of orientation
286     switch(anOwner->Priority())
287     {
288     case 7:
289       {
290         //add to objects with forward orientation
291         aSelectGroup->SetGroupPrimitivesAspect(aLineAspect);
292         aSelectGroup->AddPrimitiveArray(myForwardArray);
293         break;
294       }
295     case 6:
296       {
297         //add to objects with reversed orientation
298         aSelectGroup->SetGroupPrimitivesAspect(aLineAspect);
299         aSelectGroup->AddPrimitiveArray(myReversedArray);
300         break;
301       }
302     case 5:
303       {
304         //add to objects with internal orientation
305         aSelectGroup->SetGroupPrimitivesAspect(aLineAspect);
306         aSelectGroup->AddPrimitiveArray(myInternalArray);
307         break;
308       }
309     case 4:
310       {
311         //add to objects with external orientation
312         aSelectGroup->SetGroupPrimitivesAspect(aLineAspect);
313         aSelectGroup->AddPrimitiveArray(myExternalArray);
314         break;
315       }
316     }
317
318   }
319   aSelectionPrs->Display();
320
321 }
322
323 void Sample2D_Face::ClearSelected ()
324 {
325   Handle( Prs3d_Presentation ) aSelectionPrs = GetSelectPresentation( NULL );  
326   if( !aSelectionPrs.IsNull() )
327     aSelectionPrs->Clear(); 
328 }
329
330
331
332 //Method for advanced customizable highlighting of picked object
333 void Sample2D_Face::HilightOwnerWithColor ( const Handle(PrsMgr_PresentationManager3d)& thePM,
334                                            const Handle(Prs3d_Drawer)& theStyle,
335                                            const Handle(SelectMgr_EntityOwner)& theOwner)
336 {
337   Handle( Prs3d_Presentation ) aHighlightPrs;
338   aHighlightPrs = GetHilightPresentation( thePM );
339   if( HasPresentation() )
340     aHighlightPrs->SetTransformPersistence (Presentation()->TransformPersistence());
341   if(theOwner.IsNull())
342     return;
343   aHighlightPrs->Clear();
344   FillData();
345
346   //Direct highlighting
347   Prs3d_Root::NewGroup ( aHighlightPrs );
348   Handle (Graphic3d_Group) aHilightGroup = Prs3d_Root::CurrentGroup(aHighlightPrs);
349   Handle(Graphic3d_AspectLine3d) aLineAspect =
350     new Graphic3d_AspectLine3d(theStyle->Color(), Aspect_TOL_SOLID,2);
351   switch(theOwner->Priority())
352   {
353   case 7:
354     {
355       aHilightGroup->SetGroupPrimitivesAspect(aLineAspect);
356       aHilightGroup->AddPrimitiveArray(myForwardArray);
357       break;
358     }
359   case 6:
360     {
361       aHilightGroup->SetGroupPrimitivesAspect(aLineAspect);
362       aHilightGroup->AddPrimitiveArray(myReversedArray);
363       break;
364     }
365   case 5:
366     {
367       aHilightGroup->SetGroupPrimitivesAspect(aLineAspect);
368       aHilightGroup->AddPrimitiveArray(myInternalArray);
369       break;
370     }
371   case 4:
372     {
373       aHilightGroup->SetGroupPrimitivesAspect(aLineAspect);
374       aHilightGroup->AddPrimitiveArray(myExternalArray);
375       break;
376     }
377   }
378   if( thePM->IsImmediateModeOn() )
379     thePM->AddToImmediateList( aHighlightPrs );
380
381 }
382
383
384
385 //for auto select
386 void Sample2D_Face::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
387                                       const Standard_Integer /*theMode*/)
388 {
389   if(myshape.IsNull()) 
390     return;
391
392   if(mySeq_FORWARD.Length()==0 && 
393     mySeq_REVERSED.Length()==0 &&
394     mySeq_INTERNAL.Length()==0 &&
395     mySeq_EXTERNAL.Length()==0) return;
396
397   //create entity owner for every part of the face
398   //set different priorities for primitives of different orientation
399   Handle(SelectMgr_EntityOwner) anOwner_Forward = new SelectMgr_EntityOwner(this,7);
400   Handle(SelectMgr_EntityOwner) anOwner_Reversed = new SelectMgr_EntityOwner(this,6);
401   Handle(SelectMgr_EntityOwner) anOwner_Internal = new SelectMgr_EntityOwner(this,5);
402   Handle(SelectMgr_EntityOwner) anOwner_External = new SelectMgr_EntityOwner(this,4);
403
404   //create a sensitive for every part
405   Handle(Select3D_SensitiveGroup) aForwardGroup = new Select3D_SensitiveGroup(anOwner_Forward);
406   Handle(Select3D_SensitiveGroup) aReversedGroup = new Select3D_SensitiveGroup(anOwner_Reversed);
407   Handle(Select3D_SensitiveGroup) aInternalGroup = new Select3D_SensitiveGroup(anOwner_Internal);
408   Handle(Select3D_SensitiveGroup) aExternalGroup = new Select3D_SensitiveGroup(anOwner_External);
409
410   Standard_Integer aLength =  mySeq_FORWARD.Length();
411   for(Standard_Integer i=1;i<=aLength;++i)
412   {
413     Handle(Select3D_SensitiveCurve) aSensitveCurve = new Select3D_SensitiveCurve(anOwner_Forward,mySeq_FORWARD(i));
414     aForwardGroup->Add(aSensitveCurve);
415   }
416   theSelection->Add(aForwardGroup);
417
418   aLength =  mySeq_REVERSED.Length();
419   for(Standard_Integer i=1;i<=aLength;++i)
420   {
421     Handle(Select3D_SensitiveCurve) aSensitveCurve = new Select3D_SensitiveCurve(anOwner_Reversed,mySeq_REVERSED(i));
422     aReversedGroup->Add(aSensitveCurve);
423   }
424   theSelection->Add(aReversedGroup);
425
426   aLength =  mySeq_INTERNAL.Length();
427   for(Standard_Integer i=1;i<=aLength;++i)
428   {
429     Handle(Select3D_SensitiveCurve) aSensitveCurve = new Select3D_SensitiveCurve(anOwner_Internal,mySeq_INTERNAL(i));
430     aInternalGroup->Add(aSensitveCurve);
431   }
432   theSelection->Add(aInternalGroup);
433
434   aLength =  mySeq_EXTERNAL.Length();
435   for(Standard_Integer i=1;i<=aLength;++i)
436   {
437     Handle(Select3D_SensitiveCurve) aSensitveCurve = new Select3D_SensitiveCurve(anOwner_External,mySeq_EXTERNAL(i));
438     aExternalGroup->Add(aSensitveCurve);
439   }
440   theSelection->Add(aExternalGroup);
441 }
442