// Created on: 1993-02-02 // Created by: Laurent BUCHARD // 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. // modified by Edward AGAPOV (eap) Tue Jan 22 12:29:55 2002 // modified by Oleg FEDYAED (ofv) Fri Nov 29 16:08:02 2002 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static void SectionPointToParameters(const Intf_SectionPoint& Sp, const IntPatch_Polyhedron& Surf1, const IntPatch_Polyhedron& Surf2, Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2); static void AdjustOnPeriodic(const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_HSurface)& Surf2, IntPatch_SequenceOfLine& aSLin); static IntSurf_PntOn2S MakeNewPoint(const IntSurf_PntOn2S& replacePnt, const IntSurf_PntOn2S& oldPnt, const Standard_Real* Periods); static Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S &thePOn2S, const Handle(IntPatch_WLine) &theWLine, const Standard_Real Deflection); static void AddWLine(IntPatch_SequenceOfLine &theLines, const Handle(IntPatch_WLine) &theWLine, const Standard_Real Deflection); static void SeveralWlinesProcessing(const Handle(Adaptor3d_HSurface)& theSurf1, const Handle(Adaptor3d_HSurface)& theSurf2, const IntPatch_SequenceOfLine& theSLin, const Standard_Real* const thePeriodsArr, const IntSurf_TypeTrans theTrans1, const IntSurf_TypeTrans theTrans2, const Standard_Real theTol, const Standard_Real theMaxStepS1, const Standard_Real theMaxStepS2, Handle(IntPatch_WLine)& theWLline) { if(theSLin.Length() == 0) return; Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0; Standard_Integer cnbV = theWLline->NbVertex(); Standard_Integer ciV; for( ciV = 1; ciV <= cnbV; ciV++ ) { Standard_Real pntDMin = 1.e+100; Standard_Integer VDMin = 0; Standard_Integer WLDMin = 0; gp_Pnt cPV = theWLline->Vertex(ciV).Value(); theWLline->Vertex(ciV).Parameters(aU1, aV1, aU2, aV2); const gp_Pnt2d aPCS1(aU1, aV1), aPCS2(aU2, aV2); Standard_Integer iL; for( iL = 1; iL <= theSLin.Length(); iL++) { const Handle(IntPatch_Line)& aSLine = theSLin.Value(iL); IntPatch_IType aType = aSLine->ArcType(); if( aType != IntPatch_Walking) continue; const Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(aSLine); Standard_Integer tnbV = aWLine->NbVertex(); Standard_Integer tiV; for( tiV = 1; tiV <= tnbV; tiV++ ) { gp_Pnt tPV = aWLine->Vertex(tiV).Value(); aWLine->Vertex(tiV).Parameters(aU1, aV1, aU2, aV2); const gp_Pnt2d aPTS1(aU1, aV1), aPTS2(aU2, aV2); Standard_Real tDistance = cPV.Distance(tPV); Standard_Real uRs1 = theSurf1->Surface().UResolution(tDistance); Standard_Real vRs1 = theSurf1->Surface().VResolution(tDistance); Standard_Real uRs2 = theSurf2->Surface().UResolution(tDistance); Standard_Real vRs2 = theSurf2->Surface().VResolution(tDistance); Standard_Real RmaxS1 = Max(uRs1,vRs1); Standard_Real RmaxS2 = Max(uRs2,vRs2); if(RmaxS1 < theMaxStepS1 && RmaxS2 < theMaxStepS2) { if( pntDMin > tDistance && tDistance > Precision::PConfusion()) { const Standard_Real aSqDist1 = aPCS1.SquareDistance(aPTS1), aSqDist2 = aPCS2.SquareDistance(aPTS2); if((aSqDist1 < RmaxS1*RmaxS1) && (aSqDist2 < RmaxS2*RmaxS2)) { pntDMin = tDistance; VDMin = tiV; WLDMin = iL; } } } } } if( VDMin != 0 ) { const Handle(IntPatch_Line)& aSLine = theSLin.Value(WLDMin); const Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(aSLine); Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine(); Standard_Integer ciVpar = (Standard_Integer)theWLline->Vertex(ciV).ParameterOnLine(); Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.; Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.; theWLline->Point(ciVpar).Parameters(u11,v11,u12,v12); aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22); Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S(); IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar); Standard_Integer cNbP = theWLline->NbPnts(); TColStd_SequenceOfInteger VPold; Standard_Integer iPo; for( iPo = 1; iPo <= cnbV; iPo++ ) { Standard_Real Po = theWLline->Vertex(iPo).ParameterOnLine(); Standard_Integer IPo = (Standard_Integer) Po; VPold.Append(IPo); } Standard_Boolean removeNext = Standard_False; Standard_Boolean removePrev = Standard_False; if( ciV == 1) { Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1)); if(dPar > 10) { removeNext = Standard_True; for( iPo = (ciV+1); iPo <= cnbV; iPo++ ) VPold.SetValue(iPo, VPold.Value(iPo) - 1 ); } } else if( ciV == cnbV) { Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1)); if(dPar > 10) { removePrev = Standard_True; VPold.SetValue(ciV, VPold.Value(ciV) - 1 ); } } else { Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1)); Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1)); if(dParMi > 10) { removePrev = Standard_True; VPold.SetValue(ciV, VPold.Value(ciV) - 1 ); } if(dParMa > 10) { removeNext = Standard_True; for( iPo = (ciV+1); iPo <= cnbV; iPo++ ) { if(dParMi > 10) VPold.SetValue(iPo, VPold.Value(iPo) - 2 ); else VPold.SetValue(iPo, VPold.Value(iPo) - 1 ); } } else { if(dParMi > 10) for( iPo = (ciV+1); iPo <= cnbV; iPo++ ) VPold.SetValue(iPo, VPold.Value(iPo) - 1 ); } } Standard_Integer pI = ciVpar; Standard_Integer iP; for( iP = 1; iP <= cNbP; iP++) { if( pI == iP ) { IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, theWLline->Point(iP), thePeriodsArr); newL2s->Add(newPnt); } else if(removeNext && iP == (pI + 1)) continue; else if(removePrev && iP == (pI - 1)) continue; else newL2s->Add(theWLline->Point(iP)); } IntPatch_Point newVtx; gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value(); newVtx.SetValue(Pnt3dV,theTol,Standard_False); newVtx.SetParameters(u21,v21,u22,v22); newVtx.SetParameter(VPold.Value(ciV)); Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,theTrans1,theTrans2); Standard_Integer iV; for( iV = 1; iV <= cnbV; iV++ ) { if( iV == ciV ) NWLine->AddVertex(newVtx); else { IntPatch_Point theVtx = theWLline->Vertex(iV); theVtx.SetParameter(VPold.Value(iV)); NWLine->AddVertex(theVtx); } } theWLline = NWLine; }//if( VDMin != 0 ) }//for( ciV = 1; ciV <= cnbV; ciV++ ) } //======================================================================= //function : DublicateOfLinesProcessing //purpose : Decides, if rejecting current line is necessary //======================================================================= static void DublicateOfLinesProcessing( const IntWalk_PWalking& thePW, const Standard_Integer theWLID, IntPatch_SequenceOfLine& theLines, Standard_Boolean& theIsRejectReq) { const Handle(IntPatch_WLine)& anExistWL = *((Handle(IntPatch_WLine)*)&theLines.Value(theWLID)); const Standard_Integer aNbPrevPoints = anExistWL->NbPnts(); const Standard_Integer aNbCurrPoints = thePW.NbPoints(); if(aNbPrevPoints < aNbCurrPoints) {//Remove preview line theLines.Remove(theWLID); theIsRejectReq = Standard_False; } else if(aNbPrevPoints == aNbCurrPoints) { Standard_Real aLPrev = 0.0, aLCurr = 0.0; for(Standard_Integer aNbPP = 1; aNbPP < aNbPrevPoints; aNbPP++) { const gp_Pnt aP1prev(anExistWL->Point(aNbPP).Value()), aP2prev(anExistWL->Point(aNbPP+1).Value()); const gp_Pnt aP1curr(thePW.Value(aNbPP).Value()), aP2curr(thePW.Value(aNbPP+1).Value()); aLPrev += aP1prev.Distance(aP2prev); aLCurr += aP1curr.Distance(aP2curr); } if(aLPrev < aLCurr) {//Remove preview line theLines.Remove(theWLID); theIsRejectReq = Standard_False; } } } //================================================================================== // function : // purpose : //================================================================================== IntPatch_PrmPrmIntersection::IntPatch_PrmPrmIntersection(): done(Standard_False) { } //================================================================================== // function : Perform // purpose : //================================================================================== void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_TopolTool)& D1, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment) { IntPatch_Polyhedron Poly1( Surf1, D1->NbSamplesU(), D1->NbSamplesV() ); Perform( Surf1, Poly1, D1, TolTangency, Epsilon, Deflection, Increment ); } //================================================================================== // function : Perform // purpose : //================================================================================== void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1, const IntPatch_Polyhedron& Poly1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& Surf2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment) { IntPatch_Polyhedron Poly2( Surf2 ); Perform( Surf1, Poly1, D1, Surf2, Poly2, D2, TolTangency, Epsilon, Deflection, Increment); } //================================================================================== // function : Perform // purpose : //================================================================================== void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& Surf2, const IntPatch_Polyhedron& Poly2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment) { IntPatch_Polyhedron Poly1( Surf1 ); Perform( Surf1, Poly1, D1, Surf2, Poly2, D2, TolTangency, Epsilon, Deflection, Increment ); } //================================================================================== // function : Perform // purpose : //================================================================================== void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1, const IntPatch_Polyhedron& Poly1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& Surf2, const IntPatch_Polyhedron& Poly2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment) { IntPatch_InterferencePolyhedron Interference(Poly1,Poly2); empt = Standard_True; done = Standard_True; SLin.Clear(); Standard_Integer nbLigSec = Interference.NbSectionLines(); Standard_Integer nbTanZon = Interference.NbTangentZones(); Standard_Integer NbLigCalculee = 0; Standard_Real U1,U2,V1,V2; Standard_Real pu1,pu2,pv1,pv2; TColStd_Array1OfReal StartParams(1,4); IntWalk_PWalking PW( Surf1, Surf2, TolTangency, Epsilon, Deflection, Increment ); Standard_Real SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant Standard_Real incidence; Standard_Real dminiPointLigne; Standard_Boolean HasStartPoint,RejetLigne; IntSurf_PntOn2S StartPOn2S; Standard_Integer ver; gp_Pnt Point3dDebut,Point3dFin; if( nbLigSec >= 1 ) { Standard_Integer *TabL = new Standard_Integer [nbLigSec+1]; Standard_Integer ls; for( ls = 1; ls <= nbLigSec; ls++ ) TabL[ls]=ls; Standard_Boolean triok; do { triok=Standard_True; for(Standard_Integer b=2; b<=nbLigSec; b++) { Standard_Integer nb_B = Interference.LineValue(TabL[b]).NumberOfPoints(); Standard_Integer nb_A = Interference.LineValue(TabL[b-1]).NumberOfPoints(); if( nb_B > nb_A ) { Standard_Integer tyu=TabL[b]; TabL[b]=TabL[b-1]; TabL[b-1]=tyu; triok=Standard_False; } } } while( triok==Standard_False ); for( ls = 1; ls <= nbLigSec; ls++) { const Intf_SectionLine& LineSec=Interference.LineValue(TabL[ls]); Standard_Integer nbp = LineSec.NumberOfPoints(); Standard_Integer *TabPtDep = new Standard_Integer [nbp+1]; Standard_Integer ilig; for( ilig = 1; ilig <= nbp; ilig++) TabPtDep[ilig]=0; Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1; Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2; SectionPointToParameters(LineSec.GetPoint(1),Poly1,Poly2,UminLig1,VminLig1,UminLig2,VminLig2); UmaxLig1=UminLig1; VmaxLig1=VminLig1; UmaxLig2=UminLig2; VmaxLig2=VminLig2; for( ilig = 2; ilig <= nbp; ilig++ ) { SectionPointToParameters(LineSec.GetPoint(ilig),Poly1,Poly2,U1,V1,U2,V2); if(U1>UmaxLig1) UmaxLig1=U1; if(V1>VmaxLig1) VmaxLig1=V1; if(U2>UmaxLig2) UmaxLig2=U2; if(V2>VmaxLig2) VmaxLig2=V2; if(U13)? (nbp/2) : 1; Standard_Integer NombreDePointsDeDepartDuCheminement = 0; Standard_Integer IndicePointdeDepart1 = 0,IndicePointdeDepart2 = 0; Standard_Boolean lignetrouvee=Standard_False; do { NombreDePointsDeDepartDuCheminement++; if(NombreDePointsDeDepartDuCheminement == 1) { incidence=3.0; Standard_Integer nbp1_4=nbp/4; Standard_Integer nbp3_4=nbp-nbp1_4; Standard_Integer nsp; for(nsp=nbp/2; nspnbp1_4; nsp--) { Standard_Real CurrentIncidence = LineSec.GetPoint(nsp).Incidence(); if(CurrentIncidence < incidence) { nbps2 = nsp; incidence = 0.9*CurrentIncidence; } } if(nbp<3) NombreDePointsDeDepartDuCheminement=3; IndicePointdeDepart1 = nbps2; } else if(NombreDePointsDeDepartDuCheminement == 2) { if(IndicePointdeDepart1 == 1) { nbps2 = nbp/2; IndicePointdeDepart2 = nbps2; } else { nbps2 = 1; IndicePointdeDepart2 = 1; } } else if(NombreDePointsDeDepartDuCheminement == 3) { if(IndicePointdeDepart1 == nbp) nbps2 = (IndicePointdeDepart1+IndicePointdeDepart2)/2; else nbps2 = nbp; } else { nbps2 = NombreDePointsDeDepartDuCheminement-3; NombreDePointsDeDepartDuCheminement++; } if(TabPtDep[nbps2]==0) { TabPtDep[nbps2]=1; SectionPointToParameters(LineSec.GetPoint(nbps2),Poly1,Poly2,U1,V1,U2,V2); StartParams(1) = U1; StartParams(2) = V1; StartParams(3) = U2; StartParams(4) = V2; HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S); dminiPointLigne = SeuildPointLigne + SeuildPointLigne; if(HasStartPoint) { StartPOn2S.Parameters(pu1,pv1,pu2,pv2); NbLigCalculee = SLin.Length(); Standard_Integer l; for( l=1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if (IsPointOnLine(StartPOn2S, testwline, Deflection)) { dminiPointLigne = 0.0; } } // for ( l ... if(dminiPointLigne > SeuildPointLigne) { PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2,UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2); if(PW.IsDone()) { if(PW.NbPoints()>2) { RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); Point3dFin = PointFin.Value(); for( ver = 1 ; ver<= NbLigCalculee ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); // Check end point if it is on existing line. // Start point is checked before. if (IsPointOnLine(PointFin, verwline, Deflection)) { RejetLigne = Standard_True; break; } const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if( (Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency) && (Point3dFin.Distance(verPointFin.Value()) <= TolTangency)) { RejetLigne = Standard_True; break; } } if(RejetLigne) { DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne); } if(!RejetLigne) { // Calculation transition IntSurf_TypeTrans trans1,trans2; Standard_Real locu,locv; gp_Vec norm1,norm2,d1u,d1v; gp_Pnt ptbid; Standard_Integer indextg; gp_Vec tgline(PW.TangentAtLine(indextg)); PW.Line()->Value(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf2->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if(tgline.DotCross(norm2,norm1)>0.) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); if(wline->NbVertex() == 0) { IntPatch_Point vtx; IntSurf_PntOn2S POn2S = PW.Line()->Value(1); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); POn2S = PW.Line()->Value(wline->NbPnts()); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } lignetrouvee = Standard_True; AddWLine(SLin, wline, Deflection); empt = Standard_False; }// !RejetLigne }// PW.NbPoints()>2 }// done is True }// dminiPointLigne > SeuildPointLigne }// HasStartPoint }// TabPtDep[nbps2]==0 } while( nbp>5 && ( !( ( (NombreDePointsDeDepartDuCheminement >= 3) && lignetrouvee ) || ( (NombreDePointsDeDepartDuCheminement-3>=nbp) && !lignetrouvee ) ) ) ); delete [] TabPtDep; }// for( ls ... delete [] TabL; }// nbLigSec >= 1 Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1; Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2; UminLig1=VminLig1=UminLig2=VminLig2=RealLast(); UmaxLig1=VmaxLig1=UmaxLig2=VmaxLig2=-UminLig1; Standard_Integer z; for(z=1; z <= nbTanZon; z++) { const Intf_TangentZone& TangentZone=Interference.ZoneValue(z); for(Standard_Integer pz=1; pz<=TangentZone.NumberOfPoints(); pz++) { SectionPointToParameters(TangentZone.GetPoint(pz),Poly1,Poly2,U1,V1,U2,V2); if(U1>UmaxLig1) UmaxLig1=U1; if(V1>VmaxLig1) VmaxLig1=V1; if(U2>UmaxLig2) UmaxLig2=U2; if(V2>VmaxLig2) VmaxLig2=V2; if(U1= SeuildPointLigne); l++) { const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if (IsPointOnLine(StartPOn2S, testwline, Deflection)) { dminiPointLigne = 0.0; } }// for( l ... if(dminiPointLigne > SeuildPointLigne) { PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2,UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2); if(PW.IsDone()) { if(PW.NbPoints()>2) { RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); Point3dFin = PointFin.Value(); for(ver=1 ; ver<= NbLigCalculee ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); // Check end point if it is on existing line. // Start point is checked before. if (IsPointOnLine(PointFin, verwline, Deflection)) { RejetLigne = Standard_True; break; } const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if( (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) || (Point3dFin.Distance(verPointFin.Value()) < TolTangency)) { RejetLigne = Standard_True; break; } } if(RejetLigne) { DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne); } if(!RejetLigne) { IntSurf_TypeTrans trans1,trans2; Standard_Real locu,locv; gp_Vec norm1,norm2,d1u,d1v; gp_Pnt ptbid; Standard_Integer indextg; gp_Vec tgline(PW.TangentAtLine(indextg)); PW.Line()->Value(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf2->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if(tgline.DotCross(norm2,norm1)>0.) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); if(wline->NbVertex() == 0) { IntPatch_Point vtx; IntSurf_PntOn2S POn2S = PW.Line()->Value(1); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); POn2S = PW.Line()->Value(wline->NbPnts()); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } AddWLine(SLin, wline, Deflection); empt = Standard_False; }// if !RejetLigne }// PW.NbPoints()>2 }// done is True }// dminiPointLigne > SeuildPointLigne }// HasStartPoint }// for( pz ... }// for( z ... } //================================================================================== // function : Perform // purpose : //================================================================================== void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1, const IntPatch_Polyhedron& Poly1, const Handle(Adaptor3d_TopolTool)& D1, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment) { IntPatch_InterferencePolyhedron Interference(Poly1); empt = Standard_True; done = Standard_True; SLin.Clear(); Standard_Integer nbLigSec = Interference.NbSectionLines(); Standard_Integer nbTanZon = Interference.NbTangentZones(); Standard_Integer NbPntOn2SOnLine; Standard_Integer NbLigCalculee = 0; Standard_Real U1,U2,V1,V2; Standard_Real pu1,pu2,pv1,pv2; TColStd_Array1OfReal StartParams(1,4); IntWalk_PWalking PW(Surf1,Surf1,TolTangency,Epsilon,Deflection,Increment); Standard_Real SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant Standard_Real incidence; Standard_Real dminiPointLigne; Standard_Boolean HasStartPoint,RejetLigne; IntSurf_PntOn2S StartPOn2S; Standard_Integer ver; gp_Pnt Point3dDebut,Point3dFin; if(nbLigSec>=1) { Standard_Integer ls; for( ls = 1; ls <= nbLigSec; ls++) { const Intf_SectionLine& LineSec=Interference.LineValue(ls); Standard_Integer nbp = LineSec.NumberOfPoints(); Standard_Integer nbps2 = (nbp>3)? (nbp/2) : 1; Standard_Integer NombreDePointsDeDepartDuCheminement = 0; Standard_Integer IndicePointdeDepart1 = 0, IndicePointdeDepart2 = 0; do { NombreDePointsDeDepartDuCheminement++; if(NombreDePointsDeDepartDuCheminement == 1) { incidence = 0.0; Standard_Integer nsp1; for( nsp1= nbp/2; nsp1 >= 1; nsp1--) { SectionPointToParameters(LineSec.GetPoint(nsp1),Poly1,Poly1,U1,V1,U2,V2); Standard_Real CurrentIncidence = Abs(U1-U2)+Abs(V1-V2); if(CurrentIncidence > incidence) { nbps2 = nsp1; incidence = CurrentIncidence; } } for( nsp1 = nbp/2; nsp1 <= nbp; nsp1++) { SectionPointToParameters(LineSec.GetPoint(nsp1),Poly1,Poly1,U1,V1,U2,V2); Standard_Real CurrentIncidence = Abs(U1-U2)+Abs(V1-V2); if(CurrentIncidence > incidence) { nbps2 = nsp1; incidence = CurrentIncidence; } } if(nbp<3) NombreDePointsDeDepartDuCheminement=3; IndicePointdeDepart1 = nbps2; } else if(NombreDePointsDeDepartDuCheminement == 2) { if(IndicePointdeDepart1 == 1) { nbps2 = nbp/2; IndicePointdeDepart2 = nbps2; } else { nbps2 = 1; IndicePointdeDepart2 = 1; } } else { if(IndicePointdeDepart1 == nbp) nbps2 = (IndicePointdeDepart1+IndicePointdeDepart2)/2; else nbps2 = nbp; } SectionPointToParameters(LineSec.GetPoint(nbps2),Poly1,Poly1,U1,V1,U2,V2); StartParams(1) = U1; StartParams(2) = V1; StartParams(3) = U2; StartParams(4) = V2; HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S); dminiPointLigne = SeuildPointLigne + SeuildPointLigne; if(HasStartPoint) { StartPOn2S.Parameters(pu1,pv1,pu2,pv2); if(Abs(pu1-pu2)>1e-7 || Abs(pv1-pv2)>1e-7) { NbLigCalculee = SLin.Length(); Standard_Integer l; for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) && (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) && (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { NbPntOn2SOnLine = testwline->NbPnts(); Standard_Integer ll; for( ll=1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++) { Standard_Real t,Au1,Av1,Au2,Av2,Bu1,Bv1,Bu2,Bv2; testwline->Point(ll).Parameters(Au1,Av1,Au2,Av2); testwline->Point(ll+1).Parameters(Bu1,Bv1,Bu2,Bv2); if(Au1>Bu1) { t=Au1; Au1=Bu1; Bu1=t; } if(Av1>Bv1) { t=Av1; Av1=Bv1; Bv1=t; } Au1-=1.0e-7; Av1-=1.0e-7; Bu1+=1.0e-7; Bv1+=1.0e-7; if((pu1>=Au1) && (pu1<=Bu1) && (pv1>=Av1) && (pv1<=Bv1)) dminiPointLigne = 0.0; else { if((pu2>=Au1) && (pu2<=Bu1) && (pv2>=Av1) && (pv2<=Bv1)) dminiPointLigne = 0.0; } }// for( ll ... }// if ... }// for( l ... if(dminiPointLigne > SeuildPointLigne) { PW.Perform(StartParams); if(PW.IsDone()) { if(PW.NbPoints()>2) { RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); Point3dFin = PW.Value(PW.NbPoints()).Value(); for(ver=1 ; ver<= NbLigCalculee ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if( (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) || (Point3dFin.Distance(verPointFin.Value()) < TolTangency)) { RejetLigne = Standard_True; break; } } if(RejetLigne) { DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne); } if(!RejetLigne) { IntSurf_TypeTrans trans1,trans2; Standard_Real locu,locv; gp_Vec norm1,norm2,d1u,d1v; gp_Pnt ptbid; Standard_Integer indextg; gp_Vec tgline(PW.TangentAtLine(indextg)); PW.Line()->Value(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if (tgline.DotCross(norm2,norm1)>0.) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } IntSurf_LineOn2S LineOn2S; Standard_Integer nbpw,imin,imax,i; nbpw = PW.Line()->NbPoints(); Standard_Real u1,v1,u2,v2; i=0; do { i++; imin=i; const IntSurf_PntOn2S& Pi = PW.Line()->Value(i); Pi.Parameters(u1,v1,u2,v2); } while((i2) imin--; i=nbpw+1; do { i--; imax=i; const IntSurf_PntOn2S& Pi = PW.Line()->Value(i); Pi.Parameters(u1,v1,u2,v2); } while((i>2)&&(Abs(u1-u2)<=1e-6 && Abs(v1-v2)<=1e-6)); if(imaxAdd(PW.Line()->Value(i)); Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PWLine,Standard_False,trans1,trans2); const IntSurf_PntOn2S& POn2SDeb = wline->Point(1); const IntSurf_PntOn2S& POn2SFin = wline->Point(wline->NbPnts()); if((POn2SDeb.Value()).Distance(POn2SFin.Value()) <= TolTangency) { Standard_Real u1t,v1t,u2t,v2t; POn2SDeb.Parameters(u1t,v1t,u2t,v2t); IntPatch_Point vtx; vtx.SetValue(POn2SDeb.Value(),TolTang,Standard_False); vtx.SetParameters(u2t,v2t,u1t,v1t); vtx.SetParameter(wline->NbPnts()); wline->SetPoint(wline->NbPnts(),vtx); } IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf1,Standard_True,TolTang); if(wline->NbVertex() == 0) { IntPatch_Point vtx; IntSurf_PntOn2S POn2S = PW.Line()->Value(1); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); POn2S = PW.Line()->Value(wline->NbPnts()); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } SLin.Append(wline); empt = Standard_False; }// imin2 }// done is True }// dminiPointLigne > SeuildPointLigne }// Abs || Abs }// HasStartPoint } while(nbp>5 && NombreDePointsDeDepartDuCheminement<3); }// for( ls ... }// nbLigSec>=1 Standard_Integer z; for( z = 1; z <= nbTanZon; z++) { const Intf_TangentZone& TangentZone=Interference.ZoneValue(z); for(Standard_Integer pz=1; pz<=TangentZone.NumberOfPoints(); pz++) { SectionPointToParameters(TangentZone.GetPoint(pz),Poly1,Poly1,U1,V1,U2,V2); StartParams(1) = U1; StartParams(2) = V1; StartParams(3) = U2; StartParams(4) = V2; HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S); if(HasStartPoint) { StartPOn2S.Parameters(pu1,pv1,pu2,pv2); if(Abs(pu1-pu2)>1e-7 || Abs(pv1-pv2)>1e-7) { NbLigCalculee = SLin.Length(); dminiPointLigne = SeuildPointLigne + SeuildPointLigne; Standard_Integer l; for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if( (testwline->IsOutSurf1Box(gp_Pnt2d(pu1,pv1))==Standard_False) && (testwline->IsOutSurf2Box(gp_Pnt2d(pu2,pv2))==Standard_False) && (testwline->IsOutBox(StartPOn2S.Value())==Standard_False) ) { NbPntOn2SOnLine = testwline->NbPnts(); Standard_Integer ll; for( ll = 1; (ll < NbPntOn2SOnLine) && (dminiPointLigne >= SeuildPointLigne); ll++) { Standard_Real t,Au1,Av1,Au2,Av2,Bu1,Bv1,Bu2,Bv2; testwline->Point(ll).Parameters(Au1,Av1,Au2,Av2); testwline->Point(ll+1).Parameters(Bu1,Bv1,Bu2,Bv2); if(Au1>Bu1) { t=Au1; Au1=Bu1; Bu1=t; } if(Av1>Bv1) { t=Av1; Av1=Bv1; Bv1=t; } Au1-=1.0e-7; Av1-=1.0e-7; Bu1+=1.0e-7; Bv1+=1.0e-7; if((pu1>=Au1) && (pu1<=Bu1) && (pv1>=Av1) && (pv1<=Bv1)) dminiPointLigne = 0.0; else { if((pu2>=Au1) && (pu2<=Bu1) && (pv2>=Av1) && (pv2<=Bv1)) dminiPointLigne = 0.0; } }// for( ll ... }// if ... }// for( l ... if(dminiPointLigne > SeuildPointLigne) { PW.Perform(StartParams); if(PW.IsDone()) { if(PW.NbPoints()>2) { RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); Point3dFin = PW.Value(PW.NbPoints()).Value(); for( ver = 1 ; ver<= NbLigCalculee ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if( (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) || (Point3dFin.Distance(verPointFin.Value()) < TolTangency)) { RejetLigne = Standard_True; break; } } if(RejetLigne) { DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne); } if(!RejetLigne) { IntSurf_TypeTrans trans1,trans2; Standard_Real locu,locv; gp_Vec norm1,norm2,d1u,d1v; gp_Pnt ptbid; Standard_Integer indextg; gp_Vec tgline(PW.TangentAtLine(indextg)); PW.Line()->Value(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if(tgline.DotCross(norm2,norm1)>0.) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } IntSurf_LineOn2S LineOn2S; Standard_Integer nbp,imin,imax,i; nbp = PW.Line()->NbPoints(); Standard_Real u1,v1,u2,v2; i=0; do { i++; imin=i; const IntSurf_PntOn2S& Pi = PW.Line()->Value(i); Pi.Parameters(u1,v1,u2,v2); } while((i2) imin--; i=nbp+1; do { i--; imax=i; const IntSurf_PntOn2S& Pi = PW.Line()->Value(i); Pi.Parameters(u1,v1,u2,v2); } while((i>2)&&(Abs(u1-u2)<=1e-6 && Abs(v1-v2)<=1e-6)); if(imaxAdd(PW.Line()->Value(i)); Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PWLine,Standard_False,trans1,trans2); const IntSurf_PntOn2S& POn2SDeb = wline->Point(1); const IntSurf_PntOn2S& POn2SFin = wline->Point(wline->NbPnts()); if((POn2SDeb.Value()).Distance(POn2SFin.Value()) <= TolTangency) { Standard_Real u1t,v1t,u2t,v2t; POn2SDeb.Parameters(u1t,v1t,u2t,v2t); IntPatch_Point vtx; vtx.SetValue(POn2SDeb.Value(),TolTang,Standard_False); vtx.SetParameters(u2t,v2t,u1t,v1t); vtx.SetParameter(wline->NbPnts()); wline->SetPoint(wline->NbPnts(),vtx); } IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf1,Standard_True,TolTang); if(wline->NbVertex() == 0) { IntPatch_Point vtx; IntSurf_PntOn2S POn2S = PW.Line()->Value(1); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); POn2S = PW.Line()->Value(wline->NbPnts()); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } SLin.Append(wline); empt = Standard_False; }// imin2 }// done a True }// dminiPointLigne > SeuildPointLigne }// Abs || Abs }// HasStartPoint }// for ( pz ... }// for( z ... } //================================================================================== // function : NewLine // purpose : //================================================================================== Handle(IntPatch_Line) IntPatch_PrmPrmIntersection::NewLine (const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_HSurface)& Surf2, const Standard_Integer NumLine, const Standard_Integer Low, const Standard_Integer High, const Standard_Integer NbPntsToInsert) const { Standard_Integer NbPnts = NbPntsToInsert + High - Low; if(NumLine>NbLines() || NumLine<1 || Low>=High ) Standard_OutOfRange::Raise(" IntPatch_PrmPrmIntersection NewLine "); //------------------------------------------------------------------ //-- Indice : Low Low+1 I I+1 High -- //-- -- //-- Abs.Curv. : S(Low) S(I) S(I+1) S(High) -- //-- -- //-- On echantillonne a abcisse curviligne -- //-- constante. -- //-- L abcisse est calculee sur les params U1,V1 -- //------------------------------------------------------------------ TColStd_Array1OfReal U1(Low,High); TColStd_Array1OfReal V1(Low,High); TColStd_Array1OfReal U2(Low,High); TColStd_Array1OfReal V2(Low,High); TColStd_Array1OfReal AC(Low,High); Standard_Real s,ds; Handle(IntPatch_WLine) TheLine = Handle(IntPatch_WLine)::DownCast(Line(NumLine)); const IntSurf_PntOn2S& Point=TheLine->Point(Low); Standard_Real u1,v1,u2,v2; Point.Parameters(u1,v1,u2,v2); U1(Low) = u1; V1(Low) = v1; U2(Low) = u2; V2(Low) = v2; AC(Low) =0.0; IntWalk_PWalking PW(Surf1,Surf2,0.000001,0.000001,0.001,0.001); Standard_Integer i; for(i=Low+1; i<=High; i++) { const IntSurf_PntOn2S& Pointi=TheLine->Point(i); Pointi.Parameters(u1,v1,u2,v2); U1(i) = u1; V1(i) = v1; U2(i) = u2; V2(i) = v2; Standard_Real du1=u1-U1(i-1); Standard_Real dv1=v1-V1(i-1); AC(i) = AC(i-1) + Sqrt((du1*du1)+(dv1*dv1)); } Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S(); IntSurf_PntOn2S StartPOn2S; TColStd_Array1OfReal StartParams(1,4); ResultPntOn2SLine->Add(TheLine->Point(Low)); ds = AC(High) / (NbPnts-1); Standard_Integer Indice = Low; Standard_Real dsmin = ds*0.3; Standard_Real smax = AC(High); for(i=2,s=ds; (iAdd(TheLine->Point(Indice)); Indice++; } Standard_Real a = s - AC(Indice); Standard_Real b = AC(Indice+1) - s; Standard_Real nab = 1.0/(a+b); //---------------------------------------------------------- //-- Verification : Si Dist au prochain point < dsmin -- //-- Si Dist au precedent point < dsmin -- //-- -- //---------------------------------------------------------- if((nab > ds)&&(a>dsmin)&&(b>dsmin)) { StartParams(1) = (U1(Indice) * b + U1(Indice+1) * a) * nab; StartParams(2) = (V1(Indice) * b + V1(Indice+1) * a) * nab; StartParams(3) = (U2(Indice) * b + U2(Indice+1) * a) * nab; StartParams(4) = (V2(Indice) * b + V2(Indice+1) * a) * nab; Standard_Boolean HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S); if(HasStartPoint) ResultPntOn2SLine->Add(StartPOn2S); } else s+=dsmin; } ResultPntOn2SLine->Add(TheLine->Point(High)); return(new IntPatch_WLine(ResultPntOn2SLine,Standard_False)); } //================================================================================== // function : SectionPointToParameters // purpose : //================================================================================== void SectionPointToParameters(const Intf_SectionPoint& Sp, const IntPatch_Polyhedron& Poly1, const IntPatch_Polyhedron& Poly2, Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2) { Intf_PIType typ; Standard_Integer Adr1,Adr2; Standard_Real Param,u,v; gp_Pnt P(Sp.Pnt()); Standard_Integer Pt1,Pt2,Pt3; Sp.InfoFirst(typ,Adr1,Adr2,Param); switch(typ) { case Intf_VERTEX: //-- Adr1 est le numero du vertex { Poly1.Parameters(Adr1,u1,v1); break; } case Intf_EDGE: { Poly1.Parameters(Adr1,u1,v1); Poly1.Parameters(Adr2,u,v); u1+= Param * (u-u1); v1+= Param * (v-v1); break; } case Intf_FACE: { Standard_Real ua,va,ub,vb,uc,vc,ca,cb,cc,cabc; Poly1.Triangle(Adr1,Pt1,Pt2,Pt3); gp_Pnt PA(Poly1.Point(Pt1)); gp_Pnt PB(Poly1.Point(Pt2)); gp_Pnt PC(Poly1.Point(Pt3)); Poly1.Parameters(Pt1,ua,va); Poly1.Parameters(Pt2,ub,vb); Poly1.Parameters(Pt3,uc,vc); gp_Vec Normale(gp_Vec(PA,PB).Crossed(gp_Vec(PA,PC))); cc = (gp_Vec(PA,PB).Crossed(gp_Vec(PA,P))).Dot(Normale); ca = (gp_Vec(PB,PC).Crossed(gp_Vec(PB,P))).Dot(Normale); cb = (gp_Vec(PC,PA).Crossed(gp_Vec(PC,P))).Dot(Normale); cabc = ca + cb + cc; ca/=cabc; cb/=cabc; cc/=cabc; u1 = ca * ua + cb * ub + cc * uc; v1 = ca * va + cb * vb + cc * vc; break; } default: { //-- cout<<" Default dans SectionPointToParameters "<>1; yg = (y1+y2)>>1; zg = (z1+z2)>>1; RemplitLin(x1,y1,z1,xg,yg,zg,Map); RemplitLin(x2,y2,z2,xg,yg,zg,Map); } //================================================================================== // function : RemplitTri // purpose : //================================================================================== void IntPatch_PrmPrmIntersection::RemplitTri(const Standard_Integer x1, const Standard_Integer y1, const Standard_Integer z1, const Standard_Integer x2, const Standard_Integer y2, const Standard_Integer z2, const Standard_Integer x3, const Standard_Integer y3, const Standard_Integer z3, IntPatch_PrmPrmIntersection_T3Bits& Map) const { if(x1==x2 && x1==x3 && y1==y2 && y1==y3 && z1==z2 && z1==z3) { if(DansGrille(x1) && DansGrille(y1) && DansGrille(z1)) { Standard_Integer t = GrilleInteger(x1,y1,z1); Map.Add(t); } return; } else { Standard_Integer xg=(x1+x2+x3)/3; Standard_Integer yg=(y1+y2+y3)/3; Standard_Integer zg=(z1+z2+z3)/3; if(xg==x1 && yg==y1 && zg==z1) { RemplitLin(x1,y1,z1,x2,y2,z2,Map); RemplitLin(x1,y1,z1,x3,y3,z3,Map); return; } if(xg==x2 && yg==y2 && zg==z2) { RemplitLin(x2,y2,z2,x1,y1,z1,Map); RemplitLin(x2,y2,z2,x3,y3,z3,Map); return; } if(xg==x3 && yg==y3 && zg==z3) { RemplitLin(x3,y3,z3,x2,y2,z2,Map); RemplitLin(x3,y3,z3,x1,y1,z1,Map); return; } if(DansGrille(xg) && DansGrille(yg) && DansGrille(zg)) { Standard_Integer t = GrilleInteger(xg,yg,zg); Map.Add(t); } if(xg!=x3 || yg!=y3 || zg!=z3) RemplitTri(x1,y1,z1, x2,y2,z2, xg,yg,zg, Map); if(xg!=x1 || yg!=y1 || zg!=z1) RemplitTri(xg,yg,zg, x2,y2,z2, x3,y3,z3, Map); if(xg!=x2 || yg!=y2 || zg!=z2) RemplitTri(x1,y1,z1, xg,yg,zg, x3,y3,z3, Map); } } //================================================================================== // function : Remplit // purpose : //================================================================================== void IntPatch_PrmPrmIntersection::Remplit(const Standard_Integer a, const Standard_Integer b, const Standard_Integer c, IntPatch_PrmPrmIntersection_T3Bits& Map) const { int iax,iay,iaz,ibx,iby,ibz,icx,icy,icz; if(a!=-1) Map.Add(a); if(b!=-1) Map.Add(b); if(c!=-1) Map.Add(c); if(a!=-1 && b!=-1 && c!=-1 ) { IntegerGrille(a,iax,iay,iaz); IntegerGrille(b,ibx,iby,ibz); IntegerGrille(c,icx,icy,icz); RemplitTri(iax,iay,iaz,ibx,iby,ibz,icx,icy,icz,Map); } } //======================================================================= //function : Perform //purpose : //======================================================================= void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& Surf2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine) { if (LOfPnts.IsEmpty()){ done = Standard_True; return; } empt = Standard_True; SLin.Clear(); Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1; Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2; Standard_Real U1,U2,V1,V2; UminLig1 = Surf1->FirstUParameter(); VminLig1 = Surf1->FirstVParameter(); UmaxLig1 = Surf1->LastUParameter(); VmaxLig1 = Surf1->LastVParameter(); UminLig2 = Surf2->FirstUParameter(); VminLig2 = Surf2->FirstVParameter(); UmaxLig2 = Surf2->LastUParameter(); VmaxLig2 = Surf2->LastVParameter(); Standard_Real Periods [4]; Periods[0] = (Surf1->IsUPeriodic())? Surf1->UPeriod() : 0.; Periods[1] = (Surf1->IsVPeriodic())? Surf1->VPeriod() : 0.; Periods[2] = (Surf2->IsUPeriodic())? Surf2->UPeriod() : 0.; Periods[3] = (Surf2->IsVPeriodic())? Surf2->VPeriod() : 0.; IntSurf_ListIteratorOfListOfPntOn2S IterLOP1(LOfPnts); if (Surf1->IsUClosed() || Surf1->IsVClosed() || Surf2->IsUClosed() || Surf2->IsVClosed()) { Standard_Real TolPar = Precision::PConfusion(); IntSurf_ListOfPntOn2S AdditionalPnts; Standard_Real NewU1, NewV1, NewU2, NewV2; for(; IterLOP1.More(); IterLOP1.Next()) { IntSurf_PntOn2S Pnt = IterLOP1.Value(); Pnt.Parameters(U1, V1, U2, V2); IntSurf_PntOn2S NewPnt; if (Surf1->IsUClosed()) { if (Abs(U1 - Surf1->FirstUParameter()) <= TolPar) { NewU1 = Surf1->LastUParameter(); NewPnt.SetValue( NewU1, V1, U2, V2 ); AdditionalPnts.Append(NewPnt); } else if (Abs(U1 - Surf1->LastUParameter()) <= TolPar) { NewU1 = Surf1->FirstUParameter(); NewPnt.SetValue( NewU1, V1, U2, V2 ); AdditionalPnts.Append(NewPnt); } } if (Surf1->IsVClosed()) { if (Abs(V1 - Surf1->FirstVParameter()) <= TolPar) { NewV1 = Surf1->LastVParameter(); NewPnt.SetValue( U1, NewV1, U2, V2 ); AdditionalPnts.Append(NewPnt); } else if (Abs(V1 - Surf1->LastVParameter()) <= TolPar) { NewV1 = Surf1->FirstVParameter(); NewPnt.SetValue( U1, NewV1, U2, V2 ); AdditionalPnts.Append(NewPnt); } } if (Surf2->IsUClosed()) { if (Abs(U2 - Surf2->FirstUParameter()) <= TolPar) { NewU2 = Surf2->LastUParameter(); NewPnt.SetValue( U1, V1, NewU2, V2); AdditionalPnts.Append(NewPnt); } else if (Abs(U2 - Surf2->LastUParameter()) <= TolPar) { NewU2 = Surf2->FirstUParameter(); NewPnt.SetValue( U1, V1, NewU2, V2); AdditionalPnts.Append(NewPnt); } } if (Surf2->IsVClosed()) { if (Abs(V2 - Surf2->FirstVParameter()) <= TolPar) { NewV2 = Surf2->LastVParameter(); NewPnt.SetValue( U1, V1, U2, NewV2 ); AdditionalPnts.Append(NewPnt); } else if (Abs(V2 - Surf2->LastVParameter()) <= TolPar) { NewV2 = Surf2->FirstVParameter(); NewPnt.SetValue( U1, V1, U2, NewV2 ); AdditionalPnts.Append(NewPnt); } } } //Cut repeated points for (IterLOP1.Initialize(LOfPnts); IterLOP1.More(); IterLOP1.Next()) { IntSurf_PntOn2S aPnt = IterLOP1.Value(); aPnt.Parameters(U1, V1, U2, V2); IntSurf_ListIteratorOfListOfPntOn2S iter2(AdditionalPnts); while (iter2.More()) { IntSurf_PntOn2S aNewPnt = iter2.Value(); aNewPnt.Parameters(NewU1, NewV1, NewU2, NewV2); if (Abs(U1 - NewU1) <= TolPar && Abs(V1 - NewV1) <= TolPar && Abs(U2 - NewU2) <= TolPar && Abs(V2 - NewV2) <= TolPar) AdditionalPnts.Remove(iter2); else iter2.Next(); } } LOfPnts.Append(AdditionalPnts); } for(IterLOP1.Initialize(LOfPnts); IterLOP1.More(); IterLOP1.Next()){ IntSurf_PntOn2S Pnt = IterLOP1.Value(); Pnt.Parameters(U1, V1, U2, V2); if(U1>UmaxLig1) UmaxLig1=U1; if(V1>VmaxLig1) VmaxLig1=V1; if(U2>UmaxLig2) UmaxLig2=U2; if(V2>VmaxLig2) VmaxLig2=V2; if(U1= SeuildPointLigne); l++) { const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if (IsPointOnLine(StartPOn2S, testwline, Deflection)) { dminiPointLigne = 0.0; } }// for( l ... if(dminiPointLigne > SeuildPointLigne) { PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2,UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2); if(PW.IsDone()) { if(PW.NbPoints()>2) { //Try to extend the intersection line to boundary, if it is possible. PW.PutToBoundary(Surf1, Surf2); RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); Point3dFin = PointFin.Value(); for( ver = 1 ; ver<= NbLigCalculee ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); // Check end point if it is on existing line. // Start point is checked before. if (IsPointOnLine(PointFin, verwline, Deflection)) { RejetLigne = Standard_True; break; } const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if( (Point3dDebut.Distance(verPointDebut.Value()) <= TolTangency) && (Point3dFin.Distance(verPointFin.Value()) <= TolTangency)) { RejetLigne = Standard_True; break; } } if(RejetLigne) { DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne); } if(!RejetLigne) { IntSurf_TypeTrans trans1,trans2; Standard_Real locu,locv; gp_Vec norm1,norm2,d1u,d1v; gp_Pnt ptbid; Standard_Integer indextg; gp_Vec tgline(PW.TangentAtLine(indextg)); PW.Line()->Value(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf2->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if( tgline.DotCross(norm2,norm1) >= 0. ) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); if (RestrictLine){ IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); } if(wline->NbVertex() == 0) { IntPatch_Point vtx; IntSurf_PntOn2S POn2S = PW.Line()->Value(1); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); POn2S = PW.Line()->Value(wline->NbPnts()); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2, TolTang, Max(PW.MaxStep(0), PW.MaxStep(1)), Max(PW.MaxStep(2), PW.MaxStep(3)), wline); AddWLine(SLin, wline, Deflection); empt = Standard_False; }// !RejetLigne }// PW points > 2 }// done is True }// dminiPointLigne > SeuildPointLigne }// HasStartPoint }// for( IterLOP ... done = Standard_True; return; } //======================================================================= //function : Perform //purpose : //======================================================================= void IntPatch_PrmPrmIntersection::Perform(const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& Surf2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real U1Depart, const Standard_Real V1Depart, const Standard_Real U2Depart, const Standard_Real V2Depart, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment) { // Standard_Integer NbU1 = D1->NbSamplesU(); // Standard_Integer NbV1 = D1->NbSamplesV(); // Standard_Integer NbU2 = D2->NbSamplesU(); // Standard_Integer NbV2 = D2->NbSamplesV(); //-- Traitement des Lignes de sections empt = Standard_True; done = Standard_True; SLin.Clear(); //------------------------------------------------------------ Standard_Real pu1,pu2,pv1,pv2; TColStd_Array1OfReal StartParams(1,4); // Standard_Integer MaxOscill = NbU1; // if(MaxOscill < NbU2) MaxOscill=NbU2; // if(MaxOscill < NbV1) MaxOscill=NbV1; // if(MaxOscill < NbV2) MaxOscill=NbV2; // Standard_Real nIncrement=Increment; // if(MaxOscill>10) { // #ifdef OCCT_DEBUG // cout<<"\n IntPatch_PrmPrmIntersection.gxx : Increment:"< "<Value(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf2->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if (tgline.DotCross(norm2,norm1)>0.) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); //--------------- if(wline->NbVertex() == 0) { IntPatch_Point vtx; IntSurf_PntOn2S POn2S = PW.Line()->Value(1); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); POn2S = PW.Line()->Value(wline->NbPnts()); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } //--------------- SLin.Append(wline); empt = Standard_False; } } } //================================================================================== // function : AdjustOnPeriodic // purpose : //================================================================================== void AdjustOnPeriodic(const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_HSurface)& Surf2, IntPatch_SequenceOfLine& aSLin) { Standard_Boolean bIsPeriodic[4], bModified, bIsNull, bIsPeriod; Standard_Integer i, j, k, aNbLines, aNbPx, aIndx, aIndq; Standard_Real aPeriod[4], dPeriod[4], ux[4], uq[4], aEps, du; // aEps=Precision::Confusion(); // for (k=0; k<4; ++k) { aPeriod[k]=0.; } // bIsPeriodic[0]=Surf1->IsUPeriodic(); bIsPeriodic[1]=Surf1->IsVPeriodic(); bIsPeriodic[2]=Surf2->IsUPeriodic(); bIsPeriodic[3]=Surf2->IsVPeriodic(); // if (bIsPeriodic[0]){ aPeriod[0]=Surf1->UPeriod(); } if (bIsPeriodic[1]){ aPeriod[1]=Surf1->VPeriod(); } if (bIsPeriodic[2]){ aPeriod[2]=Surf2->UPeriod(); } if (bIsPeriodic[3]){ aPeriod[3]=Surf2->VPeriod(); } // for (k=0; k<4; ++k) { dPeriod[k]=0.25*aPeriod[k]; } // aNbLines=aSLin.Length(); for (i=1; i<=aNbLines; ++i) { Handle(IntPatch_WLine) aIL=Handle(IntPatch_WLine)::DownCast(aSLin.Value(i)); Handle(IntSurf_LineOn2S) aL=aIL->Curve(); aNbPx=aL->NbPoints(); if (aNbPx<10) { continue; } // for (j=0; j<2; ++j) { bModified=Standard_False; aIndx=1; aIndq=2; if (j) { aIndx=aNbPx; aIndq=aNbPx-1; } // const IntSurf_PntOn2S& aPSx=aL->Value(aIndx); const IntSurf_PntOn2S& aPSq=aL->Value(aIndq); // aPSx.Parameters(ux[0], ux[1], ux[2], ux[3]); aPSq.Parameters(uq[0], uq[1], uq[2], uq[3]); // for (k=0; k<4; ++k) { bIsNull=Standard_False; bIsPeriod=Standard_False; // if (!bIsPeriodic[k]) { continue; } // if (fabs(ux[k]) dPeriod[k]) { if(bIsNull){ ux[k]=aPeriod[k]; } if(bIsPeriod) { ux[k]=0.; } } } }//for (k=0; k<4; ++k) if (bModified) { IntSurf_PntOn2S aPntOn2S; // aPntOn2S=aPSx; aPntOn2S.SetValue(ux[0], ux[1], ux[2], ux[3]); aL->Value(aIndx, aPntOn2S); } }//for (j=0; j<1; ++j) { }//for (i=1; i<=aNbLines; ++i) } //================================================================================== // function : MakeNewPoint // purpose : //================================================================================== IntSurf_PntOn2S MakeNewPoint(const IntSurf_PntOn2S& replacePnt, const IntSurf_PntOn2S& oldPnt, const Standard_Real* Periods) { IntSurf_PntOn2S NewPoint; NewPoint.SetValue(replacePnt.Value()); Standard_Real OldParams[4], NewParams[4]; oldPnt.Parameters(OldParams[0], OldParams[1], OldParams[2], OldParams[3]); replacePnt.Parameters(NewParams[0], NewParams[1], NewParams[2], NewParams[3]); Standard_Integer i; for (i = 0; i < 4; i++) if (Periods[i] != 0.) { if (Abs(NewParams[i] - OldParams[i]) >= 0.5*Periods[i]) { if (NewParams[i] < OldParams[i]) NewParams[i] += Periods[i]; else NewParams[i] -= Periods[i]; } } NewPoint.SetValue(NewParams[0], NewParams[1], NewParams[2], NewParams[3]); return NewPoint; } //================================================================================== // function : Perform // purpose : base SS Int. function //================================================================================== void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Surf1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& Surf2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, const Standard_Boolean ClearFlag) { Standard_Integer Limit = 2500; Standard_Integer NbU1 = 10, NbV1 = 10, NbU2 = 10, NbV2 = 10; // D1->SamplePnts(Deflection, NbU1, NbV1); D2->SamplePnts(Deflection, NbU2, NbV2); // NbU1 = D1->NbSamplesU(); NbV1 = D1->NbSamplesV(); NbU2 = D2->NbSamplesU(); NbV2 = D2->NbSamplesV(); TColStd_Array1OfReal anUpars1(1, NbU1), aVpars1(1, NbV1); TColStd_Array1OfReal anUpars2(1, NbU2), aVpars2(1, NbV2); // D1->UParameters(anUpars1); D1->VParameters(aVpars1); D2->UParameters(anUpars2); D2->VParameters(aVpars2); Standard_Real Periods [4]; Periods[0] = (Surf1->IsUPeriodic())? Surf1->UPeriod() : 0.; Periods[1] = (Surf1->IsVPeriodic())? Surf1->VPeriod() : 0.; Periods[2] = (Surf2->IsUPeriodic())? Surf2->UPeriod() : 0.; Periods[3] = (Surf2->IsVPeriodic())? Surf2->VPeriod() : 0.; //--------------------------------------------- if((NbU1*NbV1<=Limit && NbV2*NbU2<=Limit)) { empt = Standard_True; if (ClearFlag) { SLin.Clear(); } // IntPolyh_Intersection* pInterference = NULL; if ( D1->IsUniformSampling() || D2->IsUniformSampling() ) { pInterference = new IntPolyh_Intersection(Surf1,NbU1,NbV1,Surf2,NbU2,NbV2); } else { pInterference = new IntPolyh_Intersection(Surf1, anUpars1, aVpars1, Surf2, anUpars2, aVpars2 ); } if ( !pInterference ) { done = Standard_False; return; } // IntPolyh_Intersection& Interference = *pInterference; // done = Interference.IsDone(); if( !done ) { if (pInterference) { delete pInterference; pInterference = NULL; } return; } Standard_Integer nbLigSec = Interference.NbSectionLines(); Standard_Integer nbTanZon = Interference.NbTangentZones(); Standard_Real SeuildPointLigne = 15.0 * Increment * Increment; Standard_Integer NbLigCalculee = 0, ver; Standard_Real pu1,pu2,pv1,pv2, incidence, dminiPointLigne; Standard_Boolean HasStartPoint = Standard_False, RejectLine = Standard_False; IntSurf_PntOn2S StartPOn2S; gp_Pnt Point3dDebut,Point3dFin; TColStd_Array1OfReal StartParams(1,4); IntWalk_PWalking PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,Increment); if(nbLigSec>=1) { Standard_Integer *TabL = new Standard_Integer [nbLigSec+1]; for(Standard_Integer ls=1; ls<=nbLigSec; ++ls) { TabL[ls]=ls; } //----------------------------------------1.1 { Standard_Boolean triok; Standard_Integer nb_A, nb_B, tyu; do { triok=Standard_True; for(Standard_Integer b = 2; b <= nbLigSec; ++b ) { nb_B = Interference.NbPointsInLine(TabL[b]); nb_A = Interference.NbPointsInLine(TabL[b-1]); if( nb_B > nb_A ) { tyu=TabL[b]; TabL[b]=TabL[b-1]; TabL[b-1]=tyu; triok=Standard_False; } } } while(triok==Standard_False); } //---------------------------------------- // 1.2 For the line "ls" get 2D-bounds U,V for surfaces 1,2 // for(Standard_Integer ls = 1; ls <= nbLigSec; ++ls) { Standard_Integer nbp = Interference.NbPointsInLine(TabL[ls]); if (!nbp) { continue; } // Standard_Integer *TabPtDep = new Standard_Integer [nbp+1]; for(Standard_Integer ilig = 1; ilig <= nbp; ++ilig ) { TabPtDep[ilig]=0; } // Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1; Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2; Standard_Real _x,_y,_z; // Interference.GetLinePoint(TabL[ls], 1, _x, _y, _z, UminLig1, VminLig1, UminLig2, VminLig2, incidence); UmaxLig1=UminLig1; VmaxLig1=VminLig1; UmaxLig2=UminLig2; VmaxLig2=VminLig2; // for(Standard_Integer ilig = 2; ilig <= nbp; ilig++ ) { Standard_Real U1, U2, V1, V2; Interference.GetLinePoint(TabL[ls],ilig,_x,_y,_z,U1,V1,U2,V2,incidence); // if(U1>UmaxLig1) UmaxLig1=U1; if(V1>VmaxLig1) VmaxLig1=V1; if(U2>UmaxLig2) UmaxLig2=U2; if(V2>VmaxLig2) VmaxLig2=V2; // if(U13)? (nbp/2) : 1; Standard_Integer NombreDePointsDeDepartDuCheminement = 0; Standard_Boolean lignetrouvee=Standard_False; const Standard_Integer NbDePointsDeDepartDuChmLimit = 5; // do { NombreDePointsDeDepartDuCheminement++; switch (NombreDePointsDeDepartDuCheminement) { case 1: nbps2 = (nbp > 1) ? nbp/2 : 1; if(nbp<3) NombreDePointsDeDepartDuCheminement = NbDePointsDeDepartDuChmLimit; break; case 2: nbps2 = 1; break; case 3: nbps2 = nbp-1; break; case 4: nbps2 = 3 * nbp / 4; break; case 5: nbps2 = nbp / 4; break; default: nbps2 = NombreDePointsDeDepartDuCheminement-3; NombreDePointsDeDepartDuCheminement++; } // if(TabPtDep[nbps2] == 0) { Standard_Real U1, U2, V1, V2; TabPtDep[nbps2] = 1; Interference.GetLinePoint(TabL[ls],nbps2,_x,_y,_z,U1,V1,U2,V2,incidence); StartParams(1) = U1; StartParams(2) = V1; StartParams(3) = U2; StartParams(4) = V2; HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S); dminiPointLigne = SeuildPointLigne + SeuildPointLigne; if(HasStartPoint) { StartPOn2S.Parameters(pu1,pv1,pu2,pv2); NbLigCalculee = SLin.Length(); Standard_Integer l; for( l = 1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if (IsPointOnLine(StartPOn2S, testwline, Deflection)) { dminiPointLigne = 0.0; } }// for( l ... if(dminiPointLigne > SeuildPointLigne) { PW.Perform(StartParams, UminLig1, VminLig1, UminLig2, VminLig2, UmaxLig1, VmaxLig1, UmaxLig2, VmaxLig2); // Standard_Boolean bPWIsDone; Standard_Integer iPWNbPoints, aNbPointsVer; Standard_Real aD11, aD12, aD21, aD22, aDx; // bPWIsDone=PW.IsDone(); if(bPWIsDone) { iPWNbPoints=PW.NbPoints(); // if( iPWNbPoints > 2 ) { //Try to extend the intersection line to boundary, if it is possibly PW.PutToBoundary(Surf1, Surf2); const Standard_Integer aMinNbPoints = 40; if(iPWNbPoints < aMinNbPoints) { PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints); iPWNbPoints = PW.NbPoints(); } RejectLine = Standard_False; Point3dDebut = PW.Value(1).Value(); Point3dFin = PW.Value(iPWNbPoints).Value(); for( ver = 1; (!RejectLine) && (ver<= NbLigCalculee); ++ver) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); // aNbPointsVer=verwline->NbPnts(); if (aNbPointsVer<3) { continue; } // const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); //xf const gp_Pnt& aP21=verPointDebut.Value(); const gp_Pnt& aP22=verPointFin.Value(); // aD11=Point3dDebut.Distance(aP21); aD12=Point3dDebut.Distance(aP22); aD21=Point3dFin.Distance(aP21); aD22=Point3dFin.Distance(aP22); // if((aD11<=TolTangency && aD22<=TolTangency) || (aD12<=TolTangency && aD21<=TolTangency)) { Standard_Integer m, mx; // mx=aNbPointsVer/2; if (aNbPointsVer%2) { ++mx; } // const gp_Pnt& aPx=verwline->Point(mx).Value(); for(m=1; mValue(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf2->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if( tgline.DotCross(norm2,norm1) >= 0. ) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); if(wline->NbVertex() == 0) { IntPatch_Point vtx; IntSurf_PntOn2S POn2S = PW.Line()->Value(1); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); POn2S = PW.Line()->Value(wline->NbPnts()); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } lignetrouvee = Standard_True; SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2, TolTang, Max(PW.MaxStep(0), PW.MaxStep(1)), Max(PW.MaxStep(2), PW.MaxStep(3)), wline); AddWLine(SLin, wline, Deflection); empt = Standard_False; }// !RejetLigne }// PW points > 2 }// done is True }// dminiPointLigne > SeuildPointLigne }// HasStartPoint }// if TabPtDep[nbps2] == 0 } while(nbp>5 && !( (NombreDePointsDeDepartDuCheminement >= NbDePointsDeDepartDuChmLimit && lignetrouvee) || (NombreDePointsDeDepartDuCheminement-3 >= nbp && (!lignetrouvee)))); delete [] TabPtDep; }// for( ls ... delete [] TabL; }// if nbLigSec >= 1 // AdjustOnPeriodic(Surf1, Surf2, SLin); // //-------------------------------------------------------------------- //-- Calcul des parametres approches a partir des Zones De Tangence -- //-------------------------------------------------------------------- Standard_Real UminLig1,VminLig1,UmaxLig1,VmaxLig1; Standard_Real UminLig2,VminLig2,UmaxLig2,VmaxLig2; UminLig1=VminLig1=UminLig2=VminLig2=RealLast(); UmaxLig1=VmaxLig1=UmaxLig2=VmaxLig2=-UminLig1; // NbPointsInTangentZone always == 1 (eap) Standard_Integer z; for( z=1; z <= nbTanZon; z++) { //Standard_Integer NbPointsInTangentZone=Interference.NbPointsInTangentZone(z); //for(Standard_Integer pz=1; pz<=NbPointsInTangentZone; pz++) { Standard_Integer pz=1; Standard_Real _x,_y,_z; Standard_Real U1, U2, V1, V2; Interference.GetTangentZonePoint(z,pz,_x,_y,_z,U1,V1,U2,V2); if(U1>UmaxLig1) UmaxLig1=U1; if(V1>VmaxLig1) VmaxLig1=V1; if(U2>UmaxLig2) UmaxLig2=U2; if(V2>VmaxLig2) VmaxLig2=V2; if(U1= SeuildPointLigne); l++) { const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if (IsPointOnLine(StartPOn2S, testwline, Deflection)) { dminiPointLigne = 0.0; } } //-- Fin d exploration des lignes if(dminiPointLigne > SeuildPointLigne) { //--------------------------------------------------- //-- Le point de depart du nouveau cheminement -- //-- n est present dans aucune ligne deja calculee.-- //--------------------------------------------------- PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2, UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2); if(PW.IsDone()) { if(PW.NbPoints()>2) { const Standard_Integer aMinNbPoints = 40; if(PW.NbPoints() < aMinNbPoints) { PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints); } //----------------------------------------------- //-- Verification a posteriori : //-- On teste si le point de depart et de fin de //-- la ligne de cheminement est present dans une //-- autre ligne . //----------------------------------------------- RejectLine = Standard_False; Point3dDebut = PW.Value(1).Value(); const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); Point3dFin = PointFin.Value(); for(ver=1 ; (!RejectLine) && (ver<= NbLigCalculee) ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); //-- Handle(IntPatch_WLine) verwline=Handle(IntPatch_WLine)::DownCast(SLin.Value(ver)); // Check end point if it is on existing line. // Start point is checked before. if (IsPointOnLine(PointFin, verwline, Deflection)) { RejectLine = Standard_True; break; } const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if(Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) { RejectLine = Standard_True; } else { if(Point3dFin.Distance(verPointFin.Value()) < TolTangency) { RejectLine = Standard_True; } } } if(!RejectLine) { IntSurf_TypeTrans trans1,trans2; Standard_Real locu,locv; gp_Vec norm1,norm2,d1u,d1v; gp_Pnt ptbid; Standard_Integer indextg; gp_Vec tgline(PW.TangentAtLine(indextg)); PW.Line()->Value(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf2->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if (tgline.DotCross(norm2,norm1)>0.) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); //--------------- if(wline->NbVertex() == 0) { IntPatch_Point vtx; IntSurf_PntOn2S POn2S = PW.Line()->Value(1); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); POn2S = PW.Line()->Value(wline->NbPnts()); POn2S.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } //--------------- AddWLine(SLin, wline, Deflection); empt = Standard_False; } else { //-- cout<<" ----- REJET DE LIGNE (POINT DE DEPART) ----- "<10) //nIncrement/=0.5*MaxOscill; IntWalk_PWalking PW(Surf1,Surf2,TolTangency,Epsilon,Deflection,nIncrement); Standard_Real SeuildPointLigne = 15.0 * Increment * Increment; //-- 10 est insuffisant Standard_Real dminiPointLigne; Standard_Boolean HasStartPoint,RejetLigne; IntSurf_PntOn2S StartPOn2S; Standard_Integer ver; gp_Pnt Point3dDebut,Point3dFin; //------------------------------------------------------------ //-- Calcul des parametres approches a partir des Zones De Tangence -- //-------------------------------------------------------------------- Standard_Integer nbTanZon = LOn2S->NbPoints(); for(Standard_Integer z=1; z <= nbTanZon; z++) { const IntSurf_PntOn2S& POn2S = LOn2S->Value(z); POn2S.Parameters(U1,V1,U2,V2); StartParams(1) = U1; StartParams(2) = V1; StartParams(3) = U2; StartParams(4) = V2; //----------------------------------------------------------------------- //-- Calcul du premier point de cheminement a partir du point approche -- //----------------------------------------------------------------------- HasStartPoint = PW.PerformFirstPoint(StartParams,StartPOn2S); if(HasStartPoint) { //------------------------------------------------- //-- Un point a ete trouve -- //-- On verifie qu il n appartient pas -- //-- a une ligne de cheminement deja calculee. -- //------------------------------------------------- StartPOn2S.Parameters(pu1,pv1,pu2,pv2); NbLigCalculee = SLin.Length(); dminiPointLigne = SeuildPointLigne + SeuildPointLigne; for(Standard_Integer l=1; (l <= NbLigCalculee) && (dminiPointLigne >= SeuildPointLigne); l++) { const Handle(IntPatch_WLine)& testwline = *((Handle(IntPatch_WLine)*)&SLin.Value(l)); if (IsPointOnLine(StartPOn2S, testwline, Deflection)) { dminiPointLigne = 0.0; } } //-- Fin d exploration des lignes if(dminiPointLigne > SeuildPointLigne) { //--------------------------------------------------- //-- Le point de depart du nouveau cheminement -- //-- n est present dans aucune ligne deja calculee.-- //--------------------------------------------------- PW.Perform(StartParams); if(PW.IsDone()) { if(PW.NbPoints()>2) { //----------------------------------------------- //-- Verification a posteriori : //-- On teste si le point de depart et de fin de //-- la ligne de cheminement est present dans une //-- autre ligne . //----------------------------------------------- RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); Point3dFin = PointFin.Value(); for(ver=1 ; ver<= NbLigCalculee ; ver++) { const Handle(IntPatch_WLine)& verwline = *((Handle(IntPatch_WLine)*)&SLin.Value(ver)); //-- Handle(IntPatch_WLine) verwline=Handle(IntPatch_WLine)::DownCast(SLin.Value(ver)); // Check end point if it is on existing line. // Start point is checked before. if (IsPointOnLine(PointFin, verwline, Deflection)) { RejetLigne = Standard_True; break; } const IntSurf_PntOn2S& verPointDebut = verwline->Point(1); const IntSurf_PntOn2S& verPointFin = verwline->Point(verwline->NbPnts()); if( (Point3dDebut.Distance(verPointDebut.Value()) < TolTangency) || (Point3dFin.Distance(verPointFin.Value()) < TolTangency)) { RejetLigne = Standard_True; break; } } if(RejetLigne) { DublicateOfLinesProcessing(PW, ver, SLin, RejetLigne); } if(!RejetLigne) { IntSurf_TypeTrans trans1,trans2; Standard_Real locu,locv; gp_Vec norm1,norm2,d1u,d1v; gp_Pnt ptbid; Standard_Integer indextg; gp_Vec tgline(PW.TangentAtLine(indextg)); PW.Line()->Value(indextg).ParametersOnS1(locu,locv); Surf1->D1(locu,locv,ptbid,d1u,d1v); norm1 = d1u.Crossed(d1v); PW.Line()->Value(indextg).ParametersOnS2(locu,locv); Surf2->D1(locu,locv,ptbid,d1u,d1v); norm2 = d1u.Crossed(d1v); if (tgline.DotCross(norm2,norm1)>0.) { trans1 = IntSurf_Out; trans2 = IntSurf_In; } else { trans1 = IntSurf_In; trans2 = IntSurf_Out; } Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); //--------------- if(wline->NbVertex() == 0) { IntPatch_Point vtx; const IntSurf_PntOn2S& POn2Sf = PW.Line()->Value(1); POn2Sf.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dDebut,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(1); wline->AddVertex(vtx); const IntSurf_PntOn2S& POn2Sl = PW.Line()->Value(wline->NbPnts()); POn2Sl.Parameters(pu1,pv1,pu2,pv2); vtx.SetValue(Point3dFin,TolTang,Standard_False); vtx.SetParameters(pu1,pv1,pu2,pv2); vtx.SetParameter(wline->NbPnts()); wline->AddVertex(vtx); } //--------------- AddWLine(SLin, wline, Deflection); empt = Standard_False; } else { //-- cout<<" ----- REJET DE LIGNE (POINT DE DEPART) ----- "<FirstUParameter(); U1 = S1->LastUParameter(); V0 = S1->FirstVParameter(); V1 = S1->LastVParameter(); // resu0=U0; resv0=V0; // dmaxOn1 = 0.0; dmaxOn2 = 0.0; //----- du1 = (U1-U0)/(SU1-1); dv1 = (V1-V0)/(SV1-1); for(U=U0,i=0; iValue(U,V); Box1.Add(aIPD.xP1(i, j)); if(i>0 && j>0) { aIPD.xP1(i, j) .Coord(x0,y0,z0); aIPD.xP1(i-1, j-1).Coord(x1,y1,z1); // d=Abs(x1-x0)+Abs(y1-y0)+Abs(z1-z0); if(d>dmaxOn1) { dmaxOn1 = d; } } } } Box1.Enlarge(1.e-8); // U0 = S2->FirstUParameter(); U1 = S2->LastUParameter(); V0 = S2->FirstVParameter(); V1 = S2->LastVParameter(); // du2 = (U1-U0)/(SU2-1); dv2 = (V1-V0)/(SV2-1); for(U=U0,i=0; iValue(U,V); Box2.Add(aIPD.xP2(i, j)); if(i>0 && j>0) { aIPD.xP2(i, j) .Coord(x0,y0,z0); aIPD.xP2(i-1, j-1).Coord(x1,y1,z1); d = Abs(x1-x0)+Abs(y1-y0)+Abs(z1-z0); if(d>dmaxOn2) { dmaxOn2 = d; } } } } Box2.Enlarge(1.e-8); //-------- // if(Box1.IsOut(Box2)) { return; } // Standard_Integer aNbPG; Standard_Real x10,y10,z10,x11,y11,z11; Standard_Real x20,y20,z20,x21,y21,z21; Standard_Real dx, dy, dz, dmax; Standard_Real dx2, dy2, dz2; // Box1.Get(x10,y10,z10,x11,y11,z11); Box2.Get(x20,y20,z20,x21,y21,z21); // x0 = (x10>x20)? x10 : x20; y0 = (y10>y20)? y10 : y20; z0 = (z10>z20)? z10 : z20; // x1 = (x11 dmaxOn1) { dmaxOn1 = dmaxOn2; } // dmaxOn1+=dmaxOn1; x0-=dmaxOn1; y0-=dmaxOn1; z0-=dmaxOn1; x1+=dmaxOn1; y1+=dmaxOn1; z1+=dmaxOn1; // x10-=dmaxOn1; y10-=dmaxOn1; z10-=dmaxOn1; x11+=dmaxOn1; y11+=dmaxOn1; z11+=dmaxOn1; x20-=dmaxOn1; y20-=dmaxOn1; z20-=dmaxOn1; x21+=dmaxOn1; y21+=dmaxOn1; z21+=dmaxOn1; aNbPG=NbPointsGrille(); dx = (x1-x0)/aNbPG; dy = (y1-y0)/aNbPG; dz = (z1-z0)/aNbPG; // dmax = dx; if(dy>dmax) { dmax = dy; } if(dz>dmax){ dmax = dz; } // if(dx=LIM) { for(si=-1; si<= 1; si++) { for(sj=-1; sj<= 1; sj++) { for(sk=-1; sk<= 1; sk++) { if(si || sj || sk) { long unsigned lu=GrilleInteger(i+si,j+sj,k+sk); M1.Raz(lu); } } } } } } // gp_Pnt P(dx*i + x0, dy*j + y0, dz*k+z0); // Standard_Integer nu1=-1,nu2=-1; Standard_Integer nv1=0, nv2=0; int nbsur1 = 0; for(nu=0;nu1<0 && nu=0) { int nbsur2 = 0; for(nu=0;nu2<0 && nu=0 && nu2>=0) { IntSurf_PntOn2S POn2S; POn2S.SetValue(P, S1->FirstUParameter()+nu1*du1, S1->FirstVParameter()+nv1*dv1, S2->FirstUParameter()+nu2*du2, S2->FirstVParameter()+nv2*dv2); LineOn2S->Add(POn2S); Compt++; } else { //-- aucun point du triangle n a ete trouve assez proche //-- on recherche les 3 points les plus proches de P //-- dans chacun des tableaux Standard_Real Dist3[3],u3[3] = { 0.0, 0.0, 0.0 },v3[3] = { 0.0, 0.0, 0.0 }; Dist3[0]=Dist3[1]=Dist3[2]=RealLast(); for(U=resu0,i=0; iAdd(POn2S); Compt++; } } } while(ok); } //================================================================================== // function : IsPointOnLine // purpose : //================================================================================== Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S &thePOn2S, const Handle(IntPatch_WLine) &theWLine, const Standard_Real Deflection) { Standard_Boolean isOnLine = Standard_False; Standard_Real Deflection2 = Deflection*Deflection; Standard_Real pu1, pu2, pv1, pv2; thePOn2S.Parameters(pu1, pv1, pu2, pv2); if ((theWLine->IsOutSurf1Box(gp_Pnt2d(pu1, pv1)) == Standard_False) && (theWLine->IsOutSurf2Box(gp_Pnt2d(pu2, pv2)) == Standard_False) && (theWLine->IsOutBox(thePOn2S.Value()) == Standard_False)) { const Standard_Integer NbPntOn2SOnLine = theWLine->NbPnts(); Standard_Integer ll; for (ll=1; ll < NbPntOn2SOnLine && !isOnLine; ll++) { const gp_Pnt &Pa = theWLine->Point(ll).Value(); const gp_Pnt &Pb = theWLine->Point(ll+1).Value(); const gp_Pnt &PStart = thePOn2S.Value(); const gp_Vec AM(Pa, PStart); const gp_Vec MB(PStart,Pb); const Standard_Real AMMB = AM.Dot(MB); if(AMMB > 0.0) { gp_Dir ABN(Pb.X() - Pa.X(), Pb.Y() - Pa.Y(), Pb.Z() - Pa.Z()); Standard_Real lan = ABN.X()*AM.X() + ABN.Y()*AM.Y() + ABN.Z()*AM.Z(); gp_Vec AH(lan*ABN.X(), lan*ABN.Y(), lan*ABN.Z()); gp_Vec HM(AM.X() - AH.X(), AM.Y() - AH.Y(), AM.Z() - AH.Z()); Standard_Real d = 0.0; if(HM.X() < Deflection) { d += HM.X()*HM.X(); if(HM.Y() < Deflection) { d += HM.Y()*HM.Y(); if(HM.Z() < Deflection) { d += HM.Z()*HM.Z(); } else { d = Deflection2; } } else { d = Deflection2; } } else { d = Deflection2; } if(d < Deflection2) { isOnLine = Standard_True; } } else { Standard_Real dab = Pa.SquareDistance(Pb); Standard_Real dap = Pa.SquareDistance(PStart); if(dap < dab) { isOnLine = Standard_True; } else { Standard_Real dbp = Pb.SquareDistance(PStart); if(dbp < dab) { isOnLine = Standard_True; } } } } } return isOnLine; } //================================================================================== // function : AddWLine // purpose : //================================================================================== void AddWLine(IntPatch_SequenceOfLine &theLines, const Handle(IntPatch_WLine) &theWLine, const Standard_Real Deflection) { Standard_Integer i = 1; Standard_Integer aNbLines = theLines.Length(); Standard_Boolean isToRemove; // Check each line of theLines if it is on theWLine. while (i <= aNbLines) { Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(theLines.Value(i)); isToRemove = Standard_False; if (aWLine.IsNull() == Standard_False) { // Check the middle point. Standard_Integer aMidIndex = (aWLine->NbPnts() + 1)/2; if (aMidIndex > 0) { const IntSurf_PntOn2S &aPnt = aWLine->Point(aMidIndex); if (IsPointOnLine(aPnt, theWLine, Deflection)) { // Middle point is on theWLine. Check vertices. isToRemove = Standard_True; Standard_Integer j; const Standard_Integer aNbVtx = aWLine->NbVertex(); for (j = 1; j <= aNbVtx; j++) { const IntPatch_Point &aPoint = aWLine->Vertex(j); if (!IsPointOnLine(aPoint.PntOn2S(), theWLine, Deflection)) { isToRemove = Standard_False; break; } } } } } if (isToRemove) { theLines.Remove(i); aNbLines--; } else { i++; } } // Add theWLine to the sequence of lines. theLines.Append(theWLine); }