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