Skip to content

Commit ae1ce2b

Browse files
committed
manget hole chamfers for all hole shapes
1 parent 881a70a commit ae1ce2b

File tree

7 files changed

+44
-78
lines changed

7 files changed

+44
-78
lines changed

freecad/gridfinity_workbench/baseplate_feature_construction.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,6 @@ def magnet_holes_properties(obj: fc.DocumentObject) -> None:
7272
"<br> <br> default = 3 mm",
7373
).MagnetBaseHole = const.MAGNET_BASE_HOLE
7474

75-
obj.addProperty(
76-
"App::PropertyLength",
77-
"MagnetChamfer",
78-
"NonStandard",
79-
"Chamfer at top of magnet hole <br> <br> default = 0.4 mm",
80-
).MagnetChamfer = const.MAGNET_CHAMFER
81-
8275
## Gridfinity Expert Only Parameters
8376
obj.addProperty(
8477
"App::PropertyLength",
@@ -229,7 +222,7 @@ def make_connection_holes(obj: fc.DocumentObject, layout: GridfinityLayout) -> P
229222
return fuse_total
230223

231224

232-
def _center_cut_wire(obj: fc.DocumentObject) -> Part.Wire:
225+
def _center_cut_face(obj: fc.DocumentObject) -> Part.Face:
233226
"""Create wire for the baseplate center cut."""
234227
x_inframedis = (
235228
obj.xGridSize / 2
@@ -324,7 +317,7 @@ def _center_cut_wire(obj: fc.DocumentObject) -> Part.Wire:
324317
l5 = Part.LineSegment(l4.EndPoint, mec_middle)
325318
l6 = Part.LineSegment(l5.EndPoint, l1.StartPoint)
326319

327-
return utils.curve_to_wire([l1, ar1, l2, ar2, l3, ar3, l4, l5, l6])
320+
return utils.curve_to_face([l1, ar1, l2, ar2, l3, ar3, l4, l5, l6])
328321

329322

330323
def center_cut_properties(obj: fc.DocumentObject) -> None:
@@ -339,9 +332,9 @@ def center_cut_properties(obj: fc.DocumentObject) -> None:
339332

340333
def make_center_cut(obj: fc.DocumentObject, layout: GridfinityLayout) -> Part.Shape:
341334
"""Create baseplate center cutout."""
342-
wire = _center_cut_wire(obj)
335+
face = _center_cut_face(obj)
343336

344-
partial_shape1 = Part.Face(wire).extrude(fc.Vector(0, 0, -obj.TotalHeight))
337+
partial_shape1 = face.extrude(fc.Vector(0, 0, -obj.TotalHeight))
345338
partial_shape2 = partial_shape1.mirror(fc.Vector(0, 0, 0), fc.Vector(0, 1, 0))
346339
partial_shape3 = partial_shape1.mirror(fc.Vector(0, 0, 0), fc.Vector(1, 0, 0))
347340
partial_shape4 = partial_shape2.mirror(fc.Vector(0, 0, 0), fc.Vector(1, 0, 0))

freecad/gridfinity_workbench/const.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
MAGNET_EDGE_THICKNESS = 1.2
9898
MAGNET_BASE = 0.4
9999
MAGNET_BASE_HOLE = 3
100-
MAGNET_CHAMFER = 0.4
101100

102101
# Screw Together Baseplate Specific
103102
CONNECTION_HOLE_DIAMETER = 3.2

freecad/gridfinity_workbench/feature_construction.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ def make_fillet(rotation: float, translation: fc.Vector) -> Part.Shape:
330330
Part.LineSegment(v3, v1),
331331
]
332332

333-
face = Part.Face(utils.curve_to_wire(lines))
333+
face = utils.curve_to_face(lines)
334334
face.rotate(fc.Vector(0, 0, 0), fc.Vector(0, 0, 1), rotation)
335335
face.translate(translation)
336336
return face.extrude(fc.Vector(0, 0, -obj.TotalHeight))

freecad/gridfinity_workbench/label_shelf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def _corner_fillet(radius: float) -> Part.Face:
2626
Part.LineSegment(v3, v1),
2727
]
2828

29-
return Part.Face(utils.curve_to_wire(lines))
29+
return utils.curve_to_face(lines)
3030

3131

3232
def outside_fillet(
@@ -79,7 +79,7 @@ def from_dimensions(
7979
fc.Vector(0, yoffset, -height),
8080
]
8181

82-
face = Part.Face(utils.curve_to_wire(utils.loop(v)))
82+
face = utils.curve_to_face(utils.loop(v))
8383
shape = face.extrude(fc.Vector(0, length))
8484

8585
# Front fillet

freecad/gridfinity_workbench/magnet_hole.py

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,14 @@
99

1010
from . import utils
1111

12+
unitmm = fc.Units.Quantity("1 mm")
1213

13-
def _crush_ribs(
14-
radius: fc.Units.Quantity,
15-
depth: fc.Units.Quantity,
16-
*,
17-
n: int,
18-
beta: float,
19-
) -> Part.Shape:
20-
"""Make crush ribs inner shape.
14+
15+
def _crush_ribs(radius: fc.Units.Quantity, *, n: int, beta: float) -> tuple[Part.Face, float]:
16+
"""Make crush ribs inner face.
2117
2218
Args:
2319
radius (fc.Units.Quantity): Inner radius.
24-
depth (fc.Units.Quantity): Depth.
2520
n (int): Number of ribs.
2621
beta (float): Waviness of the ribs. It is the angle at wich inner at outer arcs meet.
2722
A value of 0 would result in a perfect circle.
@@ -52,14 +47,10 @@ def get_midpoint(beta: float) -> float:
5247
math.degrees((i + 0.5) / len(lines) * 2 * math.pi),
5348
)
5449
arc.rotate(placement)
55-
wire = utils.curve_to_wire(lines)
56-
face = Part.Face(wire)
57-
shape = face.extrude(fc.Vector(0, 0, depth))
58-
59-
return shape
50+
return utils.curve_to_face(lines), r3 - r1
6051

6152

62-
def _hex_shape(radius: fc.Units.Quantity, depth: fc.Units.Quantity) -> Part.Shape:
53+
def _hex_shape(radius: fc.Units.Quantity) -> Part.Shape:
6354
# Ratio of 2/sqrt(3) converts from inscribed circle radius to circumscribed
6455
# circle radius
6556
radius = 2 * radius / math.sqrt(3)
@@ -70,7 +61,7 @@ def _hex_shape(radius: fc.Units.Quantity, depth: fc.Units.Quantity) -> Part.Shap
7061
p.recompute()
7162

7263
p_wire: Part.Wire = p.Shape
73-
shape = Part.Face(p_wire).extrude(fc.Vector(0, 0, depth))
64+
shape = Part.Face(p_wire)
7465
fc.ActiveDocument.removeObject(p.Name)
7566
return shape
7667

@@ -83,25 +74,31 @@ def from_obj(obj: fc.DocumentObject) -> Part.Shape:
8374
hole_shape = obj.MagnetHolesShape
8475
radius = obj.MagnetHoleDiameter / 2
8576
depth = obj.MagnetHoleDepth
77+
chamfer_depth = depth / 8
8678

8779
if hole_shape == "Hex":
88-
shape = _hex_shape(radius, depth)
80+
shape = _hex_shape(radius)
81+
chamfer_width = (2 / math.sqrt(3) - 1) * radius
8982
elif hole_shape == "Crush ribs":
90-
shape = _crush_ribs(radius, depth, n=8, beta=0.5 * math.pi / 2)
83+
shape, ch = _crush_ribs(radius, n=8, beta=0.5 * math.pi / 2)
84+
chamfer_width = ch * unitmm
9185
elif hole_shape == "Round":
92-
shape = Part.makeCylinder(radius, depth)
93-
if obj.Baseplate:
94-
chamfer = obj.MagnetChamfer
95-
chamfer_shape = utils.round_chamfer(
96-
radius,
97-
radius + chamfer,
98-
chamfer,
99-
pPnt=fc.Vector(0, 0, depth - chamfer),
100-
)
101-
shape = shape.fuse(chamfer_shape)
86+
shape = Part.Face(Part.Wire(Part.makeCircle(radius)))
87+
chamfer_width = chamfer_depth
10288
else:
10389
raise ValueError(f"Unrecognised magnet hole shape {hole_shape:!r}")
10490

91+
shape = shape.extrude(fc.Vector(0, 0, depth))
92+
93+
if obj.Baseplate:
94+
chamfer_shape = utils.round_chamfer(
95+
radius,
96+
radius + chamfer_width,
97+
chamfer_depth,
98+
pPnt=fc.Vector(0, 0, depth - chamfer_depth),
99+
)
100+
shape = shape.fuse(chamfer_shape)
101+
105102
return shape
106103

107104

@@ -125,8 +122,7 @@ def relief(obj: fc.DocumentObject) -> Part.Shape:
125122
Part.LineSegment(p4, p5),
126123
Part.LineSegment(p5, p1),
127124
]
128-
wire = utils.curve_to_wire(lines)
129-
face = Part.Face(wire)
125+
face = utils.curve_to_face(lines)
130126
shape = face.extrude(fc.Vector(0, 0, obj.MagnetHoleDepth))
131127

132128
positions = [

freecad/gridfinity_workbench/utils.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,22 @@ def copy_in_grid(
115115
return multi_fuse(shapes)
116116

117117

118-
def curve_to_wire(list_of_items: Sequence[Part.TrimmedCurve]) -> Part.Wire:
119-
"""Make a wire from curves (line,linesegment,arc,ect).
118+
def curve_to_face(curves: Sequence[Part.TrimmedCurve]) -> Part.Face:
119+
"""Make a face from curves (line,linesegment,arc,ect).
120120
121-
This function accepts all curves and makes it into a wire. Note that the wire should be
122-
closed.
121+
Note that the sequence should be a closed curve -- the end of last curve should be the beginning
122+
of the first one.
123123
124124
Args:
125-
list_of_items (list[Part.LineSegment]): List of items to convert in a wire.
126-
127-
Returns:
128-
Part.Wire: The created wire.
125+
curves (Sequence[Part.LineSegment]): Sequence of corves to that enclose the face.
129126
130127
"""
131-
if not list_of_items:
128+
if not curves:
132129
raise ValueError("List is empty")
130+
if curves[0].StartPoint != curves[-1].EndPoint:
131+
raise ValueError("The sequence is not a closed curve")
133132

134-
return Part.Wire([item.toShape() for item in list_of_items])
133+
return Part.Face(Part.Wire([item.toShape() for item in curves]))
135134

136135

137136
def create_rounded_rectangle(

tests/test_unit_utils.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -63,29 +63,8 @@ def test_copy_in_grid(self) -> None:
6363
)
6464
self.assertEqual(shapes, shape.translated().multiFuse())
6565

66-
def test_curve_to_wire_empty_list(self) -> None:
67-
self.assertRaises(ValueError, utils.curve_to_wire, [])
68-
69-
def test_curve_to_wire_one_line(self) -> None:
70-
vertexes = [fc.Vector(0, 0, 0), fc.Vector(10, 0, 0)]
71-
line = Part.LineSegment(vertexes[0], vertexes[1])
72-
73-
wire = utils.curve_to_wire([line])
74-
75-
self.assertEqual(wire.Length, 10)
76-
self.assertListEqual(vertexes, [vertex.Point for vertex in wire.Vertexes])
77-
78-
def test_cuve_to_wire_rectangle(self) -> None:
79-
line_1 = Part.LineSegment(fc.Vector(0, 0, 0), fc.Vector(10, 0, 0))
80-
line_2 = Part.LineSegment(fc.Vector(10, 0, 0), fc.Vector(10, 10, 0))
81-
line_3 = Part.LineSegment(fc.Vector(10, 10, 0), fc.Vector(10, 0, 0))
82-
line_4 = Part.LineSegment(fc.Vector(10, 0, 0), fc.Vector(0, 0, 0))
83-
84-
wire = utils.curve_to_wire([line_1, line_2, line_3, line_4])
85-
86-
self.assertTrue(wire.isClosed)
87-
self.assertEqual(wire.Length, 10 * 4)
88-
self.assertEqual(len(wire.Edges), 4)
66+
def test_curve_to_face_empty_list(self) -> None:
67+
self.assertRaises(ValueError, utils.curve_to_face, [])
8968

9069
def test_create_rounded_rectangle_radius_1(self) -> None:
9170
length, width, radius = 5, 6, 1

0 commit comments

Comments
 (0)