Commit bbd016dc authored by D1plo1d's avatar D1plo1d

Merge branch 'master' of github.com:kliment/Printrun

parents cebc3212 baa22754
Some cleanup commands : Some cleanup commands:
To add a space after each comma : To add a space after each comma:
sed -e "s/\(\w\),\(\w\)/\1, \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\),\(\w\)/\1, \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\w\),\(\"\)/\1, \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\),\(\"\)/\1, \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\"\),\(\w\)/\1, \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\"\),\(\w\)/\1, \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\"\),\(\"\)/\1, \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\"\),\(\"\)/\1, \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\([)}\]]\),\(\w\)/\1, \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\([)}\]]\),\(\w\)/\1, \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\([)}\]]\),\([\[{(]\)/\1, \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\([)}\]]\),\([\[{(]\)/\1, \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\w\),\([\[{(]\)/\1, \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\),\([\[{(]\)/\1, \2/g" -i *.py printrun/*.py printrun/*/*.py
To add spaces around each = : To add spaces around each =:
sed -e "s/\(\w\)=\(\w\)/\1 = \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\)=\(\w\)/\1 = \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\w\)=\(\"\)/\1 = \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\)=\(\"\)/\1 = \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\w\)=\((\)/\1 = \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\)=\((\)/\1 = \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\w\)=\((\)/\1 = \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\)=\((\)/\1 = \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\w\)=\([\[{(]\)/\1 = \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\)=\([\[{(]\)/\1 = \2/g" -i *.py printrun/*.py printrun/*/*.py
To add spaces around each == : To add spaces around each ==:
sed -e "s/\(\w\)==\(\w\)/\1 == \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\)==\(\w\)/\1 == \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\w\)==\(\"\)/\1 == \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\)==\(\"\)/\1 == \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\(\w\)==\((\)/\1 == \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\(\w\)==\((\)/\1 == \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\()\)==\(\w\)/\1 == \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\()\)==\(\w\)/\1 == \2/g" -i *.py printrun/*.py printrun/*/*.py
sed -e "s/\()\)==\((\)/\1 == \2/g" -i *.py printrun/*.py printrun/svg/*.py sed -e "s/\()\)==\((\)/\1 == \2/g" -i *.py printrun/*.py printrun/*/*.py
Obviously this is not a perfect solution, it WILL break the code. Juste check the diff and fix what's wrong before commiting. Obviously this is not a perfect solution, it WILL break the code. Juste check the diff and fix what's wrong before commiting.
Flake8 checking:
Flake8 can be used to check the coding style of the project.
The current source code (as of July 23rd 2013) has been checked using the following command:
flake8 . --statistics --count --ignore=E251,E701,E302,E501 --exclude=.svn,CVS,.bzr,.hg,.git,__pycache__,prontserve.py,./printrun/server,projectlayer.py,./printrun/cairosvg
This call ignores 4 kind of errors (E501: line being greater than 80 chars,
E701: multiple statements on one line (usually this is if ...: ...), E302:
wrong number of blank lines between functions, E251: unexpected spaces around
keywoard/parameter equals), the rest of the errors and warnings should be
killed as much as possible. Long lines should be avoided too.
#!/usr/bin/env python
# This file is part of the Printrun suite.
#
# Printrun is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Printrun 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>.
# Set up Internationalization using gettext
# searching for installed locales on /usr/share; uses relative folder if not found (windows)
from printrun.printrun_utils import install_locale
install_locale('plater')
import wx
import sys
from printrun import gcview
from printrun import gcoder
from printrun.objectplater import Plater
from printrun.gl.libtatlin import actors
class GcodePlater(Plater):
load_wildcard = _("GCODE files (*.gcode;*.GCODE;*.g)")
save_wildcard = _("GCODE files (*.gcode;*.GCODE;*.g)")
def __init__(self, filenames = [], size = (800, 580), callback = None, parent = None, build_dimensions = None):
super(GcodePlater, self).__init__(filenames, size, callback, parent, build_dimensions)
viewer = gcview.GcodeViewPanel(self, build_dimensions = self.build_dimensions)
self.set_viewer(viewer)
self.platform = actors.Platform(self.build_dimensions)
self.platform_object = gcview.GCObject(self.platform)
def get_objects(self):
return [self.platform_object] + self.models.values()
objects = property(get_objects)
def load_file(self, filename):
gcode = gcoder.GCode(open(filename))
model = actors.GcodeModel()
model.load_data(gcode)
obj = gcview.GCObject(model)
obj.gcode = gcode
obj.dims = [gcode.xmin, gcode.xmax,
gcode.ymin, gcode.ymax,
gcode.zmin, gcode.zmax]
obj.centeroffset = [-(obj.dims[1] + obj.dims[0]) / 2,
-(obj.dims[3] + obj.dims[2]) / 2,
0]
self.add_model(filename, obj)
wx.CallAfter(self.Refresh)
# What's hard in there ?
# 1) finding the order in which the objects are printed
# 2) handling layers correctly
# 3) handling E correctly
# 4) handling position shifts: should we either reset absolute 0 using G92
# or should we rewrite all positions ?
# 5) handling the start & end gcode properly ?
# Initial implementation should just print the objects sequentially,
# but the end goal is to have a clean per-layer merge
def export_to(self, name):
with open(name, "w") as f:
models = self.models.values()
last_real_position = None
# Sort models by Z max to print smaller objects first
models.sort(key = lambda x: x.dims[-1])
for model in models:
r = model.rot # no rotation support for now
if r != 0:
print _("Warning: no rotation support for now, "
"object won't be correctly rotated")
o = model.offsets
co = model.centeroffset
offset_pos = last_real_position if last_real_position is not None else [0, 0, 0]
trans = (offset_pos[0] - (o[0] + co[0]),
offset_pos[1] - (o[1] + co[1]),
offset_pos[2] - (o[2] + co[2]))
f.write("G90\n")
f.write("G92 X%.5f Y%.5f Z%.5f E0\n" % trans)
for l in model.gcode:
if l.command != "G28" and (l.command != "92" or not any([l.x, l.y, l.z])):
f.write(l.raw + "\n")
# Find the current real position
for i in xrange(len(model.gcode) - 1, -1, -1):
if model.gcode.lines[i].is_move:
gline = model.gcode.lines[i]
last_real_position = [- trans[0] + gline.current_x,
- trans[1] + gline.current_y,
- trans[2] + gline.current_z]
break
print _("Exported merged G-Codes to %s") % name
if __name__ == '__main__':
app = wx.App(False)
main = GcodePlater(sys.argv[1:])
main.Show()
app.MainLoop()
This diff is collapsed.
This diff is collapsed.
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import re
import gcoder import gcoder
class GCodeAnalyzer(): class GCodeAnalyzer():
...@@ -70,7 +69,7 @@ class GCodeAnalyzer(): ...@@ -70,7 +69,7 @@ class GCodeAnalyzer():
def Analyze(self, gcode): def Analyze(self, gcode):
gline = gcoder.Line(gcode) gline = gcoder.Line(gcode)
split_raw = gcoder.split(gline) split_raw = gcoder.split(gline)
if gline.command.startswith(";@"): return # code is a host command if gline.command.startswith(";@"): return # code is a host command
gcoder.parse_coordinates(gline, split_raw, self.imperial) gcoder.parse_coordinates(gline, split_raw, self.imperial)
code_g = int(gline.command[1:]) if gline.command.startswith("G") else None code_g = int(gline.command[1:]) if gline.command.startswith("G") else None
code_m = int(gline.command[1:]) if gline.command.startswith("M") else None code_m = int(gline.command[1:]) if gline.command.startswith("M") else None
...@@ -81,9 +80,8 @@ class GCodeAnalyzer(): ...@@ -81,9 +80,8 @@ class GCodeAnalyzer():
self.lastY = self.y self.lastY = self.y
self.lastZ = self.z self.lastZ = self.z
self.lastE = self.e self.lastE = self.e
eChanged = False;
code_f = gline.f code_f = gline.f
if code_f != None: if code_f is not None:
self.f = code_f self.f = code_f
code_x = gline.x code_x = gline.x
...@@ -92,27 +90,24 @@ class GCodeAnalyzer(): ...@@ -92,27 +90,24 @@ class GCodeAnalyzer():
code_e = gline.e code_e = gline.e
if self.relative: if self.relative:
if code_x != None: self.x += code_x if code_x is not None: self.x += code_x
if code_y != None: self.y += code_y if code_y is not None: self.y += code_y
if code_z != None: self.z += code_z if code_z is not None: self.z += code_z
if code_e != None: if code_e is not None:
if code_e != 0: if code_e != 0:
eChanged = True
self.e += code_e self.e += code_e
else: else:
# absolute coordinates # absolute coordinates
if code_x != None: self.x = self.xOffset + code_x if code_x is not None: self.x = self.xOffset + code_x
if code_y != None: self.y = self.yOffset + code_y if code_y is not None: self.y = self.yOffset + code_y
if code_z != None: self.z = self.zOffset + code_z if code_z is not None: self.z = self.zOffset + code_z
if code_e != None: if code_e is not None:
if self.eRelative: if self.eRelative:
if code_e != 0: if code_e != 0:
eChanged = True
self.e += code_e self.e += code_e
else: else:
# e is absolute. Is it changed? # e is absolute. Is it changed?
if self.e != self.eOffset + code_e: if self.e != self.eOffset + code_e:
eChanged = True
self.e = self.eOffset + code_e self.e = self.eOffset + code_e
#limit checking #limit checking
""" """
...@@ -137,20 +132,20 @@ class GCodeAnalyzer(): ...@@ -137,20 +132,20 @@ class GCodeAnalyzer():
code_z = gline.z code_z = gline.z
code_e = gline.e code_e = gline.e
homeAll = False homeAll = False
if code_x == None and code_y == None and code_z == None: homeAll = True if code_x is None and code_y is None and code_z is None: homeAll = True
if code_x != None or homeAll: if code_x is not None or homeAll:
self.hasHomeX = True self.hasHomeX = True
self.xOffset = 0 self.xOffset = 0
self.x = self.homeX self.x = self.homeX
if code_y != None or homeAll: if code_y is not None or homeAll:
self.hasHomeY = True self.hasHomeY = True
self.yOffset = 0 self.yOffset = 0
self.y = self.homeY self.y = self.homeY
if code_z != None or homeAll: if code_z is not None or homeAll:
self.hasHomeZ = True self.hasHomeZ = True
self.zOffset = 0 self.zOffset = 0
self.z = self.homeZ self.z = self.homeZ
if code_e != None: if code_e is not None:
self.eOffset = 0 self.eOffset = 0
self.e = 0 self.e = 0
elif code_g == 162: elif code_g == 162:
...@@ -162,16 +157,16 @@ class GCodeAnalyzer(): ...@@ -162,16 +157,16 @@ class GCodeAnalyzer():
code_y = gline.y code_y = gline.y
code_z = gline.z code_z = gline.z
homeAll = False homeAll = False
if code_x == None and code_y == None and code_z == None: homeAll = True if code_x is None and code_y is None and code_z is None: homeAll = True
if code_x != None or homeAll: if code_x is not None or homeAll:
self.hasHomeX = True self.hasHomeX = True
self.xOffset = 0 self.xOffset = 0
self.x = self.maxX self.x = self.maxX
if code_y != None or homeAll: if code_y is not None or homeAll:
self.hasHomeY = True self.hasHomeY = True
self.yOffset = 0 self.yOffset = 0
self.y = self.maxY self.y = self.maxY
if code_z != None or homeAll: if code_z is not None or homeAll:
self.hasHomeZ = True self.hasHomeZ = True
self.zOffset = 0 self.zOffset = 0
self.z = self.maxZ self.z = self.maxZ
...@@ -182,20 +177,20 @@ class GCodeAnalyzer(): ...@@ -182,20 +177,20 @@ class GCodeAnalyzer():
code_y = gline.y code_y = gline.y
code_z = gline.z code_z = gline.z
code_e = gline.e code_e = gline.e
if code_x != None: if code_x is not None:
self.xOffset = self.x - float(code_x) self.xOffset = self.x - float(code_x)
self.x = self.xOffset self.x = self.xOffset
if code_y != None: if code_y is not None:
self.yOffset = self.y - float(code_y) self.yOffset = self.y - float(code_y)
self.y = self.yOffset self.y = self.yOffset
if code_z != None: if code_z is not None:
self.zOffset = self.z - float(code_z) self.zOffset = self.z - float(code_z)
self.z = self.zOffset self.z = self.zOffset
if code_e != None: if code_e is not None:
self.xOffset = self.e - float(code_e) self.xOffset = self.e - float(code_e)
self.e = self.eOffset self.e = self.eOffset
#End code_g != None #End code_g is not None
if code_m != None: if code_m is not None:
if code_m == 82: self.eRelative = False if code_m == 82: self.eRelative = False
elif code_m == 83: self.eRelative = True elif code_m == 83: self.eRelative = True
......
...@@ -38,16 +38,15 @@ class SkeinforgeQuickEditDialog(wx.Dialog): ...@@ -38,16 +38,15 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
NOTE: Skeinforge is tightly integrated with Tkinter and there appears to be a dependency which stops radio-button values from being saved. NOTE: Skeinforge is tightly integrated with Tkinter and there appears to be a dependency which stops radio-button values from being saved.
Perhaps this can be solved, but at the moment this dialog cannot modify radio button values. One will have to use the main Skeinforge application. Perhaps this can be solved, but at the moment this dialog cannot modify radio button values. One will have to use the main Skeinforge application.
""" """
self.moduleSettingsMap = { self.moduleSettingsMap = {'dimension': ['Filament Diameter (mm):', 'Retraction Distance (millimeters):', 'Retraction Distance (millimeters):', 'Extruder Retraction Speed (mm/s):'],
'dimension':['Filament Diameter (mm):','Retraction Distance (millimeters):', 'Retraction Distance (millimeters):','Extruder Retraction Speed (mm/s):'], 'carve': ['Layer Height = Extrusion Thickness (mm):', 'Extrusion Width (mm):'],
'carve':['Layer Height = Extrusion Thickness (mm):', 'Extrusion Width (mm):'], 'chamber': ['Heated PrintBed Temperature (Celcius):', 'Turn print Bed Heater Off at Shut Down', 'Turn Extruder Heater Off at Shut Down'],
'chamber':['Heated PrintBed Temperature (Celcius):', 'Turn print Bed Heater Off at Shut Down', 'Turn Extruder Heater Off at Shut Down'], 'cool': ['Activate Cool.. but use with a fan!', 'Use Cool if layer takes shorter than(seconds):'],
'cool':['Activate Cool.. but use with a fan!', 'Use Cool if layer takes shorter than(seconds):'], 'fill': ['Activate Fill:', 'Infill Solidity (ratio):', 'Fully filled Layers (each top and bottom):', 'Extra Shells on Sparse Layer (layers):', 'Extra Shells on Alternating Solid Layer (layers):'],
'fill':['Activate Fill:', 'Infill Solidity (ratio):', 'Fully filled Layers (each top and bottom):', 'Extra Shells on Sparse Layer (layers):', 'Extra Shells on Alternating Solid Layer (layers):'], 'multiply': ['Number of Columns (integer):', 'Number of Rows (integer):'],
'multiply':['Number of Columns (integer):', 'Number of Rows (integer):'], 'raft': ['First Layer Main Feedrate (mm/s):', 'First Layer Perimeter Feedrate (mm/s):', 'First Layer Flow Rate Infill(scaler):', 'First Layer Flow Rate Perimeter(scaler):'],
'raft':['First Layer Main Feedrate (mm/s):','First Layer Perimeter Feedrate (mm/s):','First Layer Flow Rate Infill(scaler):','First Layer Flow Rate Perimeter(scaler):',], 'speed': ['Main Feed Rate (mm/s):', 'Main Flow Rate (scaler):', 'Perimeter Feed Rate (mm/s):', 'Perimeter Flow Rate (scaler):', 'Travel Feed Rate (mm/s):']
'speed':['Main Feed Rate (mm/s):','Main Flow Rate (scaler):','Perimeter Feed Rate (mm/s):','Perimeter Flow Rate (scaler):','Travel Feed Rate (mm/s):'] }
}
self.scrollbarPanel = wx.ScrolledWindow(self, -1, style = wx.TAB_TRAVERSAL) self.scrollbarPanel = wx.ScrolledWindow(self, -1, style = wx.TAB_TRAVERSAL)
self.settingsSizer = self.getProfileSettings() self.settingsSizer = self.getProfileSettings()
...@@ -140,7 +139,7 @@ class SkeinforgeQuickEditDialog(wx.Dialog): ...@@ -140,7 +139,7 @@ class SkeinforgeQuickEditDialog(wx.Dialog):
isDirty = False isDirty = False
for setting in settings.getReadRepository(repo).preferences: for setting in settings.getReadRepository(repo).preferences:
if setting.name == settingName: if setting.name == settingName:
if setting.value == None or str(x.GetValue()) != str(setting.value): if setting.value is None or str(x.GetValue()) != str(setting.value):
print('Saving ... ' + settingName + ' = ' + str(x.GetValue())) print('Saving ... ' + settingName + ' = ' + str(x.GetValue()))
setting.value = x.GetValue() setting.value = x.GetValue()
isDirty = True isDirty = True
......
...@@ -62,15 +62,15 @@ class BufferedCanvas(wx.Panel): ...@@ -62,15 +62,15 @@ class BufferedCanvas(wx.Panel):
ID=-1, ID=-1,
pos = wx.DefaultPosition, pos = wx.DefaultPosition,
size = wx.DefaultSize, size = wx.DefaultSize,
style = wx.NO_FULL_REPAINT_ON_RESIZE|wx.WANTS_CHARS): style = wx.NO_FULL_REPAINT_ON_RESIZE | wx.WANTS_CHARS):
wx.Panel.__init__(self, parent, ID, pos, size, style) wx.Panel.__init__(self, parent, ID, pos, size, style)
# Bind events # Bind events
self.Bind(wx.EVT_PAINT, self.onPaint) self.Bind(wx.EVT_PAINT, self.onPaint)
# Disable background erasing (flicker-licious) # Disable background erasing (flicker-licious)
def disable_event(*pargs,**kwargs): def disable_event(*pargs, **kwargs):
pass # the sauce, please pass # the sauce, please
self.Bind(wx.EVT_ERASE_BACKGROUND, disable_event) self.Bind(wx.EVT_ERASE_BACKGROUND, disable_event)
## ##
......
...@@ -17,27 +17,30 @@ ...@@ -17,27 +17,30 @@
#Interactive RepRap e axis calibration program #Interactive RepRap e axis calibration program
#(C) Nathan Zadoks 2011 #(C) Nathan Zadoks 2011
s = 300 #Extrusion speed (mm/min) s = 300 # Extrusion speed (mm/min)
n = 100 #Default length to extrude n = 100 # Default length to extrude
m= 0 #User-entered measured extrusion length m = 0 # User-entered measured extrusion length
k = 300 #Default amount of steps per mm k = 300 # Default amount of steps per mm
port='/dev/ttyUSB0' #Default serial port to connect to printer port = '/dev/ttyUSB0' # Default serial port to connect to printer
temp = 210 #Default extrusion temperature temp = 210 # Default extrusion temperature
tempmax = 250 #Maximum extrusion temperature tempmax = 250 # Maximum extrusion temperature
t = int(n*60)/s #Time to wait for extrusion t = int(n * 60) / s # Time to wait for extrusion
try: try:
from printdummy import printcore from printdummy import printcore
except ImportError: except ImportError:
from printcore import printcore from printcore import printcore
import time, getopt, sys, os
import time
import getopt
import sys
import os
def float_input(prompt=''): def float_input(prompt=''):
import sys
f = None f = None
while f == None: while f is None:
s = raw_input(prompt) s = raw_input(prompt)
try: try:
f = float(s) f = float(s)
...@@ -46,14 +49,13 @@ def float_input(prompt=''): ...@@ -46,14 +49,13 @@ def float_input(prompt=''):
sys.stderr.flush() sys.stderr.flush()
return f return f
def wait(t, m=''): def wait(t, m=''):
import time, sys sys.stdout.write(m + '[' + (' ' * t) + ']\r' + m + '[')
sys.stdout.write(m+'['+(' '*t)+']\r'+m+'[')
sys.stdout.flush() sys.stdout.flush()
for i in range(t): for i in range(t):
for s in ['|\b','/\b','-\b','\\\b','|']: for s in ['|\b', '/\b', '-\b', '\\\b', '|']:
sys.stdout.write(s) sys.stdout.write(s)
sys.stdout.flush() sys.stdout.flush()
time.sleep(1.0/5) time.sleep(1.0 / 5)
print print
def w(s): def w(s):
sys.stdout.write(s) sys.stdout.write(s)
...@@ -62,31 +64,31 @@ def w(s): ...@@ -62,31 +64,31 @@ def w(s):
def heatup(p, temp, s = 0): def heatup(p, temp, s = 0):
curtemp = gettemp(p) curtemp = gettemp(p)
p.send_now('M109 S%03d'%temp) p.send_now('M109 S%03d' % temp)
p.temp = 0 p.temp = 0
if not s: w("Heating extruder up..") if not s: w("Heating extruder up..")
f = False f = False
while curtemp<=(temp-1): while curtemp <= (temp - 1):
p.send_now('M105') p.send_now('M105')
time.sleep(0.5) time.sleep(0.5)
if not f: if not f:
time.sleep(1.5) time.sleep(1.5)
f = True f = True
curtemp = gettemp(p) curtemp = gettemp(p)
if curtemp: w(u"\rHeating extruder up.. %3d \xb0C"%curtemp) if curtemp: w(u"\rHeating extruder up.. %3d \xb0C" % curtemp)
if s: print if s: print
else: print "\nReady." else: print "\nReady."
def gettemp(p): def gettemp(p):
try: p.logl try: p.logl
except: setattr(p,'logl',0) except: setattr(p, 'logl', 0)
try: p.temp try: p.temp
except: setattr(p,'temp',0) except: setattr(p, 'temp', 0)
for n in range(p.logl, len(p.log)): for n in range(p.logl, len(p.log)):
line = p.log[n] line = p.log[n]
if 'T:' in line: if 'T:' in line:
try: try:
setattr(p,'temp',int(line.split('T:')[1].split()[0])) setattr(p, 'temp', int(line.split('T:')[1].split()[0]))
except: print line except: print line
p.logl = len(p.log) p.logl = len(p.log)
return p.temp return p.temp
...@@ -101,35 +103,35 @@ help = u""" ...@@ -101,35 +103,35 @@ help = u"""
-t --temp Extrusion temperature in degrees Celsius (default: %d \xb0C, max %d \xb0C) -t --temp Extrusion temperature in degrees Celsius (default: %d \xb0C, max %d \xb0C)
-p --port Serial port the printer is connected to (default: %s) -p --port Serial port the printer is connected to (default: %s)
-h --help This cruft. -h --help This cruft.
"""[1:-1].encode('utf-8')%(sys.argv[0], n, k, temp, tempmax, port if port else 'auto') """[1:-1].encode('utf-8') % (sys.argv[0], n, k, temp, tempmax, port if port else 'auto')
try: try:
opts, args = getopt.getopt(sys.argv[1:],"hl:s:t:p:",["help", "length=", "steps=", "temp=", "port="]) opts, args = getopt.getopt(sys.argv[1:], "hl:s:t:p:", ["help", "length=", "steps=", "temp=", "port="])
except getopt.GetoptError, err: except getopt.GetoptError, err:
print str(err) print str(err)
print help print help
sys.exit(2) sys.exit(2)
for o, a in opts: for o, a in opts:
if o in ('-h','--help'): if o in ('-h', '--help'):
print help print help
sys.exit() sys.exit()
elif o in ('-l','--length'): elif o in ('-l', '--length'):
n = float(a) n = float(a)
elif o in ('-s','--steps'): elif o in ('-s', '--steps'):
k = int(a) k = int(a)
elif o in ('-t','--temp'): elif o in ('-t', '--temp'):
temp = int(a) temp = int(a)
if temp>=tempmax: if temp >= tempmax:
print (u'%d \xb0C? Are you insane?'.encode('utf-8')%temp)+(" That's over nine thousand!" if temp>9000 else '') print (u'%d \xb0C? Are you insane?'.encode('utf-8') % temp) + (" That's over nine thousand!" if temp > 9000 else '')
sys.exit(255) sys.exit(255)
elif o in ('-p','--port'): elif o in ('-p', '--port'):
port = a port = a
#Show initial parameters #Show initial parameters
print "Initial parameters" print "Initial parameters"
print "Steps per mm: %3d steps"%k print "Steps per mm: %3d steps" % k
print "Length extruded: %3d mm"%n print "Length extruded: %3d mm" % n
print print
print "Serial port: %s"%(port if port else 'auto') print "Serial port: %s" % (port if port else 'auto')
p = None p = None
try: try:
...@@ -148,18 +150,18 @@ try: ...@@ -148,18 +150,18 @@ try:
heatup(p, temp) heatup(p, temp)
#Calibration loop #Calibration loop
while n!=m: while n != m:
heatup(p, temp, True) heatup(p, temp, True)
p.send_now("G92 E0") #Reset e axis p.send_now("G92 E0") # Reset e axis
p.send_now("G1 E%d F%d"%(n, s)) #Extrude length of filament p.send_now("G1 E%d F%d" % (n, s)) # Extrude length of filament
wait(t,'Extruding.. ') wait(t, 'Extruding.. ')
m = float_input("How many millimeters of filament were extruded? ") m = float_input("How many millimeters of filament were extruded? ")
if m == 0: continue if m == 0: continue
if n!=m: if n != m:
k = (n/m)*k k = (n / m) * k
p.send_now("M92 E%d"%int(round(k))) #Set new step count p.send_now("M92 E%d" % int(round(k))) # Set new step count
print "Steps per mm: %3d steps"%k #Tell user print "Steps per mm: %3d steps" % k # Tell user
print 'Calibration completed.' #Yay! print 'Calibration completed.' # Yay!
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
finally: finally:
......
...@@ -24,7 +24,10 @@ class ExcluderWindow(gviz.GvizWindow): ...@@ -24,7 +24,10 @@ class ExcluderWindow(gviz.GvizWindow):
def __init__(self, excluder, *args, **kwargs): def __init__(self, excluder, *args, **kwargs):
super(ExcluderWindow, self).__init__(*args, **kwargs) super(ExcluderWindow, self).__init__(*args, **kwargs)
self.SetTitle(_("Part excluder: draw rectangles where print instructions should be ignored")) self.SetTitle(_("Part excluder: draw rectangles where print instructions should be ignored"))
self.toolbar.AddLabelTool(128, " " + _("Reset selection"), wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(), shortHelp = _("Reset selection"), longHelp = "") self.toolbar.AddLabelTool(128, " " + _("Reset selection"),
wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
shortHelp = _("Reset selection"),
longHelp = "")
self.Bind(wx.EVT_TOOL, self.reset_selection, id = 128) self.Bind(wx.EVT_TOOL, self.reset_selection, id = 128)
self.parent = excluder self.parent = excluder
self.p.paint_overlay = self.paint_selection self.p.paint_overlay = self.paint_selection
...@@ -39,7 +42,8 @@ class ExcluderWindow(gviz.GvizWindow): ...@@ -39,7 +42,8 @@ class ExcluderWindow(gviz.GvizWindow):
self.p.build_dimensions[1] - (y - self.p.build_dimensions[4])) self.p.build_dimensions[1] - (y - self.p.build_dimensions[4]))
def mouse(self, event): def mouse(self, event):
if event.ButtonUp(wx.MOUSE_BTN_LEFT) or event.ButtonUp(wx.MOUSE_BTN_RIGHT): if event.ButtonUp(wx.MOUSE_BTN_LEFT) \
or event.ButtonUp(wx.MOUSE_BTN_RIGHT):
self.initpos = None self.initpos = None
elif event.Dragging() and event.RightIsDown(): elif event.Dragging() and event.RightIsDown():
e = event.GetPositionTuple() e = event.GetPositionTuple()
...@@ -74,11 +78,11 @@ class ExcluderWindow(gviz.GvizWindow): ...@@ -74,11 +78,11 @@ class ExcluderWindow(gviz.GvizWindow):
def _line_scaler(self, orig): def _line_scaler(self, orig):
x0, y0 = self.gcode_to_real(orig[0], orig[1]) x0, y0 = self.gcode_to_real(orig[0], orig[1])
x0 = self.p.scale[0]*x0 + self.p.translate[0] x0 = self.p.scale[0] * x0 + self.p.translate[0]
y0 = self.p.scale[1]*y0 + self.p.translate[1] y0 = self.p.scale[1] * y0 + self.p.translate[1]
x1, y1 = self.gcode_to_real(orig[2], orig[3]) x1, y1 = self.gcode_to_real(orig[2], orig[3])
x1 = self.p.scale[0]*x1 + self.p.translate[0] x1 = self.p.scale[0] * x1 + self.p.translate[0]
y1 = self.p.scale[1]*y1 + self.p.translate[1] y1 = self.p.scale[1] * y1 + self.p.translate[1]
width = max(x0, x1) - min(x0, x1) + 1 width = max(x0, x1) - min(x0, x1) + 1
height = max(y0, y1) - min(y0, y1) + 1 height = max(y0, y1) - min(y0, y1) + 1
return (min(x0, x1), min(y0, y1), width, height,) return (min(x0, x1), min(y0, y1), width, height,)
...@@ -86,7 +90,8 @@ class ExcluderWindow(gviz.GvizWindow): ...@@ -86,7 +90,8 @@ class ExcluderWindow(gviz.GvizWindow):
def paint_selection(self, dc): def paint_selection(self, dc):
dc = wx.GCDC(dc) dc = wx.GCDC(dc)
dc.SetPen(wx.TRANSPARENT_PEN) dc.SetPen(wx.TRANSPARENT_PEN)
dc.DrawRectangleList([self._line_scaler(rect) for rect in self.parent.rectangles], dc.DrawRectangleList([self._line_scaler(rect)
for rect in self.parent.rectangles],
None, wx.Brush((200, 200, 200, 150))) None, wx.Brush((200, 200, 200, 150)))
def reset_selection(self, event): def reset_selection(self, event):
...@@ -117,6 +122,7 @@ class Excluder(object): ...@@ -117,6 +122,7 @@ class Excluder(object):
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
import gcoder
gcode = gcoder.GCode(open(sys.argv[1])) gcode = gcoder.GCode(open(sys.argv[1]))
app = wx.App(False) app = wx.App(False)
ex = Excluder() ex = Excluder()
......
This diff is collapsed.
This diff is collapsed.
...@@ -21,8 +21,13 @@ import numpy ...@@ -21,8 +21,13 @@ import numpy
import math import math
import logging import logging
from pyglet.gl import * from pyglet.gl import glPushMatrix, glPopMatrix, glTranslatef, \
from pyglet import gl glGenLists, glNewList, GL_COMPILE, glEndList, glCallList, \
GL_ARRAY_BUFFER, GL_STATIC_DRAW, glColor4f, glVertex3f, glRectf, \
glBegin, glEnd, GL_LINES, glEnable, glDisable, glGetFloatv, \
GL_LINE_SMOOTH, glLineWidth, GL_LINE_WIDTH, GLfloat, GL_FLOAT, \
glVertexPointer, glColorPointer, glDrawArrays, \
glEnableClientState, glDisableClientState, GL_VERTEX_ARRAY, GL_COLOR_ARRAY
from pyglet.graphics.vertexbuffer import create_buffer, VertexBufferObject from pyglet.graphics.vertexbuffer import create_buffer, VertexBufferObject
from printrun.printrun_utils import install_locale from printrun.printrun_utils import install_locale
...@@ -80,13 +85,13 @@ class Platform(object): ...@@ -80,13 +85,13 @@ class Platform(object):
self.yoffset = build_dimensions[4] self.yoffset = build_dimensions[4]
self.zoffset = build_dimensions[5] self.zoffset = build_dimensions[5]
self.color_grads_minor = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.1) self.color_grads_minor = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.1)
self.color_grads_interm = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.2) self.color_grads_interm = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.2)
self.color_grads_major = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.33) self.color_grads_major = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.33)
self.color_fill = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.05) self.color_fill = (0xaf / 255, 0xdf / 255, 0x5f / 255, 0.05)
self.initialized = False self.initialized = False
self.loaded = True self.loaded = True
def init(self): def init(self):
self.display_list = compile_display_list(self.draw) self.display_list = compile_display_list(self.draw)
...@@ -111,12 +116,12 @@ class Platform(object): ...@@ -111,12 +116,12 @@ class Platform(object):
glBegin(GL_LINES) glBegin(GL_LINES)
for i in range(0, int(math.ceil(self.width + 1))): for i in range(0, int(math.ceil(self.width + 1))):
if color(i): if color(i):
glVertex3f(float(i), 0.0, 0.0) glVertex3f(float(i), 0.0, 0.0)
glVertex3f(float(i), self.depth, 0.0) glVertex3f(float(i), self.depth, 0.0)
for i in range(0, int(math.ceil(self.depth + 1))): for i in range(0, int(math.ceil(self.depth + 1))):
if color(i): if color(i):
glVertex3f(0, float(i), 0.0) glVertex3f(0, float(i), 0.0)
glVertex3f(self.width, float(i), 0.0) glVertex3f(self.width, float(i), 0.0)
glEnd() glEnd()
...@@ -136,7 +141,7 @@ class PrintHead(object): ...@@ -136,7 +141,7 @@ class PrintHead(object):
self.height = 5 self.height = 5
self.initialized = False self.initialized = False
self.loaded = True self.loaded = True
def init(self): def init(self):
self.display_list = compile_display_list(self.draw) self.display_list = compile_display_list(self.draw)
...@@ -232,7 +237,7 @@ class Model(object): ...@@ -232,7 +237,7 @@ class Model(object):
def movement_angle(src, dst, precision=0): def movement_angle(src, dst, precision=0):
x = dst[0] - src[0] x = dst[0] - src[0]
y = dst[1] - src[1] y = dst[1] - src[1]
angle = math.degrees(math.atan2(y, -x)) # negate x for clockwise rotation angle angle = math.degrees(math.atan2(y, -x)) # negate x for clockwise rotation angle
return round(angle, precision) return round(angle, precision)
class GcodeModel(Model): class GcodeModel(Model):
...@@ -253,15 +258,14 @@ class GcodeModel(Model): ...@@ -253,15 +258,14 @@ class GcodeModel(Model):
def load_data(self, model_data, callback=None): def load_data(self, model_data, callback=None):
t_start = time.time() t_start = time.time()
self.dims = ((model_data.xmin,model_data.xmax,model_data.width), self.dims = ((model_data.xmin, model_data.xmax, model_data.width),
(model_data.ymin,model_data.ymax,model_data.depth), (model_data.ymin, model_data.ymax, model_data.depth),
(model_data.zmin,model_data.zmax,model_data.height)) (model_data.zmin, model_data.zmax, model_data.height))
vertex_list = [] vertex_list = []
color_list = [] color_list = []
self.layer_stops = [0] self.layer_stops = [0]
arrow_list = [] num_layers = len(model_data.all_layers)
num_layers = len(model_data.all_layers)
prev_pos = (0, 0, 0) prev_pos = (0, 0, 0)
for layer_idx, layer in enumerate(model_data.all_layers): for layer_idx, layer in enumerate(model_data.all_layers):
...@@ -284,14 +288,14 @@ class GcodeModel(Model): ...@@ -284,14 +288,14 @@ class GcodeModel(Model):
callback(layer_idx + 1, num_layers) callback(layer_idx + 1, num_layers)
self.vertices = numpy.array(vertex_list, dtype = GLfloat) self.vertices = numpy.array(vertex_list, dtype = GLfloat)
self.colors = numpy.array(color_list, dtype = GLfloat).repeat(2, 0) self.colors = numpy.array(color_list, dtype = GLfloat).repeat(2, 0)
self.max_layers = len(self.layer_stops) - 1 self.max_layers = len(self.layer_stops) - 1
self.num_layers_to_draw = self.max_layers self.num_layers_to_draw = self.max_layers
self.printed_until = -1 self.printed_until = -1
self.only_current = False self.only_current = False
self.initialized = False self.initialized = False
self.loaded = True self.loaded = True
t_end = time.time() t_end = time.time()
...@@ -323,8 +327,8 @@ class GcodeModel(Model): ...@@ -323,8 +327,8 @@ class GcodeModel(Model):
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
def init(self): def init(self):
self.vertex_buffer = numpy2vbo(self.vertices, use_vbos = self.use_vbos) self.vertex_buffer = numpy2vbo(self.vertices, use_vbos = self.use_vbos)
self.vertex_color_buffer = numpy2vbo(self.colors, use_vbos = self.use_vbos) # each pair of vertices shares the color self.vertex_color_buffer = numpy2vbo(self.colors, use_vbos = self.use_vbos) # each pair of vertices shares the color
self.initialized = True self.initialized = True
def display(self, mode_2d=False): def display(self, mode_2d=False):
...@@ -359,7 +363,7 @@ class GcodeModel(Model): ...@@ -359,7 +363,7 @@ class GcodeModel(Model):
else: else:
end_prev_layer = -1 end_prev_layer = -1
end = self.layer_stops[min(self.num_layers_to_draw, self.max_layers)] end = self.layer_stops[min(self.num_layers_to_draw, self.max_layers)]
glDisableClientState(GL_COLOR_ARRAY) glDisableClientState(GL_COLOR_ARRAY)
glColor4f(*self.color_printed) glColor4f(*self.color_printed)
...@@ -384,14 +388,14 @@ class GcodeModel(Model): ...@@ -384,14 +388,14 @@ class GcodeModel(Model):
# Draw current layer # Draw current layer
if end_prev_layer >= 0: if end_prev_layer >= 0:
glDisableClientState(GL_COLOR_ARRAY) glDisableClientState(GL_COLOR_ARRAY)
# Backup & increase line width # Backup & increase line width
orig_linewidth = (GLfloat)() orig_linewidth = (GLfloat)()
glGetFloatv(GL_LINE_WIDTH, orig_linewidth) glGetFloatv(GL_LINE_WIDTH, orig_linewidth)
glLineWidth(2.0) glLineWidth(2.0)
glColor4f(*self.color_current_printed) glColor4f(*self.color_current_printed)
if cur_end > end_prev_layer: if cur_end > end_prev_layer:
glDrawArrays(GL_LINES, end_prev_layer, cur_end - end_prev_layer) glDrawArrays(GL_LINES, end_prev_layer, cur_end - end_prev_layer)
...@@ -413,4 +417,3 @@ class GcodeModel(Model): ...@@ -413,4 +417,3 @@ class GcodeModel(Model):
self.vertex_buffer.unbind() self.vertex_buffer.unbind()
self.vertex_color_buffer.unbind() self.vertex_color_buffer.unbind()
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>. # along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import os
import math
import wx import wx
from wx import glcanvas from wx import glcanvas
...@@ -26,6 +23,7 @@ pyglet.options['debug_gl'] = True ...@@ -26,6 +23,7 @@ pyglet.options['debug_gl'] = True
from pyglet.gl import * from pyglet.gl import *
from pyglet import gl from pyglet import gl
from .trackball import trackball, mulquat
class wxGLPanel(wx.Panel): class wxGLPanel(wx.Panel):
'''A simple class for using OpenGL with wxPython.''' '''A simple class for using OpenGL with wxPython.'''
...@@ -64,7 +62,7 @@ class wxGLPanel(wx.Panel): ...@@ -64,7 +62,7 @@ class wxGLPanel(wx.Panel):
def processSizeEvent(self, event): def processSizeEvent(self, event):
'''Process the resize event.''' '''Process the resize event.'''
if (wx.VERSION > (2,9) and self.canvas.IsShownOnScreen()) or self.canvas.GetContext(): if (wx.VERSION > (2, 9) and self.canvas.IsShownOnScreen()) or self.canvas.GetContext():
# Make sure the frame is shown before calling SetCurrent. # Make sure the frame is shown before calling SetCurrent.
self.canvas.SetCurrent(self.context) self.canvas.SetCurrent(self.context)
self.OnReshape() self.OnReshape()
...@@ -74,7 +72,7 @@ class wxGLPanel(wx.Panel): ...@@ -74,7 +72,7 @@ class wxGLPanel(wx.Panel):
def processPaintEvent(self, event): def processPaintEvent(self, event):
'''Process the drawing event.''' '''Process the drawing event.'''
self.canvas.SetCurrent(self.context) self.canvas.SetCurrent(self.context)
self.OnInitGL() self.OnInitGL()
self.OnDraw() self.OnDraw()
event.Skip() event.Skip()
...@@ -110,7 +108,7 @@ class wxGLPanel(wx.Panel): ...@@ -110,7 +108,7 @@ class wxGLPanel(wx.Panel):
self.OnReshape() self.OnReshape()
def OnReshape(self): def OnReshape(self):
'''Reshape the OpenGL viewport based on the dimensions of the window.''' """Reshape the OpenGL viewport based on the size of the window"""
size = self.GetClientSize() size = self.GetClientSize()
oldwidth, oldheight = self.width, self.height oldwidth, oldheight = self.width, self.height
width, height = size.width, size.height width, height = size.width, size.height
...@@ -174,7 +172,8 @@ class wxGLPanel(wx.Panel): ...@@ -174,7 +172,8 @@ class wxGLPanel(wx.Panel):
def mouse_to_3d(self, x, y, z = 1.0): def mouse_to_3d(self, x, y, z = 1.0):
x = float(x) x = float(x)
y = self.height - float(y) y = self.height - float(y)
# The following could work if we were not initially scaling to zoom on the bed # The following could work if we were not initially scaling to zoom on
# the bed
#if self.orthographic: #if self.orthographic:
# return (x - self.width / 2, y - self.height / 2, 0) # return (x - self.width / 2, y - self.height / 2, 0)
pmat = (GLdouble * 16)() pmat = (GLdouble * 16)()
...@@ -183,7 +182,7 @@ class wxGLPanel(wx.Panel): ...@@ -183,7 +182,7 @@ class wxGLPanel(wx.Panel):
px = (GLdouble)() px = (GLdouble)()
py = (GLdouble)() py = (GLdouble)()
pz = (GLdouble)() pz = (GLdouble)()
glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_VIEWPORT, viewport)
glGetDoublev(GL_PROJECTION_MATRIX, pmat) glGetDoublev(GL_PROJECTION_MATRIX, pmat)
glGetDoublev(GL_MODELVIEW_MATRIX, mvmat) glGetDoublev(GL_MODELVIEW_MATRIX, mvmat)
gluUnProject(x, y, z, mvmat, pmat, viewport, px, py, pz) gluUnProject(x, y, z, mvmat, pmat, viewport, px, py, pz)
...@@ -204,3 +203,32 @@ class wxGLPanel(wx.Panel): ...@@ -204,3 +203,32 @@ class wxGLPanel(wx.Panel):
self.canvas.SetCurrent(self.context) self.canvas.SetCurrent(self.context)
x, y, _ = self.mouse_to_3d(self.width / 2, self.height / 2) x, y, _ = self.mouse_to_3d(self.width / 2, self.height / 2)
self.zoom(factor, (x, y)) self.zoom(factor, (x, y))
def handle_rotation(self, event):
if self.initpos is None:
self.initpos = event.GetPositionTuple()
else:
p1 = self.initpos
p2 = event.GetPositionTuple()
sz = self.GetClientSize()
p1x = float(p1[0]) / (sz[0] / 2) - 1
p1y = 1 - float(p1[1]) / (sz[1] / 2)
p2x = float(p2[0]) / (sz[0] / 2) - 1
p2y = 1 - float(p2[1]) / (sz[1] / 2)
quat = trackball(p1x, p1y, p2x, p2y, self.dist / 250.0)
self.basequat = mulquat(self.basequat, quat)
self.initpos = p2
def handle_translation(self, event):
if self.initpos is None:
self.initpos = event.GetPositionTuple()
else:
p1 = self.initpos
p2 = event.GetPositionTuple()
if self.orthographic:
x1, y1, _ = self.mouse_to_3d(p1[0], p1[1])
x2, y2, _ = self.mouse_to_3d(p2[0], p2[1])
glTranslatef(x2 - x1, y2 - y1, 0)
else:
glTranslatef(p2[0] - p1[0], -(p2[1] - p1[1]), 0)
self.initpos = p2
...@@ -17,10 +17,12 @@ ...@@ -17,10 +17,12 @@
import math import math
from pyglet.gl import * from pyglet.gl import GLdouble
def cross(v1, v2): def cross(v1, v2):
return [v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0]] return [v1[1] * v2[2] - v1[2] * v2[1],
v1[2] * v2[0] - v1[0] * v2[2],
v1[0] * v2[1] - v1[1] * v2[0]]
def trackball(p1x, p1y, p2x, p2y, r): def trackball(p1x, p1y, p2x, p2y, r):
TRACKBALLSIZE = r TRACKBALLSIZE = r
...@@ -85,6 +87,6 @@ def project_to_sphere(r, x, y): ...@@ -85,6 +87,6 @@ def project_to_sphere(r, x, y):
def mulquat(q1, rq): def mulquat(q1, rq):
return [q1[3] * rq[0] + q1[0] * rq[3] + q1[1] * rq[2] - q1[2] * rq[1], return [q1[3] * rq[0] + q1[0] * rq[3] + q1[1] * rq[2] - q1[2] * rq[1],
q1[3] * rq[1] + q1[1] * rq[3] + q1[2] * rq[0] - q1[0] * rq[2], q1[3] * rq[1] + q1[1] * rq[3] + q1[2] * rq[0] - q1[0] * rq[2],
q1[3] * rq[2] + q1[2] * rq[3] + q1[0] * rq[1] - q1[1] * rq[0], q1[3] * rq[2] + q1[2] * rq[3] + q1[0] * rq[1] - q1[1] * rq[0],
q1[3] * rq[3] - q1[0] * rq[0] - q1[1] * rq[1] - q1[2] * rq[2]] q1[3] * rq[3] - q1[0] * rq[0] - q1[1] * rq[1] - q1[2] * rq[2]]
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
## Imported from python-rectangle-packer commit 32fce1aaba
## https://github.com/maxretter/python-rectangle-packer
##
## Python Rectangle Packer - Packs rectangles around a central point
## Copyright (C) 2013 Max Retter
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## 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 General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
import math
import Polygon
import Polygon.Utils
class Vector2(object):
"""Simple 2d vector / point class."""
def __init__(self, x=0, y=0):
self.x = float(x)
self.y = float(y)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def add(self, other):
return Vector2(self.x + other.x, self.y + other.y)
def sub(self, other):
return Vector2(self.x - other.x, self.y - other.y)
def scale(self, factor):
return Vector2(self.x * factor, self.y * factor)
def magnitude(self):
return math.sqrt(self.dot_product(self))
def unit(self):
"""Build unit vector."""
return self.scale(1 / self.magnitude())
def dot_product(self, other):
return self.x * other.x + self.y * other.y
def distance(self, other):
"""Distance forumla for other point."""
return math.sqrt(
(other.x - self.x) ** 2 +
(other.y - self.y) ** 2
)
class Rect(object):
"""Simple rectangle object."""
def __init__(self, width, height, data={}):
self.width = width
self.height = height
self.data = data
## upper left
self.position = Vector2()
def half(self):
"""Half width and height."""
return Vector2(
self.width / 2,
self.height / 2
)
def expand(self, width, height):
"""Builds a new rectangle based on this one with given offsets."""
expanded = Rect(self.width + width, self.height + height)
expanded.set_center(self.center())
return expanded
def point_list(self):
top = self.position.y
right = self.position.x + self.width
bottom = self.position.y + self.height
left = self.position.x
return PointList([
(left, top),
(right, top),
(right, bottom),
(left, bottom),
])
def center(self):
"""Center of rect calculated from position and dimensions."""
return self.position.add(self.half())
def set_center(self, center):
"""Set the position based on a new center point."""
self.position = center.sub(self.half())
def area(self):
"""Area: length * width."""
return self.width * self.height
class PointList(object):
"""Methods for transforming a list of points."""
def __init__(self, points=[]):
self.points = points
self._polygon = None
def polygon(self):
"""Builds a polygon from the set of points."""
if not self._polygon:
self._polygon = Polygon.Polygon(self.points)
return self._polygon
def segments(self):
"""Returns a list of LineSegment objects."""
segs = []
for i, point in enumerate(self.points[1:]):
index = i + 1
segs.append(LineSegment(
Vector2(self.points[index-1][0], self.points[index-1][1]),
Vector2(self.points[index][0], self.points[index][1])
))
segs.append(LineSegment(
Vector2(self.points[-1][0], self.points[-1][1]),
Vector2(self.points[0][0], self.points[0][1]),
))
return segs
class LineSegment(object):
def __init__(self, start, end):
self.start = start
self.end = end
def length(self):
"""Length of segment vector."""
return self.end.sub(self.start).magnitude()
def closest_point_to_point(self, point):
"""Point along segment that is closest to given point."""
segment_vector = self.end.sub(self.start)
point_vector = point.sub(self.start)
seg_mag = segment_vector.magnitude()
## project point_vector on segment_vector
projection = segment_vector.dot_product(point_vector)
## scalar value used to interpolate new point along segment_vector
scalar = projection / seg_mag ** 2
## clamp on [0,1]
scalar = 1.0 if scalar > 1.0 else scalar
scalar = 0.0 if scalar < 0.0 else scalar
## interpolate scalar along segment and add start point back in
return self.start.add(segment_vector.unit().scale(scalar * seg_mag))
def closest_distance_to_point(self, point):
"""Helper method too automatically return distance."""
closest_point = self.closest_point_to_point(point)
return closest_point.distance(point)
class Packer(object):
def __init__(self):
self._rects = []
def add_rect(self, width, height, data={}):
self._rects.append(Rect(width, height, data))
def pack(self, padding=0, center=Vector2()):
## init everything
placed_rects = []
sorted_rects = sorted(self._rects, key=lambda rect: -rect.area())
## double padding due to halfing later on
padding *= 2
for rect in sorted_rects:
if not placed_rects:
## first rect, right on target.
rect.set_center(center)
else:
## Expand each rectangle based on new rect size and padding
## get a list of points
## build a polygon
point_lists = [
pr.expand(rect.width + padding, rect.height + padding).point_list().polygon()
for pr in placed_rects
]
## take the union of all the polygons (relies on + operator override)
## the [0] at the end returns the first "contour", which is the only one we need
bounding_points = PointList(sum(
point_lists[1:],
point_lists[0]
)[0])
## find the closest segment
closest_segments = sorted(
bounding_points.segments(),
key=lambda segment: segment.closest_distance_to_point(center)
)
## get the closest point
place_point = closest_segments[0].closest_point_to_point(center)
## set the rect position
rect.set_center(place_point)
placed_rects.append(rect)
return placed_rects
...@@ -13,25 +13,36 @@ ...@@ -13,25 +13,36 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>. # along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import os, sys import os
import sys
import gettext import gettext
# Set up Internationalization using gettext # Set up Internationalization using gettext
# searching for installed locales on /usr/share; uses relative folder if not found (windows) # searching for installed locales on /usr/share; uses relative folder if not
# found (windows)
def install_locale(domain): def install_locale(domain):
if os.path.exists('/usr/share/pronterface/locale'): if os.path.exists('/usr/share/pronterface/locale'):
gettext.install(domain, '/usr/share/pronterface/locale', unicode = 1) gettext.install(domain, '/usr/share/pronterface/locale', unicode = 1)
elif os.path.exists('/usr/local/share/pronterface/locale'): elif os.path.exists('/usr/local/share/pronterface/locale'):
gettext.install(domain, '/usr/local/share/pronterface/locale', unicode = 1) gettext.install(domain, '/usr/local/share/pronterface/locale',
unicode = 1)
else: else:
gettext.install(domain, './locale', unicode = 1) gettext.install(domain, './locale', unicode = 1)
def iconfile(filename):
if hasattr(sys, "frozen") and sys.frozen == "windows_exe":
return sys.executable
else:
return pixmapfile("plater.ico")
def imagefile(filename): def imagefile(filename):
for prefix in ['/usr/local/share/pronterface/images', '/usr/share/pronterface/images']: for prefix in ['/usr/local/share/pronterface/images',
'/usr/share/pronterface/images']:
candidate = os.path.join(prefix, filename) candidate = os.path.join(prefix, filename)
if os.path.exists(candidate): if os.path.exists(candidate):
return candidate return candidate
local_candidate = os.path.join(os.path.dirname(sys.argv[0]), "images", filename) local_candidate = os.path.join(os.path.dirname(sys.argv[0]),
"images", filename)
if os.path.exists(local_candidate): if os.path.exists(local_candidate):
return local_candidate return local_candidate
else: else:
...@@ -49,13 +60,15 @@ def lookup_file(filename, prefixes): ...@@ -49,13 +60,15 @@ def lookup_file(filename, prefixes):
return filename return filename
def pixmapfile(filename): def pixmapfile(filename):
return lookup_file(filename, ['/usr/local/share/pixmaps', '/usr/share/pixmaps']) return lookup_file(filename, ['/usr/local/share/pixmaps',
'/usr/share/pixmaps'])
def sharedfile(filename): def sharedfile(filename):
return lookup_file(filename, ['/usr/local/share/pronterface', '/usr/share/pronterface']) return lookup_file(filename, ['/usr/local/share/pronterface',
'/usr/share/pronterface'])
def configfile(filename): def configfile(filename):
return lookup_file(filename, [os.path.expanduser("~/.printrun/"),]) return lookup_file(filename, [os.path.expanduser("~/.printrun/"), ])
class RemainingTimeEstimator(object): class RemainingTimeEstimator(object):
...@@ -88,7 +101,7 @@ class RemainingTimeEstimator(object): ...@@ -88,7 +101,7 @@ class RemainingTimeEstimator(object):
if idx == self.last_idx: if idx == self.last_idx:
return self.last_estimate return self.last_estimate
layer, line = self.gcode.idxs(idx) layer, line = self.gcode.idxs(idx)
layer_progress = (1 - (float(line+1) / self.current_layer_lines)) layer_progress = (1 - (float(line + 1) / self.current_layer_lines))
remaining = layer_progress * self.current_layer_estimate + self.remaining_layers_estimate remaining = layer_progress * self.current_layer_estimate + self.remaining_layers_estimate
estimate = self.drift * remaining estimate = self.drift * remaining
total = estimate + printtime total = estimate + printtime
......
This diff is collapsed.
...@@ -13,19 +13,21 @@ ...@@ -13,19 +13,21 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>. # along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import sys, struct, math import sys
import struct
import math
def cross(v1, v2): def cross(v1, v2):
return [v1[1]*v2[2]-v1[2]*v2[1], v1[2]*v2[0]-v1[0]*v2[2], v1[0]*v2[1]-v1[1]*v2[0]] return [v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0]]
def genfacet(v): def genfacet(v):
veca = [v[1][0]-v[0][0], v[1][1]-v[0][1], v[1][2]-v[0][2]] veca = [v[1][0] - v[0][0], v[1][1] - v[0][1], v[1][2] - v[0][2]]
vecb = [v[2][0]-v[1][0], v[2][1]-v[1][1], v[2][2]-v[1][2]] vecb = [v[2][0] - v[1][0], v[2][1] - v[1][1], v[2][2] - v[1][2]]
vecx = cross(veca, vecb) vecx = cross(veca, vecb)
vlen = math.sqrt(sum(map(lambda x:x*x, vecx))) vlen = math.sqrt(sum(map(lambda x: x * x, vecx)))
if vlen == 0: if vlen == 0:
vlen = 1 vlen = 1
normal = map(lambda x:x/vlen, vecx) normal = map(lambda x: x / vlen, vecx)
return [normal, v] return [normal, v]
I = [ I = [
...@@ -40,14 +42,14 @@ def transpose(matrix): ...@@ -40,14 +42,14 @@ def transpose(matrix):
#return [[v[i] for v in matrix] for i in xrange(len(matrix[0]))] #return [[v[i] for v in matrix] for i in xrange(len(matrix[0]))]
def multmatrix(vector, matrix): def multmatrix(vector, matrix):
return map(sum, transpose(map(lambda x:[x[0]*p for p in x[1]], zip(vector, transpose(matrix))))) return map(sum, transpose(map(lambda x: [x[0] * p for p in x[1]], zip(vector, transpose(matrix)))))
def applymatrix(facet, matrix = I): def applymatrix(facet, matrix = I):
#return facet #return facet
#return [map(lambda x:-1.0*x, multmatrix(facet[0]+[1], matrix)[:3]), map(lambda x:multmatrix(x+[1], matrix)[:3], facet[1])] #return [map(lambda x:-1.0*x, multmatrix(facet[0]+[1], matrix)[:3]), map(lambda x:multmatrix(x+[1], matrix)[:3], facet[1])]
return genfacet(map(lambda x:multmatrix(x+[1], matrix)[:3], facet[1])) return genfacet(map(lambda x: multmatrix(x + [1], matrix)[:3], facet[1]))
f = [[0, 0, 0],[[-3.022642, 0.642482, -9.510565],[-3.022642, 0.642482, -9.510565],[-3.022642, 0.642482, -9.510565]]] f = [[0, 0, 0], [[-3.022642, 0.642482, -9.510565], [-3.022642, 0.642482, -9.510565], [-3.022642, 0.642482, -9.510565]]]
m = [ m = [
[1, 0, 0, 0], [1, 0, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
...@@ -60,37 +62,35 @@ def emitstl(filename, facets = [], objname = "stltool_export", binary = 1): ...@@ -60,37 +62,35 @@ def emitstl(filename, facets = [], objname = "stltool_export", binary = 1):
return return
if binary: if binary:
f = open(filename, "wb") f = open(filename, "wb")
buf = "".join(["\0"]*80) buf = "".join(["\0"] * 80)
buf+=struct.pack("<I", len(facets)) buf += struct.pack("<I", len(facets))
facetformat = struct.Struct("<ffffffffffffH") facetformat = struct.Struct("<ffffffffffffH")
for i in facets: for i in facets:
l = list(i[0][:]) l = list(i[0][:])
for j in i[1]: for j in i[1]:
l+=j[:] l += j[:]
l+=[0] l += [0]
#print len(l) #print len(l)
buf+=facetformat.pack(*l) buf += facetformat.pack(*l)
f.write(buf) f.write(buf)
f.close() f.close()
return return
f = open(filename, "w") f = open(filename, "w")
f.write("solid "+objname+"\n") f.write("solid " + objname + "\n")
for i in facets: for i in facets:
f.write(" facet normal "+" ".join(map(str, i[0]))+"\n outer loop\n") f.write(" facet normal " + " ".join(map(str, i[0])) + "\n outer loop\n")
for j in i[1]: for j in i[1]:
f.write(" vertex "+" ".join(map(str, j))+"\n") f.write(" vertex " + " ".join(map(str, j)) + "\n")
f.write(" endloop"+"\n") f.write(" endloop" + "\n")
f.write(" endfacet"+"\n") f.write(" endfacet" + "\n")
f.write("endsolid "+objname+"\n") f.write("endsolid " + objname + "\n")
f.close() f.close()
class stl(object): class stl(object):
def __init__(self, filename = None): def __init__(self, filename = None):
self.facet = [[0, 0, 0],[[0, 0, 0],[0, 0, 0],[0, 0, 0]]] self.facet = [[0, 0, 0], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
self.facets = [] self.facets = []
self.facetsminz = [] self.facetsminz = []
self.facetsmaxz = [] self.facetsmaxz = []
...@@ -129,57 +129,51 @@ class stl(object): ...@@ -129,57 +129,51 @@ class stl(object):
buf += newdata buf += newdata
fd = list(facetformat.unpack(buf)) fd = list(facetformat.unpack(buf))
self.name = "binary soloid" self.name = "binary soloid"
facet = [fd[:3],[fd[3:6], fd[6:9], fd[9:12]]] facet = [fd[:3], [fd[3:6], fd[6:9], fd[9:12]]]
self.facets.append(facet) self.facets.append(facet)
self.facetsminz.append((min(map(lambda x:x[2], facet[1])), facet)) self.facetsminz.append((min(map(lambda x: x[2], facet[1])), facet))
self.facetsmaxz.append((max(map(lambda x:x[2], facet[1])), facet)) self.facetsmaxz.append((max(map(lambda x: x[2], facet[1])), facet))
f.close() f.close()
return return
def translate(self, v = [0, 0, 0]): def translate(self, v = [0, 0, 0]):
matrix = [ matrix = [[1, 0, 0, v[0]],
[1, 0, 0, v[0]], [0, 1, 0, v[1]],
[0, 1, 0, v[1]], [0, 0, 1, v[2]],
[0, 0, 1, v[2]], [0, 0, 0, 1]
[0, 0, 0, 1] ]
]
return self.transform(matrix) return self.transform(matrix)
def rotate(self, v = [0, 0, 0]): def rotate(self, v = [0, 0, 0]):
import math import math
z = v[2] z = v[2]
matrix1 = [ matrix1 = [[math.cos(math.radians(z)), -math.sin(math.radians(z)), 0, 0],
[math.cos(math.radians(z)),-math.sin(math.radians(z)), 0, 0], [math.sin(math.radians(z)), math.cos(math.radians(z)), 0, 0],
[math.sin(math.radians(z)), math.cos(math.radians(z)), 0, 0], [0, 0, 1, 0],
[0, 0, 1, 0], [0, 0, 0, 1]
[0, 0, 0, 1] ]
]
y = v[0] y = v[0]
matrix2 = [ matrix2 = [[1, 0, 0, 0],
[1, 0, 0, 0], [0, math.cos(math.radians(y)), -math.sin(math.radians(y)), 0],
[0, math.cos(math.radians(y)),-math.sin(math.radians(y)), 0], [0, math.sin(math.radians(y)), math.cos(math.radians(y)), 0],
[0, math.sin(math.radians(y)), math.cos(math.radians(y)), 0], [0, 0, 0, 1]
[0, 0, 0, 1] ]
]
x = v[1] x = v[1]
matrix3 = [ matrix3 = [[math.cos(math.radians(x)), 0, -math.sin(math.radians(x)), 0],
[math.cos(math.radians(x)), 0,-math.sin(math.radians(x)), 0], [0, 1, 0, 0],
[0, 1, 0, 0], [math.sin(math.radians(x)), 0, math.cos(math.radians(x)), 0],
[math.sin(math.radians(x)), 0, math.cos(math.radians(x)), 0], [0, 0, 0, 1]
[0, 0, 0, 1] ]
]
return self.transform(matrix1).transform(matrix2).transform(matrix3) return self.transform(matrix1).transform(matrix2).transform(matrix3)
def scale(self, v = [0, 0, 0]): def scale(self, v = [0, 0, 0]):
matrix = [ matrix = [[v[0], 0, 0, 0],
[v[0], 0, 0, 0], [0, v[1], 0, 0],
[0, v[1], 0, 0], [0, 0, v[2], 0],
[0, 0, v[2], 0], [0, 0, 0, 1]
[0, 0, 0, 1] ]
]
return self.transform(matrix) return self.transform(matrix)
def transform(self, m = I): def transform(self, m = I):
s = stl() s = stl()
s.facets = [applymatrix(i, m) for i in self.facets] s.facets = [applymatrix(i, m) for i in self.facets]
...@@ -189,20 +183,20 @@ class stl(object): ...@@ -189,20 +183,20 @@ class stl(object):
s.facetloc = 0 s.facetloc = 0
s.name = self.name s.name = self.name
for facet in s.facets: for facet in s.facets:
s.facetsminz+=[(min(map(lambda x:x[2], facet[1])), facet)] s.facetsminz += [(min(map(lambda x:x[2], facet[1])), facet)]
s.facetsmaxz+=[(max(map(lambda x:x[2], facet[1])), facet)] s.facetsmaxz += [(max(map(lambda x:x[2], facet[1])), facet)]
return s return s
def export(self, f = sys.stdout): def export(self, f = sys.stdout):
f.write("solid "+self.name+"\n") f.write("solid " + self.name + "\n")
for i in self.facets: for i in self.facets:
f.write(" facet normal "+" ".join(map(str, i[0]))+"\n") f.write(" facet normal " + " ".join(map(str, i[0])) + "\n")
f.write(" outer loop"+"\n") f.write(" outer loop" + "\n")
for j in i[1]: for j in i[1]:
f.write(" vertex "+" ".join(map(str, j))+"\n") f.write(" vertex " + " ".join(map(str, j)) + "\n")
f.write(" endloop"+"\n") f.write(" endloop" + "\n")
f.write(" endfacet"+"\n") f.write(" endfacet" + "\n")
f.write("endsolid "+self.name+"\n") f.write("endsolid " + self.name + "\n")
f.flush() f.flush()
def parseline(self, l): def parseline(self, l):
...@@ -216,33 +210,34 @@ class stl(object): ...@@ -216,33 +210,34 @@ class stl(object):
self.insolid = 0 self.insolid = 0
return 0 return 0
elif l.startswith("facet normal"): elif l.startswith("facet normal"):
l = l.replace(", ",".") l = l.replace(", ", ".")
self.infacet = 11 self.infacet = 11
self.facetloc = 0 self.facetloc = 0
self.facet = [[0, 0, 0],[[0, 0, 0],[0, 0, 0],[0, 0, 0]]] self.facet = [[0, 0, 0], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
self.facet[0]=map(float, l.split()[2:]) self.facet[0] = map(float, l.split()[2:])
elif l.startswith("endfacet"): elif l.startswith("endfacet"):
self.infacet = 0 self.infacet = 0
self.facets+=[self.facet] self.facets += [self.facet]
facet = self.facet facet = self.facet
self.facetsminz+=[(min(map(lambda x:x[2], facet[1])), facet)] self.facetsminz += [(min(map(lambda x:x[2], facet[1])), facet)]
self.facetsmaxz+=[(max(map(lambda x:x[2], facet[1])), facet)] self.facetsmaxz += [(max(map(lambda x:x[2], facet[1])), facet)]
elif l.startswith("vertex"): elif l.startswith("vertex"):
l = l.replace(", ",".") l = l.replace(", ", ".")
self.facet[1][self.facetloc]=map(float, l.split()[1:]) self.facet[1][self.facetloc] = map(float, l.split()[1:])
self.facetloc+=1 self.facetloc += 1
return 1 return 1
if __name__ == "__main__": if __name__ == "__main__":
s = stl("../../Downloads/frame-vertex-neo-foot-x4.stl") s = stl("../../Downloads/frame-vertex-neo-foot-x4.stl")
for i in xrange(11, 11): for i in xrange(11, 11):
working = s.facets[:] working = s.facets[:]
for j in reversed(sorted(s.facetsminz)): for j in reversed(sorted(s.facetsminz)):
if(j[0]>i): if(j[0] > i):
working.remove(j[1]) working.remove(j[1])
else: else:
break break
for j in (sorted(s.facetsmaxz)): for j in (sorted(s.facetsmaxz)):
if(j[0]<i): if(j[0] < i):
working.remove(j[1]) working.remove(j[1])
else: else:
break break
......
...@@ -15,13 +15,8 @@ ...@@ -15,13 +15,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Printrun. If not, see <http://www.gnu.org/licenses/>. # along with Printrun. If not, see <http://www.gnu.org/licenses/>.
import os
import math
import stltool
import wx import wx
from wx import glcanvas
import time import time
import threading
import pyglet import pyglet
pyglet.options['debug_gl'] = True pyglet.options['debug_gl'] = True
...@@ -130,9 +125,11 @@ class StlViewPanel(wxGLPanel): ...@@ -130,9 +125,11 @@ class StlViewPanel(wxGLPanel):
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, vec(0, 0.1, 0, 0.9)) glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, vec(0, 0.1, 0, 0.9))
if call_reshape: if call_reshape:
self.OnReshape() self.OnReshape()
if self.parent.filenames: if hasattr(self.parent, "filenames") and self.parent.filenames:
for filename in self.parent.filenames: for filename in self.parent.filenames:
self.parent.load_file(None, filename) self.parent.load_file(filename)
self.parent.autoplate()
self.parent.filenames = None
def double(self, event): def double(self, event):
p = event.GetPositionTuple() p = event.GetPositionTuple()
...@@ -140,34 +137,14 @@ class StlViewPanel(wxGLPanel): ...@@ -140,34 +137,14 @@ class StlViewPanel(wxGLPanel):
v = map(lambda m, w, b: b * m / w, p, sz, self.build_dimensions[0:2]) v = map(lambda m, w, b: b * m / w, p, sz, self.build_dimensions[0:2])
v[1] = self.build_dimensions[1] - v[1] v[1] = self.build_dimensions[1] - v[1]
v += [300] v += [300]
print "Double-click at "+str(v)+" in " print "Double-click at " + str(v) + " in "
print self print self
def forceresize(self): def forceresize(self):
self.SetClientSize((self.GetClientSize()[0], self.GetClientSize()[1] + 1)) self.SetClientSize((self.GetClientSize()[0], self.GetClientSize()[1] + 1))
self.SetClientSize((self.GetClientSize()[0], self.GetClientSize()[1] - 1)) self.SetClientSize((self.GetClientSize()[0], self.GetClientSize()[1] - 1))
threading.Thread(target = self.update).start()
self.initialized = 0 self.initialized = 0
def move_shape(self, delta):
"""moves shape (selected in l, which is list ListBox of shapes)
by an offset specified in tuple delta.
Positive numbers move to (rigt, down)"""
name = self.parent.l.GetSelection()
if name == wx.NOT_FOUND:
return False
name = self.parent.l.GetString(name)
model = self.parent.models[name]
model.offsets = [
model.offsets[0] + delta[0],
model.offsets[1] + delta[1],
model.offsets[2]
]
self.Refresh()
return True
def move(self, event): def move(self, event):
"""react to mouse actions: """react to mouse actions:
no mouse: show red mousedrop no mouse: show red mousedrop
...@@ -178,80 +155,38 @@ class StlViewPanel(wxGLPanel): ...@@ -178,80 +155,38 @@ class StlViewPanel(wxGLPanel):
""" """
self.mousepos = event.GetPositionTuple() self.mousepos = event.GetPositionTuple()
if event.Dragging() and event.LeftIsDown(): if event.Dragging() and event.LeftIsDown():
if self.initpos == None: self.handle_rotation(event)
self.initpos = event.GetPositionTuple() elif event.Dragging() and event.RightIsDown():
else: self.handle_translation(event)
if not event.ShiftDown():
p1 = self.initpos
p2 = event.GetPositionTuple()
x1, y1, _ = self.mouse_to_3d(p1[0], p1[1])
x2, y2, _ = self.mouse_to_3d(p2[0], p2[1])
self.move_shape((x2 - x1, y2 - y1))
self.initpos = p2
return
p1 = self.initpos
p2 = event.GetPositionTuple()
sz = self.GetClientSize()
p1x = (float(p1[0]) - sz[0] / 2) / (sz[0] / 2)
p1y = -(float(p1[1]) - sz[1] / 2) / (sz[1] / 2)
p2x = (float(p2[0]) - sz[0] / 2) / (sz[0] / 2)
p2y = -(float(p2[1]) - sz[1] / 2) / (sz[1] / 2)
quat = trackball(p1x, p1y, p2x, p2y, 0.8)
self.basequat = mulquat(self.basequat, quat)
self.initpos = p2
elif event.ButtonUp(wx.MOUSE_BTN_LEFT): elif event.ButtonUp(wx.MOUSE_BTN_LEFT):
if self.initpos is not None: if self.initpos is not None:
self.initpos = None self.initpos = None
elif event.ButtonUp(wx.MOUSE_BTN_RIGHT): elif event.ButtonUp(wx.MOUSE_BTN_RIGHT):
if self.initpos is not None: if self.initpos is not None:
self.initpos = None self.initpos = None
else:
event.Skip()
return
event.Skip()
wx.CallAfter(self.Refresh)
elif event.Dragging() and event.RightIsDown(): def handle_wheel(self, event):
if self.initpos is None: delta = event.GetWheelRotation()
self.initpos = event.GetPositionTuple() factor = 1.05
else: x, y = event.GetPositionTuple()
p1 = self.initpos x, y, _ = self.mouse_to_3d(x, y)
p2 = event.GetPositionTuple() if delta > 0:
if self.orthographic: self.zoom(factor, (x, y))
x1, y1, _ = self.mouse_to_3d(p1[0], p1[1]) else:
x2, y2, _ = self.mouse_to_3d(p2[0], p2[1]) self.zoom(1 / factor, (x, y))
glTranslatef(x2 - x1, y2 - y1, 0)
else:
glTranslatef(p2[0] - p1[0], -(p2[1] - p1[1]), 0)
self.initpos = p2
def rotate_shape(self, angle):
"""rotates acive shape
positive angle is clockwise
"""
name = self.parent.l.GetSelection()
if name == wx.NOT_FOUND:
return False
name = self.parent.l.GetString(name)
model = self.parent.models[name]
model.rot += angle
def wheel(self, event): def wheel(self, event):
"""react to mouse wheel actions: """react to mouse wheel actions:
rotate object rotate object
with shift zoom viewport with shift zoom viewport
""" """
delta = event.GetWheelRotation() self.handle_wheel(event)
if not event.ShiftDown(): wx.CallAfter(self.Refresh)
angle = 10
if delta > 0:
self.rotate_shape(angle / 2)
else:
self.rotate_shape(-angle / 2)
else:
factor = 1.05
x, y = event.GetPositionTuple()
x, y, _ = self.mouse_to_3d(x, y)
if delta > 0:
self.zoom(factor, (x, y))
else:
self.zoom(1/factor, (x, y))
def keypress(self, event): def keypress(self, event):
"""gets keypress events and moves/rotates acive shape""" """gets keypress events and moves/rotates acive shape"""
...@@ -264,32 +199,24 @@ class StlViewPanel(wxGLPanel): ...@@ -264,32 +199,24 @@ class StlViewPanel(wxGLPanel):
angle = 1 angle = 1
#h #h
if keycode == 72: if keycode == 72:
self.move_shape((-step, 0)) self.parent.move_shape((-step, 0))
#l #l
if keycode == 76: if keycode == 76:
self.move_shape((step, 0)) self.parent.move_shape((step, 0))
#j #j
if keycode == 75: if keycode == 75:
self.move_shape((0, step)) self.parent.move_shape((0, step))
#k #k
if keycode == 74: if keycode == 74:
self.move_shape((0, -step)) self.parent.move_shape((0, -step))
#[ #[
if keycode == 91: if keycode == 91:
self.rotate_shape(-angle) self.parent.rotate_shape(-angle)
#] #]
if keycode == 93: if keycode == 93:
self.rotate_shape(angle) self.parent.rotate_shape(angle)
event.Skip() event.Skip()
wx.CallAfter(self.Refresh)
def update(self):
while(1):
dt = 0.05
time.sleep(0.05)
try:
wx.CallAfter(self.Refresh)
except:
return
def anim(self, obj): def anim(self, obj):
g = 50 * 9.8 g = 50 * 9.8
...@@ -321,7 +248,7 @@ class StlViewPanel(wxGLPanel): ...@@ -321,7 +248,7 @@ class StlViewPanel(wxGLPanel):
def drawmodel(self, m, n): def drawmodel(self, m, n):
batch = pyglet.graphics.Batch() batch = pyglet.graphics.Batch()
stl = stlview(m.facets, batch = batch) stlview(m.facets, batch = batch)
m.batch = batch m.batch = batch
m.animoffset = 300 m.animoffset = 300
#print m #print m
...@@ -338,10 +265,10 @@ class StlViewPanel(wxGLPanel): ...@@ -338,10 +265,10 @@ class StlViewPanel(wxGLPanel):
glPushMatrix() glPushMatrix()
glTranslatef(0, 0, -self.dist) glTranslatef(0, 0, -self.dist)
glMultMatrixd(build_rotmatrix(self.basequat)) # Rotate according to trackball glMultMatrixd(build_rotmatrix(self.basequat)) # Rotate according to trackball
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.2, 0.2, 0.2, 1)) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, vec(0.2, 0.2, 0.2, 1))
glTranslatef(- self.build_dimensions[3] - self.platform.width/2, glTranslatef(- self.build_dimensions[3] - self.platform.width / 2,
- self.build_dimensions[4] - self.platform.depth/2, 0) # Move origin to bottom left of platform - self.build_dimensions[4] - self.platform.depth / 2, 0) # Move origin to bottom left of platform
# Draw platform # Draw platform
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
self.platform.draw() self.platform.draw()
...@@ -365,12 +292,14 @@ class StlViewPanel(wxGLPanel): ...@@ -365,12 +292,14 @@ class StlViewPanel(wxGLPanel):
glPushMatrix() glPushMatrix()
# Draw objects # Draw objects
for i in self.parent.models.values(): for i in self.parent.models:
model = self.parent.models[i]
glPushMatrix() glPushMatrix()
glTranslatef(*(i.offsets)) glTranslatef(*(model.offsets))
glRotatef(i.rot, 0.0, 0.0, 1.0) glRotatef(model.rot, 0.0, 0.0, 1.0)
glScalef(*i.scale) glTranslatef(*(model.centeroffset))
i.batch.draw() glScalef(*model.scale)
model.batch.draw()
glPopMatrix() glPopMatrix()
glPopMatrix() glPopMatrix()
glPopMatrix() glPopMatrix()
...@@ -378,7 +307,7 @@ class StlViewPanel(wxGLPanel): ...@@ -378,7 +307,7 @@ class StlViewPanel(wxGLPanel):
def main(): def main():
app = wx.App(redirect = False) app = wx.App(redirect = False)
frame = wx.Frame(None, -1, "GL Window", size = (400, 400)) frame = wx.Frame(None, -1, "GL Window", size = (400, 400))
panel = StlViewPanel(frame) StlViewPanel(frame)
frame.Show(True) frame.Show(True)
app.MainLoop() app.MainLoop()
app.Destroy() app.Destroy()
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment