1 // Created on: 1993-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 // ----------------------------------------------------------------------
23 //-- lbr: Modifs importantes du 16-17 Nov 95
24 //-- - Chercher APointOnRstStillExist et OnDifferentRst
25 //-- On veut pouvoir creer un Vtx (A1 sur S1, A2 sur S2)
26 //-- et le Vtx (A1 sur S1, A2bis sur S2)
27 //-- ce qui revient a distinguer un point deja pose sur une
28 //-- restriction de S avec un point pose sur une nouvelle
29 //-- restriction de S.
30 //-- - Pour rester coherent avec cette facon de faire,
31 //-- Chercher(Nbvtx++).
33 #include <IntPatch_RstInt.ixx>
35 #include <IntSurf.hxx>
37 #include <TColgp_SequenceOfPnt.hxx>
38 #include <TColgp_SequenceOfPnt2d.hxx>
39 #include <Intf_SectionPoint.hxx>
40 #include <Intf_TangentZone.hxx>
41 #include <gp_Pnt2d.hxx>
42 #include <Precision.hxx>
44 #include <Adaptor2d_HCurve2d.hxx>
45 #include <IntPatch_WLine.hxx>
46 #include <IntPatch_RLine.hxx>
47 #include <IntPatch_HInterTool.hxx>
48 #include <IntPatch_SearchPnt.hxx>
49 #include <IntPatch_PolyLine.hxx>
50 #include <IntPatch_PolyArc.hxx>
51 #include <IntPatch_CSFunction.hxx>
52 #include <IntPatch_CurvIntSurf.hxx>
54 #define myInfinite 1.e15 // the same as was in Adaptor3d_TopolTool
56 static void Recadre(GeomAbs_SurfaceType typeS1,
57 GeomAbs_SurfaceType typeS2,
58 const Handle(IntPatch_WLine)& wlin,
59 Standard_Integer Param,
65 Standard_Integer nbpnts = wlin->NbPnts();
66 if(Param<1) Param=1; else if(Param>nbpnts) Param=nbpnts;
67 Standard_Real U1p,V1p,U2p,V2p;
69 wlin->Point(Param).Parameters(U1p,V1p,U2p,V2p);
71 case GeomAbs_Cylinder:
75 while(U1<(U1p-1.5*M_PI)) U1+=M_PI+M_PI;
76 while(U1>(U1p+1.5*M_PI)) U1-=M_PI+M_PI;
81 if(typeS1==GeomAbs_Torus) {
82 while(V1<(V1p-1.5*M_PI)) V1+=M_PI+M_PI;
83 while(V1>(V1p+1.5*M_PI)) V1-=M_PI+M_PI;
87 case GeomAbs_Cylinder:
91 while(U2<(U2p-1.5*M_PI)) U2+=M_PI+M_PI;
92 while(U2>(U2p+1.5*M_PI)) U2-=M_PI+M_PI;
97 if(typeS2==GeomAbs_Torus) {
98 while(V2<(V1p-1.5*M_PI)) V2+=M_PI+M_PI;
99 while(V2>(V2p+1.5*M_PI)) V2-=M_PI+M_PI;
103 const Standard_Real Confusion = Precision::Confusion();
105 inline Standard_Real Tol3d (const Handle(Adaptor3d_HVertex)& vtx,
106 const Handle(Adaptor3d_TopolTool)& Domain,
107 const Standard_Real tolDef = 0.)
109 return (Domain->Has3d() ? Domain->Tol3d(vtx)
110 : tolDef < Confusion ? Confusion
114 inline Standard_Real Tol3d (const Handle(Adaptor2d_HCurve2d)& arc,
115 const Handle(Adaptor3d_TopolTool)& Domain,
116 const Standard_Real tolDef = 0.)
118 return (Domain->Has3d() ? Domain->Tol3d(arc)
119 : tolDef < Confusion ? Confusion
123 static Standard_Boolean CoincideOnArc(const gp_Pnt& Ptsommet,
124 const Handle(Adaptor2d_HCurve2d)& A,
125 const Handle(Adaptor3d_HSurface)& Surf,
126 const Standard_Real Toler,
127 const Handle(Adaptor3d_TopolTool)& Domain,
128 Handle(Adaptor3d_HVertex)& Vtx)
130 Standard_Real distmin = RealLast();
131 Standard_Real tolarc = Max(Toler,Tol3d(A,Domain));
133 Domain->Initialize(A);
134 Domain->InitVertexIterator();
135 while (Domain->MoreVertex()) {
136 Handle(Adaptor3d_HVertex) vtx1 = Domain->Vertex();
137 Standard_Real prm = IntPatch_HInterTool::Parameter(vtx1,A);
138 gp_Pnt2d p2d = A->Value(prm);
139 gp_Pnt point = Surf->Value(p2d.X(),p2d.Y());
140 const Standard_Real dist = point.Distance(Ptsommet);
141 Standard_Real tol = Max (tolarc, Tol3d(vtx1,Domain));
143 if (dist <= tol && dist <= distmin) { // the best coincidence
147 Domain->NextVertex();
149 return distmin < RealLast();
153 static void VerifyTgline(const Handle(IntPatch_WLine)& wlin,
154 const Standard_Integer param,
155 const Standard_Real Tol,
160 && Abs(Tgl.Z())<Tol) {
161 //-- On construit une tangente plus grande
162 //-- (Eviter des points tres proches ds Walking)
163 Standard_Integer i, n, nbpt=wlin->NbPnts();
164 Standard_Boolean forward = (nbpt-param) >= (param-1);
165 for (n = 2; n > 0; n--, forward = !forward) {
167 for(i=param+1; i<=nbpt; i++) {
168 gp_Vec T(wlin->Point(param).Value(),wlin->Point(i).Value());
171 || Abs(T.Z())>=Tol) {
178 for(i=param-1; i>=1; i--) {
179 gp_Vec T(wlin->Point(i).Value(),wlin->Point(param).Value());
182 || Abs(T.Z())>=Tol) {
192 static void GetLinePoint2d (const Handle(IntPatch_Line)& L,
193 const Standard_Real param,
194 const Standard_Boolean OnFirst,
195 Standard_Real& U, Standard_Real& V)
197 IntPatch_IType typL = L->ArcType();
198 const Handle(IntPatch_WLine)& wlin = (const Handle(IntPatch_WLine)&)L;
199 const Handle(IntPatch_RLine)& rlin = (const Handle(IntPatch_RLine)&)L;
200 Standard_Integer Nbptlin = (typL == IntPatch_Walking
204 Standard_Real par = IntegerPart(param);
205 Standard_Integer Irang = Standard_Integer(par);
206 if (Irang == Nbptlin) {
211 par = Abs(param-par);
213 Standard_Real us1,vs1,us2,vs2;
214 if (typL == IntPatch_Walking) {
216 wlin->Point(Irang).ParametersOnS1(us1,vs1);
217 wlin->Point(Irang+1).ParametersOnS1(us2,vs2);
220 wlin->Point(Irang).ParametersOnS2(us1,vs1);
221 wlin->Point(Irang+1).ParametersOnS2(us2,vs2);
226 rlin->Point(Irang).ParametersOnS1(us1,vs1);
227 rlin->Point(Irang+1).ParametersOnS1(us2,vs2);
230 rlin->Point(Irang).ParametersOnS2(us1,vs1);
231 rlin->Point(Irang+1).ParametersOnS2(us2,vs2);
235 U = (1.-par)*us1+par*us2;
236 V = (1.-par)*vs1+par*vs2;
239 static void GetWLinePoint (const Handle(IntPatch_WLine)& wlin,
240 const Standard_Real param,
241 Standard_Real& U1, Standard_Real& V1,
242 Standard_Real& U2, Standard_Real& V2,
245 Standard_Integer Nbptlin = wlin->NbPnts();
246 Standard_Real par = IntegerPart(param);
247 Standard_Integer Irang = Standard_Integer(par);
248 if (Irang == Nbptlin) {
253 par = Abs(param-par);
255 const IntSurf_PntOn2S& p2s1 = wlin->Point(Irang);
256 const IntSurf_PntOn2S& p2s2 = wlin->Point(Irang+1);
257 const gp_Pnt& p1 = p2s1.Value();
258 const gp_Pnt& p2 = p2s2.Value();
259 P.ChangeCoord().SetLinearForm(1.-par, p1.XYZ(), par, p2.XYZ());
261 Standard_Real us1,vs1,us2,vs2;
262 p2s1.ParametersOnS1(us1,vs1);
263 p2s2.ParametersOnS1(us2,vs2);
264 U1 = (1.-par)*us1+par*us2;
265 V1 = (1.-par)*vs1+par*vs2;
267 p2s1.ParametersOnS2(us1,vs1);
268 p2s2.ParametersOnS2(us2,vs2);
269 U2 = (1.-par)*us1+par*us2;
270 V2 = (1.-par)*vs1+par*vs2;
273 static Standard_Boolean FindParameter(const Handle(IntPatch_Line)& L,
274 const Handle(Adaptor3d_HSurface)& OtherSurf,
275 const Standard_Real Tol,
277 const gp_Pnt2d& Ptsom2d,
278 Standard_Real& Param,
280 const Standard_Integer ParamApproche,
281 const Standard_Boolean OnFirst)
284 // MSV 28.03.2002: find parameter on WLine in 2d space
286 //Si la ligne est de type restriction, c est qu on provient necessairement
287 // du cas implicite/parametree, et que la ligne est restriction de
288 // la surface bi-parametree. Cette surface bi-parametree est necessairement
289 // passee en argument a PutVertexOnline dans la variable OtherSurf.
291 // Dans le cas d une ligne de cheminement, il faudrait voir la projection
292 // et le calcul de la tangente.
294 const Handle(IntPatch_RLine)& rlin = (*((Handle(IntPatch_RLine)*)&L)); //-- aucune verification n est
295 const Handle(IntPatch_WLine)& wlin = (*((Handle(IntPatch_WLine)*)&L)); //-- faite au cast.
300 Standard_Real Tol2 = Tol*Tol;
301 IntPatch_IType typL = L->ArcType();
302 Tgl.SetCoord(0.0,0.0,0.0);
304 if ( typL == IntPatch_Restriction) {
305 if (!OnFirst && rlin->IsArcOnS1()) {
306 IntPatch_HInterTool::Project(rlin->ArcOnS1(),Ptsom2d,Param,p2d);
307 rlin->ArcOnS1()->D1(Param,p2d,d2d);
309 else if (OnFirst && rlin->IsArcOnS2()) {
310 IntPatch_HInterTool::Project(rlin->ArcOnS2(),Ptsom2d,Param,p2d);
311 rlin->ArcOnS2()->D1(Param,p2d,d2d);
314 return(Standard_False);
316 OtherSurf->D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
317 if (ptbid.SquareDistance(Ptsom) > Tol2) {
318 return Standard_False;
320 Tgl.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
321 return(Standard_True);
324 else if (typL == IntPatch_Walking) {
325 Standard_Integer i, is, nbpt=wlin->NbPnts();
326 Standard_Real norm1,norm2;
327 Standard_Integer ParamSearchInf=1;
328 Standard_Integer ParamSearchSup=nbpt;
330 if((ParamApproche-2) > ParamSearchInf) {
331 ParamSearchInf = ParamApproche-2;
333 if((ParamApproche+2) < ParamSearchSup) {
334 ParamSearchSup = ParamApproche+2;
337 Standard_Integer inf[3],sup[3];
338 // first search inside close bounding around ParamApproche;
339 // then search to the nearest end of line;
340 // and then search to the farest end of line.
341 inf[0] = ParamSearchInf; sup[0] = ParamSearchSup;
342 if (ParamSearchInf-1 < nbpt-ParamSearchSup) {
343 inf[1] = 1; sup[1] = ParamSearchInf;
344 inf[2] = ParamSearchSup; sup[2] = nbpt;
347 inf[1] = ParamSearchSup; sup[1] = nbpt;
348 inf[2] = 1; sup[2] = ParamSearchInf;
351 Standard_Boolean found = Standard_False;
352 for (is=0; is < 3 && !found; is++) {
355 p1 = wlin->Point(inf[is]).Value();
356 v1 = gp_Vec (Ptsom,p1);
357 norm1 = v1.SquareMagnitude();
358 Standard_Real normmin = Tol2;
359 Standard_Integer ibest = 0;
360 if (norm1 <= normmin) {
364 for (i=inf[is]+1; i <= sup[is] && !found; i++) {
365 p2 = wlin->Point(i).Value();
366 v2 = gp_Vec (Ptsom,p2);
367 norm2 = v2.SquareMagnitude();
368 if (v1.Dot(v2) < 0.) {
369 Param = (Standard_Real)(i-1) + 1./(1.+Sqrt(norm2/norm1));
370 Tgl = gp_Vec (p1,p2);
371 found = Standard_True;
373 else if (norm2 < normmin) {
377 v1 = v2; p1 = p2; norm1 = norm2;
379 if (!found && ibest) {
380 Param = (Standard_Real)ibest;
381 found = Standard_True;
384 if (found) return Standard_True;
387 Standard_DomainError::Raise();
389 return Standard_False;
392 inline Standard_Boolean ArePnt2dEqual(const gp_Pnt2d& p1, const gp_Pnt2d& p2,
393 const Standard_Real tolU,
394 const Standard_Real tolV)
396 return Abs(p1.X()-p2.X()) < tolU && Abs(p1.Y()-p2.Y()) < tolV;
399 static gp_Pnt2d GetPointOnPolygo(const IntPatch_Polygo& Pol,
400 const Standard_Real param)
402 Standard_Real par = IntegerPart(param);
403 Standard_Integer irang = Standard_Integer(par) + 1;
404 if (irang == Pol.NbPoints()) {
409 par = Abs(param-par);
411 gp_Pnt2d p1 = Pol.Point(irang);
412 gp_Pnt2d p2 = Pol.Point(irang+1);
414 p.ChangeCoord().SetLinearForm(1.-par,p1.XY(),par,p2.XY());
418 static Standard_Boolean IsSegment2dSmall(const IntPatch_Polygo& Pol,
419 const Standard_Real parmin,
420 const Standard_Real parmax,
421 const Standard_Real URes,
422 const Standard_Real VRes)
424 Standard_Integer irang1 = Standard_Integer(IntegerPart(parmin)) + 2;
425 Standard_Integer irang2 = Standard_Integer(IntegerPart(parmax)) + 1;
427 Standard_Real du=0.,dv=0.;
428 p1 = GetPointOnPolygo(Pol,parmin);
429 for (Standard_Integer i=irang1; i <= irang2 && du <= URes && dv <= VRes; i++) {
431 du += Abs(p2.X()-p1.X());
432 dv += Abs(p2.Y()-p1.Y());
435 if (du <= URes && dv <= VRes) {
436 p2 = GetPointOnPolygo(Pol,parmax);
437 du += Abs(p2.X()-p1.X());
438 dv += Abs(p2.Y()-p1.Y());
440 return du <= URes && dv <= VRes;
443 //=======================================================================
444 //function : PutVertexOnLine
446 //=======================================================================
448 void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L,
449 const Handle(Adaptor3d_HSurface)& Surf,
450 const Handle(Adaptor3d_TopolTool)& Domain,
451 const Handle(Adaptor3d_HSurface)& OtherSurf,
452 const Standard_Boolean OnFirst,
453 const Standard_Real Tol )
456 // Domain est le domaine de restriction de la surface Surf.
457 // On intersectera un arc de Surf avec la surface OtherSurf.
458 // Si OnFirst = True, c est que la surface Surf correspond a la 1ere
459 // surface donnee aux algo d intersection.
461 IntPatch_SearchPnt Commun;
464 Standard_Real U1,V1,U2 = 0.,V2 = 0.;
465 Standard_Real paramarc=0.,paramline=0.;
466 Standard_Integer i,j,k;
467 TColgp_SequenceOfPnt locpt;
468 TColgp_SequenceOfPnt2d locpt2;
469 const Handle(IntPatch_RLine)& rlin = (*((Handle(IntPatch_RLine)*)&L)); //-- aucune verification n est
470 const Handle(IntPatch_WLine)& wlin = (*((Handle(IntPatch_WLine)*)&L)); //-- faite au cast.
471 Standard_Integer Nbvtx =0;
472 Standard_Integer Nbptlin =0;
473 Standard_Real tolPLin = Surf->UResolution(Precision::Confusion());
474 tolPLin = Max (tolPLin, Surf->VResolution(Precision::Confusion()));
475 tolPLin = Min (tolPLin, Precision::Confusion());
476 IntPatch_PolyLine PLin(tolPLin);
478 Standard_Real PFirst,PLast;
479 Standard_Integer NbEchant;
480 gp_Pnt ptsommet, ptbid;
481 gp_Vec tgline, tgrst, d1u, d1v, normsurf;
486 IntPatch_Point Sommet, ptline;
487 Handle(Adaptor3d_HVertex) vtxarc,vtxline;
488 Handle(Adaptor2d_HCurve2d) arc;
489 Standard_Boolean VtxOnArc, duplicate, found;
490 IntSurf_Transition transarc,transline;
492 IntPatch_IType typL = L->ArcType();
493 if (typL == IntPatch_Walking) {
494 Nbvtx = wlin->NbVertex();
495 PLin.SetWLine(OnFirst,wlin);
496 Nbptlin = wlin->NbPnts();
498 else if ( typL == IntPatch_Restriction) {
499 Nbvtx = rlin->NbVertex();
500 PLin.SetRLine(OnFirst,rlin);
501 Nbptlin = rlin->NbPnts();
504 Standard_DomainError::Raise();
506 if (!Domain->Has3d())
507 // don't use computed deflection in the mode of pure geometric intersection
510 const Standard_Boolean SurfaceIsUClosed = Surf->IsUClosed();
511 const Standard_Boolean SurfaceIsVClosed = Surf->IsVClosed();
512 const Standard_Boolean OSurfaceIsUClosed = OtherSurf->IsUClosed();
513 const Standard_Boolean OSurfaceIsVClosed = OtherSurf->IsVClosed();
514 const Standard_Boolean possiblyClosed = (SurfaceIsUClosed || SurfaceIsVClosed ||
515 OSurfaceIsUClosed || OSurfaceIsVClosed);
516 Standard_Real tolUClosed=0., tolVClosed=0., tolOUClosed=0., tolOVClosed=0.;
517 if (possiblyClosed) {
518 if (SurfaceIsUClosed)
519 tolUClosed = (Surf->LastUParameter() - Surf->FirstUParameter()) * 0.01;
520 if (SurfaceIsVClosed)
521 tolVClosed = (Surf->LastVParameter() - Surf->FirstVParameter()) * 0.01;
522 if (OSurfaceIsUClosed)
523 tolOUClosed = (OtherSurf->LastUParameter() - OtherSurf->FirstUParameter()) * 0.01;
524 if (OSurfaceIsVClosed)
525 tolOVClosed = (OtherSurf->LastVParameter() - OtherSurf->FirstVParameter()) * 0.01;
528 //------------------------------------------------------------------------
529 //-- On traite le cas ou la surface est periodique --
530 //-- il faut dans ce cas considerer la restriction --
531 //-- la restriction decalee de +-2PI --
532 //------------------------------------------------------------------------
533 const Handle(Adaptor3d_HSurface)& Surf1 = (OnFirst ? Surf : OtherSurf);
534 const Handle(Adaptor3d_HSurface)& Surf2 = (OnFirst ? OtherSurf : Surf);
535 GeomAbs_SurfaceType TypeS1 = Surf1->GetType();
536 GeomAbs_SurfaceType TypeS2 = Surf2->GetType();
537 Standard_Boolean SurfaceIsPeriodic = Standard_False;
538 Standard_Boolean SurfaceIsBiPeriodic = Standard_False;
539 GeomAbs_SurfaceType surfacetype = (OnFirst ? TypeS1 : TypeS2);
540 if( surfacetype == GeomAbs_Cylinder
541 || surfacetype == GeomAbs_Cone
542 || surfacetype == GeomAbs_Torus
543 || surfacetype == GeomAbs_Sphere) {
544 SurfaceIsPeriodic = Standard_True;
545 if(surfacetype == GeomAbs_Torus) {
546 SurfaceIsBiPeriodic = Standard_True;
550 Standard_Integer NumeroEdge=0;
552 while (Domain->More()) {
554 arc = Domain->Value();
556 // MSV Oct 15, 2001: use tolerance of this edge if possible
557 Standard_Real edgeTol = Tol3d(arc,Domain,Tol);
558 Standard_Real URes = Surf->UResolution(edgeTol);
559 Standard_Real VRes = Surf->VResolution(edgeTol);
561 IntPatch_HInterTool::Bounds(arc,PFirst,PLast);
562 if(Precision::IsNegativeInfinite(PFirst))
563 PFirst = -myInfinite;
564 if(Precision::IsPositiveInfinite(PLast))
566 //if (Precision::IsNegativeInfinite(PFirst) ||
567 // Precision::IsPositiveInfinite(PLast)) {
568 // //-- cout<<" IntPatch_RstInt::PutVertexOnLine ---> Restrictions Infinies :"<<endl;
572 Standard_Boolean isVFirst = Standard_False, isVLast = Standard_False;
573 gp_Pnt2d p2dFirst,p2dLast;
574 Standard_Real tolUFirst=0.,tolVFirst=0.,tolULast=0.,tolVLast=0.;
575 Domain->Initialize(arc);
576 for (Domain->InitVertexIterator(); Domain->MoreVertex(); Domain->NextVertex()) {
577 Handle(Adaptor3d_HVertex) vtx = Domain->Vertex();
578 Standard_Real prm = IntPatch_HInterTool::Parameter(vtx,arc);
579 if (Abs(prm - PFirst) < Precision::PConfusion()) {
580 arc->D0(PFirst,p2dFirst);
581 Standard_Real tol3d = Max (Tol3d(vtx,Domain), edgeTol);
582 tolUFirst = Surf->UResolution(tol3d);
583 tolVFirst = Surf->VResolution(tol3d);
584 isVFirst = Standard_True;
586 else if (Abs(prm - PLast) < Precision::PConfusion()) {
587 arc->D0(PLast,p2dLast);
588 Standard_Real tol3d = Max (edgeTol, Tol3d(vtx,Domain));
589 tolULast = Surf->UResolution(tol3d);
590 tolVLast = Surf->VResolution(tol3d);
591 isVLast = Standard_True;
595 Bnd_Box2d BPLin = PLin.Bounding();
597 if(SurfaceIsPeriodic) {
598 Standard_Real xmin,ymin,xmax,ymax,g;
599 BPLin.Get(xmin,ymin,xmax,ymax);
602 BPLin.Update(xmin-M_PI-M_PI,ymin,
603 xmax+M_PI+M_PI,ymax);
606 if(SurfaceIsBiPeriodic) {
607 Standard_Real xmin,ymin,xmax,ymax,g;
608 BPLin.Get(xmin,ymin,xmax,ymax);
611 BPLin.Update(xmin,ymin-M_PI-M_PI,
612 xmax,ymax+M_PI+M_PI);
616 switch(arc->GetType())
618 case GeomAbs_Line: NbEchant=10; break;
619 case GeomAbs_BezierCurve:
621 NbEchant = (3 + arc->NbPoles());
622 if(NbEchant<10) NbEchant=10;
623 else if(NbEchant>50) NbEchant=50;
626 case GeomAbs_BSplineCurve:
628 //szv:const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(arc->LastParameter() - arc->FirstParameter())/(PLast-PFirst);
629 const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(PLast-PFirst)/(arc->LastParameter() - arc->FirstParameter());
630 NbEchant = (nbs < 2.0 ? 2 : (Standard_Integer)nbs);
631 if(NbEchant<10) NbEchant=10;
632 else if (NbEchant>50) NbEchant=50;
641 IntPatch_PolyArc Brise(arc,NbEchant,PFirst,PLast,BPLin);
643 Standard_Integer IndiceOffsetBiPeriodic = 0;
644 Standard_Integer IndiceOffsetPeriodic = 0;
645 Standard_Real OffsetV = 0.0;
646 Standard_Real OffsetU = 0.0;
649 if(IndiceOffsetBiPeriodic == 1)
650 OffsetV = -M_PI-M_PI;
651 else if(IndiceOffsetBiPeriodic == 2)
655 if(IndiceOffsetPeriodic == 1)
656 OffsetU = -M_PI-M_PI;
657 else if(IndiceOffsetPeriodic == 2)
660 Brise.SetOffset(OffsetU,OffsetV);
662 static int debug_polygon2d =0;
663 if(debug_polygon2d) {
664 cout<<" ***** Numero Restriction : "<<NumeroEdge<<" *****"<<endl;
669 Commun.Perform(PLin,Brise);
672 Standard_Integer Commun_NbSectionPoints = Commun.NbSectionPoints();
673 Standard_Integer Commun_NbTangentZones = Commun.NbTangentZones();
674 Standard_Integer Commun_Section_Tangent = Commun_NbSectionPoints
675 + Commun_NbTangentZones;
676 for (i=1;i<=Commun_Section_Tangent;i++) {
677 Standard_Real W1[2],W2[2];
678 Standard_Boolean refine[2],useWL[2];
679 Standard_Integer nbpt = 1;
680 if(i<=Commun_NbSectionPoints) {
681 // intersection point
682 W1[0] = Commun.PntValue(i).ParamOnFirst();
683 W2[0] = Commun.PntValue(i).ParamOnSecond();
684 refine[0] = Standard_True;
688 Standard_Real UMinCh,UMaxCh; //-- ligne de cheminement 0..(Nbptlin-1)
689 Standard_Real UMinAr,UMaxAr; //-- polyline of arc 0..(NbEchant-1)
690 Commun.ZoneValue(i-Commun_NbSectionPoints).ParamOnFirst(UMinCh,UMaxCh);
691 Commun.ZoneValue(i-Commun_NbSectionPoints).ParamOnSecond(UMinAr,UMaxAr);
692 gp_Pnt2d p1Ar = GetPointOnPolygo(Brise,UMinAr);
693 gp_Pnt2d p2Ar = GetPointOnPolygo(Brise,UMaxAr);
694 Standard_Real tolU = URes*2.;
695 Standard_Real tolV = VRes*2.;
696 if (isVFirst && ArePnt2dEqual(p1Ar,p2dFirst,tolUFirst,tolVFirst)) {
697 tolU = Max(tolUFirst,tolU); tolV = Max(tolVFirst,tolV);
699 if (isVLast && ArePnt2dEqual(p2Ar,p2dLast,tolULast,tolVLast)) {
700 tolU = Max(tolULast,tolU); tolV = Max(tolVLast,tolV);
702 Standard_Real nptCh = UMaxCh-UMinCh;
703 Standard_Boolean isNptLow = (nptCh < 10. && nptCh < Nbptlin/100.) ||
704 (!Domain->Has3d() && Standard_Integer(nptCh)+1 < Nbptlin);
705 if (!isNptLow && !IsSegment2dSmall(Brise,UMinAr,UMaxAr,tolU,tolV)) {
707 Standard_Real UMinChP,UMaxChP,UMinArP,UMaxArP;
708 UMinChP = IntegerPart(UMinCh); UMinArP = IntegerPart(UMinAr);
709 UMaxChP = IntegerPart(UMaxCh); UMaxArP = IntegerPart(UMaxAr);
710 Standard_Integer irangCh1,irangCh2,irangAr1,irangAr2;
711 irangCh1 = Standard_Integer(UMinChP)+1; irangCh2 = Standard_Integer(UMaxChP)+1;
712 irangAr1 = Standard_Integer(UMinArP)+1; irangAr2 = Standard_Integer(UMaxArP)+1;
713 UMinChP = UMinCh - UMinChP; UMinArP = UMinAr - UMinArP;
714 //UMaxChP = UMaxCh - UMaxChP; UMaxArP = UMaxAr - UMaxArP;
715 const Standard_Real eps = 1e-10;
716 // Standard_Boolean isChExtr1 = irangCh1==1 && UMinChP<eps;
717 // Standard_Boolean isChExtr2 = irangCh2==Nbptlin;
718 Standard_Boolean isArExtr1 = irangAr1==1 && UMinArP<eps;
719 Standard_Boolean isArExtr2 = irangAr2==NbEchant;
720 // detect orientation
721 gp_Pnt2d p1Ch = GetPointOnPolygo(PLin,UMinCh);
722 Standard_Real d11 = p1Ch.SquareDistance(p1Ar);
723 Standard_Real d12 = p1Ch.SquareDistance(p2Ar);
724 Standard_Boolean sameOri = d11 < d12;
726 Standard_Boolean itmp=isArExtr1; isArExtr1=isArExtr2; isArExtr2=itmp;
727 Standard_Real dtmp=UMinAr; UMinAr=UMaxAr; UMaxAr=dtmp;
729 W1[0] = UMinCh; W1[1] = UMaxCh;
730 W2[0] = UMinAr; W2[1] = UMaxAr;
731 //refine[0] = ! (isChExtr1 || isArExtr1);
732 //refine[1] = ! (isChExtr2 || isArExtr2);
733 refine[0] = refine[1] = Standard_False;
734 useWL[0] = !isArExtr1;
735 useWL[1] = !isArExtr2;
739 // treat the middle point as an intersection point
740 W1[0] = 0.5*(UMinCh+UMaxCh);
741 W2[0] = 0.5*(UMinAr+UMaxAr);
742 refine[0] = Standard_True;
746 Standard_Boolean nbTreated = 0;
747 for (Standard_Integer ip=0; ip < nbpt; ip++) {
748 GetLinePoint2d (L, W1[ip]+1, !OnFirst, U,V);
750 if (!refine[ip] && useWL[ip]) {
751 Standard_Real aU1,aV1;
752 GetLinePoint2d (L, W1[ip]+1, OnFirst, aU1,aV1);
753 p2d.SetCoord(aU1,aV1);
754 Standard_Real paramProj;
755 if (!IntPatch_HInterTool::Project(arc,p2d,paramProj,p2d)) continue;
759 Standard_Real par = IntegerPart(W2[ip]);
760 Standard_Integer Irang = Standard_Integer(par) + 1;
761 if (Irang == Brise.NbPoints()) {
766 par =Abs(W2[ip]-par);
768 W = (1.-par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang+1);
771 Standard_Boolean refined = Standard_False;
773 //------------------------------------------------------------------------
774 //-- On a trouve un point 2d approche Ua,Va intersection de la ligne
775 //-- de cheminement et de la restriction.
777 //-- On injecte ce point ds les intersections Courbe-Surface
779 IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
780 // MSV: extend UV bounds to not miss solution near the boundary
781 Standard_Real margCoef = 0.004;
782 IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
783 if (IntCS.IsDone()) {
784 if (!IntCS.IsEmpty()) {
785 ptsommet = IntCS.Point();
786 IntCS.ParameterOnSurface(U2,V2);
787 paramarc = IntCS.ParameterOnCurve();
788 refined = Standard_True;
795 arc->D0(paramarc,p2d);
796 Surf->D0(p2d.X(),p2d.Y(),ptsommet);
799 if (!refine[ip] || refined) {
800 duplicate = Standard_False;
801 for (j=1; j<=locpt.Length();j++) {
802 if (ptsommet.Distance(locpt(j)) <= edgeTol) {
803 if (possiblyClosed) {
804 locpt2(j).Coord(U,V);
805 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
806 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
809 duplicate = Standard_True;
815 Standard_Integer ParamApproxOnLine = Standard_Integer(W1[ip])+1;
817 arc->D1(paramarc,p2d,d2d);
818 U1 = p2d.X(); V1 = p2d.Y();
819 if (typL == IntPatch_Walking && SurfaceIsPeriodic) {
821 Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2);
823 Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1);
825 locpt.Append(ptsommet);
826 locpt2.Append(gp_Pnt2d(U2,V2));
828 found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2),
829 paramline,tgline,ParamApproxOnLine,OnFirst);
831 if (typL == IntPatch_Walking && found && possiblyClosed) {
833 if (SurfaceIsUClosed || SurfaceIsVClosed) {
834 GetLinePoint2d (L, paramline, OnFirst, U,V);
835 if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
836 (SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
837 found = Standard_False;
839 if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) {
840 GetLinePoint2d (L, paramline, !OnFirst, U,V);
841 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
842 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
843 found = Standard_False;
850 VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc);
851 Standard_Real vtxTol;
853 vtxTol = Tol3d(vtxarc,Domain);
854 if (edgeTol > vtxTol) vtxTol = edgeTol;
856 else vtxTol = edgeTol;
858 //-- It is necessary to test that the point does not already exist
859 //-- - It can be already a point on arc
860 //-- BUT on a different arc
861 // MSV 27.03.2002: find the nearest point; add check in 2d
862 Standard_Integer ivtx = 0;
863 Standard_Real dmin = RealLast();
864 for (j=1; j<=Nbvtx; j++) {
865 const IntPatch_Point& Rptline = (typL == IntPatch_Walking
868 Standard_Boolean APointOnRstStillExist =
869 ((OnFirst && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc) ||
870 (!OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc));
871 if(!APointOnRstStillExist) {
872 if (possiblyClosed) {
873 if (SurfaceIsUClosed || SurfaceIsVClosed) {
874 if (OnFirst) Rptline.ParametersOnS1(U,V);
875 else Rptline.ParametersOnS2(U,V);
876 if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
877 (SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
880 if (OSurfaceIsUClosed || OSurfaceIsVClosed) {
881 if (OnFirst) Rptline.ParametersOnS2(U,V);
882 else Rptline.ParametersOnS1(U,V);
883 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
884 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
888 Standard_Real dist = ptsommet.Distance(Rptline.Value());
889 Standard_Real dt = Max(vtxTol, Rptline.Tolerance());
894 if( surfacetype == GeomAbs_Cone ) {
899 // cancel previous solution because this point is better
900 // but its tolerance is not large enough
908 if (ptline.Tolerance() > vtxTol) {
909 vtxTol = ptline.Tolerance();
911 // now we should repeat attempt to coincide on a bound of arc
912 VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc);
914 Standard_Real tol = Tol3d(vtxarc,Domain);
915 if (tol > vtxTol) vtxTol = tol;
921 if (typL == IntPatch_Walking)
922 VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline);
924 Surf->D1(U1,V1,ptbid,d1u,d1v);
925 tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
927 normsurf = d1u.Crossed(d1v);
928 if (normsurf.Magnitude() < gp::Resolution()) {
929 transline.SetValue(Standard_True,IntSurf_Undecided);
930 transarc.SetValue(Standard_True,IntSurf_Undecided);
933 IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc);
935 if (typL == IntPatch_Walking && !refine[ip]) {
936 // for new vertex use coordinates from Line
938 GetWLinePoint (wlin, paramline, U1,V1,U2,V2,ptsommet);
940 GetWLinePoint (wlin, paramline, U2,V2,U1,V1,ptsommet);
945 Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence
947 Sommet.SetParameters(U1,V1,U2,V2);
949 Sommet.SetParameters(U2,V2,U1,V1);
952 Sommet.SetVertex(OnFirst,vtxarc);
954 //---------------------------------------------------------
955 //-- lbr : On remplace le point d indice paramline sur la -
956 //-- ligne par le vertex . -
957 //---------------------------------------------------------
958 Sommet.SetParameter(paramline); // sur ligne d intersection
959 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
961 if (typL == IntPatch_Walking) {
962 wlin->AddVertex(Sommet);
966 rlin->AddVertex(Sommet);
971 // CAS DE FIGURE : en appelant s1 la surf sur laquelle on
972 // connait les pts sur restriction, et s2 celle sur laquelle
973 // on les cherche. Le point trouve verifie necessairement
975 // Pas vtxS1, pas vtxS2 :
976 // on recupere le point et on applique SetArcOnS2 et
977 // eventuellement SetVertexOnS2. Si on a deja IsOnDomS2,
978 // on considere que le point est deja traite, mais ne devrait
980 // vtxS1, pas vtxS2 :
981 // si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2,
982 // et eventuellement SetVertexOnS2.
983 // si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2.
985 // on doit avoir VtxOnArc = True. On duplique chaque occurrence
986 // "sur S1" du point en changeant ArcOnS2.
987 // pas vtxS1, vtxS2 :
988 // on doit avoir VtxOnArc = True. On duplique le point sur S1
989 // en changeant ArcOnS2.
990 Standard_Boolean OnDifferentRst =
991 ((OnFirst && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc) ||
992 (!OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc));
993 ptline.SetTolerance(vtxTol);
994 if ( (!ptline.IsVertexOnS1() && OnFirst)
995 || (!ptline.IsVertexOnS2() && !OnFirst)
996 || (OnDifferentRst)) {
997 if ( (!ptline.IsOnDomS2() && !OnFirst)
998 ||(!ptline.IsOnDomS1() && OnFirst)
999 ||(OnDifferentRst)) {
1000 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
1001 //ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97
1003 ptline.SetVertex(OnFirst,vtxarc);
1004 if (typL == IntPatch_Walking) {
1005 if(OnDifferentRst) {
1006 wlin->AddVertex(ptline);
1010 wlin->Replace(ivtx,ptline);
1014 if(OnDifferentRst) {
1015 rlin->AddVertex(ptline);
1019 rlin->Replace(ivtx,ptline);
1023 else if ( ( OnFirst && ptline.IsVertexOnS2())
1024 ||(!OnFirst && ptline.IsVertexOnS1())) {
1026 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
1028 Sommet.SetVertex(OnFirst,vtxarc);
1029 if (typL == IntPatch_Walking) {
1030 wlin->AddVertex(Sommet);
1034 rlin->AddVertex(Sommet);
1039 //-- cout << "pb dans RstInt Type 1 " << endl;
1043 Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ;
1044 if ( ( OnFirst && !ptline.IsOnDomS2())
1045 ||(!OnFirst && !ptline.IsOnDomS1())) {
1046 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
1048 ptline.SetVertex(OnFirst,vtxarc);
1049 if (typL == IntPatch_Walking) {
1050 wlin->Replace(ivtx,ptline);
1053 rlin->Replace(ivtx,ptline);
1056 for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
1057 if (typL == IntPatch_Walking) {
1058 ptline = wlin->Vertex(k);
1061 ptline = rlin->Vertex(k);
1063 if ( ( OnFirst && ptline.IsVertexOnS1())
1064 || (!OnFirst && ptline.IsVertexOnS2())) {
1065 if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
1066 if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
1067 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
1069 ptline.SetVertex(OnFirst,vtxarc);
1070 if (typL == IntPatch_Walking) {
1071 wlin->Replace(k,ptline);
1074 rlin->Replace(k,ptline);
1080 else if( ( OnFirst && ptline.IsVertexOnS2())
1081 || (!OnFirst && ptline.IsVertexOnS1())) {
1082 // on doit avoir vtxons2 = vtxarc... pas de verif...
1084 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
1085 if (typL == IntPatch_Walking) {
1086 wlin->AddVertex(Sommet);
1090 rlin->AddVertex(Sommet);
1093 for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
1094 if (typL == IntPatch_Walking) {
1095 ptline = wlin->Vertex(k);
1098 ptline = rlin->Vertex(k);
1100 if ( ( OnFirst && ptline.IsVertexOnS1())
1101 ||(!OnFirst && ptline.IsVertexOnS2())) {
1102 if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
1103 if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
1105 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
1106 if (typL == IntPatch_Walking) {
1107 wlin->Replace(k,ptline);
1108 wlin->AddVertex(Sommet);
1112 rlin->Replace(k,ptline);
1113 rlin->AddVertex(Sommet);
1122 //-- cout << "pb dans RstInt Type 2 " << endl;
1129 if (nbTreated == 2 && typL == IntPatch_Walking) {
1130 // We processed a tangent zone, and both ends have been treated.
1131 // So mark WLine as having arc
1132 if(OnFirst) wlin->SetArcOnS1(arc);
1133 else wlin->SetArcOnS2(arc);
1137 IndiceOffsetPeriodic++;
1139 while(SurfaceIsPeriodic && IndiceOffsetPeriodic<=2);
1141 IndiceOffsetBiPeriodic++;
1143 while(SurfaceIsBiPeriodic && IndiceOffsetBiPeriodic<=2);
1147 //--------------------------------------------------------------------------------
1148 //-- On reprend la ligne et on recale les parametres des vertex.
1150 if (typL == IntPatch_Walking) {
1151 Standard_Real pu1,pv1,pu2,pv2;
1152 pu1=pv1=pu2=pv2=0.0;
1154 case GeomAbs_Cylinder:
1156 case GeomAbs_Sphere:
1164 if( Surf1->IsUPeriodic()) {
1165 pu1=Surf1->UPeriod();
1167 else if(Surf1->IsUClosed()) {
1168 pu1=Surf1->LastUParameter() - Surf1->FirstUParameter();
1169 //cout<<" UClosed1 "<<pu1<<endl;
1171 if( Surf1->IsVPeriodic()) {
1172 pv1=Surf1->VPeriod();
1174 else if(Surf1->IsVClosed()) {
1175 pv1=Surf1->LastVParameter() - Surf1->FirstVParameter();
1176 //cout<<" VClosed1 "<<pv1<<endl;
1184 case GeomAbs_Cylinder:
1186 case GeomAbs_Sphere:
1195 if( Surf2->IsUPeriodic()) {
1196 pu2=Surf2->UPeriod();
1198 else if(Surf2->IsUClosed()) {
1199 pu2=Surf2->LastUParameter() - Surf2->FirstUParameter();
1200 //cout<<" UClosed2 "<<pu2<<endl;
1203 if( Surf2->IsVPeriodic()) {
1204 pv2=Surf2->VPeriod();
1206 else if(Surf2->IsVClosed()) {
1207 pv2=Surf2->LastVParameter() - Surf2->FirstVParameter();
1208 //cout<<" VClosed2 "<<pv2<<endl;
1217 pu1=Surf1->LastUParameter() - Surf1->FirstUParameter();
1221 pu2=Surf2->LastUParameter() - Surf2->FirstUParameter();
1225 pv1=Surf1->LastVParameter() - Surf1->FirstVParameter();
1229 pv2=Surf2->LastVParameter() - Surf2->FirstVParameter();
1234 wlin->SetPeriod(pu1,pv1,pu2,pv2);
1235 wlin->ComputeVertexParameters(Tol);
1239 //if(rlin->NbVertex()==0) {
1240 // cout<<" \n *** IntPatch RstInt.gxx : nbvtx = 0 sur rline *** \n"<<endl;
1243 rlin->ComputeVertexParameters(Tol);