// File: Intf_InterferencePolygon2d.gxx // Created: Mon Jun 24 11:52:34 1991 // Author: Didier PIFFAULT // #include #include #include #include #include #include #include #include static Standard_Integer debug=0; // Angular precision (sinus) below that value two right segments // are considered as having a potential zone of tangency. static Standard_Real PRCANG=Precision::Angular(); //======================================================================= //function : Intf_InterferencePolygon2d //purpose : constructor empty //======================================================================= Intf_InterferencePolygon2d::Intf_InterferencePolygon2d() : Intf_Interference(Standard_False) {} //======================================================================= //function : Intf_InterferencePolygon2d //purpose : Constructor of the interference beetween two Polygon. //======================================================================= static Standard_Boolean oClos, tClos; static Standard_Integer iObje1, iObje2, nbso; Intf_InterferencePolygon2d::Intf_InterferencePolygon2d (const Polygon2d1& Obje1, const Polygon2d2& Obje2) : Intf_Interference(Standard_False) { if (!ToolPolygon2d1::Bounding(Obje1).IsOut (ToolPolygon2d2::Bounding(Obje2))) { Tolerance=ToolPolygon2d1::DeflectionOverEstimation(Obje1)+ ToolPolygon2d2::DeflectionOverEstimation(Obje2); if (Tolerance==0.) Tolerance=Epsilon(1000.); nbso=ToolPolygon2d1::NbSegments(Obje1); oClos=ToolPolygon2d1::Closed(Obje1); tClos=ToolPolygon2d2::Closed(Obje2); Interference(Obje1, Obje2); Clean(); } } //======================================================================= //function : Intf_InterferencePolygon2d //purpose : Constructor of the auto interference of a Polygon. //======================================================================= Intf_InterferencePolygon2d::Intf_InterferencePolygon2d (const Polygon2d1& Obje) : Intf_Interference(Standard_True) { Tolerance=ToolPolygon2d1::DeflectionOverEstimation(Obje)*2; if (Tolerance==0.) Tolerance=Epsilon(1000.); oClos=ToolPolygon2d1::Closed(Obje); tClos=oClos; Interference(Obje); Clean(); } //======================================================================= //function : Perform //purpose : //======================================================================= void Intf_InterferencePolygon2d::Perform (const Polygon2d1& Obje1, const Polygon2d2& Obje2) { SelfInterference(Standard_False); if (!ToolPolygon2d1::Bounding(Obje1).IsOut(ToolPolygon2d2::Bounding(Obje2))) { Tolerance=ToolPolygon2d1::DeflectionOverEstimation(Obje1)+ ToolPolygon2d2::DeflectionOverEstimation(Obje2); if (Tolerance==0.) Tolerance=Epsilon(1000.); nbso=ToolPolygon2d1::NbSegments(Obje1); oClos=ToolPolygon2d1::Closed(Obje1); tClos=ToolPolygon2d2::Closed(Obje2); Interference(Obje1, Obje2); Clean(); } } //======================================================================= //function : Perform //purpose : //======================================================================= void Intf_InterferencePolygon2d::Perform (const Polygon2d1& Obje) { SelfInterference(Standard_True); Tolerance=ToolPolygon2d1::DeflectionOverEstimation(Obje)*2; if (Tolerance==0.) Tolerance=Epsilon(1000.); oClos=ToolPolygon2d1::Closed(Obje); tClos=oClos; Interference(Obje); Clean(); } //======================================================================= //function : Pnt2dValue //purpose : Give the section point of range Index in the interference. //======================================================================= gp_Pnt2d Intf_InterferencePolygon2d::Pnt2dValue (const Standard_Integer Index) const { return gp_Pnt2d((mySPoins(Index)).Pnt().X(), (mySPoins(Index)).Pnt().Y()); } //======================================================================= //function : Interference //purpose : //======================================================================= static Standard_Boolean BeginOfNotClosedObje1; static Standard_Boolean BeginOfNotClosedObje2; void Intf_InterferencePolygon2d::Interference (const Polygon2d1& Obje1, const Polygon2d2& Obje2) { Bnd_Box2d bSO; Bnd_Box2d bST; BeginOfNotClosedObje1=!oClos; for (iObje1=1; iObje1<=ToolPolygon2d1::NbSegments(Obje1); iObje1++) { bSO.SetVoid(); bSO.Add(ToolPolygon2d1::BeginOfSeg(Obje1, iObje1)); bSO.Add(ToolPolygon2d1::EndOfSeg(Obje1, iObje1)); bSO.Enlarge(ToolPolygon2d1::DeflectionOverEstimation(Obje1)); if (!ToolPolygon2d2::Bounding(Obje2).IsOut(bSO)) { BeginOfNotClosedObje2=!tClos; for (iObje2=1; iObje2<=ToolPolygon2d2::NbSegments(Obje2); iObje2++) { bST.SetVoid(); bST.Add(ToolPolygon2d2::BeginOfSeg(Obje2, iObje2)); bST.Add(ToolPolygon2d2::EndOfSeg(Obje2, iObje2)); bST.Enlarge(ToolPolygon2d2::DeflectionOverEstimation(Obje2)); if (!bSO.IsOut(bST)) Intersect(ToolPolygon2d1::BeginOfSeg(Obje1, iObje1), ToolPolygon2d1::EndOfSeg(Obje1, iObje1), ToolPolygon2d2::BeginOfSeg(Obje2, iObje2), ToolPolygon2d2::EndOfSeg(Obje2, iObje2)); } BeginOfNotClosedObje2=Standard_False; } BeginOfNotClosedObje1=Standard_False; } } //======================================================================= //function : Interference //purpose : //======================================================================= void Intf_InterferencePolygon2d::Interference (const Polygon2d1& Obje) { Bnd_Box2d bSO; Bnd_Box2d bST; BeginOfNotClosedObje1=!oClos; for (iObje1=1; iObje1<=ToolPolygon2d1::NbSegments(Obje); iObje1++) { bSO.SetVoid(); bSO.Add(ToolPolygon2d1::BeginOfSeg(Obje, iObje1)); bSO.Add(ToolPolygon2d1::EndOfSeg(Obje, iObje1)); bSO.Enlarge(ToolPolygon2d1::DeflectionOverEstimation(Obje)); if (!ToolPolygon2d1::Bounding(Obje).IsOut(bSO)) { BeginOfNotClosedObje2=!tClos; for (iObje2=iObje1+1;iObje2<=ToolPolygon2d1::NbSegments(Obje);iObje2++){ bST.SetVoid(); bST.Add(ToolPolygon2d1::BeginOfSeg(Obje, iObje2)); bST.Add(ToolPolygon2d1::EndOfSeg(Obje, iObje2)); bST.Enlarge(ToolPolygon2d1::DeflectionOverEstimation(Obje)); if (!bSO.IsOut(bST)) Intersect(ToolPolygon2d1::BeginOfSeg(Obje, iObje1), ToolPolygon2d1::EndOfSeg(Obje, iObje1), ToolPolygon2d1::BeginOfSeg(Obje, iObje2), ToolPolygon2d1::EndOfSeg(Obje, iObje2)); } BeginOfNotClosedObje2=Standard_False; } BeginOfNotClosedObje1=Standard_False; } } //======================================================================= //function : Clean //purpose : //======================================================================= void Intf_InterferencePolygon2d::Clean() { // The zones of tangency that concerns only one couple of segments are // conserved if the angle between the segments is less than and // if there is no real point of intersection EDGE/EDGE: Standard_Integer nbIt=myTZones.Length(); Standard_Integer decal=0; Standard_Integer addr1, addr2; Intf_PIType dim1, dim2; Standard_Real par; Standard_Integer tsp, tsps; Standard_Integer lpi, ltz; Standard_Boolean Only1Seg=Standard_False; #define PI1 (myTZones(ltz-decal).GetPoint(lpi)) #define PI2 (myTZones(ltz-decal).GetPoint(tsp)) for (ltz=1; ltz<=nbIt; ltz++) { tsp=tsps=0; Standard_Real pr1mi,pr1ma,pr2mi,pr2ma,delta1,delta2; myTZones(ltz-decal).ParamOnFirst(pr1mi,pr1ma); delta1=pr1ma-pr1mi; myTZones(ltz-decal).ParamOnSecond(pr2mi,pr2ma); delta2=pr2ma-pr2mi; if (delta1<1. && delta2<1.) Only1Seg=Standard_True; if (delta1==0. || delta2==0.) Only1Seg=Standard_True; if (debug==1) { cout<<"\n tz("<0) { tsp=0; Only1Seg=Standard_False; break; } tsp=lpi; } else if (dim1!=Intf_EXTERNAL && dim2!=Intf_EXTERNAL) { tsps=lpi; } } if (tsp>0) { mySPoins.Append(myTZones(ltz-decal).GetPoint(tsp)); myTZones.Remove(ltz-decal); decal++; } else if (Only1Seg && tsps!=0) { mySPoins.Append(myTZones(ltz-decal).GetPoint(tsps)); myTZones.Remove(ltz-decal); decal++; } } // The points of intersection located in the tangency zone are // removed from the list : nbIt=mySPoins.Length(); decal=0; for (lpi=1; lpi<=nbIt; lpi++) { for (ltz=1; ltz<=myTZones.Length(); ltz++) { if (myTZones(ltz).RangeContains(mySPoins(lpi-decal))) { mySPoins.Remove(lpi-decal); decal++; break; } } } } //======================================================================= //function : Intersect //purpose : //======================================================================= void Intf_InterferencePolygon2d::Intersect (const gp_Pnt2d& BegO, const gp_Pnt2d& EndO, const gp_Pnt2d& BegT, const gp_Pnt2d& EndT) { if(SelfIntf) { if(Abs(iObje1-iObje2)<=1) return; //-- Ajout du 15 jan 98 } Standard_Integer nbpi=0; Standard_Real parO[8]; Standard_Real parT[8]; Intf_SeqOfSectionPoint thePi; gp_XY segT =EndT.XY()-BegT.XY(); gp_XY segO =EndO.XY()-BegO.XY(); // If the length of segment is zero, nothing is done Standard_Real lgT =Sqrt(segT*segT); if (lgT<=0.) return; Standard_Real lgO =Sqrt(segO*segO); if (lgO<=0.) return; // Direction of parsing of segments Standard_Real sigPS=(segO*segT)>0.0 ? 1.0 : -1.0; // Precision of calculation Standard_Real floatgap=Epsilon(lgO+lgT); // Angle between two straight lines and radius of interference Standard_Real sinTeta=(segO.CrossMagnitude(segT)/lgO)/lgT; Standard_Real rayIntf=0.; if (sinTeta>0.) rayIntf=Tolerance/sinTeta; // Interference Standard_Real dbOT=((BegO.XY()-BegT.XY())^segT)/lgT; Standard_Real dbObT=BegO.Distance(BegT); Standard_Real dbOeT=BegO.Distance(EndT); if (Abs(dbOT)<=Tolerance) { if (dbObT<=Tolerance) { nbpi++; parO[nbpi]=0.;parT[nbpi]=0.; thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0., Intf_VERTEX,iObje2,0.,sinTeta)); } if (dbOeT<=Tolerance) { nbpi++; parO[nbpi]=0.;parT[nbpi]=1.; thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0., Intf_VERTEX,iObje2+1,0.,sinTeta)); } if (dbObT>Tolerance && dbOeT>Tolerance && dbObT+dbOeT<=(lgT+Tolerance)) { nbpi++; parO[nbpi]=0.;parT[nbpi]=dbObT/lgT; thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0., Intf_EDGE,iObje2,parT[nbpi],sinTeta)); } } // Interference Standard_Real deOT=((EndO.XY()-BegT.XY())^segT)/lgT; Standard_Real deObT=EndO.Distance(BegT); Standard_Real deOeT=EndO.Distance(EndT); if (Abs(deOT)<=Tolerance) { if (deObT<=Tolerance) { nbpi++; parO[nbpi]=1.;parT[nbpi]=0.; thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0., Intf_VERTEX,iObje2,0.,sinTeta)); } if (deOeT<=Tolerance) { nbpi++; parO[nbpi]=1.;parT[nbpi]=1.; thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0., Intf_VERTEX,iObje2+1,0.,sinTeta)); } if (deObT>Tolerance && deOeT>Tolerance && deObT+deOeT<=(lgT+Tolerance)) { nbpi++; parO[nbpi]=1.;parT[nbpi]=deObT/lgT; thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0., Intf_EDGE,iObje2,parT[nbpi],sinTeta)); } } // Interference Standard_Real dbTO=((BegT.XY()-BegO.XY())^segO)/lgO; if (Abs(dbTO)<=Tolerance) { if (dbObT>Tolerance && deObT>Tolerance && dbObT+deObT<=(lgO+Tolerance)) { nbpi++; parO[nbpi]=dbObT/lgO;parT[nbpi]=0.; thePi.Append(Intf_SectionPoint(BegT,Intf_EDGE,iObje1,parO[nbpi], Intf_VERTEX,iObje2,0.,sinTeta)); } } // Interference Standard_Real deTO=((EndT.XY()-BegO.XY())^segO)/lgO; if (Abs(deTO)<=Tolerance) { if (dbOeT>Tolerance && deOeT>Tolerance && dbOeT+deOeT<=(lgO+Tolerance)) { nbpi++; parO[nbpi]=dbOeT/lgO;parT[nbpi]=1.; thePi.Append(Intf_SectionPoint(EndT,Intf_EDGE,iObje1,parO[nbpi], Intf_VERTEX,iObje2+1,0.,sinTeta)); } } Standard_Boolean edgeSP=Standard_False; Standard_Real parOSP=0, parTSP=0; if (Abs(dbOT-deOT)>floatgap && Abs(dbTO-deTO)>floatgap) { parOSP=dbOT/(dbOT-deOT); parTSP=dbTO/(dbTO-deTO); if (dbOT*deOT<=0. && dbTO*deTO<=0.) { edgeSP=Standard_True; } else if (nbpi==0) return; // If there is no interference it is necessary to take the points segment by segment if (nbpi==0 && sinTeta>PRCANG) { nbpi++; parO[nbpi]=parOSP; parT[nbpi]=parTSP; thePi.Append(Intf_SectionPoint(gp_Pnt2d (BegO.X()+ (segO.X()*parOSP), BegO.Y()+ (segO.Y()*parOSP)), Intf_EDGE,iObje1,parOSP, Intf_EDGE,iObje2,parTSP,sinTeta)); } // Otherwise it is required to check if there is no other else if (rayIntf>=Tolerance) { Standard_Real deltaO=rayIntf/lgO; Standard_Real deltaT=rayIntf/lgT; Standard_Real x, y; Standard_Real parOdeb=parOSP-deltaO; Standard_Real parOfin=parOSP+deltaO; Standard_Real parTdeb=parTSP-sigPS*deltaT; Standard_Real parTfin=parTSP+sigPS*deltaT; if (nbpi==0) { parO[1]=parOdeb; parO[2]=parOfin; parT[1]=parTdeb; parT[2]=parTfin; while (nbpi<2) { nbpi++; x=BegO.X()+ (segO.X()*parO[nbpi]); y=BegO.Y()+ (segO.Y()*parO[nbpi]); thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y), Intf_EXTERNAL, iObje1, parO[nbpi], Intf_EXTERNAL, iObje2, parT[nbpi], sinTeta)); } } else { //nbpi>0 if (nbpi==1) { Standard_Boolean ok=Standard_True; if (0.= (Tolerance/4.)) { nbpi++; thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y), Intf_EXTERNAL, iObje1, parO[nbpi], Intf_EXTERNAL, iObje2, parT[nbpi], sinTeta)); } } } else { // plus d une singularite Standard_Real parOmin=parO[1]; Standard_Real parOmax=parO[1]; Standard_Real parTmin=parT[1]; Standard_Real parTmax=parT[1]; for (Standard_Integer i=2; i<=nbpi; i++) { parOmin=Min(parOmin, parO[i]); parOmax=Max(parOmax, parO[i]); parTmin=Min(parTmin, parT[i]); parTmax=Max(parTmax, parT[i]); } Standard_Real delta; if (parOdeb<0.) { delta=-parOdeb; parOdeb=0.; parTdeb=parTdeb+sigPS*(delta*(deltaT/deltaO)); } if (parOfin>1.) { delta=parOfin-1.; parOfin=1.; parTfin=parTfin-sigPS*(delta*(deltaT/deltaO)); } if (sigPS>0.) { if (parTdeb<0.) { delta=-parTdeb; parTdeb=0.; parOdeb=parOdeb+delta*(deltaO/deltaT); } if (parTfin>1.) { delta=parTfin-1.; parTfin=1.; parOfin=parOfin-delta*(deltaO/deltaT); } } else { if (parTdeb>1.) { delta=parTdeb-1.; parTdeb=1.; parOdeb=parOdeb+delta*(deltaO/deltaT); } if (parTfin<0.) { delta=-parTfin; parTfin=0.; parOfin=parOfin-delta*(deltaO/deltaT); } } if ((parOdeb0.) || (sigPS>0. && parTdeb0.) || (sigPS<0. && parTdeb>parTmax && parTmax<1.)) { nbpi++; parO[nbpi]=Max(0., Min(1., parOdeb)); parT[nbpi]=Max(0., Min(1., parTdeb)); x=BegO.X()+ (segO.X()*parO[nbpi]); y=BegO.Y()+ (segO.Y()*parO[nbpi]); thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y), Intf_EXTERNAL, iObje1, parO[nbpi], Intf_EXTERNAL, iObje2, parT[nbpi], sinTeta)); } if ((parOfin>parOmax && parOmax<1.) || (sigPS<0. && parTfin0.) || (sigPS>0. && parTfin>parTmax && parTmax<1.)) { nbpi++; parO[nbpi]=Min(1., Max(0., parOfin)); parT[nbpi]=Min(1., Max(0., parTfin)); x=BegO.X()+ (segO.X()*parO[nbpi]); y=BegO.Y()+ (segO.Y()*parO[nbpi]); thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y), Intf_EXTERNAL, iObje1, parO[nbpi], Intf_EXTERNAL, iObje2, parT[nbpi], sinTeta)); } } } } } //-- lbr : The points too close to each other are suspended Standard_Boolean suppr; do { suppr=Standard_False; for(Standard_Integer i=2; suppr==Standard_False && i<=nbpi; i++) { const gp_Pnt& Pim1 = thePi(i-1).Pnt(); const gp_Pnt& Pi = thePi(i).Pnt(); Standard_Real d=Pi.Distance(Pim1); d*=50.0; if(d0. && parT[1]>0.)) { { Standard_Boolean contains = Standard_False; for (Standard_Integer i = 1; i <= mySPoins.Length(); i++) if (thePi(1).IsEqual(mySPoins(i))) { contains = Standard_True; break; } if (!contains) mySPoins.Append(thePi(1)); } } else if (iObje2-iObje1!=1 && (!oClos || (iObje1!=1 && iObje2!=nbso))) { mySPoins.Append(thePi(1)); } } else if (nbpi>=2) { Intf_TangentZone TheTZ; if (nbpi==2) { TheTZ.PolygonInsert(thePi(1)); TheTZ.PolygonInsert(thePi(2)); } else { Standard_Integer lpj; Standard_Integer lmin=1; Standard_Integer lmax=1; for (lpj=2; lpj<=nbpi; lpj++) { if (parO[lpj]parO[lmax]) lmax=lpj; } TheTZ.PolygonInsert(thePi(lmin)); TheTZ.PolygonInsert(thePi(lmax)); Standard_Integer ltmin=1; Standard_Integer ltmax=1; for (lpj=2; lpj<=nbpi; lpj++) { if (parT[lpj]parT[ltmax]) ltmax=lpj; } if (ltmin!=lmin && ltmin!=lmax) TheTZ.PolygonInsert(thePi(ltmin)); if (ltmax!=lmin && ltmax!=lmax) TheTZ.PolygonInsert(thePi(ltmax)); } if (edgeSP) TheTZ.PolygonInsert(Intf_SectionPoint (gp_Pnt2d (BegO.X()+ (segO.X()*parOSP), BegO.Y()+ (segO.Y()*parOSP)), Intf_EDGE,iObje1,parOSP, Intf_EDGE,iObje2,parTSP,sinTeta)); Standard_Integer nbtz=myTZones.Length(); #if 0 Standard_Integer decaltz=0; for (Standard_Integer ltz=1; ltz<=nbtz; ltz++) { if (TheTZ.HasCommonRange(myTZones(ltz-decaltz))) { TheTZ.Append(myTZones(ltz-decaltz)); myTZones.Remove(ltz-decaltz); decaltz++; } } myTZones.Append(TheTZ); #else TColStd_ListOfInteger LIndex; for (Standard_Integer ltz=1; ltz<=nbtz; ltz++) { if (TheTZ.HasCommonRange(myTZones(ltz))) { LIndex.Append(ltz); } } //------------------------------------------------------------------------ //-- The list is parsed in ascending order by index, zone and tg //-- if(LIndex.IsEmpty()) { myTZones.Append(TheTZ); } else { Standard_Integer indexfirst = LIndex.First(); LIndex.RemoveFirst(); Standard_Integer decal = 0; myTZones(indexfirst).Append(TheTZ); while(!LIndex.IsEmpty()) { Standard_Integer index = LIndex.First(); LIndex.RemoveFirst(); myTZones(indexfirst).Append(myTZones(index-decal)); myTZones.Remove(index-decal); decal++; } } #endif } } // EOF File: Intf_InterferencePolygon2d.gxx