Nektar++
CADSurf.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: CADSystem.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 methods.
32 //
33 ////////////////////////////////////////////////////////////////////////////////
34 #include "CADSurf.h"
35 #include "CADCurve.h"
36 
37 #include <boost/geometry.hpp>
38 #include <boost/geometry/algorithms/assign.hpp>
39 #include <boost/geometry/geometries/point_xy.hpp>
40 #include <boost/geometry/geometries/polygon.hpp>
41 
42 namespace bg = boost::geometry;
43 typedef bg::model::d2::point_xy<double> point_xy;
44 
45 using namespace std;
46 
47 namespace Nektar
48 {
49 namespace NekMeshUtils
50 {
51 
53 {
54  NekDouble dist;
55  Array<OneD, NekDouble> uv = locuv(p, dist);
56 
57  WARNINGL1(dist < 1e-3, "large locuv distance");
58 
59  return uv;
60 }
61 
62 void CADSurf::OrientateEdges(CADSurfSharedPtr surf,
63  vector<EdgeLoopSharedPtr> &ein)
64 {
65  // this piece of code orientates the surface,
66  // it used to be face mesh but its easier to have it here
67  int np = 20;
68  vector<vector<Array<OneD, NekDouble>>> loopt;
69  for (int i = 0; i < ein.size(); i++)
70  {
71  vector<Array<OneD, NekDouble>> loop;
72  for (int j = 0; j < ein[i]->edges.size(); j++)
73  {
74  Array<OneD, NekDouble> bnds = ein[i]->edges[j]->GetBounds();
75  NekDouble dt = (bnds[1] - bnds[0]) / (np - 1);
76  if (ein[i]->edgeo[j] == CADOrientation::eForwards)
77  {
78  for (int k = 0; k < np - 1; k++)
79  {
80  NekDouble t = bnds[0] + dt * k;
81  Array<OneD, NekDouble> l = ein[i]->edges[j]->P(t);
82  Array<OneD, NekDouble> uv = surf->locuv(l);
83  loop.push_back(uv);
84  }
85  }
86  else
87  {
88  for (int k = np - 1; k > 0; k--)
89  {
90  NekDouble t = bnds[0] + dt * k;
91  Array<OneD, NekDouble> l = ein[i]->edges[j]->P(t);
92  Array<OneD, NekDouble> uv = surf->locuv(l);
93  loop.push_back(uv);
94  }
95  }
96  }
97  loopt.push_back(loop);
98  }
99 
100  vector<bg::model::polygon<point_xy, false, true>> polygons;
101 
102  for (int i = 0; i < loopt.size(); i++)
103  {
104  bg::model::polygon<point_xy, false, true> polygon;
105  vector<point_xy> points;
106  for (int j = 0; j < loopt[i].size(); j++)
107  {
108  points.push_back(point_xy(loopt[i][j][0], loopt[i][j][1]));
109  }
110  // boost requires for closed polygons (last point == first point)
111  points.push_back(point_xy(loopt[i][0][0], loopt[i][0][1]));
112 
113  bg::assign_points(polygon, points);
114 
115  NekDouble area = bg::area(polygon);
116 
117  ein[i]->area = area;
118 
119  point_xy cen(0.0, 0.0);
120  bg::centroid(polygon, cen);
121 
122  ein[i]->center = Array<OneD, NekDouble>(2);
123  ein[i]->center[0] = cen.x();
124  ein[i]->center[1] = cen.y();
125 
126  polygons.push_back(polygon);
127  }
128 
129  // order by absoulte area
130  int ct = 0;
131  do
132  {
133  ct = 0;
134  for (int i = 0; i < ein.size() - 1; i++)
135  {
136  if (fabs(ein[i]->area) < fabs(ein[i + 1]->area))
137  {
138  // swap
139  swap(ein[i], ein[i + 1]);
140  swap(loopt[i], loopt[i + 1]);
141  swap(polygons[i], polygons[i + 1]);
142  ct += 1;
143  }
144  }
145 
146  } while (ct > 0);
147 
148  // only need center points for inner loops
149  for (int i = 1; i < ein.size(); i++)
150  {
151  point_xy p(ein[i]->center[0], ein[i]->center[1]);
152 
153  if (!bg::within(p, polygons[i]))
154  {
155  Array<OneD, NekDouble> n1 = loopt[i][0];
156  Array<OneD, NekDouble> n2 = loopt[i][1];
157 
159  NekDouble mag = sqrt((n1[0] - n2[0]) * (n1[0] - n2[0]) +
160  (n1[1] - n2[1]) * (n1[1] - n2[1]));
161 
162  N[0] = (n2[1] - n1[1]) / mag;
163  N[1] = -1.0 * (n2[0] - n1[0]) / mag;
164 
166  P[0] = n1[0] + N[0];
167  P[1] = n1[1] + N[1];
168 
169  ein[i]->center = P;
170 
171  p = point_xy(P[0], P[1]);
172 
173  ASSERTL0(boost::geometry::within(p, polygons[i]),
174  "point is not side loop");
175  }
176  }
177 }
178 }
179 }
std::shared_ptr< CADSurf > CADSurfSharedPtr
Definition: CADCurve.h:51
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
STL namespace.
bg::model::d2::point_xy< double > point_xy
Definition: CADSurf.cpp:43
double NekDouble
#define WARNINGL1(condition, msg)
Definition: ErrorUtil.hpp:251