// Created on: 1993-05-07 // Created by: Jacques GOUSSARD // Copyright (c) 1993-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. // ---------------------------------------------------------------------- //-- lbr: Modifs importantes du 16-17 Nov 95 //-- - Chercher APointOnRstStillExist et OnDifferentRst //-- On veut pouvoir creer un Vtx (A1 sur S1, A2 sur S2) //-- et le Vtx (A1 sur S1, A2bis sur S2) //-- ce qui revient a distinguer un point deja pose sur une //-- restriction de S avec un point pose sur une nouvelle //-- restriction de S. //-- - Pour rester coherent avec cette facon de faire, //-- Chercher(Nbvtx++). #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define myInfinite 1.e15 // the same as was in Adaptor3d_TopolTool static void Recadre(GeomAbs_SurfaceType typeS1, GeomAbs_SurfaceType typeS2, const Handle(IntPatch_WLine)& wlin, Standard_Integer Param, Standard_Real& U1, Standard_Real& V1, Standard_Real& U2, Standard_Real& V2) { Standard_Integer nbpnts = wlin->NbPnts(); if(Param<1) Param=1; else if(Param>nbpnts) Param=nbpnts; Standard_Real U1p,V1p,U2p,V2p; wlin->Point(Param).Parameters(U1p,V1p,U2p,V2p); switch(typeS1) { case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: while(U1<(U1p-1.5*M_PI)) U1+=M_PI+M_PI; while(U1>(U1p+1.5*M_PI)) U1-=M_PI+M_PI; break; default: break; } if(typeS1==GeomAbs_Torus) { while(V1<(V1p-1.5*M_PI)) V1+=M_PI+M_PI; while(V1>(V1p+1.5*M_PI)) V1-=M_PI+M_PI; } switch(typeS2) { case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: case GeomAbs_Torus: while(U2<(U2p-1.5*M_PI)) U2+=M_PI+M_PI; while(U2>(U2p+1.5*M_PI)) U2-=M_PI+M_PI; break; default: break; } if(typeS2==GeomAbs_Torus) { while(V2<(V1p-1.5*M_PI)) V2+=M_PI+M_PI; while(V2>(V2p+1.5*M_PI)) V2-=M_PI+M_PI; } } const Standard_Real Confusion = Precision::Confusion(); inline Standard_Real Tol3d (const Handle(Adaptor3d_HVertex)& vtx, const Handle(Adaptor3d_TopolTool)& Domain, const Standard_Real tolDef = 0.) { return (Domain->Has3d() ? Domain->Tol3d(vtx) : tolDef < Confusion ? Confusion : tolDef); } inline Standard_Real Tol3d (const Handle(Adaptor2d_HCurve2d)& arc, const Handle(Adaptor3d_TopolTool)& Domain, const Standard_Real tolDef = 0.) { return (Domain->Has3d() ? Domain->Tol3d(arc) : tolDef < Confusion ? Confusion : tolDef); } static Standard_Boolean CoincideOnArc(const gp_Pnt& Ptsommet, const Handle(Adaptor2d_HCurve2d)& A, const Handle(Adaptor3d_HSurface)& Surf, const Standard_Real Toler, const Handle(Adaptor3d_TopolTool)& Domain, Handle(Adaptor3d_HVertex)& Vtx) { Standard_Real distmin = RealLast(); Standard_Real tolarc = Max(Toler,Tol3d(A,Domain)); Domain->Initialize(A); Domain->InitVertexIterator(); while (Domain->MoreVertex()) { Handle(Adaptor3d_HVertex) vtx1 = Domain->Vertex(); Standard_Real prm = IntPatch_HInterTool::Parameter(vtx1,A); gp_Pnt2d p2d = A->Value(prm); gp_Pnt point = Surf->Value(p2d.X(),p2d.Y()); const Standard_Real dist = point.Distance(Ptsommet); Standard_Real tol = Max (tolarc, Tol3d(vtx1,Domain)); if (dist <= tol && dist <= distmin) { // the best coincidence distmin = dist; Vtx = vtx1; } Domain->NextVertex(); } return distmin < RealLast(); } static void VerifyTgline(const Handle(IntPatch_WLine)& wlin, const Standard_Integer param, const Standard_Real Tol, gp_Vec& Tgl) { if( Abs(Tgl.X())NbPnts(); Standard_Boolean forward = (nbpt-param) >= (param-1); for (n = 2; n > 0; n--, forward = !forward) { if (forward) { for(i=param+1; i<=nbpt; i++) { gp_Vec T(wlin->Point(param).Value(),wlin->Point(i).Value()); if( Abs(T.X())>=Tol || Abs(T.Y())>=Tol || Abs(T.Z())>=Tol) { Tgl = T ; return; } } } else { for(i=param-1; i>=1; i--) { gp_Vec T(wlin->Point(i).Value(),wlin->Point(param).Value()); if( Abs(T.X())>=Tol || Abs(T.Y())>=Tol || Abs(T.Z())>=Tol) { Tgl = T ; return; } } } } } } static void GetLinePoint2d (const Handle(IntPatch_Line)& L, const Standard_Real param, const Standard_Boolean OnFirst, Standard_Real& U, Standard_Real& V) { Handle(IntPatch_WLine) wlin = Handle(IntPatch_WLine)::DownCast(L); Handle(IntPatch_RLine) rlin = Handle(IntPatch_RLine)::DownCast(L); IntPatch_IType typL = L->ArcType(); Standard_Integer Nbptlin = (typL == IntPatch_Walking ? wlin->NbPnts() : rlin->NbPnts()); Standard_Real par = IntegerPart(param); Standard_Integer Irang = Standard_Integer(par); if (Irang == Nbptlin) { Irang--; par = 1.0; } else par = Abs(param-par); Standard_Real us1,vs1,us2,vs2; if (typL == IntPatch_Walking) { if (OnFirst) { wlin->Point(Irang).ParametersOnS1(us1,vs1); wlin->Point(Irang+1).ParametersOnS1(us2,vs2); } else { wlin->Point(Irang).ParametersOnS2(us1,vs1); wlin->Point(Irang+1).ParametersOnS2(us2,vs2); } } else { if (OnFirst) { rlin->Point(Irang).ParametersOnS1(us1,vs1); rlin->Point(Irang+1).ParametersOnS1(us2,vs2); } else { rlin->Point(Irang).ParametersOnS2(us1,vs1); rlin->Point(Irang+1).ParametersOnS2(us2,vs2); } } U = (1.-par)*us1+par*us2; V = (1.-par)*vs1+par*vs2; } static void GetWLinePoint (const Handle(IntPatch_WLine)& wlin, const Standard_Real param, Standard_Real& U1, Standard_Real& V1, Standard_Real& U2, Standard_Real& V2, gp_Pnt& P) { Standard_Integer Nbptlin = wlin->NbPnts(); Standard_Real par = IntegerPart(param); Standard_Integer Irang = Standard_Integer(par); if (Irang == Nbptlin) { Irang--; par = 1.0; } else par = Abs(param-par); const IntSurf_PntOn2S& p2s1 = wlin->Point(Irang); const IntSurf_PntOn2S& p2s2 = wlin->Point(Irang+1); const gp_Pnt& p1 = p2s1.Value(); const gp_Pnt& p2 = p2s2.Value(); P.ChangeCoord().SetLinearForm(1.-par, p1.XYZ(), par, p2.XYZ()); Standard_Real us1,vs1,us2,vs2; p2s1.ParametersOnS1(us1,vs1); p2s2.ParametersOnS1(us2,vs2); U1 = (1.-par)*us1+par*us2; V1 = (1.-par)*vs1+par*vs2; p2s1.ParametersOnS2(us1,vs1); p2s2.ParametersOnS2(us2,vs2); U2 = (1.-par)*us1+par*us2; V2 = (1.-par)*vs1+par*vs2; } static Standard_Boolean FindParameter(const Handle(IntPatch_Line)& L, const Handle(Adaptor3d_HSurface)& OtherSurf, const Standard_Real Tol, const gp_Pnt& Ptsom, const gp_Pnt2d& Ptsom2d, Standard_Real& Param, gp_Vec& Tgl, const Standard_Integer ParamApproche, const Standard_Boolean OnFirst) { // MSV 28.03.2002: find parameter on WLine in 2d space //Si la ligne est de type restriction, c est qu on provient necessairement // du cas implicite/parametree, et que la ligne est restriction de // la surface bi-parametree. Cette surface bi-parametree est necessairement // passee en argument a PutVertexOnline dans la variable OtherSurf. // Dans le cas d une ligne de cheminement, il faudrait voir la projection // et le calcul de la tangente. Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast. gp_Pnt ptbid; gp_Vec d1u,d1v; gp_Pnt2d p2d; gp_Vec2d d2d; Standard_Real Tol2 = Tol*Tol; IntPatch_IType typL = L->ArcType(); Tgl.SetCoord(0.0,0.0,0.0); if ( typL == IntPatch_Restriction) { if (!OnFirst && rlin->IsArcOnS1()) { IntPatch_HInterTool::Project(rlin->ArcOnS1(),Ptsom2d,Param,p2d); rlin->ArcOnS1()->D1(Param,p2d,d2d); } else if (OnFirst && rlin->IsArcOnS2()) { IntPatch_HInterTool::Project(rlin->ArcOnS2(),Ptsom2d,Param,p2d); rlin->ArcOnS2()->D1(Param,p2d,d2d); } else { return(Standard_False); } OtherSurf->D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v); if (ptbid.SquareDistance(Ptsom) > Tol2) { return Standard_False; } Tgl.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); return(Standard_True); } else if (typL == IntPatch_Walking) { Standard_Integer i, is, nbpt=wlin->NbPnts(); Standard_Real norm1,norm2; Standard_Integer ParamSearchInf=1; Standard_Integer ParamSearchSup=nbpt; if((ParamApproche-2) > ParamSearchInf) { ParamSearchInf = ParamApproche-2; } if((ParamApproche+2) < ParamSearchSup) { ParamSearchSup = ParamApproche+2; } Standard_Integer inf[3],sup[3]; // first search inside close bounding around ParamApproche; // then search to the nearest end of line; // and then search to the farest end of line. inf[0] = ParamSearchInf; sup[0] = ParamSearchSup; if (ParamSearchInf-1 < nbpt-ParamSearchSup) { inf[1] = 1; sup[1] = ParamSearchInf; inf[2] = ParamSearchSup; sup[2] = nbpt; } else { inf[1] = ParamSearchSup; sup[1] = nbpt; inf[2] = 1; sup[2] = ParamSearchInf; } Standard_Boolean found = Standard_False; for (is=0; is < 3 && !found; is++) { gp_Vec v1,v2; gp_Pnt p1,p2; p1 = wlin->Point(inf[is]).Value(); v1 = gp_Vec (Ptsom,p1); norm1 = v1.SquareMagnitude(); Standard_Real normmin = Tol2; Standard_Integer ibest = 0; if (norm1 <= normmin) { normmin = norm1; ibest = inf[is]; } for (i=inf[is]+1; i <= sup[is] && !found; i++) { p2 = wlin->Point(i).Value(); v2 = gp_Vec (Ptsom,p2); norm2 = v2.SquareMagnitude(); if (v1.Dot(v2) < 0.) { Param = (Standard_Real)(i-1) + 1./(1.+Sqrt(norm2/norm1)); Tgl = gp_Vec (p1,p2); found = Standard_True; } else if (norm2 < normmin) { normmin = norm2; ibest = i; } v1 = v2; p1 = p2; norm1 = norm2; } if (!found && ibest) { Param = (Standard_Real)ibest; found = Standard_True; } } if (found) return Standard_True; } else { Standard_DomainError::Raise(); } return Standard_False; } inline Standard_Boolean ArePnt2dEqual(const gp_Pnt2d& p1, const gp_Pnt2d& p2, const Standard_Real tolU, const Standard_Real tolV) { return Abs(p1.X()-p2.X()) < tolU && Abs(p1.Y()-p2.Y()) < tolV; } static gp_Pnt2d GetPointOnPolygo(const IntPatch_Polygo& Pol, const Standard_Real param) { Standard_Real par = IntegerPart(param); Standard_Integer irang = Standard_Integer(par) + 1; if (irang == Pol.NbPoints()) { irang--; par = 1.; } else { par = Abs(param-par); } gp_Pnt2d p1 = Pol.Point(irang); gp_Pnt2d p2 = Pol.Point(irang+1); gp_Pnt2d p; p.ChangeCoord().SetLinearForm(1.-par,p1.XY(),par,p2.XY()); return p; } static Standard_Boolean IsSegment2dSmall(const IntPatch_Polygo& Pol, const Standard_Real parmin, const Standard_Real parmax, const Standard_Real URes, const Standard_Real VRes) { Standard_Integer irang1 = Standard_Integer(IntegerPart(parmin)) + 2; Standard_Integer irang2 = Standard_Integer(IntegerPart(parmax)) + 1; gp_Pnt2d p1,p2; Standard_Real du=0.,dv=0.; p1 = GetPointOnPolygo(Pol,parmin); for (Standard_Integer i=irang1; i <= irang2 && du <= URes && dv <= VRes; i++) { p2 = Pol.Point(i); du += Abs(p2.X()-p1.X()); dv += Abs(p2.Y()-p1.Y()); p1 = p2; } if (du <= URes && dv <= VRes) { p2 = GetPointOnPolygo(Pol,parmax); du += Abs(p2.X()-p1.X()); dv += Abs(p2.Y()-p1.Y()); } return du <= URes && dv <= VRes; } //======================================================================= //function : PutVertexOnLine //purpose : //======================================================================= void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L, const Handle(Adaptor3d_HSurface)& Surf, const Handle(Adaptor3d_TopolTool)& Domain, const Handle(Adaptor3d_HSurface)& OtherSurf, const Standard_Boolean OnFirst, const Standard_Real Tol) { // Domain est le domaine de restriction de la surface Surf. // On intersectera un arc de Surf avec la surface OtherSurf. // Si OnFirst = True, c est que la surface Surf correspond a la 1ere // surface donnee aux algo d intersection. IntPatch_SearchPnt Commun; Standard_Real U,V,W; Standard_Real U1,V1,U2 = 0.,V2 = 0.; Standard_Real paramarc=0.,paramline=0.; Standard_Integer i,j,k; TColgp_SequenceOfPnt locpt; TColgp_SequenceOfPnt2d locpt2; Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast. Standard_Integer Nbvtx =0; Standard_Integer Nbptlin =0; Standard_Real tolPLin = Surf->UResolution(Precision::Confusion()); tolPLin = Max (tolPLin, Surf->VResolution(Precision::Confusion())); tolPLin = Min (tolPLin, Precision::Confusion()); IntPatch_PolyLine PLin(tolPLin); Standard_Real PFirst,PLast; Standard_Integer NbEchant; gp_Pnt ptsommet, ptbid; gp_Vec tgline, tgrst, d1u, d1v, normsurf; gp_Pnt2d p2d; gp_Vec2d d2d; IntPatch_Point Sommet, ptline; Handle(Adaptor3d_HVertex) vtxarc,vtxline; Handle(Adaptor2d_HCurve2d) arc; Standard_Boolean VtxOnArc, duplicate, found; IntSurf_Transition transarc,transline; IntPatch_IType typL = L->ArcType(); if (typL == IntPatch_Walking) { Nbvtx = wlin->NbVertex(); PLin.SetWLine(OnFirst,wlin); Nbptlin = wlin->NbPnts(); } else if ( typL == IntPatch_Restriction) { Nbvtx = rlin->NbVertex(); PLin.SetRLine(OnFirst,rlin); Nbptlin = rlin->NbPnts(); } else { Standard_DomainError::Raise(); } if (!Domain->Has3d()) // don't use computed deflection in the mode of pure geometric intersection PLin.ResetError(); const Standard_Boolean SurfaceIsUClosed = Surf->IsUClosed(); const Standard_Boolean SurfaceIsVClosed = Surf->IsVClosed(); const Standard_Boolean OSurfaceIsUClosed = OtherSurf->IsUClosed(); const Standard_Boolean OSurfaceIsVClosed = OtherSurf->IsVClosed(); const Standard_Boolean possiblyClosed = (SurfaceIsUClosed || SurfaceIsVClosed || OSurfaceIsUClosed || OSurfaceIsVClosed); Standard_Real tolUClosed=0., tolVClosed=0., tolOUClosed=0., tolOVClosed=0.; if (possiblyClosed) { if (SurfaceIsUClosed) tolUClosed = (Surf->LastUParameter() - Surf->FirstUParameter()) * 0.01; if (SurfaceIsVClosed) tolVClosed = (Surf->LastVParameter() - Surf->FirstVParameter()) * 0.01; if (OSurfaceIsUClosed) tolOUClosed = (OtherSurf->LastUParameter() - OtherSurf->FirstUParameter()) * 0.01; if (OSurfaceIsVClosed) tolOVClosed = (OtherSurf->LastVParameter() - OtherSurf->FirstVParameter()) * 0.01; } //------------------------------------------------------------------------ //-- On traite le cas ou la surface est periodique -- //-- il faut dans ce cas considerer la restriction -- //-- la restriction decalee de +-2PI -- //------------------------------------------------------------------------ const Handle(Adaptor3d_HSurface)& Surf1 = (OnFirst ? Surf : OtherSurf); const Handle(Adaptor3d_HSurface)& Surf2 = (OnFirst ? OtherSurf : Surf); GeomAbs_SurfaceType TypeS1 = Surf1->GetType(); GeomAbs_SurfaceType TypeS2 = Surf2->GetType(); Standard_Boolean SurfaceIsPeriodic = Standard_False; Standard_Boolean SurfaceIsBiPeriodic = Standard_False; GeomAbs_SurfaceType surfacetype = (OnFirst ? TypeS1 : TypeS2); if( surfacetype == GeomAbs_Cylinder || surfacetype == GeomAbs_Cone || surfacetype == GeomAbs_Torus || surfacetype == GeomAbs_Sphere) { SurfaceIsPeriodic = Standard_True; if(surfacetype == GeomAbs_Torus) { SurfaceIsBiPeriodic = Standard_True; } } Standard_Integer NumeroEdge=0; Domain->Init(); while (Domain->More()) { NumeroEdge++; arc = Domain->Value(); // MSV Oct 15, 2001: use tolerance of this edge if possible Standard_Real edgeTol = Tol3d(arc,Domain,Tol); Standard_Real URes = Surf->UResolution(edgeTol); Standard_Real VRes = Surf->VResolution(edgeTol); IntPatch_HInterTool::Bounds(arc,PFirst,PLast); if(Precision::IsNegativeInfinite(PFirst)) PFirst = -myInfinite; if(Precision::IsPositiveInfinite(PLast)) PLast = myInfinite; //if (Precision::IsNegativeInfinite(PFirst) || // Precision::IsPositiveInfinite(PLast)) { // //-- cout<<" IntPatch_RstInt::PutVertexOnLine ---> Restrictions Infinies :"<Initialize(arc); for (Domain->InitVertexIterator(); Domain->MoreVertex(); Domain->NextVertex()) { Handle(Adaptor3d_HVertex) vtx = Domain->Vertex(); Standard_Real prm = IntPatch_HInterTool::Parameter(vtx,arc); if (Abs(prm - PFirst) < Precision::PConfusion()) { arc->D0(PFirst,p2dFirst); Standard_Real tol3d = Max (Tol3d(vtx,Domain), edgeTol); tolUFirst = Surf->UResolution(tol3d); tolVFirst = Surf->VResolution(tol3d); isVFirst = Standard_True; } else if (Abs(prm - PLast) < Precision::PConfusion()) { arc->D0(PLast,p2dLast); Standard_Real tol3d = Max (edgeTol, Tol3d(vtx,Domain)); tolULast = Surf->UResolution(tol3d); tolVLast = Surf->VResolution(tol3d); isVLast = Standard_True; } } Bnd_Box2d BPLin = PLin.Bounding(); Standard_Real OffsetV = 0.0; Standard_Real OffsetU = 0.0; switch(arc->GetType()) { case GeomAbs_Line: { NbEchant=10; Standard_Real aXmin, aYmin, aXmax, aYmax; BPLin.Get(aXmin, aYmin, aXmax, aYmax); gp_Lin2d aLin = arc->Curve2d().Line(); const gp_Pnt2d& aLoc = aLin.Location(); const gp_Dir2d& aDir = aLin.Direction(); //Here, we consider rectangular axis-aligned domain only. const Standard_Boolean isAlongU = (Abs(aDir.X()) > Abs(aDir.Y())); if(SurfaceIsPeriodic && !isAlongU) { //Shift along U-direction const Standard_Real aNewLocation = ElCLib::InPeriod(aLoc.X(), aXmin, aXmin + M_PI + M_PI); OffsetU = aNewLocation - aLoc.X(); } else if(SurfaceIsBiPeriodic && isAlongU) { //Shift along V-direction const Standard_Real aNewLocation = ElCLib::InPeriod(aLoc.Y(), aYmin, aYmin + M_PI + M_PI); OffsetV = aNewLocation - aLoc.Y(); } } break; case GeomAbs_BezierCurve: { NbEchant = (3 + arc->NbPoles()); if(NbEchant<10) NbEchant=10; else if(NbEchant>50) NbEchant=50; } break; case GeomAbs_BSplineCurve: { //szv:const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(arc->LastParameter() - arc->FirstParameter())/(PLast-PFirst); const Standard_Real nbs = (arc->NbKnots() * arc->Degree())*(PLast-PFirst)/(arc->LastParameter() - arc->FirstParameter()); NbEchant = (nbs < 2.0 ? 2 : (Standard_Integer)nbs); if(NbEchant<10) NbEchant=10; else if (NbEchant>50) NbEchant=50; } break; default: { NbEchant = 25; } } if(SurfaceIsPeriodic) { Standard_Real xmin,ymin,xmax,ymax,g; BPLin.Get(xmin,ymin,xmax,ymax); g = BPLin.GetGap(); BPLin.SetVoid(); BPLin.Update(xmin-M_PI-M_PI,ymin, xmax+M_PI+M_PI,ymax); BPLin.SetGap(g); } if(SurfaceIsBiPeriodic) { Standard_Real xmin,ymin,xmax,ymax,g; BPLin.Get(xmin,ymin,xmax,ymax); g = BPLin.GetGap(); BPLin.SetVoid(); BPLin.Update(xmin,ymin-M_PI-M_PI, xmax,ymax+M_PI+M_PI); BPLin.SetGap(g); } IntPatch_PolyArc Brise(arc,NbEchant,PFirst,PLast,BPLin); Standard_Integer IndiceOffsetBiPeriodic = 0; Standard_Integer IndiceOffsetPeriodic = 0; const Standard_Real aRefOU = OffsetU, aRefOV = OffsetV; do { if(IndiceOffsetBiPeriodic == 1) OffsetV = aRefOV - M_PI - M_PI; else if(IndiceOffsetBiPeriodic == 2) OffsetV = aRefOV + M_PI + M_PI; do { if(IndiceOffsetPeriodic == 1) OffsetU = aRefOU - M_PI - M_PI; else if(IndiceOffsetPeriodic == 2) OffsetU = aRefOU + M_PI + M_PI; Brise.SetOffset(OffsetU,OffsetV); static int debug_polygon2d =0; if(debug_polygon2d) { cout<<" ***** Numero Restriction : "<Has3d() && Standard_Integer(nptCh)+1 < Nbptlin); if (!isNptLow && !IsSegment2dSmall(Brise,UMinAr,UMaxAr,tolU,tolV)) { // treat both ends Standard_Real UMinChP,UMinArP,UMaxArP; UMinChP = IntegerPart(UMinCh); UMinArP = IntegerPart(UMinAr); UMaxArP = IntegerPart(UMaxAr); Standard_Integer irangAr1,irangAr2; irangAr1 = Standard_Integer(UMinArP)+1; irangAr2 = Standard_Integer(UMaxArP)+1; UMinChP = UMinCh - UMinChP; UMinArP = UMinAr - UMinArP; //UMaxChP = UMaxCh - UMaxChP; UMaxArP = UMaxAr - UMaxArP; const Standard_Real eps = 1e-10; // Standard_Boolean isChExtr1 = irangCh1==1 && UMinChPD0(U,V, anOldPnt); OtherSurf->D0(U2,V2, aNewPnt); if (anOldPnt.SquareDistance(aNewPnt) < Precision::Confusion() * Precision::Confusion()) { U2 = U; V2 = V; } paramarc = IntCS.ParameterOnCurve(); refined = Standard_True; } } } else { U2 = U; V2 = V; paramarc = W; arc->D0(paramarc,p2d); Surf->D0(p2d.X(),p2d.Y(),ptsommet); } if (!refine[ip] || refined) { duplicate = Standard_False; for (j=1; j<=locpt.Length();j++) { if (ptsommet.Distance(locpt(j)) <= edgeTol) { if (possiblyClosed) { locpt2(j).Coord(U,V); if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) || (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed)) continue; } duplicate = Standard_True; break; } } if (!duplicate) { Standard_Integer ParamApproxOnLine = Standard_Integer(W1[ip])+1; arc->D1(paramarc,p2d,d2d); U1 = p2d.X(); V1 = p2d.Y(); if (typL == IntPatch_Walking && SurfaceIsPeriodic) { if (OnFirst) Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2); else Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1); } locpt.Append(ptsommet); locpt2.Append(gp_Pnt2d(U2,V2)); found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2), paramline,tgline,ParamApproxOnLine,OnFirst); if (typL == IntPatch_Walking && found && possiblyClosed) { // check in 2d if (SurfaceIsUClosed || SurfaceIsVClosed) { GetLinePoint2d (L, paramline, OnFirst, U,V); if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) || (SurfaceIsVClosed && Abs(V-V1) > tolVClosed)) found = Standard_False; } if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) { GetLinePoint2d (L, paramline, !OnFirst, U,V); if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) || (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed)) found = Standard_False; } } if (!found) { continue; } VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc); Standard_Real vtxTol; if (VtxOnArc) { vtxTol = Tol3d(vtxarc,Domain); if (edgeTol > vtxTol) vtxTol = edgeTol; } else vtxTol = edgeTol; //-- It is necessary to test that the point does not already exist //-- - It can be already a point on arc //-- BUT on a different arc // MSV 27.03.2002: find the nearest point; add check in 2d Standard_Integer ivtx = 0; Standard_Real dmin = RealLast(); for (j=1; j<=Nbvtx; j++) { const IntPatch_Point& Rptline = (typL == IntPatch_Walking ? wlin->Vertex(j) : rlin->Vertex(j)); Standard_Boolean APointOnRstStillExist = ((OnFirst && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc) || (!OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc)); if(!APointOnRstStillExist) { if (possiblyClosed) { if (SurfaceIsUClosed || SurfaceIsVClosed) { if (OnFirst) Rptline.ParametersOnS1(U,V); else Rptline.ParametersOnS2(U,V); if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) || (SurfaceIsVClosed && Abs(V-V1) > tolVClosed)) continue; } if (OSurfaceIsUClosed || OSurfaceIsVClosed) { if (OnFirst) Rptline.ParametersOnS2(U,V); else Rptline.ParametersOnS1(U,V); if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) || (OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed)) continue; } } Standard_Real dist = ptsommet.Distance(Rptline.Value()); Standard_Real dt = Max(vtxTol, Rptline.Tolerance()); if (dist < dmin) { if (dist <= dt) { ptline = Rptline; ivtx = j; if( surfacetype == GeomAbs_Cone ) { ivtx = 0; } } else { // cancel previous solution because this point is better // but its tolerance is not large enough ivtx = 0; } dmin = dist; } } } if (ivtx) { if (ptline.Tolerance() > vtxTol) { vtxTol = ptline.Tolerance(); if (!VtxOnArc) { // now we should repeat attempt to coincide on a bound of arc VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc); if (VtxOnArc) { Standard_Real tol = Tol3d(vtxarc,Domain); if (tol > vtxTol) vtxTol = tol; } } } } if (typL == IntPatch_Walking) VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline); Surf->D1(U1,V1,ptbid,d1u,d1v); tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); normsurf = d1u.Crossed(d1v); if (normsurf.Magnitude() < gp::Resolution()) { transline.SetValue(Standard_True,IntSurf_Undecided); transarc.SetValue(Standard_True,IntSurf_Undecided); } else IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc); if (typL == IntPatch_Walking && !refine[ip]) { // for new vertex use coordinates from Line if (OnFirst) GetWLinePoint (wlin, paramline, U1,V1,U2,V2,ptsommet); else GetWLinePoint (wlin, paramline, U2,V2,U1,V1,ptsommet); } nbTreated++; if (!ivtx) { Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence if (OnFirst) Sommet.SetParameters(U1,V1,U2,V2); else Sommet.SetParameters(U2,V2,U1,V1); if (VtxOnArc) Sommet.SetVertex(OnFirst,vtxarc); //--------------------------------------------------------- //-- lbr : On remplace le point d indice paramline sur la - //-- ligne par le vertex . - //--------------------------------------------------------- Sommet.SetParameter(paramline); // sur ligne d intersection Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc); if (typL == IntPatch_Walking) { wlin->AddVertex(Sommet); Nbvtx++; } else { rlin->AddVertex(Sommet); Nbvtx++; } } else { // CAS DE FIGURE : en appelant s1 la surf sur laquelle on // connait les pts sur restriction, et s2 celle sur laquelle // on les cherche. Le point trouve verifie necessairement // IsOnDomS1 = True. // Pas vtxS1, pas vtxS2 : // on recupere le point et on applique SetArcOnS2 et // eventuellement SetVertexOnS2. Si on a deja IsOnDomS2, // on considere que le point est deja traite, mais ne devrait // pas se produire. // vtxS1, pas vtxS2 : // si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2, // et eventuellement SetVertexOnS2. // si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2. // vtxS1,vtxS2 : // on doit avoir VtxOnArc = True. On duplique chaque occurrence // "sur S1" du point en changeant ArcOnS2. // pas vtxS1, vtxS2 : // on doit avoir VtxOnArc = True. On duplique le point sur S1 // en changeant ArcOnS2. Standard_Boolean OnDifferentRst = ((OnFirst && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc) || (!OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc)); ptline.SetTolerance(vtxTol); if ( (!ptline.IsVertexOnS1() && OnFirst) || (!ptline.IsVertexOnS2() && !OnFirst) || (OnDifferentRst)) { if ( (!ptline.IsOnDomS2() && !OnFirst) ||(!ptline.IsOnDomS1() && OnFirst) ||(OnDifferentRst)) { ptline.SetArc(OnFirst,arc,paramarc,transline,transarc); //ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97 if (VtxOnArc) ptline.SetVertex(OnFirst,vtxarc); if (typL == IntPatch_Walking) { if(OnDifferentRst) { wlin->AddVertex(ptline); Nbvtx++; } else { wlin->Replace(ivtx,ptline); } } else { if(OnDifferentRst) { rlin->AddVertex(ptline); Nbvtx++; } else { rlin->Replace(ivtx,ptline); } } } else if ( ( OnFirst && ptline.IsVertexOnS2()) ||(!OnFirst && ptline.IsVertexOnS1())) { Sommet = ptline; Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc); if (VtxOnArc) Sommet.SetVertex(OnFirst,vtxarc); if (typL == IntPatch_Walking) { wlin->AddVertex(Sommet); Nbvtx++; } else { rlin->AddVertex(Sommet); Nbvtx++; } } else { //-- cout << "pb dans RstInt Type 1 " << endl; } } else { Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ; if ( ( OnFirst && !ptline.IsOnDomS2()) ||(!OnFirst && !ptline.IsOnDomS1())) { ptline.SetArc(OnFirst,arc,paramarc,transline,transarc); if (VtxOnArc) ptline.SetVertex(OnFirst,vtxarc); if (typL == IntPatch_Walking) { wlin->Replace(ivtx,ptline); } else { rlin->Replace(ivtx,ptline); } for (k=1; k<=Nbvtx; k++) if (k != ivtx) { if (typL == IntPatch_Walking) { ptline = wlin->Vertex(k); } else { ptline = rlin->Vertex(k); } if ( ( OnFirst && ptline.IsVertexOnS1()) || (!OnFirst && ptline.IsVertexOnS2())) { if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) { if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol); ptline.SetArc(OnFirst,arc,paramarc,transline,transarc); if (VtxOnArc) ptline.SetVertex(OnFirst,vtxarc); if (typL == IntPatch_Walking) { wlin->Replace(k,ptline); } else { rlin->Replace(k,ptline); } } } } } else if( ( OnFirst && ptline.IsVertexOnS2()) || (!OnFirst && ptline.IsVertexOnS1())) { // on doit avoir vtxons2 = vtxarc... pas de verif... Sommet = ptline; Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc); if (typL == IntPatch_Walking) { wlin->AddVertex(Sommet); Nbvtx++; } else { rlin->AddVertex(Sommet); Nbvtx++; } for (k=1; k<=Nbvtx; k++) if (k != ivtx) { if (typL == IntPatch_Walking) { ptline = wlin->Vertex(k); } else { ptline = rlin->Vertex(k); } if ( ( OnFirst && ptline.IsVertexOnS1()) ||(!OnFirst && ptline.IsVertexOnS2())) { if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) { if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol); Sommet = ptline; Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc); if (typL == IntPatch_Walking) { wlin->Replace(k,ptline); wlin->AddVertex(Sommet); Nbvtx++; } else { rlin->Replace(k,ptline); rlin->AddVertex(Sommet); Nbvtx++; } } } } } else { //-- cout << "pb dans RstInt Type 2 " << endl; } } } } } } if (nbTreated == 2 && typL == IntPatch_Walking) { // We processed a tangent zone, and both ends have been treated. // So mark WLine as having arc if(OnFirst) wlin->SetArcOnS1(arc); else wlin->SetArcOnS2(arc); } } IndiceOffsetPeriodic++; } while(SurfaceIsPeriodic && IndiceOffsetPeriodic<=2); IndiceOffsetBiPeriodic++; } while(SurfaceIsBiPeriodic && IndiceOffsetBiPeriodic<=2); Domain->Next(); } //-------------------------------------------------------------------------------- //-- On reprend la ligne et on recale les parametres des vertex. //-- if (typL == IntPatch_Walking) { Standard_Real pu1,pv1,pu2,pv2; pu1=pv1=pu2=pv2=0.0; switch(TypeS1) { case GeomAbs_Cylinder: case GeomAbs_Cone: case GeomAbs_Sphere: pu1=M_PI+M_PI; break; case GeomAbs_Torus: pu1=pv1=M_PI+M_PI; break; default: { if( Surf1->IsUPeriodic()) { pu1=Surf1->UPeriod(); } else if(Surf1->IsUClosed()) { pu1=Surf1->LastUParameter() - Surf1->FirstUParameter(); //cout<<" UClosed1 "<IsVPeriodic()) { pv1=Surf1->VPeriod(); } else if(Surf1->IsVClosed()) { pv1=Surf1->LastVParameter() - Surf1->FirstVParameter(); //cout<<" VClosed1 "<IsUPeriodic()) { pu2=Surf2->UPeriod(); } else if(Surf2->IsUClosed()) { pu2=Surf2->LastUParameter() - Surf2->FirstUParameter(); //cout<<" UClosed2 "<IsVPeriodic()) { pv2=Surf2->VPeriod(); } else if(Surf2->IsVClosed()) { pv2=Surf2->LastVParameter() - Surf2->FirstVParameter(); //cout<<" VClosed2 "<LastUParameter() - Surf1->FirstUParameter(); pu1+=pu1; } if(pu2==0) { pu2=Surf2->LastUParameter() - Surf2->FirstUParameter(); pu2+=pu2; } if(pv1==0) { pv1=Surf1->LastVParameter() - Surf1->FirstVParameter(); pv1+=pv1; } if(pv2==0) { pv2=Surf2->LastVParameter() - Surf2->FirstVParameter(); pv2+=pv2; } */ wlin->SetPeriod(pu1,pv1,pu2,pv2); wlin->ComputeVertexParameters(Tol); } else { rlin->ComputeVertexParameters(Tol); } }