Correct some bugs
This commit is contained in:
		
							parent
							
								
									bfcac1615d
								
							
						
					
					
						commit
						9c7184836b
					
				@ -2,6 +2,8 @@ import bpy
 | 
			
		||||
from bpy.types import Operator
 | 
			
		||||
import bgl
 | 
			
		||||
from gpu_extras.presets import draw_circle_2d
 | 
			
		||||
from gpu_extras.batch import batch_for_shader
 | 
			
		||||
import gpu
 | 
			
		||||
from time import time
 | 
			
		||||
from mathutils import Vector, Matrix, Euler
 | 
			
		||||
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, \
 | 
			
		||||
location_3d_to_region_2d, region_2d_to_origin_3d, region_2d_to_location_3d
 | 
			
		||||
from time import time
 | 
			
		||||
from math import pi, cos, sin
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
            continue
 | 
			
		||||
        
 | 
			
		||||
        print('Cut Stroke', s)
 | 
			
		||||
        for i, p in enumerate(s.points):
 | 
			
		||||
            
 | 
			
		||||
            if not p.select and not is_polyline:
 | 
			
		||||
@ -132,15 +136,20 @@ def get_cuts_data(strokes, mouse, radius):
 | 
			
		||||
                    continue
 | 
			
		||||
                    
 | 
			
		||||
                
 | 
			
		||||
                print('intersects', intersects)
 | 
			
		||||
 | 
			
		||||
                line_intersects = []
 | 
			
		||||
                for i_2d in intersects:                            
 | 
			
		||||
                    #factor = ((i_2d-p1_2d).length) / length_2d
 | 
			
		||||
                    #factor_3d = factor_2d * length_3d
 | 
			
		||||
                    #vec = region_2d_to_vector_3d(region, rv3d, i_2d)
 | 
			
		||||
                    p3_3d = region_2d_to_location_3d(region, rv3d, i_2d, org)
 | 
			
		||||
                    p4_3d = region_2d_to_origin_3d(region, rv3d, i_2d)
 | 
			
		||||
                    #p3_3d = region_2d_to_location_3d(region, rv3d, i_2d, org)
 | 
			
		||||
                    #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)
 | 
			
		||||
                    if not line_intersect:
 | 
			
		||||
@ -153,6 +162,7 @@ def get_cuts_data(strokes, mouse, radius):
 | 
			
		||||
                    
 | 
			
		||||
                    #context.scene.cursor.location = i1_3d
 | 
			
		||||
                
 | 
			
		||||
                print('line_intersects', line_intersects)
 | 
			
		||||
                if line_intersects:
 | 
			
		||||
                    line_intersects.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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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):
 | 
			
		||||
    """Draw a line with the mouse"""
 | 
			
		||||
    bl_idname = "gp.eraser"
 | 
			
		||||
@ -169,9 +191,30 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
 | 
			
		||||
    def draw_callback_px(self):
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    '''
 | 
			
		||||
    def draw_holdout(self, context, event):
 | 
			
		||||
        gp = context.object
 | 
			
		||||
        mat_inv = gp.matrix_world.inverted()
 | 
			
		||||
@ -193,7 +236,7 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
            p.pressure = search_radius * 2000
 | 
			
		||||
            
 | 
			
		||||
            #context.scene.cursor.location = mouse_3d
 | 
			
		||||
            
 | 
			
		||||
    '''
 | 
			
		||||
    def get_radius(self, context, event):
 | 
			
		||||
        pressure = event.pressure or 1
 | 
			
		||||
        return context.scene.gptoolprops.eraser_radius * pressure
 | 
			
		||||
@ -209,12 +252,12 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
        
 | 
			
		||||
        #print(self.cuts_data)
 | 
			
		||||
        
 | 
			
		||||
        for f in self.gp_frames:
 | 
			
		||||
            for s in [s for s in f.strokes if s.material_index==self.hld_index]:
 | 
			
		||||
                f.strokes.remove(s)
 | 
			
		||||
       # for f in self.gp_frames:
 | 
			
		||||
       #     for s in [s for s in f.strokes if s.material_index==self.hld_index]:
 | 
			
		||||
       #         f.strokes.remove(s)
 | 
			
		||||
        
 | 
			
		||||
        gp.data.materials.pop(index=self.hld_index)
 | 
			
		||||
        bpy.data.materials.remove(self.hld_mat)  
 | 
			
		||||
        #gp.data.materials.pop(index=self.hld_index)
 | 
			
		||||
        #bpy.data.materials.remove(self.hld_mat)  
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        bpy.ops.object.mode_set(mode='EDIT_GPENCIL')
 | 
			
		||||
@ -229,7 +272,7 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
        t0 = time()
 | 
			
		||||
        print()
 | 
			
		||||
        
 | 
			
		||||
        print('Number of cuts', len(self.mouse_path))
 | 
			
		||||
        #print('Number of cuts', len(self.mouse_path))
 | 
			
		||||
        
 | 
			
		||||
        for mouse in self.mouse_path:
 | 
			
		||||
            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)
 | 
			
		||||
            
 | 
			
		||||
            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()
 | 
			
		||||
            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()
 | 
			
		||||
            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)
 | 
			
		||||
                
 | 
			
		||||
                
 | 
			
		||||
                new_p1 = stroke.points[p1_index+1]
 | 
			
		||||
                new_p1.co = mat_inv@intersects[0]
 | 
			
		||||
                new_points += [(stroke, p1_index+1)]
 | 
			
		||||
@ -279,9 +324,11 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
                    new_p3.co = mat_inv@intersects[1]
 | 
			
		||||
                    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]
 | 
			
		||||
@ -304,9 +351,9 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
            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()
 | 
			
		||||
        #for stroke, index in new_points:
 | 
			
		||||
        #    stroke.points[index].select = False
 | 
			
		||||
@ -317,7 +364,7 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
        #bpy.ops.object.mode_set(mode='PAINT_GPENCIL')
 | 
			
		||||
                
 | 
			
		||||
    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)
 | 
			
		||||
        context.area.tag_redraw()
 | 
			
		||||
@ -329,13 +376,13 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
            bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
 | 
			
		||||
            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'}    
 | 
			
		||||
            
 | 
			
		||||
        self.mouse = mouse
 | 
			
		||||
        self.mouse_prev = self.mouse
 | 
			
		||||
        
 | 
			
		||||
        if event.type in {'MOUSEMOVE', 'INBETWEEN_MOUSEMOVE'}:
 | 
			
		||||
            self.draw_holdout(context, event)
 | 
			
		||||
            #self.draw_holdout(context, event)
 | 
			
		||||
            self.mouse_path.append(self.mouse)
 | 
			
		||||
            #self.update_cuts_data(context, event)
 | 
			
		||||
            #self.erase(context, event)
 | 
			
		||||
@ -351,8 +398,8 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
        gp = context.object
 | 
			
		||||
        matrix = gp.matrix_world
 | 
			
		||||
        
 | 
			
		||||
        self.mouse = Vector((event.mouse_region_x, event.mouse_region_y))
 | 
			
		||||
        self.mouse_path = [self.mouse]
 | 
			
		||||
        self.mouse_prev = Vector((event.mouse_region_x, event.mouse_region_y))
 | 
			
		||||
        self.mouse_path = [self.mouse_prev]
 | 
			
		||||
        
 | 
			
		||||
        area = context.area
 | 
			
		||||
        region = context.region
 | 
			
		||||
@ -421,6 +468,7 @@ class GPTB_OT_eraser(Operator):
 | 
			
		||||
        print('create kdtree', time()-t0)
 | 
			
		||||
        '''
 | 
			
		||||
        
 | 
			
		||||
        '''
 | 
			
		||||
        # Create holdout mat
 | 
			
		||||
        self.hld_mat = get_gp_mat(gp, name='Eraser Holdout Stroke')
 | 
			
		||||
        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.draw_holdout(context, event)
 | 
			
		||||
        
 | 
			
		||||
        '''
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        context.area.tag_redraw()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user