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