readOBJ.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "triSurface.H"
27 #include "IFstream.H"
28 #include "IStringStream.H"
29 
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
31 
32 bool Foam::triSurface::readOBJ(const fileName& OBJfileName)
33 {
34  IFstream OBJfile(OBJfileName);
35 
36  if (!OBJfile.good())
37  {
39  << "Cannot read file " << OBJfileName
40  << exit(FatalError);
41  }
42 
43  DynamicList<point> points;
44  DynamicList<labelledTri> faces;
45  HashTable<label> groupToPatch;
46 
47  label groupID = 0;
48  label maxGroupID = 0;
49 
50  while (OBJfile.good())
51  {
52  string line = getLineNoComment(OBJfile);
53 
54  label sz = line.size();
55 
56  if (sz && line[sz-1] == '\\')
57  {
58  line.substr(0, sz-1);
59  line += getLineNoComment(OBJfile);
60  }
61 
62  // Read first word
63  IStringStream lineStream(line);
64  word cmd;
65  lineStream >> cmd;
66 
67  if (cmd == "v")
68  {
69  scalar x, y, z;
70 
71  lineStream >> x >> y >> z;
72 
73  points.append(point(x, y, z));
74  }
75  else if (cmd == "g")
76  {
77  word group;
78 
79  lineStream >> group;
80 
82  groupToPatch.find(group);
83 
84  if (findGroup != groupToPatch.end())
85  {
86  groupID = findGroup();
87  }
88  else
89  {
90  groupID = maxGroupID;
91 
92  groupToPatch.insert(group, groupID);
93 
94  maxGroupID++;
95  }
96  }
97  else if (cmd == "f")
98  {
99  DynamicList<label> verts;
100 
101  // Assume 'f' is followed by space.
102  string::size_type endNum = 1;
103 
104  while (true)
105  {
106  string::size_type startNum =
107  line.find_first_not_of(" \r", endNum);
108 
109  if (startNum == string::npos)
110  {
111  break;
112  }
113 
114  endNum = line.find(' ', startNum);
115 
116  string vertexSpec;
117  if (endNum != string::npos)
118  {
119  vertexSpec = line.substr(startNum, endNum-startNum);
120  }
121  else
122  {
123  vertexSpec = line.substr(startNum, line.size() - startNum);
124  }
125 
126  string::size_type slashPos = vertexSpec.find('/');
127 
128  label vertI = 0;
129  if (slashPos != string::npos)
130  {
131  IStringStream intStream(vertexSpec.substr(0, slashPos));
132 
133  intStream >> vertI;
134  }
135  else
136  {
137  IStringStream intStream(vertexSpec);
138 
139  intStream >> vertI;
140  }
141  verts.append(vertI - 1);
142  }
143 
144  verts.shrink();
145 
146  // Do simple face triangulation around f[0].
147  // Cannot use face::triangulation since no complete points yet.
148  for (label fp = 1; fp < verts.size() - 1; fp++)
149  {
150  label fp1 = verts.fcIndex(fp);
151 
152  labelledTri tri(verts[0], verts[fp], verts[fp1], groupID);
153 
154  faces.append(tri);
155  }
156  }
157  }
158 
159  points.shrink();
160  faces.shrink();
161 
162  // Convert groupToPatch to patchList.
164 
165  if (maxGroupID == 0)
166  {
167  // Generate default patch
168  patches.setSize(1);
169  patches[0] = geometricSurfacePatch("empty", "patch0", 0);
170  }
171  else
172  {
173  forAllConstIter(HashTable<label>, groupToPatch, iter)
174  {
175  patches[iter()] = geometricSurfacePatch
176  (
177  "empty",
178  iter.key(),
179  iter()
180  );
181  }
182  }
183 
184 
185  // Transfer DynamicLists to straight ones.
186  pointField allPoints(move(points));
187 
188  // Create triSurface
189  *this = triSurface(faces, patches, allPoints, true);
190 
191  return true;
192 }
193 
194 
195 // ************************************************************************* //
scalar y
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
friend class const_iterator
Declare friendship with the const_iterator.
Definition: HashTable.H:197
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
void setSize(const label)
Reset size of List.
Definition: List.C:281
const Field< PointType > & points() const
Return reference to global points.
triSurface()
Construct null.
Definition: triSurface.C:535
const geometricSurfacePatchList & patches() const
Definition: triSurface.H:322
faceList faces() const
Return the list of triangles as a faceList.
Definition: triSurface.C:1131
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
const char *const group
Group name for atomic constants.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
List< geometricSurfacePatch > geometricSurfacePatchList
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
vector point
Point is a vector.
Definition: point.H:41
error FatalError