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