forked from niewinny/Other-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextrude_plus.py
133 lines (108 loc) · 4 KB
/
extrude_plus.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import math
import bpy
from mathutils import Vector, Matrix
bl_info = {
"name": "Extrud Bay Distance",
"location": "View3D > Add > Mesh > Extrud Bay Distance",
"author": "Nedovizin Alexander, Vladislav Kindushov",
"version": (1, 0),
"blender": (2, 7, 9),
"category": "Mesh",
}
class ExtrudBayDistance(bpy.types.Operator):
"""Border Occlusion selection """
bl_idname = "view3d.extrud_bay_distance"
bl_label = "Extrud Bay Distance"
bl_options = {'REGISTER', 'UNDO'}
def modal(self, context, event):
context.area.tag_redraw()
bpy.ops.view3d.cursor3d('INVOKE_DEFAULT')
if self.x != event.mouse_x or self.y != event.mouse_y or self.dist == 0:
v1 = bpy.context.scene.cursor_location.copy()
v2 = self.main_position
self.x = event.mouse_x
self.y = event.mouse_y
dist = (v1 - v2).length
if self.is_set_dist:
self.dist = dist
draw_radius(self)
elif dist >= self.dist:
bpy.ops.mesh.dupli_extrude_cursor('INVOKE_DEFAULT', rotate_source=False)
self.main_position = bpy.context.scene.cursor_location.copy()
if event.type == 'LEFTMOUSE' and event.value == 'PRESS':
if self.is_set_dist:
self.is_set_dist = False
else:
self.dist = 0
self.is_set_dist = True
elif event.type == 'RIGHTMOUSE':
if self.is_set_dist:
self.main_position = bpy.context.scene.cursor_location.copy()
self.dist = 0
return {'PASS_THROUGH'}
else:
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'FINISHED'}
elif event.type in {'ESC'}:
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'CANCELLED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
bpy.ops.view3d.snap_cursor_to_selected()
self.main_position = bpy.context.scene.cursor_location.copy()
self.is_set_dist = True
self.dist = 0
self.x = event.mouse_x
self.y = event.mouse_y
ars = (self,)
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_radius, ars, 'WINDOW', 'POST_VIEW')
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
@property
def view(self):
""" Returns the set of 3D views.
"""
if bpy.context.area.type == 'VIEW_3D':
return bpy.context.area
else:
for area in bpy.context.window.screen.areas:
if area.type == 'VIEW_3D':
return area
return None
def draw_radius(self):
if not self.is_set_dist:
return
number_sides = int(self.dist * 20) + 10
angle_step = 2 * math.pi / number_sides
data_verts = []
q_rot = self.view.spaces[0].region_3d.view_matrix
for ns in range(number_sides):
angle = angle_step * ns
co = Vector((math.sin(angle) * self.dist,
math.cos(angle) * self.dist,
0)) * q_rot
co += self.main_position
data_verts.append(co)
data_verts.append(data_verts[0])
draw_point_line_gl(Matrix(), data_verts)
return True
def draw_point_line_gl(data_matrix, data_vector):
from bgl import glVertex3f, glLineWidth, glBegin, glEnd, GL_POINTS, GL_LINES, \
glDisable, GL_BLEND, glColor4f, GL_LINE_STRIP, GL_LINE_STIPPLE
# lines
glLineWidth(3.0)
glBegin(GL_LINE_STRIP)
glColor4f(0.0, 1.0, 0.0, 1.0)
for i, vector in enumerate(data_vector):
glVertex3f(*data_matrix * data_vector[i])
glEnd()
# restore opengl defaults
glDisable(GL_BLEND)
glLineWidth(1.0)
glColor4f(0.0, 0.0, 0.0, 1.0)
def register():
bpy.utils.register_class(ExtrudBayDistance)
def unregister():
bpy.utils.unregister_class(ExtrudBayDistance)
if __name__ == "__main__":
register()