// Created on: 1997-05-14 // Created by: Robert COUBLANC // Copyright (c) 1997-1999 Matra Datavision // Copyright (c) 1999-2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. #include #include #include #include #include #include #include #include #include #include static Standard_Boolean S3D_Str_NearSegment (const gp_XY& p0, const gp_XY& p1, const gp_XY& TheP, const Standard_Real aTol, Standard_Real& aDMin) { gp_XY V01(p1); V01 -= p0; gp_XY Vec(TheP); Vec -= p0; Standard_Real u = Vec*V01.Normalized(); if(u<-aTol) return Standard_False; Standard_Real u1 = u-aTol; Standard_Real modmod = V01.SquareModulus(); if(u1*u1> modmod) return Standard_False; gp_XY N01 (-V01.Y(),V01.X()); N01.Normalize(); aDMin = Abs (Vec * N01); return aDMin <= aTol; } //================================================== // Function: Creation // Purpose : //================================================== Select3D_SensitiveTriangle:: Select3D_SensitiveTriangle(const Handle(SelectBasics_EntityOwner)& OwnerId, const gp_Pnt& P0, const gp_Pnt& P1, const gp_Pnt& P2, const Select3D_TypeOfSensitivity aType): Select3D_SensitivePoly(OwnerId,3), mytype (aType) { mypolyg.SetPnt(0, P0); mypolyg.SetPnt(1, P1); mypolyg.SetPnt(2, P2); } //================================================== // Function: Matches // Purpose : //================================================== Standard_Boolean Select3D_SensitiveTriangle:: Matches(const Standard_Real X, const Standard_Real Y, const Standard_Real aTol, Standard_Real& DMin) { Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); if(Bnd_Box2d(mybox2d).IsOut(gp_Pnt2d(X,Y))) return Standard_False; Standard_Integer Res; switch (mytype) { case Select3D_TOS_BOUNDARY: Res = Status(X,Y,aTol,DMin); return Res== 1; break; case Select3D_TOS_INTERIOR: Res = Status(X,Y,aTol,DMin); return (Res==0 || Res == 1); default: break; } return Standard_True; } //================================================== // Function: Matches // Purpose : //================================================== Standard_Boolean Select3D_SensitiveTriangle:: Matches (const Standard_Real XMin, const Standard_Real YMin, const Standard_Real XMax, const Standard_Real YMax, const Standard_Real aTol) { Bnd_Box2d B; B.Update(Min(XMin,XMax)-aTol, Min(YMin,YMax)-aTol, Max(XMin,XMax)+aTol, Max(YMin,YMax)+aTol); for(Standard_Integer anIndex=0;anIndex<=2;++anIndex) { if(B.IsOut(mypolyg.Pnt2d(anIndex))) return Standard_False; } return Standard_True; } //======================================================================= //function : Matches //purpose : //======================================================================= Standard_Boolean Select3D_SensitiveTriangle:: Matches (const TColgp_Array1OfPnt2d& aPoly, const Bnd_Box2d& aBox, const Standard_Real aTol) { Standard_Real Umin,Vmin,Umax,Vmax; aBox.Get(Umin,Vmin,Umax,Vmax); Standard_Real Tolu,Tolv; Tolu = 1e-7; Tolv = 1e-7; CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax); for(Standard_Integer anIndex=0;anIndex<=2;++anIndex) { Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex)); if(RES!=1) return Standard_False; } return Standard_True; } //================================================== // Function: Points3D // Purpose : //================================================== void Select3D_SensitiveTriangle::Points3D(gp_Pnt& P0,gp_Pnt& P1,gp_Pnt& P2) const { P0 = mypolyg.Pnt(0); P1 = mypolyg.Pnt(1); P2 = mypolyg.Pnt(2); } //================================================== // Function: Center3D // Purpose : //================================================== gp_Pnt Select3D_SensitiveTriangle::Center3D() const { gp_XYZ aPnt1, aPnt2, aPnt3; aPnt1 = mypolyg.Pnt(0); aPnt2 = mypolyg.Pnt(1); aPnt3 = mypolyg.Pnt(2); return gp_Pnt((aPnt1+aPnt2+aPnt3)/3.); } //================================================== // Function: Center2D // Purpose : //================================================== gp_XY Select3D_SensitiveTriangle::Center2D() const { gp_XY aPnt1, aPnt2, aPnt3; aPnt1 = mypolyg.Pnt2d(0); aPnt2 = mypolyg.Pnt2d(1); aPnt3 = mypolyg.Pnt2d(2); return (aPnt1+aPnt2+aPnt3)/3.; } //======================================================================= //function : Status //purpose : 0 = inside /1 = Boundary/ 2 = outside //======================================================================= Standard_Integer Select3D_SensitiveTriangle::Status(const Standard_Real X, const Standard_Real Y, const Standard_Real aTol, Standard_Real& DMin) const { return Status(mypolyg.Pnt2d(0), mypolyg.Pnt2d(1), mypolyg.Pnt2d(2), gp_XY(X,Y), aTol, DMin); } //======================================================================= //function : Status //purpose : //======================================================================= Standard_Integer Select3D_SensitiveTriangle::Status(const gp_XY& p0, const gp_XY& p1, const gp_XY& p2, const gp_XY& TheP, const Standard_Real aTol, Standard_Real& DMin) { Bnd_Box2d B; B.Update(p0.X(),p0.Y());B.Update(p1.X(),p1.Y());B.Update(p2.X(),p2.Y()); B.Enlarge(aTol); if(B.IsOut(TheP)) return 2; // the point is classified corresponding to demi-spaces limited // by each side of the triangle (with tolerance) gp_XY V01(p1);V01-=p0; gp_XY V02(p2);V02-=p0; gp_XY V12(p2);V12-=p1; // check these particular cases... // if one of vectors is almost null (2 points are mixed), // leave at once (it is already in the bounding box, which is good...) DMin = aTol; if ( V01.SquareModulus() <= gp::Resolution() ) { Standard_Real LV = V02.SquareModulus(); if ( LV <= gp::Resolution()) return 0; // 3 points are mixed, and TheP is in the bounding box B... if ( S3D_Str_NearSegment (p0, p2, TheP, aTol, DMin) ) return 0; return 2; } if ( V02.SquareModulus() <= gp::Resolution() ) { if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) ) return 0; return 2; } if ( V12.SquareModulus() <= gp::Resolution() ) { if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) ) return 0; return 2; } if ( V01.CrossMagnitude(V02) <= gp::Resolution() ) { if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) ) return 0; return 2; } // oriented normal to p0p1... gp_Dir2d N (-V01.Y(), V01.X()); Standard_Boolean Neg = (N * V02 < 0.); if ( Neg ) N.Reverse(); gp_XY Vec(TheP); Vec -= p0; Standard_Real aD1 = Vec * N.XY(); if ( aD1 < -aTol ) return 2; // oriented normal to p1p2... if(Neg) N.SetCoord(p2.Y()-p1.Y(),p1.X()-p2.X()); else N.SetCoord(p1.Y()-p2.Y(),p2.X()-p1.X()); Vec.SetCoord(TheP.X()-p1.X(),TheP.Y()-p1.Y()); Standard_Real aD2 = Vec * N.XY(); if ( aD2 < -aTol ) return 2; // outside // oriented normal to p2p0... // attention v20 (x0-x2) => N y2-y0 => -N y0-y2 // (y0-y2) x0-x2 x2-x0 if(Neg) N.SetCoord(p0.Y()-p2.Y(),p2.X()-p0.X()); else N.SetCoord(p2.Y()-p0.Y(),p0.X()-p2.X()); Vec.SetCoord(TheP.X()-p2.X(),TheP.Y()-p2.Y()); Standard_Real aD3 = Vec * N.XY(); if ( aD3 < -aTol ) return 2; // outside // compute 2d distance to triangle Standard_Real aD = Min (aD1, Min (aD2, aD3)); DMin = ( aD < 0 ? -aD : 0. ); return 0; } //======================================================================= //function : Dump //purpose : //======================================================================= void Select3D_SensitiveTriangle::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const { // general information.... S<<"\tSensitiveTriangle 3D :\n"; if(HasLocation()) S<<"\t\tExisting Location"<Precision::Confusion()) prof =val1/val2; if (prof==Precision::Infinite()) { prof= ElCLib::Parameter(EyeLine,P1); prof = Min (prof, ElCLib::Parameter(EyeLine,P2)); prof = Min (prof, ElCLib::Parameter(EyeLine,P3)); } return prof; } //================================================== // Function: GetConnected // Purpose : //================================================== Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangle:: GetConnected(const TopLoc_Location &theLocation) { // Create a copy of this Handle(Select3D_SensitiveEntity) aNewEntity = new Select3D_SensitiveTriangle(myOwnerId, mypolyg.Pnt(0), mypolyg.Pnt(1), mypolyg.Pnt(2), mytype); if (HasLocation()) aNewEntity->SetLocation(Location()); aNewEntity->UpdateLocation(theLocation); return aNewEntity; }