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 | //:r5 abv 06.04.99: ec_turbine-A.stp, #4313: protect against null curve |
15 | // abv 09.04.99 S4136: add parameter preci (to eliminate BRepAPI::Precision) |
7fd59977 |
16 | |
17 | #include <Adaptor3d_CurveOnSurface.hxx> |
42cf5bc1 |
18 | #include <BRep_Tool.hxx> |
19 | #include <ElCLib.hxx> |
20 | #include <Extrema_ExtPC.hxx> |
21 | #include <Geom2d_BoundedCurve.hxx> |
7fd59977 |
22 | #include <Geom2d_BSplineCurve.hxx> |
42cf5bc1 |
23 | #include <Geom2d_Curve.hxx> |
7fd59977 |
24 | #include <Geom2d_Line.hxx> |
42cf5bc1 |
25 | #include <Geom2dAdaptor_Curve.hxx> |
26 | #include <Geom2dAdaptor_HCurve.hxx> |
7fd59977 |
27 | #include <Geom_Curve.hxx> |
7fd59977 |
28 | #include <Geom_SphericalSurface.hxx> |
42cf5bc1 |
29 | #include <Geom_Surface.hxx> |
30 | #include <GeomAdaptor_HSurface.hxx> |
31 | #include <GeomAdaptor_Surface.hxx> |
32 | #include <gp_Pnt.hxx> |
7fd59977 |
33 | #include <Precision.hxx> |
7fd59977 |
34 | #include <ShapeAnalysis.hxx> |
35 | #include <ShapeAnalysis_Curve.hxx> |
36 | #include <ShapeAnalysis_Edge.hxx> |
37 | #include <ShapeAnalysis_Surface.hxx> |
42cf5bc1 |
38 | #include <ShapeFix_EdgeProjAux.hxx> |
39 | #include <Standard_ErrorHandler.hxx> |
40 | #include <Standard_Failure.hxx> |
41 | #include <Standard_Type.hxx> |
42 | #include <TopExp.hxx> |
43 | #include <TopoDS_Edge.hxx> |
44 | #include <TopoDS_Face.hxx> |
45 | #include <TopoDS_Vertex.hxx> |
f4dee9bb |
46 | #include <Adaptor3d_HCurve.hxx> |
47 | #include <BSplCLib.hxx> |
7fd59977 |
48 | |
25e59720 |
49 | IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_EdgeProjAux,Standard_Transient) |
92efcf78 |
50 | |
7fd59977 |
51 | //======================================================================= |
52 | //function : ShapeFix_EdgeProjAux |
53 | //purpose : |
54 | //======================================================================= |
7fd59977 |
55 | ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux () |
56 | { |
57 | myFirstDone = myLastDone = Standard_False; |
58 | } |
59 | |
60 | //======================================================================= |
61 | //function : ShapeFix_EdgeProjAux |
62 | //purpose : |
63 | //======================================================================= |
64 | |
65 | ShapeFix_EdgeProjAux::ShapeFix_EdgeProjAux (const TopoDS_Face& F, |
66 | const TopoDS_Edge& E) |
67 | { |
68 | Init (F, E); |
69 | } |
70 | |
71 | //======================================================================= |
72 | //function : Init |
73 | //purpose : |
74 | //======================================================================= |
75 | |
76 | void ShapeFix_EdgeProjAux::Init (const TopoDS_Face& F, |
77 | const TopoDS_Edge& E) |
78 | { |
79 | myFace = F; |
80 | myEdge = E; |
62f22593 |
81 | myFirstParam = myLastParam = 0.; |
7fd59977 |
82 | myFirstDone = myLastDone = Standard_False; |
83 | } |
84 | |
85 | //======================================================================= |
86 | //function : Compute |
87 | //purpose : |
88 | //======================================================================= |
89 | |
90 | void ShapeFix_EdgeProjAux::Compute (const Standard_Real preci) |
91 | { |
92 | myFirstDone = myLastDone = Standard_False; |
93 | |
94 | // Project Point3d on Surface |
95 | // TEMPORARY Call ShapeFix_EdgeProjAux |
e3096dec |
96 | myFirstParam = 0.; |
97 | myLastParam = 0.; |
7fd59977 |
98 | Init2d(preci); |
99 | if (IsFirstDone() && IsLastDone()) { |
100 | Standard_Real U1 = FirstParam(); |
101 | Standard_Real U2 = LastParam(); |
102 | if (U1>=U2) { |
0797d9d3 |
103 | #ifdef OCCT_DEBUG |
04232180 |
104 | std::cout << "Parametres inverses ... " << std::endl; |
7fd59977 |
105 | #endif |
106 | Standard_Real tmp = U1; |
107 | U1 = U2; U2 = tmp; |
108 | } |
109 | myFirstParam = U1; |
110 | myFirstDone = Standard_True; |
111 | myLastParam = U2; |
112 | myLastDone = Standard_True; |
113 | } |
114 | } |
115 | |
116 | //======================================================================= |
117 | //function : IsFirstDone |
118 | //purpose : |
119 | //======================================================================= |
120 | |
121 | Standard_Boolean ShapeFix_EdgeProjAux::IsFirstDone() const |
122 | { |
123 | return myFirstDone; |
124 | } |
125 | |
126 | //======================================================================= |
127 | //function : IsLastDone |
128 | //purpose : |
129 | //======================================================================= |
130 | |
131 | Standard_Boolean ShapeFix_EdgeProjAux::IsLastDone() const |
132 | { |
133 | return myLastDone; |
134 | } |
135 | |
136 | //======================================================================= |
137 | //function : FirstParam |
138 | //purpose : |
139 | //======================================================================= |
140 | |
141 | Standard_Real ShapeFix_EdgeProjAux::FirstParam() const |
142 | { |
143 | return myFirstParam; |
144 | } |
145 | |
146 | //======================================================================= |
147 | //function : LastParam |
148 | //purpose : |
149 | //======================================================================= |
150 | |
151 | Standard_Real ShapeFix_EdgeProjAux::LastParam() const |
152 | { |
153 | return myLastParam; |
154 | } |
155 | |
156 | //======================================================================= |
157 | //function : IsIso |
158 | //purpose : |
159 | //======================================================================= |
160 | |
161 | Standard_Boolean ShapeFix_EdgeProjAux::IsIso (const Handle(Geom2d_Curve)& /*theCurve2d*/) |
162 | { |
163 | // Until an ISO is recognized by Adaptor3d_Curve |
164 | /* |
165 | if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) { |
166 | Handle(Geom2d_Line) theLine2d = Handle(Geom2d_Line)::DownCast(theCurve2d); |
167 | gp_Dir2d theDir2d = theLine2d->Direction(); |
168 | |
169 | gp_Dir2d dir1(0.,1.); |
170 | gp_Dir2d dir2(0.,-1.); |
171 | |
172 | return (theDir2d.IsEqual(dir1,Precision::Angular()) || |
173 | theDir2d.IsEqual(dir2,Precision::Angular()) || |
174 | theDir2d.IsNormal(dir1,Precision::Angular()) || |
175 | theDir2d.IsNormal(dir2,Precision::Angular()) ); |
176 | } |
177 | */ |
178 | return Standard_False; |
179 | } |
180 | |
181 | // ---------------------------------------------------------------------------- |
182 | // static : FindParameterWithExt |
183 | // Purpose : Computes the trimming parameter of Pt1 on COnS |
184 | // ---------------------------------------------------------------------------- |
185 | |
186 | static Standard_Boolean FindParameterWithExt (const gp_Pnt& Pt1, |
187 | const Adaptor3d_CurveOnSurface& COnS, |
188 | const Standard_Real Uinf, |
189 | const Standard_Real Usup, |
190 | const Standard_Real preci, |
191 | Standard_Real& w1) |
192 | { |
193 | try { // et allez donc ! |
194 | OCC_CATCH_SIGNALS |
195 | Extrema_ExtPC myExtPC (Pt1, COnS, Uinf, Usup, preci); |
196 | |
197 | //ShapeFix_ExtPCOnS myExtPCOnS1 = |
198 | //ShapeFix_ExtPCOnS(Pt1, COnS, Uinf, Usup, preci); |
199 | |
200 | if (myExtPC.IsDone()) { |
201 | Standard_Integer NbExt1 = myExtPC.NbExt(); |
202 | for (Standard_Integer i=1; i<=NbExt1; i++) { |
203 | if (myExtPC.IsMin(i)) { |
204 | //Standard_Real dist = myExtPC.Value(i); //szv#4:S4163:12Mar99 debug mode only |
205 | w1 = myExtPC.Point(i).Parameter(); |
206 | } |
207 | } |
208 | return Standard_True; |
209 | } |
210 | else return Standard_False; |
211 | } // end try |
9775fa61 |
212 | catch(Standard_Failure const& anException) { |
213 | #ifdef OCCT_DEBUG |
214 | //:s5 |
04232180 |
215 | std::cout << "Warning: ShapeFix_EdgeProjAux, FindParameterWithExt(): Exception: "; |
216 | anException.Print(std::cout); std::cout << std::endl; |
7fd59977 |
217 | #endif |
9775fa61 |
218 | (void)anException; |
7fd59977 |
219 | return Standard_False; |
220 | } |
7fd59977 |
221 | } |
222 | |
223 | //======================================================================= |
224 | //function : Init2d |
225 | //purpose : |
226 | //======================================================================= |
227 | |
228 | void ShapeFix_EdgeProjAux::Init2d (const Standard_Real preci) |
229 | { |
e3096dec |
230 | Standard_Real cl = 0., cf = 0.; |
231 | // Extract Geometries |
232 | myFirstDone = myLastDone = Standard_False; |
7fd59977 |
233 | Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace); |
234 | Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl); |
235 | if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99: ec_turbine-A.stp, #4313 |
e3096dec |
236 | myFirstParam = 0.; |
237 | myLastParam = 0.; |
7fd59977 |
238 | TopoDS_Vertex V1,V2; |
239 | TopExp::Vertices(myEdge, V1, V2); |
240 | gp_Pnt Pt1,Pt2; |
241 | // pdn 28.12.98: r_39-db.stp #605: use ends of 3d curve instead of vertices |
242 | ShapeAnalysis_Edge sae; |
243 | Standard_Real a,b; |
244 | Handle(Geom_Curve) C3d; |
245 | if(sae.Curve3d(myEdge,C3d,a,b,Standard_False)) { |
246 | Pt1 = C3d->Value(a); |
247 | Pt2 = C3d->Value(b); |
248 | } |
249 | else { |
250 | Pt1 = BRep_Tool::Pnt(V1); |
251 | Pt2 = BRep_Tool::Pnt(V2); |
252 | } |
62f22593 |
253 | //:S4136 Standard_Real preci = BRepAPI::Precision(); |
7fd59977 |
254 | //pdn to manage degenerated case |
255 | if (V1.IsSame(V2)) { |
256 | Handle(ShapeAnalysis_Surface) stsu = new ShapeAnalysis_Surface (theSurface); |
257 | gp_Pnt2d aPt1,aPt2; |
258 | Standard_Real firstpar,lastpar; |
259 | if (stsu->DegeneratedValues(Pt1,preci,aPt1,aPt2,firstpar,lastpar)){ |
62f22593 |
260 | |
7fd59977 |
261 | if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) { |
62f22593 |
262 | if (aPt1.IsEqual(theCurve2d->Value(firstpar),preci) && |
263 | aPt2.IsEqual(theCurve2d->Value(lastpar),preci)){ |
264 | myFirstParam = firstpar; |
265 | myLastParam = lastpar; |
266 | myFirstDone = myLastDone = Standard_True; |
267 | return; |
268 | } |
7fd59977 |
269 | } |
0797d9d3 |
270 | #ifdef OCCT_DEBUG |
04232180 |
271 | else std::cout <<"Other type of deg curve"<<std::endl; |
7fd59977 |
272 | #endif |
62f22593 |
273 | |
7fd59977 |
274 | } |
275 | } |
62f22593 |
276 | |
7fd59977 |
277 | Standard_Boolean parU = Standard_False, parV = Standard_False; |
278 | GeomAdaptor_Surface SA = GeomAdaptor_Surface(theSurface); |
279 | Handle(GeomAdaptor_HSurface) myHSur = new GeomAdaptor_HSurface(SA); |
62f22593 |
280 | |
7fd59977 |
281 | cf = theCurve2d->FirstParameter(); |
282 | cl = theCurve2d->LastParameter(); |
283 | //pdn cutting pcurve by suface bounds |
fccb487b |
284 | if (Precision::IsInfinite(cf)||Precision::IsInfinite(cl)) { |
7fd59977 |
285 | if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_Line))) { |
286 | Standard_Real uf,ul,vf,vl; |
287 | theSurface->Bounds(uf,ul,vf,vl); |
f4dee9bb |
288 | //Correct surface limits for extrusion/revolution surfaces based on hyperbola |
289 | //23 is ln(1.0e+10) |
290 | if(SA.GetType() == GeomAbs_SurfaceOfExtrusion) |
291 | { |
292 | if(SA.BasisCurve()->GetType() == GeomAbs_Hyperbola) |
293 | { |
294 | uf = Max(uf, -23.); |
295 | ul = Min(ul, 23.); |
296 | } |
297 | } |
298 | if(SA.GetType() == GeomAbs_SurfaceOfRevolution) |
299 | { |
300 | if(SA.BasisCurve()->GetType() == GeomAbs_Hyperbola) |
301 | { |
302 | vf = Max(vf, -23.); |
303 | vl = Min(vl, 23.); |
304 | } |
305 | } |
7fd59977 |
306 | if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)&& |
f4dee9bb |
307 | !Precision::IsInfinite(vf)&&!Precision::IsInfinite(vl)) { |
62f22593 |
308 | Standard_Real cfi,cli; |
309 | Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d); |
310 | gp_Pnt2d pnt = lin->Location(); |
311 | gp_Dir2d dir = lin->Direction(); |
312 | if (dir.Y()==0) { |
313 | parU = Standard_True; |
314 | cfi = (uf-pnt.X())/dir.X(); |
315 | cli = (ul-pnt.X())/dir.X(); |
316 | } |
317 | else if (dir.X()==0) { |
318 | parV = Standard_True; |
319 | cfi = (vf-pnt.Y())/dir.Y(); |
320 | cli = (vl-pnt.Y())/dir.Y(); |
321 | } |
322 | else {//common case |
323 | Standard_Real xfi, xli, yfi, yli; |
324 | xfi = (uf-pnt.X())/dir.X(); |
325 | xli = (ul-pnt.X())/dir.X(); |
326 | yfi = (vf-pnt.Y())/dir.Y(); |
327 | yli = (vl-pnt.Y())/dir.Y(); |
328 | if (dir.X()*dir.Y() > 0) { |
329 | cfi = (Abs(xli-xfi) < Abs(xli-yfi)? xfi : yfi); |
330 | cli = (Abs(xfi-xli) < Abs(xfi-yli)? xli : yli); |
331 | } else { |
332 | cfi = (Abs(xli-xfi) < Abs(xli-yli)? xfi : yli); |
333 | cli = (Abs(yli-xli) < Abs(yli-yfi)? xli : yfi); |
334 | } |
335 | } |
336 | if (cfi < cli) { cf = cfi; cl = cli; } |
337 | else { cf = cli; cl = cfi; } |
7fd59977 |
338 | } |
339 | else if(!Precision::IsInfinite(uf)&&!Precision::IsInfinite(ul)){ |
62f22593 |
340 | Handle(Geom2d_Line) lin = Handle(Geom2d_Line)::DownCast(theCurve2d); |
341 | gp_Dir2d dir = lin->Direction(); |
342 | if (dir.X()!=0) { |
343 | if (dir.Y()==0) parU = Standard_True; |
344 | gp_Pnt2d pnt = lin->Location(); //szv#4:S4163:12Mar99 moved |
345 | Standard_Real cfi = (uf-pnt.X())/dir.X(); |
346 | Standard_Real cli = (ul-pnt.X())/dir.X(); |
347 | if (cfi < cli) { cf = cfi; cl = cli; } |
348 | else { cf = cli; cl = cfi; } |
349 | } |
350 | else { |
351 | cf=-10000; |
352 | cl= 10000; |
353 | } |
7fd59977 |
354 | } |
355 | else { |
62f22593 |
356 | cf=-10000; |
357 | cl= 10000; |
358 | //pdn not cutted by bounds |
0797d9d3 |
359 | #ifdef OCCT_DEBUG |
04232180 |
360 | std::cout<<"Infinite Surface"<<std::endl; |
7fd59977 |
361 | #endif |
362 | } |
363 | } |
364 | else { |
365 | //pdn not linear case not managed |
366 | cf=-10000; |
367 | cl= 10000; |
f4dee9bb |
368 | if(theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) |
369 | { |
370 | //Try to reparametrize (CASE dxf read bug25899) |
371 | Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d->Copy()); |
372 | TColStd_Array1OfReal aNewKnots(1, aBspl->NbKnots()); |
373 | aBspl->Knots(aNewKnots); |
374 | BSplCLib::Reparametrize(cf, cl, aNewKnots); |
375 | aBspl->SetKnots(aNewKnots); |
376 | theCurve2d = aBspl; |
377 | } |
378 | |
0797d9d3 |
379 | #ifdef OCCT_DEBUG |
04232180 |
380 | std::cout<<"Some infinite curve"<<std::endl; |
7fd59977 |
381 | #endif |
382 | } |
383 | } |
e3096dec |
384 | |
7fd59977 |
385 | Geom2dAdaptor_Curve CA = Geom2dAdaptor_Curve(theCurve2d,cf,cl); |
386 | Handle(Geom2dAdaptor_HCurve) myHCur = new Geom2dAdaptor_HCurve(CA); |
62f22593 |
387 | |
7fd59977 |
388 | Adaptor3d_CurveOnSurface COnS = Adaptor3d_CurveOnSurface(myHCur, myHSur); |
389 | |
390 | // ---------------------------------------------- |
391 | // --- topological limit == geometric limit ? --- |
392 | // ---------------------------------------------- |
393 | Standard_Real Uinf = COnS.FirstParameter(); |
394 | Standard_Real Usup = COnS.LastParameter(); |
e3096dec |
395 | |
62f22593 |
396 | Standard_Real w1 = 0., w2 = 0.; |
7fd59977 |
397 | ShapeAnalysis_Curve sac; |
398 | gp_Pnt pnt; |
399 | Standard_Real dist = sac.Project(COnS,Pt1,preci,pnt,w1,Standard_False); |
62f22593 |
400 | //if distance is infinite then projection is not performed |
401 | if( Precision::IsInfinite(dist)) |
62f22593 |
402 | return; |
e3096dec |
403 | |
404 | myFirstDone = Standard_True; |
405 | myFirstParam = w1; |
406 | |
7fd59977 |
407 | dist = sac.Project(COnS,Pt2,preci,pnt,w2,Standard_False); |
e3096dec |
408 | |
62f22593 |
409 | if( Precision::IsInfinite(dist)) |
62f22593 |
410 | return; |
e3096dec |
411 | |
412 | myLastDone = Standard_True; |
413 | myLastParam = w2; |
414 | |
62f22593 |
415 | if(fabs(w1 - w2) < Precision::PConfusion()) |
416 | { |
417 | if(!theSurface->IsUPeriodic() && !theSurface->IsVPeriodic()) |
418 | return; |
419 | } |
e3096dec |
420 | |
7fd59977 |
421 | if ( myFirstParam == Uinf && myLastParam == Usup ) return; |
422 | if ( myFirstParam == Usup && myLastParam == Uinf ) { |
423 | myFirstParam = theCurve2d->ReversedParameter(Usup); |
424 | myLastParam = theCurve2d->ReversedParameter(Uinf); |
425 | theCurve2d->Reverse(); |
0797d9d3 |
426 | #ifdef OCCT_DEBUG |
04232180 |
427 | std::cout << "Warning: ShapeFix_EdgeProjAux: pcurve reversed" << std::endl; |
7fd59977 |
428 | #endif |
429 | return; |
430 | } |
431 | //:abv 29.08.01: SAT: fix for closed case |
432 | if ( COnS.Value(Uinf).Distance ( COnS.Value(Usup) ) < Precision::Confusion() ) { |
433 | // 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "==" |
434 | if ( Abs(myFirstParam-Uinf) < ::Precision::PConfusion() && |
62f22593 |
435 | Abs(myLastParam-Uinf) < ::Precision::PConfusion() ) |
436 | myLastParam = w2 = Usup; |
7fd59977 |
437 | // 18.11.2002 SKL OCC630 compare values with tolerance Precision::PConfusion() instead of "==" |
438 | else if ( Abs(myFirstParam-Usup) < ::Precision::PConfusion() && |
62f22593 |
439 | Abs(myLastParam-Usup) < ::Precision::PConfusion() ) |
440 | myFirstParam = w1 = Uinf; |
7fd59977 |
441 | } |
62f22593 |
442 | |
7fd59977 |
443 | //pdn adjust parameters in periodic case |
444 | if(parU || parV) { |
445 | Standard_Real uf,ul,vf,vl; |
446 | theSurface->Bounds(uf,ul,vf,vl); |
447 | Standard_Real period = (parU ? ul-uf : vl-vf); |
448 | w1+=ShapeAnalysis::AdjustToPeriod(w1,0,period); |
449 | myFirstParam = w1; |
450 | w2+=ShapeAnalysis::AdjustToPeriod(w2,0,period); |
451 | myLastParam = w2; |
452 | Handle(Geom_Curve) C3d1; |
453 | if(!sae.Curve3d (myEdge, C3d1, cf, cl, Standard_False )) { |
454 | UpdateParam2d(theCurve2d); |
455 | return; |
456 | } |
457 | gp_Pnt mid = C3d1->Value((cf+cl)/2); |
458 | Standard_Real wmid; |
459 | sac.Project(COnS,mid,preci,pnt,wmid,Standard_False); |
460 | wmid+=ShapeAnalysis::AdjustToPeriod(wmid,0,period); |
94f71cad |
461 | if(w1>=w2) { |
7fd59977 |
462 | if(w2 > wmid) myFirstParam -= period; |
463 | else if (w1 > wmid) |
62f22593 |
464 | UpdateParam2d(theCurve2d); |
7fd59977 |
465 | else { |
62f22593 |
466 | myLastParam+=period; |
0797d9d3 |
467 | #ifdef OCCT_DEBUG |
04232180 |
468 | std::cout <<" Added"<<std::endl; |
7fd59977 |
469 | #endif |
470 | } |
471 | } |
472 | else { |
473 | if(w1 > wmid) { |
62f22593 |
474 | myLastParam -=period; |
475 | UpdateParam2d(theCurve2d); |
0797d9d3 |
476 | #ifdef OCCT_DEBUG |
04232180 |
477 | std::cout <<" Added & Inverted"<<std::endl; |
7fd59977 |
478 | #endif |
479 | } else if (w2 < wmid) { |
62f22593 |
480 | myFirstParam += period; |
481 | UpdateParam2d(theCurve2d); |
7fd59977 |
482 | } |
483 | } |
484 | } |
485 | UpdateParam2d(theCurve2d); |
486 | return; |
487 | } |
488 | |
489 | //======================================================================= |
490 | //function : Init3d |
491 | //purpose : |
492 | //======================================================================= |
493 | |
494 | void ShapeFix_EdgeProjAux::Init3d (const Standard_Real preci) |
495 | { |
496 | Standard_Real cl, cf; |
497 | |
498 | // Extract Geometries |
499 | Handle(Geom_Surface) theSurface = BRep_Tool::Surface(myFace); |
500 | Handle(Geom2d_Curve) theCurve2d = BRep_Tool::CurveOnSurface(myEdge, myFace, cf, cl); |
501 | if ( theCurve2d.IsNull() ) return; //:r5 abv 6 Apr 99: ec_turbine-A.stp, #4313 |
502 | TopoDS_Vertex V1,V2; |
62f22593 |
503 | |
7fd59977 |
504 | V1 = TopExp::FirstVertex(myEdge); |
505 | V2 = TopExp::LastVertex(myEdge); |
506 | gp_Pnt Pt1 = BRep_Tool::Pnt(V1); |
507 | gp_Pnt Pt2 = BRep_Tool::Pnt(V2); |
508 | |
509 | |
510 | GeomAdaptor_Surface SA = GeomAdaptor_Surface(theSurface); |
511 | Handle(GeomAdaptor_HSurface) myHSur = new GeomAdaptor_HSurface(SA); |
512 | |
513 | Geom2dAdaptor_Curve CA = Geom2dAdaptor_Curve(theCurve2d); |
514 | Handle(Geom2dAdaptor_HCurve) myHCur = new Geom2dAdaptor_HCurve(CA); |
515 | |
516 | Adaptor3d_CurveOnSurface COnS = Adaptor3d_CurveOnSurface(myHCur, myHSur); |
517 | |
518 | //:S4136 Standard_Real preci = BRepAPI::Precision(); |
519 | Standard_Real Uinf = theCurve2d->FirstParameter(); |
520 | Standard_Real Usup = theCurve2d->LastParameter(); |
521 | |
522 | // ---------------------------------------------- |
523 | // --- topological limit == geometric limit ? --- |
524 | // ---------------------------------------------- |
525 | |
526 | if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve))) { |
527 | |
528 | gp_Pnt Pdeb = COnS.Value(Uinf); |
529 | gp_Pnt Pfin = COnS.Value(Usup); |
530 | |
531 | //szv#4:S4163:12Mar99 optimized |
532 | if ( Pdeb.IsEqual(Pt1, preci) && Pfin.IsEqual(Pt2, preci) ) { |
533 | myFirstParam = Uinf; |
534 | myLastParam = Usup; |
535 | myFirstDone = myLastDone = Standard_True; |
536 | return; |
537 | } |
538 | } |
539 | |
540 | // ------------------------------------------ |
541 | // --- The CurveOnSurface is not infinite --- |
542 | // --- Try with Extrema --- |
543 | // ------------------------------------------ |
544 | |
545 | Standard_Real w1 = COnS.FirstParameter(); |
546 | Standard_Real w2 = COnS.LastParameter(); |
547 | |
548 | if ((!Precision::IsInfinite(w1) && |
549 | !Precision::IsInfinite(w2) && |
550 | theCurve2d->Continuity() != GeomAbs_C0) || |
551 | IsIso(theCurve2d)) { |
552 | |
553 | //szv#4:S4163:12Mar99 optimized |
554 | if ( FindParameterWithExt(Pt1, COnS, Uinf, Usup, preci, w1) && |
555 | FindParameterWithExt(Pt2, COnS, Uinf, Usup, preci, w2) ) { |
556 | myFirstParam = w1; |
557 | myLastParam = w2; |
558 | UpdateParam2d(theCurve2d); |
559 | myFirstDone = myLastDone = Standard_True; |
560 | return; |
561 | } |
562 | } |
563 | myFirstDone = myLastDone = Standard_True; |
564 | } |
565 | |
566 | //======================================================================= |
567 | //function : UpdateParam2d |
568 | //purpose : |
569 | //======================================================================= |
570 | |
571 | void ShapeFix_EdgeProjAux::UpdateParam2d (const Handle(Geom2d_Curve)& theCurve2d) |
572 | { |
573 | if (myFirstParam < myLastParam) return; |
574 | |
575 | Standard_Real cf = theCurve2d->FirstParameter(); |
576 | Standard_Real cl = theCurve2d->LastParameter(); |
577 | //:S4136 Standard_Real preci = BRepAPI::Precision(); |
578 | Standard_Real preci2d = Precision::PConfusion(); //:S4136: Parametric(preci, 0.01); |
579 | |
580 | // 15.11.2002 PTV OCC966 |
581 | if (ShapeAnalysis_Curve::IsPeriodic(theCurve2d)) { |
582 | ElCLib::AdjustPeriodic(cf,cl,preci2d,myFirstParam,myLastParam); |
583 | } |
584 | else if (theCurve2d->IsClosed()) { |
585 | //szv#4:S4163:12Mar99 optimized |
586 | if ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf; |
587 | else if ( Abs ( myLastParam - cf ) <= preci2d ) myLastParam = cl; |
588 | else { |
0797d9d3 |
589 | #ifdef OCCT_DEBUG |
04232180 |
590 | std::cout << "Error : curve 2d range crossing non periodic curve origin"; |
591 | std::cout << std::endl; |
7fd59977 |
592 | #endif |
593 | // add fail result; |
594 | return; |
595 | } |
596 | } |
597 | // the curve is closed within the 'file' 2D tolerance |
598 | else if (theCurve2d->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) { |
599 | Handle(Geom2d_BSplineCurve) aBSpline2d = |
600 | Handle(Geom2d_BSplineCurve)::DownCast(theCurve2d); |
601 | if (aBSpline2d->StartPoint().Distance(aBSpline2d->EndPoint()) <= preci2d) { |
602 | if ( Abs ( myFirstParam - cl ) <= preci2d ) myFirstParam = cf; |
603 | else if ( Abs ( myLastParam - cf ) <= preci2d ) myLastParam = cl; |
604 | } |
605 | } |
606 | else { |
0797d9d3 |
607 | #ifdef OCCT_DEBUG |
04232180 |
608 | std::cout << "Warning : non increasing parameters for 2d curve." << std::endl; |
609 | std::cout << " update parameter 2d uncertain." << std::endl; |
7fd59977 |
610 | #endif |
611 | Standard_Real tmp1 = myFirstParam, tmp2 = myLastParam; |
612 | myFirstParam = theCurve2d->ReversedParameter(tmp1); |
613 | myLastParam = theCurve2d->ReversedParameter(tmp2); |
614 | theCurve2d->Reverse(); |
04232180 |
615 | //std::cout<<"Reversed case 2"<<std::endl; |
7fd59977 |
616 | } |
617 | } |