b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
7fd59977 |
14 | |
f542b7bb |
15 | #include <algorithm> |
9369e98a |
16 | #include <memory> |
74d80fb9 |
17 | #include <TopoDS_Edge.hxx> |
18 | #include <Geom_Curve.hxx> |
19 | #include <BRepAdaptor_Curve.hxx> |
20 | #include <Adaptor3d_HSurface.hxx> |
9369e98a |
21 | #include <Adaptor3d_CurveOnSurface.hxx> |
22 | #include <Adaptor3d_HCurveOnSurface.hxx> |
74d80fb9 |
23 | #include <GeomAbs_SurfaceType.hxx> |
24 | #include <BRep_Tool.hxx> |
25 | #include <Geom_Line.hxx> |
9369e98a |
26 | #include <Geom_Plane.hxx> |
27 | #include <Geom_CylindricalSurface.hxx> |
28 | #include <Geom_ConicalSurface.hxx> |
29 | #include <Geom_SphericalSurface.hxx> |
30 | #include <Geom_ToroidalSurface.hxx> |
74d80fb9 |
31 | #include <gp_Lin.hxx> |
32 | #include <gp_Vec.hxx> |
33 | #include <gp_Dir.hxx> |
34 | #include <gp_Cylinder.hxx> |
35 | #include <gp_Ax1.hxx> |
36 | #include <gp_Lin.hxx> |
37 | |
38 | #include <GeomAdaptor_Curve.hxx> |
9369e98a |
39 | #include <GeomAdaptor_HSurface.hxx> |
74d80fb9 |
40 | #include <Precision.hxx> |
41 | #include <Extrema_ExtCC.hxx> |
9369e98a |
42 | //#include <Extrema_ExtCS.hxx> |
74d80fb9 |
43 | #include <Extrema_POnCurv.hxx> |
9369e98a |
44 | #include <IntCurveSurface_HInter.hxx> |
74d80fb9 |
45 | |
7fd59977 |
46 | #include <math_FunctionSample.hxx> |
47 | #include <math_FunctionAllRoots.hxx> |
7fd59977 |
48 | #include <TColgp_SequenceOfPnt.hxx> |
49 | |
74d80fb9 |
50 | // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 |
51 | |
52 | #include <Precision.hxx> |
53 | #include <IntSurf_Quadric.hxx> |
f542b7bb |
54 | #include <math_Function.hxx> |
55 | #include <math_BrentMinimum.hxx> |
56 | #include <math_Matrix.hxx> |
57 | #include <math_Vector.hxx> |
58 | #include <NCollection_Array1.hxx> |
74d80fb9 |
59 | |
9369e98a |
60 | #ifdef OCCT_DEBUG |
61 | #include <Geom_Circle.hxx> |
62 | #include <Geom_Ellipse.hxx> |
63 | #include <Geom_Hyperbola.hxx> |
64 | #include <Geom_Parabola.hxx> |
65 | #include <Geom_BezierCurve.hxx> |
66 | #include <Geom_BSplineCurve.hxx> |
67 | #include <GeomLib.hxx> |
68 | #endif |
69 | |
70 | |
71 | static Standard_Boolean IsDegenerated(const Handle(Adaptor3d_HCurveOnSurface)& theCurve); |
72 | static Standard_Boolean IsDegenerated(const IntSurf_Quadric& theQuadric); |
73 | |
74d80fb9 |
74 | static void FindVertex (const TheArc&, |
75 | const Handle(TheTopolTool)&, |
76 | TheFunction&, |
77 | IntStart_SequenceOfPathPoint&, |
78 | const Standard_Real); |
79 | |
80 | |
81 | static void BoundedArc (const TheArc& A, |
82 | const Handle(TheTopolTool)& Domain, |
83 | const Standard_Real Pdeb, |
84 | const Standard_Real Pfin, |
85 | TheFunction& Func, |
86 | IntStart_SequenceOfPathPoint& pnt, |
87 | IntStart_SequenceOfSegment& seg, |
88 | const Standard_Real TolBoundary, |
89 | const Standard_Real TolTangency, |
90 | Standard_Boolean& Arcsol, |
91 | const Standard_Boolean RecheckOnRegularity); |
92 | |
74d80fb9 |
93 | static void PointProcess (const gp_Pnt&, |
94 | const Standard_Real, |
95 | const TheArc&, |
96 | const Handle(TheTopolTool)&, |
97 | IntStart_SequenceOfPathPoint&, |
98 | const Standard_Real, |
99 | Standard_Integer&); |
100 | |
101 | static Standard_Integer TreatLC (const TheArc& A, |
102 | const Handle(TheTopolTool)& aDomain, |
103 | const IntSurf_Quadric& aQuadric, |
104 | const Standard_Real TolBoundary, |
105 | IntStart_SequenceOfPathPoint& pnt); |
106 | |
107 | static Standard_Boolean IsRegularity(const TheArc& A, |
108 | const Handle(TheTopolTool)& aDomain); |
109 | |
f542b7bb |
110 | class MinFunction : public math_Function |
111 | { |
112 | public: |
113 | MinFunction(TheFunction &theFunc) : myFunc(&theFunc) {}; |
114 | |
115 | //returns value of the one-dimension-function when parameter |
116 | //is equal to theX |
117 | virtual Standard_Boolean Value(const Standard_Real theX, |
118 | Standard_Real& theFVal) |
119 | { |
120 | if(!myFunc->Value(theX, theFVal)) |
121 | return Standard_False; |
122 | |
123 | theFVal *= theFVal; |
124 | return Standard_True; |
125 | } |
126 | |
127 | //see analogical method for abstract owner class math_Function |
128 | virtual Standard_Integer GetStateNumber() |
129 | { |
130 | return 0; |
131 | } |
132 | |
133 | private: |
134 | TheFunction *myFunc; |
135 | }; |
136 | |
74d80fb9 |
137 | |
138 | //======================================================================= |
139 | //function : FindVertex |
140 | //purpose : |
141 | //======================================================================= |
142 | void FindVertex (const TheArc& A, |
143 | const Handle(TheTopolTool)& Domain, |
144 | TheFunction& Func, |
145 | IntStart_SequenceOfPathPoint& pnt, |
146 | const Standard_Real Toler) |
147 | { |
148 | |
149 | // Find the vertex of the arc A restriction solutions. It stores |
150 | // Vertex in the list solutions pnt. |
151 | |
152 | |
153 | TheVertex vtx; |
154 | Standard_Real param,valf; |
155 | Standard_Integer itemp; |
156 | |
157 | Domain->Initialize(A); |
158 | Domain->InitVertexIterator(); |
159 | while (Domain->MoreVertex()) { |
160 | vtx = Domain->Vertex(); |
161 | param = TheSOBTool::Parameter(vtx,A); |
162 | |
163 | // Evaluate the function and look compared to tolerance of the |
164 | // Vertex. If distance <= tolerance then add a vertex to the list of solutions. |
165 | // The arc is already assumed in the load function. |
166 | |
167 | Func.Value(param,valf); |
168 | if (Abs(valf) <= Toler) { |
169 | itemp = Func.GetStateNumber(); |
170 | pnt.Append(IntStart_ThePathPoint(Func.Valpoint(itemp),Toler, vtx,A,param)); |
171 | // Solution is added |
172 | } |
173 | Domain->NextVertex(); |
174 | } |
175 | } |
176 | |
9369e98a |
177 | Standard_Boolean IsDegenerated(const Handle(Adaptor3d_HCurveOnSurface)& theCurve) |
178 | { |
179 | if (theCurve->GetType() == GeomAbs_Circle) |
180 | { |
181 | gp_Circ aCirc = theCurve->Circle(); |
182 | if (aCirc.Radius() <= Precision::Confusion()) |
183 | return Standard_True; |
184 | } |
185 | return Standard_False; |
186 | } |
187 | |
188 | Standard_Boolean IsDegenerated(const IntSurf_Quadric& theQuadric) |
189 | { |
190 | GeomAbs_SurfaceType TypeQuad = theQuadric.TypeQuadric(); |
191 | if (TypeQuad == GeomAbs_Cone) |
192 | { |
193 | gp_Cone aCone = theQuadric.Cone(); |
194 | Standard_Real aSemiAngle = Abs(aCone.SemiAngle()); |
195 | if (aSemiAngle < 0.02 || aSemiAngle > 1.55) |
196 | return Standard_True; |
197 | } |
198 | return Standard_False; |
199 | } |
200 | |
f542b7bb |
201 | class SolInfo |
202 | { |
203 | public: |
204 | SolInfo() : myMathIndex(-1), myValue(RealLast()) |
205 | { |
206 | } |
207 | |
208 | void Init(const math_FunctionAllRoots& theSolution, const Standard_Integer theIndex) |
209 | { |
210 | myMathIndex = theIndex; |
211 | myValue = theSolution.GetPoint(theIndex); |
212 | } |
213 | |
9369e98a |
214 | void Init(const IntCurveSurface_HInter& theSolution, const Standard_Integer theIndex) |
215 | { |
216 | myMathIndex = theIndex; |
217 | myValue = theSolution.Point(theIndex).W(); |
218 | } |
219 | |
f542b7bb |
220 | Standard_Real Value() const |
221 | { |
222 | return myValue; |
223 | } |
224 | |
225 | Standard_Integer Index() const |
226 | { |
227 | return myMathIndex; |
228 | } |
229 | |
230 | bool operator>(const SolInfo& theOther) const |
231 | { |
232 | return myValue > theOther.myValue; |
233 | } |
234 | |
235 | bool operator<(const SolInfo& theOther) const |
236 | { |
237 | return myValue < theOther.myValue; |
238 | } |
239 | |
240 | bool operator==(const SolInfo& theOther) const |
241 | { |
242 | return myValue == theOther.myValue; |
243 | } |
244 | |
245 | Standard_Real& ChangeValue() |
246 | { |
247 | return myValue; |
248 | } |
249 | |
250 | private: |
251 | Standard_Integer myMathIndex; |
252 | Standard_Real myValue; |
253 | }; |
254 | |
74d80fb9 |
255 | static |
256 | void BoundedArc (const TheArc& A, |
257 | const Handle(TheTopolTool)& Domain, |
258 | const Standard_Real Pdeb, |
259 | const Standard_Real Pfin, |
260 | TheFunction& Func, |
261 | IntStart_SequenceOfPathPoint& pnt, |
262 | IntStart_SequenceOfSegment& seg, |
263 | const Standard_Real TolBoundary, |
264 | const Standard_Real TolTangency, |
265 | Standard_Boolean& Arcsol, |
266 | const Standard_Boolean RecheckOnRegularity) |
267 | { |
f542b7bb |
268 | // Recherche des points solutions et des bouts d arc solution sur un arc donne. |
269 | // On utilise la fonction math_FunctionAllRoots. Ne convient donc que pour |
270 | // des arcs ayant un point debut et un point de fin (intervalle ferme de |
271 | // parametrage). |
74d80fb9 |
272 | |
9369e98a |
273 | Standard_Integer i, Nbi = 0, Nbp = 0; |
74d80fb9 |
274 | |
275 | gp_Pnt ptdeb,ptfin; |
295cb053 |
276 | Standard_Real pardeb = 0., parfin = 0.; |
74d80fb9 |
277 | Standard_Integer ideb,ifin,range,ranged,rangef; |
f542b7bb |
278 | |
74d80fb9 |
279 | // Creer l echantillonage (math_FunctionSample ou classe heritant) |
280 | // Appel a math_FunctionAllRoots |
281 | |
74d80fb9 |
282 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
283 | //@@@ La Tolerance est asociee a l arc ( Incoherence avec le cheminement ) |
284 | //@@@ ( EpsX ~ 1e-5 et ResolutionU et V ~ 1e-9 ) |
285 | //@@@ le vertex trouve ici n'est pas retrouve comme point d arret d une |
286 | //@@@ ligne de cheminement |
287 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
3306fdd9 |
288 | Standard_Real EpsX = 1.e-10; |
74d80fb9 |
289 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
290 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
291 | //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
f542b7bb |
292 | |
293 | // Standard_Integer NbEchant = TheSOBTool::NbSamplesOnArc(A); |
74d80fb9 |
294 | Standard_Integer NbEchant = Func.NbSamples(); |
9369e98a |
295 | if(NbEchant<100) NbEchant = 100; //-- lbr le 22 Avril 96 |
296 | //-- Toujours des pbs |
297 | |
74d80fb9 |
298 | //-- Modif 24 Aout 93 ----------------------------- |
299 | Standard_Real nTolTangency = TolTangency; |
300 | if((Pfin - Pdeb) < (TolTangency*10.0)) { |
301 | nTolTangency=(Pfin-Pdeb)*0.1; |
302 | } |
303 | if(EpsX>(nTolTangency+nTolTangency)) { |
304 | EpsX = nTolTangency * 0.1; |
305 | } |
9369e98a |
306 | |
74d80fb9 |
307 | //-------------------------------------------------- |
308 | //-- Plante avec un edge avec 2 Samples |
309 | //-- dont les extremites son solutions (f=0) |
310 | //-- et ou la derivee est nulle |
311 | //-- Exemple : un segment diametre d une sphere |
312 | //-- if(NbEchant<3) NbEchant = 3; //-- lbr le 19 Avril 95 |
313 | //-------------------------------------------------- |
314 | Standard_Real para=0,dist,maxdist; |
f542b7bb |
315 | |
74d80fb9 |
316 | //-------------------------------------------------------------- REJECTIONS le 15 oct 98 |
317 | Standard_Boolean Rejection=Standard_True; |
318 | Standard_Real maxdr,maxr,minr,ur,dur; |
319 | minr=RealLast(); |
320 | maxr=-minr; |
321 | maxdr=-minr; |
322 | dur=(Pfin-Pdeb)*0.2; |
323 | for(i=1,ur=Pdeb;i<=6;i++) { |
324 | Standard_Real F,D; |
325 | if(Func.Values(ur,F,D)) { |
326 | Standard_Real lminr,lmaxr; |
327 | if(D<0.0) D=-D; |
328 | D*=dur+dur; |
329 | if(D>maxdr) maxdr=D; |
330 | lminr=F-D; |
331 | lmaxr=F+D; |
332 | if(lminr<minr) minr=lminr; |
333 | if(lmaxr>maxr) maxr=lmaxr; |
334 | if(minr<0.0 && maxr>0.0) { |
335 | Rejection=Standard_False; |
78fdb3d3 |
336 | break; |
74d80fb9 |
337 | } |
338 | } |
339 | ur+=dur; |
340 | } |
78fdb3d3 |
341 | if(Rejection) |
342 | { |
343 | dur=0.001+maxdr+(maxr-minr)*0.1; |
344 | minr-=dur; |
345 | maxr+=dur; |
346 | if(minr<0.0 && maxr>0.0) { |
347 | Rejection=Standard_False; |
348 | } |
74d80fb9 |
349 | } |
350 | |
351 | Arcsol=Standard_False; |
352 | |
9369e98a |
353 | if(Rejection==Standard_False) |
354 | { |
355 | const IntSurf_Quadric& aQuadric = Func.Quadric(); |
356 | GeomAbs_SurfaceType TypeQuad = aQuadric.TypeQuadric(); |
357 | |
358 | IntCurveSurface_HInter IntCS; |
359 | Standard_Boolean IsIntCSdone = Standard_False; |
360 | TColStd_SequenceOfReal Params; |
361 | |
362 | #if (defined(_MSC_VER) && (_MSC_VER < 1600)) |
363 | std::auto_ptr<math_FunctionAllRoots> pSol; |
364 | #else |
365 | std::unique_ptr<math_FunctionAllRoots> pSol; |
366 | #endif |
367 | |
74d80fb9 |
368 | math_FunctionSample Echant(Pdeb,Pfin,NbEchant); |
f542b7bb |
369 | |
74d80fb9 |
370 | Standard_Boolean aelargir=Standard_True; |
371 | //modified by NIZNHY-PKV Thu Apr 12 09:25:19 2001 f |
372 | // |
373 | //maxdist = 100.0*TolBoundary; |
374 | maxdist = TolBoundary+TolTangency; |
375 | // |
376 | //modified by NIZNHY-PKV Thu Apr 12 09:25:23 2001 t |
377 | for(i=1; i<=NbEchant && aelargir;i++) { |
378 | Standard_Real u = Echant.GetParameter(i); |
379 | if(Func.Value(u,dist)) { |
380 | if(dist>maxdist || -dist>maxdist) { |
381 | aelargir=Standard_False; |
382 | } |
383 | } |
384 | } |
385 | if(!(aelargir && maxdist<0.01)) { |
386 | maxdist = TolBoundary; |
387 | } |
f542b7bb |
388 | |
9369e98a |
389 | if (TypeQuad != GeomAbs_OtherSurface) //intersection of boundary curve and quadric surface |
390 | { |
391 | //Exact solution |
392 | Handle(Adaptor3d_HSurface) aSurf = Func.Surface(); |
393 | Adaptor3d_CurveOnSurface ConS(A, aSurf); |
394 | GeomAbs_CurveType TypeConS = ConS.GetType(); |
395 | #ifdef OCCT_DEBUG |
396 | Handle(Geom_Curve) CurveConS; |
397 | switch(TypeConS) |
398 | { |
399 | case GeomAbs_Line: |
400 | { |
401 | CurveConS = new Geom_Line(ConS.Line()); |
402 | break; |
403 | } |
404 | case GeomAbs_Circle: |
405 | { |
406 | CurveConS = new Geom_Circle(ConS.Circle()); |
407 | break; |
408 | } |
409 | case GeomAbs_Ellipse: |
410 | { |
411 | CurveConS = new Geom_Ellipse(ConS.Ellipse()); |
412 | break; |
413 | } |
414 | case GeomAbs_Hyperbola: |
415 | { |
416 | CurveConS = new Geom_Hyperbola(ConS.Hyperbola()); |
417 | break; |
418 | } |
419 | case GeomAbs_Parabola: |
420 | { |
421 | CurveConS = new Geom_Parabola(ConS.Parabola()); |
422 | break; |
423 | } |
424 | case GeomAbs_BezierCurve: |
425 | { |
426 | CurveConS = ConS.Bezier(); |
427 | break; |
428 | } |
429 | case GeomAbs_BSplineCurve: |
430 | { |
431 | CurveConS = ConS.BSpline(); |
432 | break; |
433 | } |
434 | default: |
435 | { |
436 | Standard_Real MaxDeviation, AverageDeviation; |
437 | GeomLib::BuildCurve3d(1.e-5, ConS, ConS.FirstParameter(), ConS.LastParameter(), |
438 | CurveConS, MaxDeviation, AverageDeviation); |
439 | break; |
440 | } |
441 | } |
442 | #endif |
443 | Handle(Adaptor3d_HCurveOnSurface) HConS = new Adaptor3d_HCurveOnSurface(ConS); |
444 | Handle(Geom_Surface) QuadSurf; |
445 | switch (TypeQuad) |
446 | { |
447 | case GeomAbs_Plane: |
448 | { |
449 | QuadSurf = new Geom_Plane(aQuadric.Plane()); |
450 | break; |
451 | } |
452 | case GeomAbs_Cylinder: |
453 | { |
454 | QuadSurf = new Geom_CylindricalSurface(aQuadric.Cylinder()); |
455 | break; |
456 | } |
457 | case GeomAbs_Cone: |
458 | { |
459 | QuadSurf = new Geom_ConicalSurface(aQuadric.Cone()); |
460 | break; |
461 | } |
462 | case GeomAbs_Sphere: |
463 | { |
464 | QuadSurf = new Geom_SphericalSurface(aQuadric.Sphere()); |
465 | break; |
466 | } |
467 | case GeomAbs_Torus: |
468 | { |
469 | QuadSurf = new Geom_ToroidalSurface(aQuadric.Torus()); |
470 | break; |
471 | } |
472 | default: |
473 | break; |
474 | } |
475 | Handle(GeomAdaptor_HSurface) GAHsurf = new GeomAdaptor_HSurface(QuadSurf); |
476 | |
477 | if ((TypeConS == GeomAbs_Line || |
478 | TypeConS == GeomAbs_Circle || |
479 | TypeConS == GeomAbs_Ellipse || |
480 | TypeConS == GeomAbs_Parabola || |
481 | TypeConS == GeomAbs_Hyperbola) && |
482 | TypeQuad != GeomAbs_Torus && |
483 | !IsDegenerated(HConS) && |
484 | !IsDegenerated(aQuadric)) |
485 | { |
486 | //exact intersection for only canonic curves and real quadric surfaces |
487 | IntCS.Perform(HConS, GAHsurf); |
488 | } |
489 | |
490 | IsIntCSdone = IntCS.IsDone(); |
491 | if (IsIntCSdone) |
492 | { |
493 | Nbp = IntCS.NbPoints(); |
494 | Nbi = IntCS.NbSegments(); |
495 | } |
496 | //If we have not got intersection, it may be touch with some tolerance, |
497 | //need to be checked |
498 | if (Nbp == 0 && Nbi == 0) |
499 | IsIntCSdone = Standard_False; |
500 | |
501 | } //if (TypeQuad != GeomAbs_OtherSurface) - intersection of boundary curve and quadric surface |
502 | |
503 | if (!IsIntCSdone) |
504 | { |
505 | pSol.reset(new math_FunctionAllRoots(Func,Echant,EpsX,maxdist,maxdist)); //-- TolBoundary,nTolTangency); |
506 | |
507 | if (!pSol->IsDone()) {throw Standard_Failure();} |
508 | |
509 | Nbp=pSol->NbPoints(); |
510 | } |
db005e48 |
511 | // |
74d80fb9 |
512 | //jgv: build solution on the whole boundary |
513 | if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain)) |
514 | { |
515 | //Standard_Real theTol = Domain->MaxTolerance(A); |
516 | //theTol += theTol; |
517 | Standard_Real theTol = 5.e-4; |
518 | math_FunctionAllRoots SolAgain(Func,Echant,EpsX,theTol,theTol); //-- TolBoundary,nTolTangency); |
f542b7bb |
519 | |
9775fa61 |
520 | if (!SolAgain.IsDone()) {throw Standard_Failure();} |
f542b7bb |
521 | |
74d80fb9 |
522 | Standard_Integer Nbi_again = SolAgain.NbIntervals(); |
f542b7bb |
523 | |
74d80fb9 |
524 | if (Nbi_again > 0) |
525 | { |
526 | Standard_Integer NbSamples = 10; |
527 | Standard_Real delta = (Pfin - Pdeb)/NbSamples; |
528 | Standard_Real GlobalTol = theTol*10; |
529 | Standard_Boolean SolOnBoundary = Standard_True; |
530 | for (i = 0; i <= NbSamples; i++) |
531 | { |
532 | Standard_Real aParam = Pdeb + i*delta; |
533 | Standard_Real aValue; |
534 | Func.Value(aParam, aValue); |
535 | if (Abs(aValue) > GlobalTol) |
536 | { |
537 | SolOnBoundary = Standard_False; |
538 | break; |
539 | } |
540 | } |
541 | |
542 | if (SolOnBoundary) |
543 | { |
544 | for (i = 1; i <= Nbi_again; i++) |
545 | { |
546 | IntStart_TheSegment newseg; |
547 | newseg.SetValue(A); |
548 | // Recuperer point debut et fin, et leur parametre. |
549 | SolAgain.GetInterval(i,pardeb,parfin); |
f542b7bb |
550 | |
74d80fb9 |
551 | if (Abs(pardeb - Pdeb) <= Precision::PConfusion()) |
552 | pardeb = Pdeb; |
553 | if (Abs(parfin - Pfin) <= Precision::PConfusion()) |
554 | parfin = Pfin; |
f542b7bb |
555 | |
74d80fb9 |
556 | SolAgain.GetIntervalState(i,ideb,ifin); |
f542b7bb |
557 | |
74d80fb9 |
558 | //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<" ParFin:"<<parfin<<endl; |
f542b7bb |
559 | |
74d80fb9 |
560 | ptdeb=Func.Valpoint(ideb); |
561 | ptfin=Func.Valpoint(ifin); |
f542b7bb |
562 | |
74d80fb9 |
563 | PointProcess(ptdeb,pardeb,A,Domain,pnt,theTol,ranged); |
564 | newseg.SetLimitPoint(pnt.Value(ranged),Standard_True); |
565 | PointProcess(ptfin,parfin,A,Domain,pnt,theTol,rangef); |
566 | newseg.SetLimitPoint(pnt.Value(rangef),Standard_False); |
567 | seg.Append(newseg); |
568 | } |
569 | Arcsol=Standard_True; |
570 | return; |
571 | } |
572 | } |
9369e98a |
573 | } //if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain)) |
74d80fb9 |
574 | //////////////////////////////////////////// |
f542b7bb |
575 | |
74d80fb9 |
576 | //-- detection du cas ou la fonction est quasi tangente et que les |
577 | //-- zeros sont quasi confondus. |
578 | //-- Dans ce cas on prend le point "milieu" |
579 | //-- On suppose que les solutions sont triees. |
580 | |
74d80fb9 |
581 | if(Nbp) { |
f542b7bb |
582 | NCollection_Array1<SolInfo> aSI(1, Nbp); |
583 | |
584 | for(i=1;i<=Nbp;i++) |
585 | { |
9369e98a |
586 | if (IsIntCSdone) |
587 | aSI(i).Init(IntCS, i); |
588 | else |
589 | aSI(i).Init(*pSol, i); |
74d80fb9 |
590 | } |
f542b7bb |
591 | |
592 | std::sort(aSI.begin(), aSI.end()); |
593 | |
74d80fb9 |
594 | //modified by NIZNHY-PKV Wed Mar 21 18:34:18 2001 f |
595 | ////////////////////////////////////////////////////////// |
596 | // The treatment of the situation when line(arc) that is |
597 | // tangent to cylinder(domain). |
598 | // We should have only one solution i.e Nbp=1. Ok? |
599 | // But we have 2,3,.. solutions. That is wrong ersult. |
600 | // The TreatLC(...) function is dedicated to solve the pb. |
601 | // PKV Fri Mar 23 12:17:29 2001 |
f542b7bb |
602 | |
9369e98a |
603 | Standard_Integer ip = TreatLC (A, Domain, aQuadric, TolBoundary, pnt); |
74d80fb9 |
604 | if (ip) { |
f542b7bb |
605 | ////////////////////////////////////////////////////////// |
606 | //modified by NIZNHY-PKV Wed Mar 21 18:34:23 2001 t |
607 | // |
608 | // Using of old usual way proposed by Laurent |
609 | // |
610 | for(i=1;i<Nbp;i++) { |
611 | Standard_Real parap1 = aSI(i + 1).Value(); |
612 | para = aSI(i).Value(); |
613 | |
614 | Standard_Real param=(para+parap1)*0.5; |
615 | Standard_Real ym; |
616 | if(Func.Value(param,ym)) { |
617 | if(Abs(ym)<maxdist) { |
618 | // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 Begin |
619 | // Consider this interval as tangent one. Treat it to find |
620 | // parameter with the lowest function value. |
621 | |
622 | // Compute the number of nodes. |
623 | Standard_Real aTol = TolBoundary*1000.0; |
624 | if(aTol > 0.001) |
625 | aTol = 0.001; |
626 | |
627 | // fix floating point exception 569, chl-922-e9 |
628 | parap1 = (Abs(parap1) < 1.e9) ? parap1 : ((parap1 >= 0.) ? 1.e9 : -1.e9); |
629 | para = (Abs(para) < 1.e9) ? para : ((para >= 0.) ? 1.e9 : -1.e9); |
630 | |
631 | Standard_Integer aNbNodes = RealToInt(Ceiling((parap1 - para)/aTol)); |
632 | |
633 | Standard_Real aVal = RealLast(); |
634 | //Standard_Integer aNbNodes = 23; |
635 | Standard_Real aDelta = (parap1 - para)/(aNbNodes + 1.); |
636 | Standard_Integer ii; |
637 | Standard_Real aCurPar; |
638 | Standard_Real aCurVal; |
639 | |
640 | for (ii = 0; ii <= aNbNodes + 1; ii++) { |
641 | aCurPar = (ii < aNbNodes + 1) ? para + ii*aDelta : parap1; |
642 | |
643 | if (Func.Value(aCurPar, aCurVal)) { |
644 | //if (aCurVal < aVal) { |
645 | if (Abs(aCurVal) < aVal) { |
646 | //aVal = aCurVal; |
647 | aVal = Abs(aCurVal); |
648 | param = aCurPar; |
649 | } |
650 | } |
651 | } |
652 | // Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 End |
653 | aSI(i).ChangeValue() = Pdeb - 1; |
654 | aSI(i + 1).ChangeValue() = param; |
74d80fb9 |
655 | } |
74d80fb9 |
656 | } |
657 | } |
f542b7bb |
658 | |
659 | for (i=1; i<=Nbp; i++) { |
660 | para = aSI(i).Value(); |
661 | if((para-Pdeb)<EpsX || (Pfin-para)<EpsX) |
662 | continue; |
663 | |
664 | if(!Func.Value(para,dist)) |
665 | continue; |
666 | |
667 | dist = Abs(dist); |
668 | |
669 | Standard_Integer anIndx = -1; |
9369e98a |
670 | //const Standard_Real aParam = Sol->GetPoint(aSI(i).Index()); |
671 | const Standard_Real aParam = aSI(i).Value(); |
f542b7bb |
672 | if (dist < maxdist) |
673 | { |
9369e98a |
674 | if (!IsIntCSdone && |
675 | (Abs(aParam - Pdeb) <= Precision::PConfusion() || Abs(aParam - Pfin) <= Precision::PConfusion())) |
74d80fb9 |
676 | { |
9369e98a |
677 | anIndx = pSol->GetPointState(aSI(i).Index()); |
74d80fb9 |
678 | } |
f542b7bb |
679 | } |
680 | |
681 | gp_Pnt aPnt(anIndx < 0 ? Func.LastComputedPoint() : Func.Valpoint(anIndx)); |
74d80fb9 |
682 | |
f542b7bb |
683 | if (dist > 0.1*Precision::Confusion()) |
684 | { |
685 | //Precise found points. It results in following: |
686 | // 1. Make the vertex nearer to the intersection line |
687 | // (see description to issue #27252 in order to |
688 | // understand necessity). |
689 | // 2. Merge two near vertices to single point. |
690 | |
691 | //All members in TabSol array has already been sorted in increase order. |
692 | //Now, we limit precise boundaries in order to avoid changing this order. |
693 | const Standard_Real aFPar = (i == 1) ? Pdeb : (para + aSI(i - 1).Value()) / 2.0; |
694 | const Standard_Real aLPar = (i == Nbp) ? Pfin : (para + aSI(i + 1).Value()) / 2.0; |
695 | |
696 | MinFunction aNewFunc(Func); |
697 | math_BrentMinimum aMin(Precision::Confusion()); |
698 | |
699 | aMin.Perform(aNewFunc, aFPar, para, aLPar); |
700 | if(aMin.IsDone()) |
701 | { |
702 | para = aMin.Location(); |
703 | const gp_Pnt2d aP2d(A->Value(para)); |
704 | aPnt = Func.Surface()->Value(aP2d.X(), aP2d.Y()); |
705 | } |
74d80fb9 |
706 | } |
f542b7bb |
707 | |
708 | PointProcess(aPnt, para, A, Domain, pnt, TolBoundary, range); |
74d80fb9 |
709 | } |
f542b7bb |
710 | }// end of if(ip) |
74d80fb9 |
711 | } // end of if(Nbp) |
712 | |
713 | // Pour chaque intervalle trouve faire |
714 | // Traiter les extremites comme des points |
715 | // Ajouter intervalle dans la liste des segments |
f542b7bb |
716 | |
9369e98a |
717 | if (!IsIntCSdone) |
718 | Nbi = pSol->NbIntervals(); |
74d80fb9 |
719 | |
720 | if (!RecheckOnRegularity && Nbp) { |
721 | //--cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx :Nbp>0 0 <- Nbi "<<Nbi<<endl; |
722 | Nbi=0; |
723 | } |
724 | |
725 | //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : Nbi : "<<Nbi<<endl; |
f542b7bb |
726 | |
74d80fb9 |
727 | for (i=1; i<=Nbi; i++) { |
728 | IntStart_TheSegment newseg; |
729 | newseg.SetValue(A); |
730 | // Recuperer point debut et fin, et leur parametre. |
9369e98a |
731 | if (IsIntCSdone) |
732 | { |
733 | IntCurveSurface_IntersectionSegment IntSeg = IntCS.Segment(i); |
734 | IntCurveSurface_IntersectionPoint End1 = IntSeg.FirstPoint(); |
735 | IntCurveSurface_IntersectionPoint End2 = IntSeg.SecondPoint(); |
736 | pardeb = End1.W(); |
737 | parfin = End2.W(); |
738 | ptdeb = End1.Pnt(); |
739 | ptfin = End2.Pnt(); |
740 | } |
741 | else |
742 | { |
743 | pSol->GetInterval(i,pardeb,parfin); |
744 | pSol->GetIntervalState(i,ideb,ifin); |
74d80fb9 |
745 | |
9369e98a |
746 | //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<" ParFin:"<<parfin<<endl; |
747 | |
748 | ptdeb=Func.Valpoint(ideb); |
749 | ptfin=Func.Valpoint(ifin); |
750 | } |
f542b7bb |
751 | |
74d80fb9 |
752 | PointProcess(ptdeb,pardeb,A,Domain,pnt,TolBoundary,ranged); |
753 | newseg.SetLimitPoint(pnt.Value(ranged),Standard_True); |
754 | PointProcess(ptfin,parfin,A,Domain,pnt,TolBoundary,rangef); |
755 | newseg.SetLimitPoint(pnt.Value(rangef),Standard_False); |
756 | seg.Append(newseg); |
757 | } |
758 | |
759 | if (Nbi==1) { |
f542b7bb |
760 | if((Abs(pardeb - Pdeb) < Precision::PConfusion()) && |
761 | (Abs(parfin - Pfin) < Precision::PConfusion())) |
191478a5 |
762 | { |
74d80fb9 |
763 | Arcsol=Standard_True; |
764 | } |
765 | } |
766 | } |
767 | } |
768 | |
769 | //======================================================================= |
770 | //function : ComputeBoundsfromInfinite |
771 | //purpose : |
772 | //======================================================================= |
773 | // - PROVISIONAL - TEMPORARY - NOT GOOD - NYI - TO DO |
774 | // - Temporary - temporary - not good - nyi - to do |
775 | void ComputeBoundsfromInfinite(TheFunction& Func, |
776 | Standard_Real& PDeb, |
777 | Standard_Real& PFin, |
778 | Standard_Integer& NbEchant) |
779 | { |
780 | |
781 | // - We are looking for parameters for start and end of the arc (2d curve) |
782 | // - Infinity, a way to intersect the quadric with a portion of arc |
783 | // - Finished. |
784 | // |
785 | // - The quadric is a plane, a cylinder, a cone and a sphere. |
786 | // - Idea: We take any point on the arc and the fact grow |
d94fa32e |
787 | // - Terminals to the signed distance function values or is likely |
74d80fb9 |
788 | // - S cancel. |
789 | // |
790 | // - WARNING: The following calculations provide a very estimated coarse parameters. |
791 | // - This avoids the raises and allows a case of Boxes |
792 | // - Inifinies walk. It will take this code |
793 | // - With curve surface intersections. |
794 | |
7c4e9501 |
795 | NbEchant = 100; |
74d80fb9 |
796 | |
797 | Standard_Real U0 = 0.0; |
798 | Standard_Real dU = 0.001; |
799 | Standard_Real Dist0,Dist1; |
800 | |
801 | Func.Value(U0 , Dist0); |
802 | Func.Value(U0+dU, Dist1); |
803 | Standard_Real dDist = Dist1 - Dist0; |
804 | if(dDist) { |
805 | U0 -= dU*Dist0 / dDist; |
806 | PDeb = PFin = U0; |
807 | Standard_Real Umin = U0 - 1e5; |
808 | Func.Value(Umin , Dist0); |
809 | Func.Value(Umin+dU, Dist1); |
810 | dDist = Dist1-Dist0; |
811 | if(dDist) { |
812 | Umin -= dU*Dist0 / dDist; |
813 | } |
814 | else { |
815 | Umin-=10.0; |
816 | } |
817 | Standard_Real Umax = U0 + 1e8; |
818 | Func.Value(Umax , Dist0); |
819 | Func.Value(Umax+dU, Dist1); |
820 | dDist = Dist1-Dist0; |
821 | if(dDist) { |
822 | Umax -= dU*Dist0 / dDist; |
823 | } |
824 | else { |
825 | Umax+=10.0; |
826 | } |
827 | if(Umin>U0) { Umin=U0-10.0; } |
828 | if(Umax<U0) { Umax=U0+10.0; } |
829 | |
7c4e9501 |
830 | PFin = Umax + 10. * (Umax - Umin); |
831 | PDeb = Umin - 10. * (Umax - Umin); |
74d80fb9 |
832 | } |
833 | else { |
834 | //-- Possibilite de Arc totalement inclu ds Quad |
835 | PDeb = 1e10; |
836 | PFin = -1e10; |
837 | } |
838 | } |
839 | |
74d80fb9 |
840 | //======================================================================= |
841 | //function : PointProcess |
842 | //purpose : |
843 | //======================================================================= |
844 | void PointProcess (const gp_Pnt& Pt, |
845 | const Standard_Real Para, |
846 | const TheArc& A, |
847 | const Handle(TheTopolTool)& Domain, |
848 | IntStart_SequenceOfPathPoint& pnt, |
849 | const Standard_Real Tol, |
850 | Standard_Integer& Range) |
851 | { |
852 | |
853 | // Check to see if a solution point is coincident with a vertex. |
854 | // If confused, you should find this vertex in the list of |
855 | // Start. It then returns the position of this point in the list pnt. |
856 | // Otherwise, add the point in the list. |
857 | |
858 | Standard_Integer k; |
859 | Standard_Boolean found,goon; |
860 | Standard_Real dist,toler; |
861 | |
862 | Standard_Integer Nbsol = pnt.Length(); |
863 | TheVertex vtx; |
864 | IntStart_ThePathPoint ptsol; |
865 | |
866 | Domain->Initialize(A); |
867 | Domain->InitVertexIterator(); |
868 | found = Standard_False; |
869 | goon = Domain->MoreVertex(); |
870 | while (goon) { |
871 | vtx = Domain->Vertex(); |
872 | dist= Abs(Para-TheSOBTool::Parameter(vtx,A)); |
873 | toler = TheSOBTool::Tolerance(vtx,A); |
0797d9d3 |
874 | #ifdef OCCT_DEBUG |
74d80fb9 |
875 | if(toler>0.1) { |
04232180 |
876 | std::cout<<"IntStart_SearchOnBoundaries_1.gxx : ** WARNING ** Tol Vertex="<<toler<<std::endl; |
877 | std::cout<<" Ou Edge degenere Ou Kro pointu"<<std::endl; |
74d80fb9 |
878 | if(toler>10000) toler=1e-7; |
879 | } |
880 | #endif |
881 | |
882 | if (dist <= toler) { |
883 | // Locate the vertex in the list of solutions |
884 | k=1; |
885 | found = (k>Nbsol); |
886 | while (!found) { |
887 | ptsol = pnt.Value(k); |
888 | if (!ptsol.IsNew()) { |
889 | //jag 940608 if (ptsol.Vertex() == vtx && ptsol.Arc() == A) { |
890 | if (Domain->Identical(ptsol.Vertex(),vtx) && |
891 | ptsol.Arc() == A && |
892 | Abs(ptsol.Parameter()-Para) <= toler) { |
893 | found=Standard_True; |
894 | } |
895 | else { |
896 | k=k+1; |
897 | found=(k>Nbsol); |
898 | } |
899 | } |
900 | else { |
901 | k=k+1; |
902 | found=(k>Nbsol); |
903 | } |
904 | } |
905 | if (k<=Nbsol) { // We find the vertex |
906 | Range = k; |
907 | } |
908 | else { // Otherwise |
909 | ptsol.SetValue(Pt,Tol,vtx,A,Para); |
910 | pnt.Append(ptsol); |
911 | Range = pnt.Length(); |
912 | } |
913 | found = Standard_True; |
914 | goon = Standard_False; |
915 | } |
916 | else { |
917 | Domain->NextVertex(); |
918 | goon = Domain->MoreVertex(); |
919 | } |
920 | } |
921 | |
922 | if (!found) { // No one is falling on a vertex |
923 | //jgv: do not add segment's extremities if they already exist |
924 | Standard_Boolean found_internal = Standard_False; |
925 | for (k = 1; k <= pnt.Length(); k++) |
926 | { |
927 | ptsol = pnt.Value(k); |
928 | if (ptsol.Arc() != A || |
929 | !ptsol.IsNew()) //vertex |
930 | continue; |
931 | if (Abs(ptsol.Parameter()-Para) <= Precision::PConfusion()) |
932 | { |
933 | found_internal = Standard_True; |
934 | Range = k; |
935 | } |
936 | } |
937 | ///////////////////////////////////////////////////////////// |
938 | |
939 | if (!found_internal) |
940 | { |
941 | Standard_Real TOL=Tol; |
942 | TOL*=1000.0; |
db005e48 |
943 | //if(TOL>0.001) TOL=0.001; |
944 | if(TOL>0.005) TOL=0.005; //#24643 |
74d80fb9 |
945 | |
946 | ptsol.SetValue(Pt,TOL,A,Para); |
947 | pnt.Append(ptsol); |
948 | Range = pnt.Length(); |
949 | } |
950 | } |
951 | } |
952 | |
953 | //======================================================================= |
954 | //function : IsRegularity |
955 | //purpose : |
956 | //======================================================================= |
957 | Standard_Boolean IsRegularity(const TheArc& /*A*/, |
958 | const Handle(TheTopolTool)& aDomain) |
959 | { |
960 | Standard_Address anEAddress=aDomain->Edge(); |
961 | if (anEAddress==NULL) { |
962 | return Standard_False; |
963 | } |
964 | |
965 | TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress; |
966 | |
967 | return (BRep_Tool::HasContinuity(*anE)); |
968 | } |
969 | |
970 | //======================================================================= |
971 | //function : TreatLC |
972 | //purpose : |
973 | //======================================================================= |
974 | Standard_Integer TreatLC (const TheArc& A, |
975 | const Handle(TheTopolTool)& aDomain, |
976 | const IntSurf_Quadric& aQuadric, |
977 | const Standard_Real TolBoundary, |
978 | IntStart_SequenceOfPathPoint& pnt) |
979 | { |
980 | Standard_Integer anExitCode=1, aNbExt; |
981 | |
982 | Standard_Address anEAddress=aDomain->Edge(); |
983 | if (anEAddress==NULL) { |
984 | return anExitCode; |
985 | } |
986 | |
987 | TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress; |
988 | |
989 | if (BRep_Tool::Degenerated(*anE)) { |
990 | return anExitCode; |
991 | } |
992 | |
993 | GeomAbs_CurveType aTypeE; |
994 | BRepAdaptor_Curve aBAC(*anE); |
995 | aTypeE=aBAC.GetType(); |
996 | |
997 | if (aTypeE!=GeomAbs_Line) { |
998 | return anExitCode; |
999 | } |
1000 | |
1001 | GeomAbs_SurfaceType aTypeS; |
1002 | aTypeS=aQuadric.TypeQuadric(); |
1003 | |
1004 | if (aTypeS!=GeomAbs_Cylinder) { |
1005 | return anExitCode; |
1006 | } |
1007 | |
96a95605 |
1008 | Standard_Real f, l, U1f, U1l, U2f, U2l, UEgde, TOL, aDist, aR, aRRel, Tol; |
74d80fb9 |
1009 | Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, f, l); |
1010 | |
1011 | gp_Cylinder aCyl=aQuadric.Cylinder(); |
1012 | const gp_Ax1& anAx1=aCyl.Axis(); |
1013 | gp_Lin aLin(anAx1); |
1014 | Handle(Geom_Line) aCAxis=new Geom_Line (aLin); |
1015 | aR=aCyl.Radius(); |
1016 | |
1017 | U1f = aCAxis->FirstParameter(); |
1018 | U1l = aCAxis->LastParameter(); |
1019 | |
1020 | U2f = aCEdge->FirstParameter(); |
1021 | U2l = aCEdge->LastParameter(); |
1022 | |
1023 | |
1024 | GeomAdaptor_Curve C1, C2; |
1025 | |
1026 | C1.Load(aCAxis); |
1027 | C2.Load(aCEdge); |
1028 | |
1029 | Tol = Precision::PConfusion(); |
1030 | |
1031 | Extrema_ExtCC anExtCC(C1, C2, U1f, U1l, U2f, U2l, Tol, Tol); |
1032 | |
1033 | aNbExt=anExtCC.NbExt(); |
1034 | if (aNbExt!=1) { |
1035 | return anExitCode; |
1036 | } |
1037 | |
1038 | gp_Pnt P1,PEdge; |
1039 | Extrema_POnCurv PC1, PC2; |
1040 | |
1041 | anExtCC.Points(1, PC1, PC2); |
1042 | |
1043 | P1 =PC1.Value(); |
1044 | PEdge=PC2.Value(); |
1045 | |
74d80fb9 |
1046 | UEgde=PC2.Parameter(); |
1047 | |
1048 | aDist=PEdge.Distance(P1); |
1049 | aRRel=fabs(aDist-aR)/aR; |
1050 | if (aRRel > TolBoundary) { |
1051 | return anExitCode; |
1052 | } |
1053 | |
1054 | if (UEgde < (f+TolBoundary) || UEgde > (l-TolBoundary)) { |
1055 | return anExitCode; |
1056 | } |
1057 | // |
1058 | // Do not wonder ! |
1059 | // It was done as into PointProcess(...) function |
1060 | //printf("TreatLC()=> tangent line is found\n"); |
1061 | TOL=1000.*TolBoundary; |
1062 | if(TOL>0.001) TOL=0.001; |
1063 | |
1064 | IntStart_ThePathPoint ptsol; |
1065 | ptsol.SetValue(PEdge, TOL, A, UEgde); |
1066 | pnt.Append(ptsol); |
1067 | |
1068 | anExitCode=0; |
1069 | return anExitCode; |
1070 | |
1071 | } |
1072 | |
1073 | |
1074 | //======================================================================= |
1075 | //function : IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries |
1076 | //purpose : |
1077 | //======================================================================= |
1078 | IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries () |
1079 | : done(Standard_False) |
1080 | { |
1081 | } |
1082 | |
1083 | //======================================================================= |
1084 | //function : Perform |
1085 | //purpose : |
1086 | //======================================================================= |
1087 | void IntStart_SearchOnBoundaries::Perform (TheFunction& Func, |
1088 | const Handle(TheTopolTool)& Domain, |
1089 | const Standard_Real TolBoundary, |
1090 | const Standard_Real TolTangency, |
1091 | const Standard_Boolean RecheckOnRegularity) |
1092 | { |
1093 | |
1094 | done = Standard_False; |
1095 | spnt.Clear(); |
1096 | sseg.Clear(); |
1097 | |
1098 | Standard_Boolean Arcsol; |
1099 | Standard_Real PDeb,PFin, prm, tol; |
1100 | Standard_Integer i, nbknown, nbfound,index; |
1101 | gp_Pnt pt; |
1102 | |
1103 | Domain->Init(); |
1104 | |
1105 | if (Domain->More()) { |
1106 | all = Standard_True; |
1107 | } |
1108 | else { |
1109 | all = Standard_False; |
1110 | } |
1111 | |
1112 | while (Domain->More()) { |
1113 | TheArc A = Domain->Value(); |
1114 | if (!TheSOBTool::HasBeenSeen(A)) { |
1115 | Func.Set(A); |
1116 | FindVertex(A,Domain,Func,spnt,TolBoundary); |
1117 | TheSOBTool::Bounds(A,PDeb,PFin); |
1118 | if(Precision::IsNegativeInfinite(PDeb) || |
1119 | Precision::IsPositiveInfinite(PFin)) { |
7c4e9501 |
1120 | Standard_Integer NbEchant; |
1121 | ComputeBoundsfromInfinite(Func,PDeb,PFin,NbEchant); |
74d80fb9 |
1122 | } |
7c4e9501 |
1123 | BoundedArc(A,Domain,PDeb,PFin,Func,spnt,sseg,TolBoundary,TolTangency,Arcsol,RecheckOnRegularity); |
74d80fb9 |
1124 | all = (all && Arcsol); |
1125 | } |
1126 | |
1127 | else { |
1128 | // as it seems we'll never be here, because |
1129 | // TheSOBTool::HasBeenSeen(A) always returns FALSE |
1130 | nbfound = spnt.Length(); |
1131 | |
1132 | // On recupere les points connus |
1133 | nbknown = TheSOBTool::NbPoints(A); |
1134 | for (i=1; i<=nbknown; i++) { |
1135 | TheSOBTool::Value(A,i,pt,tol,prm); |
1136 | if (TheSOBTool::IsVertex(A,i)) { |
1137 | TheVertex vtx; |
1138 | TheSOBTool::Vertex(A,i,vtx); |
1139 | spnt.Append(IntStart_ThePathPoint(pt,tol,vtx,A,prm)); |
1140 | } |
1141 | else { |
1142 | spnt.Append(IntStart_ThePathPoint(pt,tol,A,prm)); |
1143 | } |
1144 | } |
1145 | // On recupere les arcs solutions |
1146 | nbknown = TheSOBTool::NbSegments(A); |
1147 | for (i=1; i<=nbknown; i++) { |
1148 | IntStart_TheSegment newseg; |
1149 | newseg.SetValue(A); |
1150 | if (TheSOBTool::HasFirstPoint(A,i,index)) { |
1151 | newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_True); |
1152 | } |
1153 | if (TheSOBTool::HasLastPoint(A,i,index)) { |
1154 | newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_False); |
1155 | } |
1156 | sseg.Append(newseg); |
1157 | } |
1158 | all = (all& TheSOBTool::IsAllSolution(A)); |
1159 | } |
1160 | Domain->Next(); |
1161 | } |
1162 | done = Standard_True; |
1163 | } |