Correct some bugs

gpv2
Christophe SEUX 2021-06-17 15:36:28 +02:00
parent bfcac1615d
commit 9c7184836b
1 changed files with 74 additions and 26 deletions

View File

@ -2,6 +2,8 @@ import bpy
from bpy.types import Operator from bpy.types import Operator
import bgl import bgl
from gpu_extras.presets import draw_circle_2d from gpu_extras.presets import draw_circle_2d
from gpu_extras.batch import batch_for_shader
import gpu
from time import time from time import time
from mathutils import Vector, Matrix, Euler from mathutils import Vector, Matrix, Euler
from mathutils.kdtree import KDTree from mathutils.kdtree import KDTree
@ -9,6 +11,7 @@ from mathutils.geometry import intersect_line_plane, intersect_line_sphere_2d, i
from bpy_extras.view3d_utils import region_2d_to_location_3d, region_2d_to_vector_3d, \ from bpy_extras.view3d_utils import region_2d_to_location_3d, region_2d_to_vector_3d, \
location_3d_to_region_2d, region_2d_to_origin_3d, region_2d_to_location_3d location_3d_to_region_2d, region_2d_to_origin_3d, region_2d_to_location_3d
from time import time from time import time
from math import pi, cos, sin
def get_gp_mat(gp, name, set_active=False): def get_gp_mat(gp, name, set_active=False):
@ -83,6 +86,7 @@ def get_cuts_data(strokes, mouse, radius):
if not is_polyline and not s.select: if not is_polyline and not s.select:
continue continue
print('Cut Stroke', s)
for i, p in enumerate(s.points): for i, p in enumerate(s.points):
if not p.select and not is_polyline: if not p.select and not is_polyline:
@ -132,15 +136,20 @@ def get_cuts_data(strokes, mouse, radius):
continue continue
print('intersects', intersects)
line_intersects = [] line_intersects = []
for i_2d in intersects: for i_2d in intersects:
#factor = ((i_2d-p1_2d).length) / length_2d #factor = ((i_2d-p1_2d).length) / length_2d
#factor_3d = factor_2d * length_3d #factor_3d = factor_2d * length_3d
#vec = region_2d_to_vector_3d(region, rv3d, i_2d) #vec = region_2d_to_vector_3d(region, rv3d, i_2d)
p3_3d = region_2d_to_location_3d(region, rv3d, i_2d, org) #p3_3d = region_2d_to_location_3d(region, rv3d, i_2d, org)
p4_3d = region_2d_to_origin_3d(region, rv3d, i_2d) #p4_3d = region_2d_to_origin_3d(region, rv3d, i_2d)
#bpy.context.scene.cursor.location = p3_3d p3_3d = co_2d_to_3d(i_2d, 0.1)
p4_3d = co_2d_to_3d(i_2d, 1000)
#bpy.context.scene.cursor.location = p4_3d
line_intersect = intersect_line_line(p1_3d, p2_3d, p3_3d, p4_3d) line_intersect = intersect_line_line(p1_3d, p2_3d, p3_3d, p4_3d)
if not line_intersect: if not line_intersect:
@ -153,6 +162,7 @@ def get_cuts_data(strokes, mouse, radius):
#context.scene.cursor.location = i1_3d #context.scene.cursor.location = i1_3d
print('line_intersects', line_intersects)
if line_intersects: if line_intersects:
line_intersects.sort(key=lambda x : (x-p1_3d).length) line_intersects.sort(key=lambda x : (x-p1_3d).length)
#cut_data[-1].sort(key=lambda x : (x-p1_3d).length) #cut_data[-1].sort(key=lambda x : (x-p1_3d).length)
@ -161,6 +171,18 @@ def get_cuts_data(strokes, mouse, radius):
return cuts_data return cuts_data
def circle(x, y, radius, segments):
coords = []
m = (1.0 / (segments - 1)) * (pi * 2)
for p in range(segments):
p1 = x + cos(m * p) * radius
p2 = y + sin(m * p) * radius
coords.append((p1, p2))
return coords
class GPTB_OT_eraser(Operator): class GPTB_OT_eraser(Operator):
"""Draw a line with the mouse""" """Draw a line with the mouse"""
bl_idname = "gp.eraser" bl_idname = "gp.eraser"
@ -169,9 +191,30 @@ class GPTB_OT_eraser(Operator):
def draw_callback_px(self): def draw_callback_px(self):
bgl.glEnable(bgl.GL_BLEND) bgl.glEnable(bgl.GL_BLEND)
draw_circle_2d(self.mouse, (0.75, 0.25, 0.35, 0.85), self.radius, 32) #bgl.glBlendFunc(bgl.GL_CONSTANT_ALPHA, bgl.GL_ONE_MINUS_CONSTANT_ALPHA)
#bgl.glBlendColor(1.0, 1.0, 1.0, 0.1)
area = bpy.context.area
#region = bpy.context.region
#rv3d = area.spaces.active.region_3d
bg_color = area.spaces.active.shading.background_color
#print(bg_color)
shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
shader.bind()
shader.uniform_float("color", (1, 1, 1, 1))
for mouse in self.mouse_path:
circle_co = circle(*mouse, self.radius, 24)
batch = batch_for_shader(shader, 'TRI_FAN', {"pos": circle_co})
batch.draw(shader)
draw_circle_2d(self.mouse, (0.75, 0.25, 0.35, 1.0), self.radius, 24)
bgl.glDisable(bgl.GL_BLEND) bgl.glDisable(bgl.GL_BLEND)
'''
def draw_holdout(self, context, event): def draw_holdout(self, context, event):
gp = context.object gp = context.object
mat_inv = gp.matrix_world.inverted() mat_inv = gp.matrix_world.inverted()
@ -193,7 +236,7 @@ class GPTB_OT_eraser(Operator):
p.pressure = search_radius * 2000 p.pressure = search_radius * 2000
#context.scene.cursor.location = mouse_3d #context.scene.cursor.location = mouse_3d
'''
def get_radius(self, context, event): def get_radius(self, context, event):
pressure = event.pressure or 1 pressure = event.pressure or 1
return context.scene.gptoolprops.eraser_radius * pressure return context.scene.gptoolprops.eraser_radius * pressure
@ -209,12 +252,12 @@ class GPTB_OT_eraser(Operator):
#print(self.cuts_data) #print(self.cuts_data)
for f in self.gp_frames: # for f in self.gp_frames:
for s in [s for s in f.strokes if s.material_index==self.hld_index]: # for s in [s for s in f.strokes if s.material_index==self.hld_index]:
f.strokes.remove(s) # f.strokes.remove(s)
gp.data.materials.pop(index=self.hld_index) #gp.data.materials.pop(index=self.hld_index)
bpy.data.materials.remove(self.hld_mat) #bpy.data.materials.remove(self.hld_mat)
bpy.ops.object.mode_set(mode='EDIT_GPENCIL') bpy.ops.object.mode_set(mode='EDIT_GPENCIL')
@ -229,7 +272,7 @@ class GPTB_OT_eraser(Operator):
t0 = time() t0 = time()
print() print()
print('Number of cuts', len(self.mouse_path)) #print('Number of cuts', len(self.mouse_path))
for mouse in self.mouse_path: for mouse in self.mouse_path:
t1 = time() t1 = time()
@ -240,11 +283,14 @@ class GPTB_OT_eraser(Operator):
bpy.ops.gpencil.select_circle(x=x, y=y, radius=self.radius, wait_for_input=False) bpy.ops.gpencil.select_circle(x=x, y=y, radius=self.radius, wait_for_input=False)
strokes = [s for f in self.gp_frames for s in f.strokes] strokes = [s for f in self.gp_frames for s in f.strokes]
print('select_circle', time()-t1) #print('select_circle', time()-t1)
t2 = time() t2 = time()
cut_data = get_cuts_data(strokes, mouse, self.radius) cut_data = get_cuts_data(strokes, mouse, self.radius)
print('get_cuts_data', time()-t2) #print('get_cuts_data', time()-t2)
#print([s for s in strokes if s.select])
print('cut_data', cut_data)
t3 = time() t3 = time()
for p1_index, p2_index, stroke, intersects in cut_data[::-1]: for p1_index, p2_index, stroke, intersects in cut_data[::-1]:
@ -263,7 +309,6 @@ class GPTB_OT_eraser(Operator):
bpy.ops.gpencil.stroke_subdivide(number_cuts=number_cuts, only_selected=True) bpy.ops.gpencil.stroke_subdivide(number_cuts=number_cuts, only_selected=True)
new_p1 = stroke.points[p1_index+1] new_p1 = stroke.points[p1_index+1]
new_p1.co = mat_inv@intersects[0] new_p1.co = mat_inv@intersects[0]
new_points += [(stroke, p1_index+1)] new_points += [(stroke, p1_index+1)]
@ -279,9 +324,11 @@ class GPTB_OT_eraser(Operator):
new_p3.co = mat_inv@intersects[1] new_p3.co = mat_inv@intersects[1]
new_points += [(stroke, p1_index+3)] new_points += [(stroke, p1_index+3)]
print('subdivide', time() - t3) #print('subdivide', time() - t3)
bpy.ops.gpencil.select_circle(x=x, y=y, radius=self.radius-2, wait_for_input=False)
bpy.ops.gpencil.select_all(action='DESELECT')
bpy.ops.gpencil.select_circle(x=x, y=y, radius=self.radius-4, wait_for_input=False)
''' '''
selected_strokes = [s for f in self.gp_frames for s in f.strokes if s.select] selected_strokes = [s for f in self.gp_frames for s in f.strokes if s.select]
@ -304,9 +351,9 @@ class GPTB_OT_eraser(Operator):
print('remove points', time()- t4) print('remove points', time()- t4)
print('Total one cut', time()-t1) #print('Total one cut', time()-t1)
print('Total all cuts', time()-t0) #print('Total all cuts', time()-t0)
#bpy.ops.gpencil.select_less() #bpy.ops.gpencil.select_less()
#for stroke, index in new_points: #for stroke, index in new_points:
# stroke.points[index].select = False # stroke.points[index].select = False
@ -317,7 +364,7 @@ class GPTB_OT_eraser(Operator):
#bpy.ops.object.mode_set(mode='PAINT_GPENCIL') #bpy.ops.object.mode_set(mode='PAINT_GPENCIL')
def modal(self, context, event): def modal(self, context, event):
mouse = Vector((event.mouse_region_x, event.mouse_region_y)) self.mouse = Vector((event.mouse_region_x, event.mouse_region_y))
self.radius = self.get_radius(context, event) self.radius = self.get_radius(context, event)
context.area.tag_redraw() context.area.tag_redraw()
@ -329,13 +376,13 @@ class GPTB_OT_eraser(Operator):
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
return {'FINISHED'} return {'FINISHED'}
if (mouse-self.mouse).length < min(self.radius, 2): if (self.mouse-self.mouse_prev).length < max(self.radius/1.33, 2):
return {'RUNNING_MODAL'} return {'RUNNING_MODAL'}
self.mouse = mouse self.mouse_prev = self.mouse
if event.type in {'MOUSEMOVE', 'INBETWEEN_MOUSEMOVE'}: if event.type in {'MOUSEMOVE', 'INBETWEEN_MOUSEMOVE'}:
self.draw_holdout(context, event) #self.draw_holdout(context, event)
self.mouse_path.append(self.mouse) self.mouse_path.append(self.mouse)
#self.update_cuts_data(context, event) #self.update_cuts_data(context, event)
#self.erase(context, event) #self.erase(context, event)
@ -351,8 +398,8 @@ class GPTB_OT_eraser(Operator):
gp = context.object gp = context.object
matrix = gp.matrix_world matrix = gp.matrix_world
self.mouse = Vector((event.mouse_region_x, event.mouse_region_y)) self.mouse_prev = Vector((event.mouse_region_x, event.mouse_region_y))
self.mouse_path = [self.mouse] self.mouse_path = [self.mouse_prev]
area = context.area area = context.area
region = context.region region = context.region
@ -421,6 +468,7 @@ class GPTB_OT_eraser(Operator):
print('create kdtree', time()-t0) print('create kdtree', time()-t0)
''' '''
'''
# Create holdout mat # Create holdout mat
self.hld_mat = get_gp_mat(gp, name='Eraser Holdout Stroke') self.hld_mat = get_gp_mat(gp, name='Eraser Holdout Stroke')
self.hld_mat.grease_pencil.use_stroke_holdout = True self.hld_mat.grease_pencil.use_stroke_holdout = True
@ -442,7 +490,7 @@ class GPTB_OT_eraser(Operator):
self.hld_strokes.append((f, hld_stroke)) self.hld_strokes.append((f, hld_stroke))
self.draw_holdout(context, event) self.draw_holdout(context, event)
'''
context.area.tag_redraw() context.area.tag_redraw()