Skip to main content

CAD-agnostic representation for 2D sketch geometry and constraints

Project description

Morphe

Pronounced "mor-FAY" (from Greek μορφή, meaning "form" or "shape")

Python 3.10+ License: MIT Tests Status: Alpha

A CAD-agnostic 2D sketch geometry and constraint representation with adapter support for FreeCAD, Fusion 360, SolidWorks, and Autodesk Inventor.

Overview

This project provides:

  • morphe: Platform-independent schema for 2D sketch geometry and constraints
  • morphe.adapters.freecad: Adapter for FreeCAD's Sketcher workbench
  • morphe.adapters.fusion: Adapter for Autodesk Fusion 360
  • morphe.adapters.solidworks: Adapter for SolidWorks (Windows only, via COM)
  • morphe.adapters.inventor: Adapter for Autodesk Inventor (Windows only, via COM)

The canonical format enables constrained sketches to be stored, transferred, and manipulated independently of any specific CAD system.

See SPECIFICATION.md for the complete technical specification, including supported geometry types, constraints, JSON schema format, and platform-specific adapter details.

Installation

pip install -e .

Platform-Specific Requirements

Adapter Platform Requirements
FreeCAD Linux, macOS, Windows FreeCAD installed and accessible via PYTHONPATH
Fusion 360 Windows, macOS Run from within Fusion 360's Python environment
SolidWorks Windows only SolidWorks installed, pywin32 package
Inventor Windows only Autodesk Inventor installed, pywin32 package

For Windows COM-based adapters (SolidWorks, Inventor):

pip install pywin32

Quick Start

from morphe import (
    SketchDocument, Point2D, Line, Circle, Horizontal, Radius,
    save_sketch, load_sketch
)

# Create a sketch
sketch = SketchDocument(name="MySketch")
line_id = sketch.add_primitive(Line(start=Point2D(0, 0), end=Point2D(100, 0)))
circle_id = sketch.add_primitive(Circle(center=Point2D(50, 50), radius=20))

sketch.add_constraint(Horizontal(line_id))
sketch.add_constraint(Radius(circle_id, 20))

save_sketch(sketch, "my_sketch.json")

# Load from file
sketch = load_sketch("my_sketch.json")

FreeCAD Integration

from morphe import load_sketch
from morphe.adapters.freecad import FreeCADAdapter

sketch = load_sketch("my_sketch.json")
adapter = FreeCADAdapter()
adapter.create_sketch(sketch.name)
adapter.load_sketch(sketch)

status, dof = adapter.get_solver_status()
print(f"Status: {status.name}, DOF: {dof}")

adapter.close_sketch()

Fusion 360 Integration

The Fusion 360 adapter runs as a script or add-in within Fusion 360:

# Run this inside Fusion 360's Scripts environment
import sys
sys.path.insert(0, r"path/to/morphe-repo")

from morphe import load_sketch
from morphe.adapters.fusion import FusionAdapter

def run(context):
    sketch = load_sketch("my_sketch.json")
    adapter = FusionAdapter()
    adapter.create_sketch(sketch.name)
    adapter.load_sketch(sketch)

    # Export back to canonical format
    exported = adapter.export_sketch()
    print(f"Exported {len(exported.primitives)} primitives")

    status, dof = adapter.get_solver_status()
    print(f"Status: {status.name}, DOF: {dof}")

SolidWorks Integration

The SolidWorks adapter uses COM automation via pywin32 (Windows only):

from morphe import load_sketch
from morphe.adapters.solidworks import SolidWorksAdapter, SOLIDWORKS_AVAILABLE

if SOLIDWORKS_AVAILABLE:
    sketch = load_sketch("my_sketch.json")
    adapter = SolidWorksAdapter()
    adapter.create_sketch(sketch.name)
    adapter.load_sketch(sketch)

    # Export back to canonical format
    exported = adapter.export_sketch()
    print(f"Exported {len(exported.primitives)} primitives")

    status, dof = adapter.get_solver_status()
    print(f"Status: {status.name}, DOF: {dof}")

Notes:

  • Requires SolidWorks to be installed and running (or will launch automatically)
  • The adapter connects to an existing SolidWorks instance or starts a new one
  • Sketches are created on the Front Plane by default (XY plane)
  • Dimensional constraints use geometry recreation to avoid blocking dialogs

Supported Features:

  • All primitive types: Line, Arc, Circle, Point, Spline, Ellipse, EllipticalArc
  • All geometric constraints: Coincident, Tangent, Parallel, Perpendicular, Horizontal, Vertical, Equal, Concentric, Collinear, Midpoint, Fixed, Symmetric
  • All dimensional constraints: Length, Radius, Diameter, Angle, Distance, DistanceX, DistanceY
  • Construction geometry
  • Solver status and DOF reporting

Inventor Integration

The Inventor adapter uses COM automation via pywin32 (Windows only):

from morphe import load_sketch
from morphe.adapters.inventor import InventorAdapter, INVENTOR_AVAILABLE

if INVENTOR_AVAILABLE:
    sketch = load_sketch("my_sketch.json")
    adapter = InventorAdapter()
    adapter.create_sketch(sketch.name)
    adapter.load_sketch(sketch)

    # Export back to canonical format
    exported = adapter.export_sketch()
    print(f"Exported {len(exported.primitives)} primitives")

    status, dof = adapter.get_solver_status()
    print(f"Status: {status.name}, DOF: {dof}")

Notes:

  • Requires Autodesk Inventor to be installed and running (or will launch automatically)
  • The adapter connects to an existing Inventor instance or starts a new one
  • Sketches are created on the XY plane by default

Supported Features:

  • All primitive types: Line, Arc, Circle, Point, Spline, Ellipse, EllipticalArc
  • All geometric constraints: Coincident, Tangent, Parallel, Perpendicular, Horizontal, Vertical, Equal, Concentric, Collinear, Midpoint, Fixed, Symmetric
  • All dimensional constraints: Length, Radius, Diameter, Angle, Distance, DistanceX, DistanceY
  • Construction geometry
  • Solver status and DOF reporting

RPC Server Mode

For GUI tools or external scripts that need to communicate with CAD applications, each adapter provides an RPC server/client pair.

Starting Servers

FreeCAD (run in FreeCAD's Python console):

from morphe.adapters.freecad import start_server
start_server()  # localhost:9876

Fusion 360 (install the MorpheServer add-in from morphe/adapters/fusion/addin/MorpheServer/):

cd morphe/adapters/fusion/addin
python setup_addin.py install

The server starts automatically when Fusion 360 launches (localhost:9879).

SolidWorks (run with SolidWorks open):

from morphe.adapters.solidworks import start_server
start_server()  # localhost:9878

Inventor (run with Inventor open):

from morphe.adapters.inventor import start_server
start_server()  # localhost:9877

Using Clients

All clients share the same interface:

from morphe.adapters.freecad import FreeCADClient
# or: from morphe.adapters.fusion import FusionClient
# or: from morphe.adapters.solidworks import SolidWorksClient
# or: from morphe.adapters.inventor import InventorClient

client = FreeCADClient()
if client.connect():
    # List available sketches
    sketches = client.list_sketches()

    # Export a sketch to canonical format
    sketch = client.export_sketch("Sketch")

    # Import a sketch into the CAD application
    client.import_sketch(my_sketch, name="NewSketch")

    # Get solver status
    status, dof = client.get_solver_status("Sketch")

Running Tests

Core tests (no CAD software required):

pytest tests/                    # All tests
pytest tests/ --cov              # With coverage

FreeCAD adapter tests (requires FreeCAD):

pytest tests/test_freecad_roundtrip.py -v

Fusion 360 adapter tests (run from within Fusion 360):

The Fusion 360 test suite (73 tests) must be run as a script inside Fusion 360:

  1. Open Fusion 360
  2. Go to Utilities > Add-Ins > Scripts
  3. Add and run the test script from morphe/adapters/fusion/script/MorpheTests/

SolidWorks adapter tests (requires SolidWorks on Windows):

pytest tests/test_solidworks_roundtrip.py -v

The SolidWorks test suite includes 80 tests covering:

  • Basic and complex geometry primitives
  • All constraint types including symmetric constraints
  • Solver status detection
  • Precision and edge cases
  • Arc variations and tangent constraints

Inventor adapter tests (requires Inventor on Windows):

pytest tests/test_inventor_roundtrip.py -v

Tests cover all primitives, constraints, solver status, and edge cases.

License

MIT - see LICENSE for details.

Project details


Download files

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

Source Distribution

morphe_sketch-0.1.0.tar.gz (178.4 kB view details)

Uploaded Source

Built Distribution

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

morphe_sketch-0.1.0-py3-none-any.whl (146.1 kB view details)

Uploaded Python 3

File details

Details for the file morphe_sketch-0.1.0.tar.gz.

File metadata

  • Download URL: morphe_sketch-0.1.0.tar.gz
  • Upload date:
  • Size: 178.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for morphe_sketch-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fa31fbc33fef44f9ff42b8cd1f8e8582a8ac04defc5880893a68c02336228e98
MD5 1ac64ab63bdd0814306963add3bed7a7
BLAKE2b-256 6b10461b2a9d4642640677a76219341bad04aa61e5b7ce48ff08e1d77bd3de21

See more details on using hashes here.

Provenance

The following attestation bundles were made for morphe_sketch-0.1.0.tar.gz:

Publisher: publish.yml on CodeReclaimers/morphe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file morphe_sketch-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: morphe_sketch-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 146.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for morphe_sketch-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 05cb2f2e8dd411f61f981278b27cd85631f8614e8c9b8d1f9ecbe56270517264
MD5 ce9f03d8855c3346c6e449d44c7035f8
BLAKE2b-256 4ac7b307fde60bbbb2ba3630f663e5ee66a01d1a164e59e2a379721c34ec4442

See more details on using hashes here.

Provenance

The following attestation bundles were made for morphe_sketch-0.1.0-py3-none-any.whl:

Publisher: publish.yml on CodeReclaimers/morphe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page