Skip to main content

ANYgeometry

ANYgeometry is the lightweight, deterministic structural-surface geometry kernel shared by ANYmesher, ANYfem, and ANYstructure. It owns neutral geometry, topology, persistent entity references, semantic groups, geometry evaluation, edits, intersections, and geometry serialization. Meshing, finite-element attributes, materials, loads, solver state, project data, and GUIs stay in their owning packages.

The kernel is intentionally focused on engineering plates, beams, panels, cylinders, cones, frames, and shell intersections. It is not a general solid CAD kernel and does not depend on OpenCASCADE, Gmsh, a GUI toolkit, an FE package, or a solver.

Installation

ANYgeometry requires Python 3.11 or newer and NumPy. Install the released package or a sibling checkout directly:

python -m pip install ANYgeometry

For editable development:

python -m pip install -e C:\Github\ANYgeometry

Planar clipping and strict planar qualification use the optional Shapely backend. Install the planar extra for those workflows:

python -m pip install -e "C:\Github\ANYgeometry[planar]"

Quick start

Build topology directly:

from anygeometry import GeometryModel

geometry = GeometryModel()
vertices = geometry.add_points(
    [(0, 0, 0), (4, 0, 0), (4, 3, 0), (0, 3, 0)]
)
face_id = geometry.add_plate(vertices)
face_ref = geometry.entity_ref("face", face_id)  # local compatibility reference
face_handle = geometry.handle("face", face_id)   # model-bound public identity
geometry.add_to_group("deck", [face_ref])

LLM and automation contract

anygeometry.automation is a provider-neutral protocol boundary. An LLM may translate natural language into its bounded JSON/record algebra, but the kernel never parses prompts, executes generated code, accepts arbitrary method names, or imports an LLM/MCP SDK.

from anygeometry.automation import Command, CommandBatch, apply_plan, plan_commands

q = lambda xyz: {"value": xyz, "unit": "m", "frame": "model_local"}
commands = tuple(
    Command(f"p{i}", "create_point", {"position": q(point)})
    for i, point in enumerate(((0, 0, 0), (4, 0, 0), (4, 3, 0), (0, 3, 0)), 1)
) + (
    Command("deck", "create_plate", {"vertices": [f"p{i}.vertex" for i in range(1, 5)]}),
)
batch = CommandBatch(1, "make-deck", geometry.model_id, geometry.revision, commands)
plan = plan_commands(geometry, batch)  # no IDs allocated; no revision/cache change
result = apply_plan(geometry, plan)    # one owner transaction / one ChangeSet
deck_sheet = result.outputs["deck.sheet"][0]

Selectors cover canonical handles and aliases (point→vertex, plate→sheet), groups/tags, ownership and incidence, exact metadata, spatial/range predicates, bounded nearest queries, Boolean composition, deterministic ordering, pagination, and explicit mutation cardinality. Positions and transforms require both units and model_local/world frame. See docs/AUTOMATION_PROTOCOL.md.

Or use a structural generator:

from anygeometry.generators import stiffened_panel

geometry = stiffened_panel(
    4.0,
    3.0,
    longitudinal_spacing=1.0,
    transverse_spacing=2.0,
    semantic_group="deck",
)
deck_faces = geometry.group("deck")
stiffener_edges = geometry.group("longitudinal_stiffeners")

EntityHandle(model_id, kind, id) is the model-bound cross-package identity. The legacy EntityRef(kind, id) remains a compact local compatibility value. IDs are allocated monotonically and are never reused, including after rollback or compatibility undo. Splitting or fragmenting an entity records descendants, updates groups, tags, and structural uses, and lets clients resolve a stale selection explicitly.

Geometry model

  • Vertex, Edge, and Face provide topology with persistent IDs.
  • Public entity stores and records are read-only. Edits go through atomic model methods or a nested GeometryModel.transaction().
  • Model identity, revision, tolerance, units, and coordinate arrays are owner-controlled. Use set_document_settings(...) for revisioned coordinate or tolerance changes; returned arrays cannot be written in place.
  • Part, Sheet, FaceUse, and Coedge persist plate ownership/incidence; Member and MemberEdgeUse persist a physical beam axis across edge splits.
  • Attachment and Junction distinguish declared beam/plate and beam/beam relationships from mere geometric coincidence.
  • Straight, Arc, and lightweight Bezier Spline curves are topology-owned.
  • Plane, Cylinder, Cone, RuledSurface, and explicit or topology-backed Coons patches provide evaluation and local UV coordinates.
  • Groups carry geometric meaning such as shell, deck, bottom, boundaries, longitudinal_stiffeners, and ring_stiffeners.
  • Tags provide lightweight geometry annotations. Materials, sections, thicknesses, loads, supports, and mesh controls must reference geometry from outside this package.

General operations include projection, closest-point queries, transforms, edge/face splitting, trimming, holes, fragmentation, and shell/shell intersection imprinting. Analytical line/plane/cylinder intersections cover common structural cases; a bounded NumPy-only engine qualifies every built-in Straight/Arc/Spline and Plane/Cylinder/Cone/Ruled/Coons operand family. It returns complete point, curve, or trim-aware region components with local parameter evidence and fails closed when a work budget or degeneracy remains unresolved. Planar crossings and axial plane/cylinder cuts become real shared edges immediately. A transverse closed ring through a complete conformal cylinder band is imprinted atomically as exact shared arcs: the plane becomes an inner disk plus an outer annular face, and every cylinder patch is split above and below the ring. Stable face lineage, groups, tags, and exact plane/cylinder surfaces are preserved. FaceIntersection.edges contains the complete ring while the compatible FaceIntersection.edge accessor remains its deterministic first edge.

Topology-changing intersections require caller intent, for example intersect_faces(model, a, b, policy=MutationPolicy.IMPRINT). Query-only calls use fragment=False; KEEP_SEPARATE_PART retains both inputs without imprinting. clip_line_to_face returns every planar material interval and subtracts holes instead of collapsing a concave or holed face to one span.

The qualified closed-ring topology path deliberately requires at least three positive-sweep cylinder patches forming one complete conformal band, a cut strictly inside the cylinder height, and a convex straight-edged plane face without existing holes that fully contains the ring. Oblique cuts, partial or nonconformal bands, and planes needing nested trim classification remain non-mutating intersection-query workflows rather than being approximated with unrelated edges.

Qualified predicates return typed IntersectionResult values that distinguish crossing, touching, overlap, coincidence, disjoint, and unclassified cases. Curved components carry IntersectionCertificate evidence and typed parameter loops/traces; only complete certificates may feed atomic imprinting. An optional IntersectionQualificationPolicy controls bounded work without changing model-owned tolerances. Multi-component curve imprints and qualified full or contained coincident-region CONNECT preserve structural ownership and are idempotent on immediate reapplication. The model-owned TolerancePolicy separates computational, merge, angular, parameter, area, and surface-residual tolerances using local feature extent, so translating a complete model does not change a local classification.

geometry.strict_audit() performs deterministic fail-closed full-model qualification with a spatial broad phase. It checks duplicate/crossing/ overlapping edges, T-junctions, sheet manifoldness, structural member intent, member-face relationships, face overlap, lineage, and unsupported candidates. Curved candidates use the same public predicate engine in full and changed-region audit. Any incomplete certificate or unclassified candidate blocks certification; reports expose subdivision/trace and affected-closure work counters.

Large beam lattices should use GeometryModel.add_members(...), which builds all member chains under one part update and one structural validation. Public remove_member, remove_sheet, remove_part, remove_attachment, and remove_junction methods enforce dependency order and rollback atomically.

Editable feature history and owner editing

GeometryModel.features stores an ordered, suppressible modelling history. Feature inputs use FeatureOutputRef so downstream intent does not depend on the materialized IDs allocated by a later regeneration. EntityHandle is the model-bound identity for mesh and analysis packages; feature executors and local compatibility APIs continue to use compact EntityRef values.

from anygeometry import FeatureOutputRef, GeometryModel

geometry = GeometryModel()
first = geometry.features.append(
    "geometry.point", parameters={"position": [0.0, 0.0, 0.0]}
)
second = geometry.features.append(
    "geometry.point", parameters={"position": [2.0, 0.0, 0.0]}
)
geometry.features.append(
    "geometry.line",
    inputs={
        "start": [FeatureOutputRef(first.feature_id, "point", "vertex")],
        "end": [FeatureOutputRef(second.feature_id, "point", "vertex")],
    },
)
report = geometry.regenerate_features()
assert report.success

The registry is extensible by namespaced feature kind, allowing consumers to add executors without a reverse dependency. Regeneration is atomic, retains replacement lineage, and reserves IDs above the old materialization so a stale EntityRef can never be silently reused for a different output.

Feature executors also declare a FeatureTopologyRole: independently AUTHORED geometry, subordinate COMPOSITE topology, or a MODIFIER that must preserve the earlier owner. feature_entity_owners(geometry) resolves the active topology of composite features through exact replacement lineage. It allows model trees and viewers to present a cylinder, cone, panel, or other generator as one intent-level object without removing the vertices, edges, and faces needed for geometry and meshing. The query never uses coordinates or proximity matching; unknown frozen feature kinds conservatively remain composite.

Flat-face sketches use the built-in geometry.sketch.extrude feature. A SketchDefinition stores named plane-local points, their ordered path, distance/coincidence constraints, and the signed normal extrusion distance. Points are not restricted to the support-face boundary. on_edge and on_vertex constraints follow the oriented support boundary, and regeneration returns stable point/*, profile/edge/*, and extrusion/face/* output keys. The small constraint solver uses minimum-norm corrections and rejects inconsistent dimensions without changing the live geometry.

High-level owner operations include insert_model, copy_entities, linear and circular patterns, mirroring, edge/face reversal, deep clone, and typed measure results. Insertion remaps all topology with fresh IDs, preserves groups, tags, surfaces, holes, and metadata, and deliberately does not weld coincident entities.

AffineTransform provides validated translation, axis-angle rotation, scale, reflection, composition, inverse, and point-array evaluation. In-place translate_entities / rotate_entities preserve model-bound identities; copy_translated / copy_rotated allocate fresh identities. Arbitrary transform lists use pattern_entities, while rectangular_pattern creates a deterministic one-, two-, or three-axis Cartesian array. Rectangular counts are copy steps beyond the unchanged original, so counts (1, 1) produce the other three positions of a 2x2 array. Pattern implementations extract the selected geometry and structural closure once rather than cloning unrelated model data.

Serialization and CLI

Geometry schema 4 is deterministic and checksummed. It preserves model UUID and revision, coordinates/CRS and tolerance policy, allocator high-water marks, support surfaces and optional parameterizations, construction/control ownership, curves/trims, structural ownership and qualified relationships, groups, tags, geometry and structural lineage, extensions, and feature history. Schemas 1–3 migrate conservatively and one-way; malformed current documents fail closed:

from anygeometry import read_geometry, write_geometry

write_geometry("panel.anygeometry.json", geometry)
restored = read_geometry("panel.anygeometry.json")

Certified output additionally requires a clean strict audit:

write_geometry("panel.certified.anygeometry.json", geometry, certified=True)

certified=True is a validation gate, not a persisted certificate. The audit report is an ephemeral result bound to the exact model UUID, revision, and audit policy; schema 4 intentionally stores no reusable certification flag. Consumers that require a qualified handoff must retain or rerun strict_audit() for that exact revision.

JSON and gzip-compressed JSON are supported. Mesh and FEM/project serialization remain outside ANYgeometry.

ANYgeometry 0.4.3 reads schemas 1–4 and writes schema 4. Automation consumers use ANYgeometry>=0.4,<0.5; geometry-only consumers may continue using schema 4 through the public codecs. A 0.2.0 reader intentionally rejects a schema-4 document. Downstream packages should use the public codecs rather than parse schema records. Legacy relationship evidence migrates as UNVERIFIED and never implies exactness or certification.

Trusted importers and local script features that have already materialized topology through GeometryModel operations can bind that exact last-good materialization without mutating detached feature records:

geometry.features.adopt_frozen(
    geometry,
    kind="vendor.script.feature",
    outputs={"face": EntityRef("face", face_id)},
)

adopt_frozen accepts only active IDs in the history's owning model; it never retargets through replacement lineage or geometric proximity. ANYgeometry computes the closure checksum and publishes the history update atomically. Callers that already certified a closure may pass expected_checksum= to make the adoption fail closed if the topology changed.

Feature edits mark the affected record dirty. For additive modelling features, regeneration starts at the earliest dirty record on a clone of the live materialization. The clean prefix keeps its exact entity IDs. A replayed output keeps its prior binding only when its stable output-key set and complete ID-independent topology closure are exactly equal; otherwise its replacement is allocated above the previous ID high-water mark and lineage is extended. This comparison uses no distance, tolerance, or nearest-geometry retargeting.

Ordinary output revalidates complete topological and structural integrity. Certified output adds the full global geometric audit before writing, but the ordinary and certified schema-4 payload shapes are identical. Feature history is owner-observed and validated before writing; direct record tampering is never accepted as a checksummed document.

The package module can create an example or inspect a saved geometry:

python -m anygeometry --version
python -m anygeometry --write-example panel.anygeometry.json
python -m anygeometry panel.anygeometry.json --json

Dependency direction

The intended dependency graph is one-way:

ANYgeometry <- ANYmesher <- ANYfem
      ^             ^
      |             |
ANYstructure -------+

ANYgeometry never imports ANYmesher, ANYfem, ANYstructure, ANYsolver, a GUI, or a finite-element package. See MIGRATION.md when moving code from the historical anymesher.geometry namespace.

Development

python -m pip install -e ".[dev]"
python -m pytest
python -m build
python -m twine check dist\*

The test suite qualifies persistent identity and history, topology, curves, surfaces, generators, operations, serialization, intersections, CLI behavior, and import boundaries.

The strict-kernel design, invariants, benchmark scope, and completed release qualification are recorded in docs/KERNEL_UPDATE_OVERVIEW.md and KERNEL_UPDATE_REPORT.md.

License

Starting with version 0.4.2, ANYgeometry source code is licensed under the Mozilla Public License 2.0. Earlier releases retain the license terms that applied when they were published. Original project documentation is licensed separately as described in docs/LICENSE.md, and third-party components retain their own terms as recorded in THIRD_PARTY_NOTICES.md.

Metadata

Release files for ANYgeometry 0.4.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ANYgeometry 0.4.3
File Size Uploaded
anygeometry-0.4.3.tar.gz 510.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ANYgeometry 0.4.3
File Interpreter ABI Platform
anygeometry-0.4.3-py3-none-any.whl Python 3 none any Details

Total release size: 913.0 kB

Release files / anygeometry-0.4.3.tar.gz

Download URL anygeometry-0.4.3.tar.gz
Size 510.6 kB
Tags Source
SHA-256 checksum
How to use checksums
50a9c789dc3c43ec851ca4c23d9e3956b3bab04d6d485933f8ad68403ea66942
BLAKE2b-256 checksum
How to use checksums
209f03270bb081c77b550f312c14004304d154db5850168d3a6a38598e97b928
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release files / anygeometry-0.4.3-py3-none-any.whl

Download URL anygeometry-0.4.3-py3-none-any.whl
Size 402.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6ab8f398de8ad1cc19b5c0d70a9787e1a15d3f5253c1125134eeb5050ec4b8b5
BLAKE2b-256 checksum
How to use checksums
b52997e1f661121aa24a6a658bb99bcd60debfc22d9449eead4cd2c2551ec098
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.5

2 release files

0.4.4

2 release files

This release

0.4.3 This release

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.2

2 release files

0.2.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page