More elegant serialization of blobs in customdata using the pickle
[blender-addons-contrib.git] / mesh_easylattice.py
index 120fd0241bf1dd6184115b11e4ffdfbe037f5a81..7e98a95ca09a841666a9ef4fa5477d4f0cd84d54 100644 (file)
 
 
 bl_info = {
-            "name": "Easy Lattice Object",
-            "author": "Kursad Karatas",
-            "version": ( 0, 5 ),
-            "blender": ( 2, 66, 0 ),
-            "location": "View3D > Easy Lattice",
-            "description": "Create a lattice for shape editing",
-            "warning": "",
-            "wiki_url": "http://wiki.blender.org/index.php/Easy_Lattice_Editing_Addon",
-            "tracker_url": "https://bitbucket.org/kursad/blender_addons_easylattice/src",
-            "category": "Mesh"}
+    "name": "Easy Lattice Object",
+    "author": "Kursad Karatas",
+    "version": (0, 5),
+    "blender": (2, 66, 0),
+    "location": "View3D > Easy Lattice",
+    "description": "Create a lattice for shape editing",
+    "warning": "",
+    "wiki_url": "http://wiki.blender.org/index.php/Easy_Lattice_Editing_Addon",
+    "tracker_url": "https://bitbucket.org/kursad/blender_addons_easylattice/src",
+    "category": "Mesh"}
+
 
 import bpy
 import mathutils
 import math
+
 # Cleanup
 def modifiersDelete( obj ):
-    
+
     for mod in obj.modifiers:
         print(mod)
         if mod.name == "latticeeasytemp":
@@ -43,85 +44,83 @@ def modifiersDelete( obj ):
                 if mod.object == bpy.data.objects['LatticeEasytTemp']:
                     print("applying modifier")
                     bpy.ops.object.modifier_apply( apply_as = 'DATA', modifier = mod.name )
-                    
+
             except:
                 bpy.ops.object.modifier_remove( modifier = mod.name )
-        
+
 # Cleanup
 def modifiersApplyRemove( obj ):
-    
-    print("passed object is", obj)
-    
-    print("current object is", bpy.context.active_object)
-    
+
+#     print("passed object is", obj)
+#     print("current object is", bpy.context.active_object)
+
     bpy.ops.object.select_all( action = 'DESELECT' )
     bpy.ops.object.select_pattern(pattern=obj.name, extend=False)
     bpy.context.scene.objects.active=obj
-    
+
     for mod in obj.modifiers:
-        print("modifier is ", mod)
+        print("modifier is ", mod)
         if mod.name == "latticeeasytemp":
 #             try:
             if mod.object == bpy.data.objects['LatticeEasytTemp']:
-                print("mod object is ", mod.object)
-                print("applying modifier", mod," - ", mod.name)
-                
+                print("mod object is ", mod.object)
+                print("applying modifier", mod," - ", mod.name)
+
                 #obj.select= True
-                print("current object is", bpy.context.active_object)
+                print("current object is", bpy.context.active_object)
                 bpy.ops.object.modifier_apply( apply_as = 'DATA', modifier = mod.name )
                 #obj.modifiers.remove(mod)
-                    
+
 #             except:
 #                 bpy.ops.object.modifier_remove( modifier = mod.name )
-                
-       
+
+
 # Cleanup
 def latticeDelete(obj):
     bpy.ops.object.select_all( action = 'DESELECT' )
     for ob in bpy.context.scene.objects:
          if "LatticeEasytTemp" in ob.name:
              ob.select = True
-    bpy.ops.object.delete( use_global = False )        
-    
+    bpy.ops.object.delete( use_global = False )
+
     #select the original object back
     obj.select=True
 
-
 def createLattice( obj, size, pos, props ):
     # Create lattice and object
     lat = bpy.data.lattices.new( 'LatticeEasytTemp' )
     ob = bpy.data.objects.new( 'LatticeEasytTemp', lat )
-    
+
     loc,rot,scl = getTransformations( obj )
+
     #get the combined rotation matrix and apply to the lattice
     #ob.matrix_world=buildRot_WorldMat(obj)*ob.matrix_world
-    
-    #the position comes from the bbox 
+
+    #the position comes from the bbox
     ob.location = pos
         #ob.location=(pos.x+loc.x,pos.y+loc.y,pos.z+loc.z)
-    
-    #the size  from bbox bbox
+
+    #the size  from bbox
     ob.scale = size
         #ob.scale=(size.x*scl.x, size.y*scl.y,size.z*scl.z)
-    
-    #the rotation comes from the combined obj world matrix which was converted to euler pairs.    
+
+    #the rotation comes from the combined obj world matrix which was converted to euler pairs.
     ob.rotation_euler = buildRot_World(obj)
-    
+
     ob.show_x_ray = True
     # Link object to scene
     scn = bpy.context.scene
     scn.objects.link( ob )
     scn.objects.active = ob
     scn.update()
+
     # Set lattice attributes
     lat.interpolation_type_u = props[3]
     lat.interpolation_type_v = props[3]
     lat.interpolation_type_w = props[3]
+
     lat.use_outside = False
-    
+
     lat.points_u = props[0]
     lat.points_v = props[1]
     lat.points_w = props[2]
@@ -136,35 +135,35 @@ def createLattice( obj, size, pos, props ):
         for k in range(3):
             #pt.co[k] = points[n][k]
     '''
-    
+
     return ob
 
 
 def selectedVerts_Grp( obj ):
 #     vertices=bpy.context.active_object.data.vertices
     vertices = obj.data.vertices
-    
+
     selverts = []
-    
+
     if obj.mode == "EDIT":
         bpy.ops.object.editmode_toggle()
 
     for grp in obj.vertex_groups:
-        
+
         if "templatticegrp" in grp.name:
             bpy.ops.object.vertex_group_set_active( group = grp.name )
             bpy.ops.object.vertex_group_remove()
-        
+
     tempgroup = obj.vertex_groups.new( "templatticegrp" )
-    
+
     # selverts=[vert for vert in vertices if vert.select==True]
     for vert in vertices:
         if vert.select == True:
             selverts.append( vert )
             tempgroup.add( [vert.index], 1.0, "REPLACE" )
-    
+
     # print(selverts)
-    
+
     return selverts
 
 def getTransformations( obj ):
@@ -175,23 +174,23 @@ def getTransformations( obj ):
     return [loc, rot, size]
 
 def findBBox( obj, selvertsarray ):
-    
+
 #     mat = buildTrnSclMat( obj )
     mat =buildTrnScl_WorldMat(obj)
-    
+
     mat_world = obj.matrix_world
-    
+
     minx, miny, minz = selvertsarray[0].co
     maxx, maxy, maxz = selvertsarray[0].co
-    
+
     c = 1
 #     for vert in selvertsarray:
     for c in range( len( selvertsarray ) ):
         # co=obj.matrix_world*vert.co.to_4d()
-        
+
 #         co = vert.co
         co = selvertsarray[c].co
-        
+
         if co.x < minx: minx = co.x
         if co.y < miny: miny = co.y
         if co.z < minz: minz = co.z
@@ -199,21 +198,21 @@ def findBBox( obj, selvertsarray ):
         if co.x > maxx: maxx = co.x
         if co.y > maxy: maxy = co.y
         if co.z > maxz: maxz = co.z
-        
+
 #         print("local cord", selvertsarray[c].co)
 #         print("world cord", co)
         c += 1
-        
+
 #     print("total verts", len(selvertsarray))
 #     print("counted verts",c)
-    
+
     # Based on world coords
 #     print("-> minx miny minz",minx, miny, minz )
 #     print("-> maxx maxy maxz",maxx, maxy, maxz )
-    
+
     minpoint = mathutils.Vector( ( minx, miny, minz ) )
     maxpoint = mathutils.Vector( ( maxx, maxy, maxz ) )
-    
+
     # middle point has to be calculated based on the real world matrix
     #middle = mat_world * mathutils.Vector((x_sum, y_sum, z_sum))/float(c)
     middle = ( ( minpoint + maxpoint ) / 2 )
@@ -221,11 +220,11 @@ def findBBox( obj, selvertsarray ):
     minpoint = mat * minpoint  # Calculate only based on loc/scale
     maxpoint = mat * maxpoint  # Calculate only based on loc/scale
     middle = mat_world * middle  # the middle has to be calculated based on the real world matrix
-    
+
     size = maxpoint - minpoint
     size = mathutils.Vector( ( abs( size.x ), abs( size.y ), abs( size.z ) ) )
-    
-    # local coords   
+
+    # local coords
     #####################################################
     '''minpoint=mathutils.Vector((minx,miny,minz))
     maxpoint=mathutils.Vector((maxx,maxy,maxz))
@@ -234,7 +233,7 @@ def findBBox( obj, selvertsarray ):
     size=mathutils.Vector((abs(size.x),abs(size.y),abs(size.z)))
     '''
     #####################################################
-    
+
 
     return [minpoint, maxpoint, size, middle  ]
 
@@ -246,34 +245,34 @@ def buildTrnSclMat( obj ):
     mat_scale = mathutils.Matrix.Scale( obj.scale[0], 4, ( 1, 0, 0 ) )
     mat_scale *= mathutils.Matrix.Scale( obj.scale[1], 4, ( 0, 1, 0 ) )
     mat_scale *= mathutils.Matrix.Scale( obj.scale[2], 4, ( 0, 0, 1 ) )
-    
+
     mat_final = mat_trans * mat_scale
-    
-    
+
+
     return mat_final
-    
+
 def buildTrnScl_WorldMat( obj ):
     # This function builds a real world matrix that encodes translation and scale and it leaves out the rotation matrix
     # The rotation is applied at obejct level if there is any
     loc,rot,scl=obj.matrix_world.decompose()
     mat_trans = mathutils.Matrix.Translation( loc)
-    
+
     mat_scale = mathutils.Matrix.Scale( scl[0], 4, ( 1, 0, 0 ) )
     mat_scale *= mathutils.Matrix.Scale( scl[1], 4, ( 0, 1, 0 ) )
     mat_scale *= mathutils.Matrix.Scale( scl[2], 4, ( 0, 0, 1 ) )
-    
+
     mat_final = mat_trans * mat_scale
-    
-    
+
+
     return mat_final
 
-#Feature use    
+#Feature use
 def buildRot_WorldMat( obj ):
     # This function builds a real world matrix that encodes rotation and it leaves out translation and scale matrices
     loc,rot,scl=obj.matrix_world.decompose()
     rot=rot.to_euler()
-    
-    mat_rot = mathutils.Matrix.Rotation(rot[0], 4,'X') 
+
+    mat_rot = mathutils.Matrix.Rotation(rot[0], 4,'X')
     mat_rot *= mathutils.Matrix.Rotation(rot[1],4,'Z')
     mat_rot *= mathutils.Matrix.Rotation(rot[2], 4,'Y')
     return mat_rot
@@ -284,7 +283,7 @@ def buildTrn_WorldMat( obj ):
     # The rotation is applied at obejct level if there is any
     loc,rot,scl=obj.matrix_world.decompose()
     mat_trans = mathutils.Matrix.Translation( loc)
-    
+
     return mat_trans
 
 #Feature use
@@ -292,55 +291,65 @@ def buildScl_WorldMat( obj ):
     # This function builds a real world matrix that encodes translation and scale and it leaves out the rotation matrix
     # The rotation is applied at obejct level if there is any
     loc,rot,scl=obj.matrix_world.decompose()
-    
+
     mat_scale = mathutils.Matrix.Scale( scl[0], 4, ( 1, 0, 0 ) )
     mat_scale *= mathutils.Matrix.Scale( scl[1], 4, ( 0, 1, 0 ) )
     mat_scale *= mathutils.Matrix.Scale( scl[2], 4, ( 0, 0, 1 ) )
-    
+
     return mat_scale
-    
+
 def buildRot_World( obj ):
     # This function builds a real world rotation values
     loc,rot,scl=obj.matrix_world.decompose()
     rot=rot.to_euler()
-    
+
     return rot
 
 def run( lat_props ):
-    
-    print("<-------------------------------->")
+
+    print("<-------------------------------->")
     #obj = bpy.context.active_object
     obj = bpy.context.object
-    
+
     if obj.type == "MESH":
         # set global property for the currently active latticed object
         bpy.types.Scene.activelatticeobject = bpy.props.StringProperty( name = "currentlatticeobject", default = "" )
         bpy.types.Scene.activelatticeobject = obj.name
-    
+
         modifiersDelete( obj )
         selvertsarray = selectedVerts_Grp( obj )
         bbox = findBBox( obj, selvertsarray )
-        
+
         size = bbox[2]
         pos = bbox[3]
-        
+
 #         print("lattce size, pos", size, " ", pos)
         latticeDelete(obj)
         lat = createLattice( obj, size, pos, lat_props )
-        
+
         modif = obj.modifiers.new( "latticeeasytemp", "LATTICE" )
         modif.object = lat
         modif.vertex_group = "templatticegrp"
-        
+
+
+        bpy.ops.object.select_all( action = 'DESELECT' )
+        bpy.ops.object.select_pattern(pattern=lat.name, extend=False)
+        bpy.context.scene.objects.active=lat
+
         bpy.context.scene.update()
         bpy.ops.object.mode_set( mode = 'EDIT' )
-    
+
     if obj.type == "LATTICE":
-        
+
+
         if bpy.types.Scene.activelatticeobject:
             name = bpy.types.Scene.activelatticeobject
             print("last active latticed object", name)
-            
+
+            #Are we in edit lattice mode? If so move on to object mode
+            if obj.mode=="EDIT":
+                bpy.ops.object.editmode_toggle()
+
             for ob in bpy.context.scene.objects:
                 if ob.name == name:  # found the object with the lattice mod
                     print("apply mod on", ob)
@@ -349,9 +358,6 @@ def run( lat_props ):
                     #modifiersDelete( object )  # apply the modifier and delete the lattice
                     latticeDelete(obj)
 
-        
-    
-    
     return
 
 
@@ -364,25 +370,25 @@ class EasyLattice( bpy.types.Operator ):
     bl_label = "Easy Lattice Creator"
     bl_space_type = "VIEW_3D"
     bl_region_type = "TOOLS"
-    
+
     lat_u = bpy.props.IntProperty( name = "Lattice u", default = 3 )
     lat_w = bpy.props.IntProperty( name = "Lattice w", default = 3 )
     lat_m = bpy.props.IntProperty( name = "Lattice m", default = 3 )
-    
+
     lat_types = ( ( '0', 'KEY_LINEAR', '0' ), ( '1', 'KEY_CARDINAL', '1' ), ( '2', 'KEY_BSPLINE', '2' ) )
     lat_type = bpy.props.EnumProperty( name = "Lattice Type", items = lat_types, default = '0' )
-    
-    
+
+
     @classmethod
     def poll( cls, context ):
         return context.active_object is not None
 
     def execute( self, context ):
-        
+
         lat_u = self.lat_u
         lat_w = self.lat_w
         lat_m = self.lat_m
-        
+
         # this is a reference to the "items" used to generate the
         # enum property.
         lat_type = self.lat_types[int( self.lat_type )][1]
@@ -395,22 +401,22 @@ class EasyLattice( bpy.types.Operator ):
         wm = context.window_manager
         return wm.invoke_props_dialog( self )
 
-def menu_draw( self, context ): 
-    self.layout.operator_context = 'INVOKE_REGION_WIN' 
-    self.layout.operator( EasyLattice.bl_idname, "Easy Lattice" ) 
+def menu_draw( self, context ):
+    self.layout.operator_context = 'INVOKE_REGION_WIN'
+    self.layout.operator( EasyLattice.bl_idname, "Easy Lattice" )
 
 def register():
     bpy.utils.register_class( EasyLattice )
     # bpy.utils.register
     # menu_func = (lambda self, context: self.layout.operator('EasyLattice'))
     # bpy.types.VIEW3D_PT_tools_objectmode.append(menu_draw)
-    bpy.types.VIEW3D_MT_edit_mesh_specials.append( menu_draw ) 
+    bpy.types.VIEW3D_MT_edit_mesh_specials.append( menu_draw )
 
 
 def unregister():
     bpy.utils.unregister_class( EasyLattice )
     # bpy.types.VIEW3D_PT_tools_objectmode.remove(menu_draw)
-    bpy.types.VIEW3D_MT_edit_mesh_specials.remove( menu_draw ) 
+    bpy.types.VIEW3D_MT_edit_mesh_specials.remove( menu_draw )
 
 if __name__ == "__main__":
     register()