0023024: Update headers of OCCT files
[occt.git] / src / BRepAlgo / BRepAlgo_NormalProjection.cxx
1 // Created on: 1997-10-13
2 // Created by: Roman BORISOV
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <BRepAlgo_NormalProjection.ixx>
23 #include <ProjLib_CompProjectedCurve.hxx>
24 #include <TopTools_HSequenceOfShape.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopAbs.hxx>
27 #include <BRepAdaptor_Curve.hxx>
28 #include <BRepAdaptor_HCurve.hxx>
29 #include <BRepAdaptor_Surface.hxx>
30 #include <BRepAdaptor_HSurface.hxx>
31 #include <ProjLib_HCompProjectedCurve.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <Approx_CurveOnSurface.hxx>
35 #include <TopoDS.hxx>
36 #include <BRep_Builder.hxx>
37 #include <BRepLib_MakeVertex.hxx>
38 #include <BRepLib_MakeWire.hxx>
39 #include <Geom2dAdaptor_HCurve.hxx>
40 #include <Geom2d_Curve.hxx>
41 #include <Geom_BSplineCurve.hxx>
42 #include <GeomAdaptor.hxx>
43 #include <BRepLib_MakeEdge.hxx>
44 #include <BRepAlgo_BooleanOperations.hxx>
45 #include <TopOpeBRepBuild_HBuilder.hxx>
46 #include <BRepTopAdaptor_FClass2d.hxx>
47 #include <Precision.hxx>
48 #include <BRepAlgo_SequenceOfSequenceOfInteger.hxx>
49 #include <TopExp.hxx>
50 #include <BRepTools.hxx>
51 #include <TColgp_Array1OfPnt2d.hxx>
52 #include <TColStd_Array1OfReal.hxx>
53 #include <TColStd_Array1OfInteger.hxx>
54 #include <Geom2d_TrimmedCurve.hxx>
55 #include <Geom2d_BSplineCurve.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57
58 #ifdef __OCC_DEBUG_CHRONO
59 #include <OSD_Timer.hxx>
60
61 OSD_Chronometer chr_total, chr_init, chr_approx, chr_booltool;
62
63 Standard_Real t_total, t_init, t_approx, t_booltool;
64 Standard_IMPORT Standard_Real t_init_point, t_dicho_bound;
65 Standard_IMPORT Standard_Integer init_point_count, dicho_bound_count;
66
67 void InitChron(OSD_Chronometer& ch)
68
69     ch.Reset();
70     ch.Start();
71 }
72
73 void ResultChron( OSD_Chronometer & ch, Standard_Real & time) 
74 {
75     Standard_Real tch ;
76     ch.Stop();
77     ch.Show(tch);
78     time=time +tch;
79 }
80
81 #endif
82 //=======================================================================
83 //function : BRepAlgo_NormalProjection
84 //purpose  : 
85 //=======================================================================
86
87  BRepAlgo_NormalProjection::BRepAlgo_NormalProjection() 
88    : myWith3d(Standard_True)
89
90 {
91   BRep_Builder BB;
92   BB.MakeCompound(TopoDS::Compound(myToProj));
93   myFaceBounds=Standard_True;
94   SetDefaultParams();
95   myMaxDist = -1;
96 }
97
98 //=======================================================================
99 //function : BRepAlgo_NormalProjection
100 //purpose  : 
101 //=======================================================================
102
103  BRepAlgo_NormalProjection::BRepAlgo_NormalProjection(const TopoDS_Shape& S) 
104     : myWith3d(Standard_True)
105 {
106   BRep_Builder BB;
107   BB.MakeCompound(TopoDS::Compound(myToProj));
108   SetDefaultParams();
109   myMaxDist = -1;
110   Init(S);
111 }
112
113 //=======================================================================
114 //function : Init
115 //purpose  : 
116 //=======================================================================
117
118  void BRepAlgo_NormalProjection::Init(const TopoDS_Shape& S) 
119 {
120   myShape = S;
121 }
122
123 //=======================================================================
124 //function : Add
125 //purpose  : 
126 //=======================================================================
127
128  void BRepAlgo_NormalProjection::Add(const TopoDS_Shape& ToProj) 
129 {
130   BRep_Builder BB;
131   BB.Add(myToProj, ToProj);
132 }
133
134 //=======================================================================
135 //function : SetParams
136 //purpose  : 
137 //=======================================================================
138
139 void BRepAlgo_NormalProjection::SetParams(const Standard_Real Tol3D,
140                                            const Standard_Real Tol2D,
141                                            const GeomAbs_Shape InternalContinuity,
142                                            const Standard_Integer MaxDegree,
143                                            const Standard_Integer MaxSeg) 
144 {
145   myTol3d = Tol3D;
146   myTol2d = Tol2D;
147   myContinuity = InternalContinuity;
148   myMaxDegree = MaxDegree;
149   myMaxSeg = MaxSeg;
150 }
151
152 //=======================================================================
153 //function : SetDefaultParams
154 //purpose  : 
155 //=======================================================================
156
157 void BRepAlgo_NormalProjection::SetDefaultParams()
158 {
159   myTol3d = 1.e-4;
160   myTol2d = Pow(myTol3d, 2./3);
161   myContinuity = GeomAbs_C2;
162   myMaxDegree = 14;
163   myMaxSeg    = 16;
164 }
165
166 //=======================================================================
167 //function : SetLimits
168 //purpose  : 
169 //=======================================================================
170
171  void BRepAlgo_NormalProjection::SetLimit(const Standard_Boolean FaceBounds)
172 {
173   myFaceBounds = FaceBounds;
174 }
175
176 //=======================================================================
177 //function : SetMaxDistance
178 //purpose  : 
179 //=======================================================================
180
181  void BRepAlgo_NormalProjection::SetMaxDistance(const Standard_Real MaxDist)
182 {
183   myMaxDist = MaxDist;
184 }
185
186 //=======================================================================
187 //function : Compute3d
188 //purpose  : 
189 //=======================================================================
190
191  void BRepAlgo_NormalProjection::Compute3d(const Standard_Boolean With3d)
192 {
193   myWith3d = With3d;
194 }
195
196 //=======================================================================
197 //function : Build
198 //purpose  : 
199 //=======================================================================
200
201  void BRepAlgo_NormalProjection::Build() 
202 {
203 #ifdef __OCC_DEBUG_CHRONO
204   Standard_Integer init_count = 0, approx_count = 0, booltool_count = 0;
205   t_total = 0;
206   t_init = 0;
207   t_approx = 0;
208   t_booltool = 0;
209   
210   t_init_point = 0;
211   init_point_count = 0;
212   
213   t_dicho_bound = 0;
214   dicho_bound_count = 0;
215   
216   InitChron(chr_total);
217 #endif
218   myIsDone = Standard_False;
219   ProjLib_CompProjectedCurve Projector;
220   Handle(TopTools_HSequenceOfShape) Edges = new TopTools_HSequenceOfShape();
221   Handle(TopTools_HSequenceOfShape) Faces = new TopTools_HSequenceOfShape();
222   TopTools_ListOfShape DescenList;
223   Standard_Integer NbEdges = 0, NbFaces = 0, i, j, k;
224   TopExp_Explorer ExpOfWire, ExpOfShape;
225   Standard_Real Udeb, Ufin;
226   TopoDS_Shape VertexRes;
227   Standard_Boolean Only3d, Only2d, Elementary;
228   
229   // for isoparametric cases
230   TColgp_Array1OfPnt2d Poles(1, 2);
231   TColStd_Array1OfReal Knots(1, 2);
232   TColStd_Array1OfInteger Mults(1,2);
233   Standard_Integer Deg;
234   Deg = 1;
235   Mults(1) = Deg + 1;
236   Mults(2) = Deg + 1;
237   //
238   
239   for(ExpOfWire.Init(myToProj, TopAbs_EDGE); 
240       ExpOfWire.More(); 
241       ExpOfWire.Next(), NbEdges++) {
242     Edges->Append(ExpOfWire.Current());
243   }
244   
245   for(ExpOfShape.Init(myShape, TopAbs_FACE); 
246       ExpOfShape.More(); 
247       ExpOfShape.Next(), NbFaces++) {
248     Faces->Append(ExpOfShape.Current());
249   }
250   
251   BRep_Builder BB;
252   BB.MakeCompound(TopoDS::Compound(myRes));
253   BB.MakeCompound(TopoDS::Compound(VertexRes));
254   Standard_Boolean YaVertexRes = Standard_False;
255   
256   for(i = 1; i <= NbEdges; i++){
257     DescenList.Clear();
258     BRepAdaptor_Curve cur(TopoDS::Edge(Edges->Value(i)));
259     Handle(BRepAdaptor_HCurve) hcur = new BRepAdaptor_HCurve();
260     hcur->Set(cur);
261     Elementary = IsElementary(cur);
262     for(j = 1; j <= NbFaces; j++){
263       BRepAdaptor_Surface sur(TopoDS::Face(Faces->Value(j)));
264       Handle(BRepAdaptor_HSurface) hsur = new BRepAdaptor_HSurface();
265       hsur->Set(sur);
266       
267       // computation of  TolU and TolV
268       
269       Standard_Real  TolU, TolV;
270       
271       TolU = hsur->UResolution(myTol3d)/20;
272       TolV = hsur->VResolution(myTol3d)/20;
273       // Projection
274 #ifdef __OCC_DEBUG_CHRONO
275       InitChron(chr_init);
276 #endif
277       Projector = 
278         ProjLib_CompProjectedCurve(hsur, hcur, TolU, TolV, myMaxDist);
279 #ifdef __OCC_DEBUG_CHRONO
280       ResultChron(chr_init,t_init);
281       init_count++;
282 #endif
283       //
284       Handle(ProjLib_HCompProjectedCurve) HProjector = 
285         new ProjLib_HCompProjectedCurve();
286       HProjector->Set(Projector);
287       TopoDS_Shape prj;
288       Standard_Boolean Degenerated = Standard_False;
289       gp_Pnt2d P2d, Pdeb, Pfin;
290       gp_Pnt P;
291       Standard_Real UIso, VIso;
292       
293       Handle(Adaptor2d_HCurve2d) HPCur;
294       Handle(Geom2d_Curve) PCur2d; // Only for isoparametric projection
295       
296       for(k = 1; k <= Projector.NbCurves(); k++){
297         if(Projector.IsSinglePnt(k, P2d)){
298 #ifdef DEBUG
299           cout << "Projection of edge "<<i<<" on face "<<j;
300           cout << " is punctual"<<endl<<endl;
301 #endif
302           Projector.GetSurface()->D0(P2d.X(), P2d.Y(), P);
303           prj = BRepLib_MakeVertex(P).Shape();
304           DescenList.Append(prj);
305           BB.Add(VertexRes, prj);
306           YaVertexRes = Standard_True;
307           
308           myAncestorMap.Bind(prj, Edges->Value(i));
309         }
310         else {
311           Only2d = Only3d = Standard_False;
312           Projector.Bounds(k, Udeb, Ufin);
313           
314           /**************************************************************/
315           if (Projector.IsUIso(k, UIso)) {
316 #ifdef DEBUG
317             cout << "Projection of edge "<<i<<" on face "<<j;
318             cout << " is U-isoparametric"<<endl<<endl;
319 #endif
320             Projector.D0(Udeb, Pdeb);
321             Projector.D0(Ufin, Pfin);
322             Poles(1) = Pdeb;
323             Poles(2) = Pfin;
324             Knots(1) = Udeb;
325             Knots(2) = Ufin;
326             Handle(Geom2d_BSplineCurve) BS2d = 
327               new Geom2d_BSplineCurve(Poles, Knots, Mults, Deg);
328             PCur2d = new Geom2d_TrimmedCurve( BS2d, Udeb, Ufin);
329             HPCur = new Geom2dAdaptor_HCurve(PCur2d);
330             Only3d = Standard_True;
331           }
332           else if (Projector.IsVIso(k, VIso)) {
333 #ifdef DEBUG
334             cout << "Projection of edge "<<i<<" on face "<<j;
335             cout << " is V-isoparametric"<<endl<<endl;
336 #endif
337             Projector.D0(Udeb, Pdeb);
338             Projector.D0(Ufin, Pfin);
339             Poles(1) = Pdeb;
340             Poles(2) = Pfin;
341             Knots(1) = Udeb;
342             Knots(2) = Ufin;
343             Handle(Geom2d_BSplineCurve) BS2d = 
344               new Geom2d_BSplineCurve(Poles, Knots, Mults, Deg);
345             PCur2d = new Geom2d_TrimmedCurve(BS2d, Udeb, Ufin);
346             HPCur = new Geom2dAdaptor_HCurve(PCur2d);
347             Only3d = Standard_True;
348           }
349           else HPCur = HProjector;
350           
351           if((myWith3d == Standard_False || Elementary) && 
352              (Projector.MaxDistance(k) <= myTol3d)        )
353             Only2d = Standard_True;
354           
355           if(Only2d && Only3d) {
356             BRepLib_MakeEdge MKed(GeomAdaptor::MakeCurve(hcur->Curve()), 
357                                   Ufin, Udeb);
358             prj = MKed.Edge();
359             BB.UpdateEdge(TopoDS::Edge(prj), 
360                           PCur2d, 
361                           TopoDS::Face(Faces->Value(j)),
362                           myTol3d);
363             BB.UpdateVertex(TopExp::FirstVertex(TopoDS::Edge(prj)),myTol3d);
364             BB.UpdateVertex(TopExp::LastVertex(TopoDS::Edge(prj)),myTol3d);
365           }
366           else {
367 #ifdef __OCC_DEBUG_CHRONO
368             InitChron(chr_approx);
369 #endif
370             Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d, 
371                                        myContinuity, myMaxDegree, myMaxSeg, 
372                                        Only3d, Only2d);
373 #ifdef __OCC_DEBUG_CHRONO
374             ResultChron(chr_approx,t_approx);
375             approx_count++;
376             
377             cout<<"Approximation.IsDone = "<<appr.IsDone()<<endl;
378             if(!Only2d)
379               cout<<"MaxError3d = "<<appr.MaxError3d()<<endl<<endl;
380             if(!Only3d) {
381               cout<<"MaxError2dU = "<<appr.MaxError2dU()<<endl;
382               cout<<"MaxError2dV = "<<appr.MaxError2dV()<<endl<<endl;
383             }
384 #endif
385
386             
387             if(!Only3d) PCur2d = appr.Curve2d();
388             if(Only2d) {
389               BRepLib_MakeEdge MKed(GeomAdaptor::MakeCurve(hcur->Curve()), 
390                                     Udeb, Ufin);
391               prj = MKed.Edge();
392             }
393             else  {
394             // It is tested if the solution is not degenerated to set the
395             // flag on edge, one takes several points, checks if the cloud of 
396             // points has less diameter than the tolerance 3D
397               Degenerated = Standard_True;
398               Standard_Real Dist;
399               Handle(Geom_BSplineCurve) BS3d  = Handle(Geom_BSplineCurve)::DownCast( appr.Curve3d());
400               gp_Pnt P1(0.,0.,0.),PP; // skl : I change "P" to "PP"
401               Standard_Integer NbPoint,ii ; // skl : I change "i" to "ii"
402               Standard_Real Par,DPar;
403               // start from 3 points to reject non degenerated edges 
404               // very fast
405               NbPoint =3;
406               DPar = (BS3d->LastParameter()-BS3d->FirstParameter())/(NbPoint-1);
407               for (ii=0;ii<NbPoint;ii++)
408               {
409                  Par=BS3d->FirstParameter()+ii*DPar;
410                  PP=BS3d->Value(Par);
411                  P1.SetXYZ(P1.XYZ() + PP.XYZ()/NbPoint);
412               }
413               for (ii=0;ii<NbPoint && Degenerated ;ii++)   
414               {
415                  Par=BS3d->FirstParameter()+ii*DPar;
416                  PP=BS3d->Value(Par);                 
417                  Dist=P1.Distance(PP);
418                  if(Dist > myTol3d) {
419                      Degenerated = Standard_False;
420                      break;
421                  }
422               }             
423               // if the test passes a more exact test with 10 points
424               if (Degenerated) {
425                  P1.SetCoord(0.,0.,0.);
426                  NbPoint =10;
427                  DPar = (BS3d->LastParameter()-BS3d->FirstParameter())/(NbPoint-1);
428                  for (ii=0;ii<NbPoint;ii++)
429                  {
430                    Par=BS3d->FirstParameter()+ii*DPar;
431                    PP=BS3d->Value(Par);
432                    P1.SetXYZ(P1.XYZ() + PP.XYZ()/NbPoint);
433                  }
434                  for (ii=0;ii<NbPoint && Degenerated ;ii++)   
435                  {
436                    Par=BS3d->FirstParameter()+ii*DPar;
437                    PP=BS3d->Value(Par);                 
438                    Dist=P1.Distance(PP);
439                    if(Dist > myTol3d) {
440                      Degenerated = Standard_False;
441                      break;
442                    }
443                  }             
444               }
445               if (Degenerated) {
446 #ifdef DEBUG
447                   cout << "Projection of edge "<<i<<" on face "<<j;
448                   cout << " is degenerated "<<endl<<endl;
449 #endif
450                 TopoDS_Vertex VV;
451                 BB.MakeVertex(VV);
452                 BB.UpdateVertex(VV,P1,myTol3d);
453                 BB.MakeEdge(TopoDS::Edge(prj));
454                 BB.Add(TopoDS::Edge(prj),VV.Oriented(TopAbs_FORWARD));
455                 BB.Add(TopoDS::Edge(prj),VV.Oriented(TopAbs_REVERSED));
456                 BB.Degenerated(TopoDS::Edge(prj), Standard_True);
457               }
458               else {
459                 prj = BRepLib_MakeEdge(BS3d).Edge();
460               }
461             }
462             
463             BB.UpdateEdge(TopoDS::Edge(prj), 
464                           PCur2d,
465                           TopoDS::Face(Faces->Value(j)), 
466                           appr.MaxError3d());
467             BB.UpdateVertex(TopExp::FirstVertex(TopoDS::Edge(prj)),appr.MaxError3d());
468             BB.UpdateVertex(TopExp::LastVertex(TopoDS::Edge(prj)),appr.MaxError3d());
469             if (Degenerated) {
470               BB.Range(TopoDS::Edge(prj),
471                        TopoDS::Face(Faces->Value(j)),
472                        Udeb,Ufin);
473             }
474           }
475           
476           if(myFaceBounds) {
477             // Trimming edges by face bounds 
478             // if the solution is degenerated, use of BoolTool is avoided
479 #ifdef __OCC_DEBUG_CHRONO
480             InitChron(chr_booltool);
481 #endif
482             if(!Degenerated){
483                BRepAlgo_BooleanOperations BoolTool;
484                BoolTool.Shapes2d(Faces->Value(j),prj);
485                BoolTool.Common();
486                Handle(TopOpeBRepBuild_HBuilder) HB;
487                TopTools_ListOfShape LS;
488                TopTools_ListIteratorOfListOfShape Iter; 
489                HB = BoolTool.Builder();
490                LS.Clear();
491                if (HB->IsSplit(prj, TopAbs_IN))
492                  LS = HB->Splits(prj, TopAbs_IN);
493                Iter.Initialize(LS);
494                if(Iter.More()) {
495 #ifdef DEBUG
496                   cout << " BooleanOperations :"  << Iter.More()<<" solutions " << endl; 
497 #endif
498                   for(; Iter.More(); Iter.Next()) {
499                      BB.Add(myRes, Iter.Value());
500                      myAncestorMap.Bind(Iter.Value(), Edges->Value(i));
501                      myCorresp.Bind(Iter.Value(),Faces->Value(j));
502                   }
503                }
504
505                else {
506
507                  BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)),
508                                                     Precision::Confusion());
509                  gp_Pnt2d Puv;
510                  Standard_Real f = PCur2d->FirstParameter();
511                  Standard_Real l = PCur2d->LastParameter();
512                  Standard_Real pmil = (f + l )/2;
513                  PCur2d->D0(pmil, Puv);
514                  TopAbs_State state;
515                  state = classifier.Perform(Puv);
516                  if(state == TopAbs_IN || state  == TopAbs_ON) {
517                    BB.Add(myRes, prj);
518                    DescenList.Append(prj);
519                    myAncestorMap.Bind(prj, Edges->Value(i));   
520                    myCorresp.Bind(prj, Faces->Value(j));
521                  }
522                }
523             }
524             else {
525 #ifdef DEB
526                  cout << " BooleanOperations : no solution " << endl;
527 #endif
528
529               BRepTopAdaptor_FClass2d classifier(TopoDS::Face(Faces->Value(j)),
530                                                  Precision::Confusion());
531               gp_Pnt2d Puv;
532               Standard_Real f = PCur2d->FirstParameter();
533               Standard_Real l = PCur2d->LastParameter();
534               Standard_Real pmil = (f + l )/2;
535               PCur2d->D0(pmil, Puv);
536               TopAbs_State state;
537               state = classifier.Perform(Puv);
538               if(state == TopAbs_IN || state  == TopAbs_ON) {
539                  BB.Add(myRes, prj);
540                  DescenList.Append(prj);
541                  myAncestorMap.Bind(prj, Edges->Value(i));   
542                  myCorresp.Bind(prj, Faces->Value(j));
543               }
544 #ifdef __OCC_DEBUG_CHRONO
545                ResultChron(chr_booltool,t_booltool);
546                booltool_count++;
547 #endif
548             }
549           }
550           else {
551             BB.Add(myRes, prj);
552             DescenList.Append(prj);
553             myAncestorMap.Bind(prj, Edges->Value(i));   
554             myCorresp.Bind(prj, Faces->Value(j));
555           }
556         }
557       }
558     }
559     myDescendants.Bind(Edges->Value(i), DescenList);
560   }
561 // JPI : eventual wire creation is reported in a specific method 
562 //       BuilWire that can be called by the user. Otherwise, the 
563 //       relations of map myAncestorMap, myCorresp will be lost.  
564
565   if(YaVertexRes) BB.Add(myRes, VertexRes);
566   
567   myIsDone = Standard_True; 
568   
569 #ifdef __OCC_DEBUG_CHRONO
570   ResultChron(chr_total,t_total);
571   
572   cout<<"Build - Total time  : "<<t_total<<" includes:" <<endl;
573   cout<<"- Projection           : "<<t_init<<endl;
574   cout<<"  -- Initial point search : "<<t_init_point<<endl;
575   cout<<"  -- DichoBound search : "<<t_dicho_bound<<endl;
576   cout<<"- Approximation        : "<<t_approx<<endl;
577   cout<<"- Boolean operation    : "<<t_booltool<<endl;
578   cout<<"- Rest of time         : "<<t_total-(t_init + t_approx + t_booltool )<<endl<<endl;
579   if (init_count != 0)
580     t_init /= init_count;
581   if (init_point_count != 0)
582     t_init_point /= init_point_count;
583   if (dicho_bound_count != 0)
584     t_dicho_bound /= dicho_bound_count;
585   if (approx_count != 0)
586     t_approx /= approx_count;
587   if (booltool_count != 0)
588     t_booltool /= booltool_count;
589   
590   cout<<"Unitary average time  : "<<endl;
591   cout<<"- Projection          : "<<t_init<<endl;
592   cout<<"  -- Initial point search: "<<t_init_point<<endl;
593   cout<<"  -- DichoBound search : "<<t_dicho_bound<<endl;
594   cout<<"- Approximation       : "<<t_approx<<endl;
595   cout<<"- Boolean operation   :"<<t_booltool<<endl;
596   cout<<endl<<"Number of initial point computations is "<<init_point_count<<endl<<endl;
597 #endif
598 }
599
600 //=======================================================================
601 //function : IsDone
602 //purpose  : 
603 //=======================================================================
604
605  Standard_Boolean BRepAlgo_NormalProjection::IsDone() const
606 {
607   return myIsDone;
608 }
609
610 //=======================================================================
611 //function : Projection
612 //purpose  : 
613 //=======================================================================
614
615  const TopoDS_Shape& BRepAlgo_NormalProjection::Projection() const
616 {
617   return myRes;
618 }
619
620 //=======================================================================
621 //function : Ancestor
622 //purpose  : 
623 //=======================================================================
624
625  const TopoDS_Shape& BRepAlgo_NormalProjection::Ancestor(const TopoDS_Edge& E) const
626 {
627   return myAncestorMap.Find(E);
628 }
629
630 //=======================================================================
631 //function : Couple
632 //purpose  : 
633 //=======================================================================
634
635  const TopoDS_Shape& BRepAlgo_NormalProjection::Couple(const TopoDS_Edge& E) const
636 {
637   return myCorresp.Find(E);
638 }
639
640 //=======================================================================
641 //function : Generated
642 //purpose  : 
643 //=======================================================================
644
645  const TopTools_ListOfShape& BRepAlgo_NormalProjection::Generated(const TopoDS_Shape& S)
646 {
647   return myDescendants.Find(S);
648 }
649
650 //=======================================================================
651 //function : IsElementary
652 //purpose  : 
653 //=======================================================================
654
655  Standard_Boolean BRepAlgo_NormalProjection::IsElementary(const Adaptor3d_Curve& C) const
656 {
657   GeomAbs_CurveType type;
658   type = C.GetType();
659   switch(type) {
660   case GeomAbs_Line:
661   case GeomAbs_Circle:
662   case GeomAbs_Ellipse:
663   case GeomAbs_Hyperbola:
664   case GeomAbs_Parabola: return Standard_True;
665   default: return Standard_False;
666   }
667 }
668 //=======================================================================
669 //function : BuildWire
670 //purpose  : 
671 //=======================================================================
672  
673  Standard_Boolean BRepAlgo_NormalProjection::BuildWire(TopTools_ListOfShape& ListOfWire) const
674 {
675   TopExp_Explorer ExpOfWire, ExpOfShape; 
676   Standard_Boolean IsWire=Standard_False;
677   ExpOfShape.Init(myRes, TopAbs_EDGE);
678   if(ExpOfShape.More()) 
679   {
680     TopTools_ListOfShape List;
681
682     for ( ; ExpOfShape.More(); ExpOfShape.Next()) 
683     {
684       const TopoDS_Shape& CurE = ExpOfShape.Current();
685       List.Append(CurE);
686     }
687     BRepLib_MakeWire MW;
688     MW.Add(List);
689     if (MW.IsDone()) 
690     {
691       const TopoDS_Shape& Wire = MW.Shape();
692       // If the resulting wire contains the same edge as at the beginning OK
693       // otherwise the result really consists of several wires.
694       TopExp_Explorer exp2(Wire,TopAbs_EDGE);
695       Standard_Integer NbEdges = 0;
696       for (;exp2.More(); exp2.Next()) NbEdges++;
697       if ( NbEdges == List.Extent()) 
698       {
699           ListOfWire.Append(Wire);
700           IsWire = Standard_True;
701       }
702     }
703   }
704    return IsWire;
705 }