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