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>
SAVFE(const TopoDS_Face & F1,const TopoDS_Edge & E)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   std::cout<<"FaceEdgeIntersector : "<<name_1<<","<<name_2<<std::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 
TopOpeBRep_FaceEdgeIntersector()61  TopOpeBRep_FaceEdgeIntersector::TopOpeBRep_FaceEdgeIntersector()
62 {
63   ResetIntersection();
64 }
65 
66 //=======================================================================
67 //function : ResetIntersection
68 //purpose  :
69 //=======================================================================
70 
ResetIntersection()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 
Perform(const TopoDS_Shape & SF,const TopoDS_Shape & SE)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()) std::cout<<"Perform : myTol = "<<myTol<<std::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 
IsEmpty()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 
Shape(const Standard_Integer Index) const151 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 throw Standard_ProgramError("TopOpeBRep_FaceEdgeIntersector::Shape");
157 }
158 
159 //=======================================================================
160 //function : ForceTolerance
161 //purpose  :
162 //=======================================================================
163 
ForceTolerance(const Standard_Real Tol)164 void TopOpeBRep_FaceEdgeIntersector::ForceTolerance(const Standard_Real Tol)
165 {
166   myTol = Tol;
167   myForceTolerance = Standard_True;
168 
169 #ifdef OCCT_DEBUG
170   if (TopOpeBRep_GettraceFITOL())
171     std::cout<<"ForceTolerance : myTol = "<<myTol<<std::endl;
172 #endif
173 }
174 
175 //=======================================================================
176 //function : Tolerance
177 //purpose  :
178 //=======================================================================
179 
Tolerance() const180 Standard_Real  TopOpeBRep_FaceEdgeIntersector::Tolerance() const
181 {
182   return myTol;
183 }
184 
185 //=======================================================================
186 //function : NbPoints
187 //purpose  :
188 //=======================================================================
189 
NbPoints() const190 Standard_Integer TopOpeBRep_FaceEdgeIntersector::NbPoints() const
191 {
192   Standard_Integer n = myNbPoints;
193   return n;
194 }
195 
196 
197 //=======================================================================
198 //function : InitPoint
199 //purpose  :
200 //=======================================================================
201 
InitPoint()202 void TopOpeBRep_FaceEdgeIntersector::InitPoint()
203 {
204   myPointIndex = 1;
205 }
206 
207 //=======================================================================
208 //function : MorePoint
209 //purpose  :
210 //=======================================================================
211 
MorePoint() const212 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::MorePoint() const
213 {
214   Standard_Boolean b = myPointIndex <= myNbPoints;
215   return b;
216 }
217 
218 //=======================================================================
219 //function : NextPoint
220 //purpose  :
221 //=======================================================================
222 
NextPoint()223 void TopOpeBRep_FaceEdgeIntersector::NextPoint()
224 {
225   myPointIndex++;
226 }
227 
228 //=======================================================================
229 //function : Value
230 //purpose  :
231 //=======================================================================
232 
Value() const233 gp_Pnt TopOpeBRep_FaceEdgeIntersector::Value() const
234 {
235   const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
236   const gp_Pnt& P = IP.Pnt();
237   return P;
238 }
239 
240 
241 //=======================================================================
242 //function : Parameter
243 //purpose  :
244 //=======================================================================
245 
Parameter() const246 Standard_Real TopOpeBRep_FaceEdgeIntersector::Parameter() const
247 {
248   const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
249   Standard_Real p = IP.W();
250   return p;
251 }
252 
253 //=======================================================================
254 //function : UVPoint
255 //purpose  :
256 //=======================================================================
257 
UVPoint(gp_Pnt2d & P2d) const258 void TopOpeBRep_FaceEdgeIntersector::UVPoint(gp_Pnt2d& P2d) const
259 {
260   const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
261   Standard_Real u = IP.U();
262   Standard_Real v = IP.V();
263   P2d.SetCoord(u,v);
264 }
265 
266 //=======================================================================
267 //function : State
268 //purpose  :
269 //=======================================================================
270 
State() const271 TopAbs_State TopOpeBRep_FaceEdgeIntersector::State() const
272 {
273   Standard_Integer i = mySequenceOfState(myPointIndex);
274   TopAbs_State s = (i == 0 ) ? TopAbs_IN : TopAbs_ON;
275   return s;
276 }
277 
278 //=======================================================================
279 //function : Transition
280 //purpose  :
281 //=======================================================================
282 
Transition(const Standard_Integer Index,const TopAbs_Orientation FaceOrientation) const283 TopOpeBRepDS_Transition TopOpeBRep_FaceEdgeIntersector::Transition
284 (const Standard_Integer Index,
285  const TopAbs_Orientation FaceOrientation) const
286 {
287 //  TopAbs_ShapeEnum onB = TopAbs_FACE, onA = TopAbs_FACE; // bidon
288 //  if ((FaceOrientation == TopAbs_INTERNAL) ||
289 //      (FaceOrientation == TopAbs_EXTERNAL)) {
290 //    TopOpeBRepDS_Transition TR(TopAbs_IN,TopAbs_IN,onB,onA); // IN bidon
291 //    TR.Set(FaceOrientation);
292 //    return TR;
293 //  }
294 
295   TopAbs_State stB, stA;
296 
297   const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
298 
299   if ( Index == 2 ) {  //--   Edge In <=>   Rentre ds la matiere face
300     switch (IP.Transition()) {
301       case IntCurveSurface_In  : stB = TopAbs_OUT; stA = TopAbs_IN; break;
302       case IntCurveSurface_Out : stB = TopAbs_IN; stA = TopAbs_OUT; break;
303       default :                  stB = TopAbs_IN; stA = TopAbs_IN; break;
304     }
305 
306     TopOpeBRepDS_Transition TR;
307     TopAbs_ShapeEnum onB = TopAbs_FACE, onA = TopAbs_FACE;
308     if      (FaceOrientation == TopAbs_FORWARD)
309       TR.Set(stB,stA,onB,onA);
310     else if (FaceOrientation == TopAbs_REVERSED)
311       TR.Set(stA,stB,onA,onB);
312     else if (FaceOrientation == TopAbs_EXTERNAL)
313       TR.Set(TopAbs_OUT,TopAbs_OUT,onA,onB);
314     else if (FaceOrientation == TopAbs_INTERNAL)
315       TR.Set(TopAbs_IN,TopAbs_IN,onA,onB);
316     return TR;
317   }
318 
319   else if ( Index == 1 ) { //-- Face On est toujours ds la face .
320     switch (IP.Transition()) {
321       case IntCurveSurface_In  : stB = stA = TopAbs_IN; break;
322       case IntCurveSurface_Out : stB = stA = TopAbs_IN; break;
323       default :                  stB = stA = TopAbs_IN; break;
324     }
325     TopAbs_ShapeEnum onB = TopAbs_FACE, onA = TopAbs_FACE;
326     TopOpeBRepDS_Transition TR;
327     TR.Set(stB,stA,onB,onA);
328     return TR;
329   }
330 
331   else throw Standard_ProgramError("FEINT Transition Index");
332 }
333 
334 //=======================================================================
335 //function : IsVertex
336 //purpose  :
337 //=======================================================================
338 
IsVertex(const TopoDS_Shape & S,const gp_Pnt & P,const Standard_Real Tol,TopoDS_Vertex & VR)339 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::IsVertex
340 (const TopoDS_Shape& S, const gp_Pnt& P,
341  const Standard_Real Tol, TopoDS_Vertex& VR)
342 {
343   Standard_Boolean isv = Standard_False;
344   VR = myNullVertex;
345 
346   Standard_Real Tol2=Tol*Tol;
347   for (myVertexExplorer.Init(S,TopAbs_VERTEX);
348        myVertexExplorer.More();
349        myVertexExplorer.Next()) {
350     const TopoDS_Shape& SS = myVertexExplorer.Current();
351     const TopoDS_Vertex& VV = TopoDS::Vertex(SS);
352     gp_Pnt PV = BRep_Tool::Pnt(VV);
353     isv = P.SquareDistance(PV) < Tol2;
354     if (isv) {
355       VR = VV;
356     }
357   }
358 
359   return isv;
360 }
361 
362 //=======================================================================
363 //function : IsVertex
364 //purpose  :
365 //=======================================================================
366 
IsVertex(const Standard_Integer I,TopoDS_Vertex & VR)367 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::IsVertex
368 (const Standard_Integer I, TopoDS_Vertex& VR)
369 {
370   Standard_Boolean isv = Standard_False;
371   gp_Pnt P = Value();
372   if      (I == 1) isv = IsVertex(myFace,P,myTol,VR);
373   else if (I == 2) isv = IsVertex(myEdge,P,myTol,VR);
374   return isv;
375 }
376 
377 //=======================================================================
378 //function : Index
379 //purpose  :
380 //=======================================================================
381 
Index() const382 Standard_Integer TopOpeBRep_FaceEdgeIntersector::Index() const
383 {
384 #ifdef OCCT_DEBUG
385   return myPointIndex;
386 #else
387   return 0;
388 #endif
389 }
390 
391 
392 //=======================================================================
393 //function : ShapeTolerances
394 //purpose  : (private)
395 //=======================================================================
396 
ShapeTolerances(const TopoDS_Shape & S1,const TopoDS_Shape & S2)397 void TopOpeBRep_FaceEdgeIntersector::ShapeTolerances(const TopoDS_Shape& S1,
398 						     const TopoDS_Shape& S2)
399 {
400   myTol = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE));
401   myForceTolerance = Standard_False;
402 
403 #ifdef OCCT_DEBUG
404   if (TopOpeBRep_GettraceFITOL()) {
405     std::cout<<"ShapeTolerances on S1 = ";TopAbs::Print(S1.ShapeType(),std::cout);
406     std::cout<<" S2 = ";TopAbs::Print(S2.ShapeType(),std::cout);
407     std::cout<<" : myTol = "<<myTol<<std::endl;
408   }
409 #endif
410 }
411 
412 //=======================================================================
413 //function : ToleranceMax
414 //purpose  : (private)
415 //=======================================================================
416 
ToleranceMax(const TopoDS_Shape & S,const TopAbs_ShapeEnum T) const417 Standard_Real TopOpeBRep_FaceEdgeIntersector::ToleranceMax
418 (const TopoDS_Shape& S,
419  const TopAbs_ShapeEnum T)const
420 {
421   TopExp_Explorer e(S,T);
422   if ( ! e.More() ) return Precision::Intersection();
423   else {
424     Standard_Real tol = RealFirst();
425     for (; e.More(); e.Next())
426       tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current()));
427     return tol;
428   }
429 }
430