Conversation
Import OpenSCAD's evaluated CSG tree format (.csg) into BRL-CAD .g files. The .csg format is produced by: openscad -o file.csg input.scad Supports cube, sphere, cylinder primitives, boolean operations (difference, union, intersection, group), multmatrix transforms, and color nodes. Warns and skips unsupported nodes (linear_extrude, rotate_extrude, hull, minkowski).
Parse OpenSCAD polyhedron() nodes, attempting to match ARB primitives before falling back to BOT (bag of triangles). Detection order: arb8 (8 verts, 6 quad faces), arb5 (5 verts, quad base + apex), arb4 (4 verts, 4 tri faces). Non-matching polyhedra are fan-triangulated into BOT solids.
Non-convex polyhedra go straight to BOT since ARB primitives require convexity for correct ray tracing. The check verifies that for each face, all other vertices lie on the same side of the face plane. Tetrahedra (arb4) skip the check since they are always convex.
Parse color([r, g, b, a]) and store as BRL-CAD attributes: color = R/G/B (0-255 range) alpha = 0.NNN (only if < 1.0)
Walks the CSG tree preserving boolean structure (union, difference, intersection), transformation matrices, and primitive geometry. Direct mappings: SPH/ELL to sphere(), TGC/REC to cylinder(), ARB to polyhedron(), BOT to polyhedron(), TOR to rotate_extrude(circle()). Unsupported primitives are tessellated via ft_tessellate/nmg_bot. Combination colors are emitted as color() wrappers.
rotate_extrude(circle()) maps to mk_tor (torus). This recovers all 1145 previously-skipped solids across the test suite. linear_extrude(square()) maps to mk_rpp (box). linear_extrude(circle()) maps to mk_tgc (cylinder/cone). Unsupported extrude children (polygon, etc.) warn and skip.
csg-g: linear_extrude(polygon()) creates a BRL-CAD sketch from the polygon vertices/paths, then extrudes it with mk_extrusion. Also handles rotate_extrude(circle()) as torus and linear_extrude with circle/square children as cylinder/box. g-scad: ID_EXTRUDE primitives are exported as linear_extrude(polygon()) by reading the referenced sketch's vertices and line segments. ID_SKETCH primitives encountered standalone are silently skipped.
ft_tessellate can corrupt the rt_db_internal structure, causing heap corruption when rt_db_free_internal runs later. Fix by re-reading the primitive from the database for a fresh copy before tessellating. Note: EHY tessellation (rt_ehy_tess) has a pre-existing heap corruption bug in BRL-CAD itself — not addressed here.
csg-g: import(file="foo.stl") now reads the referenced STL file relative to the .csg file's directory and inlines it as a BOT. Also adds render() as a pass-through wrapper. g-scad: ID_HALF (halfspace) is exported as a 2e10mm cube positioned on the correct side of the plane via multmatrix. Not mathematically exact but sufficient for any practical CSG subtraction.
ID_PARTICLE: exported as hull() of two spheres at endpoints. ID_PIPE: exported as union of cylinders for straight segments with spheres at joints for smooth connections. ID_REVOLVE: exported as rotate_extrude(polygon()) by reading the referenced sketch's vertices and line segments.
ARB6 (triangular prism): 6 vertices, 5 faces (2 triangles + 3 quads). Identifies opposing triangle faces and pairs vertices via shared side quads. ARB7 (arb8 with one collapsed corner): 7 vertices, 6 faces (2 triangles + 4 quads). Finds the bottom quad, identifies top vertices, and pairs via face adjacency. Previously these fell through to BOT.
Member
|
@erikg Is this ready to merge yet, or are you still working on it? |
Contributor
Author
ready, just wanted review/confirmation since this is a new capability |
Member
|
@erikg we're about to release, so we'll review it and plan to merge next week |
Member
|
Pretty sweet. Just fyi arbs can be planar concave now (it turned them into bots). We're also moving them all into gcv but that can happen later. Would be good to get the ones that failed attached as an issue with detail on what it needs like Minkowski or whatever. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bidirectional OpenSCAD converters that preserve CSG structure:
.csgformat into BRL-CAD.gfiles.gobjects to.scadfilesBoth converters map primitives and boolean operations directly to their equivalents rather than tessellating to mesh, producing clean analytic geometry wherever possible.
csg-g (OpenSCAD → BRL-CAD)
cube()sphere()cylinder()polyhedron()rotate_extrude(circle())linear_extrude(square())linear_extrude(circle())linear_extrude(polygon())import("file.stl")difference/union/intersection/groupmultmatrix()color()render()Polyhedron import detects all ARB types (4–8) with a convexity check — non-convex polyhedra fall back to BOT. Tetrahedra skip the convexity check since they're always convex.
g-scad (BRL-CAD → OpenSCAD)
sphere()+multmatrix()cylinder()+multmatrix()polyhedron()(degenerate faces stripped)polyhedron()rotate_extrude() circle()hull() { sphere(); sphere(); }union()of cylinders + joint spheresrotate_extrude(angle) polygon()linear_extrude() polygon()multmatrix() cube(2e10)difference/union/intersectioncolor()ft_tessellate→polyhedron()Tessellation uses a fresh
rt_db_get_internalcopy to avoid heap corruption fromft_tessellatemodifying the caller's internal.Usage
Testing
Round-trip tested across 59 BRL-CAD sample models (.g → .scad → .csg → .g):
.scadfiles verified to render in OpenSCADregress-repositorypasses (API wrapper compliance)ninja testsuite passes (1093/1095, 2 pre-existing non-issues)Solid count mismatches in round-trip are structural, not data loss:
hull()node (from PARTICLE) is not parsed back by csg-gKnown Limitations
hull()andminkowski()nodes in .csg are skipped (no CSG equivalent without shelling out to OpenSCAD)linear_extrudewithtwistparameter has no BRL-CAD equivalentimport()not yet handled (ASCII only)