cadquery
cadquery copied to clipboard
Creating and exporting multiple objects in one 3MF file
Hello together,
I have a question about exporting multiple objects in a stl file. What i want is, when I import the exported stl-file into the Cura software, the objects should be listed individually, and when I slice it, each object should be finished one at a time, instead of adding a layer to all objects in the same iteration in the print.
my current snippet for creating simple cylinder objects
workplanes = []
for point in self.__create_array_points(cylinder_radius * 2, distance, quantity):
workplane = Workplane()
workplane.pushPoints([point]).cylinder(cylinder_height, cylinder_radius)
workplanes.append(workplane)
# what i want
exporters.export(workplanes, "test.stl")
The following issue may address the same problem https://github.com/CadQuery/cadquery/issues/212, but I was not able to achieve the result I wanted due to my lack of knowledge.
Multiple objects can be exported in one STL, but AFAIK STL does not convey topology information. Maybe try 3MF? And what is your question actually?
Sorry if I did not make myself clear. So my current code to generate multiple objects can be seen in the following snippet:
def _cylinder_set(
self,
cylinder_height: float,
cylinder_radius: float,
quantity: int,
distance: int = 1,
) -> Workplane:
return self.workplane.pushPoints(
self.__create_array_points(cylinder_radius * 2, distance, quantity)
).cylinder(cylinder_height, cylinder_radius)
This snippet results in the following STL when I create 5 cylinders and is shown in the next screenshot.
You can see in the screenshot that all 5 cylinders are counted as one object, so the five cylinders get one layer each iteration.
What I really want to do can be seen in the next screenshot, where two cylinders are listed individually in the object list and are printed one after the other. So the printer finishes one cylinder before moving the head to the next cylinder position.
So I want to export an STL file from Cadquery that handles the objects individually, as in the previous screenshot.
I hope I have been able to make my problem more understandable with the information I have provided
Long story short, use 3mf instead of stl.
It is not clear that stl officially supports multiple solids (see http://www.fabbers.com/tech/STL_Format ).
Thanks for the hint!
Still gives me the problem of how I export the individual cylinders in one file (3mf)
The following snippet is not providing the solution I want. Is still one object in Cura.
workplanes = []
for point in self.__create_array_points(cylinder_radius * 2, distance, quantity):
workplane = Workplane()
workplane = workplane.pushPoints([point]).cylinder(cylinder_height, cylinder_radius)
workplanes.append(workplane.val())
exporters.export(Compound.makeCompound(workplanes), "test.3mf")
I am not sure if the solution is to export multiple compound objects in a 3mf file? But the exporter API does not provide a function to achieve this.
@tobias-mierzwa could you check if #1351 behaves as you expect?
@tobias-mierzwa could you check if #1351 behaves as you expect?
Unfortunately not. I am very happy to provide more information or files if it helps. But if the use case is too specific, we can also close the issue for now.
edit 1: Adding Script for creating and exporting multiple objects Env:
- Python 3.10
- cadquery included the fix from https://github.com/CadQuery/cadquery/pull/1351
- cadquery 2.2.0
- cadquery-ocp 7.7.0
from math import floor
from typing import List
from cadquery import Vector, Workplane, exporters, Compound
def __create_array_points(width: float, distance: int, quantity: int, xRow: int = 6) -> List[Vector]:
yColumn = floor(quantity / xRow)
yReminder = quantity % xRow
lpoints = [] # coordinates relative to bottom left point
for x in range(xRow):
for y in range(yColumn):
lpoints.append(Vector((width + distance) * x, (width + distance) * y))
# reminder extra row
for x in range(yReminder):
for y in range(yColumn + 1):
lpoints.append(Vector((width + distance) * x, (width + distance) * y))
return lpoints
distance: int = 1
cylinder_radius: float = 3.0
cylinder_height: float = 3.0
quantity: int = 3
workplanes = []
for point in __create_array_points(cylinder_radius*2, distance, quantity):
workplane = Workplane()
workplane = workplane.pushPoints([point]).cylinder(cylinder_height, cylinder_radius)
workplanes.append(workplane.val())
exporters.export(Compound.makeCompound(workplanes), "test.3mf")
exit()
Could you check with Cura devs how the 3mf file needs to be structured to achieve what you want?