Nektar++
CADSurfOCE.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: CADSurf.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: cad object surface methods.
32 //
33 ////////////////////////////////////////////////////////////////////////////////
34 
36 
37 using namespace std;
38 
39 namespace Nektar
40 {
41 namespace NekMeshUtils
42 {
43 
44 std::string CADSurfOCE::key = GetCADSurfFactory().RegisterCreatorFunction(
45  "oce", CADSurfOCE::create, "CADSurfOCE");
46 
47 void CADSurfOCE::Initialise(int i, TopoDS_Shape in)
48 {
49  m_s = BRep_Tool::Surface(TopoDS::Face(in));
50 
51  if (in.Orientation() == 1)
52  {
53  m_orientation = CADOrientation::eBackwards;
54  }
55 
56  m_id = i;
57 
58  m_bounds = Array<OneD, NekDouble>(4);
59  BRepTools::UVBounds(TopoDS::Face(in), m_bounds[0], m_bounds[1], m_bounds[2],
60  m_bounds[3]);
61  m_sas = new ShapeAnalysis_Surface(m_s);
62  m_sas->SetDomain(m_bounds[0], m_bounds[1], m_bounds[2], m_bounds[3]);
63 
64  m_shape = in;
65 
66  m_2Dclass = new BRepTopAdaptor_FClass2d(TopoDS::Face(m_shape), 1e-4);
67 }
68 
69 Array<OneD, NekDouble> CADSurfOCE::GetBounds()
70 {
71  return m_bounds;
72 }
73 
74 void CADSurfOCE::GetBounds(NekDouble &umin, NekDouble &umax, NekDouble &vmin,
75  NekDouble &vmax)
76 {
77  umin = m_bounds[0];
78  umax = m_bounds[1];
79  vmin = m_bounds[2];
80  vmax = m_bounds[3];
81 }
82 
83 bool CADSurfOCE::IsPlanar()
84 {
85  if (m_sas->Adaptor3d()->GetType() == GeomAbs_Plane)
86  {
87  return true;
88  }
89 
90  return false;
91 }
92 
93 Array<OneD, NekDouble> CADSurfOCE::BoundingBox()
94 {
95  BRepMesh_IncrementalMesh brmsh(m_shape, 0.005);
96 
97  Bnd_Box B;
98  BRepBndLib::Add(m_shape, B);
99  NekDouble e = sqrt(B.SquareExtent()) * 0.01;
100  e = min(e, 5e-3);
101  B.Enlarge(e);
102  Array<OneD, NekDouble> ret(6);
103  B.Get(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
104  ret[0] /= 1000.0;
105  ret[1] /= 1000.0;
106  ret[2] /= 1000.0;
107  ret[3] /= 1000.0;
108  ret[4] /= 1000.0;
109  ret[5] /= 1000.0;
110  return ret;
111 }
112 
114  NekDouble &dist)
115 {
116  gp_Pnt loc(p[0] * 1000.0, p[1] * 1000.0, p[2] * 1000.0);
118 
119  gp_Pnt2d p2 = m_sas->ValueOfUV(loc, Precision::Confusion());
120 
121  TopAbs_State s = m_2Dclass->Perform(p2);
122 
123  if (s == TopAbs_OUT)
124  {
125  BRepBuilderAPI_MakeVertex v(loc);
126  BRepExtrema_DistShapeShape dss(
127  BRepTools::OuterWire(TopoDS::Face(m_shape)), v.Shape());
128  dss.Perform();
129  gp_Pnt np = dss.PointOnShape1(1);
130  p2 = m_sas->ValueOfUV(np, Precision::Confusion());
131  }
132 
133  uv[0] = p2.X();
134  uv[1] = p2.Y();
135  gp_Pnt p3 = m_sas->Value(p2);
136 
137  dist = p3.Distance(loc) / 1000.0;
138 
139  return uv;
140 }
141 
142 NekDouble CADSurfOCE::Curvature(Array<OneD, NekDouble> uv)
143 {
144 #if defined(NEKTAR_DEBUG)
145  Test(uv);
146 #endif
147 
148  GeomLProp_SLProps d(m_s, 2, Precision::Confusion());
149  d.SetParameters(uv[0], uv[1]);
150 
151  return d.MaxCurvature() * 1000.0;
152 }
153 
155 {
156 #if defined(NEKTAR_DEBUG)
157  Test(uv);
158 #endif
159 
160  gp_Pnt loc = m_s->Value(uv[0], uv[1]);
161  Array<OneD, NekDouble> location(3);
162  location[0] = loc.X() / 1000.0;
163  location[1] = loc.Y() / 1000.0;
164  location[2] = loc.Z() / 1000.0;
165  return location;
166 }
167 
169  NekDouble &z)
170 {
171 #if defined(NEKTAR_DEBUG)
172  Test(uv);
173 #endif
174 
175  gp_Pnt loc = m_s->Value(uv[0], uv[1]);
176  x = loc.X() / 1000.0;
177  y = loc.Y() / 1000.0;
178  z = loc.Z() / 1000.0;
179 }
180 
182 {
183 #if defined(NEKTAR_DEBUG)
184  Test(uv);
185 #endif
186 
187  GeomLProp_SLProps d(m_s, 2, Precision::Confusion());
188  d.SetParameters(uv[0], uv[1]);
189 
190  Array<OneD, NekDouble> normal(3);
191 
192  if (!d.IsNormalDefined())
193  {
194  normal = Array<OneD, NekDouble>(3, 0.0);
195  return normal;
196  }
197 
198  gp_Dir n = d.Normal();
199 
200  if (m_orientation == CADOrientation::eBackwards)
201  {
202  n.Reverse();
203  }
204 
205  normal[0] = n.X();
206  normal[1] = n.Y();
207  normal[2] = n.Z();
208 
209  return normal;
210 }
211 
213 {
214 #if defined(NEKTAR_DEBUG)
215  Test(uv);
216 #endif
217 
219  gp_Pnt Loc;
220  gp_Vec D1U, D1V;
221  m_s->D1(uv[0], uv[1], Loc, D1U, D1V);
222 
223  r[0] = Loc.X() / 1000.0; // x
224  r[1] = Loc.Y() / 1000.0; // y
225  r[2] = Loc.Z() / 1000.0; // z
226  r[3] = D1U.X() / 1000.0; // dx/du
227  r[4] = D1U.Y() / 1000.0; // dy/du
228  r[5] = D1U.Z() / 1000.0; // dz/du
229  r[6] = D1V.X() / 1000.0; // dx/dv
230  r[7] = D1V.Y() / 1000.0; // dy/dv
231  r[8] = D1V.Z() / 1000.0; // dz/dv
232 
233  return r;
234 }
235 
237 {
238 #if defined(NEKTAR_DEBUG)
239  Test(uv);
240 #endif
241 
243  gp_Pnt Loc;
244  gp_Vec D1U, D1V, D2U, D2V, D2UV;
245  m_s->D2(uv[0], uv[1], Loc, D1U, D1V, D2U, D2V, D2UV);
246 
247  r[0] = Loc.X() / 1000.0; // x
248  r[1] = Loc.Y() / 1000.0; // y
249  r[2] = Loc.Z() / 1000.0; // z
250  r[3] = D1U.X() / 1000.0; // dx/dx
251  r[4] = D1U.Y() / 1000.0; // dy/dy
252  r[5] = D1U.Z() / 1000.0; // dz/dz
253  r[6] = D1V.X() / 1000.0; // dx/dx
254  r[7] = D1V.Y() / 1000.0; // dy/dy
255  r[8] = D1V.Z() / 1000.0; // dz/dz
256  r[9] = D2U.X() / 1000.0; // d2x/du2
257  r[10] = D2U.Y() / 1000.0; // d2y/du2
258  r[11] = D2U.Z() / 1000.0; // d2z/du2
259  r[12] = D2V.X() / 1000.0; // d2x/dv2
260  r[13] = D2V.Y() / 1000.0; // d2y/dv2
261  r[14] = D2V.Z() / 1000.0; // d2z/dv2
262  r[15] = D2UV.X() / 1000.0; // d2x/dudv
263  r[16] = D2UV.Y() / 1000.0; // d2y/dudv
264  r[17] = D2UV.Z() / 1000.0; // d2z/dudv
265 
266  return r;
267 }
268 
269 void CADSurfOCE::Test(Array<OneD, NekDouble> uv)
270 {
271  stringstream error;
272 
273  error << "Point not within parameter plane: ";
274 
275  bool passed = true;
276 
277  if (uv[0] < m_bounds[0])
278  {
279  if (fabs(uv[0] - m_bounds[0]) > 1E-6)
280  {
281  error << "U(" << uv[0] << ") is less than Umin(" << m_bounds[0]
282  << ")";
283  passed = false;
284  }
285  }
286  else if (uv[0] > m_bounds[1])
287  {
288  if (fabs(uv[0] - m_bounds[1]) > 1E-6)
289  {
290  error << "U(" << uv[0] << ") is greater than Umax(" << m_bounds[1]
291  << ")";
292  passed = false;
293  }
294  }
295  else if (uv[1] < m_bounds[2])
296  {
297  if (fabs(uv[1] - m_bounds[2]) > 1E-6)
298  {
299  error << "V(" << uv[1] << ") is less than Vmin(" << m_bounds[2]
300  << ")";
301  passed = false;
302  }
303  }
304  else if (uv[1] > m_bounds[3])
305  {
306  if (fabs(uv[1] - m_bounds[3]) > 1E-6)
307  {
308  error << "V(" << uv[1] << ") is greater than Vmax(" << m_bounds[3]
309  << ")";
310  passed = false;
311  }
312  }
313 
314  error << " On Surface: " << GetId();
315  ASSERTL1(passed, "Warning: " + error.str());
316  (void)passed; // suppress warning
317 }
318 } // namespace NekMeshUtils
319 } // namespace Nektar
STL namespace.
CADSurfFactory & GetCADSurfFactory()
Definition: CADSystem.cpp:65
double NekDouble
DNekMat void Add(NekMatrix< DataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const NekMatrix< RhsDataType, RhsMatrixType > &rhs)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:199
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250