Curves: initial surface collision for curves sculpt mode #104469

Merged
Jacques Lucke merged 29 commits from JacquesLucke/blender:temp-curves-surface-collision into main 2023-02-11 13:46:39 +01:00
204 changed files with 2853 additions and 1964 deletions
Showing only changes of commit 8777aa561e - Show all commits

4
.gitmodules vendored
View File

@ -2,15 +2,19 @@
path = release/scripts/addons
url = ../blender-addons.git
branch = main
ignore = all
[submodule "release/scripts/addons_contrib"]
path = release/scripts/addons_contrib
url = ../blender-addons-contrib.git
branch = main
ignore = all
[submodule "release/datafiles/locale"]
path = release/datafiles/locale
url = ../blender-translations.git
branch = main
ignore = all
[submodule "source/tools"]
path = source/tools
url = ../blender-dev-tools.git
branch = main
ignore = all

View File

@ -12,6 +12,7 @@ from bpy.props import (
PointerProperty,
StringProperty,
)
from bpy.app.translations import pgettext_iface as iface_
from math import pi
@ -1664,30 +1665,48 @@ class CyclesPreferences(bpy.types.AddonPreferences):
col.label(text="No compatible GPUs found for Cycles", icon='INFO')
if device_type == 'CUDA':
col.label(text="Requires NVIDIA GPU with compute capability 3.0", icon='BLANK1')
compute_capability = "3.0"
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
icon='BLANK1', translate=False)
elif device_type == 'OPTIX':
col.label(text="Requires NVIDIA GPU with compute capability 5.0", icon='BLANK1')
col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1')
compute_capability = "5.0"
driver_version = "470"
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
icon='BLANK1', translate=False)
col.label(text="and NVIDIA driver version %s or newer" % driver_version,
icon='BLANK1', translate=False)
elif device_type == 'HIP':
import sys
if sys.platform[:3] == "win":
driver_version = "21.Q4"
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1')
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
driver_version = "22.10"
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
col.label(text="and AMD driver version 22.10 or newer", icon='BLANK1')
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
translate=False)
elif device_type == 'ONEAPI':
import sys
if sys.platform.startswith("win"):
driver_version = "101.4032"
col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
col.label(text="and Windows driver version 101.4032 or newer", icon='BLANK1')
col.label(text=iface_("and Windows driver version %s or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
driver_version = "1.3.24931"
col.label(text="Requires Intel GPU with Xe-HPG architecture and", icon='BLANK1')
col.label(text=" - intel-level-zero-gpu version 1.3.24931 or newer", icon='BLANK1')
col.label(text=iface_(" - intel-level-zero-gpu version %s or newer") % driver_version,
icon='BLANK1', translate=False)
col.label(text=" - oneAPI Level-Zero Loader", icon='BLANK1')
elif device_type == 'METAL':
col.label(text="Requires Apple Silicon with macOS 12.2 or newer", icon='BLANK1')
col.label(text="or AMD with macOS 12.3 or newer", icon='BLANK1')
silicon_mac_version = "12.2"
amd_mac_version = "12.3"
col.label(text=iface_("Requires Apple Silicon with macOS %s or newer") % silicon_mac_version,
icon='BLANK1', translate=False)
col.label(text=iface_("or AMD with macOS %s or newer") % amd_mac_version, icon='BLANK1',
translate=False)
return
for device in devices:

View File

@ -105,6 +105,7 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
}
case METAL_GPU_AMD: {
max_threads_per_threadgroup = 128;
use_metalrt = info.use_metalrt;
break;
}
case METAL_GPU_APPLE: {

View File

@ -341,7 +341,7 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
hid_map_button_mask_ = int(~(UINT_MAX << hid_map_button_num_));
}
CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, (uint)hid_map_button_mask_);
CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, uint(hid_map_button_mask_));
return device_type_ != NDOF_UnknownDevice;
}
@ -445,14 +445,14 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim
2,
"button=%d, press=%d (out of range %d, ignoring!)",
button_number,
(int)press,
int(press),
hid_map_button_num_);
return;
}
const NDOF_ButtonT button = hid_map_[button_number];
if (button == NDOF_BUTTON_NONE) {
CLOG_INFO(
LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, (int)press);
LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, int(press));
return;
}
@ -460,7 +460,7 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim
2,
"button=%d, press=%d, name=%s",
button_number,
(int)press,
int(press),
ndof_button_names[button]);
GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow();

View File

@ -424,10 +424,9 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent)
processTrackpad();
/* PeekMessage above is allowed to dispatch messages to the wndproc without us
/* `PeekMessage` above is allowed to dispatch messages to the `wndproc` without us
* noticing, so we need to check the event manager here to see if there are
* events waiting in the queue.
*/
* events waiting in the queue. */
hasEventHandled |= this->m_eventManager->getNumEvents() > 0;
} while (waitForEvent && !hasEventHandled);

View File

@ -487,7 +487,7 @@ def disable_all():
def _blender_manual_url_prefix():
return "https://docs.blender.org/manual/en/%d.%d" % _bpy.app.version[:2]
return "https://docs.blender.org/manual/%s/%d.%d" % (_bpy.utils.manual_language_code(), *_bpy.app.version[:2])
def module_bl_info(mod, *, info_basis=None):

View File

@ -26,6 +26,7 @@ __all__ = (
"register_tool",
"make_rna_paths",
"manual_map",
"manual_language_code",
"previews",
"resource_path",
"script_path_user",
@ -1035,6 +1036,53 @@ def manual_map():
yield prefix, url_manual_mapping
# Languages which are supported by the user manual (commented when there is no translation).
_manual_language_codes = {
"ar_EG": "ar", # Arabic
# "bg_BG": "bg", # Bulgarian
# "ca_AD": "ca", # Catalan
# "cs_CZ": "cz", # Czech
"de_DE": "de", # German
# "el_GR": "el", # Greek
"es": "es", # Spanish
"fi_FI": "fi", # Finnish
"fr_FR": "fr", # French
"id_ID": "id", # Indonesian
"it_IT": "it", # Italian
"ja_JP": "ja", # Japanese
"ko_KR": "ko", # Korean
# "nb": "nb", # Norwegian
# "nl_NL": "nl", # Dutch
# "pl_PL": "pl", # Polish
"pt_PT": "pt", # Portuguese
# Portuguese - Brazil, for until we have a pt_BR version.
"pt_BR": "pt",
"ru_RU": "ru", # Russian
"sk_SK": "sk", # Slovak
# "sl": "sl", # Slovenian
"sr_RS": "sr", # Serbian
# "sv_SE": "sv", # Swedish
# "tr_TR": "th", # Thai
"uk_UA": "uk", # Ukrainian
"vi_VN": "vi", # Vietnamese
"zh_CN": "zh-hans", # Simplified Chinese
"zh_TW": "zh-hant", # Traditional Chinese
}
def manual_language_code(default="en"):
"""
:return:
The language code used for user manual URL component based on the current language user-preference,
falling back to the ``default`` when unavailable.
:rtype: str
"""
language = _bpy.context.preferences.view.language
if language == 'DEFAULT':
language = _os.getenv("LANG", "").split(".")[0]
return _manual_language_codes.get(language, default)
# Build an RNA path from struct/property/enum names.
def make_rna_paths(struct_name, prop_name, enum_name):
"""

View File

@ -4,38 +4,10 @@
# autopep8: off
import bpy
manual_version = '%d.%d' % bpy.app.version[:2]
url_manual_prefix = "https://docs.blender.org/manual/en/" + manual_version + "/"
language = bpy.context.preferences.view.language
if language == 'DEFAULT':
import os
language = os.getenv('LANG', '').split('.')[0]
LANG = {
"ar_EG": "ar",
"de_DE": "de",
"es": "es",
"fi_FI": "fi",
"fr_FR": "fr",
"id_ID": "id",
"it_IT": "it",
"ja_JP": "ja",
"ko_KR": "ko",
"pt_PT": "pt",
"pt_BR": "pt",
"ru_RU": "ru",
"sk_SK": "sk",
"sr_RS": "sr",
"uk_UA": "uk",
"vi_VN": "vi",
"zh_CN": "zh-hans",
"zh_TW": "zh-hant",
}.get(language)
if LANG is not None:
url_manual_prefix = url_manual_prefix.replace("manual/en", "manual/" + LANG)
url_manual_prefix = "https://docs.blender.org/manual/%s/%d.%d/" % (
bpy.utils.manual_language_code(),
*bpy.app.version[:2],
)
url_manual_mapping = (
("bpy.types.movietrackingsettings.refine_intrinsics_tangential_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-tangential-distortion"),
@ -641,7 +613,6 @@ url_manual_mapping = (
("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"),
("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"),
("bpy.ops.mesh.customdata_crease_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-clear"),
("bpy.types.brush.html#bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-html-bpy-types-brush-jitter"),
("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"),
("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"),
("bpy.types.clothcollisionsettings.collection*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collection"),
@ -672,7 +643,7 @@ url_manual_mapping = (
("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/read/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"),
("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/read/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"),
("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/read/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"),
("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_set_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"),
("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_group_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"),
("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"),
("bpy.types.lineartgpencilmodifier.use_crease*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease"),
("bpy.types.lineartgpencilmodifier.use_shadow*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-shadow"),
@ -1417,6 +1388,7 @@ url_manual_mapping = (
("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/utilities/text/replace_string.html#bpy-types-functionnodereplacestring"),
("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/utilities/color/separate_color.html#bpy-types-functionnodeseparatecolor"),
("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/utilities/text/value_to_string.html#bpy-types-functionnodevaluetostring"),
("bpy.types.geometrynodeblurattribute*", "modeling/geometry_nodes/attribute/blur_attribute.html#bpy-types-geometrynodeblurattribute"),
("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/operations/curve_to_points.html#bpy-types-geometrynodecurvetopoints"),
("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh/topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"),
("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh/topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"),
@ -2055,7 +2027,6 @@ url_manual_mapping = (
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"),
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"),
("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"),
@ -2111,7 +2082,6 @@ url_manual_mapping = (
("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/operations/bounding_box.html#bpy-types-geometrynodeboundbox"),
("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve/primitives/arc.html#bpy-types-geometrynodecurvearc"),
("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/operations/dual_mesh.html#bpy-types-geometrynodedualmesh"),
("bpy.types.geometrynodematerial*", "-1"),
("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh/primitives/cone.html#bpy-types-geometrynodemeshcone"),
("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh/primitives/cube.html#bpy-types-geometrynodemeshcube"),
("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh/primitives/grid.html#bpy-types-geometrynodemeshgrid"),

View File

@ -3478,7 +3478,8 @@ def km_animation_channels(params):
# Selection.
*_template_items_select_actions(params, "anim.channels_select_all"),
("anim.channels_select_box", {"type": 'B', "value": 'PRESS'}, None),
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, None),
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
{"properties": [("extend", False)]}),
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True},
{"properties": [("extend", True)]}),
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True},
@ -5627,6 +5628,7 @@ def km_curves(params):
("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None),
("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
*_template_items_select_actions(params, "curves.select_all"),
("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
])
return keymap

View File

@ -1056,7 +1056,7 @@ class WM_OT_url_open_preset(Operator):
return "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2]
def _url_from_manual(self, _context):
return "https://docs.blender.org/manual/en/%d.%d/" % bpy.app.version[:2]
return "https://docs.blender.org/manual/%s/%d.%d/" % (bpy.utils.manual_language_code(), *bpy.app.version[:2])
def _url_from_api(self, _context):
return "https://docs.blender.org/api/%d.%d/" % bpy.app.version[:2]

View File

@ -35,19 +35,10 @@ def draw_node_group_add_menu(context, layout):
if node_tree:
from nodeitems_builtins import node_tree_group_type
def contains_group(nodetree, group):
if nodetree == group:
return True
for node in nodetree.nodes:
if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
if contains_group(node.node_tree, group):
return True
return False
groups = [
group for group in context.blend_data.node_groups
if (group.bl_idname == node_tree.bl_idname and
not contains_group(group, node_tree) and
not group.contains_tree(node_tree) and
not group.name.startswith('.'))
]
if groups:

View File

@ -338,6 +338,7 @@ class NODE_MT_geometry_node_GEO_MESH_READ(Menu):
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices")
node_add_menu.add_node_type(layout, "GeometryNodeEdgesToFaceGroups")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea")
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors")
node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries")

View File

@ -485,7 +485,6 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
layout.use_property_split = True
layout.use_property_decorate = False
obj = context.object
me = context.mesh
col = layout.column()

View File

@ -62,7 +62,6 @@ class PARTICLE_MT_context_menu(Menu):
def draw(self, context):
layout = self.layout
psys = context.particle_system
experimental = context.preferences.experimental
props = layout.operator(
"particle.copy_particle_systems",
@ -508,7 +507,7 @@ class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel):
sub.prop(psys.settings, "bending_random", text="Random")
col.prop(cloth, "bending_damping", text="Damping")
# XXX has no noticeable effect with stiff hair structure springs
#col.prop(cloth, "spring_damping", text="Damping")
# col.prop(cloth, "spring_damping", text="Damping")
class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel):
@ -1100,7 +1099,7 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel):
if part.physics_type == 'KEYED':
col = layout.column()
# doesn't work yet
#col.alert = key.valid
# col.alert = key.valid
col.prop(key, "object")
col.prop(key, "system", text="System")
sub = col.column(align=True)
@ -1110,7 +1109,7 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel):
elif part.physics_type == 'BOIDS':
sub = layout.column()
# doesn't work yet
#sub.alert = key.valid
# sub.alert = key.valid
sub.prop(key, "object")
sub.prop(key, "system", text="System")
layout.prop(key, "alliance")
@ -1157,7 +1156,7 @@ class PARTICLE_PT_physics_fluid_interaction(ParticleButtonsPanel, Panel):
if key:
sub = layout.column()
# doesn't work yet
#sub.alert = key.valid
# sub.alert = key.valid
sub.prop(key, "object")
sub.prop(key, "system", text="System")

View File

@ -641,7 +641,6 @@ class RENDER_PT_eevee_next_film(RenderButtonsPanel, Panel):
scene = context.scene
rd = scene.render
props = scene.eevee
col = layout.column()
col.prop(rd, "filter_size")

View File

@ -1996,7 +1996,7 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
split = col.split(factor=0.4)
split.alignment = 'RIGHT'
split.label(text="Pan", heading_ctxt=i18n_contexts.id_sound)
split.label(text="Pan", text_ctxt=i18n_contexts.id_sound)
split.prop(strip, "pan", text="")
split.enabled = pan_enabled

File diff suppressed because it is too large Load Diff

View File

@ -2329,6 +2329,9 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
({"property": "use_override_templates"},
("blender/blender/issues/73318",
"Milestone 4")),
({"property": "use_new_volume_nodes"},
("blender/blender/issues/103248",
"#103248")),
),
)

View File

@ -2054,6 +2054,7 @@ class VIEW3D_MT_select_edit_curves(Menu):
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
layout.operator("curves.select_random", text="Random")
layout.operator("curves.select_end", text="Endpoints")
layout.operator("curves.select_linked", text="Linked")
class VIEW3D_MT_select_sculpt_curves(Menu):
@ -6708,13 +6709,12 @@ class VIEW3D_PT_overlay_sculpt(Panel):
def poll(cls, context):
return (
context.mode == 'SCULPT' and
(context.sculpt_object and context.tool_settings.sculpt)
context.sculpt_object
)
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
sculpt = tool_settings.sculpt
view = context.space_data
overlay = view.overlay

View File

@ -76,21 +76,11 @@ def node_group_items(context):
yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
def contains_group(nodetree, group):
if nodetree == group:
return True
else:
for node in nodetree.nodes:
if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
if contains_group(node.node_tree, group):
return True
return False
for group in context.blend_data.node_groups:
if group.bl_idname != ntree.bl_idname:
continue
# filter out recursive groups
if contains_group(group, ntree):
if group.contains_tree(ntree):
continue
# filter out hidden nodetrees
if group.name.startswith('.'):

View File

@ -25,7 +25,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 8
#define BLENDER_FILE_SUBVERSION 9
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -63,7 +63,7 @@ typedef struct FModifierTypeInfo {
/** #eFMI_Action_Types. */
short acttype;
/** #eFMI_Requirement_Flags. */
short requires;
short requires_flag;
/** name of modifier in interface. */
char name[64];
/** name of struct for SDNA. */

View File

@ -229,11 +229,6 @@ void BKE_mesh_material_remap(struct Mesh *me, const unsigned int *remap, unsigne
void BKE_mesh_smooth_flag_set(struct Mesh *me, bool use_smooth);
void BKE_mesh_auto_smooth_flag_set(struct Mesh *me, bool use_auto_smooth, float auto_smooth_angle);
/**
* Needed after converting a mesh with subsurf optimal display to mesh.
*/
void BKE_mesh_edges_set_draw_render(struct Mesh *me);
/**
* Used for unit testing; compares two meshes, checking only
* differences we care about. should be usable with leaf's

View File

@ -145,10 +145,7 @@ void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
*/
void BKE_mesh_do_versions_convert_mfaces_to_mpolys(struct Mesh *mesh);
/**
* Convert legacy #MFace.edcode to edge #ME_EDGEDRAW.
*/
void BKE_mesh_calc_edges_legacy(struct Mesh *me, bool use_old);
void BKE_mesh_calc_edges_legacy(struct Mesh *me);
void BKE_mesh_do_versions_cd_flag_init(struct Mesh *mesh);

View File

@ -170,7 +170,6 @@ void BKE_mesh_vert_edge_vert_map_create(
*/
void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
int **r_mem,
const struct MEdge *medge,
int totedge,
const struct MPoly *mpoly,
int totpoly,
@ -183,7 +182,6 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
*/
void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
int **r_mem,
const struct MEdge *medge,
int totedge,
const struct MPoly *mpoly,
int totpoly,
@ -317,8 +315,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
* starting at 1 (0 being used as 'invalid' flag).
* Note it's callers's responsibility to MEM_freeN returned array.
*/
int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge,
int totedge,
int *BKE_mesh_calc_smoothgroups(int totedge,
const struct MPoly *mpoly,
int totpoly,
const struct MLoop *mloop,
@ -353,6 +350,7 @@ Array<Vector<int>> build_vert_to_edge_map(Span<MEdge> edges, int verts_num);
Array<Vector<int>> build_vert_to_poly_map(Span<MPoly> polys, Span<MLoop> loops, int verts_num);
Array<Vector<int>> build_vert_to_loop_map(Span<MLoop> loops, int verts_num);
Array<Vector<int>> build_edge_to_loop_map(Span<MLoop> loops, int edges_num);
Array<Vector<int, 2>> build_edge_to_poly_map(Span<MPoly> polys, Span<MLoop> loops, int edges_num);
Vector<Vector<int>> build_edge_to_loop_map_resizable(Span<MLoop> loops, int edges_num);
inline int poly_loop_prev(const MPoly &poly, int loop_i)

View File

@ -174,6 +174,13 @@ struct MeshRuntime {
*/
BitVector<> subsurf_face_dot_tags;
/**
* A bit vector the size of the number of edges, set to true for edges that should be drawn in
* the viewport. Created by the "Optimal Display" feature of the subdivision surface modifier.
* Otherwise it will be empty.
*/
BitVector<> subsurf_optimal_display_edges;
MeshRuntime() = default;
~MeshRuntime();

View File

@ -504,7 +504,13 @@ struct bNodeTree *ntreeFromID(struct ID *id);
void ntreeFreeLocalNode(struct bNodeTree *ntree, struct bNode *node);
void ntreeFreeLocalTree(struct bNodeTree *ntree);
struct bNode *ntreeFindType(struct bNodeTree *ntree, int type);
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
/**
* Check recursively if a node tree contains another.
*/
bool ntreeContainsTree(const struct bNodeTree *tree_to_search_in,
const struct bNodeTree *tree_to_search_for);
void ntreeUpdateAllNew(struct Main *main);
void ntreeUpdateAllUsers(struct Main *main, struct ID *id);
@ -1534,6 +1540,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define GEO_NODE_BLUR_ATTRIBUTE 1190
#define GEO_NODE_IMAGE 1191
#define GEO_NODE_INTERPOLATE_CURVES 1192
#define GEO_NODE_EDGES_TO_FACE_GROUPS 1193
/** \} */

View File

@ -62,7 +62,6 @@ static void fill_mesh_topology(const int vert_offset,
MEdge &edge = edges[profile_edge_offset + i_ring];
edge.v1 = ring_vert_offset + i_profile;
edge.v2 = next_ring_vert_offset + i_profile;
edge.flag = ME_EDGEDRAW;
}
}
@ -78,7 +77,6 @@ static void fill_mesh_topology(const int vert_offset,
MEdge &edge = edges[ring_edge_offset + i_profile];
edge.v1 = ring_vert_offset + i_profile;
edge.v2 = ring_vert_offset + i_next_profile;
edge.flag = ME_EDGEDRAW;
}
}

View File

@ -2289,26 +2289,12 @@ bool CustomData_merge(const CustomData *source,
return changed;
}
static bool attribute_stored_in_bmesh_flag(const StringRef name)
{
return ELEM(name,
"position",
".hide_vert",
".hide_edge",
".hide_poly",
".select_vert",
".select_edge",
".select_poly",
"material_index",
"sharp_edge");
}
CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
const eCustomDataMask mask)
{
Vector<CustomDataLayer> dst_layers;
for (const CustomDataLayer &layer : Span<CustomDataLayer>{src->layers, src->totlayer}) {
if (attribute_stored_in_bmesh_flag(layer.name)) {
if (BM_attribute_stored_in_bmesh_builtin(layer.name)) {
continue;
}
if (!(mask & CD_TYPE_AS_MASK(layer.type))) {

View File

@ -772,7 +772,7 @@ bool get_effector_data(EffectorCache *eff,
if (eff->pd->forcefield == PFIELD_VORTEX || eff->pd->shape == PFIELD_SHAPE_LINE) {
add_v3_v3v3(efd->loc, ob->object_to_world[3], translate);
}
else { /* normally efd->loc is closest point on effector xy-plane */
else { /* Normally `efd->loc` is closest point on effector XY-plane. */
sub_v3_v3v3(efd->loc, point->loc, translate);
}
}
@ -1125,31 +1125,31 @@ void BKE_effectors_apply(ListBase *effectors,
/* WARNING(@ideasman42): historic comment?
* Many of these parameters don't exist!
*
* scene = scene where it runs in, for time and stuff.
* lb = listbase with objects that take part in effecting.
* opco = global coord, as input.
* force = accumulator for force.
* wind_force = accumulator for force only acting perpendicular to a surface.
* speed = actual current speed which can be altered.
* cur_time = "external" time in frames, is constant for static particles.
* loc_time = "local" time in frames, range <0-1> for the lifetime of particle.
* par_layer = layer the caller is in.
* flags = only used for soft-body wind now.
* guide = old speed of particle.
* `scene` = scene where it runs in, for time and stuff.
* `lb` = listbase with objects that take part in effecting.
* `opco` = global coord, as input.
* `force` = accumulator for force.
* `wind_force` = accumulator for force only acting perpendicular to a surface.
* `speed` = actual current speed which can be altered.
* `cur_time` = "external" time in frames, is constant for static particles.
* `loc_time` = "local" time in frames, range <0-1> for the lifetime of particle.
* `par_layer` = layer the caller is in.
* `flags` = only used for soft-body wind now.
* `guide` = old speed of particle.
*/
/*
* Modifies the force on a particle according to its
* relation with the effector object
* Different kind of effectors include:
* Force-fields: Gravity-like attractor
* (force power is related to the inverse of distance to the power of a falloff value)
* Vortex fields: swirling effectors
* (particles rotate around Z-axis of the object. otherwise, same relation as)
* (Force-fields, but this is not done through a force/acceleration)
* Guide: particles on a path
* (particles are guided along a curve bezier or old nurbs)
* (is independent of other effectors)
* - Force-fields: Gravity-like attractor
* (force power is related to the inverse of distance to the power of a falloff value)
* - Vortex fields: swirling effectors
* (particles rotate around Z-axis of the object. otherwise, same relation as)
* (Force-fields, but this is not done through a force/acceleration)
* - Guide: particles on a path
* (particles are guided along a curve bezier or old nurbs)
* (is independent of other effectors)
*/
EffectorCache *eff;
EffectorData efd;

View File

@ -64,7 +64,7 @@ static FModifierTypeInfo FMI_MODNAME = {
/*type*/ FMODIFIER_TYPE_MODNAME,
/*size*/ sizeof(FMod_ModName),
/*acttype*/ FMI_TYPE_SOME_ACTION,
/*requires*/ FMI_REQUIRES_SOME_REQUIREMENT,
/*requires_flag*/ FMI_REQUIRES_SOME_REQUIREMENT,
/*name*/ "Modifier Name",
/*structName*/ "FMod_ModName",
/*storage_size*/ 0,
@ -228,7 +228,7 @@ static FModifierTypeInfo FMI_GENERATOR = {
/*type*/ FMODIFIER_TYPE_GENERATOR,
/*size*/ sizeof(FMod_Generator),
/*acttype*/ FMI_TYPE_GENERATE_CURVE,
/*requires*/ FMI_REQUIRES_NOTHING,
/*requires_flag*/ FMI_REQUIRES_NOTHING,
/*name*/ N_("Generator"),
/*structName*/ "FMod_Generator",
/*storage_size*/ 0,
@ -358,7 +358,7 @@ static FModifierTypeInfo FMI_FN_GENERATOR = {
/*type*/ FMODIFIER_TYPE_FN_GENERATOR,
/*size*/ sizeof(FMod_FunctionGenerator),
/*acttype*/ FMI_TYPE_GENERATE_CURVE,
/*requires*/ FMI_REQUIRES_NOTHING,
/*requires_flag*/ FMI_REQUIRES_NOTHING,
/*name*/ N_("Built-In Function"),
/*structName*/ "FMod_FunctionGenerator",
/*storage_size*/ 0,
@ -471,7 +471,7 @@ static FModifierTypeInfo FMI_ENVELOPE = {
/*type*/ FMODIFIER_TYPE_ENVELOPE,
/*size*/ sizeof(FMod_Envelope),
/*acttype*/ FMI_TYPE_REPLACE_VALUES,
/*requires*/ 0,
/*requires_flag*/ 0,
/*name*/ N_("Envelope"),
/*structName*/ "FMod_Envelope",
/*storage_size*/ 0,
@ -770,7 +770,7 @@ static FModifierTypeInfo FMI_CYCLES = {
/*type*/ FMODIFIER_TYPE_CYCLES,
/*size*/ sizeof(FMod_Cycles),
/*acttype*/ FMI_TYPE_EXTRAPOLATION,
/*requires*/ FMI_REQUIRES_ORIGINAL_DATA,
/*requires_flag*/ FMI_REQUIRES_ORIGINAL_DATA,
/*name*/ CTX_N_(BLT_I18NCONTEXT_ID_ACTION, "Cycles"),
/*structName*/ "FMod_Cycles",
/*storage_size*/ sizeof(tFCMED_Cycles),
@ -832,7 +832,7 @@ static FModifierTypeInfo FMI_NOISE = {
/*type*/ FMODIFIER_TYPE_NOISE,
/*size*/ sizeof(FMod_Noise),
/*acttype*/ FMI_TYPE_REPLACE_VALUES,
/*requires*/ 0,
/*requires_flag*/ 0,
/*name*/ N_("Noise"),
/*structName*/ "FMod_Noise",
/*storage_size*/ 0,
@ -890,7 +890,7 @@ static FModifierTypeInfo FMI_PYTHON = {
/*type*/ FMODIFIER_TYPE_PYTHON,
/*size*/ sizeof(FMod_Python),
/*acttype*/ FMI_TYPE_GENERATE_CURVE,
/*requires*/ FMI_REQUIRES_RUNTIME_CHECK,
/*requires_flag*/ FMI_REQUIRES_RUNTIME_CHECK,
/*name*/ N_("Python"),
/*structName*/ "FMod_Python",
/*storage_size*/ 0,
@ -945,7 +945,7 @@ static FModifierTypeInfo FMI_LIMITS = {
/*type*/ FMODIFIER_TYPE_LIMITS,
/*size*/ sizeof(FMod_Limits),
/*acttype*/ FMI_TYPE_GENERATE_CURVE,
/*requires*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */
/*requires_flag*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */
/*name*/ N_("Limits"),
/*structName*/ "FMod_Limits",
/*storage_size*/ 0,
@ -1005,7 +1005,7 @@ static FModifierTypeInfo FMI_STEPPED = {
/*type*/ FMODIFIER_TYPE_STEPPED,
/*size*/ sizeof(FMod_Limits),
/*acttype*/ FMI_TYPE_GENERATE_CURVE,
/*requires*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */
/*requires_flag*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */
/*name*/ N_("Stepped"),
/*structName*/ "FMod_Stepped",
/*storage_size*/ 0,

View File

@ -1261,7 +1261,9 @@ bGPDframe *BKE_gpencil_layer_frame_get(bGPDlayer *gpl, int cframe, eGP_GetFrame_
found = true;
break;
}
if ((gpf->next) && (gpf->next->framenum > cframe)) {
/* If this is the last frame or the next frame is at a later time, we found the right
* frame. */
if (!(gpf->next) || (gpf->next->framenum > cframe)) {
found = true;
break;
}

View File

@ -107,10 +107,12 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
mesh_dst->runtime->wrapper_type_finalize = mesh_src->runtime->wrapper_type_finalize;
mesh_dst->runtime->subsurf_runtime_data = mesh_src->runtime->subsurf_runtime_data;
mesh_dst->runtime->cd_mask_extra = mesh_src->runtime->cd_mask_extra;
/* Copy face dot tags, since meshes may be duplicated after a subsurf modifier or node, but we
* still need to be able to draw face center vertices. The tags may be cleared explicitly when
* the topology is changed. */
/* Copy face dot tags and edge tags, since meshes may be duplicated after a subsurf modifier or
* node, but we still need to be able to draw face center vertices and "optimal edges"
* differently. The tags may be cleared explicitly when the topology is changed. */
mesh_dst->runtime->subsurf_face_dot_tags = mesh_src->runtime->subsurf_face_dot_tags;
mesh_dst->runtime->subsurf_optimal_display_edges =
mesh_src->runtime->subsurf_optimal_display_edges;
if ((mesh_src->id.tag & LIB_TAG_NO_MAIN) == 0) {
/* This is a direct copy of a main mesh, so for now it has the same topology. */
mesh_dst->runtime->deformed_only = true;

View File

@ -146,7 +146,6 @@ static void serialize_and_initialize_deduplicated_edges(MutableSpan<EdgeMap> edg
/* Initialize new edge. */
new_edge.v1 = item.key.v_low;
new_edge.v2 = item.key.v_high;
new_edge.flag = ME_EDGEDRAW;
}
item.value.index = new_edge_index;
new_edge_index++;

View File

@ -121,7 +121,7 @@ static void make_edges_mdata_extend(Mesh &mesh)
BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index));
medge->flag = ME_EDGEDRAW;
medge->flag = 0;
}
BLI_edgehashIterator_free(ehi);
@ -223,7 +223,6 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
for (b = 1; b < dl->nr; b++) {
edges[dst_edge].v1 = startvert + ofs + b - 1;
edges[dst_edge].v2 = startvert + ofs + b;
edges[dst_edge].flag = ME_EDGEDRAW;
dst_edge++;
}
@ -250,7 +249,6 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
else {
edges[dst_edge].v2 = startvert + ofs + b + 1;
}
edges[dst_edge].flag = ME_EDGEDRAW;
dst_edge++;
}
}
@ -662,14 +660,6 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint);
}
void BKE_mesh_edges_set_draw_render(Mesh *mesh)
{
MutableSpan<MEdge> edges = mesh->edges_for_write();
for (int i = 0; i < mesh->totedge; i++) {
edges[i].flag |= ME_EDGEDRAW;
}
}
void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob)
{
BLI_assert(ob->type == OB_POINTCLOUD);

View File

@ -89,7 +89,6 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/,
int totface,
int /*totloop*/,
int totpoly,
const bool use_old,
MEdge **r_medge,
int *r_totedge)
{
@ -156,9 +155,6 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/,
if (ed->v1 != (ed + 1)->v1 || ed->v2 != (ed + 1)->v2) {
med->v1 = ed->v1;
med->v2 = ed->v2;
if (use_old == false || ed->is_draw) {
med->flag = ME_EDGEDRAW;
}
/* order is swapped so extruding this edge as a surface won't flip face normals
* with cyclic curves */
@ -175,7 +171,6 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/,
/* last edge */
med->v1 = ed->v1;
med->v2 = ed->v2;
med->flag = ME_EDGEDRAW;
MEM_freeN(edsort);
@ -206,7 +201,7 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/,
*r_totedge = totedge_final;
}
void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
void BKE_mesh_calc_edges_legacy(Mesh *me)
{
using namespace blender;
MEdge *medge;
@ -224,7 +219,6 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
me->totface,
loops.size(),
polys.size(),
use_old,
&medge,
&totedge);

View File

@ -15,6 +15,7 @@
#include "BLI_array.hh"
#include "BLI_bitmap.h"
#include "BLI_buffer.h"
#include "BLI_function_ref.hh"
#include "BLI_math.h"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
@ -385,7 +386,6 @@ void BKE_mesh_vert_edge_vert_map_create(
void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
int **r_mem,
const MEdge * /*medge*/,
const int totedge,
const MPoly *mpoly,
const int totpoly,
@ -438,7 +438,6 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
int **r_mem,
const MEdge * /*medge*/,
const int totedge,
const MPoly *mpoly,
const int totpoly,
@ -610,6 +609,20 @@ Array<Vector<int>> build_edge_to_loop_map(const Span<MLoop> loops, const int edg
return map;
}
Array<Vector<int, 2>> build_edge_to_poly_map(const Span<MPoly> polys,
const Span<MLoop> loops,
const int edges_num)
{
Array<Vector<int, 2>> map(edges_num);
for (const int64_t i : polys.index_range()) {
const MPoly &poly = polys[i];
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
map[loop.e].append(int(i));
}
}
return map;
}
Vector<Vector<int>> build_edge_to_loop_map_resizable(const Span<MLoop> loops, const int edges_num)
{
Vector<Vector<int>> map(edges_num);
@ -631,27 +644,19 @@ Vector<Vector<int>> build_edge_to_loop_map_resizable(const Span<MLoop> loops, co
/**
* Callback deciding whether the given poly/loop/edge define an island boundary or not.
*/
using MeshRemap_CheckIslandBoundary = bool (*)(const MPoly *mpoly,
const MLoop *mloop,
const MEdge *medge,
const int edge_index,
const bool *sharp_edges,
const int edge_user_count,
const MPoly *mpoly_array,
const MeshElemMap *edge_poly_map,
void *user_data);
using MeshRemap_CheckIslandBoundary =
blender::FunctionRef<bool(int poly_index,
int loop_index,
int edge_index,
int edge_user_count,
const MeshElemMap &edge_poly_map_elem)>;
static void poly_edge_loop_islands_calc(const MEdge *medge,
const int totedge,
const MPoly *mpoly,
const int totpoly,
const MLoop *mloop,
const int totloop,
const bool *sharp_edges,
static void poly_edge_loop_islands_calc(const int totedge,
const blender::Span<MPoly> polys,
const blender::Span<MLoop> loops,
MeshElemMap *edge_poly_map,
const bool use_bitflags,
MeshRemap_CheckIslandBoundary edge_boundary_check,
void *edge_boundary_check_data,
int **r_poly_groups,
int *r_totgroup,
BLI_bitmap **r_edge_borders,
@ -675,7 +680,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
/* map vars */
int *edge_poly_mem = nullptr;
if (totpoly == 0) {
if (polys.size() == 0) {
*r_totgroup = 0;
*r_poly_groups = nullptr;
if (r_edge_borders) {
@ -691,12 +696,17 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
}
if (!edge_poly_map) {
BKE_mesh_edge_poly_map_create(
&edge_poly_map, &edge_poly_mem, medge, totedge, mpoly, totpoly, mloop, totloop);
BKE_mesh_edge_poly_map_create(&edge_poly_map,
&edge_poly_mem,
totedge,
polys.data(),
int(polys.size()),
loops.data(),
int(loops.size()));
}
poly_groups = static_cast<int *>(MEM_callocN(sizeof(int) * size_t(totpoly), __func__));
poly_stack = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(totpoly), __func__));
poly_groups = static_cast<int *>(MEM_callocN(sizeof(int) * size_t(polys.size()), __func__));
poly_stack = static_cast<int *>(MEM_mallocN(sizeof(int) * size_t(polys.size()), __func__));
while (true) {
int poly;
@ -704,13 +714,13 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
int poly_group_id;
int ps_curr_idx = 0, ps_end_idx = 0; /* stack indices */
for (poly = poly_prev; poly < totpoly; poly++) {
for (poly = poly_prev; poly < int(polys.size()); poly++) {
if (poly_groups[poly] == 0) {
break;
}
}
if (poly == totpoly) {
if (poly == int(polys.size())) {
/* all done */
break;
}
@ -724,23 +734,16 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
poly_stack[ps_end_idx++] = poly;
while (ps_curr_idx != ps_end_idx) {
const MPoly *mp;
const MLoop *ml;
int j;
poly = poly_stack[ps_curr_idx++];
BLI_assert(poly_groups[poly] == poly_group_id);
mp = &mpoly[poly];
for (ml = &mloop[mp->loopstart], j = mp->totloop; j--; ml++) {
for (const int64_t loop : blender::IndexRange(polys[poly].loopstart, polys[poly].totloop)) {
const int edge = int(loops[loop].e);
/* loop over poly users */
const int me_idx = int(ml->e);
const MEdge *me = &medge[me_idx];
const MeshElemMap *map_ele = &edge_poly_map[me_idx];
const int *p = map_ele->indices;
int i = map_ele->count;
if (!edge_boundary_check(
mp, ml, me, me_idx, sharp_edges, i, mpoly, map_ele, edge_boundary_check_data)) {
const MeshElemMap &map_ele = edge_poly_map[edge];
const int *p = map_ele.indices;
int i = map_ele.count;
if (!edge_boundary_check(poly, int(loop), edge, i, map_ele)) {
for (; i--; p++) {
/* if we meet other non initialized its a bug */
BLI_assert(ELEM(poly_groups[*p], 0, poly_group_id));
@ -752,8 +755,8 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
}
}
else {
if (edge_borders && !BLI_BITMAP_TEST(edge_borders, me_idx)) {
BLI_BITMAP_ENABLE(edge_borders, me_idx);
if (edge_borders && !BLI_BITMAP_TEST(edge_borders, edge)) {
BLI_BITMAP_ENABLE(edge_borders, edge);
num_edgeborders++;
}
if (use_bitflags) {
@ -814,7 +817,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
}
if (UNLIKELY(group_id_overflow)) {
int i = totpoly, *gid = poly_groups;
int i = int(polys.size()), *gid = poly_groups;
for (; i--; gid++) {
if (*gid == poly_group_id_overflowed) {
*gid = 0;
@ -838,31 +841,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
}
}
static bool poly_is_island_boundary_smooth_cb(const MPoly *mp,
const MLoop * /*ml*/,
const MEdge * /*me*/,
const int edge_index,
const bool *sharp_edges,
const int edge_user_count,
const MPoly *mpoly_array,
const MeshElemMap *edge_poly_map,
void * /*user_data*/)
{
/* Edge is sharp if one of its polys is flat, or edge itself is sharp,
* or edge is not used by exactly two polygons. */
if ((mp->flag & ME_SMOOTH) && !(sharp_edges && sharp_edges[edge_index]) &&
(edge_user_count == 2)) {
/* In that case, edge appears to be smooth, but we need to check its other poly too. */
const MPoly *mp_other = (mp == &mpoly_array[edge_poly_map->indices[0]]) ?
&mpoly_array[edge_poly_map->indices[1]] :
&mpoly_array[edge_poly_map->indices[0]];
return (mp_other->flag & ME_SMOOTH) == 0;
}
return true;
}
int *BKE_mesh_calc_smoothgroups(const MEdge *medge,
const int totedge,
int *BKE_mesh_calc_smoothgroups(const int totedge,
const MPoly *mpoly,
const int totpoly,
const MLoop *mloop,
@ -873,17 +852,30 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge,
{
int *poly_groups = nullptr;
poly_edge_loop_islands_calc(medge,
totedge,
mpoly,
totpoly,
mloop,
totloop,
sharp_edges,
auto poly_is_island_boundary_smooth = [&](const int poly_index,
const int /*loop_index*/,
const int edge_index,
const int edge_user_count,
const MeshElemMap &edge_poly_map_elem) {
/* Edge is sharp if one of its polys is flat, or edge itself is sharp,
* or edge is not used by exactly two polygons. */
if ((mpoly[poly_index].flag & ME_SMOOTH) && !(sharp_edges && sharp_edges[edge_index]) &&
(edge_user_count == 2)) {
/* In that case, edge appears to be smooth, but we need to check its other poly too. */
const int other_poly_index = (poly_index == edge_poly_map_elem.indices[0]) ?
edge_poly_map_elem.indices[1] :
edge_poly_map_elem.indices[0];
return (mpoly[other_poly_index].flag & ME_SMOOTH) == 0;
}
return true;
};
poly_edge_loop_islands_calc(totedge,
{mpoly, totpoly},
{mloop, totloop},
nullptr,
use_bitflags,
poly_is_island_boundary_smooth_cb,
nullptr,
poly_is_island_boundary_smooth,
&poly_groups,
r_totgroup,
nullptr,
@ -1007,64 +999,6 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
sizeof(*innrcut->indices) * size_t(num_innercut_items));
}
/* TODO: I'm not sure edge seam flag is enough to define UV islands?
* Maybe we should also consider UV-maps values
* themselves (i.e. different UV-edges for a same mesh-edge => boundary edge too?).
* Would make things much more complex though,
* and each UVMap would then need its own mesh mapping, not sure we want that at all!
*/
struct MeshCheckIslandBoundaryUv {
const MLoop *loops;
const float (*luvs)[2];
const MeshElemMap *edge_loop_map;
};
static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/,
const MLoop *ml,
const MEdge *me,
const int /*edge_index*/,
const bool * /*sharp_edges*/,
const int /*edge_user_count*/,
const MPoly * /*mpoly_array*/,
const MeshElemMap * /*edge_poly_map*/,
void *user_data)
{
if (user_data) {
const MeshCheckIslandBoundaryUv *data = static_cast<const MeshCheckIslandBoundaryUv *>(
user_data);
const MLoop *loops = data->loops;
const float(*luvs)[2] = data->luvs;
const MeshElemMap *edge_to_loops = &data->edge_loop_map[ml->e];
BLI_assert(edge_to_loops->count >= 2 && (edge_to_loops->count % 2) == 0);
const uint v1 = loops[edge_to_loops->indices[0]].v;
const uint v2 = loops[edge_to_loops->indices[1]].v;
const float *uvco_v1 = luvs[edge_to_loops->indices[0]];
const float *uvco_v2 = luvs[edge_to_loops->indices[1]];
for (int i = 2; i < edge_to_loops->count; i += 2) {
if (loops[edge_to_loops->indices[i]].v == v1) {
if (!equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i]]) ||
!equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i + 1]])) {
return true;
}
}
else {
BLI_assert(loops[edge_to_loops->indices[i]].v == v2);
UNUSED_VARS_NDEBUG(v2);
if (!equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i]]) ||
!equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i + 1]])) {
return true;
}
}
}
return false;
}
/* Edge is UV boundary if tagged as seam. */
return (me->flag & ME_SEAM) != 0;
}
static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges,
const int totedge,
const MPoly *polys,
@ -1084,8 +1018,6 @@ static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges,
MeshElemMap *edge_loop_map;
int *edge_loop_mem;
MeshCheckIslandBoundaryUv edge_boundary_check_data;
int *poly_indices;
int *loop_indices;
int num_pidx, num_lidx;
@ -1106,27 +1038,62 @@ static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges,
r_island_store, MISLAND_TYPE_LOOP, totloop, MISLAND_TYPE_POLY, MISLAND_TYPE_EDGE);
BKE_mesh_edge_poly_map_create(
&edge_poly_map, &edge_poly_mem, edges, totedge, polys, totpoly, loops, totloop);
&edge_poly_map, &edge_poly_mem, totedge, polys, totpoly, loops, totloop);
if (luvs) {
BKE_mesh_edge_loop_map_create(
&edge_loop_map, &edge_loop_mem, edges, totedge, polys, totpoly, loops, totloop);
edge_boundary_check_data.loops = loops;
edge_boundary_check_data.luvs = luvs;
edge_boundary_check_data.edge_loop_map = edge_loop_map;
&edge_loop_map, &edge_loop_mem, totedge, polys, totpoly, loops, totloop);
}
poly_edge_loop_islands_calc(edges,
totedge,
polys,
totpoly,
loops,
totloop,
nullptr,
/* TODO: I'm not sure edge seam flag is enough to define UV islands?
* Maybe we should also consider UV-maps values
* themselves (i.e. different UV-edges for a same mesh-edge => boundary edge too?).
* Would make things much more complex though,
* and each UVMap would then need its own mesh mapping, not sure we want that at all!
*/
auto mesh_check_island_boundary_uv = [&](const int /*poly_index*/,
const int loop_index,
const int edge_index,
const int /*edge_user_count*/,
const MeshElemMap & /*edge_poly_map_elem*/) -> bool {
if (luvs) {
const MeshElemMap &edge_to_loops = edge_loop_map[loops[loop_index].e];
BLI_assert(edge_to_loops.count >= 2 && (edge_to_loops.count % 2) == 0);
const uint v1 = loops[edge_to_loops.indices[0]].v;
const uint v2 = loops[edge_to_loops.indices[1]].v;
const float *uvco_v1 = luvs[edge_to_loops.indices[0]];
const float *uvco_v2 = luvs[edge_to_loops.indices[1]];
for (int i = 2; i < edge_to_loops.count; i += 2) {
if (loops[edge_to_loops.indices[i]].v == v1) {
if (!equals_v2v2(uvco_v1, luvs[edge_to_loops.indices[i]]) ||
!equals_v2v2(uvco_v2, luvs[edge_to_loops.indices[i + 1]])) {
return true;
}
}
else {
BLI_assert(loops[edge_to_loops.indices[i]].v == v2);
UNUSED_VARS_NDEBUG(v2);
if (!equals_v2v2(uvco_v2, luvs[edge_to_loops.indices[i]]) ||
!equals_v2v2(uvco_v1, luvs[edge_to_loops.indices[i + 1]])) {
return true;
}
}
}
return false;
}
/* Edge is UV boundary if tagged as seam. */
return (edges[edge_index].flag & ME_SEAM) != 0;
};
poly_edge_loop_islands_calc(totedge,
{polys, totpoly},
{loops, totloop},
edge_poly_map,
false,
mesh_check_island_boundary_uv,
luvs ? &edge_boundary_check_data : nullptr,
&poly_groups,
&num_poly_groups,
&edge_borders,

View File

@ -1424,7 +1424,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
/* Needed for islands (or plain mesh) to AStar graph conversion. */
BKE_mesh_edge_poly_map_create(&edge_to_poly_map_src,
&edge_to_poly_map_src_buff,
edges_src,
num_edges_src,
polys_src,
num_polys_src,

View File

@ -230,6 +230,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
mesh->runtime->loose_edges_cache.tag_dirty();
mesh->runtime->looptris_cache.tag_dirty();
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
if (mesh->runtime->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data);
}
@ -245,6 +246,7 @@ void BKE_mesh_tag_edges_split(struct Mesh *mesh)
free_subdiv_ccg(*mesh->runtime);
mesh->runtime->loose_edges_cache.tag_dirty();
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
if (mesh->runtime->shrinkwrap_data) {
BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data);
}

View File

@ -1356,8 +1356,6 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
for (int i = 0; BLI_edgesetIterator_isDone(ehi) == false;
BLI_edgesetIterator_step(ehi), i++, med++, index++) {
BLI_edgesetIterator_getKey(ehi, &med->v1, &med->v2);
med->flag = ME_EDGEDRAW;
*index = ORIGINDEX_NONE;
}
BLI_edgesetIterator_free(ehi);

View File

@ -350,7 +350,7 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
BKE_mesh_calc_normals_split(subdiv_mesh);
}
if (subdiv != runtime_data->subdiv_cpu && subdiv != runtime_data->subdiv_gpu) {
if (!ELEM(subdiv, runtime_data->subdiv_cpu, runtime_data->subdiv_gpu)) {
BKE_subdiv_free(subdiv);
}

View File

@ -2342,8 +2342,10 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree,
node_dst->typeinfo->copyfunc_api(&ptr, &node_src);
}
/* Reset the declaration of the new node. */
nodeDeclarationEnsure(dst_tree, node_dst);
/* Reset the declaration of the new node in real tree. */
if (dst_tree != nullptr) {
nodeDeclarationEnsure(dst_tree, node_dst);
}
return node_dst;
}
@ -3455,21 +3457,41 @@ bNode *ntreeFindType(bNodeTree *ntree, int type)
return nullptr;
}
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
static bool ntree_contains_tree_exec(const bNodeTree *tree_to_search_in,
const bNodeTree *tree_to_search_for,
Set<const bNodeTree *> &already_passed)
{
if (ntree == lookup) {
if (tree_to_search_in == tree_to_search_for) {
return true;
}
for (const bNode *node : ntree->all_nodes()) {
if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
if (ntreeHasTree((bNodeTree *)node->id, lookup)) {
return true;
}
tree_to_search_in->ensure_topology_cache();
for (const bNode *node_group : tree_to_search_in->group_nodes()) {
const bNodeTree *sub_tree_search_in = reinterpret_cast<const bNodeTree *>(node_group->id);
if (!sub_tree_search_in) {
continue;
}
if (!already_passed.add(sub_tree_search_in)) {
continue;
}
if (ntree_contains_tree_exec(sub_tree_search_in, tree_to_search_for, already_passed)) {
return true;
}
}
return false;
}
bool ntreeContainsTree(const bNodeTree *tree_to_search_in, const bNodeTree *tree_to_search_for)
{
if (tree_to_search_in == tree_to_search_for) {
return true;
}
Set<const bNodeTree *> already_passed;
return ntree_contains_tree_exec(tree_to_search_in, tree_to_search_for, already_passed);
}
bNodeLink *nodeFindLink(bNodeTree *ntree, const bNodeSocket *from, const bNodeSocket *to)
{
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
@ -3617,6 +3639,8 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *ntree, bNode *node)
return false;
}
if (node->typeinfo->declare_dynamic) {
BLI_assert(ntree != nullptr);
BLI_assert(node != nullptr);
node->runtime->declaration = new blender::nodes::NodeDeclaration();
blender::nodes::build_node_declaration_dynamic(*ntree, *node, *node->runtime->declaration);
return true;

View File

@ -117,7 +117,7 @@ struct DupliContext {
* decisions. However, new code uses geometry instances in places that weren't using the dupli
* system previously. To fix this, keep track of the last dupli generator type that wasn't a
* geometry set instance.
* */
*/
Vector<short> *dupli_gen_type_stack;
int persistent_id[MAX_DUPLI_RECUR];

View File

@ -222,9 +222,9 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
j1 = j1 % oc->_N;
# define BILERP(m) \
(interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \
interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \
frac_z))
interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \
interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \
frac_z)
{
if (oc->_do_disp_y) {

View File

@ -590,7 +590,7 @@ static void initialize_all_particles(ParticleSimulationData *sim)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
/* Grid distributionsets UNEXIST flag, need to take care of
/* Grid distribution-sets UNEXIST flag, need to take care of
* it here because later this flag is being reset.
*
* We can't do it for any distribution, because it'll then
@ -1931,7 +1931,7 @@ static void sphclassical_density_accum_cb(void *userdata,
return;
}
/* Smoothing factor. Utilize the Wendland kernel. gnuplot:
/* Smoothing factor. Utilize the Wendland kernel. `gnuplot`:
* q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x)
* plot [0:2] q1(x) */
q = qfac / pow3f(pfr->h) * pow4f(2.0f - rij_h) * (1.0f + 2.0f * rij_h);
@ -2021,7 +2021,7 @@ static void sphclassical_force_cb(void *sphdata_v,
NULL, psys, state->co, &pfr, interaction_radius, sphclassical_neighbor_accum_cb);
pressure = stiffness * (pow7f(pa->sphdensity / rest_density) - 1.0f);
/* multiply by mass so that we return a force, not accel */
/* Multiply by mass so that we return a force, not acceleration. */
qfac2 *= sphdata->mass / pow3f(pfr.h);
pfn = pfr.neighbors;
@ -2047,7 +2047,7 @@ static void sphclassical_force_cb(void *sphdata_v,
npressure = stiffness * (pow7f(npa->sphdensity / rest_density) - 1.0f);
/* First derivative of smoothing factor. Utilize the Wendland kernel.
* gnuplot:
* `gnuplot`:
* q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x)
* plot [0:2] q2(x)
* Particles > 2h away are excluded above. */
@ -2438,15 +2438,17 @@ static float nr_distance_to_vert(float *p,
{
return len_v3v3(p, pce->x0) - radius;
}
/**
* \param t: is the current time for newton rhapson.
* \param fac: is the starting factor for current collision iteration.
* \param col: The particle collision, `col->fac's` are factors for the
* particle sub-frame step start and end during collision modifier step.
*/
static void collision_interpolate_element(ParticleCollisionElement *pce,
float t,
float fac,
ParticleCollision *col)
{
/* t is the current time for newton rhapson */
/* fac is the starting factor for current collision iteration */
/* The col->fac's are factors for the particle subframe step start
* and end during collision modifier step. */
float f = fac + t * (1.0f - fac);
float mul = col->fac1 + f * (col->fac2 - col->fac1);
if (pce->tot > 0) {
@ -3598,19 +3600,21 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
psys_sim_data_free(sim);
}
/* Code for an adaptive time step based on the Courant-Friedrichs-Lewy
* condition. */
/** Code for an adaptive time step based on the Courant-Friedrichs-Lewy condition. */
static const float MIN_TIMESTEP = 1.0f / 101.0f;
/* Tolerance of 1.5 means the last subframe neither favors growing nor
* shrinking (e.g if it were 1.3, the last subframe would tend to be too
* small). */
/**
* Tolerance of 1.5 means the last sub-frame neither favors growing nor shrinking
* (e.g if it were 1.3, the last sub-frame would tend to be too small).
*/
static const float TIMESTEP_EXPANSION_FACTOR = 0.1f;
static const float TIMESTEP_EXPANSION_TOLERANCE = 1.5f;
/* Calculate the speed of the particle relative to the local scale of the
/**
* Calculate the speed of the particle relative to the local scale of the
* simulation. This should be called once per particle during a simulation
* step, after the velocity has been updated. element_size defines the scale of
* the simulation, and is typically the distance to neighboring particles. */
* the simulation, and is typically the distance to neighboring particles.
*/
static void update_courant_num(
ParticleSimulationData *sim, ParticleData *pa, float dtime, SPHData *sphdata, SpinLock *spin)
{

View File

@ -738,7 +738,7 @@ struct EdgeQueueContext {
/* Only tagged edges are in the queue. */
#ifdef USE_EDGEQUEUE_TAG
# define EDGE_QUEUE_TEST(e) (BM_elem_flag_test((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG))
# define EDGE_QUEUE_TEST(e) BM_elem_flag_test((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)
# define EDGE_QUEUE_ENABLE(e) \
BM_elem_flag_enable((CHECK_TYPE_INLINE(e, BMEdge *), e), BM_ELEM_TAG)
# define EDGE_QUEUE_DISABLE(e) \

View File

@ -49,7 +49,7 @@ static int primitive_get_other_uv_vertex(const MeshData &mesh_data,
mesh_loops[looptri.tri[2]].v));
for (const int loop : looptri.tri) {
const int vert = mesh_loops[loop].v;
if (vert != v1 && vert != v2) {
if (!ELEM(vert, v1, v2)) {
return vert;
}
}

View File

@ -3133,10 +3133,10 @@ static void ptcache_dt_to_str(char *str, double dtime)
if (dtime > 60.0) {
if (dtime > 3600.0) {
BLI_sprintf(
str, "%ih %im %is", (int)(dtime / 3600), ((int)(dtime / 60)) % 60, ((int)dtime) % 60);
str, "%ih %im %is", (int)(dtime / 3600), (int)(dtime / 60) % 60, ((int)dtime) % 60);
}
else {
BLI_sprintf(str, "%im %is", ((int)(dtime / 60)) % 60, ((int)dtime) % 60);
BLI_sprintf(str, "%im %is", (int)(dtime / 60) % 60, ((int)dtime) % 60);
}
}
else {

View File

@ -536,6 +536,10 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags.clear();
subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags.resize(num_vertices);
if (subdiv_context->settings->use_optimal_display) {
subdiv_context->subdiv_mesh->runtime->subsurf_optimal_display_edges.clear();
subdiv_context->subdiv_mesh->runtime->subsurf_optimal_display_edges.resize(num_edges);
}
return true;
}
@ -784,15 +788,10 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
* \{ */
static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
MEdge *subdiv_edge,
const int subdiv_edge_index,
const int coarse_edge_index)
{
const int subdiv_edge_index = subdiv_edge - ctx->subdiv_edges;
if (coarse_edge_index == ORIGINDEX_NONE) {
subdiv_edge->flag = 0;
if (!ctx->settings->use_optimal_display) {
subdiv_edge->flag |= ME_EDGEDRAW;
}
if (ctx->edge_origindex != nullptr) {
ctx->edge_origindex[subdiv_edge_index] = ORIGINDEX_NONE;
}
@ -800,7 +799,9 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
}
CustomData_copy_data(
&ctx->coarse_mesh->edata, &ctx->subdiv_mesh->edata, coarse_edge_index, subdiv_edge_index, 1);
subdiv_edge->flag |= ME_EDGEDRAW;
if (ctx->settings->use_optimal_display) {
ctx->subdiv_mesh->runtime->subsurf_optimal_display_edges[subdiv_edge_index].set();
}
}
static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context,
@ -814,7 +815,7 @@ static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context,
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
MEdge *subdiv_medge = ctx->subdiv_edges;
MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index];
subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge_index);
subdiv_copy_edge_data(ctx, subdiv_edge_index, coarse_edge_index);
subdiv_edge->v1 = subdiv_v1;
subdiv_edge->v2 = subdiv_v2;
}

View File

@ -928,7 +928,6 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
int edgeSize = ccgSubSurf_getEdgeSize(ss);
uint i = 0;
short *edgeFlags = ccgdm->edgeFlags;
const short ed_interior_flag = ccgdm->drawInteriorEdges ? ME_EDGEDRAW : 0;
totface = ccgSubSurf_getNumFaces(ss);
for (index = 0; index < totface; index++) {
@ -940,7 +939,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
ccgDM_to_MEdge(&medge[i++],
getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
ed_interior_flag);
0);
}
for (x = 1; x < gridSize - 1; x++) {
@ -948,11 +947,11 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
ccgDM_to_MEdge(&medge[i++],
getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
ed_interior_flag);
0);
ccgDM_to_MEdge(&medge[i++],
getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
ed_interior_flag);
0);
}
}
}
@ -967,12 +966,9 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
if (edgeFlags) {
if (edgeIdx != -1) {
ed_flag |= ((edgeFlags[index] & ME_SEAM) | ME_EDGEDRAW);
ed_flag |= (edgeFlags[index] & ME_SEAM);
}
}
else {
ed_flag |= ME_EDGEDRAW;
}
for (x = 0; x < edgeSize - 1; x++) {
ccgDM_to_MEdge(&medge[i++],
@ -1367,7 +1363,7 @@ static void ccgdm_create_grids(DerivedMesh *dm)
gridFlagMats = static_cast<DMFlagMat *>(
MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats"));
ccgdm->gridHidden = static_cast<unsigned int **>(
ccgdm->gridHidden = static_cast<uint **>(
MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden"));
for (gIndex = 0, index = 0; index < numFaces; index++) {

View File

@ -527,7 +527,7 @@ static const AVCodec *get_av1_encoder(
if (context->ffmpeg_crf >= 0) {
/* librav1e does not use `-crf`, but uses `-qp` in the range of 0-255.
* Calculates the roughly equivalent float, and truncates it to an integer. */
unsigned int qp_value = ((float)context->ffmpeg_crf) * 255.0F / 51.0F;
uint qp_value = ((float)context->ffmpeg_crf) * 255.0f / 51.0f;
if (qp_value > 255) {
qp_value = 255;
}

View File

@ -82,7 +82,7 @@ typedef struct BLI_memiter {
BLI_INLINE uint data_offset_from_size(uint size)
{
return (PADUP(size, (uint)sizeof(data_t))) / (uint)sizeof(data_t);
return PADUP(size, (uint)sizeof(data_t)) / (uint)sizeof(data_t);
}
static void memiter_set_rewind_offset(BLI_memiter *mi)

View File

@ -12,7 +12,7 @@ namespace blender::lazy_threading {
* deadlocks.
*/
using HintReceivers = RawStack<RawVector<FunctionRef<void()>, 0>, 0>;
thread_local HintReceivers hint_receivers = []() {
static thread_local HintReceivers hint_receivers = []() {
HintReceivers receivers;
/* Make sure there is always at least one vector. */
receivers.push_as();

View File

@ -257,7 +257,7 @@ void shuffle_m4(float R[4][4], const int index[4])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
{
if (R == A || R == B) {
if (ELEM(R, A, B)) {
float T[4][4];
mul_m4_m4m4(T, A, B);
copy_m4_m4(R, T);
@ -359,7 +359,7 @@ void mul_m3_m3_post(float R[3][3], const float B[3][3])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
{
if (R == A || R == B) {
if (ELEM(R, A, B)) {
float T[3][3];
mul_m3_m3m3(T, A, B);
copy_m3_m3(R, T);

View File

@ -3779,15 +3779,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 305, 1)) {
/* Reset edge visibility flag, since the base is meant to be "true" for original meshes. */
LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
for (MEdge &edge : mesh->edges_for_write()) {
edge.flag |= ME_EDGEDRAW;
}
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 305, 2)) {
LISTBASE_FOREACH (MovieClip *, clip, &bmain->movieclips) {
MovieTracking *tracking = &clip->tracking;
@ -3901,6 +3892,21 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 305, 9)) {
/* Enable legacy normal and rotation outputs in Distribute Points on Faces node. */
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
if (ntree->type != NTREE_GEOMETRY) {
continue;
}
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type != GEO_NODE_DISTRIBUTE_POINTS_ON_FACES) {
continue;
}
node->custom2 = true;
}
}
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@ -1467,7 +1467,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
for (me = bmain->meshes.first; me; me = me->id.next) {
if (!me->medge) {
BKE_mesh_calc_edges_legacy(me, true); /* true = use #MFace.edcode. */
BKE_mesh_calc_edges_legacy(me);
}
else {
BKE_mesh_strip_loose_faces(me);

View File

@ -113,7 +113,7 @@ using blender::StringRef;
static char bm_edge_flag_from_mflag(const short mflag)
{
return ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0);
return ((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | BM_ELEM_DRAW;
}
static char bm_face_flag_from_mflag(const char mflag)
{
@ -124,7 +124,7 @@ static short bm_edge_flag_to_mflag(const BMEdge *e)
{
const char hflag = e->head.hflag;
return ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0);
return (hflag & BM_ELEM_SEAM) ? ME_SEAM : 0;
}
static char bm_face_flag_to_mflag(const BMFace *f)
{
@ -133,6 +133,20 @@ static char bm_face_flag_to_mflag(const BMFace *f)
return ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0);
}
bool BM_attribute_stored_in_bmesh_builtin(const StringRef name)
{
return ELEM(name,
"position",
".hide_vert",
".hide_edge",
".hide_poly",
".select_vert",
".select_edge",
".select_poly",
"material_index",
"sharp_edge");
}
/* Static function for alloc (duplicate in modifiers_bmesh.c) */
static BMFace *bm_face_create_from_mpoly(BMesh &bm,
Span<MLoop> loops,
@ -1420,15 +1434,6 @@ static void bm_to_mesh_edges(const BMesh &bm,
dst_edge.v1 = BM_elem_index_get(src_edge.v1);
dst_edge.v2 = BM_elem_index_get(src_edge.v2);
dst_edge.flag = bm_edge_flag_to_mflag(&src_edge);
/* Handle this differently to editmode switching; only enable draw for single user
* edges rather than calculating angle. */
if ((dst_edge.flag & ME_EDGEDRAW) == 0) {
if (src_edge.l && src_edge.l == src_edge.l->radial_next) {
dst_edge.flag |= ME_EDGEDRAW;
}
}
CustomData_from_bmesh_block(&bm.edata, &mesh.edata, src_edge.head.data, edge_i);
}
if (!select_edge.is_empty()) {

View File

@ -9,6 +9,16 @@
#include "bmesh.h"
#ifdef __cplusplus
# include "BLI_string_ref.hh"
/**
* \return Whether attributes with the given name are stored in special flags or fields in BMesh
* rather than in the regular custom data blocks.
*/
bool BM_attribute_stored_in_bmesh_builtin(const blender::StringRef name);
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -82,7 +92,6 @@ void BM_mesh_bm_to_me(struct Main *bmain,
* - Ignore shape-keys.
* - Ignore vertex-parents.
* - Ignore selection history.
* - Uses simpler method to calculate #ME_EDGEDRAW
* - Uses #CD_MASK_DERIVEDMESH instead of #CD_MASK_MESH.
*
* \note Was `cddm_from_bmesh_ex` in 2.7x, removed `MFace` support.

View File

@ -1235,7 +1235,7 @@ void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int l
}
#define EDGE_SHARE_VERT(e1, e2) \
((ELEM((e1)[0], (e2)[0], (e2)[1])) || (ELEM((e1)[1], (e2)[0], (e2)[1])))
(ELEM((e1)[0], (e2)[0], (e2)[1]) || ELEM((e1)[1], (e2)[0], (e2)[1]))
/* do line crossing tests */
for (i = 0, i_prev = f->len - 1; i < f->len; i_prev = i++) {

View File

@ -1062,7 +1062,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
matched = 1;
for (j = 0; j < pat->len; j++) {
a = (j + i) % pat->len;
if ((!!BMO_edge_flag_test(bm, edges[a], SUBD_SPLIT)) != (!!pat->seledges[j])) {
if (!!BMO_edge_flag_test(bm, edges[a], SUBD_SPLIT) != (!!pat->seledges[j])) {
matched = 0;
break;
}
@ -1095,7 +1095,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
matched = 1;
for (b = 0; b < pat->len; b++) {
j = (b + a) % pat->len;
if ((!!BMO_edge_flag_test(bm, edges[j], SUBD_SPLIT)) != (!!pat->seledges[b])) {
if (!!BMO_edge_flag_test(bm, edges[j], SUBD_SPLIT) != (!!pat->seledges[b])) {
matched = 0;
break;
}

View File

@ -2265,7 +2265,7 @@ static void snap_to_superellipsoid(float co[3], const float super_r, bool midlin
co[2] = z;
}
#define BEV_EXTEND_EDGE_DATA_CHECK(eh, flag) (BM_elem_flag_test(eh->e, flag))
#define BEV_EXTEND_EDGE_DATA_CHECK(eh, flag) BM_elem_flag_test(eh->e, flag)
static void check_edge_data_seam_sharp_edges(BevVert *bv, int flag, bool neg)
{

View File

@ -507,7 +507,7 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata)
if (!GPU_batch_vertbuf_has(batch, vbo)) {
/* Currently, the code assumes that all objects that share the same mesh in the
* current frame also share the same mesh on other frames. */
GPU_batch_vertbuf_add_ex(batch, vbo, false);
GPU_batch_vertbuf_add(batch, vbo, false);
}
}
}

View File

@ -449,7 +449,7 @@ void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera
}
/************************************************************************
* Clipmap Distribution *
* Clip-map Distribution *
************************************************************************/
IndexRange ShadowDirectional::clipmap_level_range(const Camera &camera)
@ -593,7 +593,7 @@ void ShadowDirectional::end_sync(Light &light, const Camera &camera, float lod_b
for (int64_t i = 0; i < before_range; i++) {
tilemaps_.append(tilemap_pool.acquire());
}
/* Keep cached lods. */
/* Keep cached LOD's. */
tilemaps_.extend(cached_tilemaps);
for (int64_t i = 0; i < after_range; i++) {
tilemaps_.append(tilemap_pool.acquire());
@ -1044,7 +1044,7 @@ void ShadowModule::debug_end_sync()
debug_draw_ps_.state_set(state);
debug_draw_ps_.shader_set(inst_.shaders.static_shader_get(SHADOW_DEBUG));
debug_draw_ps_.push_constant("debug_mode", (int)inst_.debug_mode);
debug_draw_ps_.push_constant("debug_mode", int(inst_.debug_mode));
debug_draw_ps_.push_constant("debug_tilemap_index", light.tilemap_index);
debug_draw_ps_.bind_ssbo("tilemaps_buf", &tilemap_pool.tilemaps_data);
debug_draw_ps_.bind_ssbo("tiles_buf", &tilemap_pool.tiles_data);

View File

@ -268,7 +268,7 @@ class ShadowModule {
/** \name Debugging
* \{ */
/** Display informations about the virtual shadows. */
/** Display information about the virtual shadows. */
PassSimple debug_draw_ps_ = {"Shadow.Debug"};
/** \} */

View File

@ -904,10 +904,10 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in
/* Create the batches */
cache->edit_points_batch = GPU_batch_create(GPU_PRIM_POINTS, cache->vbo, nullptr);
GPU_batch_vertbuf_add(cache->edit_points_batch, cache->edit_vbo);
GPU_batch_vertbuf_add(cache->edit_points_batch, cache->edit_vbo, false);
cache->edit_lines_batch = GPU_batch_create(GPU_PRIM_LINE_STRIP, cache->vbo, nullptr);
GPU_batch_vertbuf_add(cache->edit_lines_batch, cache->edit_vbo);
GPU_batch_vertbuf_add(cache->edit_lines_batch, cache->edit_vbo, false);
}
/* Curve Handles and Points for Editing. */
@ -941,11 +941,11 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in
cache->edit_curve_handles_batch = GPU_batch_create(
GPU_PRIM_LINES, cache->edit_curve_vbo, nullptr);
GPU_batch_vertbuf_add(cache->edit_curve_handles_batch, cache->edit_curve_vbo);
GPU_batch_vertbuf_add(cache->edit_curve_handles_batch, cache->edit_curve_vbo, false);
cache->edit_curve_points_batch = GPU_batch_create(
GPU_PRIM_POINTS, cache->edit_curve_vbo, nullptr);
GPU_batch_vertbuf_add(cache->edit_curve_points_batch, cache->edit_curve_vbo);
GPU_batch_vertbuf_add(cache->edit_curve_points_batch, cache->edit_curve_vbo, false);
}
gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;

View File

@ -197,7 +197,7 @@ static void drw_volume_wireframe_cb(
GPU_PRIM_LINES, cache->face_wire.pos_nor_in_order, ibo, GPU_BATCH_OWNS_INDEX);
}
GPU_batch_vertbuf_add_ex(cache->face_wire.batch, vbo_wiredata, true);
GPU_batch_vertbuf_add(cache->face_wire.batch, vbo_wiredata, true);
}
GPUBatch *DRW_volume_batch_cache_get_wireframes_face(Volume *volume)

View File

@ -71,7 +71,7 @@ BLI_INLINE void DRW_vbo_request(GPUBatch *batch, GPUVertBuf **vbo)
}
if (batch != NULL) {
/* HACK we set VBO's that may not yet be valid. */
GPU_batch_vertbuf_add(batch, *vbo);
GPU_batch_vertbuf_add(batch, *vbo, false);
}
}

View File

@ -226,11 +226,11 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist)
GPU_batch_copy(batch, geom);
if (inst_batch != NULL) {
for (int i = 0; i < GPU_BATCH_INST_VBO_MAX_LEN && inst_batch->verts[i]; i++) {
GPU_batch_instbuf_add_ex(batch, inst_batch->verts[i], false);
GPU_batch_instbuf_add(batch, inst_batch->verts[i], false);
}
}
else {
GPU_batch_instbuf_add_ex(batch, inst_buf, false);
GPU_batch_instbuf_add(batch, inst_buf, false);
}
/* Add reference to avoid comparing pointers (in DRW_temp_batch_request) that could
* potentially be the same. This will delay the freeing of the GPUVertBuf itself. */

View File

@ -1184,7 +1184,7 @@ static void drw_engines_enable_from_engine(const RenderEngineType *engine_type,
case OB_WIRE:
case OB_SOLID:
if (U.experimental.enable_workbench_next &&
strcmp(engine_type->idname, "BLENDER_WORKBENCH_NEXT") == 0) {
STREQ(engine_type->idname, "BLENDER_WORKBENCH_NEXT")) {
use_drw_engine(DRW_engine_viewport_workbench_next_type.draw_engine);
break;
}

View File

@ -1303,10 +1303,10 @@ struct PBVHBatches {
int vbo_i = get_vbo_index(vbo);
batch.vbos.append(vbo_i);
GPU_batch_vertbuf_add_ex(batch.tris, vbo->vert_buf, false);
GPU_batch_vertbuf_add(batch.tris, vbo->vert_buf, false);
if (batch.lines) {
GPU_batch_vertbuf_add_ex(batch.lines, vbo->vert_buf, false);
GPU_batch_vertbuf_add(batch.lines, vbo->vert_buf, false);
}
}

View File

@ -60,15 +60,8 @@ static void extract_edge_fac_init(const MeshRenderData *mr,
if (mr->extract_type == MR_EXTRACT_MESH) {
data->edge_loop_count = MEM_cnew_array<uint8_t>(mr->edge_len, __func__);
/* HACK(@fclem): Detecting the need for edge render.
* We could have a flag in the mesh instead or check the modifier stack. */
const MEdge *med = mr->medge;
for (int e_index = 0; e_index < mr->edge_len; e_index++, med++) {
if ((med->flag & ME_EDGEDRAW) == 0) {
data->use_edge_render = true;
break;
}
if (!mr->me->runtime->subsurf_optimal_display_edges.is_empty()) {
data->use_edge_render = true;
}
}
else {
@ -109,6 +102,7 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_EdgeFac_Data *data = static_cast<MeshExtract_EdgeFac_Data *>(_data);
const BitVector<> &optimal_display_edges = mr->me->runtime->subsurf_optimal_display_edges;
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
@ -116,8 +110,7 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr,
const MLoop *ml = &mloop[ml_index];
if (data->use_edge_render) {
const MEdge *med = &mr->medge[ml->e];
data->vbo_data[ml_index] = (med->flag & ME_EDGEDRAW) ? 255 : 0;
data->vbo_data[ml_index] = optimal_display_edges[ml->e] ? 255 : 0;
}
else {

View File

@ -4373,6 +4373,53 @@ static bool achannel_is_being_renamed(const bAnimContext *ac,
return false;
}
float ANIM_UI_get_keyframe_scale_factor(void)
{
bTheme *btheme = UI_GetTheme();
const float yscale_fac = btheme->space_action.keyframe_scale_fac;
/* clamp to avoid problems with uninitialized values... */
if (yscale_fac < 0.1f) {
return 1.0f;
}
return yscale_fac;
}
float ANIM_UI_get_channel_height(void)
{
return 0.8f * ANIM_UI_get_keyframe_scale_factor() * U.widget_unit;
}
float ANIM_UI_get_channel_skip(void)
{
return 0.1f * U.widget_unit;
}
float ANIM_UI_get_first_channel_top(View2D *v2d)
{
return UI_view2d_scale_get_y(v2d) * -UI_TIME_SCRUB_MARGIN_Y - ANIM_UI_get_channel_skip();
}
float ANIM_UI_get_channel_step(void)
{
return ANIM_UI_get_channel_height() + ANIM_UI_get_channel_skip();
}
float ANIM_UI_get_channels_total_height(View2D *v2d, const int item_count)
{
return -ANIM_UI_get_first_channel_top(v2d) + ANIM_UI_get_channel_step() * (item_count + 1);
}
float ANIM_UI_get_channel_name_width(void)
{
return 10 * U.widget_unit;
}
float ANIM_UI_get_channel_button_width(void)
{
return 0.8f * U.widget_unit;
}
void ANIM_channel_draw(
bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc, size_t channel_index)
{
@ -4566,7 +4613,8 @@ void ANIM_channel_draw(
}
/* check if there's enough space for the toggles if the sliders are drawn too */
if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2)) {
if (!(draw_sliders) ||
(BLI_rcti_size_x(&v2d->mask) > ANIM_UI_get_channel_button_width() / 2)) {
/* protect... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
offset += ICON_WIDTH;
@ -5279,7 +5327,8 @@ void ANIM_channel_draw_widgets(const bContext *C,
}
/* check if there's enough space for the toggles if the sliders are drawn too */
if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2)) {
if (!(draw_sliders) ||
(BLI_rcti_size_x(&v2d->mask) > ANIM_UI_get_channel_button_width() / 2)) {
/* protect... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
offset -= ICON_WIDTH;

View File

@ -2718,7 +2718,7 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm
ymax = NLACHANNEL_FIRST_TOP(ac);
}
else {
ymax = ACHANNEL_FIRST_TOP(ac);
ymax = ANIM_UI_get_first_channel_top(v2d);
}
/* loop over data, doing box select */
@ -2726,7 +2726,7 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm
float ymin;
if (ale->type == ANIMTYPE_GPDATABLOCK) {
ymax -= ACHANNEL_STEP(ac);
ymax -= ANIM_UI_get_channel_step();
continue;
}
@ -2734,7 +2734,7 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm
ymin = ymax - NLACHANNEL_STEP(snla);
}
else {
ymin = ymax - ACHANNEL_STEP(ac);
ymin = ymax - ANIM_UI_get_channel_step();
}
/* if channel is within border-select region, alter it */
@ -2948,10 +2948,10 @@ static int animchannels_channel_get(bAnimContext *ac, const int mval[2])
&channel_index);
}
else {
UI_view2d_listview_view_to_cell(ACHANNEL_NAMEWIDTH,
ACHANNEL_STEP(ac),
UI_view2d_listview_view_to_cell(ANIM_UI_get_channel_name_width(),
ANIM_UI_get_channel_step(),
0,
ACHANNEL_FIRST_TOP(ac),
ANIM_UI_get_first_channel_top(v2d),
x,
y,
NULL,
@ -3484,10 +3484,10 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE
/* figure out which channel user clicked in */
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
UI_view2d_listview_view_to_cell(ACHANNEL_NAMEWIDTH,
ACHANNEL_STEP(&ac),
UI_view2d_listview_view_to_cell(ANIM_UI_get_channel_name_width(),
ANIM_UI_get_channel_step(),
0,
ACHANNEL_FIRST_TOP(&ac),
ANIM_UI_get_first_channel_top(v2d),
x,
y,
NULL,
@ -3499,7 +3499,8 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE
/* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
return OPERATOR_FINISHED;
return WM_operator_flag_only_pass_through_on_press(OPERATOR_FINISHED | OPERATOR_PASS_THROUGH,
event);
}
static void ANIM_OT_channels_click(wmOperatorType *ot)

View File

@ -92,26 +92,6 @@
/* ************************************************************ */
/* Blender Context <-> Animation Context mapping */
/* ----------- Private Stuff - General -------------------- */
/* Get vertical scaling factor (i.e. typically used for keyframe size) */
static void animedit_get_yscale_factor(bAnimContext *ac)
{
bTheme *btheme = UI_GetTheme();
/* grab scale factor directly from action editor setting
* NOTE: This theme setting doesn't have an ID, as it cannot be accessed normally
* since it is a float, and the theme settings methods can only handle chars.
*/
ac->yscale_fac = btheme->space_action.keyframe_scale_fac;
/* clamp to avoid problems with uninitialized values... */
if (ac->yscale_fac < 0.1f) {
ac->yscale_fac = 1.0f;
}
// printf("yscale_fac = %f\n", ac->yscale_fac);
}
/* ----------- Private Stuff - Action Editor ------------- */
/* Get shapekey data being edited (for Action Editor -> ShapeKey mode) */
@ -408,9 +388,6 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->spacetype = (area) ? area->spacetype : 0;
ac->regiontype = (region) ? region->regiontype : 0;
/* Initialize default y-scale factor. */
animedit_get_yscale_factor(ac);
/* get data context info */
/* XXX: if the below fails, try to grab this info from context instead...
* (to allow for scripting). */

View File

@ -103,7 +103,7 @@ static void fmodifier_reorder(bContext *C, Panel *panel, int new_index)
const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(fcm->type);
/* Cycles modifier has to be the first, so make sure it's kept that way. */
if (fmi->requires & FMI_REQUIRES_ORIGINAL_DATA) {
if (fmi->requires_flag & FMI_REQUIRES_ORIGINAL_DATA) {
WM_report(RPT_ERROR, "Modifier requires original data");
return;
}
@ -113,7 +113,7 @@ static void fmodifier_reorder(bContext *C, Panel *panel, int new_index)
/* Again, make sure we don't move a modifier before a cycles modifier. */
FModifier *fcm_first = modifiers->first;
const FModifierTypeInfo *fmi_first = get_fmodifier_typeinfo(fcm_first->type);
if (fmi_first->requires & FMI_REQUIRES_ORIGINAL_DATA && new_index == 0) {
if (fmi_first->requires_flag & FMI_REQUIRES_ORIGINAL_DATA && new_index == 0) {
WM_report(RPT_ERROR, "Modifier requires original data");
return;
}

View File

@ -25,8 +25,11 @@ struct AssetMetaData *ED_asset_handle_get_metadata(const struct AssetHandle *ass
struct ID *ED_asset_handle_get_local_id(const struct AssetHandle *asset);
ID_Type ED_asset_handle_get_id_type(const struct AssetHandle *asset);
int ED_asset_handle_get_preview_icon_id(const struct AssetHandle *asset);
void ED_asset_handle_get_full_library_path(const struct AssetHandle *asset,
char r_full_lib_path[]);
void ED_asset_handle_get_full_library_path(
const struct AssetHandle *asset,
/* `1090` for #FILE_MAX_LIBEXTRA,
* rely on warnings to let us know if this gets out of sync. */
char r_full_lib_path[1090]);
#ifdef __cplusplus
}

View File

@ -157,6 +157,19 @@ bool curves_poll(bContext *C)
return curves_poll_impl(C, false, false, false);
}
static bool editable_curves_point_domain_poll(bContext *C)
{
if (!curves::editable_curves_poll(C)) {
return false;
}
const Curves *curves_id = static_cast<const Curves *>(CTX_data_active_object(C)->data);
if (curves_id->selection_domain != ATTR_DOMAIN_POINT) {
CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode");
return false;
}
return true;
}
using bke::CurvesGeometry;
namespace convert_to_particle_system {
@ -931,19 +944,6 @@ static void CURVES_OT_select_random(wmOperatorType *ot)
1.0f);
}
static bool select_end_poll(bContext *C)
{
if (!curves::editable_curves_poll(C)) {
return false;
}
const Curves *curves_id = static_cast<const Curves *>(CTX_data_active_object(C)->data);
if (curves_id->selection_domain != ATTR_DOMAIN_POINT) {
CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode");
return false;
}
return true;
}
static int select_end_exec(bContext *C, wmOperator *op)
{
VectorSet<Curves *> unique_curves = curves::get_unique_editable_curves(*C);
@ -952,7 +952,7 @@ static int select_end_exec(bContext *C, wmOperator *op)
for (Curves *curves_id : unique_curves) {
CurvesGeometry &curves = curves_id->geometry.wrap();
select_ends(curves, eAttrDomain(curves_id->selection_domain), amount, end_points);
select_ends(curves, amount, end_points);
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
* attribute for now. */
@ -970,7 +970,7 @@ static void CURVES_OT_select_end(wmOperatorType *ot)
ot->description = "Select end points of curves";
ot->exec = select_end_exec;
ot->poll = select_end_poll;
ot->poll = editable_curves_point_domain_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@ -983,6 +983,33 @@ static void CURVES_OT_select_end(wmOperatorType *ot)
ot->srna, "amount", 1, 0, INT32_MAX, "Amount", "Number of points to select", 0, INT32_MAX);
}
static int select_linked_exec(bContext *C, wmOperator * /*op*/)
{
VectorSet<Curves *> unique_curves = get_unique_editable_curves(*C);
for (Curves *curves_id : unique_curves) {
CurvesGeometry &curves = curves_id->geometry.wrap();
select_linked(curves);
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
* attribute for now. */
DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id);
}
return OPERATOR_FINISHED;
}
static void CURVES_OT_select_linked(wmOperatorType *ot)
{
ot->name = "Select Linked";
ot->idname = __func__;
ot->description = "Select all points in curves with any point selection";
ot->exec = select_linked_exec;
ot->poll = editable_curves_point_domain_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
namespace surface_set {
static bool surface_set_poll(bContext *C)
@ -1078,6 +1105,7 @@ void ED_operatortypes_curves()
WM_operatortype_append(CURVES_OT_select_all);
WM_operatortype_append(CURVES_OT_select_random);
WM_operatortype_append(CURVES_OT_select_end);
WM_operatortype_append(CURVES_OT_select_linked);
WM_operatortype_append(CURVES_OT_surface_set);
}

View File

@ -6,7 +6,9 @@
#include "BLI_array_utils.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_lasso_2d.h"
#include "BLI_rand.hh"
#include "BLI_rect.h"
#include "BKE_attribute.hh"
#include "BKE_crazyspace.hh"
@ -163,6 +165,21 @@ bool has_anything_selected(const bke::CurvesGeometry &curves)
return !selection || contains(selection, true);
}
bool has_anything_selected(const GSpan selection)
{
if (selection.type().is<bool>()) {
return selection.typed<bool>().contains(true);
}
else if (selection.type().is<float>()) {
for (const float elem : selection.typed<float>()) {
if (elem > 0.0f) {
return true;
}
}
}
return false;
}
static void invert_selection(MutableSpan<float> selection)
{
threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) {
@ -202,14 +219,12 @@ void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain,
}
}
void select_ends(bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
int amount,
bool end_points)
void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points)
{
const bool was_anything_selected = has_anything_selected(curves);
const OffsetIndices points_by_curve = curves.points_by_curve();
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL);
if (!was_anything_selected) {
fill_selection_true(selection.span);
}
@ -222,7 +237,6 @@ void select_ends(bke::CurvesGeometry &curves,
MutableSpan<T> selection_typed = selection.span.typed<T>();
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
for (const int curve_i : range) {
const OffsetIndices points_by_curve = curves.points_by_curve();
if (end_points) {
selection_typed.slice(points_by_curve[curve_i].drop_back(amount)).fill(T(0));
}
@ -236,6 +250,23 @@ void select_ends(bke::CurvesGeometry &curves,
selection.finish();
}
void select_linked(bke::CurvesGeometry &curves)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL);
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
for (const int curve_i : range) {
GMutableSpan selection_curve = selection.span.slice(points_by_curve[curve_i]);
if (has_anything_selected(selection_curve)) {
fill_selection_true(selection_curve);
}
}
});
selection.finish();
}
void select_random(bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
uint32_t random_seed,
@ -285,6 +316,46 @@ void select_random(bke::CurvesGeometry &curves,
selection.finish();
}
static void apply_selection_operation_at_index(GMutableSpan selection,
const int index,
const eSelectOp sel_op)
{
if (selection.type().is<bool>()) {
MutableSpan<bool> selection_typed = selection.typed<bool>();
switch (sel_op) {
case SEL_OP_ADD:
case SEL_OP_SET:
selection_typed[index] = true;
break;
case SEL_OP_SUB:
selection_typed[index] = false;
break;
case SEL_OP_XOR:
selection_typed[index] ^= selection_typed[index];
break;
default:
break;
}
}
else if (selection.type().is<float>()) {
MutableSpan<float> selection_typed = selection.typed<float>();
switch (sel_op) {
case SEL_OP_ADD:
case SEL_OP_SET:
selection_typed[index] = 1.0f;
break;
case SEL_OP_SUB:
selection_typed[index] = 0.0f;
break;
case SEL_OP_XOR:
selection_typed[index] = 1.0f - selection_typed[index];
break;
default:
break;
}
}
}
/**
* Helper struct for `find_closest_point_to_screen_co`.
*/
@ -356,7 +427,7 @@ bool select_pick(const ViewContext &vc,
bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
const SelectPick_Params &params,
const int2 mval)
const int2 coord)
{
FindClosestPointData closest_point;
bool found = find_closest_point_to_screen_co(*vc.depsgraph,
@ -364,7 +435,7 @@ bool select_pick(const ViewContext &vc,
vc.rv3d,
*vc.obact,
curves,
float2(mval),
float2(coord),
ED_view3d_select_dist_px(),
closest_point);
@ -392,33 +463,188 @@ bool select_pick(const ViewContext &vc,
elem_index = std::distance(curves.offsets().begin(), it) - 1;
}
selection.span.type().to_static_type_tag<bool, float>([&](auto type_tag) {
using T = typename decltype(type_tag)::type;
if constexpr (std::is_void_v<T>) {
BLI_assert_unreachable();
}
else {
MutableSpan<T> selection_typed = selection.span.typed<T>();
switch (params.sel_op) {
case SEL_OP_ADD:
case SEL_OP_SET:
selection_typed[elem_index] = T(1);
break;
case SEL_OP_SUB:
selection_typed[elem_index] = T(0);
break;
case SEL_OP_XOR:
selection_typed[elem_index] = T(1 - selection_typed[elem_index]);
break;
default:
break;
}
}
});
apply_selection_operation_at_index(selection.span, elem_index, params.sel_op);
selection.finish();
}
return changed || found;
}
bool select_box(const ViewContext &vc,
bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
const rcti &rect,
const eSelectOp sel_op)
{
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
bool changed = false;
if (sel_op == SEL_OP_SET) {
fill_selection_false(selection.span);
changed = true;
}
float4x4 projection;
ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr());
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact);
const OffsetIndices points_by_curve = curves.points_by_curve();
if (selection_domain == ATTR_DOMAIN_POINT) {
threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) {
for (const int point_i : point_range) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) {
apply_selection_operation_at_index(selection.span, point_i, sel_op);
changed = true;
}
}
});
}
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}
}
});
}
selection.finish();
return changed;
}
bool select_lasso(const ViewContext &vc,
bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
const Span<int2> coords,
const eSelectOp sel_op)
{
rcti bbox;
const int(*coord_array)[2] = reinterpret_cast<const int(*)[2]>(coords.data());
BLI_lasso_boundbox(&bbox, coord_array, coords.size());
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
bool changed = false;
if (sel_op == SEL_OP_SET) {
fill_selection_false(selection.span);
changed = true;
}
float4x4 projection;
ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr());
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact);
const OffsetIndices points_by_curve = curves.points_by_curve();
if (selection_domain == ATTR_DOMAIN_POINT) {
threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) {
for (const int point_i : point_range) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(
coord_array, coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED)) {
apply_selection_operation_at_index(selection.span, point_i, sel_op);
changed = true;
}
}
});
}
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(
coord_array, coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED)) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}
}
});
}
selection.finish();
return changed;
}
bool select_circle(const ViewContext &vc,
bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
const int2 coord,
const float radius,
const eSelectOp sel_op)
{
const float radius_sq = pow2f(radius);
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
bool changed = false;
if (sel_op == SEL_OP_SET) {
fill_selection_false(selection.span);
changed = true;
}
float4x4 projection;
ED_view3d_ob_project_mat_get(vc.rv3d, vc.obact, projection.ptr());
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*vc.depsgraph, *vc.obact);
const OffsetIndices points_by_curve = curves.points_by_curve();
if (selection_domain == ATTR_DOMAIN_POINT) {
threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) {
for (const int point_i : point_range) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) {
apply_selection_operation_at_index(selection.span, point_i, sel_op);
changed = true;
}
}
});
}
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}
}
});
}
selection.finish();
return changed;
}
} // namespace blender::ed::curves

View File

@ -735,7 +735,7 @@ static void gpencil_create_extensions_radius(tGPDfill *tgpf)
float tan2[3];
float d1;
float d2;
float total_length = 0.f;
float total_length = 0.0f;
for (int i = 1; i < gps->totpoints; i++) {
if (i > 1) {
copy_v3_v3(tan1, tan2);
@ -751,7 +751,7 @@ static void gpencil_create_extensions_radius(tGPDfill *tgpf)
sub_v3_v3v3(curvature, tan2, tan1);
float k = normalize_v3(curvature);
k /= min_ff(d1, d2);
float radius = 1.f / k;
float radius = 1.0f / k;
/*
* The smaller the radius of curvature, the sharper the corner.
* The thicker the line, the larger the radius of curvature it

View File

@ -3327,6 +3327,14 @@ void ED_gpencil_layer_merge(bGPdata *gpd,
gpf_dst->key_type = gpf_src->key_type;
BLI_ghash_insert(gh_frames_dst, POINTER_FROM_INT(gpf_src->framenum), gpf_dst);
}
/* Copy current source frame to further frames
* that are keyframes in destination layer and not in source layer
* to keep the image equals. */
if (gpf_dst->next && (!gpf_src->next || (gpf_dst->next->framenum < gpf_src->next->framenum))) {
gpf_dst = gpf_dst->next;
BKE_gpencil_layer_frame_get(gpl_src, gpf_dst->framenum, GP_GETFRAME_ADD_COPY);
}
}
/* Read all frames from merge layer and add strokes. */

View File

@ -94,8 +94,6 @@ typedef struct bAnimContext {
/** pointer to current reports list */
struct ReportList *reports;
/** Scale factor for height of channels (i.e. based on the size of keyframes). */
float yscale_fac;
} bAnimContext;
/* Main Data container types */
@ -430,28 +428,6 @@ ENUM_OPERATORS(eAnimFilter_Flags, ANIMFILTER_TMP_IGNORE_ONLYSEL);
/** \} */
/* -------------------------------------------------------------------- */
/** \name Channel Defines
* \{ */
/** Channel heights. */
#define ACHANNEL_FIRST_TOP(ac) \
(UI_view2d_scale_get_y(&(ac)->region->v2d) * -UI_TIME_SCRUB_MARGIN_Y - ACHANNEL_SKIP)
#define ACHANNEL_HEIGHT(ac) (0.8f * (ac)->yscale_fac * U.widget_unit)
#define ACHANNEL_SKIP (0.1f * U.widget_unit)
#define ACHANNEL_STEP(ac) (ACHANNEL_HEIGHT(ac) + ACHANNEL_SKIP)
/** Additional offset to give some room at the end. */
#define ACHANNEL_TOT_HEIGHT(ac, item_amount) \
(-ACHANNEL_FIRST_TOP(ac) + ACHANNEL_STEP(ac) * (item_amount + 1))
/** Channel widths. */
#define ACHANNEL_NAMEWIDTH (10 * U.widget_unit)
/** Channel toggle-buttons. */
#define ACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit)
/** \} */
/* -------------------------------------------------------------------- */
/** \name NLA Channel Defines
* \{ */
@ -612,6 +588,20 @@ typedef struct bAnimChannelType {
void *(*setting_ptr)(bAnimListElem *ale, eAnimChannel_Settings setting, short *type);
} bAnimChannelType;
/** \} */
/* -------------------------------------------------------------------- */
/** \name Channel dimensions API
* \{ */
float ANIM_UI_get_keyframe_scale_factor(void);
float ANIM_UI_get_channel_height(void);
float ANIM_UI_get_channel_skip(void);
float ANIM_UI_get_first_channel_top(View2D *v2d);
float ANIM_UI_get_channel_step(void);
float ANIM_UI_get_channels_total_height(View2D *v2d, int item_count);
float ANIM_UI_get_channel_name_width(void);
float ANIM_UI_get_channel_button_width(void);
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -11,6 +11,7 @@ struct Curves;
struct UndoType;
struct SelectPick_Params;
struct ViewContext;
struct rcti;
#ifdef __cplusplus
extern "C" {
@ -46,6 +47,8 @@ float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3]
# include "BKE_curves.hh"
# include "ED_select_utils.h"
namespace blender::ed::curves {
bool object_has_editable_curves(const Main &bmain, const Object &object);
@ -86,6 +89,11 @@ void fill_selection_true(GMutableSpan span);
*/
bool has_anything_selected(const bke::CurvesGeometry &curves);
/**
* Return true if any element in the span is selected, on either domain with either type.
*/
bool has_anything_selected(GSpan selection);
/**
* Find curves that have any point selected (a selection factor greater than zero),
* or curves that have their own selection factor greater than zero.
@ -120,10 +128,12 @@ void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain,
* \param amount: The amount of points to select from the front or back.
* \param end_points: If true, select the last point(s), if false, select the first point(s).
*/
void select_ends(bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
int amount,
bool end_points);
void select_ends(bke::CurvesGeometry &curves, int amount, bool end_points);
/**
* Select the points of all curves that have at least one point selected.
*/
void select_linked(bke::CurvesGeometry &curves);
/**
* Select random points or curves.
@ -138,14 +148,41 @@ void select_random(bke::CurvesGeometry &curves,
float probability);
/**
* Select point or curve under the cursor.
* Select point or curve at a (screen-space) point.
*/
bool select_pick(const ViewContext &vc,
bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
const SelectPick_Params &params,
const int2 mval);
const int2 coord);
/**
* Select points or curves in a (screen-space) rectangle.
*/
bool select_box(const ViewContext &vc,
bke::CurvesGeometry &curves,
const eAttrDomain selection_domain,
const rcti &rect,
const eSelectOp sel_op);
/**
* Select points or curves in a (screen-space) poly shape.
*/
bool select_lasso(const ViewContext &vc,
bke::CurvesGeometry &curves,
eAttrDomain selection_domain,
Span<int2> coords,
eSelectOp sel_op);
/**
* Select points or curves in a (screen-space) circle.
*/
bool select_circle(const ViewContext &vc,
bke::CurvesGeometry &curves,
eAttrDomain selection_domain,
int2 coord,
float radius,
eSelectOp sel_op);
/** \} */
} // namespace blender::ed::curves

View File

@ -241,6 +241,9 @@ void ED_object_parent(struct Object *ob, struct Object *parent, int type, const
char *ED_object_ot_drop_named_material_tooltip(struct bContext *C,
const char *name,
const int mval[2]);
char *ED_object_ot_drop_geometry_nodes_tooltip(struct bContext *C,
struct PointerRNA *properties,
const int mval[2]);
/* bitflags for enter/exit editmode */
enum {
@ -475,7 +478,7 @@ void ED_object_constraint_copy_for_pose(struct Main *bmain,
struct bPoseChannel *pchan,
struct bConstraint *con);
/* object_modes.c */
/* object_modes.cc */
/**
* Checks the mode to be set is compatible with the object

View File

@ -24,7 +24,7 @@ struct wmKeyConfig;
struct wmOperator;
typedef struct PaintTileMap PaintTileMap;
/* paint_ops.c */
/* paint_ops.cc */
void ED_operatortypes_paint(void);
void ED_operatormacros_paint(void);

View File

@ -19,7 +19,13 @@ struct bContext;
void ED_sequencer_select_sequence_single(struct Scene *scene,
struct Sequence *seq,
bool deselect_all);
void ED_sequencer_deselect_all(struct Scene *scene);
/**
* Iterates over a scene's sequences and deselects all of them.
*
* \param scene: scene containing sequences to be deselected.
* \return true if any sequences were deselected; false otherwise.
*/
bool ED_sequencer_deselect_all(struct Scene *scene);
bool ED_space_sequencer_maskedit_mask_poll(struct bContext *C);
bool ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene *scene);

View File

@ -18,7 +18,7 @@ struct IDRemapper;
struct Main;
struct bContext;
/* ed_util.c */
/* ed_util.cc */
void ED_editors_init_for_undo(struct Main *bmain);
void ED_editors_init(struct bContext *C);

View File

@ -1630,7 +1630,7 @@ static void icon_draw_cache_texture_flush_ex(GPUTexture *texture,
GPUBatch *quad = GPU_batch_preset_quad();
GPU_batch_set_shader(quad, shader);
GPU_batch_draw_instanced(quad, texture_draw_calls->calls);
GPU_batch_draw_instance_range(quad, 0, texture_draw_calls->calls);
GPU_texture_unbind(texture);
GPU_uniformbuf_unbind(ubo);

View File

@ -1157,7 +1157,7 @@ void UI_widgetbase_draw_cache_flush()
MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH,
(float(*)[4])g_widget_base_batch.params);
GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
GPU_batch_draw_instanced(batch, g_widget_base_batch.count);
GPU_batch_draw_instance_range(batch, 0, g_widget_base_batch.count);
}
g_widget_base_batch.count = 0;
}

View File

@ -1260,11 +1260,6 @@ static void mesh_add_edges(Mesh *mesh, int len)
mesh->totedge = totedge;
MutableSpan<MEdge> edges = mesh->edges_for_write();
for (MEdge &edge : edges.take_back(len)) {
edge.flag = ME_EDGEDRAW;
}
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
bke::SpanAttributeWriter<bool> select_edge = attributes.lookup_or_add_for_write_span<bool>(
".select_edge", ATTR_DOMAIN_EDGE);

View File

@ -44,7 +44,7 @@ set(SRC
object_facemap_ops.c
object_gpencil_modifier.c
object_hook.c
object_modes.c
object_modes.cc
object_modifier.cc
object_ops.c
object_random.c

View File

@ -3154,8 +3154,6 @@ static int object_convert_exec(bContext *C, wmOperator *op)
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
me_eval = BKE_mesh_copy_for_eval(me_eval, false);
/* Full (edge-angle based) draw calculation should ideally be performed. */
BKE_mesh_edges_set_draw_render(me_eval);
BKE_object_material_from_eval_data(bmain, newob, &me_eval->id);
Mesh *new_mesh = (Mesh *)newob->data;
BKE_mesh_nomain_to_mesh(me_eval, new_mesh, newob);

View File

@ -62,6 +62,11 @@ void OBJECT_OT_clear_override_library(struct wmOperatorType *ot);
* Assigns to object under cursor, only first material slot.
*/
void OBJECT_OT_drop_named_material(struct wmOperatorType *ot);
/**
* Used for drop-box.
* Assigns to object under cursor, creates a new geometry nodes modifier.
*/
void OBJECT_OT_drop_geometry_nodes(struct wmOperatorType *ot);
/**
* \note Only for empty-image objects, this operator is needed
*/

View File

@ -97,7 +97,7 @@ static const char *object_mode_op_string(eObjectMode mode)
if (mode == OB_MODE_SCULPT_CURVES) {
return "CURVES_OT_sculptmode_toggle";
}
return NULL;
return nullptr;
}
bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode)
@ -160,9 +160,9 @@ bool ED_object_mode_compat_set(bContext *C, Object *ob, eObjectMode mode, Report
{
bool ok;
if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) {
const char *opstring = object_mode_op_string(ob->mode);
const char *opstring = object_mode_op_string(eObjectMode(ob->mode));
WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, NULL, NULL);
WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, nullptr, nullptr);
ok = ELEM(ob->mode, mode, OB_MODE_OBJECT);
if (!ok) {
wmOperatorType *ot = WM_operatortype_find(opstring, false);
@ -194,7 +194,7 @@ bool ED_object_mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportL
BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob == NULL) {
if (ob == nullptr) {
return (mode == OB_MODE_OBJECT);
}
@ -210,13 +210,14 @@ bool ED_object_mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportL
return false;
}
const char *opstring = object_mode_op_string((mode == OB_MODE_OBJECT) ? ob->mode : mode);
const char *opstring = object_mode_op_string((mode == OB_MODE_OBJECT) ? eObjectMode(ob->mode) :
mode);
wmOperatorType *ot = WM_operatortype_find(opstring, false);
if (!use_undo) {
wm->op_undo_depth++;
}
WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_REGION_WIN, NULL, NULL);
WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_REGION_WIN, nullptr, nullptr);
if (!use_undo) {
wm->op_undo_depth--;
}
@ -232,20 +233,17 @@ bool ED_object_mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportL
bool ED_object_mode_set(bContext *C, eObjectMode mode)
{
/* Don't do undo push by default, since this may be called by lower level code. */
return ED_object_mode_set_ex(C, mode, true, NULL);
return ED_object_mode_set_ex(C, mode, true, nullptr);
}
/**
* Use for changing works-paces or changing active object.
* Caller can check #OB_MODE_ALL_MODE_DATA to test if this needs to be run.
*/
static bool ed_object_mode_generic_exit_ex(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
bool only_test)
static bool ed_object_mode_generic_exit_ex(
Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, bool only_test)
{
BLI_assert((bmain == NULL) == only_test);
BLI_assert((bmain == nullptr) == only_test);
if (ob->mode & OB_MODE_EDIT) {
if (BKE_object_is_in_editmode(ob)) {
if (only_test) {
@ -279,7 +277,7 @@ static bool ed_object_mode_generic_exit_ex(struct Main *bmain,
}
}
else if (ob->mode & OB_MODE_POSE) {
if (ob->pose != NULL) {
if (ob->pose != nullptr) {
if (only_test) {
return true;
}
@ -332,7 +330,7 @@ static void ed_object_posemode_set_for_weight_paint_ex(bContext *C,
const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
if (ob_arm != NULL) {
if (ob_arm != nullptr) {
BKE_view_layer_synced_ensure(scene, view_layer);
const Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
if (base_arm && BASE_VISIBLE(v3d, base_arm)) {
@ -387,17 +385,14 @@ void ED_object_posemode_set_for_weight_paint(bContext *C,
}
}
void ED_object_mode_generic_exit(struct Main *bmain,
struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob)
void ED_object_mode_generic_exit(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
{
ed_object_mode_generic_exit_ex(bmain, depsgraph, scene, ob, false);
}
bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, const struct Object *ob)
bool ED_object_mode_generic_has_data(Depsgraph *depsgraph, const Object *ob)
{
return ed_object_mode_generic_exit_ex(NULL, depsgraph, NULL, (Object *)ob, true);
return ed_object_mode_generic_exit_ex(nullptr, depsgraph, nullptr, (Object *)ob, true);
}
/** \} */
@ -425,7 +420,7 @@ static void object_transfer_mode_reposition_view_pivot(bContext *C, const int mv
Scene *scene = CTX_data_scene(C);
float global_loc[3];
if (!ED_view3d_autodist_simple(region, mval, global_loc, 0, NULL)) {
if (!ED_view3d_autodist_simple(region, mval, global_loc, 0, nullptr)) {
return;
}
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
@ -446,7 +441,7 @@ static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
if (base_dst == NULL) {
if (base_dst == nullptr) {
return false;
}

View File

@ -675,7 +675,6 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/,
if (k) {
medge->v1 = cvert - 1;
medge->v2 = cvert;
medge->flag = ME_EDGEDRAW;
medge++;
}
else {
@ -694,7 +693,6 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/,
if (k) {
medge->v1 = cvert - 1;
medge->v2 = cvert;
medge->flag = ME_EDGEDRAW;
medge++;
}
else {

View File

@ -262,6 +262,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_bake_image);
WM_operatortype_append(OBJECT_OT_bake);
WM_operatortype_append(OBJECT_OT_drop_named_material);
WM_operatortype_append(OBJECT_OT_drop_geometry_nodes);
WM_operatortype_append(OBJECT_OT_unlink_data);
WM_operatortype_append(OBJECT_OT_laplaciandeform_bind);

View File

@ -99,6 +99,8 @@
#include "ED_screen.h"
#include "ED_view3d.h"
#include "MOD_nodes.h"
#include "object_intern.h"
/* ------------------------------------------------------------------- */
@ -2867,6 +2869,119 @@ void OBJECT_OT_drop_named_material(wmOperatorType *ot)
/** \} */
/* ------------------------------------------------------------------- */
/** \name Drop Geometry Nodes on Object Operator
* \{ */
char *ED_object_ot_drop_geometry_nodes_tooltip(bContext *C,
PointerRNA *properties,
const int mval[2])
{
const Object *ob = ED_view3d_give_object_under_cursor(C, mval);
if (ob == NULL) {
return BLI_strdup("");
}
const uint32_t session_uuid = RNA_int_get(properties, "session_uuid");
const ID *id = BKE_libblock_find_session_uuid(CTX_data_main(C), ID_NT, session_uuid);
if (!id) {
return BLI_strdup("");
}
const char *tooltip = TIP_("Add modifier with node group \"%s\" on object \"%s\"");
return BLI_sprintfN(tooltip, id->name, ob->id.name);
}
static bool check_geometry_node_group_sockets(wmOperator *op, const bNodeTree *tree)
{
const bNodeSocket *first_input = (const bNodeSocket *)tree->inputs.first;
if (!first_input) {
BKE_report(op->reports, RPT_ERROR, "The node group must have a geometry input socket");
return false;
}
if (first_input->type != SOCK_GEOMETRY) {
BKE_report(op->reports, RPT_ERROR, "The first input must be a geometry socket");
return false;
}
const bNodeSocket *first_output = (const bNodeSocket *)tree->outputs.first;
if (!first_output) {
BKE_report(op->reports, RPT_ERROR, "The node group must have a geometry output socket");
return false;
}
if (first_output->type != SOCK_GEOMETRY) {
BKE_report(op->reports, RPT_ERROR, "The first output must be a geometry socket");
return false;
}
return true;
}
static int drop_geometry_nodes_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = ED_view3d_give_object_under_cursor(C, event->mval);
if (!ob) {
return OPERATOR_CANCELLED;
}
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
const uint32_t uuid = RNA_int_get(op->ptr, "session_uuid");
bNodeTree *node_tree = (bNodeTree *)BKE_libblock_find_session_uuid(bmain, ID_NT, uuid);
if (!node_tree) {
return OPERATOR_CANCELLED;
}
if (node_tree->type != NTREE_GEOMETRY) {
BKE_report(op->reports, RPT_ERROR, "Node group must be a geometry node tree");
return OPERATOR_CANCELLED;
}
if (!check_geometry_node_group_sockets(op, node_tree)) {
return OPERATOR_CANCELLED;
}
NodesModifierData *nmd = (NodesModifierData *)ED_object_modifier_add(
op->reports, bmain, scene, ob, node_tree->id.name + 2, eModifierType_Nodes);
if (!nmd) {
BKE_report(op->reports, RPT_ERROR, "Could not add geometry nodes modifier");
return OPERATOR_CANCELLED;
}
nmd->node_group = node_tree;
id_us_plus(&node_tree->id);
MOD_nodes_update_interface(ob, nmd);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, NULL);
return OPERATOR_FINISHED;
}
/** \} */
void OBJECT_OT_drop_geometry_nodes(wmOperatorType *ot)
{
ot->name = "Drop Geometry Node Group on Object";
ot->idname = "OBJECT_OT_drop_geometry_nodes";
ot->invoke = drop_geometry_nodes_invoke;
ot->poll = ED_operator_view3d_active;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
PropertyRNA *prop = RNA_def_int(ot->srna,
"session_uuid",
0,
INT32_MIN,
INT32_MAX,
"Session UUID",
"Session UUID of the geometry node group being dropped",
INT32_MIN,
INT32_MAX);
RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
}
/** \} */
/* ------------------------------------------------------------------- */
/** \name Unlink Object Operator
* \{ */

View File

@ -45,15 +45,15 @@ set(SRC
paint_cursor.cc
paint_curve.c
paint_curve_undo.c
paint_hide.c
paint_hide.cc
paint_image.cc
paint_image_2d.c
paint_image_2d_curve_mask.cc
paint_image_ops_paint.cc
paint_image_proj.cc
paint_mask.cc
paint_ops.c
paint_stroke.c
paint_ops.cc
paint_stroke.cc
paint_utils.c
paint_vertex.cc
paint_vertex_color_ops.cc
@ -88,7 +88,7 @@ set(SRC
curves_sculpt_intern.h
curves_sculpt_intern.hh
paint_intern.h
sculpt_intern.h
sculpt_intern.hh
)
set(LIB

View File

@ -55,7 +55,7 @@
#include "paint_intern.h"
/* still needed for sculpt_stroke_get_location, should be
* removed eventually (TODO) */
#include "sculpt_intern.h"
#include "sculpt_intern.hh"
/* TODOs:
*

View File

@ -41,7 +41,7 @@
#include "paint_intern.h"
/* For undo push. */
#include "sculpt_intern.h"
#include "sculpt_intern.hh"
/* Return true if the element should be hidden/shown. */
static bool is_effected(PartialVisArea area,
@ -67,21 +67,21 @@ static void partialvis_update_mesh(Object *ob,
PartialVisArea area,
float planes[4][4])
{
Mesh *me = ob->data;
Mesh *me = static_cast<Mesh *>(ob->data);
const float(*positions)[3] = BKE_pbvh_get_vert_positions(pbvh);
const float *paint_mask;
int totvert, i;
bool any_changed = false, any_visible = false;
BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert);
BKE_pbvh_node_num_verts(pbvh, node, nullptr, &totvert);
const int *vert_indices = BKE_pbvh_node_get_vert_indices(node);
paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
paint_mask = static_cast<const float *>(CustomData_get_layer(&me->vdata, CD_PAINT_MASK));
bool *hide_vert = CustomData_get_layer_named_for_write(
&me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert);
if (hide_vert == NULL) {
hide_vert = CustomData_add_layer_named(
&me->vdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totvert, ".hide_vert");
bool *hide_vert = static_cast<bool *>(
CustomData_get_layer_named_for_write(&me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert));
if (hide_vert == nullptr) {
hide_vert = static_cast<bool *>(CustomData_add_layer_named(
&me->vdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me->totvert, ".hide_vert"));
}
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
@ -122,7 +122,7 @@ static void partialvis_update_grids(Depsgraph *depsgraph,
bool any_changed = false, any_visible = false;
/* Get PBVH data. */
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, &grids);
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids);
grid_hidden = BKE_pbvh_grid_hidden(pbvh);
CCGKey key = *BKE_pbvh_get_grid_key(pbvh);
@ -147,7 +147,7 @@ static void partialvis_update_grids(Depsgraph *depsgraph,
else if (action == PARTIALVIS_SHOW && area == PARTIALVIS_ALL) {
/* Special case if we're showing all, just free the grid. */
MEM_freeN(gh);
grid_hidden[g] = NULL;
grid_hidden[g] = nullptr;
any_changed = true;
any_visible = true;
continue;
@ -180,7 +180,7 @@ static void partialvis_update_grids(Depsgraph *depsgraph,
/* If everything in the grid is now visible, free the grid flags. */
if (!any_hidden) {
MEM_freeN(gh);
grid_hidden[g] = NULL;
grid_hidden[g] = nullptr;
}
}
@ -203,8 +203,9 @@ static void partialvis_update_bmesh_verts(BMesh *bm,
GSetIterator gs_iter;
GSET_ITER (gs_iter, verts) {
BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
float *vmask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
BMVert *v = static_cast<BMVert *>(BLI_gsetIterator_getKey(&gs_iter));
float *vmask = static_cast<float *>(
CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK));
/* Hide vertex if in the hide volume. */
if (is_effected(area, planes, v->co, *vmask)) {
@ -228,7 +229,7 @@ static void partialvis_update_bmesh_faces(GSet *faces)
GSetIterator gs_iter;
GSET_ITER (gs_iter, faces) {
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
BMFace *f = static_cast<BMFace *>(BLI_gsetIterator_getKey(&gs_iter));
if (paint_is_bmesh_face_hidden(f)) {
BM_elem_flag_enable(f, BM_ELEM_HIDDEN);
@ -298,7 +299,7 @@ static void clip_planes_from_rect(bContext *C,
static void get_pbvh_nodes(
PBVH *pbvh, PBVHNode ***nodes, int *totnode, float clip_planes[4][4], PartialVisArea mode)
{
BKE_pbvh_SearchCallback cb = NULL;
BKE_pbvh_SearchCallback cb = nullptr;
/* Select search callback. */
switch (mode) {
@ -313,7 +314,9 @@ static void get_pbvh_nodes(
break;
}
PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 4};
PBVHFrustumPlanes frustum{};
frustum.planes = clip_planes;
frustum.num_planes = 4;
BKE_pbvh_search_gather(pbvh, cb, &frustum, nodes, totnode);
}
@ -322,7 +325,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
ARegion *region = CTX_wm_region(C);
Object *ob = CTX_data_active_object(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Mesh *me = ob->data;
Mesh *me = static_cast<Mesh *>(ob->data);
PartialVisAction action;
PartialVisArea area;
PBVH *pbvh;
@ -333,8 +336,8 @@ static int hide_show_exec(bContext *C, wmOperator *op)
int totnode;
/* Read operator properties. */
action = RNA_enum_get(op->ptr, "action");
area = RNA_enum_get(op->ptr, "area");
action = PartialVisAction(RNA_enum_get(op->ptr, "action"));
area = PartialVisArea(RNA_enum_get(op->ptr, "area"));
rect_from_props(&rect, op->ptr);
clip_planes_from_rect(C, depsgraph, clip_planes, &rect);
@ -395,7 +398,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
static int hide_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
PartialVisArea area = RNA_enum_get(op->ptr, "area");
PartialVisArea area = PartialVisArea(RNA_enum_get(op->ptr, "area"));
if (!ELEM(area, PARTIALVIS_ALL, PARTIALVIS_MASKED)) {
return WM_gesture_box_invoke(C, op, event);
@ -403,12 +406,12 @@ static int hide_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return op->type->exec(C, op);
}
void PAINT_OT_hide_show(struct wmOperatorType *ot)
void PAINT_OT_hide_show(wmOperatorType *ot)
{
static const EnumPropertyItem action_items[] = {
{PARTIALVIS_HIDE, "HIDE", 0, "Hide", "Hide vertices"},
{PARTIALVIS_SHOW, "SHOW", 0, "Show", "Show vertices"},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem area_items[] = {
@ -420,7 +423,7 @@ void PAINT_OT_hide_show(struct wmOperatorType *ot)
0,
"Masked",
"Hide or show vertices that are masked (minimum mask value of 0.5)"},
{0, NULL, 0, NULL, NULL},
{0, nullptr, 0, nullptr, nullptr},
};
/* Identifiers. */

View File

@ -46,7 +46,7 @@ typedef struct CoNo {
float no[3];
} CoNo;
/* paint_stroke.c */
/* paint_stroke.cc */
typedef bool (*StrokeGetLocation)(struct bContext *C,
float location[3],
@ -87,7 +87,7 @@ bool paint_supports_texture(enum ePaintMode mode);
bool paint_supports_jitter(enum ePaintMode mode);
/**
* Called in paint_ops.c, on each regeneration of key-maps.
* Called in paint_ops.cc, on each regeneration of key-maps.
*/
struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf);
int paint_stroke_modal(struct bContext *C,
@ -457,7 +457,7 @@ typedef enum BrushStrokeMode {
BRUSH_STROKE_SMOOTH,
} BrushStrokeMode;
/* paint_hide.c */
/* paint_hide.cc */
typedef enum {
PARTIALVIS_HIDE,

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