1 // Created on: 1992-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1992-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 <IntPatch_ImpPrmIntersection.hxx>
19 #include <Adaptor3d_Surface.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
23 #include <IntPatch_ArcFunction.hxx>
24 #include <IntPatch_PointLine.hxx>
25 #include <IntPatch_RLine.hxx>
26 #include <IntPatch_RstInt.hxx>
27 #include <IntPatch_SpecialPoints.hxx>
28 #include <IntPatch_TheIWLineOfTheIWalking.hxx>
29 #include <IntPatch_TheIWalking.hxx>
30 #include <IntPatch_TheSurfFunction.hxx>
31 #include <IntPatch_WLine.hxx>
32 #include <IntSurf.hxx>
33 #include <IntSurf_Quadric.hxx>
34 #include <IntSurf_QuadricTool.hxx>
35 #include <IntSurf_SequenceOfPathPoint.hxx>
36 #include <TColStd_Array1OfInteger.hxx>
37 #include <TopAbs_Orientation.hxx>
38 #include <TopTrans_CurveTransition.hxx>
39 #include <math_Matrix.hxx>
40 #include <math_Vector.hxx>
43 #define No_Standard_RangeError
44 #define No_Standard_OutOfRange
47 static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLine,
48 const Standard_Boolean IsReversed,
49 const IntSurf_Quadric& theQuad,
50 const Handle(Adaptor3d_TopolTool)& thePDomain,
51 const Handle(Adaptor3d_Surface)& theQSurf,
52 const Handle(Adaptor3d_Surface)& theOtherSurf,
53 const Standard_Real theArcTol,
54 const Standard_Real theTolTang,
55 IntPatch_SequenceOfLine& theLines);
57 void ComputeTangency (const IntPatch_TheSOnBounds& solrst,
58 IntSurf_SequenceOfPathPoint& seqpdep,
59 const Handle(Adaptor3d_TopolTool)& Domain,
60 IntPatch_TheSurfFunction& Func,
61 const Handle(Adaptor3d_Surface)& PSurf,
62 TColStd_Array1OfInteger& Destination);
64 void Recadre(const Standard_Boolean ,
65 GeomAbs_SurfaceType typeS1,
66 GeomAbs_SurfaceType typeS2,
68 const Handle(IntPatch_TheIWLineOfTheIWalking)& iwline,
69 Standard_Integer Param,
76 Standard_Boolean IsCoincide(IntPatch_TheSurfFunction& theFunc,
77 const Handle(IntPatch_PointLine)& theLine,
78 const Handle(Adaptor2d_Curve2d)& theArc,
79 const Standard_Boolean isTheSurface1Using,
80 const Standard_Real theToler3D,
81 const Standard_Real theToler2D,
82 const Standard_Real thePeriod);
85 Standard_Real GetLocalStep(const Handle(Adaptor3d_Surface)& theSurf,
86 const Standard_Real theStep);
89 //=======================================================================
90 //function : IsSeamOrPole
92 //=======================================================================
93 static IntPatch_SpecPntType IsSeamOrPole(const Handle(Adaptor3d_Surface)& theQSurf,
94 const Handle(IntSurf_LineOn2S)& theLine,
95 const Standard_Boolean IsReversed,
96 const Standard_Integer theRefIndex,
97 const Standard_Real theTol3D,
98 const Standard_Real theDeltaMax)
100 if((theRefIndex < 1) || (theRefIndex >= theLine->NbPoints()))
101 return IntPatch_SPntNone;
103 //Parameters on Quadric and on parametric for reference point
104 Standard_Real aUQRef, aVQRef, aUPRef, aVPRef;
105 Standard_Real aUQNext, aVQNext, aUPNext, aVPNext;
107 const gp_Pnt &aP3d = theLine->Value(theRefIndex + 1).Value();
111 theLine->Value(theRefIndex).Parameters (aUPRef, aVPRef, aUQRef, aVQRef);
112 theLine->Value(theRefIndex+1).Parameters(aUPNext, aVPNext, aUQNext, aVQNext);
116 theLine->Value(theRefIndex).Parameters (aUQRef, aVQRef, aUPRef, aVPRef);
117 theLine->Value(theRefIndex+1).Parameters(aUQNext, aVQNext, aUPNext, aVPNext);
120 const GeomAbs_SurfaceType aType = theQSurf->GetType();
122 if ((aType == GeomAbs_Cone) &&
123 (theQSurf->Cone().Apex().SquareDistance(aP3d) < theTol3D*theTol3D))
125 return IntPatch_SPntPoleSeamU;
127 else if (aType == GeomAbs_Sphere)
129 const Standard_Real aSqTol = theTol3D*theTol3D;
130 gp_Pnt aP(ElSLib::Value(0.0, M_PI_2, theQSurf->Sphere()));
131 if (aP.SquareDistance(aP3d) < aSqTol)
133 return IntPatch_SPntPoleSeamU;
136 aP = ElSLib::Value(0.0, -M_PI_2, theQSurf->Sphere());
137 if (aP.SquareDistance(aP3d) < aSqTol)
139 return IntPatch_SPntPoleSeamU;
144 const Standard_Real aDeltaU = Abs(aUQRef - aUQNext);
146 if((aType != GeomAbs_Torus) && (aDeltaU < theDeltaMax))
147 return IntPatch_SPntNone;
151 case GeomAbs_Cylinder:
152 return IntPatch_SPntSeamU;
156 const Standard_Real aDeltaV = Abs(aVQRef - aVQNext);
158 if((aDeltaU >= theDeltaMax) && (aDeltaV >= theDeltaMax))
159 return IntPatch_SPntSeamUV;
161 if(aDeltaU >= theDeltaMax)
162 return IntPatch_SPntSeamU;
164 if(aDeltaV >= theDeltaMax)
165 return IntPatch_SPntSeamV;
171 return IntPatch_SPntPoleSeamU;
176 return IntPatch_SPntNone;
179 //=======================================================================
180 //function : IntPatch_ImpPrmIntersection
182 //=======================================================================
183 IntPatch_ImpPrmIntersection::IntPatch_ImpPrmIntersection ()
184 : done(Standard_False),
185 empt(Standard_False),
186 myIsStartPnt(Standard_False),
192 //=======================================================================
193 //function : IntPatch_ImpPrmIntersection
195 //=======================================================================
197 IntPatch_ImpPrmIntersection::IntPatch_ImpPrmIntersection
198 (const Handle(Adaptor3d_Surface)& Surf1,
199 const Handle(Adaptor3d_TopolTool)& D1,
200 const Handle(Adaptor3d_Surface)& Surf2,
201 const Handle(Adaptor3d_TopolTool)& D2,
202 const Standard_Real TolArc,
203 const Standard_Real TolTang,
204 const Standard_Real Fleche,
205 const Standard_Real Pas)
206 : done(Standard_False),
207 empt(Standard_False),
208 myIsStartPnt(Standard_False),
212 Perform(Surf1,D1,Surf2,D2,TolArc,TolTang,Fleche,Pas);
216 //=======================================================================
217 //function : SetStartPoint
219 //=======================================================================
221 void IntPatch_ImpPrmIntersection::SetStartPoint(const Standard_Real U,
222 const Standard_Real V)
224 myIsStartPnt = Standard_True;
225 myUStart = U; myVStart = V;
228 //=======================================================================
229 //function : ComputeTangency
231 //=======================================================================
232 void ComputeTangency (const IntPatch_TheSOnBounds& solrst,
233 IntSurf_SequenceOfPathPoint& seqpdep,
234 const Handle(Adaptor3d_TopolTool)& Domain,
235 IntPatch_TheSurfFunction& Func,
236 const Handle(Adaptor3d_Surface)& PSurf,
237 TColStd_Array1OfInteger& Destination)
239 Standard_Integer i,k, NbPoints, seqlength;
240 Standard_Real theparam,test;
241 Standard_Boolean fairpt, ispassing;
242 TopAbs_Orientation arcorien,vtxorien;
243 Handle(Adaptor2d_Curve2d) thearc;
244 Handle(Adaptor3d_HVertex) vtx,vtxbis;
245 //Standard_Boolean ispassing;
246 IntPatch_ThePathPointOfTheSOnBounds PStart;
247 IntSurf_PathPoint PPoint;
251 gp_Vec d1u,d1v,v1,v2;
255 double aX[2], aF[1], aD[1][2];
256 math_Vector X(aX, 1, 2);
257 math_Vector F(aF, 1, 1);
258 math_Matrix D(aD, 1, 1, 1, 2);
261 NbPoints = solrst.NbPoints();
262 for (i=1; i<= NbPoints; i++) {
263 if (Destination(i) == 0) {
264 PStart = solrst.Point(i);
265 thearc = PStart.Arc();
266 theparam = PStart.Parameter();
267 arcorien = Domain->Orientation(thearc);
268 ispassing = (arcorien == TopAbs_INTERNAL ||
269 arcorien == TopAbs_EXTERNAL);
271 thearc->D0(theparam,p2d);
274 PPoint.SetValue(PStart.Value(),X(1),X(2));
277 if (Func.IsTangent()) {
278 PPoint.SetTangency(Standard_True);
279 Destination(i) = seqlength+1;
280 if (!PStart.IsNew()) {
281 vtx = PStart.Vertex();
282 for (k=i+1; k<=NbPoints; k++) {
283 if (Destination(k) ==0) {
284 PStart = solrst.Point(k);
285 if (!PStart.IsNew()) {
286 vtxbis = PStart.Vertex();
287 if (Domain->Identical(vtx,vtxbis)) {
288 thearc = PStart.Arc();
289 theparam = PStart.Parameter();
290 arcorien = Domain->Orientation(thearc);
291 ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
292 arcorien == TopAbs_EXTERNAL);
294 thearc->D0(theparam,p2d);
295 PPoint.AddUV(p2d.X(),p2d.Y());
296 Destination(k) = seqlength+1;
302 PPoint.SetPassing(ispassing);
303 seqpdep.Append(PPoint);
306 else { // on a un point de depart potentiel
308 vectg = Func.Direction3d();
309 dirtg = Func.Direction2d();
311 PSurf->D1(X(1),X(2),ptbid,d1u,d1v);
312 thearc->D1(theparam,p2d,d2d);
313 v2.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
314 v1 = d1u.Crossed(d1v);
316 test = vectg.Dot(v1.Crossed(v2));
317 if (PStart.IsNew()) {
318 if ((test < 0. && arcorien == TopAbs_FORWARD) ||
319 (test > 0. && arcorien == TopAbs_REVERSED)) {
323 PPoint.SetDirections(vectg,dirtg);
324 PPoint.SetPassing(ispassing);
325 Destination(i) = seqlength+1;
326 seqpdep.Append(PPoint);
329 else { // traiter la transition complexe
330 gp_Dir bidnorm(1.,1.,1.);
331 Standard_Real tole = 1.e-8;
332 TopAbs_Orientation LocTrans;
333 TopTrans_CurveTransition comptrans;
334 comptrans.Reset(vectg,bidnorm,0.);
335 if (arcorien == TopAbs_FORWARD ||
336 arcorien == TopAbs_REVERSED) {
339 vtx = PStart.Vertex();
340 vtxorien = Domain->Orientation(vtx);
341 if (Abs(test) <= tole) {
342 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
345 if (((test > 0.)&& arcorien == TopAbs_FORWARD) ||
346 ((test < 0.)&& arcorien == TopAbs_REVERSED)){
347 LocTrans = TopAbs_FORWARD;
350 LocTrans = TopAbs_REVERSED;
352 if (arcorien == TopAbs_REVERSED) {v2.Reverse();}
355 comptrans.Compare(tole,v2,bidnorm,0.,LocTrans,vtxorien);
357 Destination(i) = seqlength+1;
358 for (k= i+1; k<=NbPoints; k++) {
359 if (Destination(k) == 0) {
360 PStart = solrst.Point(k);
361 if (!PStart.IsNew()) {
362 vtxbis = PStart.Vertex();
363 if (Domain->Identical(vtx,vtxbis)) {
364 thearc = PStart.Arc();
365 theparam = PStart.Parameter();
366 arcorien = Domain->Orientation(thearc);
368 PPoint.AddUV(X(1),X(2));
370 thearc->D1(theparam,p2d,d2d);
371 PPoint.AddUV(p2d.X(),p2d.Y());
373 if (arcorien == TopAbs_FORWARD ||
374 arcorien == TopAbs_REVERSED) {
375 ispassing = Standard_False;
376 v2.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
378 test = vectg.Dot(v1.Crossed(v2));
379 vtxorien = Domain->Orientation(PStart.Vertex());
380 if (Abs(test) <= tole) {
381 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
384 if (((test > 0.)&& arcorien == TopAbs_FORWARD) ||
385 ((test < 0.)&& arcorien == TopAbs_REVERSED)){
386 LocTrans = TopAbs_FORWARD;
389 LocTrans = TopAbs_REVERSED;
391 if (arcorien == TopAbs_REVERSED) {v2.Reverse();}
394 comptrans.Compare(tole,v2,bidnorm,0.,LocTrans,vtxorien);
396 Destination(k) = seqlength+1;
401 fairpt = Standard_True;
403 TopAbs_State Before = comptrans.StateBefore();
404 TopAbs_State After = comptrans.StateAfter();
405 if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
406 fairpt = Standard_False;
408 else if (Before == TopAbs_IN) {
409 if (After == TopAbs_IN) {
410 ispassing = Standard_True;
418 if (After !=TopAbs_IN) {
419 fairpt = Standard_False;
424 PPoint.SetDirections(vectg,dirtg);
425 PPoint.SetPassing(ispassing);
426 seqpdep.Append(PPoint);
429 else { // il faut remettre en "ordre" si on ne garde pas le point.
430 for (k=i; k <=NbPoints ; k++) {
431 if (Destination(k)==seqlength + 1) {
432 Destination(k) = -Destination(k);
441 //=======================================================================
444 //=======================================================================
445 void Recadre(const Standard_Boolean ,
446 GeomAbs_SurfaceType typeS1,
447 GeomAbs_SurfaceType typeS2,
449 const Handle(IntPatch_TheIWLineOfTheIWalking)& iwline,
450 Standard_Integer Param,
456 Standard_Real U1p,V1p,U2p,V2p;
457 iwline->Line()->Value(Param).Parameters(U1p,V1p,U2p,V2p);
461 while(V1<(V1p-1.5*M_PI)) V1+=M_PI+M_PI;
462 while(V1>(V1p+1.5*M_PI)) V1-=M_PI+M_PI;
464 case GeomAbs_Cylinder:
467 while(U1<(U1p-1.5*M_PI)) U1+=M_PI+M_PI;
468 while(U1>(U1p+1.5*M_PI)) U1-=M_PI+M_PI;
475 while(V2<(V2p-1.5*M_PI)) V2+=M_PI+M_PI;
476 while(V2>(V2p+1.5*M_PI)) V2-=M_PI+M_PI;
478 case GeomAbs_Cylinder:
481 while(U2<(U2p-1.5*M_PI)) U2+=M_PI+M_PI;
482 while(U2>(U2p+1.5*M_PI)) U2-=M_PI+M_PI;
486 pt.SetParameters(U1,V1,U2,V2);
489 //=======================================================================
490 //function : GetLocalStep
492 //=======================================================================
493 Standard_Real GetLocalStep(const Handle(Adaptor3d_Surface)& theSurf,
494 const Standard_Real theStep)
496 Standard_Real aLocalStep = theStep;
497 if (theSurf->UContinuity() > GeomAbs_C0 && theSurf->VContinuity() > GeomAbs_C0)
499 GeomAbs_SurfaceType aSType = theSurf->GetType();
501 if (aSType == GeomAbs_BezierSurface || aSType == GeomAbs_BSplineSurface)
503 Standard_Real aMinRes = Precision::Infinite();
504 Standard_Integer aMaxDeg = 0;
505 const Standard_Real aLimRes = 1.e-10;
507 aMinRes = Min(theSurf->UResolution(Precision::Confusion()),
508 theSurf->VResolution(Precision::Confusion()));
509 aMaxDeg = Max(theSurf->UDegree(), theSurf->VDegree());
510 if (aMinRes < aLimRes && aMaxDeg > 3)
516 if (theSurf->UContinuity() == GeomAbs_C0)
518 Standard_Integer aNbInt = theSurf->NbUIntervals(GeomAbs_C1);
521 TColStd_Array1OfReal anInts(1, aNbInt + 1);
522 theSurf->UIntervals(anInts, GeomAbs_C1);
524 Standard_Real aMinInt = Precision::Infinite();
525 for (i = 1; i <= aNbInt; ++i)
527 aMinInt = Min(aMinInt, anInts(i + 1) - anInts(i));
530 aMinInt /= theSurf->LastUParameter() - theSurf->FirstUParameter();
539 if (theSurf->VContinuity() == GeomAbs_C0)
541 Standard_Integer aNbInt = theSurf->NbVIntervals(GeomAbs_C1);
544 TColStd_Array1OfReal anInts(1, aNbInt + 1);
545 theSurf->VIntervals(anInts, GeomAbs_C1);
547 Standard_Real aMinInt = Precision::Infinite();
548 for (i = 1; i <= aNbInt; ++i)
550 aMinInt = Min(aMinInt, anInts(i + 1) - anInts(i));
553 aMinInt /= theSurf->LastVParameter() - theSurf->FirstVParameter();
561 aLocalStep = Min(theStep, aLocalStep);
564 //=======================================================================
567 //=======================================================================
568 void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_Surface)& Surf1,
569 const Handle(Adaptor3d_TopolTool)& D1,
570 const Handle(Adaptor3d_Surface)& Surf2,
571 const Handle(Adaptor3d_TopolTool)& D2,
572 const Standard_Real TolArc,
573 const Standard_Real TolTang,
574 const Standard_Real Fleche,
575 const Standard_Real Pas)
577 Standard_Boolean reversed, procf, procl, dofirst, dolast;
578 Standard_Integer indfirst = 0, indlast = 0, ind2, NbSegm;
579 Standard_Integer NbPointIns, NbPointRst, Nblines, Nbpts, NbPointDep;
580 Standard_Real U1,V1,U2,V2,paramf,paraml,currentparam;
582 IntPatch_TheSegmentOfTheSOnBounds thesegm;
583 IntSurf_PathPoint PPoint;
585 Handle(IntPatch_RLine) rline;
586 Handle(IntPatch_WLine) wline;
587 IntPatch_ThePathPointOfTheSOnBounds PStart,PStartf,PStartl;
588 IntPatch_Point ptdeb,ptfin,ptbis;
591 IntSurf_Transition TLine,TArc;
592 IntSurf_TypeTrans trans1,trans2;
594 gp_Vec tgline,tgrst,norm1,norm2,d1u,d1v;
601 Handle(Adaptor2d_Curve2d) currentarc;
602 GeomAbs_SurfaceType typeS1, typeS2;
603 IntSurf_Quadric Quad;
604 IntPatch_TheSurfFunction Func;
605 IntPatch_ArcFunction AFunc;
607 typeS1 = Surf1->GetType();
608 typeS2 = Surf2->GetType();
612 trans1 = IntSurf_Undecided;
613 trans2 = IntSurf_Undecided;
615 done = Standard_False;
616 empt = Standard_True;
620 reversed = Standard_False;
624 Quad.SetValue(Surf1->Plane());
627 case GeomAbs_Cylinder:
628 Quad.SetValue(Surf1->Cylinder());
632 Quad.SetValue(Surf1->Sphere());
636 Quad.SetValue(Surf1->Cone());
641 reversed = Standard_True;
645 Quad.SetValue(Surf2->Plane());
648 case GeomAbs_Cylinder:
649 Quad.SetValue(Surf2->Cylinder());
653 Quad.SetValue(Surf2->Sphere());
657 Quad.SetValue(Surf2->Cone());
661 throw Standard_ConstructionError();
669 Standard_Real aLocalPas = Pas;
671 aLocalPas = GetLocalStep(Surf1, Pas);
673 aLocalPas = GetLocalStep(Surf2, Pas);
675 Func.SetImplicitSurface(Quad);
676 Func.Set(IntSurf_QuadricTool::Tolerance(Quad));
677 AFunc.SetQuadric(Quad);
689 solrst.Perform(AFunc,D2,TolArc,TolTang);
692 solrst.Perform(AFunc,D1,TolArc,TolTang);
694 if (!solrst.IsDone()) {
698 IntSurf_SequenceOfPathPoint seqpdep;
699 IntSurf_SequenceOfInteriorPoint seqpins;
701 NbPointRst = solrst.NbPoints();
702 TColStd_Array1OfInteger Destination(1,NbPointRst+1); Destination.Init(0);
705 ComputeTangency(solrst,seqpdep,D2,Func,Surf2,Destination);
708 ComputeTangency(solrst,seqpdep,D1,Func,Surf1,Destination);
712 Standard_Boolean SearchIns = Standard_True;
713 if(Quad.TypeQuadric() == GeomAbs_Plane && solrst.NbSegments() > 0)
715 //For such kind of cases it is possible that whole surface is on one side of plane,
716 //plane only touches surface and does not cross it,
717 //so no inner points exist.
718 SearchIns = Standard_False;
719 Handle(Adaptor3d_TopolTool) T;
728 Standard_Integer aNbSamples = 0;
729 aNbSamples = T->NbSamples();
732 Standard_Real aValf[1], aUVap[2];
733 math_Vector Valf(aValf,1,1), UVap(aUVap,1,2);
734 T->SamplePoint(1,s2d, s3d);
737 Func.Value(UVap,Valf);
738 Standard_Real rvalf = Sign(1.,Valf(1));
739 for(Standard_Integer i = 2; i <= aNbSamples; ++i)
741 T->SamplePoint(i,s2d, s3d);
744 Func.Value(UVap,Valf);
745 if(rvalf * Valf(1) < 0.)
747 SearchIns = Standard_True;
752 // Recherche des points interieurs
757 solins.Perform(Func,Surf2,myUStart,myVStart);
759 solins.Perform(Func,Surf2,D2,TolTang);
763 solins.Perform(Func,Surf1,myUStart,myVStart);
765 solins.Perform(Func,Surf1,D1,TolTang);
767 NbPointIns = solins.NbPoints();
768 for (Standard_Integer i=1; i <= NbPointIns; i++) {
769 seqpins.Append(solins.Value(i));
773 NbPointDep=seqpdep.Length();
775 if (NbPointDep || NbPointIns) {
776 IntPatch_TheIWalking iwalk(TolTang, Fleche, aLocalPas);
777 iwalk.Perform(seqpdep, seqpins, Func, reversed ? Surf1 : Surf2, reversed);
779 if(!iwalk.IsDone()) {
783 Standard_Real Vmin, Vmax, TolV = 1.e-14;
784 if (!reversed) { //Surf1 is quadric
785 Vmin = Surf1->FirstVParameter();
786 Vmax = Surf1->LastVParameter();
788 else { //Surf2 is quadric
789 Vmin = Surf2->FirstVParameter();
790 Vmax = Surf2->LastVParameter();
793 Nblines = iwalk.NbLines();
794 for (Standard_Integer j=1; j<=Nblines; j++) {
795 const Handle(IntPatch_TheIWLineOfTheIWalking)& iwline = iwalk.Value(j);
796 const Handle(IntSurf_LineOn2S)& thelin = iwline->Line();
798 Nbpts = thelin->NbPoints();
800 Standard_Integer k = 0;
801 tgline = iwline->TangentVector(k);
802 if(k>=1 && k<=Nbpts) { } else { k=Nbpts>>1; }
803 valpt = thelin->Value(k).Value();
806 thelin->Value(k).ParametersOnS2(U2,V2);
807 norm1 = Quad.Normale(valpt);
808 Surf2->D1(U2,V2,ptbid,d1u,d1v);
809 norm2 = d1u.Crossed(d1v);
812 thelin->Value(k).ParametersOnS1(U2,V2);
813 norm2 = Quad.Normale(valpt);
814 Surf1->D1(U2,V2,ptbid,d1u,d1v);
815 norm1 = d1u.Crossed(d1v);
817 if (tgline.DotCross(norm2,norm1) > 0.) {
818 trans1 = IntSurf_Out;
823 trans2 = IntSurf_Out;
827 Standard_Real AnU1,AnU2,AnV2;
829 GeomAbs_SurfaceType typQuad = Quad.TypeQuadric();
830 Standard_Boolean arecadr=Standard_False;
831 valpt = thelin->Value(1).Value();
832 Quad.Parameters(valpt,AnU1,V1);
834 if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
835 if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
838 thelin->SetUV(1,Standard_False,AnU1,V1); //-- on va lire u2,v2
839 thelin->Value(1).ParametersOnS1(AnU2,AnV2);
842 thelin->SetUV(1,Standard_True,AnU1,V1); //-- on va lire u1,v1
843 thelin->Value(1).ParametersOnS2(AnU2,AnV2);
846 if(typQuad==GeomAbs_Cylinder ||
847 typQuad==GeomAbs_Cone ||
848 typQuad==GeomAbs_Sphere) {
849 arecadr=Standard_True;
852 for (k=2; k<=Nbpts; ++k) {
853 valpt = thelin->Value(k).Value();
854 Quad.Parameters(valpt,U1,V1);
856 if((V1 < Vmin) && (Vmin-V1 < TolV)) {
859 if((V1 > Vmax) && (V1-Vmax < TolV)) {
864 //modified by NIZNHY-PKV Fri Mar 28 15:06:01 2008f
865 Standard_Real aCf, aTwoPI;
869 if ((U1-AnU1) > 1.5*M_PI) {
870 while ((U1-AnU1) > (1.5*M_PI+aCf*aTwoPI)) {
877 while ((U1-AnU1) < (-1.5*M_PI-aCf*aTwoPI)) {
883 //if ((U1-AnU1) > 1.5*M_PI) {
886 //else if ((U1-AnU1) < -1.5*M_PI) {
889 //modified by NIZNHY-PKV Fri Mar 28 15:06:11 2008t
893 thelin->SetUV(k,Standard_False,U1,V1);
895 thelin->Value(k).ParametersOnS1(U2,V2);
897 case GeomAbs_Cylinder:
901 while(U2<(AnU2-1.5*M_PI)) U2+=M_PI+M_PI;
902 while(U2>(AnU2+1.5*M_PI)) U2-=M_PI+M_PI;
907 if(typeS2==GeomAbs_Torus) {
908 while(V2<(AnV2-1.5*M_PI)) V2+=M_PI+M_PI;
909 while(V2>(AnV2+1.5*M_PI)) V2-=M_PI+M_PI;
911 thelin->SetUV(k,Standard_True,U2,V2);
914 thelin->SetUV(k,Standard_True,U1,V1);
916 thelin->Value(k).ParametersOnS2(U2,V2);
918 case GeomAbs_Cylinder:
922 while(U2<(AnU2-1.5*M_PI)) U2+=M_PI+M_PI;
923 while(U2>(AnU2+1.5*M_PI)) U2-=M_PI+M_PI;
928 if(typeS2==GeomAbs_Torus) {
929 while(V2<(AnV2-1.5*M_PI)) V2+=M_PI+M_PI;
930 while(V2>(AnV2+1.5*M_PI)) V2-=M_PI+M_PI;
932 thelin->SetUV(k,Standard_False,U2,V2);
941 wline = new IntPatch_WLine(thelin,Standard_False,trans1,trans2);
942 wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpPrm);
944 #ifdef INTPATCH_IMPPRMINTERSECTION_DEBUG
948 if ( iwline->HasFirstPoint()
949 && iwline->IsTangentAtBegining() == Standard_False)
951 indfirst = iwline->FirstPointIndex();
952 PPoint = seqpdep(indfirst);
953 tgline = PPoint.Direction3d();
954 Standard_Integer themult = PPoint.Multiplicity();
955 for (Standard_Integer i=NbPointRst; i>=1; i--) {
956 if (Destination(i) == indfirst) {
957 if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
958 Quad.Parameters(PPoint.Value(),U1,V1);
960 if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
961 if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
963 PPoint.Parameters(themult,U2,V2);
964 Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
966 else { //-- typeS1 != Pln && Cyl && Sph && Cone
967 Quad.Parameters(PPoint.Value(),U2,V2);
969 if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
970 if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
972 PPoint.Parameters(themult,U1,V1);
973 Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
976 VecNormale = d1u.Crossed(d1v);
977 //-- Modif du 27 Septembre 94 (Recadrage des pts U,V)
978 ptdeb.SetValue(PPoint.Value(),TolArc,Standard_False);
979 ptdeb.SetParameters(U1,V1,U2,V2);
980 ptdeb.SetParameter(1.);
982 Recadre(reversed,typeS1,typeS2,ptdeb,iwline,1,U1,V1,U2,V2);
984 currentarc = solrst.Point(i).Arc();
985 currentparam = solrst.Point(i).Parameter();
986 currentarc->D1(currentparam,p2d,d2d);
987 tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
989 Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
990 if(squaremagnitudeVecNormale > 1e-13) {
991 DirNormale=VecNormale;
992 IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
995 TLine.SetValue(Standard_True,IntSurf_Undecided);
996 TArc.SetValue(Standard_True,IntSurf_Undecided);
999 ptdeb.SetArc(reversed,currentarc,currentparam,TLine,TArc);
1000 if (!solrst.Point(i).IsNew()) {
1001 ptdeb.SetVertex(reversed,solrst.Point(i).Vertex());
1003 wline->AddVertex(ptdeb);
1005 wline->SetFirstPoint(wline->NbVertex());
1012 else if (iwline->IsTangentAtBegining())
1014 gp_Pnt psol = thelin->Value(1).Value();
1015 thelin->Value(1).ParametersOnS1(U1,V1);
1016 thelin->Value(1).ParametersOnS2(U2,V2);
1017 ptdeb.SetValue(psol,TolArc,Standard_True);
1018 ptdeb.SetParameters(U1,V1,U2,V2);
1019 ptdeb.SetParameter(1.);
1020 wline->AddVertex(ptdeb);
1021 wline->SetFirstPoint(wline->NbVertex());
1025 gp_Pnt psol = thelin->Value(1).Value();
1026 thelin->Value(1).ParametersOnS1(U1,V1);
1027 thelin->Value(1).ParametersOnS2(U2,V2);
1028 ptdeb.SetValue(psol,TolArc,Standard_False);
1029 ptdeb.SetParameters(U1,V1,U2,V2);
1030 ptdeb.SetParameter(1.);
1031 wline->AddVertex(ptdeb);
1032 wline->SetFirstPoint(wline->NbVertex());
1036 if ( iwline->HasLastPoint()
1037 && iwline->IsTangentAtEnd() == Standard_False)
1039 indlast = iwline->LastPointIndex();
1040 PPoint = seqpdep(indlast);
1041 tgline = PPoint.Direction3d().Reversed();
1042 Standard_Integer themult = PPoint.Multiplicity();
1043 for (Standard_Integer i=NbPointRst; i >=1; i--) {
1044 if (Destination(i) == indlast) {
1046 Quad.Parameters(PPoint.Value(),U1,V1);
1048 if((V1 < Vmin) && (Vmin-V1 < TolV)) V1 = Vmin;
1049 if((V1 > Vmax) && (V1-Vmax < TolV)) V1 = Vmax;
1051 PPoint.Parameters(themult,U2,V2);
1052 Surf2->D1(U2,V2,ptbid,d1u,d1v); //-- @@@@
1053 VecNormale = d1u.Crossed(d1v); //-- @@@@
1056 Quad.Parameters(PPoint.Value(),U2,V2);
1058 if((V2 < Vmin) && (Vmin-V2 < TolV)) V2 = Vmin;
1059 if((V2 > Vmax) && (V2-Vmax < TolV)) V2 = Vmax;
1061 PPoint.Parameters(themult,U1,V1);
1062 Surf1->D1(U1,V1,ptbid,d1u,d1v); //-- @@@@
1063 VecNormale = d1u.Crossed(d1v); //-- @@@@
1066 ptfin.SetValue(PPoint.Value(),TolArc,Standard_False);
1067 ptfin.SetParameters(U1,V1,U2,V2);
1068 ptfin.SetParameter(Nbpts);
1070 Recadre(reversed,typeS1,typeS2,ptfin,iwline,Nbpts-1,U1,V1,U2,V2);
1072 currentarc = solrst.Point(i).Arc();
1073 currentparam = solrst.Point(i).Parameter();
1074 currentarc->D1(currentparam,p2d,d2d);
1075 tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1078 Standard_Real squaremagnitudeVecNormale = VecNormale.SquareMagnitude();
1079 if(squaremagnitudeVecNormale > 1e-13) {
1080 DirNormale=VecNormale;
1081 IntSurf::MakeTransition(tgline,tgrst,DirNormale,TLine,TArc);
1084 TLine.SetValue(Standard_True,IntSurf_Undecided);
1085 TArc.SetValue(Standard_True,IntSurf_Undecided);
1089 ptfin.SetArc(reversed,currentarc,currentparam,TLine,TArc);
1090 if (!solrst.Point(i).IsNew()) {
1091 ptfin.SetVertex(reversed,solrst.Point(i).Vertex());
1093 wline->AddVertex(ptfin);
1095 wline->SetLastPoint(wline->NbVertex());
1102 else if (iwline->IsTangentAtEnd())
1104 gp_Pnt psol = thelin->Value(Nbpts).Value();
1105 thelin->Value(Nbpts).ParametersOnS1(U1,V1);
1106 thelin->Value(Nbpts).ParametersOnS2(U2,V2);
1107 ptfin.SetValue(psol,TolArc,Standard_True);
1108 ptfin.SetParameters(U1,V1,U2,V2);
1109 ptfin.SetParameter(Nbpts);
1110 wline->AddVertex(ptfin);
1111 wline->SetLastPoint(wline->NbVertex());
1115 gp_Pnt psol = thelin->Value(Nbpts).Value();
1116 thelin->Value(Nbpts).ParametersOnS1(U1,V1);
1117 thelin->Value(Nbpts).ParametersOnS2(U2,V2);
1118 ptfin.SetValue(psol,TolArc,Standard_False);
1119 ptfin.SetParameters(U1,V1,U2,V2);
1120 ptfin.SetParameter(Nbpts);
1121 wline->AddVertex(ptfin);
1122 wline->SetLastPoint(wline->NbVertex());
1125 // Il faut traiter les points de passage.
1128 }// for (j=1; j<=Nblines; j++) {
1130 // ON GERE LES RACCORDS ENTRE LIGNES. ELLE NE PEUVENT SE RACCORDER
1131 // QUE SUR DES POINTS DE TANGENCE
1134 Nblines = slin.Length();
1135 for (Standard_Integer j=1; j<=Nblines-1; j++) {
1136 dofirst = dolast = Standard_False;
1137 const Handle(IntPatch_Line)& slinj = slin(j);
1138 Handle(IntPatch_WLine) wlin1 (Handle(IntPatch_WLine)::DownCast (slinj));
1139 if (wlin1->HasFirstPoint()) {
1140 ptdeb = wlin1->FirstPoint(indfirst);
1141 if (ptdeb.IsTangencyPoint()) {
1142 dofirst = Standard_True;
1145 if (wlin1->HasLastPoint()) {
1146 ptfin = wlin1->LastPoint(indlast);
1147 if (ptfin.IsTangencyPoint()) {
1148 dolast = Standard_True;
1152 if (dofirst || dolast) {
1153 for (Standard_Integer k=j+1; k<=Nblines;k++) {
1154 const Handle(IntPatch_Line)& slink = slin(k);
1155 Handle(IntPatch_WLine) wlin2 (Handle(IntPatch_WLine)::DownCast (slink));
1156 if (wlin2->HasFirstPoint()) {
1157 ptbis = wlin2->FirstPoint(ind2);
1158 if (ptbis.IsTangencyPoint()) {
1160 if (ptdeb.Value().Distance(ptbis.Value()) <= TolArc) {
1161 ptdeb.SetMultiple(Standard_True);
1162 if (!ptbis.IsMultiple()) {
1163 ptbis.SetMultiple(Standard_True);
1164 wlin2->Replace(ind2,ptbis);
1169 if (ptfin.Value().Distance(ptbis.Value()) <= TolArc) {
1170 ptfin.SetMultiple(Standard_True);
1171 if (!ptbis.IsMultiple()) {
1172 ptbis.SetMultiple(Standard_True);
1173 wlin2->Replace(ind2,ptbis);
1179 if (wlin2->HasLastPoint()) {
1180 ptbis = wlin2->LastPoint(ind2);
1181 if (ptbis.IsTangencyPoint()) {
1183 if (ptdeb.Value().Distance(ptbis.Value()) <= TolArc) {
1184 ptdeb.SetMultiple(Standard_True);
1185 if (!ptbis.IsMultiple()) {
1186 ptbis.SetMultiple(Standard_True);
1187 wlin2->Replace(ind2,ptbis);
1192 if (ptfin.Value().Distance(ptbis.Value()) <= TolArc) {
1193 ptfin.SetMultiple(Standard_True);
1194 if (!ptbis.IsMultiple()) {
1195 ptbis.SetMultiple(Standard_True);
1196 wlin2->Replace(ind2,ptbis);
1204 wlin1->Replace(indfirst,ptdeb);
1206 wlin1->Replace(indlast,ptfin);
1209 }// if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1211 // Treatment the segments
1212 NbSegm = solrst.NbSegments();
1214 for(Standard_Integer i=1; i<=NbSegm; i++) {
1215 thesegm = solrst.Segment(i);
1216 //Check if segment is degenerated
1217 if(thesegm.HasFirstPoint() && thesegm.HasLastPoint())
1219 Standard_Real tol2 = Precision::Confusion();
1221 const gp_Pnt& aPf = thesegm.FirstPoint().Value();
1222 const gp_Pnt& aPl = thesegm.LastPoint().Value();
1223 if(aPf.SquareDistance(aPl) <= tol2)
1225 //segment can be degenerated - check inner point
1226 paramf = thesegm.FirstPoint().Parameter();
1227 paraml = thesegm.LastPoint().Parameter();
1229 thesegm.Curve()->Value(.57735 * paramf + 0.42265 * paraml);
1233 Surf1->D0(_p2d.X(), _p2d.Y(), aPm);
1237 Surf2->D0(_p2d.X(), _p2d.Y(), aPm);
1239 if(aPm.SquareDistance(aPf) <= tol2)
1248 //----------------------------------------------------------------------
1249 // on cree une ligne d intersection contenant uniquement le segment.
1250 // VOIR POUR LA TRANSITION DE LA LIGNE
1251 // On ajoute aussi un polygone pour le traitement des intersections
1252 // entre ligne et restrictions de la surface implicite (PutVertexOnLine)
1253 //----------------------------------------------------------------------
1254 //-- Calcul de la transition sur la rline (12 fev 97)
1255 //-- reversed a le sens de OnFirst
1257 dofirst = dolast = Standard_False;
1258 procf = Standard_False;
1259 procl = Standard_False;
1260 IntSurf_Transition TLineUnk,TArcUnk;
1262 IntPatch_Point _thepointAtBeg;
1263 IntPatch_Point _thepointAtEnd;
1265 Standard_Boolean TransitionOK=Standard_False;
1267 if(thesegm.HasFirstPoint()) {
1268 Standard_Real _u1,_v1,_u2,_v2;
1270 dofirst = Standard_True;
1271 PStartf = thesegm.FirstPoint();
1272 paramf = PStartf.Parameter();
1274 gp_Pnt2d _p2d = thesegm.Curve()->Value(paramf);
1275 Handle(Adaptor3d_HVertex) _vtx;
1276 if(PStartf.IsNew()==Standard_False)
1277 _vtx= PStartf.Vertex();
1278 const gp_Pnt& _Pp = PStartf.Value();
1279 _thepointAtBeg.SetValue(_Pp,PStartf.Tolerance(),Standard_False);
1280 if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
1281 Quad.Parameters(_Pp,_u1,_v1);
1282 _u2=_p2d.X(); _v2=_p2d.Y();
1284 else { //-- typeS1 != Pln && Cyl && Sph && Cone
1285 Quad.Parameters(_Pp,_u2,_v2);
1286 _u1=_p2d.X(); _v1=_p2d.Y();
1288 _thepointAtBeg.SetParameters(_u1,_v1,_u2,_v2);
1289 _thepointAtBeg.SetParameter(paramf);
1290 if(PStartf.IsNew()==Standard_False)
1291 _thepointAtBeg.SetVertex(reversed,_vtx);
1292 _thepointAtBeg.SetArc(reversed,thesegm.Curve(),paramf,TLineUnk,TArcUnk);
1295 gp_Vec d1u1,d1v1,d1u2,d1v2; gp_Vec2d _d2d;
1296 Surf1->D1(_u1,_v1,ptbid,d1u1,d1v1);
1297 norm1 = d1u1.Crossed(d1v1);
1298 Surf2->D1(_u2,_v2,ptbid,d1u2,d1v2);
1299 norm2 = d1u2.Crossed(d1v2);
1301 thesegm.Curve()->D1(paramf,_p2d,_d2d);
1303 tgline.SetLinearForm(_d2d.X(),d1u1,_d2d.Y(),d1v1);
1306 tgline.SetLinearForm(_d2d.X(),d1u2,_d2d.Y(),d1v2);
1308 _u1=tgline.DotCross(norm2,norm1);
1309 TransitionOK=Standard_True;
1310 if (_u1 > 0.00000001) {
1311 trans1 = IntSurf_Out;
1312 trans2 = IntSurf_In;
1314 else if(_u1 < -0.00000001) {
1315 trans1 = IntSurf_In;
1316 trans2 = IntSurf_Out;
1319 TransitionOK=Standard_False;
1322 if(thesegm.HasLastPoint()) {
1323 Standard_Real _u1,_v1,_u2,_v2;
1325 dolast = Standard_True;
1326 PStartl = thesegm.LastPoint();
1327 paraml = PStartl.Parameter();
1329 gp_Pnt2d _p2d = thesegm.Curve()->Value(paraml);
1330 Handle(Adaptor3d_HVertex) _vtx;
1331 if(PStartl.IsNew()==Standard_False)
1332 _vtx = PStartl.Vertex();
1333 const gp_Pnt& _Pp = PStartl.Value();
1334 IntPatch_Point _thepoint;
1335 _thepointAtEnd.SetValue(_Pp,PStartl.Tolerance(),Standard_False);
1336 if (!reversed) { //-- typeS1 = Pln || Cyl || Sph || Cone
1337 Quad.Parameters(_Pp,_u1,_v1);
1338 _u2=_p2d.X(); _v2=_p2d.Y();
1340 else { //-- typeS1 != Pln && Cyl && Sph && Cone
1341 Quad.Parameters(_Pp,_u2,_v2);
1342 _u1=_p2d.X(); _v1=_p2d.Y();
1344 _thepointAtEnd.SetParameters(_u1,_v1,_u2,_v2);
1345 _thepointAtEnd.SetParameter(paraml);
1346 if(PStartl.IsNew()==Standard_False)
1347 _thepointAtEnd.SetVertex(reversed,_vtx);
1348 _thepointAtEnd.SetArc(reversed,thesegm.Curve(),paraml,TLineUnk,TArcUnk);
1352 gp_Vec d1u1,d1v1,d1u2,d1v2; gp_Vec2d _d2d;
1353 Surf1->D1(_u1,_v1,ptbid,d1u1,d1v1);
1354 norm1 = d1u1.Crossed(d1v1);
1355 Surf2->D1(_u2,_v2,ptbid,d1u2,d1v2);
1356 norm2 = d1u2.Crossed(d1v2);
1358 thesegm.Curve()->D1(paraml,_p2d,_d2d);
1360 tgline.SetLinearForm(_d2d.X(),d1u1,_d2d.Y(),d1v1);
1363 tgline.SetLinearForm(_d2d.X(),d1u2,_d2d.Y(),d1v2);
1365 _u1=tgline.DotCross(norm2,norm1);
1366 TransitionOK=Standard_True;
1367 if (_u1 > 0.00000001) {
1368 trans1 = IntSurf_Out;
1369 trans2 = IntSurf_In;
1371 else if(_u1 < -0.00000001) {
1372 trans1 = IntSurf_In;
1373 trans2 = IntSurf_Out;
1376 TransitionOK=Standard_False;
1379 if(TransitionOK==Standard_False) {
1380 //-- rline = new IntPatch_RLine (thesegm.Curve(),reversed,Standard_False);
1381 rline = new IntPatch_RLine (Standard_False);
1383 rline->SetArcOnS1(thesegm.Curve());
1386 rline->SetArcOnS2(thesegm.Curve());
1390 //-- rline = new IntPatch_RLine (thesegm.Curve(),reversed,Standard_False,trans1,trans2);
1391 rline = new IntPatch_RLine (Standard_False,trans1,trans2);
1393 rline->SetArcOnS1(thesegm.Curve());
1396 rline->SetArcOnS2(thesegm.Curve());
1400 //------------------------------
1401 //-- Ajout des points
1403 if (thesegm.HasFirstPoint()) {
1404 rline->AddVertex(_thepointAtBeg);
1405 rline->SetFirstPoint(rline->NbVertex());
1408 if (thesegm.HasLastPoint()) {
1409 rline->AddVertex(_thepointAtEnd);
1410 rline->SetLastPoint(rline->NbVertex());
1413 // Polygone sur restriction solution
1414 if (dofirst && dolast) {
1417 IntSurf_PntOn2S p2s;
1418 Handle(IntSurf_LineOn2S) Thelin = new IntSurf_LineOn2S ();
1419 Handle(Adaptor2d_Curve2d) arcsegm = thesegm.Curve();
1420 Standard_Integer nbsample = 100;
1423 for (Standard_Integer j=1; j<=nbsample; j++) {
1424 prm = paramf + (j-1)*(paraml-paramf)/(nbsample-1);
1425 arcsegm->D0(prm,p2d);
1426 Surf2->D0(p2d.X(),p2d.Y(),ptpoly);
1428 Quad.Parameters(ptpoly,U1,V1);
1429 p2s.SetValue(ptpoly,U1,V1,p2d.X(),p2d.Y());
1434 for (Standard_Integer j=1; j<=nbsample; j++) {
1435 prm = paramf + (j-1)*(paraml-paramf)/(nbsample-1);
1436 arcsegm->D0(prm,p2d);
1437 Surf1->D0(p2d.X(),p2d.Y(),ptpoly);
1439 Quad.Parameters(ptpoly,U2,V2);
1440 p2s.SetValue(ptpoly,p2d.X(),p2d.Y(),U2,V2);
1447 if (dofirst || dolast) {
1448 Nblines = slin.Length();
1449 for (Standard_Integer j=1; j<=Nblines; j++) {
1450 const Handle(IntPatch_Line)& slinj = slin(j);
1451 typ = slinj->ArcType();
1452 if (typ == IntPatch_Walking) {
1453 Nbpts = Handle(IntPatch_WLine)::DownCast (slinj)->NbVertex();
1456 Nbpts = Handle(IntPatch_RLine)::DownCast (slinj)->NbVertex();
1458 for (Standard_Integer k=1; k<=Nbpts;k++) {
1459 if (typ == IntPatch_Walking) {
1460 ptdeb = Handle(IntPatch_WLine)::DownCast (slinj)->Vertex(k);
1463 ptdeb = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
1467 if (ptdeb.Value().Distance(PStartf.Value()) <=TolArc) {
1468 ptdeb.SetMultiple(Standard_True);
1469 if (typ == IntPatch_Walking) {
1470 Handle(IntPatch_WLine)::DownCast (slinj)->Replace(k,ptdeb);
1473 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptdeb);
1475 ptdeb.SetParameter(paramf);
1476 rline->AddVertex(ptdeb);
1478 procf=Standard_True;
1479 rline->SetFirstPoint(rline->NbVertex());
1484 if(dofirst) { //-- on recharge le ptdeb
1485 if (typ == IntPatch_Walking) {
1486 ptdeb = Handle(IntPatch_WLine)::DownCast (slinj)->Vertex(k);
1489 ptdeb = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
1492 if (ptdeb.Value().Distance(PStartl.Value()) <=TolArc) {
1493 ptdeb.SetMultiple(Standard_True);
1494 if (typ == IntPatch_Walking) {
1495 Handle(IntPatch_WLine)::DownCast (slinj)->Replace(k,ptdeb);
1498 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptdeb);
1500 ptdeb.SetParameter(paraml);
1501 rline->AddVertex(ptdeb);
1503 procl=Standard_True;
1504 rline->SetLastPoint(rline->NbVertex());
1515 // on traite les restrictions de la surface implicite
1517 for (Standard_Integer i=1, aNbLin = slin.Length(); i<=aNbLin; i++)
1519 Handle(IntPatch_PointLine) aL = Handle(IntPatch_PointLine)::DownCast(slin(i));
1522 IntPatch_RstInt::PutVertexOnLine(aL,Surf1,D1,Surf2,Standard_True,TolTang);
1524 IntPatch_RstInt::PutVertexOnLine(aL,Surf2,D2,Surf1,Standard_False,TolTang);
1526 if (aL->NbPnts() <= 2)
1528 Standard_Boolean aCond = aL->NbPnts() < 2;
1530 aCond = (aL->Point(1).IsSame(aL->Point(2), Precision::Confusion()));
1541 if(aL->ArcType() == IntPatch_Walking)
1543 const Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(aL);
1551 // Now slin is filled as follows: lower indices correspond to Restriction line,
1552 // after (higher indices) - only Walking-line.
1554 const Standard_Real aTol3d = Max(Func.Tolerance(), TolTang);
1555 const Handle(Adaptor3d_Surface)& aQSurf = (reversed) ? Surf2 : Surf1;
1556 const Handle(Adaptor3d_Surface)& anOtherSurf = (reversed) ? Surf1 : Surf2;
1558 for (Standard_Integer i = 1; i <= slin.Length(); i++)
1560 const Handle(IntPatch_PointLine)& aL1 = Handle(IntPatch_PointLine)::DownCast(slin(i));
1561 const Handle(IntPatch_RLine)& aRL1 = Handle(IntPatch_RLine)::DownCast(aL1);
1565 //Walking-Walking cases are not supported
1569 const Handle(Adaptor2d_Curve2d)& anArc = aRL1->IsArcOnS1() ?
1572 if(anArc->GetType() != GeomAbs_Line)
1574 //Restriction line must be isoline.
1575 //Other cases are not supported by
1576 //existing algorithms.
1581 Standard_Boolean isFirstDeleted = Standard_False;
1583 for(Standard_Integer j = i + 1; j <= slin.Length(); j++)
1585 Handle(IntPatch_PointLine) aL2 = Handle(IntPatch_PointLine)::DownCast(slin(j));
1586 Handle(IntPatch_RLine) aRL2 = Handle(IntPatch_RLine)::DownCast(aL2);
1588 //Here aL1 (i-th line) is Restriction-line and aL2 (j-th line) is
1589 //Restriction or Walking
1593 const Handle(Adaptor2d_Curve2d)& anArc2 = aRL2->IsArcOnS1() ?
1596 if(anArc2->GetType() != GeomAbs_Line)
1598 //Restriction line must be isoline.
1599 //Other cases are not supported by
1600 //existing algorithms.
1606 //aDir can be equal to one of following four values only
1607 //(because Reastriction line is boundary of rectangular surface):
1608 //either {0, 1} or {0, -1} or {1, 0} or {-1, 0}.
1609 const gp_Dir2d aDir = anArc->Line().Direction();
1611 Standard_Real aTol2d = anOtherSurf->UResolution(aTol3d),
1612 aPeriod = anOtherSurf->IsVPeriodic() ? anOtherSurf->VPeriod() : 0.0;
1614 if(Abs(aDir.X()) < 0.5)
1615 {//Restriction directs along V-direction
1616 aTol2d = anOtherSurf->VResolution(aTol3d);
1617 aPeriod = anOtherSurf->IsUPeriodic() ? anOtherSurf->UPeriod() : 0.0;
1620 const Standard_Boolean isCoincide = IsCoincide(Func, aL2, anArc, aRL1->IsArcOnS1(),
1621 aTol3d, aTol2d, aPeriod);
1626 {//Delete Walking-line
1631 {//Restriction-Restriction
1632 const Handle(Adaptor2d_Curve2d)& anArc2 = aRL2->IsArcOnS1() ?
1636 const Standard_Real aRange2 = anArc2->LastParameter() -
1637 anArc2->FirstParameter();
1638 const Standard_Real aRange1 = anArc->LastParameter() -
1639 anArc->FirstParameter();
1641 if(aRange2 > aRange1)
1643 isFirstDeleted = Standard_True;
1653 } //for(Standard_Integer j = i + 1; j <= slin.Length(); j++)
1659 }//for (Standard_Integer i = 1; i <= slin.Length(); i++)
1661 empt = (slin.Length() == 0 && spnt.Length() == 0);
1662 done = Standard_True;
1665 if(slin.Length() == 0)
1668 Standard_Boolean isDecomposeRequired = (Quad.TypeQuadric() == GeomAbs_Cone) ||
1669 (Quad.TypeQuadric() == GeomAbs_Sphere) ||
1670 (Quad.TypeQuadric() == GeomAbs_Cylinder) ||
1671 (Quad.TypeQuadric() == GeomAbs_Torus);
1673 if(!isDecomposeRequired)
1676 // post processing for cones and spheres
1678 const Handle(Adaptor3d_TopolTool)& PDomain = (reversed) ? D1 : D2;
1680 IntPatch_SequenceOfLine dslin;
1681 Standard_Boolean isDecompose = Standard_False;
1682 for(Standard_Integer i = 1; i <= slin.Length(); i++ )
1684 if(DecomposeResult( Handle(IntPatch_PointLine)::DownCast(slin(i)),
1685 reversed, Quad, PDomain, aQSurf,
1686 anOtherSurf, TolArc, aTol3d, dslin))
1688 isDecompose = Standard_True;
1696 for(Standard_Integer i = 1; i <= dslin.Length(); i++ )
1697 slin.Append(dslin(i));
1700 // correct U parameter of the start point of line on Quadric
1701 // (change 0->2PI or vs, if necessary)
1702 static Standard_Real AdjustUFirst(Standard_Real U1,Standard_Real U2)
1704 Standard_Real u = U1;
1706 // case: no adjustment
1707 if( U1 > 0. && U1 < (2.*M_PI) )
1711 if( U1 == 0. || fabs(U1) <= 1.e-9 ) {
1712 if( U2 > 0. && U2 < (2.*M_PI) )
1713 u = ( U2 < ((2.*M_PI)-U2) ) ? 0. : (2.*M_PI);
1715 Standard_Real uu = U2;
1716 if( U2 > (2.*M_PI) )
1717 while( uu > (2.*M_PI) )
1723 u = ( uu < ((2.*M_PI)-uu) ) ? 0. : (2.*M_PI);
1727 else if( U1 == (2.*M_PI) || fabs((2.*M_PI)-fabs(U1)) <= 1.e-9 ) {
1728 if( U2 > 0. && U2 < (2.*M_PI) )
1729 u = ( U2 < ((2.*M_PI)-U2) ) ? 0. : (2.*M_PI);
1731 Standard_Real uu = U2;
1732 if( U2 > (2.*M_PI) )
1733 while( uu > (2.*M_PI) )
1739 u = ( uu < ((2.*M_PI)-uu) ) ? 0. : (2.*M_PI);
1742 // case: '<0. || >2PI'
1748 while(u > (2.*M_PI))
1755 // collect vertices, reject equals
1756 static Handle(IntSurf_LineOn2S) GetVertices(const Handle(IntPatch_PointLine)& thePLine,
1757 const Standard_Real TOL3D,
1758 const Standard_Real TOL2D)
1760 // Standard_Real TOL3D = 1.e-12, TOL2D = 1.e-8;
1762 Handle(IntSurf_LineOn2S) vertices = new IntSurf_LineOn2S();
1764 Standard_Real U1 = 0., U2 = 0., V1 = 0., V2 = 0.;
1765 Standard_Integer i = 0, k = 0;
1766 Standard_Integer NbVrt = thePLine->NbVertex();
1768 TColStd_Array1OfInteger anVrts(1,NbVrt);
1771 // check equal vertices
1772 for(i = 1; i <= NbVrt; i++) {
1774 if( anVrts(i) == -1 ) continue;
1776 const IntPatch_Point& Pi = thePLine->Vertex(i);
1778 for(k = (i+1); k <= NbVrt; k++) {
1780 if( anVrts(k) == -1 ) continue;
1782 const IntPatch_Point& Pk = thePLine->Vertex(k);
1784 if(Pi.Value().Distance(Pk.Value()) <= TOL3D) {
1785 // suggest the points are equal;
1786 // test 2d parameters on surface
1787 Standard_Boolean sameU1 = Standard_False;
1788 Standard_Boolean sameV1 = Standard_False;
1789 Standard_Boolean sameU2 = Standard_False;
1790 Standard_Boolean sameV2 = Standard_False;
1792 Pi.ParametersOnS1(U1,V1);
1793 Pk.ParametersOnS1(U2,V2);
1794 if(fabs(U1-U2) <= TOL2D) sameU1 = Standard_True;
1795 if(fabs(V1-V2) <= TOL2D) sameV1 = Standard_True;
1797 Pi.ParametersOnS2(U1,V1);
1798 Pk.ParametersOnS2(U2,V2);
1799 if(fabs(U1-U2) <= TOL2D) sameU2 = Standard_True;
1800 if(fabs(V1-V2) <= TOL2D) sameV2 = Standard_True;
1802 if((sameU1 && sameV1) && (sameU2 && sameV2))
1808 // copy further processed vertices
1809 for(i = 1; i <= NbVrt; i++) {
1810 if( anVrts(i) == -1 ) continue;
1811 vertices->Add(thePLine->Vertex(i).PntOn2S());
1816 static void SearchVertices(const Handle(IntSurf_LineOn2S)& Line,
1817 const Handle(IntSurf_LineOn2S)& Vertices,
1818 TColStd_Array1OfInteger& PTypes)
1820 Standard_Integer nbp = Line->NbPoints(), nbv = Vertices->NbPoints();
1821 Standard_Integer ip = 0, iv = 0;
1822 for(ip = 1; ip <= nbp; ip++) {
1823 const IntSurf_PntOn2S& aP = Line->Value(ip);
1824 Standard_Integer type = 0;
1825 for(iv = 1; iv <= nbv; iv++) {
1826 const IntSurf_PntOn2S& aV = Vertices->Value(iv);
1827 if(aP.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
1836 static inline Standard_Boolean IsSeamParameter(const Standard_Real U,
1837 const Standard_Real TOL2D)
1839 return (fabs(U) <= TOL2D || fabs(2.*M_PI - U) <= TOL2D);
1842 static inline Standard_Real AdjustU(const Standard_Real U)
1844 Standard_Real u = U, DBLPI = 2.*M_PI;
1845 if(u < 0. || u > DBLPI) {
1856 static inline void Correct2DBounds(const Standard_Real UF,
1857 const Standard_Real UL,
1858 const Standard_Real VF,
1859 const Standard_Real VL,
1860 const Standard_Real TOL2D,
1864 Standard_Real Eps = 1.e-16;
1865 Standard_Real dUF = fabs(U - UF);
1866 Standard_Real dUL = fabs(U - UL);
1867 Standard_Real dVF = fabs(V - VF);
1868 Standard_Real dVL = fabs(V - VL);
1869 if(dUF <= TOL2D && dUF > Eps) U = UF;
1870 if(dUL <= TOL2D && dUL > Eps) U = UL;
1871 if(dVF <= TOL2D && dVF > Eps) V = VF;
1872 if(dVL <= TOL2D && dVL > Eps) V = VL;
1875 static void AdjustLine(Handle(IntSurf_LineOn2S)& Line,
1876 const Standard_Boolean IsReversed,
1877 const Handle(Adaptor3d_Surface)& QSurf,
1878 const Standard_Real TOL2D)
1880 Standard_Real VF = QSurf->FirstVParameter();
1881 Standard_Real VL = QSurf->LastVParameter();
1882 Standard_Real UF = QSurf->FirstUParameter();
1883 Standard_Real UL = QSurf->LastUParameter();
1885 Standard_Integer nbp = Line->NbPoints(), ip = 0;
1886 Standard_Real U = 0., V = 0.;
1887 for(ip = 1; ip <= nbp; ip++) {
1889 Line->Value(ip).ParametersOnS2(U,V);
1891 Correct2DBounds(UF,UL,VF,VL,TOL2D,U,V);
1892 Line->SetUV(ip,Standard_False,U,V);
1895 Line->Value(ip).ParametersOnS1(U,V);
1897 Correct2DBounds(UF,UL,VF,VL,TOL2D,U,V);
1898 Line->SetUV(ip,Standard_True,U,V);
1903 static Standard_Boolean InsertSeamVertices(Handle(IntSurf_LineOn2S)& Line,
1904 const Standard_Boolean IsReversed,
1905 Handle(IntSurf_LineOn2S)& Vertices,
1906 const TColStd_Array1OfInteger& PTypes,
1907 const Standard_Real TOL2D)
1909 Standard_Boolean result = Standard_False;
1910 Standard_Integer ip = 0, nbp = Line->NbPoints();
1911 Standard_Real U = 0., V = 0.;
1912 for(ip = 1; ip <= nbp; ip++) {
1913 Standard_Integer ipt = PTypes(ip);
1915 const IntSurf_PntOn2S& aP = Line->Value(ip);
1917 aP.ParametersOnS2(U,V); // S2 - quadric
1919 aP.ParametersOnS1(U,V); // S1 - quadric
1921 if(IsSeamParameter(U,TOL2D)) {
1922 if(ip == 1 || ip == nbp) {
1923 Standard_Real U1 = 0., V1 = 0.;
1924 Standard_Integer ipp = (ip == 1) ? (ip+1) : (ip-1);
1926 Line->Value(ipp).ParametersOnS2(U1,V1); // S2 - quadric
1928 Line->Value(ipp).ParametersOnS1(U1,V1); // S1 - quadric
1929 Standard_Real u = AdjustUFirst(U,U1);
1930 if(fabs(u-U) >= 1.5*M_PI) {
1931 Standard_Real U2 = 0., V2 = 0.;
1933 Line->Value(ip).ParametersOnS1(U2,V2); // prm
1934 Line->SetUV(ip,Standard_False,u,V);
1935 Line->SetUV(ip,Standard_True,U2,V2);
1938 Line->Value(ip).ParametersOnS2(U2,V2); // prm
1939 Line->SetUV(ip,Standard_True,u,V);
1940 Line->SetUV(ip,Standard_False,U2,V2);
1945 Standard_Integer ipp = ip - 1;
1946 Standard_Integer ipn = ip + 1;
1947 Standard_Real U1 = 0., V1 = 0., U2 = 0., V2 = 0.;
1949 Line->Value(ipp).ParametersOnS2(U1,V1); // quad
1950 Line->Value(ipn).ParametersOnS2(U2,V2); // quad
1953 Line->Value(ipp).ParametersOnS1(U1,V1); // quad
1954 Line->Value(ipn).ParametersOnS1(U2,V2); // quad
1958 Standard_Boolean pnearZero = (fabs(U1) < fabs(2.*M_PI-U1)) ? Standard_True : Standard_False;
1959 Standard_Boolean cnearZero = (fabs(U) < fabs(2.*M_PI-U)) ? Standard_True : Standard_False;
1960 if(pnearZero == cnearZero) {
1961 if(!IsSeamParameter(U2,TOL2D) && !IsSeamParameter(U1,TOL2D)) {
1962 Standard_Real nU = (cnearZero) ? (2.*M_PI) : 0.;
1964 nP.SetValue(aP.Value());
1965 Standard_Real U3 = 0., V3 = 0.;
1967 Line->Value(ip).ParametersOnS1(U3,V3); // prm
1968 nP.SetValue(Standard_False,nU,V);
1969 nP.SetValue(Standard_True,U3,V3);
1972 Line->Value(ip).ParametersOnS2(U3,V3); // prm
1973 nP.SetValue(Standard_True,nU,V);
1974 nP.SetValue(Standard_False,U3,V3);
1976 Line->InsertBefore(ipn,nP);
1978 result = Standard_True;
1983 if(!IsSeamParameter(U2,TOL2D) && !IsSeamParameter(U1,TOL2D)) {
1984 Standard_Real nU = (cnearZero) ? (2.*M_PI) : 0.;
1986 nP.SetValue(aP.Value());
1987 Standard_Real U3 = 0., V3 = 0.;
1989 Line->Value(ip).ParametersOnS1(U3,V3); // prm
1990 nP.SetValue(Standard_False,nU,V);
1991 nP.SetValue(Standard_True,U3,V3);
1994 Line->Value(ip).ParametersOnS2(U3,V3); // prm
1995 nP.SetValue(Standard_True,nU,V);
1996 nP.SetValue(Standard_False,U3,V3);
1998 Line->InsertBefore(ip,nP);
2000 result = Standard_True;
2004 // Line->InsertBefore(ip,Line->Value(ipn));
2005 // Line->RemovePoint(ip+2);
2006 // result = Standard_True;
2007 // std::cout << "swap vertex " << std::endl;
2018 static void ToSmooth( const Handle(IntSurf_LineOn2S)& Line,
2019 const Standard_Boolean IsReversed,
2020 const IntSurf_Quadric& Quad,
2021 const Standard_Boolean IsFirst,
2024 if(Line->NbPoints() <= 10)
2028 Standard_Integer NbTestPnts = Line->NbPoints() / 5;
2029 if(NbTestPnts < 5) NbTestPnts = 5;
2031 Standard_Integer startp = (IsFirst) ? 2 : (Line->NbPoints() - NbTestPnts - 2);
2032 Standard_Integer ip = 0;
2033 Standard_Real Uc = 0., Vc = 0., Un = 0., Vn = 0., DDU = 0.;
2034 //Standard_Real DDV = 0.;
2036 for(ip = startp; ip <= NbTestPnts; ip++) {
2038 Line->Value(ip).ParametersOnS2(Uc,Vc); // S2 - quadric
2039 Line->Value(ip+1).ParametersOnS2(Un,Vn);
2042 Line->Value(ip).ParametersOnS1(Uc,Vc); // S1 - quadric
2043 Line->Value(ip+1).ParametersOnS1(Un,Vn);
2045 DDU += fabs(fabs(Uc)-fabs(Un));
2046 //DDV += fabs(fabs(Vc)-fabs(Vn));
2049 Standard_Real DP = Line->Value(ip).Value().Distance(Line->Value(ip-1).Value());
2054 DDU /= (Standard_Real) NbTestPnts + 1;
2055 //DDV /= (Standard_Real) NbTestPnts + 1;
2057 D3D /= (Standard_Real) NbTestPnts + 1;
2060 Standard_Integer Index1 = (IsFirst) ? 1 : (Line->NbPoints());
2061 Standard_Integer Index2 = (IsFirst) ? 2 : (Line->NbPoints()-1);
2062 Standard_Integer Index3 = (IsFirst) ? 3 : (Line->NbPoints()-2);
2064 Standard_Boolean doU = Standard_False;
2066 Standard_Real U1 = 0., U2 = 0., V1 = 0., V2 = 0., U3 = 0., V3 = 0.;
2069 Line->Value(Index1).ParametersOnS2(U1,V1); // S2 - quadric
2070 Line->Value(Index2).ParametersOnS2(U2,V2);
2071 Line->Value(Index3).ParametersOnS2(U3,V3);
2074 Line->Value(Index1).ParametersOnS1(U1,V1); // S1 - quadric
2075 Line->Value(Index2).ParametersOnS1(U2,V2);
2076 Line->Value(Index3).ParametersOnS1(U3,V3);
2079 if(!doU && Quad.TypeQuadric() == GeomAbs_Sphere) {
2080 if(fabs(fabs(U1)-fabs(U2)) > (M_PI/16.)) doU = Standard_True;
2082 if(doU && (fabs(U1) <= 1.e-9 || fabs(U1-2.*M_PI) <= 1.e-9)) {
2083 if(fabs(V1-M_PI/2.) <= 1.e-9 || fabs(V1+M_PI/2.) <= 1.e-9) {}
2085 doU = Standard_False;
2090 if(Quad.TypeQuadric() == GeomAbs_Cone) {
2091 Standard_Real Uapx = 0., Vapx = 0.;
2092 Quad.Parameters(Quad.Cone().Apex(),Uapx,Vapx);
2094 if(fabs(fabs(U1)-fabs(U2)) > M_PI/32.) doU = Standard_True;
2096 if(doU && (fabs(U1) <= 1.e-9 || fabs(U1-2.*M_PI) <= 1.e-9)) {
2097 if(fabs(V1-Vapx) <= 1.e-9) {}
2099 doU = Standard_False;
2105 Standard_Real dU = Min((DDU/10.),5.e-8);
2106 Standard_Real U = (U2 > U3) ? (U2 + dU) : (U2 - dU);
2108 Line->SetUV(Index1,Standard_False,U,V1);
2110 Line->SetUV(Index1,Standard_True,U,V1);
2115 static Standard_Boolean TestMiddleOnPrm(const IntSurf_PntOn2S& aP,
2116 const IntSurf_PntOn2S& aV,
2117 const Standard_Boolean IsReversed,
2118 const Standard_Real ArcTol,
2119 const Handle(Adaptor3d_TopolTool)& PDomain)
2122 Standard_Boolean result = Standard_False;
2123 Standard_Real Up = 0., Vp = 0., Uv = 0., Vv = 0.;
2125 aP.ParametersOnS1(Up,Vp); //S1 - parametric
2126 aV.ParametersOnS1(Uv,Vv);
2129 aP.ParametersOnS2(Up,Vp); // S2 - parametric
2130 aV.ParametersOnS2(Uv,Vv);
2132 Standard_Real Um = (Up + Uv)*0.5, Vm = (Vp + Vv)*0.5;
2133 gp_Pnt2d a2DPntM(Um,Vm);
2134 TopAbs_State PosM = PDomain->Classify(a2DPntM,ArcTol);
2135 if(PosM == TopAbs_ON || PosM == TopAbs_IN )
2136 result = Standard_True;
2140 static void VerifyVertices( const Handle(IntSurf_LineOn2S)& Line,
2141 const Standard_Boolean IsReversed,
2142 const Handle(IntSurf_LineOn2S)& Vertices,
2143 const Standard_Real TOL2D,
2144 const Standard_Real ArcTol,
2145 const Handle(Adaptor3d_TopolTool)& PDomain,
2146 IntSurf_PntOn2S& VrtF,
2147 Standard_Boolean& AddFirst,
2148 IntSurf_PntOn2S& VrtL,
2149 Standard_Boolean& AddLast)
2151 Standard_Integer nbp = Line->NbPoints(), nbv = Vertices->NbPoints();
2152 Standard_Integer FIndexSame = 0, FIndexNear = 0, LIndexSame = 0, LIndexNear = 0;
2153 const IntSurf_PntOn2S& aPF = Line->Value(1);
2154 const IntSurf_PntOn2S& aPL = Line->Value(nbp);
2155 Standard_Real UF = 0., VF = 0., UL = 0., VL = 0.;
2157 aPF.ParametersOnS2(UF,VF);
2158 aPL.ParametersOnS2(UL,VL);
2161 aPF.ParametersOnS1(UF,VF);
2162 aPL.ParametersOnS1(UL,VL);
2164 gp_Pnt2d a2DPF(UF,VF);
2165 gp_Pnt2d a2DPL(UL,VL);
2166 Standard_Real DistMinF = 1.e+100, DistMinL = 1.e+100;
2167 Standard_Integer FConjugated = 0, LConjugated = 0;
2169 Standard_Integer iv = 0;
2171 for(iv = 1; iv <= nbv; iv++) {
2172 Standard_Real Uv = 0., Vv = 0.;
2174 Vertices->Value(iv).ParametersOnS2(Uv,Vv);
2176 Vertices->SetUV(iv,Standard_False,Uv,Vv);
2179 Vertices->Value(iv).ParametersOnS1(Uv,Vv);
2181 Vertices->SetUV(iv,Standard_True,Uv,Vv);
2185 for(iv = 1; iv <= nbv; iv++) {
2186 const IntSurf_PntOn2S& aV = Vertices->Value(iv);
2187 if(aPF.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
2192 Standard_Real Uv = 0., Vv = 0.;
2194 aV.ParametersOnS2(Uv,Vv);
2196 aV.ParametersOnS1(Uv,Vv);
2197 gp_Pnt2d a2DV(Uv,Vv);
2198 Standard_Real Dist = a2DV.Distance(a2DPF);
2199 if(Dist < DistMinF) {
2202 if(FConjugated != 0)
2205 if(IsSeamParameter(Uv,TOL2D)) {
2206 Standard_Real Ucv = (fabs(Uv) < fabs(2.*M_PI-Uv)) ? (2.*M_PI) : 0.;
2207 gp_Pnt2d a2DCV(Ucv,Vv);
2208 Standard_Real CDist = a2DCV.Distance(a2DPF);
2209 if(CDist < DistMinF) {
2218 for(iv = 1; iv <= nbv; iv++) {
2219 const IntSurf_PntOn2S& aV = Vertices->Value(iv);
2220 if(aPL.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
2225 Standard_Real Uv = 0., Vv = 0.;
2227 aV.ParametersOnS2(Uv,Vv);
2229 aV.ParametersOnS1(Uv,Vv);
2230 gp_Pnt2d a2DV(Uv,Vv);
2231 Standard_Real Dist = a2DV.Distance(a2DPL);
2232 if(Dist < DistMinL) {
2235 if(LConjugated != 0)
2238 if(IsSeamParameter(Uv,TOL2D)) {
2239 Standard_Real Ucv = (fabs(Uv) < fabs(2.*M_PI-Uv)) ? (2.*M_PI) : 0.;
2240 gp_Pnt2d a2DCV(Ucv,Vv);
2241 Standard_Real CDist = a2DCV.Distance(a2DPL);
2242 if(CDist < DistMinL) {
2251 AddFirst = Standard_False;
2252 AddLast = Standard_False;
2254 if(FIndexSame == 0) {
2255 if(FIndexNear != 0) {
2256 const IntSurf_PntOn2S& aV = Vertices->Value(FIndexNear);
2257 Standard_Real Uv = 0., Vv = 0.;
2259 aV.ParametersOnS2(Uv,Vv);
2261 aV.ParametersOnS1(Uv,Vv);
2262 if(IsSeamParameter(Uv,TOL2D)) {
2263 Standard_Real Ucv = (fabs(Uv) < fabs(2.*M_PI-Uv)) ? (2.*M_PI) : 0.;
2264 Standard_Boolean test = TestMiddleOnPrm(aPF,aV,IsReversed,ArcTol,PDomain);
2266 VrtF.SetValue(aV.Value());
2268 Standard_Real U2 = 0., V2 = 0.;
2269 aV.ParametersOnS1(U2,V2); // S1 - prm
2270 VrtF.SetValue(Standard_True,U2,V2);
2271 if(FConjugated == 0)
2272 VrtF.SetValue(Standard_False,Uv,Vv);
2274 VrtF.SetValue(Standard_False,Ucv,Vv);
2277 Standard_Real U2 = 0., V2 = 0.;
2278 aV.ParametersOnS2(U2,V2); // S2 - prm
2279 VrtF.SetValue(Standard_False,U2,V2);
2280 if(FConjugated == 0)
2281 VrtF.SetValue(Standard_True,Uv,Vv);
2283 VrtF.SetValue(Standard_True,Ucv,Vv);
2285 Standard_Real Dist3D = VrtF.Value().Distance(aPF.Value());
2286 if(Dist3D > 1.5e-7 && DistMinF > TOL2D) {
2287 AddFirst = Standard_True;
2292 // to do: analyze internal vertex
2297 if(LIndexSame == 0) {
2298 if(LIndexNear != 0) {
2299 const IntSurf_PntOn2S& aV = Vertices->Value(LIndexNear);
2300 Standard_Real Uv = 0., Vv = 0.;
2302 aV.ParametersOnS2(Uv,Vv);
2304 aV.ParametersOnS1(Uv,Vv);
2305 if(IsSeamParameter(Uv,TOL2D)) {
2306 Standard_Real Ucv = (fabs(Uv) < fabs(2.*M_PI-Uv)) ? (2.*M_PI) : 0.;
2307 Standard_Boolean test = TestMiddleOnPrm(aPL,aV,IsReversed,ArcTol,PDomain);
2309 VrtL.SetValue(aV.Value());
2311 Standard_Real U2 = 0., V2 = 0.;
2312 aV.ParametersOnS1(U2,V2); // S1 - prm
2313 VrtL.SetValue(Standard_True,U2,V2);
2314 if(LConjugated == 0)
2315 VrtL.SetValue(Standard_False,Uv,Vv);
2317 VrtL.SetValue(Standard_False,Ucv,Vv);
2320 Standard_Real U2 = 0., V2 = 0.;
2321 aV.ParametersOnS2(U2,V2); // S2 - prm
2322 VrtL.SetValue(Standard_False,U2,V2);
2323 if(LConjugated == 0)
2324 VrtL.SetValue(Standard_True,Uv,Vv);
2326 VrtL.SetValue(Standard_True,Ucv,Vv);
2328 Standard_Real Dist3D = VrtL.Value().Distance(aPL.Value());
2329 if(Dist3D > 1.5e-7 && DistMinL > TOL2D) {
2330 AddLast = Standard_True;
2335 // to do: analyze internal vertex
2341 static Standard_Boolean AddVertices(Handle(IntSurf_LineOn2S)& Line,
2342 const IntSurf_PntOn2S& VrtF,
2343 const Standard_Boolean AddFirst,
2344 const IntSurf_PntOn2S& VrtL,
2345 const Standard_Boolean AddLast,
2346 const Standard_Real D3DF,
2347 const Standard_Real D3DL)
2349 Standard_Boolean result = Standard_False;
2351 Standard_Real DF = Line->Value(1).Value().Distance(VrtF.Value());
2352 if((D3DF*2.) > DF && DF > 1.5e-7) {
2353 Line->InsertBefore(1,VrtF);
2354 result = Standard_True;
2358 Standard_Real DL = Line->Value(Line->NbPoints()).Value().Distance(VrtL.Value());
2359 if((D3DL*2.) > DL && DL > 1.5e-7) {
2361 result = Standard_True;
2368 static void PutIntVertices(const Handle(IntPatch_PointLine)& Line,
2369 Handle(IntSurf_LineOn2S)& Result,
2370 Standard_Boolean theIsReversed,
2371 Handle(IntSurf_LineOn2S)& Vertices,
2372 const Standard_Real ArcTol)
2374 Standard_Integer nbp = Result->NbPoints(), nbv = Vertices->NbPoints();
2379 const Handle(IntPatch_RLine) aRLine = Handle(IntPatch_RLine)::DownCast(Line);
2381 Standard_Integer ip = 0, iv = 0;
2383 IntPatch_Point thePnt;
2384 Standard_Real U1 = 0., V1 = 0., U2 = 0., V2 = 0.;
2386 for(ip = 2; ip <= (nbp-1); ip++) {
2387 const IntSurf_PntOn2S& aP = Result->Value(ip);
2388 for(iv = 1; iv <= nbv; iv++) {
2389 const IntSurf_PntOn2S& aV = Vertices->Value(iv);
2390 if(aP.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
2391 aPnt = Result->Value(ip).Value();
2392 Result->Value(ip).ParametersOnS1(U1,V1);
2393 Result->Value(ip).ParametersOnS2(U2,V2);
2394 thePnt.SetValue(aPnt,ArcTol,Standard_False);
2395 thePnt.SetParameters(U1,V1,U2,V2);
2397 Standard_Real aParam = (Standard_Real)ip;
2399 if(!aRLine.IsNull())
2401 //In fact, aRLine is always on the parametric surface.
2402 //If (theIsReversed == TRUE) then (U1, V1) - point on
2403 //parametric surface, otherwise - point on quadric.
2404 const Handle(Adaptor2d_Curve2d)& anArc = aRLine->IsArcOnS1() ?
2408 const gp_Lin2d aLin(anArc->Line());
2413 aPSurf.SetCoord(U1, V1);
2417 aPSurf.SetCoord(U2, V2);
2420 aParam = ElCLib::Parameter(aLin, aPSurf);
2423 thePnt.SetParameter(aParam);
2424 Line->AddVertex(thePnt);
2430 static Standard_Boolean HasInternals(Handle(IntSurf_LineOn2S)& Line,
2431 Handle(IntSurf_LineOn2S)& Vertices)
2433 Standard_Integer nbp = Line->NbPoints(), nbv = Vertices->NbPoints();
2434 Standard_Integer ip = 0, iv = 0;
2435 Standard_Boolean result = Standard_False;
2440 for(ip = 2; ip <= (nbp-1); ip++) {
2441 const IntSurf_PntOn2S& aP = Line->Value(ip);
2442 for(iv = 1; iv <= nbv; iv++) {
2443 const IntSurf_PntOn2S& aV = Vertices->Value(iv);
2444 if(aP.IsSame(aV, Precision::Confusion(), Precision::PConfusion())) {
2445 result = Standard_True;
2455 static Handle(IntPatch_WLine) MakeSplitWLine (Handle(IntPatch_WLine)& WLine,
2456 Standard_Boolean Tang,
2457 IntSurf_TypeTrans Trans1,
2458 IntSurf_TypeTrans Trans2,
2459 Standard_Real ArcTol,
2460 Standard_Integer ParFirst,
2461 Standard_Integer ParLast)
2463 Handle(IntSurf_LineOn2S) SLine = WLine->Curve();
2464 Handle(IntSurf_LineOn2S) sline = new IntSurf_LineOn2S();
2466 Standard_Integer ip = 0;
2467 for(ip = ParFirst; ip <= ParLast; ip++)
2468 sline->Add(SLine->Value(ip));
2470 Handle(IntPatch_WLine) wline = new IntPatch_WLine(sline,Tang,Trans1,Trans2);
2471 wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpPrm);
2474 IntPatch_Point TPntF,TPntL;
2475 Standard_Real uu1 = 0., vv1 = 0., uu2 = 0., vv2 = 0.;
2477 aSPnt = sline->Value(1).Value();
2478 sline->Value(1).ParametersOnS1(uu1,vv1);
2479 sline->Value(1).ParametersOnS2(uu2,vv2);
2480 TPntF.SetValue(aSPnt,ArcTol,Standard_False);
2481 TPntF.SetParameters(uu1,vv1,uu2,vv2);
2482 TPntF.SetParameter(1.);
2483 wline->AddVertex(TPntF);
2484 wline->SetFirstPoint(1);
2486 aSPnt = sline->Value(sline->NbPoints()).Value();
2487 sline->Value(sline->NbPoints()).ParametersOnS1(uu1,vv1);
2488 sline->Value(sline->NbPoints()).ParametersOnS2(uu2,vv2);
2489 TPntL.SetValue(aSPnt,ArcTol,Standard_False);
2490 TPntL.SetParameters(uu1,vv1,uu2,vv2);
2491 TPntL.SetParameter((Standard_Real)sline->NbPoints());
2492 wline->AddVertex(TPntL);
2493 wline->SetLastPoint(wline->NbVertex());
2498 static Standard_Boolean SplitOnSegments(Handle(IntPatch_WLine)& WLine,
2499 Standard_Boolean Tang,
2500 IntSurf_TypeTrans Trans1,
2501 IntSurf_TypeTrans Trans2,
2502 Standard_Real ArcTol,
2503 IntPatch_SequenceOfLine& Segments)
2505 Standard_Boolean result = Standard_False;
2508 Standard_Integer nbv = WLine->NbVertex();
2510 Standard_Integer iv = 0;
2511 for(iv = 1; iv < nbv; iv++) {
2512 Standard_Integer firstPar =
2513 (Standard_Integer) WLine->Vertex(iv).ParameterOnLine();
2514 Standard_Integer lastPar =
2515 (Standard_Integer) WLine->Vertex(iv+1).ParameterOnLine();
2516 if((lastPar - firstPar) <= 1)
2519 Handle(IntPatch_WLine) splitwline = MakeSplitWLine(WLine,Tang,Trans1,Trans2,
2520 ArcTol,firstPar,lastPar);
2521 Segments.Append(splitwline);
2523 result = Standard_True;
2530 //=======================================================================
2531 //function : IsPointOnBoundary
2532 //purpose : Returns TRUE if point <theParam> matches <theBoundary +/- thePeriod>
2533 // with given tolerance criterion.
2534 // For not-periodic case, thePeriod must be equal to 0.0.
2535 //=======================================================================
2536 static Standard_Boolean IsPointOnBoundary(const Standard_Real theToler2D,
2537 const Standard_Real theBoundary,
2538 const Standard_Real thePeriod,
2539 const Standard_Real theParam)
2541 Standard_Real aDelta = Abs(theParam - theBoundary);
2542 if (thePeriod != 0.0)
2544 aDelta = fmod(aDelta, thePeriod);
2546 // 0 <= aDelta < thePeriod
2547 return ((aDelta < theToler2D) || ((thePeriod - aDelta) < theToler2D));
2550 // Here, thePeriod == 0.0, aDelta > 0.0
2552 return (aDelta < theToler2D);
2555 //=======================================================================
2556 //function : DetectOfBoundaryAchievement
2557 //purpose : Can change values of theNewLine (by adding the computed point on boundary,
2558 // which parameter will be adjusted) and theIsOnBoundary variables.
2559 //=======================================================================
2560 static void DetectOfBoundaryAchievement(const Handle(Adaptor3d_Surface)& theQSurf, // quadric
2561 const Standard_Boolean theIsReversed,
2562 const Handle(IntSurf_LineOn2S)& theSourceLine,
2563 const Standard_Integer thePointIndex,
2564 const Standard_Real theToler2D,
2565 Handle(IntSurf_LineOn2S)& theNewLine,
2566 Standard_Boolean& theIsOnBoundary)
2568 const Standard_Real aUPeriod = theQSurf->IsUPeriodic() ? theQSurf->UPeriod() : 0.0,
2569 aVPeriod = theQSurf->IsVPeriodic() ? theQSurf->VPeriod() : 0.0;
2570 const Standard_Real aUf = theQSurf->FirstUParameter(),
2571 aUl = theQSurf->LastUParameter(),
2572 aVf = theQSurf->FirstVParameter(),
2573 aVl = theQSurf->LastVParameter();
2575 const IntSurf_PntOn2S &aPPrev = theSourceLine->Value(thePointIndex - 1),
2576 &aPCurr = theSourceLine->Value(thePointIndex);
2577 Standard_Real aUPrev, aVPrev, aUCurr, aVCurr;
2580 aPPrev.ParametersOnS2(aUPrev, aVPrev); // S2 - quadric, set U,V by Pnt3D
2581 aPCurr.ParametersOnS2(aUCurr, aVCurr); // S2 - quadric, set U,V by Pnt3D
2585 aPPrev.ParametersOnS1(aUPrev, aVPrev); // S1 - quadric, set U,V by Pnt3D
2586 aPCurr.ParametersOnS1(aUCurr, aVCurr); // S1 - quadric, set U,V by Pnt3D
2589 // Ignore cases when the WLine goes along the surface boundary completely.
2591 if (IsPointOnBoundary(theToler2D, aUf, aUPeriod, aUCurr) &&
2592 !IsPointOnBoundary(theToler2D, aUf, aUPeriod, aUPrev))
2594 theIsOnBoundary = Standard_True;
2596 else if (IsPointOnBoundary(theToler2D, aUl, aUPeriod, aUCurr) &&
2597 !IsPointOnBoundary(theToler2D, aUl, aUPeriod, aUPrev))
2599 theIsOnBoundary = Standard_True;
2601 else if (IsPointOnBoundary(theToler2D, aVf, aVPeriod, aVCurr) &&
2602 !IsPointOnBoundary(theToler2D, aVf, aVPeriod, aVPrev))
2604 theIsOnBoundary = Standard_True;
2606 else if (IsPointOnBoundary(theToler2D, aVl, aVPeriod, aVCurr) &&
2607 !IsPointOnBoundary(theToler2D, aVl, aVPeriod, aVPrev))
2609 theIsOnBoundary = Standard_True;
2612 if (theIsOnBoundary)
2614 // Adjust, to avoid bad jumping of the WLine.
2616 const Standard_Real aDu = (aUPrev - aUCurr);
2617 const Standard_Real aDv = (aVPrev - aVCurr);
2618 if (aUPeriod > 0.0 && (2.0*Abs(aDu) > aUPeriod))
2620 aUCurr += Sign(aUPeriod, aDu);
2623 if (aVPeriod > 0.0 && (2.0*Abs(aDv) > aVPeriod))
2625 aVCurr += Sign(aVPeriod, aDv);
2628 IntSurf_PntOn2S aPoint = aPCurr;
2629 aPoint.SetValue(!theIsReversed, aUCurr, aVCurr);
2630 theNewLine->Add(aPoint);
2633 //=======================================================================
2634 //function : DecomposeResult
2635 //purpose : Split <theLine> in the places where it passes through seam edge
2636 // or singularity (apex of cone or pole of sphere).
2637 // This passage is detected by jump of U-parameter
2638 // from point to point.
2639 //=======================================================================
2640 static Standard_Boolean DecomposeResult(const Handle(IntPatch_PointLine)& theLine,
2641 const Standard_Boolean IsReversed,
2642 const IntSurf_Quadric& theQuad,
2643 const Handle(Adaptor3d_TopolTool)& thePDomain,
2644 const Handle(Adaptor3d_Surface)& theQSurf, //quadric
2645 const Handle(Adaptor3d_Surface)& thePSurf, //parametric
2646 const Standard_Real theArcTol,
2647 const Standard_Real theTolTang,
2648 IntPatch_SequenceOfLine& theLines)
2650 if(theLine->ArcType() == IntPatch_Restriction)
2652 const Handle(IntPatch_RLine)& aRL = Handle(IntPatch_RLine)::DownCast(theLine);
2655 const Handle(Adaptor2d_Curve2d)& anArc = aRL->IsArcOnS1() ?
2658 if(anArc->GetType() != GeomAbs_Line)
2660 //Restriction line must be isoline.
2661 //Other cases are not supported by
2662 //existing algorithms.
2664 return Standard_False;
2669 const Standard_Real aDeltaUmax = M_PI_2;
2670 const Standard_Real aTOL3D = 1.e-10,
2671 aTOL2D = Precision::PConfusion(),
2672 aTOL2DS = Precision::PConfusion();
2674 const Handle(IntSurf_LineOn2S)& aSLine = theLine->Curve();
2676 if(aSLine->NbPoints() <= 2)
2678 return Standard_False;
2681 //Deletes repeated vertices
2682 Handle(IntSurf_LineOn2S) aVLine = GetVertices(theLine,aTOL3D,aTOL2D);
2684 Handle(IntSurf_LineOn2S) aSSLine(aSLine);
2686 if(aSSLine->NbPoints() <= 1)
2687 return Standard_False;
2689 AdjustLine(aSSLine,IsReversed,theQSurf,aTOL2D);
2691 if(theLine->ArcType() == IntPatch_Walking)
2693 Standard_Boolean isInserted = Standard_True;
2696 const Standard_Integer aNbPnts = aSSLine->NbPoints();
2697 TColStd_Array1OfInteger aPTypes(1,aNbPnts);
2698 SearchVertices(aSSLine,aVLine,aPTypes);
2699 isInserted = InsertSeamVertices(aSSLine,IsReversed,aVLine,aPTypes,aTOL2D);
2703 const Standard_Integer aLindex = aSSLine->NbPoints();
2704 Standard_Integer aFindex = 1, aBindex = 0;
2706 // build WLine parts (if any)
2707 Standard_Boolean flNextLine = Standard_True;
2708 Standard_Boolean hasBeenDecomposed = Standard_False;
2709 IntPatch_SpecPntType aPrePointExist = IntPatch_SPntNone;
2711 IntSurf_PntOn2S PrePoint;
2715 flNextLine = Standard_False;
2716 Standard_Boolean isDecomposited = Standard_False;
2718 Handle(IntSurf_LineOn2S) sline = new IntSurf_LineOn2S();
2720 //if((Lindex-Findex+1) <= 2 )
2721 if((aLindex <= aFindex) && !aPrePointExist)
2723 //break of "while(flNextLine)" cycle
2729 const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aFindex);
2731 const Standard_Real aURes = theQSurf->UResolution(theArcTol),
2732 aVRes = theQSurf->VResolution(theArcTol);
2734 const Standard_Real aTol2d = (aPrePointExist == IntPatch_SPntPole) ? -1.0 :
2735 (aPrePointExist == IntPatch_SPntSeamV)? aVRes :
2736 (aPrePointExist == IntPatch_SPntSeamUV)? Max(aURes, aVRes) : aURes;
2738 if(IntPatch_SpecialPoints::ContinueAfterSpecialPoint(theQSurf, thePSurf, aRefPt,
2739 aPrePointExist, aTol2d,
2740 PrePoint, IsReversed))
2742 sline->Add(PrePoint);
2744 //Avoid adding duplicate points.
2745 for (;aFindex <= aLindex; aFindex++)
2747 if (!PrePoint.IsSame(aSSLine->Value(aFindex), theTolTang))
2755 //break of "while(flNextLine)" cycle
2760 aPrePointExist = IntPatch_SPntNone;
2762 // analyze other points
2763 for(Standard_Integer k = aFindex; k <= aLindex; k++)
2767 PrePoint = aSSLine->Value(k);
2768 sline->Add(PrePoint);
2772 //Check whether the current point is on the boundary of theQSurf.
2773 //If that is TRUE then the Walking-line will be decomposed in this point.
2774 //However, this boundary is not singular-point (like seam or pole of sphere).
2775 //Therefore, its processing will be simplified.
2776 Standard_Boolean isOnBoundary = Standard_False;
2778 // Values of sline and isOnBoundary can be changed by this function
2779 DetectOfBoundaryAchievement(theQSurf, IsReversed, aSSLine,
2780 k, aTOL2D, sline, isOnBoundary);
2782 aPrePointExist = IsSeamOrPole(theQSurf, aSSLine, IsReversed,
2783 k - 1, theTolTang, aDeltaUmax);
2785 if (isOnBoundary && (aPrePointExist != IntPatch_SPntPoleSeamU))
2787 // If the considered point is on seam then its UV-parameters
2788 // are defined to within the surface period. Therefore, we can
2789 // trust already computed parameters of this point.
2790 // However, if this point (which is on the surface boundary) is
2791 // a sphere pole or cone apex then its (point's) parameters
2792 // have to be recomputed in the code below
2793 // (see IntPatch_SpecialPoints::AddSingularPole() method).
2794 // E.g. see "bugs modalg_6 bug26684_2" test case.
2796 aPrePointExist = IntPatch_SPntNone;
2799 if (aPrePointExist != IntPatch_SPntNone)
2802 isDecomposited = Standard_True;
2804 const IntSurf_PntOn2S& aRefPt = aSSLine->Value(aBindex-1);
2806 Standard_Real aCompareTol3D = Precision::Confusion();
2807 Standard_Real aCompareTol2D = Precision::PConfusion();
2809 IntSurf_PntOn2S aNewPoint = aRefPt;
2810 IntPatch_SpecPntType aLastType = IntPatch_SPntNone;
2812 if(aPrePointExist == IntPatch_SPntSeamUV)
2814 aPrePointExist = IntPatch_SPntNone;
2815 aLastType = IntPatch_SPntSeamUV;
2816 IntPatch_SpecialPoints::AddCrossUVIsoPoint(theQSurf, thePSurf,
2818 aNewPoint, IsReversed);
2820 else if(aPrePointExist == IntPatch_SPntSeamV)
2821 {//WLine goes through seam
2822 aPrePointExist = IntPatch_SPntNone;
2823 aLastType = IntPatch_SPntSeamV;
2826 Standard_Real aU0 = 0.0, aV0 = 0.0;
2828 Standard_Real aUQuadRef = 0.0, aVQuadRef = 0.0;
2832 aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef);
2836 aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0);
2839 math_Vector aTol(1, 3), aStartPoint(1,3),
2840 anInfBound(1, 3), aSupBound(1, 3);
2842 //Parameters on parametric surface
2843 Standard_Real aUp = 0.0, aVp = 0.0, aUq = 0.0, aVq = 0.0;
2846 aSSLine->Value(k).Parameters(aUp, aVp, aUq, aVq);
2850 aSSLine->Value(k).Parameters(aUq, aVq, aUp, aVp);
2853 aTol(1) = thePSurf->UResolution(theArcTol);
2854 aTol(2) = thePSurf->VResolution(theArcTol);
2855 aTol(3) = theQSurf->UResolution(theArcTol);
2856 aStartPoint(1) = 0.5*(aU0 + aUp);
2857 aStartPoint(2) = 0.5*(aV0 + aVp);
2858 aStartPoint(3) = 0.5*(aUQuadRef + aUq);
2859 anInfBound(1) = thePSurf->FirstUParameter();
2860 anInfBound(2) = thePSurf->FirstVParameter();
2861 anInfBound(3) = theQSurf->FirstUParameter();
2862 aSupBound(1) = thePSurf->LastUParameter();
2863 aSupBound(2) = thePSurf->LastVParameter();
2864 aSupBound(3) = theQSurf->LastUParameter();
2866 IntPatch_SpecialPoints::
2867 AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_False, 0.0,
2868 aTol, aStartPoint, anInfBound, aSupBound,
2869 aNewPoint, IsReversed);
2871 else if(aPrePointExist == IntPatch_SPntPoleSeamU)
2873 aPrePointExist = IntPatch_SPntNone;
2875 IntPatch_Point aVert;
2876 aVert.SetValue(aRefPt);
2877 aVert.SetTolerance(theTolTang);
2879 if(IntPatch_SpecialPoints::
2880 AddSingularPole(theQSurf, thePSurf, aRefPt,
2881 aVert, aNewPoint, IsReversed))
2883 aPrePointExist = IntPatch_SPntPole;
2884 aLastType = IntPatch_SPntPole;
2887 // It is necessary to replace earlier added point on
2888 // the surface boundary with the pole. For that,
2889 // here we delete excess point. New point will be added later.
2890 isOnBoundary = Standard_False;
2891 sline->RemovePoint(sline->NbPoints());
2894 aCompareTol2D = -1.0;
2895 } //if(IntPatch_AddSpecialPoints::AddSingularPole(...))
2897 {//Pole is not an intersection point
2898 aPrePointExist = IntPatch_SPntSeamU;
2902 if(aPrePointExist == IntPatch_SPntSeamU)
2903 {//WLine goes through seam
2904 aPrePointExist = IntPatch_SPntNone;
2905 aLastType = IntPatch_SPntSeamU;
2908 Standard_Real aU0 = 0.0, aV0 = 0.0;
2910 Standard_Real aUQuadRef = 0.0, aVQuadRef = 0.0;
2914 aRefPt.Parameters(aU0, aV0, aUQuadRef, aVQuadRef);
2918 aRefPt.Parameters(aUQuadRef, aVQuadRef, aU0, aV0);
2921 math_Vector aTol(1, 3), aStartPoint(1,3),
2922 anInfBound(1, 3), aSupBound(1, 3);
2924 //Parameters on parametric surface
2925 Standard_Real aUp = 0.0, aVp = 0.0, aUq = 0.0, aVq = 0.0;
2928 aSSLine->Value(k).Parameters(aUp, aVp, aUq, aVq);
2932 aSSLine->Value(k).Parameters(aUq, aVq, aUp, aVp);
2935 aTol(1) = thePSurf->UResolution(theArcTol);
2936 aTol(2) = thePSurf->VResolution(theArcTol);
2937 aTol(3) = theQSurf->VResolution(theArcTol);
2938 aStartPoint(1) = 0.5*(aU0 + aUp);
2939 aStartPoint(2) = 0.5*(aV0 + aVp);
2940 aStartPoint(3) = 0.5*(aVQuadRef + aVq);
2941 anInfBound(1) = thePSurf->FirstUParameter();
2942 anInfBound(2) = thePSurf->FirstVParameter();
2943 anInfBound(3) = theQSurf->FirstVParameter();
2944 aSupBound(1) = thePSurf->LastUParameter();
2945 aSupBound(2) = thePSurf->LastVParameter();
2946 aSupBound(3) = theQSurf->LastVParameter();
2948 IntPatch_SpecialPoints::
2949 AddPointOnUorVIso(theQSurf, thePSurf, aRefPt, Standard_True, 0.0, aTol,
2950 aStartPoint, anInfBound, aSupBound, aNewPoint,
2954 if(!aNewPoint.IsSame(aRefPt, aCompareTol3D, aCompareTol2D))
2959 sline->Add(aNewPoint);
2960 aPrePointExist = aLastType;
2961 PrePoint = aNewPoint;
2965 if (isOnBoundary || (sline->NbPoints() == 1))
2967 //FIRST point of the sline is the pole of the quadric.
2968 //Therefore, there is no point in decomposition.
2970 // If the considered point is on surface boundary then
2971 // it is already marked as vertex. So, decomposition is
2972 // not required, too.
2975 aPrePointExist = isOnBoundary ? IntPatch_SPntNone : aLastType;
2981 } //if (aPrePointExist != IntPatch_SPntNone) cond.
2983 PrePoint = aSSLine->Value(k);
2988 isDecomposited = Standard_True;
2989 aPrePointExist = IntPatch_SPntNone;
2994 sline->Add(aSSLine->Value(k));
2996 } //for(Standard_Integer k = aFindex; k <= aLindex; k++)
2998 //Creation of new line as part of existing theLine.
2999 //This part is defined by sline.
3001 if(sline->NbPoints() == 1)
3003 flNextLine = Standard_True;
3005 if (aFindex < aBindex)
3008 //Go to the next part of aSSLine
3009 //because we cannot create the line
3010 //with single point.
3015 IntSurf_PntOn2S aVF, aVL;
3016 Standard_Boolean addVF = Standard_False, addVL = Standard_False;
3017 VerifyVertices(sline,IsReversed,aVLine,aTOL2DS,theArcTol,
3018 thePDomain,aVF,addVF,aVL,addVL);
3020 Standard_Boolean hasInternals = HasInternals(sline,aVLine);
3022 Standard_Real D3F = 0., D3L = 0.;
3023 ToSmooth(sline,IsReversed,theQuad,Standard_True,D3F);
3024 ToSmooth(sline,IsReversed,theQuad,Standard_False,D3L);
3026 //if(D3F <= 1.5e-7 && sline->NbPoints() >=3) {
3027 // D3F = sline->Value(2).Value().Distance(sline->Value(3).Value());
3029 //if(D3L <= 1.5e-7 && sline->NbPoints() >=3) {
3030 // D3L = sline->Value(sline->NbPoints()-1).Value().Distance(sline->
3031 // Value(sline->NbPoints()-2).Value());
3036 Standard_Boolean isAdded = AddVertices(sline,aVF,addVF,aVL,addVL,D3F,D3L);
3039 ToSmooth(sline,IsReversed,theQuad,Standard_True,D3F);
3040 ToSmooth(sline,IsReversed,theQuad,Standard_False,D3L);
3044 if(theLine->ArcType() == IntPatch_Walking)
3046 IntPatch_Point aTPntF, aTPntL;
3048 Handle(IntPatch_WLine) wline =
3049 new IntPatch_WLine(sline,Standard_False,
3050 theLine->TransitionOnS1(),theLine->TransitionOnS2());
3051 wline->SetCreatingWayInfo(IntPatch_WLine::IntPatch_WLImpPrm);
3053 Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
3054 gp_Pnt aSPnt(sline->Value(1).Value());
3055 sline->Value(1).Parameters(aU1, aV1, aU2, aV2);
3056 aTPntF.SetValue(aSPnt,theArcTol,Standard_False);
3057 aTPntF.SetParameters(aU1, aV1, aU2, aV2);
3058 aTPntF.SetParameter(1.0);
3059 wline->AddVertex(aTPntF);
3060 wline->SetFirstPoint(1);
3064 PutIntVertices(wline,sline,IsReversed,aVLine,theArcTol);
3067 aSPnt = sline->Value(sline->NbPoints()).Value();
3068 sline->Value(sline->NbPoints()).Parameters(aU1, aV1, aU2, aV2);
3069 aTPntL.SetValue(aSPnt,theArcTol,Standard_False);
3070 aTPntL.SetParameters(aU1, aV1, aU2, aV2);
3071 aTPntL.SetParameter(sline->NbPoints());
3072 wline->AddVertex(aTPntL);
3073 wline->SetLastPoint(wline->NbVertex());
3075 IntPatch_SequenceOfLine segm;
3076 Standard_Boolean isSplited = SplitOnSegments(wline,Standard_False,
3077 theLine->TransitionOnS1(),theLine->TransitionOnS2(),theArcTol,segm);
3081 theLines.Append(wline);
3085 Standard_Integer nbsegms = segm.Length();
3086 Standard_Integer iseg = 0;
3087 for(iseg = 1; iseg <= nbsegms; iseg++)
3088 theLines.Append(segm(iseg));
3092 {//theLine->ArcType() == IntPatch_Restriction
3093 if(!isDecomposited && !hasBeenDecomposed)
3095 //The line has not been changed
3096 theLines.Append(Handle(IntPatch_RLine)::DownCast(theLine));
3097 return hasBeenDecomposed;
3100 IntPatch_Point aTPnt;
3104 Handle(IntPatch_RLine) aRLine = new IntPatch_RLine(*Handle(IntPatch_RLine)::DownCast(theLine));
3106 aRLine->ClearVertexes();
3107 aRLine->SetCurve(sline);
3111 PutIntVertices(aRLine,sline,IsReversed,aVLine,theArcTol);
3114 const Handle(Adaptor2d_Curve2d)& anArc = aRLine->IsArcOnS1() ?
3118 Standard_Real aFPar = anArc->FirstParameter(),
3119 aLPar = anArc->LastParameter();
3121 const IntSurf_PntOn2S &aRFirst = sline->Value(1),
3122 &aRLast = sline->Value(sline->NbPoints());
3124 const gp_Lin2d aLin(anArc->Line());
3126 for(Standard_Integer aFLIndex = 0; aFLIndex < 2; aFLIndex++)
3128 Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
3131 aRFirst.Parameters(aU1, aV1, aU2, aV2);
3132 aSPnt.SetXYZ(aRFirst.Value().XYZ());
3136 aRLast.Parameters(aU1, aV1, aU2, aV2);
3137 aSPnt.SetXYZ(aRLast.Value().XYZ());
3142 aPSurf.SetCoord(aU1, aV1);
3146 aPSurf.SetCoord(aU2, aV2);
3149 Standard_Real aPar = ElCLib::Parameter(aLin, aPSurf);
3153 aFPar = Max(aFPar, aPar);
3158 aLPar = Min(aLPar, aPar);
3162 aTPnt.SetParameter(aPar);
3163 aTPnt.SetValue(aSPnt,theArcTol,Standard_False);
3164 aTPnt.SetParameters(aU1, aV1, aU2, aV2);
3166 aRLine->AddVertex(aTPnt);
3169 if(aLPar - aFPar > Precision::PConfusion())
3171 aRLine->SetFirstPoint(1);
3172 aRLine->SetLastPoint(aRLine->NbVertex());
3174 anArc->Trim(aFPar, aLPar, theArcTol);
3176 theLines.Append(aRLine);
3183 flNextLine = hasBeenDecomposed = Standard_True;
3187 return hasBeenDecomposed;
3190 //=======================================================================
3191 //function : CheckSegmSegm
3192 //purpose : Returns TRUE if the segment [theParF, theParL] is included
3193 // in the segment [theRefParF, theRefParL] segment.
3194 //=======================================================================
3195 static Standard_Boolean CheckSegmSegm(const Standard_Real theRefParF,
3196 const Standard_Real theRefParL,
3197 const Standard_Real theParF,
3198 const Standard_Real theParL)
3200 if((theParF < theRefParF) || (theParF > theRefParL))
3202 return Standard_False;
3205 if((theParL < theRefParF) || (theParL > theRefParL))
3207 return Standard_False;
3210 return Standard_True;
3213 //=======================================================================
3214 //function : IsCoincide
3215 //purpose : Check, if theLine is coincided with theArc (in 2d-space).
3218 // Cases when theArc is not 2d-line adaptor are supported by
3219 // TopOpeBRep classes only (i.e. are archaic).
3220 //=======================================================================
3221 Standard_Boolean IsCoincide(IntPatch_TheSurfFunction& theFunc,
3222 const Handle(IntPatch_PointLine)& theLine,
3223 const Handle(Adaptor2d_Curve2d)& theArc,
3224 const Standard_Boolean isTheSurface1Using, //Surf1 is parametric?
3225 const Standard_Real theToler3D,
3226 const Standard_Real theToler2D,
3227 const Standard_Real thePeriod) // Period of parametric surface in direction which is perpendicular to theArc direction.
3229 const Standard_Real aCoeffs[] = { 0.02447174185, 0.09549150281, 0.20610737385, 0.34549150281, /*Sin(x)*Sin(x)*/
3230 0.5, 0.65450849719, 0.79389262615 };
3231 if(theLine->ArcType() == IntPatch_Restriction)
3232 {//Restriction-restriction processing
3233 const Handle(IntPatch_RLine)& aRL2 = Handle(IntPatch_RLine)::DownCast(theLine);
3234 const Handle(Adaptor2d_Curve2d)& anArc = aRL2->IsArcOnS1() ? aRL2->ArcOnS1() : aRL2->ArcOnS2();
3236 if(anArc->GetType() != GeomAbs_Line)
3238 //Restriction line must be isoline.
3239 //Other cases are not supported by
3240 //existing algorithms.
3242 return Standard_False;
3245 const gp_Lin2d aLin1(theArc->Line()),
3246 aLin2(anArc->Line());
3248 if(!aLin1.Direction().IsParallel(aLin2.Direction(), Precision::Angular()))
3250 return Standard_False;
3253 const Standard_Real aDist =
3254 theArc->Line().Distance(anArc->Line());
3255 if((aDist < theToler2D) || (Abs(aDist - thePeriod) < theToler2D))
3257 const Standard_Real aRf = theArc->FirstParameter(),
3258 aRl = theArc->LastParameter();
3259 const Standard_Real aParf = anArc->FirstParameter(),
3260 aParl = anArc->LastParameter();
3261 const gp_Pnt2d aP1(ElCLib::Value(aParf, aLin2)),
3262 aP2(ElCLib::Value(aParl, aLin2));
3264 Standard_Real aParam1 = ElCLib::Parameter(aLin1, aP1),
3265 aParam2 = ElCLib::Parameter(aLin1, aP2);
3267 if(CheckSegmSegm(aRf, aRl, aParam1, aParam2))
3268 return Standard_True;
3270 //Lines are parallel. Therefore, there is no point in
3271 //projecting points to another line in order to check
3272 //if segment second line is included in segment of first one.
3274 return CheckSegmSegm(aParam1, aParam2, aRf, aRl);
3277 return Standard_False;
3280 const Standard_Integer aNbPnts = theLine->NbPnts();
3281 const Standard_Real aUAf = theArc->FirstParameter(),
3282 aUAl = theArc->LastParameter();
3283 const gp_Lin2d anArcLin(theArc->Line());
3285 math_Vector aX(1, 2), aVal(1, 1);
3287 for(Standard_Integer aPtID = 1; aPtID <= aNbPnts; aPtID++)
3289 Standard_Real aUf = 0.0, aVf = 0.0;
3290 if(isTheSurface1Using)
3291 theLine->Point(aPtID).ParametersOnS1(aUf, aVf);
3293 theLine->Point(aPtID).ParametersOnS2(aUf, aVf);
3295 //Take 2d-point in parametric surface (because theArc is
3296 //2d-line in parametric surface).
3297 const gp_Pnt2d aPloc(aUf, aVf);
3299 const Standard_Real aRParam = ElCLib::Parameter(anArcLin, aPloc);
3301 if((aRParam < aUAf) || (aRParam > aUAl))
3302 return Standard_False;
3304 const gp_Pnt2d aPmin(ElCLib::Value(aRParam, anArcLin));
3306 const Standard_Real aDist = aPloc.Distance(aPmin);
3307 if((aDist < theToler2D) || (Abs(aDist - thePeriod) < theToler2D))
3308 {//Considered point is in Restriction line.
3309 //Go to the next point.
3313 //Check if intermediate points between aPloc and theArc are
3314 //intersection point (i.e. if aPloc is in tangent zone between
3315 //two intersected surfaces).
3317 const Standard_Real aUl = aPmin.X(), aVl = aPmin.Y();
3319 Standard_Real aU, aV;
3320 Standard_Real dU = aUl - aUf, dV = aVl - aVf;
3321 for(Standard_Integer i = 0; i < 7; i++)
3323 aU = aUf + aCoeffs[i] * dU;
3324 aV = aVf + aCoeffs[i] * dV;
3329 if(!theFunc.Value(aX, aVal))
3331 return Standard_False;
3334 if(Abs(theFunc.Root()) > theToler3D)
3336 return Standard_False;
3341 return Standard_True;