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