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