#*************************************************************************** #* * #* Copyright (c) 2013-2015 - Juergen Riegel * #* * #* 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 from FemTools import FemTools if FreeCAD.GuiUp: import FreeCADGui import FemGui from PySide import QtCore, QtGui __title__ = "Mechanical Analysis managment" __author__ = "Juergen Riegel" __url__ = "http://www.freecadweb.org" def makeMechanicalAnalysis(name): '''makeFemAnalysis(name): makes a Fem Analysis object''' obj = FreeCAD.ActiveDocument.addObject("Fem::FemAnalysisPython", name) import _FemAnalysis _FemAnalysis._FemAnalysis(obj) import _ViewProviderFemAnalysis _ViewProviderFemAnalysis._ViewProviderFemAnalysis() #FreeCAD.ActiveDocument.recompute() return obj class _CommandNewMechanicalAnalysis: "the Fem Analysis command definition" def GetResources(self): return {'Pixmap': 'fem-analysis', 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_Analysis", "New mechanical analysis"), 'Accel': "N, A", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_Analysis", "Create a new mechanical analysis")} def Activated(self): FreeCAD.ActiveDocument.openTransaction("Create Analysis") FreeCADGui.addModule("FemGui") FreeCADGui.addModule("MechanicalAnalysis") #FreeCADGui.doCommand("FreeCADGui.ActiveDocument.ActiveView.setAxisCross(True)") FreeCADGui.doCommand("MechanicalAnalysis.makeMechanicalAnalysis('MechanicalAnalysis')") FreeCADGui.doCommand("FemGui.setActiveAnalysis(App.activeDocument().ActiveObject)") sel = FreeCADGui.Selection.getSelection() if (len(sel) == 1): if(sel[0].isDerivedFrom("Fem::FemMeshObject")): FreeCADGui.doCommand("App.activeDocument().ActiveObject.Member = App.activeDocument().ActiveObject.Member + [App.activeDocument()." + sel[0].Name + "]") if(sel[0].isDerivedFrom("Part::Feature")): FreeCADGui.doCommand("App.activeDocument().addObject('Fem::FemMeshShapeNetgenObject', '" + sel[0].Name + "_Mesh')") FreeCADGui.doCommand("App.activeDocument().ActiveObject.Shape = App.activeDocument()." + sel[0].Name) FreeCADGui.doCommand("FemGui.getActiveAnalysis().Member = FemGui.getActiveAnalysis().Member + [App.activeDocument().ActiveObject]") #FreeCADGui.doCommand("Gui.activeDocument().hide('" + sel[0].Name + "')") #FreeCADGui.doCommand("App.activeDocument().ActiveObject.touch()") #FreeCADGui.doCommand("App.activeDocument().recompute()") FreeCADGui.doCommand("Gui.activeDocument().setEdit(App.ActiveDocument.ActiveObject.Name)") #FreeCAD.ActiveDocument.commitTransaction() FreeCADGui.Selection.clearSelection() def IsActive(self): return FreeCADGui.ActiveDocument is not None and FemGui.getActiveAnalysis() is None class _CommandFemFromShape: def GetResources(self): return {'Pixmap': 'fem-fem-mesh-from-shape', 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_CreateFromShape", "Create FEM mesh"), 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_CreateFromShape", "Create FEM mesh from shape")} def Activated(self): FreeCAD.ActiveDocument.openTransaction("Create FEM mesh") FreeCADGui.addModule("FemGui") FreeCADGui.addModule("MechanicalAnalysis") sel = FreeCADGui.Selection.getSelection() if (len(sel) == 1): if(sel[0].isDerivedFrom("Part::Feature")): FreeCADGui.doCommand("App.activeDocument().addObject('Fem::FemMeshShapeNetgenObject', '" + sel[0].Name + "_Mesh')") FreeCADGui.doCommand("App.activeDocument().ActiveObject.Shape = App.activeDocument()." + sel[0].Name) FreeCADGui.doCommand("Gui.activeDocument().setEdit(App.ActiveDocument.ActiveObject.Name)") FreeCADGui.Selection.clearSelection() def IsActive(self): sel = FreeCADGui.Selection.getSelection() if len(sel) == 1: return sel[0].isDerivedFrom("Part::Feature") return False class _CommandMechanicalJobControl: "the Fem JobControl command definition" def GetResources(self): return {'Pixmap': 'fem-new-analysis', 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_JobControl", "Start calculation"), 'Accel': "S, C", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_JobControl", "Dialog to start the calculation of the mechanical anlysis")} def Activated(self): import _JobControlTaskPanel taskd = _JobControlTaskPanel._JobControlTaskPanel(FemGui.getActiveAnalysis()) #taskd.obj = vobj.Object taskd.update() FreeCADGui.Control.showDialog(taskd) def IsActive(self): return FreeCADGui.ActiveDocument is not None and FemGui.getActiveAnalysis() is not None class _CommandPurgeFemResults: def GetResources(self): return {'Pixmap': 'fem-purge-results', 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_PurgeResults", "Purge results"), 'Accel': "S, S", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_PurgeResults", "Purge results from an analysis")} def Activated(self): fea = FemTools() fea.reset_all() def IsActive(self): return FreeCADGui.ActiveDocument is not None and results_present() class _CommandQuickAnalysis: def GetResources(self): return {'Pixmap': 'fem-quick-analysis', 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_Quick_Analysis", "Run CalculiX ccx"), 'Accel': "R, C", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_Quick_Analysis", "Write .inp file and run CalculiX ccx")} def Activated(self): def load_results(ret_code): if ret_code == 0: self.fea.load_results() self.show_results_on_mesh() else: print "CalculiX failed ccx finished with error {}".format(ret_code) self.fea = FemTools() self.fea.reset_all() message = self.fea.check_prerequisites() if message: QtGui.QMessageBox.critical(None, "Missing prerequisite", message) return self.fea.finished.connect(load_results) QtCore.QThreadPool.globalInstance().start(self.fea) def show_results_on_mesh(self): #FIXME proprer mesh refreshing as per FreeCAD.FEM_dialog settings required # or confirmation that it's safe to call restore_result_dialog import _ResultControlTaskPanel tp = _ResultControlTaskPanel._ResultControlTaskPanel() tp.restore_result_dialog() def IsActive(self): return FreeCADGui.ActiveDocument is not None and FemGui.getActiveAnalysis() is not None # Helpers def results_present(): results = False analysis_members = FemGui.getActiveAnalysis().Member for o in analysis_members: if o.isDerivedFrom('Fem::FemResultObject'): results = True return results if FreeCAD.GuiUp: FreeCADGui.addCommand('Fem_NewMechanicalAnalysis', _CommandNewMechanicalAnalysis()) FreeCADGui.addCommand('Fem_CreateFromShape', _CommandFemFromShape()) FreeCADGui.addCommand('Fem_MechanicalJobControl', _CommandMechanicalJobControl()) FreeCADGui.addCommand('Fem_Quick_Analysis', _CommandQuickAnalysis()) FreeCADGui.addCommand('Fem_PurgeResults', _CommandPurgeFemResults())