Skip to content
Snippets Groups Projects
Commit 4d15f470 authored by Martin Buerbaum's avatar Martin Buerbaum
Browse files

* Version 1.1

* Major re-write.
* Use existing code from createFaces, obj_store_recall_properties and apply_view_rotation.
* "Edit" button is now defined by the "Recall object operator" script => has to be activated in the Add-On panel.
* A lot of cleanup.
* TODO: createFaces, obj_store_recall_properties and apply_view_rotation should really be put into a central file/library.
parent 35f942d8
No related branches found
No related tags found
No related merge requests found
...@@ -23,16 +23,124 @@ ...@@ -23,16 +23,124 @@
bl_addon_info = { bl_addon_info = {
'name': 'Add Mesh: Gem', 'name': 'Add Mesh: Gem',
'author': 'Dreampainter', 'author': 'Dreampainter',
'version': '1.0.1', 'version': '1.1',
'blender': (2, 5, 3), 'blender': (2, 5, 3),
'location': 'View3D > Add > Mesh ', 'location': 'View3D > Add > Mesh ',
'url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Add_Gem', 'url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
'Scripts/Add_Gem',
'category': 'Add Mesh'} 'category': 'Add Mesh'}
import bpy import bpy
# Stores the values of a list of properties in a
# property group (named like the operator) in the object.
# Always replaces any existing property group with the same name!
# @todo: Should we do this in EDIT Mode? Sounds dangerous.
def obj_store_recall_properties(ob, op, prop_list):
if ob and op and prop_list:
#print("Storing recall data for operator: " + op.bl_idname) # DEBUG
# Store new recall properties.
prop_list['recall_op'] = op.bl_idname
ob['recall'] = prop_list
# Apply view rotation to objects if "Align To" for new objects
# was set to "VIEW" in the User Preference.
def apply_view_rotation(context, ob):
align = bpy.context.user_preferences.edit.object_align
if (context.space_data.type == 'VIEW_3D'
and align == 'VIEW'):
view3d = context.space_data
region = view3d.region_3d
viewMatrix = region.view_matrix
rot = viewMatrix.rotation_part()
ob.rotation_euler = rot.invert().to_euler()
def createObject(context, verts, faces, name, edit):
'''Creates Meshes & Objects for the given lists of vertices and faces.'''
scene = context.scene
# Create new mesh
mesh = bpy.data.meshes.new(name)
# Add the geometry to the mesh.
#mesh.add_geometry(len(verts), 0, len(faces))
#mesh.verts.foreach_set("co", unpack_list(verts))
#mesh.faces.foreach_set("verts_raw", unpack_face_list(faces))
# To quote the documentation:
# "Make a mesh from a list of verts/edges/faces Until we have a nicer
# way to make geometry, use this."
# http://www.blender.org/documentation/250PythonDoc/
# bpy.types.Mesh.html#bpy.types.Mesh.from_pydata
mesh.from_pydata(verts, [], faces)
# Deselect all objects.
bpy.ops.object.select_all(action='DESELECT')
# Update mesh geometry after adding stuff.
mesh.update()
if edit:
# Recreate geometry of existing object
obj_act = context.active_object
ob_new = obj_act
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete(type='VERT')
bpy.ops.object.mode_set(mode='OBJECT')
ob_new.data = mesh
ob_new.selected = True
else:
# Create new object
ob_new = bpy.data.objects.new(name, mesh)
# Link new object to the given scene and select it.
scene.objects.link(ob_new)
ob_new.selected = True
# Place the object at the 3D cursor location.
ob_new.location = scene.cursor_location
obj_act = scene.objects.active
apply_view_rotation(context, ob_new)
if obj_act and obj_act.mode == 'EDIT':
if not edit:
# We are in EditMode, switch to ObjectMode.
bpy.ops.object.mode_set(mode='OBJECT')
# Select the active object as well.
obj_act.selected = True
# Apply location of new object.
scene.update()
# Join new object into the active.
bpy.ops.object.join()
# Switching back to EditMode.
bpy.ops.object.mode_set(mode='EDIT')
else:
# We are in ObjectMode.
# Make the new object the active one.
scene.objects.active = ob_new
return ob_new
def add_gem(r1, r2, seg, h1, h2): def add_gem(r1, r2, seg, h1, h2):
""" """
r1 = pavillion radius r1 = pavillion radius
...@@ -43,175 +151,110 @@ def add_gem(r1, r2, seg, h1, h2): ...@@ -43,175 +151,110 @@ def add_gem(r1, r2, seg, h1, h2):
Generates the vertices and faces of the gem Generates the vertices and faces of the gem
""" """
from math import cos, sin, pi from math import cos, sin, pi
verts = []
tot_verts = 2 + 4 * seg tot_verts = 2 + 4 * seg
tot_faces = 6 * seg tot_faces = 6 * seg
a = 2 * pi / seg # angle between segments a = 2 * pi / seg # angle between segments
offset = a / 2.0 # middle between segments offset = a / 2.0 # middle between segments
r3 = ((r1 + r2) / 2.0) / cos(offset) # middle of crown r3 = ((r1 + r2) / 2.0) / cos(offset) # middle of crown
r4 = (r1 / 2.0) / cos(offset) # middle of pavillion r4 = (r1 / 2.0) / cos(offset) # middle of pavillion
h3 = h2 / 2.0 # middle of crown height h3 = h2 / 2.0 # middle of crown height
h4 = -h1 / 2.0 # middle of pavillion height h4 = -h1 / 2.0 # middle of pavillion height
verts = [0, 0, -h1, 0, 0, h2]
verts.append((0, 0, -h1))
verts.append((0, 0, h2))
for i in range(seg): for i in range(seg):
s1 = sin(i * a) s1 = sin(i * a)
s2 = sin(offset + i * a) s2 = sin(offset + i * a)
c1 = cos(i * a) c1 = cos(i * a)
c2 = cos(offset + i * a) c2 = cos(offset + i * a)
verts.extend([ r4 * s1, r4 * c1, h4,r1 * s2, r1 * c2,0, verts.append((r4 * s1, r4 * c1, h4))
r3 * s1,r3 * c1, h3, r2 * s2, r2 * c2, h2 ]) verts.append((r1 * s2, r1 * c2, 0))
verts.append((r3 * s1, r3 * c1, h3))
verts.append((r2 * s2, r2 * c2, h2))
faces = [] faces = []
for index in range(seg): for index in range(seg):
i = index * 4 i = index * 4
j = ((index + 1) % seg) * 4 j = ((index + 1) % seg) * 4
faces.extend([0, j + 2, i + 3, i + 2]) faces.append([0, j + 2, i + 3, i + 2])
faces.extend([i + 3, j + 2, j +3, i + 3]) faces.append([i + 3, j + 2, j + 3, i + 3])
faces.extend([i + 3, j + 3, j +4, i + 3]) faces.append([i + 3, j + 3, j + 4, i + 3])
faces.extend([i + 3, j + 4, i +5, i + 4]) faces.append([i + 3, j + 4, i + 5, i + 4])
faces.extend([i + 5, j + 4, j +5, i + 5]) faces.append([i + 5, j + 4, j + 5, i + 5])
faces.extend([i + 5, j + 5, 1, i + 5]) faces.append([i + 5, j + 5, 1, i + 5])
return verts, faces, tot_verts, tot_faces return verts, faces, tot_verts, tot_faces
from bpy.props import IntProperty, FloatProperty, BoolProperty from bpy.props import IntProperty, FloatProperty, BoolProperty
class Parameter_Panel_Gem(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_context = "objectmode"
bl_label = "Gem parameters"
def poll(self, context):
# only show this panel if the object selected has propertie "Gem"
try:
return "Gem" in context.object
except TypeError:
return False
def draw(self,context):
layout = self.layout
layout.operator("Gem_Parameter_Edit", text="Edit")
class EditGem(bpy.types.Operator):
"""Reapply the operator"""
bl_idname = "Gem_Parameter_Edit"
bl_label = "Edit Gem"
def invoke(self, context, event):
# invoke the adding operator again,
# only this time with the Edit property = true
ob = context.active_object
bpy.ops.mesh.primitive_gem_add(edit=True,
segments=ob["Segments"],
pav_radius = ob["pav_radius"],
crown_radius = ob["tab_radius"],
crown_height = ob["tab_height"],
pav_height = ob["pav_height"])
return {'FINISHED'}
class AddGem(bpy.types.Operator): class AddGem(bpy.types.Operator):
"""Add a diamond gem""" """Add a diamond gem"""
bl_idname = "mesh.primitive_gem_add" bl_idname = "mesh.primitive_gem_add"
bl_label = "Add Gem" bl_label = "Add Gem"
bl_description = "Create an offset faceted gem." bl_description = "Create an offset faceted gem."
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
edit = BoolProperty(name="", description="",
default=False, options={'HIDDEN'}) # whether to add or update # edit - Whether to add or update.
segments = IntProperty(name="Segments", edit = BoolProperty(name="",
description="Longitudial segmentation", description="",
default=8, min=3, max=265) default=False,
options={'HIDDEN'})
segments = IntProperty(name="Segments",
description="Longitudial segmentation",
min=3,
max=265,
default=8,)
pav_radius = FloatProperty(name="Radius", pav_radius = FloatProperty(name="Radius",
description="Radius of the gem", description="Radius of the gem",
default=1.0, min=0.01, max=100.0) min=0.01,
max=100.0,
default=1.0)
crown_radius = FloatProperty(name="Table Radius", crown_radius = FloatProperty(name="Table Radius",
description="Radius of the table(top).", description="Radius of the table(top).",
default=0.6, min=0.01, max=100.0) min=0.01,
max=100.0,
default=0.6)
crown_height = FloatProperty(name="Table height", crown_height = FloatProperty(name="Table height",
description="Height of the top half.", description="Height of the top half.",
default=0.35, min=0.01, max=100.0) min=0.01,
max=100.0,
default=0.35)
pav_height = FloatProperty(name="Pavillion height", pav_height = FloatProperty(name="Pavillion height",
description="Height of bottom half.", description="Height of bottom half.",
default=0.8, min=0.01, max=100.0) min=0.01,
max=100.0,
default=0.8)
def execute(self, context): def execute(self, context):
props = self.properties
# create mesh # create mesh
verts, faces, nV, nF = add_gem(self.properties.pav_radius, verts, faces, nV, nF = add_gem(self.properties.pav_radius,
self.properties.crown_radius, props.crown_radius,
self.properties.segments, props.segments,
self.properties.pav_height, props.pav_height,
self.properties.crown_height) props.crown_height)
mesh = bpy.data.meshes.new("Gem") obj = createObject(context, verts, faces, "Gem", props.edit)
mesh.add_geometry(nV, 0, nF)
mesh.verts.foreach_set("co", verts) # Store 'recall' properties in the object.
mesh.faces.foreach_set("verts_raw", faces) recall_prop_list = {
mesh.update() "edit": True,
if self.properties.edit: "segments": props.segments,
# only update "pav_radius": props.pav_radius,
ob_new = context.active_object "crown_radius": props.crown_radius,
bpy.ops.object.mode_set(mode='EDIT') "pav_height": props.pav_height,
bpy.ops.mesh.select_all(action='SELECT') "crown_height": props.crown_height}
bpy.ops.mesh.delete(type='VERT') obj_store_recall_properties(obj, self, recall_prop_list)
bpy.ops.object.mode_set(mode='OBJECT')
ob_new.data = mesh
scene = context.scene
# ugh
for ob in scene.objects:
ob.selected = False
ob_new.selected = True
scene.objects.active = ob_new
bpy.ops.object.shade_flat()
else:
# create new object
scene = context.scene
# ugh
for ob in scene.objects:
ob.selected = False
ob_new = bpy.data.objects.new("Gem", mesh)
ob_new.data = mesh
scene.objects.link(ob_new)
ob_new.selected = True
ob_new.location = scene.cursor_location
obj_act = scene.objects.active
if obj_act and obj_act.mode == 'EDIT':
# if the mesh is added in edit mode, add the mesh to the
# excisting mesh
bpy.ops.object.mode_set(mode='OBJECT')
obj_act.selected = True
scene.update() # apply location
bpy.ops.object.join() # join into the active.
bpy.ops.object.mode_set(mode='EDIT')
else:
# add new object and make faces flat
scene.objects.active = ob_new
bpy.ops.object.shade_flat()
if context.user_preferences.edit.enter_edit_mode:
bpy.ops.object.mode_set(mode='EDIT')
# add custom properties to the object to make the edit parameters
# thingy work
ob_new["Gem"] = 1
ob_new["Segments"] = self.properties.segments
ob_new["pav_radius"] = self.properties.pav_radius
ob_new["tab_radius"] = self.properties.crown_radius
ob_new["pav_height"] = self.properties.pav_height
ob_new["tab_height"] = self.properties.crown_height
return {'FINISHED'} return {'FINISHED'}
# register all operators and panels # register all operators and panels
...@@ -223,15 +266,11 @@ menu_func = (lambda self, context: self.layout.operator(AddGem.bl_idname, ...@@ -223,15 +266,11 @@ menu_func = (lambda self, context: self.layout.operator(AddGem.bl_idname,
def register(): def register():
bpy.types.register(AddGem) bpy.types.register(AddGem)
bpy.types.register(Parameter_Panel_Gem)
bpy.types.register(EditGem)
bpy.types.INFO_MT_mesh_add.append(menu_func) bpy.types.INFO_MT_mesh_add.append(menu_func)
def unregister(): def unregister():
bpy.types.unregister(AddGem) bpy.types.unregister(AddGem)
bpy.types.unregister(Parameter_Panel_Gem)
bpy.types.unregister(EditGem)
bpy.types.INFO_MT_mesh_add.remove(menu_func) bpy.types.INFO_MT_mesh_add.remove(menu_func)
# Remove "Gem" menu from the "Add Mesh" menu. # Remove "Gem" menu from the "Add Mesh" menu.
#space_info.INFO_MT_mesh_add.remove(menu_func) #space_info.INFO_MT_mesh_add.remove(menu_func)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment