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 <Bnd_Box.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <Geom2dAdaptor_Curve.hxx>
22 #include <gp_Pnt.hxx>
23 #include <gp_Pnt2d.hxx>
24 #include <IntRes2d_IntersectionPoint.hxx>
25 #include <IntRes2d_IntersectionSegment.hxx>
26 #include <Precision.hxx>
27 #include <Standard_Failure.hxx>
28 #include <TCollection_AsciiString.hxx>
29 #include <TopExp.hxx>
30 #include <TopExp_Explorer.hxx>
31 #include <TopoDS.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopOpeBRep_define.hxx>
34 #include <TopOpeBRep_EdgesIntersector.hxx>
35 #include <TopOpeBRep_Point2d.hxx>
36 #include <TopOpeBRepDS_Transition.hxx>
37 #include <TopOpeBRepTool_ShapeTool.hxx>
38
39 //=======================================================================
40 //function : Segment1
41 //purpose :
42 //=======================================================================
Segment1() const43 const IntRes2d_IntersectionSegment& TopOpeBRep_EdgesIntersector::Segment1() const
44 {
45 if ( ! IsPointOfSegment1() )
46 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Not a segment point");
47 Standard_Integer iseg = 1 + (myPointIndex - myNbPoints - 1) / 2;
48 return mylseg.Value(iseg);
49 }
50
51 //=======================================================================
52 //function : IsOpposite1
53 //purpose :
54 //=======================================================================
IsOpposite1() const55 Standard_Boolean TopOpeBRep_EdgesIntersector::IsOpposite1() const
56 {
57 Standard_Boolean b = Segment1().IsOpposite();
58 return b;
59 }
60
61 //=======================================================================
62 //function : InitPoint1
63 //purpose :
64 //=======================================================================
InitPoint1()65 void TopOpeBRep_EdgesIntersector::InitPoint1()
66 {
67 myPointIndex = 1;
68 myIsVertexPointIndex = 0;
69 myIsVertexIndex = 0;
70 myIsVertexValue = Standard_False;
71 }
72
73 //=======================================================================
74 //function : MorePoint1
75 //purpose :
76 //=======================================================================
MorePoint1() const77 Standard_Boolean TopOpeBRep_EdgesIntersector::MorePoint1() const
78 {
79 return myPointIndex <= myTrueNbPoints;
80 }
81
82 //=======================================================================
83 //function : NextPoint1
84 //purpose :
85 //=======================================================================
NextPoint1()86 void TopOpeBRep_EdgesIntersector::NextPoint1()
87 {
88 myPointIndex++;
89 }
90
91 //=======================================================================
92 //function : Point1
93 //purpose :
94 //=======================================================================
Point1() const95 const IntRes2d_IntersectionPoint& TopOpeBRep_EdgesIntersector::Point1() const
96 {
97 if ( ! IsPointOfSegment1() ) { // point is an intersection point
98 return mylpnt.Value(myPointIndex);
99 }
100 else { // point is a point of segment
101 Standard_Integer i = myPointIndex - myNbPoints - 1;
102 if (i % 2 == 0) return Segment1().FirstPoint();
103 else return Segment1().LastPoint();
104 }
105 }
106
107 //=======================================================================
108 //function : Status1
109 //purpose :
110 //=======================================================================
Status1() const111 TopOpeBRep_P2Dstatus TopOpeBRep_EdgesIntersector::Status1() const
112 {
113 if ( ! IsPointOfSegment1() ) { // point is an intersection point
114 return TopOpeBRep_P2DINT;
115 }
116 else { // point is a point of segment
117 Standard_Integer i = myPointIndex - myNbPoints - 1;
118 if (i % 2 == 0) return TopOpeBRep_P2DSGF;
119 else return TopOpeBRep_P2DSGL;
120 }
121 }
122
123 //=======================================================================
124 //function : IsPointOfSegment1
125 //purpose :
126 //=======================================================================
IsPointOfSegment1() const127 Standard_Boolean TopOpeBRep_EdgesIntersector::IsPointOfSegment1() const
128 {
129 Standard_Boolean b = (myPointIndex > myNbPoints);
130 return b;
131 }
132
133 //=======================================================================
134 //function : Index1
135 //purpose :
136 //=======================================================================
Index1() const137 Standard_Integer TopOpeBRep_EdgesIntersector::Index1() const
138 {
139 return myPointIndex;
140 }
141
142 //=======================================================================
143 //function : EdgesConfig1
144 //purpose :
145 //=======================================================================
EdgesConfig1() const146 TopOpeBRepDS_Config TopOpeBRep_EdgesIntersector::EdgesConfig1() const
147 {
148 TopOpeBRepDS_Config c = TopOpeBRepDS_UNSHGEOMETRY;
149 Standard_Boolean ps = IsPointOfSegment1();
150 if ( ps ) {
151 Standard_Boolean so;
152 so = TopOpeBRepTool_ShapeTool::EdgesSameOriented(myEdge2,myEdge1);
153 c = (so) ? TopOpeBRepDS_SAMEORIENTED : TopOpeBRepDS_DIFFORIENTED;
154 }
155 return c;
156 }
157
158 //=======================================================================
159 //function : Transition1
160 //purpose :
161 //=======================================================================
Transition1(const Standard_Integer Index,const TopAbs_Orientation EdgeOrientation) const162 TopOpeBRepDS_Transition TopOpeBRep_EdgesIntersector::Transition1(const Standard_Integer Index,const TopAbs_Orientation EdgeOrientation) const
163 {
164 Standard_Boolean pointofsegment = IsPointOfSegment1();
165 Standard_Boolean pur1d = (pointofsegment && mySameDomain);
166
167 TopAbs_State staB=TopAbs_UNKNOWN,staA=TopAbs_UNKNOWN;
168 TopAbs_ShapeEnum shaB=TopAbs_COMPOUND,shaA=TopAbs_COMPOUND; Standard_Boolean pextremity;
169
170 TopAbs_State staINON = TopAbs_IN;
171 Standard_Integer dim = myDimension;
172 if (dim == 1) { shaA = shaB = TopAbs_EDGE; }
173 else if (dim == 2 && pur1d) { shaA = shaB = TopAbs_EDGE; }
174 else if (dim == 2 && !pur1d) { shaA = shaB = TopAbs_FACE; }
175
176 if ( (EdgeOrientation == TopAbs_INTERNAL) ||
177 (EdgeOrientation == TopAbs_EXTERNAL) ) {
178 TopOpeBRepDS_Transition TR(staINON,staINON,shaB,shaA);
179 TR.Set(EdgeOrientation);
180 return TR;
181 }
182
183 pextremity = Standard_False; // JYL290998 corr regr cto100K1 fex6 fex4 : 5eme inters E/E
184
185 const IntRes2d_IntersectionPoint& IP = Point1();
186 const IntRes2d_Transition& T = (Index == 1) ?
187 IP.TransitionOfFirst() : IP.TransitionOfSecond();
188
189 switch (T.TransitionType()) {
190
191 case IntRes2d_In :
192 staB = TopAbs_OUT;
193 staA = staINON;
194 break;
195
196 case IntRes2d_Out :
197 staB = staINON;
198 staA = TopAbs_OUT;
199 break;
200
201 case IntRes2d_Touch :
202 switch (T.Situation()) {
203
204 case IntRes2d_Inside :
205 staB = staINON;
206 staA = staINON;
207 break;
208
209 case IntRes2d_Outside :
210 staB = TopAbs_OUT;
211 staA = TopAbs_OUT;
212 break;
213
214 case IntRes2d_Unknown : {
215
216 // get posindex = position on of point on edge <Index>
217 IntRes2d_Position posindex =
218 (Index == 1) ?
219 IP.TransitionOfFirst().PositionOnCurve() :
220 IP.TransitionOfSecond().PositionOnCurve();
221
222 if (pointofsegment) {
223
224 // get posother = position of point on the other edge
225 IntRes2d_Position posother =
226 (Index == 1) ?
227 IP.TransitionOfSecond().PositionOnCurve() :
228 IP.TransitionOfFirst().PositionOnCurve();
229
230 if (posother == IntRes2d_Middle) {
231 if (posindex != IntRes2d_Middle) {
232 staB = staINON;
233 staA = staINON;
234 }
235 else // Middle/Middle is impossible
236 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Situation Unknown MM");
237 }
238 else { // posother = Head or End
239 Standard_Boolean opposite = IsOpposite1();
240 if (opposite) {
241 if (posother == IntRes2d_Head) {
242 staB = staINON;
243 staA = TopAbs_OUT;
244 }
245 else if (posother == IntRes2d_End) {
246 staB = TopAbs_OUT;
247 staA = staINON;
248 }
249 }
250 else {
251 if (posother == IntRes2d_Head) {
252 staB = TopAbs_OUT;
253 staA = staINON;
254 }
255 else if (posother == IntRes2d_End) {
256 staB = staINON;
257 staA = TopAbs_OUT;
258 }
259 }
260 }
261 } // point is a segment point
262
263 else { // point is not a segment point
264 // two edges intersect on a vertex
265 // the vertex is shared by the two edges
266 // the edges are tangent on vertex.
267 pextremity = Standard_True;
268 shaA = shaB = TopAbs_EDGE;
269
270 if ( posindex == IntRes2d_Head ) {
271 staB = staINON;
272 staA = TopAbs_OUT;
273 }
274 else if (posindex == IntRes2d_End) {
275 staB = TopAbs_OUT;
276 staA = staINON;
277 }
278 else { // Middle is impossible
279 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Situation Unknown M");
280 }
281 } // point is not a segment point
282
283 } // T.Situation == IntRes2d_Unknown
284 break;
285
286 } // switch T.Situation()
287 break;
288
289 case IntRes2d_Undecided :
290 throw Standard_Failure("TopOpeBRep_EdgesIntersector : TransitionType Undecided");
291 break;
292
293 } // switch TransitionType()
294
295 TopOpeBRepDS_Transition TR;
296 if (pur1d || pextremity) {
297 TR.Set(staB,staA,shaB,shaA);
298 }
299 else { // +ooOO
300 Standard_Boolean composori = Standard_False;
301 composori = composori || ((Index == 1) && (!myf2surf1F_sameoriented));
302 composori = composori || ((Index == 2) && (!myf1surf1F_sameoriented));
303 // Index = 1 <==> on demande la transition sur
304 // une arete de la 1ere face par rapport a une arete orientee de
305 // la 2eme face.
306 // EdgeOrientation est l'orientation d'une arete de la 2eme face
307 // de l'appel SetFaces(), i.e ume arete de la face dont la surface
308 // n'est PAS la surface de reference de l'intersecteur 2d.
309 // Cette orientation d'arete dans la face doit etre composee avec
310 // l'orientation relative de la topologie de la 2eme face par rapport
311 // a la topologie de la 1ere face orientee FORWARD (car la
312 // geometrie naturelle de la 1ere face est la reference).
313 TopAbs_Orientation eori = EdgeOrientation;
314 if (composori) {
315 eori = TopAbs::Reverse(eori);
316 }
317
318 // retournement des etats en fonction de l'orientation de l'arete
319 // croisee dans l'espace geometrique de reference.
320 TR.Set(staB,staA,shaB,shaA);
321 if (eori == TopAbs_REVERSED) {
322 TR = TR.Complement();
323 }
324 }
325 return TR;
326 }
327
328 //=======================================================================
329 //function : Parameter1
330 //purpose :
331 //=======================================================================
Parameter1(const Standard_Integer Index) const332 Standard_Real TopOpeBRep_EdgesIntersector::Parameter1(const Standard_Integer Index) const
333 {
334 if (Index == 1) return Point1().ParamOnFirst();
335 else return Point1().ParamOnSecond();
336 }
337
338 //=======================================================================
339 //function : IsVertex1
340 //purpose :
341 //=======================================================================
IsVertex1(const Standard_Integer Index)342 Standard_Boolean TopOpeBRep_EdgesIntersector::IsVertex1(const Standard_Integer Index)
343 {
344 // check if last IsVertex1() call has been performed
345 // on current point and with same <Index>.
346 if ( myIsVertexPointIndex == myPointIndex &&
347 myIsVertexIndex == Index )
348 return myIsVertexValue;
349
350 // search if current point is a vertex of edge <Index>
351 myIsVertexValue = Standard_False;
352 IntRes2d_Position pos;
353 if (Index == 1) pos = Point1().TransitionOfFirst().PositionOnCurve();
354 else pos = Point1().TransitionOfSecond().PositionOnCurve();
355
356 if ( pos == IntRes2d_Middle ) {
357 // search for an INTERNAL vertex on edge <Index> with
358 // a 2d parameter <parV> equal to current point parameter <par>
359 Standard_Real par = Parameter1(Index);
360 const TopoDS_Edge *pE = NULL;
361 pE = (Index == 1) ? &myEdge1 : &myEdge2;
362 const TopoDS_Edge& E = *pE;
363 TopExp_Explorer ex;
364 for (ex.Init(E,TopAbs_VERTEX); ex.More(); ex.Next()) {
365 // for (TopExp_Explorer ex(E,TopAbs_VERTEX); ex.More(); ex.Next()) {
366 const TopoDS_Vertex& V = TopoDS::Vertex(ex.Current());
367 if ( V.Orientation() == TopAbs_INTERNAL) {
368 Standard_Real parV = BRep_Tool::Parameter(V,E,myFace1);
369 if (Abs(par-parV) <= Precision::PConfusion()) {
370 myIsVertexValue = Standard_True;
371 myIsVertexVertex = V;
372 break;
373 }
374 }
375 }
376 }
377 else { // pos = head or end
378 TopoDS_Vertex V1,V2;
379 if (Index == 1) TopExp::Vertices(myEdge1,V1,V2);
380 else TopExp::Vertices(myEdge2,V1,V2);
381 if ( pos == IntRes2d_Head && !V1.IsNull()) {
382 myIsVertexValue = Standard_True;
383 myIsVertexVertex = V1;
384 }
385 else if ( pos == IntRes2d_End && !V2.IsNull()) {
386 myIsVertexValue = Standard_True;
387 myIsVertexVertex = V2;
388 }
389 // ... else myIsVertexValue has been set to False
390 }
391
392 // memorize that IsVertex1() has been called :
393 // - on point myPointIndex
394 // - on edge <Index>
395 myIsVertexPointIndex = myPointIndex;
396 myIsVertexIndex = Index;
397
398 return myIsVertexValue;
399 }
400
401
402 //=======================================================================
403 //function : Vertex1
404 //purpose :
405 //=======================================================================
Vertex1(const Standard_Integer Index)406 const TopoDS_Shape& TopOpeBRep_EdgesIntersector::Vertex1(const Standard_Integer Index)
407 {
408 if ( ! IsVertex1(Index) )
409 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Vertex1");
410 return myIsVertexVertex;
411 }
412
413 //=======================================================================
414 //function : Value1
415 //purpose :
416 //=======================================================================
Value1() const417 gp_Pnt TopOpeBRep_EdgesIntersector::Value1() const
418 {
419 gp_Pnt2d p2 = Point1().Value();
420 gp_Pnt p;
421 if (Precision::IsInfinite(p2.X()) || Precision::IsInfinite(p2.Y())) {
422 Standard_Real inf = Precision::Infinite();
423 p.SetCoord (inf, inf, inf);
424 }
425 else
426 mySurface1->Surface().D0(p2.X(),p2.Y(), p);
427 return p;
428 }
429