Commit | Line | Data |
---|---|---|
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 | 64 | IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Edge,MMgt_TShared) |
65 | ||
7fd59977 | 66 | //======================================================================= |
67 | //function : ShapeFix_Edge | |
68 | //purpose : | |
69 | //======================================================================= | |
7fd59977 | 70 | ShapeFix_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 | ||
81 | Handle(ShapeConstruct_ProjectCurveOnSurface) ShapeFix_Edge::Projector() | |
82 | { | |
83 | return myProjector; | |
84 | } | |
85 | ||
86 | ||
87 | //======================================================================= | |
88 | //function : FixRemovePCurve | |
89 | //purpose : | |
90 | //======================================================================= | |
91 | ||
92 | Standard_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 | ||
105 | Standard_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 | ||
121 | Standard_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 | ||
135 | Standard_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 | ||
150 | Standard_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 | ||
165 | Standard_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 | ||
192 | static 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 | ||
444 | Standard_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 | 581 | Standard_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 | ||
619 | Standard_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 | ||
655 | Standard_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 | ||
668 | Standard_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 | ||
709 | Standard_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 | ||
721 | Standard_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 | ||
849 | inline Handle(ShapeBuild_ReShape) ShapeFix_Edge::Context() const | |
850 | { | |
851 | return myContext; | |
852 | } | |
853 | ||
854 | //======================================================================= | |
855 | //function : SetContext | |
856 | //purpose : | |
857 | //======================================================================= | |
858 | ||
859 | void ShapeFix_Edge::SetContext (const Handle(ShapeBuild_ReShape)& context) | |
860 | { | |
861 | myContext = context; | |
862 | } |