cadquery icon indicating copy to clipboard operation
cadquery copied to clipboard

Creating and exporting multiple objects in one 3MF file

Open tobias-mierzwa opened this issue 2 years ago • 7 comments
trafficstars

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.

tobias-mierzwa avatar Jun 12 '23 09:06 tobias-mierzwa

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?

adam-urbanczyk avatar Jun 12 '23 17:06 adam-urbanczyk

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.

Screenshot_1

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.

Screenshot_2

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

tobias-mierzwa avatar Jun 13 '23 05:06 tobias-mierzwa

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 ).

adam-urbanczyk avatar Jun 13 '23 06:06 adam-urbanczyk

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")

Screenshot_3

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 avatar Jun 13 '23 08:06 tobias-mierzwa

@tobias-mierzwa could you check if #1351 behaves as you expect?

adam-urbanczyk avatar Jun 18 '23 14:06 adam-urbanczyk

@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()

tobias-mierzwa avatar Jun 19 '23 05:06 tobias-mierzwa

Could you check with Cura devs how the 3mf file needs to be structured to achieve what you want?

adam-urbanczyk avatar Jun 20 '23 19:06 adam-urbanczyk