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