Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1991-06-24 |
2 | // Created by: Didier PIFFAULT | |
3 | // Copyright (c) -1999 Matra Datavision | |
4 | // Copyright (c) 1991-1999 Matra Datavision | |
5 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
6 | // | |
7 | // The content of this file is subject to the Open CASCADE Technology Public | |
8 | // License Version 6.5 (the "License"). You may not use the content of this file | |
9 | // except in compliance with the License. Please obtain a copy of the License | |
10 | // at http://www.opencascade.org and read it completely before using this file. | |
11 | // | |
12 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
13 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
14 | // | |
15 | // The Original Code and all software distributed under the License is | |
16 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
17 | // Initial Developer hereby disclaims all such warranties, including without | |
18 | // limitation, any warranties of merchantability, fitness for a particular | |
19 | // purpose or non-infringement. Please see the License for the specific terms | |
20 | // and conditions governing the rights and limitations under the License. | |
21 | ||
9530af27 | 22 | |
23 | #include <Intf_InterferencePolygon2d.ixx> | |
24 | ||
25 | #include <gp_Pnt2d.hxx> | |
26 | #include <Bnd_Box2d.hxx> | |
27 | #include <Intf_SectionPoint.hxx> | |
28 | #include <Intf_SeqOfSectionPoint.hxx> | |
29 | #include <Intf_TangentZone.hxx> | |
30 | #include <Intf_SeqOfTangentZone.hxx> | |
31 | #include <Precision.hxx> | |
32 | #include <TColStd_ListOfInteger.hxx> | |
33 | ||
34 | // Angular precision (sinus) below that value two right segments | |
35 | // are considered as having a potential zone of tangency. | |
36 | namespace | |
37 | { | |
38 | static const Standard_Real PRCANG = Precision::Angular(); | |
39 | }; | |
40 | ||
41 | //======================================================================= | |
42 | //function : Intf_InterferencePolygon2d | |
43 | //purpose : constructor empty | |
44 | //======================================================================= | |
45 | ||
46 | Intf_InterferencePolygon2d::Intf_InterferencePolygon2d() | |
47 | : Intf_Interference (Standard_False), | |
48 | oClos (Standard_False), | |
49 | tClos (Standard_False), | |
50 | nbso (0) | |
51 | {} | |
52 | ||
53 | //======================================================================= | |
54 | //function : Intf_InterferencePolygon2d | |
55 | //purpose : Constructor of the interference beetween two Polygon. | |
56 | //======================================================================= | |
57 | ||
58 | Intf_InterferencePolygon2d::Intf_InterferencePolygon2d | |
59 | (const Intf_Polygon2d& Obje1, const Intf_Polygon2d& Obje2) | |
60 | : Intf_Interference (Standard_False), | |
61 | oClos (Standard_False), | |
62 | tClos (Standard_False), | |
63 | nbso (0) | |
64 | { | |
65 | if (!Obje1.Bounding().IsOut(Obje2.Bounding())) { | |
66 | Tolerance=Obje1.DeflectionOverEstimation()+ | |
67 | Obje2.DeflectionOverEstimation(); | |
68 | if (Tolerance==0.) | |
69 | Tolerance=Epsilon(1000.); | |
70 | nbso=Obje1.NbSegments(); | |
71 | oClos=Obje1.Closed(); | |
72 | tClos=Obje2.Closed(); | |
73 | Interference(Obje1, Obje2); | |
74 | Clean(); | |
75 | } | |
76 | } | |
77 | ||
78 | ||
79 | //======================================================================= | |
80 | //function : Intf_InterferencePolygon2d | |
81 | //purpose : Constructor of the auto interference of a Polygon. | |
82 | //======================================================================= | |
83 | ||
84 | Intf_InterferencePolygon2d::Intf_InterferencePolygon2d | |
85 | (const Intf_Polygon2d& Obje) | |
86 | : Intf_Interference (Standard_True), | |
87 | oClos (Standard_False), | |
88 | tClos (Standard_False), | |
89 | nbso (0) | |
90 | { | |
91 | Tolerance=Obje.DeflectionOverEstimation()*2; | |
92 | if (Tolerance==0.) | |
93 | Tolerance=Epsilon(1000.); | |
94 | oClos=Obje.Closed(); | |
95 | tClos=oClos; | |
96 | Interference(Obje); | |
97 | Clean(); | |
98 | } | |
99 | ||
100 | //======================================================================= | |
101 | //function : Perform | |
102 | //purpose : | |
103 | //======================================================================= | |
104 | ||
105 | void Intf_InterferencePolygon2d::Perform | |
106 | (const Intf_Polygon2d& Obje1, const Intf_Polygon2d& Obje2) | |
107 | { | |
108 | SelfInterference(Standard_False); | |
109 | if (!Obje1.Bounding().IsOut(Obje2.Bounding())) { | |
110 | Tolerance=Obje1.DeflectionOverEstimation()+ | |
111 | Obje2.DeflectionOverEstimation(); | |
112 | if (Tolerance==0.) | |
113 | Tolerance=Epsilon(1000.); | |
114 | nbso=Obje1.NbSegments(); | |
115 | oClos=Obje1.Closed(); | |
116 | tClos=Obje2.Closed(); | |
117 | Interference(Obje1, Obje2); | |
118 | Clean(); | |
119 | } | |
120 | } | |
121 | ||
122 | //======================================================================= | |
123 | //function : Perform | |
124 | //purpose : | |
125 | //======================================================================= | |
126 | ||
127 | void Intf_InterferencePolygon2d::Perform | |
128 | (const Intf_Polygon2d& Obje) | |
129 | { | |
130 | SelfInterference(Standard_True); | |
131 | Tolerance=Obje.DeflectionOverEstimation()*2; | |
132 | if (Tolerance==0.) | |
133 | Tolerance=Epsilon(1000.); | |
134 | oClos=Obje.Closed(); | |
135 | tClos=oClos; | |
136 | Interference(Obje); | |
137 | Clean(); | |
138 | } | |
139 | ||
140 | //======================================================================= | |
141 | //function : Pnt2dValue | |
142 | //purpose : Give the section point of range Index in the interference. | |
143 | //======================================================================= | |
144 | ||
145 | gp_Pnt2d Intf_InterferencePolygon2d::Pnt2dValue | |
146 | (const Standard_Integer Index) const | |
147 | { | |
148 | return gp_Pnt2d((mySPoins(Index)).Pnt().X(), | |
149 | (mySPoins(Index)).Pnt().Y()); | |
150 | } | |
151 | ||
152 | ||
153 | //======================================================================= | |
154 | //function : Interference | |
155 | //purpose : | |
156 | //======================================================================= | |
157 | ||
158 | void Intf_InterferencePolygon2d::Interference | |
159 | (const Intf_Polygon2d& Obje1, | |
160 | const Intf_Polygon2d& Obje2) | |
161 | { | |
162 | Bnd_Box2d bSO; | |
163 | Bnd_Box2d bST; | |
164 | ||
96a85238 RL |
165 | Standard_Integer iObje1, iObje2, n1 = nbso, n2 = Obje2.NbSegments(); |
166 | Standard_Real d1 = Obje1.DeflectionOverEstimation(), | |
167 | d2 = Obje2.DeflectionOverEstimation(); | |
9530af27 | 168 | |
169 | gp_Pnt2d p1b, p1e, p2b, p2e; | |
96a85238 | 170 | for (iObje1=1; iObje1<=n1; iObje1++) |
9530af27 | 171 | { |
172 | bSO.SetVoid(); | |
173 | Obje1.Segment(iObje1,p1b,p1e); | |
174 | bSO.Add(p1b); | |
175 | bSO.Add(p1e); | |
96a85238 | 176 | bSO.Enlarge(d1); |
9530af27 | 177 | if (!Obje2.Bounding().IsOut(bSO)) { |
96a85238 | 178 | for (iObje2=1; iObje2<=n2; iObje2++) { |
9530af27 | 179 | bST.SetVoid(); |
180 | Obje2.Segment(iObje2,p2b,p2e); | |
181 | bST.Add(p2b); | |
182 | bST.Add(p2e); | |
96a85238 | 183 | bST.Enlarge(d2); |
9530af27 | 184 | if (!bSO.IsOut(bST)) |
185 | Intersect(iObje1, iObje2, p1b, p1e, p2b, p2e); | |
186 | } | |
187 | } | |
188 | } | |
189 | } | |
190 | ||
191 | //======================================================================= | |
192 | //function : Interference | |
193 | //purpose : | |
194 | //======================================================================= | |
195 | ||
196 | void Intf_InterferencePolygon2d::Interference | |
197 | (const Intf_Polygon2d& Obje) | |
198 | { | |
199 | Bnd_Box2d bSO; | |
200 | Bnd_Box2d bST; | |
201 | ||
96a85238 RL |
202 | Standard_Integer iObje1, iObje2, n = Obje.NbSegments(); |
203 | Standard_Real d = Obje.DeflectionOverEstimation(); | |
9530af27 | 204 | |
205 | gp_Pnt2d p1b, p1e, p2b, p2e; | |
96a85238 | 206 | for (iObje1=1; iObje1<=n; iObje1++) { |
9530af27 | 207 | bSO.SetVoid(); |
208 | Obje.Segment(iObje1,p1b,p1e); | |
209 | bSO.Add(p1b); | |
210 | bSO.Add(p1e); | |
96a85238 | 211 | bSO.Enlarge(d); |
9530af27 | 212 | if (!Obje.Bounding().IsOut(bSO)) { |
96a85238 | 213 | for (iObje2=iObje1+1;iObje2<=n;iObje2++){ |
9530af27 | 214 | bST.SetVoid(); |
215 | Obje.Segment(iObje2,p2b,p2e); | |
216 | bST.Add(p2b); | |
217 | bST.Add(p2e); | |
96a85238 | 218 | bST.Enlarge(d); |
9530af27 | 219 | if (!bSO.IsOut(bST)) |
220 | Intersect(iObje1, iObje2, p1b, p1e, p2b, p2e); | |
221 | } | |
222 | } | |
223 | } | |
224 | } | |
225 | ||
226 | ||
227 | //======================================================================= | |
228 | //function : Clean | |
229 | //purpose : | |
230 | //======================================================================= | |
231 | ||
232 | void Intf_InterferencePolygon2d::Clean() | |
233 | { | |
234 | ||
235 | // The zones of tangency that concerns only one couple of segments are | |
236 | // conserved if the angle between the segments is less than <PRCANG> and | |
237 | // if there is no real point of intersection EDGE/EDGE: | |
238 | Standard_Integer nbIt=myTZones.Length(); | |
239 | Standard_Integer decal=0; | |
240 | Standard_Integer addr1, addr2; | |
241 | Intf_PIType dim1, dim2; | |
242 | Standard_Real par; | |
243 | Standard_Integer tsp, tsps; | |
244 | Standard_Integer lpi, ltz; | |
245 | Standard_Boolean Only1Seg=Standard_False; | |
246 | ||
247 | #define PI1 (myTZones(ltz-decal).GetPoint(lpi)) | |
248 | #define PI2 (myTZones(ltz-decal).GetPoint(tsp)) | |
249 | ||
250 | for (ltz=1; ltz<=nbIt; ltz++) { | |
251 | tsp=tsps=0; | |
252 | Standard_Real pr1mi,pr1ma,pr2mi,pr2ma,delta1,delta2; | |
253 | myTZones(ltz-decal).ParamOnFirst(pr1mi,pr1ma); | |
254 | delta1=pr1ma-pr1mi; | |
255 | myTZones(ltz-decal).ParamOnSecond(pr2mi,pr2ma); | |
256 | delta2=pr2ma-pr2mi; | |
257 | if (delta1<1. && delta2<1.) Only1Seg=Standard_True; | |
258 | if (delta1==0. || delta2==0.) Only1Seg=Standard_True; | |
259 | ||
260 | for (lpi=1; lpi<=myTZones(ltz-decal).NumberOfPoints(); lpi++) { | |
261 | if (PI1.Incidence()<=PRCANG) {tsp=tsps=0;break;} | |
262 | PI1.InfoFirst(dim1,addr1,par); | |
263 | PI1.InfoSecond(dim2,addr2,par); | |
264 | if (dim1==Intf_EDGE && dim2==Intf_EDGE) { | |
265 | tsps=0; | |
266 | if (tsp>0) { | |
267 | tsp=0; | |
268 | Only1Seg=Standard_False; | |
269 | break; | |
270 | } | |
271 | tsp=lpi; | |
272 | } | |
273 | else if (dim1!=Intf_EXTERNAL && dim2!=Intf_EXTERNAL) { | |
274 | tsps=lpi; | |
275 | } | |
276 | } | |
277 | if (tsp>0) { | |
278 | mySPoins.Append(myTZones(ltz-decal).GetPoint(tsp)); | |
279 | myTZones.Remove(ltz-decal); | |
280 | decal++; | |
281 | } | |
282 | else if (Only1Seg && tsps!=0) { | |
283 | mySPoins.Append(myTZones(ltz-decal).GetPoint(tsps)); | |
284 | myTZones.Remove(ltz-decal); | |
285 | decal++; | |
286 | } | |
287 | } | |
288 | ||
289 | ||
290 | // The points of intersection located in the tangency zone are | |
291 | // removed from the list : | |
292 | nbIt=mySPoins.Length(); | |
293 | decal=0; | |
294 | ||
295 | for (lpi=1; lpi<=nbIt; lpi++) { | |
296 | for (ltz=1; ltz<=myTZones.Length(); ltz++) { | |
297 | if (myTZones(ltz).RangeContains(mySPoins(lpi-decal))) { | |
298 | mySPoins.Remove(lpi-decal); | |
299 | decal++; | |
300 | break; | |
301 | } | |
302 | } | |
303 | } | |
304 | } | |
305 | ||
306 | ||
307 | //======================================================================= | |
308 | //function : Intersect | |
309 | //purpose : | |
310 | //======================================================================= | |
311 | ||
312 | void Intf_InterferencePolygon2d::Intersect | |
313 | (const Standard_Integer iObje1, const Standard_Integer iObje2, | |
314 | const gp_Pnt2d& BegO, const gp_Pnt2d& EndO, | |
315 | const gp_Pnt2d& BegT, const gp_Pnt2d& EndT) | |
316 | { | |
317 | if(SelfIntf) { | |
318 | if(Abs(iObje1-iObje2)<=1) return; //-- Ajout du 15 jan 98 | |
319 | } | |
320 | ||
321 | Standard_Integer nbpi=0; | |
322 | Standard_Real parO[8]; | |
323 | Standard_Real parT[8]; | |
324 | Intf_SeqOfSectionPoint thePi; | |
325 | gp_XY segT =EndT.XY()-BegT.XY(); | |
326 | gp_XY segO =EndO.XY()-BegO.XY(); | |
327 | ||
328 | // If the length of segment is zero, nothing is done | |
329 | Standard_Real lgT =Sqrt(segT*segT); | |
330 | if (lgT<=0.) return; | |
331 | Standard_Real lgO =Sqrt(segO*segO); | |
332 | if (lgO<=0.) return; | |
333 | ||
334 | // Direction of parsing of segments | |
335 | Standard_Real sigPS=(segO*segT)>0.0 ? 1.0 : -1.0; | |
336 | ||
337 | // Precision of calculation | |
338 | Standard_Real floatgap=Epsilon(lgO+lgT); | |
339 | ||
340 | // Angle between two straight lines and radius of interference | |
341 | Standard_Real sinTeta=(segO.CrossMagnitude(segT)/lgO)/lgT; | |
342 | Standard_Real rayIntf=0.; | |
343 | if (sinTeta>0.) rayIntf=Tolerance/sinTeta; | |
344 | ||
345 | // Interference <begO> <segT> | |
346 | Standard_Real dbOT=((BegO.XY()-BegT.XY())^segT)/lgT; | |
347 | Standard_Real dbObT=BegO.Distance(BegT); | |
348 | Standard_Real dbOeT=BegO.Distance(EndT); | |
349 | if (Abs(dbOT)<=Tolerance) { | |
350 | if (dbObT<=Tolerance) { | |
351 | nbpi++; | |
352 | parO[nbpi]=0.;parT[nbpi]=0.; | |
353 | thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0., | |
354 | Intf_VERTEX,iObje2,0.,sinTeta)); | |
355 | } | |
356 | if (dbOeT<=Tolerance) { | |
357 | nbpi++; | |
358 | parO[nbpi]=0.;parT[nbpi]=1.; | |
359 | thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0., | |
360 | Intf_VERTEX,iObje2+1,0.,sinTeta)); | |
361 | } | |
362 | if (dbObT>Tolerance && dbOeT>Tolerance && | |
363 | dbObT+dbOeT<=(lgT+Tolerance)) { | |
364 | nbpi++; | |
365 | parO[nbpi]=0.;parT[nbpi]=dbObT/lgT; | |
366 | thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0., | |
367 | Intf_EDGE,iObje2,parT[nbpi],sinTeta)); | |
368 | } | |
369 | } | |
370 | ||
371 | // Interference <endO> <segT> | |
372 | Standard_Real deOT=((EndO.XY()-BegT.XY())^segT)/lgT; | |
373 | Standard_Real deObT=EndO.Distance(BegT); | |
374 | Standard_Real deOeT=EndO.Distance(EndT); | |
375 | if (Abs(deOT)<=Tolerance) { | |
376 | if (deObT<=Tolerance) { | |
377 | nbpi++; | |
378 | parO[nbpi]=1.;parT[nbpi]=0.; | |
379 | thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0., | |
380 | Intf_VERTEX,iObje2,0.,sinTeta)); | |
381 | } | |
382 | if (deOeT<=Tolerance) { | |
383 | nbpi++; | |
384 | parO[nbpi]=1.;parT[nbpi]=1.; | |
385 | thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0., | |
386 | Intf_VERTEX,iObje2+1,0.,sinTeta)); | |
387 | } | |
388 | if (deObT>Tolerance && deOeT>Tolerance && | |
389 | deObT+deOeT<=(lgT+Tolerance)) { | |
390 | nbpi++; | |
391 | parO[nbpi]=1.;parT[nbpi]=deObT/lgT; | |
392 | thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0., | |
393 | Intf_EDGE,iObje2,parT[nbpi],sinTeta)); | |
394 | } | |
395 | } | |
396 | ||
397 | // Interference <begT> <segO> | |
398 | Standard_Real dbTO=((BegT.XY()-BegO.XY())^segO)/lgO; | |
399 | if (Abs(dbTO)<=Tolerance) { | |
400 | if (dbObT>Tolerance && deObT>Tolerance && | |
401 | dbObT+deObT<=(lgO+Tolerance)) { | |
402 | nbpi++; | |
403 | parO[nbpi]=dbObT/lgO;parT[nbpi]=0.; | |
404 | thePi.Append(Intf_SectionPoint(BegT,Intf_EDGE,iObje1,parO[nbpi], | |
405 | Intf_VERTEX,iObje2,0.,sinTeta)); | |
406 | } | |
407 | } | |
408 | ||
409 | // Interference <endT> <segO> | |
410 | Standard_Real deTO=((EndT.XY()-BegO.XY())^segO)/lgO; | |
411 | if (Abs(deTO)<=Tolerance) { | |
412 | if (dbOeT>Tolerance && deOeT>Tolerance && | |
413 | dbOeT+deOeT<=(lgO+Tolerance)) { | |
414 | nbpi++; | |
415 | parO[nbpi]=dbOeT/lgO;parT[nbpi]=1.; | |
416 | thePi.Append(Intf_SectionPoint(EndT,Intf_EDGE,iObje1,parO[nbpi], | |
417 | Intf_VERTEX,iObje2+1,0.,sinTeta)); | |
418 | } | |
419 | } | |
420 | ||
421 | Standard_Boolean edgeSP=Standard_False; | |
422 | Standard_Real parOSP=0, parTSP=0; | |
423 | ||
424 | if (Abs(dbOT-deOT)>floatgap && Abs(dbTO-deTO)>floatgap) { | |
425 | parOSP=dbOT/(dbOT-deOT); | |
426 | parTSP=dbTO/(dbTO-deTO); | |
427 | if (dbOT*deOT<=0. && dbTO*deTO<=0.) { | |
428 | edgeSP=Standard_True; | |
429 | } | |
430 | else if (nbpi==0) return; | |
431 | ||
432 | // If there is no interference it is necessary to take the points segment by segment | |
433 | if (nbpi==0 && sinTeta>PRCANG) { | |
434 | nbpi++; | |
435 | parO[nbpi]=parOSP; | |
436 | parT[nbpi]=parTSP; | |
437 | thePi.Append(Intf_SectionPoint(gp_Pnt2d (BegO.X()+ (segO.X()*parOSP), | |
438 | BegO.Y()+ (segO.Y()*parOSP)), | |
439 | Intf_EDGE,iObje1,parOSP, | |
440 | Intf_EDGE,iObje2,parTSP,sinTeta)); | |
441 | } | |
442 | ||
443 | // Otherwise it is required to check if there is no other | |
444 | else if (rayIntf>=Tolerance) { | |
445 | Standard_Real deltaO=rayIntf/lgO; | |
446 | Standard_Real deltaT=rayIntf/lgT; | |
447 | Standard_Real x, y; | |
448 | Standard_Real parOdeb=parOSP-deltaO; | |
449 | Standard_Real parOfin=parOSP+deltaO; | |
450 | Standard_Real parTdeb=parTSP-sigPS*deltaT; | |
451 | Standard_Real parTfin=parTSP+sigPS*deltaT; | |
452 | if (nbpi==0) { | |
453 | parO[1]=parOdeb; | |
454 | parO[2]=parOfin; | |
455 | parT[1]=parTdeb; | |
456 | parT[2]=parTfin; | |
457 | while (nbpi<2) { | |
458 | nbpi++; | |
459 | x=BegO.X()+ (segO.X()*parO[nbpi]); | |
460 | y=BegO.Y()+ (segO.Y()*parO[nbpi]); | |
461 | thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y), | |
462 | Intf_EXTERNAL, iObje1, parO[nbpi], | |
463 | Intf_EXTERNAL, iObje2, parT[nbpi], | |
464 | sinTeta)); | |
465 | } | |
466 | } | |
467 | else { //nbpi>0 | |
468 | if (nbpi==1) { | |
469 | Standard_Boolean ok=Standard_True; | |
470 | if (0.<parOdeb && parOdeb<1. && 0.<parTdeb && parTdeb<1. ) { | |
471 | parO[nbpi+1]=parOdeb; | |
472 | parT[nbpi+1]=parTdeb; | |
473 | } | |
474 | else if (0.<parOfin && parOfin<1. && 0.<parTfin && parTfin<1. ) { | |
475 | parO[nbpi+1]= parOfin; | |
476 | parT[nbpi+1]= parTfin; | |
477 | } | |
478 | else { | |
479 | ok=Standard_False; | |
480 | } | |
481 | ||
482 | if (ok) { | |
483 | x=BegO.X()+ (segO.X()*parO[nbpi+1]); | |
484 | y=BegO.Y()+ (segO.Y()*parO[nbpi+1]); | |
485 | if (thePi(1).Pnt().Distance(gp_Pnt(x, y, 0)) >= (Tolerance/4.)) { | |
486 | nbpi++; | |
487 | thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y), | |
488 | Intf_EXTERNAL, iObje1, parO[nbpi], | |
489 | Intf_EXTERNAL, iObje2, parT[nbpi], | |
490 | sinTeta)); | |
491 | } | |
492 | } | |
493 | } | |
494 | else { // plus d une singularite | |
495 | Standard_Real parOmin=parO[1]; | |
496 | Standard_Real parOmax=parO[1]; | |
497 | Standard_Real parTmin=parT[1]; | |
498 | Standard_Real parTmax=parT[1]; | |
499 | for (Standard_Integer i=2; i<=nbpi; i++) { | |
500 | parOmin=Min(parOmin, parO[i]); | |
501 | parOmax=Max(parOmax, parO[i]); | |
502 | parTmin=Min(parTmin, parT[i]); | |
503 | parTmax=Max(parTmax, parT[i]); | |
504 | } | |
505 | ||
506 | Standard_Real delta; | |
507 | if (parOdeb<0.) { | |
508 | delta=-parOdeb; | |
509 | parOdeb=0.; | |
510 | parTdeb=parTdeb+sigPS*(delta*(deltaT/deltaO)); | |
511 | } | |
512 | if (parOfin>1.) { | |
513 | delta=parOfin-1.; | |
514 | parOfin=1.; | |
515 | parTfin=parTfin-sigPS*(delta*(deltaT/deltaO)); | |
516 | } | |
517 | if (sigPS>0.) { | |
518 | if (parTdeb<0.) { | |
519 | delta=-parTdeb; | |
520 | parTdeb=0.; | |
521 | parOdeb=parOdeb+delta*(deltaO/deltaT); | |
522 | } | |
523 | if (parTfin>1.) { | |
524 | delta=parTfin-1.; | |
525 | parTfin=1.; | |
526 | parOfin=parOfin-delta*(deltaO/deltaT); | |
527 | } | |
528 | } | |
529 | else { | |
530 | if (parTdeb>1.) { | |
531 | delta=parTdeb-1.; | |
532 | parTdeb=1.; | |
533 | parOdeb=parOdeb+delta*(deltaO/deltaT); | |
534 | } | |
535 | if (parTfin<0.) { | |
536 | delta=-parTfin; | |
537 | parTfin=0.; | |
538 | parOfin=parOfin-delta*(deltaO/deltaT); | |
539 | } | |
540 | } | |
541 | ||
542 | if ((parOdeb<parOmin && parOmin>0.) || | |
543 | (sigPS>0. && parTdeb<parTmin && parTmin>0.) || | |
544 | (sigPS<0. && parTdeb>parTmax && parTmax<1.)) { | |
545 | nbpi++; | |
546 | parO[nbpi]=Max(0., Min(1., parOdeb)); | |
547 | parT[nbpi]=Max(0., Min(1., parTdeb)); | |
548 | x=BegO.X()+ (segO.X()*parO[nbpi]); | |
549 | y=BegO.Y()+ (segO.Y()*parO[nbpi]); | |
550 | thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y), | |
551 | Intf_EXTERNAL, iObje1, parO[nbpi], | |
552 | Intf_EXTERNAL, iObje2, parT[nbpi], | |
553 | sinTeta)); | |
554 | } | |
555 | ||
556 | if ((parOfin>parOmax && parOmax<1.) || | |
557 | (sigPS<0. && parTfin<parTmin && parTmin>0.) || | |
558 | (sigPS>0. && parTfin>parTmax && parTmax<1.)) { | |
559 | nbpi++; | |
560 | parO[nbpi]=Min(1., Max(0., parOfin)); | |
561 | parT[nbpi]=Min(1., Max(0., parTfin)); | |
562 | x=BegO.X()+ (segO.X()*parO[nbpi]); | |
563 | y=BegO.Y()+ (segO.Y()*parO[nbpi]); | |
564 | thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y), | |
565 | Intf_EXTERNAL, iObje1, parO[nbpi], | |
566 | Intf_EXTERNAL, iObje2, parT[nbpi], | |
567 | sinTeta)); | |
568 | } | |
569 | } | |
570 | } | |
571 | } | |
572 | } | |
573 | ||
574 | //-- lbr : The points too close to each other are suspended | |
575 | Standard_Boolean suppr; | |
576 | do { | |
577 | suppr=Standard_False; | |
578 | for(Standard_Integer i=2; suppr==Standard_False && i<=nbpi; i++) { | |
579 | const gp_Pnt& Pim1 = thePi(i-1).Pnt(); | |
580 | const gp_Pnt& Pi = thePi(i).Pnt(); | |
581 | Standard_Real d=Pi.Distance(Pim1); | |
582 | d*=50.0; | |
583 | if(d<lgT && d<lgO) { | |
584 | for(Standard_Integer j=i; j<nbpi; j++) { | |
585 | thePi(j)=thePi(j+1); | |
586 | } | |
587 | nbpi--; | |
588 | suppr=Standard_True; | |
589 | } | |
590 | } | |
591 | } | |
592 | while(suppr==Standard_True); | |
593 | ||
594 | ||
595 | ||
596 | ||
597 | ||
598 | ||
599 | if (nbpi==1) { | |
600 | if (edgeSP) { | |
601 | thePi(1)=Intf_SectionPoint(gp_Pnt2d (BegO.X()+ (segO.X()*parOSP), | |
602 | BegO.Y()+ (segO.Y()*parOSP)), | |
603 | Intf_EDGE,iObje1,parOSP, | |
604 | Intf_EDGE,iObje2,parTSP,sinTeta); | |
605 | parO[1]=parOSP; | |
606 | parT[1]=parTSP; | |
607 | } | |
608 | if (!SelfIntf) { | |
609 | Standard_Boolean contains = Standard_False; | |
610 | for (Standard_Integer i = 1; i <= mySPoins.Length(); i++) | |
611 | if (thePi(1).IsEqual(mySPoins(i))) { | |
612 | contains = Standard_True; | |
613 | break; | |
614 | } | |
615 | if (!contains) | |
616 | mySPoins.Append(thePi(1)); | |
617 | } | |
618 | else if (iObje2-iObje1!=1 && | |
619 | (!oClos || (iObje1!=1 && iObje2!=nbso))) { | |
620 | mySPoins.Append(thePi(1)); | |
621 | } | |
622 | } | |
623 | ||
624 | else if (nbpi>=2) { | |
625 | Intf_TangentZone TheTZ; | |
626 | if (nbpi==2) { | |
627 | TheTZ.PolygonInsert(thePi(1)); | |
628 | TheTZ.PolygonInsert(thePi(2)); | |
629 | } | |
630 | else { | |
631 | Standard_Integer lpj; | |
632 | Standard_Integer lmin=1; | |
633 | Standard_Integer lmax=1; | |
634 | for (lpj=2; lpj<=nbpi; lpj++) { | |
635 | if (parO[lpj]<parO[lmin]) lmin=lpj; | |
636 | else if (parO[lpj]>parO[lmax]) lmax=lpj; | |
637 | } | |
638 | TheTZ.PolygonInsert(thePi(lmin)); | |
639 | TheTZ.PolygonInsert(thePi(lmax)); | |
640 | ||
641 | Standard_Integer ltmin=1; | |
642 | Standard_Integer ltmax=1; | |
643 | for (lpj=2; lpj<=nbpi; lpj++) { | |
644 | if (parT[lpj]<parT[ltmin]) ltmin=lpj; | |
645 | else if (parT[lpj]>parT[ltmax]) ltmax=lpj; | |
646 | } | |
647 | if (ltmin!=lmin && ltmin!=lmax) TheTZ.PolygonInsert(thePi(ltmin)); | |
648 | if (ltmax!=lmin && ltmax!=lmax) TheTZ.PolygonInsert(thePi(ltmax)); | |
649 | } | |
650 | ||
651 | if (edgeSP) TheTZ.PolygonInsert(Intf_SectionPoint | |
652 | (gp_Pnt2d (BegO.X()+ (segO.X()*parOSP), | |
653 | BegO.Y()+ (segO.Y()*parOSP)), | |
654 | Intf_EDGE,iObje1,parOSP, | |
655 | Intf_EDGE,iObje2,parTSP,sinTeta)); | |
656 | ||
657 | Standard_Integer nbtz=myTZones.Length(); | |
658 | #if 0 | |
659 | Standard_Integer decaltz=0; | |
660 | for (Standard_Integer ltz=1; ltz<=nbtz; ltz++) { | |
661 | if (TheTZ.HasCommonRange(myTZones(ltz-decaltz))) { | |
662 | TheTZ.Append(myTZones(ltz-decaltz)); | |
663 | myTZones.Remove(ltz-decaltz); | |
664 | decaltz++; | |
665 | } | |
666 | } | |
667 | myTZones.Append(TheTZ); | |
668 | #else | |
669 | TColStd_ListOfInteger LIndex; | |
670 | for (Standard_Integer ltz=1; ltz<=nbtz; ltz++) { | |
671 | if (TheTZ.HasCommonRange(myTZones(ltz))) { | |
672 | LIndex.Append(ltz); | |
673 | } | |
674 | } | |
675 | //------------------------------------------------------------------------ | |
676 | //-- The list is parsed in ascending order by index, zone and tg | |
677 | //-- | |
678 | if(LIndex.IsEmpty()) { | |
679 | myTZones.Append(TheTZ); | |
680 | } | |
681 | else { | |
682 | Standard_Integer indexfirst = LIndex.First(); | |
683 | LIndex.RemoveFirst(); | |
684 | Standard_Integer decal = 0; | |
685 | myTZones(indexfirst).Append(TheTZ); | |
686 | while(!LIndex.IsEmpty()) { | |
687 | Standard_Integer index = LIndex.First(); | |
688 | LIndex.RemoveFirst(); | |
689 | myTZones(indexfirst).Append(myTZones(index-decal)); | |
690 | myTZones.Remove(index-decal); | |
691 | decal++; | |
692 | } | |
693 | } | |
694 | #endif | |
695 | } | |
696 | } |