-
Notifications
You must be signed in to change notification settings - Fork 299
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
InPlane constraint #712
InPlane constraint #712
Conversation
Codecov Report
@@ Coverage Diff @@
## master #712 +/- ##
==========================================
+ Coverage 94.51% 94.59% +0.07%
==========================================
Files 32 32
Lines 7078 7215 +137
Branches 768 785 +17
==========================================
+ Hits 6690 6825 +135
- Misses 254 255 +1
- Partials 134 135 +1
Continue to review full report at Codecov.
|
Codecov pointed out I only test when the plane is locked and the point is free, I should test the other way around too. |
At the moment this constraint requires the first object to be a plane (or at least quack like one), and the second object to be a point. I started changing the code so the constraint could be specified either way around but I didn't like what I was writing. I would have to type check to figure out which argument is a plane, and in doing so prevent the use case of constraining the centre of one face to the plane formed by another face. It was also ugly code. At the moment the responsibility is on the user to specify the plane as the first object and the point as the second. I'll keep it in the back of my head and see if I can come up with a better way to write these non-symetrical constraints (plane/point vs the symetrical axis/axis and point/point constraints). |
Yes, this seems like what I was looking for. I'm not sure when I'll get a chance to do it, but I plan to go back to your spindle assembly and retry mounting the spindle base plate to the aluminum extrusion with this constraint in place. https://raw.githubusercontent.com/marcus7070/spindle-assy-example/master/screenshot.png Melding both the way I would do it in something like SolidWorks and CadQuery's existing constraints, I expect this is what I'll try.
|
Got a chance to play around with this a little bit and I like it. I expect I will use this constraint constantly when working with assemblies in CQ. I created the following simplified assembly to accomplish what caused my confusion in #479 import cadquery as cq
block1 = cq.Workplane("XY").box(200, 100, 20)
block2 = cq.Workplane("XY").box(50, 100, 10)
assy = cq.Assembly()
assy.add(block1, name="block1", color=cq.Color(1.0, 0, 0, 1.0))
assy.add(block2, name="block2", color=cq.Color(0.0, 0, 1, 1.0))
assy.constrain("block1@faces@>Z", "block2@faces@<Z", "InPlane", param=0)
assy.constrain("block1@faces@>X", "block2@faces@>X", "InPlane", param=20)
assy.constrain("block1@faces@<X", "block2@faces@>X", "Axis")
assy.solve()
show_object(assy) Results in: I do have two questions though.
import cadquery as cq
block1 = cq.Workplane("XY").box(200, 100, 20)
block2 = cq.Workplane("XY").box(50, 80, 10)
assy = cq.Assembly()
assy.add(block1, name="block1", color=cq.Color(1.0, 0, 0, 1.0))
assy.add(block2, name="block2", color=cq.Color(0.0, 0, 1, 1.0))
assy.constrain("block1@faces@>Z", "block2@faces@<Z", "InPlane", param=0)
assy.constrain("block1@faces@>X", "block2@faces@>X", "InPlane", param=20)
assy.constrain("block1@faces@>Y", "block2@faces@>Y", "InPlane", param=30)
#assy.constrain("block1@faces@<X", "block2@faces@>X", "Axis")
assy.solve()
show_object(assy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks @marcus7070 !
If you have a look at the function that is minimized: cadquery/cadquery/occ_impl/solver.py Lines 102 to 104 in a71a93e
( So InPlane with a An alternative is to use the 5 argument |
In case there is any misunderstanding I'll just make this clear. assy.constrain("block1@faces@>Z", "block2@faces@<Z", "InPlane", param=0)
assy.constrain("block1@faces@>X", "block2@faces@>X", "InPlane", param=20)
assy.constrain("block1@faces@>Y", "block2@faces@>Y", "InPlane", param=30) I'm planning to make this quite clear in the docs, but the InPlane relationship is between a plane and a point. I've just duck typed it so that the faces you are selecting on block2 can be represented as a point. |
Still need to read the code but three general things pop up.
|
Sure, the order was always pretty arbitrary. This was in the back of my mind while writing this PR: the order of arguments in a constraint is important, right? eg. assy = cq.Assembly()
assy.add(cq.Workplane().box(1, 1, 1), name="box")
assy.add(cq.Workplane().sphere(1), name="sphere")
assy.constrain(
"sphere",
cq.Vertex.makeVertex(0, 0, 1),
"box",
cq.Vertex.makeVertex(0, 0, 0),
"Point",
)
assy.solve()
show_object(assy) But when you flip the constraint order to: assy.constrain(
"box",
cq.Vertex.makeVertex(0, 0, 0),
"sphere",
cq.Vertex.makeVertex(0, 0, 1),
"Point",
) So a user could need the reverse of this constraint, ie.
Thanks, I had planned to do wires but forgot.
Oh, so I can! That's going to be so much better, thanks! 🚀 |
I now handle Wires and introduced tests for _getPlane. I decided to make a plane from any Face (as opposed to checking for planar Faces first). Not 100% confident in that descision, let me know if you have any opinions. Still to do:
|
also reordered arguments to point then plane
I said above:
I now think the order of arguments to constraints is not important. What was happening in my examples was that I was starting with an empty assembly ( Lines 379 to 396 in a71a93e
If the user wants a part to be locked, then they should specify it like |
I think I'm done now, so ready for you to look at @adam-urbanczyk. @jmwright you can check out the changes if you like. |
I've added a constraint that positions a point within a 2D plane.
Proper docs are coming in a later PR, but I want to update SphinxCadquery to handle assemblies first.