0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / TopOpeBRep / TopOpeBRep_EdgesIntersector_1.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
7fd59977 17
42cf5bc1 18#include <Bnd_Box.hxx>
7fd59977 19#include <BRep_Tool.hxx>
42cf5bc1 20#include <BRepAdaptor_HSurface.hxx>
21#include <BRepAdaptor_Surface.hxx>
22#include <Geom2dAdaptor_Curve.hxx>
23#include <gp_Pnt.hxx>
24#include <gp_Pnt2d.hxx>
25#include <IntRes2d_IntersectionPoint.hxx>
26#include <IntRes2d_IntersectionSegment.hxx>
7fd59977 27#include <Precision.hxx>
42cf5bc1 28#include <Standard_Failure.hxx>
29#include <TCollection_AsciiString.hxx>
7fd59977 30#include <TopExp.hxx>
31#include <TopExp_Explorer.hxx>
42cf5bc1 32#include <TopoDS.hxx>
33#include <TopoDS_Shape.hxx>
7fd59977 34#include <TopOpeBRep_define.hxx>
42cf5bc1 35#include <TopOpeBRep_EdgesIntersector.hxx>
36#include <TopOpeBRep_Point2d.hxx>
37#include <TopOpeBRepDS_Transition.hxx>
38#include <TopOpeBRepTool_ShapeTool.hxx>
7fd59977 39
40//=======================================================================
41//function : Segment1
42//purpose :
43//=======================================================================
44const IntRes2d_IntersectionSegment& TopOpeBRep_EdgesIntersector::Segment1() const
45{
46 if ( ! IsPointOfSegment1() )
9775fa61 47 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Not a segment point");
7fd59977 48 Standard_Integer iseg = 1 + (myPointIndex - myNbPoints - 1) / 2;
49 return mylseg.Value(iseg);
50}
51
52//=======================================================================
53//function : IsOpposite1
54//purpose :
55//=======================================================================
56Standard_Boolean TopOpeBRep_EdgesIntersector::IsOpposite1() const
57{
58 Standard_Boolean b = Segment1().IsOpposite();
59 return b;
60}
61
62//=======================================================================
63//function : InitPoint1
64//purpose :
65//=======================================================================
66void TopOpeBRep_EdgesIntersector::InitPoint1()
67{
68 myPointIndex = 1;
69 myIsVertexPointIndex = 0;
70 myIsVertexIndex = 0;
71 myIsVertexValue = Standard_False;
72}
73
74//=======================================================================
75//function : MorePoint1
76//purpose :
77//=======================================================================
78Standard_Boolean TopOpeBRep_EdgesIntersector::MorePoint1() const
79{
80 return myPointIndex <= myTrueNbPoints;
81}
82
83//=======================================================================
84//function : NextPoint1
85//purpose :
86//=======================================================================
87void TopOpeBRep_EdgesIntersector::NextPoint1()
88{
89 myPointIndex++;
90}
91
92//=======================================================================
93//function : Point1
94//purpose :
95//=======================================================================
96const IntRes2d_IntersectionPoint& TopOpeBRep_EdgesIntersector::Point1() const
97{
98 if ( ! IsPointOfSegment1() ) { // point is an intersection point
99 return mylpnt.Value(myPointIndex);
100 }
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();
105 }
106}
107
108//=======================================================================
109//function : Status1
110//purpose :
111//=======================================================================
112TopOpeBRep_P2Dstatus TopOpeBRep_EdgesIntersector::Status1() const
113{
114 if ( ! IsPointOfSegment1() ) { // point is an intersection point
115 return TopOpeBRep_P2DINT;
116 }
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;
121 }
122}
123
124//=======================================================================
125//function : IsPointOfSegment1
126//purpose :
127//=======================================================================
128Standard_Boolean TopOpeBRep_EdgesIntersector::IsPointOfSegment1() const
129{
130 Standard_Boolean b = (myPointIndex > myNbPoints);
131 return b;
132}
133
134//=======================================================================
135//function : Index1
136//purpose :
137//=======================================================================
138Standard_Integer TopOpeBRep_EdgesIntersector::Index1() const
139{
140 return myPointIndex;
141}
142
143//=======================================================================
144//function : EdgesConfig1
145//purpose :
146//=======================================================================
147TopOpeBRepDS_Config TopOpeBRep_EdgesIntersector::EdgesConfig1() const
148{
149 TopOpeBRepDS_Config c = TopOpeBRepDS_UNSHGEOMETRY;
150 Standard_Boolean ps = IsPointOfSegment1();
151 if ( ps ) {
152 Standard_Boolean so;
153 so = TopOpeBRepTool_ShapeTool::EdgesSameOriented(myEdge2,myEdge1);
154 c = (so) ? TopOpeBRepDS_SAMEORIENTED : TopOpeBRepDS_DIFFORIENTED;
155 }
156 return c;
157}
158
159//=======================================================================
160//function : Transition1
161//purpose :
162//=======================================================================
163TopOpeBRepDS_Transition TopOpeBRep_EdgesIntersector::Transition1(const Standard_Integer Index,const TopAbs_Orientation EdgeOrientation) const
164{
165 Standard_Boolean pointofsegment = IsPointOfSegment1();
166 Standard_Boolean pur1d = (pointofsegment && mySameDomain);
167
7fd59977 168 TopAbs_State staB=TopAbs_UNKNOWN,staA=TopAbs_UNKNOWN;
169 TopAbs_ShapeEnum shaB=TopAbs_COMPOUND,shaA=TopAbs_COMPOUND; Standard_Boolean pextremity;
7fd59977 170
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; }
176
177 if ( (EdgeOrientation == TopAbs_INTERNAL) ||
178 (EdgeOrientation == TopAbs_EXTERNAL) ) {
179 TopOpeBRepDS_Transition TR(staINON,staINON,shaB,shaA);
180 TR.Set(EdgeOrientation);
181 return TR;
182 }
183
184 pextremity = Standard_False; // JYL290998 corr regr cto100K1 fex6 fex4 : 5eme inters E/E
185
186 const IntRes2d_IntersectionPoint& IP = Point1();
187 const IntRes2d_Transition& T = (Index == 1) ?
188 IP.TransitionOfFirst() : IP.TransitionOfSecond();
189
190 switch (T.TransitionType()) {
191
192 case IntRes2d_In :
193 staB = TopAbs_OUT;
194 staA = staINON;
195 break;
196
197 case IntRes2d_Out :
198 staB = staINON;
199 staA = TopAbs_OUT;
200 break;
201
202 case IntRes2d_Touch :
203 switch (T.Situation()) {
204
205 case IntRes2d_Inside :
206 staB = staINON;
207 staA = staINON;
208 break;
209
210 case IntRes2d_Outside :
211 staB = TopAbs_OUT;
212 staA = TopAbs_OUT;
213 break;
214
215 case IntRes2d_Unknown : {
216
217 // get posindex = position on of point on edge <Index>
218 IntRes2d_Position posindex =
219 (Index == 1) ?
220 IP.TransitionOfFirst().PositionOnCurve() :
221 IP.TransitionOfSecond().PositionOnCurve();
222
223 if (pointofsegment) {
224
225 // get posother = position of point on the other edge
226 IntRes2d_Position posother =
227 (Index == 1) ?
228 IP.TransitionOfSecond().PositionOnCurve() :
229 IP.TransitionOfFirst().PositionOnCurve();
230
231 if (posother == IntRes2d_Middle) {
232 if (posindex != IntRes2d_Middle) {
233 staB = staINON;
234 staA = staINON;
235 }
236 else // Middle/Middle is impossible
9775fa61 237 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Situation Unknown MM");
7fd59977 238 }
239 else { // posother = Head or End
240 Standard_Boolean opposite = IsOpposite1();
241 if (opposite) {
242 if (posother == IntRes2d_Head) {
243 staB = staINON;
244 staA = TopAbs_OUT;
245 }
246 else if (posother == IntRes2d_End) {
247 staB = TopAbs_OUT;
248 staA = staINON;
249 }
250 }
251 else {
252 if (posother == IntRes2d_Head) {
253 staB = TopAbs_OUT;
254 staA = staINON;
255 }
256 else if (posother == IntRes2d_End) {
257 staB = staINON;
258 staA = TopAbs_OUT;
259 }
260 }
261 }
262 } // point is a segment point
263
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;
270
271 if ( posindex == IntRes2d_Head ) {
272 staB = staINON;
273 staA = TopAbs_OUT;
274 }
275 else if (posindex == IntRes2d_End) {
276 staB = TopAbs_OUT;
277 staA = staINON;
278 }
279 else { // Middle is impossible
9775fa61 280 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Situation Unknown M");
7fd59977 281 }
282 } // point is not a segment point
283
284 } // T.Situation == IntRes2d_Unknown
285 break;
286
287 } // switch T.Situation()
288 break;
289
290 case IntRes2d_Undecided :
9775fa61 291 throw Standard_Failure("TopOpeBRep_EdgesIntersector : TransitionType Undecided");
7fd59977 292 break;
293
294 } // switch TransitionType()
295
296 TopOpeBRepDS_Transition TR;
297 if (pur1d || pextremity) {
298 TR.Set(staB,staA,shaB,shaA);
299 }
300 else { // +ooOO
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
306 // la 2eme face.
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;
315 if (composori) {
316 eori = TopAbs::Reverse(eori);
317 }
318
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();
324 }
325 }
326 return TR;
327}
328
329//=======================================================================
330//function : Parameter1
331//purpose :
332//=======================================================================
333Standard_Real TopOpeBRep_EdgesIntersector::Parameter1(const Standard_Integer Index) const
334{
335 if (Index == 1) return Point1().ParamOnFirst();
336 else return Point1().ParamOnSecond();
337}
338
339//=======================================================================
340//function : IsVertex1
341//purpose :
342//=======================================================================
343Standard_Boolean TopOpeBRep_EdgesIntersector::IsVertex1(const Standard_Integer Index)
344{
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;
350
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();
356
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;
364 TopExp_Explorer ex;
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;
373 break;
374 }
375 }
376 }
377 }
378 else { // pos = head or end
379 TopoDS_Vertex V1,V2;
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;
385 }
386 else if ( pos == IntRes2d_End && !V2.IsNull()) {
387 myIsVertexValue = Standard_True;
388 myIsVertexVertex = V2;
389 }
390 // ... else myIsVertexValue has been set to False
391 }
392
393 // memorize that IsVertex1() has been called :
394 // - on point myPointIndex
395 // - on edge <Index>
396 myIsVertexPointIndex = myPointIndex;
397 myIsVertexIndex = Index;
398
399 return myIsVertexValue;
400}
401
402
403//=======================================================================
404//function : Vertex1
405//purpose :
406//=======================================================================
407const TopoDS_Shape& TopOpeBRep_EdgesIntersector::Vertex1(const Standard_Integer Index)
408{
409 if ( ! IsVertex1(Index) )
9775fa61 410 throw Standard_Failure("TopOpeBRep_EdgesIntersector : Vertex1");
7fd59977 411 return myIsVertexVertex;
412}
413
414//=======================================================================
415//function : Value1
416//purpose :
417//=======================================================================
418gp_Pnt TopOpeBRep_EdgesIntersector::Value1() const
419{
420 gp_Pnt2d p2 = Point1().Value();
421 gp_Pnt p;
422 if (Precision::IsInfinite(p2.X()) || Precision::IsInfinite(p2.Y())) {
423 Standard_Real inf = Precision::Infinite();
424 p.SetCoord (inf, inf, inf);
425 }
426 else
427 mySurface1->Surface().D0(p2.X(),p2.Y(), p);
428 return p;
429}