Cleanup: Reduce nesteds in node.cc #105509
|
@ -2,4 +2,4 @@ ${CommitTitle}
|
|||
|
||||
${CommitBody}
|
||||
|
||||
Pull Request #${PullRequestIndex}
|
||||
Pull Request: https://projects.blender.org/blender/blender/pulls/${PullRequestIndex}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
${PullRequestTitle}
|
||||
|
||||
Pull Request #${PullRequestIndex}
|
||||
Pull Request: https://projects.blender.org/blender/blender/pulls/${PullRequestIndex}
|
||||
|
|
|
@ -65,3 +65,10 @@ waveletNoiseTile.bin
|
|||
/release/datafiles/locale/
|
||||
/release/scripts/addons_contrib/
|
||||
/source/tools/
|
||||
|
||||
# Build files for VS and VS Code.
|
||||
/build/
|
||||
/out/
|
||||
CMakeSettings.json
|
||||
CMakePresets.json
|
||||
CMakeUserPresets.json
|
||||
|
|
|
@ -1673,7 +1673,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
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,
|
||||
col.label(text=iface_("and NVIDIA driver version %s or newer") % driver_version,
|
||||
icon='BLANK1', translate=False)
|
||||
elif device_type == 'HIP':
|
||||
if True:
|
||||
|
@ -1719,7 +1719,8 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
.replace('(TM)', unicodedata.lookup('TRADE MARK SIGN'))
|
||||
.replace('(tm)', unicodedata.lookup('TRADE MARK SIGN'))
|
||||
.replace('(R)', unicodedata.lookup('REGISTERED SIGN'))
|
||||
.replace('(C)', unicodedata.lookup('COPYRIGHT SIGN'))
|
||||
.replace('(C)', unicodedata.lookup('COPYRIGHT SIGN')),
|
||||
translate=False
|
||||
)
|
||||
|
||||
def draw_impl(self, layout, context):
|
||||
|
|
|
@ -35,7 +35,7 @@ struct BVHReferenceCompare {
|
|||
|
||||
/* Compare two references.
|
||||
*
|
||||
* Returns value is similar to return value of strcmp().
|
||||
* Returns value is similar to return value of `strcmp()`.
|
||||
*/
|
||||
__forceinline int compare(const BVHReference &ra, const BVHReference &rb) const
|
||||
{
|
||||
|
|
|
@ -161,25 +161,12 @@ ShaderCache::~ShaderCache()
|
|||
running = false;
|
||||
cond_var.notify_all();
|
||||
|
||||
int num_incomplete = int(incomplete_requests);
|
||||
if (num_incomplete) {
|
||||
/* Shutting down the app with incomplete shader compilation requests. Give 1 second's grace for
|
||||
* clean shutdown. */
|
||||
metal_printf("ShaderCache busy (incomplete_requests = %d)...\n", num_incomplete);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
num_incomplete = int(incomplete_requests);
|
||||
}
|
||||
|
||||
if (num_incomplete && !MetalDeviceKernels::is_benchmark_warmup()) {
|
||||
metal_printf("ShaderCache still busy (incomplete_requests = %d). Terminating...\n",
|
||||
num_incomplete);
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
metal_printf("ShaderCache idle. Shutting down.\n");
|
||||
metal_printf("Waiting for ShaderCache threads... (incomplete_requests = %d)\n",
|
||||
int(incomplete_requests));
|
||||
for (auto &thread : compile_threads) {
|
||||
thread.join();
|
||||
}
|
||||
metal_printf("ShaderCache shut down.\n");
|
||||
}
|
||||
|
||||
void ShaderCache::wait_for_all()
|
||||
|
@ -675,7 +662,9 @@ void MetalKernelPipeline::compile()
|
|||
}
|
||||
}
|
||||
|
||||
__block bool creating_new_archive = false;
|
||||
bool creating_new_archive = false;
|
||||
bool recreate_archive = false;
|
||||
|
||||
if (@available(macOS 11.0, *)) {
|
||||
if (use_binary_archive) {
|
||||
if (!archive) {
|
||||
|
@ -684,51 +673,101 @@ void MetalKernelPipeline::compile()
|
|||
archive = [mtlDevice newBinaryArchiveWithDescriptor:archiveDesc error:nil];
|
||||
creating_new_archive = true;
|
||||
}
|
||||
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil];
|
||||
pipelineOptions = MTLPipelineOptionFailOnBinaryArchiveMiss;
|
||||
else {
|
||||
pipelineOptions = MTLPipelineOptionFailOnBinaryArchiveMiss;
|
||||
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lambda to do the actual pipeline compilation. */
|
||||
auto do_compilation = [&]() {
|
||||
__block bool compilation_finished = false;
|
||||
__block string error_str;
|
||||
|
||||
if (archive && path_exists(metalbin_path)) {
|
||||
/* Use the blocking variant of newComputePipelineStateWithDescriptor if an archive exists on
|
||||
* disk. It should load almost instantaneously, and will fail gracefully when loading a
|
||||
* corrupt archive (unlike the async variant). */
|
||||
NSError *error = nil;
|
||||
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
|
||||
options:pipelineOptions
|
||||
reflection:nullptr
|
||||
error:&error];
|
||||
const char *err = error ? [[error localizedDescription] UTF8String] : nullptr;
|
||||
error_str = err ? err : "nil";
|
||||
}
|
||||
else {
|
||||
/* Use the async variant of newComputePipelineStateWithDescriptor if no archive exists on
|
||||
* disk. This allows us responds to app shutdown. */
|
||||
[mtlDevice
|
||||
newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
|
||||
options:pipelineOptions
|
||||
completionHandler:^(id<MTLComputePipelineState> computePipelineState,
|
||||
MTLComputePipelineReflection *reflection,
|
||||
NSError *error) {
|
||||
pipeline = computePipelineState;
|
||||
|
||||
/* Retain the pipeline so we can use it safely past the completion
|
||||
* handler. */
|
||||
if (pipeline) {
|
||||
[pipeline retain];
|
||||
}
|
||||
const char *err = error ?
|
||||
[[error localizedDescription] UTF8String] :
|
||||
nullptr;
|
||||
error_str = err ? err : "nil";
|
||||
|
||||
compilation_finished = true;
|
||||
}];
|
||||
|
||||
/* Immediately wait for either the compilation to finish or for app shutdown. */
|
||||
while (ShaderCache::running && !compilation_finished) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
if (creating_new_archive && pipeline && ShaderCache::running) {
|
||||
/* Add pipeline into the new archive. It should be instantaneous following
|
||||
* newComputePipelineStateWithDescriptor. */
|
||||
NSError *error;
|
||||
|
||||
computePipelineStateDescriptor.binaryArchives = [NSArray arrayWithObjects:archive, nil];
|
||||
if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor
|
||||
error:&error]) {
|
||||
NSString *errStr = [error localizedDescription];
|
||||
metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil");
|
||||
}
|
||||
}
|
||||
else if (!pipeline) {
|
||||
metal_printf(
|
||||
"newComputePipelineStateWithDescriptor failed for \"%s\"%s. "
|
||||
"Error:\n%s\n",
|
||||
device_kernel_as_string((DeviceKernel)device_kernel),
|
||||
(archive && !recreate_archive) ? " Archive may be incomplete or corrupt - attempting "
|
||||
"recreation.." :
|
||||
"",
|
||||
error_str.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
double starttime = time_dt();
|
||||
|
||||
/* Block on load to ensure we continue with a valid kernel function */
|
||||
if (creating_new_archive) {
|
||||
starttime = time_dt();
|
||||
NSError *error;
|
||||
if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor
|
||||
error:&error]) {
|
||||
NSString *errStr = [error localizedDescription];
|
||||
metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil");
|
||||
}
|
||||
}
|
||||
do_compilation();
|
||||
|
||||
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
|
||||
options:pipelineOptions
|
||||
reflection:nullptr
|
||||
error:&error];
|
||||
|
||||
bool recreate_archive = false;
|
||||
/* An archive might have a corrupt entry and fail to materialize the pipeline. This shouldn't
|
||||
* happen, but if it does we recreate it. */
|
||||
if (pipeline == nil && archive) {
|
||||
NSString *errStr = [error localizedDescription];
|
||||
metal_printf(
|
||||
"Failed to create compute pipeline state \"%s\" from archive - attempting recreation... "
|
||||
"(error: %s)\n",
|
||||
device_kernel_as_string((DeviceKernel)device_kernel),
|
||||
errStr ? [errStr UTF8String] : "nil");
|
||||
pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor
|
||||
options:MTLPipelineOptionNone
|
||||
reflection:nullptr
|
||||
error:&error];
|
||||
recreate_archive = true;
|
||||
pipelineOptions = MTLPipelineOptionNone;
|
||||
path_remove(metalbin_path);
|
||||
|
||||
do_compilation();
|
||||
}
|
||||
|
||||
double duration = time_dt() - starttime;
|
||||
|
||||
if (pipeline == nil) {
|
||||
NSString *errStr = [error localizedDescription];
|
||||
error_str = string_printf("Failed to create compute pipeline state \"%s\", error: \n",
|
||||
device_kernel_as_string((DeviceKernel)device_kernel));
|
||||
error_str += (errStr ? [errStr UTF8String] : "nil");
|
||||
metal_printf("%16s | %2d | %-55s | %7.2fs | FAILED!\n",
|
||||
kernel_type_as_string(pso_type),
|
||||
device_kernel,
|
||||
|
@ -748,7 +787,8 @@ void MetalKernelPipeline::compile()
|
|||
if (creating_new_archive || recreate_archive) {
|
||||
if (![archive serializeToURL:[NSURL fileURLWithPath:@(metalbin_path.c_str())]
|
||||
error:&error]) {
|
||||
metal_printf("Failed to save binary archive, error:\n%s\n",
|
||||
metal_printf("Failed to save binary archive to %s, error:\n%s\n",
|
||||
metalbin_path.c_str(),
|
||||
[[error localizedDescription] UTF8String]);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -494,7 +494,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
|
|||
|
||||
float3 H;
|
||||
float cos_NH, cos_HI;
|
||||
float3 local_H, local_I, X, Y; /* Nneeded for anisotropic microfacets later. */
|
||||
float3 local_H, local_I, X, Y; /* Needed for anisotropic microfacets later. */
|
||||
if (m_singular) {
|
||||
H = N;
|
||||
cos_NH = 1.0f;
|
||||
|
|
|
@ -979,7 +979,7 @@ ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg,
|
|||
for (int ci = 0; ci < sd_mnee->num_closure; ci++) {
|
||||
ccl_private ShaderClosure *bsdf = &sd_mnee->closure[ci];
|
||||
if (CLOSURE_IS_REFRACTIVE(bsdf->type)) {
|
||||
/* Note that Glass closures are treates as refractive further below. */
|
||||
/* Note that Glass closures are treated as refractive further below. */
|
||||
|
||||
found_refractive_microfacet_bsdf = true;
|
||||
ccl_private MicrofacetBsdf *microfacet_bsdf = (ccl_private MicrofacetBsdf *)bsdf;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef __FFMPEG_COMPAT_H__
|
||||
#define __FFMPEG_COMPAT_H__
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
/* Check if our ffmpeg is new enough, avoids user complaints.
|
||||
|
|
|
@ -177,20 +177,53 @@ typedef enum {
|
|||
typedef enum {
|
||||
GHOST_kEventUnknown = 0,
|
||||
|
||||
GHOST_kEventCursorMove, /* Mouse move event. */
|
||||
GHOST_kEventButtonDown, /* Mouse button event. */
|
||||
GHOST_kEventButtonUp, /* Mouse button event. */
|
||||
GHOST_kEventWheel, /* Mouse wheel event. */
|
||||
GHOST_kEventTrackpad, /* Trackpad event. */
|
||||
/** Mouse move event.
|
||||
*
|
||||
* \note #GHOST_GetEventData returns #GHOST_TEventCursorData.
|
||||
*/
|
||||
GHOST_kEventCursorMove,
|
||||
/** Mouse button down event. */
|
||||
GHOST_kEventButtonDown,
|
||||
/** Mouse button up event. */
|
||||
GHOST_kEventButtonUp,
|
||||
/**
|
||||
* Mouse wheel event.
|
||||
*
|
||||
* \note #GHOST_GetEventData returns #GHOST_TEventWheelData.
|
||||
*/
|
||||
GHOST_kEventWheel,
|
||||
/**
|
||||
* Trackpad event.
|
||||
*
|
||||
* \note #GHOST_GetEventData returns #GHOST_TEventTrackpadData.
|
||||
*/
|
||||
GHOST_kEventTrackpad,
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
GHOST_kEventNDOFMotion, /* N degree of freedom device motion event. */
|
||||
GHOST_kEventNDOFButton, /* N degree of freedom device button event. */
|
||||
/**
|
||||
* N degree of freedom device motion event.
|
||||
*
|
||||
* \note #GHOST_GetEventData returns #GHOST_TEventNDOFMotionData.
|
||||
*/
|
||||
GHOST_kEventNDOFMotion,
|
||||
/**
|
||||
* N degree of freedom device button event.
|
||||
*
|
||||
* \note #GHOST_GetEventData returns #GHOST_TEventNDOFButtonData.
|
||||
*/
|
||||
GHOST_kEventNDOFButton,
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Keyboard up/down events.
|
||||
*
|
||||
* Includes repeat events, check #GHOST_TEventKeyData::is_repeat
|
||||
* if detecting repeat events is needed.
|
||||
*
|
||||
* \note #GHOST_GetEventData returns #GHOST_TEventKeyData.
|
||||
*/
|
||||
GHOST_kEventKeyDown,
|
||||
GHOST_kEventKeyUp,
|
||||
// GHOST_kEventKeyAuto,
|
||||
|
||||
GHOST_kEventQuitRequest,
|
||||
|
||||
|
|
|
@ -20,11 +20,13 @@ enum TransformType {
|
|||
TRANSFORM_SRGB_TO_LINEAR,
|
||||
TRANSFORM_SCALE,
|
||||
TRANSFORM_EXPONENT,
|
||||
TRANSFORM_NONE,
|
||||
TRANSFORM_UNKNOWN,
|
||||
};
|
||||
|
||||
#define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr *)1)
|
||||
#define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr *)2)
|
||||
#define COLORSPACE_DATA ((OCIO_ConstColorSpaceRcPtr *)3)
|
||||
|
||||
typedef struct OCIO_PackedImageDescription {
|
||||
float *data;
|
||||
|
@ -165,6 +167,8 @@ OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcP
|
|||
return COLORSPACE_LINEAR;
|
||||
else if (strcmp(name, "sRGB") == 0)
|
||||
return COLORSPACE_SRGB;
|
||||
else if (strcmp(name, "data") == 0)
|
||||
return COLORSPACE_DATA;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -179,6 +183,9 @@ int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, con
|
|||
else if (cs == COLORSPACE_SRGB) {
|
||||
return 1;
|
||||
}
|
||||
else if (cs == COLORSPACE_DATA) {
|
||||
return 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -314,7 +321,10 @@ OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstCo
|
|||
OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
|
||||
OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
|
||||
FallbackTransform transform;
|
||||
if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
|
||||
if (cs_src == COLORSPACE_DATA || cs_dst == COLORSPACE_DATA) {
|
||||
transform.type = TRANSFORM_NONE;
|
||||
}
|
||||
else if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
|
||||
transform.type = TRANSFORM_LINEAR_TO_SRGB;
|
||||
}
|
||||
else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
|
||||
|
@ -433,6 +443,9 @@ const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
|
|||
else if (cs == COLORSPACE_SRGB) {
|
||||
return "sRGB";
|
||||
}
|
||||
else if (cs == COLORSPACE_DATA) {
|
||||
return "data";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -501,9 +501,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
|||
Recursively get strings, needed in case we have "Blah" + "Blah", passed as an argument in that case it won't
|
||||
evaluate to a string. However, break on some kind of stopper nodes, like e.g. Subscript.
|
||||
"""
|
||||
# New in py 3.8: all constants are of type 'ast.Constant'.
|
||||
# 'ast.Str' will have to be removed when we officially switch to this version.
|
||||
if type(node) in {ast.Str, getattr(ast, "Constant", None)}:
|
||||
if type(node) == ast.Constant:
|
||||
eval_str = ast.literal_eval(node)
|
||||
if eval_str and type(eval_str) == str:
|
||||
yield (is_split, eval_str, (node,))
|
||||
|
@ -692,6 +690,15 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
|||
else:
|
||||
continue
|
||||
|
||||
# Skip function if it's marked as not translatable.
|
||||
do_translate = True
|
||||
for kw in node.keywords:
|
||||
if kw.arg == "translate" and not kw.value.value:
|
||||
do_translate = False
|
||||
break
|
||||
if not do_translate:
|
||||
continue
|
||||
|
||||
func_args = func_translate_args.get(func_id, {})
|
||||
|
||||
# First try to get i18n contexts, for every possible msgid id.
|
||||
|
|
|
@ -13,8 +13,8 @@ from bpy.props import (
|
|||
|
||||
|
||||
class SCENE_OT_freestyle_fill_range_by_selection(Operator):
|
||||
"""Fill the Range Min/Max entries by the min/max distance between selected mesh objects and the source object """
|
||||
"""(either a user-specified object or the active camera)"""
|
||||
"""Fill the Range Min/Max entries by the min/max distance between selected mesh objects and the source object """ \
|
||||
"""(either a user-specified object or the active camera)"""
|
||||
bl_idname = "scene.freestyle_fill_range_by_selection"
|
||||
bl_label = "Fill Range by Selection"
|
||||
bl_options = {'INTERNAL'}
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
import bpy
|
||||
from bpy.types import Menu
|
||||
from bl_ui import node_add_menu
|
||||
from bpy.app.translations import pgettext_iface as iface_
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
contexts as i18n_contexts,
|
||||
)
|
||||
|
||||
|
||||
class NODE_MT_geometry_node_GEO_ATTRIBUTE(Menu):
|
||||
|
@ -238,6 +241,7 @@ class NODE_MT_geometry_node_GEO_INPUT(Menu):
|
|||
class NODE_MT_geometry_node_GEO_INPUT_CONSTANT(Menu):
|
||||
bl_idname = "NODE_MT_geometry_node_GEO_INPUT_CONSTANT"
|
||||
bl_label = "Constant"
|
||||
bl_translation_context = i18n_contexts.id_nodetree
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
|
|
@ -745,6 +745,8 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
|
|||
row.operator("asset.open_containing_blend_file", text="", icon='TOOL_SETTINGS')
|
||||
|
||||
layout.prop(asset_file_handle.asset_data, "description")
|
||||
layout.prop(asset_file_handle.asset_data, "license")
|
||||
layout.prop(asset_file_handle.asset_data, "copyright")
|
||||
layout.prop(asset_file_handle.asset_data, "author")
|
||||
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ class TEXT_HT_footer(Header):
|
|||
text=iface_("Text: External")
|
||||
if text.library
|
||||
else iface_("Text: Internal"),
|
||||
translate=False
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -2832,7 +2832,9 @@ class VIEW3D_MT_object_parent(Menu):
|
|||
layout.separator()
|
||||
|
||||
layout.operator_context = 'EXEC_REGION_WIN'
|
||||
layout.operator("object.parent_no_inverse_set")
|
||||
layout.operator("object.parent_no_inverse_set").keep_transform = False
|
||||
props = layout.operator("object.parent_no_inverse_set", text="Make Parent without Inverse (Keep Transform)")
|
||||
props.keep_transform = True
|
||||
layout.operator_context = operator_context_default
|
||||
|
||||
layout.separator()
|
||||
|
@ -6376,6 +6378,9 @@ class VIEW3D_PT_overlay_object(Panel):
|
|||
|
||||
sub = split.column(align=True)
|
||||
sub.prop(overlay, "show_extras", text="Extras")
|
||||
subsub = sub.column()
|
||||
subsub.active = overlay.show_extras
|
||||
subsub.prop(overlay, "show_light_colors")
|
||||
sub.prop(overlay, "show_relationship_lines")
|
||||
sub.prop(overlay, "show_outline_selected")
|
||||
|
||||
|
|
|
@ -271,9 +271,20 @@ typedef struct bNodeType {
|
|||
/** Check and update if internal ID data has changed. */
|
||||
void (*group_update_func)(struct bNodeTree *ntree, struct bNode *node);
|
||||
|
||||
/** Initialize a new node instance of this type after creation. */
|
||||
/**
|
||||
* Initialize a new node instance of this type after creation.
|
||||
*
|
||||
* \note Assignments to `node->id` must not increment the user of the ID.
|
||||
* This is handled by the caller of this callback.
|
||||
*/
|
||||
void (*initfunc)(struct bNodeTree *ntree, struct bNode *node);
|
||||
/** Free the node instance. */
|
||||
/**
|
||||
* Free the node instance.
|
||||
*
|
||||
* \note Access to `node->id` must be avoided in this function as this is called
|
||||
* while freeing #Main, the state of this ID is undefined.
|
||||
* Higher level logic to remove the node handles the user-count.
|
||||
*/
|
||||
void (*freefunc)(struct bNode *node);
|
||||
/** Make a copy of the node instance. */
|
||||
void (*copyfunc)(struct bNodeTree *dest_ntree,
|
||||
|
|
|
@ -44,6 +44,8 @@ AssetMetaData::~AssetMetaData()
|
|||
}
|
||||
MEM_SAFE_FREE(author);
|
||||
MEM_SAFE_FREE(description);
|
||||
MEM_SAFE_FREE(copyright);
|
||||
MEM_SAFE_FREE(license);
|
||||
BLI_freelistN(&tags);
|
||||
}
|
||||
|
||||
|
@ -161,13 +163,19 @@ void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
|
|||
if (asset_data->properties) {
|
||||
IDP_BlendWrite(writer, asset_data->properties);
|
||||
}
|
||||
|
||||
if (asset_data->author) {
|
||||
BLO_write_string(writer, asset_data->author);
|
||||
}
|
||||
if (asset_data->description) {
|
||||
BLO_write_string(writer, asset_data->description);
|
||||
}
|
||||
if (asset_data->copyright) {
|
||||
BLO_write_string(writer, asset_data->copyright);
|
||||
}
|
||||
if (asset_data->license) {
|
||||
BLO_write_string(writer, asset_data->license);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (AssetTag *, tag, &asset_data->tags) {
|
||||
BLO_write_struct(writer, AssetTag, tag);
|
||||
}
|
||||
|
@ -185,6 +193,8 @@ void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
|
|||
|
||||
BLO_read_data_address(reader, &asset_data->author);
|
||||
BLO_read_data_address(reader, &asset_data->description);
|
||||
BLO_read_data_address(reader, &asset_data->copyright);
|
||||
BLO_read_data_address(reader, &asset_data->license);
|
||||
BLO_read_list(reader, &asset_data->tags);
|
||||
BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
|
||||
}
|
||||
|
|
|
@ -272,7 +272,7 @@ static bool library_foreach_ID_link(Main *bmain,
|
|||
}
|
||||
|
||||
if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY) &&
|
||||
(flag & IDWALK_DO_INTERNAL_RUNTIME_POINTERS) == 0 &&
|
||||
(flag & (IDWALK_DO_INTERNAL_RUNTIME_POINTERS | IDWALK_DO_LIBRARY_POINTER)) == 0 &&
|
||||
(((bmain->relations->flag & MAINIDRELATIONS_INCLUDE_UI) == 0) ==
|
||||
((data.flag & IDWALK_INCLUDE_UI) == 0))) {
|
||||
/* Note that this is minor optimization, even in worst cases (like id being an object with
|
||||
|
|
|
@ -342,7 +342,7 @@ MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name)
|
|||
BLI_strncpy(masklay->name, name, sizeof(masklay->name));
|
||||
}
|
||||
else {
|
||||
strcpy(masklay->name, "MaskLayer");
|
||||
strcpy(masklay->name, DATA_("MaskLayer"));
|
||||
}
|
||||
|
||||
BLI_addtail(&mask->masklayers, masklay);
|
||||
|
|
|
@ -2072,19 +2072,22 @@ bool nodeFindNodeTry(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r
|
|||
|
||||
bNode *nodeFindRootParent(bNode *node)
|
||||
{
|
||||
if (node->parent) {
|
||||
return nodeFindRootParent(node->parent);
|
||||
bNode *parent_iter = node;
|
||||
while (parent_iter->parent != nullptr) {
|
||||
parent_iter = parent_iter->parent;
|
||||
}
|
||||
return node->type == NODE_FRAME ? node : nullptr;
|
||||
if (parent_iter->type != NODE_FRAME) {
|
||||
return nullptr;
|
||||
}
|
||||
return parent_iter;
|
||||
}
|
||||
|
||||
bool nodeIsParentAndChild(const bNode *parent, const bNode *child)
|
||||
{
|
||||
if (parent == child) {
|
||||
return true;
|
||||
}
|
||||
if (child->parent) {
|
||||
return nodeIsParentAndChild(parent, child->parent);
|
||||
for (const bNode *child_iter = child; child_iter; child_iter = child_iter->parent) {
|
||||
if (child_iter == parent) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2583,26 +2586,26 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
|
|||
|
||||
void nodeToView(const bNode *node, const float x, const float y, float *rx, float *ry)
|
||||
{
|
||||
if (node->parent) {
|
||||
nodeToView(node->parent, x + node->locx, y + node->locy, rx, ry);
|
||||
}
|
||||
else {
|
||||
*rx = x + node->locx;
|
||||
*ry = y + node->locy;
|
||||
float mapping_x = 0.0f;
|
||||
float mapping_y = 0.0f;
|
||||
for (const bNode *node_iter = node; node_iter; node_iter = node_iter->parent) {
|
||||
mapping_x += node_iter->locx;
|
||||
mapping_y += node_iter->locy;
|
||||
}
|
||||
*rx = mapping_x + x;
|
||||
*ry = mapping_y + y;
|
||||
}
|
||||
|
||||
void nodeFromView(const bNode *node, const float x, const float y, float *rx, float *ry)
|
||||
{
|
||||
if (node->parent) {
|
||||
nodeFromView(node->parent, x, y, rx, ry);
|
||||
*rx -= node->locx;
|
||||
*ry -= node->locy;
|
||||
}
|
||||
else {
|
||||
*rx = x - node->locx;
|
||||
*ry = y - node->locy;
|
||||
float mapping_x = 0.0f;
|
||||
float mapping_y = 0.0f;
|
||||
for (const bNode *node_iter = node; node_iter; node_iter = node_iter->parent) {
|
||||
mapping_x += node_iter->locx;
|
||||
mapping_y += node_iter->locy;
|
||||
}
|
||||
*rx = -mapping_x + x;
|
||||
*ry = -mapping_y + y;
|
||||
}
|
||||
|
||||
void nodeAttachNode(bNodeTree *ntree, bNode *node, bNode *parent)
|
||||
|
|
|
@ -1517,10 +1517,9 @@ void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track,
|
|||
MovieTrackingMarker *marker_next = marker + 1;
|
||||
|
||||
if (marker_next->framenr == marker->framenr + 1) {
|
||||
/* currently only do subframing inside tracked ranges, do not extrapolate tracked segments
|
||||
/* Currently only do sub-framing inside tracked ranges, do not extrapolate tracked segments
|
||||
* could be changed when / if mask parent would be interpolating position in-between
|
||||
* tracked segments
|
||||
*/
|
||||
* tracked segments. */
|
||||
|
||||
float fac = (framenr - int(framenr)) / (marker_next->framenr - marker->framenr);
|
||||
|
||||
|
|
|
@ -310,7 +310,7 @@ static bool tracking_check_marker_margin(const libmv_Marker *libmv_marker,
|
|||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Autotrack context initialization.
|
||||
/** \name Auto-Track Context Initialization
|
||||
* \{ */
|
||||
|
||||
static bool autotrack_is_marker_usable(const MovieTrackingMarker *marker)
|
||||
|
|
|
@ -383,7 +383,7 @@ static AVFrame *generate_video_frame(FFMpegContext *context, const uint8_t *pixe
|
|||
rgb_frame = context->current_frame;
|
||||
}
|
||||
|
||||
/* Copy the Blender pixels into the FFmpeg datastructure, taking care of endianness and flipping
|
||||
/* Copy the Blender pixels into the FFMPEG data-structure, taking care of endianness and flipping
|
||||
* the image vertically. */
|
||||
int linesize = rgb_frame->linesize[0];
|
||||
for (int y = 0; y < height; y++) {
|
||||
|
|
|
@ -16,27 +16,27 @@
|
|||
|
||||
namespace blender {
|
||||
|
||||
template<typename T> class ListBaseWrapper {
|
||||
template<typename LB, typename T> class ListBaseWrapperTemplate {
|
||||
private:
|
||||
ListBase *listbase_;
|
||||
LB *listbase_;
|
||||
|
||||
public:
|
||||
ListBaseWrapper(ListBase *listbase) : listbase_(listbase)
|
||||
ListBaseWrapperTemplate(LB *listbase) : listbase_(listbase)
|
||||
{
|
||||
BLI_assert(listbase);
|
||||
}
|
||||
|
||||
ListBaseWrapper(ListBase &listbase) : ListBaseWrapper(&listbase)
|
||||
ListBaseWrapperTemplate(LB &listbase) : ListBaseWrapperTemplate(&listbase)
|
||||
{
|
||||
}
|
||||
|
||||
class Iterator {
|
||||
private:
|
||||
ListBase *listbase_;
|
||||
LB *listbase_;
|
||||
T *current_;
|
||||
|
||||
public:
|
||||
Iterator(ListBase *listbase, T *current) : listbase_(listbase), current_(current)
|
||||
Iterator(LB *listbase, T *current) : listbase_(listbase), current_(current)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -96,4 +96,7 @@ template<typename T> class ListBaseWrapper {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T> using ListBaseWrapper = ListBaseWrapperTemplate<ListBase, T>;
|
||||
template<typename T> using ConstListBaseWrapper = ListBaseWrapperTemplate<const ListBase, const T>;
|
||||
|
||||
} /* namespace blender */
|
||||
|
|
|
@ -130,6 +130,8 @@ const char *BLT_translate_do_new_dataname(const char *msgctxt, const char *msgid
|
|||
#define BLT_I18NCONTEXT_VIRTUAL_REALITY "Virtual reality"
|
||||
#define BLT_I18NCONTEXT_CONSTRAINT "Constraint"
|
||||
#define BLT_I18NCONTEXT_COLOR "Color"
|
||||
#define BLT_I18NCONTEXT_AMOUNT "Amount"
|
||||
#define BLT_I18NCONTEXT_UNIT "Unit"
|
||||
|
||||
/* Helper for bpy.app.i18n object... */
|
||||
typedef struct {
|
||||
|
@ -198,6 +200,8 @@ typedef struct {
|
|||
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_VIRTUAL_REALITY, "virtual_reality"), \
|
||||
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_CONSTRAINT, "constraint"), \
|
||||
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_COLOR, "color"), \
|
||||
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_AMOUNT, "amount"), \
|
||||
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_UNIT, "unit"), \
|
||||
{ \
|
||||
NULL, NULL, NULL \
|
||||
} \
|
||||
|
|
|
@ -76,13 +76,25 @@ void RealizeOnDomainOperation::execute()
|
|||
|
||||
GPUShader *RealizeOnDomainOperation::get_realization_shader()
|
||||
{
|
||||
switch (get_result().type()) {
|
||||
case ResultType::Color:
|
||||
return shader_manager().get("compositor_realize_on_domain_color");
|
||||
case ResultType::Vector:
|
||||
return shader_manager().get("compositor_realize_on_domain_vector");
|
||||
case ResultType::Float:
|
||||
return shader_manager().get("compositor_realize_on_domain_float");
|
||||
if (get_input().get_realization_options().interpolation == Interpolation::Bicubic) {
|
||||
switch (get_result().type()) {
|
||||
case ResultType::Color:
|
||||
return shader_manager().get("compositor_realize_on_domain_bicubic_color");
|
||||
case ResultType::Vector:
|
||||
return shader_manager().get("compositor_realize_on_domain_bicubic_vector");
|
||||
case ResultType::Float:
|
||||
return shader_manager().get("compositor_realize_on_domain_bicubic_float");
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (get_result().type()) {
|
||||
case ResultType::Color:
|
||||
return shader_manager().get("compositor_realize_on_domain_color");
|
||||
case ResultType::Vector:
|
||||
return shader_manager().get("compositor_realize_on_domain_vector");
|
||||
case ResultType::Float:
|
||||
return shader_manager().get("compositor_realize_on_domain_float");
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#pragma BLENDER_REQUIRE(gpu_shader_bicubic_sampler_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||
|
||||
void main()
|
||||
|
@ -25,5 +26,5 @@ void main()
|
|||
* the sampler's expected [0, 1] range. */
|
||||
vec2 normalized_coordinates = (coordinates - offset) / vec2(input_size);
|
||||
|
||||
imageStore(domain_img, texel, texture(input_tx, normalized_coordinates));
|
||||
imageStore(domain_img, texel, SAMPLER_FUNCTION(input_tx, normalized_coordinates));
|
||||
}
|
||||
|
|
|
@ -8,17 +8,40 @@ GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_shared)
|
|||
.sampler(0, ImageType::FLOAT_2D, "input_tx")
|
||||
.compute_source("compositor_realize_on_domain.glsl");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_color)
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_standard_shared)
|
||||
.additional_info("compositor_realize_on_domain_shared")
|
||||
.define("SAMPLER_FUNCTION", "texture");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_bicubic_shared)
|
||||
.additional_info("compositor_realize_on_domain_shared")
|
||||
.define("SAMPLER_FUNCTION", "texture_bicubic");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_color)
|
||||
.additional_info("compositor_realize_on_domain_standard_shared")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_vector)
|
||||
.additional_info("compositor_realize_on_domain_shared")
|
||||
.additional_info("compositor_realize_on_domain_standard_shared")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_float)
|
||||
.additional_info("compositor_realize_on_domain_shared")
|
||||
.additional_info("compositor_realize_on_domain_standard_shared")
|
||||
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_bicubic_color)
|
||||
.additional_info("compositor_realize_on_domain_bicubic_shared")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_bicubic_vector)
|
||||
.additional_info("compositor_realize_on_domain_bicubic_shared")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_realize_on_domain_bicubic_float)
|
||||
.additional_info("compositor_realize_on_domain_bicubic_shared")
|
||||
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "domain_img")
|
||||
.do_static_compilation(true);
|
||||
|
|
|
@ -241,7 +241,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
|
|||
}
|
||||
|
||||
/**
|
||||
* Reset for each "redraw". When rendering using ogl render,
|
||||
* Reset for each "redraw". When rendering using OpenGL render,
|
||||
* we accumulate the redraw inside the drawing loop in eevee_draw_scene().
|
||||
*/
|
||||
if (DRW_state_is_opengl_render()) {
|
||||
|
|
|
@ -233,7 +233,7 @@ void MotionBlurModule::render(View &view, GPUTexture **input_tx, GPUTexture **ou
|
|||
|
||||
tiles_tx_.acquire(tiles_extent, GPU_RGBA16F);
|
||||
|
||||
GPU_storagebuf_clear_to_zero(tile_indirection_buf_);
|
||||
tile_indirection_buf_.clear_to_zero();
|
||||
|
||||
inst_.manager->submit(motion_blur_ps_, view);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "BLI_listbase_wrapper.hh"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
@ -46,6 +47,8 @@
|
|||
|
||||
#define PT_DEFAULT_RAD 0.05f /* radius of the point batch. */
|
||||
|
||||
using namespace blender;
|
||||
|
||||
struct ArmatureDrawContext {
|
||||
/* Current armature object */
|
||||
Object *ob;
|
||||
|
@ -2355,7 +2358,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
|
|||
const Object *obact_orig = DEG_get_original_object(draw_ctx->obact);
|
||||
|
||||
const ListBase *defbase = BKE_object_defgroup_list(obact_orig);
|
||||
LISTBASE_FOREACH (const bDeformGroup *, dg, defbase) {
|
||||
for (const bDeformGroup *dg : ConstListBaseWrapper<bDeformGroup>(defbase)) {
|
||||
if (dg->flag & DG_LOCK_WEIGHT) {
|
||||
pchan = BKE_pose_channel_find_name(ob->pose, dg->name);
|
||||
|
||||
|
@ -2437,7 +2440,7 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
|
|||
draw_bone_box(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (arm->drawtype == ARM_OCTA) {
|
||||
draw_bone_update_disp_matrix_default(nullptr, pchan);
|
||||
if (!is_pose_select || pchan_culling_test_octohedral(view, ob, pchan)) {
|
||||
draw_bone_octahedral(ctx, nullptr, pchan, arm, boneflag, constflag, select_id);
|
||||
|
|
|
@ -106,7 +106,7 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
|
|||
/* Complementary Depth Pass */
|
||||
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
|
||||
if (show_retopology) {
|
||||
/* Do not cull backfaces for retopology depth pass.
|
||||
/* Do not cull back-faces for retopology depth pass.
|
||||
* This prevents edit overlays from appearing behind any faces.
|
||||
* Doing so reduces visual clutter. */
|
||||
state &= ~DRW_STATE_CULL_BACK;
|
||||
|
@ -162,9 +162,9 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
|
|||
&pd->edit_mesh_faces_cage_grp[i];
|
||||
state = state_common;
|
||||
if (show_retopology) {
|
||||
/* Cull backfaces for retopology face pass.
|
||||
* This makes it so backfaces are not drawn.
|
||||
* Doing so lets us distinguish backfaces from frontfaces. */
|
||||
/* Cull back-faces for retopology face pass.
|
||||
* This makes it so back-faces are not drawn.
|
||||
* Doing so lets us distinguish back-faces from front-faces. */
|
||||
state |= DRW_STATE_CULL_BACK;
|
||||
}
|
||||
DRW_PASS_CREATE(*edit_face_ps, state | pd->clipping_state);
|
||||
|
|
|
@ -123,6 +123,9 @@ void OVERLAY_extra_cache_init(OVERLAY_Data *vedata)
|
|||
cb->field_tube_limit = BUF_INSTANCE(grp_sub, format, DRW_cache_field_tube_limit_get());
|
||||
cb->field_vortex = BUF_INSTANCE(grp_sub, format, DRW_cache_field_vortex_get());
|
||||
cb->field_wind = BUF_INSTANCE(grp_sub, format, DRW_cache_field_wind_get());
|
||||
cb->light_icon_inner = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_inner_lines_get());
|
||||
cb->light_icon_outer = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_outer_lines_get());
|
||||
cb->light_icon_sun_rays = BUF_INSTANCE(grp_sub, format, DRW_cache_light_icon_sun_rays_get());
|
||||
cb->light_area[0] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_disk_lines_get());
|
||||
cb->light_area[1] = BUF_INSTANCE(grp_sub, format, DRW_cache_light_area_square_lines_get());
|
||||
cb->light_point = BUF_INSTANCE(grp_sub, format, DRW_cache_light_point_lines_get());
|
||||
|
@ -605,8 +608,9 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
|||
Light *la = static_cast<Light *>(ob->data);
|
||||
float *color_p;
|
||||
DRW_object_wire_theme_get(ob, view_layer, &color_p);
|
||||
|
||||
/* Remove the alpha. */
|
||||
float color[4] = {UNPACK3(color_p), 1.0f};
|
||||
float theme_color[4] = {UNPACK3(color_p), 1.0f};
|
||||
/* Pack render data into object matrix. */
|
||||
union {
|
||||
float mat[4][4];
|
||||
|
@ -636,12 +640,25 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
|||
|
||||
DRW_buffer_add_entry(cb->groundline, instdata.pos);
|
||||
|
||||
float light_color[4] = {1.0f};
|
||||
const bool show_light_colors = vedata->stl->pd->overlay.flag & V3D_OVERLAY_SHOW_LIGHT_COLORS;
|
||||
if (show_light_colors) {
|
||||
copy_v3_v3(light_color, &la->r);
|
||||
}
|
||||
|
||||
/* Draw the outer ring of the light icon and the sun rays in `light_color`, if required. */
|
||||
DRW_buffer_add_entry(
|
||||
cb->light_icon_outer, show_light_colors ? light_color : theme_color, &instdata);
|
||||
DRW_buffer_add_entry(cb->light_icon_inner, theme_color, &instdata);
|
||||
|
||||
if (la->type == LA_LOCAL) {
|
||||
instdata.area_size_x = instdata.area_size_y = la->radius;
|
||||
DRW_buffer_add_entry(cb->light_point, color, &instdata);
|
||||
DRW_buffer_add_entry(cb->light_point, theme_color, &instdata);
|
||||
}
|
||||
else if (la->type == LA_SUN) {
|
||||
DRW_buffer_add_entry(cb->light_sun, color, &instdata);
|
||||
DRW_buffer_add_entry(cb->light_sun, theme_color, &instdata);
|
||||
DRW_buffer_add_entry(
|
||||
cb->light_icon_sun_rays, show_light_colors ? light_color : theme_color, &instdata);
|
||||
}
|
||||
else if (la->type == LA_SPOT) {
|
||||
/* Previous implementation was using the clip-end distance as cone size.
|
||||
|
@ -664,8 +681,8 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
|||
instdata.spot_blend = sqrtf((a2 - a2 * c2) / (c2 - a2 * c2));
|
||||
instdata.spot_cosine = a;
|
||||
/* HACK: We pack the area size in alpha color. This is decoded by the shader. */
|
||||
color[3] = -max_ff(la->radius, FLT_MIN);
|
||||
DRW_buffer_add_entry(cb->light_spot, color, &instdata);
|
||||
theme_color[3] = -max_ff(la->radius, FLT_MIN);
|
||||
DRW_buffer_add_entry(cb->light_spot, theme_color, &instdata);
|
||||
|
||||
if ((la->mode & LA_SHOW_CONE) && !DRW_state_is_select()) {
|
||||
const float color_inside[4] = {0.0f, 0.0f, 0.0f, 0.5f};
|
||||
|
@ -679,7 +696,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
|
|||
int sqr = ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_RECT);
|
||||
instdata.area_size_x = la->area_size;
|
||||
instdata.area_size_y = uniform_scale ? la->area_size : la->area_sizey;
|
||||
DRW_buffer_add_entry(cb->light_area[sqr], color, &instdata);
|
||||
DRW_buffer_add_entry(cb->light_area[sqr], theme_color, &instdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,9 @@ typedef struct OVERLAY_ExtraCallBuffers {
|
|||
|
||||
DRWCallBuffer *groundline;
|
||||
|
||||
DRWCallBuffer *light_icon_inner;
|
||||
DRWCallBuffer *light_icon_outer;
|
||||
DRWCallBuffer *light_icon_sun_rays;
|
||||
DRWCallBuffer *light_point;
|
||||
DRWCallBuffer *light_sun;
|
||||
DRWCallBuffer *light_spot;
|
||||
|
|
|
@ -577,7 +577,7 @@ static void write_render_z_output(struct RenderLayer *layer,
|
|||
|
||||
int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
|
||||
|
||||
/* Convert ogl depth [0..1] to view Z [near..far] */
|
||||
/* Convert GPU depth [0..1] to view Z [near..far] */
|
||||
if (DRW_view_is_persp_get(nullptr)) {
|
||||
for (float &z : MutableSpan(rp->rect, pix_num)) {
|
||||
if (z == 1.0f) {
|
||||
|
|
|
@ -120,7 +120,7 @@ static void workbench_render_result_z(struct RenderLayer *rl,
|
|||
|
||||
int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
|
||||
|
||||
/* Convert ogl depth [0..1] to view Z [near..far] */
|
||||
/* Convert GPU depth [0..1] to view Z [near..far] */
|
||||
if (DRW_view_is_persp_get(NULL)) {
|
||||
for (int i = 0; i < pix_num; i++) {
|
||||
if (rp->rect[i] == 1.0f) {
|
||||
|
|
|
@ -116,6 +116,9 @@ static struct DRWShapeCache {
|
|||
GPUBatch *drw_field_cone_limit;
|
||||
GPUBatch *drw_field_sphere_limit;
|
||||
GPUBatch *drw_ground_line;
|
||||
GPUBatch *drw_light_icon_inner_lines;
|
||||
GPUBatch *drw_light_icon_outer_lines;
|
||||
GPUBatch *drw_light_icon_sun_rays;
|
||||
GPUBatch *drw_light_point_lines;
|
||||
GPUBatch *drw_light_sun_lines;
|
||||
GPUBatch *drw_light_spot_lines;
|
||||
|
@ -1461,21 +1464,90 @@ GPUBatch *DRW_cache_groundline_get(void)
|
|||
return SHC.drw_ground_line;
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_light_point_lines_get(void)
|
||||
GPUBatch *DRW_cache_light_icon_inner_lines_get(void)
|
||||
{
|
||||
if (!SHC.drw_light_point_lines) {
|
||||
if (!SHC.drw_light_icon_inner_lines) {
|
||||
GPUVertFormat format = extra_vert_format();
|
||||
|
||||
int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS + OUTER_NSEGMENTS + CIRCLE_NSEGMENTS);
|
||||
int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS);
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
const float r = 9.0f;
|
||||
int v = 0;
|
||||
/* Light Icon */
|
||||
|
||||
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
|
||||
|
||||
SHC.drw_light_icon_inner_lines = GPU_batch_create_ex(
|
||||
GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
||||
}
|
||||
return SHC.drw_light_icon_inner_lines;
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_light_icon_outer_lines_get(void)
|
||||
{
|
||||
if (!SHC.drw_light_icon_outer_lines) {
|
||||
GPUVertFormat format = extra_vert_format();
|
||||
|
||||
int v_len = 2 * OUTER_NSEGMENTS;
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
const float r = 9.0f;
|
||||
int v = 0;
|
||||
|
||||
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
||||
|
||||
SHC.drw_light_icon_outer_lines = GPU_batch_create_ex(
|
||||
GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
||||
}
|
||||
return SHC.drw_light_icon_outer_lines;
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_light_icon_sun_rays_get(void)
|
||||
{
|
||||
if (!SHC.drw_light_icon_sun_rays) {
|
||||
GPUVertFormat format = extra_vert_format();
|
||||
|
||||
const int num_rays = 8;
|
||||
int v_len = 4 * num_rays;
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
const float r = 9.0f;
|
||||
|
||||
int v = 0;
|
||||
|
||||
/* Sun Rays */
|
||||
for (int a = 0; a < num_rays; a++) {
|
||||
float angle = (2.0f * M_PI * a) / (float)num_rays;
|
||||
float s = sinf(angle) * r;
|
||||
float c = cosf(angle) * r;
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.6f, c * 1.6f, 0.0f}, VCLASS_SCREENSPACE});
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.9f, c * 1.9f, 0.0f}, VCLASS_SCREENSPACE});
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.2f, c * 2.2f, 0.0f}, VCLASS_SCREENSPACE});
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.5f, c * 2.5f, 0.0f}, VCLASS_SCREENSPACE});
|
||||
}
|
||||
|
||||
SHC.drw_light_icon_sun_rays = GPU_batch_create_ex(
|
||||
GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
||||
}
|
||||
return SHC.drw_light_icon_sun_rays;
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_light_point_lines_get(void)
|
||||
{
|
||||
if (!SHC.drw_light_point_lines) {
|
||||
GPUVertFormat format = extra_vert_format();
|
||||
|
||||
int v_len = 2 * CIRCLE_NSEGMENTS;
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
int v = 0;
|
||||
|
||||
/* Light area */
|
||||
int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE;
|
||||
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
|
||||
|
@ -1490,26 +1562,12 @@ GPUBatch *DRW_cache_light_sun_lines_get(void)
|
|||
if (!SHC.drw_light_sun_lines) {
|
||||
GPUVertFormat format = extra_vert_format();
|
||||
|
||||
int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS + OUTER_NSEGMENTS + 8 * 2 + 1);
|
||||
int v_len = 2;
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
const float r = 9.0f;
|
||||
int v = 0;
|
||||
/* Light Icon */
|
||||
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
||||
/* Sun Rays */
|
||||
for (int a = 0; a < 8; a++) {
|
||||
float angle = (2.0f * M_PI * a) / 8.0f;
|
||||
float s = sinf(angle) * r;
|
||||
float c = cosf(angle) * r;
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.6f, c * 1.6f, 0.0f}, VCLASS_SCREENSPACE});
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 1.9f, c * 1.9f, 0.0f}, VCLASS_SCREENSPACE});
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.2f, c * 2.2f, 0.0f}, VCLASS_SCREENSPACE});
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{s * 2.5f, c * 2.5f, 0.0f}, VCLASS_SCREENSPACE});
|
||||
}
|
||||
|
||||
/* Direction Line */
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0, 0.0, 0.0}, 0});
|
||||
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0, 0.0, -20.0}, 0}); /* Good default. */
|
||||
|
@ -1524,17 +1582,12 @@ GPUBatch *DRW_cache_light_spot_lines_get(void)
|
|||
if (!SHC.drw_light_spot_lines) {
|
||||
GPUVertFormat format = extra_vert_format();
|
||||
|
||||
int v_len = 2 * (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS +
|
||||
CIRCLE_NSEGMENTS * 4 + 1);
|
||||
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS * 4 + 1);
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
const float r = 9.0f;
|
||||
int v = 0;
|
||||
/* Light Icon */
|
||||
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
||||
|
||||
/* Light area */
|
||||
int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE;
|
||||
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
|
||||
|
@ -1597,17 +1650,12 @@ GPUBatch *DRW_cache_light_area_disk_lines_get(void)
|
|||
if (!SHC.drw_light_area_disk_lines) {
|
||||
GPUVertFormat format = extra_vert_format();
|
||||
|
||||
int v_len = 2 *
|
||||
(DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + CIRCLE_NSEGMENTS + 1);
|
||||
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS + 1);
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
const float r = 9.0f;
|
||||
int v = 0;
|
||||
/* Light Icon */
|
||||
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
||||
|
||||
/* Light area */
|
||||
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 0.5f, 0.0f, VCLASS_LIGHT_AREA_SHAPE);
|
||||
/* Direction Line */
|
||||
|
@ -1630,15 +1678,11 @@ GPUBatch *DRW_cache_light_area_square_lines_get(void)
|
|||
GPUVertFormat format = extra_vert_format();
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
int v_len = 2 * (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + 4 + 1);
|
||||
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + 4 + 1);
|
||||
GPU_vertbuf_data_alloc(vbo, v_len);
|
||||
|
||||
const float r = 9.0f;
|
||||
int v = 0;
|
||||
/* Light Icon */
|
||||
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
|
||||
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
||||
|
||||
/* Light area */
|
||||
int flag = VCLASS_LIGHT_AREA_SHAPE;
|
||||
for (int a = 0; a < 4; a++) {
|
||||
|
|
|
@ -106,6 +106,9 @@ struct GPUBatch *DRW_cache_field_sphere_limit_get(void);
|
|||
|
||||
/* Lights */
|
||||
|
||||
struct GPUBatch *DRW_cache_light_icon_inner_lines_get(void);
|
||||
struct GPUBatch *DRW_cache_light_icon_outer_lines_get(void);
|
||||
struct GPUBatch *DRW_cache_light_icon_sun_rays_get(void);
|
||||
struct GPUBatch *DRW_cache_light_point_lines_get(void);
|
||||
struct GPUBatch *DRW_cache_light_sun_lines_get(void);
|
||||
struct GPUBatch *DRW_cache_light_spot_lines_get(void);
|
||||
|
|
|
@ -56,13 +56,16 @@ using namespace blender::bke::idprop;
|
|||
* "catalog_name": "<catalog_name>",
|
||||
* "description": "<description>",
|
||||
* "author": "<author>",
|
||||
* "copyright": "<copyright>",
|
||||
* "license": "<license>",
|
||||
* "tags": ["<tag>"],
|
||||
* "properties": [..]
|
||||
* }]
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* NOTE: entries, author, description, tags and properties are optional attributes.
|
||||
* NOTE: entries, author, description, copyright, license, tags and properties are optional
|
||||
* attributes.
|
||||
*
|
||||
* NOTE: File browser uses name and idcode separate. Inside the index they are joined together like
|
||||
* #ID.name.
|
||||
|
@ -75,6 +78,8 @@ constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_ID("catalog_id");
|
|||
constexpr StringRef ATTRIBUTE_ENTRIES_CATALOG_NAME("catalog_name");
|
||||
constexpr StringRef ATTRIBUTE_ENTRIES_DESCRIPTION("description");
|
||||
constexpr StringRef ATTRIBUTE_ENTRIES_AUTHOR("author");
|
||||
constexpr StringRef ATTRIBUTE_ENTRIES_COPYRIGHT("copyright");
|
||||
constexpr StringRef ATTRIBUTE_ENTRIES_LICENSE("license");
|
||||
constexpr StringRef ATTRIBUTE_ENTRIES_TAGS("tags");
|
||||
constexpr StringRef ATTRIBUTE_ENTRIES_PROPERTIES("properties");
|
||||
|
||||
|
@ -178,6 +183,26 @@ struct AssetEntryReader {
|
|||
return lookup.lookup(ATTRIBUTE_ENTRIES_AUTHOR)->as_string_value()->value();
|
||||
}
|
||||
|
||||
bool has_copyright() const
|
||||
{
|
||||
return lookup.contains(ATTRIBUTE_ENTRIES_COPYRIGHT);
|
||||
}
|
||||
|
||||
StringRefNull get_copyright() const
|
||||
{
|
||||
return lookup.lookup(ATTRIBUTE_ENTRIES_COPYRIGHT)->as_string_value()->value();
|
||||
}
|
||||
|
||||
bool has_license() const
|
||||
{
|
||||
return lookup.contains(ATTRIBUTE_ENTRIES_LICENSE);
|
||||
}
|
||||
|
||||
StringRefNull get_license() const
|
||||
{
|
||||
return lookup.lookup(ATTRIBUTE_ENTRIES_LICENSE)->as_string_value()->value();
|
||||
}
|
||||
|
||||
StringRefNull get_catalog_name() const
|
||||
{
|
||||
return lookup.lookup(ATTRIBUTE_ENTRIES_CATALOG_NAME)->as_string_value()->value();
|
||||
|
@ -267,6 +292,16 @@ struct AssetEntryWriter {
|
|||
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_AUTHOR, new StringValue(author)));
|
||||
}
|
||||
|
||||
void add_copyright(const StringRefNull copyright)
|
||||
{
|
||||
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_COPYRIGHT, new StringValue(copyright)));
|
||||
}
|
||||
|
||||
void add_license(const StringRefNull license)
|
||||
{
|
||||
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_LICENSE, new StringValue(license)));
|
||||
}
|
||||
|
||||
void add_tags(const ListBase /* AssetTag */ *asset_tags)
|
||||
{
|
||||
ArrayValue *tags = new ArrayValue();
|
||||
|
@ -305,6 +340,12 @@ static void init_value_from_file_indexer_entry(AssetEntryWriter &result,
|
|||
if (asset_data.author != nullptr) {
|
||||
result.add_author(asset_data.author);
|
||||
}
|
||||
if (asset_data.copyright != nullptr) {
|
||||
result.add_copyright(asset_data.copyright);
|
||||
}
|
||||
if (asset_data.license != nullptr) {
|
||||
result.add_license(asset_data.license);
|
||||
}
|
||||
|
||||
if (!BLI_listbase_is_empty(&asset_data.tags)) {
|
||||
result.add_tags(&asset_data.tags);
|
||||
|
@ -372,6 +413,18 @@ static void init_indexer_entry_from_value(FileIndexerEntry &indexer_entry,
|
|||
BLI_strncpy(author_c_str, author.c_str(), author.size() + 1);
|
||||
asset_data->author = author_c_str;
|
||||
}
|
||||
if (entry.has_copyright()) {
|
||||
const StringRefNull copyright = entry.get_copyright();
|
||||
char *copyright_c_str = static_cast<char *>(MEM_mallocN(copyright.size() + 1, __func__));
|
||||
BLI_strncpy(copyright_c_str, copyright.c_str(), copyright.size() + 1);
|
||||
asset_data->copyright = copyright_c_str;
|
||||
}
|
||||
if (entry.has_license()) {
|
||||
const StringRefNull license = entry.get_license();
|
||||
char *license_c_str = static_cast<char *>(MEM_mallocN(license.size() + 1, __func__));
|
||||
BLI_strncpy(license_c_str, license.c_str(), license.size() + 1);
|
||||
asset_data->license = license_c_str;
|
||||
}
|
||||
|
||||
const StringRefNull catalog_name = entry.get_catalog_name();
|
||||
BLI_strncpy(asset_data->catalog_simple_name,
|
||||
|
|
|
@ -580,12 +580,19 @@ static void cage2d_draw_circle_wire(const float color[3],
|
|||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void cage2d_draw_rect_handles(const rctf *r,
|
||||
const float margin[2],
|
||||
const float color[3],
|
||||
const int transform_flag,
|
||||
bool solid)
|
||||
static void cage2d_draw_rect_corner_handles(const rctf *r,
|
||||
const int highlighted,
|
||||
const float margin[2],
|
||||
const float color[3],
|
||||
const int transform_flag,
|
||||
bool solid)
|
||||
{
|
||||
/* Only draw corner handles when hovering over the corners. */
|
||||
if (highlighted < ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y ||
|
||||
highlighted > ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
void (*circle_fn)(uint, float, float, float, float, int) = (solid) ?
|
||||
imm_draw_circle_fill_aspect_2d :
|
||||
|
@ -615,6 +622,38 @@ static void cage2d_draw_rect_handles(const rctf *r,
|
|||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void cage2d_draw_rect_edge_handles(const rctf *r,
|
||||
const int highlighted,
|
||||
const float size[2],
|
||||
const float margin[2],
|
||||
const float color[3],
|
||||
bool solid)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor3fv(color);
|
||||
|
||||
switch (highlighted) {
|
||||
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X:
|
||||
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X: {
|
||||
const float rad[2] = {0.2f * margin[0], 0.4f * size[1]};
|
||||
imm_draw_point_aspect_2d(pos, r->xmin, 0.f, rad[0], rad[1], solid);
|
||||
imm_draw_point_aspect_2d(pos, r->xmax, 0.f, rad[0], rad[1], solid);
|
||||
break;
|
||||
}
|
||||
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y:
|
||||
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y: {
|
||||
const float rad[2] = {0.4f * size[0], 0.2f * margin[1]};
|
||||
imm_draw_point_aspect_2d(pos, 0.f, r->ymin, rad[0], rad[1], solid);
|
||||
imm_draw_point_aspect_2d(pos, 0.f, r->ymax, rad[0], rad[1], solid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
||||
|
@ -665,15 +704,15 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||
else {
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) {
|
||||
int scale_parts[] = {
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y,
|
||||
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y,
|
||||
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y,
|
||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y,
|
||||
};
|
||||
for (int i = 0; i < ARRAY_SIZE(scale_parts); i++) {
|
||||
GPU_select_load_id(select_id | scale_parts[i]);
|
||||
|
@ -754,9 +793,15 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||
cage2d_draw_rect_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
|
||||
cage2d_draw_rect_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
|
||||
|
||||
/* Corner gizmos. */
|
||||
cage2d_draw_rect_handles(&r, margin, black, transform_flag, false);
|
||||
cage2d_draw_rect_handles(&r, margin, color, transform_flag, true);
|
||||
/* Edge handles. */
|
||||
cage2d_draw_rect_edge_handles(&r, gz->highlight_part, size_real, margin, color, true);
|
||||
cage2d_draw_rect_edge_handles(&r, gz->highlight_part, size_real, margin, black, false);
|
||||
|
||||
/* Corner handles. */
|
||||
cage2d_draw_rect_corner_handles(
|
||||
&r, gz->highlight_part, margin, color, transform_flag, true);
|
||||
cage2d_draw_rect_corner_handles(
|
||||
&r, gz->highlight_part, margin, black, transform_flag, false);
|
||||
}
|
||||
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
||||
cage2d_draw_circle_wire(black, size_real, margin, outline_line_width);
|
||||
|
|
|
@ -252,6 +252,7 @@ void ED_gpencil_trace_data_to_strokes(Main *bmain,
|
|||
float start_point[2], last[2];
|
||||
start_point[0] = c[n - 1][2].x;
|
||||
start_point[1] = c[n - 1][2].y;
|
||||
zero_v2(last);
|
||||
|
||||
for (int32_t i = 0; i < n; i++) {
|
||||
switch (tag[i]) {
|
||||
|
|
|
@ -3877,7 +3877,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
|
|||
case UI_BTYPE_KEY_EVENT: {
|
||||
const char *str;
|
||||
if (but->flag & UI_SELECT) {
|
||||
str = "Press a key";
|
||||
str = IFACE_("Press a key");
|
||||
}
|
||||
else {
|
||||
UI_GET_BUT_VALUE_INIT(but, value);
|
||||
|
@ -3910,7 +3910,7 @@ static void ui_but_update_ex(uiBut *but, const bool validate)
|
|||
(void)str; /* UNUSED */
|
||||
}
|
||||
else {
|
||||
BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR);
|
||||
BLI_strncpy(but->drawstr, IFACE_("Press a key"), UI_MAX_DRAW_STR);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -5912,7 +5912,8 @@ static bool ui_layout_has_panel_label(const uiLayout *layout, const PanelType *p
|
|||
LISTBASE_FOREACH (uiItem *, subitem, &layout->items) {
|
||||
if (subitem->type == ITEM_BUTTON) {
|
||||
uiButtonItem *bitem = (uiButtonItem *)subitem;
|
||||
if (!(bitem->but->flag & UI_HIDDEN) && STREQ(bitem->but->str, pt->label)) {
|
||||
if (!(bitem->but->flag & UI_HIDDEN) &&
|
||||
STREQ(bitem->but->str, CTX_IFACE_(pt->translation_context, pt->label))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ static int wm_ply_export_exec(bContext *C, wmOperator *op)
|
|||
BKE_report(op->reports, RPT_ERROR, "No filename given");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
struct PLYExportParams export_params;
|
||||
struct PLYExportParams export_params = {"\0"};
|
||||
export_params.file_base_for_tests[0] = '\0';
|
||||
RNA_string_get(op->ptr, "filepath", export_params.filepath);
|
||||
export_params.blen_filepath = CTX_data_main(C)->filepath;
|
||||
|
|
|
@ -2810,8 +2810,10 @@ void TEXT_OT_scroll(wmOperatorType *ot)
|
|||
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_XY | OPTYPE_INTERNAL;
|
||||
|
||||
/* properties */
|
||||
RNA_def_int(
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_int(
|
||||
ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100);
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -2915,8 +2917,10 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot)
|
|||
ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
|
||||
|
||||
/* properties */
|
||||
RNA_def_int(
|
||||
PropertyRNA *prop;
|
||||
prop = RNA_def_int(
|
||||
ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll", -100, 100);
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -51,6 +51,7 @@ set(SRC
|
|||
transform_convert_sequencer.c
|
||||
transform_convert_sequencer_image.c
|
||||
transform_convert_tracking.c
|
||||
transform_convert_tracking_curves.c
|
||||
transform_draw_cursors.c
|
||||
transform_generics.c
|
||||
transform_gizmo_2d.c
|
||||
|
|
|
@ -624,7 +624,9 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
|
|||
return false;
|
||||
}
|
||||
if (value == TFM_MODAL_TRANSLATE && t->mode == TFM_TRANSLATION) {
|
||||
return false;
|
||||
/* The tracking transform in MovieClip has an alternate translate that modifies the offset
|
||||
* of the tracks. */
|
||||
return t->data_type == &TransConvertType_Tracking;
|
||||
}
|
||||
if (value == TFM_MODAL_ROTATE && t->mode == TFM_ROTATION) {
|
||||
return false;
|
||||
|
@ -987,16 +989,16 @@ int transformEvent(TransInfo *t, const wmEvent *event)
|
|||
t->redraw |= TREDRAW_HARD;
|
||||
handled = true;
|
||||
}
|
||||
else if (t->options & (CTX_MOVIECLIP | CTX_MASK)) {
|
||||
restoreTransObjects(t);
|
||||
|
||||
t->flag ^= T_ALT_TRANSFORM;
|
||||
t->redraw |= TREDRAW_HARD;
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (t->mode == TFM_TRANSLATION) {
|
||||
if (t->data_type == &TransConvertType_Tracking) {
|
||||
restoreTransObjects(t);
|
||||
|
||||
t->flag ^= T_ALT_TRANSFORM;
|
||||
t->redraw |= TREDRAW_HARD;
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
restoreTransObjects(t);
|
||||
|
|
|
@ -932,6 +932,9 @@ static TransConvertTypeInfo *convert_type_get(const TransInfo *t, Object **r_obj
|
|||
}
|
||||
if (t->spacetype == SPACE_CLIP) {
|
||||
if (t->options & CTX_MOVIECLIP) {
|
||||
if (t->region->regiontype == RGN_TYPE_PREVIEW) {
|
||||
return &TransConvertType_TrackingCurves;
|
||||
}
|
||||
return &TransConvertType_Tracking;
|
||||
}
|
||||
if (t->options & CTX_MASK) {
|
||||
|
|
|
@ -276,6 +276,10 @@ extern TransConvertTypeInfo TransConvertType_SequencerImage;
|
|||
|
||||
extern TransConvertTypeInfo TransConvertType_Tracking;
|
||||
|
||||
/* transform_convert_tracking_curves.c */
|
||||
|
||||
extern TransConvertTypeInfo TransConvertType_TrackingCurves;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -9,26 +9,24 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_tracking.h"
|
||||
|
||||
#include "ED_clip.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "transform.h"
|
||||
#include "transform_convert.h"
|
||||
|
||||
typedef struct TransDataTracking {
|
||||
int mode, flag;
|
||||
int mode;
|
||||
int flag;
|
||||
|
||||
/* tracks transformation from main window */
|
||||
int area;
|
||||
|
@ -41,18 +39,13 @@ typedef struct TransDataTracking {
|
|||
int framenr;
|
||||
MovieTrackingMarker *markers;
|
||||
|
||||
/* marker transformation from curves editor */
|
||||
float *prev_pos, scale;
|
||||
short coord;
|
||||
|
||||
MovieTrackingTrack *track;
|
||||
MovieTrackingPlaneTrack *plane_track;
|
||||
} TransDataTracking;
|
||||
|
||||
enum transDataTracking_Mode {
|
||||
transDataTracking_ModeTracks = 0,
|
||||
transDataTracking_ModeCurves = 1,
|
||||
transDataTracking_ModePlaneTracks = 2,
|
||||
transDataTracking_ModePlaneTracks = 1,
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -379,139 +372,8 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
|
|||
}
|
||||
}
|
||||
|
||||
static void markerToTransCurveDataInit(TransData *td,
|
||||
TransData2D *td2d,
|
||||
TransDataTracking *tdt,
|
||||
MovieTrackingTrack *track,
|
||||
MovieTrackingMarker *marker,
|
||||
MovieTrackingMarker *prev_marker,
|
||||
short coord,
|
||||
float size)
|
||||
{
|
||||
float frames_delta = (marker->framenr - prev_marker->framenr);
|
||||
|
||||
tdt->flag = marker->flag;
|
||||
marker->flag &= ~MARKER_TRACKED;
|
||||
|
||||
tdt->mode = transDataTracking_ModeCurves;
|
||||
tdt->coord = coord;
|
||||
tdt->scale = 1.0f / size * frames_delta;
|
||||
tdt->prev_pos = prev_marker->pos;
|
||||
tdt->track = track;
|
||||
|
||||
/* calculate values depending on marker's speed */
|
||||
td2d->loc[0] = marker->framenr;
|
||||
td2d->loc[1] = (marker->pos[coord] - prev_marker->pos[coord]) * size / frames_delta;
|
||||
td2d->loc[2] = 0.0f;
|
||||
|
||||
td2d->loc2d = marker->pos; /* current location */
|
||||
|
||||
td->flag = 0;
|
||||
td->loc = td2d->loc;
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
td->flag |= TD_SELECTED;
|
||||
td->dist = 0.0;
|
||||
|
||||
unit_m3(td->mtx);
|
||||
unit_m3(td->smtx);
|
||||
}
|
||||
|
||||
static void createTransTrackingCurvesData(bContext *C, TransInfo *t)
|
||||
{
|
||||
TransData *td;
|
||||
TransData2D *td2d;
|
||||
SpaceClip *sc = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
|
||||
TransDataTracking *tdt;
|
||||
|
||||
int width, height;
|
||||
BKE_movieclip_get_size(clip, &sc->user, &width, &height);
|
||||
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
|
||||
/* count */
|
||||
tc->data_len = 0;
|
||||
|
||||
if ((sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
||||
if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
|
||||
for (int i = 1; i < track->markersnr; i++) {
|
||||
const MovieTrackingMarker *marker = &track->markers[i];
|
||||
const MovieTrackingMarker *prev_marker = &track->markers[i - 1];
|
||||
|
||||
if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marker->flag & MARKER_GRAPH_SEL_X) {
|
||||
tc->data_len += 1;
|
||||
}
|
||||
|
||||
if (marker->flag & MARKER_GRAPH_SEL_Y) {
|
||||
tc->data_len += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tc->data_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
|
||||
td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
|
||||
"TransTracking TransData2D");
|
||||
tc->custom.type.data = tdt = MEM_callocN(tc->data_len * sizeof(TransDataTracking),
|
||||
"TransTracking TransDataTracking");
|
||||
tc->custom.type.free_cb = transDataTrackingFree;
|
||||
|
||||
/* create actual data */
|
||||
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
||||
if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
|
||||
for (int i = 1; i < track->markersnr; i++) {
|
||||
MovieTrackingMarker *marker = &track->markers[i];
|
||||
MovieTrackingMarker *prev_marker = &track->markers[i - 1];
|
||||
|
||||
if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marker->flag & MARKER_GRAPH_SEL_X) {
|
||||
markerToTransCurveDataInit(
|
||||
td, td2d, tdt, track, marker, &track->markers[i - 1], 0, width);
|
||||
td += 1;
|
||||
td2d += 1;
|
||||
tdt += 1;
|
||||
}
|
||||
|
||||
if (marker->flag & MARKER_GRAPH_SEL_Y) {
|
||||
markerToTransCurveDataInit(
|
||||
td, td2d, tdt, track, marker, &track->markers[i - 1], 1, height);
|
||||
|
||||
td += 1;
|
||||
td2d += 1;
|
||||
tdt += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createTransTrackingData(bContext *C, TransInfo *t)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
SpaceClip *sc = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
int width, height;
|
||||
|
@ -530,13 +392,7 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
|
|||
return;
|
||||
}
|
||||
|
||||
if (region->regiontype == RGN_TYPE_PREVIEW) {
|
||||
/* transformation was called from graph editor */
|
||||
createTransTrackingCurvesData(C, t);
|
||||
}
|
||||
else {
|
||||
createTransTrackingTracksData(C, t);
|
||||
}
|
||||
createTransTrackingTracksData(C, t);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -574,24 +430,6 @@ static void cancelTransTracking(TransInfo *t)
|
|||
i += 2;
|
||||
}
|
||||
}
|
||||
else if (tdt->mode == transDataTracking_ModeCurves) {
|
||||
MovieTrackingTrack *track = tdt->track;
|
||||
MovieTrackingMarker *marker, *prev_marker;
|
||||
int a;
|
||||
|
||||
for (a = 1; a < track->markersnr; a++) {
|
||||
marker = &track->markers[a];
|
||||
prev_marker = &track->markers[a - 1];
|
||||
|
||||
if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marker->flag & (MARKER_GRAPH_SEL_X | MARKER_GRAPH_SEL_Y)) {
|
||||
marker->flag = tdt->flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tdt->mode == transDataTracking_ModePlaneTracks) {
|
||||
MovieTrackingPlaneTrack *plane_track = tdt->plane_track;
|
||||
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get_exact(plane_track,
|
||||
|
@ -675,9 +513,6 @@ static void flushTransTracking(TransInfo *t)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (tdt->mode == transDataTracking_ModeCurves) {
|
||||
td2d->loc2d[tdt->coord] = tdt->prev_pos[tdt->coord] + td2d->loc[1] * tdt->scale;
|
||||
}
|
||||
else if (tdt->mode == transDataTracking_ModePlaneTracks) {
|
||||
td2d->loc2d[0] = td2d->loc[0] / t->aspect[0];
|
||||
td2d->loc2d[1] = td2d->loc[1] / t->aspect[1];
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2001-2002 NaN Holding BV. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup edtransform
|
||||
*/
|
||||
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_tracking.h"
|
||||
|
||||
#include "ED_clip.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "transform.h"
|
||||
#include "transform_convert.h"
|
||||
|
||||
typedef struct TransDataTrackingCurves {
|
||||
int flag;
|
||||
|
||||
/* marker transformation from curves editor */
|
||||
float *prev_pos;
|
||||
float scale;
|
||||
short coord;
|
||||
|
||||
MovieTrackingTrack *track;
|
||||
} TransDataTrackingCurves;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Clip Editor Motion Tracking Transform Creation
|
||||
* \{ */
|
||||
|
||||
static void markerToTransCurveDataInit(TransData *td,
|
||||
TransData2D *td2d,
|
||||
TransDataTrackingCurves *tdt,
|
||||
MovieTrackingTrack *track,
|
||||
MovieTrackingMarker *marker,
|
||||
MovieTrackingMarker *prev_marker,
|
||||
short coord,
|
||||
float size)
|
||||
{
|
||||
float frames_delta = (marker->framenr - prev_marker->framenr);
|
||||
|
||||
tdt->flag = marker->flag;
|
||||
marker->flag &= ~MARKER_TRACKED;
|
||||
|
||||
tdt->coord = coord;
|
||||
tdt->scale = 1.0f / size * frames_delta;
|
||||
tdt->prev_pos = prev_marker->pos;
|
||||
tdt->track = track;
|
||||
|
||||
/* calculate values depending on marker's speed */
|
||||
td2d->loc[0] = marker->framenr;
|
||||
td2d->loc[1] = (marker->pos[coord] - prev_marker->pos[coord]) * size / frames_delta;
|
||||
td2d->loc[2] = 0.0f;
|
||||
|
||||
td2d->loc2d = marker->pos; /* current location */
|
||||
|
||||
td->flag = 0;
|
||||
td->loc = td2d->loc;
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
|
||||
memset(td->axismtx, 0, sizeof(td->axismtx));
|
||||
td->axismtx[2][2] = 1.0f;
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
td->flag |= TD_SELECTED;
|
||||
td->dist = 0.0;
|
||||
|
||||
unit_m3(td->mtx);
|
||||
unit_m3(td->smtx);
|
||||
}
|
||||
|
||||
static void createTransTrackingCurvesData(bContext *C, TransInfo *t)
|
||||
{
|
||||
TransData *td;
|
||||
TransData2D *td2d;
|
||||
SpaceClip *sc = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
|
||||
TransDataTrackingCurves *tdt;
|
||||
|
||||
int width, height;
|
||||
BKE_movieclip_get_size(clip, &sc->user, &width, &height);
|
||||
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
|
||||
/* count */
|
||||
tc->data_len = 0;
|
||||
|
||||
if ((sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
||||
if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
|
||||
for (int i = 1; i < track->markersnr; i++) {
|
||||
const MovieTrackingMarker *marker = &track->markers[i];
|
||||
const MovieTrackingMarker *prev_marker = &track->markers[i - 1];
|
||||
|
||||
if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marker->flag & MARKER_GRAPH_SEL_X) {
|
||||
tc->data_len += 1;
|
||||
}
|
||||
|
||||
if (marker->flag & MARKER_GRAPH_SEL_Y) {
|
||||
tc->data_len += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tc->data_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
|
||||
td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D),
|
||||
"TransTracking TransData2D");
|
||||
tc->custom.type.data = tdt = MEM_callocN(tc->data_len * sizeof(TransDataTrackingCurves),
|
||||
"TransTracking TransDataTracking");
|
||||
tc->custom.type.free_cb = NULL;
|
||||
|
||||
/* create actual data */
|
||||
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
||||
if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
|
||||
for (int i = 1; i < track->markersnr; i++) {
|
||||
MovieTrackingMarker *marker = &track->markers[i];
|
||||
MovieTrackingMarker *prev_marker = &track->markers[i - 1];
|
||||
|
||||
if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marker->flag & MARKER_GRAPH_SEL_X) {
|
||||
markerToTransCurveDataInit(
|
||||
td, td2d, tdt, track, marker, &track->markers[i - 1], 0, width);
|
||||
td += 1;
|
||||
td2d += 1;
|
||||
tdt += 1;
|
||||
}
|
||||
|
||||
if (marker->flag & MARKER_GRAPH_SEL_Y) {
|
||||
markerToTransCurveDataInit(
|
||||
td, td2d, tdt, track, marker, &track->markers[i - 1], 1, height);
|
||||
|
||||
td += 1;
|
||||
td2d += 1;
|
||||
tdt += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createTransTrackingCurves(bContext *C, TransInfo *t)
|
||||
{
|
||||
SpaceClip *sc = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
int width, height;
|
||||
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
|
||||
tc->data_len = 0;
|
||||
|
||||
if (!clip) {
|
||||
return;
|
||||
}
|
||||
|
||||
BKE_movieclip_get_size(clip, &sc->user, &width, &height);
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* transformation was called from graph editor */
|
||||
BLI_assert(CTX_wm_region(C)->regiontype == RGN_TYPE_PREVIEW);
|
||||
createTransTrackingCurvesData(C, t);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name recalc Motion Tracking TransData
|
||||
* \{ */
|
||||
|
||||
static void cancelTransTrackingCurves(TransInfo *t)
|
||||
{
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
TransDataTrackingCurves *tdt_array = tc->custom.type.data;
|
||||
|
||||
int i = 0;
|
||||
while (i < tc->data_len) {
|
||||
TransDataTrackingCurves *tdt = &tdt_array[i];
|
||||
|
||||
{
|
||||
MovieTrackingTrack *track = tdt->track;
|
||||
MovieTrackingMarker *marker, *prev_marker;
|
||||
int a;
|
||||
|
||||
for (a = 1; a < track->markersnr; a++) {
|
||||
marker = &track->markers[a];
|
||||
prev_marker = &track->markers[a - 1];
|
||||
|
||||
if ((marker->flag & MARKER_DISABLED) || (prev_marker->flag & MARKER_DISABLED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (marker->flag & (MARKER_GRAPH_SEL_X | MARKER_GRAPH_SEL_Y)) {
|
||||
marker->flag = tdt->flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void flushTransTrackingCurves(TransInfo *t)
|
||||
{
|
||||
TransData *td;
|
||||
TransData2D *td2d;
|
||||
TransDataTrackingCurves *tdt;
|
||||
int td_index;
|
||||
|
||||
if (t->state == TRANS_CANCEL) {
|
||||
cancelTransTrackingCurves(t);
|
||||
}
|
||||
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
|
||||
/* flush to 2d vector from internally used 3d vector */
|
||||
for (td_index = 0, td = tc->data, td2d = tc->data_2d, tdt = tc->custom.type.data;
|
||||
td_index < tc->data_len;
|
||||
td_index++, td2d++, td++, tdt++) {
|
||||
{
|
||||
td2d->loc2d[tdt->coord] = tdt->prev_pos[tdt->coord] + td2d->loc[1] * tdt->scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void recalcData_tracking_curves(TransInfo *t)
|
||||
{
|
||||
SpaceClip *sc = t->area->spacedata.first;
|
||||
|
||||
if (ED_space_clip_check_show_trackedit(sc)) {
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
|
||||
flushTransTrackingCurves(t);
|
||||
|
||||
DEG_id_tag_update(&clip->id, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Special After Transform Tracking
|
||||
* \{ */
|
||||
|
||||
static void special_aftertrans_update__movieclip_for_curves(bContext *C, TransInfo *t)
|
||||
{
|
||||
SpaceClip *sc = t->area->spacedata.first;
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
if (t->scene->nodetree != NULL) {
|
||||
/* Tracks can be used for stabilization nodes,
|
||||
* flush update for such nodes.
|
||||
*/
|
||||
if (t->context != NULL) {
|
||||
Main *bmain = CTX_data_main(C);
|
||||
BKE_ntree_update_tag_id_changed(bmain, &clip->id);
|
||||
BKE_ntree_update_main(bmain, NULL);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_NODES, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
TransConvertTypeInfo TransConvertType_TrackingCurves = {
|
||||
/*flags*/ (T_POINTS | T_2D_EDIT),
|
||||
/*createTransData*/ createTransTrackingCurves,
|
||||
/*recalcData*/ recalcData_tracking_curves,
|
||||
/*special_aftertrans_update*/ special_aftertrans_update__movieclip_for_curves,
|
||||
};
|
|
@ -594,7 +594,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
|
|||
Object *ob,
|
||||
BMEditMesh *em,
|
||||
const UnwrapOptions *options,
|
||||
UnwrapResultInfo *result_info)
|
||||
int *r_count_failed = nullptr)
|
||||
{
|
||||
/* pointers to modifier data for unwrap control */
|
||||
SubsurfModifierData *smd_real;
|
||||
|
@ -666,8 +666,8 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
|
|||
nullptr;
|
||||
}
|
||||
|
||||
/* Prepare and feed faces to the solver */
|
||||
for (const int i : subsurf_polys.index_range()) {
|
||||
/* Prepare and feed faces to the solver. */
|
||||
for (const int64_t i : subsurf_polys.index_range()) {
|
||||
const MPoly &poly = subsurf_polys[i];
|
||||
ParamKey key, vkeys[4];
|
||||
bool pin[4], select[4];
|
||||
|
@ -717,8 +717,8 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
|
|||
blender::geometry::uv_parametrizer_face_add(handle, key, 4, vkeys, co, uv, pin, select);
|
||||
}
|
||||
|
||||
/* these are calculated from original mesh too */
|
||||
for (const int i : subsurf_edges.index_range()) {
|
||||
/* These are calculated from original mesh too. */
|
||||
for (const int64_t i : subsurf_edges.index_range()) {
|
||||
if ((edgeMap[i] != nullptr) && BM_elem_flag_test(edgeMap[i], BM_ELEM_SEAM)) {
|
||||
const MEdge *edge = &subsurf_edges[i];
|
||||
ParamKey vkeys[2];
|
||||
|
@ -728,11 +728,8 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
|
|||
}
|
||||
}
|
||||
|
||||
blender::geometry::uv_parametrizer_construct_end(handle,
|
||||
options->fill_holes,
|
||||
options->topology_from_uvs,
|
||||
result_info ? &result_info->count_failed :
|
||||
nullptr);
|
||||
blender::geometry::uv_parametrizer_construct_end(
|
||||
handle, options->fill_holes, options->topology_from_uvs, r_count_failed);
|
||||
|
||||
/* cleanup */
|
||||
MEM_freeN(faceMap);
|
||||
|
@ -1804,7 +1801,8 @@ static void uvedit_unwrap(const Scene *scene,
|
|||
|
||||
ParamHandle *handle;
|
||||
if (use_subsurf) {
|
||||
handle = construct_param_handle_subsurfed(scene, obedit, em, options, result_info);
|
||||
handle = construct_param_handle_subsurfed(
|
||||
scene, obedit, em, options, result_info ? &result_info->count_failed : nullptr);
|
||||
}
|
||||
else {
|
||||
handle = construct_param_handle(
|
||||
|
|
|
@ -146,12 +146,21 @@ void solve_length_and_collision_constraints(const OffsetIndices<int> points_by_c
|
|||
float slide_direction_length_cu;
|
||||
const float3 normalized_slide_direction_cu = math::normalize_and_get_length(
|
||||
slide_direction_cu, slide_direction_length_cu);
|
||||
const float slide_normal_length_sq_cu = math::length_squared(slide_normal_cu);
|
||||
|
||||
/* Use pythagorian theorem to determine how far to slide. */
|
||||
const float slide_distance_cu = std::sqrt(pow2f(goal_segment_length_cu) -
|
||||
math::length_squared(slide_normal_cu)) -
|
||||
slide_direction_length_cu;
|
||||
positions_cu[point_i] = plane_pos_cu + normalized_slide_direction_cu * slide_distance_cu;
|
||||
if (pow2f(goal_segment_length_cu) > slide_normal_length_sq_cu) {
|
||||
/* Use pythagorian theorem to determine how far to slide. */
|
||||
const float slide_distance_cu = std::sqrt(pow2f(goal_segment_length_cu) -
|
||||
slide_normal_length_sq_cu) -
|
||||
slide_direction_length_cu;
|
||||
positions_cu[point_i] = plane_pos_cu +
|
||||
normalized_slide_direction_cu * slide_distance_cu;
|
||||
}
|
||||
else {
|
||||
/* Minimum distance is larger than allowed segment length.
|
||||
* The unilateral collision constraint is satisfied by just clamping segment length. */
|
||||
positions_cu[point_i] = prev_pos_cu + math::normalize(old_pos_su - prev_pos_cu) * goal_segment_length_cu;
|
||||
}
|
||||
}
|
||||
if (used_iterations == max_collisions) {
|
||||
revert_curve = true;
|
||||
|
|
|
@ -28,12 +28,12 @@ static float pack_islands_scale_margin(const Span<PackIsland *> &island_vector,
|
|||
for (const int64_t index : island_vector.index_range()) {
|
||||
PackIsland *island = island_vector[index];
|
||||
BoxPack *box = &box_array[index];
|
||||
box->index = (int)index;
|
||||
box->index = int(index);
|
||||
box->w = BLI_rctf_size_x(&island->bounds_rect) * scale + 2 * margin;
|
||||
box->h = BLI_rctf_size_y(&island->bounds_rect) * scale + 2 * margin;
|
||||
}
|
||||
float max_u, max_v;
|
||||
BLI_box_pack_2d(box_array, (int)island_vector.size(), &max_u, &max_v);
|
||||
BLI_box_pack_2d(box_array, int(island_vector.size()), &max_u, &max_v);
|
||||
return max_ff(max_u, max_v);
|
||||
}
|
||||
|
||||
|
|
|
@ -410,6 +410,7 @@ set(GLSL_SRC
|
|||
|
||||
shaders/gpu_shader_codegen_lib.glsl
|
||||
|
||||
shaders/common/gpu_shader_bicubic_sampler_lib.glsl
|
||||
shaders/common/gpu_shader_common_color_ramp.glsl
|
||||
shaders/common/gpu_shader_common_color_utils.glsl
|
||||
shaders/common/gpu_shader_common_curves.glsl
|
||||
|
|
|
@ -313,15 +313,15 @@ bool GPU_framebuffer_check_valid(GPUFrameBuffer *framebuffer, char err_out[256])
|
|||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Empty framebuffer
|
||||
/** \name Empty frame-buffer
|
||||
*
|
||||
* An empty framebuffer is a framebuffer with no attachments. This allow to rasterize geometry
|
||||
* An empty frame-buffer is a frame-buffer with no attachments. This allow to rasterize geometry
|
||||
* without creating any dummy attachments and write some computation results using other means
|
||||
* (SSBOs, Images).
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Default size is used if the framebuffer contains no attachments.
|
||||
* Default size is used if the frame-buffer contains no attachments.
|
||||
* It needs to be re-specified each time an attachment is added.
|
||||
*/
|
||||
void GPU_framebuffer_default_size(GPUFrameBuffer *framebuffer, int width, int height);
|
||||
|
@ -349,7 +349,7 @@ void GPU_framebuffer_viewport_set(
|
|||
void GPU_framebuffer_viewport_get(GPUFrameBuffer *framebuffer, int r_viewport[4]);
|
||||
|
||||
/**
|
||||
* Reset a framebuffer viewport bounds to its attachment(s) size.
|
||||
* Reset a frame-buffer viewport bounds to its attachment(s) size.
|
||||
* \note Viewport and scissor size is stored per frame-buffer.
|
||||
*/
|
||||
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *framebuffer);
|
||||
|
@ -361,7 +361,7 @@ void GPU_framebuffer_viewport_reset(GPUFrameBuffer *framebuffer);
|
|||
* \{ */
|
||||
|
||||
/**
|
||||
* Clear the framebuffer attachments.
|
||||
* Clear the frame-buffer attachments.
|
||||
* \a buffers controls the types of attachments to clear. Setting GPU_COLOR_BIT will clear *all*
|
||||
* the color attachment.
|
||||
* Each attachment gets cleared to the value of its type:
|
||||
|
@ -438,19 +438,19 @@ void GPU_framebuffer_clear_color_depth_stencil(GPUFrameBuffer *fb,
|
|||
void GPU_framebuffer_multi_clear(GPUFrameBuffer *framebuffer, const float (*clear_colors)[4]);
|
||||
|
||||
/**
|
||||
* Clear all color attachment textures of the active framebuffer with the given red, green, blue,
|
||||
* Clear all color attachment textures of the active frame-buffer with the given red, green, blue,
|
||||
* alpha values.
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
* DEPRECATED: Use `GPU_framebuffer_clear_color` with explicit framebuffer.
|
||||
* DEPRECATED: Use `GPU_framebuffer_clear_color` with explicit frame-buffer.
|
||||
*/
|
||||
void GPU_clear_color(float red, float green, float blue, float alpha);
|
||||
|
||||
/**
|
||||
* Clear the depth attachment texture of the active framebuffer with the given depth value.
|
||||
* Clear the depth attachment texture of the active frame-buffer with the given depth value.
|
||||
* \note `GPU_write_mask`, and stencil test do not affect this command.
|
||||
* \note Viewport and scissor regions affect this command but are not efficient nor recommended.
|
||||
* DEPRECATED: Use `GPU_framebuffer_clear_color` with explicit framebuffer.
|
||||
* DEPRECATED: Use `GPU_framebuffer_clear_color` with explicit frame-buffer.
|
||||
*/
|
||||
void GPU_clear_depth(float depth);
|
||||
|
||||
|
@ -467,7 +467,7 @@ const char *GPU_framebuffer_get_name(GPUFrameBuffer *framebuffer);
|
|||
/* -------------------------------------------------------------------- */
|
||||
/** \name Python API & meta-data
|
||||
*
|
||||
* These are not intrinsic properties of a framebuffer but they are stored inside the
|
||||
* These are not intrinsic properties of a frame-buffer but they are stored inside the
|
||||
* gpu::FrameBuffer structure for tracking purpose.
|
||||
* \{ */
|
||||
|
||||
|
@ -481,8 +481,8 @@ void GPU_framebuffer_py_reference_set(GPUFrameBuffer *framebuffer, void **py_ref
|
|||
#endif
|
||||
|
||||
/**
|
||||
* Keep a stack of bound framebuffer to allow scoped binding of framebuffer in python.
|
||||
* This is also used by #GPUOffScreen to save/restore the current framebuffers.
|
||||
* Keep a stack of bound frame-buffer to allow scoped binding of frame-buffer in python.
|
||||
* This is also used by #GPUOffScreen to save/restore the current frame-buffers.
|
||||
* \note This isn't thread safe.
|
||||
*/
|
||||
/* TODO(fclem): This has nothing to do with the GPU module and should be move to the pyGPU module.
|
||||
|
@ -547,7 +547,7 @@ void GPU_frontbuffer_read_pixels(
|
|||
* The attachments types are chosen by \a blit_buffers .
|
||||
* Only one color buffer can by copied at a time and its index is chosen by \a read_slot and \a
|
||||
* write_slot.
|
||||
* The source and destination framebuffers dimensions have to match.
|
||||
* The source and destination frame-buffers dimensions have to match.
|
||||
* DEPRECATED: Prefer using `GPU_texture_copy()`.
|
||||
*/
|
||||
void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
|
||||
|
|
|
@ -417,7 +417,7 @@ void GPU_framebuffer_clear_color(GPUFrameBuffer *fb, const float clear_col[4])
|
|||
|
||||
void GPU_framebuffer_clear_depth(GPUFrameBuffer *fb, float clear_depth)
|
||||
{
|
||||
GPU_framebuffer_clear(fb, GPU_DEPTH_BIT, NULL, clear_depth, 0x00);
|
||||
GPU_framebuffer_clear(fb, GPU_DEPTH_BIT, nullptr, clear_depth, 0x00);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_color_depth(GPUFrameBuffer *fb,
|
||||
|
@ -429,12 +429,12 @@ void GPU_framebuffer_clear_color_depth(GPUFrameBuffer *fb,
|
|||
|
||||
void GPU_framebuffer_clear_stencil(GPUFrameBuffer *fb, uint clear_stencil)
|
||||
{
|
||||
GPU_framebuffer_clear(fb, GPU_STENCIL_BIT, NULL, 0.0f, clear_stencil);
|
||||
GPU_framebuffer_clear(fb, GPU_STENCIL_BIT, nullptr, 0.0f, clear_stencil);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_depth_stencil(GPUFrameBuffer *fb, float clear_depth, uint clear_stencil)
|
||||
{
|
||||
GPU_framebuffer_clear(fb, GPU_DEPTH_BIT | GPU_STENCIL_BIT, NULL, clear_depth, clear_stencil);
|
||||
GPU_framebuffer_clear(fb, GPU_DEPTH_BIT | GPU_STENCIL_BIT, nullptr, clear_depth, clear_stencil);
|
||||
}
|
||||
|
||||
void GPU_framebuffer_clear_color_depth_stencil(GPUFrameBuffer *fb,
|
||||
|
|
|
@ -62,11 +62,24 @@ template<> uint denormalize<uint>(float val)
|
|||
return uint(float(DEPTH_SCALE_FACTOR) * val);
|
||||
}
|
||||
|
||||
/* Float to other type case. */
|
||||
template<typename T> T convert_type(float type)
|
||||
{
|
||||
return T(type);
|
||||
}
|
||||
|
||||
/* Uint to other types. */
|
||||
template<typename T> T convert_type(uint type)
|
||||
{
|
||||
return T(type);
|
||||
}
|
||||
|
||||
/* Int to other types. */
|
||||
template<typename T> T convert_type(int type)
|
||||
{
|
||||
return T(type);
|
||||
}
|
||||
|
||||
template<> uchar convert_type<uchar>(float val)
|
||||
{
|
||||
return uchar(val * float(0xFF));
|
||||
|
@ -141,8 +154,8 @@ kernel void compute_texture_read(constant TextureReadParams ¶ms [[buffer(0)]
|
|||
uint xx = position[0];
|
||||
uint yy = position[1];
|
||||
uint zz = position[2];
|
||||
int index = (zz * (params.extent[0] * params.extent[1]) + yy * params.extnt[0] + xx) *
|
||||
COMPONENT_COUNT_INPUT;
|
||||
int index = (zz * (params.extent[0] * params.extent[1]) + yy * params.extent[0] + xx) *
|
||||
COMPONENT_COUNT_OUTPUT;
|
||||
read_colour = read_tex.read(uint3(params.offset[0], params.offset[1], params.offset[2]) +
|
||||
uint3(xx, yy, zz));
|
||||
|
||||
|
@ -163,7 +176,7 @@ kernel void compute_texture_read(constant TextureReadParams ¶ms [[buffer(0)]
|
|||
uint yy = position[1];
|
||||
uint layer = position[2];
|
||||
int index = (layer * (params.extent[0] * params.extent[1]) + yy * params.extent[0] + xx) *
|
||||
COMPONENT_COUNT_INPUT;
|
||||
COMPONENT_COUNT_OUTPUT;
|
||||
|
||||
/* Read data */
|
||||
# if IS_DEPTH_FORMAT == 1
|
||||
|
|
|
@ -606,17 +606,6 @@ void MTLFrameBuffer::update_attachments(bool update_viewport)
|
|||
if (!dirty_attachments_) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Cache viewport and scissor (If we have existing attachments). */
|
||||
int t_viewport[4], t_scissor[4];
|
||||
update_viewport = update_viewport &&
|
||||
(this->get_attachment_count() > 0 && this->has_depth_attachment() &&
|
||||
this->has_stencil_attachment());
|
||||
if (update_viewport) {
|
||||
this->viewport_get(t_viewport);
|
||||
this->scissor_get(t_scissor);
|
||||
}
|
||||
|
||||
/* Clear current attachments state. */
|
||||
this->remove_all_attachments();
|
||||
|
||||
|
@ -738,22 +727,25 @@ void MTLFrameBuffer::update_attachments(bool update_viewport)
|
|||
}
|
||||
}
|
||||
|
||||
/* Check whether the first attachment is SRGB. */
|
||||
/* Extract attachment size and determine if framebuffer is SRGB. */
|
||||
if (first_attachment != GPU_FB_MAX_ATTACHMENT) {
|
||||
srgb_ = (first_attachment_mtl.texture->format_get() == GPU_SRGB8_A8);
|
||||
}
|
||||
|
||||
/* Reset viewport and Scissor (If viewport is smaller or equal to the framebuffer size). */
|
||||
if (update_viewport && t_viewport[2] <= width_ && t_viewport[3] <= height_) {
|
||||
|
||||
this->viewport_set(t_viewport);
|
||||
this->scissor_set(t_viewport);
|
||||
/* Ensure size is correctly assigned. */
|
||||
GPUAttachment &attach = attachments_[first_attachment];
|
||||
int size[3];
|
||||
GPU_texture_get_mipmap_size(attach.tex, attach.mip, size);
|
||||
this->size_set(size[0], size[1]);
|
||||
srgb_ = (GPU_texture_format(attach.tex) == GPU_SRGB8_A8);
|
||||
}
|
||||
else {
|
||||
this->viewport_reset();
|
||||
this->scissor_reset();
|
||||
/* Empty frame-buffer. */
|
||||
width_ = 0;
|
||||
height_ = 0;
|
||||
}
|
||||
|
||||
/* Reset viewport and Scissor. */
|
||||
this->viewport_reset();
|
||||
this->scissor_reset();
|
||||
|
||||
/* We have now updated our internal structures. */
|
||||
dirty_attachments_ = false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/** \param f: Offset from texel center in pixel space. */
|
||||
void cubic_bspline_coefficients(vec2 f, out vec2 w0, out vec2 w1, out vec2 w2, out vec2 w3)
|
||||
{
|
||||
vec2 f2 = f * f;
|
||||
vec2 f3 = f2 * f;
|
||||
/* Optimized formulae for cubic B-Spline coefficients. */
|
||||
w3 = f3 / 6.0;
|
||||
w0 = -w3 + f2 * 0.5 - f * 0.5 + 1.0 / 6.0;
|
||||
w1 = f3 * 0.5 - f2 * 1.0 + 2.0 / 3.0;
|
||||
w2 = 1.0 - w0 - w1 - w3;
|
||||
}
|
||||
|
||||
/* Samples the given 2D sampler at the given coordinates using Bicubic interpolation. This function
|
||||
* uses an optimized algorithm which assumes a linearly filtered sampler, so the caller needs to
|
||||
* take that into account when setting up the sampler. */
|
||||
vec4 texture_bicubic(sampler2D sampler, vec2 coordinates)
|
||||
{
|
||||
vec2 texture_size = vec2(textureSize(sampler, 0).xy);
|
||||
coordinates.xy *= texture_size;
|
||||
|
||||
vec2 w0, w1, w2, w3;
|
||||
vec2 texel_center = floor(coordinates.xy - 0.5) + 0.5;
|
||||
cubic_bspline_coefficients(coordinates.xy - texel_center, w0, w1, w2, w3);
|
||||
|
||||
#if 1 /* Optimized version using 4 filtered taps. */
|
||||
vec2 s0 = w0 + w1;
|
||||
vec2 s1 = w2 + w3;
|
||||
|
||||
vec2 f0 = w1 / (w0 + w1);
|
||||
vec2 f1 = w3 / (w2 + w3);
|
||||
|
||||
vec4 sampling_coordinates;
|
||||
sampling_coordinates.xy = texel_center - 1.0 + f0;
|
||||
sampling_coordinates.zw = texel_center + 1.0 + f1;
|
||||
|
||||
sampling_coordinates /= texture_size.xyxy;
|
||||
|
||||
vec4 sampled_color = textureLod(sampler, sampling_coordinates.xy, 0.0) * s0.x * s0.y;
|
||||
sampled_color += textureLod(sampler, sampling_coordinates.zy, 0.0) * s1.x * s0.y;
|
||||
sampled_color += textureLod(sampler, sampling_coordinates.xw, 0.0) * s0.x * s1.y;
|
||||
sampled_color += textureLod(sampler, sampling_coordinates.zw, 0.0) * s1.x * s1.y;
|
||||
|
||||
return sampled_color;
|
||||
|
||||
#else /* Reference brute-force 16 taps. */
|
||||
vec4 color = texelFetch(sampler, ivec2(texel_center + vec2(-1.0, -1.0)), 0) * w0.x * w0.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(0.0, -1.0)), 0) * w1.x * w0.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(1.0, -1.0)), 0) * w2.x * w0.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(2.0, -1.0)), 0) * w3.x * w0.y;
|
||||
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(-1.0, 0.0)), 0) * w0.x * w1.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(0.0, 0.0)), 0) * w1.x * w1.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(1.0, 0.0)), 0) * w2.x * w1.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(2.0, 0.0)), 0) * w3.x * w1.y;
|
||||
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(-1.0, 1.0)), 0) * w0.x * w2.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(0.0, 1.0)), 0) * w1.x * w2.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(1.0, 1.0)), 0) * w2.x * w2.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(2.0, 1.0)), 0) * w3.x * w2.y;
|
||||
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(-1.0, 2.0)), 0) * w0.x * w3.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(0.0, 2.0)), 0) * w1.x * w3.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(1.0, 2.0)), 0) * w2.x * w3.y;
|
||||
color += texelFetch(sampler, ivec2(texel_center + vec2(2.0, 2.0)), 0) * w3.x * w3.y;
|
||||
|
||||
return color;
|
||||
#endif
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
#pragma BLENDER_REQUIRE(gpu_shader_bicubic_sampler_lib.glsl)
|
||||
|
||||
void point_texco_remap_square(vec3 vin, out vec3 vout)
|
||||
{
|
||||
vout = vin * 2.0 - 1.0;
|
||||
|
@ -54,68 +56,9 @@ void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alp
|
|||
alpha = color.a;
|
||||
}
|
||||
|
||||
/** \param f: Signed distance to texel center. */
|
||||
void cubic_bspline_coefs(vec2 f, out vec2 w0, out vec2 w1, out vec2 w2, out vec2 w3)
|
||||
{
|
||||
vec2 f2 = f * f;
|
||||
vec2 f3 = f2 * f;
|
||||
/* Bspline coefs (optimized) */
|
||||
w3 = f3 / 6.0;
|
||||
w0 = -w3 + f2 * 0.5 - f * 0.5 + 1.0 / 6.0;
|
||||
w1 = f3 * 0.5 - f2 * 1.0 + 2.0 / 3.0;
|
||||
w2 = 1.0 - w0 - w1 - w3;
|
||||
}
|
||||
|
||||
void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha)
|
||||
{
|
||||
vec2 tex_size = vec2(textureSize(ima, 0).xy);
|
||||
|
||||
co.xy *= tex_size;
|
||||
/* texel center */
|
||||
vec2 tc = floor(co.xy - 0.5) + 0.5;
|
||||
vec2 w0, w1, w2, w3;
|
||||
cubic_bspline_coefs(co.xy - tc, w0, w1, w2, w3);
|
||||
|
||||
#if 1 /* Optimized version using 4 filtered tap. */
|
||||
vec2 s0 = w0 + w1;
|
||||
vec2 s1 = w2 + w3;
|
||||
|
||||
vec2 f0 = w1 / (w0 + w1);
|
||||
vec2 f1 = w3 / (w2 + w3);
|
||||
|
||||
vec4 final_co;
|
||||
final_co.xy = tc - 1.0 + f0;
|
||||
final_co.zw = tc + 1.0 + f1;
|
||||
|
||||
final_co /= tex_size.xyxy;
|
||||
|
||||
color = safe_color(textureLod(ima, final_co.xy, 0.0)) * s0.x * s0.y;
|
||||
color += safe_color(textureLod(ima, final_co.zy, 0.0)) * s1.x * s0.y;
|
||||
color += safe_color(textureLod(ima, final_co.xw, 0.0)) * s0.x * s1.y;
|
||||
color += safe_color(textureLod(ima, final_co.zw, 0.0)) * s1.x * s1.y;
|
||||
|
||||
#else /* Reference bruteforce 16 tap. */
|
||||
color = texelFetch(ima, ivec2(tc + vec2(-1.0, -1.0)), 0) * w0.x * w0.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(0.0, -1.0)), 0) * w1.x * w0.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(1.0, -1.0)), 0) * w2.x * w0.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(2.0, -1.0)), 0) * w3.x * w0.y;
|
||||
|
||||
color += texelFetch(ima, ivec2(tc + vec2(-1.0, 0.0)), 0) * w0.x * w1.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(0.0, 0.0)), 0) * w1.x * w1.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(1.0, 0.0)), 0) * w2.x * w1.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(2.0, 0.0)), 0) * w3.x * w1.y;
|
||||
|
||||
color += texelFetch(ima, ivec2(tc + vec2(-1.0, 1.0)), 0) * w0.x * w2.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(0.0, 1.0)), 0) * w1.x * w2.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(1.0, 1.0)), 0) * w2.x * w2.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(2.0, 1.0)), 0) * w3.x * w2.y;
|
||||
|
||||
color += texelFetch(ima, ivec2(tc + vec2(-1.0, 2.0)), 0) * w0.x * w3.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(0.0, 2.0)), 0) * w1.x * w3.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(1.0, 2.0)), 0) * w2.x * w3.y;
|
||||
color += texelFetch(ima, ivec2(tc + vec2(2.0, 2.0)), 0) * w3.x * w3.y;
|
||||
#endif
|
||||
|
||||
color = safe_color(texture_bicubic(ima, co.xy));
|
||||
alpha = color.a;
|
||||
}
|
||||
|
||||
|
@ -263,7 +206,7 @@ void node_tex_tile_cubic(
|
|||
/* texel center */
|
||||
vec2 tc = floor(co.xy - 0.5) + 0.5;
|
||||
vec2 w0, w1, w2, w3;
|
||||
cubic_bspline_coefs(co.xy - tc, w0, w1, w2, w3);
|
||||
cubic_bspline_coefficients(co.xy - tc, w0, w1, w2, w3);
|
||||
|
||||
vec2 s0 = w0 + w1;
|
||||
vec2 s1 = w2 + w3;
|
||||
|
|
|
@ -143,8 +143,8 @@ static void do_push_constants_test(const char *info_name, const int num_calls_si
|
|||
shader.update_push_constants(call_data);
|
||||
shader.dispatch();
|
||||
}
|
||||
/* All calls will be "simultaneously" in flight. First readback will wait until the dispatches
|
||||
* have finished execution.*/
|
||||
/* All calls will be "simultaneously" in flight. First read-back will wait until the dispatches
|
||||
* have finished execution. */
|
||||
for (const int call_index : IndexRange(num_calls_simultaneously)) {
|
||||
CallData &call_data = shader.call_datas[call_index];
|
||||
call_data.read_back();
|
||||
|
@ -152,7 +152,7 @@ static void do_push_constants_test(const char *info_name, const int num_calls_si
|
|||
}
|
||||
}
|
||||
|
||||
/* Test case with single call as sanity check, before we make it more interesting.*/
|
||||
/* Test case with single call as sanity check, before we make it more interesting. */
|
||||
static void test_push_constants()
|
||||
{
|
||||
do_push_constants_test("gpu_push_constants_test");
|
||||
|
@ -180,7 +180,7 @@ GPU_TEST(push_constants_512bytes)
|
|||
#if 0
|
||||
/* Schedule multiple simultaneously. */
|
||||
/* These test have been disabled for now as this will to be solved in a separate PR.
|
||||
* - DescriptorSets may not be altered, when they are in the command queue or being executed.
|
||||
* - `DescriptorSets` may not be altered, when they are in the command queue or being executed.
|
||||
*/
|
||||
static void test_push_constants_multiple()
|
||||
{
|
||||
|
@ -207,4 +207,4 @@ static void test_push_constants_multiple_512bytes()
|
|||
GPU_TEST(push_constants_multiple_512bytes)
|
||||
#endif
|
||||
|
||||
} // namespace blender::gpu::tests
|
||||
} // namespace blender::gpu::tests
|
||||
|
|
|
@ -31,7 +31,6 @@ class VKShaderInterface : public ShaderInterface {
|
|||
|
||||
VKPushConstants::Layout push_constants_layout_;
|
||||
|
||||
|
||||
public:
|
||||
VKShaderInterface() = default;
|
||||
|
||||
|
|
|
@ -23,10 +23,10 @@ namespace blender::io::ply {
|
|||
std::unique_ptr<PlyData> import_ply_ascii(fstream &file, PlyHeader *header);
|
||||
|
||||
/**
|
||||
* Loads the information from the PLY file in ASCII format to the PlyData datastructure.
|
||||
* Loads the information from the PLY file in ASCII format to the #PlyData data-structure.
|
||||
* \param file: The PLY file that was opened.
|
||||
* \param header: The information in the PLY header.
|
||||
* \return The PlyData datastructure that can be used for conversion to a Mesh.
|
||||
* \return The #PlyData data-structure that can be used for conversion to a Mesh.
|
||||
*/
|
||||
PlyData load_ply_ascii(fstream &file, const PlyHeader *header);
|
||||
|
||||
|
|
|
@ -17,15 +17,15 @@ namespace blender::io::ply {
|
|||
* The function that gets called from the importer.
|
||||
* \param file: The PLY file that was opened.
|
||||
* \param header: The information in the PLY header.
|
||||
* \return The PlyData datastructure that can be used for conversion to a Mesh.
|
||||
* \return The #PlyData data-structure that can be used for conversion to a #Mesh.
|
||||
*/
|
||||
std::unique_ptr<PlyData> import_ply_binary(fstream &file, const PlyHeader *header);
|
||||
|
||||
/**
|
||||
* Loads the information from the PLY file in binary format to the PlyData datastructure.
|
||||
* Loads the information from the PLY file in binary format to the #PlyData data-structure.
|
||||
* \param file: The PLY file that was opened.
|
||||
* \param header: The information in the PLY header.
|
||||
* \return The PlyData datastructure that can be used for conversion to a Mesh.
|
||||
* \return The #PlyData data-structure that can be used for conversion to a Mesh.
|
||||
*/
|
||||
PlyData load_ply_binary(fstream &file, const PlyHeader *header);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
namespace blender::io::ply {
|
||||
|
||||
/**
|
||||
* Converts the PlyData datastructure to a mesh.
|
||||
* Converts the #PlyData data-structure to a mesh.
|
||||
* \param data: The PLY data.
|
||||
* \return The mesh that can be used inside blender.
|
||||
*/
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "testing/testing.h"
|
||||
#include "tests/blendfile_loading_base_test.h"
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
#include "BKE_blender_version.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
@ -31,6 +32,26 @@ class PlyExportTest : public BlendfileLoadingBaseTest {
|
|||
depsgraph_create(eval_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
BlendfileLoadingBaseTest::SetUp();
|
||||
|
||||
BKE_tempdir_init("");
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
BlendfileLoadingBaseTest::TearDown();
|
||||
|
||||
BKE_tempdir_session_purge();
|
||||
}
|
||||
|
||||
std::string get_temp_ply_filename(const std::string &filename)
|
||||
{
|
||||
return std::string(BKE_tempdir_session()) + "/" + filename;
|
||||
}
|
||||
};
|
||||
|
||||
static std::unique_ptr<PlyData> load_cube(PLYExportParams ¶ms)
|
||||
|
@ -103,8 +124,8 @@ static std::vector<char> read_temp_file_in_vectorchar(const std::string &file_pa
|
|||
|
||||
TEST_F(PlyExportTest, WriteHeaderAscii)
|
||||
{
|
||||
std::string filePath = blender::tests::flags_test_release_dir() + "/" + temp_file_path;
|
||||
PLYExportParams _params;
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params = {};
|
||||
_params.ascii_format = true;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
|
||||
|
@ -141,8 +162,8 @@ TEST_F(PlyExportTest, WriteHeaderAscii)
|
|||
|
||||
TEST_F(PlyExportTest, WriteHeaderBinary)
|
||||
{
|
||||
std::string filePath = blender::tests::flags_test_release_dir() + "/" + temp_file_path;
|
||||
PLYExportParams _params;
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params = {};
|
||||
_params.ascii_format = false;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
|
||||
|
@ -179,8 +200,8 @@ TEST_F(PlyExportTest, WriteHeaderBinary)
|
|||
|
||||
TEST_F(PlyExportTest, WriteVerticesAscii)
|
||||
{
|
||||
std::string filePath = blender::tests::flags_test_release_dir() + "/" + temp_file_path;
|
||||
PLYExportParams _params;
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params = {};
|
||||
_params.ascii_format = true;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
|
||||
|
@ -211,8 +232,8 @@ TEST_F(PlyExportTest, WriteVerticesAscii)
|
|||
|
||||
TEST_F(PlyExportTest, WriteVerticesBinary)
|
||||
{
|
||||
std::string filePath = blender::tests::flags_test_release_dir() + "/" + temp_file_path;
|
||||
PLYExportParams _params;
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params = {};
|
||||
_params.ascii_format = false;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
|
||||
|
@ -253,8 +274,8 @@ TEST_F(PlyExportTest, WriteVerticesBinary)
|
|||
|
||||
TEST_F(PlyExportTest, WriteFacesAscii)
|
||||
{
|
||||
std::string filePath = blender::tests::flags_test_release_dir() + "/" + temp_file_path;
|
||||
PLYExportParams _params;
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params = {};
|
||||
_params.ascii_format = true;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
|
||||
|
@ -283,8 +304,8 @@ TEST_F(PlyExportTest, WriteFacesAscii)
|
|||
|
||||
TEST_F(PlyExportTest, WriteFacesBinary)
|
||||
{
|
||||
std::string filePath = blender::tests::flags_test_release_dir() + "/" + temp_file_path;
|
||||
PLYExportParams _params;
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params = {};
|
||||
_params.ascii_format = false;
|
||||
_params.export_normals = false;
|
||||
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
|
||||
|
@ -326,8 +347,8 @@ TEST_F(PlyExportTest, WriteFacesBinary)
|
|||
|
||||
TEST_F(PlyExportTest, WriteVertexNormalsAscii)
|
||||
{
|
||||
std::string filePath = blender::tests::flags_test_release_dir() + "/" + temp_file_path;
|
||||
PLYExportParams _params;
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params = {};
|
||||
_params.ascii_format = true;
|
||||
_params.export_normals = true;
|
||||
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
|
||||
|
@ -358,8 +379,8 @@ TEST_F(PlyExportTest, WriteVertexNormalsAscii)
|
|||
|
||||
TEST_F(PlyExportTest, WriteVertexNormalsBinary)
|
||||
{
|
||||
std::string filePath = blender::tests::flags_test_release_dir() + "/" + temp_file_path;
|
||||
PLYExportParams _params;
|
||||
std::string filePath = get_temp_ply_filename(temp_file_path);
|
||||
PLYExportParams _params = {};
|
||||
_params.ascii_format = false;
|
||||
_params.export_normals = true;
|
||||
_params.vertex_colors = PLY_VERTEX_COLOR_NONE;
|
||||
|
@ -429,14 +450,14 @@ class ply_exporter_ply_data_test : public PlyExportTest {
|
|||
|
||||
TEST_F(ply_exporter_ply_data_test, CubeLoadPLYDataVertices)
|
||||
{
|
||||
PLYExportParams params;
|
||||
PLYExportParams params = {};
|
||||
PlyData plyData = load_ply_data_from_blendfile("io_tests/blend_geometry/cube_all_data.blend",
|
||||
params);
|
||||
EXPECT_EQ(plyData.vertices.size(), 8);
|
||||
}
|
||||
TEST_F(ply_exporter_ply_data_test, CubeLoadPLYDataUV)
|
||||
{
|
||||
PLYExportParams params;
|
||||
PLYExportParams params = {};
|
||||
params.export_uv = true;
|
||||
PlyData plyData = load_ply_data_from_blendfile("io_tests/blend_geometry/cube_all_data.blend",
|
||||
params);
|
||||
|
@ -444,16 +465,16 @@ TEST_F(ply_exporter_ply_data_test, CubeLoadPLYDataUV)
|
|||
}
|
||||
TEST_F(ply_exporter_ply_data_test, SuzanneLoadPLYDataUV)
|
||||
{
|
||||
PLYExportParams params;
|
||||
PLYExportParams params = {};
|
||||
params.export_uv = true;
|
||||
PlyData plyData = load_ply_data_from_blendfile("io_tests/blend_geometry/suzanne_all_data.blend",
|
||||
params);
|
||||
EXPECT_EQ(plyData.uv_coordinates.size(), 541);
|
||||
EXPECT_EQ(plyData.uv_coordinates.size(), 542);
|
||||
}
|
||||
|
||||
TEST_F(ply_exporter_ply_data_test, CubeLoadPLYDataUVDisabled)
|
||||
{
|
||||
PLYExportParams params;
|
||||
PLYExportParams params = {};
|
||||
params.export_uv = false;
|
||||
PlyData plyData = load_ply_data_from_blendfile("io_tests/blend_geometry/cube_all_data.blend",
|
||||
params);
|
||||
|
|
|
@ -72,6 +72,12 @@ typedef struct AssetMetaData {
|
|||
/** Optional description of this asset for display in the UI. Dynamic length. */
|
||||
char *description;
|
||||
|
||||
/** Optional copyright of this asset for display in the UI. Dynamic length. */
|
||||
char *copyright;
|
||||
|
||||
/** Optional license of this asset for display in the UI. Dynamic length. */
|
||||
char *license;
|
||||
|
||||
/** User defined tags for this asset. The asset manager uses these for filtering, but how they
|
||||
* function exactly (e.g. how they are registered to provide a list of searchable available tags)
|
||||
* is up to the asset-engine. */
|
||||
|
|
|
@ -243,7 +243,7 @@ typedef struct bArmatureConstraint {
|
|||
ListBase targets;
|
||||
} bArmatureConstraint;
|
||||
|
||||
/* Single-target subobject constraints --------------------- */
|
||||
/* Single-target sub-object constraints --------------------- */
|
||||
|
||||
/* Track To Constraint */
|
||||
typedef struct bTrackToConstraint {
|
||||
|
|
|
@ -330,7 +330,11 @@ typedef struct bNode {
|
|||
int16_t custom1, custom2;
|
||||
float custom3, custom4;
|
||||
|
||||
/** Optional link to libdata. */
|
||||
/**
|
||||
* Optional link to libdata.
|
||||
*
|
||||
* \see #bNodeType::initfunc & #bNodeType::freefunc for details on ID user-count.
|
||||
*/
|
||||
struct ID *id;
|
||||
|
||||
/** Custom data struct for node properties for storage in files. */
|
||||
|
|
|
@ -552,6 +552,7 @@ enum {
|
|||
V3D_OVERLAY_SCULPT_SHOW_MASK = (1 << 14),
|
||||
V3D_OVERLAY_SCULPT_SHOW_FACE_SETS = (1 << 15),
|
||||
V3D_OVERLAY_SCULPT_CURVES_CAGE = (1 << 16),
|
||||
V3D_OVERLAY_SHOW_LIGHT_COLORS = (1 << 17),
|
||||
};
|
||||
|
||||
/** #View3DOverlay.edit_flag */
|
||||
|
|
|
@ -205,6 +205,74 @@ static void rna_AssetMetaData_description_set(PointerRNA *ptr, const char *value
|
|||
}
|
||||
}
|
||||
|
||||
static void rna_AssetMetaData_copyright_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
AssetMetaData *asset_data = ptr->data;
|
||||
|
||||
if (asset_data->copyright) {
|
||||
strcpy(value, asset_data->copyright);
|
||||
}
|
||||
else {
|
||||
value[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static int rna_AssetMetaData_copyright_length(PointerRNA *ptr)
|
||||
{
|
||||
AssetMetaData *asset_data = ptr->data;
|
||||
return asset_data->copyright ? strlen(asset_data->copyright) : 0;
|
||||
}
|
||||
|
||||
static void rna_AssetMetaData_copyright_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
AssetMetaData *asset_data = ptr->data;
|
||||
|
||||
if (asset_data->copyright) {
|
||||
MEM_freeN(asset_data->copyright);
|
||||
}
|
||||
|
||||
if (value[0]) {
|
||||
asset_data->copyright = BLI_strdup(value);
|
||||
}
|
||||
else {
|
||||
asset_data->copyright = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_AssetMetaData_license_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
AssetMetaData *asset_data = ptr->data;
|
||||
|
||||
if (asset_data->license) {
|
||||
strcpy(value, asset_data->license);
|
||||
}
|
||||
else {
|
||||
value[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static int rna_AssetMetaData_license_length(PointerRNA *ptr)
|
||||
{
|
||||
AssetMetaData *asset_data = ptr->data;
|
||||
return asset_data->license ? strlen(asset_data->license) : 0;
|
||||
}
|
||||
|
||||
static void rna_AssetMetaData_license_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
AssetMetaData *asset_data = ptr->data;
|
||||
|
||||
if (asset_data->license) {
|
||||
MEM_freeN(asset_data->license);
|
||||
}
|
||||
|
||||
if (value[0]) {
|
||||
asset_data->license = BLI_strdup(value);
|
||||
}
|
||||
else {
|
||||
asset_data->license = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_AssetMetaData_active_tag_range(
|
||||
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
|
||||
{
|
||||
|
@ -397,6 +465,30 @@ static void rna_def_asset_data(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(
|
||||
prop, "Description", "A description of the asset to be displayed for the user");
|
||||
|
||||
prop = RNA_def_property(srna, "copyright", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");
|
||||
RNA_def_property_string_funcs(prop,
|
||||
"rna_AssetMetaData_copyright_get",
|
||||
"rna_AssetMetaData_copyright_length",
|
||||
"rna_AssetMetaData_copyright_set");
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Copyright",
|
||||
"Copyright notice for this asset. An empty copyright notice does not necessarily indicate "
|
||||
"that this is copyright-free. Contact the author if any clarification is needed");
|
||||
|
||||
prop = RNA_def_property(srna, "license", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");
|
||||
RNA_def_property_string_funcs(prop,
|
||||
"rna_AssetMetaData_license_get",
|
||||
"rna_AssetMetaData_license_length",
|
||||
"rna_AssetMetaData_license_set");
|
||||
RNA_def_property_ui_text(prop,
|
||||
"License",
|
||||
"The type of license this asset is distributed under. An empty license "
|
||||
"name does not necessarily indicate that this is free of licensing "
|
||||
"terms. Contact the author if any clarification is needed");
|
||||
|
||||
prop = RNA_def_property(srna, "tags", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "AssetTag");
|
||||
RNA_def_property_editable_func(prop, "rna_AssetMetaData_editable");
|
||||
|
|
|
@ -2556,6 +2556,8 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "curve_preset", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, brush_curve_preset_items);
|
||||
RNA_def_property_ui_text(prop, "Curve Preset", "");
|
||||
RNA_def_property_translation_context(prop,
|
||||
BLT_I18NCONTEXT_ID_CURVES); /* Abusing id_curves :/ */
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "deform_target", PROP_ENUM, PROP_NONE);
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "DNA_cachefile_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
@ -364,6 +366,7 @@ static void rna_def_cachefile(BlenderRNA *brna)
|
|||
"Velocity Unit",
|
||||
"Define how the velocity vectors are interpreted with regard to time, 'frame' means "
|
||||
"the delta time is 1 frame, 'second' means the delta time is 1 / FPS");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UNIT);
|
||||
RNA_def_property_update(prop, 0, "rna_CacheFile_update");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
|
||||
|
|
|
@ -1821,6 +1821,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
|
|||
RNA_def_property_range(prop, 1, 5);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Number", "Particle number factor (higher value results in more particles)");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_AMOUNT);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
|
||||
|
||||
prop = RNA_def_property(srna, "particle_min", PROP_INT, PROP_NONE);
|
||||
|
|
|
@ -2948,6 +2948,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
|||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_range(prop, 0, 1000000, 1, -1);
|
||||
RNA_def_property_ui_text(prop, "Number", "Total number of particles");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_AMOUNT);
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop = RNA_def_property(
|
||||
|
|
|
@ -6440,6 +6440,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "hair_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, hair_shape_type_items);
|
||||
RNA_def_property_ui_text(prop, "Curves Shape Type", "Curves shape type");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVES);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_render_update");
|
||||
|
||||
prop = RNA_def_property(srna, "hair_subdiv", PROP_INT, PROP_NONE);
|
||||
|
|
|
@ -4407,6 +4407,11 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
|
|||
prop, "Extras", "Object details, including empty wire, cameras and other visual guides");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_light_colors", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_SHOW_LIGHT_COLORS);
|
||||
RNA_def_property_ui_text(prop, "Light Colors", "Show light colors");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_bones", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_negative_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_HIDE_BONES);
|
||||
RNA_def_property_ui_text(
|
||||
|
|
|
@ -237,6 +237,7 @@ static void rna_def_text(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "lines", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "TextLine");
|
||||
RNA_def_property_ui_text(prop, "Lines", "Lines of text");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
|
||||
|
||||
prop = RNA_def_property(srna, "current_line", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
|
|
|
@ -664,6 +664,7 @@ static void rna_def_volume(BlenderRNA *brna)
|
|||
"Velocity Unit",
|
||||
"Define how the velocity vectors are interpreted with regard to time, 'frame' means "
|
||||
"the delta time is 1 frame, 'second' means the delta time is 1 / FPS");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UNIT);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
|
||||
prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE);
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
*
|
||||
* The main missing features in this code compared to the paper are:
|
||||
*
|
||||
* + No mesh evolution. The paper suggests iteratively subsurfing the
|
||||
* - No mesh evolution. The paper suggests iteratively subdivision-surfacing the
|
||||
* skin output and adapting the output to better conform with the
|
||||
* spheres of influence surrounding each vertex.
|
||||
*
|
||||
* + No mesh fairing. The paper suggests re-aligning output edges to
|
||||
* - No mesh fairing. The paper suggests re-aligning output edges to
|
||||
* follow principal mesh curvatures.
|
||||
*
|
||||
* + No auxiliary balls. These would serve to influence mesh
|
||||
* - No auxiliary balls. These would serve to influence mesh
|
||||
* evolution, which as noted above is not implemented.
|
||||
*
|
||||
* The code also adds some features not present in the paper:
|
||||
|
@ -236,6 +236,8 @@ static bool quad_crosses_symmetry_plane(BMVert *quad[4], const SkinModifierData
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef WITH_BULLET
|
||||
|
||||
/* Returns true if the frame is filled by precisely two faces (and
|
||||
* outputs those faces to fill_faces), otherwise returns false. */
|
||||
static bool skin_frame_find_contained_faces(const Frame *frame, BMFace *fill_faces[2])
|
||||
|
@ -255,6 +257,8 @@ static bool skin_frame_find_contained_faces(const Frame *frame, BMFace *fill_fac
|
|||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Returns true if hull is successfully built, false otherwise */
|
||||
static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
|
||||
{
|
||||
|
@ -370,7 +374,7 @@ static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
|
|||
|
||||
return true;
|
||||
#else
|
||||
UNUSED_VARS(so, frames, totframe, skin_frame_find_contained_faces);
|
||||
UNUSED_VARS(so, frames, totframe);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ typedef struct RenderView {
|
|||
float *rectf;
|
||||
/* if this exists, result of composited layers */
|
||||
float *rectz;
|
||||
/* optional, 32 bits version of picture, used for sequencer, ogl render and image curves */
|
||||
/* optional, 32 bits version of picture, used for sequencer, OpenGL render and image curves */
|
||||
int *rect32;
|
||||
|
||||
} RenderView;
|
||||
|
@ -105,7 +105,7 @@ typedef struct RenderResult {
|
|||
/* The following rect32, rectf and rectz buffers are for temporary storage only,
|
||||
* for RenderResult structs created in #RE_AcquireResultImage - which do not have RenderView */
|
||||
|
||||
/* optional, 32 bits version of picture, used for ogl render and image curves */
|
||||
/* Optional, 32 bits version of picture, used for OpenGL render and image curves. */
|
||||
int *rect32;
|
||||
/* if this exists, a copy of one of layers, or result of composited layers */
|
||||
float *rectf;
|
||||
|
|
|
@ -116,7 +116,7 @@ bool RE_engine_is_external(const Render *re)
|
|||
|
||||
bool RE_engine_is_opengl(RenderEngineType *render_type)
|
||||
{
|
||||
/* TODO: refine? Can we have ogl render engine without ogl render pipeline? */
|
||||
/* TODO: refine? Can we have OpenGL render engine without OpenGL render pipeline? */
|
||||
return (render_type->draw_engine != nullptr) &&
|
||||
DRW_engine_render_support(render_type->draw_engine);
|
||||
}
|
||||
|
|
|
@ -862,7 +862,7 @@ void RE_test_break_cb(Render *re, void *handle, bool (*f)(void *handle))
|
|||
|
||||
void RE_gl_context_create(Render *re)
|
||||
{
|
||||
/* Needs to be created in the main ogl thread. */
|
||||
/* Needs to be created in the main OpenGL thread. */
|
||||
re->gl_context = WM_opengl_context_create();
|
||||
/* So we activate the window's one afterwards. */
|
||||
wm_window_reset_drawable();
|
||||
|
@ -870,7 +870,7 @@ void RE_gl_context_create(Render *re)
|
|||
|
||||
void RE_gl_context_destroy(Render *re)
|
||||
{
|
||||
/* Needs to be called from the thread which used the ogl context for rendering. */
|
||||
/* Needs to be called from the thread which used the OpenGL context for rendering. */
|
||||
if (re->gl_context) {
|
||||
if (re->gpu_context) {
|
||||
WM_opengl_context_activate(re->gl_context);
|
||||
|
|
|
@ -713,7 +713,18 @@ typedef struct wmEvent {
|
|||
/** Custom data type, stylus, 6-DOF, see `wm_event_types.h`. */
|
||||
short custom;
|
||||
short customdata_free;
|
||||
/** Ascii, unicode, mouse-coords, angles, vectors, NDOF data, drag-drop info. */
|
||||
/**
|
||||
* The #wmEvent::type implies the following #wmEvent::custodata.
|
||||
*
|
||||
* - #EVT_ACTIONZONE_AREA / #EVT_ACTIONZONE_FULLSCREEN / #EVT_ACTIONZONE_FULLSCREEN:
|
||||
* Uses #sActionzoneData.
|
||||
* - #EVT_DROP: uses #ListBase of #wmDrag (also #wmEvent::custom == #EVT_DATA_DRAGDROP).
|
||||
* Typically set to #wmWindowManger::drags.
|
||||
* - #EVT_FILESELECT: uses #wmOperator.
|
||||
* - #EVT_XR_ACTION: uses #wmXrActionData (also #wmEvent::custom == #EVT_DATA_XR).
|
||||
* - #NDOF_MOTION: uses #wmNDOFMotionData (also #wmEvent::custom == #EVT_DATA_NDOF_MOTION).
|
||||
* - #TIMER: uses #wmTimer (also #wmEvent::custom == #EVT_DATA_TIMER).
|
||||
*/
|
||||
void *customdata;
|
||||
|
||||
/* Previous State. */
|
||||
|
@ -849,7 +860,7 @@ typedef enum {
|
|||
/** Do not attempt to free custom-data pointer even if non-NULL. */
|
||||
WM_TIMER_NO_FREE_CUSTOM_DATA = 1 << 0,
|
||||
|
||||
/* Internal falgs, should not be used outside of WM code. */
|
||||
/* Internal flags, should not be used outside of WM code. */
|
||||
/** This timer has been tagged for removal and deletion, handled by WM code to ensure timers are
|
||||
* deleted in a safe context. */
|
||||
WM_TIMER_TAGGED_FOR_REMOVAL = 1 << 16,
|
||||
|
|
|
@ -271,18 +271,18 @@ void WM_gizmotype_target_property_def(wmGizmoType *gzt,
|
|||
int data_type,
|
||||
int array_length)
|
||||
{
|
||||
wmGizmoPropertyType *mpt;
|
||||
|
||||
BLI_assert(WM_gizmotype_target_property_find(gzt, idname) == NULL);
|
||||
|
||||
const uint idname_size = strlen(idname) + 1;
|
||||
mpt = MEM_callocN(sizeof(wmGizmoPropertyType) + idname_size, __func__);
|
||||
memcpy(mpt->idname, idname, idname_size);
|
||||
mpt->data_type = data_type;
|
||||
mpt->array_length = array_length;
|
||||
mpt->index_in_type = gzt->target_property_defs_len;
|
||||
wmGizmoPropertyType *gz_prop_type = MEM_callocN(sizeof(wmGizmoPropertyType) + idname_size,
|
||||
__func__);
|
||||
memcpy(gz_prop_type->idname, idname, idname_size);
|
||||
gz_prop_type->data_type = data_type;
|
||||
gz_prop_type->array_length = array_length;
|
||||
gz_prop_type->index_in_type = gzt->target_property_defs_len;
|
||||
gzt->target_property_defs_len += 1;
|
||||
BLI_addtail(&gzt->target_property_defs, mpt);
|
||||
BLI_addtail(&gzt->target_property_defs, gz_prop_type);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
Loading…
Reference in New Issue