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. Until the first compatible release is available from PyPI, install the sibling checkout directly:

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])

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 deterministic sampled fallback is available for other supported parametric surface pairs. 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. 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. Any unclassified candidate blocks certification.

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.

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.

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.2.1 reads schemas 1–4 and writes schema 4. The Python API remains within ANYgeometry>=0.2,<0.3, but 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.

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anygeometry-0.2.2.tar.gz (328.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

anygeometry-0.2.2-py3-none-any.whl (274.8 kB view details)

Uploaded Python 3

File details

Details for the file anygeometry-0.2.2.tar.gz.

File metadata

  • Download URL: anygeometry-0.2.2.tar.gz
  • Upload date:
  • Size: 328.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for anygeometry-0.2.2.tar.gz
Algorithm Hash digest
SHA256 f44151ae4ab3f4a360804b4ff5f05b33e3383a279ed779a10d7f70a1820abb4b
MD5 dacbeb2d583a53ff87c6f1a3acdb75f0
BLAKE2b-256 0925aae668c4b69a1250accdf9cacb6b620aab22072c9391cb30305b1ac1d01e

See more details on using hashes here.

File details

Details for the file anygeometry-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: anygeometry-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 274.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for anygeometry-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 19a93072e302b49de2522d7adf0a1dcbcec30f2229c39f1453ade734b7e8a7f7
MD5 fc6df29a9b0e2d5ef759a107a4a2ab22
BLAKE2b-256 b6ae85368853e5148621d56bd555d78b05f46a775744d1d912486ae0ff3d697c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.2.4

2 files

This release

0.2.2 This release

2 files

0.2.1

2 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