New Grease Pencil object for 2D animation
This commit merge the full development done in greasepencil-object branch and include mainly the following features. - New grease pencil object. - New drawing engine. - New grease pencil modes Draw/Sculpt/Edit and Weight Paint. - New brushes for grease pencil. - New modifiers for grease pencil. - New shaders FX. - New material system (replace old palettes and colors). - Split of annotations (old grease pencil) and new grease pencil object. - UI adapted to blender 2.8. You can get more info here: https://code.blender.org/2017/12/drawing-2d-animation-in-blender-2-8/ https://code.blender.org/2018/07/grease-pencil-status-update/ This is the result of nearly two years of development and I want thanks firstly the other members of the grease pencil team: Daniel M. Lara, Matias Mendiola and Joshua Leung for their support, ideas and to keep working in the project all the time, without them this project had been impossible. Also, I want thanks other Blender developers for their help, advices and to be there always to help me, and specially to Clément Foucault, Dalai Felinto, Pablo Vázquez and Campbell Barton.
@@ -598,12 +598,12 @@ function(SETUP_BLENDER_SORTED_LIBS)
 | 
			
		||||
		bf_editor_util
 | 
			
		||||
		bf_editor_uvedit
 | 
			
		||||
		bf_editor_curve
 | 
			
		||||
		bf_editor_gpencil
 | 
			
		||||
		bf_editor_interface
 | 
			
		||||
		bf_editor_gizmo_library
 | 
			
		||||
		bf_editor_mesh
 | 
			
		||||
		bf_editor_metaball
 | 
			
		||||
		bf_editor_object
 | 
			
		||||
		bf_editor_gpencil
 | 
			
		||||
		bf_editor_lattice
 | 
			
		||||
		bf_editor_armature
 | 
			
		||||
		bf_editor_physics
 | 
			
		||||
@@ -626,12 +626,15 @@ function(SETUP_BLENDER_SORTED_LIBS)
 | 
			
		||||
		bf_freestyle
 | 
			
		||||
		bf_ikplugin
 | 
			
		||||
		bf_modifiers
 | 
			
		||||
		bf_gpencil_modifiers
 | 
			
		||||
		bf_alembic
 | 
			
		||||
		bf_bmesh
 | 
			
		||||
		bf_gpu
 | 
			
		||||
		bf_draw
 | 
			
		||||
		bf_blenloader
 | 
			
		||||
		bf_blenkernel
 | 
			
		||||
		bf_shader_fx
 | 
			
		||||
		bf_gpencil_modifiers
 | 
			
		||||
		bf_physics
 | 
			
		||||
		bf_nodes
 | 
			
		||||
		bf_rna
 | 
			
		||||
 
 | 
			
		||||
@@ -895,7 +895,10 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        return (context.material or context.object) and CyclesButtonsPanel.poll(context)
 | 
			
		||||
        if context.active_object and context.active_object.type == 'GPENCIL':
 | 
			
		||||
            return False
 | 
			
		||||
        else:
 | 
			
		||||
            return (context.material or context.object) and CyclesButtonsPanel.poll(context)
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_block.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_clone.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_erase_hard.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_erase_soft.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_erase_stroke.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_fill.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_grab.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_ink.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_inknoise.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_marker.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_pen.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_pencil.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_pinch.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_push.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_randomize.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_smooth.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_strength.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_thickness.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_twist.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/brushicons/gp_brush_weight.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw.eraser_hard.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw.eraser_soft.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw.eraser_stroke.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw_block.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw_fill.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw_ink.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw_marker.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw_noise.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw_pen.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/brush.gpencil.draw_pencil.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.draw.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.draw.eraser.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.draw.line.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.draw.poly.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.edit_bend.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.edit_mirror.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.edit_shear.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.edit_to_sphere.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_clone.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_grab.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_pinch.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_push.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_randomize.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_smooth.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_strength.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_thickness.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_twist.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/icons/ops.gpencil.sculpt_weight.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								release/datafiles/preview_grease_pencil.blend
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -1,8 +1,8 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Generated by 'source/tools/utils/blender_theme_as_c.py'
 | 
			
		||||
 *
 | 
			
		||||
 * Do not hand edit this file!
 | 
			
		||||
 */
 | 
			
		||||
* Generated by 'source/tools/utils/blender_theme_as_c.py'
 | 
			
		||||
*
 | 
			
		||||
* Do not hand edit this file!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "DNA_userdef_types.h"
 | 
			
		||||
 | 
			
		||||
@@ -1040,5 +1040,5 @@ const bTheme U_theme_default = {
 | 
			
		||||
			.select = RGBA(0x000000ff),
 | 
			
		||||
			.active = RGBA(0x000000ff),
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
},
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -121,6 +121,12 @@ KM_HIERARCHY = [
 | 
			
		||||
 | 
			
		||||
    ('Grease Pencil', 'EMPTY', 'WINDOW', [  # grease pencil stuff (per region)
 | 
			
		||||
        ('Grease Pencil Stroke Edit Mode', 'EMPTY', 'WINDOW', []),
 | 
			
		||||
        ('Grease Pencil Stroke Paint (Draw brush)', 'EMPTY', 'WINDOW', []),
 | 
			
		||||
        ('Grease Pencil Stroke Paint (Fill)', 'EMPTY', 'WINDOW', []),
 | 
			
		||||
        ('Grease Pencil Stroke Paint (Erase)', 'EMPTY', 'WINDOW', []),
 | 
			
		||||
        ('Grease Pencil Stroke Paint Mode', 'EMPTY', 'WINDOW', []),
 | 
			
		||||
        ('Grease Pencil Stroke Sculpt Mode', 'EMPTY', 'WINDOW', []),
 | 
			
		||||
        ('Grease Pencil Stroke Weight Mode', 'EMPTY', 'WINDOW', []),
 | 
			
		||||
    ]),
 | 
			
		||||
    ('Mask Editing', 'EMPTY', 'WINDOW', []),
 | 
			
		||||
    ('Frames', 'EMPTY', 'WINDOW', []),    # frame navigation (per region)
 | 
			
		||||
 
 | 
			
		||||
@@ -670,6 +670,42 @@ class AddPresetUnitsLength(AddPresetBase, Operator):
 | 
			
		||||
    preset_subdir = "units_length"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AddPresetGpencilBrush(AddPresetBase, Operator):
 | 
			
		||||
    """Add or remove grease pencil brush preset"""
 | 
			
		||||
    bl_idname = "scene.gpencil_brush_preset_add"
 | 
			
		||||
    bl_label = "Add Grease Pencil Brush Preset"
 | 
			
		||||
    preset_menu = "VIEW3D_PT_gpencil_brush_presets"
 | 
			
		||||
 | 
			
		||||
    preset_defines = [
 | 
			
		||||
        "brush = bpy.context.active_gpencil_brush",
 | 
			
		||||
        "settings = brush.gpencil_settings"
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    preset_values = [
 | 
			
		||||
        "settings.input_samples",
 | 
			
		||||
        "settings.active_smooth_factor",
 | 
			
		||||
        "settings.angle",
 | 
			
		||||
        "settings.angle_factor",
 | 
			
		||||
        "settings.use_stabilizer",
 | 
			
		||||
        "brush.smooth_stroke_radius",
 | 
			
		||||
        "brush.smooth_stroke_factor",
 | 
			
		||||
        "settings.pen_smooth_factor",
 | 
			
		||||
        "settings.pen_smooth_steps",
 | 
			
		||||
        "settings.pen_thick_smooth_factor",
 | 
			
		||||
        "settings.pen_thick_smooth_steps",
 | 
			
		||||
        "settings.pen_subdivision_steps",
 | 
			
		||||
        "settings.random_subdiv",
 | 
			
		||||
        "settings.enable_random",
 | 
			
		||||
        "settings.random_pressure",
 | 
			
		||||
        "settings.random_strength",
 | 
			
		||||
        "settings.uv_random",
 | 
			
		||||
        "settings.pen_jitter",
 | 
			
		||||
        "settings.use_jitter_pressure",
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    preset_subdir = "gpencil_brush"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
classes = (
 | 
			
		||||
    AddPresetCamera,
 | 
			
		||||
    AddPresetCloth,
 | 
			
		||||
@@ -686,6 +722,7 @@ classes = (
 | 
			
		||||
    AddPresetTrackingSettings,
 | 
			
		||||
    AddPresetTrackingTrackColor,
 | 
			
		||||
    AddPresetUnitsLength,
 | 
			
		||||
    AddPresetGpencilBrush,
 | 
			
		||||
    ExecutePreset,
 | 
			
		||||
    WM_MT_operator_presets,
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -34,16 +34,19 @@ _modules = [
 | 
			
		||||
    "properties_data_camera",
 | 
			
		||||
    "properties_data_curve",
 | 
			
		||||
    "properties_data_empty",
 | 
			
		||||
    "properties_data_gpencil",
 | 
			
		||||
    "properties_data_light",
 | 
			
		||||
    "properties_data_lattice",
 | 
			
		||||
    "properties_data_mesh",
 | 
			
		||||
    "properties_data_metaball",
 | 
			
		||||
    "properties_data_modifier",
 | 
			
		||||
    "properties_data_shaderfx",
 | 
			
		||||
    "properties_data_lightprobe",
 | 
			
		||||
    "properties_data_speaker",
 | 
			
		||||
    "properties_data_workspace",
 | 
			
		||||
    "properties_mask_common",
 | 
			
		||||
    "properties_material",
 | 
			
		||||
    "properties_material_gpencil",
 | 
			
		||||
    "properties_object",
 | 
			
		||||
    "properties_paint_common",
 | 
			
		||||
    "properties_grease_pencil_common",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										402
									
								
								release/scripts/startup/bl_ui/properties_data_gpencil.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,402 @@
 | 
			
		||||
# ##### BEGIN GPL LICENSE BLOCK #####
 | 
			
		||||
#
 | 
			
		||||
#  This program is free software; you can redistribute it and/or
 | 
			
		||||
#  modify it under the terms of the GNU General Public License
 | 
			
		||||
#  as published by the Free Software Foundation; either version 2
 | 
			
		||||
#  of the License, or (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
#  This program is distributed in the hope that it will be useful,
 | 
			
		||||
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
#  GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
#  You should have received a copy of the GNU General Public License
 | 
			
		||||
#  along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
#
 | 
			
		||||
# ##### END GPL LICENSE BLOCK #####
 | 
			
		||||
 | 
			
		||||
# <pep8 compliant>
 | 
			
		||||
import bpy
 | 
			
		||||
from bpy.types import Menu, Panel, UIList
 | 
			
		||||
from rna_prop_ui import PropertyPanel
 | 
			
		||||
from .properties_grease_pencil_common import (
 | 
			
		||||
        GreasePencilDataPanel,
 | 
			
		||||
        GreasePencilOnionPanel,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
###############################
 | 
			
		||||
# Base-Classes (for shared stuff - e.g. poll, attributes, etc.)
 | 
			
		||||
 | 
			
		||||
class DataButtonsPanel:
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "data"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        return context.object and context.object.type == 'GPENCIL'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LayerDataButtonsPanel:
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "data"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        return (context.object and
 | 
			
		||||
                context.object.type == 'GPENCIL' and
 | 
			
		||||
                context.active_gpencil_layer)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###############################
 | 
			
		||||
# GP Object Properties Panels and Helper Classes
 | 
			
		||||
 | 
			
		||||
class DATA_PT_gpencil(DataButtonsPanel, Panel):
 | 
			
		||||
    bl_label = ""
 | 
			
		||||
    bl_options = {'HIDE_HEADER'}
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        # Grease Pencil data selector
 | 
			
		||||
        gpd_owner = context.gpencil_data_owner
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
 | 
			
		||||
        layout.template_ID(gpd_owner, "data")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GPENCIL_UL_layer(UIList):
 | 
			
		||||
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
 | 
			
		||||
        # assert(isinstance(item, bpy.types.GPencilLayer)
 | 
			
		||||
        gpl = item
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
 | 
			
		||||
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
 | 
			
		||||
            if gpl.lock:
 | 
			
		||||
                layout.active = False
 | 
			
		||||
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
            if gpl.is_parented:
 | 
			
		||||
                icon = 'BONE_DATA'
 | 
			
		||||
            else:
 | 
			
		||||
                icon = 'BLANK1'
 | 
			
		||||
 | 
			
		||||
            row.label(text="", icon=icon)
 | 
			
		||||
            row.prop(gpl, "info", text="", emboss=False)
 | 
			
		||||
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
            row.prop(gpl, "lock", text="", emboss=False)
 | 
			
		||||
            row.prop(gpl, "hide", text="", emboss=False)
 | 
			
		||||
            row.prop(gpl, "unlock_color", text="", emboss=False)
 | 
			
		||||
            if gpl.use_onion_skinning is False:
 | 
			
		||||
                icon = 'GHOST_DISABLED'
 | 
			
		||||
            else:
 | 
			
		||||
                icon = 'GHOST_ENABLED'
 | 
			
		||||
            subrow = row.row(align=True)
 | 
			
		||||
            subrow.prop(gpl, "use_onion_skinning", text="", icon=icon, emboss=False)
 | 
			
		||||
            subrow.active = gpd.use_onion_skinning
 | 
			
		||||
        elif self.layout_type == 'GRID':
 | 
			
		||||
            layout.alignment = 'CENTER'
 | 
			
		||||
            layout.label(text="", icon_value=icon)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GPENCIL_MT_layer_specials(Menu):
 | 
			
		||||
    bl_label = "Layer"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.layer_duplicate", icon='COPY_ID')  # XXX: needs a dedicated icon
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
 | 
			
		||||
        layout.operator("gpencil.hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All")
 | 
			
		||||
        layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.layer_merge", icon='NLA', text="Merge Down")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_gpencil_datapanel(Panel):
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "data"
 | 
			
		||||
    bl_label = "Layers"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        if context.gpencil_data is None:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        if ob is not None and ob.type == 'GPENCIL':
 | 
			
		||||
            return True
 | 
			
		||||
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        #layout.use_property_split = True
 | 
			
		||||
        layout.use_property_decorate = False
 | 
			
		||||
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
 | 
			
		||||
        # Grease Pencil data...
 | 
			
		||||
        if (gpd is None) or (not gpd.layers):
 | 
			
		||||
            layout.operator("gpencil.layer_add", text="New Layer")
 | 
			
		||||
        else:
 | 
			
		||||
            self.draw_layers(context, layout, gpd)
 | 
			
		||||
 | 
			
		||||
    def draw_layers(self, context, layout, gpd):
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
 | 
			
		||||
        col = row.column()
 | 
			
		||||
        if len(gpd.layers) >= 2:
 | 
			
		||||
            layer_rows = 5
 | 
			
		||||
        else:
 | 
			
		||||
            layer_rows = 2
 | 
			
		||||
        col.template_list("GPENCIL_UL_layer", "", gpd, "layers", gpd.layers, "active_index", rows=layer_rows)
 | 
			
		||||
 | 
			
		||||
        col = row.column()
 | 
			
		||||
 | 
			
		||||
        sub = col.column(align=True)
 | 
			
		||||
        sub.operator("gpencil.layer_add", icon='ZOOMIN', text="")
 | 
			
		||||
        sub.operator("gpencil.layer_remove", icon='ZOOMOUT', text="")
 | 
			
		||||
 | 
			
		||||
        gpl = context.active_gpencil_layer
 | 
			
		||||
        if gpl:
 | 
			
		||||
            sub.menu("GPENCIL_MT_layer_specials", icon='DOWNARROW_HLT', text="")
 | 
			
		||||
 | 
			
		||||
            if len(gpd.layers) > 1:
 | 
			
		||||
                col.separator()
 | 
			
		||||
 | 
			
		||||
                sub = col.column(align=True)
 | 
			
		||||
                sub.operator("gpencil.layer_move", icon='TRIA_UP', text="").type = 'UP'
 | 
			
		||||
                sub.operator("gpencil.layer_move", icon='TRIA_DOWN', text="").type = 'DOWN'
 | 
			
		||||
 | 
			
		||||
                col.separator()
 | 
			
		||||
 | 
			
		||||
                sub = col.column(align=True)
 | 
			
		||||
                sub.operator("gpencil.layer_isolate", icon='LOCKED', text="").affect_visibility = False
 | 
			
		||||
                sub.operator("gpencil.layer_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
 | 
			
		||||
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        if gpl:
 | 
			
		||||
            row.prop(gpl, "opacity", text="Opacity", slider=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_gpencil_layer_optionpanel(LayerDataButtonsPanel, Panel):
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "data"
 | 
			
		||||
    bl_label = "Adjustments"
 | 
			
		||||
    bl_parent_id = 'DATA_PT_gpencil_datapanel'
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
        gpl = context.active_gpencil_layer
 | 
			
		||||
        layout.active = not gpl.lock
 | 
			
		||||
 | 
			
		||||
        # Layer options
 | 
			
		||||
        # Offsets - Color Tint
 | 
			
		||||
        layout.enabled = not gpl.lock
 | 
			
		||||
        col = layout.column(align=True)
 | 
			
		||||
        col.prop(gpl, "tint_color")
 | 
			
		||||
        col.prop(gpl, "tint_factor", slider=True)
 | 
			
		||||
 | 
			
		||||
        # Offsets - Thickness
 | 
			
		||||
        col = layout.row(align=True)
 | 
			
		||||
        col.prop(gpl, "line_change", text="Stroke Thickness")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_gpencil_parentpanel(LayerDataButtonsPanel, Panel):
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "data"
 | 
			
		||||
    bl_label = "Relations"
 | 
			
		||||
    bl_parent_id = 'DATA_PT_gpencil_datapanel'
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
        layout.use_property_decorate = False
 | 
			
		||||
 | 
			
		||||
        gpl = context.active_gpencil_layer
 | 
			
		||||
        col = layout.column(align=True)
 | 
			
		||||
        col.active = not gpl.lock
 | 
			
		||||
        col.prop(gpl, "parent", text="Parent")
 | 
			
		||||
        col.prop(gpl, "parent_type", text="Parent Type")
 | 
			
		||||
        parent = gpl.parent
 | 
			
		||||
 | 
			
		||||
        if parent and gpl.parent_type == 'BONE' and parent.type == 'ARMATURE':
 | 
			
		||||
            col.prop_search(gpl, "parent_bone", parent.data, "bones", text="Bone")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_gpencil_onionpanel(Panel):
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "data"
 | 
			
		||||
    bl_label = "Onion Skinning"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        return bool(context.active_gpencil_layer)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw_header(self, context):
 | 
			
		||||
        self.layout.prop(context.gpencil_data, "use_onion_skinning", text="")
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
        layout.enabled = gpd.use_onion_skinning
 | 
			
		||||
 | 
			
		||||
        GreasePencilOnionPanel.draw_settings(layout, gpd)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GPENCIL_MT_gpencil_vertex_group(Menu):
 | 
			
		||||
    bl_label = "GP Vertex Groups"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        layout.operator_context = 'EXEC_AREA'
 | 
			
		||||
        layout.operator("object.vertex_group_add")
 | 
			
		||||
 | 
			
		||||
        ob = context.active_object
 | 
			
		||||
        if ob.vertex_groups.active:
 | 
			
		||||
            layout.separator()
 | 
			
		||||
 | 
			
		||||
            layout.operator("gpencil.vertex_group_assign", text="Assign to Active Group")
 | 
			
		||||
            layout.operator("gpencil.vertex_group_remove_from", text="Remove from Active Group")
 | 
			
		||||
 | 
			
		||||
            layout.separator()
 | 
			
		||||
            layout.operator_menu_enum("object.vertex_group_set_active", "group", text="Set Active Group")
 | 
			
		||||
            layout.operator("object.vertex_group_remove", text="Remove Active Group").all = False
 | 
			
		||||
            layout.operator("object.vertex_group_remove", text="Remove All Groups").all = True
 | 
			
		||||
 | 
			
		||||
            layout.separator()
 | 
			
		||||
            layout.operator("gpencil.vertex_group_select", text="Select Points")
 | 
			
		||||
            layout.operator("gpencil.vertex_group_deselect", text="Deselect Points")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GPENCIL_UL_vgroups(UIList):
 | 
			
		||||
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
 | 
			
		||||
        vgroup = item
 | 
			
		||||
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
 | 
			
		||||
            layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon)
 | 
			
		||||
            # icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED'
 | 
			
		||||
            # layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False)
 | 
			
		||||
        elif self.layout_type == 'GRID':
 | 
			
		||||
            layout.alignment = 'CENTER'
 | 
			
		||||
            layout.label(text="", icon_value=icon)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_gpencil_vertexpanel(DataButtonsPanel, Panel):
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "data"
 | 
			
		||||
    bl_label = "Vertex Groups"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        group = ob.vertex_groups.active
 | 
			
		||||
 | 
			
		||||
        rows = 2
 | 
			
		||||
        if group:
 | 
			
		||||
            rows = 4
 | 
			
		||||
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        row.template_list("GPENCIL_UL_vgroups", "", ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
 | 
			
		||||
 | 
			
		||||
        col = row.column(align=True)
 | 
			
		||||
        col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
 | 
			
		||||
        col.operator("object.vertex_group_remove", icon='ZOOMOUT', text="").all = False
 | 
			
		||||
 | 
			
		||||
        if ob.vertex_groups:
 | 
			
		||||
            row = layout.row()
 | 
			
		||||
 | 
			
		||||
            sub = row.row(align=True)
 | 
			
		||||
            sub.operator("gpencil.vertex_group_assign", text="Assign")
 | 
			
		||||
            sub.operator("gpencil.vertex_group_remove_from", text="Remove")
 | 
			
		||||
 | 
			
		||||
            sub = row.row(align=True)
 | 
			
		||||
            sub.operator("gpencil.vertex_group_select", text="Select")
 | 
			
		||||
            sub.operator("gpencil.vertex_group_deselect", text="Deselect")
 | 
			
		||||
 | 
			
		||||
            layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_gpencil_display(DataButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Viewport Display"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
        ob = context.object
 | 
			
		||||
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
        gpl = context.active_gpencil_layer
 | 
			
		||||
 | 
			
		||||
        layout.prop(gpd, "xray_mode", text="Depth Ordering")
 | 
			
		||||
        layout.prop(gpd, "edit_line_color", text="Edit Line Color")
 | 
			
		||||
        layout.prop(ob, "empty_draw_size", text="Marker Size")
 | 
			
		||||
 | 
			
		||||
        col = layout.column(align=True)
 | 
			
		||||
        col.prop(gpd, "show_constant_thickness")
 | 
			
		||||
        sub = col.column()
 | 
			
		||||
        sub.active = not gpd.show_constant_thickness
 | 
			
		||||
        sub.prop(gpd, "pixfactor", text="Thickness Scale")
 | 
			
		||||
 | 
			
		||||
        if gpl:
 | 
			
		||||
            layout.prop(gpd, "show_stroke_direction", text="Show Stroke Directions")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_custom_props_gpencil(DataButtonsPanel, PropertyPanel, Panel):
 | 
			
		||||
    _context_path = "object.data"
 | 
			
		||||
    _property_type = bpy.types.GreasePencil
 | 
			
		||||
 | 
			
		||||
###############################
 | 
			
		||||
 | 
			
		||||
classes = (
 | 
			
		||||
    DATA_PT_gpencil,
 | 
			
		||||
    DATA_PT_gpencil_datapanel,
 | 
			
		||||
    DATA_PT_gpencil_onionpanel,
 | 
			
		||||
    DATA_PT_gpencil_layer_optionpanel,
 | 
			
		||||
    DATA_PT_gpencil_parentpanel,
 | 
			
		||||
    DATA_PT_gpencil_vertexpanel,
 | 
			
		||||
    DATA_PT_gpencil_display,
 | 
			
		||||
    DATA_PT_custom_props_gpencil,
 | 
			
		||||
 | 
			
		||||
    GPENCIL_UL_layer,
 | 
			
		||||
    GPENCIL_UL_vgroups,
 | 
			
		||||
 | 
			
		||||
    GPENCIL_MT_layer_specials,
 | 
			
		||||
    GPENCIL_MT_gpencil_vertex_group,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":  # only for live edit.
 | 
			
		||||
    from bpy.utils import register_class
 | 
			
		||||
    for cls in classes:
 | 
			
		||||
        register_class(cls)
 | 
			
		||||
@@ -28,10 +28,14 @@ class ModifierButtonsPanel:
 | 
			
		||||
    bl_context = "modifier"
 | 
			
		||||
    bl_options = {'HIDE_HEADER'}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Modifiers"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        return ob and ob.type != 'GPENCIL'
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
@@ -1563,8 +1567,447 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
 | 
			
		||||
            layout.operator("object.correctivesmooth_bind", text="Unbind" if is_bind else "Bind")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Modifiers"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        return ob and ob.type == 'GPENCIL'
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        ob = context.object
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("object.gpencil_modifier_add", "type")
 | 
			
		||||
 | 
			
		||||
        for md in ob.grease_pencil_modifiers:
 | 
			
		||||
            box = layout.template_greasepencil_modifier(md)
 | 
			
		||||
            if box:
 | 
			
		||||
                # match enum type to our functions, avoids a lookup table.
 | 
			
		||||
                getattr(self, md.type)(box, ob, md)
 | 
			
		||||
 | 
			
		||||
    # the mt.type enum is (ab)used for a lookup on function names
 | 
			
		||||
    # ...to avoid lengthy if statements
 | 
			
		||||
    # so each type must have a function here.
 | 
			
		||||
 | 
			
		||||
    def GP_NOISE(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "factor")
 | 
			
		||||
        row.prop(md, "random", text="", icon="TIME", toggle=True)
 | 
			
		||||
        row = col.row()
 | 
			
		||||
        row.enabled = md.random
 | 
			
		||||
        row.prop(md, "step")
 | 
			
		||||
        col.prop(md, "full_stroke")
 | 
			
		||||
        col.prop(md, "move_extreme")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col.label("Vertex Group:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 | 
			
		||||
        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.label("Affect:")
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.prop(md, "affect_position", text="Position", icon='MESH_DATA', toggle=True)
 | 
			
		||||
        row.prop(md, "affect_strength", text="Strength", icon='COLOR', toggle=True)
 | 
			
		||||
        row.prop(md, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
 | 
			
		||||
        row.prop(md, "affect_uv", text="UV", icon='MOD_UVPROJECT', toggle=True)
 | 
			
		||||
 | 
			
		||||
    def GP_SMOOTH(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        row = layout.row(align=False)
 | 
			
		||||
        row.prop(md, "factor")
 | 
			
		||||
        row.prop(md, "step")
 | 
			
		||||
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Vertex Group:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 | 
			
		||||
        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.label("Affect:")
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.prop(md, "affect_position", text="Position", icon='MESH_DATA', toggle=True)
 | 
			
		||||
        row.prop(md, "affect_strength", text="Strength", icon='COLOR', toggle=True)
 | 
			
		||||
        row.prop(md, "affect_thickness", text="Thickness", icon='LINE_DATA', toggle=True)
 | 
			
		||||
        row.prop(md, "affect_uv", text="UV", icon='MOD_UVPROJECT', toggle=True)
 | 
			
		||||
 | 
			
		||||
    def GP_SUBDIV(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "level")
 | 
			
		||||
        row.prop(md, "simple", text="", icon="PARTICLE_POINT")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
    def GP_SIMPLIFY(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        row.prop(md, "mode")
 | 
			
		||||
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Settings:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.enabled = md.mode == 'FIXED'
 | 
			
		||||
        row.prop(md, "step")
 | 
			
		||||
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.enabled = not md.mode == 'FIXED'
 | 
			
		||||
        row.prop(md, "factor")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
    def GP_THICK(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "thickness")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col.prop(md, "normalize_thickness")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col.label("Vertex Group:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 | 
			
		||||
        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        if not md.normalize_thickness:
 | 
			
		||||
            split = layout.split()
 | 
			
		||||
            col = split.column()
 | 
			
		||||
            col.prop(md, "use_custom_curve")
 | 
			
		||||
 | 
			
		||||
            if md.use_custom_curve:
 | 
			
		||||
                col.template_curve_mapping(md, "curve")
 | 
			
		||||
 | 
			
		||||
    def GP_TINT(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.prop(md, "color")
 | 
			
		||||
        col.prop(md, "factor")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        row.prop(md, "create_colors")
 | 
			
		||||
 | 
			
		||||
    def GP_COLOR(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Color:")
 | 
			
		||||
        col.prop(md, "hue", text="H")
 | 
			
		||||
        col.prop(md, "saturation", text="S")
 | 
			
		||||
        col.prop(md, "value", text="V")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        row.prop(md, "create_colors")
 | 
			
		||||
 | 
			
		||||
    def GP_OPACITY(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Opacity:")
 | 
			
		||||
        col.prop(md, "factor")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col.label("Vertex Group:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 | 
			
		||||
        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
    def GP_INSTANCE(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
 | 
			
		||||
        col = layout.column()
 | 
			
		||||
        col.prop(md, "count")
 | 
			
		||||
        col.prop(md, "use_make_objects")
 | 
			
		||||
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Offset:")
 | 
			
		||||
        col.prop(md, "offset", text="")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Shift:")
 | 
			
		||||
        col.prop(md, "shift", text="")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "lock_axis", expand=True)
 | 
			
		||||
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Rotation:")
 | 
			
		||||
        col.prop(md, "rotation", text="")
 | 
			
		||||
        col.separator()
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "random_rot", text="", icon="TIME", toggle=True)
 | 
			
		||||
        row.prop(md, "rot_factor", text="")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Scale:")
 | 
			
		||||
        col.prop(md, "scale", text="")
 | 
			
		||||
        col.separator()
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "random_scale", text="", icon="TIME", toggle=True)
 | 
			
		||||
        row.prop(md, "scale_factor", text="")
 | 
			
		||||
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
    def GP_BUILD(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.prop(md, "mode")
 | 
			
		||||
        if md.mode == 'CONCURRENT':
 | 
			
		||||
            col.prop(md, "concurrent_time_alignment")
 | 
			
		||||
        else:
 | 
			
		||||
            col.separator() # For spacing
 | 
			
		||||
            col.separator()
 | 
			
		||||
        col.separator()
 | 
			
		||||
 | 
			
		||||
        col.prop(md, "transition")
 | 
			
		||||
        sub = col.column(align=True)
 | 
			
		||||
        sub.prop(md, "start_delay")
 | 
			
		||||
        sub.prop(md, "length")
 | 
			
		||||
 | 
			
		||||
        col = split.column(align=True)
 | 
			
		||||
        col.prop(md, "use_restrict_frame_range")
 | 
			
		||||
        sub = col.column(align=True)
 | 
			
		||||
        sub.active = md.use_restrict_frame_range
 | 
			
		||||
        sub.prop(md, "frame_start", text="Start")
 | 
			
		||||
        sub.prop(md, "frame_end", text="End")
 | 
			
		||||
        col.separator()
 | 
			
		||||
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
    def GP_LATTICE(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label(text="Object:")
 | 
			
		||||
        col.prop(md, "object", text="")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col.label("Vertex Group:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 | 
			
		||||
        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
        layout.prop(md, "strength", slider=True)
 | 
			
		||||
 | 
			
		||||
    def GP_MIRROR(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.prop(md, "x_axis")
 | 
			
		||||
        row.prop(md, "y_axis")
 | 
			
		||||
        row.prop(md, "z_axis")
 | 
			
		||||
 | 
			
		||||
        # GPXX: Not implemented yet
 | 
			
		||||
        # layout.separator()
 | 
			
		||||
        # layout.prop(md, "clip")
 | 
			
		||||
 | 
			
		||||
        layout.label("Layer:")
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        layout.label(text="Object:")
 | 
			
		||||
        layout.prop(md, "object", text="")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def GP_HOOK(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label(text="Object:")
 | 
			
		||||
        col.prop(md, "object", text="")
 | 
			
		||||
        if md.object and md.object.type == 'ARMATURE':
 | 
			
		||||
            col.label(text="Bone:")
 | 
			
		||||
            col.prop_search(md, "subtarget", md.object.data, "bones", text="")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col.label("Vertex Group:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 | 
			
		||||
        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        use_falloff = (md.falloff_type != 'NONE')
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        if use_falloff:
 | 
			
		||||
            row.prop(md, "falloff_radius")
 | 
			
		||||
        row.prop(md, "strength", slider=True)
 | 
			
		||||
        layout.prop(md, "falloff_type")
 | 
			
		||||
 | 
			
		||||
        col = layout.column()
 | 
			
		||||
        if use_falloff:
 | 
			
		||||
            if md.falloff_type == 'CURVE':
 | 
			
		||||
                col.template_curve_mapping(md, "falloff_curve")
 | 
			
		||||
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.prop(md, "use_falloff_uniform")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def GP_OFFSET(self, layout, ob, md):
 | 
			
		||||
        gpd = ob.data
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.prop(md, "location")
 | 
			
		||||
        col.prop(md, "scale")
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.prop(md, "rotation")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        col.label("Layer:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "layer", gpd, "layers", text="", icon='GREASEPENCIL')
 | 
			
		||||
        row.prop(md, "invert_layers", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        col.label("Vertex Group:")
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
 | 
			
		||||
        row.prop(md, "invert_vertex", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(md, "pass_index", text="Pass")
 | 
			
		||||
        row.prop(md, "invert_pass", text="", icon="ARROW_LEFTRIGHT")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
classes = (
 | 
			
		||||
    DATA_PT_modifiers,
 | 
			
		||||
    DATA_PT_gpencil_modifiers,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":  # only for live edit.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										134
									
								
								release/scripts/startup/bl_ui/properties_data_shaderfx.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,134 @@
 | 
			
		||||
# ##### BEGIN GPL LICENSE BLOCK #####
 | 
			
		||||
#
 | 
			
		||||
#  This program is free software; you can redistribute it and/or
 | 
			
		||||
#  modify it under the terms of the GNU General Public License
 | 
			
		||||
#  as published by the Free Software Foundation; either version 2
 | 
			
		||||
#  of the License, or (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
#  This program is distributed in the hope that it will be useful,
 | 
			
		||||
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
#  GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
#  You should have received a copy of the GNU General Public License
 | 
			
		||||
#  along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
#
 | 
			
		||||
# ##### END GPL LICENSE BLOCK #####
 | 
			
		||||
 | 
			
		||||
# <pep8 compliant>
 | 
			
		||||
import bpy
 | 
			
		||||
from bpy.types import Panel
 | 
			
		||||
from bpy.app.translations import pgettext_iface as iface_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ShaderFxButtonsPanel:
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "shaderfx"
 | 
			
		||||
    bl_options = {'HIDE_HEADER'}
 | 
			
		||||
 | 
			
		||||
class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Effects"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        return True
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        return ob and ob.type == 'GPENCIL'
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
        ob = context.object
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("object.shaderfx_add", "type")
 | 
			
		||||
 | 
			
		||||
        for fx in ob.shader_effects:
 | 
			
		||||
            box = layout.template_shaderfx(fx)
 | 
			
		||||
            if box:
 | 
			
		||||
                # match enum type to our functions, avoids a lookup table.
 | 
			
		||||
                getattr(self, fx.type)(box, fx)
 | 
			
		||||
 | 
			
		||||
    # the mt.type enum is (ab)used for a lookup on function names
 | 
			
		||||
    # ...to avoid lengthy if statements
 | 
			
		||||
    # so each type must have a function here.
 | 
			
		||||
 | 
			
		||||
    def FX_BLUR(self, layout, fx):
 | 
			
		||||
 | 
			
		||||
        layout.prop(fx, "factor", text="Factor")
 | 
			
		||||
        layout.prop(fx, "samples", text="Samples")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
        layout.prop(fx, "use_dof_mode")
 | 
			
		||||
        if fx.use_dof_mode:
 | 
			
		||||
            layout.prop(fx, "coc")
 | 
			
		||||
 | 
			
		||||
    def FX_COLORIZE(self, layout, fx):
 | 
			
		||||
        layout.prop(fx, "mode", text="Mode")
 | 
			
		||||
 | 
			
		||||
        if fx.mode == 'BITONE':
 | 
			
		||||
            layout.prop(fx, "low_color", text="Low Color")
 | 
			
		||||
        if fx.mode == 'CUSTOM':
 | 
			
		||||
            layout.prop(fx, "low_color", text="Color")
 | 
			
		||||
 | 
			
		||||
        if fx.mode == 'BITONE':
 | 
			
		||||
            layout.prop(fx, "high_color", text="High Color")
 | 
			
		||||
 | 
			
		||||
        if fx.mode in {'BITONE', 'CUSTOM', 'TRANSPARENT'}:
 | 
			
		||||
            layout.prop(fx, "factor")
 | 
			
		||||
 | 
			
		||||
    def FX_WAVE(self, layout,fx):
 | 
			
		||||
        layout.prop(fx, "orientation", expand=True)
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
        layout.prop(fx, "amplitude")
 | 
			
		||||
        layout.prop(fx, "period")
 | 
			
		||||
        layout.prop(fx, "phase")
 | 
			
		||||
 | 
			
		||||
    def FX_PIXEL(self, layout, fx):
 | 
			
		||||
        layout.prop(fx, "size", text="Size")
 | 
			
		||||
 | 
			
		||||
        layout.prop(fx, "use_lines", text="Display Lines")
 | 
			
		||||
 | 
			
		||||
        col = layout.column()
 | 
			
		||||
        col.enabled = fx.use_lines
 | 
			
		||||
        col.prop(fx, "color")
 | 
			
		||||
 | 
			
		||||
    def FX_RIM(self, layout, fx):
 | 
			
		||||
        layout.prop(fx, "offset", text="Offset")
 | 
			
		||||
 | 
			
		||||
        layout.prop(fx, "rim_color")
 | 
			
		||||
        layout.prop(fx, "mask_color")
 | 
			
		||||
        layout.prop(fx, "mode")
 | 
			
		||||
        layout.prop(fx, "blur")
 | 
			
		||||
        layout.prop(fx, "samples")
 | 
			
		||||
 | 
			
		||||
    def FX_SWIRL(self, layout, fx):
 | 
			
		||||
        layout.prop(fx, "object", text="Object")
 | 
			
		||||
 | 
			
		||||
        layout.prop(fx, "radius")
 | 
			
		||||
        layout.prop(fx, "angle")
 | 
			
		||||
 | 
			
		||||
        layout.prop(fx, "transparent")
 | 
			
		||||
 | 
			
		||||
    def FX_FLIP(self, layout, fx):
 | 
			
		||||
        layout.prop(fx, "flip_horizontal")
 | 
			
		||||
        layout.prop(fx, "flip_vertical")
 | 
			
		||||
 | 
			
		||||
    def FX_LIGHT(self, layout, fx):
 | 
			
		||||
        layout.prop(fx, "object", text="Object")
 | 
			
		||||
 | 
			
		||||
        layout.prop(fx, "energy")
 | 
			
		||||
        layout.prop(fx, "ambient")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
classes = (
 | 
			
		||||
    DATA_PT_shader_fx,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":  # only for live edit.
 | 
			
		||||
    from bpy.utils import register_class
 | 
			
		||||
    for cls in classes:
 | 
			
		||||
        register_class(cls)
 | 
			
		||||
@@ -86,8 +86,11 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        engine = context.engine
 | 
			
		||||
        return (context.material or context.object) and (engine in cls.COMPAT_ENGINES)
 | 
			
		||||
        if context.active_object and context.active_object.type == 'GPENCIL':
 | 
			
		||||
            return False
 | 
			
		||||
        else:
 | 
			
		||||
            engine = context.engine
 | 
			
		||||
            return (context.material or context.object) and (engine in cls.COMPAT_ENGINES)
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										322
									
								
								release/scripts/startup/bl_ui/properties_material_gpencil.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,322 @@
 | 
			
		||||
# ##### BEGIN GPL LICENSE BLOCK #####
 | 
			
		||||
#
 | 
			
		||||
#  This program is free software; you can redistribute it and/or
 | 
			
		||||
#  modify it under the terms of the GNU General Public License
 | 
			
		||||
#  as published by the Free Software Foundation; either version 2
 | 
			
		||||
#  of the License, or (at your option) any later version.
 | 
			
		||||
#
 | 
			
		||||
#  This program is distributed in the hope that it will be useful,
 | 
			
		||||
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
#  GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
#  You should have received a copy of the GNU General Public License
 | 
			
		||||
#  along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
#
 | 
			
		||||
# ##### END GPL LICENSE BLOCK #####
 | 
			
		||||
 | 
			
		||||
# <pep8 compliant>
 | 
			
		||||
import bpy
 | 
			
		||||
from bpy.types import Menu, Panel, UIList
 | 
			
		||||
from rna_prop_ui import PropertyPanel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GPENCIL_MT_color_specials(Menu):
 | 
			
		||||
    bl_label = "Layer"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.color_reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
 | 
			
		||||
        layout.operator("gpencil.color_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.color_lock_all", icon='LOCKED', text="Lock All")
 | 
			
		||||
        layout.operator("gpencil.color_unlock_all", icon='UNLOCKED', text="UnLock All")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.stroke_lock_color", icon='BORDER_RECT', text="Lock Unselected")
 | 
			
		||||
        layout.operator("gpencil.lock_layer", icon='COLOR', text="Lock Unused")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GPENCIL_UL_matslots(UIList):
 | 
			
		||||
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
 | 
			
		||||
        slot = item
 | 
			
		||||
        ma = slot.material
 | 
			
		||||
        if (ma is not None) and (ma.grease_pencil is not None):
 | 
			
		||||
            gpcolor = ma.grease_pencil
 | 
			
		||||
 | 
			
		||||
            if self.layout_type in {'DEFAULT', 'COMPACT'}:
 | 
			
		||||
                if gpcolor.lock:
 | 
			
		||||
                    layout.active = False
 | 
			
		||||
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.enabled = not gpcolor.lock
 | 
			
		||||
                row.prop(ma, "name", text="", emboss=False, icon_value=icon)
 | 
			
		||||
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(gpcolor, "lock", text="", emboss=False)
 | 
			
		||||
                row.prop(gpcolor, "hide", text="", emboss=False)
 | 
			
		||||
                if gpcolor.ghost is True:
 | 
			
		||||
                    icon = 'GHOST_DISABLED'
 | 
			
		||||
                else:
 | 
			
		||||
                    icon = 'GHOST_ENABLED'
 | 
			
		||||
                row.prop(gpcolor, "ghost", text="", icon=icon, emboss=False)
 | 
			
		||||
 | 
			
		||||
            elif self.layout_type == 'GRID':
 | 
			
		||||
                layout.alignment = 'CENTER'
 | 
			
		||||
                layout.label(text="", icon_value=icon)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GPMaterialButtonsPanel:
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "material"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        return (ob and ob.type == 'GPENCIL' and
 | 
			
		||||
                ob.active_material and
 | 
			
		||||
                ob.active_material.grease_pencil)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MATERIAL_PT_gpencil_slots(Panel):
 | 
			
		||||
    bl_label = "Grease Pencil Material Slots"
 | 
			
		||||
    bl_space_type = 'PROPERTIES'
 | 
			
		||||
    bl_region_type = 'WINDOW'
 | 
			
		||||
    bl_context = "material"
 | 
			
		||||
    bl_options = {'HIDE_HEADER'}
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        return ob and ob.type == 'GPENCIL'
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
 | 
			
		||||
        mat = context.object.active_material
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        slot = context.material_slot
 | 
			
		||||
        space = context.space_data
 | 
			
		||||
 | 
			
		||||
        if ob:
 | 
			
		||||
            is_sortable = len(ob.material_slots) > 1
 | 
			
		||||
            rows = 1
 | 
			
		||||
            if (is_sortable):
 | 
			
		||||
                rows = 4
 | 
			
		||||
 | 
			
		||||
            row = layout.row()
 | 
			
		||||
 | 
			
		||||
            row.template_list("GPENCIL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
 | 
			
		||||
 | 
			
		||||
            col = row.column(align=True)
 | 
			
		||||
            col.operator("object.material_slot_add", icon='ZOOMIN', text="")
 | 
			
		||||
            col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
 | 
			
		||||
 | 
			
		||||
            col.menu("GPENCIL_MT_color_specials", icon='DOWNARROW_HLT', text="")
 | 
			
		||||
 | 
			
		||||
            if is_sortable:
 | 
			
		||||
                col.separator()
 | 
			
		||||
 | 
			
		||||
                col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP'
 | 
			
		||||
                col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
 | 
			
		||||
 | 
			
		||||
                col.separator()
 | 
			
		||||
 | 
			
		||||
                sub = col.column(align=True)
 | 
			
		||||
                sub.operator("gpencil.color_isolate", icon='LOCKED', text="").affect_visibility = False
 | 
			
		||||
                sub.operator("gpencil.color_isolate", icon='RESTRICT_VIEW_OFF', text="").affect_visibility = True
 | 
			
		||||
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
 | 
			
		||||
        if ob:
 | 
			
		||||
            row.template_ID(ob, "active_material", new="material.new", live_icon=True)
 | 
			
		||||
 | 
			
		||||
            if slot:
 | 
			
		||||
                icon_link = 'MESH_DATA' if slot.link == 'DATA' else 'OBJECT_DATA'
 | 
			
		||||
                row.prop(slot, "link", icon=icon_link, icon_only=True)
 | 
			
		||||
 | 
			
		||||
            if gpd.use_stroke_edit_mode:
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.operator("gpencil.stroke_change_color", text="Assign")
 | 
			
		||||
                row.operator("gpencil.color_select", text="Select")
 | 
			
		||||
 | 
			
		||||
        elif mat:
 | 
			
		||||
            row.template_ID(space, "pin_id")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Used as parent for "Stroke" and "Fill" panels
 | 
			
		||||
class MATERIAL_PT_gpencil_surface(GPMaterialButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Surface"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        ob = context.object
 | 
			
		||||
        ma = context.object.active_material
 | 
			
		||||
        if ma is None or ma.grease_pencil is None:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        return ob and ob.type == 'GPENCIL'
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Stroke"
 | 
			
		||||
    bl_parent_id = 'MATERIAL_PT_gpencil_surface'
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
        ma = context.object.active_material
 | 
			
		||||
        if ma is not None and ma.grease_pencil is not None:
 | 
			
		||||
            gpcolor = ma.grease_pencil
 | 
			
		||||
 | 
			
		||||
            col = layout.column()
 | 
			
		||||
            col.active = not gpcolor.lock
 | 
			
		||||
 | 
			
		||||
            col.prop(gpcolor, "mode")
 | 
			
		||||
 | 
			
		||||
            col.prop(gpcolor, "stroke_style", text="Style")
 | 
			
		||||
 | 
			
		||||
            if gpcolor.stroke_style == 'TEXTURE':
 | 
			
		||||
                row = col.row()
 | 
			
		||||
                row.enabled = not gpcolor.lock
 | 
			
		||||
                col = row.column(align=True)
 | 
			
		||||
                col.template_ID(gpcolor, "stroke_image", open="image.open")
 | 
			
		||||
                col.prop(gpcolor, "pixel_size", text="UV Factor")
 | 
			
		||||
                col.prop(gpcolor, "use_stroke_pattern", text="Use As Pattern")
 | 
			
		||||
 | 
			
		||||
            if gpcolor.stroke_style == 'SOLID' or gpcolor.use_stroke_pattern is True:
 | 
			
		||||
                col.prop(gpcolor, "color", text="Color")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MATERIAL_PT_gpencil_fillcolor(GPMaterialButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Fill"
 | 
			
		||||
    bl_parent_id = 'MATERIAL_PT_gpencil_surface'
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
        ma = context.object.active_material
 | 
			
		||||
        if ma is not None and ma.grease_pencil:
 | 
			
		||||
            gpcolor = ma.grease_pencil
 | 
			
		||||
 | 
			
		||||
            # color settings
 | 
			
		||||
            col = layout.column()
 | 
			
		||||
            col.active = not gpcolor.lock
 | 
			
		||||
            col.prop(gpcolor, "fill_style", text="Style")
 | 
			
		||||
 | 
			
		||||
            if gpcolor.fill_style == 'GRADIENT':
 | 
			
		||||
                col.prop(gpcolor, "gradient_type")
 | 
			
		||||
 | 
			
		||||
            if gpcolor.fill_style != 'TEXTURE':
 | 
			
		||||
                col.prop(gpcolor, "fill_color", text="Color")
 | 
			
		||||
 | 
			
		||||
                if gpcolor.fill_style in ('GRADIENT', 'CHESSBOARD'):
 | 
			
		||||
                    col.prop(gpcolor, "mix_color", text="Secondary Color")
 | 
			
		||||
 | 
			
		||||
                if gpcolor.fill_style == 'GRADIENT':
 | 
			
		||||
                    col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True)
 | 
			
		||||
 | 
			
		||||
                if gpcolor.fill_style in ('GRADIENT', 'CHESSBOARD'):
 | 
			
		||||
                    col.prop(gpcolor, "flip", text="Flip Colors")
 | 
			
		||||
 | 
			
		||||
                    col.prop(gpcolor, "pattern_shift", text="Location")
 | 
			
		||||
                    col.prop(gpcolor, "pattern_scale", text="Scale")
 | 
			
		||||
 | 
			
		||||
                if gpcolor.gradient_type == 'RADIAL' and gpcolor.fill_style not in ('SOLID', 'CHESSBOARD'):
 | 
			
		||||
                    col.prop(gpcolor, "pattern_radius", text="Radius")
 | 
			
		||||
                else:
 | 
			
		||||
                    if gpcolor.fill_style != 'SOLID':
 | 
			
		||||
                        col.prop(gpcolor, "pattern_angle", text="Angle")
 | 
			
		||||
 | 
			
		||||
                if gpcolor.fill_style == 'CHESSBOARD':
 | 
			
		||||
                    col.prop(gpcolor, "pattern_gridsize", text="Box Size")
 | 
			
		||||
 | 
			
		||||
            # Texture
 | 
			
		||||
            if gpcolor.fill_style == 'TEXTURE' or (gpcolor.texture_mix is True and gpcolor.fill_style == 'SOLID'):
 | 
			
		||||
                col.template_ID(gpcolor, "fill_image", open="image.open")
 | 
			
		||||
 | 
			
		||||
                if gpcolor.fill_style == 'TEXTURE':
 | 
			
		||||
                    col.prop(gpcolor, "use_fill_pattern", text="Use As Pattern")
 | 
			
		||||
                    if gpcolor.use_fill_pattern is True:
 | 
			
		||||
                        col.prop(gpcolor, "fill_color", text="Color")
 | 
			
		||||
 | 
			
		||||
                col.prop(gpcolor, "texture_offset", text="Offset")
 | 
			
		||||
                col.prop(gpcolor, "texture_scale", text="Scale")
 | 
			
		||||
                col.prop(gpcolor, "texture_angle")
 | 
			
		||||
                col.prop(gpcolor, "texture_opacity")
 | 
			
		||||
                col.prop(gpcolor, "texture_clamp", text="Clip Image")
 | 
			
		||||
 | 
			
		||||
                if gpcolor.use_fill_pattern is False:
 | 
			
		||||
                    col.prop(gpcolor, "texture_mix", text="Mix With Color")
 | 
			
		||||
 | 
			
		||||
                    if gpcolor.texture_mix is True:
 | 
			
		||||
                        col.prop(gpcolor, "fill_color", text="Mix Color")
 | 
			
		||||
                        col.prop(gpcolor, "mix_factor", text="Mix Factor", slider=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Preview"
 | 
			
		||||
    COMPAT_ENGINES = {'BLENDER_EEVEE'}
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        ma = context.object.active_material
 | 
			
		||||
        self.layout.label(ma.name)
 | 
			
		||||
        self.layout.template_preview(ma)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MATERIAL_PT_gpencil_custom_props(GPMaterialButtonsPanel, PropertyPanel, Panel):
 | 
			
		||||
    COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_OPENGL'}
 | 
			
		||||
    _context_path = "object.active_material"
 | 
			
		||||
    _property_type = bpy.types.Material
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MATERIAL_PT_gpencil_options(GPMaterialButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Options"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
        ma = context.object.active_material
 | 
			
		||||
        if ma is not None and ma.grease_pencil is not None:
 | 
			
		||||
            gpcolor = ma.grease_pencil
 | 
			
		||||
            layout.prop(gpcolor, "pass_index")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
classes = (
 | 
			
		||||
    GPENCIL_UL_matslots,
 | 
			
		||||
    GPENCIL_MT_color_specials,
 | 
			
		||||
    MATERIAL_PT_gpencil_slots,
 | 
			
		||||
    MATERIAL_PT_gpencil_preview,
 | 
			
		||||
    MATERIAL_PT_gpencil_surface,
 | 
			
		||||
    MATERIAL_PT_gpencil_strokecolor,
 | 
			
		||||
    MATERIAL_PT_gpencil_fillcolor,
 | 
			
		||||
    MATERIAL_PT_gpencil_options,
 | 
			
		||||
    MATERIAL_PT_gpencil_custom_props,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":  # only for live edit.
 | 
			
		||||
    from bpy.utils import register_class
 | 
			
		||||
    for cls in classes:
 | 
			
		||||
        register_class(cls)
 | 
			
		||||
@@ -28,9 +28,9 @@ from rna_prop_ui import PropertyPanel
 | 
			
		||||
from bl_operators.presets import PresetMenu
 | 
			
		||||
 | 
			
		||||
from .properties_physics_common import (
 | 
			
		||||
    point_cache_ui,
 | 
			
		||||
    effector_weights_ui,
 | 
			
		||||
)
 | 
			
		||||
        point_cache_ui,
 | 
			
		||||
        effector_weights_ui,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SCENE_PT_units_length_presets(PresetMenu):
 | 
			
		||||
@@ -104,7 +104,6 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel):
 | 
			
		||||
        col.prop(unit, "scale_length")
 | 
			
		||||
        col.prop(unit, "use_separate")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SceneKeyingSetsPanel:
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
@@ -568,6 +567,33 @@ class SCENE_PT_simplify_render(SceneButtonsPanel, Panel):
 | 
			
		||||
        col.prop(rd, "simplify_child_particles_render", text="Max Child Particles")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SCENE_PT_simplify_greasepencil(SceneButtonsPanel, Panel):
 | 
			
		||||
    bl_label = "Simplify Grease Pencil"
 | 
			
		||||
    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    def draw_header(self, context):
 | 
			
		||||
        rd = context.scene.render
 | 
			
		||||
        self.layout.prop(rd, "simplify_gpencil", text="")
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        rd = context.scene.render
 | 
			
		||||
 | 
			
		||||
        layout.active = rd.simplify_gpencil
 | 
			
		||||
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        row.prop(rd, "simplify_gpencil_onplay", text="Only on Play")
 | 
			
		||||
 | 
			
		||||
        split = layout.split()
 | 
			
		||||
 | 
			
		||||
        col = split.column()
 | 
			
		||||
        col.prop(rd, "simplify_gpencil_view_fill", text="Fill")
 | 
			
		||||
        col.prop(rd, "simplify_gpencil_remove_lines", text="Remove Fill Lines")
 | 
			
		||||
        col.prop(rd, "simplify_gpencil_view_modifier", text="Modifiers")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel):
 | 
			
		||||
    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
 | 
			
		||||
    _context_path = "scene"
 | 
			
		||||
@@ -593,6 +619,7 @@ classes = (
 | 
			
		||||
    SCENE_PT_simplify,
 | 
			
		||||
    SCENE_PT_simplify_viewport,
 | 
			
		||||
    SCENE_PT_simplify_render,
 | 
			
		||||
    SCENE_PT_simplify_greasepencil,
 | 
			
		||||
    SCENE_PT_custom_props,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,14 +23,8 @@ from bpy.types import Panel, Header, Menu, UIList
 | 
			
		||||
from bpy.app.translations import pgettext_iface as iface_
 | 
			
		||||
from bl_operators.presets import PresetMenu
 | 
			
		||||
from .properties_grease_pencil_common import (
 | 
			
		||||
    GreasePencilDrawingToolsPanel,
 | 
			
		||||
    GreasePencilStrokeEditPanel,
 | 
			
		||||
    GreasePencilStrokeSculptPanel,
 | 
			
		||||
    GreasePencilBrushPanel,
 | 
			
		||||
    GreasePencilBrushCurvesPanel,
 | 
			
		||||
    GreasePencilDataPanel,
 | 
			
		||||
    GreasePencilPaletteColorPanel,
 | 
			
		||||
)
 | 
			
		||||
        GreasePencilDrawingToolsPanel,
 | 
			
		||||
        GreasePencilDataPanel)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CLIP_UL_tracking_objects(UIList):
 | 
			
		||||
@@ -1154,40 +1148,12 @@ class CLIP_PT_grease_pencil(GreasePencilDataPanel, CLIP_PT_clip_view_panel, Pane
 | 
			
		||||
    # But, this should only be visible in "clip" view
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil palette colors
 | 
			
		||||
class CLIP_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, CLIP_PT_clip_view_panel, Panel):
 | 
			
		||||
    bl_space_type = 'CLIP_EDITOR'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    # NOTE: this is just a wrapper around the generic GP Panel
 | 
			
		||||
    # But, this should only be visible in "clip" view
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing tools
 | 
			
		||||
class CLIP_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
 | 
			
		||||
    bl_space_type = 'CLIP_EDITOR'
 | 
			
		||||
    bl_region_type = 'TOOLS'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke editing tools
 | 
			
		||||
class CLIP_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
 | 
			
		||||
    bl_space_type = 'CLIP_EDITOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke sculpting tools
 | 
			
		||||
class CLIP_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
 | 
			
		||||
    bl_space_type = 'CLIP_EDITOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing brushes
 | 
			
		||||
class CLIP_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
 | 
			
		||||
    bl_space_type = 'CLIP_EDITOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing curves
 | 
			
		||||
class CLIP_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
 | 
			
		||||
    bl_space_type = 'CLIP_EDITOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CLIP_MT_view(Menu):
 | 
			
		||||
    bl_label = "View"
 | 
			
		||||
@@ -1515,12 +1481,7 @@ classes = (
 | 
			
		||||
    CLIP_PT_footage_info,
 | 
			
		||||
    CLIP_PT_tools_scenesetup,
 | 
			
		||||
    CLIP_PT_grease_pencil,
 | 
			
		||||
    CLIP_PT_grease_pencil_palettecolor,
 | 
			
		||||
    CLIP_PT_tools_grease_pencil_draw,
 | 
			
		||||
    CLIP_PT_tools_grease_pencil_edit,
 | 
			
		||||
    CLIP_PT_tools_grease_pencil_sculpt,
 | 
			
		||||
    CLIP_PT_tools_grease_pencil_brush,
 | 
			
		||||
    CLIP_PT_tools_grease_pencil_brushcurves,
 | 
			
		||||
    CLIP_MT_view,
 | 
			
		||||
    CLIP_MT_clip,
 | 
			
		||||
    CLIP_MT_proxy,
 | 
			
		||||
 
 | 
			
		||||
@@ -21,20 +21,15 @@ import bpy
 | 
			
		||||
import math
 | 
			
		||||
from bpy.types import Header, Menu, Panel, UIList
 | 
			
		||||
from .properties_paint_common import (
 | 
			
		||||
    UnifiedPaintPanel,
 | 
			
		||||
    brush_texture_settings,
 | 
			
		||||
    brush_texpaint_common,
 | 
			
		||||
    brush_mask_texture_settings,
 | 
			
		||||
)
 | 
			
		||||
        UnifiedPaintPanel,
 | 
			
		||||
        brush_texture_settings,
 | 
			
		||||
        brush_texpaint_common,
 | 
			
		||||
        brush_mask_texture_settings,
 | 
			
		||||
        )
 | 
			
		||||
from .properties_grease_pencil_common import (
 | 
			
		||||
    GreasePencilDrawingToolsPanel,
 | 
			
		||||
    GreasePencilStrokeEditPanel,
 | 
			
		||||
    GreasePencilStrokeSculptPanel,
 | 
			
		||||
    GreasePencilBrushPanel,
 | 
			
		||||
    GreasePencilBrushCurvesPanel,
 | 
			
		||||
    GreasePencilDataPanel,
 | 
			
		||||
    GreasePencilPaletteColorPanel,
 | 
			
		||||
)
 | 
			
		||||
        GreasePencilDrawingToolsPanel,
 | 
			
		||||
        GreasePencilDataPanel
 | 
			
		||||
        )
 | 
			
		||||
from bpy.app.translations import pgettext_iface as iface_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1346,39 +1341,12 @@ class IMAGE_PT_grease_pencil(GreasePencilDataPanel, Panel):
 | 
			
		||||
 | 
			
		||||
    # NOTE: this is just a wrapper around the generic GP Panel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil palette colors
 | 
			
		||||
class IMAGE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
 | 
			
		||||
    bl_space_type = 'IMAGE_EDITOR'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
 | 
			
		||||
    # NOTE: this is just a wrapper around the generic GP Panel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing tools
 | 
			
		||||
class IMAGE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
 | 
			
		||||
    bl_space_type = 'IMAGE_EDITOR'
 | 
			
		||||
    bl_region_type = 'TOOLS'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke editing tools
 | 
			
		||||
class IMAGE_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
 | 
			
		||||
    bl_space_type = 'IMAGE_EDITOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke sculpting tools
 | 
			
		||||
class IMAGE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
 | 
			
		||||
    bl_space_type = 'IMAGE_EDITOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing brushes
 | 
			
		||||
class IMAGE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
 | 
			
		||||
    bl_space_type = 'IMAGE_EDITOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing curves
 | 
			
		||||
class IMAGE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
 | 
			
		||||
    bl_space_type = 'IMAGE_EDITOR'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
classes = (
 | 
			
		||||
    IMAGE_MT_view,
 | 
			
		||||
@@ -1430,12 +1398,7 @@ classes = (
 | 
			
		||||
    IMAGE_PT_sample_line,
 | 
			
		||||
    IMAGE_PT_scope_sample,
 | 
			
		||||
    IMAGE_PT_grease_pencil,
 | 
			
		||||
    IMAGE_PT_grease_pencil_palettecolor,
 | 
			
		||||
    IMAGE_PT_tools_grease_pencil_draw,
 | 
			
		||||
    IMAGE_PT_tools_grease_pencil_edit,
 | 
			
		||||
    IMAGE_PT_tools_grease_pencil_sculpt,
 | 
			
		||||
    IMAGE_PT_tools_grease_pencil_brush,
 | 
			
		||||
    IMAGE_PT_tools_grease_pencil_brushcurves,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":  # only for live edit.
 | 
			
		||||
 
 | 
			
		||||
@@ -23,15 +23,10 @@ from bpy.types import Header, Menu, Panel
 | 
			
		||||
from bpy.app.translations import pgettext_iface as iface_
 | 
			
		||||
from bl_operators.presets import PresetMenu
 | 
			
		||||
from .properties_grease_pencil_common import (
 | 
			
		||||
    GreasePencilDrawingToolsPanel,
 | 
			
		||||
    GreasePencilStrokeEditPanel,
 | 
			
		||||
    GreasePencilStrokeSculptPanel,
 | 
			
		||||
    GreasePencilBrushPanel,
 | 
			
		||||
    GreasePencilBrushCurvesPanel,
 | 
			
		||||
    GreasePencilDataPanel,
 | 
			
		||||
    GreasePencilPaletteColorPanel,
 | 
			
		||||
    GreasePencilToolsPanel
 | 
			
		||||
)
 | 
			
		||||
        GreasePencilDrawingToolsPanel,
 | 
			
		||||
        GreasePencilDataPanel,
 | 
			
		||||
        GreasePencilToolsPanel
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NODE_HT_header(Header):
 | 
			
		||||
@@ -539,19 +534,6 @@ class NODE_PT_grease_pencil(GreasePencilDataPanel, Panel):
 | 
			
		||||
        return snode is not None and snode.node_tree is not None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil palette colors
 | 
			
		||||
class NODE_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
 | 
			
		||||
    bl_space_type = 'NODE_EDITOR'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
 | 
			
		||||
    # NOTE: this is just a wrapper around the generic GP Panel
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        snode = context.space_data
 | 
			
		||||
        return snode is not None and snode.node_tree is not None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NODE_PT_grease_pencil_tools(GreasePencilToolsPanel, Panel):
 | 
			
		||||
    bl_space_type = 'NODE_EDITOR'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
@@ -571,31 +553,6 @@ class NODE_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
 | 
			
		||||
    bl_region_type = 'TOOLS'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke editing tools
 | 
			
		||||
class NODE_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
 | 
			
		||||
    bl_space_type = 'NODE_EDITOR'
 | 
			
		||||
    bl_region_type = 'TOOLS'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke sculpting tools
 | 
			
		||||
class NODE_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
 | 
			
		||||
    bl_space_type = 'NODE_EDITOR'
 | 
			
		||||
    bl_region_type = 'TOOLS'
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing brushes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NODE_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
 | 
			
		||||
    bl_space_type = 'NODE_EDITOR'
 | 
			
		||||
    bl_region_type = 'TOOLS'
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing curves
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NODE_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
 | 
			
		||||
    bl_space_type = 'NODE_EDITOR'
 | 
			
		||||
    bl_region_type = 'TOOLS'
 | 
			
		||||
 | 
			
		||||
# -----------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -620,13 +577,8 @@ classes = (
 | 
			
		||||
    NODE_PT_quality,
 | 
			
		||||
    NODE_UL_interface_sockets,
 | 
			
		||||
    NODE_PT_grease_pencil,
 | 
			
		||||
    NODE_PT_grease_pencil_palettecolor,
 | 
			
		||||
    NODE_PT_grease_pencil_tools,
 | 
			
		||||
    NODE_PT_tools_grease_pencil_draw,
 | 
			
		||||
    NODE_PT_tools_grease_pencil_edit,
 | 
			
		||||
    NODE_PT_tools_grease_pencil_sculpt,
 | 
			
		||||
    NODE_PT_tools_grease_pencil_brush,
 | 
			
		||||
    NODE_PT_tools_grease_pencil_brushcurves,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ from bpy.types import Header, Menu, Panel
 | 
			
		||||
from rna_prop_ui import PropertyPanel
 | 
			
		||||
from .properties_grease_pencil_common import (
 | 
			
		||||
    GreasePencilDataPanel,
 | 
			
		||||
    GreasePencilPaletteColorPanel,
 | 
			
		||||
    GreasePencilToolsPanel,
 | 
			
		||||
)
 | 
			
		||||
from bpy.app.translations import pgettext_iface as iface_
 | 
			
		||||
@@ -1281,14 +1280,6 @@ class SEQUENCER_PT_grease_pencil(GreasePencilDataPanel, SequencerButtonsPanel_Ou
 | 
			
		||||
    # But, it should only show up when there are images in the preview region
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SEQUENCER_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, SequencerButtonsPanel_Output, Panel):
 | 
			
		||||
    bl_space_type = 'SEQUENCE_EDITOR'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
 | 
			
		||||
    # NOTE: this is just a wrapper around the generic GP Panel
 | 
			
		||||
    # But, it should only show up when there are images in the preview region
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsPanel_Output, Panel):
 | 
			
		||||
    bl_space_type = 'SEQUENCE_EDITOR'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
@@ -1333,7 +1324,6 @@ classes = (
 | 
			
		||||
    SEQUENCER_PT_view_safe_areas,
 | 
			
		||||
    SEQUENCER_PT_modifiers,
 | 
			
		||||
    SEQUENCER_PT_grease_pencil,
 | 
			
		||||
    SEQUENCER_PT_grease_pencil_palettecolor,
 | 
			
		||||
    SEQUENCER_PT_grease_pencil_tools,
 | 
			
		||||
    SEQUENCER_PT_custom_props,
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
# For now keep this in a single file since it's an area that may change,
 | 
			
		||||
# so avoid making changes all over the place.
 | 
			
		||||
 | 
			
		||||
import bpy
 | 
			
		||||
from bpy.types import Panel
 | 
			
		||||
 | 
			
		||||
from .space_toolsystem_common import (
 | 
			
		||||
@@ -39,21 +40,77 @@ def generate_from_brushes_ex(
 | 
			
		||||
        brush_category_attr,
 | 
			
		||||
        brush_category_layout,
 | 
			
		||||
):
 | 
			
		||||
    def draw_settings(context, layout, tool):
 | 
			
		||||
        _defs_gpencil_paint.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
    # Categories
 | 
			
		||||
    brush_categories = {}
 | 
			
		||||
    for brush in context.blend_data.brushes:
 | 
			
		||||
        if getattr(brush, brush_test_attr):
 | 
			
		||||
            category = getattr(brush, brush_category_attr)
 | 
			
		||||
            name = brush.name
 | 
			
		||||
            brush_categories.setdefault(category, []).append(
 | 
			
		||||
                ToolDef.from_dict(
 | 
			
		||||
                    dict(
 | 
			
		||||
                        text=name,
 | 
			
		||||
                        icon=icon_prefix + category.lower(),
 | 
			
		||||
                        data_block=name,
 | 
			
		||||
    if context.mode != 'GPENCIL_PAINT':
 | 
			
		||||
        for brush in context.blend_data.brushes:
 | 
			
		||||
            if getattr(brush, brush_test_attr) and brush.gpencil_settings is None:
 | 
			
		||||
                category = getattr(brush, brush_category_attr)
 | 
			
		||||
                name = brush.name
 | 
			
		||||
                brush_categories.setdefault(category, []).append(
 | 
			
		||||
                    ToolDef.from_dict(
 | 
			
		||||
                        dict(
 | 
			
		||||
                            text=name,
 | 
			
		||||
                            icon=icon_prefix + category.lower(),
 | 
			
		||||
                            data_block=name,
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
    else:
 | 
			
		||||
        for brush_type in brush_category_layout:
 | 
			
		||||
            for brush in context.blend_data.brushes:
 | 
			
		||||
                if getattr(brush, brush_test_attr) and brush.gpencil_settings.gp_icon == brush_type[0]:
 | 
			
		||||
                    category = brush_type[0]
 | 
			
		||||
                    name = brush.name
 | 
			
		||||
 | 
			
		||||
                    # rename default brushes for tool bar
 | 
			
		||||
                    if name.startswith("Draw "):
 | 
			
		||||
                        text = name.replace("Draw ", "")
 | 
			
		||||
                    elif name.startswith("Eraser "):
 | 
			
		||||
                        text = name.replace("Eraser ", "")
 | 
			
		||||
                    elif name.startswith("Fill "):
 | 
			
		||||
                        text = name.replace(" Area", "")
 | 
			
		||||
                    else:
 | 
			
		||||
                        text = name
 | 
			
		||||
 | 
			
		||||
                    # define icon
 | 
			
		||||
                    gp_icon = brush.gpencil_settings.gp_icon
 | 
			
		||||
                    if gp_icon == 'PENCIL':
 | 
			
		||||
                        icon_name = 'draw_pencil'
 | 
			
		||||
                    elif gp_icon == 'PEN':
 | 
			
		||||
                        icon_name = 'draw_pen'
 | 
			
		||||
                    elif gp_icon == 'INK':
 | 
			
		||||
                        icon_name = 'draw_ink'
 | 
			
		||||
                    elif gp_icon == 'INKNOISE':
 | 
			
		||||
                        icon_name = 'draw_noise'
 | 
			
		||||
                    elif gp_icon == 'BLOCK':
 | 
			
		||||
                        icon_name = 'draw_block'
 | 
			
		||||
                    elif gp_icon == 'MARKER':
 | 
			
		||||
                        icon_name = 'draw_marker'
 | 
			
		||||
                    elif gp_icon == 'FILL':
 | 
			
		||||
                        icon_name = 'draw_fill'
 | 
			
		||||
                    elif gp_icon == 'SOFT':
 | 
			
		||||
                        icon_name = 'draw.eraser_soft'
 | 
			
		||||
                    elif gp_icon == 'HARD':
 | 
			
		||||
                        icon_name = 'draw.eraser_hard'
 | 
			
		||||
                    elif gp_icon == 'STROKE':
 | 
			
		||||
                        icon_name = 'draw.eraser_stroke'
 | 
			
		||||
 | 
			
		||||
                    brush_categories.setdefault(category, []).append(
 | 
			
		||||
                        ToolDef.from_dict(
 | 
			
		||||
                            dict(
 | 
			
		||||
                                text=text,
 | 
			
		||||
                                icon=icon_prefix + icon_name,
 | 
			
		||||
                                data_block=name,
 | 
			
		||||
                                widget=None,
 | 
			
		||||
                                operator="gpencil.draw",
 | 
			
		||||
                                draw_settings=draw_settings,
 | 
			
		||||
                            )
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
    def tools_from_brush_group(groups):
 | 
			
		||||
        assert(type(groups) is tuple)
 | 
			
		||||
@@ -61,6 +118,7 @@ def generate_from_brushes_ex(
 | 
			
		||||
            tool_defs = tuple(brush_categories.pop(groups[0], ()))
 | 
			
		||||
        else:
 | 
			
		||||
            tool_defs = tuple(item for g in groups for item in brush_categories.pop(g, ()))
 | 
			
		||||
 | 
			
		||||
        if len(tool_defs) > 1:
 | 
			
		||||
            return (tool_defs,)
 | 
			
		||||
        else:
 | 
			
		||||
@@ -125,6 +183,112 @@ class _defs_view3d_generic:
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _defs_annotate:
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def draw_settings_common(cls, context, layout, tool):
 | 
			
		||||
        user_prefs = context.user_preferences
 | 
			
		||||
        ts = context.tool_settings
 | 
			
		||||
 | 
			
		||||
        # XXX: These context checks are needed for layer-dependent settings,
 | 
			
		||||
        # but this breaks for using topbar for 2D editor active tools, etc.
 | 
			
		||||
        if type(context.gpencil_data_owner) is bpy.types.Object:
 | 
			
		||||
            gpd = context.scene.grease_pencil
 | 
			
		||||
        else:
 | 
			
		||||
            gpd = context.gpencil_data
 | 
			
		||||
 | 
			
		||||
        gpl = gpd.layers.active if gpd else None
 | 
			
		||||
 | 
			
		||||
        if gpd and gpl:
 | 
			
		||||
            layout.prop(gpd.layers, "active_note", text="")
 | 
			
		||||
            layout.prop(gpl, "thickness", text="Thickness")
 | 
			
		||||
        else:
 | 
			
		||||
            layout.prop(user_prefs.edit, "grease_pencil_default_color", text="Color")
 | 
			
		||||
            layout.prop(ts, "annotation_thickness", text="Thickness")
 | 
			
		||||
 | 
			
		||||
        # For 3D view, show the stroke placement settings
 | 
			
		||||
        # XXX: How to tell what editor the active tool comes from?
 | 
			
		||||
        is_3d_view = True
 | 
			
		||||
        if is_3d_view:
 | 
			
		||||
            layout.separator()
 | 
			
		||||
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
            row.prop(ts, "annotation_stroke_placement_view3d", text="Orientation")
 | 
			
		||||
            if ts.gpencil_stroke_placement_view3d == 'CURSOR':
 | 
			
		||||
                row.prop(ts.gpencil_sculpt, "lockaxis")
 | 
			
		||||
            elif ts.gpencil_stroke_placement_view3d in {'SURFACE', 'STROKE'}:
 | 
			
		||||
                row.prop(ts, "use_gpencil_stroke_endpoints")
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def scribble():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_annotate.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Annotate",
 | 
			
		||||
            icon="ops.gpencil.draw",
 | 
			
		||||
            cursor='PAINT_BRUSH',
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.annotate",
 | 
			
		||||
                 dict(mode='DRAW', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def line():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_annotate.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Draw Line",
 | 
			
		||||
            icon="ops.gpencil.draw.line",
 | 
			
		||||
            cursor='CROSSHAIR',
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.annotate",
 | 
			
		||||
                 dict(mode='DRAW_STRAIGHT', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def poly():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_annotate.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Draw Polygon",
 | 
			
		||||
            icon="ops.gpencil.draw.poly",
 | 
			
		||||
            cursor='CROSSHAIR',
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.annotate",
 | 
			
		||||
                 dict(mode='DRAW_POLY', wait_for_input=False),
 | 
			
		||||
                 dict(type='ACTIONMOUSE', value='PRESS')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def eraser():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            # TODO: Move this setting to toolsettings
 | 
			
		||||
            user_prefs = context.user_preferences
 | 
			
		||||
            layout.prop(user_prefs.edit, "grease_pencil_eraser_radius", text="Radius")
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Eraser",
 | 
			
		||||
            icon="ops.gpencil.draw.eraser",
 | 
			
		||||
            cursor='CROSSHAIR', # XXX: Always show brush circle when enabled
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.annotate",
 | 
			
		||||
                 dict(mode='ERASER', wait_for_input=False),
 | 
			
		||||
                 dict(type='ACTIONMOUSE', value='PRESS')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _defs_transform:
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
@@ -865,6 +1029,331 @@ class _defs_uv_select:
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
class _defs_gpencil_paint:
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def draw_color_selector(cls, context, layout):
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
        ts = context.tool_settings
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.prop(ts, "use_gpencil_thumbnail_list", text="", icon="IMGDISPLAY")
 | 
			
		||||
        if ts.use_gpencil_thumbnail_list is False:
 | 
			
		||||
            row.template_ID(gp_settings, "material", live_icon=True)
 | 
			
		||||
        else:
 | 
			
		||||
            row.template_greasepencil_color(gp_settings, "material", rows=3, cols=8, scale=0.8)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def draw_settings_common(cls, context, layout, tool):
 | 
			
		||||
        ob = context.active_object
 | 
			
		||||
        if ob and ob.mode == 'GPENCIL_PAINT':
 | 
			
		||||
            brush = context.active_gpencil_brush
 | 
			
		||||
            gp_settings = brush.gpencil_settings
 | 
			
		||||
            tool_settings= context.tool_settings
 | 
			
		||||
 | 
			
		||||
            if gp_settings.gpencil_brush_type == 'ERASE':
 | 
			
		||||
                row = layout.row()
 | 
			
		||||
                row.prop(brush, "size", text="Radius")
 | 
			
		||||
            elif gp_settings.gpencil_brush_type == 'FILL':
 | 
			
		||||
                row = layout.row()
 | 
			
		||||
                row.prop(gp_settings, "gpencil_fill_leak", text="Leak Size")
 | 
			
		||||
                row.prop(brush, "size", text="Thickness")
 | 
			
		||||
                row.prop(gp_settings, "gpencil_fill_simplyfy_level", text="Simplify")
 | 
			
		||||
 | 
			
		||||
                _defs_gpencil_paint.draw_color_selector(context, layout)
 | 
			
		||||
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(gp_settings, "gpencil_fill_draw_mode", text="")
 | 
			
		||||
                row.prop(gp_settings, "gpencil_fill_show_boundary", text="", icon='GRID')
 | 
			
		||||
 | 
			
		||||
            else:  # bgpsettings.gpencil_brush_type == 'DRAW':
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(brush, "size", text="Radius")
 | 
			
		||||
                row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE')
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(gp_settings, "pen_strength", slider=True)
 | 
			
		||||
                row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
 | 
			
		||||
 | 
			
		||||
                _defs_gpencil_paint.draw_color_selector(context, layout)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def generate_from_brushes(context):
 | 
			
		||||
        return generate_from_brushes_ex(
 | 
			
		||||
            context,
 | 
			
		||||
            icon_prefix="brush.gpencil.",
 | 
			
		||||
            brush_test_attr="use_paint_grease_pencil",
 | 
			
		||||
            brush_category_attr="grease_pencil_tool",
 | 
			
		||||
            brush_category_layout=(
 | 
			
		||||
                ('PENCIL',),
 | 
			
		||||
                ('PEN',),
 | 
			
		||||
                ('INK',),
 | 
			
		||||
                ('INKNOISE',),
 | 
			
		||||
                ('BLOCK',),
 | 
			
		||||
                ('MARKER',),
 | 
			
		||||
                ('FILL',),
 | 
			
		||||
                ('SOFT',),
 | 
			
		||||
                ('HARD',),
 | 
			
		||||
                ('STROKE',),
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _defs_gpencil_edit:
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def bend():
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Bend",
 | 
			
		||||
            icon="ops.gpencil.edit_bend",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("transform.bend",
 | 
			
		||||
                 dict(),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def mirror():
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Mirror",
 | 
			
		||||
            icon="ops.gpencil.edit_mirror",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("transform.mirror",
 | 
			
		||||
                 dict(),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def shear():
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Shear",
 | 
			
		||||
            icon="ops.gpencil.edit_shear",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("transform.shear",
 | 
			
		||||
                 dict(),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def tosphere():
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="To Sphere",
 | 
			
		||||
            icon="ops.gpencil.edit_to_sphere",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("transform.tosphere",
 | 
			
		||||
                 dict(),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _defs_gpencil_sculpt:
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def draw_settings_common(cls, context, layout, tool):
 | 
			
		||||
        ob = context.active_object
 | 
			
		||||
        if ob and ob.mode == 'GPENCIL_SCULPT':
 | 
			
		||||
            ts = context.tool_settings
 | 
			
		||||
            settings = ts.gpencil_sculpt
 | 
			
		||||
            brush = settings.brush
 | 
			
		||||
 | 
			
		||||
            layout.prop(brush, "size", slider=True)
 | 
			
		||||
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
            row.prop(brush, "strength", slider=True)
 | 
			
		||||
            row.prop(brush, "use_pressure_strength", text="")
 | 
			
		||||
            row.separator()
 | 
			
		||||
            row.prop(ts.gpencil_sculpt, "use_select_mask", text="")
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def smooth():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Smooth",
 | 
			
		||||
            icon="ops.gpencil.sculpt_smooth",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='SMOOTH', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def thickness():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Thickness",
 | 
			
		||||
            icon="ops.gpencil.sculpt_thickness",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='THICKNESS', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def strength():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Strength",
 | 
			
		||||
            icon="ops.gpencil.sculpt_strength",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='STRENGTH', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def grab():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Grab",
 | 
			
		||||
            icon="ops.gpencil.sculpt_grab",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='GRAB', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def push():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Push",
 | 
			
		||||
            icon="ops.gpencil.sculpt_push",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='PUSH', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def twist():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Twist",
 | 
			
		||||
            icon="ops.gpencil.sculpt_twist",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='TWIST', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def pinch():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Pinch",
 | 
			
		||||
            icon="ops.gpencil.sculpt_pinch",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='PINCH', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def randomize():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Randomize",
 | 
			
		||||
            icon="ops.gpencil.sculpt_randomize",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='RANDOMIZE', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def clone():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_sculpt.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Clone",
 | 
			
		||||
            icon="ops.gpencil.sculpt_clone",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='CLONE', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _defs_gpencil_weight:
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def draw_settings_common(cls, context, layout, tool):
 | 
			
		||||
        ob = context.active_object
 | 
			
		||||
        if ob and ob.mode == 'GPENCIL_WEIGHT':
 | 
			
		||||
            settings = context.tool_settings.gpencil_sculpt
 | 
			
		||||
            brush = settings.brush
 | 
			
		||||
 | 
			
		||||
            layout.prop(brush, "size", slider=True)
 | 
			
		||||
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
            row.prop(brush, "strength", slider=True)
 | 
			
		||||
            row.prop(brush, "use_pressure_strength", text="")
 | 
			
		||||
 | 
			
		||||
    @ToolDef.from_fn
 | 
			
		||||
    def paint():
 | 
			
		||||
        def draw_settings(context, layout, tool):
 | 
			
		||||
            _defs_gpencil_weight.draw_settings_common(context, layout, tool)
 | 
			
		||||
 | 
			
		||||
        return dict(
 | 
			
		||||
            text="Draw",
 | 
			
		||||
            icon="ops.gpencil.sculpt_weight",
 | 
			
		||||
            widget=None,
 | 
			
		||||
            keymap=(
 | 
			
		||||
                ("gpencil.brush_paint",
 | 
			
		||||
                 dict(mode='WEIGHT', wait_for_input=False),
 | 
			
		||||
                 dict(type='EVT_TWEAK_A', value='ANY')),
 | 
			
		||||
            ),
 | 
			
		||||
            draw_settings=draw_settings,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
			
		||||
    bl_space_type = 'IMAGE_EDITOR'
 | 
			
		||||
@@ -951,8 +1440,6 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
			
		||||
            _defs_transform.scale,
 | 
			
		||||
            _defs_transform.scale_cage,
 | 
			
		||||
        ),
 | 
			
		||||
        None,
 | 
			
		||||
        _defs_view3d_generic.ruler,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    _tools_select = (
 | 
			
		||||
@@ -963,6 +1450,16 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    _tools_annotate = (
 | 
			
		||||
        (
 | 
			
		||||
            _defs_annotate.scribble,
 | 
			
		||||
            _defs_annotate.line,
 | 
			
		||||
            _defs_annotate.poly,
 | 
			
		||||
            _defs_annotate.eraser,
 | 
			
		||||
        ),
 | 
			
		||||
        _defs_view3d_generic.ruler,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    _tools = {
 | 
			
		||||
        None: [
 | 
			
		||||
            _defs_view3d_generic.cursor,
 | 
			
		||||
@@ -972,21 +1469,27 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
			
		||||
            *_tools_select,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_transform,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_annotate,
 | 
			
		||||
        ],
 | 
			
		||||
        'POSE': [
 | 
			
		||||
            *_tools_select,
 | 
			
		||||
            *_tools_transform,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_annotate,
 | 
			
		||||
            None,
 | 
			
		||||
            (
 | 
			
		||||
                _defs_pose.breakdown,
 | 
			
		||||
                _defs_pose.push,
 | 
			
		||||
                _defs_pose.relax,
 | 
			
		||||
            )
 | 
			
		||||
            ),
 | 
			
		||||
        ],
 | 
			
		||||
        'EDIT_ARMATURE': [
 | 
			
		||||
            *_tools_select,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_transform,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_annotate,
 | 
			
		||||
            _defs_edit_armature.roll,
 | 
			
		||||
            (
 | 
			
		||||
                _defs_edit_armature.bone_size,
 | 
			
		||||
@@ -996,13 +1499,15 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
			
		||||
            (
 | 
			
		||||
                _defs_edit_armature.extrude,
 | 
			
		||||
                _defs_edit_armature.extrude_cursor,
 | 
			
		||||
            )
 | 
			
		||||
            ),
 | 
			
		||||
        ],
 | 
			
		||||
        'EDIT_MESH': [
 | 
			
		||||
            *_tools_select,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_transform,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_annotate,
 | 
			
		||||
            None,
 | 
			
		||||
            _defs_edit_mesh.cube_add,
 | 
			
		||||
            None,
 | 
			
		||||
            (
 | 
			
		||||
@@ -1047,6 +1552,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_transform,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_annotate,
 | 
			
		||||
            None,
 | 
			
		||||
            _defs_edit_curve.draw,
 | 
			
		||||
            _defs_edit_curve.extrude_cursor,
 | 
			
		||||
        ],
 | 
			
		||||
@@ -1075,6 +1582,33 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
 | 
			
		||||
            None,
 | 
			
		||||
            _defs_weight_paint.gradient,
 | 
			
		||||
        ],
 | 
			
		||||
        'GPENCIL_PAINT': [
 | 
			
		||||
            _defs_gpencil_paint.generate_from_brushes,
 | 
			
		||||
        ],
 | 
			
		||||
        'GPENCIL_EDIT': [
 | 
			
		||||
            *_tools_select,
 | 
			
		||||
            None,
 | 
			
		||||
            *_tools_transform,
 | 
			
		||||
            None,
 | 
			
		||||
            _defs_gpencil_edit.bend,
 | 
			
		||||
            _defs_gpencil_edit.mirror,
 | 
			
		||||
            _defs_gpencil_edit.shear,
 | 
			
		||||
            _defs_gpencil_edit.tosphere,
 | 
			
		||||
        ],
 | 
			
		||||
        'GPENCIL_SCULPT': [
 | 
			
		||||
            _defs_gpencil_sculpt.smooth,
 | 
			
		||||
            _defs_gpencil_sculpt.thickness,
 | 
			
		||||
            _defs_gpencil_sculpt.strength,
 | 
			
		||||
            _defs_gpencil_sculpt.grab,
 | 
			
		||||
            _defs_gpencil_sculpt.push,
 | 
			
		||||
            _defs_gpencil_sculpt.twist,
 | 
			
		||||
            _defs_gpencil_sculpt.pinch,
 | 
			
		||||
            _defs_gpencil_sculpt.randomize,
 | 
			
		||||
            _defs_gpencil_sculpt.clone,
 | 
			
		||||
        ],
 | 
			
		||||
        'GPENCIL_WEIGHT': [
 | 
			
		||||
            _defs_gpencil_weight.paint,
 | 
			
		||||
        ],
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -128,6 +128,8 @@ class TOPBAR_HT_lower_bar(Header):
 | 
			
		||||
            pass
 | 
			
		||||
        elif mode == 'PARTICLE':
 | 
			
		||||
            layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".paint_common", category="")
 | 
			
		||||
        elif mode == 'GPENCIL_PAINT':
 | 
			
		||||
            layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".greasepencil_paint", category="")
 | 
			
		||||
 | 
			
		||||
    def draw_center(self, context):
 | 
			
		||||
        pass
 | 
			
		||||
@@ -165,6 +167,15 @@ class TOPBAR_HT_lower_bar(Header):
 | 
			
		||||
            layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".particlemode", category="")
 | 
			
		||||
        elif mode == 'OBJECT':
 | 
			
		||||
            layout.popover_group(space_type='PROPERTIES', region_type='WINDOW', context=".objectmode", category="")
 | 
			
		||||
        elif mode == 'GPENCIL_PAINT':
 | 
			
		||||
            layout.prop(context.tool_settings, "gpencil_stroke_placement_view3d", text='')
 | 
			
		||||
            if context.tool_settings.gpencil_stroke_placement_view3d in ('ORIGIN', 'CURSOR'):
 | 
			
		||||
                layout.prop(context.tool_settings.gpencil_sculpt, "lockaxis", text='')
 | 
			
		||||
            layout.prop(context.tool_settings, "use_gpencil_draw_onback", text="", icon='ORTHO')
 | 
			
		||||
            layout.prop(context.tool_settings, "use_gpencil_additive_drawing", text="", icon='FREEZE')
 | 
			
		||||
 | 
			
		||||
        elif mode == 'GPENCIL_SCULPT':
 | 
			
		||||
            layout.prop(context.tool_settings.gpencil_sculpt, "lockaxis", text='')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _draw_left_context_mode:
 | 
			
		||||
 
 | 
			
		||||
@@ -361,14 +361,16 @@ class USERPREF_PT_edit(Panel):
 | 
			
		||||
        row.separator()
 | 
			
		||||
 | 
			
		||||
        col = row.column()
 | 
			
		||||
        col.label(text="Grease Pencil:")
 | 
			
		||||
        col.label(text="Annotations:")
 | 
			
		||||
        sub = col.row()
 | 
			
		||||
        sub.prop(edit, "grease_pencil_default_color", text="Default Color")
 | 
			
		||||
        col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius")
 | 
			
		||||
        col.separator()
 | 
			
		||||
        col.label(text="Grease Pencil/Annotations:")
 | 
			
		||||
        col.separator()
 | 
			
		||||
        col.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance")
 | 
			
		||||
        col.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance")
 | 
			
		||||
        col.separator()
 | 
			
		||||
        col.prop(edit, "grease_pencil_default_color", text="Default Color")
 | 
			
		||||
        col.separator()
 | 
			
		||||
        col.prop(edit, "use_grease_pencil_simplify_stroke", text="Simplify Stroke")
 | 
			
		||||
        col.separator()
 | 
			
		||||
        col.separator()
 | 
			
		||||
@@ -527,7 +529,10 @@ class USERPREF_PT_system(Panel):
 | 
			
		||||
        col.prop(system, "gpu_viewport_quality")
 | 
			
		||||
 | 
			
		||||
        col.separator()
 | 
			
		||||
        col.label(text="Grease Pencil Options:")
 | 
			
		||||
        col.prop(system, "gpencil_multi_sample", text="")
 | 
			
		||||
 | 
			
		||||
        col.separator()
 | 
			
		||||
        col.label(text="Text Draw Options:")
 | 
			
		||||
        col.prop(system, "use_text_antialiasing")
 | 
			
		||||
        if system.use_text_antialiasing:
 | 
			
		||||
 
 | 
			
		||||
@@ -19,11 +19,8 @@
 | 
			
		||||
# <pep8 compliant>
 | 
			
		||||
import bpy
 | 
			
		||||
from bpy.types import Header, Menu, Panel
 | 
			
		||||
from .properties_grease_pencil_common import (
 | 
			
		||||
    GreasePencilDataPanel,
 | 
			
		||||
    GreasePencilPaletteColorPanel,
 | 
			
		||||
)
 | 
			
		||||
from .properties_paint_common import UnifiedPaintPanel
 | 
			
		||||
from .properties_grease_pencil_common import GreasePencilDataPanel
 | 
			
		||||
from bpy.app.translations import contexts as i18n_contexts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -80,18 +77,40 @@ class VIEW3D_HT_header(Header):
 | 
			
		||||
            row.operator("pose.paste", text="", icon='PASTEDOWN').flipped = False
 | 
			
		||||
            row.operator("pose.paste", text="", icon='PASTEFLIPDOWN').flipped = True
 | 
			
		||||
 | 
			
		||||
        # GPencil
 | 
			
		||||
        if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
            row.operator("gpencil.copy", text="", icon='COPYDOWN')
 | 
			
		||||
            row.operator("gpencil.paste", text="", icon='PASTEDOWN')
 | 
			
		||||
        # Grease Pencil
 | 
			
		||||
        if obj and obj.type == 'GPENCIL' and context.gpencil_data:
 | 
			
		||||
            gpd = context.gpencil_data
 | 
			
		||||
 | 
			
		||||
            # XXX: icon
 | 
			
		||||
            layout.prop(context.gpencil_data, "use_onion_skinning", text="Onion Skins", icon='PARTICLE_PATH')
 | 
			
		||||
            if gpd.is_stroke_paint_mode:
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.popover(
 | 
			
		||||
                    panel="VIEW3D_PT_tools_grease_pencil_shapes",
 | 
			
		||||
                    text="Shapes"
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
            row.prop(tool_settings.gpencil_sculpt, "use_select_mask")
 | 
			
		||||
            row.prop(tool_settings.gpencil_sculpt, "selection_alpha", slider=True)
 | 
			
		||||
            if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode:
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(gpd, "use_multiedit", text="", icon="FORCE_HARMONIC")
 | 
			
		||||
 | 
			
		||||
                sub = row.row(align=True)
 | 
			
		||||
                sub.active = gpd.use_multiedit
 | 
			
		||||
                sub.popover(
 | 
			
		||||
                    panel="VIEW3D_PT_gpencil_multi_frame",
 | 
			
		||||
                    text="Multiframe"
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            if gpd.use_stroke_edit_mode:
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.operator("gpencil.copy", text="", icon='COPYDOWN')
 | 
			
		||||
                row.operator("gpencil.paste", text="", icon='PASTEDOWN')
 | 
			
		||||
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(tool_settings.gpencil_sculpt, "use_select_mask", text="")
 | 
			
		||||
 | 
			
		||||
                row.popover(
 | 
			
		||||
                    panel="VIEW3D_PT_tools_grease_pencil_interpolate",
 | 
			
		||||
                    text="Interpolate"
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
        VIEW3D_MT_editor_menus.draw_collapsible(context, layout)
 | 
			
		||||
 | 
			
		||||
@@ -101,7 +120,7 @@ class VIEW3D_HT_header(Header):
 | 
			
		||||
        scene = context.scene
 | 
			
		||||
 | 
			
		||||
        # Orientation
 | 
			
		||||
        if object_mode in {'OBJECT', 'EDIT', 'POSE'}:
 | 
			
		||||
        if object_mode in {'OBJECT', 'EDIT', 'POSE', 'GPENCIL_EDIT'}:
 | 
			
		||||
            orientation = scene.transform_orientation
 | 
			
		||||
            current_orientation = scene.current_orientation
 | 
			
		||||
 | 
			
		||||
@@ -126,7 +145,8 @@ class VIEW3D_HT_header(Header):
 | 
			
		||||
        if obj is None:
 | 
			
		||||
            show_snap = True
 | 
			
		||||
        else:
 | 
			
		||||
            if object_mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT'}:
 | 
			
		||||
            if object_mode not in {'SCULPT', 'VERTEX_PAINT', 'WEIGHT_PAINT', 'TEXTURE_PAINT',
 | 
			
		||||
                                   'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}:
 | 
			
		||||
                show_snap = True
 | 
			
		||||
            else:
 | 
			
		||||
 | 
			
		||||
@@ -160,13 +180,15 @@ class VIEW3D_HT_header(Header):
 | 
			
		||||
 | 
			
		||||
        # Proportional editing
 | 
			
		||||
        if obj:
 | 
			
		||||
            if context.gpencil_data and context.gpencil_data.use_stroke_edit_mode:
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(tool_settings, "proportional_edit", icon_only=True)
 | 
			
		||||
            gpd = context.gpencil_data
 | 
			
		||||
            if gpd is not None:
 | 
			
		||||
                if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode:
 | 
			
		||||
                    row = layout.row(align=True)
 | 
			
		||||
                    row.prop(tool_settings, "proportional_edit", icon_only=True)
 | 
			
		||||
 | 
			
		||||
                sub = row.row(align=True)
 | 
			
		||||
                sub.active = tool_settings.proportional_edit != 'DISABLED'
 | 
			
		||||
                sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
 | 
			
		||||
                    sub = row.row(align=True)
 | 
			
		||||
                    sub.active = tool_settings.proportional_edit != 'DISABLED'
 | 
			
		||||
                    sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
 | 
			
		||||
 | 
			
		||||
            elif object_mode in {'EDIT', 'PARTICLE_EDIT'}:
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
@@ -190,7 +212,7 @@ class VIEW3D_HT_header(Header):
 | 
			
		||||
                sub.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
 | 
			
		||||
 | 
			
		||||
        # Pivot
 | 
			
		||||
        if object_mode in {'OBJECT', 'EDIT', 'POSE'}:
 | 
			
		||||
        if object_mode in {'OBJECT', 'EDIT', 'POSE', 'GPENCIL_EDIT', 'GPENCIL_SCULPT'}:
 | 
			
		||||
            pivot_point = tool_settings.transform_pivot_point
 | 
			
		||||
            act_pivot_point = bpy.types.ToolSettings.bl_rna.properties["transform_pivot_point"].enum_items[pivot_point]
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
@@ -234,13 +256,14 @@ class VIEW3D_MT_editor_menus(Menu):
 | 
			
		||||
        obj = context.active_object
 | 
			
		||||
        mode_string = context.mode
 | 
			
		||||
        edit_object = context.edit_object
 | 
			
		||||
        gp_edit = context.gpencil_data and context.gpencil_data.use_stroke_edit_mode
 | 
			
		||||
        gp_edit = obj and obj.mode in {'GPENCIL_EDIT', 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}
 | 
			
		||||
 | 
			
		||||
        layout.menu("VIEW3D_MT_view")
 | 
			
		||||
 | 
			
		||||
        # Select Menu
 | 
			
		||||
        if gp_edit:
 | 
			
		||||
            layout.menu("VIEW3D_MT_select_gpencil")
 | 
			
		||||
            if mode_string not in {'GPENCIL_PAINT', 'GPENCIL_WEIGHT'}:
 | 
			
		||||
                layout.menu("VIEW3D_MT_select_gpencil")
 | 
			
		||||
        elif mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
 | 
			
		||||
            mesh = obj.data
 | 
			
		||||
            if mesh.use_paint_mask:
 | 
			
		||||
@@ -266,7 +289,15 @@ class VIEW3D_MT_editor_menus(Menu):
 | 
			
		||||
            layout.menu("INFO_MT_edit_armature_add", text="Add")
 | 
			
		||||
 | 
			
		||||
        if gp_edit:
 | 
			
		||||
            layout.menu("VIEW3D_MT_edit_gpencil")
 | 
			
		||||
            if obj and obj.mode == 'GPENCIL_PAINT':
 | 
			
		||||
                layout.menu("VIEW3D_MT_paint_gpencil")
 | 
			
		||||
            elif obj and obj.mode == 'GPENCIL_EDIT':
 | 
			
		||||
                layout.menu("VIEW3D_MT_edit_gpencil")
 | 
			
		||||
            elif obj and obj.mode == 'GPENCIL_SCULPT':
 | 
			
		||||
                layout.menu("VIEW3D_MT_sculpt_gpencil")
 | 
			
		||||
            elif obj and obj.mode == 'GPENCIL_WEIGHT':
 | 
			
		||||
                layout.menu("VIEW3D_MT_weight_gpencil")
 | 
			
		||||
 | 
			
		||||
        elif edit_object:
 | 
			
		||||
            layout.menu("VIEW3D_MT_edit_%s" % edit_object.type.lower())
 | 
			
		||||
 | 
			
		||||
@@ -1194,6 +1225,7 @@ class VIEW3D_MT_select_gpencil(Menu):
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.select_linked", text="Linked")
 | 
			
		||||
        layout.operator("gpencil.select_alternate")
 | 
			
		||||
        layout.operator_menu_enum("gpencil.select_grouped", "type", text="Grouped")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
@@ -1454,6 +1486,7 @@ class INFO_MT_add(Menu):
 | 
			
		||||
        layout.menu("INFO_MT_armature_add", icon='OUTLINER_OB_ARMATURE')
 | 
			
		||||
        layout.operator("object.add", text="Lattice", icon='OUTLINER_OB_LATTICE').type = 'LATTICE'
 | 
			
		||||
        layout.operator_menu_enum("object.empty_add", "type", text="Empty", icon='OUTLINER_OB_EMPTY')
 | 
			
		||||
        layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL')
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("object.speaker_add", text="Speaker", icon='OUTLINER_OB_SPEAKER')
 | 
			
		||||
@@ -3110,12 +3143,17 @@ class VIEW3D_MT_edit_gpencil_delete(Menu):
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.dissolve")
 | 
			
		||||
        layout.operator_enum("gpencil.dissolve", "type")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.active_frames_delete_all")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes").mode = 'ACTIVE'
 | 
			
		||||
        layout.operator("gpencil.frame_clean_fill", text="Clean Boundary Strokes all Frames").mode = 'ALL'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Edit Curve
 | 
			
		||||
# draw_curve is used by VIEW3D_MT_edit_curve and VIEW3D_MT_edit_surface
 | 
			
		||||
@@ -3476,11 +3514,34 @@ class VIEW3D_MT_edit_armature_delete(Menu):
 | 
			
		||||
        layout.operator("armature.dissolve", text="Dissolve")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# ********** GPencil Stroke Edit menu **********
 | 
			
		||||
# ********** Grease Pencil Stroke menus **********
 | 
			
		||||
class VIEW3D_MT_gpencil_simplify(Menu):
 | 
			
		||||
    bl_label = "Simplify"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.operator("gpencil.stroke_simplify_fixed", text="Fixed")
 | 
			
		||||
        layout.operator("gpencil.stroke_simplify", text="Adaptative")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_MT_paint_gpencil(Menu):
 | 
			
		||||
    bl_label = "Strokes"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        layout.menu("VIEW3D_MT_gpencil_animation")
 | 
			
		||||
        layout.menu("VIEW3D_MT_edit_gpencil_interpolate")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.delete", text="Delete Frame").type = 'FRAME'
 | 
			
		||||
        layout.operator("gpencil.active_frames_delete_all")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_MT_edit_gpencil(Menu):
 | 
			
		||||
    bl_label = "GPencil"
 | 
			
		||||
    bl_label = "Strokes"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        tool_settings = context.tool_settings
 | 
			
		||||
@@ -3488,44 +3549,41 @@ class VIEW3D_MT_edit_gpencil(Menu):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        layout.menu("VIEW3D_MT_edit_gpencil_transform")
 | 
			
		||||
        layout.operator("transform.mirror", text="Mirror")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
        layout.menu("GPENCIL_MT_snap")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.brush_paint", text="Sculpt Strokes").wait_for_input = True
 | 
			
		||||
        layout.prop_menu_enum(tool_settings.gpencil_sculpt, "tool", text="Sculpt Brush")
 | 
			
		||||
        layout.menu("VIEW3D_MT_gpencil_animation")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.menu("VIEW3D_MT_object_animation")   # NOTE: provides keyingset access...
 | 
			
		||||
        layout.menu("VIEW3D_MT_edit_gpencil_interpolate")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.duplicate_move", text="Duplicate")
 | 
			
		||||
        layout.operator("gpencil.stroke_subdivide", text="Subdivide")
 | 
			
		||||
        layout.menu("VIEW3D_MT_gpencil_simplify")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("gpencil.stroke_separate", "mode", text="Separate...")
 | 
			
		||||
        layout.operator("gpencil.stroke_split", text="Split")
 | 
			
		||||
        layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...")
 | 
			
		||||
        layout.operator("gpencil.stroke_flip", text="Flip Direction")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.copy", text="Copy")
 | 
			
		||||
        layout.operator("gpencil.paste", text="Paste")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.reveal")
 | 
			
		||||
        layout.operator("gpencil.hide", text="Show Active Layer Only").unselected = True
 | 
			
		||||
        layout.operator("gpencil.hide", text="Hide Active Layer").unselected = False
 | 
			
		||||
        layout.operator("gpencil.paste", text="Paste").type = 'COPY'
 | 
			
		||||
        layout.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE'
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer")
 | 
			
		||||
        layout.operator("gpencil.stroke_change_color", text="Move to Color")
 | 
			
		||||
        layout.operator("gpencil.stroke_change_color", text="Change Color")
 | 
			
		||||
        layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
@@ -3535,6 +3593,82 @@ class VIEW3D_MT_edit_gpencil(Menu):
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.menu("VIEW3D_MT_edit_gpencil_delete")
 | 
			
		||||
        layout.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("gpencil.frame_clean_fill", text="Clean Boundary Strokes...", property="mode")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_MT_sculpt_gpencil(Menu):
 | 
			
		||||
    bl_label = "Strokes"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        layout.menu("VIEW3D_MT_edit_gpencil_transform")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
        layout.menu("GPENCIL_MT_snap")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.duplicate_move", text="Duplicate")
 | 
			
		||||
        layout.operator("gpencil.stroke_subdivide", text="Subdivide")
 | 
			
		||||
        layout.menu("VIEW3D_MT_gpencil_simplify")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("gpencil.stroke_separate", "mode", text="Separate...")
 | 
			
		||||
        layout.operator("gpencil.stroke_split", text="Split")
 | 
			
		||||
        layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...")
 | 
			
		||||
        layout.operator("gpencil.stroke_flip", text="Flip Direction")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.copy", text="Copy")
 | 
			
		||||
        layout.operator("gpencil.paste", text="Paste").type = 'COPY'
 | 
			
		||||
        layout.operator("gpencil.paste", text="Paste & Merge").type = 'MERGE'
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer")
 | 
			
		||||
        layout.operator("gpencil.stroke_change_color", text="Change Color")
 | 
			
		||||
        layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
 | 
			
		||||
        layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_MT_weight_gpencil(Menu):
 | 
			
		||||
    bl_label = "Weights"
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.vertex_group_invert", text="Invert")
 | 
			
		||||
        layout.operator("gpencil.vertex_group_smooth", text="Smooth")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_MT_gpencil_animation(Menu):
 | 
			
		||||
    bl_label = "Animation"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        ob = context.active_object
 | 
			
		||||
        return ob and ob.type == 'GPENCIL' and ob.mode != 'OBJECT'
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
 | 
			
		||||
        layout.operator("gpencil.blank_frame_add")
 | 
			
		||||
        layout.operator("gpencil.active_frames_delete_all", text="Delete Frame(s)")
 | 
			
		||||
 | 
			
		||||
        layout.separator()
 | 
			
		||||
        layout.operator("gpencil.frame_duplicate", text="Duplicate Active Frame")
 | 
			
		||||
        layout.operator("gpencil.frame_duplicate", text="Duplicate All Layers").mode = 'ALL'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_MT_edit_gpencil_transform(Menu):
 | 
			
		||||
@@ -3595,20 +3729,6 @@ class VIEW3D_MT_view_pie(Menu):
 | 
			
		||||
# ********** Panel **********
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
 | 
			
		||||
    # NOTE: this is just a wrapper around the generic GP Panel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
 | 
			
		||||
    # NOTE: this is just a wrapper around the generic GP Panel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_view3d_properties(Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
@@ -3720,6 +3840,7 @@ class VIEW3D_PT_object_type_visibility(Panel):
 | 
			
		||||
            "armature",
 | 
			
		||||
            "lattice",
 | 
			
		||||
            "empty",
 | 
			
		||||
		    "grease_pencil",
 | 
			
		||||
            "camera",
 | 
			
		||||
            "light",
 | 
			
		||||
            "light_probe",
 | 
			
		||||
@@ -4040,6 +4161,8 @@ class VIEW3D_PT_overlay_guides(Panel):
 | 
			
		||||
        if shading.type == 'MATERIAL':
 | 
			
		||||
            col.prop(overlay, "show_look_dev")
 | 
			
		||||
 | 
			
		||||
        col.prop(overlay, "show_annotation", text="Annotations")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_overlay_object(Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
@@ -4578,6 +4701,60 @@ class VIEW3D_PT_transform_orientations(Panel):
 | 
			
		||||
            row.operator("transform.delete_orientation", text="", icon='X', emboss=False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_overlay_gpencil_options(Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'HEADER'
 | 
			
		||||
    bl_parent_id = 'VIEW3D_PT_overlay'
 | 
			
		||||
    bl_label = ""
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        return context.object and context.object.type == 'GPENCIL'
 | 
			
		||||
 | 
			
		||||
    def draw_header(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.label(text={
 | 
			
		||||
            'GPENCIL_PAINT': "Draw Grease Pencil",
 | 
			
		||||
            'GPENCIL_EDIT': "Edit Grease Pencil",
 | 
			
		||||
            'GPENCIL_SCULPT': "Sculpt Grease Pencil",
 | 
			
		||||
            'GPENCIL_WEIGHT': "Weight Grease Pencil",
 | 
			
		||||
            'OBJECT': "Grease Pencil",
 | 
			
		||||
        }[context.mode])
 | 
			
		||||
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        view = context.space_data
 | 
			
		||||
        overlay = view.overlay
 | 
			
		||||
 | 
			
		||||
        layout.prop(overlay, "use_gpencil_onion_skin", text="Onion Skin")
 | 
			
		||||
 | 
			
		||||
        col = layout.column()
 | 
			
		||||
        row = col.row()
 | 
			
		||||
        row.prop(overlay, "use_gpencil_paper", text="")
 | 
			
		||||
        sub = row.row()
 | 
			
		||||
        sub.active = overlay.use_gpencil_paper
 | 
			
		||||
        sub.prop(overlay, "gpencil_paper_opacity", text="Fade 3D Objects", slider=True)
 | 
			
		||||
 | 
			
		||||
        col = layout.column()
 | 
			
		||||
        row = col.row()
 | 
			
		||||
        row.prop(overlay, "use_gpencil_grid", text="")
 | 
			
		||||
        sub = row.row()
 | 
			
		||||
        sub.active = overlay.use_gpencil_grid
 | 
			
		||||
        sub.prop(overlay, "gpencil_grid_opacity", text="Canvas Grid", slider=True)
 | 
			
		||||
 | 
			
		||||
        if overlay.use_gpencil_grid:
 | 
			
		||||
            row = layout.row(align=True)
 | 
			
		||||
            row.prop(overlay, "gpencil_grid_scale")
 | 
			
		||||
            col = row.column()
 | 
			
		||||
            col.prop(overlay, "gpencil_grid_lines", text="Subdivisions")
 | 
			
		||||
            col.prop(overlay, "gpencil_grid_axis")
 | 
			
		||||
 | 
			
		||||
        if context.object.mode in {'GPENCIL_EDIT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}:
 | 
			
		||||
            layout.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines")
 | 
			
		||||
            layout.prop(overlay, "use_gpencil_multiedit_line_only", text="Show Edit Lines only in multiframe")
 | 
			
		||||
            layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_quad_view(Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
@@ -4605,6 +4782,14 @@ class VIEW3D_PT_quad_view(Panel):
 | 
			
		||||
        row.prop(region, "use_box_clip")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Annotation properties
 | 
			
		||||
class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
 | 
			
		||||
    # NOTE: this is just a wrapper around the generic GP Panel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_view3d_stereo(Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'UI'
 | 
			
		||||
@@ -4684,6 +4869,27 @@ class VIEW3D_PT_context_properties(Panel):
 | 
			
		||||
            rna_prop_ui.draw(self.layout, context, member, object, False)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil Object - Multiframe falloff tools
 | 
			
		||||
class VIEW3D_PT_gpencil_multi_frame(Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'HEADER'
 | 
			
		||||
    bl_label = "Multi Frame"
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
        settings = context.tool_settings.gpencil_sculpt
 | 
			
		||||
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        col = layout.column(align=True)
 | 
			
		||||
        col.prop(settings, "use_multiframe_falloff")
 | 
			
		||||
 | 
			
		||||
        # Falloff curve
 | 
			
		||||
        if gpd.use_multiedit and settings.use_multiframe_falloff:
 | 
			
		||||
            layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
classes = (
 | 
			
		||||
    VIEW3D_HT_header,
 | 
			
		||||
    VIEW3D_MT_editor_menus,
 | 
			
		||||
@@ -4791,8 +4997,13 @@ classes = (
 | 
			
		||||
    VIEW3D_MT_edit_mesh_clean,
 | 
			
		||||
    VIEW3D_MT_edit_mesh_delete,
 | 
			
		||||
    VIEW3D_MT_edit_mesh_showhide,
 | 
			
		||||
    VIEW3D_MT_paint_gpencil,
 | 
			
		||||
    VIEW3D_MT_edit_gpencil,
 | 
			
		||||
    VIEW3D_MT_edit_gpencil_delete,
 | 
			
		||||
    VIEW3D_MT_sculpt_gpencil,
 | 
			
		||||
    VIEW3D_MT_weight_gpencil,
 | 
			
		||||
    VIEW3D_MT_gpencil_animation,
 | 
			
		||||
    VIEW3D_MT_gpencil_simplify,
 | 
			
		||||
    VIEW3D_MT_edit_curve,
 | 
			
		||||
    VIEW3D_MT_edit_curve_ctrlpoints,
 | 
			
		||||
    VIEW3D_MT_edit_curve_segments,
 | 
			
		||||
@@ -4815,12 +5026,12 @@ classes = (
 | 
			
		||||
    VIEW3D_MT_edit_gpencil_interpolate,
 | 
			
		||||
    VIEW3D_MT_object_mode_pie,
 | 
			
		||||
    VIEW3D_MT_view_pie,
 | 
			
		||||
    VIEW3D_PT_grease_pencil,
 | 
			
		||||
    VIEW3D_PT_grease_pencil_palettecolor,
 | 
			
		||||
    VIEW3D_PT_view3d_properties,
 | 
			
		||||
    VIEW3D_PT_view3d_camera_lock,
 | 
			
		||||
    VIEW3D_PT_view3d_cursor,
 | 
			
		||||
    VIEW3D_PT_object_type_visibility,
 | 
			
		||||
    VIEW3D_PT_grease_pencil,
 | 
			
		||||
    VIEW3D_PT_gpencil_multi_frame,
 | 
			
		||||
    VIEW3D_PT_quad_view,
 | 
			
		||||
    VIEW3D_PT_view3d_stereo,
 | 
			
		||||
    VIEW3D_PT_shading,
 | 
			
		||||
@@ -4849,6 +5060,7 @@ classes = (
 | 
			
		||||
    VIEW3D_PT_pivot_point,
 | 
			
		||||
    VIEW3D_PT_snapping,
 | 
			
		||||
    VIEW3D_PT_transform_orientations,
 | 
			
		||||
    VIEW3D_PT_overlay_gpencil_options,
 | 
			
		||||
    VIEW3D_PT_context_properties,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,19 +20,17 @@
 | 
			
		||||
import bpy
 | 
			
		||||
from bpy.types import Menu, Panel, UIList
 | 
			
		||||
from .properties_grease_pencil_common import (
 | 
			
		||||
    GreasePencilDrawingToolsPanel,
 | 
			
		||||
    GreasePencilStrokeEditPanel,
 | 
			
		||||
    GreasePencilInterpolatePanel,
 | 
			
		||||
    GreasePencilStrokeSculptPanel,
 | 
			
		||||
    GreasePencilBrushPanel,
 | 
			
		||||
    GreasePencilBrushCurvesPanel
 | 
			
		||||
)
 | 
			
		||||
        GreasePencilStrokeEditPanel,
 | 
			
		||||
        GreasePencilStrokeSculptPanel,
 | 
			
		||||
        GreasePencilAppearancePanel,
 | 
			
		||||
        )
 | 
			
		||||
from .properties_paint_common import (
 | 
			
		||||
    UnifiedPaintPanel,
 | 
			
		||||
    brush_texture_settings,
 | 
			
		||||
    brush_texpaint_common,
 | 
			
		||||
    brush_mask_texture_settings,
 | 
			
		||||
)
 | 
			
		||||
        UnifiedPaintPanel,
 | 
			
		||||
        brush_texture_settings,
 | 
			
		||||
        brush_texpaint_common,
 | 
			
		||||
        brush_mask_texture_settings,
 | 
			
		||||
        )
 | 
			
		||||
from bl_operators.presets import PresetMenu
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class View3DPanel:
 | 
			
		||||
@@ -70,6 +68,12 @@ def draw_vpaint_symmetry(layout, vpaint):
 | 
			
		||||
    col.use_property_split = True
 | 
			
		||||
    col.prop(vpaint, "radial_symmetry", text="Radial")
 | 
			
		||||
 | 
			
		||||
# Most of these panels should not be visible in GP edit modes
 | 
			
		||||
def is_not_gpencil_edit_mode(context):
 | 
			
		||||
    is_gpmode = context.active_object and \
 | 
			
		||||
                context.active_object.mode in {'GPENCIL_EDIT', 'GPENCIL_PAINT', 'GPENCIL_SCULPT', 'GPENCIL_WEIGHT'}
 | 
			
		||||
    return not is_gpmode
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# ********** default tools for editmode_mesh ****************
 | 
			
		||||
 | 
			
		||||
@@ -1341,9 +1345,272 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
 | 
			
		||||
            sub.prop(pe, "fade_frames", slider=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing tools
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
 | 
			
		||||
# ********** grease pencil object tool panels ****************
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing brushes
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_brush(View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_paint"
 | 
			
		||||
    bl_label = "Brush"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        is_3d_view = context.space_data.type == 'VIEW_3D'
 | 
			
		||||
        if is_3d_view:
 | 
			
		||||
            if context.gpencil_data is None:
 | 
			
		||||
                return False
 | 
			
		||||
 | 
			
		||||
            gpd = context.gpencil_data
 | 
			
		||||
            return bool(gpd.is_stroke_paint_mode)
 | 
			
		||||
        else:
 | 
			
		||||
            return True
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
        layout.use_property_decorate = False
 | 
			
		||||
 | 
			
		||||
        ts = context.scene.tool_settings
 | 
			
		||||
        settings = ts.gpencil_paint
 | 
			
		||||
 | 
			
		||||
        row = layout.row()
 | 
			
		||||
        col = row.column()
 | 
			
		||||
        col.template_ID_preview(settings, "brush", new="brush.add_gpencil", rows=3, cols=8)
 | 
			
		||||
 | 
			
		||||
        col = row.column()
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
 | 
			
		||||
        sub = col.column(align=True)
 | 
			
		||||
        sub.operator("gpencil.brush_presets_create", icon='HELP', text="")
 | 
			
		||||
 | 
			
		||||
        if brush is not None:
 | 
			
		||||
            # XXX: Items in "sub" currently show up beside the brush selector in a separate column
 | 
			
		||||
            if gp_settings.gpencil_brush_type == 'ERASE':
 | 
			
		||||
                sub.prop(gp_settings, "default_eraser", text="")
 | 
			
		||||
 | 
			
		||||
            # Brush details
 | 
			
		||||
            if gp_settings.gpencil_brush_type == 'ERASE':
 | 
			
		||||
                col = layout.column(align=True)
 | 
			
		||||
                col.prop(brush, "size", text="Radius")
 | 
			
		||||
 | 
			
		||||
                col.separator()
 | 
			
		||||
                row = col.row()
 | 
			
		||||
                row.prop(gp_settings, "eraser_mode", expand=True)
 | 
			
		||||
            elif gp_settings.gpencil_brush_type == 'FILL':
 | 
			
		||||
                col = layout.column(align=True)
 | 
			
		||||
                col.prop(gp_settings, "gpencil_fill_leak", text="Leak Size")
 | 
			
		||||
                col.prop(brush, "size", text="Thickness")
 | 
			
		||||
                col.prop(gp_settings, "gpencil_fill_simplyfy_level", text="Simplify")
 | 
			
		||||
 | 
			
		||||
                col = layout.row(align=True)
 | 
			
		||||
                col.template_ID(gp_settings, "material")
 | 
			
		||||
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(gp_settings, "gpencil_fill_draw_mode", text="Boundary Draw Mode")
 | 
			
		||||
                row.prop(gp_settings, "gpencil_fill_show_boundary", text="", icon='GRID')
 | 
			
		||||
 | 
			
		||||
                col = layout.column(align=True)
 | 
			
		||||
                col.enabled = gp_settings.gpencil_fill_draw_mode != "STROKE"
 | 
			
		||||
                col.prop(gp_settings, "gpencil_fill_hide", text="Hide Transparent Lines")
 | 
			
		||||
                sub = col.row(align=True)
 | 
			
		||||
                sub.enabled = gp_settings.gpencil_fill_hide
 | 
			
		||||
                sub.prop(gp_settings, "gpencil_fill_threshold", text="Threshold")
 | 
			
		||||
            else:  # bgpsettings.gpencil_brush_type == 'DRAW':
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(brush, "size", text="Radius")
 | 
			
		||||
                row.prop(gp_settings, "use_pressure", text="", icon='STYLUS_PRESSURE')
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.prop(gp_settings, "pen_strength", slider=True)
 | 
			
		||||
                row.prop(gp_settings, "use_strength_pressure", text="", icon='STYLUS_PRESSURE')
 | 
			
		||||
 | 
			
		||||
                row = layout.row(align=True)
 | 
			
		||||
                row.template_ID(gp_settings, "material")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing brushes options
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_brush_option(View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_paint"
 | 
			
		||||
    bl_label = "Options"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    def draw_header_preset(self, context):
 | 
			
		||||
        VIEW3D_PT_gpencil_brush_presets.draw_panel_header(self.layout)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
        layout.use_property_decorate = False
 | 
			
		||||
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
 | 
			
		||||
        if brush is not None:
 | 
			
		||||
            col = layout.column(align=True)
 | 
			
		||||
            col.prop(gp_settings, "input_samples")
 | 
			
		||||
            col.separator()
 | 
			
		||||
 | 
			
		||||
            col.prop(gp_settings, "active_smooth_factor")
 | 
			
		||||
            col.separator()
 | 
			
		||||
 | 
			
		||||
            col.prop(gp_settings, "angle", slider=True)
 | 
			
		||||
            col.prop(gp_settings, "angle_factor", text="Factor", slider=True)
 | 
			
		||||
            col.separator()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_paint"
 | 
			
		||||
    bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
 | 
			
		||||
    bl_label = "Stabilizer"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
 | 
			
		||||
        return brush is not None and gp_settings.gpencil_brush_type == 'DRAW'
 | 
			
		||||
 | 
			
		||||
    def draw_header(self, context):
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
        self.layout.prop(gp_settings, "use_stabilizer", text="")
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
        layout.use_property_decorate = False
 | 
			
		||||
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
        layout.active = gp_settings.use_stabilizer
 | 
			
		||||
 | 
			
		||||
        layout.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
 | 
			
		||||
        layout.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_brush_settings(View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_paint"
 | 
			
		||||
    bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
 | 
			
		||||
    bl_label = "Post-processing Settings"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
 | 
			
		||||
        return brush is not None
 | 
			
		||||
 | 
			
		||||
    def draw_header(self, context):
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
        self.layout.prop(gp_settings, "enable_settings", text="")
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
        layout.use_property_decorate = False
 | 
			
		||||
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
        layout.active = gp_settings.enable_settings
 | 
			
		||||
 | 
			
		||||
        layout.prop(gp_settings, "pen_smooth_factor")
 | 
			
		||||
        layout.prop(gp_settings, "pen_smooth_steps")
 | 
			
		||||
 | 
			
		||||
        layout.prop(gp_settings, "pen_thick_smooth_factor")
 | 
			
		||||
        layout.prop(gp_settings, "pen_thick_smooth_steps")
 | 
			
		||||
 | 
			
		||||
        layout.prop(gp_settings, "pen_subdivision_steps")
 | 
			
		||||
        layout.prop(gp_settings, "random_subdiv", text="Randomness", slider=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_paint"
 | 
			
		||||
    bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_option'
 | 
			
		||||
    bl_label = "Random Settings"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
 | 
			
		||||
        return brush is not None
 | 
			
		||||
 | 
			
		||||
    def draw_header(self, context):
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
        self.layout.prop(gp_settings, "enable_random", text="")
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
        layout.use_property_decorate = False
 | 
			
		||||
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
        layout.active = gp_settings.enable_random
 | 
			
		||||
 | 
			
		||||
        layout.prop(gp_settings, "random_pressure", text="Pressure", slider=True)
 | 
			
		||||
        layout.prop(gp_settings, "random_strength", text="Strength", slider=True)
 | 
			
		||||
        layout.prop(gp_settings, "uv_random", text="UV", slider=True)
 | 
			
		||||
 | 
			
		||||
        row = layout.row(align=True)
 | 
			
		||||
        row.prop(gp_settings, "pen_jitter", slider=True)
 | 
			
		||||
        row.prop(gp_settings, "use_jitter_pressure", text="", icon='STYLUS_PRESSURE')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawingcurves
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_brushcurves(View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_paint"
 | 
			
		||||
    bl_label = "Curves"
 | 
			
		||||
    bl_options = {'DEFAULT_CLOSED'}
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
        brush = context.active_gpencil_brush
 | 
			
		||||
        gp_settings = brush.gpencil_settings
 | 
			
		||||
 | 
			
		||||
        # Brush
 | 
			
		||||
        layout.label("Sensitivity")
 | 
			
		||||
        layout.template_curve_mapping(gp_settings, "curve_sensitivity", brush=True)
 | 
			
		||||
 | 
			
		||||
        layout.label("Strength")
 | 
			
		||||
        layout.template_curve_mapping(gp_settings, "curve_strength", brush=True)
 | 
			
		||||
 | 
			
		||||
        layout.label("Jitter")
 | 
			
		||||
        layout.template_curve_mapping(gp_settings, "curve_jitter", brush=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil create shapes
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_shapes(View3DPanel, Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'HEADER'
 | 
			
		||||
    bl_label = "Shapes"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        ob = context.active_object
 | 
			
		||||
        return ob and ob.type == 'GPENCIL'
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
 | 
			
		||||
        col = layout.column(align=True)
 | 
			
		||||
        col.operator("gpencil.primitive", text="Line", icon='IPO_CONSTANT').type = 'LINE'
 | 
			
		||||
        col.operator("gpencil.primitive", text="Rectangle", icon='UV_FACESEL').type = 'BOX'
 | 
			
		||||
        col.operator("gpencil.primitive", text="Circle", icon='ANTIALIASED').type = 'CIRCLE'
 | 
			
		||||
 | 
			
		||||
        layout.operator("object.gpencil_add", text="Monkey", icon='MONKEY').type = 'MONKEY'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke editing tools
 | 
			
		||||
@@ -1352,24 +1619,109 @@ class VIEW3D_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke interpolation tools
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_interpolate(GreasePencilInterpolatePanel, Panel):
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_interpolate(Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
    bl_region_type = 'HEADER'
 | 
			
		||||
    bl_label = "Interpolate"
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def poll(cls, context):
 | 
			
		||||
        if context.gpencil_data is None:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
        return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode)
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        settings = context.tool_settings.gpencil_interpolate
 | 
			
		||||
 | 
			
		||||
        col = layout.column(align=True)
 | 
			
		||||
        col.label("Interpolate Strokes")
 | 
			
		||||
        col.operator("gpencil.interpolate", text="Interpolate")
 | 
			
		||||
        col.operator("gpencil.interpolate_sequence", text="Sequence")
 | 
			
		||||
        col.operator("gpencil.interpolate_reverse", text="Remove Breakdowns")
 | 
			
		||||
 | 
			
		||||
        col = layout.column(align=True)
 | 
			
		||||
        col.label(text="Options:")
 | 
			
		||||
        col.prop(settings, "interpolate_all_layers")
 | 
			
		||||
        col.prop(settings, "interpolate_selected_only")
 | 
			
		||||
 | 
			
		||||
        col = layout.column(align=True)
 | 
			
		||||
        col.label(text="Sequence Options:")
 | 
			
		||||
        col.prop(settings, "type")
 | 
			
		||||
        if settings.type == 'CUSTOM':
 | 
			
		||||
            # TODO: Options for loading/saving curve presets?
 | 
			
		||||
            col.template_curve_mapping(settings, "interpolation_curve", brush=True)
 | 
			
		||||
        elif settings.type != 'LINEAR':
 | 
			
		||||
            col.prop(settings, "easing")
 | 
			
		||||
 | 
			
		||||
            if settings.type == 'BACK':
 | 
			
		||||
                layout.prop(settings, "back")
 | 
			
		||||
            elif setting.type == 'ELASTIC':
 | 
			
		||||
                sub = layout.column(align=True)
 | 
			
		||||
                sub.prop(settings, "amplitude")
 | 
			
		||||
                sub.prop(settings, "period")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil stroke sculpting tools
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_sculpt"
 | 
			
		||||
    bl_category = "Tools"
 | 
			
		||||
    bl_label = "Sculpt Strokes"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawing brushes
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
# Grease Pencil weight painting tools
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_weight_paint(View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_weight"
 | 
			
		||||
    bl_category = "Tools"
 | 
			
		||||
    bl_label = "Weight Paint"
 | 
			
		||||
 | 
			
		||||
# Grease Pencil drawingcurves
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def draw(self, context):
 | 
			
		||||
        layout = self.layout
 | 
			
		||||
        layout.use_property_split = True
 | 
			
		||||
        layout.use_property_decorate = False
 | 
			
		||||
 | 
			
		||||
        gpd = context.gpencil_data
 | 
			
		||||
        settings = context.tool_settings.gpencil_sculpt
 | 
			
		||||
        tool = settings.tool
 | 
			
		||||
        brush = settings.brush
 | 
			
		||||
 | 
			
		||||
        layout.template_icon_view(settings, "weight_tool", show_labels=True)
 | 
			
		||||
 | 
			
		||||
        col = layout.column()
 | 
			
		||||
        col.prop(brush, "size", slider=True)
 | 
			
		||||
        row = col.row(align=True)
 | 
			
		||||
        row.prop(brush, "strength", slider=True)
 | 
			
		||||
        row.prop(brush, "use_pressure_strength", text="")
 | 
			
		||||
 | 
			
		||||
        col.prop(brush, "use_falloff")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
 | 
			
		||||
    bl_space_type = 'VIEW_3D'
 | 
			
		||||
# Grease Pencil Brush Appeareance (one for each mode)
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_paint_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_paint"
 | 
			
		||||
    bl_label = "Appearance"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_sculpt_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_sculpt"
 | 
			
		||||
    bl_label = "Appearance"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_tools_grease_pencil_weight_appearance(GreasePencilAppearancePanel, View3DPanel, Panel):
 | 
			
		||||
    bl_context = ".greasepencil_weight"
 | 
			
		||||
    bl_label = "Appearance"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VIEW3D_PT_gpencil_brush_presets(PresetMenu):
 | 
			
		||||
    """Brush settings"""
 | 
			
		||||
    bl_label = "Brush Presets"
 | 
			
		||||
    preset_subdir = "gpencil_brush"
 | 
			
		||||
    preset_operator = "script.execute_preset"
 | 
			
		||||
    preset_add_operator = "scene.gpencil_brush_preset_add"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
classes = (
 | 
			
		||||
@@ -1401,12 +1753,21 @@ classes = (
 | 
			
		||||
    VIEW3D_PT_tools_projectpaint,
 | 
			
		||||
    VIEW3D_MT_tools_projectpaint_stencil,
 | 
			
		||||
    VIEW3D_PT_tools_particlemode,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_draw,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_edit,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_interpolate,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_sculpt,
 | 
			
		||||
 | 
			
		||||
    VIEW3D_PT_gpencil_brush_presets,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_brush,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_brush_option,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_brush_settings,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_brush_stabilizer,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_brush_random,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_brushcurves,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_shapes,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_sculpt,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_weight_paint,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_paint_appearance,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_sculpt_appearance,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_weight_appearance,
 | 
			
		||||
    VIEW3D_PT_tools_grease_pencil_interpolate,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":  # only for live edit.
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,9 @@ set(SRC_DNA_INC
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_fileglobal_types.h
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_freestyle_types.h
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_genfile.h
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_types.h
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_shader_fx_types.h
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_group_types.h
 | 
			
		||||
	${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h
 | 
			
		||||
@@ -112,6 +114,8 @@ add_subdirectory(gpu)
 | 
			
		||||
add_subdirectory(imbuf)
 | 
			
		||||
add_subdirectory(nodes)
 | 
			
		||||
add_subdirectory(modifiers)
 | 
			
		||||
add_subdirectory(gpencil_modifiers)
 | 
			
		||||
add_subdirectory(shader_fx)
 | 
			
		||||
add_subdirectory(makesdna)
 | 
			
		||||
add_subdirectory(makesrna)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,11 +28,14 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
enum eCurveMappingPreset;
 | 
			
		||||
struct bContext;
 | 
			
		||||
struct Brush;
 | 
			
		||||
struct Paint;
 | 
			
		||||
struct ImBuf;
 | 
			
		||||
struct ImagePool;
 | 
			
		||||
struct Main;
 | 
			
		||||
struct Scene;
 | 
			
		||||
struct ToolSettings;
 | 
			
		||||
struct UnifiedPaintSettings;
 | 
			
		||||
// enum eCurveMappingPreset;
 | 
			
		||||
 | 
			
		||||
@@ -45,14 +48,17 @@ void BKE_brush_system_exit(void);
 | 
			
		||||
/* datablock functions */
 | 
			
		||||
void BKE_brush_init(struct Brush *brush);
 | 
			
		||||
struct Brush *BKE_brush_add(struct Main *bmain, const char *name, const eObjectMode ob_mode);
 | 
			
		||||
struct Brush *BKE_brush_add_gpencil(struct Main *bmain, struct ToolSettings *ts, const char *name);
 | 
			
		||||
struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode);
 | 
			
		||||
void BKE_brush_copy_data(struct Main *bmain, struct Brush *brush_dst, const struct Brush *brush_src, const int flag);
 | 
			
		||||
struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush);
 | 
			
		||||
void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local);
 | 
			
		||||
void BKE_brush_unlink(struct Main *bmain, struct Brush *brush);
 | 
			
		||||
void BKE_brush_free(struct Brush *brush);
 | 
			
		||||
 | 
			
		||||
void BKE_brush_sculpt_reset(struct Brush *brush);
 | 
			
		||||
void BKE_brush_gpencil_presets(struct bContext *C);
 | 
			
		||||
struct Brush *BKE_brush_getactive_gpencil(struct ToolSettings *ts);
 | 
			
		||||
struct Paint *BKE_brush_get_gpencil_paint(struct ToolSettings *ts);
 | 
			
		||||
 | 
			
		||||
/* image icon function */
 | 
			
		||||
struct ImBuf *get_brush_icon(struct Brush *brush);
 | 
			
		||||
 
 | 
			
		||||
@@ -65,9 +65,7 @@ struct bPoseChannel;
 | 
			
		||||
struct bGPdata;
 | 
			
		||||
struct bGPDlayer;
 | 
			
		||||
struct bGPDframe;
 | 
			
		||||
struct bGPDpalette;
 | 
			
		||||
struct bGPDpalettecolor;
 | 
			
		||||
struct bGPDbrush;
 | 
			
		||||
struct Brush;
 | 
			
		||||
struct wmWindow;
 | 
			
		||||
struct wmWindowManager;
 | 
			
		||||
struct RenderEngineType;
 | 
			
		||||
@@ -120,6 +118,10 @@ enum {
 | 
			
		||||
	CTX_MODE_PAINT_TEXTURE,
 | 
			
		||||
	CTX_MODE_PARTICLE,
 | 
			
		||||
	CTX_MODE_OBJECT,
 | 
			
		||||
	CTX_MODE_GPENCIL_PAINT,
 | 
			
		||||
	CTX_MODE_GPENCIL_EDIT,
 | 
			
		||||
	CTX_MODE_GPENCIL_SCULPT,
 | 
			
		||||
	CTX_MODE_GPENCIL_WEIGHT,
 | 
			
		||||
	CTX_MODE_NUM /* must be last */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -313,9 +315,7 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list);
 | 
			
		||||
struct bGPdata *CTX_data_gpencil_data(const bContext *C);
 | 
			
		||||
struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C);
 | 
			
		||||
struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C);
 | 
			
		||||
struct bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C);
 | 
			
		||||
struct bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C);
 | 
			
		||||
struct bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C);
 | 
			
		||||
struct Brush *CTX_data_active_gpencil_brush(const bContext *C);
 | 
			
		||||
int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
 | 
			
		||||
int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
 | 
			
		||||
int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
 | 
			
		||||
 
 | 
			
		||||
@@ -31,25 +31,45 @@
 | 
			
		||||
 *  \author Joshua Leung
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
struct CurveMapping;
 | 
			
		||||
struct Depsgraph;
 | 
			
		||||
struct GpencilModifierData;
 | 
			
		||||
struct ToolSettings;
 | 
			
		||||
struct ListBase;
 | 
			
		||||
struct bGPdata;
 | 
			
		||||
struct bGPDlayer;
 | 
			
		||||
struct bGPDframe;
 | 
			
		||||
struct bGPDspoint;
 | 
			
		||||
struct bGPDstroke;
 | 
			
		||||
struct Material;
 | 
			
		||||
struct bGPDpalette;
 | 
			
		||||
struct bGPDpalettecolor;
 | 
			
		||||
struct Main;
 | 
			
		||||
struct BoundBox;
 | 
			
		||||
struct Brush;
 | 
			
		||||
struct Object;
 | 
			
		||||
struct bDeformGroup;
 | 
			
		||||
struct SimplifyGpencilModifierData;
 | 
			
		||||
struct InstanceGpencilModifierData;
 | 
			
		||||
struct LatticeGpencilModifierData;
 | 
			
		||||
 | 
			
		||||
struct MDeformVert;
 | 
			
		||||
struct MDeformWeight;
 | 
			
		||||
 | 
			
		||||
/* ------------ Grease-Pencil API ------------------ */
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_free_point_weights(struct MDeformVert *dvert);
 | 
			
		||||
void BKE_gpencil_free_stroke_weights(struct bGPDstroke *gps);
 | 
			
		||||
void BKE_gpencil_free_stroke(struct bGPDstroke *gps);
 | 
			
		||||
bool BKE_gpencil_free_strokes(struct bGPDframe *gpf);
 | 
			
		||||
void BKE_gpencil_free_frames(struct bGPDlayer *gpl);
 | 
			
		||||
void BKE_gpencil_free_layers(struct ListBase *list);
 | 
			
		||||
void BKE_gpencil_free_brushes(struct ListBase *list);
 | 
			
		||||
void BKE_gpencil_free_palettes(struct ListBase *list);
 | 
			
		||||
void BKE_gpencil_free(struct bGPdata *gpd, bool free_palettes);
 | 
			
		||||
bool BKE_gpencil_free_frame_runtime_data(struct bGPDframe *derived_gpf);
 | 
			
		||||
void BKE_gpencil_free_derived_frames(struct bGPdata *gpd);
 | 
			
		||||
void BKE_gpencil_free(struct bGPdata *gpd, bool free_all);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_batch_cache_dirty(struct bGPdata *gpd);
 | 
			
		||||
void BKE_gpencil_batch_cache_free(struct bGPdata *gpd);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_stroke_sync_selection(struct bGPDstroke *gps);
 | 
			
		||||
 | 
			
		||||
@@ -60,21 +80,36 @@ struct bGPdata   *BKE_gpencil_data_addnew(struct Main *bmain, const char name[])
 | 
			
		||||
 | 
			
		||||
struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src);
 | 
			
		||||
struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src);
 | 
			
		||||
void BKE_gpencil_frame_copy_strokes(struct bGPDframe *gpf_src, struct bGPDframe *gpf_dst);
 | 
			
		||||
struct bGPDstroke *BKE_gpencil_stroke_duplicate(struct bGPDstroke *gps_src);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_copy_data(struct Main *bmain, struct bGPdata *gpd_dst, const struct bGPdata *gpd_src, const int flag);
 | 
			
		||||
struct bGPdata   *BKE_gpencil_copy(struct Main *bmain, const struct bGPdata *gpd);
 | 
			
		||||
struct bGPdata   *BKE_gpencil_data_duplicate(struct Main *bmain, const struct bGPdata *gpd, bool internal_copy);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_make_local(struct Main *bmain, struct bGPdata *gpd, const bool lib_local);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf);
 | 
			
		||||
 | 
			
		||||
struct bGPDpalette *BKE_gpencil_palette_addnew(struct bGPdata *gpd, const char *name, bool setactive);
 | 
			
		||||
struct bGPDpalette *BKE_gpencil_palette_duplicate(const struct bGPDpalette *palette_src);
 | 
			
		||||
struct bGPDpalettecolor *BKE_gpencil_palettecolor_addnew(struct bGPDpalette *palette, const char *name, bool setactive);
 | 
			
		||||
/* materials */
 | 
			
		||||
void BKE_gpencil_material_index_remove(struct bGPdata *gpd, int index);
 | 
			
		||||
void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len);
 | 
			
		||||
 | 
			
		||||
struct bGPDbrush *BKE_gpencil_brush_addnew(struct ToolSettings *ts, const char *name, bool setactive);
 | 
			
		||||
struct bGPDbrush *BKE_gpencil_brush_duplicate(const struct bGPDbrush *brush_src);
 | 
			
		||||
void BKE_gpencil_brush_init_presets(struct ToolSettings *ts);
 | 
			
		||||
/* statistics functions */
 | 
			
		||||
void BKE_gpencil_stats_update(struct bGPdata *gpd);
 | 
			
		||||
 | 
			
		||||
/* Utilities for creating and populating GP strokes */
 | 
			
		||||
/* - Number of values defining each point in the built-in data
 | 
			
		||||
 *   buffers for primitives (e.g. 2D Monkey)
 | 
			
		||||
 */
 | 
			
		||||
#define GP_PRIM_DATABUF_SIZE  5
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_stroke_add_points(
 | 
			
		||||
        struct bGPDstroke *gps,
 | 
			
		||||
        const float *array, const int totpoints,
 | 
			
		||||
        const float mat[4][4]);
 | 
			
		||||
 | 
			
		||||
struct bGPDstroke *BKE_gpencil_add_stroke(struct bGPDframe *gpf, int mat_idx, int totpoints, short thickness);
 | 
			
		||||
 | 
			
		||||
/* Stroke and Fill - Alpha Visibility Threshold */
 | 
			
		||||
#define GPENCIL_ALPHA_OPACITY_THRESH 0.001f
 | 
			
		||||
@@ -103,20 +138,40 @@ struct bGPDlayer *BKE_gpencil_layer_getactive(struct bGPdata *gpd);
 | 
			
		||||
void BKE_gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active);
 | 
			
		||||
void BKE_gpencil_layer_delete(struct bGPdata *gpd, struct bGPDlayer *gpl);
 | 
			
		||||
 | 
			
		||||
struct bGPDbrush *BKE_gpencil_brush_getactive(struct ToolSettings *ts);
 | 
			
		||||
void BKE_gpencil_brush_setactive(struct ToolSettings *ts, struct bGPDbrush *active);
 | 
			
		||||
void BKE_gpencil_brush_delete(struct ToolSettings *ts, struct bGPDbrush *brush);
 | 
			
		||||
struct Material *BKE_gpencil_get_material_from_brush(struct Brush *brush);
 | 
			
		||||
struct Material *BKE_gpencil_material_ensure(struct Main *bmain, struct Object *ob);
 | 
			
		||||
 | 
			
		||||
struct bGPDpalette *BKE_gpencil_palette_getactive(struct bGPdata *gpd);
 | 
			
		||||
void BKE_gpencil_palette_setactive(struct bGPdata *gpd, struct bGPDpalette *active);
 | 
			
		||||
void BKE_gpencil_palette_delete(struct bGPdata *gpd, struct bGPDpalette *palette);
 | 
			
		||||
void BKE_gpencil_palette_change_strokes(struct bGPdata *gpd);
 | 
			
		||||
/* object boundbox */
 | 
			
		||||
bool BKE_gpencil_stroke_minmax(
 | 
			
		||||
        const struct bGPDstroke *gps, const bool use_select,
 | 
			
		||||
        float r_min[3], float r_max[3]);
 | 
			
		||||
 | 
			
		||||
struct bGPDpalettecolor *BKE_gpencil_palettecolor_getactive(struct bGPDpalette *palette);
 | 
			
		||||
void BKE_gpencil_palettecolor_setactive(struct bGPDpalette *palette, struct bGPDpalettecolor *active);
 | 
			
		||||
void BKE_gpencil_palettecolor_delete(struct bGPDpalette *palette, struct bGPDpalettecolor *palcolor);
 | 
			
		||||
struct bGPDpalettecolor *BKE_gpencil_palettecolor_getbyname(struct bGPDpalette *palette, char *name);
 | 
			
		||||
void BKE_gpencil_palettecolor_changename(struct bGPdata *gpd, char *oldname, const char *newname);
 | 
			
		||||
void BKE_gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name);
 | 
			
		||||
struct BoundBox *BKE_gpencil_boundbox_get(struct Object *ob);
 | 
			
		||||
void BKE_gpencil_centroid_3D(struct bGPdata *gpd, float r_centroid[3]);
 | 
			
		||||
 | 
			
		||||
/* vertex groups */
 | 
			
		||||
float BKE_gpencil_vgroup_use_index(struct MDeformVert *dvert, int index);
 | 
			
		||||
void BKE_gpencil_vgroup_remove(struct Object *ob, struct bDeformGroup *defgroup);
 | 
			
		||||
struct MDeformWeight *BKE_gpencil_vgroup_add_point_weight(struct MDeformVert *dvert, int index, float weight);
 | 
			
		||||
bool BKE_gpencil_vgroup_remove_point_weight(struct MDeformVert *dvert, int index);
 | 
			
		||||
void BKE_gpencil_stroke_weights_duplicate(struct bGPDstroke *gps_src, struct bGPDstroke *gps_dst);
 | 
			
		||||
 | 
			
		||||
/* GPencil geometry evaluation */
 | 
			
		||||
void BKE_gpencil_eval_geometry(struct Depsgraph *depsgraph, struct bGPdata *gpd);
 | 
			
		||||
 | 
			
		||||
/* stroke geometry utilities */
 | 
			
		||||
void BKE_gpencil_stroke_normal(const struct bGPDstroke *gps, float r_normal[3]);
 | 
			
		||||
void BKE_gpencil_simplify_stroke(struct bGPDstroke *gps, float factor);
 | 
			
		||||
void BKE_gpencil_simplify_fixed(struct bGPDstroke *gps);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_transform(struct bGPdata *gpd, float mat[4][4]);
 | 
			
		||||
 | 
			
		||||
bool BKE_gpencil_smooth_stroke(struct bGPDstroke *gps, int i, float inf);
 | 
			
		||||
bool BKE_gpencil_smooth_stroke_strength(struct bGPDstroke *gps, int point_index, float influence);
 | 
			
		||||
bool BKE_gpencil_smooth_stroke_thickness(struct bGPDstroke *gps, int point_index, float influence);
 | 
			
		||||
bool BKE_gpencil_smooth_stroke_uv(struct bGPDstroke *gps, int point_index, float influence);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_get_range_selected(struct bGPDlayer *gpl, int *r_initframe, int *r_endframe);
 | 
			
		||||
float BKE_gpencil_multiframe_falloff_calc(struct bGPDframe *gpf, int actnum, int f_init, int f_end, struct CurveMapping *cur_falloff);
 | 
			
		||||
 | 
			
		||||
#endif /*  __BKE_GPENCIL_H__ */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										256
									
								
								source/blender/blenkernel/BKE_gpencil_modifier.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,256 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2
 | 
			
		||||
 * of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * The Original Code is: all of this file.
 | 
			
		||||
 *
 | 
			
		||||
 * ***** END GPL LICENSE BLOCK *****
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __BKE_GPENCIL_MODIFIER_H__
 | 
			
		||||
#define __BKE_GPENCIL_MODIFIER_H__
 | 
			
		||||
 | 
			
		||||
/** \file BKE_greasepencil_modifier.h
 | 
			
		||||
 *  \ingroup bke
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "DNA_gpencil_modifier_types.h"     /* needed for all enum typdefs */
 | 
			
		||||
#include "BLI_compiler_attrs.h"
 | 
			
		||||
#include "BKE_customdata.h"
 | 
			
		||||
 | 
			
		||||
struct ID;
 | 
			
		||||
struct Depsgraph;
 | 
			
		||||
struct DerivedMesh;
 | 
			
		||||
struct bContext; /* NOTE: bakeModifier() - called from UI - needs to create new datablocks, hence the need for this */
 | 
			
		||||
struct Mesh;
 | 
			
		||||
struct Object;
 | 
			
		||||
struct Scene;
 | 
			
		||||
struct ViewLayer;
 | 
			
		||||
struct ListBase;
 | 
			
		||||
struct bArmature;
 | 
			
		||||
struct Main;
 | 
			
		||||
struct GpencilModifierData;
 | 
			
		||||
struct BMEditMesh;
 | 
			
		||||
struct DepsNodeHandle;
 | 
			
		||||
struct bGPDlayer;
 | 
			
		||||
struct bGPDframe;
 | 
			
		||||
struct bGPDstroke;
 | 
			
		||||
struct ModifierUpdateDepsgraphContext;
 | 
			
		||||
 | 
			
		||||
#define GPENCIL_MODIFIER_ACTIVE(_md, _is_render) (((_md->mode & eGpencilModifierMode_Realtime) && (_is_render == false)) || \
 | 
			
		||||
												  ((_md->mode & eGpencilModifierMode_Render) && (_is_render == true)))
 | 
			
		||||
#define GPENCIL_MODIFIER_EDIT(_md, _is_edit) (((_md->mode & eGpencilModifierMode_Editmode) == 0) && (_is_edit))
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	/* Should not be used, only for None modifier type */
 | 
			
		||||
	eGpencilModifierTypeType_None,
 | 
			
		||||
 | 
			
		||||
	/* grease pencil modifiers */
 | 
			
		||||
	eGpencilModifierTypeType_Gpencil,
 | 
			
		||||
}  GpencilModifierTypeType;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	eGpencilModifierTypeFlag_SupportsMapping = (1 << 0),
 | 
			
		||||
	eGpencilModifierTypeFlag_SupportsEditmode = (1 << 1),
 | 
			
		||||
 | 
			
		||||
	/* For modifiers that support editmode this determines if the
 | 
			
		||||
	* modifier should be enabled by default in editmode. This should
 | 
			
		||||
	* only be used by modifiers that are relatively speedy and
 | 
			
		||||
	* also generally used in editmode, otherwise let the user enable
 | 
			
		||||
	* it by hand.
 | 
			
		||||
	*/
 | 
			
		||||
	eGpencilModifierTypeFlag_EnableInEditmode = (1 << 2),
 | 
			
		||||
 | 
			
		||||
	/* For modifiers that require original data and so cannot
 | 
			
		||||
	* be placed after any non-deformative modifier.
 | 
			
		||||
	*/
 | 
			
		||||
	eGpencilModifierTypeFlag_RequiresOriginalData = (1 << 3),
 | 
			
		||||
 | 
			
		||||
	/* max one per type */
 | 
			
		||||
	eGpencilModifierTypeFlag_Single = (1 << 4),
 | 
			
		||||
 | 
			
		||||
	/* can't be added manually by user */
 | 
			
		||||
	eGpencilModifierTypeFlag_NoUserAdd = (1 << 5),
 | 
			
		||||
} GpencilModifierTypeFlag;
 | 
			
		||||
 | 
			
		||||
/* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */
 | 
			
		||||
typedef void(*GreasePencilObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cb_flag);
 | 
			
		||||
typedef void(*GreasePencilIDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag);
 | 
			
		||||
typedef void(*GreasePencilTexWalkFunc)(void *userData, struct Object *ob, struct GpencilModifierData *md, const char *propname);
 | 
			
		||||
 | 
			
		||||
typedef struct GpencilModifierTypeInfo {
 | 
			
		||||
	/* The user visible name for this modifier */
 | 
			
		||||
	char name[32];
 | 
			
		||||
 | 
			
		||||
	/* The DNA struct name for the modifier data type, used to
 | 
			
		||||
	 * write the DNA data out.
 | 
			
		||||
	 */
 | 
			
		||||
	char struct_name[32];
 | 
			
		||||
 | 
			
		||||
	/* The size of the modifier data type, used by allocation. */
 | 
			
		||||
	int struct_size;
 | 
			
		||||
 | 
			
		||||
	GpencilModifierType type;
 | 
			
		||||
	GpencilModifierTypeFlag flags;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/********************* Non-optional functions *********************/
 | 
			
		||||
 | 
			
		||||
	/* Copy instance data for this modifier type. Should copy all user
 | 
			
		||||
	 * level settings to the target modifier.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*copyData)(const struct GpencilModifierData *md, struct GpencilModifierData *target);
 | 
			
		||||
 | 
			
		||||
	/* Callback for GP "stroke" modifiers that operate on the
 | 
			
		||||
	 * shape and parameters of the provided strokes (e.g. Thickness, Noise, etc.)
 | 
			
		||||
	 *
 | 
			
		||||
	 * The gpl parameter contains the GP layer that the strokes come from.
 | 
			
		||||
	 * While access is provided to this data, you should not directly access
 | 
			
		||||
	 * the gpl->frames data from the modifier. Instead, use the gpf parameter
 | 
			
		||||
	 * instead.
 | 
			
		||||
	 *
 | 
			
		||||
	 * The gps parameter contains the GP stroke to operate on. This is usually a copy
 | 
			
		||||
	 * of the original (unmodified and saved to files) stroke data.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*deformStroke)(struct GpencilModifierData *md, struct Depsgraph *depsgraph,
 | 
			
		||||
	                     struct Object *ob, struct bGPDlayer *gpl, struct bGPDstroke *gps);
 | 
			
		||||
 | 
			
		||||
	/* Callback for GP "geometry" modifiers that create extra geometry
 | 
			
		||||
	 * in the frame (e.g. Array)
 | 
			
		||||
	 *
 | 
			
		||||
	 * The gpf parameter contains the GP frame/strokes to operate on. This is
 | 
			
		||||
	 * usually a copy of the original (unmodified and saved to files) stroke data.
 | 
			
		||||
	 * Modifiers should only add any generated strokes to this frame (and not one accessed
 | 
			
		||||
	 * via the gpl parameter).
 | 
			
		||||
	 *
 | 
			
		||||
	 * The modifier_index parameter indicates where the modifier is
 | 
			
		||||
	 * in the modifier stack in relation to other modifiers.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*generateStrokes)(struct GpencilModifierData *md, struct Depsgraph *depsgraph,
 | 
			
		||||
	                        struct Object *ob, struct bGPDlayer *gpl, struct bGPDframe *gpf);
 | 
			
		||||
 | 
			
		||||
	/* Bake-down GP modifier's effects into the GP datablock.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This gets called when the user clicks the "Apply" button in the UI.
 | 
			
		||||
	 * As such, this callback needs to go through all layers/frames in the
 | 
			
		||||
	 * datablock, mutating the geometry and/or creating new datablocks/objects
 | 
			
		||||
	 */
 | 
			
		||||
	void (*bakeModifier)(struct Main *bmain, struct Depsgraph *depsgraph,
 | 
			
		||||
                           struct GpencilModifierData *md, struct Object *ob);
 | 
			
		||||
 | 
			
		||||
	/********************* Optional functions *********************/
 | 
			
		||||
 | 
			
		||||
	/* Initialize new instance data for this modifier type, this function
 | 
			
		||||
	 * should set modifier variables to their default values.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*initData)(struct GpencilModifierData *md);
 | 
			
		||||
 | 
			
		||||
	/* Free internal modifier data variables, this function should
 | 
			
		||||
	 * not free the md variable itself.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*freeData)(struct GpencilModifierData *md);
 | 
			
		||||
 | 
			
		||||
	/* Return a boolean value indicating if this modifier is able to be
 | 
			
		||||
	 * calculated based on the modifier data. This is *not* regarding the
 | 
			
		||||
	 * md->flag, that is tested by the system, this is just if the data
 | 
			
		||||
	 * validates (for example, a lattice will return false if the lattice
 | 
			
		||||
	 * object is not defined).
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional (assumes never disabled if not present).
 | 
			
		||||
	 */
 | 
			
		||||
	bool (*isDisabled)(struct GpencilModifierData *md, int userRenderParams);
 | 
			
		||||
 | 
			
		||||
	/* Add the appropriate relations to the dependency graph.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*updateDepsgraph)(struct GpencilModifierData *md,
 | 
			
		||||
	                        const struct ModifierUpdateDepsgraphContext *ctx);
 | 
			
		||||
 | 
			
		||||
	/* Should return true if the modifier needs to be recalculated on time
 | 
			
		||||
	 * changes.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional (assumes false if not present).
 | 
			
		||||
	 */
 | 
			
		||||
	bool (*dependsOnTime)(struct GpencilModifierData *md);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* Should call the given walk function on with a pointer to each Object
 | 
			
		||||
	 * pointer that the modifier data stores. This is used for linking on file
 | 
			
		||||
	 * load and for unlinking objects or forwarding object references.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*foreachObjectLink)(struct GpencilModifierData *md, struct Object *ob,
 | 
			
		||||
	                          GreasePencilObjectWalkFunc walk, void *userData);
 | 
			
		||||
 | 
			
		||||
	/* Should call the given walk function with a pointer to each ID
 | 
			
		||||
	 * pointer (i.e. each datablock pointer) that the modifier data
 | 
			
		||||
	 * stores. This is used for linking on file load and for
 | 
			
		||||
	 * unlinking datablocks or forwarding datablock references.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional. If it is not present, foreachObjectLink
 | 
			
		||||
	 * will be used.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*foreachIDLink)(struct GpencilModifierData *md, struct Object *ob,
 | 
			
		||||
	                      GreasePencilIDWalkFunc walk, void *userData);
 | 
			
		||||
 | 
			
		||||
	/* Should call the given walk function for each texture that the
 | 
			
		||||
	 * modifier data stores. This is used for finding all textures in
 | 
			
		||||
	 * the context for the UI.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional. If it is not present, it will be
 | 
			
		||||
	 * assumed the modifier has no textures.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*foreachTexLink)(struct GpencilModifierData *md, struct Object *ob,
 | 
			
		||||
	                       GreasePencilTexWalkFunc walk, void *userData);
 | 
			
		||||
} GpencilModifierTypeInfo;
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_instance_modifier_instance_tfm(struct InstanceGpencilModifierData *mmd, const int elem_idx[3], float r_mat[4][4]);
 | 
			
		||||
 | 
			
		||||
/* Initialize modifier's global data (type info and some common global storages). */
 | 
			
		||||
void BKE_gpencil_modifier_init(void);
 | 
			
		||||
 | 
			
		||||
const GpencilModifierTypeInfo *BKE_gpencil_modifierType_getInfo(GpencilModifierType type);
 | 
			
		||||
struct GpencilModifierData  *BKE_gpencil_modifier_new(int type);
 | 
			
		||||
void BKE_gpencil_modifier_free_ex(struct GpencilModifierData *md, const int flag);
 | 
			
		||||
void BKE_gpencil_modifier_free(struct GpencilModifierData *md);
 | 
			
		||||
bool BKE_gpencil_modifier_unique_name(struct ListBase *modifiers, struct GpencilModifierData *gmd);
 | 
			
		||||
bool BKE_gpencil_modifier_dependsOnTime(struct GpencilModifierData *md);
 | 
			
		||||
struct GpencilModifierData *BKE_gpencil_modifiers_findByType(struct Object *ob, GpencilModifierType type);
 | 
			
		||||
struct GpencilModifierData *BKE_gpencil_modifiers_findByName(struct Object *ob, const char *name);
 | 
			
		||||
void BKE_gpencil_modifier_copyData_generic(const struct GpencilModifierData *md_src, struct GpencilModifierData *md_dst);
 | 
			
		||||
void BKE_gpencil_modifier_copyData(struct GpencilModifierData *md, struct GpencilModifierData *target);
 | 
			
		||||
void BKE_gpencil_modifier_copyData_ex(struct GpencilModifierData *md, struct GpencilModifierData *target, const int flag);
 | 
			
		||||
void BKE_gpencil_modifiers_foreachIDLink(struct Object *ob, GreasePencilIDWalkFunc walk, void *userData);
 | 
			
		||||
void BKE_gpencil_modifiers_foreachTexLink(struct Object *ob, GreasePencilTexWalkFunc walk, void *userData);
 | 
			
		||||
 | 
			
		||||
bool BKE_gpencil_has_geometry_modifiers(struct Object *ob);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_stroke_modifiers(
 | 
			
		||||
	struct Depsgraph *depsgraph, struct Object *ob,
 | 
			
		||||
	struct bGPDlayer *gpl, struct bGPDframe *gpf, struct bGPDstroke *gps, bool is_render);
 | 
			
		||||
void BKE_gpencil_geometry_modifiers(
 | 
			
		||||
	struct Depsgraph *depsgraph, struct Object *ob,
 | 
			
		||||
	struct bGPDlayer *gpl, struct bGPDframe *gpf, bool is_render);
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_lattice_init(struct Object *ob);
 | 
			
		||||
void BKE_gpencil_lattice_clear(struct Object *ob);
 | 
			
		||||
 | 
			
		||||
#endif /* __BKE_GPENCIL_MODIFIER_H__ */
 | 
			
		||||
@@ -43,7 +43,10 @@ enum {
 | 
			
		||||
	ICON_DATA_PREVIEW,
 | 
			
		||||
	/** 2D triangles: obj is #Icon_Geom */
 | 
			
		||||
	ICON_DATA_GEOM,
 | 
			
		||||
	/** Studiolight */
 | 
			
		||||
	ICON_DATA_STUDIOLIGHT,
 | 
			
		||||
	/** GPencil Layer color preview (annotations): obj is #bGPDlayer */
 | 
			
		||||
	ICON_DATA_GPLAYER,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Icon {
 | 
			
		||||
@@ -79,6 +82,7 @@ struct ImBuf;
 | 
			
		||||
struct PreviewImage;
 | 
			
		||||
struct ID;
 | 
			
		||||
struct StudioLight;
 | 
			
		||||
struct bGPDlayer;
 | 
			
		||||
 | 
			
		||||
enum eIconSizes;
 | 
			
		||||
 | 
			
		||||
@@ -87,6 +91,9 @@ void BKE_icons_init(int first_dyn_id);
 | 
			
		||||
/* return icon id for library object or create new icon if not found */
 | 
			
		||||
int BKE_icon_id_ensure(struct ID *id);
 | 
			
		||||
 | 
			
		||||
/* return icon id for Grease Pencil layer (color preview) or create new icon if not found */
 | 
			
		||||
int BKE_icon_gplayer_color_ensure(struct bGPDlayer *gpl);
 | 
			
		||||
 | 
			
		||||
int BKE_icon_preview_ensure(struct ID *id, struct PreviewImage *preview);
 | 
			
		||||
 | 
			
		||||
/* retrieve icon for id */
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,6 @@ void BKE_lattice_free(struct Lattice *lt);
 | 
			
		||||
void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool lib_local);
 | 
			
		||||
void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du);
 | 
			
		||||
 | 
			
		||||
struct LatticeDeformData;
 | 
			
		||||
struct LatticeDeformData *init_latt_deform(struct Object *oblatt, struct Object *ob) ATTR_WARN_UNUSED_RESULT;
 | 
			
		||||
void calc_latt_deform(struct LatticeDeformData *lattice_deform_data, float co[3], float weight);
 | 
			
		||||
void end_latt_deform(struct LatticeDeformData *lattice_deform_data);
 | 
			
		||||
 
 | 
			
		||||
@@ -54,11 +54,13 @@ void BKE_material_init(struct Material *ma);
 | 
			
		||||
void BKE_material_remap_object(struct Object *ob, const unsigned int *remap);
 | 
			
		||||
void BKE_material_remap_object_calc(struct  Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst);
 | 
			
		||||
struct Material *BKE_material_add(struct Main *bmain, const char *name);
 | 
			
		||||
struct Material *BKE_material_add_gpencil(struct Main *bmain, const char *name);
 | 
			
		||||
void BKE_material_copy_data(struct Main *bmain, struct Material *ma_dst, const struct Material *ma_src, const int flag);
 | 
			
		||||
struct Material *BKE_material_copy(struct Main *bmain, const struct Material *ma);
 | 
			
		||||
struct Material *BKE_material_localize(struct Material *ma);
 | 
			
		||||
struct Material *give_node_material(struct Material *ma); /* returns node material or self */
 | 
			
		||||
void BKE_material_make_local(struct Main *bmain, struct Material *ma, const bool lib_local);
 | 
			
		||||
void BKE_material_init_gpencil_settings(struct Material *ma);
 | 
			
		||||
 | 
			
		||||
/* UNUSED */
 | 
			
		||||
// void automatname(struct Material *);
 | 
			
		||||
@@ -87,6 +89,8 @@ short BKE_object_material_slot_find_index(struct Object *ob, struct Material *ma
 | 
			
		||||
bool  BKE_object_material_slot_add(struct Main *bmain, struct Object *ob);
 | 
			
		||||
bool  BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob);
 | 
			
		||||
 | 
			
		||||
struct MaterialGPencilStyle *BKE_material_gpencil_settings_get(struct Object *ob, short act);
 | 
			
		||||
 | 
			
		||||
void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma);
 | 
			
		||||
void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,8 +37,11 @@ extern "C" {
 | 
			
		||||
 | 
			
		||||
struct Base;
 | 
			
		||||
struct Depsgraph;
 | 
			
		||||
struct GpencilModifierData;
 | 
			
		||||
struct Scene;
 | 
			
		||||
struct ShaderFxData;
 | 
			
		||||
struct ViewLayer;
 | 
			
		||||
struct ID;
 | 
			
		||||
struct Object;
 | 
			
		||||
struct BoundBox;
 | 
			
		||||
struct View3D;
 | 
			
		||||
@@ -49,6 +52,7 @@ struct Mesh;
 | 
			
		||||
struct RigidBodyWorld;
 | 
			
		||||
struct HookModifierData;
 | 
			
		||||
struct ModifierData;
 | 
			
		||||
struct HookGpencilModifierData;
 | 
			
		||||
 | 
			
		||||
#include "DNA_object_enums.h"
 | 
			
		||||
 | 
			
		||||
@@ -69,11 +73,16 @@ void BKE_object_free_derived_mesh_caches(struct Object *ob);
 | 
			
		||||
void BKE_object_free_caches(struct Object *object);
 | 
			
		||||
 | 
			
		||||
void BKE_object_modifier_hook_reset(struct Object *ob, struct HookModifierData *hmd);
 | 
			
		||||
void BKE_object_modifier_gpencil_hook_reset(struct Object *ob, struct HookGpencilModifierData *hmd);
 | 
			
		||||
bool BKE_object_modifier_gpencil_use_time(struct Object *ob, struct GpencilModifierData *md);
 | 
			
		||||
 | 
			
		||||
bool BKE_object_shaderfx_use_time(struct Object *ob, struct ShaderFxData *md);
 | 
			
		||||
 | 
			
		||||
bool BKE_object_support_modifier_type_check(const struct Object *ob, int modifier_type);
 | 
			
		||||
 | 
			
		||||
void BKE_object_link_modifiers(struct Scene *scene, struct Object *ob_dst, const struct Object *ob_src);
 | 
			
		||||
void BKE_object_free_modifiers(struct Object *ob, const int flag);
 | 
			
		||||
void BKE_object_free_shaderfx(struct Object *ob, const int flag);
 | 
			
		||||
 | 
			
		||||
void BKE_object_make_proxy(struct Main *bmain, struct Object *ob, struct Object *target, struct Object *gob);
 | 
			
		||||
void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
 | 
			
		||||
@@ -108,6 +117,9 @@ struct Object *BKE_object_add_from(
 | 
			
		||||
        struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer,
 | 
			
		||||
        int type, const char *name, struct Object *ob_src)
 | 
			
		||||
        ATTR_NONNULL(1, 2, 3, 6) ATTR_RETURNS_NONNULL;
 | 
			
		||||
struct Object *BKE_object_add_for_data(
 | 
			
		||||
        struct Main *bmain, struct ViewLayer *view_layer,
 | 
			
		||||
        int type, const char *name, struct ID *data, bool do_id_user) ATTR_RETURNS_NONNULL;
 | 
			
		||||
void *BKE_object_obdata_add_from_type(
 | 
			
		||||
        struct Main *bmain,
 | 
			
		||||
        int type, const char *name)
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,8 @@ typedef enum ePaintMode {
 | 
			
		||||
	ePaintTextureProjective = 3,
 | 
			
		||||
	ePaintTexture2D = 4,
 | 
			
		||||
	ePaintSculptUV = 5,
 | 
			
		||||
	ePaintInvalid = 6
 | 
			
		||||
	ePaintInvalid = 6,
 | 
			
		||||
	ePaintGpencil = 7
 | 
			
		||||
} ePaintMode;
 | 
			
		||||
 | 
			
		||||
/* overlay invalidation */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										180
									
								
								source/blender/blenkernel/BKE_shader_fx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,180 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2
 | 
			
		||||
 * of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * The Original Code is: all of this file.
 | 
			
		||||
 *
 | 
			
		||||
 * ***** END GPL LICENSE BLOCK *****
 | 
			
		||||
 */
 | 
			
		||||
#ifndef __BKE_SHADER_FX_H__
 | 
			
		||||
#define __BKE_SHADER_FX_H__
 | 
			
		||||
 | 
			
		||||
/** \file BKE_shader_fx.h
 | 
			
		||||
 *  \ingroup bke
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "DNA_shader_fx_types.h"     /* needed for all enum typdefs */
 | 
			
		||||
#include "BLI_compiler_attrs.h"
 | 
			
		||||
#include "BKE_customdata.h"
 | 
			
		||||
 | 
			
		||||
struct ID;
 | 
			
		||||
struct Depsgraph;
 | 
			
		||||
struct DerivedMesh;
 | 
			
		||||
struct Mesh;
 | 
			
		||||
struct Object;
 | 
			
		||||
struct Scene;
 | 
			
		||||
struct ViewLayer;
 | 
			
		||||
struct ListBase;
 | 
			
		||||
struct bArmature;
 | 
			
		||||
struct Main;
 | 
			
		||||
struct ShaderFxData;
 | 
			
		||||
struct DepsNodeHandle;
 | 
			
		||||
struct bGPDlayer;
 | 
			
		||||
struct bGPDframe;
 | 
			
		||||
struct bGPDstroke;
 | 
			
		||||
struct ModifierUpdateDepsgraphContext;
 | 
			
		||||
 | 
			
		||||
#define SHADER_FX_ACTIVE(_fx, _is_render) (((_fx->mode & eShaderFxMode_Realtime) && (_is_render == false)) || \
 | 
			
		||||
												  ((_fx->mode & eShaderFxMode_Render) && (_is_render == true))) 
 | 
			
		||||
#define SHADER_FX_EDIT(_fx, _is_edit) (((_fx->mode & eShaderFxMode_Editmode) == 0) && (_is_edit))
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	/* Should not be used, only for None type */
 | 
			
		||||
	eShaderFxType_NoneType,
 | 
			
		||||
 | 
			
		||||
	/* grease pencil effects */
 | 
			
		||||
	eShaderFxType_GpencilType,
 | 
			
		||||
}  ShaderFxTypeType;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	eShaderFxTypeFlag_SupportsEditmode = (1 << 0),
 | 
			
		||||
 | 
			
		||||
	/* For effects that support editmode this determines if the
 | 
			
		||||
	* effect should be enabled by default in editmode. 
 | 
			
		||||
	*/
 | 
			
		||||
	eShaderFxTypeFlag_EnableInEditmode = (1 << 2),
 | 
			
		||||
 | 
			
		||||
	/* max one per type */
 | 
			
		||||
	eShaderFxTypeFlag_Single = (1 << 4),
 | 
			
		||||
 | 
			
		||||
	/* can't be added manually by user */
 | 
			
		||||
	eShaderFxTypeFlag_NoUserAdd = (1 << 5),
 | 
			
		||||
} ShaderFxTypeFlag;
 | 
			
		||||
 | 
			
		||||
/* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */
 | 
			
		||||
typedef void(*ShaderFxObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cb_flag);
 | 
			
		||||
typedef void(*ShaderFxIDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag);
 | 
			
		||||
typedef void(*ShaderFxTexWalkFunc)(void *userData, struct Object *ob, struct ShaderFxData *fx, const char *propname);
 | 
			
		||||
 | 
			
		||||
typedef struct ShaderFxTypeInfo {
 | 
			
		||||
	/* The user visible name for this effect */
 | 
			
		||||
	char name[32];
 | 
			
		||||
 | 
			
		||||
	/* The DNA struct name for the effect data type, used to
 | 
			
		||||
	 * write the DNA data out.
 | 
			
		||||
	 */
 | 
			
		||||
	char struct_name[32];
 | 
			
		||||
 | 
			
		||||
	/* The size of the effect data type, used by allocation. */
 | 
			
		||||
	int struct_size;
 | 
			
		||||
 | 
			
		||||
	ShaderFxTypeType type;
 | 
			
		||||
	ShaderFxTypeFlag flags;
 | 
			
		||||
 | 
			
		||||
	/* Copy instance data for this effect type. Should copy all user
 | 
			
		||||
	* level settings to the target effect.
 | 
			
		||||
	*/
 | 
			
		||||
	void(*copyData)(const struct ShaderFxData *fx, struct ShaderFxData *target);
 | 
			
		||||
 | 
			
		||||
	/* Initialize new instance data for this effect type, this function
 | 
			
		||||
	 * should set effect variables to their default values.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * This function is optional.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*initData)(struct ShaderFxData *fx);
 | 
			
		||||
 | 
			
		||||
	/* Free internal effect data variables, this function should
 | 
			
		||||
	 * not free the fx variable itself.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*freeData)(struct ShaderFxData *fx);
 | 
			
		||||
 | 
			
		||||
	/* Return a boolean value indicating if this effect is able to be
 | 
			
		||||
	 * calculated based on the effect data. This is *not* regarding the
 | 
			
		||||
	 * fx->flag, that is tested by the system, this is just if the data
 | 
			
		||||
	 * validates (for example, a lattice will return false if the lattice
 | 
			
		||||
	 * object is not defined).
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional (assumes never disabled if not present).
 | 
			
		||||
	 */
 | 
			
		||||
	bool (*isDisabled)(struct ShaderFxData *fx, int userRenderParams);
 | 
			
		||||
 | 
			
		||||
	/* Add the appropriate relations to the dependency graph.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*updateDepsgraph)(struct ShaderFxData *fx,
 | 
			
		||||
	                        const struct ModifierUpdateDepsgraphContext *ctx);
 | 
			
		||||
 
 | 
			
		||||
	/* Should return true if the effect needs to be recalculated on time
 | 
			
		||||
	 * changes.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional (assumes false if not present).
 | 
			
		||||
	 */
 | 
			
		||||
	bool (*dependsOnTime)(struct ShaderFxData *fx);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* Should call the given walk function on with a pointer to each Object
 | 
			
		||||
	 * pointer that the effect data stores. This is used for linking on file
 | 
			
		||||
	 * load and for unlinking objects or forwarding object references.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*foreachObjectLink)(struct ShaderFxData *fx, struct Object *ob,
 | 
			
		||||
	                          ShaderFxObjectWalkFunc walk, void *userData);
 | 
			
		||||
 | 
			
		||||
	/* Should call the given walk function with a pointer to each ID
 | 
			
		||||
	 * pointer (i.e. each datablock pointer) that the effect data
 | 
			
		||||
	 * stores. This is used for linking on file load and for
 | 
			
		||||
	 * unlinking datablocks or forwarding datablock references.
 | 
			
		||||
	 *
 | 
			
		||||
	 * This function is optional. If it is not present, foreachObjectLink
 | 
			
		||||
	 * will be used.
 | 
			
		||||
	 */
 | 
			
		||||
	void (*foreachIDLink)(struct ShaderFxData *fx, struct Object *ob,
 | 
			
		||||
	                      ShaderFxIDWalkFunc walk, void *userData);
 | 
			
		||||
} ShaderFxTypeInfo;
 | 
			
		||||
 | 
			
		||||
/* Initialize  global data (type info and some common global storages). */
 | 
			
		||||
void BKE_shaderfx_init(void);
 | 
			
		||||
 | 
			
		||||
const ShaderFxTypeInfo *BKE_shaderfxType_getInfo(ShaderFxType type);
 | 
			
		||||
struct ShaderFxData  *BKE_shaderfx_new(int type);
 | 
			
		||||
void BKE_shaderfx_free_ex(struct ShaderFxData *fx, const int flag);
 | 
			
		||||
void BKE_shaderfx_free(struct ShaderFxData *fx);
 | 
			
		||||
bool BKE_shaderfx_unique_name(struct ListBase *shaderfx, struct ShaderFxData *fx);
 | 
			
		||||
bool BKE_shaderfx_dependsOnTime(struct ShaderFxData *fx);
 | 
			
		||||
struct ShaderFxData *BKE_shaderfx_findByType(struct Object *ob, ShaderFxType type);
 | 
			
		||||
struct ShaderFxData *BKE_shaderfx_findByName(struct Object *ob, const char *name);
 | 
			
		||||
void BKE_shaderfx_copyData_generic(const struct ShaderFxData *fx_src, struct ShaderFxData *fx_dst);
 | 
			
		||||
void BKE_shaderfx_copyData(struct ShaderFxData *fx, struct ShaderFxData *target);
 | 
			
		||||
void BKE_shaderfx_copyData_ex(struct ShaderFxData *fx, struct ShaderFxData *target, const int flag);
 | 
			
		||||
void BKE_shaderfx_foreachIDLink(struct Object *ob, ShaderFxIDWalkFunc walk, void *userData);
 | 
			
		||||
 | 
			
		||||
bool BKE_shaderfx_has_gpencil(struct Object *ob);
 | 
			
		||||
 | 
			
		||||
#endif /* __BKE_SHADER_FX_H__ */
 | 
			
		||||
@@ -38,6 +38,8 @@ set(INC
 | 
			
		||||
	../makesrna
 | 
			
		||||
	../bmesh
 | 
			
		||||
	../modifiers
 | 
			
		||||
	../gpencil_modifiers
 | 
			
		||||
	../shader_fx
 | 
			
		||||
	../nodes
 | 
			
		||||
	../physics
 | 
			
		||||
	../render/extern/include
 | 
			
		||||
@@ -115,6 +117,7 @@ set(SRC
 | 
			
		||||
	intern/font.c
 | 
			
		||||
	intern/freestyle.c
 | 
			
		||||
	intern/gpencil.c
 | 
			
		||||
	intern/gpencil_modifier.c
 | 
			
		||||
	intern/icons.c
 | 
			
		||||
	intern/icons_rasterize.c
 | 
			
		||||
	intern/idcode.c
 | 
			
		||||
@@ -180,6 +183,7 @@ set(SRC
 | 
			
		||||
	intern/seqeffects.c
 | 
			
		||||
	intern/seqmodifier.c
 | 
			
		||||
	intern/sequencer.c
 | 
			
		||||
	intern/shader_fx.c
 | 
			
		||||
	intern/shrinkwrap.c
 | 
			
		||||
	intern/smoke.c
 | 
			
		||||
	intern/softbody.c
 | 
			
		||||
@@ -259,6 +263,7 @@ set(SRC
 | 
			
		||||
	BKE_freestyle.h
 | 
			
		||||
	BKE_global.h
 | 
			
		||||
	BKE_gpencil.h
 | 
			
		||||
	BKE_gpencil_modifier.h
 | 
			
		||||
	BKE_icons.h
 | 
			
		||||
	BKE_idcode.h
 | 
			
		||||
	BKE_idprop.h
 | 
			
		||||
@@ -306,6 +311,7 @@ set(SRC
 | 
			
		||||
	BKE_scene.h
 | 
			
		||||
	BKE_screen.h
 | 
			
		||||
	BKE_sequencer.h
 | 
			
		||||
	BKE_shader_fx.h
 | 
			
		||||
	BKE_shrinkwrap.h
 | 
			
		||||
	BKE_smoke.h
 | 
			
		||||
	BKE_softbody.h
 | 
			
		||||
 
 | 
			
		||||
@@ -104,6 +104,7 @@ bool id_type_can_have_animdata(const short id_type)
 | 
			
		||||
		case ID_MSK:
 | 
			
		||||
		case ID_GD:
 | 
			
		||||
		case ID_CF:
 | 
			
		||||
		case ID_PAL:
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		/* no AnimData */
 | 
			
		||||
@@ -1150,6 +1151,9 @@ void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *use
 | 
			
		||||
	/* grease pencil */
 | 
			
		||||
	ANIMDATA_IDS_CB(bmain->gpencil.first);
 | 
			
		||||
 | 
			
		||||
	/* palettes */
 | 
			
		||||
	ANIMDATA_IDS_CB(bmain->palettes.first);
 | 
			
		||||
 | 
			
		||||
	/* cache files */
 | 
			
		||||
	ANIMDATA_IDS_CB(bmain->cachefiles.first);
 | 
			
		||||
}
 | 
			
		||||
@@ -2925,6 +2929,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, Scene
 | 
			
		||||
	/* grease pencil */
 | 
			
		||||
	EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM);
 | 
			
		||||
 | 
			
		||||
	/* palettes */
 | 
			
		||||
	EVAL_ANIM_IDS(main->palettes.first, ADT_RECALC_ANIM);
 | 
			
		||||
 | 
			
		||||
	/* cache files */
 | 
			
		||||
	EVAL_ANIM_IDS(main->cachefiles.first, ADT_RECALC_ANIM);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
#include "DNA_brush_types.h"
 | 
			
		||||
#include "DNA_scene_types.h"
 | 
			
		||||
#include "DNA_object_types.h"
 | 
			
		||||
#include "DNA_gpencil_types.h"
 | 
			
		||||
 | 
			
		||||
#include "BLI_math.h"
 | 
			
		||||
#include "BLI_blenlib.h"
 | 
			
		||||
@@ -36,6 +37,7 @@
 | 
			
		||||
 | 
			
		||||
#include "BKE_brush.h"
 | 
			
		||||
#include "BKE_colortools.h"
 | 
			
		||||
#include "BKE_context.h"
 | 
			
		||||
#include "BKE_global.h"
 | 
			
		||||
#include "BKE_library.h"
 | 
			
		||||
#include "BKE_library_query.h"
 | 
			
		||||
@@ -129,6 +131,7 @@ static void brush_defaults(Brush *brush)
 | 
			
		||||
 | 
			
		||||
	brush->stencil_dimension[0] = 256;
 | 
			
		||||
	brush->stencil_dimension[1] = 256;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Datablock add/copy/free/make_local */
 | 
			
		||||
@@ -164,6 +167,368 @@ Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode)
 | 
			
		||||
	return brush;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* add a new gp-brush */
 | 
			
		||||
Brush *BKE_brush_add_gpencil(Main *bmain, ToolSettings *ts, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	Brush *brush;
 | 
			
		||||
	Paint *paint = BKE_brush_get_gpencil_paint(ts);
 | 
			
		||||
	brush = BKE_brush_add(bmain, name, OB_MODE_GPENCIL_PAINT);
 | 
			
		||||
 | 
			
		||||
	BKE_paint_brush_set(paint, brush);
 | 
			
		||||
	id_us_min(&brush->id);
 | 
			
		||||
 | 
			
		||||
	/* grease pencil basic settings */
 | 
			
		||||
	brush->size = 3;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings = MEM_callocN(sizeof(BrushGpencilSettings), "BrushGpencilSettings");
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_smoothlvl = 1;
 | 
			
		||||
	brush->gpencil_settings->flag = 0;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
 | 
			
		||||
	brush->gpencil_settings->draw_sensitivity = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_strength = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_jitter = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN;
 | 
			
		||||
 | 
			
		||||
	/* curves */
 | 
			
		||||
	brush->gpencil_settings->curve_sensitivity = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
 | 
			
		||||
	brush->gpencil_settings->curve_strength = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
 | 
			
		||||
	brush->gpencil_settings->curve_jitter = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
 | 
			
		||||
 | 
			
		||||
	/* return brush */
 | 
			
		||||
	return brush;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Paint *BKE_brush_get_gpencil_paint(ToolSettings *ts)
 | 
			
		||||
{
 | 
			
		||||
	/* alloc paint session */
 | 
			
		||||
	if (ts->gp_paint == NULL) {
 | 
			
		||||
		ts->gp_paint = MEM_callocN(sizeof(GpPaint), "GpPaint");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &ts->gp_paint->paint;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* grease pencil cumapping->preset */
 | 
			
		||||
typedef enum eGPCurveMappingPreset {
 | 
			
		||||
	GPCURVE_PRESET_PENCIL = 0,
 | 
			
		||||
	GPCURVE_PRESET_INK = 1,
 | 
			
		||||
	GPCURVE_PRESET_INKNOISE = 2,
 | 
			
		||||
} eGPCurveMappingPreset;
 | 
			
		||||
 | 
			
		||||
static void brush_gpencil_curvemap_reset(CurveMap *cuma, int preset)
 | 
			
		||||
{
 | 
			
		||||
	if (cuma->curve)
 | 
			
		||||
		MEM_freeN(cuma->curve);
 | 
			
		||||
 | 
			
		||||
	cuma->totpoint = 3;
 | 
			
		||||
	cuma->curve = MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), __func__);
 | 
			
		||||
 | 
			
		||||
	switch (preset) {
 | 
			
		||||
		case GPCURVE_PRESET_PENCIL:
 | 
			
		||||
			cuma->curve[0].x = 0.0f;
 | 
			
		||||
			cuma->curve[0].y = 0.0f;
 | 
			
		||||
			cuma->curve[1].x = 0.75115f;
 | 
			
		||||
			cuma->curve[1].y = 0.25f;
 | 
			
		||||
			cuma->curve[2].x = 1.0f;
 | 
			
		||||
			cuma->curve[2].y = 1.0f;
 | 
			
		||||
			break;
 | 
			
		||||
		case GPCURVE_PRESET_INK:
 | 
			
		||||
			cuma->curve[0].x = 0.0f;
 | 
			
		||||
			cuma->curve[0].y = 0.0f;
 | 
			
		||||
			cuma->curve[1].x = 0.63448f;
 | 
			
		||||
			cuma->curve[1].y = 0.375f;
 | 
			
		||||
			cuma->curve[2].x = 1.0f;
 | 
			
		||||
			cuma->curve[2].y = 1.0f;
 | 
			
		||||
			break;
 | 
			
		||||
		case GPCURVE_PRESET_INKNOISE:
 | 
			
		||||
			cuma->curve[0].x = 0.0f;
 | 
			
		||||
			cuma->curve[0].y = 0.0f;
 | 
			
		||||
			cuma->curve[1].x = 0.63134f;
 | 
			
		||||
			cuma->curve[1].y = 0.3625f;
 | 
			
		||||
			cuma->curve[2].x = 1.0f;
 | 
			
		||||
			cuma->curve[2].y = 1.0f;
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cuma->table) {
 | 
			
		||||
		MEM_freeN(cuma->table);
 | 
			
		||||
		cuma->table = NULL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* create a set of grease pencil presets */
 | 
			
		||||
void BKE_brush_gpencil_presets(bContext *C)
 | 
			
		||||
{
 | 
			
		||||
#define SMOOTH_STROKE_RADIUS 40
 | 
			
		||||
#define SMOOTH_STROKE_FACTOR 0.9f
 | 
			
		||||
 | 
			
		||||
	ToolSettings *ts = CTX_data_tool_settings(C);
 | 
			
		||||
	Paint *paint = BKE_brush_get_gpencil_paint(ts);
 | 
			
		||||
	Main *bmain = CTX_data_main(C);
 | 
			
		||||
 | 
			
		||||
	Brush *brush, *deft;
 | 
			
		||||
	CurveMapping *custom_curve;
 | 
			
		||||
 | 
			
		||||
	/* Pencil brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Draw Pencil");
 | 
			
		||||
	brush->size = 25.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
 | 
			
		||||
	brush->gpencil_settings->draw_sensitivity = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_strength = 0.6f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_random_press = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_jitter = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_angle = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_angle_factor = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothfac = 0.5f;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothlvl = 1;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothfac = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothlvl = 3;
 | 
			
		||||
	brush->gpencil_settings->draw_subdivide = 1;
 | 
			
		||||
	brush->gpencil_settings->draw_random_sub = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PENCIL;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
 | 
			
		||||
 | 
			
		||||
	brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
 | 
			
		||||
	brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
 | 
			
		||||
 | 
			
		||||
	/* Pen brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Draw Pen");
 | 
			
		||||
	deft = brush; /* save default brush */
 | 
			
		||||
	brush->size = 30.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
 | 
			
		||||
	brush->gpencil_settings->draw_sensitivity = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_strength = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_random_press = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_random_strength = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_jitter = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_angle = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_angle_factor = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothfac = 0.5f;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothlvl = 1;
 | 
			
		||||
	brush->gpencil_settings->draw_subdivide = 1;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothfac = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothlvl = 3;
 | 
			
		||||
	brush->gpencil_settings->draw_random_sub = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_PEN;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
 | 
			
		||||
 | 
			
		||||
	brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
 | 
			
		||||
	brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
 | 
			
		||||
 | 
			
		||||
	/* Ink brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Draw Ink");
 | 
			
		||||
	brush->size = 60.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
 | 
			
		||||
	brush->gpencil_settings->draw_sensitivity = 1.6f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_strength = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_random_press = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_jitter = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_angle = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_angle_factor = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothfac = 0.5f;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothlvl = 1;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothfac = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothlvl = 3;
 | 
			
		||||
	brush->gpencil_settings->draw_subdivide = 1;
 | 
			
		||||
	brush->gpencil_settings->draw_random_sub = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INK;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
 | 
			
		||||
 | 
			
		||||
	brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
 | 
			
		||||
	brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
 | 
			
		||||
 | 
			
		||||
	/* Curve */
 | 
			
		||||
	custom_curve = brush->gpencil_settings->curve_sensitivity;
 | 
			
		||||
	curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
 | 
			
		||||
	curvemapping_initialize(custom_curve);
 | 
			
		||||
	brush_gpencil_curvemap_reset(custom_curve->cm, GPCURVE_PRESET_INK);
 | 
			
		||||
 | 
			
		||||
	/* Ink Noise brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Draw Noise");
 | 
			
		||||
	brush->size = 60.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
 | 
			
		||||
	brush->gpencil_settings->draw_sensitivity = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_strength = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_GROUP_RANDOM;
 | 
			
		||||
	brush->gpencil_settings->draw_random_press = 0.7f;
 | 
			
		||||
	brush->gpencil_settings->draw_random_strength = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_jitter = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_angle = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_angle_factor = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothfac = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothlvl = 2;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothfac = 0.5f;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothlvl = 2;
 | 
			
		||||
	brush->gpencil_settings->draw_subdivide = 1;
 | 
			
		||||
	brush->gpencil_settings->draw_random_sub = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INKNOISE;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
 | 
			
		||||
 | 
			
		||||
	brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
 | 
			
		||||
	brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
 | 
			
		||||
 | 
			
		||||
	/* Curve */
 | 
			
		||||
	custom_curve = brush->gpencil_settings->curve_sensitivity;
 | 
			
		||||
	curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
 | 
			
		||||
	curvemapping_initialize(custom_curve);
 | 
			
		||||
	brush_gpencil_curvemap_reset(custom_curve->cm, GPCURVE_PRESET_INKNOISE);
 | 
			
		||||
 | 
			
		||||
	/* Block Basic brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Draw Block");
 | 
			
		||||
	brush->size = 150.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
 | 
			
		||||
	brush->gpencil_settings->draw_sensitivity = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_strength = 0.7f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_STENGTH_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_random_press = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_jitter = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_angle = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_angle_factor = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothfac = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothlvl = 1;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothfac = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothlvl = 3;
 | 
			
		||||
	brush->gpencil_settings->draw_subdivide = 0;
 | 
			
		||||
	brush->gpencil_settings->draw_random_sub = 0;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_BLOCK;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
 | 
			
		||||
 | 
			
		||||
	brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
 | 
			
		||||
	brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
 | 
			
		||||
 | 
			
		||||
	/* Marker brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Draw Marker");
 | 
			
		||||
	brush->size = 80.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= (GP_BRUSH_USE_PRESSURE | GP_BRUSH_ENABLE_CURSOR);
 | 
			
		||||
	brush->gpencil_settings->draw_sensitivity = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_strength = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_GROUP_RANDOM;
 | 
			
		||||
	brush->gpencil_settings->draw_random_press = 0.374f;
 | 
			
		||||
	brush->gpencil_settings->draw_random_strength = 0.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_jitter = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_angle = M_PI_4; /* 45 degrees */
 | 
			
		||||
	brush->gpencil_settings->draw_angle_factor = 1.0f;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothfac = 0.5f;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothlvl = 1;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothfac = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothlvl = 3;
 | 
			
		||||
	brush->gpencil_settings->draw_subdivide = 1;
 | 
			
		||||
	brush->gpencil_settings->draw_random_sub = 0.0f;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_MARKER;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_DRAW;
 | 
			
		||||
 | 
			
		||||
	brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
 | 
			
		||||
	brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
 | 
			
		||||
 | 
			
		||||
	/* Fill brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Fill Area");
 | 
			
		||||
	brush->size = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR;
 | 
			
		||||
	brush->gpencil_settings->draw_sensitivity = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->fill_leak = 3;
 | 
			
		||||
	brush->gpencil_settings->fill_threshold = 0.1f;
 | 
			
		||||
	brush->gpencil_settings->fill_simplylvl = 1;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_FILL;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_FILL;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_smoothfac = 0.5f;
 | 
			
		||||
	brush->gpencil_settings->draw_smoothlvl = 1;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothfac = 1.0f;
 | 
			
		||||
	brush->gpencil_settings->thick_smoothlvl = 3;
 | 
			
		||||
	brush->gpencil_settings->draw_subdivide = 1;
 | 
			
		||||
 | 
			
		||||
	brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
 | 
			
		||||
	brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
 | 
			
		||||
 | 
			
		||||
	brush->gpencil_settings->draw_strength = 1.0f;
 | 
			
		||||
 | 
			
		||||
	/* Soft Eraser brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Soft");
 | 
			
		||||
	brush->size = 30.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= (GP_BRUSH_ENABLE_CURSOR | GP_BRUSH_DEFAULT_ERASER);
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_SOFT;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE;
 | 
			
		||||
	brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_SOFT;
 | 
			
		||||
 | 
			
		||||
	/* Hard Eraser brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Hard");
 | 
			
		||||
	brush->size = 30.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_HARD;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE;
 | 
			
		||||
	brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_HARD;
 | 
			
		||||
 | 
			
		||||
	/* Stroke Eraser brush */
 | 
			
		||||
	brush = BKE_brush_add_gpencil(bmain, ts, "Eraser Stroke");
 | 
			
		||||
	brush->size = 30.0f;
 | 
			
		||||
	brush->gpencil_settings->flag |= GP_BRUSH_ENABLE_CURSOR;
 | 
			
		||||
	brush->gpencil_settings->icon_id = GP_BRUSH_ICON_ERASE_STROKE;
 | 
			
		||||
	brush->gpencil_settings->brush_type = GP_BRUSH_TYPE_ERASE;
 | 
			
		||||
	brush->gpencil_settings->eraser_mode = GP_BRUSH_ERASER_STROKE;
 | 
			
		||||
 | 
			
		||||
	/* set defaut brush */
 | 
			
		||||
	BKE_paint_brush_set(paint, deft);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* get the active gp-brush for editing */
 | 
			
		||||
Brush *BKE_brush_getactive_gpencil(ToolSettings *ts)
 | 
			
		||||
{
 | 
			
		||||
	/* error checking */
 | 
			
		||||
	if (ELEM(NULL, ts, ts->gp_paint)) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	Paint *paint = &ts->gp_paint->paint;
 | 
			
		||||
 | 
			
		||||
	return paint->brush;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode)
 | 
			
		||||
{
 | 
			
		||||
	Brush *brush;
 | 
			
		||||
@@ -197,6 +562,12 @@ void BKE_brush_copy_data(Main *UNUSED(bmain), Brush *brush_dst, const Brush *bru
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	brush_dst->curve = curvemapping_copy(brush_src->curve);
 | 
			
		||||
	if (brush_src->gpencil_settings != NULL) {
 | 
			
		||||
		brush_dst->gpencil_settings = MEM_dupallocN(brush_src->gpencil_settings);
 | 
			
		||||
		brush_dst->gpencil_settings->curve_sensitivity = curvemapping_copy(brush_src->gpencil_settings->curve_sensitivity);
 | 
			
		||||
		brush_dst->gpencil_settings->curve_strength = curvemapping_copy(brush_src->gpencil_settings->curve_strength);
 | 
			
		||||
		brush_dst->gpencil_settings->curve_jitter = curvemapping_copy(brush_src->gpencil_settings->curve_jitter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* enable fake user by default */
 | 
			
		||||
	id_fake_user_set(&brush_dst->id);
 | 
			
		||||
@@ -215,11 +586,18 @@ void BKE_brush_free(Brush *brush)
 | 
			
		||||
	if (brush->icon_imbuf) {
 | 
			
		||||
		IMB_freeImBuf(brush->icon_imbuf);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	curvemapping_free(brush->curve);
 | 
			
		||||
 | 
			
		||||
	if (brush->gpencil_settings != NULL) {
 | 
			
		||||
		curvemapping_free(brush->gpencil_settings->curve_sensitivity);
 | 
			
		||||
		curvemapping_free(brush->gpencil_settings->curve_strength);
 | 
			
		||||
		curvemapping_free(brush->gpencil_settings->curve_jitter);
 | 
			
		||||
		MEM_SAFE_FREE(brush->gpencil_settings);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	MEM_SAFE_FREE(brush->gradient);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	BKE_previewimg_free(&(brush->preview));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -282,6 +282,7 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
 | 
			
		||||
		case CURVE_PRESET_MID9: cuma->totpoint = 9; break;
 | 
			
		||||
		case CURVE_PRESET_ROUND: cuma->totpoint = 4; break;
 | 
			
		||||
		case CURVE_PRESET_ROOT: cuma->totpoint = 4; break;
 | 
			
		||||
		case CURVE_PRESET_GAUSS: cuma->totpoint = 7; break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cuma->curve = MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), "curve points");
 | 
			
		||||
@@ -352,6 +353,24 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
 | 
			
		||||
			cuma->curve[3].x = 1;
 | 
			
		||||
			cuma->curve[3].y = 0;
 | 
			
		||||
			break;
 | 
			
		||||
		case CURVE_PRESET_GAUSS:
 | 
			
		||||
			cuma->curve[0].x = 0;
 | 
			
		||||
			cuma->curve[0].y = 0.025f;
 | 
			
		||||
			cuma->curve[1].x = 0.16f;
 | 
			
		||||
			cuma->curve[1].y = 0.135f;
 | 
			
		||||
			cuma->curve[2].x = 0.298f;
 | 
			
		||||
			cuma->curve[2].y = 0.36f;
 | 
			
		||||
 | 
			
		||||
			cuma->curve[3].x = 0.50f;
 | 
			
		||||
			cuma->curve[3].y = 1.0f;
 | 
			
		||||
 | 
			
		||||
			cuma->curve[4].x = 0.70f;
 | 
			
		||||
			cuma->curve[4].y = 0.36f;
 | 
			
		||||
			cuma->curve[5].x = 0.84f;
 | 
			
		||||
			cuma->curve[5].y = 0.135f;
 | 
			
		||||
			cuma->curve[6].x = 1.0f;
 | 
			
		||||
			cuma->curve[6].y = 0.025f;
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* mirror curve in x direction to have positive slope
 | 
			
		||||
 
 | 
			
		||||
@@ -1014,6 +1014,10 @@ int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, const eObjectM
 | 
			
		||||
			else if (object_mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
 | 
			
		||||
			else if (object_mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
 | 
			
		||||
			else if (object_mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
 | 
			
		||||
			else if (object_mode & OB_MODE_GPENCIL_PAINT) return CTX_MODE_GPENCIL_PAINT;
 | 
			
		||||
			else if (object_mode & OB_MODE_GPENCIL_EDIT) return CTX_MODE_GPENCIL_EDIT;
 | 
			
		||||
			else if (object_mode & OB_MODE_GPENCIL_SCULPT) return CTX_MODE_GPENCIL_SCULPT;
 | 
			
		||||
			else if (object_mode & OB_MODE_GPENCIL_WEIGHT) return CTX_MODE_GPENCIL_WEIGHT;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1044,6 +1048,10 @@ static const char *data_mode_strings[] = {
 | 
			
		||||
	"imagepaint",
 | 
			
		||||
	"particlemode",
 | 
			
		||||
	"objectmode",
 | 
			
		||||
	"greasepencil_paint",
 | 
			
		||||
	"greasepencil_edit",
 | 
			
		||||
	"greasepencil_sculpt",
 | 
			
		||||
	"greasepencil_weight",
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
BLI_STATIC_ASSERT(ARRAY_SIZE(data_mode_strings) == CTX_MODE_NUM + 1, "Must have a string for each context mode")
 | 
			
		||||
@@ -1212,17 +1220,7 @@ bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C)
 | 
			
		||||
	return ctx_data_pointer_get(C, "active_gpencil_layer");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bGPDpalette *CTX_data_active_gpencil_palette(const bContext *C)
 | 
			
		||||
{
 | 
			
		||||
	return ctx_data_pointer_get(C, "active_gpencil_palette");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bGPDpalettecolor *CTX_data_active_gpencil_palettecolor(const bContext *C)
 | 
			
		||||
{
 | 
			
		||||
	return ctx_data_pointer_get(C, "active_gpencil_palettecolor");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bGPDbrush *CTX_data_active_gpencil_brush(const bContext *C)
 | 
			
		||||
Brush *CTX_data_active_gpencil_brush(const bContext *C)
 | 
			
		||||
{
 | 
			
		||||
	return ctx_data_pointer_get(C, "active_gpencil_brush");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,9 @@ bDeformGroup *BKE_defgroup_new(Object *ob, const char *name)
 | 
			
		||||
	BLI_addtail(&ob->defbase, defgroup);
 | 
			
		||||
	defgroup_unique_name(defgroup, ob);
 | 
			
		||||
 | 
			
		||||
	BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
 | 
			
		||||
	if (ob->type != OB_GPENCIL) {
 | 
			
		||||
		BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return defgroup;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										679
									
								
								source/blender/blenkernel/intern/gpencil_modifier.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,679 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License
 | 
			
		||||
 * as published by the Free Software Foundation; either version 2
 | 
			
		||||
 * of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * The Original Code is Copyright (C) 2017, Blender Foundation
 | 
			
		||||
 * This is a new part of Blender
 | 
			
		||||
 *
 | 
			
		||||
 * Contributor(s): Antonio Vazquez
 | 
			
		||||
 *
 | 
			
		||||
 * ***** END GPL LICENSE BLOCK *****
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \file blender/blenkernel/intern/gpencil_modifier.c
 | 
			
		||||
 *  \ingroup bke
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "MEM_guardedalloc.h"
 | 
			
		||||
 | 
			
		||||
#include "BLI_blenlib.h"
 | 
			
		||||
#include "BLI_utildefines.h"
 | 
			
		||||
#include "BLI_math_vector.h"
 | 
			
		||||
#include "BLI_string_utils.h"
 | 
			
		||||
 | 
			
		||||
#include "BLT_translation.h"
 | 
			
		||||
 | 
			
		||||
#include "DNA_meshdata_types.h"
 | 
			
		||||
#include "DNA_scene_types.h"
 | 
			
		||||
#include "DNA_object_types.h"
 | 
			
		||||
#include "DNA_gpencil_types.h"
 | 
			
		||||
#include "DNA_gpencil_modifier_types.h"
 | 
			
		||||
 | 
			
		||||
#include "BKE_global.h"
 | 
			
		||||
#include "BKE_library.h"
 | 
			
		||||
#include "BKE_library_query.h"
 | 
			
		||||
#include "BKE_gpencil.h"
 | 
			
		||||
#include "BKE_lattice.h"
 | 
			
		||||
#include "BKE_gpencil_modifier.h"
 | 
			
		||||
#include "BKE_object.h"
 | 
			
		||||
 | 
			
		||||
#include "DEG_depsgraph.h"
 | 
			
		||||
#include "DEG_depsgraph_query.h"
 | 
			
		||||
 | 
			
		||||
#include "MOD_gpencil_modifiertypes.h"
 | 
			
		||||
 | 
			
		||||
static GpencilModifierTypeInfo *modifier_gpencil_types[NUM_GREASEPENCIL_MODIFIER_TYPES] = { NULL };
 | 
			
		||||
 | 
			
		||||
/* *************************************************** */
 | 
			
		||||
/* Geometry Utilities */
 | 
			
		||||
 | 
			
		||||
/* calculate stroke normal using some points */
 | 
			
		||||
void BKE_gpencil_stroke_normal(const bGPDstroke *gps, float r_normal[3])
 | 
			
		||||
{
 | 
			
		||||
	if (gps->totpoints < 3) {
 | 
			
		||||
		zero_v3(r_normal);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bGPDspoint *points = gps->points;
 | 
			
		||||
	int totpoints = gps->totpoints;
 | 
			
		||||
 | 
			
		||||
	const bGPDspoint *pt0 = &points[0];
 | 
			
		||||
	const bGPDspoint *pt1 = &points[1];
 | 
			
		||||
	const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)];
 | 
			
		||||
 | 
			
		||||
	float vec1[3];
 | 
			
		||||
	float vec2[3];
 | 
			
		||||
 | 
			
		||||
	/* initial vector (p0 -> p1) */
 | 
			
		||||
	sub_v3_v3v3(vec1, &pt1->x, &pt0->x);
 | 
			
		||||
 | 
			
		||||
	/* point vector at 3/4 */
 | 
			
		||||
	sub_v3_v3v3(vec2, &pt3->x, &pt0->x);
 | 
			
		||||
 | 
			
		||||
	/* vector orthogonal to polygon plane */
 | 
			
		||||
	cross_v3_v3v3(r_normal, vec1, vec2);
 | 
			
		||||
 | 
			
		||||
	/* Normalize vector */
 | 
			
		||||
	normalize_v3(r_normal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get points of stroke always flat to view not affected by camera view or view position */
 | 
			
		||||
static void gpencil_stroke_project_2d(const bGPDspoint *points, int totpoints, vec2f *points2d)
 | 
			
		||||
{
 | 
			
		||||
	const bGPDspoint *pt0 = &points[0];
 | 
			
		||||
	const bGPDspoint *pt1 = &points[1];
 | 
			
		||||
	const bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)];
 | 
			
		||||
 | 
			
		||||
	float locx[3];
 | 
			
		||||
	float locy[3];
 | 
			
		||||
	float loc3[3];
 | 
			
		||||
	float normal[3];
 | 
			
		||||
 | 
			
		||||
	/* local X axis (p0 -> p1) */
 | 
			
		||||
	sub_v3_v3v3(locx, &pt1->x, &pt0->x);
 | 
			
		||||
 | 
			
		||||
	/* point vector at 3/4 */
 | 
			
		||||
	sub_v3_v3v3(loc3, &pt3->x, &pt0->x);
 | 
			
		||||
 | 
			
		||||
	/* vector orthogonal to polygon plane */
 | 
			
		||||
	cross_v3_v3v3(normal, locx, loc3);
 | 
			
		||||
 | 
			
		||||
	/* local Y axis (cross to normal/x axis) */
 | 
			
		||||
	cross_v3_v3v3(locy, normal, locx);
 | 
			
		||||
 | 
			
		||||
	/* Normalize vectors */
 | 
			
		||||
	normalize_v3(locx);
 | 
			
		||||
	normalize_v3(locy);
 | 
			
		||||
 | 
			
		||||
	/* Get all points in local space */
 | 
			
		||||
	for (int i = 0; i < totpoints; i++) {
 | 
			
		||||
		const bGPDspoint *pt = &points[i];
 | 
			
		||||
		float loc[3];
 | 
			
		||||
 | 
			
		||||
		/* Get local space using first point as origin */
 | 
			
		||||
		sub_v3_v3v3(loc, &pt->x, &pt0->x);
 | 
			
		||||
 | 
			
		||||
		vec2f *point = &points2d[i];
 | 
			
		||||
		point->x = dot_v3v3(loc, locx);
 | 
			
		||||
		point->y = dot_v3v3(loc, locy);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Stroke Simplify ------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* Reduce a series of points to a simplified version, but
 | 
			
		||||
 * maintains the general shape of the series
 | 
			
		||||
 *
 | 
			
		||||
 * Ramer - Douglas - Peucker algorithm
 | 
			
		||||
 * by http ://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
 | 
			
		||||
 */
 | 
			
		||||
static void gpencil_rdp_stroke(bGPDstroke *gps, vec2f *points2d, float epsilon)
 | 
			
		||||
{
 | 
			
		||||
	vec2f *old_points2d = points2d;
 | 
			
		||||
	int totpoints = gps->totpoints;
 | 
			
		||||
	char *marked = NULL;
 | 
			
		||||
	char work;
 | 
			
		||||
 | 
			
		||||
	int start = 1;
 | 
			
		||||
	int end = gps->totpoints - 2;
 | 
			
		||||
 | 
			
		||||
	marked = MEM_callocN(totpoints, "GP marked array");
 | 
			
		||||
	marked[start] = 1;
 | 
			
		||||
	marked[end] = 1;
 | 
			
		||||
 | 
			
		||||
	work = 1;
 | 
			
		||||
	int totmarked = 0;
 | 
			
		||||
	/* while still reducing */
 | 
			
		||||
	while (work) {
 | 
			
		||||
		int ls, le;
 | 
			
		||||
		work = 0;
 | 
			
		||||
 | 
			
		||||
		ls = start;
 | 
			
		||||
		le = start + 1;
 | 
			
		||||
 | 
			
		||||
		/* while not over interval */
 | 
			
		||||
		while (ls < end) {
 | 
			
		||||
			int max_i = 0;
 | 
			
		||||
			float v1[2];
 | 
			
		||||
			/* divided to get more control */
 | 
			
		||||
			float max_dist = epsilon / 10.0f;
 | 
			
		||||
 | 
			
		||||
			/* find the next marked point */
 | 
			
		||||
			while (marked[le] == 0) {
 | 
			
		||||
				le++;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* perpendicular vector to ls-le */
 | 
			
		||||
			v1[1] = old_points2d[le].x - old_points2d[ls].x;
 | 
			
		||||
			v1[0] = old_points2d[ls].y - old_points2d[le].y;
 | 
			
		||||
 | 
			
		||||
			for (int i = ls + 1; i < le; i++) {
 | 
			
		||||
				float mul;
 | 
			
		||||
				float dist;
 | 
			
		||||
				float v2[2];
 | 
			
		||||
 | 
			
		||||
				v2[0] = old_points2d[i].x - old_points2d[ls].x;
 | 
			
		||||
				v2[1] = old_points2d[i].y - old_points2d[ls].y;
 | 
			
		||||
 | 
			
		||||
				if (v2[0] == 0 && v2[1] == 0) {
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				mul = (float)(v1[0] * v2[0] + v1[1] * v2[1]) / (float)(v2[0] * v2[0] + v2[1] * v2[1]);
 | 
			
		||||
 | 
			
		||||
				dist = mul * mul * (v2[0] * v2[0] + v2[1] * v2[1]);
 | 
			
		||||
 | 
			
		||||
				if (dist > max_dist) {
 | 
			
		||||
					max_dist = dist;
 | 
			
		||||
					max_i = i;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (max_i != 0) {
 | 
			
		||||
				work = 1;
 | 
			
		||||
				marked[max_i] = 1;
 | 
			
		||||
				totmarked++;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ls = le;
 | 
			
		||||
			le = ls + 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* adding points marked */
 | 
			
		||||
	bGPDspoint *old_points = MEM_dupallocN(gps->points);
 | 
			
		||||
	MDeformVert *old_dvert = MEM_dupallocN(gps->dvert);
 | 
			
		||||
 | 
			
		||||
	/* resize gps */
 | 
			
		||||
	gps->flag |= GP_STROKE_RECALC_CACHES;
 | 
			
		||||
	gps->tot_triangles = 0;
 | 
			
		||||
 | 
			
		||||
	int j = 0;
 | 
			
		||||
	for (int i = 0; i < totpoints; i++) {
 | 
			
		||||
		bGPDspoint *pt_src = &old_points[i];
 | 
			
		||||
		bGPDspoint *pt = &gps->points[j];
 | 
			
		||||
 | 
			
		||||
		MDeformVert *dvert_src = &old_dvert[i];
 | 
			
		||||
		MDeformVert *dvert = &gps->dvert[j];
 | 
			
		||||
 | 
			
		||||
		if ((marked[i]) || (i == 0) || (i == totpoints - 1)) {
 | 
			
		||||
			memcpy(pt, pt_src, sizeof(bGPDspoint));
 | 
			
		||||
			memcpy(dvert, dvert_src, sizeof(MDeformVert));
 | 
			
		||||
			j++;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			BKE_gpencil_free_point_weights(dvert_src);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gps->totpoints = j;
 | 
			
		||||
 | 
			
		||||
	MEM_SAFE_FREE(old_points);
 | 
			
		||||
	MEM_SAFE_FREE(old_dvert);
 | 
			
		||||
	MEM_SAFE_FREE(marked);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Simplify stroke using Ramer-Douglas-Peucker algorithm */
 | 
			
		||||
void BKE_gpencil_simplify_stroke(bGPDstroke *gps, float factor)
 | 
			
		||||
{
 | 
			
		||||
	/* first create temp data and convert points to 2D */
 | 
			
		||||
	vec2f *points2d = MEM_mallocN(sizeof(vec2f) * gps->totpoints, "GP Stroke temp 2d points");
 | 
			
		||||
 | 
			
		||||
	gpencil_stroke_project_2d(gps->points, gps->totpoints, points2d);
 | 
			
		||||
 | 
			
		||||
	gpencil_rdp_stroke(gps, points2d, factor);
 | 
			
		||||
 | 
			
		||||
	MEM_SAFE_FREE(points2d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Simplify alternate vertex of stroke except extrems */
 | 
			
		||||
void BKE_gpencil_simplify_fixed(bGPDstroke *gps)
 | 
			
		||||
{
 | 
			
		||||
	if (gps->totpoints < 5) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* save points */
 | 
			
		||||
	bGPDspoint *old_points = MEM_dupallocN(gps->points);
 | 
			
		||||
	MDeformVert *old_dvert = MEM_dupallocN(gps->dvert);
 | 
			
		||||
 | 
			
		||||
	/* resize gps */
 | 
			
		||||
	int newtot = (gps->totpoints - 2) / 2;
 | 
			
		||||
	if (((gps->totpoints - 2) % 2) > 0) {
 | 
			
		||||
		newtot++;
 | 
			
		||||
	}
 | 
			
		||||
	newtot += 2;
 | 
			
		||||
 | 
			
		||||
	gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot);
 | 
			
		||||
	gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
 | 
			
		||||
	gps->flag |= GP_STROKE_RECALC_CACHES;
 | 
			
		||||
	gps->tot_triangles = 0;
 | 
			
		||||
 | 
			
		||||
	int j = 0;
 | 
			
		||||
	for (int i = 0; i < gps->totpoints; i++) {
 | 
			
		||||
		bGPDspoint *pt_src = &old_points[i];
 | 
			
		||||
		bGPDspoint *pt = &gps->points[j];
 | 
			
		||||
 | 
			
		||||
		MDeformVert *dvert_src = &old_dvert[i];
 | 
			
		||||
		MDeformVert *dvert = &gps->dvert[j];
 | 
			
		||||
 | 
			
		||||
		if ((i == 0) || (i == gps->totpoints - 1) || ((i % 2) > 0.0)) {
 | 
			
		||||
			memcpy(pt, pt_src, sizeof(bGPDspoint));
 | 
			
		||||
			memcpy(dvert, dvert_src, sizeof(MDeformVert));
 | 
			
		||||
			j++;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			BKE_gpencil_free_point_weights(dvert_src);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gps->totpoints = j;
 | 
			
		||||
 | 
			
		||||
	MEM_SAFE_FREE(old_points);
 | 
			
		||||
	MEM_SAFE_FREE(old_dvert);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* *************************************************** */
 | 
			
		||||
/* Modifier Utilities */
 | 
			
		||||
 | 
			
		||||
/* Lattice Modifier ---------------------------------- */
 | 
			
		||||
/* Usually, evaluation of the lattice modifier is self-contained.
 | 
			
		||||
 * However, since GP's modifiers operate on a per-stroke basis,
 | 
			
		||||
 * we need to these two extra functions that called before/after
 | 
			
		||||
 * each loop over all the geometry being evaluated.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* init lattice deform data */
 | 
			
		||||
void BKE_gpencil_lattice_init(Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	GpencilModifierData *md;
 | 
			
		||||
	for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
 | 
			
		||||
		if (md->type == eGpencilModifierType_Lattice) {
 | 
			
		||||
			LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
 | 
			
		||||
			Object *latob = NULL;
 | 
			
		||||
 | 
			
		||||
			latob = mmd->object;
 | 
			
		||||
			if ((!latob) || (latob->type != OB_LATTICE)) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			if (mmd->cache_data) {
 | 
			
		||||
				end_latt_deform((struct LatticeDeformData *)mmd->cache_data);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* init deform data */
 | 
			
		||||
			mmd->cache_data = (struct LatticeDeformData *)init_latt_deform(latob, ob);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* clear lattice deform data */
 | 
			
		||||
void BKE_gpencil_lattice_clear(Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	GpencilModifierData *md;
 | 
			
		||||
	for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
 | 
			
		||||
		if (md->type == eGpencilModifierType_Lattice) {
 | 
			
		||||
			LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
 | 
			
		||||
			if ((mmd) && (mmd->cache_data)) {
 | 
			
		||||
				end_latt_deform((struct LatticeDeformData *)mmd->cache_data);
 | 
			
		||||
				mmd->cache_data = NULL;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* *************************************************** */
 | 
			
		||||
/* Modifier Methods - Evaluation Loops, etc. */
 | 
			
		||||
 | 
			
		||||
/* check if exist geometry modifiers */
 | 
			
		||||
bool BKE_gpencil_has_geometry_modifiers(Object *ob)
 | 
			
		||||
{
 | 
			
		||||
	GpencilModifierData *md;
 | 
			
		||||
	for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
 | 
			
		||||
		const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
 | 
			
		||||
 | 
			
		||||
		if (mti && mti->generateStrokes) {
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* apply stroke modifiers */
 | 
			
		||||
void BKE_gpencil_stroke_modifiers(Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDframe *UNUSED(gpf), bGPDstroke *gps, bool is_render)
 | 
			
		||||
{
 | 
			
		||||
	GpencilModifierData *md;
 | 
			
		||||
	bGPdata *gpd = ob->data;
 | 
			
		||||
	const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
 | 
			
		||||
 | 
			
		||||
	for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
 | 
			
		||||
		if (GPENCIL_MODIFIER_ACTIVE(md, is_render))
 | 
			
		||||
		{
 | 
			
		||||
			const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
 | 
			
		||||
 | 
			
		||||
			if (GPENCIL_MODIFIER_EDIT(md, is_edit)) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (mti && mti->deformStroke) {
 | 
			
		||||
				mti->deformStroke(md, depsgraph, ob, gpl, gps);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* apply stroke geometry modifiers */
 | 
			
		||||
void BKE_gpencil_geometry_modifiers(Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bool is_render)
 | 
			
		||||
{
 | 
			
		||||
	GpencilModifierData *md;
 | 
			
		||||
	bGPdata *gpd = ob->data;
 | 
			
		||||
	const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
 | 
			
		||||
 | 
			
		||||
	for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
 | 
			
		||||
		if (GPENCIL_MODIFIER_ACTIVE(md, is_render))
 | 
			
		||||
		{
 | 
			
		||||
			const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
 | 
			
		||||
 | 
			
		||||
			if (GPENCIL_MODIFIER_EDIT(md, is_edit)) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (mti->generateStrokes) {
 | 
			
		||||
				mti->generateStrokes(md, depsgraph, ob, gpl, gpf);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* *************************************************** */
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_eval_geometry(Depsgraph *depsgraph,
 | 
			
		||||
                               bGPdata *gpd)
 | 
			
		||||
{
 | 
			
		||||
	DEG_debug_print_eval(depsgraph, __func__, gpd->id.name, gpd);
 | 
			
		||||
	int ctime = (int)DEG_get_ctime(depsgraph);
 | 
			
		||||
 | 
			
		||||
	/* update active frame */
 | 
			
		||||
	for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
 | 
			
		||||
		gpl->actframe = BKE_gpencil_layer_getframe(gpl, ctime, GP_GETFRAME_USE_PREV);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* TODO: Move "derived_gpf" logic here from DRW_gpencil_populate_datablock()?
 | 
			
		||||
	 * This would be better than inventing our own logic for this stuff...
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	/* TODO: Move the following code to "BKE_gpencil_eval_done()" (marked as an exit node)
 | 
			
		||||
	 * later when there's more happening here. For now, let's just keep this in here to avoid
 | 
			
		||||
	 * needing to have one more node slowing down evaluation...
 | 
			
		||||
	 */
 | 
			
		||||
	if (DEG_is_active(depsgraph)) {
 | 
			
		||||
		bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&gpd->id);
 | 
			
		||||
 | 
			
		||||
		/* sync "actframe" changes back to main-db too,
 | 
			
		||||
		 * so that editing tools work with copy-on-write
 | 
			
		||||
		 * when the current frame changes
 | 
			
		||||
		 */
 | 
			
		||||
		for (bGPDlayer *gpl = gpd_orig->layers.first; gpl; gpl = gpl->next) {
 | 
			
		||||
			gpl->actframe = BKE_gpencil_layer_getframe(gpl, ctime, GP_GETFRAME_USE_PREV);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_modifier_init(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Initialize modifier types */
 | 
			
		||||
	gpencil_modifier_type_init(modifier_gpencil_types); /* MOD_gpencil_util.c */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GpencilModifierData *BKE_gpencil_modifier_new(int type)
 | 
			
		||||
{
 | 
			
		||||
	const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(type);
 | 
			
		||||
	GpencilModifierData *md = MEM_callocN(mti->struct_size, mti->struct_name);
 | 
			
		||||
 | 
			
		||||
	/* note, this name must be made unique later */
 | 
			
		||||
	BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
 | 
			
		||||
 | 
			
		||||
	md->type = type;
 | 
			
		||||
	md->mode = eGpencilModifierMode_Realtime | eGpencilModifierMode_Render | eGpencilModifierMode_Expanded;
 | 
			
		||||
	md->flag = eGpencilModifierFlag_StaticOverride_Local;
 | 
			
		||||
 | 
			
		||||
	if (mti->flags & eGpencilModifierTypeFlag_EnableInEditmode)
 | 
			
		||||
		md->mode |= eGpencilModifierMode_Editmode;
 | 
			
		||||
 | 
			
		||||
	if (mti->initData) mti->initData(md);
 | 
			
		||||
 | 
			
		||||
	return md;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void modifier_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
 | 
			
		||||
{
 | 
			
		||||
	ID *id = *idpoin;
 | 
			
		||||
	if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
 | 
			
		||||
		id_us_min(id);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_modifier_free_ex(GpencilModifierData *md, const int flag)
 | 
			
		||||
{
 | 
			
		||||
	const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
 | 
			
		||||
 | 
			
		||||
	if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
 | 
			
		||||
		if (mti->foreachIDLink) {
 | 
			
		||||
			mti->foreachIDLink(md, NULL, modifier_free_data_id_us_cb, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		else if (mti->foreachObjectLink) {
 | 
			
		||||
			mti->foreachObjectLink(md, NULL, (GreasePencilObjectWalkFunc)modifier_free_data_id_us_cb, NULL);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (mti->freeData) mti->freeData(md);
 | 
			
		||||
	if (md->error) MEM_freeN(md->error);
 | 
			
		||||
 | 
			
		||||
	MEM_freeN(md);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_modifier_free(GpencilModifierData *md)
 | 
			
		||||
{
 | 
			
		||||
	BKE_gpencil_modifier_free_ex(md, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* check unique name */
 | 
			
		||||
bool BKE_gpencil_modifier_unique_name(ListBase *modifiers, GpencilModifierData *gmd)
 | 
			
		||||
{
 | 
			
		||||
	if (modifiers && gmd) {
 | 
			
		||||
		const GpencilModifierTypeInfo *gmti = BKE_gpencil_modifierType_getInfo(gmd->type);
 | 
			
		||||
		return BLI_uniquename(modifiers, gmd, DATA_(gmti->name), '.', offsetof(GpencilModifierData, name), sizeof(gmd->name));
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BKE_gpencil_modifier_dependsOnTime(GpencilModifierData *md)
 | 
			
		||||
{
 | 
			
		||||
	const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
 | 
			
		||||
 | 
			
		||||
	return mti->dependsOnTime && mti->dependsOnTime(md);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const GpencilModifierTypeInfo *BKE_gpencil_modifierType_getInfo(GpencilModifierType type)
 | 
			
		||||
{
 | 
			
		||||
	/* type unsigned, no need to check < 0 */
 | 
			
		||||
	if (type < NUM_GREASEPENCIL_MODIFIER_TYPES && modifier_gpencil_types[type]->name[0] != '\0') {
 | 
			
		||||
		return modifier_gpencil_types[type];
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_modifier_copyData_generic(const GpencilModifierData *md_src, GpencilModifierData *md_dst)
 | 
			
		||||
{
 | 
			
		||||
	const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md_src->type);
 | 
			
		||||
 | 
			
		||||
	/* md_dst may have alredy be fully initialized with some extra allocated data,
 | 
			
		||||
	* we need to free it now to avoid memleak. */
 | 
			
		||||
	if (mti->freeData) {
 | 
			
		||||
		mti->freeData(md_dst);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const size_t data_size = sizeof(GpencilModifierData);
 | 
			
		||||
	const char *md_src_data = ((const char *)md_src) + data_size;
 | 
			
		||||
	char       *md_dst_data = ((char *)md_dst) + data_size;
 | 
			
		||||
	BLI_assert(data_size <= (size_t)mti->struct_size);
 | 
			
		||||
	memcpy(md_dst_data, md_src_data, (size_t)mti->struct_size - data_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void gpencil_modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
 | 
			
		||||
{
 | 
			
		||||
	ID *id = *idpoin;
 | 
			
		||||
	if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
 | 
			
		||||
		id_us_plus(id);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_modifier_copyData_ex(GpencilModifierData *md, GpencilModifierData *target, const int flag)
 | 
			
		||||
{
 | 
			
		||||
	const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
 | 
			
		||||
 | 
			
		||||
	target->mode = md->mode;
 | 
			
		||||
	target->flag = md->flag;
 | 
			
		||||
 | 
			
		||||
	if (mti->copyData) {
 | 
			
		||||
		mti->copyData(md, target);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
 | 
			
		||||
		if (mti->foreachIDLink) {
 | 
			
		||||
			mti->foreachIDLink(target, NULL, gpencil_modifier_copy_data_id_us_cb, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		else if (mti->foreachObjectLink) {
 | 
			
		||||
			mti->foreachObjectLink(target, NULL, (GreasePencilObjectWalkFunc)gpencil_modifier_copy_data_id_us_cb, NULL);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_modifier_copyData(GpencilModifierData *md, GpencilModifierData *target)
 | 
			
		||||
{
 | 
			
		||||
	BKE_gpencil_modifier_copyData_ex(md, target, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GpencilModifierData *BKE_gpencil_modifiers_findByType(Object *ob, GpencilModifierType type)
 | 
			
		||||
{
 | 
			
		||||
	GpencilModifierData *md = ob->greasepencil_modifiers.first;
 | 
			
		||||
 | 
			
		||||
	for (; md; md = md->next)
 | 
			
		||||
		if (md->type == type)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
	return md;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_modifiers_foreachIDLink(Object *ob, GreasePencilIDWalkFunc walk, void *userData)
 | 
			
		||||
{
 | 
			
		||||
	GpencilModifierData *md = ob->greasepencil_modifiers.first;
 | 
			
		||||
 | 
			
		||||
	for (; md; md = md->next) {
 | 
			
		||||
		const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
 | 
			
		||||
 | 
			
		||||
		if (mti->foreachIDLink) mti->foreachIDLink(md, ob, walk, userData);
 | 
			
		||||
		else if (mti->foreachObjectLink) {
 | 
			
		||||
			/* each Object can masquerade as an ID, so this should be OK */
 | 
			
		||||
			GreasePencilObjectWalkFunc fp = (GreasePencilObjectWalkFunc)walk;
 | 
			
		||||
			mti->foreachObjectLink(md, ob, fp, userData);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_gpencil_modifiers_foreachTexLink(Object *ob, GreasePencilTexWalkFunc walk, void *userData)
 | 
			
		||||
{
 | 
			
		||||
	GpencilModifierData *md = ob->greasepencil_modifiers.first;
 | 
			
		||||
 | 
			
		||||
	for (; md; md = md->next) {
 | 
			
		||||
		const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
 | 
			
		||||
 | 
			
		||||
		if (mti->foreachTexLink)
 | 
			
		||||
			mti->foreachTexLink(md, ob, walk, userData);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GpencilModifierData *BKE_gpencil_modifiers_findByName(Object *ob, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	return BLI_findstring(&(ob->greasepencil_modifiers), name, offsetof(GpencilModifierData, name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* helper function for per-instance positioning */
 | 
			
		||||
void BKE_gpencil_instance_modifier_instance_tfm(InstanceGpencilModifierData *mmd, const int elem_idx[3], float r_mat[4][4])
 | 
			
		||||
{
 | 
			
		||||
	float offset[3], rot[3], scale[3];
 | 
			
		||||
	int ri = mmd->rnd[0];
 | 
			
		||||
	float factor;
 | 
			
		||||
 | 
			
		||||
	offset[0] = mmd->offset[0] * elem_idx[0];
 | 
			
		||||
	offset[1] = mmd->offset[1] * elem_idx[1];
 | 
			
		||||
	offset[2] = mmd->offset[2] * elem_idx[2];
 | 
			
		||||
 | 
			
		||||
	/* rotation */
 | 
			
		||||
	if (mmd->flag & GP_INSTANCE_RANDOM_ROT) {
 | 
			
		||||
		factor = mmd->rnd_rot * mmd->rnd[ri];
 | 
			
		||||
		mul_v3_v3fl(rot, mmd->rot, factor);
 | 
			
		||||
		add_v3_v3(rot, mmd->rot);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		copy_v3_v3(rot, mmd->rot);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* scale */
 | 
			
		||||
	if (mmd->flag & GP_INSTANCE_RANDOM_SIZE) {
 | 
			
		||||
		factor = mmd->rnd_size * mmd->rnd[ri];
 | 
			
		||||
		mul_v3_v3fl(scale, mmd->scale, factor);
 | 
			
		||||
		add_v3_v3(scale, mmd->scale);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		copy_v3_v3(scale, mmd->scale);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* advance random index */
 | 
			
		||||
	mmd->rnd[0]++;
 | 
			
		||||
	if (mmd->rnd[0] > 19) {
 | 
			
		||||
		mmd->rnd[0] = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* calculate matrix */
 | 
			
		||||
	loc_eul_size_to_mat4(r_mat, offset, rot, scale);
 | 
			
		||||
}
 | 
			
		||||
@@ -37,6 +37,8 @@
 | 
			
		||||
 | 
			
		||||
#include "MEM_guardedalloc.h"
 | 
			
		||||
 | 
			
		||||
#include "DNA_brush_types.h"
 | 
			
		||||
#include "DNA_gpencil_types.h"
 | 
			
		||||
#include "DNA_group_types.h"
 | 
			
		||||
#include "DNA_lamp_types.h"
 | 
			
		||||
#include "DNA_material_types.h"
 | 
			
		||||
@@ -45,7 +47,6 @@
 | 
			
		||||
#include "DNA_screen_types.h"
 | 
			
		||||
#include "DNA_texture_types.h"
 | 
			
		||||
#include "DNA_world_types.h"
 | 
			
		||||
#include "DNA_brush_types.h"
 | 
			
		||||
 | 
			
		||||
#include "BLI_utildefines.h"
 | 
			
		||||
#include "BLI_ghash.h"
 | 
			
		||||
@@ -127,6 +128,9 @@ static void icon_free_data(int icon_id, Icon *icon)
 | 
			
		||||
	else if (icon->obj_type == ICON_DATA_PREVIEW) {
 | 
			
		||||
		((PreviewImage *)(icon->obj))->icon_id = 0;
 | 
			
		||||
	}
 | 
			
		||||
	else if (icon->obj_type == ICON_DATA_GPLAYER) {
 | 
			
		||||
		((bGPDlayer *)(icon->obj))->runtime.icon_id = 0;
 | 
			
		||||
	}
 | 
			
		||||
	else if (icon->obj_type == ICON_DATA_GEOM) {
 | 
			
		||||
		((struct Icon_Geom *)(icon->obj))->icon_id = 0;
 | 
			
		||||
	}
 | 
			
		||||
@@ -598,6 +602,44 @@ int BKE_icon_id_ensure(struct ID *id)
 | 
			
		||||
	return icon_id_ensure_create_icon(id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int icon_gplayer_color_ensure_create_icon(bGPDlayer *gpl)
 | 
			
		||||
{
 | 
			
		||||
	BLI_assert(BLI_thread_is_main());
 | 
			
		||||
 | 
			
		||||
	/* NOTE: The color previews for GP Layers don't really need
 | 
			
		||||
	 * to be "rendered" to image per se (as it will just be a plain
 | 
			
		||||
	 * colored rectangle), we need to define icon data here so that
 | 
			
		||||
	 * we can store a pointer to the layer data in icon->obj.
 | 
			
		||||
	 */
 | 
			
		||||
	Icon *icon = icon_create(gpl->runtime.icon_id, ICON_DATA_GPLAYER, gpl);
 | 
			
		||||
	icon->flag = ICON_FLAG_MANAGED;
 | 
			
		||||
 | 
			
		||||
	return gpl->runtime.icon_id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int BKE_icon_gplayer_color_ensure(bGPDlayer *gpl)
 | 
			
		||||
{
 | 
			
		||||
	/* Never handle icons in non-main thread! */
 | 
			
		||||
	BLI_assert(BLI_thread_is_main());
 | 
			
		||||
 | 
			
		||||
	if (!gpl || G.background) {
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (gpl->runtime.icon_id)
 | 
			
		||||
		return gpl->runtime.icon_id;
 | 
			
		||||
 | 
			
		||||
	gpl->runtime.icon_id = get_next_free_id();
 | 
			
		||||
 | 
			
		||||
	if (!gpl->runtime.icon_id) {
 | 
			
		||||
		printf("%s: Internal error - not enough IDs\n", __func__);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return icon_gplayer_color_ensure_create_icon(gpl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return icon id of given preview, or create new icon if not found.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -1073,6 +1073,7 @@ int set_listbasepointers(Main *main, ListBase **lb)
 | 
			
		||||
	lb[INDEX_ID_IP] = &(main->ipo);
 | 
			
		||||
	lb[INDEX_ID_AC] = &(main->action); /* moved here to avoid problems when freeing with animato (aligorith) */
 | 
			
		||||
	lb[INDEX_ID_KE] = &(main->key);
 | 
			
		||||
	lb[INDEX_ID_PAL] = &(main->palettes); /* referenced by gpencil, so needs to be before that to avoid crashes */
 | 
			
		||||
	lb[INDEX_ID_GD] = &(main->gpencil); /* referenced by nodes, objects, view, scene etc, before to free after. */
 | 
			
		||||
	lb[INDEX_ID_NT] = &(main->nodetree);
 | 
			
		||||
	lb[INDEX_ID_IM] = &(main->image);
 | 
			
		||||
 
 | 
			
		||||
@@ -417,7 +417,6 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
 | 
			
		||||
					SEQ_END
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER);
 | 
			
		||||
 | 
			
		||||
				for (CollectionObject *cob = scene->master_collection->gobject.first; cob; cob = cob->next) {
 | 
			
		||||
					CALLBACK_INVOKE(cob->ob, IDWALK_CB_USER);
 | 
			
		||||
@@ -478,6 +477,9 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
 | 
			
		||||
					if (toolsett->uvsculpt) {
 | 
			
		||||
						library_foreach_paint(&data, &toolsett->uvsculpt->paint);
 | 
			
		||||
					}
 | 
			
		||||
					if (toolsett->gp_paint) {
 | 
			
		||||
						library_foreach_paint(&data, &toolsett->gp_paint->paint);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (scene->rigidbody_world) {
 | 
			
		||||
@@ -641,6 +643,10 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
 | 
			
		||||
				if (material->texpaintslot != NULL) {
 | 
			
		||||
					CALLBACK_INVOKE(material->texpaintslot->ima, IDWALK_CB_NOP);
 | 
			
		||||
				}
 | 
			
		||||
				if (material->gp_style != NULL) {
 | 
			
		||||
					CALLBACK_INVOKE(material->gp_style->sima, IDWALK_CB_USER);
 | 
			
		||||
					CALLBACK_INVOKE(material->gp_style->ima, IDWALK_CB_USER);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -758,6 +764,9 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
 | 
			
		||||
				CALLBACK_INVOKE(brush->toggle_brush, IDWALK_CB_NOP);
 | 
			
		||||
				CALLBACK_INVOKE(brush->clone.image, IDWALK_CB_NOP);
 | 
			
		||||
				CALLBACK_INVOKE(brush->paint_curve, IDWALK_CB_USER);
 | 
			
		||||
				if (brush->gpencil_settings) {
 | 
			
		||||
					CALLBACK_INVOKE(brush->gpencil_settings->material, IDWALK_CB_USER);
 | 
			
		||||
				}
 | 
			
		||||
				library_foreach_mtex(&data, &brush->mtex);
 | 
			
		||||
				library_foreach_mtex(&data, &brush->mask_mtex);
 | 
			
		||||
				break;
 | 
			
		||||
@@ -941,10 +950,15 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
 | 
			
		||||
			case ID_GD:
 | 
			
		||||
			{
 | 
			
		||||
				bGPdata *gpencil = (bGPdata *) id;
 | 
			
		||||
 | 
			
		||||
				for (bGPDlayer *gp_layer = gpencil->layers.first; gp_layer; gp_layer = gp_layer->next) {
 | 
			
		||||
					CALLBACK_INVOKE(gp_layer->parent, IDWALK_CB_NOP);
 | 
			
		||||
				/* materials */
 | 
			
		||||
				for (i = 0; i < gpencil->totcol; i++) {
 | 
			
		||||
					CALLBACK_INVOKE(gpencil->mat[i], IDWALK_CB_USER);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				for (bGPDlayer *gplayer = gpencil->layers.first; gplayer != NULL; gplayer = gplayer->next) {
 | 
			
		||||
					CALLBACK_INVOKE(gplayer->parent, IDWALK_CB_NOP);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -1072,7 +1086,7 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
 | 
			
		||||
			return true;
 | 
			
		||||
#endif
 | 
			
		||||
		case ID_BR:
 | 
			
		||||
			return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE);
 | 
			
		||||
			return ELEM(id_type_used, ID_BR, ID_IM, ID_PC, ID_TE, ID_MA);
 | 
			
		||||
		case ID_PA:
 | 
			
		||||
			return ELEM(id_type_used, ID_OB, ID_GR, ID_TE);
 | 
			
		||||
		case ID_MC:
 | 
			
		||||
@@ -1083,6 +1097,8 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
 | 
			
		||||
			return (ELEM(id_type_used, ID_TE, ID_OB));
 | 
			
		||||
		case ID_LP:
 | 
			
		||||
			return ELEM(id_type_used, ID_IM);
 | 
			
		||||
		case ID_GD:
 | 
			
		||||
			return ELEM(id_type_used, ID_MA);
 | 
			
		||||
		case ID_WS:
 | 
			
		||||
			return ELEM(id_type_used, ID_SCR, ID_SCE);
 | 
			
		||||
		case ID_IM:
 | 
			
		||||
@@ -1091,7 +1107,6 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
 | 
			
		||||
		case ID_SO:
 | 
			
		||||
		case ID_AR:
 | 
			
		||||
		case ID_AC:
 | 
			
		||||
		case ID_GD:
 | 
			
		||||
		case ID_WM:
 | 
			
		||||
		case ID_PAL:
 | 
			
		||||
		case ID_PC:
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,7 @@
 | 
			
		||||
#include "DNA_mesh_types.h"
 | 
			
		||||
#include "DNA_meshdata_types.h"
 | 
			
		||||
#include "DNA_customdata_types.h"
 | 
			
		||||
#include "DNA_gpencil_types.h"
 | 
			
		||||
#include "DNA_ID.h"
 | 
			
		||||
#include "DNA_meta_types.h"
 | 
			
		||||
#include "DNA_node_types.h"
 | 
			
		||||
@@ -58,6 +59,7 @@
 | 
			
		||||
#include "BKE_animsys.h"
 | 
			
		||||
#include "BKE_displist.h"
 | 
			
		||||
#include "BKE_global.h"
 | 
			
		||||
#include "BKE_gpencil.h"
 | 
			
		||||
#include "BKE_icons.h"
 | 
			
		||||
#include "BKE_image.h"
 | 
			
		||||
#include "BKE_library.h"
 | 
			
		||||
@@ -103,10 +105,30 @@ void BKE_material_free(Material *ma)
 | 
			
		||||
 | 
			
		||||
	MEM_SAFE_FREE(ma->texpaintslot);
 | 
			
		||||
 | 
			
		||||
	MEM_SAFE_FREE(ma->gp_style);
 | 
			
		||||
 | 
			
		||||
	BKE_icon_id_delete((ID *)ma);
 | 
			
		||||
	BKE_previewimg_free(&ma->preview);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_material_init_gpencil_settings(Material *ma)
 | 
			
		||||
{
 | 
			
		||||
	if ((ma) && (ma->gp_style == NULL)) {
 | 
			
		||||
		ma->gp_style = MEM_callocN(sizeof(MaterialGPencilStyle), "Grease Pencil Material Settings");
 | 
			
		||||
 | 
			
		||||
		MaterialGPencilStyle *gp_style = ma->gp_style;
 | 
			
		||||
		/* set basic settings */
 | 
			
		||||
		gp_style->stroke_rgba[3] = 1.0f;
 | 
			
		||||
		gp_style->pattern_gridsize = 0.1f;
 | 
			
		||||
		gp_style->gradient_radius = 0.5f;
 | 
			
		||||
		ARRAY_SET_ITEMS(gp_style->mix_rgba, 1.0f, 1.0f, 1.0f, 0.2f);
 | 
			
		||||
		ARRAY_SET_ITEMS(gp_style->gradient_scale, 1.0f, 1.0f);
 | 
			
		||||
		ARRAY_SET_ITEMS(gp_style->texture_scale, 1.0f, 1.0f);
 | 
			
		||||
		gp_style->texture_opacity = 1.0f;
 | 
			
		||||
		gp_style->texture_pixsize = 100.0f;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_material_init(Material *ma)
 | 
			
		||||
{
 | 
			
		||||
	BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ma, id));
 | 
			
		||||
@@ -124,6 +146,7 @@ void BKE_material_init(Material *ma)
 | 
			
		||||
	ma->preview = NULL;
 | 
			
		||||
 | 
			
		||||
	ma->alpha_threshold = 0.5f;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Material *BKE_material_add(Main *bmain, const char *name)
 | 
			
		||||
@@ -137,6 +160,19 @@ Material *BKE_material_add(Main *bmain, const char *name)
 | 
			
		||||
	return ma;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Material *BKE_material_add_gpencil(Main *bmain, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	Material *ma;
 | 
			
		||||
 | 
			
		||||
	ma = BKE_material_add(bmain, name);
 | 
			
		||||
 | 
			
		||||
	/* grease pencil settings */
 | 
			
		||||
	BKE_material_init_gpencil_settings(ma);
 | 
			
		||||
 | 
			
		||||
	return ma;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Only copy internal data of Material ID from source to already allocated/initialized destination.
 | 
			
		||||
 * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
 | 
			
		||||
@@ -164,6 +200,10 @@ void BKE_material_copy_data(Main *bmain, Material *ma_dst, const Material *ma_sr
 | 
			
		||||
		ma_dst->texpaintslot = MEM_dupallocN(ma_src->texpaintslot);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ma_src->gp_style != NULL) {
 | 
			
		||||
		ma_dst->gp_style = MEM_dupallocN(ma_src->gp_style);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BLI_listbase_clear(&ma_dst->gpumaterial);
 | 
			
		||||
 | 
			
		||||
	/* TODO Duplicate Engine Settings and set runtime to NULL */
 | 
			
		||||
@@ -199,6 +239,7 @@ Material *BKE_material_localize(Material *ma)
 | 
			
		||||
	man->texpaintslot = NULL;
 | 
			
		||||
	man->preview = NULL;
 | 
			
		||||
 | 
			
		||||
	/* man->gp_style = NULL; */ /* XXX: We probably don't want to clear here, or else we may get problems with COW later? */
 | 
			
		||||
	BLI_listbase_clear(&man->gpumaterial);
 | 
			
		||||
 | 
			
		||||
	/* TODO Duplicate Engine Settings and set runtime to NULL */
 | 
			
		||||
@@ -218,6 +259,7 @@ Material ***give_matarar(Object *ob)
 | 
			
		||||
	Mesh *me;
 | 
			
		||||
	Curve *cu;
 | 
			
		||||
	MetaBall *mb;
 | 
			
		||||
	bGPdata *gpd;
 | 
			
		||||
 | 
			
		||||
	if (ob->type == OB_MESH) {
 | 
			
		||||
		me = ob->data;
 | 
			
		||||
@@ -231,6 +273,10 @@ Material ***give_matarar(Object *ob)
 | 
			
		||||
		mb = ob->data;
 | 
			
		||||
		return &(mb->mat);
 | 
			
		||||
	}
 | 
			
		||||
	else if (ob->type == OB_GPENCIL) {
 | 
			
		||||
		gpd = ob->data;
 | 
			
		||||
		return &(gpd->mat);
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -239,6 +285,7 @@ short *give_totcolp(Object *ob)
 | 
			
		||||
	Mesh *me;
 | 
			
		||||
	Curve *cu;
 | 
			
		||||
	MetaBall *mb;
 | 
			
		||||
	bGPdata *gpd;
 | 
			
		||||
 | 
			
		||||
	if (ob->type == OB_MESH) {
 | 
			
		||||
		me = ob->data;
 | 
			
		||||
@@ -252,6 +299,10 @@ short *give_totcolp(Object *ob)
 | 
			
		||||
		mb = ob->data;
 | 
			
		||||
		return &(mb->totcol);
 | 
			
		||||
	}
 | 
			
		||||
	else if (ob->type == OB_GPENCIL) {
 | 
			
		||||
		gpd = ob->data;
 | 
			
		||||
		return &(gpd->totcol);
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -286,6 +337,8 @@ short *give_totcolp_id(ID *id)
 | 
			
		||||
			return &(((Curve *)id)->totcol);
 | 
			
		||||
		case ID_MB:
 | 
			
		||||
			return &(((MetaBall *)id)->totcol);
 | 
			
		||||
		case ID_GD:
 | 
			
		||||
			return &(((bGPdata *)id)->totcol);
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
@@ -307,6 +360,9 @@ static void material_data_index_remove_id(ID *id, short index)
 | 
			
		||||
		case ID_MB:
 | 
			
		||||
			/* meta-elems don't have materials atm */
 | 
			
		||||
			break;
 | 
			
		||||
		case ID_GD:
 | 
			
		||||
			BKE_gpencil_material_index_remove((bGPdata *)id, index);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
@@ -487,6 +543,21 @@ Material *give_current_material(Object *ob, short act)
 | 
			
		||||
	return ma;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MaterialGPencilStyle *BKE_material_gpencil_settings_get(Object *ob, short act)
 | 
			
		||||
{
 | 
			
		||||
	Material *ma = give_current_material(ob, act);
 | 
			
		||||
	if (ma != NULL) {
 | 
			
		||||
		if (ma->gp_style == NULL) {
 | 
			
		||||
			BKE_material_init_gpencil_settings(ma);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return ma->gp_style;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Material *give_node_material(Material *ma)
 | 
			
		||||
{
 | 
			
		||||
	if (ma && ma->use_nodes && ma->nodetree) {
 | 
			
		||||
@@ -727,6 +798,9 @@ void BKE_material_remap_object(Object *ob, const unsigned int *remap)
 | 
			
		||||
	else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
 | 
			
		||||
		BKE_curve_material_remap(ob->data, remap, ob->totcol);
 | 
			
		||||
	}
 | 
			
		||||
	if (ob->type == OB_GPENCIL) {
 | 
			
		||||
		BKE_gpencil_material_remap(ob->data, remap, ob->totcol);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		/* add support for this object data! */
 | 
			
		||||
		BLI_assert(matar == NULL);
 | 
			
		||||
@@ -924,7 +998,7 @@ bool BKE_object_material_slot_remove(Main *bmain, Object *ob)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* check indices from mesh */
 | 
			
		||||
	if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
 | 
			
		||||
	if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_GPENCIL)) {
 | 
			
		||||
		material_data_index_remove_id((ID *)ob->data, actcol - 1);
 | 
			
		||||
		if (ob->runtime.curve_cache) {
 | 
			
		||||
			BKE_displist_free(&ob->runtime.curve_cache->disp);
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,7 @@
 | 
			
		||||
#include "DNA_camera_types.h"
 | 
			
		||||
#include "DNA_constraint_types.h"
 | 
			
		||||
#include "DNA_gpencil_types.h"
 | 
			
		||||
#include "DNA_gpencil_modifier_types.h"
 | 
			
		||||
#include "DNA_group_types.h"
 | 
			
		||||
#include "DNA_key_types.h"
 | 
			
		||||
#include "DNA_lamp_types.h"
 | 
			
		||||
@@ -53,6 +54,7 @@
 | 
			
		||||
#include "DNA_scene_types.h"
 | 
			
		||||
#include "DNA_screen_types.h"
 | 
			
		||||
#include "DNA_sequence_types.h"
 | 
			
		||||
#include "DNA_shader_fx_types.h"
 | 
			
		||||
#include "DNA_smoke_types.h"
 | 
			
		||||
#include "DNA_space_types.h"
 | 
			
		||||
#include "DNA_view3d_types.h"
 | 
			
		||||
@@ -86,6 +88,7 @@
 | 
			
		||||
#include "BKE_displist.h"
 | 
			
		||||
#include "BKE_effect.h"
 | 
			
		||||
#include "BKE_fcurve.h"
 | 
			
		||||
#include "BKE_gpencil_modifier.h"
 | 
			
		||||
#include "BKE_icons.h"
 | 
			
		||||
#include "BKE_key.h"
 | 
			
		||||
#include "BKE_lamp.h"
 | 
			
		||||
@@ -110,12 +113,14 @@
 | 
			
		||||
#include "BKE_rigidbody.h"
 | 
			
		||||
#include "BKE_scene.h"
 | 
			
		||||
#include "BKE_sequencer.h"
 | 
			
		||||
#include "BKE_shader_fx.h"
 | 
			
		||||
#include "BKE_speaker.h"
 | 
			
		||||
#include "BKE_softbody.h"
 | 
			
		||||
#include "BKE_subsurf.h"
 | 
			
		||||
#include "BKE_material.h"
 | 
			
		||||
#include "BKE_camera.h"
 | 
			
		||||
#include "BKE_image.h"
 | 
			
		||||
#include "BKE_gpencil.h"
 | 
			
		||||
 | 
			
		||||
#include "DEG_depsgraph.h"
 | 
			
		||||
#include "DEG_depsgraph_query.h"
 | 
			
		||||
@@ -185,11 +190,15 @@ void BKE_object_free_curve_cache(Object *ob)
 | 
			
		||||
void BKE_object_free_modifiers(Object *ob, const int flag)
 | 
			
		||||
{
 | 
			
		||||
	ModifierData *md;
 | 
			
		||||
	GpencilModifierData *gp_md;
 | 
			
		||||
 | 
			
		||||
	while ((md = BLI_pophead(&ob->modifiers))) {
 | 
			
		||||
		modifier_free_ex(md, flag);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while ((gp_md = BLI_pophead(&ob->greasepencil_modifiers))) {
 | 
			
		||||
		BKE_gpencil_modifier_free_ex(gp_md, flag);
 | 
			
		||||
	}
 | 
			
		||||
	/* particle modifiers were freed, so free the particlesystems as well */
 | 
			
		||||
	BKE_object_free_particlesystems(ob);
 | 
			
		||||
 | 
			
		||||
@@ -200,6 +209,15 @@ void BKE_object_free_modifiers(Object *ob, const int flag)
 | 
			
		||||
	BKE_object_free_derived_caches(ob);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_object_free_shaderfx(Object *ob, const int flag)
 | 
			
		||||
{
 | 
			
		||||
	ShaderFxData *fx;
 | 
			
		||||
 | 
			
		||||
	while ((fx = BLI_pophead(&ob->shader_fx))) {
 | 
			
		||||
		BKE_shaderfx_free_ex(fx, flag);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_object_modifier_hook_reset(Object *ob, HookModifierData *hmd)
 | 
			
		||||
{
 | 
			
		||||
	/* reset functionality */
 | 
			
		||||
@@ -222,6 +240,29 @@ void BKE_object_modifier_hook_reset(Object *ob, HookModifierData *hmd)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BKE_object_modifier_gpencil_hook_reset(Object *ob, HookGpencilModifierData *hmd)
 | 
			
		||||
{
 | 
			
		||||
	if (hmd->object == NULL) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	/* reset functionality */
 | 
			
		||||
	bPoseChannel *pchan = BKE_pose_channel_find_name(hmd->object->pose, hmd->subtarget);
 | 
			
		||||
 | 
			
		||||
	if (hmd->subtarget[0] && pchan) {
 | 
			
		||||
		float imat[4][4], mat[4][4];
 | 
			
		||||
 | 
			
		||||
		/* calculate the world-space matrix for the pose-channel target first, then carry on as usual */
 | 
			
		||||
		mul_m4_m4m4(mat, hmd->object->obmat, pchan->pose_mat);
 | 
			
		||||
 | 
			
		||||
		invert_m4_m4(imat, mat);
 | 
			
		||||
		mul_m4_m4m4(hmd->parentinv, imat, ob->obmat);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		invert_m4_m4(hmd->object->imat, hmd->object->obmat);
 | 
			
		||||
		mul_m4_m4m4(hmd->parentinv, hmd->object->imat, ob->obmat);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
 | 
			
		||||
{
 | 
			
		||||
	const ModifierTypeInfo *mti;
 | 
			
		||||
@@ -428,6 +469,7 @@ void BKE_object_free(Object *ob)
 | 
			
		||||
 | 
			
		||||
	/* BKE_<id>_free shall never touch to ID->us. Never ever. */
 | 
			
		||||
	BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
 | 
			
		||||
	BKE_object_free_shaderfx(ob, LIB_ID_CREATE_NO_USER_REFCOUNT);
 | 
			
		||||
 | 
			
		||||
	MEM_SAFE_FREE(ob->mat);
 | 
			
		||||
	MEM_SAFE_FREE(ob->matbits);
 | 
			
		||||
@@ -653,6 +695,7 @@ static const char *get_obdata_defname(int type)
 | 
			
		||||
		case OB_ARMATURE: return DATA_("Armature");
 | 
			
		||||
		case OB_SPEAKER: return DATA_("Speaker");
 | 
			
		||||
		case OB_EMPTY: return DATA_("Empty");
 | 
			
		||||
		case OB_GPENCIL: return DATA_("GPencil");
 | 
			
		||||
		default:
 | 
			
		||||
			printf("get_obdata_defname: Internal error, bad type: %d\n", type);
 | 
			
		||||
			return DATA_("Empty");
 | 
			
		||||
@@ -677,6 +720,7 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name)
 | 
			
		||||
		case OB_ARMATURE:  return BKE_armature_add(bmain, name);
 | 
			
		||||
		case OB_SPEAKER:   return BKE_speaker_add(bmain, name);
 | 
			
		||||
		case OB_LIGHTPROBE:return BKE_lightprobe_add(bmain, name);
 | 
			
		||||
		case OB_GPENCIL:   return BKE_gpencil_data_addnew(bmain, name);
 | 
			
		||||
		case OB_EMPTY:     return NULL;
 | 
			
		||||
		default:
 | 
			
		||||
			printf("%s: Internal error, bad type: %d\n", __func__, type);
 | 
			
		||||
@@ -810,7 +854,7 @@ Object *BKE_object_add(
 | 
			
		||||
/**
 | 
			
		||||
 * Add a new object, using another one as a reference
 | 
			
		||||
 *
 | 
			
		||||
 * /param ob_src object to use to determine the collections of the new object.
 | 
			
		||||
 * \param ob_src object to use to determine the collections of the new object.
 | 
			
		||||
 */
 | 
			
		||||
Object *BKE_object_add_from(
 | 
			
		||||
        Main *bmain, Scene *scene, ViewLayer *view_layer,
 | 
			
		||||
@@ -828,6 +872,41 @@ Object *BKE_object_add_from(
 | 
			
		||||
	return ob;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add a new object, but assign the given datablock as the ob->data
 | 
			
		||||
 * for the newly created object.
 | 
			
		||||
 *
 | 
			
		||||
 * \param data The datablock to assign as ob->data for the new object.
 | 
			
		||||
 *             This is assumed to be of the correct type.
 | 
			
		||||
 * \param do_id_user If true, id_us_plus() will be called on data when
 | 
			
		||||
 *                 assigning it to the object.
 | 
			
		||||
 */
 | 
			
		||||
Object *BKE_object_add_for_data(
 | 
			
		||||
        Main *bmain, ViewLayer *view_layer,
 | 
			
		||||
        int type, const char *name, ID *data, bool do_id_user)
 | 
			
		||||
{
 | 
			
		||||
	Object *ob;
 | 
			
		||||
	Base *base;
 | 
			
		||||
	LayerCollection *layer_collection;
 | 
			
		||||
 | 
			
		||||
	/* same as object_add_common, except we don't create new ob->data */
 | 
			
		||||
	ob = BKE_object_add_only_object(bmain, type, name);
 | 
			
		||||
	ob->data = data;
 | 
			
		||||
	if (do_id_user) id_us_plus(data);
 | 
			
		||||
 | 
			
		||||
	BKE_view_layer_base_deselect_all(view_layer);
 | 
			
		||||
	DEG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 | 
			
		||||
 | 
			
		||||
	layer_collection = BKE_layer_collection_get_active(view_layer);
 | 
			
		||||
	BKE_collection_object_add(bmain, layer_collection->collection, ob);
 | 
			
		||||
 | 
			
		||||
	base = BKE_view_layer_base_find(view_layer, ob);
 | 
			
		||||
	BKE_view_layer_base_select(view_layer, base);
 | 
			
		||||
 | 
			
		||||
	return ob;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src, const int flag)
 | 
			
		||||
{
 | 
			
		||||
	SoftBody *sb = ob_src->soft;
 | 
			
		||||
@@ -1153,6 +1232,8 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
 | 
			
		||||
void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
 | 
			
		||||
{
 | 
			
		||||
	ModifierData *md;
 | 
			
		||||
	GpencilModifierData *gmd;
 | 
			
		||||
	ShaderFxData *fx;
 | 
			
		||||
 | 
			
		||||
	/* Do not copy runtime data. */
 | 
			
		||||
	BKE_object_runtime_reset(ob_dst);
 | 
			
		||||
@@ -1179,6 +1260,24 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con
 | 
			
		||||
		BLI_addtail(&ob_dst->modifiers, nmd);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BLI_listbase_clear(&ob_dst->greasepencil_modifiers);
 | 
			
		||||
 | 
			
		||||
	for (gmd = ob_src->greasepencil_modifiers.first; gmd; gmd = gmd->next) {
 | 
			
		||||
		GpencilModifierData *nmd = BKE_gpencil_modifier_new(gmd->type);
 | 
			
		||||
		BLI_strncpy(nmd->name, gmd->name, sizeof(nmd->name));
 | 
			
		||||
		BKE_gpencil_modifier_copyData_ex(gmd, nmd, flag_subdata);
 | 
			
		||||
		BLI_addtail(&ob_dst->greasepencil_modifiers, nmd);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BLI_listbase_clear(&ob_dst->shader_fx);
 | 
			
		||||
 | 
			
		||||
	for (fx = ob_src->shader_fx.first; fx; fx = fx->next) {
 | 
			
		||||
		ShaderFxData *nfx = BKE_shaderfx_new(fx->type);
 | 
			
		||||
		BLI_strncpy(nfx->name, fx->name, sizeof(nfx->name));
 | 
			
		||||
		BKE_shaderfx_copyData_ex(fx, nfx, flag_subdata);
 | 
			
		||||
		BLI_addtail(&ob_dst->shader_fx, nfx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ob_src->pose) {
 | 
			
		||||
		copy_object_pose(ob_dst, ob_src, flag_subdata);
 | 
			
		||||
		/* backwards compat... non-armatures can get poses in older files? */
 | 
			
		||||
@@ -1210,6 +1309,10 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con
 | 
			
		||||
	BLI_listbase_clear((ListBase *)&ob_dst->drawdata);
 | 
			
		||||
	BLI_listbase_clear(&ob_dst->pc_ids);
 | 
			
		||||
 | 
			
		||||
	/* grease pencil: clean derived data */
 | 
			
		||||
	if (ob_dst->type == OB_GPENCIL)
 | 
			
		||||
		BKE_gpencil_free_derived_frames(ob_dst->data);
 | 
			
		||||
 | 
			
		||||
	ob_dst->avs = ob_src->avs;
 | 
			
		||||
	ob_dst->mpath = animviz_copy_motionpath(ob_src->mpath);
 | 
			
		||||
 | 
			
		||||
@@ -1469,6 +1572,11 @@ void BKE_object_obdata_size_init(struct Object *ob, const float size)
 | 
			
		||||
			ob->empty_drawsize *= size;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OB_GPENCIL:
 | 
			
		||||
		{
 | 
			
		||||
			ob->empty_drawsize *= size;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OB_FONT:
 | 
			
		||||
		{
 | 
			
		||||
			Curve *cu = ob->data;
 | 
			
		||||
@@ -2452,7 +2560,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us
 | 
			
		||||
		float size[3];
 | 
			
		||||
 | 
			
		||||
		copy_v3_v3(size, ob->size);
 | 
			
		||||
		if (ob->type == OB_EMPTY) {
 | 
			
		||||
		if ((ob->type == OB_EMPTY) || (ob->type == OB_GPENCIL)) {
 | 
			
		||||
			mul_v3_fl(size, ob->empty_drawsize);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -3694,6 +3802,88 @@ bool BKE_object_modifier_use_time(Object *ob, ModifierData *md)
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BKE_object_modifier_gpencil_use_time(Object *ob, GpencilModifierData *md)
 | 
			
		||||
{
 | 
			
		||||
	if (BKE_gpencil_modifier_dependsOnTime(md)) {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check whether modifier is animated. */
 | 
			
		||||
	/* TODO (Aligorith): this should be handled as part of build_animdata() */
 | 
			
		||||
	if (ob->adt) {
 | 
			
		||||
		AnimData *adt = ob->adt;
 | 
			
		||||
		FCurve *fcu;
 | 
			
		||||
 | 
			
		||||
		char pattern[MAX_NAME + 32];
 | 
			
		||||
		BLI_snprintf(pattern, sizeof(pattern), "grease_pencil_modifiers[\"%s\"]", md->name);
 | 
			
		||||
 | 
			
		||||
		/* action - check for F-Curves with paths containing 'grease_pencil_modifiers[' */
 | 
			
		||||
		if (adt->action) {
 | 
			
		||||
			for (fcu = (FCurve *)adt->action->curves.first;
 | 
			
		||||
				fcu != NULL;
 | 
			
		||||
				fcu = (FCurve *)fcu->next)
 | 
			
		||||
			{
 | 
			
		||||
				if (fcu->rna_path && strstr(fcu->rna_path, pattern))
 | 
			
		||||
					return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* This here allows modifier properties to get driven and still update properly
 | 
			
		||||
		*
 | 
			
		||||
		*/
 | 
			
		||||
		for (fcu = (FCurve *)adt->drivers.first;
 | 
			
		||||
			fcu != NULL;
 | 
			
		||||
			fcu = (FCurve *)fcu->next)
 | 
			
		||||
		{
 | 
			
		||||
			if (fcu->rna_path && strstr(fcu->rna_path, pattern))
 | 
			
		||||
				return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BKE_object_shaderfx_use_time(Object *ob, ShaderFxData *fx)
 | 
			
		||||
{
 | 
			
		||||
	if (BKE_shaderfx_dependsOnTime(fx)) {
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check whether effect is animated. */
 | 
			
		||||
	/* TODO (Aligorith): this should be handled as part of build_animdata() */
 | 
			
		||||
	if (ob->adt) {
 | 
			
		||||
		AnimData *adt = ob->adt;
 | 
			
		||||
		FCurve *fcu;
 | 
			
		||||
 | 
			
		||||
		char pattern[MAX_NAME + 32];
 | 
			
		||||
		BLI_snprintf(pattern, sizeof(pattern), "shader_effects[\"%s\"]", fx->name);
 | 
			
		||||
 | 
			
		||||
		/* action - check for F-Curves with paths containing string[' */
 | 
			
		||||
		if (adt->action) {
 | 
			
		||||
			for (fcu = (FCurve *)adt->action->curves.first;
 | 
			
		||||
				fcu != NULL;
 | 
			
		||||
				fcu = (FCurve *)fcu->next)
 | 
			
		||||
			{
 | 
			
		||||
				if (fcu->rna_path && strstr(fcu->rna_path, pattern))
 | 
			
		||||
					return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* This here allows properties to get driven and still update properly
 | 
			
		||||
		*
 | 
			
		||||
		*/
 | 
			
		||||
		for (fcu = (FCurve *)adt->drivers.first;
 | 
			
		||||
			fcu != NULL;
 | 
			
		||||
			fcu = (FCurve *)fcu->next)
 | 
			
		||||
		{
 | 
			
		||||
			if (fcu->rna_path && strstr(fcu->rna_path, pattern))
 | 
			
		||||
				return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* set "ignore cache" flag for all caches on this object */
 | 
			
		||||
static void object_cacheIgnoreClear(Object *ob, int state)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,7 @@
 | 
			
		||||
#include "BKE_object.h"
 | 
			
		||||
#include "BKE_mesh.h"
 | 
			
		||||
#include "BKE_modifier.h"
 | 
			
		||||
#include "BKE_gpencil.h"
 | 
			
		||||
 | 
			
		||||
/** \name Misc helpers
 | 
			
		||||
 * \{ */
 | 
			
		||||
@@ -402,12 +403,17 @@ static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg)
 | 
			
		||||
 */
 | 
			
		||||
void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
 | 
			
		||||
{
 | 
			
		||||
	if (BKE_object_is_in_editmode_vgroup(ob))
 | 
			
		||||
		object_defgroup_remove_edit_mode(ob, defgroup);
 | 
			
		||||
	else
 | 
			
		||||
		object_defgroup_remove_object_mode(ob, defgroup);
 | 
			
		||||
	if ((ob) && (ob->type == OB_GPENCIL)) {
 | 
			
		||||
		BKE_gpencil_vgroup_remove(ob, defgroup);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		if (BKE_object_is_in_editmode_vgroup(ob))
 | 
			
		||||
			object_defgroup_remove_edit_mode(ob, defgroup);
 | 
			
		||||
		else
 | 
			
		||||
			object_defgroup_remove_object_mode(ob, defgroup);
 | 
			
		||||
 | 
			
		||||
	BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
 | 
			
		||||
		BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@
 | 
			
		||||
#include "BKE_particle.h"
 | 
			
		||||
#include "BKE_pointcache.h"
 | 
			
		||||
#include "BKE_scene.h"
 | 
			
		||||
#include "BKE_gpencil.h"
 | 
			
		||||
 | 
			
		||||
#include "MEM_guardedalloc.h"
 | 
			
		||||
 | 
			
		||||
@@ -324,6 +325,9 @@ void BKE_object_eval_uber_data(Depsgraph *depsgraph,
 | 
			
		||||
		case OB_MBALL:
 | 
			
		||||
			BKE_mball_batch_cache_dirty(ob->data, BKE_MBALL_BATCH_DIRTY_ALL);
 | 
			
		||||
			break;
 | 
			
		||||
		case OB_GPENCIL:
 | 
			
		||||
			BKE_gpencil_batch_cache_dirty(ob->data);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,13 +41,19 @@
 | 
			
		||||
#include "DNA_scene_types.h"
 | 
			
		||||
#include "DNA_brush_types.h"
 | 
			
		||||
#include "DNA_space_types.h"
 | 
			
		||||
#include "DNA_gpencil_types.h"
 | 
			
		||||
#include "DNA_workspace_types.h"
 | 
			
		||||
 | 
			
		||||
#include "BLI_bitmap.h"
 | 
			
		||||
#include "BLI_blenlib.h"
 | 
			
		||||
#include "BLI_utildefines.h"
 | 
			
		||||
#include "BLI_string_utils.h"
 | 
			
		||||
#include "BLI_math_vector.h"
 | 
			
		||||
#include "BLI_listbase.h"
 | 
			
		||||
 | 
			
		||||
#include "BLT_translation.h"
 | 
			
		||||
 | 
			
		||||
#include "BKE_animsys.h"
 | 
			
		||||
#include "BKE_brush.h"
 | 
			
		||||
#include "BKE_colortools.h"
 | 
			
		||||
#include "BKE_deform.h"
 | 
			
		||||
@@ -55,6 +61,7 @@
 | 
			
		||||
#include "BKE_context.h"
 | 
			
		||||
#include "BKE_crazyspace.h"
 | 
			
		||||
#include "BKE_global.h"
 | 
			
		||||
#include "BKE_gpencil.h"
 | 
			
		||||
#include "BKE_image.h"
 | 
			
		||||
#include "BKE_key.h"
 | 
			
		||||
#include "BKE_library.h"
 | 
			
		||||
@@ -151,6 +158,8 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode)
 | 
			
		||||
				return &ts->imapaint.paint;
 | 
			
		||||
			case ePaintSculptUV:
 | 
			
		||||
				return &ts->uvsculpt->paint;
 | 
			
		||||
			case ePaintGpencil:
 | 
			
		||||
				return &ts->gp_paint->paint;
 | 
			
		||||
			case ePaintInvalid:
 | 
			
		||||
				return NULL;
 | 
			
		||||
			default:
 | 
			
		||||
@@ -176,6 +185,8 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
 | 
			
		||||
					return &ts->wpaint->paint;
 | 
			
		||||
				case OB_MODE_TEXTURE_PAINT:
 | 
			
		||||
					return &ts->imapaint.paint;
 | 
			
		||||
				case OB_MODE_GPENCIL_PAINT:
 | 
			
		||||
					return &ts->gp_paint->paint;
 | 
			
		||||
				case OB_MODE_EDIT:
 | 
			
		||||
					if (ts->use_uv_sculpt)
 | 
			
		||||
						return &ts->uvsculpt->paint;
 | 
			
		||||
@@ -430,13 +441,11 @@ PaletteColor *BKE_palette_color_add(Palette *palette)
 | 
			
		||||
	return color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool BKE_palette_is_empty(const struct Palette *palette)
 | 
			
		||||
{
 | 
			
		||||
	return BLI_listbase_is_empty(&palette->colors);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* are we in vertex paint or weight pain face select mode? */
 | 
			
		||||
bool BKE_paint_select_face_test(Object *ob)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||