CadQuery / cadquery

A python parametric CAD scripting framework based on OCCT
https://cadquery.readthedocs.io
Other
2.93k stars 276 forks source link

Add selectors for local coordinate system #1592

Closed cactorium closed 1 month ago

cactorium commented 1 month ago

Hey there! From my understanding, the selectors currently only work in the global coordinate space. Would it be possible to make a set of selectors that work in the local coordinate space? This is useful when you have models that could be instantiated in different orientations, I've got a linear carriage bearing model where I'm using ">Z" to pick the top surface to start the next model, but this breaks when I change the orientation of the starting workplane to something other than the XY plane.

Maybe they could use the lower case versions of the existing selectors, like ">z", "|z", etc

adam-urbanczyk commented 1 month ago

Not planned, but you can relatively easily implement custom selectors. Some examples can be found here: https://github.com/michaelgale/cq-kit/blob/master/cqkit/cq_selectors.py

Also, based on your description I'm not sure that this would be optimal. Did you look into assemblies and constraints?

cactorium commented 1 month ago

Yeah I've thought about using constraints, but that seems more heavy-handed than necessary for my use case; I know exactly how each part needs to bolt onto the others so it's been really easy just to pass workplanes around instead of trying to set up constraints, my code basically boils down to something like:

class BaseStruct:
  def __init__(self, w):
    self.solid = ....
    self.wp_face = ....

def StackableThing:
  def __init__(self, w):
    self.solid = ....
    self.wp_face1 = ...
    self.wp_face2 = ....

b = Base(cq.Workplane())
s1 = StackableThing(b.wp_face1)
s2 = StackableThing(b.wp_face2)
s3 = StackableThing(s2.wp_face2)

Thanks for the link! Would there be any interest in adding such a feature? I'd be willing to work on it, if not I'll probably write some rough selectors just to use for myself

adam-urbanczyk commented 1 month ago

I still think that you are approaching it in a sub-optimal way. If you know exactly the desired locations, you can use static assemblies and specify the locations. NB: you can add sub-assemblies to an assembly and thus compose the relative locations. Alternatively, you can compose the locations themselves.

If you still want some use-case specific selectors, simply develop it as a separate project (like cq-kit).

jmwright commented 1 month ago

@cactorium You could consider developing this as a plugin. https://github.com/CadQuery/cadquery-plugins

cactorium commented 1 month ago

Thank you guys for the feedback, I'll write a plugin for it

adam-urbanczyk commented 1 month ago

@cactorium if you really think you need this, IMO this would be the best way to approach such a functionality.

Selectors are not specific to cq.Workplane (they are also used by cq.Shape, cq.Sketch and cq.Assembly), so probably it is better to define a special method(s)/kw arg specifically for cq.Workplane that would apply inverse location of the current workplane, do the selection, and than reapply the original location again to the selected objects. This way you would not need to modify all the existing selectors.

cactorium commented 4 weeks ago

Well, I ended up with this in case anyone wants to take a look/give feedback: https://github.com/cactorium/cadquery-plugins/blob/main/plugins/localselectors/localselectors.py I'll work on cleaning it up over the weekend and seeing if it could be added to cadquery-plugins