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