discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Re: packing objects in 2 space

J
jon
Sat, Feb 12, 2022 3:36 PM

Ah.  There is no space between "-D" and the assignment statement.  Not
the way the documentation is written, which is why examples are so powerful.

I have about a dozen cookie() routines, so I need another parameter to
select which routine to invoke.  Then I need the logic to match the
routine parameters to invoke the function calls.  And I then have to
write over 100 near-identical lines of command processor code.  Writing
loops in a Windows batch file is almost as much work as just enumerating
the cases; and with enumerated cases, I can remove some if they turn out
to be unnecessary.  This is a LOT of work compared to having an
intrinsic inside OpenSCAD to just emit the STL file.  I will spend as
much time on this as I have already writing the some 350 lines of
OpenSCAD code.

Jon

On 2/12/2022 10:26 AM, Adrian Mariano wrote:

I do not understand why it will require writing any additional
openscad code.  If you have cookie() and it takes x and y then you can
just invoke it in a loop written from the command line.

I have test36.scad containing:

module cookie(x,y){
linear_extrude(height=1)
text(str(x,y));
}

cookie(x,y);

and my command line is:

openscad -Dx=3 -Dy=4 -otest.stl test36.scad

and I get the expected test.stl file output.  So the only extra work
is to write a script that loops over the necessary x and y.  I don't
know what OS you're using or what scripting language you like.

On Sat, Feb 12, 2022 at 10:10 AM jon jon@jonbondy.com wrote:

Adrian:

You are, of course, correct.  I can emit each STL separately using
command line scripts.  It will take writing a lot of command line code
and a lot more OpenSCAD code, which would be unnecessary with my
hypothetical code, but I guess that's were I'm heading.

I am already getting a lot of errors with my command line attempts.  Are
there any working examples somewhere?

This

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment

has documentation but no working examples.

For example, if I put this in my command line:

-D mod="Spiral"

I get

WARNING: Ignoring unknown variable 'Spiral'

I am trying to assign the string "Spiral" to the variable/constant
"mod".  Do  I have to create the "mod" variable in my program first?  I
have tried it both ways.

I'm sure that once I get this set up, it will work well, but I'm in the
frustrating phase at the moment.

Thanks!

Jon

On 2/12/2022 9:43 AM, Adrian Mariano wrote:

I think you can do something sort of like that with scripting, where
you run OpenSCAD from the command line, pass in parameters with -D to
tell it what to do, and use -o to tell it to save the STL with the
appropriate name.

On Sat, Feb 12, 2022 at 9:23 AM jon jon@jonbondy.com wrote:

Yes, if OpenSCAD had a way to export an STL on command, then I could
emit all of the STLs trivially and then collect them and position them
in PrusaSlicer.

So, if my current code looks (schematically) like

for (x = [1:3])

   for (y = [1:3])

       translate([x*10, y*10, 0])

           cookie(x, y);

new hypothetical code (excuse the poor string syntax) could look like

for (x = [1:3])

   for (y = [1:3])

       export_stl("cookie" + x + "," + y + ".stl")

           cookie(x, y);

I do not believe that OpenSCAD supports this, but I now have a good
personal use case for this kind of feature

Jon

On 2/12/2022 8:37 AM, Adrian Mariano wrote:

So my understanding is that if you create a module and pass your
objects as children, then if that module passes (some of its) children
to a submodule, the children are all unioned into one object.  This
makes it impossible to pass children around in a powerful, flexible
way.  The new experimental lazy union feature may fix this, but I
think it only sometimes skipped the union, so I'm not sure.

Assuming that you can't go that route, then, when you have to do is
work with the bounding boxes to compute object positions.  So you
precompute bounding box info and put it in a list.  Invoke your
recursive 2d layout fnction.  The result is a list of object
positions.  Once you have all the positions, you can then position all
the objects on those positions using a simple loop, though it seems
like you'll need a giant cascading if statement to the object with
index i.  So once you have a position list you can do something like
for(i=[0:N]) translate(pos[i]) object(i) where object() is a module
that produces all the objects based on the index number.  Thiis would
be pretty easy to do if you had a 1d spacing problem but in 2d it
seems like it's going to be tricky.  Like if you want to pursue this,
try to solve the 1d problem first.

My slicer has a button that does this.  If yours doesn't...might
consider switching slicers.

On Fri, Feb 11, 2022 at 10:25 PM jon jon@jonbondy.com wrote:

Adrian:

Thank you!

Imagine I am creating a series of cookies.  Some are of Santa. Some are
of reindeer.  Some are Christmas tree ornaments. So there are three
different cookie generators, one for Santas, one for reindeer, and one
for ornaments.  Each generator creates a series of sizes, so each
generator might create 5 different objects, for a total of 15.

How would I do this?  Create each object in each generator and stuff the
15 into some data structure, and then pass the data structure into the
recursive routine?  The part of your suggestion that has me stuck is the
"it does one object at a time".  They are not all generated from one
piece of code, but from three, and I don't see how to store them for
processing by the recursion.

On 2/11/2022 9:30 PM, Adrian Mariano wrote:

I don't know if it's "nice", but it OpenSCAD the way to do that is
with recursion.  You write a function to generate the positions of all
the objects.  It does one object at a time and the state information
(x, y, which objects are left, and the list of positions determined)
is passed to a recursive call.  When there are no objects left you
return the list of positions.

On Fri, Feb 11, 2022 at 9:23 PM jon jon@jonbondy.com wrote:

I am generating perhaps 100 2D objects with varying sizes and shapes
(they are not all the same width as depth).  I want to place the objects
in a fairly tightly packed array for printing, with perhaps 2 mm between
each object.  I know the 2D bounding box of each item.  In a "regular"
programming language I would have X and Y variables which I incremented
as I added each object.  Is there a nice way to do this in OpenSCAD?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Ah.  There is no space between "-D" and the assignment statement.  Not the way the documentation is written, which is why examples are so powerful. I have about a dozen cookie() routines, so I need another parameter to select which routine to invoke.  Then I need the logic to match the routine parameters to invoke the function calls.  And I then have to write over 100 near-identical lines of command processor code.  Writing loops in a Windows batch file is almost as much work as just enumerating the cases; and with enumerated cases, I can remove some if they turn out to be unnecessary.  This is a LOT of work compared to having an intrinsic inside OpenSCAD to just emit the STL file.  I will spend as much time on this as I have already writing the some 350 lines of OpenSCAD code. Jon On 2/12/2022 10:26 AM, Adrian Mariano wrote: > I do not understand why it will require writing *any* additional > openscad code. If you have cookie() and it takes x and y then you can > just invoke it in a loop written from the command line. > > I have test36.scad containing: > > module cookie(x,y){ > linear_extrude(height=1) > text(str(x,y)); > } > > cookie(x,y); > > and my command line is: > > openscad -Dx=3 -Dy=4 -otest.stl test36.scad > > and I get the expected test.stl file output. So the only extra work > is to write a script that loops over the necessary x and y. I don't > know what OS you're using or what scripting language you like. > > On Sat, Feb 12, 2022 at 10:10 AM jon <jon@jonbondy.com> wrote: >> Adrian: >> >> You are, of course, correct. I can emit each STL separately using >> command line scripts. It will take writing a lot of command line code >> and a lot more OpenSCAD code, which would be unnecessary with my >> hypothetical code, but I guess that's were I'm heading. >> >> I am already getting a lot of errors with my command line attempts. Are >> there any working examples somewhere? >> >> This >> >> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_OpenSCAD_in_a_command_line_environment >> >> has documentation but no working examples. >> >> For example, if I put this in my command line: >> >> -D mod="Spiral" >> >> I get >> >> WARNING: Ignoring unknown variable 'Spiral' >> >> I am trying to assign the string "Spiral" to the variable/constant >> "mod". Do I have to create the "mod" variable in my program first? I >> have tried it both ways. >> >> I'm sure that once I get this set up, it will work well, but I'm in the >> frustrating phase at the moment. >> >> Thanks! >> >> Jon >> >> >> On 2/12/2022 9:43 AM, Adrian Mariano wrote: >>> I think you can do something sort of like that with scripting, where >>> you run OpenSCAD from the command line, pass in parameters with -D to >>> tell it what to do, and use -o to tell it to save the STL with the >>> appropriate name. >>> >>> On Sat, Feb 12, 2022 at 9:23 AM jon <jon@jonbondy.com> wrote: >>>> Yes, if OpenSCAD had a way to export an STL on command, then I could >>>> emit all of the STLs trivially and then collect them and position them >>>> in PrusaSlicer. >>>> >>>> So, if my current code looks (schematically) like >>>> >>>> for (x = [1:3]) >>>> >>>> for (y = [1:3]) >>>> >>>> translate([x*10, y*10, 0]) >>>> >>>> cookie(x, y); >>>> >>>> new hypothetical code (excuse the poor string syntax) could look like >>>> >>>> for (x = [1:3]) >>>> >>>> for (y = [1:3]) >>>> >>>> export_stl("cookie" + x + "," + y + ".stl") >>>> >>>> cookie(x, y); >>>> >>>> I do not believe that OpenSCAD supports this, but I now have a good >>>> personal use case for this kind of feature >>>> >>>> Jon >>>> >>>> >>>> On 2/12/2022 8:37 AM, Adrian Mariano wrote: >>>>> So my understanding is that if you create a module and pass your >>>>> objects as children, then if that module passes (some of its) children >>>>> to a submodule, the children are all unioned into one object. This >>>>> makes it impossible to pass children around in a powerful, flexible >>>>> way. The new experimental lazy union feature may fix this, but I >>>>> think it only *sometimes* skipped the union, so I'm not sure. >>>>> >>>>> Assuming that you can't go that route, then, when you have to do is >>>>> work with the bounding boxes to compute object positions. So you >>>>> precompute bounding box info and put it in a list. Invoke your >>>>> recursive 2d layout fnction. The result is a list of object >>>>> positions. Once you have all the positions, you can then position all >>>>> the objects on those positions using a simple loop, though it seems >>>>> like you'll need a giant cascading if statement to the object with >>>>> index i. So once you have a position list you can do something like >>>>> for(i=[0:N]) translate(pos[i]) object(i) where object() is a module >>>>> that produces all the objects based on the index number. Thiis would >>>>> be pretty easy to do if you had a 1d spacing problem but in 2d it >>>>> seems like it's going to be tricky. Like if you want to pursue this, >>>>> try to solve the 1d problem first. >>>>> >>>>> My slicer has a button that does this. If yours doesn't...might >>>>> consider switching slicers. >>>>> >>>>> On Fri, Feb 11, 2022 at 10:25 PM jon <jon@jonbondy.com> wrote: >>>>>> Adrian: >>>>>> >>>>>> Thank you! >>>>>> >>>>>> Imagine I am creating a series of cookies. Some are of Santa. Some are >>>>>> of reindeer. Some are Christmas tree ornaments. So there are three >>>>>> different cookie generators, one for Santas, one for reindeer, and one >>>>>> for ornaments. Each generator creates a series of sizes, so each >>>>>> generator might create 5 different objects, for a total of 15. >>>>>> >>>>>> How would I do this? Create each object in each generator and stuff the >>>>>> 15 into some data structure, and then pass the data structure into the >>>>>> recursive routine? The part of your suggestion that has me stuck is the >>>>>> "it does one object at a time". They are not all generated from one >>>>>> piece of code, but from three, and I don't see how to store them for >>>>>> processing by the recursion. >>>>>> >>>>>> >>>>>> On 2/11/2022 9:30 PM, Adrian Mariano wrote: >>>>>>> I don't know if it's "nice", but it OpenSCAD the way to do that is >>>>>>> with recursion. You write a function to generate the positions of all >>>>>>> the objects. It does one object at a time and the state information >>>>>>> (x, y, which objects are left, and the list of positions determined) >>>>>>> is passed to a recursive call. When there are no objects left you >>>>>>> return the list of positions. >>>>>>> >>>>>>> On Fri, Feb 11, 2022 at 9:23 PM jon <jon@jonbondy.com> wrote: >>>>>>>> I am generating perhaps 100 2D objects with varying sizes and shapes >>>>>>>> (they are not all the same width as depth). I want to place the objects >>>>>>>> in a fairly tightly packed array for printing, with perhaps 2 mm between >>>>>>>> each object. I know the 2D bounding box of each item. In a "regular" >>>>>>>> programming language I would have X and Y variables which I incremented >>>>>>>> as I added each object. Is there a nice way to do this in OpenSCAD? >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org
JB
Jordan Brown
Sat, Feb 12, 2022 7:32 PM

On 2/12/2022 7:36 AM, jon wrote:

Writing loops in a Windows batch file is almost as much work as just
enumerating the cases [...]

You might try Cygwin or Msys2, to get a UNIX-like environment with a
sort of decent scripting language.

Or I suspect PowerShell is good, but I don't know much about it.

Or maybe do it all in Python.

Note that in the

-D mod="spiral"

if you just do it like that a UNIX-style shell will eat the quotes, and
the quotes need to make it through to OpenSCAD.  In a shell script you
would need something like

-D 'mod="spiral"'
-D mod=\"spiral\"
et cetera

Windows batch files don't do the same quote processing, so don't have
the same issues.  (But it means that the quote processing is erratic and
differs from program to program, which brings in its own issues.)

On 2/12/2022 7:36 AM, jon wrote: > Writing loops in a Windows batch file is almost as much work as just > enumerating the cases [...] You might try Cygwin or Msys2, to get a UNIX-like environment with a sort of decent scripting language. Or I suspect PowerShell is good, but I don't know much about it. Or maybe do it all in Python. Note that in the -D mod="spiral" if you just do it like that a UNIX-style shell will eat the quotes, and the quotes need to make it through to OpenSCAD.  In a shell script you would need something like -D 'mod="spiral"' -D mod=\"spiral\" et cetera Windows batch files don't do the same quote processing, so don't have the same issues.  (But it means that the quote processing is erratic and differs from program to program, which brings in its own issues.)