Skip to content

Commit

Permalink
Bend perforation (#370)
Browse files Browse the repository at this point in the history
* Add perforation feature to bends
  • Loading branch information
Erhannis authored Sep 18, 2024
1 parent bece5ec commit 429844a
Showing 1 changed file with 182 additions and 1 deletion.
183 changes: 182 additions & 1 deletion SheetMetalCmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,75 @@ def smMakeReliefFace(edge, dir, gap, reliefW, reliefD, reliefType, op=""):
return face


def smMakePerforationFace(
edge,
dir,
bendR,
bendA,
perforationAngle,
flipped,
extLen,
gap1,
gap2,
lenIPerf1,
lenIPerf2,
lenPerf,
lenNPerf,
op="",
):
L0 = (edge.LastParameter - gap2 - lenIPerf2) - (edge.FirstParameter + gap1 + lenIPerf1)
Lp = lenPerf
Ln = lenNPerf
P0 = (L0-Ln) / (Lp+Ln)
P = math.ceil(P0)
N = P+1
F = L0 / (math.ceil(P0)*Lp + math.ceil(P0)*Ln + Ln)

if perforationAngle == 0:
perforationAngle = bendA
extAngle = (perforationAngle - bendA) / 2;
S = (1 / math.cos(extAngle * (2*math.pi/360)))

pivotL = -bendR
swingL = extLen + (S-1)*(bendR+extLen)
if not flipped:
pivotL = extLen - pivotL
swingL = extLen - swingL

# Initial perf, near
p1 = edge.valueAt(edge.FirstParameter + gap1) + dir.normalize() * pivotL
p2 = edge.valueAt(edge.FirstParameter + gap1 + lenIPerf1) + dir.normalize() * pivotL
p3 = edge.valueAt(edge.FirstParameter + gap1 + lenIPerf1) + dir.normalize() * swingL
p4 = edge.valueAt(edge.FirstParameter + gap1) + dir.normalize() * swingL
w = Part.makePolygon([p1, p2, p3, p4, p1])
face = Part.Face(w)
totalFace = face

# Initial perf, far
p1 = edge.valueAt(edge.LastParameter - gap2 - lenIPerf2) + dir.normalize() * pivotL
p2 = edge.valueAt(edge.LastParameter - gap2) + dir.normalize() * pivotL
p3 = edge.valueAt(edge.LastParameter - gap2) + dir.normalize() * swingL
p4 = edge.valueAt(edge.LastParameter - gap2 - lenIPerf2) + dir.normalize() * swingL
w = Part.makePolygon([p1, p2, p3, p4, p1])
face = Part.Face(w)
totalFace = totalFace.fuse(face)

# Perforations, inner
for i in range(P):
x = (edge.FirstParameter + gap1 + lenIPerf1) + (Ln * F * (i+1)) + (Lp * F * i)
p1 = edge.valueAt(x) + dir.normalize() * pivotL
p2 = edge.valueAt(x + Lp*F) + dir.normalize() * pivotL
p3 = edge.valueAt(x + Lp*F) + dir.normalize() * swingL
p4 = edge.valueAt(x) + dir.normalize() * swingL
w = Part.makePolygon([p1, p2, p3, p4, p1])
face = Part.Face(w)
totalFace = totalFace.fuse(face)

if hasattr(totalFace, "mapShapes"):
totalFace.mapShapes([(edge, totalFace)], None, op)
return totalFace


def smMakeFace(edge, dir, extLen, gap1=0.0, gap2=0.0, angle1=0.0, angle2=0.0, op=""):
len1 = extLen * math.tan(math.radians(angle1))
len2 = extLen * math.tan(math.radians(angle2))
Expand Down Expand Up @@ -917,6 +986,11 @@ def smBend(
sketch=None,
extendType="Simple",
LengthSpec="Leg",
Perforate=False,
PerforationAngle=0.0,
PerforationInitialLength=5.0,
PerforationMaxLength=5.0,
NonperforationMaxLength=5.0,
):
# if sketch is as wall
sketches = False
Expand Down Expand Up @@ -1287,8 +1361,8 @@ def smBend(
# Part.show(wallSolid.Faces[2])
thk_faceList.append(wallSolid.Faces[2])

# Produce bend Solid
if not (unfold):
# Produce bend Solid
if bendA > 0.0:
# create bend
# narrow the wall if we have gaps
Expand All @@ -1302,6 +1376,41 @@ def smBend(
resultSolid = resultSolid.fuse(wallSolid)
# Part.show(resultSolid,"resultSolid")

# Remove perforation
if Perforate:
#CHECK I'm not sure about flipped - the main one gets overwritten for each sublist item
perfFace = smMakePerforationFace(
lenEdge,
thkDir,
bendR,
bendA,
PerforationAngle,
flipped,
thk,
gap1,
gap2,
PerforationInitialLength,
PerforationInitialLength,
PerforationMaxLength,
NonperforationMaxLength,
op="SMR",
)
# Part.show(perfFace)
#CHECK 'Part.Compound' object has no attribute 'normalAt' ; might need it
# if perfFace.normalAt(0, 0) != FaceDir:
# perfFace.reverse()
if PerforationAngle > 0.0:
perfFace = perfFace.rotate(
revAxisP,
revAxisV,
(bendA/2)-(PerforationAngle/2)
)
perfSolid = perfFace.revolve(revAxisP, revAxisV, PerforationAngle)
else:
perfSolid = perfFace.revolve(revAxisP, revAxisV, bendA)
# Part.show(perfSolid)
resultSolid = resultSolid.cut(perfSolid)

# Produce unfold Solid
else:
if bendA > 0.0:
Expand All @@ -1316,10 +1425,42 @@ def smBend(
resultSolid = resultSolid.fuse(unfoldSolid)

if extLen > 0.0:
# Flatten the wall back out
wallSolid.rotate(revAxisP, revAxisV, -bendA)
# Part.show(wallSolid, "wallSolid")
wallSolid.translate(FaceDir * unfoldLength)
resultSolid = resultSolid.fuse(wallSolid)

# Remove perforation
if Perforate:
perfFace = smMakePerforationFace(
lenEdge,
thkDir,
bendR,
bendA,
PerforationAngle,
flipped,
thk,
gap1,
gap2,
PerforationInitialLength,
PerforationInitialLength,
PerforationMaxLength,
NonperforationMaxLength,
op="SMR",
)
#CHECK 'Part.Compound' object has no attribute 'normalAt' ; might need it
# if perfFace.normalAt(0, 0) != FaceDir:
# perfFace.reverse()
if PerforationAngle > 0.0:
perfUnfoldLength = (bendR + kfactor * thk) * PerforationAngle * math.pi / 180.0
perfFace = perfFace.translate(FaceDir * ((unfoldLength/2)-(perfUnfoldLength/2)))
perfSolid = perfFace.extrude(FaceDir * perfUnfoldLength)
else:
perfSolid = perfFace.extrude(FaceDir * unfoldLength)
# Part.show(perfSolid)
resultSolid = resultSolid.cut(perfSolid)

# Part.show(resultSolid, "resultSolid")
return resultSolid, thk_faceList

Expand Down Expand Up @@ -1530,6 +1671,41 @@ def _addProperties(self, obj):
None,
"ParametersEx3",
)
smAddBoolProperty(
obj,
"Perforate",
FreeCAD.Qt.translate("App::Property", "Enable Perforation"),
False,
"ParametersPerforation",
)
smAddAngleProperty(
obj,
"PerforationAngle",
FreeCAD.Qt.translate("App::Property", "Perforation Angle"),
0.0,
"ParametersPerforation",
)
smAddLengthProperty(
obj,
"PerforationInitialLength",
FreeCAD.Qt.translate("App::Property", "Initial Perforation Length"),
5.0,
"ParametersPerforation",
)
smAddLengthProperty(
obj,
"PerforationMaxLength",
FreeCAD.Qt.translate("App::Property", "Perforation Max Length"),
5.0,
"ParametersPerforation",
)
smAddLengthProperty(
obj,
"NonperforationMaxLength",
FreeCAD.Qt.translate("App::Property", "Non-Perforation Max Length"),
5.0,
"ParametersPerforation",
)

def getElementMapVersion(self, _fp, ver, _prop, restored):
if not restored:
Expand Down Expand Up @@ -1613,6 +1789,11 @@ def execute(self, fp):
mingap=fp.minGap.Value,
maxExtendGap=fp.maxExtendDist.Value,
LengthSpec=fp.LengthSpec,
Perforate=fp.Perforate,
PerforationAngle=fp.PerforationAngle.Value,
PerforationInitialLength=fp.PerforationInitialLength.Value,
PerforationMaxLength=fp.PerforationMaxLength.Value,
NonperforationMaxLength=fp.NonperforationMaxLength.Value,
)
faces = smGetFace(f, s)
face = faces
Expand Down

0 comments on commit 429844a

Please sign in to comment.