diff --git a/src/Mod/PartDesign/WizardShaft/SegmentFunction.py b/src/Mod/PartDesign/WizardShaft/SegmentFunction.py
index 629c2acda..a9e7c501e 100644
--- a/src/Mod/PartDesign/WizardShaft/SegmentFunction.py
+++ b/src/Mod/PartDesign/WizardShaft/SegmentFunction.py
@@ -137,12 +137,16 @@ class SegmentFunction:
xvals = set([self.segments[0].start + s * offset for s in range(pointsX)])
starts = set([self.segments[i].start for i in range(len(self.segments))])
xvals = xvals.union(starts) # Make sure we have a point on each segment start
- result = []
+ xresult = []
+ yresult = []
for xval in sorted(xvals):
if xval in starts:
- result.append( (xval, self.lowervalue(xval)) ) # create double point at segment border
- result.append( (xval, self.value(xval)) )
- return result
+ # create double point at segment border
+ xresult.append(xval)
+ yresult.append(self.lowervalue(xval))
+ xresult.append(xval)
+ yresult.append(self.value(xval))
+ return (xresult, yresult)
def output(self):
FreeCAD.Console.PrintMessage(self.name + " = ")
diff --git a/src/Mod/PartDesign/WizardShaft/Shaft.py b/src/Mod/PartDesign/WizardShaft/Shaft.py
index ff5da1afc..8dffa008a 100644
--- a/src/Mod/PartDesign/WizardShaft/Shaft.py
+++ b/src/Mod/PartDesign/WizardShaft/Shaft.py
@@ -20,30 +20,11 @@
# * *
# ******************************************************************************/
-import os, tempfile
import FreeCAD, FreeCADGui # FreeCAD just required for debug printing to the console...
-import WebGui
from SegmentFunction import SegmentFunction
from ShaftFeature import ShaftFeature
from ShaftDiagram import Diagram
-htmlHeader = """
-
-
-
-
-
-
-
-
-
-"""
-htmlFooter = """
-
-
-
-"""
-
class ShaftSegment:
length = 0.0
diameter = 0.0
@@ -64,11 +45,6 @@ class Shaft:
#featureWindow = None
# The diagrams
diagrams = {} # map of function name against Diagram object
- # Directory for diagram files
- tmpdir = ""
- # HTML browser
- haveBrowser = False
- #htmlWindow = None
# Calculation of shaft
Qy = 0 # force in direction of y axis
Qz = 0 # force in direction of z axis
@@ -77,8 +53,6 @@ class Shaft:
Mtz = 0 # torsion moment around z axis
def __init__(self, doc):
- # Create a temporary directory
- self.tmpdir = tempfile.mkdtemp()
self.sketch = ShaftFeature(doc)
def getLengthTo(self, index):
@@ -129,30 +103,16 @@ class Shaft:
self.diagrams[self.Qy.name].update(self.Qy, self.getLengthTo(len(self.segments)) / 1000.0)
else:
# Create diagram
- self.diagrams[self.Qy.name] = Diagram(self.tmpdir)
+ self.diagrams[self.Qy.name] = Diagram()
self.diagrams[self.Qy.name].create("Shear force", self.Qy, self.getLengthTo(len(self.segments)) / 1000.0, "x", "mm", 1000.0, "Q_y", "N", 1.0, 10)
if self.Mbz.name in self.diagrams:
# Update diagram
self.diagrams[self.Mbz.name].update(self.Mbz, self.getLengthTo(len(self.segments)) / 1000.0)
else:
# Create diagram
- self.diagrams[self.Mbz.name] = Diagram(self.tmpdir)
+ self.diagrams[self.Mbz.name] = Diagram()
self.diagrams[self.Mbz.name].create("Bending moment", self.Mbz, self.getLengthTo(len(self.segments)) / 1000.0, "x", "mm", 1000.0, "M_{b,z}", "Nm", 1.0, 10)
- if self.haveBrowser is False:
- # Create HTML file with the diagrams
- htmlFile = os.path.join(self.tmpdir, "diagrams.html")
- file = open(htmlFile, "w")
- file.write(htmlHeader)
- for fname in self.diagrams.iterkeys():
- plotFile = os.path.join(self.tmpdir, (fname + ".png"))
- file.write("
\n" % (plotFile, fname))
- file.write(htmlFooter)
- file.close()
- WebGui.openBrowser(htmlFile)
- self.haveBrowser = True
- # Once the diagram is created, it will take care of refreshing the HTML view
-
def equilibrium(self):
# Build equilibrium equations
forces = {0.0:0.0} # dictionary of (location : outer force)
@@ -247,12 +207,3 @@ class Shaft:
if (i < len(var) - 1) and (i != 0):
FreeCAD.Console.PrintMessage(" + ")
FreeCAD.Console.PrintMessage("\n")
-
- def __del__(self):
- "Remove the temporary directory"
- for fname in self.diagrams.iterkeys():
- os.remove(os.path.join(self.tmpdir, (fname + ".dat")))
- os.remove(os.path.join(self.tmpdir, (fname + ".pyxplot")))
- os.remove(os.path.join(self.tmpdir, (fname + ".png")))
- os.remove(os.path.join(self.tmpdir, "diagrams.html"))
- os.rmdir(self.tmpdir)
diff --git a/src/Mod/PartDesign/WizardShaft/ShaftDiagram.py b/src/Mod/PartDesign/WizardShaft/ShaftDiagram.py
index 715453d8a..74962dded 100644
--- a/src/Mod/PartDesign/WizardShaft/ShaftDiagram.py
+++ b/src/Mod/PartDesign/WizardShaft/ShaftDiagram.py
@@ -20,12 +20,9 @@
# * *
# ******************************************************************************/
-import os, subprocess
from PyQt4 import QtCore, QtGui
import FreeCAD, FreeCADGui
-header = " ### FREECAD SHAFT WIZARD ###\n #\n"
-
class Diagram:
function = 0 # This is assumed to be always a SegmentFunction
fname = "y(x)"
@@ -37,26 +34,14 @@ class Diagram:
yunit = ""
yscale = 1.0
numxpoints = 10
- points = []
- # process object of pyxplot running in the background
- pyxplot = None
- # Filesystem watcher
- graphicsFile = ""
- timer = 0
- watcher = 0
- updatePending = False
-
- def __init__(self, tmpdir):
- self.tmpdir = tmpdir
- # Set up watcher and timer
- self.watcher = QtCore.QFileSystemWatcher()
- self.watcher.fileChanged.connect(self.updateFinished)
- self.timer = QtCore.QTimer()
- self.timer.setInterval(100)
- self.timer.timeout.connect(self.pollFile)
+ xpoints = []
+ ypoints = []
+ # Plot object
+ thePlot = None
def create(self, title, function, xlength, xname, xunit, xscale, yname, yunit, yscale, numxpoints):
# Initialize
+ import Plot
self.title = title
self.function = function
self.xlength = xlength
@@ -67,12 +52,20 @@ class Diagram:
self.yunit = yunit
self.yscale = yscale
self.numxpoints = numxpoints
- self.graphicsFile = os.path.join(self.tmpdir, self.function.name + '.png')
+
+ # Create a plot window
+ win = Plot.figure(title)
+ # Get the plot object from the window
+ self.thePlot = Plot.getPlot()
+ # Format the plot object
+ Plot.xlabel("$%s$ [%s]" % (xname, xunit))
+ Plot.ylabel("$%s$ [%s]" % (yname, yunit))
+ Plot.grid(True)
# Calculate points
- self.points = self.function.evaluate(self.xlength, self.numxpoints)
- # Write files
- self.write()
+ (self.xpoints, self.ypoints) = self.function.evaluate(self.xlength, self.numxpoints)
+ # Create plot
+ self.plot()
def update(self, function = None, xlength = None):
if function is not None:
@@ -80,113 +73,19 @@ class Diagram:
if xlength is not None:
self.xlength = xlength
# Calculate points
- self.points = self.function.evaluate(self.xlength, self.numxpoints)
- # Write files
- self.write()
-
- def write(self):
- "Write diagram files"
- # Check if pyxplot is still running in the background
- if (self.pyxplot is not None) and (self.pyxplot.poll() is None):
- # Process hasn't terminated yet, set flag to update again
- # as soon as the graphicsFile has been written by the current pyxplot process
- self.updatePending = True
- return
-
- # Get max and min values
- (xmin, xmax) = self.minmaxX()
- (ymin, ymax) = self.minmaxY()
-
- # Create data file
- dataFile = os.path.join(self.tmpdir, (self.function.name + ".dat"))
- file = open(dataFile, "w")
- file.write(header)
- file.write(" # File automatically exported by FreeCAD Shaft Wizard\n")
- file.write(" # This file contains xy data, filled with following columns:\n")
- file.write(" # 1: %s [%s]\n" % (self.xname, self.xunit))
- file.write(" # 2: %s [%s]\n" % (self.yname, self.yunit))
- file.write(" #\n")
- for (x, y) in self.points:
- file.write("%f %f\n" % (x * self.xscale, y * self.yscale))
- file.close()
-
- # Create pyxplot file
- commandFile = os.path.join(self.tmpdir, (self.function.name + ".pyxplot"))
- file = open(commandFile, "w")
- file.write(header)
- file.write(" # File automatically exported by FreeCAD Shaft Wizard\n")
- file.write(" # This file contains a script to plot xy data.\n")
- file.write(" # To use it execute:\n")
- file.write(" #\n")
- file.write(" # pyxplot %s\n" % (commandFile))
- file.write(" #\n")
- file.write(" #################################################################\n")
- # Write general options
- file.write("set numeric display latex\n")
- file.write("set terminal png\n")
- file.write("set output '%s'\n" % (self.graphicsFile))
- file.write("set nokey\n")
- file.write("set grid\n")
- file.write("# X axis\n")
- file.write("set xlabel '$%s$ [%s]'\n" % (self.xname, self.xunit))
- file.write("set xrange [%f:%f]\n" % ((xmin * self.xscale * 1.05, xmax * self.xscale * 1.05)))
- file.write("set xtic\n")
- file.write("# Y axis\n")
- file.write("set ylabel '$%s$ [%s]'\n" % (self.yname, self.yunit))
- file.write("set yrange [%f:%f]\n" % ((ymin * self.yscale * 1.05, ymax * self.yscale * 1.05)))
- file.write("set ytic\n")
- file.write("# Line styles\n")
- file.write("set style 1 line linetype 1 linewidth 2 colour rgb (0):(0):(0)\n")
- file.write("# Title\n")
- file.write("set title '%s'" % self.title)
- # Write plot call
- file.write("# Plot\n")
- file.write("plot '%s' using 1:2 axes x1y1 with lines style 1\n" % (dataFile))
- # Close file
- file.close()
-
- # Run pyxplot on the files, but don't wait for execution to finish
- # Instead, set timer to poll for the process to finish
- try:
- self.pyxplot = subprocess.Popen(["pyxplot", commandFile])
- # Poll the process to add a watcher as soon as it has created the graphics file
- if len(self.watcher.files()) == 0:
- self.timer.start()
- except OSError:
- FreeCAD.Console.PrintError("Can't execute pyxplot. Maybe it is not installed?\n")
-
- self.updatePending = False
-
- def pollFile(self):
- # Check if process has finished
- if self.pyxplot.poll() is None:
- return
- # Check if the graphics file has appeared and then set a watcher on it
- if not os.path.isfile(self.graphicsFile):
- return
- # We don't need the timer any more now
- self.timer.stop()
- FreeCADGui.SendMsgToActiveView('Refresh')
- self.watcher.addPath(self.graphicsFile)
-
- def updateFinished(self, filePath):
- # filePath is not important because we are only watching a single file
- # FIXME: Will give a warning in the console if the active window is not the HTML page
- FreeCADGui.SendMsgToActiveView('Refresh')
- if self.updatePending is True:
- self.write()
-
- def minmaxX(self):
- xpoints = []
- for (x, y) in self.points:
- xpoints.append(x)
- return (min(xpoints), max(xpoints))
-
- def minmaxY(self):
- ypoints = []
- for (x, y) in self.points:
- ypoints.append(y)
- return (min(ypoints), max(ypoints))
+ (self.xpoints, self.ypoints) = self.function.evaluate(self.xlength, self.numxpoints)
+ # Create plot
+ self.plot()
+ def plot(self):
+ plots = self.thePlot.series
+ if plots:
+ # Remove line from plot
+ axes = plots[0].axes
+ axes.lines.pop(plots[0].lid)
+ # Remove serie from list
+ del self.thePlot.series[0]
+ self.thePlot.update()
+ self.thePlot.plot(self.xpoints, self.ypoints)