Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Escaped OpenSCAD identifiers don't get exposed (because a single _ makes them private) #10

Closed
jreiberkyle opened this issue Mar 11, 2023 · 9 comments

Comments

@jreiberkyle
Copy link

A part of my workflow is to import stls into my openscad project. I couldn't figure out a way to do this in solid2 so I created a new class that extends OpenSCADObject, shown below. Would there be any interest in adding this to solid2 somewhere?

class imported(OpenSCADObject):
    def __init__(self, path, name='Imported', params={}):
        self.path = path
        super().__init__(name=name, params=params)

    def _render(self):
        return f'import("{self.path}");'
@jeff-dh
Copy link
Owner

jeff-dh commented Mar 11, 2023

class import_(OpenSCADObject):

but we just discovered a bug, becaused it's (still) called import_ instead of _import.

I need to think about it -- the renaming -- a little, because the _foobar policy does not work properly in this situation (_foobar -> private class)

@jeff-dh
Copy link
Owner

jeff-dh commented Mar 11, 2023

So, I can't come up with a solution for the naming issue right now. The issue is the following:

OpenSCAD identifiers -- which get imported into SolidPython -- might be illegal python identifiers (keywords like import or they might start with $ or with a digit). The solution implemented when refactoring SolidPython is to prepend a single underscore for each illegal identifier. This turns out to have the issue, that a single underscore defines a private "thing" in python and therefor _import is not exposed.
I don't have a solution for this up until now. If anyone has any idea, let me know. (trailing underscores do not work, because 12ptStar -> 12ptStar_ is still an illegal python identifier)

For now you should use the import_ "command". Note, there's also import_stl and import_dxf. All of those "commands" are part of the builtins and get imported by default when you execute from solid2 import *.

Even though this is not the ideal solution, I guess it makes your proposal obsolete, right?

I would leave this ticket open (and rename it) because of the escape identifier issue.

@jeff-dh jeff-dh changed the title proposal to add support for import() Escaped OpenSCAD identifiers don't get exposed (because a single _ makes them private) Mar 11, 2023
@jeff-dh
Copy link
Owner

jeff-dh commented Mar 11, 2023

In other words, we need a different escaping mechanism or a "python hack" to expose private classes / functions.

Any ideas and suggestions are welcome!

cf.

def escape_openscad_identifier(identifier):

@jreiberkyle
Copy link
Author

import_() works great! For me, this was more of an awareness issue than an issue with the naming convention. From my standpoint, where I'd rather not endure a breaking change update such as _fn becoming something else, I'd be happy with adding import_() (and any functions with similar override-averting name changes) specifically to the docs (aka a summary of how to map from one to the other).

@jreiberkyle
Copy link
Author

For the sake of brainstorming, a more radical idea that came to mind is a function look up table or factory, akaopenscad('import') which returns import_. This is a paradigm shift from how things are implemented and I'm not sure of the usability, but it is an idea!

@jreiberkyle
Copy link
Author

I'd be happy to contribute an example for using import_ if one doesn't exist yet. Let me know where you'd like to see it.

@jeff-dh
Copy link
Owner

jeff-dh commented Mar 13, 2023

Yeah, I'd be happy to merge it. Add an example as 18_xyz.py to the example folder and create a pull request.

I'm wondering what you're actually doing (considering your other ticket). If you manipulate a imported stl with BOSL2 (e.g. attaching stuff to a stl using BOSL2?) I think that would be a really cool example. (Don't know whether it's possible at all....)

@jreiberkyle
Copy link
Author

here's an example of what I'm doing with import:

```python
def traffic_cone():
    cone_file = 'traffic-cone.stl'
    cone_center = [44.5/2, 44.5/2]
    return import_(cone_file).translate([-v for v in cone_center])

No BOSL2 here but it is possible to attach stuff to a stl with BOSL2 just like anything else, you just have to do the work of making it attachable, which requires you know the size / shape of the stl.

Given that we are working in Python and not subject to the OpenSCAD paradigm of not knowing the size of anything, I've begun to fall out of love with attaching objects using the BOSL2 attachable solution, though I absolutely love it for orienting geometries. I still feel like I have a lot to learn in how to enable attachments with non-cube geometries. It is definitely powerful in the OpenSCAD paradigm where modules do not carry any additional information beside the base geometry. However, we have to know the size to make a shape attachable, and once we've made it attachable it's not easy to access the size parameter again. I find myself tempted to add a _size property to OpenSCADObject and do my own math, but I have satisfied myself thus far with sometimes returning a tuple of (OpenSCADObject, size).

Here's an example of that approach:

def bottom_cone_band(hole=False, _fn=FN_VIEW, anchor=aCENTER, spin=0, orient=UP):
    top_height = CONE_HEIGHT - TOP_BAND_SPACING - TOP_BAND_WIDTH - BOTTOM_BAND_SPACING
    obj, size = _cone_band_and_size(BOTTOM_BAND_WIDTH, top_height, hole=hole, _fn=_fn)
    return attachable(anchor, spin, orient, size=size) (obj)

def _cone_band_and_size(width, top_height, _fn):
    shape_width = EXTRUDE_WIDTH+epsilon
    
    base_height = top_height - width
    top_od = CONE_BOTTOM_OD - 2*top_height/tan(CONE_TAPER_ANGLE_RAD)
    bottom_od = CONE_BOTTOM_OD - 2*base_height/tan(CONE_TAPER_ANGLE_RAD)
    obj = tube(h=width, od1=bottom_od+2*epsilon, od2=top_od+2*epsilon, wall=shape_width, _fn=_fn, anchor=aCENTER)
    size = [bottom_od, bottom_od, width]
        
    return obj.up(dz), size

@jeff-dh
Copy link
Owner

jeff-dh commented Mar 20, 2023

I extracted the current essence of this issue into #17 and gonna close this issue.

@jeff-dh jeff-dh closed this as completed Mar 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants