SolidCode / SolidPython

A python frontend for solid modelling that compiles to OpenSCAD
1.1k stars 171 forks source link

Does not appear to handle chained transformations correctly #185

Closed charlieb closed 2 years ago

charlieb commented 2 years ago

When transformations are chained together in the normal openscad way solid only seems to take the outermost.

The two snippets should generate the same object but in the second case all that's generated is a translated sphere.

Consider the results of: sp = s.sphere(r=10)
sp = s.scale([1, 2, 0.5])(sp)
sp = s.rotate([0, 20 + 9, 10])(sp)
sp = s.translate([-4, 0, 8])(sp)

vs

s.translate([-4, 0, 8])(
s.rotate([0, 20 + 9, 10])(
s.scale([1, 2, 0.5])))(
s.sphere(r=10))

jeff-dh commented 2 years ago

Take a closer look at the parenthesis of your second code snippet.

I only reformated it:

s.translate([-4, 0, 8])(
    s.rotate([0, 20 + 9, 10])(
        s.scale([1, 2, 0.5])
    )
)(
    s.sphere(r=10)
)

And that's exactly the code (at least exp)Solid generates:

translate(v = [-4, 0, 8]) {
        rotate(a = [0, 29, 10]) {
                scale(v = [1, 2, 0.5000000000]);
        }
        sphere(r = 10);
}
charlieb commented 2 years ago

Oh I see what I did. I wasn't thinking of it as a tree. I had imagined that calling translate with a rotation argument would result in a callable that performs both operations and that if I called that operation on a sphere it would do both. What it actually does is to build a tree from the translation object with two children that are processed separately.

The code I was looking for was: s.translate([-4, 0, 8])( s.rotate([0, 20 + 9, 10])( s.scale([1, 2, 0.5])( s.sphere(r=10))))

Where every subsequent call creates a single branch from its predecessor.