[OpenSCAD] design processes (was Re: Extending OpenSCAD from assembler to C or Perlish language and adding standard library)

Jordan Brown openscad at jordan.maileater.net
Wed Oct 2 20:03:10 EDT 2019

Changed the subject, since this has drifted way off the original topic.

On 10/2/2019 12:40 AM, Robin2 wrote:
> JordanBrown wrote
>> In your user interface, how would you do this?
>> cylinder(h=10);
>> translate([0,0,10]) {
>>     rotate([0,90,0]) cylinder(h=10,center=true);
>>     rotate([90,0,0]) cylinder(h=10,center=true);
>> }
> The end product will be essentially the same but rather than remembering the
> syntax for (say) rotate() the user just CLICKS to select a ROTATE and
> provides the numbers 0, 90, 0 and the then CLICKS to select the object (the
> cylinder) it is to be applied to. 

So for the translate (which affects both cylinders), you'd select a
range and then say "translate"?

> All the text for the code then gets written by the Python program without
> any typos. 

What I'm wondering about - and maybe I'm just not imaginative enough -
is how I would apply this methodology to anything that I'd actually do. 
Mostly, I consider it wrong if I ever put a number into the dimensions
of an object, or a non-zero number into the argument to translate.  I
would never actually use the example above, because the *intent* is that
the cylinders are all the same size and the rotated cylinders are
translated to the top of the vertical cylinder, and using numbers
doesn't convey that intent.  If I wanted to make it be 20 units tall,
I'd have to go change four instances of "10".  That's not too hard, but
in real life often the values are fractions or multiples of each other,
or are sums of various components.  My second example is how I'd really
create this figure, so that changing one parameter in one place creates
the new version of the object.

If I wanted to just draw boxes and spheres and place them in space, I'd
use Sketchup.

> Yours is a useful example of something I have noticed with Openscad.
> Developing a model involves a lot of re-tracing of steps. 
> For example, I create a cylinder.  
>      Then I say "oops, I need to go back and rotate the cylinder". 
>             Then "I now need to go back and translate the rotated cylinder". 
> Maybe your mind is capable of envisaging the entire process and writing it
> directly from top to bottom, but mine certainly is not.

Indeed, the design process is often (but not always) "inside out".  I
start with a primitive component, then position it with respect to other
primitive components to form a subassembly, then position that
subassembly with respect to others to form a larger subassembly, and so
on.  Perhaps that would be more obvious if expressed in a reverse Polish
notation, e.g.

    cylinder(h=10) rotate([0,90,0]) translate([0,0,10]);

But I don't think so.

Sometimes I'll design more top-down.  Sometimes I'll say "I know I need
a thing <here>, applying an appropriate translation between a convenient
point on the intended "child" object and a convenient point on the
"parent" object, and I need it oriented <this> way, applying a rotation
from the convenient axis for designing the child to the orientation
needed in the parent, and then start designing the child.  Depending on
the context, the child might then be split out into a separate module,
or as a child of the parent.

For instance:


    module door() {
        h = 78;
        w = 36;
        t = 1.5;
        handle_h = 30;
        handle_inset = 3;
        cube([w, t, h]);
        translate([w-handle_inset, 0, handle_h])
        translate([w-handle_inset, t, handle_h])

    module handle() {
        shaft_h = 2;
        cylinder(h=shaft_h, d=1);


Here's the process I used:

  * I want to make a door.  ("module door() {}")
  * The door is a rectangle with certain dimensions ("h=... w=... t=...
  * And let's actually render something.  ("door();")
  * I need a handle on the front side.  I'll design a handle so that the
    base of the handle is at [0,0,0] and it extends up into +Z, so that
    means that it needs to be translated up to the right place
    ("handle_h = ... handle_inset = ... translate(...)" and rotated into
    the right orientation ("rotate(...)").
  * But I don't want to design the handle now, because I'm going to want
    to design it once and place it twice.  ("handle( )")
  * Let's design the handle.  ("module handle() {  }")
  * The only tricky part is the relationship between the cylinder and
    the sphere.  Let's measure from the face of the door to the center
    of the sphere.  (contents of the module)
  * OK, that's a handle on the front.  Now for a handle on the back.  It
    needs to be translated to the same place, but on the other side
    ("translate([..., t, ...])"),
  * The back handle needs to be pointed the other direction. 

More likely, I'd make the handle be a child of the door module, so that
I could have doors with different kinds of handles.  A fully-fleshed out
example would have more complex rules for the handle, to allow for
asymmetric handles and positioning them on the left and right sides of
the door.

OK, in some ways that's wildly more complex than a "place boxes and
spheres in space" model.  But when I realize that doors are actually 2"
thick rather than 1.5" thick, I change one parameter and it all still works.

FreeCAD claims to have this kind of parameterization, but so far (in
maybe a half hour of playing with it) it's defeated me.  I can't even
figure out how to make two spheres that will stay next to each other. 
In OpenSCAD that's:

    r1 = 5;
    r2 = 10;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscad.org/pipermail/discuss_lists.openscad.org/attachments/20191003/44838384/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hlgpgglddmbkkgnd.png
Type: image/png
Size: 13483 bytes
Desc: not available
URL: <http://lists.openscad.org/pipermail/discuss_lists.openscad.org/attachments/20191003/44838384/attachment.png>

More information about the Discuss mailing list