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-2025 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  const string line = getLineNoComment(OBJfile);
53 
54  // Read first word
55  IStringStream lineStream(line);
56  word cmd;
57  lineStream >> cmd;
58 
59  if (cmd == "v")
60  {
61  scalar x, y, z;
62 
63  lineStream >> x >> y >> z;
64 
65  points.append(point(x, y, z));
66  }
67  else if (cmd == "g")
68  {
69  word group;
70 
71  lineStream >> group;
72 
74  groupToPatch.find(group);
75 
76  if (findGroup != groupToPatch.end())
77  {
78  groupID = findGroup();
79  }
80  else
81  {
82  groupID = maxGroupID;
83 
84  groupToPatch.insert(group, groupID);
85 
86  maxGroupID++;
87  }
88  }
89  else if (cmd == "f")
90  {
91  DynamicList<label> verts;
92 
93  // Assume 'f' is followed by space.
94  string::size_type endNum = 1;
95 
96  while (true)
97  {
98  string::size_type startNum =
99  line.find_first_not_of(" \r", endNum);
100 
101  if (startNum == string::npos)
102  {
103  break;
104  }
105 
106  endNum = line.find(' ', startNum);
107 
108  string vertexSpec;
109  if (endNum != string::npos)
110  {
111  vertexSpec = line.substr(startNum, endNum-startNum);
112  }
113  else
114  {
115  vertexSpec = line.substr(startNum, line.size() - startNum);
116  }
117 
118  string::size_type slashPos = vertexSpec.find('/');
119 
120  label vertI = 0;
121  if (slashPos != string::npos)
122  {
123  IStringStream intStream(vertexSpec.substr(0, slashPos));
124 
125  intStream >> vertI;
126  }
127  else
128  {
129  IStringStream intStream(vertexSpec);
130 
131  intStream >> vertI;
132  }
133  verts.append(vertI - 1);
134  }
135 
136  verts.shrink();
137 
138  // Do simple face triangulation around f[0].
139  // Cannot use face::triangulation since no complete points yet.
140  for (label fp = 1; fp < verts.size() - 1; fp++)
141  {
142  label fp1 = verts.fcIndex(fp);
143 
144  labelledTri tri(verts[0], verts[fp], verts[fp1], groupID);
145 
146  faces.append(tri);
147  }
148  }
149  }
150 
151  points.shrink();
152  faces.shrink();
153 
154  // Convert groupToPatch to patchList.
156 
157  if (maxGroupID == 0)
158  {
159  // Generate default patch
160  patches.setSize(1);
161  patches[0] = geometricSurfacePatch("empty", "patch0", 0);
162  }
163  else
164  {
165  forAllConstIter(HashTable<label>, groupToPatch, iter)
166  {
167  patches[iter()] = geometricSurfacePatch
168  (
169  "empty",
170  iter.key(),
171  iter()
172  );
173  }
174  }
175 
176 
177  // Transfer DynamicLists to straight ones.
178  pointField allPoints(move(points));
179 
180  // Create triSurface
181  *this = triSurface(faces, patches, allPoints, true);
182 
183  return true;
184 }
185 
186 
187 // ************************************************************************* //
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:492
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:320
faceList faces() const
Return the list of triangles as a faceList.
Definition: triSurface.C:1142
#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