Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
50 most recent check-ins
|
2026-06-27
| ||
| 19:04 | Embed fossil hash as runtime version: bcad/_version.py reads manifest.uuid; version() returns ['bcad', HASH], version_num() returns 0; show hash in About dialog; build scripts bundle manifest.uuid leaf check-in: 4dd15c42db user: johnfound tags: boolean_operations | |
| 18:37 | loft fix: collect_wires handles shape-based parts (circle, cube); add IsDone check + try/except; first-render auto reset_view+fit_all; File→Examples menu; add cyan color; curated example files check-in: c6be41f66a user: johnfound tags: boolean_operations | |
| 16:08 | build scripts: --portable mode, fix OCCT symlink duplication, --help; layout: Output/Console side-by-side check-in: 63376a3054 user: johnfound tags: boolean_operations | |
| 13:22 | offset/minkowski: added progress tracking (push_label, check_cancel, advance_progress) check-in: fea41ecb3f user: johnfound tags: boolean_operations | |
| 13:05 | offset/minkowski: added color_blend parameter (mode/blend) for _adjacency_fill_colors; two-phase collect→apply eliminates dependency on OCCT traversal order check-in: fd61d6da22 user: johnfound tags: boolean_operations | |
| 09:37 | _offset_3d: rewritten with resolve_high_valence_vertices + BRepOffsetAPI_MakeOffsetShape.PerformByJoin; _adjacency_fill_colors: multi-pass mode-based color propagation; _bool_op: hardcoded OBB=True; removed dead _find_valency_vertices/_place_micro_spheres/_map_offset_colors check-in: 81998ce235 user: johnfound tags: boolean_operations | |
|
2026-06-26
| ||
| 17:42 | Removed limit on the scale factor. check-in: e8e471e007 user: johnfound tags: boolean_operations | |
| 13:52 | Fixed the bug with offset(0) removing colors. check-in: cd9aca3086 user: johnfound tags: boolean_operations | |
| 13:22 |
get_children: skip recursion into nodes that already have .shape
SCLProfile2 is a child of SCLPart3, but represents the same geometry. When get_children() recursed into SCLPart3, it exposed SCLProfile2 as a separate item — causing difference() to cut the base with an identical face (from the profile), producing empty. Fix: only recurse into children that don't have .shape set. Nodes with .shape (SCLPart3 after add_profile_shape, boolean ops, etc.) contain their result directly — their children are implementation details. translate/rotate/mirror/scale/circle-wrapper (no .shape) still recurse correctly into their nested shape-bearing children. check-in: c5f30e92e9 user: johnfound tags: boolean_operations | |
| 12:08 |
offset: replace _is_2d heuristic with _get_offset_path validation
Old _is_2d checked only face count — 1 face → 2D path. Sphere (1 face, non-planar) was misclassified → crash in topods.Wire(). New _get_offset_path: - Solids → 3D (catches sphere, cube, etc.) - Single planar face → 2D - Non-planar single face → None (warning + return original) - Wires: check planarity via BRepBuilderAPI_FindPlane → 2D or None - Multiple faces, no solid → 3D (shell attempt) BRepBuilderAPI_FindPlane added to imports. GeomAbs_Plane added to imports. check-in: 07ec3d32d5 user: johnfound tags: boolean_operations | |
| 11:20 |
remove dead seen dedup from SCLGroup, SCLDifference, SCLIntersection
Experiment confirmed zero duplicates across all 59 .scad test files. seen = set() with id()-based dedup is dead code — two different children can't share the same Python object id() in BCad. Only _find_valency_vertices retains its IsSame-based seen for edge dedup across adjacent faces (shared edges appear twice). check-in: 324d2702fa user: johnfound tags: boolean_operations | |
| 10:47 |
cleanup: remove DEBUG_GROUPS/FLATTEN_GROUPS flags, move debug utilities to end of file, drop redundant local imports
- Remove DEBUG_GROUPS and FLATTEN_GROUPS module constants - SCLGroup.group() always flattens compounds (was behind FLATTEN_GROUPS=True) - Remove dead if DEBUG_GROUPS: block from SCLGroup.group() - Move _shape_type_str, debug_shape_structure, print_algo_diagnostics to end of file under '# --- Debug utilities ---' section - Move from OCC.Core.Message import inside print_algo_diagnostics() - Remove redundant local imports (already at module level): topods, TopologyExplorer, TopoDS_Compound, BRepBuilderAPI_MakeFace check-in: 1a11ea0263 user: johnfound tags: boolean_operations | |
| 07:29 |
transform_shape/transform_gtrsf: remap face colors after transform — fixes color loss on translate/rotate/mirror of boolean op results
BRepBuilderAPI_Transform creates new shape with new face hashes, but _face_colors dict kept old hashes → all faces got PERU. Fix: save hashes of old faces before transform, iterate new faces in same topological order after transform, copy colors across. check-in: bca7a306e1 user: johnfound tags: boolean_operations | |
| 07:24 |
_fuse_parts: use _extract_face_colors instead of {} fallback — fixes union() color loss
_face_colors can be None (no per-face colors), in which case _extract_face_colors falls back to shape_rgba (solid color from color() directive). Using {} meant _map_colors got empty dicts → all-PERU result. check-in: a4c231296a user: johnfound tags: boolean_operations | |
| 06:56 | Broken colors regression. check-in: 104b24a33b user: johnfound tags: boolean_operations | |
|
2026-06-25
| ||
| 20:15 | snapshot before _fuse_parts refactor check-in: 5ca9d06039 user: johnfound tags: boolean_operations | |
| 13:24 |
cleanup: remove experimental boolean operation variants (algo=1/2/3)
- Remove dead functions: smart_unpack, flatten_shape, universal_optimized_common, universal_optimized_fuse, universal_optimized_fuse_colored, tree_fuse_colored, union_via_builder_algo - Remove algo parameter from union() and intersection() — only proven paths remain (single multi-tool Fuse for union, pairwise Common with bbox filter for intersection) - Remove timing instrumentation from hot paths - Remove debug_shape_structure calls - Always-on SetUseOBB(True) in _bool_op check-in: 1b01a26b53 user: johnfound tags: boolean_operations | |
| 13:02 |
experiments: preserve boolean operation variants before cleanup
- Add union_via_builder_algo() — BRepAlgoAPI_BuilderAlgo with configurable NonDestructive/OBB/SimplifyResult/parallel/fuzzy - Add algo=3 in union() — uses union_via_builder_algo - Add use_obb parameter to _bool_op() — OBB toggle for all BOPs - tree_fuse_colored: changed from tree-reduce to linear sequential (algo=2) - All kept for reference before removal check-in: 4e22fabd52 user: johnfound tags: boolean_operations | |
| 10:16 |
union: add algo=1 (bbox clusters) and algo=2 (tree-reduce) for comparison
- Add universal_optimized_fuse_colored(all_parts) - cluster-based fuse with bbox graph + BFS, per-cluster multi-tool Fuse + ShapeUpgrade + colors - Add tree_fuse_colored(all_parts) - tree-reduce pairwise fuse Without intermediate Unify (only final); per-level timing output - union_module_definition + _handle_union: accept algo parameter union() / algo=0: single multi-tool Fuse (default) union(1): bbox clusters union(2): tree-reduce pairwise check-in: 90cd6931d0 user: johnfound tags: boolean_operations | |
| 08:53 |
boolean ops: replace legacy 2-arg BOP constructors with multi-tool API
- Add _bool_op(op_class, args, tools=None, fuzzy=None) helper in scl_context.py All boolean operations now go through the new OCC multi-tool API (SetArguments/SetTools/Build) instead of legacy 2-arg constructors. ~3x faster per operation — confirmed by timing measurements. - Replace all legacy BRepAlgoAPI_Cut/Fuse/Common(a, b) calls: _cut_parts, linear_extrude, _fuse_two (x4), _ensure_solid (x2), _place_micro_spheres, universal_optimized_common - Convert remaining manual SetArguments/SetTools blocks to _bool_op: SCLUnion.union(), SCLIntersection.intersection(algo=1), universal_optimized_common_colored, universal_optimized_fuse - intersection(algo): add algo=0/1 parameter to SCLIntersection algo=0 (default): existing iterative pairwise Common with bbox filter algo=1: single multi-tool BRepAlgoAPI_Common call (union-style) Both now use new API — timing shows ~equal speed for simple cases, algo=0 better for many shapes due to bbox filtering - Add timing output to intersection(0) and universal_optimized_common_colored check-in: 9196aa8d1f user: johnfound tags: boolean_operations | |
|
2026-06-24
| ||
| 22:30 |
display mode: independent Shaded/Wireframe toggle buttons
Replace radio-group (shaded|wireframe) with two independent toggles. Three resulting modes: shaded-only, wireframe-only, shaded+edges. Forbidden state (both off) handled by auto-enabling the other button. Shaded+edges uses SetFaceBoundaryDraw on the default drawer. Force recomputation of all displayed objects via Context.Redisplay() to pick up the changed drawer settings. check-in: 1d33eb440f user: johnfound tags: boolean_operations | |
| 21:48 |
remove HLR (hidden line removal) display mode
HLR used ComputedMode which was extremely slow and not useful. Removed: DISP_MODE_HLR constant, SetModeHLR(), _was_hlr tracking, ComputedMode checks during viewport interactions, commented-out code, UI menu/toolbar entries, and icon files. check-in: 4bc59efbce user: johnfound tags: boolean_operations | |
| 21:42 |
add group() builtin module (lightweight container, no boolean fuse)
Exposes SCLGroup via group() command — collects children into TopoDS_Compound without expensive boolean operations. check-in: 18c3e46cc0 user: johnfound tags: boolean_operations | |
| 16:47 | mythread.scad almost done. check-in: 981155f88d user: johnfound tags: boolean_operations | |
| 13:57 | ResetView preserves current projection type check-in: 53d36efa0d user: johnfound tags: boolean_operations | |
| 13:50 | Refactor scene lighting: replace SetIntensity with SetColor via _light_color(); 3 fill lights via _direction_from_angles(); change material to STEEL check-in: 4b4b5d8929 user: johnfound tags: boolean_operations | |
| 08:45 | Add max_y() function and tests; fix flatten recursion check-in: b568c80211 user: johnfound tags: boolean_operations | |
| 05:52 |
Fix string iteration in [for(...)]: convert str to list of chars
In OpenSCAD, for-range can be a string — iterates over characters. check-in: ff68d6e061 user: johnfound tags: boolean_operations | |
| 05:50 |
Support nested for/if inside [for(...)] list comprehensions
- Replace flat expr_array_for grammar with recursive array_for_body supporting arbitrary nesting: for/if/for/if/... chains - New node type expr_array_for_filter for if-without-for inside array_for_body (chained filters compose via wrapping) - Runtime: detect nested expr_array_for through filter wrappers, extend instead of append for nested loops - Tests: list-flatten.scad (qsort companion from OpenSCAD manual) and all prior for/if/else variants continue to pass check-in: 4b7dd17e4b user: johnfound tags: boolean_operations | |
| 05:30 |
Fix rands() seed handling: deterministic when seed arg provided
- Extract _rands() helper to avoid per-iteration Random recreation - Use random.Random(seed) when 4th arg given, random.Random() otherwise - Add 'seed' param to rands signature check-in: 48c859a1ea user: johnfound tags: boolean_operations | |
| 05:25 |
Add if/else filter support inside [for(...)] list comprehensions
- Parser: three grammar variants for expr_array_for (no filter, with if, with if/else) all produce the same expr_array_for node with optional filter/else_body fields - Runtime: single handler evaluates filter condition via scl_bool, skips or uses else_body when condition is false - No duplicated logic — same node type, no new loop infrastructure check-in: a6347a87ba user: johnfound tags: boolean_operations | |
|
2026-06-23
| ||
| 23:01 | mythread.scad Ðlibrary almost working. check-in: 3c55402da0 user: johnfound tags: boolean_operations | |
| 23:01 |
Robustness improvements: error handling for arithmetic and OCCT operations, current_pos() builtin, clear logs on reload
- Arithmetic binop/unop: catch TypeError/ZeroDivisionError instead of crashing, emit warning + return undef - Line3/Arc3/Spline3.to_edge(): validate inputs, catch OCCT exceptions - get_wire(): skip None edges from failed to_edge() - get_face(): catch BRepBuilderAPI_MakeFace exceptions - Add current_pos() builtin function returning [x,y] inside profile() - Clear Console and Output windows on each render/reload check-in: 9a16ab0932 user: johnfound tags: boolean_operations | |
| 18:31 |
SCLProfile2.close(): skip degenerate zero-length closing edge with tolerance check
When the last primitive already closes the contour back to start_pos, close() would add a Line3 from current_pos to start_pos. Due to floating-point drift (cos^2+sin^2 != 1.0), the positions differed by ~4e-16, creating a zero-length edge. BRepBuilderAPI_MakeFace then failed with Standard_NullObject: No geometry. Fix: skip adding the closing line if squared distance < 1e-14. check-in: 8b7bf314ea user: johnfound tags: boolean_operations | |
| 17:27 | progress: shared memory instead of pipe; right-aligned bar text; for-loop progress labels restored; hash-based face color mapping check-in: 2c9dd4ce36 user: johnfound tags: boolean_operations | |
| 15:16 | SCLUnion batch fuse with face colors; _map_batch_face_colors/_map_unified_face_colors; progress throttle removed check-in: e8be2f5779 user: johnfound tags: boolean_operations | |
| 05:18 | optimized intersection/difference with bbox filter and face colors; _unpack_compound universal; polyhedron None→0.0 check-in: 4b9d3f5c15 user: johnfound tags: boolean_operations | |
|
2026-06-22
| ||
| 14:30 | Test case for compaunds debugging. check-in: bee11611c2 user: johnfound tags: boolean_operations | |
| 12:50 |
Refactor: SCLGroup replaces implicit union, SCLUnion simplified
- New SCLGroup class: always creates TopoDS_Compound (was implicit SCLUnion). - Pass-through for single child (no compound wrapper). - FLATTEN_GROUPS flag to unpack nested compounds into flat compound. - _unpack_compound() with correct face-color remapping across sub-shapes. - debug_shape_structure() for debugging group output. - SCLUnion: removed implicit flag, always does real BRepAlgoAPI_Fuse. - scl.py: _should_union() → _should_group(), all implicit sites use SCLGroup. - Explicit union{} still calls SCLUnion with real fuse. - Parser cache cleared. check-in: bf51d964c9 user: johnfound tags: boolean_operations | |
| 09:36 |
Progress bar, cancel, axes fix, and mirror warning removal
Port from gui_works branch: - bcad/binterpreter/progress_helper.py — new module with StopExecution, init/advance/adjust progress, push_label/pop_label, check_cancel - rqq.py — RQ_CANCEL requests, RP_PROGRESS replies, rq_cancel() - glfw_display.py — send_urgent() method - main_window.py — _reloading, _reload_progress fields, RP_PROGRESS handler, rq_cancel() in _reload_active, disable Reload menu during reload, pass reload state to toolbar, clear _reloading on RP_ACK too - bcode_tools.py — _render_reload_toolbar with Cancel button + progress bar - scl.py — progress checks in load_file(), stat_call, stat_for; push_label/pop_label for hierarchical label display; StopExecution handling - scl_context.py — advance_progress, check_cancel, push_label/pop_label in union/difference/intersection; axis uses adaptive length; mirror silent no-op - offscreen_display.py — _update_axis_length call in update_img() - progress_helper.py throttle reduced to 30ms check-in: 455268b183 user: johnfound tags: boolean_operations | |
| 08:11 | New branch in order to develop correctly working and simple boolean operations. check-in: f0b8129e53 user: johnfound tags: boolean_operations | |
|
2026-06-21
| ||
| 21:41 |
Fix boolean operations with compound operands for intersection() and difference()
intersection(): - Rewrote sequential processing to handle compound operands correctly - Fixed color preservation: create wrapper with colors for ANY result (not just COMPOUND) - Handles compound∩solid, solid∩compound, compound∩compound, and 3+ operands - Nested and flat intersection produce identical results with correct colors difference(): - Fixed color loss when fusing multiple cutters via _run_boolean_loop - Corrected _map_face_colors to use returned cutter_colors, not empty dict - Handles compound base with multiple cutters (fuse cutters first, then cut) - Fixed compound base + compound cutters case _unpack_compound_wrappers: - IsSame-based algorithm for correct color mapping per sub-shape - Previously used wrong index (i+1) instead of first face of each sub All boolean operations now correctly preserve per-face colors through compound operands with 3+ participants. leaf check-in: 9d31001d1e user: johnfound tags: gui_works | |
| 08:26 |
fix progress bar tracking in _run_boolean_loop with tree/group merge
- n_total set only at outermost call; recursive calls pass it through - advance_progress after every merge step (tree merge and spatial group merge) - Flat indexing idx/n_total, always monotonic, no N > M - Spatial group merge and Cut disjoint now also advance progress check-in: 187cc5ad36 user: johnfound tags: gui_works | |
| 08:18 | silent no-op for mirror([0,0,0]) check-in: df904b49e1 user: johnfound tags: gui_works | |
| 08:15 |
fix: per-face color mapping after ShapeUpgrade_UnifySameDomain merges coplanar faces
- Preserve original colors for unchanged faces via hash-based IsEqual matching - Merged faces get first parent's color instead of all-or-nothing reset - Remove break from Modified loop in _map_face_colors (all split faces get color) - Replace O(m×n) face scan with hash-based O(m) lookup - Fix _echo_output NoneType crash for headless mode check-in: 62c32f4e92 user: johnfound tags: gui_works | |
|
2026-06-20
| ||
| 17:49 | Minimal length of the axis for nano objects. check-in: 18202124d5 user: johnfound tags: gui_works | |
| 14:13 | adaptive axis length: AIS_Line(Geom_Line) + SetMaximalParameterValue, 10x viewport diagonal on update_img() check-in: 039fe0490c user: johnfound tags: gui_works | |
| 06:47 | reload toolbar: Cancel before progress bar, no 'Reloading...' label, 4px padding check-in: 71ba2ed3aa user: johnfound tags: gui_works | |
| 06:35 |
progress + cancel: dynamic counter, RP_PROGRESS/RQ_CANCEL, toolbar progress bar, cancel guard
- progress_helper.py: StopExecution, init/advance/adjust progress, check_cancel, send_urgent - rqq.py: RQ_CANCEL(23), RP_PROGRESS(9), rq_cancel() clears queue - glfw_display.py: send_urgent() bypasses waiting_reply - scl.py: load_file init_progress + per-stmt advance; stat_for adjust_total + per-iteration advance; check_cancel in stat_call - scl_context.py: union/difference/intersection per-op advance + cancel check - main_window.py: _reloading flag, RP_PROGRESS handler, F5/menu guard during reload - bcode_tools.py: reload toolbar with progress bar + Cancel button check-in: a78ec9a06b user: johnfound tags: gui_works | |
|
2026-06-19
| ||
| 21:55 |
union: fix 2D coplanar face fusion, clean up circle() nesting
- circle(): set self.shape directly instead of nesting SCLPart3 - union explicit: unwrap COMPOUND via TopoDS_Iterator, apply ShapeUpgrade - close(): guard degenerate zero-length edge - add_profile_shape(): remove SCLProfile2 from children - get_children(): skip SCLProfile2 recursion - collect_wires(): fix for non-SCLProfile2 children - _print_shape_tree(): recursive debug printer for OCC shapes - print_tree(): show shape tree after context info check-in: 5ca11e1f80 user: johnfound tags: gui_works | |