From bbdaa62890aa35516db4e6328784fff66e756940 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Fri, 17 Apr 2020 22:46:14 +0200 Subject: [PATCH] FEM: mesh export, add export to Python module --- src/Mod/Fem/CMakeLists.txt | 1 + src/Mod/Fem/Init.py | 2 + src/Mod/Fem/feminout/importPyMesh.py | 148 +++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 src/Mod/Fem/feminout/importPyMesh.py diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 18f21804ca..304ee9d7e3 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -72,6 +72,7 @@ SET(FemInOut_SRCS feminout/importCcxFrdResults.py feminout/importFenicsMesh.py feminout/importInpMesh.py + feminout/importPyMesh.py feminout/importToolsFem.py feminout/importVTKResults.py feminout/importYamlJsonMesh.py diff --git a/src/Mod/Fem/Init.py b/src/Mod/Fem/Init.py index f12096a6fa..d06b24904f 100644 --- a/src/Mod/Fem/Init.py +++ b/src/Mod/Fem/Init.py @@ -27,6 +27,8 @@ import FreeCAD +FreeCAD.addExportType("FEM mesh Python (*.meshpy)", "feminout.importPyMesh") + FreeCAD.addExportType("FEM mesh TetGen (*.poly)", "feminout.convert2TetGen") # see FemMesh::read() and FemMesh::write() methods in src/Mod/Fem/App/FemMesh.cpp diff --git a/src/Mod/Fem/feminout/importPyMesh.py b/src/Mod/Fem/feminout/importPyMesh.py new file mode 100644 index 0000000000..7c64bec66a --- /dev/null +++ b/src/Mod/Fem/feminout/importPyMesh.py @@ -0,0 +1,148 @@ +# *************************************************************************** +# * Copyright (c) 2016 Bernd Hahnebach * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +__title__ = "FreeCAD Python Mesh reader and writer" +__author__ = "Bernd Hahnebach" +__url__ = "http://www.freecadweb.org" + +## @package importPyMesh +# \ingroup FEM +# \brief FreeCAD Python Mesh reader and writer for FEM workbench + +import FreeCAD +from femmesh import meshtools + +# ************************************************************************************************ +# ********* generic FreeCAD import and export methods ******************************************** +# names are fix given from FreeCAD, these methods are called from FreeCAD +# they are set in FEM modules Init.py + +if open.__module__ == "__builtin__": + # because we'll redefine open below (Python2) + pyopen = open +elif open.__module__ == "io": + # because we'll redefine open below (Python3) + pyopen = open + + +# export mesh to python +def export( + objectslist, + filename +): + "called when freecad exports a file" + if len(objectslist) != 1: + FreeCAD.Console.PrintError("This exporter can only export one object.\n") + return + obj = objectslist[0] + if not obj.isDerivedFrom("Fem::FemMeshObject"): + FreeCAD.Console.PrintError("No FEM mesh object selected.\n") + return + femnodes_mesh = obj.FemMesh.Nodes + femelement_table = meshtools.get_femelement_table(obj.FemMesh) + if meshtools.is_solid_femmesh(obj.FemMesh): + fem_mesh_type = "Solid" + elif meshtools.is_face_femmesh(obj.FemMesh): + fem_mesh_type = "Face" + elif meshtools.is_edge_femmesh(obj.FemMesh): + fem_mesh_type = "Edge" + else: + FreeCAD.Console.PrintError("Export of this FEM mesh to Python not supported.\n") + return + f = pyopen(filename, "w") + write_python_mesh_to_file(femnodes_mesh, femelement_table, fem_mesh_type, f) + f.close() + + +# ************************************************************************************************ +# ********* module specific methods ************************************************************** +# writer: +# - a method directly writes a FemMesh to the mesh file +# - a method takes a file handle, mesh data and writes to the file handle + +# ********* writer ******************************************************************************* + +def write( + fem_mesh, + filename +): + """directly write a FemMesh to a Python mesh file + fem_mesh: a FemMesh""" + + if not fem_mesh.isDerivedFrom("Fem::FemMesh"): + FreeCAD.Console.PrintError("Not a FemMesh was given as parameter.\n") + return + femnodes_mesh = fem_mesh.Nodes + femelement_table = meshtools.get_femelement_table(fem_mesh) + if meshtools.is_solid_femmesh(fem_mesh): + fem_mesh_type = "Solid" + elif meshtools.is_face_femmesh(fem_mesh): + fem_mesh_type = "Face" + elif meshtools.is_edge_femmesh(fem_mesh): + fem_mesh_type = "Edge" + else: + FreeCAD.Console.PrintError("Export of this FEM mesh to Python not supported.\n") + return + f = pyopen(filename, "w") + write_python_mesh_to_file(femnodes_mesh, femelement_table, fem_mesh_type, f) + f.close() + + +def write_python_mesh_to_file(femnodes_mesh, femelement_table, fem_mesh_type, f): + + mesh_name = "femmesh" + + # nodes + f.write("def create_nodes(femmesh):\n") + f.write(" # nodes\n") + for node in femnodes_mesh: + # print(node, ' --> ', femnodes_mesh[node]) + vec = femnodes_mesh[node] + f.write( + " {0}.addNode({1}, {2}, {3}, {4})\n" + .format(mesh_name, vec.x, vec.y, vec.z, node) + ) + f.write(" return True\n") + f.write("\n\n") + + # elements + f.write("def create_elements(femmesh):\n") + f.write(" # elements\n") + for element in femelement_table: + # print(element, ' --> ', femelement_table[element]) + if fem_mesh_type == "Solid": + f.write( + " {0}.addVolume({1}, {2})\n" + .format(mesh_name, list(femelement_table[element]), element) + ) + elif fem_mesh_type == "Face": + f.write( + " {0}.addFace({1}, {2})\n" + .format(mesh_name, list(femelement_table[element]), element) + ) + elif fem_mesh_type == "Edge": + f.write( + " {0}.addEdge({1}, {2})\n" + .format(mesh_name, list(femelement_table[element]), element) + ) + f.write(" return True\n")