0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / IntPolyh / IntPolyh_Tools.cxx
1 // Created by: Eugeny MALTCHIKOV
2 // Copyright (c) 2017 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <IntPolyh_Tools.hxx>
16
17 #include <Adaptor3d_HSurface.hxx>
18 #include <Precision.hxx>
19 #include <IntCurveSurface_ThePolyhedronOfHInter.hxx>
20
21 //=======================================================================
22 //function : IsEnlargePossible
23 //purpose  :
24 //=======================================================================
25 void IntPolyh_Tools::IsEnlargePossible(const Handle(Adaptor3d_HSurface)& theSurf,
26                                        Standard_Boolean& theUEnlarge,
27                                        Standard_Boolean& theVEnlarge)
28 {
29   theUEnlarge = Standard_False;
30   theVEnlarge = Standard_False;
31
32   // In the context of IntPolyh_Intersection only BSpline and Bezier surfaces
33   // should be enlarged
34   if (theSurf->GetType() == GeomAbs_BSplineSurface ||
35       theSurf->GetType() == GeomAbs_BezierSurface)
36   {
37     // Check U periodicity and closeness
38     if (!theSurf->IsUClosed() && !theSurf->IsUPeriodic())
39     {
40       // Check that surface is not infinite in U direction
41       if (!Precision::IsInfinite(theSurf->FirstUParameter()) &&
42           !Precision::IsInfinite(theSurf->LastUParameter()))
43       {
44         theUEnlarge = Standard_True;
45       }
46     }
47
48     // Check V periodicity and closeness
49     if (!theSurf->IsVClosed() && !theSurf->IsVPeriodic())
50     {
51       // Check that surface is not infinite in V direction
52       if (!Precision::IsInfinite(theSurf->FirstVParameter()) &&
53           !Precision::IsInfinite(theSurf->LastVParameter()))
54       {
55         theVEnlarge = Standard_True;
56       }
57     }
58   }
59 }
60
61 //=======================================================================
62 //function : EnlargeZone
63 //purpose  : Enlarges the sampling zone of the surface
64 //=======================================================================
65 static void EnlargeZone(const Handle(Adaptor3d_HSurface)& theSurf,
66                         Standard_Real &u0,
67                         Standard_Real &u1,
68                         Standard_Real &v0,
69                         Standard_Real &v1)
70 {
71   Standard_Boolean isToEnlargeU, isToEnlargeV;
72   IntPolyh_Tools::IsEnlargePossible(theSurf, isToEnlargeU, isToEnlargeV);
73   // Enlarge U
74   if (isToEnlargeU)
75   {
76     Standard_Real delta_u = 0.01*Abs(u1 - u0);
77     u0 -= delta_u;
78     u1 += delta_u;
79   }
80
81   if (isToEnlargeV)
82   {
83     Standard_Real delta_v = 0.01*Abs(v1 - v0);
84     v0 -= delta_v;
85     v1 += delta_v;
86   }
87 }
88
89 //=======================================================================
90 //function : MakeSampling
91 //purpose  :
92 //=======================================================================
93 void IntPolyh_Tools::MakeSampling(const Handle(Adaptor3d_HSurface)& theSurf,
94                                   const Standard_Integer theNbSU,
95                                   const Standard_Integer theNbSV,
96                                   const Standard_Boolean theEnlargeZone,
97                                   TColStd_Array1OfReal& theUPars,
98                                   TColStd_Array1OfReal& theVPars)
99 {
100   // Resize arrays
101   theUPars.Resize(1, theNbSU, Standard_False);
102   theVPars.Resize(1, theNbSV, Standard_False);
103   //
104   Standard_Real u0, u1, v0, v1;
105   u0 = theSurf->FirstUParameter();
106   u1 = theSurf->LastUParameter();
107   v0 = theSurf->FirstVParameter();
108   v1 = theSurf->LastVParameter();
109
110   // Enlarge surface intersection zone if necessary
111   if (theEnlargeZone)
112     EnlargeZone(theSurf, u0, u1, v0, v1);
113
114   Standard_Integer aNbSamplesU1 = theNbSU - 1;
115   Standard_Integer aNbSamplesV1 = theNbSV - 1;
116
117   // U step
118   Standard_Real dU = (u1 - u0) / Standard_Real(aNbSamplesU1);
119   // V step
120   Standard_Real dV = (v1 - v0) / Standard_Real(aNbSamplesV1);
121
122   // Fill arrays
123   for (Standard_Integer i = 0; i < theNbSU; ++i) {
124     Standard_Real aU = u0 + i*dU;
125     if (i == aNbSamplesU1) {
126       aU = u1;
127     }
128     theUPars.SetValue(i + 1, aU);
129   }
130   //
131   for (Standard_Integer i = 0; i < theNbSV; ++i) {
132     Standard_Real aV = v0 + i*dV;
133     if (i == aNbSamplesV1) {
134       aV = v1;
135     }
136     theVPars.SetValue(i + 1, aV);
137   }
138 }
139
140 //=======================================================================
141 //function : ComputeDeflection
142 //purpose  : 
143 //=======================================================================
144 Standard_Real IntPolyh_Tools::ComputeDeflection(const Handle(Adaptor3d_HSurface)& theSurf,
145                                                 const TColStd_Array1OfReal& theUPars,
146                                                 const TColStd_Array1OfReal& theVPars)
147 {
148   IntCurveSurface_ThePolyhedronOfHInter polyhedron(theSurf, theUPars, theVPars);
149   Standard_Real aDeflTol = polyhedron.DeflectionOverEstimation();
150   return aDeflTol;
151 }
152
153 //=======================================================================
154 //function : FillArrayOfPointNormal
155 //purpose  : 
156 //=======================================================================
157 void IntPolyh_Tools::FillArrayOfPointNormal(const Handle(Adaptor3d_HSurface)& theSurf,
158                                             const TColStd_Array1OfReal& theUPars,
159                                             const TColStd_Array1OfReal& theVPars,
160                                             IntPolyh_ArrayOfPointNormal& thePoints)
161 {
162   Standard_Integer aNbU = theUPars.Length();
163   Standard_Integer aNbV = theVPars.Length();
164   Standard_Integer iCnt = 0;
165   thePoints.Init(aNbU * aNbV);
166   for (Standard_Integer i = 1; i <= aNbU; ++i)
167   {
168     Standard_Real aU = theUPars(i);
169
170     for (Standard_Integer j = 1; j <= aNbV; ++j)
171     {
172       Standard_Real aV = theVPars(j);
173       // Compute the point
174       gp_Pnt aP;
175       gp_Vec aDU, aDV;
176       theSurf->D1(aU, aV, aP, aDU, aDV);
177       // Compute normal
178       gp_Vec aVNorm = aDU.Crossed(aDV);
179       Standard_Real aLength = aVNorm.Magnitude();
180       if (aLength > gp::Resolution())
181       {
182         aVNorm /= aLength;
183       }
184       else
185       {
186         aVNorm.SetCoord(0.0, 0.0, 0.0);
187       }
188
189       // Save the pair
190       IntPolyh_PointNormal& aPN  = thePoints[iCnt];
191       aPN.Point = aP;
192       aPN.Normal = aVNorm;
193
194       ++iCnt;
195     }
196   }
197   thePoints.SetNbItems(iCnt);
198 }