Newer
Older
# GPL # "author": "Pontiac, Fourmadmen, Dreampainter"
Martin Buerbaum
committed
import bpy
from mathutils import *
from math import *
from bpy.props import *
# Create a new mesh (object) from verts/edges/faces.
# verts/edges/faces ... List of vertices/edges/faces for the
# new mesh (as used in from_pydata).
# name ... Name of the new mesh (& object).
Campbell Barton
committed
def create_mesh_object(context, verts, edges, faces, name):
Martin Buerbaum
committed
# Create new mesh
mesh = bpy.data.meshes.new(name)
# Make a mesh from a list of verts/edges/faces.
mesh.from_pydata(verts, edges, faces)
# Update mesh geometry after adding stuff.
mesh.update()
Martin Buerbaum
committed
Campbell Barton
committed
from bpy_extras import object_utils
return object_utils.object_data_add(context, mesh, operator=None)
Martin Buerbaum
committed
# A very simple "bridge" tool.
Martin Buerbaum
committed
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
faces = []
if not vertIdx1 or not vertIdx2:
return None
if len(vertIdx1) < 2 and len(vertIdx2) < 2:
return None
fan = False
if (len(vertIdx1) != len(vertIdx2)):
if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
fan = True
else:
return None
total = len(vertIdx2)
if closed:
# Bridge the start with the end.
if flipped:
face = [
vertIdx1[0],
vertIdx2[0],
vertIdx2[total - 1]]
if not fan:
face.append(vertIdx1[total - 1])
faces.append(face)
else:
face = [vertIdx2[0], vertIdx1[0]]
if not fan:
face.append(vertIdx1[total - 1])
face.append(vertIdx2[total - 1])
faces.append(face)
# Bridge the rest of the faces.
for num in range(total - 1):
if flipped:
if fan:
face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
else:
face = [vertIdx2[num], vertIdx1[num],
vertIdx1[num + 1], vertIdx2[num + 1]]
faces.append(face)
else:
if fan:
face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
else:
face = [vertIdx1[num], vertIdx2[num],
vertIdx2[num + 1], vertIdx1[num + 1]]
faces.append(face)
return faces
# @todo Clean up vertex&face creation process a bit.
def add_gem(r1, r2, seg, h1, h2):
"""
r1 = pavilion radius
r2 = crown radius
seg = number of segments
h1 = pavilion height
h2 = crown height
Generates the vertices and faces of the gem
"""
verts = []
Martin Buerbaum
committed
offset = a / 2.0 # Middle between segments
r3 = ((r1 + r2) / 2.0) / cos(offset) # Middle of crown
r4 = (r1 / 2.0) / cos(offset) # Middle of pavilion
h3 = h2 / 2.0 # Middle of crown height
h4 = -h1 / 2.0 # Middle of pavilion height
# Tip
vert_tip = len(verts)
verts.append(Vector((0.0, 0.0, -h1)))
Martin Buerbaum
committed
# Middle vertex of the flat side (crown)
vert_flat = len(verts)
verts.append(Vector((0.0, 0.0, h2)))
Martin Buerbaum
committed
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
edgeloop_flat = []
for i in range(seg):
s1 = sin(i * a)
s2 = sin(offset + i * a)
c1 = cos(i * a)
c2 = cos(offset + i * a)
verts.append((r4 * s1, r4 * c1, h4)) # Middle of pavilion
verts.append((r1 * s2, r1 * c2, 0.0)) # Pavilion
verts.append((r3 * s1, r3 * c1, h3)) # Middle crown
edgeloop_flat.append(len(verts))
verts.append((r2 * s2, r2 * c2, h2)) # Crown
faces = []
for index in range(seg):
i = index * 4
j = ((index + 1) % seg) * 4
faces.append([j + 2, vert_tip, i + 2, i + 3]) # Tip -> Middle of pav
faces.append([j + 2, i + 3, j + 3]) # Middle of pav -> pav
faces.append([j + 3, i + 3, j + 4]) # Pav -> Middle crown
faces.append([j + 4, i + 3, i + 4, i + 5]) # Crown quads
faces.append([j + 4, i + 5, j + 5]) # Middle crown -> crown
faces_flat = createFaces([vert_flat], edgeloop_flat, closed=True)
faces.extend(faces_flat)
return verts, faces
def add_diamond(segments, girdle_radius, table_radius,
crown_height, pavilion_height):
PI_2 = pi * 2.0
z_axis = (0.0, 0.0, -1.0)
verts = []
faces = []
height_flat = crown_height
height_middle = 0.0
height_tip = -pavilion_height
# Middle vertex of the flat side (crown)
vert_flat = len(verts)
verts.append(Vector((0.0, 0.0, height_flat)))
Martin Buerbaum
committed
# Tip
vert_tip = len(verts)
verts.append(Vector((0.0, 0.0, height_tip)))
Martin Buerbaum
committed
verts_flat = []
verts_girdle = []
for index in range(segments):
quat = Quaternion(z_axis, (index / segments) * PI_2)
Martin Buerbaum
committed
# Row for flat side
verts_flat.append(len(verts))
vec = quat * Vector((table_radius, 0.0, height_flat))
Martin Buerbaum
committed
verts.append(vec)
# Row for the middle/girdle
verts_girdle.append(len(verts))
vec = quat * Vector((girdle_radius, 0.0, height_middle))
Martin Buerbaum
committed
verts.append(vec)
# Flat face
faces_flat = createFaces([vert_flat], verts_flat, closed=True,
flipped=True)
# Side face
faces_side = createFaces(verts_girdle, verts_flat, closed=True)
# Tip faces
faces_tip = createFaces([vert_tip], verts_girdle, closed=True)
faces.extend(faces_tip)
faces.extend(faces_side)
faces.extend(faces_flat)
return verts, faces
class AddDiamond(bpy.types.Operator):
"""Add a diamond mesh"""
Martin Buerbaum
committed
bl_idname = "mesh.primitive_diamond_add"
bl_label = "Add Diamond"
Martin Buerbaum
committed
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
segments = IntProperty(name="Segments",
description="Number of segments for the diamond",
min=3,
max=256,
default=32)
girdle_radius = FloatProperty(name="Girdle Radius",
description="Girdle radius of the diamond",
min=0.01,
max=9999.0,
default=1.0)
table_radius = FloatProperty(name="Table Radius",
description="Girdle radius of the diamond",
min=0.01,
max=9999.0,
default=0.6)
crown_height = FloatProperty(name="Crown Height",
description="Crown height of the diamond",
min=0.01,
max=9999.0,
default=0.35)
pavilion_height = FloatProperty(name="Pavilion Height",
description="Pavilion height of the diamond",
min=0.01,
max=9999.0,
default=0.8)
def execute(self, context):
Thomas Dinges
committed
verts, faces = add_diamond(self.segments,
self.girdle_radius,
self.table_radius,
self.crown_height,
self.pavilion_height)
Martin Buerbaum
committed
Campbell Barton
committed
obj = create_mesh_object(context, verts, [], faces, "Diamond")
Martin Buerbaum
committed
return {'FINISHED'}
class AddGem(bpy.types.Operator):
"""Add a diamond gem"""
bl_idname = "mesh.primitive_gem_add"
bl_label = "Add Gem"
bl_description = "Create an offset faceted gem"
Martin Buerbaum
committed
segments = IntProperty(name="Segments",
description="Longitudial segmentation",
min=3,
max=265,
default=8,)
pavilion_radius = FloatProperty(name="Radius",
description="Radius of the gem",
min=0.01,
max=9999.0,
default=1.0)
crown_radius = FloatProperty(name="Table Radius",
description="Radius of the table(top)",
Martin Buerbaum
committed
min=0.01,
max=9999.0,
default=0.6)
crown_height = FloatProperty(name="Table height",
description="Height of the top half",
Martin Buerbaum
committed
min=0.01,
max=9999.0,
default=0.35)
pavilion_height = FloatProperty(name="Pavilion height",
description="Height of bottom half",
Martin Buerbaum
committed
min=0.01,
max=9999.0,
default=0.8)
def execute(self, context):
# create mesh
verts, faces = add_gem(
Thomas Dinges
committed
self.pavilion_radius,
self.crown_radius,
self.segments,
self.pavilion_height,
self.crown_height)
Martin Buerbaum
committed
Campbell Barton
committed
obj = create_mesh_object(context, verts, [], faces, "Gem")
Martin Buerbaum
committed
return {'FINISHED'}