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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Tool.hxx>
19 #include <BRepIntCurveSurface_Inter.hxx>
20 #include <Geom_Curve.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>
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>
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)
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);
50 extern Standard_Boolean TopOpeBRepTool_GettraceKRO();
51 #include <TopOpeBRepTool_KRO.hxx>
52 Standard_EXPORT TOPKRO KRO_DSFILLER_INTFE("intersection face/edge");
56 //=======================================================================
57 //function : TopOpeBRep_FaceEdgeIntersector
59 //=======================================================================
61 TopOpeBRep_FaceEdgeIntersector::TopOpeBRep_FaceEdgeIntersector()
66 //=======================================================================
67 //function : ResetIntersection
69 //=======================================================================
71 void TopOpeBRep_FaceEdgeIntersector::ResetIntersection()
73 mySequenceOfPnt.Clear();
74 mySequenceOfState.Clear();
76 myIntersectionDone = Standard_False;
80 //=======================================================================
83 //=======================================================================
85 void TopOpeBRep_FaceEdgeIntersector::Perform(const TopoDS_Shape& SF,
86 const TopoDS_Shape& SE)
89 if (!myForceTolerance) ShapeTolerances(SF,SE);
90 myTol = BRep_Tool::Tolerance(TopoDS::Edge(SE));
92 if (TopOpeBRep_GettraceFITOL()) cout<<"Perform : myTol = "<<myTol<<endl;
95 myFace = TopoDS::Face(SF); myFace.Orientation(TopAbs_FORWARD);
96 myEdge = TopoDS::Edge(SE); myEdge.Orientation(TopAbs_FORWARD);
99 if (TopOpeBRep_GettraceSAVFF()) SAVFE(myFace,myEdge);
104 const Handle(Geom_Curve) C = BRep_Tool::Curve(myEdge,loc,f,l);
106 Handle(Geom_Geometry) GGao1 = C->Transformed(loc.Transformation());
107 Handle(Geom_Curve)* PGCao1 = (Handle(Geom_Curve)*)&GGao1;
108 myCurve.Load(*PGCao1,f,l);
112 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFE.Start();
115 BRepIntCurveSurface_Inter FEINT;
116 FEINT.Init(myFace,myCurve,myTol);
119 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFE.Stop();
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);
128 myNbPoints = mySequenceOfPnt.Length();
129 myIntersectionDone = Standard_True;
134 //=======================================================================
137 //=======================================================================
139 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::IsEmpty ()
141 Standard_Boolean b = myNbPoints == 0;
146 //=======================================================================
149 //=======================================================================
151 const TopoDS_Shape& TopOpeBRep_FaceEdgeIntersector::Shape
152 (const Standard_Integer Index) const
154 if ( Index == 1 ) return myFace;
155 else if ( Index == 2 ) return myEdge;
156 else Standard_ProgramError::Raise("TopOpeBRep_FaceEdgeIntersector::Shape");
161 //=======================================================================
162 //function : ForceTolerance
164 //=======================================================================
166 void TopOpeBRep_FaceEdgeIntersector::ForceTolerance(const Standard_Real Tol)
169 myForceTolerance = Standard_True;
172 if (TopOpeBRep_GettraceFITOL())
173 cout<<"ForceTolerance : myTol = "<<myTol<<endl;
177 //=======================================================================
178 //function : Tolerance
180 //=======================================================================
182 Standard_Real TopOpeBRep_FaceEdgeIntersector::Tolerance() const
187 //=======================================================================
188 //function : NbPoints
190 //=======================================================================
192 Standard_Integer TopOpeBRep_FaceEdgeIntersector::NbPoints() const
194 Standard_Integer n = myNbPoints;
199 //=======================================================================
200 //function : InitPoint
202 //=======================================================================
204 void TopOpeBRep_FaceEdgeIntersector::InitPoint()
209 //=======================================================================
210 //function : MorePoint
212 //=======================================================================
214 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::MorePoint() const
216 Standard_Boolean b = myPointIndex <= myNbPoints;
220 //=======================================================================
221 //function : NextPoint
223 //=======================================================================
225 void TopOpeBRep_FaceEdgeIntersector::NextPoint()
230 //=======================================================================
233 //=======================================================================
235 gp_Pnt TopOpeBRep_FaceEdgeIntersector::Value() const
237 const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
238 const gp_Pnt& P = IP.Pnt();
243 //=======================================================================
244 //function : Parameter
246 //=======================================================================
248 Standard_Real TopOpeBRep_FaceEdgeIntersector::Parameter() const
250 const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
251 Standard_Real p = IP.W();
255 //=======================================================================
258 //=======================================================================
260 void TopOpeBRep_FaceEdgeIntersector::UVPoint(gp_Pnt2d& P2d) const
262 const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
263 Standard_Real u = IP.U();
264 Standard_Real v = IP.V();
268 //=======================================================================
271 //=======================================================================
273 TopAbs_State TopOpeBRep_FaceEdgeIntersector::State() const
275 Standard_Integer i = mySequenceOfState(myPointIndex);
276 TopAbs_State s = (i == 0 ) ? TopAbs_IN : TopAbs_ON;
280 //=======================================================================
281 //function : Transition
283 //=======================================================================
285 TopOpeBRepDS_Transition TopOpeBRep_FaceEdgeIntersector::Transition
286 (const Standard_Integer Index,
287 const TopAbs_Orientation FaceOrientation) const
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);
297 TopAbs_State stB, stA;
299 const IntCurveSurface_IntersectionPoint& IP = mySequenceOfPnt(myPointIndex);
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;
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);
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;
327 TopAbs_ShapeEnum onB = TopAbs_FACE, onA = TopAbs_FACE;
328 TopOpeBRepDS_Transition TR;
329 TR.Set(stB,stA,onB,onA);
333 else Standard_ProgramError::Raise("FEINT Transition Index");
335 // return(TopOpeBRepDS_Transition());
336 TopOpeBRepDS_Transition aValRet ;
340 //=======================================================================
341 //function : IsVertex
343 //=======================================================================
345 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::IsVertex
346 (const TopoDS_Shape& S, const gp_Pnt& P,
347 const Standard_Real Tol, TopoDS_Vertex& VR)
349 Standard_Boolean isv = Standard_False;
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;
368 //=======================================================================
369 //function : IsVertex
371 //=======================================================================
373 Standard_Boolean TopOpeBRep_FaceEdgeIntersector::IsVertex
374 (const Standard_Integer I, TopoDS_Vertex& VR)
376 Standard_Boolean isv = Standard_False;
378 if (I == 1) isv = IsVertex(myFace,P,myTol,VR);
379 else if (I == 2) isv = IsVertex(myEdge,P,myTol,VR);
383 //=======================================================================
386 //=======================================================================
388 Standard_Integer TopOpeBRep_FaceEdgeIntersector::Index() const
398 //=======================================================================
399 //function : ShapeTolerances
400 //purpose : (private)
401 //=======================================================================
403 void TopOpeBRep_FaceEdgeIntersector::ShapeTolerances(const TopoDS_Shape& S1,
404 const TopoDS_Shape& S2)
406 myTol = Max(ToleranceMax(S1,TopAbs_EDGE),ToleranceMax(S2,TopAbs_EDGE));
407 myForceTolerance = Standard_False;
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;
418 //=======================================================================
419 //function : ToleranceMax
420 //purpose : (private)
421 //=======================================================================
423 Standard_Real TopOpeBRep_FaceEdgeIntersector::ToleranceMax
424 (const TopoDS_Shape& S,
425 const TopAbs_ShapeEnum T)const
427 TopExp_Explorer e(S,T);
428 if ( ! e.More() ) return Precision::Intersection();
430 Standard_Real tol = RealFirst();
431 for (; e.More(); e.Next())
432 tol = Max(tol,TopOpeBRepTool_ShapeTool::Tolerance(e.Current()));