8bc04d768305e6db6d0b373c34be8a0987f51080
[occt.git] / src / HLRAlgo / HLRAlgo_PolyAlgo.cxx
1 // Created on: 1995-05-05
2 // Created by: Christophe MARION
3 // Copyright (c) 1995-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 #ifndef No_Exception
18 //#define No_Exception
19 #endif
20
21
22 #include <HLRAlgo_BiPoint.hxx>
23 #include <HLRAlgo_EdgeStatus.hxx>
24 #include <HLRAlgo_ListOfBPoint.hxx>
25 #include <HLRAlgo_PolyAlgo.hxx>
26 #include <HLRAlgo_PolyShellData.hxx>
27 #include <HLRAlgo_PolyMask.hxx>
28
29 #include <Precision.hxx>
30 #include <Standard_Type.hxx>
31
32 IMPLEMENT_STANDARD_RTTIEXT(HLRAlgo_PolyAlgo,Standard_Transient)
33
34 //static Standard_Integer ERROR = Standard_False;
35
36 //=======================================================================
37 //function : HLRAlgo_PolyAlgo
38 //purpose  : 
39 //=======================================================================
40
41 HLRAlgo_PolyAlgo::HLRAlgo_PolyAlgo ()
42 : myNbrShell(0),
43   myCurShell(0),
44   myFound(Standard_False)
45 {
46   myTriangle.TolParam   = 0.00000001;
47   myTriangle.TolAng = 0.0001;
48 }
49
50 //=======================================================================
51 //function : Init
52 //purpose  : 
53 //=======================================================================
54
55 void
56 HLRAlgo_PolyAlgo::Init (const Handle(TColStd_HArray1OfTransient)& HShell)
57 { myHShell = HShell; }
58
59 //=======================================================================
60 //function : Clear
61 //purpose  : 
62 //=======================================================================
63
64 void HLRAlgo_PolyAlgo::Clear ()
65 {
66   if (!myHShell.IsNull()) {
67     myHShell.Nullify();
68   }
69   myNbrShell = 0;
70 }
71
72 //=======================================================================
73 //function : Update
74 //purpose  : 
75 //=======================================================================
76
77 void HLRAlgo_PolyAlgo::Update ()
78 {
79   Standard_Integer i,j;
80   Standard_Integer nxMin,nyMin,nzMin,nxMax,nyMax,nzMax;
81   Standard_Real xShellMin,yShellMin,zShellMin;
82   Standard_Real xShellMax,yShellMax,zShellMax;
83   Standard_Real xPolyTMin,yPolyTMin,zPolyTMin;
84   Standard_Real xPolyTMax,yPolyTMax,zPolyTMax;
85   Standard_Real xTrianMin,yTrianMin,zTrianMin;
86   Standard_Real xTrianMax,yTrianMax,zTrianMax;
87   Standard_Real xSegmnMin,ySegmnMin,zSegmnMin;
88   Standard_Real xSegmnMax,ySegmnMax,zSegmnMax;
89   Standard_Real Big = Precision::Infinite();
90   HLRAlgo_PolyData::Box aBox(Big, Big, Big, -Big, -Big, -Big);
91   TColStd_Array1OfTransient& Shell = myHShell->ChangeArray1();
92   myNbrShell = Shell.Upper();
93   Handle(HLRAlgo_PolyShellData)* psd1 = 
94     (Handle(HLRAlgo_PolyShellData)*)&(Shell.ChangeValue(1));
95
96   for (i = 1; i <= myNbrShell; i++) {
97     (*psd1)->UpdateGlobalMinMax(aBox);
98     psd1++;
99   }
100
101   Standard_Real dx = aBox.XMax - aBox.XMin;
102   Standard_Real dy = aBox.YMax - aBox.YMin;
103   Standard_Real dz = aBox.ZMax - aBox.ZMin;
104   Standard_Real    precad = dx;
105   if (precad < dy) precad = dy;
106   if (precad < dz) precad = dz;
107   myTriangle.Tolerance = precad * myTriangle.TolParam;
108   precad = precad * 0.01;
109   Standard_Real SurDX = 1020 / (dx + precad);
110   Standard_Real SurDY = 1020 / (dy + precad);
111   Standard_Real SurDZ =  508 / (dz + precad);
112   precad = precad * 0.5;
113   Standard_Real DecaX = - aBox.XMin + precad;
114   Standard_Real DecaY = - aBox.YMin + precad;
115   Standard_Real DecaZ = - aBox.ZMin + precad;
116
117   Handle(HLRAlgo_PolyShellData)* psd2 = 
118     (Handle(HLRAlgo_PolyShellData)*)&(Shell.ChangeValue(1));
119
120   for (i = 1; i <= myNbrShell; i++) {
121     HLRAlgo_PolyShellData::ShellIndices& aShellIndices = (*psd2)->Indices();
122     xShellMin =  Big;
123     yShellMin =  Big;
124     zShellMin =  Big;
125     xShellMax = -Big;
126     yShellMax = -Big;
127     zShellMax = -Big;
128
129     for (mySegListIt.Initialize((*psd2)->Edges());
130          mySegListIt.More();
131          mySegListIt.Next()) {      
132       HLRAlgo_BiPoint& BP = mySegListIt.Value();
133       HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
134       HLRAlgo_BiPoint::IndicesT& theIndices = BP.Indices();
135       if (aPoints.PntP1.X() < aPoints.PntP2.X()) { xSegmnMin = aPoints.PntP1.X(); xSegmnMax = aPoints.PntP2.X(); }
136       else                 { xSegmnMin = aPoints.PntP2.X(); xSegmnMax = aPoints.PntP1.X(); }
137       if (aPoints.PntP1.Y() < aPoints.PntP2.Y()) { ySegmnMin = aPoints.PntP1.Y(); ySegmnMax = aPoints.PntP2.Y(); }
138       else                 { ySegmnMin = aPoints.PntP2.Y(); ySegmnMax = aPoints.PntP1.Y(); }
139       if (aPoints.PntP1.Z() < aPoints.PntP2.Z()) { zSegmnMin = aPoints.PntP1.Z(); zSegmnMax = aPoints.PntP2.Z(); }
140       else                 { zSegmnMin = aPoints.PntP2.Z(); zSegmnMax = aPoints.PntP1.Z(); }
141       nxMin = (Standard_Integer)((DecaX + xSegmnMin) * SurDX);
142       nyMin = (Standard_Integer)((DecaY + ySegmnMin) * SurDY);
143       nzMin = (Standard_Integer)((DecaZ + zSegmnMin) * SurDZ);
144       nxMax = (Standard_Integer)((DecaX + xSegmnMax) * SurDX);
145       nyMax = (Standard_Integer)((DecaY + ySegmnMax) * SurDY);
146       nzMax = (Standard_Integer)((DecaZ + zSegmnMax) * SurDZ);
147       theIndices.MinSeg = nyMin + (nxMin << 11);
148       theIndices.MinSeg <<= 10;
149       theIndices.MinSeg += nzMin;
150       theIndices.MaxSeg = nyMax + (nxMax << 11);
151       theIndices.MaxSeg <<= 10;
152       theIndices.MaxSeg += nzMax + 0x00000200;
153       if (xShellMin > xSegmnMin) xShellMin = xSegmnMin;
154       if (xShellMax < xSegmnMax) xShellMax = xSegmnMax;
155       if (yShellMin > ySegmnMin) yShellMin = ySegmnMin;
156       if (yShellMax < ySegmnMax) yShellMax = ySegmnMax;
157       if (zShellMin > zSegmnMin) zShellMin = zSegmnMin;
158       if (zShellMax < zSegmnMax) zShellMax = zSegmnMax;
159     }
160     TColStd_Array1OfTransient& Polyg = (*psd2)->PolyData();
161     Standard_Integer nbFace = Polyg.Upper();
162     Standard_Integer nbFaHi = 0;
163     Handle(HLRAlgo_PolyData)* pd = NULL;
164     if(nbFace > 0) pd = (Handle(HLRAlgo_PolyData)*)&(Polyg.ChangeValue(1));
165     
166     for (j = 1; j <= nbFace; j++) {
167       if ((*pd)->Hiding()) {
168         nbFaHi++;
169         xPolyTMin =  Big;
170         yPolyTMin =  Big;
171         zPolyTMin =  Big;
172         xPolyTMax = -Big;
173         yPolyTMax = -Big;
174         zPolyTMax = -Big;
175         Standard_Integer otheri,nbHide = 0;//min,max;
176         Standard_Real X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3;
177         Standard_Real dn,dnx,dny,dnz,dx1,dy1,dz1,dx2,dy2,dz2,dx3,dy3;
178         Standard_Real adx1,ady1,adx2,ady2,adx3,ady3;
179         Standard_Real a =0.,b =0.,c =0.,d =0.;
180         HLRAlgo_PolyData::FaceIndices& PolyTIndices = (*pd)->Indices();
181         TColgp_Array1OfXYZ   & Nodes        = (*pd)->Nodes();
182         HLRAlgo_Array1OfTData& TData        = (*pd)->TData();
183         HLRAlgo_Array1OfPHDat& PHDat        = (*pd)->PHDat();
184         Standard_Integer nbT = TData.Upper();
185         HLRAlgo_TriangleData* TD = &(TData.ChangeValue(1));
186         
187         for (otheri = 1; otheri <= nbT; otheri++) {
188           if (TD->Flags & HLRAlgo_PolyMask_FMskHiding) {
189             const gp_XYZ& P1 = Nodes(TD->Node1);
190             const gp_XYZ& P2 = Nodes(TD->Node2);
191             const gp_XYZ& P3 = Nodes(TD->Node3);
192             X1 = P1.X();
193             Y1 = P1.Y();
194             Z1 = P1.Z();
195             X2 = P2.X();
196             Y2 = P2.Y();
197             Z2 = P2.Z();
198             X3 = P3.X();
199             Y3 = P3.Y();
200             Z3 = P3.Z();
201             xTrianMax = xTrianMin = X1;
202             yTrianMax = yTrianMin = Y1;
203             zTrianMax = zTrianMin = Z1;
204             if      (xTrianMin > X2) xTrianMin = X2;
205             else if (xTrianMax < X2) xTrianMax = X2;
206             if      (yTrianMin > Y2) yTrianMin = Y2;
207             else if (yTrianMax < Y2) yTrianMax = Y2;
208             if      (zTrianMin > Z2) zTrianMin = Z2;
209             else if (zTrianMax < Z2) zTrianMax = Z2;
210             if      (xTrianMin > X3) xTrianMin = X3;
211             else if (xTrianMax < X3) xTrianMax = X3;
212             if      (yTrianMin > Y3) yTrianMin = Y3;
213             else if (yTrianMax < Y3) yTrianMax = Y3;
214             if      (zTrianMin > Z3) zTrianMin = Z3;
215             else if (zTrianMax < Z3) zTrianMax = Z3;
216             nxMin = (Standard_Integer)((DecaX + xTrianMin) * SurDX);
217             nyMin = (Standard_Integer)((DecaY + yTrianMin) * SurDY);
218             nzMin = (Standard_Integer)((DecaZ + zTrianMin) * SurDZ);
219             nxMax = (Standard_Integer)((DecaX + xTrianMax) * SurDX);
220             nyMax = (Standard_Integer)((DecaY + yTrianMax) * SurDY);
221             nzMax = (Standard_Integer)((DecaZ + zTrianMax) * SurDZ);
222             Standard_Integer MinTrian,MaxTrian;
223             MinTrian   = nyMin + (nxMin << 11);
224             MinTrian <<= 10;
225             MinTrian  += nzMin - 0x00000200;
226             MaxTrian   = nyMax + (nxMax << 11);
227             MaxTrian <<= 10;
228             MaxTrian  += nzMax;
229             dx1 = X2 - X1;
230             dy1 = Y2 - Y1;
231             dz1 = Z2 - Z1;
232             dx2 = X3 - X2;
233             dy2 = Y3 - Y2;
234             dz2 = Z3 - Z2;
235             dx3 = X1 - X3;
236             dy3 = Y1 - Y3;
237             dnx = dy1 * dz2 - dy2 * dz1;
238             dny = dz1 * dx2 - dz2 * dx1;
239             dnz = dx1 * dy2 - dx2 * dy1;
240             dn = sqrt(dnx * dnx + dny * dny + dnz * dnz);
241             if (dn > 0) {
242               a = dnx / dn;
243               b = dny / dn;
244               c = dnz / dn;
245             }
246             d = a * X1 + b * Y1 + c * Z1;
247             nbHide++;
248             PHDat(nbHide).Set(otheri,MinTrian,MaxTrian,a,b,c,d);
249             adx1 = dx1;
250             ady1 = dy1;
251             if (dx1 < 0) adx1 = -dx1;
252             if (dy1 < 0) ady1 = -dy1;
253             adx2 = dx2;
254             ady2 = dy2;
255             if (dx2 < 0) adx2 = -dx2;
256             if (dy2 < 0) ady2 = -dy2;
257             adx3 = dx3;
258             ady3 = dy3;
259             if (dx3 < 0) adx3 = -dx3;
260             if (dy3 < 0) ady3 = -dy3;
261             if (adx1 > ady1) TD->Flags |=  HLRAlgo_PolyMask_EMskGrALin1;
262             else             TD->Flags &= ~HLRAlgo_PolyMask_EMskGrALin1;
263             if (adx2 > ady2) TD->Flags |=  HLRAlgo_PolyMask_EMskGrALin2;
264             else             TD->Flags &= ~HLRAlgo_PolyMask_EMskGrALin2;
265             if (adx3 > ady3) TD->Flags |=  HLRAlgo_PolyMask_EMskGrALin3;
266             else             TD->Flags &= ~HLRAlgo_PolyMask_EMskGrALin3;
267             if (xPolyTMin > xTrianMin) xPolyTMin = xTrianMin;
268             if (xPolyTMax < xTrianMax) xPolyTMax = xTrianMax;
269             if (yPolyTMin > yTrianMin) yPolyTMin = yTrianMin;
270             if (yPolyTMax < yTrianMax) yPolyTMax = yTrianMax;
271             if (zPolyTMin > zTrianMin) zPolyTMin = zTrianMin;
272             if (zPolyTMax < zTrianMax) zPolyTMax = zTrianMax;
273           }
274           TD++;
275         }
276         nxMin = (Standard_Integer)((DecaX + xPolyTMin) * SurDX);
277         nyMin = (Standard_Integer)((DecaY + yPolyTMin) * SurDY);
278         nzMin = (Standard_Integer)((DecaZ + zPolyTMin) * SurDZ);
279         nxMax = (Standard_Integer)((DecaX + xPolyTMax) * SurDX);
280         nyMax = (Standard_Integer)((DecaY + yPolyTMax) * SurDY);
281         nzMax = (Standard_Integer)((DecaZ + zPolyTMax) * SurDZ);
282         PolyTIndices.Min = nyMin + (nxMin << 11);
283         PolyTIndices.Min <<= 10;
284         PolyTIndices.Min  += nzMin - 0x00000200;
285         PolyTIndices.Max   = nyMax + (nxMax << 11);
286         PolyTIndices.Max <<= 10;
287         PolyTIndices.Max  += nzMax;
288         if (xShellMin > xPolyTMin) xShellMin = xPolyTMin;
289         if (xShellMax < xPolyTMax) xShellMax = xPolyTMax;
290         if (yShellMin > yPolyTMin) yShellMin = yPolyTMin;
291         if (yShellMax < yPolyTMax) yShellMax = yPolyTMax;
292         if (zShellMin > zPolyTMin) zShellMin = zPolyTMin;
293         if (zShellMax < zPolyTMax) zShellMax = zPolyTMax;
294       }
295       pd++;
296     }
297     if (nbFaHi > 0) {
298       nxMin = (Standard_Integer)((DecaX + xShellMin) * SurDX);
299       nyMin = (Standard_Integer)((DecaY + yShellMin) * SurDY);
300       nzMin = (Standard_Integer)((DecaZ + zShellMin) * SurDZ);
301       nxMax = (Standard_Integer)((DecaX + xShellMax) * SurDX);
302       nyMax = (Standard_Integer)((DecaY + yShellMax) * SurDY);
303       nzMax = (Standard_Integer)((DecaZ + zShellMax) * SurDZ);
304       aShellIndices.Min = nyMin + (nxMin << 11);
305       aShellIndices.Min <<= 10;
306       aShellIndices.Min += nzMin - 0x00000200;
307       aShellIndices.Max = nyMax + (nxMax << 11);
308       aShellIndices.Max <<= 10;
309       aShellIndices.Max += nzMax;
310       (*psd2)->UpdateHiding(nbFaHi);
311       TColStd_Array1OfTransient& PolHi = (*psd2)->HidingPolyData();
312       pd = (Handle(HLRAlgo_PolyData)*)&(Polyg.ChangeValue(1));
313       Handle(HLRAlgo_PolyData)* phd = 
314         (Handle(HLRAlgo_PolyData)*)&(PolHi.ChangeValue(1));
315       
316       for (j = 1; j <= nbFace; j++) {
317         if ((*pd)->Hiding()) {
318           *phd = *pd;
319           phd++;
320         }
321         pd++;
322       }
323     }
324     else {
325       (*psd2)->UpdateHiding(0);
326       aShellIndices.Min = 0;
327       aShellIndices.Max = 0;
328     }
329     psd2++;
330   }
331 }
332
333 //=======================================================================
334 //function : NextHide
335 //purpose  : 
336 //=======================================================================
337
338 void HLRAlgo_PolyAlgo::NextHide ()
339 {
340   myFound = Standard_False;
341   if (myCurShell != 0) {
342     mySegListIt.Next();
343     if (mySegListIt.More()) myFound = Standard_True;
344   }
345   if (!myFound) {
346     myCurShell++;
347
348 //POP ADN pour que cela marche sur WNT
349 //    while (myCurShell <= myNbrShell && !myFound) {
350 //      mySegListIt.Initialize((*(Handle(HLRAlgo_PolyShellData)*)&
351 //                            (myHShell->ChangeValue(myCurShell)))
352 //                           ->Edges());
353     while (myCurShell <= myNbrShell && !myFound) {
354           Handle(HLRAlgo_PolyShellData) data = 
355                   Handle(HLRAlgo_PolyShellData)::DownCast(myHShell->Value(myCurShell));
356       mySegListIt.Initialize(data->Edges());
357       if (mySegListIt.More()) myFound = Standard_True;
358       else                    myCurShell++;
359     }
360   }
361 }
362
363 //=======================================================================
364 //function : Hide
365 //purpose  : 
366 //=======================================================================
367
368 HLRAlgo_BiPoint::PointsT& HLRAlgo_PolyAlgo::Hide (
369                              HLRAlgo_EdgeStatus& status,
370                              Standard_Integer& Index,
371                              Standard_Boolean& reg1,
372                              Standard_Boolean& regn,
373                              Standard_Boolean& outl,
374                              Standard_Boolean& intl)
375 {
376   HLRAlgo_BiPoint& BP             = mySegListIt.Value();
377   HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
378   HLRAlgo_BiPoint::IndicesT& theIndices = BP.Indices();
379   status = HLRAlgo_EdgeStatus(0.,(Standard_ShortReal)myTriangle.TolParam,1.,(Standard_ShortReal)myTriangle.TolParam);
380   Index = theIndices.ShapeIndex;
381   reg1       = BP.Rg1Line();
382   regn       = BP.RgNLine();
383   outl       = BP.OutLine();
384   intl       = BP.IntLine();
385   if (BP.Hidden())
386     status.HideAll();
387   else {
388     Standard_Boolean HidingShell;
389     TColStd_Array1OfTransient& Shell = myHShell->ChangeArray1();
390     Handle(HLRAlgo_PolyShellData)* psd = 
391       (Handle(HLRAlgo_PolyShellData)*)&(Shell.ChangeValue(1));
392     
393     for (Standard_Integer s = 1; s <= myNbrShell; s++) {
394       if ((*psd)->Hiding()) {
395         HLRAlgo_PolyShellData::ShellIndices& aShellIndices = (*psd)->Indices();
396         if (((aShellIndices.Max - theIndices.MinSeg) & 0x80100200) == 0 &&
397             ((theIndices.MaxSeg - aShellIndices.Min) & 0x80100000) == 0) {
398           HidingShell = (s == myCurShell);
399           TColStd_Array1OfTransient& Face = (*psd)->HidingPolyData();
400           Standard_Integer nbFace = Face.Upper();
401           Handle(HLRAlgo_PolyData)* pd = 
402             (Handle(HLRAlgo_PolyData)*)&(Face.ChangeValue(1));
403           
404           for (Standard_Integer f = 1; f <= nbFace; f++) {
405             (*pd)->HideByPolyData(aPoints,
406                                   myTriangle,
407                                   theIndices,
408                                   HidingShell,
409                                   status);
410             pd++;
411           }
412         }
413       }
414       psd++;
415     }
416   }
417   return aPoints;
418 }
419
420 //=======================================================================
421 //function : NextShow
422 //purpose  : 
423 //=======================================================================
424
425 void HLRAlgo_PolyAlgo::NextShow ()
426 {
427   myFound = Standard_False;
428   if (myCurShell != 0) {
429     mySegListIt.Next();
430     if (mySegListIt.More()) myFound = Standard_True;
431   }
432   if (!myFound) {
433     myCurShell++;
434
435     while (myCurShell <= myNbrShell && !myFound) {
436       mySegListIt.Initialize((*(Handle(HLRAlgo_PolyShellData)*)&
437                               (myHShell->ChangeValue(myCurShell)))
438                              ->Edges());
439       if (mySegListIt.More()) myFound = Standard_True;
440       else                    myCurShell++;
441     }
442   }
443 }
444
445 //=======================================================================
446 //function : Show
447 //purpose  : 
448 //=======================================================================
449
450 HLRAlgo_BiPoint::PointsT& HLRAlgo_PolyAlgo::Show (
451                              Standard_Integer& Index,
452                              Standard_Boolean& reg1,
453                              Standard_Boolean& regn,
454                              Standard_Boolean& outl,
455                              Standard_Boolean& intl)
456 {
457   HLRAlgo_BiPoint& BP = mySegListIt.Value();
458   HLRAlgo_BiPoint::IndicesT& theIndices = BP.Indices();
459   HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
460   Index = theIndices.ShapeIndex;
461   reg1  = BP.Rg1Line();
462   regn  = BP.RgNLine();
463   outl  = BP.OutLine();
464   intl  = BP.IntLine();
465   return aPoints;
466 }
467