Commit e94d076b authored by Guillaume Seguin's avatar Guillaume Seguin

Compute a single transformation to speed up model processing

Also add a little reference to the ray-triangle intersection algorithm
parent 5d637a90
......@@ -48,6 +48,15 @@ if "-nogl" not in sys.argv:
def evalme(s):
return eval(s[s.find("(") + 1:s.find(")")])
def transformation_matrix(model):
matrix = stltool.I
if any(model.centeroffset):
matrix = model.translation_matrix(model.centeroffset).dot(matrix)
if model.rot:
matrix = model.rotation_matrix([0, 0, model.rot]).dot(matrix)
if any(model.offsets):
matrix = model.translation_matrix(model.offsets).dot(matrix)
return matrix
class showstl(wx.Window):
def __init__(self, parent, size, pos):
......@@ -237,13 +246,7 @@ class StlPlater(Plater):
# TODO: speedup search by first checking if ray is in bounding box
# of the given model
for key, model in self.models.iteritems():
transformed = model
if any(model.centeroffset):
transformed = transformed.translate(model.centeroffset)
if model.rot:
transformed = transformed.rotate([0, 0, model.rot])
if any(model.offsets):
transformed = transformed.translate(model.offsets)
transformed = model.transform(transformation_matrix(model))
facet, facet_dist = transformed.intersect(ray_near, ray_far)
if facet is not None and facet_dist < best_dist:
best_match = key
......@@ -355,7 +358,6 @@ class StlPlater(Plater):
facets = []
for model in self.models.values():
r = model.rot
rot = [0, 0, r] if r else None
o = model.offsets
co = model.centeroffset
sf.write("translate([%s, %s, %s])"
......@@ -365,12 +367,7 @@ class StlPlater(Plater):
r,
co[0], co[1], co[2],
model.filename))
if any(co):
model = model.translate(co)
if rot:
model = model.rotate(rot)
if any(o):
model = model.translate(o)
model = model.transform(transformation_matrix(model))
facets += model.facets
stltool.emitstl(name, facets, "plater_export")
print _("Wrote plate to %s") % name
......
# coding: utf-8
# This file is part of the Printrun suite.
#
# Printrun is free software: you can redistribute it and/or modify
......@@ -158,6 +160,10 @@ class stl(object):
return
def intersect(self, ray_far, ray_near):
"""
Möller–Trumbore intersection algorithm in pure python
Based on http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
"""
ray_near = numpy.array(ray_near)
ray_far = numpy.array(ray_far)
ray_dir = normalize(ray_far - ray_near)
......@@ -215,15 +221,18 @@ class stl(object):
newmodel = self.transform(matrix)
return newmodel
def translate(self, v = [0, 0, 0]):
def translation_matrix(self, v):
matrix = [[1, 0, 0, v[0]],
[0, 1, 0, v[1]],
[0, 0, 1, v[2]],
[0, 0, 0, 1]
]
return self.transform(numpy.array(matrix))
return numpy.array(matrix)
def rotate(self, v = [0, 0, 0]):
def translate(self, v = [0, 0, 0]):
return self.transform(self.translation_matrix(v))
def rotation_matrix(self, v):
z = v[2]
matrix1 = [[math.cos(math.radians(z)), -math.sin(math.radians(z)), 0, 0],
[math.sin(math.radians(z)), math.cos(math.radians(z)), 0, 0],
......@@ -245,15 +254,21 @@ class stl(object):
[0, 0, 0, 1]
]
matrix3 = numpy.array(matrix3)
return self.transform(matrix1).transform(matrix2).transform(matrix3)
return matrix3.dot(matrix2.dot(matrix1))
def scale(self, v = [0, 0, 0]):
def rotate(self, v = [0, 0, 0]):
return self.transform(self.rotation_matrix(v))
def scale_matrix(self, v):
matrix = [[v[0], 0, 0, 0],
[0, v[1], 0, 0],
[0, 0, v[2], 0],
[0, 0, 0, 1]
]
return self.transform(numpy.array(matrix))
return numpy.array(matrix)
def scale(self, v = [0, 0, 0]):
return self.transform(self.scale_matrix(v))
def transform(self, m = I):
s = stl()
......
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