X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=blender%2Fio_mspmath%2Fexport_shape.py;fp=blender%2Fio_mspmath%2Fexport_shape.py;h=793daaee77adf406623e2b0dada2187154f1022c;hb=1df02cf6bf187dfc8f0afe9223dd0f4cbb90b559;hp=0000000000000000000000000000000000000000;hpb=0aaef0b1fd412875137937f9e58ccb480c304be8;p=libs%2Fmath.git diff --git a/blender/io_mspmath/export_shape.py b/blender/io_mspmath/export_shape.py new file mode 100644 index 0000000..793daae --- /dev/null +++ b/blender/io_mspmath/export_shape.py @@ -0,0 +1,195 @@ +import math +from mathutils import Vector + +class Vertex: + def __init__(self, v=None): + self.vertex = v + if v: + self.co = v.co + else: + self.co = Vector((0, 0, 0)) + +class Edge: + def __init__(self, e=None): + self.edge = e + self.vertices = [] + self.polygons = [] + self.convex = True + +class Polygon: + def __init__(self, p=None): + self.polygon = p + self.edges = [] + self.vertices = [] + if p: + self.normal = p.normal + else: + self.normal = Vector((0, 0, 1)) + +class Mesh: + def __init__(self, m=None): + if m: + self.vertices = [Vertex(v) for v in m.vertices] + self.edges = [Edge(e) for e in m.edges] + self.polygons = [Polygon(p) for p in m.polygons] + + for e in self.edges: + e.vertices = [self.vertices[i] for i in e.edge.vertices] + + for p in self.polygons: + p.vertices = [self.vertices[i] for i in p.polygon.vertices] + p.edges = [self.edges[m.loops[i].edge_index] for i in p.polygon.loop_indices] + for e in p.edges: + e.polygons.append(p) + + else: + self.edges = [] + self.vertices = [] + self.polygons = [] + self.convex = True + +class SphereFit: + def __init__(self, mesh): + self.mesh = mesh + min_coords = tuple(map(min, zip(*(v.co for v in self.mesh.vertices)))) + max_coords = tuple(map(max, zip(*(v.co for v in self.mesh.vertices)))) + self.center = (Vector(min_coords)+Vector(max_coords))/2 + self.radius = max(max_coords[i]-min_coords[i] for i in range(3))/2 + + def calculate_center_error(self): + error = Vector() + for v in self.mesh.vertices: + p = v.co-self.center + p.normalize() + p = self.center+p*self.radius + error += p-v.co + + return error/len(self.mesh.vertices) + + def calculate_radius_error(self): + error = 0 + for v in self.mesh.vertices: + error += self.radius-(v.co-self.center).length + return error/len(self.mesh.vertices) + + def calculate_fit_error(self): + error = 0 + for v in self.mesh.vertices: + error += (self.radius-(v.co-self.center).length)**2 + return math.sqrt(error/len(self.mesh.vertices)) + + def fit(self, epsilon=1e-3): + while 1: + error = self.calculate_radius_error() + if errordistances[side[0]][side[1]]: + side = (i, j) + + errors[side[0]][side[1]] += distances[side[0]][side[1]] + counts[side[0]][side[1]] += 1 + + for i in range(3): + for j in range(2): + if counts[i][j]: + errors[i][j] /= counts[i][j] + + return errors + + def calculate_fit_error(self): + error = 0 + for v in self.mesh.vertices: + distances = tuple((r[0]-v.co[i], v.co[i]-r[1]) for i, r in enumerate(self.ranges)) + error += max(max(*d) for d in distances)**2 + return math.sqrt(error/len(self.mesh.vertices)) + + def fit(self, epsilon=1e-3): + while 1: + errors = self.calculate_side_errors() + max_error = max(max(map(abs, e)) for e in errors) + if max_errorsphere.radius/1e5 + if use_center: + out_file.begin("transformed") + out_file.write("translate", *sphere.center) + + out_file.begin("sphere") + out_file.write("radius", sphere.radius) + out_file.end() + + if use_center: + out_file.end() + + elif shape_type=="BOX": + box = BoxFit(mesh) + error = box.fit() + + use_center = box.center.length>min(box.dimensions)/1e5 + if use_center: + out_file.begin("transformed") + out_file.write("translate", *box.center) + + out_file.begin("box") + out_file.write("dimensions", *box.dimensions) + out_file.end() + + if use_center: + out_file.end()