Skip to content

Repository files navigation

Plasdecode — Plasticity curves → Blender

Reads a .plasticity file, decodes only the curve objects (lines, arcs, circles, ellipses, NURBS) with their exact control points, weights and knots, and writes them into a .blend file (plus a JSON dump and a preview image).

preview

Quick start (macOS)

You need Plasticity and Blender installed in /Applications, and a Python 3.10+ (python.org, Homebrew, or Blender's own Python is used automatically).

  1. Download / clone this repo (Code → Download ZIP, unzip anywhere).

  2. Double-click Make Droplet.command once. It builds Plasticity2Blend.app next to it. (If macOS says the file can't be opened: right-click → Open, or run chmod +x *.command in Terminal.)

  3. Drag one or more .plasticity files onto Plasticity2Blend.app. A Terminal window shows progress; next to each input you get

    <name>.curves.blend   Blender file, one curve object per Plasticity curve
    <name>.curves.json    control points / weights / knots of every edge
    <name>.curves.png     orthographic front view for a quick check
    

    The first run creates a .venv folder and installs parasolid-kit (needs internet once).

Double-clicking Plasticity2Blend.command itself opens a file chooser instead (Finder cannot drop files onto a .command, hence the droplet app).

Command line

python3 plasticity2blend.py "sakina tilk.plasticity" out.blend
python3 plasticity2blend.py "sakina tilk.plasticity" --json curves.json     # geometry only, no Blender
python3 plasticity2blend.py in.plasticity out.blend --preview check.png     # + orthographic render
python3 plasticity2blend.py in.plasticity out.blend --all-nurbs --scale 1000
./Plasticity2Blend.command a.plasticity b.plasticity                        # same as dropping

Requirements

  • Python 3.10+ and pip install -r requirements.txt (only parasolid-kit)
  • Plasticity installed (its app bundle contains the Parasolid schema catalogs the parser needs; override with --schema-dir / $PLASDECODE_SCHEMA_DIR)
  • Blender 4.x/5.x for .blend output (found automatically in /Applications, $BLENDER, or --blender PATH)

Windows/Linux: the Python CLI works the same; only the .command launcher and the droplet are macOS-specific. Point --schema-dir at Plasticity's resources/app/.webpack/main/parasolid-schema folder.

Options

flag meaning
--json PATH write decoded geometry (raw Parasolid data and Bezier pieces) as JSON
--all-nurbs store every spline as NURBS with weights instead of Bezier splines
--scale S multiply coordinates (data is in meters; 1000 gives millimeters)
--collection NAME Blender collection to put the objects in
--bevel D bevel depth for the curve objects (0 = wire only)
--preview PNG render a front orthographic view for a visual check

Each Blender object is named like the Plasticity outliner entry and carries custom properties plasticity_item (index in the file) and plasticity_stable_id.


How a .plasticity file stores curves

1. Container

.plasticity is a small glTF-style binary container (little-endian):

offset size content
0 10 magic plasticity
10 4 uint32 container version (1)
14 4 uint32 total file length
18 4 uint32 JSON chunk length n
22 4 JSON
26 n JSON document
26+n 4 uint32 BIN chunk length m
30+n 4 BIN\0
34+n m binary buffer 0

The JSON (asset.version 2.5 for Plasticity 25.3) contains:

  • nodes[] — outliner entries {"item": i, "name": "Bridge curve.001"} (also {"group": g}, {"measurement": m}), which give items their names;
  • items[] — one per solid/sheet/curve: {"bufferView": k, "stableId": id, "lods": [{"mesh": j}]}. Curve items have no lods (solids and sheets carry tessellated display meshes there); this is how curves are told apart;
  • bufferViews[] — {"buffer": 0, "byteOffset": o, "byteLength": l} slices of the binary buffer;
  • meshes[] etc. describe the display tessellation and are ignored here.

2. Each item is a Parasolid X_B part file

Every item's bufferView is a complete Parasolid binary transmit file ("X_B", signature PS, header TRANSMIT FILE created by modeller version 3800198, schema key e.g. SCH_3800198_37102_13006). Plasticity uses the Parasolid kernel, so this is the native B-Rep, not an export.

The X_B node stream is schema-driven; to read it one needs the schema catalog named in the header. Plasticity ships them:

/Applications/Plasticity.app/Contents/Resources/app/.webpack/main/parasolid-schema/sch_13006.sch_txt

We parse the stream with parasolid-kit (read_brep(blob, schema_dir=...)), which resolves the schema and maps the nodes to a typed B-Rep model.

3. Curve items are wire bodies

A curve object is a Parasolid wire body: BODY → REGION → SHELL → EDGEs, each edge with two VERTEX nodes (each holding a POINT) and a geometric curve node:

Parasolid node data
LINE point, unit direction (unbounded)
CIRCLE center, normal, x_axis, radius (full circle)
ELLIPSE center, normal, x_axis, major/minor radius
NURBS_CURVE + BSPLINE_VERTICES + KNOT_SET + KNOT_MULT degree, periodic/closed flags, control vertices (homogeneous wx wy wz w when rational), distinct knots + multiplicities
SP_CURVE a 2-D NURBS curve in the parameter space of a surface (used e.g. by Offset curve)

Important details when reconstructing an edge:

  • Curves are unbounded/full; the edge's extent comes from its two vertex points. For lines the piece is simply start→end. For circles the angles of the vertex points are measured from x_axis towards normal × x_axis. For NURBS the vertex points are inverted to parameters (closest point) and the portion is cut out exactly by knot insertion.
  • Every curve node has a sense (+/-). - means the edge runs from its start vertex to its end vertex against the curve's parametric direction.
  • An edge with no vertices (or identical vertices) is a closed loop (full circle, whole periodic NURBS).
  • Periodic NURBS (periodic = true, e.g. Plasticity's Circle.002/003, which are actually degree-3 B-spline approximations of circles) carry wrapped control points and an extended knot vector; the parametric domain is [knots[degree], knots[n]] and a trimmed portion may wrap through the seam.
  • Coordinates are in meters even though Plasticity's UI shows mm.
  • An SP_CURVE on an offset surface (an offset of a B-spline surface) has no exact NURBS form; the tool samples it into a polyline and reports a warning.

4. What the JSON dump contains

For every curve item: name, item, stable_id, closed_loop, and per edge

  • kind, sense, start, end, closed
  • geometry — the raw Parasolid definition (line point/direction; circle center/normal/x_axis/radius and the arc angles; NURBS degree, control points, weights, full knot vector, periodic flag, and the edge's parameter interval)
  • bezier — the edge as exact rational Bezier segments in chain order: {"degree": d, "segments": [{"points": [[x,y,z]...], "weights": [w...]}]}. Circle/ellipse arcs become quadratic rational segments (≤ 90° each, middle weight cos(θ/2)), NURBS become segments of their own degree, lines are degree 1.

This Bezier form is what any downstream tool needs to reproduce the curve exactly: points + weights per segment, no knot vectors required.

5. Blender mapping

piece Blender spline
lines / polylines POLY
non-rational degree 2/3 BEZIER (quadratics degree-elevated to cubic; handles = control points)
rational (arcs, circles) or --all-nurbs NURBS, order = degree+1, Bezier + Endpoint knot mode, weights in point.co.w
degree ≥ 4 one single-span NURBS spline (Endpoint mode) per segment
sampled SP curves POLY

Blender's legacy curves expose no custom knot vector, but its Bezier knot mode generates exactly the piecewise-Bezier knot vector (verified for orders 3 and 4 to ~1e-7), so a run of segments of equal degree fits in one NURBS spline with no loss.

Files

plasticity2blend.py        CLI entry point
plasdecode/container.py    .plasticity container reader
plasdecode/decode.py       Parasolid wire bodies -> exact Bezier pieces (+JSON)
plasdecode/nurbs.py        knot insertion, Bezier extraction, point inversion, arcs
plasdecode/blender_import.py  runs inside Blender, builds splines, saves .blend
plasdecode/cli.py          argument handling and Blender subprocess

About

Decode the curve objects of Plasticity (.plasticity) files into Blender with exact control points and weights

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages