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