Skip to content

Commit

Permalink
FEM: Move _JobControlTaskPanel class to separate file
Browse files Browse the repository at this point in the history
Signed-off-by: Przemo Firszt <przemo@firszt.eu>
  • Loading branch information
PrzemoF authored and wwmayer committed Oct 11, 2015
1 parent e3a7a79 commit 0f71211
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 212 deletions.
1 change: 1 addition & 0 deletions src/Mod/Fem/App/CMakeLists.txt
Expand Up @@ -83,6 +83,7 @@ SET(FemScripts_SRCS
MechanicalMaterial.py
ShowDisplacement.ui
_ResultControlTaskPanel.py
_JobControlTaskPanel.py
)
#SOURCE_GROUP("Scripts" FILES ${FemScripts_SRCS})

Expand Down
1 change: 1 addition & 0 deletions src/Mod/Fem/CMakeLists.txt
Expand Up @@ -25,6 +25,7 @@ INSTALL(
MechanicalAnalysis.ui
ShowDisplacement.ui
_ResultControlTaskPanel.py
_JobControlTaskPanel.py
DESTINATION
Mod/Fem
)
Expand Down
216 changes: 4 additions & 212 deletions src/Mod/Fem/MechanicalAnalysis.py
Expand Up @@ -20,18 +20,13 @@
#* *
#***************************************************************************

import ccxFrdReader
import FreeCAD
from FemTools import FemTools
import os
import time

if FreeCAD.GuiUp:
import FreeCADGui
import FemGui
from PySide import QtCore, QtGui
from PySide.QtCore import Qt
from PySide.QtGui import QApplication

__title__ = "Mechanical Analysis managment"
__author__ = "Juergen Riegel"
Expand Down Expand Up @@ -117,7 +112,8 @@ def GetResources(self):
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_JobControl", "Dialog to start the calculation of the mechanical anlysis")}

def Activated(self):
taskd = _JobControlTaskPanel(FemGui.getActiveAnalysis())
import _JobControlTaskPanel
taskd = _JobControlTaskPanel._JobControlTaskPanel(FemGui.getActiveAnalysis())
#taskd.obj = vobj.Object
taskd.update()
FreeCADGui.Control.showDialog(taskd)
Expand Down Expand Up @@ -277,7 +273,8 @@ def doubleClicked(self, vobj):
FemGui.setActiveAnalysis(self.Object)
return True
else:
taskd = _JobControlTaskPanel(self.Object)
import _JobControlTaskPanel
taskd = _JobControlTaskPanel._JobControlTaskPanel(self.Object)
FreeCADGui.Control.showDialog(taskd)
return True

Expand All @@ -288,211 +285,6 @@ def __setstate__(self, state):
return None


class _JobControlTaskPanel:
def __init__(self, analysis_object):
self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/MechanicalAnalysis.ui")
self.fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem")
ccx_binary = self.fem_prefs.GetString("ccxBinaryPath", "")
if ccx_binary:
self.CalculixBinary = ccx_binary
print "Using ccx binary path from FEM preferences: {}".format(ccx_binary)
else:
from platform import system
if system() == 'Linux':
self.CalculixBinary = 'ccx'
elif system() == 'Windows':
self.CalculixBinary = FreeCAD.getHomePath() + 'bin/ccx.exe'
else:
self.CalculixBinary = 'ccx'
self.fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem")
self.working_dir = self.fem_prefs.GetString("WorkingDir", '/tmp')

self.analysis_object = analysis_object
self.Calculix = QtCore.QProcess()
self.Timer = QtCore.QTimer()
self.Timer.start(300)

self.fem_console_message = ''

#Connect Signals and Slots
QtCore.QObject.connect(self.form.tb_choose_working_dir, QtCore.SIGNAL("clicked()"), self.choose_working_dir)
QtCore.QObject.connect(self.form.pushButton_write, QtCore.SIGNAL("clicked()"), self.write_input_file_handler)
QtCore.QObject.connect(self.form.pushButton_edit, QtCore.SIGNAL("clicked()"), self.editCalculixInputFile)
QtCore.QObject.connect(self.form.pushButton_generate, QtCore.SIGNAL("clicked()"), self.runCalculix)

QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("started()"), self.calculixStarted)
QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("stateChanged(QProcess::ProcessState)"), self.calculixStateChanged)
QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("error(QProcess::ProcessError)"), self.calculixError)
QtCore.QObject.connect(self.Calculix, QtCore.SIGNAL("finished(int)"), self.calculixFinished)

QtCore.QObject.connect(self.Timer, QtCore.SIGNAL("timeout()"), self.UpdateText)

self.update()

def femConsoleMessage(self, message="", color="#000000"):
self.fem_console_message = self.fem_console_message + '<font color="#0000FF">{0:4.1f}:</font> <font color="{1}">{2}</font><br>'.\
format(time.time() - self.Start, color, message.encode('utf-8', 'replace'))
self.form.textEdit_Output.setText(self.fem_console_message)
self.form.textEdit_Output.moveCursor(QtGui.QTextCursor.End)

def printCalculiXstdout(self):
out = self.Calculix.readAllStandardOutput()
if out.isEmpty():
self.femConsoleMessage("CalculiX stdout is empty", "#FF0000")
else:
try:
out = unicode(out, 'utf-8', 'replace')
rx = QtCore.QRegExp("\\*ERROR.*\\n\\n")
rx.setMinimal(True)
pos = rx.indexIn(out)
while not pos < 0:
match = rx.cap(0)
FreeCAD.Console.PrintError(match.strip().replace('\n', ' ') + '\n')
pos = rx.indexIn(out, pos + 1)
out = os.linesep.join([s for s in out.splitlines() if s])
self.femConsoleMessage(out.replace('\n', '<br>'))
except UnicodeDecodeError:
self.femConsoleMessage("Error converting stdout from CalculiX", "#FF0000")

def UpdateText(self):
if(self.Calculix.state() == QtCore.QProcess.ProcessState.Running):
self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start))

def calculixError(self, error):
print "Error()", error
self.femConsoleMessage("CalculiX execute error: {}".format(error), "#FF0000")

def calculixStarted(self):
print "calculixStarted()"
print self.Calculix.state()
self.form.pushButton_generate.setText("Break Calculix")

def calculixStateChanged(self, newState):
if (newState == QtCore.QProcess.ProcessState.Starting):
self.femConsoleMessage("Starting CalculiX...")
if (newState == QtCore.QProcess.ProcessState.Running):
self.femConsoleMessage("CalculiX is running...")
if (newState == QtCore.QProcess.ProcessState.NotRunning):
self.femConsoleMessage("CalculiX stopped.")

def calculixFinished(self, exitCode):
print "calculixFinished()", exitCode
print self.Calculix.state()

# Restore previous cwd
QtCore.QDir.setCurrent(self.cwd)

self.printCalculiXstdout()
self.Timer.stop()

self.femConsoleMessage("Calculix done!", "#00AA00")

self.form.pushButton_generate.setText("Re-run Calculix")
print "Loading results...."
self.femConsoleMessage("Loading result sets...")
self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start))
fea = FemTools()
fea.reset_all()
frd_result_file = os.path.splitext(self.inp_file_name)[0] + '.frd'
if os.path.isfile(frd_result_file):
QApplication.setOverrideCursor(Qt.WaitCursor)
ccxFrdReader.importFrd(frd_result_file, FemGui.getActiveAnalysis())
QApplication.restoreOverrideCursor()
self.femConsoleMessage("Loading results done!", "#00AA00")
else:
self.femConsoleMessage("Loading results failed! Results file doesn\'t exist", "#FF0000")
self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start))

def getStandardButtons(self):
return int(QtGui.QDialogButtonBox.Close)

def update(self):
'fills the widgets'
self.form.le_working_dir.setText(self.working_dir)
return

def accept(self):
FreeCADGui.Control.closeDialog()

def reject(self):
FreeCADGui.Control.closeDialog()

def choose_working_dir(self):
self.fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem")
self.working_dir = QtGui.QFileDialog.getExistingDirectory(None,
'Choose CalculiX working directory',
self.fem_prefs.GetString("WorkingDir", '/tmp'))
if self.working_dir:
self.fem_prefs.SetString("WorkingDir", str(self.working_dir))
self.form.le_working_dir.setText(self.working_dir)

def write_input_file_handler(self):
QApplication.restoreOverrideCursor()
if self.check_prerequisites_helper():
QApplication.setOverrideCursor(Qt.WaitCursor)
self.inp_file_name = ""
fea = FemTools()
fea.update_objects()
fea.write_inp_file()
if fea.inp_file_name != "":
self.inp_file_name = fea.inp_file_name
self.femConsoleMessage("Write completed.")
self.form.pushButton_edit.setEnabled(True)
self.form.pushButton_generate.setEnabled(True)
else:
self.femConsoleMessage("Write .inp file failed!", "#FF0000")
QApplication.restoreOverrideCursor()

def check_prerequisites_helper(self):
self.Start = time.time()
self.femConsoleMessage("Check dependencies...")
self.form.label_Time.setText('Time: {0:4.1f}: '.format(time.time() - self.Start))

fea = FemTools()
fea.update_objects()
message = fea.check_prerequisites()
if message != "":
QtGui.QMessageBox.critical(None, "Missing prerequisit(s)", message)
return False
return True

def start_ext_editor(self, ext_editor_path, filename):
if not hasattr(self, "ext_editor_process"):
self.ext_editor_process = QtCore.QProcess()
if self.ext_editor_process.state() != QtCore.QProcess.Running:
self.ext_editor_process.start(ext_editor_path, [filename])

def editCalculixInputFile(self):
print 'editCalculixInputFile {}'.format(self.inp_file_name)
if self.fem_prefs.GetBool("UseInternalEditor", True):
FemGui.open(self.inp_file_name)
else:
ext_editor_path = self.fem_prefs.GetString("ExternalEditorPath", "")
if ext_editor_path:
self.start_ext_editor(ext_editor_path, self.inp_file_name)
else:
print "External editor is not defined in FEM preferences. Falling back to internal editor"
FemGui.open(self.inp_file_name)

def runCalculix(self):
print 'runCalculix'
self.Start = time.time()

self.femConsoleMessage("CalculiX binary: {}".format(self.CalculixBinary))
self.femConsoleMessage("Run Calculix...")

# run Calculix
print 'run Calculix at: ', self.CalculixBinary, ' with: ', os.path.splitext(self.inp_file_name)[0]
# change cwd because ccx may crash if directory has no write permission
# there is also a limit of the length of file names so jump to the document directory
self.cwd = QtCore.QDir.currentPath()
fi = QtCore.QFileInfo(self.inp_file_name)
QtCore.QDir.setCurrent(fi.path())
self.Calculix.start(self.CalculixBinary, ['-i', fi.baseName()])

QApplication.restoreOverrideCursor()


# Helpers


Expand Down

0 comments on commit 0f71211

Please sign in to comment.