diff --git a/src/Mod/Fem/CalculixLib.py b/src/Mod/Fem/CalculixLib.py index 573bbd872..b79cbedda 100644 --- a/src/Mod/Fem/CalculixLib.py +++ b/src/Mod/Fem/CalculixLib.py @@ -140,6 +140,7 @@ def importFrd(filename): disp = m['Displacement'] o = FreeCAD.ActiveDocument.addObject('Fem::FemResultVector','Displacement') o.Values = disp.values() + o.DataType = 'Displacement' o.ElementNumbers = disp.keys() if(MeshObject): o.Mesh = MeshObject @@ -153,12 +154,15 @@ def importFrd(filename): mstress.append( sqrt( pow( i[0] - i[1] ,2) + pow( i[1] - i[2] ,2) + pow( i[2] - i[0] ,2) + 6 * (pow(i[3],2)+pow(i[4],2)+pow(i[5],2) ) ) ) o.Values = mstress + o.DataType = 'VanMisesStress' o.ElementNumbers = stress.keys() if(MeshObject): o.Mesh = MeshObject AnalysisObject.Member = AnalysisObject.Member + [o] if(FreeCAD.GuiUp): - import FemGui + import FemGui, FreeCADGui + if FreeCADGui.activeWorkbench().name() != 'FemWorkbench': + FreeCADGui.activateWorkbench("FemWorkbench") FemGui.setActiveAnalysis(AnalysisObject) def insert(filename,docname): diff --git a/src/Mod/Fem/FemLib.py b/src/Mod/Fem/FemLib.py index 98985ab84..03ad52dcc 100644 --- a/src/Mod/Fem/FemLib.py +++ b/src/Mod/Fem/FemLib.py @@ -20,8 +20,17 @@ #* * #*************************************************************************** -def DebugLoad(): - import MechanicalAnalysis,MechanicalMaterial - reload(MechanicalAnalysis) - reload(MechanicalMaterial) +__title__="Mechanical Analysis managment" +__author__ = "Juergen Riegel" +__url__ = "http://www.freecadweb.org" + + +def colorValue(value,min,max): + 'creates a homogenouse color ramp between [min,max] green to red' + if value < min: return (0.0,1.0,0.0) + if value > max: return (1.0,0.0,0.0) + if value < (min + (max-min)/2.0): + return ((value-min) / ((max-min)/2.0),1.0,0.0) + else: + return (1.0,1-((value-min-((max-min)/2.0)) / ((max-min)/2.0)),0.0) \ No newline at end of file diff --git a/src/Mod/Fem/Gui/Resources/Fem.qrc b/src/Mod/Fem/Gui/Resources/Fem.qrc index ee00e6358..f47660125 100755 --- a/src/Mod/Fem/Gui/Resources/Fem.qrc +++ b/src/Mod/Fem/Gui/Resources/Fem.qrc @@ -18,7 +18,7 @@ icons/Fem_ResultStress.svg translations/Fem_af.qm translations/Fem_de.qm - translations/Fem_fi.qm + translations/Fem_fi.qm translations/Fem_fr.qm translations/Fem_hr.qm translations/Fem_it.qm diff --git a/src/Mod/Fem/Gui/Workbench.cpp b/src/Mod/Fem/Gui/Workbench.cpp index 2acc9a1b6..7afdd9cee 100755 --- a/src/Mod/Fem/Gui/Workbench.cpp +++ b/src/Mod/Fem/Gui/Workbench.cpp @@ -69,8 +69,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const << "Fem_ConstraintGear" << "Fem_ConstraintPulley" << "Separator" - << "Fem_ShowStressResult" - << "Fem_ShowDisplacementResult"; + << "Fem_ShowResult"; return root; } @@ -95,8 +94,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Fem_ConstraintGear" << "Fem_ConstraintPulley" << "Separator" - << "Fem_ShowStressResult" - << "Fem_ShowDisplacementResult" + << "Fem_ShowResult" ; return root; diff --git a/src/Mod/Fem/Init.py b/src/Mod/Fem/Init.py index 6878192ae..e9e284a01 100755 --- a/src/Mod/Fem/Init.py +++ b/src/Mod/Fem/Init.py @@ -46,3 +46,4 @@ ParGrp = App.ParamGet("System parameter:Modules").GetGroup("Fem") FreeCAD.addExportType("TetGen file (*.poly)","convert2TetGen") FreeCAD.addImportType("FEM formats (*.unv *.med *.dat *.bdf)","Fem") FreeCAD.addExportType("FEM formats (*.unv *.med *.dat *.inp)","Fem") +FreeCAD.addImportType("CalculiX result (*.frd)","CalculixLib") diff --git a/src/Mod/Fem/MechanicalAnalysis.py b/src/Mod/Fem/MechanicalAnalysis.py index f4b3a9af7..7272a605c 100644 --- a/src/Mod/Fem/MechanicalAnalysis.py +++ b/src/Mod/Fem/MechanicalAnalysis.py @@ -20,7 +20,8 @@ #* * #*************************************************************************** -import FreeCAD, Fem, os,sys,string,math,shutil,glob,subprocess,tempfile +import FreeCAD, Fem, FemLib +import os,sys,string,math,shutil,glob,subprocess,tempfile if FreeCAD.GuiUp: import FreeCADGui,FemGui @@ -29,7 +30,7 @@ if FreeCAD.GuiUp: from pivy import coin import PyQt4.uic as uic -__title__="Machine-Distortion Analysis managment" +__title__="Mechanical Analysis managment" __author__ = "Juergen Riegel" __url__ = "http://www.freecadweb.org" @@ -100,47 +101,33 @@ class _CommandMechanicalJobControl: return FreeCADGui.ActiveDocument != None and FemGui.getActiveAnalysis() != None -class _CommandMechanicalShowStress: + +class _CommandMechanicalShowResult: "the Fem JobControl command definition" def GetResources(self): - return {'Pixmap' : 'Fem_ResultStress', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_ResultStress","Show stress result"), + return {'Pixmap' : 'Fem_Result', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_ResultDisplacement","Show result"), 'Accel': "A", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_ResultStress","Show stress result")} - - def Activated(self): - import FemGui - - taskd = _JobControlTaskPanel(FemGui.getActiveAnalysis()) - #taskd.obj = vobj.Object - taskd.update() - FreeCADGui.Control.showDialog(taskd) - - - def IsActive(self): - import FemGui - return FreeCADGui.ActiveDocument != None and FemGui.getActiveAnalysis() != None - - -class _CommandMechanicalShowDisplacement: - "the Fem JobControl command definition" - def GetResources(self): - return {'Pixmap' : 'Fem_ResultDisplacement', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Fem_ResultDisplacement","Show displacement result"), - 'Accel': "A", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_ResultDisplacement","Show displacement result")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_ResultDisplacement","Show result imformatation of an analysis")} def Activated(self): import FemGui DisplacementObject = None for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("Fem::FemResultVector"): - DisplacementObject = i - if not DisplacementObject: - QtGui.QMessageBox.critical(None, "Missing prerequisit","No displacement result in active Analysis") + if i.DataType == 'Displacement': + DisplacementObject = i + StressObject = None + for i in FemGui.getActiveAnalysis().Member: + if i.isDerivedFrom("Fem::FemResultValue"): + if i.DataType == 'VanMisesStress': + StressObject = i + + if not DisplacementObject and not StressObject: + QtGui.QMessageBox.critical(None, "Missing prerequisit","No result found in active Analysis") return - taskd = _DisplacementControlTaskPanel(FemGui.getActiveAnalysis()) + taskd = _ResultControlTaskPanel(FemGui.getActiveAnalysis()) #taskd.obj = vobj.Object taskd.update() FreeCADGui.Control.showDialog(taskd) @@ -314,7 +301,7 @@ class _JobControlTaskPanel: #poisson_ratio = float(matmap['FEM_poissonratio']) -class _DisplacementControlTaskPanel: +class _ResultControlTaskPanel: '''The control for the displacement post-processing''' def __init__(self,object): # the panel has a tree widget that contains categories @@ -328,8 +315,18 @@ class _DisplacementControlTaskPanel: self.formUi.setupUi(self.form) #Connect Signals and Slots - #QtCore.QObject.connect(self.formUi.toolButton_chooseOutputDir, QtCore.SIGNAL("clicked()"), self.chooseOutputDir) - #QtCore.QObject.connect(self.formUi.pushButton_generate, QtCore.SIGNAL("clicked()"), self.run) + QtCore.QObject.connect(self.formUi.radioButton_Displacement, QtCore.SIGNAL("clicked(bool)"), self.displacementClicked) + QtCore.QObject.connect(self.formUi.radioButton_Stress, QtCore.SIGNAL("clicked(bool)"), self.stressClicked) + QtCore.QObject.connect(self.formUi.radioButton_NoColor, QtCore.SIGNAL("clicked(bool)"), self.noColorClicked) + QtCore.QObject.connect(self.formUi.checkBox_ShowDisplacement, QtCore.SIGNAL("clicked(bool)"), self.showDisplacementClicked) + + QtCore.QObject.connect(self.formUi.verticalScrollBar_Factor, QtCore.SIGNAL("valueChanged(int)"), self.sliderValue) + + QtCore.QObject.connect(self.formUi.spinBox_SliderFactor, QtCore.SIGNAL("valueChanged(double)"), self.sliderMaxValue) + QtCore.QObject.connect(self.formUi.spinBox_DisplacementFactor, QtCore.SIGNAL("valueChanged(double)"), self.displacementFactorValue) + + self.DisplacementObject = None + self.StressObject = None self.update() @@ -337,11 +334,88 @@ class _DisplacementControlTaskPanel: def getStandardButtons(self): return int(QtGui.QDialogButtonBox.Close) + + def displacementClicked(self,bool): + QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor) + self.setColorDisplacement() + QtGui.qApp.restoreOverrideCursor() + + def stressClicked(self,bool): + print 'stressClicked()' + QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor) + self.setColorStress() + QtGui.qApp.restoreOverrideCursor() + + def noColorClicked(self,bool): + self.MeshObject.ViewObject.NodeColor = {} + self.MeshObject.ViewObject.ElementColor = {} + + def showDisplacementClicked(self,bool): + QtGui.qApp.setOverrideCursor(QtCore.Qt.WaitCursor) + self.setDisplacement() + QtGui.qApp.restoreOverrideCursor() + + def sliderValue(self,value): + if(self.formUi.checkBox_ShowDisplacement.isChecked()): + self.MeshObject.ViewObject.animate(value) + + self.formUi.spinBox_DisplacementFactor.setValue(value) + + def sliderMaxValue(self,value): + print 'sliderMaxValue()' + self.formUi.verticalScrollBar_Factor.setMaximum(value) + + def displacementFactorValue(self,value): + print 'displacementFactorValue()' + self.formUi.verticalScrollBar_Factor.setValue(value) + + def setColorDisplacement(self): + if self.DisplacementObject: + values = self.DisplacementObject.Values + maxL = 0.0 + for i in values: + if i.Length > maxL: + maxL = i.Length + + self.formUi.lineEdit_Max.setText(str(maxL)) + self.formUi.doubleSpinBox_MinValueColor.setValue(maxL) + + colors = [] + for i in values: + colors.append( FemLib.colorValue(i.Length,0.0,maxL) ) + self.MeshObject.ViewObject.NodeColor = dict(zip( self.DisplacementObject.ElementNumbers,colors)) + def setDisplacement(self): + if self.DisplacementObject: + values = self.DisplacementObject.Values + self.MeshObject.ViewObject.NodeDisplacement = dict(zip( self.DisplacementObject.ElementNumbers,values)) + + def setColorStress(self): + if self.StressObject: + values = self.StressObject.Values + maxVal = max(values) + self.formUi.doubleSpinBox_MinValueColor.setValue(maxVal) + colors = [] + for i in values: + colors.append( FemLib.colorValue(i,0.0,maxVal) ) + self.MeshObject.ViewObject.ElementColor = dict(zip(self.StressObject.ElementNumbers,colors)) def update(self): 'fills the widgets' - #self.formUi.lineEdit_outputDir.setText(self.params.GetString("JobDir",'/')) - return + + self.MeshObject = None + if FemGui.getActiveAnalysis(): + for i in FemGui.getActiveAnalysis().Member: + if i.isDerivedFrom("Fem::FemMeshObject"): + self.MeshObject = i + + for i in FemGui.getActiveAnalysis().Member: + if i.isDerivedFrom("Fem::FemResultVector"): + if i.DataType == 'Displacement': + self.DisplacementObject = i + for i in FemGui.getActiveAnalysis().Member: + if i.isDerivedFrom("Fem::FemResultValue"): + if i.DataType == 'VanMisesStress': + self.StressObject = i def accept(self): FreeCADGui.Control.closeDialog() @@ -357,5 +431,4 @@ class _DisplacementControlTaskPanel: FreeCADGui.addCommand('Fem_NewMechanicalAnalysis',_CommandNewMechanicalAnalysis()) FreeCADGui.addCommand('Fem_MechanicalJobControl',_CommandMechanicalJobControl()) -FreeCADGui.addCommand('Fem_ShowStressResult',_CommandMechanicalShowStress()) -FreeCADGui.addCommand('Fem_ShowDisplacementResult',_CommandMechanicalShowDisplacement()) +FreeCADGui.addCommand('Fem_ShowResult',_CommandMechanicalShowResult()) diff --git a/src/Mod/Fem/ShowDisplacement.ui b/src/Mod/Fem/ShowDisplacement.ui index c00138f93..71d40d880 100644 --- a/src/Mod/Fem/ShowDisplacement.ui +++ b/src/Mod/Fem/ShowDisplacement.ui @@ -28,7 +28,7 @@ Stress - true + false @@ -37,6 +37,9 @@ Displacement + + false + @@ -44,6 +47,9 @@ No color + + true + @@ -56,7 +62,11 @@ - + + + true + + @@ -67,6 +77,9 @@ + + true + 99999990.000000000000000 @@ -143,7 +156,7 @@ Show - true + false @@ -158,6 +171,15 @@ + + true + + + 99999 + + + 2 + 1 @@ -176,11 +198,17 @@ + + true + 99999 + + 5 + - 20 + 100 @@ -207,7 +235,7 @@ - 20 + 100 1