The goal of this tutorial is to fix a deliberately broken mesh using Solidean’s healing pipeline. We will:
- Create a
ContextandExactArithmetic - Import a mesh that is not supersolid (holes/overlaps)
- Run
healto make it supersolid - Run
selfUnionto remove inner structure and ensure solidity - Export indexed triangles (shared vertices, connected output)
- Compute area/volume to verify the result
Along the way, you’ll use: Context, ExactArithmetic, Operation::heal, Operation::selfUnion, Operation::exportToIndexedTrianglesF32, and MeshType::NonSupersolid.
Note:
All C++ tutorials/examples use
ExampleFramework.hh for tiny POD types (pos3, triangle, tri_idx) and helpers.
1) Project setup (CMake)
Add the C++17 binding and link it:
add_subdirectory(path/to/solidean/lang/cpp17)
target_link_libraries(YourProject PRIVATE Solidean::Cpp17)
Ensure the Solidean dynamic library is discoverable at runtime (same folder as your binary or on your system path).
2) Minimal program
We concatenate two overlapping cubes, delete one triangle to create a hole, then repair the mesh and export an indexed result.
#include <cstring>
#include <iostream>
#include <vector>
#include <solidean.hh>
#include "ExampleFramework.hh"
int main()
{
std::unique_ptr<solidean::Context> ctx = solidean::Context::create();
std::unique_ptr<solidean::ExactArithmetic> arithmetic = ctx->createExactArithmetic(10.f);
// create two overlapping cubes
auto const cubeA = example::createCube();
auto const cubeB = example::createCube({0.5f, 0.5f, 0.5f});
// create a concatenation of all triangles
// NOTE: this is a single mesh that contains intersecting triangles now
auto cubeConcat = cubeA;
for (auto const& t : cubeB) cubeConcat.push_back(t);
// remove one triangle to create a hole
cubeConcat.pop_back();
std::cout << "Initial mesh has " << cubeConcat.size() << " triangles (unrolled).\n";
std::unique_ptr<solidean::TypedBlob> blob =
ctx->execute(*arithmetic, [&](solidean::Operation& op)
{
// reinterpret example triangle type as Solidean triangle
auto const triSpan = solidean::as_triangle3_span(cubeConcat);
// 1) Heal: map arbitrary input → supersolid mesh
auto healed = op.heal(op.importFromTrianglesF32(triSpan, solidean::MeshType::NonSupersolid));
// 2) Self-union: remove inner structures; ensure a clean solid
auto solid = op.selfUnion(healed);
// 3) Export indexed triangles (shared vertices, connected result)
return op.exportToIndexedTrianglesF32(solid);
});
auto const vertexSpan = blob->getPositionsF32<example::pos3>();
auto const indexSpan = blob->getTrianglesIndexed<example::tri_idx>();
auto const vertices = std::vector<example::pos3>(vertexSpan.begin(), vertexSpan.end());
auto const indices = std::vector<example::tri_idx>(indexSpan.begin(), indexSpan.end());
auto const [areaResult, volumeResult] = example::computeAreaAndVolume(vertices, indices);
std::cout << "Result mesh: " << indices.size() << " triangles, "
<< vertices.size() << " shared vertices.\n";
std::cout << "Area: " << areaResult << " Volume: " << volumeResult << "\n";
return EXIT_SUCCESS;
}
3) What you learned
- Declare guarantees honestly: broken inputs must be marked as
MeshType::NonSupersolid(or via builder flags). - Healing works on any input mesh:
Operation::healupgrades arbitrary geometry to a supersolid. - Make it strictly solid:
Operation::selfUnionremoves inner structure, yielding a solid mesh. - Export connected results:
exportToIndexedTrianglesF32deduplicates vertices and resolves T-junctions. - Exactness is preserved: floats are storage; Solidean converts to an exact internal representation on import.
4) Variations to try
- Swap the export for
ExportFormat::HalfedgeExplicitusing
Operation::exportMeshand addHalfedgeTo*options. - Add
ExportOption::Manifoldto enforce manifoldness even on complex inputs. - Skip
selfUnionto see the difference between supersolid and solid output. - Import the two cubes as separate surfaces and experiment with
MeshBuilder::AllowSurfaceIntersections.
Next steps
- Browse the API Reference (search functions, classes, and types).
- Scan All Symbols (A–Z) for quick symbol lookup.
- See FAQ for developer-focused questions.
- Check Troubleshooting for common issues and fixes.
- Track changes in the Changelog.