### AnchorSCAD Workflow Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Illustrates a step-by-step guide to building a 3D model using AnchorSCAD, from creating a basic shape to defining its frame of reference and adding components. ```Python # Step 1: Creating a Basic Shape # Example: Define a cube from anchorscad import Shape, Cube class MyCube(Shape): def __init__(self, size=10): super().__init__() self.add(Cube(size=size)) # Step 2: Naming and Modifying Attributes # Example: Assign a name and color my_cube_instance = MyCube(size=20) my_cube_instance.name = "PrimaryCube" my_cube_instance.color = "red" # Step 3: Defining the Frame of Reference Generates a Maker # Example: Create a Maker for the cube from anchorscad import Maker my_maker = Maker(my_cube_instance) # Step 4: Adding Shapes to the Maker # Example: Add another shape (e.g., a sphere) to the maker from anchorscad import Sphere class MyAssembly(Shape): def __init__(self): super().__init__() self.add(my_maker) self.add(Sphere(radius=5, position=(10, 0, 0))) # To render the model: # from anchorscad import anchorscad_main # anchorscad_main(MyAssembly) ``` -------------------------------- ### Render Box Module Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/InstallingAnchorSCAD.md Renders the default Box example module using anchorscad_main and writes output files (.scad, .stl) to the examples_out directory. This command verifies the core rendering functionality. ```bash python -m anchorscad.core --shape Box --write ``` -------------------------------- ### Browse Generated Files Locally Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/InstallingAnchorSCAD.md Starts a local web server to browse generated files from the runner. The generated files will be in a 'generated' folder in the directory where the command is run. ```bash python -m anchorscad.runner.anchorscad_runner --browse ``` -------------------------------- ### Direct Mesh Viewing Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/InstallingAnchorSCAD.md Tests the direct mesh viewing capability of AnchorSCAD. This requires dependencies like manifold3d and a viewer backend. It opens a window displaying the default Box example. ```bash python -m anchorscad.ad_viewer --module anchorscad --shape Box ``` -------------------------------- ### Windows Installation Steps Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/InstallingAnchorSCAD.md Installs AnchorSCAD on Windows. It involves cloning the repository into the user's home directory, navigating into it, and then installing the package using pip. It also mentions an option for development installation. ```shell cd %USERPROFILE% mkdir git # Don't run if the git directory already exists. cd git REM Either install the core library or the full package - git clone https://github.com/owebeeone/anchorscad-core.git - cd anchorscad-core REM OR OR git clone https://github.com/owebeeone/anchorscad.git cd anchorscad REM Install dependencies defined in pyproject.toml pip install . REM For development including testing tools, use: REM pip install -e ".[dev]" ``` -------------------------------- ### Example Shape Definition with Arguments Source: https://github.com/owebeeone/anchorscad-core/blob/main/README.md Demonstrates how to define a custom shape (SquarePipe) inheriting from CompositeShape and setting example arguments using EXAMPLE_SHAPE_ARGS. This allows for easy creation of default examples for the shape. ```python class SquarePipe(ad.CompositeShape): ... EXAMPLE_SHAPE_ARGS = ad.args((70, 50, 30)) ``` -------------------------------- ### Run Multiple Modules with Runner Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/InstallingAnchorSCAD.md Executes a longer test across multiple modules using the AnchorSCAD runner. Replace `` with the path to your AnchorSCAD models. ```bash python -m anchorscad.runner.anchorscad_runner ``` -------------------------------- ### Install anchorscad-core using pip Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/InstallingAnchorSCAD.md Installs the core AnchorSCAD library from the Python Package Index (PyPI). This is the primary method for obtaining the core functionality. ```shell pip install anchorscad-core ``` -------------------------------- ### Linux Installation Steps Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/InstallingAnchorSCAD.md Installs AnchorSCAD on Debian-based Linux distributions. Includes updating package lists, installing Python, pip, Git, and optionally OpenSCAD and Graphviz. It then clones the repository and installs the package using pip. ```bash sudo apt update # Install prerequisites (OpenSCAD/Graphviz are optional) sudo apt install python3 python3-pip git [openscad] [graphviz] mkdir -p ~/git cd ~/git # Clone the desired repository (core or full) # git clone https://github.com/owebeeone/anchorscad-core.git ; cd anchorscad-core # OR git clone https://github.com/owebeeone/anchorscad.git ; cd anchorscad # Install Python dependencies pip3 install . ``` -------------------------------- ### Simple Shape Composition Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/README.md A basic example demonstrating how to compose shapes in AnchorSCAD to create a box tube. It shows how to define a solid shape, add a hole, and then render the resulting OpenSCAD script. Shapes are named and given a composition mode (solid/hole) and a frame of reference. ```python # A simple composition example of a box tube using AnchorSCAD. import anchorscad as ad # Create a shape that we build upon. maker = ad.Box([20, 20, 40]).solid('box').at('centre') # Add a hole shape. hole = ad.Box([10, 10, 40.001]).hole('hole').at('centre') maker.add_at(hole, 'centre') # Render and print the OpenSCAD file for the shape. print(ad.render(maker).rendered_shape) ``` -------------------------------- ### Physical Output Example (Lazy Union) Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/multi_material.md Illustrates the structure of a physical-only output file using AnchorSCAD's lazy union feature, omitting non-physical elements. ```openscad // Start: lazy_union default_5_box_10(); default_5_sphere_9_cured(); // End: lazy_union ... rest of definitions ``` -------------------------------- ### AnchorSCAD Model Construction Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Demonstrates building a 3D model with a cone and a sphere, including adding holes to the sphere using a loop. It showcases chaining methods for setting properties like color and material, and using the `at()` function for transformations. ```python from anchorscad import Cone, Material, Sphere, Cylinder # Create a Cone shape with height (h), base radius (r_base), # and top radius (r_top) with chaining to set additional # properties and specify the frame of reference graph_maker = Cone(h=20, r_base=10, r_top=5) \ .solid('MyCone') \ .colour('blue') \ .material(Material('PLA')) \ .at("base") # Create a Sphere the name radius as the top radius of the Cone. sphere_maker = Sphere(r=5) \ .solid('MySphere') \ .at('centre') graph_maker.add_at(sphere_maker, 'top') # Place 6 holes on the circumference of MyShpere. cylinder_shape = Cylinder(r=1.2, h=5) n = 6 for i in range(n): graph_maker.add_at( cylinder_shape.hole((hole, i)).at('base'), 'MySphere', 'surface', (i / n * 360, 0)) ``` -------------------------------- ### Shape Naming and Positioning Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/README.md Illustrates the fundamental process of creating a shape, assigning it a name, and positioning it within the AnchorSCAD hierarchy. This involves using a name (string or tuple) and potentially an anchor for orientation and location. ```python # Example of a simple Box shape being named and positioned. # Assuming 'Box' is a defined shape class and 'maker' is an instance of Maker # maker.add(Box().named("myBox").at(anchor_matrix)) ``` -------------------------------- ### Datatree Wraps Dataclass Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Demonstrates how the @datatree decorator extends Python's built-in dataclasses. This example showcases default value functionality, including field injection and factory defaults, using a simple class 'A'. It also shows instance creation and equality comparison. ```python @datatree class A: '''Demonstrates Python dataclasses default value functionality. Even though @datatree is used, this example only uses the base Python @dataclass functionality. ''' v1: int v2: int=2 v3: int=field(default=3) v4: int=field(default_factory=lambda: 7 - 3) # Construct with v1 provided.. A(v1=1) # -> A(v1=1, v2=2, v3=3, v4=4) # Comparison of two different instances with the same value. A(v1=2) == A(v1=2) # -> True ``` -------------------------------- ### View Models with ad_viewer Source: https://github.com/owebeeone/anchorscad-core/blob/main/README.md Demonstrates how to use the `ad_viewer` module to render and view AnchorSCAD models without needing OpenSCAD installed. It utilizes the `manifold3d` library for mesh generation. You can specify modules, shapes, parts, and materials to view. ```bash python -m anchorscad.ad_viewer --module anchorscad --shape Sphere --material default ``` ```bash python -m anchorscad.ad_viewer --module anchorscad_models.cases.rpi.rpi5 --shape RaspberryPi5Case ``` ```bash python -m anchorscad.ad_viewer --help ``` -------------------------------- ### MultiMaterialTest Example in Python Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/multi_material.md A Python class demonstrating multi-material support in AnchorSCAD. It defines a box and a sphere with different materials and priorities, showcasing how AnchorSCAD handles geometric conflicts. ```python import anchorscad as ad @ad.shape @ad.datatree class MultiMaterialTest(ad.CompositeShape): ''' A basic test of multi-material support. Basically a box with a sphere on top. The box and sphere are different materials. ''' xy: float=30 z: float=10 size: tuple=ad.dtfield( doc='The (x,y,z) size of ShapeName', self_default=lambda s: (s.xy, s.xy, s.z)) # A node that builds a box from the size tuple. See: # https://github.com/owebeeone/anchorscad/blob/master/docs/datatrees_docs.md box_node: ad.Node=ad.dtfield(ad.ShapeNode(ad.Box, 'size')) sphere_r: float=ad.dtfield(self_default=lambda s: s.xy/2) shpere_node: ad.Node=ad.dtfield(ad.ShapeNode(ad.Sphere, prefix='sphere_')) EXAMPLE_SHAPE_ARGS=ad.args(xy=20, z=10) EXAMPLE_ANCHORS=( ad.surface_args('sphere', 'top'),) def build(self) -> ad.Maker: box_shape = self.box_node() maker = box_shape.solid('box') \ .material(ad.Material('box', priority=10)) \ .at('face_centre', 'base', post=ad.ROTX_180) maker.add_at( self.shpere_node() .solid('sphere') .material(ad.Material('sphere', priority=9)) .at('top', rh=1.4), 'face_centre', 'top') return maker ``` -------------------------------- ### Python Datatree Override Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/datatrees_docs.md Demonstrates the usage of the 'override' parameter with datatrees for hierarchical value replacement. Shows how to override nested parameters and the potential fragility of this approach. ```python @datatree class O: '''Deep tree of injected fields.''' c_node: Node=dtfield(Node(C, 'a_v1'), init=False, repr=False O() -> O(a_v1=11) O().c_node() -> C(a_v1=11, a_v2=2, a_v4=4, a_v3=3, b_v1=12, b_v2=2, b_v4=4, b_v3=3, computed=4) O( override=override( c_node=dtargs( override=override( b_node=dtargs(v2=909090) )))).c_node().b_node(v2=55555) -> A(v1=12, v2=909090, v3=3, v4=4) ``` -------------------------------- ### Render Parts and Scroller Source: https://github.com/owebeeone/anchorscad-core/blob/main/src/anchorscad/webpage/generated_viewer.html Renders the parts associated with a specific model (shape and example). It displays part items with preview images or text and initializes a scrolling element for part navigation. ```javascript function renderParts(module, shape, example) { var partsNames = Object.keys(example.parts_model_files); var partList = $("#part-list"); partList.remove(); if (partsNames.length == 0) { return; } $(".part-list-container").append("
") partList = $("#part-list"); $(".part-menu-element").remove(); partList.append("
"); partsNames.sort().forEach(partName => { var partData = example.parts_model_files[partName]; const partItem = $("
").addClass("part-menu-element").addClass("align-vertical").click(() => { renderModelDetails(module, shape, example, partData, $(".model-details")); }); if (partData.png_file) { partItem.css("background-image", `url(/${partData.png_file})`); } else { partItem.addClass("text-wrap"); partItem.text(shape.class_name + '\n' + example.example_name + '\n' + partName); } partList.append(partItem); }); partList.append("
"); partList.append("
"); try { scroller = new ScrollingElementBuilder() .setScrollingElement(".part-list-container") .setMenuItemsContainer($("#part-list")) .setMenuItems($(".part-menu-element")) .setChevronElements($("#bcheveron-left"), $("#bcheveron-right")) .setOverscrollElements($("#part-left-elastic"), $("#part-right-elastic"), $("#part-elastic-filler")) .setParams({inertiaAnimationDuration ``` -------------------------------- ### Anchor Definition Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html This snippet demonstrates the definition of an anchor in AnchorSCAD Core. It specifies the shape ('shell'), the anchor function ('face_edge'), its parameters ('front', 1, 0.15), and a post-multiply transformation to translate the anchor along the Z-axis. ```APIDOC 'shell', 'face_edge', 'front', 1, 0.15, post=tranZ(epsilon) ``` -------------------------------- ### Hole Gauge Example - Pydoc Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Presents the pydoc-generated documentation for the `HoleGauge` class, detailing its parameters, their types, and default values. This includes parameters like `hole_rss`, `sep`, `fn`, `epsilon`, `fa`, `h`, `fs`, and `override`, which are crucial for defining and rendering 3D models. ```APIDOC class HoleGauge(anchorscad.core.CompositeShape) | HoleGauge(hole_rss: Tuple[Tuple[float]], sep: float = 5, fn: int = None, epsilon: float = 0.005, fa: float = None, h: float = 5, fs: float = None, override: anchorscad.datatrees.Overrides = None) -> None | | A plate with a matrix of holes of different radii provided in hole_rss. | Args: | hole_rss: Tuple of tuple of hole radii | sep: None: Margin of separation between holes and edges | fn: None: None: fixed number of segments. Overrides fa and fs | epsilon: None: Fudge factor to remove aliasing | fa: None: None: minimum angle (in degrees) of each segment | h: None: Depth of plate | fs: None: None: minimum length of each segment | Other args: | override | ... ``` -------------------------------- ### Generated SCAD Code for SquarePipe Source: https://github.com/owebeeone/anchorscad-core/blob/main/README.md The SCAD code generated by AnchorSCAD for the `SquarePipe` example. It uses `union` and `difference` operations to create the final shape, with `multmatrix` for positioning. ```scad // Start: lazy_union default_5_default_5(); // End: lazy_union // Modules. // 'PartMaterial undef-default - default 5.0' module default_5_default_5() { // 'None : _combine_solids_and_holes' union() { // '_combine_solids_and_holes' difference() { // 'default : _combine_solids_and_holes' union() { // 'outer' multmatrix(m=[[1.0, 0.0, 0.0, -35.0], [0.0, 1.0, 0.0, -25.0], [0.0, 0.0, 1.0, -15.0], [0.0, 0.0, 0.0, 1.0]]) { // 'outer : _combine_solids_and_holes' union() { // 'outer' cube(size=[70.0, 50.0, 30.0]); } } } // 'default' multmatrix(m=[[1.0, 0.0, 0.0, -30.0], [0.0, 1.0, 0.0, -20.0], [0.0, 0.0, 1.0, -15.0005], [0.0, 0.0, 0.0, 1.0]]) { // 'hole : _combine_solids_and_holes' union() { // 'hole' cube(size=[60.0, 40.0, 30.001]); } } } } } // end module default_5_default_5 ``` -------------------------------- ### Class A Help Documentation Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/datatrees_docs.md Provides the help documentation for class A, detailing its constructor signature, default parameters, and the purpose of the class as described in its docstring. ```APIDOC class A(builtins.object) | A(v1: int, v2: int = 2, v3: int = 3, v4: int = , override: anchorscad.datatrees.Overrides = None) -> None | | Demonstrates Python dataclasses default value | functionality. Even though @datatree is used, this | example only uses the base Python @dataclass | functionality. | … ``` -------------------------------- ### AnchorSCAD Main Execution Source: https://github.com/owebeeone/anchorscad-core/blob/main/README.md Provides the standard boilerplate for running AnchorSCAD modules. It includes the `ad.anchorscad_main()` call, which handles rendering, testing, and file generation based on command-line arguments or default settings. ```Python if __name__ == '__main__': ad.anchorscad_main() ``` -------------------------------- ### Get SVG Group Source: https://github.com/owebeeone/anchorscad-core/blob/main/tests/test-data/testConstructionRender.html Retrieves the SVG group element associated with a given path ID. This function is used to target specific SVG elements for manipulation. ```javascript function getSvgGroup(pathId) { return JQ(`#${pathId} > g`); } ``` -------------------------------- ### Evaluate Line Segment Source: https://github.com/owebeeone/anchorscad-core/blob/main/tests/test-data/testConstructionRender.html Calculates a point on a straight line segment based on a parameter 't'. It performs linear interpolation between the start and end points of the segment. ```javascript function evaluateLine(segmentData, t) { const [startPoint, endPoint] = segmentData.points; const x = startPoint[0] + t * (endPoint[0] - startPoint[0]); const y = startPoint[1] + t * (endPoint[1] - startPoint[1]); return [x, y]; } ``` -------------------------------- ### Help for Class A Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Provides the signature and docstring for class 'A', which is decorated with @datatree. It details the constructor parameters, including type hints and default values, and reiterates the class's purpose related to Python dataclass functionality. ```APIDOC class A(builtins.object): '''Demonstrates Python dataclasses default value functionality. Even though @datatree is used, this example only uses the base Python @dataclass functionality. ''' def __init__(v1: int, v2: int = 2, v3: int = 3, v4: int = , override: anchorscad.datatrees.Overrides = None) -> None ''' A(v1: int, v2: int = 2, v3: int = 3, v4: int = , override: anchorscad.datatrees.Overrides = None) -> None Demonstrates Python dataclasses default value functionality. Even though @datatree is used, this example only uses the base Python @dataclass functionality. ''' ``` -------------------------------- ### Handle SVG Line Segments Source: https://github.com/owebeeone/anchorscad-core/blob/main/tests/test-data/testConstructionRender.html Processes data for a simple SVG line segment by adding dots for its start and end points. Assumes segmentData.points contains [startPoint, endPoint]. ```javascript function handleLine(segmentData, svgGroup, segId) { addDots(segmentData.points, svgGroup, segId); } ``` -------------------------------- ### Anchor Usage and GMatrix Output Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Compares the output of using the `at('centre')` method versus a direct `centre()` method, showing that both produce identical GMatrix transformations for positioning. ```python print(ad.Box((10, 20, 30)).at('centre')) print(ad.Box((10, 20, 30)).centre()) ``` -------------------------------- ### Datatree Field Binding and Overriding Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/datatrees_docs.md Shows how to use the `BoundNode` created by datatrees for field binding. This example demonstrates creating an instance of `A` from `Anode` and overriding specific fields during the binding process. ```python Anode().a_node() -> A(v1=55, v2=2, v3=3, v4=4) Anode().a_node(v3=33) -> A(v1=55, v2=2, v3=33, v4=4) ``` -------------------------------- ### AnchorSCAD Core Concepts Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Explains the fundamental components of the AnchorSCAD ecosystem, including anchors, parametric complexity simplification using datatrees, and the module structure for generating models and resources. ```APIDOC Anchors: - Static specifiers evaluated at model build time. - Can reference any part of the model graph. - Extensible by adding annotated functions. Parametric Complexity Simplification: - Uses an extension to Python's dataclasses (datatrees). - Allows injection and binding of parameters. - Simplifies code and improves resilience to parameter changes. Module Structure: - Every AnchorSCAD module is a library and a model generator. - `anchorscad_main()` function renders @shape class objects. - Generates resources: path, datatree field binding documentation, visual model graph. Multi-material Support: - Works around OpenSCAD's lack of multi-material support. - Utilizes OpenSCAD's 'lazy union' feature. - Enables multi-model 3MF files with separate models per material. ``` -------------------------------- ### Datatree Construction and Default Values Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/datatrees_docs.md Demonstrates constructing a dataclass decorated with @datatree and how default values are applied. It also shows the comparison of two instances with identical values. ```python A(v1=1) -> A(v1=1, v2=2, v3=3, v4=4) A(v1=2) == A(v1=2) -> True ``` -------------------------------- ### Custom Anchor Definition Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Defines a custom anchor function 'inner_surface' for a shape class using the @anchor decorator. This example demonstrates flipping the Z direction for an inner surface by rotating the matrix. ```python @anchor('inner surface anchor') def inner_surface(self, *args, **kwds): '''Inner surface anchor with corrected Z points away from surface.''' return self.maker.at('inner', 'surface', *args, **kwds) * ad.ROTX_180 ``` -------------------------------- ### Dataclass with Datatree Decorator Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/datatrees_docs.md Demonstrates the basic usage of the @datatree decorator on a Python dataclass. This example showcases default values and default factories, similar to standard dataclasses, but within the datatree framework. ```python @datatree class A: '''Demonstrates Python dataclasses default value functionality. Even though @datatree is used, this example only uses the base Python @dataclass functionality. ''' v1: int v2: int=2 v3: int=field(default=3) v4: int=field(default_factory=lambda: 7 - 3) ``` -------------------------------- ### Fetch and Render Text File Source: https://github.com/owebeeone/anchorscad-core/blob/main/src/anchorscad/webpage/generated_viewer.html Asynchronously fetches a text file from a given URL and renders its content within a specified container. It can optionally format the content as code. Includes error handling for failed requests. ```javascript function fetchAndRenderTextFile(container, url, title, isCode = false) { $.get("/" + url, function(data) { const textContainer = $("
").addClass("monospace").text(data); if (isCode) { textContainer.addClass("code"); } container.append(`

${title}

`); container.append(textContainer); }).fail(function() { console.error(`Error loading file: ${url}`); container.append(`
Error loading file: ${url}
`); }); } ``` -------------------------------- ### Datatree Field Injection Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/datatrees_docs.md Illustrates how datatrees can inject fields from one dataclass into another. The `Anode` class injects fields from `class A`, demonstrating how to manage default values and control injection behavior. ```python @datatree class Anode: '''Injects fields from class A and provides a default value for A.v1. The a_node field becomes a callable object that provides an instance of A with field values retrieved from self. ''' v1: int=55 a_node: Node=Node(A) # Inject field names from A ``` -------------------------------- ### Creating and Modifying Basic Shapes Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Demonstrates the process of creating a basic shape, naming it, and applying attributes like color. ```python # Creates a box with dimensions 10x20x30. shape = Box([10, 20, 30]) # Names the shape and sets its colour. named_shape = shape.solid("box").colour("red") ``` -------------------------------- ### Initialize and Load Status Data Source: https://github.com/owebeeone/anchorscad-core/blob/main/src/anchorscad/webpage/generated_viewer.html Initializes the application by loading status data from '/status.json' using jQuery's AJAX. It then filters modules with content and renders the errors and modules tabs. ```javascript import * as THREE from 'three'; import { STLLoader } from 'three/addons/loaders/STLLoader.js'; import { ThreeMFLoader } from 'three/addons/loaders/3MFLoader.js'; var runnerStatus = null; $(document).ready(function() { $.getJSON('/status.json', function(data) { runnerStatus = data; const modules_with_content = filterModules(runnerStatus.module_status); renderErrorsTab(modules_with_content); renderModulesTab(modules_with_content); }).fail(function() { console.error('Error loading JSON'); }); }); ``` -------------------------------- ### Get SVG Coordinates Source: https://github.com/owebeeone/anchorscad-core/blob/main/tests/test-data/testConstructionRender.html Converts screen coordinates (from a mouse event) into SVG coordinates, taking into account the SVG element's transformations. This is crucial for accurately determining pointer positions within the SVG canvas. ```javascript function getSVGCoordinates(evt, svg, group) { const point = svg.createSVGPoint(); point.x = evt.clientX; point.y = evt.clientY; const ctm = group.getScreenCTM(); if (ctm === null) { return null; } const svgPoint = point.matrixTransform(ctm.inverse()); return [svgPoint.x, svgPoint.y]; } ``` -------------------------------- ### Injected Fields with Anode Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Demonstrates how class A constructor parameters are injected as fields into the containing class Anode. It shows how name mappings, prefixes, suffixes, and exclusions can be used, and how default parameters are handled. ```python Anode() -> Anode(v1=55, a_node=BoundNode(node=Node(clz_or_func=A, use_defaults=True, suffix='', prefix='', expose_all=True, node_doc=None)), v4=4, v2=2, v3=3) ``` ```python Anode().a_node() -> A(v1=55, v2=2, v3=3, v4=4) ``` ```python Anode().a_node(v3=33) -> A(v1=55, v2=2, v3=33, v4=4) ``` -------------------------------- ### Anode Construction with Injected Fields Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/datatrees_docs.md Illustrates the construction of an `Anode` object, showing how fields from `class A` are injected and how the `a_node` field is transformed into a `BoundNode`. ```python Anode() -> Anode(v1=55, a_node=BoundNode(node=Node(clz_or_func=A, use_defaults=True, suffix='', prefix='', expose_all=True, node_doc=None)), v4=4, v2=2, v3=3) ``` -------------------------------- ### Handle SVG Arc Segments Source: https://github.com/owebeeone/anchorscad-core/blob/main/tests/test-data/testConstructionRender.html Processes data for an SVG arc segment by adding dots for its points and control lines connecting the start, control points, and center. Assumes segmentData.points contains [startPoint, controlPoint1, controlPoint2, centerPoint]. ```javascript function handleArc(segmentData, svgGroup, segId) { addDots(segmentData.points, svgGroup, segId); addControlLine(segmentData.points[0], segmentData.points[2], svgGroup, segId); addControlLine(segmentData.points[1], segmentData.points[2], svgGroup, segId); } ``` -------------------------------- ### AnchorSCAD Instance Functions and Relations Source: https://github.com/owebeeone/anchorscad-core/blob/main/docs/index.html Table detailing instance functions and their relationships between classes in AnchorSCAD. It covers functions for adding modifiers and building model graph nodes. ```apidoc Table 2: Instance Functions and Relations Function | Source Class | Target Class | Description ---|---|---|--- solid(name), hole(name), cage(name), composite(name), intersect(name), hull(name), minkowski(name) | Shape | NamedShape | Allows specifying modifiers (colour, material etc) for the subnodes. build(self) -> Maker | CompositeShape | Maker | Abstract function build() called on instance initialization returns a Maker representing the Shape. add_at(maker, anchor, pre, post) -> self | Maker | Maker | Adds model graph node (Maker) at a specified anchor. ``` -------------------------------- ### Evaluate Arc Segment Source: https://github.com/owebeeone/anchorscad-core/blob/main/tests/test-data/testConstructionRender.html Calculates a point on an elliptical arc segment based on a parameter 't'. It interpolates between start and end points, considering radius, angle, and sweep flags. Dependencies include Math functions for trigonometric operations and square roots. ```javascript function evaluateArc(segmentData, t) { const centerPoint = segmentData.center; const startPoint = segmentData.points[0]; const endPoint = segmentData.points[1]; const radius1 = Math.sqrt( (startPoint[0] - centerPoint[0]) ** 2 + (startPoint[1] - centerPoint[1]) ** 2); const radius2 = Math.sqrt( (endPoint[0] - centerPoint[0]) ** 2 + (endPoint[1] - centerPoint[1]) ** 2); const interpolatedRadius = radius1 + (radius2 - radius1) * t; const initialAngle = Math.atan2( startPoint[1] - centerPoint[1], startPoint[0] - centerPoint[0]); const sweepAngle = segmentData.sweep_flag ? segmentData.sweep_angle : -segmentData.sweep_angle; const finalAngle = sweepAngle * t + initialAngle; const x = centerPoint[0] + interpolatedRadius * Math.cos(finalAngle); const y = centerPoint[1] + interpolatedRadius * Math.sin(finalAngle); return [x, y]; } ``` -------------------------------- ### SquarePipe Composite Shape Example Source: https://github.com/owebeeone/anchorscad-core/blob/main/README.md Defines a SquarePipe shape as a composite shape in AnchorSCAD. It utilizes dataclasses and the `datatree` decorator for parametric design. The `build` method constructs the shape by creating an outer box and a subtracted inner box, ensuring a wall thickness. ```Python import anchorscad as ad EPSILON = 1.0e-3 @ad.shape @ad.datatree # wrapper over dataclasses class SquarePipe(ad.CompositeShape): '''Pipe with box section consisting of an outer box with an inner box hole.''' size: tuple wall_size: float = 5.0 EXAMPLE_SHAPE_ARGS = ad.args((70, 50, 30)) def build(self) -> ad.Maker: maker = ad.Box(self.size).solid('outer').at('centre') # Make the inner box slightly larger to stop tearing # when rendered. inner_size = ( self.size[0] - 2 * self.wall_size, self.size[1] - 2 * self.wall_size, self.size[2] + EPSILON ) maker2 = ad.Box(inner_size).hole('hole').at('centre') maker.add_at(maker2, 'centre') return maker ```