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