Skip to content

Commit

Permalink
Add Assembly YAML aka ASSY (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
openvmp authored Jan 6, 2024
1 parent 7b596d6 commit b9bc51e
Show file tree
Hide file tree
Showing 40 changed files with 610 additions and 419 deletions.
305 changes: 191 additions & 114 deletions README.md

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions examples/assembly_assy/logo.assy
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
links:
- part: bone
package: example_part_cadquery_logo
name: bone1
location: [[0,0,0], [0,0,1], 0]
- part: bone
package: example_part_cadquery_logo
name: bone2
location: [[0,0,-2.5], [0,0,1], -90]
- part: head_half
package: example_part_cadquery_logo
name: head_half_1
location: [[0,0,27.5], [0,0,1], 0]
- part: head_half
package: example_part_cadquery_logo
name: head_half_2
location: [[0,0,25], [0,0,1], -90]
- part: bolt
package: example_part_step
location: [[0,0,7.5], [0,0,1], 0]
Binary file added examples/assembly_assy/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions examples/assembly_assy/logo_embedded.assy
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
links:
- part: bone
package: example_part_cadquery_logo
name: bone1
location: [[0,0,0], [0,0,1], 0]
- part: bone
package: example_part_cadquery_logo
name: bone2
location: [[0,0,-2.5], [0,0,1], -90]
- links:
- part: head_half
package: example_part_cadquery_logo
name: head_half_1
location: [[0,0,2.5], [0,0,1], 0]
- part: head_half
package: example_part_cadquery_logo
name: head_half_2
location: [[0,0,0], [0,0,1], -90]
name: head
location: [[0,0,25], [1,0,0], 0]
- part: bolt
package: example_part_step
location: [[0,0,7.5], [0,0,1], 0]
Binary file added examples/assembly_assy/logo_embedded.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ import:
example_part_cadquery_logo:
type: local
path: ../part_cadquery_logo
example_part_cadquery_primitive:
type: local
path: ../part_cadquery_primitive

assemblies:
primitive:
type: assy
logo:
build:
size: 10.0
run:
angle:
type: float
default: 0.0
type: assy
logo_embedded:
type: assy

render:
png:
prefix: ./
width: 256
height: 256
width: 128
height: 128
markdown: README.md
7 changes: 7 additions & 0 deletions examples/assembly_assy/primitive.assy
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
links:
- package: example_part_cadquery_primitive
part: cube
location: [[0,0,0], [0,0,1], 0]
- package: example_part_cadquery_primitive
part: cylinder
location: [[0,0,5], [0,0,1], 0]
Binary file added examples/assembly_assy/primitive.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed examples/assembly_logo/logo.png
Binary file not shown.
26 changes: 0 additions & 26 deletions examples/assembly_logo/logo.py

This file was deleted.

Binary file removed examples/assembly_primitive/assembly.png
Binary file not shown.
22 changes: 0 additions & 22 deletions examples/assembly_primitive/assembly.py

This file was deleted.

9 changes: 0 additions & 9 deletions examples/assembly_primitive/partcad.yaml

This file was deleted.

Binary file modified examples/part_build123d_primitive/cube.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/part_build123d_primitive/partcad.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ parts:
render:
png:
prefix: ./
width: 256
width: 128
height: 128
markdown: README.md
Binary file modified examples/part_cadquery_logo/bone.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/part_cadquery_logo/head_half.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion examples/part_cadquery_logo/partcad.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ parts:
desc: Plate used as one of the bones on PartCAD logo

render:
png: ./
png:
prefix: ./
width: 128
height: 128
markdown: README.md
Binary file modified examples/part_cadquery_primitive/cube.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/part_cadquery_primitive/cylinder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/part_cadquery_primitive/partcad.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ parts:
render:
png:
prefix: ./
width: 256
width: 128
height: 128
markdown: README.md
Binary file modified examples/part_step/bolt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/part_step/partcad.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ parts:
render:
png:
prefix: ./
width: 256
width: 128
height: 128
markdown: README.md
6 changes: 6 additions & 0 deletions examples/render_all_examples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

for i in part_* assembly_*; do
echo "Rendering $i..."
(cd $i && pc render)
done
6 changes: 4 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
pycairo
build123d==0.2.0
cadquery>=2.3.1
numpy>=1.25.2
scipy>=1.11.1
#tox==4.9.0
pyyaml==6.0.1
cairosvg==2.7.0
pycairo
renderlab
rlPyCairo
svglib
ocp_vscode==2.0.13
GitPython==3.1.40
progress==1.6
Expand Down
41 changes: 30 additions & 11 deletions src/partcad/assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
from . import shape


class AssemblyChild:
def __init__(self, item, name=None, location=None):
self.item = item
self.name = name
self.location = location


class Assembly(shape.Shape):
def __init__(self, name=None, config={}):
super().__init__(name)
Expand All @@ -26,6 +33,10 @@ def __init__(self, name=None, config={}):
)
else:
self.name = name
if "location" in config:
self.location = config["location"]
else:
self.location = None
self.shape = None

# self.children contains all child parts and assemblies
Expand All @@ -36,31 +47,39 @@ def __init__(self, name=None, config={}):

def add(
self,
child: shape.Shape, # pc.Part or pc.Assembly
child_item: shape.Shape, # pc.Part or pc.Assembly
name=None,
loc=b3d.Location((0.0, 0.0, 0.0), (0.0, 0.0, 1.0), 0.0),
):
child_item = copy.copy(child.get_build123d()).locate(loc) # Shallow copy
# child_item.label = name # TODO(clairbee): fix this
self.children.append(child_item)
self.children.append(AssemblyChild(child_item, name, loc))

# Keep part reference counter for bill-of-materials purposes
child.ref_inc()
child_item.ref_inc()

# Destroy the previous object if any
self.shape = None

def ref_inc(self):
for child in self.children:
child.ref_inc()
child.item.ref_inc()

def get_shape(self):
if self.shape is None:
self.shape = b3d.Compound(label=self.name, children=self.children)
return self.shape

def get_build123d(self):
return copy.copy(self.get_shape())
child_shapes = []
for child in self.children:
item = copy.copy(child.item.get_build123d())
if not child.name is None:
item.label = child.name
if not item.location is None:
item.locate(child.location)
child_shapes.append(item)
shape = b3d.Compound(children=child_shapes)
if not self.name is None:
shape.label = self.name
if not self.location is None:
shape.locate(self.location)
self.shape = shape.wrapped
return copy.copy(self.shape)

def get_wrapped(self):
return self.get_shape()
Expand Down
2 changes: 1 addition & 1 deletion src/partcad/assembly_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, ctx, project, assembly_config, extension=""):
raise Exception("ERROR: The project path must be a directory")
self.path = os.path.join(project.path, self.path)
if not os.path.exists(self.path):
raise Exception("ERROR: The part path must exist")
raise Exception("ERROR: The assembly path must exist")

# Pass the autodetected path to the 'Assembly' class
assembly_config["path"] = self.path
Expand Down
75 changes: 75 additions & 0 deletions src/partcad/assembly_factory_assy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#
# OpenVMP, 2023
#
# Author: Roman Kuzmenko
# Created: 2024-01-06
#
# Licensed under Apache License, Version 2.0.
#

import build123d as b3d
import copy
import logging
import os
import yaml

from .assembly import Assembly
from . import assembly_factory as af


class AssemblyFactoryAssy(af.AssemblyFactory):
def __init__(self, ctx, project, assembly_config):
super().__init__(ctx, project, assembly_config, extension=".assy")
# Complement the config object here if necessary
self._create(assembly_config)

self.assy = {}
if os.path.exists(self.path):
try:
self.assy = yaml.safe_load(open(self.path))
except Exception as e:
logging.error("ERROR: Failed to parse the assembly file %s" % self.path)
if self.assy is None:
self.assy = {}
else:
logging.error("ERROR: Assembly file not found: %s" % self.path)

if "links" in self.assy and not self.assy["links"] is None:
self.handle_node_list(self.assembly, self.assy["links"])

self._save()

def handle_node_list(self, assembly, node_list):
for link in node_list:
self.handle_node(assembly, link)

def handle_node(self, assembly, node):
# "name" is an optional parameter for both parts and assemblies
if "name" in node:
name = node["name"]
else:
name = None

# "location" is an optional parameter for both parts and assemblies
if "location" in node:
l = node["location"]
location = b3d.Location(
(l[0][0], l[0][1], l[0][2]), (l[1][0], l[1][1], l[1][2]), l[2]
)
else:
location = b3d.Location((0, 0, 0), (0, 0, 1), 0)

# Check if this node is for an assembly
if "links" in node:
item = Assembly(name, node["links"])
self.handle_node_list(item, node["links"])
else:
# This is a node for a part
if "package" in node:
package_name = node["package"]
else:
package_name = "this"
part_name = node["part"]
item = self.ctx.get_part(part_name, package_name)

assembly.add(item, name, location)
Loading

0 comments on commit b9bc51e

Please sign in to comment.