Commit d603348b authored by sumpfralle's avatar sumpfralle

moved some opengl functions to OpenGLTools

moved some ODE functions to ode_objects
added an EmergencyDialog class for displaying dependency problems via the builtin Tk interface


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@261 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 55510618
from pycam.Geometry.Point import Point
import OpenGL.GL as GL
import OpenGL.GLU as GLU
import OpenGL.GLUT as GLUT
import math
# the length of the distance vector does not matter - it will be normalized and multiplied later anyway
......@@ -174,3 +175,151 @@ class Camera:
return (factors_x, factors_y)
def keep_gl_mode(func):
def wrapper(*args, **kwargs):
prev_mode = GL.glGetIntegerv(GL.GL_MATRIX_MODE)
func(*args, **kwargs)
GL.glMatrixMode(prev_mode)
return wrapper
def keep_matrix(func):
def wrapper(*args, **kwargs):
pushed_matrix_mode = GL.glGetIntegerv(GL.GL_MATRIX_MODE)
GL.glPushMatrix()
func(*args, **kwargs)
final_matrix_mode = GL.glGetIntegerv(GL.GL_MATRIX_MODE)
GL.glMatrixMode(pushed_matrix_mode)
GL.glPopMatrix()
GL.glMatrixMode(final_matrix_mode)
return wrapper
@keep_matrix
def draw_string(x, y, z, p, s, scale=.01):
GL.glPushMatrix()
GL.glTranslatef(x, y, z)
if p == 'xy':
GL.glRotatef(90, 1, 0, 0)
pass
elif p == 'yz':
GL.glRotatef(90, 0, 1, 0)
GL.glRotatef(90, 0, 0, 1)
elif p == 'xz':
GL.glRotatef(90, 0, 1, 0)
GL.glRotatef(90, 0, 0, 1)
GL.glRotatef(45, 0, 1, 0)
GL.glScalef(scale, scale, scale)
for c in str(s):
GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_ROMAN, ord(c))
GL.glPopMatrix()
@keep_gl_mode
@keep_matrix
def draw_axes(settings):
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glLoadIdentity()
#GL.glTranslatef(0, 0, -2)
size_x = abs(settings.get("maxx"))
size_y = abs(settings.get("maxy"))
size_z = abs(settings.get("maxz"))
size = 1.5 * max(max(size_x, size_y), size_z)
# the divider is just based on playing with numbers
scale = size/1500.0
string_distance = 1.1 * size
GL.glBegin(GL.GL_LINES)
GL.glColor3f(1, 0, 0)
GL.glVertex3f(0, 0, 0)
GL.glVertex3f(size, 0, 0)
GL.glEnd()
draw_string(string_distance, 0, 0, 'xy', "X", scale=scale)
GL.glBegin(GL.GL_LINES)
GL.glColor3f(0, 1, 0)
GL.glVertex3f(0, 0, 0)
GL.glVertex3f(0, size, 0)
GL.glEnd()
draw_string(0, string_distance, 0, 'yz', "Y", scale=scale)
GL.glBegin(GL.GL_LINES)
GL.glColor3f(0, 0, 1)
GL.glVertex3f(0, 0, 0)
GL.glVertex3f(0, 0, size)
GL.glEnd()
draw_string(0, 0, string_distance, 'xz', "Z", scale=scale)
@keep_matrix
def draw_bounding_box(minx, miny, minz, maxx, maxy, maxz, color):
p1 = [minx, miny, minz]
p2 = [minx, maxy, minz]
p3 = [maxx, maxy, minz]
p4 = [maxx, miny, minz]
p5 = [minx, miny, maxz]
p6 = [minx, maxy, maxz]
p7 = [maxx, maxy, maxz]
p8 = [maxx, miny, maxz]
# lower rectangle
GL.glBegin(GL.GL_LINES)
GL.glColor3f(*color)
# all combinations of neighbouring corners
for corner_pair in [(p1, p2), (p1, p5), (p1, p4), (p2, p3),
(p2, p6), (p3, p4), (p3, p7), (p4, p8), (p5, p6),
(p6, p7), (p7, p8), (p8, p5)]:
GL.glVertex3f(*(corner_pair[0]))
GL.glVertex3f(*(corner_pair[1]))
GL.glEnd()
@keep_gl_mode
@keep_matrix
def draw_cutter(cutter, color):
if not cutter is None:
GL.glColor3f(*color)
cutter.to_OpenGL()
@keep_gl_mode
@keep_matrix
def draw_complete_model_view(settings):
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glLoadIdentity()
# axes
if settings.get("show_axes"):
draw_axes(settings)
# stock model
if settings.get("show_bounding_box"):
draw_bounding_box(float(settings.get("minx")), float(settings.get("miny")),
float(settings.get("minz")), float(settings.get("maxx")),
float(settings.get("maxy")), float(settings.get("maxz")),
settings.get("color_bounding_box"))
# draw the model
if settings.get("show_model"):
GL.glColor3f(*settings.get("color_model"))
settings.get("model").to_OpenGL()
# draw the toolpath
if settings.get("show_toolpath"):
for toolpath_obj in settings.get("toolpath"):
if toolpath_obj.visible:
draw_toolpath(toolpath_obj.get_path(),
settings.get("color_toolpath_cut"),
settings.get("color_toolpath_return"))
# draw the drill
if settings.get("show_drill_progress"):
draw_cutter(settings.get("cutter"), settings.get("color_cutter"))
@keep_gl_mode
@keep_matrix
def draw_toolpath(toolpath, color_forward, color_backward):
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glLoadIdentity()
if toolpath:
last = None
for path in toolpath:
if last:
GL.glColor3f(*color_backward)
GL.glBegin(GL.GL_LINES)
GL.glVertex3f(last.x, last.y, last.z)
last = path.points[0]
GL.glVertex3f(last.x, last.y, last.z)
GL.glEnd()
GL.glColor3f(*color_forward)
GL.glBegin(GL.GL_LINE_STRIP)
for point in path.points:
GL.glVertex3f(point.x, point.y, point.z)
GL.glEnd()
last = path.points[-1]
......@@ -10,6 +10,7 @@ import pycam.PathGenerators
import pycam.PathProcessors
import pycam.Geometry.utils as utils
import pycam.Gui.OpenGLTools as ogl_tools
import pycam.Gui.ode_objects as ode_objects
import OpenGL.GL as GL
import OpenGL.GLU as GLU
import OpenGL.GLUT as GLUT
......@@ -347,7 +348,7 @@ class GLView:
def _paint_raw(self, widget=None):
# draw the model
GuiCommon.draw_complete_model_view(self.settings)
ogl_tools.draw_complete_model_view(self.settings)
# update the dimension display
s = self.settings
dimension_bar = self.gui.get_object("view3ddimension")
......@@ -512,7 +513,7 @@ class ProjectGui:
for name in COLORS.keys():
self.settings.set(name, COLORS[name])
# set the availability of ODE
if GuiCommon.is_ode_available():
if ode_objects.is_ode_available():
self.settings.set("enable_ode", True)
self.gui.get_object("SettingEnableODE").set_sensitive(True)
self.gui.get_object("MaterialAllowanceControl").set_sensitive(True)
......@@ -684,7 +685,7 @@ class ProjectGui:
def get_physics(self, cutter):
if self.settings.get("enable_ode"):
self._physics_cache = GuiCommon.generate_physics(self.settings, cutter, self._physics_cache)
self._physics_cache = ode_objects.generate_physics(self.settings, cutter, self._physics_cache)
else:
self._physics_cache = None
return self._physics_cache
......
......@@ -16,7 +16,7 @@ from pycam.PathProcessors import *
from pycam.Geometry.utils import *
from pycam.Importers import *
from pycam.Exporters import *
import pycam.Gui.common as GuiCommon
import pycam.Gui.OpenGLTools as ogl_tools
import pycam.Gui.Settings
import time
......@@ -53,22 +53,6 @@ class OpenglWidget(Tk.Opengl):
self.master.resetView()
class SimpleGui(Tk.Frame):
def draw_string(self, x, y, z, p, s, scale=.01):
GL.glPushMatrix()
GL.glTranslatef(x,y,z)
if p == 'xy':
pass
elif p == 'yz':
GL.glRotatef(90, 0, 1, 0)
GL.glRotatef(90, 0, 0, 1)
elif p == 'xz':
GL.glRotatef(90, 0, 1, 0)
GL.glRotatef(90, 0, 0, 1)
GL.glRotatef(-90, 0, 1, 0)
GL.glScalef(scale,scale,scale)
for c in str(s):
GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_ROMAN, ord(c))
GL.glPopMatrix()
def load_model(self, model):
self.model = model
......@@ -88,19 +72,19 @@ class SimpleGui(Tk.Frame):
GL.glVertex3f(0,0,0)
GL.glVertex3f(size,0,0)
GL.glEnd()
GuiCommon.draw_string(size,0,0,'xy',"X")
ogl_tools.draw_string(size,0,0,'xy',"X")
GL.glBegin(GL.GL_LINES)
GL.glColor3f(0,1,0)
GL.glVertex3f(0,0,0)
GL.glVertex3f(0,size,0)
GL.glEnd()
GuiCommon.draw_string(0,size,0,'yz',"Y")
ogl_tools.draw_string(0,size,0,'yz',"Y")
GL.glBegin(GL.GL_LINES)
GL.glColor3f(0,0,1)
GL.glVertex3f(0,0,0)
GL.glVertex3f(0,0,size)
GL.glEnd()
GuiCommon.draw_string(0,0,size,'xz',"Z")
ogl_tools.draw_string(0,0,size,'xz',"Z")
if True:
# stock model
......
import OpenGL.GL as GL
import OpenGL.GLUT as GLUT
import Tkinter
# "ode" is imported later, if required
#import ode_objects
import random
......@@ -18,165 +17,6 @@ MODEL_TRANSFORMATIONS = {
"y_swap_z": ((1, 0, 0, 0), (0, 0, 1, 0), (0, 1, 0, 0)),
}
_ode_override_state = None
def keep_gl_mode(func):
def wrapper(*args, **kwargs):
prev_mode = GL.glGetIntegerv(GL.GL_MATRIX_MODE)
func(*args, **kwargs)
GL.glMatrixMode(prev_mode)
return wrapper
def keep_matrix(func):
def wrapper(*args, **kwargs):
pushed_matrix_mode = GL.glGetIntegerv(GL.GL_MATRIX_MODE)
GL.glPushMatrix()
func(*args, **kwargs)
final_matrix_mode = GL.glGetIntegerv(GL.GL_MATRIX_MODE)
GL.glMatrixMode(pushed_matrix_mode)
GL.glPopMatrix()
GL.glMatrixMode(final_matrix_mode)
return wrapper
@keep_matrix
def draw_string(x, y, z, p, s, scale=.01):
GL.glPushMatrix()
GL.glTranslatef(x, y, z)
if p == 'xy':
GL.glRotatef(90, 1, 0, 0)
pass
elif p == 'yz':
GL.glRotatef(90, 0, 1, 0)
GL.glRotatef(90, 0, 0, 1)
elif p == 'xz':
GL.glRotatef(90, 0, 1, 0)
GL.glRotatef(90, 0, 0, 1)
GL.glRotatef(45, 0, 1, 0)
GL.glScalef(scale, scale, scale)
for c in str(s):
GLUT.glutStrokeCharacter(GLUT.GLUT_STROKE_ROMAN, ord(c))
GL.glPopMatrix()
@keep_gl_mode
@keep_matrix
def draw_axes(settings):
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glLoadIdentity()
#GL.glTranslatef(0, 0, -2)
size_x = abs(settings.get("maxx"))
size_y = abs(settings.get("maxy"))
size_z = abs(settings.get("maxz"))
size = 1.5 * max(max(size_x, size_y), size_z)
# the divider is just based on playing with numbers
scale = size/1500.0
string_distance = 1.1 * size
GL.glBegin(GL.GL_LINES)
GL.glColor3f(1, 0, 0)
GL.glVertex3f(0, 0, 0)
GL.glVertex3f(size, 0, 0)
GL.glEnd()
draw_string(string_distance, 0, 0, 'xy', "X", scale=scale)
GL.glBegin(GL.GL_LINES)
GL.glColor3f(0, 1, 0)
GL.glVertex3f(0, 0, 0)
GL.glVertex3f(0, size, 0)
GL.glEnd()
draw_string(0, string_distance, 0, 'yz', "Y", scale=scale)
GL.glBegin(GL.GL_LINES)
GL.glColor3f(0, 0, 1)
GL.glVertex3f(0, 0, 0)
GL.glVertex3f(0, 0, size)
GL.glEnd()
draw_string(0, 0, string_distance, 'xz', "Z", scale=scale)
@keep_matrix
def draw_bounding_box(minx, miny, minz, maxx, maxy, maxz, color):
p1 = [minx, miny, minz]
p2 = [minx, maxy, minz]
p3 = [maxx, maxy, minz]
p4 = [maxx, miny, minz]
p5 = [minx, miny, maxz]
p6 = [minx, maxy, maxz]
p7 = [maxx, maxy, maxz]
p8 = [maxx, miny, maxz]
# lower rectangle
GL.glBegin(GL.GL_LINES)
GL.glColor3f(*color)
# all combinations of neighbouring corners
for corner_pair in [(p1, p2), (p1, p5), (p1, p4), (p2, p3),
(p2, p6), (p3, p4), (p3, p7), (p4, p8), (p5, p6),
(p6, p7), (p7, p8), (p8, p5)]:
GL.glVertex3f(*(corner_pair[0]))
GL.glVertex3f(*(corner_pair[1]))
GL.glEnd()
@keep_gl_mode
@keep_matrix
def draw_cutter(cutter, color):
if not cutter is None:
GL.glColor3f(*color)
cutter.to_OpenGL()
@keep_gl_mode
@keep_matrix
def draw_complete_model_view(settings):
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glLoadIdentity()
# axes
if settings.get("show_axes"):
draw_axes(settings)
# stock model
if settings.get("show_bounding_box"):
draw_bounding_box(float(settings.get("minx")), float(settings.get("miny")),
float(settings.get("minz")), float(settings.get("maxx")),
float(settings.get("maxy")), float(settings.get("maxz")),
settings.get("color_bounding_box"))
# draw the model
if settings.get("show_model"):
GL.glColor3f(*settings.get("color_model"))
settings.get("model").to_OpenGL()
# draw the toolpath
if settings.get("show_toolpath"):
for toolpath_obj in settings.get("toolpath"):
if toolpath_obj.visible:
draw_toolpath(toolpath_obj.get_path(),
settings.get("color_toolpath_cut"),
settings.get("color_toolpath_return"))
# draw the drill
if settings.get("show_drill_progress"):
draw_cutter(settings.get("cutter"), settings.get("color_cutter"))
@keep_gl_mode
@keep_matrix
def draw_toolpath(toolpath, color_forward, color_backward):
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glLoadIdentity()
if toolpath:
last = None
for path in toolpath:
if last:
GL.glColor3f(*color_backward)
GL.glBegin(GL.GL_LINES)
GL.glVertex3f(last.x, last.y, last.z)
last = path.points[0]
GL.glVertex3f(last.x, last.y, last.z)
GL.glEnd()
GL.glColor3f(*color_forward)
GL.glBegin(GL.GL_LINE_STRIP)
for point in path.points:
GL.glVertex3f(point.x, point.y, point.z)
GL.glEnd()
last = path.points[-1]
@keep_gl_mode
def rotate_view(scale, rotation=None):
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GL.glScalef(scale, scale, scale)
if rotation:
for one_rot in rotation:
GL.glRotatef(*one_rot)
def transform_model(model, direction="normal"):
model.transform(MODEL_TRANSFORMATIONS[direction])
......@@ -189,30 +29,38 @@ def scale_model(model, scale):
matrix = ((scale, 0, 0, 0), (0, scale, 0, 0), (0, 0, scale, 0))
model.transform(matrix)
def generate_physics(settings, cutter, physics=None):
import ode_objects
if physics is None:
physics = ode_objects.PhysicalWorld()
physics.reset()
physics.add_mesh((0, 0, 0), settings.get("model").triangles())
shape_info = cutter.get_shape("ODE", additional_distance=settings.get("material_allowance"))
physics.set_drill(shape_info[0], (0.0, 0.0, 0.0))
return physics
def is_ode_available():
global _ode_override_state
if not _ode_override_state is None:
return _ode_override_state
else:
try:
import ode
return True
except ImportError:
return False
class EmergencyDialog(Tkinter.Frame):
""" This graphical message window requires no external dependencies.
The Tk interface package is part of the main python distribution.
Use this class for displaying dependency errors (especially on Windows).
"""
def override_ode_availability(state):
global _ode_override_state
_ode_override_state = state
def __init__(self, title, message):
try:
root = Tkinter.Tk()
except Tkinter.TclError, err_msg:
print >>sys.stderr, "Warning: Failed to create error dialog window (%s). Probably you are running PyCAM from a terminal." % str(err_msg)
print >>sys.stderr, "%s: %s" % (title, message)
return
root.title(title)
root.bind("<Return>", self.finish)
root.bind("<Escape>", self.finish)
root.minsize(300, 100)
Tkinter.Frame.__init__(self, root, width=400)
self.pack()
# add text output as label
message = Tkinter.Message(self, text=message, width=200)
message["width"] = 200
message.pack()
# add the "close" button
close = Tkinter.Button(root, text="Close")
close["command"] = self.finish
close.pack(side=Tkinter.BOTTOM)
self.mainloop()
def finish(self, *args):
self.quit()
class ToolPathList(list):
......
import ode
try:
import ode
except ImportError:
ode = None
ShapeCylinder = lambda radius, height: ode.GeomCylinder(None, radius, height)
ShapeCapsule = lambda radius, height: ode.GeomCapsule(None, radius, height - (2 * radius))
_ode_override_state = None
def generate_physics(settings, cutter, physics=None):
if physics is None:
physics = PhysicalWorld()
physics.reset()
physics.add_mesh((0, 0, 0), settings.get("model").triangles())
shape_info = cutter.get_shape("ODE", additional_distance=settings.get("material_allowance"))
physics.set_drill(shape_info[0], (0.0, 0.0, 0.0))
return physics
def is_ode_available():
global _ode_override_state
if not _ode_override_state is None:
return _ode_override_state
else:
if ode is None:
return False
else:
return True
def override_ode_availability(state):
global _ode_override_state
_ode_override_state = state
def convert_triangles_to_vertices_faces(triangles):
corners = []
......
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