Developer Documentation
Loading...
Searching...
No Matches
OBJNode.cc
1/*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40\*===========================================================================*/
41
42
43
44
45
46//=============================================================================
47//
48// CLASS FastMeshNode - IMPLEMENTATION
49//
50//=============================================================================
51
52
53//== INCLUDES =================================================================
54
55
56#include "OBJNode.hh"
57
58#include <cstdio>
59
60//== NAMESPACES ===============================================================
61
62namespace ACG {
63namespace SceneGraph {
64
65
66//== IMPLEMENTATION ==========================================================
67
68
69void
71boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
72{
75
76 for(unsigned int i=0; i<vertices_.size(); ++i)
77 {
78 bbMin.minimize(vertices_[i]);
79 bbMax.maximize(vertices_[i]);
80 }
81
82 Vec3d bbMind = ACG::Vec3d(bbMin);
83 Vec3d bbMaxd = ACG::Vec3d(bbMax);
84
85 _bbMin.minimize(bbMind);
86 _bbMax.maximize(bbMaxd);
87
88}
89
90
91//----------------------------------------------------------------------------
92
93
104
105
106//----------------------------------------------------------------------------
107
108
109void
111draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
112{
113 if (_drawMode & DrawModes::POINTS)
114 {
115 ACG::GLState::disable(GL_LIGHTING);
117 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
118 draw_obj();
119 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
120 }
121
122
123 if (_drawMode & DrawModes::WIREFRAME)
124 {
125 ACG::GLState::disable(GL_LIGHTING);
127 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
128 draw_obj();
129 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
130 }
131
132
133 else if (_drawMode & DrawModes::HIDDENLINE)
134 {
135 Vec4f base_color_backup = _state.base_color();
136
137 ACG::GLState::disable(GL_LIGHTING);
139
140 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
141 glColor(_state.clear_color());
142 ACG::GLState::depthRange(0.01, 1.0);
143 draw_obj();
144
145 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
146 glColor(base_color_backup);
147 ACG::GLState::depthRange(0.0, 1.0);
148 draw_obj();
149
150 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
151 }
152
153
154 else if (_drawMode & DrawModes::SOLID_FLAT_SHADED)
155 {
156 ACG::GLState::enable(GL_LIGHTING);
158 draw_obj();
159 }
160
161
162 else if (_drawMode & DrawModes::SOLID_TEXTURED)
163 {
164 ACG::GLState::enable( GL_TEXTURE_2D );
165 ACG::GLState::disable(GL_LIGHTING);
167 draw_obj_tex();
168 ACG::GLState::disable( GL_TEXTURE_2D );
169 }
170}
171
172
173//----------------------------------------------------------------------------
174
175
176void
177OBJNode::draw_obj() const
178{
179 glBegin(GL_TRIANGLES);
180
181 for(unsigned int i=0; i<faces_.size(); ++i)
182 {
183 glNormal(normals_[i]);
184 glVertex(vertices_[faces_[i].i0]);
185 glVertex(vertices_[faces_[i].i1]);
186 glVertex(vertices_[faces_[i].i2]);
187 }
188
189 glEnd();
190}
191
192
193//----------------------------------------------------------------------------
194
195
196void
197OBJNode::draw_obj_tex() const
198{
199 glBegin(GL_TRIANGLES);
200
201 for(unsigned int i=0; i<faces_.size(); ++i)
202 {
203 glNormal(normals_[i]);
204 if (faces_[i].t0 != -1)
205 {
206 glTexCoord(texCoords_[faces_[i].t0]);
207 glVertex(vertices_[faces_[i].i0]);
208 glTexCoord(texCoords_[faces_[i].t1]);
209 glVertex(vertices_[faces_[i].i1]);
210 glTexCoord(texCoords_[faces_[i].t2]);
211 glVertex(vertices_[faces_[i].i2]);
212 }
213 else
214 {
215 glVertex(vertices_[faces_[i].i0]);
216 glVertex(vertices_[faces_[i].i1]);
217 glVertex(vertices_[faces_[i].i2]);
218 }
219 }
220
221 glEnd();
222}
223
224
225//----------------------------------------------------------------------------
226
227
228void
230{
231 switch (_target)
232 {
233 case PICK_VERTEX:
234 {
235 break;
236 }
237 case PICK_EDGE:
238 {
239 break;
240 }
241 case PICK_ANYTHING:
242 case PICK_FACE:
243 {
244 _state.pick_set_maximum (1);
245 _state.pick_set_name (0);
246 draw_obj();
247 break;
248 }
249
250 default: // avoid warning
251 break;
252 }
253}
254
255
256//----------------------------------------------------------------------------
257
258
259bool
260OBJNode::read(const std::string& _filename)
261{
262 FILE* in = fopen(_filename.c_str(), "r");
263 if (!in) return false;
264
265
266 char s[200];
267 float x, y, z, u, v;
268
269
270 // clear mesh
271 vertices_.clear();
272 texCoords_.clear();
273 faces_.clear();
274
275
276
277 while(!feof(in) && fgets(s, 200, in))
278 {
279 // comment
280 if (s[0] == '#') continue;
281
282
283 // vertex
284 else if (strncmp(s, "v ", 2) == 0)
285 {
286 if (sscanf(s, "v %30f %30f %30f", &x, &y, &z))
287 {
288 vertices_.push_back(Vec3f(x,y,z));
289 }
290 }
291
292
293 // texture coord
294 else if (strncmp(s, "vt ", 3) == 0)
295 {
296 if (sscanf(s, "vt %40f %40f", &u, &v))
297 texCoords_.push_back(Vec2f(u, v));
298 }
299
300
301 // face
302 else if (strncmp(s, "f ", 2) == 0)
303 {
304 std::vector<unsigned int> vIdx, tIdx;
305 int component(0), nV(0);
306 bool endOfVertex(false);
307 char* p1(s+2);
308
309 vIdx.clear();
310 tIdx.clear();
311
312
313 while(p1)
314 {
315 char* p0 = p1;
316
317 // overwrite next separator
318 if (p1)
319 {
320 while (*p1 != '/' && *p1 != '\r' && *p1 != '\n' &&
321 *p1 != ' ' && *p1 != '\0')
322 p1++;
323
324 // detect end of vertex
325 if (*p1 != '/') endOfVertex = true;
326
327 // replace separator by '\0'
328 if (*p1 != '\0')
329 {
330 *p1 = '\0';
331 p1++; // point to next token
332 }
333
334 // detect end of line and break
335 if (*p1 == '\0' || *p1 == '\n')
336 p1 = 0;
337 }
338
339 if (*p0 != '\0')
340 {
341 switch (component)
342 {
343 case 0: vIdx.push_back(atoi(p0)-1); break;
344 case 1: tIdx.push_back(atoi(p0)-1); break;
345 case 2: /* ignore vertex normals */ break;
346 }
347
348 component++;
349
350 if (endOfVertex)
351 {
352 component = 0;
353 nV++;
354 endOfVertex = false;
355 }
356 }
357 }
358
359
360 if (vIdx.size() >= 3)
361 {
362 // texture
363 if (vIdx.size() == tIdx.size())
364 {
365 for (unsigned int i1=1, i2=2; i2 < vIdx.size(); ++i1, ++i2)
366 faces_.push_back(Face(vIdx[0], vIdx[i1], vIdx[i2],
367 tIdx[0], tIdx[i1], tIdx[i2]));
368 }
369
370 // no texture
371 else
372 {
373 for (unsigned int i1=1, i2=2; i2 < vIdx.size(); ++i1, ++i2)
374 {
375 faces_.push_back(Face(vIdx[0], vIdx[i1], vIdx[i2]));
376 }
377 }
378 }
379 }
380
381
382 s[0]=' ';
383 }
384
385
386 fclose(in);
387
389
390 return true;
391}
392
393
394//----------------------------------------------------------------------------
395
396
397void
399{
400 normals_.clear();
401 normals_.reserve(faces_.size());
402
403 std::vector<Face>::const_iterator f_it(faces_.begin()), f_end(faces_.end());
404 for (; f_it!=f_end; ++f_it)
405 {
406 const Vec3f& v0(vertex(f_it->i0));
407 const Vec3f& v1(vertex(f_it->i1));
408 const Vec3f& v2(vertex(f_it->i2));
409 normals_.push_back(((v1-v0) % (v2-v0)).normalize());
410 }
411}
412
413//=============================================================================
414} // namespace SceneGraph
415} // namespace ACG
416//=============================================================================
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition GLState.cc:1507
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition GLState.cc:1061
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition GLState.hh:951
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition GLState.cc:1051
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
Definition GLState.cc:1757
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition GLState.cc:1527
const Vec4f & clear_color() const
get background color
Definition GLState.hh:946
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition GLState.cc:1729
bool read(const std::string &_filename)
Read from file. Implemented using OpenMesh loader and OBJNodeExporter.
Definition OBJNode.cc:260
DrawModes::DrawMode availableDrawModes() const override
return available draw modes
Definition OBJNode.cc:96
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
drawing the primitive
Definition OBJNode.cc:111
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
update bounding box
Definition OBJNode.cc:71
void pick(GLState &_state, PickTarget _target) override
picking
Definition OBJNode.cc:229
void update_face_normals()
Update face normals. Call when geometry changes.
Definition OBJNode.cc:398
Vec3f & vertex(unsigned int _i)
get i'th vertex
Definition OBJNode.hh:167
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition Vector11T.hh:588
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition Vector11T.hh:560
DrawMode WIREFRAME
draw wireframe
Definition DrawModes.cc:78
DrawMode HIDDENLINE
draw hidden line (2 rendering passes needed)
Definition DrawModes.cc:80
DrawMode POINTS
draw unlighted points using the default base color
Definition DrawModes.cc:73
DrawMode SOLID_TEXTURED
draw textured faces
Definition DrawModes.cc:88
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition DrawModes.cc:81
PickTarget
What target to use for picking.
Definition PickTarget.hh:74
@ PICK_EDGE
picks edges (may not be implemented for all nodes)
Definition PickTarget.hh:80
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition PickTarget.hh:84
@ PICK_FACE
picks faces (should be implemented for all nodes)
Definition PickTarget.hh:78
@ PICK_VERTEX
picks verices (may not be implemented for all nodes)
Definition PickTarget.hh:82
Namespace providing different geometric functions concerning angles.
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition gl.hh:144
void glNormal(const Vec3f &_n)
Wrapper: glNormal for Vec3f.
Definition gl.hh:135
VectorT< float, 3 > Vec3f
Definition VectorT.hh:119
void glVertex(const Vec2i &_v)
Wrapper: glVertex for Vec2i.
Definition gl.hh:95
VectorT< float, 2 > Vec2f
Definition VectorT.hh:102
void glTexCoord(const Vec2f &_t)
Wrapper: glTexCoord for Vec2f.
Definition gl.hh:116
VectorT< double, 3 > Vec3d
Definition VectorT.hh:121