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 | |
19 | static 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 | //---------------------------------------------------------------------- |
31 | static Standard_Boolean TransitionEqual( const IntRes2d_Transition& T1 |
32 | ,const IntRes2d_Transition& T2); |
33 | |
34 | |
35 | Standard_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 | |
59 | void 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 | |
90 | void 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 | //-- |
152 | void 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 |
384 | void AffPosition(IntRes2d_Transition& T,const Standard_Real u,const char *Texte); |
385 | void 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 | |
392 | void 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 |
401 | AffPosition(T1,PParamOnFirst," Point 1 "); |
402 | AffPosition(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 | |
438 | char *DebugPos(const IntRes2d_Position P); |
439 | |
440 | Debug(FirstParam1); |
441 | Debug(LastParam1); |
442 | Debug(FirstParam2); |
443 | Debug(LastParam2); |
444 | Debug(PParamOnFirst); |
445 | Debug(PParamOnSecond); |
446 | cout<<" ##### T1 <> Middle ###### "<<DebugPos(T1.PositionOnCurve())<<endl; |
447 | char *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 | |