0022627: Change OCCT memory management defaults
[occt.git] / src / ShapeFix / ShapeFix_Edge.cxx
CommitLineData
7fd59977 1// abv 30 Dec 98: code optimizations
2//:o1 abv 16.02.99: updating vertices tolerance when edge is updated
3// rln 03.03.99 S4135: removed unnecessary check for Geom_SphericalSurface (as not V-closed)
4//:q8 abv 23.03.99: bm4_al_eye.stp #53710: avoid shifting pcurves for pseudo-seam
5//#78 rln 12.03.99 S4135: checking spatial closure with prec
6//#81 rln 15.03.99 S4135: for not SP edge chose the best result (either BRepLib or deviation only)
7//#82 rln 16.03.99 S4135: avoiding setting input precision into the edge in FixAddPCurve
8//:r4 abv 02.04.99 improving method FixSameParameter()
9//:s5 abv 22.04.99 Adding debug printouts in catch {} blocks
10// abv 05.05.99 S4137: method CopyPCurves moved to ShapeBuild_Edge
11#include <ShapeFix_Edge.ixx>
12
13#include <Standard_ErrorHandler.hxx>
14#include <Standard_Failure.hxx>
15
16#include <BRep_Builder.hxx>
17#include <BRep_GCurve.hxx>
18#include <BRep_TEdge.hxx>
19#include <BRep_Tool.hxx>
20#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
21#include <BRep_ListOfCurveRepresentation.hxx>
22#include <BRepLib.hxx>
23
24#include <Geom2d_Curve.hxx>
25#include <Geom2d_Line.hxx>
26#include <Geom2d_BSplineCurve.hxx>
27#include <Geom2d_TrimmedCurve.hxx>
28#include <Geom2d_BezierCurve.hxx>
29
30#include <Geom_Curve.hxx>
31#include <GeomLib.hxx>
32
33#include <Precision.hxx>
34#include <TopExp.hxx>
35#include <TopoDS_Vertex.hxx>
36#include <TopoDS.hxx>
37
38#include <ShapeAnalysis_Edge.hxx>
39#include <ShapeExtend.hxx>
40#include <ShapeBuild_Edge.hxx>
41#include <ShapeFix_ShapeTolerance.hxx>
42#include <Geom2d_OffsetCurve.hxx>
43#include <ShapeAnalysis_Curve.hxx>
44
45
46//=======================================================================
47//function : ShapeFix_Edge
48//purpose :
49//=======================================================================
50
51ShapeFix_Edge::ShapeFix_Edge()
52{
53 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
54 myProjector = new ShapeConstruct_ProjectCurveOnSurface;
55}
56
57//=======================================================================
58//function : Projector
59//purpose :
60//=======================================================================
61
62Handle(ShapeConstruct_ProjectCurveOnSurface) ShapeFix_Edge::Projector()
63{
64 return myProjector;
65}
66
67
68//=======================================================================
69//function : FixRemovePCurve
70//purpose :
71//=======================================================================
72
73Standard_Boolean ShapeFix_Edge::FixRemovePCurve (const TopoDS_Edge& edge,
74 const TopoDS_Face& face)
75{
76 TopLoc_Location L;
77 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
78 return FixRemovePCurve (edge, S, L);
79}
80
81//=======================================================================
82//function : FixRemovePCurve
83//purpose :
84//=======================================================================
85
86Standard_Boolean ShapeFix_Edge::FixRemovePCurve (const TopoDS_Edge& edge,
87 const Handle(Geom_Surface)& surface,
88 const TopLoc_Location& location)
89{
90 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
91 ShapeAnalysis_Edge EA;
92 Standard_Boolean result = EA.CheckVerticesWithPCurve (edge, surface, location);
93 if (result) ShapeBuild_Edge().RemovePCurve (edge, surface, location);
94 return result;
95}
96
97//=======================================================================
98//function : FixRemoveCurve3d
99//purpose :
100//=======================================================================
101
102Standard_Boolean ShapeFix_Edge::FixRemoveCurve3d (const TopoDS_Edge& edge)
103{
104 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
105 ShapeAnalysis_Edge EA;
106 Standard_Boolean result = EA.CheckVerticesWithCurve3d (edge);
107 if (result) ShapeBuild_Edge().RemoveCurve3d (edge);
108 return result;
109}
110
111//=======================================================================
112//function : FixAddPCurve
113//purpose :
114//=======================================================================
115
116Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
117 const TopoDS_Face& face,
118 const Standard_Boolean isSeam,
119 const Standard_Real prec)
120{
121 TopLoc_Location L;
122 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
123 return FixAddPCurve (edge, S, L, isSeam, prec);
124}
125
126//=======================================================================
127//function : FixAddPCurve
128//purpose :
129//=======================================================================
130
131Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
132 const Handle(Geom_Surface)& surface,
133 const TopLoc_Location& location,
134 const Standard_Boolean isSeam,
135 const Standard_Real prec)
136{
137 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface (surface);
138 return FixAddPCurve (edge, surface, location, isSeam, sas, prec);
139}
140
141//=======================================================================
142//function : FixAddPCurve
143//purpose :
144//=======================================================================
145
146Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
147 const TopoDS_Face& face,
148 const Standard_Boolean isSeam,
149 const Handle(ShapeAnalysis_Surface)& surfana,
150 const Standard_Real prec)
151{
152 TopLoc_Location L;
153 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
154 return FixAddPCurve (edge, S, L, isSeam, surfana, prec);
155}
156
157//=======================================================================
158//function : FixAddPCurve
159//purpose :
160//=======================================================================
161
162//#12 rln 17/03/98 making this method to be more general : if a curve is
163//parallel to one iso let us translate it parallely in the direction to another
164//iso (which is located farther from aC2d). Thus, the requirement for closeness
165//to the surface bounds may be avoid.
166//For example, instead of Abs(theLoc.X()-uf) <= Tol) ... elseif (...-ul..)...
167//the comparison if (Abs(theLoc.X()-uf) <= Abs(theLoc.X()-ul)) .... can be used.
168
169//The reason of this fix #12 is that seam is not sure to lie on the bound :
170//if a surface is periodic the whole contour may be shifted (e.g. ProSTEP,
171//file ug_exhaust-A.stp entity #284920)
172
173static Handle(Geom2d_Curve) TranslatePCurve (const Handle(Geom_Surface)& aSurf,
174 Handle(Geom2d_Curve)& aC2d,
175 const Standard_Real& aTol)
176{
177 Standard_Real uf,ul,vf,vl;
178 aSurf->Bounds(uf,ul,vf,vl);
179
180 // cas d une ligne
181 Handle(Geom2d_Line) theL2d = Handle(Geom2d_Line)::DownCast(aC2d);
182 if (!theL2d.IsNull()) {
183 gp_Pnt2d theLoc = theL2d->Location();
184 gp_Dir2d theDir = theL2d->Direction();
185
186 gp_Pnt2d newLoc;
187 Handle(Geom2d_Line) theNewL2d = theL2d;
188
189 //case UClosed
190 if (Abs(theDir.X()) <= aTol && Abs(theDir.Y()) >= aTol) {
191 if (Abs(theLoc.X() - uf) < Abs(theLoc.X() - ul))
192 newLoc.SetCoord (theLoc.X() + (ul - uf), theLoc.Y());
193 else
194 newLoc.SetCoord (theLoc.X() - (ul - uf), theLoc.Y());
195 theNewL2d = new Geom2d_Line(newLoc, theDir);
196 }
197/* // case UClosed and line in U = UFirst
198 if ((Abs(theLoc.X() - uf) <= aTol) &&
199 (Abs(theDir.X()) <= aTol) &&
200 (Abs(theDir.Y()) >= aTol)) {
201 // on translate en ul
202 gp_Pnt2d newLoc(ul, theLoc.Y());
203 Handle(Geom2d_Line) theNewL2d = new Geom2d_Line(newLoc, theDir);
204 return theNewL2d;
205 }
206 // cas UClosed and line in U = ULast
207 if ((Abs(theLoc.X() - ul) <= aTol) &&
208 (Abs(theDir.X()) <= aTol) &&
209 (Abs(theDir.Y()) >= aTol)) {
210 // on translate en uf
211 gp_Pnt2d newLoc(uf, theLoc.Y());
212 Handle(Geom2d_Line) theNewL2d = new Geom2d_Line(newLoc, theDir);
213 return theNewL2d;
214 }
215*/
216 //case VClosed
217 if (Abs(theDir.X()) >= aTol && Abs(theDir.Y()) <= aTol) {
218 if (Abs(theLoc.Y() - vf) < Abs(theLoc.Y() - vl))
219 newLoc.SetCoord (theLoc.X(), theLoc.Y() + (vl - vf));
220 else
221 newLoc.SetCoord (theLoc.X(), theLoc.Y() - (vl - vf));
222 theNewL2d = new Geom2d_Line(newLoc, theDir);
223 }
224/* // case VClosed and line in V = VFirst
225 if ((Abs(theLoc.Y() - vf) <= aTol) &&
226 (Abs(theDir.X()) >= aTol) &&
227 (Abs(theDir.Y()) <= aTol)) {
228 // on translate en vl
229 gp_Pnt2d newLoc(theLoc.X(), vl);
230 Handle(Geom2d_Line) theNewL2d = new Geom2d_Line(newLoc, theDir);
231 return theNewL2d;
232 }
233 // cas VClosed and line in V = VLast
234 if ((Abs(theLoc.Y() - vl) <= aTol) &&
235 (Abs(theDir.X()) >= aTol) &&
236 (Abs(theDir.Y()) <= aTol)) {
237 // on translate en vf
238 gp_Pnt2d newLoc(theLoc.X(), vf);
239 Handle(Geom2d_Line) theNewL2d = new Geom2d_Line(newLoc, theDir);
240 return theNewL2d;
241 }
242*/
243 // Other case not yet implemented
244#ifdef DEBUG
245 cout << "TranslatePCurve not performed" << endl;
246#endif
247 return theNewL2d;//*theL2d;
248 }
249 else {
250 // cas bspline curve
251 Handle(Geom2d_BSplineCurve)
252 aBC = Handle(Geom2d_BSplineCurve)::DownCast(aC2d);
253 if (aBC.IsNull()) {
254#ifdef DEBUG
255 cout << "Untreated curve type in TranslatePCurve" << endl;
256#endif
257 return aC2d;
258 }
259 Handle(Geom2d_BSplineCurve) newC =
260 Handle(Geom2d_BSplineCurve)::DownCast(aBC->Copy());
261 gp_Pnt2d FirstPoint = aBC->StartPoint();
262 gp_Pnt2d LastPoint = aBC->EndPoint();
263 gp_Vec2d theVector (FirstPoint, LastPoint);
264 gp_Pnt2d p00(uf, vf), p01(uf,vl), p10(ul,vf);
265 gp_Vec2d VectIsoUF(p00, p01);
266 gp_Vec2d VectIsoVF(p00, p10);
267
268 gp_Trsf2d T;
269 if (theVector.IsParallel(VectIsoUF, aTol)) {
270 if (Abs(FirstPoint.X() - uf) < Abs(FirstPoint.X() - ul)) T.SetTranslation(p00, p10);
271 else T.SetTranslation(p10, p00);
272 newC->Transform(T);
273 return newC;
274 }
275/* // case UClosed and line in U = UFirst
276 if (Abs(FirstPoint.X() - uf) <= aTol) {
277 gp_Trsf2d T;
278 T.SetTranslation(p00, p10);
279 newC->Transform(T);
280 return newC;
281 }
282 // case UClosed and line in U = ULast
283 else if (Abs(FirstPoint.X() - ul) <= aTol) {
284 gp_Trsf2d T;
285 T.SetTranslation(p10, p00);
286 newC->Transform(T);
287 return newC;
288 }
289 else { // les courbes ne sont pas sur la couture
290 return aC2d;
291 }
292*/
293 else if (theVector.IsParallel(VectIsoVF, aTol)) {
294//#ifdef DEBUG
295// cout << "other curve-VClosed Surface. TranslatePC not impl." << endl;
296//#endif
297 if (Abs(FirstPoint.Y() - vf) < Abs(FirstPoint.Y() - vl)) T.SetTranslation(p00, p01);
298 else T.SetTranslation(p01, p00);
299 newC->Transform(T);
300 return newC;
301 }
302 }
303 // les courbes ne sont pas sur la couture
304 return aC2d;
305}
306
307//=======================================================================
308//static : Range3d
309//purpose : contournement du Range de BRep_Builder pour ne pas affecter
310// les ranges des pcurves.
311//=======================================================================
312
313static void Range3d (const TopoDS_Edge& E,
314 const Standard_Real First, const Standard_Real Last,
315 const Standard_Real myPrecision)
316{
317 // set the range to all the representations
318 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
319
320 BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
321 BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
322 Handle(BRep_GCurve) GC;
323
324 while (itcr.More()) {
325 GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
326 if (!GC.IsNull()) {
327 if (GC->IsCurve3D()) {
328 GC->SetRange(First,Last);
329 // Set the closedness flag to the correct value.
330 Handle(Geom_Curve) C = GC->Curve3D();
331 if ( !C.IsNull() ) {
332 Standard_Boolean closed = C->Value(First).IsEqual(C->Value(Last),myPrecision);
333 TE->Closed(closed);
334 }
335 }
336 }
337 itcr.Next();
338 }
339
340 TE->Modified(Standard_True);
341}
342//=======================================================================
343//function : SameRange (Temp)
344//purpose :
345//=======================================================================
346//:b0 abv 16 Feb 98: This is a copy of BRepLib::SameRange()
347// modified in order to be able to fix seam edges
348// NOTE: It is to be removed when is fixed either BRepLib::SameRange()
349// (concerning seam edges) or BRepLib::SameParameter() (concerning call
350// to GeomLib::SameRange() with 3d tolerance)
351
352 static void TempSameRange(const TopoDS_Edge& AnEdge,
353 const Standard_Real Tolerance)
354{
355 BRep_ListIteratorOfListOfCurveRepresentation an_Iterator
356 ((*((Handle(BRep_TEdge)*)&AnEdge.TShape()))->ChangeCurves());
357
358 Handle(Geom2d_Curve) Curve2dPtr, NewCurve2dPtr;
359 Handle(Geom2d_Curve) Curve2dPtr2, NewCurve2dPtr2;
360 TopLoc_Location LocalLoc ;
361
362 //Standard_Boolean IsSameRange = Standard_True //skl
363 Standard_Boolean first_time_in = Standard_True, has_curve, has_closed_curve;
364 Handle(BRep_GCurve) geometric_representation_ptr;
365 Standard_Real first, current_first, last, current_last;
366
367 const Handle(Geom_Curve) C = BRep_Tool::Curve(AnEdge, LocalLoc,
368 current_first, current_last);
369 if (!C.IsNull()) first_time_in = Standard_False;
370
371 while (an_Iterator.More()) {
372 geometric_representation_ptr =
373 Handle(BRep_GCurve)::DownCast(an_Iterator.Value());
374 if (! geometric_representation_ptr.IsNull()) {
375 has_closed_curve = has_curve = Standard_False;
376 first = geometric_representation_ptr->First();
377 last = geometric_representation_ptr->Last();
378 if (geometric_representation_ptr->IsCurveOnSurface()) {
379 Curve2dPtr = geometric_representation_ptr->PCurve() ;
380 has_curve = Standard_True ;
381 }
382 if (geometric_representation_ptr->IsCurveOnClosedSurface()) {
383 Curve2dPtr2 = geometric_representation_ptr->PCurve2() ;
384 has_closed_curve = Standard_True ;
385 }
386 if (has_curve || has_closed_curve) {
387 if (first_time_in) {
388 current_first = first;
389 current_last = last;
390 first_time_in = Standard_False;
391 }
392
393 if (Abs(first - current_first) > Precision::PConfusion() || //:b8 abv 20 Feb 98: Confusion -> PConfusion
394 Abs(last - current_last) > Precision::PConfusion() ) { //:b8
395 Standard_Real oldFirst=0., oldLast=0.; //skl
396 if (has_curve) {
397 //pdn 20.05.99 Work around
398 oldFirst = geometric_representation_ptr->First();
399 oldLast = geometric_representation_ptr->Last();
400 // 15.11.2002 PTV OCC966
401 if(ShapeAnalysis_Curve::IsPeriodic(Curve2dPtr)) {
402 Handle(Geom2d_TrimmedCurve) tc = new Geom2d_TrimmedCurve(Curve2dPtr,oldFirst,oldLast);
403 Standard_Real shift = tc->FirstParameter()-oldFirst;
404 oldFirst += shift;
405 oldLast += shift;
406 }
407 //pdn 30.06.2000 work arounf on beziers
408 Standard_Real oldFirstCurve1 = oldFirst, oldLastCurve1 = oldLast;
409 if(Curve2dPtr->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) {
410
411 Standard_Real preci = Precision::PConfusion();
412 if ( Abs(oldFirst) > preci || Abs(oldLast-1) > preci ) {
413 Handle(Geom2d_BezierCurve) bezier = Handle(Geom2d_BezierCurve)::DownCast(Curve2dPtr->Copy());
414 bezier->Segment(oldFirst,oldLast);
415 Curve2dPtr = bezier;
416 }
417 oldFirstCurve1 = 0;
418 oldLastCurve1 = 1;
419 }
420
421 GeomLib::SameRange(Tolerance, Curve2dPtr,
422 oldFirstCurve1,
423 oldLastCurve1,
424 current_first, current_last, NewCurve2dPtr);
425 geometric_representation_ptr->PCurve(NewCurve2dPtr) ;
426 }
427 if (has_closed_curve) {
428
429 Standard_Real oldFirstCurve2 = oldFirst, oldLastCurve2 = oldLast;
430
431 if(Curve2dPtr2->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) {
432
433 Standard_Real preci = Precision::PConfusion();
434 if ( Abs(oldFirst) > preci || Abs(oldLast-1) > preci ) {
435 Handle(Geom2d_BezierCurve) bezier = Handle(Geom2d_BezierCurve)::DownCast(Curve2dPtr2->Copy());
436 bezier->Segment(oldFirst,oldLast);
437 Curve2dPtr2 = bezier;
438 }
439 oldFirstCurve2 = 0;
440 oldLastCurve2 = 1;
441 }
442
443 GeomLib::SameRange(Tolerance, Curve2dPtr2,
444 oldFirstCurve2,
445 oldLastCurve2,
446 current_first, current_last, NewCurve2dPtr2);
447 geometric_representation_ptr->PCurve2(NewCurve2dPtr2);
448 }
449 }
450 }
451 }
452 an_Iterator.Next();
453 }
454 BRep_Builder B;
455 B.Range(TopoDS::Edge(AnEdge), current_first, current_last);
456 B.SameRange(AnEdge, Standard_True);
457}
458
459//=======================================================================
460//function : FixAddPCurve
461//=======================================================================
462
463Standard_Boolean ShapeFix_Edge::FixAddPCurve (const TopoDS_Edge& edge,
464 const Handle(Geom_Surface)& surf,
465 const TopLoc_Location& location,
466 const Standard_Boolean isSeam,
467 const Handle(ShapeAnalysis_Surface)& sas,
468 const Standard_Real prec)
469{
470 ShapeAnalysis_Edge sae;
471 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
472 if ( (!isSeam && sae.HasPCurve (edge, surf, location))||
473 ( isSeam && sae.IsSeam(edge, surf, location))) return Standard_False;
474
475 // PCurve on Plane not computed
476 if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) return Standard_False;
477
478// Standard_Real step = 0;
479 try {
480 OCC_CATCH_SIGNALS
481 Standard_Real First, Last;
482
483 BRep_Builder B;
484
485 Standard_Real preci = ( prec >0. ? prec : BRep_Tool::Tolerance(edge) );
486 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, /*Loc,*/ First, Last);
487 // Handle(Geom_Curve) c3d = BRep_Tool::Curve(E, First, Last);
488 if (c3d.IsNull() || (Abs(Last-First) <Precision::PConfusion())) {
489 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
490 return Standard_False;
491 }
492
493 // Trim the curve to avoid problem ??
494// c3d = Handle(Geom_Curve)::DownCast(c3d->Transformed(Loc.Transformation()));
495// Handle(Geom_TrimmedCurve) theTrimmed = new Geom_TrimmedCurve(c3d, First, Last);
496// c3d = theTrimmed;
497
498// step = 1;
499
500 // A present, on projette
501 // stat : 0 pas pu faire, 1 analytique, 2 approx
502 Handle(Geom2d_Curve) c2d;
503 Standard_Real a1, b1;
504 if ( ! sae.HasPCurve (edge, surf, location)) {
505 myProjector->Init ( sas, preci );
506 myProjector->Perform (c3d,First,Last,c2d);
507 // stat = 2 : reinterpoler la c3d ?
508 if ( myProjector->Status ( ShapeExtend_DONE4 ) )
509 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
510 a1 = First;
511 b1 = Last;
512 }
513 else {
514 sae.PCurve ( edge, surf, location, c2d, a1, b1, Standard_False );
515 }
516
517// step = 2;
518
519 // adding by skl 28.03.2003 for usung Line instead of BSpline
520 Standard_Real fp=0.,lp=0.;
521 Standard_Boolean isLine=Standard_False;
522 if(c2d->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
523 Handle(Geom2d_TrimmedCurve) tc = Handle(Geom2d_TrimmedCurve)::DownCast(c2d);
524 if(tc->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Line))) {
525 fp = tc->FirstParameter();
526 lp = tc->LastParameter();
527 isLine = Standard_True;
528 }
529 }
530
531 if (isSeam) {
532 // On ne sait pas laquelle est Forward. Au PIF. La geometrie Forward
533 // sera mise a jour dans ComputeWire
534 Handle(Geom2d_Curve) c2d2 = Handle(Geom2d_Curve)::DownCast(c2d->Copy());
535 // ATTENTION : TranslatePCurve reconstruit une Line // bords, en
536 // intuitant U ou V ...
537 // Ici, on exploite les infos deja connues
538 Standard_Real uf,ul,vf,vl;
539 surf->Bounds (uf,ul,vf,vl);
540 //#4 rln 19/02/98 ProSTEP ug_exhaust-A.stp entity #284920 (thoroidal surface)
541 //#13 rln 17/03/98 (updating fix #4) call to TranslatePCurve in the case
542 //when a surface is either u- and vclosed or neither u- nor vclosed
543 //#78 rln 12.03.99 S4135: checking spatial closure with prec
544 if (sas->IsUClosed(prec) && ! sas->IsVClosed(prec) //rln S4135 sphere is not considered as V-closed anymore ||
545 /* rln S4135 sas->Surface()->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) */ ) {//:d9 abv 17 Mar 98: any sphere
546 gp_Vec2d tranvec (ul-uf,0);
547 c2d2->Translate (tranvec);
548 }
549 else if (sas->IsVClosed(prec) && ! sas->IsUClosed(prec) ) {
550 gp_Vec2d tranvec (0,vl-vf);
551 c2d2->Translate (tranvec);
552 }
553 else if ( sas->IsUClosed() && sas->IsVClosed() ) { //:q8 abv 23 Mar 99: bm4_al_eye.stp #53710: avoid shifting pcurves for pseudo-seam
554 // Doublement fermee (ex tore) : on lance la charge
555 c2d2 = TranslatePCurve(sas->Surface(), c2d2, prec);
556 }
557 B.UpdateEdge (edge,c2d,c2d2,surf,location, 0.); //#82 rln 16.03.99: preci
558// if ( c2d->IsKind (STANDARD_TYPE(Geom2d_BoundedCurve)) )
559// B.Range (edge,surf,location,c2d->FirstParameter(),c2d->LastParameter());
560 B.Range (edge,surf,location,a1,b1);
561 }
562 else {
563 B.UpdateEdge (edge,c2d,surf,location, 0.); //#82 rln 16.03.99: preci
564 }
565
566 if ( isLine ) {
567 B.Range(edge,surf,location,fp,lp);
568 B.SameParameter(edge,Standard_False);
569 B.SameRange(edge,Standard_False);
570 }
571
572 // Conclusion
573// step = 3;
574 if ( myProjector->Status ( ShapeExtend_DONE3 ) ) {
575 Standard_Real G3dCFirst = c3d->FirstParameter();
576 Standard_Real G3dCLast = c3d->LastParameter();
577 B.UpdateEdge(edge, c3d, 0.);
578 Range3d(edge, G3dCFirst, G3dCLast, 0.);
579 }
580 } // end try
581 catch(Standard_Failure) {
582 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
583#ifdef DEB //:s5
584 cout << "Warning: ShapeFix_Edge::FixAddPCurve(): Exception: ";
585 Standard_Failure::Caught()->Print(cout); cout << endl;
586#endif
587 }
588 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
589 return Standard_True;
590}
591
592//=======================================================================
593//function : FixAddCurve3d
594//purpose :
595//=======================================================================
596
597 Standard_Boolean ShapeFix_Edge::FixAddCurve3d(const TopoDS_Edge& edge)
598{
599 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
600 ShapeAnalysis_Edge EA;
601 if ( BRep_Tool::Degenerated ( edge ) || EA.HasCurve3d (edge) ) return Standard_False;
602 if(!BRep_Tool::SameRange(edge))
603 TempSameRange(edge,Precision::PConfusion());
604
605 if (!ShapeBuild_Edge().BuildCurve3d(edge)) {
606 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
607 return Standard_False;
608 }
609 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
610 return Standard_True;
611}
612
613//=======================================================================
614//function : FixVertexTolerance
615//purpose :
616//=======================================================================
617
618Standard_Boolean ShapeFix_Edge::FixVertexTolerance(const TopoDS_Edge& edge,
619 const TopoDS_Face& face)
620{
621 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
622 ShapeAnalysis_Edge sae;
623 Standard_Real toler1, toler2;
624 if (!sae.CheckVertexTolerance (edge, face, toler1, toler2)) return Standard_False;
625 if (sae.Status (ShapeExtend_DONE1))
626 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
627 if (sae.Status (ShapeExtend_DONE2))
628 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
629 BRep_Builder B;
630 TopoDS_Vertex V1 = sae.FirstVertex(edge);
631 TopoDS_Vertex V2 = sae.LastVertex(edge);
632 B.UpdateVertex (V1, toler1);
633 B.UpdateVertex (V2, toler2);
634 return Standard_True;
635}
636
637//=======================================================================
638//function : FixVertexTolerance
639//purpose :
640//=======================================================================
641
642Standard_Boolean ShapeFix_Edge::FixVertexTolerance(const TopoDS_Edge& edge)
643{
644 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
645 ShapeAnalysis_Edge sae;
646 Standard_Real toler1, toler2;
647 if (!sae.CheckVertexTolerance (edge, toler1, toler2)) return Standard_False;
648 if (sae.Status (ShapeExtend_DONE1))
649 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
650 if (sae.Status (ShapeExtend_DONE2))
651 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
652 BRep_Builder B;
653 TopoDS_Vertex V1 = sae.FirstVertex(edge);
654 TopoDS_Vertex V2 = sae.LastVertex(edge);
655 B.UpdateVertex (V1, toler1);
656 B.UpdateVertex (V2, toler2);
657 return Standard_True;
658}
659
660//=======================================================================
661//function : FixReversed2d
662//purpose :
663//=======================================================================
664
665Standard_Boolean ShapeFix_Edge::FixReversed2d (const TopoDS_Edge& edge,
666 const TopoDS_Face& face)
667{
668 TopLoc_Location L;
669 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
670 return FixReversed2d (edge, S, L);
671}
672
673//=======================================================================
674//function : FixReversed2d
675//purpose :
676//=======================================================================
677
678Standard_Boolean ShapeFix_Edge::FixReversed2d (const TopoDS_Edge& edge,
679 const Handle(Geom_Surface)& surface,
680 const TopLoc_Location& location)
681{
682 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
683
684 ShapeAnalysis_Edge EA;
685 EA.CheckCurve3dWithPCurve (edge, surface, location);
686 if (EA.Status (ShapeExtend_FAIL1))
687 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
688 if (EA.Status (ShapeExtend_FAIL2))
689 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
690 if ( ! EA.Status (ShapeExtend_DONE) ) return Standard_False;
691
692 Handle(Geom2d_Curve) c2d;
693 Standard_Real f,l;
694 EA.PCurve (edge, surface, location, c2d, f, l, Standard_False);
695 //#46 rln 01.12.98 buc40130, entity 272 (4-th curve)
696 Standard_Real newf = c2d->ReversedParameter (l), newl = c2d->ReversedParameter (f);
697 c2d->Reverse();
698 BRep_Builder B;
699//will break seams! B.UpdateEdge (edge, c2d, surface, location, Precision::Confusion());
700 B.Range (edge, surface, location, newf, newl);
701 //#51 rln 15.12.98 pro6562 entity 2788
702 //Because of numerical accuracy the range on B-Splines (moreover, on any curve!)
703 //the range is changed
704 Standard_Real first, last;
705 BRep_Tool::Range (edge, first, last);
706 if (first != newf || last != newl) {
707 B.SameRange (edge, Standard_False);
708 B.SameParameter (edge, Standard_False);
709 }
710 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
711 return Standard_True;
712}
713
714
715//=======================================================================
716//function : FixSameParameter
717//purpose :
718//=======================================================================
719
720Standard_Boolean ShapeFix_Edge::FixSameParameter(const TopoDS_Edge& edge,
721 const Standard_Real tolerance)
722{
723 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
724
725 if ( BRep_Tool::Degenerated ( edge ) ) {
726 BRep_Builder B;
727 if ( ! BRep_Tool::SameRange (edge) )
728 TempSameRange ( edge, Precision::PConfusion() );
729 B.SameParameter ( edge, Standard_True );
730 return Standard_False;
731 }
732 ShapeFix_ShapeTolerance SFST;
733 ShapeAnalysis_Edge sae;
734 BRep_Builder B;
735
736 TopoDS_Edge copyedge;
737 TopoDS_Vertex V1 = sae.FirstVertex (edge);
738 TopoDS_Vertex V2 = sae.LastVertex (edge);
739 Standard_Real TolFV = ( V1.IsNull() ? 0. : BRep_Tool::Tolerance ( V1 ) );
740 Standard_Real TolLV = ( V2.IsNull() ? 0. : BRep_Tool::Tolerance ( V2 ) );
741 Standard_Real tol = BRep_Tool::Tolerance (edge);
742
743 Standard_Boolean wasSP = BRep_Tool::SameParameter ( edge ), SP = Standard_False;
744 {
745 try {
746 OCC_CATCH_SIGNALS
747 if ( ! BRep_Tool::SameRange (edge) )
748 TempSameRange ( edge, Precision::PConfusion() );
749 //#81 rln 15.03.99 S4135: for not SP edge choose the best result (either BRepLib or deviation only)
750 if ( ! wasSP ) {
751 //create copyedge as copy of edge with the same vertices and copy of pcurves on the same surface(s)
752 copyedge = ShapeBuild_Edge().Copy ( edge, Standard_False );
753 B.SameParameter ( copyedge, Standard_False );
31c3b8f0
SK
754 // ShapeBuild_Edge::Copy() may change 3D curve range (if it's outside of its period).
755 // In this case pcurves in BRepLib::SameParameter() will be changed as well
756 // and later ShapeBuild_Edge::CopyPCurves() will copy pcurves keeping original range.
757 // To prevent this discrepancy we enforce original 3D range.
758 Standard_Real aF, aL;
759 BRep_Tool::Range (edge, aF, aL);
760 B.Range (copyedge, aF, aL, Standard_True); // only 3D
7fd59977 761 BRepLib::SameParameter ( copyedge, ( tolerance >= Precision::Confusion() ?
762 tolerance : tol ) );
763 SP = BRep_Tool::SameParameter ( copyedge );
764 if ( ! SP ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
765 }
766 }
767 catch(Standard_Failure) {
768#ifdef DEB
769 cout << "\nWarning: ShapeFix_Edge: Exception in SameParameter: ";
770 Standard_Failure::Caught()->Print(cout); cout << endl;
771#endif
772 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
773 }
774 }
775
776 // compute deviation on the original pcurves
777 Standard_Real maxdev;
778 B.SameParameter ( edge, Standard_True );
779 sae.CheckSameParameter ( edge, maxdev );
780 if ( sae.Status ( ShapeExtend_FAIL2 ) )
781 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
782
783 // if BRepLib was OK, compare and select the best variant
784 if ( SP ) {
785 Standard_Real BRLTol = BRep_Tool::Tolerance ( copyedge ), BRLDev;
786 sae.CheckSameParameter ( copyedge, BRLDev );
787 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 );
788 if ( BRLTol < BRLDev ) BRLTol = BRLDev;
789
790 //chose the best result
791 if ( BRLTol < maxdev ) {
792 if ( sae.Status ( ShapeExtend_FAIL2 ) )
793 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
794 //copy pcurves and tolerances from copyedge
795 ShapeBuild_Edge().CopyPCurves ( edge, copyedge );
796 maxdev = BRLTol;
797 SFST.SetTolerance (edge, BRLTol, TopAbs_EDGE);
798 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE5 );
799 }
800 }
801 //restore tolerances because they could be modified by BRepLib
802 if ( ! V1.IsNull() ) SFST.SetTolerance ( V1, Max (maxdev, TolFV), TopAbs_VERTEX);
803 if ( ! V2.IsNull() ) SFST.SetTolerance ( V2, Max (maxdev, TolLV), TopAbs_VERTEX);
804
805 if ( maxdev > tol ) {
806 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
807 B.UpdateEdge ( edge, maxdev );
808 FixVertexTolerance(edge);
809 }
810
811 if ( ! wasSP && ! SP ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
812 return Status ( ShapeExtend_DONE );
813}
814
815//=======================================================================
816//function : Status
817//purpose :
818//=======================================================================
819
820 Standard_Boolean ShapeFix_Edge::Status(const ShapeExtend_Status status) const
821{
822 return ShapeExtend::DecodeStatus (myStatus, status);
823}