From a3e53337b60d1af30c4dbc0d75fcb4f662ecfa1d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 22 Feb 2012 17:47:16 +0900 Subject: [PATCH] Put my blender struts script in a safe place. Nothing to do with QF, but then again, it might be useful. --- tools/misc/MakeStruts.py | 206 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 tools/misc/MakeStruts.py diff --git a/tools/misc/MakeStruts.py b/tools/misc/MakeStruts.py new file mode 100644 index 000000000..736d8f803 --- /dev/null +++ b/tools/misc/MakeStruts.py @@ -0,0 +1,206 @@ +# vim:ts=4:et +# +# Copyright (C) 2012 Bill Currie +# Date: 2012/2/20 +# +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# 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 2 +# 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, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +bl_info = { + "name": "Strut Generator", + "author": "Bill Currie", + "blender": (2, 6, 2), + "api": 35622, + "location": "View3D > Add > Mesh > Struts", + "description": "Add struts meshes based on selected truss meshes", + "warning": "can get very high-poly", + "wiki_url": "", + "tracker_url": "", + "category": "Add Mesh"} + +import bpy +from bpy.props import FloatProperty,IntProperty,BoolProperty +from mathutils import Vector,Matrix +from math import pi, cos, sin + +cossin = [] + +def build_cossin(n): + global cossin + cossin = [] + for i in range(n): + a = 2 * pi * i / n + cossin.append((cos(a), sin(a))) + + +def make_strut(v1, v2, id, od, n, solid, loops): + v1 = Vector(v1) + v2 = Vector(v2) + axis = v2 - v1 + pos = [(0, od / 2)] + if loops: + pos += [((od - id) / 2, od / 2), + (axis.length - (od - id) / 2, od / 2)] + pos += [(axis.length, od / 2)] + if solid: + pos += [(axis.length, id / 2)] + if loops: + pos += [(axis.length - (od - id) / 2, id / 2), + ((od - id) / 2, id / 2)] + pos += [(0, id / 2)] + vps = len(pos) + fps = vps + if not solid: + fps -= 1 + fw = axis.copy() + fw.normalize() + if (abs(axis[0] / axis.length) < 1e-5 + and abs(axis[1] / axis.length) < 1e-5): + up = Vector((-1, 0, 0)) + else: + up = Vector((0, 0, 1)) + lf = up.cross(fw) + lf.normalize() + up = fw.cross(lf) + mat = Matrix((fw, lf, up)) + mat.transpose() + verts = [None] * n * vps + faces = [None] * n * fps + for i in range(n): + base = (i - 1) * vps + x = cossin[i][0] + y = cossin[i][1] + for j in range(vps): + p = Vector((pos[j][0], pos[j][1] * x, pos[j][1] * y)) + p = mat * p + verts[i * vps + j] = p + v1 + if i: + for j in range(fps): + f = (i - 1) * fps + j + faces[f] = [base + j, base + vps + j, + base + vps + (j + 1) % vps, base + (j + 1) % vps] + base = len(verts) - vps + i = n + for j in range(fps): + f = (i - 1) * fps + j + faces[f] = [base + j, j, (j + 1) % vps, base + (j + 1) % vps] + #print(verts,faces) + return verts, faces + +def create_struts(self, context, id, od, segments, solid, loops): + build_cossin(segments) + vps = 2 + if solid: + vps *= 2 + if loops: + vps *= 2 + fps = vps + if not solid: + fps -= 1 + + bpy.context.user_preferences.edit.use_global_undo = False + for truss_obj in bpy.context.scene.objects: + if not truss_obj.select: + continue + truss_obj.select = False + truss_mesh = truss_obj.to_mesh(context.scene, True, 'PREVIEW') + if not truss_mesh.edges: + continue + mesh = bpy.data.meshes.new("Struts") + + verts = [None] * len(truss_mesh.edges) * segments * vps + faces = [None] * len(truss_mesh.edges) * segments * fps + vbase = 0 + fbase = 0 + for e in truss_mesh.edges: + v1 = truss_mesh.vertices[e.vertices[0]] + v2 = truss_mesh.vertices[e.vertices[1]] + v, f = make_strut(v1.co, v2.co, id, od, segments, solid, loops) + for fv in f: + for i in range(len(fv)): + fv[i] += vbase + for i in range(len(v)): + verts[vbase + i] = v[i] + for i in range(len(f)): + faces[fbase + i] = f[i] + #if not base % 12800: + # print (base * 100 / len(verts)) + vbase += vps * segments + fbase += fps * segments + #print(verts,faces) + mesh.from_pydata(verts, [], faces) + obj = bpy.data.objects.new("Struts", mesh) + bpy.context.scene.objects.link(obj) + obj.select = True + obj.location = truss_obj.location + bpy.context.scene.objects.active = obj + mesh.update() + bpy.context.user_preferences.edit.use_global_undo = True + return {'FINISHED'} + +class Struts(bpy.types.Operator): + """Add one or more struts meshes based on selected truss meshes""" + bl_idname = "mesh.generate_struts" + bl_label = "Struts" + bl_description = """Add one or more struts meshes based on selected truss meshes""" + bl_options = {'REGISTER', 'UNDO'} + + id = FloatProperty(name = "Inside Diameter", + description = "diameter of inner surface", + min = 0.0, + soft_min = 0.0, + max = 100, + soft_max = 100, + default = 0.04) + od = FloatProperty(name = "Outside Diameter", + description = "diameter of outer surface", + min = 0.01, + soft_min = 0.01, + max = 100, + soft_max = 100, + default = 0.05) + solid = BoolProperty(name="Solid", + description="Create inner surface.", + default=True) + loops = BoolProperty(name="Loops", + description="Create sub-surf friendly loops.", + default=False) + segments = IntProperty(name="Segments", + description="Number of segments around strut", + min=3, soft_min=3, + max=64, soft_max=64, + default=32) + + def execute(self, context): + keywords = self.as_keywords () + return create_struts(self, context, **keywords) + +def menu_func(self, context): + self.layout.operator(Struts.bl_idname, text = "Struts", icon='PLUGIN') + +def register(): + bpy.utils.register_module(__name__) + bpy.types.INFO_MT_mesh_add.append(menu_func) + +def unregister(): + bpy.utils.unregister_module(__name__) + +if __name__ == "__main__": + register()