Releases: Fluid-CAD/FluidCAD
Release list
v0.0.39
Release Notes — v0.0.39
Covers changes from v0.0.38 to v0.0.39.
The headline feature is guided lofting: rails and end conditions for loft(), built on an in-house B-spline skinning pipeline. Also includes a sweep extension helper and several fixes to fillet, repeat, shell, rib, and intersect.
Features
Loft guide curves and end conditions
loft() now accepts .guides() to pull the loft through one or more rail curves, and .startCondition()/.endCondition() to control tangency at the first and last profile. Thin lofts assemble conditioned walls and ring caps directly instead of going through a boolean, and wall faces split at curvature jumps so rounded offset corners keep their edges.
See the loft guide.
Sweep extend
sweep() gained .extend() to continue a swept profile past the ends of its path along the path's tangent.
Bug Fixes
fillet: the radius-first spread formfillet(r, ...curves)now dispatches correctly inside sketches.repeat: cloning a sweep whose path comes from another sketch freezes the borrowed 2D curves instead of orphaning them.rib: parallel ribs flip direction under a mirror repeat so the mirrored clone lands on the correct side.shell: a failed wall offset now surfaces an error instead of silently returning the original solid.intersect: only consumes source geometries that are actual scene selections.
v0.0.38
Release Notes — v0.0.38
Covers changes from v0.0.37 to v0.0.38.
A small release: a new way to derive a plane from an edge, plus a handful of fixes.
Features
Plane from an edge
You can now create a plane from an edge at a normalized 0–1 position along it, oriented normal to the edge (the start point faces outward). Handy for placing a sketch perpendicular to a curve or at a precise fraction along it.
See the sketching guide.
Bug Fixes
sweep: the fixed binormal is derived from the spine's rotation axis, so helix sweeps no longer twist.offset: the sketch plane is passed as a reference face, so offsetting a single line works.recompute: drops the compare baseline so a recompute fully rebuilds and reports build timings.- Sketcher: screen‑space markers are sized at creation, so the tangent indicator isn't oversized after a timeline rollback.
v0.0.37
Release Notes — v0.0.37
Covers changes from v0.0.36 to v0.0.37.
A big release: three new modeling features — helixes, 3D text, and wrap — plus an measure tool, all on top of a new OpenCASCADE 8.0 geometry kernel. FluidCAD is now MIT licensed.
Features
Helix
helix() creates a helical wire — the curve behind springs, threads, and coils. Size it with any two of .pitch(), .turns(), and .height(), taper it, derive its axis from existing geometry, and pair it with sweep() to turn it into a solid. It's now built on OpenCASCADE's TKHelix for clean, stable curves.
See the helix guide.
3D text
text() turns a string into extrudable outline geometry — each glyph a closed profile, counters preserved. Use it inside a sketch() or standalone on a plane, pick a system font or a workspace .ttf/.otf with .weight() and .italic(), and lay text along any planar path with text(string, path) and alignment options.
See the text guide and the text() reference.
Wrap
wrap(thickness, sketch, face) develops a flat sketch onto a cylindrical or conical face — labels, embossed logos, engraved text — preserving every length and angle instead of squashing them like a projection. Chain .remove() to engrave rather than emboss; holes and fusion scope work as they do elsewhere.
See the wrap guide.
Measure tool
A new measure tool in the viewer, multi‑select faces and edges to read distances, lengths, areas, angles, and more. Results appear in the status bar with an expandable panel, unit selection, and a viewport overlay. Also exposed over the HTTP API and as an MCP tool for agents.
Geometry engine: OpenCASCADE 8.0
The geometry kernel moved to OpenCASCADE 8.0 (opencascade.js v3).
Other improvements
- Sketcher: rectangle and rounded‑rectangle dimension inputs are anchored at the edge midpoint.
- Features and shapes without a custom icon now fall back to a default icon.
Licensing
FluidCAD is now released under the MIT license.
Bug Fixes
extrudehonorsendOffsetwhen extruding to a conical target face.- Import/export no longer closes an un‑opened document, and import errors surface decoded WASM messages.
Docs
- New guides, API references, and examples for helix, 3D text, and wrap.
v0.0.36
Release Notes — v0.0.36
Covers changes from v0.0.34 to v0.0.36.
Features
Interactive sketcher
The headline of this release: an interactive sketching toolbar in the viewer. It's a helper for writing sketches faster, not a replacement for the code‑first workflow — it covers the common drawing tools and writes clean, editable code back into your .fluid.js file, but it doesn't expose the full sketch API. Reach for it to rough things out or place geometry by eye, then keep refining in code.
Everything the toolbar produces is plain FluidCAD code, so anything it doesn't cover you can still add or adjust by hand. Geometry that isn't part of the active toolbar set is rendered in a distinct, non‑interactive color so it's always clear what the tools will touch. The toolbar is vertical and grouped, with icons switched to Iconoir.
Parameters
A new param() API turns model inputs into live controls in a dedicated Params panel — change a value and the model re‑renders in place.
import { param } from "fluidcad/core";
const width = param("Width", 40, "number", { min: 10, max: 100, group: "Box" });
const round = param("Rounded corners", true, "checkbox");In local development this is of limited use — you're editing the code anyway, so changing a value in the panel is rarely faster than changing it in the source. Where it pays off is publishing models online (coming soon): parameters become the knobs viewers can turn to customize a published model without touching any code.
Other improvements
copynow transfers ownership of the original shapes to the copy feature.back()skips non‑geometry children when resolving the previous tangent.
Bug Fixes
- Windows: ESM/fork paths now resolve correctly on non‑
C:drives (#52). repeat: a structuralcompareToavoids a crash on unbuilt axis/plane sources during cache comparison.
Docs
- Documented local‑only installation alongside the Windows drive fix.
v0.0.34
Release Notes — v0.0.34
Covers changes from v0.0.33 to v0.0.34.
Features
MCP server
New FluidCAD MCP server lets LLM coding agents drive a running workspace end‑to‑end. Highlights:
- Discovery & docs —
list_workspaces,list_docs,search_docs,read_doc,get_api_signature,get_type_definition, plus a self‑containedllm-docs/corpus with a coverage gate that fails CI when a documented symbol drifts. - Source editing — synchronous
write_fileandedit_range(each call returns once the render settles), with a dirty‑buffer guard and amissing-importsrefusal for.fluid.jsfiles that use FluidCAD symbols without importing them. - Scene inspection —
get_scene_summary,list_shapes,get_shape_properties,get_face_properties,get_edge_properties,hit_test. - Screenshots & cameras —
screenshot,screenshot_multi,screenshot_shape,get_camera_state, stateless camera views. - Engine control —
recompute,rollback_to,import_step,export,add_breakpoint,clear_breakpoints,wait_for_idle. - Skill bundle — installable skill teaches an agent FluidCAD conventions, common pitfalls (e.g. extrude/cut sign convention), and the right tool‑use order.
See the MCP server docs for setup with Claude Code, opencode, and other MCP clients.
fluidcad CLI: init and serve subcommands
The CLI is now built on commander and exposes:
fluidcad init— scaffold a new workspace.fluidcad serve— run the server (with--opento launch the UI).
Tangent arc improvements
tArc(radius, target)— new overload that ends at the first intersection withtarget.tArc(targetLine)— new overload with.flip()to curve the other way.createCopyimplemented on all tangent arc feature classes so they participate inrepeat().
Arc improvements
.major()— explicit selector for arcs greater than 180°.IArcPointssplit intoIArcRadiusandIArcCenterfor clearer typing.- Two‑point arc center defaults to the chord midpoint instead of the current position.
Repeat features
- Shapes are now removed from axis/plane sources consumed by repeat features.
- Repeat‑feature matrix resolution is deferred to build time via
LazyMatrix.
Shell .join()
shell() gains a chained .join() for selecting the inner‑corner blend style — arc, intersection, or tangent.
Back command tangent restore
back() now restores the tangent in addition to the position.
Init options with mesh deflection
New init options expose mesh deflection configuration for tuning render quality vs. performance.
Docs
- Regenerated API reference.
- Expanded primitive shape guide with detailed examples and screenshots.
- Expanded constrained geometry guide with examples and screenshots.
- Two new tutorials.
Commits
50fb7c2chore: release v0.0.34b978a4afix(mcp): read SERVER_VERSION from root package.jsonaf20e78docs(skill): add common pitfalls section with extrude/cut sign convention1786235docs(mcp): simplify skill install sectiona119283refactor(mcp): read SERVER_VERSION from package.json59715ccfeat(mcp): rename server to FluidCAD and document skill installe1110b8feat(mcp): add skill710ea4eupdate llm docs509e934docs(mcp): note opencode mcp add is interactive2d961e8feat(mcp): add get_type_definition tool and generated type docsd6a8abadocs(cut): note direction convention in summary64beb8brefactor(mcp): drop wait_for_render now that mutations are synchronous3400095feat(mcp): refuse .fluid.js writes that use FluidCAD symbols without importse5f98fcdocs(sketch): note first face is used when selection has multiple5a48bedtest(mcp): assert docs-tag behavior instead of seed-set membership334eadefeat(mcp): make write_file/edit_range synchronous via POST /api/render5d227c9docs(mcp): document opencode mcp installationdd9d358docs(mcp): add 'Imported from' note and import statements to every API doc example82f23eddocs(mcp): document cut direction convention vs sketch normal98e545edocs(mcp): spell out required count + offset/length/angle options on repeat/copyccc853ddocs(mcp): migrate references & IO to llm-docs/ (phase 11 slice 6)3bbdd54docs(mcp): migrate transforms & patterns to llm-docs/ (phase 11 slice 5)0c76319docs(mcp): migrate selections & filters to llm-docs/ (phase 11 slice 4)ed9d4cddocs(mcp): migrate 3D features to llm-docs/ (phase 11 slice 3)2e77aa8docs(mcp): migrate constrained geometry to llm-docs/ (phase 11 slice 2)9a198f4fix(extensions): stop per-keystroke dirty-state sends starving live render956ca49docs(mcp): use --scope user for claude mcp add snippetbcc83c7add mcp readme.mdedf806edocs(mcp): migrate 2D primitives to llm-docs/ (phase 11 slice 1)15887f4feat(mcp): add llm-docs coverage gate + example execution (phase 10)8cad644feat(mcp): add engine-control tools (phase 9)2828c98feat(mcp): add source-editing tools with dirty-buffer guard (phase 8)a0e366cfeat(mcp): add wait_for_render/wait_for_idle coordination tools (phase 7)e4bb9cbfeat(mcp): add screenshot tools and stateless camera views (phase 6)78637b2feat(mcp): add inspection tools and scene endpoints (phase 5)6f167b3feat(mcp): add documentation tools and resources (phase 4)bd57070docs: clarify that "x"/"y"/"z" are world axes even inside a sketch40675cefeat(mcp): seed llm-docs/ and add manifest generator (phase 3)8077b0bfeat(mcp): add discovery and stdio MCP server skeleton (phases 1-2)1bfaaa5docs(cli): showfluidcad servewithout -w and document --open91efbc7add missing files40077cdfeat(cli): switch to commander with init and serve subcommandsdbae652docs(llm): add design-intent guidance and math footgune0103b9add llm.mdb5870deupdate docs8f42d4edocs(api): regenerate API referencea26c64cdocs: expand constrained geometry guide with examples and screenshots3b1e114docs: expand primitive shape guide with detailed examples and screenshotsa7c8d50feat(back): restore tangent in addition to position1379c91fix(arc): default two-point arc center to chord midpoint instead of current position0e29c78fix(tarc): route single LazyVertex arg to endpoint overload11f5609feat(tarc): implement createCopy on all tangent arc feature classes865a907feat(arc): add .major() for arcs >180°, split IArcPoints into IArcRadius/IArcCenter00b3c99feat: add init options with mesh deflection configuration014f926feat(tarc): add tArc(radius, target) overload ending at first intersection37f3aa6feat(tarc): add tArc(targetLine) overload with .flip() to curve the other way0e7b98afeat: remove shapes from axis/plane sources consumed by repeat featuresb98a3c9refactor: defer repeat-feature matrix resolution to build time via LazyMatrixd762757feat: add chained .join() to shell for selecting arc/intersection/tangent inner-corner blend35a58c7docs: add new tutorial8c76e34docs: add new tutorial
v0.0.33
Release Notes — v0.0.33
Covers changes from v0.0.32 to v0.0.33.
Features
rib() for thin wall extrusions
New rib() feature creates thin wall extrusions from sketch spines. Supports parallel direction, draft, and extend() to blend rib side faces with target solids — useful for stiffening ribs against drafted or curved cavity faces.
Positional filters on face/edge selectors
face() and edge() filters now accept positional selectors first(), last(), and at(index) for direct index-based picking.
Chainable options on load()
load() now supports noColors(), include(), and exclude() chainable options for finer control over imported geometry.
UI
- Shapes panel now displays the scene object name or type instead of the shape type.
- Timeline no longer auto-capitalizes custom names.
- Scene object ids are preserved across renders.
- Sketch mode section caps are disabled for cleaner sketch views.
Performance
- Faster meshing.
- Faster face/edge lookups.
Bug Fixes
- Color bleeding between shapes in some cases.
Docs
- New rib documentation.
- Drafted box tutorial updated to use the new rib feature.
Commits
4d6f31echore: release v0.0.339eb7a80restore meshing params updated by mistakeafdbea6docs: update drafted box tutorial to use the new rib featureb878d05refactor: replace parallel-mode rib draft with tapered loft for exact start-face thickness preservation2387120fix: scale rib draft neutral-plane shift to thickness so thin ribs preserve start-face thickness87451c6docs: add rib documentation98b304ffix: reverse rib thickness sign convention so positive thickness extrudes opposite to sketch normale233078fix: exclude rib cap faces (perpendicular to spine) from draft so only wall faces tapere3444dffix: compute scope-coincidence via direct perpendicular distance instead of buggy gp_Pln.Distance4dc08bafix: select rib solids via spine-interior containment instead of tuned volume thresholdsabd93b8fix: raise rib conformance volume threshold to drop cavity-trace phantom solids378a19bfix: exclude rib faces flush with scope from draft so wall-mounted ribs taper correctly65487c7fix: parallel-mode draft preserves spine-plane thickness and tapers only the tip8c777dafix: parallel-mode draft direction and angle convention so rib actually tapers2dabb58fix: drop sub-volume sliver fragments and fix parallel-mode draft + fuse-side cleanup185e443fix: unify coplanar artifact faces on conformed rib584cd0afix: propagate rib _parallel and _extend flags through createCopy so repeat() clones don't silently fall back to normal-mode no-extend ribs8a35eb9rewrite rib extend(): bbox-scaled spine extension + lineage-tracked conformal cut for robust blending with drafted/curved cavity facesb063d7arefactoring the rib extending algorithm - wip9812de6bug fix: rib extend and trim producing incorrect geometry with fuse and complex shapes5d9609abug fix: rib trim and extend producing incorrect geometry081e6a6feature: add extend() to rib for blending side faces with target solidsb249793feature: add parallel direction and draft support to rib()baaa045feature: add rib() for thin wall extrusions from sketch spines47e8b93feature: add noColors(), include(), exclude() chainable options to load()5e82088feature: add first(), last(), at(index) positional selectors to face/edge filters4069df4improve meshing performancede9f268Update shapes panel to use scene object name or type instead of shape type; update timeline to not auto-capitalize custom namesf31dc5aimprove face/edge lookup performancefe673b1bug fix: incorrect color bleedingee7ef3dpreserve scene object id across rendersa83cb26disable sketch mode section caps
v0.0.32
Release Notes — v0.0.32
Covers changes from v0.0.31 to v0.0.32.
Features
Cross-part shape selection
edge() and face() now support .from(part) to select shapes from a different part, making it easier to reference geometry across parts.
Face filters in extrude('first-face') and extrude('last-face')
extrude('first-face') and extrude('last-face') now accept face filters, giving finer control over which face the extrusion targets.
planar() face filter
New planar() face filter to select only planar faces.
above() / below() face filters
New above() and below() filters for selecting faces by their position relative to a reference.
Bug Fixes
- extrude().add() caused all touching shapes to fuse even when they did not touch the extrusion.
- Extrude failed for sketches outside the 1000 unit bound.
- Extrude-to-face comparison was failing making uncacheable.
guide()method moved fromISceneObjecttoIGeometry.- 2D
mirrorreturned the wrong interface type. - Extrude to
first-facewas not respecting the normal direction. extrude().sideFaces()was empty when extruding in the sketch normal reverse direction.linefeature was not repeatable; implementedcreateCopy.- Section view in sketch mode was not exactly at the sketch plane.
- Drafted cut through all (
cut().draft()) was not working. - Rotate operations were failing to cache.
Docs
- New drafted box tutorial.
- Analytics setup.
Commits
20a3ddachore: release v0.0.32598fef0bug fix: new extrude causes all touching shapes to fuse even if they are not touching the extrusion9125242bug fix: extrude fails for sketches outside 1000 unit bound60808fbdocs: setup analytics69074c5docs: new drafted box tutorial1cad19dbug fix: extrude to face comparison failing1853ddbbug fix: move guide() method from ISceneObject to IGeometrybf20b23bug fix: mirror 2D returning wrong interface type4a287e9bug fix: extrude to first-face not respecting normal directioneb840a5bug fix: extrude().sideFaces() empty when extruding in sketch normal reverse direction03b579bfeature: allow filtering faces in extrude('first-face') and extrude('last-face')aa3668ffeature: add new planar() face filter30a7412bug fix: implement createCopy in line feature to make it repetableed34daafeature: add above/below filters for faces1e78308bug fix: section view in sketch mode is not exactly at sketch planeaedf3d2bug fix: drafted cut through all cut().draft() is not working2c273babug fix: rotate operations failing to cache99cf2a3feature: allow selecting shapes from different part using edge().from(part) and face().from(part)
v0.0.31
Release Notes — v0.0.31
Covers changes from v0.0.30 to v0.0.31.
Features
Fusion type and scope on mirror()
mirror() now supports fusion type and scope via .add(), .new() and .remove(), matching the other fusing features.
Move up to a geometry
hmove, vmove and pmove can now move up to another piece of geometry, instead of always requiring an explicit distance.
Validation for consumed/stale shapes
Attempting to use a consumed or stale shape now produces a clear validation error instead of silently misbehaving downstream.
Opaque sketch section view
The sketch section view now renders opaque faces instead of hollow shapes, making sectioned geometry easier to read.
UI updates
- Updated highlight colors.
- Visibility and transparency are now tracked by shape id, and transparency is reset on popup close.
Breaking Changes
pmove() and arc() use the current tangent
pMove() now performs the polar move starting from the current tangent direction, and arc() draws using the current tangent as the zero angle. Existing sketches that relied on the previous absolute angles will need to be updated.
Bug Fixes
shellcleared colors in some cases.- Default tangent was not set on sketches.
start()andend()returned incorrect values on projected and intersected curves.face().cylinderCurve()did not work when the cylindrical curve had ellipse edges.- First attempt to import a STEP file always throws an error. Fixed by updated OC bindings.
project()generated coincident edges; the implementation now removes them.
Docs
- New
l-stubtutorial, plus a follow-up fix. - Tutorial updates for the
pmove/arcbreaking changes. - Documentation for
mirror()fusion type and scope. - Updated lines documentation.
- Added missing API docs.
Commits
1969d18chore: release v0.0.3143c4074docs: fix l-stub tutorial1bc081dadd validation errors for attempts to use consumed/stale shapesfbcea3bupdate sketch section view to render opaque faces instead of hollow shapesb935805bug fix: shell clearing colors in some cases008dcacrestore the selection colorbfd09c2docs: update with new information for pmove and arc3395323docs: update tutorial after new breaking changes79c06deupdated pMove() to do the polar move starting from the current tangent direction; updated arc to draw using current tangent as zero angleb17db3abug fix: set default tangent on sketches02c4ce5bug fix: start() and end() in projected and intersected curves is not correcta19fdb1fix error messages description + fix offset bugb949e3ebug fix: face().cylinderCurve() not working when the cylindrical curve has ellipse edges253a8defeature: allow hmove, vmove and pmove to move up to a geometry instead of distanceb4f1770bug fix: update binding to fix step import issue059d14ddocs: add new l-stub tutorialdd89191bug fix: project() generates coincident edges - update the implementation to remove them001f31eui: update highlight colors1a9323cuse shape id for visibility/transparency tracking + reset transparency on popup closedf06b2fdocs: add mirror fusion type and scope documentation8b93e38feature: mirror() now supports fusion type and scope .add() .new() .remove()ca5921bdocs: update lines documentationd1dac9fuse shape id for tracking transparency instead of shape index03c9bb4docs: add missing api docs
v0.0.30
Release Notes — v0.0.30
Covers changes from v0.0.29 to v0.0.30.
Features
exclude() on transforms and mirror
rotate(), translate() and mirror() now accept an .exclude(...) method to omit specific objects from the operation.
2D back() command
New back() command in 2D sketches that moves the cursor back to the previous position, making it easier to build paths that branch off from an earlier point.
Draw lines up to an intersection
hline, vline and aline can now be drawn up to the intersection with another piece of geometry, instead of always requiring an explicit length.
Better error reporting
Improved error reporting across the board, with clearer messages and better context for debugging.
Breaking Changes
.centered() method on hline / vline / aline
The centered argument has been removed from hline, vline and aline. Use the .centered() method instead, for consistency with how other features configure this option.
Bug Fixes
color()was adding faces to the scene as a side effect.
Docs
- Updated
hline,vlineandalinedocumentation to reflect the new signatures and.centered()method.
Commits
08b80a4chore: release v0.0.304e38d40feature: better error reporting97621c2bug fix: using color() adds faces to scenea4a4f2afeature: add exclude() to rotate() and translate() to exclude specific objects from operation096bb0efeature: add new 2d back() command to move back to the previous positionaec7424feature: added .exclude() to mirror to exclude specific objects from the operationd3f0b72feature: allow drawing hline, vline and aline up to the intersection with another geometryfb3fbdeupdate the signature for aline, hline and vline to remove the centered option and replaced it with a method config .centered() to match other featuresd19d047docs: update hline and vline docsb05cf11removed 'centered' argument from hline and vline. use .centered() method insteadee57e8bdocs: update aline docs8564a2fupdate aLine parameters order + move centered to be set via method to make it consistent with other features
v0.0.29
Release Notes — v0.0.29
Covers changes from v0.0.28 to v0.0.29.
Features
Ellipse 2D feature
New ellipse(...) 2D feature for sketching ellipses, alongside the existing circle/arc/rectangle primitives.
from() selection filter
New from(...) selection filter to scope a selection to the shapes of specific objects, instead of searching the whole scene.
select(face().from(myPart));Closing an open offset wire
Open offset wires can now be closed, completing the shape into a closed region.
Breaking Changes
Plane-first signature for standalone 2D features
Standalone 2D features (used outside a sketch) now take the plane as their first argument instead of the last.
Sketch / part return values are namespaced
Values returned from sketch(...) and part(...) callbacks are now namespaced under regions / features on the returned scene object, so they can no longer accidentally overwrite internal scene-object properties.
Bug Fixes
- VSCode keybindings did not work when the viewer was in focus.
- Guide shapes were not visible in rollback.
- The current-position indicator did not render in rollback.
- Switching between Neovim-opened buffers did not update the scene.
- Neovim showed all scene objects from cache on first render.
revolvecap faces returned the wrong faces.mirrorperformed an unintended axis-to-plane conversion; mirror now also validates its 2D/3D context #47.- 2D
rotatecalled in a 3D context now throws a clear error (#47).
Performance
- Faster fusion history recording — skips empty color-bleed and unused additions.
- Faster edge classification using
TopTools_MapOfShapefor dedup. - Added a scene-object profiler with custom profiling categories, plus more profiling coverage across features.
Internal
- Refactored extrude base classes for clearer logic branches.
Docs
- Updated color documentation.
- Documented the new
from()filter, offset updates, and the new 2D feature signatures.
Commits
eb93461chore: release v0.0.29ace94a7feature: add new ellipse 2d featuref686415bug fix: vscode keybindings not working when the viewer is in focus0ece120refactor: namespace sketch/part callback returns under regions/features to prevent overwriting scene-object internals562af2bdocs: update 2d features signaturec572488update all standalone 2d features (outside sketch) to accept the plane as first argument instead of last3efb529bug fix: guide shapes not visible in rollback4520756bug fix: current position indicator not rendering in rollbackaaae9fedocs: add new offset updatesda79aeefeature: allow closing an open offseted wiredde685edocs: add new from() filter69f9718feature: add new from() selection filter to scope the selection to specific object shapes7364225speed up Record fusion history by skipping empty color bleed and unused additions5c70e18speed up edge classification by switching to TopTools_MapOfShape dedup4250ec9add more profiling informationa22370ebug fix: switching between neovim opened buffers does not update the scene1e2d4c4disable axis to plane conversion in mirror86895aevalidate 2d and 3d context in mirror function7ef8588throw an error when 2d rotate is called in 3d context #4773026f9bug fix: revolve cap faces returning wrong faces6f93b2frefactor extrude base classes to better organize the logic branches2e48009bug fix: neovim showing all scene objects served from cache on first renderd0b2423add more profiling information to more featuresadccce0feature: add profiler for scene objects to add custom profiling categoriesdffa1b7docs: update color documentation