Merge branch 'FreeCAD:master' into master
This commit is contained in:
@@ -48,10 +48,17 @@ SET(FemExamples_SRCS
|
||||
femexamples/buckling_platebuckling.py
|
||||
femexamples/buckling_lateraltorsionalbuckling.py
|
||||
femexamples/ccx_buckling_flexuralbuckling.py
|
||||
femexamples/ccx_cantilever_base.py
|
||||
femexamples/ccx_cantilever_base_edge.py
|
||||
femexamples/ccx_cantilever_base_face.py
|
||||
femexamples/ccx_cantilever_base_solid.py
|
||||
femexamples/ccx_cantilever_ele_hexa20.py
|
||||
femexamples/ccx_cantilever_ele_tetra4.py
|
||||
femexamples/ccx_cantilever_ele_tria3.py
|
||||
femexamples/ccx_cantilever_ele_tria6.py
|
||||
femexamples/ccx_cantilever_ele_seg2.py
|
||||
femexamples/ccx_cantilever_ele_seg3.py
|
||||
femexamples/ccx_cantilever_faceload.py
|
||||
femexamples/ccx_cantilever_nodeload.py
|
||||
femexamples/ccx_cantilever_hexa20faceload.py
|
||||
femexamples/ccx_cantilever_prescribeddisplacement.py
|
||||
femexamples/constraint_centrif.py
|
||||
femexamples/constraint_contact_shell_shell.py
|
||||
@@ -87,7 +94,11 @@ SET(FemExampleMeshes_SRCS
|
||||
femexamples/meshes/mesh_buckling_ibeam_tria6.py
|
||||
femexamples/meshes/mesh_buckling_plate_tria6.py
|
||||
femexamples/meshes/mesh_canticcx_hexa20.py
|
||||
femexamples/meshes/mesh_canticcx_seg2.py
|
||||
femexamples/meshes/mesh_canticcx_seg3.py
|
||||
femexamples/meshes/mesh_canticcx_tetra10.py
|
||||
femexamples/meshes/mesh_canticcx_tria3.py
|
||||
femexamples/meshes/mesh_canticcx_tria6.py
|
||||
femexamples/meshes/mesh_capacitance_two_balls_tetra10.py
|
||||
femexamples/meshes/mesh_constraint_centrif_tetra10.py
|
||||
femexamples/meshes/mesh_constraint_tie_tetra10.py
|
||||
@@ -287,10 +298,10 @@ SET(FemTestsCcx_SRCS
|
||||
femtest/data/calculix/box.FCStd
|
||||
femtest/data/calculix/ccx_buckling_flexuralbuckling.dat
|
||||
femtest/data/calculix/ccx_buckling_flexuralbuckling.inp
|
||||
femtest/data/calculix/ccxcantilever_faceload.inp
|
||||
femtest/data/calculix/ccxcantilever_hexa20.inp
|
||||
femtest/data/calculix/ccxcantilever_nodeload.inp
|
||||
femtest/data/calculix/ccxcantilever_prescribeddisplacement.inp
|
||||
femtest/data/calculix/ccx_cantilever_faceload.inp
|
||||
femtest/data/calculix/ccx_cantilever_ele_hexa20.inp
|
||||
femtest/data/calculix/ccx_cantilever_nodeload.inp
|
||||
femtest/data/calculix/ccx_cantilever_prescribeddisplacement.inp
|
||||
femtest/data/calculix/constraint_centrif.inp
|
||||
femtest/data/calculix/constraint_contact_shell_shell.FCStd
|
||||
femtest/data/calculix/constraint_contact_shell_shell.inp
|
||||
@@ -353,41 +364,41 @@ SET(FemTestsZ88Main_SRCS
|
||||
|
||||
SET(FemTestsZ88Ccxcantifl_SRCS
|
||||
femtest/data/z88/__init__.py
|
||||
femtest/data/z88/ccxcantilever_faceload/51.txt
|
||||
femtest/data/z88/ccxcantilever_faceload/z88.dyn
|
||||
femtest/data/z88/ccxcantilever_faceload/z88elp.txt
|
||||
femtest/data/z88/ccxcantilever_faceload/z88i1.txt
|
||||
femtest/data/z88/ccxcantilever_faceload/z88i2.txt
|
||||
femtest/data/z88/ccxcantilever_faceload/z88i5.txt
|
||||
femtest/data/z88/ccxcantilever_faceload/z88int.txt
|
||||
femtest/data/z88/ccxcantilever_faceload/z88man.txt
|
||||
femtest/data/z88/ccxcantilever_faceload/z88mat.txt
|
||||
femtest/data/z88/ccx_cantilever_faceload/51.txt
|
||||
femtest/data/z88/ccx_cantilever_faceload/z88.dyn
|
||||
femtest/data/z88/ccx_cantilever_faceload/z88elp.txt
|
||||
femtest/data/z88/ccx_cantilever_faceload/z88i1.txt
|
||||
femtest/data/z88/ccx_cantilever_faceload/z88i2.txt
|
||||
femtest/data/z88/ccx_cantilever_faceload/z88i5.txt
|
||||
femtest/data/z88/ccx_cantilever_faceload/z88int.txt
|
||||
femtest/data/z88/ccx_cantilever_faceload/z88man.txt
|
||||
femtest/data/z88/ccx_cantilever_faceload/z88mat.txt
|
||||
)
|
||||
|
||||
SET(FemTestsZ88Ccxcantihex_SRCS
|
||||
femtest/data/z88/__init__.py
|
||||
femtest/data/z88/ccxcantilever_hexa20/51.txt
|
||||
femtest/data/z88/ccxcantilever_hexa20/z88.dyn
|
||||
femtest/data/z88/ccxcantilever_hexa20/z88elp.txt
|
||||
femtest/data/z88/ccxcantilever_hexa20/z88i1.txt
|
||||
femtest/data/z88/ccxcantilever_hexa20/z88i2.txt
|
||||
femtest/data/z88/ccxcantilever_hexa20/z88i5.txt
|
||||
femtest/data/z88/ccxcantilever_hexa20/z88int.txt
|
||||
femtest/data/z88/ccxcantilever_hexa20/z88man.txt
|
||||
femtest/data/z88/ccxcantilever_hexa20/z88mat.txt
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/51.txt
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/z88.dyn
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/z88elp.txt
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/z88i1.txt
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/z88i2.txt
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/z88i5.txt
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/z88int.txt
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/z88man.txt
|
||||
femtest/data/z88/ccx_cantilever_ele_hexa20/z88mat.txt
|
||||
)
|
||||
|
||||
SET(FemTestsZ88Ccxcantinl_SRCS
|
||||
femtest/data/z88/__init__.py
|
||||
femtest/data/z88/ccxcantilever_nodeload/51.txt
|
||||
femtest/data/z88/ccxcantilever_nodeload/z88.dyn
|
||||
femtest/data/z88/ccxcantilever_nodeload/z88elp.txt
|
||||
femtest/data/z88/ccxcantilever_nodeload/z88i1.txt
|
||||
femtest/data/z88/ccxcantilever_nodeload/z88i2.txt
|
||||
femtest/data/z88/ccxcantilever_nodeload/z88i5.txt
|
||||
femtest/data/z88/ccxcantilever_nodeload/z88int.txt
|
||||
femtest/data/z88/ccxcantilever_nodeload/z88man.txt
|
||||
femtest/data/z88/ccxcantilever_nodeload/z88mat.txt
|
||||
femtest/data/z88/ccx_cantilever_nodeload/51.txt
|
||||
femtest/data/z88/ccx_cantilever_nodeload/z88.dyn
|
||||
femtest/data/z88/ccx_cantilever_nodeload/z88elp.txt
|
||||
femtest/data/z88/ccx_cantilever_nodeload/z88i1.txt
|
||||
femtest/data/z88/ccx_cantilever_nodeload/z88i2.txt
|
||||
femtest/data/z88/ccx_cantilever_nodeload/z88i5.txt
|
||||
femtest/data/z88/ccx_cantilever_nodeload/z88int.txt
|
||||
femtest/data/z88/ccx_cantilever_nodeload/z88man.txt
|
||||
femtest/data/z88/ccx_cantilever_nodeload/z88mat.txt
|
||||
)
|
||||
|
||||
SET(FemTools_SRCS
|
||||
@@ -462,9 +473,9 @@ INSTALL(FILES ${FemTestsElmer_SRCS} DESTINATION Mod/Fem/femtest/data/elmer)
|
||||
INSTALL(FILES ${FemTestsMesh_SRCS} DESTINATION Mod/Fem/femtest/data/mesh)
|
||||
INSTALL(FILES ${FemTestsOpen_SRCS} DESTINATION Mod/Fem/femtest/data/open)
|
||||
INSTALL(FILES ${FemTestsZ88Main_SRCS} DESTINATION Mod/Fem/femtest/data/z88)
|
||||
INSTALL(FILES ${FemTestsZ88Ccxcantifl_SRCS} DESTINATION Mod/Fem/femtest/data/z88/ccxcantilever_faceload)
|
||||
INSTALL(FILES ${FemTestsZ88Ccxcantihex_SRCS} DESTINATION Mod/Fem/femtest/data/z88/ccxcantilever_hexa20)
|
||||
INSTALL(FILES ${FemTestsZ88Ccxcantinl_SRCS} DESTINATION Mod/Fem/femtest/data/z88/ccxcantilever_nodeload)
|
||||
INSTALL(FILES ${FemTestsZ88Ccxcantifl_SRCS} DESTINATION Mod/Fem/femtest/data/z88/ccx_cantilever_faceload)
|
||||
INSTALL(FILES ${FemTestsZ88Ccxcantihex_SRCS} DESTINATION Mod/Fem/femtest/data/z88/ccx_cantilever_ele_hexa20)
|
||||
INSTALL(FILES ${FemTestsZ88Ccxcantinl_SRCS} DESTINATION Mod/Fem/femtest/data/z88/ccx_cantilever_nodeload)
|
||||
INSTALL(FILES ${FemTools_SRCS} DESTINATION Mod/Fem/femtools)
|
||||
|
||||
|
||||
|
||||
138
src/Mod/Fem/femexamples/ccx_cantilever_base_edge.py
Normal file
138
src/Mod/Fem/femexamples/ccx_cantilever_base_edge.py
Normal file
@@ -0,0 +1,138 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2020 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * Copyright (c) 2020 Sudhanshu Dubey <sudhanshu.thethunder@gmail.com *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
|
||||
import Fem
|
||||
import ObjectsFem
|
||||
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
def setup_cantilever_base_edge(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
doc = init_doc()
|
||||
|
||||
# geometric objects
|
||||
# load line
|
||||
load_line = doc.addObject("Part::Line", "LoadLine")
|
||||
load_line.X1 = 0
|
||||
load_line.Y1 = 0
|
||||
load_line.Z1 = 1000
|
||||
load_line.X2 = 0
|
||||
load_line.Y2 = 0
|
||||
load_line.Z2 = 0
|
||||
|
||||
# cantilever line
|
||||
geom_obj = doc.addObject("Part::Line", "CantileverLine")
|
||||
geom_obj.X1 = 0
|
||||
geom_obj.Y1 = 500
|
||||
geom_obj.Z1 = 500
|
||||
geom_obj.X2 = 8000
|
||||
geom_obj.Y2 = 500
|
||||
geom_obj.Z2 = 500
|
||||
|
||||
doc.recompute()
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
geom_obj.ViewObject.Document.activeView().viewAxonometric()
|
||||
geom_obj.ViewObject.Document.activeView().fitAll()
|
||||
|
||||
# analysis
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
|
||||
# solver
|
||||
if solvertype == "calculix":
|
||||
solver_obj = ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX")
|
||||
elif solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Not known or not supported solver type: {}. "
|
||||
"No solver object was created.\n".format(solvertype)
|
||||
)
|
||||
if solvertype == "calculix" or solvertype == "ccxtools":
|
||||
solver_obj.AnalysisType = "static"
|
||||
solver_obj.GeometricalNonlinearity = "linear"
|
||||
solver_obj.ThermoMechSteadyState = False
|
||||
solver_obj.MatrixSolverType = "default"
|
||||
solver_obj.IterationsControlParameterTimeUse = False
|
||||
solver_obj.SplitInputWriter = False
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# beam section
|
||||
beamsection_obj = ObjectsFem.makeElementGeometry1D(
|
||||
doc,
|
||||
sectiontype="Rectangular",
|
||||
width=1000.0,
|
||||
height=1000.0,
|
||||
name="BeamCrossSection"
|
||||
)
|
||||
analysis.addObject(beamsection_obj)
|
||||
|
||||
# material
|
||||
material_obj = ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial")
|
||||
mat = material_obj.Material
|
||||
mat["Name"] = "Calculix-Steel"
|
||||
mat["YoungsModulus"] = "210000 MPa"
|
||||
mat["PoissonRatio"] = "0.30"
|
||||
material_obj.Material = mat
|
||||
analysis.addObject(material_obj)
|
||||
|
||||
# constraint fixed
|
||||
con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed")
|
||||
con_fixed.References = [(geom_obj, "Vertex1")]
|
||||
analysis.addObject(con_fixed)
|
||||
|
||||
# constraint force
|
||||
con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce")
|
||||
con_force.References = [(geom_obj, "Vertex2")]
|
||||
con_force.Force = 9000000.0 # 9'000'000 N = 9 MN
|
||||
con_force.Direction = (load_line, ["Edge1"])
|
||||
con_force.Reversed = False
|
||||
analysis.addObject(con_force)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_canticcx_seg3 import create_nodes, create_elements
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "1D"
|
||||
femmesh_obj.CharacteristicLengthMax = "1750.0 mm"
|
||||
femmesh_obj.CharacteristicLengthMin = "1750.0 mm"
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
121
src/Mod/Fem/femexamples/ccx_cantilever_base_face.py
Normal file
121
src/Mod/Fem/femexamples/ccx_cantilever_base_face.py
Normal file
@@ -0,0 +1,121 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
|
||||
import Fem
|
||||
import ObjectsFem
|
||||
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
def setup_cantilever_base_face(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
doc = init_doc()
|
||||
|
||||
# geometric objects
|
||||
geom_obj = doc.addObject("Part::Plane", "CanileverPlate")
|
||||
geom_obj.Width = 1000
|
||||
geom_obj.Length = 8000
|
||||
geom_obj.Placement = FreeCAD.Placement(
|
||||
FreeCAD.Vector(0, 500, 0),
|
||||
FreeCAD.Rotation(0, 0, 90),
|
||||
FreeCAD.Vector(1, 0, 0),
|
||||
)
|
||||
|
||||
doc.recompute()
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
geom_obj.ViewObject.Document.activeView().viewAxonometric()
|
||||
geom_obj.ViewObject.Document.activeView().fitAll()
|
||||
|
||||
# analysis
|
||||
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
|
||||
|
||||
# solver
|
||||
if solvertype == "calculix":
|
||||
solver_obj = ObjectsFem.makeSolverCalculix(doc, "SolverCalculiX")
|
||||
elif solvertype == "ccxtools":
|
||||
solver_obj = ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiXccxTools")
|
||||
solver_obj.WorkingDir = u""
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Not known or not supported solver type: {}. "
|
||||
"No solver object was created.\n".format(solvertype)
|
||||
)
|
||||
if solvertype == "calculix" or solvertype == "ccxtools":
|
||||
solver_obj.AnalysisType = "static"
|
||||
solver_obj.GeometricalNonlinearity = "linear"
|
||||
solver_obj.ThermoMechSteadyState = False
|
||||
solver_obj.MatrixSolverType = "default"
|
||||
solver_obj.IterationsControlParameterTimeUse = False
|
||||
solver_obj.SplitInputWriter = False
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# shell thickness
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 1000, 'Thickness')
|
||||
analysis.addObject(thickness_obj)
|
||||
|
||||
# material
|
||||
material_obj = ObjectsFem.makeMaterialSolid(doc, "MechanicalMaterial")
|
||||
mat = material_obj.Material
|
||||
mat["Name"] = "Calculix-Steel"
|
||||
mat["YoungsModulus"] = "210000 MPa"
|
||||
mat["PoissonRatio"] = "0.30"
|
||||
material_obj.Material = mat
|
||||
analysis.addObject(material_obj)
|
||||
|
||||
# constraint fixed
|
||||
con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed")
|
||||
con_fixed.References = [(geom_obj, "Edge1")]
|
||||
analysis.addObject(con_fixed)
|
||||
|
||||
# constraint force
|
||||
con_force = ObjectsFem.makeConstraintForce(doc, "ConstraintForce")
|
||||
con_force.References = [(geom_obj, "Edge3")]
|
||||
con_force.Force = 9000000.0 # 9'000'000 N = 9 MN
|
||||
con_force.Direction = (geom_obj, ["Edge3"])
|
||||
con_force.Reversed = True
|
||||
analysis.addObject(con_force)
|
||||
|
||||
# mesh
|
||||
from .meshes.mesh_canticcx_tria6 import create_nodes, create_elements
|
||||
fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
|
||||
femmesh_obj.FemMesh = fem_mesh
|
||||
femmesh_obj.Part = geom_obj
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
femmesh_obj.CharacteristicLengthMax = "500.0 mm"
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
@@ -31,7 +31,7 @@ from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
def setup_cantileverbase(doc=None, solvertype="ccxtools"):
|
||||
def setup_cantilever_base_solid(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
@@ -34,7 +34,7 @@ from .manager import init_doc
|
||||
|
||||
def get_information():
|
||||
return {
|
||||
"name": "CCX cantilever hexa20 face load",
|
||||
"name": "CCX cantilever hexa20 solid elements",
|
||||
"meshtype": "solid",
|
||||
"meshelement": "Hexa20",
|
||||
"constraints": ["fixed", "force"],
|
||||
@@ -48,11 +48,12 @@ def get_explanation(header=""):
|
||||
return header + """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_hexa20faceload import setup
|
||||
from femexamples.ccx_cantilever_ele_hexa20 import setup
|
||||
setup()
|
||||
|
||||
|
||||
See forum topic post:
|
||||
hexa20 elements and face load
|
||||
...
|
||||
|
||||
"""
|
||||
@@ -68,10 +69,15 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# just keep the following line and change text string in get_explanation method
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup cantilever faceload and exchange the mesh
|
||||
# setup cantilever faceload
|
||||
doc = setup_with_faceload(doc, solvertype)
|
||||
femmesh_obj = doc.getObject(get_meshname())
|
||||
|
||||
# delete explanation object wrongly added with setup faceload
|
||||
if hasattr(doc, "Explanation_Report001"):
|
||||
doc.removeObject("Explanation_Report001")
|
||||
doc.recompute()
|
||||
|
||||
# load the hexa20 mesh
|
||||
from .meshes.mesh_canticcx_hexa20 import create_nodes, create_elements
|
||||
new_fem_mesh = Fem.FemMesh()
|
||||
97
src/Mod/Fem/femexamples/ccx_cantilever_ele_seg2.py
Normal file
97
src/Mod/Fem/femexamples/ccx_cantilever_ele_seg2.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
|
||||
import Fem
|
||||
|
||||
from . import manager
|
||||
from .ccx_cantilever_base_edge import setup_cantilever_base_edge
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
def get_information():
|
||||
return {
|
||||
"name": "CCX cantilever seg2 beam elements",
|
||||
"meshtype": "edge",
|
||||
"meshelement": "Seg2",
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["calculix"],
|
||||
"material": "solid",
|
||||
"equation": "mechanical"
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_seg2 import setup
|
||||
setup()
|
||||
|
||||
|
||||
See forum topic post (for seg3):
|
||||
https://forum.freecadweb.org/viewtopic.php?f=18&t=16044
|
||||
|
||||
CalculiX cantilever modeled with seg2 beam elements
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
doc = init_doc()
|
||||
|
||||
# explanation object
|
||||
# just keep the following line and change text string in get_explanation method
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup CalculiX cantilever
|
||||
doc = setup_cantilever_base_edge(doc, solvertype)
|
||||
femmesh_obj = doc.getObject(get_meshname())
|
||||
|
||||
# load the seg2 mesh
|
||||
from .meshes.mesh_canticcx_seg2 import create_nodes, create_elements
|
||||
new_fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
|
||||
# overwrite mesh with the seg2 mesh
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "1D"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
femmesh_obj.CharacteristicLengthMax = "150.0 mm"
|
||||
femmesh_obj.CharacteristicLengthMin = "150.0 mm"
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
71
src/Mod/Fem/femexamples/ccx_cantilever_ele_seg3.py
Normal file
71
src/Mod/Fem/femexamples/ccx_cantilever_ele_seg3.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
from . import manager
|
||||
from .ccx_cantilever_base_edge import setup_cantilever_base_edge
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
def get_information():
|
||||
return {
|
||||
"name": "CCX cantilever seg3 beam elements",
|
||||
"meshtype": "edge",
|
||||
"meshelement": "Seg3",
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["calculix"],
|
||||
"material": "solid",
|
||||
"equation": "mechanical"
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_seg3 import setup
|
||||
setup()
|
||||
|
||||
|
||||
See forum topic post:
|
||||
https://forum.freecadweb.org/viewtopic.php?f=18&t=16044
|
||||
|
||||
CalculiX cantilever modeled with seg3 beam elements
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
doc = init_doc()
|
||||
|
||||
# explanation object
|
||||
# just keep the following line and change text string in get_explanation method
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup CalculiX cantilever
|
||||
doc = setup_cantilever_base_edge(doc, solvertype)
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
83
src/Mod/Fem/femexamples/ccx_cantilever_ele_tetra4.py
Normal file
83
src/Mod/Fem/femexamples/ccx_cantilever_ele_tetra4.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2019 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * Copyright (c) 2020 Sudhanshu Dubey <sudhanshu.thethunder@gmail.com> *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import Fem
|
||||
|
||||
from . import manager
|
||||
from .ccx_cantilever_faceload import setup as setup_with_faceload
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
def get_information():
|
||||
return {
|
||||
"name": "CCX cantilever tetra4 solid elements",
|
||||
"meshtype": "solid",
|
||||
"meshelement": "Tetra4",
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["calculix", "elmer", "z88"],
|
||||
"material": "solid",
|
||||
"equation": "mechanical"
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_tetra4 import setup
|
||||
setup()
|
||||
|
||||
|
||||
Tetra4 elements. There are really a lot needed thus mesh is cleared.
|
||||
Mesh before run the example.
|
||||
...
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
doc = init_doc()
|
||||
|
||||
# explanation object
|
||||
# just keep the following line and change text string in get_explanation method
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup cantilever faceload and exchange the mesh
|
||||
doc = setup_with_faceload(doc, solvertype)
|
||||
femmesh_obj = doc.getObject(get_meshname())
|
||||
|
||||
# clear mesh and set meshing parameter
|
||||
femmesh_obj.FemMesh = Fem.FemMesh()
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "3D"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
femmesh_obj.CharacteristicLengthMax = "150.0 mm"
|
||||
femmesh_obj.CharacteristicLengthMin = "150.0 mm"
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
97
src/Mod/Fem/femexamples/ccx_cantilever_ele_tria3.py
Normal file
97
src/Mod/Fem/femexamples/ccx_cantilever_ele_tria3.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
|
||||
import Fem
|
||||
|
||||
from . import manager
|
||||
from .ccx_cantilever_base_face import setup_cantilever_base_face
|
||||
from .manager import get_meshname
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
def get_information():
|
||||
return {
|
||||
"name": "CCX cantilever tria3 face elements",
|
||||
"meshtype": "face",
|
||||
"meshelement": "Tria3",
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["calculix"],
|
||||
"material": "solid",
|
||||
"equation": "mechanical"
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_tria3 import setup
|
||||
setup()
|
||||
|
||||
|
||||
See forum topic post:
|
||||
|
||||
|
||||
CalculiX cantilever modeled with tria3 face elements
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
doc = init_doc()
|
||||
|
||||
# explanation object
|
||||
# just keep the following line and change text string in get_explanation method
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup CalculiX cantilever
|
||||
doc = setup_cantilever_base_face(doc, solvertype)
|
||||
femmesh_obj = doc.getObject(get_meshname())
|
||||
|
||||
# load the tria3 mesh
|
||||
from .meshes.mesh_canticcx_tria3 import create_nodes, create_elements
|
||||
new_fem_mesh = Fem.FemMesh()
|
||||
control = create_nodes(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating nodes.\n")
|
||||
control = create_elements(new_fem_mesh)
|
||||
if not control:
|
||||
FreeCAD.Console.PrintError("Error on creating elements.\n")
|
||||
|
||||
# overwrite mesh with the tria3 mesh
|
||||
femmesh_obj.FemMesh = new_fem_mesh
|
||||
|
||||
# set mesh obj parameter
|
||||
femmesh_obj.SecondOrderLinear = False
|
||||
femmesh_obj.ElementDimension = "2D"
|
||||
femmesh_obj.ElementOrder = "1st"
|
||||
femmesh_obj.CharacteristicLengthMax = "150.0 mm"
|
||||
femmesh_obj.CharacteristicLengthMin = "150.0 mm"
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
70
src/Mod/Fem/femexamples/ccx_cantilever_ele_tria6.py
Normal file
70
src/Mod/Fem/femexamples/ccx_cantilever_ele_tria6.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
from . import manager
|
||||
from .ccx_cantilever_base_face import setup_cantilever_base_face
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
def get_information():
|
||||
return {
|
||||
"name": "CCX cantilever tria6 face elements",
|
||||
"meshtype": "face",
|
||||
"meshelement": "Tria6",
|
||||
"constraints": ["fixed", "force"],
|
||||
"solvers": ["calculix"],
|
||||
"material": "solid",
|
||||
"equation": "mechanical"
|
||||
}
|
||||
|
||||
|
||||
def get_explanation(header=""):
|
||||
return header + """
|
||||
|
||||
To run the example from Python console use:
|
||||
from femexamples.ccx_cantilever_ele_tria6 import setup
|
||||
setup()
|
||||
|
||||
|
||||
See forum topic post:
|
||||
|
||||
CalculiX cantilever modeled with face elements
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# init FreeCAD document
|
||||
if doc is None:
|
||||
doc = init_doc()
|
||||
|
||||
# explanation object
|
||||
# just keep the following line and change text string in get_explanation method
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup CalculiX cantilever
|
||||
doc = setup_cantilever_base_face(doc, solvertype)
|
||||
|
||||
doc.recompute()
|
||||
return doc
|
||||
@@ -25,7 +25,7 @@
|
||||
import ObjectsFem
|
||||
|
||||
from . import manager
|
||||
from .ccx_cantilever_base import setup_cantileverbase
|
||||
from .ccx_cantilever_base_solid import setup_cantilever_base_solid
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# just keep the following line and change text string in get_explanation method
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup CalculiX cantilever, apply 9 MN on surface of front end face
|
||||
doc = setup_cantileverbase(doc, solvertype)
|
||||
# setup CalculiX cantilever
|
||||
doc = setup_cantilever_base_solid(doc, solvertype)
|
||||
analysis = doc.Analysis
|
||||
geom_obj = doc.Box
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
import ObjectsFem
|
||||
|
||||
from . import manager
|
||||
from .ccx_cantilever_base import setup_cantileverbase
|
||||
from .ccx_cantilever_base_solid import setup_cantilever_base_solid
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
|
||||
|
||||
# setup CalculiX cantilever, apply 9 MN on the 4 nodes of the front end face
|
||||
doc = setup_cantileverbase(doc, solvertype)
|
||||
doc = setup_cantilever_base_solid(doc, solvertype)
|
||||
analysis = doc.Analysis
|
||||
geom_obj = doc.Box
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
import ObjectsFem
|
||||
|
||||
from . import manager
|
||||
from .ccx_cantilever_base import setup_cantileverbase
|
||||
from .ccx_cantilever_base_solid import setup_cantilever_base_solid
|
||||
from .manager import init_doc
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# setup CalculiX cantilever
|
||||
# apply a prescribed displacement of 250 mm in -z on the front end face
|
||||
doc = setup_cantileverbase(doc, solvertype)
|
||||
doc = setup_cantilever_base_solid(doc, solvertype)
|
||||
analysis = doc.Analysis
|
||||
geom_obj = doc.Box
|
||||
|
||||
|
||||
@@ -57,7 +57,9 @@ class FemExamples(QtGui.QWidget):
|
||||
"__init__.py",
|
||||
"__pycache__",
|
||||
"boxanalysis_base.py",
|
||||
"ccx_cantilever_base.py",
|
||||
"ccx_cantilever_base_edge.py",
|
||||
"ccx_cantilever_base_face.py",
|
||||
"ccx_cantilever_base_solid.py",
|
||||
"examplesgui.py",
|
||||
"manager.py",
|
||||
"meshes",
|
||||
|
||||
@@ -72,33 +72,33 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# geometric objects
|
||||
# name is important because the other method in this module use obj name
|
||||
box_obj1 = doc.addObject('Part::Box', 'Box1')
|
||||
box_obj1 = doc.addObject("Part::Box", "Box1")
|
||||
box_obj1.Height = 10
|
||||
box_obj1.Width = 10
|
||||
box_obj1.Length = 20
|
||||
box_obj2 = doc.addObject('Part::Box', 'Box2')
|
||||
box_obj2 = doc.addObject("Part::Box", "Box2")
|
||||
box_obj2.Height = 10
|
||||
box_obj2.Width = 10
|
||||
box_obj2.Length = 20
|
||||
box_obj2.Placement.Base = (20, 0, 0)
|
||||
box_obj3 = doc.addObject('Part::Box', 'Box3')
|
||||
box_obj3 = doc.addObject("Part::Box", "Box3")
|
||||
box_obj3.Height = 10
|
||||
box_obj3.Width = 10
|
||||
box_obj3.Length = 20
|
||||
box_obj3.Placement.Base = (40, 0, 0)
|
||||
box_obj4 = doc.addObject('Part::Box', 'Box4')
|
||||
box_obj4 = doc.addObject("Part::Box", "Box4")
|
||||
box_obj4.Height = 10
|
||||
box_obj4.Width = 10
|
||||
box_obj4.Length = 20
|
||||
box_obj4.Placement.Base = (60, 0, 0)
|
||||
box_obj5 = doc.addObject('Part::Box', 'Box5')
|
||||
box_obj5 = doc.addObject("Part::Box", "Box5")
|
||||
box_obj5.Height = 10
|
||||
box_obj5.Width = 10
|
||||
box_obj5.Length = 20
|
||||
box_obj5.Placement.Base = (80, 0, 0)
|
||||
|
||||
# make a CompSolid out of the boxes, to be able to remesh with GUI
|
||||
j = BOPTools.SplitFeatures.makeBooleanFragments(name='BooleanFragments')
|
||||
j = BOPTools.SplitFeatures.makeBooleanFragments(name="BooleanFragments")
|
||||
j.Objects = [box_obj1, box_obj2, box_obj3, box_obj4, box_obj5]
|
||||
j.Mode = "CompSolid"
|
||||
j.Proxy.execute(j)
|
||||
@@ -108,7 +108,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
for obj in j.ViewObject.Proxy.claimChildren():
|
||||
obj.ViewObject.hide()
|
||||
|
||||
geom_obj = doc.addObject('Part::Feature', 'CompSolid')
|
||||
geom_obj = doc.addObject("Part::Feature", "CompSolid")
|
||||
geom_obj.Shape = j.Shape.CompSolids[0]
|
||||
if FreeCAD.GuiUp:
|
||||
j.ViewObject.hide()
|
||||
@@ -142,33 +142,33 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# material
|
||||
material_obj1 = ObjectsFem.makeMaterialSolid(doc, 'FemMaterial1')
|
||||
material_obj1 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial1")
|
||||
material_obj1.References = [(doc.Box3, "Solid1")]
|
||||
mat = material_obj1.Material
|
||||
mat['Name'] = "Concrete-Generic"
|
||||
mat['YoungsModulus'] = "32000 MPa"
|
||||
mat['PoissonRatio'] = "0.17"
|
||||
mat['Density'] = "0 kg/m^3"
|
||||
mat["Name"] = "Concrete-Generic"
|
||||
mat["YoungsModulus"] = "32000 MPa"
|
||||
mat["PoissonRatio"] = "0.17"
|
||||
mat["Density"] = "0 kg/m^3"
|
||||
material_obj1.Material = mat
|
||||
analysis.addObject(material_obj1)
|
||||
|
||||
material_obj2 = ObjectsFem.makeMaterialSolid(doc, 'FemMaterial2')
|
||||
material_obj2 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial2")
|
||||
material_obj2.References = [(doc.Box2, "Solid1"), (doc.Box4, "Solid1")]
|
||||
mat = material_obj2.Material
|
||||
mat['Name'] = "PLA"
|
||||
mat['YoungsModulus'] = "3640 MPa"
|
||||
mat['PoissonRatio'] = "0.36"
|
||||
mat['Density'] = "0 kg/m^3"
|
||||
mat["Name"] = "PLA"
|
||||
mat["YoungsModulus"] = "3640 MPa"
|
||||
mat["PoissonRatio"] = "0.36"
|
||||
mat["Density"] = "0 kg/m^3"
|
||||
material_obj2.Material = mat
|
||||
analysis.addObject(material_obj2)
|
||||
|
||||
material_obj3 = ObjectsFem.makeMaterialSolid(doc, 'FemMaterial3')
|
||||
material_obj3 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial3")
|
||||
material_obj3.References = []
|
||||
mat = material_obj3.Material
|
||||
mat['Name'] = "Steel-Generic"
|
||||
mat['YoungsModulus'] = "200000 MPa"
|
||||
mat['PoissonRatio'] = "0.30"
|
||||
mat['Density'] = "7900 kg/m^3"
|
||||
mat["Name"] = "Steel-Generic"
|
||||
mat["YoungsModulus"] = "200000 MPa"
|
||||
mat["PoissonRatio"] = "0.30"
|
||||
mat["Density"] = "7900 kg/m^3"
|
||||
material_obj3.Material = mat
|
||||
analysis.addObject(material_obj3)
|
||||
|
||||
|
||||
@@ -71,22 +71,22 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# geometric objects
|
||||
# name is important because the other method in this module use obj name
|
||||
# parts
|
||||
face_obj1 = doc.addObject('Part::Plane', 'Face1')
|
||||
face_obj1 = doc.addObject("Part::Plane", "Face1")
|
||||
face_obj1.Width = 10
|
||||
face_obj1.Length = 20
|
||||
face_obj2 = doc.addObject('Part::Plane', 'Face2')
|
||||
face_obj2 = doc.addObject("Part::Plane", "Face2")
|
||||
face_obj2.Width = 10
|
||||
face_obj2.Length = 20
|
||||
face_obj2.Placement.Base = (20, 0, 0)
|
||||
face_obj3 = doc.addObject('Part::Plane', 'Face3')
|
||||
face_obj3 = doc.addObject("Part::Plane", "Face3")
|
||||
face_obj3.Width = 10
|
||||
face_obj3.Length = 20
|
||||
face_obj3.Placement.Base = (40, 0, 0)
|
||||
face_obj4 = doc.addObject('Part::Plane', 'Face4')
|
||||
face_obj4 = doc.addObject("Part::Plane", "Face4")
|
||||
face_obj4.Width = 10
|
||||
face_obj4.Length = 20
|
||||
face_obj4.Placement.Base = (60, 0, 0)
|
||||
face_obj5 = doc.addObject('Part::Plane', 'Face5')
|
||||
face_obj5 = doc.addObject("Part::Plane", "Face5")
|
||||
face_obj5.Width = 10
|
||||
face_obj5.Length = 20
|
||||
face_obj5.Placement.Base = (80, 0, 0)
|
||||
@@ -131,40 +131,40 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
analysis.addObject(solver_obj)
|
||||
|
||||
# shell thickness
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 10, 'ShellThickness')
|
||||
thickness_obj = ObjectsFem.makeElementGeometry2D(doc, 10, "ShellThickness")
|
||||
analysis.addObject(thickness_obj)
|
||||
|
||||
# materials
|
||||
material_obj1 = ObjectsFem.makeMaterialSolid(doc, 'FemMaterial1')
|
||||
material_obj1 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial1")
|
||||
material_obj1.References = [(doc.Face3, "Face1")]
|
||||
mat = material_obj1.Material
|
||||
mat['Name'] = "Concrete-Generic"
|
||||
mat['YoungsModulus'] = "32000 MPa"
|
||||
mat['PoissonRatio'] = "0.17"
|
||||
mat['Density'] = "0 kg/m^3"
|
||||
mat["Name"] = "Concrete-Generic"
|
||||
mat["YoungsModulus"] = "32000 MPa"
|
||||
mat["PoissonRatio"] = "0.17"
|
||||
mat["Density"] = "0 kg/m^3"
|
||||
material_obj1.Material = mat
|
||||
analysis.addObject(material_obj1)
|
||||
|
||||
material_obj2 = ObjectsFem.makeMaterialSolid(doc, 'FemMaterial2')
|
||||
material_obj2 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial2")
|
||||
material_obj2.References = [
|
||||
(doc.Face2, "Face1"),
|
||||
(doc.Face4, "Face1")
|
||||
]
|
||||
mat = material_obj2.Material
|
||||
mat['Name'] = "PLA"
|
||||
mat['YoungsModulus'] = "3640 MPa"
|
||||
mat['PoissonRatio'] = "0.36"
|
||||
mat['Density'] = "0 kg/m^3"
|
||||
mat["Name"] = "PLA"
|
||||
mat["YoungsModulus"] = "3640 MPa"
|
||||
mat["PoissonRatio"] = "0.36"
|
||||
mat["Density"] = "0 kg/m^3"
|
||||
material_obj2.Material = mat
|
||||
analysis.addObject(material_obj2)
|
||||
|
||||
material_obj3 = ObjectsFem.makeMaterialSolid(doc, 'FemMaterial3')
|
||||
material_obj3 = ObjectsFem.makeMaterialSolid(doc, "FemMaterial3")
|
||||
material_obj3.References = []
|
||||
mat = material_obj3.Material
|
||||
mat['Name'] = "Steel-Generic"
|
||||
mat['YoungsModulus'] = "200000 MPa"
|
||||
mat['PoissonRatio'] = "0.30"
|
||||
mat['Density'] = "7900 kg/m^3"
|
||||
mat["Name"] = "Steel-Generic"
|
||||
mat["YoungsModulus"] = "200000 MPa"
|
||||
mat["PoissonRatio"] = "0.30"
|
||||
mat["Density"] = "7900 kg/m^3"
|
||||
material_obj3.Material = mat
|
||||
analysis.addObject(material_obj3)
|
||||
|
||||
|
||||
117
src/Mod/Fem/femexamples/meshes/mesh_canticcx_seg2.py
Normal file
117
src/Mod/Fem/femexamples/meshes/mesh_canticcx_seg2.py
Normal file
@@ -0,0 +1,117 @@
|
||||
def create_nodes(femmesh):
|
||||
# nodes
|
||||
femmesh.addNode(0.0, 500.0, 500.0, 1)
|
||||
femmesh.addNode(8000.0, 500.0, 500.0, 2)
|
||||
femmesh.addNode(148.14814814814792, 500.0, 500.0, 3)
|
||||
femmesh.addNode(296.29629629629585, 500.0, 500.0, 4)
|
||||
femmesh.addNode(444.4444444444438, 500.0, 500.0, 5)
|
||||
femmesh.addNode(592.5925925925918, 500.0, 500.0, 6)
|
||||
femmesh.addNode(740.7407407407396, 500.0, 500.0, 7)
|
||||
femmesh.addNode(888.8888888888874, 500.0, 500.0, 8)
|
||||
femmesh.addNode(1037.0370370370354, 500.0, 500.0, 9)
|
||||
femmesh.addNode(1185.1851851851832, 500.0, 500.0, 10)
|
||||
femmesh.addNode(1333.333333333331, 500.0, 500.0, 11)
|
||||
femmesh.addNode(1481.4814814814792, 500.0, 500.0, 12)
|
||||
femmesh.addNode(1629.6296296296275, 500.0, 500.0, 13)
|
||||
femmesh.addNode(1777.7777777777753, 500.0, 500.0, 14)
|
||||
femmesh.addNode(1925.9259259259236, 500.0, 500.0, 15)
|
||||
femmesh.addNode(2074.0740740740716, 500.0, 500.0, 16)
|
||||
femmesh.addNode(2222.22222222222, 500.0, 500.0, 17)
|
||||
femmesh.addNode(2370.370370370368, 500.0, 500.0, 18)
|
||||
femmesh.addNode(2518.5185185185155, 500.0, 500.0, 19)
|
||||
femmesh.addNode(2666.666666666663, 500.0, 500.0, 20)
|
||||
femmesh.addNode(2814.8148148148107, 500.0, 500.0, 21)
|
||||
femmesh.addNode(2962.962962962958, 500.0, 500.0, 22)
|
||||
femmesh.addNode(3111.1111111111054, 500.0, 500.0, 23)
|
||||
femmesh.addNode(3259.259259259253, 500.0, 500.0, 24)
|
||||
femmesh.addNode(3407.4074074074006, 500.0, 500.0, 25)
|
||||
femmesh.addNode(3555.555555555548, 500.0, 500.0, 26)
|
||||
femmesh.addNode(3703.7037037036957, 500.0, 500.0, 27)
|
||||
femmesh.addNode(3851.851851851843, 500.0, 500.0, 28)
|
||||
femmesh.addNode(3999.9999999999905, 500.0, 500.0, 29)
|
||||
femmesh.addNode(4148.148148148138, 500.0, 500.0, 30)
|
||||
femmesh.addNode(4296.296296296286, 500.0, 500.0, 31)
|
||||
femmesh.addNode(4444.4444444444325, 500.0, 500.0, 32)
|
||||
femmesh.addNode(4592.59259259258, 500.0, 500.0, 33)
|
||||
femmesh.addNode(4740.740740740728, 500.0, 500.0, 34)
|
||||
femmesh.addNode(4888.888888888877, 500.0, 500.0, 35)
|
||||
femmesh.addNode(5037.037037037026, 500.0, 500.0, 36)
|
||||
femmesh.addNode(5185.185185185173, 500.0, 500.0, 37)
|
||||
femmesh.addNode(5333.333333333322, 500.0, 500.0, 38)
|
||||
femmesh.addNode(5481.481481481471, 500.0, 500.0, 39)
|
||||
femmesh.addNode(5629.6296296296205, 500.0, 500.0, 40)
|
||||
femmesh.addNode(5777.777777777769, 500.0, 500.0, 41)
|
||||
femmesh.addNode(5925.925925925918, 500.0, 500.0, 42)
|
||||
femmesh.addNode(6074.074074074067, 500.0, 500.0, 43)
|
||||
femmesh.addNode(6222.222222222214, 500.0, 500.0, 44)
|
||||
femmesh.addNode(6370.370370370363, 500.0, 500.0, 45)
|
||||
femmesh.addNode(6518.518518518513, 500.0, 500.0, 46)
|
||||
femmesh.addNode(6666.6666666666615, 500.0, 500.0, 47)
|
||||
femmesh.addNode(6814.81481481481, 500.0, 500.0, 48)
|
||||
femmesh.addNode(6962.962962962959, 500.0, 500.0, 49)
|
||||
femmesh.addNode(7111.111111111108, 500.0, 500.0, 50)
|
||||
femmesh.addNode(7259.259259259256, 500.0, 500.0, 51)
|
||||
femmesh.addNode(7407.407407407406, 500.0, 500.0, 52)
|
||||
femmesh.addNode(7555.555555555554, 500.0, 500.0, 53)
|
||||
femmesh.addNode(7703.703703703703, 500.0, 500.0, 54)
|
||||
femmesh.addNode(7851.851851851851, 500.0, 500.0, 55)
|
||||
return True
|
||||
|
||||
|
||||
def create_elements(femmesh):
|
||||
# elements
|
||||
femmesh.addEdge([1, 3], 1)
|
||||
femmesh.addEdge([3, 4], 2)
|
||||
femmesh.addEdge([4, 5], 3)
|
||||
femmesh.addEdge([5, 6], 4)
|
||||
femmesh.addEdge([6, 7], 5)
|
||||
femmesh.addEdge([7, 8], 6)
|
||||
femmesh.addEdge([8, 9], 7)
|
||||
femmesh.addEdge([9, 10], 8)
|
||||
femmesh.addEdge([10, 11], 9)
|
||||
femmesh.addEdge([11, 12], 10)
|
||||
femmesh.addEdge([12, 13], 11)
|
||||
femmesh.addEdge([13, 14], 12)
|
||||
femmesh.addEdge([14, 15], 13)
|
||||
femmesh.addEdge([15, 16], 14)
|
||||
femmesh.addEdge([16, 17], 15)
|
||||
femmesh.addEdge([17, 18], 16)
|
||||
femmesh.addEdge([18, 19], 17)
|
||||
femmesh.addEdge([19, 20], 18)
|
||||
femmesh.addEdge([20, 21], 19)
|
||||
femmesh.addEdge([21, 22], 20)
|
||||
femmesh.addEdge([22, 23], 21)
|
||||
femmesh.addEdge([23, 24], 22)
|
||||
femmesh.addEdge([24, 25], 23)
|
||||
femmesh.addEdge([25, 26], 24)
|
||||
femmesh.addEdge([26, 27], 25)
|
||||
femmesh.addEdge([27, 28], 26)
|
||||
femmesh.addEdge([28, 29], 27)
|
||||
femmesh.addEdge([29, 30], 28)
|
||||
femmesh.addEdge([30, 31], 29)
|
||||
femmesh.addEdge([31, 32], 30)
|
||||
femmesh.addEdge([32, 33], 31)
|
||||
femmesh.addEdge([33, 34], 32)
|
||||
femmesh.addEdge([34, 35], 33)
|
||||
femmesh.addEdge([35, 36], 34)
|
||||
femmesh.addEdge([36, 37], 35)
|
||||
femmesh.addEdge([37, 38], 36)
|
||||
femmesh.addEdge([38, 39], 37)
|
||||
femmesh.addEdge([39, 40], 38)
|
||||
femmesh.addEdge([40, 41], 39)
|
||||
femmesh.addEdge([41, 42], 40)
|
||||
femmesh.addEdge([42, 43], 41)
|
||||
femmesh.addEdge([43, 44], 42)
|
||||
femmesh.addEdge([44, 45], 43)
|
||||
femmesh.addEdge([45, 46], 44)
|
||||
femmesh.addEdge([46, 47], 45)
|
||||
femmesh.addEdge([47, 48], 46)
|
||||
femmesh.addEdge([48, 49], 47)
|
||||
femmesh.addEdge([49, 50], 48)
|
||||
femmesh.addEdge([50, 51], 49)
|
||||
femmesh.addEdge([51, 52], 50)
|
||||
femmesh.addEdge([52, 53], 51)
|
||||
femmesh.addEdge([53, 54], 52)
|
||||
femmesh.addEdge([54, 55], 53)
|
||||
femmesh.addEdge([55, 2], 54)
|
||||
return True
|
||||
24
src/Mod/Fem/femexamples/meshes/mesh_canticcx_seg3.py
Normal file
24
src/Mod/Fem/femexamples/meshes/mesh_canticcx_seg3.py
Normal file
@@ -0,0 +1,24 @@
|
||||
def create_nodes(femmesh):
|
||||
# nodes
|
||||
femmesh.addNode(0.0, 500.0, 500.0, 1)
|
||||
femmesh.addNode(8000.0, 500.0, 500.0, 2)
|
||||
femmesh.addNode(1600.0000000000023, 500.0, 500.0, 3)
|
||||
femmesh.addNode(3200.000000000006, 500.0, 500.0, 4)
|
||||
femmesh.addNode(4800.000000000003, 500.0, 500.0, 5)
|
||||
femmesh.addNode(6399.999999999996, 500.0, 500.0, 6)
|
||||
femmesh.addNode(800.0000000000011, 500.0, 500.0, 7)
|
||||
femmesh.addNode(2400.000000000004, 500.0, 500.0, 8)
|
||||
femmesh.addNode(4000.0000000000045, 500.0, 500.0, 9)
|
||||
femmesh.addNode(5599.999999999999, 500.0, 500.0, 10)
|
||||
femmesh.addNode(7199.999999999998, 500.0, 500.0, 11)
|
||||
return True
|
||||
|
||||
|
||||
def create_elements(femmesh):
|
||||
# elements
|
||||
femmesh.addEdge([1, 3, 7], 1)
|
||||
femmesh.addEdge([3, 4, 8], 2)
|
||||
femmesh.addEdge([4, 5, 9], 3)
|
||||
femmesh.addEdge([5, 6, 10], 4)
|
||||
femmesh.addEdge([6, 2, 11], 5)
|
||||
return True
|
||||
1522
src/Mod/Fem/femexamples/meshes/mesh_canticcx_tria3.py
Normal file
1522
src/Mod/Fem/femexamples/meshes/mesh_canticcx_tria3.py
Normal file
File diff suppressed because it is too large
Load Diff
255
src/Mod/Fem/femexamples/meshes/mesh_canticcx_tria6.py
Normal file
255
src/Mod/Fem/femexamples/meshes/mesh_canticcx_tria6.py
Normal file
@@ -0,0 +1,255 @@
|
||||
def create_nodes(femmesh):
|
||||
# nodes
|
||||
femmesh.addNode(0.0, 500.0, 0.0, 1)
|
||||
femmesh.addNode(0.0, 500.00000000000324, 1000.0, 2)
|
||||
femmesh.addNode(8000.0, 500.0, 0.0, 3)
|
||||
femmesh.addNode(8000.0, 500.00000000000324, 1000.0, 4)
|
||||
femmesh.addNode(0.0, 500.0000000000001, 500.0, 5)
|
||||
femmesh.addNode(0.0, 500.00000000000006, 250.0, 6)
|
||||
femmesh.addNode(0.0, 500.00000000000017, 750.0, 7)
|
||||
femmesh.addNode(500.0, 500.0, 0.0, 8)
|
||||
femmesh.addNode(1000.0, 500.0, 0.0, 9)
|
||||
femmesh.addNode(1500.0, 500.0, 0.0, 10)
|
||||
femmesh.addNode(2000.0, 500.0, 0.0, 11)
|
||||
femmesh.addNode(2500.0, 500.0, 0.0, 12)
|
||||
femmesh.addNode(3000.0, 500.0, 0.0, 13)
|
||||
femmesh.addNode(3500.0, 500.0, 0.0, 14)
|
||||
femmesh.addNode(4000.0, 500.0, 0.0, 15)
|
||||
femmesh.addNode(4500.0, 500.0, 0.0, 16)
|
||||
femmesh.addNode(5000.0, 500.0, 0.0, 17)
|
||||
femmesh.addNode(5500.0, 500.0, 0.0, 18)
|
||||
femmesh.addNode(6000.0, 500.0, 0.0, 19)
|
||||
femmesh.addNode(6500.0, 500.0, 0.0, 20)
|
||||
femmesh.addNode(7000.0, 500.0, 0.0, 21)
|
||||
femmesh.addNode(7500.0, 500.0, 0.0, 22)
|
||||
femmesh.addNode(250.0, 500.0, 0.0, 23)
|
||||
femmesh.addNode(750.0, 500.0, 0.0, 24)
|
||||
femmesh.addNode(1250.0, 500.0, 0.0, 25)
|
||||
femmesh.addNode(1750.0, 500.0, 0.0, 26)
|
||||
femmesh.addNode(2250.0, 500.0, 0.0, 27)
|
||||
femmesh.addNode(2750.0, 500.0, 0.0, 28)
|
||||
femmesh.addNode(3250.0, 500.0, 0.0, 29)
|
||||
femmesh.addNode(3750.0, 500.0, 0.0, 30)
|
||||
femmesh.addNode(4250.0, 500.0, 0.0, 31)
|
||||
femmesh.addNode(4750.0, 500.0, 0.0, 32)
|
||||
femmesh.addNode(5250.0, 500.0, 0.0, 33)
|
||||
femmesh.addNode(5750.0, 500.0, 0.0, 34)
|
||||
femmesh.addNode(6250.0, 500.0, 0.0, 35)
|
||||
femmesh.addNode(6750.0, 500.0, 0.0, 36)
|
||||
femmesh.addNode(7250.0, 500.0, 0.0, 37)
|
||||
femmesh.addNode(7750.0, 500.0, 0.0, 38)
|
||||
femmesh.addNode(8000.0, 500.0000000000001, 500.0, 39)
|
||||
femmesh.addNode(8000.0, 500.00000000000006, 250.0, 40)
|
||||
femmesh.addNode(8000.0, 500.00000000000017, 750.0, 41)
|
||||
femmesh.addNode(500.0, 500.0000000000002, 1000.0, 42)
|
||||
femmesh.addNode(1000.0, 500.0000000000002, 1000.0, 43)
|
||||
femmesh.addNode(1500.0, 500.0000000000002, 1000.0, 44)
|
||||
femmesh.addNode(2000.0, 500.0000000000002, 1000.0, 45)
|
||||
femmesh.addNode(2500.0, 500.0000000000002, 1000.0, 46)
|
||||
femmesh.addNode(3000.0, 500.0000000000002, 1000.0, 47)
|
||||
femmesh.addNode(3500.0, 500.0000000000002, 1000.0, 48)
|
||||
femmesh.addNode(4000.0, 500.0000000000002, 1000.0, 49)
|
||||
femmesh.addNode(4500.0, 500.0000000000002, 1000.0, 50)
|
||||
femmesh.addNode(5000.0, 500.0000000000002, 1000.0, 51)
|
||||
femmesh.addNode(5500.0, 500.0000000000002, 1000.0, 52)
|
||||
femmesh.addNode(6000.0, 500.0000000000002, 1000.0, 53)
|
||||
femmesh.addNode(6500.0, 500.0000000000002, 1000.0, 54)
|
||||
femmesh.addNode(7000.0, 500.0000000000002, 1000.0, 55)
|
||||
femmesh.addNode(7500.0, 500.0000000000002, 1000.0, 56)
|
||||
femmesh.addNode(250.0, 500.0000000000002, 1000.0, 57)
|
||||
femmesh.addNode(750.0, 500.0000000000002, 1000.0, 58)
|
||||
femmesh.addNode(1250.0, 500.0000000000002, 1000.0, 59)
|
||||
femmesh.addNode(1750.0, 500.0000000000002, 1000.0, 60)
|
||||
femmesh.addNode(2250.0, 500.0000000000002, 1000.0, 61)
|
||||
femmesh.addNode(2750.0, 500.0000000000002, 1000.0, 62)
|
||||
femmesh.addNode(3250.0, 500.0000000000002, 1000.0, 63)
|
||||
femmesh.addNode(3750.0, 500.0000000000002, 1000.0, 64)
|
||||
femmesh.addNode(4250.0, 500.0000000000002, 1000.0, 65)
|
||||
femmesh.addNode(4750.0, 500.0000000000002, 1000.0, 66)
|
||||
femmesh.addNode(5250.0, 500.0000000000002, 1000.0, 67)
|
||||
femmesh.addNode(5750.0, 500.0000000000002, 1000.0, 68)
|
||||
femmesh.addNode(6250.0, 500.0000000000002, 1000.0, 69)
|
||||
femmesh.addNode(6750.0, 500.0000000000002, 1000.0, 70)
|
||||
femmesh.addNode(7250.0, 500.0000000000002, 1000.0, 71)
|
||||
femmesh.addNode(7750.0, 500.0000000000002, 1000.0, 72)
|
||||
femmesh.addNode(714.9234693877551, 500.0000000000001, 484.05612244897964, 73)
|
||||
femmesh.addNode(1750.0, 500.0000000000001, 500.0, 74)
|
||||
femmesh.addNode(2750.0, 500.0000000000001, 500.0, 75)
|
||||
femmesh.addNode(3750.0, 500.0000000000001, 500.0, 76)
|
||||
femmesh.addNode(4750.0, 500.0000000000001, 500.0, 77)
|
||||
femmesh.addNode(5750.0, 500.0000000000001, 500.0, 78)
|
||||
femmesh.addNode(6756.944444444443, 500.0000000000001, 489.5833333333333, 79)
|
||||
femmesh.addNode(7301.463293650793, 500.0000000000001, 489.7073412698406, 80)
|
||||
femmesh.addNode(1244.1539115646258, 500.0000000000001, 497.34268707482994, 81)
|
||||
femmesh.addNode(2250.0, 500.0000000000001, 500.0, 82)
|
||||
femmesh.addNode(3250.0, 500.0000000000001, 500.0, 83)
|
||||
femmesh.addNode(4250.0, 500.0000000000001, 500.0, 84)
|
||||
femmesh.addNode(5250.0, 500.0000000000001, 500.0, 85)
|
||||
femmesh.addNode(6251.157407407407, 500.0000000000001, 498.2638888888889, 86)
|
||||
femmesh.addNode(355.2776691684587, 500.0000000000001, 632.304566974645, 87)
|
||||
femmesh.addNode(7660.398197179746, 500.00000000000017, 648.5965255878823, 88)
|
||||
femmesh.addNode(7699.764777975907, 500.00000000000006, 310.456176890242, 89)
|
||||
femmesh.addNode(314.0402277112428, 500.00000000000006, 323.27213788472494, 90)
|
||||
femmesh.addNode(1122.0769557823128, 500.00000000000017, 748.6713435374149, 91)
|
||||
femmesh.addNode(1372.0769557823128, 500.00000000000017, 748.6713435374149, 92)
|
||||
femmesh.addNode(2125.0, 500.00000000000017, 750.0, 93)
|
||||
femmesh.addNode(2375.0, 500.00000000000017, 750.0, 94)
|
||||
femmesh.addNode(3125.0, 500.00000000000017, 750.0, 95)
|
||||
femmesh.addNode(3375.0, 500.00000000000017, 750.0, 96)
|
||||
femmesh.addNode(4125.0, 500.00000000000017, 750.0, 97)
|
||||
femmesh.addNode(4375.0, 500.00000000000017, 750.0, 98)
|
||||
femmesh.addNode(5125.0, 500.00000000000017, 750.0, 99)
|
||||
femmesh.addNode(5375.0, 500.00000000000017, 750.0, 100)
|
||||
femmesh.addNode(6125.5787037037035, 500.00000000000017, 749.1319444444445, 101)
|
||||
femmesh.addNode(6375.5787037037035, 500.00000000000017, 749.1319444444445, 102)
|
||||
femmesh.addNode(857.4617346938776, 500.00000000000017, 742.0280612244899, 103)
|
||||
femmesh.addNode(979.5386904761904, 500.0000000000001, 490.6994047619048, 104)
|
||||
femmesh.addNode(1497.0769557823128, 500.0000000000001, 498.67134353741494, 105)
|
||||
femmesh.addNode(1625.0, 500.00000000000017, 750.0, 106)
|
||||
femmesh.addNode(1875.0, 500.00000000000017, 750.0, 107)
|
||||
femmesh.addNode(2000.0, 500.0000000000001, 500.0, 108)
|
||||
femmesh.addNode(2500.0, 500.0000000000001, 500.0, 109)
|
||||
femmesh.addNode(2625.0, 500.00000000000017, 750.0, 110)
|
||||
femmesh.addNode(2875.0, 500.00000000000017, 750.0, 111)
|
||||
femmesh.addNode(3000.0, 500.0000000000001, 500.0, 112)
|
||||
femmesh.addNode(3500.0, 500.0000000000001, 500.0, 113)
|
||||
femmesh.addNode(3625.0, 500.00000000000017, 750.0, 114)
|
||||
femmesh.addNode(3875.0, 500.00000000000017, 750.0, 115)
|
||||
femmesh.addNode(4000.0, 500.0000000000001, 500.0, 116)
|
||||
femmesh.addNode(4500.0, 500.0000000000001, 500.0, 117)
|
||||
femmesh.addNode(4625.0, 500.00000000000017, 750.0, 118)
|
||||
femmesh.addNode(4875.0, 500.00000000000017, 750.0, 119)
|
||||
femmesh.addNode(5000.0, 500.0000000000001, 500.0, 120)
|
||||
femmesh.addNode(5500.0, 500.0000000000001, 500.0, 121)
|
||||
femmesh.addNode(5625.0, 500.00000000000017, 750.0, 122)
|
||||
femmesh.addNode(5875.0, 500.00000000000017, 750.0, 123)
|
||||
femmesh.addNode(6000.5787037037035, 500.0000000000001, 499.13194444444446, 124)
|
||||
femmesh.addNode(6504.050925925925, 500.0000000000001, 493.9236111111111, 125)
|
||||
femmesh.addNode(6628.472222222222, 500.00000000000017, 744.7916666666666, 126)
|
||||
femmesh.addNode(7150.731646825397, 500.00000000000006, 244.8536706349203, 127)
|
||||
femmesh.addNode(7029.203869047618, 500.0000000000001, 489.64533730158695, 128)
|
||||
femmesh.addNode(6878.472222222222, 500.00000000000006, 244.79166666666666, 129)
|
||||
femmesh.addNode(6878.472222222222, 500.00000000000017, 744.7916666666666, 130)
|
||||
femmesh.addNode(7150.731646825397, 500.00000000000017, 744.8536706349203, 131)
|
||||
femmesh.addNode(7400.731646825397, 500.00000000000006, 244.8536706349203, 132)
|
||||
femmesh.addNode(7400.731646825397, 500.00000000000017, 744.8536706349203, 133)
|
||||
femmesh.addNode(857.4617346938776, 500.00000000000006, 242.02806122448982, 134)
|
||||
femmesh.addNode(607.4617346938776, 500.00000000000006, 242.02806122448982, 135)
|
||||
femmesh.addNode(1875.0, 500.00000000000006, 250.0, 136)
|
||||
femmesh.addNode(1625.0, 500.00000000000006, 250.0, 137)
|
||||
femmesh.addNode(2875.0, 500.00000000000006, 250.0, 138)
|
||||
femmesh.addNode(2625.0, 500.00000000000006, 250.0, 139)
|
||||
femmesh.addNode(3875.0, 500.00000000000006, 250.0, 140)
|
||||
femmesh.addNode(3625.0, 500.00000000000006, 250.0, 141)
|
||||
femmesh.addNode(4875.0, 500.00000000000006, 250.0, 142)
|
||||
femmesh.addNode(4625.0, 500.00000000000006, 250.0, 143)
|
||||
femmesh.addNode(5875.0, 500.00000000000006, 250.0, 144)
|
||||
femmesh.addNode(5625.0, 500.00000000000006, 250.0, 145)
|
||||
femmesh.addNode(6628.472222222222, 500.00000000000006, 244.79166666666666, 146)
|
||||
femmesh.addNode(607.4617346938776, 500.00000000000017, 742.0280612244899, 147)
|
||||
femmesh.addNode(1122.0769557823128, 500.00000000000006, 248.67134353741497, 148)
|
||||
femmesh.addNode(1372.0769557823128, 500.00000000000006, 248.67134353741497, 149)
|
||||
femmesh.addNode(2125.0, 500.00000000000006, 250.0, 150)
|
||||
femmesh.addNode(2375.0, 500.00000000000006, 250.0, 151)
|
||||
femmesh.addNode(3125.0, 500.00000000000006, 250.0, 152)
|
||||
femmesh.addNode(3375.0, 500.00000000000006, 250.0, 153)
|
||||
femmesh.addNode(4125.0, 500.00000000000006, 250.0, 154)
|
||||
femmesh.addNode(4375.0, 500.00000000000006, 250.0, 155)
|
||||
femmesh.addNode(5125.0, 500.00000000000006, 250.0, 156)
|
||||
femmesh.addNode(5375.0, 500.00000000000006, 250.0, 157)
|
||||
femmesh.addNode(6125.5787037037035, 500.00000000000006, 249.13194444444446, 158)
|
||||
femmesh.addNode(6375.5787037037035, 500.00000000000006, 249.13194444444446, 159)
|
||||
femmesh.addNode(514.4818485494989, 500.0000000000001, 403.66413016685226, 160)
|
||||
femmesh.addNode(407.0201138556214, 500.00000000000006, 161.63606894236247, 161)
|
||||
femmesh.addNode(177.63883458422936, 500.0000000000001, 566.1522834873225, 162)
|
||||
femmesh.addNode(177.63883458422936, 500.00000000000017, 816.1522834873225, 163)
|
||||
femmesh.addNode(427.63883458422936, 500.00000000000017, 816.1522834873225, 164)
|
||||
femmesh.addNode(535.1005692781068, 500.0000000000001, 558.1803447118123, 165)
|
||||
femmesh.addNode(7599.882388987953, 500.00000000000006, 155.228088445121, 166)
|
||||
femmesh.addNode(7500.614035813351, 500.0000000000001, 400.08175908004125, 167)
|
||||
femmesh.addNode(7830.199098589873, 500.00000000000017, 824.2982627939411, 168)
|
||||
femmesh.addNode(7830.199098589873, 500.0000000000001, 574.2982627939411, 169)
|
||||
femmesh.addNode(7580.199098589873, 500.00000000000017, 824.2982627939411, 170)
|
||||
femmesh.addNode(7480.9307454152695, 500.0000000000001, 569.1519334288614, 171)
|
||||
femmesh.addNode(334.65894843985075, 500.0000000000001, 477.788352429685, 172)
|
||||
femmesh.addNode(7849.882388987953, 500.0000000000001, 405.228088445121, 173)
|
||||
femmesh.addNode(7849.882388987953, 500.00000000000006, 155.228088445121, 174)
|
||||
femmesh.addNode(157.0201138556214, 500.00000000000006, 161.63606894236247, 175)
|
||||
femmesh.addNode(157.0201138556214, 500.0000000000001, 411.6360689423625, 176)
|
||||
femmesh.addNode(7680.081487577827, 500.0000000000001, 479.52635123906214, 177)
|
||||
return True
|
||||
|
||||
|
||||
def create_elements(femmesh):
|
||||
# elements
|
||||
femmesh.addFace([43, 81, 44, 91, 92, 59], 37)
|
||||
femmesh.addFace([45, 82, 46, 93, 94, 61], 38)
|
||||
femmesh.addFace([47, 83, 48, 95, 96, 63], 39)
|
||||
femmesh.addFace([49, 84, 50, 97, 98, 65], 40)
|
||||
femmesh.addFace([51, 85, 52, 99, 100, 67], 41)
|
||||
femmesh.addFace([53, 86, 54, 101, 102, 69], 42)
|
||||
femmesh.addFace([43, 73, 81, 103, 104, 91], 43)
|
||||
femmesh.addFace([44, 81, 74, 92, 105, 106], 44)
|
||||
femmesh.addFace([45, 74, 82, 107, 108, 93], 45)
|
||||
femmesh.addFace([46, 82, 75, 94, 109, 110], 46)
|
||||
femmesh.addFace([47, 75, 83, 111, 112, 95], 47)
|
||||
femmesh.addFace([48, 83, 76, 96, 113, 114], 48)
|
||||
femmesh.addFace([49, 76, 84, 115, 116, 97], 49)
|
||||
femmesh.addFace([50, 84, 77, 98, 117, 118], 50)
|
||||
femmesh.addFace([51, 77, 85, 119, 120, 99], 51)
|
||||
femmesh.addFace([52, 85, 78, 100, 121, 122], 52)
|
||||
femmesh.addFace([53, 78, 86, 123, 124, 101], 53)
|
||||
femmesh.addFace([54, 86, 79, 102, 125, 126], 54)
|
||||
femmesh.addFace([21, 80, 79, 127, 128, 129], 55)
|
||||
femmesh.addFace([55, 79, 80, 130, 128, 131], 56)
|
||||
femmesh.addFace([21, 22, 80, 37, 132, 127], 57)
|
||||
femmesh.addFace([55, 80, 56, 131, 133, 71], 58)
|
||||
femmesh.addFace([8, 9, 73, 24, 134, 135], 59)
|
||||
femmesh.addFace([10, 11, 74, 26, 136, 137], 60)
|
||||
femmesh.addFace([12, 13, 75, 28, 138, 139], 61)
|
||||
femmesh.addFace([14, 15, 76, 30, 140, 141], 62)
|
||||
femmesh.addFace([16, 17, 77, 32, 142, 143], 63)
|
||||
femmesh.addFace([18, 19, 78, 34, 144, 145], 64)
|
||||
femmesh.addFace([20, 21, 79, 36, 129, 146], 65)
|
||||
femmesh.addFace([42, 73, 43, 147, 103, 58], 66)
|
||||
femmesh.addFace([44, 74, 45, 106, 107, 60], 67)
|
||||
femmesh.addFace([46, 75, 47, 110, 111, 62], 68)
|
||||
femmesh.addFace([48, 76, 49, 114, 115, 64], 69)
|
||||
femmesh.addFace([50, 77, 51, 118, 119, 66], 70)
|
||||
femmesh.addFace([52, 78, 53, 122, 123, 68], 71)
|
||||
femmesh.addFace([54, 79, 55, 126, 130, 70], 72)
|
||||
femmesh.addFace([9, 81, 73, 148, 104, 134], 73)
|
||||
femmesh.addFace([10, 74, 81, 137, 105, 149], 74)
|
||||
femmesh.addFace([11, 82, 74, 150, 108, 136], 75)
|
||||
femmesh.addFace([12, 75, 82, 139, 109, 151], 76)
|
||||
femmesh.addFace([13, 83, 75, 152, 112, 138], 77)
|
||||
femmesh.addFace([14, 76, 83, 141, 113, 153], 78)
|
||||
femmesh.addFace([15, 84, 76, 154, 116, 140], 79)
|
||||
femmesh.addFace([16, 77, 84, 143, 117, 155], 80)
|
||||
femmesh.addFace([17, 85, 77, 156, 120, 142], 81)
|
||||
femmesh.addFace([18, 78, 85, 145, 121, 157], 82)
|
||||
femmesh.addFace([19, 86, 78, 158, 124, 144], 83)
|
||||
femmesh.addFace([20, 79, 86, 146, 125, 159], 84)
|
||||
femmesh.addFace([9, 10, 81, 25, 149, 148], 85)
|
||||
femmesh.addFace([11, 12, 82, 27, 151, 150], 86)
|
||||
femmesh.addFace([13, 14, 83, 29, 153, 152], 87)
|
||||
femmesh.addFace([15, 16, 84, 31, 155, 154], 88)
|
||||
femmesh.addFace([17, 18, 85, 33, 157, 156], 89)
|
||||
femmesh.addFace([19, 20, 86, 35, 159, 158], 90)
|
||||
femmesh.addFace([8, 73, 90, 135, 160, 161], 91)
|
||||
femmesh.addFace([2, 5, 87, 7, 162, 163], 92)
|
||||
femmesh.addFace([2, 87, 42, 163, 164, 57], 93)
|
||||
femmesh.addFace([42, 87, 73, 164, 165, 147], 94)
|
||||
femmesh.addFace([22, 89, 80, 166, 167, 132], 95)
|
||||
femmesh.addFace([4, 88, 39, 168, 169, 41], 96)
|
||||
femmesh.addFace([4, 56, 88, 72, 170, 168], 97)
|
||||
femmesh.addFace([56, 80, 88, 133, 171, 170], 98)
|
||||
femmesh.addFace([73, 87, 90, 165, 172, 160], 99)
|
||||
femmesh.addFace([3, 39, 89, 40, 173, 174], 100)
|
||||
femmesh.addFace([3, 89, 22, 174, 166, 38], 101)
|
||||
femmesh.addFace([1, 90, 5, 175, 176, 6], 102)
|
||||
femmesh.addFace([1, 8, 90, 23, 161, 175], 103)
|
||||
femmesh.addFace([80, 89, 88, 167, 177, 171], 104)
|
||||
femmesh.addFace([5, 90, 87, 176, 172, 162], 105)
|
||||
femmesh.addFace([39, 88, 89, 169, 177, 173], 106)
|
||||
return True
|
||||
@@ -79,7 +79,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
l4 = Part.makeLine((-142.5, 142.5, 0), (-142.5, -142.5, 0))
|
||||
wire = Part.Wire([l1, l2, l3, l4])
|
||||
shape = wire.extrude(Vector(0, 0, 1000))
|
||||
geom_obj = doc.addObject('Part::Feature', 'SquareTube')
|
||||
geom_obj = doc.addObject("Part::Feature", "SquareTube")
|
||||
geom_obj.Shape = shape
|
||||
doc.recompute()
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
l4 = Part.makeLine((-142.5, 142.5, 0), (-142.5, -142.5, 0))
|
||||
wire = Part.Wire([l1, l2, l3, l4])
|
||||
shape = wire.extrude(Vector(0, 0, 1000))
|
||||
geom_obj = doc.addObject('Part::Feature', 'SquareTube')
|
||||
geom_obj = doc.addObject("Part::Feature", "SquareTube")
|
||||
geom_obj.Shape = shape
|
||||
|
||||
points_forces = []
|
||||
@@ -182,9 +182,9 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
points_fixes.append(Part.Vertex(-71.25, 142.5, 1000.0))
|
||||
points_fixes.append(Part.Vertex(-118.75, 142.5, 1000.0))
|
||||
|
||||
geoforces_obj = doc.addObject('Part::Feature', 'Forces')
|
||||
geoforces_obj = doc.addObject("Part::Feature", "Forces")
|
||||
geoforces_obj.Shape = Part.makeCompound(points_forces)
|
||||
geofixes_obj = doc.addObject('Part::Feature', 'Fixes')
|
||||
geofixes_obj = doc.addObject("Part::Feature", "Fixes")
|
||||
geofixes_obj.Shape = Part.makeCompound(points_fixes)
|
||||
|
||||
doc.recompute()
|
||||
@@ -237,59 +237,59 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# constraint fixed
|
||||
con_fixed = ObjectsFem.makeConstraintFixed(doc, "ConstraintFixed")
|
||||
con_fixed.References = [
|
||||
(geofixes_obj, 'Vertex6'),
|
||||
(geofixes_obj, 'Vertex15'),
|
||||
(geofixes_obj, 'Vertex5'),
|
||||
(geofixes_obj, 'Vertex29'),
|
||||
(geofixes_obj, 'Vertex42'),
|
||||
(geofixes_obj, 'Vertex30'),
|
||||
(geofixes_obj, 'Vertex9'),
|
||||
(geofixes_obj, 'Vertex31'),
|
||||
(geofixes_obj, 'Vertex33'),
|
||||
(geofixes_obj, 'Vertex32'),
|
||||
(geofixes_obj, 'Vertex3'),
|
||||
(geofixes_obj, 'Vertex34'),
|
||||
(geofixes_obj, 'Vertex46'),
|
||||
(geofixes_obj, 'Vertex1'),
|
||||
(geofixes_obj, 'Vertex36'),
|
||||
(geofixes_obj, 'Vertex11'),
|
||||
(geofixes_obj, 'Vertex38'),
|
||||
(geofixes_obj, 'Vertex12'),
|
||||
(geofixes_obj, 'Vertex39'),
|
||||
(geofixes_obj, 'Vertex13'),
|
||||
(geofixes_obj, 'Vertex40'),
|
||||
(geofixes_obj, 'Vertex16'),
|
||||
(geofixes_obj, 'Vertex35'),
|
||||
(geofixes_obj, 'Vertex14'),
|
||||
(geofixes_obj, 'Vertex47'),
|
||||
(geofixes_obj, 'Vertex20'),
|
||||
(geofixes_obj, 'Vertex37'),
|
||||
(geofixes_obj, 'Vertex18'),
|
||||
(geofixes_obj, 'Vertex41'),
|
||||
(geofixes_obj, 'Vertex17'),
|
||||
(geofixes_obj, 'Vertex10'),
|
||||
(geofixes_obj, 'Vertex26'),
|
||||
(geofixes_obj, 'Vertex43'),
|
||||
(geofixes_obj, 'Vertex21'),
|
||||
(geofixes_obj, 'Vertex44'),
|
||||
(geofixes_obj, 'Vertex19'),
|
||||
(geofixes_obj, 'Vertex4'),
|
||||
(geofixes_obj, 'Vertex28'),
|
||||
(geofixes_obj, 'Vertex48'),
|
||||
(geofixes_obj, 'Vertex22'),
|
||||
(geofixes_obj, 'Vertex8'),
|
||||
(geofixes_obj, 'Vertex23'),
|
||||
(geofixes_obj, 'Vertex7'),
|
||||
(geofixes_obj, 'Vertex24'),
|
||||
(geofixes_obj, 'Vertex45'),
|
||||
(geofixes_obj, 'Vertex27'),
|
||||
(geofixes_obj, 'Vertex2'),
|
||||
(geofixes_obj, 'Vertex25')]
|
||||
(geofixes_obj, "Vertex6"),
|
||||
(geofixes_obj, "Vertex15"),
|
||||
(geofixes_obj, "Vertex5"),
|
||||
(geofixes_obj, "Vertex29"),
|
||||
(geofixes_obj, "Vertex42"),
|
||||
(geofixes_obj, "Vertex30"),
|
||||
(geofixes_obj, "Vertex9"),
|
||||
(geofixes_obj, "Vertex31"),
|
||||
(geofixes_obj, "Vertex33"),
|
||||
(geofixes_obj, "Vertex32"),
|
||||
(geofixes_obj, "Vertex3"),
|
||||
(geofixes_obj, "Vertex34"),
|
||||
(geofixes_obj, "Vertex46"),
|
||||
(geofixes_obj, "Vertex1"),
|
||||
(geofixes_obj, "Vertex36"),
|
||||
(geofixes_obj, "Vertex11"),
|
||||
(geofixes_obj, "Vertex38"),
|
||||
(geofixes_obj, "Vertex12"),
|
||||
(geofixes_obj, "Vertex39"),
|
||||
(geofixes_obj, "Vertex13"),
|
||||
(geofixes_obj, "Vertex40"),
|
||||
(geofixes_obj, "Vertex16"),
|
||||
(geofixes_obj, "Vertex35"),
|
||||
(geofixes_obj, "Vertex14"),
|
||||
(geofixes_obj, "Vertex47"),
|
||||
(geofixes_obj, "Vertex20"),
|
||||
(geofixes_obj, "Vertex37"),
|
||||
(geofixes_obj, "Vertex18"),
|
||||
(geofixes_obj, "Vertex41"),
|
||||
(geofixes_obj, "Vertex17"),
|
||||
(geofixes_obj, "Vertex10"),
|
||||
(geofixes_obj, "Vertex26"),
|
||||
(geofixes_obj, "Vertex43"),
|
||||
(geofixes_obj, "Vertex21"),
|
||||
(geofixes_obj, "Vertex44"),
|
||||
(geofixes_obj, "Vertex19"),
|
||||
(geofixes_obj, "Vertex4"),
|
||||
(geofixes_obj, "Vertex28"),
|
||||
(geofixes_obj, "Vertex48"),
|
||||
(geofixes_obj, "Vertex22"),
|
||||
(geofixes_obj, "Vertex8"),
|
||||
(geofixes_obj, "Vertex23"),
|
||||
(geofixes_obj, "Vertex7"),
|
||||
(geofixes_obj, "Vertex24"),
|
||||
(geofixes_obj, "Vertex45"),
|
||||
(geofixes_obj, "Vertex27"),
|
||||
(geofixes_obj, "Vertex2"),
|
||||
(geofixes_obj, "Vertex25")]
|
||||
analysis.addObject(con_fixed)
|
||||
|
||||
# con_force1
|
||||
con_force1 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce1")
|
||||
con_force1.References = [(geoforces_obj, 'Vertex1'), (geoforces_obj, 'Vertex14')]
|
||||
con_force1.References = [(geoforces_obj, "Vertex1"), (geoforces_obj, "Vertex14")]
|
||||
con_force1.Force = 5555.56
|
||||
con_force1.Direction = (geom_obj, ["Edge9"])
|
||||
con_force1.Reversed = False
|
||||
@@ -297,7 +297,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# con_force2
|
||||
con_force2 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce2")
|
||||
con_force2.References = [(geoforces_obj, 'Vertex2'), (geoforces_obj, 'Vertex8')]
|
||||
con_force2.References = [(geoforces_obj, "Vertex2"), (geoforces_obj, "Vertex8")]
|
||||
con_force2.Force = 5555.56
|
||||
con_force2.Direction = (geom_obj, ["Edge3"])
|
||||
con_force2.Reversed = False
|
||||
@@ -306,11 +306,11 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# con_force3
|
||||
con_force3 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce3")
|
||||
con_force3.References = [
|
||||
(geoforces_obj, 'Vertex20'),
|
||||
(geoforces_obj, 'Vertex21'),
|
||||
(geoforces_obj, 'Vertex22'),
|
||||
(geoforces_obj, 'Vertex23'),
|
||||
(geoforces_obj, 'Vertex24'), ]
|
||||
(geoforces_obj, "Vertex20"),
|
||||
(geoforces_obj, "Vertex21"),
|
||||
(geoforces_obj, "Vertex22"),
|
||||
(geoforces_obj, "Vertex23"),
|
||||
(geoforces_obj, "Vertex24"), ]
|
||||
con_force3.Force = 27777.78
|
||||
con_force3.Direction = (geom_obj, ["Edge9"])
|
||||
con_force3.Reversed = False
|
||||
@@ -319,11 +319,11 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# con_force4
|
||||
con_force4 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce4")
|
||||
con_force4.References = [
|
||||
(geoforces_obj, 'Vertex9'),
|
||||
(geoforces_obj, 'Vertex10'),
|
||||
(geoforces_obj, 'Vertex11'),
|
||||
(geoforces_obj, 'Vertex12'),
|
||||
(geoforces_obj, 'Vertex13'), ]
|
||||
(geoforces_obj, "Vertex9"),
|
||||
(geoforces_obj, "Vertex10"),
|
||||
(geoforces_obj, "Vertex11"),
|
||||
(geoforces_obj, "Vertex12"),
|
||||
(geoforces_obj, "Vertex13"), ]
|
||||
con_force4.Force = 27777.78
|
||||
con_force4.Direction = (geom_obj, ["Edge3"])
|
||||
con_force4.Reversed = False
|
||||
@@ -332,12 +332,12 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# con_force5
|
||||
con_force5 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce5")
|
||||
con_force5.References = [
|
||||
(geoforces_obj, 'Vertex43'),
|
||||
(geoforces_obj, 'Vertex44'),
|
||||
(geoforces_obj, 'Vertex45'),
|
||||
(geoforces_obj, 'Vertex46'),
|
||||
(geoforces_obj, 'Vertex47'),
|
||||
(geoforces_obj, 'Vertex48'), ]
|
||||
(geoforces_obj, "Vertex43"),
|
||||
(geoforces_obj, "Vertex44"),
|
||||
(geoforces_obj, "Vertex45"),
|
||||
(geoforces_obj, "Vertex46"),
|
||||
(geoforces_obj, "Vertex47"),
|
||||
(geoforces_obj, "Vertex48"), ]
|
||||
con_force5.Force = 66666.67
|
||||
con_force5.Direction = (geom_obj, ["Edge9"])
|
||||
con_force5.Reversed = False
|
||||
@@ -346,12 +346,12 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# con_force6
|
||||
con_force6 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce6")
|
||||
con_force6.References = [
|
||||
(geoforces_obj, 'Vertex31'),
|
||||
(geoforces_obj, 'Vertex32'),
|
||||
(geoforces_obj, 'Vertex33'),
|
||||
(geoforces_obj, 'Vertex34'),
|
||||
(geoforces_obj, 'Vertex35'),
|
||||
(geoforces_obj, 'Vertex36'), ]
|
||||
(geoforces_obj, "Vertex31"),
|
||||
(geoforces_obj, "Vertex32"),
|
||||
(geoforces_obj, "Vertex33"),
|
||||
(geoforces_obj, "Vertex34"),
|
||||
(geoforces_obj, "Vertex35"),
|
||||
(geoforces_obj, "Vertex36"), ]
|
||||
con_force6.Force = 66666.67
|
||||
con_force6.Direction = (geom_obj, ["Edge3"])
|
||||
con_force6.Reversed = False
|
||||
@@ -359,7 +359,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# con_force7
|
||||
con_force7 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce7")
|
||||
con_force7.References = [(geoforces_obj, 'Vertex1'), (geoforces_obj, 'Vertex2')]
|
||||
con_force7.References = [(geoforces_obj, "Vertex1"), (geoforces_obj, "Vertex2")]
|
||||
con_force7.Force = 5555.56
|
||||
con_force7.Direction = (geom_obj, ["Edge11"])
|
||||
con_force7.Reversed = False
|
||||
@@ -367,7 +367,7 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
|
||||
# con_force8
|
||||
con_force8 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce8")
|
||||
con_force8.References = [(geoforces_obj, 'Vertex8'), (geoforces_obj, 'Vertex14')]
|
||||
con_force8.References = [(geoforces_obj, "Vertex8"), (geoforces_obj, "Vertex14")]
|
||||
con_force8.Force = 5555.56
|
||||
con_force8.Direction = (geom_obj, ["Edge6"])
|
||||
con_force8.Reversed = False
|
||||
@@ -376,11 +376,11 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# con_force9
|
||||
con_force9 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce9")
|
||||
con_force9.References = [
|
||||
(geoforces_obj, 'Vertex3'),
|
||||
(geoforces_obj, 'Vertex4'),
|
||||
(geoforces_obj, 'Vertex5'),
|
||||
(geoforces_obj, 'Vertex6'),
|
||||
(geoforces_obj, 'Vertex7'), ]
|
||||
(geoforces_obj, "Vertex3"),
|
||||
(geoforces_obj, "Vertex4"),
|
||||
(geoforces_obj, "Vertex5"),
|
||||
(geoforces_obj, "Vertex6"),
|
||||
(geoforces_obj, "Vertex7"), ]
|
||||
con_force9.Force = 27777.78
|
||||
con_force9.Direction = (geom_obj, ["Edge11"])
|
||||
con_force9.Reversed = False
|
||||
@@ -389,11 +389,11 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# con_force10
|
||||
con_force10 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce10")
|
||||
con_force10.References = [
|
||||
(geoforces_obj, 'Vertex15'),
|
||||
(geoforces_obj, 'Vertex16'),
|
||||
(geoforces_obj, 'Vertex17'),
|
||||
(geoforces_obj, 'Vertex18'),
|
||||
(geoforces_obj, 'Vertex19'), ]
|
||||
(geoforces_obj, "Vertex15"),
|
||||
(geoforces_obj, "Vertex16"),
|
||||
(geoforces_obj, "Vertex17"),
|
||||
(geoforces_obj, "Vertex18"),
|
||||
(geoforces_obj, "Vertex19"), ]
|
||||
con_force10.Force = 27777.78
|
||||
con_force10.Direction = (geom_obj, ["Edge6"])
|
||||
con_force10.Reversed = False
|
||||
@@ -402,12 +402,12 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# con_force11
|
||||
con_force11 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce11")
|
||||
con_force11.References = [
|
||||
(geoforces_obj, 'Vertex25'),
|
||||
(geoforces_obj, 'Vertex26'),
|
||||
(geoforces_obj, 'Vertex27'),
|
||||
(geoforces_obj, 'Vertex28'),
|
||||
(geoforces_obj, 'Vertex29'),
|
||||
(geoforces_obj, 'Vertex30'), ]
|
||||
(geoforces_obj, "Vertex25"),
|
||||
(geoforces_obj, "Vertex26"),
|
||||
(geoforces_obj, "Vertex27"),
|
||||
(geoforces_obj, "Vertex28"),
|
||||
(geoforces_obj, "Vertex29"),
|
||||
(geoforces_obj, "Vertex30"), ]
|
||||
con_force11.Force = 66666.67
|
||||
con_force11.Direction = (geom_obj, ["Edge11"])
|
||||
con_force11.Reversed = False
|
||||
@@ -416,12 +416,12 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
# con_force12
|
||||
con_force12 = ObjectsFem.makeConstraintForce(doc, name="ConstraintForce12")
|
||||
con_force12.References = [
|
||||
(geoforces_obj, 'Vertex37'),
|
||||
(geoforces_obj, 'Vertex38'),
|
||||
(geoforces_obj, 'Vertex39'),
|
||||
(geoforces_obj, 'Vertex40'),
|
||||
(geoforces_obj, 'Vertex41'),
|
||||
(geoforces_obj, 'Vertex42'), ]
|
||||
(geoforces_obj, "Vertex37"),
|
||||
(geoforces_obj, "Vertex38"),
|
||||
(geoforces_obj, "Vertex39"),
|
||||
(geoforces_obj, "Vertex40"),
|
||||
(geoforces_obj, "Vertex41"),
|
||||
(geoforces_obj, "Vertex42"), ]
|
||||
con_force12.Force = 66666.67
|
||||
con_force12.Direction = (geom_obj, ["Edge6"])
|
||||
con_force12.Reversed = False
|
||||
|
||||
@@ -106,7 +106,8 @@ class Solve(run.Solve):
|
||||
[binary, "-i", _inputFileName],
|
||||
cwd=self.directory,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
stderr=subprocess.PIPE
|
||||
)
|
||||
self.signalAbort.add(self._process.terminate)
|
||||
# output = self._observeSolver(self._process)
|
||||
self._process.communicate()
|
||||
@@ -127,16 +128,23 @@ class Results(run.Results):
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/General")
|
||||
if not prefs.GetBool("KeepResultsOnReRun", False):
|
||||
self.purge_results()
|
||||
self.load_results_ccxfrd()
|
||||
self.load_results_ccxdat()
|
||||
self.load_results()
|
||||
|
||||
def purge_results(self):
|
||||
|
||||
# dat file will not be removed
|
||||
# results from other solvers will be removed too
|
||||
# the user should decide if purge should only delete the solver results or all results
|
||||
for m in membertools.get_member(self.analysis, "Fem::FemResultObject"):
|
||||
if m.Mesh and femutils.is_of_type(m.Mesh, "Fem::MeshResult"):
|
||||
self.analysis.Document.removeObject(m.Mesh.Name)
|
||||
self.analysis.Document.removeObject(m.Name)
|
||||
self.analysis.Document.recompute()
|
||||
|
||||
def load_results(self):
|
||||
self.load_results_ccxfrd()
|
||||
self.load_results_ccxdat()
|
||||
|
||||
def load_results_ccxfrd(self):
|
||||
frd_result_file = os.path.join(
|
||||
self.directory, _inputFileName + ".frd")
|
||||
|
||||
@@ -48,7 +48,7 @@ def write_meshdata_constraint(f, femobj, force_obj, ccxwriter):
|
||||
|
||||
direction_vec = femobj["Object"].DirectionVector
|
||||
for ref_shape in femobj["NodeLoadTable"]:
|
||||
f.write("** " + ref_shape[0] + "\n")
|
||||
f.write("** {}\n".format(ref_shape[0]))
|
||||
for n in sorted(ref_shape[1]):
|
||||
node_load = ref_shape[1][n]
|
||||
if (direction_vec.x != 0.0):
|
||||
|
||||
@@ -95,8 +95,8 @@ def run_fem_solver(solver, working_dir=None):
|
||||
|
||||
:note:
|
||||
There is some legacy code to execute the old Calculix solver
|
||||
(pre-framework) which behaives differently because it doesn't use a
|
||||
:class:`Machine`.
|
||||
(pre-framework) which behaives differently because it does not
|
||||
use a :class:`Machine`.
|
||||
"""
|
||||
|
||||
if solver.Proxy.Type == "Fem::SolverCcxTools":
|
||||
|
||||
@@ -85,7 +85,7 @@ def get_binary(name):
|
||||
|
||||
Return the specific path set by the user in FreeCADs settings/parameter
|
||||
system if set or the default binary name if no specific path is set. If no
|
||||
path was found because the solver *name* isn't supported ``None`` is
|
||||
path was found because the solver *name* is not supported ``None`` is
|
||||
returned. This method does not check whether the binary actually exists
|
||||
and is callable.
|
||||
|
||||
@@ -93,12 +93,15 @@ def get_binary(name):
|
||||
"""
|
||||
if name in _SOLVER_PARAM:
|
||||
binary = _SOLVER_PARAM[name].get_binary()
|
||||
FreeCAD.Console.PrintMessage('Solver binary path: {} \n'.format(binary))
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Solver binary path (returned from binary getter): {} \n'
|
||||
.format(binary)
|
||||
)
|
||||
return binary
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
'Settings solver name: {} not found in '
|
||||
'solver settings modules _SOLVER_PARAM dirctionary.\n'
|
||||
"Settings solver name: {} not found in "
|
||||
"solver settings modules _SOLVER_PARAM dirctionary.\n"
|
||||
.format(name)
|
||||
)
|
||||
return None
|
||||
@@ -108,8 +111,8 @@ def get_write_comments(name):
|
||||
""" Check whether "write_comments" is set for solver.
|
||||
|
||||
Returns ``True`` if the "write_comments" setting/parameter is set for the
|
||||
solver with the id *name*. Returns ``False`` otherwise. If the solver isn't
|
||||
supported ``None`` is returned.
|
||||
solver with the id *name*. Returns ``False`` otherwise. If the solver is
|
||||
not supported ``None`` is returned.
|
||||
|
||||
:param name: solver id as a ``str`` (see :mod:`femsolver.settings`)
|
||||
"""
|
||||
@@ -117,8 +120,8 @@ def get_write_comments(name):
|
||||
return _SOLVER_PARAM[name].get_write_comments()
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
'Settings solver name: {} not found in '
|
||||
'solver settings modules _SOLVER_PARAM dirctionary.\n'
|
||||
"Settings solver name: {} not found in "
|
||||
"solver settings modules _SOLVER_PARAM dirctionary.\n"
|
||||
.format(name)
|
||||
)
|
||||
return None
|
||||
@@ -190,19 +193,31 @@ class _SolverDlg(object):
|
||||
def get_binary(self):
|
||||
|
||||
# set the binary path to the FreeCAD defaults
|
||||
# ATM pure unix shell commands without path names are used
|
||||
# ATM pure unix shell commands without path names are used as standard
|
||||
# TODO the binaries provieded with the FreeCAD distribution should be found
|
||||
# without any additional user input
|
||||
# see ccxttols, it works for Windows and Linux there
|
||||
binary = self.default
|
||||
FreeCAD.Console.PrintLog("Solver binary path: {} \n".format(binary))
|
||||
FreeCAD.Console.PrintLog("Solver binary path default: {} \n".format(binary))
|
||||
|
||||
# check if use_default is set to True
|
||||
# if True the standard binary path will be overwritten with a user binary path
|
||||
if self.param_group.GetBool(self.use_default, True) is False:
|
||||
binary = self.param_group.GetString(self.custom_path)
|
||||
FreeCAD.Console.PrintLog("Solver binary path: {} \n".format(binary))
|
||||
FreeCAD.Console.PrintLog("Solver binary path user setting: {} \n".format(binary))
|
||||
|
||||
# get the whole binary path name for the given command or binary path and return it
|
||||
# None is returned if the binary has not been found
|
||||
# The user does not know what exactly has going wrong.
|
||||
from distutils.spawn import find_executable as find_bin
|
||||
return find_bin(binary)
|
||||
the_found_binary = find_bin(binary)
|
||||
if the_found_binary is None:
|
||||
FreeCAD.Console.PrintError(
|
||||
"The binary has not been found. Full binary search path: {}\n"
|
||||
.format(binary)
|
||||
)
|
||||
FreeCAD.Console.PrintLog("Solver binary found path: {}\n".format(the_found_binary))
|
||||
return the_found_binary
|
||||
|
||||
def get_write_comments(self):
|
||||
return self.param_group.GetBool(self.WRITE_COMMENTS_PARAM, True)
|
||||
|
||||
@@ -72,7 +72,7 @@ class ControlTaskPanel(QtCore.QObject):
|
||||
self.form.abortClicked.connect(self.abort)
|
||||
self.form.directoryChanged.connect(self.updateMachine)
|
||||
|
||||
# Seems that the task panel doesn't get destroyed. Disconnect
|
||||
# Seems that the task panel does not get destroyed. Disconnect
|
||||
# as soon as the widget of the task panel gets destroyed.
|
||||
self.form.destroyed.connect(self._disconnectMachine)
|
||||
self.form.destroyed.connect(self._timer.stop)
|
||||
|
||||
@@ -56,7 +56,7 @@ class FemInputWriter():
|
||||
self.document = self.analysis.Document
|
||||
# working dir
|
||||
self.dir_name = dir_name
|
||||
# if dir_name was not given or if it exists but isn't empty: create a temporary dir
|
||||
# if dir_name was not given or if it exists but is not empty: create a temporary dir
|
||||
# Purpose: makes sure the analysis can be run even on wired situation
|
||||
if not dir_name:
|
||||
FreeCAD.Console.PrintWarning(
|
||||
|
||||
@@ -112,7 +112,7 @@ class Results(run.Results):
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/General")
|
||||
if not prefs.GetBool("KeepResultsOnReRun", False):
|
||||
self.purge_results()
|
||||
self.load_results_z88o2()
|
||||
self.load_results()
|
||||
|
||||
def purge_results(self):
|
||||
for m in membertools.get_member(self.analysis, "Fem::FemResultObject"):
|
||||
@@ -121,7 +121,8 @@ class Results(run.Results):
|
||||
self.analysis.Document.removeObject(m.Name)
|
||||
self.analysis.Document.recompute()
|
||||
|
||||
def load_results_z88o2(self):
|
||||
def load_results(self):
|
||||
# displacements from z88o2 file
|
||||
disp_result_file = os.path.join(
|
||||
self.directory, "z88o2.txt")
|
||||
if os.path.isfile(disp_result_file):
|
||||
|
||||
@@ -104,7 +104,7 @@ class TestSolverCalculix(unittest.TestCase):
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccxcantilever_faceload(
|
||||
def test_ccx_cantilever_faceload(
|
||||
self
|
||||
):
|
||||
from femexamples.ccx_cantilever_faceload import setup
|
||||
@@ -112,15 +112,15 @@ class TestSolverCalculix(unittest.TestCase):
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccxcantilever_hexa20(
|
||||
def test_ccx_cantilever_ele_hexa20(
|
||||
self
|
||||
):
|
||||
from femexamples.ccx_cantilever_hexa20faceload import setup
|
||||
from femexamples.ccx_cantilever_ele_hexa20 import setup
|
||||
setup(self.document, "calculix")
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccxcantilever_nodeload(
|
||||
def test_ccx_cantilever_nodeload(
|
||||
self
|
||||
):
|
||||
from femexamples.ccx_cantilever_nodeload import setup
|
||||
@@ -128,7 +128,7 @@ class TestSolverCalculix(unittest.TestCase):
|
||||
self.input_file_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccxcantilever_prescribeddisplacement(
|
||||
def test_ccx_cantilever_prescribeddisplacement(
|
||||
self
|
||||
):
|
||||
from femexamples.ccx_cantilever_prescribeddisplacement import setup
|
||||
|
||||
@@ -76,7 +76,7 @@ class TestSolverZ88(unittest.TestCase):
|
||||
))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccxcantilever_faceload(
|
||||
def test_ccx_cantilever_faceload(
|
||||
self
|
||||
):
|
||||
from femexamples.ccx_cantilever_faceload import setup
|
||||
@@ -84,15 +84,15 @@ class TestSolverZ88(unittest.TestCase):
|
||||
self.inputfile_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccxcantilever_hexa20(
|
||||
def test_ccx_cantilever_ele_hexa20(
|
||||
self
|
||||
):
|
||||
from femexamples.ccx_cantilever_hexa20faceload import setup
|
||||
from femexamples.ccx_cantilever_ele_hexa20 import setup
|
||||
setup(self.document, "z88")
|
||||
self.inputfile_writing_test(get_namefromdef("test_"))
|
||||
|
||||
# ********************************************************************************************
|
||||
def test_ccxcantilever_nodeload(
|
||||
def test_ccx_cantilever_nodeload(
|
||||
self
|
||||
):
|
||||
from femexamples.ccx_cantilever_nodeload import setup
|
||||
|
||||
@@ -194,7 +194,14 @@ SET(Tools_Shape_SRCS
|
||||
|
||||
SET(PathTests_SRCS
|
||||
PathTests/__init__.py
|
||||
PathTests/boxtest.fcstd
|
||||
PathTests/PathTestUtils.py
|
||||
PathTests/test_adaptive.fcstd
|
||||
PathTests/test_centroid_00.ngc
|
||||
PathTests/test_geomop.fcstd
|
||||
PathTests/test_holes00.fcstd
|
||||
PathTests/test_linuxcnc_00.ngc
|
||||
PathTests/TestPathAdaptive.py
|
||||
PathTests/TestPathCore.py
|
||||
PathTests/TestPathDeburr.py
|
||||
PathTests/TestPathDepthParams.py
|
||||
@@ -220,11 +227,6 @@ SET(PathTests_SRCS
|
||||
PathTests/Tools/Bit/test-path-tool-bit-bit-00.fctb
|
||||
PathTests/Tools/Library/test-path-tool-bit-library-00.fctl
|
||||
PathTests/Tools/Shape/test-path-tool-bit-shape-00.fcstd
|
||||
PathTests/boxtest.fcstd
|
||||
PathTests/test_centroid_00.ngc
|
||||
PathTests/test_geomop.fcstd
|
||||
PathTests/test_holes00.fcstd
|
||||
PathTests/test_linuxcnc_00.ngc
|
||||
)
|
||||
|
||||
SET(PathImages_Ops
|
||||
|
||||
@@ -42,6 +42,7 @@ Part = LazyLoader('Part', globals(), 'Part')
|
||||
FeatureExtensions = LazyLoader('PathScripts.PathFeatureExtensions',
|
||||
globals(),
|
||||
'PathScripts.PathFeatureExtensions')
|
||||
DraftGeomUtils = LazyLoader('DraftGeomUtils', globals(), 'DraftGeomUtils')
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
from pivy import coin
|
||||
@@ -559,16 +560,16 @@ def Execute(op, obj):
|
||||
|
||||
|
||||
def _get_working_edges(op, obj):
|
||||
"""_get_working_edges(op, obj)...
|
||||
'''_get_working_edges(op, obj)...
|
||||
Compile all working edges from the Base Geometry selection (obj.Base)
|
||||
for the current operation.
|
||||
Additional modifications to selected region(face), such as extensions,
|
||||
should be placed within this function.
|
||||
"""
|
||||
regions = list()
|
||||
'''
|
||||
all_regions = list()
|
||||
edge_list = list()
|
||||
avoidFeatures = list()
|
||||
rawEdges = list()
|
||||
|
||||
# Get extensions and identify faces to avoid
|
||||
extensions = FeatureExtensions.getExtensions(obj)
|
||||
@@ -579,20 +580,30 @@ def _get_working_edges(op, obj):
|
||||
# Get faces selected by user
|
||||
for base, subs in obj.Base:
|
||||
for sub in subs:
|
||||
if sub not in avoidFeatures:
|
||||
if obj.UseOutline:
|
||||
face = base.Shape.getElement(sub)
|
||||
# get outline with wire_A method used in PocketShape, but it does not play nicely later
|
||||
# wire_A = TechDraw.findShapeOutline(face, 1, FreeCAD.Vector(0.0, 0.0, 1.0))
|
||||
wire_B = face.Wires[0]
|
||||
shape = Part.Face(wire_B)
|
||||
else:
|
||||
shape = base.Shape.getElement(sub)
|
||||
regions.append(shape)
|
||||
if sub.startswith("Face"):
|
||||
if sub not in avoidFeatures:
|
||||
if obj.UseOutline:
|
||||
face = base.Shape.getElement(sub)
|
||||
# get outline with wire_A method used in PocketShape, but it does not play nicely later
|
||||
# wire_A = TechDraw.findShapeOutline(face, 1, FreeCAD.Vector(0.0, 0.0, 1.0))
|
||||
wire_B = face.Wires[0]
|
||||
shape = Part.Face(wire_B)
|
||||
else:
|
||||
shape = base.Shape.getElement(sub)
|
||||
all_regions.append(shape)
|
||||
elif sub.startswith("Edge"):
|
||||
# Save edges for later processing
|
||||
rawEdges.append(base.Shape.getElement(sub))
|
||||
# Efor
|
||||
|
||||
# Return Extend Outline extension, OR regular edge extension
|
||||
all_regions = regions
|
||||
# Process selected edges
|
||||
if rawEdges:
|
||||
edgeWires = DraftGeomUtils.findWires(rawEdges)
|
||||
if edgeWires:
|
||||
for w in edgeWires:
|
||||
for e in w.Edges:
|
||||
edge_list.append([discretize(e)])
|
||||
|
||||
# Apply regular Extensions
|
||||
op.exts = [] # pylint: disable=attribute-defined-outside-init
|
||||
for ext in extensions:
|
||||
@@ -605,10 +616,12 @@ def _get_working_edges(op, obj):
|
||||
|
||||
# Second face-combining method attempted
|
||||
horizontal = PathGeom.combineHorizontalFaces(all_regions)
|
||||
for f in horizontal:
|
||||
for w in f.Wires:
|
||||
for e in w.Edges:
|
||||
edge_list.append([discretize(e)])
|
||||
if horizontal:
|
||||
obj.removalshape = Part.makeCompound(horizontal)
|
||||
for f in horizontal:
|
||||
for w in f.Wires:
|
||||
for e in w.Edges:
|
||||
edge_list.append([discretize(e)])
|
||||
|
||||
return edge_list
|
||||
|
||||
@@ -662,6 +675,9 @@ class PathAdaptive(PathOp.ObjectOp):
|
||||
|
||||
obj.addProperty("App::PropertyBool", "UseOutline", "Adaptive", "Uses the outline of the base geometry.")
|
||||
|
||||
obj.addProperty("Part::PropertyPartShape", "removalshape", "Path", "")
|
||||
obj.setEditorMode('removalshape', 2) # hide
|
||||
|
||||
FeatureExtensions.initialize_properties(obj)
|
||||
|
||||
def opSetDefaultValues(self, obj, job):
|
||||
@@ -703,6 +719,11 @@ class PathAdaptive(PathOp.ObjectOp):
|
||||
"UseOutline",
|
||||
"Adaptive",
|
||||
"Uses the outline of the base geometry.")
|
||||
|
||||
if not hasattr(obj, "removalshape"):
|
||||
obj.addProperty("Part::PropertyPartShape", "removalshape", "Path", "")
|
||||
obj.setEditorMode('removalshape', 2) # hide
|
||||
|
||||
FeatureExtensions.initialize_properties(obj)
|
||||
|
||||
|
||||
|
||||
@@ -440,7 +440,7 @@ class TaskPanelExtensionPage(PathOpGui.TaskPanelPage):
|
||||
baseItem.setData(base[0].Label, QtCore.Qt.EditRole)
|
||||
baseItem.setSelectable(False)
|
||||
for sub in sorted(base[1]):
|
||||
if sub.startswith('Face') or True:
|
||||
if sub.startswith('Face'):
|
||||
show = True
|
||||
baseItem.appendRow(self.createItemForBaseModel(base[0], sub, edges, extensions))
|
||||
if show:
|
||||
|
||||
@@ -213,7 +213,8 @@ class JobCreate:
|
||||
def setupTemplate(self):
|
||||
templateFiles = []
|
||||
for path in PathPreferences.searchPaths():
|
||||
templateFiles.extend(self.templateFilesIn(path))
|
||||
cleanPaths = [f.replace("\\", "/") for f in self.templateFilesIn(path)] # Standardize slashes used accross os platforms
|
||||
templateFiles.extend(cleanPaths)
|
||||
|
||||
template = {}
|
||||
for tFile in templateFiles:
|
||||
|
||||
459
src/Mod/Path/PathTests/TestPathAdaptive.py
Normal file
459
src/Mod/Path/PathTests/TestPathAdaptive.py
Normal file
@@ -0,0 +1,459 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2021 Russell Johnson (russ4262) <russ4262@gmail.com> *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
import Part
|
||||
import PathScripts.PathJob as PathJob
|
||||
import PathScripts.PathAdaptive as PathAdaptive
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
from PathTests.PathTestUtils import PathTestBase
|
||||
if FreeCAD.GuiUp:
|
||||
import PathScripts.PathAdaptiveGui as PathAdaptiveGui
|
||||
import PathScripts.PathJobGui as PathJobGui
|
||||
|
||||
|
||||
class TestPathAdaptive(PathTestBase):
|
||||
'''Unit tests for the Adaptive operation.'''
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
'''setUpClass()...
|
||||
This method is called upon instantiation of this test class. Add code and objects here
|
||||
that are needed for the duration of the test() methods in this class. In other words,
|
||||
set up the 'global' test environment here; use the `setUp()` method to set up a 'local'
|
||||
test environment.
|
||||
This method does not have access to the class `self` reference, but it
|
||||
is able to call static methods within this same class.
|
||||
'''
|
||||
|
||||
# Open existing FreeCAD document with test geometry
|
||||
doc = FreeCAD.open(FreeCAD.getHomePath() + 'Mod/Path/PathTests/test_adaptive.fcstd')
|
||||
|
||||
# Create Job object, adding geometry objects from file opened above
|
||||
job = PathJob.Create('Job', [doc.Fusion], None)
|
||||
job.GeometryTolerance.Value = 0.001
|
||||
if FreeCAD.GuiUp:
|
||||
job.ViewObject.Proxy = PathJobGui.ViewProvider(job.ViewObject)
|
||||
|
||||
# Instantiate an Adaptive operation for quering available properties
|
||||
prototype = PathAdaptive.Create("Adaptive")
|
||||
prototype.Base = [(doc.Fusion, ["Face3"])]
|
||||
prototype.Label = "Prototype"
|
||||
_addViewProvider(prototype)
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
'''tearDownClass()...
|
||||
This method is called prior to destruction of this test class. Add code and objects here
|
||||
that cleanup the test environment after the test() methods in this class have been executed.
|
||||
This method does not have access to the class `self` reference. This method
|
||||
is able to call static methods within this same class.
|
||||
'''
|
||||
# FreeCAD.Console.PrintMessage("TestPathAdaptive.tearDownClass()\n")
|
||||
|
||||
# Close geometry document without saving
|
||||
FreeCAD.closeDocument(FreeCAD.ActiveDocument.Name)
|
||||
|
||||
# Setup and tear down methods called before and after each unit test
|
||||
def setUp(self):
|
||||
'''setUp()...
|
||||
This method is called prior to each `test()` method. Add code and objects here
|
||||
that are needed for multiple `test()` methods.
|
||||
'''
|
||||
self.doc = FreeCAD.ActiveDocument
|
||||
self.con = FreeCAD.Console
|
||||
|
||||
def tearDown(self):
|
||||
'''tearDown()...
|
||||
This method is called after each test() method. Add cleanup instructions here.
|
||||
Such cleanup instructions will likely undo those in the setUp() method.
|
||||
'''
|
||||
pass
|
||||
|
||||
# Unit tests
|
||||
def test00(self):
|
||||
'''test00() Empty test.'''
|
||||
return
|
||||
|
||||
def test01(self):
|
||||
'''test01() Verify path generated on Face3.'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Face3"])] # (base, subs_list)
|
||||
adaptive.Label = "test01+"
|
||||
adaptive.Comment = "test01() Verify path generated on Face3."
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
# moves = getGcodeMoves(adaptive.Path.Commands, includeRapids=False)
|
||||
# operationMoves = "; ".join(moves)
|
||||
# self.con.PrintMessage("test00_moves: " + operationMoves + "\n")
|
||||
|
||||
# self.assertTrue(expected_moves_test01 == operationMoves,
|
||||
# "expected_moves_test01: {}\noperationMoves: {}".format(expected_moves_test01, operationMoves))
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test02(self):
|
||||
'''test02() Verify path generated on adjacent, combined Face3 and Face10. The Z heights are different.'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Face3", "Face10"])] # (base, subs_list)
|
||||
adaptive.Label = "test02+"
|
||||
adaptive.Comment = "test02() Verify path generated on adjacent, combined Face3 and Face10. The Z heights are different."
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test03(self):
|
||||
'''test03() Verify path generated on adjacent, combined Face3 and Face10. The Z heights are different.'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Face3", "Face10"])] # (base, subs_list)
|
||||
adaptive.Label = "test03+"
|
||||
adaptive.Comment = "test03() Verify path generated on adjacent, combined Face3 and Face10. The Z heights are different."
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = True
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test04(self):
|
||||
'''test04() Verify path generated non-closed edges with differing Z-heights that are closed with Z=1 projection: "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19".'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19"])] # (base, subs_list)
|
||||
adaptive.Label = "test04+"
|
||||
adaptive.Comment = 'test04() Verify path generated non-closed edges with differing Z-heights that are closed with Z=1 projection: "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19".'
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test05(self):
|
||||
'''test05() Verify path generated closed wire with differing Z-heights: "Edge13", "Edge7", "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19".'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Edge13", "Edge7", "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19"])] # (base, subs_list)
|
||||
adaptive.Label = "test05+"
|
||||
adaptive.Comment = 'test05() Verify path generated closed wire with differing Z-heights: "Edge13", "Edge7", "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19".'
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test06(self):
|
||||
'''test06() Verify path generated with outer and inner edge loops at same Z height: "Edge15", "Edge30", "Edge31", "Edge29", "Edge19", "Edge18", "Edge35", "Edge32", "Edge34", "Edge33".'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Edge15", "Edge30", "Edge31", "Edge29", "Edge19", "Edge18", "Edge35", "Edge32", "Edge34", "Edge33"])] # (base, subs_list)
|
||||
adaptive.Label = "test06+"
|
||||
adaptive.Comment = 'test06() Verify path generated with outer and inner edge loops at same Z height: "Edge15", "Edge30", "Edge31", "Edge29", "Edge19", "Edge18", "Edge35", "Edge32", "Edge34", "Edge33".'
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
# Check command count
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
# Check if any paths originate inside inner hole of donut. They should not.
|
||||
isInBox = False
|
||||
edges = [self.doc.Fusion.Shape.getElement(e) for e in ["Edge35", "Edge32", "Edge33", "Edge34"]]
|
||||
square = Part.Wire(edges)
|
||||
sqrBB = square.BoundBox
|
||||
minPoint = FreeCAD.Vector(sqrBB.XMin, sqrBB.YMin, 0.0)
|
||||
maxPoint = FreeCAD.Vector(sqrBB.XMax, sqrBB.YMax, 0.0)
|
||||
for c in adaptive.Path.Commands:
|
||||
if pathOriginatesInBox(c, minPoint, maxPoint):
|
||||
isInBox = True
|
||||
break
|
||||
self.assertFalse(isInBox, "Paths originating within the inner hole.")
|
||||
|
||||
def test07(self):
|
||||
'''test07() Verify path generated on donut-shaped Face10.'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Face10"])] # (base, subs_list)
|
||||
adaptive.Label = "test07+"
|
||||
adaptive.Comment = "test07() Verify path generated on donut-shaped Face10."
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
# Check if any paths originate inside inner hole of donut. They should not.
|
||||
isInBox = False
|
||||
edges = [self.doc.Fusion.Shape.getElement(e) for e in ["Edge35", "Edge32", "Edge33", "Edge34"]]
|
||||
square = Part.Wire(edges)
|
||||
sqrBB = square.BoundBox
|
||||
minPoint = FreeCAD.Vector(sqrBB.XMin, sqrBB.YMin, 0.0)
|
||||
maxPoint = FreeCAD.Vector(sqrBB.XMax, sqrBB.YMax, 0.0)
|
||||
for c in adaptive.Path.Commands:
|
||||
if pathOriginatesInBox(c, minPoint, maxPoint):
|
||||
isInBox = True
|
||||
break
|
||||
self.assertFalse(isInBox, "Paths originating within the inner hole.")
|
||||
|
||||
# Set Adaptive op to only use the outline of the face.
|
||||
adaptive.UseOutline = True
|
||||
self.doc.recompute()
|
||||
|
||||
# Check if any paths originate inside inner hole of donut. They should not.
|
||||
isInBox = False
|
||||
edges = [self.doc.Fusion.Shape.getElement(e) for e in ["Edge35", "Edge32", "Edge33", "Edge34"]]
|
||||
square = Part.Wire(edges)
|
||||
sqrBB = square.BoundBox
|
||||
minPoint = FreeCAD.Vector(sqrBB.XMin, sqrBB.YMin, 0.0)
|
||||
maxPoint = FreeCAD.Vector(sqrBB.XMax, sqrBB.YMax, 0.0)
|
||||
for c in adaptive.Path.Commands:
|
||||
if pathOriginatesInBox(c, minPoint, maxPoint):
|
||||
isInBox = True
|
||||
break
|
||||
self.assertTrue(isInBox, "No paths originating within the inner hole.")
|
||||
# Eclass
|
||||
|
||||
|
||||
def setDepthsAndHeights(op, strDep=20.0, finDep=0.0):
|
||||
'''setDepthsAndHeights(op, strDep=20.0, finDep=0.0)... Sets default depths and heights for `op` passed to it'''
|
||||
|
||||
# Set start and final depth in order to eliminate effects of stock (and its default values)
|
||||
op.setExpression('StartDepth', None)
|
||||
op.StartDepth.Value = strDep
|
||||
op.setExpression('FinalDepth', None)
|
||||
op.FinalDepth.Value = finDep
|
||||
|
||||
# Set step down so as to only produce one layer path
|
||||
op.setExpression('StepDown', None)
|
||||
op.StepDown.Value = 20.0
|
||||
|
||||
# Set Heights
|
||||
# default values used
|
||||
|
||||
|
||||
def getGcodeMoves(cmdList, includeRapids=True, includeLines=True, includeArcs=True):
|
||||
'''getGcodeMoves(cmdList, includeRapids=True, includeLines=True, includeArcs=True)...
|
||||
Accepts command dict and returns point string coordinate.
|
||||
'''
|
||||
gcode_list = list()
|
||||
last = FreeCAD.Vector(0.0, 0.0, 0.0)
|
||||
for c in cmdList:
|
||||
p = c.Parameters
|
||||
name = c.Name
|
||||
if includeRapids and name in ["G0", "G00"]:
|
||||
gcode = name
|
||||
x = last.x
|
||||
y = last.y
|
||||
z = last.z
|
||||
if p.get("X"):
|
||||
x = round(p["X"], 2)
|
||||
gcode += " X" + str(x)
|
||||
if p.get("Y"):
|
||||
y = round(p["Y"], 2)
|
||||
gcode += " Y" + str(y)
|
||||
if p.get("Z"):
|
||||
z = round(p["Z"], 2)
|
||||
gcode += " Z" + str(z)
|
||||
last.x = x
|
||||
last.y = y
|
||||
last.z = z
|
||||
gcode_list.append(gcode)
|
||||
elif includeLines and name in ["G1", "G01"]:
|
||||
gcode = name
|
||||
x = last.x
|
||||
y = last.y
|
||||
z = last.z
|
||||
if p.get("X"):
|
||||
x = round(p["X"], 2)
|
||||
gcode += " X" + str(x)
|
||||
if p.get("Y"):
|
||||
y = round(p["Y"], 2)
|
||||
gcode += " Y" + str(y)
|
||||
if p.get("Z"):
|
||||
z = round(p["Z"], 2)
|
||||
gcode += " Z" + str(z)
|
||||
last.x = x
|
||||
last.y = y
|
||||
last.z = z
|
||||
gcode_list.append(gcode)
|
||||
elif includeArcs and name in ["G2", "G3", "G02", "G03"]:
|
||||
gcode = name
|
||||
x = last.x
|
||||
y = last.y
|
||||
z = last.z
|
||||
i = 0.0
|
||||
j = 0.0
|
||||
k = 0.0
|
||||
if p.get("I"):
|
||||
i = round(p["I"], 2)
|
||||
gcode += " I" + str(i)
|
||||
if p.get("J"):
|
||||
j = round(p["J"], 2)
|
||||
gcode += " J" + str(j)
|
||||
if p.get("K"):
|
||||
k = round(p["K"], 2)
|
||||
gcode += " K" + str(k)
|
||||
|
||||
if p.get("X"):
|
||||
x = round(p["X"], 2)
|
||||
gcode += " X" + str(x)
|
||||
if p.get("Y"):
|
||||
y = round(p["Y"], 2)
|
||||
gcode += " Y" + str(y)
|
||||
if p.get("Z"):
|
||||
z = round(p["Z"], 2)
|
||||
gcode += " Z" + str(z)
|
||||
|
||||
gcode_list.append(gcode)
|
||||
last.x = x
|
||||
last.y = y
|
||||
last.z = z
|
||||
return gcode_list
|
||||
|
||||
|
||||
def pathOriginatesInBox(cmd, minPoint, maxPoint):
|
||||
p = cmd.Parameters
|
||||
name = cmd.Name
|
||||
if name in ["G0", "G00", "G1", "G01"]:
|
||||
if p.get("X") and p.get("Y"):
|
||||
x = p.get("X")
|
||||
y = p.get("Y")
|
||||
if x > minPoint.x and y > minPoint.y and x < maxPoint.x and y < maxPoint.y:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _addViewProvider(adaptiveOp):
|
||||
if FreeCAD.GuiUp:
|
||||
PathOpGui = PathAdaptiveGui.PathOpGui
|
||||
cmdRes = PathAdaptiveGui.Command.res
|
||||
adaptiveOp.ViewObject.Proxy = PathOpGui.ViewProvider(adaptiveOp.ViewObject, cmdRes)
|
||||
|
||||
|
||||
# Example string literal of expected path moves from an operation
|
||||
# Expected moves for unit test01
|
||||
expected_moves_test01 = "G1 X32.5 Y32.5 Z5.0; \
|
||||
G1 X17.5 Y32.5 Z5.0; \
|
||||
G1 X17.5 Y30.0 Z5.0; \
|
||||
G1 X32.5 Y30.0 Z5.0; \
|
||||
G1 X32.5 Y27.5 Z5.0; \
|
||||
G1 X17.5 Y27.5 Z5.0; \
|
||||
G1 X17.5 Y25.0 Z5.0; \
|
||||
G1 X32.5 Y25.0 Z5.0; \
|
||||
G1 X32.5 Y22.5 Z5.0; \
|
||||
G1 X17.5 Y22.5 Z5.0; \
|
||||
G1 X17.5 Y20.0 Z5.0; \
|
||||
G1 X32.5 Y20.0 Z5.0; \
|
||||
G1 X32.5 Y17.5 Z5.0; \
|
||||
G1 X17.5 Y17.5 Z5.0"
|
||||
BIN
src/Mod/Path/PathTests/test_adaptive.fcstd
Normal file
BIN
src/Mod/Path/PathTests/test_adaptive.fcstd
Normal file
Binary file not shown.
@@ -22,50 +22,51 @@
|
||||
|
||||
import TestApp
|
||||
|
||||
from PathTests.TestPathLog import TestPathLog
|
||||
from PathTests.TestPathPreferences import TestPathPreferences
|
||||
from PathTests.TestPathPropertyBag import TestPathPropertyBag
|
||||
from PathTests.TestPathCore import TestPathCore
|
||||
#from PathTests.TestPathPost import PathPostTestCases
|
||||
from PathTests.TestPathGeom import TestPathGeom
|
||||
from PathTests.TestPathOpTools import TestPathOpTools
|
||||
from PathTests.TestPathUtil import TestPathUtil
|
||||
# from PathTests.TestPathPost import PathPostTestCases
|
||||
from PathTests.TestPathAdaptive import TestPathAdaptive
|
||||
from PathTests.TestPathCore import TestPathCore
|
||||
from PathTests.TestPathDeburr import TestPathDeburr
|
||||
from PathTests.TestPathDepthParams import depthTestCases
|
||||
from PathTests.TestPathDressupHoldingTags import TestHoldingTags
|
||||
from PathTests.TestPathDressupDogbone import TestDressupDogbone
|
||||
from PathTests.TestPathStock import TestPathStock
|
||||
from PathTests.TestPathTool import TestPathTool
|
||||
from PathTests.TestPathToolBit import TestPathToolBit
|
||||
from PathTests.TestPathTooltable import TestPathTooltable
|
||||
from PathTests.TestPathToolController import TestPathToolController
|
||||
from PathTests.TestPathDressupHoldingTags import TestHoldingTags
|
||||
from PathTests.TestPathGeom import TestPathGeom
|
||||
from PathTests.TestPathHelix import TestPathHelix
|
||||
from PathTests.TestPathLog import TestPathLog
|
||||
from PathTests.TestPathOpTools import TestPathOpTools
|
||||
from PathTests.TestPathPreferences import TestPathPreferences
|
||||
from PathTests.TestPathPropertyBag import TestPathPropertyBag
|
||||
from PathTests.TestPathSetupSheet import TestPathSetupSheet
|
||||
from PathTests.TestPathDeburr import TestPathDeburr
|
||||
from PathTests.TestPathHelix import TestPathHelix
|
||||
from PathTests.TestPathVoronoi import TestPathVoronoi
|
||||
from PathTests.TestPathThreadMilling import TestPathThreadMilling
|
||||
from PathTests.TestPathVcarve import TestPathVcarve
|
||||
from PathTests.TestPathStock import TestPathStock
|
||||
from PathTests.TestPathThreadMilling import TestPathThreadMilling
|
||||
from PathTests.TestPathTool import TestPathTool
|
||||
from PathTests.TestPathToolBit import TestPathToolBit
|
||||
from PathTests.TestPathToolController import TestPathToolController
|
||||
from PathTests.TestPathTooltable import TestPathTooltable
|
||||
from PathTests.TestPathUtil import TestPathUtil
|
||||
from PathTests.TestPathVcarve import TestPathVcarve
|
||||
from PathTests.TestPathVoronoi import TestPathVoronoi
|
||||
|
||||
# dummy usage to get flake8 and lgtm quiet
|
||||
False if TestApp.__name__ else True
|
||||
False if TestPathLog.__name__ else True
|
||||
False if TestPathCore.__name__ else True
|
||||
False if TestPathGeom.__name__ else True
|
||||
False if TestPathOpTools.__name__ else True
|
||||
False if TestPathUtil.__name__ else True
|
||||
False if depthTestCases.__name__ else True
|
||||
False if TestHoldingTags.__name__ else True
|
||||
False if TestApp.__name__ else True
|
||||
False if TestDressupDogbone.__name__ else True
|
||||
False if TestPathStock.__name__ else True
|
||||
False if TestPathTool.__name__ else True
|
||||
False if TestPathTooltable.__name__ else True
|
||||
False if TestPathToolController.__name__ else True
|
||||
False if TestPathSetupSheet.__name__ else True
|
||||
False if TestHoldingTags.__name__ else True
|
||||
False if TestPathAdaptive.__name__ else True
|
||||
False if TestPathCore.__name__ else True
|
||||
False if TestPathDeburr.__name__ else True
|
||||
False if TestPathGeom.__name__ else True
|
||||
False if TestPathHelix.__name__ else True
|
||||
False if TestPathLog.__name__ else True
|
||||
False if TestPathOpTools.__name__ else True
|
||||
False if TestPathPreferences.__name__ else True
|
||||
False if TestPathToolBit.__name__ else True
|
||||
False if TestPathVoronoi.__name__ else True
|
||||
False if TestPathThreadMilling.__name__ else True
|
||||
False if TestPathVcarve.__name__ else True
|
||||
False if TestPathPropertyBag.__name__ else True
|
||||
|
||||
False if TestPathSetupSheet.__name__ else True
|
||||
False if TestPathStock.__name__ else True
|
||||
False if TestPathThreadMilling.__name__ else True
|
||||
False if TestPathTool.__name__ else True
|
||||
False if TestPathToolBit.__name__ else True
|
||||
False if TestPathToolController.__name__ else True
|
||||
False if TestPathTooltable.__name__ else True
|
||||
False if TestPathUtil.__name__ else True
|
||||
False if TestPathVcarve.__name__ else True
|
||||
False if TestPathVoronoi.__name__ else True
|
||||
|
||||
Reference in New Issue
Block a user