Collection IO: Enable file exporters to be specified on Collections #116646
|
@ -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):
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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.
|
@ -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",
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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"):
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -101,7 +101,7 @@ struct DRWSubdivLooseGeom {
|
|||
* \{ */
|
||||
|
||||
struct DRWSubdivCache {
|
||||
Mesh *mesh;
|
||||
const Mesh *mesh;
|
||||
BMesh *bm;
|
||||
Subdiv *subdiv;
|
||||
bool optimal_display;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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]);
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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> <ri = 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> <ri = 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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])
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
using namespace blender;
|
||||
|
||||
eSnapMode snapCamera(SnapObjectContext *sctx,
|
||||
Object *object,
|
||||
const Object *object,
|
||||
const float4x4 &obmat,
|
||||
eSnapMode snap_to_flag)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue