cgv
Loading...
Searching...
No Matches
simple_mesh.h
1#pragma once
2
3#include <cstdint>
4#include <vector>
5
6#include <cgv/math/fvec.h>
7#include <cgv/math/fmat.h>
8#include <cgv/utils/file.h>
9#include <cgv/media/illum/textured_surface_material.h>
10#include <cgv/media/axis_aligned_box.h>
11#include <cgv/media/colored_model.h>
12
13#include "../lib_begin.h"
14
15namespace cgv {
16 namespace media {
17 namespace mesh {
19template <typename T>
22template <typename T>
23class CGV_API obj_loader_generic;
24
26class CGV_API simple_mesh_base : public colored_model
27{
28public:
40 enum class attribute_type {
41 begin=0, position=0, texcoords=1, normal=2, tangent=3, color=4, end=5
42 };
43 // flags to define a selection of attributes
45 AF_position = 1,
46 AF_texcoords = 2,
47 AF_normal = 4,
48 AF_tangent = 8,
49 AF_color = 16
50 };
51 static std::string get_attribute_name(attribute_type attr);
52 static AttributeFlags get_attribute_flag(attribute_type attr);
53 virtual bool has_attribute(attribute_type attr) const = 0;
54 virtual const uint8_t* get_attribute_ptr(attribute_type attr, idx_type ai = 0) const = 0;
55 virtual size_t get_attribute_size(attribute_type attr) const = 0;
56 virtual size_t get_attribute_offset(attribute_type attr) const = 0;
57protected:
58 std::vector<idx_type> position_indices;
59 std::vector<idx_type> tex_coord_indices;
60 std::vector<idx_type> normal_indices;
61 std::vector<idx_type> tangent_indices;
62 std::vector<idx_type> faces;
63 std::vector<idx_type> group_indices;
64 std::vector<std::string> group_names;
65 std::vector<idx_type> material_indices;
66 std::vector<mat_type> materials;
67public:
75 simple_mesh_base& operator=(const simple_mesh_base& smb);
77 simple_mesh_base& operator=(simple_mesh_base&& smb);
79 virtual idx_type get_nr_positions() const = 0;
81 virtual uint32_t get_coord_size() const = 0;
87 idx_type start_face();
96 idx_type new_corner(idx_type position_index, idx_type normal_index = -1, idx_type tex_coord_index = -1); //FIXME: -1 underflows unsigned int!
98 idx_type c2p(idx_type ci) const { return position_indices[ci]; }
100 idx_type c2n(idx_type ci) const { return normal_indices[ci]; }
102 bool has_normal_indices() const { return normal_indices.size() > 0 && normal_indices.size() == position_indices.size(); }
104 idx_type c2t(idx_type ci) const { return tex_coord_indices[ci]; }
106 bool has_tex_coord_indices() const { return tex_coord_indices.size() > 0 && tex_coord_indices.size() == position_indices.size(); }
108 idx_type get_nr_faces() const { return idx_type(faces.size()); }
110 idx_type get_nr_corners() const { return idx_type(position_indices.size()); }
117 idx_type begin_corner(idx_type fi) const { return faces[fi]; }
124 idx_type end_corner(idx_type fi) const { return fi + 1 == faces.size() ? idx_type(position_indices.size()) : faces[fi + 1]; }
126 idx_type face_degree(idx_type fi) const { return end_corner(fi) - begin_corner(fi); }
128 size_t get_nr_materials() const { return materials.size(); }
130 idx_type new_material() { materials.push_back(mat_type()); return idx_type(materials.size() - 1); }
132 const mat_type& get_material(size_t i) const { return materials[i]; }
134 mat_type& ref_material(size_t i) { return materials[i]; }
136 const idx_type& material_index(idx_type fi) const { return material_indices[fi]; }
138 idx_type& material_index(idx_type fi) { return material_indices[fi]; }
140 size_t get_nr_groups() const { return group_names.size(); }
142 const std::string& group_name(size_t i) const { return group_names[i]; }
144 std::string& group_name(size_t i) { return group_names[i]; }
146 idx_type new_group(const std::string& name) { group_names.push_back(name); return idx_type(group_names.size() - 1); }
148 const idx_type& group_index(idx_type fi) const { return group_indices[fi]; }
150 idx_type& group_index(idx_type fi) { return group_indices[fi]; }
152 void revert_face_orientation();
162 void sort_faces(std::vector<idx_type>& perm, bool by_group = true, bool by_material = true) const;
185 void merge_indices(std::vector<idx_type>& vertex_indices, std::vector<idx4_type>& unique_tuples,
186 bool* include_tex_coords_ptr = 0, bool* include_normals_ptr = 0, bool* include_tangents_ptr = 0) const;
198 void extract_triangle_element_buffer(const std::vector<idx_type>& vertex_indices,
199 std::vector<idx_type>& triangle_element_buffer,
200 const std::vector<idx_type>* face_permutation_ptr = 0,
201 std::vector<idx3_type>* material_group_start_ptr = 0) const;
210 void extract_wireframe_element_buffer(const std::vector<idx_type>& vertex_indices,
211 std::vector<idx_type>& edge_element_buffer) const;
213 idx_type extract_vertex_attribute_buffer_base(const std::vector<idx4_type>& unique_quadruples, AttributeFlags& flags, std::vector<uint8_t>& attrib_buffer) const;
215
230 idx_type compute_inv(
231 std::vector<idx_type>& inv,
232 bool link_non_manifold_edges = false,
233 std::vector<idx_type>* p2c_ptr = 0,
234 std::vector<idx_type>* next_ptr = 0,
235 std::vector<idx_type>* prev_ptr = 0,
236 std::vector<idx_type>* unmatched = 0,
237 std::vector<idx_type>* non_manifold = 0,
238 std::vector<idx_type>* unmatched_elements = 0,
239 std::vector<idx_type>* non_manifold_elements = 0) const;
241 idx_type compute_c2e(const std::vector<idx_type>& inv, std::vector<idx_type>& c2e, std::vector<idx_type>* e2c_ptr = 0) const;
243 void compute_c2f(std::vector<idx_type>& c2f) const;
244};
245
247template <typename T = float>
248class CGV_API simple_mesh : public simple_mesh_base
249{
250public:
251 using numeric_type = T;
252
263protected:
264 friend class simple_mesh_obj_reader<T>;
265 std::vector<vec3_type> positions;
266 std::vector<vec3_type> normals;
267 std::vector<vec3_type> tangents;
268 std::vector<vec2_type> tex_coords;
269 bool has_attribute(attribute_type attr) const {
270 switch (attr) {
271 case attribute_type::position: return true;
272 case attribute_type::texcoords: return has_tex_coords() && has_tex_coord_indices();
273 case attribute_type::normal: return has_normals() && has_normal_indices();
274 case attribute_type::tangent: return has_tangents();
275 case attribute_type::color: return has_colors();
276 default: /* see below */;
277 }
278 return false;
279 }
280 const uint8_t* get_attribute_ptr(attribute_type attr, idx_type ai = 0) const {
281 switch (attr) {
282 case attribute_type::position: return reinterpret_cast<const uint8_t*>( &positions[ai]);
283 case attribute_type::texcoords: return reinterpret_cast<const uint8_t*>(&tex_coords[ai]);
284 case attribute_type::normal: return reinterpret_cast<const uint8_t*>( &normals[ai]);
285 case attribute_type::tangent: return reinterpret_cast<const uint8_t*>( &tangents[ai]);
286 case attribute_type::color: return reinterpret_cast<const uint8_t*>(get_color_data_ptr()) + ai * get_color_size();
287 default: /* see below */;
288 }
289 return nullptr;
290 }
291 size_t get_attribute_size(attribute_type attr) const {
292 switch (attr) {
293 case attribute_type::position: return sizeof(vec3_type);
294 case attribute_type::texcoords: return sizeof(vec2_type);
295 case attribute_type::normal: return sizeof(vec3_type);
296 case attribute_type::tangent: return sizeof(vec3_type);
297 case attribute_type::color: return get_color_size();
298 default: /* see below */;
299 }
300 return 0;
301 }
302 size_t get_attribute_offset(attribute_type attr) const
303 {
304 size_t s = get_attribute_size(attr);
305 if (s < sizeof(T))
306 s = sizeof(T);
307 return s;
308 }
309 vec3_type compute_normal(const vec3_type& p0, const vec3_type& p1, const vec3_type& p2);
310public:
312 simple_mesh(const simple_mesh<T>& sm);
314 simple_mesh(simple_mesh<T>&& sm);
316 simple_mesh(const std::string& conway_notation = "");
318 simple_mesh<T>& operator= (const simple_mesh<T>& sm);
320 simple_mesh<T>& operator= (simple_mesh<T>&& sm);
322 uint32_t get_coord_size() const { return sizeof(T); }
324 void clear();
325
327 idx_type new_position(const vec3_type& p) { positions.push_back(p); return idx_type(positions.size()-1); }
329 idx_type get_nr_positions() const { return idx_type(positions.size()); }
330 vec3_type& position(idx_type pi) { return positions[pi]; }
331 const vec3_type& position(idx_type pi) const { return positions[pi]; }
332 const std::vector<vec3_type>& get_positions() const { return positions; }
333 std::vector<vec3_type>& ref_positions() { return positions; }
334
336 idx_type new_normal(const vec3_type& n) { normals.push_back(n); return idx_type(normals.size()-1); }
338 bool has_normals() const { return get_nr_normals() > 0; }
339 idx_type get_nr_normals() const { return idx_type(normals.size()); }
340 vec3_type& normal(idx_type ni) { return normals[ni]; }
341 const vec3_type& normal(idx_type ni) const { return normals[ni]; }
342 const std::vector<vec3_type>& get_normals() const { return normals; }
343
345 idx_type new_tangent(const vec3_type& tc) { tangents.push_back(tc); return idx_type(tangents.size() - 1); }
347 bool has_tangents() const { return get_nr_tangents() > 0; }
348 idx_type get_nr_tangents() const { return idx_type(tangents.size()); }
349 vec3_type& tangent(idx_type ti) { return tangents[ti]; }
350 const vec3_type& tangent(idx_type ti) const { return tangents[ti]; }
351
353 idx_type new_tex_coord(const vec2_type& tc) { tex_coords.push_back(tc); return idx_type(tex_coords.size() - 1); }
355 bool has_tex_coords() const { return get_nr_tex_coords() > 0; }
356 idx_type get_nr_tex_coords() const { return idx_type(tex_coords.size()); }
357 vec2_type& tex_coord(idx_type ti) { return tex_coords[ti]; }
358 const vec2_type& tex_coord(idx_type ti) const { return tex_coords[ti]; }
359
361 bool compute_face_normal(idx_type fi, vec3_type& nml, bool normalize = true) const;
363 vec3_type compute_face_center(idx_type fi) const;
365 void compute_face_normals(bool construct_normal_indices = true);
367 void compute_face_tangents(bool construct_tangent_indices = true);
369 void ambo();
371 void truncate(T lambda = 0.33333f);
373 void snub(T lambda = 0.33333f);
375 void dual();
377 void gyro(T lambda = 0.3333f);
379 void join();
381 void ortho();
383 void construct_conway_polyhedron(const std::string& conway_notation);
384
386 box_type compute_box() const;
388 void compute_vertex_normals(bool use_parallel_implementation = true);
390 void construct(const obj_loader_generic<T>& loader, bool copy_grp_info, bool copy_material_info);
392 bool read(const std::string& file_name);
394 bool write(const std::string& file_name) const;
407 unsigned extract_vertex_attribute_buffer(const std::vector<idx4_type>& unique_quadruples, bool include_tex_coords,
408 bool include_normals, bool include_tangents, std::vector<T>& attrib_buffer,
409 bool* include_colors_ptr = 0, int* num_floats_in_vertex = nullptr) const;
411 void transform(const mat3_type& linear_transformation, const vec3_type& translation);
413 void transform(const mat3_type& linear_transform, const vec3_type& translation, const mat3_type& inverse_linear_transform);
414};
415
416 }
417 }
418}
419
420#include <cgv/config/lib_end.h>
matrix of fixed size dimensions
Definition fmat.h:23
A vector with zero based index.
Definition fvec.h:26
An axis aligned box, defined by to points: min and max.
represent a color with components of given type and color and alpha model as specified.
Definition color.h:574
coordinate type independent base class of simple mesh data structure that handles indices and colors.
simple class to hold the material properties of a phong material
implements the virtual interface of the obj_reader and stores all read information.
Definition obj_loader.h:65
coordinate type independent base class of simple mesh data structure that handles indices and colors.
Definition simple_mesh.h:27
const mat_type & get_material(size_t i) const
return const reference to i-th material
idx_type new_material()
add a new material and return its index
cgv::type::uint32_type idx_type
define index type
Definition simple_mesh.h:30
idx_type end_corner(idx_type fi) const
Retrieve index of the vertex which follows the end corner of a face.
const std::string & group_name(size_t i) const
return the name of the i-th face group
mat_type & ref_material(size_t i)
return reference to i-th material
size_t get_nr_groups() const
return number of face groups
const idx_type & material_index(idx_type fi) const
return material index of given face
cgv::math::fvec< idx_type, 4 > idx4_type
define index quadruple type
Definition simple_mesh.h:36
idx_type get_nr_corners() const
return the number of corners
const idx_type & group_index(idx_type fi) const
return group index of given face
std::string & group_name(size_t i)
set a new group name
bool has_normal_indices() const
return whether normal indices are stored
idx_type c2t(idx_type ci) const
return texture index of corner
idx_type & group_index(idx_type fi)
return reference to group index of given face
bool has_tex_coord_indices() const
return whether texture coordinate indices are stored
idx_type c2p(idx_type ci) const
return position index of corner
Definition simple_mesh.h:98
size_t get_nr_materials() const
return number of materials in mesh
virtual idx_type get_nr_positions() const =0
position count
idx_type c2n(idx_type ci) const
return normal index of corner
illum::textured_surface_material mat_type
define material type
Definition simple_mesh.h:38
virtual uint32_t get_coord_size() const =0
return the size of one coordinate in bytes
idx_type new_group(const std::string &name)
add a new group and return its index
attribute_type
different mesh attributes
Definition simple_mesh.h:40
idx_type & material_index(idx_type fi)
return reference to material index of given face
idx_type get_nr_faces() const
return the number of faces
idx_type begin_corner(idx_type fi) const
Retrieve the vertex index of the first corner of a face.
cgv::math::fvec< idx_type, 2 > idx2_type
define index pair type
Definition simple_mesh.h:32
idx_type face_degree(idx_type fi) const
return number of edges/corners of face with index fi
cgv::math::fvec< idx_type, 3 > idx3_type
define index triple type
Definition simple_mesh.h:34
the simple_mesh class is templated over the coordinate type that defaults to float
cgv::math::fvec< T, 2 > vec2_type
type of 2d vector
idx_type get_nr_positions() const
access to positions
uint32_t get_coord_size() const
return the size of one coordinate in bytes
bool has_tangents() const
access to tangents
cgv::math::fmat< T, 3, 3 > mat3_type
linear transformation
cgv::math::fvec< T, 3 > vec3_type
type of 3d vector
bool has_tex_coords() const
access to texture coordinates
idx_type new_tangent(const vec3_type &tc)
add a new tangent and return tangent index
idx_type new_tex_coord(const vec2_type &tc)
add a new texture coordinate and return texture coordinate index
idx_type new_position(const vec3_type &p)
add a new position and return position index
simple_mesh< T > mesh_type
type of axis aligned 3d box
bool has_normals() const
access to normals
cgv::media::axis_aligned_box< T, 3 > box_type
type of axis aligned 3d box
idx_type new_normal(const vec3_type &n)
add a new normal and return normal index
unsigned int uint32_type
this type provides an 32 bit unsigned integer type
the cgv namespace
Definition print.h:11