-
Notifications
You must be signed in to change notification settings - Fork 289
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
Make Workplane Work Better as a Base Class #673
Comments
If you need it, then no problem. Just use Keep in mind that if you want to share your plugins they might be not easily usable by others if implemented as subclasses. |
Is there a repository of contributed plugins? I was thinking more of having the ability to ensure I'm using a workplane with the plugins I expect to exist. E.g., something like: class WorkplaneWithSpirals(cadquery.Workplane):
def archimedeanSpiral(parameters):
# . . . Implementation . . .
result = WorkplaneWithSpirals("XY").archimedeanSpiral(parameters) In some other module: class WorkplaneWithMetricBoltProfile(WorkplaneWithSpirals):
def metricBoltProfile(parameres):
return self.archimedeanSpiral(parameters1).archimedeanSpiral(parameters2) # . . .
result = WorkplaneWithMetricBoltProfile("XY").metricBoltProfile(parameters).twistExtrude(
distance = pitch * thread_turns, angle = 2 * math.pi * thread_turns)
Interestingly, in the example above, The code in the screen capture below is similar to the example from typing import Iterable, TypeVar, cast
import cadquery
SelfT = TypeVar("SelfT")
class ExtendedWorkplane(cadquery.Workplane):
# . . .
def typedMoveTo(self: SelfT, x: float, y: float) -> SelfT:
# Keeping `mypy` happy here requires a few casts:
return cast(
SelfT,
super(ExtendedWorkplane, cast(ExtendedWorkplane, self)).moveTo(x=x, y=y),
)
def newShape(self):
print("Fancy")
return self Of course,
So, you can see code completion suggests |
We could use cadquery-contrib, but I would probably rather create a cadquery-plugins repo. @pavpen If you want to contribute plugins, I can create that repo and post the link here. |
It makes no difference to me. I could contribute to this repository or another one, whatever is easier for you to manage. I'll need to spend some time to make sure my code is good enough for other people to see. (E.g., calculating the deviation of a B-spline from an Archimedean spiral, so you can stay within a given tolerance.) Also are there some criteria for what should go into the core |
Resolved by #677. |
As a CadQuery user, and developer of custom plugins, I would like to be able to derive classes from
Workplane
that add functionality, such as methods for generating curves I may often use. Currently, deriving a class fromWorkplane
produces class, which can't directly use the inherited fluent API methods.Notes
Why Inheritance Breaks
Workplane.newObject()
is called by many of the methods that add points, curves, wires, or solids to the workplane stack. ThenewObject()
method instantiates the result returned by the fluent API methods like this:The result is that any instance of a class derived from
cq.Workplane
would inherit fluent API methods that return instances ofcq.Workplane
, rather than instances of the derived class.Example
E.g.:
We want to still have an
ExtendedWorkplane
afterresult.moveTo()
, but:What a Fix would Look Like
The following implementation of
newObject()
will fix this problem:A change to the return types of the
Workplane
methods callingnewObject()
would also be needed to satisfy type checkers.Opinion
In my view, class inheritance is a better way to add plugins to CadQuery's
Workplane
, rather thanWorkplane.someMethodName = functionExpression
. Inheritance works better with code autocompletion and analysis, such as type checking, and provides a way to name plugins, and put them in a hierarchy, in order to avoid possible name collisions if multiple users try to add a method with the same name toWorkplane
.Let me know what you think, I'd be willing to implement this when I get a bit of time.
The text was updated successfully, but these errors were encountered: