FullControlXYZ / fullcontrol

Python version of FullControl for toolpath design (and more) - the readme below is best source of information
GNU General Public License v3.0
672 stars 78 forks source link

[QUESTION] push/pop ExtrusionGeometry #92

Open aavogt opened 5 months ago

aavogt commented 5 months ago

I use two different extrusion widths. It looks like this will work:

w1 = fc.ExtrusionGeometry(width=0.4, height=0.28, units="mm")
w2 = fc.ExtrusionGeometry(width=0.8, height=0.28, units="mm")
r.append(w2)
r += wide_geom
r.append(w1)
r += narrow_geom

I would rather not have to override w1. The best I can do in my py file is:

class Lambda:
    def __init__(self, f):
        self.f = f
    def gcode(self, state):
        self.f(state)

w2 = fc.ExtrusionGeometry(width=0.8, height=0.28, units="mm")
w1 = None
r.append(Lambda(lambda state: (w1 := state.extrusion_geometry)))
r.append(w2)
r+= wide_geom
r.append(Lambda(lambda state: setattr(state,'extrusion_geometry',w1)))
r+= narrow_geom

The duplicate Lambda, := instead of =, setattr instead of state.extrusion_geometry = w1 make this "improvement" worse than the original problem.

fullcontrol-xyz commented 4 months ago

Can you give a little more info about what you're trying to achieve and what the exact intentions of r, wide_geom, narrow_geom are.

To switch between extrusion geometries, I like your approach of defining w1 and w2. in your design you'd have them like this and it should work well:

steps = []
steps.append(w1) 
steps.extend([various fc.Point objects]) 
steps.append(w2) 
steps.extend([various fc.Point objects]) 
aavogt commented 4 months ago

Yes we have a solution, but it could be better. My intention with w1 isn't to set the line width to 0.4, but rather to set it to whatever the default/previous happens to be. Ideally the code could match my intention, in which case there needs to be a way to refer to the previous or default line width.

In my example, wide_geom = [various fc.Point objects], r corresponds to your steps.

The Lambda option doesn't quite work it needs global and maybe an explicit copy (I don't understand python) so that the last occurrence of w1 actually restores the state instead of setting it to None.

fullcontrol-xyz commented 4 months ago

I somewhat understand what you're trying to do, but my question is why do you want to set it in this manner?

You will have already put the information in the design about the desired extrusion width, so why to refer to that? You must already define the initial extrusion width (the default value is not intended to be used in real designs). Hence all documentation indicates that you should supply initialisation data about extrusion width/height to the gcode transformation function.

If it's to make the design experience more pleasant, would a short function to return the last fc.ExtrusionGeometry object in steps achieve what you want? Or the second last? The following code seems to be the same number of lines as your original code.

E.g. w_temp = get_last_EG_object(steps) steps.append(...) steps.append(...) steps.append(...) steps.append(...) steps.append(w_temp )

aavogt commented 4 months ago

I didn't know the default extrusion geometry couldn't be trusted. Currently I have steps += f(...). To use get_last_EG_object in f, it would have to become f(steps,...) which is acceptable.

fullcontrol-xyz commented 4 months ago

Yeh because someone might use a 1.2 mm nozzle and someone else a 0.15 mm nozzle, even in the same printer. So the extrudate geometry really needs to be defined by the designer.

You could do it without providing steps if you want, if the function refers to the global steps variable. That would allow the most concise design code, but would constrain the designer a little.