Update testing case for issue 0024499
[occt.git] / src / IntPoly / IntPoly_PlaneSection.cxx
CommitLineData
b311480e 1// Created on: 1995-07-17
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_PlaneSection.ixx>
18
19#include <IntPoly_SequenceOfSequenceOfPnt2d.hxx>
20#include <IntPoly_IndexedMapOfPnt2d.hxx>
21#include <IntPoly_Pnt2dHasher.hxx>
22#include <Precision.hxx>
23#include <TopExp_Explorer.hxx>
24#include <TopoDS_Shape.hxx>
25#include <TopoDS_Edge.hxx>
26#include <BRep_Tool.hxx>
27#include <BRep_Builder.hxx>
28#include <TopoDS.hxx>
29#include <Poly_Triangulation.hxx>
30#include <Poly_Polygon3D.hxx>
31#include <OSD_Chronometer.hxx>
32
33
34//=======================================================================
35//function : IntPoly_PlaneSection
36//purpose :
37//=======================================================================
38
39IntPoly_PlaneSection::IntPoly_PlaneSection()
40{}
41
42
43//=======================================================================
44//function : IntPoly_PlaneSection
45//purpose :
46//=======================================================================
47
48IntPoly_PlaneSection::IntPoly_PlaneSection(const TopoDS_Shape& S,
49 const gp_Pln& P)
50{
51 myShape = S;
52 myTransform.SetTransformation(P.Position());
53 gp_Ax3 Ax0(gp_Pnt(0,0,0),gp_Dir(0,0,1));
54 myBackTransform.SetTransformation(P.Position(),Ax0);
55 Section();
56}
57
58
59//=======================================================================
60//function : Section
61//purpose :
62//=======================================================================
63
64void IntPoly_PlaneSection::Section()
65{
66 TopExp_Explorer ex;
67 Standard_Integer NbTrian,i,i1,i2,i3,Result;
68 Standard_Real Big = Precision::Infinite();
69 Standard_Boolean Inter;
70 //gp_Pnt Nod1,Nod2,Nod3;
71 gp_Pnt2d BegPoint,EndPoint,OutPoint;
72 TopLoc_Location Loc;
73 Handle(Poly_Triangulation) Tr;
74 myCpt = 0;
75
76 for (ex.Init(myShape,TopAbs_FACE);ex.More();ex.Next()) {
77 Tr = (BRep_Tool::Triangulation(TopoDS::Face(ex.Current()),Loc));
78 if (!Tr.IsNull()) {
79 NbTrian = Tr->NbTriangles();
80 const Poly_Array1OfTriangle& TabTrian = Tr->Triangles();
81 const TColgp_Array1OfPnt& TabNodes = Tr->Nodes();
82 TColgp_Array1OfPnt TabTransfNodes(1,Tr->NbNodes());
83 for (i = 1;i <= Tr->NbNodes();i++) {
84 if (!Loc.IsIdentity())
85 TabTransfNodes(i) =
86 (TabNodes(i).Transformed(Loc.Transformation()))
87 .Transformed(myTransform);
88 else
89 TabTransfNodes(i) = TabNodes(i).Transformed(myTransform);
90 }
91 for (i = 1;i <= NbTrian;i++) {
92 TabTrian(i).Get(i1,i2,i3);
93 Inter = Intersect(TabTransfNodes(i1),
94 TabTransfNodes(i2),
95 TabTransfNodes(i3),
96 BegPoint,EndPoint);
97 if (Inter) {
98 if (myMapBegPoints.Contains(BegPoint)) {
99 Standard_Integer Index = myMapBegPoints.FindIndex(BegPoint);
100 Insert(myMapEndPoints.FindKey(Index),BegPoint,EndPoint);
101 myCpt++;
102 myMapBegPoints.Substitute(Index,gp_Pnt2d(Big,myCpt));
103 myMapEndPoints.Substitute(Index,gp_Pnt2d(Big,myCpt));
104 }
105 else if (myMapEndPoints.Contains(EndPoint)) {
106 Standard_Integer Index = myMapEndPoints.FindIndex(EndPoint);
107 Insert(myMapBegPoints.FindKey(Index),EndPoint,BegPoint);
108 myCpt++;
109 myMapBegPoints.Substitute(Index,gp_Pnt2d(Big,myCpt));
110 myMapEndPoints.Substitute(Index,gp_Pnt2d(Big,myCpt));
111 }
112 else {
113 myMapBegPoints.Add(BegPoint);
114 myMapEndPoints.Add(EndPoint);
115 }
116 }
117 }
118 }
119 }
120
121 Standard_Integer NbLinks = myMapBegPoints.Extent();
122 i = 1;
123 while (i <= NbLinks) {
124 if (!(Precision::IsInfinite((myMapBegPoints.FindKey(i)).X()))) {
125 BegPoint = myMapBegPoints.FindKey(i);
126 EndPoint = myMapEndPoints.FindKey(i);
127 myCpt++;
128 myMapBegPoints.Substitute(i,gp_Pnt2d(Big,myCpt));
129 myMapEndPoints.Substitute(i,gp_Pnt2d(Big,myCpt));
130 Result = Concat(BegPoint,EndPoint,OutPoint);
131 if (Result == 2)
132 ForwConstruction(OutPoint);
133 else
134 if (Result == 1)
135 PrevConstruction(OutPoint);
136 else {
137 ForwConstruction(EndPoint);
138 PrevConstruction(BegPoint);
139 }
140 }
141 i++;
142 }
143
144 i = 1;
145 while (i < mySection.Length()) {
146 ConcatSection(mySection.ChangeValue(i),mySection.Length(),i+1);
147 i++;
148 }
149 myNbEdges = mySection.Length();
150}
151
152
153//=======================================================================
154//function : Intersect
155//purpose : Determines the 2 2D-points resulting of the intersection
156// of the triangle (Point1,Point2,Point3) by the plane
157//=======================================================================
158
159Standard_Boolean IntPoly_PlaneSection::Intersect(const gp_Pnt& Point1,
160 const gp_Pnt& Point2,
161 const gp_Pnt& Point3,
162 gp_Pnt2d& OutPoint1,
163 gp_Pnt2d& OutPoint2)
164{
165 gp_Pnt Pt1 = Point1;
166 gp_Pnt Pt2 = Point2;
167 gp_Pnt Pt3 = Point3;
168 Standard_Real z1 = Pt1.Z();
169 Standard_Real z2 = Pt2.Z();
170 Standard_Real z3 = Pt3.Z();
171 Standard_Boolean intersection = Standard_False;
172
173 if ((z1 == 0) && (z2 == 0) && (z3 == 0))
174 return intersection;
175 if ((z1 == 0) && (z2 == 0)) {
176 intersection = Standard_True;
177 OutPoint1.SetCoord(Pt1.X(),Pt1.Y());
178 OutPoint2.SetCoord(Pt2.X(),Pt2.Y());
179 return intersection;
180 }
181 if ((z2 == 0) && (z3 == 0)) {
182 intersection = Standard_True;
183 OutPoint1.SetCoord(Pt2.X(),Pt2.Y());
184 OutPoint2.SetCoord(Pt3.X(),Pt3.Y());
185 return intersection;
186 }
187 if ((z3 == 0) && (z1 == 0)) {
188 intersection = Standard_True;
189 OutPoint1.SetCoord(Pt3.X(),Pt3.Y());
190 OutPoint2.SetCoord(Pt1.X(),Pt1.Y());
191 return intersection;
192 }
193 if (z1 == 0) {
194 if ((z2 < 0) && (z3 > 0))
195 intersection = Standard_True;
196 if ((z2 > 0) && (z3 < 0)) {
197 intersection = Standard_True;
198 gp_Pnt Pt = Pt2;
199 Pt2 = Pt3;
200 Pt3 = Pt;
201 }
202 if (intersection) {
203 Standard_Real u1 = Pt2.X();
204 Standard_Real v1 = Pt2.Y();
205 z1 = Pt2.Z();
206 Standard_Real u2 = Pt3.X();
207 Standard_Real v2 = Pt3.Y();
208 z2 = Pt3.Z();
209 Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1);
210 Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1);
211 OutPoint1.SetCoord(Pt1.X(),Pt1.Y());
212 OutPoint2.SetCoord(U,V);
213 return intersection;
214 }
215 }
216 else
217 if (z2 == 0) {
218 if ((z1 < 0) && (z3 > 0))
219 intersection = Standard_True;
220 if ((z1 > 0) && (z3 < 0)) {
221 intersection = Standard_True;
222 gp_Pnt Pt = Pt1;
223 Pt1 = Pt3;
224 Pt3 = Pt;
225 }
226 if (intersection) {
227 Standard_Real u1 = Pt1.X();
228 Standard_Real v1 = Pt1.Y();
229 z1 = Pt1.Z();
230 Standard_Real u2 = Pt3.X();
231 Standard_Real v2 = Pt3.Y();
232 z2 = Pt3.Z();
233 Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1);
234 Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1);
235 OutPoint1.SetCoord(Pt2.X(),Pt2.Y());
236 OutPoint2.SetCoord(U,V);
237 return intersection;
238 }
239 }
240 else
241 if (z3 == 0) {
242 if ((z2 < 0) && (z1 > 0))
243 intersection = Standard_True;
244 if ((z2 > 0) && (z1 < 0)) {
245 intersection = Standard_True;
246 gp_Pnt Pt = Pt2;
247 Pt2 = Pt1;
248 Pt1 = Pt;
249 }
250 if (intersection) {
251 Standard_Real u1 = Pt2.X();
252 Standard_Real v1 = Pt2.Y();
253 z1 = Pt2.Z();
254 Standard_Real u2 = Pt1.X();
255 Standard_Real v2 = Pt1.Y();
256 z2 = Pt1.Z();
257 Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1);
258 Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1);
259 OutPoint1.SetCoord(Pt3.X(),Pt3.Y());
260 OutPoint2.SetCoord(U,V);
261 return intersection;
262 }
263 }
264
265 if ((z1 < 0) && (z2 > 0))
266 intersection = Standard_True;
267 if ((z1 > 0) && (z2 < 0)) {
268 intersection = Standard_True;
269 gp_Pnt Pt = Pt1;
270 Pt1 = Pt2;
271 Pt2 = Pt;
272 }
273 if (intersection) {
274 Standard_Real u1 = Pt1.X();
275 Standard_Real v1 = Pt1.Y();
276 z1 = Pt1.Z();
277 Standard_Real u2 = Pt2.X();
278 Standard_Real v2 = Pt2.Y();
279 z2 = Pt2.Z();
280 Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1);
281 Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1);
282 OutPoint1.SetCoord(U,V);
283 intersection = Standard_False;
284 Pt1 = Point1;
285 Pt2 = Point2;
286 z1 = Pt1.Z();
287 z2 = Pt2.Z();
288 if ((z2 < 0) && (z3 > 0))
289 intersection = Standard_True;
290 if ((z2 > 0) && (z3 < 0)) {
291 intersection = Standard_True;
292 gp_Pnt Pt = Pt2;
293 Pt2 = Pt3;
294 Pt3 = Pt;
295 }
296 if (intersection) {
297 u1 = Pt2.X();
298 v1 = Pt2.Y();
299 z1 = Pt2.Z();
300 u2 = Pt3.X();
301 v2 = Pt3.Y();
302 z2 = Pt3.Z();
303 U = u1 - z1 * (u2 - u1)/(z2 - z1);
304 V = v1 - z1 * (v2 - v1)/(z2 - z1);
305 OutPoint2.SetCoord(U,V);
306 return intersection;
307 }
308 else {
309 intersection = Standard_True;
310 Pt3 = Point3;
311 z3 = Pt3.Z();
312 if ((z3 > 0) && (z1 < 0)) {
313 gp_Pnt Pt = Pt3;
314 Pt3 = Pt1;
315 Pt1 = Pt;
316 }
317 u1 = Pt3.X();
318 v1 = Pt3.Y();
319 z1 = Pt3.Z();
320 u2 = Pt1.X();
321 v2 = Pt1.Y();
322 z2 = Pt1.Z();
323 U = u1 - z1 * (u2 - u1)/(z2 - z1);
324 V = v1 - z1 * (v2 - v1)/(z2 - z1);
325 OutPoint2.SetCoord(U,V);
326 return intersection;
327 }
328 }
329 else {
330 if ((z2 < 0) && (z3 > 0))
331 intersection = Standard_True;
332 if ((z2 > 0) && (z3 < 0)) {
333 intersection = Standard_True;
334 gp_Pnt Pt = Pt2;
335 Pt2 = Pt3;
336 Pt3 = Pt;
337 }
338 if (intersection) {
339 Standard_Real u1 = Pt2.X();
340 Standard_Real v1 = Pt2.Y();
341 z1 = Pt2.Z();
342 Standard_Real u2 = Pt3.X();
343 Standard_Real v2 = Pt3.Y();
344 z2 = Pt3.Z();
345 Standard_Real U = u1 - z1 * (u2 - u1)/(z2 - z1);
346 Standard_Real V = v1 - z1 * (v2 - v1)/(z2 - z1);
347 OutPoint1.SetCoord(U,V);
348 Pt3 = Point3;
349 z3 = Pt3.Z();
350 if ((z3 > 0) && (z1 < 0)) {
351 gp_Pnt Pt = Pt3;
352 Pt3 = Pt1;
353 Pt1 = Pt;
354 }
355 u1 = Pt3.X();
356 v1 = Pt3.Y();
357 z1 = Pt3.Z();
358 u2 = Pt1.X();
359 v2 = Pt1.Y();
360 z2 = Pt1.Z();
361 U = u1 - z1 * (u2 - u1)/(z2 - z1);
362 V = v1 - z1 * (v2 - v1)/(z2 - z1);
363 OutPoint2.SetCoord(U,V);
364 return intersection;
365 }
366 }
367 return intersection;
368}
369
370
371//=======================================================================
372//function : Insert
373//purpose : Sees whether OldPnt and NewPnt begins or ends a section
374// created before and adds the 2 others points.
375// If not, creates a section
376//=======================================================================
377
378void IntPoly_PlaneSection::Insert(const gp_Pnt2d& OldPnt,
379 const gp_Pnt2d& ComPnt,
380 const gp_Pnt2d& NewPnt)
381{
382 Standard_Integer i = 0;
383 Standard_Integer NbSection = mySection.Length();
384 Standard_Boolean IsInSection = Standard_False;
385
386 while (i < NbSection) {
387 i++;
388 TColgp_SequenceOfPnt2d& CurSection = mySection.ChangeValue(i);
389 if (IntPoly_Pnt2dHasher::IsEqual(OldPnt,CurSection.First())) {
390 IsInSection = Standard_True;
391 CurSection.Prepend(ComPnt);
392 CurSection.Prepend(NewPnt);
393 break;
394 }
395 if (IntPoly_Pnt2dHasher::IsEqual(OldPnt,CurSection.Last())) {
396 IsInSection = Standard_True;
397 CurSection.Append(ComPnt);
398 CurSection.Append(NewPnt);
399 break;
400 }
401 if (IntPoly_Pnt2dHasher::IsEqual(NewPnt,CurSection.First())) {
402 IsInSection = Standard_True;
403 CurSection.Prepend(ComPnt);
404 CurSection.Prepend(OldPnt);
405 break;
406 }
407 if (IntPoly_Pnt2dHasher::IsEqual(NewPnt,CurSection.Last())) {
408 IsInSection = Standard_True;
409 CurSection.Append(ComPnt);
410 CurSection.Append(OldPnt);
411 break;
412 }
413 }
414 if (!(IsInSection)) {
415 TColgp_SequenceOfPnt2d EmptySec;
416 EmptySec.Append(OldPnt);
417 EmptySec.Append(ComPnt);
418 EmptySec.Append(NewPnt);
419 mySection.Append(EmptySec);
420 }
421}
422
423
424//=======================================================================
425//function : Concat
426//purpose : sees whether BegPnt or EndPnt begins or ends a section
427// created before, and returns the other point to continue
428// the construction
429// Returns 2 if the construction is 'Forward'
430// Returns 1 if the construction is 'Previous'
431// Returns 0 if not and creates a section
432//=======================================================================
433
434Standard_Integer IntPoly_PlaneSection::Concat(const gp_Pnt2d& BegPnt,
435 const gp_Pnt2d& EndPnt,
436 gp_Pnt2d& OutPnt)
437{
438 Standard_Integer i = 0;
439 Standard_Integer NbSection = mySection.Length();
440 Standard_Integer ConcatIdx = 0;
441
442 while (i < NbSection) {
443 i++;
444 TColgp_SequenceOfPnt2d& CurSection = mySection.ChangeValue(i);
445 if (IntPoly_Pnt2dHasher::IsEqual(BegPnt,CurSection.First())) {
446 ConcatIdx = 1;
447 myIndex = i;
448 CurSection.Prepend(EndPnt);
449 OutPnt = EndPnt;
450 break;
451 }
452 if (IntPoly_Pnt2dHasher::IsEqual(BegPnt,CurSection.Last())) {
453 ConcatIdx = 2;
454 myIndex = i;
455 CurSection.Append(EndPnt);
456 OutPnt = EndPnt;
457 break;
458 }
459 if (IntPoly_Pnt2dHasher::IsEqual(EndPnt,CurSection.First())) {
460 ConcatIdx = 1;
461 myIndex = i;
462 CurSection.Prepend(BegPnt);
463 OutPnt = BegPnt;
464 break;
465 }
466 if (IntPoly_Pnt2dHasher::IsEqual(EndPnt,CurSection.Last())) {
467 ConcatIdx = 2;
468 myIndex = i;
469 CurSection.Append(BegPnt);
470 OutPnt = BegPnt;
471 break;
472 }
473 }
474 if (ConcatIdx == 0) {
475 TColgp_SequenceOfPnt2d EmptySec;
476 EmptySec.Append(BegPnt);
477 EmptySec.Append(EndPnt);
478 mySection.Append(EmptySec);
479 NbSection++;
480 myIndex = NbSection;
481 }
482 return ConcatIdx;
483}
484
485
486//=======================================================================
487//function : ConcatSection
488//purpose : Sees whether Section begins or ends another one in mySection,
489// from the rank 'Index' to the last one 'NbSection'
490//=======================================================================
491
492void IntPoly_PlaneSection::ConcatSection(TColgp_SequenceOfPnt2d& Section,
493 const Standard_Integer NbSection,
494 const Standard_Integer Index)
495{
496 Standard_Integer j;
497 Standard_Integer i = Index;
498 gp_Pnt2d BegPnt = Section.First();
499 gp_Pnt2d EndPnt = Section.Last();
500
501 while (i <= NbSection) {
502 TColgp_SequenceOfPnt2d& CurSection = mySection.ChangeValue(i);
503 Standard_Integer CurSection_Length = CurSection.Length();
504 if (IntPoly_Pnt2dHasher::IsEqual(BegPnt,CurSection.First())) {
505 for (j = 2;j <= CurSection_Length;j++)
506 Section.Prepend(CurSection.Value(j));
507 mySection.Remove(i);
508 ConcatSection(Section,NbSection-1,Index);
509 break;
510 }
511 else
512 if (IntPoly_Pnt2dHasher::IsEqual(BegPnt,CurSection.Last())) {
513 for (j = CurSection_Length-1;j >= 1;j--)
514 Section.Prepend(CurSection.Value(j));
515 mySection.Remove(i);
516 ConcatSection(Section,NbSection-1,Index);
517 break;
518 }
519 else
520 if (IntPoly_Pnt2dHasher::IsEqual(EndPnt,CurSection.First())) {
521 for (j = 2;j <= CurSection_Length;j++)
522 Section.Append(CurSection.Value(j));
523 mySection.Remove(i);
524 ConcatSection(Section,NbSection-1,Index);
525 break;
526 }
527 else
528 if (IntPoly_Pnt2dHasher::IsEqual(EndPnt,CurSection.Last())) {
529 for (j = CurSection_Length-1;j >= 1;j--)
530 Section.Append(CurSection.Value(j));
531 mySection.Remove(i);
532 ConcatSection(Section,NbSection-1,Index);
533 break;
534 }
535 i++;
536 }
537}
538
539
540//=======================================================================
541//function : ForwContruction
542//purpose : Builds a section from Point in this way
543// ___ ___ ___ ___
544// <---/__/--/__/--/__/--/__/--Point
545//=======================================================================
546
547void IntPoly_PlaneSection::ForwConstruction(const gp_Pnt2d& Point)
548{
549 if (myMapBegPoints.Contains(Point)) {
550 Standard_Integer Index = myMapBegPoints.FindIndex(Point);
551 gp_Pnt2d Pnt = myMapEndPoints.FindKey(Index);
552 (mySection.ChangeValue(myIndex)).Append(Pnt);
553 Standard_Real Big = Precision::Infinite();
554 myCpt++;
555 myMapBegPoints.Substitute(Index,gp_Pnt2d(Big,myCpt));
556 myMapEndPoints.Substitute(Index,gp_Pnt2d(Big,myCpt));
557 ForwConstruction(Pnt);
558 }
559}
560
561
562//=======================================================================
563//function : PrevContruction
564//purpose : Builds a section from Point in this way
565// ___ ___ ___ ___
566// Point--/__/--/__/--/__/--/__/--->
567//=======================================================================
568
569void IntPoly_PlaneSection::PrevConstruction(const gp_Pnt2d& Point)
570{
571 if (myMapEndPoints.Contains(Point)) {
572 Standard_Integer Index = myMapEndPoints.FindIndex(Point);
573 gp_Pnt2d Pnt = myMapBegPoints.FindKey(Index);
574 (mySection.ChangeValue(myIndex)).Prepend(Pnt);
575 Standard_Real Big = Precision::Infinite();
576 myCpt++;
577 myMapBegPoints.Substitute(Index,gp_Pnt2d(Big,myCpt));
578 myMapEndPoints.Substitute(Index,gp_Pnt2d(Big,myCpt));
579 PrevConstruction(Pnt);
580 }
581}
582
583
584//=======================================================================
585//function : NbEdges
586//purpose : Returns the final number of edges in the section
587//=======================================================================
588
589Standard_Integer IntPoly_PlaneSection::NbEdges()
590{ return myNbEdges; }
591
592
593//=======================================================================
594//function : Edge
595//purpose : Builds the edges of the section
596//=======================================================================
597
598TopoDS_Edge IntPoly_PlaneSection::Edge(const Standard_Integer Index)
599{
600 const TColgp_SequenceOfPnt2d& CurSection = mySection.ChangeValue(Index);
601 Standard_Integer NbPoints = CurSection.Length();
602 TColgp_Array1OfPnt TabPnt(1,NbPoints);
603 gp_Pnt CurPoint;
604 for (Standard_Integer i = 1 ; i <= NbPoints ; i++) {
605 CurPoint.SetX((CurSection.Value(i)).X());
606 CurPoint.SetY((CurSection.Value(i)).Y());
607 CurPoint.SetZ(0);
608 TabPnt.SetValue(i,CurPoint.Transformed(myBackTransform));
609 }
610 Handle(Poly_Polygon3D) Pol = new Poly_Polygon3D(TabPnt);
611 TopoDS_Edge Edge;
612 BRep_Builder B;
613 B.MakeEdge(Edge,Pol);
614 return Edge;
615}
616
617
618
619
620
621
622
623