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