de6a9e0697553c6a638c281c33ace8d5c775a2d2
[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   Prs3d_NListOfSequenceOfPnt anUIsoCurves;
161   Prs3d_NListOfSequenceOfPnt aVIsoCurves;
162   Prs3d_NListOfSequenceOfPnt aWireCurves;
163   Prs3d_NListOfSequenceOfPnt aFreeCurves;
164   Prs3d_NListOfSequenceOfPnt anUnFreeCurves;
165
166   const Standard_Integer anIsoU = theDrawer->UIsoAspect()->Number();
167   const Standard_Integer anIsoV = theDrawer->VIsoAspect()->Number();
168
169   Standard_Boolean hasIsoU = anIsoU > 0;
170   Standard_Boolean hasIsoV = anIsoV > 0;
171
172   if (IsSame (theDrawer->UIsoAspect()->Aspect(),
173               theDrawer->VIsoAspect()->Aspect()))
174   {
175     if (hasIsoU || hasIsoV)
176     {
177       BRepAdaptor_Surface aSurface;
178       for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
179       {
180         if (aTool.HasSurface())
181         {
182           if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane())
183           {
184             aSurface.Initialize (aTool.GetFace());
185             Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface);
186             try
187             {
188               OCC_CATCH_SIGNALS
189               Prs3d_NListOfSequenceOfPnt aCurUIsoCurves;
190               myFaceAlgo.Add (thePresentation, aHSurface,
191                               hasIsoU, hasIsoV,
192                               aDeflection,
193                               anIsoU, anIsoV,
194                               theDrawer,
195                               aCurUIsoCurves);
196               Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
197               for (anIt.Init (aCurUIsoCurves); anIt.More(); anIt.Next())
198               {
199                 anUIsoCurves.Append (anIt.Value());
200               }
201             }
202             catch (Standard_Failure)
203             {
204             }
205           }
206         }
207       }
208     }
209   }
210   else
211   {
212     if (hasIsoU)
213     {
214       BRepAdaptor_Surface aSurface;
215       for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
216       {
217         if (aTool.HasSurface())
218         {
219           if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane())
220           {
221             aSurface.Initialize (aTool.GetFace());
222             Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface);
223             try
224             {
225               OCC_CATCH_SIGNALS
226               Prs3d_NListOfSequenceOfPnt aCurUIsoCurves;
227               myFaceAlgo.Add (thePresentation, aHSurface,
228                               hasIsoU, Standard_False,
229                               aDeflection,
230                               anIsoU, 0,
231                               theDrawer,
232                               aCurUIsoCurves);
233             }
234             catch (Standard_Failure)
235             {
236             #ifdef OCCT_DEBUG
237               const TopoDS_Face& aFace = aSurface.Face();
238               std::cout << "Problem with the face " << (void* ) &(*(aFace).TShape()) << std::endl;
239             #endif
240             }
241           }
242         }
243       }
244     }
245     if (hasIsoV)
246     {
247       BRepAdaptor_Surface aSurface;
248       for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
249       {
250         if (aTool.HasSurface())
251         {
252           if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane())
253           {
254             aSurface.Initialize (aTool.GetFace());
255             Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface);
256             try
257             {
258               OCC_CATCH_SIGNALS
259               Prs3d_NListOfSequenceOfPnt aCurUIsoCurves;
260               myFaceAlgo.Add (thePresentation, aHSurface,
261                               Standard_False, hasIsoV,
262                               aDeflection,
263                               0, anIsoV,
264                               theDrawer,
265                               aCurUIsoCurves);
266             }
267             catch (Standard_Failure)
268             {
269             #ifdef OCCT_DEBUG
270               const TopoDS_Face& aFace = aSurface.Face();
271               std::cout << "Problem with the face " << (void* ) &(*(aFace).TShape()) << std::endl;
272             #endif
273             }
274           }
275         }
276       }
277     }
278   }
279
280   Standard_Integer aNbVertices = 0, aNbBounds = 0;
281   if (anUIsoCurves.Size() > 0)
282   {
283     aNbBounds = anUIsoCurves.Size();
284     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
285     for (anIt.Init (anUIsoCurves); anIt.More(); anIt.Next())
286     {
287       aNbVertices += anIt.Value()->Length();
288     }
289     Handle(Graphic3d_ArrayOfPolylines) anUIsoArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
290     for (anIt.Init (anUIsoCurves); anIt.More(); anIt.Next())
291     {
292       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
293       anUIsoArray->AddBound (aPoints->Length());
294       for (Standard_Integer anI = 1; anI <= aPoints->Length(); ++anI)
295       {
296         anUIsoArray->AddVertex (aPoints->Value (anI));
297       }
298     }
299     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
300     aGroup->SetPrimitivesAspect (theDrawer->UIsoAspect()->Aspect());
301     aGroup->AddPrimitiveArray (anUIsoArray);
302   }
303
304   // NOTE: THIS BLOCK WILL NEVER EXECUTE AS aVIsoCurves IS NOT FILLED!!
305   if (aVIsoCurves.Size() > 0)
306   {
307     aNbBounds = aVIsoCurves.Size();
308     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
309     for (anIt.Init (aVIsoCurves); anIt.More(); anIt.Next())
310     {
311       aNbVertices += anIt.Value()->Length();
312     }
313     Handle(Graphic3d_ArrayOfPolylines) VIsoArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
314     for (anIt.Init (aVIsoCurves); anIt.More(); anIt.Next())
315     {
316       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
317       VIsoArray->AddBound (aPoints->Length());
318       for (int anI = 1; anI <= aPoints->Length(); anI++)
319       {
320         VIsoArray->AddVertex (aPoints->Value (anI));
321       }
322     }
323     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
324     aGroup->SetPrimitivesAspect (theDrawer->VIsoAspect()->Aspect());
325     aGroup->AddPrimitiveArray (VIsoArray);
326   }
327
328   TopLoc_Location aLocation;
329   Standard_Integer anI, aJ, aN[3];
330
331   TColgp_SequenceOfPnt aSurfPoints;
332   for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
333   {
334     if (!aTool.HasSurface())
335     {
336       Handle(Poly_Triangulation) T = aTool.CurrentTriangulation (aLocation);
337       if (!T.IsNull())
338       {
339         const TColgp_Array1OfPnt& aNodes = T->Nodes();
340         // Build the connect tool
341         Poly_Connect aPolyConnect (T);
342
343         Standard_Integer aNbTriangles = T->NbTriangles();
344         Standard_Integer aT[3];
345
346         // Count the free edges
347         Standard_Integer aNbFree = 0;
348         for (anI = 1; anI <= aNbTriangles; ++anI)
349         {
350           aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
351           for (aJ = 0; aJ < 3; ++aJ)
352           {
353             if (aT[aJ] == 0)
354             {
355               ++aNbFree;
356             }
357           }
358         }
359
360         // Allocate the arrays
361         TColStd_Array1OfInteger aFree (1, 2 * aNbFree);
362         Standard_Integer aNbInternal = (3 * aNbTriangles - aNbFree) / 2;
363         TColStd_Array1OfInteger anInternal (0, 2 * aNbInternal);
364
365         Standard_Integer aFreeIndex = 1, anIntIndex = 1;
366         const Poly_Array1OfTriangle& aTriangles = T->Triangles();
367         for (anI = 1; anI <= aNbTriangles; ++anI)
368         {
369           aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
370           aTriangles (anI).Get (aN[0], aN[1], aN[2]);
371           for (aJ = 0; aJ < 3; aJ++)
372           {
373             Standard_Integer k = (aJ + 1) % 3;
374             if (aT[aJ] == 0)
375             {
376               aFree (aFreeIndex)     = aN[aJ];
377               aFree (aFreeIndex + 1) = aN[k];
378               aFreeIndex += 2;
379             }
380             // internal edge if this triangle has a lower index than the adjacent
381             else if (anI < aT[aJ])
382             {
383               anInternal (anIntIndex)     = aN[aJ];
384               anInternal (anIntIndex + 1) = aN[k];
385               anIntIndex += 2;
386             }
387           }
388         }
389
390         if (!aTool.HasSurface())
391         {
392           // free edges
393           Standard_Integer aFreeHalfNb = aFree.Length() / 2;
394           for (anI = 1; anI <= aFreeHalfNb; ++anI)
395           {
396             gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (aLocation);
397             gp_Pnt aPoint2 = aNodes (aFree (2 * anI    )).Transformed (aLocation);
398             aSurfPoints.Append (aPoint1);
399             aSurfPoints.Append (aPoint2);
400           }
401         }
402       }
403     }
404   }
405   if (aSurfPoints.Length() > 0)
406   {
407     aNbVertices = aSurfPoints.Length();
408     aNbBounds   = (Standard_Integer)aNbVertices / 2;
409     Handle(Graphic3d_ArrayOfPolylines) aSurfArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
410     for (anI = 1; anI <= aNbVertices; anI += 2)
411     {
412       aSurfArray->AddBound (2);
413       aSurfArray->AddVertex (aSurfPoints.Value (anI));
414       aSurfArray->AddVertex (aSurfPoints.Value (anI + 1));
415     }
416     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
417     aGroup->SetPrimitivesAspect (theDrawer->FreeBoundaryAspect()->Aspect());
418     aGroup->AddPrimitiveArray (aSurfArray);
419   }
420
421   TopTools_ListIteratorOfListOfShape anIt;
422   if (theDrawer->WireDraw())
423   {
424     // Wire (without any neighbour)
425     for (anIt.Initialize(aLWire); anIt.More(); anIt.Next())
426     {
427       const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value());
428       try
429       {
430         OCC_CATCH_SIGNALS
431         const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt;
432         if (!AddPolygon (anEdge, aDeflection, aPoints->ChangeSequence()))
433         {
434           if (BRep_Tool::IsGeometric (anEdge))
435           {
436             BRepAdaptor_Curve aCurve (anEdge);
437             myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer,
438                              aPoints->ChangeSequence(), Standard_False);
439             aWireCurves.Append (aPoints);
440           }
441         }
442         else
443         {
444           aWireCurves.Append (aPoints);
445         }
446       }
447       catch (Standard_Failure)
448       {
449       #ifdef OCCT_DEBUG
450         std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl;
451       #endif
452       }
453     }
454   }
455
456   if (theDrawer->FreeBoundaryDraw())
457   {
458     // aFree boundaries;
459     for (anIt.Initialize (aLFree); anIt.More(); anIt.Next())
460     {
461       const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value());
462       if (!BRep_Tool::Degenerated (anEdge))
463       {
464         try
465         {
466           OCC_CATCH_SIGNALS
467           const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt;
468           if (!AddPolygon (anEdge, aDeflection, aPoints->ChangeSequence()))
469           {
470             if (BRep_Tool::IsGeometric (anEdge))
471             {
472               BRepAdaptor_Curve aCurve (anEdge);
473               myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer,
474                                aPoints->ChangeSequence(), Standard_False);
475               aFreeCurves.Append (aPoints);
476             }
477           }
478           else
479           {
480             aFreeCurves.Append (aPoints);
481           }
482         }
483         catch (Standard_Failure)
484         {
485         #ifdef OCCT_DEBUG
486           std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl;
487         #endif
488         }
489       }
490     }
491   }
492
493   if (theDrawer->UnFreeBoundaryDraw())
494   {
495     // Unfree boundaries;
496     for (anIt.Initialize (aLUnFree); anIt.More(); anIt.Next())
497     {
498       const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value());
499       try
500       {
501         OCC_CATCH_SIGNALS
502         const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt;
503         if (!AddPolygon (anEdge, aDeflection, aPoints->ChangeSequence()))
504         {
505           if (BRep_Tool::IsGeometric (anEdge))
506           {
507             BRepAdaptor_Curve aCurve (anEdge);
508             myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer, aPoints->ChangeSequence(), Standard_False);
509             anUnFreeCurves.Append (aPoints);
510           }
511         }
512         else
513         {
514           anUnFreeCurves.Append (aPoints);
515         }
516       }
517       catch (Standard_Failure)
518       {
519       #ifdef OCCT_DEBUG
520         std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl;
521       #endif
522       }
523     }
524   }
525
526   if (aWireCurves.Size() > 0)
527   {
528     aNbBounds = aWireCurves.Size();
529     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
530     for (anIt.Init (aWireCurves); anIt.More(); anIt.Next())
531     {
532       aNbVertices += anIt.Value()->Length();
533     }
534     Handle(Graphic3d_ArrayOfPolylines) WireArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
535     for (anIt.Init (aWireCurves); anIt.More(); anIt.Next())
536     {
537       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
538       WireArray->AddBound (aPoints->Length());
539       for (anI = 1; anI <= aPoints->Length(); ++anI)
540       {
541         WireArray->AddVertex (aPoints->Value (anI));
542       }
543     }
544     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
545     aGroup->SetPrimitivesAspect (theDrawer->WireAspect()->Aspect());
546     aGroup->AddPrimitiveArray (WireArray);
547   }
548
549   if (aFreeCurves.Size() > 0)
550   {
551     aNbBounds = aFreeCurves.Size();
552     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
553     for (anIt.Init (aFreeCurves); anIt.More(); anIt.Next())
554     {
555       aNbVertices += anIt.Value()->Length();
556     }
557     Handle(Graphic3d_ArrayOfPolylines) aFreeArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
558     for (anIt.Init(aFreeCurves); anIt.More(); anIt.Next())
559     {
560       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
561       aFreeArray->AddBound (aPoints->Length());
562       for (anI = 1; anI <= aPoints->Length(); ++anI)
563       {
564         aFreeArray->AddVertex (aPoints->Value (anI));
565       }
566     }  
567     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
568     aGroup->SetPrimitivesAspect (theDrawer->FreeBoundaryAspect()->Aspect());
569     aGroup->AddPrimitiveArray (aFreeArray);
570   }
571
572   if (anUnFreeCurves.Size() > 0)
573   {
574     aNbBounds = anUnFreeCurves.Size();
575     Prs3d_NListIteratorOfListOfSequenceOfPnt anIt;
576     for (anIt.Init (anUnFreeCurves); anIt.More(); anIt.Next())
577     {
578       aNbVertices += anIt.Value()->Length();
579     }
580     Handle(Graphic3d_ArrayOfPolylines) anUnFreeArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds);
581     for (anIt.Init (anUnFreeCurves); anIt.More(); anIt.Next())
582     {
583       const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
584       anUnFreeArray->AddBound (aPoints->Length());
585       for (anI = 1; anI <= aPoints->Length(); ++anI)
586       {
587         anUnFreeArray->AddVertex (aPoints->Value (anI));
588       }
589     }
590     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
591     aGroup->SetPrimitivesAspect (theDrawer->UnFreeBoundaryAspect()->Aspect());
592     aGroup->AddPrimitiveArray (anUnFreeArray);
593   }
594
595   // Points
596   TColgp_SequenceOfPnt aShapePoints;
597   for (aTool.InitVertex(); aTool.MoreVertex(); aTool.NextVertex())
598   {
599     aShapePoints.Append (BRep_Tool::Pnt (aTool.GetVertex()));
600   }
601
602   aNbVertices = aShapePoints.Length();
603   if (aNbVertices > 0)
604   {
605     Handle(Graphic3d_ArrayOfPoints) aPointArray = new Graphic3d_ArrayOfPoints (aNbVertices);
606     for (anI = 1; anI <= aNbVertices; ++anI)
607     {
608       aPointArray->AddVertex (aShapePoints.Value (anI));
609     }
610
611     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation);
612     aGroup->SetPrimitivesAspect (theDrawer->PointAspect()->Aspect());
613     aGroup->AddPrimitiveArray (aPointArray);
614   }
615 }
616
617 // =========================================================================
618 // function: PickCurve
619 // purpose :
620 // =========================================================================
621 Handle(TopTools_HSequenceOfShape) Prs3d_WFShape::PickCurve
622       (const Quantity_Length        theX,
623        const Quantity_Length        theY,
624        const Quantity_Length        theZ,
625        const Quantity_Length        theDistance,
626        const TopoDS_Shape&          theShape,
627        const Handle (Prs3d_Drawer)& theDrawer)
628 {
629   Handle(TopTools_HSequenceOfShape) aSeq = new TopTools_HSequenceOfShape();
630   Prs3d_ShapeTool aTool (theShape);
631   for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve())
632   {
633     Bnd_Box aBndBox = aTool.CurveBound();
634     aBndBox.Enlarge (theDistance);
635     if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ)))
636     {
637       if (myCurveAlgo.Match (theX, theY, theZ, theDistance,
638                              BRepAdaptor_Curve (aTool.GetCurve()), theDrawer))
639       {
640         Standard_Boolean isContain = Standard_False;
641         for (Standard_Integer anI = 1; anI <= aSeq->Length(); ++anI)
642         {
643           if (aSeq->Value (anI) == (aTool.GetCurve()))
644           {
645             isContain = Standard_True;
646             break;
647           }
648         }
649         if (!isContain)
650         {
651           aSeq->Append (aTool.GetCurve());
652         }
653       }
654     }
655   }
656   return aSeq;
657 }
658
659 // =========================================================================
660 // function: PickPatch
661 // purpose :
662 // =========================================================================
663 Handle(TopTools_HSequenceOfShape) Prs3d_WFShape::PickPatch
664       (const Quantity_Length       theX,
665        const Quantity_Length       theY,
666        const Quantity_Length       theZ,
667        const Quantity_Length       theDistance,
668        const TopoDS_Shape&         theShape,
669        const Handle(Prs3d_Drawer)& theDrawer)
670 {
671    Handle(TopTools_HSequenceOfShape) aSeq = new TopTools_HSequenceOfShape();
672    Prs3d_ShapeTool aTool (theShape);
673
674    Standard_Boolean aRba1 = theDrawer->UIsoAspect()->Number() != 0;
675    Standard_Boolean aRba2 = theDrawer->VIsoAspect()->Number() != 0;
676    Standard_Boolean isContain;
677
678    if (aRba1 || aRba2)
679    {
680      BRepAdaptor_Surface aSurface;
681      for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace())
682      {
683        Bnd_Box aBndBox = aTool.FaceBound();
684        aBndBox.Enlarge (theDistance);
685        if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ)))
686        {
687          aSurface.Initialize (aTool.GetFace());
688          Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface);
689          if (myFaceAlgo.Match (theX, theY, theZ, theDistance, aHSurface, theDrawer))
690          {
691            isContain = Standard_False;
692            for (Standard_Integer anI = 1; anI <= aSeq->Length(); ++anI)
693            {
694              if (aSeq->Value (anI) == (aTool.GetFace()))
695              {
696                isContain = Standard_True;
697                break;
698              }
699            }
700            if (!isContain)
701            {
702              aSeq->Append (aTool.GetFace());
703            }
704          }
705        }
706      }
707    }
708
709    for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve())
710    {
711      Bnd_Box aBndBox = aTool.CurveBound();
712      aBndBox.Enlarge (theDistance);
713      if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ)))
714      {
715        if (myCurveAlgo.Match (theX, theY, theZ, theDistance,
716                               BRepAdaptor_Curve(aTool.GetCurve()), theDrawer))
717        {
718          Handle(TopTools_HSequenceOfShape) aSurface = aTool.FacesOfEdge();
719          for (Standard_Integer anI = 1; anI <= aSurface->Length(); ++anI)
720          {
721            isContain = Standard_False;
722            for (Standard_Integer aJ = 1; aJ <= aSeq->Length(); ++aJ)
723            {
724              if (aSeq->Value (aJ) == (aSurface->Value (anI)))
725              {
726                isContain = Standard_True;
727                break;
728              }
729            }
730            if (!isContain)
731            {
732              aSeq->Append (aSurface->Value (anI));
733            }
734          }
735        }
736      }
737    }
738    return aSeq;
739 }