1 ### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 3
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 # ##### END GPL LICENSE BLOCK #####
18 from mathutils
import Vector
28 'perpendicular_color',
29 'constrain_shift_color',
34 '_format_pos_and_color',
36 '_program_smooth_col',
39 def __init__(self
, out_color
, face_color
,
40 edge_color
, vert_color
, center_color
,
41 perpendicular_color
, constrain_shift_color
,
42 axis_x_color
, axis_y_color
, axis_z_color
):
46 self
.out_color
= out_color
47 self
.face_color
= face_color
48 self
.edge_color
= edge_color
49 self
.vert_color
= vert_color
50 self
.center_color
= center_color
51 self
.perpendicular_color
= perpendicular_color
52 self
.constrain_shift_color
= constrain_shift_color
54 self
.axis_x_color
= axis_x_color
55 self
.axis_y_color
= axis_y_color
56 self
.axis_z_color
= axis_z_color
58 self
._format
_pos
= gpu
.types
.GPUVertFormat()
59 self
._format
_pos
.attr_add(id="pos", comp_type
='F32', len=3, fetch_mode
='FLOAT')
61 self
._format
_pos
_and
_color
= gpu
.types
.GPUVertFormat()
62 self
._format
_pos
_and
_color
.attr_add(id="pos", comp_type
='F32', len=3, fetch_mode
='FLOAT')
63 self
._format
_pos
_and
_color
.attr_add(id="color", comp_type
='F32', len=4, fetch_mode
='FLOAT')
65 self
._program
_unif
_col
= gpu
.shader
.from_builtin("3D_UNIFORM_COLOR")
66 self
._program
_smooth
_col
= gpu
.shader
.from_builtin("3D_SMOOTH_COLOR")
68 self
._batch
_point
= None
71 def _gl_state_push(self
):
72 gpu
.state
.program_point_size_set(False)
73 gpu
.state
.blend_set('ALPHA')
75 def _gl_state_restore(self
):
76 gpu
.state
.blend_set('NONE')
78 def batch_line_strip_create(self
, coords
):
79 from gpu
.types
import (
84 vbo
= GPUVertBuf(self
._format
_pos
, len = len(coords
))
85 vbo
.attr_fill(0, data
= coords
)
86 batch_lines
= GPUBatch(type = "LINE_STRIP", buf
= vbo
)
89 def batch_lines_smooth_color_create(self
, coords
, colors
):
90 from gpu
.types
import (
95 vbo
= GPUVertBuf(self
._format
_pos
_and
_color
, len = len(coords
))
96 vbo
.attr_fill(0, data
= coords
)
97 vbo
.attr_fill(1, data
= colors
)
98 batch_lines
= GPUBatch(type = "LINES", buf
= vbo
)
101 def batch_triangles_create(self
, coords
):
102 from gpu
.types
import (
107 vbo
= GPUVertBuf(self
._format
_pos
, len = len(coords
))
108 vbo
.attr_fill(0, data
= coords
)
109 batch_tris
= GPUBatch(type = "TRIS", buf
= vbo
)
112 def batch_point_get(self
):
113 if self
._batch
_point
is None:
114 from gpu
.types
import (
118 vbo
= GPUVertBuf(self
._format
_pos
, len = 1)
119 vbo
.attr_fill(0, ((0.0, 0.0, 0.0),))
120 self
._batch
_point
= GPUBatch(type = "POINTS", buf
= vbo
)
121 return self
._batch
_point
123 def draw(self
, type, location
, list_verts_co
, vector_constrain
, prevloc
):
126 self
._gl
_state
_push
()
128 self
._program
_unif
_col
.bind()
131 # draw 3d line OpenGL in the 3D View
132 winmat
= gpu
.matrix
.get_projection_matrix()
133 winmat
[3][2] -= 0.0001
134 gpu
.matrix
.push_projection()
135 gpu
.matrix
.load_projection_matrix(winmat
)
136 gpu
.state
.line_width_set(3.0)
138 batch
= self
.batch_line_strip_create([v
.to_tuple() for v
in list_verts_co
] + [location
.to_tuple()])
140 self
._program
_unif
_col
.bind()
141 self
._program
_unif
_col
.uniform_float("color", (1.0, 0.8, 0.0, 0.5))
142 batch
.draw(self
._program
_unif
_col
)
143 gpu
.matrix
.pop_projection()
146 gpu
.state
.depth_test_set('NONE')
148 point_batch
= self
.batch_point_get()
151 gpu
.state
.point_size_set(5.0)
152 gpu
.matrix
.translate(prevloc
)
154 self
._program
_unif
_col
.bind()
155 self
._program
_unif
_col
.uniform_float("color", (1.0, 1.0, 1.0, 0.5))
156 point_batch
.draw(self
._program
_unif
_col
)
157 gpu
.matrix
.translate(-prevloc
)
159 if vector_constrain
[2] == 'X':
160 Color4f
= self
.axis_x_color
161 elif vector_constrain
[2] == 'Y':
162 Color4f
= self
.axis_y_color
163 elif vector_constrain
[2] == 'Z':
164 Color4f
= self
.axis_z_color
166 Color4f
= self
.constrain_shift_color
169 Color4f
= self
.out_color
171 Color4f
= self
.face_color
173 Color4f
= self
.edge_color
175 Color4f
= self
.vert_color
176 elif type == 'CENTER':
177 Color4f
= self
.center_color
178 elif type == 'PERPENDICULAR':
179 Color4f
= self
.perpendicular_color
181 Color4f
= self
.out_color
183 gpu
.state
.point_size_set(10.0)
185 gpu
.matrix
.translate(location
)
186 self
._program
_unif
_col
.bind()
187 self
._program
_unif
_col
.uniform_float("color", Color4f
)
188 point_batch
.draw(self
._program
_unif
_col
)
190 # restore opengl defaults
191 gpu
.state
.point_size_set(1.0)
192 gpu
.state
.line_width_set(1.0)
193 gpu
.state
.depth_test_set('LESS_EQUAL')
196 self
._gl
_state
_restore
()
198 def draw_elem(self
, snap_obj
, bm
, elem
):
199 #TODO: Cache coords (because antialiasing)
201 from bmesh
.types
import(
207 with gpu
.matrix
.push_pop():
208 self
._gl
_state
_push
()
209 gpu
.state
.depth_test_set('NONE')
211 gpu
.matrix
.multiply_matrix(snap_obj
.mat
)
213 if isinstance(elem
, BMVert
):
217 color
= self
.vert_color
218 edges
= np
.empty((len(elem
.link_edges
), 2), [("pos", "f4", 3), ("color", "f4", 4)])
219 edges
["pos"][:, 0] = elem
.co
220 edges
["pos"][:, 1] = [e
.other_vert(elem
).co
for e
in elem
.link_edges
]
221 edges
["color"][:, 0] = color
222 edges
["color"][:, 1] = (color
[0], color
[1], color
[2], 0.0)
225 self
._program
_smooth
_col
.bind()
226 gpu
.state
.line_width_set(3.0)
227 batch
= self
.batch_lines_smooth_color_create(edges
["pos"], edges
["color"])
228 batch
.draw(self
._program
_smooth
_col
)
229 gpu
.state
.line_width_set(1.0)
231 self
._program
_unif
_col
.bind()
233 if isinstance(elem
, BMEdge
):
234 self
._program
_unif
_col
.bind()
235 self
._program
_unif
_col
.uniform_float("color", self
.edge_color
)
237 gpu
.state
.line_width_set(3.0)
238 batch
= self
.batch_line_strip_create([v
.co
for v
in elem
.verts
])
239 batch
.draw(self
._program
_unif
_col
)
240 gpu
.state
.line_width_set(1.0)
242 elif isinstance(elem
, BMFace
):
243 if len(snap_obj
.data
) == 2:
244 face_color
= self
.face_color
[0], self
.face_color
[1], self
.face_color
[2], self
.face_color
[3] * 0.2
245 self
._program
_unif
_col
.bind()
246 self
._program
_unif
_col
.uniform_float("color", face_color
)
248 tris
= snap_obj
.data
[1].get_loop_tri_co_by_bmface(bm
, elem
)
250 batch
= self
.batch_triangles_create(tris
)
251 batch
.draw(self
._program
_unif
_col
)
253 # restore opengl defaults
254 gpu
.state
.depth_test_set('LESS_EQUAL')
256 self
._gl
_state
_restore
()