From b86bf451673257ec6c4ec183d0557f8d55f1864f Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 21 Jan 2026 12:32:11 +1100 Subject: [PATCH] Remove claude --- .claude/settings.local.json | 10 - CLAUDE.md | 637 ------------------------------------ 2 files changed, 647 deletions(-) delete mode 100644 .claude/settings.local.json delete mode 100644 CLAUDE.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index 7968720238..0000000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(cat:*)", - "Bash(find:*)", - "Bash(grep:*)", - "Bash(xargs:*)" - ] - } -} diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 01aaf0b19b..0000000000 --- a/CLAUDE.md +++ /dev/null @@ -1,637 +0,0 @@ -# CLAUDE.md - Saikei Civil Context for IfcOpenShell Contributions - -> This document provides context for Claude Code when working on Saikei Civil contributions to IfcOpenShell, specifically horizontal alignment visualization. - ---- - -## Project Overview - -**Saikei Civil** (formerly BlenderCivil) is an open-source Blender extension for native IFC 4.3 infrastructure design. The project aims to democratize professional civil engineering tools by providing free alternatives to expensive commercial software like Civil 3D ($2,500/year) and OpenRoads ($4,000/year). - -### Mission -- **Bonsai BIM** = Buildings (vertical construction) -- **Saikei Civil** = Infrastructure (horizontal construction: roads, earthwork, drainage) - -> "While Bonsai crafts the buildings, Saikei shapes the world around them." - -### Key Differentiator -**Native IFC Philosophy**: IFC files serve as the primary database rather than export targets. We're not converting TO IFC - we ARE IFC from the start. - ---- - -## Architecture Principles - -### Three-Layer Architecture (Matches Bonsai) - -Saikei follows Bonsai's proven architecture with `core/` and `tool/` at the **package root level**: - -``` -saikei/ -├── core/ # Layer 1: Pure Python - NO bpy imports -│ └── alignment.py # Business logic, math, validation -├── tool/ # Layer 2: Blender implementations - HAS bpy -│ └── alignment.py # Blender object creation, linking -└── civil/ # Layer 3: UI (like Bonsai's bim/) - └── module/ - └── alignment/ - ├── __init__.py # Registration - ├── operator.py # Blender operators - ├── ui.py # UI panels - ├── prop.py # PropertyGroups - └── data.py # UI data caching -``` - -**Layer Responsibilities:** - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Layer 3: civil/module/{name}/ (UI Layer) │ -│ - operator.py: User actions (bpy.types.Operator) │ -│ - ui.py: Interface panels (bpy.types.Panel) │ -│ - prop.py: UI state (bpy.types.PropertyGroup) │ -│ - Calls core functions, passing tool implementations │ -└─────────────────────────────────────────────────────────────┘ - │ calls - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ Layer 1: core/ (Pure Python - NO bpy imports) │ -│ - All business logic, algorithms, mathematics │ -│ - Receives tool classes as parameters (dependency inject) │ -│ - MUST be testable outside Blender │ -└─────────────────────────────────────────────────────────────┘ - │ receives as parameters - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ Layer 2: tool/ (Blender implementations) │ -│ - Concrete implementations with bpy │ -│ - Blender object creation, scene manipulation │ -│ - Wraps Bonsai's tool.Ifc, tool.Collector, etc. │ -└─────────────────────────────────────────────────────────────┘ -``` - -### Bonsai's Dependency Injection Pattern - -Core functions receive tool classes as parameters, enabling testability: - -```python -# In core/alignment.py (NO bpy imports) -from __future__ import annotations -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - import ifcopenshell - import saikei.tool as tool - -def create_alignment_visualization( - ifc: type[tool.Ifc], - alignment_tool: type[tool.Alignment], - alignment: ifcopenshell.entity_instance, -) -> list: - """Pure business logic - tools passed as parameters.""" - segments = get_layout_segments(alignment) - objects = [] - for segment in segments: - obj = alignment_tool.create_segment_object(segment) - ifc.link(obj, segment) - objects.append(obj) - return objects -``` - -```python -# In civil/module/alignment/operator.py (HAS bpy) -import bpy -import saikei.tool as tool -import saikei.core.alignment as core - -class SAIKEI_OT_visualize_alignment(bpy.types.Operator): - def execute(self, context): - alignment = self.get_active_alignment() - # Call core logic, passing tool implementations - core.create_alignment_visualization( - tool.Ifc, tool.Alignment, alignment - ) - return {'FINISHED'} -``` - -### Golden Pattern for Native IFC - -```python -# 1. GET IFC FILE -ifc = NativeIfcManager.get_file() - -# 2. CREATE/MODIFY IFC ENTITY FIRST -entity = ifc.create_entity("IfcAlignment", ...) - -# 3. CREATE BLENDER VISUALIZATION SECOND -obj = create_blender_object(...) - -# 4. LINK THEM (minimal storage in Blender) -NativeIfcManager.link_object(obj, entity) -# obj["ifc_definition_id"] = entity.id() -# obj["ifc_class"] = entity.is_a() -# obj["GlobalId"] = entity.GlobalId - -# 5. SAVE = WRITE IFC FILE -NativeIfcManager.save_file("project.ifc") -``` - -### Key Principles -1. **IFC-First Design**: ALL civil engineering data lives in the IFC file -2. **Minimal Blender Storage**: Only 3 properties stored in Blender objects -3. **Separation of Concerns**: Core logic has NO bpy imports -4. **IfcStore Pattern**: Following Bonsai's proven pattern for IFC file management - ---- - -## IFC 4.3 Alignment Structure - -### Entity Hierarchy - -``` -IfcProject -└── IfcSite - └── IfcRoad (via IfcRelAggregates) - └── IfcAlignment (via IfcRelContainedInSpatialStructure) - ├── IfcAlignmentHorizontal (via IfcRelNests) - │ └── [IfcAlignmentSegment → IfcAlignmentHorizontalSegment]* - ├── IfcAlignmentVertical (via IfcRelNests) - │ └── [IfcAlignmentSegment → IfcAlignmentVerticalSegment]* - └── IfcAlignmentCant (via IfcRelNests) [Future] - └── [IfcAlignmentSegment → IfcAlignmentCantSegment]* -``` - -### Critical IFC Rules - -1. **Zero-Length Terminal Segments**: The last `IfcAlignmentSegment.DesignParameters` in each layout MUST be zero length to provide the end point -2. **Ordered Collections**: `IfcRelNests.RelatedObjects` maintains segment order (start to end) -3. **Nesting Order**: Horizontal precedes Vertical precedes Cant in `IfcRelNests` - -### Semantic vs Geometric Representation - -The IFC 4.3 alignment model has TWO parallel structures: - -**Semantic (Business Logic)**: -- `IfcAlignmentHorizontalSegment` with `PredefinedType` (LINE, CIRCULARARC, CLOTHOID, etc.) -- Contains design parameters (radius, length, direction) - -**Geometric (Shape)**: -- `IfcCurveSegment` → `ParentCurve` (IfcLine, IfcCircle, IfcClothoid) -- Combined into `IfcCompositeCurve` (horizontal) or `IfcGradientCurve` (vertical) - -**Mapping Table:** -| Business Logic (Semantic) | Geometric ParentCurve | -|---------------------------|----------------------| -| LINE | IfcLine | -| CIRCULARARC | IfcCircle | -| CLOTHOID | IfcClothoid | -| CUBIC | IfcPolynomialCurve | -| PARABOLICARC | IfcPolynomialCurve | -| CONSTANTGRADIENT | IfcLine | - -### The 2.5D Layered Model - -IFC alignments use a "2.5D" approach - combining multiple 2D curves: - -1. **Layer 1 - Horizontal**: `IfcCompositeCurve` in X-Y (Easting-Northing) plane -2. **Layer 2 - Vertical**: `IfcGradientCurve` in "Distance Along, Elevation" coordinate system - - `BaseCurve` attribute points to horizontal `IfcCompositeCurve` -3. **Layer 3 - Cant**: `IfcSegmentedReferenceCurve` for superelevation - - `BaseCurve` typically points to `IfcGradientCurve` - ---- - -## Horizontal Alignment Implementation - -### PI-Driven Design Approach - -Saikei Civil uses the **Point of Intersection (PI)** method, matching professional workflows in Civil 3D and OpenRoads: - -``` - PI● is just an intersection point - ╲ - ╲ Tangent - BC (Begin Curve) - ╲ ╱ - ● Curve (R=150m) - ╱ ╲ - EC (End Curve) - ╱ Tangent - ╱ -``` - -**Key Distinction**: -- PIs are just intersection points (NO radius property) -- Curves are separate entities inserted between tangents (Curves HAVE radius) - -### Core Classes - -```python -class HorizontalAlignmentManager: - """Core engine for horizontal alignment""" - def add_pi(self, x: float, y: float) -> PI - def insert_curve(self, pi_index: int, radius: float) -> Curve - def generate_segments(self) -> List[Segment] - -class PI: - """Point of Intersection - just a position""" - position: Tuple[float, float] - # NO radius property - -class Curve: - """Curve inserted at a PI""" - radius: float - bc: Tuple[float, float] # Begin Curve point - ec: Tuple[float, float] # End Curve point - at_pi: int # Which PI this curve is at -``` - -### Civil Engineering Mathematics - -**Deflection Angle:** -``` -Δ = arccos(t₁ · t₂) -``` -Where t₁ and t₂ are normalized incoming/outgoing tangent vectors. - -**Tangent Length:** -``` -T = R × tan(Δ/2) -``` - -**Arc Length:** -``` -L = R × Δ (radians) -``` - -**BC/EC Points:** -``` -BC = PI - t₁ × T -EC = PI + t₂ × T -``` - -### Segment Generation - -```python -def regenerate_segments(self): - """Auto-generate tangent and curve segments from PIs""" - segments = [] - - for i, pi in enumerate(self.pis[:-1]): - next_pi = self.pis[i + 1] - - # Check if curve at this PI - curve = self.get_curve_at_pi(i) - - if curve: - # Add incoming tangent (trimmed to BC) - segments.append(create_line_segment(prev_end, curve.bc)) - # Add curve - segments.append(create_arc_segment(curve)) - prev_end = curve.ec - else: - # Add full tangent - segments.append(create_line_segment(prev_end, next_pi.position)) - prev_end = next_pi.position - - return segments -``` - ---- - -## Visualization Layer - -### AlignmentVisualizer Class - -```python -class AlignmentVisualizer: - """Create Blender visualization of IFC alignment""" - - def __init__(self, native_alignment): - self.alignment = native_alignment - self.collection = None - self.pi_objects = [] - self.segment_objects = [] - - def visualize_all(self): - """Generate complete visualization""" - self.setup_collection() - self.create_pi_markers() - self.create_segment_curves() -``` - -### Color Coding Convention - -**PI Markers (Empties):** -- 🟢 Green = Tangent points (no curve) -- 🟠 Orange = Curve PIs (curve inserted) - -**Segment Objects (Curves):** -- 🔵 Blue = Tangent segments (LINE) -- 🔴 Red = Circular arcs (CIRCULARARC) - -### Object Linking Pattern - -```python -# Every Blender object stores only 3 properties -obj["ifc_definition_id"] = entity.id() -obj["ifc_class"] = entity.is_a() -obj["GlobalId"] = entity.GlobalId - -# All other data comes from IFC -entity = NativeIfcManager.get_entity(obj) -params = entity.DesignParameters # Real data from IFC! -``` - ---- - -## Rick Brice's IfcOpenShell Alignment API - -Rick Brice's alignment API was merged into IfcOpenShell v0.8.0 (PR #6234, March 14, 2025). This API provides comprehensive Python functions for IFC alignment creation. - -### Key Functions - -**Creation:** -```python -import ifcopenshell.api.alignment as align_api - -# Create alignment with PI method -alignment = align_api.create_by_pi_method( - ifc_file, - name='Main Alignment', - hpoints=[(0,0), (100,50), (200,100)], # Horizontal PI coordinates - radii=[0, 150, 200], # Curve radii at PIs - start_station=0.0 -) - -# Create alignment structure -alignment = align_api.create( - ifc_file, - name="Highway 101", - horizontal_layout=horiz, - vertical_layout=vert # Optional -) -``` - -**Layout Functions:** -```python -# Add to existing horizontal -align_api.layout_horizontal_alignment_by_pi_method( - ifc_file, horiz_alignment, hpoints, radii -) - -# Add vertical layout -align_api.add_vertical_layout(alignment, vertical_layout) - -# Add zero-length terminator (required!) -align_api.add_zero_length_segment(layout) -``` - -**Getters:** -```python -horiz = align_api.get_horizontal_layout(alignment) -vert = align_api.get_vertical_layout(alignment) -segments = align_api.get_layout_segments(layout) -curve = align_api.get_layout_curve(layout) # IfcCompositeCurve/IfcGradientCurve -``` - -### Integration Strategy - -**Recommended architecture for Saikei contributions:** - -| Layer | Rick's API Responsibility | Saikei's Responsibility | -|-------|--------------------------|------------------------| -| IFC Backend | All IFC entity creation, relationships, geometric representations | None - use Rick's API | -| Business Logic | Alignment math, segment generation, stationing | Design validation, AASHTO rules | -| UI Layer | None (Python API only) | Full Blender panels, operators | -| Visualization | None | Real-time 3D preview, PI markers | - -### Example Integration Pattern - -```python -# Saikei Civil operator using Rick's API backend -import ifcopenshell.api.alignment as align_api - -class SAIKEI_OT_create_alignment(bpy.types.Operator): - def execute(self, context): - # Get PI data from Blender UI - hpoints = [(pi.x, pi.y) for pi in context.scene.saikei_pis] - radii = [pi.radius for pi in context.scene.saikei_pis] - - # Use Rick's API for IFC creation - alignment = align_api.create_by_pi_method( - self.ifc_file, - name='Main Alignment', - hpoints=hpoints, - radii=radii, - start_station=context.scene.saikei_start_station - ) - - # Saikei handles visualization - self.visualizer.update_from_ifc(alignment) - return {'FINISHED'} -``` - ---- - -## Validation and Compliance - -### buildingSMART Validation - -Saikei Civil has undergone extensive validation testing with buildingSMART International. Key compliance requirements: - -1. **Zero-Length Terminal Segments**: Every layout must end with a zero-length segment -2. **Spatial Hierarchy**: Proper `IfcRelAggregates` and `IfcRelContainedInSpatialStructure` -3. **Segment Continuity**: End of segment N must match start of segment N+1 (< 0.001m tolerance) -4. **Ordered Nesting**: Segments in correct order via `IfcRelNests.RelatedObjects` - -### Validation Code Pattern - -```python -def validate_alignment(alignment): - """Validate IFC alignment structure""" - errors = [] - warnings = [] - - # Check basic structure - if not alignment: - errors.append("No IfcAlignment entity") - return errors, warnings - - # Get horizontal layout - horiz = get_horizontal_layout(alignment) - if not horiz: - errors.append("No IfcAlignmentHorizontal") - return errors, warnings - - # Check segments - segments = get_layout_segments(horiz) - if len(segments) < 2: - warnings.append("Need at least 2 segments") - - # Check zero-length terminator - last_seg = segments[-1].DesignParameters - if last_seg.SegmentLength > 0.0001: - errors.append("Missing zero-length terminal segment") - - # Check continuity - for i in range(len(segments) - 1): - gap = calculate_gap(segments[i], segments[i+1]) - if gap > 0.001: - errors.append(f"Gap of {gap}m between segments {i} and {i+1}") - - return errors, warnings -``` - ---- - -## PR Focus: Horizontal Alignment Visualization - -For your first PR focused on horizontal alignment visualization, focus on: - -### Core Requirements - -1. **Read IFC alignment data** using Rick's API getters -2. **Generate Blender visualization objects** (curves/empties) -3. **Link objects to IFC entities** with minimal storage -4. **Color-code by segment type** (LINE=blue, CIRCULARARC=red) -5. **Support real-time updates** via depsgraph handlers - -### Key Files to Create/Modify - -Following Bonsai's architecture with `core/` and `tool/` at package root: - -``` -saikei/ -├── core/ # NEW - Pure Python (NO bpy) -│ ├── __init__.py -│ └── alignment.py # Business logic, math, validation -├── tool/ # NEW - Blender implementations -│ ├── __init__.py -│ └── alignment.py # Blender object creation, linking -└── civil/ # EXISTING - UI layer - └── module/ - └── alignment/ - ├── __init__.py # Registration - ├── operator.py # Operators call core.*, passing tool.* - ├── ui.py # UI panels - ├── prop.py # PropertyGroups - └── data.py # UI data caching -``` - -### Minimal Visualization Implementation - -```python -def visualize_horizontal_alignment(alignment, collection): - """Create Blender visualization from IFC alignment""" - - # Get segments from IFC - horiz = align_api.get_horizontal_layout(alignment) - segments = align_api.get_layout_segments(horiz) - - objects = [] - for i, segment in enumerate(segments): - params = segment.DesignParameters - - if params.PredefinedType == "LINE": - obj = create_line_curve(params, name=f"Tangent_{i}") - set_material_color(obj, BLUE) - elif params.PredefinedType == "CIRCULARARC": - obj = create_arc_curve(params, name=f"Curve_{i}") - set_material_color(obj, RED) - - # Link to IFC - obj["ifc_definition_id"] = segment.id() - obj["ifc_class"] = segment.is_a() - obj["GlobalId"] = segment.GlobalId - - collection.objects.link(obj) - objects.append(obj) - - return objects -``` - ---- - -## Development Guidelines - -### Code Style -- Follow PEP 8 -- Type annotations for all public functions -- Docstrings with examples -- No `bpy` imports in `core/` modules - -### Testing -- Unit tests for all core logic (outside Blender) -- Integration tests with sample IFC files -- Validation against buildingSMART checker - -### Commit Messages -``` -feat(alignment): Add horizontal alignment visualization - -- Create AlignmentVisualizer class for Blender curve generation -- Support LINE and CIRCULARARC segment types -- Implement IFC entity linking pattern -- Add color coding by segment type - -Refs: #123 -``` - ---- - -## Resources - -### Documentation -- IFC 4.3 Specification: https://ifc43-docs.standards.buildingsmart.org/ -- IfcOpenShell Docs: https://docs.ifcopenshell.org/ -- Bonsai Wiki: https://wiki.osarch.org/ - -### Community -- OSArch Forum: https://community.osarch.org/ -- IfcOpenShell GitHub: https://github.com/IfcOpenShell/IfcOpenShell -- buildingSMART Forums: https://forums.buildingsmart.org/ - -### Key Contacts -- **Rick Brice** (WSDOT) - IfcOpenShell alignment API author -- **Dion Moult** - Bonsai BIM founder -- **Will Sharp** (HDR) - buildingSMART committee co-chair - ---- - -## Quick Reference - -### Entity Creation Pattern -```python -# Always create IFC first, then Blender, then link -entity = ifc.create_entity("IfcAlignmentSegment", ...) -obj = bpy.data.objects.new("Segment", curve_data) -obj["ifc_definition_id"] = entity.id() -``` - -### Segment Types -- `LINE` → IfcLine (blue visualization) -- `CIRCULARARC` → IfcCircle (red visualization) -- `CLOTHOID` → IfcClothoid (future) -- `CONSTANTGRADIENT` → IfcLine (vertical) -- `PARABOLICARC` → IfcPolynomialCurve (vertical) - -### Required Terminal Segment -```python -# Last segment MUST be zero-length -align_api.add_zero_length_segment(layout) -``` - -### Minimal Object Storage -```python -# ONLY these 3 properties in Blender -obj["ifc_definition_id"] = entity.id() -obj["ifc_class"] = entity.is_a() -obj["GlobalId"] = entity.GlobalId -``` - ---- - -*Document Version: 1.1* -*Updated: January 2026* -*Changes: Updated architecture to match Bonsai's actual pattern (core/ and tool/ at package root)* -*For: Saikei Civil IfcOpenShell PR - Horizontal Alignment Visualization*