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