Newer
Older
# GPL # "author": "Pontiac, Fourmadmen, Dreampainter"
Martin Buerbaum
committed
import bpy
from bpy.types import Operator
from mathutils import (
Vector,
Quaternion,
)
from math import cos, sin, pi
from bpy.props import (
FloatProperty,
IntProperty,
)
Martin Buerbaum
committed
# 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
Martin Buerbaum
committed
# A very simple "bridge" tool.
Martin Buerbaum
committed
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
Martin Buerbaum
committed
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
Martin Buerbaum
committed
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
Martin Buerbaum
committed
# @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
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
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
Martin Buerbaum
committed
def add_diamond(segments, girdle_radius, table_radius,
crown_height, pavilion_height):
Martin Buerbaum
committed
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(Operator):
Martin Buerbaum
committed
bl_idname = "mesh.primitive_diamond_add"
bl_label = "Add Diamond"
bl_description = "Construct a diamond mesh"
Martin Buerbaum
committed
name="Segments",
description="Number of segments for the diamond",
min=3,
max=256,
default=32
)
name="Girdle Radius",
description="Girdle radius of the diamond",
min=0.01,
max=9999.0,
default=1.0
)
name="Table Radius",
description="Girdle radius of the diamond",
min=0.01,
max=9999.0,
default=0.6
)
name="Crown Height",
description="Crown height of the diamond",
min=0.01,
max=9999.0,
default=0.35
)
name="Pavilion Height",
description="Pavilion height of the diamond",
min=0.01,
max=9999.0,
default=0.8
)
Martin Buerbaum
committed
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(Operator):
Martin Buerbaum
committed
bl_idname = "mesh.primitive_gem_add"
bl_label = "Add Gem"
bl_description = "Construct an offset faceted gem mesh"
Martin Buerbaum
committed
name="Segments",
description="Longitudial segmentation",
min=3,
max=265,
default=8
)
name="Radius",
description="Radius of the gem",
min=0.01,
max=9999.0,
default=1.0
)
name="Table Radius",
description="Radius of the table(top)",
min=0.01,
max=9999.0,
default=0.6
)
name="Table height",
description="Height of the top half",
min=0.01,
max=9999.0,
default=0.35
)
name="Pavilion height",
description="Height of bottom half",
min=0.01,
max=9999.0,
default=0.8
)
Martin Buerbaum
committed
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'}