Skip to content

perf: 90% speedup via CGAL integration#174

Closed
jf--- wants to merge 27 commits intocompas-dev:masterfrom
jf---:jf/extend_cgal
Closed

perf: 90% speedup via CGAL integration#174
jf--- wants to merge 27 commits intocompas-dev:masterfrom
jf---:jf/extend_cgal

Conversation

@jf---
Copy link
Copy Markdown
Collaborator

@jf--- jf--- commented Dec 9, 2025

Summary

  • switch geodesics default from exact_igl to heat_igl: 22s → 3.4s (85%)
  • add CGAL heat geodesics option: 3.4s → 2.1s (additional 38%)
  • total: 22s → 2.1s (90% speedup)

Changes

  • add heat_cgal geodesics method using compas_cgal.HeatGeodesicSolver
  • vectorize distance assignment operations
  • add CGAL polygon offset, remesh utilities

Test plan

  • 27 tests passing
  • curved slicing example runs correctly

jf--- added 27 commits December 9, 2025 16:07
Build System:
- Migrate from setup.py/setup.cfg to pyproject.toml
- Remove MANIFEST.in, pytest.ini (config now in pyproject.toml)
- Update Python requirement to >=3.9
- Replace flake8/autopep8/isort with ruff for linting/formatting
- Add mypy for optional type checking

Dependencies:
- compas>=2.0 (was <2.0)
- numpy>=1.24 (remove restrictive upper bound)
- networkx>=3.0
- progressbar2>=4.0
- pyclipper>=1.3
- libigl>=2.5

COMPAS 2.x Migration:
- Replace compas._os.absjoin() with pathlib.Path
- Update pairwise import: compas.utilities -> compas.itertools
- Replace mesh_weld(mesh) with mesh.weld() method
- Modernize compas_slicer_ghpython install.py for COMPAS 2.x

Python 3.9+ Modernization:
- Remove all __future__ imports (14 files)
- Remove explicit (object) inheritance from classes
- Use pathlib.Path throughout
- Use f-strings consistently

CI/CD:
- Test matrix: Python 3.9/3.10/3.11/3.12
- Test on ubuntu/windows/macos
- Use ruff for linting, mypy for type checking
- Update GitHub Actions to v4/v5

Tasks:
- Add invoke tasks: lint, format, typecheck
- Update release task to use python -m build
- geometry/path.py: full type annotations for Path class
- geometry/layer.py: type hints for Layer, VerticalLayer, VerticalLayersManager
- geometry/print_point.py: full type annotations for PrintPoint
- slicers/base_slicer.py: type hints for BaseSlicer base class

Uses Python 3.9+ style hints with `from __future__ import annotations`
for forward references and modern union syntax (X | Y).
- convert % formatting to f-strings
- fix SIM102/SIM103 (collapsible if)
- fix B007 (unused loop vars)
- fix B904 (raise from err)
- update mesh_bounding_box -> bounding_box(vertices)
- resolve circular imports via direct module imports
- mesh.edge_faces() now takes edge tuple instead of u/v kwargs
- fix Path import in layer.py (needed at runtime for isinstance)
- fix seams_align import in generate_brim.py
Major refactoring to use typed dataclasses instead of unstructured dicts.
All dataclasses inherit from compas.data.Data for COMPAS serialization.

New dataclasses:
- GcodeParameters: typed G-code params with 25+ fields and defaults
- PrintPath: wraps list[PrintPoint] with iteration/indexing
- PrintLayer: wraps list[PrintPath] with iteration/indexing
- PrintPointsCollection: replaces dict[str, dict[str, list[PrintPoint]]]

Converted to dataclasses:
- PrintPoint: @DataClass(Data) with __data__/__from_data__
- Path: @DataClass(Data) with legacy dict format compat
- Layer/VerticalLayer: @DataClass(Data) with inheritance

Key changes:
- Integer indices instead of string keys ('layer_0' -> [0])
- Access: collection[0][1][2] vs dict['layer_0']['path_1'][2]
- Type-safe with IDE autocomplete
- printpoints_dict property for backward compat
- Updated all print organizers and utilities
- new config.py: SlicerConfig, InterpolationConfig, GcodeConfig, PrintConfig dataclasses
- enums: GeodesicsMethod, UnionMethod for type-safe config
- full type hints: planar/interpolation/scalar_field/uv slicers
- full type hints: planar/interpolation/scalar_field print organizers
- fix direct imports in planar_slicer (create_planar_paths)
- fix mypy issues (optional types, null checks)
- type hints: get_param, defaults_layers, defaults_gcode, defaults_interpolation_slicing
- add min_layer_height, max_layer_height to layers defaults
- add filament_diameter key (underscore) alongside legacy space key
- deprecation note on GcodeParameters (prefer GcodeConfig)
- add _numpy_ops.py with vectorized helpers (KDTree, batch distances)
- add test_performance.py with benchmarks + regression tests
- vectorize gradient.py (vertex/face/edge gradient, divergence)
- vectorize topological_sorting.py (point cloud neighbor check)
- add KDTree to mesh_attributes_handling.py (restore_mesh_attributes)
- pre-factor sparse matrix in geodesics.py heat diffusion (250x speedup)
- vectorize data_smoothing.py iterative loop
- vectorize sort_paths_minimum_travel_time.py (seam adjustment)
- vectorize seams_align.py (distance calculations)
- add numba, pytest-benchmark to deps

Test fixtures use Sphere (Box ignores u,v params):
- small: ~180 faces
- medium: ~2k faces
- large: ~8k faces

Benchmark results:
- vertex gradient (8k faces): ~860μs
- divergence (2k faces): ~125μs
- batch closest points (1k pts): ~650μs
convert list back to Vector in set_ppt_up_vec
curved slicing: 22s -> 13.5s (38% speedup)
- generate_brim: CGAL offset_polygon w/ pyclipper fallback
- offset_polygon_with_holes for complex slices (CGAL-only)
- remesh_mesh via CGAL trimesh_remesh for mesh quality
- add get_cgal_HEAT_geodesic_distances using compas_cgal.HeatGeodesicSolver
- add HEAT_CGAL enum to GeodesicsMethod
- CGAL heat ~2.1s vs libigl ~3.1s in full workflow (30% faster)
@jf---
Copy link
Copy Markdown
Collaborator Author

jf--- commented Dec 11, 2025

superseded by #177

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant