From ee08ffe1ad862c4a7ccbe75aa5c0afdef9af2eb8 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Fri, 27 Mar 2020 05:33:58 +0100 Subject: [PATCH] FEM: geom tools, add new module and move some geom tools from mesh tools in --- src/Mod/Fem/CMakeLists.txt | 1 + src/Mod/Fem/femmesh/gmshtools.py | 3 +- src/Mod/Fem/femmesh/meshtools.py | 110 +----------------- src/Mod/Fem/femsolver/calculix/writer.py | 5 +- src/Mod/Fem/femtools/geomtools.py | 140 +++++++++++++++++++++++ 5 files changed, 148 insertions(+), 111 deletions(-) create mode 100644 src/Mod/Fem/femtools/geomtools.py diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index ac7d898d29..18f21804ca 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -226,6 +226,7 @@ SET(FemTools_SRCS femtools/constants.py femtools/errors.py femtools/femutils.py + femtools/geomtools.py femtools/membertools.py femtools/tokrules.py ) diff --git a/src/Mod/Fem/femmesh/gmshtools.py b/src/Mod/Fem/femmesh/gmshtools.py index bf577033f7..7a07276155 100644 --- a/src/Mod/Fem/femmesh/gmshtools.py +++ b/src/Mod/Fem/femmesh/gmshtools.py @@ -37,6 +37,7 @@ from FreeCAD import Units import Fem from . import meshtools from femtools import femutils +from femtools import geomtools class GmshTools(): @@ -451,7 +452,7 @@ class GmshTools(): for eleml in self.ele_length_map: # the method getElement(element) does not return Solid elements ele_shape = meshtools.get_element(self.part_obj, eleml) - ele_vertexes = meshtools.get_vertexes_by_element(self.part_obj.Shape, ele_shape) + ele_vertexes = geomtools.get_vertexes_by_element(self.part_obj.Shape, ele_shape) self.ele_node_map[eleml] = ele_vertexes Console.PrintMessage(" {}\n".format(self.ele_length_map)) Console.PrintMessage(" {}\n".format(self.ele_node_map)) diff --git a/src/Mod/Fem/femmesh/meshtools.py b/src/Mod/Fem/femmesh/meshtools.py index 23bc864b11..fe6293bd87 100644 --- a/src/Mod/Fem/femmesh/meshtools.py +++ b/src/Mod/Fem/femmesh/meshtools.py @@ -29,6 +29,8 @@ __url__ = "http://www.freecadweb.org" import FreeCAD +from femtools import geomtools + # ************************************************************************************************ def get_femnodes_by_femobj_with_references( @@ -2111,55 +2113,6 @@ def find_element_in_shape( FreeCAD.Console.PrintError("Compound is not supported.\n") -# ************************************************************************************************ -def get_vertexes_by_element( - aShape, - anElement -): - # we're going to extend the method find_element_in_shape and return the vertexes - # import Part - ele_vertexes = [] - ele_st = anElement.ShapeType - if ele_st == "Solid" or ele_st == "CompSolid": - for index, solid in enumerate(aShape.Solids): - if is_same_geometry(solid, anElement): - for vele in aShape.Solids[index].Vertexes: - for i, v in enumerate(aShape.Vertexes): - if vele.isSame(v): # use isSame, because orientation could be different - ele_vertexes.append(i) - # FreeCAD.Console.PrintMessage(" " + str(sorted(ele_vertexes)), "\n") - return ele_vertexes - FreeCAD.Console.PrintError( - "Error, Solid " + str(anElement) + " not found in: " + str(aShape) + "\n" - ) - elif ele_st == "Face" or ele_st == "Shell": - for index, face in enumerate(aShape.Faces): - if is_same_geometry(face, anElement): - for vele in aShape.Faces[index].Vertexes: - for i, v in enumerate(aShape.Vertexes): - if vele.isSame(v): # use isSame, because orientation could be different - ele_vertexes.append(i) - # FreeCAD.Console.PrintMessage(" " + str(sorted(ele_vertexes)) + "\n") - return ele_vertexes - elif ele_st == "Edge" or ele_st == "Wire": - for index, edge in enumerate(aShape.Edges): - if is_same_geometry(edge, anElement): - for vele in aShape.Edges[index].Vertexes: - for i, v in enumerate(aShape.Vertexes): - if vele.isSame(v): # use isSame, because orientation could be different - ele_vertexes.append(i) - # FreeCAD.Console.PrintMessage(" " + str(sorted(ele_vertexes)) + "\n") - return ele_vertexes - elif ele_st == "Vertex": - for index, vertex in enumerate(aShape.Vertexes): - if is_same_geometry(vertex, anElement): - ele_vertexes.append(index) - # FreeCAD.Console.PrintMessage(" " + str(sorted(ele_vertexes)) + "\n") - return ele_vertexes - elif ele_st == "Compound": - FreeCAD.Console.PrintError("Compound is not supported.\n") - - # ************************************************************************************************ def is_same_geometry( shape1, @@ -2374,65 +2327,6 @@ def get_three_non_colinear_nodes( return [node_1, node_2, node_3] -# ************************************************************************************************ -def get_rectangular_coords( - obj -): - from math import cos, sin, radians - A = [1, 0, 0] - B = [0, 1, 0] - a_x = A[0] - a_y = A[1] - a_z = A[2] - b_x = B[0] - b_y = B[1] - b_z = B[2] - x_rot = radians(obj.X_rot) - y_rot = radians(obj.Y_rot) - z_rot = radians(obj.Z_rot) - if obj.X_rot != 0: - a_y = A[1] * cos(x_rot) + A[2] * sin(x_rot) - a_z = A[2] * cos(x_rot) - A[1] * sin(x_rot) - b_y = B[1] * cos(x_rot) + B[2] * sin(x_rot) - b_z = B[2] * cos(x_rot) - B[1] * sin(x_rot) - if obj.Y_rot != 0: - a_x = A[0] * cos(y_rot) - A[2] * sin(y_rot) - a_z = A[2] * cos(y_rot) + A[0] * sin(y_rot) - b_x = B[0] * cos(y_rot) - B[2] * sin(y_rot) - b_z = B[2] * cos(y_rot) + B[0] * sin(z_rot) - if obj.Z_rot != 0: - a_x = A[0] * cos(z_rot) + A[1] * sin(z_rot) - a_y = A[1] * cos(z_rot) - A[0] * sin(z_rot) - b_x = B[0] * cos(z_rot) + B[1] * sin(z_rot) - b_y = B[1] * cos(z_rot) - B[0] * sin(z_rot) - A = [a_x, a_y, a_z] - B = [b_x, b_y, b_z] - A_coords = str(round(A[0], 4)) + "," + str(round(A[1], 4)) + "," + str(round(A[2], 4)) - B_coords = str(round(B[0], 4)) + "," + str(round(B[1], 4)) + "," + str(round(B[2], 4)) - coords = A_coords + "," + B_coords - return coords - - -# ************************************************************************************************ -def get_cylindrical_coords( - obj -): - vec = obj.Axis - base = obj.BasePoint - Ax = base[0] + 10 * vec[0] - Ay = base[1] + 10 * vec[1] - Az = base[2] + 10 * vec[2] - Bx = base[0] - 10 * vec[0] - By = base[1] - 10 * vec[1] - Bz = base[2] - 10 * vec[2] - A = [Ax, Ay, Az] - B = [Bx, By, Bz] - A_coords = str(A[0]) + "," + str(A[1]) + "," + str(A[2]) - B_coords = str(B[0]) + "," + str(B[1]) + "," + str(B[2]) - coords = A_coords + "," + B_coords - return coords - - # ************************************************************************************************ def write_D_network_element_to_inputfile( fileName diff --git a/src/Mod/Fem/femsolver/calculix/writer.py b/src/Mod/Fem/femsolver/calculix/writer.py index f73228f8f7..cda2e38200 100644 --- a/src/Mod/Fem/femsolver/calculix/writer.py +++ b/src/Mod/Fem/femsolver/calculix/writer.py @@ -39,6 +39,7 @@ import FreeCAD from .. import writerbase from femmesh import meshtools +from femtools import geomtools class FemInputWriterCcx(writerbase.FemInputWriter): @@ -1084,11 +1085,11 @@ class FemInputWriterCcx(writerbase.FemInputWriter): f.write("** " + trans_obj.Label + "\n") if trans_obj.TransformType == "Rectangular": f.write("*TRANSFORM, NSET=Rect" + trans_obj.Name + ", TYPE=R\n") - coords = meshtools.get_rectangular_coords(trans_obj) + coords = geomtools.get_rectangular_coords(trans_obj) f.write(coords + "\n") elif trans_obj.TransformType == "Cylindrical": f.write("*TRANSFORM, NSET=Cylin" + trans_obj.Name + ", TYPE=C\n") - coords = meshtools.get_cylindrical_coords(trans_obj) + coords = geomtools.get_cylindrical_coords(trans_obj) f.write(coords + "\n") def write_constraints_selfweight(self, f): diff --git a/src/Mod/Fem/femtools/geomtools.py b/src/Mod/Fem/femtools/geomtools.py new file mode 100644 index 0000000000..73df2688c9 --- /dev/null +++ b/src/Mod/Fem/femtools/geomtools.py @@ -0,0 +1,140 @@ +# *************************************************************************** +# * Copyright (c) 2020 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__ = "FEM geometry tools" +__author__ = "Markus Hovorka, Bernd Hahnebach" +__url__ = "http://www.freecadweb.org" + +import FreeCAD + +from . import femutils + + +# ************************************************************************************************ +def get_vertexes_by_element( + aShape, + anElement +): + # we're going to extend the method find_element_in_shape and return the vertexes + # import Part + ele_vertexes = [] + ele_st = anElement.ShapeType + if ele_st == "Solid" or ele_st == "CompSolid": + for index, solid in enumerate(aShape.Solids): + if is_same_geometry(solid, anElement): + for vele in aShape.Solids[index].Vertexes: + for i, v in enumerate(aShape.Vertexes): + if vele.isSame(v): # use isSame, because orientation could be different + ele_vertexes.append(i) + # FreeCAD.Console.PrintMessage(" " + str(sorted(ele_vertexes)), "\n") + return ele_vertexes + FreeCAD.Console.PrintError( + "Error, Solid " + str(anElement) + " not found in: " + str(aShape) + "\n" + ) + elif ele_st == "Face" or ele_st == "Shell": + for index, face in enumerate(aShape.Faces): + if is_same_geometry(face, anElement): + for vele in aShape.Faces[index].Vertexes: + for i, v in enumerate(aShape.Vertexes): + if vele.isSame(v): # use isSame, because orientation could be different + ele_vertexes.append(i) + # FreeCAD.Console.PrintMessage(" " + str(sorted(ele_vertexes)) + "\n") + return ele_vertexes + elif ele_st == "Edge" or ele_st == "Wire": + for index, edge in enumerate(aShape.Edges): + if is_same_geometry(edge, anElement): + for vele in aShape.Edges[index].Vertexes: + for i, v in enumerate(aShape.Vertexes): + if vele.isSame(v): # use isSame, because orientation could be different + ele_vertexes.append(i) + # FreeCAD.Console.PrintMessage(" " + str(sorted(ele_vertexes)) + "\n") + return ele_vertexes + elif ele_st == "Vertex": + for index, vertex in enumerate(aShape.Vertexes): + if is_same_geometry(vertex, anElement): + ele_vertexes.append(index) + # FreeCAD.Console.PrintMessage(" " + str(sorted(ele_vertexes)) + "\n") + return ele_vertexes + elif ele_st == "Compound": + FreeCAD.Console.PrintError("Compound is not supported.\n") + + +# ************************************************************************************************ +def get_rectangular_coords( + obj +): + from math import cos, sin, radians + A = [1, 0, 0] + B = [0, 1, 0] + a_x = A[0] + a_y = A[1] + a_z = A[2] + b_x = B[0] + b_y = B[1] + b_z = B[2] + x_rot = radians(obj.X_rot) + y_rot = radians(obj.Y_rot) + z_rot = radians(obj.Z_rot) + if obj.X_rot != 0: + a_y = A[1] * cos(x_rot) + A[2] * sin(x_rot) + a_z = A[2] * cos(x_rot) - A[1] * sin(x_rot) + b_y = B[1] * cos(x_rot) + B[2] * sin(x_rot) + b_z = B[2] * cos(x_rot) - B[1] * sin(x_rot) + if obj.Y_rot != 0: + a_x = A[0] * cos(y_rot) - A[2] * sin(y_rot) + a_z = A[2] * cos(y_rot) + A[0] * sin(y_rot) + b_x = B[0] * cos(y_rot) - B[2] * sin(y_rot) + b_z = B[2] * cos(y_rot) + B[0] * sin(z_rot) + if obj.Z_rot != 0: + a_x = A[0] * cos(z_rot) + A[1] * sin(z_rot) + a_y = A[1] * cos(z_rot) - A[0] * sin(z_rot) + b_x = B[0] * cos(z_rot) + B[1] * sin(z_rot) + b_y = B[1] * cos(z_rot) - B[0] * sin(z_rot) + A = [a_x, a_y, a_z] + B = [b_x, b_y, b_z] + A_coords = str(round(A[0], 4)) + "," + str(round(A[1], 4)) + "," + str(round(A[2], 4)) + B_coords = str(round(B[0], 4)) + "," + str(round(B[1], 4)) + "," + str(round(B[2], 4)) + coords = A_coords + "," + B_coords + return coords + + +# ************************************************************************************************ +def get_cylindrical_coords( + obj +): + vec = obj.Axis + base = obj.BasePoint + Ax = base[0] + 10 * vec[0] + Ay = base[1] + 10 * vec[1] + Az = base[2] + 10 * vec[2] + Bx = base[0] - 10 * vec[0] + By = base[1] - 10 * vec[1] + Bz = base[2] - 10 * vec[2] + A = [Ax, Ay, Az] + B = [Bx, By, Bz] + A_coords = str(A[0]) + "," + str(A[1]) + "," + str(A[2]) + B_coords = str(B[0]) + "," + str(B[1]) + "," + str(B[2]) + coords = A_coords + "," + B_coords + return coords + +