0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / TopOpeBRep / TopOpeBRep_VPointInterClassifier.cxx
1 // Created on: 1993-11-18
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Surface.hxx>
20 #include <Geom2d_Curve.hxx>
21 #include <Geom_Curve.hxx>
22 #include <GeomAPI_ProjectPointOnCurve.hxx>
23 #include <gp_Pnt2d.hxx>
24 #include <Precision.hxx>
25 #include <Standard_ProgramError.hxx>
26 #include <TopoDS.hxx>
27 #include <TopoDS_Shape.hxx>
28 #include <TopoDS_Vertex.hxx>
29 #include <TopOpeBRep_PointClassifier.hxx>
30 #include <TopOpeBRep_VPointInter.hxx>
31 #include <TopOpeBRep_VPointInterClassifier.hxx>
32 #include <TopOpeBRepTool_ShapeTool.hxx>
33
34 //modified by NIZHNY-MKK  Fri Jun 16 15:04:09 2000.BEGIN
35 //modified by NIZHNY-MKK  Fri Jun 16 15:04:09 2000.END
36 //modified by NIZHNY-MKK  Mon Jun 19 11:47:48 2000.BEGIN
37 static TopAbs_State SlowClassifyOnBoundary(const gp_Pnt& thePointToClassify, 
38                                            const gp_Pnt2d& thePoint2dToClassify,
39                                            BRepClass_FaceClassifier& theSlowClassifier, 
40                                            const TopoDS_Face& theFace);
41 //modified by NIZHNY-MKK  Mon Jun 19 11:47:51 2000.END
42
43 //=======================================================================
44 //function : TopOpeBRep_VPointInterClassifier
45 //purpose  : 
46 //=======================================================================
47
48 TopOpeBRep_VPointInterClassifier::TopOpeBRep_VPointInterClassifier() :
49 myState(TopAbs_UNKNOWN)
50 {
51 }
52
53 //=======================================================================
54 //function : VPointPosition
55 //purpose  : 
56 //=======================================================================
57
58 TopAbs_State TopOpeBRep_VPointInterClassifier::VPointPosition
59 (const TopoDS_Shape&  F,
60  TopOpeBRep_VPointInter& VP,
61  const Standard_Integer FaceClassifyIndex,
62  TopOpeBRep_PointClassifier& PC,
63  const Standard_Boolean AssumeINON,
64  const Standard_Real Tol)
65 {
66   myState = TopAbs_UNKNOWN;
67
68   Standard_Real u,v;
69   switch (FaceClassifyIndex) {
70   case 1 : { 
71     VP.ParametersOnS1(u,v); 
72     if(VP.IsOnDomS1()) { 
73       VP.State(TopAbs_ON,1);
74       const TopoDS_Edge& E = TopoDS::Edge(VP.ArcOnS1());
75       const Standard_Real pE = VP.ParameterOnArc1();
76       VP.EdgeON(E,pE,1);
77       myState = TopAbs_ON;
78       return myState;
79     }
80     break;
81   }
82   case 2 : {
83     VP.ParametersOnS2(u,v); 
84     if(VP.IsOnDomS2()) { 
85       VP.State(TopAbs_ON,2);
86       const TopoDS_Edge& E = TopoDS::Edge(VP.ArcOnS2());
87       const Standard_Real pE = VP.ParameterOnArc2();
88       VP.EdgeON(E,pE,2);
89       myState = TopAbs_ON;
90       return myState;
91     }
92     break;
93   }
94   default : throw Standard_ProgramError("VPointClassifier : wrong Index");
95   }
96
97   if (myState == TopAbs_ON) {
98     return myState;
99   }
100
101   TopoDS_Face FF = TopoDS::Face(F);
102   TopOpeBRepTool_ShapeTool::AdjustOnPeriodic(FF,u,v);
103   gp_Pnt2d p2d(u,v);
104   TopAbs_State statefast = PC.Classify(FF,p2d,Tol);
105   myState = statefast;
106   VP.State(myState,FaceClassifyIndex);
107
108   // AssumeINON = True <=> on considere que tout VP rendu par les
109   // intersections est sur une frontiere de la face FF (ON)ou dans la face FF (IN)  
110   Standard_Integer VPSI = VP.ShapeIndex();
111   if (AssumeINON && FaceClassifyIndex == VPSI) {
112     mySlowFaceClassifier.Perform(FF,p2d,Tol);
113     myState = mySlowFaceClassifier.State();
114     if      (myState == TopAbs_ON) {
115 //modified by NIZHNY-MKK  Mon Jun 19 11:45:36 2000.BEGIN
116       myState = SlowClassifyOnBoundary(VP.Value(), p2d, mySlowFaceClassifier, FF);      
117       if(myState == TopAbs_ON) {
118 //modified by NIZHNY-MKK  Mon Jun 19 11:45:36 2000.END
119         VP.EdgeON(mySlowFaceClassifier.Edge().Edge(),
120                   mySlowFaceClassifier.EdgeParameter(),
121                   FaceClassifyIndex);
122       }
123     }
124     else if ( myState == TopAbs_OUT) {
125       myState = TopAbs_IN; 
126       // ou biwn myState = TopAbs_OUT ce qui va entrainer VP.UnKeep()
127       // si on privilegie le classifieur / donnees d'intersection.
128     }
129   } // (AssumeINON && FaceClassifyIndex == VPSI)
130
131   else if (!AssumeINON) {
132     if (statefast == TopAbs_OUT || statefast == TopAbs_ON) {
133       mySlowFaceClassifier.Perform(FF,p2d,Tol);
134       myState = mySlowFaceClassifier.State();
135       if      (myState == TopAbs_ON) {
136 //modified by NIZHNY-MKK  Mon Jun 19 11:45:36 2000.BEGIN
137         myState = SlowClassifyOnBoundary(VP.Value(), p2d, mySlowFaceClassifier, FF);
138         if(myState == TopAbs_ON) {
139 //modified by NIZHNY-MKK  Mon Jun 19 11:45:36 2000.END
140           VP.EdgeON(mySlowFaceClassifier.Edge().Edge(),
141                     mySlowFaceClassifier.EdgeParameter(),
142                     FaceClassifyIndex);
143         }
144       }
145     }
146   }
147  
148   else if (FaceClassifyIndex != VPSI) {
149     // AssumeINON = True
150     //modified by NIZNHY-PKV Mon Feb  5 19:04:01 2001 f
151     if (statefast == TopAbs_ON || statefast == TopAbs_OUT) {
152     //if (statefast == TopAbs_ON) {
153       mySlowFaceClassifier.Perform(FF, p2d, Tol);
154       myState = mySlowFaceClassifier.State();
155       
156       if (myState == TopAbs_ON || myState == TopAbs_OUT) {
157       //if  (myState == TopAbs_ON) {
158       //modified by NIZNHY-PKV Mon Feb  5 19:04:49 2001 t
159         myState = SlowClassifyOnBoundary(VP.Value(), p2d, mySlowFaceClassifier, FF);
160         if(myState==TopAbs_ON) {
161           VP.EdgeON(mySlowFaceClassifier.Edge().Edge(),
162                     mySlowFaceClassifier.EdgeParameter(),
163                     FaceClassifyIndex);
164         }
165       }
166     }
167   }
168   
169   VP.State(myState,FaceClassifyIndex);
170   return myState;
171 }
172
173
174 //=======================================================================
175 //function : Edge
176 //purpose  : 
177 //=======================================================================
178
179 const TopoDS_Shape& TopOpeBRep_VPointInterClassifier::Edge() const
180 {
181   if (myState == TopAbs_ON) {
182     const TopoDS_Shape& S = mySlowFaceClassifier.Edge().Edge();
183     return S;
184   }
185   else {
186     return myNullShape;
187   }
188 }
189
190
191 //=======================================================================
192 //function : EdgeParameter
193 //purpose  : 
194 //=======================================================================
195
196 Standard_Real TopOpeBRep_VPointInterClassifier::EdgeParameter() const
197 {
198   if (myState == TopAbs_ON) return mySlowFaceClassifier.EdgeParameter();
199   else return 0;
200 }
201
202 //modified by NIZHNY-MKK  Mon Jun 19 11:47:23 2000.BEGIN
203 //=======================================================================
204 //static function : SlowClassifyOnBoundary
205 //purpose  : 
206 //=======================================================================
207 static TopAbs_State SlowClassifyOnBoundary(const gp_Pnt& thePointToClassify, 
208                                            const gp_Pnt2d& thePoint2dToClassify,
209                                            BRepClass_FaceClassifier& theSlowClassifier, 
210                                            const TopoDS_Face& theFace) {   
211
212   Standard_Real aParameterOnEdge = theSlowClassifier.EdgeParameter();
213   const TopoDS_Edge& anEdge = theSlowClassifier.Edge().Edge();
214
215   Standard_Real parf, parl;
216   Handle(Geom_Curve) anEdgeCurve = BRep_Tool::Curve(anEdge, parf, parl);
217   
218   if(!anEdgeCurve.IsNull()) {
219     Standard_Real minparameterdiff = parl - parf;
220     Standard_Real aDistanceToCompare = 0;
221     Standard_Boolean samewithvertex = Standard_False;
222     TopExp_Explorer anExp(anEdge, TopAbs_VERTEX);
223     for(;anExp.More() && !samewithvertex; anExp.Next()) {
224       TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
225       Standard_Real aVertexTolerance = BRep_Tool::Tolerance(aVertex);
226       gp_Pnt anEdgeVertexPoint = BRep_Tool::Pnt(aVertex);
227       if(thePointToClassify.IsEqual(anEdgeVertexPoint, aVertexTolerance))
228         samewithvertex = Standard_True;
229     }
230     if(samewithvertex)
231       return TopAbs_ON;
232
233     GeomAPI_ProjectPointOnCurve aProjTool(thePointToClassify, anEdgeCurve);
234
235     for(Standard_Integer i=1; i<=aProjTool.NbPoints(); i++) {
236       Standard_Real curparamdiff = Abs(aProjTool.Parameter(i) - aParameterOnEdge);
237       if(curparamdiff < minparameterdiff) {
238         minparameterdiff = curparamdiff;
239           aDistanceToCompare = aProjTool.Distance(i);
240       }
241     }
242     
243     Standard_Real anEdgeTolerance = BRep_Tool::Tolerance(anEdge);
244       
245     if((aProjTool.NbPoints()==0) || (aDistanceToCompare >= anEdgeTolerance)) {
246       Handle(Geom2d_Curve) anEdgePCurve = BRep_Tool::CurveOnSurface(anEdge, theFace, parf, parl);
247           
248       if(!anEdgePCurve.IsNull()) {
249         gp_Pnt2d aPoint2dOnEdge = anEdgePCurve->Value(aParameterOnEdge);
250         Standard_Real aTol2d = thePoint2dToClassify.Distance(aPoint2dOnEdge) / 3;
251         theSlowClassifier.Perform(theFace, thePoint2dToClassify, aTol2d);
252         if(theSlowClassifier.State() == TopAbs_IN)
253           return TopAbs_IN;
254         else
255           return TopAbs_OUT;
256       }
257       else {
258         return TopAbs_OUT;
259       }
260     }
261   } //end if(!anEdgeCurve.IsNull())
262
263   return TopAbs_ON;
264 }
265 //modified by NIZHNY-MKK  Mon Jun 19 11:47:26 2000.END
266