LCInterlocking
LCInterlocking copied to clipboard
Interlocking: AttributeError: 'NoneType' object has no attribute 'Length'
Hi, I wasn't able to make interlocking pieces between a boolean and a solid from a sketch. I've tried also to make simple copies of objects. Is my object (LABEL: "Cut") too complex for making interlocking?
I'm getting this error:
16:37:03 Traceback (most recent call last):
16:37:03 File "C:\Users\x\AppData\Roaming\FreeCAD\Mod\LCInterlocking\panel\treepanel.py", line 255, in add_tabs
16:37:03 item = self.tabsList.append(face, self.tab_type_box.currentText())
16:37:03 File "C:\Users\x\AppData\Roaming\FreeCAD\Mod\LCInterlocking\panel\tab.py", line 165, in append
16:37:03 tab_properties = TabProperties(freecad_face=face['face'],
16:37:03 File "C:\Users\x\AppData\Roaming\FreeCAD\Mod\LCInterlocking\lasercut\tabproperties.py", line 71, in __init__
16:37:03 self.thickness = thickness.Length
16:37:03 AttributeError: 'NoneType' object has no attribute 'Length'
I've attached my file: v4.zip
OS: Windows 10 (10.0) Word size of FreeCAD: 64-bit Version: 0.20.25429 (Git) Build type: Release Branch: master Hash: acce57a25d82b0408fa07b9452ed31c8a06c7a1b Python version: 3.8.10 Qt version: 5.12.9 Coin version: 4.0.0 OCC version: 7.5.2 Locale: Italian/Italy (it_IT)
Thanks SDeSalve
I had the same problem. I think it's due to a face having more than four points (even a rectangular face may have more than four points, as some may be redundant or used for connecting shapes).
I was able to bodge it in to working by replacing the get_local_axis
function in helper.py:
def getExtends(edge):
extends_X = (edge.Vertexes[0].X != edge.Vertexes[1].X)
extends_Y = (edge.Vertexes[0].Y != edge.Vertexes[1].Y)
extends_Z = (edge.Vertexes[0].Z != edge.Vertexes[1].Z)
return extends_X, extends_Y, extends_Z
def get_local_axis(face):
list_edges = Part.__sortEdges__(face.Edges)
coalescedEdges = []
previousEdge = None
for edge in list_edges:
extends_X, extends_Y, extends_Z = getExtends(edge)
if previousEdge is not None:
# If we extend in only one direction, and that is the same direction as the previous edge,
# then we can merge the two edges together.
dirsExtended = 0
if extends_X:
dirsExtended = dirsExtended + 1
if extends_Y:
dirsExtended = dirsExtended + 1
if extends_Z:
dirsExtended = dirsExtended + 1
if dirsExtended == 1 and extends_X == prev_extends_X and extends_Y == prev_extends_Y and extends_Z == prev_extends_Z:
if extends_X:
coalescedEdges[-1].Vertexes[1] = Part.Vertex( edge.Vertexes[1].X, coalescedEdges[-1].Vertexes[1].Y, coalescedEdges[-1].Vertexes[1].Z)
if extends_Y:
ls = Part.LineSegment( coalescedEdges[-1].Vertexes[0].Point, FreeCAD.Vector(coalescedEdges[-1].Vertexes[1].X, edge.Vertexes[1].Y, coalescedEdges[-1].Vertexes[1].Z) )
coalescedEdges[-1] = Part.Edge(ls)
if extends_Z:
coalescedEdges[-1].Vertexes[1] = Part.Vertex( coalescedEdges[-1].Vertexes[1].X, coalescedEdges[-1].Vertexes[1].Y, edge.Vertexes[1].Z)
else:
coalescedEdges.append(edge)
else:
coalescedEdges.append(edge)
prev_extends_X = extends_X
prev_extends_Y = extends_Y
prev_extends_Z = extends_Z
previousEdge = edge
# And check in case the last edge is an extension of the first.
extends_X, extends_Y, extends_Z = getExtends(coalescedEdges[-1])
prev_extends_X, prev_extends_Y, prev_extends_Z = getExtends(coalescedEdges[0])
dirsExtended = 0
if extends_X:
dirsExtended = dirsExtended + 1
if extends_Y:
dirsExtended = dirsExtended + 1
if extends_Z:
dirsExtended = dirsExtended + 1
if dirsExtended == 1 and extends_X == prev_extends_X and extends_Y == prev_extends_Y and extends_Z == prev_extends_Z:
if extends_X:
coalescedEdges[-1].Vertexes[1] = Part.Vertex( coalescedEdges[0].Vertexes[1].X, coalescedEdges[-1].Vertexes[1].Y, coalescedEdges[-1].Vertexes[1].Z)
if extends_Y:
ls = Part.LineSegment( coalescedEdges[-1].Vertexes[0].Point, FreeCAD.Vector(coalescedEdges[-1].Vertexes[1].X, edge.Vertexes[1].Y, coalescedEdges[-1].Vertexes[1].Z) )
coalescedEdges[-1] = Part.Edge(ls)
if extends_Z:
coalescedEdges[-1].Vertexes[1] = Part.Vertex( coalescedEdges[-1].Vertexes[1].X, coalescedEdges[-1].Vertexes[1].Y, coalescedEdges[0].Vertexes[1].Z)
coalescedEdges.remove(coalescedEdges[0])
list_edges = coalescedEdges
#get_local_axis(elt)
list_points = sort_quad_vertex(list_edges, False)
if list_points is None:
list_points = sort_quad_vertex(list_edges, True)
if list_points is None:
raise ValueError("Error sorting vertex")
normal_face = face.normalAt(0, 0)
y_local = None
z_local = None
#x_local = normal_face.negative()
x_local = normal_face.normalize()
z_local_not_normalized = None
y_local_not_normalized = None
for x in range(0, len(list_edges)):
vector1 = list_points[(x + 1) % len(list_edges)] - list_points[x]
vector2 = list_points[(x - 1) % len(list_edges)] - list_points[x]
y_local = None
z_local = None
if vector1.Length >= vector2.Length:
z_local_not_normalized = vector2 * 1
y_local_not_normalized = vector1 * 1
y_local = vector1.normalize()
z_local = vector2.normalize()
else:
z_local_not_normalized = vector1 * 1
y_local_not_normalized = vector2 * 1
y_local = vector2.normalize()
z_local = vector1.normalize()
computed_x_local = y_local.cross(z_local)
if compare_freecad_vector(computed_x_local, x_local):
return x_local, y_local_not_normalized, z_local_not_normalized
return None, None, None
Please note that I haven't got a clue about geometry, and so I don't know if this will help at all! It might make things worse! Hopefully someone with deeper knowlege can help out later, but in the meantime, I hope this helps. It's horribly written, I know. But it works [for me.]