-
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
Fix workplane cylinder center when generated using a custom direction #1593
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1593 +/- ##
==========================================
+ Coverage 94.86% 95.33% +0.47%
==========================================
Files 28 27 -1
Lines 6226 6774 +548
Branches 1261 1010 -251
==========================================
+ Hits 5906 6458 +552
Misses 193 193
+ Partials 127 123 -4 ☔ View full report in Codecov by Sentry. |
Something like the following should handle it.
if isinstance(centered, bool):
centered = (centered, centered, centered)
offset = Vector()
plane = Plane((0, 0, 0), normal=direct)
if not centered[0]:
offset += plane.toWorldCoords((radius, 0, 0))
if not centered[1]:
offset += plane.toWorldCoords((0, radius, 0))
if centered[2]:
offset += plane.toWorldCoords((0, 0, -height / 2))
s = Solid.makeCylinder(radius, height, offset, direct, angle)
# We want a cylinder for each point on the workplane
return self.eachpoint(lambda loc: s.moved(loc), True, combine, clean) |
Thanks, I prefer this than what I did but then it requires to be careful about the axis to set for centering. To center a cylinder along its height but directed along the y axis, it requires to put the third component of c1 = cq.Shape.centerOfMass(
cq.Workplane("XY").cylinder(
radius=1,
height=10,
direct=cq.Vector(0, 1, 0),
centered=(False, False, True),
).val()
)
print(c1)
c2 = cq.Shape.centerOfMass(
cq.Workplane("XY").cylinder(
radius=1,
height=10,
direct=cq.Vector(0, 1, 0),
centered=(False, True, False),
).val()
)
print(c2) Results in Vector: (1.0, 0.0, 1.0)
Vector: (0.0, 5.0, 1.0) Is it the expected behavior? |
res = cq.Workplane("XY").cylinder(
radius=1,
height=10,
direct=cq.Vector(0, 1, 0),
centered=(False, False, True),
).val() res2 = cq.Workplane("XY").cylinder(
radius=1,
height=10,
direct=cq.Vector(0, 1, 0),
centered=(False, True, False),
).val() and @kmarchais how did you actually generate the reference data for the tests? Visually the result is as expected AFAICT. |
The test was pretty straight forward in the previous implementation, testing all the possible combinations of centering and directions. Also I want to make sure, is the following the expected result? >>> cq.Shape.centerOfMass(cq.Workplane("XY").cylinder(radius=10, height=40, direct=cq.Vector(1, 0, 0), centered=False).val())
Vector: (20, -10, 10) |
I am just not used to this radius shift and wanted to make sure that this -10 in the y direction is fine. |
Hey @kmarchais any updates on this? Do you intend to finalize it? |
@adam-urbanczyk Thanks for the remainder. I'm on it. |
I could not find a simple way to test every combination of centered and direct parameters. I made it so that it checks different configurations:
|
Another idea is update the typing of the direct: Union[Tuple[float, float, float], Vector] = Vector(0, 0, 1), or cadquery/cadquery/occ_impl/geom.py Line 553 in 0c472ef
|
@lorenzncode it seems that your suggestions were applied. Are you OK with merging? |
I came across a couple of cases I'm not certain are correct.
import cadquery as cq
centered = (False, False, False)
r = 1
h = 10
cyl1 = (
cq.Workplane()
.cylinder(h, r, (1, 0, 0), centered=centered)
)
box1 = (
cq.Workplane()
.box(h, r * 2, r * 2, centered=centered)
)
import cadquery as cq
r = 1
h = 10
centered = (False, False, False)
cyl1 = (
cq.Workplane()
.cylinder(h, r, (1, 0, 0), centered=centered)
)
cyl2 = (
cq.Workplane()
.cylinder(h, r, (-1, 0, 0), centered=centered)
) |
I tested the snippet again here and get the same result. I suppose this is fine as is. If I were to use this method I think I would choose only one of these centering options: centered = (True, True, True)
# or
centered = (True, True, False) Anyway the default is |
Alright, merging. Thanks @kmarchais ! |
Fixes #1591.
(0, 0, 1)
was not centered at the right position.A test has been added to check these two points. It fails before the fix and passes after the fix.
The case where
centered != (True, True, True)
with a direction different than one along the x, y, or z axes is not managed. What would we like to do in this case?