Salome HOME
Join modifications from branch BR_DEBUG_3_2_0b1
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_FinderShapeOnQuad.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 //  This library is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU Lesser General Public
6 //  License as published by the Free Software Foundation; either
7 //  version 2.1 of the License.
8 //
9 //  This library is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 //  Lesser General Public License for more details.
13 //
14 //  You should have received a copy of the GNU Lesser General Public
15 //  License along with this library; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //
21 //
22 // File      : GEOMAlgo_FinderShapeOnQuad.cxx
23 // Created   : Mon Oct 17 17:31:45 2005
24 // Author    : Edward AGAPOV (eap)
25
26 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
27 #include "GEOMAlgo_SurfaceTools.hxx"
28
29 #include <gp_Pnt.hxx>
30 #include <gp_Vec.hxx>
31 #include <Geom_Plane.hxx>
32
33
34 GEOMAlgo_FinderShapeOnQuad::GEOMAlgo_FinderShapeOnQuad(const gp_Pnt & theTopLeftPoint,
35                                                        const gp_Pnt & theTopRigthPoint,
36                                                        const gp_Pnt & theBottomLeftPoint,
37                                                        const gp_Pnt & theBottomRigthPoint)
38 {
39   myPoints.resize(6);
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];
46
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;
53
54   if ( myQuadNormal.SquareMagnitude() <= DBL_MIN ) {
55     myErrorStatus = 101;
56     return;
57   }
58
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;
66   }
67
68   // loop on quadrangle sides
69   myPlanes.reserve( 4 );
70   for ( int i = 0; i < 4; ++i )
71   {
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;
75
76     // plane normal
77     gp_Vec aSideNorm = aSideVec ^ myQuadNormal;
78     if ( aSideNorm.SquareMagnitude() <= DBL_MIN )
79       continue;
80     //std::cout<<" Z Vec : "<<aSideNorm.X()<<" "<<aSideNorm.Y()<<" "<<aSideNorm.Z()<<" "<<endl;
81
82     // make plane
83     Handle(Geom_Plane) aPlane = new Geom_Plane( myPoints[ i ], aSideNorm );
84     myPlanes.push_back( GeomAdaptor_Surface() );
85     myPlanes.back().Load( aPlane );
86   }
87 }
88
89 //=======================================================================
90 //function : CheckData
91 //purpose  : 
92 //=======================================================================
93
94 void GEOMAlgo_FinderShapeOnQuad::CheckData()
95 {
96   if ( !myPlanes.empty() )
97     mySurface = myPlanes[0].Surface();
98   GEOMAlgo_FinderShapeOn1::CheckData();
99 }
100
101 //=======================================================================
102 //function : GetPointState
103 //purpose  : 
104 //=======================================================================
105
106 TopAbs_State GEOMAlgo_FinderShapeOnQuad::GetPointState(const gp_Pnt& aP) 
107 {
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
111   double nbIn = 0.;
112   for ( int i = 0; i < myPlanes.size(); ++i )
113   {
114     TopAbs_State aSt;
115     GEOMAlgo_SurfaceTools::GetState(aP, myPlanes[i], myTolerance, aSt);
116     if ( aSt == TopAbs_IN )
117     {
118       nbIn += myConcaveSide[i] ? 0.5 : 1.0;
119     }
120     else if ( aSt == TopAbs_ON )
121     {
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. )
129         return TopAbs_ON;
130       // consider to be IN (???????????)
131       //nbIn += myConcaveSide[i] ? 0.5 : 1.0;
132     }
133   }
134   Standard_Real inThreshold = myPlanes.size(); // usually 4.0
135   if ( myConcaveQuad )
136     inThreshold = 2.5; // 1.0 + 1.0 + 0.5
137
138   if ( nbIn >= inThreshold )
139     return TopAbs_IN;
140
141   return TopAbs_OUT;
142 }
143