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.
17 #include <ProjLib_CompProjectedCurve.ixx>
18 #include <ProjLib_HCompProjectedCurve.hxx>
20 #include <gp_Mat2d.hxx>
21 #include <Extrema_ExtPS.hxx>
22 #include <Precision.hxx>
23 #include <Extrema_ExtCS.hxx>
24 #include <TColgp_HSequenceOfPnt.hxx>
25 #include <Extrema_GenLocateExtPS.hxx>
26 #include <Extrema_POnSurf.hxx>
27 #include <Extrema_POnCurv.hxx>
28 #include <ProjLib_PrjResolve.hxx>
29 #include <GeomAbs_CurveType.hxx>
30 #include <GeomLib.hxx>
32 #define FuncTol 1.e-10
34 #ifdef OCCT_DEBUG_CHRONO
35 #include <OSD_Timer.hxx>
37 static OSD_Chronometer chr_init_point, chr_dicho_bound;
39 Standard_EXPORT Standard_Real t_init_point, t_dicho_bound;
40 Standard_EXPORT Standard_Integer init_point_count, dicho_bound_count;
42 static void InitChron(OSD_Chronometer& ch)
48 static void ResultChron( OSD_Chronometer & ch, Standard_Real & time)
58 //=======================================================================
60 //purpose : computes first derivative of the projected curve
61 //=======================================================================
63 static void d1(const Standard_Real t,
64 const Standard_Real u,
65 const Standard_Real v,
67 const Handle(Adaptor3d_HCurve)& Curve,
68 const Handle(Adaptor3d_HSurface)& Surface)
71 gp_Vec DS1_u, DS1_v, DS2_u, DS2_uv, DS2_v, DC1_t;
72 Surface->D2(u, v, S, DS1_u, DS1_v, DS2_u, DS2_v, DS2_uv);
73 Curve->D1(t, C, DC1_t);
74 gp_Vec Ort(C, S);// Ort = S - C
76 gp_Vec2d dE_dt(-DC1_t*DS1_u, -DC1_t*DS1_v);
77 gp_XY dE_du(DS1_u*DS1_u + Ort*DS2_u,
78 DS1_u*DS1_v + Ort*DS2_uv);
79 gp_XY dE_dv(DS1_v*DS1_u + Ort*DS2_uv,
80 DS1_v*DS1_v + Ort*DS2_v);
82 Standard_Real det = dE_du.X()*dE_dv.Y() - dE_du.Y()*dE_dv.X();
83 if (fabs(det) < gp::Resolution()) Standard_ConstructionError::Raise();
85 gp_Mat2d M(gp_XY(dE_dv.Y()/det, -dE_du.Y()/det),
86 gp_XY(-dE_dv.X()/det, dE_du.X()/det));
88 V = - gp_Vec2d(gp_Vec2d(M.Row(1))*dE_dt, gp_Vec2d(M.Row(2))*dE_dt);
91 //=======================================================================
93 //purpose : computes second derivative of the projected curve
94 //=======================================================================
96 static void d2(const Standard_Real t,
97 const Standard_Real u,
98 const Standard_Real v,
99 gp_Vec2d& V1, gp_Vec2d& V2,
100 const Handle(Adaptor3d_HCurve)& Curve,
101 const Handle(Adaptor3d_HSurface)& Surface)
104 gp_Vec DS1_u, DS1_v, DS2_u, DS2_uv, DS2_v,
105 DS3_u, DS3_v, DS3_uuv, DS3_uvv,
107 Surface->D3(u, v, S, DS1_u, DS1_v, DS2_u, DS2_v, DS2_uv,
108 DS3_u, DS3_v, DS3_uuv, DS3_uvv);
109 Curve->D2(t, C, DC1_t, DC2_t);
112 gp_Vec2d dE_dt(-DC1_t*DS1_u, -DC1_t*DS1_v);
113 gp_XY dE_du(DS1_u*DS1_u + Ort*DS2_u,
114 DS1_u*DS1_v + Ort*DS2_uv);
115 gp_XY dE_dv(DS1_v*DS1_u + Ort*DS2_uv,
116 DS1_v*DS1_v + Ort*DS2_v);
118 Standard_Real det = dE_du.X()*dE_dv.Y() - dE_du.Y()*dE_dv.X();
119 if (fabs(det) < gp::Resolution()) Standard_ConstructionError::Raise();
121 gp_Mat2d M(gp_XY(dE_dv.Y()/det, -dE_du.Y()/det),
122 gp_XY(-dE_dv.X()/det, dE_du.X()/det));
125 V1 = - gp_Vec2d(gp_Vec2d(M.Row(1))*dE_dt, gp_Vec2d(M.Row(2))*dE_dt);
127 /* Second derivative */
129 // Computation of d2E_dt2 = S1
130 gp_Vec2d d2E_dt(-DC2_t*DS1_u, -DC2_t*DS1_v);
132 // Computation of 2*(d2E/dtdX)(dX/dt) = S2
133 gp_Vec2d d2E1_dtdX(-DC1_t*DS2_u,
135 gp_Vec2d d2E2_dtdX(-DC1_t*DS2_uv,
137 gp_Vec2d S2 = 2*gp_Vec2d(d2E1_dtdX*V1, d2E2_dtdX*V1);
139 // Computation of (d2E/dX2)*(dX/dt)2 = S3
141 // Row11 = (d2E1/du2, d2E1/dudv)
143 gp_Vec2d Row11(3*DS1_u*DS2_u + Ort*DS3_u,
144 tmp = 2*DS1_u*DS2_uv +
145 DS1_v*DS2_u + Ort*DS3_uuv);
147 // Row12 = (d2E1/dudv, d2E1/dv2)
148 gp_Vec2d Row12(tmp, DS2_v*DS1_u + 2*DS1_v*DS2_uv +
151 // Row21 = (d2E2/du2, d2E2/dudv)
152 gp_Vec2d Row21(DS2_u*DS1_v + 2*DS1_u*DS2_uv + Ort*DS3_uuv,
153 tmp = 2*DS2_uv*DS1_v + DS1_u*DS2_v + Ort*DS3_uvv);
155 // Row22 = (d2E2/duv, d2E2/dvdv)
156 gp_Vec2d Row22(tmp, 3*DS1_v*DS2_v + Ort*DS3_v);
158 gp_Vec2d S3(V1*gp_Vec2d(Row11*V1, Row12*V1),
159 V1*gp_Vec2d(Row21*V1, Row22*V1));
161 gp_Vec2d Sum = d2E_dt + S2 + S3;
163 V2 = - gp_Vec2d(gp_Vec2d(M.Row(1))*Sum, gp_Vec2d(M.Row(2))*Sum);
165 //=======================================================================
166 //function : d1CurveOnSurf
167 //purpose : computes first derivative of the 3d projected curve
168 //=======================================================================
171 static void d1CurvOnSurf(const Standard_Real t,
172 const Standard_Real u,
173 const Standard_Real v,
175 const Handle(Adaptor3d_HCurve)& Curve,
176 const Handle(Adaptor3d_HSurface)& Surface)
180 gp_Vec DS1_u, DS1_v, DS2_u, DS2_uv, DS2_v, DC1_t;
181 Surface->D2(u, v, S, DS1_u, DS1_v, DS2_u, DS2_v, DS2_uv);
182 Curve->D1(t, C, DC1_t);
183 gp_Vec Ort(C, S);// Ort = S - C
185 gp_Vec2d dE_dt(-DC1_t*DS1_u, -DC1_t*DS1_v);
186 gp_XY dE_du(DS1_u*DS1_u + Ort*DS2_u,
187 DS1_u*DS1_v + Ort*DS2_uv);
188 gp_XY dE_dv(DS1_v*DS1_u + Ort*DS2_uv,
189 DS1_v*DS1_v + Ort*DS2_v);
191 Standard_Real det = dE_du.X()*dE_dv.Y() - dE_du.Y()*dE_dv.X();
192 if (fabs(det) < gp::Resolution()) Standard_ConstructionError::Raise();
194 gp_Mat2d M(gp_XY(dE_dv.Y()/det, -dE_du.Y()/det),
195 gp_XY(-dE_dv.X()/det, dE_du.X()/det));
197 V2d = - gp_Vec2d(gp_Vec2d(M.Row(1))*dE_dt, gp_Vec2d(M.Row(2))*dE_dt);
199 V = DS1_u * V2d.X() + DS1_v * V2d.Y();
204 //=======================================================================
205 //function : d2CurveOnSurf
206 //purpose : computes second derivative of the 3D projected curve
207 //=======================================================================
209 static void d2CurvOnSurf(const Standard_Real t,
210 const Standard_Real u,
211 const Standard_Real v,
212 gp_Vec& V1 , gp_Vec& V2 ,
213 const Handle(Adaptor3d_HCurve)& Curve,
214 const Handle(Adaptor3d_HSurface)& Surface)
218 gp_Vec DS1_u, DS1_v, DS2_u, DS2_uv, DS2_v,
219 DS3_u, DS3_v, DS3_uuv, DS3_uvv,
221 Surface->D3(u, v, S, DS1_u, DS1_v, DS2_u, DS2_v, DS2_uv,
222 DS3_u, DS3_v, DS3_uuv, DS3_uvv);
223 Curve->D2(t, C, DC1_t, DC2_t);
226 gp_Vec2d dE_dt(-DC1_t*DS1_u, -DC1_t*DS1_v);
227 gp_XY dE_du(DS1_u*DS1_u + Ort*DS2_u,
228 DS1_u*DS1_v + Ort*DS2_uv);
229 gp_XY dE_dv(DS1_v*DS1_u + Ort*DS2_uv,
230 DS1_v*DS1_v + Ort*DS2_v);
232 Standard_Real det = dE_du.X()*dE_dv.Y() - dE_du.Y()*dE_dv.X();
233 if (fabs(det) < gp::Resolution()) Standard_ConstructionError::Raise();
235 gp_Mat2d M(gp_XY(dE_dv.Y()/det, -dE_du.Y()/det),
236 gp_XY(-dE_dv.X()/det, dE_du.X()/det));
239 V12d = - gp_Vec2d(gp_Vec2d(M.Row(1))*dE_dt, gp_Vec2d(M.Row(2))*dE_dt);
241 /* Second derivative */
243 // Computation of d2E_dt2 = S1
244 gp_Vec2d d2E_dt(-DC2_t*DS1_u, -DC2_t*DS1_v);
246 // Computation of 2*(d2E/dtdX)(dX/dt) = S2
247 gp_Vec2d d2E1_dtdX(-DC1_t*DS2_u,
249 gp_Vec2d d2E2_dtdX(-DC1_t*DS2_uv,
251 gp_Vec2d S2 = 2*gp_Vec2d(d2E1_dtdX*V12d, d2E2_dtdX*V12d);
253 // Computation of (d2E/dX2)*(dX/dt)2 = S3
255 // Row11 = (d2E1/du2, d2E1/dudv)
257 gp_Vec2d Row11(3*DS1_u*DS2_u + Ort*DS3_u,
258 tmp = 2*DS1_u*DS2_uv +
259 DS1_v*DS2_u + Ort*DS3_uuv);
261 // Row12 = (d2E1/dudv, d2E1/dv2)
262 gp_Vec2d Row12(tmp, DS2_v*DS1_u + 2*DS1_v*DS2_uv +
265 // Row21 = (d2E2/du2, d2E2/dudv)
266 gp_Vec2d Row21(DS2_u*DS1_v + 2*DS1_u*DS2_uv + Ort*DS3_uuv,
267 tmp = 2*DS2_uv*DS1_v + DS1_u*DS2_v + Ort*DS3_uvv);
269 // Row22 = (d2E2/duv, d2E2/dvdv)
270 gp_Vec2d Row22(tmp, 3*DS1_v*DS2_v + Ort*DS3_v);
272 gp_Vec2d S3(V12d*gp_Vec2d(Row11*V12d, Row12*V12d),
273 V12d*gp_Vec2d(Row21*V12d, Row22*V12d));
275 gp_Vec2d Sum = d2E_dt + S2 + S3;
277 V22d = - gp_Vec2d(gp_Vec2d(M.Row(1))*Sum, gp_Vec2d(M.Row(2))*Sum);
279 V1 = DS1_u * V12d.X() + DS1_v * V12d.Y();
280 V2 = DS2_u * V12d.X() *V12d.X()
282 + 2 * DS2_uv * V12d.X() *V12d.Y()
283 + DS2_v * V12d.Y() * V12d.Y()
287 //=======================================================================
288 //function : ExactBound
289 //purpose : computes exact boundary point
290 //=======================================================================
292 static Standard_Boolean ExactBound(gp_Pnt& Sol,
293 const Standard_Real NotSol,
294 const Standard_Real Tol,
295 const Standard_Real TolU,
296 const Standard_Real TolV,
297 const Handle(Adaptor3d_HCurve)& Curve,
298 const Handle(Adaptor3d_HSurface)& Surface)
300 Standard_Real U0, V0, t, t1, t2, FirstU, LastU, FirstV, LastV;
304 FirstU = Surface->FirstUParameter();
305 LastU = Surface->LastUParameter();
306 FirstV = Surface->FirstVParameter();
307 LastV = Surface->LastVParameter();
308 // Here we have to compute the boundary that projection is going to intersect
310 //these variables are to estimate which boundary has more apportunity
312 Standard_Real RU1, RU2, RV1, RV2;
313 d1(Sol.X(), U0, V0, D2d, Curve, Surface);
314 // Here we assume that D2d != (0, 0)
315 if(Abs(D2d.X()) < gp::Resolution())
317 RU1 = Precision::Infinite();
318 RU2 = Precision::Infinite();
322 else if(Abs(D2d.Y()) < gp::Resolution())
326 RV1 = Precision::Infinite();
327 RV2 = Precision::Infinite();
331 RU1 = gp_Pnt2d(U0, V0).
332 Distance(gp_Pnt2d(FirstU, V0 + (FirstU - U0)*D2d.Y()/D2d.X()));
333 RU2 = gp_Pnt2d(U0, V0).
334 Distance(gp_Pnt2d(LastU, V0 + (LastU - U0)*D2d.Y()/D2d.X()));
335 RV1 = gp_Pnt2d(U0, V0).
336 Distance(gp_Pnt2d(U0 + (FirstV - V0)*D2d.X()/D2d.Y(), FirstV));
337 RV2 = gp_Pnt2d(U0, V0).
338 Distance(gp_Pnt2d(U0 + (LastV - V0)*D2d.X()/D2d.Y(), LastV));
340 TColgp_SequenceOfPnt Seq;
341 Seq.Append(gp_Pnt(FirstU, RU1, 2));
342 Seq.Append(gp_Pnt(LastU, RU2, 2));
343 Seq.Append(gp_Pnt(FirstV, RV1, 3));
344 Seq.Append(gp_Pnt(LastV, RV2, 3));
345 Standard_Integer i, j;
346 for(i = 1; i <= 3; i++)
347 for(j = 1; j <= 4-i; j++)
348 if(Seq(j).Y() < Seq(j+1).Y())
351 swp = Seq.Value(j+1);
352 Seq.ChangeValue(j+1) = Seq.Value(j);
353 Seq.ChangeValue(j) = swp;
357 t1 = Min(Sol.X(), NotSol);
358 t2 = Max(Sol.X(), NotSol);
360 Standard_Boolean isDone = Standard_False;
361 while (!Seq.IsEmpty())
365 Seq.Remove(Seq.Length());
366 ProjLib_PrjResolve aPrjPS(Curve->Curve(),
368 Standard_Integer(P.Z()));
369 if(Standard_Integer(P.Z()) == 2)
371 aPrjPS.Perform(t, P.X(), V0, gp_Pnt2d(Tol, TolV),
372 gp_Pnt2d(t1, Surface->FirstVParameter()),
373 gp_Pnt2d(t2, Surface->LastVParameter()), FuncTol);
374 if(!aPrjPS.IsDone()) continue;
375 POnS = aPrjPS.Solution();
376 Sol = gp_Pnt(POnS.X(), P.X(), POnS.Y());
377 isDone = Standard_True;
382 aPrjPS.Perform(t, U0, P.X(), gp_Pnt2d(Tol, TolU),
383 gp_Pnt2d(t1, Surface->FirstUParameter()),
384 gp_Pnt2d(t2, Surface->LastUParameter()), FuncTol);
385 if(!aPrjPS.IsDone()) continue;
386 POnS = aPrjPS.Solution();
387 Sol = gp_Pnt(POnS.X(), POnS.Y(), P.X());
388 isDone = Standard_True;
396 //=======================================================================
397 //function : DichExactBound
398 //purpose : computes exact boundary point
399 //=======================================================================
401 static void DichExactBound(gp_Pnt& Sol,
402 const Standard_Real NotSol,
403 const Standard_Real Tol,
404 const Standard_Real TolU,
405 const Standard_Real TolV,
406 const Handle(Adaptor3d_HCurve)& Curve,
407 const Handle(Adaptor3d_HSurface)& Surface)
409 #ifdef OCCT_DEBUG_CHRONO
410 InitChron(chr_dicho_bound);
413 Standard_Real U0, V0, t;
417 ProjLib_PrjResolve aPrjPS(Curve->Curve(), Surface->Surface(), 1);
419 Standard_Real aNotSol = NotSol;
420 while (fabs(Sol.X() - aNotSol) > Tol)
422 t = (Sol.X() + aNotSol)/2;
423 aPrjPS.Perform(t, U0, V0, gp_Pnt2d(TolU, TolV),
424 gp_Pnt2d(Surface->FirstUParameter(),Surface->FirstVParameter()),
425 gp_Pnt2d(Surface->LastUParameter(),Surface->LastVParameter()),
426 FuncTol, Standard_True);
430 POnS = aPrjPS.Solution();
431 Sol = gp_Pnt(t, POnS.X(), POnS.Y());
437 #ifdef OCCT_DEBUG_CHRONO
438 ResultChron(chr_dicho_bound,t_dicho_bound);
443 //=======================================================================
444 //function : InitialPoint
446 //=======================================================================
448 static Standard_Boolean InitialPoint(const gp_Pnt& Point,
449 const Standard_Real t,
450 const Handle(Adaptor3d_HCurve)& C,
451 const Handle(Adaptor3d_HSurface)& S,
452 const Standard_Real TolU,
453 const Standard_Real TolV,
458 ProjLib_PrjResolve aPrjPS(C->Curve(), S->Surface(), 1);
459 Standard_Real ParU,ParV;
460 Extrema_ExtPS aExtPS;
461 aExtPS.Initialize(S->Surface(), S->FirstUParameter(),
462 S->LastUParameter(), S->FirstVParameter(),
463 S->LastVParameter(), TolU, TolV);
465 aExtPS.Perform(Point);
466 Standard_Integer argmin = 0;
467 if (aExtPS.IsDone() && aExtPS.NbExt())
469 Standard_Integer i, Nend;
470 // Search for the nearest solution which is also a normal projection
471 Nend = aExtPS.NbExt();
472 for(i = 1; i <= Nend; i++)
474 Extrema_POnSurf POnS = aExtPS.Point(i);
475 POnS.Parameter(ParU, ParV);
476 aPrjPS.Perform(t, ParU, ParV, gp_Pnt2d(TolU, TolV),
477 gp_Pnt2d(S->FirstUParameter(), S->FirstVParameter()),
478 gp_Pnt2d(S->LastUParameter(), S->LastVParameter()),
479 FuncTol, Standard_True);
481 if (argmin == 0 || aExtPS.SquareDistance(i) < aExtPS.SquareDistance(argmin)) argmin = i;
484 if( argmin == 0 ) return Standard_False;
487 Extrema_POnSurf POnS = aExtPS.Point(argmin);
488 POnS.Parameter(U, V);
489 return Standard_True;
493 //=======================================================================
494 //function : ProjLib_CompProjectedCurve
496 //=======================================================================
498 ProjLib_CompProjectedCurve::ProjLib_CompProjectedCurve()
506 //=======================================================================
507 //function : ProjLib_CompProjectedCurve
509 //=======================================================================
511 ProjLib_CompProjectedCurve::ProjLib_CompProjectedCurve
512 (const Handle(Adaptor3d_HSurface)& theSurface,
513 const Handle(Adaptor3d_HCurve)& theCurve,
514 const Standard_Real theTolU,
515 const Standard_Real theTolV)
516 : mySurface (theSurface),
519 mySequence(new ProjLib_HSequenceOfHSequenceOfPnt()),
527 //=======================================================================
528 //function : ProjLib_CompProjectedCurve
530 //=======================================================================
532 ProjLib_CompProjectedCurve::ProjLib_CompProjectedCurve
533 (const Handle(Adaptor3d_HSurface)& theSurface,
534 const Handle(Adaptor3d_HCurve)& theCurve,
535 const Standard_Real theTolU,
536 const Standard_Real theTolV,
537 const Standard_Real theMaxDist)
538 : mySurface (theSurface),
541 mySequence(new ProjLib_HSequenceOfHSequenceOfPnt()),
544 myMaxDist (theMaxDist)
549 //=======================================================================
552 //=======================================================================
554 void ProjLib_CompProjectedCurve::Init()
558 Standard_Real Tol;// Tolerance for ExactBound
559 Standard_Integer i, Nend = 0;
560 Standard_Boolean FromLastU=Standard_False;
562 //new part (to discard far solutions)
563 Standard_Real TolC = Precision::Confusion(), TolS = Precision::Confusion();
564 Extrema_ExtCS CExt(myCurve->Curve(),
565 mySurface->Surface(),
568 if (CExt.IsDone() && CExt.NbExt())
570 // Search for the minimum solution
573 // Avoid usage of extrema result that can be wrong for extrusion
574 mySurface->GetType() != GeomAbs_SurfaceOfExtrusion)
576 Standard_Real min_val2;
577 min_val2 = CExt.SquareDistance(1);
578 for(i = 2; i <= Nend; i++)
579 if (CExt.SquareDistance(i) < min_val2) min_val2 = CExt.SquareDistance(i);
580 if (min_val2 > myMaxDist * myMaxDist)
586 Standard_Real FirstU, LastU, Step, SearchStep, WalkStep, t;
588 FirstU = myCurve->FirstParameter();
589 LastU = myCurve->LastParameter();
590 const Standard_Real GlobalMinStep = 1.e-4;
591 //<GlobalMinStep> is sufficiently small to provide solving from initial point
592 //and, on the other hand, it is sufficiently large to avoid too close solutions.
593 const Standard_Real MinStep = 0.01*(LastU - FirstU),
594 MaxStep = 0.1*(LastU - FirstU);
595 SearchStep = 10*MinStep;
598 //Initialization of aPrjPS
599 Standard_Real Uinf = mySurface->FirstUParameter();
600 Standard_Real Usup = mySurface->LastUParameter();
601 Standard_Real Vinf = mySurface->FirstVParameter();
602 Standard_Real Vsup = mySurface->LastVParameter();
604 ProjLib_PrjResolve aPrjPS(myCurve->Curve(), mySurface->Surface(), 1);
607 Standard_Boolean new_part;
608 Standard_Real prevDeb=0.;
609 Standard_Boolean SameDeb=Standard_False;
612 gp_Pnt Triple, prevTriple;
617 //Search for the begining a new continuous part
618 //To avoid infinite computation in some difficult cases
619 new_part = Standard_False;
620 if(t > FirstU && Abs(t-prevDeb) <= Precision::PConfusion()) SameDeb=Standard_True;
621 while(t <= LastU && !new_part && !FromLastU && !SameDeb)
624 if (t == LastU) FromLastU=Standard_True;
625 Standard_Boolean initpoint=Standard_False;
626 Standard_Real U = 0., V = 0.;
628 Standard_Real ParT,ParU,ParV;
630 // Search an initpoint in the list of Extrema Curve-Surface
631 if(Nend != 0 && !CExt.IsParallel())
633 for (i=1;i<=Nend;i++)
637 CExt.Points(i,P1,P2);
639 P2.Parameter(ParU, ParV);
641 aPrjPS.Perform(ParT, ParU, ParV, gp_Pnt2d(myTolU, myTolV),
642 gp_Pnt2d(mySurface->FirstUParameter(),mySurface->FirstVParameter()),
643 gp_Pnt2d(mySurface->LastUParameter(), mySurface->LastVParameter()),
644 FuncTol, Standard_True);
645 if ( aPrjPS.IsDone() && P1.Parameter() > Max(FirstU,t-Step+Precision::PConfusion())
646 && P1.Parameter() <= t)
652 initpoint = Standard_True;
659 myCurve->D0(t,CPoint);
660 #ifdef OCCT_DEBUG_CHRONO
661 InitChron(chr_init_point);
663 initpoint=InitialPoint(CPoint, t,myCurve,mySurface, myTolU, myTolV, U, V);
664 #ifdef OCCT_DEBUG_CHRONO
665 ResultChron(chr_init_point,t_init_point);
671 // When U or V lie on surface joint in some cases we cannot use them
672 // as initial point for aPrjPS, so we switch them
675 if ((mySurface->IsUPeriodic() &&
676 Abs(Usup - Uinf - mySurface->UPeriod()) < Precision::Confusion()) ||
677 (mySurface->IsVPeriodic() &&
678 Abs(Vsup - Vinf - mySurface->VPeriod()) < Precision::Confusion()))
680 if((Abs(U - Uinf) < mySurface->UResolution(Precision::PConfusion())) &&
681 mySurface->IsUPeriodic())
683 d1(t, U, V, D, myCurve, mySurface);
684 if (D.X() < 0 ) U = Usup;
686 else if((Abs(U - Usup) < mySurface->UResolution(Precision::PConfusion())) &&
687 mySurface->IsUPeriodic())
689 d1(t, U, V, D, myCurve, mySurface);
690 if (D.X() > 0) U = Uinf;
693 if((Abs(V - Vinf) < mySurface->VResolution(Precision::PConfusion())) &&
694 mySurface->IsVPeriodic())
696 d1(t, U, V, D, myCurve, mySurface);
697 if (D.Y() < 0) V = Vsup;
699 else if((Abs(V - Vsup) <= mySurface->VResolution(Precision::PConfusion())) &&
700 mySurface->IsVPeriodic())
702 d1(t, U, V, D, myCurve, mySurface);
703 if (D.Y() > 0) V = Vinf;
710 // Here we are going to stop if the distance between projection and
711 // corresponding curve point is greater than myMaxDist
714 mySurface->D0(U, V, POnS);
715 d = CPoint.Distance(POnS);
723 Triple = gp_Pnt(t, U, V);
726 //Search for exact boundary point
727 Tol = Min(myTolU, myTolV);
729 d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface);
730 Tol /= Max(Abs(D.X()), Abs(D.Y()));
732 if(!ExactBound(Triple, t - Step, Tol,
733 myTolU, myTolV, myCurve, mySurface))
736 cout<<"There is a problem with ExactBound computation"<<endl;
738 DichExactBound(Triple, t - Step, Tol, myTolU, myTolV,
742 new_part = Standard_True;
746 if(t == LastU) break;
755 if (!new_part) break;
758 //We have found a new continuous part
759 Handle(TColgp_HSequenceOfPnt) hSeq = new TColgp_HSequenceOfPnt();
760 mySequence->Append(hSeq);
762 mySequence->Value(myNbCurves)->Append(Triple);
765 if (Triple.X() == LastU) break;//return;
767 //Computation of WalkStep
769 Standard_Real MagnD1, MagnD2;
770 d2CurvOnSurf(Triple.X(), Triple.Y(), Triple.Z(), D1, D2, myCurve, mySurface);
771 MagnD1 = D1.Magnitude();
772 MagnD2 = D2.Magnitude();
773 if(MagnD2 < Precision::Confusion()) WalkStep = MaxStep;
774 else WalkStep = Min(MaxStep, Max(MinStep, 0.1*MagnD1/MagnD2));
778 t = Triple.X() + Step;
779 if (t > LastU) t = LastU;
780 Standard_Real prevStep = Step;
781 Standard_Real U0, V0;
782 gp_Pnt2d aLowBorder(mySurface->FirstUParameter(),mySurface->FirstVParameter());
783 gp_Pnt2d aUppBorder(mySurface->LastUParameter(), mySurface->LastVParameter());
784 gp_Pnt2d aTol(myTolU, myTolV);
785 //Here we are trying to prolong continuous part
786 while (t <= LastU && new_part)
789 U0 = Triple.Y() + (Step / prevStep) * (Triple.Y() - prevTriple.Y());
790 V0 = Triple.Z() + (Step / prevStep) * (Triple.Z() - prevTriple.Z());
791 // adjust U0 to be in [mySurface->FirstUParameter(),mySurface->LastUParameter()]
792 U0 = Min(Max(U0, aLowBorder.X()), aUppBorder.X());
793 // adjust V0 to be in [mySurface->FirstVParameter(),mySurface->LastVParameter()]
794 V0 = Min(Max(V0, aLowBorder.Y()), aUppBorder.Y());
797 aPrjPS.Perform(t, U0, V0, aTol,
798 aLowBorder, aUppBorder, FuncTol, Standard_True);
801 if (Step <= GlobalMinStep)
803 //Search for exact boundary point
804 Tol = Min(myTolU, myTolV);
806 d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface);
807 Tol /= Max(Abs(D.X()), Abs(D.Y()));
809 if(!ExactBound(Triple, t, Tol, myTolU, myTolV,
813 cout<<"There is a problem with ExactBound computation"<<endl;
815 DichExactBound(Triple, t, Tol, myTolU, myTolV,
819 if((Triple.X() - mySequence->Value(myNbCurves)->Value(mySequence->Value(myNbCurves)->Length()).X()) > 1.e-10)
820 mySequence->Value(myNbCurves)->Append(Triple);
821 if((LastU - Triple.X()) < Tol) {t = LastU + 1; break;}//return;
824 t = Triple.X() + Step;
825 if (t > (LastU-MinStep/2) )
830 new_part = Standard_False;
835 Standard_Real SaveStep = Step;
837 t = Triple .X() + Step;
838 if (t > (LastU-MinStep/4) )
841 if (Abs(Step - SaveStep) <= Precision::PConfusion())
842 Step = GlobalMinStep; //to avoid looping
852 Triple = gp_Pnt(t, aPrjPS.Solution().X(), aPrjPS.Solution().Y());
854 if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution &&
855 (Abs (Triple.Z() - mySurface->FirstVParameter()) < Precision::Confusion() ||
856 Abs (Triple.Z() - mySurface->LastVParameter() ) < Precision::Confusion() ))
858 // Go out from possible attraktor.
861 InitialPoint(myCurve->Value(t), t, myCurve, mySurface, myTolU, myTolV, U, V);
862 if (Abs (Abs(U - Triple.Y()) - mySurface->UPeriod()) < Precision::Confusion())
864 // Handle period jump.
871 if((Triple.X() - mySequence->Value(myNbCurves)->Value(mySequence->Value(myNbCurves)->Length()).X()) > 1.e-10)
872 mySequence->Value(myNbCurves)->Append(Triple);
873 if (t == LastU) {t = LastU + 1; break;}//return;
875 //Computation of WalkStep
876 d2CurvOnSurf(Triple.X(), Triple.Y(), Triple.Z(), D1, D2, myCurve, mySurface);
877 MagnD1 = D1.Magnitude();
878 MagnD2 = D2.Magnitude();
879 if(MagnD2 < Precision::Confusion() ) WalkStep = MaxStep;
880 else WalkStep = Min(MaxStep, Max(MinStep, 0.1*MagnD1/MagnD2));
884 if (t > (LastU-MinStep/2) )
892 // Sequence postproceeding
895 // 1. Removing poor parts
896 Standard_Integer NbPart=myNbCurves;
897 Standard_Integer ipart=1;
898 for(i = 1; i <= NbPart; i++) {
899 // Standard_Integer NbPoints = mySequence->Value(i)->Length();
900 if(mySequence->Value(ipart)->Length() < 2) {
901 mySequence->Remove(ipart);
907 if(myNbCurves == 0) return;
909 // 2. Removing common parts of bounds
910 for(i = 1; i < myNbCurves; i++)
912 if(mySequence->Value(i)->Value(mySequence->Value(i)->Length()).X() >=
913 mySequence->Value(i+1)->Value(1).X())
914 mySequence->ChangeValue(i+1)->ChangeValue(1).SetX(mySequence->Value(i)->Value(mySequence->Value(i)->Length()).X() + 1.e-12);
917 // 3. Computation of the maximum distance from each part of curve to surface
919 myMaxDistance = new TColStd_HArray1OfReal(1, myNbCurves);
920 myMaxDistance->Init(0);
921 for(i = 1; i <= myNbCurves; i++)
922 for(j = 1; j <= mySequence->Value(i)->Length(); j++)
924 gp_Pnt POnC, POnS, Triple;
925 Standard_Real Distance;
926 Triple = mySequence->Value(i)->Value(j);
927 myCurve->D0(Triple.X(), POnC);
928 mySurface->D0(Triple.Y(), Triple.Z(), POnS);
929 Distance = POnC.Distance(POnS);
930 if (myMaxDistance->Value(i) < Distance)
931 myMaxDistance->ChangeValue(i) = Distance;
935 // 4. Check the projection to be a single point
937 gp_Pnt2d Pmoy, Pcurr, P;
938 Standard_Real AveU, AveV;
939 mySnglPnts = new TColStd_HArray1OfBoolean(1, myNbCurves);
940 for(i = 1; i <= myNbCurves; i++) mySnglPnts->SetValue(i, Standard_True);
942 for(i = 1; i <= myNbCurves; i++)
944 //compute an average U and V
946 for(j = 1, AveU = 0., AveV = 0.; j <= mySequence->Value(i)->Length(); j++)
948 AveU += mySequence->Value(i)->Value(j).Y();
949 AveV += mySequence->Value(i)->Value(j).Z();
951 AveU /= mySequence->Value(i)->Length();
952 AveV /= mySequence->Value(i)->Length();
954 Pmoy.SetCoord(AveU,AveV);
955 for(j = 1; j <= mySequence->Value(i)->Length(); j++)
958 gp_Pnt2d(mySequence->Value(i)->Value(j).Y(), mySequence->Value(i)->Value(j).Z());
959 if (Pcurr.Distance(Pmoy) > ((myTolU < myTolV) ? myTolV : myTolU))
961 mySnglPnts->SetValue(i, Standard_False);
967 // 5. Check the projection to be an isoparametric curve of the surface
969 myUIso = new TColStd_HArray1OfBoolean(1, myNbCurves);
970 for(i = 1; i <= myNbCurves; i++) myUIso->SetValue(i, Standard_True);
972 myVIso = new TColStd_HArray1OfBoolean(1, myNbCurves);
973 for(i = 1; i <= myNbCurves; i++) myVIso->SetValue(i, Standard_True);
975 for(i = 1; i <= myNbCurves; i++) {
976 if (IsSinglePnt(i, P)|| mySequence->Value(i)->Length() <=2) {
977 myUIso->SetValue(i, Standard_False);
978 myVIso->SetValue(i, Standard_False);
982 // new test for isoparametrics
984 if ( mySequence->Value(i)->Length() > 2) {
985 //compute an average U and V
987 for(j = 1, AveU = 0., AveV = 0.; j <= mySequence->Value(i)->Length(); j++) {
988 AveU += mySequence->Value(i)->Value(j).Y();
989 AveV += mySequence->Value(i)->Value(j).Z();
991 AveU /= mySequence->Value(i)->Length();
992 AveV /= mySequence->Value(i)->Length();
994 // is i-part U-isoparametric ?
995 for(j = 1; j <= mySequence->Value(i)->Length(); j++)
997 if(Abs(mySequence->Value(i)->Value(j).Y() - AveU) > myTolU)
999 myUIso->SetValue(i, Standard_False);
1004 // is i-part V-isoparametric ?
1005 for(j = 1; j <= mySequence->Value(i)->Length(); j++)
1007 if(Abs(mySequence->Value(i)->Value(j).Z() - AveV) > myTolV)
1009 myVIso->SetValue(i, Standard_False);
1017 //=======================================================================
1020 //=======================================================================
1022 void ProjLib_CompProjectedCurve::Load(const Handle(Adaptor3d_HSurface)& S)
1027 //=======================================================================
1030 //=======================================================================
1032 void ProjLib_CompProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C)
1037 //=======================================================================
1038 //function : GetSurface
1040 //=======================================================================
1042 const Handle(Adaptor3d_HSurface)& ProjLib_CompProjectedCurve::GetSurface() const
1048 //=======================================================================
1049 //function : GetCurve
1051 //=======================================================================
1053 const Handle(Adaptor3d_HCurve)& ProjLib_CompProjectedCurve::GetCurve() const
1058 //=======================================================================
1059 //function : GetTolerance
1061 //=======================================================================
1063 void ProjLib_CompProjectedCurve::GetTolerance(Standard_Real& TolU,
1064 Standard_Real& TolV) const
1070 //=======================================================================
1071 //function : NbCurves
1073 //=======================================================================
1075 Standard_Integer ProjLib_CompProjectedCurve::NbCurves() const
1079 //=======================================================================
1082 //=======================================================================
1084 void ProjLib_CompProjectedCurve::Bounds(const Standard_Integer Index,
1085 Standard_Real& Udeb,
1086 Standard_Real& Ufin) const
1088 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1089 Udeb = mySequence->Value(Index)->Value(1).X();
1090 Ufin = mySequence->Value(Index)->Value(mySequence->Value(Index)->Length()).X();
1092 //=======================================================================
1093 //function : IsSinglePnt
1095 //=======================================================================
1097 Standard_Boolean ProjLib_CompProjectedCurve::IsSinglePnt(const Standard_Integer Index, gp_Pnt2d& P) const
1099 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1100 P = gp_Pnt2d(mySequence->Value(Index)->Value(1).Y(), mySequence->Value(Index)->Value(1).Z());
1101 return mySnglPnts->Value(Index);
1104 //=======================================================================
1107 //=======================================================================
1109 Standard_Boolean ProjLib_CompProjectedCurve::IsUIso(const Standard_Integer Index, Standard_Real& U) const
1111 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1112 U = mySequence->Value(Index)->Value(1).Y();
1113 return myUIso->Value(Index);
1115 //=======================================================================
1118 //=======================================================================
1120 Standard_Boolean ProjLib_CompProjectedCurve::IsVIso(const Standard_Integer Index, Standard_Real& V) const
1122 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1123 V = mySequence->Value(Index)->Value(1).Z();
1124 return myVIso->Value(Index);
1126 //=======================================================================
1129 //=======================================================================
1131 gp_Pnt2d ProjLib_CompProjectedCurve::Value(const Standard_Real t) const
1137 //=======================================================================
1140 //=======================================================================
1142 void ProjLib_CompProjectedCurve::D0(const Standard_Real U,gp_Pnt2d& P) const
1144 Standard_Integer i, j;
1145 Standard_Real Udeb, Ufin;
1146 Standard_Boolean found = Standard_False;
1148 for(i = 1; i <= myNbCurves; i++)
1150 Bounds(i, Udeb, Ufin);
1151 if (U >= Udeb && U <= Ufin)
1153 found = Standard_True;
1157 if (!found) Standard_DomainError::Raise("ProjLib_CompProjectedCurve::D0");
1159 Standard_Real U0, V0;
1161 Standard_Integer End = mySequence->Value(i)->Length();
1162 for(j = 1; j < End; j++)
1163 if ((U >= mySequence->Value(i)->Value(j).X()) && (U <= mySequence->Value(i)->Value(j + 1).X())) break;
1165 // U0 = mySequence->Value(i)->Value(j).Y();
1166 // V0 = mySequence->Value(i)->Value(j).Z();
1168 // Cubic Interpolation
1169 if(mySequence->Value(i)->Length() < 4 ||
1170 (Abs(U-mySequence->Value(i)->Value(j).X()) <= Precision::PConfusion()) )
1172 U0 = mySequence->Value(i)->Value(j).Y();
1173 V0 = mySequence->Value(i)->Value(j).Z();
1175 else if (Abs(U-mySequence->Value(i)->Value(j+1).X())
1176 <= Precision::PConfusion())
1178 U0 = mySequence->Value(i)->Value(j+1).Y();
1179 V0 = mySequence->Value(i)->Value(j+1).Z();
1184 if (j > mySequence->Value(i)->Length() - 2)
1185 j = mySequence->Value(i)->Length() - 2;
1187 gp_Vec2d I1, I2, I3, I21, I22, I31, Y1, Y2, Y3, Y4, Res;
1188 Standard_Real X1, X2, X3, X4;
1190 X1 = mySequence->Value(i)->Value(j - 1).X();
1191 X2 = mySequence->Value(i)->Value(j).X();
1192 X3 = mySequence->Value(i)->Value(j + 1).X();
1193 X4 = mySequence->Value(i)->Value(j + 2).X();
1195 Y1 = gp_Vec2d(mySequence->Value(i)->Value(j - 1).Y(),
1196 mySequence->Value(i)->Value(j - 1).Z());
1197 Y2 = gp_Vec2d(mySequence->Value(i)->Value(j).Y(),
1198 mySequence->Value(i)->Value(j).Z());
1199 Y3 = gp_Vec2d(mySequence->Value(i)->Value(j + 1).Y(),
1200 mySequence->Value(i)->Value(j + 1).Z());
1201 Y4 = gp_Vec2d(mySequence->Value(i)->Value(j + 2).Y(),
1202 mySequence->Value(i)->Value(j + 2).Z());
1204 I1 = (Y1 - Y2)/(X1 - X2);
1205 I2 = (Y2 - Y3)/(X2 - X3);
1206 I3 = (Y3 - Y4)/(X3 - X4);
1208 I21 = (I1 - I2)/(X1 - X3);
1209 I22 = (I2 - I3)/(X2 - X4);
1211 I31 = (I21 - I22)/(X1 - X4);
1213 Res = Y1 + (U - X1)*(I1 + (U - X2)*(I21 + (U - X3)*I31));
1218 if(U0 < mySurface->FirstUParameter()) U0 = mySurface->FirstUParameter();
1219 else if(U0 > mySurface->LastUParameter()) U0 = mySurface->LastUParameter();
1221 if(V0 < mySurface->FirstVParameter()) V0 = mySurface->FirstVParameter();
1222 else if(V0 > mySurface->LastVParameter()) V0 = mySurface->LastVParameter();
1224 //End of cubic interpolation
1226 ProjLib_PrjResolve aPrjPS(myCurve->Curve(), mySurface->Surface(), 1);
1227 aPrjPS.Perform(U, U0, V0, gp_Pnt2d(myTolU, myTolV),
1228 gp_Pnt2d(mySurface->FirstUParameter(), mySurface->FirstVParameter()),
1229 gp_Pnt2d(mySurface->LastUParameter(), mySurface->LastVParameter()));
1230 if (aPrjPS.IsDone())
1231 P = aPrjPS.Solution();
1234 gp_Pnt thePoint = myCurve->Value(U);
1235 Extrema_ExtPS aExtPS(thePoint, mySurface->Surface(), myTolU, myTolV);
1236 if (aExtPS.IsDone() && aExtPS.NbExt())
1238 Standard_Integer i, Nend, imin = 1;
1239 // Search for the nearest solution which is also a normal projection
1240 Nend = aExtPS.NbExt();
1241 for(i = 2; i <= Nend; i++)
1242 if (aExtPS.SquareDistance(i) < aExtPS.SquareDistance(imin))
1244 const Extrema_POnSurf& POnS = aExtPS.Point(imin);
1245 Standard_Real ParU,ParV;
1246 POnS.Parameter(ParU, ParV);
1247 P.SetCoord(ParU, ParV);
1253 //=======================================================================
1256 //=======================================================================
1258 void ProjLib_CompProjectedCurve::D1(const Standard_Real t,
1266 d1(t, u, v, V, myCurve, mySurface);
1268 //=======================================================================
1271 //=======================================================================
1273 void ProjLib_CompProjectedCurve::D2(const Standard_Real t,
1282 d2(t, u, v, V1, V2, myCurve, mySurface);
1284 //=======================================================================
1287 //=======================================================================
1289 gp_Vec2d ProjLib_CompProjectedCurve::DN(const Standard_Real t,
1290 const Standard_Integer N) const
1292 if (N < 1 ) Standard_OutOfRange::Raise("ProjLib_CompProjectedCurve : N must be greater than 0");
1308 Standard_NotImplemented::Raise("ProjLib_CompProjectedCurve::DN");
1312 //=======================================================================
1313 //function : GetSequence
1315 //=======================================================================
1317 const Handle(ProjLib_HSequenceOfHSequenceOfPnt)& ProjLib_CompProjectedCurve::GetSequence() const
1321 //=======================================================================
1322 //function : FirstParameter
1324 //=======================================================================
1326 Standard_Real ProjLib_CompProjectedCurve::FirstParameter() const
1328 return myCurve->FirstParameter();
1331 //=======================================================================
1332 //function : LastParameter
1334 //=======================================================================
1336 Standard_Real ProjLib_CompProjectedCurve::LastParameter() const
1338 return myCurve->LastParameter();
1341 //=======================================================================
1342 //function : MaxDistance
1344 //=======================================================================
1346 Standard_Real ProjLib_CompProjectedCurve::MaxDistance(const Standard_Integer Index) const
1348 if(Index < 1 || Index > myNbCurves) Standard_NoSuchObject::Raise();
1349 return myMaxDistance->Value(Index);
1352 //=======================================================================
1353 //function : NbIntervals
1355 //=======================================================================
1357 Standard_Integer ProjLib_CompProjectedCurve::NbIntervals(const GeomAbs_Shape S) const
1359 const_cast<ProjLib_CompProjectedCurve*>(this)->myTabInt.Nullify();
1361 return myTabInt->Length() - 1;
1364 //=======================================================================
1365 //function : Intervals
1367 //=======================================================================
1369 void ProjLib_CompProjectedCurve::Intervals(TColStd_Array1OfReal& T,const GeomAbs_Shape S) const
1371 if (myTabInt.IsNull()) BuildIntervals (S);
1372 T = myTabInt->Array1();
1375 //=======================================================================
1376 //function : BuildIntervals
1378 //=======================================================================
1380 void ProjLib_CompProjectedCurve::BuildIntervals(const GeomAbs_Shape S) const
1382 GeomAbs_Shape SforS = GeomAbs_CN;
1400 Standard_OutOfRange::Raise();
1402 Standard_Integer i, j, k;
1403 Standard_Integer NbIntCur = myCurve->NbIntervals(S);
1404 Standard_Integer NbIntSurU = mySurface->NbUIntervals(SforS);
1405 Standard_Integer NbIntSurV = mySurface->NbVIntervals(SforS);
1407 TColStd_Array1OfReal CutPntsT(1, NbIntCur+1);
1408 TColStd_Array1OfReal CutPntsU(1, NbIntSurU+1);
1409 TColStd_Array1OfReal CutPntsV(1, NbIntSurV+1);
1411 myCurve->Intervals(CutPntsT, S);
1412 mySurface->UIntervals(CutPntsU, SforS);
1413 mySurface->VIntervals(CutPntsV, SforS);
1415 Standard_Real Tl, Tr, Ul, Ur, Vl, Vr, Tol;
1417 Handle(TColStd_HArray1OfReal) BArr = NULL,
1422 // proccessing projection bounds
1423 BArr = new TColStd_HArray1OfReal(1, 2*myNbCurves);
1424 for(i = 1; i <= myNbCurves; i++)
1425 Bounds(i, BArr->ChangeValue(2*i - 1), BArr->ChangeValue(2*i));
1427 // proccessing curve discontinuities
1429 CArr = new TColStd_HArray1OfReal(1, NbIntCur - 1);
1430 for(i = 1; i <= CArr->Length(); i++)
1431 CArr->ChangeValue(i) = CutPntsT(i + 1);
1434 // proccessing U-surface discontinuities
1435 TColStd_SequenceOfReal TUdisc;
1437 for(k = 2; k <= NbIntSurU; k++) {
1438 // cout<<"CutPntsU("<<k<<") = "<<CutPntsU(k)<<endl;
1439 for(i = 1; i <= myNbCurves; i++)
1440 for(j = 1; j < mySequence->Value(i)->Length(); j++) {
1441 Ul = mySequence->Value(i)->Value(j).Y();
1442 Ur = mySequence->Value(i)->Value(j + 1).Y();
1444 if(Abs(Ul - CutPntsU(k)) <= myTolU)
1445 TUdisc.Append(mySequence->Value(i)->Value(j).X());
1446 else if(Abs(Ur - CutPntsU(k)) <= myTolU)
1447 TUdisc.Append(mySequence->Value(i)->Value(j + 1).X());
1448 else if((Ul < CutPntsU(k) && CutPntsU(k) < Ur) ||
1449 (Ur < CutPntsU(k) && CutPntsU(k) < Ul))
1452 V = (mySequence->Value(i)->Value(j).Z()
1453 + mySequence->Value(i)->Value(j +1).Z())/2;
1454 ProjLib_PrjResolve Solver(myCurve->Curve(), mySurface->Surface(), 2);
1458 Triple = mySequence->Value(i)->Value(j);
1459 d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface);
1460 if (Abs(D.X()) < Precision::Confusion())
1463 Tol = Min(myTolU, myTolU / Abs(D.X()));
1465 Tl = mySequence->Value(i)->Value(j).X();
1466 Tr = mySequence->Value(i)->Value(j + 1).X();
1468 Solver.Perform((Tl + Tr)/2, CutPntsU(k), V,
1469 gp_Pnt2d(Tol, myTolV),
1470 gp_Pnt2d(Tl, mySurface->FirstVParameter()),
1471 gp_Pnt2d(Tr, mySurface->LastVParameter()));
1475 TUdisc.Append(Solver.Solution().X());
1480 for(i = 2; i <= TUdisc.Length(); i++)
1481 if(TUdisc(i) - TUdisc(i-1) < Precision::PConfusion())
1486 UArr = new TColStd_HArray1OfReal(1, TUdisc.Length());
1487 for(i = 1; i <= UArr->Length(); i++)
1488 UArr->ChangeValue(i) = TUdisc(i);
1490 // proccessing V-surface discontinuities
1491 TColStd_SequenceOfReal TVdisc;
1493 for(k = 2; k <= NbIntSurV; k++)
1494 for(i = 1; i <= myNbCurves; i++)
1496 // cout<<"CutPntsV("<<k<<") = "<<CutPntsV(k)<<endl;
1497 for(j = 1; j < mySequence->Value(i)->Length(); j++) {
1499 Vl = mySequence->Value(i)->Value(j).Z();
1500 Vr = mySequence->Value(i)->Value(j + 1).Z();
1502 if(Abs(Vl - CutPntsV(k)) <= myTolV)
1503 TVdisc.Append(mySequence->Value(i)->Value(j).X());
1504 else if (Abs(Vr - CutPntsV(k)) <= myTolV)
1505 TVdisc.Append(mySequence->Value(i)->Value(j + 1).X());
1506 else if((Vl < CutPntsV(k) && CutPntsV(k) < Vr) ||
1507 (Vr < CutPntsV(k) && CutPntsV(k) < Vl))
1510 U = (mySequence->Value(i)->Value(j).Y()
1511 + mySequence->Value(i)->Value(j +1).Y())/2;
1512 ProjLib_PrjResolve Solver(myCurve->Curve(), mySurface->Surface(), 3);
1516 Triple = mySequence->Value(i)->Value(j);
1517 d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface);
1518 if (Abs(D.Y()) < Precision::Confusion())
1521 Tol = Min(myTolV, myTolV / Abs(D.Y()));
1523 Tl = mySequence->Value(i)->Value(j).X();
1524 Tr = mySequence->Value(i)->Value(j + 1).X();
1526 Solver.Perform((Tl + Tr)/2, U, CutPntsV(k),
1527 gp_Pnt2d(Tol, myTolV),
1528 gp_Pnt2d(Tl, mySurface->FirstUParameter()),
1529 gp_Pnt2d(Tr, mySurface->LastUParameter()));
1533 TVdisc.Append(Solver.Solution().X());
1538 for(i = 2; i <= TVdisc.Length(); i++)
1539 if(TVdisc(i) - TVdisc(i-1) < Precision::PConfusion())
1544 VArr = new TColStd_HArray1OfReal(1, TVdisc.Length());
1545 for(i = 1; i <= VArr->Length(); i++)
1546 VArr->ChangeValue(i) = TVdisc(i);
1550 TColStd_SequenceOfReal Fusion;
1553 GeomLib::FuseIntervals(BArr->ChangeArray1(),
1554 CArr->ChangeArray1(),
1555 Fusion, Precision::PConfusion());
1556 BArr = new TColStd_HArray1OfReal(1, Fusion.Length());
1557 for(i = 1; i <= BArr->Length(); i++)
1558 BArr->ChangeValue(i) = Fusion(i);
1564 GeomLib::FuseIntervals(BArr->ChangeArray1(),
1565 UArr->ChangeArray1(),
1566 Fusion, Precision::PConfusion());
1567 BArr = new TColStd_HArray1OfReal(1, Fusion.Length());
1568 for(i = 1; i <= BArr->Length(); i++)
1569 BArr->ChangeValue(i) = Fusion(i);
1575 GeomLib::FuseIntervals(BArr->ChangeArray1(),
1576 VArr->ChangeArray1(),
1577 Fusion, Precision::PConfusion());
1578 BArr = new TColStd_HArray1OfReal(1, Fusion.Length());
1579 for(i = 1; i <= BArr->Length(); i++)
1580 BArr->ChangeValue(i) = Fusion(i);
1583 const_cast<ProjLib_CompProjectedCurve*>(this)->myTabInt = new TColStd_HArray1OfReal(1, BArr->Length());
1584 for(i = 1; i <= BArr->Length(); i++)
1585 myTabInt->ChangeValue(i) = BArr->Value(i);
1589 //=======================================================================
1592 //=======================================================================
1594 Handle(Adaptor2d_HCurve2d) ProjLib_CompProjectedCurve::Trim
1595 (const Standard_Real First,
1596 const Standard_Real Last,
1597 const Standard_Real Tol) const
1599 Handle(ProjLib_HCompProjectedCurve) HCS =
1600 new ProjLib_HCompProjectedCurve(*this);
1601 HCS->ChangeCurve2d().Load(mySurface);
1602 HCS->ChangeCurve2d().Load(myCurve->Trim(First,Last,Tol));
1606 //=======================================================================
1607 //function : GetType
1609 //=======================================================================
1611 GeomAbs_CurveType ProjLib_CompProjectedCurve::GetType() const
1613 return GeomAbs_OtherCurve;