Paste Code
Paste Blends
Paste Images
bl_info = {
"name": "Z Projection",
"description": "Help Clone tool",
"author": "kgeogeo",
"version": (1, 0),
"blender": (2, 6, 3),
"category": "Paint"}

import bpy
from bpy.types import Panel, Operator
from bpy.props import IntProperty, FloatProperty, BoolProperty, IntVectorProperty, StringProperty
from bpy_extras import view3d_utils
from mathutils import *
from math import *
import mathutils
import math

def align_to_view(context):
ob = context.object
rotation = ob.custom_rotation
scale = ob.custom_scale
z = ob.custom_z
posx = ob.custom_location[0]
posy = ob.custom_location[1]

reg = bpy.context.area.regions[4]
width = reg.width
height = reg.height

r3d = context.space_data.region_3d
r3d.update()
vl = r3d.view_location
vr = r3d.view_rotation
quat = mathutils.Quaternion((0.0, 0.0, 1.0), math.radians(float(rotation)))

v = Vector((1,0,z))
v.rotate(vr)

pos = (posx,posy)

em = bpy.data.objects['Empty for clone']
img = bpy.data.textures['Texture for clone'].image
if img and img.size[1] != 0:
prop = img.size[0]/img.size[1]
em.scale[0] = prop
else: prop = 1

em.scale = Vector((prop*scale, scale, scale))
em.location = view3d_utils.region_2d_to_location_3d(context.area.regions[4], r3d, pos, v)
em.rotation_euler = Quaternion.to_euler(vr*quat)

class HelpClone(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Help Clone"

@classmethod
def poll(cls, context):
return (context.image_paint_object)

def draw(self, context):
layout = self.layout

try:
bpy.data.objects['Empty for clone']

col = layout.column(align =True)
col.operator("object.removecloneplane", text="Remove clone plane")

tex = bpy.data.textures['Texture for clone']

layout.template_ID_preview(tex, "image", open="image.open", rows=3, cols=3)

col = layout.column(align =True)
col.operator('object.applyimage', text = "Apply image")
col = layout.column(align =True)
ob = context.object
col.prop(ob, "custom_c3d",text="Capture Cursor3d")
col.prop(ob, "custom_rot",text="Rotate around selection")
col = layout.column(align =True)
col.prop(ob,'custom_rotation', slider = True)
col.prop(ob,'custom_scale', slider = True)
col.prop(ob,'custom_z', slider = True)
col.prop(ob,'custom_location')
col = layout.column(align =True)
col.prop(ob,'custom_scaleuv', slider = True)
col = layout.column(align =True)
col.prop(ob.material_slots['Material for clone'].material,'alpha', slider = True)

except:
col = layout.column(align =True)
col.operator("object.addcloneplane", text="Add clone plan")

class ApplyImage(Operator):
bl_idname = "object.applyimage"
bl_label = "Apply image"

def execute(self, context):
img = bpy.data.textures['Texture for clone'].image
em = bpy.data.objects['Empty for clone']
uvdata = bpy.context.object.data.uv_textures.active.data
uvdata[len(uvdata)-1].image = img
if img and img.size[1] != 0:
prop = img.size[0]/img.size[1]
em.scale[0] = prop

context.object.data.update()
align_to_view(context)

return {'FINISHED'}

class DrawLines(Operator):
bl_idname = "object.drawlines"
bl_label = "Draw lines"

def invoke(self, context, event):

x = event.mouse_region_x
y = event.mouse_region_y
if len(bpy.context.object.grease_pencil.layers.active.frames)==0:
bpy.ops.gpencil.draw(mode='DRAW', stroke=[{"name":"", "pen_flip":False,
"is_start":True, "location":(0, 0, 0),
"mouse":(x,y), "pressure":1, "time":0}])
else:
if len(bpy.context.object.grease_pencil.layers.active.frames[0].strokes) < 4:
bpy.ops.gpencil.draw(mode='DRAW', stroke=[{"name":"", "pen_flip":False,
"is_start":True, "location":(0, 0, 0),
"mouse":(x,y), "pressure":1, "time":0}])
if len(bpy.context.object.grease_pencil.layers.active.frames[0].strokes) == 4:
s = bpy.context.object.grease_pencil.layers.active.frames[0]
v1 = s.strokes[1].points[0].co - s.strokes[0].points[0].co
v2 = s.strokes[3].points[0].co - s.strokes[2].points[0].co
prop = v1.x/v2.x
bpy.context.object.custom_scale *= abs(prop)
bpy.ops.gpencil.active_frame_delete()

return {'FINISHED'}

class AddClonePlane(Operator):
bl_idname = "object.addcloneplane"
bl_label = "Configure"

def creatematerial(self, context):
try:
matclone = bpy.data.materials['Material for clone']
except:
bpy.data.textures.new(name='Texture for clone',type='IMAGE')

bpy.data.materials.new(name='Material for clone')

matclone = bpy.data.materials['Material for clone']
matclone.texture_slots.add()
matclone.use_shadeless = True
matclone.use_transparency = True
matclone.active_texture = bpy.data.textures['Texture for clone']

index = matclone.active_texture_index
matclone.texture_slots[index].texture_coords = 'UV'

old_index = context.object.active_material_index
bpy.ops.object.material_slot_add()
index = context.object.active_material_index
bpy.context.object.material_slots[index].material = bpy.data.materials['Material for clone']
bpy.ops.object.material_slot_assign()
context.object.active_material_index = old_index

def execute(self, context):
try:
bpy.data.objects['Empty for clone']

except:
bpy.ops.paint.texture_paint_toggle()

bpy.context.space_data.show_relationship_lines = False

ob = bpy.context.object

bpy.ops.object.add()
em = bpy.context.object
em.name = "Empty for clone"

bpy.data.scenes['Scene'].objects.active = ob
ob.select = True

bpy.ops.object.editmode_toggle()

bpy.ops.mesh.primitive_plane_add()
bpy.ops.object.vertex_group_assign(new = True)
ob.vertex_groups.active.name = 'texture plane'
bpy.ops.uv.unwrap()

bpy.ops.object.editmode_toggle()
for i in range(4):
ob.data.edges[len(ob.data.edges)-1-i].crease = 1
bpy.ops.object.editmode_toggle()

em.select = True
bpy.ops.object.hook_add_selob()

self.creatematerial(context)

bpy.ops.gpencil.data_add()
bpy.context.object.grease_pencil.draw_mode = 'VIEW'
bpy.ops.gpencil.layer_add()
bpy.context.object.grease_pencil.layers.active.color = [1.0,0,0]

bpy.ops.mesh.hide()

em.select = False
em.hide = True

bpy.ops.object.editmode_toggle()

bpy.ops.object.applyimage()
km = bpy.data.window_managers['WinMan'].keyconfigs['Blender'].keymaps['3D View']
km.keymap_items[3-1].idname = 'view3d.rotate_view3d'
km.keymap_items[19-1].idname = 'view3d.zoom_view3d'
km.keymap_items[19-1].properties.delta = 1.0
km.keymap_items[20-1].idname = 'view3d.zoom_view3d'
km.keymap_items[20-1].properties.delta = -1.0
km.keymap_items[4-1].idname = 'view3d.pan_view3d'
km.keymap_items[26-1].idname = 'view3d.preset_view3d'
km.keymap_items[26-1].properties.view = 'FRONT'
km.keymap_items[28-1].idname = 'view3d.preset_view3d'
km.keymap_items[28-1].properties.view = 'RIGHT'
km.keymap_items[32-1].idname = 'view3d.preset_view3d'
km.keymap_items[32-1].properties.view = 'TOP'
km.keymap_items[34-1].idname = 'view3d.preset_view3d'
km.keymap_items[34-1].properties.view = 'BACK'
km.keymap_items[35-1].idname = 'view3d.preset_view3d'
km.keymap_items[35-1].properties.view = 'LEFT'
km.keymap_items[36-1].idname = 'view3d.preset_view3d'
km.keymap_items[36-1].properties.view = 'BOTTOM'
km = bpy.context.window_manager.keyconfigs.default.keymaps['Image Paint']
kmi = km.keymap_items.new("object.drawlines", 'LEFTMOUSE', 'PRESS', shift=True)

align_to_view(context)

bpy.ops.paint.texture_paint_toggle()

return {'FINISHED'}

class RemoveClonePlane(Operator):
bl_idname = "object.removecloneplane"
bl_label = "Configure"

def removematerial(self, context):
i = 0
for ms in context.object.material_slots:
if ms.name == 'Material for clone':
index = i
i+=1

context.object.active_material_index = index
bpy.ops.object.material_slot_remove()

def execute(self, context):
try:
bpy.ops.paint.texture_paint_toggle()

context.space_data.show_relationship_lines = True

bpy.ops.object.modifier_remove(modifier="Hook-Empty for clone")

self.removematerial(context)

ob = bpy.context.object

bpy.ops.object.editmode_toggle()

bpy.ops.mesh.reveal()

bpy.ops.mesh.select_all()
bpy.ops.object.editmode_toggle()
if ob.data.vertices[0].select:
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.select_all()
bpy.ops.object.editmode_toggle()
bpy.ops.object.editmode_toggle()

ob.vertex_groups.active.name = 'texture plane'
bpy.ops.object.vertex_group_select()
bpy.ops.mesh.delete()
bpy.ops.object.vertex_group_remove()

bpy.ops.object.editmode_toggle()

ob.select = False

em = bpy.data.objects['Empty for clone']
bpy.data.scenes['Scene'].objects.active = em
em.hide = False
em.select = True
bpy.ops.object.delete()

bpy.data.scenes['Scene'].objects.active = ob
ob.select = True

km = bpy.data.window_managers['WinMan'].keyconfigs['Blender'].keymaps['3D View']
km.keymap_items[3-1].idname = 'view3d.rotate'
km.keymap_items[19-1].idname = 'view3d.zoom'
km.keymap_items[19-1].properties.delta = 1.0
km.keymap_items[20-1].idname = 'view3d.zoom'
km.keymap_items[20-1].properties.delta = -1.0
km.keymap_items[4-1].idname = 'view3d.move'
km.keymap_items[26-1].idname = 'view3d.viewnumpad'
km.keymap_items[26-1].properties.type = 'FRONT'
km.keymap_items[28-1].idname = 'view3d.viewnumpad'
km.keymap_items[28-1].properties.type = 'RIGHT'
km.keymap_items[32-1].idname = 'view3d.viewnumpad'
km.keymap_items[32-1].properties.type = 'TOP'
km.keymap_items[34-1].idname = 'view3d.viewnumpad'
km.keymap_items[34-1].properties.type = 'BACK'
km.keymap_items[35-1].idname = 'view3d.viewnumpad'
km.keymap_items[35-1].properties.type = 'LEFT'
km.keymap_items[36-1].idname = 'view3d.viewnumpad'
km.keymap_items[36-1].properties.type = 'BOTTOM'

km = bpy.context.window_manager.keyconfigs.default.keymaps['Image Paint']
for kmi in km.keymap_items:
if kmi.idname in ["object.drawlines"]:
km.keymap_items.remove(kmi)

bpy.ops.paint.texture_paint_toggle()

except:
nothing

return {'FINISHED'}

class RotateView3D(Operator):
bl_idname = "view3d.rotate_view3d"
bl_label = "Rotate the View3D"

first_mouse_x = 0
first_mouse_y = 0

panx = 0
pany = 0

rkey = False
skey = False
gkey = False
zkey = False
ukey = False
first_time = True

def vect_sphere(self,mx,my):
width = bpy.context.area.regions[4].width
height = bpy.context.area.regions[4].height

if width >= height:
ratio = height/width

x = 2*mx/width
y = 2*ratio*my/height

x = x - 1
y = y - ratio
else:
ratio = width/height

x = 2*ratio*mx/width
y = 2*my/height

x = x - ratio
y = y - 1

z2 = 1 - x * x - y * y
if z2 > 0:
z= sqrt(z2)
else : z=0

p = Vector((x, y, z))
p.normalize()
return p

def tracball(self,mx,my,origine):
pos_init_cursor = view3d_utils.location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, bpy.context.space_data.cursor_location)
if bpy.context.object.custom_rot:
pos_init = view3d_utils.location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, origine)
bpy.context.space_data.region_3d.view_location = origine

v1 = self.vect_sphere(self.first_mouse_x,self.first_mouse_y)
v2 = self.vect_sphere(mx,my)

axis = Vector.cross(v1, v2);
angle = Vector.angle(v1, v2);

q = Quaternion(axis,-2*angle)

bpy.context.space_data.region_3d.view_rotation *=q
bpy.context.space_data.region_3d.update()

if bpy.context.object.custom_rot:
pos_end = view3d_utils.region_2d_to_location_3d(bpy.context.region, bpy.context.space_data.region_3d, pos_init, Vector((0,0,0)))
bpy.context.space_data.region_3d.view_location = -1*pos_end

if bpy.context.object.custom_c3d:
bpy.context.space_data.region_3d.update()
bpy.context.space_data.cursor_location = view3d_utils.region_2d_to_location_3d(bpy.context.region, bpy.context.space_data.region_3d, pos_init_cursor, Vector((0,0,0)))

self.first_mouse_x = mx
self.first_mouse_y = my

def modal(self, context, event):
if event.value == 'PRESS':
self.panx = event.mouse_region_x
self.pany = event.mouse_region_y

if event.type == 'S':
self.skey = True

if event.type == 'R':
self.rkey = True

if event.type == 'G':
self.gkey = True

if event.type == 'Z':
self.zkey = True

if event.type == 'U':
self.ukey = True

if event.value == 'RELEASE':
if event.type == 'S':
self.skey = False

if event.type == 'R':
self.rkey = False

if event.type == 'G':
self.gkey = False

if event.type == 'Z':
self.zkey = False

if event.type == 'U':
self.ukey = False

if event.type == 'MOUSEMOVE':

if self.rkey == False and self.skey == False and self.gkey == False and self.zkey == False and self.ukey == False:
self.tracball(event.mouse_region_x,event.mouse_region_y,bpy.context.object.location)
align_to_view(context)
if self.first_time:
rot_ang = bpy.context.user_preferences.view.rotation_angle
bpy.context.user_preferences.view.rotation_angle = 0
bpy.ops.view3d.view_orbit(type='ORBITLEFT')
bpy.context.user_preferences.view.rotation_angle = rot_ang
bpy.ops.view3d.view_persportho()
bpy.ops.view3d.view_persportho()
self.first_time = False

deltax = event.mouse_region_x - self.panx
deltay = event.mouse_region_y - self.pany

if self.rkey == False and self.skey == False and self.gkey == True and self.zkey == False and self.ukey == False:
bpy.context.object.custom_location[0]+=deltax
bpy.context.object.custom_location[1]+=deltay

if self.rkey == False and self.skey == True and self.gkey == False and self.zkey == False and self.ukey == False:
bpy.context.object.custom_scale+=deltax/10

if self.rkey == False and self.skey == False and self.gkey == False and self.zkey == True and self.ukey == False:
bpy.context.object.custom_z+=deltax/10

if self.rkey == True and self.skey == False and self.gkey == False and self.zkey == False and self.ukey == False:
bpy.context.object.custom_rotation+=deltax

if self.rkey == False and self.skey == False and self.gkey == False and self.zkey == False and self.ukey == True:
bpy.context.object.custom_scaleuv+=deltax/10

self.panx = event.mouse_region_x
self.pany = event.mouse_region_y
self.first_mouse_x = event.mouse_region_x
self.first_mouse_y = event.mouse_region_y

elif event.type == 'MIDDLEMOUSE'and event.value == 'RELEASE':

return {'FINISHED'}

return {'RUNNING_MODAL'}

def execute(self, context):
align_to_view(context)

return{'FINISHED'}

def invoke(self, context, event):
context.window_manager.modal_handler_add(self)
self.first_mouse_x = event.mouse_region_x
self.first_mouse_y = event.mouse_region_y
self.first_time = True

return {'RUNNING_MODAL'}

class ZoomView3D(Operator):
bl_idname = "view3d.zoom_view3d"
bl_label = "Zoom View3D"

delta = FloatProperty(
name="delta",
description="Delta",
min=-1.0, max=1,
default=1.0,
)

def invoke(self, context, event):
bpy.ops.view3d.zoom(delta = self.delta)

align_to_view(context)

return {'FINISHED'}

def execute(self, context):
align_to_view(context)

return{'FINISHED'}

class PresetView3D(Operator):
bl_idname = "view3d.preset_view3d"
bl_label = "Preset View3D"

view = StringProperty(name="View", description="Select the view", default='TOP',)

def invoke(self, context, event):
tmp = bpy.context.user_preferences.view.smooth_view
bpy.context.user_preferences.view.smooth_view = 0
bpy.ops.view3d.viewnumpad(type=self.view)
align_to_view(context)
bpy.context.user_preferences.view.smooth_view = tmp

return {'FINISHED'}


class PanView3D(bpy.types.Operator):
bl_idname = "view3d.pan_view3d"
bl_label = "Pan View3D"


first_mouse_x = 0
first_mouse_y = 0

panx = 0
pany = 0

def modal(self, context, event):
width = bpy.context.area.regions[4].width
height = bpy.context.area.regions[4].height

deltax = event.mouse_region_x - self.first_mouse_x
deltay = event.mouse_region_y - self.first_mouse_y

l = bpy.context.space_data.region_3d
vr = l.view_rotation

v = Vector((deltax/max(width,height),deltay/max(width,height),0))
v.rotate(vr)

pos = [0,0]
v1 = view3d_utils.region_2d_to_location_3d(bpy.context.region, l, pos, v)
pos = [width,height]
v2 = view3d_utils.region_2d_to_location_3d(bpy.context.region, l, pos, v)

v3 = (v2 - v1)

pos_init_cursor = view3d_utils.location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, bpy.context.space_data.cursor_location)

bpy.context.space_data.region_3d.view_location -= v*v3.length

bpy.context.space_data.region_3d.update()
bpy.context.space_data.cursor_location = view3d_utils.region_2d_to_location_3d(bpy.context.region, bpy.context.space_data.region_3d, pos_init_cursor, Vector((0,0,0)))

align_to_view(context)

self.first_mouse_x = event.mouse_region_x
self.first_mouse_y = event.mouse_region_y

if event.type == 'MIDDLEMOUSE'and event.value == 'RELEASE':
return {'FINISHED'}

return {'RUNNING_MODAL'}

def invoke(self, context, event):
context.window_manager.modal_handler_add(self)
self.first_mouse_x = event.mouse_region_x
self.first_mouse_y = event.mouse_region_y

return {'RUNNING_MODAL'}

def execute(self, context):
align_to_view(context)

return{'FINISHED'}

def update_func(self, context):
v = Vector((0.5,0.5))
for i in range(4):
vres = v - bpy.context.object.data.uv_loop_layers.active.data[len(bpy.context.object.data.uv_loop_layers.active.data)-1-i].uv
vres /= vres.length
for j in range(2):
if abs(vres[j-1])>0:
vres[j-1] /= abs(vres[j-1])
bpy.context.object.data.uv_loop_layers.active.data[len(bpy.context.object.data.uv_loop_layers.active.data)-1-i].uv = v - vres*bpy.context.object.custom_scaleuv/2

align_to_view(context)

def createcustomprops():
Ob = bpy.types.Object
Ob.custom_rotation = IntProperty(name="Rotation", description="Rotate the plane", min=-180, max=180, default=0,update = update_func)
Ob.custom_scale = FloatProperty(name="Scale", description="Scale the plane", min=0, max=10, default=1.0,update = update_func)
Ob.custom_z = FloatProperty(name="Z", description="Z axis for the plane", min=-10, max=10, default=-1.0,update = update_func)
Ob.custom_scaleuv = FloatProperty(name="ScaleUV", description="Scale the texture's UV", min=1.0, max=10, default=1.0,update = update_func)
Ob.custom_location = IntVectorProperty(name="Location", description="Location of the plan", default=(0, 0), subtype = 'XYZ', size=2, update = update_func)
Ob.custom_c3d = BoolProperty(name="c3d", default=True)
Ob.custom_rot = BoolProperty(name="rot", default=True)

def register():
bpy.utils.register_module(__name__)
createcustomprops()

def unregister():
bpy.utils.unregister_module(__name__)

if __name__ == "__main__":
register()

  1. bl_info = {
  2.     "name": "Z Projection",
  3.     "description": "Help Clone tool",
  4.     "author": "kgeogeo",
  5.     "version": (1, 0),
  6.     "blender": (2, 6, 3),
  7.     "category": "Paint"}
  8.  
  9. import bpy
  10. from bpy.types import Panel, Operator
  11. from bpy.props import IntProperty, FloatProperty, BoolProperty, IntVectorProperty, StringProperty
  12. from bpy_extras import view3d_utils
  13. from mathutils import *
  14. from math import *
  15. import mathutils
  16. import math
  17.  
  18. def align_to_view(context):
  19.     ob = context.object        
  20.     rotation = ob.custom_rotation
  21.     scale = ob.custom_scale
  22.     z = ob.custom_z
  23.     posx = ob.custom_location[0]
  24.     posy = ob.custom_location[1]
  25.  
  26.     reg = bpy.context.area.regions[4]        
  27.     width = reg.width
  28.     height = reg.height
  29.        
  30.     r3d =  context.space_data.region_3d        
  31.     r3d.update()
  32.     vl = r3d.view_location
  33.     vr = r3d.view_rotation
  34.     quat = mathutils.Quaternion((0.0, 0.0, 1.0), math.radians(float(rotation)))
  35.        
  36.     v = Vector((1,0,z))
  37.     v.rotate(vr)
  38.  
  39.     pos = (posx,posy)
  40.  
  41.     em = bpy.data.objects['Empty for clone']
  42.     img = bpy.data.textures['Texture for clone'].image
  43.     if img and img.size[1] != 0:
  44.         prop = img.size[0]/img.size[1]
  45.         em.scale[0] = prop
  46.     else: prop = 1    
  47.        
  48.     em.scale =  Vector((prop*scale, scale, scale))
  49.     em.location = view3d_utils.region_2d_to_location_3d(context.area.regions[4], r3d, pos, v)        
  50.     em.rotation_euler = Quaternion.to_euler(vr*quat)
  51.  
  52. class HelpClone(Panel):
  53.     bl_space_type = 'VIEW_3D'
  54.     bl_region_type = 'UI'
  55.     bl_label = "Help Clone"
  56.  
  57.     @classmethod
  58.     def poll(cls, context):
  59.         return (context.image_paint_object)
  60.  
  61.     def draw(self, context):        
  62.         layout = self.layout
  63.                
  64.         try:
  65.             bpy.data.objects['Empty for clone']
  66.  
  67.             col = layout.column(align =True)
  68.             col.operator("object.removecloneplane", text="Remove clone plane")
  69.        
  70.             tex = bpy.data.textures['Texture for clone']
  71.  
  72.             layout.template_ID_preview(tex, "image", open="image.open", rows=3, cols=3)
  73.        
  74.             col = layout.column(align =True)
  75.             col.operator('object.applyimage', text = "Apply image")
  76.             col = layout.column(align =True)
  77.             ob = context.object
  78.             col.prop(ob, "custom_c3d",text="Capture Cursor3d")
  79.             col.prop(ob, "custom_rot",text="Rotate around selection")
  80.             col = layout.column(align =True)
  81.             col.prop(ob,'custom_rotation', slider = True)
  82.             col.prop(ob,'custom_scale', slider = True)
  83.             col.prop(ob,'custom_z', slider = True)
  84.             col.prop(ob,'custom_location')
  85.             col = layout.column(align =True)
  86.             col.prop(ob,'custom_scaleuv', slider = True)
  87.             col = layout.column(align =True)
  88.             col.prop(ob.material_slots['Material for clone'].material,'alpha', slider = True)
  89.  
  90.         except:
  91.             col = layout.column(align =True)
  92.             col.operator("object.addcloneplane", text="Add clone plan")            
  93.                
  94. class ApplyImage(Operator):
  95.     bl_idname = "object.applyimage"
  96.     bl_label = "Apply image"
  97.  
  98.     def execute(self, context):        
  99.         img = bpy.data.textures['Texture for clone'].image
  100.         em = bpy.data.objects['Empty for clone']
  101.         uvdata = bpy.context.object.data.uv_textures.active.data        
  102.         uvdata[len(uvdata)-1].image = img
  103.         if img and img.size[1] != 0:        
  104.             prop = img.size[0]/img.size[1]                
  105.             em.scale[0] = prop
  106.            
  107.         context.object.data.update()
  108.         align_to_view(context)
  109.        
  110.         return {'FINISHED'}
  111.  
  112. class DrawLines(Operator):
  113.     bl_idname = "object.drawlines"
  114.     bl_label = "Draw lines"
  115.  
  116.     def invoke(self, context, event):
  117.        
  118.         x = event.mouse_region_x
  119.         y = event.mouse_region_y                
  120.         if len(bpy.context.object.grease_pencil.layers.active.frames)==0:
  121.             bpy.ops.gpencil.draw(mode='DRAW', stroke=[{"name":"", "pen_flip":False,
  122.                                                                 "is_start":True, "location":(0, 0, 0),
  123.                                                                 "mouse":(x,y), "pressure":1, "time":0}])
  124.         else:
  125.             if len(bpy.context.object.grease_pencil.layers.active.frames[0].strokes) < 4:
  126.                 bpy.ops.gpencil.draw(mode='DRAW', stroke=[{"name":"", "pen_flip":False,
  127.                                                                     "is_start":True, "location":(0, 0, 0),
  128.                                                                     "mouse":(x,y), "pressure":1, "time":0}])
  129.             if len(bpy.context.object.grease_pencil.layers.active.frames[0].strokes) == 4:
  130.                 s = bpy.context.object.grease_pencil.layers.active.frames[0]
  131.                 v1 = s.strokes[1].points[0].co - s.strokes[0].points[0].co
  132.                 v2 = s.strokes[3].points[0].co - s.strokes[2].points[0].co
  133.                 prop = v1.x/v2.x
  134.                 bpy.context.object.custom_scale *= abs(prop)
  135.                 bpy.ops.gpencil.active_frame_delete()
  136.        
  137.         return {'FINISHED'}
  138.  
  139. class AddClonePlane(Operator):
  140.     bl_idname = "object.addcloneplane"
  141.     bl_label = "Configure"
  142.    
  143.     def creatematerial(self, context):        
  144.         try:
  145.             matclone = bpy.data.materials['Material for clone']
  146.         except:            
  147.             bpy.data.textures.new(name='Texture for clone',type='IMAGE')
  148.    
  149.             bpy.data.materials.new(name='Material for clone')
  150.            
  151.             matclone = bpy.data.materials['Material for clone']
  152.             matclone.texture_slots.add()
  153.             matclone.use_shadeless = True
  154.             matclone.use_transparency = True
  155.             matclone.active_texture = bpy.data.textures['Texture for clone']
  156.        
  157.             index = matclone.active_texture_index
  158.             matclone.texture_slots[index].texture_coords = 'UV'
  159.      
  160.         old_index = context.object.active_material_index
  161.         bpy.ops.object.material_slot_add()
  162.         index = context.object.active_material_index
  163.         bpy.context.object.material_slots[index].material = bpy.data.materials['Material for clone']
  164.         bpy.ops.object.material_slot_assign()
  165.         context.object.active_material_index = old_index
  166.            
  167.     def execute(self, context):    
  168.         try:
  169.             bpy.data.objects['Empty for clone']
  170.  
  171.         except:            
  172.             bpy.ops.paint.texture_paint_toggle()
  173.            
  174.             bpy.context.space_data.show_relationship_lines = False
  175.            
  176.             ob = bpy.context.object
  177.        
  178.             bpy.ops.object.add()
  179.             em = bpy.context.object
  180.             em.name = "Empty for clone"
  181.                        
  182.             bpy.data.scenes['Scene'].objects.active = ob
  183.             ob.select = True
  184.    
  185.             bpy.ops.object.editmode_toggle()
  186.    
  187.             bpy.ops.mesh.primitive_plane_add()
  188.             bpy.ops.object.vertex_group_assign(new = True)
  189.             ob.vertex_groups.active.name = 'texture plane'  
  190.             bpy.ops.uv.unwrap()
  191.            
  192.             bpy.ops.object.editmode_toggle()
  193.             for i in range(4):
  194.                 ob.data.edges[len(ob.data.edges)-1-i].crease = 1
  195.             bpy.ops.object.editmode_toggle()
  196.    
  197.             em.select = True
  198.             bpy.ops.object.hook_add_selob()
  199.            
  200.             self.creatematerial(context)
  201.            
  202.             bpy.ops.gpencil.data_add()
  203.             bpy.context.object.grease_pencil.draw_mode = 'VIEW'
  204.             bpy.ops.gpencil.layer_add()
  205.             bpy.context.object.grease_pencil.layers.active.color = [1.0,0,0]
  206.  
  207.             bpy.ops.mesh.hide()
  208.            
  209.             em.select = False
  210.             em.hide = True
  211.            
  212.             bpy.ops.object.editmode_toggle()
  213.                    
  214.             bpy.ops.object.applyimage()
  215.             km = bpy.data.window_managers['WinMan'].keyconfigs['Blender'].keymaps['3D View']
  216.             km.keymap_items[3-1].idname = 'view3d.rotate_view3d'
  217.             km.keymap_items[19-1].idname = 'view3d.zoom_view3d'
  218.             km.keymap_items[19-1].properties.delta = 1.0
  219.             km.keymap_items[20-1].idname = 'view3d.zoom_view3d'
  220.             km.keymap_items[20-1].properties.delta = -1.0
  221.             km.keymap_items[4-1].idname = 'view3d.pan_view3d'
  222.             km.keymap_items[26-1].idname = 'view3d.preset_view3d'
  223.             km.keymap_items[26-1].properties.view = 'FRONT'
  224.             km.keymap_items[28-1].idname = 'view3d.preset_view3d'
  225.             km.keymap_items[28-1].properties.view = 'RIGHT'            
  226.             km.keymap_items[32-1].idname = 'view3d.preset_view3d'
  227.             km.keymap_items[32-1].properties.view = 'TOP'
  228.             km.keymap_items[34-1].idname = 'view3d.preset_view3d'
  229.             km.keymap_items[34-1].properties.view = 'BACK'
  230.             km.keymap_items[35-1].idname = 'view3d.preset_view3d'
  231.             km.keymap_items[35-1].properties.view = 'LEFT'            
  232.             km.keymap_items[36-1].idname = 'view3d.preset_view3d'
  233.             km.keymap_items[36-1].properties.view = 'BOTTOM'                                  
  234.             km = bpy.context.window_manager.keyconfigs.default.keymaps['Image Paint']
  235.             kmi = km.keymap_items.new("object.drawlines", 'LEFTMOUSE', 'PRESS', shift=True)
  236.                        
  237.             align_to_view(context)
  238.            
  239.             bpy.ops.paint.texture_paint_toggle()
  240.            
  241.         return {'FINISHED'}
  242.    
  243. class RemoveClonePlane(Operator):
  244.     bl_idname = "object.removecloneplane"
  245.     bl_label = "Configure"
  246.  
  247.     def removematerial(self, context):
  248.         i = 0
  249.         for ms in context.object.material_slots:
  250.             if ms.name == 'Material for clone':
  251.                 index = i
  252.             i+=1
  253.                
  254.         context.object.active_material_index = index
  255.         bpy.ops.object.material_slot_remove()
  256.    
  257.     def execute(self, context):
  258.         try:              
  259.             bpy.ops.paint.texture_paint_toggle()
  260.            
  261.             context.space_data.show_relationship_lines = True
  262.            
  263.             bpy.ops.object.modifier_remove(modifier="Hook-Empty for clone")
  264.            
  265.             self.removematerial(context)
  266.  
  267.             ob = bpy.context.object
  268.    
  269.             bpy.ops.object.editmode_toggle()
  270.    
  271.             bpy.ops.mesh.reveal()
  272.                                    
  273.             bpy.ops.mesh.select_all()
  274.             bpy.ops.object.editmode_toggle()
  275.             if ob.data.vertices[0].select:
  276.                 bpy.ops.object.editmode_toggle()
  277.                 bpy.ops.mesh.select_all()
  278.                 bpy.ops.object.editmode_toggle()
  279.             bpy.ops.object.editmode_toggle()                    
  280.            
  281.             ob.vertex_groups.active.name = 'texture plane'
  282.             bpy.ops.object.vertex_group_select()
  283.             bpy.ops.mesh.delete()
  284.             bpy.ops.object.vertex_group_remove()
  285.    
  286.             bpy.ops.object.editmode_toggle()
  287.    
  288.             ob.select = False
  289.                
  290.             em = bpy.data.objects['Empty for clone']
  291.             bpy.data.scenes['Scene'].objects.active = em
  292.             em.hide = False
  293.             em.select = True
  294.             bpy.ops.object.delete()
  295.    
  296.             bpy.data.scenes['Scene'].objects.active = ob
  297.             ob.select = True
  298.            
  299.             km = bpy.data.window_managers['WinMan'].keyconfigs['Blender'].keymaps['3D View']
  300.             km.keymap_items[3-1].idname = 'view3d.rotate'
  301.             km.keymap_items[19-1].idname = 'view3d.zoom'
  302.             km.keymap_items[19-1].properties.delta = 1.0
  303.             km.keymap_items[20-1].idname = 'view3d.zoom'
  304.             km.keymap_items[20-1].properties.delta = -1.0
  305.             km.keymap_items[4-1].idname = 'view3d.move'
  306.             km.keymap_items[26-1].idname = 'view3d.viewnumpad'
  307.             km.keymap_items[26-1].properties.type = 'FRONT'
  308.             km.keymap_items[28-1].idname = 'view3d.viewnumpad'
  309.             km.keymap_items[28-1].properties.type = 'RIGHT'            
  310.             km.keymap_items[32-1].idname = 'view3d.viewnumpad'
  311.             km.keymap_items[32-1].properties.type = 'TOP'
  312.             km.keymap_items[34-1].idname = 'view3d.viewnumpad'
  313.             km.keymap_items[34-1].properties.type = 'BACK'
  314.             km.keymap_items[35-1].idname = 'view3d.viewnumpad'
  315.             km.keymap_items[35-1].properties.type = 'LEFT'            
  316.             km.keymap_items[36-1].idname = 'view3d.viewnumpad'
  317.             km.keymap_items[36-1].properties.type = 'BOTTOM'            
  318.            
  319.             km = bpy.context.window_manager.keyconfigs.default.keymaps['Image Paint']
  320.             for kmi in km.keymap_items:
  321.                 if kmi.idname in ["object.drawlines"]:
  322.                     km.keymap_items.remove(kmi)
  323.            
  324.             bpy.ops.paint.texture_paint_toggle()
  325.                    
  326.         except:
  327.             nothing
  328.        
  329.         return {'FINISHED'}
  330.  
  331. class RotateView3D(Operator):
  332.     bl_idname = "view3d.rotate_view3d"
  333.     bl_label = "Rotate the View3D"
  334.    
  335.     first_mouse_x = 0
  336.     first_mouse_y = 0
  337.  
  338.     panx = 0
  339.     pany = 0
  340.  
  341.     rkey = False
  342.     skey = False
  343.     gkey = False
  344.     zkey = False
  345.     ukey = False
  346.     first_time = True
  347.    
  348.     def vect_sphere(self,mx,my):
  349.         width = bpy.context.area.regions[4].width
  350.         height = bpy.context.area.regions[4].height
  351.            
  352.         if width >= height:
  353.             ratio = height/width
  354.        
  355.             x = 2*mx/width
  356.             y = 2*ratio*my/height
  357.            
  358.             x = x - 1
  359.             y = y - ratio
  360.         else:
  361.             ratio = width/height
  362.        
  363.             x = 2*ratio*mx/width
  364.             y = 2*my/height
  365.  
  366.             x = x - ratio
  367.             y = y - 1
  368.        
  369.         z2 = 1 - x * x - y * y
  370.         if z2 > 0:
  371.             z= sqrt(z2)
  372.         else : z=0
  373.            
  374.         p = Vector((x, y, z))
  375.         p.normalize()
  376.         return p
  377.    
  378.     def tracball(self,mx,my,origine):
  379.         pos_init_cursor = view3d_utils.location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, bpy.context.space_data.cursor_location)        
  380.         if bpy.context.object.custom_rot:
  381.             pos_init = view3d_utils.location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, origine)
  382.             bpy.context.space_data.region_3d.view_location = origine
  383.        
  384.         v1 = self.vect_sphere(self.first_mouse_x,self.first_mouse_y)
  385.         v2 = self.vect_sphere(mx,my)
  386.                        
  387.         axis = Vector.cross(v1, v2);
  388.         angle = Vector.angle(v1, v2);
  389.            
  390.         q =  Quaternion(axis,-2*angle)
  391.                        
  392.         bpy.context.space_data.region_3d.view_rotation *=q
  393.         bpy.context.space_data.region_3d.update()
  394.        
  395.         if bpy.context.object.custom_rot:
  396.             pos_end = view3d_utils.region_2d_to_location_3d(bpy.context.region, bpy.context.space_data.region_3d, pos_init, Vector((0,0,0)))                
  397.             bpy.context.space_data.region_3d.view_location =  -1*pos_end
  398.  
  399.         if bpy.context.object.custom_c3d:
  400.             bpy.context.space_data.region_3d.update()      
  401.             bpy.context.space_data.cursor_location = view3d_utils.region_2d_to_location_3d(bpy.context.region, bpy.context.space_data.region_3d, pos_init_cursor, Vector((0,0,0)))
  402.        
  403.         self.first_mouse_x = mx
  404.         self.first_mouse_y = my
  405.                
  406.     def modal(self, context, event):                                
  407.         if event.value == 'PRESS':
  408.             self.panx = event.mouse_region_x
  409.             self.pany = event.mouse_region_y
  410.                    
  411.             if event.type == 'S':
  412.                 self.skey = True
  413.            
  414.             if event.type == 'R':
  415.                 self.rkey = True    
  416.  
  417.             if event.type == 'G':
  418.                 self.gkey = True
  419.  
  420.             if event.type == 'Z':
  421.                 self.zkey = True            
  422.  
  423.             if event.type == 'U':
  424.                 self.ukey = True
  425.                            
  426.         if event.value == 'RELEASE':
  427.             if event.type == 'S':
  428.                 self.skey = False
  429.            
  430.             if event.type == 'R':
  431.                 self.rkey = False
  432.            
  433.             if event.type == 'G':
  434.                 self.gkey = False            
  435.  
  436.             if event.type == 'Z':
  437.                 self.zkey = False
  438.  
  439.             if event.type == 'U':
  440.                 self.ukey = False
  441.            
  442.         if event.type == 'MOUSEMOVE':                        
  443.            
  444.             if self.rkey == False and self.skey == False and self.gkey == False and self.zkey == False and self.ukey == False:
  445.                 self.tracball(event.mouse_region_x,event.mouse_region_y,bpy.context.object.location)
  446.                 align_to_view(context)
  447.                 if self.first_time:
  448.                     rot_ang = bpy.context.user_preferences.view.rotation_angle            
  449.                     bpy.context.user_preferences.view.rotation_angle = 0
  450.                     bpy.ops.view3d.view_orbit(type='ORBITLEFT')
  451.                     bpy.context.user_preferences.view.rotation_angle = rot_ang  
  452.                     bpy.ops.view3d.view_persportho()        
  453.                     bpy.ops.view3d.view_persportho()
  454.                     self.first_time = False
  455.          
  456.             deltax = event.mouse_region_x - self.panx
  457.             deltay = event.mouse_region_y - self.pany          
  458.  
  459.             if self.rkey == False and self.skey == False and self.gkey == True and self.zkey == False and self.ukey == False:      
  460.                 bpy.context.object.custom_location[0]+=deltax
  461.                 bpy.context.object.custom_location[1]+=deltay                
  462.                                    
  463.             if self.rkey == False and self.skey == True and self.gkey == False and self.zkey == False and self.ukey == False:                
  464.                 bpy.context.object.custom_scale+=deltax/10
  465.                                          
  466.             if self.rkey == False and self.skey == False and self.gkey == False and self.zkey == True and self.ukey == False:                
  467.                 bpy.context.object.custom_z+=deltax/10
  468.                      
  469.             if self.rkey == True and self.skey == False and self.gkey == False and self.zkey == False and self.ukey == False:
  470.                 bpy.context.object.custom_rotation+=deltax
  471.  
  472.             if self.rkey == False and self.skey == False and self.gkey == False and self.zkey == False and self.ukey == True:
  473.                 bpy.context.object.custom_scaleuv+=deltax/10                
  474.  
  475.             self.panx = event.mouse_region_x
  476.             self.pany = event.mouse_region_y
  477.             self.first_mouse_x = event.mouse_region_x
  478.             self.first_mouse_y = event.mouse_region_y
  479.            
  480.         elif event.type == 'MIDDLEMOUSE'and event.value == 'RELEASE':
  481.  
  482.             return {'FINISHED'}
  483.        
  484.         return {'RUNNING_MODAL'}
  485.    
  486.     def execute(self, context):        
  487.         align_to_view(context)  
  488.        
  489.         return{'FINISHED'}
  490.  
  491.     def invoke(self, context, event):
  492.         context.window_manager.modal_handler_add(self)
  493.         self.first_mouse_x = event.mouse_region_x
  494.         self.first_mouse_y = event.mouse_region_y
  495.         self.first_time = True
  496.        
  497.         return {'RUNNING_MODAL'}
  498.  
  499. class ZoomView3D(Operator):
  500.     bl_idname = "view3d.zoom_view3d"
  501.     bl_label = "Zoom View3D"
  502.  
  503.     delta = FloatProperty(
  504.         name="delta",
  505.         description="Delta",
  506.         min=-1.0, max=1,
  507.         default=1.0,
  508.         )
  509.  
  510.     def invoke(self, context, event):                  
  511.         bpy.ops.view3d.zoom(delta = self.delta)
  512.        
  513.         align_to_view(context)
  514.        
  515.         return {'FINISHED'}
  516.  
  517.     def execute(self, context):        
  518.         align_to_view(context)
  519.        
  520.         return{'FINISHED'}
  521.  
  522. class PresetView3D(Operator):
  523.     bl_idname = "view3d.preset_view3d"
  524.     bl_label = "Preset View3D"
  525.  
  526.     view = StringProperty(name="View", description="Select the view", default='TOP',)
  527.  
  528.     def invoke(self, context, event):                  
  529.         tmp = bpy.context.user_preferences.view.smooth_view
  530.         bpy.context.user_preferences.view.smooth_view = 0
  531.         bpy.ops.view3d.viewnumpad(type=self.view)        
  532.         align_to_view(context)
  533.         bpy.context.user_preferences.view.smooth_view = tmp
  534.        
  535.         return {'FINISHED'}
  536.  
  537.  
  538. class PanView3D(bpy.types.Operator):
  539.     bl_idname = "view3d.pan_view3d"
  540.     bl_label = "Pan View3D"
  541.  
  542.    
  543.     first_mouse_x = 0
  544.     first_mouse_y = 0
  545.  
  546.     panx = 0
  547.     pany = 0
  548.  
  549.     def modal(self, context, event):
  550.         width = bpy.context.area.regions[4].width
  551.         height = bpy.context.area.regions[4].height
  552.  
  553.         deltax = event.mouse_region_x - self.first_mouse_x
  554.         deltay = event.mouse_region_y - self.first_mouse_y                
  555.                
  556.         l =  bpy.context.space_data.region_3d
  557.         vr = l.view_rotation
  558.        
  559.         v = Vector((deltax/max(width,height),deltay/max(width,height),0))
  560.         v.rotate(vr)
  561.        
  562.         pos = [0,0]
  563.         v1 = view3d_utils.region_2d_to_location_3d(bpy.context.region, l, pos, v)
  564.         pos = [width,height]
  565.         v2 = view3d_utils.region_2d_to_location_3d(bpy.context.region, l, pos, v)
  566.        
  567.         v3 = (v2 - v1)
  568.        
  569.         pos_init_cursor = view3d_utils.location_3d_to_region_2d(bpy.context.region, bpy.context.space_data.region_3d, bpy.context.space_data.cursor_location)
  570.        
  571.         bpy.context.space_data.region_3d.view_location -= v*v3.length
  572.        
  573.         bpy.context.space_data.region_3d.update()      
  574.         bpy.context.space_data.cursor_location = view3d_utils.region_2d_to_location_3d(bpy.context.region, bpy.context.space_data.region_3d, pos_init_cursor, Vector((0,0,0)))
  575.            
  576.         align_to_view(context)
  577.  
  578.         self.first_mouse_x = event.mouse_region_x
  579.         self.first_mouse_y = event.mouse_region_y
  580.  
  581.         if event.type == 'MIDDLEMOUSE'and event.value == 'RELEASE':
  582.             return {'FINISHED'}
  583.        
  584.         return {'RUNNING_MODAL'}
  585.                
  586.     def invoke(self, context, event):
  587.         context.window_manager.modal_handler_add(self)
  588.         self.first_mouse_x = event.mouse_region_x
  589.         self.first_mouse_y = event.mouse_region_y  
  590.        
  591.         return {'RUNNING_MODAL'}
  592.  
  593.     def execute(self, context):        
  594.         align_to_view(context)  
  595.        
  596.         return{'FINISHED'}
  597.  
  598. def update_func(self, context):          
  599.     v = Vector((0.5,0.5))
  600.     for i in range(4):
  601.         vres =  v - bpy.context.object.data.uv_loop_layers.active.data[len(bpy.context.object.data.uv_loop_layers.active.data)-1-i].uv
  602.         vres /= vres.length
  603.         for j in range(2):
  604.             if abs(vres[j-1])>0:
  605.                 vres[j-1] /= abs(vres[j-1])
  606.         bpy.context.object.data.uv_loop_layers.active.data[len(bpy.context.object.data.uv_loop_layers.active.data)-1-i].uv = v - vres*bpy.context.object.custom_scaleuv/2
  607.    
  608.     align_to_view(context)
  609.  
  610. def createcustomprops():
  611.     Ob = bpy.types.Object    
  612.     Ob.custom_rotation = IntProperty(name="Rotation", description="Rotate the plane", min=-180, max=180, default=0,update = update_func)
  613.     Ob.custom_scale = FloatProperty(name="Scale", description="Scale the plane", min=0, max=10, default=1.0,update = update_func)
  614.     Ob.custom_z = FloatProperty(name="Z", description="Z axis for the plane", min=-10, max=10, default=-1.0,update = update_func)
  615.     Ob.custom_scaleuv = FloatProperty(name="ScaleUV", description="Scale the texture's UV", min=1.0, max=10, default=1.0,update = update_func)
  616.     Ob.custom_location = IntVectorProperty(name="Location", description="Location of the plan", default=(0, 0), subtype = 'XYZ', size=2, update = update_func)
  617.     Ob.custom_c3d = BoolProperty(name="c3d", default=True)
  618.     Ob.custom_rot = BoolProperty(name="rot", default=True)
  619.  
  620. def register():
  621.     bpy.utils.register_module(__name__)
  622.     createcustomprops()
  623.  
  624. def unregister():
  625.     bpy.utils.unregister_module(__name__)
  626.  
  627. if __name__ == "__main__":
  628.     register()
  629.    
  630.        
go to heaven