0025099: Visualization - Option to show vertices of a shape
[occt.git] / src / Prs3d / Prs3d_WFShape.cxx
1 // Copyright (c) 2013-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <Prs3d_WFShape.hxx>
15
16 #include <Bnd_Box.hxx>
17 #include <BRepAdaptor_HSurface.hxx>
18 #include <BRepAdaptor_Curve.hxx>
19 #include <BRepBndLib.hxx>
20 #include <BRep_Tool.hxx>
21 #include <Graphic3d_Group.hxx>
22 #include <Graphic3d_AspectLine3d.hxx>
23 #include <Graphic3d_ArrayOfPolylines.hxx>
24 #include <Graphic3d_ArrayOfPoints.hxx>
25 #include <gp_Pnt.hxx>
26 #include <Poly_Connect.hxx>
27 #include <Poly_Triangulation.hxx>
28 #include <Poly_Array1OfTriangle.hxx>
29 #include <Poly_Polygon3D.hxx>
30 #include <Poly_PolygonOnTriangulation.hxx>
31 #include <Prs3d.hxx>
32 #include <Prs3d_Drawer.hxx>
33 #include <Prs3d_IsoAspect.hxx>
34 #include <Prs3d_PointAspect.hxx>
35 #include <Prs3d_NListIteratorOfListOfSequenceOfPnt.hxx>
36 #include <Prs3d_ShapeTool.hxx>
37 #include <Standard_ErrorHandler.hxx>
38 #include <TColgp_Array1OfPnt.hxx>
39 #include <TColgp_SequenceOfPnt.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS.hxx>
42 #include <TopTools_HSequenceOfShape.hxx>
43 #include <TopTools_ListOfShape.hxx>
44 #include <TopTools_ListIteratorOfListOfShape.hxx>
45
46 namespace
47 {
48
49   //! Compare two aspects
50   inline Standard_Boolean IsSame (const Handle(Graphic3d_AspectLine3d)& theUAspect,
51                                   const Handle(Graphic3d_AspectLine3d)& theVAspect)
52   {
53     Quantity_Color aCU, aCV;
54     Aspect_TypeOfLine aTlU, aTlV;
55     Standard_Real aWU, aWV;
56     theUAspect->Values (aCU, aTlU, aWU);
57     theVAspect->Values (aCV, aTlV, aWV);
58     return aCU  == aCV 
59         && aTlU == aTlV
60         && aWU  == aWV;
61   }
62
63 };
64
65 // =========================================================================
66 // function: AddPolygon
67 // purpose :
68 // =========================================================================
69 Standard_Boolean Prs3d_WFShape::AddPolygon (const TopoDS_Edge&    theEdge,
70                                             const Standard_Real   theDeflection,
71                                             TColgp_SequenceOfPnt& thePoints)
72 {
73   TopLoc_Location aLocation;
74   Standard_Real aFirst, aLast;
75   Handle(Geom_Curve)     aCurve3d = BRep_Tool::Curve     (theEdge, aFirst, aLast);
76   Handle(Poly_Polygon3D) aPolygon = BRep_Tool::Polygon3D (theEdge, aLocation);
77   if (!aPolygon.IsNull())
78   {
79     if ((aPolygon->Deflection() <= theDeflection) || aCurve3d.IsNull())
80     {
81       const TColgp_Array1OfPnt& aPoints = aPolygon->Nodes();
82       Standard_Integer anIndex = aPoints.Lower();
83       if (aLocation.IsIdentity())
84       {
85         for (; anIndex <= aPoints.Upper(); ++anIndex)
86         {
87           thePoints.Append (aPoints.Value (anIndex));
88         }
89       }
90       else
91       {
92         for (; anIndex <= aPoints.Upper(); ++anIndex)
93         {
94           thePoints.Append (aPoints.Value (anIndex).Transformed (aLocation));
95         }
96       }
97       return Standard_True;
98     }
99   }
100
101   Handle(Poly_Triangulation)          aTriangulation;
102   Handle(Poly_PolygonOnTriangulation) aHIndices;
103   BRep_Tool::PolygonOnTriangulation (theEdge, aHIndices, aTriangulation, aLocation);
104   if (!aHIndices.IsNull())
105   {
106     if ((aHIndices->Deflection() <= theDeflection) || aCurve3d.IsNull())
107     {
108       const TColStd_Array1OfInteger& anIndices = aHIndices->Nodes();
109       const TColgp_Array1OfPnt&      aNodes    = aTriangulation->Nodes();
110
111       Standard_Integer anIndex = anIndices.Lower();
112       if (aLocation.IsIdentity())
113       {
114         for (; anIndex <= anIndices.Upper(); ++anIndex)
115         {
116           thePoints.Append (aNodes (anIndices (anIndex)));
117         }
118       }
119       else
120       {
121         for (; anIndex <= anIndices.Upper(); ++anIndex)
122         {
123           thePoints.Append (aNodes (anIndices (anIndex)).Transformed (aLocation));
124         }
125       }
126       return Standard_True;
127     }
128   }
129   return Standard_False;
130 }
131
132 // =========================================================================
133 // function: Add
134 // purpose :
135 // =========================================================================
136 void Prs3d_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation,
137                          const TopoDS_Shape&                theShape,
138                          const Handle (Prs3d_Drawer)&       theDrawer)
139 {
140   if (theShape.IsNull())
141   {
142     return;
143   }
144
145   Prs3d_ShapeTool aTool (theShape, theDrawer->VertexDrawMode() == Prs3d_VDM_All);
146   TopTools_ListOfShape aLFree, aLUnFree, aLWire;
147   for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve())
148   {
149     const TopoDS_Edge& anEdge = aTool.GetCurve();
150     switch (aTool.Neighbours())
151     {
152       case 0:  aLWire.Append (anEdge);   break;
153       case 1:  aLFree.Append (anEdge);   break;
154       default: aLUnFree.Append (anEdge); break;
155     }
156   }
157
158   Standard_Real aDeflection = Prs3d::GetDeflection(theShape, theDrawer);
159
160   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
161
162   Prs3d_NListOfSequenceOfPnt anUIsoCurves;
163   Prs3d_NListOfSequenceOfPnt aVIsoCurves;
164   Prs3d_NListOfSequenceOfPnt aWireCurves;
165   Prs3d_NListOfSequenceOfPnt aFreeCurves;
166   Prs3d_NListOfSequenceOfPnt anUnFreeCurves;
167
168   const Standard_Integer anIsoU = theDrawer->UIsoAspect()->Number();
169   const Standard_Integer anIsoV = theDrawer->VIsoAspect()->Number();
170
171   Standard_Boolean hasIsoU = anIsoU > 0;
172   Standard_Boolean hasIsoV = anIsoV > 0;
173
174   if (IsSame (theDrawer->UIsoAspect()->Aspect(),
175               theDrawer->VIsoAspect()->Aspect()))
176   {
177     if (hasIsoU || hasIsoV)
178     {
179       BRepAdaptor_Surface aSurface;
180       for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
181       {
182         if (aTool.HasSurface())
183         {
184           if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane())
185           {
186             aSurface.Initialize (aTool.GetFace());
187             Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface);
188             try
189             {
190               OCC_CATCH_SIGNALS
191               Prs3d_NListOfSequenceOfPnt aCurUIsoCurves;
192               myFaceAlgo.Add (thePresentation, aHSurface,
193                               hasIsoU, hasIsoV,
194                               aDeflection,
195                               anIsoU, anIsoV,
196                               theDrawer,
197                               aCurUIsoCurves);
198               Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
199               for (anIt.Init (aCurUIsoCurves); anIt.More(); anIt.Next())
200               {
201                 anUIsoCurves.Append (anIt.Value());
202               }
203             }
204             catch (Standard_Failure)
205             {
206             }
207           }
208         }
209       }
210     }
211   }
212   else
213   {
214     if (hasIsoU)
215     {
216       BRepAdaptor_Surface aSurface;
217       for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
218       {
219         if (aTool.HasSurface())
220         {
221           if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane())
222           {
223             aSurface.Initialize (aTool.GetFace());
224             Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface);
225             try
226             {
227               OCC_CATCH_SIGNALS
228               Prs3d_NListOfSequenceOfPnt aCurUIsoCurves;
229               myFaceAlgo.Add (thePresentation, aHSurface,
230                               hasIsoU, Standard_False,
231                               aDeflection,
232                               anIsoU, 0,
233                               theDrawer,
234                               aCurUIsoCurves);
235             }
236             catch (Standard_Failure)
237             {
238             #ifdef DEB
239               const TopoDS_Face& aFace = aSurface.Face();
240               std::cout << "Problem with the face " << (void* ) &(*(aFace).TShape()) << std::endl;
241             #endif
242             }
243           }
244         }
245       }
246     }
247     if (hasIsoV)
248     {
249       BRepAdaptor_Surface aSurface;
250       for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
251       {
252         if (aTool.HasSurface())
253         {
254           if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane())
255           {
256             aSurface.Initialize (aTool.GetFace());
257             Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface);
258             try
259             {
260               OCC_CATCH_SIGNALS
261               Prs3d_NListOfSequenceOfPnt aCurUIsoCurves;
262               myFaceAlgo.Add (thePresentation, aHSurface,
263                               Standard_False, hasIsoV,
264                               aDeflection,
265                               0, anIsoV,
266                               theDrawer,
267                               aCurUIsoCurves);
268             }
269             catch (Standard_Failure)
270             {
271             #ifdef DEB
272               const TopoDS_Face& aFace = aSurface.Face();
273               std::cout << "Problem with the face " << (void* ) &(*(aFace).TShape()) << std::endl;
274             #endif
275             }
276           }
277         }
278       }
279     }
280   }
281
282   Standard_Integer aNbVertices = 0, aNbBounds = 0;
283   if (anUIsoCurves.Size() > 0)
284   {
285     aNbBounds = anUIsoCurves.Size();
286     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
287     for (anIt.Init (anUIsoCurves); anIt.More(); anIt.Next())
288     {
289       aNbVertices += anIt.Value()->Length();
290     }
291     Handle(Graphic3d_ArrayOfPolylines) anUIsoArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
292     for (anIt.Init (anUIsoCurves); anIt.More(); anIt.Next())
293     {
294       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
295       anUIsoArray->AddBound (aPoints->Length());
296       for (Standard_Integer anI = 1; anI <= aPoints->Length(); ++anI)
297       {
298         anUIsoArray->AddVertex (aPoints->Value (anI));
299       }
300     }
301     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
302     aGroup->SetPrimitivesAspect (theDrawer->UIsoAspect()->Aspect());
303     aGroup->AddPrimitiveArray (anUIsoArray);
304   }
305
306   // NOTE: THIS BLOCK WILL NEVER EXECUTE AS aVIsoCurves IS NOT FILLED!!
307   if (aVIsoCurves.Size() > 0)
308   {
309     aNbBounds = aVIsoCurves.Size();
310     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
311     for (anIt.Init (aVIsoCurves); anIt.More(); anIt.Next())
312     {
313       aNbVertices += anIt.Value()->Length();
314     }
315     Handle(Graphic3d_ArrayOfPolylines) VIsoArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
316     for (anIt.Init (aVIsoCurves); anIt.More(); anIt.Next())
317     {
318       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
319       VIsoArray->AddBound (aPoints->Length());
320       for (int anI = 1; anI <= aPoints->Length(); anI++)
321       {
322         VIsoArray->AddVertex (aPoints->Value (anI));
323       }
324     }
325     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
326     aGroup->SetPrimitivesAspect (theDrawer->VIsoAspect()->Aspect());
327     aGroup->AddPrimitiveArray (VIsoArray);
328   }
329
330   TopLoc_Location aLocation;
331   Standard_Integer anI, aJ, aN[3];
332
333   TColgp_SequenceOfPnt aSurfPoints;
334   for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
335   {
336     if (!aTool.HasSurface())
337     {
338       Handle(Poly_Triangulation) T = aTool.CurrentTriangulation (aLocation);
339       if (!T.IsNull())
340       {
341         const TColgp_Array1OfPnt& aNodes = T->Nodes();
342         // Build the connect tool
343         Poly_Connect aPolyConnect (T);
344
345         Standard_Integer aNbTriangles = T->NbTriangles();
346         Standard_Integer aT[3];
347
348         // Count the free edges
349         Standard_Integer aNbFree = 0;
350         for (anI = 1; anI <= aNbTriangles; ++anI)
351         {
352           aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
353           for (aJ = 0; aJ < 3; ++aJ)
354           {
355             if (aT[aJ] == 0)
356             {
357               ++aNbFree;
358             }
359           }
360         }
361
362         // Allocate the arrays
363         TColStd_Array1OfInteger aFree (1, 2 * aNbFree);
364         Standard_Integer aNbInternal = (3 * aNbTriangles - aNbFree) / 2;
365         TColStd_Array1OfInteger anInternal (0, 2 * aNbInternal);
366
367         Standard_Integer aFreeIndex = 1, anIntIndex = 1;
368         const Poly_Array1OfTriangle& aTriangles = T->Triangles();
369         for (anI = 1; anI <= aNbTriangles; ++anI)
370         {
371           aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
372           aTriangles (anI).Get (aN[0], aN[1], aN[2]);
373           for (aJ = 0; aJ < 3; aJ++)
374           {
375             Standard_Integer k = (aJ + 1) % 3;
376             if (aT[aJ] == 0)
377             {
378               aFree (aFreeIndex)     = aN[aJ];
379               aFree (aFreeIndex + 1) = aN[k];
380               aFreeIndex += 2;
381             }
382             // internal edge if this triangle has a lower index than the adjacent
383             else if (anI < aT[aJ])
384             {
385               anInternal (anIntIndex)     = aN[aJ];
386               anInternal (anIntIndex + 1) = aN[k];
387               anIntIndex += 2;
388             }
389           }
390         }
391
392         if (!aTool.HasSurface())
393         {
394           // free edges
395           Standard_Integer aFreeHalfNb = aFree.Length() / 2;
396           for (anI = 1; anI <= aFreeHalfNb; ++anI)
397           {
398             gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (aLocation);
399             gp_Pnt aPoint2 = aNodes (aFree (2 * anI    )).Transformed (aLocation);
400             aSurfPoints.Append (aPoint1);
401             aSurfPoints.Append (aPoint2);
402           }
403         }
404       }
405     }
406   }
407   if (aSurfPoints.Length() > 0)
408   {
409     aNbVertices = aSurfPoints.Length();
410     aNbBounds   = (Standard_Integer)aNbVertices / 2;
411     Handle(Graphic3d_ArrayOfPolylines) aSurfArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
412     for (anI = 1; anI <= aNbVertices; anI += 2)
413     {
414       aSurfArray->AddBound (2);
415       aSurfArray->AddVertex (aSurfPoints.Value (anI));
416       aSurfArray->AddVertex (aSurfPoints.Value (anI + 1));
417     }
418     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
419     aGroup->SetPrimitivesAspect (theDrawer->FreeBoundaryAspect()->Aspect());
420     aGroup->AddPrimitiveArray (aSurfArray);
421   }
422
423   TopTools_ListIteratorOfListOfShape anIt;
424   if (theDrawer->WireDraw())
425   {
426     // Wire (without any neighbour)
427     aGroup->SetPrimitivesAspect (theDrawer->WireAspect()->Aspect());
428     for (anIt.Initialize(aLWire); anIt.More(); anIt.Next())
429     {
430       const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value());
431       try
432       {
433         OCC_CATCH_SIGNALS
434         const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt;
435         if (!AddPolygon (anEdge, aDeflection, aPoints->ChangeSequence()))
436         {
437           if (BRep_Tool::IsGeometric (anEdge))
438           {
439             BRepAdaptor_Curve aCurve (anEdge);
440             myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer,
441                              aPoints->ChangeSequence(), Standard_False);
442             aWireCurves.Append (aPoints);
443           }
444         }
445         else
446         {
447           aWireCurves.Append (aPoints);
448         }
449       }
450       catch (Standard_Failure)
451       {
452       #ifdef DEB
453         std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl;
454       #endif
455       }
456     }
457   }
458
459   if (theDrawer->FreeBoundaryDraw())
460   {
461     // aFree boundaries;
462     for (anIt.Initialize (aLFree); anIt.More(); anIt.Next())
463     {
464       const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value());
465       if (!BRep_Tool::Degenerated (anEdge))
466       {
467         try
468         {
469           OCC_CATCH_SIGNALS
470           const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt;
471           if (!AddPolygon (anEdge, aDeflection, aPoints->ChangeSequence()))
472           {
473             if (BRep_Tool::IsGeometric (anEdge))
474             {
475               BRepAdaptor_Curve aCurve (anEdge);
476               myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer,
477                                aPoints->ChangeSequence(), Standard_False);
478               aFreeCurves.Append (aPoints);
479             }
480           }
481           else
482           {
483             aFreeCurves.Append (aPoints);
484           }
485         }
486         catch (Standard_Failure)
487         {
488         #ifdef DEB
489           std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl;
490         #endif
491         }
492       }
493     }
494   }
495
496   if (theDrawer->UnFreeBoundaryDraw())
497   {
498     // Unfree boundaries;
499     for (anIt.Initialize (aLUnFree); anIt.More(); anIt.Next())
500     {
501       const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value());
502       try
503       {
504         OCC_CATCH_SIGNALS
505         const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt;
506         if (!AddPolygon (anEdge, aDeflection, aPoints->ChangeSequence()))
507         {
508           if (BRep_Tool::IsGeometric (anEdge))
509           {
510             BRepAdaptor_Curve aCurve (anEdge);
511             myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer, aPoints->ChangeSequence(), Standard_False);
512             anUnFreeCurves.Append (aPoints);
513           }
514         }
515         else
516         {
517           anUnFreeCurves.Append (aPoints);
518         }
519       }
520       catch (Standard_Failure)
521       {
522       #ifdef DEB
523         std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl;
524       #endif
525       }
526     }
527   }
528
529   if (aWireCurves.Size() > 0)
530   {
531     aNbBounds = aWireCurves.Size();
532     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
533     for (anIt.Init (aWireCurves); anIt.More(); anIt.Next())
534     {
535       aNbVertices += anIt.Value()->Length();
536     }
537     Handle(Graphic3d_ArrayOfPolylines) WireArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
538     for (anIt.Init (aWireCurves); anIt.More(); anIt.Next())
539     {
540       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
541       WireArray->AddBound (aPoints->Length());
542       for (anI = 1; anI <= aPoints->Length(); ++anI)
543       {
544         WireArray->AddVertex (aPoints->Value (anI));
545       }
546     }
547     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
548     aGroup->SetPrimitivesAspect (theDrawer->WireAspect()->Aspect());
549     aGroup->AddPrimitiveArray (WireArray);
550   }
551
552   if (aFreeCurves.Size() > 0)
553   {
554     aNbBounds = aFreeCurves.Size();
555     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
556     for (anIt.Init (aFreeCurves); anIt.More(); anIt.Next())
557     {
558       aNbVertices += anIt.Value()->Length();
559     }
560     Handle(Graphic3d_ArrayOfPolylines) aFreeArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
561     for (anIt.Init(aFreeCurves); anIt.More(); anIt.Next())
562     {
563       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
564       aFreeArray->AddBound (aPoints->Length());
565       for (anI = 1; anI <= aPoints->Length(); ++anI)
566       {
567         aFreeArray->AddVertex (aPoints->Value (anI));
568       }
569     }  
570     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
571     aGroup->SetPrimitivesAspect (theDrawer->FreeBoundaryAspect()->Aspect());
572     aGroup->AddPrimitiveArray (aFreeArray);
573   }
574
575   if (anUnFreeCurves.Size() > 0)
576   {
577     aNbBounds = anUnFreeCurves.Size();
578     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
579     for (anIt.Init (anUnFreeCurves); anIt.More(); anIt.Next())
580     {
581       aNbVertices += anIt.Value()->Length();
582     }
583     Handle(Graphic3d_ArrayOfPolylines) anUnFreeArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
584     for (anIt.Init (anUnFreeCurves); anIt.More(); anIt.Next())
585     {
586       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
587       anUnFreeArray->AddBound (aPoints->Length());
588       for (anI = 1; anI <= aPoints->Length(); ++anI)
589       {
590         anUnFreeArray->AddVertex (aPoints->Value (anI));
591       }
592     }
593     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
594     aGroup->SetPrimitivesAspect (theDrawer->UnFreeBoundaryAspect()->Aspect());
595     aGroup->AddPrimitiveArray (anUnFreeArray);
596   }
597
598   // Points
599   TColgp_SequenceOfPnt aShapePoints;
600   for (aTool.InitVertex(); aTool.MoreVertex(); aTool.NextVertex())
601   {
602     aShapePoints.Append (BRep_Tool::Pnt (aTool.GetVertex()));
603   }
604
605   aNbVertices = aShapePoints.Length();
606   if (aNbVertices > 0)
607   {
608     Handle(Graphic3d_ArrayOfPoints) aPointArray = new Graphic3d_ArrayOfPoints (aNbVertices);
609     for (anI = 1; anI <= aNbVertices; ++anI)
610     {
611       aPointArray->AddVertex (aShapePoints.Value (anI));
612     }
613
614     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
615     aGroup->SetPrimitivesAspect (theDrawer->PointAspect()->Aspect());
616     aGroup->AddPrimitiveArray (aPointArray);
617   }
618 }
619
620 // =========================================================================
621 // function: PickCurve
622 // purpose :
623 // =========================================================================
624 Handle(TopTools_HSequenceOfShape) Prs3d_WFShape::PickCurve
625       (const Quantity_Length        theX,
626        const Quantity_Length        theY,
627        const Quantity_Length        theZ,
628        const Quantity_Length        theDistance,
629        const TopoDS_Shape&          theShape,
630        const Handle (Prs3d_Drawer)& theDrawer)
631 {
632   Handle(TopTools_HSequenceOfShape) aSeq = new TopTools_HSequenceOfShape();
633   Prs3d_ShapeTool aTool (theShape);
634   for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve())
635   {
636     Bnd_Box aBndBox = aTool.CurveBound();
637     aBndBox.Enlarge (theDistance);
638     if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ)))
639     {
640       if (myCurveAlgo.Match (theX, theY, theZ, theDistance,
641                              BRepAdaptor_Curve (aTool.GetCurve()), theDrawer))
642       {
643         Standard_Boolean isContain = Standard_False;
644         for (Standard_Integer anI = 1; anI <= aSeq->Length(); ++anI)
645         {
646           if (aSeq->Value (anI) == (aTool.GetCurve()))
647           {
648             isContain = Standard_True;
649             break;
650           }
651         }
652         if (!isContain)
653         {
654           aSeq->Append (aTool.GetCurve());
655         }
656       }
657     }
658   }
659   return aSeq;
660 }
661
662 // =========================================================================
663 // function: PickPatch
664 // purpose :
665 // =========================================================================
666 Handle(TopTools_HSequenceOfShape) Prs3d_WFShape::PickPatch
667       (const Quantity_Length       theX,
668        const Quantity_Length       theY,
669        const Quantity_Length       theZ,
670        const Quantity_Length       theDistance,
671        const TopoDS_Shape&         theShape,
672        const Handle(Prs3d_Drawer)& theDrawer)
673 {
674    Handle(TopTools_HSequenceOfShape) aSeq = new TopTools_HSequenceOfShape();
675    Prs3d_ShapeTool aTool (theShape);
676
677    Standard_Boolean aRba1 = theDrawer->UIsoAspect()->Number() != 0;
678    Standard_Boolean aRba2 = theDrawer->VIsoAspect()->Number() != 0;
679    Standard_Boolean isContain;
680
681    if (aRba1 || aRba2)
682    {
683      BRepAdaptor_Surface aSurface;
684      for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
685      {
686        Bnd_Box aBndBox = aTool.FaceBound();
687        aBndBox.Enlarge (theDistance);
688        if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ)))
689        {
690          aSurface.Initialize (aTool.GetFace());
691          Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface);
692          if (myFaceAlgo.Match (theX, theY, theZ, theDistance, aHSurface, theDrawer))
693          {
694            isContain = Standard_False;
695            for (Standard_Integer anI = 1; anI <= aSeq->Length(); ++anI)
696            {
697              if (aSeq->Value (anI) == (aTool.GetFace()))
698              {
699                isContain = Standard_True;
700                break;
701              }
702            }
703            if (!isContain)
704            {
705              aSeq->Append (aTool.GetFace());
706            }
707          }
708        }
709      }
710    }
711
712    for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve())
713    {
714      Bnd_Box aBndBox = aTool.CurveBound();
715      aBndBox.Enlarge (theDistance);
716      if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ)))
717      {
718        if (myCurveAlgo.Match (theX, theY, theZ, theDistance,
719                               BRepAdaptor_Curve(aTool.GetCurve()), theDrawer))
720        {
721          Handle(TopTools_HSequenceOfShape) aSurface = aTool.FacesOfEdge();
722          for (Standard_Integer anI = 1; anI <= aSurface->Length(); ++anI)
723          {
724            isContain = Standard_False;
725            for (Standard_Integer aJ = 1; aJ <= aSeq->Length(); ++aJ)
726            {
727              if (aSeq->Value (aJ) == (aSurface->Value (anI)))
728              {
729                isContain = Standard_True;
730                break;
731              }
732            }
733            if (!isContain)
734            {
735              aSeq->Append (aSurface->Value (anI));
736            }
737          }
738        }
739      }
740    }
741    return aSeq;
742 }