Nektar++
CADSystem.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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: cad object methods.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <string>
37 #include <sstream>
38 #include <limits>
39 
40 #include <boost/algorithm/string.hpp>
41 #include <boost/filesystem.hpp>
42 
44 
45 using namespace std;
46 
47 namespace Nektar {
48 namespace LibUtilities {
49 
50 /**
51  * @brief Return the name of the CAD system.
52  */
53 string CADSystem::GetName()
54 {
55  return m_name;
56 }
57 
58 /**
59  * @brief Reports basic properties to screen.
60  */
61 void CADSystem::Report()
62 {
63  cout << endl << "CAD report:" << endl;
64  cout << "\tCAD has: " << m_curves.size() << " curves." << endl;
65  cout << "\tCAD has: " << m_surfs.size() << " surfaces." << endl;
66  cout << "\tCAD Euler-PoincarĂ© characteristic: " << m_epc << endl;
67 }
68 
69 /**
70  * @brief Returns bounding box of the domain.
71  *
72  * Gets the bounding box of the domain by considering the start and end
73  * points of each curve in the geometry.
74  *
75  * @return Array with 6 entries: xmin, xmax, ymin, ymax, zmin and zmax.
76  */
77 Array<OneD, NekDouble> CADSystem::GetBoundingBox()
78 {
79  Array<OneD, NekDouble> bound(6);
80  bound[0] = numeric_limits<double>::max(); //xmin
81  bound[1] = numeric_limits<double>::min(); //xmax
82  bound[2] = numeric_limits<double>::max(); //ymin
83  bound[3] = numeric_limits<double>::min(); //ymax
84  bound[4] = numeric_limits<double>::max(); //zmin
85  bound[5] = numeric_limits<double>::min(); //zmax
86 
87  for(int i = 1; i <= m_curves.size(); i++)
88  {
89  gp_Pnt start, end;
90  CADCurveSharedPtr c = GetCurve(i);
91  Array<OneD, NekDouble> ends = c->GetMinMax();
92 
93  bound[0] = min(bound[0], min(ends[0],ends[3]));
94  bound[1] = max(bound[1], max(ends[0],ends[3]));
95 
96  bound[2] = min(bound[2], min(ends[1],ends[4]));
97  bound[3] = max(bound[3], max(ends[1],ends[4]));
98 
99  bound[4] = min(bound[4], min(ends[2],ends[5]));
100  bound[5] = max(bound[5], max(ends[2],ends[5]));
101  }
102 
103  return bound;
104 }
105 
106 /**
107  * @brief Initialises CAD and makes surface and curve maps.
108  *
109  * @return true if completed successfully
110  */
111 bool CADSystem::LoadCAD()
112 {
113  if (!boost::filesystem::exists(m_name.c_str()))
114  {
115  return false;
116  }
117 
118  string ext;
119  size_t pos = m_name.find(".");
120  ext = m_name.substr(pos);
121 
122  TopoDS_Shape shape;
123 
124  if (boost::iequals(ext,".STEP") || boost::iequals(ext,".STP"))
125  {
126  // Takes step file and makes OpenCascade shape
127  STEPControl_Reader reader;
128  reader = STEPControl_Reader();
129  reader.ReadFile(m_name.c_str());
130  reader.NbRootsForTransfer();
131  reader.TransferRoots();
132  shape = reader.OneShape();
133  if(shape.IsNull())
134  {
135  return false;
136  }
137  }
138  else if(boost::iequals(ext,".IGES") || boost::iequals(ext,".IGS"))
139  {
140  // Takes IGES file and makes OpenCascade shape
141  IGESControl_Reader reader;
142  reader = IGESControl_Reader();
143  reader.ReadFile(m_name.c_str());
144  reader.NbRootsForTransfer();
145  reader.TransferRoots();
146  shape = reader.OneShape();
147  if(shape.IsNull())
148  {
149  return false;
150  }
151  }
152  else
153  {
154  return false;
155  }
156 
157  // From OpenCascade maps calculate Euler-Poincare number.
158  TopTools_IndexedMapOfShape fc, vc, ec;
159  TopExp::MapShapes(shape, TopAbs_FACE, fc);
160  TopExp::MapShapes(shape, TopAbs_EDGE, ec);
161  TopExp::MapShapes(shape, TopAbs_VERTEX, vc);
162 
163  m_epc = vc.Extent() - ec.Extent() + fc.Extent();
164 
165  TopTools_IndexedMapOfShape mapOfFaces;
166  TopTools_IndexedMapOfShape mapOfEdges;
167  TopExp::MapShapes(shape, TopAbs_FACE, mapOfFaces);
168 
169  // For each face of the geometry, get the local edges which bound it. If
170  // they are valid (their type != 7), then add them to an edge map. This
171  // filters out the dummy edges which OCC uses.
172  for(int i = 1; i <= mapOfFaces.Extent(); i++)
173  {
174  TopoDS_Shape face= mapOfFaces.FindKey(i);
175 
176  TopTools_IndexedMapOfShape localEdges;
177  TopExp::MapShapes(face, TopAbs_EDGE, localEdges);
178 
179  for(int j = 1; j <= localEdges.Extent(); j++)
180  {
181  TopoDS_Shape edge = localEdges.FindKey(j);
182  BRepAdaptor_Curve curve = BRepAdaptor_Curve(TopoDS::Edge(edge));
183  if(curve.GetType() != 7)
184  {
185  if(!(mapOfEdges.Contains(edge)))
186  {
187  mapOfEdges.Add(edge);
188  }
189  }
190  }
191  }
192 
193  map<int, vector<int> > adjsurfmap;
194 
195  // Adds edges to our type and map
196  for(int i = 1; i <= mapOfEdges.Extent(); i++)
197  {
198  TopoDS_Shape edge = mapOfEdges.FindKey(i);
199  AddCurve(i, edge);
200  }
201 
202  // For each face, examine all the wires (i.e. bounding loops) and
203  // investigates the loop. Using this information, connectivity is determined
204  // and edges are associated with surfaces.
205  for(int i = 1; i <= mapOfFaces.Extent(); i++)
206  {
207  vector<vector<pair<int,int> > > edges;
208 
209  TopoDS_Shape face = mapOfFaces.FindKey(i);
210 
211  TopTools_IndexedMapOfShape mapOfWires;
212  TopExp::MapShapes(face, TopAbs_WIRE, mapOfWires);
213 
214  for(int j = 1; j <= mapOfWires.Extent(); j++)
215  {
216  vector<pair<int,int> > edgeloop;
217 
218  TopoDS_Shape wire = mapOfWires.FindKey(j);
219 
220  ShapeAnalysis_Wire wiretest(TopoDS::Wire(wire),
221  TopoDS::Face(face),
222  1E-6);
223 
224  BRepTools_WireExplorer exp;
225 
226  exp.Init(TopoDS::Wire(wire));
227 
228  while(exp.More())
229  {
230  TopoDS_Shape edge = exp.Current();
231 
232  if(mapOfEdges.Contains(edge))
233  {
234  pair<int,int> e;
235  e.first = mapOfEdges.FindIndex(edge);
236  adjsurfmap[e.first].push_back(i);
237  e.second = exp.Orientation();
238  edgeloop.push_back(e);
239  }
240 
241  exp.Next();
242  }
243 
244  edges.push_back(edgeloop);
245  }
246 
247  AddSurf(i, face, edges);
248  }
249 
250  // This checks that all edges are bound by two surfaces, sanity check.
251  for(map<int,vector<int> >::iterator it = adjsurfmap.begin();
252  it != adjsurfmap.end(); it++)
253  {
254  ASSERTL0(it->second.size() == 2, "no three curve surfaces");
255  m_curves[it->first]->SetAdjSurf(it->second);
256  }
257 
258  return true;
259 }
260 
261 void CADSystem::AddCurve(int i, TopoDS_Shape in)
262 {
264  AllocateSharedPtr(i,in);
265  m_curves[i] = newCurve;
266 }
267 
268 void CADSystem::AddSurf(int i, TopoDS_Shape in,
269  std::vector<std::vector<std::pair<int,int> > > ein)
270 {
272  AllocateSharedPtr(i,in,ein);
273  m_surfs[i] = newSurf;
274 }
275 
276 }
277 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
STL namespace.
boost::shared_ptr< CADCurve > CADCurveSharedPtr
Definition: CADCurve.h:92
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::shared_ptr< CADSurf > CADSurfSharedPtr
Definition: CADSurf.h:109