Changeset View
Changeset View
Standalone View
Standalone View
release/scripts/startup/bl_operators/vertexpaint_dirt.py
| # SPDX-License-Identifier: GPL-2.0-or-later | # SPDX-License-Identifier: GPL-2.0-or-later | ||||
| # Copyright Campbell Barton. | # Copyright Campbell Barton. | ||||
| def get_vcolor_layer_data(me): | def ensure_active_color_attribute(me): | ||||
| for lay in me.vertex_colors: | if me.attributes.active_color: | ||||
| if lay.active: | return me.attributes.active_color | ||||
| return lay.data | return me.color_attributes.new("Color", 'BYTE_COLOR', 'FACE_CORNER') | ||||
| lay = me.vertex_colors.new() | |||||
| lay.active = True | |||||
| return lay.data | |||||
| def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, dirt_only, normalize): | def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, dirt_only, normalize): | ||||
| from mathutils import Vector | from mathutils import Vector | ||||
| from math import acos | from math import acos | ||||
| import array | import array | ||||
| # We simulate the accumulation of dirt in the creases of geometric surfaces | # We simulate the accumulation of dirt in the creases of geometric surfaces | ||||
| # by comparing the vertex normal to the average direction of all vertices | # by comparing the vertex normal to the average direction of all vertices | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean, dirt_only, normalize): | ||||
| tone_range = max_tone - min_tone | tone_range = max_tone - min_tone | ||||
| if tone_range < 0.0001: | if tone_range < 0.0001: | ||||
| # weak, don't cancel, see T43345 | # weak, don't cancel, see T43345 | ||||
| tone_range = 0.0 | tone_range = 0.0 | ||||
| else: | else: | ||||
| tone_range = 1.0 / tone_range | tone_range = 1.0 / tone_range | ||||
| active_col_layer = get_vcolor_layer_data(me) | active_color_attribute = ensure_active_color_attribute(me) | ||||
| if not active_col_layer: | if not active_color_attribute: | ||||
| return {'CANCELLED'} | return {'CANCELLED'} | ||||
| point_domain = active_color_attribute.domain == 'POINT' | |||||
| attribute_data = active_color_attribute.data | |||||
| use_paint_mask = me.use_paint_mask | use_paint_mask = me.use_paint_mask | ||||
| for i, p in enumerate(me.polygons): | for i, p in enumerate(me.polygons): | ||||
| if not use_paint_mask or p.select: | if not use_paint_mask or p.select: | ||||
| for loop_index in p.loop_indices: | for loop_index in p.loop_indices: | ||||
| loop = me.loops[loop_index] | loop = me.loops[loop_index] | ||||
| v = loop.vertex_index | v = loop.vertex_index | ||||
| col = active_col_layer[loop_index].color | col = attribute_data[v if point_domain else loop_index].color | ||||
| tone = vert_tone[v] | tone = vert_tone[v] | ||||
| tone = (tone - min_tone) * tone_range | tone = (tone - min_tone) * tone_range | ||||
| if dirt_only: | if dirt_only: | ||||
| tone = min(tone, 0.5) * 2.0 | tone = min(tone, 0.5) * 2.0 | ||||
| col[0] = tone * col[0] | col[0] = tone * col[0] | ||||
| col[1] = tone * col[1] | col[1] = tone * col[1] | ||||
| ▲ Show 20 Lines • Show All 78 Lines • Show Last 20 Lines | |||||