Calculate normals in manifold kernel

This commit is contained in:
Thomas Krijnen
2026-05-18 18:16:49 +02:00
parent 424e70ac86
commit 6dea7a5110
3 changed files with 31 additions and 7 deletions
@@ -180,6 +180,12 @@ namespace {
}
}
ifcopenshell::geometry::ManifoldShape::ManifoldShape(const manifold::Manifold& solid) {
auto copy = solid;
auto with_normals = copy.CalculateNormals(3);
parts_.push_back({with_normals.GetMeshGL64(), solid});
}
ifcopenshell::geometry::ManifoldShape::ManifoldShape(const ManifoldPart& part)
: parts_{ part } {}
@@ -221,6 +227,12 @@ void ifcopenshell::geometry::ManifoldShape::Triangulate(ifcopenshell::geometry::
mesh.vertProperties[i * mesh.numProp + 0],
mesh.vertProperties[i * mesh.numProp + 1],
mesh.vertProperties[i * mesh.numProp + 2]);
if (mesh.numProp == 6) {
t->addNormal(
mesh.vertProperties[i * mesh.numProp + 3],
mesh.vertProperties[i * mesh.numProp + 4],
mesh.vertProperties[i * mesh.numProp + 5]);
}
}
auto edges = count_edges(mesh);
for (size_t i = 0; i < mesh.NumTri(); ++i) {
@@ -499,7 +511,7 @@ ConversionResultShape* ifcopenshell::geometry::ManifoldShape::moved(ifcopenshell
if (part.solid && !solid) {
throw std::runtime_error("Failed to transform shape");
}
moved_parts.push_back({ std::move(mesh), std::move(solid) });
moved_parts.emplace_back(mesh, *solid);
}
return new ManifoldShape(std::move(moved_parts));
}
@@ -14,12 +14,24 @@ namespace geometry {
struct IFC_GEOMLIBRARY_API ManifoldPart {
manifold::MeshGL64 mesh;
std::optional<manifold::Manifold> solid;
ManifoldPart(const manifold::Manifold& s) {
auto copy = s;
copy.CalculateNormals(3);
mesh = copy.GetMeshGL64();
solid = s;
}
ManifoldPart(const manifold::MeshGL64& s) : mesh(s) {}
ManifoldPart(const manifold::MeshGL64& s, const manifold::Manifold& m) : mesh(s), solid(m) {}
};
class IFC_GEOMLIBRARY_API ManifoldShape : public IfcGeom::ConversionResultShape {
public:
ManifoldShape() = default;
explicit ManifoldShape(const ManifoldPart& part);
explicit ManifoldShape(const manifold::Manifold& part);
explicit ManifoldShape(const ManifoldPart& part);
explicit ManifoldShape(ManifoldPart&& part);
explicit ManifoldShape(const std::vector<ManifoldPart>& parts);
explicit ManifoldShape(std::vector<ManifoldPart>&& parts);
@@ -1066,9 +1066,9 @@ namespace {
return std::nullopt;
}
if (solid) {
return Part{ solid->GetMeshGL64(), solid };
return *solid;
}
return Part{ mesh, std::nullopt };
return mesh;
}
std::optional<Part> part_from_shell(const taxonomy::shell::ptr& shell, double precision, double dilation, manifold::Manifold::Error* status_ptr = nullptr) {
@@ -1544,7 +1544,7 @@ bool ManifoldKernel::convert_impl(const taxonomy::solid::ptr solid, IfcGeom::Con
results.emplace_back(IfcGeom::ConversionResult(
solid->instance.id(),
solid->matrix,
new ifcopenshell::geometry::ManifoldShape(Part{ result.GetMeshGL64(), result }),
new ifcopenshell::geometry::ManifoldShape(result),
solid->surface_style));
return true;
}
@@ -1622,7 +1622,7 @@ bool ManifoldKernel::convert_impl(const taxonomy::boolean_result::ptr br, IfcGeo
results.emplace_back(IfcGeom::ConversionResult(
br->instance.id(),
br->matrix,
new ifcopenshell::geometry::ManifoldShape(Part{ result->GetMeshGL64(), *result }),
new ifcopenshell::geometry::ManifoldShape(*result),
br->surface_style ? br->surface_style : style));
return true;
}
@@ -1671,7 +1671,7 @@ bool ManifoldKernel::convert_openings(const express::Base&, const std::vector<st
auto result = *operand - opening_union;
cut_shapes.emplace_back(IfcGeom::ConversionResult(
entity_shape.ItemId(),
new ifcopenshell::geometry::ManifoldShape(Part{ result.GetMeshGL64(), result }),
new ifcopenshell::geometry::ManifoldShape(result),
entity_shape.StylePtr()));
}
return !cut_shapes.empty();