1 // Copyright (C) 2007-2024 CEA, EDF, 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, or (at your option) any later version.
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
23 // File: GEOMAlgo_ClsfQuad.cxx
24 // Created: Fri Feb 13 16:03:19 2015
25 // Author: Sergey KHROMOV
29 #include <GEOMAlgo_ClsfQuad.hxx>
30 #include <GEOMAlgo_SurfaceTools.hxx>
32 #include <Geom_Plane.hxx>
34 IMPLEMENT_STANDARD_RTTIEXT(GEOMAlgo_ClsfQuad, GEOMAlgo_Clsf)
36 //=======================================================================
39 //=======================================================================
40 GEOMAlgo_ClsfQuad::GEOMAlgo_ClsfQuad()
42 myQuadNormal(0., 0., 0.)
45 //=======================================================================
48 //=======================================================================
49 GEOMAlgo_ClsfQuad::~GEOMAlgo_ClsfQuad()
52 //=======================================================================
53 //function : SetCorners
55 //=======================================================================
56 void GEOMAlgo_ClsfQuad::SetCorners(const gp_Pnt &theTopLeftPoint,
57 const gp_Pnt &theTopRightPoint,
58 const gp_Pnt &theBottomLeftPoint,
59 const gp_Pnt &theBottomRightPoint)
62 myPoints[0] = theTopLeftPoint;
63 myPoints[1] = theTopRightPoint;
64 myPoints[2] = theBottomRightPoint;
65 myPoints[3] = theBottomLeftPoint;
66 myPoints[4] = myPoints[0];
67 myPoints[5] = myPoints[1];
69 // Find plane normal defined by corner points, it will be used to define
70 // a plane for each quadrangle side.
71 myQuadNormal.SetCoord (0., 0., 0.);
73 for ( int i = 1; i <= 4; ++i ) {
75 gp_Vec(myPoints[i], myPoints[i+1]) ^ gp_Vec(myPoints[i], myPoints[i-1]);
78 if (myQuadNormal.SquareMagnitude() <= DBL_MIN) {
82 // detect concave quadrangle sides
83 myConcaveQuad = false;
84 myConcaveSide.resize (4, false);
86 for ( int i = 1; i <= 4; ++i ) {
88 gp_Vec(myPoints[i], myPoints[i+1]) ^ gp_Vec(myPoints[i], myPoints[i-1]);
90 if (myQuadNormal * localQN < 0) {
91 myConcaveSide[i-1] = myConcaveSide[i] = myConcaveQuad = true;
95 // loop on quadrangle sides
96 myPlanes.reserve( 4 );
98 for ( int i = 0; i < 4; ++i ) {
99 // point1 -> point2 vector
100 gp_Vec aSideVec( myPoints[ i ], myPoints[ i + 1 ]);
103 gp_Vec aSideNorm = aSideVec ^ myQuadNormal;
104 if (aSideNorm.SquareMagnitude() <= DBL_MIN) {
109 Handle(Geom_Plane) aPlane = new Geom_Plane(myPoints[i], aSideNorm);
111 myPlanes.push_back(GeomAdaptor_Surface());
112 myPlanes.back().Load( aPlane );
116 //=======================================================================
117 //function : GetCorners
119 //=======================================================================
120 void GEOMAlgo_ClsfQuad::GetCorners(gp_Pnt &theTopLeftPoint,
121 gp_Pnt &theTopRightPoint,
122 gp_Pnt &theBottomLeftPoint,
123 gp_Pnt &theBottomRightPoint) const
125 if (myPoints.size() == 6) {
126 theTopLeftPoint = myPoints[0];
127 theTopRightPoint = myPoints[1];
128 theBottomLeftPoint = myPoints[3];
129 theBottomRightPoint = myPoints[2];
133 //=======================================================================
134 //function : CheckData
136 //=======================================================================
137 void GEOMAlgo_ClsfQuad::CheckData()
141 if (myQuadNormal.SquareMagnitude() <= DBL_MIN) {
142 myErrorStatus = 10; // undefined quadrangle normal.
146 //=======================================================================
149 //=======================================================================
150 void GEOMAlgo_ClsfQuad::Perform()
154 // Return IN if aP has TopAbs_IN with all sides.
155 // In the case of concave quadrangle, return IN if
156 // aP is OUT of only one concave side
159 for (size_t i = 0; i < myPlanes.size(); ++i) {
162 GEOMAlgo_SurfaceTools::GetState(myPnt, myPlanes[i], myTolerance, aSt);
164 if (aSt == TopAbs_IN) {
165 nbIn += myConcaveSide[i] ? 0.5 : 1.0;
166 } else if (aSt == TopAbs_ON) {
167 // check that aP is between quadrangle corners
168 Handle(Geom_Plane) aSidePlane =
169 Handle(Geom_Plane)::DownCast(myPlanes[i].Surface());
170 gp_Vec aSideNorm = aSidePlane->Axis().Direction();
171 gp_Vec aSideVec = myQuadNormal ^ aSideNorm;
172 gp_Vec c1p (myPoints[i], myPnt);
173 gp_Vec pc2 (myPnt, myPoints[i+1]);
175 if (aSideVec * c1p >= 0. && aSideVec * pc2 >= 0.) {
179 // consider to be IN (???????????)
180 //nbIn += myConcaveSide[i] ? 0.5 : 1.0;
184 Standard_Real inThreshold = myPlanes.size(); // usually 4.0
187 inThreshold = 2.5; // 1.0 + 1.0 + 0.5
190 if (nbIn >= inThreshold) {
193 myState = TopAbs_OUT;
196 //=======================================================================
199 //=======================================================================
200 Standard_Boolean GEOMAlgo_ClsfQuad::CanBeON(const Handle(Geom_Curve)& aC) const
202 return GEOMAlgo_Clsf::CanBeON(aC);
204 //=======================================================================
207 //=======================================================================
208 Standard_Boolean GEOMAlgo_ClsfQuad::CanBeON(const Handle(Geom_Surface)& aS1) const
210 GeomAdaptor_Surface aGAS1;
214 GeomAbs_SurfaceType aST1 = aGAS1.GetType();
215 Standard_Boolean bRet = (aST1 == GeomAbs_Plane);