1 // Created on: 1993-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1993-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 // ----------------------------------------------------------------------
18 //-- lbr: Modifs importantes du 16-17 Nov 95
19 //-- - Chercher APointOnRstStillExist et OnDifferentRst
20 //-- On veut pouvoir creer un Vtx (A1 sur S1, A2 sur S2)
21 //-- et le Vtx (A1 sur S1, A2bis sur S2)
22 //-- ce qui revient a distinguer un point deja pose sur une
23 //-- restriction de S avec un point pose sur une nouvelle
24 //-- restriction de S.
25 //-- - Pour rester coherent avec cette facon de faire,
26 //-- Chercher(Nbvtx++).
28 #include <Adaptor2d_HCurve2d.hxx>
29 #include <Adaptor3d_HSurface.hxx>
30 #include <Adaptor3d_TopolTool.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <Intf_SectionPoint.hxx>
33 #include <Intf_TangentZone.hxx>
34 #include <IntPatch_CSFunction.hxx>
35 #include <IntPatch_CurvIntSurf.hxx>
36 #include <IntPatch_HInterTool.hxx>
37 #include <IntPatch_Line.hxx>
38 #include <IntPatch_PolyArc.hxx>
39 #include <IntPatch_PolyLine.hxx>
40 #include <IntPatch_RLine.hxx>
41 #include <IntPatch_RstInt.hxx>
42 #include <IntPatch_SearchPnt.hxx>
43 #include <IntPatch_WLine.hxx>
44 #include <IntSurf.hxx>
45 #include <Precision.hxx>
46 #include <Standard_DomainError.hxx>
47 #include <TColgp_SequenceOfPnt.hxx>
48 #include <TColgp_SequenceOfPnt2d.hxx>
52 #define myInfinite 1.e15 // the same as was in Adaptor3d_TopolTool
54 static void Recadre(GeomAbs_SurfaceType typeS1,
55 GeomAbs_SurfaceType typeS2,
56 const Handle(IntPatch_WLine)& wlin,
57 Standard_Integer Param,
63 Standard_Integer nbpnts = wlin->NbPnts();
64 if(Param<1) Param=1; else if(Param>nbpnts) Param=nbpnts;
65 Standard_Real U1p,V1p,U2p,V2p;
67 wlin->Point(Param).Parameters(U1p,V1p,U2p,V2p);
69 case GeomAbs_Cylinder:
73 while(U1<(U1p-1.5*M_PI)) U1+=M_PI+M_PI;
74 while(U1>(U1p+1.5*M_PI)) U1-=M_PI+M_PI;
79 if(typeS1==GeomAbs_Torus) {
80 while(V1<(V1p-1.5*M_PI)) V1+=M_PI+M_PI;
81 while(V1>(V1p+1.5*M_PI)) V1-=M_PI+M_PI;
85 case GeomAbs_Cylinder:
89 while(U2<(U2p-1.5*M_PI)) U2+=M_PI+M_PI;
90 while(U2>(U2p+1.5*M_PI)) U2-=M_PI+M_PI;
95 if(typeS2==GeomAbs_Torus) {
96 while(V2<(V1p-1.5*M_PI)) V2+=M_PI+M_PI;
97 while(V2>(V2p+1.5*M_PI)) V2-=M_PI+M_PI;
101 const Standard_Real Confusion = Precision::Confusion();
103 inline Standard_Real Tol3d (const Handle(Adaptor3d_HVertex)& vtx,
104 const Handle(Adaptor3d_TopolTool)& Domain,
105 const Standard_Real tolDef = 0.)
107 return (Domain->Has3d() ? Domain->Tol3d(vtx)
108 : tolDef < Confusion ? Confusion
112 inline Standard_Real Tol3d (const Handle(Adaptor2d_HCurve2d)& arc,
113 const Handle(Adaptor3d_TopolTool)& Domain,
114 const Standard_Real tolDef = 0.)
116 return (Domain->Has3d() ? Domain->Tol3d(arc)
117 : tolDef < Confusion ? Confusion
121 static Standard_Boolean CoincideOnArc(const gp_Pnt& Ptsommet,
122 const Handle(Adaptor2d_HCurve2d)& A,
123 const Handle(Adaptor3d_HSurface)& Surf,
124 const Standard_Real Toler,
125 const Handle(Adaptor3d_TopolTool)& Domain,
126 Handle(Adaptor3d_HVertex)& Vtx)
128 Standard_Real distmin = RealLast();
129 Standard_Real tolarc = Max(Toler,Tol3d(A,Domain));
131 Domain->Initialize(A);
132 Domain->InitVertexIterator();
133 while (Domain->MoreVertex()) {
134 Handle(Adaptor3d_HVertex) vtx1 = Domain->Vertex();
135 Standard_Real prm = IntPatch_HInterTool::Parameter(vtx1,A);
136 gp_Pnt2d p2d = A->Value(prm);
137 gp_Pnt point = Surf->Value(p2d.X(),p2d.Y());
138 const Standard_Real dist = point.Distance(Ptsommet);
139 Standard_Real tol = Max (tolarc, Tol3d(vtx1,Domain));
141 if (dist <= tol && dist <= distmin) { // the best coincidence
145 Domain->NextVertex();
147 return distmin < RealLast();
151 static void VerifyTgline(const Handle(IntPatch_WLine)& wlin,
152 const Standard_Integer param,
153 const Standard_Real Tol,
158 && Abs(Tgl.Z())<Tol) {
159 //-- On construit une tangente plus grande
160 //-- (Eviter des points tres proches ds Walking)
161 Standard_Integer i, n, nbpt=wlin->NbPnts();
162 Standard_Boolean forward = (nbpt-param) >= (param-1);
163 for (n = 2; n > 0; n--, forward = !forward) {
165 for(i=param+1; i<=nbpt; i++) {
166 gp_Vec T(wlin->Point(param).Value(),wlin->Point(i).Value());
169 || Abs(T.Z())>=Tol) {
176 for(i=param-1; i>=1; i--) {
177 gp_Vec T(wlin->Point(i).Value(),wlin->Point(param).Value());
180 || Abs(T.Z())>=Tol) {
190 static void GetLinePoint2d (const Handle(IntPatch_Line)& L,
191 const Standard_Real param,
192 const Standard_Boolean OnFirst,
193 Standard_Real& U, Standard_Real& V)
195 Handle(IntPatch_WLine) wlin = Handle(IntPatch_WLine)::DownCast(L);
196 Handle(IntPatch_RLine) rlin = Handle(IntPatch_RLine)::DownCast(L);
197 IntPatch_IType typL = L->ArcType();
198 Standard_Integer Nbptlin = (typL == IntPatch_Walking
202 Standard_Real par = IntegerPart(param);
203 Standard_Integer Irang = Standard_Integer(par);
204 if (Irang == Nbptlin) {
209 par = Abs(param-par);
211 Standard_Real us1,vs1,us2,vs2;
212 if (typL == IntPatch_Walking) {
214 wlin->Point(Irang).ParametersOnS1(us1,vs1);
215 wlin->Point(Irang+1).ParametersOnS1(us2,vs2);
218 wlin->Point(Irang).ParametersOnS2(us1,vs1);
219 wlin->Point(Irang+1).ParametersOnS2(us2,vs2);
224 rlin->Point(Irang).ParametersOnS1(us1,vs1);
225 rlin->Point(Irang+1).ParametersOnS1(us2,vs2);
228 rlin->Point(Irang).ParametersOnS2(us1,vs1);
229 rlin->Point(Irang+1).ParametersOnS2(us2,vs2);
233 U = (1.-par)*us1+par*us2;
234 V = (1.-par)*vs1+par*vs2;
237 static Standard_Boolean FindParameter(const Handle(IntPatch_Line)& L,
238 const Handle(Adaptor3d_HSurface)& OtherSurf,
239 const Standard_Real Tol,
241 const gp_Pnt2d& Ptsom2d,
242 Standard_Real& Param,
244 const Standard_Integer ParamApproche,
245 const Standard_Boolean OnFirst)
248 // MSV 28.03.2002: find parameter on WLine in 2d space
250 //Si la ligne est de type restriction, c est qu on provient necessairement
251 // du cas implicite/parametree, et que la ligne est restriction de
252 // la surface bi-parametree. Cette surface bi-parametree est necessairement
253 // passee en argument a PutVertexOnline dans la variable OtherSurf.
255 // Dans le cas d une ligne de cheminement, il faudrait voir la projection
256 // et le calcul de la tangente.
258 Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est
259 Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast.
264 Standard_Real Tol2 = Tol*Tol;
265 IntPatch_IType typL = L->ArcType();
266 Tgl.SetCoord(0.0,0.0,0.0);
268 if ( typL == IntPatch_Restriction) {
269 if (!OnFirst && rlin->IsArcOnS1()) {
270 IntPatch_HInterTool::Project(rlin->ArcOnS1(),Ptsom2d,Param,p2d);
271 rlin->ArcOnS1()->D1(Param,p2d,d2d);
273 else if (OnFirst && rlin->IsArcOnS2()) {
274 IntPatch_HInterTool::Project(rlin->ArcOnS2(),Ptsom2d,Param,p2d);
275 rlin->ArcOnS2()->D1(Param,p2d,d2d);
278 return(Standard_False);
280 OtherSurf->D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
281 if (ptbid.SquareDistance(Ptsom) > Tol2) {
282 return Standard_False;
284 Tgl.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
285 return(Standard_True);
288 else if (typL == IntPatch_Walking) {
289 Standard_Integer i, is, nbpt=wlin->NbPnts();
290 Standard_Real norm1,norm2;
291 Standard_Integer ParamSearchInf=1;
292 Standard_Integer ParamSearchSup=nbpt;
294 if((ParamApproche-2) > ParamSearchInf) {
295 ParamSearchInf = ParamApproche-2;
297 if((ParamApproche+2) < ParamSearchSup) {
298 ParamSearchSup = ParamApproche+2;
301 Standard_Integer inf[3],sup[3];
302 // first search inside close bounding around ParamApproche;
303 // then search to the nearest end of line;
304 // and then search to the farest end of line.
305 inf[0] = ParamSearchInf; sup[0] = ParamSearchSup;
306 if (ParamSearchInf-1 < nbpt-ParamSearchSup) {
307 inf[1] = 1; sup[1] = ParamSearchInf;
308 inf[2] = ParamSearchSup; sup[2] = nbpt;
311 inf[1] = ParamSearchSup; sup[1] = nbpt;
312 inf[2] = 1; sup[2] = ParamSearchInf;
315 Standard_Boolean found = Standard_False;
316 for (is=0; is < 3 && !found; is++) {
319 p1 = wlin->Point(inf[is]).Value();
320 v1 = gp_Vec (Ptsom,p1);
321 norm1 = v1.SquareMagnitude();
322 Standard_Real normmin = Tol2;
323 Standard_Integer ibest = 0;
324 if (norm1 <= normmin) {
328 for (i=inf[is]+1; i <= sup[is] && !found; i++) {
329 p2 = wlin->Point(i).Value();
330 v2 = gp_Vec (Ptsom,p2);
331 norm2 = v2.SquareMagnitude();
332 if (v1.Dot(v2) < 0.) {
333 Param = (Standard_Real)(i-1) + 1./(1.+Sqrt(norm2/norm1));
334 Tgl = gp_Vec (p1,p2);
335 found = Standard_True;
337 else if (norm2 < normmin) {
341 v1 = v2; p1 = p2; norm1 = norm2;
343 if (!found && ibest) {
344 Param = (Standard_Real)ibest;
345 found = Standard_True;
348 if (found) return Standard_True;
351 throw Standard_DomainError();
353 return Standard_False;
356 inline Standard_Boolean ArePnt2dEqual(const gp_Pnt2d& p1, const gp_Pnt2d& p2,
357 const Standard_Real tolU,
358 const Standard_Real tolV)
360 return Abs(p1.X()-p2.X()) < tolU && Abs(p1.Y()-p2.Y()) < tolV;
363 //=======================================================================
364 //function : PutVertexOnLine
366 //=======================================================================
368 void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
369 const Handle(Adaptor3d_HSurface)& Surf,
370 const Handle(Adaptor3d_TopolTool)& Domain,
371 const Handle(Adaptor3d_HSurface)& OtherSurf,
372 const Standard_Boolean OnFirst,
373 const Standard_Real Tol)
376 // Domain est le domaine de restriction de la surface Surf.
377 // On intersectera un arc de Surf avec la surface OtherSurf.
378 // Si OnFirst = True, c est que la surface Surf correspond a la 1ere
379 // surface donnee aux algo d intersection.
381 IntPatch_SearchPnt Commun;
384 Standard_Real U1,V1,U2 = 0.,V2 = 0.;
385 Standard_Real paramarc=0.,paramline=0.;
386 Standard_Integer i,j,k;
387 TColgp_SequenceOfPnt locpt;
388 TColgp_SequenceOfPnt2d locpt2;
389 Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est
390 Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast.
391 Standard_Integer Nbvtx =0;
392 Standard_Real tolPLin = Surf->UResolution(Precision::Confusion());
393 tolPLin = Max (tolPLin, Surf->VResolution(Precision::Confusion()));
394 tolPLin = Min (tolPLin, Precision::Confusion());
395 IntPatch_PolyLine PLin(tolPLin);
397 Standard_Real PFirst,PLast;
398 Standard_Integer NbEchant;
399 gp_Pnt ptsommet, ptbid;
400 gp_Vec tgline, tgrst, d1u, d1v, normsurf;
405 IntPatch_Point Sommet, ptline;
406 Handle(Adaptor3d_HVertex) vtxarc,vtxline;
407 Handle(Adaptor2d_HCurve2d) arc;
408 Standard_Boolean VtxOnArc, duplicate, found;
409 IntSurf_Transition transarc,transline;
411 IntPatch_IType typL = L->ArcType();
412 if (typL == IntPatch_Walking) {
413 Nbvtx = wlin->NbVertex();
414 PLin.SetWLine(OnFirst,wlin);
416 else if ( typL == IntPatch_Restriction) {
417 Nbvtx = rlin->NbVertex();
418 PLin.SetRLine(OnFirst,rlin);
421 throw Standard_DomainError();
423 if (!Domain->Has3d())
424 // don't use computed deflection in the mode of pure geometric intersection
427 const Standard_Boolean SurfaceIsUClosed = Surf->IsUClosed();
428 const Standard_Boolean SurfaceIsVClosed = Surf->IsVClosed();
429 const Standard_Boolean OSurfaceIsUClosed = OtherSurf->IsUClosed();
430 const Standard_Boolean OSurfaceIsVClosed = OtherSurf->IsVClosed();
431 const Standard_Boolean possiblyClosed = (SurfaceIsUClosed || SurfaceIsVClosed ||
432 OSurfaceIsUClosed || OSurfaceIsVClosed);
433 Standard_Real tolUClosed=0., tolVClosed=0., tolOUClosed=0., tolOVClosed=0.;
434 if (possiblyClosed) {
435 if (SurfaceIsUClosed)
436 tolUClosed = (Surf->LastUParameter() - Surf->FirstUParameter()) * 0.01;
437 if (SurfaceIsVClosed)
438 tolVClosed = (Surf->LastVParameter() - Surf->FirstVParameter()) * 0.01;
439 if (OSurfaceIsUClosed)
440 tolOUClosed = (OtherSurf->LastUParameter() - OtherSurf->FirstUParameter()) * 0.01;
441 if (OSurfaceIsVClosed)
442 tolOVClosed = (OtherSurf->LastVParameter() - OtherSurf->FirstVParameter()) * 0.01;
445 //------------------------------------------------------------------------
446 //-- On traite le cas ou la surface est periodique --
447 //-- il faut dans ce cas considerer la restriction --
448 //-- la restriction decalee de +-2PI --
449 //------------------------------------------------------------------------
450 const Handle(Adaptor3d_HSurface)& Surf1 = (OnFirst ? Surf : OtherSurf);
451 const Handle(Adaptor3d_HSurface)& Surf2 = (OnFirst ? OtherSurf : Surf);
452 GeomAbs_SurfaceType TypeS1 = Surf1->GetType();
453 GeomAbs_SurfaceType TypeS2 = Surf2->GetType();
454 Standard_Boolean SurfaceIsPeriodic = Standard_False;
455 Standard_Boolean SurfaceIsBiPeriodic = Standard_False;
456 GeomAbs_SurfaceType surfacetype = (OnFirst ? TypeS1 : TypeS2);
457 if( surfacetype == GeomAbs_Cylinder
458 || surfacetype == GeomAbs_Cone
459 || surfacetype == GeomAbs_Torus
460 || surfacetype == GeomAbs_Sphere) {
461 SurfaceIsPeriodic = Standard_True;
462 if(surfacetype == GeomAbs_Torus) {
463 SurfaceIsBiPeriodic = Standard_True;
467 Standard_Integer NumeroEdge=0;
469 while (Domain->More()) {
471 arc = Domain->Value();
473 // MSV Oct 15, 2001: use tolerance of this edge if possible
474 Standard_Real edgeTol = Tol3d(arc,Domain,Tol);
476 IntPatch_HInterTool::Bounds(arc,PFirst,PLast);
477 if(Precision::IsNegativeInfinite(PFirst))
478 PFirst = -myInfinite;
479 if(Precision::IsPositiveInfinite(PLast))
481 //if (Precision::IsNegativeInfinite(PFirst) ||
482 // Precision::IsPositiveInfinite(PLast)) {
483 // //-- cout<<" IntPatch_RstInt::PutVertexOnLine ---> Restrictions Infinies :"<<endl;
487 gp_Pnt2d p2dFirst,p2dLast;
488 Domain->Initialize(arc);
489 for (Domain->InitVertexIterator(); Domain->MoreVertex(); Domain->NextVertex()) {
490 Handle(Adaptor3d_HVertex) vtx = Domain->Vertex();
491 Standard_Real prm = IntPatch_HInterTool::Parameter(vtx,arc);
492 if (Abs(prm - PFirst) < Precision::PConfusion()) {
493 arc->D0(PFirst,p2dFirst);
495 else if (Abs(prm - PLast) < Precision::PConfusion()) {
496 arc->D0(PLast,p2dLast);
500 Bnd_Box2d BPLin = PLin.Bounding();
501 Standard_Real OffsetV = 0.0;
502 Standard_Real OffsetU = 0.0;
504 switch(arc->GetType())
510 Standard_Real aXmin, aYmin, aXmax, aYmax;
511 BPLin.Get(aXmin, aYmin, aXmax, aYmax);
512 gp_Lin2d aLin = arc->Curve2d().Line();
513 const gp_Pnt2d& aLoc = aLin.Location();
514 const gp_Dir2d& aDir = aLin.Direction();
516 //Here, we consider rectangular axis-aligned domain only.
517 const Standard_Boolean isAlongU = (Abs(aDir.X()) > Abs(aDir.Y()));
519 if(SurfaceIsPeriodic && !isAlongU)
521 //Shift along U-direction
522 const Standard_Real aNewLocation =
523 ElCLib::InPeriod(aLoc.X(), aXmin, aXmin + M_PI + M_PI);
524 OffsetU = aNewLocation - aLoc.X();
526 else if(SurfaceIsBiPeriodic && isAlongU)
528 //Shift along V-direction
529 const Standard_Real aNewLocation =
530 ElCLib::InPeriod(aLoc.Y(), aYmin, aYmin + M_PI + M_PI);
531 OffsetV = aNewLocation - aLoc.Y();
535 case GeomAbs_BezierCurve:
537 NbEchant = (3 + arc->NbPoles());
538 if(NbEchant<10) NbEchant=10;
539 else if(NbEchant>50) NbEchant=50;
542 case GeomAbs_BSplineCurve:
544 //szv:const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(arc->LastParameter() - arc->FirstParameter())/(PLast-PFirst);
545 const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(PLast-PFirst)/(arc->LastParameter() - arc->FirstParameter());
546 NbEchant = (nbs < 2.0 ? 2 : (Standard_Integer)nbs);
547 if(NbEchant<10) NbEchant=10;
548 else if (NbEchant>50) NbEchant=50;
557 if(SurfaceIsPeriodic) {
558 Standard_Real xmin,ymin,xmax,ymax,g;
559 BPLin.Get(xmin,ymin,xmax,ymax);
562 BPLin.Update(xmin-M_PI-M_PI,ymin,
563 xmax+M_PI+M_PI,ymax);
566 if(SurfaceIsBiPeriodic) {
567 Standard_Real xmin,ymin,xmax,ymax,g;
568 BPLin.Get(xmin,ymin,xmax,ymax);
571 BPLin.Update(xmin,ymin-M_PI-M_PI,
572 xmax,ymax+M_PI+M_PI);
576 IntPatch_PolyArc Brise(arc,NbEchant,PFirst,PLast,BPLin);
578 Standard_Integer IndiceOffsetBiPeriodic = 0;
579 Standard_Integer IndiceOffsetPeriodic = 0;
580 const Standard_Real aRefOU = OffsetU,
584 if(IndiceOffsetBiPeriodic == 1)
585 OffsetV = aRefOV - M_PI - M_PI;
586 else if(IndiceOffsetBiPeriodic == 2)
587 OffsetV = aRefOV + M_PI + M_PI;
590 if(IndiceOffsetPeriodic == 1)
591 OffsetU = aRefOU - M_PI - M_PI;
592 else if(IndiceOffsetPeriodic == 2)
593 OffsetU = aRefOU + M_PI + M_PI;
595 Brise.SetOffset(OffsetU,OffsetV);
597 static int debug_polygon2d =0;
598 if(debug_polygon2d) {
599 cout<<" ***** Numero Restriction : "<<NumeroEdge<<" *****"<<endl;
604 Commun.Perform(PLin,Brise);
608 // We do not need in putting vertex into tangent zone(s).
609 // Therefore, only section points are interested by us.
610 // Boundary of WLine (its first/last points) will be
611 // marked by some vertex later. See bug #29494.
612 const Standard_Integer aNbSectionPts = Commun.NbSectionPoints();
613 for (i = 1; i <= aNbSectionPts; i++)
615 const Standard_Real aW1 = Commun.PntValue(i).ParamOnFirst(),
616 aW2 = Commun.PntValue(i).ParamOnSecond();
618 Standard_Integer nbTreated = 0;
619 GetLinePoint2d (L, aW1+1, !OnFirst, U,V);
621 Standard_Real par = IntegerPart(aW2);
622 Standard_Integer Irang = Standard_Integer(par) + 1;
623 if (Irang == Brise.NbPoints())
630 par = Abs(aW2 - par);
633 W = (1. - par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang + 1);
635 //------------------------------------------------------------------------
636 //-- On a trouve un point 2d approche Ua,Va intersection de la ligne
637 //-- de cheminement et de la restriction.
639 //-- On injecte ce point ds les intersections Courbe-Surface
641 IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
642 // MSV: extend UV bounds to not miss solution near the boundary
643 const Standard_Real margCoef = 0.004;
644 Standard_Boolean refined = Standard_False;
645 IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
646 if (IntCS.IsDone() && !IntCS.IsEmpty())
648 ptsommet = IntCS.Point();
649 IntCS.ParameterOnSurface(U2,V2);
650 gp_Pnt anOldPnt, aNewPnt;
651 OtherSurf->D0(U,V, anOldPnt);
652 OtherSurf->D0(U2,V2, aNewPnt);
653 if (anOldPnt.SquareDistance(aNewPnt) < Precision::SquareConfusion())
658 paramarc = IntCS.ParameterOnCurve();
659 refined = Standard_True;
663 duplicate = Standard_False;
664 for (j=1; j<=locpt.Length();j++) {
665 if (ptsommet.Distance(locpt(j)) <= edgeTol) {
666 if (possiblyClosed) {
667 locpt2(j).Coord(U,V);
668 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
669 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
672 duplicate = Standard_True;
678 Standard_Integer ParamApproxOnLine = Standard_Integer(aW1)+1;
680 arc->D1(paramarc,p2d,d2d);
681 U1 = p2d.X(); V1 = p2d.Y();
682 if (typL == IntPatch_Walking && SurfaceIsPeriodic) {
684 Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2);
686 Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1);
688 locpt.Append(ptsommet);
689 locpt2.Append(gp_Pnt2d(U2,V2));
691 found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2),
692 paramline,tgline,ParamApproxOnLine,OnFirst);
694 if (typL == IntPatch_Walking && found && possiblyClosed) {
696 if (SurfaceIsUClosed || SurfaceIsVClosed) {
697 GetLinePoint2d (L, paramline, OnFirst, U,V);
698 if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
699 (SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
700 found = Standard_False;
702 if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) {
703 GetLinePoint2d (L, paramline, !OnFirst, U,V);
704 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
705 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
706 found = Standard_False;
713 VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc);
714 Standard_Real vtxTol;
716 vtxTol = Tol3d(vtxarc,Domain);
717 if (edgeTol > vtxTol) vtxTol = edgeTol;
719 else vtxTol = edgeTol;
721 //-- It is necessary to test that the point does not already exist
722 //-- - It can be already a point on arc
723 //-- BUT on a different arc
724 // MSV 27.03.2002: find the nearest point; add check in 2d
725 Standard_Integer ivtx = 0;
726 Standard_Real dmin = RealLast();
727 for (j=1; j<=Nbvtx; j++) {
728 const IntPatch_Point& Rptline = (typL == IntPatch_Walking
731 Standard_Boolean APointOnRstStillExist =
732 ((OnFirst && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc) ||
733 (!OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc));
734 if(!APointOnRstStillExist) {
735 if (possiblyClosed) {
736 if (SurfaceIsUClosed || SurfaceIsVClosed) {
737 if (OnFirst) Rptline.ParametersOnS1(U,V);
738 else Rptline.ParametersOnS2(U,V);
739 if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
740 (SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
743 if (OSurfaceIsUClosed || OSurfaceIsVClosed) {
744 if (OnFirst) Rptline.ParametersOnS2(U,V);
745 else Rptline.ParametersOnS1(U,V);
746 if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
747 (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
751 Standard_Real dist = ptsommet.Distance(Rptline.Value());
752 Standard_Real dt = Max(vtxTol, Rptline.Tolerance());
757 if( surfacetype == GeomAbs_Cone ) {
762 // cancel previous solution because this point is better
763 // but its tolerance is not large enough
771 if (ptline.Tolerance() > vtxTol) {
772 vtxTol = ptline.Tolerance();
774 // now we should repeat attempt to coincide on a bound of arc
775 VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc);
777 Standard_Real tol = Tol3d(vtxarc,Domain);
778 if (tol > vtxTol) vtxTol = tol;
784 if (typL == IntPatch_Walking)
785 VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline);
787 Surf->D1(U1,V1,ptbid,d1u,d1v);
788 tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
790 normsurf = d1u.Crossed(d1v);
791 if (normsurf.Magnitude() < gp::Resolution()) {
792 transline.SetValue(Standard_True,IntSurf_Undecided);
793 transarc.SetValue(Standard_True,IntSurf_Undecided);
796 IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc);
800 Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence
802 Sommet.SetParameters(U1,V1,U2,V2);
804 Sommet.SetParameters(U2,V2,U1,V1);
807 Sommet.SetVertex(OnFirst,vtxarc);
809 //---------------------------------------------------------
810 //-- lbr : On remplace le point d indice paramline sur la -
811 //-- ligne par le vertex . -
812 //---------------------------------------------------------
813 Sommet.SetParameter(paramline); // sur ligne d intersection
814 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
816 if (typL == IntPatch_Walking) {
817 wlin->AddVertex(Sommet);
821 rlin->AddVertex(Sommet);
826 // CAS DE FIGURE : en appelant s1 la surf sur laquelle on
827 // connait les pts sur restriction, et s2 celle sur laquelle
828 // on les cherche. Le point trouve verifie necessairement
830 // Pas vtxS1, pas vtxS2 :
831 // on recupere le point et on applique SetArcOnS2 et
832 // eventuellement SetVertexOnS2. Si on a deja IsOnDomS2,
833 // on considere que le point est deja traite, mais ne devrait
835 // vtxS1, pas vtxS2 :
836 // si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2,
837 // et eventuellement SetVertexOnS2.
838 // si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2.
840 // on doit avoir VtxOnArc = True. On duplique chaque occurrence
841 // "sur S1" du point en changeant ArcOnS2.
842 // pas vtxS1, vtxS2 :
843 // on doit avoir VtxOnArc = True. On duplique le point sur S1
844 // en changeant ArcOnS2.
845 Standard_Boolean OnDifferentRst =
846 ((OnFirst && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc) ||
847 (!OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc));
848 ptline.SetTolerance(vtxTol);
849 if ( (!ptline.IsVertexOnS1() && OnFirst)
850 || (!ptline.IsVertexOnS2() && !OnFirst)
851 || (OnDifferentRst)) {
852 if ( (!ptline.IsOnDomS2() && !OnFirst)
853 ||(!ptline.IsOnDomS1() && OnFirst)
854 ||(OnDifferentRst)) {
855 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
856 //ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97
858 ptline.SetVertex(OnFirst,vtxarc);
859 if (typL == IntPatch_Walking) {
861 wlin->AddVertex(ptline);
865 wlin->Replace(ivtx,ptline);
870 rlin->AddVertex(ptline);
874 rlin->Replace(ivtx,ptline);
878 else if ( ( OnFirst && ptline.IsVertexOnS2())
879 ||(!OnFirst && ptline.IsVertexOnS1())) {
881 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
883 Sommet.SetVertex(OnFirst,vtxarc);
884 if (typL == IntPatch_Walking) {
885 wlin->AddVertex(Sommet);
889 rlin->AddVertex(Sommet);
894 //-- cout << "pb dans RstInt Type 1 " << endl;
898 Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ;
899 if ( ( OnFirst && !ptline.IsOnDomS2())
900 ||(!OnFirst && !ptline.IsOnDomS1())) {
901 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
903 ptline.SetVertex(OnFirst,vtxarc);
904 if (typL == IntPatch_Walking) {
905 wlin->Replace(ivtx,ptline);
908 rlin->Replace(ivtx,ptline);
911 for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
912 if (typL == IntPatch_Walking) {
913 ptline = wlin->Vertex(k);
916 ptline = rlin->Vertex(k);
918 if ( ( OnFirst && ptline.IsVertexOnS1())
919 || (!OnFirst && ptline.IsVertexOnS2())) {
920 if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
921 if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
922 ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
924 ptline.SetVertex(OnFirst,vtxarc);
925 if (typL == IntPatch_Walking) {
926 wlin->Replace(k,ptline);
929 rlin->Replace(k,ptline);
935 else if( ( OnFirst && ptline.IsVertexOnS2())
936 || (!OnFirst && ptline.IsVertexOnS1())) {
937 // on doit avoir vtxons2 = vtxarc... pas de verif...
939 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
940 if (typL == IntPatch_Walking) {
941 wlin->AddVertex(Sommet);
945 rlin->AddVertex(Sommet);
948 for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
949 if (typL == IntPatch_Walking) {
950 ptline = wlin->Vertex(k);
953 ptline = rlin->Vertex(k);
955 if ( ( OnFirst && ptline.IsVertexOnS1())
956 ||(!OnFirst && ptline.IsVertexOnS2())) {
957 if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
958 if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
960 Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
961 if (typL == IntPatch_Walking) {
962 wlin->Replace(k,ptline);
963 wlin->AddVertex(Sommet);
967 rlin->Replace(k,ptline);
968 rlin->AddVertex(Sommet);
977 //-- cout << "pb dans RstInt Type 2 " << endl;
983 if (nbTreated == 2 && typL == IntPatch_Walking) {
984 // We processed a tangent zone, and both ends have been treated.
985 // So mark WLine as having arc
986 if(OnFirst) wlin->SetArcOnS1(arc);
987 else wlin->SetArcOnS2(arc);
991 IndiceOffsetPeriodic++;
993 while(SurfaceIsPeriodic && IndiceOffsetPeriodic<=2);
995 IndiceOffsetBiPeriodic++;
997 while(SurfaceIsBiPeriodic && IndiceOffsetBiPeriodic<=2);
1001 //--------------------------------------------------------------------------------
1002 //-- On reprend la ligne et on recale les parametres des vertex.
1004 if (typL == IntPatch_Walking) {
1005 Standard_Real pu1,pv1,pu2,pv2;
1006 pu1=pv1=pu2=pv2=0.0;
1008 case GeomAbs_Cylinder:
1010 case GeomAbs_Sphere:
1018 if( Surf1->IsUPeriodic()) {
1019 pu1=Surf1->UPeriod();
1021 else if(Surf1->IsUClosed()) {
1022 pu1=Surf1->LastUParameter() - Surf1->FirstUParameter();
1023 //cout<<" UClosed1 "<<pu1<<endl;
1025 if( Surf1->IsVPeriodic()) {
1026 pv1=Surf1->VPeriod();
1028 else if(Surf1->IsVClosed()) {
1029 pv1=Surf1->LastVParameter() - Surf1->FirstVParameter();
1030 //cout<<" VClosed1 "<<pv1<<endl;
1038 case GeomAbs_Cylinder:
1040 case GeomAbs_Sphere:
1049 if( Surf2->IsUPeriodic()) {
1050 pu2=Surf2->UPeriod();
1052 else if(Surf2->IsUClosed()) {
1053 pu2=Surf2->LastUParameter() - Surf2->FirstUParameter();
1054 //cout<<" UClosed2 "<<pu2<<endl;
1057 if( Surf2->IsVPeriodic()) {
1058 pv2=Surf2->VPeriod();
1060 else if(Surf2->IsVClosed()) {
1061 pv2=Surf2->LastVParameter() - Surf2->FirstVParameter();
1062 //cout<<" VClosed2 "<<pv2<<endl;
1071 pu1=Surf1->LastUParameter() - Surf1->FirstUParameter();
1075 pu2=Surf2->LastUParameter() - Surf2->FirstUParameter();
1079 pv1=Surf1->LastVParameter() - Surf1->FirstVParameter();
1083 pv2=Surf2->LastVParameter() - Surf2->FirstVParameter();
1088 wlin->SetPeriod(pu1,pv1,pu2,pv2);
1089 wlin->ComputeVertexParameters(Tol);
1092 rlin->ComputeVertexParameters(Tol);