Version (0, 3, 4)

Fixed the default values to match the default preset. This also fixed the default Cap Head size.
Added "Align to View", "Location" and "Rotation" properties.
Now adds the mesh the same way as the Template example.  This fixes some of the problems when using this script with 2.8.
This commit is contained in:
Aaron Keith 2018-06-22 13:29:54 +12:00
parent 3a13cb7edb
commit e578b0f187
3 changed files with 65 additions and 153 deletions

View File

@ -20,44 +20,29 @@
import bpy
from mathutils import Matrix
from bpy.types import Operator
from bpy_extras.object_utils import AddObjectHelper
from bpy.props import (
BoolProperty,
EnumProperty,
FloatProperty,
IntProperty,
FloatVectorProperty,
)
from . import createMesh
# ------------------------------------------------------------
# calculates the matrix for the new object depending on user pref
def align_matrix(context):
loc = Matrix.Translation(context.scene.cursor_location)
obj_align = context.user_preferences.edit.object_align
if (context.space_data.type == 'VIEW_3D' and obj_align == 'VIEW'):
rot = context.space_data.region_3d.view_matrix.to_3x3().inverted().to_4x4()
else:
rot = Matrix()
align_matrix = loc * rot
return align_matrix
class add_mesh_bolt(Operator):
class add_mesh_bolt(Operator, AddObjectHelper):
bl_idname = "mesh.bolt_add"
bl_label = "Add Bolt"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
bl_description = "Construct many types of Bolts"
align_matrix = Matrix()
MAX_INPUT_NUMBER = 50
# edit - Whether to add or update
edit = BoolProperty(
name="",
description="",
default=False,
options={'HIDDEN'}
)
# Model Types
Model_Type_List = [('bf_Model_Bolt', 'BOLT', 'Bolt Model'),
('bf_Model_Nut', 'NUT', 'Nut Model')]
@ -148,35 +133,35 @@ class add_mesh_bolt(Operator):
)
bf_CounterSink_Head_Dia = FloatProperty(
attr='bf_CounterSink_Head_Dia',
name='Head Dia', default=5.5,
name='Head Dia', default=6.300000190734863,
min=0, soft_min=0,
max=MAX_INPUT_NUMBER,
description='Diameter of the Counter Sink Head'
)
bf_Cap_Head_Height = FloatProperty(
attr='bf_Cap_Head_Height',
name='Head Height', default=5.5,
name='Head Height', default=3,
min=0, soft_min=0,
max=MAX_INPUT_NUMBER,
description='Height of the Cap Head'
)
bf_Cap_Head_Dia = FloatProperty(
attr='bf_Cap_Head_Dia',
name='Head Dia', default=3,
name='Head Dia', default=5.5,
min=0, soft_min=0,
max=MAX_INPUT_NUMBER,
description='Diameter of the Cap Head'
)
bf_Dome_Head_Dia = FloatProperty(
attr='bf_Dome_Head_Dia',
name='Dome Head Dia', default=5.6,
name='Dome Head Dia', default=5.599999904632568,
min=0, soft_min=0,
max=MAX_INPUT_NUMBER,
description='Length of the unthreaded shank'
)
bf_Pan_Head_Dia = FloatProperty(
attr='bf_Pan_Head_Dia',
name='Pan Head Dia', default=5.6,
name='Pan Head Dia', default=5.599999904632568,
min=0, soft_min=0,
max=MAX_INPUT_NUMBER,
description='Diameter of the Pan Head')
@ -204,7 +189,7 @@ class add_mesh_bolt(Operator):
bf_Pitch = FloatProperty(
attr='bf_Pitch',
name='Pitch', default=0.35,
name='Pitch', default=0.3499999940395355,
min=0.1, soft_min=0.1,
max=7.0,
description='Pitch if the thread'
@ -239,7 +224,7 @@ class add_mesh_bolt(Operator):
)
bf_Hex_Nut_Height = FloatProperty(
attr='bf_Hex_Nut_Height',
name='Hex Nut Height', default=2.4,
name='Hex Nut Height', default=2.4000000953674316,
min=0, soft_min=0,
max=MAX_INPUT_NUMBER,
description='Height of the Hex Nut'
@ -251,6 +236,23 @@ class add_mesh_bolt(Operator):
max=MAX_INPUT_NUMBER,
description='Flat distance of the Hex Nut'
)
# generic transform props
view_align = BoolProperty(
name="Align to View",
default=False,
update=AddObjectHelper.view_align_update_callback,
)
location = FloatVectorProperty(
name="Location",
subtype='TRANSLATION',
)
rotation = FloatVectorProperty(
name="Rotation",
subtype='EULER',
)
def draw(self, context):
layout = self.layout
@ -309,18 +311,22 @@ class add_mesh_bolt(Operator):
col.prop(self, 'bf_Crest_Percent')
col.prop(self, 'bf_Root_Percent')
col.prop(self, 'bf_Div_Count')
# generic transform props
col.separator()
col.prop(self, 'view_align')
col.prop(self, 'location')
col.prop(self, 'rotation')
@classmethod
def poll(cls, context):
return context.scene is not None
def execute(self, context):
createMesh.Create_New_Mesh(self, context, self.align_matrix)
createMesh.Create_New_Mesh(self, context)
return {'FINISHED'}
def invoke(self, context, event):
# store creation_matrix
self.align_matrix = align_matrix(context)
self.execute(context)
return {'FINISHED'}

View File

@ -19,7 +19,7 @@
bl_info = {
"name": "BoltFactory",
"author": "Aaron Keith",
"version": (0, 3, 3),
"version": (0, 3, 4),
"blender": (2, 78, 0),
"location": "View3D > Add > Mesh",
"description": "Add a bolt or nut",

View File

@ -26,6 +26,7 @@ from math import (
tan, radians,
)
from random import triangular
from bpy_extras.object_utils import AddObjectHelper, object_data_add
NARROW_UI = 180
MAX_INPUT_NUMBER = 50
@ -69,7 +70,7 @@ Remove Doubles takes a list on Verts and a list of Faces and
removes the doubles, much like Blender does in edit mode.
It doesnt have the range function but it will round the corrdinates
and remove verts that are very close togther. The function
is useful because you can perform a Remove Doubles with out
is useful because you can perform a "Remove Doubles" with out
having to enter Edit Mode. Having to enter edit mode has the
disadvantage of not being able to interactively change the properties.
"""
@ -1964,39 +1965,37 @@ def Bolt_Mesh(props, context):
return Move_Verts_Up_Z(verts, Thread_Height), faces
# calculates the matrix for the new object
# depending on user pref
def align_matrix(context):
loc = Matrix.Translation(context.scene.cursor_location)
obj_align = context.user_preferences.edit.object_align
if (context.space_data.type == 'VIEW_3D' and obj_align == 'VIEW'):
rot = context.space_data.region_3d.view_matrix.to_3x3().inverted().to_4x4()
else:
rot = Matrix()
align_matrix = loc * rot
return align_matrix
# 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).
# edit ... Replace existing mesh data.
# Note: Using "edit" will destroy/delete existing mesh data.
def create_mesh_object(context, verts, edges, faces, name, edit, align_matrix):
scene = context.scene
obj_act = scene.objects.active
# Can't edit anything, unless we have an active obj.
if edit and not obj_act:
return None
# Create new mesh
mesh = bpy.data.meshes.new(name)
# Make a mesh from a list of verts/edges/faces.
def Create_New_Mesh(props, context):
verts = []
faces = []
edges = []
sObjName = ''
if props.bf_Model_Type == 'bf_Model_Bolt':
# print('Create Bolt')
verts, faces = Bolt_Mesh(props, context)
sObjName = 'Bolt'
if props.bf_Model_Type == 'bf_Model_Nut':
# print('Create Nut')
verts, faces = Nut_Mesh(props, context)
sObjName = 'Nut'
verts, faces = RemoveDoubles(verts, faces)
verts = Scale_Mesh_Verts(verts, GLOBAL_SCALE)
mesh = bpy.data.meshes.new(name=sObjName)
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# Fix T51338 : Validate the mesh (the internal thread generator for the Nut
# should be more reliable now, however there could be other possible errors)
is_not_mesh_valid = mesh.validate()
@ -2004,100 +2003,7 @@ def create_mesh_object(context, verts, edges, faces, name, edit, align_matrix):
if is_not_mesh_valid:
print("\n[BoltFactory]\nFunction: create_mesh_object\n"
"Mesh is not Valid, correcting\n")
# Update mesh geometry after adding stuff.
mesh.update()
# Deselect all objects when in object mode
if bpy.ops.object.select_all.poll():
bpy.ops.object.select_all(action='DESELECT')
if edit:
# Replace geometry of existing object
# Use the active obj and select it.
ob_new = obj_act
ob_new.select = True
if obj_act.mode == 'OBJECT':
# Get existing mesh datablock.
old_mesh = ob_new.data
# Set object data to nothing
ob_new.data = None
# Clear users of existing mesh datablock.
old_mesh.user_clear()
# Remove old mesh datablock if no users are left.
if (old_mesh.users == 0):
bpy.data.meshes.remove(old_mesh)
# Assign new mesh datablock.
ob_new.data = mesh
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.select = True
# Place the object at the 3D cursor location.
# apply viewRotaion
ob_new.matrix_world = align_matrix
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.select = 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')
ob_new = obj_act
else:
# We are in ObjectMode.
# Make the new object the active one.
scene.objects.active = ob_new
return ob_new
object_data_add(context, mesh, operator=props)
def Create_New_Mesh(props, context, align_matrix):
verts = []
faces = []
# sMeshName ='' # UNUSED
sObjName = ''
if props.bf_Model_Type == 'bf_Model_Bolt':
# print('Create Bolt')
verts, faces = Bolt_Mesh(props, context)
# sMeshName = 'Bolt' # UNUSED
sObjName = 'Bolt'
if props.bf_Model_Type == 'bf_Model_Nut':
# print('Create Nut')
verts, faces = Nut_Mesh(props, context)
# sMeshName = 'Nut' # UNUSED
sObjName = 'Nut'
verts, faces = RemoveDoubles(verts, faces)
verts = Scale_Mesh_Verts(verts, GLOBAL_SCALE)
obj = create_mesh_object(context, verts, [], faces, sObjName,
props.edit, align_matrix)
return obj