Commit working code.
This commit is contained in:
parent
7327e15630
commit
99b9c1bcad
|
@ -140,16 +140,11 @@ def draw_vpaint_symmetry(layout, vpaint, obj):
|
|||
|
||||
# Most of these panels should not be visible in GP edit modes
|
||||
def is_not_gpencil_edit_mode(context):
|
||||
is_gpmode = (
|
||||
context.active_object and
|
||||
context.active_object.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'}
|
||||
)
|
||||
is_gpmode = (context.active_object and context.active_object.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL'})
|
||||
return not is_gpmode
|
||||
|
||||
|
||||
# ********** default tools for object mode ****************
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_object_options(View3DPanel, Panel):
|
||||
bl_category = "Tool"
|
||||
bl_context = ".objectmode" # dot on purpose (access from topbar)
|
||||
|
@ -181,8 +176,6 @@ class VIEW3D_PT_tools_object_options_transform(View3DPanel, Panel):
|
|||
|
||||
|
||||
# ********** default tools for editmode_mesh ****************
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
|
||||
bl_category = "Tool"
|
||||
bl_context = ".mesh_edit" # dot on purpose (access from topbar)
|
||||
|
@ -256,8 +249,6 @@ class VIEW3D_PT_tools_meshedit_options_automerge(View3DPanel, Panel):
|
|||
|
||||
|
||||
# ********** default tools for editmode_armature ****************
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
|
||||
bl_category = "Tool"
|
||||
bl_context = ".armature_edit" # dot on purpose (access from topbar)
|
||||
|
@ -270,7 +261,6 @@ class VIEW3D_PT_tools_armatureedit_options(View3DPanel, Panel):
|
|||
|
||||
|
||||
# ********** default tools for pose-mode ****************
|
||||
|
||||
class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
|
||||
bl_category = "Tool"
|
||||
bl_context = ".posemode" # dot on purpose (access from topbar)
|
||||
|
@ -292,8 +282,6 @@ class VIEW3D_PT_tools_posemode_options(View3DPanel, Panel):
|
|||
layout.prop(tool_settings, "use_transform_pivot_point_align", text="Locations")
|
||||
|
||||
# ********** default tools for paint modes ****************
|
||||
|
||||
|
||||
class TEXTURE_UL_texpaintslots(UIList):
|
||||
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
||||
# mat = data
|
||||
|
@ -461,8 +449,7 @@ class VIEW3D_PT_tools_brush_settings_channels_preview(Panel, View3DPaintBrushPan
|
|||
brush_settings_channels(layout.column(), context, brush, show_reorder=True, ui_editing=False,
|
||||
popover=self.is_popover,
|
||||
prefix="VIEW3D_PT_brush_category_edit_",
|
||||
parent="VIEW3D_PT_tools_brush_settings_channels_preview"
|
||||
)
|
||||
parent="VIEW3D_PT_tools_brush_settings_channels_preview")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_brush_settings_advanced(Panel, View3DPaintBrushPanel):
|
||||
|
@ -538,14 +525,12 @@ class VIEW3D_PT_tools_persistent_base_channels(Panel, View3DPaintPanel):
|
|||
brush = settings.brush
|
||||
sculpt = context.tool_settings.sculpt
|
||||
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
layout,
|
||||
UnifiedPaintPanel.channel_unified(layout,
|
||||
context,
|
||||
brush,
|
||||
"use_persistent",
|
||||
#text="Weight By Face Area",
|
||||
ui_editing=False
|
||||
)
|
||||
ui_editing=False)
|
||||
|
||||
layout.operator("sculpt.set_persistent_base")
|
||||
|
||||
|
@ -740,10 +725,11 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if (
|
||||
(settings:= cls.paint_settings(context)) and
|
||||
(brush:= settings.brush)
|
||||
):
|
||||
settings = cls.paint_settings(context)
|
||||
|
||||
if settings and settings.brush:
|
||||
brush = settings.brush
|
||||
|
||||
if context.sculpt_object or context.vertex_paint_object:
|
||||
return True
|
||||
elif context.image_paint_object:
|
||||
|
@ -935,34 +921,28 @@ class VIEW3D_PT_sculpt_dyntopo_advanced(Panel, View3DPaintPanel):
|
|||
row.label(text="Remesher Options")
|
||||
row.prop(ch, "inherit", text="", icon="BRUSHES_ALL")
|
||||
else:
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
layout,
|
||||
UnifiedPaintPanel.channel_unified(layout,
|
||||
context,
|
||||
brush,
|
||||
"dyntopo_mode",
|
||||
text="Remesher Options",
|
||||
expand=True
|
||||
)
|
||||
expand=True)
|
||||
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
layout,
|
||||
UnifiedPaintPanel.channel_unified(layout,
|
||||
context,
|
||||
brush,
|
||||
"dyntopo_detail_mode",
|
||||
text="Detail Mode",
|
||||
expand=False
|
||||
)
|
||||
expand=False)
|
||||
|
||||
keys = ["dyntopo_spacing", "dyntopo_detail_size", "dyntopo_detail_range", "dyntopo_detail_percent",
|
||||
"dyntopo_constant_detail", "dyntopo_radius_scale", "dyntopo_disabled"]
|
||||
for k in keys:
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
layout,
|
||||
UnifiedPaintPanel.channel_unified(layout,
|
||||
context,
|
||||
brush,
|
||||
k,
|
||||
slider=True
|
||||
)
|
||||
slider=True)
|
||||
|
||||
return
|
||||
layout.use_property_split = True
|
||||
|
@ -1017,17 +997,15 @@ class VIEW3D_PT_sculpt_dyntopo_advanced(Panel, View3DPaintPanel):
|
|||
do_prop("radius_scale")
|
||||
|
||||
|
||||
class SCULPT_OT_set_dyntopo_mode (Operator):
|
||||
class SCULPT_OT_set_dyntopo_mode(Operator):
|
||||
"""Set refine mode"""
|
||||
|
||||
bl_label = "Set Detail Mode"
|
||||
bl_idname = "sculpt.set_dyntopo_mode"
|
||||
|
||||
mode: EnumProperty(items=[
|
||||
("SC", "Subdivide Collapse", "", 1),
|
||||
mode : EnumProperty(items=[("SC", "Subdivide Collapse", "", 1),
|
||||
("S", "Subdivide Edges", "", 2),
|
||||
("C", "Collapse Edges", "", 3)
|
||||
])
|
||||
("C", "Collapse Edges", "", 3)])
|
||||
|
||||
def execute(self, context):
|
||||
brush = context.tool_settings.sculpt.brush
|
||||
|
@ -1083,12 +1061,10 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
|
|||
def draw_header(self, context):
|
||||
is_popover = self.is_popover
|
||||
layout = self.layout
|
||||
layout.operator(
|
||||
"sculpt.dynamic_topology_toggle",
|
||||
layout.operator("sculpt.dynamic_topology_toggle",
|
||||
icon='CHECKBOX_HLT' if context.sculpt_object.use_dynamic_topology_sculpting else 'CHECKBOX_DEHLT',
|
||||
text="",
|
||||
emboss=is_popover,
|
||||
)
|
||||
emboss=is_popover,)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1113,51 +1089,43 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
|
|||
if detail_mode in {'CONSTANT', 'MANUAL'}:
|
||||
row = sub.row(align=True)
|
||||
#row.prop(sculpt, "constant_detail_resolution")
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
row,
|
||||
UnifiedPaintPanel.channel_unified(row,
|
||||
context,
|
||||
brush,
|
||||
"dyntopo_constant_detail",
|
||||
text="Constant Resolution",
|
||||
# slider=True,
|
||||
ui_editing=False,
|
||||
pressure=False
|
||||
)
|
||||
pressure=False)
|
||||
props = row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
|
||||
props.mode = 'DYNTOPO'
|
||||
elif detail_mode == 'BRUSH':
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
sub,
|
||||
UnifiedPaintPanel.channel_unified(sub,
|
||||
context,
|
||||
brush,
|
||||
"dyntopo_detail_percent",
|
||||
text="Detail Percent",
|
||||
# slider=True,
|
||||
ui_editing=False,
|
||||
pressure=False
|
||||
)
|
||||
pressure=False)
|
||||
else:
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
sub,
|
||||
UnifiedPaintPanel.channel_unified(sub,
|
||||
context,
|
||||
brush,
|
||||
"dyntopo_detail_size",
|
||||
text="Detail Size",
|
||||
# slider=True,
|
||||
ui_editing=False,
|
||||
pressure=False
|
||||
)
|
||||
pressure=False)
|
||||
|
||||
# """
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
sub,
|
||||
UnifiedPaintPanel.channel_unified(sub,
|
||||
context,
|
||||
brush,
|
||||
"dyntopo_detail_mode",
|
||||
text="Detailing",
|
||||
expand=False,
|
||||
ui_editing=False
|
||||
)
|
||||
ui_editing=False)
|
||||
|
||||
set_dyntopo_mode_button(sub, context)
|
||||
|
||||
|
@ -1189,10 +1157,16 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
|
|||
UnifiedPaintPanel.channel_unified(layout, context, brush, "dyntopo_spacing", slider=True, ui_editing=False)
|
||||
UnifiedPaintPanel.channel_unified(layout, context, brush, "dyntopo_radius_scale", slider=True, ui_editing=False)
|
||||
|
||||
UnifiedPaintPanel.channel_unified(sub,
|
||||
context,
|
||||
brush,
|
||||
"dyntopo_disable_smooth",
|
||||
expand=False,
|
||||
text="No Dyntopo Smooth",
|
||||
ui_editing=False)
|
||||
|
||||
#col.prop(sculpt, "dyntopo_spacing")
|
||||
#col.prop(sculpt, "dyntopo_radius_scale")
|
||||
|
||||
|
||||
class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel):
|
||||
bl_context = ".sculpt_mode" # dot on purpose (access from topbar)
|
||||
bl_label = "Remesh"
|
||||
|
@ -1255,8 +1229,7 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
|
|||
col.prop(sculpt, "use_deform_only")
|
||||
col.prop(sculpt, "show_sculpt_pivot")
|
||||
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
layout.column(),
|
||||
UnifiedPaintPanel.channel_unified(layout.column(),
|
||||
context,
|
||||
brush,
|
||||
"smooth_strength_factor", ui_editing=False, slider=True)
|
||||
|
@ -1265,19 +1238,16 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
|
|||
|
||||
col.separator()
|
||||
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
layout.column(),
|
||||
UnifiedPaintPanel.channel_unified(layout.column(),
|
||||
context,
|
||||
brush,
|
||||
"automasking", toolsettings_only=True, expand=True, ui_editing=False)
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
layout.column(),
|
||||
UnifiedPaintPanel.channel_unified(layout.column(),
|
||||
context,
|
||||
brush,
|
||||
"automasking_boundary_edges_propagation_steps",
|
||||
toolsettings_only=True, ui_editing=False)
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
layout.column(),
|
||||
UnifiedPaintPanel.channel_unified(layout.column(),
|
||||
context,
|
||||
brush,
|
||||
"concave_mask_factor",
|
||||
|
@ -1327,11 +1297,9 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (
|
||||
(context.sculpt_object and context.tool_settings.sculpt) and
|
||||
# When used in the tool header, this is explicitly included next to the XYZ symmetry buttons.
|
||||
(context.region.type != 'TOOL_HEADER')
|
||||
)
|
||||
return ((context.sculpt_object and context.tool_settings.sculpt) and # When used in the tool header, this is explicitly included next to
|
||||
# the XYZ symmetry buttons.
|
||||
(context.region.type != 'TOOL_HEADER'))
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1387,7 +1355,8 @@ class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
# When used in the tool header, this is explicitly included next to the XYZ symmetry buttons.
|
||||
# When used in the tool header, this is explicitly included next to the
|
||||
# XYZ symmetry buttons.
|
||||
return (context.region.type != 'TOOL_HEADER')
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -1451,7 +1420,8 @@ class VIEW3D_PT_tools_vertexpaint_options(Panel, View3DPaintPanel):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, _context):
|
||||
# This is currently unused, since there aren't any Vertex Paint mode specific options.
|
||||
# This is currently unused, since there aren't any Vertex Paint mode
|
||||
# specific options.
|
||||
return False
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -1468,7 +1438,8 @@ class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
# When used in the tool header, this is explicitly included next to the XYZ symmetry buttons.
|
||||
# When used in the tool header, this is explicitly included next to the
|
||||
# XYZ symmetry buttons.
|
||||
return (context.region.type != 'TOOL_HEADER')
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -1529,7 +1500,8 @@ class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
# When used in the tool header, this is explicitly included next to the XYZ symmetry buttons.
|
||||
# When used in the tool header, this is explicitly included next to the
|
||||
# XYZ symmetry buttons.
|
||||
return (context.region.type != 'TOOL_HEADER')
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -1608,9 +1580,11 @@ class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, _context):
|
||||
# This is currently unused, since there aren't any Vertex Paint mode specific options.
|
||||
# This is currently unused, since there aren't any Vertex Paint mode
|
||||
# specific options.
|
||||
return False
|
||||
# return (context.image_paint_object and context.tool_settings.image_paint)
|
||||
# return (context.image_paint_object and
|
||||
# context.tool_settings.image_paint)
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
@ -1741,7 +1715,6 @@ class VIEW3D_PT_tools_particlemode_options_display(View3DPanel, Panel):
|
|||
# ********** grease pencil object tool panels ****************
|
||||
|
||||
# Grease Pencil drawing brushes
|
||||
|
||||
def tool_use_brush(context):
|
||||
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
|
||||
tool = ToolSelectPanelHelper.tool_active_from_context(context)
|
||||
|
@ -1801,7 +1774,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_settings(Panel, View3DPanel, GreasePen
|
|||
bl_label = "Brush Settings"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
# What is the point of brush presets? Seems to serve the exact same purpose as brushes themselves??
|
||||
# What is the point of brush presets? Seems to serve the exact same
|
||||
# purpose as brushes themselves??
|
||||
def draw_header_preset(self, _context):
|
||||
VIEW3D_PT_gpencil_brush_presets.draw_panel_header(self.layout)
|
||||
|
||||
|
@ -1888,12 +1862,10 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
|
|||
elif brush.gpencil_tool == 'FILL':
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "fill_draw_mode", text="Boundary")
|
||||
row.prop(
|
||||
gp_settings,
|
||||
row.prop(gp_settings,
|
||||
"show_fill_boundary",
|
||||
icon='HIDE_OFF' if gp_settings.show_fill_boundary else 'HIDE_ON',
|
||||
text="",
|
||||
)
|
||||
text="",)
|
||||
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
|
@ -1902,12 +1874,10 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
|
|||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "extend_stroke_factor")
|
||||
row.prop(
|
||||
gp_settings,
|
||||
row.prop(gp_settings,
|
||||
"show_fill_extend",
|
||||
icon='HIDE_OFF' if gp_settings.show_fill_extend else 'HIDE_ON',
|
||||
text="",
|
||||
)
|
||||
text="",)
|
||||
|
||||
col.separator()
|
||||
col.prop(gp_settings, "fill_leak", text="Leak Size")
|
||||
|
@ -2612,8 +2582,7 @@ class VIEW3D_PT_gpencil_brush_presets(Panel, PresetPanel):
|
|||
preset_add_operator = "scene.gpencil_brush_preset_add"
|
||||
|
||||
|
||||
classes = (
|
||||
VIEW3D_MT_brush_context_menu,
|
||||
classes = (VIEW3D_MT_brush_context_menu,
|
||||
VIEW3D_MT_brush_gpencil_context_menu,
|
||||
VIEW3D_MT_brush_context_menu_paint_modes,
|
||||
VIEW3D_PT_tools_object_options,
|
||||
|
@ -2705,8 +2674,7 @@ classes = (
|
|||
VIEW3D_PT_tools_brush_swatches_channels,
|
||||
VIEW3D_PT_tools_persistent_base_channels,
|
||||
VIEW3D_PT_sculpt_dyntopo_advanced,
|
||||
SCULPT_OT_set_dyntopo_mode
|
||||
)
|
||||
SCULPT_OT_set_dyntopo_mode)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
from bpy.utils import register_class
|
||||
|
|
|
@ -475,7 +475,8 @@ bool BKE_pbvh_bmesh_update_topology(
|
|||
bool updatePBVH,
|
||||
DyntopoMaskCB mask_cb,
|
||||
void *mask_cb_data,
|
||||
int custom_max_steps); // if 0, will use defaul hueristics for max steps
|
||||
int custom_max_steps, // if 0, will use defaul hueristics for max steps
|
||||
bool disable_surface_relax);
|
||||
|
||||
bool BKE_pbvh_bmesh_update_topology_nodes(PBVH *pbvh,
|
||||
bool (*searchcb)(PBVHNode *node, void *data),
|
||||
|
@ -490,7 +491,8 @@ bool BKE_pbvh_bmesh_update_topology_nodes(PBVH *pbvh,
|
|||
int sym_axis,
|
||||
bool updatePBVH,
|
||||
DyntopoMaskCB mask_cb,
|
||||
void *mask_cb_data);
|
||||
void *mask_cb_data,
|
||||
bool disable_surface_relax);
|
||||
/* Node Access */
|
||||
|
||||
void BKE_pbvh_check_tri_areas(PBVH *pbvh, PBVHNode *node);
|
||||
|
@ -801,8 +803,20 @@ void BKE_pbvh_bmesh_free_tris(PBVH *pbvh, PBVHNode *node);
|
|||
symmetrize.*/
|
||||
void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh);
|
||||
|
||||
/* saves all bmesh references to internal indices, to be restored later */
|
||||
void BKE_pbvh_bmesh_save_indices(PBVH *pbvh);
|
||||
|
||||
/* restore bmesh references from previously indices saved by BKE_pbvh_bmesh_save_indices */
|
||||
void BKE_pbvh_bmesh_from_saved_indices(PBVH *pbvh);
|
||||
|
||||
/* wraps calls to BM_mesh_toolflags_set in BKE_pbvh_bmesh_save_indices and
|
||||
* BKE_pbvh_bmesh_from_saved_indices */
|
||||
void BKE_pbvh_bmesh_set_toolflags(PBVH *pbvh, bool use_toolflags);
|
||||
|
||||
void BKE_pbvh_bmesh_remove_face(PBVH *pbvh, struct BMFace *f, bool log_face);
|
||||
void BKE_pbvh_bmesh_remove_edge(PBVH *pbvh, struct BMEdge *e, bool log_vert);
|
||||
void BKE_pbvh_bmesh_remove_vertex(PBVH *pbvh, struct BMVert *v, bool log_vert);
|
||||
|
||||
void BKE_pbvh_bmesh_add_face(PBVH *pbvh, struct BMFace *f, bool log_face, bool force_tree_walk);
|
||||
|
||||
// note that e_tri and f_example are allowed to be NULL
|
||||
|
|
|
@ -205,6 +205,7 @@ places in rna_engine_codebase are relevent:
|
|||
"used for topology rake", 1.0f, 0.001f, 5.0f, 0.01f, 2.0f, false)
|
||||
MAKE_FLOAT_EX_FLAG(dyntopo_radius_scale, "Radius Scale", "Ratio between the brush radius and the radius that is going to be "
|
||||
"used for DynTopo", 1.0f, 0.001f, 5.0f, 0.01f, 2.0f, false, BRUSH_CHANNEL_INHERIT)
|
||||
MAKE_BOOL(dyntopo_disable_smooth, "Disable Dyntopo Smooth", "Disable the small amount of smoothing dyntopo applies to improve numerical stability", false)
|
||||
MAKE_FLOAT_EX(projection, "Projection", "Amount of volume preserving projection", 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, false)
|
||||
MAKE_FLOAT_EX(autosmooth_projection, "Auto-Smooth Projection", "Amount of volume preserving projection", 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, false)
|
||||
MAKE_FLOAT_EX(topology_rake_projection, "Rake Projection", "Amount of volume preserving projection", 0.975f, 0.0f, 1.0f, 0.0f, 1.0f, false)
|
||||
|
|
|
@ -1002,6 +1002,7 @@ void BKE_brush_builtin_patch(Brush *brush, int tool)
|
|||
ADDCH(concave_mask_factor);
|
||||
|
||||
ADDCH(dyntopo_disabled);
|
||||
ADDCH(dyntopo_disable_smooth);
|
||||
|
||||
ADDCH(dyntopo_detail_mode);
|
||||
ADDCH(dyntopo_mode)->flag;
|
||||
|
|
|
@ -1257,6 +1257,14 @@ void BKE_pbvh_bmesh_remove_face(PBVH *pbvh, BMFace *f, bool log_face)
|
|||
pbvh_bmesh_face_remove(pbvh, f, log_face, true, true);
|
||||
}
|
||||
|
||||
|
||||
void BKE_pbvh_bmesh_remove_edge(PBVH *pbvh, BMEdge *e, bool log_vert)
|
||||
{
|
||||
if (log_vert) {
|
||||
BM_log_edge_removed(pbvh->bm_log, e);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_pbvh_bmesh_remove_vertex(PBVH *pbvh, BMVert *v, bool log_vert)
|
||||
{
|
||||
pbvh_bmesh_vert_remove(pbvh, v);
|
||||
|
@ -1973,9 +1981,9 @@ BLI_INLINE int dyntopo_thread_rand(int seed)
|
|||
return (seed * multiplier + addend) & mask;
|
||||
}
|
||||
|
||||
static void long_edge_queue_task_cb(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
ATTR_NO_OPT static void long_edge_queue_task_cb(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
{
|
||||
EdgeQueueThreadData *tdata = ((EdgeQueueThreadData *)userdata) + n;
|
||||
PBVHNode *node = tdata->node;
|
||||
|
@ -1989,6 +1997,7 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
|
|||
BMFace *f, **faces = NULL;
|
||||
BLI_array_declare(faces);
|
||||
const int cd_dyn_vert = tdata->pbvh->cd_dyn_vert;
|
||||
bool do_smooth = eq_ctx->surface_smooth_fac > 0.0f;
|
||||
|
||||
#if 1
|
||||
# if 0
|
||||
|
@ -2052,7 +2061,7 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
|
|||
// but tangentially to surface.
|
||||
int randval = (seed = dyntopo_thread_rand(seed)) & 255;
|
||||
|
||||
if (randval > 127) {
|
||||
if (do_smooth && randval > 127) {
|
||||
surface_smooth_v_safe(tdata->pbvh, l_iter->v, eq_ctx->surface_smooth_fac);
|
||||
}
|
||||
|
||||
|
@ -5269,7 +5278,8 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
|
|||
bool updatePBVH,
|
||||
DyntopoMaskCB mask_cb,
|
||||
void *mask_cb_data,
|
||||
int custom_max_steps)
|
||||
int custom_max_steps,
|
||||
bool disable_surface_relax)
|
||||
{
|
||||
|
||||
/* 2 is enough for edge faces - manifold edge */
|
||||
|
@ -5322,7 +5332,10 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
|
|||
|
||||
float safe_smooth;
|
||||
|
||||
if ((mode & PBVH_Subdivide) && (!(mode & PBVH_Collapse) || (mode & PBVH_LocalCollapse))) {
|
||||
if (disable_surface_relax) {
|
||||
safe_smooth = 0.0f;
|
||||
}
|
||||
else if ((mode & PBVH_Subdivide) && (!(mode & PBVH_Collapse) || (mode & PBVH_LocalCollapse))) {
|
||||
safe_smooth = DYNTOPO_SAFE_SMOOTH_SUBD_ONLY_FAC;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1885,7 +1885,8 @@ bool BKE_pbvh_bmesh_update_topology_nodes(PBVH *pbvh,
|
|||
int sym_axis,
|
||||
bool updatePBVH,
|
||||
DyntopoMaskCB mask_cb,
|
||||
void *mask_cb_data)
|
||||
void *mask_cb_data,
|
||||
bool disable_surface_relax)
|
||||
{
|
||||
bool modified = false;
|
||||
|
||||
|
@ -1915,7 +1916,8 @@ bool BKE_pbvh_bmesh_update_topology_nodes(PBVH *pbvh,
|
|||
updatePBVH,
|
||||
mask_cb,
|
||||
mask_cb_data,
|
||||
0);
|
||||
0,
|
||||
disable_surface_relax);
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
@ -5151,3 +5153,208 @@ void pbvh_bmesh_do_cache_test()
|
|||
// pbvh_bmesh_cache_test_default_params(¶ms);
|
||||
// pbvh_bmesh_cache_test(¶ms, &bm, &pbvh);
|
||||
}
|
||||
|
||||
/* saves all bmesh references to internal indices, to be restored later */
|
||||
ATTR_NO_OPT void BKE_pbvh_bmesh_save_indices(PBVH *pbvh)
|
||||
{
|
||||
BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT | BM_EDGE | BM_FACE);
|
||||
|
||||
BMFace *f;
|
||||
BMVert *v;
|
||||
BMIter iter;
|
||||
|
||||
int j = 0;
|
||||
|
||||
BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l = f->l_first;
|
||||
|
||||
do {
|
||||
l->head.index = j++;
|
||||
} while ((l = l->next) != f->l_first);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pbvh->totnode; i++) {
|
||||
PBVHNode *node = pbvh->nodes + i;
|
||||
|
||||
if (!(node->flag & PBVH_Leaf)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
node->prim_indices = MEM_calloc_arrayN(1 + node->bm_faces->length +
|
||||
node->bm_unique_verts->length,
|
||||
sizeof(int),
|
||||
"saved bmesh indices");
|
||||
|
||||
int j = 0;
|
||||
|
||||
TGSET_ITER (f, node->bm_faces) {
|
||||
node->prim_indices[j++] = f->head.index;
|
||||
}
|
||||
TGSET_ITER_END;
|
||||
|
||||
// flag start of vertex array
|
||||
node->prim_indices[j++] = -1;
|
||||
|
||||
TGSET_ITER (v, node->bm_unique_verts) {
|
||||
node->prim_indices[j++] = v->head.index;
|
||||
}
|
||||
TGSET_ITER_END;
|
||||
|
||||
node->totprim = j;
|
||||
|
||||
// don't try to save invalid triangulation
|
||||
if (node->flag & PBVH_UpdateTris) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// now do tribufs
|
||||
for (j = 0; j < node->tot_tri_buffers + 1; j++) {
|
||||
PBVHTriBuf *tribuf = j == node->tot_tri_buffers ? node->tribuf : node->tri_buffers + j;
|
||||
|
||||
if (!tribuf) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int k = 0; k < tribuf->totvert; k++) {
|
||||
if (i == 35 && k == 12) {
|
||||
printf("eek!");
|
||||
}
|
||||
|
||||
tribuf->verts[k].i = ((BMVert *)tribuf->verts[k].i)->head.index;
|
||||
}
|
||||
|
||||
for (int k = 0; k < tribuf->totloop; k++) {
|
||||
tribuf->loops[k] = ((BMLoop *)tribuf->loops[k])->head.index;
|
||||
}
|
||||
|
||||
for (int k = 0; k < tribuf->tottri; k++) {
|
||||
PBVHTri *tri = tribuf->tris + k;
|
||||
BMFace *f = (BMFace *)tri->f.i;
|
||||
|
||||
tri->f.i = f->head.index;
|
||||
|
||||
for (int l = 0; l < 3; l++) {
|
||||
tri->l[l] = ((BMLoop *)tri->l[l])->head.index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* restore bmesh references from previously indices saved by BKE_pbvh_bmesh_save_indices */
|
||||
ATTR_NO_OPT void BKE_pbvh_bmesh_from_saved_indices(PBVH *pbvh)
|
||||
{
|
||||
BM_mesh_elem_table_ensure(pbvh->bm, BM_VERT | BM_EDGE | BM_FACE);
|
||||
BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT | BM_EDGE | BM_FACE);
|
||||
|
||||
BMLoop **ltable = NULL;
|
||||
BLI_array_declare(ltable);
|
||||
|
||||
BMFace *f;
|
||||
BMIter iter;
|
||||
int i = 0;
|
||||
|
||||
BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l = f->l_first;
|
||||
|
||||
do {
|
||||
l->head.index = i++;
|
||||
BLI_array_append(ltable, l);
|
||||
} while ((l = l->next) != f->l_first);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pbvh->totnode; i++) {
|
||||
PBVHNode *node = pbvh->nodes + i;
|
||||
|
||||
if (!(node->flag & PBVH_Leaf)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BLI_table_gset_free(node->bm_unique_verts, NULL);
|
||||
BLI_table_gset_free(node->bm_faces, NULL);
|
||||
|
||||
if (node->bm_other_verts) {
|
||||
BLI_table_gset_free(node->bm_other_verts, NULL);
|
||||
}
|
||||
|
||||
node->bm_other_verts = BLI_table_gset_new("bm_other_verts");
|
||||
node->flag |= PBVH_UpdateOtherVerts;
|
||||
|
||||
node->bm_faces = BLI_table_gset_new("bm_faces");
|
||||
node->bm_unique_verts = BLI_table_gset_new("bm_verts");
|
||||
|
||||
int j = 0;
|
||||
int *data = node->prim_indices;
|
||||
|
||||
while (data[j] != -1 && j < node->totprim) {
|
||||
BMFace *f = pbvh->bm->ftable[data[j]];
|
||||
BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, i);
|
||||
|
||||
BLI_table_gset_insert(node->bm_faces, f);
|
||||
j++;
|
||||
}
|
||||
|
||||
j++;
|
||||
|
||||
while (j < node->totprim) {
|
||||
if (data[j] < 0 || data[j] >= pbvh->bm->totvert) {
|
||||
printf("%s: bad vertex at index %d!\n", __func__, data[j]);
|
||||
continue;
|
||||
}
|
||||
BMVert *v = pbvh->bm->vtable[data[j]];
|
||||
BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, i);
|
||||
|
||||
BLI_table_gset_insert(node->bm_unique_verts, v);
|
||||
j++;
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(node->prim_indices);
|
||||
|
||||
// don't try to load invalid triangulation
|
||||
if (node->flag & PBVH_UpdateTris) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < node->tot_tri_buffers + 1; j++) {
|
||||
PBVHTriBuf *tribuf = j == node->tot_tri_buffers ? node->tribuf : node->tri_buffers + j;
|
||||
|
||||
if (!tribuf) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int k = 0; k < tribuf->totvert; k++) {
|
||||
tribuf->verts[k].i = (intptr_t)pbvh->bm->vtable[tribuf->verts[k].i];
|
||||
}
|
||||
|
||||
for (int k = 0; k < tribuf->totloop; k++) {
|
||||
tribuf->loops[k] = (uintptr_t)ltable[tribuf->loops[k]];
|
||||
}
|
||||
|
||||
for (int k = 0; k < tribuf->tottri; k++) {
|
||||
PBVHTri *tri = tribuf->tris + k;
|
||||
|
||||
for (int l = 0; l < 3; l++) {
|
||||
tri->l[l] = (uintptr_t)ltable[tri->l[l]];
|
||||
}
|
||||
|
||||
tri->f.i = (intptr_t)pbvh->bm->ftable[tri->f.i];
|
||||
}
|
||||
}
|
||||
|
||||
node->prim_indices = NULL;
|
||||
node->totprim = 0;
|
||||
}
|
||||
|
||||
BLI_array_free(ltable);
|
||||
}
|
||||
|
||||
void BKE_pbvh_bmesh_set_toolflags(PBVH *pbvh, bool use_toolflags)
|
||||
{
|
||||
if (use_toolflags == pbvh->bm->use_toolflags) {
|
||||
return;
|
||||
}
|
||||
|
||||
BKE_pbvh_bmesh_save_indices(pbvh);
|
||||
BM_mesh_toolflags_set(pbvh->bm, use_toolflags);
|
||||
BKE_pbvh_bmesh_from_saved_indices(pbvh);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ extern "C" {
|
|||
struct MemArena;
|
||||
typedef struct MemArena MemArena;
|
||||
|
||||
int BLI_memarena_size(const struct MemArena *ma);
|
||||
|
||||
struct MemArena *BLI_memarena_new(const size_t bufsize,
|
||||
const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
|
||||
ATTR_NONNULL(2) ATTR_MALLOC;
|
||||
|
|
|
@ -53,6 +53,8 @@ typedef struct {
|
|||
unsigned int i;
|
||||
} SmallHashIter;
|
||||
|
||||
int BLI_smallhash_memuse(SmallHash *sh);
|
||||
|
||||
void BLI_smallhash_init_ex(SmallHash *sh, const unsigned int nentries_reserve) ATTR_NONNULL(1);
|
||||
void BLI_smallhash_init(SmallHash *sh) ATTR_NONNULL(1);
|
||||
void BLI_smallhash_release(SmallHash *sh) ATTR_NONNULL(1);
|
||||
|
|
|
@ -64,6 +64,17 @@ struct MemArena {
|
|||
bool use_calloc;
|
||||
};
|
||||
|
||||
int BLI_memarena_size(const struct MemArena *ma)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
for (struct MemBuf *buf = ma->bufs; buf; buf = buf->next) {
|
||||
ret += (int)ma->bufsize;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void memarena_buf_free_all(struct MemBuf *mb)
|
||||
{
|
||||
while (mb != NULL) {
|
||||
|
|
|
@ -118,6 +118,11 @@ BLI_INLINE bool smallhash_val_is_used(const void *val)
|
|||
extern const uint BLI_ghash_hash_sizes[];
|
||||
#define hashsizes BLI_ghash_hash_sizes
|
||||
|
||||
int BLI_smallhash_memuse(SmallHash *sh)
|
||||
{
|
||||
return (int)sh->nbuckets * sizeof(SmallHashEntry) + (int)sizeof(SmallHash);
|
||||
}
|
||||
|
||||
BLI_INLINE uintptr_t smallhash_key(const uintptr_t key)
|
||||
{
|
||||
#if 1
|
||||
|
|
|
@ -1248,3 +1248,78 @@ void bm_update_idmap_cdlayers(BMesh *bm)
|
|||
bm->idmap.cd_id_off[BM_LOOP] = CustomData_get_offset(&bm->ldata, CD_MESH_ID);
|
||||
bm->idmap.cd_id_off[BM_FACE] = CustomData_get_offset(&bm->pdata, CD_MESH_ID);
|
||||
}
|
||||
|
||||
ATTR_NO_OPT void bm_rebuild_idmap(BMesh *bm)
|
||||
{
|
||||
CustomData *cdatas[4] = {
|
||||
&bm->vdata,
|
||||
&bm->edata,
|
||||
&bm->ldata,
|
||||
&bm->pdata,
|
||||
};
|
||||
|
||||
if (bm->idmap.flag & BM_HAS_ID_MAP) {
|
||||
if (bm->idmap.flag & BM_NO_REUSE_IDS) {
|
||||
if (bm->idmap.ghash) {
|
||||
BLI_ghash_clear(bm->idmap.ghash, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
bm->idmap.ghash = BLI_ghash_ptr_new("bm->idmap.ghash");
|
||||
}
|
||||
}
|
||||
else if (bm->idmap.map) {
|
||||
memset(bm->idmap.map, 0, sizeof(void *) * bm->idmap.map_size);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int type = 1 << i;
|
||||
|
||||
if (!(bm->idmap.flag & type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int cd_off = bm->idmap.cd_id_off[type];
|
||||
cd_off = CustomData_get_offset(cdatas[i], CD_MESH_ID);
|
||||
|
||||
if (bm->idmap.flag & BM_NO_REUSE_IDS) {
|
||||
BLI_mempool_iter iter;
|
||||
|
||||
BLI_mempool_iternew((&bm->vpool)[i], &iter);
|
||||
BMElem *elem = (BMElem *)BLI_mempool_iterstep(&iter);
|
||||
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&iter)) {
|
||||
void **val;
|
||||
|
||||
if (!BLI_ghash_ensure_p(bm->idmap.ghash, (void *)elem, &val)) {
|
||||
*val = POINTER_FROM_INT(BM_ELEM_CD_GET_INT(elem, cd_off));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_mempool_iter iter;
|
||||
|
||||
BLI_mempool_iternew((&bm->vpool)[i], &iter);
|
||||
BMElem *elem = (BMElem *)BLI_mempool_iterstep(&iter);
|
||||
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&iter)) {
|
||||
void **val;
|
||||
int id = BM_ELEM_CD_GET_INT(elem, cd_off);
|
||||
|
||||
if (!bm->idmap.map || bm->idmap.map_size <= id) {
|
||||
int size = (2 + id);
|
||||
size += size >> 1;
|
||||
|
||||
if (!bm->idmap.map) {
|
||||
bm->idmap.map = MEM_calloc_arrayN(size, sizeof(*bm->idmap.map), "bm->idmap.map");
|
||||
}
|
||||
else {
|
||||
bm->idmap.map = MEM_recallocN(bm->idmap.map, sizeof(void *) * size);
|
||||
}
|
||||
|
||||
bm->idmap.map_size = size;
|
||||
}
|
||||
|
||||
bm->idmap.map[BM_ELEM_CD_GET_INT(elem, cd_off)] = elem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "BLI_math.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_mempool.h"
|
||||
#include "BLI_smallhash.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
@ -57,6 +58,66 @@
|
|||
|
||||
#define CUSTOMDATA
|
||||
|
||||
#define BM_LOG_USE_SMALLHASH
|
||||
|
||||
#ifdef BM_LOG_USE_SMALLHASH
|
||||
static SmallHash *new_smallhash()
|
||||
{
|
||||
SmallHash *sh = MEM_callocN(sizeof(*sh), "smallhash for dyntopo");
|
||||
|
||||
BLI_smallhash_init(sh);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
static void free_smallhash(SmallHash *sh)
|
||||
{
|
||||
BLI_smallhash_release(sh);
|
||||
MEM_freeN(sh);
|
||||
}
|
||||
|
||||
static void smallhash_reserve(SmallHash *sh, int n)
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct myiter {
|
||||
SmallHashIter iter;
|
||||
uintptr_t key;
|
||||
void *data;
|
||||
} myiter;
|
||||
|
||||
# ifdef GHASH_ITER
|
||||
# undef GHASH_ITER
|
||||
# endif
|
||||
|
||||
# define GHashIterator myiter
|
||||
|
||||
# define BLI_ghash_free(sh, a, b) free_smallhash(sh)
|
||||
# define BLI_ghash_int_new_ex(a, b) new_smallhash()
|
||||
# define BLI_ghash_reserve(sh, n) smallhash_reserve(sh, n)
|
||||
# define BLI_ghash_new(a, b, c) new_smallhash()
|
||||
# define BLI_ghash_insert(sh, key, val) BLI_smallhash_insert((sh), (uintptr_t)(key), (val))
|
||||
# define BLI_ghash_remove(sh, key, a, b) BLI_smallhash_remove((sh), (uintptr_t)(key))
|
||||
# define BLI_ghash_lookup(sh, key) BLI_smallhash_lookup((sh), (uintptr_t)(key))
|
||||
# define BLI_ghash_lookup_p(sh, key) BLI_smallhash_lookup_p((sh), (uintptr_t)(key))
|
||||
# define BLI_ghash_haskey(sh, key) BLI_smallhash_haskey((sh), (uintptr_t)(key))
|
||||
# define GHASH_ITER(iter1, sh) \
|
||||
for (iter1.data = BLI_smallhash_iternew(sh, &iter1.iter, &iter1.key); iter1.data; \
|
||||
iter1.data = BLI_smallhash_iternext(&iter1.iter, &iter1.key))
|
||||
# define BLI_ghashIterator_getKey(iter) ((void *)(iter)->key)
|
||||
# define BLI_ghashIterator_getValue(iter) ((void *)(iter)->data)
|
||||
# define BLI_ghash_ensure_p(sh, key, val) BLI_smallhash_ensure_p(sh, (uintptr_t)(key), val)
|
||||
# define BLI_ghash_reinsert(sh, key, val, a, b) BLI_smallhash_reinsert(sh, (uintptr_t)(key), val)
|
||||
# define BLI_ghash_len(sh) (int)sh->nentries
|
||||
# define GHash SmallHash
|
||||
|
||||
# ifdef BM_ELEM_FROM_ID
|
||||
# undef BM_ELEM_FROM_ID
|
||||
# endif
|
||||
|
||||
# define BM_ELEM_FROM_ID(bm, id) bm->idmap.map[id]
|
||||
|
||||
#endif
|
||||
//#define DEBUG_LOG_REFCOUNTNG
|
||||
//#define PRINT_LOG_REF_COUNTING
|
||||
|
||||
|
@ -2406,6 +2467,40 @@ void BM_log_face_modified(BMLog *log, BMFace *f)
|
|||
bm_log_face_customdata(log->bm, log, f, lf);
|
||||
}
|
||||
|
||||
bool BM_log_has_vert(BMLog *log, BMVert *v)
|
||||
{
|
||||
int id = BM_ELEM_GET_ID(log->bm, v);
|
||||
|
||||
bool ret = BLI_ghash_haskey(log->current_entry->added_verts, POINTER_FROM_INT(id));
|
||||
ret = ret || BLI_ghash_haskey(log->current_entry->deleted_verts, POINTER_FROM_INT(id));
|
||||
ret = ret || BLI_ghash_haskey(log->current_entry->modified_verts, POINTER_FROM_INT(id));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool BM_log_has_edge(BMLog *log, BMEdge *e)
|
||||
{
|
||||
int id = BM_ELEM_GET_ID(log->bm, e);
|
||||
|
||||
bool ret = BLI_ghash_haskey(log->current_entry->added_edges, POINTER_FROM_INT(id));
|
||||
ret = ret || BLI_ghash_haskey(log->current_entry->deleted_edges, POINTER_FROM_INT(id));
|
||||
ret = ret || BLI_ghash_haskey(log->current_entry->modified_edges, POINTER_FROM_INT(id));
|
||||
ret = ret || BLI_ghash_haskey(log->current_entry->deleted_edges_post, POINTER_FROM_INT(id));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool BM_log_has_face(BMLog *log, BMFace *f)
|
||||
{
|
||||
int id = BM_ELEM_GET_ID(log->bm, f);
|
||||
|
||||
bool ret = BLI_ghash_haskey(log->current_entry->added_faces, POINTER_FROM_INT(id));
|
||||
ret = ret || BLI_ghash_haskey(log->current_entry->deleted_faces, POINTER_FROM_INT(id));
|
||||
ret = ret || BLI_ghash_haskey(log->current_entry->modified_faces, POINTER_FROM_INT(id));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Log a new face as added to the BMesh
|
||||
*
|
||||
* The new face gets a unique ID assigned. It is then added to a map
|
||||
|
@ -2875,7 +2970,7 @@ void bm_log_print(const BMLog *log, const char *description)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int bmlog_entry_memsize(BMLogEntry *entry)
|
||||
ATTR_NO_OPT static int bmlog_entry_memsize(BMLogEntry *entry)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -2888,6 +2983,11 @@ static int bmlog_entry_memsize(BMLogEntry *entry)
|
|||
ret += entry->ldata.pool ? (int)BLI_mempool_get_size(entry->ldata.pool) : 0;
|
||||
ret += entry->pdata.pool ? (int)BLI_mempool_get_size(entry->pdata.pool) : 0;
|
||||
|
||||
ret += BLI_memarena_size(entry->arena);
|
||||
|
||||
if (BLI_memarena_size(entry->arena)) {
|
||||
printf("%d\n", BLI_memarena_size(entry->arena));
|
||||
}
|
||||
// estimate ghash memory usage
|
||||
ret += (int)BLI_ghash_len(entry->added_verts) * (int)sizeof(void *) * 4;
|
||||
ret += (int)BLI_ghash_len(entry->added_edges) * (int)sizeof(void *) * 4;
|
||||
|
|
|
@ -156,3 +156,7 @@ void BM_log_undo_skip(BMesh *bm, BMLog *log);
|
|||
BMVert *BM_log_edge_split_do(BMLog *log, BMEdge *e, BMVert *v, BMEdge **newe, float t);
|
||||
|
||||
int BM_log_entry_size(BMLogEntry *entry);
|
||||
|
||||
bool BM_log_has_vert(BMLog *log, BMVert *v);
|
||||
bool BM_log_has_edge(BMLog *log, BMEdge *e);
|
||||
bool BM_log_has_face(BMLog *log, BMFace *f);
|
||||
|
|
|
@ -1642,6 +1642,8 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
BLI_mempool_destroy(bm->fpool);
|
||||
bm->fpool = fpool_dst;
|
||||
}
|
||||
|
||||
bm_rebuild_idmap(bm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1058,6 +1058,7 @@ static BMOpDefine bmo_extrude_face_region_def = {
|
|||
},
|
||||
/* slots_out */
|
||||
{{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
|
||||
{"side_geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
|
||||
{{'\0'}},
|
||||
},
|
||||
bmo_extrude_face_region_exec,
|
||||
|
@ -2111,89 +2112,87 @@ static BMOpDefine bmo_symmetrize_def = {
|
|||
#undef BM_EDGE
|
||||
#undef BM_VERT
|
||||
|
||||
const BMOpDefine *bmo_opdefines[] = {
|
||||
&bmo_average_vert_facedata_def,
|
||||
&bmo_beautify_fill_def,
|
||||
&bmo_bevel_def,
|
||||
&bmo_bisect_edges_def,
|
||||
&bmo_bmesh_to_mesh_def,
|
||||
&bmo_bridge_loops_def,
|
||||
&bmo_collapse_def,
|
||||
&bmo_collapse_uvs_def,
|
||||
&bmo_connect_verts_def,
|
||||
&bmo_connect_verts_concave_def,
|
||||
&bmo_connect_verts_nonplanar_def,
|
||||
&bmo_connect_vert_pair_def,
|
||||
&bmo_contextual_create_def,
|
||||
const BMOpDefine *bmo_opdefines[] = {&bmo_average_vert_facedata_def,
|
||||
&bmo_beautify_fill_def,
|
||||
&bmo_bevel_def,
|
||||
&bmo_bisect_edges_def,
|
||||
&bmo_bmesh_to_mesh_def,
|
||||
&bmo_bridge_loops_def,
|
||||
&bmo_collapse_def,
|
||||
&bmo_collapse_uvs_def,
|
||||
&bmo_connect_verts_def,
|
||||
&bmo_connect_verts_concave_def,
|
||||
&bmo_connect_verts_nonplanar_def,
|
||||
&bmo_connect_vert_pair_def,
|
||||
&bmo_contextual_create_def,
|
||||
#ifdef WITH_BULLET
|
||||
&bmo_convex_hull_def,
|
||||
&bmo_convex_hull_def,
|
||||
#endif
|
||||
&bmo_create_circle_def,
|
||||
&bmo_create_cone_def,
|
||||
&bmo_create_cube_def,
|
||||
&bmo_create_grid_def,
|
||||
&bmo_create_icosphere_def,
|
||||
&bmo_create_monkey_def,
|
||||
&bmo_create_uvsphere_def,
|
||||
&bmo_create_vert_def,
|
||||
&bmo_delete_def,
|
||||
&bmo_dissolve_edges_def,
|
||||
&bmo_dissolve_faces_def,
|
||||
&bmo_dissolve_verts_def,
|
||||
&bmo_dissolve_limit_def,
|
||||
&bmo_dissolve_degenerate_def,
|
||||
&bmo_duplicate_def,
|
||||
&bmo_holes_fill_def,
|
||||
&bmo_face_attribute_fill_def,
|
||||
&bmo_offset_edgeloops_def,
|
||||
&bmo_edgeloop_fill_def,
|
||||
&bmo_edgenet_fill_def,
|
||||
&bmo_edgenet_prepare_def,
|
||||
&bmo_extrude_discrete_faces_def,
|
||||
&bmo_extrude_edge_only_def,
|
||||
&bmo_extrude_face_region_def,
|
||||
&bmo_extrude_vert_indiv_def,
|
||||
&bmo_find_doubles_def,
|
||||
&bmo_grid_fill_def,
|
||||
&bmo_inset_individual_def,
|
||||
&bmo_inset_region_def,
|
||||
&bmo_join_triangles_def,
|
||||
&bmo_mesh_to_bmesh_def,
|
||||
&bmo_mirror_def,
|
||||
&bmo_object_load_bmesh_def,
|
||||
&bmo_pointmerge_def,
|
||||
&bmo_pointmerge_facedata_def,
|
||||
&bmo_poke_def,
|
||||
&bmo_recalc_face_normals_def,
|
||||
&bmo_planar_faces_def,
|
||||
&bmo_region_extend_def,
|
||||
&bmo_remove_doubles_def,
|
||||
&bmo_reverse_colors_def,
|
||||
&bmo_reverse_faces_def,
|
||||
&bmo_reverse_uvs_def,
|
||||
&bmo_rotate_colors_def,
|
||||
&bmo_rotate_def,
|
||||
&bmo_rotate_edges_def,
|
||||
&bmo_rotate_uvs_def,
|
||||
&bmo_scale_def,
|
||||
&bmo_smooth_vert_def,
|
||||
&bmo_smooth_laplacian_vert_def,
|
||||
&bmo_solidify_def,
|
||||
&bmo_spin_def,
|
||||
&bmo_split_def,
|
||||
&bmo_split_edges_def,
|
||||
&bmo_subdivide_edges_def,
|
||||
&bmo_subdivide_edgering_def,
|
||||
&bmo_bisect_plane_def,
|
||||
&bmo_symmetrize_def,
|
||||
&bmo_transform_def,
|
||||
&bmo_translate_def,
|
||||
&bmo_triangle_fill_def,
|
||||
&bmo_triangulate_def,
|
||||
&bmo_unsubdivide_def,
|
||||
&bmo_weld_verts_def,
|
||||
&bmo_wireframe_def,
|
||||
&bmo_test_mres_smooth_def
|
||||
};
|
||||
&bmo_create_circle_def,
|
||||
&bmo_create_cone_def,
|
||||
&bmo_create_cube_def,
|
||||
&bmo_create_grid_def,
|
||||
&bmo_create_icosphere_def,
|
||||
&bmo_create_monkey_def,
|
||||
&bmo_create_uvsphere_def,
|
||||
&bmo_create_vert_def,
|
||||
&bmo_delete_def,
|
||||
&bmo_dissolve_edges_def,
|
||||
&bmo_dissolve_faces_def,
|
||||
&bmo_dissolve_verts_def,
|
||||
&bmo_dissolve_limit_def,
|
||||
&bmo_dissolve_degenerate_def,
|
||||
&bmo_duplicate_def,
|
||||
&bmo_holes_fill_def,
|
||||
&bmo_face_attribute_fill_def,
|
||||
&bmo_offset_edgeloops_def,
|
||||
&bmo_edgeloop_fill_def,
|
||||
&bmo_edgenet_fill_def,
|
||||
&bmo_edgenet_prepare_def,
|
||||
&bmo_extrude_discrete_faces_def,
|
||||
&bmo_extrude_edge_only_def,
|
||||
&bmo_extrude_face_region_def,
|
||||
&bmo_extrude_vert_indiv_def,
|
||||
&bmo_find_doubles_def,
|
||||
&bmo_grid_fill_def,
|
||||
&bmo_inset_individual_def,
|
||||
&bmo_inset_region_def,
|
||||
&bmo_join_triangles_def,
|
||||
&bmo_mesh_to_bmesh_def,
|
||||
&bmo_mirror_def,
|
||||
&bmo_object_load_bmesh_def,
|
||||
&bmo_pointmerge_def,
|
||||
&bmo_pointmerge_facedata_def,
|
||||
&bmo_poke_def,
|
||||
&bmo_recalc_face_normals_def,
|
||||
&bmo_planar_faces_def,
|
||||
&bmo_region_extend_def,
|
||||
&bmo_remove_doubles_def,
|
||||
&bmo_reverse_colors_def,
|
||||
&bmo_reverse_faces_def,
|
||||
&bmo_reverse_uvs_def,
|
||||
&bmo_rotate_colors_def,
|
||||
&bmo_rotate_def,
|
||||
&bmo_rotate_edges_def,
|
||||
&bmo_rotate_uvs_def,
|
||||
&bmo_scale_def,
|
||||
&bmo_smooth_vert_def,
|
||||
&bmo_smooth_laplacian_vert_def,
|
||||
&bmo_solidify_def,
|
||||
&bmo_spin_def,
|
||||
&bmo_split_def,
|
||||
&bmo_split_edges_def,
|
||||
&bmo_subdivide_edges_def,
|
||||
&bmo_subdivide_edgering_def,
|
||||
&bmo_bisect_plane_def,
|
||||
&bmo_symmetrize_def,
|
||||
&bmo_transform_def,
|
||||
&bmo_translate_def,
|
||||
&bmo_triangle_fill_def,
|
||||
&bmo_triangulate_def,
|
||||
&bmo_unsubdivide_def,
|
||||
&bmo_weld_verts_def,
|
||||
&bmo_wireframe_def,
|
||||
&bmo_test_mres_smooth_def};
|
||||
|
||||
const int bmo_opdefines_total = ARRAY_SIZE(bmo_opdefines);
|
||||
|
|
|
@ -52,6 +52,7 @@ int bmesh_elem_check(void *element, const char htype);
|
|||
int bmesh_radial_length(const BMLoop *l);
|
||||
int bmesh_disk_count_at_most(const BMVert *v, const int count_max);
|
||||
int bmesh_disk_count(const BMVert *v);
|
||||
void bm_rebuild_idmap(BMesh *bm);
|
||||
|
||||
/**
|
||||
* Internal BMHeader.api_flag
|
||||
|
|
|
@ -35,12 +35,7 @@
|
|||
|
||||
#define USE_EDGE_REGION_FLAGS
|
||||
|
||||
enum {
|
||||
EXT_INPUT = 1,
|
||||
EXT_KEEP = 2,
|
||||
EXT_DEL = 4,
|
||||
EXT_TAG = 8,
|
||||
};
|
||||
enum { EXT_INPUT = 1, EXT_KEEP = 2, EXT_DEL = 4, EXT_TAG = 8, EXT_ALT = 16 };
|
||||
|
||||
#define VERT_MARK 1
|
||||
#define EDGE_MARK 1
|
||||
|
@ -332,13 +327,17 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
|||
BMFace *f;
|
||||
bool found, delorig = false;
|
||||
BMOpSlot *slot_facemap_out;
|
||||
BMOpSlot *slot_sidemap_out;
|
||||
BMOpSlot *slot_edges_exclude;
|
||||
|
||||
const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
|
||||
const bool use_normal_from_adjacent = BMO_slot_bool_get(op->slots_in,
|
||||
"use_normal_from_adjacent");
|
||||
const bool use_dissolve_ortho_edges = BMO_slot_bool_get(op->slots_in,
|
||||
"use_dissolve_ortho_edges");
|
||||
|
||||
bool side_tag = EXT_ALT;
|
||||
|
||||
/* initialize our sub-operators */
|
||||
BMO_op_initf(bm,
|
||||
&dupeop,
|
||||
|
@ -552,29 +551,37 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
|||
char e_hflag[2];
|
||||
bool e_hflag_ok = bm_extrude_region_edge_flag(f_verts[2], e_hflag);
|
||||
f_edges[1] = BM_edge_create(bm, f_verts[1], f_verts[2], NULL, BM_CREATE_NOP);
|
||||
|
||||
if (e_hflag_ok) {
|
||||
BM_elem_flag_enable(f_edges[1], e_hflag[0]);
|
||||
BM_elem_flag_disable(f_edges[1], e_hflag[1]);
|
||||
}
|
||||
}
|
||||
BMO_elem_flag_set(bm, f_edges[1], side_tag, true);
|
||||
|
||||
f_edges[3] = BM_edge_exists(f_verts[3], f_verts[0]);
|
||||
|
||||
if (f_edges[3] == NULL) {
|
||||
char e_hflag[2];
|
||||
bool e_hflag_ok = bm_extrude_region_edge_flag(f_verts[3], e_hflag);
|
||||
f_edges[3] = BM_edge_create(bm, f_verts[3], f_verts[0], NULL, BM_CREATE_NOP);
|
||||
|
||||
if (e_hflag_ok) {
|
||||
BM_elem_flag_enable(f_edges[3], e_hflag[0]);
|
||||
BM_elem_flag_disable(f_edges[3], e_hflag[1]);
|
||||
}
|
||||
}
|
||||
BMO_elem_flag_set(bm, f_edges[3], side_tag, true);
|
||||
|
||||
f = BM_face_create(bm, f_verts, f_edges, 4, NULL, BM_CREATE_NOP);
|
||||
|
||||
#else
|
||||
f = BM_face_create_verts(bm, f_verts, 4, NULL, BM_CREATE_NOP, true);
|
||||
#endif
|
||||
|
||||
bm_extrude_copy_face_loop_attributes(bm, f);
|
||||
BMO_elem_flag_set(bm, (BMElem *)f, side_tag, true);
|
||||
|
||||
if (join_face) {
|
||||
BMVert *v1 = e->v1;
|
||||
BMVert *v2 = e->v2;
|
||||
|
@ -605,7 +612,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
|||
}
|
||||
}
|
||||
|
||||
BM_edge_create(bm, v, v2, NULL, BM_CREATE_NO_DOUBLE);
|
||||
BMO_elem_flag_set(bm, BM_edge_create(bm, v, v2, NULL, BM_CREATE_NO_DOUBLE), side_tag, true);
|
||||
}
|
||||
|
||||
if (dissolve_verts) {
|
||||
|
@ -626,6 +633,9 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
|||
MEM_freeN(dissolve_verts);
|
||||
}
|
||||
|
||||
BMO_slot_buffer_from_enabled_flag(
|
||||
bm, op, op->slots_out, "side_geom.out", BM_FACE | BM_EDGE, side_tag);
|
||||
|
||||
/* cleanup */
|
||||
if (delorig) {
|
||||
BMO_op_finish(bm, &delop);
|
||||
|
|
|
@ -8460,7 +8460,7 @@ typedef struct DynTopoAutomaskState {
|
|||
bool free_automasking;
|
||||
} DynTopoAutomaskState;
|
||||
|
||||
static float sculpt_topology_automasking_cb(SculptVertRef vertex, void *vdata)
|
||||
ATTR_NO_OPT static float sculpt_topology_automasking_cb(SculptVertRef vertex, void *vdata)
|
||||
{
|
||||
DynTopoAutomaskState *state = (DynTopoAutomaskState *)vdata;
|
||||
float mask = SCULPT_automasking_factor_get(state->cache, state->ss, vertex);
|
||||
|
@ -8469,7 +8469,7 @@ static float sculpt_topology_automasking_cb(SculptVertRef vertex, void *vdata)
|
|||
return mask * mask2;
|
||||
}
|
||||
|
||||
static float sculpt_topology_automasking_mask_cb(SculptVertRef vertex, void *vdata)
|
||||
ATTR_NO_OPT static float sculpt_topology_automasking_mask_cb(SculptVertRef vertex, void *vdata)
|
||||
{
|
||||
DynTopoAutomaskState *state = (DynTopoAutomaskState *)vdata;
|
||||
return 1.0f - SCULPT_vertex_mask_get(state->ss, vertex);
|
||||
|
@ -8614,7 +8614,8 @@ static void sculpt_topology_update(Sculpt *sd,
|
|||
symidx,
|
||||
DYNTOPO_HAS_DYNAMIC_SPLIT(brush->sculpt_tool),
|
||||
mask_cb,
|
||||
mask_cb_data);
|
||||
mask_cb_data,
|
||||
SCULPT_get_int(ss, dyntopo_disable_smooth, sd, brush));
|
||||
|
||||
SCULPT_dyntopo_automasking_end(mask_cb_data);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "BKE_brush_engine.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
|
@ -72,8 +73,10 @@ static bool sculpt_and_constant_or_manual_detail_poll(bContext *C)
|
|||
Object *ob = CTX_data_active_object(C);
|
||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||
|
||||
return SCULPT_mode_poll(C) && ob->sculpt->bm &&
|
||||
(sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL));
|
||||
/*checking for constant/manual mode isn't necassary since we do this on the python side
|
||||
in the ui scripts*/
|
||||
return SCULPT_mode_poll(C) && ob->sculpt->bm; /*&&
|
||||
(sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL));*/
|
||||
}
|
||||
|
||||
static bool sculpt_and_dynamic_topology_poll(bContext *C)
|
||||
|
@ -87,6 +90,8 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
{
|
||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
SculptSession *ss = ob->sculpt;
|
||||
float size;
|
||||
float bb_min[3], bb_max[3], center[3], dim[3];
|
||||
|
@ -109,9 +114,17 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
sub_v3_v3v3(dim, bb_max, bb_min);
|
||||
size = max_fff(dim[0], dim[1], dim[2]);
|
||||
|
||||
float constant_detail = BRUSHSET_GET_FINAL_FLOAT(
|
||||
brush ? brush->channels : NULL, sd->channels, dyntopo_constant_detail, NULL);
|
||||
float detail_range = BRUSHSET_GET_FINAL_FLOAT(
|
||||
brush ? brush->channels : NULL, sd->channels, dyntopo_detail_range, NULL);
|
||||
|
||||
/* Update topology size. */
|
||||
float object_space_constant_detail = 1.0f / (sd->constant_detail * mat4_to_scale(ob->obmat));
|
||||
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail, sd->detail_range);
|
||||
float object_space_constant_detail = 1.0f / (constant_detail * mat4_to_scale(ob->obmat));
|
||||
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail, detail_range);
|
||||
|
||||
bool enable_surface_relax = BRUSHSET_GET_FINAL_INT(
|
||||
brush ? brush->channels : NULL, sd->channels, dyntopo_disable_smooth, NULL);
|
||||
|
||||
SCULPT_undo_push_begin(ob, "Dynamic topology flood fill");
|
||||
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS);
|
||||
|
@ -140,7 +153,8 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
false,
|
||||
mask_cb,
|
||||
mask_cb_data,
|
||||
max_dyntopo_steps_coll);
|
||||
max_dyntopo_steps_coll,
|
||||
enable_surface_relax);
|
||||
|
||||
for (int j = 0; j < totnodes; j++) {
|
||||
BKE_pbvh_node_mark_topology_update(nodes[j]);
|
||||
|
@ -157,7 +171,8 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
false,
|
||||
mask_cb,
|
||||
mask_cb_data,
|
||||
max_dyntopo_steps_subd);
|
||||
max_dyntopo_steps_subd,
|
||||
enable_surface_relax);
|
||||
for (int j = 0; j < totnodes; j++) {
|
||||
BKE_pbvh_node_mark_topology_update(nodes[j]);
|
||||
}
|
||||
|
@ -184,7 +199,8 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
false,
|
||||
mask_cb,
|
||||
mask_cb_data,
|
||||
max_dyntopo_steps_coll);
|
||||
max_dyntopo_steps_coll,
|
||||
enable_surface_relax);
|
||||
}
|
||||
|
||||
SCULPT_dyntopo_automasking_end(mask_cb_data);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -622,6 +622,10 @@ static void update_unode_bmesh_memsize(SculptUndoNode *unode)
|
|||
// update memory size
|
||||
UndoSculpt *usculpt = sculpt_undo_get_nodes();
|
||||
|
||||
if (!usculpt) {
|
||||
return;
|
||||
}
|
||||
|
||||
// subtract old size
|
||||
if (usculpt->undo_size >= unode->undo_size) {
|
||||
usculpt->undo_size -= unode->undo_size;
|
||||
|
@ -1932,6 +1936,10 @@ bool SCULPT_ensure_dyntopo_node_undo(Object *ob,
|
|||
return SCULPT_ensure_dyntopo_node_undo(ob, node, type, extraType);
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
int n = BKE_pbvh_get_node_id(ss->pbvh, node);
|
||||
|
||||
if (unode->nodemap_size <= n) {
|
||||
|
|
|
@ -2572,6 +2572,7 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
RNA_def_property_enum_items(prop, brush_curve_preset_items);
|
||||
RNA_def_property_ui_text(prop, "Curve Preset", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
|
||||
prop = RNA_def_property(srna, "deform_target", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, brush_deformation_target_items);
|
||||
|
@ -2678,6 +2679,7 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
RNA_def_property_enum_items(prop, falloff_shape_unit_items);
|
||||
RNA_def_property_ui_text(prop, "Falloff Shape", "Use projected or spherical falloff");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
|
||||
/* number values */
|
||||
prop = RNA_def_property(srna, "size", PROP_INT, PROP_PIXEL);
|
||||
|
@ -3695,6 +3697,7 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
RNA_def_property_ui_text(prop, "Curve", "Editable falloff curve");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
|
||||
prop = RNA_def_property(srna, "pressure_size_curve", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
|
|
Loading…
Reference in New Issue