1 // Created on: 1997-09-23
2 // Created by: Roman BORISOV
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Adaptor3d_HCurve.hxx>
20 #include <Adaptor3d_HSurface.hxx>
21 #include <Extrema_ExtCS.hxx>
22 #include <Extrema_ExtPS.hxx>
23 #include <Extrema_GenLocateExtPS.hxx>
24 #include <Extrema_POnCurv.hxx>
25 #include <Extrema_POnSurf.hxx>
26 #include <GeomAbs_CurveType.hxx>
27 #include <GeomLib.hxx>
28 #include <gp_Mat2d.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <gp_Vec2d.hxx>
32 #include <Precision.hxx>
33 #include <ProjLib_CompProjectedCurve.hxx>
34 #include <ProjLib_HCompProjectedCurve.hxx>
35 #include <ProjLib_PrjResolve.hxx>
36 #include <Standard_DomainError.hxx>
37 #include <Standard_NoSuchObject.hxx>
38 #include <Standard_NotImplemented.hxx>
39 #include <Standard_OutOfRange.hxx>
40 #include <TColgp_HSequenceOfPnt.hxx>
42 #define FuncTol 1.e-10
44 #ifdef OCCT_DEBUG_CHRONO
45 #include <OSD_Timer.hxx>
47 static OSD_Chronometer chr_init_point, chr_dicho_bound;
49 Standard_EXPORT Standard_Real t_init_point, t_dicho_bound;
50 Standard_EXPORT Standard_Integer init_point_count, dicho_bound_count;
52 static void InitChron(OSD_Chronometer& ch)
58 static void ResultChron( OSD_Chronometer & ch, Standard_Real & time)
68 //=======================================================================
70 //purpose : computes first derivative of the projected curve
71 //=======================================================================
73 static void d1(const Standard_Real t,
74 const Standard_Real u,
75 const Standard_Real v,
77 const Handle(Adaptor3d_HCurve)& Curve,
78 const Handle(Adaptor3d_HSurface)& Surface)
81 gp_Vec DS1_u, DS1_v, DS2_u, DS2_uv, DS2_v, DC1_t;
82 Surface->D2(u, v, S, DS1_u, DS1_v, DS2_u, DS2_v, DS2_uv);
83 Curve->D1(t, C, DC1_t);
84 gp_Vec Ort(C, S);// Ort = S - C
86 gp_Vec2d dE_dt(-DC1_t*DS1_u, -DC1_t*DS1_v);
87 gp_XY dE_du(DS1_u*DS1_u + Ort*DS2_u,
88 DS1_u*DS1_v + Ort*DS2_uv);
89 gp_XY dE_dv(DS1_v*DS1_u + Ort*DS2_uv,
90 DS1_v*DS1_v + Ort*DS2_v);
92 Standard_Real det = dE_du.X()*dE_dv.Y() - dE_du.Y()*dE_dv.X();
93 if (fabs(det) < gp::Resolution()) Standard_ConstructionError::Raise();
95 gp_Mat2d M(gp_XY(dE_dv.Y()/det, -dE_du.Y()/det),
96 gp_XY(-dE_dv.X()/det, dE_du.X()/det));
98 V = - gp_Vec2d(gp_Vec2d(M.Row(1))*dE_dt, gp_Vec2d(M.Row(2))*dE_dt);
101 //=======================================================================
103 //purpose : computes second derivative of the projected curve
104 //=======================================================================
106 static void d2(const Standard_Real t,
107 const Standard_Real u,
108 const Standard_Real v,
109 gp_Vec2d& V1, gp_Vec2d& V2,
110 const Handle(Adaptor3d_HCurve)& Curve,
111 const Handle(Adaptor3d_HSurface)& Surface)
114 gp_Vec DS1_u, DS1_v, DS2_u, DS2_uv, DS2_v,
115 DS3_u, DS3_v, DS3_uuv, DS3_uvv,
117 Surface->D3(u, v, S, DS1_u, DS1_v, DS2_u, DS2_v, DS2_uv,
118 DS3_u, DS3_v, DS3_uuv, DS3_uvv);
119 Curve->D2(t, C, DC1_t, DC2_t);
122 gp_Vec2d dE_dt(-DC1_t*DS1_u, -DC1_t*DS1_v);
123 gp_XY dE_du(DS1_u*DS1_u + Ort*DS2_u,
124 DS1_u*DS1_v + Ort*DS2_uv);
125 gp_XY dE_dv(DS1_v*DS1_u + Ort*DS2_uv,
126 DS1_v*DS1_v + Ort*DS2_v);
128 Standard_Real det = dE_du.X()*dE_dv.Y() - dE_du.Y()*dE_dv.X();
129 if (fabs(det) < gp::Resolution()) Standard_ConstructionError::Raise();
131 gp_Mat2d M(gp_XY(dE_dv.Y()/det, -dE_du.Y()/det),
132 gp_XY(-dE_dv.X()/det, dE_du.X()/det));
135 V1 = - gp_Vec2d(gp_Vec2d(M.Row(1))*dE_dt, gp_Vec2d(M.Row(2))*dE_dt);
137 /* Second derivative */
139 // Computation of d2E_dt2 = S1
140 gp_Vec2d d2E_dt(-DC2_t*DS1_u, -DC2_t*DS1_v);
142 // Computation of 2*(d2E/dtdX)(dX/dt) = S2
143 gp_Vec2d d2E1_dtdX(-DC1_t*DS2_u,
145 gp_Vec2d d2E2_dtdX(-DC1_t*DS2_uv,
147 gp_Vec2d S2 = 2*gp_Vec2d(d2E1_dtdX*V1, d2E2_dtdX*V1);
149 // Computation of (d2E/dX2)*(dX/dt)2 = S3
151 // Row11 = (d2E1/du2, d2E1/dudv)
153 gp_Vec2d Row11(3*DS1_u*DS2_u + Ort*DS3_u,
154 tmp = 2*DS1_u*DS2_uv +
155 DS1_v*DS2_u + Ort*DS3_uuv);
157 // Row12 = (d2E1/dudv, d2E1/dv2)
158 gp_Vec2d Row12(tmp, DS2_v*DS1_u + 2*DS1_v*DS2_uv +
161 // Row21 = (d2E2/du2, d2E2/dudv)
162 gp_Vec2d Row21(DS2_u*DS1_v + 2*DS1_u*DS2_uv + Ort*DS3_uuv,
163 tmp = 2*DS2_uv*DS1_v + DS1_u*DS2_v + Ort*DS3_uvv);
165 // Row22 = (d2E2/duv, d2E2/dvdv)
166 gp_Vec2d Row22(tmp, 3*DS1_v*DS2_v + Ort*DS3_v);
168 gp_Vec2d S3(V1*gp_Vec2d(Row11*V1, Row12*V1),
169 V1*gp_Vec2d(Row21*V1, Row22*V1));
171 gp_Vec2d Sum = d2E_dt + S2 + S3;
173 V2 = - gp_Vec2d(gp_Vec2d(M.Row(1))*Sum, gp_Vec2d(M.Row(2))*Sum);
175 //=======================================================================
176 //function : d1CurveOnSurf
177 //purpose : computes first derivative of the 3d projected curve
178 //=======================================================================
181 static void d1CurvOnSurf(const Standard_Real t,
182 const Standard_Real u,
183 const Standard_Real v,
185 const Handle(Adaptor3d_HCurve)& Curve,
186 const Handle(Adaptor3d_HSurface)& Surface)
190 gp_Vec DS1_u, DS1_v, DS2_u, DS2_uv, DS2_v, DC1_t;
191 Surface->D2(u, v, S, DS1_u, DS1_v, DS2_u, DS2_v, DS2_uv);
192 Curve->D1(t, C, DC1_t);
193 gp_Vec Ort(C, S);// Ort = S - C
195 gp_Vec2d dE_dt(-DC1_t*DS1_u, -DC1_t*DS1_v);
196 gp_XY dE_du(DS1_u*DS1_u + Ort*DS2_u,
197 DS1_u*DS1_v + Ort*DS2_uv);
198 gp_XY dE_dv(DS1_v*DS1_u + Ort*DS2_uv,
199 DS1_v*DS1_v + Ort*DS2_v);
201 Standard_Real det = dE_du.X()*dE_dv.Y() - dE_du.Y()*dE_dv.X();
202 if (fabs(det) < gp::Resolution()) Standard_ConstructionError::Raise();
204 gp_Mat2d M(gp_XY(dE_dv.Y()/det, -dE_du.Y()/det),
205 gp_XY(-dE_dv.X()/det, dE_du.X()/det));
207 V2d = - gp_Vec2d(gp_Vec2d(M.Row(1))*dE_dt, gp_Vec2d(M.Row(2))*dE_dt);
209 V = DS1_u * V2d.X() + DS1_v * V2d.Y();
214 //=======================================================================
215 //function : d2CurveOnSurf
216 //purpose : computes second derivative of the 3D projected curve
217 //=======================================================================
219 static void d2CurvOnSurf(const Standard_Real t,
220 const Standard_Real u,
221 const Standard_Real v,
222 gp_Vec& V1 , gp_Vec& V2 ,
223 const Handle(Adaptor3d_HCurve)& Curve,
224 const Handle(Adaptor3d_HSurface)& Surface)
228 gp_Vec DS1_u, DS1_v, DS2_u, DS2_uv, DS2_v,
229 DS3_u, DS3_v, DS3_uuv, DS3_uvv,
231 Surface->D3(u, v, S, DS1_u, DS1_v, DS2_u, DS2_v, DS2_uv,
232 DS3_u, DS3_v, DS3_uuv, DS3_uvv);
233 Curve->D2(t, C, DC1_t, DC2_t);
236 gp_Vec2d dE_dt(-DC1_t*DS1_u, -DC1_t*DS1_v);
237 gp_XY dE_du(DS1_u*DS1_u + Ort*DS2_u,
238 DS1_u*DS1_v + Ort*DS2_uv);
239 gp_XY dE_dv(DS1_v*DS1_u + Ort*DS2_uv,
240 DS1_v*DS1_v + Ort*DS2_v);
242 Standard_Real det = dE_du.X()*dE_dv.Y() - dE_du.Y()*dE_dv.X();
243 if (fabs(det) < gp::Resolution()) Standard_ConstructionError::Raise();
245 gp_Mat2d M(gp_XY(dE_dv.Y()/det, -dE_du.Y()/det),
246 gp_XY(-dE_dv.X()/det, dE_du.X()/det));
249 V12d = - gp_Vec2d(gp_Vec2d(M.Row(1))*dE_dt, gp_Vec2d(M.Row(2))*dE_dt);
251 /* Second derivative */
253 // Computation of d2E_dt2 = S1
254 gp_Vec2d d2E_dt(-DC2_t*DS1_u, -DC2_t*DS1_v);
256 // Computation of 2*(d2E/dtdX)(dX/dt) = S2
257 gp_Vec2d d2E1_dtdX(-DC1_t*DS2_u,
259 gp_Vec2d d2E2_dtdX(-DC1_t*DS2_uv,
261 gp_Vec2d S2 = 2*gp_Vec2d(d2E1_dtdX*V12d, d2E2_dtdX*V12d);
263 // Computation of (d2E/dX2)*(dX/dt)2 = S3
265 // Row11 = (d2E1/du2, d2E1/dudv)
267 gp_Vec2d Row11(3*DS1_u*DS2_u + Ort*DS3_u,
268 tmp = 2*DS1_u*DS2_uv +
269 DS1_v*DS2_u + Ort*DS3_uuv);
271 // Row12 = (d2E1/dudv, d2E1/dv2)
272 gp_Vec2d Row12(tmp, DS2_v*DS1_u + 2*DS1_v*DS2_uv +
275 // Row21 = (d2E2/du2, d2E2/dudv)
276 gp_Vec2d Row21(DS2_u*DS1_v + 2*DS1_u*DS2_uv + Ort*DS3_uuv,
277 tmp = 2*DS2_uv*DS1_v + DS1_u*DS2_v + Ort*DS3_uvv);
279 // Row22 = (d2E2/duv, d2E2/dvdv)
280 gp_Vec2d Row22(tmp, 3*DS1_v*DS2_v + Ort*DS3_v);
282 gp_Vec2d S3(V12d*gp_Vec2d(Row11*V12d, Row12*V12d),
283 V12d*gp_Vec2d(Row21*V12d, Row22*V12d));
285 gp_Vec2d Sum = d2E_dt + S2 + S3;
287 V22d = - gp_Vec2d(gp_Vec2d(M.Row(1))*Sum, gp_Vec2d(M.Row(2))*Sum);
289 V1 = DS1_u * V12d.X() + DS1_v * V12d.Y();
290 V2 = DS2_u * V12d.X() *V12d.X()
292 + 2 * DS2_uv * V12d.X() *V12d.Y()
293 + DS2_v * V12d.Y() * V12d.Y()
297 //=======================================================================
298 //function : ExactBound
299 //purpose : computes exact boundary point
300 //=======================================================================
302 static Standard_Boolean ExactBound(gp_Pnt& Sol,
303 const Standard_Real NotSol,
304 const Standard_Real Tol,
305 const Standard_Real TolU,
306 const Standard_Real TolV,
307 const Handle(Adaptor3d_HCurve)& Curve,
308 const Handle(Adaptor3d_HSurface)& Surface)
310 Standard_Real U0, V0, t, t1, t2, FirstU, LastU, FirstV, LastV;
314 FirstU = Surface->FirstUParameter();
315 LastU = Surface->LastUParameter();
316 FirstV = Surface->FirstVParameter();
317 LastV = Surface->LastVParameter();
318 // Here we have to compute the boundary that projection is going to intersect
320 //these variables are to estimate which boundary has more apportunity
322 Standard_Real RU1, RU2, RV1, RV2;
323 d1(Sol.X(), U0, V0, D2d, Curve, Surface);
324 // Here we assume that D2d != (0, 0)
325 if(Abs(D2d.X()) < gp::Resolution())
327 RU1 = Precision::Infinite();
328 RU2 = Precision::Infinite();
332 else if(Abs(D2d.Y()) < gp::Resolution())
336 RV1 = Precision::Infinite();
337 RV2 = Precision::Infinite();
341 RU1 = gp_Pnt2d(U0, V0).
342 Distance(gp_Pnt2d(FirstU, V0 + (FirstU - U0)*D2d.Y()/D2d.X()));
343 RU2 = gp_Pnt2d(U0, V0).
344 Distance(gp_Pnt2d(LastU, V0 + (LastU - U0)*D2d.Y()/D2d.X()));
345 RV1 = gp_Pnt2d(U0, V0).
346 Distance(gp_Pnt2d(U0 + (FirstV - V0)*D2d.X()/D2d.Y(), FirstV));
347 RV2 = gp_Pnt2d(U0, V0).
348 Distance(gp_Pnt2d(U0 + (LastV - V0)*D2d.X()/D2d.Y(), LastV));
350 TColgp_SequenceOfPnt Seq;
351 Seq.Append(gp_Pnt(FirstU, RU1, 2));
352 Seq.Append(gp_Pnt(LastU, RU2, 2));
353 Seq.Append(gp_Pnt(FirstV, RV1, 3));
354 Seq.Append(gp_Pnt(LastV, RV2, 3));
355 Standard_Integer i, j;
356 for(i = 1; i <= 3; i++)
357 for(j = 1; j <= 4-i; j++)
358 if(Seq(j).Y() < Seq(j+1).Y())
361 swp = Seq.Value(j+1);
362 Seq.ChangeValue(j+1) = Seq.Value(j);
363 Seq.ChangeValue(j) = swp;
367 t1 = Min(Sol.X(), NotSol);
368 t2 = Max(Sol.X(), NotSol);
370 Standard_Boolean isDone = Standard_False;
371 while (!Seq.IsEmpty())
375 Seq.Remove(Seq.Length());
376 ProjLib_PrjResolve aPrjPS(Curve->Curve(),
378 Standard_Integer(P.Z()));
379 if(Standard_Integer(P.Z()) == 2)
381 aPrjPS.Perform(t, P.X(), V0, gp_Pnt2d(Tol, TolV),
382 gp_Pnt2d(t1, Surface->FirstVParameter()),
383 gp_Pnt2d(t2, Surface->LastVParameter()), FuncTol);
384 if(!aPrjPS.IsDone()) continue;
385 POnS = aPrjPS.Solution();
386 Sol = gp_Pnt(POnS.X(), P.X(), POnS.Y());
387 isDone = Standard_True;
392 aPrjPS.Perform(t, U0, P.X(), gp_Pnt2d(Tol, TolU),
393 gp_Pnt2d(t1, Surface->FirstUParameter()),
394 gp_Pnt2d(t2, Surface->LastUParameter()), FuncTol);
395 if(!aPrjPS.IsDone()) continue;
396 POnS = aPrjPS.Solution();
397 Sol = gp_Pnt(POnS.X(), POnS.Y(), P.X());
398 isDone = Standard_True;
406 //=======================================================================
407 //function : DichExactBound
408 //purpose : computes exact boundary point
409 //=======================================================================
411 static void DichExactBound(gp_Pnt& Sol,
412 const Standard_Real NotSol,
413 const Standard_Real Tol,
414 const Standard_Real TolU,
415 const Standard_Real TolV,
416 const Handle(Adaptor3d_HCurve)& Curve,
417 const Handle(Adaptor3d_HSurface)& Surface)
419 #ifdef OCCT_DEBUG_CHRONO
420 InitChron(chr_dicho_bound);
423 Standard_Real U0, V0, t;
427 ProjLib_PrjResolve aPrjPS(Curve->Curve(), Surface->Surface(), 1);
429 Standard_Real aNotSol = NotSol;
430 while (fabs(Sol.X() - aNotSol) > Tol)
432 t = (Sol.X() + aNotSol)/2;
433 aPrjPS.Perform(t, U0, V0, gp_Pnt2d(TolU, TolV),
434 gp_Pnt2d(Surface->FirstUParameter(),Surface->FirstVParameter()),
435 gp_Pnt2d(Surface->LastUParameter(),Surface->LastVParameter()),
436 FuncTol, Standard_True);
440 POnS = aPrjPS.Solution();
441 Sol = gp_Pnt(t, POnS.X(), POnS.Y());
447 #ifdef OCCT_DEBUG_CHRONO
448 ResultChron(chr_dicho_bound,t_dicho_bound);
453 //=======================================================================
454 //function : InitialPoint
456 //=======================================================================
458 static Standard_Boolean InitialPoint(const gp_Pnt& Point,
459 const Standard_Real t,
460 const Handle(Adaptor3d_HCurve)& C,
461 const Handle(Adaptor3d_HSurface)& S,
462 const Standard_Real TolU,
463 const Standard_Real TolV,
468 ProjLib_PrjResolve aPrjPS(C->Curve(), S->Surface(), 1);
469 Standard_Real ParU,ParV;
470 Extrema_ExtPS aExtPS;
471 aExtPS.Initialize(S->Surface(), S->FirstUParameter(),
472 S->LastUParameter(), S->FirstVParameter(),
473 S->LastVParameter(), TolU, TolV);
475 aExtPS.Perform(Point);
476 Standard_Integer argmin = 0;
477 if (aExtPS.IsDone() && aExtPS.NbExt())
479 Standard_Integer i, Nend;
480 // Search for the nearest solution which is also a normal projection
481 Nend = aExtPS.NbExt();
482 for(i = 1; i <= Nend; i++)
484 Extrema_POnSurf POnS = aExtPS.Point(i);
485 POnS.Parameter(ParU, ParV);
486 aPrjPS.Perform(t, ParU, ParV, gp_Pnt2d(TolU, TolV),
487 gp_Pnt2d(S->FirstUParameter(), S->FirstVParameter()),
488 gp_Pnt2d(S->LastUParameter(), S->LastVParameter()),
489 FuncTol, Standard_True);
491 if (argmin == 0 || aExtPS.SquareDistance(i) < aExtPS.SquareDistance(argmin)) argmin = i;
494 if( argmin == 0 ) return Standard_False;
497 Extrema_POnSurf POnS = aExtPS.Point(argmin);
498 POnS.Parameter(U, V);
499 return Standard_True;
503 //=======================================================================
504 //function : ProjLib_CompProjectedCurve
506 //=======================================================================
508 ProjLib_CompProjectedCurve::ProjLib_CompProjectedCurve()
516 //=======================================================================
517 //function : ProjLib_CompProjectedCurve
519 //=======================================================================
521 ProjLib_CompProjectedCurve::ProjLib_CompProjectedCurve
522 (const Handle(Adaptor3d_HSurface)& theSurface,
523 const Handle(Adaptor3d_HCurve)& theCurve,
524 const Standard_Real theTolU,
525 const Standard_Real theTolV)
526 : mySurface (theSurface),
529 mySequence(new ProjLib_HSequenceOfHSequenceOfPnt()),
537 //=======================================================================
538 //function : ProjLib_CompProjectedCurve
540 //=======================================================================
542 ProjLib_CompProjectedCurve::ProjLib_CompProjectedCurve
543 (const Handle(Adaptor3d_HSurface)& theSurface,
544 const Handle(Adaptor3d_HCurve)& theCurve,
545 const Standard_Real theTolU,
546 const Standard_Real theTolV,
547 const Standard_Real theMaxDist)
548 : mySurface (theSurface),
551 mySequence(new ProjLib_HSequenceOfHSequenceOfPnt()),
554 myMaxDist (theMaxDist)
559 //=======================================================================
562 //=======================================================================
564 void ProjLib_CompProjectedCurve::Init()
568 Standard_Real Tol;// Tolerance for ExactBound
569 Standard_Integer i, Nend = 0;
570 Standard_Boolean FromLastU=Standard_False;
572 //new part (to discard far solutions)
573 Standard_Real TolC = Precision::Confusion(), TolS = Precision::Confusion();
574 Extrema_ExtCS CExt(myCurve->Curve(),
575 mySurface->Surface(),
578 if (CExt.IsDone() && CExt.NbExt())
580 // Search for the minimum solution
583 // Avoid usage of extrema result that can be wrong for extrusion
584 mySurface->GetType() != GeomAbs_SurfaceOfExtrusion)
586 Standard_Real min_val2;
587 min_val2 = CExt.SquareDistance(1);
588 for(i = 2; i <= Nend; i++)
589 if (CExt.SquareDistance(i) < min_val2) min_val2 = CExt.SquareDistance(i);
590 if (min_val2 > myMaxDist * myMaxDist)
596 Standard_Real FirstU, LastU, Step, SearchStep, WalkStep, t;
598 FirstU = myCurve->FirstParameter();
599 LastU = myCurve->LastParameter();
600 const Standard_Real GlobalMinStep = 1.e-4;
601 //<GlobalMinStep> is sufficiently small to provide solving from initial point
602 //and, on the other hand, it is sufficiently large to avoid too close solutions.
603 const Standard_Real MinStep = 0.01*(LastU - FirstU),
604 MaxStep = 0.1*(LastU - FirstU);
605 SearchStep = 10*MinStep;
608 //Initialization of aPrjPS
609 Standard_Real Uinf = mySurface->FirstUParameter();
610 Standard_Real Usup = mySurface->LastUParameter();
611 Standard_Real Vinf = mySurface->FirstVParameter();
612 Standard_Real Vsup = mySurface->LastVParameter();
614 ProjLib_PrjResolve aPrjPS(myCurve->Curve(), mySurface->Surface(), 1);
617 Standard_Boolean new_part;
618 Standard_Real prevDeb=0.;
619 Standard_Boolean SameDeb=Standard_False;
622 gp_Pnt Triple, prevTriple;
627 // Search for the beginning of a new continuous part
628 // to avoid infinite computation in some difficult cases.
629 new_part = Standard_False;
630 if(t > FirstU && Abs(t-prevDeb) <= Precision::PConfusion()) SameDeb=Standard_True;
631 while(t <= LastU && !new_part && !FromLastU && !SameDeb)
634 if (t == LastU) FromLastU=Standard_True;
635 Standard_Boolean initpoint=Standard_False;
636 Standard_Real U = 0., V = 0.;
638 Standard_Real ParT,ParU,ParV;
640 // Search an initial point in the list of Extrema Curve-Surface
641 if(Nend != 0 && !CExt.IsParallel())
643 for (i=1;i<=Nend;i++)
647 CExt.Points(i,P1,P2);
649 P2.Parameter(ParU, ParV);
651 aPrjPS.Perform(ParT, ParU, ParV, gp_Pnt2d(myTolU, myTolV),
652 gp_Pnt2d(mySurface->FirstUParameter(),mySurface->FirstVParameter()),
653 gp_Pnt2d(mySurface->LastUParameter(), mySurface->LastVParameter()),
654 FuncTol, Standard_True);
655 if ( aPrjPS.IsDone() && P1.Parameter() > Max(FirstU,t-Step+Precision::PConfusion())
656 && P1.Parameter() <= t)
662 initpoint = Standard_True;
669 myCurve->D0(t,CPoint);
670 #ifdef OCCT_DEBUG_CHRONO
671 InitChron(chr_init_point);
673 initpoint=InitialPoint(CPoint, t,myCurve,mySurface, myTolU, myTolV, U, V);
674 #ifdef OCCT_DEBUG_CHRONO
675 ResultChron(chr_init_point,t_init_point);
681 // When U or V lie on surface joint in some cases we cannot use them
682 // as initial point for aPrjPS, so we switch them
685 if ((mySurface->IsUPeriodic() &&
686 Abs(Usup - Uinf - mySurface->UPeriod()) < Precision::Confusion()) ||
687 (mySurface->IsVPeriodic() &&
688 Abs(Vsup - Vinf - mySurface->VPeriod()) < Precision::Confusion()))
690 if((Abs(U - Uinf) < mySurface->UResolution(Precision::PConfusion())) &&
691 mySurface->IsUPeriodic())
693 d1(t, U, V, D, myCurve, mySurface);
694 if (D.X() < 0 ) U = Usup;
696 else if((Abs(U - Usup) < mySurface->UResolution(Precision::PConfusion())) &&
697 mySurface->IsUPeriodic())
699 d1(t, U, V, D, myCurve, mySurface);
700 if (D.X() > 0) U = Uinf;
703 if((Abs(V - Vinf) < mySurface->VResolution(Precision::PConfusion())) &&
704 mySurface->IsVPeriodic())
706 d1(t, U, V, D, myCurve, mySurface);
707 if (D.Y() < 0) V = Vsup;
709 else if((Abs(V - Vsup) <= mySurface->VResolution(Precision::PConfusion())) &&
710 mySurface->IsVPeriodic())
712 d1(t, U, V, D, myCurve, mySurface);
713 if (D.Y() > 0) V = Vinf;
720 // Here we are going to stop if the distance between projection and
721 // corresponding curve point is greater than myMaxDist
724 mySurface->D0(U, V, POnS);
725 d = CPoint.Distance(POnS);
733 Triple = gp_Pnt(t, U, V);
736 //Search for exact boundary point
737 Tol = Min(myTolU, myTolV);
739 d1(Triple.X(), Triple.Y(), Triple.Z(), aD, myCurve, mySurface);
740 Tol /= Max(Abs(aD.X()), Abs(aD.Y()));
742 if(!ExactBound(Triple, t - Step, Tol,
743 myTolU, myTolV, myCurve, mySurface))
746 cout<<"There is a problem with ExactBound computation"<<endl;
748 DichExactBound(Triple, t - Step, Tol, myTolU, myTolV,
752 new_part = Standard_True;
756 if(t == LastU) break;
765 if (!new_part) break;
768 //We have found a new continuous part
769 Handle(TColgp_HSequenceOfPnt) hSeq = new TColgp_HSequenceOfPnt();
770 mySequence->Append(hSeq);
772 mySequence->Value(myNbCurves)->Append(Triple);
775 if (Triple.X() == LastU) break;//return;
777 //Computation of WalkStep
779 Standard_Real MagnD1, MagnD2;
780 d2CurvOnSurf(Triple.X(), Triple.Y(), Triple.Z(), D1, D2, myCurve, mySurface);
781 MagnD1 = D1.Magnitude();
782 MagnD2 = D2.Magnitude();
783 if(MagnD2 < Precision::Confusion()) WalkStep = MaxStep;
784 else WalkStep = Min(MaxStep, Max(MinStep, 0.1*MagnD1/MagnD2));
788 t = Triple.X() + Step;
789 if (t > LastU) t = LastU;
790 Standard_Real prevStep = Step;
791 Standard_Real U0, V0;
792 gp_Pnt2d aLowBorder(mySurface->FirstUParameter(),mySurface->FirstVParameter());
793 gp_Pnt2d aUppBorder(mySurface->LastUParameter(), mySurface->LastVParameter());
794 gp_Pnt2d aTol(myTolU, myTolV);
795 //Here we are trying to prolong continuous part
796 while (t <= LastU && new_part)
799 U0 = Triple.Y() + (Step / prevStep) * (Triple.Y() - prevTriple.Y());
800 V0 = Triple.Z() + (Step / prevStep) * (Triple.Z() - prevTriple.Z());
801 // adjust U0 to be in [mySurface->FirstUParameter(),mySurface->LastUParameter()]
802 U0 = Min(Max(U0, aLowBorder.X()), aUppBorder.X());
803 // adjust V0 to be in [mySurface->FirstVParameter(),mySurface->LastVParameter()]
804 V0 = Min(Max(V0, aLowBorder.Y()), aUppBorder.Y());
807 aPrjPS.Perform(t, U0, V0, aTol,
808 aLowBorder, aUppBorder, FuncTol, Standard_True);
811 if (Step <= GlobalMinStep)
813 //Search for exact boundary point
814 Tol = Min(myTolU, myTolV);
816 d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface);
817 Tol /= Max(Abs(D.X()), Abs(D.Y()));
819 if(!ExactBound(Triple, t, Tol, myTolU, myTolV,
823 cout<<"There is a problem with ExactBound computation"<<endl;
825 DichExactBound(Triple, t, Tol, myTolU, myTolV,
829 if((Triple.X() - mySequence->Value(myNbCurves)->Value(mySequence->Value(myNbCurves)->Length()).X()) > 1.e-10)
830 mySequence->Value(myNbCurves)->Append(Triple);
831 if((LastU - Triple.X()) < Tol) {t = LastU + 1; break;}//return;
834 t = Triple.X() + Step;
835 if (t > (LastU-MinStep/2) )
840 new_part = Standard_False;
845 Standard_Real SaveStep = Step;
847 t = Triple .X() + Step;
848 if (t > (LastU-MinStep/4) )
851 if (Abs(Step - SaveStep) <= Precision::PConfusion())
852 Step = GlobalMinStep; //to avoid looping
862 Triple = gp_Pnt(t, aPrjPS.Solution().X(), aPrjPS.Solution().Y());
864 // Check for possible local traps.
865 UpdateTripleByTrapCriteria(Triple);
867 if((Triple.X() - mySequence->Value(myNbCurves)->Value(mySequence->Value(myNbCurves)->Length()).X()) > 1.e-10)
868 mySequence->Value(myNbCurves)->Append(Triple);
869 if (t == LastU) {t = LastU + 1; break;}//return;
870 //Computation of WalkStep
871 d2CurvOnSurf(Triple.X(), Triple.Y(), Triple.Z(), D1, D2, myCurve, mySurface);
872 MagnD1 = D1.Magnitude();
873 MagnD2 = D2.Magnitude();
874 if(MagnD2 < Precision::Confusion() ) WalkStep = MaxStep;
875 else WalkStep = Min(MaxStep, Max(MinStep, 0.1*MagnD1/MagnD2));
879 if (t > (LastU-MinStep/2) )
887 // Sequence post-proceeding.
890 // 1. Removing poor parts
891 Standard_Integer NbPart=myNbCurves;
892 Standard_Integer ipart=1;
893 for(i = 1; i <= NbPart; i++) {
894 // Standard_Integer NbPoints = mySequence->Value(i)->Length();
895 if(mySequence->Value(ipart)->Length() < 2) {
896 mySequence->Remove(ipart);
902 if(myNbCurves == 0) return;
904 // 2. Removing common parts of bounds
905 for(i = 1; i < myNbCurves; i++)
907 if(mySequence->Value(i)->Value(mySequence->Value(i)->Length()).X() >=
908 mySequence->Value(i+1)->Value(1).X())
909 mySequence->ChangeValue(i+1)->ChangeValue(1).SetX(mySequence->Value(i)->Value(mySequence->Value(i)->Length()).X() + 1.e-12);
912 // 3. Computation of the maximum distance from each part of curve to surface
914 myMaxDistance = new TColStd_HArray1OfReal(1, myNbCurves);
915 myMaxDistance->Init(0);
916 for(i = 1; i <= myNbCurves; i++)
917 for(j = 1; j <= mySequence->Value(i)->Length(); j++)
919 gp_Pnt POnC, POnS, aTriple;
920 Standard_Real Distance;
921 aTriple = mySequence->Value(i)->Value(j);
922 myCurve->D0(aTriple.X(), POnC);
923 mySurface->D0(aTriple.Y(), aTriple.Z(), POnS);
924 Distance = POnC.Distance(POnS);
925 if (myMaxDistance->Value(i) < Distance)
926 myMaxDistance->ChangeValue(i) = Distance;
930 // 4. Check the projection to be a single point
932 gp_Pnt2d Pmoy, Pcurr, P;
933 Standard_Real AveU, AveV;
934 mySnglPnts = new TColStd_HArray1OfBoolean(1, myNbCurves);
935 for(i = 1; i <= myNbCurves; i++) mySnglPnts->SetValue(i, Standard_True);
937 for(i = 1; i <= myNbCurves; i++)
939 //compute an average U and V
941 for(j = 1, AveU = 0., AveV = 0.; j <= mySequence->Value(i)->Length(); j++)
943 AveU += mySequence->Value(i)->Value(j).Y();
944 AveV += mySequence->Value(i)->Value(j).Z();
946 AveU /= mySequence->Value(i)->Length();
947 AveV /= mySequence->Value(i)->Length();
949 Pmoy.SetCoord(AveU,AveV);
950 for(j = 1; j <= mySequence->Value(i)->Length(); j++)
953 gp_Pnt2d(mySequence->Value(i)->Value(j).Y(), mySequence->Value(i)->Value(j).Z());
954 if (Pcurr.Distance(Pmoy) > ((myTolU < myTolV) ? myTolV : myTolU))
956 mySnglPnts->SetValue(i, Standard_False);
962 // 5. Check the projection to be an isoparametric curve of the surface
964 myUIso = new TColStd_HArray1OfBoolean(1, myNbCurves);
965 for(i = 1; i <= myNbCurves; i++) myUIso->SetValue(i, Standard_True);
967 myVIso = new TColStd_HArray1OfBoolean(1, myNbCurves);
968 for(i = 1; i <= myNbCurves; i++) myVIso->SetValue(i, Standard_True);
970 for(i = 1; i <= myNbCurves; i++) {
971 if (IsSinglePnt(i, P)|| mySequence->Value(i)->Length() <=2) {
972 myUIso->SetValue(i, Standard_False);
973 myVIso->SetValue(i, Standard_False);
977 // new test for isoparametrics
979 if ( mySequence->Value(i)->Length() > 2) {
980 //compute an average U and V
982 for(j = 1, AveU = 0., AveV = 0.; j <= mySequence->Value(i)->Length(); j++) {
983 AveU += mySequence->Value(i)->Value(j).Y();
984 AveV += mySequence->Value(i)->Value(j).Z();
986 AveU /= mySequence->Value(i)->Length();
987 AveV /= mySequence->Value(i)->Length();
989 // is i-part U-isoparametric ?
990 for(j = 1; j <= mySequence->Value(i)->Length(); j++)
992 if(Abs(mySequence->Value(i)->Value(j).Y() - AveU) > myTolU)
994 myUIso->SetValue(i, Standard_False);
999 // is i-part V-isoparametric ?
1000 for(j = 1; j <= mySequence->Value(i)->Length(); j++)
1002 if(Abs(mySequence->Value(i)->Value(j).Z() - AveV) > myTolV)
1004 myVIso->SetValue(i, Standard_False);
1012 //=======================================================================
1015 //=======================================================================
1017 void ProjLib_CompProjectedCurve::Load(const Handle(Adaptor3d_HSurface)& S)
1022 //=======================================================================
1025 //=======================================================================
1027 void ProjLib_CompProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
1032 //=======================================================================
1033 //function : GetSurface
1035 //=======================================================================
1037 const Handle(Adaptor3d_HSurface)& ProjLib_CompProjectedCurve::GetSurface() const
1043 //=======================================================================
1044 //function : GetCurve
1046 //=======================================================================
1048 const Handle(Adaptor3d_HCurve)& ProjLib_CompProjectedCurve::GetCurve() const
1053 //=======================================================================
1054 //function : GetTolerance
1056 //=======================================================================
1058 void ProjLib_CompProjectedCurve::GetTolerance(Standard_Real& TolU,
1059 Standard_Real& TolV) const
1065 //=======================================================================
1066 //function : NbCurves
1068 //=======================================================================
1070 Standard_Integer ProjLib_CompProjectedCurve::NbCurves() const
1074 //=======================================================================
1077 //=======================================================================
1079 void ProjLib_CompProjectedCurve::Bounds(const Standard_Integer Index,
1080 Standard_Real& Udeb,
1081 Standard_Real& Ufin) const
1083 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1084 Udeb = mySequence->Value(Index)->Value(1).X();
1085 Ufin = mySequence->Value(Index)->Value(mySequence->Value(Index)->Length()).X();
1087 //=======================================================================
1088 //function : IsSinglePnt
1090 //=======================================================================
1092 Standard_Boolean ProjLib_CompProjectedCurve::IsSinglePnt(const Standard_Integer Index, gp_Pnt2d& P) const
1094 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1095 P = gp_Pnt2d(mySequence->Value(Index)->Value(1).Y(), mySequence->Value(Index)->Value(1).Z());
1096 return mySnglPnts->Value(Index);
1099 //=======================================================================
1102 //=======================================================================
1104 Standard_Boolean ProjLib_CompProjectedCurve::IsUIso(const Standard_Integer Index, Standard_Real& U) const
1106 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1107 U = mySequence->Value(Index)->Value(1).Y();
1108 return myUIso->Value(Index);
1110 //=======================================================================
1113 //=======================================================================
1115 Standard_Boolean ProjLib_CompProjectedCurve::IsVIso(const Standard_Integer Index, Standard_Real& V) const
1117 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1118 V = mySequence->Value(Index)->Value(1).Z();
1119 return myVIso->Value(Index);
1121 //=======================================================================
1124 //=======================================================================
1126 gp_Pnt2d ProjLib_CompProjectedCurve::Value(const Standard_Real t) const
1132 //=======================================================================
1135 //=======================================================================
1137 void ProjLib_CompProjectedCurve::D0(const Standard_Real U,gp_Pnt2d& P) const
1139 Standard_Integer i, j;
1140 Standard_Real Udeb, Ufin;
1141 Standard_Boolean found = Standard_False;
1143 for(i = 1; i <= myNbCurves; i++)
1145 Bounds(i, Udeb, Ufin);
1146 if (U >= Udeb && U <= Ufin)
1148 found = Standard_True;
1152 if (!found) Standard_DomainError::Raise("ProjLib_CompProjectedCurve::D0");
1154 Standard_Real U0, V0;
1156 Standard_Integer End = mySequence->Value(i)->Length();
1157 for(j = 1; j < End; j++)
1158 if ((U >= mySequence->Value(i)->Value(j).X()) && (U <= mySequence->Value(i)->Value(j + 1).X())) break;
1160 // U0 = mySequence->Value(i)->Value(j).Y();
1161 // V0 = mySequence->Value(i)->Value(j).Z();
1163 // Cubic Interpolation
1164 if(mySequence->Value(i)->Length() < 4 ||
1165 (Abs(U-mySequence->Value(i)->Value(j).X()) <= Precision::PConfusion()) )
1167 U0 = mySequence->Value(i)->Value(j).Y();
1168 V0 = mySequence->Value(i)->Value(j).Z();
1170 else if (Abs(U-mySequence->Value(i)->Value(j+1).X())
1171 <= Precision::PConfusion())
1173 U0 = mySequence->Value(i)->Value(j+1).Y();
1174 V0 = mySequence->Value(i)->Value(j+1).Z();
1179 if (j > mySequence->Value(i)->Length() - 2)
1180 j = mySequence->Value(i)->Length() - 2;
1182 gp_Vec2d I1, I2, I3, I21, I22, I31, Y1, Y2, Y3, Y4, Res;
1183 Standard_Real X1, X2, X3, X4;
1185 X1 = mySequence->Value(i)->Value(j - 1).X();
1186 X2 = mySequence->Value(i)->Value(j).X();
1187 X3 = mySequence->Value(i)->Value(j + 1).X();
1188 X4 = mySequence->Value(i)->Value(j + 2).X();
1190 Y1 = gp_Vec2d(mySequence->Value(i)->Value(j - 1).Y(),
1191 mySequence->Value(i)->Value(j - 1).Z());
1192 Y2 = gp_Vec2d(mySequence->Value(i)->Value(j).Y(),
1193 mySequence->Value(i)->Value(j).Z());
1194 Y3 = gp_Vec2d(mySequence->Value(i)->Value(j + 1).Y(),
1195 mySequence->Value(i)->Value(j + 1).Z());
1196 Y4 = gp_Vec2d(mySequence->Value(i)->Value(j + 2).Y(),
1197 mySequence->Value(i)->Value(j + 2).Z());
1199 I1 = (Y1 - Y2)/(X1 - X2);
1200 I2 = (Y2 - Y3)/(X2 - X3);
1201 I3 = (Y3 - Y4)/(X3 - X4);
1203 I21 = (I1 - I2)/(X1 - X3);
1204 I22 = (I2 - I3)/(X2 - X4);
1206 I31 = (I21 - I22)/(X1 - X4);
1208 Res = Y1 + (U - X1)*(I1 + (U - X2)*(I21 + (U - X3)*I31));
1213 if(U0 < mySurface->FirstUParameter()) U0 = mySurface->FirstUParameter();
1214 else if(U0 > mySurface->LastUParameter()) U0 = mySurface->LastUParameter();
1216 if(V0 < mySurface->FirstVParameter()) V0 = mySurface->FirstVParameter();
1217 else if(V0 > mySurface->LastVParameter()) V0 = mySurface->LastVParameter();
1219 //End of cubic interpolation
1221 ProjLib_PrjResolve aPrjPS(myCurve->Curve(), mySurface->Surface(), 1);
1222 aPrjPS.Perform(U, U0, V0, gp_Pnt2d(myTolU, myTolV),
1223 gp_Pnt2d(mySurface->FirstUParameter(), mySurface->FirstVParameter()),
1224 gp_Pnt2d(mySurface->LastUParameter(), mySurface->LastVParameter()));
1225 if (aPrjPS.IsDone())
1226 P = aPrjPS.Solution();
1229 gp_Pnt thePoint = myCurve->Value(U);
1230 Extrema_ExtPS aExtPS(thePoint, mySurface->Surface(), myTolU, myTolV);
1231 if (aExtPS.IsDone() && aExtPS.NbExt())
1233 Standard_Integer k, Nend, imin = 1;
1234 // Search for the nearest solution which is also a normal projection
1235 Nend = aExtPS.NbExt();
1236 for(k = 2; k <= Nend; k++)
1237 if (aExtPS.SquareDistance(k) < aExtPS.SquareDistance(imin))
1239 const Extrema_POnSurf& POnS = aExtPS.Point(imin);
1240 Standard_Real ParU,ParV;
1241 POnS.Parameter(ParU, ParV);
1242 P.SetCoord(ParU, ParV);
1248 //=======================================================================
1251 //=======================================================================
1253 void ProjLib_CompProjectedCurve::D1(const Standard_Real t,
1261 d1(t, u, v, V, myCurve, mySurface);
1263 //=======================================================================
1266 //=======================================================================
1268 void ProjLib_CompProjectedCurve::D2(const Standard_Real t,
1277 d2(t, u, v, V1, V2, myCurve, mySurface);
1279 //=======================================================================
1282 //=======================================================================
1284 gp_Vec2d ProjLib_CompProjectedCurve::DN(const Standard_Real t,
1285 const Standard_Integer N) const
1287 if (N < 1 ) Standard_OutOfRange::Raise("ProjLib_CompProjectedCurve : N must be greater than 0");
1303 Standard_NotImplemented::Raise("ProjLib_CompProjectedCurve::DN");
1307 //=======================================================================
1308 //function : GetSequence
1310 //=======================================================================
1312 const Handle(ProjLib_HSequenceOfHSequenceOfPnt)& ProjLib_CompProjectedCurve::GetSequence() const
1316 //=======================================================================
1317 //function : FirstParameter
1319 //=======================================================================
1321 Standard_Real ProjLib_CompProjectedCurve::FirstParameter() const
1323 return myCurve->FirstParameter();
1326 //=======================================================================
1327 //function : LastParameter
1329 //=======================================================================
1331 Standard_Real ProjLib_CompProjectedCurve::LastParameter() const
1333 return myCurve->LastParameter();
1336 //=======================================================================
1337 //function : MaxDistance
1339 //=======================================================================
1341 Standard_Real ProjLib_CompProjectedCurve::MaxDistance(const Standard_Integer Index) const
1343 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1344 return myMaxDistance->Value(Index);
1347 //=======================================================================
1348 //function : NbIntervals
1350 //=======================================================================
1352 Standard_Integer ProjLib_CompProjectedCurve::NbIntervals(const GeomAbs_Shape S) const
1354 const_cast<ProjLib_CompProjectedCurve*>(this)->myTabInt.Nullify();
1356 return myTabInt->Length() - 1;
1359 //=======================================================================
1360 //function : Intervals
1362 //=======================================================================
1364 void ProjLib_CompProjectedCurve::Intervals(TColStd_Array1OfReal& T,const GeomAbs_Shape S) const
1366 if (myTabInt.IsNull()) BuildIntervals (S);
1367 T = myTabInt->Array1();
1370 //=======================================================================
1371 //function : BuildIntervals
1373 //=======================================================================
1375 void ProjLib_CompProjectedCurve::BuildIntervals(const GeomAbs_Shape S) const
1377 GeomAbs_Shape SforS = GeomAbs_CN;
1395 Standard_OutOfRange::Raise();
1397 Standard_Integer i, j, k;
1398 Standard_Integer NbIntCur = myCurve->NbIntervals(S);
1399 Standard_Integer NbIntSurU = mySurface->NbUIntervals(SforS);
1400 Standard_Integer NbIntSurV = mySurface->NbVIntervals(SforS);
1402 TColStd_Array1OfReal CutPntsT(1, NbIntCur+1);
1403 TColStd_Array1OfReal CutPntsU(1, NbIntSurU+1);
1404 TColStd_Array1OfReal CutPntsV(1, NbIntSurV+1);
1406 myCurve->Intervals(CutPntsT, S);
1407 mySurface->UIntervals(CutPntsU, SforS);
1408 mySurface->VIntervals(CutPntsV, SforS);
1410 Standard_Real Tl, Tr, Ul, Ur, Vl, Vr, Tol;
1412 Handle(TColStd_HArray1OfReal) BArr = NULL,
1417 // proccessing projection bounds
1418 BArr = new TColStd_HArray1OfReal(1, 2*myNbCurves);
1419 for(i = 1; i <= myNbCurves; i++)
1420 Bounds(i, BArr->ChangeValue(2*i - 1), BArr->ChangeValue(2*i));
1422 // proccessing curve discontinuities
1424 CArr = new TColStd_HArray1OfReal(1, NbIntCur - 1);
1425 for(i = 1; i <= CArr->Length(); i++)
1426 CArr->ChangeValue(i) = CutPntsT(i + 1);
1429 // proccessing U-surface discontinuities
1430 TColStd_SequenceOfReal TUdisc;
1432 for(k = 2; k <= NbIntSurU; k++) {
1433 // cout<<"CutPntsU("<<k<<") = "<<CutPntsU(k)<<endl;
1434 for(i = 1; i <= myNbCurves; i++)
1435 for(j = 1; j < mySequence->Value(i)->Length(); j++) {
1436 Ul = mySequence->Value(i)->Value(j).Y();
1437 Ur = mySequence->Value(i)->Value(j + 1).Y();
1439 if(Abs(Ul - CutPntsU(k)) <= myTolU)
1440 TUdisc.Append(mySequence->Value(i)->Value(j).X());
1441 else if(Abs(Ur - CutPntsU(k)) <= myTolU)
1442 TUdisc.Append(mySequence->Value(i)->Value(j + 1).X());
1443 else if((Ul < CutPntsU(k) && CutPntsU(k) < Ur) ||
1444 (Ur < CutPntsU(k) && CutPntsU(k) < Ul))
1447 V = (mySequence->Value(i)->Value(j).Z()
1448 + mySequence->Value(i)->Value(j +1).Z())/2;
1449 ProjLib_PrjResolve Solver(myCurve->Curve(), mySurface->Surface(), 2);
1453 Triple = mySequence->Value(i)->Value(j);
1454 d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface);
1455 if (Abs(D.X()) < Precision::Confusion())
1458 Tol = Min(myTolU, myTolU / Abs(D.X()));
1460 Tl = mySequence->Value(i)->Value(j).X();
1461 Tr = mySequence->Value(i)->Value(j + 1).X();
1463 Solver.Perform((Tl + Tr)/2, CutPntsU(k), V,
1464 gp_Pnt2d(Tol, myTolV),
1465 gp_Pnt2d(Tl, mySurface->FirstVParameter()),
1466 gp_Pnt2d(Tr, mySurface->LastVParameter()));
1470 TUdisc.Append(Solver.Solution().X());
1475 for(i = 2; i <= TUdisc.Length(); i++)
1476 if(TUdisc(i) - TUdisc(i-1) < Precision::PConfusion())
1481 UArr = new TColStd_HArray1OfReal(1, TUdisc.Length());
1482 for(i = 1; i <= UArr->Length(); i++)
1483 UArr->ChangeValue(i) = TUdisc(i);
1485 // proccessing V-surface discontinuities
1486 TColStd_SequenceOfReal TVdisc;
1488 for(k = 2; k <= NbIntSurV; k++)
1489 for(i = 1; i <= myNbCurves; i++)
1491 // cout<<"CutPntsV("<<k<<") = "<<CutPntsV(k)<<endl;
1492 for(j = 1; j < mySequence->Value(i)->Length(); j++) {
1494 Vl = mySequence->Value(i)->Value(j).Z();
1495 Vr = mySequence->Value(i)->Value(j + 1).Z();
1497 if(Abs(Vl - CutPntsV(k)) <= myTolV)
1498 TVdisc.Append(mySequence->Value(i)->Value(j).X());
1499 else if (Abs(Vr - CutPntsV(k)) <= myTolV)
1500 TVdisc.Append(mySequence->Value(i)->Value(j + 1).X());
1501 else if((Vl < CutPntsV(k) && CutPntsV(k) < Vr) ||
1502 (Vr < CutPntsV(k) && CutPntsV(k) < Vl))
1505 U = (mySequence->Value(i)->Value(j).Y()
1506 + mySequence->Value(i)->Value(j +1).Y())/2;
1507 ProjLib_PrjResolve Solver(myCurve->Curve(), mySurface->Surface(), 3);
1511 Triple = mySequence->Value(i)->Value(j);
1512 d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface);
1513 if (Abs(D.Y()) < Precision::Confusion())
1516 Tol = Min(myTolV, myTolV / Abs(D.Y()));
1518 Tl = mySequence->Value(i)->Value(j).X();
1519 Tr = mySequence->Value(i)->Value(j + 1).X();
1521 Solver.Perform((Tl + Tr)/2, U, CutPntsV(k),
1522 gp_Pnt2d(Tol, myTolV),
1523 gp_Pnt2d(Tl, mySurface->FirstUParameter()),
1524 gp_Pnt2d(Tr, mySurface->LastUParameter()));
1528 TVdisc.Append(Solver.Solution().X());
1533 for(i = 2; i <= TVdisc.Length(); i++)
1534 if(TVdisc(i) - TVdisc(i-1) < Precision::PConfusion())
1539 VArr = new TColStd_HArray1OfReal(1, TVdisc.Length());
1540 for(i = 1; i <= VArr->Length(); i++)
1541 VArr->ChangeValue(i) = TVdisc(i);
1545 TColStd_SequenceOfReal Fusion;
1548 GeomLib::FuseIntervals(BArr->ChangeArray1(),
1549 CArr->ChangeArray1(),
1550 Fusion, Precision::PConfusion());
1551 BArr = new TColStd_HArray1OfReal(1, Fusion.Length());
1552 for(i = 1; i <= BArr->Length(); i++)
1553 BArr->ChangeValue(i) = Fusion(i);
1559 GeomLib::FuseIntervals(BArr->ChangeArray1(),
1560 UArr->ChangeArray1(),
1561 Fusion, Precision::PConfusion());
1562 BArr = new TColStd_HArray1OfReal(1, Fusion.Length());
1563 for(i = 1; i <= BArr->Length(); i++)
1564 BArr->ChangeValue(i) = Fusion(i);
1570 GeomLib::FuseIntervals(BArr->ChangeArray1(),
1571 VArr->ChangeArray1(),
1572 Fusion, Precision::PConfusion());
1573 BArr = new TColStd_HArray1OfReal(1, Fusion.Length());
1574 for(i = 1; i <= BArr->Length(); i++)
1575 BArr->ChangeValue(i) = Fusion(i);
1578 const_cast<ProjLib_CompProjectedCurve*>(this)->myTabInt = new TColStd_HArray1OfReal(1, BArr->Length());
1579 for(i = 1; i <= BArr->Length(); i++)
1580 myTabInt->ChangeValue(i) = BArr->Value(i);
1584 //=======================================================================
1587 //=======================================================================
1589 Handle(Adaptor2d_HCurve2d) ProjLib_CompProjectedCurve::Trim
1590 (const Standard_Real First,
1591 const Standard_Real Last,
1592 const Standard_Real Tol) const
1594 Handle(ProjLib_HCompProjectedCurve) HCS =
1595 new ProjLib_HCompProjectedCurve(*this);
1596 HCS->ChangeCurve2d().Load(mySurface);
1597 HCS->ChangeCurve2d().Load(myCurve->Trim(First,Last,Tol));
1601 //=======================================================================
1602 //function : GetType
1604 //=======================================================================
1606 GeomAbs_CurveType ProjLib_CompProjectedCurve::GetType() const
1608 return GeomAbs_OtherCurve;
1611 //=======================================================================
1612 //function : UpdateTripleByTrapCriteria
1614 //=======================================================================
1615 void ProjLib_CompProjectedCurve::UpdateTripleByTrapCriteria(gp_Pnt &thePoint) const
1617 Standard_Boolean isProblemsPossible = Standard_False;
1618 // Check possible traps cases:
1621 if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution)
1623 // Compute maximal deviation from 3D and choose the biggest one.
1624 Standard_Real aVRes = mySurface->VResolution(Precision::Confusion());
1625 Standard_Real aMaxTol = Max(Precision::PConfusion(), aVRes);
1627 if (Abs (thePoint.Z() - mySurface->FirstVParameter()) < aMaxTol ||
1628 Abs (thePoint.Z() - mySurface->LastVParameter() ) < aMaxTol )
1630 isProblemsPossible = Standard_True;
1634 // 27135 bug. Trap on degenerated edge.
1635 if (mySurface->GetType() == GeomAbs_Sphere &&
1636 (Abs (thePoint.Z() - mySurface->FirstVParameter()) < Precision::PConfusion() ||
1637 Abs (thePoint.Z() - mySurface->LastVParameter() ) < Precision::PConfusion() ||
1638 Abs (thePoint.Y() - mySurface->FirstUParameter()) < Precision::PConfusion() ||
1639 Abs (thePoint.Y() - mySurface->LastUParameter() ) < Precision::PConfusion() ))
1641 isProblemsPossible = Standard_True;
1644 if (!isProblemsPossible)
1648 InitialPoint(myCurve->Value(thePoint.X()), thePoint.X(), myCurve, mySurface, myTolU, myTolV, U, V);
1650 // Restore original position in case of period jump.
1651 if (mySurface->IsUPeriodic() &&
1652 Abs (Abs(U - thePoint.Y()) - mySurface->UPeriod()) < Precision::PConfusion())
1656 if (mySurface->IsVPeriodic() &&
1657 Abs (Abs(V - thePoint.Z()) - mySurface->VPeriod()) < Precision::PConfusion())