0028883: Invalid result of Section operation
[occt.git] / src / HLRAlgo / HLRAlgo_PolyData.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <HLRAlgo_PolyData.hxx>
18
19 #include <HLRAlgo_EdgeStatus.hxx>
20 #include <HLRAlgo_PolyMask.hxx>
21
22 #include <Standard_Type.hxx>
23
24 IMPLEMENT_STANDARD_RTTIEXT(HLRAlgo_PolyData,MMgt_TShared)
25
26 #ifdef OCCT_DEBUG
27 static Standard_Integer ERROR = Standard_False;
28 #endif
29 //=======================================================================
30 //function : PolyData
31 //purpose  : 
32 //=======================================================================
33
34 HLRAlgo_PolyData::HLRAlgo_PolyData ()
35 {}
36
37 //=======================================================================
38 //function : HNodes
39 //purpose  : 
40 //=======================================================================
41
42 void HLRAlgo_PolyData::HNodes(const Handle(TColgp_HArray1OfXYZ)& HNodes)
43 { myHNodes = HNodes; }
44
45 //=======================================================================
46 //function : HTData
47 //purpose  : 
48 //=======================================================================
49
50 void HLRAlgo_PolyData::HTData(const Handle(HLRAlgo_HArray1OfTData)& HTData)
51 { myHTData = HTData; }
52
53 //=======================================================================
54 //function : HPHDat
55 //purpose  : 
56 //=======================================================================
57
58 void HLRAlgo_PolyData::HPHDat(const Handle(HLRAlgo_HArray1OfPHDat)& HPHDat)
59 { myHPHDat = HPHDat; }
60
61 //=======================================================================
62 //function : UpdateGlobalMinMax
63 //purpose  : 
64 //=======================================================================
65
66 void
67 HLRAlgo_PolyData::UpdateGlobalMinMax (Box& theBox)
68 {
69   Standard_Integer i;
70   Standard_Real X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3;
71   const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
72   HLRAlgo_Array1OfTData&    TData = myHTData->ChangeArray1();
73   Standard_Integer          nbT   = TData.Upper();
74   HLRAlgo_TriangleData*     TD    = &(TData.ChangeValue(1));
75   
76   for (i = 1; i <= nbT; i++) {
77     if (TD->Flags & HLRAlgo_PolyMask_FMskHiding) {
78       const gp_XYZ& P1 = Nodes(TD->Node1);
79       const gp_XYZ& P2 = Nodes(TD->Node2);
80       const gp_XYZ& P3 = Nodes(TD->Node3);
81       X1 = P1.X();
82       Y1 = P1.Y();
83       Z1 = P1.Z();
84       X2 = P2.X();
85       Y2 = P2.Y();
86       Z2 = P2.Z();
87       X3 = P3.X();
88       Y3 = P3.Y();
89       Z3 = P3.Z();
90       if      (theBox.XMin > X1) theBox.XMin = X1;
91       else if (theBox.XMax < X1) theBox.XMax = X1;
92       if      (theBox.YMin > Y1) theBox.YMin = Y1;
93       else if (theBox.YMax < Y1) theBox.YMax = Y1;
94       if      (theBox.ZMin > Z1) theBox.ZMin = Z1;
95       else if (theBox.ZMax < Z1) theBox.ZMax = Z1;
96       if      (theBox.XMin > X2) theBox.XMin = X2;
97       else if (theBox.XMax < X2) theBox.XMax = X2;
98       if      (theBox.YMin > Y2) theBox.YMin = Y2;
99       else if (theBox.YMax < Y2) theBox.YMax = Y2;
100       if      (theBox.ZMin > Z2) theBox.ZMin = Z2;
101       else if (theBox.ZMax < Z2) theBox.ZMax = Z2;
102       if      (theBox.XMin > X3) theBox.XMin = X3;
103       else if (theBox.XMax < X3) theBox.XMax = X3;
104       if      (theBox.YMin > Y3) theBox.YMin = Y3;
105       else if (theBox.YMax < Y3) theBox.YMax = Y3;
106       if      (theBox.ZMin > Z3) theBox.ZMin = Z3;
107       else if (theBox.ZMax < Z3) theBox.ZMax = Z3;
108     }
109     TD++;
110   }
111 }
112
113 //=======================================================================
114 //function : HideByPolyData
115 //purpose  : 
116 //=======================================================================
117
118 void HLRAlgo_PolyData::HideByPolyData (const HLRAlgo_BiPoint::PointsT& thePoints,
119                                        Triangle& theTriangle,
120                                        HLRAlgo_BiPoint::IndicesT& theIndices,
121                                        const Standard_Boolean HidingShell,
122                                        HLRAlgo_EdgeStatus& status)
123 {
124   if (((myFaceIndices.Max - theIndices.MinSeg) & 0x80100200) == 0 &&
125       ((theIndices.MaxSeg - myFaceIndices.Min) & 0x80100000) == 0) {
126     HLRAlgo_Array1OfPHDat& PHDat = myHPHDat->ChangeArray1();
127     const HLRAlgo_Array1OfTData& TData = myHTData->Array1();
128     Standard_Real d1,d2;
129     Standard_Boolean NotConnex    = Standard_False;
130     Standard_Boolean isCrossing   = Standard_False;
131     Standard_Boolean toHideBefore = Standard_False;
132     Standard_Integer TFlag = 0;
133     Standard_Integer h,h2 = PHDat.Upper();
134     HLRAlgo_PolyHidingData* PH = &(PHDat(1));
135     
136     for (h = 1; h <= h2; h++) {
137       HLRAlgo_PolyHidingData::TriangleIndices& aTriangleIndices = PH->Indices();
138       if (((aTriangleIndices.Max - theIndices.MinSeg) & 0x80100200) == 0 &&
139           ((theIndices.MaxSeg - aTriangleIndices.Min) & 0x80100000) == 0) {
140         const HLRAlgo_TriangleData& aTriangle = TData(aTriangleIndices.Index);
141         NotConnex = Standard_True;
142         if (HidingShell) {
143           if      (myFaceIndices.Index == theIndices.FaceConex1) {
144             if      (theIndices.Face1Pt1 == aTriangle.Node1)
145               NotConnex = theIndices.Face1Pt2 != aTriangle.Node2 && theIndices.Face1Pt2 != aTriangle.Node3;
146             else if (theIndices.Face1Pt1 == aTriangle.Node2)
147               NotConnex = theIndices.Face1Pt2 != aTriangle.Node3 && theIndices.Face1Pt2 != aTriangle.Node1;
148             else if (theIndices.Face1Pt1 == aTriangle.Node3)
149               NotConnex = theIndices.Face1Pt2 != aTriangle.Node1 && theIndices.Face1Pt2 != aTriangle.Node2;
150           }
151           else if (myFaceIndices.Index == theIndices.FaceConex2) {
152             if      (theIndices.Face2Pt1 == aTriangle.Node1)
153               NotConnex = theIndices.Face2Pt2 != aTriangle.Node2 && theIndices.Face2Pt2 != aTriangle.Node3;
154             else if (theIndices.Face2Pt1 == aTriangle.Node2)
155               NotConnex = theIndices.Face2Pt2 != aTriangle.Node3 && theIndices.Face2Pt2 != aTriangle.Node1;
156             else if (theIndices.Face2Pt1 == aTriangle.Node3)
157               NotConnex = theIndices.Face2Pt2 != aTriangle.Node1 && theIndices.Face2Pt2 != aTriangle.Node2;
158           }
159         }
160         if (NotConnex) {
161           HLRAlgo_PolyHidingData::PlaneT& aPlane = PH->Plane();
162           d1 = aPlane.Normal * thePoints.PntP1 - aPlane.D;
163           d2 = aPlane.Normal * thePoints.PntP2 - aPlane.D;
164           if      (d1 > theTriangle.Tolerance) {
165             if    (d2 < -theTriangle.Tolerance) {
166               theTriangle.Param = d1 / ( d1 - d2 );
167               toHideBefore = Standard_False;
168               isCrossing   = Standard_True;
169               TFlag = aTriangle.Flags;
170               const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
171               const gp_XYZ            & P1    = Nodes(aTriangle.Node1);
172               const gp_XYZ            & P2    = Nodes(aTriangle.Node2);
173               const gp_XYZ            & P3    = Nodes(aTriangle.Node3);
174         theTriangle.V1 = gp_XY(P1.X(), P1.Y());
175         theTriangle.V2 = gp_XY(P2.X(), P2.Y());
176         theTriangle.V3 = gp_XY(P3.X(), P3.Y());
177               hideByOneTriangle (thePoints, theTriangle, isCrossing, toHideBefore, TFlag, status);
178             }
179           }
180           else if (d1 < -theTriangle.Tolerance) {
181             if    (d2 > theTriangle.Tolerance) {
182               theTriangle.Param = d1 / ( d1 - d2 );
183               toHideBefore = Standard_True;
184               isCrossing   = Standard_True;
185               TFlag = aTriangle.Flags;
186               const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
187               const gp_XYZ            & P1    = Nodes(aTriangle.Node1);
188               const gp_XYZ            & P2    = Nodes(aTriangle.Node2);
189               const gp_XYZ            & P3    = Nodes(aTriangle.Node3);
190               theTriangle.V1 = gp_XY(P1.X(), P1.Y());
191               theTriangle.V2 = gp_XY(P2.X(), P2.Y());
192               theTriangle.V3 = gp_XY(P3.X(), P3.Y());
193               hideByOneTriangle (thePoints, theTriangle, isCrossing, toHideBefore, TFlag, status);
194             }
195             else {
196               isCrossing = Standard_False;
197               TFlag = aTriangle.Flags;
198               const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
199               const gp_XYZ            & P1    = Nodes(aTriangle.Node1);
200               const gp_XYZ            & P2    = Nodes(aTriangle.Node2);
201               const gp_XYZ            & P3    = Nodes(aTriangle.Node3);
202               theTriangle.V1 = gp_XY(P1.X(), P1.Y());
203               theTriangle.V2 = gp_XY(P2.X(), P2.Y());
204               theTriangle.V3 = gp_XY(P3.X(), P3.Y());
205               hideByOneTriangle (thePoints, theTriangle, isCrossing, toHideBefore, TFlag, status);
206             }
207           }
208           else if (d2 < -theTriangle.Tolerance) {
209             isCrossing = Standard_False;
210             TFlag = aTriangle.Flags;
211             const TColgp_Array1OfXYZ& Nodes = myHNodes->Array1();
212             const gp_XYZ            & P1    = Nodes(aTriangle.Node1);
213             const gp_XYZ            & P2    = Nodes(aTriangle.Node2);
214             const gp_XYZ            & P3    = Nodes(aTriangle.Node3);
215             theTriangle.V1 = gp_XY(P1.X(), P1.Y());
216             theTriangle.V2 = gp_XY(P2.X(), P2.Y());
217             theTriangle.V3 = gp_XY(P3.X(), P3.Y());
218             hideByOneTriangle(thePoints, theTriangle, isCrossing, toHideBefore, TFlag, status);
219           }
220         }
221       }
222       PH++;
223     }
224   }
225 }
226
227 //=======================================================================
228 //function : hideByOneTriangle
229 //purpose  :
230 //=======================================================================
231
232 void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoints,
233                                           Triangle& theTriangle,
234                                           const Standard_Boolean Crossing,
235                                           const Standard_Boolean HideBefore,
236                                           const Standard_Integer TrFlags,
237                                           HLRAlgo_EdgeStatus& status)
238 {
239   Standard_Boolean CrosSeg = Standard_False;
240   Standard_Integer n1 = 0;
241   Standard_Real pd1 = 0., pd2 = 0.;
242   Standard_Integer nn1 = 0, nn2 = 0;
243   Standard_Real pend = 1., psta = 0., pp = 0., pdp = 0.;
244   Standard_Integer npi = -1;
245   Standard_Boolean o[] = {Standard_False, Standard_False};
246   Standard_Boolean  m[] = {Standard_False, Standard_False};
247   Standard_Real p[] = {0., 0.};
248   Standard_Integer npiRej = 0;
249
250   {
251   const gp_XY aD = theTriangle.V2 - theTriangle.V1;
252   const gp_XY aA = (1 / aD.Modulus()) * gp_XY(-aD.Y(), aD.X());
253   const Standard_Real aDot = aA * theTriangle.V1;
254   const Standard_Real d1 = aA * thePoints.PntP12D() - aDot;
255   const Standard_Real d2 = aA * thePoints.PntP22D() - aDot;
256   if      (d1 > theTriangle.Tolerance) {
257     if (d2 < -theTriangle.Tolerance) {
258       n1 =  2;
259       CrosSeg = Standard_True;
260     }
261     else
262       CrosSeg = Standard_False;
263   }
264   else if (d1 < -theTriangle.Tolerance) {
265     if (d2 > theTriangle.Tolerance) {
266       n1 = -1;
267       CrosSeg = Standard_True;
268     }
269     else return;
270   }
271   else {
272     if      (d2 > theTriangle.Tolerance)
273       CrosSeg = Standard_False;
274     else if (d2 < -theTriangle.Tolerance) return;
275     else {
276       CrosSeg = Standard_False;
277       if (TrFlags & HLRAlgo_PolyMask_EMskGrALin1) {
278         pd1 = (thePoints.PntP1.X() - theTriangle.V1.X()) / aD.X();
279         pd2 = (thePoints.PntP2.X() - theTriangle.V1.X()) / aD.X();
280       }
281       else {
282         pd1 = (thePoints.PntP1.Y() - theTriangle.V1.Y()) / aD.Y();
283         pd2 = (thePoints.PntP2.Y() - theTriangle.V1.Y()) / aD.Y();
284       }
285       if      (pd1      < -theTriangle.TolParam) nn1 = 1;
286       else if (pd1      < theTriangle.TolParam) nn1 = 2;
287       else if (pd1 - 1. < -theTriangle.TolParam) nn1 = 3;
288       else if (pd1 - 1. < theTriangle.TolParam) nn1 = 4;
289       else                           nn1 = 5;
290       if      (pd2      < -theTriangle.TolParam) nn2 = 1;
291       else if (pd2      < theTriangle.TolParam) nn2 = 2;
292       else if (pd2 - 1. < -theTriangle.TolParam) nn2 = 3;
293       else if (pd2 - 1. < theTriangle.TolParam) nn2 = 4;
294       else                           nn2 = 5;
295       if      (nn1 == 3) {
296         if      (nn2 == 1) pend = pd1 / (pd1 - pd2);
297         else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
298       }
299       else if (nn1 == 1) {
300         if (nn2 <= 2) return;
301         else {
302           psta = - pd1 / (pd2 - pd1);
303           if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
304         }
305       }
306       else if (nn1 == 5) {
307         if (nn2 >= 4) return;
308         else {
309           psta = (pd1 - 1.) / (pd1 - pd2);
310           if (nn2 == 1) pend = pd1 / (pd1 - pd2);
311         }
312       }
313       else if (nn1 == 2) {
314         if (nn2 == 1) return;
315         else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
316       }
317       else if (nn1 == 4) {
318         if (nn2 == 5) return;
319         else if (nn2 == 1) pend = pd1 / (pd1 - pd2);
320       }
321     }
322   }
323   if (CrosSeg) {
324     Standard_Real ad1 = d1;
325     if (d1 < 0) ad1 = -d1;
326     Standard_Real ad2 = d2;
327     if (d2 < 0) ad2 = -d2;
328     pp = ad1 / ( ad1 + ad2 );
329     if (TrFlags & HLRAlgo_PolyMask_EMskGrALin1)
330       pdp = (thePoints.PntP1.X() + (thePoints.PntP2.X() - thePoints.PntP1.X()) * pp - theTriangle.V1.X()) / aD.X();
331     else
332       pdp = (thePoints.PntP1.Y() + (thePoints.PntP2.Y() - thePoints.PntP1.Y()) * pp - theTriangle.V1.Y()) / aD.Y();
333     Standard_Boolean OutSideP = Standard_False;
334     Standard_Boolean Multiple = Standard_False;
335     if      (pdp      < -theTriangle.TolParam) OutSideP = Standard_True;
336     else if (pdp      < theTriangle.TolParam) {
337       Multiple = Standard_True;
338
339       for (Standard_Integer l = 0; l <= npi; l++) {
340         if (m[l]) {
341           OutSideP = Standard_True;
342
343           if (o[l] != (n1 == -1)) {
344             if (l == 0 && npi == 1) {
345               p[0] = p[1];
346               o[0] = o[1];
347               m[0] = m[1];
348             }
349             npi--;
350             npiRej++;
351           }
352         }
353       }
354     }
355     else if (pdp - 1. < -theTriangle.TolParam) {}
356     else if (pdp - 1. < theTriangle.TolParam) {
357       Multiple = Standard_True;
358
359       for (Standard_Integer l = 0; l <= npi; l++) {
360         if (m[l]) {
361           OutSideP = Standard_True;
362           if (o[l] != (n1 == -1)) {
363             if (l == 0 && npi == 1) {
364               p[0] = p[1];
365               o[0] = o[1];
366               m[0] = m[1];
367             }
368             npi--;
369             npiRej++;
370           }
371         }
372       }
373     }
374     else                           OutSideP = Standard_True;
375     if (OutSideP) npiRej++;
376     else {
377       npi++;
378       if (npi < 2) {
379         p[npi] = pp;
380         o[npi] = n1 == -1;
381         m[npi] = Multiple;
382       }
383 #ifdef OCCT_DEBUG
384       else if (ERROR) {
385         cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
386         cout << " ( more than 2 points )." << endl;
387       }
388 #endif
389     }
390   }
391   }
392
393   {
394   const gp_XY aD = theTriangle.V3 - theTriangle.V2;
395   const gp_XY aA = (1 / aD.Modulus()) * gp_XY(-aD.Y(), aD.X());
396   const Standard_Real aDot = aA * theTriangle.V2;
397   const Standard_Real d1 = aA * thePoints.PntP12D() - aDot;
398   const Standard_Real d2 = aA * thePoints.PntP22D() - aDot;
399   if      (d1 > theTriangle.Tolerance) {
400     if (d2 < -theTriangle.Tolerance) {
401       n1 =  2;
402       CrosSeg = Standard_True;
403     }
404     else
405       CrosSeg = Standard_False;
406   }
407   else if (d1 < -theTriangle.Tolerance) {
408     if (d2 > theTriangle.Tolerance) {
409       n1 = -1;
410       CrosSeg = Standard_True;
411     }
412     else return;
413   }
414   else {
415     if      (d2 > theTriangle.Tolerance)
416       CrosSeg = Standard_False;
417     else if (d2 < -theTriangle.Tolerance) return;
418     else {
419       CrosSeg = Standard_False;
420       if (TrFlags & HLRAlgo_PolyMask_EMskGrALin2) {
421         pd1 = (thePoints.PntP1.X() - theTriangle.V2.X()) / aD.X();
422         pd2 = (thePoints.PntP2.X() - theTriangle.V2.X()) / aD.X();
423       }
424       else {
425         pd1 = (thePoints.PntP1.Y() - theTriangle.V2.Y()) / aD.Y();
426         pd2 = (thePoints.PntP2.Y() - theTriangle.V2.Y()) / aD.Y();
427       }
428       if      (pd1      < -theTriangle.TolParam) nn1 = 1;
429       else if (pd1      < theTriangle.TolParam) nn1 = 2;
430       else if (pd1 - 1. < -theTriangle.TolParam) nn1 = 3;
431       else if (pd1 - 1. < theTriangle.TolParam) nn1 = 4;
432       else                           nn1 = 5;
433       if      (pd2      < -theTriangle.TolParam) nn2 = 1;
434       else if (pd2      < theTriangle.TolParam) nn2 = 2;
435       else if (pd2 - 1. < -theTriangle.TolParam) nn2 = 3;
436       else if (pd2 - 1. < theTriangle.TolParam) nn2 = 4;
437       else                           nn2 = 5;
438       if      (nn1 == 3) {
439         if      (nn2 == 1) pend = pd1 / (pd1 - pd2);
440         else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
441       }
442       else if (nn1 == 1) {
443         if (nn2 <= 2) return;
444         else {
445           psta = - pd1 / (pd2 - pd1);
446           if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
447         }
448       }
449       else if (nn1 == 5) {
450         if (nn2 >= 4) return;
451         else {
452           psta = (pd1 - 1.) / (pd1 - pd2);
453           if (nn2 == 1) pend = pd1 / (pd1 - pd2);
454         }
455       }
456       else if (nn1 == 2) {
457         if (nn2 == 1) return;
458         else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
459       }
460       else if (nn1 == 4) {
461         if (nn2 == 5) return;
462         else if (nn2 == 1) pend = pd1 / (pd1 - pd2);
463       }
464     }
465   }
466   if (CrosSeg) {
467     Standard_Real ad1 = d1;
468     if (d1 < 0) ad1 = -d1;
469     Standard_Real ad2 = d2;
470     if (d2 < 0) ad2 = -d2;
471     pp = ad1 / ( ad1 + ad2 );
472     if (TrFlags & HLRAlgo_PolyMask_EMskGrALin2)
473       pdp = (thePoints.PntP1.X() + (thePoints.Pnt2.X() - thePoints.PntP1.X()) * pp - theTriangle.V2.X()) / aD.X();
474     else
475       pdp = (thePoints.PntP1.Y() + (thePoints.PntP2.Y() - thePoints.PntP1.Y()) * pp - theTriangle.V2.Y()) / aD.Y();
476     Standard_Boolean OutSideP = Standard_False;
477     Standard_Boolean Multiple = Standard_False;
478     if      (pdp      < -theTriangle.TolParam) OutSideP = Standard_True;
479     else if (pdp      < theTriangle.TolParam) {
480       Multiple = Standard_True;
481
482       for (Standard_Integer l = 0; l <= npi; l++) {
483         if (m[l]) {
484           OutSideP = Standard_True;
485           if (o[l] != (n1 == -1)) {
486             if (l == 0 && npi == 1) {
487               p[0] = p[1];
488               o[0] = o[1];
489               m[0] = m[1];
490             }
491             npi--;
492             npiRej++;
493           }
494         }
495       }
496     }
497     else if (pdp - 1. < -theTriangle.TolParam) {}
498     else if (pdp - 1. < theTriangle.TolParam) {
499       Multiple = Standard_True;
500
501       for (Standard_Integer l = 0; l <= npi; l++) {
502         if (m[l]) {
503           OutSideP = Standard_True;
504           if (o[l] != (n1 == -1)) {
505             if (l == 0 && npi == 1) {
506               p[0] = p[1];
507               o[0] = o[1];
508               m[0] = m[1];
509             }
510             npi--;
511             npiRej++;
512           }
513         }
514       }
515     }
516     else                           OutSideP = Standard_True;
517     if (OutSideP) npiRej++;
518     else {
519       npi++;
520       if (npi < 2) {
521         p[npi] = pp;
522         o[npi] = n1 == -1;
523         m[npi] = Multiple;
524       }
525 #ifdef OCCT_DEBUG
526       else if (ERROR) {
527         cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
528         cout << " ( more than 2 points )." << endl;
529       }
530 #endif
531     }
532   }
533   }
534
535   {
536   const gp_XY aD = theTriangle.V1 - theTriangle.V3;
537   const gp_XY aA = (1 / aD.Modulus()) * gp_XY(-aD.Y(), aD.X());
538   const Standard_Real aDot = aA * theTriangle.V3;
539   const Standard_Real d1 = aA * thePoints.PntP12D() - aDot;
540   const Standard_Real d2 = aA * thePoints.PntP22D() - aDot;
541   if      (d1 > theTriangle.Tolerance) {
542     if (d2 < -theTriangle.Tolerance) {
543       n1 =  2;
544       CrosSeg = Standard_True;
545     }
546     else
547       CrosSeg = Standard_False;
548   }
549   else if (d1 < -theTriangle.Tolerance) {
550     if (d2 > theTriangle.Tolerance) {
551       n1 = -1;
552       CrosSeg = Standard_True;
553     }
554     else return;
555   }
556   else {
557     if      (d2 > theTriangle.Tolerance)
558       CrosSeg = Standard_False;
559     else if (d2 < -theTriangle.Tolerance) return;
560     else {
561       CrosSeg = Standard_False;
562       if (TrFlags & HLRAlgo_PolyMask_EMskGrALin3) {
563         pd1 = (thePoints.PntP1.X() - theTriangle.V3.X()) / aD.X();
564         pd2 = (thePoints.PntP2.X() - theTriangle.V3.X()) / aD.X();
565       }
566       else {
567         pd1 = (thePoints.PntP1.Y() - theTriangle.V3.Y()) / aD.Y();
568         pd2 = (thePoints.PntP2.Y() - theTriangle.V3.Y()) / aD.Y();
569       }
570       if      (pd1      < -theTriangle.TolParam) nn1 = 1;
571       else if (pd1      < theTriangle.TolParam) nn1 = 2;
572       else if (pd1 - 1. < -theTriangle.TolParam) nn1 = 3;
573       else if (pd1 - 1. < theTriangle.TolParam) nn1 = 4;
574       else                           nn1 = 5;
575       if      (pd2      < -theTriangle.TolParam) nn2 = 1;
576       else if (pd2      < theTriangle.TolParam) nn2 = 2;
577       else if (pd2 - 1. < -theTriangle.TolParam) nn2 = 3;
578       else if (pd2 - 1. < theTriangle.TolParam) nn2 = 4;
579       else                           nn2 = 5;
580       if      (nn1 == 3) {
581         if      (nn2 == 1) pend = pd1 / (pd1 - pd2);
582         else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
583       }
584       else if (nn1 == 1) {
585         if (nn2 <= 2) return;
586         else {
587           psta = - pd1 / (pd2 - pd1);
588           if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
589         }
590       }
591       else if (nn1 == 5) {
592         if (nn2 >= 4) return;
593         else {
594           psta = (pd1 - 1.) / (pd1 - pd2);
595           if (nn2 == 1) pend = pd1 / (pd1 - pd2);
596         }
597       }
598       else if (nn1 == 2) {
599         if (nn2 == 1) return;
600         else if (nn2 == 5) pend = (1. - pd1) / (pd2 - pd1);
601       }
602       else if (nn1 == 4) {
603         if (nn2 == 5) return;
604         else if (nn2 == 1) pend = pd1 / (pd1 - pd2);
605       }
606     }
607   }
608   if (CrosSeg) {
609     Standard_Real ad1 = d1;
610     if (d1 < 0) ad1 = -d1;
611     Standard_Real ad2 = d2;
612     if (d2 < 0) ad2 = -d2;
613     pp = ad1 / ( ad1 + ad2 );
614     if (TrFlags & HLRAlgo_PolyMask_EMskGrALin3)
615       pdp = (thePoints.PntP1.X() + (thePoints.PntP2.X() - thePoints.PntP1.X()) * pp - theTriangle.V3.X()) / aD.X();
616     else
617       pdp = (thePoints.PntP1.Y() + (thePoints.PntP2.Y() - thePoints.PntP1.Y()) * pp - theTriangle.V3.Y()) / aD.Y();
618     Standard_Boolean OutSideP = Standard_False;
619     Standard_Boolean Multiple = Standard_False;
620     if      (pdp      < -theTriangle.TolParam) OutSideP = Standard_True;
621     else if (pdp      < theTriangle.TolParam) {
622       Multiple = Standard_True;
623
624       for (Standard_Integer l = 0; l <= npi; l++) {
625         if (m[l]) {
626           OutSideP = Standard_True;
627           if (o[l] != (n1 == -1)) {
628             if (l == 0 && npi == 1) {
629               p[0] = p[1];
630               o[0] = o[1];
631               m[0] = m[1];
632             }
633             npi--;
634             npiRej++;
635           }
636         }
637       }
638     }
639     else if (pdp - 1. < -theTriangle.TolParam) {}
640     else if (pdp - 1. < theTriangle.TolParam) {
641       Multiple = Standard_True;
642
643       for (Standard_Integer l = 0; l <= npi; l++) {
644         if (m[l]) {
645           OutSideP = Standard_True;
646           if (o[l] != (n1 == -1)) {
647             if (l == 0 && npi == 1) {
648               p[0] = p[1];
649               o[0] = o[1];
650               m[0] = m[1];
651             }
652             npi--;
653             npiRej++;
654           }
655         }
656       }
657     }
658     else                           OutSideP = Standard_True;
659     if (OutSideP) npiRej++;
660     else {
661       npi++;
662       if (npi < 2) {
663         p[npi] = pp;
664         o[npi] = n1 == -1;
665         m[npi] = Multiple;
666       }
667 #ifdef OCCT_DEBUG
668       else if (ERROR) {
669         cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
670         cout << " ( more than 2 points )." << endl;
671       }
672 #endif
673     }
674   }
675   }
676
677   if (npi == -1) {
678     if (npiRej >= 2) return;
679   }
680   else if (npi == 0) {
681     if (o[0]) {
682       psta = p[0];
683       pend = 1.;
684     }
685     else {
686       psta = 0.;
687       pend = p[0];
688     }
689   }
690   else if (npi == 1) {
691     if (p[0] > p[1]) {
692       psta = p[1];
693       pend = p[0];
694     }
695     else {
696       psta = p[0];
697       pend = p[1];
698     }
699   }
700
701   if (Crossing) {
702     if (HideBefore) {
703       if      (theTriangle.Param - psta < theTriangle.TolParam) return;
704       else if (theTriangle.Param < pend)          pend   = theTriangle.Param;
705     }
706     else {
707       if      (pend - theTriangle.Param < theTriangle.TolParam) return;
708       else if (psta < theTriangle.Param)          psta   = theTriangle.Param;
709     }
710   }
711
712   Standard_Boolean total;
713   if (psta > 0) total = psta < theTriangle.TolParam;
714   else          total = psta > -theTriangle.TolParam;
715   if (total) {
716     Standard_Real pfin = pend - 1.;
717     if (pfin > 0) total = pfin < theTriangle.TolParam;
718     else          total = pfin > -theTriangle.TolParam;
719   }
720   if (total) status.HideAll();
721   else       status.Hide(psta,(Standard_ShortReal)theTriangle.TolParam,pend,(Standard_ShortReal)theTriangle.TolParam,
722                          Standard_False,Standard_False);
723 }