Update testing case for issue 0024499
[occt.git] / src / IntPoly / IntPoly_ShapeSection.cxx
CommitLineData
b311480e 1// Created on: 1995-08-01
2// Created by: Stagiaire Alain JOURDAIN
3// Copyright (c) 1995-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//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public version 2.1 as published
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 <IntPoly_ShapeSection.ixx>
18
19#include <IntPoly_SequenceOfSequenceOfPnt.hxx>
20#include <IntPoly_IndexedMapOfPnt.hxx>
21#include <IntPoly_PntHasher.hxx>
22#include <Precision.hxx>
23#include <TopExp_Explorer.hxx>
24#include <TopoDS_Shape.hxx>
25#include <TopoDS_Edge.hxx>
26#include <TColStd_Array1OfReal.hxx>
27#include <TColStd_Array1OfInteger.hxx>
28#include <BRep_Tool.hxx>
29#include <BRep_Builder.hxx>
30#include <TopoDS.hxx>
31#include <gp_Pnt.hxx>
32#include <gp_Dir.hxx>
33#include <gp_XYZ.hxx>
34#include <Poly_Triangulation.hxx>
35#include <Poly_Polygon3D.hxx>
36
37
38//=======================================================================
39//function : IntPoly_ShapeSection
40//purpose :
41//=======================================================================
42
43IntPoly_ShapeSection::IntPoly_ShapeSection()
44{}
45
46
47//=======================================================================
48//function : IntPoly_ShapeSection
49//purpose :
50//=======================================================================
51
52IntPoly_ShapeSection::IntPoly_ShapeSection(const TopoDS_Shape& S1,
53 const TopoDS_Shape& S2)
54{
55 myShape1 = S1;
56 myShape2 = S2;
57 Section();
58}
59
60
61//=======================================================================
62//function : Section
63//purpose :
64//=======================================================================
65
66void IntPoly_ShapeSection::Section()
67{
68 Explore();
69 Standard_Integer NbLinks = myMapBegPoints.Extent();
70 Standard_Integer Result,i = 1;
71 Standard_Real Big = Precision::Infinite();
72 gp_Pnt BegPoint,EndPoint,OutPoint;
73
74 while (i <= NbLinks) {
75 if (!(Precision::IsInfinite((myMapBegPoints.FindKey(i)).X()))) {
76 BegPoint = myMapBegPoints.FindKey(i);
77 EndPoint = myMapEndPoints.FindKey(i);
78 myCpt++;
79 myMapBegPoints.Substitute(i,gp_Pnt(Big,myCpt,myCpt));
80 myMapEndPoints.Substitute(i,gp_Pnt(Big,myCpt,myCpt));
81 Result = Concat(BegPoint,EndPoint,OutPoint);
82 if (Result == 2)
83 ForwConstruction(OutPoint);
84 else
85 if (Result == 1)
86 PrevConstruction(OutPoint);
87 else {
88 ForwConstruction(EndPoint);
89 PrevConstruction(BegPoint);
90 }
91 }
92 i++;
93 }
94
95 i = 1;
96 while (i < mySection.Length()) {
97 ConcatSection(mySection.ChangeValue(i),mySection.Length(),i+1);
98 i++;
99 }
100 myNbEdges = mySection.Length();
101}
102
103
104
105//=======================================================================
106//function : Explore
107//purpose :
108//=======================================================================
109
110inline Standard_Boolean SAMESIGN(Standard_Real a,
111 Standard_Real b,
112 Standard_Real c)
113{
114 return ((a > 0.0 && b > 0.0 && c > 0.0) ||
115 (a < 0.0 && b < 0.0 && c < 0.0) ||
116 (a == 0.0 && b == 0.0 && c == 0.0));
117}
118
119inline void MINMAX(Standard_Real a,Standard_Real b,Standard_Real c,
120 Standard_Real &m,Standard_Real &M)
121{
122 m = M = a;
123 if (b < c) {
124 if (b < m) m = b;
125 if (c > M) M = c;
126 }
127 else {
128 if (c < m) m = c;
129 if (b > M) M = b;
130 }
131}
132
133void IntPoly_ShapeSection::Explore()
134{
135 TopExp_Explorer ex1,ex2;
136 Standard_Integer i,i1,i2,i3,j,j1,j2,j3;
137 Standard_Integer NbTrian1,NbFaces1,NbTriATotal;
138 Standard_Integer NbTrian2,NbFaces2,NbTriBTotal;
139 Standard_Real Big = Precision::Infinite();
140 Standard_Real min,minfx,minfy,minfz,max,maxfx,maxfy,maxfz;
141 TopLoc_Location Loc1,Loc2;
142 Handle(Poly_Triangulation) Tr1,Tr2;
143 myCpt = 0;
144
145 //-----------------------------------------------------------------
146 //-- Traitement pour recuperer le nombre de faces et le nombre
147 //-- de triangles des shapes 1 et 2
148 //-----------------------------------------------------------------
149 NbFaces1 = NbTriATotal = 0;
150 for (ex1.Init(myShape1,TopAbs_FACE);ex1.More();ex1.Next()) {
151 Tr1 = (BRep_Tool::Triangulation(TopoDS::Face(ex1.Current()),Loc1));
152 if (!Tr1.IsNull()) {
153 NbTriATotal += Tr1->NbTriangles();
154 NbFaces1++;
155 }
156 }
157 NbFaces2 = NbTriBTotal = 0;
158 for (ex2.Init(myShape2,TopAbs_FACE);ex2.More();ex2.Next()) {
159 Tr2 = (BRep_Tool::Triangulation(TopoDS::Face(ex2.Current()),Loc2));
160 if (!Tr2.IsNull()) {
161 NbTriBTotal += Tr2->NbTriangles();
162 NbFaces2++;
163 }
164 }
165
166 if (NbTriATotal < NbTriBTotal) {
167 TopoDS_Shape S = myShape2;
168 myShape2 = myShape1;
169 myShape1 = S;
170 Standard_Integer Nb = NbTriBTotal;
171 NbTriBTotal = NbTriATotal;
172 NbTriATotal = Nb;
173 Nb = NbFaces2;
174 NbFaces2 = NbFaces1;
175 NbFaces1 = Nb;
176 }
177
178 //-----------------------------------------------------------------
179 //-- Tableaux des sommets des NbTriATotal triangles du shape 1
180 //-----------------------------------------------------------------
181 TColgp_Array1OfPnt TA1(1,NbTriATotal);
182 TColgp_Array1OfPnt TA2(1,NbTriATotal);
183 TColgp_Array1OfPnt TA3(1,NbTriATotal);
184 //-----------------------------------------------------------------
185 //-- Tableaux des MinMax des NbTriATotal triangles du shape 1
186 //-----------------------------------------------------------------
187 TColStd_Array1OfReal MinAx(1,NbTriATotal);
188 TColStd_Array1OfReal MinAy(1,NbTriATotal);
189 TColStd_Array1OfReal MinAz(1,NbTriATotal);
190 TColStd_Array1OfReal MaxAx(1,NbTriATotal);
191 TColStd_Array1OfReal MaxAy(1,NbTriATotal);
192 TColStd_Array1OfReal MaxAz(1,NbTriATotal);
193 //-----------------------------------------------------------------
194 //-- Tableaux des MinMax des NbFaces1 faces du shape 1
195 //-----------------------------------------------------------------
196 TColStd_Array1OfReal MinFAx(1,NbFaces1);
197 TColStd_Array1OfReal MinFAy(1,NbFaces1);
198 TColStd_Array1OfReal MinFAz(1,NbFaces1);
199 TColStd_Array1OfReal MaxFAx(1,NbFaces1);
200 TColStd_Array1OfReal MaxFAy(1,NbFaces1);
201 TColStd_Array1OfReal MaxFAz(1,NbFaces1);
202 //-----------------------------------------------------------------
203 //-- Tableau contenant le nombre de triangles des faces du shape 1
204 //-----------------------------------------------------------------
205 TColStd_Array1OfInteger TNbTr1(1,NbFaces1);
206
207 //-----------------------------------------------------------------
208 //-- Preparation : Mise a jour des tableaux et calcul des MinMax
209 //-----------------------------------------------------------------
210 NbTriATotal = NbFaces1 = 0;
211 for (ex1.Init(myShape1,TopAbs_FACE);ex1.More();ex1.Next()) {
212 Tr1 = (BRep_Tool::Triangulation(TopoDS::Face(ex1.Current()),Loc1));
213 if (!Tr1.IsNull()) {
214 NbTrian1 = Tr1->NbTriangles();
215 NbFaces1++;
216 TNbTr1.SetValue(NbFaces1,NbTrian1);
217 const Poly_Array1OfTriangle& TabTrian1 = Tr1->Triangles();
218 const TColgp_Array1OfPnt& TabNodes1 = Tr1->Nodes();
219 minfx = minfy = minfz = -Big;
220 maxfx = maxfy = maxfz = Big;
221 for (i = 1;i <= NbTrian1;i++) {
222 TabTrian1(i).Get(i1,i2,i3);
223 NbTriATotal++;
224 TA1.SetValue(NbTriATotal,TabNodes1(i1).Transformed(Loc1.Transformation()));
225 TA2.SetValue(NbTriATotal,TabNodes1(i2).Transformed(Loc1.Transformation()));
226 TA3.SetValue(NbTriATotal,TabNodes1(i3).Transformed(Loc1.Transformation()));
227 MINMAX(TA1.Value(NbTriATotal).X(),
228 TA2.Value(NbTriATotal).X(),
229 TA3.Value(NbTriATotal).X(),min,max);
230 MinAx.SetValue(NbTriATotal,min);
231 MaxAx.SetValue(NbTriATotal,max);
232 if (min < minfx) minfx = min;
233 if (max > maxfx) maxfx = max;
234 MINMAX(TA1.Value(NbTriATotal).Y(),
235 TA2.Value(NbTriATotal).Y(),
236 TA3.Value(NbTriATotal).Y(),min,max);
237 MinAy.SetValue(NbTriATotal,min);
238 MaxAy.SetValue(NbTriATotal,max);
239 if (min < minfy) minfy = min;
240 if (max > maxfy) maxfy = max;
241 MINMAX(TA1.Value(NbTriATotal).Z(),
242 TA2.Value(NbTriATotal).Z(),
243 TA3.Value(NbTriATotal).Z(),min,max);
244 MinAz.SetValue(NbTriATotal,min);
245 MaxAz.SetValue(NbTriATotal,max);
246 if (min < minfz) minfz = min;
247 if (max > maxfz) maxfz = max;
248 }
249 MinFAx.SetValue(NbFaces1,minfx);
250 MaxFAx.SetValue(NbFaces1,maxfx);
251 MinFAy.SetValue(NbFaces1,minfy);
252 MaxFAy.SetValue(NbFaces1,maxfy);
253 MinFAz.SetValue(NbFaces1,minfz);
254 MaxFAz.SetValue(NbFaces1,maxfz);
255 }
256 }
257
258 //-----------------------------------------------------------------
259 //-- Tableaux des sommets des NbTriBTotal triangles du shape 2
260 //-----------------------------------------------------------------
261 TColgp_Array1OfPnt TB1(1,NbTriBTotal);
262 TColgp_Array1OfPnt TB2(1,NbTriBTotal);
263 TColgp_Array1OfPnt TB3(1,NbTriBTotal);
264 //-----------------------------------------------------------------
265 //-- Tableaux des MinMax des NbTriBTotal triangles du shape 2
266 //-----------------------------------------------------------------
267 TColStd_Array1OfReal MinBx(1,NbTriBTotal);
268 TColStd_Array1OfReal MinBy(1,NbTriBTotal);
269 TColStd_Array1OfReal MinBz(1,NbTriBTotal);
270 TColStd_Array1OfReal MaxBx(1,NbTriBTotal);
271 TColStd_Array1OfReal MaxBy(1,NbTriBTotal);
272 TColStd_Array1OfReal MaxBz(1,NbTriBTotal);
273 //-----------------------------------------------------------------
274 //-- Tableaux des MinMax des NbFaces2 faces du shape 2
275 //-----------------------------------------------------------------
276 TColStd_Array1OfReal MinFBx(1,NbFaces2);
277 TColStd_Array1OfReal MinFBy(1,NbFaces2);
278 TColStd_Array1OfReal MinFBz(1,NbFaces2);
279 TColStd_Array1OfReal MaxFBx(1,NbFaces2);
280 TColStd_Array1OfReal MaxFBy(1,NbFaces2);
281 TColStd_Array1OfReal MaxFBz(1,NbFaces2);
282 //-----------------------------------------------------------------
283 //-- Tableau contenant le nombre de triangles des faces du shape 2
284 //-----------------------------------------------------------------
285 TColStd_Array1OfInteger TNbTr2(1,NbFaces2);
286
287 //-----------------------------------------------------------------
288 //-- Preparation : Mise a jour des tableaux et calcul des MinMax
289 //-----------------------------------------------------------------
290 NbTriBTotal = NbFaces2 = 0;
291 for (ex2.Init(myShape2,TopAbs_FACE);ex2.More();ex2.Next()) {
292 Tr2 = (BRep_Tool::Triangulation(TopoDS::Face(ex2.Current()),Loc2));
293 if (!Tr2.IsNull()) {
294 NbTrian2 = Tr2->NbTriangles();
295 NbFaces2++;
296 TNbTr2.SetValue(NbFaces2,NbTrian2);
297 const Poly_Array1OfTriangle& TabTrian2 = Tr2->Triangles();
298 const TColgp_Array1OfPnt& TabNodes2 = Tr2->Nodes();
299 minfx = minfy = minfz = -Big;
300 maxfx = maxfy = maxfz = Big;
301 for (j = 1;j <= NbTrian2;j++) {
302 TabTrian2(j).Get(j1,j2,j3);
303 NbTriBTotal++;
304 TB1.SetValue(NbTriBTotal,TabNodes2(j1).Transformed(Loc2.Transformation()));
305 TB2.SetValue(NbTriBTotal,TabNodes2(j2).Transformed(Loc2.Transformation()));
306 TB3.SetValue(NbTriBTotal,TabNodes2(j3).Transformed(Loc2.Transformation()));
307 MINMAX(TB1.Value(NbTriBTotal).X(),
308 TB2.Value(NbTriBTotal).X(),
309 TB3.Value(NbTriBTotal).X(),min,max);
310 MinBx.SetValue(NbTriBTotal,min);
311 MaxBx.SetValue(NbTriBTotal,max);
312 if (min < minfx) minfx = min;
313 if (max > maxfx) maxfx = max;
314 MINMAX(TB1.Value(NbTriBTotal).Y(),
315 TB2.Value(NbTriBTotal).Y(),
316 TB3.Value(NbTriBTotal).Y(),min,max);
317 MinBy.SetValue(NbTriBTotal,min);
318 MaxBy.SetValue(NbTriBTotal,max);
319 if (min < minfy) minfy = min;
320 if (max > maxfy) maxfy = max;
321 MINMAX(TB1.Value(NbTriBTotal).Z(),
322 TB2.Value(NbTriBTotal).Z(),
323 TB3.Value(NbTriBTotal).Z(),min,max);
324 MinBz.SetValue(NbTriBTotal,min);
325 MaxBz.SetValue(NbTriBTotal,max);
326 if (min < minfz) minfz = min;
327 if (max > maxfz) maxfz = max;
328 }
329 MinFBx.SetValue(NbFaces2,minfx);
330 MaxFBx.SetValue(NbFaces2,maxfx);
331 MinFBy.SetValue(NbFaces2,minfy);
332 MaxFBy.SetValue(NbFaces2,maxfy);
333 MinFBz.SetValue(NbFaces2,minfz);
334 MaxFBz.SetValue(NbFaces2,maxfz);
335 }
336 }
337
338 Standard_Integer ii,jj,fi,fj;
339 i = j = 0;
340 for (fi = 1;fi <= NbFaces1;fi++) {
341 NbTrian1 = TNbTr1.Value(fi);
342 i += NbTrian1;
343 j = 0;
344 for (fj = 1;fj <= NbFaces2;fj++) {
345 NbTrian2 = TNbTr2.Value(fj);
346 if (MinFAx.Value(fi) > MaxFBx.Value(fj) ||
347 MinFBx.Value(fj) > MaxFAx.Value(fi)) {
348 j += NbTrian2;
349 continue;
350 }
351 else {
352 if (MinFAy.Value(fi) > MaxFBy.Value(fj) ||
353 MinFBy.Value(fj) > MaxFAy.Value(fi)) {
354 j += NbTrian2;
355 continue;
356 }
357 else if (MinFAz.Value(fi) > MaxFBz.Value(fj) ||
358 MinFBz.Value(fj) > MaxFAz.Value(fi)) {
359 j += NbTrian2;
360 continue;
361 }
362 }
363 i -= NbTrian1;
364 j += NbTrian2;
365
366 for (ii = 1;ii <= NbTrian1;ii++) {
367 i++;
368 j -= NbTrian2;
369 const gp_Pnt& A1 = TA1.Value(i);
370 const gp_Pnt& A2 = TA2.Value(i);
371 const gp_Pnt& A3 = TA3.Value(i);
efef9da8 372 gp_Vec OA1(A1.X(), A1.Y(), A1.Z());
7fd59977 373 gp_Vec VA0 = gp_Vec(A1,A2);
374 gp_Vec VA = gp_Vec(A1,A3);
375 VA0.Cross(VA);
376 VA0.Normalize();
377
378 for (jj = 1;jj <= NbTrian2;jj++) {
379 j++;
380 if(MinAx.Value(i) > MaxBx.Value(j) ||
381 MinBx.Value(j) > MaxAx.Value(i)) {
382 continue;
383 }
384 else {
385 if (MinAy.Value(i) > MaxBy.Value(j) ||
386 MinBy.Value(j) > MaxAy.Value(i)) {
387 continue;
388 }
389 else if (MinAz.Value(i) > MaxBz.Value(j) ||
390 MinBz.Value(j) > MaxAz.Value(i)) {
391 continue;
392 }
393 }
394 const gp_Pnt& B1 = TB1.Value(j);
395 const gp_Pnt& B2 = TB2.Value(j);
396 const gp_Pnt& B3 = TB3.Value(j);
397 gp_Vec VB0(B1,B2);
398 gp_Vec VB(B1,B3);
399 VB0.Cross(VB);
400 VB0.Normalize();
401 gp_Vec OB1(B1.XYZ());
402 gp_Vec V1(B1,A1);
403 gp_Vec V2(B1,A2);
404 gp_Vec V3(B1,A3);
405 Standard_Real h1 = VB0.Dot(V1);
406 Standard_Real h2 = VB0.Dot(V2);
407 Standard_Real h3 = VB0.Dot(V3);
408 Standard_Real ah1 = Abs(h1);
409 Standard_Real ah2 = Abs(h2);
410 Standard_Real ah3 = Abs(h3);
411
412 if(!SAMESIGN(h1,h2,h3)) {
413 myFirstTime = Standard_True;
414 if (h1 == 0.0) {
415 if (IsInside(A1,B1,B2,B3,VB0)) {
416 myFirstTime = Standard_False;
417 myBegPoint = A1;
418 if (h2 == 0.0) {
419 if (IsInside(A2,B1,B2,B3,VB0)) {
420 if (!IsEqual(A2,myBegPoint)) {
421 myEndPoint = A2;
422 InsertInMap();
423 continue;
424 }
425 }
426 }
427 if (h3 == 0.0) {
428 if (IsInside(A3,B1,B2,B3,VB0)) {
429 if (!IsEqual(A3,myBegPoint)) {
430 myEndPoint = A3;
431 InsertInMap();
432 continue;
433 }
434 }
435 }
436 }
437 }
438 if (h2 == 0.0) { // h1 <> 0
439 if (IsInside(A2,B1,B2,B3,VB0)) {
440 myFirstTime = Standard_False;
441 myBegPoint = A2;
442 if (h3 == 0.0) {
443 if (IsInside(A3,B1,B2,B3,VB0)) {
444 if (!IsEqual(A3,myBegPoint)) {
445 myEndPoint = A3;
446 InsertInMap();
447 continue;
448 }
449 }
450 }
451 }
452 }
453 if (h3 == 0.0) { // h1 <> 0 and h2 <> 0
454 if (IsInside(A3,B1,B2,B3,VB0)) {
455 myFirstTime = Standard_False;
456 myBegPoint = A3;
457 }
458 }
459 if (Intersect(B1,B2,B3,OB1,VB0,V1,V2,h1,h2,ah1,ah2))
460 continue;
461 if (Intersect(B1,B2,B3,OB1,VB0,V2,V3,h2,h3,ah2,ah3))
462 continue;
463 if (Intersect(B1,B2,B3,OB1,VB0,V3,V1,h3,h1,ah3,ah1))
464 continue;
465
466 V1 = gp_Vec(A1,B1);
467 V2 = gp_Vec(A1,B2);
468 V3 = gp_Vec(A1,B3);
469 h1 = VA0.Dot(V1);
470 h2 = VA0.Dot(V2);
471 h3 = VA0.Dot(V3);
472 ah1 = Abs(h1);
473 ah2 = Abs(h2);
474 ah3 = Abs(h3);
475
476 if(!SAMESIGN(h1,h2,h3)) {
477 if (h1 == 0.0) {
478 if (IsInside(B1,A1,A2,A3,VA0)) {
479 if (myFirstTime) {
480 myFirstTime = Standard_False;
481 myBegPoint = B1;
482 }
483 else {
484 if (!IsEqual(B1,myBegPoint)) {
485 myEndPoint = B1;
486 InsertInMap();
487 continue;
488 }
489 }
490 if (h2 == 0.0) {
491 if (IsInside(B2,A1,A2,A3,VA0)) {
492 if (!IsEqual(B2,myBegPoint)) {
493 myEndPoint = B2;
494 InsertInMap();
495 continue;
496 }
497 }
498 }
499 if (h3 == 0.0) {
500 if (IsInside(B3,A1,A2,A3,VA0)) {
501 if (!IsEqual(B3,myBegPoint)) {
502 myEndPoint = B3;
503 InsertInMap();
504 continue;
505 }
506 }
507 }
508 }
509 }
510 if (h2 == 0.0) { // h1 <> 0
511 if (IsInside(B2,A1,A2,A3,VA0)) {
512 if (myFirstTime) {
513 myFirstTime = Standard_False;
514 myBegPoint = B2;
515 }
516 else {
517 if (!IsEqual(B2,myBegPoint)) {
518 myEndPoint = B2;
519 InsertInMap();
520 continue;
521 }
522 }
523 if (h3 == 0.0) {
524 if (IsInside(B3,A1,A2,A3,VA0)) {
525 if (!IsEqual(B3,myBegPoint)) {
526 myEndPoint = B3;
527 InsertInMap();
528 continue;
529 }
530 }
531 }
532 }
533 }
534 if (h3 == 0.0) { // h1 <> 0 and h2 <> 0
535 if (IsInside(B3,A1,A2,A3,VA0)) {
536 if (myFirstTime) {
537 myBegPoint = B3;
538 myFirstTime = Standard_False;
539 }
540 else {
541 if (!IsEqual(B3,myBegPoint)) {
542 myEndPoint = B3;
543 InsertInMap();
544 continue;
545 }
546 }
547 }
548 }
549 if (Intersect(A1,A2,A3,OA1,VA0,V1,V2,h1,h2,ah1,ah2))
550 continue;
551 if (Intersect(A1,A2,A3,OA1,VA0,V2,V3,h2,h3,ah2,ah3))
552 continue;
553 if (Intersect(A1,A2,A3,OA1,VA0,V3,V1,h3,h1,ah3,ah1))
554 continue;
555 }
556 }
557 }
558 }
559 }
560 }
561}
562
563//=======================================================================
564//function : Intersect
565//purpose :
566//=======================================================================
567#define DIFFSIGN(a,b) (((a)>0.0 && (b)<0.0) || ((a)<0.0 && (b)>0.0))
568
569Standard_Boolean IntPoly_ShapeSection::Intersect(const gp_Pnt& S1,
570 const gp_Pnt& S2,
571 const gp_Pnt& S3,
572 const gp_Vec& OS1,
573 const gp_Vec& VS0,
574 const gp_Vec& V1,
575 const gp_Vec& V2,
576 Standard_Real& h1,
577 Standard_Real& h2,
578 Standard_Real& ah1,
579 Standard_Real& ah2)
580{
581 if (DIFFSIGN(h1,h2)) {
582 gp_XYZ OP;
583 OP.SetLinearForm(ah2/(ah1+ah2),V1.XYZ(),
584 ah1/(ah1+ah2),V2.XYZ(),
585 OS1.XYZ());
586 gp_Pnt P(OP.X(),OP.Y(),OP.Z());
587 if (IsInside(P,S1,S2,S3,VS0)) {
588 if (myFirstTime) {
589 myFirstTime = Standard_False;
590 myBegPoint = P;
591 }
592 else {
593 if (!IsEqual(P,myBegPoint)) {
594 myEndPoint = P;
595 InsertInMap();
596 return (Standard_True);
597 }
598 }
599 }
600 }
601 return (Standard_False);
602}
603
604
605//=======================================================================
606//function : IsEqual
607//purpose :
608//=======================================================================
609#define epsilon 0.000000000001
610
0ebaa4db 611Standard_Boolean IntPoly_ShapeSection::IsEqual(const gp_Pnt& Pt1, const gp_Pnt& Pt2)
7fd59977 612{
0ebaa4db 613 return (((Pt1.X() <= Pt2.X() && Pt2.X() < Pt1.X()+epsilon) ||
614 (Pt2.X() <= Pt1.X() && Pt1.X() < Pt2.X()+epsilon)) &&
615 ((Pt1.Y() <= Pt2.Y() && Pt2.Y() < Pt1.Y()+epsilon) ||
616 (Pt2.Y() <= Pt1.Y() && Pt1.Y() < Pt2.Y()+epsilon)) &&
617 ((Pt1.Z() <= Pt2.Z() && Pt2.Z() < Pt1.Z()+epsilon) ||
618 (Pt2.Z() <= Pt1.Z() && Pt1.Z() < Pt2.Z()+epsilon)));
7fd59977 619}
620
621
622//=======================================================================
623//function : IsInside
624//purpose :
625//=======================================================================
626
627static Standard_Boolean IsInside1(Standard_Real PU,
628 Standard_Real PV,
629 Standard_Real *Pu,
630 Standard_Real *Pv)
631{
632 Standard_Real u = Pu[0] - PU;
633 Standard_Real v = Pv[0] - PV;
634 Standard_Real nu,nv;
635 Standard_Integer SH = (v < 0.0)? -1 : 1;
636 Standard_Integer NH,i,ip1 = 1;
637 Standard_Integer NbCrossing = 0;
638
639 for (i = 0;i < 3;i++,ip1++) {
640 nu = Pu[ip1] - PU;
641 nv = Pv[ip1] - PV;
642 NH = (nv < 0.0)? -1 : 1;
643 if (NH != SH) {
644 if (u > 0.0 && nu > 0.0) NbCrossing++;
645 else if (u > 0.0 || nu > 0.0)
646 if ((u - v * (nu - u) / (nv - v)) > 0.0) NbCrossing++;
647 SH = NH;
648 }
649 u = nu;
650 v = nv;
651 }
652 return (NbCrossing & 1);
653}
654
655#define TOLBRUIT 0.00000000000001
656
657Standard_Boolean IntPoly_ShapeSection::IsInside(const gp_Pnt& P,
658 const gp_Pnt& P1,
659 const gp_Pnt& P2,
660 const gp_Pnt& P3,
661 const gp_Vec& N0)
662{
663 if (IsEqual(P,P1) || IsEqual(P,P2) || IsEqual(P,P3))
664 return(Standard_True);
665 Standard_Real Nx = Abs(N0.X());
666 Standard_Real Ny = Abs(N0.Y());
667 Standard_Real Nz = Abs(N0.Z());
668 Standard_Real PU,PV,Pu[4],Pv[4];
669 Standard_Integer Ind = 1; //-- 1:x 2:y 3:z
670 if (Nx > Ny) { //-- x or z
671 if (Nx > Nz) Ind = 1;
672 else Ind = 3;
673 }
674 else { //-- y or z
675 if (Ny > Nz) Ind = 2;
676 else Ind = 3;
677 }
678 if (Ind == 1) {
679 PU = P.Y();
680 PV = P.Z();
681 Pu[0] = Pu[3] = P1.Y();
682 Pv[0] = Pv[3] = P1.Z();
683 Pu[1] = P2.Y();
684 Pv[1] = P2.Z();
685 Pu[2] = P3.Y();
686 Pv[2] = P3.Z();
687 }
688 else if (Ind == 2) {
689 PU = P.Z();
690 PV = P.X();
691 Pu[0] = Pu[3] = P1.Z();
692 Pv[0] = Pv[3] = P1.X();
693 Pu[1] = P2.Z();
694 Pv[1] = P2.X();
695 Pu[2] = P3.Z();
696 Pv[2] = P3.X();
697 }
698 else {
699 PU = P.X();
700 PV = P.Y();
701 Pu[0] = Pu[3] = P1.X();
702 Pv[0] = Pv[3] = P1.Y();
703 Pu[1] = P2.X();
704 Pv[1] = P2.Y();
705 Pu[2] = P3.X();
706 Pv[2] = P3.Y();
707 }
708 if (IsInside1(PU,PV,Pu,Pv))
709 return(Standard_True);
710
711 if (IsInside1(PU+TOLBRUIT,PV,Pu,Pv))
712 return(Standard_True);
713
714 if (IsInside1(PU-TOLBRUIT,PV,Pu,Pv))
715 return(Standard_True);
716
717 if (IsInside1(PU,PV+TOLBRUIT,Pu,Pv))
718 return(Standard_True);
719
720 if (IsInside1(PU,PV-TOLBRUIT,Pu,Pv))
721 return(Standard_True);
722
723 return(Standard_False);
724}
725
726
727//=======================================================================
728//function : InsertInMap
729//purpose :
730//=======================================================================
731
732void IntPoly_ShapeSection::InsertInMap()
733{
734 Standard_Integer Index;
735 Standard_Real Big = Precision::Infinite();
736
737 if (myMapBegPoints.Contains(myBegPoint)) {
738 Index = myMapBegPoints.FindIndex(myBegPoint);
739 Insert(myMapEndPoints.FindKey(Index),myBegPoint,myEndPoint);
740 myCpt++;
741 myMapBegPoints.Substitute(Index,gp_Pnt(Big,myCpt,myCpt));
742 myMapEndPoints.Substitute(Index,gp_Pnt(Big,myCpt,myCpt));
743 }
744 else if (myMapEndPoints.Contains(myEndPoint)) {
745 Index = myMapEndPoints.FindIndex(myEndPoint);
746 Insert(myMapBegPoints.FindKey(Index),myEndPoint,myBegPoint);
747 myCpt++;
748 myMapBegPoints.Substitute(Index,gp_Pnt(Big,myCpt,myCpt));
749 myMapEndPoints.Substitute(Index,gp_Pnt(Big,myCpt,myCpt));
750 }
751 else {
752 myMapBegPoints.Add(myBegPoint);
753 myMapEndPoints.Add(myEndPoint);
754 }
755}
756
757
758//=======================================================================
759//function : Insert
760//purpose :
761//=======================================================================
762
763void IntPoly_ShapeSection::Insert(const gp_Pnt& OldPnt,
764 const gp_Pnt& ComPnt,
765 const gp_Pnt& NewPnt)
766{
767 Standard_Integer i = 0;
768 Standard_Integer NbSection = mySection.Length();
769 Standard_Boolean IsInSection = Standard_False;
770
771 while (i < NbSection) {
772 i++;
773 TColgp_SequenceOfPnt& CurSection = mySection.ChangeValue(i);
774 if (IsEqual(OldPnt,CurSection.First())) {
775 IsInSection = Standard_True;
776 CurSection.Prepend(ComPnt);
777 CurSection.Prepend(NewPnt);
778 break;
779 }
780 if (IsEqual(OldPnt,CurSection.Last())) {
781 IsInSection = Standard_True;
782 CurSection.Append(ComPnt);
783 CurSection.Append(NewPnt);
784 break;
785 }
786 if (IsEqual(NewPnt,CurSection.First())) {
787 IsInSection = Standard_True;
788 CurSection.Prepend(ComPnt);
789 CurSection.Prepend(OldPnt);
790 break;
791 }
792 if (IsEqual(NewPnt,CurSection.Last())) {
793 IsInSection = Standard_True;
794 CurSection.Append(ComPnt);
795 CurSection.Append(OldPnt);
796 break;
797 }
798 }
799 if (!(IsInSection)) {
800 TColgp_SequenceOfPnt EmptySec;
801 EmptySec.Append(OldPnt);
802 EmptySec.Append(ComPnt);
803 EmptySec.Append(NewPnt);
804 mySection.Append(EmptySec);
805 }
806}
807
808
809//=======================================================================
810//function : Concat
811//purpose :
812//=======================================================================
813
814Standard_Integer IntPoly_ShapeSection::Concat(const gp_Pnt& BegPnt,
815 const gp_Pnt& EndPnt,
816 gp_Pnt& OutPnt)
817{
818 Standard_Integer i = 0;
819 Standard_Integer NbSection = mySection.Length();
820 Standard_Integer ConcatIdx = 0;
821
822 while (i < NbSection) {
823 i++;
824 TColgp_SequenceOfPnt& CurSection = mySection.ChangeValue(i);
825 if (IsEqual(BegPnt,CurSection.First())) {
826 ConcatIdx = 1;
827 myIndex = i;
828 CurSection.Prepend(EndPnt);
829 OutPnt = EndPnt;
830 break;
831 }
832 if (IsEqual(BegPnt,CurSection.Last())) {
833 ConcatIdx = 2;
834 myIndex = i;
835 CurSection.Append(EndPnt);
836 OutPnt = EndPnt;
837 break;
838 }
839 if (IsEqual(EndPnt,CurSection.First())) {
840 ConcatIdx = 1;
841 myIndex = i;
842 CurSection.Prepend(BegPnt);
843 OutPnt = BegPnt;
844 break;
845 }
846 if (IsEqual(EndPnt,CurSection.Last())) {
847 ConcatIdx = 2;
848 myIndex = i;
849 CurSection.Append(BegPnt);
850 OutPnt = BegPnt;
851 break;
852 }
853 }
854 if (ConcatIdx == 0) {
855 TColgp_SequenceOfPnt EmptySec;
856 EmptySec.Append(BegPnt);
857 EmptySec.Append(EndPnt);
858 mySection.Append(EmptySec);
859 NbSection++;
860 myIndex = NbSection;
861 }
862 return ConcatIdx;
863}
864
865
866//=======================================================================
867//function : ConcatSection
868//purpose :
869//=======================================================================
870
871void IntPoly_ShapeSection::ConcatSection(TColgp_SequenceOfPnt& Section,
872 const Standard_Integer NbSection,
873 const Standard_Integer Index)
874{
875 Standard_Integer j;
876 Standard_Integer i = Index;
877 gp_Pnt BegPnt = Section.First();
878 gp_Pnt EndPnt = Section.Last();
879
880 while (i <= NbSection) {
881 TColgp_SequenceOfPnt& CurSection = mySection.ChangeValue(i);
882 Standard_Integer CurSection_Length = CurSection.Length();
883 if (IsEqual(BegPnt,CurSection.First())) {
884 for (j = 2;j <= CurSection_Length;j++)
885 Section.Prepend(CurSection.Value(j));
886 mySection.Remove(i);
887 ConcatSection(Section,NbSection-1,Index);
888 break;
889 }
890 else
891 if (IsEqual(BegPnt,CurSection.Last())) {
892 for (j = CurSection_Length-1;j >= 1;j--)
893 Section.Prepend(CurSection.Value(j));
894 mySection.Remove(i);
895 ConcatSection(Section,NbSection-1,Index);
896 break;
897 }
898 else
899 if (IsEqual(EndPnt,CurSection.First())) {
900 for (j = 2;j <= CurSection_Length;j++)
901 Section.Append(CurSection.Value(j));
902 mySection.Remove(i);
903 ConcatSection(Section,NbSection-1,Index);
904 break;
905 }
906 else
907 if (IsEqual(EndPnt,CurSection.Last())) {
908 for (j = CurSection_Length-1;j >= 1;j--)
909 Section.Append(CurSection.Value(j));
910 mySection.Remove(i);
911 ConcatSection(Section,NbSection-1,Index);
912 break;
913 }
914 i++;
915 }
916}
917
918
919//=======================================================================
920//function : ForwContruction
921//purpose :
922//=======================================================================
923
924void IntPoly_ShapeSection::ForwConstruction(const gp_Pnt& Point)
925{
926 if (myMapBegPoints.Contains(Point)) {
927 Standard_Integer Index = myMapBegPoints.FindIndex(Point);
928 gp_Pnt Pnt = myMapEndPoints.FindKey(Index);
929 (mySection.ChangeValue(myIndex)).Append(Pnt);
930 Standard_Real Big = Precision::Infinite();
931 myCpt++;
932 myMapBegPoints.Substitute(Index,gp_Pnt(Big,myCpt,myCpt));
933 myMapEndPoints.Substitute(Index,gp_Pnt(Big,myCpt,myCpt));
934 ForwConstruction(Pnt);
935 }
936}
937
938
939//=======================================================================
940//function : PrevContruction
941//purpose :
942//=======================================================================
943
944void IntPoly_ShapeSection::PrevConstruction(const gp_Pnt& Point)
945{
946 if (myMapEndPoints.Contains(Point)) {
947 Standard_Integer Index = myMapEndPoints.FindIndex(Point);
948 gp_Pnt Pnt = myMapBegPoints.FindKey(Index);
949 (mySection.ChangeValue(myIndex)).Prepend(Pnt);
950 Standard_Real Big = Precision::Infinite();
951 myCpt++;
952 myMapBegPoints.Substitute(Index,gp_Pnt(Big,myCpt,myCpt));
953 myMapEndPoints.Substitute(Index,gp_Pnt(Big,myCpt,myCpt));
954 PrevConstruction(Pnt);
955 }
956}
957
958
959//=======================================================================
960//function : NbEdges
961//purpose :
962//=======================================================================
963
964Standard_Integer IntPoly_ShapeSection::NbEdges()
965{ return myNbEdges; }
966
967
968//=======================================================================
969//function : Edge
970//purpose :
971//=======================================================================
972
973TopoDS_Edge IntPoly_ShapeSection::Edge(const Standard_Integer Index)
974{
975 const TColgp_SequenceOfPnt& CurSection = mySection.ChangeValue(Index);
976 Standard_Integer NbPoints = CurSection.Length();
977 TColgp_Array1OfPnt TabPnt(1,NbPoints);
978 //gp_Pnt CurPoint;
979 for (Standard_Integer i = 1 ; i <= NbPoints ; i++) {
980 TabPnt.SetValue(i,CurSection.Value(i));
981 }
982 Handle(Poly_Polygon3D) Pol = new Poly_Polygon3D(TabPnt);
983 TopoDS_Edge Edge;
984 BRep_Builder B;
985 B.MakeEdge(Edge,Pol);
986 return Edge;
987}
988
989
990
991
992
993
994