Integration of OCCT 6.5.0 from SVN
[occt.git] / src / IntRes2d / IntRes2d_Intersection.cxx
CommitLineData
7fd59977 1// File: IntRes2d_Intersection.cxx
2// Created: Tue Apr 28 10:21:36 1992
3// Author: Laurent BUCHARD
4// <lbr@topsn3>
5
6
7#include <IntRes2d_Intersection.ixx>
8
9#include <StdFail_NotDone.hxx>
10#include <Standard_OutOfRange.hxx>
11#include <IntRes2d_SequenceOfIntersectionPoint.hxx>
12#include <IntRes2d_SequenceOfIntersectionSegment.hxx>
13#include <IntRes2d_Position.hxx>
14
15
16#define PARAMEQUAL(a,b) (Abs((a)-(b))< (1e-8))
17
18
19static void InternalVerifyPosition(IntRes2d_Transition& T1,
20 IntRes2d_Transition& T2,
21 const Standard_Real PParamOnFirst,
22 const Standard_Real PParamOnSecond,
23 const Standard_Real FirstParam1,
24 const Standard_Real LastParam1,
25 const Standard_Real FirstParam2,
26 const Standard_Real LastParam2);
27
28
29
30//----------------------------------------------------------------------
31static Standard_Boolean TransitionEqual( const IntRes2d_Transition& T1
32 ,const IntRes2d_Transition& T2);
33
34
35Standard_Boolean TransitionEqual( const IntRes2d_Transition& T1
36 ,const IntRes2d_Transition& T2) {
37
38 if(T1.PositionOnCurve() == T2.PositionOnCurve()) {
39 if(T1.TransitionType() == T2.TransitionType()) {
40 if(T1.TransitionType() == IntRes2d_Touch) {
41 if(T1.IsTangent()==T2.IsTangent()) {
42 if(T1.Situation() == T2.Situation()) {
43 if(T1.IsOpposite() == T2.IsOpposite()) {
44 return(Standard_True);
45 }
46 }
47 }
48 }
49 else {
50 return(Standard_True);
51 }
52 }
53 }
54 return(Standard_False);
55}
56
57
58
59void IntRes2d_Intersection::Insert(const IntRes2d_IntersectionPoint& Pnt) {
60 Standard_Integer n = lpnt.Length();
61 if(n==0) {
62 lpnt.Append(Pnt);
63 }
64 else {
65 Standard_Real u = Pnt.ParamOnFirst();
66 Standard_Integer i = 1;
67 Standard_Integer b = n+1;
68 while(i<=n) {
69 const IntRes2d_IntersectionPoint& Pnti=lpnt(i);
70 Standard_Real ui = Pnti.ParamOnFirst();
71 if(ui >= u) { b=i; i=n; }
72 if(PARAMEQUAL(ui,u)) {
73 if(PARAMEQUAL((Pnt.ParamOnSecond()),(Pnti.ParamOnSecond()))) {
74 if( (TransitionEqual(Pnt.TransitionOfFirst(),Pnti.TransitionOfFirst()))
75 && (TransitionEqual(Pnt.TransitionOfSecond(),Pnti.TransitionOfSecond()))) {
76 b=0;
77 i=n;
78 }
79 }
80 }
81 //----------------------------------------------------------------
82
83 i++;
84 }
85 if(b>n) { lpnt.Append(Pnt); }
86 else if(b>0) { lpnt.InsertBefore(b,Pnt); }
87 }
88}
89
90void IntRes2d_Intersection::SetValues(const IntRes2d_Intersection& Other) {
91 Standard_Integer i ;
92 if(Other.done) {
93 lseg.Clear();
94 lpnt.Clear();
95 Standard_Integer N = Other.lpnt.Length();
96 for( i=1; i<= N ; i++) {
97 lpnt.Append(Other.lpnt(i));
98 }
99 N = Other.lseg.Length();
100 for(i=1; i<= N ; i++) {
101 lseg.Append(Other.lseg(i));
102 }
103 //-----------------------
104 //lpnt=Other.lpnt; Pose des problemes
105 //lseg=Other.lseg; pour des objets composites
106 //-----------------------
107 done=Standard_True;
108 }
109 else {
110 done=Standard_False;
111 }
112}
113
114//----------------------------------------------------------------------
115//-- Function used to Merge the results of two Intersections .
116//-- for Composite Curves only. FirstParam and LastParam are the
117//-- parameter of the bounds of the composite Curve
118//-- Merge of two Intersection Segments S1 and S2 when :
119//--
120//-- S1 : U1First,PosU1Fisrt --> U1Last,PosU1Last
121//-- V1First,PosV1Fisrt --> V1Last,PosV1Last
122//-- S2 : U2First,PosU2Fisrt --> U2Last,PosU2Last
123//-- V2First,PosV2Fisrt --> V2Last,PosV2Last
124//--
125//-- 1 U : X------1-------E H-----2-------X U -->
126//-- V : X------1-------X X-----2-------X <- V -> ?
127//--
128//-- PosU1Last == End && PosU2First == Head
129//-- && U1Last == U2First
130//-- && V1Last == V2First
131//--
132//-- OR
133//--
134//-- 2 U : X------1-------H E-----2-------X U <--
135//-- V : X------1-------X X-----2-------X <- V -> ?
136//--
137//-- PosU1Last == Head && PosU2First == End
138//-- && U1Last == U2First
139//-- && V1Last == V2First
140//--
141//-- merge the two Segment in :
142//--
143//-- U : X------1----------2-------X U
144//-- V : X------1----------2-------X <- V -> ?
145//--
146//--
147//--
148//-- The Position of Intersection Point is set to Middle
149//-- when the Parameters U et V are between FirstParam1, EndParam1
150//-- and FirstParam2, EndParam2
151//--
152void IntRes2d_Intersection::Append( const IntRes2d_Intersection& Other
153 ,const Standard_Real FirstParam1
154 ,const Standard_Real LastParam1
155 ,const Standard_Real FirstParam2
156 ,const Standard_Real LastParam2) {
157
158
159 if(Other.done) {
160 //-- Verification of the Position of the IntersectionPoints
161 Standard_Integer n=Other.lpnt.Length();
162 Standard_Integer i ;
163 for( i=1; i<=n ; i++) {
164
165 const IntRes2d_IntersectionPoint& P=Other.lpnt(i);
166 Standard_Real PParamOnFirst=P.ParamOnFirst();
167 Standard_Real PParamOnSecond=P.ParamOnSecond();
168 IntRes2d_Transition T1=P.TransitionOfFirst();
169 IntRes2d_Transition T2=P.TransitionOfSecond();
170 gp_Pnt2d Pt=P.Value();
171
172
173 InternalVerifyPosition(T1,T2
174 ,PParamOnFirst,PParamOnSecond
175 ,FirstParam1,LastParam1
176 ,FirstParam2,LastParam2);
177
178 this->Insert(IntRes2d_IntersectionPoint(Pt,
179 PParamOnFirst,
180 PParamOnSecond,
181 T1,T2,
182 Standard_False));
183 }
184
185 //--------------------------------------------------
186 //-- IntersectionSegment
187 //-- (we assume that a composite curve is always bounded)
188 //-- (a segment has always a FirstPoint and a LastPoint)
189 //--------------------------------------------------
190 n=Other.lseg.Length();
191 Standard_Real SegModif_P1First=0,SegModif_P1Second=0;
192 Standard_Real SegModif_P2First=0,SegModif_P2Second=0;
193
194 for(i=1; i<=n ; i++) {
195
196 const IntRes2d_IntersectionPoint& P1=Other.lseg(i).FirstPoint();
197
198 Standard_Real P1PParamOnFirst=P1.ParamOnFirst();
199 Standard_Real P1PParamOnSecond=P1.ParamOnSecond();
200 IntRes2d_Transition P1T1=P1.TransitionOfFirst();
201 IntRes2d_Transition P1T2=P1.TransitionOfSecond();
202 const gp_Pnt2d& P1Pt=P1.Value();
203
204 InternalVerifyPosition(P1T1,P1T2
205 ,P1PParamOnFirst,P1PParamOnSecond
206 ,FirstParam1,LastParam1
207 ,FirstParam2,LastParam2);
208
209 const IntRes2d_IntersectionPoint& P2=Other.lseg(i).LastPoint();
210
211 Standard_Real P2PParamOnFirst=P2.ParamOnFirst();
212 Standard_Real P2PParamOnSecond=P2.ParamOnSecond();
213 IntRes2d_Transition P2T1=P2.TransitionOfFirst();
214 IntRes2d_Transition P2T2=P2.TransitionOfSecond();
215 const gp_Pnt2d& P2Pt=P2.Value();
216
217 Standard_Boolean Opposite=Other.lseg(i).IsOpposite();
218
219 InternalVerifyPosition(P2T1,P2T2
220 ,P2PParamOnFirst,P2PParamOnSecond
221 ,FirstParam1,LastParam1
222 ,FirstParam2,LastParam2);
223
224
225
226 //-- Loop on the previous segments
227 //--
228 Standard_Integer an=lseg.Length();
229 Standard_Boolean NotYetModified=Standard_True;
230
231 for(Standard_Integer j=1;(j<=an)&&(NotYetModified);j++) {
232
233 const IntRes2d_IntersectionPoint& AnP1=lseg(j).FirstPoint();
234 Standard_Real AnP1PParamOnFirst=AnP1.ParamOnFirst();
235 Standard_Real AnP1PParamOnSecond=AnP1.ParamOnSecond();
236#if DEB
237 const IntRes2d_Transition& AnP1T1=AnP1.TransitionOfFirst();
238#else
239 AnP1.TransitionOfFirst();
240#endif
241#if DEB
242 const IntRes2d_Transition& AnP1T2=AnP1.TransitionOfSecond();
243#else
244 AnP1.TransitionOfSecond();
245#endif
246#if DEB
247 const gp_Pnt2d& AnPt1=AnP1.Value();
248#else
249 AnP1.Value();
250#endif
251
252 const IntRes2d_IntersectionPoint& AnP2=lseg(j).LastPoint();
253 Standard_Real AnP2PParamOnFirst=AnP2.ParamOnFirst();
254 Standard_Real AnP2PParamOnSecond=AnP2.ParamOnSecond();
255#if DEB
256 const IntRes2d_Transition& AnP2T1=AnP2.TransitionOfFirst();
257#else
258 AnP2.TransitionOfFirst();
259#endif
260#if DEB
261 const IntRes2d_Transition& AnP2T2=AnP2.TransitionOfSecond();
262#else
263 AnP2.TransitionOfSecond();
264#endif
265#if DEB
266 const gp_Pnt2d& AnPt2=AnP2.Value();
267#else
268 AnP2.Value();
269#endif
270
271
272 if(Opposite == lseg(j).IsOpposite()) {
273 //---------------------------------------------------------------
274 //-- AnP1---------AnP2
275 //-- P1-------------P2
276 //--
277 if( PARAMEQUAL(P1PParamOnFirst,AnP2PParamOnFirst)
278 &&PARAMEQUAL(P1PParamOnSecond,AnP2PParamOnSecond)) {
279 NotYetModified=Standard_False;
280 lseg(j)=IntRes2d_IntersectionSegment(AnP1,P2,
281 Opposite,Standard_False);
282 SegModif_P1First = AnP1PParamOnFirst;
283 SegModif_P1Second = AnP1PParamOnSecond;
284 SegModif_P2First = P2PParamOnFirst;
285 SegModif_P2Second = P2PParamOnSecond;
286 }
287 //---------------------------------------------------------------
288 //-- AnP1---------AnP2
289 //-- P1-------------P2
290 //--
291 else if( PARAMEQUAL(P2PParamOnFirst,AnP1PParamOnFirst)
292 &&PARAMEQUAL(P2PParamOnSecond,AnP1PParamOnSecond)) {
293 NotYetModified=Standard_False;
294 lseg(j)=IntRes2d_IntersectionSegment(P1,AnP2,
295 Opposite,Standard_False);
296 SegModif_P1First = P1PParamOnFirst;
297 SegModif_P1Second = P1PParamOnSecond;
298 SegModif_P2First = AnP2PParamOnFirst;
299 SegModif_P2Second = AnP2PParamOnSecond;
300 }
301 //---------------------------------------------------------------
302 //-- AnP2---------AnP1
303 //-- P1-------------P2
304 //--
305 if( PARAMEQUAL(P1PParamOnFirst,AnP1PParamOnFirst)
306 &&PARAMEQUAL(P1PParamOnSecond,AnP1PParamOnSecond)) {
307 NotYetModified=Standard_False;
308 lseg(j)=IntRes2d_IntersectionSegment(AnP2,P2,
309 Opposite,Standard_False);
310 SegModif_P1First = P2PParamOnFirst;
311 SegModif_P1Second = P2PParamOnSecond;
312 SegModif_P2First = AnP2PParamOnFirst;
313 SegModif_P2Second = AnP2PParamOnSecond;
314 }
315 //---------------------------------------------------------------
316 //-- AnP2---------AnP1
317 //-- P1-------------P2
318 //--
319 else if( PARAMEQUAL(P2PParamOnFirst,AnP2PParamOnFirst)
320 &&PARAMEQUAL(P2PParamOnSecond,AnP2PParamOnSecond)) {
321 NotYetModified=Standard_False;
322 lseg(j)=IntRes2d_IntersectionSegment(P1,AnP1,
323 Opposite,Standard_False);
324 SegModif_P1First = P1PParamOnFirst;
325 SegModif_P1Second = P1PParamOnSecond;
326 SegModif_P2First = AnP1PParamOnFirst;
327 SegModif_P2Second = AnP1PParamOnSecond;
328 }
329 }
330 }
331 if(NotYetModified) {
332 this->Append(IntRes2d_IntersectionSegment(
333 IntRes2d_IntersectionPoint(P1Pt,
334 P1PParamOnFirst,
335 P1PParamOnSecond,
336 P1T1,P1T2,
337 Standard_False),
338 IntRes2d_IntersectionPoint(P2Pt,
339 P2PParamOnFirst,
340 P2PParamOnSecond,
341 P2T1,P2T2,
342 Standard_False),
343 Opposite,Standard_False));
344
345 } //-- if(NotYetModified)
346 else {
347 //--------------------------------------------------------------
348 //-- Are some Existing Points in this segment ?
349 //--------------------------------------------------------------
350 Standard_Integer rnbpts=lpnt.Length();
351 for(Standard_Integer rp=1; (rp<=rnbpts)&&(rp>=1); rp++) {
352 Standard_Real PonFirst=lpnt(rp).ParamOnFirst();
353 Standard_Real PonSecond=lpnt(rp).ParamOnSecond();
354
355 if( ((PonFirst >= SegModif_P1First && PonFirst <= SegModif_P2First)
356 ||(PonFirst <= SegModif_P1First && PonFirst >= SegModif_P2First))
357 && ((PonSecond >= SegModif_P1Second && PonSecond <= SegModif_P2Second)
358 ||(PonSecond<= SegModif_P1Second && PonSecond >= SegModif_P2Second))) {
359 lpnt.Remove(rp);
360 rp--;
361 rnbpts--;
362 }
363 } //-- for(Standard_Integer rp=1; (rp<=rnbpts)&&(rp>=1); rp++)
364 }
365 }
366 //--------------------------------------------------
367 //-- Remove some Points ?
368 //-- Example : Points which lie in a segment.
369 //--------------------------------------------------
370
371 done=Standard_True;
372 }
373 else {
374 done=Standard_False;
375 }
376}
377
378
379//----------------------------------------------------------------------
380//--
381#define DEBUGPOSITION 0
382
383#if DEBUGPOSITION
384void AffPosition(IntRes2d_Transition& T,const Standard_Real u,const char *Texte);
385void AffPosition(IntRes2d_Transition& T,const Standard_Real u,const char *Texte) {
386 if(T.PositionOnCurve() == IntRes2d_End) { cout <<Texte<<" Param :"<<u<<" End "<<endl; }
387 if(T.PositionOnCurve() == IntRes2d_Middle) { cout <<Texte<<" Param :"<<u<<" Middle "<<endl; }
388 if(T.PositionOnCurve() == IntRes2d_Head) { cout <<Texte<<" Param :"<<u<<" Head "<<endl; }
389}
390#endif
391
392void InternalVerifyPosition(IntRes2d_Transition& T1,
393 IntRes2d_Transition& T2,
394 const Standard_Real PParamOnFirst,
395 const Standard_Real PParamOnSecond,
396 const Standard_Real FirstParam1,
397 const Standard_Real LastParam1,
398 const Standard_Real FirstParam2,
399 const Standard_Real LastParam2) {
400#if DEBUGPOSITION
401AffPosition(T1,PParamOnFirst," Point 1 ");
402AffPosition(T2,PParamOnSecond," Point 2 ");
403#endif
404 if(T1.PositionOnCurve() != IntRes2d_Middle) {
405 if(!( PARAMEQUAL(PParamOnFirst,FirstParam1)
406 || PARAMEQUAL(PParamOnFirst,LastParam1))) {
407 //-- Middle on the Curve 1
408
409 // modified by NIZHNY-MKK Tue Nov 26 14:23:24 2002.BEGIN
410 if((PParamOnFirst > FirstParam1) && (PParamOnFirst < LastParam1))
411 // modified by NIZHNY-MKK Tue Nov 26 14:23:27 2002.END
412 T1.SetPosition(IntRes2d_Middle);
413 }
414 }
415 if(T2.PositionOnCurve() != IntRes2d_Middle) {
416 if(!( PARAMEQUAL(PParamOnSecond,FirstParam2)
417 || PARAMEQUAL(PParamOnSecond,LastParam2))) {
418
419 // modified by NIZHNY-MKK Tue Nov 26 14:24:15 2002.BEGIN
420 if((PParamOnSecond > FirstParam2) && (PParamOnSecond < LastParam2))
421 // modified by NIZHNY-MKK Tue Nov 26 14:24:19 2002.END
422 T2.SetPosition(IntRes2d_Middle);
423 }
424 }
425}
426//----------------------------------------------------------------------
427
428
429
430
431
432
433
434#if 0
435~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
436#define Debug(q) cout<<"IntRes2d_Intersection"<<"q ="<<q<<endl;
437
438char *DebugPos(const IntRes2d_Position P);
439
440Debug(FirstParam1);
441Debug(LastParam1);
442Debug(FirstParam2);
443Debug(LastParam2);
444Debug(PParamOnFirst);
445Debug(PParamOnSecond);
446cout<<" ##### T1 <> Middle ###### "<<DebugPos(T1.PositionOnCurve())<<endl;
447char *DebugPos(const IntRes2d_Position P) {
448 if(P==IntRes2d_Middle) return(" Middle ");
449 if(P==IntRes2d_Head) return(" Head ");
450 if(P==IntRes2d_End) return(" End ");
451}
452~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
453#endif
454