[Bf-committers] Translate to 2.57

Yuniel Castro González ycastrog at estudiantes.uci.cu
Sat Apr 30 15:45:53 CEST 2011


Hi.
I need to translate them to later upload script in blender 2.57.
Thanks in advance. 


****************************************************************

import bpy
import time
from math import *

mball_definition = 2
mball_wire_resolution = 0.1

bpy.types.Scene.FloatProperty(attr = "ASKETCH_stroke_size", name = "Size", description = "Size of the stroke", default = 0.5, min = 0, max = 10)
bpy.types.Scene.FloatProperty(attr = "ASKETCH_stroke_central_size", name = "Fatten", description = "Fatten / Shrink towards the middle of the stroke", default = 3, min = 0, max = 10)
bpy.types.Scene.FloatProperty(attr = "ASKETCH_stroke_elements_offset", name = "Offset", description = "Distance between elements of the stroke", default = 1, min = 0, max = 2)
bpy.types.Scene.BoolProperty(attr = "ASKETCH_mirror_x_on", name = "Mirror X", description = "Mirror on X axis", default = True)
bpy.types.Scene.StringProperty(attr = "ASKETCH_brush_object", name = "Brush", description = "Name of the object used as brush", default = "A_SK_brush_default")

default_brush_name = "A_SK_brush_default"

def ASKETCH_default_brush_object(self): return default_brush_name
bpy.types.Object.ASKETCH_default_brush_object = property(ASKETCH_default_brush_object)

def ASKETCH_brush_object(self): return default_brush_name
bpy.types.Object.ASKETCH_brush_object = property(ASKETCH_brush_object)

def ASKETCH_mball_stroke_definition(self): return mball_definition
bpy.types.Object.ASKETCH_mball_stroke_definition = property(ASKETCH_mball_stroke_definition)

def ASKETCH_mball_wire_resolution(self): return mball_wire_resolution
bpy.types.Object.ASKETCH_mball_wire_resolution = property(ASKETCH_mball_wire_resolution)

class View3DPanel(bpy.types.Panel):
	bl_space_type = 'VIEW_3D'
	bl_region_type = 'TOOLS'
	
class VIEW3D_PT_tools_ASKETCH(View3DPanel):
	bl_context = "objectmode"
	bl_label = "Arrays Sketching"
	
	def poll(self, context):
		return context.active_object

	def draw(self, context):
		layout = self.layout
		
		scn = context.scene
		ob = context.object
		
		col = layout.column(align=True)
		row = layout.row()
		row.separator()
		col.operator("OBJECT_OT_ASKETCH_stroke_editmode", text="Stroke Edit Mode")
		row.separator()
		col.separator()
		col.label(text="Stroke")
		col.prop(scn, "ASKETCH_mirror_x_on")
		col.operator("GPENCIL_OT_ASKETCH_stroke_draw", text="Add")
		col.prop(scn, "ASKETCH_stroke_size", slider = True)
		col.prop(scn, "ASKETCH_stroke_central_size", slider = True)
		col.prop(scn, "ASKETCH_stroke_elements_offset", slider = True)
		row.separator()
		col.operator("OBJECT_OT_ASKETCH_delete_strokes", text="Delete")
		row.separator()
		col.separator()
		col.label(text="Toggle Visibility")
		col.operator("OBJECT_OT_ASKETCH_toggle_mesh_visibility", text="Strokes / Mesh")
		row.separator()
		col.separator()
		col.label(text="Convert to Mesh")
		col.operator("OBJECT_OT_ASKETCH_strokes_to_metaballs", text="Step 1 (few minutes...)")
		col.operator("OBJECT_OT_ASKETCH_metaballs_rename", text="Step 2")
		col.operator("OBJECT_OT_ASKETCH_metaballs_to_mesh", text="Step 3 (few minutes...)")
		row.separator()
		col.separator()
		row.separator()
		col.label(text="")
		col.operator("OBJECT_OT_ASKETCH_set_brush_object", text="Pick Brush")
		col.label(text = bpy.context.scene.ASKETCH_brush_object)

class VIEW3D_PT_tools_ASKETCH_editmode(View3DPanel):
	bl_context = "curve_edit"
	bl_label = "Arrays Sketching"
	
	def poll(self, context):
		return context.active_object

	def draw(self, context):
		layout = self.layout
		
		ob = context.object
		
		col = layout.column(align=True)
		col.operator("OBJECT_OT_ASKETCH_stroke_editmode_exit", text="Stroke Object Mode")
		col.separator()
		col.label(text="Stroke tools")
		col.operator("OBJECT_OT_ASKETCH_stroke_smooth_size", text="Smooth size")

# Draw the Stroke
class GPENCIL_OT_ASKETCH_stroke_draw(bpy.types.Operator):
	bl_idname = "GPENCIL_OT_ASKETCH_stroke_draw"
	bl_label = "Array Sketch Stroke Draw"
	
	#stroke_size = bpy.props.FloatProperty(name="Stroke Size", description="Size of the stroke", default = stroke_size)
	#stroke_central_size = bpy.props.FloatProperty(name="Stroke Central Size", description="Size of the middle of the stroke", default = stroke_central_size)
	#stroke_elements_offset = bpy.props.FloatProperty(name="Stroke Elements Distance", description="Distance between elements of the stroke", default = stroke_elements_offset)
	
	def set_stroke_radius(self, curve):
		points = bpy.data.curves[curve.name].splines[0].bezier_points
		central_point = int(len(points)/2)
		
		bpy.ops.curve.select_all(action="DESELECT") 
		bpy.ops.curve.de_select_first()
		bpy.ops.curve.de_select_last()
		bpy.ops.curve.radius_set(radius = self.stroke_size)
		
		bpy.ops.curve.select_all(action="DESELECT")
		bpy.ops.curve.de_select_first()
		bpy.ops.curve.select_every_nth(n=central_point)
		bpy.ops.curve.de_select_first()
		if (int(len(points)/2) != len(points)/2):
			bpy.ops.curve.de_select_last()
		
		bpy.ops.curve.radius_set(radius = self.stroke_size * self.stroke_central_size)
		
		bpy.ops.curve.select_all(action="INVERT")
		bpy.ops.curve.de_select_first()
		bpy.ops.curve.de_select_last()
		bpy.ops.curve.smooth_radius()
		bpy.ops.curve.select_all(action="DESELECT")
		
		

	def append_stroke_number(self, partial_name):
		n = 1
		while True:
			name_stroke_obj = partial_name + ".SKS" + str(n)
			name_stroke_curve = partial_name + ".SKD" + str(n)
			
			if (not name_stroke_obj in bpy.data.objects and not name_stroke_curve in bpy.data.objects):
				break
			n += 1
		
		return name_stroke_curve
	
	
	def execute(self, context):
		#### Convert grease pencil to Curve
		bpy.ops.gpencil.convert(type='CURVE')
		curve_obj = bpy.context.object
		
		bpy.ops.object.editmode_toggle()
		
		bpy.ops.curve.select_all(action="SELECT")
		bpy.ops.curve.radius_set(radius=1)
		
		curve_crv = bpy.context.object.data
		bpy.ops.curve.spline_type_set(type="BEZIER")
		bpy.ops.curve.handle_type_set(type="AUTOMATIC")
		bpy.data.curves[curve_crv.name].use_stretch = True
		bpy.data.curves[curve_crv.name].draw_handles = False
		bpy.data.curves[curve_crv.name].draw_normals = False
		bpy.data.curves[curve_crv.name].use_path = True
		bpy.ops.curve.smooth()
		bpy.ops.curve.smooth()
		bpy.ops.curve.smooth()
		bpy.ops.curve.smooth()
		bpy.ops.curve.smooth()
		bpy.ops.curve.smooth()
		
		stroke_curve_obj = bpy.context.active_object
		stroke_curve_crv = bpy.context.active_object.data
		
		
		#### Set curve name.
		if self.is_default_brush:
			stroke_curve_obj.name = self.append_stroke_number(self.main_object.name)
		else:
			stroke_curve_obj.name = self.append_stroke_number("A_SK_ARRAY")
		
		
		#### Inflate stroke.
		self.set_stroke_radius(stroke_curve_crv)
		bpy.ops.object.editmode_toggle()
		
		
		### Set curve's interpolation to "Cardinal"
		stroke_curve_obj.data.splines[0].radius_interpolation = "CARDINAL"
		
		
		#### Set Curve's origin to the position of the main object's origin.
		cursor_loc = bpy.data.scenes[bpy.context.scene.name].cursor_location
		previous_cursor_loc = [cursor_loc[0], cursor_loc[1], cursor_loc[2]]
		
		bpy.ops.object.select_name(name = stroke_curve_obj.name)
		bpy.context.scene.objects.active = bpy.context.scene.objects[stroke_curve_obj.name]
		
		bpy.data.scenes[bpy.context.scene.name].cursor_location = self.main_object.location
		bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
		
		bpy.data.scenes[bpy.context.scene.name].cursor_location = previous_cursor_loc
		
		
		#### Add brush object to be repeated along the curve.
		bpy.ops.object.select_name(name = self.brush_object.name)
		bpy.context.scene.objects.active = bpy.context.scene.objects[self.brush_object.name]
		bpy.ops.object.duplicate_move()
		bpy.context.object.location = stroke_curve_obj.location
		
		stroke_brush_obj = bpy.context.object
		stroke_brush_obj.name = stroke_curve_obj.name.replace(".SKD", ".SKS", 2)

		
		#### Add Array modifier to the brush-object and make it follow the curve.
		bpy.ops.object.modifier_add(type='ARRAY')
		stroke_brush_obj.modifiers["Array"].relative_offset_displacement = [self.stroke_elements_offset, 0, 0]
		stroke_brush_obj.modifiers["Array"].fit_type = "FIT_CURVE"
		stroke_brush_obj.modifiers["Array"].curve = stroke_curve_obj
		
		if self.brush_object.name + "_a" in bpy.data.objects:
			stroke_brush_obj.modifiers["Array"].end_cap = bpy.data.objects[self.brush_object.name + "_a"]
		
		if self.brush_object.name + "_b" in bpy.data.objects:
			stroke_brush_obj.modifiers["Array"].start_cap = bpy.data.objects[self.brush_object.name + "_b"]
		elif self.brush_object.name + "_a" in bpy.data.objects:
			stroke_brush_obj.modifiers["Array"].start_cap = bpy.data.objects[self.brush_object.name + "_a"]
			
		bpy.ops.object.modifier_add(type='CURVE')
		stroke_brush_obj.modifiers["Curve"].object = stroke_curve_obj
		
		
		#### Add Mirror modifier
		if self.mirror_x_on:
			bpy.ops.object.modifier_add(type='MIRROR')
			stroke_brush_obj.modifiers["Mirror"].mirror_object = self.main_object
		
		
		#### Make stroke elements children of main object.
		bpy.data.objects[stroke_curve_obj.name].parent = self.main_object
		bpy.data.objects[stroke_brush_obj.name].parent = self.main_object
		
		bpy.ops.object.select_name(name = stroke_curve_obj.name)
		bpy.context.scene.objects.active = bpy.context.scene.objects[stroke_curve_obj.name]
		bpy.ops.object.location_clear()
		
		bpy.ops.object.select_name(name = stroke_brush_obj.name)
		bpy.context.scene.objects.active = bpy.context.scene.objects[stroke_brush_obj.name]
		bpy.ops.object.location_clear()

		
		#### Lock movement of the stroke's object and curve.
		bpy.data.objects[stroke_brush_obj.name].lock_location[0] = True
		bpy.data.objects[stroke_brush_obj.name].lock_location[1] = True
		bpy.data.objects[stroke_brush_obj.name].lock_location[2] = True
		
		bpy.data.objects[stroke_curve_obj.name].lock_location[0] = True
		bpy.data.objects[stroke_curve_obj.name].lock_location[1] = True
		bpy.data.objects[stroke_curve_obj.name].lock_location[2] = True
		
		
		#### Set main object as active.
		bpy.ops.object.select_name(name = self.main_object.name)
		bpy.context.scene.objects.active = self.main_object
		
		
		#### Delete the last grease pencil stroke done.
		bpy.ops.gpencil.active_frame_delete()
		
		
	def invoke(self, context, event):
		self.main_object = bpy.context.object
		self.brush_object = bpy.context.scene.objects[bpy.context.scene.ASKETCH_brush_object]
		self.mirror_x_on = bpy.context.scene.ASKETCH_mirror_x_on
		
		self.stroke_size = bpy.context.scene.ASKETCH_stroke_size
		self.stroke_central_size = bpy.context.scene.ASKETCH_stroke_central_size
		self.stroke_elements_offset = bpy.context.scene.ASKETCH_stroke_elements_offset
		
		
		# Check if the brush is the default one (spheres) or a custom one (arrays).
		if (bpy.context.scene.ASKETCH_brush_object == bpy.context.object.ASKETCH_default_brush_object):
			self.is_default_brush = True
		else:
			self.is_default_brush = False
			
		if (bpy.context.object.name.find("SKS") == -1 and bpy.context.object.name.find("SKD") == -1):
			self.execute(context)
		
		
		return {"FINISHED"}


# Enter "Stroke-Editmode"
class OBJECT_OT_ASKETCH_stroke_editmode(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_stroke_editmode"
	bl_label = "Array Sketch Stroke Editmode"
	
	
	def execute(self, context):
		stroke_obj_name = bpy.context.object.name
		
		if (stroke_obj_name.find(".SKS") != -1):
			name_to_query = bpy.context.object.name.replace(".SKS", ".SKD")
			
			if bpy.context.scene.objects[name_to_query]:
				bpy.ops.object.select_name(name = name_to_query)
				bpy.context.scene.objects.active = bpy.context.scene.objects[name_to_query]
				bpy.ops.object.editmode_toggle()
		
	
	def invoke (self, context, event):
		self.execute(context)
		
		return {"FINISHED"}


# Exit "Stroke-Editmode"
class OBJECT_OT_ASKETCH_stroke_editmode_exit(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_stroke_editmode_exit"
	bl_label = "Array Sketch Stroke Exit Editmode"
	
	
	def execute(self, context):
		bpy.ops.object.editmode_toggle()
		
		#splitted_name = bpy.context.object.name.split(".SKD")
		#main_object_name = splitted_name[0]
		main_object_name = bpy.context.object.parent.name
		
		if bpy.context.scene.objects[main_object_name]:
			bpy.ops.object.select_name(name = main_object_name)
			bpy.context.scene.objects.active = bpy.context.scene.objects[main_object_name]
	
	
	def invoke (self, context, event):
		self.execute(context)
		
		return {"FINISHED"}


# Toggle "Stroke-Editmode"
class GPENCIL_OT_ASKETCH_stroke_editmode_toggle(bpy.types.Operator):
	bl_idname = "GPENCIL_OT_ASKETCH_stroke_editmode_toggle"
	bl_label = "Array Sketch Stroke Editmode Toggle"
	
	
	def execute(self, context):
		if self.stroke_obj.name.find(".SKS") != -1:
			deformer_curve_name = self.stroke_obj.name.replace(".SKS", ".SKD")
			
			if deformer_curve_name in bpy.data.objects:
				curve = bpy.data.objects[deformer_curve_name]
				#curve.data.restrict_view = False
				
				bpy.ops.object.select_name(name = deformer_curve_name)
				bpy.context.scene.objects.active = bpy.context.scene.objects[deformer_curve_name]
				bpy.ops.object.editmode_toggle()
		elif self.stroke_obj.name.find(".SKD") != -1:
			if bpy.context.edit_object == self.stroke_obj:
				bpy.ops.object.editmode_toggle()
			
			#bpy.data.objects[self.stroke_obj.name].restrict_view = True
			
			#splitted_name = bpy.context.object.name.split(".SKD")
			#main_object_name = splitted_name[0]
			main_object_name = bpy.context.object.parent.name
			
			if main_object_name in bpy.data.objects:
				bpy.ops.object.select_name(name = main_object_name)
				bpy.context.scene.objects.active = bpy.context.scene.objects[main_object_name]
			
	
	def invoke (self, context, event):
		self.stroke_obj = bpy.context.object
		self.execute(context)
		
		return {"FINISHED"}
		
		
# Set brush object
class OBJECT_OT_ASKETCH_set_brush_object(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_set_brush_object"
	bl_label = "Array Sketch Set Brush Object"
	
	
	def execute(self, context):
		bpy.context.scene.ASKETCH_brush_object = bpy.context.active_object.name
		
		
	def invoke (self, context, event):
		self.execute(context)
		
		return {"FINISHED"}



# Delete selected strokes (or last grease pencil stroke)
class OBJECT_OT_ASKETCH_delete_strokes(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_delete_strokes"
	bl_label = "Array Sketch Delete Strokes"
	
	def object_type(self, obj):
		if (obj.name.find(".SKS") != -1):
			obj_type = "stroke_object"
		elif (obj.name.find(".SKD") != -1):
			obj_type = "stroke_curve"
		else:
			obj_type = "main_object"
		
		return obj_type
	
	
	def delete_stroke(self, stroke_object):
		if (stroke_object.grease_pencil):
			if (stroke_object.grease_pencil.layers[0]):
				gp_layers = stroke_object.grease_pencil.layers
				l = None
				for l in gp_layers:
					if l.active:
						break
				
				if (l.active_frame):
					if (len(l.active_frame.strokes) > 0):
						bpy.ops.gpencil.active_frame_delete()
					
		
		if (self.object_type(stroke_object) == "stroke_object"):
			stroke_object_name = stroke_object.name
			stroke_curve_name = stroke_object_name.replace(".SKS", ".SKD")
			
			bpy.ops.object.select_name(name = stroke_curve_name)
			bpy.ops.object.select_name(name = stroke_object_name, extend=True)
			bpy.context.scene.objects.active = bpy.data.objects[stroke_object_name]
			bpy.ops.object.delete()
			
	
	def execute(self, context):
		if (bpy.context.object.parent != None):
			main_object_name = bpy.context.object.parent.name
		
		# Get selected objects
		strokes_to_delete = []
		for stroke in bpy.context.selected_objects:
			strokes_to_delete.append(stroke)
		
		for stroke in strokes_to_delete:
			bpy.ops.object.select_name(name = stroke.name)
			bpy.context.scene.objects.active = bpy.data.objects[stroke.name]
			
			self.delete_stroke(stroke)
		
		#splitted_name = strokes_to_delete[0].name.split(".SKS")
		#main_object_name = splitted_name[0]
		
		if main_object_name in bpy.data.objects:
			bpy.ops.object.select_name(name = main_object_name)
			bpy.context.scene.objects.active = bpy.data.objects[main_object_name]
		
		
	def invoke (self, context, event):
		self.execute(context)
		
		return {"FINISHED"}


# Smooth Curve Radius using control points
class OBJECT_OT_ASKETCH_stroke_smooth_size(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_stroke_smooth_size"
	bl_label = "Array Sketch Smooth Stroke Size"
	
	
	def execute(self, context):
		bpy.ops.curve.select_all(action="INVERT")
		bpy.ops.curve.smooth_radius()
		bpy.ops.curve.select_all(action="INVERT")

		
	def invoke (self, context, event):
		self.execute(context)
		
		return {"FINISHED"}


# Convert strokes to metaballs.
class OBJECT_OT_ASKETCH_strokes_to_metaballs(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_strokes_to_metaballs"
	bl_label = "Array Sketch Stroke To Metaballs"
	
	def create_metaball(self, point, mball_radius, mball_name):
			bpy.ops.object.metaball_add(type='MBALL_BALL', view_align=False, enter_editmode=False, location=(point.co), rotation=(0, 0, 0))
			mball_object = bpy.context.object
			mball_object.name = mball_name
			
			#bpy.data.objects[mball_object.name].parent = self.main_object
			bpy.data.objects[mball_object.name].location += self.main_object.location
			
			mball = bpy.data.metaballs[mball_object.data.name]
			mball.wire_size = 1
			mball.elements[0].radius = mball_radius * 2
			mball.elements[0].stiffness = self.mballs_stiffness
			
			return mball_object
	
	def execute(self, context):
		#### Be sure that all strokes and their curves are visible
		for obj in bpy.data.objects:
			if (obj.name.find(self.main_object.name + ".SKS") != -1 or obj.name.find(self.main_object.name + ".SKD") != -1):
				bpy.data.objects[obj.name].restrict_view = False
		
		
		#### If there was a baked mesh, delete it.
		baked_mesh_name = self.main_object.name + ".SKME"
		
		if baked_mesh_name in bpy.data.objects:
			bpy.data.objects[baked_mesh_name].restrict_view = False
			
			bpy.ops.object.select_name(name = baked_mesh_name)
			bpy.context.scene.objects.active = bpy.data.objects[baked_mesh_name]
			
			bpy.ops.object.delete()
			
			bpy.ops.object.select_name(name = self.main_object.name)
			bpy.context.scene.objects.active = bpy.data.objects[self.main_object.name]
		
		
		bpy.ops.object.select_name(name = self.main_object.name)
		bpy.context.scene.objects.active = self.main_object
		
		
		#### Get all curves that will be converted to metaballs, and duplicate and mirror the ones that should be mirrored.
		all_strokes_curves = []
		for obj in bpy.data.objects:
			if obj.name.find(self.main_object.name + ".SKD") != -1:
				mirrored_curve = False
				stroke_brush_name = obj.name.replace(".SKD", ".SKS")
				for mod in bpy.data.objects[stroke_brush_name].modifiers:
					if mod.type == "MIRROR" and mod.x == True:
						mirrored_curve = True
									
				bpy.ops.object.select_name(name = obj.name)
				bpy.context.scene.objects.active = bpy.data.objects[obj.name]
				
				bpy.ops.object.duplicate_move()
				bpy.ops.object.editmode_toggle()
				bpy.ops.curve.select_all(action='SELECT')
				bpy.ops.curve.subdivide()
				bpy.ops.curve.subdivide()
				bpy.ops.object.editmode_toggle()
				
				bpy.context.object.name = "A_SK_TEMP_CURVE"
				
				# Append the first duplicate.
				all_strokes_curves.append(bpy.context.object)
				
				if mirrored_curve:
					bpy.ops.object.duplicate_move()
					bpy.ops.transform.mirror(proportional='DISABLED', proportional_editing_falloff='SMOOTH', proportional_size=1, constraint_axis=(True, False, False), constraint_orientation='GLOBAL')
					bpy.ops.object.scale_apply()
					
					bpy.context.object.name = "A_SK_TEMP_CURVE"
					
					# Append the mirrored duplicate
					all_strokes_curves.append(bpy.context.object)
				
				
		#### Create the Metaball object for each curve and set its properties.
		strokes_total_time = 0
		curves_count = 1
		mballs_num = 1
		all_mballs = []
		for curve_obj in all_strokes_curves:
			bpy.ops.object.select_name(name = curve_obj.name)
			bpy.context.scene.objects.active = bpy.data.objects[curve_obj.name]
			
			pts = bpy.data.objects[curve_obj.name].data.splines[0].bezier_points
			
			
			mballs_count = 0
			mballs_start_time = time.time()
			first_pt = True
			for p in pts:
				# Radius of the metaball not less than the minimum wire resolution
				if p.radius < self.stroke_wire_resolution:
					mball_radius = self.ball_brush_size / 2 * self.mballs_size_compensation * self.stroke_wire_resolution
				else:
					mball_radius = self.ball_brush_size / 2 * self.mballs_size_compensation * p.radius
				
				
				new_mball_created = False
				if first_pt:
					mball_object = self.create_metaball(p, mball_radius, self.final_mesh_name + str(mballs_num))
					
					new_mball_created = True
					
					first_pt = False
				else:
					prev_mball = bpy.data.metaballs[prev_mball_object.data.name]
					prev_pt_loc = prev_pt.co
					
					pts_difs = [prev_pt_loc[0] - p.co[0], prev_pt_loc[1] - p.co[1], prev_pt_loc[2] - p.co[2]]
					pts_distance = abs(sqrt(pts_difs[0] * pts_difs[0] + pts_difs[1] * pts_difs[1] + pts_difs[2] * pts_difs[2]))
					
					# Checks if the distance between the previous point with a metaball and the actual point is long enough to "deserve" a new metaball.
					if ((prev_mball.elements[0].radius * self.ball_brush_size + mball_radius) / self.stroke_definition < pts_distance + mball_radius / 10):
						mball_object = self.create_metaball(p, mball_radius,  self.final_mesh_name + str(mballs_num))
						new_mball_created = True
						
						
				if new_mball_created:
					#mball_object.data.threshold = 0
					mball_object.data.elements[0].hide = True
					
					all_mballs.append(mball_object)
					
					prev_mball_object = mball_object
					prev_pt = p
					
					mballs_num += 1
					mballs_count += 1
			
			
			stroke_time = time.time() - mballs_start_time
			strokes_total_time += stroke_time
			print("DONE " + str(curves_count) + " strokes of " + str(len(all_strokes_curves)))
			#print("Metaballs: " + str(mballs_count) + "  Time: " + str(time.time() - mballs_start_time) + "Points: " + str(len(pts)))
			print(".............................................. total time: " + str(int(strokes_total_time)) + " seconds")
			print("")
			
			curves_count += 1
		
		
		bpy.ops.object.select_name(name = self.main_object.name)
		bpy.context.scene.objects.active = self.main_object
		
	
	def invoke (self, context, event):
		self.main_object = bpy.context.object
		self.ball_brush_size = 1
		self.mballs_stiffness = 2
		self.mballs_size_compensation = 0.9
		self.stroke_definition = bpy.context.object.ASKETCH_mball_stroke_definition
		self.stroke_wire_resolution = bpy.context.object.ASKETCH_mball_wire_resolution
		
		self.final_mesh_name = self.main_object.name + ".SKMB"
		
		self.mirror_x_on = bpy.context.scene.ASKETCH_mirror_x_on
		
		self.execute(context)
		
		return {"FINISHED"}


# Metaballs rename
class OBJECT_OT_ASKETCH_metaballs_rename(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_metaballs_rename"
	bl_label = "Array Sketch Metaballs Rename"

	
	def execute(self, context):
		renamed_mballs_count = 1
		for mb in self.metaballs_objects:
			mb.data.elements[0].hide = False
			mb.name = self.final_mesh_name
			
		print("Meshing metaballs...")
		bpy.data.objects[self.final_mesh_name].data.wire_size = self.stroke_wire_resolution
		#bpy.data.objects[self.final_mesh_name].data.threshold = 0.01
		bpy.data.objects[self.final_mesh_name].data.threshold = 0.6
		
		
		bpy.ops.object.select_name(name = self.main_object.name)
		bpy.context.scene.objects.active = self.main_object
		
	
	def invoke (self, context, event):
		self.main_object = bpy.context.object
		self.stroke_wire_resolution = bpy.context.object.ASKETCH_mball_wire_resolution
		self.final_mesh_name = self.main_object.name + ".SKMB"
		
		self.metaballs_objects = []
		
		for ob in bpy.data.objects:
			if ob.name.find(self.final_mesh_name) != -1:
				self.metaballs_objects.append(ob)
			
		self.execute(context)
		
		return {"FINISHED"}
			

# Convert metaballs to mesh.
class OBJECT_OT_ASKETCH_metaballs_to_mesh(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_metaballs_to_mesh"
	bl_label = "Array Sketch Metaballs To Mesh"

	
	def execute(self, context):
		if not self.starting_from_fixed_mesh:
			print("STAGE 1 of 4: Converting to Mesh...")
			start_time = time.time()
			bpy.ops.object.select_name(name = self.metaballs_object.name)
			bpy.context.scene.objects.active = self.metaballs_object
			
			bpy.ops.object.convert(target='MESH', keep_original = False)
			print("DONE... Time: " + str(time.time() - start_time) + " seconds")
			print("Preparing next stage...")
			print("")
			
				
			mesh_object = bpy.context.selected_objects[0]
			bpy.context.scene.objects.active = mesh_object
			
			
			#### Setting mesh's origin.
			cursor_loc = bpy.data.scenes[bpy.context.scene.name].cursor_location
			previous_cursor_loc = [cursor_loc[0], cursor_loc[1], cursor_loc[2]]
			
			bpy.ops.object.select_name(name = mesh_object.name)
			bpy.context.scene.objects.active = bpy.context.scene.objects[mesh_object.name]
			
			bpy.data.scenes[bpy.context.scene.name].cursor_location = self.main_object.location
			bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
			
			bpy.data.scenes[bpy.context.scene.name].cursor_location = previous_cursor_loc
			
			
			#### Make it child of the main object
			mesh_object.name = self.main_object.name + ".SKMTMP"
			mesh_object.parent = self.main_object
			mesh_object.location = [0, 0, 0]
			
			
			#### Delete metaballs
			for obj in bpy.data.objects:
				if obj.name.find(self.main_object.name + ".SKMB") != -1:
					bpy.ops.object.select_name(name = obj.name)
					bpy.context.scene.objects.active = obj
					bpy.ops.object.delete()
			
			#### Delete all temporal curves.
			for obj in bpy.data.objects:
				if obj.name.find("A_SK_TEMP_CURVE") != -1:
					bpy.ops.object.select_name(name = obj.name)
					bpy.context.scene.objects.active = bpy.data.objects[obj.name]
					bpy.ops.object.delete()
		else:
			mesh_object = bpy.data.objects[self.temp_mesh.name]
			print("STAGE 1 of 4: Converting to Mesh...")
			print("Already converted. Preparing next stage...")
			print("")
		
		
		#### Cleaning mesh result.
		####################################
		
		bpy.ops.object.select_name(name = mesh_object.name)
		bpy.context.scene.objects.active = mesh_object
		
		#### Check if the mesh has non-manifold areas.
		bpy.ops.object.editmode_toggle()
		bpy.ops.mesh.select_all(action='DESELECT')
		bpy.ops.mesh.select_non_manifold()
		bpy.ops.object.editmode_toggle()
		
		is_non_manifold = False
		for v in bpy.data.objects[mesh_object.name].data.verts:
			if v.selected:
				is_non_manifold = True
				break
		
		
		#### If the resulting mesh is non-manifold do the mesh optimizations.
		if not is_non_manifold:
			#### To keep temporarily a copy of the non-decimated mesh.
			non_decimated_object = bpy.context.object
			bpy.ops.object.duplicate_move()
			
			
			# Decimate.
			print("STAGE 2 of 4: Decimating...")
			start_time = time.time()
			bpy.ops.object.modifier_add(type='DECIMATE')
			bpy.context.object.modifiers["Decimate"].ratio = 0.02
			bpy.ops.object.convert(target='MESH', keep_original = False)
			print("STAGE DONE... Time: " + str(time.time() - start_time) + " seconds")
			print("Preparing next stage...")
			print("")
			
			# Tris to Quads.
			print("STAGE 3 of 4: Making all Quads...")
			start_time = time.time()
			bpy.ops.object.editmode_toggle()
			bpy.ops.mesh.select_all(action='SELECT')
			bpy.ops.mesh.tris_convert_to_quads()
			bpy.ops.mesh.tris_convert_to_quads()
			bpy.ops.object.editmode_toggle()
			
			# One level of Subdivision.
			bpy.ops.object.modifier_add(type='SUBSURF')
			bpy.context.object.modifiers["Subsurf"].levels = 1
			bpy.ops.object.convert(target='MESH', keep_original = False)
			print("DONE... Time: " + str(time.time() - start_time) + " seconds")
			print("Preparing next stage...")
			print("")
			
			# Smooth shading for faces
			bpy.ops.object.editmode_toggle()
			bpy.ops.mesh.select_all(action='SELECT')
			bpy.ops.mesh.faces_shade_smooth()
			bpy.ops.object.editmode_toggle()
			
			# Shrinkwrap and smooth results to the non-decimated mesh.
			print("STAGE 4 of 4: Fitting...")
			start_time = time.time()
			bpy.ops.object.modifier_add(type='SHRINKWRAP')
			bpy.context.object.modifiers["Shrinkwrap"].negative = True
			bpy.context.object.modifiers["Shrinkwrap"].positive = True
			bpy.context.object.modifiers["Shrinkwrap"].mode = "PROJECT"
			bpy.context.object.modifiers["Shrinkwrap"].target = non_decimated_object
			bpy.ops.object.convert(target='MESH', keep_original = False)
			print("DONE... Time: " + str(time.time() - start_time) + " seconds")
			print("")
			
			# Add Multires
			bpy.ops.object.modifier_add(type='MULTIRES')
			bpy.context.object.modifiers["Multires"].optimal_display = True
			
			
			#### Name the resulting mesh.
			bpy.context.object.name = self.main_object.name + ".SKME"
			
			
			#### Apply the material of the main object to the new mesh
			if len(bpy.data.objects[self.main_object.name].materials) > 0:
				bpy.ops.object.material_slot_add()
				bpy.data.objects[bpy.context.object.name].materials[0].material = bpy.data.objects[self.main_object.name].materials[0].material
			
			
			#### Delete non-decimated mesh
			bpy.ops.object.select_name(name = non_decimated_object.name)
			bpy.context.scene.objects.active = non_decimated_object
			bpy.ops.object.delete()
		else:
			print("WARNING: There are non-manifold areas in the resulting mesh")
			print("(To solve this fix the non-manifold areas (now selected) and then press STEP 3 again")
		
		
		#### Select main object.
		bpy.ops.object.select_name(name = self.main_object.name)
		bpy.context.scene.objects.active = self.main_object
		
		
		#### Hide all strokes
		for obj in bpy.data.objects:
			if obj.name.find(self.main_object.name + ".SKS") != -1 or obj.name.find(self.main_object.name + ".SKD") != -1:
				bpy.data.objects[obj.name].restrict_view = True
		
		
		
	def invoke (self, context, event):
		#### Check if the resulting mesh with non-manifold areas is selected, to change selection to main object.
		if bpy.context.object.name.find(".SKMTMP") != -1:
			self.main_object = bpy.context.object.parent
			self.final_mesh_name = self.main_object.name + ".SKMB"
			
			bpy.ops.object.select_name(name = self.main_object.name)
			bpy.context.scene.objects.active = self.main_object
		else:
			self.main_object = bpy.context.object
			self.final_mesh_name = self.main_object.name + ".SKMB"
		
		#### Check if there is a Metaballs object
		if self.main_object.name + ".SKMB" in bpy.data.objects:
			self.metaballs_object = bpy.data.objects[self.main_object.name + ".SKMB"]
			
		
		#### Check if there is a previous (not decimated) mesh.
		self.starting_from_fixed_mesh = False
		if self.main_object.name + ".SKMTMP" in bpy.data.objects:
			self.starting_from_fixed_mesh = True
			self.temp_mesh = bpy.data.objects[self.main_object.name + ".SKMTMP"]
			
		
		self.execute(context)
		
		return {"FINISHED"}



# Toggle visibility between Strokes and "baked" Mesh object.
class OBJECT_OT_ASKETCH_toggle_mesh_visibility(bpy.types.Operator):
	bl_idname = "OBJECT_OT_ASKETCH_toggle_mesh_visibility"
	bl_label = "Array Sketch Smooth Stroke Size"
	
	
	def execute(self, context):
		mesh_obj_name = self.main_object.name + ".SKME"
		
		if mesh_obj_name in bpy.data.objects:
			if (bpy.data.objects[mesh_obj_name].restrict_view == True):
				bpy.data.objects[mesh_obj_name].restrict_view = False
				
				for obj in bpy.data.objects:
					if (obj.name.find(self.main_object.name + ".SKS") != -1 or obj.name.find(self.main_object.name + ".SKD") != -1):
						bpy.data.objects[obj.name].restrict_view = True
			else:
				bpy.data.objects[mesh_obj_name].restrict_view = True
				
				for obj in bpy.data.objects:
					if (obj.name.find(self.main_object.name + ".SKS") != -1 or obj.name.find(self.main_object.name + ".SKD") != -1):
						bpy.data.objects[obj.name].restrict_view = False
		else:
			for obj in bpy.data.objects:
				if (obj.name.find(self.main_object.name + ".SKS") != -1 or obj.name.find(self.main_object.name + ".SKD") != -1):
					bpy.data.objects[obj.name].restrict_view = False
			
			bpy.ops.object.select_name(name = self.main_object.name)
			bpy.context.scene.objects.active = self.main_object
			
		
	def invoke (self, context, event):
		if bpy.context.object.name.find(".SKME") != -1:
			self.main_object = bpy.data.objects[bpy.context.object.name.split(".SKME")[0]]
			
			bpy.ops.object.select_name(name = self.main_object.name)
			bpy.context.scene.objects.active = self.main_object
		else:
			self.main_object = bpy.context.object
			
		self.execute(context)
		
		return {"FINISHED"}
		



bpy.types.register(OBJECT_OT_ASKETCH_metaballs_rename)
bpy.types.register(GPENCIL_OT_ASKETCH_stroke_editmode_toggle)
bpy.types.register(OBJECT_OT_ASKETCH_toggle_mesh_visibility)
bpy.types.register(OBJECT_OT_ASKETCH_metaballs_to_mesh)
bpy.types.register(OBJECT_OT_ASKETCH_strokes_to_metaballs)
bpy.types.register(OBJECT_OT_ASKETCH_stroke_smooth_size)
bpy.types.register(OBJECT_OT_ASKETCH_delete_strokes)
bpy.types.register(GPENCIL_OT_ASKETCH_stroke_draw)
bpy.types.register(OBJECT_OT_ASKETCH_stroke_editmode)
bpy.types.register(OBJECT_OT_ASKETCH_stroke_editmode_exit)
bpy.types.register(OBJECT_OT_ASKETCH_set_brush_object)
bpy.types.register(VIEW3D_PT_tools_ASKETCH)
bpy.types.register(VIEW3D_PT_tools_ASKETCH_editmode)















-- 








Yuniel 


More information about the Bf-committers mailing list