Skip to content

Commit

Permalink
PolySet: Add setters for isTriangular (#5037)
Browse files Browse the repository at this point in the history
  • Loading branch information
kintel committed Mar 11, 2024
1 parent f96ef9b commit db167b1
Show file tree
Hide file tree
Showing 12 changed files with 40 additions and 27 deletions.
16 changes: 10 additions & 6 deletions src/RenderStatistic.cc
Expand Up @@ -242,8 +242,13 @@ void LogVisitor::printBoundingBox3(const BoundingBox& bb)
void LogVisitor::visit(const PolySet& ps)
{
assert(ps.getDimension() == 3);
LOG("Top level object is a 3D object:");
LOG(" Facets: %1$6d", ps.numFacets());
LOG("Top level object is a 3D object (PolySet):");
LOG(" Convex: %1$s", (ps.isConvex() ? "yes" : "no"));
if (ps.isTriangular()) {
LOG(" Triangles: %1$6d", ps.numFacets());
} else {
LOG(" Facets: %1$6d", ps.numFacets());
}
printBoundingBox3(ps.getBoundingBox());
}

Expand All @@ -252,7 +257,7 @@ void LogVisitor::visit(const CGAL_Nef_polyhedron& nef)
{
if (nef.getDimension() == 3) {
bool simple = nef.p3->is_simple();
LOG("Top level object is a 3D object:");
LOG("Top level object is a 3D object (Nef polyhedron):");
LOG(" Simple: %1$s", (simple ? "yes" : "no"));
LOG(" Vertices: %1$6d", nef.p3->number_of_vertices());
LOG(" Halfedges: %1$6d", nef.p3->number_of_halfedges());
Expand Down Expand Up @@ -285,14 +290,12 @@ void LogVisitor::visit(const ManifoldGeometry& mani_geom)
{
LOG(" Top level object is a 3D object (manifold):");
auto &mani = mani_geom.getManifold();
auto bbox = mani.BoundingBox();

LOG(" Status: %1$s", ManifoldUtils::statusToString(mani.Status()));
LOG(" Genus: %1$d", mani.Genus());
LOG(" Vertices: %1$6d", mani.NumVert());
LOG(" Facets: %1$6d", mani.NumTri());
LOG(" BBox.min: %1$f, %2$f, %3$f", bbox.min.x, bbox.min.y, bbox.min.z);
LOG(" BBox.max: %1$f, %2$f, %3$f", bbox.max.x, bbox.max.y, bbox.max.z);
printBoundingBox3(mani_geom.getBoundingBox());
}
#endif // ENABLE_MANIFOLD

Expand Down Expand Up @@ -355,6 +358,7 @@ void StreamVisitor::visit(const PolySet& ps)
nlohmann::json geometryJson;
geometryJson["dimensions"] = 3;
geometryJson["convex"] = ps.isConvex();
geometryJson["triangular"] = ps.isTriangular();
geometryJson["facets"] = ps.numFacets();
if (is_enabled(RenderStatistic::BOUNDING_BOX)) {
geometryJson["bounding_box"] = getBoundingBox3(ps);
Expand Down
11 changes: 6 additions & 5 deletions src/core/primitives.cc
Expand Up @@ -129,7 +129,7 @@ std::unique_ptr<const Geometry> CubeNode::createGeometry() const
z2 = this->z;
}
int dimension = 3;
auto ps = std::make_unique<PolySet>(3, true);
auto ps = std::make_unique<PolySet>(3, /*convex*/true);
for (int i = 0; i < 8; i++) {
ps->vertices.emplace_back(i & 1 ? x2 : x1, i & 2 ? y2 : y1,
i & 4 ? z2 : z1);
Expand Down Expand Up @@ -194,7 +194,7 @@ std::unique_ptr<const Geometry> SphereNode::createGeometry() const
// if (num_rings % 2 == 0) num_rings++; // To ensure that the middle ring is at
// phi == 0 degrees

auto polyset = std::make_unique<PolySet>(3, true);
auto polyset = std::make_unique<PolySet>(3, /*convex*/true);
polyset->vertices.reserve(num_rings * num_fragments);

// double offset = 0.5 * ((fragments / 2) % 2);
Expand Down Expand Up @@ -408,13 +408,14 @@ std::unique_ptr<const Geometry> PolyhedronNode::createGeometry() const
p->setConvexity(this->convexity);
p->vertices=this->points;
p->indices=this->faces;
p->isTriangular = true;
bool is_triangular = true;
for (auto &poly : p->indices) {
std::reverse(poly.begin(),poly.end());
if (p->isTriangular && poly.size() > 3) {
p->isTriangular = false;
if (is_triangular && poly.size() > 3) {
is_triangular = false;
}
}
p->setTriangular(is_triangular);
return p;
}

Expand Down
2 changes: 1 addition & 1 deletion src/geometry/GeometryEvaluator.cc
Expand Up @@ -76,7 +76,7 @@ std::shared_ptr<const Geometry> GeometryEvaluator::evaluateGeometry(const Abstra
ps = PolySetUtils::getGeometryAsPolySet(result);
assert(ps && ps->getDimension() == 3);
// We cannot render concave polygons, so tessellate any PolySets
if (!ps->isEmpty() && !ps->isTriangular) {
if (!ps->isEmpty() && !ps->isTriangular()) {
// Since is_convex() doesn't handle non-planar faces, we need to tessellate
// also in the indeterminate state so we cannot just use a boolean comparison. See #1061
bool convex = bool(ps->convexValue()); // bool is true only if tribool is true, (not indeterminate and not false)
Expand Down
7 changes: 5 additions & 2 deletions src/geometry/PolySet.cc
Expand Up @@ -46,7 +46,8 @@
*/

PolySet::PolySet(unsigned int dim, boost::tribool convex) : dim_(dim), convex_(convex)
PolySet::PolySet(unsigned int dim, boost::tribool convex)
: dim_(dim), convex_(convex)
{
}

Expand Down Expand Up @@ -108,7 +109,9 @@ void PolySet::transform(const Transform3d& mat)
bool PolySet::isConvex() const {
if (convex_ || this->isEmpty()) return true;
if (!convex_) return false;
return PolySetUtils::is_approximately_convex(*this);
bool is_convex = PolySetUtils::is_approximately_convex(*this);
convex_ = is_convex;
return is_convex;
}

void PolySet::resize(const Vector3d& newsize, const Eigen::Matrix<bool, 3, 1>& autosize)
Expand Down
5 changes: 4 additions & 1 deletion src/geometry/PolySet.h
Expand Up @@ -34,11 +34,14 @@ class PolySet : public Geometry

bool isConvex() const;
boost::tribool convexValue() const { return convex_; }
bool isTriangular = false;

bool isTriangular() const { return is_triangular_; }
void setTriangular(bool triangular) { is_triangular_ = triangular; }

static std::unique_ptr<PolySet> createEmpty() { return std::make_unique<PolySet>(3); }

private:
bool is_triangular_ = false;
unsigned int dim_;
mutable boost::tribool convex_;
mutable BoundingBox bbox_;
Expand Down
8 changes: 4 additions & 4 deletions src/geometry/PolySetBuilder.cc
Expand Up @@ -141,17 +141,17 @@ void PolySetBuilder::append(const PolySet& ps)

std::unique_ptr<PolySet> PolySetBuilder::build()
{
std::unique_ptr<PolySet> polyset;
polyset = std::make_unique<PolySet>(dim_, convex_);
auto polyset = std::make_unique<PolySet>(dim_, convex_);
vertices_.copy(std::back_inserter(polyset->vertices));
polyset->indices = std::move(indices_);
polyset->setConvexity(convexity_);
polyset->isTriangular = true;
bool is_triangular = true;
for (const auto& face : polyset->indices) {
if (face.size() > 3) {
polyset->isTriangular = false;
is_triangular = false;
break;
}
}
polyset->setTriangular(is_triangular);
return polyset;
}
4 changes: 2 additions & 2 deletions src/geometry/PolySetUtils.cc
Expand Up @@ -56,9 +56,9 @@ std::unique_ptr<PolySet> tessellate_faces(const PolySet& polyset)
int degeneratePolygons = 0;
auto result = std::make_unique<PolySet>(3, polyset.convexValue());
result->setConvexity(polyset.getConvexity());
result->isTriangular = true;
result->setTriangular(true);
// ideally this should not require a copy...
if (polyset.isTriangular) {
if (polyset.isTriangular()) {
result->vertices = polyset.vertices;
result->indices = polyset.indices;
return result;
Expand Down
2 changes: 1 addition & 1 deletion src/geometry/cgal/cgalutils.cc
Expand Up @@ -384,7 +384,7 @@ std::unique_ptr<PolySet> createPolySetFromNefPolyhedron3(const CGAL::Nef_polyhed
for (const auto& tri : allTriangles) {
polyset->indices.push_back({tri[0], tri[1], tri[2]});
}
polyset->isTriangular = true;
polyset->setTriangular(true);

#if 0 // For debugging
std::cerr.precision(20);
Expand Down
2 changes: 1 addition & 1 deletion src/geometry/manifold/ManifoldGeometry.cc
Expand Up @@ -94,7 +94,7 @@ std::string ManifoldGeometry::dump() const {
std::shared_ptr<const PolySet> ManifoldGeometry::toPolySet() const {
manifold::MeshGL mesh = getManifold().GetMeshGL();
auto ps = std::make_shared<PolySet>(3);
ps->isTriangular = true;
ps->setTriangular(true);
ps->vertices.reserve(mesh.NumVert());
ps->indices.reserve(mesh.NumTri());
ps->setConvexity(convexity);
Expand Down
4 changes: 2 additions & 2 deletions src/geometry/manifold/manifoldutils.cc
Expand Up @@ -36,9 +36,9 @@ const char* statusToString(Error status) {
std::shared_ptr<manifold::Manifold> trustedPolySetToManifold(const PolySet& ps) {
manifold::Mesh mesh;
std::unique_ptr<PolySet> buffer;
if (!ps.isTriangular)
if (!ps.isTriangular())
buffer = PolySetUtils::tessellate_faces(ps);
const PolySet& triangulated = ps.isTriangular ? ps : *buffer;
const PolySet& triangulated = ps.isTriangular() ? ps : *buffer;

auto numfaces = triangulated.indices.size();
const auto &vertices = triangulated.vertices;
Expand Down
4 changes: 3 additions & 1 deletion src/io/export.cc
Expand Up @@ -195,7 +195,9 @@ struct LexographicLess {

std::unique_ptr<PolySet> createSortedPolySet(const PolySet& ps)
{
auto out = PolySet::createEmpty();
auto out = std::make_unique<PolySet>(ps.getDimension(), ps.convexValue());
out->setTriangular(ps.isTriangular());
out->setConvexity(ps.getConvexity());

std::map<Vector3d, int, LexographicLess> vertexMap;

Expand Down
2 changes: 1 addition & 1 deletion src/io/export_stl.cc
Expand Up @@ -102,7 +102,7 @@ uint64_t append_stl(std::shared_ptr<const PolySet> polyset, std::ostream& output
static_assert(sizeof(float) == 4, "Need 32 bit float");

std::shared_ptr<const PolySet> ps = polyset;
if (!ps->isTriangular) {
if (!ps->isTriangular()) {
ps = PolySetUtils::tessellate_faces(*ps);
}
if (Feature::ExperimentalPredictibleOutput.is_enabled()) {
Expand Down

0 comments on commit db167b1

Please sign in to comment.