[OpenSCAD] feature request: resize

Don Bright hugh.m.bright at gmail.com
Wed Aug 10 05:00:59 CEST 2011

I couldn't figure out how it is possible to create a generic 'resize'
function to perform in 'realtime' so that it would be usable in
OpenSCAD's preview (f5) mode. Imagine for example a right-hand-facing
2d pacman of unknown size; Pacman's body is a circle, and his mouth,
on the right, is a triangle, which is subtracted from his body. Say
that you want to resize Pacman to be exactly 10 mm wide, from the
exact edge on the left side of his body, to the tip of his mouth on
the right side. How do you do this?

Step 1. Find out how wide your given pac-man is. Say its 8mm.
Step 2. Find the ratio of desired_width / actual_width, in this case
10mm/8mm or 1.125.
Step 3. Multiply all the x-coordinates of pacman by that ratio.
 circle_center *= 1.125
 circle_radius *= 1.125
 mouth-triangle_points *= 1.125

Step 4: Multiply all the y-coordinates by the same ratio to match (or
not if you wish)

The problem is Step 1. How do you find out how wide your given pacman
is? You have to calculate the right-most point and the left-most point
in the pacman, then subtract the leftmost from the rightmost to find
the actual x size of 8mm. But this size is not the diameter of his
body circle. It is something less, depending on where the mouth
triangle intersects the body circle. To find those intersection
points, it is necessary to use a geometry engine like CGAL.

OpenSCAD's "preview" mode (f5) doesnt do any CSG calculation, it uses
optical trickery of OpenCSG and OpenGL to render CSG operations
without actually calculating the resulting intersection points. Thus,
you cannot find the intersection of Pacman's mouth triangle and
Pacman's body circle in the 'preview' (f5) mode in OpenSCAD, because
no actual CSG operations have been done at that point. That means you
can't find the actual size of Pacman in f5 mode, so you can't do Step
1 of resize() on him in f5 mode. Pacman, of course, is so simple that
perhaps you could do it in f6 mode in realtime and somehow skip the
preview mode thing.

But instead of something simple like pacman, imagine something
complicated like a 3d v-8 internal combustion engine that someone has
sliced down the middle so the insides are visible. Except they left
the pistons and the crankshaft as normal, unsliced, poking out from
the body. To resize such an object, you need to do similar
calculations to pac-man -- find the highest and lowest points in all
three dimensions, subtract to find the 3 sizes, then find the scaling
ratio, then multiply the points by the new ratio. But first you have
to calculate the CSG operations like intersection, difference, union,
etc for the engine block, pistons, piston holes, crankshaft, etc.
Those calculations probably take a long, long time for a CSG geometry
engine like CGAL to calculate on a 3d v-8 engine.

That is why i couldn't figure out how to make a generic resize()
function that would be appropriate for OpenSCAD - which needs to
render reasonably accurate 'previews' in realtime, and which needs
functions that return very accurate numbers in realtime. Because I
don't know how you find the actual size of a complicated group of CSG
objects in realtime. Something tells me it is a difficult problem,
unless you use a different technology entirely, like boundary

I guess there could be a 'hack', like if you popped out of 'preview'
mode the first time someone called 'resize', did all the 'render' of
CSG operations, then cached the result for future 'previews'. But that
doesnt feel right.

Of course I might be 100% wrong about all of these assumptions.


On Tue, Aug 9, 2011 at 1:31 PM, Tony Buser <tbuser at gmail.com> wrote:
> I think you're right, the only difference from your patch being that instead
> of adding it as options to import_stl, it should be a regular function so it
> can be used on anything such as:
> resize([0, 0, 100], autosize=false) import_stl("foo.stl");
> resize([5, 0, 0], autosize=true) my_module();
> And autosize default to true.
> On Tue, Aug 9, 2011 at 2:11 PM, Don Bright <hugh.m.bright at gmail.com> wrote:
>> Here is an example to illustrate my confusion. Say you have a bunny
>> rabbit, of unknown size.
>> In situation 1 you want to import the rabbit as a very tall stretched
>> rabbit, 100 units high, with the x and y left as they are.
>> For situation one, your syntax might be like this: resize=[0,0,100]
>> In situation 2 you want to import it as a rabbit that is exactly 5 in
>> x, but you want y and z to scale automatically to keep the bunny
>> rabbit proportions, not stretch him or shrink him.
>> For situation two, what is your syntax? "resize=[5,0,0]" is already
>> supposed to indicate 'leave y and z' alone. How do you indicate you
>> want it 5 wide, but auto scale y and z?
>> That is the purpose of an 'autosize' option in my patch.
>> DB
>> For situation two, what is your syntax? resize=
>> On Tue, Aug 9, 2011 at 12:24 PM, Tony Buser <tbuser at gmail.com> wrote:
>> > I'm guessing if all numbers are >0 it scales each independently, if 2
>> > axis
>> > are 0 it autosizes, if only 1 is 0 it raises an error?
>> >
>> > On Tue, Aug 9, 2011 at 12:50 PM, Don Bright <hugh.m.bright at gmail.com>
>> > wrote:
>> >>
>> >> On Tue, Aug 9, 2011 at 10:55 AM, Giles Bathgate
>> >> <giles.bathgate at gmail.com> wrote:
>> >> > On 9 August 2011 16:46, Tony Buser <tbuser at gmail.com> wrote:
>> >> >> That's close, but still requires that you know what the dimensions
>> >> >> of
>> >> >> the
>> >> >> stl are ahead of time in order to make the resize scale
>> >> >> proportionally
>> >> >> when
>> >> >> I just want to scale one axis to a specific size.
>> >> >
>> >> > Yeah, so when you supply 0 for any of the vector values, it would
>> >> > leave those axis alone accordingly (since you can't have a primitive
>> >> > of 0 size)
>> >> >
>> >> > resize([10,0,0]) cube([5,2,1]);
>> >> >
>> >> > would do:
>> >> >
>> >> > scale([2,1,1]) cube([5,2,1]);
>> >> >
>> >> > ..and you would get a cube of 10x2x1
>> >> >
>> >> > (There was also the 'autosize=true' flag as suggested by don, but I
>> >> > don't think its necessary.)
>> >> >
>> >> > Regards
>> >> >
>> >> > Giles
>> >>
>> >>
>> >> If you dont have an 'autosize' option, then how do you switch between
>> >> 'autoscaling' mode and 'leave the other dimensions alone' mode?
>> >>
>> >> DB
>> >> _______________________________________________
>> >> OpenSCAD mailing list
>> >> OpenSCAD at rocklinux.org
>> >> http://rocklinux.net/mailman/listinfo/openscad
>> >
>> >
>> > _______________________________________________
>> > OpenSCAD mailing list
>> > OpenSCAD at rocklinux.org
>> > http://rocklinux.net/mailman/listinfo/openscad
>> >
>> >
>> _______________________________________________
>> OpenSCAD mailing list
>> OpenSCAD at rocklinux.org
>> http://rocklinux.net/mailman/listinfo/openscad
> _______________________________________________
> OpenSCAD mailing list
> OpenSCAD at rocklinux.org
> http://rocklinux.net/mailman/listinfo/openscad

More information about the OpenSCAD mailing list