mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
Put my blender struts script in a safe place.
Nothing to do with QF, but then again, it might be useful.
This commit is contained in:
parent
82679066cc
commit
a3e53337b6
1 changed files with 206 additions and 0 deletions
206
tools/misc/MakeStruts.py
Normal file
206
tools/misc/MakeStruts.py
Normal file
|
@ -0,0 +1,206 @@
|
|||
# vim:ts=4:et
|
||||
#
|
||||
# Copyright (C) 2012 Bill Currie <bill@taniwha.org>
|
||||
# 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 #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
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()
|
Loading…
Reference in a new issue