1 // Created on: 1993-01-11
2 // Created by: Christophe MARION
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <HLRAlgo_PolyData.hxx>
19 #include <HLRAlgo_EdgeStatus.hxx>
21 #include <Standard_Type.hxx>
23 IMPLEMENT_STANDARD_RTTIEXT(HLRAlgo_PolyData,MMgt_TShared)
25 #define EMskGrALin1 ((Standard_Integer) 8)
26 #define EMskGrALin2 ((Standard_Integer) 16)
27 #define EMskGrALin3 ((Standard_Integer) 32)
28 #define FMskHiding ((Standard_Integer) 256)
30 #define FIndex myIndices[0]
31 #define MinFac myIndices[1]
32 #define MaxFac myIndices[2]
34 #define TriNode1 ((Standard_Integer*)TriIndices)[0]
35 #define TriNode2 ((Standard_Integer*)TriIndices)[1]
36 #define TriNode3 ((Standard_Integer*)TriIndices)[2]
37 #define TriFlags ((Standard_Integer*)TriIndices)[3]
39 #define PntX1 ((Standard_Real*)Coordinates)[ 0]
40 #define PntY1 ((Standard_Real*)Coordinates)[ 1]
41 #define PntZ1 ((Standard_Real*)Coordinates)[ 2]
42 #define PntX2 ((Standard_Real*)Coordinates)[ 3]
43 #define PntY2 ((Standard_Real*)Coordinates)[ 4]
44 #define PntZ2 ((Standard_Real*)Coordinates)[ 5]
45 #define PntXP1 ((Standard_Real*)Coordinates)[ 6]
46 #define PntYP1 ((Standard_Real*)Coordinates)[ 7]
47 #define PntZP1 ((Standard_Real*)Coordinates)[ 8]
48 #define PntXP2 ((Standard_Real*)Coordinates)[ 9]
49 #define PntYP2 ((Standard_Real*)Coordinates)[10]
50 #define PntZP2 ((Standard_Real*)Coordinates)[11]
52 #define XV1 ((Standard_Real*)RealPtr)[0]
53 #define XV2 ((Standard_Real*)RealPtr)[1]
54 #define XV3 ((Standard_Real*)RealPtr)[2]
55 #define YV1 ((Standard_Real*)RealPtr)[3]
56 #define YV2 ((Standard_Real*)RealPtr)[4]
57 #define YV3 ((Standard_Real*)RealPtr)[5]
58 #define Param ((Standard_Real*)RealPtr)[6]
59 #define TolParam ((Standard_Real*)RealPtr)[7]
60 #define TolAng ((Standard_Real*)RealPtr)[8]
61 #define Tolerance ((Standard_Real*)RealPtr)[9]
63 #define TotXMin ((Standard_Real*)TotMinMax)[0]
64 #define TotYMin ((Standard_Real*)TotMinMax)[1]
65 #define TotZMin ((Standard_Real*)TotMinMax)[2]
66 #define TotXMax ((Standard_Real*)TotMinMax)[3]
67 #define TotYMax ((Standard_Real*)TotMinMax)[4]
68 #define TotZMax ((Standard_Real*)TotMinMax)[5]
70 #define IndexTri ((Standard_Integer*)MinMaxPtr)[0]
71 #define MinTri ((Standard_Integer*)MinMaxPtr)[1]
72 #define MaxTri ((Standard_Integer*)MinMaxPtr)[2]
74 #define APlan ((Standard_Real*)PlanPtr)[0]
75 #define BPlan ((Standard_Real*)PlanPtr)[1]
76 #define CPlan ((Standard_Real*)PlanPtr)[2]
77 #define DPlan ((Standard_Real*)PlanPtr)[3]
79 #define ShapeIndex ((Standard_Integer*)Indices)[0]
80 #define FaceConex1 ((Standard_Integer*)Indices)[1]
81 #define Face1Pt1 ((Standard_Integer*)Indices)[2]
82 #define Face1Pt2 ((Standard_Integer*)Indices)[3]
83 #define FaceConex2 ((Standard_Integer*)Indices)[4]
84 #define Face2Pt1 ((Standard_Integer*)Indices)[5]
85 #define Face2Pt2 ((Standard_Integer*)Indices)[6]
86 #define MinSeg ((Standard_Integer*)Indices)[7]
87 #define MaxSeg ((Standard_Integer*)Indices)[8]
88 #define SegFlags ((Standard_Integer*)Indices)[9]
90 static Standard_Integer ERROR = Standard_False;
92 //=======================================================================
95 //=======================================================================
97 HLRAlgo_PolyData::HLRAlgo_PolyData ()
100 //=======================================================================
103 //=======================================================================
105 void HLRAlgo_PolyData::HNodes(const Handle(TColgp_HArray1OfXYZ)& HNodes)
106 { myHNodes = HNodes; }
108 //=======================================================================
111 //=======================================================================
113 void HLRAlgo_PolyData::HTData(const Handle(HLRAlgo_HArray1OfTData)& HTData)
114 { myHTData = HTData; }
116 //=======================================================================
119 //=======================================================================
121 void HLRAlgo_PolyData::HPHDat(const Handle(HLRAlgo_HArray1OfPHDat)& HPHDat)
122 { myHPHDat = HPHDat; }
124 //=======================================================================
125 //function : UpdateGlobalMinMax
127 //=======================================================================
130 HLRAlgo_PolyData::UpdateGlobalMinMax (const Standard_Address TotMinMax)
133 Standard_Real X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3;
134 const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
135 HLRAlgo_Array1OfTData& TData = myHTData->ChangeArray1();
136 Standard_Integer nbT = TData.Upper();
137 HLRAlgo_TriangleData* TD = &(TData.ChangeValue(1));
139 for (i = 1; i <= nbT; i++) {
140 const Standard_Address TriIndices = TD->Indices();
141 if (TriFlags & FMskHiding) {
142 const gp_XYZ& P1 = Nodes(TriNode1);
143 const gp_XYZ& P2 = Nodes(TriNode2);
144 const gp_XYZ& P3 = Nodes(TriNode3);
154 if (TotXMin > X1) TotXMin = X1;
155 else if (TotXMax < X1) TotXMax = X1;
156 if (TotYMin > Y1) TotYMin = Y1;
157 else if (TotYMax < Y1) TotYMax = Y1;
158 if (TotZMin > Z1) TotZMin = Z1;
159 else if (TotZMax < Z1) TotZMax = Z1;
160 if (TotXMin > X2) TotXMin = X2;
161 else if (TotXMax < X2) TotXMax = X2;
162 if (TotYMin > Y2) TotYMin = Y2;
163 else if (TotYMax < Y2) TotYMax = Y2;
164 if (TotZMin > Z2) TotZMin = Z2;
165 else if (TotZMax < Z2) TotZMax = Z2;
166 if (TotXMin > X3) TotXMin = X3;
167 else if (TotXMax < X3) TotXMax = X3;
168 if (TotYMin > Y3) TotYMin = Y3;
169 else if (TotYMax < Y3) TotYMax = Y3;
170 if (TotZMin > Z3) TotZMin = Z3;
171 else if (TotZMax < Z3) TotZMax = Z3;
177 //=======================================================================
178 //function : HideByPolyData
180 //=======================================================================
182 void HLRAlgo_PolyData::HideByPolyData (const Standard_Address Coordinates,
183 const Standard_Address RealPtr,
184 const Standard_Address Indices,
185 const Standard_Boolean HidingShell,
186 HLRAlgo_EdgeStatus& status)
188 if (((MaxFac - MinSeg) & 0x80100200) == 0 &&
189 ((MaxSeg - MinFac) & 0x80100000) == 0) {
190 HLRAlgo_Array1OfPHDat& PHDat = myHPHDat->ChangeArray1();
191 const HLRAlgo_Array1OfTData& TData = myHTData->Array1();
193 Standard_Boolean NotConnex = Standard_False;
194 Standard_Boolean isCrossing = Standard_False;
195 Standard_Boolean toHideBefore = Standard_False;
196 Standard_Integer TFlag = 0;
197 Standard_Address PlanPtr,MinMaxPtr,TriIndices;
198 Standard_Integer h,h2 = PHDat.Upper();
199 HLRAlgo_PolyHidingData* PH = &(PHDat(1));
201 for (h = 1; h <= h2; h++) {
202 MinMaxPtr = PH->IndexAndMinMax();
203 if (((MaxTri - MinSeg) & 0x80100200) == 0 &&
204 ((MaxSeg - MinTri) & 0x80100000) == 0) {
205 TriIndices = TData(IndexTri).Indices();
206 NotConnex = Standard_True;
208 if (FIndex == FaceConex1) {
209 if (Face1Pt1 == TriNode1)
210 NotConnex = Face1Pt2 != TriNode2 && Face1Pt2 != TriNode3;
211 else if (Face1Pt1 == TriNode2)
212 NotConnex = Face1Pt2 != TriNode3 && Face1Pt2 != TriNode1;
213 else if (Face1Pt1 == TriNode3)
214 NotConnex = Face1Pt2 != TriNode1 && Face1Pt2 != TriNode2;
216 else if (FIndex == FaceConex2) {
217 if (Face2Pt1 == TriNode1)
218 NotConnex = Face2Pt2 != TriNode2 && Face2Pt2 != TriNode3;
219 else if (Face2Pt1 == TriNode2)
220 NotConnex = Face2Pt2 != TriNode3 && Face2Pt2 != TriNode1;
221 else if (Face2Pt1 == TriNode3)
222 NotConnex = Face2Pt2 != TriNode1 && Face2Pt2 != TriNode2;
226 PlanPtr = PH->Plan();
227 d1 = APlan * PntXP1 + BPlan * PntYP1 + CPlan * PntZP1 - DPlan;
228 d2 = APlan * PntXP2 + BPlan * PntYP2 + CPlan * PntZP2 - DPlan;
229 if (d1 > Tolerance) {
230 if (d2 < -Tolerance) {
231 Param = d1 / ( d1 - d2 );
232 toHideBefore = Standard_False;
233 isCrossing = Standard_True;
235 const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
236 const gp_XYZ & P1 = Nodes(TriNode1);
237 const gp_XYZ & P2 = Nodes(TriNode2);
238 const gp_XYZ & P3 = Nodes(TriNode3);
245 hideByOneTriangle (Coordinates, RealPtr, isCrossing, toHideBefore, TFlag, status);
248 else if (d1 < -Tolerance) {
249 if (d2 > Tolerance) {
250 Param = d1 / ( d1 - d2 );
251 toHideBefore = Standard_True;
252 isCrossing = Standard_True;
254 const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
255 const gp_XYZ & P1 = Nodes(TriNode1);
256 const gp_XYZ & P2 = Nodes(TriNode2);
257 const gp_XYZ & P3 = Nodes(TriNode3);
264 hideByOneTriangle (Coordinates, RealPtr, isCrossing, toHideBefore, TFlag, status);
267 isCrossing = Standard_False;
269 const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
270 const gp_XYZ & P1 = Nodes(TriNode1);
271 const gp_XYZ & P2 = Nodes(TriNode2);
272 const gp_XYZ & P3 = Nodes(TriNode3);
279 hideByOneTriangle (Coordinates, RealPtr, isCrossing, toHideBefore, TFlag, status);
282 else if (d2 < -Tolerance) {
283 isCrossing = Standard_False;
285 const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
286 const gp_XYZ & P1 = Nodes(TriNode1);
287 const gp_XYZ & P2 = Nodes(TriNode2);
288 const gp_XYZ & P3 = Nodes(TriNode3);
295 hideByOneTriangle(Coordinates, RealPtr, isCrossing, toHideBefore, TFlag, status);
304 //=======================================================================
305 //function : hideByOneTriangle
307 //=======================================================================
309 void HLRAlgo_PolyData::hideByOneTriangle (const Standard_Address Coordinates,
310 const Standard_Address RealPtr,
311 const Standard_Boolean Crossing,
312 const Standard_Boolean HideBefore,
313 const Standard_Integer TrFlags,
314 HLRAlgo_EdgeStatus& status)
316 Standard_Boolean o[2],m[2];
317 Standard_Integer l,n1=0,nn1,nn2,npi=-1,npiRej=0;
318 Standard_Real a,b,c,da,db,d1,d2,p[2]={0.,0.},pd1,pd2,pdp,pp,psta=0.,pend=1.;
319 Standard_Boolean CrosSeg;
325 c = sqrt( a * a + b * b);
328 c = a * XV1 + b * YV1;
329 d1 = a * PntXP1 + b * PntYP1 - c;
330 d2 = a * PntXP2 + b * PntYP2 - c;
331 if (d1 > Tolerance) {
332 if (d2 < -Tolerance) {
334 CrosSeg = Standard_True;
337 CrosSeg = Standard_False;
339 else if (d1 < -Tolerance) {
340 if (d2 > Tolerance) {
342 CrosSeg = Standard_True;
348 CrosSeg = Standard_False;
349 else if (d2 < -Tolerance) return;
351 CrosSeg = Standard_False;
352 if (TrFlags & EMskGrALin1) {
353 pd1 = (PntXP1 - XV1) / da;
354 pd2 = (PntXP2 - XV1) / da;
357 pd1 = (PntYP1 - YV1) / db;
358 pd2 = (PntYP2 - YV1) / db;
360 if (pd1 < -TolParam) nn1 = 1;
361 else if (pd1 < TolParam) nn1 = 2;
362 else if (pd1 - 1. < -TolParam) nn1 = 3;
363 else if (pd1 - 1. < TolParam) nn1 = 4;
365 if (pd2 < -TolParam) nn2 = 1;
366 else if (pd2 < TolParam) nn2 = 2;
367 else if (pd2 - 1. < -TolParam) nn2 = 3;
368 else if (pd2 - 1. < TolParam) nn2 = 4;
371 if (nn2 == 1) pend = pd1 / (pd1 - pd2);
372 else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
375 if (nn2 <= 2) return;
377 psta = - pd1 / (pd2 - pd1);
378 if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
382 if (nn2 >= 4) return;
384 psta = (pd1 - 1.) / (pd1 - pd2);
385 if (nn2 == 1) pend = pd1 / (pd1 - pd2);
389 if (nn2 == 1) return;
390 else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
393 if (nn2 == 5) return;
394 else if (nn2 == 1) pend = pd1 / (pd1 - pd2);
399 Standard_Real ad1 = d1;
400 if (d1 < 0) ad1 = -d1;
401 Standard_Real ad2 = d2;
402 if (d2 < 0) ad2 = -d2;
403 pp = ad1 / ( ad1 + ad2 );
404 if (TrFlags & EMskGrALin1)
405 pdp = (PntXP1 + (PntXP2 - PntXP1) * pp - XV1) / da;
407 pdp = (PntYP1 + (PntYP2 - PntYP1) * pp - YV1) / db;
408 Standard_Boolean OutSideP = Standard_False;
409 Standard_Boolean Multiple = Standard_False;
410 if (pdp < -TolParam) OutSideP = Standard_True;
411 else if (pdp < TolParam) {
412 Multiple = Standard_True;
414 for (l = 0; l <= npi; l++) {
416 OutSideP = Standard_True;
418 if (o[l] != (n1 == -1)) {
419 if (l == 0 && npi == 1) {
430 else if (pdp - 1. < -TolParam) {}
431 else if (pdp - 1. < TolParam) {
432 Multiple = Standard_True;
434 for (l = 0; l <= npi; l++) {
436 OutSideP = Standard_True;
437 if (o[l] != (n1 == -1)) {
438 if (l == 0 && npi == 1) {
449 else OutSideP = Standard_True;
450 if (OutSideP) npiRej++;
460 cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
461 cout << " ( more than 2 points )." << endl;
471 c = sqrt(a * a + b * b);
474 c = a * XV2 + b * YV2;
475 d1 = a * PntXP1 + b * PntYP1 - c;
476 d2 = a * PntXP2 + b * PntYP2 - c;
477 if (d1 > Tolerance) {
478 if (d2 < -Tolerance) {
480 CrosSeg = Standard_True;
483 CrosSeg = Standard_False;
485 else if (d1 < -Tolerance) {
486 if (d2 > Tolerance) {
488 CrosSeg = Standard_True;
494 CrosSeg = Standard_False;
495 else if (d2 < -Tolerance) return;
497 CrosSeg = Standard_False;
498 if (TrFlags & EMskGrALin2) {
499 pd1 = (PntXP1 - XV2) / da;
500 pd2 = (PntXP2 - XV2) / da;
503 pd1 = (PntYP1 - YV2) / db;
504 pd2 = (PntYP2 - YV2) / db;
506 if (pd1 < -TolParam) nn1 = 1;
507 else if (pd1 < TolParam) nn1 = 2;
508 else if (pd1 - 1. < -TolParam) nn1 = 3;
509 else if (pd1 - 1. < TolParam) nn1 = 4;
511 if (pd2 < -TolParam) nn2 = 1;
512 else if (pd2 < TolParam) nn2 = 2;
513 else if (pd2 - 1. < -TolParam) nn2 = 3;
514 else if (pd2 - 1. < TolParam) nn2 = 4;
517 if (nn2 == 1) pend = pd1 / (pd1 - pd2);
518 else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
521 if (nn2 <= 2) return;
523 psta = - pd1 / (pd2 - pd1);
524 if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
528 if (nn2 >= 4) return;
530 psta = (pd1 - 1.) / (pd1 - pd2);
531 if (nn2 == 1) pend = pd1 / (pd1 - pd2);
535 if (nn2 == 1) return;
536 else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
539 if (nn2 == 5) return;
540 else if (nn2 == 1) pend = pd1 / (pd1 - pd2);
545 Standard_Real ad1 = d1;
546 if (d1 < 0) ad1 = -d1;
547 Standard_Real ad2 = d2;
548 if (d2 < 0) ad2 = -d2;
549 pp = ad1 / ( ad1 + ad2 );
550 if (TrFlags & EMskGrALin2)
551 pdp = (PntXP1 + (PntXP2 - PntXP1) * pp - XV2) / da;
553 pdp = (PntYP1 + (PntYP2 - PntYP1) * pp - YV2) / db;
554 Standard_Boolean OutSideP = Standard_False;
555 Standard_Boolean Multiple = Standard_False;
556 if (pdp < -TolParam) OutSideP = Standard_True;
557 else if (pdp < TolParam) {
558 Multiple = Standard_True;
560 for (l = 0; l <= npi; l++) {
562 OutSideP = Standard_True;
563 if (o[l] != (n1 == -1)) {
564 if (l == 0 && npi == 1) {
575 else if (pdp - 1. < -TolParam) {}
576 else if (pdp - 1. < TolParam) {
577 Multiple = Standard_True;
579 for (l = 0; l <= npi; l++) {
581 OutSideP = Standard_True;
582 if (o[l] != (n1 == -1)) {
583 if (l == 0 && npi == 1) {
594 else OutSideP = Standard_True;
595 if (OutSideP) npiRej++;
605 cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
606 cout << " ( more than 2 points )." << endl;
616 c = sqrt(a * a + b * b);
619 c = a * XV3 + b * YV3;
620 d1 = a * PntXP1 + b * PntYP1 - c;
621 d2 = a * PntXP2 + b * PntYP2 - c;
622 if (d1 > Tolerance) {
623 if (d2 < -Tolerance) {
625 CrosSeg = Standard_True;
628 CrosSeg = Standard_False;
630 else if (d1 < -Tolerance) {
631 if (d2 > Tolerance) {
633 CrosSeg = Standard_True;
639 CrosSeg = Standard_False;
640 else if (d2 < -Tolerance) return;
642 CrosSeg = Standard_False;
643 if (TrFlags & EMskGrALin3) {
644 pd1 = (PntXP1 - XV3) / da;
645 pd2 = (PntXP2 - XV3) / da;
648 pd1 = (PntYP1 - YV3) / db;
649 pd2 = (PntYP2 - YV3) / db;
651 if (pd1 < -TolParam) nn1 = 1;
652 else if (pd1 < TolParam) nn1 = 2;
653 else if (pd1 - 1. < -TolParam) nn1 = 3;
654 else if (pd1 - 1. < TolParam) nn1 = 4;
656 if (pd2 < -TolParam) nn2 = 1;
657 else if (pd2 < TolParam) nn2 = 2;
658 else if (pd2 - 1. < -TolParam) nn2 = 3;
659 else if (pd2 - 1. < TolParam) nn2 = 4;
662 if (nn2 == 1) pend = pd1 / (pd1 - pd2);
663 else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
666 if (nn2 <= 2) return;
668 psta = - pd1 / (pd2 - pd1);
669 if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
673 if (nn2 >= 4) return;
675 psta = (pd1 - 1.) / (pd1 - pd2);
676 if (nn2 == 1) pend = pd1 / (pd1 - pd2);
680 if (nn2 == 1) return;
681 else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
684 if (nn2 == 5) return;
685 else if (nn2 == 1) pend = pd1 / (pd1 - pd2);
690 Standard_Real ad1 = d1;
691 if (d1 < 0) ad1 = -d1;
692 Standard_Real ad2 = d2;
693 if (d2 < 0) ad2 = -d2;
694 pp = ad1 / ( ad1 + ad2 );
695 if (TrFlags & EMskGrALin3)
696 pdp = (PntXP1 + (PntXP2 - PntXP1) * pp - XV3) / da;
698 pdp = (PntYP1 + (PntYP2 - PntYP1) * pp - YV3) / db;
699 Standard_Boolean OutSideP = Standard_False;
700 Standard_Boolean Multiple = Standard_False;
701 if (pdp < -TolParam) OutSideP = Standard_True;
702 else if (pdp < TolParam) {
703 Multiple = Standard_True;
705 for (l = 0; l <= npi; l++) {
707 OutSideP = Standard_True;
708 if (o[l] != (n1 == -1)) {
709 if (l == 0 && npi == 1) {
720 else if (pdp - 1. < -TolParam) {}
721 else if (pdp - 1. < TolParam) {
722 Multiple = Standard_True;
724 for (l = 0; l <= npi; l++) {
726 OutSideP = Standard_True;
727 if (o[l] != (n1 == -1)) {
728 if (l == 0 && npi == 1) {
739 else OutSideP = Standard_True;
740 if (OutSideP) npiRej++;
750 cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
751 cout << " ( more than 2 points )." << endl;
758 if (npiRej >= 2) return;
783 if (Param-psta < TolParam) return;
784 else if (Param < pend) pend = Param;
787 if (pend-Param < TolParam) return;
788 else if (psta < Param) psta = Param;
792 Standard_Boolean total;
793 if (psta > 0) total = psta < TolParam;
794 else total = psta > -TolParam;
796 Standard_Real pfin = pend - 1.;
797 if (pfin > 0) total = pfin < TolParam;
798 else total = pfin > -TolParam;
800 if (total) status.HideAll();
801 else status.Hide(psta,(Standard_ShortReal)TolParam,pend,(Standard_ShortReal)TolParam,
802 Standard_False,Standard_False);