47983aca8176cdd4b12013099cefdbb123b9c61e
[occt.git] / src / BOPTools / BOPTools_StateFiller.cxx
1 // File:        BOPTools_StateFiller.cxx
2 // Created:     Mon Feb  4 10:08:20 2002
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6 //  Modified by skv - Tue Aug 24 12:31:16 2004 OCC6450
7
8 #include <BOPTools_StateFiller.ixx>
9
10 #include <Precision.hxx>
11
12 #include <Geom_Curve.hxx>
13 #include <gp_Pnt.hxx>
14
15 #include <BRep_Tool.hxx>
16 #include <BRepClass3d_SolidClassifier.hxx>
17
18 #include <TopoDS.hxx>
19 #include <TopoDS_Vertex.hxx>
20 #include <TopoDS_Solid.hxx>
21
22 #include <TopAbs_State.hxx>
23 #include <TopTools_IndexedMapOfShape.hxx>
24 #include <TopExp.hxx>
25
26 #include <BooleanOperations_StateOfShape.hxx>
27
28 #include <IntTools_Tools.hxx>
29 #include <IntTools_Context.hxx>
30 #include <Geom_Surface.hxx>
31
32 //=======================================================================
33 // function:  BOPTools_StateFiller::BOPTools_StateFiller
34 // purpose: 
35 //=======================================================================
36   BOPTools_StateFiller::BOPTools_StateFiller(const BOPTools_PaveFiller& aFiller)
37 :
38   myIsDone(Standard_False)
39 {
40   myFiller=(BOPTools_PaveFiller*) &aFiller;
41   myDS=myFiller->DS();
42   myIntrPool=myFiller->InterfPool();
43 }
44 //=======================================================================
45 // function: Do 
46 // purpose: 
47 //=======================================================================
48   void BOPTools_StateFiller::Do()
49 {
50 }
51 //=======================================================================
52 // function:  IsDone
53 // purpose: 
54 //=======================================================================
55   Standard_Boolean BOPTools_StateFiller::IsDone() const
56 {
57   return myIsDone;
58 }
59
60 //=======================================================================
61 // function:  ConvertState
62 // purpose: 
63 //=======================================================================
64   BooleanOperations_StateOfShape BOPTools_StateFiller::ConvertState(const TopAbs_State aSt)
65 {
66   BooleanOperations_StateOfShape aState;
67   switch (aSt) {
68     case TopAbs_IN:
69       aState=BooleanOperations_IN;
70       break;
71     case TopAbs_OUT:
72       aState=BooleanOperations_OUT;
73       break;  
74     case TopAbs_ON:
75       aState=BooleanOperations_ON;
76       break;  
77     case TopAbs_UNKNOWN:
78       aState=BooleanOperations_UNKNOWN;
79       break;  
80     default:
81       aState=BooleanOperations_UNKNOWN;
82       break;  
83   }
84   return aState;
85 }
86
87 //=======================================================================
88 // function:  ConvertState
89 // purpose: 
90 //=======================================================================
91   TopAbs_State BOPTools_StateFiller::ConvertState(const BooleanOperations_StateOfShape aSt)
92 {
93   TopAbs_State aState;
94   
95   switch (aSt) {
96     case BooleanOperations_IN:
97       aState=TopAbs_IN;
98       break;
99     case BooleanOperations_OUT:
100       aState=TopAbs_OUT;
101       break;  
102     case BooleanOperations_ON:
103       aState=TopAbs_ON;
104       break;  
105     case BooleanOperations_UNKNOWN:
106       aState=TopAbs_UNKNOWN;
107       break;  
108     default:
109       aState=TopAbs_UNKNOWN;
110       break;  
111   }
112   return aState;
113 }
114                                             
115 //=======================================================================
116 // function:  ClassifyShapeByRef
117 // purpose: 
118 //=======================================================================
119   BooleanOperations_StateOfShape BOPTools_StateFiller::ClassifyShapeByRef (const TopoDS_Shape& aS,
120                                                                            const TopoDS_Shape& aRef)
121 {
122   TopAbs_ShapeEnum aType;
123   aType=aS.ShapeType();
124
125 //  Modified by skv - Tue Aug 24 12:31:16 2004 OCC6450 Begin
126   Standard_Boolean hasEdge = Standard_True;
127 //  Modified by skv - Tue Aug 24 12:31:17 2004 OCC6450 End
128   TopoDS_Edge aE;
129   if (aType!=TopAbs_EDGE) {
130     TopTools_IndexedMapOfShape aME;
131     TopExp::MapShapes(aS, TopAbs_EDGE, aME);
132
133 //  Modified by skv - Tue Aug 24 12:31:16 2004 OCC6450 Begin
134     if (aME.Extent() == 0)
135       hasEdge = Standard_False;
136     else
137 //  Modified by skv - Tue Aug 24 12:31:16 2004 OCC6450 End
138       aE=TopoDS::Edge(aME(1));
139   }
140   else {
141     aE=TopoDS::Edge(aS);
142   }
143   
144 //  Modified by skv - Tue Aug 24 12:31:16 2004 OCC6450 Begin
145 //   TopAbs_State aSt=ClassifyEdgeToSolidByOnePoint(aE, aRef);
146   TopAbs_State aSt;
147
148   if (hasEdge) {
149     aSt = ClassifyEdgeToSolidByOnePoint(aE, aRef);
150   } else {
151     TopTools_IndexedMapOfShape aMF;
152     Standard_Boolean           hasFace = Standard_True;
153     TopoDS_Face                aF;
154
155     TopExp::MapShapes(aS, TopAbs_FACE, aMF);
156
157 //  Modified by skv - Tue Aug 24 12:31:16 2004 OCC6450 Begin
158     if (aMF.Extent() == 0) {
159       hasFace = Standard_False;
160     } else {
161       aF = TopoDS::Face(aMF(1));
162     }
163
164     if (!hasFace) {
165       aSt = TopAbs_UNKNOWN;
166     } else {
167       Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aF);
168       Standard_Real        aUMin;
169       Standard_Real        aUMax;
170       Standard_Real        aVMin;
171       Standard_Real        aVMax;
172
173       aSurf->Bounds(aUMin, aUMax, aVMin, aVMax);
174
175       Standard_Boolean isMinInf = Precision::IsNegativeInfinite(aUMin);
176       Standard_Boolean isMaxInf = Precision::IsPositiveInfinite(aUMax);
177       Standard_Real    dT=10.;
178       Standard_Real    aParU;
179       Standard_Real    aParV;
180
181       if (isMinInf && !isMaxInf) {
182         aParU = aUMax - dT;
183       } else if (!isMinInf && isMaxInf) {
184         aParU = aUMin + dT;
185       } else if (isMinInf && isMaxInf) {
186         aParU = 0.;
187       } else {
188         aParU = IntTools_Tools::IntermediatePoint(aUMin, aUMax);
189       }
190
191       isMinInf = Precision::IsNegativeInfinite(aVMin);
192       isMaxInf = Precision::IsPositiveInfinite(aVMax);
193
194       if (isMinInf && !isMaxInf) {
195         aParV = aVMax - dT;
196       } else if (!isMinInf && isMaxInf) {
197         aParV = aVMin + dT;
198       } else if (isMinInf && isMaxInf) {
199         aParV = 0.;
200       } else {
201         aParV = IntTools_Tools::IntermediatePoint(aVMin, aVMax);
202       }
203
204       gp_Pnt aP3d = aSurf->Value(aParU, aParV);
205
206       const TopoDS_Solid          &aRefSolid = TopoDS::Solid(aRef);
207       IntTools_Context            &aContext  = myFiller->ChangeContext();
208       BRepClass3d_SolidClassifier &aSC       = 
209                                        aContext.SolidClassifier(aRefSolid);
210   //
211       aSC.Perform(aP3d, 1e-7);
212   //
213       aSt = aSC.State();
214     }
215   }
216 //  Modified by skv - Tue Aug 24 12:31:16 2004 OCC6450 Begin
217
218   BooleanOperations_StateOfShape aState=BOPTools_StateFiller::ConvertState(aSt) ;
219   
220   return aState;
221 }
222
223
224 //=======================================================================
225 // function:  ClassifyEdgeToSolidByOnePoint
226 // purpose: 
227 //=======================================================================
228   TopAbs_State  BOPTools_StateFiller::ClassifyEdgeToSolidByOnePoint(const TopoDS_Edge& E,
229                                                                     const TopoDS_Shape& Ref)
230 {
231   Standard_Real f2 = 0., l2 = 0., par = 0.;
232   
233   Handle(Geom_Curve) C3D = BRep_Tool::Curve(E, f2, l2);
234   gp_Pnt aP3d;
235         
236   if(C3D.IsNull()) {
237     //it means that we are in degenerated edge
238     const TopoDS_Vertex& fv = TopExp::FirstVertex(E);
239     if(fv.IsNull()){
240       return TopAbs_UNKNOWN;
241     }
242     aP3d = BRep_Tool::Pnt(fv);
243   }
244   else {//usual case
245     Standard_Boolean bF2Inf, bL2Inf;
246     Standard_Real dT=10.;
247     //
248     bF2Inf = Precision::IsNegativeInfinite(f2);
249     bL2Inf = Precision::IsPositiveInfinite(l2);
250     //
251     if (bF2Inf && !bL2Inf) {
252       par=l2-dT;
253     }
254     else if (!bF2Inf && bL2Inf) {
255       par=f2+dT;
256     }
257     else if (bF2Inf && bL2Inf) {
258       par=0.;
259     }
260     else {
261       par=IntTools_Tools::IntermediatePoint(f2, l2);
262     }
263     C3D -> D0(par, aP3d);
264   }
265   //
266   const TopoDS_Solid& aRefSolid=TopoDS::Solid(Ref);
267   IntTools_Context& aContext=myFiller->ChangeContext();
268   BRepClass3d_SolidClassifier& aSC=aContext.SolidClassifier(aRefSolid);
269   //
270   aSC.Perform(aP3d, 1e-7);
271   //
272   TopAbs_State aState=aSC.State();
273   
274   return aState;
275 }
276 //=======================================================================
277 // function:  SubType
278 // purpose: 
279 //=======================================================================
280   TopAbs_ShapeEnum BOPTools_StateFiller::SubType(const TopoDS_Shape& aS)
281 {
282   TopAbs_ShapeEnum aSourceType, aReturnType;
283   aSourceType=aS.ShapeType();
284
285   switch (aSourceType) {
286     case TopAbs_SOLID:
287       aReturnType=TopAbs_SHELL;
288       break;
289     case TopAbs_SHELL:
290       aReturnType=TopAbs_FACE;
291       break;
292     case TopAbs_FACE:
293       aReturnType=TopAbs_WIRE;
294       break;  
295     case TopAbs_WIRE:
296       aReturnType=TopAbs_EDGE;
297       break;   
298     case TopAbs_EDGE:
299       aReturnType=TopAbs_VERTEX;
300       break;     
301     default:
302       aReturnType=TopAbs_SHAPE;
303       break;
304   }
305   return aReturnType;
306 }