1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMAlgo_FinderShapeOnQuad.cxx
23 // Created : Mon Oct 17 17:31:45 2005
24 // Author : Edward AGAPOV (eap)
26 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
27 #include "GEOMAlgo_SurfaceTools.hxx"
31 #include <Geom_Plane.hxx>
34 GEOMAlgo_FinderShapeOnQuad::GEOMAlgo_FinderShapeOnQuad(const gp_Pnt & theTopLeftPoint,
35 const gp_Pnt & theTopRigthPoint,
36 const gp_Pnt & theBottomLeftPoint,
37 const gp_Pnt & theBottomRigthPoint)
40 myPoints[0] = theTopLeftPoint ;
41 myPoints[1] = theTopRigthPoint ;
42 myPoints[2] = theBottomRigthPoint;
43 myPoints[3] = theBottomLeftPoint ;
44 myPoints[4] = myPoints[0];
45 myPoints[5] = myPoints[1];
47 // Find plane normal defined by corner points, it will be used to define a plane
48 // for each quadrangle side.
49 myQuadNormal.SetCoord (0,0,0);
50 for ( int i = 1; i <= 4; ++i )
51 myQuadNormal += gp_Vec( myPoints[i], myPoints[i+1] ) ^ gp_Vec( myPoints[i], myPoints[i-1] );
52 //std::cout<<std::endl<<" X Vec : "<<myQuadNormal.X()<<" "<<myQuadNormal.Y()<<" "<<myQuadNormal.Z()<<" "<<endl;
54 if ( myQuadNormal.SquareMagnitude() <= DBL_MIN ) {
59 // detect concave quadrangle sides
60 myConcaveQuad = false;
61 myConcaveSide.resize (4, false);
62 for ( int i = 1; i <= 4; ++i ) {
63 gp_Vec localQN = gp_Vec( myPoints[i], myPoints[i+1] ) ^ gp_Vec( myPoints[i], myPoints[i-1] );
64 if ( myQuadNormal * localQN < 0 )
65 myConcaveSide[i-1] = myConcaveSide[i] = myConcaveQuad = true;
68 // loop on quadrangle sides
69 myPlanes.reserve( 4 );
70 for ( int i = 0; i < 4; ++i )
72 // point1 -> point2 vector
73 gp_Vec aSideVec( myPoints[ i ], myPoints[ i + 1 ]);
74 //std::cout<<" Y Vec : "<<aSideVec.X()<<" "<<aSideVec.Y()<<" "<<aSideVec.Z()<<" "<<endl;
77 gp_Vec aSideNorm = aSideVec ^ myQuadNormal;
78 if ( aSideNorm.SquareMagnitude() <= DBL_MIN )
80 //std::cout<<" Z Vec : "<<aSideNorm.X()<<" "<<aSideNorm.Y()<<" "<<aSideNorm.Z()<<" "<<endl;
83 Handle(Geom_Plane) aPlane = new Geom_Plane( myPoints[ i ], aSideNorm );
84 myPlanes.push_back( GeomAdaptor_Surface() );
85 myPlanes.back().Load( aPlane );
89 //=======================================================================
90 //function : CheckData
92 //=======================================================================
94 void GEOMAlgo_FinderShapeOnQuad::CheckData()
96 if ( !myPlanes.empty() )
97 mySurface = myPlanes[0].Surface();
98 GEOMAlgo_FinderShapeOn1::CheckData();
101 //=======================================================================
102 //function : GetPointState
104 //=======================================================================
106 TopAbs_State GEOMAlgo_FinderShapeOnQuad::GetPointState(const gp_Pnt& aP)
108 // Return IN if aP has TopAbs_IN with all sides.
109 // In the case of concave quadrangle, return IN if
110 // aP is OUT of only one concave side
112 for ( int i = 0; i < myPlanes.size(); ++i )
115 GEOMAlgo_SurfaceTools::GetState(aP, myPlanes[i], myTolerance, aSt);
116 if ( aSt == TopAbs_IN )
118 nbIn += myConcaveSide[i] ? 0.5 : 1.0;
120 else if ( aSt == TopAbs_ON )
122 // check that aP is between quadrangle corners
123 Handle(Geom_Plane) aSidePlane = Handle(Geom_Plane)::DownCast( myPlanes[i].Surface() );
124 gp_Vec aSideNorm = aSidePlane->Axis().Direction();
125 gp_Vec aSideVec = myQuadNormal ^ aSideNorm;
126 gp_Vec c1p ( myPoints[i], aP );
127 gp_Vec pc2 ( aP, myPoints[i+1] );
128 if ( aSideVec * c1p >= 0. && aSideVec * pc2 >= 0. )
130 // consider to be IN (???????????)
131 //nbIn += myConcaveSide[i] ? 0.5 : 1.0;
134 Standard_Real inThreshold = myPlanes.size(); // usually 4.0
136 inThreshold = 2.5; // 1.0 + 1.0 + 0.5
138 if ( nbIn >= inThreshold )