Skip to content

New export module and blade/propeller/shaft readaptation + tests - #124

Open
Dassoo wants to merge 1 commit into
mathLab:masterfrom
Dassoo:exports-fix
Open

Dassoo wants to merge 1 commit into
mathLab:masterfrom
Dassoo:exports-fix

Conversation

@Dassoo

@Dassoo Dassoo commented Nov 10, 2026

Copy link
Copy Markdown

Summary

Exports were assembled independently in Blade, Propeller and Shaft, each with its own sewing tolerance and its own forced cast to TopoDS_Shell. When the four blade faces do not sew into a single shell (geometry-dependent, e.g. a tip collapsing to a point), that cast raises Standard_TypeMismatch and the whole export fails. This is a failure triggering an HTTP 500 on IGES exports.

This PR moves the B-Rep assembly and the file writing into one module and makes the export path never depend on a boolean fuse or on a closed shell.

 bladex/
+├── export.py       # compounds, sewing, solid assembly, meshing, writers
 ├── blade.py        # Blade.shell() -> export_stl / export_iges
 ├── propeller.py    # blades_shape() / compound() -> export_stl / export_iges
 └── shaft/
     └── shaft.py    # generates its solid through the same helpers

Geometry and I/O are now separate:

Blade.shell()              -> shape        write_stl(shape, path, ...)
Blade.generate_solid()     -> solid|shape  write_iges(shape, path)
Propeller.blades_shape()   -> compound     mesh(shape, ...)
Propeller.compound()       -> compound
Propeller.solid            -> fused solid  (explicit, not used by exports)

Changes

New: bladex/export.py

Function Purpose
make_compound single implementation, previously a local helper in propeller.py
sew_shapes sewing with explicit tolerance, clear error when a face is None
to_solid MakeSolid only when there is exactly one shell, recursively through nested compounds; returns the sewn shape otherwise
mesh one tessellation path with linear, angular and is_relative
write_stl binary output only, checks the writer return value
write_iges checks the writer return value

bladex/blade.py

  • Blade.shell(sewing_tolerance=1e-2): the sewn four faces, used by STL, IGES and generate_solid.
  • generate_solid(): tolerance 1e-7 -> 1e-2, no blind cast, falls back to the sewn shape.
  • export_stl(): adds angular_deflection (0.3).
  • export_iges(): exports the sewn shell with a tunable tolerance; leading-edge curves unchanged.

bladex/propeller.py

  • blades_shape() and compound() are public: assembly is geometry, not an export detail.
  • shape is now the compound; solid is the explicit boolean union, uncached.
  • export_iges() / export_stl() write sewn blades plus the shaft, with include_shaft and exposed deflections; no fuse on the default path. STL is always binary.
  • tmp_stl() is a deprecated alias of export_stl(include_shaft=False) and emits DeprecationWarning.
  • display() shows the compound.
  • generate_obj() and generate_obj_blades() are repaired: they referenced self.shaft_solid / self.blades_solid (removed in 4f2ffe4) and used fixed /tmp/temp_*.stl paths. They now use tempfile.TemporaryDirectory.
  • smithers is imported inside the two OBJ methods, so import bladex no longer requires it.

bladex/shaft/shaft.py

  • generate_solid() uses the same helpers, removing the same blind shell cast.

Packaging

  • New optional extra: obj = ["smithers[vtk]"].

Tests

  • 11 new tests in tests/test_propeller.py: to_solid nested-compound conversion, non-shell shapes left unchanged, binary STL with and without shaft (triangle counts), single-body blade shell, readable propeller IGES, blade IGES with and without leading-edge curves, export surviving unsewable faces, tmp_stl equivalence plus deprecation warning, reflect_blade contract, OBJ regions for propeller and blades.

@Dassoo

Dassoo commented Nov 10, 2026 •

Copy link
Copy Markdown
Author

@ndem0 : tested on marinAI, works fine

@DavideOberto you may want to see and test everything on your end before merging, I thought it would have been better to centralize export functions without rewriting the same code. Should be fine against a few errors that were previously being triggered also on the app I'm working on, which is using BladeX

This branch has not been deployed

No deployments
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