0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / TopOpeBRep / TopOpeBRep_FaceEdgeIntersector.cxx
CommitLineData
b311480e 1// Created on: 1994-10-07
2// Created by: Jean Yves LEBEY
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
42cf5bc1 17
7fd59977 18#include <BRep_Tool.hxx>
42cf5bc1 19#include <BRepIntCurveSurface_Inter.hxx>
7fd59977 20#include <Geom_Curve.hxx>
42cf5bc1 21#include <gp_Pnt.hxx>
22#include <gp_Pnt2d.hxx>
7fd59977 23#include <IntCurveSurface_IntersectionPoint.hxx>
24#include <IntCurveSurface_TransitionOnCurve.hxx>
7fd59977 25#include <Precision.hxx>
26#include <Standard_ProgramError.hxx>
42cf5bc1 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>
7fd59977 35
0797d9d3 36#ifdef OCCT_DEBUG
7fd59977 37#include <TopAbs.hxx>
1d0a9d4d 38extern Standard_Boolean TopOpeBRep_GettraceFITOL();
39extern Standard_Boolean TopOpeBRep_GettraceSAVFF();
7fd59977 40#include <TCollection_AsciiString.hxx>
41#include <Standard_CString.hxx>
42#include <BRepTools.hxx>
43static 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}
1d0a9d4d 50extern Standard_Boolean TopOpeBRepTool_GettraceKRO();
7fd59977 51#include <TopOpeBRepTool_KRO.hxx>
52Standard_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
71void 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
85void 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));
0797d9d3 91#ifdef OCCT_DEBUG
7fd59977 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
0797d9d3 98#ifdef OCCT_DEBUG
7fd59977 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
7fd59977 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
0797d9d3 111#ifdef OCCT_DEBUG
7fd59977 112 if (TopOpeBRepTool_GettraceKRO()) KRO_DSFILLER_INTFE.Start();
113#endif
114
115 BRepIntCurveSurface_Inter FEINT;
116 FEINT.Init(myFace,myCurve,myTol);
117
0797d9d3 118#ifdef OCCT_DEBUG
7fd59977 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
139Standard_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
151const 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;
9775fa61 156 else throw Standard_ProgramError("TopOpeBRep_FaceEdgeIntersector::Shape");
7fd59977 157}
158
159//=======================================================================
160//function : ForceTolerance
161//purpose :
162//=======================================================================
163
164void TopOpeBRep_FaceEdgeIntersector::ForceTolerance(const Standard_Real Tol)
165{
166 myTol = Tol;
167 myForceTolerance = Standard_True;
168
0797d9d3 169#ifdef OCCT_DEBUG
7fd59977 170 if (TopOpeBRep_GettraceFITOL())
171 cout<<"ForceTolerance : myTol = "<<myTol<<endl;
172#endif
173}
174
175//=======================================================================
176//function : Tolerance
177//purpose :
178//=======================================================================
179
180Standard_Real TopOpeBRep_FaceEdgeIntersector::Tolerance() const
181{
182 return myTol;
183}
184
185//=======================================================================
186//function : NbPoints
187//purpose :
188//=======================================================================
189
190Standard_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
202void TopOpeBRep_FaceEdgeIntersector::InitPoint()
203{
204 myPointIndex = 1;
205}
206
207//=======================================================================
208//function : MorePoint
209//purpose :
210//=======================================================================
211
212Standard_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
223void TopOpeBRep_FaceEdgeIntersector::NextPoint()
224{
225 myPointIndex++;
226}
227
228//=======================================================================
229//function : Value
230//purpose :
231//=======================================================================
232
233gp_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
246Standard_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
258void 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
271TopAbs_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
283TopOpeBRepDS_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
9775fa61 331 else throw Standard_ProgramError("FEINT Transition Index");
7fd59977 332}
333
334//=======================================================================
335//function : IsVertex
336//purpose :
337//=======================================================================
338
339Standard_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
367Standard_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
382Standard_Integer TopOpeBRep_FaceEdgeIntersector::Index() const
383{
0797d9d3 384#ifdef OCCT_DEBUG
7fd59977 385 return myPointIndex;
386#else
387 return 0;
388#endif
389}
390
391
392//=======================================================================
393//function : ShapeTolerances
394//purpose : (private)
395//=======================================================================
396
397void 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
0797d9d3 403#ifdef OCCT_DEBUG
7fd59977 404 if (TopOpeBRep_GettraceFITOL()) {
405 cout<<"ShapeTolerances on S1 = ";TopAbs::Print(S1.ShapeType(),cout);
406 cout<<" S2 = ";TopAbs::Print(S2.ShapeType(),cout);
407 cout<<" : myTol = "<<myTol<<endl;
408 }
409#endif
410}
411
412//=======================================================================
413//function : ToleranceMax
414//purpose : (private)
415//=======================================================================
416
417Standard_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}