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