Configuration

Packages

The package is described using the configuration file partcad.yaml placed in the package folder. Besides the list of imported dependencies, it declares parts and assemblies.

desc: <(optional) description>
url: <(optional) package or maintainer's url>
poc: <(optional) point of contact, maintainer's email>
partcad: <(optional) required PartCAD version spec string>
pythonVersion: <(optional) python version for sandboxing if applicable>
pythonRequirements: <(python scripts only) the list of dependencies to install>

import:
    <dependency-name>:
        desc: <(optional) textual description>
        type: <(optional) git|tar|local, can be guessed by path or url>
        path: <(local only) relative path to the package>
        url: <(git|tar only) URL of the package>
        relPath: <(git|tar only) relative path within the repository>
        revision: <(git only) the exact revision to import>

parts:
    <part declarations, see below>

assemblies:
    <assembly declarations, see below>

Here are some import examples:

Method

Example

Local files
(in the same
source code
repository)
import:
  other_directory:
    path: ../../other

GIT repository
(HTTPS, SSH)

import:
  other_repo:
      url: https://github.com/openvmp/partcad
      relPath: examples  # where to "cd"

Hosted tar ball
(HTTPS)

import:
  other_archive:
    url: https://github.com/openvmp/partcad/archive/7544a5a1e3d8909c9ecee9e87b30998c05d090ca.tar.gz

Sketches

Sketches are declared in partcad.yaml using the following syntax:

sketches:
  <sketch name>:
    type: <basic|dxf|svg>
    desc: <(optional) textual description>
    path: <(optional) the source file path, "{sketch name}.{ext}" otherwise>
    <... type-specific options ...>

The basic sketches are defined using the following syntax:

sketches:
  <sketch name>:
    type: basic
    desc: <(optional) textual description>
    circle: <(optional) radius>
    circle:  # alternative syntax
      radius: <radius>
      x: <(optional) x offset>
      y: <(optional) y offset>
    square: <(optional) edge size>
    square:  # alternative syntax
      side: <edge size>
      x: <(optional) x offset>
      y: <(optional) y offset>
    rectangle: <(optional)>
      side-x: <x edge size>
      side-y: <y edge size>
      x: <(optional) x offset>
      y: <(optional) y offset>

Interfaces

Interfaces are declared in partcad.yaml using the following syntax:

interfaces:
  <interface name>:
    abstract: <(optional) whether the interface is abstract>
    desc: <(optional) textual description>
    path: <(optional) the source file path, "{interface name}.{ext}" otherwise>
    inherits: # (optional) the list of other interfaces to inherit from
      <parent interface name>: <instance name>
      <other interface name>: # instance name is implied to be empty ("")
      <yet another interface>:
        <instance name>: <OCCT Location object> # e.g. [[0,0,0], [0,0,1], 0]
    ports:  # (optional) the list of ports in addition to the inherited ones
      <port name>: <OCCT Location object> # e.g. [[0,0,0], [0,0,1], 0]
      <other port name>: # [[0,0,0], [0,0,1], 0] is implied
      <another port name>:
        location: <OCCT Location object> # e.g. [[0,0,0], [0,0,1], 0]
        sketch: <(optional) name of the sketch used for visualization>

Abstract interfaces can’t be implemented by parts directly. They also can’t be used for mating with other interfaces.

_images/interface-m3.png

Each port has the coordinates of the logical center of the port and the direction (orientation) of the port. Whenever two ports are meant to connect without any offset or angle (e.g. male and female connectors), their coordinates and directions should match (not inverted directions). The suggested convention is to use the Z-axis (blue) as the main direction. Male ports should have the Z-axis pointing outwards, while female ports should have the Z-axis pointing inwards.

Sometimes there are multiple interchangeable ports within one interface. For example, take a look at the NEMA-17 mounting ports:

_images/interface-orientation.png

It is desired that any mounting port of the motor can be connected to any mounting port of the bracket. That can be achieved by orienting the ports in a circular direction. See how the X-axis (red) is pointing to the next port clockwise (right-hand rule). If any pair of ports is aligned then all three other port pairs are aligned too.

_images/interface-orientation-2.png

See the feature_interfaces example for more information.

Parts

Parts are declared in partcad.yaml using the following syntax:

parts:
  <part name>:
    type: <openscad|cadquery|build123d|ai-openscad|ai-cadquery|ai-build123d|step|stl|3mf>
    desc: <(optional) textual description, also used by AI>
    path: <(optional) the source file path, "{part name}.{ext}" otherwise>
    <... type-specific options ...>
    offset: <OCCT Location object, e.g. "[[0,0,0], [0,0,1], 0]">

    # The below syntax is similar to the one used for interfaces,
    # with the only exception being the word "implements" instead of "inherits".
    implements: # (optional) the list of interfaces to implement
      <interface name>: <instance name>
      <other interface name>: # instance name is implied to be be empty ("")
      <yet another interface>:
        <instance name>: <OCCT Location object> # e.g. [[0,0,0], [0,0,1], 0]
    ports: # (optional) the list of ports in addition to the inherited ones
      <port name>: <OCCT Location object> # e.g. [[0,0,0], [0,0,1], 0]
      <other port name>: # [[0,0,0], [0,0,1], 0] is implied
      <another port name>:
        location: <OCCT Location object> # e.g. [[0,0,0], [0,0,1], 0]
        sketch: <(optional) name of the sketch used for visualization>

Depending on the type of the part, the configuration may have different options:

parts:
  <part name>:
    type: <openscad|cadquery|build123d>
    cwd: <alternative current working directory>
    patch:
      <...regexp substitutions to apply...>
      "patern": "repl"
    pythonRequirements: <(python scripts only) the list of dependencies to install>
    parameters:
      <param name>:
        type: <string|float|int|bool>
        enum: <(optional) list of possible values>
        default: <default value>
parts:
  <part name>:
    type: <ai-openscad|ai-cadquery|ai-build123d>
    provider: <the model provider to use, google|openai>
    tokens: <the limit of token context>
    top_p: <(openai only) the top_p parameter>
    images: <representative images as input for AI>
      - <image path>
parts:
  <part name>:
    type: stl
    binary: <use the binary format>

When the source file (path) is not present but needs to be pulled from a remote location, the following options can be used:

fileFrom: url
fileUrl: <url to pull the file from>
# fileCompressed: <(optional) whether the file needs to be decompressed before use>
# fileMd5Sum: <(optional) the MD5 checksum of the file>
# fileSha1Sum: <(optional) the SHA1 checksum of the file>
# fileSha2Sum: <(optional) the SHA2 checksum of the file>

Here are some examples:

Example

Configuration

Result

AI-generated
CadQuery or
OpenSCAD script
parts:
  cube:
    type: ai-cadquery
    # type: ai-openscad
    desc: A cube
https://github.com/openvmp/partcad/blob/main/examples/produce_part_ai_cadquery/cube.svg?raw=true
build123d script
in src/cylinder.py
parts:
  src/cylinder:
    type: cadquery
    # type: build123d
https://github.com/openvmp/partcad/blob/main/examples/produce_part_cadquery_primitive/cylinder.svg?raw=true
OpenSCAD script
in cube.scad
parts:
  cube:
    type: scad
https://github.com/openvmp/partcad/blob/main/examples/produce_part_openscad/cube.svg?raw=true
CAD file
(STEP in screw.step,
STL in screw.stl,
or 3MF in screw.3mf)
parts:
  screw:
    type: step
    # type: stl
    # type: 3mf
https://github.com/openvmp/partcad/blob/main/examples/produce_part_step/bolt.svg?raw=true

Other methods to define parts are coming soon (e.g. SDF).

It is also possible to declare parts in ways that piggyback on parts that are already defined elsewhere.

Method

Configuration

Description

Alias

parts:
  <alias-name>:
    type: alias
    source: </path/to:existing-part>
Create a shallow
clone of the
existing part.
For example, to
make it easier to
reference it locally.

Enrich

parts:
  <enriched-part-name>:
    type: enrich
    source: </path/to:existing-part>
    with:
      <param1>: <value1>
      <param2>: <value2>
    offset: <OCCT-Location-obj>
Create an opinionated
alternative to the
existing part by
initializing some of
its parameters, and
overriding any of its
properties. For
example, to avoid
passing the same set
of parameters many times.

Assemblies

Assemblies are declared in partcad.yaml using the following syntax:

assemblies:
  <assembly name>:
    type: assy
    path: <(optional) the source file path>
    parameters:  # (optional)
      <param name>:
        type: <string|float|int|bool>
        enum: <(optional) list of possible values>
        default: <default value>
    offset: <OCCT Location object, e.g. "[[0,0,0], [0,0,1], 0]">

Here is an example:

Configuration

Result

# partcad.yaml
assemblies:
 logo:
   type: assy

# logo.assy
links:
- part: /produce_part_cadquery_logo:bone
  location: [[0,0,0], [0,0,1], 0]
- part: /produce_part_cadquery_logo:bone
  location: [[0,0,-2.5], [0,0,1], -90]
- links:
  - part: /produce_part_cadquery_logo:head_half
    name: head_half_1
    location: [[0,0,2.5], [0,0,1], 0]
  - part: /produce_part_cadquery_logo:head_half
    name: head_half_2
    location: [[0,0,0], [0,0,1], -90]
  name: {{name}}_head
  location: [[0,0,25], [1,0,0], 0]
- part: /produce_part_step:bolt
  location: [[0,0,7.5], [0,0,1], 0]
https://github.com/openvmp/partcad/blob/main/examples/produce_assembly_assy/logo.svg?raw=true

Other methods to define assemblies are coming soon (e.g. using CadQuery or build123d).

It is also possible to declare assemblies in ways that piggyback on assemblies that are already defined elsewhere. Unfortunately, “enrich” is not yet implemented for assemblies.

Method

Configuration

Description

Alias

assemblies:
  <alias-name>:
    type: alias
    source: </path/to:existing-assembly>
Create a shallow
clone of the
existing assembly.
For example, to
make it easier to
reference it locally.