SolidCode / SolidPython

A python frontend for solid modelling that compiles to OpenSCAD
1.12k stars 174 forks source link

Access $preview variable #195

Open occivink opened 2 years ago

occivink commented 2 years ago

Hi,

I would like to access the OpenScad $preview variable (introduced in version 2019.05), so that I can use a lower number of segments during preview. I looked around in the SolidPython code, but as far as I can tell it is not exposed in any way.

Thanks in advance

jeff-dh commented 2 years ago

It is not supported atm.

And the support is not trivial because the value of the $preview variable is unknown at python (SolidPython) runtime (because all the $openScadVariables are only evaluated in OpenSCAD render time, which is after the solid python runtime).

But, we spend some thoughts on how some kind of support for these features could look like.

You could have a look at #178, #181, #180, #183. Those issues point towards the direction on how it could "somehow" be possible to use the $preview variable. I guess it'll all fall back to the scad_inline idea from #178.

jeff-dh commented 2 years ago

Another hint:

There's technically no way to get to something like:

if some_new_feature("$preview"):
    #blablub
else:
   #foobar

The path that could have success would be something like:

sphere(....,segments = scad_inline("$preview ? 8 : 64"))

(which might(!) work more or less out of the box if you grab scad_inline from #178)

etjones commented 2 years ago

@jeff-dh, are all the OpenSCAD variables supported in your fork now? Olivier, I’d like to add support in this fork, but it may be that Jeff’s work already gets you all those features.

On Feb 19, 2022, at 12:02 PM, jeff-dh @.***> wrote:

 Another hint:

There's technically no way to get to something like:

if some_new_feature("$preview"):

blablub

else:

foobar

The path that could have success would be something like:

sphere(....,segments = scad_inline("$preview ? 8 : 64")) (which might(!) work more or less out of the box if you grab scad_inline from #178)

— Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you are subscribed to this thread.

jeff-dh commented 2 years ago

No, but it would be easy to add new ones. Take a look at https://github.com/SolidCode/SolidPython/pull/183/files#diff-f8efb1c60a2f98567dded653dbdd4ea83ddfdb7687d80ebaf9c8aa87b7e9bed8

This is not my fork but the #183 pull request but it is pretty much the same.

So for now merging #183 would be the easiest way to fix this issue.

Btw: I'm playing with the scad_inline idea, it does not work out of the box (there's a minor issue with the scad_inline from #178), but I might(!) come up with a user-space hack which would make the line I posted above possible, maybe tomorrow.

jeff-dh commented 2 years ago
from solid import *

class ConstantOpenSCADObject(IncludedOpenSCADObject):
    def __init__(self, code):
        self._get_include_path = lambda x : ''
        super().__init__("not reander able", {}, "blablub")
        self.include_string = ''
        self.code = " " + code + " "

    def _render(self, render_holes=42):
        return self.code

def scad_inline(code):
    return ConstantOpenSCADObject(code)

s = sphere(10, segments = scad_inline("$preview ? 4 : 16"))

scad_render_to_file(s)

This works (but scad_inline is really a hack).

jeff-dh commented 2 years ago

After thinking about it for a few hours, I think the scad_inline version is more or less the best I can come up with for the $preview variable.

The reason is that we can't evaluate any openscad variable while python runtime and since it only makes sense to use it if you can evaluate it in an if-else statement.......

(This is different with -- for example -- the $t variable, because we can build up arithmetic expressions in a pythonic way with it, but I don't see any reasonable way to build up logical if-else expression in python).

I don't see any way to make further major steps towards a "more pythonic way". If #183 would be merged we could get to:

s = sphere(..., segments = PreviewCondition(4, 16))

but I think that's it.

occivink commented 2 years ago

Thanks for the clarifications. I now see that it is indeed tricky to solve properly due to the late (i.e. after compiling to openscad) evaluation of $preview. I would be happy with the proposed scad_inline solution.

jeff-dh commented 2 years ago

You can copy & paste it into any SolidPython file and use it right away.