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 <Bnd_Box.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_HSurface.hxx>
21 #include <BRepAdaptor_Surface.hxx>
22 #include <Geom2dAdaptor_Curve.hxx>
24 #include <gp_Pnt2d.hxx>
25 #include <IntRes2d_IntersectionPoint.hxx>
26 #include <IntRes2d_IntersectionSegment.hxx>
27 #include <Precision.hxx>
28 #include <Standard_Failure.hxx>
29 #include <TCollection_AsciiString.hxx>
31 #include <TopExp_Explorer.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <TopOpeBRep_define.hxx>
35 #include <TopOpeBRep_EdgesIntersector.hxx>
36 #include <TopOpeBRep_Point2d.hxx>
37 #include <TopOpeBRepDS_Transition.hxx>
38 #include <TopOpeBRepTool_ShapeTool.hxx>
40 //=======================================================================
43 //=======================================================================
44 const IntRes2d_IntersectionSegment& TopOpeBRep_EdgesIntersector::Segment1() const
46 if ( ! IsPointOfSegment1() )
47 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Not a segment point");
48 Standard_Integer iseg = 1 + (myPointIndex - myNbPoints - 1) / 2;
49 return mylseg.Value(iseg);
52 //=======================================================================
53 //function : IsOpposite1
55 //=======================================================================
56 Standard_Boolean TopOpeBRep_EdgesIntersector::IsOpposite1() const
58 Standard_Boolean b = Segment1().IsOpposite();
62 //=======================================================================
63 //function : InitPoint1
65 //=======================================================================
66 void TopOpeBRep_EdgesIntersector::InitPoint1()
69 myIsVertexPointIndex = 0;
71 myIsVertexValue = Standard_False;
74 //=======================================================================
75 //function : MorePoint1
77 //=======================================================================
78 Standard_Boolean TopOpeBRep_EdgesIntersector::MorePoint1() const
80 return myPointIndex <= myTrueNbPoints;
83 //=======================================================================
84 //function : NextPoint1
86 //=======================================================================
87 void TopOpeBRep_EdgesIntersector::NextPoint1()
92 //=======================================================================
95 //=======================================================================
96 const IntRes2d_IntersectionPoint& TopOpeBRep_EdgesIntersector::Point1() const
98 if ( ! IsPointOfSegment1() ) { // point is an intersection point
99 return mylpnt.Value(myPointIndex);
101 else { // point is a point of segment
102 Standard_Integer i = myPointIndex - myNbPoints - 1;
103 if (i % 2 == 0) return Segment1().FirstPoint();
104 else return Segment1().LastPoint();
108 //=======================================================================
111 //=======================================================================
112 TopOpeBRep_P2Dstatus TopOpeBRep_EdgesIntersector::Status1() const
114 if ( ! IsPointOfSegment1() ) { // point is an intersection point
115 return TopOpeBRep_P2DINT;
117 else { // point is a point of segment
118 Standard_Integer i = myPointIndex - myNbPoints - 1;
119 if (i % 2 == 0) return TopOpeBRep_P2DSGF;
120 else return TopOpeBRep_P2DSGL;
124 //=======================================================================
125 //function : IsPointOfSegment1
127 //=======================================================================
128 Standard_Boolean TopOpeBRep_EdgesIntersector::IsPointOfSegment1() const
130 Standard_Boolean b = (myPointIndex > myNbPoints);
134 //=======================================================================
137 //=======================================================================
138 Standard_Integer TopOpeBRep_EdgesIntersector::Index1() const
143 //=======================================================================
144 //function : EdgesConfig1
146 //=======================================================================
147 TopOpeBRepDS_Config TopOpeBRep_EdgesIntersector::EdgesConfig1() const
149 TopOpeBRepDS_Config c = TopOpeBRepDS_UNSHGEOMETRY;
150 Standard_Boolean ps = IsPointOfSegment1();
153 so = TopOpeBRepTool_ShapeTool::EdgesSameOriented(myEdge2,myEdge1);
154 c = (so) ? TopOpeBRepDS_SAMEORIENTED : TopOpeBRepDS_DIFFORIENTED;
159 //=======================================================================
160 //function : Transition1
162 //=======================================================================
163 TopOpeBRepDS_Transition TopOpeBRep_EdgesIntersector::Transition1(const Standard_Integer Index,const TopAbs_Orientation EdgeOrientation) const
165 Standard_Boolean pointofsegment = IsPointOfSegment1();
166 Standard_Boolean pur1d = (pointofsegment && mySameDomain);
168 TopAbs_State staB=TopAbs_UNKNOWN,staA=TopAbs_UNKNOWN;
169 TopAbs_ShapeEnum shaB=TopAbs_COMPOUND,shaA=TopAbs_COMPOUND; Standard_Boolean pextremity;
171 TopAbs_State staINON = TopAbs_IN;
172 Standard_Integer dim = myDimension;
173 if (dim == 1) { shaA = shaB = TopAbs_EDGE; }
174 else if (dim == 2 && pur1d) { shaA = shaB = TopAbs_EDGE; }
175 else if (dim == 2 && !pur1d) { shaA = shaB = TopAbs_FACE; }
177 if ( (EdgeOrientation == TopAbs_INTERNAL) ||
178 (EdgeOrientation == TopAbs_EXTERNAL) ) {
179 TopOpeBRepDS_Transition TR(staINON,staINON,shaB,shaA);
180 TR.Set(EdgeOrientation);
184 pextremity = Standard_False; // JYL290998 corr regr cto100K1 fex6 fex4 : 5eme inters E/E
186 const IntRes2d_IntersectionPoint& IP = Point1();
187 const IntRes2d_Transition& T = (Index == 1) ?
188 IP.TransitionOfFirst() : IP.TransitionOfSecond();
190 switch (T.TransitionType()) {
202 case IntRes2d_Touch :
203 switch (T.Situation()) {
205 case IntRes2d_Inside :
210 case IntRes2d_Outside :
215 case IntRes2d_Unknown : {
217 // get posindex = position on of point on edge <Index>
218 IntRes2d_Position posindex =
220 IP.TransitionOfFirst().PositionOnCurve() :
221 IP.TransitionOfSecond().PositionOnCurve();
223 if (pointofsegment) {
225 // get posother = position of point on the other edge
226 IntRes2d_Position posother =
228 IP.TransitionOfSecond().PositionOnCurve() :
229 IP.TransitionOfFirst().PositionOnCurve();
231 if (posother == IntRes2d_Middle) {
232 if (posindex != IntRes2d_Middle) {
236 else // Middle/Middle is impossible
237 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Situation Unknown MM");
239 else { // posother = Head or End
240 Standard_Boolean opposite = IsOpposite1();
242 if (posother == IntRes2d_Head) {
246 else if (posother == IntRes2d_End) {
252 if (posother == IntRes2d_Head) {
256 else if (posother == IntRes2d_End) {
262 } // point is a segment point
264 else { // point is not a segment point
265 // two edges intersect on a vertex
266 // the vertex is shared by the two edges
267 // the edges are tangent on vertex.
268 pextremity = Standard_True;
269 shaA = shaB = TopAbs_EDGE;
271 if ( posindex == IntRes2d_Head ) {
275 else if (posindex == IntRes2d_End) {
279 else { // Middle is impossible
280 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Situation Unknown M");
282 } // point is not a segment point
284 } // T.Situation == IntRes2d_Unknown
287 } // switch T.Situation()
290 case IntRes2d_Undecided :
291 throw Standard_Failure("TopOpeBRep_EdgesIntersector : TransitionType Undecided");
294 } // switch TransitionType()
296 TopOpeBRepDS_Transition TR;
297 if (pur1d || pextremity) {
298 TR.Set(staB,staA,shaB,shaA);
301 Standard_Boolean composori = Standard_False;
302 composori = composori || ((Index == 1) && (!myf2surf1F_sameoriented));
303 composori = composori || ((Index == 2) && (!myf1surf1F_sameoriented));
304 // Index = 1 <==> on demande la transition sur
305 // une arete de la 1ere face par rapport a une arete orientee de
307 // EdgeOrientation est l'orientation d'une arete de la 2eme face
308 // de l'appel SetFaces(), i.e ume arete de la face dont la surface
309 // n'est PAS la surface de reference de l'intersecteur 2d.
310 // Cette orientation d'arete dans la face doit etre composee avec
311 // l'orientation relative de la topologie de la 2eme face par rapport
312 // a la topologie de la 1ere face orientee FORWARD (car la
313 // geometrie naturelle de la 1ere face est la reference).
314 TopAbs_Orientation eori = EdgeOrientation;
316 eori = TopAbs::Reverse(eori);
319 // retournement des etats en fonction de l'orientation de l'arete
320 // croisee dans l'espace geometrique de reference.
321 TR.Set(staB,staA,shaB,shaA);
322 if (eori == TopAbs_REVERSED) {
323 TR = TR.Complement();
329 //=======================================================================
330 //function : Parameter1
332 //=======================================================================
333 Standard_Real TopOpeBRep_EdgesIntersector::Parameter1(const Standard_Integer Index) const
335 if (Index == 1) return Point1().ParamOnFirst();
336 else return Point1().ParamOnSecond();
339 //=======================================================================
340 //function : IsVertex1
342 //=======================================================================
343 Standard_Boolean TopOpeBRep_EdgesIntersector::IsVertex1(const Standard_Integer Index)
345 // check if last IsVertex1() call has been performed
346 // on current point and with same <Index>.
347 if ( myIsVertexPointIndex == myPointIndex &&
348 myIsVertexIndex == Index )
349 return myIsVertexValue;
351 // search if current point is a vertex of edge <Index>
352 myIsVertexValue = Standard_False;
353 IntRes2d_Position pos;
354 if (Index == 1) pos = Point1().TransitionOfFirst().PositionOnCurve();
355 else pos = Point1().TransitionOfSecond().PositionOnCurve();
357 if ( pos == IntRes2d_Middle ) {
358 // search for an INTERNAL vertex on edge <Index> with
359 // a 2d parameter <parV> equal to current point parameter <par>
360 Standard_Real par = Parameter1(Index);
361 const TopoDS_Edge *pE = NULL;
362 pE = (Index == 1) ? &myEdge1 : &myEdge2;
363 const TopoDS_Edge& E = *pE;
365 for (ex.Init(E,TopAbs_VERTEX); ex.More(); ex.Next()) {
366 // for (TopExp_Explorer ex(E,TopAbs_VERTEX); ex.More(); ex.Next()) {
367 const TopoDS_Vertex& V = TopoDS::Vertex(ex.Current());
368 if ( V.Orientation() == TopAbs_INTERNAL) {
369 Standard_Real parV = BRep_Tool::Parameter(V,E,myFace1);
370 if (Abs(par-parV) <= Precision::PConfusion()) {
371 myIsVertexValue = Standard_True;
372 myIsVertexVertex = V;
378 else { // pos = head or end
380 if (Index == 1) TopExp::Vertices(myEdge1,V1,V2);
381 else TopExp::Vertices(myEdge2,V1,V2);
382 if ( pos == IntRes2d_Head && !V1.IsNull()) {
383 myIsVertexValue = Standard_True;
384 myIsVertexVertex = V1;
386 else if ( pos == IntRes2d_End && !V2.IsNull()) {
387 myIsVertexValue = Standard_True;
388 myIsVertexVertex = V2;
390 // ... else myIsVertexValue has been set to False
393 // memorize that IsVertex1() has been called :
394 // - on point myPointIndex
396 myIsVertexPointIndex = myPointIndex;
397 myIsVertexIndex = Index;
399 return myIsVertexValue;
403 //=======================================================================
406 //=======================================================================
407 const TopoDS_Shape& TopOpeBRep_EdgesIntersector::Vertex1(const Standard_Integer Index)
409 if ( ! IsVertex1(Index) )
410 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Vertex1");
411 return myIsVertexVertex;
414 //=======================================================================
417 //=======================================================================
418 gp_Pnt TopOpeBRep_EdgesIntersector::Value1() const
420 gp_Pnt2d p2 = Point1().Value();
422 if (Precision::IsInfinite(p2.X()) || Precision::IsInfinite(p2.Y())) {
423 Standard_Real inf = Precision::Infinite();
424 p.SetCoord (inf, inf, inf);
427 mySurface1->Surface().D0(p2.X(),p2.Y(), p);