905e140fdd515fcdc2aef7e134d08841b9411a97
[occt.git] / src / TopOpeBRep / TopOpeBRep_FaceEdgeIntersector.cxx
1 // Created on: 1994-10-07
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-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 <BRepIntCurveSurface_Inter.hxx>
20 #include <Geom_Curve.hxx>
21 #include <gp_Pnt.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <IntCurveSurface_IntersectionPoint.hxx>
24 #include <IntCurveSurface_TransitionOnCurve.hxx>
25 #include <Precision.hxx>
26 #include <Standard_ProgramError.hxx>
27 #include <TopExp_Explorer.hxx>
28 #include <TopLoc_Location.hxx>
29 #include <TopoDS.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Vertex.hxx>
32 #include <TopOpeBRep_FaceEdgeIntersector.hxx>
33 #include <TopOpeBRepDS_Transition.hxx>
34 #include <TopOpeBRepTool_ShapeTool.hxx>
35
36 #ifdef OCCT_DEBUG
37 #include <TopAbs.hxx>
38 extern Standard_Boolean TopOpeBRep_GettraceFITOL();
39 extern Standard_Boolean TopOpeBRep_GettraceSAVFF();
40 #include <TCollection_AsciiString.hxx>
41 #include <Standard_CString.hxx>
42 #include <BRepTools.hxx>
43 static void SAVFE(const TopoDS_Face& F1,const TopoDS_Edge& E)
44 {
45   TCollection_AsciiString aname_1("FE_face"), aname_2("FE_edge");
46   Standard_CString name_1 = aname_1.ToCString(), name_2 = aname_2.ToCString();
47   cout<<"FaceEdgeIntersector : "<<name_1<<","<<name_2<<endl;
48   BRepTools::Write(F1,name_1); BRepTools::Write(E,name_2); 
49 }
50 extern Standard_Boolean TopOpeBRepTool_GettraceKRO();
51 #include <TopOpeBRepTool_KRO.hxx>
52 Standard_EXPORT TOPKRO KRO_DSFILLER_INTFE("intersection face/edge");
53 #endif
54
55
56 //=======================================================================
57 //function : TopOpeBRep_FaceEdgeIntersector
58 //purpose  : 
59 //=======================================================================
60
61  TopOpeBRep_FaceEdgeIntersector::TopOpeBRep_FaceEdgeIntersector()
62 {
63   ResetIntersection();
64 }
65
66 //=======================================================================
67 //function : ResetIntersection
68 //purpose  : 
69 //=======================================================================
70
71 void TopOpeBRep_FaceEdgeIntersector::ResetIntersection() 
72 {
73   mySequenceOfPnt.Clear();
74   mySequenceOfState.Clear();
75   myNbPoints = 0;
76   myIntersectionDone = Standard_False;
77 }
78
79
80 //=======================================================================
81 //function : Perform
82 //purpose  : 
83 //=======================================================================
84
85 void TopOpeBRep_FaceEdgeIntersector::Perform(const TopoDS_Shape& SF,
86                                              const TopoDS_Shape& SE)
87 {
88   ResetIntersection();
89   if (!myForceTolerance) ShapeTolerances(SF,SE);
90   myTol = BRep_Tool::Tolerance(TopoDS::Edge(SE));
91 #ifdef OCCT_DEBUG
92   if (TopOpeBRep_GettraceFITOL()) cout<<"Perform : myTol = "<<myTol<<endl;
93 #endif
94   
95   myFace = TopoDS::Face(SF); myFace.Orientation(TopAbs_FORWARD);
96   myEdge = TopoDS::Edge(SE); myEdge.Orientation(TopAbs_FORWARD);
97
98 #ifdef OCCT_DEBUG
99   if (TopOpeBRep_GettraceSAVFF()) SAVFE(myFace,myEdge);
100 #endif
101   
102   Standard_Real f,l;
103   TopLoc_Location loc;
104   const Handle(Geom_Curve) C = BRep_Tool::Curve(myEdge,loc,f,l);
105   
106   Handle(Geom_Geometry) GGao1 = C->Transformed(loc.Transformation());
107   Handle(Geom_Curve)* PGCao1 = (Handle(Geom_Curve)*)&GGao1;
108   myCurve.Load(*PGCao1,f,l);
109
110
111 #ifdef OCCT_DEBUG
112   if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFE.Start();
113 #endif
114
115   BRepIntCurveSurface_Inter FEINT;
116   FEINT.Init(myFace,myCurve,myTol);
117
118 #ifdef OCCT_DEBUG
119   if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFE.Stop();
120 #endif
121
122   for (FEINT.Init(myFace,myCurve,myTol); FEINT.More(); FEINT.Next()) {
123     mySequenceOfPnt.Append(FEINT.Point());
124     Standard_Integer i = (FEINT.State() == TopAbs_IN) ? 0 : 1;
125     mySequenceOfState.Append(i);
126   }
127
128   myNbPoints = mySequenceOfPnt.Length();
129   myIntersectionDone = Standard_True;
130
131 }
132
133
134 //=======================================================================
135 //function : IsEmpty
136 //purpose  : 
137 //=======================================================================
138
139 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::IsEmpty () 
140 {
141   Standard_Boolean b = myNbPoints == 0;
142   return b;
143 }
144
145
146 //=======================================================================
147 //function : Shape
148 //purpose  : 
149 //=======================================================================
150
151 const TopoDS_Shape& TopOpeBRep_FaceEdgeIntersector::Shape
152 (const Standard_Integer Index) const 
153 {
154   if      ( Index == 1 ) return myFace;
155   else if ( Index == 2 ) return myEdge;
156   else Standard_ProgramError::Raise("TopOpeBRep_FaceEdgeIntersector::Shape");
157
158   return myNullShape;
159 }
160
161 //=======================================================================
162 //function : ForceTolerance
163 //purpose  : 
164 //=======================================================================
165
166 void TopOpeBRep_FaceEdgeIntersector::ForceTolerance(const Standard_Real Tol)
167 {
168   myTol = Tol;
169   myForceTolerance = Standard_True;
170   
171 #ifdef OCCT_DEBUG
172   if (TopOpeBRep_GettraceFITOL())
173     cout<<"ForceTolerance : myTol = "<<myTol<<endl;
174 #endif
175 }
176
177 //=======================================================================
178 //function : Tolerance
179 //purpose  : 
180 //=======================================================================
181
182 Standard_Real  TopOpeBRep_FaceEdgeIntersector::Tolerance() const
183 {
184   return myTol;
185 }
186
187 //=======================================================================
188 //function : NbPoints
189 //purpose  : 
190 //=======================================================================
191
192 Standard_Integer TopOpeBRep_FaceEdgeIntersector::NbPoints() const 
193 {
194   Standard_Integer n = myNbPoints;
195   return n;
196 }
197
198
199 //=======================================================================
200 //function : InitPoint
201 //purpose  : 
202 //=======================================================================
203
204 void TopOpeBRep_FaceEdgeIntersector::InitPoint()
205 {
206   myPointIndex = 1;
207 }
208
209 //=======================================================================
210 //function : MorePoint
211 //purpose  : 
212 //=======================================================================
213
214 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::MorePoint() const 
215 {
216   Standard_Boolean b = myPointIndex <= myNbPoints;
217   return b;
218 }
219
220 //=======================================================================
221 //function : NextPoint
222 //purpose  : 
223 //=======================================================================
224
225 void TopOpeBRep_FaceEdgeIntersector::NextPoint()
226 {
227   myPointIndex++;
228 }
229
230 //=======================================================================
231 //function : Value
232 //purpose  : 
233 //=======================================================================
234
235 gp_Pnt TopOpeBRep_FaceEdgeIntersector::Value() const 
236 {
237   const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
238   const gp_Pnt& P = IP.Pnt();
239   return P;
240 }
241
242
243 //=======================================================================
244 //function : Parameter
245 //purpose  : 
246 //=======================================================================
247
248 Standard_Real TopOpeBRep_FaceEdgeIntersector::Parameter() const
249 {
250   const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
251   Standard_Real p = IP.W();
252   return p;
253 }
254
255 //=======================================================================
256 //function : UVPoint
257 //purpose  : 
258 //=======================================================================
259
260 void TopOpeBRep_FaceEdgeIntersector::UVPoint(gp_Pnt2d& P2d) const
261 {
262   const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
263   Standard_Real u = IP.U();
264   Standard_Real v = IP.V();
265   P2d.SetCoord(u,v);
266 }
267
268 //=======================================================================
269 //function : State
270 //purpose  : 
271 //=======================================================================
272
273 TopAbs_State TopOpeBRep_FaceEdgeIntersector::State() const
274 {
275   Standard_Integer i = mySequenceOfState(myPointIndex);
276   TopAbs_State s = (i == 0 ) ? TopAbs_IN : TopAbs_ON;
277   return s;
278 }
279
280 //=======================================================================
281 //function : Transition
282 //purpose  : 
283 //=======================================================================
284
285 TopOpeBRepDS_Transition TopOpeBRep_FaceEdgeIntersector::Transition
286 (const Standard_Integer Index,
287  const TopAbs_Orientation FaceOrientation) const 
288 {
289 //  TopAbs_ShapeEnum onB = TopAbs_FACE, onA = TopAbs_FACE; // bidon
290 //  if ((FaceOrientation == TopAbs_INTERNAL) || 
291 //      (FaceOrientation == TopAbs_EXTERNAL)) {
292 //    TopOpeBRepDS_Transition TR(TopAbs_IN,TopAbs_IN,onB,onA); // IN bidon
293 //    TR.Set(FaceOrientation);
294 //    return TR;
295 //  }
296
297   TopAbs_State stB, stA;
298
299   const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
300
301   if ( Index == 2 ) {  //--   Edge In <=>   Rentre ds la matiere face
302     switch (IP.Transition()) { 
303       case IntCurveSurface_In  : stB = TopAbs_OUT; stA = TopAbs_IN; break;
304       case IntCurveSurface_Out : stB = TopAbs_IN; stA = TopAbs_OUT; break;
305       default :                  stB = TopAbs_IN; stA = TopAbs_IN; break;
306     }
307
308     TopOpeBRepDS_Transition TR;
309     TopAbs_ShapeEnum onB = TopAbs_FACE, onA = TopAbs_FACE; 
310     if      (FaceOrientation == TopAbs_FORWARD) 
311       TR.Set(stB,stA,onB,onA);
312     else if (FaceOrientation == TopAbs_REVERSED) 
313       TR.Set(stA,stB,onA,onB);
314     else if (FaceOrientation == TopAbs_EXTERNAL) 
315       TR.Set(TopAbs_OUT,TopAbs_OUT,onA,onB);
316     else if (FaceOrientation == TopAbs_INTERNAL) 
317       TR.Set(TopAbs_IN,TopAbs_IN,onA,onB);
318     return TR;
319   }
320
321   else if ( Index == 1 ) { //-- Face On est toujours ds la face . 
322     switch (IP.Transition()) { 
323       case IntCurveSurface_In  : stB = stA = TopAbs_IN; break;
324       case IntCurveSurface_Out : stB = stA = TopAbs_IN; break;
325       default :                  stB = stA = TopAbs_IN; break;
326     }
327     TopAbs_ShapeEnum onB = TopAbs_FACE, onA = TopAbs_FACE; 
328     TopOpeBRepDS_Transition TR;
329     TR.Set(stB,stA,onB,onA);
330     return TR;
331   }
332
333   else Standard_ProgramError::Raise("FEINT Transition Index");
334
335 //  return(TopOpeBRepDS_Transition());
336   TopOpeBRepDS_Transition aValRet ;
337   return (aValRet);
338 }
339
340 //=======================================================================
341 //function : IsVertex
342 //purpose  : 
343 //=======================================================================
344
345 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::IsVertex
346 (const TopoDS_Shape& S, const gp_Pnt& P,
347  const Standard_Real Tol, TopoDS_Vertex& VR)
348 {
349   Standard_Boolean isv = Standard_False;
350   VR = myNullVertex;
351
352   Standard_Real Tol2=Tol*Tol;
353   for (myVertexExplorer.Init(S,TopAbs_VERTEX); 
354        myVertexExplorer.More(); 
355        myVertexExplorer.Next()) {
356     const TopoDS_Shape& SS = myVertexExplorer.Current();
357     const TopoDS_Vertex& VV = TopoDS::Vertex(SS);
358     gp_Pnt PV = BRep_Tool::Pnt(VV);
359     isv = P.SquareDistance(PV) < Tol2;
360     if (isv) {
361       VR = VV;
362     }
363   }
364
365   return isv;
366 }
367
368 //=======================================================================
369 //function : IsVertex
370 //purpose  : 
371 //=======================================================================
372
373 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::IsVertex
374 (const Standard_Integer I, TopoDS_Vertex& VR)
375 {
376   Standard_Boolean isv = Standard_False;
377   gp_Pnt P = Value();
378   if      (I == 1) isv = IsVertex(myFace,P,myTol,VR);
379   else if (I == 2) isv = IsVertex(myEdge,P,myTol,VR);
380   return isv;
381 }
382
383 //=======================================================================
384 //function : Index
385 //purpose  : 
386 //=======================================================================
387
388 Standard_Integer TopOpeBRep_FaceEdgeIntersector::Index() const 
389 {
390 #ifdef OCCT_DEBUG
391   return myPointIndex;
392 #else
393   return 0;
394 #endif
395 }
396
397
398 //=======================================================================
399 //function : ShapeTolerances
400 //purpose  : (private)
401 //=======================================================================
402
403 void TopOpeBRep_FaceEdgeIntersector::ShapeTolerances(const TopoDS_Shape& S1,
404                                                      const TopoDS_Shape& S2)
405 {
406   myTol = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE));
407   myForceTolerance = Standard_False;
408   
409 #ifdef OCCT_DEBUG
410   if (TopOpeBRep_GettraceFITOL()) {
411     cout<<"ShapeTolerances on S1 = ";TopAbs::Print(S1.ShapeType(),cout);
412     cout<<" S2 = ";TopAbs::Print(S2.ShapeType(),cout);
413     cout<<" : myTol = "<<myTol<<endl;
414   }
415 #endif
416 }
417
418 //=======================================================================
419 //function : ToleranceMax
420 //purpose  : (private)
421 //=======================================================================
422
423 Standard_Real TopOpeBRep_FaceEdgeIntersector::ToleranceMax
424 (const TopoDS_Shape& S,
425  const TopAbs_ShapeEnum T)const
426 {
427   TopExp_Explorer e(S,T);
428   if ( ! e.More() ) return Precision::Intersection();
429   else {
430     Standard_Real tol = RealFirst();
431     for (; e.More(); e.Next())
432       tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current()));
433     return tol;
434   }
435 }