{"id":42304702,"url":"https://github.com/polydera/trueform","last_synced_at":"2026-01-27T11:02:35.468Z","repository":{"id":334706855,"uuid":"1137652741","full_name":"polydera/trueform","owner":"polydera","description":"Real-time geometric processing. Easy to use, robust on real-world data.","archived":false,"fork":false,"pushed_at":"2026-01-26T20:50:06.000Z","size":74103,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-27T01:12:02.428Z","etag":null,"topics":["computational-geometry","cpp","geometry-processing","mesh-boolean","mesh-processing","python","spatial-indexing"],"latest_commit_sha":null,"homepage":"https://trueform.polydera.com/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/polydera.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-19T16:45:52.000Z","updated_at":"2026-01-26T20:48:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/polydera/trueform","commit_stats":null,"previous_names":["polydera/trueform"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/polydera/trueform","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polydera%2Ftrueform","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polydera%2Ftrueform/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polydera%2Ftrueform/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polydera%2Ftrueform/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/polydera","download_url":"https://codeload.github.com/polydera/trueform/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polydera%2Ftrueform/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28812367,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T07:41:26.337Z","status":"ssl_error","status_checked_at":"2026-01-27T07:41:08.776Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computational-geometry","cpp","geometry-processing","mesh-boolean","mesh-processing","python","spatial-indexing"],"created_at":"2026-01-27T11:02:33.960Z","updated_at":"2026-01-27T11:02:35.461Z","avatar_url":"https://github.com/polydera.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# trueform\n\n[![Tests](https://github.com/polydera/trueform/actions/workflows/tests.yml/badge.svg)](https://github.com/polydera/trueform/actions/workflows/tests.yml)\n[![Docs](https://github.com/polydera/trueform/actions/workflows/generate-docs.yml/badge.svg)](https://github.com/polydera/trueform/actions/workflows/generate-docs.yml)\n[![Build](https://github.com/polydera/trueform/actions/workflows/build-python.yml/badge.svg)](https://github.com/polydera/trueform/actions/workflows/build-python.yml)\n[![PyPI](https://img.shields.io/pypi/v/trueform)](https://pypi.org/project/trueform/)\n\nReal-time geometric processing. Easy to use, robust on real-world data.\n\nSpatial queries, mesh booleans, isocontours, topology — at interactive speed on million-polygon meshes. Robust to non-manifold flaps, inconsistent winding, and pipeline artifacts. Header-only C++17; works directly on your data with zero-copy views.\n\n**[▶ Try it live](https://trueform.polydera.com/live-examples/boolean)** — Interactive mesh booleans, collisions, isobands and more. No install needed. \n\n**[Documentation and Tutorials](https://trueform.polydera.com)** — Primitives, trees, topology, booleans — step by step.\n\n## Requirements\n\n- C++17 or later\n- [oneTBB](https://github.com/oneapi-src/oneTBB)\n\n## Installation\n\nInstall both the Python bindings and the C++ header-only CMake package via pip:\n\n```bash\npip install trueform\n```\n\nUse the header-only library as a CMake package:\n\n```cmake\nfind_package(trueform REQUIRED CONFIG)\ntarget_link_libraries(my_target PRIVATE tf::trueform)\n```\n\nConfigure your build so CMake can find the package installed by pip:\n\n```bash\ncmake -B build -Dtrueform_ROOT=$(python -m trueform.cmake)\ncmake --build build\n```\n\n### FetchContent\n\nUse FetchContent directly:\n\n```cmake\ninclude(FetchContent)\nFetchContent_Declare(trueform\n  GIT_REPOSITORY https://github.com/polydera/trueform.git\n  GIT_TAG main)\nFetchContent_MakeAvailable(trueform)\ntarget_link_libraries(my_target PRIVATE tf::trueform)\n```\n\n### Conan\n\nCreate the package from the recipe included in the repository:\n\n```bash\ngit clone https://github.com/polydera/trueform.git\nconan create trueform/conan/trueform --build=missing\n```\n\nThen add to your `conanfile.txt`:\n\n```ini\n[requires]\ntrueform/[\u003e=0.1.0]\n```\n\nInstall dependencies and build:\n\n```bash\nconan install . --build=missing\ncmake --preset conan-release\ncmake --build --preset conan-release\n```\n\n→ [Full installation guide](https://trueform.polydera.com/cpp/getting-started/installation)\n\n## Integrations\n\n- **[VTK](https://trueform.polydera.com/cpp/vtk)** — Filters and functions that integrate with VTK pipelines\n- **[Python](https://trueform.polydera.com/py/getting-started)** — NumPy in, NumPy out\n- **[Blender](https://trueform.polydera.com/py/blender)** — Cached meshes with automatic updates for live preview\n\n## Quick Tour\n\n```cpp\n#include \u003ctrueform/trueform.hpp\u003e\n\n// Start with your raw data—no copies, no conversions\nstd::vector\u003cfloat\u003e raw_points = {0, 0, 0, 1, 0, 0, 0, 1, 0};\nstd::vector\u003cint\u003e indices = {0, 1, 2};\n\nauto points = tf::make_points\u003c3\u003e(raw_points);\nauto faces = tf::make_faces\u003c3\u003e(indices);\nauto triangles = tf::make_polygons(faces, points);\n// or maybe faces are variable\nstd::vector\u003cint\u003e offsets = {0, 3};\nauto d_faces = tf::make_faces(offsets, indices);\nauto d_polygons = tf::make_polygons(d_faces, points);\n\nauto polygons_buffer = tf::read_stl(\"file.stl\");\nauto polygons = polygons_buffer.polygons();\n```\n\n**Primitive queries** work directly on geometry:\n\n```cpp\nauto polygon = polygons.front();\nauto segment = tf::make_segment_between_points(points[0], points[1]);\nauto ray = tf::make_ray_between_points(\n    tf::make_point(0.2f, 0.2f, -1.0f),\n    tf::make_point(0.2f, 0.2f, 1.0f));\n\nauto [dist2, pt_on_poly, pt_on_seg] = tf::closest_metric_point_pair(polygon, segment);\nbool contains = tf::contains_point(polygon, points[0]);\nif (auto hit = tf::ray_hit(ray, polygon)) {\n    auto [status, t, hit_point] = hit;\n}\n```\n\n**Mesh analysis** reveals structure and defects:\n\n```cpp\nauto polygons = polygons_buffer.polygons();\n// Connected components\nauto [n_components, labels] = tf::make_manifold_edge_connected_component_labels(polygons);\nauto [components, component_ids] = tf::split_into_components(polygons, labels);\n\n// Vertex neighborhoods\nauto v_link = tf::make_vertex_link(polygons);\nauto k2_ring = tf::make_k_rings(v_link, 2);\nauto neighs = tf::make_neighborhoods(polygons.points() | tf::tag(v_link), 0.5f);\n\n// Principal curvatures and directions\nauto [k0, k1, d0, d1] = tf::make_principal_directions(polygons);\n\n// Boundary curves (open edges)\nauto boundary_paths = tf::make_boundary_paths(polygons);\nauto boundary_curves = tf::make_curves(boundary_paths, polygons.points());\n\n// Non-manifold edges (shared by \u003e2 faces)\nauto bad_edges = tf::make_non_manifold_edges(polygons);\nauto bad_segments = tf::make_segments(bad_edges, polygons.points());\n\n// Fix inconsistent face winding\ntf::orient_faces_consistently(polygons);\n```\n\n**Spatial acceleration** enables queries on transformed geometry:\n\n```cpp\ntf::aabb_tree\u003cint, float, 3\u003e tree(polygons, tf::config_tree(4, 4));\n\nauto dynamic_form = polygons | tf::tag(tree)\n    | tf::tag(tf::random_transformation\u003cfloat, 3\u003e());\nauto static_form = polygons | tf::tag(tree);\n\n// Collision detection\nbool does_intersect = tf::intersects(static_form, dynamic_form);\nfloat distance2 = tf::distance2(static_form, dynamic_form);\n\n// Collect all intersecting primitive pairs\nstd::vector\u003cstd::pair\u003cint, int\u003e\u003e collisions;\ntf::gather_ids(static_form, dynamic_form, tf::intersects_f,\n               std::back_inserter(collisions));\n\n// Compute intersection curves\nauto curves = tf::make_intersection_curves(static_form, dynamic_form);\n```\n\n**Boolean operations** combine meshes:\n\n```cpp\nauto [result_mesh, labels] = tf::make_boolean(\n    polygons0,\n    polygons1 | tf::tag(tf::make_rotation(tf::deg(45.f), tf::axis\u003c2\u003e)),\n    tf::boolean_op::merge);\n\n// With intersection curves\nauto [result, labels, curves] = tf::make_boolean(\n    polygons0, polygons1, tf::boolean_op::intersection, tf::return_curves);\n```\n\n**Scalar fields and isocontours**:\n\n```cpp\n// Compute distance field from a plane\nauto plane = tf::make_plane(polygons.front());\ntf::buffer\u003cfloat\u003e scalars;\nscalars.allocate(polygons.points().size());\ntf::parallel_transform(polygons.points(), scalars, tf::distance_f(plane));\n\n// Extract isocontours embedded into the mesh\nstd::vector\u003cfloat\u003e cut_values = {-0.5f, 0.0f, 0.5f};\nauto [contour_mesh, contour_labels, isocontours] = tf::embedded_isocurves(\n    polygons, scalars, tf::make_range(cut_values), tf::return_curves);\n```\n\n**Mesh cleanup** prepares geometry for processing:\n\n```cpp\n// Merge coincident vertices, remove degenerates and duplicates\nauto clean_mesh = tf::cleaned(polygons, tf::epsilon\u003cfloat\u003e);\n\n// Triangulate n-gons\nauto tri_mesh = tf::triangulated(polygons);\n\n// Ensure outward-facing normals on closed meshes\ntf::ensure_positive_orientation(polygons);\n```\n\n→ [Geometry Walkthrough](https://trueform.polydera.com/cpp/examples/mesh-assembly) — A hands-on tour from raw geometry through booleans and connected components.\n\n→ [Modules](https://trueform.polydera.com/cpp/modules) — Primitives, ranges, policies, and the patterns that connect them.\n\n## Benchmarks\n\nSample comparisons against VTK, CGAL, libigl, Coal, FCL, and nanoflann:\n\n| Operation | Input | Time | Speedup | Baseline | TrueForm |\n|-----------|-------|------|---------|----------|----------|\n| Boolean Union | 2 × 1M | 28 ms | **84×** | CGAL `Simple_cartesian\u003cdouble\u003e` | reduction diagrams, double |\n| Mesh–Mesh Curves | 2 × 1M | 7 ms | **233×** | CGAL `Simple_cartesian\u003cdouble\u003e` | reduction diagrams, double |\n| Self-Intersection | 1M | 78 ms | **37×** | libigl EPECK (GMP/MPFR) | reduction diagrams, double |\n| Isocontours | 1M, 16 cuts | 3.8 ms | **38×** | VTK `vtkContourFilter` | reduction diagrams, float |\n| Connected Components | 1M | 15 ms | **10×** | CGAL | parallel union-find |\n| Boundary Paths | 1M | 12 ms | **11×** | CGAL | Hierholzer's algorithm |\n| k-NN Query | 500K | 1.7 µs | **3×** | nanoflann k-d tree | AABB tree |\n| Mesh–Mesh Distance | 2 × 1M | 0.2 ms | **2×** | Coal (FCL) `OBBRSS` | OBBRSS tree |\n| Principal Curvatures | 1M | 25 ms | **55×** | libigl | parallel k-ring quadric fitting |\n\nApple M4 Max, 16 threads, Clang `-O3 -march=native`. Full methodology, interactive charts, source code, and datasets in [benchmarks documentation](https://trueform.polydera.com/cpp/benchmarks).\n\n## Documentation\n\n- [Getting Started](https://trueform.polydera.com/cpp/getting-started) — Installation and first steps\n- [Modules](https://trueform.polydera.com/cpp/modules) — Primitives, trees, topology, booleans\n- [Benchmarks](https://trueform.polydera.com/cpp/benchmarks) — Performance comparisons\n- [Examples](https://trueform.polydera.com/cpp/examples) — Workflows and library comparisons\n- [Python Bindings](https://trueform.polydera.com/py/getting-started) — Full API for Python\n- [Research](https://trueform.polydera.com/cpp/about/research) — Theory, publications, and citation\n\n## License\n\nDual-licensed:\n- **Noncommercial**: [PolyForm Noncommercial License 1.0.0](./LICENSE.noncommercial)\n- **Commercial**: Contact [info@polydera.com](mailto:info@polydera.com)\n\n## Contributing\n\nBrowse [open issues](https://github.com/polydera/trueform/issues) labeled by difficulty. See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.\n\n## Citation\n\nIf you use trueform in your work, please cite:\n\n```bibtex\n@software{trueform2025,\n    title={trueform: Real-time Geometric Processing},\n    author={Sajovic, {\\v{Z}}iga and {et al.}},\n    organization={XLAB d.o.o.},\n    year={2025},\n    url={https://github.com/polydera/trueform}\n}\n```\n\n---\n\n**Developed by [XLAB Medical](https://xlab.si)**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolydera%2Ftrueform","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolydera%2Ftrueform","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolydera%2Ftrueform/lists"}