Skip to content
Snippets Groups Projects

De/Serialization for wavefront object files

Merged Ludwig Jaeck requested to merge serialization into main
All threads resolved!
Files
7
+ 42
21
@@ -29,38 +29,59 @@ const double eps = 2e-16;
const double q_limit_series = 1e-2;
const int n_limit_series = 20;
} // namespace
ff::Polyhedron::Polyhedron(const PolyhedralTopology& topology, const std::vector<R3>& vertices)
: m_sym_Ci(topology.symmetry_Ci)
std::vector<ff::PolyhedralFace> precompute_faces(const ff::PolyhedralTopology& topology,
const std::vector<R3>& vertices)
{
m_faces.clear();
for (const PolygonalTopology& tf : topology.faces) {
std::vector<ff::PolyhedralFace> faces;
for (const ff::PolygonalTopology& tf : topology.faces) {
std::vector<R3> corners; // of one face
for (int i : tf.vertexIndices)
corners.push_back(vertices[i]);
m_faces.emplace_back(corners, tf.symmetry_S2);
faces.emplace_back(corners, tf.symmetry_S2);
}
if (m_faces.size() < 4)
if (faces.size() < 4)
throw std::runtime_error("Invalid polyhedron: less than four non-vanishing faces");
m_radius = 0;
m_volume = 0;
for (const PolyhedralFace& Gk : m_faces) {
m_radius = std::max(m_radius, Gk.radius3d());
m_volume += Gk.pyramidalVolume();
}
if (m_sym_Ci) {
if (m_faces.size() & 1)
if (topology.symmetry_Ci) {
if (faces.size() & 1)
throw std::runtime_error("Invalid polyhedron: odd #faces violates symmetry Ci");
size_t N = m_faces.size() / 2;
size_t N = faces.size() / 2;
// for this tests, m_faces must be in a specific order
for (size_t k = 0; k < N; ++k)
m_faces[k].assert_Ci(m_faces[2 * N - 1 - k]);
faces[k].assert_Ci(faces[2 * N - 1 - k]);
// keep only half of the faces
m_faces.erase(m_faces.begin() + N, m_faces.end());
faces.erase(faces.begin() + N, faces.end());
}
return faces;
}
double precompute_radius(const std::vector<ff::PolyhedralFace>& faces)
{
double radius = 0;
for (const ff::PolyhedralFace& Gk : faces)
radius = std::max(radius, Gk.radius3d());
return radius;
}
double precompute_volume(const std::vector<ff::PolyhedralFace>& faces, bool symmetry_Ci)
{
double volume = 0;
for (const ff::PolyhedralFace& Gk : faces)
volume += Gk.pyramidalVolume();
if (symmetry_Ci)
volume = 2 * volume;
return volume;
}
} // namespace
ff::Polyhedron::Polyhedron(const PolyhedralTopology& topology, const std::vector<R3>& vertices)
: m_topology(topology)
, m_vertices(vertices)
, m_sym_Ci(topology.symmetry_Ci)
, m_faces(precompute_faces(topology, vertices))
, m_radius(precompute_radius(m_faces))
, m_volume(precompute_volume(m_faces, m_sym_Ci))
{
}
void ff::Polyhedron::assert_platonic() const
Loading