GSOC 2013 paint
Yep, at last it's here! There are a few minor issues remaining but development can go on in master after discussion at blender institute. For full list of features see: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72/Painting Thanks to Sergey and Campbell for the extensive review and to the countless artists that have given their input and reported issues during development.
This commit is contained in:
@@ -730,6 +730,8 @@ if B.targets != ['cudakernels']:
|
||||
data_to_c_simple("release/datafiles/brushicons/soften.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/subtract.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/texdraw.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/texfill.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/texmask.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/thumb.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/twist.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/vertexdraw.png")
|
||||
|
||||
@@ -50,6 +50,10 @@ class UnifiedPaintPanel():
|
||||
row.prop(ups, "use_unified_strength", text="Strength")
|
||||
if context.weight_paint_object:
|
||||
parent.prop(ups, "use_unified_weight", text="Weight")
|
||||
elif context.vertex_paint_object or context.image_paint_object:
|
||||
parent.prop(ups, "use_unified_color", text="Color")
|
||||
else:
|
||||
parent.prop(ups, "use_unified_color", text="Color")
|
||||
|
||||
@staticmethod
|
||||
def prop_unified_size(parent, context, brush, prop_name, icon='NONE', text="", slider=False):
|
||||
@@ -69,6 +73,105 @@ class UnifiedPaintPanel():
|
||||
ptr = ups if ups.use_unified_weight else brush
|
||||
parent.prop(ptr, prop_name, icon=icon, text=text, slider=slider)
|
||||
|
||||
@staticmethod
|
||||
def prop_unified_color(parent, context, brush, prop_name, text=""):
|
||||
ups = context.tool_settings.unified_paint_settings
|
||||
ptr = ups if ups.use_unified_color else brush
|
||||
parent.prop(ptr, prop_name, text=text)
|
||||
|
||||
@staticmethod
|
||||
def prop_unified_color_picker(parent, context, brush, prop_name, value_slider=True):
|
||||
ups = context.tool_settings.unified_paint_settings
|
||||
ptr = ups if ups.use_unified_color else brush
|
||||
parent.template_color_picker(ptr, prop_name, value_slider=value_slider)
|
||||
|
||||
|
||||
def brush_texpaint_common(panel, context, layout, brush, settings):
|
||||
capabilities = brush.image_paint_capabilities
|
||||
|
||||
col = layout.column()
|
||||
|
||||
if brush.image_tool in {'DRAW', 'FILL'}:
|
||||
if brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'}:
|
||||
if not brush.use_gradient:
|
||||
panel.prop_unified_color_picker(col, context, brush, "color", value_slider=True)
|
||||
|
||||
if settings.palette:
|
||||
col.template_palette(settings, "palette", color=True)
|
||||
|
||||
if brush.use_gradient:
|
||||
col.label("Gradient Colors")
|
||||
col.template_color_ramp(brush, "gradient", expand=True)
|
||||
|
||||
if brush.image_tool != 'FILL':
|
||||
col.label("Background Color")
|
||||
row = col.row(align=True)
|
||||
panel.prop_unified_color(row, context, brush, "secondary_color", text="")
|
||||
|
||||
if brush.image_tool == 'DRAW':
|
||||
col.prop(brush, "gradient_stroke_mode", text="Mode")
|
||||
if brush.gradient_stroke_mode in {'SPACING_REPEAT', 'SPACING_CLAMP'}:
|
||||
col.prop(brush, "grad_spacing")
|
||||
elif brush.image_tool == 'FILL':
|
||||
col.prop(brush, "gradient_fill_mode")
|
||||
else:
|
||||
row = col.row(align=True)
|
||||
panel.prop_unified_color(row, context, brush, "color", text="")
|
||||
if brush.image_tool == 'FILL':
|
||||
col.prop(brush, "fill_threshold")
|
||||
else:
|
||||
panel.prop_unified_color(row, context, brush, "secondary_color", text="")
|
||||
row.separator()
|
||||
row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="")
|
||||
|
||||
elif brush.image_tool == 'SOFTEN':
|
||||
col = layout.column(align=True)
|
||||
col.row().prop(brush, "direction", expand=True)
|
||||
col.separator()
|
||||
col.prop(brush, "sharp_threshold")
|
||||
col.prop(brush, "blur_kernel_radius")
|
||||
col.separator()
|
||||
col.prop(brush, "blur_mode")
|
||||
elif brush.image_tool == 'MASK':
|
||||
col.prop(brush, "weight", text="Mask Value", slider=True)
|
||||
|
||||
elif brush.image_tool == 'CLONE':
|
||||
col.separator()
|
||||
col.prop(brush, "clone_image", text="Image")
|
||||
col.prop(brush, "clone_alpha", text="Alpha")
|
||||
|
||||
col.separator()
|
||||
|
||||
if capabilities.has_radius:
|
||||
row = col.row(align=True)
|
||||
panel.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
|
||||
panel.prop_unified_size(row, context, brush, "use_pressure_size")
|
||||
|
||||
row = col.row(align=True)
|
||||
|
||||
if capabilities.has_space_attenuation:
|
||||
row.prop(brush, "use_space_attenuation", toggle=True, icon_only=True)
|
||||
|
||||
panel.prop_unified_strength(row, context, brush, "strength", text="Strength")
|
||||
panel.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
if brush.image_tool in {'DRAW', 'FILL'}:
|
||||
col.separator()
|
||||
col.prop(brush, "blend", text="Blend")
|
||||
|
||||
col = layout.column()
|
||||
|
||||
# use_accumulate
|
||||
if capabilities.has_accumulate:
|
||||
col = layout.column(align=True)
|
||||
col.prop(brush, "use_accumulate")
|
||||
|
||||
col.prop(brush, "use_alpha")
|
||||
col.prop(brush, "use_gradient")
|
||||
|
||||
col.separator()
|
||||
col.template_ID(settings, "palette", new="palette.new")
|
||||
|
||||
|
||||
# Used in both the View3D toolbar and texture properties
|
||||
def brush_texture_settings(layout, brush, sculpt):
|
||||
@@ -136,6 +239,7 @@ def brush_mask_texture_settings(layout, brush):
|
||||
layout.operator("brush.stencil_reset_transform").mask = True
|
||||
|
||||
col = layout.column()
|
||||
col.prop(brush, "use_pressure_masking", text="")
|
||||
col.label(text="Angle:")
|
||||
col.active = brush.brush_capabilities.has_texture_angle
|
||||
col.prop(mask_tex_slot, "angle", text="")
|
||||
|
||||
@@ -22,6 +22,7 @@ from bpy.types import Header, Menu, Panel
|
||||
from bl_ui.properties_paint_common import (
|
||||
UnifiedPaintPanel,
|
||||
brush_texture_settings,
|
||||
brush_texpaint_common,
|
||||
brush_mask_texture_settings,
|
||||
)
|
||||
from bl_ui.properties_grease_pencil_common import GreasePencilPanel
|
||||
@@ -31,13 +32,11 @@ from bpy.app.translations import pgettext_iface as iface_
|
||||
class ImagePaintPanel(UnifiedPaintPanel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_category = "Tools"
|
||||
|
||||
|
||||
class BrushButtonsPanel:
|
||||
class BrushButtonsPanel(UnifiedPaintPanel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_category = "Tools"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -66,6 +65,7 @@ class IMAGE_MT_view(Menu):
|
||||
sima = context.space_data
|
||||
uv = sima.uv_editor
|
||||
toolsettings = context.tool_settings
|
||||
paint = toolsettings.image_paint
|
||||
|
||||
show_uvedit = sima.show_uvedit
|
||||
show_render = sima.show_render
|
||||
@@ -80,6 +80,8 @@ class IMAGE_MT_view(Menu):
|
||||
layout.prop(toolsettings, "show_uv_local_view")
|
||||
|
||||
layout.prop(uv, "show_other_objects")
|
||||
if paint.brush and (context.image_paint_object or sima.mode == 'PAINT'):
|
||||
layout.prop(uv, "show_texpaint")
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -140,6 +142,24 @@ class IMAGE_MT_select(Menu):
|
||||
layout.operator("uv.select_split")
|
||||
|
||||
|
||||
class IMAGE_MT_brush(Menu):
|
||||
bl_label = "Brush"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
toolsettings = context.tool_settings
|
||||
settings = toolsettings.image_paint
|
||||
brush = settings.brush
|
||||
|
||||
ups = context.tool_settings.unified_paint_settings
|
||||
layout.prop(ups, "use_unified_size", text="Unified Size")
|
||||
layout.prop(ups, "use_unified_strength", text="Unified Strength")
|
||||
layout.separator()
|
||||
|
||||
# brush tool
|
||||
layout.prop_menu_enum(brush, "image_tool")
|
||||
|
||||
|
||||
class IMAGE_MT_image(Menu):
|
||||
bl_label = "Image"
|
||||
|
||||
@@ -382,7 +402,6 @@ class IMAGE_HT_header(Header):
|
||||
mode = sima.mode
|
||||
|
||||
show_render = sima.show_render
|
||||
# show_paint = sima.show_paint
|
||||
show_uvedit = sima.show_uvedit
|
||||
show_maskedit = sima.show_maskedit
|
||||
|
||||
@@ -401,8 +420,7 @@ class IMAGE_HT_header(Header):
|
||||
row = layout.row()
|
||||
row.template_ID(sima, "mask", new="mask.new")
|
||||
|
||||
if show_uvedit or show_maskedit:
|
||||
layout.prop(sima, "pivot_point", icon_only=True)
|
||||
layout.prop(sima, "pivot_point", icon_only=True)
|
||||
|
||||
# uv editing
|
||||
if show_uvedit:
|
||||
@@ -462,6 +480,7 @@ class MASK_MT_editor_menus(Menu):
|
||||
|
||||
show_uvedit = sima.show_uvedit
|
||||
show_maskedit = sima.show_maskedit
|
||||
show_paint = sima.show_paint
|
||||
|
||||
layout.menu("IMAGE_MT_view")
|
||||
|
||||
@@ -469,6 +488,8 @@ class MASK_MT_editor_menus(Menu):
|
||||
layout.menu("IMAGE_MT_select")
|
||||
if show_maskedit:
|
||||
layout.menu("MASK_MT_select")
|
||||
if show_paint:
|
||||
layout.menu("IMAGE_MT_brush")
|
||||
|
||||
if ima and ima.is_dirty:
|
||||
layout.menu("IMAGE_MT_image", text="Image*")
|
||||
@@ -658,49 +679,27 @@ class IMAGE_PT_tools_transform_uvs(Panel, UVToolsPanel):
|
||||
col.operator("transform.shear")
|
||||
|
||||
|
||||
class IMAGE_PT_paint(Panel, ImagePaintPanel):
|
||||
class IMAGE_PT_paint(Panel, BrushButtonsPanel):
|
||||
bl_label = "Paint"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sima = context.space_data
|
||||
return sima.show_paint
|
||||
bl_category = "Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
toolsettings = context.tool_settings.image_paint
|
||||
brush = toolsettings.brush
|
||||
settings = context.tool_settings.image_paint
|
||||
brush = settings.brush
|
||||
|
||||
col = layout.column()
|
||||
col.template_ID_preview(toolsettings, "brush", new="brush.add", rows=2, cols=6)
|
||||
col.template_ID_preview(settings, "brush", new="brush.add", rows=2, cols=6)
|
||||
|
||||
if brush:
|
||||
col = layout.column()
|
||||
|
||||
if brush.image_tool == 'DRAW' and brush.blend not in ('ERASE_ALPHA', 'ADD_ALPHA'):
|
||||
col.template_color_picker(brush, "color", value_slider=True)
|
||||
col.prop(brush, "color", text="")
|
||||
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
|
||||
self.prop_unified_size(row, context, brush, "use_pressure_size")
|
||||
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_strength(row, context, brush, "strength", slider=True, text="Strength")
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
col.prop(brush, "blend", text="Blend")
|
||||
|
||||
if brush.image_tool == 'CLONE':
|
||||
col.separator()
|
||||
col.prop(brush, "clone_image", text="Image")
|
||||
col.prop(brush, "clone_alpha", text="Alpha")
|
||||
brush_texpaint_common(self, context, layout, brush, settings)
|
||||
|
||||
|
||||
class IMAGE_PT_tools_brush_overlay(BrushButtonsPanel, Panel):
|
||||
bl_label = "Overlay"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_category = "Options"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -754,6 +753,7 @@ class IMAGE_PT_tools_brush_overlay(BrushButtonsPanel, Panel):
|
||||
class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
|
||||
bl_label = "Texture"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_category = "Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -770,6 +770,7 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
|
||||
class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel):
|
||||
bl_label = "Texture Mask"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_category = "Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -786,6 +787,7 @@ class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel):
|
||||
class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, Panel):
|
||||
bl_label = "Tool"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_category = "Options"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -804,6 +806,7 @@ class IMAGE_PT_tools_brush_tool(BrushButtonsPanel, Panel):
|
||||
class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
|
||||
bl_label = "Paint Stroke"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_category = "Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -828,10 +831,19 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
|
||||
if brush.use_space:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
if brush.use_line or brush.use_curve:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
|
||||
if brush.use_curve:
|
||||
col.separator()
|
||||
col.template_ID(brush, "paint_curve", new="paintcurve.new")
|
||||
col.operator("paintcurve.draw")
|
||||
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
@@ -846,25 +858,23 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
if brush.brush_capabilities.has_smooth_stroke:
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = brush.use_smooth_stroke
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
sub = col.column()
|
||||
sub.active = brush.use_smooth_stroke
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
col.separator()
|
||||
col.separator()
|
||||
|
||||
col.prop(toolsettings, "input_samples")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_wrap")
|
||||
|
||||
|
||||
class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
|
||||
bl_label = "Paint Curve"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_category = "Tools"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -874,7 +884,8 @@ class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
|
||||
|
||||
layout.template_curve_mapping(brush, "curve")
|
||||
|
||||
row = layout.row(align=True)
|
||||
col = layout.column(align=True)
|
||||
row = col.row(align=True)
|
||||
row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
|
||||
row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
|
||||
row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
|
||||
@@ -886,6 +897,7 @@ class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
|
||||
class IMAGE_PT_tools_brush_appearance(BrushButtonsPanel, Panel):
|
||||
bl_label = "Appearance"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_category = "Options"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -912,6 +924,30 @@ class IMAGE_PT_tools_brush_appearance(BrushButtonsPanel, Panel):
|
||||
sub.prop(brush, "icon_filepath", text="")
|
||||
|
||||
|
||||
class IMAGE_PT_tools_paint_options(BrushButtonsPanel, Panel):
|
||||
bl_label = "Image Paint"
|
||||
bl_category = "Options"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
toolsettings = context.tool_settings
|
||||
brush = toolsettings.image_paint.brush
|
||||
|
||||
ups = toolsettings.unified_paint_settings
|
||||
|
||||
col = layout.column(align=True)
|
||||
|
||||
col.prop(brush, "use_wrap")
|
||||
col.separator()
|
||||
|
||||
col.label(text="Unified Settings:")
|
||||
row = col.row()
|
||||
row.prop(ups, "use_unified_size", text="Size")
|
||||
row.prop(ups, "use_unified_strength", text="Strength")
|
||||
col.prop(ups, "use_unified_color", text="Color")
|
||||
|
||||
|
||||
class IMAGE_UV_sculpt_curve(Panel):
|
||||
bl_space_type = 'IMAGE_EDITOR'
|
||||
bl_region_type = 'TOOLS'
|
||||
|
||||
@@ -1454,7 +1454,7 @@ class VIEW3D_MT_brush(Menu):
|
||||
layout.separator()
|
||||
|
||||
if sculpt_tool != 'GRAB':
|
||||
layout.prop_menu_enum(brush, "stroke_method")
|
||||
layout.prop_menu_enum(brush, "sculpt_stroke_method")
|
||||
|
||||
if sculpt_tool in {'DRAW', 'PINCH', 'INFLATE', 'LAYER', 'CLAY'}:
|
||||
layout.prop_menu_enum(brush, "direction")
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
from bpy.types import Menu, Panel
|
||||
from bpy.types import Menu, Panel, UIList
|
||||
from bl_ui.properties_grease_pencil_common import GreasePencilPanel
|
||||
from bl_ui.properties_paint_common import (
|
||||
UnifiedPaintPanel,
|
||||
brush_texture_settings,
|
||||
brush_texpaint_common,
|
||||
brush_mask_texture_settings,
|
||||
)
|
||||
|
||||
@@ -363,6 +364,7 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
|
||||
|
||||
draw_repeat_tools(context, layout)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_meshweight(View3DPanel, Panel):
|
||||
bl_category = "Tools"
|
||||
bl_context = "mesh_edit"
|
||||
@@ -388,6 +390,7 @@ class VIEW3D_PT_tools_meshweight(View3DPanel, Panel):
|
||||
layout = self.layout
|
||||
self.draw_generic(layout)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_add_mesh_edit(View3DPanel, Panel):
|
||||
bl_category = "Create"
|
||||
bl_context = "mesh_edit"
|
||||
@@ -979,25 +982,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
# Texture Paint Mode #
|
||||
|
||||
elif context.image_paint_object and brush:
|
||||
col = layout.column()
|
||||
|
||||
if brush.image_tool == 'DRAW' and brush.blend not in ('ERASE_ALPHA', 'ADD_ALPHA'):
|
||||
col.template_color_picker(brush, "color", value_slider=True)
|
||||
col.prop(brush, "color", text="")
|
||||
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
|
||||
self.prop_unified_size(row, context, brush, "use_pressure_size")
|
||||
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_strength(row, context, brush, "strength", text="Strength")
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
col.prop(brush, "blend", text="Blend")
|
||||
|
||||
col = layout.column()
|
||||
col.active = (brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'})
|
||||
col.prop(brush, "use_alpha")
|
||||
brush_texpaint_common(self, context, layout, brush, settings)
|
||||
|
||||
# Weight Paint Mode #
|
||||
elif context.weight_paint_object and brush:
|
||||
@@ -1024,9 +1009,12 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
# Vertex Paint Mode #
|
||||
elif context.vertex_paint_object and brush:
|
||||
col = layout.column()
|
||||
col.template_color_picker(brush, "color", value_slider=True)
|
||||
col.prop(brush, "color", text="")
|
||||
self.prop_unified_color_picker(col, context, brush, "color", value_slider=True)
|
||||
if settings.palette:
|
||||
col.template_palette(settings, "palette", color=True)
|
||||
self.prop_unified_color(col, context, brush, "color", text="")
|
||||
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
|
||||
self.prop_unified_size(row, context, brush, "use_pressure_size")
|
||||
@@ -1036,12 +1024,75 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
# XXX - TODO
|
||||
#row = col.row(align=True)
|
||||
#row.prop(brush, "jitter", slider=True)
|
||||
#row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
# row = col.row(align=True)
|
||||
# row.prop(brush, "jitter", slider=True)
|
||||
# row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
col.separator()
|
||||
col.prop(brush, "vertex_tool", text="Blend")
|
||||
|
||||
col.separator()
|
||||
col.template_ID(settings, "palette", new="palette.new")
|
||||
|
||||
|
||||
class TEXTURE_UL_texpaintslots(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
ma = data
|
||||
ima = item
|
||||
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
layout.label(text=ima.name, translate=False, icon_value=icon)
|
||||
elif self.layout_type in {'GRID'}:
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label(text="")
|
||||
|
||||
|
||||
class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
|
||||
bl_context = "imagepaint"
|
||||
bl_label = "Slots"
|
||||
bl_category = "Layers"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
brush = context.tool_settings.image_paint.brush
|
||||
ob = context.active_object
|
||||
return (brush is not None and ob is not None)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
settings = context.tool_settings.image_paint
|
||||
brush = settings.brush
|
||||
|
||||
ob = context.active_object
|
||||
col = layout.column()
|
||||
|
||||
if len(ob.material_slots) > 1:
|
||||
col.label("Materials")
|
||||
col.template_list("MATERIAL_UL_matslots", "",
|
||||
ob, "material_slots",
|
||||
ob, "active_material_index", rows=2)
|
||||
|
||||
mat = ob.active_material
|
||||
if mat:
|
||||
col.label("Available Paint Slots")
|
||||
col.template_list("TEXTURE_UL_texpaintslots", "",
|
||||
mat, "texture_paint_slots",
|
||||
mat, "paint_active_slot", rows=2)
|
||||
|
||||
if not mat.use_nodes:
|
||||
col.operator_menu_enum("paint.add_texture_paint_slot", "type")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(settings, "slot_xresolution_default")
|
||||
row.prop(settings, "slot_yresolution_default")
|
||||
col.prop(settings, "slot_color_default")
|
||||
|
||||
if brush.image_tool == 'CLONE' and settings.use_clone_layer:
|
||||
col.label("Clone Slot")
|
||||
col.template_list("TEXTURE_UL_texpaintslots", "",
|
||||
mat, "texture_paint_slots",
|
||||
mat, "paint_clone_slot", rows=2)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_overlay(Panel, View3DPaintPanel):
|
||||
bl_category = "Options"
|
||||
@@ -1194,10 +1245,19 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
if brush.use_space:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.active = brush.use_space
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
|
||||
|
||||
if brush.use_line or brush.use_curve:
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "spacing", text="Spacing")
|
||||
|
||||
if brush.use_curve:
|
||||
col.separator()
|
||||
col.template_ID(brush, "paint_curve", new="paintcurve.new")
|
||||
col.operator("paintcurve.draw")
|
||||
|
||||
if context.sculpt_object:
|
||||
if brush.sculpt_capabilities.has_jitter:
|
||||
col.separator()
|
||||
@@ -1234,12 +1294,13 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
if brush.brush_capabilities.has_smooth_stroke:
|
||||
col.prop(brush, "use_smooth_stroke")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = brush.use_smooth_stroke
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
sub = col.column()
|
||||
sub.active = brush.use_smooth_stroke
|
||||
sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
|
||||
sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
|
||||
|
||||
layout.prop(settings, "input_samples")
|
||||
|
||||
@@ -1263,7 +1324,8 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
|
||||
|
||||
layout.template_curve_mapping(brush, "curve", brush=True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
col = layout.column(align=True)
|
||||
row = col.row(align=True)
|
||||
row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
|
||||
row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
|
||||
row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
|
||||
@@ -1493,7 +1555,7 @@ class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel):
|
||||
|
||||
col = layout.column()
|
||||
row = col.row()
|
||||
#col.prop(vpaint, "mode", text="")
|
||||
# col.prop(vpaint, "mode", text="")
|
||||
row.prop(vpaint, "use_normal")
|
||||
col.prop(vpaint, "use_spray")
|
||||
|
||||
@@ -1531,7 +1593,7 @@ class VIEW3D_PT_tools_imagepaint_external(Panel, View3DPaintPanel):
|
||||
col.operator("image.save_dirty", text="Save All Edited")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
|
||||
class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel):
|
||||
bl_category = "Options"
|
||||
bl_context = "imagepaint"
|
||||
bl_label = "Project Paint"
|
||||
@@ -1551,6 +1613,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
|
||||
settings = toolsettings.image_paint
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.prop(ipaint, "use_occlude")
|
||||
col.prop(ipaint, "use_backface_culling")
|
||||
|
||||
@@ -1565,19 +1628,21 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
|
||||
|
||||
split.prop(ipaint, "use_stencil_layer", text="Stencil")
|
||||
|
||||
row = split.row()
|
||||
row.active = (ipaint.use_stencil_layer)
|
||||
col = split.column()
|
||||
col.active = (ipaint.use_stencil_layer)
|
||||
row = col.row()
|
||||
stencil_text = mesh.uv_texture_stencil.name if mesh.uv_texture_stencil else ""
|
||||
row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text, translate=False)
|
||||
row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA')
|
||||
col.template_ID(ipaint, "stencil_image", new="image.new")
|
||||
col.prop(ipaint, "stencil_color")
|
||||
|
||||
col = layout.column()
|
||||
col.active = (settings.brush.image_tool == 'CLONE')
|
||||
col.prop(ipaint, "use_clone_layer", text="Clone from UV map")
|
||||
clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else ""
|
||||
col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text, translate=False)
|
||||
col.prop(ipaint, "use_clone_layer", text="Clone from paint slot")
|
||||
|
||||
layout.prop(ipaint, "seam_bleed")
|
||||
self.unified_paint_settings(layout, context)
|
||||
|
||||
|
||||
class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
|
||||
|
||||
@@ -150,8 +150,10 @@ typedef DMDrawOption (*DMSetDrawOptions)(void *userData, int index);
|
||||
typedef DMDrawOption (*DMSetDrawOptionsTex)(struct MTFace *tface, const bool has_vcol, int matnr);
|
||||
|
||||
typedef enum DMDrawFlag {
|
||||
DM_DRAW_USE_COLORS = 1,
|
||||
DM_DRAW_ALWAYS_SMOOTH = 2
|
||||
DM_DRAW_USE_COLORS = (1 << 0),
|
||||
DM_DRAW_ALWAYS_SMOOTH = (1 << 1),
|
||||
DM_DRAW_USE_ACTIVE_UV = (1 << 2),
|
||||
DM_DRAW_USE_TEXPAINT_UV = (1 << 3),
|
||||
} DMDrawFlag;
|
||||
|
||||
typedef enum DMForeachFlag {
|
||||
@@ -389,7 +391,7 @@ struct DerivedMesh {
|
||||
void (*drawFacesTex)(DerivedMesh *dm,
|
||||
DMSetDrawOptionsTex setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData);
|
||||
void *userData, DMDrawFlag uvflag);
|
||||
|
||||
/** Draw all faces with GLSL materials
|
||||
* o setMaterial is called for every different material nr
|
||||
@@ -423,7 +425,7 @@ struct DerivedMesh {
|
||||
void (*drawMappedFacesTex)(DerivedMesh *dm,
|
||||
DMSetDrawOptions setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData);
|
||||
void *userData, DMDrawFlag uvflag);
|
||||
|
||||
/** Draw mapped faces with GLSL materials
|
||||
* - setMaterial is called for every different material nr
|
||||
@@ -593,6 +595,8 @@ void DM_ensure_tessface(DerivedMesh *dm);
|
||||
void DM_update_tessface_data(DerivedMesh *dm);
|
||||
|
||||
void DM_update_materials(DerivedMesh *dm, struct Object *ob);
|
||||
struct MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr);
|
||||
|
||||
/** interpolates vertex data from the vertices indexed by src_indices in the
|
||||
* source mesh using the given weights and stores the result in the vertex
|
||||
* indexed by dest_index in the dest mesh
|
||||
|
||||
@@ -42,7 +42,7 @@ extern "C" {
|
||||
* and keep comment above the defines.
|
||||
* Use STRINGIFY() rather than defining with quotes */
|
||||
#define BLENDER_VERSION 271
|
||||
#define BLENDER_SUBVERSION 2
|
||||
#define BLENDER_SUBVERSION 3
|
||||
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
|
||||
#define BLENDER_MINVERSION 270
|
||||
#define BLENDER_MINSUBVERSION 5
|
||||
|
||||
@@ -81,7 +81,11 @@ unsigned int *BKE_brush_gen_texture_cache(struct Brush *br, int half_side, bool
|
||||
/* radial control */
|
||||
struct ImBuf *BKE_brush_gen_radial_control_imbuf(struct Brush *br, bool secondary);
|
||||
|
||||
/* unified strength and size */
|
||||
/* unified strength size and color */
|
||||
|
||||
float *BKE_brush_color_get(const struct Scene *scene, struct Brush *brush);
|
||||
float *BKE_brush_secondary_color_get(const struct Scene *scene, struct Brush *brush);
|
||||
void BKE_brush_color_set(struct Scene *scene, struct Brush *brush, const float color[3]);
|
||||
|
||||
int BKE_brush_size_get(const struct Scene *scene, struct Brush *brush);
|
||||
void BKE_brush_size_set(struct Scene *scene, struct Brush *brush, int value);
|
||||
|
||||
@@ -71,7 +71,7 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id);
|
||||
|
||||
struct ListBase *which_libbase(struct Main *mainlib, short type);
|
||||
|
||||
#define MAX_LIBARRAY 41
|
||||
#define MAX_LIBARRAY 43
|
||||
int set_listbasepointers(struct Main *main, struct ListBase **lb);
|
||||
|
||||
void BKE_libblock_free(struct Main *bmain, void *idv);
|
||||
|
||||
@@ -87,6 +87,8 @@ typedef struct Main {
|
||||
ListBase nodetree;
|
||||
ListBase brush;
|
||||
ListBase particle;
|
||||
ListBase palettes;
|
||||
ListBase paintcurves;
|
||||
ListBase wm;
|
||||
ListBase gpencil;
|
||||
ListBase movieclip;
|
||||
|
||||
@@ -86,6 +86,10 @@ short find_material_index(struct Object *ob, struct Material *ma);
|
||||
bool object_add_material_slot(struct Object *ob);
|
||||
bool object_remove_material_slot(struct Object *ob);
|
||||
|
||||
void BKE_texpaint_slot_refresh_cache(struct Material *ma, bool use_nodes);
|
||||
void BKE_texpaint_slots_refresh_object(struct Object *ob, bool use_nodes);
|
||||
void BKE_texpaint_slots_clear(struct Material *ma);
|
||||
|
||||
/* rna api */
|
||||
void BKE_material_resize_id(struct ID *id, short totcol, bool do_id_user);
|
||||
void BKE_material_append_id(struct ID *id, struct Material *ma);
|
||||
|
||||
@@ -40,11 +40,15 @@ struct CurveMapping;
|
||||
struct MDisps;
|
||||
struct MeshElemMap;
|
||||
struct GridPaintMask;
|
||||
struct Main;
|
||||
struct MFace;
|
||||
struct MultireModifierData;
|
||||
struct MVert;
|
||||
struct Object;
|
||||
struct Paint;
|
||||
struct PaintCurve;
|
||||
struct Palette;
|
||||
struct PaletteColor;
|
||||
struct PBVH;
|
||||
struct Scene;
|
||||
struct Sculpt;
|
||||
@@ -52,6 +56,7 @@ struct StrokeCache;
|
||||
struct Tex;
|
||||
struct ImagePool;
|
||||
struct UnifiedPaintSettings;
|
||||
struct wmOperator;
|
||||
|
||||
enum OverlayFlags;
|
||||
|
||||
@@ -91,6 +96,19 @@ OverlayControlFlags BKE_paint_get_overlay_flags(void);
|
||||
void BKE_paint_reset_overlay_invalid(OverlayControlFlags flag);
|
||||
void BKE_paint_set_overlay_override(enum OverlayFlags flag);
|
||||
|
||||
/* palettes */
|
||||
void BKE_palette_free(struct Palette *palette);
|
||||
struct Palette *BKE_palette_add(struct Main *bmain, const char *name);
|
||||
struct PaletteColor *BKE_palette_color_add(struct Palette *palette);
|
||||
void BKE_palette_color_delete(struct Palette *palette);
|
||||
bool BKE_palette_is_empty(const struct Palette *palette);
|
||||
void BKE_palette_color_remove(struct Palette *palette, struct PaletteColor *color);
|
||||
void BKE_palette_cleanup(struct Palette *palette);
|
||||
|
||||
/* paint curves */
|
||||
struct PaintCurve *BKE_paint_curve_add(struct Main *bmain, const char *name);
|
||||
void BKE_paint_curve_free(struct PaintCurve *pc);
|
||||
|
||||
void BKE_paint_init(struct Paint *p, const char col[3]);
|
||||
void BKE_paint_free(struct Paint *p);
|
||||
void BKE_paint_copy(struct Paint *src, struct Paint *tar);
|
||||
@@ -100,6 +118,9 @@ struct Paint *BKE_paint_get_active_from_context(const struct bContext *C);
|
||||
PaintMode BKE_paintmode_get_active_from_context(const struct bContext *C);
|
||||
struct Brush *BKE_paint_brush(struct Paint *paint);
|
||||
void BKE_paint_brush_set(struct Paint *paint, struct Brush *br);
|
||||
struct Palette *BKE_paint_palette(struct Paint *paint);
|
||||
void BKE_paint_palette_set(struct Paint *p, struct Palette *palette);
|
||||
void BKE_paint_curve_set(struct Brush *br, struct PaintCurve *pc);
|
||||
|
||||
/* testing face select mode
|
||||
* Texture paint could be removed since selected faces are not used
|
||||
@@ -117,7 +138,10 @@ bool paint_is_bmesh_face_hidden(struct BMFace *f);
|
||||
/* paint masks */
|
||||
float paint_grid_paint_mask(const struct GridPaintMask *gpm, unsigned level,
|
||||
unsigned x, unsigned y);
|
||||
|
||||
/* stroke related */
|
||||
void paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, const float mouse_pos[2]);
|
||||
|
||||
/* Session data (mode-specific) */
|
||||
|
||||
typedef struct SculptSession {
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "DNA_cloth_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
@@ -501,11 +502,36 @@ void DM_update_materials(DerivedMesh *dm, Object *ob)
|
||||
|
||||
dm->mat = MEM_callocN(totmat * sizeof(*dm->mat), "DerivedMesh.mat");
|
||||
|
||||
for (i = 1; i < totmat; i++) {
|
||||
dm->mat[i] = give_current_material(ob, i);
|
||||
/* we leave last material as empty - rationale here is being able to index
|
||||
* the materials by using the mf->mat_nr directly and leaving the last
|
||||
* material as NULL in case no materials exist on mesh, so indexing will not fail */
|
||||
for (i = 0; i < totmat - 1; i++) {
|
||||
dm->mat[i] = give_current_material(ob, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr)
|
||||
{
|
||||
MTFace *tf_base;
|
||||
|
||||
BLI_assert(mat_nr < dm->totmat);
|
||||
|
||||
if (dm->mat[mat_nr] && dm->mat[mat_nr]->texpaintslot &&
|
||||
dm->mat[mat_nr]->texpaintslot[dm->mat[mat_nr]->paint_active_slot].uvname[0])
|
||||
{
|
||||
tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
|
||||
dm->mat[mat_nr]->texpaintslot[dm->mat[mat_nr]->paint_active_slot].uvname);
|
||||
/* This can fail if we have changed the name in the UV layer list and have assigned the old name in the material
|
||||
* texture slot.*/
|
||||
if (!tf_base)
|
||||
tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE);
|
||||
}
|
||||
else {
|
||||
tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE);
|
||||
}
|
||||
|
||||
return tf_base;
|
||||
}
|
||||
|
||||
void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
|
||||
{
|
||||
@@ -3091,7 +3117,7 @@ static void navmesh_drawColored(DerivedMesh *dm)
|
||||
static void navmesh_DM_drawFacesTex(DerivedMesh *dm,
|
||||
DMSetDrawOptionsTex setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag UNUSED(flag))
|
||||
{
|
||||
(void) setDrawOptions;
|
||||
(void) compareDrawOptions;
|
||||
|
||||
@@ -83,6 +83,7 @@ static void brush_defaults(Brush *brush)
|
||||
brush->plane_trim = 0.5f;
|
||||
brush->clone.alpha = 0.5f;
|
||||
brush->normal_weight = 0.0f;
|
||||
brush->fill_threshold = 0.2f;
|
||||
brush->flag |= BRUSH_ALPHA_PRESSURE;
|
||||
|
||||
/* BRUSH PAINT TOOL SETTINGS */
|
||||
@@ -90,6 +91,8 @@ static void brush_defaults(Brush *brush)
|
||||
brush->rgb[1] = 1.0f;
|
||||
brush->rgb[2] = 1.0f;
|
||||
|
||||
zero_v3(brush->secondary_rgb);
|
||||
|
||||
/* BRUSH STROKE SETTINGS */
|
||||
brush->flag |= (BRUSH_SPACE | BRUSH_SPACE_ATTEN);
|
||||
brush->spacing = 10; /* how far each brush dot should be spaced as a percentage of brush diameter */
|
||||
@@ -161,6 +164,9 @@ Brush *BKE_brush_copy(Brush *brush)
|
||||
if (brush->mask_mtex.tex)
|
||||
id_us_plus((ID *)brush->mask_mtex.tex);
|
||||
|
||||
if (brush->paint_curve)
|
||||
id_us_plus((ID *)brush->paint_curve);
|
||||
|
||||
if (brush->icon_imbuf)
|
||||
brushn->icon_imbuf = IMB_dupImBuf(brush->icon_imbuf);
|
||||
|
||||
@@ -180,11 +186,9 @@ Brush *BKE_brush_copy(Brush *brush)
|
||||
/* not brush itself */
|
||||
void BKE_brush_free(Brush *brush)
|
||||
{
|
||||
if (brush->mtex.tex)
|
||||
brush->mtex.tex->id.us--;
|
||||
|
||||
if (brush->mask_mtex.tex)
|
||||
brush->mask_mtex.tex->id.us--;
|
||||
id_us_min((ID *)brush->mtex.tex);
|
||||
id_us_min((ID *)brush->mask_mtex.tex);
|
||||
id_us_min((ID *)brush->paint_curve);
|
||||
|
||||
if (brush->icon_imbuf)
|
||||
IMB_freeImBuf(brush->icon_imbuf);
|
||||
@@ -192,6 +196,9 @@ void BKE_brush_free(Brush *brush)
|
||||
BKE_previewimg_free(&(brush->preview));
|
||||
|
||||
curvemapping_free(brush->curve);
|
||||
|
||||
if (brush->gradient)
|
||||
MEM_freeN(brush->gradient);
|
||||
}
|
||||
|
||||
static void extern_local_brush(Brush *brush)
|
||||
@@ -199,6 +206,7 @@ static void extern_local_brush(Brush *brush)
|
||||
id_lib_extern((ID *)brush->mtex.tex);
|
||||
id_lib_extern((ID *)brush->mask_mtex.tex);
|
||||
id_lib_extern((ID *)brush->clone.image);
|
||||
id_lib_extern((ID *)brush->paint_curve);
|
||||
}
|
||||
|
||||
void BKE_brush_make_local(Brush *brush)
|
||||
@@ -742,10 +750,23 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
|
||||
rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
|
||||
}
|
||||
|
||||
CLAMP(intensity, 0.0f, 1.0f);
|
||||
|
||||
switch (br->mask_pressure) {
|
||||
case BRUSH_MASK_PRESSURE_CUTOFF:
|
||||
intensity = ((1.0f - intensity) < ups->size_pressure_value) ? 1.0f : 0.0f;
|
||||
break;
|
||||
case BRUSH_MASK_PRESSURE_RAMP:
|
||||
intensity = ups->size_pressure_value + intensity * (1.0f - ups->size_pressure_value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return intensity;
|
||||
}
|
||||
|
||||
/* Unified Size and Strength */
|
||||
/* Unified Size / Strength / Color */
|
||||
|
||||
/* XXX: be careful about setting size and unprojected radius
|
||||
* because they depend on one another
|
||||
@@ -760,6 +781,29 @@ float BKE_brush_sample_masktex(const Scene *scene, Brush *br,
|
||||
* In any case, a better solution is needed to prevent
|
||||
* inconsistency. */
|
||||
|
||||
|
||||
float *BKE_brush_color_get(const struct Scene *scene, struct Brush *brush)
|
||||
{
|
||||
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
|
||||
return (ups->flag & UNIFIED_PAINT_COLOR) ? ups->rgb : brush->rgb;
|
||||
}
|
||||
|
||||
float *BKE_brush_secondary_color_get(const struct Scene *scene, struct Brush *brush)
|
||||
{
|
||||
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
|
||||
return (ups->flag & UNIFIED_PAINT_COLOR) ? ups->secondary_rgb : brush->secondary_rgb;
|
||||
}
|
||||
|
||||
void BKE_brush_color_set(struct Scene *scene, struct Brush *brush, const float color[3])
|
||||
{
|
||||
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
|
||||
|
||||
if (ups->flag & UNIFIED_PAINT_COLOR)
|
||||
copy_v3_v3(ups->rgb, color);
|
||||
else
|
||||
copy_v3_v3(brush->rgb, color);
|
||||
}
|
||||
|
||||
void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
|
||||
{
|
||||
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_curve.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
@@ -669,7 +670,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
DMSetDrawOptionsTex drawParams,
|
||||
DMSetDrawOptions drawParamsMapped,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag uvflag)
|
||||
{
|
||||
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
|
||||
MVert *mv = cddm->mvert;
|
||||
@@ -680,6 +681,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
MCol *mcol;
|
||||
int i, orig;
|
||||
int colType, startFace = 0;
|
||||
bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0;
|
||||
|
||||
/* double lookup */
|
||||
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
|
||||
@@ -718,14 +720,35 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
cdDM_update_normals_from_pbvh(dm);
|
||||
|
||||
if (GPU_buffer_legacy(dm)) {
|
||||
int mat_nr_cache = -1;
|
||||
MTFace *tf_base = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
MTFace *tf_stencil_base = NULL;
|
||||
MTFace *tf_stencil = NULL;
|
||||
|
||||
if (uvflag & DM_DRAW_USE_TEXPAINT_UV) {
|
||||
int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
|
||||
tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
|
||||
}
|
||||
|
||||
DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n");
|
||||
for (i = 0; i < dm->numTessFaceData; i++, mf++) {
|
||||
MVert *mvert;
|
||||
DMDrawOption draw_option;
|
||||
unsigned char *cp = NULL;
|
||||
|
||||
if (uvflag & DM_DRAW_USE_TEXPAINT_UV) {
|
||||
if (mf->mat_nr != mat_nr_cache) {
|
||||
tf_base = DM_paint_uvlayer_active_get(dm, mf->mat_nr);
|
||||
|
||||
mat_nr_cache = mf->mat_nr;
|
||||
}
|
||||
}
|
||||
|
||||
tf = tf_base ? tf_base + i : NULL;
|
||||
tf_stencil = tf_stencil_base ? tf_stencil_base + i : NULL;
|
||||
|
||||
if (drawParams) {
|
||||
draw_option = drawParams(tf ? &tf[i] : NULL, (mcol != NULL), mf->mat_nr);
|
||||
draw_option = drawParams(use_tface ? tf : NULL, (mcol != NULL), mf->mat_nr);
|
||||
}
|
||||
else {
|
||||
if (index_mf_to_mpoly) {
|
||||
@@ -778,21 +801,24 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
}
|
||||
|
||||
glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
|
||||
if (tf) glTexCoord2fv(tf[i].uv[0]);
|
||||
if (tf) glTexCoord2fv(tf->uv[0]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[0]);
|
||||
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
|
||||
mvert = &mv[mf->v1];
|
||||
if (lnors) glNormal3sv((const GLshort *)lnors[0][0]);
|
||||
else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
|
||||
glVertex3fv(mvert->co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf[i].uv[1]);
|
||||
if (tf) glTexCoord2fv(tf->uv[1]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[1]);
|
||||
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
|
||||
mvert = &mv[mf->v2];
|
||||
if (lnors) glNormal3sv((const GLshort *)lnors[0][1]);
|
||||
else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
|
||||
glVertex3fv(mvert->co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf[i].uv[2]);
|
||||
if (tf) glTexCoord2fv(tf->uv[2]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[2]);
|
||||
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
|
||||
mvert = &mv[mf->v3];
|
||||
if (lnors) glNormal3sv((const GLshort *)lnors[0][2]);
|
||||
@@ -800,7 +826,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
glVertex3fv(mvert->co);
|
||||
|
||||
if (mf->v4) {
|
||||
if (tf) glTexCoord2fv(tf[i].uv[3]);
|
||||
if (tf) glTexCoord2fv(tf->uv[3]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf->uv[3]);
|
||||
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
|
||||
mvert = &mv[mf->v4];
|
||||
if (lnors) glNormal3sv((const GLshort *)lnors[0][3]);
|
||||
@@ -819,7 +846,10 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
|
||||
GPU_vertex_setup(dm);
|
||||
GPU_normal_setup(dm);
|
||||
GPU_uv_setup(dm);
|
||||
if (uvflag & DM_DRAW_USE_TEXPAINT_UV)
|
||||
GPU_texpaint_uv_setup(dm);
|
||||
else
|
||||
GPU_uv_setup(dm);
|
||||
if (mcol) {
|
||||
GPU_color_setup(dm, colType);
|
||||
}
|
||||
@@ -839,7 +869,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
|
||||
|
||||
if (drawParams) {
|
||||
draw_option = drawParams(tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
|
||||
draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
|
||||
}
|
||||
else {
|
||||
if (index_mf_to_mpoly) {
|
||||
@@ -895,9 +925,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
static void cdDM_drawFacesTex(DerivedMesh *dm,
|
||||
DMSetDrawOptionsTex setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag uvflag)
|
||||
{
|
||||
cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
|
||||
cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, uvflag);
|
||||
}
|
||||
|
||||
static void cdDM_drawMappedFaces(DerivedMesh *dm,
|
||||
@@ -1123,9 +1153,9 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
|
||||
static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
|
||||
DMSetDrawOptions setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag flag)
|
||||
{
|
||||
cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
|
||||
cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
|
||||
}
|
||||
|
||||
static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert,
|
||||
|
||||
@@ -2472,6 +2472,17 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
|
||||
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
|
||||
}
|
||||
|
||||
if (ELEM(idtype, ID_MA, ID_TE)) {
|
||||
const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(sce);
|
||||
for (obt = bmain->object.first; obt; obt = obt->id.next) {
|
||||
if (obt->mode & OB_MODE_TEXTURE_PAINT) {
|
||||
obt->recalc |= OB_RECALC_DATA;
|
||||
BKE_texpaint_slots_refresh_object(obt, new_shading_nodes);
|
||||
lib_id_recalc_data_tag(bmain, &obt->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (idtype == ID_MC) {
|
||||
MovieClip *clip = (MovieClip *) id;
|
||||
|
||||
|
||||
@@ -911,7 +911,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
static void emDM_drawFacesTex(DerivedMesh *dm,
|
||||
DMSetDrawOptionsTex setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag UNUSED(flag))
|
||||
{
|
||||
emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
|
||||
}
|
||||
@@ -919,7 +919,7 @@ static void emDM_drawFacesTex(DerivedMesh *dm,
|
||||
static void emDM_drawMappedFacesTex(DerivedMesh *dm,
|
||||
DMSetDrawOptions setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag UNUSED(flag))
|
||||
{
|
||||
emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,8 @@ static IDType idtypes[] = {
|
||||
{ ID_NT, "NodeTree", "node_groups", IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_OB, "Object", "objects", IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_PA, "ParticleSettings", "particles", 0 },
|
||||
{ ID_PAL, "Palettes", "palettes", IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_PC, "PaintCurve", "paint_curves", IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE },
|
||||
{ ID_SCR, "Screen", "screens", 0 },
|
||||
{ ID_SEQ, "Sequence", "sequences", 0 }, /* not actually ID data */
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
#include "BKE_mask.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_packedFile.h"
|
||||
#include "BKE_speaker.h"
|
||||
@@ -515,6 +516,10 @@ ListBase *which_libbase(Main *mainlib, short type)
|
||||
return &(mainlib->mask);
|
||||
case ID_LS:
|
||||
return &(mainlib->linestyle);
|
||||
case ID_PAL:
|
||||
return &(mainlib->palettes);
|
||||
case ID_PC:
|
||||
return &(mainlib->paintcurves);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -596,6 +601,8 @@ int set_listbasepointers(Main *main, ListBase **lb)
|
||||
lb[a++] = &(main->text);
|
||||
lb[a++] = &(main->sound);
|
||||
lb[a++] = &(main->group);
|
||||
lb[a++] = &(main->palettes);
|
||||
lb[a++] = &(main->paintcurves);
|
||||
lb[a++] = &(main->brush);
|
||||
lb[a++] = &(main->script);
|
||||
lb[a++] = &(main->particle);
|
||||
@@ -731,6 +738,12 @@ static ID *alloc_libblock_notest(short type)
|
||||
case ID_LS:
|
||||
id = MEM_callocN(sizeof(FreestyleLineStyle), "Freestyle Line Style");
|
||||
break;
|
||||
case ID_PAL:
|
||||
id = MEM_callocN(sizeof(Palette), "Palette");
|
||||
break;
|
||||
case ID_PC:
|
||||
id = MEM_callocN(sizeof(PaintCurve), "Paint Curve");
|
||||
break;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
@@ -1007,6 +1020,12 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, bool do_id_user)
|
||||
case ID_LS:
|
||||
BKE_linestyle_free((FreestyleLineStyle *)id);
|
||||
break;
|
||||
case ID_PAL:
|
||||
BKE_palette_free((Palette *)id);
|
||||
break;
|
||||
case ID_PC:
|
||||
BKE_paint_curve_free((PaintCurve *)id);
|
||||
break;
|
||||
}
|
||||
|
||||
/* avoid notifying on removed data */
|
||||
|
||||
@@ -111,6 +111,9 @@ void BKE_material_free_ex(Material *ma, bool do_id_user)
|
||||
MEM_freeN(ma->nodetree);
|
||||
}
|
||||
|
||||
if (ma->texpaintslot)
|
||||
MEM_freeN(ma->texpaintslot);
|
||||
|
||||
if (ma->gpumaterial.first)
|
||||
GPU_material_free(ma);
|
||||
}
|
||||
@@ -269,7 +272,9 @@ Material *localize_material(Material *ma)
|
||||
|
||||
if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
|
||||
if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
|
||||
|
||||
|
||||
if (ma->texpaintslot) man->texpaintslot = MEM_dupallocN(man->texpaintslot);
|
||||
|
||||
man->preview = NULL;
|
||||
|
||||
if (ma->nodetree)
|
||||
@@ -1301,6 +1306,114 @@ bool object_remove_material_slot(Object *ob)
|
||||
return true;
|
||||
}
|
||||
|
||||
void BKE_texpaint_slots_clear(struct Material *ma)
|
||||
{
|
||||
|
||||
if (ma->texpaintslot) {
|
||||
MEM_freeN(ma->texpaintslot);
|
||||
ma->texpaintslot = NULL;
|
||||
}
|
||||
ma->tot_slots = 0;
|
||||
ma->paint_active_slot = 0;
|
||||
ma->paint_clone_slot = 0;
|
||||
}
|
||||
|
||||
|
||||
static bool get_mtex_slot_valid_texpaint(struct MTex *mtex)
|
||||
{
|
||||
return (mtex && (mtex->texco == TEXCO_UV) &&
|
||||
mtex->tex && (mtex->tex->type == TEX_IMAGE) &&
|
||||
mtex->tex->ima);
|
||||
}
|
||||
|
||||
void BKE_texpaint_slot_refresh_cache(Material *ma, bool use_nodes)
|
||||
{
|
||||
MTex **mtex;
|
||||
short count = 0;
|
||||
short index = 0, i;
|
||||
|
||||
if (!ma)
|
||||
return;
|
||||
|
||||
if (ma->texpaintslot) {
|
||||
MEM_freeN(ma->texpaintslot);
|
||||
ma->texpaintslot = NULL;
|
||||
}
|
||||
|
||||
if (use_nodes) {
|
||||
bNode *node, *active_node;
|
||||
|
||||
if (!(ma->use_nodes && ma->nodetree))
|
||||
return;
|
||||
|
||||
for (node = ma->nodetree->nodes.first; node; node = node->next) {
|
||||
if (node->typeinfo->nclass == NODE_CLASS_TEXTURE)
|
||||
count++;
|
||||
}
|
||||
|
||||
ma->tot_slots = count;
|
||||
|
||||
if (count == 0) {
|
||||
ma->paint_active_slot = 0;
|
||||
return;
|
||||
}
|
||||
ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
|
||||
|
||||
active_node = nodeGetActiveTexture(ma->nodetree);
|
||||
|
||||
for (node = ma->nodetree->nodes.first; node; node = node->next) {
|
||||
if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
|
||||
if (active_node == node)
|
||||
ma->paint_active_slot = index;
|
||||
ma->texpaintslot[index++].ima = (Image *)node->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) {
|
||||
if (get_mtex_slot_valid_texpaint(*mtex)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
ma->tot_slots = count;
|
||||
|
||||
if (count == 0) {
|
||||
ma->paint_active_slot = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
|
||||
|
||||
for (mtex = ma->mtex, i = 0; i < MAX_MTEX; i++, mtex++) {
|
||||
if (get_mtex_slot_valid_texpaint(*mtex)) {
|
||||
ma->texpaintslot[index].ima = (*mtex)->tex->ima;
|
||||
BLI_strncpy(ma->texpaintslot[index++].uvname, (*mtex)->uvname, 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ma->paint_active_slot >= count) {
|
||||
ma->paint_active_slot = count - 1;
|
||||
}
|
||||
|
||||
if (ma->paint_clone_slot >= count) {
|
||||
ma->paint_clone_slot = count - 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void BKE_texpaint_slots_refresh_object(struct Object *ob, bool use_nodes)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < ob->totcol + 1; i++) {
|
||||
Material *ma = give_current_material(ob, i);
|
||||
BKE_texpaint_slot_refresh_cache(ma, use_nodes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* r_col = current value, col = new value, (fac == 0) is no change */
|
||||
void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
|
||||
|
||||
@@ -45,8 +45,10 @@
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_crazyspace.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
@@ -269,6 +271,105 @@ void BKE_paint_brush_set(Paint *p, Brush *br)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_paint_curve_free(PaintCurve *pc)
|
||||
{
|
||||
if (pc->points) {
|
||||
MEM_freeN(pc->points);
|
||||
pc->points = NULL;
|
||||
pc->tot_points = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name)
|
||||
{
|
||||
PaintCurve *pc;
|
||||
|
||||
pc = BKE_libblock_alloc(bmain, ID_PC, name);
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
Palette *BKE_paint_palette(Paint *p)
|
||||
{
|
||||
return p ? p->palette : NULL;
|
||||
}
|
||||
|
||||
void BKE_paint_palette_set(Paint *p, Palette *palette)
|
||||
{
|
||||
if (p) {
|
||||
id_us_min((ID *)p->palette);
|
||||
id_us_plus((ID *)palette);
|
||||
p->palette = palette;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_paint_curve_set(Brush *br, PaintCurve *pc)
|
||||
{
|
||||
if (br) {
|
||||
id_us_min((ID *)br->paint_curve);
|
||||
id_us_plus((ID *)pc);
|
||||
br->paint_curve = pc;
|
||||
}
|
||||
}
|
||||
|
||||
/* remove colour from palette. Must be certain color is inside the palette! */
|
||||
void BKE_palette_color_remove(Palette *palette, PaletteColor *color)
|
||||
{
|
||||
BLI_remlink(&palette->colors, color);
|
||||
BLI_addhead(&palette->deleted, color);
|
||||
}
|
||||
|
||||
void BKE_palette_cleanup(Palette *palette)
|
||||
{
|
||||
BLI_freelistN(&palette->deleted);
|
||||
}
|
||||
|
||||
|
||||
Palette *BKE_palette_add(Main *bmain, const char *name)
|
||||
{
|
||||
Palette *palette;
|
||||
|
||||
palette = BKE_libblock_alloc(bmain, ID_PAL, name);
|
||||
|
||||
/* enable fake user by default */
|
||||
palette->id.flag |= LIB_FAKEUSER;
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
void BKE_palette_free(Palette *palette)
|
||||
{
|
||||
BLI_freelistN(&palette->colors);
|
||||
}
|
||||
|
||||
PaletteColor *BKE_palette_color_add(Palette *palette)
|
||||
{
|
||||
PaletteColor *color = MEM_callocN(sizeof(*color), "Pallete Color");
|
||||
BLI_addtail(&palette->colors, color);
|
||||
palette->active_color = BLI_countlist(&palette->colors) - 1;
|
||||
return color;
|
||||
}
|
||||
|
||||
void BKE_palette_color_delete(struct Palette *palette)
|
||||
{
|
||||
PaletteColor *color = BLI_findlink(&palette->colors, palette->active_color);
|
||||
|
||||
if(color) {
|
||||
if ((color == palette->colors.last) && (palette->colors.last != palette->colors.first))
|
||||
palette->active_color--;
|
||||
|
||||
BLI_remlink(&palette->colors, color);
|
||||
BLI_addhead(&palette->deleted, 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)
|
||||
{
|
||||
@@ -318,6 +419,7 @@ void BKE_paint_init(Paint *p, const char col[3])
|
||||
void BKE_paint_free(Paint *paint)
|
||||
{
|
||||
id_us_min((ID *)paint->brush);
|
||||
id_us_min((ID *)paint->palette);
|
||||
}
|
||||
|
||||
/* called when copying scene settings, so even if 'src' and 'tar' are the same
|
||||
@@ -328,6 +430,7 @@ void BKE_paint_copy(Paint *src, Paint *tar)
|
||||
{
|
||||
tar->brush = src->brush;
|
||||
id_us_plus((ID *)tar->brush);
|
||||
id_us_plus((ID *)tar->palette);
|
||||
}
|
||||
|
||||
/* returns non-zero if any of the face's vertices
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
@@ -2291,18 +2292,23 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
DMSetDrawOptionsTex drawParams,
|
||||
DMSetDrawOptions drawParamsMapped,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag flag)
|
||||
{
|
||||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
|
||||
CCGSubSurf *ss = ccgdm->ss;
|
||||
CCGKey key;
|
||||
MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
|
||||
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
MTFace *tf_stencil_base = NULL;
|
||||
MTFace *tf_stencil = NULL;
|
||||
MTFace *tf_base;
|
||||
short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
|
||||
DMFlagMat *faceFlags = ccgdm->faceFlags;
|
||||
DMDrawOption draw_option;
|
||||
int i, totface, gridSize = ccgSubSurf_getGridSize(ss);
|
||||
int gridFaces = gridSize - 1;
|
||||
int gridOffset = 0;
|
||||
int mat_nr_cache = -1;
|
||||
|
||||
(void) compareDrawOptions;
|
||||
|
||||
@@ -2316,6 +2322,12 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
mcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
|
||||
|
||||
totface = ccgSubSurf_getNumFaces(ss);
|
||||
|
||||
if (flag & DM_DRAW_USE_TEXPAINT_UV) {
|
||||
int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
|
||||
tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
|
||||
}
|
||||
|
||||
for (i = 0; i < totface; i++) {
|
||||
CCGFace *f = ccgdm->faceMap[i].face;
|
||||
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
|
||||
@@ -2334,6 +2346,18 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
mat_nr = 0;
|
||||
}
|
||||
|
||||
/* texture painting, handle the correct uv layer here */
|
||||
if (flag & DM_DRAW_USE_TEXPAINT_UV) {
|
||||
if (mat_nr != mat_nr_cache) {
|
||||
tf_base = DM_paint_uvlayer_active_get(dm, mat_nr);
|
||||
|
||||
mat_nr_cache = mat_nr;
|
||||
}
|
||||
tf = tf_base + gridOffset;
|
||||
tf_stencil = tf_stencil_base + gridOffset;
|
||||
gridOffset += gridFaces * gridFaces * numVerts;
|
||||
}
|
||||
|
||||
if (drawParams)
|
||||
draw_option = drawParams(tf, (mcol != NULL), mat_nr);
|
||||
else if (index != ORIGINDEX_NONE)
|
||||
@@ -2374,26 +2398,31 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[1]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]);
|
||||
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
|
||||
glNormal3sv(ln[0][1]);
|
||||
glVertex3fv(d_co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[2]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]);
|
||||
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
|
||||
glNormal3sv(ln[0][2]);
|
||||
glVertex3fv(c_co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[3]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]);
|
||||
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
|
||||
glNormal3sv(ln[0][3]);
|
||||
glVertex3fv(b_co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[0]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]);
|
||||
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glNormal3sv(ln[0][0]);
|
||||
glVertex3fv(a_co);
|
||||
|
||||
if (tf) tf++;
|
||||
if (tf_stencil) tf_stencil++;
|
||||
if (cp) cp += 16;
|
||||
ln++;
|
||||
}
|
||||
@@ -2409,17 +2438,20 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
b = CCG_grid_elem(&key, faceGridData, x, y + 1);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[0]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]);
|
||||
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glNormal3fv(CCG_elem_no(&key, a));
|
||||
glVertex3fv(CCG_elem_co(&key, a));
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[1]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]);
|
||||
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
|
||||
glNormal3fv(CCG_elem_no(&key, b));
|
||||
glVertex3fv(CCG_elem_co(&key, b));
|
||||
|
||||
if (x != gridFaces - 1) {
|
||||
if (tf) tf++;
|
||||
if (tf_stencil) tf_stencil++;
|
||||
if (cp) cp += 16;
|
||||
}
|
||||
}
|
||||
@@ -2428,16 +2460,19 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
b = CCG_grid_elem(&key, faceGridData, x, y + 1);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[3]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]);
|
||||
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
|
||||
glNormal3fv(CCG_elem_no(&key, a));
|
||||
glVertex3fv(CCG_elem_co(&key, a));
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[2]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]);
|
||||
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
|
||||
glNormal3fv(CCG_elem_no(&key, b));
|
||||
glVertex3fv(CCG_elem_co(&key, b));
|
||||
|
||||
if (tf) tf++;
|
||||
if (tf_stencil) tf_stencil++;
|
||||
if (cp) cp += 16;
|
||||
|
||||
glEnd();
|
||||
@@ -2456,22 +2491,27 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[1]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[1]);
|
||||
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
|
||||
glVertex3fv(d_co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[2]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[2]);
|
||||
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
|
||||
glVertex3fv(c_co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[3]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[3]);
|
||||
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
|
||||
glVertex3fv(b_co);
|
||||
|
||||
if (tf) glTexCoord2fv(tf->uv[0]);
|
||||
if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE1, tf_stencil->uv[0]);
|
||||
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
|
||||
glVertex3fv(a_co);
|
||||
|
||||
if (tf) tf++;
|
||||
if (tf_stencil) tf_stencil++;
|
||||
if (cp) cp += 16;
|
||||
}
|
||||
}
|
||||
@@ -2484,17 +2524,17 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
|
||||
static void ccgDM_drawFacesTex(DerivedMesh *dm,
|
||||
DMSetDrawOptionsTex setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag flag)
|
||||
{
|
||||
ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
|
||||
ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag);
|
||||
}
|
||||
|
||||
static void ccgDM_drawMappedFacesTex(DerivedMesh *dm,
|
||||
DMSetDrawOptions setDrawOptions,
|
||||
DMCompareDrawOptions compareDrawOptions,
|
||||
void *userData)
|
||||
void *userData, DMDrawFlag flag)
|
||||
{
|
||||
ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
|
||||
ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
|
||||
}
|
||||
|
||||
static void ccgDM_drawUVEdges(DerivedMesh *dm)
|
||||
|
||||
@@ -474,7 +474,8 @@ void BKE_texture_free(Tex *tex)
|
||||
|
||||
void default_tex(Tex *tex)
|
||||
{
|
||||
tex->type = TEX_CLOUDS;
|
||||
tex->type = TEX_IMAGE;
|
||||
tex->ima = NULL;
|
||||
tex->stype = 0;
|
||||
tex->flag = TEX_CHECKER_ODD;
|
||||
tex->imaflag = TEX_INTERPOL | TEX_MIPMAP | TEX_USEALPHA;
|
||||
@@ -592,7 +593,7 @@ Tex *add_texture(Main *bmain, const char *name)
|
||||
|
||||
void default_mtex(MTex *mtex)
|
||||
{
|
||||
mtex->texco = TEXCO_ORCO;
|
||||
mtex->texco = TEXCO_UV;
|
||||
mtex->mapto = MAP_COL;
|
||||
mtex->object = NULL;
|
||||
mtex->projx = PROJ_X;
|
||||
|
||||
@@ -49,6 +49,24 @@ MINLINE void blend_color_lighten_byte(unsigned char dst[4], const unsigned char
|
||||
MINLINE void blend_color_darken_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]);
|
||||
MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]);
|
||||
MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4]);
|
||||
|
||||
MINLINE void blend_color_overlay_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_hardlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_burn_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_linearburn_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_dodge_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_screen_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_softlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_pinlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_linearlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_vividlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_difference_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_exclusion_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_color_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_hue_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_saturation_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
MINLINE void blend_color_luminosity_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4]);
|
||||
|
||||
MINLINE void blend_color_interpolate_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4], float t);
|
||||
|
||||
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4]);
|
||||
@@ -59,6 +77,24 @@ MINLINE void blend_color_lighten_float(float dst[4], const float src1[4], const
|
||||
MINLINE void blend_color_darken_float(float dst[4], const float src1[4], const float src2[4]);
|
||||
MINLINE void blend_color_erase_alpha_float(float dst[4], const float src1[4], const float src2[4]);
|
||||
MINLINE void blend_color_add_alpha_float(float dst[4], const float src1[4], const float src2[4]);
|
||||
|
||||
MINLINE void blend_color_overlay_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_burn_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_linearburn_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_dodge_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_screen_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_pinlight_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_linearlight_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_vividlight_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_difference_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_exclusion_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_color_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_hue_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_saturation_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
MINLINE void blend_color_luminosity_float(float dst[4], const float src1[4], const float src2[2]);
|
||||
|
||||
MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], const float src2[4], float t);
|
||||
|
||||
#if BLI_MATH_DO_INLINE
|
||||
|
||||
@@ -65,6 +65,7 @@ MINLINE void swap_v4_v4(float a[4], float b[4]);
|
||||
MINLINE void copy_v2_v2_char(char r[2], const char a[2]);
|
||||
MINLINE void copy_v3_v3_char(char r[3], const char a[3]);
|
||||
MINLINE void copy_v4_v4_char(char r[4], const char a[4]);
|
||||
|
||||
/* short */
|
||||
MINLINE void copy_v2_v2_short(short r[2], const short a[2]);
|
||||
MINLINE void copy_v3_v3_short(short r[3], const short a[3]);
|
||||
@@ -231,6 +232,7 @@ MINLINE bool equals_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_R
|
||||
MINLINE bool compare_v2v2(const float a[2], const float b[2], const float limit) ATTR_WARN_UNUSED_RESULT;
|
||||
MINLINE bool compare_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT;
|
||||
MINLINE bool compare_len_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT;
|
||||
MINLINE bool compare_len_squared_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
MINLINE bool compare_v4v4(const float a[4], const float b[4], const float limit) ATTR_WARN_UNUSED_RESULT;
|
||||
MINLINE bool equals_v4v4(const float a[4], const float b[4]) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1824,6 +1824,7 @@ static void lib_link_brush(FileData *fd, Main *main)
|
||||
brush->mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mtex.tex);
|
||||
brush->mask_mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mask_mtex.tex);
|
||||
brush->clone.image = newlibadr_us(fd, brush->id.lib, brush->clone.image);
|
||||
brush->paint_curve = newlibadr_us(fd, brush->id.lib, brush->paint_curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1834,6 +1835,8 @@ static void direct_link_brush(FileData *fd, Brush *brush)
|
||||
|
||||
/* fallof curve */
|
||||
brush->curve = newdataadr(fd, brush->curve);
|
||||
brush->gradient = newdataadr(fd, brush->gradient);
|
||||
|
||||
if (brush->curve)
|
||||
direct_link_curvemapping(fd, brush->curve);
|
||||
else
|
||||
@@ -1843,6 +1846,43 @@ static void direct_link_brush(FileData *fd, Brush *brush)
|
||||
brush->icon_imbuf = NULL;
|
||||
}
|
||||
|
||||
/* ************ READ Palette *************** */
|
||||
static void lib_link_palette(FileData *UNUSED(fd), Main *main)
|
||||
{
|
||||
Palette *palette;
|
||||
|
||||
/* only link ID pointers */
|
||||
for (palette = main->palettes.first; palette; palette = palette->id.next) {
|
||||
if (palette->id.flag & LIB_NEED_LINK) {
|
||||
palette->id.flag -= LIB_NEED_LINK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void direct_link_palette(FileData *fd, Palette *palette)
|
||||
{
|
||||
/* palette itself has been read */
|
||||
link_list(fd, &palette->colors);
|
||||
}
|
||||
|
||||
static void lib_link_paint_curve(FileData *UNUSED(fd), Main *main)
|
||||
{
|
||||
PaintCurve *pc;
|
||||
|
||||
/* only link ID pointers */
|
||||
for (pc = main->paintcurves.first; pc; pc = pc->id.next) {
|
||||
if (pc->id.flag & LIB_NEED_LINK) {
|
||||
pc->id.flag -= LIB_NEED_LINK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void direct_link_paint_curve(FileData *fd, PaintCurve *pc)
|
||||
{
|
||||
pc->points = newdataadr(fd, pc->points);
|
||||
}
|
||||
|
||||
|
||||
static void direct_link_script(FileData *UNUSED(fd), Script *script)
|
||||
{
|
||||
script->id.us = 1;
|
||||
@@ -3516,7 +3556,8 @@ static void direct_link_material(FileData *fd, Material *ma)
|
||||
for (a = 0; a < MAX_MTEX; a++) {
|
||||
ma->mtex[a] = newdataadr(fd, ma->mtex[a]);
|
||||
}
|
||||
|
||||
ma->texpaintslot = NULL;
|
||||
|
||||
ma->ramp_col = newdataadr(fd, ma->ramp_col);
|
||||
ma->ramp_spec = newdataadr(fd, ma->ramp_spec);
|
||||
|
||||
@@ -5059,6 +5100,7 @@ static void link_paint(FileData *fd, Scene *sce, Paint *p)
|
||||
{
|
||||
if (p) {
|
||||
p->brush = newlibadr_us(fd, sce->id.lib, p->brush);
|
||||
p->palette = newlibadr_us(fd, sce->id.lib, p->palette);
|
||||
p->paint_cursor = NULL;
|
||||
}
|
||||
}
|
||||
@@ -5107,6 +5149,10 @@ static void lib_link_scene(FileData *fd, Main *main)
|
||||
sce->toolsettings->sculpt->gravity_object =
|
||||
newlibadr_us(fd, sce->id.lib, sce->toolsettings->sculpt->gravity_object);
|
||||
|
||||
if (sce->toolsettings->imapaint.stencil)
|
||||
sce->toolsettings->imapaint.stencil =
|
||||
newlibadr_us(fd, sce->id.lib, sce->toolsettings->imapaint.stencil);
|
||||
|
||||
sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
|
||||
|
||||
for (base = sce->base.first; base; base = next) {
|
||||
@@ -7138,6 +7184,8 @@ static const char *dataname(short id_code)
|
||||
case ID_NT: return "Data from NT";
|
||||
case ID_BR: return "Data from BR";
|
||||
case ID_PA: return "Data from PA";
|
||||
case ID_PAL: return "Data from PAL";
|
||||
case ID_PC: return "Data from PCRV";
|
||||
case ID_GD: return "Data from GD";
|
||||
case ID_WM: return "Data from WM";
|
||||
case ID_MC: return "Data from MC";
|
||||
@@ -7323,6 +7371,12 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
|
||||
case ID_LS:
|
||||
direct_link_linestyle(fd, (FreestyleLineStyle *)id);
|
||||
break;
|
||||
case ID_PAL:
|
||||
direct_link_palette(fd, (Palette *)id);
|
||||
break;
|
||||
case ID_PC:
|
||||
direct_link_paint_curve(fd, (PaintCurve *)id);
|
||||
break;
|
||||
}
|
||||
|
||||
oldnewmap_free_unused(fd->datamap);
|
||||
@@ -7511,6 +7565,8 @@ static void lib_link_all(FileData *fd, Main *main)
|
||||
lib_link_vfont(fd, main);
|
||||
lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */
|
||||
lib_link_brush(fd, main);
|
||||
lib_link_palette(fd, main);
|
||||
lib_link_paint_curve(fd, main);
|
||||
lib_link_particlesettings(fd, main);
|
||||
lib_link_movieclip(fd, main);
|
||||
lib_link_mask(fd, main);
|
||||
@@ -8050,6 +8106,7 @@ static void expand_brush(FileData *fd, Main *mainvar, Brush *brush)
|
||||
expand_doit(fd, mainvar, brush->mtex.tex);
|
||||
expand_doit(fd, mainvar, brush->mask_mtex.tex);
|
||||
expand_doit(fd, mainvar, brush->clone.image);
|
||||
expand_doit(fd, mainvar, brush->paint_curve);
|
||||
}
|
||||
|
||||
static void expand_material(FileData *fd, Main *mainvar, Material *ma)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
/* allow readfile to use deprecated functionality */
|
||||
#define DNA_DEPRECATED_ALLOW
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_sdna_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
@@ -309,6 +310,13 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
mat->line_col[3] = mat->alpha;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
|
||||
Scene *scene;
|
||||
for (scene = main->scene.first; scene; scene = scene->id.next) {
|
||||
scene->r.preview_start_resolution = 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(main, 271, 2)) {
|
||||
@@ -334,6 +342,20 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(main, 271, 3)) {
|
||||
Scene *sce;
|
||||
Brush *br;
|
||||
|
||||
for (sce = main->scene.first; sce; sce = sce->id.next) {
|
||||
sce->toolsettings->imapaint.slot_xresolution_default = 1024;
|
||||
sce->toolsettings->imapaint.slot_yresolution_default = 1024;
|
||||
}
|
||||
|
||||
for (br = main->brush.first; br; br = br->id.next) {
|
||||
br->fill_threshold = 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
|
||||
Scene *scene;
|
||||
for (scene = main->scene.first; scene; scene = scene->id.next) {
|
||||
|
||||
@@ -2924,6 +2924,38 @@ static void write_brushes(WriteData *wd, ListBase *idbase)
|
||||
|
||||
if (brush->curve)
|
||||
write_curvemapping(wd, brush->curve);
|
||||
if (brush->curve)
|
||||
writestruct(wd, DATA, "ColorBand", 1, brush->gradient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_palettes(WriteData *wd, ListBase *idbase)
|
||||
{
|
||||
Palette *palette;
|
||||
|
||||
for (palette = idbase->first; palette; palette = palette->id.next) {
|
||||
if (palette->id.us > 0 || wd->current) {
|
||||
PaletteColor *color;
|
||||
writestruct(wd, ID_PAL, "Palette", 1, palette);
|
||||
if (palette->id.properties) IDP_WriteProperty(palette->id.properties, wd);
|
||||
|
||||
for (color = palette->colors.first; color; color= color->next)
|
||||
writestruct(wd, DATA, "PaletteColor", 1, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_paintcurves(WriteData *wd, ListBase *idbase)
|
||||
{
|
||||
PaintCurve *pc;
|
||||
|
||||
for (pc = idbase->first; pc; pc = pc->id.next) {
|
||||
if (pc->id.us > 0 || wd->current) {
|
||||
writestruct(wd, ID_PC, "PaintCurve", 1, pc);
|
||||
|
||||
writestruct(wd, DATA, "PaintCurvePoint", pc->tot_points, pc->points);
|
||||
if (pc->id.properties) IDP_WriteProperty(pc->id.properties, wd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3399,6 +3431,8 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
|
||||
write_particlesettings(wd, &mainvar->particle);
|
||||
write_nodetrees(wd, &mainvar->nodetree);
|
||||
write_brushes (wd, &mainvar->brush);
|
||||
write_palettes (wd, &mainvar->palettes);
|
||||
write_paintcurves (wd, &mainvar->paintcurves);
|
||||
write_scripts (wd, &mainvar->script);
|
||||
write_gpencils (wd, &mainvar->gpencil);
|
||||
write_linestyles(wd, &mainvar->linestyle);
|
||||
|
||||
@@ -93,6 +93,8 @@ if(WITH_BLENDER)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/soften.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/subtract.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/texdraw.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/texfill.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/texmask.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/thumb.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/twist.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/vertexdraw.png SRC)
|
||||
|
||||
@@ -77,6 +77,8 @@ sources.extend((
|
||||
os.path.join(env['DATA_SOURCES'], "soften.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "subtract.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "texdraw.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "texfill.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "texmask.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "thumb.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "twist.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "vertexdraw.png.c"),
|
||||
|
||||
@@ -150,6 +150,12 @@ extern char datatoc_subtract_png[];
|
||||
extern int datatoc_texdraw_png_size;
|
||||
extern char datatoc_texdraw_png[];
|
||||
|
||||
extern int datatoc_texfill_png_size;
|
||||
extern char datatoc_texfill_png[];
|
||||
|
||||
extern int datatoc_texmask_png_size;
|
||||
extern char datatoc_texmask_png[];
|
||||
|
||||
extern int datatoc_thumb_png_size;
|
||||
extern char datatoc_thumb_png[];
|
||||
|
||||
|
||||
@@ -69,8 +69,11 @@ void ED_image_point_pos__reverse(struct SpaceImage *sima, struct ARegion *ar, co
|
||||
bool ED_space_image_show_render(struct SpaceImage *sima);
|
||||
bool ED_space_image_show_paint(struct SpaceImage *sima);
|
||||
bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit);
|
||||
bool ED_space_image_show_texpaint(struct SpaceImage *sima, struct Object *ob);
|
||||
bool ED_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit);
|
||||
|
||||
bool ED_space_image_paint_curve(const struct bContext *C);
|
||||
|
||||
bool ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *sima);
|
||||
int ED_space_image_maskedit_poll(struct bContext *C);
|
||||
int ED_space_image_maskedit_mask_poll(struct bContext *C);
|
||||
|
||||
@@ -28,9 +28,11 @@
|
||||
struct bContext;
|
||||
struct RegionView3D;
|
||||
struct wmKeyConfig;
|
||||
struct wmOperator;
|
||||
|
||||
/* paint_ops.c */
|
||||
void ED_operatortypes_paint(void);
|
||||
void ED_operatormacros_paint(void);
|
||||
void ED_keymap_paint(struct wmKeyConfig *keyconf);
|
||||
|
||||
/* paint_undo.c */
|
||||
@@ -41,6 +43,7 @@ enum {
|
||||
|
||||
typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb);
|
||||
typedef void (*UndoFreeCb)(struct ListBase *lb);
|
||||
typedef bool (*UndoCleanupCb)(struct bContext *C, struct ListBase *lb);
|
||||
|
||||
int ED_undo_paint_step(struct bContext *C, int type, int step, const char *name);
|
||||
void ED_undo_paint_step_num(struct bContext *C, int type, int num);
|
||||
@@ -48,7 +51,7 @@ const char *ED_undo_paint_get_name(struct bContext *C, int type, int nr, int *ac
|
||||
void ED_undo_paint_free(void);
|
||||
int ED_undo_paint_valid(int type, const char *name);
|
||||
bool ED_undo_paint_empty(int type);
|
||||
void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free);
|
||||
void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free, UndoCleanupCb cleanup);
|
||||
void ED_undo_paint_push_end(int type);
|
||||
|
||||
/* paint_image.c */
|
||||
@@ -57,5 +60,6 @@ void ED_image_undo_restore(struct bContext *C, struct ListBase *lb);
|
||||
void ED_image_undo_free(struct ListBase *lb);
|
||||
void ED_imapaint_clear_partial_redraw(void);
|
||||
void ED_imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h);
|
||||
void ED_imapaint_bucket_fill(struct bContext *C, float color[3], struct wmOperator *op);
|
||||
|
||||
#endif /* __ED_PAINT_H__ */
|
||||
|
||||
@@ -98,6 +98,7 @@ enum TfmMode {
|
||||
#define CTX_NDOF (1 << 5)
|
||||
#define CTX_MOVIECLIP (1 << 6)
|
||||
#define CTX_MASK (1 << 7)
|
||||
#define CTX_PAINT_CURVE (1 << 8)
|
||||
|
||||
/* Standalone call to get the transformation center corresponding to the current situation
|
||||
* returns 1 if successful, 0 otherwise (usually means there's no selection)
|
||||
|
||||
@@ -84,6 +84,7 @@ typedef struct ViewDepths {
|
||||
|
||||
float *ED_view3d_cursor3d_get(struct Scene *scene, struct View3D *v3d);
|
||||
void ED_view3d_cursor3d_position(struct bContext *C, float fp[3], const int mval[2]);
|
||||
void ED_view3d_cursor3d_update(struct bContext *C, const int mval[2]);
|
||||
|
||||
struct Camera *ED_view3d_camera_data_get(struct View3D *v3d, struct RegionView3D *rv3d);
|
||||
|
||||
|
||||
@@ -976,6 +976,8 @@ DEF_ICON(BRUSH_SNAKE_HOOK)
|
||||
DEF_ICON(BRUSH_SOFTEN)
|
||||
DEF_ICON(BRUSH_SUBTRACT)
|
||||
DEF_ICON(BRUSH_TEXDRAW)
|
||||
DEF_ICON(BRUSH_TEXFILL)
|
||||
DEF_ICON(BRUSH_TEXMASK)
|
||||
DEF_ICON(BRUSH_THUMB)
|
||||
DEF_ICON(BRUSH_ROTATE)
|
||||
DEF_ICON(BRUSH_VERTEXDRAW)
|
||||
|
||||
@@ -75,6 +75,9 @@ struct ImBuf;
|
||||
struct bNodeTree;
|
||||
struct bNode;
|
||||
struct bNodeSocket;
|
||||
struct wmDropBox;
|
||||
struct wmDrag;
|
||||
struct wmEvent;
|
||||
|
||||
typedef struct uiBut uiBut;
|
||||
typedef struct uiBlock uiBlock;
|
||||
@@ -288,6 +291,9 @@ typedef enum {
|
||||
#define UI_GRAD_V_ALT 9
|
||||
#define UI_GRAD_L_ALT 10
|
||||
|
||||
#define UI_PALETTE_COLOR 20
|
||||
#define UI_PALETTE_COLOR_ACTIVE 1
|
||||
|
||||
/* Drawing
|
||||
*
|
||||
* Functions to draw various shapes, taking theme settings into account.
|
||||
@@ -437,6 +443,7 @@ void uiButSetDragValue(uiBut *but);
|
||||
void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale);
|
||||
|
||||
bool UI_but_active_drop_name(struct bContext *C);
|
||||
bool UI_but_active_drop_color(struct bContext *C);
|
||||
|
||||
void uiButSetFlag(uiBut *but, int flag);
|
||||
void uiButClearFlag(uiBut *but, int flag);
|
||||
@@ -847,6 +854,7 @@ void uiTemplateVectorscope(uiLayout *layout, struct PointerRNA *ptr, const char
|
||||
void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int type,
|
||||
int levels, int brush, int neg_slope);
|
||||
void uiTemplateColorPicker(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int value_slider, int lock, int lock_luminosity, int cubic);
|
||||
void uiTemplatePalette(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int color);
|
||||
void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
|
||||
PointerRNA *used_ptr, const char *used_propname, int active_layer);
|
||||
void uiTemplateGameStates(uiLayout *layout, struct PointerRNA *ptr, const char *propname,
|
||||
@@ -916,7 +924,14 @@ void uiItemMenuEnumO(uiLayout *layout, struct bContext *C, const char *opname, c
|
||||
void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon);
|
||||
|
||||
/* UI Operators */
|
||||
typedef struct uiDragColorHandle {
|
||||
float color[3];
|
||||
bool gamma_corrected;
|
||||
} uiDragColorHandle;
|
||||
|
||||
void UI_buttons_operatortypes(void);
|
||||
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
|
||||
int UI_drop_color_poll(struct bContext *C, struct wmDrag *drag, const struct wmEvent *event);
|
||||
|
||||
/* Helpers for Operators */
|
||||
uiBut *uiContextActiveButton(const struct bContext *C);
|
||||
|
||||
@@ -237,6 +237,9 @@ enum {
|
||||
TH_STITCH_PREVIEW_UNSTITCHABLE,
|
||||
TH_STITCH_PREVIEW_ACTIVE,
|
||||
|
||||
TH_PAINT_CURVE_HANDLE,
|
||||
TH_PAINT_CURVE_PIVOT,
|
||||
|
||||
TH_UV_SHADOW,
|
||||
TH_UV_OTHERS,
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_sensor_types.h"
|
||||
#include "DNA_controller_types.h"
|
||||
#include "DNA_actuator_types.h"
|
||||
@@ -60,6 +61,7 @@
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_idprop.h"
|
||||
@@ -1189,7 +1191,7 @@ static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *eve
|
||||
|
||||
BLI_rcti_rctf_copy(&rect, &but->rect);
|
||||
|
||||
if (but->imb) {
|
||||
if (but->imb || but->type == COLOR) {
|
||||
/* use button size itself */
|
||||
}
|
||||
else if (but->drawflag & UI_BUT_ICON_LEFT) {
|
||||
@@ -1242,10 +1244,42 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (but->type == COLOR) {
|
||||
bool valid = false;
|
||||
uiDragColorHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
|
||||
|
||||
/* TODO support more button pointer types */
|
||||
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
|
||||
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, drag_info->color);
|
||||
drag_info->gamma_corrected = true;
|
||||
valid = true;
|
||||
}
|
||||
else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
|
||||
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, drag_info->color);
|
||||
drag_info->gamma_corrected = false;
|
||||
valid = true;
|
||||
}
|
||||
else if (but->pointype == UI_BUT_POIN_FLOAT) {
|
||||
copy_v3_v3(drag_info->color, (float *)but->poin);
|
||||
valid = true;
|
||||
}
|
||||
else if (but->pointype == UI_BUT_POIN_CHAR) {
|
||||
rgba_uchar_to_float(drag_info->color, (unsigned char *)but->poin);
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
WM_event_start_drag(C, ICON_COLOR, WM_DRAG_COLOR, drag_info, 0.0, WM_DRAG_FREE_DATA);
|
||||
}
|
||||
else {
|
||||
MEM_freeN(drag_info);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wmDrag *drag;
|
||||
|
||||
drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but));
|
||||
drag = WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but), WM_DRAG_NOP);
|
||||
if (but->imb)
|
||||
WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect));
|
||||
}
|
||||
@@ -4053,7 +4087,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
|
||||
}
|
||||
}
|
||||
#ifdef USE_DRAG_TOGGLE
|
||||
if (event->type == LEFTMOUSE && ui_is_but_drag_toggle(but)) {
|
||||
if (event->type == LEFTMOUSE && event->val == KM_PRESS && (ui_is_but_drag_toggle(but))) {
|
||||
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
|
||||
data->dragstartx = event->x;
|
||||
data->dragstarty = event->y;
|
||||
@@ -4206,6 +4240,24 @@ static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data,
|
||||
static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
|
||||
{
|
||||
if (data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
/* first handle click on icondrag type button */
|
||||
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
|
||||
if (ui_but_mouse_inside_icon(but, data->region, event)) {
|
||||
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
|
||||
data->dragstartx = event->x;
|
||||
data->dragstarty = event->y;
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
#ifdef USE_DRAG_TOGGLE
|
||||
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
|
||||
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
|
||||
data->dragstartx = event->x;
|
||||
data->dragstarty = event->y;
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
#endif
|
||||
/* regular open menu */
|
||||
if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
|
||||
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
@@ -4233,6 +4285,81 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
|
||||
ui_apply_button(C, but->block, but, data, true);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
else if ((int)(but->a1) == UI_PALETTE_COLOR &&
|
||||
event->type == DELKEY && event->val == KM_PRESS)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Paint *paint = BKE_paint_get_active(scene);
|
||||
Palette *palette = BKE_paint_palette(paint);
|
||||
PaletteColor *color = but->rnapoin.data;
|
||||
|
||||
BKE_palette_color_remove(palette, color);
|
||||
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
else if (data->state == BUTTON_STATE_WAIT_DRAG) {
|
||||
|
||||
/* this function also ends state */
|
||||
if (ui_but_start_drag(C, but, data, event)) {
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
/* outside icon quit, not needed if drag activated */
|
||||
if (0 == ui_but_mouse_inside_icon(but, data->region, event)) {
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
data->cancel = true;
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
|
||||
if ((int)(but->a1) == UI_PALETTE_COLOR) {
|
||||
Palette *palette = but->rnapoin.id.data;
|
||||
PaletteColor *color = but->rnapoin.data;
|
||||
palette->active_color = BLI_findindex(&palette->colors, color);
|
||||
|
||||
if( !event->ctrl) {
|
||||
float color[3];
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Paint *paint = BKE_paint_get_active(scene);
|
||||
Brush *brush = BKE_paint_brush(paint);
|
||||
|
||||
if (brush->flag & BRUSH_USE_GRADIENT) {
|
||||
float *target = &brush->gradient->data[brush->gradient->cur].r;
|
||||
|
||||
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
|
||||
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target);
|
||||
ui_block_to_scene_linear_v3(but->block, target);
|
||||
}
|
||||
else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
|
||||
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
|
||||
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color);
|
||||
BKE_brush_color_set(scene, brush, color);
|
||||
}
|
||||
else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
|
||||
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color);
|
||||
ui_block_to_display_space_v3(but->block, color);
|
||||
BKE_brush_color_set(scene, brush, color);
|
||||
}
|
||||
}
|
||||
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
else {
|
||||
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
|
||||
}
|
||||
}
|
||||
else {
|
||||
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
|
||||
}
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
@@ -6250,7 +6377,7 @@ static bool ui_but_contains_pt(uiBut *but, float mx, float my)
|
||||
return BLI_rctf_isect_pt(&but->rect, mx, my);
|
||||
}
|
||||
|
||||
static uiBut *ui_but_find_activated(ARegion *ar)
|
||||
uiBut *ui_but_find_activated(ARegion *ar)
|
||||
{
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
@@ -6305,6 +6432,17 @@ bool UI_but_active_drop_name(bContext *C)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool UI_but_active_drop_color(bContext *C)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
uiBut *but = ui_but_find_activated(ar);
|
||||
|
||||
if (but && but->type == COLOR)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ui_blocks_set_tooltips(ARegion *ar, const bool enable)
|
||||
{
|
||||
uiBlock *block;
|
||||
|
||||
@@ -508,6 +508,8 @@ static void init_brush_icons(void)
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_SOFTEN, soften);
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_SUBTRACT, subtract);
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_TEXDRAW, texdraw);
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_TEXFILL, texfill);
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_TEXMASK, texmask);
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_THUMB, thumb);
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_ROTATE, twist);
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_VERTEXDRAW, vertexdraw);
|
||||
|
||||
@@ -186,6 +186,7 @@ struct uiBut {
|
||||
* (type == LABEL), Use (a1 == 1.0f) to use a2 as a blending factor (wow, this is imaginative!).
|
||||
* (type == SCROLL) Use as scroll size.
|
||||
* (type == SEARCH_MENU) Use as number or rows.
|
||||
* (type == COLOR) Use as indication of color palette
|
||||
*/
|
||||
float a1;
|
||||
|
||||
@@ -193,6 +194,7 @@ struct uiBut {
|
||||
* (type == NUM), Use to store RNA 'precision' value, for dragging and click-step.
|
||||
* (type == LABEL), If (a1 == 1.0f) use a2 as a blending factor.
|
||||
* (type == SEARCH_MENU) Use as number or columns.
|
||||
* (type == COLOR) Use as indication of active palette color
|
||||
*/
|
||||
float a2;
|
||||
|
||||
@@ -556,6 +558,8 @@ extern void ui_button_active_free(const struct bContext *C, uiBut *but);
|
||||
extern bool ui_button_is_active(struct ARegion *ar) ATTR_WARN_UNUSED_RESULT;
|
||||
extern int ui_button_open_menu_direction(uiBut *but);
|
||||
extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, const bool restore);
|
||||
extern uiBut *ui_but_find_activated(struct ARegion *ar);
|
||||
|
||||
void ui_button_clipboard_free(void);
|
||||
void ui_panel_menu(struct bContext *C, ARegion *ar, Panel *pa);
|
||||
uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "DNA_text_types.h" /* for UI_OT_reports_to_text */
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math_color.h"
|
||||
|
||||
#include "BLF_api.h"
|
||||
#include "BLF_translation.h"
|
||||
@@ -44,6 +45,7 @@
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_text.h" /* for UI_OT_reports_to_text */
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_paint.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
@@ -55,6 +57,8 @@
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_paint.h"
|
||||
|
||||
/* only for UI_OT_editsource */
|
||||
#include "ED_screen.h"
|
||||
#include "BKE_main.h"
|
||||
@@ -810,6 +814,91 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot)
|
||||
ot->exec = reloadtranslation_exec;
|
||||
}
|
||||
|
||||
int UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
|
||||
{
|
||||
/* should only return true for regions that include buttons, for now
|
||||
* return true always */
|
||||
if (drag->type == WM_DRAG_COLOR) {
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
||||
if (UI_but_active_drop_color(C))
|
||||
return 1;
|
||||
|
||||
if (sima && (sima->mode == SI_MODE_PAINT) &&
|
||||
sima->image && (ar && ar->regiontype == RGN_TYPE_WINDOW))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UI_drop_color_copy(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
uiDragColorHandle *drag_info = (uiDragColorHandle *)drag->poin;
|
||||
|
||||
RNA_float_set_array(drop->ptr, "color", drag_info->color);
|
||||
RNA_boolean_set(drop->ptr, "gamma", drag_info->gamma_corrected);
|
||||
}
|
||||
|
||||
static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
uiBut *but = NULL;
|
||||
float color[3];
|
||||
bool gamma;
|
||||
|
||||
RNA_float_get_array(op->ptr, "color", color);
|
||||
gamma = RNA_boolean_get(op->ptr, "gamma");
|
||||
|
||||
/* find button under mouse, check if it has RNA color property and
|
||||
* if it does copy the data */
|
||||
but = ui_but_find_activated(ar);
|
||||
|
||||
if (but && but->type == COLOR && but->rnaprop) {
|
||||
if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
|
||||
if (!gamma)
|
||||
ui_block_to_display_space_v3(but->block, color);
|
||||
RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
|
||||
RNA_property_update(C, &but->rnapoin, but->rnaprop);
|
||||
}
|
||||
else if (RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
|
||||
if (gamma)
|
||||
ui_block_to_scene_linear_v3(but->block, color);
|
||||
RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
|
||||
RNA_property_update(C, &but->rnapoin, but->rnaprop);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (gamma) {
|
||||
srgb_to_linearrgb_v3_v3(color, color);
|
||||
}
|
||||
|
||||
ED_imapaint_bucket_fill(C, color, op);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
||||
static void UI_OT_drop_color(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Drop Color";
|
||||
ot->idname = "UI_OT_drop_color";
|
||||
ot->description = "Drop colors to buttons";
|
||||
|
||||
ot->invoke = drop_color_invoke;
|
||||
|
||||
RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0);
|
||||
RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ********************************************************* */
|
||||
/* Registration */
|
||||
|
||||
@@ -821,7 +910,7 @@ void UI_buttons_operatortypes(void)
|
||||
WM_operatortype_append(UI_OT_unset_property_button);
|
||||
WM_operatortype_append(UI_OT_copy_to_selected_button);
|
||||
WM_operatortype_append(UI_OT_reports_to_textblock); /* XXX: temp? */
|
||||
|
||||
WM_operatortype_append(UI_OT_drop_color);
|
||||
#ifdef WITH_PYTHON
|
||||
WM_operatortype_append(UI_OT_editsource);
|
||||
WM_operatortype_append(UI_OT_edittranslation_init);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_brush_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_string.h"
|
||||
@@ -60,6 +61,7 @@
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_packedFile.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_sca.h"
|
||||
#include "BKE_screen.h"
|
||||
@@ -349,6 +351,8 @@ static const char *template_id_browse_tip(StructRNA *type)
|
||||
case ID_BR: return N_("Browse Brush to be linked");
|
||||
case ID_PA: return N_("Browse Particle Settings to be linked");
|
||||
case ID_GD: return N_("Browse Grease Pencil Data to be linked");
|
||||
case ID_PAL: return N_("Browse Palette Data to be linked");
|
||||
case ID_PC: return N_("Browse Paint Curve Data to be linked");
|
||||
}
|
||||
}
|
||||
return N_("Browse ID data to be linked");
|
||||
@@ -2363,6 +2367,61 @@ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propna
|
||||
}
|
||||
}
|
||||
|
||||
void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname, int UNUSED(colors))
|
||||
{
|
||||
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
||||
PointerRNA cptr;
|
||||
Palette *palette;
|
||||
PaletteColor *color;
|
||||
uiBlock *block;
|
||||
uiLayout *col;
|
||||
int row_cols = 0, col_id = 0;
|
||||
int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1);
|
||||
|
||||
if (!prop) {
|
||||
RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
|
||||
return;
|
||||
}
|
||||
|
||||
cptr = RNA_property_pointer_get(ptr, prop);
|
||||
if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Palette))
|
||||
return;
|
||||
|
||||
block = uiLayoutGetBlock(layout);
|
||||
|
||||
palette = cptr.data;
|
||||
|
||||
/* first delete any pending colors */
|
||||
BKE_palette_cleanup(palette);
|
||||
|
||||
color = palette->colors.first;
|
||||
|
||||
col = uiLayoutColumn(layout, true);
|
||||
uiLayoutRow(col, true);
|
||||
uiDefIconButO(block, BUT, "PALETTE_OT_color_add", WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
|
||||
uiDefIconButO(block, BUT, "PALETTE_OT_color_delete", WM_OP_INVOKE_DEFAULT, ICON_ZOOMOUT, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
|
||||
|
||||
col = uiLayoutColumn(layout, true);
|
||||
uiLayoutRow(col, true);
|
||||
|
||||
for (; color; color = color->next) {
|
||||
PointerRNA ptr;
|
||||
|
||||
if (row_cols >= cols_per_row) {
|
||||
uiLayoutRow(col, true);
|
||||
row_cols = 0;
|
||||
}
|
||||
|
||||
RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &ptr);
|
||||
uiDefButR(block, COLOR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, &ptr, "color", -1, 0.0, 1.0,
|
||||
UI_PALETTE_COLOR, (col_id == palette->active_color) ? UI_PALETTE_COLOR_ACTIVE : 0.0, "");
|
||||
|
||||
row_cols++;
|
||||
col_id++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************* Layer Buttons Template ************************/
|
||||
|
||||
static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
@@ -2825,6 +2826,17 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
|
||||
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
|
||||
if (but->a1 == UI_PALETTE_COLOR && but->a2 == UI_PALETTE_COLOR_ACTIVE) {
|
||||
float width = rect->xmax - rect->xmin;
|
||||
float height = rect->ymax - rect->ymin;
|
||||
|
||||
glColor4ubv((unsigned char *)wcol->outline);
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex2f(rect->xmin + 0.1f * width, rect->ymin + 0.9f * height);
|
||||
glVertex2f(rect->xmin + 0.1f * width, rect->ymin + 0.5f * height);
|
||||
glVertex2f(rect->xmin + 0.5f * width, rect->ymin + 0.9f * height);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
static void widget_normal(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
|
||||
|
||||
@@ -35,21 +35,25 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_mesh_types.h" /* init_userdef_factory */
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
#include "DNA_mesh_types.h" /* init_userdef_factory */
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_library.h"
|
||||
|
||||
|
||||
#include "BIF_gl.h"
|
||||
@@ -537,6 +541,13 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
|
||||
cp = ts->preview_stitch_active;
|
||||
break;
|
||||
|
||||
case TH_PAINT_CURVE_HANDLE:
|
||||
cp = ts->paint_curve_handle;
|
||||
break;
|
||||
case TH_PAINT_CURVE_PIVOT:
|
||||
cp = ts->paint_curve_pivot;
|
||||
break;
|
||||
|
||||
case TH_UV_OTHERS:
|
||||
cp = ts->uv_others;
|
||||
break;
|
||||
@@ -871,6 +882,8 @@ void ui_theme_init_default(void)
|
||||
rgba_char_args_set(btheme->tv3d.title, 0, 0, 0, 255);
|
||||
rgba_char_args_set(btheme->tv3d.freestyle_edge_mark, 0x7f, 0xff, 0x7f, 255);
|
||||
rgba_char_args_set(btheme->tv3d.freestyle_face_mark, 0x7f, 0xff, 0x7f, 51);
|
||||
rgba_char_args_set_fl(btheme->tv3d.paint_curve_handle, 0.5f, 1.0f, 0.5f, 0.5f);
|
||||
rgba_char_args_set_fl(btheme->tv3d.paint_curve_pivot, 1.0f, 0.5f, 0.5f, 0.5f);
|
||||
|
||||
btheme->tv3d.facedot_size = 4;
|
||||
|
||||
@@ -2427,6 +2440,16 @@ void init_userdef_do_versions(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (U.versionfile < 272|| (U.versionfile == 272 && U.subversionfile < 2)) {
|
||||
bTheme *btheme;
|
||||
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
|
||||
rgba_char_args_set_fl(btheme->tv3d.paint_curve_handle, 0.5f, 1.0f, 0.5f, 0.5f);
|
||||
rgba_char_args_set_fl(btheme->tv3d.paint_curve_pivot, 1.0f, 0.5f, 0.5f, 0.5f);
|
||||
rgba_char_args_set_fl(btheme->tima.paint_curve_handle, 0.5f, 1.0f, 0.5f, 0.5f);
|
||||
rgba_char_args_set_fl(btheme->tima.paint_curve_pivot, 1.0f, 0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
bTheme *btheme;
|
||||
for (btheme = U.themes.first; btheme; btheme = btheme->next) {
|
||||
@@ -2470,4 +2493,34 @@ void init_userdef_factory(void)
|
||||
me->flag &= ~ME_TWOSIDED;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Brush *br;
|
||||
br = BKE_brush_add(G.main, "Fill");
|
||||
br->imagepaint_tool = PAINT_TOOL_FILL;
|
||||
br->ob_mode = OB_MODE_TEXTURE_PAINT;
|
||||
|
||||
br = (Brush *)BKE_libblock_find_name(ID_BR, "Mask");
|
||||
if (br) {
|
||||
br->imagepaint_tool = PAINT_TOOL_MASK;
|
||||
br->ob_mode |= OB_MODE_TEXTURE_PAINT;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Scene *scene;
|
||||
|
||||
for (scene = G.main->scene.first; scene; scene = scene->id.next) {
|
||||
if (scene->toolsettings) {
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
|
||||
if (ts->sculpt) {
|
||||
Sculpt *sculpt = ts->sculpt;
|
||||
sculpt->paint.symmetry_flags |= PAINT_SYMM_X;
|
||||
sculpt->flags |= SCULPT_DYNTOPO_COLLAPSE;
|
||||
sculpt->detail_size = 12;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +165,7 @@ void ED_render_engine_changed(Main *bmain)
|
||||
bScreen *sc;
|
||||
ScrArea *sa;
|
||||
Scene *scene;
|
||||
Material *ma;
|
||||
|
||||
for (sc = bmain->screen.first; sc; sc = sc->id.next)
|
||||
for (sa = sc->areabase.first; sa; sa = sa->next)
|
||||
@@ -174,6 +175,11 @@ void ED_render_engine_changed(Main *bmain)
|
||||
|
||||
for (scene = bmain->scene.first; scene; scene = scene->id.next)
|
||||
ED_render_id_flush_update(bmain, &scene->id);
|
||||
|
||||
/* reset texture painting */
|
||||
for (ma = bmain->mat.first; ma; ma = ma->id.next) {
|
||||
BKE_texpaint_slots_clear(ma);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************** Updates ***********************************
|
||||
|
||||
@@ -4154,7 +4154,8 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
|
||||
/* dropbox for entire window */
|
||||
lb = WM_dropboxmap_find("Window", 0, 0);
|
||||
WM_dropbox_add(lb, "WM_OT_open_mainfile", open_file_drop_poll, open_file_drop_copy);
|
||||
|
||||
WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy);
|
||||
|
||||
keymap_modal_set(keyconf);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ set(INC_SYS
|
||||
|
||||
set(SRC
|
||||
paint_cursor.c
|
||||
paint_curve.c
|
||||
paint_hide.c
|
||||
paint_image.c
|
||||
paint_image_2d.c
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_paint.h"
|
||||
@@ -58,6 +59,8 @@
|
||||
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "paint_intern.h"
|
||||
/* still needed for sculpt_stroke_get_location, should be
|
||||
* removed eventually (TODO) */
|
||||
@@ -791,6 +794,138 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
BLI_INLINE void draw_tri_point(float *co, float width, bool selected)
|
||||
{
|
||||
float w = width / 2.0f;
|
||||
if (selected)
|
||||
UI_ThemeColor4(TH_VERTEX_SELECT);
|
||||
else
|
||||
UI_ThemeColor4(TH_PAINT_CURVE_PIVOT);
|
||||
|
||||
glLineWidth(3.0);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(co[0], co[1] + w);
|
||||
glVertex2f(co[0] - w, co[1] - w);
|
||||
glVertex2f(co[0] + w, co[1] - w);
|
||||
glEnd();
|
||||
|
||||
glColor4f(1.0, 1.0, 1.0, 0.5);
|
||||
glLineWidth(1.0);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(co[0], co[1] + w);
|
||||
glVertex2f(co[0] - w, co[1] - w);
|
||||
glVertex2f(co[0] + w, co[1] - w);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
BLI_INLINE void draw_rect_point(float *co, float width, bool selected)
|
||||
{
|
||||
float w = width / 2.0f;
|
||||
if (selected)
|
||||
UI_ThemeColor4(TH_VERTEX_SELECT);
|
||||
else
|
||||
UI_ThemeColor4(TH_PAINT_CURVE_HANDLE);
|
||||
glLineWidth(3.0);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(co[0] + w, co[1] + w);
|
||||
glVertex2f(co[0] - w, co[1] + w);
|
||||
glVertex2f(co[0] - w, co[1] - w);
|
||||
glVertex2f(co[0] + w, co[1] - w);
|
||||
glEnd();
|
||||
|
||||
glColor4f(1.0, 1.0, 1.0, 0.5);
|
||||
glLineWidth(1.0);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2f(co[0] + w, co[1] + w);
|
||||
glVertex2f(co[0] - w, co[1] + w);
|
||||
glVertex2f(co[0] - w, co[1] - w);
|
||||
glVertex2f(co[0] + w, co[1] - w);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
BLI_INLINE void draw_bezier_handle_lines(BezTriple *bez)
|
||||
{
|
||||
short line1[] = {0, 1};
|
||||
short line2[] = {1, 2};
|
||||
|
||||
glVertexPointer(2, GL_FLOAT, 3 * sizeof(float), bez->vec);
|
||||
glColor4f(0.0, 0.0, 0.0, 0.5);
|
||||
glLineWidth(3.0);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, 3);
|
||||
|
||||
glLineWidth(1.0);
|
||||
if (bez->f1 || bez->f2)
|
||||
UI_ThemeColor4(TH_VERTEX_SELECT);
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, 0.5);
|
||||
glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, line1);
|
||||
if (bez->f3 || bez->f2)
|
||||
UI_ThemeColor4(TH_VERTEX_SELECT);
|
||||
else
|
||||
glColor4f(1.0, 1.0, 1.0, 0.5);
|
||||
glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, line2);
|
||||
}
|
||||
|
||||
static void paint_draw_curve_cursor(Brush *brush)
|
||||
{
|
||||
if (brush->paint_curve && brush->paint_curve->points) {
|
||||
int i;
|
||||
PaintCurve *pc = brush->paint_curve;
|
||||
PaintCurvePoint *cp = pc->points;
|
||||
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
/* draw the bezier handles and the curve segment between the current and next point */
|
||||
for (i = 0; i < pc->tot_points - 1; i++, cp++) {
|
||||
int j;
|
||||
PaintCurvePoint *cp_next = cp + 1;
|
||||
float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2];
|
||||
/* use color coding to distinguish handles vs curve segments */
|
||||
draw_bezier_handle_lines(&cp->bez);
|
||||
draw_tri_point(&cp->bez.vec[1][0], 10.0, cp->bez.f2);
|
||||
draw_rect_point(&cp->bez.vec[0][0], 8.0, cp->bez.f1 || cp->bez.f2);
|
||||
draw_rect_point(&cp->bez.vec[2][0], 8.0, cp->bez.f3 || cp->bez.f2);
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
BKE_curve_forward_diff_bezier(
|
||||
cp->bez.vec[1][j],
|
||||
cp->bez.vec[2][j],
|
||||
cp_next->bez.vec[0][j],
|
||||
cp_next->bez.vec[1][j],
|
||||
data + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2]));
|
||||
|
||||
glVertexPointer(2, GL_FLOAT, 0, data);
|
||||
glLineWidth(3.0);
|
||||
glColor4f(0.0, 0.0, 0.0, 0.5);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, PAINT_CURVE_NUM_SEGMENTS + 1);
|
||||
|
||||
glLineWidth(1.0);
|
||||
glColor4f(0.9, 0.9, 1.0, 0.5);
|
||||
glDrawArrays(GL_LINE_STRIP, 0, PAINT_CURVE_NUM_SEGMENTS + 1);
|
||||
}
|
||||
|
||||
/* draw last line segment */
|
||||
draw_bezier_handle_lines(&cp->bez);
|
||||
draw_tri_point(&cp->bez.vec[1][0], 10.0, cp->bez.f2);
|
||||
draw_rect_point(&cp->bez.vec[0][0], 8.0, cp->bez.f1 || cp->bez.f2);
|
||||
draw_rect_point(&cp->bez.vec[2][0], 8.0, cp->bez.f3 || cp->bez.f2);
|
||||
|
||||
glLineWidth(1.0);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
/* Special actions taken when paint cursor goes over mesh */
|
||||
/* TODO: sculpt only for now */
|
||||
static void paint_cursor_on_hit(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc,
|
||||
@@ -848,6 +983,12 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
||||
zoomx = max_ff(zoomx, zoomy);
|
||||
mode = BKE_paintmode_get_active_from_context(C);
|
||||
|
||||
/* skip everything and draw brush here */
|
||||
if (brush->flag & BRUSH_CURVE) {
|
||||
paint_draw_curve_cursor(brush);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set various defaults */
|
||||
translation[0] = x;
|
||||
translation[1] = y;
|
||||
@@ -857,8 +998,11 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
||||
|
||||
/* don't calculate rake angles while a stroke is active because the rake variables are global and
|
||||
* we may get interference with the stroke itself. For line strokes, such interference is visible */
|
||||
if (!ups->stroke_active && (brush->flag & BRUSH_RAKE))
|
||||
paint_calculate_rake_rotation(ups, translation);
|
||||
if (!ups->stroke_active) {
|
||||
if (brush->flag & BRUSH_RAKE)
|
||||
/* here, translation contains the mouse coordinates. */
|
||||
paint_calculate_rake_rotation(ups, translation);
|
||||
}
|
||||
|
||||
/* draw overlay */
|
||||
paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode);
|
||||
@@ -878,7 +1022,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
||||
/* check if brush is subtracting, use different color then */
|
||||
/* TODO: no way currently to know state of pen flip or
|
||||
* invert key modifier without starting a stroke */
|
||||
if ((!(brush->flag & BRUSH_INVERTED) ^
|
||||
if ((!(ups->draw_inverted) ^
|
||||
!(brush->flag & BRUSH_DIR_IN)) &&
|
||||
ELEM(brush->sculpt_tool, SCULPT_TOOL_DRAW,
|
||||
SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY,
|
||||
@@ -890,12 +1034,12 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
||||
/* only do if brush is over the mesh */
|
||||
if (hit)
|
||||
paint_cursor_on_hit(ups, brush, &vc, location);
|
||||
}
|
||||
|
||||
if (ups->draw_anchored) {
|
||||
final_radius = ups->anchored_size;
|
||||
translation[0] = ups->anchored_initial_mouse[0];
|
||||
translation[1] = ups->anchored_initial_mouse[1];
|
||||
}
|
||||
if (ups->draw_anchored) {
|
||||
final_radius = ups->anchored_size;
|
||||
translation[0] = ups->anchored_initial_mouse[0];
|
||||
translation[1] = ups->anchored_initial_mouse[1];
|
||||
}
|
||||
|
||||
/* make lines pretty */
|
||||
|
||||
@@ -0,0 +1,800 @@
|
||||
/*
|
||||
* ***** 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 *****
|
||||
*/
|
||||
|
||||
/** \file blender/editors/sculpt_paint/paint_curve.c
|
||||
* \ingroup edsculpt
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_paint.h"
|
||||
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "ED_paint.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "paint_intern.h"
|
||||
|
||||
#define PAINT_CURVE_SELECT_THRESHOLD 40.0f
|
||||
#define PAINT_CURVE_POINT_SELECT(pcp, i) (*(&pcp->bez.f1 + i) = SELECT)
|
||||
|
||||
|
||||
int paint_curve_poll(bContext *C)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Paint *p;
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
SpaceImage *sima;
|
||||
|
||||
if (rv3d && !(ob && ((ob->mode & OB_MODE_ALL_PAINT) != 0)))
|
||||
return false;
|
||||
|
||||
sima = CTX_wm_space_image(C);
|
||||
|
||||
if (sima && sima->mode != SI_MODE_PAINT)
|
||||
return false;
|
||||
|
||||
p = BKE_paint_get_active_from_context(C);
|
||||
|
||||
if (p && p->brush && (p->brush->flag & BRUSH_CURVE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Paint Curve Undo*/
|
||||
|
||||
typedef struct UndoCurve {
|
||||
struct UndoImageTile *next, *prev;
|
||||
|
||||
PaintCurvePoint *points; /* points of curve */
|
||||
int tot_points;
|
||||
int active_point;
|
||||
|
||||
char idname[MAX_ID_NAME]; /* name instead of pointer*/
|
||||
} UndoCurve;
|
||||
|
||||
static void paintcurve_undo_restore(bContext *C, ListBase *lb)
|
||||
{
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
UndoCurve *uc;
|
||||
PaintCurve *pc;
|
||||
|
||||
if (p->brush) {
|
||||
pc = p->brush->paint_curve;
|
||||
}
|
||||
|
||||
if (!pc)
|
||||
return;
|
||||
|
||||
uc = (UndoCurve *)lb->first;
|
||||
|
||||
if (strncmp(uc->idname, pc->id.name, BLI_strnlen(uc->idname, sizeof(uc->idname))) == 0) {
|
||||
SWAP(PaintCurvePoint *, pc->points, uc->points);
|
||||
SWAP(int, pc->tot_points, uc->tot_points);
|
||||
SWAP(int, pc->add_index, uc->active_point);
|
||||
}
|
||||
}
|
||||
|
||||
static void paintcurve_undo_delete(ListBase *lb)
|
||||
{
|
||||
UndoCurve *uc;
|
||||
uc = (UndoCurve *)lb->first;
|
||||
|
||||
if (uc->points)
|
||||
MEM_freeN(uc->points);
|
||||
uc->points = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void paintcurve_undo_begin(bContext *C, wmOperator *op, PaintCurve *pc)
|
||||
{
|
||||
PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
ListBase *lb = NULL;
|
||||
int undo_stack_id;
|
||||
UndoCurve *uc;
|
||||
|
||||
switch (mode) {
|
||||
case PAINT_TEXTURE_2D:
|
||||
case PAINT_TEXTURE_PROJECTIVE:
|
||||
undo_stack_id = UNDO_PAINT_IMAGE;
|
||||
break;
|
||||
|
||||
case PAINT_SCULPT:
|
||||
undo_stack_id = UNDO_PAINT_MESH;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* do nothing, undo is handled by global */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ED_undo_paint_push_begin(undo_stack_id, op->type->name,
|
||||
paintcurve_undo_restore, paintcurve_undo_delete, NULL);
|
||||
lb = undo_paint_push_get_list(undo_stack_id);
|
||||
|
||||
uc = MEM_callocN(sizeof(*uc), "Undo_curve");
|
||||
|
||||
lb->first = uc;
|
||||
|
||||
BLI_strncpy(uc->idname, pc->id.name, sizeof(uc->idname));
|
||||
uc->tot_points = pc->tot_points;
|
||||
uc->active_point = pc->add_index;
|
||||
uc->points = MEM_dupallocN(pc->points);
|
||||
|
||||
undo_paint_push_count_alloc(undo_stack_id, sizeof(*uc) + sizeof(*pc->points) * pc->tot_points);
|
||||
|
||||
ED_undo_paint_push_end(undo_stack_id);
|
||||
}
|
||||
#define SEL_F1 (1 << 0)
|
||||
#define SEL_F2 (1 << 1)
|
||||
#define SEL_F3 (1 << 2)
|
||||
|
||||
/* returns 0, 1, or 2 in point according to handle 1, pivot or handle 2 */
|
||||
static PaintCurvePoint *paintcurve_point_get_closest(PaintCurve *pc, const float pos[2], bool ignore_pivot, const float threshold, char *point)
|
||||
{
|
||||
PaintCurvePoint *pcp, *closest = NULL;
|
||||
int i;
|
||||
float dist, closest_dist = FLT_MAX;
|
||||
|
||||
for (i = 0, pcp = pc->points; i < pc->tot_points; i++, pcp++) {
|
||||
dist = len_manhattan_v2v2(pos, pcp->bez.vec[0]);
|
||||
if (dist < threshold) {
|
||||
if (dist < closest_dist) {
|
||||
closest = pcp;
|
||||
closest_dist = dist;
|
||||
if (point)
|
||||
*point = SEL_F1;
|
||||
}
|
||||
}
|
||||
if (!ignore_pivot) {
|
||||
dist = len_manhattan_v2v2(pos, pcp->bez.vec[1]);
|
||||
if (dist < threshold) {
|
||||
if (dist < closest_dist) {
|
||||
closest = pcp;
|
||||
closest_dist = dist;
|
||||
if (point)
|
||||
*point = SEL_F2;
|
||||
}
|
||||
}
|
||||
}
|
||||
dist = len_manhattan_v2v2(pos, pcp->bez.vec[2]);
|
||||
if (dist < threshold) {
|
||||
if (dist < closest_dist) {
|
||||
closest = pcp;
|
||||
closest_dist = dist;
|
||||
if (point)
|
||||
*point = SEL_F3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
static int paintcurve_point_co_index(char sel)
|
||||
{
|
||||
char i = 0;
|
||||
while (sel != 1) {
|
||||
sel >>= 1;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/******************* Operators *********************************/
|
||||
|
||||
static int paintcurve_new_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
||||
if (p && p->brush) {
|
||||
p->brush->paint_curve = BKE_paint_curve_add(bmain, "PaintCurve");
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void PAINTCURVE_OT_new(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add New Paint Curve";
|
||||
ot->description = "Add new paint curve";
|
||||
ot->idname = "PAINTCURVE_OT_new";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = paintcurve_new_exec;
|
||||
ot->poll = paint_curve_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2])
|
||||
{
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
Brush *br = p->brush;
|
||||
Main *bmain = CTX_data_main(C);
|
||||
PaintCurve *pc;
|
||||
PaintCurvePoint *pcp;
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
float vec[3] = {loc[0], loc[1], 0.0};
|
||||
int add_index;
|
||||
int i;
|
||||
|
||||
pc = br->paint_curve;
|
||||
if (!pc) {
|
||||
br->paint_curve = pc = BKE_paint_curve_add(bmain, "PaintCurve");
|
||||
}
|
||||
|
||||
paintcurve_undo_begin(C, op, pc);
|
||||
|
||||
pcp = MEM_mallocN((pc->tot_points + 1) * sizeof(PaintCurvePoint), "PaintCurvePoint");
|
||||
add_index = pc->add_index;
|
||||
|
||||
if (pc->points) {
|
||||
if (add_index > 0)
|
||||
memcpy(pcp, pc->points, add_index * sizeof(PaintCurvePoint));
|
||||
if (add_index < pc->tot_points)
|
||||
memcpy(pcp + add_index + 1, pc->points + add_index, (pc->tot_points - add_index) * sizeof(PaintCurvePoint));
|
||||
|
||||
MEM_freeN(pc->points);
|
||||
}
|
||||
pc->points = pcp;
|
||||
pc->tot_points++;
|
||||
|
||||
/* initialize new point */
|
||||
memset(&pcp[add_index], 0, sizeof(PaintCurvePoint));
|
||||
copy_v3_v3(pcp[add_index].bez.vec[0], vec);
|
||||
copy_v3_v3(pcp[add_index].bez.vec[1], vec);
|
||||
copy_v3_v3(pcp[add_index].bez.vec[2], vec);
|
||||
|
||||
/* last step, clear selection from all bezier handles expect the next */
|
||||
for (i = 0; i < pc->tot_points; i++) {
|
||||
pcp[i].bez.f1 = pcp[i].bez.f2 = pcp[i].bez.f3 = 0;
|
||||
}
|
||||
pcp[add_index].bez.f3 = SELECT;
|
||||
pcp[add_index].bez.h2 = HD_ALIGN;
|
||||
|
||||
pc->add_index = add_index + 1;
|
||||
|
||||
WM_paint_cursor_tag_redraw(window, ar);
|
||||
}
|
||||
|
||||
|
||||
static int paintcurve_add_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
int loc[2] = {event->mval[0], event->mval[1]};
|
||||
paintcurve_point_add(C, op, loc);
|
||||
RNA_int_set_array(op->ptr, "location", loc);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int paintcurve_add_point_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
int loc[2];
|
||||
|
||||
if (RNA_struct_property_is_set(op->ptr, "location")) {
|
||||
RNA_int_get_array(op->ptr, "location", loc);
|
||||
paintcurve_point_add(C, op, loc);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
void PAINTCURVE_OT_add_point(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add New Paint Curve Point";
|
||||
ot->description = "Add new paint curve point";
|
||||
ot->idname = "PAINTCURVE_OT_add_point";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = paintcurve_add_point_invoke;
|
||||
ot->exec = paintcurve_add_point_exec;
|
||||
ot->poll = paint_curve_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
|
||||
|
||||
/* properties */
|
||||
RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, SHRT_MAX,
|
||||
"Location", "Location of vertex in area space", 0, SHRT_MAX);
|
||||
}
|
||||
|
||||
static int paintcurve_delete_point_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
Brush *br = p->brush;
|
||||
PaintCurve *pc;
|
||||
PaintCurvePoint *pcp;
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
int i;
|
||||
int tot_del = 0;
|
||||
pc = br->paint_curve;
|
||||
|
||||
if (!pc || pc->tot_points == 0) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
paintcurve_undo_begin(C, op, pc);
|
||||
|
||||
#define DELETE_TAG 2
|
||||
|
||||
for (i = 0, pcp = pc->points; i < pc->tot_points; i++, pcp++) {
|
||||
if ((pcp->bez.f1 & SELECT) || (pcp->bez.f2 & SELECT) || (pcp->bez.f3 & SELECT)) {
|
||||
pcp->bez.f2 |= DELETE_TAG;
|
||||
tot_del++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tot_del > 0) {
|
||||
int j = 0;
|
||||
int new_tot = pc->tot_points - tot_del;
|
||||
PaintCurvePoint *points_new = NULL;
|
||||
if (new_tot > 0)
|
||||
points_new = MEM_mallocN(new_tot * sizeof(PaintCurvePoint), "PaintCurvePoint");
|
||||
|
||||
for (i = 0, pcp = pc->points; i < pc->tot_points; i++, pcp++) {
|
||||
if (!(pcp->bez.f2 & DELETE_TAG)) {
|
||||
points_new[j] = pc->points[i];
|
||||
|
||||
if ((i + 1) == pc->add_index) {
|
||||
pc->add_index = j + 1;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
else if ((i + 1) == pc->add_index) {
|
||||
/* prefer previous point */
|
||||
pc->add_index = j;
|
||||
}
|
||||
}
|
||||
MEM_freeN(pc->points);
|
||||
|
||||
pc->points = points_new;
|
||||
pc->tot_points = new_tot;
|
||||
}
|
||||
|
||||
#undef DELETE_TAG
|
||||
|
||||
WM_paint_cursor_tag_redraw(window, ar);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
||||
void PAINTCURVE_OT_delete_point(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add New Paint Curve Point";
|
||||
ot->description = "Add new paint curve point";
|
||||
ot->idname = "PAINTCURVE_OT_delete_point";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = paintcurve_delete_point_exec;
|
||||
ot->poll = paint_curve_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
|
||||
static bool paintcurve_point_select(bContext *C, wmOperator *op, const int loc[2], bool toggle, bool extend)
|
||||
{
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
Brush *br = p->brush;
|
||||
PaintCurve *pc;
|
||||
PaintCurvePoint *pcp;
|
||||
int i;
|
||||
const float loc_fl[2] = {UNPACK2(loc)};
|
||||
|
||||
pc = br->paint_curve;
|
||||
|
||||
if (!pc)
|
||||
return false;
|
||||
|
||||
paintcurve_undo_begin(C, op, pc);
|
||||
|
||||
pcp = pc->points;
|
||||
|
||||
if (toggle) {
|
||||
char select = 0;
|
||||
bool selected = false;
|
||||
|
||||
for (i = 0; i < pc->tot_points; i++) {
|
||||
if (pcp[i].bez.f1 || pcp[i].bez.f2 || pcp[i].bez.f3) {
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!selected) {
|
||||
select = SELECT;
|
||||
}
|
||||
|
||||
for (i = 0; i < pc->tot_points; i++) {
|
||||
pc->points[i].bez.f1 = pc->points[i].bez.f2 = pc->points[i].bez.f3 = select;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PaintCurvePoint *pcp;
|
||||
char selflag;
|
||||
|
||||
pcp = paintcurve_point_get_closest(pc, loc_fl, false, PAINT_CURVE_SELECT_THRESHOLD, &selflag);
|
||||
|
||||
if (pcp) {
|
||||
pc->add_index = (pcp - pc->points) + 1;
|
||||
|
||||
if (selflag == SEL_F2) {
|
||||
if (extend)
|
||||
pcp->bez.f2 ^= SELECT;
|
||||
else
|
||||
pcp->bez.f2 |= SELECT;
|
||||
}
|
||||
else if (selflag == SEL_F1) {
|
||||
if (extend)
|
||||
pcp->bez.f1 ^= SELECT;
|
||||
else
|
||||
pcp->bez.f1 |= SELECT;
|
||||
}
|
||||
else if (selflag == SEL_F3) {
|
||||
if (extend)
|
||||
pcp->bez.f3 ^= SELECT;
|
||||
else
|
||||
pcp->bez.f3 |= SELECT;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear selection for unselected points if not extending and if a point has been selected */
|
||||
if (!extend && pcp) {
|
||||
for (i = 0; i < pc->tot_points; i++) {
|
||||
pc->points[i].bez.f1 = pc->points[i].bez.f2 = pc->points[i].bez.f3 = 0;
|
||||
|
||||
if ((pc->points + i) == pcp) {
|
||||
char index = paintcurve_point_co_index(selflag);
|
||||
PAINT_CURVE_POINT_SELECT(pcp, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pcp)
|
||||
return false;
|
||||
}
|
||||
|
||||
WM_paint_cursor_tag_redraw(window, ar);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int paintcurve_select_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
int loc[2] = {UNPACK2(event->mval)};
|
||||
bool toggle = RNA_boolean_get(op->ptr, "toggle");
|
||||
bool extend = RNA_boolean_get(op->ptr, "extend");
|
||||
if (paintcurve_point_select(C, op, loc, toggle, extend)) {
|
||||
RNA_int_set_array(op->ptr, "location", loc);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
static int paintcurve_select_point_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
int loc[2];
|
||||
|
||||
if (RNA_struct_property_is_set(op->ptr, "location")) {
|
||||
bool toggle = RNA_boolean_get(op->ptr, "toggle");
|
||||
bool extend = RNA_boolean_get(op->ptr, "extend");
|
||||
RNA_int_get_array(op->ptr, "location", loc);
|
||||
if (paintcurve_point_select(C, op, loc, toggle, extend))
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
void PAINTCURVE_OT_select(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Select Paint Curve Point";
|
||||
ot->description = "Select a paint curve point";
|
||||
ot->idname = "PAINTCURVE_OT_select";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = paintcurve_select_point_invoke;
|
||||
ot->exec = paintcurve_select_point_exec;
|
||||
ot->poll = paint_curve_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;
|
||||
|
||||
/* properties */
|
||||
RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, SHRT_MAX,
|
||||
"Location", "Location of vertex in area space", 0, SHRT_MAX);
|
||||
prop = RNA_def_boolean(ot->srna, "toggle", false, "Toggle", "Select/Deselect all");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
typedef struct PointSlideData {
|
||||
PaintCurvePoint *pcp;
|
||||
char select;
|
||||
int initial_loc[2];
|
||||
float point_initial_loc[3][2];
|
||||
int event;
|
||||
bool align;
|
||||
} PointSlideData;
|
||||
|
||||
static int paintcurve_slide_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
const float loc_fl[2] = {UNPACK2(event->mval)};
|
||||
char select;
|
||||
int i;
|
||||
bool do_select = RNA_boolean_get(op->ptr, "select");
|
||||
bool align = RNA_boolean_get(op->ptr, "align");
|
||||
Brush *br = p->brush;
|
||||
PaintCurve *pc = br->paint_curve;
|
||||
PaintCurvePoint *pcp;
|
||||
|
||||
if (!pc)
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
|
||||
if (do_select) {
|
||||
pcp = paintcurve_point_get_closest(pc, loc_fl, align, PAINT_CURVE_SELECT_THRESHOLD, &select);
|
||||
}
|
||||
else {
|
||||
/* just find first selected point */
|
||||
for (i = 0; i < pc->tot_points; i++) {
|
||||
if (pc->points[i].bez.f1 || pc->points[i].bez.f2 || pc->points[i].bez.f3) {
|
||||
pcp = &pc->points[i];
|
||||
select = SEL_F3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (pcp) {
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
PointSlideData *psd = MEM_mallocN(sizeof(PointSlideData), "PointSlideData");
|
||||
copy_v2_v2_int(psd->initial_loc, event->mval);
|
||||
psd->event = event->type;
|
||||
psd->pcp = pcp;
|
||||
psd->select = paintcurve_point_co_index(select);
|
||||
for (i = 0; i < 3; i++) {
|
||||
copy_v2_v2(psd->point_initial_loc[i], pcp->bez.vec[i]);
|
||||
}
|
||||
psd->align = align;
|
||||
op->customdata = psd;
|
||||
|
||||
if (do_select)
|
||||
paintcurve_undo_begin(C, op, pc);
|
||||
|
||||
/* first, clear all selection from points */
|
||||
for (i = 0; i < pc->tot_points; i++)
|
||||
pc->points[i].bez.f1 = pc->points[i].bez.f3 = pc->points[i].bez.f2 = 0;
|
||||
|
||||
/* only select the active point */
|
||||
PAINT_CURVE_POINT_SELECT(pcp, psd->select);
|
||||
pc->add_index = (pcp - pc->points) + 1;
|
||||
|
||||
WM_event_add_modal_handler(C, op);
|
||||
WM_paint_cursor_tag_redraw(window, ar);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
static int paintcurve_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
PointSlideData *psd = op->customdata;
|
||||
|
||||
if (event->type == psd->event && event->val == KM_RELEASE) {
|
||||
MEM_freeN(psd);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
switch (event->type) {
|
||||
case MOUSEMOVE:
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
float diff[2] = {event->mval[0] - psd->initial_loc[0],
|
||||
event->mval[1] - psd->initial_loc[1]};
|
||||
if (psd->select == 1) {
|
||||
int i;
|
||||
for (i = 0; i < 3; i++)
|
||||
add_v2_v2v2(psd->pcp->bez.vec[i], diff, psd->point_initial_loc[i]);
|
||||
}
|
||||
else {
|
||||
add_v2_v2(diff, psd->point_initial_loc[psd->select]);
|
||||
copy_v2_v2(psd->pcp->bez.vec[psd->select], diff);
|
||||
|
||||
if (psd->align) {
|
||||
char opposite = (psd->select == 0) ? 2 : 0;
|
||||
sub_v2_v2v2(diff, psd->pcp->bez.vec[1], psd->pcp->bez.vec[psd->select]);
|
||||
add_v2_v2v2(psd->pcp->bez.vec[opposite], psd->pcp->bez.vec[1], diff);
|
||||
}
|
||||
}
|
||||
WM_paint_cursor_tag_redraw(window, ar);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
|
||||
void PAINTCURVE_OT_slide(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Slide Paint Curve Point";
|
||||
ot->description = "Select and slide paint curve point";
|
||||
ot->idname = "PAINTCURVE_OT_slide";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = paintcurve_slide_invoke;
|
||||
ot->modal = paintcurve_slide_modal;
|
||||
ot->poll = paint_curve_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_boolean(ot->srna, "align", false, "Align Handles", "Aligns opposite point handle during transform");
|
||||
RNA_def_boolean(ot->srna, "select", true, "Select", "Attempt to select a point handle before transform");
|
||||
}
|
||||
|
||||
static int paintcurve_draw_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
const char *name;
|
||||
|
||||
switch (mode) {
|
||||
case PAINT_TEXTURE_2D:
|
||||
case PAINT_TEXTURE_PROJECTIVE:
|
||||
name = "PAINT_OT_image_paint";
|
||||
break;
|
||||
case PAINT_WEIGHT:
|
||||
name = "PAINT_OT_weight_paint";
|
||||
break;
|
||||
case PAINT_VERTEX:
|
||||
name = "PAINT_OT_vertex_paint";
|
||||
break;
|
||||
case PAINT_SCULPT:
|
||||
name = "SCULPT_OT_brush_stroke";
|
||||
break;
|
||||
default:
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
return WM_operator_name_call(C, name, WM_OP_INVOKE_DEFAULT, NULL);
|
||||
}
|
||||
|
||||
void PAINTCURVE_OT_draw(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Draw Curve";
|
||||
ot->description = "Draw curve";
|
||||
ot->idname = "PAINTCURVE_OT_draw";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = paintcurve_draw_exec;
|
||||
ot->poll = paint_curve_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int paintcurve_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
op->customdata = SET_INT_IN_POINTER(event->type);
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int paintcurve_cursor_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
if (event->type == GET_INT_FROM_POINTER(op->customdata) && event->val == KM_RELEASE)
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
if (event->type == MOUSEMOVE) {
|
||||
PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
|
||||
switch (mode) {
|
||||
case PAINT_TEXTURE_2D:
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
float location[2];
|
||||
|
||||
if (!sima)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
|
||||
copy_v2_v2(sima->cursor, location);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ED_view3d_cursor3d_update(C, event->mval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
void PAINTCURVE_OT_cursor(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Place Cursor";
|
||||
ot->description = "Place cursor";
|
||||
ot->idname = "PAINTCURVE_OT_cursor";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = paintcurve_cursor_invoke;
|
||||
ot->modal = paintcurve_cursor_modal;
|
||||
ot->poll = paint_curve_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,9 @@ struct bglMats;
|
||||
struct Brush;
|
||||
struct ImagePool;
|
||||
struct ColorSpace;
|
||||
struct ColorManagedDisplay;
|
||||
struct ListBase;
|
||||
struct Material;
|
||||
struct Mesh;
|
||||
struct MTex;
|
||||
struct Object;
|
||||
@@ -65,7 +67,7 @@ typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke,
|
||||
typedef void (*StrokeRedraw)(const struct bContext *C, struct PaintStroke *stroke, bool final);
|
||||
typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke);
|
||||
|
||||
struct PaintStroke *paint_stroke_new(struct bContext *C,
|
||||
struct PaintStroke *paint_stroke_new(struct bContext *C, struct wmOperator *op,
|
||||
StrokeGetLocation get_location, StrokeTestStart test_start,
|
||||
StrokeUpdateStep update_step, StrokeRedraw redraw,
|
||||
StrokeDone done, int event_type);
|
||||
@@ -84,6 +86,7 @@ int paint_stroke_exec(struct bContext *C, struct wmOperator *op);
|
||||
void paint_stroke_cancel(struct bContext *C, struct wmOperator *op);
|
||||
struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
|
||||
void *paint_stroke_mode_data(struct PaintStroke *stroke);
|
||||
float paint_stroke_distance_get(struct PaintStroke *stroke);
|
||||
void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data);
|
||||
int paint_poll(struct bContext *C);
|
||||
void paint_cursor_start(struct bContext *C, int (*poll)(struct bContext *C));
|
||||
@@ -117,7 +120,7 @@ void PAINT_OT_weight_gradient(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vertex_paint_toggle(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
|
||||
|
||||
unsigned int vpaint_get_current_col(struct VPaint *vp);
|
||||
unsigned int vpaint_get_current_col(struct Scene *scene, struct VPaint *vp);
|
||||
|
||||
|
||||
/* paint_vertex_proj.c */
|
||||
@@ -144,32 +147,42 @@ typedef struct ImagePaintPartialRedraw {
|
||||
#define IMAPAINT_TILE_NUMBER(size) (((size) + IMAPAINT_TILE_SIZE - 1) >> IMAPAINT_TILE_BITS)
|
||||
|
||||
int image_texture_paint_poll(struct bContext *C);
|
||||
void *image_undo_find_tile(struct Image *ima, struct ImBuf *ibuf, int x_tile, int y_tile, unsigned short **mask);
|
||||
void *image_undo_push_tile(struct Image *ima, struct ImBuf *ibuf, struct ImBuf **tmpibuf, int x_tile, int y_tile);
|
||||
void *image_undo_find_tile(struct Image *ima, struct ImBuf *ibuf, int x_tile, int y_tile, unsigned short **mask, bool validate);
|
||||
void *image_undo_push_tile(struct Image *ima, struct ImBuf *ibuf, struct ImBuf **tmpibuf, int x_tile, int y_tile, unsigned short **, bool **valid, bool proj);
|
||||
void image_undo_remove_masks(void);
|
||||
void image_undo_init_locks(void);
|
||||
void image_undo_end_locks(void);
|
||||
|
||||
void imapaint_image_update(struct SpaceImage *sima, struct Image *image, struct ImBuf *ibuf, short texpaint);
|
||||
struct ImagePaintPartialRedraw *get_imapaintpartial(void);
|
||||
void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr);
|
||||
void imapaint_region_tiles(struct ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th);
|
||||
int get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy);
|
||||
void *paint_2d_new_stroke(struct bContext *, struct wmOperator *);
|
||||
void *paint_2d_new_stroke(struct bContext *, struct wmOperator *, int mode);
|
||||
void paint_2d_redraw(const bContext *C, void *ps, bool final);
|
||||
void paint_2d_stroke_done(void *ps);
|
||||
void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], int eraser);
|
||||
void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], int eraser, float pressure, float distance, float size);
|
||||
void paint_2d_bucket_fill(const struct bContext *C, const float color[3], struct Brush *br, const float mouse_init[2], void *ps);
|
||||
void paint_2d_gradient_fill (const struct bContext *C, struct Brush *br, const float mouse_init[2], const float mouse_final[2], void *ps);
|
||||
void *paint_proj_new_stroke(struct bContext *C, struct Object *ob, const float mouse[2], int mode);
|
||||
void paint_proj_stroke(struct bContext *C, void *ps, const float prevmval_i[2], const float mval_i[2]);
|
||||
void paint_proj_redraw(const bContext *C, void *pps, bool final);
|
||||
void paint_proj_stroke(const struct bContext *C, void *ps, const float prevmval_i[2], const float mval_i[2], float pressure, float distance, float size);
|
||||
void paint_proj_redraw(const struct bContext *C, void *pps, bool final);
|
||||
void paint_proj_stroke_done(void *ps);
|
||||
void paint_proj_mesh_data_ensure(bContext *C, struct Object *ob, struct wmOperator *op);
|
||||
bool proj_paint_add_slot(bContext *C, int type, struct Material *ma);
|
||||
|
||||
void paint_brush_color_get(struct Scene *scene, struct Brush *br, bool color_correction, bool invert, float distance, float pressure, float color[3], struct ColorManagedDisplay *display);
|
||||
bool paint_use_opacity_masking(struct Brush *brush);
|
||||
void paint_brush_init_tex(struct Brush *brush);
|
||||
void paint_brush_exit_tex(struct Brush *brush);
|
||||
|
||||
void PAINT_OT_grab_clone(struct wmOperatorType *ot);
|
||||
void PAINT_OT_sample_color(struct wmOperatorType *ot);
|
||||
void PAINT_OT_brush_colors_flip(struct wmOperatorType *ot);
|
||||
void PAINT_OT_texture_paint_toggle(struct wmOperatorType *ot);
|
||||
void PAINT_OT_project_image(struct wmOperatorType *ot);
|
||||
void PAINT_OT_image_from_view(struct wmOperatorType *ot);
|
||||
|
||||
/* new texture painting */
|
||||
void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot);
|
||||
void PAINT_OT_image_paint(struct wmOperatorType *ot);
|
||||
|
||||
/* uv sculpting */
|
||||
@@ -202,7 +215,7 @@ float paint_calc_object_space_radius(struct ViewContext *vc, const float center[
|
||||
float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
|
||||
void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert, struct ColorSpace *colorspace);
|
||||
|
||||
void paint_sample_color(const struct bContext *C, struct ARegion *ar, int x, int y);
|
||||
void paint_sample_color(bContext *C, struct ARegion *ar, int x, int y, bool texpaint_proj, bool palette);
|
||||
void BRUSH_OT_curve_preset(struct wmOperatorType *ot);
|
||||
|
||||
void PAINT_OT_face_select_linked(struct wmOperatorType *ot);
|
||||
@@ -213,8 +226,10 @@ void PAINT_OT_face_select_reveal(struct wmOperatorType *ot);
|
||||
|
||||
void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vert_select_ungrouped(struct wmOperatorType *ot);
|
||||
|
||||
int vert_paint_poll(struct bContext *C);
|
||||
int mask_paint_poll(struct bContext *C);
|
||||
int paint_curve_poll(struct bContext *C);
|
||||
|
||||
int facemask_paint_poll(struct bContext *C);
|
||||
void flip_v3_v3(float out[3], const float in[3], const char symm);
|
||||
@@ -229,7 +244,6 @@ typedef enum BrushStrokeMode {
|
||||
/* paint_undo.c */
|
||||
struct ListBase *undo_paint_push_get_list(int type);
|
||||
void undo_paint_push_count_alloc(int type, int size);
|
||||
bool sculpt_undo_cleanup(struct bContext *C, struct ListBase *lb);
|
||||
|
||||
/* paint_hide.c */
|
||||
|
||||
@@ -258,4 +272,29 @@ typedef enum {
|
||||
void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot);
|
||||
void PAINT_OT_mask_lasso_gesture(struct wmOperatorType *ot);
|
||||
|
||||
/* paint_curve.c */
|
||||
void PAINTCURVE_OT_new(struct wmOperatorType *ot);
|
||||
void PAINTCURVE_OT_add_point(struct wmOperatorType *ot);
|
||||
void PAINTCURVE_OT_delete_point(struct wmOperatorType *ot);
|
||||
void PAINTCURVE_OT_select(struct wmOperatorType *ot);
|
||||
void PAINTCURVE_OT_slide(struct wmOperatorType *ot);
|
||||
void PAINTCURVE_OT_draw(struct wmOperatorType *ot);
|
||||
void PAINTCURVE_OT_cursor(struct wmOperatorType *ot);
|
||||
|
||||
/* image painting blur kernel */
|
||||
typedef struct {
|
||||
float *wdata; /* actual kernel */
|
||||
int side; /* kernel side */
|
||||
int side_squared; /* data side */
|
||||
int pixel_len; /* pixels around center that kernel is wide */
|
||||
} BlurKernel;
|
||||
|
||||
enum BlurKernelType;
|
||||
/* can be extended to other blur kernels later */
|
||||
BlurKernel *paint_new_blur_kernel(struct Brush *br);
|
||||
void paint_delete_blur_kernel(BlurKernel *);
|
||||
|
||||
/* paint curve defines */
|
||||
#define PAINT_CURVE_NUM_SEGMENTS 40
|
||||
|
||||
#endif /* __PAINT_INTERN_H__ */
|
||||
|
||||
@@ -149,11 +149,112 @@ static void BRUSH_OT_scale_size(wmOperatorType *ot)
|
||||
RNA_def_float(ot->srna, "scalar", 1, 0, 2, "Scalar", "Factor to scale brush size by", 0, 2);
|
||||
}
|
||||
|
||||
/* Palette operators */
|
||||
|
||||
static int palette_new_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Palette *palette;
|
||||
|
||||
palette = BKE_palette_add(bmain, "Palette");
|
||||
|
||||
BKE_paint_palette_set(paint, palette);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void PALETTE_OT_new(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add New Palette";
|
||||
ot->description = "Add new palette";
|
||||
ot->idname = "PALETTE_OT_new";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = palette_new_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int palette_poll(bContext *C)
|
||||
{
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
|
||||
if (paint && paint->palette != NULL)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int palette_color_add_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
Brush *brush = paint->brush;
|
||||
PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
Palette *palette = paint->palette;
|
||||
PaletteColor *color = BKE_palette_color_add(palette);
|
||||
|
||||
if (ELEM(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX)) {
|
||||
copy_v3_v3(color->rgb, BKE_brush_color_get(scene, brush));
|
||||
color->value = 0.0;
|
||||
}
|
||||
else if (mode == PAINT_WEIGHT) {
|
||||
zero_v3(color->rgb);
|
||||
color->value = brush->weight;
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void PALETTE_OT_color_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "New Palette Color";
|
||||
ot->description = "Add new color to active palette";
|
||||
ot->idname = "PALETTE_OT_color_add";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = palette_color_add_exec;
|
||||
ot->poll = palette_poll;
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
|
||||
static int palette_color_delete_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
Palette *palette = paint->palette;
|
||||
|
||||
BKE_palette_color_delete(palette);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void PALETTE_OT_color_delete(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Delete Palette Color";
|
||||
ot->description = "Remove active color from palette";
|
||||
ot->idname = "PALETTE_OT_color_delete";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = palette_color_delete_exec;
|
||||
ot->poll = palette_poll;
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int vertex_color_set_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *obact = CTX_data_active_object(C);
|
||||
unsigned int paintcol = vpaint_get_current_col(scene->toolsettings->vpaint);
|
||||
unsigned int paintcol = vpaint_get_current_col(scene, scene->toolsettings->vpaint);
|
||||
|
||||
if (ED_vpaint_fill(obact, paintcol)) {
|
||||
ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
|
||||
@@ -332,6 +433,7 @@ static int brush_generic_tool_set(Main *bmain, Paint *paint, const int tool,
|
||||
if (brush) {
|
||||
BKE_paint_brush_set(paint, brush);
|
||||
BKE_paint_invalidate_overlay_all();
|
||||
|
||||
WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -928,8 +1030,37 @@ static void ed_keymap_stencil(wmKeyMap *keymap)
|
||||
|
||||
/**************************** registration **********************************/
|
||||
|
||||
void ED_operatormacros_paint(void)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
wmOperatorTypeMacro *otmacro;
|
||||
|
||||
ot = WM_operatortype_append_macro("PAINTCURVE_OT_add_point_slide", "Add Curve Point and Slide",
|
||||
"Add new curve point and slide it", OPTYPE_UNDO);
|
||||
ot->description = "Add new curve point and slide it";
|
||||
WM_operatortype_macro_define(ot, "PAINTCURVE_OT_add_point");
|
||||
otmacro = WM_operatortype_macro_define(ot, "PAINTCURVE_OT_slide");
|
||||
RNA_boolean_set(otmacro->ptr, "align", true);
|
||||
RNA_boolean_set(otmacro->ptr, "select", false);
|
||||
}
|
||||
|
||||
|
||||
void ED_operatortypes_paint(void)
|
||||
{
|
||||
/* palette */
|
||||
WM_operatortype_append(PALETTE_OT_new);
|
||||
WM_operatortype_append(PALETTE_OT_color_add);
|
||||
WM_operatortype_append(PALETTE_OT_color_delete);
|
||||
|
||||
/* paint curve */
|
||||
WM_operatortype_append(PAINTCURVE_OT_new);
|
||||
WM_operatortype_append(PAINTCURVE_OT_add_point);
|
||||
WM_operatortype_append(PAINTCURVE_OT_delete_point);
|
||||
WM_operatortype_append(PAINTCURVE_OT_select);
|
||||
WM_operatortype_append(PAINTCURVE_OT_slide);
|
||||
WM_operatortype_append(PAINTCURVE_OT_draw);
|
||||
WM_operatortype_append(PAINTCURVE_OT_cursor);
|
||||
|
||||
/* brush */
|
||||
WM_operatortype_append(BRUSH_OT_add);
|
||||
WM_operatortype_append(BRUSH_OT_scale_size);
|
||||
@@ -950,6 +1081,8 @@ void ED_operatortypes_paint(void)
|
||||
WM_operatortype_append(PAINT_OT_grab_clone);
|
||||
WM_operatortype_append(PAINT_OT_project_image);
|
||||
WM_operatortype_append(PAINT_OT_image_from_view);
|
||||
WM_operatortype_append(PAINT_OT_brush_colors_flip);
|
||||
WM_operatortype_append(PAINT_OT_add_texture_paint_slot);
|
||||
|
||||
/* weight */
|
||||
WM_operatortype_append(PAINT_OT_weight_paint_toggle);
|
||||
@@ -1119,12 +1252,44 @@ static void paint_partial_visibility_keys(wmKeyMap *keymap)
|
||||
RNA_enum_set(kmi->ptr, "area", PARTIALVIS_ALL);
|
||||
}
|
||||
|
||||
|
||||
static void paint_keymap_curve(wmKeyMap *keymap)
|
||||
{
|
||||
wmKeyMapItem *kmi;
|
||||
|
||||
WM_keymap_add_item(keymap, "PAINTCURVE_OT_add_point_slide", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "PAINTCURVE_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "PAINTCURVE_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "extend", true);
|
||||
WM_keymap_add_item(keymap, "PAINTCURVE_OT_slide", ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "PAINTCURVE_OT_slide", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(kmi->ptr, "align", true);
|
||||
kmi = WM_keymap_add_item(keymap, "PAINTCURVE_OT_select", AKEY, KM_PRESS, 0, 0);
|
||||
RNA_boolean_set(kmi->ptr, "toggle", true);
|
||||
|
||||
WM_keymap_add_item(keymap, "PAINTCURVE_OT_cursor", ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "PAINTCURVE_OT_delete_point", XKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "PAINTCURVE_OT_draw", RETKEY, KM_PRESS, 0, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
|
||||
RNA_boolean_set(kmi->ptr, "release_confirm", true);
|
||||
WM_keymap_add_item(keymap, "TRANSFORM_OT_rotate", RKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "TRANSFORM_OT_resize", SKEY, KM_PRESS, 0, 0);
|
||||
}
|
||||
|
||||
void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
{
|
||||
wmKeyMap *keymap;
|
||||
wmKeyMapItem *kmi;
|
||||
int i;
|
||||
|
||||
keymap = WM_keymap_find(keyconf, "Paint Curve", 0, 0);
|
||||
keymap->poll = paint_curve_poll;
|
||||
|
||||
paint_keymap_curve(keymap);
|
||||
|
||||
/* Sculpt mode */
|
||||
keymap = WM_keymap_find(keyconf, "Sculpt", 0, 0);
|
||||
keymap->poll = sculpt_mode_poll;
|
||||
@@ -1191,7 +1356,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
RNA_boolean_set(kmi->ptr, "create_missing", 1);
|
||||
|
||||
/* */
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", EKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.stroke_method");
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
@@ -1225,7 +1390,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.texture_angle_source_random");
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", EKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.stroke_method");
|
||||
|
||||
/* Weight Paint mode */
|
||||
@@ -1250,7 +1415,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
|
||||
ed_keymap_stencil(keymap);
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", EKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.stroke_method");
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* face mask toggle */
|
||||
@@ -1283,6 +1448,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "mode", BRUSH_STROKE_NORMAL);
|
||||
RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "mode", BRUSH_STROKE_INVERT);
|
||||
WM_keymap_add_item(keymap, "PAINT_OT_brush_colors_flip", XKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "PAINT_OT_sample_color", SKEY, KM_PRESS, 0, 0);
|
||||
|
||||
@@ -1301,7 +1467,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.texture_angle_source_random");
|
||||
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", EKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.stroke_method");
|
||||
|
||||
/* face-mask mode */
|
||||
|
||||
@@ -36,16 +36,19 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_image.h"
|
||||
|
||||
@@ -72,7 +75,7 @@ typedef struct PaintSample {
|
||||
|
||||
typedef struct PaintStroke {
|
||||
void *mode_data;
|
||||
void *smooth_stroke_cursor;
|
||||
void *stroke_cursor;
|
||||
wmTimer *timer;
|
||||
|
||||
/* Cached values */
|
||||
@@ -81,6 +84,9 @@ typedef struct PaintStroke {
|
||||
Brush *brush;
|
||||
UnifiedPaintSettings *ups;
|
||||
|
||||
/* used for lines and curves */
|
||||
ListBase line;
|
||||
|
||||
/* Paint stroke can use up to PAINT_MAX_INPUT_SAMPLES prior inputs
|
||||
* to smooth the stroke */
|
||||
PaintSample samples[PAINT_MAX_INPUT_SAMPLES];
|
||||
@@ -88,6 +94,8 @@ typedef struct PaintStroke {
|
||||
int cur_sample;
|
||||
|
||||
float last_mouse_position[2];
|
||||
/* space distance covered so far */
|
||||
float stroke_distance;
|
||||
|
||||
/* Set whether any stroke step has yet occurred
|
||||
* e.g. in sculpt mode, stroke doesn't start until cursor
|
||||
@@ -116,18 +124,17 @@ typedef struct PaintStroke {
|
||||
StrokeDone done;
|
||||
} PaintStroke;
|
||||
|
||||
/*** Cursor ***/
|
||||
static void paint_draw_smooth_stroke(bContext *C, int x, int y, void *customdata)
|
||||
/*** Cursors ***/
|
||||
static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata)
|
||||
{
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
Brush *brush = BKE_paint_brush(paint);
|
||||
PaintStroke *stroke = customdata;
|
||||
|
||||
if (stroke && brush && (brush->flag & BRUSH_SMOOTH_STROKE)) {
|
||||
glColor4ubv(paint->paint_cursor_col);
|
||||
if (stroke && brush) {
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glColor4ubv(paint->paint_cursor_col);
|
||||
sdrawline(x, y, (int)stroke->last_mouse_position[0],
|
||||
(int)stroke->last_mouse_position[1]);
|
||||
glDisable(GL_BLEND);
|
||||
@@ -135,6 +142,33 @@ static void paint_draw_smooth_stroke(bContext *C, int x, int y, void *customdata
|
||||
}
|
||||
}
|
||||
|
||||
static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata)
|
||||
{
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
PaintStroke *stroke = customdata;
|
||||
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glEnable(GL_LINE_STIPPLE);
|
||||
glLineStipple(3, 0xAAAA);
|
||||
|
||||
glColor4ub(0, 0, 0, paint->paint_cursor_col[3]);
|
||||
glLineWidth(3.0);
|
||||
sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
|
||||
x, y);
|
||||
|
||||
glColor4ub(255, 255, 255, paint->paint_cursor_col[3]);
|
||||
glLineWidth(1.0);
|
||||
sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
|
||||
x, y);
|
||||
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
}
|
||||
|
||||
static bool paint_tool_require_location(Brush *brush, PaintMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
@@ -155,13 +189,18 @@ static bool paint_tool_require_location(Brush *brush, PaintMode mode)
|
||||
}
|
||||
|
||||
/* Initialize the stroke cache variants from operator properties */
|
||||
static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
|
||||
struct PaintStroke *stroke,
|
||||
const float mouse[2], float pressure)
|
||||
static bool paint_brush_update(bContext *C,
|
||||
Brush *brush,
|
||||
PaintMode mode,
|
||||
struct PaintStroke *stroke,
|
||||
const float mouse_init[2],
|
||||
float mouse[2], float pressure,
|
||||
float location[3])
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
|
||||
|
||||
UnifiedPaintSettings *ups = stroke->ups;
|
||||
bool location_sampled = false;
|
||||
bool location_success = false;
|
||||
/* XXX: Use pressure value from first brush step for brushes which don't
|
||||
* support strokes (grab, thumb). They depends on initial state and
|
||||
* brush coord/pressure/etc.
|
||||
@@ -222,14 +261,14 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
|
||||
else {
|
||||
copy_v2_v2(ups->tex_mouse, mouse);
|
||||
}
|
||||
}
|
||||
|
||||
/* take care of mask texture, if any */
|
||||
if (brush->mask_mtex.tex) {
|
||||
if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
|
||||
BKE_brush_randomize_texture_coordinates(ups, true);
|
||||
else {
|
||||
copy_v2_v2(ups->mask_tex_mouse, mouse);
|
||||
/* take care of mask texture, if any */
|
||||
if (brush->mask_mtex.tex) {
|
||||
if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
|
||||
BKE_brush_randomize_texture_coordinates(ups, true);
|
||||
else {
|
||||
copy_v2_v2(ups->mask_tex_mouse, mouse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,14 +285,14 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
|
||||
ups->brush_rotation = atan2(dx, dy) + M_PI;
|
||||
|
||||
if (brush->flag & BRUSH_EDGE_TO_EDGE) {
|
||||
float out[3];
|
||||
|
||||
halfway[0] = dx * 0.5f + stroke->initial_mouse[0];
|
||||
halfway[1] = dy * 0.5f + stroke->initial_mouse[1];
|
||||
|
||||
if (stroke->get_location) {
|
||||
if (stroke->get_location(C, out, halfway)) {
|
||||
if (stroke->get_location(C, location, halfway)) {
|
||||
hit = true;
|
||||
location_sampled = true;
|
||||
location_success = true;
|
||||
}
|
||||
else if (!paint_tool_require_location(brush, mode)) {
|
||||
hit = true;
|
||||
@@ -266,17 +305,43 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
|
||||
if (hit) {
|
||||
copy_v2_v2(ups->anchored_initial_mouse, halfway);
|
||||
copy_v2_v2(ups->tex_mouse, halfway);
|
||||
copy_v2_v2(ups->mask_tex_mouse, halfway);
|
||||
copy_v2_v2(mouse, halfway);
|
||||
ups->anchored_size /= 2.0f;
|
||||
ups->pixel_radius /= 2.0f;
|
||||
stroke->stroke_distance = ups->pixel_radius;
|
||||
}
|
||||
else
|
||||
else {
|
||||
copy_v2_v2(ups->anchored_initial_mouse, stroke->initial_mouse);
|
||||
|
||||
copy_v2_v2(mouse, stroke->initial_mouse);
|
||||
stroke->stroke_distance = ups->pixel_radius;
|
||||
}
|
||||
ups->pixel_radius /= stroke->zoom_2d;
|
||||
ups->draw_anchored = true;
|
||||
}
|
||||
else if (brush->flag & BRUSH_RAKE) {
|
||||
paint_calculate_rake_rotation(ups, mouse);
|
||||
/* here we are using the initial mouse coordinate because we do not want the rake
|
||||
* result to depend on jittering */
|
||||
if (!stroke->brush_init)
|
||||
copy_v2_v2(ups->last_rake, mouse_init);
|
||||
else
|
||||
paint_calculate_rake_rotation(ups, mouse_init);
|
||||
}
|
||||
|
||||
if (!location_sampled) {
|
||||
if (stroke->get_location) {
|
||||
if (stroke->get_location(C, location, mouse))
|
||||
location_success = true;
|
||||
else if (!paint_tool_require_location(brush, mode))
|
||||
location_success = true;
|
||||
}
|
||||
else {
|
||||
zero_v3(location);
|
||||
location_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
return location_success;
|
||||
}
|
||||
|
||||
|
||||
@@ -284,12 +349,11 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
|
||||
static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const float mouse_in[2], float pressure)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
Brush *brush = BKE_paint_brush(paint);
|
||||
PaintStroke *stroke = op->customdata;
|
||||
UnifiedPaintSettings *ups = stroke->ups;
|
||||
float mouse_out[2];
|
||||
PointerRNA itemptr;
|
||||
float location[3];
|
||||
@@ -315,8 +379,6 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const float
|
||||
copy_v2_v2(stroke->last_mouse_position, mouse_in);
|
||||
stroke->last_pressure = pressure;
|
||||
|
||||
paint_brush_update(C, brush, mode, stroke, mouse_in, pressure);
|
||||
|
||||
{
|
||||
float delta[2];
|
||||
float factor = stroke->zoom_2d;
|
||||
@@ -336,22 +398,13 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const float
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: can remove the if statement once all modes have this */
|
||||
if (stroke->get_location) {
|
||||
if (!stroke->get_location(C, location, mouse_out)) {
|
||||
if (paint_tool_require_location(brush, mode)) {
|
||||
if (ar && (paint->flags & PAINT_SHOW_BRUSH))
|
||||
WM_paint_cursor_tag_redraw(window, ar);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!paint_brush_update(C, brush, mode, stroke, mouse_in, mouse_out, pressure, location)) {
|
||||
return;
|
||||
}
|
||||
else
|
||||
zero_v3(location);
|
||||
|
||||
/* Add to stroke */
|
||||
RNA_collection_add(op->ptr, "stroke", &itemptr);
|
||||
|
||||
RNA_float_set(&itemptr, "size", ups->pixel_radius);
|
||||
RNA_float_set_array(&itemptr, "location", location);
|
||||
RNA_float_set_array(&itemptr, "mouse", mouse_out);
|
||||
RNA_boolean_set(&itemptr, "pen_flip", stroke->pen_flip);
|
||||
@@ -362,20 +415,12 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const float
|
||||
/* don't record this for now, it takes up a lot of memory when doing long
|
||||
* strokes with small brush size, and operators have register disabled */
|
||||
RNA_collection_clear(op->ptr, "stroke");
|
||||
|
||||
/* always redraw region if brush is shown */
|
||||
if (ar && (paint->flags & PAINT_SHOW_BRUSH))
|
||||
WM_paint_cursor_tag_redraw(window, ar);
|
||||
}
|
||||
|
||||
/* Returns zero if no sculpt changes should be made, non-zero otherwise */
|
||||
static int paint_smooth_stroke(PaintStroke *stroke, float output[2], float *outpressure,
|
||||
const PaintSample *sample, PaintMode mode)
|
||||
{
|
||||
output[0] = sample->mouse[0];
|
||||
output[1] = sample->mouse[1];
|
||||
*outpressure = sample->pressure;
|
||||
|
||||
if (paint_supports_smooth_stroke(stroke->brush, mode)) {
|
||||
float radius = stroke->brush->smooth_stroke_radius * stroke->zoom_2d;
|
||||
float u = stroke->brush->smooth_stroke_factor, v = 1.0f - u;
|
||||
@@ -391,6 +436,11 @@ static int paint_smooth_stroke(PaintStroke *stroke, float output[2], float *outp
|
||||
output[1] = sample->mouse[1] * v + stroke->last_mouse_position[1] * u;
|
||||
*outpressure = sample->pressure * v + stroke->last_pressure * u;
|
||||
}
|
||||
else {
|
||||
output[0] = sample->mouse[0];
|
||||
output[1] = sample->mouse[1];
|
||||
*outpressure = sample->pressure;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -413,6 +463,55 @@ static float paint_space_stroke_spacing(const Scene *scene, PaintStroke *stroke,
|
||||
return max_ff(1.0, size_clamp * spacing / 50.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static float paint_stroke_overlapped_curve(Brush *br, float x, float spacing)
|
||||
{
|
||||
int i;
|
||||
const int n = 100 / spacing;
|
||||
const float h = spacing / 50.0f;
|
||||
const float x0 = x - 1;
|
||||
|
||||
float sum;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
float xx;
|
||||
|
||||
xx = fabs(x0 + i * h);
|
||||
|
||||
if (xx < 1.0f)
|
||||
sum += BKE_brush_curve_strength(br, xx, 1);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static float paint_stroke_integrate_overlap(Brush *br, float factor)
|
||||
{
|
||||
int i;
|
||||
int m;
|
||||
float g;
|
||||
float max;
|
||||
|
||||
float spacing = br->spacing * factor;
|
||||
|
||||
if (!(br->flag & BRUSH_SPACE_ATTEN && (br->spacing < 100)))
|
||||
return 1.0;
|
||||
|
||||
m = 10;
|
||||
g = 1.0f / m;
|
||||
max = 0;
|
||||
for (i = 0; i < m; i++) {
|
||||
float overlap = paint_stroke_overlapped_curve(br, i * g, spacing);
|
||||
|
||||
if (overlap > max)
|
||||
max = overlap;
|
||||
}
|
||||
|
||||
return 1.0f / max;
|
||||
}
|
||||
|
||||
static float paint_space_stroke_spacing_variable(const Scene *scene, PaintStroke *stroke, float pressure, float dpressure, float length)
|
||||
{
|
||||
if (BKE_brush_use_size_pressure(scene, stroke->brush)) {
|
||||
@@ -444,40 +543,42 @@ static int paint_space_stroke(bContext *C, wmOperator *op, const float final_mou
|
||||
{
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
PaintStroke *stroke = op->customdata;
|
||||
PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
UnifiedPaintSettings *ups = stroke->ups;
|
||||
int cnt = 0;
|
||||
|
||||
if (paint_space_stroke_enabled(stroke->brush, mode)) {
|
||||
float pressure, dpressure;
|
||||
float mouse[2], dmouse[2];
|
||||
float length;
|
||||
float pressure, dpressure;
|
||||
float mouse[2], dmouse[2];
|
||||
float length;
|
||||
float no_pressure_spacing = paint_space_stroke_spacing(scene, stroke, 1.0f, 1.0f);
|
||||
|
||||
sub_v2_v2v2(dmouse, final_mouse, stroke->last_mouse_position);
|
||||
sub_v2_v2v2(dmouse, final_mouse, stroke->last_mouse_position);
|
||||
|
||||
pressure = stroke->last_pressure;
|
||||
dpressure = final_pressure - stroke->last_pressure;
|
||||
pressure = stroke->last_pressure;
|
||||
dpressure = final_pressure - stroke->last_pressure;
|
||||
|
||||
length = normalize_v2(dmouse);
|
||||
length = normalize_v2(dmouse);
|
||||
|
||||
while (length > 0.0f) {
|
||||
float spacing = paint_space_stroke_spacing_variable(scene, stroke, pressure, dpressure, length);
|
||||
|
||||
if (length >= spacing) {
|
||||
mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing;
|
||||
mouse[1] = stroke->last_mouse_position[1] + dmouse[1] * spacing;
|
||||
pressure = stroke->last_pressure + (spacing / length) * dpressure;
|
||||
while (length > 0.0f) {
|
||||
float spacing = paint_space_stroke_spacing_variable(scene, stroke, pressure, dpressure, length);
|
||||
|
||||
paint_brush_stroke_add_step(C, op, mouse, pressure);
|
||||
if (length >= spacing) {
|
||||
mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing;
|
||||
mouse[1] = stroke->last_mouse_position[1] + dmouse[1] * spacing;
|
||||
pressure = stroke->last_pressure + (spacing / length) * dpressure;
|
||||
|
||||
length -= spacing;
|
||||
pressure = stroke->last_pressure;
|
||||
dpressure = final_pressure - stroke->last_pressure;
|
||||
ups->overlap_factor = paint_stroke_integrate_overlap(stroke->brush, spacing / no_pressure_spacing);
|
||||
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
stroke->stroke_distance += spacing / stroke->zoom_2d;
|
||||
paint_brush_stroke_add_step(C, op, mouse, pressure);
|
||||
|
||||
length -= spacing;
|
||||
pressure = stroke->last_pressure;
|
||||
dpressure = final_pressure - stroke->last_pressure;
|
||||
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,6 +588,7 @@ static int paint_space_stroke(bContext *C, wmOperator *op, const float final_mou
|
||||
/**** Public API ****/
|
||||
|
||||
PaintStroke *paint_stroke_new(bContext *C,
|
||||
wmOperator *op,
|
||||
StrokeGetLocation get_location,
|
||||
StrokeTestStart test_start,
|
||||
StrokeUpdateStep update_step,
|
||||
@@ -497,6 +599,7 @@ PaintStroke *paint_stroke_new(bContext *C,
|
||||
ToolSettings *toolsettings = CTX_data_tool_settings(C);
|
||||
UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings;
|
||||
Brush *br = stroke->brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
|
||||
float zoomx, zoomy;
|
||||
|
||||
view3d_set_viewcontext(C, &stroke->vc);
|
||||
if (stroke->vc.v3d)
|
||||
@@ -510,6 +613,18 @@ PaintStroke *paint_stroke_new(bContext *C,
|
||||
stroke->event_type = event_type; /* for modal, return event */
|
||||
stroke->ups = ups;
|
||||
|
||||
get_imapaint_zoom(C, &zoomx, &zoomy);
|
||||
stroke->zoom_2d = max_ff(zoomx, zoomy);
|
||||
|
||||
if ((br->flag & BRUSH_CURVE) &&
|
||||
RNA_struct_property_is_set(op->ptr, "mode"))
|
||||
{
|
||||
RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL);
|
||||
}
|
||||
/* initialize here */
|
||||
ups->overlap_factor = 1.0;
|
||||
ups->stroke_active = true;
|
||||
|
||||
/* initialize here to avoid initialization conflict with threaded strokes */
|
||||
curvemapping_initialize(br->curve);
|
||||
|
||||
@@ -521,8 +636,7 @@ PaintStroke *paint_stroke_new(bContext *C,
|
||||
void paint_stroke_data_free(struct wmOperator *op)
|
||||
{
|
||||
BKE_paint_set_overlay_override(0);
|
||||
MEM_freeN(op->customdata);
|
||||
op->customdata = NULL;
|
||||
MEM_SAFE_FREE(op->customdata);
|
||||
}
|
||||
|
||||
static void stroke_done(struct bContext *C, struct wmOperator *op)
|
||||
@@ -552,8 +666,10 @@ static void stroke_done(struct bContext *C, struct wmOperator *op)
|
||||
stroke->timer);
|
||||
}
|
||||
|
||||
if (stroke->smooth_stroke_cursor)
|
||||
WM_paint_cursor_end(CTX_wm_manager(C), stroke->smooth_stroke_cursor);
|
||||
if (stroke->stroke_cursor)
|
||||
WM_paint_cursor_end(CTX_wm_manager(C), stroke->stroke_cursor);
|
||||
|
||||
BLI_freelistN(&stroke->line);
|
||||
|
||||
paint_stroke_data_free(op);
|
||||
}
|
||||
@@ -584,6 +700,16 @@ bool paint_supports_dynamic_size(Brush *br, PaintMode mode)
|
||||
if (sculpt_is_grab_tool(br))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case PAINT_TEXTURE_2D: /* fall through */
|
||||
case PAINT_TEXTURE_PROJECTIVE:
|
||||
if ((br->imagepaint_tool == PAINT_TOOL_FILL) &&
|
||||
(br->flag & BRUSH_USE_GRADIENT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -593,8 +719,7 @@ bool paint_supports_dynamic_size(Brush *br, PaintMode mode)
|
||||
bool paint_supports_smooth_stroke(Brush *br, PaintMode mode)
|
||||
{
|
||||
if (!(br->flag & BRUSH_SMOOTH_STROKE) ||
|
||||
(br->flag & BRUSH_ANCHORED) ||
|
||||
(br->flag & BRUSH_DRAG_DOT))
|
||||
(br->flag & (BRUSH_ANCHORED | BRUSH_DRAG_DOT | BRUSH_LINE)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -701,28 +826,141 @@ static void paint_stroke_sample_average(const PaintStroke *stroke,
|
||||
/*printf("avg=(%f, %f), num=%d\n", average->mouse[0], average->mouse[1], stroke->num_samples);*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Slightly different version of spacing for line/curve strokes,
|
||||
* makes sure the dabs stay on the line path.
|
||||
*/
|
||||
static void paint_line_strokes_spacing(
|
||||
bContext *C, wmOperator *op, PaintStroke *stroke, float spacing, float *length_residue,
|
||||
const float old_pos[2], const float new_pos[2])
|
||||
{
|
||||
UnifiedPaintSettings *ups = stroke->ups;
|
||||
|
||||
float mouse[2], dmouse[2];
|
||||
float length;
|
||||
|
||||
sub_v2_v2v2(dmouse, new_pos, old_pos);
|
||||
copy_v2_v2(stroke->last_mouse_position, old_pos);
|
||||
|
||||
length = normalize_v2(dmouse);
|
||||
|
||||
BLI_assert(length >= 0.0f);
|
||||
|
||||
if (length == 0.0f)
|
||||
return;
|
||||
|
||||
while (length > 0.0f) {
|
||||
float spacing_final = spacing - *length_residue;
|
||||
length += *length_residue;
|
||||
*length_residue = 0.0;
|
||||
|
||||
if (length >= spacing) {
|
||||
mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing_final;
|
||||
mouse[1] = stroke->last_mouse_position[1] + dmouse[1] * spacing_final;
|
||||
|
||||
ups->overlap_factor = paint_stroke_integrate_overlap(stroke->brush, 1.0);
|
||||
|
||||
stroke->stroke_distance += spacing / stroke->zoom_2d;
|
||||
paint_brush_stroke_add_step(C, op, mouse, 1.0);
|
||||
|
||||
length -= spacing;
|
||||
spacing_final = spacing;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*length_residue = length;
|
||||
}
|
||||
|
||||
|
||||
static void paint_stroke_line_end(bContext *C, wmOperator *op, PaintStroke *stroke, float mouse[2])
|
||||
{
|
||||
Brush *br = stroke->brush;
|
||||
if (stroke->stroke_started && (br->flag & BRUSH_LINE)) {
|
||||
stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
|
||||
|
||||
paint_brush_stroke_add_step(C, op, stroke->last_mouse_position, 1.0);
|
||||
paint_space_stroke(C, op, mouse, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *stroke)
|
||||
{
|
||||
Brush *br = stroke->brush;
|
||||
if (br->flag & BRUSH_CURVE) {
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
const float spacing = paint_space_stroke_spacing(scene, stroke, 1.0f, 1.0f);
|
||||
PaintCurve *pc = br->paint_curve;
|
||||
PaintCurvePoint *pcp;
|
||||
float length_residue = 0.0f;
|
||||
int i;
|
||||
|
||||
if (!pc)
|
||||
return true;
|
||||
|
||||
pcp = pc->points;
|
||||
stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
|
||||
|
||||
for (i = 0; i < pc->tot_points - 1; i++, pcp++) {
|
||||
int j;
|
||||
float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2];
|
||||
PaintCurvePoint *pcp_next = pcp + 1;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
BKE_curve_forward_diff_bezier(
|
||||
pcp->bez.vec[1][j],
|
||||
pcp->bez.vec[2][j],
|
||||
pcp_next->bez.vec[0][j],
|
||||
pcp_next->bez.vec[1][j],
|
||||
data + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2]));
|
||||
|
||||
|
||||
for (j = 0; j < PAINT_CURVE_NUM_SEGMENTS; j++) {
|
||||
if (!stroke->stroke_started) {
|
||||
stroke->last_pressure = 1.0;
|
||||
copy_v2_v2(stroke->last_mouse_position, data + 2 * j);
|
||||
stroke->stroke_started = stroke->test_start(C, op, stroke->last_mouse_position);
|
||||
|
||||
if (stroke->stroke_started) {
|
||||
paint_brush_stroke_add_step(C, op, data + 2 * j, 1.0);
|
||||
paint_line_strokes_spacing(C, op, stroke, spacing, &length_residue, data + 2 * j, data + 2 * (j + 1));
|
||||
}
|
||||
}
|
||||
else {
|
||||
paint_line_strokes_spacing(C, op, stroke, spacing, &length_residue, data + 2 * j, data + 2 * (j + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stroke_done(C, op);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
PaintStroke *stroke = op->customdata;
|
||||
Brush *br = stroke->brush;
|
||||
PaintSample sample_average;
|
||||
float mouse[2];
|
||||
bool first_dab = false;
|
||||
bool first_modal = false;
|
||||
float zoomx, zoomy;
|
||||
bool redraw = false;
|
||||
float pressure;
|
||||
|
||||
/* see if tablet affects event */
|
||||
pressure = WM_event_tablet_data(event, &stroke->pen_flip, NULL);
|
||||
/* see if tablet affects event. Line, anchored and drag dot strokes do not support pressure */
|
||||
pressure = (br->flag & (BRUSH_LINE | BRUSH_ANCHORED | BRUSH_DRAG_DOT)) ? 1.0f : WM_event_tablet_data(event, &stroke->pen_flip, NULL);
|
||||
|
||||
paint_stroke_add_sample(p, stroke, event->mval[0], event->mval[1], pressure);
|
||||
paint_stroke_sample_average(stroke, &sample_average);
|
||||
|
||||
get_imapaint_zoom(C, &zoomx, &zoomy);
|
||||
stroke->zoom_2d = max_ff(zoomx, zoomy);
|
||||
|
||||
/* let NDOF motion pass through to the 3D view so we can paint and rotate simultaneously!
|
||||
* this isn't perfect... even when an extra MOUSEMOVE is spoofed, the stroke discards it
|
||||
* since the 2D deltas are zero -- code in this file needs to be updated to use the
|
||||
@@ -732,8 +970,12 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
/* one time initialization */
|
||||
if (!stroke->stroke_init) {
|
||||
stroke->smooth_stroke_cursor =
|
||||
WM_paint_cursor_activate(CTX_wm_manager(C), paint_poll, paint_draw_smooth_stroke, stroke);
|
||||
if (paint_stroke_curve_end(C, op, stroke))
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
if (paint_supports_smooth_stroke(br, mode))
|
||||
stroke->stroke_cursor =
|
||||
WM_paint_cursor_activate(CTX_wm_manager(C), paint_poll, paint_draw_smooth_cursor, stroke);
|
||||
|
||||
stroke->stroke_init = true;
|
||||
first_modal = true;
|
||||
@@ -747,9 +989,14 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
BLI_assert((stroke->stroke_started & ~1) == 0); /* 0/1 */
|
||||
|
||||
if (stroke->stroke_started) {
|
||||
if (stroke->brush->flag & BRUSH_AIRBRUSH)
|
||||
if (br->flag & BRUSH_AIRBRUSH)
|
||||
stroke->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, stroke->brush->rate);
|
||||
|
||||
if (br->flag & BRUSH_LINE) {
|
||||
stroke->stroke_cursor =
|
||||
WM_paint_cursor_activate(CTX_wm_manager(C), paint_poll, paint_draw_line_cursor, stroke);
|
||||
}
|
||||
|
||||
first_dab = true;
|
||||
}
|
||||
}
|
||||
@@ -765,20 +1012,42 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (event->type == stroke->event_type && event->val == KM_RELEASE && !first_modal) {
|
||||
if (event->type == stroke->event_type && !first_modal) {
|
||||
if (event->val == KM_RELEASE) {
|
||||
paint_stroke_line_end (C, op, stroke, sample_average.mouse);
|
||||
stroke_done(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
}
|
||||
else if (ELEM(event->type, RETKEY, SPACEKEY)) {
|
||||
paint_stroke_line_end(C, op, stroke, sample_average.mouse);
|
||||
stroke_done(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else if (first_modal || (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) ||
|
||||
(event->type == TIMER && (event->customdata == stroke->timer)) )
|
||||
else if ((br->flag & BRUSH_LINE) && stroke->stroke_started &&
|
||||
(first_modal || (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))))
|
||||
{
|
||||
if (br->flag & BRUSH_RAKE) {
|
||||
copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position);
|
||||
paint_calculate_rake_rotation(stroke->ups, sample_average.mouse);
|
||||
}
|
||||
}
|
||||
else if (first_modal ||
|
||||
/* regular dabs */
|
||||
(!(br->flag & (BRUSH_AIRBRUSH)) && (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))) ||
|
||||
/* airbrush */
|
||||
((br->flag & BRUSH_AIRBRUSH) && event->type == TIMER && event->customdata == stroke->timer))
|
||||
{
|
||||
if (paint_smooth_stroke(stroke, mouse, &pressure, &sample_average, mode)) {
|
||||
if (stroke->stroke_started) {
|
||||
if (paint_space_stroke_enabled(stroke->brush, mode)) {
|
||||
if (paint_space_stroke_enabled(br, mode)) {
|
||||
if (paint_space_stroke(C, op, mouse, pressure))
|
||||
redraw = true;
|
||||
}
|
||||
else {
|
||||
float dmouse[2];
|
||||
sub_v2_v2v2(dmouse, mouse, stroke->last_mouse_position);
|
||||
stroke->stroke_distance += len_v2(dmouse);
|
||||
paint_brush_stroke_add_step(C, op, mouse, pressure);
|
||||
redraw = true;
|
||||
}
|
||||
@@ -789,19 +1058,27 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
/* we want the stroke to have the first daub at the start location
|
||||
* instead of waiting till we have moved the space distance */
|
||||
if (first_dab &&
|
||||
paint_space_stroke_enabled(stroke->brush, mode) &&
|
||||
!(stroke->brush->flag & BRUSH_ANCHORED) &&
|
||||
!(stroke->brush->flag & BRUSH_SMOOTH_STROKE))
|
||||
paint_space_stroke_enabled(br, mode) &&
|
||||
!(br->flag & BRUSH_SMOOTH_STROKE))
|
||||
{
|
||||
paint_brush_stroke_add_step(C, op, mouse, pressure);
|
||||
stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
|
||||
paint_brush_stroke_add_step(C, op, sample_average.mouse, sample_average.pressure);
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
/* do updates for redraw. if event is inbetween mousemove there are more
|
||||
* coming, so postpone potentially slow redraw updates until all are done */
|
||||
if (event->type != INBETWEEN_MOUSEMOVE)
|
||||
if (event->type != INBETWEEN_MOUSEMOVE) {
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
||||
/* At the very least, invalidate the cursor */
|
||||
if (ar && (p->flags & PAINT_SHOW_BRUSH))
|
||||
WM_paint_cursor_tag_redraw(window, ar);
|
||||
|
||||
if (redraw && stroke->redraw)
|
||||
stroke->redraw(C, stroke, false);
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
@@ -843,6 +1120,11 @@ void *paint_stroke_mode_data(struct PaintStroke *stroke)
|
||||
return stroke->mode_data;
|
||||
}
|
||||
|
||||
float paint_stroke_distance_get(struct PaintStroke *stroke)
|
||||
{
|
||||
return stroke->stroke_distance;
|
||||
}
|
||||
|
||||
void paint_stroke_set_mode_data(PaintStroke *stroke, void *mode_data)
|
||||
{
|
||||
stroke->mode_data = mode_data;
|
||||
@@ -856,6 +1138,6 @@ int paint_poll(bContext *C)
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
||||
return p && ob && BKE_paint_brush(p) &&
|
||||
(sa && sa->spacetype == SPACE_VIEW3D) &&
|
||||
(sa && ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) &&
|
||||
(ar && ar->regiontype == RGN_TYPE_WINDOW);
|
||||
}
|
||||
|
||||
@@ -51,19 +51,17 @@ typedef struct UndoElem {
|
||||
|
||||
UndoRestoreCb restore;
|
||||
UndoFreeCb free;
|
||||
UndoCleanupCb cleanup;
|
||||
} UndoElem;
|
||||
|
||||
typedef bool (*UndoCleanupCb)(struct bContext *C, ListBase *lb);
|
||||
|
||||
typedef struct UndoStack {
|
||||
int type;
|
||||
ListBase elems;
|
||||
UndoElem *current;
|
||||
UndoCleanupCb cleanup;
|
||||
} UndoStack;
|
||||
|
||||
static UndoStack ImageUndoStack = {UNDO_PAINT_IMAGE, {NULL, NULL}, NULL, NULL};
|
||||
static UndoStack MeshUndoStack = {UNDO_PAINT_MESH, {NULL, NULL}, NULL, sculpt_undo_cleanup};
|
||||
static UndoStack ImageUndoStack = {UNDO_PAINT_IMAGE, {NULL, NULL}, NULL};
|
||||
static UndoStack MeshUndoStack = {UNDO_PAINT_MESH, {NULL, NULL}, NULL};
|
||||
|
||||
/* Generic */
|
||||
|
||||
@@ -81,7 +79,7 @@ static void undo_elem_free(UndoStack *UNUSED(stack), UndoElem *uel)
|
||||
}
|
||||
}
|
||||
|
||||
static void undo_stack_push_begin(UndoStack *stack, const char *name, UndoRestoreCb restore, UndoFreeCb free)
|
||||
static void undo_stack_push_begin(UndoStack *stack, const char *name, UndoRestoreCb restore, UndoFreeCb free, UndoCleanupCb cleanup)
|
||||
{
|
||||
UndoElem *uel;
|
||||
int nr;
|
||||
@@ -101,6 +99,7 @@ static void undo_stack_push_begin(UndoStack *stack, const char *name, UndoRestor
|
||||
stack->current = uel = MEM_callocN(sizeof(UndoElem), "undo file");
|
||||
uel->restore = restore;
|
||||
uel->free = free;
|
||||
uel->cleanup = cleanup;
|
||||
BLI_addtail(&stack->elems, uel);
|
||||
|
||||
/* name can be a dynamic string */
|
||||
@@ -179,25 +178,24 @@ static void undo_stack_cleanup(UndoStack *stack, bContext *C)
|
||||
UndoElem *uel = stack->elems.first;
|
||||
bool stack_reset = false;
|
||||
|
||||
if (stack->cleanup) {
|
||||
while (uel) {
|
||||
if (stack->cleanup(C, &uel->elems)) {
|
||||
UndoElem *uel_tmp = uel->next;
|
||||
if (stack->current == uel) {
|
||||
stack->current = NULL;
|
||||
stack_reset = true;
|
||||
}
|
||||
undo_elem_free(stack, uel);
|
||||
BLI_freelinkN(&stack->elems, uel);
|
||||
uel = uel_tmp;
|
||||
while (uel) {
|
||||
if (uel->cleanup && uel->cleanup(C, &uel->elems)) {
|
||||
UndoElem *uel_tmp = uel->next;
|
||||
if (stack->current == uel) {
|
||||
stack->current = NULL;
|
||||
stack_reset = true;
|
||||
}
|
||||
else
|
||||
uel = uel->next;
|
||||
}
|
||||
if (stack_reset) {
|
||||
stack->current = stack->elems.last;
|
||||
undo_elem_free(stack, uel);
|
||||
BLI_freelinkN(&stack->elems, uel);
|
||||
uel = uel_tmp;
|
||||
}
|
||||
else
|
||||
uel = uel->next;
|
||||
}
|
||||
if (stack_reset) {
|
||||
stack->current = stack->elems.last;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char *name)
|
||||
@@ -255,23 +253,25 @@ static void undo_stack_free(UndoStack *stack)
|
||||
|
||||
/* Exported Functions */
|
||||
|
||||
void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free)
|
||||
void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free, UndoCleanupCb cleanup)
|
||||
{
|
||||
if (type == UNDO_PAINT_IMAGE)
|
||||
undo_stack_push_begin(&ImageUndoStack, name, restore, free);
|
||||
undo_stack_push_begin(&ImageUndoStack, name, restore, free, cleanup);
|
||||
else if (type == UNDO_PAINT_MESH)
|
||||
undo_stack_push_begin(&MeshUndoStack, name, restore, free);
|
||||
undo_stack_push_begin(&MeshUndoStack, name, restore, free, cleanup);
|
||||
}
|
||||
|
||||
ListBase *undo_paint_push_get_list(int type)
|
||||
{
|
||||
if (type == UNDO_PAINT_IMAGE) {
|
||||
if (ImageUndoStack.current)
|
||||
if (ImageUndoStack.current) {
|
||||
return &ImageUndoStack.current->elems;
|
||||
}
|
||||
}
|
||||
else if (type == UNDO_PAINT_MESH) {
|
||||
if (MeshUndoStack.current)
|
||||
if (MeshUndoStack.current) {
|
||||
return &MeshUndoStack.current->elems;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -35,23 +35,28 @@
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_color.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_rect.h"
|
||||
|
||||
#include "BLF_translation.h"
|
||||
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_image.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
@@ -67,6 +72,10 @@
|
||||
|
||||
#include "ED_view3d.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_uvedit.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
#include "ED_mesh.h" /* for face mask functions */
|
||||
@@ -205,6 +214,175 @@ void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct
|
||||
CLAMP(rgba[3], 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
/* 3D Paint */
|
||||
|
||||
static void imapaint_project(float matrix[4][4], const float co[3], float pco[4])
|
||||
{
|
||||
copy_v3_v3(pco, co);
|
||||
pco[3] = 1.0f;
|
||||
|
||||
mul_m4_v4(matrix, pco);
|
||||
}
|
||||
|
||||
static void imapaint_tri_weights(float matrix[4][4], GLint view[4],
|
||||
const float v1[3], const float v2[3], const float v3[3],
|
||||
const float co[2], float w[3])
|
||||
{
|
||||
float pv1[4], pv2[4], pv3[4], h[3], divw;
|
||||
float wmat[3][3], invwmat[3][3];
|
||||
|
||||
/* compute barycentric coordinates */
|
||||
|
||||
/* project the verts */
|
||||
imapaint_project(matrix, v1, pv1);
|
||||
imapaint_project(matrix, v2, pv2);
|
||||
imapaint_project(matrix, v3, pv3);
|
||||
|
||||
/* do inverse view mapping, see gluProject man page */
|
||||
h[0] = (co[0] - view[0]) * 2.0f / view[2] - 1.0f;
|
||||
h[1] = (co[1] - view[1]) * 2.0f / view[3] - 1.0f;
|
||||
h[2] = 1.0f;
|
||||
|
||||
/* solve for (w1,w2,w3)/perspdiv in:
|
||||
* h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3) */
|
||||
|
||||
wmat[0][0] = pv1[0]; wmat[1][0] = pv2[0]; wmat[2][0] = pv3[0];
|
||||
wmat[0][1] = pv1[1]; wmat[1][1] = pv2[1]; wmat[2][1] = pv3[1];
|
||||
wmat[0][2] = pv1[3]; wmat[1][2] = pv2[3]; wmat[2][2] = pv3[3];
|
||||
|
||||
invert_m3_m3(invwmat, wmat);
|
||||
mul_m3_v3(invwmat, h);
|
||||
|
||||
copy_v3_v3(w, h);
|
||||
|
||||
/* w is still divided by perspdiv, make it sum to one */
|
||||
divw = w[0] + w[1] + w[2];
|
||||
if (divw != 0.0f) {
|
||||
mul_v3_fl(w, 1.0f / divw);
|
||||
}
|
||||
}
|
||||
|
||||
/* compute uv coordinates of mouse in face */
|
||||
static void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2])
|
||||
{
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
||||
MTFace *tf_base, *tf;
|
||||
Material *ma;
|
||||
TexPaintSlot *slot;
|
||||
int numfaces = dm->getNumTessFaces(dm), a, findex;
|
||||
float p[2], w[3], absw, minabsw;
|
||||
MFace mf;
|
||||
MVert mv[4];
|
||||
float matrix[4][4], proj[4][4];
|
||||
GLint view[4];
|
||||
|
||||
/* compute barycentric coordinates */
|
||||
|
||||
/* double lookup */
|
||||
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
|
||||
const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
|
||||
if (index_mf_to_mpoly == NULL) {
|
||||
index_mp_to_orig = NULL;
|
||||
}
|
||||
|
||||
/* get the needed opengl matrices */
|
||||
glGetIntegerv(GL_VIEWPORT, view);
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, (float *)matrix);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, (float *)proj);
|
||||
view[0] = view[1] = 0;
|
||||
mul_m4_m4m4(matrix, matrix, ob->obmat);
|
||||
mul_m4_m4m4(matrix, proj, matrix);
|
||||
|
||||
minabsw = 1e10;
|
||||
uv[0] = uv[1] = 0.0;
|
||||
|
||||
/* test all faces in the derivedmesh with the original index of the picked face */
|
||||
for (a = 0; a < numfaces; a++) {
|
||||
findex = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
|
||||
|
||||
if (findex == faceindex) {
|
||||
dm->getTessFace(dm, a, &mf);
|
||||
|
||||
ma = dm->mat[mf.mat_nr];
|
||||
slot = &ma->texpaintslot[ma->paint_active_slot];
|
||||
|
||||
dm->getVert(dm, mf.v1, &mv[0]);
|
||||
dm->getVert(dm, mf.v2, &mv[1]);
|
||||
dm->getVert(dm, mf.v3, &mv[2]);
|
||||
if (mf.v4)
|
||||
dm->getVert(dm, mf.v4, &mv[3]);
|
||||
|
||||
if (!slot->uvname[0] || !(tf_base = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, slot->uvname)))
|
||||
tf_base = CustomData_get_layer(&dm->faceData, CD_MTFACE);
|
||||
|
||||
tf = &tf_base[a];
|
||||
|
||||
p[0] = xy[0];
|
||||
p[1] = xy[1];
|
||||
|
||||
if (mf.v4) {
|
||||
/* the triangle with the largest absolute values is the one
|
||||
* with the most negative weights */
|
||||
imapaint_tri_weights(matrix, view, mv[0].co, mv[1].co, mv[3].co, p, w);
|
||||
absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
|
||||
if (absw < minabsw) {
|
||||
uv[0] = tf->uv[0][0] * w[0] + tf->uv[1][0] * w[1] + tf->uv[3][0] * w[2];
|
||||
uv[1] = tf->uv[0][1] * w[0] + tf->uv[1][1] * w[1] + tf->uv[3][1] * w[2];
|
||||
minabsw = absw;
|
||||
}
|
||||
|
||||
imapaint_tri_weights(matrix, view, mv[1].co, mv[2].co, mv[3].co, p, w);
|
||||
absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
|
||||
if (absw < minabsw) {
|
||||
uv[0] = tf->uv[1][0] * w[0] + tf->uv[2][0] * w[1] + tf->uv[3][0] * w[2];
|
||||
uv[1] = tf->uv[1][1] * w[0] + tf->uv[2][1] * w[1] + tf->uv[3][1] * w[2];
|
||||
minabsw = absw;
|
||||
}
|
||||
}
|
||||
else {
|
||||
imapaint_tri_weights(matrix, view, mv[0].co, mv[1].co, mv[2].co, p, w);
|
||||
absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
|
||||
if (absw < minabsw) {
|
||||
uv[0] = tf->uv[0][0] * w[0] + tf->uv[1][0] * w[1] + tf->uv[2][0] * w[2];
|
||||
uv[1] = tf->uv[0][1] * w[0] + tf->uv[1][1] * w[1] + tf->uv[2][1] * w[2];
|
||||
minabsw = absw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
/* returns 0 if not found, otherwise 1 */
|
||||
static int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *r_index, unsigned int totface)
|
||||
{
|
||||
if (totface == 0)
|
||||
return 0;
|
||||
|
||||
/* sample only on the exact position */
|
||||
*r_index = view3d_sample_backbuf(vc, mval[0], mval[1]);
|
||||
|
||||
if ((*r_index) == 0 || (*r_index) > (unsigned int)totface) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
(*r_index)--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static Image *imapaint_face_image(DerivedMesh *dm, int face_index)
|
||||
{
|
||||
Image *ima;
|
||||
MFace *mf = dm->getTessFaceArray(dm) + face_index;
|
||||
Material *ma = dm->mat[mf->mat_nr];
|
||||
ima = ma->texpaintslot[ma->paint_active_slot].ima;
|
||||
|
||||
return ima;
|
||||
}
|
||||
|
||||
/* Uses symm to selectively flip any axis of a coordinate. */
|
||||
void flip_v3_v3(float out[3], const float in[3], const char symm)
|
||||
{
|
||||
@@ -223,25 +401,123 @@ void flip_v3_v3(float out[3], const float in[3], const char symm)
|
||||
}
|
||||
|
||||
/* used for both 3d view and image window */
|
||||
void paint_sample_color(const bContext *C, ARegion *ar, int x, int y) /* frontbuf */
|
||||
void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_proj, bool use_palette)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
Palette *palette = BKE_paint_palette(paint);
|
||||
PaletteColor *color;
|
||||
Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C));
|
||||
unsigned int col;
|
||||
const char *cp;
|
||||
const unsigned char *cp;
|
||||
|
||||
CLAMP(x, 0, ar->winx);
|
||||
CLAMP(y, 0, ar->winy);
|
||||
|
||||
glReadBuffer(GL_FRONT);
|
||||
glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
|
||||
glReadBuffer(GL_BACK);
|
||||
if (use_palette) {
|
||||
if (!palette) {
|
||||
palette = BKE_palette_add(CTX_data_main(C), "Palette");
|
||||
BKE_paint_palette_set(paint, palette);
|
||||
}
|
||||
|
||||
cp = (char *)&col;
|
||||
color = BKE_palette_color_add(palette);
|
||||
}
|
||||
|
||||
|
||||
if (CTX_wm_view3d(C) && texpaint_proj) {
|
||||
/* first try getting a colour directly from the mesh faces if possible */
|
||||
Object *ob = OBACT;
|
||||
bool sample_success = false;
|
||||
|
||||
if (ob) {
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
||||
|
||||
ViewContext vc;
|
||||
const int mval[2] = {x, y};
|
||||
unsigned int faceindex;
|
||||
unsigned int totface = dm->getNumTessFaces(dm);
|
||||
MTFace *dm_mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
|
||||
|
||||
DM_update_materials(dm, ob);
|
||||
|
||||
if (dm_mtface) {
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
if (imapaint_pick_face(&vc, mval, &faceindex, totface)) {
|
||||
Image *image = imapaint_face_image(dm, faceindex);
|
||||
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
|
||||
if (ibuf && ibuf->rect) {
|
||||
float uv[2];
|
||||
float u, v;
|
||||
imapaint_pick_uv(scene, ob, faceindex, mval, uv);
|
||||
sample_success = true;
|
||||
|
||||
u = fmodf(uv[0], 1.0f);
|
||||
v = fmodf(uv[1], 1.0f);
|
||||
|
||||
if (u < 0.0f) u += 1.0f;
|
||||
if (v < 0.0f) v += 1.0f;
|
||||
|
||||
u = u * ibuf->x - 0.5f;
|
||||
v = v * ibuf->y - 0.5f;
|
||||
|
||||
if (ibuf->rect_float) {
|
||||
float rgba_f[4];
|
||||
bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v);
|
||||
straight_to_premul_v4(rgba_f);
|
||||
if (use_palette) {
|
||||
linearrgb_to_srgb_v3_v3(color->rgb, rgba_f);
|
||||
}
|
||||
else {
|
||||
linearrgb_to_srgb_v3_v3(rgba_f, rgba_f);
|
||||
BKE_brush_color_set(scene, br, rgba_f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned char rgba[4];
|
||||
bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v);
|
||||
if (use_palette) {
|
||||
rgb_uchar_to_float(color->rgb, rgba);
|
||||
}
|
||||
else {
|
||||
float rgba_f[3];
|
||||
rgb_uchar_to_float(rgba_f, rgba);
|
||||
BKE_brush_color_set(scene, br, rgba_f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BKE_image_release_ibuf(image, ibuf, NULL);
|
||||
}
|
||||
}
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
if (!sample_success) {
|
||||
glReadBuffer(GL_FRONT);
|
||||
glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
|
||||
glReadBuffer(GL_BACK);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else {
|
||||
glReadBuffer(GL_FRONT);
|
||||
glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
|
||||
glReadBuffer(GL_BACK);
|
||||
}
|
||||
cp = (unsigned char *)&col;
|
||||
|
||||
if (br) {
|
||||
br->rgb[0] = cp[0] / 255.0f;
|
||||
br->rgb[1] = cp[1] / 255.0f;
|
||||
br->rgb[2] = cp[2] / 255.0f;
|
||||
if (use_palette) {
|
||||
rgb_uchar_to_float(color->rgb, cp);
|
||||
}
|
||||
else {
|
||||
float rgba_f[3];
|
||||
rgb_uchar_to_float(rgba_f, cp);
|
||||
BKE_brush_color_set(scene, br, rgba_f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -197,11 +197,11 @@ static int *get_indexarray(Mesh *me)
|
||||
return MEM_mallocN(sizeof(int) * (me->totpoly + 1), "vertexpaint");
|
||||
}
|
||||
|
||||
unsigned int vpaint_get_current_col(VPaint *vp)
|
||||
unsigned int vpaint_get_current_col(Scene *scene, VPaint *vp)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&vp->paint);
|
||||
unsigned char col[4];
|
||||
rgb_float_to_uchar(col, brush->rgb);
|
||||
rgb_float_to_uchar(col, BKE_brush_color_get(scene, brush));
|
||||
col[3] = 255; /* alpha isn't used, could even be removed to speedup paint a little */
|
||||
return *(unsigned int *)col;
|
||||
}
|
||||
@@ -2547,14 +2547,17 @@ static int wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
int retval;
|
||||
|
||||
op->customdata = paint_stroke_new(C, NULL, wpaint_stroke_test_start,
|
||||
op->customdata = paint_stroke_new(C, op, NULL, wpaint_stroke_test_start,
|
||||
wpaint_stroke_update_step, NULL,
|
||||
wpaint_stroke_done, event->type);
|
||||
|
||||
if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
|
||||
paint_stroke_data_free(op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
retval = op->type->modal(C, op, event);
|
||||
OPERATOR_RETVAL_CHECK(retval);
|
||||
BLI_assert(retval == OPERATOR_RUNNING_MODAL);
|
||||
|
||||
@@ -2563,7 +2566,7 @@ static int wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
static int wpaint_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
op->customdata = paint_stroke_new(C, NULL, wpaint_stroke_test_start,
|
||||
op->customdata = paint_stroke_new(C, op, NULL, wpaint_stroke_test_start,
|
||||
wpaint_stroke_update_step, NULL,
|
||||
wpaint_stroke_done, 0);
|
||||
|
||||
@@ -2778,7 +2781,8 @@ static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
|
||||
|
||||
static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const float UNUSED(mouse[2]))
|
||||
{
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
struct PaintStroke *stroke = op->customdata;
|
||||
VPaint *vp = ts->vpaint;
|
||||
Brush *brush = BKE_paint_brush(&vp->paint);
|
||||
@@ -2810,7 +2814,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
|
||||
vpd->vp_handle = ED_vpaint_proj_handle_create(vpd->vc.scene, ob, &vpd->vertexcosnos);
|
||||
|
||||
vpd->indexar = get_indexarray(me);
|
||||
vpd->paintcol = vpaint_get_current_col(vp);
|
||||
vpd->paintcol = vpaint_get_current_col(scene, vp);
|
||||
|
||||
vpd->is_texbrush = !(brush->vertexpaint_tool == PAINT_BLEND_BLUR) &&
|
||||
brush->mtex.tex;
|
||||
@@ -3062,14 +3066,18 @@ static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
int retval;
|
||||
|
||||
op->customdata = paint_stroke_new(C, NULL, vpaint_stroke_test_start,
|
||||
op->customdata = paint_stroke_new(C, op, NULL, vpaint_stroke_test_start,
|
||||
vpaint_stroke_update_step, NULL,
|
||||
vpaint_stroke_done, event->type);
|
||||
|
||||
if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
|
||||
paint_stroke_data_free(op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
retval = op->type->modal(C, op, event);
|
||||
OPERATOR_RETVAL_CHECK(retval);
|
||||
BLI_assert(retval == OPERATOR_RUNNING_MODAL);
|
||||
|
||||
@@ -3078,7 +3086,7 @@ static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
||||
static int vpaint_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
op->customdata = paint_stroke_new(C, NULL, vpaint_stroke_test_start,
|
||||
op->customdata = paint_stroke_new(C, op, NULL, vpaint_stroke_test_start,
|
||||
vpaint_stroke_update_step, NULL,
|
||||
vpaint_stroke_done, 0);
|
||||
|
||||
|
||||
@@ -663,47 +663,6 @@ static bool sculpt_brush_test_cyl(SculptBrushTest *test, float co[3], float loca
|
||||
/* ===== Sculpting =====
|
||||
*
|
||||
*/
|
||||
|
||||
static float overlapped_curve(Brush *br, float x)
|
||||
{
|
||||
int i;
|
||||
const int n = 100 / br->spacing;
|
||||
const float h = br->spacing / 50.0f;
|
||||
const float x0 = x - 1;
|
||||
|
||||
float sum;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
float xx;
|
||||
|
||||
xx = fabsf(x0 + i * h);
|
||||
|
||||
if (xx < 1.0f)
|
||||
sum += BKE_brush_curve_strength(br, xx, 1);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static float integrate_overlap(Brush *br)
|
||||
{
|
||||
int i;
|
||||
int m = 10;
|
||||
float g = 1.0f / m;
|
||||
float max;
|
||||
|
||||
max = 0;
|
||||
for (i = 0; i < m; i++) {
|
||||
float overlap = overlapped_curve(br, i * g);
|
||||
|
||||
if (overlap > max)
|
||||
max = overlap;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
static void flip_v3(float v[3], const char symm)
|
||||
{
|
||||
flip_v3_v3(v, v, symm);
|
||||
@@ -776,7 +735,7 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache)
|
||||
/* Return modified brush strength. Includes the direction of the brush, positive
|
||||
* values pull vertices, negative values push. Uses tablet pressure and a
|
||||
* special multiplier found experimentally to scale the strength factor. */
|
||||
static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather)
|
||||
static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather, UnifiedPaintSettings *ups)
|
||||
{
|
||||
const Scene *scene = cache->vc->scene;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -788,13 +747,10 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather)
|
||||
float pressure = BKE_brush_use_alpha_pressure(scene, brush) ? cache->pressure : 1;
|
||||
float pen_flip = cache->pen_flip ? -1 : 1;
|
||||
float invert = cache->invert ? -1 : 1;
|
||||
float accum = integrate_overlap(brush);
|
||||
float overlap = ups->overlap_factor;
|
||||
/* spacing is integer percentage of radius, divide by 50 to get
|
||||
* normalized diameter */
|
||||
float overlap = (brush->flag & BRUSH_SPACE_ATTEN &&
|
||||
brush->flag & BRUSH_SPACE &&
|
||||
!(brush->flag & BRUSH_ANCHORED) &&
|
||||
(brush->spacing < 100)) ? 1.0f / accum : 1;
|
||||
|
||||
float flip = dir * invert * pen_flip;
|
||||
|
||||
switch (brush->sculpt_tool) {
|
||||
@@ -3377,7 +3333,7 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
|
||||
/* XXX This reduces the length of the grab delta if it approaches the line of symmetry
|
||||
* XXX However, a different approach appears to be needed */
|
||||
#if 0
|
||||
if (sd->flags & SCULPT_SYMMETRY_FEATHER) {
|
||||
if (sd->paint.symmetry_flags & SCULPT_SYMMETRY_FEATHER) {
|
||||
float frac = 1.0f / max_overlap_count(sd);
|
||||
float reduce = (feather - frac) / (1 - frac);
|
||||
|
||||
@@ -3437,7 +3393,7 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
|
||||
}
|
||||
|
||||
static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
|
||||
BrushActionFunc action)
|
||||
BrushActionFunc action, UnifiedPaintSettings *ups)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
@@ -3447,7 +3403,7 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
|
||||
|
||||
float feather = calc_symmetry_feather(sd, ss->cache);
|
||||
|
||||
cache->bstrength = brush_strength(sd, cache, feather);
|
||||
cache->bstrength = brush_strength(sd, cache, feather, ups);
|
||||
cache->symmetry = symm;
|
||||
|
||||
/* symm is a bit combination of XYZ - 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
|
||||
@@ -3733,8 +3689,8 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
|
||||
|
||||
/* not very nice, but with current events system implementation
|
||||
* we can't handle brush appearance inversion hotkey separately (sergey) */
|
||||
if (cache->invert) brush->flag |= BRUSH_INVERTED;
|
||||
else brush->flag &= ~BRUSH_INVERTED;
|
||||
if (cache->invert) ups->draw_inverted = true;
|
||||
else ups->draw_inverted = false;
|
||||
|
||||
/* Alt-Smooth */
|
||||
if (cache->alt_smooth) {
|
||||
@@ -3992,16 +3948,9 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
|
||||
cache->radius_squared = cache->radius * cache->radius;
|
||||
|
||||
if (brush->flag & BRUSH_ANCHORED) {
|
||||
/* true location has been calculated as part of the stroke system already here */
|
||||
if (brush->flag & BRUSH_EDGE_TO_EDGE) {
|
||||
float halfway[2];
|
||||
float out[3];
|
||||
halfway[0] = 0.5f * (cache->mouse[0] + cache->initial_mouse[0]);
|
||||
halfway[1] = 0.5f * (cache->mouse[1] + cache->initial_mouse[1]);
|
||||
|
||||
if (sculpt_stroke_get_location(C, out, halfway)) {
|
||||
copy_v3_v3(cache->anchored_location, out);
|
||||
copy_v3_v3(cache->true_location, cache->anchored_location);
|
||||
}
|
||||
RNA_float_get_array(ptr, "location", cache->true_location);
|
||||
}
|
||||
|
||||
cache->radius = paint_calc_object_space_radius(cache->vc,
|
||||
@@ -4393,10 +4342,10 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st
|
||||
}
|
||||
|
||||
if (sculpt_stroke_dynamic_topology(ss, brush)) {
|
||||
do_symmetrical_brush_actions(sd, ob, sculpt_topology_update);
|
||||
do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups);
|
||||
}
|
||||
|
||||
do_symmetrical_brush_actions(sd, ob, do_brush_action);
|
||||
do_symmetrical_brush_actions(sd, ob, do_brush_action, ups);
|
||||
|
||||
sculpt_combine_proxies(sd, ob);
|
||||
|
||||
@@ -4446,8 +4395,9 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
|
||||
|
||||
/* Finished */
|
||||
if (ss->cache) {
|
||||
UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
brush->flag &= ~BRUSH_INVERTED;
|
||||
ups->draw_inverted = false;
|
||||
|
||||
sculpt_stroke_modifiers_check(C, ob);
|
||||
|
||||
@@ -4506,7 +4456,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
if (!sculpt_brush_stroke_init(C, op))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
stroke = paint_stroke_new(C, sculpt_stroke_get_location,
|
||||
stroke = paint_stroke_new(C, op, sculpt_stroke_get_location,
|
||||
sculpt_stroke_test_start,
|
||||
sculpt_stroke_update_step, NULL,
|
||||
sculpt_stroke_done, event->type);
|
||||
@@ -4521,10 +4471,13 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
|
||||
paint_stroke_data_free(op);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
/* add modal handler */
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
retval = op->type->modal(C, op, event);
|
||||
OPERATOR_RETVAL_CHECK(retval);
|
||||
BLI_assert(retval == OPERATOR_RUNNING_MODAL);
|
||||
|
||||
@@ -4536,7 +4489,7 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
|
||||
if (!sculpt_brush_stroke_init(C, op))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
op->customdata = paint_stroke_new(C, sculpt_stroke_get_location, sculpt_stroke_test_start,
|
||||
op->customdata = paint_stroke_new(C, op, sculpt_stroke_get_location, sculpt_stroke_test_start,
|
||||
sculpt_stroke_update_step, NULL, sculpt_stroke_done, 0);
|
||||
|
||||
/* frees op->customdata */
|
||||
@@ -5062,11 +5015,11 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
|
||||
ts->sculpt->paint.flags |= PAINT_SHOW_BRUSH;
|
||||
|
||||
/* Make sure at least dyntopo subdivision is enabled */
|
||||
ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE;
|
||||
ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE;
|
||||
}
|
||||
|
||||
if (!ts->sculpt->detail_size) {
|
||||
ts->sculpt->detail_size = 30;
|
||||
ts->sculpt->detail_size = 12;
|
||||
}
|
||||
|
||||
if (ts->sculpt->constant_detail == 0.0f)
|
||||
|
||||
@@ -543,7 +543,7 @@ static void sculpt_undo_free(ListBase *lb)
|
||||
}
|
||||
}
|
||||
|
||||
bool sculpt_undo_cleanup(bContext *C, ListBase *lb)
|
||||
static bool sculpt_undo_cleanup(bContext *C, ListBase *lb)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
SculptUndoNode *unode;
|
||||
@@ -551,10 +551,8 @@ bool sculpt_undo_cleanup(bContext *C, ListBase *lb)
|
||||
unode = lb->first;
|
||||
|
||||
if (unode && strcmp(unode->idname, ob->id.name) != 0) {
|
||||
for (unode = lb->first; unode; unode = unode->next) {
|
||||
if (unode->bm_entry)
|
||||
BM_log_cleanup_entry(unode->bm_entry);
|
||||
}
|
||||
if (unode->bm_entry)
|
||||
BM_log_cleanup_entry(unode->bm_entry);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -881,7 +879,7 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
|
||||
void sculpt_undo_push_begin(const char *name)
|
||||
{
|
||||
ED_undo_paint_push_begin(UNDO_PAINT_MESH, name,
|
||||
sculpt_undo_restore, sculpt_undo_free);
|
||||
sculpt_undo_restore, sculpt_undo_free, sculpt_undo_cleanup);
|
||||
}
|
||||
|
||||
void sculpt_undo_push_end(void)
|
||||
|
||||
@@ -144,6 +144,7 @@ void ED_spacetypes_init(void)
|
||||
ED_operatormacros_curve();
|
||||
ED_operatormacros_mask();
|
||||
ED_operatormacros_sequencer();
|
||||
ED_operatormacros_paint();
|
||||
|
||||
/* register dropboxes (can use macros) */
|
||||
spacetypes = BKE_spacetypes_list();
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
* \ingroup spimage
|
||||
*/
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_mask_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
@@ -297,44 +298,51 @@ bool ED_space_image_show_render(SpaceImage *sima)
|
||||
bool ED_space_image_show_paint(SpaceImage *sima)
|
||||
{
|
||||
if (ED_space_image_show_render(sima))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
return (sima->mode == SI_MODE_PAINT);
|
||||
}
|
||||
|
||||
bool ED_space_image_show_texpaint(SpaceImage *sima, Object *ob)
|
||||
{
|
||||
return (ob && ob->type == OB_MESH &&
|
||||
ob->mode == OB_MODE_TEXTURE_PAINT &&
|
||||
!(sima->flag & SI_NO_DRAW_TEXPAINT));
|
||||
}
|
||||
|
||||
bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
|
||||
{
|
||||
if (sima && (ED_space_image_show_render(sima) || ED_space_image_show_paint(sima)))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (obedit && obedit->type == OB_MESH) {
|
||||
struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
int ret;
|
||||
bool ret;
|
||||
|
||||
ret = EDBM_mtexpoly_check(em);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
|
||||
{
|
||||
if (ED_space_image_show_render(sima))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (ED_space_image_show_paint(sima))
|
||||
if (obedit && obedit->type == OB_MESH) {
|
||||
struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
int ret;
|
||||
bool ret;
|
||||
|
||||
ret = EDBM_mtexpoly_check(em);
|
||||
|
||||
return ret;
|
||||
return ret && !(sima->flag & SI_NO_DRAW_TEXPAINT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* matches clip function */
|
||||
@@ -361,6 +369,21 @@ int ED_space_image_maskedit_poll(bContext *C)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ED_space_image_paint_curve(const bContext *C)
|
||||
{
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
|
||||
if (sima && sima->mode == SI_MODE_PAINT) {
|
||||
Brush *br = CTX_data_tool_settings(C)->imapaint.paint.brush;
|
||||
|
||||
if (br && (br->flag & BRUSH_CURVE))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int ED_space_image_maskedit_mask_poll(bContext *C)
|
||||
{
|
||||
if (ED_space_image_maskedit_poll(C)) {
|
||||
|
||||
@@ -1896,6 +1896,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
|
||||
SpaceImage *sima;
|
||||
Scene *scene;
|
||||
Object *obedit;
|
||||
Object *ob;
|
||||
Image *ima;
|
||||
Main *bmain;
|
||||
PointerRNA ptr, idptr;
|
||||
@@ -1910,6 +1911,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
|
||||
scene = CTX_data_scene(C);
|
||||
obedit = CTX_data_edit_object(C);
|
||||
bmain = CTX_data_main(C);
|
||||
ob = OBACT;
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "name");
|
||||
RNA_property_string_get(op->ptr, prop, name);
|
||||
@@ -1955,6 +1957,13 @@ static int image_new_exec(bContext *C, wmOperator *op)
|
||||
tex->ima = ima;
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
}
|
||||
else if (ob && ob->mode == OB_MODE_TEXTURE_PAINT) {
|
||||
ImagePaintSettings *imapaint = &(CTX_data_tool_settings(C)->imapaint);
|
||||
|
||||
if (imapaint->stencil)
|
||||
id_us_min(&imapaint->stencil->id);
|
||||
imapaint->stencil = ima;
|
||||
}
|
||||
}
|
||||
|
||||
BKE_image_signal(ima, (sima) ? &sima->iuser : NULL, IMA_SIGNAL_USER_NEW_IMAGE);
|
||||
@@ -2037,7 +2046,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
|
||||
|
||||
if (support_undo) {
|
||||
ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
|
||||
ED_image_undo_restore, ED_image_undo_free);
|
||||
ED_image_undo_restore, ED_image_undo_free, NULL);
|
||||
/* not strictly needed, because we only imapaint_dirty_region to invalidate all tiles
|
||||
* but better do this right in case someone copies this for a tool that uses partial redraw better */
|
||||
ED_imapaint_clear_partial_redraw();
|
||||
|
||||
@@ -633,6 +633,12 @@ static void image_main_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
|
||||
|
||||
/* image paint polls for mode */
|
||||
keymap = WM_keymap_find(wm->defaultconf, "Curve", 0, 0);
|
||||
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
|
||||
|
||||
keymap = WM_keymap_find(wm->defaultconf, "Paint Curve", 0, 0);
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
|
||||
keymap = WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
|
||||
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
|
||||
|
||||
@@ -657,6 +663,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
|
||||
Object *obact = CTX_data_active_object(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Mask *mask = NULL;
|
||||
bool curve = false;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View2D *v2d = &ar->v2d;
|
||||
//View2DScrollers *scrollers;
|
||||
@@ -702,6 +709,9 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
|
||||
else if (sima->mode == SI_MODE_MASK) {
|
||||
mask = ED_space_image_get_mask(sima);
|
||||
}
|
||||
else if (ED_space_image_paint_curve(C)) {
|
||||
curve = true;
|
||||
}
|
||||
|
||||
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
|
||||
|
||||
@@ -753,6 +763,11 @@ static void image_main_area_draw(const bContext *C, ARegion *ar)
|
||||
draw_image_cursor(ar, sima->cursor);
|
||||
UI_view2d_view_restore(C);
|
||||
}
|
||||
else if (curve) {
|
||||
UI_view2d_view_ortho(v2d);
|
||||
draw_image_cursor(ar, sima->cursor);
|
||||
UI_view2d_view_restore(C);
|
||||
}
|
||||
|
||||
draw_image_cache(C, ar);
|
||||
|
||||
|
||||
@@ -212,12 +212,16 @@ static Material *give_current_material_or_def(Object *ob, int matnr)
|
||||
|
||||
static struct TextureDrawState {
|
||||
Object *ob;
|
||||
Image *stencil;
|
||||
bool stencil_invert;
|
||||
bool use_game_mat;
|
||||
int is_lit, is_tex;
|
||||
int color_profile;
|
||||
bool use_backface_culling;
|
||||
unsigned char obcol[4];
|
||||
} Gtexdraw = {NULL, false, 0, 0, 0, false, {0, 0, 0, 0}};
|
||||
float stencil_col[4];
|
||||
bool is_texpaint;
|
||||
} Gtexdraw = {NULL, NULL, false, false, 0, 0, 0, false, {0, 0, 0, 0}, {0.0f, 0.0f, 0.0f, 1.0f}, false};
|
||||
|
||||
static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
|
||||
{
|
||||
@@ -229,13 +233,15 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
|
||||
static int c_lit;
|
||||
static int c_has_texface;
|
||||
|
||||
Object *litob = NULL; /* to get mode to turn off mipmap in painting mode */
|
||||
int backculled = 1;
|
||||
int alphablend = GPU_BLEND_SOLID;
|
||||
int textured = 0;
|
||||
int lit = 0;
|
||||
int has_texface = texface != NULL;
|
||||
bool need_set_tpage = false;
|
||||
bool texpaint = ((gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) != 0);
|
||||
|
||||
Image *ima = NULL;
|
||||
|
||||
if (ma != NULL) {
|
||||
if (ma->mode & MA_TRANSP) {
|
||||
@@ -248,10 +254,10 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
|
||||
memset(&c_texface, 0, sizeof(MTFace));
|
||||
c_badtex = false;
|
||||
c_has_texface = -1;
|
||||
c_ma = NULL;
|
||||
}
|
||||
else {
|
||||
textured = gtexdraw.is_tex;
|
||||
litob = gtexdraw.ob;
|
||||
}
|
||||
|
||||
/* convert number of lights into boolean */
|
||||
@@ -266,14 +272,16 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
|
||||
}
|
||||
}
|
||||
|
||||
if (texface) {
|
||||
if (texface && !texpaint) {
|
||||
textured = textured && (texface->tpage);
|
||||
|
||||
/* no material, render alpha if texture has depth=32 */
|
||||
if (!ma && BKE_image_has_alpha(texface->tpage))
|
||||
alphablend = GPU_BLEND_ALPHA;
|
||||
}
|
||||
|
||||
else if (texpaint && ma) {
|
||||
ima = ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
|
||||
}
|
||||
else
|
||||
textured = 0;
|
||||
|
||||
@@ -287,11 +295,25 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
|
||||
/* need to re-set tpage if textured flag changed or existsment of texface changed.. */
|
||||
need_set_tpage = textured != c_textured || has_texface != c_has_texface;
|
||||
/* ..or if settings inside texface were changed (if texface was used) */
|
||||
need_set_tpage |= texface && memcmp(&c_texface, texface, sizeof(c_texface));
|
||||
need_set_tpage |= (texpaint && c_ma != ma) || (texface && memcmp(&c_texface, texface, sizeof(c_texface)));
|
||||
|
||||
if (need_set_tpage) {
|
||||
if (textured) {
|
||||
c_badtex = !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
|
||||
if (texpaint) {
|
||||
c_badtex = false;
|
||||
if (GPU_verify_image(ima, NULL, 0, 1, 0, false)) {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
else {
|
||||
c_badtex = true;
|
||||
GPU_clear_tpage(true);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
c_badtex = !GPU_set_tpage(texface, !texpaint, alphablend);
|
||||
}
|
||||
}
|
||||
else {
|
||||
GPU_set_tpage(NULL, 0, 0);
|
||||
@@ -325,6 +347,7 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
}
|
||||
c_lit = lit;
|
||||
c_ma = ma;
|
||||
}
|
||||
|
||||
return c_badtex;
|
||||
@@ -335,6 +358,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
|
||||
unsigned char obcol[4];
|
||||
bool is_tex, solidtex;
|
||||
Mesh *me = ob->data;
|
||||
ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
|
||||
|
||||
/* XXX scene->obedit warning */
|
||||
|
||||
@@ -364,8 +388,34 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
|
||||
else is_tex = false;
|
||||
|
||||
Gtexdraw.ob = ob;
|
||||
Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL;
|
||||
Gtexdraw.stencil_invert = ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0);
|
||||
Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT);
|
||||
copy_v3_v3(Gtexdraw.stencil_col, imapaint->stencil_col);
|
||||
Gtexdraw.is_tex = is_tex;
|
||||
|
||||
/* load the stencil texture here */
|
||||
if (Gtexdraw.is_texpaint && (Gtexdraw.stencil != NULL)) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
if (GPU_verify_image(Gtexdraw.stencil, NULL, false, false, false, false)) {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, Gtexdraw.stencil_col);
|
||||
if (!Gtexdraw.stencil_invert) {
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR);
|
||||
}
|
||||
else {
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
|
||||
}
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
|
||||
Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0;
|
||||
Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
|
||||
@@ -379,8 +429,24 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
|
||||
|
||||
static void draw_textured_end(void)
|
||||
{
|
||||
/* switch off textures */
|
||||
GPU_set_tpage(NULL, 0, 0);
|
||||
if (Gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) {
|
||||
if (Gtexdraw.stencil != NULL) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
/* manual reset, since we don't use tpage */
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
/* force switch off textures */
|
||||
GPU_clear_tpage(true);
|
||||
}
|
||||
else {
|
||||
/* switch off textures */
|
||||
GPU_set_tpage(NULL, 0, 0);
|
||||
}
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
@@ -456,7 +522,7 @@ static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mc
|
||||
|
||||
if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
|
||||
|
||||
if (tface)
|
||||
if (tface || Gtexdraw.is_texpaint)
|
||||
set_draw_settings_cached(0, tface, ma, Gtexdraw);
|
||||
|
||||
/* always use color from mcol, as set in update_tface_color_layer */
|
||||
@@ -770,7 +836,8 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
|
||||
Object *ob, DerivedMesh *dm, const int draw_flags)
|
||||
{
|
||||
Mesh *me = ob->data;
|
||||
|
||||
DMDrawFlag uvflag = DM_DRAW_USE_ACTIVE_UV;
|
||||
|
||||
/* correct for negative scale */
|
||||
if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
|
||||
else glFrontFace(GL_CCW);
|
||||
@@ -780,6 +847,10 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (ob->mode & OB_MODE_TEXTURE_PAINT) {
|
||||
uvflag = DM_DRAW_USE_TEXPAINT_UV;
|
||||
}
|
||||
|
||||
if (ob->mode & OB_MODE_EDIT) {
|
||||
drawEMTFMapped_userData data;
|
||||
|
||||
@@ -789,7 +860,7 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
|
||||
data.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
|
||||
data.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
|
||||
dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
|
||||
dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data, 0);
|
||||
}
|
||||
else if (draw_flags & DRAW_FACE_SELECT) {
|
||||
if (ob->mode & OB_MODE_WEIGHT_PAINT)
|
||||
@@ -801,15 +872,15 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
|
||||
userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
|
||||
userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
userData.me = me;
|
||||
dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData);
|
||||
dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData, uvflag);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (GPU_buffer_legacy(dm)) {
|
||||
if (draw_flags & DRAW_MODIFIERS_PREVIEW)
|
||||
dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
|
||||
dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL, uvflag);
|
||||
else
|
||||
dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
|
||||
dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL, uvflag);
|
||||
}
|
||||
else {
|
||||
drawTFace_userData userData;
|
||||
@@ -820,7 +891,7 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d
|
||||
userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
||||
userData.me = NULL;
|
||||
|
||||
dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
|
||||
dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -955,7 +1026,8 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
|
||||
/* if not cycles, or preview-modifiers, or drawing matcaps */
|
||||
if ((draw_flags & DRAW_MODIFIERS_PREVIEW) ||
|
||||
(v3d->flag2 & V3D_SHOW_SOLID_MATCAP) ||
|
||||
(BKE_scene_use_new_shading_nodes(scene) == false))
|
||||
(BKE_scene_use_new_shading_nodes(scene) == false) ||
|
||||
((ob->mode & OB_MODE_TEXTURE_PAINT) && ELEM(v3d->drawtype, OB_TEXTURE, OB_SOLID)))
|
||||
{
|
||||
draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
|
||||
return;
|
||||
|
||||
@@ -301,7 +301,7 @@ bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
|
||||
if (BKE_scene_use_new_shading_nodes(scene))
|
||||
return false;
|
||||
|
||||
return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
|
||||
return ((scene->gm.matmode == GAME_MAT_GLSL) || (v3d->drawtype == OB_MATERIAL)) && (dt > OB_SOLID);
|
||||
}
|
||||
|
||||
static bool check_alpha_pass(Base *base)
|
||||
|
||||
@@ -483,6 +483,12 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
|
||||
keymap = WM_keymap_find(wm->defaultconf, "Object Mode", 0, 0);
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
|
||||
keymap = WM_keymap_find(wm->defaultconf, "Paint Curve", 0, 0);
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
|
||||
keymap = WM_keymap_find(wm->defaultconf, "Curve", 0, 0);
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
|
||||
keymap = WM_keymap_find(wm->defaultconf, "Image Paint", 0, 0);
|
||||
WM_event_add_keymap_handler(&ar->handlers, keymap);
|
||||
|
||||
@@ -673,7 +679,7 @@ static void view3d_dropboxes(void)
|
||||
WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_mesh_drop_poll, view3d_id_path_drop_copy);
|
||||
WM_dropbox_add(lb, "OBJECT_OT_drop_named_image", view3d_ima_empty_drop_poll, view3d_id_path_drop_copy);
|
||||
WM_dropbox_add(lb, "VIEW3D_OT_background_image_add", view3d_ima_bg_drop_poll, view3d_id_path_drop_copy);
|
||||
WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
|
||||
WM_dropbox_add(lb, "OBJECT_OT_group_instance_add", view3d_group_drop_poll, view3d_group_drop_copy);
|
||||
}
|
||||
|
||||
|
||||
@@ -860,14 +866,18 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN
|
||||
switch (wmn->data) {
|
||||
case ND_SHADING:
|
||||
case ND_NODES:
|
||||
{
|
||||
Object *ob = OBACT;
|
||||
if ((v3d->drawtype == OB_MATERIAL) ||
|
||||
(ob && (ob->mode == OB_MODE_TEXTURE_PAINT)) ||
|
||||
(v3d->drawtype == OB_TEXTURE &&
|
||||
(scene->gm.matmode == GAME_MAT_GLSL ||
|
||||
BKE_scene_use_new_shading_nodes(scene))))
|
||||
(scene->gm.matmode == GAME_MAT_GLSL ||
|
||||
BKE_scene_use_new_shading_nodes(scene))))
|
||||
{
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ND_SHADING_DRAW:
|
||||
case ND_SHADING_LINKS:
|
||||
ED_region_tag_redraw(ar);
|
||||
@@ -1099,6 +1109,11 @@ static void view3d_buttons_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa
|
||||
if (wmn->data == ND_DATA || wmn->action == NA_EDITED)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_IMAGE:
|
||||
/* Update for the image layers in texture paint. */
|
||||
if (wmn->action == NA_EDITED)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1287,6 +1287,12 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
/* texture paint mode sampling */
|
||||
else if (base && (base->object->mode & OB_MODE_TEXTURE_PAINT) &&
|
||||
(v3d->drawtype > OB_WIRE))
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
|
||||
v3d->drawtype > OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT))
|
||||
{
|
||||
@@ -2509,7 +2515,7 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
|
||||
mask |= CD_MASK_ORCO;
|
||||
}
|
||||
else {
|
||||
if (scene->gm.matmode == GAME_MAT_GLSL)
|
||||
if (scene->gm.matmode == GAME_MAT_GLSL || v3d->drawtype == OB_MATERIAL)
|
||||
mask |= CD_MASK_ORCO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4435,7 +4435,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_cursor3d_update(bContext *C, const int *mval)
|
||||
void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
@@ -4451,7 +4451,7 @@ static void view3d_cursor3d_update(bContext *C, const int *mval)
|
||||
|
||||
static int view3d_cursor3d_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
view3d_cursor3d_update(C, event->mval);
|
||||
ED_view3d_cursor3d_update(C, event->mval);
|
||||
op->customdata = SET_INT_IN_POINTER(event->type);
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
@@ -4468,7 +4468,7 @@ static int view3d_cursor3d_modal(bContext *C, wmOperator *op, const wmEvent *eve
|
||||
|
||||
switch (event->type) {
|
||||
case MOUSEMOVE:
|
||||
view3d_cursor3d_update(C, event->mval);
|
||||
ED_view3d_cursor3d_update(C, event->mval);
|
||||
break;
|
||||
case LEFTMOUSE:
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
@@ -45,6 +46,7 @@
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_editmesh.h"
|
||||
|
||||
@@ -336,8 +338,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
|
||||
uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
||||
|
||||
if (obedit == NULL && is_paint) {
|
||||
|
||||
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
|
||||
if (ob->mode & OB_MODE_ALL_PAINT) {
|
||||
/* Only for Weight Paint. makes no sense in other paint modes. */
|
||||
row = uiLayoutRow(layout, true);
|
||||
uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
||||
|
||||
@@ -192,7 +192,7 @@ static bool transdata_check_local_center(TransInfo *t, short around)
|
||||
(t->flag & (T_OBJECT | T_POSE)) ||
|
||||
(t->obedit && ELEM(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE)) ||
|
||||
(t->spacetype == SPACE_IPO) ||
|
||||
(t->options & (CTX_MOVIECLIP | CTX_MASK)))
|
||||
(t->options & (CTX_MOVIECLIP | CTX_MASK | CTX_PAINT_CURVE)))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -263,17 +263,27 @@ static void convertViewVec2D_mask(View2D *v2d, float r_vec[3], int dx, int dy)
|
||||
void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
|
||||
{
|
||||
if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) {
|
||||
const float mval_f[2] = {(float)dx, (float)dy};
|
||||
ED_view3d_win_to_delta(t->ar, mval_f, r_vec, t->zfac);
|
||||
if (t->options & CTX_PAINT_CURVE) {
|
||||
r_vec[0] = dx;
|
||||
r_vec[1] = dy;
|
||||
}
|
||||
else { const float mval_f[2] = {(float)dx, (float)dy};
|
||||
ED_view3d_win_to_delta(t->ar, mval_f, r_vec, t->zfac);
|
||||
}
|
||||
}
|
||||
else if (t->spacetype == SPACE_IMAGE) {
|
||||
float aspx, aspy;
|
||||
|
||||
if (t->options & CTX_MASK) {
|
||||
|
||||
convertViewVec2D_mask(t->view, r_vec, dx, dy);
|
||||
ED_space_image_get_aspect(t->sa->spacedata.first, &aspx, &aspy);
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
r_vec[0] = dx;
|
||||
r_vec[1] = dy;
|
||||
|
||||
aspx = aspy = 1.0;
|
||||
}
|
||||
else {
|
||||
convertViewVec2D(t->view, r_vec, dx, dy);
|
||||
ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
|
||||
@@ -351,6 +361,10 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
|
||||
adr[0] = v[0];
|
||||
adr[1] = v[1];
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
adr[0] = vec[0];
|
||||
adr[1] = vec[1];
|
||||
}
|
||||
else {
|
||||
float aspx, aspy, v[2];
|
||||
|
||||
@@ -452,7 +466,11 @@ void projectFloatViewEx(TransInfo *t, const float vec[3], float adr[2], const eV
|
||||
switch (t->spacetype) {
|
||||
case SPACE_VIEW3D:
|
||||
{
|
||||
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
|
||||
if (t->options & CTX_PAINT_CURVE) {
|
||||
adr[0] = vec[0];
|
||||
adr[1] = vec[1];
|
||||
}
|
||||
else if (t->ar->regiontype == RGN_TYPE_WINDOW) {
|
||||
/* allow points behind the view [#33643] */
|
||||
if (ED_view3d_project_float_global(t->ar, vec, adr, flag) != V3D_PROJ_RET_OK) {
|
||||
/* XXX, 2.64 and prior did this, weak! */
|
||||
@@ -480,7 +498,7 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
|
||||
|
||||
void applyAspectRatio(TransInfo *t, float vec[2])
|
||||
{
|
||||
if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION)) {
|
||||
if ((t->spacetype == SPACE_IMAGE) && (t->mode == TFM_TRANSLATION) && !(t->options & CTX_PAINT_CURVE)) {
|
||||
SpaceImage *sima = t->sa->spacedata.first;
|
||||
float aspx, aspy;
|
||||
|
||||
@@ -557,17 +575,23 @@ void removeAspectRatio(TransInfo *t, float vec[2])
|
||||
static void viewRedrawForce(const bContext *C, TransInfo *t)
|
||||
{
|
||||
if (t->spacetype == SPACE_VIEW3D) {
|
||||
/* Do we need more refined tags? */
|
||||
if (t->flag & T_POSE)
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
|
||||
else
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
|
||||
if (t->options & CTX_PAINT_CURVE) {
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
WM_paint_cursor_tag_redraw(window, t->ar);
|
||||
}
|
||||
else {
|
||||
/* Do we need more refined tags? */
|
||||
if (t->flag & T_POSE)
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
|
||||
else
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
|
||||
|
||||
/* for realtime animation record - send notifiers recognised by animation editors */
|
||||
// XXX: is this notifier a lame duck?
|
||||
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene))
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
|
||||
|
||||
/* for realtime animation record - send notifiers recognised by animation editors */
|
||||
// XXX: is this notifier a lame duck?
|
||||
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene))
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
|
||||
|
||||
}
|
||||
}
|
||||
else if (t->spacetype == SPACE_ACTION) {
|
||||
//SpaceAction *saction = (SpaceAction *)t->sa->spacedata.first;
|
||||
@@ -593,6 +617,10 @@ static void viewRedrawForce(const bContext *C, TransInfo *t)
|
||||
|
||||
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
wmWindow *window = CTX_wm_window(C);
|
||||
WM_paint_cursor_tag_redraw(window, t->ar);
|
||||
}
|
||||
else {
|
||||
// XXX how to deal with lock?
|
||||
SpaceImage *sima = (SpaceImage *)t->sa->spacedata.first;
|
||||
@@ -3592,8 +3620,15 @@ static void initRotation(TransInfo *t)
|
||||
if (t->flag & T_2D_EDIT)
|
||||
t->flag |= T_NO_CONSTRAINT;
|
||||
|
||||
negate_v3_v3(t->axis, t->viewinv[2]);
|
||||
normalize_v3(t->axis);
|
||||
if (t->options & CTX_PAINT_CURVE) {
|
||||
t->axis[0] = 0.0;
|
||||
t->axis[1] = 0.0;
|
||||
t->axis[2] = -1.0;
|
||||
}
|
||||
else {
|
||||
negate_v3_v3(t->axis, t->viewinv[2]);
|
||||
normalize_v3(t->axis);
|
||||
}
|
||||
|
||||
copy_v3_v3(t->axis_orig, t->axis);
|
||||
}
|
||||
|
||||
@@ -532,6 +532,7 @@ void flushTransNodes(TransInfo *t);
|
||||
void flushTransSeq(TransInfo *t);
|
||||
void flushTransTracking(TransInfo *t);
|
||||
void flushTransMasking(TransInfo *t);
|
||||
void flushTransPaintCurve(TransInfo *t);
|
||||
void restoreBones(TransInfo *t);
|
||||
|
||||
/*********************** exported from transform_manipulator.c ********** */
|
||||
|
||||
@@ -756,6 +756,9 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
|
||||
/* untested - mask aspect is TODO */
|
||||
ED_space_image_get_aspect(t->sa->spacedata.first, &aspx, &aspy);
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
aspx = aspy = 1.0;
|
||||
}
|
||||
else {
|
||||
ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
@@ -80,6 +81,7 @@
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_rigidbody.h"
|
||||
@@ -5847,6 +5849,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
/* pass */
|
||||
}
|
||||
else if ((t->scene->basact) &&
|
||||
(ob = t->scene->basact->object) &&
|
||||
(ob->mode & OB_MODE_PARTICLE_EDIT) &&
|
||||
@@ -7026,6 +7031,172 @@ void flushTransMasking(TransInfo *t)
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct TransDataPaintCurve {
|
||||
PaintCurvePoint *pcp; /* initial curve point */
|
||||
char id;
|
||||
} TransDataPaintCurve;
|
||||
|
||||
|
||||
#define PC_IS_ANY_SEL(pc) (((pc)->bez.f1 | (pc)->bez.f2 | (pc)->bez.f3) & SELECT)
|
||||
|
||||
static void PaintCurveConvertHandle(PaintCurvePoint *pcp, int id, TransData2D *td2d, TransDataPaintCurve *tdpc, TransData *td) {
|
||||
BezTriple *bezt = &pcp->bez;
|
||||
copy_v2_v2(td2d->loc, bezt->vec[id]);
|
||||
td2d->loc[2] = 0.0f;
|
||||
td2d->loc2d = bezt->vec[id];
|
||||
|
||||
td->flag = 0;
|
||||
td->loc = td2d->loc;
|
||||
copy_v3_v3(td->center, bezt->vec[1]);
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
td->flag |= TD_SELECTED;
|
||||
td->dist = 0.0;
|
||||
|
||||
unit_m3(td->mtx);
|
||||
unit_m3(td->smtx);
|
||||
|
||||
tdpc->id = id;
|
||||
tdpc->pcp = pcp;
|
||||
}
|
||||
|
||||
static void PaintCurvePointToTransData(PaintCurvePoint *pcp, TransData *td, TransData2D *td2d, TransDataPaintCurve *tdpc)
|
||||
{
|
||||
BezTriple *bezt = &pcp->bez;
|
||||
|
||||
if (pcp->bez.f2 == SELECT) {
|
||||
int i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
copy_v2_v2(td2d->loc, bezt->vec[i]);
|
||||
td2d->loc[2] = 0.0f;
|
||||
td2d->loc2d = bezt->vec[i];
|
||||
|
||||
td->flag = 0;
|
||||
td->loc = td2d->loc;
|
||||
copy_v3_v3(td->center, bezt->vec[1]);
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
td->flag |= TD_SELECTED;
|
||||
td->dist = 0.0;
|
||||
|
||||
unit_m3(td->mtx);
|
||||
unit_m3(td->smtx);
|
||||
|
||||
tdpc->id = i;
|
||||
tdpc->pcp = pcp;
|
||||
|
||||
td++;
|
||||
td2d++;
|
||||
tdpc++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (bezt->f3 & SELECT) {
|
||||
PaintCurveConvertHandle(pcp, 2, td2d, tdpc, td);
|
||||
td2d++;
|
||||
tdpc++;
|
||||
td++;
|
||||
}
|
||||
|
||||
if (bezt->f1 & SELECT) {
|
||||
PaintCurveConvertHandle(pcp, 0, td2d, tdpc, td);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createTransPaintCurveVerts(bContext *C, TransInfo *t)
|
||||
{
|
||||
Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
PaintCurve *pc;
|
||||
PaintCurvePoint *pcp;
|
||||
Brush *br;
|
||||
TransData *td = NULL;
|
||||
TransData2D *td2d = NULL;
|
||||
TransDataPaintCurve *tdpc = NULL;
|
||||
int i;
|
||||
int total = 0;
|
||||
|
||||
t->total = 0;
|
||||
|
||||
if (!paint || !paint->brush || !paint->brush->paint_curve)
|
||||
return;
|
||||
|
||||
br = paint->brush;
|
||||
pc = br->paint_curve;
|
||||
|
||||
for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) {
|
||||
if (PC_IS_ANY_SEL(pcp)) {
|
||||
if (pcp->bez.f2 & SELECT) {
|
||||
total += 3;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if (pcp->bez.f1 & SELECT)
|
||||
total++;
|
||||
if (pcp->bez.f3 & SELECT)
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!total)
|
||||
return;
|
||||
|
||||
t->total = total;
|
||||
td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransData2D");
|
||||
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransData");
|
||||
tdpc = t->customData = MEM_callocN(t->total * sizeof(TransDataPaintCurve), "TransDataPaintCurve");
|
||||
t->flag |= T_FREE_CUSTOMDATA;
|
||||
|
||||
for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) {
|
||||
if (PC_IS_ANY_SEL(pcp)) {
|
||||
PaintCurvePointToTransData (pcp, td, td2d, tdpc);
|
||||
|
||||
if (pcp->bez.f2 & SELECT) {
|
||||
td += 3;
|
||||
td2d += 3;
|
||||
tdpc += 3;
|
||||
}
|
||||
else {
|
||||
if (pcp->bez.f1 & SELECT) {
|
||||
td++;
|
||||
td2d++;
|
||||
tdpc++;
|
||||
}
|
||||
if (pcp->bez.f3 & SELECT) {
|
||||
td++;
|
||||
td2d++;
|
||||
tdpc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void flushTransPaintCurve(TransInfo *t)
|
||||
{
|
||||
int i;
|
||||
TransData2D *td2d = t->data2d;
|
||||
TransDataPaintCurve *tdpc = (TransDataPaintCurve *)t->customData;
|
||||
|
||||
for (i = 0; i < t->total; i++, tdpc++, td2d++) {
|
||||
PaintCurvePoint *pcp = tdpc->pcp;
|
||||
copy_v2_v2(pcp->bez.vec[tdpc->id], td2d->loc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void createTransData(bContext *C, TransInfo *t)
|
||||
{
|
||||
Scene *scene = t->scene;
|
||||
@@ -7058,6 +7229,10 @@ void createTransData(bContext *C, TransInfo *t)
|
||||
sort_trans_data_dist(t);
|
||||
}
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
if(!ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN))
|
||||
createTransPaintCurveVerts(C, t);
|
||||
}
|
||||
else if (t->obedit) {
|
||||
createTransUVs(C, t);
|
||||
if (t->data && (t->flag & T_PROP_EDIT)) {
|
||||
@@ -7164,7 +7339,7 @@ void createTransData(bContext *C, TransInfo *t)
|
||||
// XXX active-layer checking isn't done as that should probably be checked through context instead
|
||||
createTransPose(t, ob);
|
||||
}
|
||||
else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
|
||||
else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
|
||||
/* important that ob_armature can be set even when its not selected [#23412]
|
||||
* lines below just check is also visible */
|
||||
Object *ob_armature = modifiers_isDeformedByArmature(ob);
|
||||
@@ -7189,12 +7364,11 @@ void createTransData(bContext *C, TransInfo *t)
|
||||
sort_trans_data_dist(t);
|
||||
}
|
||||
}
|
||||
else if (ob && (ob->mode & (OB_MODE_ALL_PAINT))) {
|
||||
/* sculpt mode and project paint have own undo stack
|
||||
* transform ops redo clears sculpt/project undo stack.
|
||||
*
|
||||
* Could use 'OB_MODE_ALL_PAINT' since there are key conflicts,
|
||||
* transform + paint isn't well supported. */
|
||||
else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) {
|
||||
if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
|
||||
t->flag |= T_POINTS | T_2D_EDIT;
|
||||
createTransPaintCurveVerts(C, t);
|
||||
}
|
||||
}
|
||||
else {
|
||||
createTransObject(C, t);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
@@ -74,6 +75,7 @@
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_tracking.h"
|
||||
@@ -98,6 +100,7 @@
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "transform.h"
|
||||
|
||||
@@ -653,6 +656,9 @@ static void recalcData_image(TransInfo *t)
|
||||
if (t->options & CTX_MASK) {
|
||||
recalcData_mask_common(t);
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
flushTransPaintCurve(t);
|
||||
}
|
||||
else if (t->obedit && t->obedit->type == OB_MESH) {
|
||||
SpaceImage *sima = t->sa->spacedata.first;
|
||||
|
||||
@@ -965,6 +971,9 @@ void recalcData(TransInfo *t)
|
||||
else if (t->options & CTX_EDGE) {
|
||||
recalcData_objects(t);
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
flushTransPaintCurve(t);
|
||||
}
|
||||
else if (t->spacetype == SPACE_IMAGE) {
|
||||
recalcData_image(t);
|
||||
}
|
||||
@@ -1073,6 +1082,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
PropertyRNA *prop;
|
||||
|
||||
t->scene = sce;
|
||||
@@ -1198,6 +1208,13 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
}
|
||||
}
|
||||
|
||||
if (ob && ob->mode & OB_MODE_ALL_PAINT) {
|
||||
Paint *p = BKE_paint_get_active_from_context(C);
|
||||
if (p && p->brush && (p->brush->flag & BRUSH_CURVE)) {
|
||||
t->options |= CTX_PAINT_CURVE;
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize UV transform from */
|
||||
if (op && ((prop = RNA_struct_find_property(op->ptr, "correct_uv")))) {
|
||||
if (RNA_property_is_set(op->ptr, prop)) {
|
||||
@@ -1226,9 +1243,13 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
else if (sima->mode == SI_MODE_MASK) {
|
||||
t->options |= CTX_MASK;
|
||||
}
|
||||
else {
|
||||
/* image not in uv edit, nor in mask mode, can happen for some tools */
|
||||
else if (sima->mode == SI_MODE_PAINT) {
|
||||
Paint *p = &sce->toolsettings->imapaint.paint;
|
||||
if (p->brush && (p->brush->flag & BRUSH_CURVE)) {
|
||||
t->options |= CTX_PAINT_CURVE;
|
||||
}
|
||||
}
|
||||
/* image not in uv edit, nor in mask mode, can happen for some tools */
|
||||
}
|
||||
else if (t->spacetype == SPACE_NODE) {
|
||||
// XXX for now, get View2D from the active region
|
||||
@@ -1409,7 +1430,7 @@ void postTrans(bContext *C, TransInfo *t)
|
||||
}
|
||||
|
||||
if (t->spacetype == SPACE_IMAGE) {
|
||||
if (t->options & CTX_MASK) {
|
||||
if (t->options & (CTX_MASK | CTX_PAINT_CURVE)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
@@ -1539,6 +1560,13 @@ void calculateCenterCursor(TransInfo *t, float r_center[3])
|
||||
invert_m3_m3(imat, mat);
|
||||
mul_m3_v3(imat, r_center);
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
if (ED_view3d_project_float_global(t->ar, cursor, r_center, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
|
||||
r_center[0] = t->ar->winx / 2.0f;
|
||||
r_center[1] = t->ar->winy / 2.0f;
|
||||
}
|
||||
r_center[2] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void calculateCenterCursor2D(TransInfo *t, float r_center[2])
|
||||
@@ -1586,6 +1614,12 @@ void calculateCenterCursor2D(TransInfo *t, float r_center[2])
|
||||
r_center[0] = co[0] * aspx;
|
||||
r_center[1] = co[1] * aspy;
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
if (t->spacetype == SPACE_IMAGE) {
|
||||
r_center[0] = UI_view2d_view_to_region_x(&t->ar->v2d, cursor[0]);
|
||||
r_center[1] = UI_view2d_view_to_region_y(&t->ar->v2d, cursor[1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
r_center[0] = cursor[0] * aspx;
|
||||
r_center[1] = cursor[1] * aspy;
|
||||
@@ -1720,6 +1754,14 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
Paint *p = BKE_paint_get_active(t->scene);
|
||||
Brush *br = p->brush;
|
||||
PaintCurve *pc = br->paint_curve;
|
||||
copy_v3_v3(r_center, pc->points[pc->add_index - 1].bez.vec[1]);
|
||||
r_center[2] = 0.0f;
|
||||
ok = true;
|
||||
}
|
||||
else {
|
||||
/* object mode */
|
||||
Scene *scene = t->scene;
|
||||
|
||||
@@ -2383,6 +2383,9 @@ static void applyGridIncrement(TransInfo *t, float *val, int max_index, float fa
|
||||
if (t->options & CTX_MASK) {
|
||||
ED_space_image_get_aspect(t->sa->spacedata.first, asp, asp + 1);
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
asp[0] = asp[1] = 1.0;
|
||||
}
|
||||
else {
|
||||
ED_space_image_get_uv_aspect(t->sa->spacedata.first, asp, asp + 1);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
@@ -48,6 +49,8 @@
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
@@ -479,13 +482,39 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob)
|
||||
{
|
||||
const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
|
||||
Image *curimage = ED_space_image(sima);
|
||||
Mesh *me = ob->data;
|
||||
Material *ma;
|
||||
|
||||
if (sima->flag & SI_DRAW_OTHER) {
|
||||
draw_uvs_other(scene, ob, curimage, new_shading_nodes);
|
||||
}
|
||||
|
||||
UI_ThemeColor(TH_UV_SHADOW);
|
||||
draw_uvs_other_mesh(ob, curimage, new_shading_nodes);
|
||||
|
||||
ma = give_current_material(ob, ob->actcol);
|
||||
|
||||
if (me->mtpoly) {
|
||||
MPoly *mpoly = me->mpoly;
|
||||
MLoopUV *mloopuv, *mloopuv_base;
|
||||
int a, b;
|
||||
if (!(ma && ma->texpaintslot && ma->texpaintslot[ma->paint_active_slot].uvname[0] &&
|
||||
(mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ma->texpaintslot[ma->paint_active_slot].uvname))))
|
||||
{
|
||||
mloopuv = me->mloopuv;
|
||||
}
|
||||
|
||||
mloopuv_base = mloopuv;
|
||||
|
||||
for (a = me->totpoly; a > 0; a--, mpoly++) {
|
||||
glBegin(GL_LINE_LOOP);
|
||||
|
||||
mloopuv = mloopuv_base + mpoly->loopstart;
|
||||
for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
|
||||
glVertex2fv(mloopuv->uv);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_EDBM_LOOPTRIS
|
||||
@@ -922,7 +951,7 @@ void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedi
|
||||
ToolSettings *toolsettings = scene->toolsettings;
|
||||
int show_uvedit, show_uvshadow, show_texpaint_uvshadow;
|
||||
|
||||
show_texpaint_uvshadow = (obact && obact->type == OB_MESH && obact->mode == OB_MODE_TEXTURE_PAINT);
|
||||
show_texpaint_uvshadow = ED_space_image_show_texpaint(sima, obact);
|
||||
show_uvedit = ED_space_image_show_uvedit(sima, obedit);
|
||||
show_uvshadow = ED_space_image_show_uvshadow(sima, obedit);
|
||||
|
||||
|
||||
@@ -3827,7 +3827,8 @@ static void UV_OT_reveal(wmOperatorType *ot)
|
||||
static int uv_set_2d_cursor_poll(bContext *C)
|
||||
{
|
||||
return ED_operator_uvedit_space_image(C) ||
|
||||
ED_space_image_maskedit_poll(C);
|
||||
ED_space_image_maskedit_poll(C) ||
|
||||
ED_space_image_paint_curve(C);
|
||||
}
|
||||
|
||||
static int uv_set_2d_cursor_exec(bContext *C, wmOperator *op)
|
||||
|
||||
@@ -139,6 +139,7 @@ void GPU_drawobject_free(struct DerivedMesh *dm);
|
||||
void GPU_vertex_setup(struct DerivedMesh *dm);
|
||||
void GPU_normal_setup(struct DerivedMesh *dm);
|
||||
void GPU_uv_setup(struct DerivedMesh *dm);
|
||||
void GPU_texpaint_uv_setup(struct DerivedMesh *dm);
|
||||
/* colType is the cddata MCol type to use! */
|
||||
void GPU_color_setup(struct DerivedMesh *dm, int colType);
|
||||
void GPU_edge_setup(struct DerivedMesh *dm); /* does not mix with other data */
|
||||
|
||||
@@ -87,7 +87,7 @@ int GPU_get_material_alpha_blend(void);
|
||||
* - passing NULL clears the state again */
|
||||
|
||||
int GPU_set_tpage(struct MTFace *tface, int mipmap, int transp);
|
||||
|
||||
void GPU_clear_tpage(bool force);
|
||||
/* Lights
|
||||
* - returns how many lights were enabled
|
||||
* - this affects fixed functions materials and texface, not glsl */
|
||||
|
||||
@@ -46,11 +46,13 @@
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_pbvh.h"
|
||||
|
||||
#include "DNA_userdef_types.h"
|
||||
@@ -63,13 +65,16 @@
|
||||
typedef enum {
|
||||
GPU_BUFFER_VERTEX_STATE = 1,
|
||||
GPU_BUFFER_NORMAL_STATE = 2,
|
||||
GPU_BUFFER_TEXCOORD_STATE = 4,
|
||||
GPU_BUFFER_COLOR_STATE = 8,
|
||||
GPU_BUFFER_ELEMENT_STATE = 16,
|
||||
GPU_BUFFER_TEXCOORD_UNIT_0_STATE = 4,
|
||||
GPU_BUFFER_TEXCOORD_UNIT_1_STATE = 8,
|
||||
GPU_BUFFER_COLOR_STATE = 16,
|
||||
GPU_BUFFER_ELEMENT_STATE = 32,
|
||||
} GPUBufferState;
|
||||
|
||||
#define MAX_GPU_ATTRIB_DATA 32
|
||||
|
||||
#define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n))
|
||||
|
||||
/* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
|
||||
static int useVBOs = -1;
|
||||
static GPUBufferState GLStates = 0;
|
||||
@@ -836,6 +841,61 @@ static void GPU_buffer_copy_uv(DerivedMesh *dm, float *varray, int *index, int *
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void GPU_buffer_copy_uv_texpaint(DerivedMesh *dm, float *varray, int *index, int *mat_orig_to_new, void *UNUSED(user))
|
||||
{
|
||||
int start;
|
||||
int i, totface;
|
||||
|
||||
int totmaterial = dm->totmat;
|
||||
MTFace **mtface_base;
|
||||
MTFace *stencil_base;
|
||||
int stencil;
|
||||
MFace *mf;
|
||||
|
||||
/* should have been checked for before, reassert */
|
||||
BLI_assert(DM_get_tessface_data_layer(dm, CD_MTFACE));
|
||||
mf = dm->getTessFaceArray(dm);
|
||||
mtface_base = MEM_mallocN(totmaterial * sizeof(*mtface_base), "texslots");
|
||||
|
||||
for (i = 0; i < totmaterial; i++) {
|
||||
mtface_base[i] = DM_paint_uvlayer_active_get(dm, i);
|
||||
}
|
||||
|
||||
stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
|
||||
stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
|
||||
|
||||
totface = dm->getNumTessFaces(dm);
|
||||
|
||||
for (i = 0; i < totface; i++, mf++) {
|
||||
int mat_i = mf->mat_nr;
|
||||
start = index[mat_orig_to_new[mat_i]];
|
||||
|
||||
/* v1 v2 v3 */
|
||||
copy_v2_v2(&varray[start], mtface_base[mat_i][i].uv[0]);
|
||||
copy_v2_v2(&varray[start + 2], stencil_base[i].uv[0]);
|
||||
copy_v2_v2(&varray[start + 4], mtface_base[mat_i][i].uv[1]);
|
||||
copy_v2_v2(&varray[start + 6], stencil_base[i].uv[1]);
|
||||
copy_v2_v2(&varray[start + 8], mtface_base[mat_i][i].uv[2]);
|
||||
copy_v2_v2(&varray[start + 10], stencil_base[i].uv[2]);
|
||||
index[mat_orig_to_new[mat_i]] += 12;
|
||||
|
||||
if (mf->v4) {
|
||||
/* v3 v4 v1 */
|
||||
copy_v2_v2(&varray[start + 12], mtface_base[mat_i][i].uv[2]);
|
||||
copy_v2_v2(&varray[start + 14], stencil_base[i].uv[2]);
|
||||
copy_v2_v2(&varray[start + 16], mtface_base[mat_i][i].uv[3]);
|
||||
copy_v2_v2(&varray[start + 18], stencil_base[i].uv[3]);
|
||||
copy_v2_v2(&varray[start + 20], mtface_base[mat_i][i].uv[0]);
|
||||
copy_v2_v2(&varray[start + 22], stencil_base[i].uv[0]);
|
||||
index[mat_orig_to_new[mat_i]] += 12;
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(mtface_base);
|
||||
}
|
||||
|
||||
|
||||
static void copy_mcol_uc3(unsigned char *v, unsigned char *col)
|
||||
{
|
||||
v[0] = col[3];
|
||||
@@ -925,6 +985,7 @@ typedef enum {
|
||||
GPU_BUFFER_NORMAL,
|
||||
GPU_BUFFER_COLOR,
|
||||
GPU_BUFFER_UV,
|
||||
GPU_BUFFER_UV_TEXPAINT,
|
||||
GPU_BUFFER_EDGE,
|
||||
GPU_BUFFER_UVEDGE,
|
||||
} GPUBufferType;
|
||||
@@ -940,6 +1001,7 @@ const GPUBufferTypeSettings gpu_buffer_type_settings[] = {
|
||||
{GPU_buffer_copy_normal, GL_ARRAY_BUFFER_ARB, 3},
|
||||
{GPU_buffer_copy_mcol, GL_ARRAY_BUFFER_ARB, 3},
|
||||
{GPU_buffer_copy_uv, GL_ARRAY_BUFFER_ARB, 2},
|
||||
{GPU_buffer_copy_uv_texpaint, GL_ARRAY_BUFFER_ARB, 4},
|
||||
{GPU_buffer_copy_edge, GL_ELEMENT_ARRAY_BUFFER_ARB, 2},
|
||||
{GPU_buffer_copy_uvedge, GL_ELEMENT_ARRAY_BUFFER_ARB, 4}
|
||||
};
|
||||
@@ -956,6 +1018,8 @@ static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBuffer
|
||||
return &gdo->colors;
|
||||
case GPU_BUFFER_UV:
|
||||
return &gdo->uv;
|
||||
case GPU_BUFFER_UV_TEXPAINT:
|
||||
return &gdo->uv;
|
||||
case GPU_BUFFER_EDGE:
|
||||
return &gdo->edges;
|
||||
case GPU_BUFFER_UVEDGE:
|
||||
@@ -977,6 +1041,8 @@ static int gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type)
|
||||
return sizeof(char) * 3 * dm->drawObject->tot_triangle_point;
|
||||
case GPU_BUFFER_UV:
|
||||
return sizeof(float) * 2 * dm->drawObject->tot_triangle_point;
|
||||
case GPU_BUFFER_UV_TEXPAINT:
|
||||
return sizeof(float) * 4 * dm->drawObject->tot_triangle_point;
|
||||
case GPU_BUFFER_EDGE:
|
||||
return sizeof(int) * 2 * dm->drawObject->totedge;
|
||||
case GPU_BUFFER_UVEDGE:
|
||||
@@ -1005,7 +1071,7 @@ static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type)
|
||||
if (!(user_data = DM_get_tessface_data_layer(dm, dm->drawObject->colType)))
|
||||
return NULL;
|
||||
}
|
||||
else if (type == GPU_BUFFER_UV) {
|
||||
else if (ELEM(type, GPU_BUFFER_UV, GPU_BUFFER_UV_TEXPAINT)) {
|
||||
if (!DM_get_tessface_data_layer(dm, CD_MTFACE))
|
||||
return NULL;
|
||||
}
|
||||
@@ -1081,9 +1147,35 @@ void GPU_uv_setup(DerivedMesh *dm)
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, dm->drawObject->uv->pointer);
|
||||
}
|
||||
|
||||
GLStates |= GPU_BUFFER_TEXCOORD_STATE;
|
||||
GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE;
|
||||
}
|
||||
|
||||
void GPU_texpaint_uv_setup(DerivedMesh *dm)
|
||||
{
|
||||
if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV_TEXPAINT))
|
||||
return;
|
||||
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
if (useVBOs) {
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id);
|
||||
glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
|
||||
glClientActiveTexture(GL_TEXTURE1);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), BUFFER_OFFSET(2 * sizeof(float)));
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
else {
|
||||
glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv->pointer);
|
||||
glClientActiveTexture(GL_TEXTURE1);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv->pointer + 2 * sizeof(float));
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_1_STATE;
|
||||
}
|
||||
|
||||
|
||||
void GPU_color_setup(DerivedMesh *dm, int colType)
|
||||
{
|
||||
if (!dm->drawObject) {
|
||||
@@ -1241,8 +1333,13 @@ void GPU_buffer_unbind(void)
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (GLStates & GPU_BUFFER_NORMAL_STATE)
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
if (GLStates & GPU_BUFFER_TEXCOORD_STATE)
|
||||
if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_0_STATE)
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_1_STATE) {
|
||||
glClientActiveTexture(GL_TEXTURE1);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
if (GLStates & GPU_BUFFER_COLOR_STATE)
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
if (GLStates & GPU_BUFFER_ELEMENT_STATE) {
|
||||
@@ -1251,8 +1348,8 @@ void GPU_buffer_unbind(void)
|
||||
}
|
||||
}
|
||||
GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE |
|
||||
GPU_BUFFER_TEXCOORD_STATE | GPU_BUFFER_COLOR_STATE |
|
||||
GPU_BUFFER_ELEMENT_STATE);
|
||||
GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_1_STATE |
|
||||
GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE);
|
||||
|
||||
for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
|
||||
if (attribData[i].index != -1) {
|
||||
|
||||
@@ -370,9 +370,9 @@ static void gpu_make_repbind(Image *ima)
|
||||
BKE_image_release_ibuf(ima, ibuf, NULL);
|
||||
}
|
||||
|
||||
static void gpu_clear_tpage(void)
|
||||
void GPU_clear_tpage(bool force)
|
||||
{
|
||||
if (GTS.lasttface==NULL)
|
||||
if (GTS.lasttface==NULL && !force)
|
||||
return;
|
||||
|
||||
GTS.lasttface= NULL;
|
||||
@@ -866,7 +866,7 @@ int GPU_set_tpage(MTFace *tface, int mipmap, int alphablend)
|
||||
|
||||
/* check if we need to clear the state */
|
||||
if (tface==NULL) {
|
||||
gpu_clear_tpage();
|
||||
GPU_clear_tpage(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -163,6 +163,22 @@ typedef enum IMB_BlendMode {
|
||||
IMB_BLEND_DARKEN = 5,
|
||||
IMB_BLEND_ERASE_ALPHA = 6,
|
||||
IMB_BLEND_ADD_ALPHA = 7,
|
||||
IMB_BLEND_OVERLAY = 8,
|
||||
IMB_BLEND_HARDLIGHT = 9,
|
||||
IMB_BLEND_COLORBURN = 10,
|
||||
IMB_BLEND_LINEARBURN = 11,
|
||||
IMB_BLEND_COLORDODGE = 12,
|
||||
IMB_BLEND_SCREEN = 13,
|
||||
IMB_BLEND_SOFTLIGHT = 14,
|
||||
IMB_BLEND_PINLIGHT = 15,
|
||||
IMB_BLEND_VIVIDLIGHT = 16,
|
||||
IMB_BLEND_LINEARLIGHT = 17,
|
||||
IMB_BLEND_DIFFERENCE = 18,
|
||||
IMB_BLEND_EXCLUSION = 19,
|
||||
IMB_BLEND_HUE = 20,
|
||||
IMB_BLEND_SATURATION = 21,
|
||||
IMB_BLEND_LUMINOSITY = 22,
|
||||
IMB_BLEND_COLOR = 23,
|
||||
|
||||
IMB_BLEND_COPY = 1000,
|
||||
IMB_BLEND_COPY_RGB = 1001,
|
||||
@@ -179,9 +195,9 @@ void IMB_rectclip(struct ImBuf *dbuf, struct ImBuf *sbuf, int *destx,
|
||||
void IMB_rectcpy(struct ImBuf *drect, struct ImBuf *srect, int destx,
|
||||
int desty, int srcx, int srcy, int width, int height);
|
||||
void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *obuf, struct ImBuf *sbuf,
|
||||
unsigned short *dmask, unsigned short *smask, unsigned short mask_max,
|
||||
unsigned short *dmask, unsigned short *curvemask, unsigned short *mmask, float mask_max,
|
||||
int destx, int desty, int origx, int origy, int srcx, int srcy,
|
||||
int width, int height, IMB_BlendMode mode);
|
||||
int width, int height, IMB_BlendMode mode, bool accumulate);
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -65,6 +65,39 @@ void IMB_blend_color_byte(unsigned char dst[4], unsigned char src1[4], unsigned
|
||||
blend_color_erase_alpha_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_ADD_ALPHA:
|
||||
blend_color_add_alpha_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_OVERLAY:
|
||||
blend_color_overlay_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_HARDLIGHT:
|
||||
blend_color_hardlight_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_COLORBURN:
|
||||
blend_color_burn_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_LINEARBURN:
|
||||
blend_color_linearburn_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_COLORDODGE:
|
||||
blend_color_dodge_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_SCREEN:
|
||||
blend_color_screen_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_SOFTLIGHT:
|
||||
blend_color_softlight_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_PINLIGHT:
|
||||
blend_color_pinlight_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_LINEARLIGHT:
|
||||
blend_color_linearlight_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_VIVIDLIGHT:
|
||||
blend_color_vividlight_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_DIFFERENCE:
|
||||
blend_color_difference_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_EXCLUSION:
|
||||
blend_color_exclusion_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_COLOR:
|
||||
blend_color_color_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_HUE:
|
||||
blend_color_hue_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_SATURATION:
|
||||
blend_color_saturation_byte(dst, src1, src2); break;
|
||||
case IMB_BLEND_LUMINOSITY:
|
||||
blend_color_luminosity_byte(dst, src1, src2); break;
|
||||
|
||||
default:
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[1];
|
||||
@@ -93,6 +126,38 @@ void IMB_blend_color_float(float dst[4], float src1[4], float src2[4], IMB_Blend
|
||||
blend_color_erase_alpha_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_ADD_ALPHA:
|
||||
blend_color_add_alpha_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_OVERLAY:
|
||||
blend_color_overlay_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_HARDLIGHT:
|
||||
blend_color_hardlight_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_COLORBURN:
|
||||
blend_color_burn_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_LINEARBURN:
|
||||
blend_color_linearburn_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_COLORDODGE:
|
||||
blend_color_dodge_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_SCREEN:
|
||||
blend_color_screen_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_SOFTLIGHT:
|
||||
blend_color_softlight_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_PINLIGHT:
|
||||
blend_color_pinlight_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_LINEARLIGHT:
|
||||
blend_color_linearlight_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_VIVIDLIGHT:
|
||||
blend_color_vividlight_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_DIFFERENCE:
|
||||
blend_color_difference_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_EXCLUSION:
|
||||
blend_color_exclusion_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_COLOR:
|
||||
blend_color_color_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_HUE:
|
||||
blend_color_hue_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_SATURATION:
|
||||
blend_color_saturation_float(dst, src1, src2); break;
|
||||
case IMB_BLEND_LUMINOSITY:
|
||||
blend_color_luminosity_float(dst, src1, src2); break;
|
||||
default:
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[1];
|
||||
@@ -226,22 +291,23 @@ static void imb_rectclip3(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, int *destx,
|
||||
void IMB_rectcpy(ImBuf *dbuf, ImBuf *sbuf, int destx,
|
||||
int desty, int srcx, int srcy, int width, int height)
|
||||
{
|
||||
IMB_rectblend(dbuf, dbuf, sbuf, NULL, NULL, 0, destx, desty, destx, desty, srcx, srcy, width, height, IMB_BLEND_COPY);
|
||||
IMB_rectblend(dbuf, dbuf, sbuf, NULL, NULL, NULL, 0, destx, desty, destx, desty, srcx, srcy, width, height, IMB_BLEND_COPY, false);
|
||||
}
|
||||
|
||||
typedef void (*IMB_blend_func)(unsigned char *dst, const unsigned char *src1, const unsigned char *src2);
|
||||
typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2);
|
||||
|
||||
|
||||
void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
|
||||
unsigned short *smask, unsigned short mask_max,
|
||||
void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask, unsigned short *curvemask,
|
||||
unsigned short *texmask, float mask_max,
|
||||
int destx, int desty, int origx, int origy, int srcx, int srcy, int width, int height,
|
||||
IMB_BlendMode mode)
|
||||
IMB_BlendMode mode, bool accumulate)
|
||||
{
|
||||
unsigned int *drect = NULL, *orect, *srect = NULL, *dr, *or, *sr;
|
||||
float *drectf = NULL, *orectf, *srectf = NULL, *drf, *orf, *srf;
|
||||
unsigned short *smaskrect = smask, *smr;
|
||||
unsigned short *cmaskrect = curvemask, *cmr;
|
||||
unsigned short *dmaskrect = dmask, *dmr;
|
||||
unsigned short *texmaskrect = texmask, *tmr;
|
||||
int do_float, do_char, srcskip, destskip, origskip, x;
|
||||
IMB_blend_func func = NULL;
|
||||
IMB_blend_func_float func_float = NULL;
|
||||
@@ -277,8 +343,11 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
|
||||
if (do_float) srectf = sbuf->rect_float + (srcy * sbuf->x + srcx) * 4;
|
||||
srcskip = sbuf->x;
|
||||
|
||||
if (smaskrect)
|
||||
smaskrect += srcy * sbuf->x + srcx;
|
||||
if (cmaskrect)
|
||||
cmaskrect += srcy * sbuf->x + srcx;
|
||||
|
||||
if (texmaskrect)
|
||||
texmaskrect += srcy * sbuf->x + srcx;
|
||||
}
|
||||
else {
|
||||
srect = drect;
|
||||
@@ -388,6 +457,70 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
|
||||
func = blend_color_add_alpha_byte;
|
||||
func_float = blend_color_add_alpha_float;
|
||||
break;
|
||||
case IMB_BLEND_OVERLAY:
|
||||
func = blend_color_overlay_byte;
|
||||
func_float = blend_color_overlay_float;
|
||||
break;
|
||||
case IMB_BLEND_HARDLIGHT:
|
||||
func = blend_color_hardlight_byte;
|
||||
func_float = blend_color_hardlight_float;
|
||||
break;
|
||||
case IMB_BLEND_COLORBURN:
|
||||
func = blend_color_burn_byte;
|
||||
func_float = blend_color_burn_float;
|
||||
break;
|
||||
case IMB_BLEND_LINEARBURN:
|
||||
func = blend_color_linearburn_byte;
|
||||
func_float = blend_color_linearburn_float;
|
||||
break;
|
||||
case IMB_BLEND_COLORDODGE:
|
||||
func = blend_color_dodge_byte;
|
||||
func_float = blend_color_dodge_float;
|
||||
break;
|
||||
case IMB_BLEND_SCREEN:
|
||||
func = blend_color_screen_byte;
|
||||
func_float = blend_color_screen_float;
|
||||
break;
|
||||
case IMB_BLEND_SOFTLIGHT:
|
||||
func = blend_color_softlight_byte;
|
||||
func_float = blend_color_softlight_float;
|
||||
break;
|
||||
case IMB_BLEND_PINLIGHT:
|
||||
func = blend_color_pinlight_byte;
|
||||
func_float = blend_color_pinlight_float;
|
||||
break;
|
||||
case IMB_BLEND_LINEARLIGHT:
|
||||
func = blend_color_linearlight_byte;
|
||||
func_float = blend_color_linearlight_float;
|
||||
break;
|
||||
case IMB_BLEND_VIVIDLIGHT:
|
||||
func = blend_color_vividlight_byte;
|
||||
func_float = blend_color_vividlight_float;
|
||||
break;
|
||||
case IMB_BLEND_DIFFERENCE:
|
||||
func = blend_color_difference_byte;
|
||||
func_float = blend_color_difference_float;
|
||||
break;
|
||||
case IMB_BLEND_EXCLUSION:
|
||||
func = blend_color_exclusion_byte;
|
||||
func_float = blend_color_exclusion_float;
|
||||
break;
|
||||
case IMB_BLEND_COLOR:
|
||||
func = blend_color_color_byte;
|
||||
func_float = blend_color_color_float;
|
||||
break;
|
||||
case IMB_BLEND_HUE:
|
||||
func = blend_color_hue_byte;
|
||||
func_float = blend_color_hue_float;
|
||||
break;
|
||||
case IMB_BLEND_SATURATION:
|
||||
func = blend_color_saturation_byte;
|
||||
func_float = blend_color_saturation_float;
|
||||
break;
|
||||
case IMB_BLEND_LUMINOSITY:
|
||||
func = blend_color_luminosity_byte;
|
||||
func_float = blend_color_luminosity_float;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -399,22 +532,61 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
|
||||
or = orect;
|
||||
sr = srect;
|
||||
|
||||
if (dmaskrect && smaskrect) {
|
||||
if (cmaskrect) {
|
||||
/* mask accumulation for painting */
|
||||
dmr = dmaskrect;
|
||||
smr = smaskrect;
|
||||
cmr = cmaskrect;
|
||||
tmr = texmaskrect;
|
||||
|
||||
for (x = width; x > 0; x--, dr++, or++, sr++, dmr++, smr++) {
|
||||
unsigned char *src = (unsigned char *)sr;
|
||||
/* destination mask present, do max alpha masking */
|
||||
if (dmaskrect) {
|
||||
dmr = dmaskrect;
|
||||
for (x = width; x > 0; x--, dr++, or++, sr++, dmr++, cmr++) {
|
||||
unsigned char *src = (unsigned char *)sr;
|
||||
float mask_lim = mask_max * (*cmr);
|
||||
|
||||
if (src[3] && *smr) {
|
||||
unsigned short mask = *dmr + (((mask_max - *dmr) * (*smr)) / 65535);
|
||||
if (texmaskrect)
|
||||
mask_lim *= ((*tmr++) / 65535.0f);
|
||||
|
||||
if (mask > *dmr) {
|
||||
if (src[3] && mask_lim) {
|
||||
float mask;
|
||||
|
||||
if (accumulate)
|
||||
mask = *dmr + mask_lim;
|
||||
else
|
||||
mask = *dmr + mask_lim - (*dmr * (*cmr / 65535.0f));
|
||||
|
||||
mask = min_ff(mask, 65535.0);
|
||||
|
||||
if (mask > *dmr) {
|
||||
unsigned char mask_src[4];
|
||||
|
||||
*dmr = mask;
|
||||
|
||||
mask_src[0] = src[0];
|
||||
mask_src[1] = src[1];
|
||||
mask_src[2] = src[2];
|
||||
mask_src[3] = divide_round_i(src[3] * mask, 65535);
|
||||
|
||||
func((unsigned char *)dr, (unsigned char *)or, mask_src);
|
||||
}
|
||||
}
|
||||
}
|
||||
dmaskrect += origskip;
|
||||
}
|
||||
/* no destination mask buffer, do regular blend with masktexture if present */
|
||||
else {
|
||||
for (x = width; x > 0; x--, dr++, or++, sr++, cmr++) {
|
||||
unsigned char *src = (unsigned char *)sr;
|
||||
float mask = (float)mask_max * ((float)(*cmr));
|
||||
|
||||
if (texmaskrect)
|
||||
mask *= ((float)(*tmr++) / 65535.0f);
|
||||
|
||||
mask = min_ff(mask, 65535.0);
|
||||
|
||||
if (src[3] && (mask > 0.0f)) {
|
||||
unsigned char mask_src[4];
|
||||
|
||||
*dmr = mask;
|
||||
|
||||
mask_src[0] = src[0];
|
||||
mask_src[1] = src[1];
|
||||
mask_src[2] = src[2];
|
||||
@@ -425,8 +597,9 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
|
||||
}
|
||||
}
|
||||
|
||||
dmaskrect += origskip;
|
||||
smaskrect += srcskip;
|
||||
cmaskrect += srcskip;
|
||||
if (texmaskrect)
|
||||
texmaskrect += srcskip;
|
||||
}
|
||||
else {
|
||||
/* regular blending */
|
||||
@@ -446,28 +619,65 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
|
||||
orf = orectf;
|
||||
srf = srectf;
|
||||
|
||||
if (dmaskrect && smaskrect) {
|
||||
if (cmaskrect) {
|
||||
/* mask accumulation for painting */
|
||||
dmr = dmaskrect;
|
||||
smr = smaskrect;
|
||||
cmr = cmaskrect;
|
||||
tmr = texmaskrect;
|
||||
|
||||
for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4, dmr++, smr++) {
|
||||
if (srf[3] != 0 && *smr) {
|
||||
unsigned short mask = *dmr + (((mask_max - *dmr) * (*smr)) / 65535);
|
||||
/* destination mask present, do max alpha masking */
|
||||
if (dmaskrect) {
|
||||
dmr = dmaskrect;
|
||||
for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4, dmr++, cmr++) {
|
||||
float mask_lim = mask_max * (*cmr);
|
||||
|
||||
if (mask > *dmr) {
|
||||
if (texmaskrect)
|
||||
mask_lim *= ((*tmr++) / 65535.0f);
|
||||
|
||||
if (srf[3] && mask_lim) {
|
||||
float mask;
|
||||
|
||||
if (accumulate)
|
||||
mask = min_ff(*dmr + mask_lim, 65535.0);
|
||||
else
|
||||
mask = *dmr + mask_lim - (*dmr * (*cmr / 65535.0f));
|
||||
|
||||
mask = min_ff(mask, 65535.0);
|
||||
|
||||
if (mask > *dmr) {
|
||||
float mask_srf[4];
|
||||
|
||||
*dmr = mask;
|
||||
mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
|
||||
|
||||
func_float(drf, orf, mask_srf);
|
||||
}
|
||||
}
|
||||
}
|
||||
dmaskrect += origskip;
|
||||
}
|
||||
/* no destination mask buffer, do regular blend with masktexture if present */
|
||||
else {
|
||||
for (x = width; x > 0; x--, drf += 4, orf += 4, srf += 4, cmr++) {
|
||||
float mask = (float)mask_max * ((float)(*cmr));
|
||||
|
||||
if (texmaskrect)
|
||||
mask *= ((float)(*tmr++) / 65535.0f);
|
||||
|
||||
mask = min_ff(mask, 65535.0);
|
||||
|
||||
if (srf[3] && (mask > 0.0f)) {
|
||||
float mask_srf[4];
|
||||
|
||||
*dmr = mask;
|
||||
mul_v4_v4fl(mask_srf, srf, mask * (1.0f / 65535.0f));
|
||||
mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
|
||||
|
||||
func_float(drf, orf, mask_srf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dmaskrect += origskip;
|
||||
smaskrect += srcskip;
|
||||
cmaskrect += srcskip;
|
||||
if (texmaskrect)
|
||||
texmaskrect += srcskip;
|
||||
}
|
||||
else {
|
||||
/* regular blending */
|
||||
|
||||
@@ -213,6 +213,8 @@ typedef struct PreviewImage {
|
||||
#define ID_MC MAKE_ID2('M', 'C') /* MovieClip */
|
||||
#define ID_MSK MAKE_ID2('M', 'S') /* Mask */
|
||||
#define ID_LS MAKE_ID2('L', 'S') /* FreestyleLineStyle */
|
||||
#define ID_PAL MAKE_ID2('P', 'L') /* Palette */
|
||||
#define ID_PC MAKE_ID2('P', 'C') /* Paint Curve */
|
||||
|
||||
/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
|
||||
#define ID_SEQ MAKE_ID2('S', 'Q')
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_texture_types.h" /* for MTex */
|
||||
#include "DNA_curve_types.h"
|
||||
|
||||
//#ifndef MAX_MTEX // XXX Not used?
|
||||
//#define MAX_MTEX 18
|
||||
@@ -62,6 +63,9 @@ typedef struct Brush {
|
||||
|
||||
struct ImBuf *icon_imbuf;
|
||||
PreviewImage *preview;
|
||||
struct ColorBand *gradient; /* color gradient */
|
||||
struct PaintCurve *paint_curve;
|
||||
|
||||
char icon_filepath[1024]; /* 1024 = FILE_MAX */
|
||||
|
||||
float normal_weight;
|
||||
@@ -71,6 +75,7 @@ typedef struct Brush {
|
||||
float weight; /* brush weight */
|
||||
int size; /* brush diameter */
|
||||
int flag; /* general purpose flag */
|
||||
int mask_pressure; /* pressure influence for mask */
|
||||
float jitter; /* jitter the position of the brush */
|
||||
int jitter_absolute; /* absolute jitter in pixels */
|
||||
int overlay_flags;
|
||||
@@ -82,10 +87,17 @@ typedef struct Brush {
|
||||
float rgb[3]; /* color */
|
||||
float alpha; /* opacity */
|
||||
|
||||
float secondary_rgb[3]; /* background color */
|
||||
|
||||
int sculpt_plane; /* the direction of movement for sculpt vertices */
|
||||
|
||||
float plane_offset; /* offset for plane brushes (clay, flatten, fill, scrape) */
|
||||
|
||||
float pad;
|
||||
int gradient_spacing;
|
||||
int gradient_stroke_mode; /* source for stroke color gradient application */
|
||||
int gradient_fill_mode; /* source for fill tool color gradient application */
|
||||
|
||||
char sculpt_tool; /* active sculpt tool */
|
||||
char vertexpaint_tool; /* active vertex/weight paint blend mode (poorly named) */
|
||||
char imagepaint_tool; /* active image paint tool */
|
||||
@@ -100,12 +112,21 @@ typedef struct Brush {
|
||||
|
||||
float texture_sample_bias;
|
||||
|
||||
/* overlay */
|
||||
int texture_overlay_alpha;
|
||||
int mask_overlay_alpha;
|
||||
int cursor_overlay_alpha;
|
||||
|
||||
float unprojected_radius;
|
||||
|
||||
/* soften/sharpen */
|
||||
float sharp_threshold;
|
||||
int blur_kernel_radius;
|
||||
int blur_mode;
|
||||
|
||||
/* fill tool */
|
||||
float fill_threshold;
|
||||
|
||||
float add_col[3];
|
||||
float sub_col[3];
|
||||
|
||||
@@ -116,6 +137,52 @@ typedef struct Brush {
|
||||
float mask_stencil_dimension[2];
|
||||
} Brush;
|
||||
|
||||
typedef struct PaletteColor
|
||||
{
|
||||
struct PaletteColor *next, *prev;
|
||||
/* two values, one to store rgb, other to store values for sculpt/weight */
|
||||
float rgb[3];
|
||||
float value;
|
||||
} PaletteColor;
|
||||
|
||||
typedef struct Palette
|
||||
{
|
||||
ID id;
|
||||
|
||||
/* pointer to individual colours */
|
||||
ListBase colors;
|
||||
ListBase deleted;
|
||||
|
||||
int num_of_colours;
|
||||
int active_color;
|
||||
} Palette;
|
||||
|
||||
typedef struct PaintCurvePoint
|
||||
{
|
||||
BezTriple bez; /* bezier handle */
|
||||
float pressure; /* pressure on that point */
|
||||
} PaintCurvePoint;
|
||||
|
||||
typedef struct PaintCurve
|
||||
{
|
||||
ID id;
|
||||
PaintCurvePoint *points; /* points of curve */
|
||||
int tot_points;
|
||||
int add_index; /* index where next point will be added */
|
||||
} PaintCurve;
|
||||
|
||||
/* Brush.gradient_source */
|
||||
typedef enum BrushGradientSourceStroke {
|
||||
BRUSH_GRADIENT_PRESSURE = 0, /* gradient from pressure */
|
||||
BRUSH_GRADIENT_SPACING_REPEAT = 1, /* gradient from spacing */
|
||||
BRUSH_GRADIENT_SPACING_CLAMP = 2 /* gradient from spacing */
|
||||
} BrushGradientSourceStroke;
|
||||
|
||||
typedef enum BrushGradientSourceFill {
|
||||
BRUSH_GRADIENT_LINEAR = 0, /* gradient from pressure */
|
||||
BRUSH_GRADIENT_RADIAL = 1 /* gradient from spacing */
|
||||
} BrushGradientSourceFill;
|
||||
|
||||
/* Brush.flag */
|
||||
typedef enum BrushFlags {
|
||||
BRUSH_AIRBRUSH = (1 << 0),
|
||||
@@ -124,7 +191,7 @@ typedef enum BrushFlags {
|
||||
BRUSH_SIZE_PRESSURE = (1 << 3),
|
||||
BRUSH_JITTER_PRESSURE = (1 << 4),
|
||||
BRUSH_SPACING_PRESSURE = (1 << 5),
|
||||
// BRUSH_FIXED_TEX = (1 << 6), /* obsolete, use mtex->brush_map_mode = MTEX_MAP_MODE_TILED instead */
|
||||
BRUSH_UNUSED = (1 << 6),
|
||||
BRUSH_RAKE = (1 << 7),
|
||||
BRUSH_ANCHORED = (1 << 8),
|
||||
BRUSH_DIR_IN = (1 << 9),
|
||||
@@ -138,7 +205,7 @@ typedef enum BrushFlags {
|
||||
BRUSH_SPACE_ATTEN = (1 << 18),
|
||||
BRUSH_ADAPTIVE_SPACE = (1 << 19),
|
||||
BRUSH_LOCK_SIZE = (1 << 20),
|
||||
// BRUSH_TEXTURE_OVERLAY = (1 << 21), /* obsolete, use overlay_flags |= BRUSH_OVERLAY_PRIMARY instead */
|
||||
BRUSH_USE_GRADIENT = (1 << 21),
|
||||
BRUSH_EDGE_TO_EDGE = (1 << 22),
|
||||
BRUSH_DRAG_DOT = (1 << 23),
|
||||
BRUSH_INVERSE_SMOOTH_PRESSURE = (1 << 24),
|
||||
@@ -146,13 +213,16 @@ typedef enum BrushFlags {
|
||||
BRUSH_PLANE_TRIM = (1 << 26),
|
||||
BRUSH_FRONTFACE = (1 << 27),
|
||||
BRUSH_CUSTOM_ICON = (1 << 28),
|
||||
|
||||
/* temporary flag which sets up automatically for correct brush
|
||||
* drawing when inverted modal operator is running */
|
||||
BRUSH_INVERTED = (1 << 29),
|
||||
BRUSH_ABSOLUTE_JITTER = (1 << 30)
|
||||
BRUSH_LINE = (1 << 29),
|
||||
BRUSH_ABSOLUTE_JITTER = (1 << 30),
|
||||
BRUSH_CURVE = (1 << 31)
|
||||
} BrushFlags;
|
||||
|
||||
typedef enum {
|
||||
BRUSH_MASK_PRESSURE_RAMP = (1 << 1),
|
||||
BRUSH_MASK_PRESSURE_CUTOFF = (1 << 2)
|
||||
} BrushMaskPressureFlags;
|
||||
|
||||
/* Brush.overlay_flags */
|
||||
typedef enum OverlayFlags {
|
||||
BRUSH_OVERLAY_CURSOR = (1),
|
||||
@@ -195,7 +265,9 @@ typedef enum BrushImagePaintTool {
|
||||
PAINT_TOOL_DRAW = 0,
|
||||
PAINT_TOOL_SOFTEN = 1,
|
||||
PAINT_TOOL_SMEAR = 2,
|
||||
PAINT_TOOL_CLONE = 3
|
||||
PAINT_TOOL_CLONE = 3,
|
||||
PAINT_TOOL_FILL = 4,
|
||||
PAINT_TOOL_MASK = 5
|
||||
} BrushImagePaintTool;
|
||||
|
||||
/* direction that the brush displaces along */
|
||||
@@ -222,6 +294,12 @@ typedef enum {
|
||||
BRUSH_MASK_SMOOTH = 1
|
||||
} BrushMaskTool;
|
||||
|
||||
/* blur kernel types, Brush.blur_mode */
|
||||
typedef enum BlurKernelType {
|
||||
KERNEL_GAUSSIAN,
|
||||
KERNEL_BOX
|
||||
} BlurKernelType;
|
||||
|
||||
#define MAX_BRUSH_PIXEL_RADIUS 200
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#endif
|
||||
|
||||
struct MTex;
|
||||
struct Image;
|
||||
struct ColorBand;
|
||||
struct Group;
|
||||
struct bNodeTree;
|
||||
@@ -82,6 +83,11 @@ typedef struct GameSettings {
|
||||
int pad1;
|
||||
} GameSettings;
|
||||
|
||||
typedef struct TexPaintSlot {
|
||||
struct Image *ima; /* image to be painted on */
|
||||
char uvname[64]; /* customdata index for uv layer, MAX_NAME*/
|
||||
} TexPaintSlot;
|
||||
|
||||
typedef struct Material {
|
||||
ID id;
|
||||
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
|
||||
@@ -182,8 +188,15 @@ typedef struct Material {
|
||||
float line_col[4];
|
||||
short line_priority;
|
||||
short vcol_alpha;
|
||||
int pad4;
|
||||
|
||||
/* texture painting */
|
||||
short paint_active_slot;
|
||||
short paint_clone_slot;
|
||||
short tot_slots;
|
||||
short pad4[3];
|
||||
|
||||
struct TexPaintSlot *texpaintslot; /* cached slot for painting. Make sure to recalculate before use
|
||||
* with refresh_texpaint_image_cache */
|
||||
ListBase gpumaterial; /* runtime */
|
||||
} Material;
|
||||
|
||||
|
||||
@@ -811,7 +811,8 @@ typedef struct TimeMarker {
|
||||
/* Paint Tool Base */
|
||||
typedef struct Paint {
|
||||
struct Brush *brush;
|
||||
|
||||
struct Palette *palette;
|
||||
|
||||
/* WM Paint cursor */
|
||||
void *paint_cursor;
|
||||
unsigned char paint_cursor_col[4];
|
||||
@@ -840,9 +841,17 @@ typedef struct ImagePaintSettings {
|
||||
short seam_bleed, normal_angle;
|
||||
short screen_grab_size[2]; /* capture size for re-projection */
|
||||
|
||||
/* new layer default resolution */
|
||||
int slot_xresolution_default;
|
||||
int slot_yresolution_default;
|
||||
|
||||
int pad1;
|
||||
|
||||
void *paintcursor; /* wm handle */
|
||||
struct Image *stencil; /* workaround until we support true layer masks */
|
||||
float slot_color_default[4];
|
||||
float stencil_col[3];
|
||||
float pad2;
|
||||
} ImagePaintSettings;
|
||||
|
||||
/* ------------------------------------------- */
|
||||
@@ -966,6 +975,11 @@ typedef struct UnifiedPaintSettings {
|
||||
/* unified brush weight, [0, 1] */
|
||||
float weight;
|
||||
|
||||
/* unified brush color */
|
||||
float rgb[3];
|
||||
/* unified brush secondary color */
|
||||
float secondary_rgb[3];
|
||||
|
||||
/* user preferences for sculpt and paint */
|
||||
int flag;
|
||||
|
||||
@@ -973,7 +987,6 @@ typedef struct UnifiedPaintSettings {
|
||||
|
||||
/* record movement of mouse so that rake can start at an intuitive angle */
|
||||
float last_rake[2];
|
||||
int pad;
|
||||
|
||||
float brush_rotation;
|
||||
|
||||
@@ -981,7 +994,14 @@ typedef struct UnifiedPaintSettings {
|
||||
* all data below are used to communicate with cursor drawing and tex sampling *
|
||||
*********************************************************************************/
|
||||
int draw_anchored;
|
||||
int anchored_size;
|
||||
int anchored_size;
|
||||
|
||||
char draw_inverted;
|
||||
char pad3[7];
|
||||
|
||||
float overlap_factor; /* normalization factor due to accumulated value of curve along spacing.
|
||||
* Calculated when brush spacing changes to dampen strength of stroke
|
||||
* if space attenuation is used*/
|
||||
float anchored_initial_mouse[2];
|
||||
|
||||
/* check is there an ongoing stroke right now */
|
||||
@@ -1001,15 +1021,16 @@ typedef struct UnifiedPaintSettings {
|
||||
struct ColorSpace *colorspace;
|
||||
|
||||
/* radius of brush, premultiplied with pressure.
|
||||
* In case of anchored brushes contains that radius */
|
||||
* In case of anchored brushes contains the anchored radius */
|
||||
float pixel_radius;
|
||||
int pad2;
|
||||
int pad4;
|
||||
} UnifiedPaintSettings;
|
||||
|
||||
typedef enum {
|
||||
UNIFIED_PAINT_SIZE = (1 << 0),
|
||||
UNIFIED_PAINT_ALPHA = (1 << 1),
|
||||
UNIFIED_PAINT_WEIGHT = (1 << 5),
|
||||
UNIFIED_PAINT_COLOR = (1 << 6),
|
||||
|
||||
/* only used if unified size is enabled, mirrors the brush flags
|
||||
* BRUSH_LOCK_SIZE and BRUSH_SIZE_PRESSURE */
|
||||
@@ -1647,7 +1668,7 @@ enum {
|
||||
typedef enum {
|
||||
PAINT_SHOW_BRUSH = (1 << 0),
|
||||
PAINT_FAST_NAVIGATE = (1 << 1),
|
||||
PAINT_SHOW_BRUSH_ON_SURFACE = (1 << 2),
|
||||
PAINT_SHOW_BRUSH_ON_SURFACE = (1 << 2)
|
||||
} PaintFlags;
|
||||
|
||||
/* Paint.symmetry_flags
|
||||
|
||||
@@ -809,6 +809,8 @@ typedef enum eSpaceImage_Flag {
|
||||
SI_DRAW_OTHER = (1 << 23),
|
||||
|
||||
SI_COLOR_CORRECTION = (1 << 24),
|
||||
|
||||
SI_NO_DRAW_TEXPAINT = (1 << 25)
|
||||
} eSpaceImage_Flag;
|
||||
|
||||
/* Text Editor ============================================ */
|
||||
|
||||
@@ -154,7 +154,6 @@ typedef struct uiGradientColors {
|
||||
char high_gradient[4];
|
||||
int show_grad;
|
||||
int pad2;
|
||||
|
||||
} uiGradientColors;
|
||||
|
||||
typedef struct ThemeUI {
|
||||
@@ -328,6 +327,9 @@ typedef struct ThemeSpace {
|
||||
char info_warning[4], info_warning_text[4];
|
||||
char info_info[4], info_info_text[4];
|
||||
char info_debug[4], info_debug_text[4];
|
||||
|
||||
char paint_curve_pivot[4];
|
||||
char paint_curve_handle[4];
|
||||
} ThemeSpace;
|
||||
|
||||
|
||||
|
||||
@@ -427,6 +427,9 @@ extern StructRNA RNA_OrController;
|
||||
extern StructRNA RNA_OutflowFluidSettings;
|
||||
extern StructRNA RNA_PackedFile;
|
||||
extern StructRNA RNA_Paint;
|
||||
extern StructRNA RNA_PaintCurve;
|
||||
extern StructRNA RNA_Palette;
|
||||
extern StructRNA RNA_PaletteColor;
|
||||
extern StructRNA RNA_Panel;
|
||||
extern StructRNA RNA_Particle;
|
||||
extern StructRNA RNA_ParticleBrush;
|
||||
|
||||
@@ -153,6 +153,8 @@ short RNA_type_to_ID_code(StructRNA *type)
|
||||
if (RNA_struct_is_a(type, &RNA_WindowManager)) return ID_WM;
|
||||
if (RNA_struct_is_a(type, &RNA_MovieClip)) return ID_MC;
|
||||
if (RNA_struct_is_a(type, &RNA_Mask)) return ID_MSK;
|
||||
if (RNA_struct_is_a(type, &RNA_Palette)) return ID_PAL;
|
||||
if (RNA_struct_is_a(type, &RNA_PaintCurve)) return ID_PC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -190,6 +192,9 @@ StructRNA *ID_code_to_RNA_type(short idcode)
|
||||
case ID_WM: return &RNA_WindowManager;
|
||||
case ID_MC: return &RNA_MovieClip;
|
||||
case ID_MSK: return &RNA_Mask;
|
||||
case ID_PAL: return &RNA_Palette;
|
||||
case ID_PC: return &RNA_PaintCurve;
|
||||
|
||||
default: return &RNA_ID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ static EnumPropertyItem sculpt_stroke_method_items[] = {
|
||||
{BRUSH_SPACE, "SPACE", 0, "Space", "Limit brush application to the distance specified by spacing"},
|
||||
{BRUSH_AIRBRUSH, "AIRBRUSH", 0, "Airbrush", "Keep applying paint effect while holding mouse (spray)"},
|
||||
{BRUSH_ANCHORED, "ANCHORED", 0, "Anchored", "Keep the brush anchored to the initial location"},
|
||||
{BRUSH_LINE, "LINE", 0, "Line", "Draw a line with dabs separated according to spacing"},
|
||||
{BRUSH_CURVE, "CURVE", 0, "Curve", "Define the stroke curve with a bezier curve. Dabs are separated according to spacing"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -99,6 +101,8 @@ EnumPropertyItem brush_image_tool_items[] = {
|
||||
{PAINT_TOOL_SOFTEN, "SOFTEN", ICON_BRUSH_SOFTEN, "Soften", ""},
|
||||
{PAINT_TOOL_SMEAR, "SMEAR", ICON_BRUSH_SMEAR, "Smear", ""},
|
||||
{PAINT_TOOL_CLONE, "CLONE", ICON_BRUSH_CLONE, "Clone", ""},
|
||||
{PAINT_TOOL_FILL, "FILL", ICON_BRUSH_TEXFILL, "Fill", ""},
|
||||
{PAINT_TOOL_MASK, "MASK", ICON_BRUSH_TEXMASK, "Mask", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -222,17 +226,35 @@ static int rna_SculptToolCapabilities_has_smooth_stroke_get(PointerRNA *ptr)
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
return (!(br->flag & BRUSH_ANCHORED) &&
|
||||
!(br->flag & BRUSH_DRAG_DOT) &&
|
||||
!ELEM(br->sculpt_tool,
|
||||
SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
|
||||
SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
|
||||
!(br->flag & BRUSH_LINE) &&
|
||||
!(br->flag & BRUSH_CURVE) &&
|
||||
!ELEM(br->sculpt_tool,
|
||||
SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
|
||||
SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
|
||||
}
|
||||
|
||||
static int rna_BrushCapabilities_has_smooth_stroke_get(PointerRNA *ptr)
|
||||
{
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
return (!(br->flag & BRUSH_ANCHORED) &&
|
||||
!(br->flag & BRUSH_DRAG_DOT) &&
|
||||
!(br->flag & BRUSH_LINE) &&
|
||||
!(br->flag & BRUSH_CURVE));
|
||||
}
|
||||
|
||||
static int rna_SculptToolCapabilities_has_space_attenuation_get(PointerRNA *ptr)
|
||||
{
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
return ((br->flag & BRUSH_SPACE) &&
|
||||
!ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
|
||||
SCULPT_TOOL_SMOOTH, SCULPT_TOOL_SNAKE_HOOK));
|
||||
return ((br->flag & (BRUSH_SPACE | BRUSH_LINE | BRUSH_CURVE)) &&
|
||||
!ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
|
||||
SCULPT_TOOL_SMOOTH, SCULPT_TOOL_SNAKE_HOOK));
|
||||
}
|
||||
|
||||
static int rna_ImapaintToolCapabilities_has_space_attenuation_get(PointerRNA *ptr)
|
||||
{
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
return (br->flag & (BRUSH_SPACE | BRUSH_LINE | BRUSH_CURVE)) &&
|
||||
br->imagepaint_tool != PAINT_TOOL_FILL;
|
||||
}
|
||||
|
||||
static int rna_BrushCapabilities_has_spacing_get(PointerRNA *ptr)
|
||||
@@ -273,11 +295,40 @@ static int rna_BrushCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
|
||||
MTEX_MAP_MODE_RANDOM);
|
||||
}
|
||||
|
||||
static PointerRNA rna_Sculpt_sculpt_tool_capabilities_get(PointerRNA *ptr)
|
||||
static int rna_ImapaintToolCapabilities_has_accumulate_get(PointerRNA *ptr)
|
||||
{
|
||||
/* only support for draw tool */
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
|
||||
return ((br->flag & BRUSH_AIRBRUSH) ||
|
||||
(br->flag & BRUSH_DRAG_DOT) ||
|
||||
(br->flag & BRUSH_ANCHORED) ||
|
||||
(br->imagepaint_tool == PAINT_TOOL_SOFTEN) ||
|
||||
(br->imagepaint_tool == PAINT_TOOL_SMEAR) ||
|
||||
(br->imagepaint_tool == PAINT_TOOL_FILL) ||
|
||||
(br->mtex.tex && !ELEM(br->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_3D))
|
||||
) ? false : true;
|
||||
}
|
||||
|
||||
static int rna_ImapaintToolCapabilities_has_radius_get(PointerRNA *ptr)
|
||||
{
|
||||
/* only support for draw tool */
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
|
||||
return (br->imagepaint_tool != PAINT_TOOL_FILL);
|
||||
}
|
||||
|
||||
|
||||
static PointerRNA rna_Sculpt_tool_capabilities_get(PointerRNA *ptr)
|
||||
{
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_SculptToolCapabilities, ptr->id.data);
|
||||
}
|
||||
|
||||
static PointerRNA rna_Imapaint_tool_capabilities_get(PointerRNA *ptr)
|
||||
{
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_ImapaintToolCapabilities, ptr->id.data);
|
||||
}
|
||||
|
||||
static PointerRNA rna_Brush_capabilities_get(PointerRNA *ptr)
|
||||
{
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_BrushCapabilities, ptr->id.data);
|
||||
@@ -328,7 +379,6 @@ static void rna_Brush_size_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
static void rna_Brush_sculpt_tool_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
BKE_paint_invalidate_overlay_all();
|
||||
rna_Brush_reset_icon(br, "sculpt");
|
||||
rna_Brush_update(bmain, scene, ptr);
|
||||
}
|
||||
@@ -336,7 +386,6 @@ static void rna_Brush_sculpt_tool_update(Main *bmain, Scene *scene, PointerRNA *
|
||||
static void rna_Brush_vertex_tool_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
BKE_paint_invalidate_overlay_all();
|
||||
rna_Brush_reset_icon(br, "vertex_paint");
|
||||
rna_Brush_update(bmain, scene, ptr);
|
||||
}
|
||||
@@ -344,11 +393,16 @@ static void rna_Brush_vertex_tool_update(Main *bmain, Scene *scene, PointerRNA *
|
||||
static void rna_Brush_imagepaint_tool_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
BKE_paint_invalidate_overlay_all();
|
||||
rna_Brush_reset_icon(br, "image_paint");
|
||||
rna_Brush_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_Brush_stroke_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, scene);
|
||||
rna_Brush_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_Brush_icon_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
@@ -388,6 +442,17 @@ static void rna_Brush_set_size(PointerRNA *ptr, int value)
|
||||
brush->size = value;
|
||||
}
|
||||
|
||||
static void rna_Brush_use_gradient_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
Brush *br = (Brush *)ptr->data;
|
||||
|
||||
if (value) br->flag |= BRUSH_USE_GRADIENT;
|
||||
else br->flag &= ~BRUSH_USE_GRADIENT;
|
||||
|
||||
if ((br->flag & BRUSH_USE_GRADIENT) && br->gradient == NULL)
|
||||
br->gradient = add_colorband(true);
|
||||
}
|
||||
|
||||
static void rna_Brush_set_unprojected_radius(PointerRNA *ptr, float value)
|
||||
{
|
||||
Brush *brush = ptr->data;
|
||||
@@ -397,13 +462,16 @@ static void rna_Brush_set_unprojected_radius(PointerRNA *ptr, float value)
|
||||
brush->unprojected_radius = value;
|
||||
}
|
||||
|
||||
static EnumPropertyItem *rna_Brush_direction_itemf(bContext *UNUSED(C), PointerRNA *ptr,
|
||||
static EnumPropertyItem *rna_Brush_direction_itemf(bContext *C, PointerRNA *ptr,
|
||||
PropertyRNA *UNUSED(prop), bool *UNUSED(r_free))
|
||||
{
|
||||
PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
|
||||
static EnumPropertyItem prop_default_items[] = {
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
/* sculpt mode */
|
||||
static EnumPropertyItem prop_flatten_contrast_items[] = {
|
||||
{0, "FLATTEN", 0, "Flatten", "Add effect of brush"},
|
||||
{BRUSH_DIR_IN, "CONTRAST", 0, "Contrast", "Subtract effect of brush"},
|
||||
@@ -434,41 +502,66 @@ static EnumPropertyItem *rna_Brush_direction_itemf(bContext *UNUSED(C), PointerR
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
/* texture paint mode */
|
||||
static EnumPropertyItem prop_soften_sharpen_items[] = {
|
||||
{0, "SOFTEN", 0, "Soften", "Blur effect of brush"},
|
||||
{BRUSH_DIR_IN, "SHARPEN", 0, "Sharpen", "Sharpen effect of brush"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
Brush *me = (Brush *)(ptr->data);
|
||||
|
||||
switch (me->sculpt_tool) {
|
||||
case SCULPT_TOOL_DRAW:
|
||||
case SCULPT_TOOL_CREASE:
|
||||
case SCULPT_TOOL_BLOB:
|
||||
case SCULPT_TOOL_LAYER:
|
||||
case SCULPT_TOOL_CLAY:
|
||||
case SCULPT_TOOL_CLAY_STRIPS:
|
||||
return prop_direction_items;
|
||||
|
||||
case SCULPT_TOOL_MASK:
|
||||
switch ((BrushMaskTool)me->mask_tool) {
|
||||
case BRUSH_MASK_DRAW:
|
||||
switch (mode) {
|
||||
case PAINT_SCULPT:
|
||||
switch (me->sculpt_tool) {
|
||||
case SCULPT_TOOL_DRAW:
|
||||
case SCULPT_TOOL_CREASE:
|
||||
case SCULPT_TOOL_BLOB:
|
||||
case SCULPT_TOOL_LAYER:
|
||||
case SCULPT_TOOL_CLAY:
|
||||
case SCULPT_TOOL_CLAY_STRIPS:
|
||||
return prop_direction_items;
|
||||
break;
|
||||
case BRUSH_MASK_SMOOTH:
|
||||
|
||||
case SCULPT_TOOL_MASK:
|
||||
switch ((BrushMaskTool)me->mask_tool) {
|
||||
case BRUSH_MASK_DRAW:
|
||||
return prop_direction_items;
|
||||
break;
|
||||
case BRUSH_MASK_SMOOTH:
|
||||
return prop_default_items;
|
||||
break;
|
||||
}
|
||||
|
||||
case SCULPT_TOOL_FLATTEN:
|
||||
return prop_flatten_contrast_items;
|
||||
|
||||
case SCULPT_TOOL_FILL:
|
||||
return prop_fill_deepen_items;
|
||||
|
||||
case SCULPT_TOOL_SCRAPE:
|
||||
return prop_scrape_peaks_items;
|
||||
|
||||
case SCULPT_TOOL_PINCH:
|
||||
return prop_pinch_magnify_items;
|
||||
|
||||
case SCULPT_TOOL_INFLATE:
|
||||
return prop_inflate_deflate_items;
|
||||
|
||||
default:
|
||||
return prop_default_items;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCULPT_TOOL_FLATTEN:
|
||||
return prop_flatten_contrast_items;
|
||||
case PAINT_TEXTURE_2D:
|
||||
case PAINT_TEXTURE_PROJECTIVE:
|
||||
switch (me->imagepaint_tool) {
|
||||
case PAINT_TOOL_SOFTEN:
|
||||
return prop_soften_sharpen_items;
|
||||
|
||||
case SCULPT_TOOL_FILL:
|
||||
return prop_fill_deepen_items;
|
||||
|
||||
case SCULPT_TOOL_SCRAPE:
|
||||
return prop_scrape_peaks_items;
|
||||
|
||||
case SCULPT_TOOL_PINCH:
|
||||
return prop_pinch_magnify_items;
|
||||
|
||||
case SCULPT_TOOL_INFLATE:
|
||||
return prop_inflate_deflate_items;
|
||||
default:
|
||||
return prop_default_items;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return prop_default_items;
|
||||
@@ -484,11 +577,15 @@ static EnumPropertyItem *rna_Brush_stroke_itemf(bContext *C, PointerRNA *UNUSED(
|
||||
{0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"},
|
||||
{BRUSH_SPACE, "SPACE", 0, "Space", "Limit brush application to the distance specified by spacing"},
|
||||
{BRUSH_AIRBRUSH, "AIRBRUSH", 0, "Airbrush", "Keep applying paint effect while holding mouse (spray)"},
|
||||
{BRUSH_LINE, "LINE", 0, "Line", "Drag a line with dabs separated according to spacing"},
|
||||
{BRUSH_CURVE, "CURVE", 0, "Curve", "Define the stroke curve with a bezier curve. Dabs are separated according to spacing"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
switch (mode) {
|
||||
case PAINT_SCULPT:
|
||||
case PAINT_TEXTURE_2D:
|
||||
case PAINT_TEXTURE_PROJECTIVE:
|
||||
return sculpt_stroke_method_items;
|
||||
|
||||
default:
|
||||
@@ -622,10 +719,39 @@ static void rna_def_brush_capabilities(BlenderRNA *brna)
|
||||
BRUSH_CAPABILITY(has_texture_angle, "Has Texture Angle");
|
||||
BRUSH_CAPABILITY(has_texture_angle_source, "Has Texture Angle Source");
|
||||
BRUSH_CAPABILITY(has_spacing, "Has Spacing");
|
||||
BRUSH_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke");
|
||||
|
||||
|
||||
#undef BRUSH_CAPABILITY
|
||||
}
|
||||
|
||||
static void rna_def_image_paint_capabilities(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "ImapaintToolCapabilities", NULL);
|
||||
RNA_def_struct_sdna(srna, "Brush");
|
||||
RNA_def_struct_nested(brna, srna, "Brush");
|
||||
RNA_def_struct_ui_text(srna, "Image Paint Capabilities",
|
||||
"Read-only indications of which brush operations "
|
||||
"are supported by the current image paint brush");
|
||||
|
||||
#define IMAPAINT_TOOL_CAPABILITY(prop_name_, ui_name_) \
|
||||
prop = RNA_def_property(srna, #prop_name_, \
|
||||
PROP_BOOLEAN, PROP_NONE); \
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE); \
|
||||
RNA_def_property_boolean_funcs(prop, "rna_ImapaintToolCapabilities_" \
|
||||
#prop_name_ "_get", NULL); \
|
||||
RNA_def_property_ui_text(prop, ui_name_, NULL)
|
||||
|
||||
IMAPAINT_TOOL_CAPABILITY(has_accumulate, "Has Accumulate");
|
||||
IMAPAINT_TOOL_CAPABILITY(has_space_attenuation, "Has Space Attenuation");
|
||||
IMAPAINT_TOOL_CAPABILITY(has_radius, "Has Radius");
|
||||
|
||||
#undef IMAPAINT_TOOL_CAPABILITY
|
||||
}
|
||||
|
||||
static void rna_def_brush(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -640,6 +766,22 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
{IMB_BLEND_DARKEN, "DARKEN", 0, "Darken", "Use darken blending mode while painting"},
|
||||
{IMB_BLEND_ERASE_ALPHA, "ERASE_ALPHA", 0, "Erase Alpha", "Erase alpha while painting"},
|
||||
{IMB_BLEND_ADD_ALPHA, "ADD_ALPHA", 0, "Add Alpha", "Add alpha while painting"},
|
||||
{IMB_BLEND_OVERLAY, "OVERLAY", 0, "Overlay", "Use overlay blending mode while painting"},
|
||||
{IMB_BLEND_HARDLIGHT, "HARDLIGHT", 0, "Hard light", "Use hard light blending mode while painting"},
|
||||
{IMB_BLEND_COLORBURN, "COLORBURN", 0, "Color burn", "Use color burn blending mode while painting"},
|
||||
{IMB_BLEND_LINEARBURN, "LINEARBURN", 0, "Linear burn", "Use linear burn blending mode while painting"},
|
||||
{IMB_BLEND_COLORDODGE, "COLORDODGE", 0, "Color dodge", "Use color dodge blending mode while painting"},
|
||||
{IMB_BLEND_SCREEN, "SCREEN", 0, "Screen", "Use screen blending mode while painting"},
|
||||
{IMB_BLEND_SOFTLIGHT, "SOFTLIGHT", 0, "Soft light", "Use softlight blending mode while painting"},
|
||||
{IMB_BLEND_PINLIGHT, "PINLIGHT", 0, "Pin light", "Use pinlight blending mode while painting"},
|
||||
{IMB_BLEND_VIVIDLIGHT, "VIVIDLIGHT", 0, "Vivid light", "Use vividlight blending mode while painting"},
|
||||
{IMB_BLEND_LINEARLIGHT, "LINEARLIGHT", 0, "Linear light", "Use linearlight blending mode while painting"},
|
||||
{IMB_BLEND_DIFFERENCE, "DIFFERENCE", 0, "Difference", "Use difference blending mode while painting"},
|
||||
{IMB_BLEND_EXCLUSION, "EXCLUSION", 0, "Exclusion", "Use exclusion blending mode while painting"},
|
||||
{IMB_BLEND_HUE, "HUE", 0, "Hue", "Use hue blending mode while painting"},
|
||||
{IMB_BLEND_SATURATION, "SATURATION", 0, "Saturation", "Use saturation blending mode while painting"},
|
||||
{IMB_BLEND_LUMINOSITY, "LUMINOSITY", 0, "Luminosity", "Use luminosity blending mode while painting"},
|
||||
{IMB_BLEND_COLOR, "COLOR", 0, "Color", "Use color blending mode while painting"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -671,6 +813,32 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem brush_blur_mode_items[] = {
|
||||
{KERNEL_BOX, "BOX", 0, "Box", ""},
|
||||
{KERNEL_GAUSSIAN, "GAUSSIAN", 0, "Gaussian", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem brush_gradient_items[] = {
|
||||
{BRUSH_GRADIENT_PRESSURE, "PRESSURE", 0, "Pressure", ""},
|
||||
{BRUSH_GRADIENT_SPACING_REPEAT, "SPACING_REPEAT", 0, "Repeat", ""},
|
||||
{BRUSH_GRADIENT_SPACING_CLAMP, "SPACING_CLAMP", 0, "Clamp", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem brush_gradient_fill_items[] = {
|
||||
{BRUSH_GRADIENT_LINEAR, "LINEAR", 0, "Linear", ""},
|
||||
{BRUSH_GRADIENT_RADIAL, "RADIAL", 0, "Radial", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem brush_mask_pressure_items[] = {
|
||||
{0, "NONE", 0, "Off", ""},
|
||||
{BRUSH_MASK_PRESSURE_RAMP, "RAMP", ICON_STYLUS_PRESSURE, "Ramp", ""},
|
||||
{BRUSH_MASK_PRESSURE_CUTOFF, "CUTOFF", ICON_STYLUS_PRESSURE, "Cutoff", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "Brush", "ID");
|
||||
RNA_def_struct_ui_text(srna, "Brush", "Brush datablock for storing brush settings for painting and sculpting");
|
||||
RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA);
|
||||
@@ -710,7 +878,7 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_enum_items(prop, sculpt_stroke_method_items);
|
||||
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Brush_stroke_itemf");
|
||||
RNA_def_property_ui_text(prop, "Stroke Method", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_stroke_update");
|
||||
|
||||
prop = RNA_def_property(srna, "texture_angle_source_random", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
|
||||
@@ -769,6 +937,13 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Spacing", "Spacing between brush daubs as a percentage of brush diameter");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "grad_spacing", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "gradient_spacing");
|
||||
RNA_def_property_range(prop, 1, 10000);
|
||||
RNA_def_property_ui_range(prop, 1, 10000, 5, -1);
|
||||
RNA_def_property_ui_text(prop, "Gradient Spacing", "Spacing before brush gradient goes full circle");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "smooth_stroke_radius", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 10, 200);
|
||||
RNA_def_property_ui_text(prop, "Smooth Stroke Radius", "Minimum distance from last point before stroke continues");
|
||||
@@ -791,7 +966,13 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_float_sdna(prop, NULL, "rgb");
|
||||
RNA_def_property_ui_text(prop, "Color", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
|
||||
prop = RNA_def_property(srna, "secondary_color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "secondary_rgb");
|
||||
RNA_def_property_ui_text(prop, "Secondary Color", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
@@ -884,6 +1065,32 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Mask Stencil Dimensions", "Dimensions of mask stencil in viewport");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "sharp_threshold", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0.0, 100.0);
|
||||
RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 3);
|
||||
RNA_def_property_float_sdna(prop, NULL, "sharp_threshold");
|
||||
RNA_def_property_ui_text(prop, "Sharp Threshold", "Threshold below which, no sharpening is done");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fill_threshold", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0.0, 100.0);
|
||||
RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 3);
|
||||
RNA_def_property_float_sdna(prop, NULL, "fill_threshold");
|
||||
RNA_def_property_ui_text(prop, "Fill Threshold", "Threshold above which filling is not propagated");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "blur_kernel_radius", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "blur_kernel_radius");
|
||||
RNA_def_property_range(prop, 1, 10000);
|
||||
RNA_def_property_ui_range(prop, 1, 50, 1, -1);
|
||||
RNA_def_property_ui_text(prop, "Kernel Radius", "Radius of kernel used for soften and sharpen in pixels");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "blur_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, brush_blur_mode_items);
|
||||
RNA_def_property_ui_text(prop, "Blur Mode", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
/* flag */
|
||||
prop = RNA_def_property(srna, "use_airbrush", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_AIRBRUSH);
|
||||
@@ -919,7 +1126,13 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
|
||||
RNA_def_property_ui_text(prop, "Size Pressure", "Enable tablet pressure sensitivity for size");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
|
||||
prop = RNA_def_property(srna, "use_gradient", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_USE_GRADIENT);
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_Brush_use_gradient_set");
|
||||
RNA_def_property_ui_text(prop, "Use Gradient", "Use Gradient by utilizing a sampling method");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_pressure_jitter", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_JITTER_PRESSURE);
|
||||
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
|
||||
@@ -932,6 +1145,12 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Spacing Pressure", "Enable tablet pressure sensitivity for spacing");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_pressure_masking", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "mask_pressure");
|
||||
RNA_def_property_enum_items(prop, brush_mask_pressure_items);
|
||||
RNA_def_property_ui_text(prop, "Mask Pressure Mode", "Pen pressure makes texture influence smaller");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_inverse_smooth_pressure", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_INVERSE_SMOOTH_PRESSURE);
|
||||
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
|
||||
@@ -974,6 +1193,16 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Space", "Limit brush application to the distance specified by spacing");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_line", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_LINE);
|
||||
RNA_def_property_ui_text(prop, "Line", "Draw a line with dabs separated according to spacing");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_curve", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_CURVE);
|
||||
RNA_def_property_ui_text(prop, "Curve", "Define the stroke curve with a bezier curve. Dabs are separated according to spacing");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_smooth_stroke", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SMOOTH_STROKE);
|
||||
RNA_def_property_ui_text(prop, "Smooth Stroke", "Brush lags behind mouse and follows a smoother path");
|
||||
@@ -1015,7 +1244,7 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Edge-to-edge", "Drag anchor brush from edge-to-edge");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_drag_dot", PROP_BOOLEAN, PROP_NONE);
|
||||
prop = RNA_def_property(srna, "use_restore_mesh", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_DRAG_DOT);
|
||||
RNA_def_property_ui_text(prop, "Restore Mesh", "Allow a single dot to be carefully positioned");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
@@ -1031,6 +1260,28 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Curve", "Editable falloff curve");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "paint_curve", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Paint Curve", "Active Paint Curve");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "gradient", PROP_POINTER, PROP_NEVER_NULL);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "gradient");
|
||||
RNA_def_property_struct_type(prop, "ColorRamp");
|
||||
RNA_def_property_ui_text(prop, "Gradient", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
/* gradient source */
|
||||
prop = RNA_def_property(srna, "gradient_stroke_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, brush_gradient_items);
|
||||
RNA_def_property_ui_text(prop, "Gradient Stroke Mode", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "gradient_fill_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, brush_gradient_fill_items);
|
||||
RNA_def_property_ui_text(prop, "Gradient Fill Mode", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
/* overlay flags */
|
||||
prop = RNA_def_property(srna, "use_primary_overlay", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "overlay_flags", BRUSH_OVERLAY_PRIMARY);
|
||||
@@ -1173,8 +1424,14 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "sculpt_capabilities", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
RNA_def_property_struct_type(prop, "SculptToolCapabilities");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_Sculpt_sculpt_tool_capabilities_get", NULL, NULL, NULL);
|
||||
RNA_def_property_pointer_funcs(prop, "rna_Sculpt_tool_capabilities_get", NULL, NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Sculpt Capabilities", "Brush's capabilities in sculpt mode");
|
||||
|
||||
prop = RNA_def_property(srna, "image_paint_capabilities", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
RNA_def_property_struct_type(prop, "ImapaintToolCapabilities");
|
||||
RNA_def_property_pointer_funcs(prop, "rna_Imapaint_tool_capabilities_get", NULL, NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Image Painting Capabilities", "Brush's capabilities in image paint mode");
|
||||
}
|
||||
|
||||
|
||||
@@ -1211,6 +1468,11 @@ static void rna_def_operator_stroke_element(BlenderRNA *brna)
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Pressure", "Tablet pressure");
|
||||
|
||||
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_IDPROPERTY);
|
||||
RNA_def_property_range(prop, 0.0f, FLT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Brush Size", "Brush Size in screen space");
|
||||
|
||||
prop = RNA_def_property(srna, "pen_flip", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_IDPROPERTY);
|
||||
RNA_def_property_ui_text(prop, "Flip", "");
|
||||
@@ -1237,6 +1499,7 @@ void RNA_def_brush(BlenderRNA *brna)
|
||||
rna_def_brush(brna);
|
||||
rna_def_brush_capabilities(brna);
|
||||
rna_def_sculpt_capabilities(brna);
|
||||
rna_def_image_paint_capabilities(brna);
|
||||
rna_def_brush_texture_slot(brna);
|
||||
rna_def_operator_stroke_element(brna);
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ void rna_def_texmat_common(struct StructRNA *srna, const char *texspace_editable
|
||||
void rna_def_mtex_common(struct BlenderRNA *brna, struct StructRNA *srna, const char *begin, const char *activeget,
|
||||
const char *activeset, const char *activeeditable, const char *structname,
|
||||
const char *structname_slots, const char *update, const char *update_index);
|
||||
void rna_def_mtex_texpaint(struct StructRNA *srna);
|
||||
void rna_def_render_layer_common(struct StructRNA *srna, int scene);
|
||||
|
||||
void rna_def_actionbone_group_common(struct StructRNA *srna, int update_flag, const char *update_cb);
|
||||
|
||||
@@ -82,6 +82,8 @@ EnumPropertyItem ramp_blend_items[] = {
|
||||
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
@@ -92,6 +94,8 @@ EnumPropertyItem ramp_blend_items[] = {
|
||||
#include "BKE_paint.h"
|
||||
|
||||
#include "ED_node.h"
|
||||
#include "ED_image.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
static void rna_Material_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
@@ -165,6 +169,50 @@ static void rna_Material_mtex_begin(CollectionPropertyIterator *iter, PointerRNA
|
||||
rna_iterator_array_begin(iter, (void *)ma->mtex, sizeof(MTex *), MAX_MTEX, 0, NULL);
|
||||
}
|
||||
|
||||
static void rna_Material_texpaint_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
Material *ma = (Material *)ptr->data;
|
||||
rna_iterator_array_begin(iter, (void *)ma->texpaintslot, sizeof(TexPaintSlot), ma->tot_slots, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
bScreen *sc;
|
||||
Material *ma = ptr->id.data;
|
||||
|
||||
|
||||
if (ma->use_nodes && ma->nodetree && BKE_scene_use_new_shading_nodes(scene)) {
|
||||
struct bNode *node;
|
||||
int index = 0;
|
||||
for (node = ma->nodetree->nodes.first; node; node = node->next) {
|
||||
if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
|
||||
if (index++ == ma->paint_active_slot) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node)
|
||||
nodeSetActive(ma->nodetree, node);
|
||||
}
|
||||
|
||||
for (sc = bmain->screen.first; sc; sc = sc->id.next) {
|
||||
ScrArea *sa;
|
||||
for (sa = sc->areabase.first; sa; sa = sa->next) {
|
||||
SpaceLink *sl;
|
||||
for (sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
if (sl->spacetype == SPACE_IMAGE) {
|
||||
SpaceImage *sima = (SpaceImage *)sl;
|
||||
ED_space_image_set(sima, scene, scene->obedit, ma->texpaintslot[ma->paint_active_slot].ima);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DAG_id_tag_update(&ma->id, 0);
|
||||
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, ma);
|
||||
}
|
||||
|
||||
static PointerRNA rna_Material_active_texture_get(PointerRNA *ptr)
|
||||
{
|
||||
Material *ma = (Material *)ptr->data;
|
||||
@@ -2059,6 +2107,8 @@ void RNA_def_material(BlenderRNA *brna)
|
||||
"rna_Material_active_texture_set", "rna_Material_active_texture_editable",
|
||||
"MaterialTextureSlot", "MaterialTextureSlots", "rna_Material_update", "rna_Material_update");
|
||||
|
||||
rna_def_mtex_texpaint(srna);
|
||||
|
||||
/* only material has this one */
|
||||
prop = RNA_def_property(srna, "use_textures", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "septex", 1);
|
||||
@@ -2147,4 +2197,27 @@ void rna_def_mtex_common(BlenderRNA *brna, StructRNA *srna, const char *begin,
|
||||
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, update_index);
|
||||
}
|
||||
|
||||
void rna_def_mtex_texpaint(StructRNA *srna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* mtex */
|
||||
prop = RNA_def_property(srna, "texture_paint_slots", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_funcs(prop, "rna_Material_texpaint_begin", "rna_iterator_array_next", "rna_iterator_array_end",
|
||||
"rna_iterator_array_dereference_get", NULL, NULL, NULL, NULL);
|
||||
RNA_def_property_struct_type(prop, "Image");
|
||||
RNA_def_property_ui_text(prop, "Textures", "Texture slots defining the mapping and influence of textures");
|
||||
|
||||
prop = RNA_def_property(srna, "paint_active_slot", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_range(prop, 0, INT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Active Paint Texture Index", "Index of active texture paint slot");
|
||||
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, "rna_Material_active_paint_texture_index_update");
|
||||
|
||||
prop = RNA_def_property(srna, "paint_clone_slot", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_range(prop, 0, INT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Clone Paint Texture Index", "Index of clone texture paint slot");
|
||||
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING_LINKS, NULL);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3121,11 +3121,13 @@ static void rna_def_mesh(BlenderRNA *brna)
|
||||
"rna_Mesh_uv_texture_stencil_set", NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Mask UV Map", "UV map to mask the painted area");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
|
||||
|
||||
prop = RNA_def_property(srna, "uv_texture_stencil_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_funcs(prop, "rna_Mesh_uv_texture_stencil_index_get",
|
||||
"rna_Mesh_uv_texture_stencil_index_set", "rna_Mesh_uv_texture_index_range");
|
||||
RNA_def_property_ui_text(prop, "Mask UV Map Index", "Mask UV map index");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
|
||||
|
||||
/* Tessellated face colors - used by renderers */
|
||||
|
||||
|
||||
@@ -2120,6 +2120,11 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Use Unified Weight",
|
||||
"Instead of per-brush weight, the weight is shared across brushes");
|
||||
|
||||
prop = RNA_def_property(srna, "use_unified_color", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_COLOR);
|
||||
RNA_def_property_ui_text(prop, "Use Unified Color",
|
||||
"Instead of per-brush color, the color is shared across brushes");
|
||||
|
||||
/* unified paint settings that override the equivalent settings
|
||||
* from the active brush */
|
||||
prop = RNA_def_property(srna, "size", PROP_INT, PROP_PIXEL);
|
||||
@@ -2152,6 +2157,18 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Weight", "Weight to assign in vertex groups");
|
||||
RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update");
|
||||
|
||||
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "rgb");
|
||||
RNA_def_property_ui_text(prop, "Color", "");
|
||||
RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update");
|
||||
|
||||
prop = RNA_def_property(srna, "secondary_color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "secondary_rgb");
|
||||
RNA_def_property_ui_text(prop, "Secondary Color", "");
|
||||
RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_pressure_size", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_BRUSH_SIZE_PRESSURE);
|
||||
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
|
||||
|
||||
@@ -285,8 +285,67 @@ static void rna_Paint_brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
|
||||
BKE_paint_invalidate_overlay_all();
|
||||
WM_main_add_notifier(NC_BRUSH | NA_EDITED, br);
|
||||
}
|
||||
|
||||
static void rna_ImaPaint_stencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
/* not the best solution maybe, but will refresh the 3D viewport */
|
||||
WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
|
||||
}
|
||||
#else
|
||||
|
||||
static void rna_def_palettecolor(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "PaletteColor", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Palette Color", "");
|
||||
|
||||
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "rgb");
|
||||
RNA_def_property_ui_text(prop, "Color", "");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "value");
|
||||
RNA_def_property_ui_text(prop, "Value", "");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "value");
|
||||
RNA_def_property_ui_text(prop, "Weight", "");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void rna_def_palette(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "Palette", "ID");
|
||||
RNA_def_struct_ui_text(srna, "Palette", "");
|
||||
RNA_def_struct_ui_icon(srna, ICON_COLOR);
|
||||
|
||||
prop = RNA_def_property(srna, "colors", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "PaletteColor");
|
||||
RNA_def_property_ui_text(prop, "Palette Color", "Colors that are part of this palette");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_paint_curve(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
srna = RNA_def_struct(brna, "PaintCurve", "ID");
|
||||
RNA_def_struct_ui_text(srna, "Paint Curve", "");
|
||||
RNA_def_struct_ui_icon(srna, ICON_CURVE_BEZCURVE);
|
||||
}
|
||||
|
||||
|
||||
static void rna_def_paint(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -302,6 +361,11 @@ static void rna_def_paint(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Brush", "Active Brush");
|
||||
RNA_def_property_update(prop, 0, "rna_Paint_brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "palette", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Palette", "Active Palette");
|
||||
|
||||
prop = RNA_def_property(srna, "show_brush", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", PAINT_SHOW_BRUSH);
|
||||
RNA_def_property_ui_text(prop, "Show Brush", "");
|
||||
@@ -532,11 +596,28 @@ static void rna_def_image_paint(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "use_stencil_layer", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL);
|
||||
RNA_def_property_ui_text(prop, "Stencil Layer", "Set the mask layer from the UV map buttons");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert_stencil", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_LAYER_STENCIL_INV);
|
||||
RNA_def_property_ui_text(prop, "Invert", "Invert the stencil layer");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "stencil_image", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "stencil");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Stencil Image", "Image used as stencil");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "stencil_color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "stencil_col");
|
||||
RNA_def_property_ui_text(prop, "Stencil Color", "Stencil color in the viewport");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
|
||||
|
||||
prop = RNA_def_property(srna, "slot_color_default", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_ui_text(prop, "New Layer Color", "Color/Alpha used for new");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_clone_layer", PROP_BOOLEAN, PROP_NONE);
|
||||
@@ -558,6 +639,16 @@ static void rna_def_image_paint(BlenderRNA *brna)
|
||||
prop = RNA_def_int_array(srna, "screen_grab_size", 2, NULL, 0, 0, "screen_grab_size",
|
||||
"Size to capture the image for re-projecting", 0, 0);
|
||||
RNA_def_property_range(prop, 512, 16384);
|
||||
|
||||
prop = RNA_def_property(srna, "slot_xresolution_default", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_range(prop, 1, SHRT_MAX);
|
||||
RNA_def_property_ui_range(prop, 64, 4096, 0, -1);
|
||||
RNA_def_property_ui_text(prop, "X resolution", "X Resolution of new image");
|
||||
|
||||
prop = RNA_def_property(srna, "slot_yresolution_default", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_range(prop, 1, SHRT_MAX);
|
||||
RNA_def_property_ui_range(prop, 64, 4096, 0, -1);
|
||||
RNA_def_property_ui_text(prop, "Y resolution", "Y Resolution of new image");
|
||||
}
|
||||
|
||||
static void rna_def_particle_edit(BlenderRNA *brna)
|
||||
@@ -741,6 +832,9 @@ void RNA_def_sculpt_paint(BlenderRNA *brna)
|
||||
{
|
||||
/* *** Non-Animated *** */
|
||||
RNA_define_animate_sdna(false);
|
||||
rna_def_palettecolor(brna);
|
||||
rna_def_palette(brna);
|
||||
rna_def_paint_curve(brna);
|
||||
rna_def_paint(brna);
|
||||
rna_def_sculpt(brna);
|
||||
rna_def_uv_sculpt(brna);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user