0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / IntPolyh / IntPolyh_Tools.cxx
CommitLineData
03cca6f7 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//=======================================================================
25void 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//=======================================================================
65static 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//=======================================================================
93void 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//=======================================================================
144Standard_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//=======================================================================
157void 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}