Overlay-Next: Initial implementation #107045

Closed
Clément Foucault wants to merge 28 commits from fclem/blender:overlay-next into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
182 changed files with 2627 additions and 1991 deletions
Showing only changes of commit 953cef7b7a - Show all commits

View File

@ -231,7 +231,7 @@ class FileBlockHeader:
self.SDNAIndex = 0
self.Count = 0
self.FileOffset = handle.tell()
#self.Code += ' ' * (4 - len(self.Code))
# self.Code += ' ' * (4 - len(self.Code))
log.debug("found blend-file-block-fileheader {0} {1}".format(self.Code, self.FileOffset))
def skip(self, handle):

View File

@ -182,7 +182,7 @@ class Device {
{
}
/* Return true if device is ready for rendering, or report status if not. */
/* Report status and return true if device is ready for rendering. */
virtual bool is_ready(string & /*status*/) const
{
return true;

View File

@ -490,6 +490,9 @@ bool MetalDevice::make_source_and_check_if_compile_needed(MetalPipelineType pso_
MD5Hash md5;
md5.append(constant_values);
md5.append(source[pso_type]);
if (use_metalrt) {
md5.append(string_printf("metalrt_features=%d", kernel_features & METALRT_FEATURE_MASK));
}
kernels_md5[pso_type] = md5.get_hex();
return MetalDeviceKernels::should_load_kernels(this, pso_type);
@ -934,6 +937,17 @@ bool MetalDevice::is_ready(string &status) const
DEVICE_KERNEL_NUM);
return false;
}
if (int num_requests = MetalDeviceKernels::num_incomplete_specialization_requests()) {
status = string_printf("%d kernels to optimize", num_requests);
}
else if (kernel_specialization_level == PSO_SPECIALIZED_INTERSECT) {
status = "Using optimized intersection kernels";
}
else if (kernel_specialization_level == PSO_SPECIALIZED_SHADE) {
status = "Using optimized kernels";
}
metal_printf("MetalDevice::is_ready(...) --> true\n");
return true;
}
@ -970,7 +984,7 @@ void MetalDevice::optimize_for_scene(Scene *scene)
}
if (specialize_in_background) {
if (!MetalDeviceKernels::any_specialization_happening_now()) {
if (MetalDeviceKernels::num_incomplete_specialization_requests() == 0) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
specialize_kernels_fn);
}

View File

@ -63,8 +63,7 @@ enum MetalPipelineType {
};
# define METALRT_FEATURE_MASK \
(KERNEL_FEATURE_HAIR | KERNEL_FEATURE_HAIR_THICK | KERNEL_FEATURE_POINTCLOUD | \
KERNEL_FEATURE_OBJECT_MOTION)
(KERNEL_FEATURE_HAIR | KERNEL_FEATURE_HAIR_THICK | KERNEL_FEATURE_POINTCLOUD)
const char *kernel_type_as_string(MetalPipelineType pso_type);
@ -81,7 +80,7 @@ struct MetalKernelPipeline {
KernelData kernel_data_;
bool use_metalrt;
uint32_t metalrt_features = 0;
uint32_t kernel_features = 0;
int threads_per_threadgroup;
@ -104,7 +103,7 @@ struct MetalKernelPipeline {
/* Cache of Metal kernels for each DeviceKernel. */
namespace MetalDeviceKernels {
bool any_specialization_happening_now();
int num_incomplete_specialization_requests();
int get_loaded_kernel_count(MetalDevice const *device, MetalPipelineType pso_type);
bool should_load_kernels(MetalDevice const *device, MetalPipelineType pso_type);
bool load(MetalDevice *device, MetalPipelineType pso_type);

View File

@ -344,9 +344,7 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
/* metalrt options */
pipeline->use_metalrt = device->use_metalrt;
pipeline->metalrt_features = device->use_metalrt ?
(device->kernel_features & METALRT_FEATURE_MASK) :
0;
pipeline->kernel_features = device->kernel_features;
{
thread_scoped_lock lock(cache_mutex);
@ -357,65 +355,36 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const MetalDevice *device)
{
/* metalrt options */
bool use_metalrt = device->use_metalrt;
bool device_metalrt_hair = use_metalrt && device->kernel_features & KERNEL_FEATURE_HAIR;
bool device_metalrt_hair_thick = use_metalrt &&
device->kernel_features & KERNEL_FEATURE_HAIR_THICK;
bool device_metalrt_pointcloud = use_metalrt &&
device->kernel_features & KERNEL_FEATURE_POINTCLOUD;
bool device_metalrt_motion = use_metalrt &&
device->kernel_features & KERNEL_FEATURE_OBJECT_MOTION;
MetalKernelPipeline *best_pipeline = nullptr;
while (!best_pipeline) {
while (running) {
/* Search all loaded pipelines with matching kernels_md5 checksums. */
MetalKernelPipeline *best_match = nullptr;
{
thread_scoped_lock lock(cache_mutex);
for (auto &pipeline : pipelines[kernel]) {
if (!pipeline->loaded) {
/* still loading - ignore */
continue;
}
bool pipeline_metalrt_hair = pipeline->metalrt_features & KERNEL_FEATURE_HAIR;
bool pipeline_metalrt_hair_thick = pipeline->metalrt_features & KERNEL_FEATURE_HAIR_THICK;
bool pipeline_metalrt_pointcloud = pipeline->metalrt_features & KERNEL_FEATURE_POINTCLOUD;
bool pipeline_metalrt_motion = use_metalrt &&
pipeline->metalrt_features & KERNEL_FEATURE_OBJECT_MOTION;
if (pipeline->use_metalrt != use_metalrt || pipeline_metalrt_hair != device_metalrt_hair ||
pipeline_metalrt_hair_thick != device_metalrt_hair_thick ||
pipeline_metalrt_pointcloud != device_metalrt_pointcloud ||
pipeline_metalrt_motion != device_metalrt_motion) {
/* wrong combination of metalrt options */
continue;
}
if (pipeline->pso_type != PSO_GENERIC) {
if (pipeline->kernels_md5 == device->kernels_md5[PSO_SPECIALIZED_INTERSECT] ||
pipeline->kernels_md5 == device->kernels_md5[PSO_SPECIALIZED_SHADE]) {
best_pipeline = pipeline.get();
for (auto &candidate : pipelines[kernel]) {
if (candidate->loaded &&
candidate->kernels_md5 == device->kernels_md5[candidate->pso_type]) {
/* Replace existing match if candidate is more specialized. */
if (!best_match || candidate->pso_type > best_match->pso_type) {
best_match = candidate.get();
}
}
else if (!best_pipeline) {
best_pipeline = pipeline.get();
}
}
}
if (!best_pipeline) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (best_match) {
if (best_match->usage_count == 0 && best_match->pso_type != PSO_GENERIC) {
metal_printf("Swapping in %s version of %s\n",
kernel_type_as_string(best_match->pso_type),
device_kernel_as_string(kernel));
}
best_match->usage_count += 1;
return best_match;
}
}
if (best_pipeline->usage_count == 0 && best_pipeline->pso_type != PSO_GENERIC) {
metal_printf("Swapping in %s version of %s\n",
kernel_type_as_string(best_pipeline->pso_type),
device_kernel_as_string(kernel));
/* Spin until a matching kernel is loaded, or we're shutting down. */
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
best_pipeline->usage_count += 1;
return best_pipeline;
return nullptr;
}
bool MetalKernelPipeline::should_use_binary_archive() const
@ -570,18 +539,14 @@ void MetalKernelPipeline::compile()
NSArray *table_functions[METALRT_TABLE_NUM] = {nil};
NSArray *linked_functions = nil;
bool metalrt_hair = use_metalrt && (metalrt_features & KERNEL_FEATURE_HAIR);
bool metalrt_hair_thick = use_metalrt && (metalrt_features & KERNEL_FEATURE_HAIR_THICK);
bool metalrt_pointcloud = use_metalrt && (metalrt_features & KERNEL_FEATURE_POINTCLOUD);
if (use_metalrt) {
id<MTLFunction> curve_intersect_default = nil;
id<MTLFunction> curve_intersect_shadow = nil;
id<MTLFunction> point_intersect_default = nil;
id<MTLFunction> point_intersect_shadow = nil;
if (metalrt_hair) {
if (kernel_features & KERNEL_FEATURE_HAIR) {
/* Add curve intersection programs. */
if (metalrt_hair_thick) {
if (kernel_features & KERNEL_FEATURE_HAIR_THICK) {
/* Slower programs for thick hair since that also slows down ribbons.
* Ideally this should not be needed. */
curve_intersect_default = rt_intersection_function[METALRT_FUNC_CURVE_ALL];
@ -592,7 +557,7 @@ void MetalKernelPipeline::compile()
curve_intersect_shadow = rt_intersection_function[METALRT_FUNC_CURVE_RIBBON_SHADOW];
}
}
if (metalrt_pointcloud) {
if (kernel_features & KERNEL_FEATURE_POINTCLOUD) {
point_intersect_default = rt_intersection_function[METALRT_FUNC_POINT];
point_intersect_shadow = rt_intersection_function[METALRT_FUNC_POINT_SHADOW];
}
@ -682,15 +647,6 @@ void MetalKernelPipeline::compile()
local_md5.append((uint8_t *)&this->threads_per_threadgroup,
sizeof(this->threads_per_threadgroup));
string options;
if (use_metalrt && kernel_has_intersection(device_kernel)) {
/* incorporate any MetalRT specializations into the archive name */
options += string_printf(".hair_%d.hair_thick_%d.pointcloud_%d",
metalrt_hair ? 1 : 0,
metalrt_hair_thick ? 1 : 0,
metalrt_pointcloud ? 1 : 0);
}
/* Replace non-alphanumerical characters with underscores. */
string device_name = [mtlDevice.name UTF8String];
for (char &c : device_name) {
@ -702,7 +658,7 @@ void MetalKernelPipeline::compile()
metalbin_name = device_name;
metalbin_name = path_join(metalbin_name, device_kernel_as_string(device_kernel));
metalbin_name = path_join(metalbin_name, kernel_type_as_string(pso_type));
metalbin_name = path_join(metalbin_name, local_md5.get_hex() + options + ".bin");
metalbin_name = path_join(metalbin_name, local_md5.get_hex() + ".bin");
metalbin_path = path_cache_get(path_join("kernels", metalbin_name));
path_create_directories(metalbin_path);
@ -860,16 +816,15 @@ void MetalDeviceKernels::wait_for_all()
}
}
bool MetalDeviceKernels::any_specialization_happening_now()
int MetalDeviceKernels::num_incomplete_specialization_requests()
{
/* Return true if any ShaderCaches have ongoing specialization requests (typically there will be
* only 1). */
int total = 0;
for (int i = 0; i < g_shaderCacheCount; i++) {
if (g_shaderCache[i].second->incomplete_specialization_requests > 0) {
return true;
}
total += g_shaderCache[i].second->incomplete_specialization_requests;
}
return false;
return total;
}
int MetalDeviceKernels::get_loaded_kernel_count(MetalDevice const *device,

View File

@ -706,6 +706,12 @@ void Session::update_status_time(bool show_pause, bool show_done)
string_printf("Sample %d/%d", current_sample, num_samples));
}
/* Append any device-specific status (such as background kernel optimization) */
string device_status;
if (device->is_ready(device_status) && !device_status.empty()) {
substatus += string_printf(" (%s)", device_status.c_str());
}
/* TODO(sergey): Denoising status from the path trace. */
if (show_pause) {

View File

@ -33,7 +33,8 @@ aggressive = 2
# Exclude:
# - `./extern/` because it's maintained separately.
# - `./scripts/addons*` & `./tools/` because they are external repositories
# - `./tools/svn_rev_map/` contains data-files which are slow to re-format and don't benefit from formatting.
# - `./scripts/addons*` because it is an external repository.
# which can contain their own configuration and be handled separately.
# - `./scripts/modules/rna_manual_reference.py` because it's a generated data-file.
exclude = """
@ -41,7 +42,8 @@ exclude = """
./scripts/addons/*,
./scripts/addons_contrib/*,
./scripts/modules/rna_manual_reference.py,
./tools/*,
./tools/svn_rev_map/sha1_to_rev.py,
./tools/svn_rev_map/rev_to_sha1.py,
"""
# Omit settings such as `jobs`, `in_place` & `recursive` as they can cause editor utilities that auto-format on save

View File

@ -20,7 +20,7 @@ from freestyle.types import IntegrationType, Operators, Stroke
Operators.select(QuantitativeInvisibilityUP1D(0))
Operators.bidirectional_chain(ChainSilhouetteIterator())
#Operators.sequential_split(pyVertexNatureUP0D(Nature.VIEW_VERTEX), 2)
# Operators.sequential_split(pyVertexNatureUP0D(Nature.VIEW_VERTEX), 2)
Operators.sort(pyZBP1D())
shaders_list = [
ConstantThicknessShader(3),

View File

@ -76,7 +76,7 @@ class DataPathBuilder:
break
if type_ok:
try:
#print("base." + item_new)
# print("base." + item_new)
base_new = eval("base." + item_new)
break # found, don't keep looking
except:

View File

@ -92,7 +92,7 @@ def module_list(path):
folder_list = []
else:
folder_list = []
#folder_list = glob.glob(os.path.join(path,'*'))
# folder_list = glob.glob(os.path.join(path,'*'))
folder_list = [
p for p in folder_list
if (os.path.exists(os.path.join(path, p, '__init__.py')) or

View File

@ -559,7 +559,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
# foobar(text="Foo", text_ctxt=i18n_ctxt.id_object)
if type(node) == ast.Attribute:
if node.attr in i18n_ctxt_ids:
#print(node, node.attr, getattr(i18n_contexts, node.attr))
# print(node, node.attr, getattr(i18n_contexts, node.attr))
return getattr(i18n_contexts, node.attr)
return i18n_contexts.default

View File

@ -7,7 +7,7 @@ import os
import re
import struct
import tempfile
#import time
# import time
from bl_i18n_utils import (
settings,
@ -173,7 +173,7 @@ def list_po_dir(root_path, settings):
isocodes = dict(e for e in isocodes if os.path.isfile(e[1]))
for num_id, name, uid in settings.LANGUAGES[2:]: # Skip "default" and "en" languages!
best_po = find_best_isocode_matches(uid, isocodes)
#print(uid, "->", best_po)
# print(uid, "->", best_po)
if best_po:
isocode = best_po[0]
yield (True, uid, num_id, name, isocode, isocodes[isocode])
@ -438,7 +438,7 @@ class I18nMessages:
# Avoid parsing again!
# Keys should be (pseudo) file-names, values are tuples (hash, I18nMessages)
# Note: only used by po parser currently!
#_parser_cache = {}
# _parser_cache = {}
def __init__(self, uid=None, kind=None, key=None, src=None, settings=settings):
self.settings = settings
@ -791,7 +791,7 @@ class I18nMessages:
k &= src_to_msg[src_enum]
msgmap["enum_label"]["key"] = k
rlbl = getattr(msgs, msgmap["rna_label"]["msgstr"])
#print("rna label: " + rlbl, rlbl in msgid_to_msg, rlbl in msgstr_to_msg)
# print("rna label: " + rlbl, rlbl in msgid_to_msg, rlbl in msgstr_to_msg)
if rlbl:
k = ctxt_to_msg[rna_ctxt].copy()
if k and rlbl in msgid_to_msg:
@ -831,7 +831,7 @@ class I18nMessages:
# Tips (they never have a specific context).
etip = getattr(msgs, msgmap["enum_tip"]["msgstr"])
#print("enum tip: " + etip)
# print("enum tip: " + etip)
if etip:
k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
if etip in msgid_to_msg:
@ -845,7 +845,7 @@ class I18nMessages:
k &= src_to_msg[src_enum]
msgmap["enum_tip"]["key"] = k
rtip = getattr(msgs, msgmap["rna_tip"]["msgstr"])
#print("rna tip: " + rtip)
# print("rna tip: " + rtip)
if rtip:
k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
if k and rtip in msgid_to_msg:
@ -860,7 +860,7 @@ class I18nMessages:
msgmap["rna_tip"]["key"] = k
# print(k)
btip = getattr(msgs, msgmap["but_tip"]["msgstr"])
#print("button tip: " + btip)
# print("button tip: " + btip)
if btip and btip not in {rtip, etip}:
k = ctxt_to_msg[self.settings.DEFAULT_CONTEXT].copy()
if btip in msgid_to_msg:
@ -1038,7 +1038,7 @@ class I18nMessages:
msgstr_lines.append(line)
else:
self.parsing_errors.append((line_nr, "regular string outside msgctxt, msgid or msgstr scope"))
#self.parsing_errors += (str(comment_lines), str(msgctxt_lines), str(msgid_lines), str(msgstr_lines))
# self.parsing_errors += (str(comment_lines), str(msgctxt_lines), str(msgid_lines), str(msgstr_lines))
# If no final empty line, last message is not finalized!
if reading_msgstr:

View File

@ -69,7 +69,7 @@ def language_menu(args, settings):
continue
for po_path in os.listdir(po_dir):
uid = po_to_uid.get(po_path, None)
#print("Checking %s, found uid %s" % (po_path, uid))
# print("Checking %s, found uid %s" % (po_path, uid))
po_path = os.path.join(settings.TRUNK_PO_DIR, po_path)
if uid is not None:
po = utils_i18n.I18nMessages(uid=uid, kind='PO', src=po_path, settings=settings)

View File

@ -60,4 +60,22 @@ def keyconfig_update(keyconfig_data, keyconfig_version):
}.get(item_event.get("type")):
item_event["type"] = ty_new
if keyconfig_version <= (3, 6, 0):
# The modal keys "Vert/Edge Slide" and "TrackBall" didn't exist until then.
# The operator reused the "Move" and "Rotate" respectively.
if not has_copy:
keyconfig_data = copy.deepcopy(keyconfig_data)
has_copy = True
for km_name, _km_parms, km_items_data in keyconfig_data:
if km_name == "Transform Modal Map":
km_items = km_items_data["items"]
for (item_modal, item_event, _item_prop) in km_items:
if item_modal == 'TRANSLATE':
km_items.append(('VERT_EDGE_SLIDE', item_event, None))
elif item_modal == 'ROTATE':
km_items.append(('TRACKBALL', item_event, None))
break
return keyconfig_data

View File

@ -392,7 +392,7 @@ def ngon_tessellate(from_data, indices, fix_loops=True, debug_print=True):
fill = tessellate_polygon([[v[0] for v in loop] for loop in loop_list])
# draw_loops(loop_list)
#raise Exception("done loop")
# raise Exception("done loop")
# map to original indices
fill = [[vert_map[i] for i in f] for f in fill]

View File

@ -329,8 +329,11 @@ def banner(context):
"",
)
# NOTE: Using `OUTPUT` style (intended for the `stdout` is also valid).
# Using `INFO` has a slight advantage that it's excluded by the "Copy as Script" operator.
# As the banner isn't useful to include in a script - leave it out.
for line in message:
add_scrollback(line, 'OUTPUT')
add_scrollback(line, 'INFO')
sc.prompt = PROMPT

View File

@ -25,8 +25,8 @@ def compat_str(text, line_length=0):
text_ls.append(text)
text = '\n '.join(text_ls)
#text = text.replace('.', '.\n')
#text = text.replace(']', ']\n')
# text = text.replace('.', '.\n')
# text = text.replace(']', ']\n')
text = text.replace("\n", "\\n")
text = text.replace('"', '\\"')
return text
@ -135,7 +135,7 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr
if not rna_path.startswith("pose.bones["):
return None
#rna_path_bone = rna_path[:rna_path.index("]") + 1]
# rna_path_bone = rna_path[:rna_path.index("]") + 1]
# return obj.path_resolve(rna_path_bone)
bone_name = rna_path.split("[")[1].split("]")[0]
return obj.pose.bones[bone_name[1:-1]]

View File

@ -629,7 +629,7 @@ def BuildRNAInfo():
except:
return "" # invalid id
#structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()]
# structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()]
'''
structs = []
for rna_struct in bpy.doc.structs.values():
@ -703,7 +703,7 @@ def BuildRNAInfo():
# Store a list of functions, remove inherited later
# NOT USED YET
## rna_functions_dict[identifier] = get_direct_functions(rna_struct)
# rna_functions_dict[identifier] = get_direct_functions(rna_struct)
# fill in these later
rna_children_dict[identifier] = []
@ -786,7 +786,7 @@ def BuildRNAInfo():
# if rna_struct.nested:
# continue
#write_struct(rna_struct, '')
# write_struct(rna_struct, '')
info_struct = GetInfoStructRNA(rna_struct)
if rna_base:
info_struct.base = GetInfoStructRNA(rna_struct_dict[rna_base])

View File

@ -5789,7 +5789,9 @@ def km_transform_modal_map(_params):
("PLANE_Z", {"type": 'Z', "value": 'PRESS', "shift": True}, None),
("CONS_OFF", {"type": 'C', "value": 'PRESS'}, None),
("TRANSLATE", {"type": 'G', "value": 'PRESS'}, None),
("VERT_EDGE_SLIDE", {"type": 'G', "value": 'PRESS'}, None),
("ROTATE", {"type": 'R', "value": 'PRESS'}, None),
("TRACKBALL", {"type": 'R', "value": 'PRESS'}, None),
("RESIZE", {"type": 'S', "value": 'PRESS'}, None),
("SNAP_TOGGLE", {"type": 'TAB', "value": 'PRESS', "shift": True}, None),
("SNAP_INV_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": True}, None),

View File

@ -3971,7 +3971,9 @@ def km_transform_modal_map(_params):
("PLANE_Z", {"type": 'Z', "value": 'PRESS', "shift": True}, None),
("CONS_OFF", {"type": 'C', "value": 'PRESS'}, None),
("TRANSLATE", {"type": 'G', "value": 'PRESS'}, None),
("VERT_EDGE_SLIDE", {"type": 'G', "value": 'PRESS'}, None),
("ROTATE", {"type": 'R', "value": 'PRESS'}, None),
("TRACKBALL", {"type": 'R', "value": 'PRESS'}, None),
("RESIZE", {"type": 'S', "value": 'PRESS'}, None),
("SNAP_TOGGLE", {"type": 'TAB', "value": 'PRESS', "shift": True}, None),
("SNAP_INV_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": True}, None),

View File

@ -164,7 +164,7 @@ class RandomizeLocRotSize(Operator):
scale = None if not self.use_scale else self.scale
scale_even = self.scale_even
#scale_min = self.scale_min
# scale_min = self.scale_min
scale_min = 0
randomize_selected(context, seed, delta,

View File

@ -165,9 +165,9 @@ class prettyface:
def set_uv(f, p1, p2, p3):
# cos =
#v1 = cos[0]-cos[1]
#v2 = cos[1]-cos[2]
#v3 = cos[2]-cos[0]
# v1 = cos[0]-cos[1]
# v2 = cos[1]-cos[2]
# v3 = cos[2]-cos[0]
# angles_co = get_tri_angles(*[v.co for v in f])
angles_co = get_tri_angles(*[f.id_data.vertices[v].co for v in f.vertices]) # XXX25

View File

@ -132,7 +132,6 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, Panel):
rows=rows,
)
col = row.column(align=True)
col.operator("pose.group_add", icon='ADD', text="")
col.operator("pose.group_remove", icon='REMOVE', text="")
@ -218,7 +217,7 @@ class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, Panel):
class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel):
#bl_label = "Bones Motion Paths"
# bl_label = "Bones Motion Paths"
bl_options = {'DEFAULT_CLOSED'}
bl_context = "data"
@ -240,7 +239,7 @@ class DATA_PT_motion_paths(MotionPathButtonsPanel, Panel):
class DATA_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel):
#bl_label = "Bones Motion Paths"
# bl_label = "Bones Motion Paths"
bl_context = "data"
bl_parent_id = "DATA_PT_motion_paths"
bl_options = {'DEFAULT_CLOSED'}

View File

@ -190,7 +190,7 @@ class MASK_PT_point:
col = layout.column()
# Currently only parenting the movie-clip is allowed,
# so do not over-complicate things for now by using single template_ID
#col.template_any_ID(parent, "id", "id_type", text="")
# col.template_any_ID(parent, "id", "id_type", text="")
col.label(text="Parent:")
col.prop(parent, "id", text="")

View File

@ -325,7 +325,7 @@ class OBJECT_PT_lineart(ObjectButtonsPanel, Panel):
class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
#bl_label = "Object Motion Paths"
# bl_label = "Object Motion Paths"
bl_context = "object"
bl_options = {'DEFAULT_CLOSED'}
@ -344,7 +344,7 @@ class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
class OBJECT_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel):
#bl_label = "Object Motion Paths"
# bl_label = "Object Motion Paths"
bl_context = "object"
bl_parent_id = "OBJECT_PT_motion_paths"
bl_options = {'DEFAULT_CLOSED'}

View File

@ -879,7 +879,7 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel):
col.prop(domain, "mesh_concave_lower", text="Lower")
# TODO (sebbas): for now just interpolate any upres grids, ie not sampling highres grids
#col.prop(domain, "highres_sampling", text="Flow Sampling:")
# col.prop(domain, "highres_sampling", text="Flow Sampling:")
if domain.cache_type == 'MODULAR':
col.separator()

View File

@ -25,7 +25,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 0
#define BLENDER_FILE_SUBVERSION 1
/* 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

@ -97,7 +97,7 @@ typedef struct ClothVertex {
float tv[3]; /* temporary "velocity", mostly used as tv = tx-txold */
float mass; /* mass / weight of the vertex */
float goal; /* goal, from SB */
float impulse[3]; /* used in collision.c */
float impulse[3]; /* used in collision.cc */
float xrest[3]; /* rest position of the vertex */
float dcvel[3]; /* delta velocities to be applied by collision response */
unsigned int impulse_count; /* same as above */
@ -196,7 +196,7 @@ typedef enum {
} CLOTH_SPRINGS_FLAGS;
/* -------------------------------------------------------------------- */
/* collision.c */
/* collision.cc */
struct CollPair;
@ -232,7 +232,7 @@ void clothModifier_do(struct ClothModifierData *clmd,
int cloth_uses_vgroup(struct ClothModifierData *clmd);
/* Needed for collision.c */
/* Needed for collision.cc */
void bvhtree_update_from_cloth(struct ClothModifierData *clmd, bool moving, bool self);
/* Needed for button_object.c */

View File

@ -18,7 +18,7 @@ struct MVertTri;
struct Object;
////////////////////////////////////////
// used for collisions in collision.c
// used for collisions in collision.cc
////////////////////////////////////////
/* COLLISION FLAGS */
@ -32,9 +32,9 @@ typedef enum {
} COLLISION_FLAGS;
////////////////////////////////////////
// used for collisions in collision.c
// used for collisions in collision.cc
////////////////////////////////////////
/* used for collisions in collision.c */
/* used for collisions in collision.cc */
typedef struct CollPair {
unsigned int face1; /* cloth face */
unsigned int face2; /* object face */
@ -58,7 +58,7 @@ typedef struct CollPair {
int pointsb[4];
} CollPair;
/* used for collisions in collision.c */
/* used for collisions in collision.cc */
typedef struct EdgeCollPair {
unsigned int p11, p12, p21, p22;
float normal[3];
@ -68,7 +68,7 @@ typedef struct EdgeCollPair {
float pa[3], pb[3]; /* collision point p1 on face1, p2 on face2 */
} EdgeCollPair;
/* used for collisions in collision.c */
/* used for collisions in collision.cc */
typedef struct FaceCollPair {
unsigned int p11, p12, p13, p21;
float normal[3];
@ -85,7 +85,7 @@ typedef struct FaceCollPair {
/////////////////////////////////////////////////
/////////////////////////////////////////////////
// used in modifier.cc from collision.c
// used in modifier.cc from collision.cc
/////////////////////////////////////////////////
struct BVHTree *bvhtree_build_from_mvert(const float (*positions)[3],

View File

@ -138,6 +138,13 @@ typedef struct Main {
*/
bool is_locked_for_linking;
/**
* When set, indicates that an unrecoverable error/data corruption was detected.
* Should only be set by readfile code, and used by upper-level code (typically #setup_app_data)
* to cancel a file reading operation.
*/
bool is_read_invalid;
/**
* True if this main is the 'GMAIN' of current Blender.
*

View File

@ -99,6 +99,9 @@ void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_edges_from_flags(struct Mesh *mesh);
void BKE_mesh_legacy_uv_seam_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_uv_seam_from_flags(struct Mesh *mesh);
struct MVert *BKE_mesh_legacy_convert_positions_to_verts(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,

View File

@ -260,6 +260,7 @@ typedef bool (*MeshRemapIslandsCalc)(const float (*vert_positions)[3],
int totvert,
const struct MEdge *edges,
int totedge,
const bool *uv_seams,
const struct MPoly *polys,
int totpoly,
const struct MLoop *loops,
@ -277,6 +278,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
int totvert,
const struct MEdge *edges,
int totedge,
const bool *uv_seams,
const struct MPoly *polys,
int totpoly,
const struct MLoop *loops,
@ -300,6 +302,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
int totvert,
struct MEdge *edges,
int totedge,
const bool *uv_seams,
struct MPoly *polys,
int totpoly,
struct MLoop *loops,

View File

@ -6,6 +6,7 @@
#include <mutex>
#include "BLI_cache_mutex.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_multi_value_map.hh"
#include "BLI_resource_scope.hh"
#include "BLI_utility_mixins.hh"
@ -150,6 +151,13 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
Vector<bNode *> root_frames;
Vector<bNodeSocket *> interface_inputs;
Vector<bNodeSocket *> interface_outputs;
/**
* The location of all sockets in the tree, calculated while drawing the nodes.
* Indexed with #bNodeSocket::index_in_tree(). In the node tree's "world space"
* (the same as #bNode::runtime::totr).
*/
Vector<float2> all_socket_locations;
};
/**

View File

@ -95,7 +95,6 @@ typedef struct CCGDerivedMesh {
struct CCGFace *face;
} * faceMap;
short *edgeFlags;
struct DMFlagMat *faceFlags;
int *reverseFaceMap;

View File

@ -92,7 +92,7 @@ set(SRC
intern/cdderivedmesh.cc
intern/cloth.cc
intern/collection.c
intern/collision.c
intern/collision.cc
intern/colorband.c
intern/colortools.c
intern/compute_contexts.cc

View File

@ -476,6 +476,13 @@ void BKE_blendfile_read_setup_ex(bContext *C,
const bool startup_update_defaults,
const char *startup_app_template)
{
if (bfd->main->is_read_invalid) {
BKE_reports_prepend(reports->reports,
"File could not be read, critical data corruption detected");
BLO_blendfiledata_free(bfd);
return;
}
if (startup_update_defaults) {
if ((params->skip_flags & BLO_READ_SKIP_DATA) == 0) {
BLO_update_defaults_startup_blend(bfd->main, startup_app_template);
@ -503,6 +510,10 @@ struct BlendFileData *BKE_blendfile_read(const char *filepath,
}
BlendFileData *bfd = BLO_read_from_file(filepath, eBLOReadSkip(params->skip_flags), reports);
if (bfd && bfd->main->is_read_invalid) {
BLO_blendfiledata_free(bfd);
bfd = nullptr;
}
if (bfd) {
handle_subversion_warning(bfd->main, reports);
}
@ -519,6 +530,10 @@ struct BlendFileData *BKE_blendfile_read_from_memory(const void *filebuf,
{
BlendFileData *bfd = BLO_read_from_memory(
filebuf, filelength, eBLOReadSkip(params->skip_flags), reports);
if (bfd && bfd->main->is_read_invalid) {
BLO_blendfiledata_free(bfd);
bfd = nullptr;
}
if (bfd) {
/* Pass. */
}
@ -535,6 +550,10 @@ struct BlendFileData *BKE_blendfile_read_from_memfile(Main *bmain,
{
BlendFileData *bfd = BLO_read_from_memfile(
bmain, BKE_main_blendfile_path(bmain), memfile, params, reports);
if (bfd && bfd->main->is_read_invalid) {
BLO_blendfiledata_free(bfd);
bfd = nullptr;
}
if (bfd) {
/* Removing the unused workspaces, screens and wm is useless here, setup_app_data will switch
* those lists with the ones from old bmain, which freeing is much more efficient than

View File

@ -580,7 +580,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
const MEdge *edge,
const MFace *face,
const MLoop *loop,
const MLoopTri *looptri,
const Span<MLoopTri> looptris,
BVHTreeFromMesh *r_data)
{
memset(r_data, 0, sizeof(*r_data));
@ -591,7 +591,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
r_data->edge = edge;
r_data->face = face;
r_data->loop = loop;
r_data->looptri = looptri;
r_data->looptri = looptris.data();
switch (bvh_cache_type) {
case BVHTREE_FROM_VERTS:
@ -779,7 +779,7 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
if (data) {
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(
tree, BVHTREE_FROM_VERTS, vert_positions, nullptr, nullptr, nullptr, nullptr, data);
tree, BVHTREE_FROM_VERTS, vert_positions, nullptr, nullptr, nullptr, {}, data);
}
return tree;
@ -914,7 +914,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
if (data) {
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(
tree, BVHTREE_FROM_EDGES, vert_positions, edge, nullptr, nullptr, nullptr, data);
tree, BVHTREE_FROM_EDGES, vert_positions, edge, nullptr, nullptr, {}, data);
}
return tree;
@ -1037,16 +1037,15 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
int axis,
const float (*positions)[3],
const MLoop *mloop,
const MLoopTri *looptri,
const int looptri_num,
const Span<MLoopTri> looptris,
const BitSpan looptri_mask,
int looptri_num_active)
{
if (!looptri_mask.is_empty()) {
BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptri_num));
BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptris.size()));
}
else {
looptri_num_active = looptri_num;
looptri_num_active = looptris.size();
}
if (looptri_num_active == 0) {
return nullptr;
@ -1059,16 +1058,16 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
return nullptr;
}
if (positions && looptri) {
for (int i = 0; i < looptri_num; i++) {
if (positions && !looptris.is_empty()) {
for (const int i : looptris.index_range()) {
float co[3][3];
if (!looptri_mask.is_empty() && !looptri_mask[i]) {
continue;
}
copy_v3_v3(co[0], positions[mloop[looptri[i].tri[0]].v]);
copy_v3_v3(co[1], positions[mloop[looptri[i].tri[1]].v]);
copy_v3_v3(co[2], positions[mloop[looptri[i].tri[2]].v]);
copy_v3_v3(co[0], positions[mloop[looptris[i].tri[0]].v]);
copy_v3_v3(co[1], positions[mloop[looptris[i].tri[1]].v]);
copy_v3_v3(co[2], positions[mloop[looptris[i].tri[2]].v]);
BLI_bvhtree_insert(tree, i, co[0], 3);
}
@ -1121,8 +1120,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
axis,
vert_positions,
mloop,
looptri,
looptri_num,
{looptri, looptri_num},
looptri_mask,
looptri_num_active);
@ -1130,8 +1128,14 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
if (data) {
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(
tree, BVHTREE_FROM_LOOPTRI, vert_positions, nullptr, nullptr, mloop, looptri, data);
bvhtree_from_mesh_setup_data(tree,
BVHTREE_FROM_LOOPTRI,
vert_positions,
nullptr,
nullptr,
mloop,
{looptri, looptri_num},
data);
}
return tree;
@ -1208,11 +1212,9 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
{
BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime->bvh_cache;
const MLoopTri *looptri = nullptr;
int looptri_len = 0;
Span<MLoopTri> looptris;
if (ELEM(bvh_cache_type, BVHTREE_FROM_LOOPTRI, BVHTREE_FROM_LOOPTRI_NO_HIDDEN)) {
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
looptri_len = BKE_mesh_runtime_looptri_len(mesh);
looptris = mesh->looptris();