diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 88460c7304ff..38aab6b7c52d 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -206,6 +206,7 @@ SET(FemObjectsScripts_SRCS femobjects/_FemElementGeometry2D.py femobjects/_FemElementRotation1D.py femobjects/_FemMaterial.py + femobjects/_FemMaterialReinforced.py femobjects/_FemMaterialMechanicalNonlinear.py femobjects/_FemMeshBoundaryLayer.py femobjects/_FemMeshGmsh.py @@ -286,6 +287,7 @@ SET(FemGuiScripts_SRCS femguiobjects/_ViewProviderFemElementGeometry2D.py femguiobjects/_ViewProviderFemElementRotation1D.py femguiobjects/_ViewProviderFemMaterial.py + femguiobjects/_ViewProviderFemMaterialReinforced.py femguiobjects/_ViewProviderFemMaterialMechanicalNonlinear.py femguiobjects/_ViewProviderFemMeshBoundaryLayer.py femguiobjects/_ViewProviderFemMeshGmsh.py diff --git a/src/Mod/Fem/ObjectsFem.py b/src/Mod/Fem/ObjectsFem.py index a49fcabeafdc..6ba8a97ea555 100644 --- a/src/Mod/Fem/ObjectsFem.py +++ b/src/Mod/Fem/ObjectsFem.py @@ -372,6 +372,21 @@ def makeMaterialMechanicalNonlinear( return obj +def makeMaterialReinforced( + doc, + name="MaterialReinforced" +): + '''makeMaterialReinforced(document, [matrix_material], [reinforcement_material], [name]): + creates a reinforced material object''' + obj = doc.addObject("App::MaterialObjectPython", name) + from femobjects import _FemMaterialReinforced + _FemMaterialReinforced._FemMaterialReinforced(obj) + if FreeCAD.GuiUp: + from femguiobjects import _ViewProviderFemMaterialReinforced + _ViewProviderFemMaterialReinforced._ViewProviderFemMaterialReinforced(obj.ViewObject) + return obj + + def makeMaterialSolid( doc, name="MechanicalSolidMaterial" diff --git a/src/Mod/Fem/femguiobjects/_ViewProviderFemMaterialReinforced.py b/src/Mod/Fem/femguiobjects/_ViewProviderFemMaterialReinforced.py new file mode 100644 index 000000000000..39556b3b8b42 --- /dev/null +++ b/src/Mod/Fem/femguiobjects/_ViewProviderFemMaterialReinforced.py @@ -0,0 +1,89 @@ +# *************************************************************************** +# * Copyright (c) 2019 Bernd Hahnebach * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +__title__ = "FreeCAD FEM material reinforced ViewProvider for the document object" +__author__ = "Bernd Hahnebach" +__url__ = "http://www.freecadweb.org" + +## @package ViewProviderFemMaterialReinforced +# \ingroup FEM +# \brief FreeCAD FEM _ViewProviderFemMaterialReinforced + +import FreeCAD +import FreeCADGui +import FemGui # needed to display the icons in TreeView +False if False else FemGui.__name__ # flake8, dummy FemGui usage, returns 'FemGui' + + +class _ViewProviderFemMaterialReinforced: + "A View Provider for the FemMaterialReinfocement object" + def __init__(self, vobj): + vobj.Proxy = self + + def getIcon(self): + return ":/icons/fem-constraint-selfweight.svg" # TODO: create one + + def attach(self, vobj): + from pivy import coin + self.ViewObject = vobj + self.Object = vobj.Object + self.standard = coin.SoGroup() + vobj.addDisplayMode(self.standard, "Default") + + def getDisplayModes(self, obj): + return ["Default"] + + def updateData(self, obj, prop): + return + + def onChanged(self, vobj, prop): + return + + def setEdit(self, vobj, mode=0): + # avoid edit mode by return False + # https://forum.freecadweb.org/viewtopic.php?t=12139&start=10#p161062 + return False + + def unsetEdit(self, vobj, mode=0): + FreeCADGui.Control.closeDialog() + return True + + def doubleClicked(self, vobj): + guidoc = FreeCADGui.getDocument(vobj.Object.Document) + # check if another VP is in edit mode + # https://forum.freecadweb.org/viewtopic.php?t=13077#p104702 + if not guidoc.getInEdit(): + guidoc.setEdit(vobj.Object.Name) + else: + from PySide.QtGui import QMessageBox + message = ( + 'Active Task Dialog found! ' + 'Please close this one before opening a new one!' + ) + QMessageBox.critical(None, "Error in tree view", message) + FreeCAD.Console.PrintError(message + '\n') + return True + + def __getstate__(self): + return None + + def __setstate__(self, state): + return None diff --git a/src/Mod/Fem/femobjects/_FemMaterialReinforced.py b/src/Mod/Fem/femobjects/_FemMaterialReinforced.py new file mode 100644 index 000000000000..d8b970e0db41 --- /dev/null +++ b/src/Mod/Fem/femobjects/_FemMaterialReinforced.py @@ -0,0 +1,59 @@ +# *************************************************************************** +# * * +# * Copyright (c) 2019 Bernd Hahnebach * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +__title__ = "FreeCAD FEM reinforced material" +__author__ = "Bernd Hahnebach" +__url__ = "http://www.freecadweb.org" + +## @package FemMaterialReinforced +# \ingroup FEM +# \brief FreeCAD FEM _FemMaterialReinforced + + +class _FemMaterialReinforced: + "The FemMaterialReinforced object" + def __init__(self, obj): + obj.addProperty( + "App::PropertyLinkSubList", + "References", + "Material", + "List of material shapes" + ) + obj.addProperty( + "App::PropertyMap", + "Reinforcement", + "Composites", + "Reinforcement material properties" + ) + obj.addProperty( + "App::PropertyEnumeration", + "Category", + "Material", + "Matrix material properties" + ) + obj.Category = ['Solid'] + obj.Category = 'Solid' + obj.Proxy = self + self.Type = "Fem::MaterialReinforced" + + def execute(self, obj): + return diff --git a/src/Mod/Fem/femtest/testobject.py b/src/Mod/Fem/femtest/testobject.py index a56b076a0777..4adb6e968bbe 100644 --- a/src/Mod/Fem/femtest/testobject.py +++ b/src/Mod/Fem/femtest/testobject.py @@ -82,6 +82,7 @@ def test_femobjects_make( analysis.addObject(ObjectsFem.makeMaterialFluid(doc)) mat = analysis.addObject(ObjectsFem.makeMaterialSolid(doc))[0] analysis.addObject(ObjectsFem.makeMaterialMechanicalNonlinear(doc, mat)) + analysis.addObject(ObjectsFem.makeMaterialReinforced(doc)) msh = analysis.addObject(ObjectsFem.makeMeshGmsh(doc))[0] analysis.addObject(ObjectsFem.makeMeshBoundaryLayer(doc, msh)) @@ -266,6 +267,10 @@ def test_femobjects_type( 'Fem::MaterialMechanicalNonlinear', type_of_obj(ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid)) ) + self.assertEqual( + 'Fem::MaterialReinforced', + type_of_obj(ObjectsFem.makeMaterialReinforced(doc)) + ) mesh = ObjectsFem.makeMeshGmsh(doc) self.assertEqual( 'Fem::FemMeshGmsh', @@ -330,7 +335,7 @@ def test_femobjects_type( 'Fem::FemEquationElmerHeat', type_of_obj(ObjectsFem.makeEquationHeat(doc, solverelmer)) ) - # is = 43 (just copy in empty file to test) + # is = 44 tests (just copy in empty file to test) # TODO: vtk post objs # TODO: use different type for fluid and solid material @@ -450,6 +455,10 @@ def test_femobjects_isoftype( ObjectsFem.makeMaterialMechanicalNonlinear(doc, materialsolid), 'Fem::MaterialMechanicalNonlinear' )) + self.assertTrue(is_of_type( + ObjectsFem.makeMaterialReinforced(doc), + 'Fem::MaterialReinforced' + )) mesh = ObjectsFem.makeMeshGmsh(doc) self.assertTrue(is_of_type( mesh, @@ -516,7 +525,7 @@ def test_femobjects_isoftype( ObjectsFem.makeEquationHeat(doc, solverelmer), 'Fem::FemEquationElmerHeat' )) - # is = 43 (just copy in empty file to test) + # is = 44 tests (just copy in empty file to test) # ******************************************************************************************** def test_femobjects_derivedfromfem( @@ -899,6 +908,20 @@ def test_femobjects_derivedfromfem( 'Fem::MaterialMechanicalNonlinear' )) + # MaterialReinforced + self.assertTrue(is_derived_from( + ObjectsFem.makeMaterialReinforced(doc), + 'App::DocumentObject' + )) + self.assertTrue(is_derived_from( + ObjectsFem.makeMaterialReinforced(doc), + 'App::MaterialObjectPython' + )) + self.assertTrue(is_derived_from( + ObjectsFem.makeMaterialReinforced(doc), + 'Fem::MaterialReinforced' + )) + # FemMeshGmsh self.assertTrue(is_derived_from( mesh, 'App::DocumentObject' @@ -1270,6 +1293,11 @@ def test_femobjects_derivedfromstd( materialsolid ).isDerivedFrom('Fem::FeaturePython') ) + self.assertTrue( + ObjectsFem.makeMaterialReinforced( + doc + ).isDerivedFrom('App::MaterialObjectPython') + ) mesh = ObjectsFem.makeMeshGmsh(doc) self.assertTrue( mesh.isDerivedFrom('Fem::FemMeshObjectPython') @@ -1356,7 +1384,7 @@ def test_femobjects_derivedfromstd( solverelmer ).isDerivedFrom('App::FeaturePython') ) - # is = 43 (just copy in empty file to test) + # is = 44 tests (just copy in empty file to test) # ******************************************************************************************** def tearDown(