Code: Select all
# These dictionaries list the nodes, that define faces of an element.
# The key is the face number, used internally by FreeCAD.
# The list contains the nodes in the element for each face.
tetFaces = {
1: [0, 1, 2],
2: [0, 3, 1],
3: [1, 3, 2],
4: [2, 3, 0]}
pentaFaces = {
1: [0, 1, 2],
2: [3, 5, 4],
3: [0, 3, 4, 1],
4: [1, 4, 5, 2],
5: [0, 2, 5, 3]}
hexaFaces = { # hexa8 or hexa20 (ignoring mid-nodes)
1: [0, 1, 2, 3],
2: [4, 7, 6, 5],
3: [0, 4, 5, 1],
4: [1, 5, 6, 2],
5: [2, 6, 7, 3],
6: [3, 7, 4, 0]}
pyraFaces = { # pyra5 or pyra13 (ignoring mid-nodes)
1: [0, 1, 2, 3],
2: [0, 4, 1],
3: [1, 4, 2],
4: [2, 4, 3],
5: [3, 4, 0]}
face_dicts = {
4: tetFaces,
5: pyraFaces,
6: pentaFaces,
8: hexaFaces,
10: tetFaces,
13: pyraFaces,
15: pentaFaces,
20: hexaFaces}
def femmesh_2_mesh_disp(myFemMesh, myResults=None, myDisp=1):
import time
shiftBits = 20 # allows a million nodes, needs to be higher for more nodes in a FemMesh
# This code generates a dict and a faceCode for each face of all elements
# All faceCodes are than sorted.
start_time = time.process_time()
faceCodeList = []
faceCodeDict = {}
if myFemMesh.VolumeCount > 0:
for ele in myFemMesh.Volumes:
element_nodes = myFemMesh.getElementNodes(ele)
# print("element_node: ", element_nodes)
faceDef = face_dicts[len(element_nodes)]
for key in faceDef:
nodeList = []
codeList = []
faceCode = 0
shifter = 0
for nodeIdx in faceDef[key]:
nodeList.append(element_nodes[nodeIdx])
codeList.append(element_nodes[nodeIdx])
codeList.sort()
for node in codeList:
faceCode += (node << shifter)
# x << n: x shifted left by n bits = Multiplication
shifter += shiftBits
# print("codeList: ", codeList)
faceCodeDict[faceCode] = nodeList
faceCodeList.append(faceCode)
elif myFemMesh.FaceCount > 0:
for ele in myFemMesh.Faces:
element_nodes = myFemMesh.getElementNodes(ele)
# print("element_node: ", element_nodes)
faceDef = {1: [0, 1, 2]}
for key in faceDef:
nodeList = []
codeList = []
faceCode = 0
shifter = 0
for nodeIdx in faceDef[key]:
nodeList.append(element_nodes[nodeIdx])
codeList.append(element_nodes[nodeIdx])
codeList.sort()
for node in codeList:
faceCode += (node << shifter)
# x << n: x shifted left by n bits = Multiplication
shifter += shiftBits
# print("codeList: ", codeList)
faceCodeDict[faceCode] = nodeList
faceCodeList.append(faceCode)
faceCodeList.sort()
allFaces = len(faceCodeList)
actFaceIdx = 0
singleFaces = []
# Here we search for faces, which do not have a counterpart.
# These are the faces on the surface of the mesh.
while actFaceIdx < allFaces:
if actFaceIdx < (allFaces - 1):
if faceCodeList[actFaceIdx] == faceCodeList[actFaceIdx + 1]:
actFaceIdx += 2
else:
# print("found a single Face: ", faceCodeList[actFaceIdx])
singleFaces.append(faceCodeList[actFaceIdx])
actFaceIdx += 1
else:
FreeCAD.Console.PrintMessage("Found a last Face: {}\n".format(faceCodeList[actFaceIdx]))
singleFaces.append(faceCodeList[actFaceIdx])
actFaceIdx += 1
output_mesh = []
if myResults:
FreeCAD.Console.PrintMessage("{}\n".format(myResults.Name))
for myFace in singleFaces:
face_nodes = faceCodeDict[myFace]
dispVec0 = myResults.DisplacementVectors[myResults.NodeNumbers.index(face_nodes[0])]
dispVec1 = myResults.DisplacementVectors[myResults.NodeNumbers.index(face_nodes[1])]
dispVec2 = myResults.DisplacementVectors[myResults.NodeNumbers.index(face_nodes[2])]
triangle = [myFemMesh.getNodeById(face_nodes[0]) + dispVec0 * myDisp,
myFemMesh.getNodeById(face_nodes[1]) + dispVec1 * myDisp,
myFemMesh.getNodeById(face_nodes[2]) + dispVec2 * myDisp]
output_mesh.extend(triangle)
# print("my triangle: ", triangle)
if len(face_nodes) == 4:
dispVec3 = myResults.DisplacementVectors[myResults.NodeNumbers.index(face_nodes[3])]
triangle = [myFemMesh.getNodeById(face_nodes[2]) + dispVec2 * myDisp,
myFemMesh.getNodeById(face_nodes[3]) + dispVec3 * myDisp,
myFemMesh.getNodeById(face_nodes[0]) + dispVec0 * myDisp]
output_mesh.extend(triangle)
# print("my 2. triangle: ", triangle)
else:
for myFace in singleFaces:
face_nodes = faceCodeDict[myFace]
triangle = [myFemMesh.getNodeById(face_nodes[0]),
myFemMesh.getNodeById(face_nodes[1]),
myFemMesh.getNodeById(face_nodes[2])]
output_mesh.extend(triangle)
# print("my triangle: ", triangle)
if len(face_nodes) == 4:
triangle = [myFemMesh.getNodeById(face_nodes[2]),
myFemMesh.getNodeById(face_nodes[3]),
myFemMesh.getNodeById(face_nodes[0])]
output_mesh.extend(triangle)
# print("my 2. triangle: ", triangle)
end_time = time.process_time()
FreeCAD.Console.PrintMessage(
"Mesh by surface search method: {}\n".format(end_time - start_time)
)
return output_mesh
out_mesh = femmesh_2_mesh_disp(FreeCAD.ActiveDocument.ResultMesh.FemMesh, FreeCAD.ActiveDocument.CCX_Results, 100)
import Mesh
Mesh.show(Mesh.Mesh(out_mesh))