Commit ed5f6d95 authored by Philip Trettner's avatar Philip Trettner
Browse files

first circulator, objs

parent 0a8a4f3e
......@@ -1042,6 +1042,76 @@ inline bool halfedge_handle::is_deleted() const
return !idx.is_valid() || !mesh->halfedge(idx).is_valid();
}
inline vertex_handle halfedge_handle::vertex_to() const
{
return mesh->handle_of(mesh->halfedge(idx).to_vertex);
}
inline vertex_handle halfedge_handle::vertex_from() const
{
return mesh->handle_of(mesh->halfedge(mesh->opposite(idx)).to_vertex);
}
inline face_handle halfedge_handle::face() const
{
return mesh->handle_of(mesh->halfedge(idx).face);
}
inline halfedge_handle halfedge_handle::next() const
{
return mesh->handle_of(mesh->halfedge(idx).next_halfedge);
}
inline halfedge_handle halfedge_handle::prev() const
{
return mesh->handle_of(mesh->halfedge(idx).prev_halfedge);
}
inline halfedge_handle halfedge_handle::opposite() const
{
return mesh->handle_of(mesh->opposite(idx));
}
inline face_handle halfedge_handle::opposite_face() const
{
return mesh->handle_of(mesh->halfedge(mesh->opposite(idx)).face);
}
inline halfedge_handle edge_handle::halfedgeA() const
{
return mesh->handle_of(mesh->halfedge_of(idx, 0));
}
inline halfedge_handle edge_handle::halfedgeB() const
{
return mesh->handle_of(mesh->halfedge_of(idx, 1));
}
inline face_handle vertex_handle::any_face() const
{
return mesh->handle_of(mesh->halfedge(mesh->vertex(idx).outgoing_halfedge).face);
}
inline halfedge_handle vertex_handle::any_halfedge() const
{
return mesh->handle_of(mesh->vertex(idx).outgoing_halfedge);
}
inline vertex_handle face_handle::any_vertex() const
{
return mesh->handle_of(mesh->halfedge(mesh->face(idx).halfedge).to_vertex);
}
inline halfedge_handle face_handle::any_halfedge() const
{
return mesh->handle_of(mesh->face(idx).halfedge);
}
inline face_vertex_ring face_handle::vertices() const
{
return {*this};
}
/// ======== PROPERTIES IMPLEMENTATION ========
template <typename PropT>
......
......@@ -13,6 +13,13 @@ struct edge_property;
template <typename PropT>
struct halfedge_property;
struct vertex_handle;
struct face_handle;
struct edge_handle;
struct halfedge_handle;
struct face_vertex_ring;
// ======================== INDICES ========================
struct face_index
......@@ -112,6 +119,17 @@ struct face_handle
bool is_valid() const; ///< valid idx and not deleted
bool is_deleted() const; ///< marked for deletion (or invalid idx)
vertex_handle any_vertex() const;
halfedge_handle any_halfedge() const;
face_vertex_ring vertices() const;
// TODO:
// faces (1-ring)
// edges
// halfedges
// vertices
};
struct vertex_handle
......@@ -133,6 +151,9 @@ struct vertex_handle
bool is_valid() const; ///< valid idx and not deleted
bool is_deleted() const; ///< marked for deletion (or invalid idx)
face_handle any_face() const;
halfedge_handle any_halfedge() const;
};
struct edge_handle
......@@ -154,6 +175,9 @@ struct edge_handle
bool is_valid() const; ///< valid idx and not deleted
bool is_deleted() const; ///< marked for deletion (or invalid idx)
halfedge_handle halfedgeA() const;
halfedge_handle halfedgeB() const;
};
struct halfedge_handle
......@@ -176,12 +200,13 @@ struct halfedge_handle
bool is_valid() const; ///< valid idx and not deleted
bool is_deleted() const; ///< marked for deletion (or invalid idx)
// TODO:
// vertex_to
// vertex_from
// face
// opposite_face
// opposite
vertex_handle vertex_to() const;
vertex_handle vertex_from() const;
face_handle face() const;
halfedge_handle next() const;
halfedge_handle prev() const;
halfedge_handle opposite() const;
face_handle opposite_face() const;
};
}
......@@ -224,4 +224,38 @@ struct halfedge_iterator
private:
halfedge_handle handle;
};
/// Iterates over all vertices of a given face
struct face_vertex_circulator
{
face_vertex_circulator() = default;
face_vertex_circulator(face_handle handle, bool not_at_begin) : handle(handle.any_halfedge()), not_at_begin(not_at_begin) {}
vertex_handle operator*() const { return handle.vertex_to(); }
face_vertex_circulator& operator++()
{
handle = handle.next();
not_at_begin = true;
return *this;
}
face_vertex_circulator operator++(int)
{
auto i = *this;
return ++i;
}
bool operator==(face_vertex_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin == rhs.not_at_begin && handle.idx == rhs.handle.idx;
}
bool operator!=(face_vertex_circulator const& rhs) const
{
assert(handle.mesh == rhs.handle.mesh && "comparing iterators from different meshes");
return not_at_begin != rhs.not_at_begin || handle.idx != rhs.handle.idx;
}
private:
halfedge_handle handle;
bool not_at_begin;
};
}
#include "obj_writer.hh"
#include <fstream>
#include "Mesh.hh"
using namespace polymesh;
obj_writer::obj_writer(const std::string &filename)
{
tmp_out = new std::ofstream(filename);
out = tmp_out;
}
obj_writer::obj_writer(std::ostream &out)
{
this->out = &out;
}
obj_writer::~obj_writer()
{
delete tmp_out;
}
void obj_writer::write_object_name(std::string object_name)
{
*out << "o " << object_name << "\n";
}
void obj_writer::write_mesh(const Mesh &mesh,
vertex_property<glm::vec3> const &position,
vertex_property<glm::vec2> const *tex_coord,
vertex_property<glm::vec3> const *normal)
{
auto base_v = vertex_idx;
auto base_t = texture_idx;
auto base_n = normal_idx;
for (auto v : mesh.vertices())
{
auto pos = v[position];
*out << "v " << pos.x << " " << pos.y << " " << pos.z << "\n";
++vertex_idx;
}
if (tex_coord)
for (auto v : mesh.vertices())
{
auto t = v[*tex_coord];
*out << "vt " << t.x << " " << t.y << "\n";
++texture_idx;
}
if (normal)
for (auto v : mesh.vertices())
{
auto n = v[*normal];
*out << "vn " << n.x << " " << n.y << " " << n.z << "\n";
++normal_idx;
}
for (auto f : mesh.faces())
{
*out << "f";
for (auto v : f.vertices())
{
auto i = v.idx.value;
*out << " ";
*out << base_v + i;
if (tex_coord || normal)
*out << "/";
if (tex_coord)
*out << base_t + i;
if (normal)
{
*out << base_n + i;
*out << "/";
}
}
*out << "\n";
}
}
#pragma once
#include <glm/glm.hpp>
#include <iostream>
#include <string>
#include "Mesh.hh"
namespace polymesh
{
struct obj_writer
{
obj_writer(std::string const& filename);
obj_writer(std::ostream& out);
~obj_writer();
void write_object_name(std::string object_name);
void write_mesh(Mesh const& mesh,
vertex_property<glm::vec3> const& position,
vertex_property<glm::vec2> const* tex_coord = nullptr,
vertex_property<glm::vec3> const* normal = nullptr);
private:
std::ostream* tmp_out = nullptr;
std::ostream* out = nullptr;
int vertex_idx = 1;
int texture_idx = 1;
int normal_idx = 1;
};
}
......@@ -26,7 +26,7 @@ struct vertex_collection
// TODO: delete
/// Creates a new vertex property
template<typename PropT>
template <typename PropT>
vertex_property<PropT> make_property(PropT const& def_value = PropT());
// Iteration:
......@@ -95,7 +95,7 @@ struct face_collection
// TODO: delete
/// Creates a new face property
template<typename PropT>
template <typename PropT>
face_property<PropT> make_property(PropT const& def_value = PropT());
// Iteration:
......@@ -152,7 +152,7 @@ struct edge_collection
// TODO: delete
/// Creates a new edge property
template<typename PropT>
template <typename PropT>
edge_property<PropT> make_property(PropT const& def_value = PropT());
// Iteration:
......@@ -208,7 +208,7 @@ struct halfedge_collection
halfedge_handle add_or_get(vertex_handle v_from, vertex_handle v_to);
/// Creates a new half-edge property
template<typename PropT>
template <typename PropT>
halfedge_property<PropT> make_property(PropT const& def_value = PropT());
// Iteration:
......@@ -246,4 +246,31 @@ struct valid_halfedge_collection
valid_halfedge_iterator end() const;
};
/// all vertices belonging to a face
struct face_vertex_ring
{
face_handle face;
/// Number of vertices
/// O(result) computation
int size() const;
// Iteration:
face_vertex_circulator begin() const { return {face, false}; }
face_vertex_circulator end() const { return {face, true}; }
};
/// ======== IMPLEMENTATION ========
inline int face_vertex_ring::size() const
{
auto cnt = 0;
for (auto v : *this)
{
(void)v; // unused
cnt++;
}
return cnt;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment