b311480e |
1 | // Created on: 1996-06-11 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1996-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 <Geom_Circle.hxx> |
19 | #include <GeomAdaptor_HCurve.hxx> |
20 | #include <IntCurvesFace_Intersector.hxx> |
21 | #include <LocOpe_CSIntersector.hxx> |
7fd59977 |
22 | #include <LocOpe_PntFace.hxx> |
23 | #include <LocOpe_SequenceOfPntFace.hxx> |
42cf5bc1 |
24 | #include <Precision.hxx> |
7fd59977 |
25 | #include <Standard_ConstructionError.hxx> |
42cf5bc1 |
26 | #include <Standard_OutOfRange.hxx> |
27 | #include <StdFail_NotDone.hxx> |
28 | #include <TopExp_Explorer.hxx> |
7fd59977 |
29 | #include <TopoDS.hxx> |
42cf5bc1 |
30 | #include <TopoDS_Shape.hxx> |
7fd59977 |
31 | |
32 | static Standard_Boolean LocAfter (const LocOpe_SequenceOfPntFace&, |
33 | const Standard_Real, |
34 | const Standard_Real, |
35 | TopAbs_Orientation&, |
36 | Standard_Integer&, |
37 | Standard_Integer&); |
38 | |
39 | static Standard_Boolean LocBefore (const LocOpe_SequenceOfPntFace&, |
40 | const Standard_Real, |
41 | const Standard_Real, |
42 | TopAbs_Orientation&, |
43 | Standard_Integer&, |
44 | Standard_Integer&); |
45 | |
46 | static Standard_Boolean LocAfter (const LocOpe_SequenceOfPntFace&, |
47 | const Standard_Integer, |
48 | const Standard_Real, |
49 | TopAbs_Orientation&, |
50 | Standard_Integer&, |
51 | Standard_Integer&); |
52 | |
7fd59977 |
53 | static void AddPoints(IntCurvesFace_Intersector&, |
54 | LocOpe_SequenceOfPntFace&, |
55 | const TopoDS_Face&); |
56 | |
7fd59977 |
57 | //======================================================================= |
58 | //function : Init |
59 | //purpose : |
60 | //======================================================================= |
61 | |
62 | void LocOpe_CSIntersector::Init(const TopoDS_Shape& S) |
63 | { |
64 | myDone = Standard_False; |
65 | myShape = S; |
66 | if (myPoints != NULL) { |
67 | delete [] (LocOpe_SequenceOfPntFace *)myPoints; |
68 | myPoints = NULL; |
69 | } |
70 | myNbelem = 0; |
71 | } |
72 | |
73 | |
74 | //======================================================================= |
75 | //function : Perform |
76 | //purpose : |
77 | //======================================================================= |
78 | |
79 | void LocOpe_CSIntersector::Perform(const LocOpe_SequenceOfLin& Slin) |
80 | { |
81 | if (myShape.IsNull() || Slin.Length() <= 0) { |
9775fa61 |
82 | throw Standard_ConstructionError(); |
7fd59977 |
83 | } |
84 | myDone = Standard_False; |
85 | |
86 | myNbelem = Slin.Length(); |
87 | if (myPoints != NULL) { |
88 | delete [] (LocOpe_SequenceOfPntFace *)myPoints; |
89 | } |
90 | myPoints = |
91 | (LocOpe_SequenceOfPntFace *) new LocOpe_SequenceOfPntFace[myNbelem]; |
92 | |
93 | Standard_Real binf = RealFirst(); |
94 | Standard_Real bsup = RealLast(); |
95 | TopExp_Explorer exp(myShape,TopAbs_FACE); |
96 | for (; exp.More(); exp.Next()) { |
97 | const TopoDS_Face& theface = TopoDS::Face(exp.Current()); |
98 | IntCurvesFace_Intersector theInt(theface,Precision::PConfusion()); |
99 | for (Standard_Integer i = 1; i<=myNbelem; i++) { |
100 | theInt.Perform(Slin(i),binf,bsup); |
101 | if (theInt.IsDone()) { |
102 | AddPoints(theInt,(((LocOpe_SequenceOfPntFace*)myPoints)[i-1]),theface); |
103 | } |
104 | } |
105 | } |
106 | myDone = Standard_True; |
107 | } |
108 | |
109 | |
110 | //======================================================================= |
111 | //function : Perform |
112 | //purpose : |
113 | //======================================================================= |
114 | |
115 | void LocOpe_CSIntersector::Perform(const LocOpe_SequenceOfCirc& Scir) |
116 | { |
117 | if (myShape.IsNull() || Scir.Length() <= 0) { |
9775fa61 |
118 | throw Standard_ConstructionError(); |
7fd59977 |
119 | } |
120 | myDone = Standard_False; |
121 | |
122 | myNbelem = Scir.Length(); |
123 | if (myPoints != NULL) { |
124 | delete [] (LocOpe_SequenceOfPntFace *)myPoints; |
125 | } |
126 | myPoints = |
127 | (LocOpe_SequenceOfPntFace *) new LocOpe_SequenceOfPntFace[myNbelem]; |
128 | |
129 | TopExp_Explorer exp(myShape,TopAbs_FACE); |
130 | Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve (); |
131 | Standard_Real binf = 0.; |
c6541a0c |
132 | Standard_Real bsup = 2.*M_PI; |
7fd59977 |
133 | |
134 | |
135 | for (; exp.More(); exp.Next()) { |
136 | const TopoDS_Face& theface = TopoDS::Face(exp.Current()); |
137 | IntCurvesFace_Intersector theInt(theface,0.); |
7fd59977 |
138 | for (Standard_Integer i = 1; i<=myNbelem; i++) { |
139 | |
140 | HC->ChangeCurve().Load(new Geom_Circle(Scir(i))); |
141 | theInt.Perform(HC,binf,bsup); |
142 | if (theInt.IsDone()) { |
143 | AddPoints(theInt,(((LocOpe_SequenceOfPntFace*)myPoints)[i-1]),theface); |
144 | } |
145 | } |
146 | } |
147 | myDone = Standard_True; |
148 | } |
149 | |
150 | |
151 | |
152 | //======================================================================= |
153 | //function : Perform |
154 | //purpose : |
155 | //======================================================================= |
156 | |
157 | void LocOpe_CSIntersector::Perform(const TColGeom_SequenceOfCurve& Scur) |
158 | { |
159 | if (myShape.IsNull() || Scur.Length() <= 0) { |
9775fa61 |
160 | throw Standard_ConstructionError(); |
7fd59977 |
161 | } |
162 | myDone = Standard_False; |
163 | |
164 | myNbelem = Scur.Length(); |
165 | if (myPoints != NULL) { |
166 | delete [] (LocOpe_SequenceOfPntFace *)myPoints; |
167 | } |
168 | myPoints = |
169 | (LocOpe_SequenceOfPntFace *) new LocOpe_SequenceOfPntFace[myNbelem]; |
170 | |
171 | TopExp_Explorer exp(myShape,TopAbs_FACE); |
172 | Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve (); |
173 | for (; exp.More(); exp.Next()) { |
174 | const TopoDS_Face& theface = TopoDS::Face(exp.Current()); |
175 | IntCurvesFace_Intersector theInt(theface,0.); |
7fd59977 |
176 | for (Standard_Integer i = 1; i<=myNbelem; i++) { |
177 | if (Scur(i).IsNull()) { |
178 | continue; |
179 | } |
180 | HC->ChangeCurve().Load(Scur(i)); |
181 | Standard_Real binf = HC->FirstParameter(); |
182 | Standard_Real bsup = HC->LastParameter(); |
183 | theInt.Perform(HC,binf,bsup); |
184 | if (theInt.IsDone()) { |
185 | AddPoints(theInt,(((LocOpe_SequenceOfPntFace*)myPoints)[i-1]),theface); |
186 | } |
187 | } |
188 | } |
189 | myDone = Standard_True; |
190 | } |
191 | |
192 | |
193 | |
194 | //======================================================================= |
195 | //function : NbPoints |
196 | //purpose : |
197 | //======================================================================= |
198 | |
199 | Standard_Integer LocOpe_CSIntersector::NbPoints |
200 | (const Standard_Integer I) const |
201 | { |
9775fa61 |
202 | if (!myDone) {throw StdFail_NotDone();} |
7fd59977 |
203 | if (I <= 0 || I > myNbelem) { |
9775fa61 |
204 | throw Standard_OutOfRange(); |
7fd59977 |
205 | } |
206 | return ((LocOpe_SequenceOfPntFace *)myPoints)[I-1].Length(); |
207 | } |
208 | |
209 | //======================================================================= |
210 | //function : Point |
211 | //purpose : |
212 | //======================================================================= |
213 | |
214 | const LocOpe_PntFace& LocOpe_CSIntersector:: |
215 | Point(const Standard_Integer I, |
216 | const Standard_Integer Index) const |
217 | { |
9775fa61 |
218 | if (!myDone) {throw StdFail_NotDone();} |
7fd59977 |
219 | if (I <= 0 || I > myNbelem) { |
9775fa61 |
220 | throw Standard_OutOfRange(); |
7fd59977 |
221 | } |
222 | return ((LocOpe_SequenceOfPntFace *)myPoints)[I-1](Index); |
223 | } |
224 | |
225 | //======================================================================= |
226 | //function : Destroy |
227 | //purpose : |
228 | //======================================================================= |
229 | |
230 | void LocOpe_CSIntersector::Destroy() |
231 | { |
232 | if (myPoints != NULL) { |
233 | delete [] (LocOpe_SequenceOfPntFace *)myPoints; |
234 | myPoints = NULL; |
235 | } |
236 | } |
237 | |
238 | |
239 | //======================================================================= |
240 | //function : LocalizeAfter |
241 | //purpose : |
242 | //======================================================================= |
243 | |
244 | Standard_Boolean LocOpe_CSIntersector::LocalizeAfter |
245 | (const Standard_Integer I, |
246 | const Standard_Real From, |
247 | const Standard_Real Tol, |
248 | TopAbs_Orientation& Or, |
249 | Standard_Integer& IndFrom, |
250 | Standard_Integer& IndTo) const |
251 | { |
252 | if (!myDone) { |
9775fa61 |
253 | throw StdFail_NotDone(); |
7fd59977 |
254 | } |
255 | if (I <= 0 || I > myNbelem) { |
9775fa61 |
256 | throw Standard_OutOfRange(); |
7fd59977 |
257 | } |
258 | return LocAfter((((LocOpe_SequenceOfPntFace*)myPoints)[I-1]), |
259 | From,Tol,Or,IndFrom,IndTo); |
260 | } |
261 | |
262 | |
263 | //======================================================================= |
264 | //function : LocalizeBefore |
265 | //purpose : |
266 | //======================================================================= |
267 | |
268 | Standard_Boolean LocOpe_CSIntersector::LocalizeBefore |
269 | (const Standard_Integer I, |
270 | const Standard_Real From, |
271 | const Standard_Real Tol, |
272 | TopAbs_Orientation& Or, |
273 | Standard_Integer& IndFrom, |
274 | Standard_Integer& IndTo) const |
275 | { |
276 | if (!myDone) { |
9775fa61 |
277 | throw StdFail_NotDone(); |
7fd59977 |
278 | } |
279 | if (I <= 0 || I > myNbelem) { |
9775fa61 |
280 | throw Standard_OutOfRange(); |
7fd59977 |
281 | } |
282 | return LocBefore(((LocOpe_SequenceOfPntFace*)myPoints)[I-1], |
283 | From,Tol,Or,IndFrom,IndTo); |
284 | } |
285 | |
286 | //======================================================================= |
287 | //function : LocalizeAfter |
288 | //purpose : |
289 | //======================================================================= |
290 | |
291 | Standard_Boolean LocOpe_CSIntersector::LocalizeAfter |
292 | (const Standard_Integer I, |
293 | const Standard_Integer FromInd, |
294 | const Standard_Real Tol, |
295 | TopAbs_Orientation& Or, |
296 | Standard_Integer& IndFrom, |
297 | Standard_Integer& IndTo) const |
298 | { |
299 | if (!myDone) { |
9775fa61 |
300 | throw StdFail_NotDone(); |
7fd59977 |
301 | } |
302 | if (I <= 0 || I > myNbelem) { |
9775fa61 |
303 | throw Standard_OutOfRange(); |
7fd59977 |
304 | } |
305 | return LocAfter(((LocOpe_SequenceOfPntFace*)myPoints)[I-1], |
306 | FromInd,Tol,Or,IndFrom,IndTo); |
307 | |
308 | } |
309 | |
310 | //======================================================================= |
311 | //function : LocalizeBefore |
312 | //purpose : |
313 | //======================================================================= |
314 | |
315 | Standard_Boolean LocOpe_CSIntersector::LocalizeBefore |
316 | (const Standard_Integer I, |
317 | const Standard_Integer FromInd, |
318 | const Standard_Real Tol, |
319 | TopAbs_Orientation& Or, |
320 | Standard_Integer& IndFrom, |
321 | Standard_Integer& IndTo) const |
322 | { |
323 | if (!myDone) { |
9775fa61 |
324 | throw StdFail_NotDone(); |
7fd59977 |
325 | } |
326 | if (I <= 0 || I > myNbelem) { |
9775fa61 |
327 | throw Standard_OutOfRange(); |
7fd59977 |
328 | } |
329 | return LocBefore(((LocOpe_SequenceOfPntFace*)myPoints)[I-1], |
330 | FromInd,Tol,Or,IndFrom,IndTo); |
331 | |
332 | } |
333 | |
334 | |
335 | |
336 | |
337 | //======================================================================= |
338 | //function : LocAfter |
339 | //purpose : |
340 | //======================================================================= |
341 | |
342 | static Standard_Boolean LocAfter (const LocOpe_SequenceOfPntFace& Spt, |
343 | const Standard_Real From, |
344 | const Standard_Real Tol, |
345 | TopAbs_Orientation& Or, |
346 | Standard_Integer& IndFrom, |
347 | Standard_Integer& IndTo) |
348 | { |
349 | |
350 | Standard_Real param,FMEPS = From - Tol; |
351 | Standard_Integer i,ifirst,nbpoints = Spt.Length(); |
352 | for (ifirst=1; ifirst<=nbpoints; ifirst++) { |
353 | if (Spt(ifirst).Parameter() >= FMEPS) { |
354 | break; |
355 | } |
356 | } |
357 | Standard_Boolean RetVal = Standard_False; |
358 | if (ifirst <= nbpoints) { |
359 | i = ifirst; |
360 | IndFrom = ifirst; |
361 | Standard_Boolean found = Standard_False; |
362 | while (!found) { |
363 | Or = Spt(i).Orientation(); |
364 | param = Spt(i).Parameter(); |
365 | i = i+1; |
366 | while (i<=nbpoints) { |
367 | if (Spt(i).Parameter()-param <= Tol) { |
368 | if (Or != TopAbs_EXTERNAL && Or != Spt(i).Orientation()) { |
369 | Or = TopAbs_EXTERNAL; |
370 | } |
371 | i++; |
372 | } |
373 | else { |
374 | break; |
375 | } |
376 | } |
377 | if (Or == TopAbs_EXTERNAL) { |
378 | found = (i > nbpoints); |
379 | IndFrom = i; |
380 | } |
381 | else { // on a une intersection franche |
382 | IndTo = i-1; |
383 | found = Standard_True; |
384 | RetVal = Standard_True; |
385 | } |
386 | } |
387 | } |
388 | |
389 | return RetVal; |
390 | } |
391 | |
392 | //======================================================================= |
393 | //function : LocBefore |
394 | //purpose : |
395 | //======================================================================= |
396 | |
397 | static Standard_Boolean LocBefore (const LocOpe_SequenceOfPntFace& Spt, |
398 | const Standard_Real From, |
399 | const Standard_Real Tol, |
400 | TopAbs_Orientation& Or, |
401 | Standard_Integer& IndFrom, |
402 | Standard_Integer& IndTo) |
403 | { |
404 | Standard_Real param,FPEPS = From + Tol; |
405 | Standard_Integer i,ifirst,nbpoints = Spt.Length(); |
406 | for (ifirst=nbpoints; ifirst>=1; ifirst--) { |
407 | if (Spt(ifirst).Parameter() <= FPEPS) { |
408 | break; |
409 | } |
410 | } |
411 | Standard_Boolean RetVal = Standard_False; |
412 | if (ifirst >= 1) { |
413 | i = ifirst; |
414 | IndTo = ifirst; |
415 | Standard_Boolean found = Standard_False; |
416 | while (!found) { |
417 | Or = Spt(i).Orientation(); |
418 | param = Spt(i).Parameter(); |
419 | i = i-1; |
420 | while (i>=1) { |
421 | if (param - Spt(i).Parameter() <= Tol) { |
422 | if (Or != TopAbs_EXTERNAL && Or != Spt(i).Orientation()) { |
423 | Or = TopAbs_EXTERNAL; |
424 | } |
425 | i--; |
426 | } |
427 | else { |
428 | break; |
429 | } |
430 | } |
431 | if (Or == TopAbs_EXTERNAL) { |
432 | found = (i < 1); |
433 | IndTo = i; |
434 | } |
435 | else { // on a une intersection franche |
436 | IndFrom = i+1; |
437 | found = Standard_True; |
438 | RetVal = Standard_True; |
439 | } |
440 | } |
441 | } |
442 | |
443 | return RetVal; |
444 | } |
445 | |
446 | //======================================================================= |
447 | //function : LocAfter |
448 | //purpose : |
449 | //======================================================================= |
450 | |
451 | static Standard_Boolean LocAfter (const LocOpe_SequenceOfPntFace& Spt, |
452 | const Standard_Integer FromInd, |
453 | const Standard_Real Tol, |
454 | TopAbs_Orientation& Or, |
455 | Standard_Integer& IndFrom, |
456 | Standard_Integer& IndTo) |
457 | { |
458 | Standard_Integer nbpoints = Spt.Length(); |
459 | if (FromInd >= nbpoints) { |
460 | return Standard_False; |
461 | } |
462 | |
463 | Standard_Real param,FMEPS; |
464 | Standard_Integer i,ifirst; |
465 | if (FromInd >= 1) { |
466 | FMEPS = Spt(FromInd).Parameter() - Tol; |
467 | for (ifirst=FromInd+1; ifirst<=nbpoints; ifirst++) { |
468 | if (Spt(ifirst).Parameter() >= FMEPS) { |
469 | break; |
470 | } |
471 | } |
472 | } |
473 | else { |
474 | ifirst = 1; |
475 | } |
476 | |
477 | Standard_Boolean RetVal = Standard_False; |
478 | if (ifirst <= nbpoints) { |
479 | i = ifirst; |
480 | IndFrom = ifirst; |
481 | Standard_Boolean found = Standard_False; |
482 | while (!found) { |
483 | Or = Spt(i).Orientation(); |
484 | param = Spt(i).Parameter(); |
485 | i = i+1; |
486 | while (i<=nbpoints) { |
487 | if (Spt(i).Parameter()-param <= Tol) { |
488 | if (Or != TopAbs_EXTERNAL && Or != Spt(i).Orientation()) { |
489 | Or = TopAbs_EXTERNAL; |
490 | } |
491 | i++; |
492 | } |
493 | else { |
494 | break; |
495 | } |
496 | } |
497 | if (Or == TopAbs_EXTERNAL) { |
498 | found = (i > nbpoints); |
499 | IndFrom = i; |
500 | } |
501 | else { // on a une intersection franche |
502 | IndTo = i-1; |
503 | found = Standard_True; |
504 | RetVal = Standard_True; |
505 | } |
506 | } |
507 | } |
508 | return RetVal; |
509 | } |
510 | |
7fd59977 |
511 | //======================================================================= |
512 | //function : AddPoints |
513 | //purpose : |
514 | //======================================================================= |
515 | |
516 | static void AddPoints(IntCurvesFace_Intersector& theInt, |
517 | LocOpe_SequenceOfPntFace& theSeq, |
518 | const TopoDS_Face& theface) |
519 | { |
520 | Standard_Integer nbpoints = theSeq.Length(); |
521 | Standard_Integer newpnt = theInt.NbPnt(); |
522 | Standard_Real param,paramu,paramv; |
7fd59977 |
523 | for (Standard_Integer j = 1; j<=newpnt; j++) { |
524 | const gp_Pnt& thept = theInt.Pnt(j); |
525 | param = theInt.WParameter(j); |
526 | paramu = theInt.UParameter(j); |
527 | paramv = theInt.VParameter(j); |
1d47d8d0 |
528 | |
7fd59977 |
529 | TopAbs_Orientation theor=TopAbs_FORWARD; |
1d47d8d0 |
530 | |
7fd59977 |
531 | switch (theInt.Transition(j)) { |
532 | case IntCurveSurface_In: |
533 | /* JAG 13.09.96 |
534 | if ( orface == TopAbs_FORWARD) { |
535 | theor = TopAbs_FORWARD; |
536 | } |
537 | else if (orface == TopAbs_REVERSED) { |
538 | theor = TopAbs_REVERSED; |
539 | } |
540 | else { |
541 | theor = TopAbs_EXTERNAL; |
542 | } |
543 | */ |
544 | theor = TopAbs_FORWARD; |
545 | |
546 | break; |
547 | case IntCurveSurface_Out: |
548 | /* JAG 13.09.96 |
549 | if ( orface == TopAbs_FORWARD) { |
550 | theor = TopAbs_REVERSED; |
551 | } |
552 | else if (orface == TopAbs_REVERSED) { |
553 | theor = TopAbs_FORWARD; |
554 | } |
555 | else { |
556 | theor = TopAbs_EXTERNAL; |
557 | } |
558 | */ |
559 | theor = TopAbs_REVERSED; |
560 | break; |
561 | case IntCurveSurface_Tangent: |
562 | theor = TopAbs_EXTERNAL; |
563 | break; |
564 | |
565 | } |
566 | LocOpe_PntFace newpt(thept,theface,theor,param,paramu,paramv); |
567 | // for (Standard_Integer k=1; k <= nbpoints; k++) { |
568 | Standard_Integer k; |
569 | for ( k=1; k <= nbpoints; k++) { |
570 | if (theSeq(k).Parameter() - param > 0.) { |
571 | break; |
572 | } |
573 | } |
574 | if (k <= nbpoints) { |
575 | theSeq.InsertBefore(k,newpt); |
576 | } |
577 | else { |
578 | theSeq.Append(newpt); |
579 | } |
580 | nbpoints++; |
581 | } |
582 | } |