Collection IO: Enable file exporters to be specified on Collections #116646

Merged
Jesse Yurkovich merged 56 commits from deadpin/blender:collection-io into main 2024-04-08 22:10:52 +02:00
102 changed files with 880 additions and 836 deletions
Showing only changes of commit f8dadcd573 - Show all commits

View File

@ -16,10 +16,11 @@ This ``directory`` and ``files`` properties now will be used by the
"""
import bpy
from bpy_extras.io_utils import ImportHelper
from mathutils import Vector
class ShaderScriptImport(bpy.types.Operator):
class ShaderScriptImport(bpy.types.Operator, ImportHelper):
"""Test importer that creates scripts nodes from .txt files"""
bl_idname = "shader.script_import"
bl_label = "Import a text file as a script node"
@ -28,8 +29,11 @@ class ShaderScriptImport(bpy.types.Operator):
This Operator can import multiple .txt files, we need following directory and files
properties that the file handler will use to set files path data
"""
directory: bpy.props.StringProperty(subtype='FILE_PATH', options={'SKIP_SAVE'})
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={'SKIP_SAVE'})
directory: bpy.props.StringProperty(subtype='FILE_PATH', options={'SKIP_SAVE', 'HIDDEN'})
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={'SKIP_SAVE', 'HIDDEN'})
"""Allow the user to select if the node's label is set or not"""
set_label: bpy.props.BoolProperty(name="Set Label", default=False)
@classmethod
def poll(cls, context):
@ -57,23 +61,26 @@ class ShaderScriptImport(bpy.types.Operator):
filepath = os.path.join(self.directory, file.name)
text_node.filepath = filepath
text_node.location = Vector((x, y))
# Set the node's title to the file name
if self.set_label:
text_node.label = file.name
x += 20.0
y -= 20.0
return {'FINISHED'}
"""
By default the file handler invokes the operator with the directory and files properties set.
In this example if this properties are set the operator is executed, if not the
file select window is invoked.
This depends on setting ``options={'SKIP_SAVE'}`` to the properties options to avoid
to reuse filepath data between operator calls.
Use ImportHelper's invoke_popup() to handle the invocation so that this operator's properties
are shown in a popup. This allows the user to configure additional settings on the operator like
the `set_label` property. Consider having a draw() method on the operator in order to layout the
properties in the UI appropriately.
If filepath information is not provided the file select window will be invoked instead.
"""
def invoke(self, context, event):
if self.directory:
return self.execute(context)
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
return self.invoke_popup(context)
class SHADER_FH_script_import(bpy.types.FileHandler):

View File

@ -210,7 +210,7 @@ rbCollisionShape *RB_shape_new_cylinder(float radius, float height);
/* Setup (Convex Hull) ------------ */
rbCollisionShape *RB_shape_new_convex_hull(
float *verts, int stride, int count, float margin, bool *can_embed);
const float *verts, int stride, int count, float margin, bool *can_embed);
/* Setup (Triangle Mesh) ---------- */
@ -244,7 +244,7 @@ float RB_shape_get_margin(rbCollisionShape *shape);
void RB_shape_set_margin(rbCollisionShape *shape, float value);
void RB_shape_trimesh_update(rbCollisionShape *shape,
float *vertices,
const float *vertices,
int num_verts,
int vert_stride,
const float min[3],

View File

@ -712,7 +712,7 @@ rbCollisionShape *RB_shape_new_cylinder(float radius, float height)
/* Setup (Convex Hull) ------------ */
rbCollisionShape *RB_shape_new_convex_hull(
float *verts, int stride, int count, float margin, bool *can_embed)
const float *verts, int stride, int count, float margin, bool *can_embed)
{
btConvexHullComputer hull_computer = btConvexHullComputer();
@ -800,7 +800,7 @@ rbCollisionShape *RB_shape_new_trimesh(rbMeshData *mesh)
}
void RB_shape_trimesh_update(rbCollisionShape *shape,
float *vertices,
const float *vertices,
int num_verts,
int vert_stride,
const float min[3],

@ -1 +1 @@
Subproject commit 1d44611dd36032c1889c66d673801ef7d699f592
Subproject commit 0b910c0a718a1d54d07ecf95c63617576ee9a847

Binary file not shown.

View File

@ -23,7 +23,10 @@ from bpy.props import (
EnumProperty,
StringProperty,
)
from bpy.app.translations import pgettext_data as data_
from bpy.app.translations import (
pgettext_iface as iface_,
pgettext_data as data_,
)
def _check_axis_conversion(op):
@ -96,12 +99,29 @@ class ImportHelper:
description="Filepath used for importing the file",
maxlen=1024,
subtype='FILE_PATH',
options={'SKIP_PRESET', 'HIDDEN'}
)
def invoke(self, context, _event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
def invoke_popup(self, context, confirm_text=""):
if self.properties.is_property_set("filepath"):
title = self.filepath
if len(self.files) > 1:
title = iface_("Import {} files").format(len(self.files))
if not confirm_text:
confirm_text = self.bl_label
confirm_text = iface_(confirm_text)
return context.window_manager.invoke_props_dialog(
self, confirm_text=confirm_text, title=title, translate=False)
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
def check(self, _context):
return _check_axis_conversion(self)
@ -394,6 +414,19 @@ def unpack_face_list(list_of_tuples):
return flat_ls
def poll_file_object_drop(context):
"""
A default implementation for FileHandler poll_drop methods. Allows for both the 3D Viewport and
the Outliner (in ViewLayer display mode) to be targets for file drag and drop.
"""
area = context.area
if not area:
return False
is_v3d = area.type == 'VIEW_3D'
is_outliner_view_layer = area.type == 'OUTLINER' and area.spaces.active.display_mode == 'VIEW_LAYER'
return is_v3d or is_outliner_view_layer
path_reference_mode = EnumProperty(
name="Path Mode",
description="Method used to reference paths",

View File

@ -2330,8 +2330,7 @@ def km_file_browser(params):
("file.next", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True}, None),
("wm.context_toggle", {"type": 'H', "value": 'PRESS'},
{"properties": [("data_path", 'space_data.params.show_hidden')]}),
("file.directory_new", {"type": 'I', "value": 'PRESS'},
{"properties": [("confirm", False)]}),
("file.directory_new", {"type": 'I', "value": 'PRESS'}, None),
("file.rename", {"type": 'F2', "value": 'PRESS'}, None),
("file.delete", {"type": 'X', "value": 'PRESS'}, None),
("file.delete", {"type": 'DEL', "value": 'PRESS'}, None),
@ -7907,6 +7906,21 @@ def km_3d_view_tool_sculpt_lasso_hide(params):
)
def km_3d_view_tool_sculpt_line_hide(params):
return (
"3D View Tool: Sculpt, Line Hide",
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
("paint.hide_show_line_gesture", params.tool_maybe_tweak_event,
{"properties": [("action", 'HIDE')]}),
("paint.hide_show_line_gesture", {**params.tool_maybe_tweak_event, "ctrl": True},
{"properties": [("action", 'SHOW')]}),
("paint.hide_show_all", {"type": params.select_mouse, "value": params.select_mouse_value},
{"properties": [("action", 'SHOW')]}),
]},
)
def km_3d_view_tool_sculpt_box_mask(params):
return (
"3D View Tool: Sculpt, Box Mask",
@ -8753,6 +8767,7 @@ def generate_keymaps(params=None):
km_3d_view_tool_edit_curves_draw(params),
km_3d_view_tool_sculpt_box_hide(params),
km_3d_view_tool_sculpt_lasso_hide(params),
km_3d_view_tool_sculpt_line_hide(params),
km_3d_view_tool_sculpt_box_mask(params),
km_3d_view_tool_sculpt_lasso_mask(params),
km_3d_view_tool_sculpt_box_face_set(params),

View File

@ -1240,8 +1240,7 @@ def km_file_browser(params):
("file.next", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True}, None),
("wm.context_toggle", {"type": 'H', "value": 'PRESS'},
{"properties": [("data_path", 'space_data.params.show_hidden')]}),
("file.directory_new", {"type": 'I', "value": 'PRESS'},
{"properties": [("confirm", False)]}),
("file.directory_new", {"type": 'I', "value": 'PRESS'}, None),
("file.rename", {"type": 'F2', "value": 'PRESS'}, None),
("file.delete", {"type": 'DEL', "value": 'PRESS'}, None),
("file.smoothscroll", {"type": 'TIMER1', "value": 'ANY', "any": True}, None),

View File

@ -530,11 +530,12 @@ class ARMATURE_OT_copy_bone_color_to_selected(Operator):
def _armature_from_context(context):
pin_armature = getattr(context, 'armature', None)
pin_armature = getattr(context, "armature", None)
if pin_armature:
return pin_armature
if context.object and context.object.type == 'ARMATURE':
return context.object.data
ob = context.object
if ob and ob.type == 'ARMATURE':
return ob.data
return None

View File

@ -270,8 +270,8 @@ class WM_OT_blend_strings_utf8_validate(Operator):
continue
if prop.type == 'STRING':
val_bytes = item.path_resolve(prop.identifier, False).as_bytes()
val_utf8 = val_bytes.decode('utf-8', 'replace')
val_bytes_valid = val_utf8.encode('utf-8')
val_utf8 = val_bytes.decode("utf-8", "replace")
val_bytes_valid = val_utf8.encode("utf-8")
if val_bytes_valid != val_bytes:
print("found bad utf8 encoded string %r, fixing to %r (%r)..."
"" % (val_bytes, val_bytes_valid, val_utf8))

View File

@ -48,7 +48,8 @@ def geometry_node_group_empty_tool_new(context):
group.use_fake_user = True
group.is_tool = True
ob_type = context.object.type if context.object else 'MESH'
ob = context.object
ob_type = ob.type if ob else 'MESH'
if ob_type == 'CURVES':
group.is_type_curve = True
elif ob_type == 'POINTCLOUD':
@ -56,7 +57,7 @@ def geometry_node_group_empty_tool_new(context):
else:
group.is_type_mesh = True
mode = context.object.mode if context.object else 'OBJECT'
mode = ob.mode if ob else 'OBJECT'
if mode in {'SCULPT', 'SCULPT_CURVES'}:
group.is_mode_sculpt = True
elif mode == 'EDIT':

View File

@ -147,7 +147,7 @@ class AddPresetBase:
file_preset.write("%s = %r\n" % (rna_path_step, value))
file_preset = open(filepath, 'w', encoding="utf-8")
file_preset = open(filepath, "w", encoding="utf-8")
file_preset.write("import bpy\n")
if hasattr(self, "preset_defines"):

View File

@ -674,7 +674,7 @@ class PREFERENCES_OT_addon_install(Operator):
# check to see if the file is in compressed format (.zip)
if zipfile.is_zipfile(pyfile):
try:
file_to_extract = zipfile.ZipFile(pyfile, 'r')
file_to_extract = zipfile.ZipFile(pyfile, "r")
except BaseException:
traceback.print_exc()
return {'CANCELLED'}
@ -926,7 +926,7 @@ class PREFERENCES_OT_app_template_install(Operator):
# check to see if the file is in compressed format (.zip)
if zipfile.is_zipfile(filepath):
try:
file_to_extract = zipfile.ZipFile(filepath, 'r')
file_to_extract = zipfile.ZipFile(filepath, "r")
except BaseException:
traceback.print_exc()
return {'CANCELLED'}

View File

@ -31,10 +31,11 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
def execute(self, context):
from bpy_extras.object_utils import object_report_if_active_shape_key_is_locked
if object_report_if_active_shape_key_is_locked(context.object, self):
ob = context.object
if object_report_if_active_shape_key_is_locked(ob, self):
return {'CANCELLED'}
mesh = context.object.data
mesh = ob.data
select_mode = context.tool_settings.mesh_select_mode
totface = mesh.total_face_sel
@ -99,10 +100,11 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
def extrude_region(operator, context, use_vert_normals, dissolve_and_intersect):
from bpy_extras.object_utils import object_report_if_active_shape_key_is_locked
if object_report_if_active_shape_key_is_locked(context.object, operator):
ob = context.object
if object_report_if_active_shape_key_is_locked(ob, operator):
return {'CANCELLED'}
mesh = context.object.data
mesh = ob.data
totface = mesh.total_face_sel
totedge = mesh.total_edge_sel

View File

@ -3367,10 +3367,13 @@ class WM_MT_splash_about(Menu):
col.scale_y = 0.8
col.label(text=iface_("Version: %s") % bpy.app.version_string, translate=False)
col.separator(factor=2.5)
col.label(text=iface_("Date: %s %s") % (bpy.app.build_commit_date.decode('utf-8', 'replace'),
bpy.app.build_commit_time.decode('utf-8', 'replace')), translate=False)
col.label(text=iface_("Hash: %s") % bpy.app.build_hash.decode('ascii'), translate=False)
col.label(text=iface_("Branch: %s") % bpy.app.build_branch.decode('utf-8', 'replace'), translate=False)
col.label(text=iface_("Date: %s %s") % (
bpy.app.build_commit_date.decode("utf-8", "replace"),
bpy.app.build_commit_time.decode("utf-8", "replace")),
translate=False
)
col.label(text=iface_("Hash: %s") % bpy.app.build_hash.decode("ascii"), translate=False)
col.label(text=iface_("Branch: %s") % bpy.app.build_branch.decode("utf-8", "replace"), translate=False)
# This isn't useful information on MS-Windows or Apple systems as dynamically switching
# between windowing systems is only supported between X11/WAYLAND.

View File

@ -82,7 +82,8 @@ class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu):
def draw(self, context):
layout = self.layout
grease_pencil = context.object.data
ob = context.object
grease_pencil = ob.data
space = context.space_data
if space.type == 'PROPERTIES':

View File

@ -417,20 +417,23 @@ class AnnotationDataPanel:
bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
if context.space_data.type not in {
space = context.space_data
if space.type not in {
'VIEW_3D',
'TOPBAR',
'SEQUENCE_EDITOR',
'IMAGE_EDITOR',
'NODE_EDITOR',
'PROPERTIES'}:
self.layout.prop(context.space_data, "show_annotation", text="")
'PROPERTIES',
}:
self.layout.prop(space, "show_annotation", text="")
def draw(self, context):
layout = self.layout
layout.use_property_decorate = False
space = context.space_data
is_clip_editor = context.space_data.type == 'CLIP_EDITOR'
is_clip_editor = space.type == 'CLIP_EDITOR'
# Grease Pencil owner.
gpd_owner = context.annotation_data_owner
@ -441,7 +444,7 @@ class AnnotationDataPanel:
col = layout.column()
col.label(text="Data Source:")
row = col.row()
row.prop(context.space_data, "annotation_source", expand=True)
row.prop(space, "annotation_source", expand=True)
# Only allow adding annotation ID if its owner exist
if context.annotation_data_owner is None:

View File

@ -258,9 +258,9 @@ class ToolSelectPanelHelper:
# tool flattening
#
# usually 'tools' is already expanded into `ToolDef`
# usually "tools" is already expanded into `ToolDef`
# but when registering a tool, this can still be a function
# (_tools_flatten is usually called with cls.tools_from_context(context)
# (`_tools_flatten` is usually called with `cls.tools_from_context(context)`
# [that already yields from the function])
# so if item is still a function (e.g._defs_XXX.generate_from_brushes)
# seems like we cannot expand here (have no context yet)

View File

@ -1416,6 +1416,21 @@ class _defs_sculpt:
draw_settings=draw_settings,
)
@ToolDef.from_fn
def hide_line():
def draw_settings(_context, layout, tool):
props = tool.operator_properties("paint.hide_show_line_gesture")
layout.prop(props, "use_limit_to_segment", expand=False)
return dict(
idname="builtin.line_hide",
label="Line Hide",
icon="ops.sculpt.line_hide",
widget=None,
keymap=(),
draw_settings=draw_settings,
)
@ToolDef.from_fn
def mask_border():
def draw_settings(_context, layout, tool):
@ -3108,7 +3123,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
),
(
_defs_sculpt.hide_border,
_defs_sculpt.hide_lasso
_defs_sculpt.hide_lasso,
_defs_sculpt.hide_line,
),
(
_defs_sculpt.face_set_box,

View File

@ -409,27 +409,27 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
datablock_types = (
("use_duplicate_action", "Action", 'ACTION', ''),
("use_duplicate_armature", "Armature", 'OUTLINER_DATA_ARMATURE', ''),
("use_duplicate_camera", "Camera", 'OUTLINER_DATA_CAMERA', ''),
("use_duplicate_curve", "Curve", 'OUTLINER_DATA_CURVE', ''),
("use_duplicate_curves", "Curves", 'OUTLINER_DATA_CURVES', ''),
("use_duplicate_grease_pencil", "Grease Pencil", 'OUTLINER_OB_GREASEPENCIL', ''),
("use_duplicate_lattice", "Lattice", 'OUTLINER_DATA_LATTICE', ''),
("use_duplicate_action", "Action", 'ACTION', ""),
("use_duplicate_armature", "Armature", 'OUTLINER_DATA_ARMATURE', ""),
("use_duplicate_camera", "Camera", 'OUTLINER_DATA_CAMERA', ""),
("use_duplicate_curve", "Curve", 'OUTLINER_DATA_CURVE', ""),
("use_duplicate_curves", "Curves", 'OUTLINER_DATA_CURVES', ""),
("use_duplicate_grease_pencil", "Grease Pencil", 'OUTLINER_OB_GREASEPENCIL', ""),
("use_duplicate_lattice", "Lattice", 'OUTLINER_DATA_LATTICE', ""),
(None, None, None, None),
("use_duplicate_light", "Light", 'OUTLINER_DATA_LIGHT', ''),
("use_duplicate_lightprobe", "Light Probe", 'OUTLINER_DATA_LIGHTPROBE', ''),
("use_duplicate_material", "Material", 'MATERIAL_DATA', ''),
("use_duplicate_mesh", "Mesh", 'OUTLINER_DATA_MESH', ''),
("use_duplicate_metaball", "Metaball", 'OUTLINER_DATA_META', ''),
("use_duplicate_node_tree", "Node Tree", 'NODETREE', ''),
("use_duplicate_particle", "Particle", 'PARTICLES', ''),
("use_duplicate_light", "Light", 'OUTLINER_DATA_LIGHT', ""),
("use_duplicate_lightprobe", "Light Probe", 'OUTLINER_DATA_LIGHTPROBE', ""),
("use_duplicate_material", "Material", 'MATERIAL_DATA', ""),
("use_duplicate_mesh", "Mesh", 'OUTLINER_DATA_MESH', ""),
("use_duplicate_metaball", "Metaball", 'OUTLINER_DATA_META', ""),
("use_duplicate_node_tree", "Node Tree", 'NODETREE', ""),
("use_duplicate_particle", "Particle", 'PARTICLES', ""),
(None, None, None, None),
("use_duplicate_pointcloud", "Point Cloud", 'OUTLINER_DATA_POINTCLOUD', ''),
("use_duplicate_speaker", "Speaker", 'OUTLINER_DATA_SPEAKER', ''),
("use_duplicate_surface", "Surface", 'OUTLINER_DATA_SURFACE', ''),
("use_duplicate_text", "Text", 'OUTLINER_DATA_FONT', ''),
("use_duplicate_volume", "Volume", 'OUTLINER_DATA_VOLUME', 'i18n_contexts.id_id'),
("use_duplicate_pointcloud", "Point Cloud", 'OUTLINER_DATA_POINTCLOUD', ""),
("use_duplicate_speaker", "Speaker", 'OUTLINER_DATA_SPEAKER', ""),
("use_duplicate_surface", "Surface", 'OUTLINER_DATA_SURFACE', ""),
("use_duplicate_text", "Text", 'OUTLINER_DATA_FONT', ""),
("use_duplicate_volume", "Volume", 'OUTLINER_DATA_VOLUME', "i18n_contexts.id_id"),
)
col = flow.column()
@ -2726,7 +2726,7 @@ class USERPREF_PT_experimental_debugging(ExperimentalPanel, Panel):
# Class Registration
# Order of registration defines order in UI,
# so dynamically generated classes are 'injected' in the intended order.
# so dynamically generated classes are "injected" in the intended order.
classes = (
USERPREF_PT_theme_user_interface,
*ThemeGenericClassGenerator.generate_panel_classes_for_wcols(),

View File

@ -139,17 +139,20 @@ class VIEW3D_HT_tool_header(Header):
return row, sub
if mode_string == 'EDIT_ARMATURE':
ob = context.object
_row, sub = row_for_mirror()
sub.prop(context.object.data, "use_mirror_x", text="X", toggle=True)
sub.prop(ob.data, "use_mirror_x", text="X", toggle=True)
elif mode_string == 'POSE':
ob = context.object
_row, sub = row_for_mirror()
sub.prop(context.object.pose, "use_mirror_x", text="X", toggle=True)
sub.prop(ob.pose, "use_mirror_x", text="X", toggle=True)
elif mode_string in {'EDIT_MESH', 'PAINT_WEIGHT', 'SCULPT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
# Mesh Modes, Use Mesh Symmetry
ob = context.object
row, sub = row_for_mirror()
sub.prop(context.object, "use_mesh_mirror_x", text="X", toggle=True)
sub.prop(context.object, "use_mesh_mirror_y", text="Y", toggle=True)
sub.prop(context.object, "use_mesh_mirror_z", text="Z", toggle=True)
sub.prop(ob, "use_mesh_mirror_x", text="X", toggle=True)
sub.prop(ob, "use_mesh_mirror_y", text="Y", toggle=True)
sub.prop(ob, "use_mesh_mirror_z", text="Z", toggle=True)
if mode_string == 'EDIT_MESH':
tool_settings = context.tool_settings
layout.prop(tool_settings, "use_mesh_automerge", text="")
@ -160,12 +163,13 @@ class VIEW3D_HT_tool_header(Header):
elif mode_string == 'PAINT_VERTEX':
row.popover(panel="VIEW3D_PT_tools_vertexpaint_symmetry_for_topbar", text="")
elif mode_string == 'SCULPT_CURVES':
ob = context.object
_row, sub = row_for_mirror()
sub.prop(context.object.data, "use_mirror_x", text="X", toggle=True)
sub.prop(context.object.data, "use_mirror_y", text="Y", toggle=True)
sub.prop(context.object.data, "use_mirror_z", text="Z", toggle=True)
sub.prop(ob.data, "use_mirror_x", text="X", toggle=True)
sub.prop(ob.data, "use_mirror_y", text="Y", toggle=True)
sub.prop(ob.data, "use_mirror_z", text="Z", toggle=True)
layout.prop(context.object.data, "use_sculpt_collision", icon='MOD_PHYSICS', icon_only=True, toggle=True)
layout.prop(ob.data, "use_sculpt_collision", icon='MOD_PHYSICS', icon_only=True, toggle=True)
# Expand panels from the side-bar as popovers.
popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"}
@ -373,19 +377,20 @@ class _draw_tool_settings_context_mode:
if brush is None:
return False
ob = context.object
gp_settings = brush.gpencil_settings
row = layout.row(align=True)
settings = tool_settings.gpencil_paint
row.template_ID_preview(settings, "brush", rows=3, cols=8, hide_buttons=True)
if context.object and brush.gpencil_tool in {'FILL', 'DRAW'}:
if ob and brush.gpencil_tool in {'FILL', 'DRAW'}:
from bl_ui.properties_paint_common import (
brush_basic__draw_color_selector,
)
brush_basic__draw_color_selector(context, layout, brush, gp_settings, None)
if context.object and brush.gpencil_tool == 'TINT':
if ob and brush.gpencil_tool == 'TINT':
row.separator(factor=0.4)
row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_gpencil_vertexcolor")
@ -2717,6 +2722,8 @@ class VIEW3D_MT_object(Menu):
def draw(self, context):
layout = self.layout
ob = context.object
layout.menu("VIEW3D_MT_transform_object")
layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type")
layout.menu("VIEW3D_MT_mirror")
@ -2752,7 +2759,7 @@ class VIEW3D_MT_object(Menu):
layout.separator()
layout.operator("object.shade_smooth")
if context.object and context.object.type == 'MESH':
if ob and ob.type == 'MESH':
layout.operator("object.shade_smooth_by_angle")
layout.operator("object.shade_flat")
@ -3585,6 +3592,12 @@ class VIEW3D_MT_sculpt(Menu):
props = layout.operator("paint.hide_show_lasso_gesture", text="Lasso Show")
props.action = 'SHOW'
props = layout.operator("paint.hide_show_line_gesture", text="Line Hide")
props.action = 'HIDE'
props = layout.operator("paint.hide_show_line_gesture", text="Line Show")
props.action = 'SHOW'
layout.separator()
props = layout.operator("sculpt.face_set_change_visibility", text="Toggle Visibility")
@ -4095,9 +4108,10 @@ class VIEW3D_MT_bone_collections(Menu):
@classmethod
def poll(cls, context):
if not context.object or context.object.type != 'ARMATURE':
ob = context.object
if not (ob and ob.type == 'ARMATURE'):
return False
if context.object.data.library:
if ob.data.library:
return False
return True
@ -4551,7 +4565,8 @@ class VIEW3D_MT_edit_mesh_extrude(Menu):
tool_settings = context.tool_settings
select_mode = tool_settings.mesh_select_mode
mesh = context.object.data
ob = context.object
mesh = ob.data
if mesh.total_face_sel:
layout.operator("view3d.edit_mesh_extrude_move_normal", text="Extrude Faces")
@ -7745,13 +7760,16 @@ class VIEW3D_PT_overlay_gpencil_options(Panel):
@classmethod
def poll(cls, context):
return context.object and context.object.type == 'GPENCIL'
ob = context.object
return ob and ob.type == 'GPENCIL'
def draw(self, context):
layout = self.layout
view = context.space_data
overlay = view.overlay
ob = context.object
layout.label(text={
'PAINT_GPENCIL': iface_("Draw Grease Pencil"),
'EDIT_GPENCIL': iface_("Edit Grease Pencil"),
@ -7784,15 +7802,15 @@ class VIEW3D_PT_overlay_gpencil_options(Panel):
sub.prop(overlay, "gpencil_fade_objects", text="Fade Inactive Objects", slider=True)
sub.prop(overlay, "use_gpencil_fade_gp_objects", text="", icon='OUTLINER_OB_GREASEPENCIL')
if context.object.mode in {'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL'}:
if ob.mode in {'EDIT_GPENCIL', 'SCULPT_GPENCIL', 'WEIGHT_GPENCIL', 'VERTEX_GPENCIL'}:
split = layout.split()
col = split.column()
col.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines")
col = split.column()
col.prop(overlay, "use_gpencil_multiedit_line_only", text="Only in Multiframe")
if context.object.mode == 'EDIT_GPENCIL':
gpd = context.object.data
if ob.mode == 'EDIT_GPENCIL':
gpd = ob.data
split = layout.split()
col = split.column()
col.prop(overlay, "use_gpencil_show_directions")
@ -7805,10 +7823,10 @@ class VIEW3D_PT_overlay_gpencil_options(Panel):
# Handles for Curve Edit
layout.prop(overlay, "display_handle", text="Handles")
if context.object.mode == 'SCULPT_GPENCIL':
if ob.mode == 'SCULPT_GPENCIL':
layout.prop(overlay, "vertex_opacity", text="Vertex Opacity", slider=True)
if context.object.mode in {'PAINT_GPENCIL', 'VERTEX_GPENCIL'}:
if ob.mode in {'PAINT_GPENCIL', 'VERTEX_GPENCIL'}:
layout.label(text="Vertex Paint")
row = layout.row()
shading = VIEW3D_PT_shading.get_shading(context)
@ -7824,20 +7842,23 @@ class VIEW3D_PT_overlay_grease_pencil_options(Panel):
@classmethod
def poll(cls, context):
return context.object and context.object.type == 'GREASEPENCIL'
ob = context.object
return ob and ob.type == 'GREASEPENCIL'
def draw(self, context):
layout = self.layout
view = context.space_data
overlay = view.overlay
ob = context.object
layout.label(text={
'PAINT_GREASE_PENCIL': iface_("Draw Grease Pencil"),
'EDIT_GREASE_PENCIL': iface_("Edit Grease Pencil"),
'OBJECT': iface_("Grease Pencil"),
}[context.mode], translate=False)
if context.object.mode in {'EDIT'}:
if ob.mode in {'EDIT'}:
split = layout.split()
col = split.column()
col.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines")
@ -8723,7 +8744,7 @@ class TOPBAR_PT_gpencil_materials(GreasePencilMaterialsPanel, Panel):
@classmethod
def poll(cls, context):
ob = context.object
return ob and (ob.type == 'GPENCIL' or ob.type == 'GREASEPENCIL')
return ob and ob.type in {'GPENCIL', 'GREASEPENCIL'}
class TOPBAR_PT_gpencil_vertexcolor(GreasePencilVertexcolorPanel, Panel):

View File

@ -615,7 +615,7 @@ class VIEW3D_PT_slots_paint_canvas(SelectPaintSlotHelper, View3DPanel, Panel):
def draw_header(self, context):
paint = context.tool_settings.paint_mode
ob = context.object
me = context.object.data
me = ob.data
mat = ob.active_material
label = iface_("Canvas")
@ -646,7 +646,8 @@ class VIEW3D_PT_slots_color_attributes(Panel):
)
def draw(self, context):
mesh = context.object.data
ob = context.object
mesh = ob.data
layout = self.layout
row = layout.row()
@ -1124,7 +1125,9 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
sculpt = context.tool_settings.sculpt
row = layout.row(align=True, heading="Mirror")
mesh = context.object.data
ob = context.object
mesh = ob.data
row.prop(mesh, "use_mirror_x", text="X", toggle=True)
row.prop(mesh, "use_mirror_y", text="Y", toggle=True)
row.prop(mesh, "use_mirror_z", text="Z", toggle=True)
@ -1167,14 +1170,16 @@ class VIEW3D_PT_curves_sculpt_symmetry(Panel, View3DPaintPanel):
@classmethod
def poll(cls, context):
return context.object and context.object.type == 'CURVES'
ob = context.object
return ob and ob.type == 'CURVES'
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
curves = context.object.data
ob = context.object
curves = ob.data
row = layout.row(align=True, heading="Mirror")
row.prop(curves, "use_mirror_x", text="X", toggle=True)
@ -1211,11 +1216,13 @@ class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel):
tool_settings = context.tool_settings
wpaint = tool_settings.weight_paint
mesh = context.object.data
ob = context.object
mesh = ob.data
layout.prop(mesh, "use_mirror_vertex_groups")
draw_vpaint_symmetry(layout, wpaint, context.object)
draw_vpaint_symmetry(layout, wpaint, ob)
row = layout.row()
row.active = mesh.use_mirror_vertex_groups
@ -1293,7 +1300,9 @@ class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
tool_settings = context.tool_settings
vpaint = tool_settings.vertex_paint
draw_vpaint_symmetry(layout, vpaint, context.object)
ob = context.object
draw_vpaint_symmetry(layout, vpaint, ob)
class VIEW3D_PT_tools_vertexpaint_symmetry_for_topbar(Panel):
@ -1358,7 +1367,8 @@ class VIEW3D_PT_tools_imagepaint_symmetry(Panel, View3DPaintPanel):
col = split.column()
row = col.row(align=True)
mesh = context.object.data
ob = context.object
mesh = ob.data
row.prop(mesh, "use_mirror_x", text="X", toggle=True)
row.prop(mesh, "use_mirror_y", text="Y", toggle=True)
row.prop(mesh, "use_mirror_z", text="Z", toggle=True)
@ -1938,7 +1948,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.tool_active_from_context(context)
if tool and tool.idname != 'builtin_brush.Tint':
if tool and tool.idname != "builtin_brush.Tint":
return False
gptool = brush.gpencil_tool
@ -2349,7 +2359,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.tool_active_from_context(context)
if tool and tool.idname in {'builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'}:
if tool and tool.idname in {"builtin.cutter", "builtin.eyedropper", "builtin.interpolate"}:
return False
if brush.gpencil_tool == 'TINT':
@ -2410,7 +2420,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.tool_active_from_context(context)
if tool and tool.idname in {'builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'}:
if tool and tool.idname in {"builtin.cutter", "builtin.eyedropper", "builtin.interpolate"}:
return False
if brush.gpencil_tool == 'TINT':
@ -2575,7 +2585,7 @@ class VIEW3D_PT_tools_grease_pencil_v3_brush_mixcolor(View3DPanel, Panel):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.tool_active_from_context(context)
if tool and tool.idname in {'builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'}:
if tool and tool.idname in {"builtin.cutter", "builtin.eyedropper", "builtin.interpolate"}:
return False
if brush.gpencil_tool == 'TINT':
@ -2632,7 +2642,7 @@ class VIEW3D_PT_tools_grease_pencil_v3_brush_mix_palette(View3DPanel, Panel):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.tool_active_from_context(context)
if tool and tool.idname in {'builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'}:
if tool and tool.idname in {"builtin.cutter", "builtin.eyedropper", "builtin.interpolate"}:
return False
if brush.gpencil_tool == 'TINT':

View File

@ -15,6 +15,7 @@
#include <array>
#include "BLI_array.hh"
#include "BLI_math_vector_types.hh"
#include "DNA_customdata_types.h"
@ -103,14 +104,16 @@ BMEditMesh *BKE_editmesh_from_object(Object *ob);
*/
void BKE_editmesh_free_data(BMEditMesh *em);
float (*BKE_editmesh_vert_coords_alloc(
Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, int *r_vert_len))[3];
float (*BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em, int *r_vert_len))[3];
const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
BMEditMesh *em,
Scene *scene,
Object *obedit,
int *r_vert_len,
bool *r_is_alloc))[3];
blender::Array<blender::float3> BKE_editmesh_vert_coords_alloc(Depsgraph *depsgraph,
BMEditMesh *em,
Scene *scene,
Object *ob);
blender::Array<blender::float3> BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em);
blender::Span<blender::float3> BKE_editmesh_vert_coords_when_deformed(
Depsgraph *depsgraph,
BMEditMesh *em,
Scene *scene,
Object *obedit,
blender::Array<blender::float3> &r_alloc);
void BKE_editmesh_lnorspace_update(BMEditMesh *em);

View File

@ -18,13 +18,13 @@ namespace blender::bke {
struct EditMeshData {
/** when set, \a vertexNos, faceNos are lazy initialized */
Array<float3> vertexCos;
Array<float3> vert_positions;
/** lazy initialize (when \a vertexCos is set) */
Array<float3> vertexNos;
Array<float3> faceNos;
/** also lazy init but don't depend on \a vertexCos */
Array<float3> faceCos;
/** lazy initialize (when \a vert_positions is set) */
Array<float3> vert_normals;
Array<float3> face_normals;
/** also lazy init but don't depend on \a vert_positions */
Array<float3> face_centers;
};
} // namespace blender::bke

View File

@ -53,7 +53,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
uint corner_tris_len,
const blender::Span<bool> sharp_faces,
CustomData *loopdata,
const CustomData *loopdata,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
@ -72,7 +72,7 @@ void BKE_mesh_calc_loop_tangents(Mesh *mesh_eval,
int tangent_names_len);
/* Helpers */
void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data,
void BKE_mesh_add_loop_tangent_named_layer_for_uv(const CustomData *uv_data,
CustomData *tan_data,
int numLoopData,
const char *layer_name);

View File

@ -26,15 +26,15 @@ int BKE_mesh_wrapper_face_len(const Mesh *mesh);
/**
* Return a contiguous array of vertex position values, if available.
* Otherwise, vertex positions are stored in BMesh vertices.
* Otherwise, vertex positions are stored in BMesh vertices and this returns null.
*/
const float (*BKE_mesh_wrapper_vert_coords(const Mesh *mesh))[3];
blender::Span<blender::float3> BKE_mesh_wrapper_vert_coords(const Mesh *mesh);
/**
* Return a contiguous array of face normal values, if available.
* Otherwise, normals are stored in BMesh faces.
* Otherwise, normals are stored in BMesh faces and this returns null.
*/
const float (*BKE_mesh_wrapper_face_normals(Mesh *mesh))[3];
blender::Span<blender::float3> BKE_mesh_wrapper_face_normals(Mesh *mesh);
void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh);

View File

@ -200,8 +200,8 @@ struct ModifierTypeInfo {
/********************* Deform modifier functions *********************/
/**
* Apply a deformation to the positions in the \a vertexCos array. If the \a mesh argument is
* non-null, if will contain proper (not wrapped) mesh data. The \a vertexCos array may or may
* Apply a deformation to the positions in the \a positions array. If the \a mesh argument is
* non-null, if will contain proper (not wrapped) mesh data. The \a positions array may or may
* not be the same as the mesh's position attribute.
*/
void (*deform_verts)(ModifierData *md,

View File

@ -242,11 +242,11 @@ Object *BKE_object_duplicate(Main *bmain,
*/
void BKE_object_obdata_size_init(Object *ob, float size);
void BKE_object_scale_to_mat3(Object *ob, float r_mat[3][3]);
void BKE_object_scale_to_mat3(const Object *ob, float r_mat[3][3]);
void BKE_object_rot_to_mat3(const Object *ob, float r_mat[3][3], bool use_drot);
void BKE_object_mat3_to_rot(Object *ob, float r_mat[3][3], bool use_compat);
void BKE_object_to_mat3(Object *ob, float r_mat[3][3]);
void BKE_object_to_mat4(Object *ob, float r_mat[4][4]);
void BKE_object_to_mat3(const Object *ob, float r_mat[3][3]);
void BKE_object_to_mat4(const Object *ob, float r_mat[4][4]);
/**
* Applies the global transformation \a mat to the \a ob using a relative parent space if
* supplied.
@ -319,7 +319,7 @@ blender::Vector<Base *> BKE_object_pose_base_array_get(const Scene *scene,
ViewLayer *view_layer,
View3D *v3d);
void BKE_object_get_parent_matrix(Object *ob, Object *par, float r_parentmat[4][4]);
void BKE_object_get_parent_matrix(const Object *ob, Object *par, float r_parentmat[4][4]);
/**
* Compute object world transform and store it in `ob->object_to_world().ptr()`.
@ -334,7 +334,7 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
* No changes to object and its parent would be done.
* Used for bundles orientation in 3d space relative to parented blender camera.
*/
void BKE_object_where_is_calc_mat4(Object *ob, float r_obmat[4][4]);
void BKE_object_where_is_calc_mat4(const Object *ob, float r_obmat[4][4]);
/* Possibly belong in its own module? */
@ -522,8 +522,9 @@ Mesh *BKE_object_get_pre_modified_mesh(const Object *object);
*/
Mesh *BKE_object_get_original_mesh(const Object *object);
Mesh *BKE_object_get_editmesh_eval_final(const Object *object);
Mesh *BKE_object_get_editmesh_eval_cage(const Object *object);
const Mesh *BKE_object_get_editmesh_eval_final(const Object *object);
const Mesh *BKE_object_get_editmesh_eval_cage(const Object *object);
const Mesh *BKE_object_get_mesh_deform_eval(const Object *object);
/* Lattice accessors.
* These functions return either the regular lattice, or the edit-mode lattice,
@ -576,7 +577,7 @@ bool BKE_object_moves_in_time(const Object *object, bool recurse_parent);
/** Return the number of scenes using (instantiating) that object in their collections. */
int BKE_object_scenes_users_get(Main *bmain, Object *ob);
MovieClip *BKE_object_movieclip_get(Scene *scene, Object *ob, bool use_default);
MovieClip *BKE_object_movieclip_get(Scene *scene, const Object *ob, bool use_default);
void BKE_object_runtime_reset(Object *object);
/**

View File

@ -75,7 +75,7 @@ void BKE_tracking_settings_init(struct MovieTracking *tracking);
* Get transformation matrix for a given object which is used
* for parenting motion tracker reconstruction to 3D world.
*/
void BKE_tracking_get_camera_object_matrix(struct Object *camera_object, float mat[4][4]);
void BKE_tracking_get_camera_object_matrix(const struct Object *camera_object, float mat[4][4]);
/**
* Get projection matrix for camera specified by given tracking object
* and frame number.

View File

@ -981,18 +981,6 @@ static void mesh_calc_modifiers(Depsgraph *depsgraph,
}
}
static blender::Array<float3> editbmesh_vert_coords_alloc(const BMEditMesh *em)
{
blender::Array<float3> cos(em->bm->totvert);
BMIter iter;
BMVert *eve;
int i;
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
cos[i] = eve->co;
}
return cos;
}
bool editbmesh_modifier_is_enabled(const Scene *scene,
const Object *ob,
ModifierData *md,
@ -1022,7 +1010,7 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final)
case ME_WRAPPER_TYPE_BMESH: {
BMEditMesh &em = *mesh_final->runtime->edit_mesh;
blender::bke::EditMeshData &emd = *mesh_final->runtime->edit_data;
if (!emd.vertexCos.is_empty()) {
if (!emd.vert_positions.is_empty()) {
BKE_editmesh_cache_ensure_vert_normals(em, emd);
BKE_editmesh_cache_ensure_face_normals(em, emd);
}
@ -1047,11 +1035,11 @@ static MutableSpan<float3> mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh)
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
if (mesh->runtime->edit_data->vertexCos.is_empty()) {
mesh->runtime->edit_data->vertexCos = editbmesh_vert_coords_alloc(
mesh->runtime->edit_mesh);
if (mesh->runtime->edit_data->vert_positions.is_empty()) {
mesh->runtime->edit_data->vert_positions = BM_mesh_vert_coords_alloc(
mesh->runtime->edit_mesh->bm);
}
return mesh->runtime->edit_data->vertexCos;
return mesh->runtime->edit_data->vert_positions;
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return mesh->vert_positions_for_write();

View File

@ -1510,13 +1510,11 @@ void BKE_brush_gpencil_vertex_presets(Main *bmain, ToolSettings *ts, const bool
}
/* Set default Vertex brush. */
if (reset || brush_prev == nullptr) {
BKE_paint_brush_set(vertexpaint, deft_vertex);
if ((reset == false) && (brush_prev != nullptr)) {
BKE_paint_brush_set(vertexpaint, brush_prev);
}
else {
if (brush_prev != nullptr) {
BKE_paint_brush_set(vertexpaint, brush_prev);
}
BKE_paint_brush_set(vertexpaint, deft_vertex);
}
}
@ -1587,13 +1585,11 @@ void BKE_brush_gpencil_sculpt_presets(Main *bmain, ToolSettings *ts, const bool
}
/* Set default brush. */
if (reset || brush_prev == nullptr) {
BKE_paint_brush_set(sculptpaint, deft_sculpt);
if ((reset == false) && (brush_prev != nullptr)) {
BKE_paint_brush_set(sculptpaint, brush_prev);
}
else {
if (brush_prev != nullptr) {
BKE_paint_brush_set(sculptpaint, brush_prev);
}
BKE_paint_brush_set(sculptpaint, deft_sculpt);
}
}
@ -1632,13 +1628,11 @@ void BKE_brush_gpencil_weight_presets(Main *bmain, ToolSettings *ts, const bool
}
/* Set default brush. */
if (reset || brush_prev == nullptr) {
BKE_paint_brush_set(weightpaint, deft_weight);
if ((reset == false) && (brush_prev != nullptr)) {
BKE_paint_brush_set(weightpaint, brush_prev);
}
else {
if (brush_prev != nullptr) {
BKE_paint_brush_set(weightpaint, brush_prev);
}
BKE_paint_brush_set(weightpaint, deft_weight);
}
}

View File

@ -27,6 +27,10 @@
#include "DEG_depsgraph_query.hh"
using blender::Array;
using blender::float3;
using blender::Span;
BMEditMesh *BKE_editmesh_create(BMesh *bm)
{
BMEditMesh *em = MEM_new<BMEditMesh>(__func__);
@ -124,7 +128,7 @@ void BKE_editmesh_free_data(BMEditMesh *em)
struct CageUserData {
int totvert;
float (*cos_cage)[3];
blender::MutableSpan<float3> positions_cage;
BLI_bitmap *visit_bitmap;
};
@ -137,16 +141,17 @@ static void cage_mapped_verts_callback(void *user_data,
if ((index >= 0 && index < data->totvert) && !BLI_BITMAP_TEST(data->visit_bitmap, index)) {
BLI_BITMAP_ENABLE(data->visit_bitmap, index);
copy_v3_v3(data->cos_cage[index], co);
copy_v3_v3(data->positions_cage[index], co);
}
}
float (*BKE_editmesh_vert_coords_alloc(
Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, int *r_vert_len))[3]
Array<float3> BKE_editmesh_vert_coords_alloc(Depsgraph *depsgraph,
BMEditMesh *em,
Scene *scene,
Object *ob)
{
Mesh *cage = editbmesh_get_eval_cage(depsgraph, scene, ob, em, &CD_MASK_BAREMESH);
float(*cos_cage)[3] = static_cast<float(*)[3]>(
MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, __func__));
Array<float3> positions_cage(em->bm->totvert);
/* When initializing cage verts, we only want the first cage coordinate for each vertex,
* so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate. */
@ -154,38 +159,29 @@ float (*BKE_editmesh_vert_coords_alloc(
CageUserData data;
data.totvert = em->bm->totvert;
data.cos_cage = cos_cage;
data.positions_cage = positions_cage;
data.visit_bitmap = visit_bitmap;
BKE_mesh_foreach_mapped_vert(cage, cage_mapped_verts_callback, &data, MESH_FOREACH_NOP);
MEM_freeN(visit_bitmap);
if (r_vert_len) {
*r_vert_len = em->bm->totvert;
}
return cos_cage;
return positions_cage;
}
const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
BMEditMesh *em,
Scene *scene,
Object *ob,
int *r_vert_len,
bool *r_is_alloc))[3]
Span<float3> BKE_editmesh_vert_coords_when_deformed(
Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, Array<float3> &r_alloc)
{
const float(*coords)[3] = nullptr;
*r_is_alloc = false;
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
Mesh *mesh_cage = BKE_object_get_editmesh_eval_cage(ob);
const Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
const Mesh *mesh_cage = BKE_object_get_editmesh_eval_cage(ob);
Span<float3> vert_positions;
if (mesh_cage && mesh_cage->runtime->deformed_only) {
BLI_assert(BKE_mesh_wrapper_vert_len(mesh_cage) == em->bm->totvert);
/* Deformed, and we have deformed coords already. */
coords = BKE_mesh_wrapper_vert_coords(mesh_cage);
vert_positions = BKE_mesh_wrapper_vert_coords(mesh_cage);
}
else if ((editmesh_eval_final != nullptr) &&
(editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH))
@ -194,15 +190,15 @@ const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
}
else {
/* Constructive modifiers have been used, we need to allocate coordinates. */
*r_is_alloc = true;
coords = BKE_editmesh_vert_coords_alloc(depsgraph, em, scene, ob, r_vert_len);
r_alloc = BKE_editmesh_vert_coords_alloc(depsgraph, em, scene, ob);
return r_alloc.as_span();
}
return coords;
return vert_positions;
}
float (*BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em, int *r_vert_len))[3]
Array<float3> BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em)
{
return BM_mesh_vert_coords_alloc(em->bm, r_vert_len);
return BM_mesh_vert_coords_alloc(em->bm);
}
void BKE_editmesh_lnorspace_update(BMEditMesh *em)

View File

@ -23,12 +23,12 @@
void BKE_editmesh_cache_ensure_face_normals(BMEditMesh &em, blender::bke::EditMeshData &emd)
{
if (emd.vertexCos.is_empty() || !emd.faceNos.is_empty()) {
if (emd.vert_positions.is_empty() || !emd.face_normals.is_empty()) {
return;
}
BMesh *bm = em.bm;
emd.faceNos.reinitialize(bm->totface);
emd.face_normals.reinitialize(bm->totface);
BM_mesh_elem_index_ensure(bm, BM_VERT);
BMFace *efa;
@ -36,15 +36,17 @@ void BKE_editmesh_cache_ensure_face_normals(BMEditMesh &em, blender::bke::EditMe
int i;
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
BM_elem_index_set(efa, i); /* set_inline */
BM_face_calc_normal_vcos(
bm, efa, emd.faceNos[i], reinterpret_cast<const float(*)[3]>(emd.vertexCos.data()));
BM_face_calc_normal_vcos(bm,
efa,
emd.face_normals[i],
reinterpret_cast<const float(*)[3]>(emd.vert_positions.data()));
}
bm->elem_index_dirty &= ~BM_FACE;
}
void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh &em, blender::bke::EditMeshData &emd)
{
if (emd.vertexCos.is_empty() || !emd.vertexNos.is_empty()) {
if (emd.vert_positions.is_empty() || !emd.vert_normals.is_empty()) {
return;
}
BMesh *bm = em.bm;
@ -52,37 +54,36 @@ void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh &em, blender::bke::EditMe
/* Calculate vertex normals from face normals. */
BKE_editmesh_cache_ensure_face_normals(em, emd);
emd.vertexNos.reinitialize(bm->totvert);
emd.vert_normals.reinitialize(bm->totvert);
BM_mesh_elem_index_ensure(bm, BM_FACE);
BM_verts_calc_normal_vcos(bm,
reinterpret_cast<const float(*)[3]>(emd.faceNos.data()),
reinterpret_cast<const float(*)[3]>(emd.vertexCos.data()),
reinterpret_cast<float(*)[3]>(emd.vertexNos.data()));
reinterpret_cast<const float(*)[3]>(emd.face_normals.data()),
reinterpret_cast<const float(*)[3]>(emd.vert_positions.data()),
reinterpret_cast<float(*)[3]>(emd.vert_normals.data()));
}
void BKE_editmesh_cache_ensure_face_centers(BMEditMesh &em, blender::bke::EditMeshData &emd)
{
if (!emd.faceCos.is_empty()) {
if (!emd.face_centers.is_empty()) {
return;
}
BMesh *bm = em.bm;
emd.faceCos.reinitialize(bm->totface);
emd.face_centers.reinitialize(bm->totface);
BMFace *efa;
BMIter fiter;
int i;
if (emd.vertexCos.is_empty()) {
if (emd.vert_positions.is_empty()) {
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
BM_face_calc_center_median(efa, emd.faceCos[i]);
BM_face_calc_center_median(efa, emd.face_centers[i]);
}
}
else {
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
BM_face_calc_center_median_vcos(
bm, efa, emd.faceCos[i], reinterpret_cast<const float(*)[3]>(emd.vertexCos.data()));
BM_face_calc_center_median_vcos(bm, efa, emd.face_centers[i], emd.vert_positions);
}
}
}
@ -102,7 +103,7 @@ std::optional<blender::Bounds<blender::float3>> BKE_editmesh_cache_calc_minmax(
return std::nullopt;
}
if (emd.vertexCos.is_empty()) {
if (emd.vert_positions.is_empty()) {
BMVert *eve;
BMIter iter;
float3 min(std::numeric_limits<float>::max());
@ -113,7 +114,7 @@ std::optional<blender::Bounds<blender::float3>> BKE_editmesh_cache_calc_minmax(
return Bounds<float3>{min, max};
}
return bounds::min_max(emd.vertexCos.as_span());
return bounds::min_max(emd.vert_positions.as_span());
}
/** \} */

View File

@ -727,13 +727,13 @@ Material *BKE_object_material_get(Object *ob, short act)
return ma_p ? *ma_p : nullptr;
}
static ID *get_evaluated_object_data_with_materials(Object *ob)
static const ID *get_evaluated_object_data_with_materials(Object *ob)
{
ID *data = static_cast<ID *>(ob->data);
const ID *data = static_cast<ID *>(ob->data);
/* Meshes in edit mode need special handling. */
if (ob->type == OB_MESH && ob->mode == OB_MODE_EDIT) {
Mesh *mesh = static_cast<Mesh *>(ob->data);
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
const Mesh *mesh = static_cast<const Mesh *>(ob->data);
const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
if (mesh->runtime->edit_mesh && editmesh_eval_final) {
data = &editmesh_eval_final->id;
}
@ -745,8 +745,8 @@ Material *BKE_object_material_get_eval(Object *ob, short act)
{
BLI_assert(DEG_is_evaluated_object(ob));
ID *data = get_evaluated_object_data_with_materials(ob);
const short *tot_slots_data_ptr = BKE_id_material_len_p(data);
const ID *data = get_evaluated_object_data_with_materials(ob);
const short *tot_slots_data_ptr = BKE_id_material_len_p(const_cast<ID *>(data));
const int tot_slots_data = tot_slots_data_ptr ? *tot_slots_data_ptr : 0;
if (tot_slots_data == 0) {
@ -757,7 +757,7 @@ Material *BKE_object_material_get_eval(Object *ob, short act)
const int slot_index = clamp_i(act - 1, 0, tot_slots_data - 1);
const int tot_slots_object = ob->totcol;
Material ***materials_data_ptr = BKE_id_material_array_p(data);
Material ***materials_data_ptr = BKE_id_material_array_p(const_cast<ID *>(data));
Material **materials_data = materials_data_ptr ? *materials_data_ptr : nullptr;
Material **materials_object = ob->mat;

View File

@ -769,15 +769,15 @@ static Mesh *mesh_new_from_mball_object(Object *object)
return BKE_mesh_copy_for_eval(mesh_eval);
}
static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
static Mesh *mesh_new_from_mesh(Object *object, const Mesh *mesh)
{
/* While we could copy this into the new mesh,
* add the data to 'mesh' so future calls to this function don't need to re-convert the data. */
if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
BKE_mesh_wrapper_ensure_mdata(mesh);
BKE_mesh_wrapper_ensure_mdata(const_cast<Mesh *>(mesh));
}
else {
mesh = BKE_mesh_wrapper_ensure_subdivision(mesh);
mesh = BKE_mesh_wrapper_ensure_subdivision(const_cast<Mesh *>(mesh));
}
Mesh *mesh_result = (Mesh *)BKE_id_copy_ex(
@ -828,12 +828,11 @@ static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
if (preserve_all_data_layers || preserve_origindex) {
return mesh_new_from_mesh_object_with_layers(depsgraph, object, preserve_origindex);
}
Mesh *mesh_input = (Mesh *)object->data;
const Mesh *mesh_input = (const Mesh *)object->data;
/* If we are in edit mode, use evaluated mesh from edit structure, matching to what
* viewport is using for visualization. */
if (mesh_input->runtime->edit_mesh != nullptr) {
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object);
if (editmesh_eval_final != nullptr) {
if (const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object)) {
mesh_input = editmesh_eval_final;
}
}

View File

@ -41,12 +41,12 @@ void BKE_mesh_foreach_mapped_vert(
BMIter iter;
BMVert *eve;
int i;
if (!mesh->runtime->edit_data->vertexCos.is_empty()) {
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vertexCos;
if (!mesh->runtime->edit_data->vert_positions.is_empty()) {
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vert_positions;
blender::Span<blender::float3> vert_normals;
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_editmesh_cache_ensure_vert_normals(*em, *mesh->runtime->edit_data);
vert_normals = mesh->runtime->edit_data->vertexNos;
vert_normals = mesh->runtime->edit_data->vert_normals;
}
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? &vert_normals[i].x : nullptr;
@ -100,8 +100,8 @@ void BKE_mesh_foreach_mapped_edge(
BMIter iter;
BMEdge *eed;
int i;
if (!mesh->runtime->edit_data->vertexCos.is_empty()) {
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vertexCos;
if (!mesh->runtime->edit_data->vert_positions.is_empty()) {
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vert_positions;
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
func(user_data,
@ -159,7 +159,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
BMIter iter;
BMFace *efa;
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vertexCos;
const blender::Span<blender::float3> positions = mesh->runtime->edit_data->vert_positions;
/* XXX: investigate using EditMesh data. */
blender::Span<blender::float3> corner_normals;
@ -243,11 +243,11 @@ void BKE_mesh_foreach_mapped_face_center(
int i;
BKE_editmesh_cache_ensure_face_centers(*em, *mesh->runtime->edit_data);
face_centers = mesh->runtime->edit_data->faceCos; /* always set */
face_centers = mesh->runtime->edit_data->face_centers; /* always set */
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_editmesh_cache_ensure_face_normals(*em, *mesh->runtime->edit_data);
face_normals = mesh->runtime->edit_data->faceNos; /* maybe nullptr */
face_normals = mesh->runtime->edit_data->face_normals; /* maybe nullptr */
}
if (!face_normals.is_empty()) {

View File

@ -297,7 +297,7 @@ static void DM_calc_loop_tangents_thread(TaskPool *__restrict /*pool*/, void *ta
mikk.genTangSpace();
}
void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data,
void BKE_mesh_add_loop_tangent_named_layer_for_uv(const CustomData *uv_data,
CustomData *tan_data,
int numLoopData,
const char *layer_name)
@ -393,7 +393,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const uint corner_tris_len,
const blender::Span<bool> sharp_faces,
CustomData *loopdata,
const CustomData *loopdata,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
@ -554,7 +554,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
if (act_uv_index != -1) {
int tan_index = CustomData_get_named_layer_index(
loopdata, CD_TANGENT, loopdata->layers[act_uv_index].name);
CustomData_set_layer_active_index(loopdata, CD_TANGENT, tan_index);
CustomData_set_layer_active_index(loopdata_out, CD_TANGENT, tan_index);
} /* else tangent has been built from orco */
/* Update render layer index */
@ -564,7 +564,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
if (ren_uv_index != -1) {
int tan_index = CustomData_get_named_layer_index(
loopdata, CD_TANGENT, loopdata->layers[ren_uv_index].name);
CustomData_set_layer_render_index(loopdata, CD_TANGENT, tan_index);
CustomData_set_layer_render_index(loopdata_out, CD_TANGENT, tan_index);
} /* else tangent has been built from orco */
}
}

View File

@ -124,8 +124,8 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
BKE_mesh_ensure_default_orig_index_customdata_no_check(mesh);
blender::bke::EditMeshData &edit_data = *mesh->runtime->edit_data;
if (!edit_data.vertexCos.is_empty()) {
mesh->vert_positions_for_write().copy_from(edit_data.vertexCos);
if (!edit_data.vert_positions.is_empty()) {
mesh->vert_positions_for_write().copy_from(edit_data.vert_positions);
mesh->runtime->is_original_bmesh = false;
}
@ -148,35 +148,31 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
/** \name Mesh Coordinate Access
* \{ */
const float (*BKE_mesh_wrapper_vert_coords(const Mesh *mesh))[3]
Span<float3> BKE_mesh_wrapper_vert_coords(const Mesh *mesh)
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
if (mesh->runtime->edit_data->vertexCos.is_empty()) {
return nullptr;
}
return reinterpret_cast<const float(*)[3]>(mesh->runtime->edit_data->vertexCos.data());
return mesh->runtime->edit_data->vert_positions;
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return reinterpret_cast<const float(*)[3]>(mesh->vert_positions().data());
return mesh->vert_positions();
}
return nullptr;
BLI_assert_unreachable();
return {};
}
const float (*BKE_mesh_wrapper_face_normals(Mesh *mesh))[3]
Span<float3> BKE_mesh_wrapper_face_normals(Mesh *mesh)
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
BKE_editmesh_cache_ensure_face_normals(*mesh->runtime->edit_mesh, *mesh->runtime->edit_data);
if (mesh->runtime->edit_data->faceNos.is_empty()) {
return nullptr;
}
return reinterpret_cast<const float(*)[3]>(mesh->runtime->edit_data->faceNos.data());
return mesh->runtime->edit_data->face_normals;
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD:
return reinterpret_cast<const float(*)[3]>(mesh->face_normals().data());
return mesh->face_normals();
}
return nullptr;
BLI_assert_unreachable();
return {};
}
void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh)
@ -184,9 +180,9 @@ void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh)
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:
if (mesh->runtime->edit_data) {
mesh->runtime->edit_data->vertexNos = {};
mesh->runtime->edit_data->faceCos = {};
mesh->runtime->edit_data->faceNos = {};
mesh->runtime->edit_data->vert_normals = {};
mesh->runtime->edit_data->face_centers = {};
mesh->runtime->edit_data->face_normals = {};
}
break;
case ME_WRAPPER_TYPE_MDATA:
@ -202,8 +198,8 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *mesh, blender::MutableSpan<fl
case ME_WRAPPER_TYPE_BMESH: {
BMesh *bm = mesh->runtime->edit_mesh->bm;
const blender::bke::EditMeshData &edit_data = *mesh->runtime->edit_data;
if (!edit_data.vertexCos.is_empty()) {
positions.copy_from(edit_data.vertexCos);
if (!edit_data.vert_positions.is_empty()) {
positions.copy_from(edit_data.vert_positions);
}
else {
BMIter iter;
@ -234,9 +230,9 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *mesh,
BMesh *bm = mesh->runtime->edit_mesh->bm;
BLI_assert(vert_coords_len == bm->totvert);
const blender::bke::EditMeshData &edit_data = *mesh->runtime->edit_data;
if (!edit_data.vertexCos.is_empty()) {
if (!edit_data.vert_positions.is_empty()) {
for (int i = 0; i < vert_coords_len; i++) {
mul_v3_m4v3(vert_coords[i], mat, edit_data.vertexCos[i]);
mul_v3_m4v3(vert_coords[i], mat, edit_data.vert_positions[i]);
}
}
else {

View File

@ -879,7 +879,7 @@ static void modwrap_dependsOnNormals(Mesh *mesh)
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH: {
blender::bke::EditMeshData &edit_data = *mesh->runtime->edit_data;
if (!edit_data.vertexCos.is_empty()) {
if (!edit_data.vert_positions.is_empty()) {
/* Note that 'ensure' is acceptable here since these values aren't modified in-place.
* If that changes we'll need to recalculate. */
BKE_editmesh_cache_ensure_vert_normals(*mesh->runtime->edit_mesh, edit_data);
@ -952,10 +952,10 @@ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval)
if ((ob_eval->type == OB_MESH) && (ob_eval->mode & OB_MODE_EDIT)) {
/* In EditMode, evaluated mesh is stored in BMEditMesh, not the object... */
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
const BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
/* 'em' might not exist yet in some cases, just after loading a .blend file, see #57878. */
if (em != nullptr) {
mesh = BKE_object_get_editmesh_eval_final(ob_eval);
mesh = const_cast<Mesh *>(BKE_object_get_editmesh_eval_final(ob_eval));
}
}
if (mesh == nullptr) {

View File

@ -2764,7 +2764,7 @@ void BKE_object_obdata_size_init(Object *ob, const float size)
/** \name Object Matrix Get/Set API
* \{ */
void BKE_object_scale_to_mat3(Object *ob, float mat[3][3])
void BKE_object_scale_to_mat3(const Object *ob, float mat[3][3])
{
float3 vec;
mul_v3_v3v3(vec, ob->scale, ob->dscale);
@ -2946,7 +2946,7 @@ void BKE_object_tfm_copy(Object *object_dst, const Object *object_src)
#undef TFMCPY4D
}
void BKE_object_to_mat3(Object *ob, float r_mat[3][3]) /* no parent */
void BKE_object_to_mat3(const Object *ob, float r_mat[3][3]) /* no parent */
{
float smat[3][3];
float rmat[3][3];
@ -2959,7 +2959,7 @@ void BKE_object_to_mat3(Object *ob, float r_mat[3][3]) /* no parent */
mul_m3_m3m3(r_mat, rmat, smat);
}
void BKE_object_to_mat4(Object *ob, float r_mat[4][4])
void BKE_object_to_mat4(const Object *ob, float r_mat[4][4])
{
float tmat[3][3];
@ -2987,7 +2987,7 @@ void BKE_object_matrix_local_get(Object *ob, float r_mat[4][4])
/**
* \return success if \a mat is set.
*/
static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4])
static bool ob_parcurve(const Object *ob, Object *par, float r_mat[4][4])
{
Curve *cu = (Curve *)par->data;
float vec[4], quat[4], radius, ctime;
@ -3046,7 +3046,7 @@ static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4])
return true;
}
static void ob_parbone(Object *ob, Object *par, float r_mat[4][4])
static void ob_parbone(const Object *ob, const Object *par, float r_mat[4][4])
{
float3 vec;
@ -3056,7 +3056,7 @@ static void ob_parbone(Object *ob, Object *par, float r_mat[4][4])
}
/* Make sure the bone is still valid */
bPoseChannel *pchan = BKE_pose_channel_find_name(par->pose, ob->parsubstr);
const bPoseChannel *pchan = BKE_pose_channel_find_name(par->pose, ob->parsubstr);
if (!pchan || !pchan->bone) {
CLOG_WARN(
&LOG, "Parent Bone: '%s' for Object: '%s' doesn't exist", ob->parsubstr, ob->id.name + 2);
@ -3080,15 +3080,15 @@ static void ob_parbone(Object *ob, Object *par, float r_mat[4][4])
}
}
static void give_parvert(Object *par, int nr, float vec[3])
static void give_parvert(const Object *par, int nr, float vec[3])
{
zero_v3(vec);
if (par->type == OB_MESH) {
Mesh *mesh = (Mesh *)par->data;
BMEditMesh *em = mesh->runtime->edit_mesh;
Mesh *mesh_eval = (em) ? BKE_object_get_editmesh_eval_final(par) :
BKE_object_get_evaluated_mesh(par);
const Mesh *mesh = (const Mesh *)par->data;
const BMEditMesh *em = mesh->runtime->edit_mesh;
const Mesh *mesh_eval = (em) ? BKE_object_get_editmesh_eval_final(par) :
BKE_object_get_evaluated_mesh(par);
if (mesh_eval) {
const Span<float3> positions = mesh_eval->vert_positions();
@ -3111,9 +3111,9 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
if (nr < numVerts) {
if (mesh_eval && mesh_eval->runtime->edit_data &&
!mesh_eval->runtime->edit_data->vertexCos.is_empty())
!mesh_eval->runtime->edit_data->vert_positions.is_empty())
{
add_v3_v3(vec, mesh_eval->runtime->edit_data->vertexCos[nr]);
add_v3_v3(vec, mesh_eval->runtime->edit_data->vert_positions[nr]);
}
else {
const BMVert *v = BM_vert_at_index(em->bm, nr);
@ -3201,7 +3201,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
}
static void ob_parvert3(Object *ob, Object *par, float r_mat[4][4])
static void ob_parvert3(const Object *ob, const Object *par, float r_mat[4][4])
{
/* in local ob space */
if (OB_TYPE_SUPPORT_PARVERT(par->type)) {
@ -3222,7 +3222,7 @@ static void ob_parvert3(Object *ob, Object *par, float r_mat[4][4])
}
}
void BKE_object_get_parent_matrix(Object *ob, Object *par, float r_parentmat[4][4])
void BKE_object_get_parent_matrix(const Object *ob, Object *par, float r_parentmat[4][4])
{
float tmat[4][4];
float vec[3];
@ -3277,8 +3277,11 @@ void BKE_object_get_parent_matrix(Object *ob, Object *par, float r_parentmat[4][
* \param r_originmat: Optional matrix that stores the space the object is in
* (without its own matrix applied)
*/
static void solve_parenting(
Object *ob, Object *par, const bool set_origin, float r_obmat[4][4], float r_originmat[3][3])
static void solve_parenting(const Object *ob,
Object *par,
const bool set_origin,
float r_obmat[4][4],
float r_originmat[3][3])
{
float totmat[4][4];
float tmat[4][4];
@ -3358,7 +3361,7 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
object_where_is_calc_ex(depsgraph, scene, ob, ctime, nullptr, nullptr);
}
void BKE_object_where_is_calc_mat4(Object *ob, float r_obmat[4][4])
void BKE_object_where_is_calc_mat4(const Object *ob, float r_obmat[4][4])
{
if (ob->parent) {
Object *par = ob->parent;
@ -4202,7 +4205,7 @@ Mesh *BKE_object_get_original_mesh(const Object *object)
return result;
}
Mesh *BKE_object_get_editmesh_eval_final(const Object *object)
const Mesh *BKE_object_get_editmesh_eval_final(const Object *object)
{
BLI_assert(!DEG_is_original_id(&object->id));
BLI_assert(object->type == OB_MESH);
@ -4217,7 +4220,7 @@ Mesh *BKE_object_get_editmesh_eval_final(const Object *object)
return reinterpret_cast<Mesh *>(object->runtime->data_eval);
}
Mesh *BKE_object_get_editmesh_eval_cage(const Object *object)
const Mesh *BKE_object_get_editmesh_eval_cage(const Object *object)
{
BLI_assert(!DEG_is_original_id(&object->id));
BLI_assert(object->type == OB_MESH);
@ -4229,6 +4232,13 @@ Mesh *BKE_object_get_editmesh_eval_cage(const Object *object)
return object->runtime->editmesh_eval_cage;
}
const Mesh *BKE_object_get_mesh_deform_eval(const Object *object)
{
BLI_assert(!DEG_is_original_id(&object->id));
BLI_assert(object->type == OB_MESH);
return object->runtime->mesh_deform_eval;
}
Lattice *BKE_object_get_lattice(const Object *object)
{
ID *data = (ID *)object->data;
@ -4806,7 +4816,7 @@ int BKE_object_scenes_users_get(Main *bmain, Object *ob)
return num_scenes;
}
MovieClip *BKE_object_movieclip_get(Scene *scene, Object *ob, bool use_default)
MovieClip *BKE_object_movieclip_get(Scene *scene, const Object *ob, bool use_default)
{
MovieClip *clip = use_default ? scene->clip : nullptr;
bConstraint *con = (bConstraint *)ob->constraints.first, *scon = nullptr;
@ -5039,8 +5049,9 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
Mesh *mesh = (Mesh *)ob->data;
uint i;
Mesh *mesh_eval = ob->runtime->mesh_deform_eval ? ob->runtime->mesh_deform_eval :
BKE_object_get_evaluated_mesh(ob);
const Mesh *mesh_eval = BKE_object_get_mesh_deform_eval(ob) ?
BKE_object_get_mesh_deform_eval(ob) :
BKE_object_get_evaluated_mesh(ob);
const int *index;
if (mesh_eval &&

View File

@ -472,11 +472,11 @@ static const Mesh *mesh_data_from_duplicator_object(Object *ob,
*r_em = em;
mesh_eval = nullptr;
if ((emd != nullptr) && !emd->vertexCos.is_empty()) {
*r_vert_coords = reinterpret_cast<const float(*)[3]>(emd->vertexCos.data());
if ((emd != nullptr) && !emd->vert_positions.is_empty()) {
*r_vert_coords = reinterpret_cast<const float(*)[3]>(emd->vert_positions.data());
if (r_vert_normals != nullptr) {
BKE_editmesh_cache_ensure_vert_normals(*em, *emd);
*r_vert_normals = reinterpret_cast<const float(*)[3]>(emd->vertexNos.data());
*r_vert_normals = reinterpret_cast<const float(*)[3]>(emd->vert_normals.data());
}
}
}

View File

@ -1769,7 +1769,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
bool used_me_eval = false;
if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
Mesh *me_eval_deform = ob_eval->runtime->mesh_deform_eval;
const Mesh *me_eval_deform = BKE_object_get_mesh_deform_eval(ob_eval);
/* If the fully evaluated mesh has the same topology as the deform-only version, use it.
* This matters because crazyspace evaluation is very restrictive and excludes even modifiers
@ -2127,7 +2127,7 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
ob->sculpt->attrs.dyntopo_node_id_face->bmesh_cd_offset);
}
static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform)
static PBVH *build_pbvh_from_regular_mesh(Object *ob, const Mesh *me_eval_deform)
{
Mesh *mesh = BKE_object_get_original_mesh(ob);
PBVH *pbvh = pbvh::build_mesh(mesh);
@ -2200,7 +2200,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime->subdiv_ccg.get());
}
else if (ob->type == OB_MESH) {
Mesh *me_eval_deform = object_eval->runtime->mesh_deform_eval;
const Mesh *me_eval_deform = BKE_object_get_mesh_deform_eval(object_eval);
pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform);
}
}

View File

@ -44,7 +44,6 @@
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.hh"
#include "BKE_object.hh"
#include "BKE_object_types.hh"
#include "BKE_pointcache.h"
#include "BKE_report.hh"
#include "BKE_rigidbody.h"
@ -338,13 +337,13 @@ void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src
/* Setup Utilities - Validate Sim Instances */
/* get the appropriate evaluated mesh based on rigid body mesh source */
static Mesh *rigidbody_get_mesh(Object *ob)
static const Mesh *rigidbody_get_mesh(Object *ob)
{
BLI_assert(ob->type == OB_MESH);
switch (ob->rigidbody_object->mesh_source) {
case RBO_MESH_DEFORM:
return ob->runtime->mesh_deform_eval;
return BKE_object_get_mesh_deform_eval(ob);
case RBO_MESH_FINAL:
return BKE_object_get_evaluated_mesh(ob);
case RBO_MESH_BASE:
@ -366,13 +365,13 @@ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob,
bool *can_embed)
{
rbCollisionShape *shape = nullptr;
Mesh *mesh = nullptr;
float(*positions)[3] = nullptr;
const Mesh *mesh = nullptr;
const float(*positions)[3] = nullptr;
int totvert = 0;
if (ob->type == OB_MESH && ob->data) {
mesh = rigidbody_get_mesh(ob);
positions = (mesh) ? reinterpret_cast<float(*)[3]>(mesh->vert_positions_for_write().data()) :
positions = (mesh) ? reinterpret_cast<const float(*)[3]>(mesh->vert_positions().data()) :
nullptr;
totvert = (mesh) ? mesh->verts_num : 0;
}
@ -399,7 +398,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
rbCollisionShape *shape = nullptr;
if (ob->type == OB_MESH) {
Mesh *mesh = rigidbody_get_mesh(ob);
const Mesh *mesh = rigidbody_get_mesh(ob);
if (mesh == nullptr) {
return nullptr;
}
@ -668,7 +667,7 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
case RB_SHAPE_CONVEXH:
case RB_SHAPE_TRIMESH: {
if (ob->type == OB_MESH) {
Mesh *mesh = rigidbody_get_mesh(ob);
const Mesh *mesh = rigidbody_get_mesh(ob);
if (mesh == nullptr) {
return;
}
@ -742,7 +741,7 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
case RB_SHAPE_CONVEXH:
case RB_SHAPE_TRIMESH: {
if (ob->type == OB_MESH) {
Mesh *mesh = rigidbody_get_mesh(ob);
const Mesh *mesh = rigidbody_get_mesh(ob);
if (mesh == nullptr) {
return;
}
@ -1763,10 +1762,10 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO
const bool is_selected = base ? (base->flag & BASE_SELECTED) != 0 : false;
if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
Mesh *mesh = ob->runtime->mesh_deform_eval;
const Mesh *mesh = BKE_object_get_mesh_deform_eval(ob);
if (mesh) {
float(*positions)[3] = reinterpret_cast<float(*)[3]>(
mesh->vert_positions_for_write().data());
const float(*positions)[3] = reinterpret_cast<const float(*)[3]>(
mesh->vert_positions().data());
int totvert = mesh->verts_num;
const std::optional<blender::Bounds<blender::float3>> bounds = BKE_object_boundbox_get(ob);

View File

@ -367,7 +367,7 @@ void BKE_tracking_settings_init(MovieTracking *tracking)
BKE_tracking_object_add(tracking, DATA_("Camera"));
}
void BKE_tracking_get_camera_object_matrix(Object *camera_object, float mat[4][4])
void BKE_tracking_get_camera_object_matrix(const Object *camera_object, float mat[4][4])
{
BLI_assert(camera_object != nullptr);
/* NOTE: Construct matrix from scratch rather than using obmat because the camera object here

View File

@ -22,6 +22,10 @@
#include "bmesh.hh"
using blender::Array;
using blender::float3;
using blender::MutableSpan;
const BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512};
const BMAllocTemplate bm_mesh_chunksize_default = {512, 1024, 2048, 512};
@ -1328,23 +1332,21 @@ void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags)
/** \name BMesh Coordinate Access
* \{ */
void BM_mesh_vert_coords_get(BMesh *bm, float (*vert_coords)[3])
void BM_mesh_vert_coords_get(BMesh *bm, MutableSpan<float3> positions)
{
BMIter iter;
BMVert *v;
int i;
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
copy_v3_v3(vert_coords[i], v->co);
positions[i] = v->co;
}
}
float (*BM_mesh_vert_coords_alloc(BMesh *bm, int *r_vert_len))[3]
Array<float3> BM_mesh_vert_coords_alloc(BMesh *bm)
{
float(*vert_coords)[3] = static_cast<float(*)[3]>(
MEM_mallocN(bm->totvert * sizeof(*vert_coords), __func__));
BM_mesh_vert_coords_get(bm, vert_coords);
*r_vert_len = bm->totvert;
return vert_coords;
Array<float3> positions(bm->totvert);
BM_mesh_vert_coords_get(bm, positions);
return positions;
}
void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3])

View File

@ -8,6 +8,10 @@
* \ingroup bmesh
*/
#include "BLI_array.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
#include "bmesh_class.hh"
struct BMAllocTemplate;
@ -197,8 +201,8 @@ extern const BMAllocTemplate bm_mesh_chunksize_default;
VA_NARGS_CALL_OVERLOAD(_VA_BMALLOC_TEMPLATE_FROM_ME_, __VA_ARGS__)
/* Vertex coords access. */
void BM_mesh_vert_coords_get(BMesh *bm, float (*vert_coords)[3]);
float (*BM_mesh_vert_coords_alloc(BMesh *bm, int *r_vert_len))[3];
void BM_mesh_vert_coords_get(BMesh *bm, blender::MutableSpan<blender::float3> positions);
blender::Array<blender::float3> BM_mesh_vert_coords_alloc(BMesh *bm);
void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3]);
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
const float (*vert_coords)[3],

View File

@ -90,9 +90,8 @@ static float bm_face_calc_poly_normal_vertex_cos(const BMFace *f,
/**
* \brief COMPUTE POLY CENTER (BMFace)
*/
static void bm_face_calc_poly_center_median_vertex_cos(const BMFace *f,
float r_cent[3],
float const (*vertexCos)[3])
static void bm_face_calc_poly_center_median_vertex_cos(
const BMFace *f, float r_cent[3], const blender::Span<blender::float3> vert_positions)
{
const BMLoop *l_first, *l_iter;
@ -101,7 +100,7 @@ static void bm_face_calc_poly_center_median_vertex_cos(const BMFace *f,
/* Newell's Method */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
add_v3_v3(r_cent, vertexCos[BM_elem_index_get(l_iter->v)]);
add_v3_v3(r_cent, vert_positions[BM_elem_index_get(l_iter->v)]);
} while ((l_iter = l_iter->next) != l_first);
mul_v3_fl(r_cent, 1.0f / f->len);
}
@ -520,7 +519,7 @@ void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
void BM_face_calc_center_bounds_vcos(const BMesh *bm,
const BMFace *f,
float r_cent[3],
float const (*vertexCos)[3])
const blender::Span<blender::float3> vert_positions)
{
/* must have valid index data */
BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
@ -533,7 +532,7 @@ void BM_face_calc_center_bounds_vcos(const BMesh *bm,
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
minmax_v3v3_v3(min, max, vertexCos[BM_elem_index_get(l_iter->v)]);
minmax_v3v3_v3(min, max, vert_positions[BM_elem_index_get(l_iter->v)]);
} while ((l_iter = l_iter->next) != l_first);
mid_v3_v3v3(r_cent, min, max);
@ -900,13 +899,13 @@ float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, fl
void BM_face_calc_center_median_vcos(const BMesh *bm,
const BMFace *f,
float r_cent[3],
float const (*vertexCos)[3])
const blender::Span<blender::float3> vert_positions)
{
/* must have valid index data */
BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
(void)bm;
bm_face_calc_poly_center_median_vertex_cos(f, r_cent, vertexCos);
bm_face_calc_poly_center_median_vertex_cos(f, r_cent, vert_positions);
}
void BM_face_normal_flip_ex(BMesh *bm,

View File

@ -11,6 +11,8 @@
struct Heap;
#include "BLI_compiler_attrs.h"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
/**
* For tools that insist on using triangles, ideally we would cache this data.
@ -128,7 +130,7 @@ void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3]) ATTR_NONNULL()
void BM_face_calc_center_bounds_vcos(const BMesh *bm,
const BMFace *f,
float r_center[3],
float const (*vertexCos)[3]) ATTR_NONNULL();
blender::Span<blender::float3> vert_positions) ATTR_NONNULL();
/**
* computes the center of a face, using the mean average
*/
@ -137,7 +139,8 @@ void BM_face_calc_center_median(const BMFace *f, float r_center[3]) ATTR_NONNULL
void BM_face_calc_center_median_vcos(const BMesh *bm,
const BMFace *f,
float r_center[3],
float const (*vertexCos)[3]) ATTR_NONNULL();
const blender::Span<blender::float3> vert_positions)
ATTR_NONNULL();
/**
* computes the center of a face, using the mean average
* weighted by edge length

View File

@ -237,8 +237,8 @@ static void overlay_edit_mesh_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob
/* TODO: Should be its own function. */
Mesh *mesh = (Mesh *)ob->data;
if (BMEditMesh *em = mesh->runtime->edit_mesh) {
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
has_edit_mesh_cage = editmesh_eval_cage && (editmesh_eval_cage != editmesh_eval_final);
has_skin_roots = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN) != -1;

View File

@ -177,11 +177,11 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
bool is_mesh_verts_only = false;
if (is_mesh) {
/* TODO: Should be its own function. */
Mesh *mesh = static_cast<Mesh *>(ob->data);
const Mesh *mesh = static_cast<const Mesh *>(ob->data);
if (is_edit_mode) {
BLI_assert(mesh->runtime->edit_mesh);
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
has_edit_mesh_cage = editmesh_eval_cage && (editmesh_eval_cage != editmesh_eval_final);
if (editmesh_eval_final) {
mesh = editmesh_eval_final;

View File

@ -336,8 +336,7 @@ void mesh_render_data_update_faces_sorted(MeshRenderData &mr,
const Mesh *editmesh_final_or_this(const Object *object, const Mesh *mesh)
{
if (mesh->runtime->edit_mesh != nullptr) {
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object);
if (editmesh_eval_final != nullptr) {
if (const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object)) {
return editmesh_eval_final;
}
}
@ -507,7 +506,7 @@ void mesh_render_data_update_normals(MeshRenderData &mr, const eMRDataType data_
const float(*vert_normals)[3] = nullptr;
const float(*face_normals)[3] = nullptr;
if (mr.edit_data && !mr.edit_data->vertexCos.is_empty()) {
if (mr.edit_data && !mr.edit_data->vert_positions.is_empty()) {
vert_coords = reinterpret_cast<const float(*)[3]>(mr.bm_vert_coords.data());
vert_normals = reinterpret_cast<const float(*)[3]>(mr.bm_vert_normals.data());
face_normals = reinterpret_cast<const float(*)[3]>(mr.bm_face_normals.data());
@ -559,8 +558,8 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->use_hide = use_hide;
if (is_editmode) {
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object);
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(object);
const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object);
const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(object);
BLI_assert(editmesh_eval_cage && editmesh_eval_final);
mr->bm = mesh->runtime->edit_mesh->bm;
@ -573,15 +572,14 @@ MeshRenderData *mesh_render_data_create(Object *object,
if (mr->edit_data) {
bke::EditMeshData *emd = mr->edit_data;
if (!emd->vertexCos.is_empty()) {
if (!emd->vert_positions.is_empty()) {
BKE_editmesh_cache_ensure_vert_normals(*mr->edit_bmesh, *emd);
BKE_editmesh_cache_ensure_face_normals(*mr->edit_bmesh, *emd);
}
mr->bm_vert_coords = mr->edit_data->vertexCos;
mr->bm_vert_normals = mr->edit_data->vertexNos;
mr->bm_face_normals = mr->edit_data->faceNos;
mr->bm_face_centers = mr->edit_data->faceCos;
mr->bm_vert_coords = mr->edit_data->vert_positions;
mr->bm_vert_normals = mr->edit_data->vert_normals;
mr->bm_face_normals = mr->edit_data->face_normals;
}
int bm_ensure_types = BM_VERT | BM_EDGE | BM_LOOP | BM_FACE;

View File

@ -105,7 +105,7 @@ static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
MBC_WIRE_EDGES | MBC_WIRE_LOOPS | MBC_SCULPT_OVERLAYS | MBC_VIEWER_ATTRIBUTE_OVERLAY |
MBC_SURFACE_PER_MAT;
case BUFFER_INDEX(vbo.nor):
return MBC_SURFACE | MBC_EDIT_LNOR | MBC_WIRE_LOOPS | MBC_SURFACE_PER_MAT;
return MBC_SURFACE | MBC_EDIT_LNOR | MBC_WIRE_LOOPS | MBC_SURFACE_PER_MAT | MBC_ALL_VERTS;
case BUFFER_INDEX(vbo.edge_fac):
return MBC_WIRE_EDGES;
case BUFFER_INDEX(vbo.weights):
@ -1407,7 +1407,8 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph *task_graph,
/* Modifiers will only generate an orco layer if the mesh is deformed. */
if (cache.cd_needed.orco != 0) {
/* Orco is always extracted from final mesh. */
Mesh *me_final = (mesh->runtime->edit_mesh) ? BKE_object_get_editmesh_eval_final(ob) : mesh;
const Mesh *me_final = (mesh->runtime->edit_mesh) ? BKE_object_get_editmesh_eval_final(ob) :
mesh;
if (CustomData_get_layer(&me_final->vert_data, CD_ORCO) == nullptr) {
/* Skip orco calculation */
cache.cd_needed.orco = 0;
@ -1512,8 +1513,8 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph *task_graph,
bool do_cage = false, do_uvcage = false;
if (is_editmode && is_mode_active) {
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
do_cage = editmesh_eval_final != editmesh_eval_cage;
do_uvcage = !(editmesh_eval_final->runtime->is_original_bmesh &&
@ -1555,9 +1556,10 @@ void DRW_mesh_batch_cache_create_requested(TaskGraph *task_graph,
}
drw_add_attributes_vbo(cache.batch.surface, mbuflist, &cache.attr_used);
}
assert_deps_valid(MBC_ALL_VERTS, {BUFFER_INDEX(vbo.pos)});
assert_deps_valid(MBC_ALL_VERTS, {BUFFER_INDEX(vbo.pos), BUFFER_INDEX(vbo.nor)});
if (DRW_batch_requested(cache.batch.all_verts, GPU_PRIM_POINTS)) {
DRW_vbo_request(cache.batch.all_verts, &mbuflist->vbo.pos);
DRW_vbo_request(cache.batch.all_verts, &mbuflist->vbo.nor);
}
assert_deps_valid(
MBC_SCULPT_OVERLAYS,

View File

@ -750,7 +750,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_bm(BMesh *bm,
}
static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData &mr,
Mesh *mesh,
const Mesh *mesh,
uint32_t *flags_data)
{
const OffsetIndices faces = mesh->faces();
@ -771,7 +771,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData &
}
}
static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
static void draw_subdiv_cache_extra_coarse_face_data_mapped(const Mesh *mesh,
BMesh *bm,
MeshRenderData &mr,
uint32_t *flags_data)
@ -797,7 +797,7 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
}
static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache &cache,
Mesh *mesh,
const Mesh *mesh,
MeshRenderData &mr)
{
if (cache.extra_coarse_face_data == nullptr) {
@ -839,7 +839,7 @@ static DRWSubdivCache &mesh_batch_cache_ensure_subdiv_cache(MeshBatchCache &mbc)
return *subdiv_cache;
}
static void draw_subdiv_invalidate_evaluator_for_orco(Subdiv *subdiv, Mesh *mesh)
static void draw_subdiv_invalidate_evaluator_for_orco(Subdiv *subdiv, const Mesh *mesh)
{
if (!(subdiv && subdiv->evaluator)) {
return;
@ -1167,7 +1167,7 @@ static void build_vertex_face_adjacency_maps(DRWSubdivCache &cache)
static bool draw_subdiv_build_cache(DRWSubdivCache &cache,
Subdiv *subdiv,
Mesh *mesh_eval,
const Mesh *mesh_eval,
const SubsurfRuntimeData *runtime_data)
{
SubdivToMeshSettings to_mesh_settings;
@ -2020,7 +2020,7 @@ void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache &cache,
* since all sub-faces are contiguous, they all share the same offset.
*/
static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache &cache,
Mesh *mesh_eval,
const Mesh *mesh_eval,
uint mat_len)
{
draw_subdiv_cache_free_material_data(cache);
@ -2108,7 +2108,7 @@ static bool draw_subdiv_create_requested_buffers(Object *ob,
return false;
}
Mesh *mesh_eval = mesh;
const Mesh *mesh_eval = mesh;
BMesh *bm = nullptr;
if (mesh->runtime->edit_mesh) {
mesh_eval = BKE_object_get_editmesh_eval_final(ob);

View File

@ -46,6 +46,9 @@
#include "draw_manager_text.hh"
#include "intern/bmesh_polygon.hh"
using blender::float3;
using blender::Span;
struct ViewCachedString {
float vec[3];
union {
@ -255,7 +258,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
*/
DRWTextStore *dt = DRW_text_cache_ensure();
const short txt_flag = DRW_TEXT_CACHE_GLOBALSPACE;
Mesh *mesh = BKE_object_get_editmesh_eval_cage(ob);
const Mesh *mesh = BKE_object_get_editmesh_eval_cage(ob);
BMEditMesh *em = mesh->runtime->edit_mesh;
float v1[3], v2[3], v3[3], vmid[3], fvec[3];
char numstr[32]; /* Stores the measurement display text here */
@ -269,8 +272,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
float clip_planes[4][4];
/* allow for displaying shape keys and deform mods */
BMIter iter;
const float(*vert_coords)[3] = BKE_mesh_wrapper_vert_coords(mesh);
const bool use_coords = (vert_coords != nullptr);
const Span<float3> vert_positions = BKE_mesh_wrapper_vert_coords(mesh);
const bool use_coords = !vert_positions.is_empty();
/* when 2 or more edge-info options are enabled, space apart */
short edge_tex_count = 0;
@ -329,9 +332,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
{
float v1_clip[3], v2_clip[3];
if (vert_coords) {
copy_v3_v3(v1, vert_coords[BM_elem_index_get(eed->v1)]);
copy_v3_v3(v2, vert_coords[BM_elem_index_get(eed->v2)]);
if (use_coords) {
copy_v3_v3(v1, vert_positions[BM_elem_index_get(eed->v1)]);
copy_v3_v3(v2, vert_positions[BM_elem_index_get(eed->v2)]);
}
else {
copy_v3_v3(v1, eed->v1->co);
@ -373,10 +376,12 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col);
const float(*face_normals)[3] = nullptr;
Span<float3> face_normals;
if (use_coords) {
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
face_normals = BKE_mesh_wrapper_face_normals(mesh);
/* TODO: This is not const correct for wrapper meshes, but it should be okay because
* every evaluated object gets its own evaluated cage mesh (they are not shared). */
face_normals = BKE_mesh_wrapper_face_normals(const_cast<Mesh *>(mesh));
}
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
@ -395,9 +400,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
{
float v1_clip[3], v2_clip[3];
if (vert_coords) {
copy_v3_v3(v1, vert_coords[BM_elem_index_get(eed->v1)]);
copy_v3_v3(v2, vert_coords[BM_elem_index_get(eed->v2)]);
if (use_coords) {
copy_v3_v3(v1, vert_positions[BM_elem_index_get(eed->v1)]);
copy_v3_v3(v2, vert_positions[BM_elem_index_get(eed->v2)]);
}
else {
copy_v3_v3(v1, eed->v1->co);
@ -462,9 +467,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
for (int j = 0; j < f_corner_tris_len; j++) {
if (use_coords) {
copy_v3_v3(v1, vert_coords[BM_elem_index_get(ltri_array[j][0]->v)]);
copy_v3_v3(v2, vert_coords[BM_elem_index_get(ltri_array[j][1]->v)]);
copy_v3_v3(v3, vert_coords[BM_elem_index_get(ltri_array[j][2]->v)]);
copy_v3_v3(v1, vert_positions[BM_elem_index_get(ltri_array[j][0]->v)]);
copy_v3_v3(v2, vert_positions[BM_elem_index_get(ltri_array[j][1]->v)]);
copy_v3_v3(v3, vert_positions[BM_elem_index_get(ltri_array[j][2]->v)]);
}
else {
copy_v3_v3(v1, ltri_array[j][0]->v->co);
@ -537,7 +542,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
/* lazy init center calc */
if (is_first) {
if (use_coords) {
BM_face_calc_center_bounds_vcos(em->bm, efa, vmid, vert_coords);
BM_face_calc_center_bounds_vcos(em->bm, efa, vmid, vert_positions);
}
else {
BM_face_calc_center_bounds(efa, vmid);
@ -545,9 +550,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
is_first = false;
}
if (use_coords) {
copy_v3_v3(v1, vert_coords[BM_elem_index_get(loop->prev->v)]);
copy_v3_v3(v2, vert_coords[BM_elem_index_get(loop->v)]);
copy_v3_v3(v3, vert_coords[BM_elem_index_get(loop->next->v)]);
copy_v3_v3(v1, vert_positions[BM_elem_index_get(loop->prev->v)]);
copy_v3_v3(v2, vert_positions[BM_elem_index_get(loop->v)]);
copy_v3_v3(v3, vert_positions[BM_elem_index_get(loop->next->v)]);
}
else {
copy_v3_v3(v1, loop->prev->v->co);
@ -595,7 +600,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
if (use_coords) {
copy_v3_v3(v1, vert_coords[BM_elem_index_get(v)]);
copy_v3_v3(v1, vert_positions[BM_elem_index_get(v)]);
}
else {
copy_v3_v3(v1, v->co);
@ -620,8 +625,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
float v1_clip[3], v2_clip[3];
if (use_coords) {
copy_v3_v3(v1, vert_coords[BM_elem_index_get(eed->v1)]);
copy_v3_v3(v2, vert_coords[BM_elem_index_get(eed->v2)]);
copy_v3_v3(v1, vert_positions[BM_elem_index_get(eed->v1)]);
copy_v3_v3(v2, vert_positions[BM_elem_index_get(eed->v2)]);
}
else {
copy_v3_v3(v1, eed->v1->co);
@ -658,7 +663,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
if (use_coords) {
BM_face_calc_center_median_vcos(em->bm, f, v1, vert_coords);
BM_face_calc_center_median_vcos(em->bm, f, v1, vert_positions);
}
else {
BM_face_calc_center_median(f, v1);

View File

@ -101,7 +101,7 @@ struct DRWSubdivLooseGeom {
* \{ */
struct DRWSubdivCache {
Mesh *mesh;
const Mesh *mesh;
BMesh *bm;
Subdiv *subdiv;
bool optimal_display;

View File

@ -197,7 +197,7 @@ static DRWShadingGroup *drw_volume_object_mesh_init(Scene *scene,
return nullptr;
}
if (fds->fluid && (fds->type == FLUID_DOMAIN_TYPE_GAS)) {
if (fds->type == FLUID_DOMAIN_TYPE_GAS) {
DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
}
@ -384,7 +384,7 @@ PassType *drw_volume_object_mesh_init(PassType &ps,
return nullptr;
}
if (fds->fluid && (fds->type == FLUID_DOMAIN_TYPE_GAS)) {
if (fds->type == FLUID_DOMAIN_TYPE_GAS) {
DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
}

View File

@ -80,7 +80,6 @@ struct MeshRenderData {
Span<float3> bm_vert_coords;
Span<float3> bm_vert_normals;
Span<float3> bm_face_normals;
Span<float3> bm_face_centers;
Array<float3> bm_loop_normals;
const int *v_origindex, *e_origindex, *p_origindex;
@ -90,7 +89,7 @@ struct MeshRenderData {
int freestyle_edge_ofs;
int freestyle_face_ofs;
/** Mesh */
Mesh *mesh;
const Mesh *mesh;
Span<float3> vert_positions;
Span<int2> edges;
OffsetIndices<int> faces;

View File

@ -268,7 +268,7 @@ static void extract_attr_init_subdiv(const DRWSubdivCache &subdiv_cache,
const DRW_Attributes *attrs_used = &cache.attr_used;
const DRW_AttributeRequest &request = attrs_used->requests[index];
Mesh *coarse_mesh = subdiv_cache.mesh;
const Mesh *coarse_mesh = subdiv_cache.mesh;
/* Prepare VBO for coarse data. The compute shader only expects floats. */
gpu::VertBuf *src_data = GPU_vertbuf_calloc();

View File

@ -253,8 +253,8 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache &subdi
/* UVs are stored contiguously so we need to compute the offset in the UVs buffer for the active
* UV layer. */
CustomData *cd_ldata = (mr.extract_type == MR_EXTRACT_MESH) ? &mr.mesh->corner_data :
&mr.bm->ldata;
const CustomData *cd_ldata = (mr.extract_type == MR_EXTRACT_MESH) ? &mr.mesh->corner_data :
&mr.bm->ldata;
uint32_t uv_layers = cache.cd_used.uv;
/* HACK to fix #68857 */

View File

@ -37,7 +37,7 @@ static void extract_orco_init(const MeshRenderData &mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, mr.corners_num);
CustomData *cd_vdata = &mr.mesh->vert_data;
const CustomData *cd_vdata = &mr.mesh->vert_data;
MeshExtract_Orco_Data *data = static_cast<MeshExtract_Orco_Data *>(tls_data);
data->vbo_data = (float(*)[4])GPU_vertbuf_get_data(vbo);

View File

@ -48,14 +48,20 @@ static void extract_pos_init(const MeshRenderData &mr,
MutableSpan vbo_data(static_cast<float3 *>(GPU_vertbuf_get_data(vbo)),
GPU_vertbuf_get_vertex_len(vbo));
if (mr.extract_type == MR_EXTRACT_MESH) {
array_utils::gather(
mr.vert_positions, mr.corner_verts, vbo_data.take_front(mr.corner_verts.size()));
extract_mesh_loose_edge_positions(mr.vert_positions,
mr.edges,
mr.loose_edges,
vbo_data.slice(mr.corners_num, mr.loose_edges.size() * 2));
array_utils::gather(
mr.vert_positions, mr.loose_verts, vbo_data.take_back(mr.loose_verts.size()));
threading::memory_bandwidth_bound_task(
mr.vert_positions.size_in_bytes() + mr.corner_verts.size_in_bytes() +
vbo_data.size_in_bytes() + mr.loose_edges.size(),
[&]() {
array_utils::gather(
mr.vert_positions, mr.corner_verts, vbo_data.take_front(mr.corner_verts.size()));
extract_mesh_loose_edge_positions(
mr.vert_positions,
mr.edges,
mr.loose_edges,
vbo_data.slice(mr.corners_num, mr.loose_edges.size() * 2));
array_utils::gather(
mr.vert_positions, mr.loose_verts, vbo_data.take_back(mr.loose_verts.size()));
});
}
else {
*static_cast<float3 **>(tls_data) = vbo_data.data();

View File

@ -117,7 +117,7 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache &subdiv_cache,
{
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buffer);
Mesh *coarse_mesh = mr.mesh;
const Mesh *coarse_mesh = mr.mesh;
/* First, interpolate mask if available. */
gpu::VertBuf *mask_vbo = nullptr;

View File

@ -38,10 +38,10 @@ static void extract_tan_init_common(const MeshRenderData &mr,
{
GPU_vertformat_deinterleave(format);
CustomData *cd_ldata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->ldata :
&mr.mesh->corner_data;
CustomData *cd_vdata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->vdata :
&mr.mesh->vert_data;
const CustomData *cd_ldata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->ldata :
&mr.mesh->corner_data;
const CustomData *cd_vdata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->vdata :
&mr.mesh->vert_data;
uint32_t tan_layers = cache.cd_used.tan;
const float(*orco)[3] = (const float(*)[3])CustomData_get_layer(cd_vdata, CD_ORCO);
float(*orco_allocated)[3] = nullptr;
@ -96,7 +96,9 @@ static void extract_tan_init_common(const MeshRenderData &mr,
copy_v3_v3(orco_allocated[v], mr.vert_positions[v]);
}
}
BKE_mesh_orco_verts_transform(mr.mesh, orco_allocated, mr.verts_num, false);
/* TODO: This is not thread-safe. Draw extraction should not modify the mesh. */
BKE_mesh_orco_verts_transform(
const_cast<Mesh *>(mr.mesh), orco_allocated, mr.verts_num, false);
orco = orco_allocated;
}
@ -118,6 +120,7 @@ static void extract_tan_init_common(const MeshRenderData &mr,
&tangent_mask);
}
else {
/* TODO: This is not thread-safe. Draw extraction should not modify the mesh. */
BKE_mesh_calc_loop_tangent_ex(reinterpret_cast<const float(*)[3]>(mr.vert_positions.data()),
mr.faces,
mr.corner_verts.data(),

View File

@ -22,9 +22,9 @@ namespace blender::draw {
/* Initialize the vertex format to be used for UVs. Return true if any UV layer is
* found, false otherwise. */
static bool mesh_extract_uv_format_init(GPUVertFormat *format,
MeshBatchCache &cache,
CustomData *cd_ldata,
eMRExtractType extract_type,
const MeshBatchCache &cache,
const CustomData *cd_ldata,
const eMRExtractType extract_type,
uint32_t &r_uv_layers)
{
GPU_vertformat_deinterleave(format);
@ -89,8 +89,8 @@ static void extract_uv_init(const MeshRenderData &mr,
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buf);
GPUVertFormat format = {0};
CustomData *cd_ldata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->ldata :
&mr.mesh->corner_data;
const CustomData *cd_ldata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->ldata :
&mr.mesh->corner_data;
int v_len = mr.corners_num;
uint32_t uv_layers = cache.cd_used.uv;
if (!mesh_extract_uv_format_init(&format, cache, cd_ldata, mr.extract_type, uv_layers)) {
@ -136,7 +136,7 @@ static void extract_uv_init_subdiv(const DRWSubdivCache &subdiv_cache,
void *buffer,
void * /*data*/)
{
Mesh *coarse_mesh = subdiv_cache.mesh;
const Mesh *coarse_mesh = subdiv_cache.mesh;
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buffer);
GPUVertFormat format = {0};

View File

@ -159,7 +159,7 @@ static void extract_weights_init_subdiv(const DRWSubdivCache &subdiv_cache,
void *buffer,
void *_data)
{
Mesh *coarse_mesh = subdiv_cache.mesh;
const Mesh *coarse_mesh = subdiv_cache.mesh;
gpu::VertBuf *vbo = static_cast<gpu::VertBuf *>(buffer);
static GPUVertFormat format = {0};

View File

@ -390,46 +390,44 @@ static void updateDuplicateSubtarget(EditBone *dup_bone,
*/
EditBone *oldtarget, *newtarget;
bPoseChannel *pchan;
ListBase *conlist;
if ((pchan = BKE_pose_channel_ensure(ob->pose, dup_bone->name))) {
if ((conlist = &pchan->constraints)) {
LISTBASE_FOREACH (bConstraint *, curcon, conlist) {
/* does this constraint have a subtarget in
* this armature?
*/
ListBase targets = {nullptr, nullptr};
ListBase *conlist = &pchan->constraints;
LISTBASE_FOREACH (bConstraint *, curcon, conlist) {
/* does this constraint have a subtarget in
* this armature?
*/
ListBase targets = {nullptr, nullptr};
if (BKE_constraint_targets_get(curcon, &targets)) {
LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
if ((ct->tar == ob) && (ct->subtarget[0])) {
oldtarget = get_named_editbone(editbones, ct->subtarget);
if (oldtarget) {
/* was the subtarget bone duplicated too? If
* so, update the constraint to point at the
* duplicate of the old subtarget.
*/
if (oldtarget->temp.ebone) {
newtarget = oldtarget->temp.ebone;
if (BKE_constraint_targets_get(curcon, &targets)) {
LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
if ((ct->tar == ob) && (ct->subtarget[0])) {
oldtarget = get_named_editbone(editbones, ct->subtarget);
if (oldtarget) {
/* was the subtarget bone duplicated too? If
* so, update the constraint to point at the
* duplicate of the old subtarget.
*/
if (oldtarget->temp.ebone) {
newtarget = oldtarget->temp.ebone;
STRNCPY(ct->subtarget, newtarget->name);
}
else if (lookup_mirror_subtarget) {
/* The subtarget was not selected for duplication, try to see if a mirror bone of
* the current target exists */
char name_flip[MAXBONENAME];
BLI_string_flip_side_name(name_flip, oldtarget->name, false, sizeof(name_flip));
newtarget = get_named_editbone(editbones, name_flip);
if (newtarget) {
STRNCPY(ct->subtarget, newtarget->name);
}
else if (lookup_mirror_subtarget) {
/* The subtarget was not selected for duplication, try to see if a mirror bone of
* the current target exists */
char name_flip[MAXBONENAME];
BLI_string_flip_side_name(name_flip, oldtarget->name, false, sizeof(name_flip));
newtarget = get_named_editbone(editbones, name_flip);
if (newtarget) {
STRNCPY(ct->subtarget, newtarget->name);
}
}
}
}
}
BKE_constraint_targets_flush(curcon, &targets, false);
}
BKE_constraint_targets_flush(curcon, &targets, false);
}
}
}

View File

@ -774,20 +774,6 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int separate_armature_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (RNA_boolean_get(op->ptr, "confirm")) {
return WM_operator_confirm_ex(C,
op,
IFACE_("Move selected bones to a separate armature?"),
nullptr,
IFACE_("Separate"),
ALERT_ICON_NONE,
false);
}
return separate_armature_exec(C, op);
}
void ARMATURE_OT_separate(wmOperatorType *ot)
{
/* identifiers */
@ -796,13 +782,11 @@ void ARMATURE_OT_separate(wmOperatorType *ot)
ot->description = "Isolate selected bones into a separate armature";
/* callbacks */
ot->invoke = separate_armature_invoke;
ot->exec = separate_armature_exec;
ot->poll = ED_operator_editarmature;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
WM_operator_properties_confirm_or_exec(ot);
}
/** \} */

View File

@ -1455,20 +1455,6 @@ static int separate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int separate_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (RNA_boolean_get(op->ptr, "confirm")) {
return WM_operator_confirm_ex(C,
op,
IFACE_("Move selected points to a new object?"),
nullptr,
IFACE_("Separate"),
ALERT_ICON_NONE,
false);
}
return separate_exec(C, op);
}
void CURVE_OT_separate(wmOperatorType *ot)
{
/* identifiers */
@ -1477,13 +1463,11 @@ void CURVE_OT_separate(wmOperatorType *ot)
ot->description = "Separate selected points from connected unselected points into a new object";
/* api callbacks */
ot->invoke = separate_invoke;
ot->exec = separate_exec;
ot->poll = ED_operator_editsurfcurve;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
WM_operator_properties_confirm_or_exec(ot);
}
/** \} */

View File

@ -878,6 +878,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
ops.sculpt.lasso_hide
ops.sculpt.lasso_mask
ops.sculpt.lasso_trim
ops.sculpt.line_hide
ops.sculpt.line_mask
ops.sculpt.line_project
ops.sculpt.mask_by_color

View File

@ -9,6 +9,8 @@
#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
struct ARegion;
struct BMBVHTree;
@ -337,7 +339,7 @@ void EDBM_preselect_edgering_update_from_edge(EditMesh_PreSelEdgeRing *psel,
BMesh *bm,
BMEdge *eed_start,
int previewlines,
const float (*coords)[3]);
blender::Span<blender::float3> vert_positions);
/* `editmesh_preselect_elem.cc` */
@ -356,7 +358,7 @@ void EDBM_preselect_elem_draw(EditMesh_PreSelElem *psel, const float matrix[4][4
void EDBM_preselect_elem_update_from_single(EditMesh_PreSelElem *psel,
BMesh *bm,
BMElem *ele,
const float (*coords)[3]);
blender::Span<blender::float3> vert_positions);
void EDBM_preselect_elem_update_preview(
EditMesh_PreSelElem *psel, ViewContext *vc, BMesh *bm, BMElem *ele, const int mval[2]);

View File

@ -86,7 +86,7 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
float r_loc[3],
float r_no[3],
int *r_index,
Object **r_ob,
const Object **r_ob,
float r_obmat[4][4]);
/**
* Convenience function for snap ray-casting.
@ -155,7 +155,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
float r_loc[3],
float r_no[3],
int *r_index,
Object **r_ob,
const Object **r_ob,
float r_obmat[4][4],
float r_face_nor[3]);
/**

View File

@ -1368,7 +1368,7 @@ static std::optional<std::string> ui_but_event_property_operator_string(const bC
int prop_index = but->rnaindex;
if ((but->type == UI_BTYPE_BUT_MENU) && (but->block->handle != nullptr)) {
uiBut *but_parent = but->block->handle->popup_create_vars.but;
if ((but->type == UI_BTYPE_BUT_MENU) && (but_parent && but_parent->rnaprop) &&
if ((but_parent && but_parent->rnaprop) &&
(RNA_property_type(but_parent->rnaprop) == PROP_ENUM) &&
ELEM(but_parent->menu_create_func,
ui_def_but_rna__menu,
@ -3420,9 +3420,7 @@ static void ui_but_free(const bContext *C, uiBut *but)
ui_but_active_free(C, but);
}
else {
if (but->active) {
MEM_freeN(but->active);
}
MEM_freeN(but->active);
}
}

View File

@ -6013,7 +6013,7 @@ static int ui_do_but_SCROLL(
button_activate_state(C, but, BUTTON_STATE_EXIT);
}
else if (event->type == MOUSEMOVE) {
const bool is_motion = (event->type == MOUSEMOVE);
const bool is_motion = true;
if (ui_numedit_but_SLI(
but, data, (horizontal) ? mx : my, horizontal, is_motion, false, false))
{

View File

@ -2568,9 +2568,7 @@ static void widget_state(uiWidgetType *wt, const uiWidgetStateInfo *state, eUIEm
copy_v3_v3_uchar(wt->wcol.text, wt->wcol.text_sel);
if (state->but_flag & UI_SELECT) {
std::swap(wt->wcol.shadetop, wt->wcol.shadedown);
}
std::swap(wt->wcol.shadetop, wt->wcol.shadedown);
}
else {
if (state->but_flag & UI_BUT_ACTIVE_DEFAULT) {

View File

@ -19,7 +19,6 @@
#include "BLF_api.hh"
#include "BLI_alloca.h"
#include "BLI_array.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_map.hh"
@ -31,6 +30,7 @@
#include "BLI_set.hh"
#include "BLI_stack.h"
#include "BLI_string.h"
#include "BLI_vector.hh"
#include "BLT_translation.hh"
@ -198,7 +198,7 @@ struct KnifeBVH {
/** Additional per-object data. */
struct KnifeObjectInfo {
const float (*cagecos)[3];
Array<float3> positions_cage;
/**
* Optionally allocate triangle indices, these are needed for non-interactive knife
@ -206,7 +206,7 @@ struct KnifeObjectInfo {
* Using these indices the it's possible to access `cagecos` even if the face has been cut
* and the loops in `em->looptris` no longer refer to the original triangles, see: #97153.
*/
const int (*tri_indices)[3];
Array<int3> tri_indices;
/** Only assigned for convenient access. */
BMEditMesh *em;
@ -227,7 +227,7 @@ struct KnifeTool_OpData {
Vector<Object *> objects;
/** Array `objects_len` length of additional per-object data. */
KnifeObjectInfo *objects_info;
Array<KnifeObjectInfo> objects_info;
MemArena *arena;
@ -258,8 +258,7 @@ struct KnifeTool_OpData {
float ethresh;
/* Used for drag-cutting. */
KnifeLineHit *linehits;
int totlinehit;
Vector<KnifeLineHit> linehits;
/* Data for mouse-position-derived data. */
KnifePosData curr; /* Current point under the cursor. */
@ -1025,23 +1024,21 @@ static void knifetool_draw(const bContext * /*C*/, ARegion * /*region*/, void *a
immEnd();
}
if (kcd->totlinehit > 0) {
KnifeLineHit *lh;
int i, snapped_verts_count, other_verts_count;
float fcol[4];
const int64_t total_hits = kcd->linehits.size();
if (total_hits > 0) {
GPU_blend(GPU_BLEND_ALPHA);
blender::gpu::VertBuf *vert = GPU_vertbuf_create_with_format(format);
GPU_vertbuf_data_alloc(vert, kcd->totlinehit);
GPU_vertbuf_data_alloc(vert, total_hits);
lh = kcd->linehits;
for (i = 0, snapped_verts_count = 0, other_verts_count = 0; i < kcd->totlinehit; i++, lh++) {
if (lh->v) {
GPU_vertbuf_attr_set(vert, pos, snapped_verts_count++, lh->cagehit);
int other_verts_count = 0;
int snapped_verts_count = 0;
for (const KnifeLineHit &hit : kcd->linehits) {
if (hit.v) {
GPU_vertbuf_attr_set(vert, pos, snapped_verts_count++, hit.cagehit);
}
else {
GPU_vertbuf_attr_set(vert, pos, kcd->totlinehit - 1 - other_verts_count++, lh->cagehit);
GPU_vertbuf_attr_set(vert, pos, total_hits - 1 - other_verts_count++, hit.cagehit);
}
}
@ -1049,6 +1046,7 @@ static void knifetool_draw(const bContext * /*C*/, ARegion * /*region*/, void *a
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
/* Draw any snapped verts first. */
float fcol[4];
rgba_uchar_to_float(fcol, kcd->colors.point_a);
GPU_batch_uniform_4fv(batch, "color", fcol);
GPU_point_size(11 * UI_SCALE_FAC);
@ -1163,7 +1161,7 @@ static const int *knife_bm_tri_index_get(const KnifeTool_OpData *kcd,
int tri_index_buf[3])
{
const KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
if (obinfo->tri_indices) {
if (!obinfo->tri_indices.is_empty()) {
return obinfo->tri_indices[tri_index];
}
const std::array<BMLoop *, 3> &ltri = obinfo->em->looptris[tri_index];
@ -1182,7 +1180,7 @@ static void knife_bm_tri_cagecos_get(const KnifeTool_OpData *kcd,
int tri_ind_buf[3];
const int *tri_ind = knife_bm_tri_index_get(kcd, ob_index, tri_index, tri_ind_buf);
for (int i = 0; i < 3; i++) {
copy_v3_v3(cos[i], obinfo->cagecos[tri_ind[i]]);
copy_v3_v3(cos[i], obinfo->positions_cage[tri_ind[i]]);
}
}
@ -1689,7 +1687,7 @@ static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, int ob_ind
BMFace *f;
if (BM_elem_index_get(v) >= 0) {
cageco = kcd->objects_info[ob_index].cagecos[BM_elem_index_get(v)];
cageco = kcd->objects_info[ob_index].positions_cage[BM_elem_index_get(v)];
}
else {
cageco = v->co;
@ -1863,30 +1861,27 @@ static void linehit_to_knifepos(KnifePosData *kpos, KnifeLineHit *lh)
* Secondary key: lambda along depth
* Tertiary key: pointer comparisons of verts if both snapped to verts
*/
static int linehit_compare(const void *vlh1, const void *vlh2)
static int linehit_compare(const KnifeLineHit &lh1, const KnifeLineHit &lh2)
{
const KnifeLineHit *lh1 = static_cast<const KnifeLineHit *>(vlh1);
const KnifeLineHit *lh2 = static_cast<const KnifeLineHit *>(vlh2);
if (lh1->l < lh2->l) {
return -1;
if (lh1.l < lh2.l) {
return true;
}
if (lh1->l > lh2->l) {
return 1;
if (lh1.l > lh2.l) {
return false;
}
if (lh1->m < lh2->m) {
return -1;
if (lh1.m < lh2.m) {
return true;
}
if (lh1->m > lh2->m) {
return 1;
if (lh1.m > lh2.m) {
return false;
}
if (lh1->v < lh2->v) {
return -1;
if (lh1.v < lh2.v) {
return true;
}
if (lh1->v > lh2->v) {
return 1;
if (lh1.v > lh2.v) {
return false;
}
return 0;
return false;
}
/*
@ -1898,26 +1893,25 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd)
{
bool is_double = false;
int n = kcd->totlinehit;
KnifeLineHit *linehits = kcd->linehits;
if (n == 0) {
if (kcd->linehits.is_empty()) {
return;
}
qsort(linehits, n, sizeof(KnifeLineHit), linehit_compare);
std::sort(kcd->linehits.begin(), kcd->linehits.end(), linehit_compare);
/* Remove any edge hits that are preceded or followed
* by a vertex hit that is very near. Mark such edge hits using
* l == -1 and then do another pass to actually remove.
* Also remove all but one of a series of vertex hits for the same vertex. */
for (int i = 0; i < n; i++) {
KnifeLineHit *lhi = &linehits[i];
const int64_t total_hits = kcd->linehits.size();
for (int i = 0; i < total_hits; i++) {
KnifeLineHit *lhi = &kcd->linehits[i];
if (lhi->v == nullptr) {
continue;
}
for (int j = i - 1; j >= 0; j--) {
KnifeLineHit *lhj = &linehits[j];
KnifeLineHit *lhj = &kcd->linehits[j];
if (!lhj->kfe || fabsf(lhi->l - lhj->l) > KNIFE_FLT_EPSBIG ||
fabsf(lhi->m - lhj->m) > KNIFE_FLT_EPSBIG)
{
@ -1929,8 +1923,8 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd)
is_double = true;
}
}
for (int j = i + 1; j < n; j++) {
KnifeLineHit *lhj = &linehits[j];
for (int j = i + 1; j < total_hits; j++) {
KnifeLineHit *lhj = &kcd->linehits[j];
if (fabsf(lhi->l - lhj->l) > KNIFE_FLT_EPSBIG || fabsf(lhi->m - lhj->m) > KNIFE_FLT_EPSBIG) {
break;
}
@ -1945,9 +1939,9 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd)
/* Delete-in-place loop: copying from pos j to pos i+1. */
int i = 0;
int j = 1;
while (j < n) {
KnifeLineHit *lhi = &linehits[i];
KnifeLineHit *lhj = &linehits[j];
while (j < total_hits) {
KnifeLineHit *lhi = &kcd->linehits[i];
KnifeLineHit *lhj = &kcd->linehits[j];
if (lhj->l == -1.0f) {
j++; /* Skip copying this one. */
}
@ -1955,18 +1949,18 @@ static void prepare_linehits_for_cut(KnifeTool_OpData *kcd)
/* Copy unless a no-op. */
if (lhi->l == -1.0f) {
/* Could happen if linehits[0] is being deleted. */
memcpy(&linehits[i], &linehits[j], sizeof(KnifeLineHit));
memcpy(&kcd->linehits[i], &kcd->linehits[j], sizeof(KnifeLineHit));
}
else {
if (i + 1 != j) {
memcpy(&linehits[i + 1], &linehits[j], sizeof(KnifeLineHit));
memcpy(&kcd->linehits[i + 1], &kcd->linehits[j], sizeof(KnifeLineHit));
}
i++;
}
j++;
}
}
kcd->totlinehit = i + 1;
kcd->linehits.resize(i + 1);
}
}
@ -2340,7 +2334,6 @@ static void knife_make_cuts(KnifeTool_OpData *kcd, int ob_index)
*/
static void knife_add_cut(KnifeTool_OpData *kcd)
{
int i;
GHash *facehits;
BMFace *f;
GHashIterator giter;
@ -2362,7 +2355,7 @@ static void knife_add_cut(KnifeTool_OpData *kcd)
kcd->mdata.is_stored = true;
prepare_linehits_for_cut(kcd);
if (kcd->totlinehit == 0) {
if (kcd->linehits.is_empty()) {
if (kcd->is_drag_hold == false) {
kcd->prev = kcd->curr;
}
@ -2370,14 +2363,14 @@ static void knife_add_cut(KnifeTool_OpData *kcd)
}
/* Consider most recent linehit in angle drawing calculations. */
if (kcd->totlinehit >= 2) {
copy_v3_v3(kcd->mdata.cage, kcd->linehits[kcd->totlinehit - 2].cagehit);
if (kcd->linehits.size() >= 2) {
copy_v3_v3(kcd->mdata.cage, kcd->linehits[kcd->linehits.size() - 2].cagehit);
}
/* Make facehits: map face -> list of linehits touching it. */
facehits = BLI_ghash_ptr_new("knife facehits");
for (i = 0; i < kcd->totlinehit; i++) {
KnifeLineHit *lh = &kcd->linehits[i];
for (KnifeLineHit &hit : kcd->linehits) {
KnifeLineHit *lh = &hit;
if (lh->f) {
add_hit_to_facehits(kcd, facehits, lh->f, lh);
}
@ -2408,29 +2401,23 @@ static void knife_add_cut(KnifeTool_OpData *kcd)
if (kcd->prev.bmface) {
/* Was "in face" but now we have a KnifeVert it is snapped to. */
KnifeLineHit *lh = &kcd->linehits[kcd->totlinehit - 1];
KnifeLineHit *lh = &kcd->linehits.last();
kcd->prev.vert = lh->v;
kcd->prev.bmface = nullptr;
}
if (kcd->is_drag_hold) {
KnifeLineHit *lh = &kcd->linehits[kcd->totlinehit - 1];
KnifeLineHit *lh = &kcd->linehits.last();
linehit_to_knifepos(&kcd->prev, lh);
}
BLI_ghash_free(facehits, nullptr, nullptr);
MEM_freeN(kcd->linehits);
kcd->linehits = nullptr;
kcd->totlinehit = 0;
kcd->linehits.clear_and_shrink();
}
static void knife_finish_cut(KnifeTool_OpData *kcd)
{
if (kcd->linehits) {
MEM_freeN(kcd->linehits);
kcd->linehits = nullptr;
kcd->totlinehit = 0;
}
kcd->linehits.clear_and_shrink();
}
/** \} */
@ -2581,10 +2568,10 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
const float(*cagecos)[3] = kcd->objects_info[ob_index].cagecos;
if (cagecos) {
const Span<float3> positions_cage = kcd->objects_info[ob_index].positions_cage;
if (!positions_cage.is_empty()) {
for (int i = 0; i < em->bm->totvert; i++) {
copy_v3_v3(ws, cagecos[i]);
copy_v3_v3(ws, positions_cage[i]);
mul_m4_v3(ob->object_to_world().ptr(), ws);
minmax_v3v3_v3(min, max, ws);
}
@ -2820,8 +2807,6 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
float v1[3], v2[3], v3[3], v4[3], s1[2], s2[2];
int *results, *result;
ListBase *list;
KnifeLineHit *linehits = nullptr;
BLI_array_declare(linehits);
KnifeLineHit hit;
float s[2], se1[2], se2[2];
float d1, d2;
@ -2831,11 +2816,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
uint tot;
int i;
if (kcd->linehits) {
MEM_freeN(kcd->linehits);
kcd->linehits = nullptr;
kcd->totlinehit = 0;
}
kcd->linehits.clear_and_shrink();
copy_v3_v3(v1, kcd->prev.cage);
copy_v3_v3(v2, kcd->curr.cage);
@ -2967,6 +2948,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
/* Assume these tolerances swamp floating point rounding errors in calculations below. */
/* First look for vertex hits. */
Vector<KnifeLineHit> linehits;
for (KnifeVert *v : kfvs) {
KnifeEdge *kfe_hit = nullptr;
@ -2991,7 +2973,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
if (kfv_is_in_cut) {
knife_linehit_set(kcd, s1, s2, s, v->cageco, v->ob_index, v, kfe_hit, &hit);
BLI_array_append(linehits, hit);
linehits.append(hit);
}
else {
/* This vertex isn't used so remove from `kfvs`.
@ -3068,7 +3050,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
}
if (kfe_is_in_cut) {
knife_linehit_set(kcd, s1, s2, p_cage_ss, p_cage, kfe->v1->ob_index, nullptr, kfe, &hit);
BLI_array_append(linehits, hit);
linehits.append(hit);
}
}
@ -3082,19 +3064,18 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
if (use_hit_prev &&
knife_linehit_face_test(kcd, s1, s2, s1, v1, v3, ob_index, f, face_tol_sq, &hit))
{
BLI_array_append(linehits, hit);
linehits.append(hit);
}
if (use_hit_curr &&
knife_linehit_face_test(kcd, s1, s2, s2, v2, v4, ob_index, f, face_tol_sq, &hit))
{
BLI_array_append(linehits, hit);
linehits.append(hit);
}
}
}
kcd->linehits = linehits;
kcd->totlinehit = BLI_array_len(linehits);
kcd->linehits = std::move(linehits);
MEM_freeN(results);
}
@ -3955,28 +3936,20 @@ static void knifetool_init_obinfo(KnifeTool_OpData *kcd,
KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
obinfo->em = em_eval;
obinfo->cagecos = (const float(*)[3])BKE_editmesh_vert_coords_alloc(
kcd->vc.depsgraph, em_eval, scene_eval, obedit_eval, nullptr);
obinfo->positions_cage = BKE_editmesh_vert_coords_alloc(
kcd->vc.depsgraph, em_eval, scene_eval, obedit_eval);
if (use_tri_indices) {
int(*tri_indices)[3] = static_cast<int(*)[3]>(
MEM_mallocN(sizeof(int[3]) * em_eval->looptris.size(), __func__));
obinfo->tri_indices.reinitialize(em_eval->looptris.size());
for (int i = 0; i < em_eval->looptris.size(); i++) {
const std::array<BMLoop *, 3> &ltri = em_eval->looptris[i];
tri_indices[i][0] = BM_elem_index_get(ltri[0]->v);
tri_indices[i][1] = BM_elem_index_get(ltri[1]->v);
tri_indices[i][2] = BM_elem_index_get(ltri[2]->v);
obinfo->tri_indices[i][0] = BM_elem_index_get(ltri[0]->v);
obinfo->tri_indices[i][1] = BM_elem_index_get(ltri[1]->v);
obinfo->tri_indices[i][2] = BM_elem_index_get(ltri[2]->v);
}
obinfo->tri_indices = tri_indices;
}
}
static void knifetool_free_obinfo(KnifeTool_OpData *kcd, int ob_index)
{
MEM_SAFE_FREE(kcd->objects_info[ob_index].cagecos);
MEM_SAFE_FREE(kcd->objects_info[ob_index].tri_indices);
}
/** \} */
/* -------------------------------------------------------------------- */
@ -4032,8 +4005,7 @@ static void knifetool_init(ViewContext *vc,
Object *ob;
BMEditMesh *em;
kcd->objects_info = static_cast<KnifeObjectInfo *>(
MEM_callocN(sizeof(*kcd->objects_info) * kcd->objects.size(), "knife cagecos"));
kcd->objects_info.reinitialize(kcd->objects.size());
for (int ob_index = 0; ob_index < kcd->objects.size(); ob_index++) {
ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
@ -4140,17 +4112,8 @@ static void knifetool_exit_ex(KnifeTool_OpData *kcd)
ED_region_tag_redraw(kcd->region);
/* Knife BVH cleanup. */
for (int i = 0; i < kcd->objects.size(); i++) {
knifetool_free_obinfo(kcd, i);
}
MEM_freeN((void *)kcd->objects_info);
knife_bvh_free(kcd);
/* Line-hits cleanup. */
if (kcd->linehits) {
MEM_freeN(kcd->linehits);
}
/* Destroy kcd itself. */
MEM_delete(kcd);
}
@ -4594,7 +4557,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
knife_update_header(C, op, kcd);
if (kcd->is_drag_hold) {
if (kcd->totlinehit >= 2) {
if (kcd->linehits.size() >= 2) {
knife_add_cut(kcd);
}
}

View File

@ -42,6 +42,9 @@
#include "mesh_intern.hh" /* own include */
using blender::Array;
using blender::float3;
using blender::Span;
using blender::Vector;
#define SUBD_SMOOTH_MAX 4.0f
@ -50,8 +53,9 @@ using blender::Vector;
/* ringsel operator */
struct MeshCoordsCache {
bool is_init, is_alloc;
const float (*coords)[3];
bool is_init;
Array<float3> allocated_vert_positions;
Span<float3> vert_positions;
};
/* struct for properties used while drawing */
@ -67,7 +71,7 @@ struct RingSelOpData {
Vector<Base *> bases;
MeshCoordsCache *geom_cache;
Array<MeshCoordsCache> geom_cache;
/* These values switch objects based on the object under the cursor. */
uint base_index;
@ -138,13 +142,13 @@ static void ringsel_find_edge(RingSelOpData *lcd, const int previewlines)
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(lcd->vc.depsgraph, &lcd->vc.scene->id);
Object *ob_eval = DEG_get_evaluated_object(lcd->vc.depsgraph, lcd->ob);
BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
gcache->coords = BKE_editmesh_vert_coords_when_deformed(
lcd->vc.depsgraph, em_eval, scene_eval, ob_eval, nullptr, &gcache->is_alloc);
gcache->vert_positions = BKE_editmesh_vert_coords_when_deformed(
lcd->vc.depsgraph, em_eval, scene_eval, ob_eval, gcache->allocated_vert_positions);
gcache->is_init = true;
}
EDBM_preselect_edgering_update_from_edge(
lcd->presel_edgering, lcd->em->bm, lcd->eed, previewlines, gcache->coords);
lcd->presel_edgering, lcd->em->bm, lcd->eed, previewlines, gcache->vert_positions);
}
else {
EDBM_preselect_edgering_clear(lcd->presel_edgering);
@ -256,14 +260,6 @@ static void ringsel_exit(bContext * /*C*/, wmOperator *op)
EDBM_preselect_edgering_destroy(lcd->presel_edgering);
for (const int i : lcd->bases.index_range()) {
MeshCoordsCache *gcache = &lcd->geom_cache[i];
if (gcache->is_alloc) {
MEM_freeN((void *)gcache->coords);
}
}
MEM_freeN(lcd->geom_cache);
ED_region_tag_redraw(lcd->region);
MEM_delete(lcd);
@ -428,8 +424,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
RingSelOpData *lcd = static_cast<RingSelOpData *>(op->customdata);
lcd->bases = std::move(bases);
lcd->geom_cache = static_cast<MeshCoordsCache *>(
MEM_callocN(sizeof(*lcd->geom_cache) * lcd->bases.size(), __func__));
lcd->geom_cache.reinitialize(lcd->bases.size());
if (is_interactive) {
copy_v2_v2_int(lcd->vc.mval, event->mval);

View File

@ -22,6 +22,9 @@
#include "UI_resources.hh"
using blender::float3;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Mesh Edge Ring Pre-Select
* Public API:
@ -34,13 +37,15 @@
*
* \{ */
static void edgering_vcos_get(BMVert *v[2][2], float r_cos[2][2][3], const float (*coords)[3])
static void edgering_vcos_get(BMVert *v[2][2],
float r_cos[2][2][3],
const Span<float3> vert_positions)
{
if (coords) {
if (!vert_positions.is_empty()) {
int j, k;
for (j = 0; j < 2; j++) {
for (k = 0; k < 2; k++) {
copy_v3_v3(r_cos[j][k], coords[BM_elem_index_get(v[j][k])]);
copy_v3_v3(r_cos[j][k], vert_positions[BM_elem_index_get(v[j][k])]);
}
}
}
@ -54,12 +59,14 @@ static void edgering_vcos_get(BMVert *v[2][2], float r_cos[2][2][3], const float
}
}
static void edgering_vcos_get_pair(BMVert *v[2], float r_cos[2][3], const float (*coords)[3])
static void edgering_vcos_get_pair(BMVert *v[2],
float r_cos[2][3],
const Span<float3> vert_positions)
{
if (coords) {
if (!vert_positions.is_empty()) {
int j;
for (j = 0; j < 2; j++) {
copy_v3_v3(r_cos[j], coords[BM_elem_index_get(v[j])]);
copy_v3_v3(r_cos[j], vert_positions[BM_elem_index_get(v[j])]);
}
}
else {
@ -204,11 +211,12 @@ void EDBM_preselect_edgering_draw(EditMesh_PreSelEdgeRing *psel, const float mat
GPU_blend(GPU_BLEND_NONE);
}
static void view3d_preselect_mesh_edgering_update_verts_from_edge(EditMesh_PreSelEdgeRing *psel,
BMesh * /*bm*/,
BMEdge *eed_start,
int previewlines,
const float (*coords)[3])
static void view3d_preselect_mesh_edgering_update_verts_from_edge(
EditMesh_PreSelEdgeRing *psel,
BMesh * /*bm*/,
BMEdge *eed_start,
int previewlines,
const Span<float3> vert_positions)
{
float v_cos[2][3];
float(*verts)[3];
@ -216,7 +224,7 @@ static void view3d_preselect_mesh_edgering_update_verts_from_edge(EditMesh_PreSe
verts = static_cast<float(*)[3]>(MEM_mallocN(sizeof(*psel->verts) * previewlines, __func__));
edgering_vcos_get_pair(&eed_start->v1, v_cos, coords);
edgering_vcos_get_pair(&eed_start->v1, v_cos, vert_positions);
for (i = 1; i <= previewlines; i++) {
const float fac = (i / (float(previewlines) + 1));
@ -228,11 +236,12 @@ static void view3d_preselect_mesh_edgering_update_verts_from_edge(EditMesh_PreSe
psel->verts_len = previewlines;
}
static void view3d_preselect_mesh_edgering_update_edges_from_edge(EditMesh_PreSelEdgeRing *psel,
BMesh *bm,
BMEdge *eed_start,
int previewlines,
const float (*coords)[3])
static void view3d_preselect_mesh_edgering_update_edges_from_edge(
EditMesh_PreSelEdgeRing *psel,
BMesh *bm,
BMEdge *eed_start,
int previewlines,
const Span<float3> vert_positions)
{
BMWalker walker;
BMEdge *eed, *eed_last;
@ -291,7 +300,7 @@ static void view3d_preselect_mesh_edgering_update_edges_from_edge(EditMesh_PreSe
const float fac = (i / (float(previewlines) + 1));
float v_cos[2][2][3];
edgering_vcos_get(v, v_cos, coords);
edgering_vcos_get(v, v_cos, vert_positions);
interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
@ -322,7 +331,7 @@ static void view3d_preselect_mesh_edgering_update_edges_from_edge(EditMesh_PreSe
continue;
}
edgering_vcos_get(v, v_cos, coords);
edgering_vcos_get(v, v_cos, vert_positions);
interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
@ -340,21 +349,21 @@ void EDBM_preselect_edgering_update_from_edge(EditMesh_PreSelEdgeRing *psel,
BMesh *bm,
BMEdge *eed_start,
int previewlines,
const float (*coords)[3])
const Span<float3> vert_positions)
{
EDBM_preselect_edgering_clear(psel);
if (coords) {
if (!vert_positions.is_empty()) {
BM_mesh_elem_index_ensure(bm, BM_VERT);
}
if (BM_edge_is_any_face_len_test(eed_start, 4)) {
view3d_preselect_mesh_edgering_update_edges_from_edge(
psel, bm, eed_start, previewlines, coords);
psel, bm, eed_start, previewlines, vert_positions);
}
else {
view3d_preselect_mesh_edgering_update_verts_from_edge(
psel, bm, eed_start, previewlines, coords);
psel, bm, eed_start, previewlines, vert_positions);
}
}

View File

@ -21,6 +21,9 @@
#include "ED_mesh.hh"
#include "ED_view3d.hh"
using blender::float3;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Mesh Element Pre-Select
* Public API:
@ -33,21 +36,21 @@
*
* \{ */
static void vcos_get(BMVert *v, float r_co[3], const float (*coords)[3])
static void vcos_get(BMVert *v, float r_co[3], const Span<float3> vert_positions)
{
if (coords) {
copy_v3_v3(r_co, coords[BM_elem_index_get(v)]);
if (!vert_positions.is_empty()) {
copy_v3_v3(r_co, vert_positions[BM_elem_index_get(v)]);
}
else {
copy_v3_v3(r_co, v->co);
}
}
static void vcos_get_pair(BMVert *v[2], float r_cos[2][3], const float (*coords)[3])
static void vcos_get_pair(BMVert *v[2], float r_cos[2][3], const Span<float3> vert_positions)
{
if (coords) {
if (!vert_positions.is_empty()) {
for (int j = 0; j < 2; j++) {
copy_v3_v3(r_cos[j], coords[BM_elem_index_get(v[j])]);
copy_v3_v3(r_cos[j], vert_positions[BM_elem_index_get(v[j])]);
}
}
else {
@ -198,10 +201,10 @@ void EDBM_preselect_elem_draw(EditMesh_PreSelElem *psel, const float matrix[4][4
static void view3d_preselect_mesh_elem_update_from_vert(EditMesh_PreSelElem *psel,
BMesh * /*bm*/,
BMVert *eve,
const float (*coords)[3])
const Span<float3> vert_positions)
{
float(*verts)[3] = static_cast<float(*)[3]>(MEM_mallocN(sizeof(*psel->verts), __func__));
vcos_get(eve, verts[0], coords);
vcos_get(eve, verts[0], vert_positions);
psel->verts = verts;
psel->verts_len = 1;
}
@ -209,10 +212,10 @@ static void view3d_preselect_mesh_elem_update_from_vert(EditMesh_PreSelElem *pse
static void view3d_preselect_mesh_elem_update_from_edge(EditMesh_PreSelElem *psel,
BMesh * /*bm*/,
BMEdge *eed,
const float (*coords)[3])
const Span<float3> vert_positions)
{
float(*edges)[2][3] = static_cast<float(*)[2][3]>(MEM_mallocN(sizeof(*psel->edges), __func__));
vcos_get_pair(&eed->v1, edges[0], coords);
vcos_get_pair(&eed->v1, edges[0], vert_positions);
psel->edges = edges;
psel->edges_len = 1;
}
@ -298,7 +301,7 @@ static void view3d_preselect_update_preview_triangle_from_face(EditMesh_PreSelEl
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
int i = 0;
do {
vcos_get_pair(&l_iter->e->v1, preview_lines[i++], nullptr);
vcos_get_pair(&l_iter->e->v1, preview_lines[i++], {});
} while ((l_iter = l_iter->next) != l_first);
psel->preview_lines = preview_lines;
psel->preview_lines_len = efa->len;
@ -336,7 +339,7 @@ static void view3d_preselect_update_preview_triangle_from_edge(
static void view3d_preselect_mesh_elem_update_from_face(EditMesh_PreSelElem *psel,
BMesh * /*bm*/,
BMFace *efa,
const float (*coords)[3])
const Span<float3> vert_positions)
{
float(*edges)[2][3] = static_cast<float(*)[2][3]>(
MEM_mallocN(sizeof(*psel->edges) * efa->len, __func__));
@ -344,7 +347,7 @@ static void view3d_preselect_mesh_elem_update_from_face(EditMesh_PreSelElem *pse
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
int i = 0;
do {
vcos_get_pair(&l_iter->e->v1, edges[i++], coords);
vcos_get_pair(&l_iter->e->v1, edges[i++], vert_positions);
} while ((l_iter = l_iter->next) != l_first);
psel->edges = edges;
psel->edges_len = efa->len;
@ -353,23 +356,23 @@ static void view3d_preselect_mesh_elem_update_from_face(EditMesh_PreSelElem *pse
void EDBM_preselect_elem_update_from_single(EditMesh_PreSelElem *psel,
BMesh *bm,
BMElem *ele,
const float (*coords)[3])
const Span<float3> vert_positions)
{
EDBM_preselect_elem_clear(psel);
if (coords) {
if (!vert_positions.is_empty()) {
BM_mesh_elem_index_ensure(bm, BM_VERT);
}
switch (ele->head.htype) {
case BM_VERT:
view3d_preselect_mesh_elem_update_from_vert(psel, bm, (BMVert *)ele, coords);
view3d_preselect_mesh_elem_update_from_vert(psel, bm, (BMVert *)ele, vert_positions);
break;
case BM_EDGE:
view3d_preselect_mesh_elem_update_from_edge(psel, bm, (BMEdge *)ele, coords);
view3d_preselect_mesh_elem_update_from_edge(psel, bm, (BMEdge *)ele, vert_positions);
break;
case BM_FACE:
view3d_preselect_mesh_elem_update_from_face(psel, bm, (BMFace *)ele, coords);
view3d_preselect_mesh_elem_update_from_face(psel, bm, (BMFace *)ele, vert_positions);
break;
default:
BLI_assert(0);

View File

@ -69,6 +69,7 @@
/* use bmesh operator flags for a few operators */
#define BMO_ELE_TAG 1
using blender::float3;
using blender::Span;
using blender::Vector;
@ -1079,16 +1080,16 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
copy_m3_m4(imat3, obedit->object_to_world().ptr());
invert_m3(imat3);
const float(*coords)[3] = nullptr;
Span<float3> vert_positions;
{
Object *obedit_eval = DEG_get_evaluated_object(vc->depsgraph, obedit);
Mesh *mesh_eval = BKE_object_get_editmesh_eval_cage(obedit_eval);
const Object *obedit_eval = DEG_get_evaluated_object(vc->depsgraph, obedit);
const Mesh *mesh_eval = BKE_object_get_editmesh_eval_cage(obedit_eval);
if (BKE_mesh_wrapper_vert_len(mesh_eval) == bm->totvert) {
coords = BKE_mesh_wrapper_vert_coords(mesh_eval);
vert_positions = BKE_mesh_wrapper_vert_coords(mesh_eval);
}
}
if (coords != nullptr) {
if (!vert_positions.is_empty()) {
BM_mesh_elem_index_ensure(bm, BM_VERT);
}
@ -1103,7 +1104,8 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
float point[3];
mul_v3_m4v3(point,
obedit->object_to_world().ptr(),
coords ? coords[BM_elem_index_get(v)] : v->co);
!vert_positions.is_empty() ? vert_positions[BM_elem_index_get(v)] :
v->co);
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
ray_origin, ray_direction, point);
if (dist_sq_test < dist_sq_best_vert) {
@ -1125,9 +1127,10 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
const float dist_sq_test = dist_squared_ray_to_seg_v3(
ray_origin, ray_direction, e->v1->co, e->v2->co, point, &depth);
#else
if (coords) {
mid_v3_v3v3(
point, coords[BM_elem_index_get(e->v1)], coords[BM_elem_index_get(e->v2)]);
if (!vert_positions.is_empty()) {
mid_v3_v3v3(point,
vert_positions[BM_elem_index_get(e->v1)],
vert_positions[BM_elem_index_get(e->v2)]);
}
else {
mid_v3_v3v3(point, e->v1->co, e->v2->co);
@ -1159,7 +1162,7 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
float point[3];
mul_v3_m4v3(point,
obedit->object_to_world().ptr(),
coords ? coords[BM_elem_index_get(v)] : v->co);
!vert_positions.is_empty() ? vert_positions[BM_elem_index_get(v)] : v->co);
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
ray_origin, ray_direction, point);
if (dist_sq_test < dist_sq_best_vert) {
@ -1182,9 +1185,10 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) {
float point[3];
if (coords) {
mid_v3_v3v3(
point, coords[BM_elem_index_get(e->v1)], coords[BM_elem_index_get(e->v2)]);
if (!vert_positions.is_empty()) {
mid_v3_v3v3(point,
vert_positions[BM_elem_index_get(e->v1)],
vert_positions[BM_elem_index_get(e->v2)]);
}
else {
mid_v3_v3v3(point, e->v1->co, e->v2->co);
@ -1212,8 +1216,8 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN) == false) {
float point[3];
if (coords) {
BM_face_calc_center_median_vcos(bm, f, point, coords);
if (!vert_positions.is_empty()) {
BM_face_calc_center_median_vcos(bm, f, point, vert_positions);
}
else {
BM_face_calc_center_median(f, point);

View File

@ -324,7 +324,8 @@ XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode)
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
BM_mesh_vert_coords_get(bm, xod->elem_array);
BM_mesh_vert_coords_get(
bm, MutableSpan(reinterpret_cast<float3 *>(xod->elem_array), elem_array_len));
xod_base = &xod->base;
if (key != nullptr) {

View File

@ -288,20 +288,6 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
#undef INDEX_UNSET
}
static int vertex_parent_set_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (RNA_boolean_get(op->ptr, "confirm")) {
return WM_operator_confirm_ex(C,
op,
IFACE_("Parent selected objects to the selected vertices?"),
nullptr,
IFACE_("Parent"),
ALERT_ICON_NONE,
false);
}
return vertex_parent_set_exec(C, op);
}
void OBJECT_OT_vertex_parent_set(wmOperatorType *ot)
{
/* identifiers */
@ -310,13 +296,11 @@ void OBJECT_OT_vertex_parent_set(wmOperatorType *ot)
ot->idname = "OBJECT_OT_vertex_parent_set";
/* api callbacks */
ot->invoke = vertex_parent_set_invoke;
ot->poll = vertex_parent_set_poll;
ot->exec = vertex_parent_set_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
WM_operator_properties_confirm_or_exec(ot);
}
/** \} */
@ -1120,20 +1104,6 @@ static int parent_noinv_set_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int parent_noinv_set_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (RNA_boolean_get(op->ptr, "confirm")) {
return WM_operator_confirm_ex(C,
op,
IFACE_("Make Parent without inverse correction?"),
nullptr,
IFACE_("Parent"),
ALERT_ICON_NONE,
false);
}
return parent_noinv_set_exec(C, op);
}
void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot)
{
/* identifiers */
@ -1142,13 +1112,11 @@ void OBJECT_OT_parent_no_inverse_set(wmOperatorType *ot)
ot->idname = "OBJECT_OT_parent_no_inverse_set";
/* api callbacks */
ot->invoke = parent_noinv_set_invoke;
ot->exec = parent_noinv_set_exec;
ot->poll = ED_operator_object_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
WM_operator_properties_confirm_or_exec(ot);
RNA_def_boolean(ot->srna,
"keep_transform",

View File

@ -478,9 +478,8 @@ static int shape_key_clear_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = context_object(C);
Key *key = BKE_key_from_object(ob);
KeyBlock *kb = BKE_keyblock_from_object(ob);
if (!key || !kb) {
if (!key || BLI_listbase_is_empty(&key->block)) {
return OPERATOR_CANCELLED;
}
@ -514,10 +513,9 @@ static int shape_key_retime_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = context_object(C);
Key *key = BKE_key_from_object(ob);
KeyBlock *kb = BKE_keyblock_from_object(ob);
float cfra = 0.0f;
if (!key || !kb) {
if (!key || BLI_listbase_is_empty(&key->block)) {
return OPERATOR_CANCELLED;
}

View File

@ -866,6 +866,17 @@ static int hide_show_gesture_lasso_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int hide_show_gesture_line_exec(bContext *C, wmOperator *op)
{
std::unique_ptr<gesture::GestureData> gesture_data = gesture::init_from_line(C, op);
if (!gesture_data) {
return OPERATOR_CANCELLED;
}
hide_show_init_properties(*C, *gesture_data, *op);
gesture::apply(*C, *gesture_data, *op);
return OPERATOR_FINISHED;
}
static void hide_show_operator_gesture_properties(wmOperatorType *ot)
{
static const EnumPropertyItem area_items[] = {
@ -930,6 +941,26 @@ void PAINT_OT_hide_show_lasso_gesture(wmOperatorType *ot)
gesture::operator_properties(ot, gesture::ShapeType::Lasso);
}
void PAINT_OT_hide_show_line_gesture(wmOperatorType *ot)
{
ot->name = "Hide/Show Line";
ot->idname = "PAINT_OT_hide_show_line_gesture";
ot->description = "Hide/show some vertices";
ot->invoke = WM_gesture_straightline_active_side_invoke;
ot->modal = WM_gesture_straightline_oneshot_modal;
ot->exec = hide_show_gesture_line_exec;
/* Sculpt-only for now. */
ot->poll = SCULPT_mode_poll_view3d;
ot->flag = OPTYPE_REGISTER;
WM_operator_properties_gesture_straightline(ot, WM_CURSOR_EDIT);
hide_show_operator_properties(ot);
hide_show_operator_gesture_properties(ot);
gesture::operator_properties(ot, gesture::ShapeType::Line);
}
/** \} */
} // namespace blender::ed::sculpt_paint::hide

View File

@ -471,6 +471,7 @@ void PAINT_OT_hide_show_masked(wmOperatorType *ot);
void PAINT_OT_hide_show_all(wmOperatorType *ot);
void PAINT_OT_hide_show(wmOperatorType *ot);
void PAINT_OT_hide_show_lasso_gesture(wmOperatorType *ot);
void PAINT_OT_hide_show_line_gesture(wmOperatorType *ot);
void PAINT_OT_visibility_invert(wmOperatorType *ot);
} // namespace blender::ed::sculpt_paint::hide

View File

@ -1551,6 +1551,7 @@ void ED_operatortypes_paint()
WM_operatortype_append(hide::PAINT_OT_hide_show_masked);
WM_operatortype_append(hide::PAINT_OT_hide_show);
WM_operatortype_append(hide::PAINT_OT_hide_show_lasso_gesture);
WM_operatortype_append(hide::PAINT_OT_hide_show_line_gesture);
WM_operatortype_append(hide::PAINT_OT_visibility_invert);
/* paint masking */

View File

@ -2698,15 +2698,6 @@ static int file_directory_new_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static int file_directory_new_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (RNA_boolean_get(op->ptr, "confirm")) {
return WM_operator_confirm_ex(
C, op, IFACE_("Create new directory?"), nullptr, IFACE_("Create"), ALERT_ICON_NONE, false);
}
return file_directory_new_exec(C, op);
}
void FILE_OT_directory_new(wmOperatorType *ot)
{
PropertyRNA *prop;
@ -2717,7 +2708,6 @@ void FILE_OT_directory_new(wmOperatorType *ot)
ot->idname = "FILE_OT_directory_new";
/* api callbacks */
ot->invoke = file_directory_new_invoke;
ot->exec = file_directory_new_exec;
/* File browsing only operator (not asset browsing). */
ot->poll = ED_operator_file_browsing_active; /* <- important, handler is on window level */
@ -2727,7 +2717,6 @@ void FILE_OT_directory_new(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "open", false, "Open", "Open new directory");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
WM_operator_properties_confirm_or_exec(ot);
}
/** \} */

View File

@ -460,33 +460,32 @@ static void outliner_id_remap(ScrArea *area,
static void outliner_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
{
SpaceOutliner *space_outliner = reinterpret_cast<SpaceOutliner *>(space_link);
if (!space_outliner->treestore) {
return;
}
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
const bool allow_pointer_access = (data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0;
if (space_outliner->treestore != nullptr) {
TreeStoreElem *tselem;
BLI_mempool_iter iter;
BLI_mempool_iternew(space_outliner->treestore, &iter);
while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
/* Do not try to restore non-ID pointers (drivers/sequence/etc.). */
if (TSE_IS_REAL_ID(tselem)) {
const int cb_flag = (tselem->id != nullptr && allow_pointer_access &&
(tselem->id->flag & LIB_EMBEDDED_DATA) != 0) ?
IDWALK_CB_EMBEDDED_NOT_OWNING :
IDWALK_CB_NOP;
BKE_LIB_FOREACHID_PROCESS_ID(data, tselem->id, cb_flag);
}
else if (!is_readonly) {
tselem->id = nullptr;
}
BLI_mempool_iter iter;
BLI_mempool_iternew(space_outliner->treestore, &iter);
while (TreeStoreElem *tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter))) {
/* Do not try to restore non-ID pointers (drivers/sequence/etc.). */
if (TSE_IS_REAL_ID(tselem)) {
const int cb_flag = (tselem->id != nullptr && allow_pointer_access &&
(tselem->id->flag & LIB_EMBEDDED_DATA) != 0) ?
IDWALK_CB_EMBEDDED_NOT_OWNING :
IDWALK_CB_NOP;
BKE_LIB_FOREACHID_PROCESS_ID(data, tselem->id, cb_flag);
}
if (!is_readonly) {
/* rebuild hash table, because it depends on ids too */
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
else if (!is_readonly) {
tselem->id = nullptr;
}
}
if (!is_readonly) {
/* rebuild hash table, because it depends on ids too */
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
}
}
static void outliner_deactivate(ScrArea *area)

View File

@ -903,7 +903,7 @@ void ED_view3d_cursor3d_position_rotation(bContext *C,
SnapObjectContext *snap_context = ED_transform_snap_object_context_create(scene, 0);
float obmat[4][4];
Object *ob_dummy = nullptr;
const Object *ob_dummy = nullptr;
float dist_px = 0;
SnapObjectParams params{};
params.snap_target_select = SCE_SNAP_TARGET_ALL;

View File

@ -44,6 +44,9 @@
#include "ED_screen.hh"
#include "ED_view3d.hh"
using blender::Array;
using blender::float3;
using blender::Span;
using blender::Vector;
/* -------------------------------------------------------------------- */
@ -236,17 +239,17 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
}
if (best.ele) {
const float(*coords)[3] = nullptr;
Span<float3> vert_positions;
{
Object *ob = gz_ele->bases[gz_ele->base_index]->object;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *mesh_eval = BKE_object_get_editmesh_eval_cage(ob_eval);
const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
const Mesh *mesh_eval = BKE_object_get_editmesh_eval_cage(ob_eval);
if (BKE_mesh_wrapper_vert_len(mesh_eval) == bm->totvert) {
coords = BKE_mesh_wrapper_vert_coords(mesh_eval);
vert_positions = BKE_mesh_wrapper_vert_coords(mesh_eval);
}
}
EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, vert_positions);
EDBM_preselect_elem_update_preview(gz_ele->psel, &vc, bm, best.ele, mval);
}
else {
@ -406,13 +409,10 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
/* Re-allocate coords each update isn't ideal, however we can't be sure
* the mesh hasn't been edited since last update. */
bool is_alloc = false;
const float(*coords)[3] = BKE_editmesh_vert_coords_when_deformed(
vc.depsgraph, em_eval, scene_eval, ob_eval, nullptr, &is_alloc);
EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords);
if (is_alloc) {
MEM_freeN((void *)coords);
}
Array<float3> storage;
const Span<float3> vert_positions = BKE_editmesh_vert_coords_when_deformed(
vc.depsgraph, em_eval, scene_eval, ob_eval, storage);
EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, vert_positions);
}
else {
EDBM_preselect_edgering_clear(gz_ring->psel);

View File

@ -291,7 +291,7 @@ eSnapMode SnapData::snap_edge_points_impl(SnapObjectContext *sctx,
}
void SnapData::register_result(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id_eval,
const float4x4 &obmat,
BVHTreeNearest *r_nearest)
@ -316,13 +316,13 @@ void SnapData::register_result(SnapObjectContext *sctx,
#endif
}
void SnapData::register_result(SnapObjectContext *sctx, Object *ob_eval, const ID *id_eval)
void SnapData::register_result(SnapObjectContext *sctx, const Object *ob_eval, const ID *id_eval)
{
this->register_result(sctx, ob_eval, id_eval, this->obmat_, &this->nearest_point);
}
void SnapData::register_result_raycast(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id_eval,
const blender::float4x4 &obmat,
const BVHTreeRayHit *hit,
@ -368,17 +368,17 @@ static ID *data_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_
switch (ob_eval->type) {
case OB_MESH: {
Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
if (BKE_object_is_in_editmode(ob_eval)) {
if (edit_mode_type == SNAP_GEOM_EDIT) {
return nullptr;
}
Mesh *editmesh_eval = (edit_mode_type == SNAP_GEOM_FINAL) ?
BKE_object_get_editmesh_eval_final(ob_eval) :
(edit_mode_type == SNAP_GEOM_CAGE) ?
BKE_object_get_editmesh_eval_cage(ob_eval) :
nullptr;
const Mesh *editmesh_eval = (edit_mode_type == SNAP_GEOM_FINAL) ?
BKE_object_get_editmesh_eval_final(ob_eval) :
(edit_mode_type == SNAP_GEOM_CAGE) ?
BKE_object_get_editmesh_eval_cage(ob_eval) :
nullptr;
if (editmesh_eval) {
if (editmesh_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
@ -409,8 +409,8 @@ static ID *data_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_
* \{ */
using IterSnapObjsCallback = eSnapMode (*)(SnapObjectContext *sctx,
Object *ob_eval,
ID *ob_data,
const Object *ob_eval,
const ID *ob_data,
const float4x4 &obmat,
bool is_object_active,
bool use_hide);
@ -588,8 +588,8 @@ bool raycast_tri_backface_culling_test(
* \note Duplicate args here are documented at #snapObjectsRay.
*/
static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
Object *ob_eval,
ID *ob_data,
const Object *ob_eval,
const ID *ob_data,
const float4x4 &obmat,
bool is_object_active,
bool use_hide)
@ -726,8 +726,8 @@ bool nearest_world_tree(SnapObjectContext *sctx,
}
static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
Object *ob_eval,
ID *ob_data,
const Object *ob_eval,
const ID *ob_data,
const float4x4 &obmat,
bool is_object_active,
bool use_hide)
@ -849,7 +849,7 @@ static eSnapMode snap_edge_points(SnapObjectContext *sctx, const float dist_px_s
/* May extend later (for now just snaps to empty or camera center). */
eSnapMode snap_object_center(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const float4x4 &obmat,
eSnapMode snap_to_flag)
{
@ -878,8 +878,8 @@ eSnapMode snap_object_center(SnapObjectContext *sctx,
* \note Duplicate args here are documented at #snapObjectsRay.
*/
static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
Object *ob_eval,
ID *ob_data,
const Object *ob_eval,
const ID *ob_data,
const float4x4 &obmat,
bool is_object_active,
bool use_hide)
@ -1184,7 +1184,7 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
float r_loc[3],
float r_no[3],
int *r_index,
Object **r_ob,
const Object **r_ob,
float r_obmat[4][4])
{
if (!snap_object_context_runtime_init(sctx,
@ -1311,7 +1311,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
float r_loc[3],
float r_no[3],
int *r_index,
Object **r_ob,
const Object **r_ob,
float r_obmat[4][4],
float r_face_nor[3])
{

View File

@ -85,7 +85,7 @@ struct SnapObjectContext {
/* List of #SnapObjectHitDepth (caller must free). */
ListBase *hit_list;
/* Snapped object. */
Object *ob;
const Object *ob;
/* Snapped data. */
const ID *data;
@ -141,13 +141,13 @@ class SnapData {
bool snap_edge(const blender::float3 &va, const blender::float3 &vb, int edge_index = -1);
eSnapMode snap_edge_points_impl(SnapObjectContext *sctx, int edge_index, float dist_px_sq_orig);
static void register_result(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id_eval,
const blender::float4x4 &obmat,
BVHTreeNearest *r_nearest);
void register_result(SnapObjectContext *sctx, Object *ob_eval, const ID *id_eval);
void register_result(SnapObjectContext *sctx, const Object *ob_eval, const ID *id_eval);
static void register_result_raycast(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id_eval,
const blender::float4x4 &obmat,
const BVHTreeRayHit *hit,
@ -187,32 +187,34 @@ bool nearest_world_tree(SnapObjectContext *sctx,
BVHTreeNearest *r_nearest);
eSnapMode snap_object_center(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const blender::float4x4 &obmat,
eSnapMode snap_to_flag);
/* `transform_snap_object_armature.cc` */
eSnapMode snapArmature(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const blender::float4x4 &obmat,
bool is_object_active);
/* `transform_snap_object_camera.cc` */
eSnapMode snapCamera(SnapObjectContext *sctx,
Object *object,
const Object *object,
const blender::float4x4 &obmat,
eSnapMode snap_to_flag);
/* `transform_snap_object_curve.cc` */
eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const blender::float4x4 &obmat);
eSnapMode snapCurve(SnapObjectContext *sctx,
const Object *ob_eval,
const blender::float4x4 &obmat);
/* `transform_snap_object_editmesh.cc` */
eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id,
const blender::float4x4 &obmat,
eSnapMode snap_to_flag,
@ -221,21 +223,21 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
/* `transform_snap_object_mesh.cc` */
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id,
const blender::float4x4 &obmat,
eSnapMode snap_to_flag,
bool use_hide);
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id,
const blender::float4x4 &obmat,
eSnapMode snap_to_flag,
int face);
eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id,
const blender::float4x4 &obmat,
float dist_px_sq_orig,

View File

@ -21,7 +21,7 @@
using blender::float4x4;
eSnapMode snapArmature(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const float4x4 &obmat,
bool is_object_active)
{

View File

@ -19,7 +19,7 @@
using namespace blender;
eSnapMode snapCamera(SnapObjectContext *sctx,
Object *object,
const Object *object,
const float4x4 &obmat,
eSnapMode snap_to_flag)
{

View File

@ -21,7 +21,7 @@
using blender::float4x4;
using blender::IndexRange;
eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float4x4 &obmat)
eSnapMode snapCurve(SnapObjectContext *sctx, const Object *ob_eval, const float4x4 &obmat)
{
bool has_snap = false;

View File

@ -26,17 +26,17 @@ using namespace blender;
/** \name Snap Object Data
* \{ */
static Mesh *get_mesh_ref(Object *ob_eval)
static const Mesh *get_mesh_ref(const Object *ob_eval)
{
if (Mesh *me = BKE_object_get_editmesh_eval_final(ob_eval)) {
if (const Mesh *me = BKE_object_get_editmesh_eval_final(ob_eval)) {
return me;
}
if (Mesh *me = BKE_object_get_editmesh_eval_cage(ob_eval)) {
if (const Mesh *me = BKE_object_get_editmesh_eval_cage(ob_eval)) {
return me;
}
return static_cast<Mesh *>(ob_eval->data);
return static_cast<const Mesh *>(ob_eval->data);
}
struct SnapCache_EditMesh : public SnapObjectContext::SnapCache {
@ -44,11 +44,11 @@ struct SnapCache_EditMesh : public SnapObjectContext::SnapCache {
Mesh *mesh;
/* Reference to pointers that change when the mesh is changed. It is used to detect updates. */
Mesh *mesh_ref;
const Mesh *mesh_ref;
bke::MeshRuntime *runtime_ref;
bke::EditMeshData *edit_data_ref;
bool has_mesh_updated(Mesh *mesh)
bool has_mesh_updated(const Mesh *mesh)
{
if (mesh != this->mesh_ref || mesh->runtime != this->runtime_ref ||
mesh->runtime->edit_data.get() != this->edit_data_ref)
@ -77,11 +77,11 @@ struct SnapCache_EditMesh : public SnapObjectContext::SnapCache {
};
static Mesh *create_mesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
eSnapEditType /*edit_mode_type*/)
{
Mesh *mesh = static_cast<Mesh *>(BKE_id_new_nomain(ID_ME, nullptr));
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
const BMEditMesh *em = BKE_editmesh_from_object(const_cast<Object *>(ob_eval));
BMesh *bm = em->bm;
BM_mesh_bm_to_me_compact(*bm, *mesh, nullptr, false);
@ -148,17 +148,17 @@ static Mesh *create_mesh(SnapObjectContext *sctx,
}
static SnapCache_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
bool create)
{
SnapCache_EditMesh *em_cache = nullptr;
bool init = false;
Mesh *mesh_ref = (G.moving) ? /* WORKAROUND:
* Avoid updating while transforming. Do not check if the reference
* mesh has been updated. */
nullptr :
get_mesh_ref(ob_eval);
const Mesh *mesh_ref = (G.moving) ? /* WORKAROUND:
* Avoid updating while transforming. Do not check if the
* reference mesh has been updated. */
nullptr :
get_mesh_ref(ob_eval);
if (std::unique_ptr<SnapObjectContext::SnapCache> *em_cache_p = sctx->editmesh_caches.lookup_ptr(
ob_eval->runtime->data_orig))
@ -213,10 +213,10 @@ static eSnapMode editmesh_snap_mode_supported(BMesh *bm)
}
static SnapCache_EditMesh *editmesh_snapdata_init(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
eSnapMode snap_to_flag)
{
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
const BMEditMesh *em = BKE_editmesh_from_object(const_cast<Object *>(ob_eval));
if (em == nullptr) {
return nullptr;
}
@ -237,7 +237,7 @@ static SnapCache_EditMesh *editmesh_snapdata_init(SnapObjectContext *sctx,
/** \} */
eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID * /*id*/,
const float4x4 &obmat,
eSnapMode snap_to_flag,

View File

@ -77,7 +77,7 @@ static void mesh_corner_tris_raycast_backface_culling_cb(void *userdata,
}
static bool raycastMesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const Mesh *mesh_eval,
const float4x4 &obmat,
const uint ob_index,
@ -106,12 +106,13 @@ static bool raycastMesh(SnapObjectContext *sctx,
}
/* Test bounding box. */
const Bounds<float3> bounds = *mesh_eval->bounds_min_max();
/* Was #BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
if (!isect_ray_aabb_v3_simple(
ray_start_local, ray_normal_local, bounds.min, bounds.max, &len_diff, nullptr))
{
return retval;
if (std::optional<Bounds<float3>> bounds = mesh_eval->bounds_min_max()) {
/* Was #BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
if (!isect_ray_aabb_v3_simple(
ray_start_local, ray_normal_local, bounds->min, bounds->max, &len_diff, nullptr))
{
return retval;
}
}
/* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with
@ -189,7 +190,7 @@ static bool raycastMesh(SnapObjectContext *sctx,
* \{ */
static bool nearest_world_mesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const Mesh *mesh_eval,
const float4x4 &obmat,
bool use_hide)
@ -354,7 +355,7 @@ static void cb_snap_tri_edges(void *userdata,
* \{ */
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id,
const float4x4 &obmat,
eSnapMode snap_to_flag,
@ -409,7 +410,7 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
}
eSnapMode snap_edge_points_mesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id,
const float4x4 &obmat,
float dist_pex_sq_orig,
@ -437,7 +438,7 @@ static eSnapMode mesh_snap_mode_supported(const Mesh *mesh)
}
static eSnapMode snapMesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const Mesh *mesh_eval,
const float4x4 &obmat,
bool use_hide,
@ -578,7 +579,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
/** \} */
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
Object *ob_eval,
const Object *ob_eval,
const ID *id,
const float4x4 &obmat,
eSnapMode snap_to_flag,

View File

@ -306,7 +306,7 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit,
}
if (mode & TM_CALC_MAPLOC) {
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(obedit);
const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(obedit);
if (tvs->transverts && editmesh_eval_cage) {
BM_mesh_elem_table_ensure(bm, BM_VERT);
BKE_mesh_foreach_mapped_vert(

View File

@ -742,7 +742,7 @@ static bool rna_Object_is_deform_modified(Object *ob, Scene *scene, int settings
void rna_Object_me_eval_info(
Object *ob, bContext *C, int type, PointerRNA *rnaptr_depsgraph, char *result)
{
Mesh *mesh_eval = nullptr;
const Mesh *mesh_eval = nullptr;
char *ret = nullptr;
result[0] = '\0';
@ -762,7 +762,7 @@ void rna_Object_me_eval_info(
}
break;
case 1:
mesh_eval = ob->runtime->mesh_deform_eval;
mesh_eval = BKE_object_get_mesh_deform_eval(ob);
break;
case 2:
mesh_eval = BKE_object_get_evaluated_mesh(ob);

View File

@ -157,7 +157,7 @@ static void rna_Scene_ray_cast(Scene *scene,
r_location,
r_normal,
r_index,
r_ob,
(const Object **)(r_ob),
(float(*)[4])r_obmat);
ED_transform_snap_object_context_destroy(sctx);

View File

@ -506,13 +506,11 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd,
Mesh *mesh,
const MDeformVert *dvert,
const int defgrp_index,
const float (*rest_coords)[3],
uint verts_num)
const blender::Span<blender::float3> rest_coords)
{
const blender::Span<int> corner_verts = mesh->corner_verts();
blender::Array<blender::float3> smooth_vertex_coords(
blender::Span(reinterpret_cast<const blender::float3 *>(rest_coords), verts_num));
blender::Array<blender::float3> smooth_vertex_coords(rest_coords);
uint l_index;
@ -644,43 +642,37 @@ static void correctivesmooth_modifier_do(ModifierData *md,
if (!csmd->delta_cache.deltas || (csmd->delta_cache.deltas_num != corner_verts.size()) ||
force_delta_cache_update)
{
const float(*rest_coords)[3];
bool is_rest_coords_alloc = false;
blender::Array<blender::float3> rest_coords_alloc;
blender::Span<blender::float3> rest_coords;
store_cache_settings(csmd);
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
/* caller needs to do sanity check here */
csmd->bind_coords_num = uint(vertexCos.size());
rest_coords = csmd->bind_coords;
rest_coords = {reinterpret_cast<const blender::float3 *>(csmd->bind_coords),
csmd->bind_coords_num};
}
else {
int me_numVerts;
if (em) {
rest_coords = BKE_editmesh_vert_coords_alloc_orco(em, &me_numVerts);
is_rest_coords_alloc = true;
rest_coords_alloc = BKE_editmesh_vert_coords_alloc_orco(em);
rest_coords = rest_coords_alloc;
}
else {
const Mesh *object_mesh = static_cast<const Mesh *>(ob->data);
rest_coords = reinterpret_cast<const float(*)[3]>(object_mesh->vert_positions().data());
me_numVerts = object_mesh->verts_num;
rest_coords = object_mesh->vert_positions();
}
BLI_assert(me_numVerts == int(vertexCos.size()));
}
#ifdef DEBUG_TIME
TIMEIT_START(corrective_smooth_deltas);
#endif
calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, uint(vertexCos.size()));
calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords);
#ifdef DEBUG_TIME
TIMEIT_END(corrective_smooth_deltas);
#endif
if (is_rest_coords_alloc) {
MEM_freeN((void *)rest_coords);
}
}
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {

Some files were not shown because too many files have changed in this diff Show More