forked from bartvdbraak/blender
Merge branch 'master' into blender2.8
This commit is contained in:
commit
ff2a74906a
@ -705,6 +705,21 @@ if [ "$WITH_ALL" = true -a "$OPENCOLLADA_SKIP" = false ]; then
|
||||
fi
|
||||
|
||||
|
||||
WARNING "****WARNING****"
|
||||
PRINT "If you are experiencing issues building Blender, _*TRY A FRESH, CLEAN BUILD FIRST*_!"
|
||||
PRINT "The same goes for install_deps itself, if you encounter issues, please first erase everything in $SRC and $INST"
|
||||
PRINT "(provided obviously you did not add anything yourself in those dirs!), and run install_deps.sh again!"
|
||||
PRINT "Often, changes in the libs built by this script, or in your distro package, cannot be handled simply, so..."
|
||||
PRINT ""
|
||||
PRINT "You may also try to use the '--build-foo' options to bypass your distribution's packages"
|
||||
PRINT "for some troublesome/buggy libraries..."
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
PRINT "Ran with:"
|
||||
PRINT " install_deps.sh $COMMANDLINE"
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
|
||||
|
||||
# This has to be done here, because user might force some versions...
|
||||
PYTHON_SOURCE=( "https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tgz" )
|
||||
@ -777,6 +792,8 @@ However, if you are experiencing linking errors (also when building Blender itse
|
||||
|
||||
Please note that until the transition to C++11-built libraries if completed in your distribution, situation will
|
||||
remain fuzzy and incompatibilities may happen..."
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||
export CXXFLAGS
|
||||
fi
|
||||
@ -4154,16 +4171,6 @@ print_info_ffmpeglink() {
|
||||
}
|
||||
|
||||
print_info() {
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
WARNING "****WARNING****"
|
||||
PRINT "If you are experiencing issues building Blender, _*TRY A FRESH, CLEAN BUILD FIRST*_!"
|
||||
PRINT "The same goes for install_deps itself, if you encounter issues, please first erase everything in $SRC and $INST"
|
||||
PRINT "(provided obviously you did not add anything yourself in those dirs!), and run install_deps.sh again!"
|
||||
PRINT "Often, changes in the libs built by this script, or in your distro package, cannot be handled simply, so..."
|
||||
PRINT ""
|
||||
PRINT "You may also try to use the '--build-foo' options to bypass your distribution's packages"
|
||||
PRINT "for some troublesome/buggy libraries..."
|
||||
PRINT ""
|
||||
PRINT ""
|
||||
PRINT "Ran with:"
|
||||
|
@ -112,7 +112,7 @@ set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221")
|
||||
|
||||
# MSVC only, Mingw doesnt need
|
||||
if(CMAKE_CL_64)
|
||||
set(PLATFORM_LINKFLAGS "/MACHINE:X64 /OPT:NOREF ${PLATFORM_LINKFLAGS}")
|
||||
set(PLATFORM_LINKFLAGS "/MACHINE:X64 ${PLATFORM_LINKFLAGS}")
|
||||
else()
|
||||
set(PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ${PLATFORM_LINKFLAGS}")
|
||||
endif()
|
||||
|
@ -77,7 +77,7 @@ namespace std {
|
||||
void resize(size_type new_size)
|
||||
{ resize(new_size, T()); }
|
||||
|
||||
#if defined(_VECTOR_)
|
||||
#if defined(_VECTOR_) && (_MSC_VER<1910)
|
||||
// workaround MSVC std::vector implementation
|
||||
void resize(size_type new_size, const value_type& x)
|
||||
{
|
||||
@ -110,7 +110,7 @@ namespace std {
|
||||
vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
|
||||
}
|
||||
#else
|
||||
// either GCC 4.1 or non-GCC
|
||||
// either GCC 4.1, MSVC2017 or non-GCC
|
||||
// default implementation which should always work.
|
||||
void resize(size_type new_size, const value_type& x)
|
||||
{
|
||||
|
3
extern/clew/include/clew.h
vendored
3
extern/clew/include/clew.h
vendored
@ -369,7 +369,8 @@ typedef unsigned int cl_GLenum;
|
||||
#endif
|
||||
|
||||
/* Define basic vector types */
|
||||
#if defined( __VEC__ )
|
||||
/* WOrkaround for ppc64el platform: conflicts with bool from C++. */
|
||||
#if defined( __VEC__ ) && !(defined(__PPC64__) && defined(__LITTLE_ENDIAN__))
|
||||
#include <altivec.h> /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */
|
||||
typedef vector unsigned char __cl_uchar16;
|
||||
typedef vector signed char __cl_char16;
|
||||
|
3
extern/glog/src/raw_logging.cc
vendored
3
extern/glog/src/raw_logging.cc
vendored
@ -59,7 +59,8 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H)
|
||||
// Hurd does not have SYS_write.
|
||||
#if (defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H)) && !defined(__GNU__)
|
||||
# define safe_write(fd, s, len) syscall(SYS_write, fd, s, len)
|
||||
#else
|
||||
// Not so safe, but what can you do?
|
||||
|
2
extern/glog/src/stacktrace_powerpc-inl.h
vendored
2
extern/glog/src/stacktrace_powerpc-inl.h
vendored
@ -111,7 +111,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
|
||||
result[n++] = *(sp+2);
|
||||
#elif defined(_CALL_SYSV)
|
||||
result[n++] = *(sp+1);
|
||||
#elif defined(__APPLE__) || (defined(__linux) && defined(__PPC64__))
|
||||
#elif defined(__APPLE__) || ((defined(__linux) || defined(__linux__)) && defined(__PPC64__))
|
||||
// This check is in case the compiler doesn't define _CALL_AIX/etc.
|
||||
result[n++] = *(sp+2);
|
||||
#elif defined(__linux)
|
||||
|
2
extern/rangetree/intern/range_tree.c
vendored
2
extern/rangetree/intern/range_tree.c
vendored
@ -808,7 +808,7 @@ bool range_tree_uint_retake(RangeTreeUInt *rt, const uint value)
|
||||
|
||||
uint range_tree_uint_take_any(RangeTreeUInt *rt)
|
||||
{
|
||||
Node *node = node = rt->list.first;
|
||||
Node *node = rt->list.first;
|
||||
uint value = node->min;
|
||||
if (value == node->max) {
|
||||
rt_node_remove(rt, node);
|
||||
|
@ -110,10 +110,10 @@ void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
|
||||
eos = true;
|
||||
}
|
||||
|
||||
if(position < m_start * rate)
|
||||
if(position < int(m_start * rate))
|
||||
{
|
||||
int len2 = length;
|
||||
for(int len = m_start * rate - position;
|
||||
for(int len = int(m_start * rate) - position;
|
||||
len2 == length && !eos;
|
||||
len -= length)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ import _cycles
|
||||
|
||||
enum_devices = (
|
||||
('CPU', "CPU", "Use CPU for rendering"),
|
||||
('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in user preferences"),
|
||||
('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in the system tab in the user preferences"),
|
||||
)
|
||||
|
||||
if _cycles.with_network:
|
||||
@ -129,6 +129,16 @@ enum_device_type = (
|
||||
('OPENCL', "OpenCL", "OpenCL", 2)
|
||||
)
|
||||
|
||||
enum_texture_limit = (
|
||||
('OFF', "No Limit", "No texture size limit", 0),
|
||||
('128', "128", "Limit texture size to 128 pixels", 1),
|
||||
('256', "256", "Limit texture size to 256 pixels", 2),
|
||||
('512', "512", "Limit texture size to 512 pixels", 3),
|
||||
('1024', "1024", "Limit texture size to 1024 pixels", 4),
|
||||
('2048', "2048", "Limit texture size to 2048 pixels", 5),
|
||||
('4096', "4096", "Limit texture size to 4096 pixels", 6),
|
||||
('8192', "8192", "Limit texture size to 8192 pixels", 7),
|
||||
)
|
||||
|
||||
class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
@classmethod
|
||||
@ -566,6 +576,19 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
min=0.0, max=5.0
|
||||
)
|
||||
|
||||
cls.use_distance_cull = BoolProperty(
|
||||
name="Use Distance Cull",
|
||||
description="Allow objects to be culled based on the distance from camera",
|
||||
default=False,
|
||||
)
|
||||
|
||||
cls.distance_cull_margin = FloatProperty(
|
||||
name="Cull Distance",
|
||||
description="Cull objects which are further away from camera than this distance",
|
||||
default=50,
|
||||
min=0.0
|
||||
)
|
||||
|
||||
cls.motion_blur_position = EnumProperty(
|
||||
name="Motion Blur Position",
|
||||
default='CENTER',
|
||||
@ -595,6 +618,20 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
min=0.0, max=1.0,
|
||||
)
|
||||
|
||||
cls.texture_limit = EnumProperty(
|
||||
name="Viewport Texture Limit",
|
||||
default='OFF',
|
||||
description="Limit texture size used by viewport rendering",
|
||||
items=enum_texture_limit
|
||||
)
|
||||
|
||||
cls.texture_limit_render = EnumProperty(
|
||||
name="Render Texture Limit",
|
||||
default='OFF',
|
||||
description="Limit texture size used by final rendering",
|
||||
items=enum_texture_limit
|
||||
)
|
||||
|
||||
# Various fine-tuning debug flags
|
||||
|
||||
def devices_update_callback(self, context):
|
||||
@ -1016,6 +1053,12 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
|
||||
default=False,
|
||||
)
|
||||
|
||||
cls.use_distance_cull = BoolProperty(
|
||||
name="Use Distance Cull",
|
||||
description="Allow this object and its duplicators to be culled by distance from camera",
|
||||
default=False,
|
||||
)
|
||||
|
||||
cls.use_adaptive_subdivision = BoolProperty(
|
||||
name="Use Adaptive Subdivision",
|
||||
description="Use adaptive render time subdivision",
|
||||
@ -1126,7 +1169,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
|
||||
def get_devices(self):
|
||||
import _cycles
|
||||
# Layout of the device tuples: (Name, Type, Internal ID, Persistent ID)
|
||||
# Layout of the device tuples: (Name, Type, Persistent ID)
|
||||
device_list = _cycles.available_devices()
|
||||
|
||||
cuda_devices = []
|
||||
@ -1174,21 +1217,19 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
|
||||
|
||||
def draw_impl(self, layout, context):
|
||||
layout.label(text="Compute Device:")
|
||||
layout.label(text="Cycles Compute Device:")
|
||||
layout.row().prop(self, "compute_device_type", expand=True)
|
||||
|
||||
cuda_devices, opencl_devices = self.get_devices()
|
||||
row = layout.row()
|
||||
|
||||
if cuda_devices:
|
||||
if self.compute_device_type == 'CUDA' and cuda_devices:
|
||||
col = row.column(align=True)
|
||||
col.label(text="CUDA devices:")
|
||||
for device in cuda_devices:
|
||||
col.prop(device, "use", text=device.name, toggle=True)
|
||||
|
||||
if opencl_devices:
|
||||
if self.compute_device_type == 'OPENCL' and opencl_devices:
|
||||
col = row.column(align=True)
|
||||
col.label(text="OpenCL devices:")
|
||||
for device in opencl_devices:
|
||||
col.prop(device, "use", text=device.name, toggle=True)
|
||||
|
||||
|
@ -769,6 +769,8 @@ class CyclesObject_PT_cycles_settings(CyclesButtonsPanel, Panel):
|
||||
row = col.row()
|
||||
row.active = scene.render.use_simplify and cscene.use_camera_cull
|
||||
row.prop(cob, "use_camera_cull")
|
||||
row.active = scene.render.use_simplify and cscene.use_distance_cull
|
||||
row.prop(cob, "use_distance_cull")
|
||||
|
||||
|
||||
class CYCLES_OT_use_shading_nodes(Operator):
|
||||
@ -1523,22 +1525,35 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
|
||||
cscene = scene.cycles
|
||||
|
||||
layout.active = rd.use_simplify
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Subdivision")
|
||||
row = col.row(align=True)
|
||||
row.prop(rd, "simplify_subdivision", text="Viewport")
|
||||
row.prop(rd, "simplify_subdivision_render", text="Render")
|
||||
|
||||
|
||||
col = layout.column(align=True)
|
||||
split = col.split()
|
||||
sub = split.column()
|
||||
sub.label(text="Texture Limit Viewport")
|
||||
sub.prop(cscene, "texture_limit", text="")
|
||||
sub = split.column()
|
||||
sub.label(text="Texture Limit Render")
|
||||
sub.prop(cscene, "texture_limit_render", text="")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Viewport:")
|
||||
col.prop(rd, "simplify_subdivision", text="Subdivision")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Render:")
|
||||
col.prop(rd, "simplify_subdivision_render", text="Subdivision")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(cscene, "use_camera_cull")
|
||||
subsub = col.column()
|
||||
subsub.active = cscene.use_camera_cull
|
||||
subsub.prop(cscene, "camera_cull_margin")
|
||||
row = col.row()
|
||||
row.active = cscene.use_camera_cull
|
||||
row.prop(cscene, "camera_cull_margin")
|
||||
|
||||
col = split.column()
|
||||
col.prop(cscene, "use_distance_cull")
|
||||
row = col.row()
|
||||
row.active = cscene.use_distance_cull
|
||||
row.prop(cscene, "distance_cull_margin", text="Distance")
|
||||
|
||||
def draw_device(self, context):
|
||||
scene = context.scene
|
||||
@ -1552,11 +1567,9 @@ def draw_device(self, context):
|
||||
|
||||
split = layout.split(percentage=1/3)
|
||||
split.label("Device:")
|
||||
row = split.row(align=True)
|
||||
sub = row.split(align=True)
|
||||
sub.active = show_device_selection(context)
|
||||
sub.prop(cscene, "device", text="")
|
||||
row.operator("wm.addon_userpref_show", text="", icon='PREFERENCES').module = __package__
|
||||
row = split.row()
|
||||
row.active = show_device_selection(context)
|
||||
row.prop(cscene, "device", text="")
|
||||
|
||||
if engine.with_osl() and use_cpu(context):
|
||||
layout.prop(cscene, "shading_system")
|
||||
|
@ -172,6 +172,24 @@ def custom_bake_remap(scene):
|
||||
|
||||
@persistent
|
||||
def do_versions(self):
|
||||
if bpy.context.user_preferences.version <= (2, 78, 1):
|
||||
prop = bpy.context.user_preferences.addons[__package__].preferences
|
||||
system = bpy.context.user_preferences.system
|
||||
if not prop.is_property_set("compute_device_type"):
|
||||
# Device might not currently be available so this can fail
|
||||
try:
|
||||
if system.legacy_compute_device_type == 1:
|
||||
prop.compute_device_type = 'OPENCL'
|
||||
elif system.legacy_compute_device_type == 2:
|
||||
prop.compute_device_type = 'CUDA'
|
||||
else:
|
||||
prop.compute_device_type = 'NONE'
|
||||
except:
|
||||
pass
|
||||
|
||||
# Init device list for UI
|
||||
prop.get_devices()
|
||||
|
||||
# We don't modify startup file because it assumes to
|
||||
# have all the default values only.
|
||||
if not bpy.data.is_saved:
|
||||
|
@ -88,6 +88,143 @@ static uint object_ray_visibility(BL::Object& b_ob)
|
||||
return flag;
|
||||
}
|
||||
|
||||
/* Culling */
|
||||
|
||||
class BlenderObjectCulling
|
||||
{
|
||||
public:
|
||||
BlenderObjectCulling(Scene *scene, BL::Scene& b_scene)
|
||||
: use_scene_camera_cull(false),
|
||||
use_camera_cull(false),
|
||||
camera_cull_margin(0.0f),
|
||||
use_scene_distance_cull(false),
|
||||
use_distance_cull(false),
|
||||
distance_cull_margin(0.0f)
|
||||
{
|
||||
if(b_scene.render().use_simplify()) {
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
|
||||
use_scene_camera_cull = scene->camera->type != CAMERA_PANORAMA &&
|
||||
!b_scene.render().use_multiview() &&
|
||||
get_boolean(cscene, "use_camera_cull");
|
||||
use_scene_distance_cull = scene->camera->type != CAMERA_PANORAMA &&
|
||||
!b_scene.render().use_multiview() &&
|
||||
get_boolean(cscene, "use_distance_cull");
|
||||
|
||||
camera_cull_margin = get_float(cscene, "camera_cull_margin");
|
||||
distance_cull_margin = get_float(cscene, "distance_cull_margin");
|
||||
|
||||
if (distance_cull_margin == 0.0f) {
|
||||
use_scene_distance_cull = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_object(Scene *scene, BL::Object& b_ob)
|
||||
{
|
||||
if(!use_scene_camera_cull && !use_scene_distance_cull) {
|
||||
return;
|
||||
}
|
||||
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
|
||||
use_camera_cull = use_scene_camera_cull && get_boolean(cobject, "use_camera_cull");
|
||||
use_distance_cull = use_scene_distance_cull && get_boolean(cobject, "use_distance_cull");
|
||||
|
||||
if(use_camera_cull || use_distance_cull) {
|
||||
/* Need to have proper projection matrix. */
|
||||
scene->camera->update();
|
||||
}
|
||||
}
|
||||
|
||||
bool test(Scene *scene, BL::Object& b_ob, Transform& tfm)
|
||||
{
|
||||
if(!use_camera_cull && !use_distance_cull) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Compute world space bounding box corners. */
|
||||
float3 bb[8];
|
||||
BL::Array<float, 24> boundbox = b_ob.bound_box();
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
float3 p = make_float3(boundbox[3 * i + 0],
|
||||
boundbox[3 * i + 1],
|
||||
boundbox[3 * i + 2]);
|
||||
bb[i] = transform_point(&tfm, p);
|
||||
}
|
||||
|
||||
bool camera_culled = use_camera_cull && test_camera(scene, bb);
|
||||
bool distance_culled = use_distance_cull && test_distance(scene, bb);
|
||||
|
||||
return ((camera_culled && distance_culled) ||
|
||||
(camera_culled && !use_distance_cull) ||
|
||||
(distance_culled && !use_camera_cull));
|
||||
}
|
||||
|
||||
private:
|
||||
/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order
|
||||
* to reduce number of objects which are wrongly considered visible.
|
||||
*/
|
||||
bool test_camera(Scene *scene, float3 bb[8])
|
||||
{
|
||||
Camera *cam = scene->camera;
|
||||
Transform& worldtondc = cam->worldtondc;
|
||||
float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
|
||||
bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
bool all_behind = true;
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
float3 p = bb[i];
|
||||
float4 b = make_float4(p.x, p.y, p.z, 1.0f);
|
||||
float4 c = make_float4(dot(worldtondc.x, b),
|
||||
dot(worldtondc.y, b),
|
||||
dot(worldtondc.z, b),
|
||||
dot(worldtondc.w, b));
|
||||
p = float4_to_float3(c / c.w);
|
||||
if(c.z < 0.0f) {
|
||||
p.x = 1.0f - p.x;
|
||||
p.y = 1.0f - p.y;
|
||||
}
|
||||
if(c.z >= -camera_cull_margin) {
|
||||
all_behind = false;
|
||||
}
|
||||
bb_min = min(bb_min, p);
|
||||
bb_max = max(bb_max, p);
|
||||
}
|
||||
if(all_behind) {
|
||||
return true;
|
||||
}
|
||||
return (bb_min.x >= 1.0f + camera_cull_margin ||
|
||||
bb_min.y >= 1.0f + camera_cull_margin ||
|
||||
bb_max.x <= -camera_cull_margin ||
|
||||
bb_max.y <= -camera_cull_margin);
|
||||
}
|
||||
|
||||
bool test_distance(Scene *scene, float3 bb[8])
|
||||
{
|
||||
float3 camera_position = transform_get_column(&scene->camera->matrix, 3);
|
||||
float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
|
||||
bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
|
||||
/* Find min & max points for x & y & z on bounding box */
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
float3 p = bb[i];
|
||||
bb_min = min(bb_min, p);
|
||||
bb_max = max(bb_max, p);
|
||||
}
|
||||
|
||||
float3 closest_point = max(min(bb_max,camera_position),bb_min);
|
||||
return (len_squared(camera_position - closest_point) >
|
||||
distance_cull_margin * distance_cull_margin);
|
||||
}
|
||||
|
||||
bool use_scene_camera_cull;
|
||||
bool use_camera_cull;
|
||||
float camera_cull_margin;
|
||||
bool use_scene_distance_cull;
|
||||
bool use_distance_cull;
|
||||
float distance_cull_margin;
|
||||
};
|
||||
|
||||
/* Light */
|
||||
|
||||
void BlenderSync::sync_light(BL::Object& b_parent,
|
||||
@ -235,55 +372,6 @@ void BlenderSync::sync_background_light(bool use_portal)
|
||||
|
||||
/* Object */
|
||||
|
||||
/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order
|
||||
* to reduce number of objects which are wrongly considered visible.
|
||||
*/
|
||||
static bool object_boundbox_clip(Scene *scene,
|
||||
BL::Object& b_ob,
|
||||
Transform& tfm,
|
||||
float margin)
|
||||
{
|
||||
Camera *cam = scene->camera;
|
||||
Transform& worldtondc = cam->worldtondc;
|
||||
BL::Array<float, 24> boundbox = b_ob.bound_box();
|
||||
float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX),
|
||||
bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
bool all_behind = true;
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
float3 p = make_float3(boundbox[3 * i + 0],
|
||||
boundbox[3 * i + 1],
|
||||
boundbox[3 * i + 2]);
|
||||
p = transform_point(&tfm, p);
|
||||
|
||||
float4 b = make_float4(p.x, p.y, p.z, 1.0f);
|
||||
float4 c = make_float4(dot(worldtondc.x, b),
|
||||
dot(worldtondc.y, b),
|
||||
dot(worldtondc.z, b),
|
||||
dot(worldtondc.w, b));
|
||||
p = float4_to_float3(c / c.w);
|
||||
if(c.z < 0.0f) {
|
||||
p.x = 1.0f - p.x;
|
||||
p.y = 1.0f - p.y;
|
||||
}
|
||||
if(c.z >= -margin) {
|
||||
all_behind = false;
|
||||
}
|
||||
bb_min = min(bb_min, p);
|
||||
bb_max = max(bb_max, p);
|
||||
}
|
||||
if(!all_behind) {
|
||||
if(bb_min.x >= 1.0f + margin ||
|
||||
bb_min.y >= 1.0f + margin ||
|
||||
bb_max.x <= -margin ||
|
||||
bb_max.y <= -margin)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Object *BlenderSync::sync_object(BL::Object& b_parent,
|
||||
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
|
||||
BL::DupliObject& b_dupli_ob,
|
||||
@ -291,8 +379,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
|
||||
uint layer_flag,
|
||||
float motion_time,
|
||||
bool hide_tris,
|
||||
bool use_camera_cull,
|
||||
float camera_cull_margin,
|
||||
BlenderObjectCulling& culling,
|
||||
bool *use_portal)
|
||||
{
|
||||
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
|
||||
@ -308,11 +395,12 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
|
||||
}
|
||||
|
||||
/* only interested in object that we can create meshes from */
|
||||
if(!object_is_mesh(b_ob))
|
||||
if(!object_is_mesh(b_ob)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Perform camera space culling. */
|
||||
if(use_camera_cull && object_boundbox_clip(scene, b_ob, tfm, camera_cull_margin)) {
|
||||
/* Perform object culling. */
|
||||
if(culling.test(scene, b_ob, tfm)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -519,17 +607,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
|
||||
mesh_motion_synced.clear();
|
||||
}
|
||||
|
||||
bool allow_camera_cull = false;
|
||||
float camera_cull_margin = 0.0f;
|
||||
if(b_scene.render().use_simplify()) {
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
allow_camera_cull = scene->camera->type != CAMERA_PANORAMA &&
|
||||
!b_scene.render().use_multiview() &&
|
||||
get_boolean(cscene, "use_camera_cull");
|
||||
if(allow_camera_cull) {
|
||||
camera_cull_margin = get_float(cscene, "camera_cull_margin");
|
||||
}
|
||||
}
|
||||
/* initialize culling */
|
||||
BlenderObjectCulling culling(scene, b_scene);
|
||||
|
||||
/* object loop */
|
||||
BL::Scene::object_bases_iterator b_base;
|
||||
@ -561,12 +640,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
|
||||
if(!hide) {
|
||||
progress.set_sync_status("Synchronizing object", b_ob.name());
|
||||
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
bool use_camera_cull = allow_camera_cull && get_boolean(cobject, "use_camera_cull");
|
||||
if(use_camera_cull) {
|
||||
/* Need to have proper projection matrix. */
|
||||
scene->camera->update();
|
||||
}
|
||||
/* load per-object culling data */
|
||||
culling.init_object(scene, b_ob);
|
||||
|
||||
if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) {
|
||||
/* dupli objects */
|
||||
b_ob.dupli_list_create(b_scene, dupli_settings);
|
||||
@ -593,8 +669,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
|
||||
ob_layer,
|
||||
motion_time,
|
||||
hide_tris,
|
||||
use_camera_cull,
|
||||
camera_cull_margin,
|
||||
culling,
|
||||
&use_portal);
|
||||
}
|
||||
}
|
||||
@ -616,8 +691,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time)
|
||||
ob_layer,
|
||||
motion_time,
|
||||
hide_tris,
|
||||
use_camera_cull,
|
||||
camera_cull_margin,
|
||||
culling,
|
||||
&use_portal);
|
||||
}
|
||||
}
|
||||
|
@ -126,8 +126,8 @@ void BlenderSession::create_session()
|
||||
|
||||
/* setup callbacks for builtin image support */
|
||||
scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7);
|
||||
scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3);
|
||||
scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3);
|
||||
scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4);
|
||||
scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4);
|
||||
|
||||
/* create session */
|
||||
session = new Session(session_params);
|
||||
@ -1080,7 +1080,13 @@ int BlenderSession::builtin_image_frame(const string &builtin_name)
|
||||
return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
|
||||
}
|
||||
|
||||
void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels)
|
||||
void BlenderSession::builtin_image_info(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
bool &is_float,
|
||||
int &width,
|
||||
int &height,
|
||||
int &depth,
|
||||
int &channels)
|
||||
{
|
||||
/* empty image */
|
||||
is_float = false;
|
||||
@ -1158,60 +1164,67 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti
|
||||
}
|
||||
}
|
||||
|
||||
bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels)
|
||||
bool BlenderSession::builtin_image_pixels(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
unsigned char *pixels,
|
||||
const size_t pixels_size)
|
||||
{
|
||||
if(!builtin_data)
|
||||
if(!builtin_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int frame = builtin_image_frame(builtin_name);
|
||||
const int frame = builtin_image_frame(builtin_name);
|
||||
|
||||
PointerRNA ptr;
|
||||
RNA_id_pointer_create((ID*)builtin_data, &ptr);
|
||||
BL::Image b_image(ptr);
|
||||
|
||||
int width = b_image.size()[0];
|
||||
int height = b_image.size()[1];
|
||||
int channels = b_image.channels();
|
||||
const int width = b_image.size()[0];
|
||||
const int height = b_image.size()[1];
|
||||
const int channels = b_image.channels();
|
||||
|
||||
unsigned char *image_pixels;
|
||||
image_pixels = image_get_pixels_for_frame(b_image, frame);
|
||||
size_t num_pixels = ((size_t)width) * height;
|
||||
unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame);
|
||||
const size_t num_pixels = ((size_t)width) * height;
|
||||
|
||||
if(image_pixels) {
|
||||
memcpy(pixels, image_pixels, num_pixels * channels * sizeof(unsigned char));
|
||||
if(image_pixels && num_pixels * channels == pixels_size) {
|
||||
memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
|
||||
MEM_freeN(image_pixels);
|
||||
}
|
||||
else {
|
||||
if(channels == 1) {
|
||||
memset(pixels, 0, num_pixels * sizeof(unsigned char));
|
||||
memset(pixels, 0, pixels_size * sizeof(unsigned char));
|
||||
}
|
||||
else {
|
||||
const size_t num_pixels_safe = pixels_size / channels;
|
||||
unsigned char *cp = pixels;
|
||||
for(size_t i = 0; i < num_pixels; i++, cp += channels) {
|
||||
for(size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
|
||||
cp[0] = 255;
|
||||
cp[1] = 0;
|
||||
cp[2] = 255;
|
||||
if(channels == 4)
|
||||
if(channels == 4) {
|
||||
cp[3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* premultiply, byte images are always straight for blender */
|
||||
/* Premultiply, byte images are always straight for Blender. */
|
||||
unsigned char *cp = pixels;
|
||||
for(size_t i = 0; i < num_pixels; i++, cp += channels) {
|
||||
cp[0] = (cp[0] * cp[3]) >> 8;
|
||||
cp[1] = (cp[1] * cp[3]) >> 8;
|
||||
cp[2] = (cp[2] * cp[3]) >> 8;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels)
|
||||
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
float *pixels,
|
||||
const size_t pixels_size)
|
||||
{
|
||||
if(!builtin_data)
|
||||
if(!builtin_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PointerRNA ptr;
|
||||
RNA_id_pointer_create((ID*)builtin_data, &ptr);
|
||||
@ -1222,16 +1235,16 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
|
||||
BL::Image b_image(b_id);
|
||||
int frame = builtin_image_frame(builtin_name);
|
||||
|
||||
int width = b_image.size()[0];
|
||||
int height = b_image.size()[1];
|
||||
int channels = b_image.channels();
|
||||
const int width = b_image.size()[0];
|
||||
const int height = b_image.size()[1];
|
||||
const int channels = b_image.channels();
|
||||
|
||||
float *image_pixels;
|
||||
image_pixels = image_get_float_pixels_for_frame(b_image, frame);
|
||||
size_t num_pixels = ((size_t)width) * height;
|
||||
const size_t num_pixels = ((size_t)width) * height;
|
||||
|
||||
if(image_pixels) {
|
||||
memcpy(pixels, image_pixels, num_pixels * channels * sizeof(float));
|
||||
if(image_pixels && num_pixels * channels == pixels_size) {
|
||||
memcpy(pixels, image_pixels, pixels_size * sizeof(float));
|
||||
MEM_freeN(image_pixels);
|
||||
}
|
||||
else {
|
||||
@ -1239,13 +1252,15 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
|
||||
memset(pixels, 0, num_pixels * sizeof(float));
|
||||
}
|
||||
else {
|
||||
const size_t num_pixels_safe = pixels_size / channels;
|
||||
float *fp = pixels;
|
||||
for(int i = 0; i < num_pixels; i++, fp += channels) {
|
||||
for(int i = 0; i < num_pixels_safe; i++, fp += channels) {
|
||||
fp[0] = 1.0f;
|
||||
fp[1] = 0.0f;
|
||||
fp[2] = 1.0f;
|
||||
if(channels == 4)
|
||||
if(channels == 4) {
|
||||
fp[3] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1257,8 +1272,9 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
|
||||
BL::Object b_ob(b_id);
|
||||
BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
|
||||
|
||||
if(!b_domain)
|
||||
if(!b_domain) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int3 resolution = get_int3(b_domain.domain_resolution());
|
||||
int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
|
||||
@ -1270,10 +1286,10 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
|
||||
amplify = 1;
|
||||
}
|
||||
|
||||
int width = resolution.x * amplify;
|
||||
int height = resolution.y * amplify;
|
||||
int depth = resolution.z * amplify;
|
||||
size_t num_pixels = ((size_t)width) * height * depth;
|
||||
const int width = resolution.x * amplify;
|
||||
const int height = resolution.y * amplify;
|
||||
const int depth = resolution.z * amplify;
|
||||
const size_t num_pixels = ((size_t)width) * height * depth;
|
||||
|
||||
if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
|
||||
SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
|
||||
|
@ -145,9 +145,21 @@ protected:
|
||||
void do_write_update_render_tile(RenderTile& rtile, bool do_update_only);
|
||||
|
||||
int builtin_image_frame(const string &builtin_name);
|
||||
void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels);
|
||||
bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels);
|
||||
bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels);
|
||||
void builtin_image_info(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
bool &is_float,
|
||||
int &width,
|
||||
int &height,
|
||||
int &depth,
|
||||
int &channels);
|
||||
bool builtin_image_pixels(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
unsigned char *pixels,
|
||||
const size_t pixels_size);
|
||||
bool builtin_image_float_pixels(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
float *pixels,
|
||||
const size_t pixels_size);
|
||||
|
||||
/* Update tile manager to reflect resumable render settings. */
|
||||
void update_resumable_tile_manager(int num_samples);
|
||||
|
@ -496,6 +496,20 @@ SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
|
||||
else
|
||||
params.persistent_data = false;
|
||||
|
||||
int texture_limit;
|
||||
if(background) {
|
||||
texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
|
||||
}
|
||||
else {
|
||||
texture_limit = RNA_enum_get(&cscene, "texture_limit");
|
||||
}
|
||||
if(texture_limit > 0 && b_scene.render().use_simplify()) {
|
||||
params.texture_limit = 1 << (texture_limit + 6);
|
||||
}
|
||||
else {
|
||||
params.texture_limit = 0;
|
||||
}
|
||||
|
||||
#if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||
if(is_cpu) {
|
||||
params.use_qbvh = DebugFlags().cpu.qbvh && system_cpu_support_sse2();
|
||||
|
@ -35,6 +35,7 @@
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Background;
|
||||
class BlenderObjectCulling;
|
||||
class Camera;
|
||||
class Film;
|
||||
class Light;
|
||||
@ -122,8 +123,7 @@ private:
|
||||
uint layer_flag,
|
||||
float motion_time,
|
||||
bool hide_tris,
|
||||
bool use_camera_cull,
|
||||
float camera_cull_margin,
|
||||
BlenderObjectCulling& culling,
|
||||
bool *use_portal);
|
||||
void sync_light(BL::Object& b_parent,
|
||||
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
|
||||
|
@ -1418,7 +1418,11 @@ void device_cuda_info(vector<DeviceInfo>& devices)
|
||||
cuDeviceGetAttribute(&pci_location[0], CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, num);
|
||||
cuDeviceGetAttribute(&pci_location[1], CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, num);
|
||||
cuDeviceGetAttribute(&pci_location[2], CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, num);
|
||||
info.id = string_printf("CUDA_%s_%04x:%02x:%02x", name, pci_location[0], pci_location[1], pci_location[2]);
|
||||
info.id = string_printf("CUDA_%s_%04x:%02x:%02x",
|
||||
name,
|
||||
(unsigned int)pci_location[0],
|
||||
(unsigned int)pci_location[1],
|
||||
(unsigned int)pci_location[2]);
|
||||
|
||||
/* if device has a kernel timeout, assume it is used for display */
|
||||
if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) {
|
||||
|
@ -16,14 +16,14 @@
|
||||
|
||||
#ifdef WITH_OPENCL
|
||||
|
||||
#include "clew.h"
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#include "util_map.h"
|
||||
#include "util_param.h"
|
||||
#include "util_string.h"
|
||||
|
||||
#include "clew.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#define CL_MEM_PTR(p) ((cl_mem)(uintptr_t)(p))
|
||||
|
@ -667,7 +667,10 @@ string OpenCLInfo::get_hardware_id(string platform_name, cl_device_id device_id)
|
||||
/* Use cl_amd_device_topology extension. */
|
||||
cl_char topology[24];
|
||||
if(clGetDeviceInfo(device_id, 0x4037, sizeof(topology), topology, NULL) == CL_SUCCESS && topology[0] == 1) {
|
||||
return string_printf("%02x:%02x.%01x", topology[21], topology[22], topology[23]);
|
||||
return string_printf("%02x:%02x.%01x",
|
||||
(unsigned int)topology[21],
|
||||
(unsigned int)topology[22],
|
||||
(unsigned int)topology[23]);
|
||||
}
|
||||
}
|
||||
else if(platform_name == "NVIDIA CUDA") {
|
||||
@ -675,7 +678,10 @@ string OpenCLInfo::get_hardware_id(string platform_name, cl_device_id device_id)
|
||||
cl_int bus_id, slot_id;
|
||||
if(clGetDeviceInfo(device_id, 0x4008, sizeof(cl_int), &bus_id, NULL) == CL_SUCCESS &&
|
||||
clGetDeviceInfo(device_id, 0x4009, sizeof(cl_int), &slot_id, NULL) == CL_SUCCESS) {
|
||||
return string_printf("%02x:%02x.%01x", bus_id, slot_id>>3, slot_id & 0x7);
|
||||
return string_printf("%02x:%02x.%01x",
|
||||
(unsigned int)(bus_id),
|
||||
(unsigned int)(slot_id >> 3),
|
||||
(unsigned int)(slot_id & 0x7));
|
||||
}
|
||||
}
|
||||
/* No general way to get a hardware ID from OpenCL => give up. */
|
||||
|
@ -245,11 +245,18 @@ ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, floa
|
||||
float t = ray->t;
|
||||
|
||||
float delta = dot((light_P - ray->P) , ray->D);
|
||||
float D = sqrtf(len_squared(light_P - ray->P) - delta * delta);
|
||||
float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
|
||||
if(UNLIKELY(D == 0.0f)) {
|
||||
*pdf = 0.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
float theta_a = -atan2f(delta, D);
|
||||
float theta_b = atan2f(t - delta, D);
|
||||
float t_ = D * tanf((xi * theta_b) + (1 - xi) * theta_a);
|
||||
|
||||
if(UNLIKELY(theta_b == theta_a)) {
|
||||
*pdf = 0.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
*pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
|
||||
|
||||
return min(t, delta + t_); /* min is only for float precision errors */
|
||||
@ -258,13 +265,19 @@ ccl_device float kernel_volume_equiangular_sample(Ray *ray, float3 light_P, floa
|
||||
ccl_device float kernel_volume_equiangular_pdf(Ray *ray, float3 light_P, float sample_t)
|
||||
{
|
||||
float delta = dot((light_P - ray->P) , ray->D);
|
||||
float D = sqrtf(len_squared(light_P - ray->P) - delta * delta);
|
||||
float D = safe_sqrtf(len_squared(light_P - ray->P) - delta * delta);
|
||||
if(UNLIKELY(D == 0.0f)) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float t = ray->t;
|
||||
float t_ = sample_t - delta;
|
||||
|
||||
float theta_a = -atan2f(delta, D);
|
||||
float theta_b = atan2f(t - delta, D);
|
||||
if(UNLIKELY(theta_b == theta_a)) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float pdf = D / ((theta_b - theta_a) * (D * D + t_ * t_));
|
||||
|
||||
@ -958,6 +971,9 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
|
||||
mis_weight = 2.0f*power_heuristic(pdf, distance_pdf);
|
||||
}
|
||||
}
|
||||
if(sample_t < 1e-6f) {
|
||||
return VOLUME_PATH_SCATTERED;
|
||||
}
|
||||
|
||||
/* compute transmittance up to this step */
|
||||
if(step != segment->steps)
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "scene.h"
|
||||
|
||||
#include "util_foreach.h"
|
||||
#include "util_logging.h"
|
||||
#include "util_path.h"
|
||||
#include "util_progress.h"
|
||||
#include "util_texture.h"
|
||||
@ -476,6 +477,7 @@ template<TypeDesc::BASETYPE FileFormat,
|
||||
typename DeviceType>
|
||||
bool ImageManager::file_load_image(Image *img,
|
||||
ImageDataType type,
|
||||
int texture_limit,
|
||||
device_vector<DeviceType>& tex_img)
|
||||
{
|
||||
const StorageType alpha_one = (FileFormat == TypeDesc::UINT8)? 255 : 1;
|
||||
@ -485,11 +487,18 @@ bool ImageManager::file_load_image(Image *img,
|
||||
return false;
|
||||
}
|
||||
/* Read RGBA pixels. */
|
||||
StorageType *pixels = (StorageType*)tex_img.resize(width, height, depth);
|
||||
if(pixels == NULL) {
|
||||
return false;
|
||||
vector<StorageType> pixels_storage;
|
||||
StorageType *pixels;
|
||||
const size_t max_size = max(max(width, height), depth);
|
||||
if(texture_limit > 0 && max_size > texture_limit) {
|
||||
pixels_storage.resize(((size_t)width)*height*depth*4);
|
||||
pixels = &pixels_storage[0];
|
||||
}
|
||||
else {
|
||||
pixels = (StorageType*)tex_img.resize(width, height, depth);
|
||||
}
|
||||
bool cmyk = false;
|
||||
const size_t num_pixels = ((size_t)width) * height * depth;
|
||||
if(in) {
|
||||
StorageType *readpixels = pixels;
|
||||
vector<StorageType> tmppixels;
|
||||
@ -526,12 +535,14 @@ bool ImageManager::file_load_image(Image *img,
|
||||
if(FileFormat == TypeDesc::FLOAT) {
|
||||
builtin_image_float_pixels_cb(img->filename,
|
||||
img->builtin_data,
|
||||
(float*)pixels);
|
||||
(float*)&pixels[0],
|
||||
num_pixels * components);
|
||||
}
|
||||
else if(FileFormat == TypeDesc::UINT8) {
|
||||
builtin_image_pixels_cb(img->filename,
|
||||
img->builtin_data,
|
||||
(uchar*)pixels);
|
||||
(uchar*)&pixels[0],
|
||||
num_pixels * components);
|
||||
}
|
||||
else {
|
||||
/* TODO(dingto): Support half for ImBuf. */
|
||||
@ -540,11 +551,10 @@ bool ImageManager::file_load_image(Image *img,
|
||||
/* Check if we actually have a float4 slot, in case components == 1,
|
||||
* but device doesn't support single channel textures.
|
||||
*/
|
||||
if(type == IMAGE_DATA_TYPE_FLOAT4 ||
|
||||
type == IMAGE_DATA_TYPE_HALF4 ||
|
||||
type == IMAGE_DATA_TYPE_BYTE4)
|
||||
{
|
||||
size_t num_pixels = ((size_t)width) * height * depth;
|
||||
bool is_rgba = (type == IMAGE_DATA_TYPE_FLOAT4 ||
|
||||
type == IMAGE_DATA_TYPE_HALF4 ||
|
||||
type == IMAGE_DATA_TYPE_BYTE4);
|
||||
if(is_rgba) {
|
||||
if(cmyk) {
|
||||
/* CMYK */
|
||||
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
|
||||
@ -587,10 +597,37 @@ bool ImageManager::file_load_image(Image *img,
|
||||
}
|
||||
}
|
||||
}
|
||||
if(pixels_storage.size() > 0) {
|
||||
float scale_factor = 1.0f;
|
||||
while(max_size * scale_factor > texture_limit) {
|
||||
scale_factor *= 0.5f;
|
||||
}
|
||||
VLOG(1) << "Scaling image " << img->filename
|
||||
<< " by a factor of " << scale_factor << ".";
|
||||
vector<StorageType> scaled_pixels;
|
||||
size_t scaled_width, scaled_height, scaled_depth;
|
||||
util_image_resize_pixels(pixels_storage,
|
||||
width, height, depth,
|
||||
is_rgba ? 4 : 1,
|
||||
scale_factor,
|
||||
&scaled_pixels,
|
||||
&scaled_width, &scaled_height, &scaled_depth);
|
||||
StorageType *texture_pixels = (StorageType*)tex_img.resize(scaled_width,
|
||||
scaled_height,
|
||||
scaled_depth);
|
||||
memcpy(texture_pixels,
|
||||
&scaled_pixels[0],
|
||||
scaled_pixels.size() * sizeof(StorageType));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot, Progress *progress)
|
||||
void ImageManager::device_load_image(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
ImageDataType type,
|
||||
int slot,
|
||||
Progress *progress)
|
||||
{
|
||||
if(progress->get_cancel())
|
||||
return;
|
||||
@ -603,6 +640,8 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
|
||||
string filename = path_filename(images[type][slot]->filename);
|
||||
progress->set_status("Updating Images", "Loading " + filename);
|
||||
|
||||
const int texture_limit = scene->params.texture_limit;
|
||||
|
||||
/* Slot assignment */
|
||||
int flat_slot = type_index_to_flattened_slot(slot, type);
|
||||
|
||||
@ -622,7 +661,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
|
||||
device->tex_free(tex_img);
|
||||
}
|
||||
|
||||
if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) {
|
||||
if(!file_load_image<TypeDesc::FLOAT, float>(img,
|
||||
type,
|
||||
texture_limit,
|
||||
tex_img))
|
||||
{
|
||||
/* on failure to load, we set a 1x1 pixels pink image */
|
||||
float *pixels = (float*)tex_img.resize(1, 1);
|
||||
|
||||
@ -648,7 +691,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
|
||||
device->tex_free(tex_img);
|
||||
}
|
||||
|
||||
if(!file_load_image<TypeDesc::FLOAT, float>(img, type, tex_img)) {
|
||||
if(!file_load_image<TypeDesc::FLOAT, float>(img,
|
||||
type,
|
||||
texture_limit,
|
||||
tex_img))
|
||||
{
|
||||
/* on failure to load, we set a 1x1 pixels pink image */
|
||||
float *pixels = (float*)tex_img.resize(1, 1);
|
||||
|
||||
@ -671,7 +718,11 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
|
||||
device->tex_free(tex_img);
|
||||
}
|
||||
|
||||
if(!file_load_image<TypeDesc::UINT8, uchar>(img, type, tex_img)) {
|
||||
if(!file_load_image<TypeDesc::UINT8, uchar>(img,
|
||||
type,
|
||||
texture_limit,
|
||||
tex_img))
|
||||
{
|
||||
/* on failure to load, we set a 1x1 pixels pink image */
|
||||
uchar *pixels = (uchar*)tex_img.resize(1, 1);
|
||||
|
||||
@ -697,7 +748,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
|
||||
device->tex_free(tex_img);
|
||||
}
|
||||
|
||||
if(!file_load_image<TypeDesc::UINT8, uchar>(img, type, tex_img)) {
|
||||
if(!file_load_image<TypeDesc::UINT8, uchar>(img,
|
||||
type,
|
||||
texture_limit,
|
||||
tex_img)) {
|
||||
/* on failure to load, we set a 1x1 pixels pink image */
|
||||
uchar *pixels = (uchar*)tex_img.resize(1, 1);
|
||||
|
||||
@ -720,7 +774,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
|
||||
device->tex_free(tex_img);
|
||||
}
|
||||
|
||||
if(!file_load_image<TypeDesc::HALF, half>(img, type, tex_img)) {
|
||||
if(!file_load_image<TypeDesc::HALF, half>(img,
|
||||
type,
|
||||
texture_limit,
|
||||
tex_img)) {
|
||||
/* on failure to load, we set a 1x1 pixels pink image */
|
||||
half *pixels = (half*)tex_img.resize(1, 1);
|
||||
|
||||
@ -746,7 +803,10 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, ImageD
|
||||
device->tex_free(tex_img);
|
||||
}
|
||||
|
||||
if(!file_load_image<TypeDesc::HALF, half>(img, type, tex_img)) {
|
||||
if(!file_load_image<TypeDesc::HALF, half>(img,
|
||||
type,
|
||||
texture_limit,
|
||||
tex_img)) {
|
||||
/* on failure to load, we set a 1x1 pixels pink image */
|
||||
half *pixels = (half*)tex_img.resize(1, 1);
|
||||
|
||||
@ -842,7 +902,10 @@ void ImageManager::device_free_image(Device *device, DeviceScene *dscene, ImageD
|
||||
}
|
||||
}
|
||||
|
||||
void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress& progress)
|
||||
void ImageManager::device_update(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
Progress& progress)
|
||||
{
|
||||
if(!need_update)
|
||||
return;
|
||||
@ -859,7 +922,14 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
|
||||
}
|
||||
else if(images[type][slot]->need_load) {
|
||||
if(!osl_texture_system || images[type][slot]->builtin_data)
|
||||
pool.push(function_bind(&ImageManager::device_load_image, this, device, dscene, (ImageDataType)type, slot, &progress));
|
||||
pool.push(function_bind(&ImageManager::device_load_image,
|
||||
this,
|
||||
device,
|
||||
dscene,
|
||||
scene,
|
||||
(ImageDataType)type,
|
||||
slot,
|
||||
&progress));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -874,6 +944,7 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
|
||||
|
||||
void ImageManager::device_update_slot(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
int flat_slot,
|
||||
Progress *progress)
|
||||
{
|
||||
@ -890,6 +961,7 @@ void ImageManager::device_update_slot(Device *device,
|
||||
if(!osl_texture_system || image->builtin_data)
|
||||
device_load_image(device,
|
||||
dscene,
|
||||
scene,
|
||||
type,
|
||||
slot,
|
||||
progress);
|
||||
|
@ -30,6 +30,7 @@ CCL_NAMESPACE_BEGIN
|
||||
class Device;
|
||||
class DeviceScene;
|
||||
class Progress;
|
||||
class Scene;
|
||||
|
||||
class ImageManager {
|
||||
public:
|
||||
@ -67,8 +68,15 @@ public:
|
||||
ExtensionType extension);
|
||||
ImageDataType get_image_metadata(const string& filename, void *builtin_data, bool& is_linear);
|
||||
|
||||
void device_update(Device *device, DeviceScene *dscene, Progress& progress);
|
||||
void device_update_slot(Device *device, DeviceScene *dscene, int flat_slot, Progress *progress);
|
||||
void device_update(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
Progress& progress);
|
||||
void device_update_slot(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
int flat_slot,
|
||||
Progress *progress);
|
||||
void device_free(Device *device, DeviceScene *dscene);
|
||||
void device_free_builtin(Device *device, DeviceScene *dscene);
|
||||
|
||||
@ -78,9 +86,25 @@ public:
|
||||
|
||||
bool need_update;
|
||||
|
||||
function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &depth, int &channels)> builtin_image_info_cb;
|
||||
function<bool(const string &filename, void *data, unsigned char *pixels)> builtin_image_pixels_cb;
|
||||
function<bool(const string &filename, void *data, float *pixels)> builtin_image_float_pixels_cb;
|
||||
/* NOTE: Here pixels_size is a size of storage, which equals to
|
||||
* width * height * depth.
|
||||
* Use this to avoid some nasty memory corruptions.
|
||||
*/
|
||||
function<void(const string &filename,
|
||||
void *data,
|
||||
bool &is_float,
|
||||
int &width,
|
||||
int &height,
|
||||
int &depth,
|
||||
int &channels)> builtin_image_info_cb;
|
||||
function<bool(const string &filename,
|
||||
void *data,
|
||||
unsigned char *pixels,
|
||||
const size_t pixels_size)> builtin_image_pixels_cb;
|
||||
function<bool(const string &filename,
|
||||
void *data,
|
||||
float *pixels,
|
||||
const size_t pixels_size)> builtin_image_float_pixels_cb;
|
||||
|
||||
struct Image {
|
||||
string filename;
|
||||
@ -114,6 +138,7 @@ private:
|
||||
typename DeviceType>
|
||||
bool file_load_image(Image *img,
|
||||
ImageDataType type,
|
||||
int texture_limit,
|
||||
device_vector<DeviceType>& tex_img);
|
||||
|
||||
int type_index_to_flattened_slot(int slot, ImageDataType type);
|
||||
@ -122,10 +147,20 @@ private:
|
||||
|
||||
uint8_t pack_image_options(ImageDataType type, size_t slot);
|
||||
|
||||
void device_load_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot, Progress *progess);
|
||||
void device_free_image(Device *device, DeviceScene *dscene, ImageDataType type, int slot);
|
||||
void device_load_image(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
ImageDataType type,
|
||||
int slot,
|
||||
Progress *progess);
|
||||
void device_free_image(Device *device,
|
||||
DeviceScene *dscene,
|
||||
ImageDataType type,
|
||||
int slot);
|
||||
|
||||
void device_pack_images(Device *device, DeviceScene *dscene, Progress& progess);
|
||||
void device_pack_images(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Progress& progess);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -1084,7 +1084,7 @@ void MeshManager::update_svm_attributes(Device *device, DeviceScene *dscene, Sce
|
||||
}
|
||||
|
||||
/* terminator */
|
||||
for(int i = 0; i < ATTR_PRIM_TYPES; i++) {
|
||||
for(int j = 0; j < ATTR_PRIM_TYPES; j++) {
|
||||
attr_map[index].x = ATTR_STD_NONE;
|
||||
attr_map[index].y = 0;
|
||||
attr_map[index].z = 0;
|
||||
@ -1665,6 +1665,7 @@ void MeshManager::device_update_displacement_images(Device *device,
|
||||
*/
|
||||
image_manager->device_update(device,
|
||||
dscene,
|
||||
scene,
|
||||
progress);
|
||||
return;
|
||||
}
|
||||
@ -1682,6 +1683,7 @@ void MeshManager::device_update_displacement_images(Device *device,
|
||||
image_manager,
|
||||
device,
|
||||
dscene,
|
||||
scene,
|
||||
slot,
|
||||
&progress));
|
||||
}
|
||||
|
@ -3993,7 +3993,7 @@ NODE_DEFINE(SeparateRGBNode)
|
||||
|
||||
SOCKET_IN_COLOR(color, "Image", make_float3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
SOCKET_OUT_FLOAT(g, "R");
|
||||
SOCKET_OUT_FLOAT(r, "R");
|
||||
SOCKET_OUT_FLOAT(g, "G");
|
||||
SOCKET_OUT_FLOAT(b, "B");
|
||||
|
||||
|
@ -187,7 +187,7 @@ void Scene::device_update(Device *device_, Progress& progress)
|
||||
if(progress.get_cancel() || device->have_error()) return;
|
||||
|
||||
progress.set_status("Updating Images");
|
||||
image_manager->device_update(device, &dscene, progress);
|
||||
image_manager->device_update(device, &dscene, this, progress);
|
||||
|
||||
if(progress.get_cancel() || device->have_error()) return;
|
||||
|
||||
|
@ -145,6 +145,7 @@ public:
|
||||
bool use_bvh_unaligned_nodes;
|
||||
bool use_qbvh;
|
||||
bool persistent_data;
|
||||
int texture_limit;
|
||||
|
||||
SceneParams()
|
||||
{
|
||||
@ -154,6 +155,7 @@ public:
|
||||
use_bvh_unaligned_nodes = true;
|
||||
use_qbvh = false;
|
||||
persistent_data = false;
|
||||
texture_limit = 0;
|
||||
}
|
||||
|
||||
bool modified(const SceneParams& params)
|
||||
@ -162,7 +164,8 @@ public:
|
||||
&& use_bvh_spatial_split == params.use_bvh_spatial_split
|
||||
&& use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes
|
||||
&& use_qbvh == params.use_qbvh
|
||||
&& persistent_data == params.persistent_data); }
|
||||
&& persistent_data == params.persistent_data
|
||||
&& texture_limit == params.texture_limit); }
|
||||
};
|
||||
|
||||
/* Scene */
|
||||
|
@ -71,14 +71,13 @@ void SVMShaderManager::device_update_shader(Scene *scene,
|
||||
scene->light_manager->need_update = true;
|
||||
}
|
||||
|
||||
/* We only calculate offset and do re-allocation from the locked block,
|
||||
* actual copy we do after the lock is releases to hopefully gain some
|
||||
* percent of performance.
|
||||
/* The copy needs to be done inside the lock, if another thread resizes the array
|
||||
* while memcpy is running, it'll be copying into possibly invalid/freed ram.
|
||||
*/
|
||||
nodes_lock_.lock();
|
||||
size_t global_nodes_size = global_svm_nodes->size();
|
||||
global_svm_nodes->resize(global_nodes_size + svm_nodes.size());
|
||||
nodes_lock_.unlock();
|
||||
|
||||
/* Offset local SVM nodes to a global address space. */
|
||||
int4& jump_node = global_svm_nodes->at(shader->id);
|
||||
jump_node.y = svm_nodes[0].y + global_nodes_size - 1;
|
||||
@ -88,6 +87,7 @@ void SVMShaderManager::device_update_shader(Scene *scene,
|
||||
memcpy(&global_svm_nodes->at(global_nodes_size),
|
||||
&svm_nodes[1],
|
||||
sizeof(int4) * (svm_nodes.size() - 1));
|
||||
nodes_lock_.unlock();
|
||||
}
|
||||
|
||||
void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
|
||||
|
@ -45,6 +45,7 @@ set(SRC_HEADERS
|
||||
util_half.h
|
||||
util_hash.h
|
||||
util_image.h
|
||||
util_image_impl.h
|
||||
util_list.h
|
||||
util_logging.h
|
||||
util_map.h
|
||||
|
@ -21,11 +21,25 @@
|
||||
|
||||
#include <OpenImageIO/imageio.h>
|
||||
|
||||
#include "util_vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
OIIO_NAMESPACE_USING
|
||||
|
||||
template<typename T>
|
||||
void util_image_resize_pixels(const vector<T>& input_pixels,
|
||||
const size_t input_width,
|
||||
const size_t input_height,
|
||||
const size_t input_depth,
|
||||
const size_t components,
|
||||
vector<T> *output_pixels,
|
||||
size_t *output_width,
|
||||
size_t *output_height,
|
||||
size_t *output_depth);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __UTIL_IMAGE_H__ */
|
||||
|
||||
#include "util_image_impl.h"
|
||||
|
168
intern/cycles/util/util_image_impl.h
Normal file
168
intern/cycles/util/util_image_impl.h
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2011-2016 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_IMAGE_IMPL_H__
|
||||
#define __UTIL_IMAGE_IMPL_H__
|
||||
|
||||
#include "util_algorithm.h"
|
||||
#include "util_debug.h"
|
||||
#include "util_image.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T>
|
||||
const T *util_image_read(const vector<T>& pixels,
|
||||
const size_t width,
|
||||
const size_t height,
|
||||
const size_t /*depth*/,
|
||||
const size_t components,
|
||||
const size_t x, const size_t y, const size_t z) {
|
||||
const size_t index = ((size_t)z * (width * height) +
|
||||
(size_t)y * width +
|
||||
(size_t)x) * components;
|
||||
return &pixels[index];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void util_image_downscale_sample(const vector<T>& pixels,
|
||||
const size_t width,
|
||||
const size_t height,
|
||||
const size_t depth,
|
||||
const size_t components,
|
||||
const size_t kernel_size,
|
||||
const float x,
|
||||
const float y,
|
||||
const float z,
|
||||
T *result)
|
||||
{
|
||||
assert(components <= 4);
|
||||
const size_t ix = (size_t)x,
|
||||
iy = (size_t)y,
|
||||
iz = (size_t)z;
|
||||
/* TODO(sergey): Support something smarter than box filer. */
|
||||
float accum[4] = {0};
|
||||
size_t count = 0;
|
||||
for(size_t dz = 0; dz < kernel_size; ++dz) {
|
||||
for(size_t dy = 0; dy < kernel_size; ++dy) {
|
||||
for(size_t dx = 0; dx < kernel_size; ++dx) {
|
||||
const size_t nx = ix + dx,
|
||||
ny = iy + dy,
|
||||
nz = iz + dz;
|
||||
if(nx >= width || ny >= height || nz >= depth) {
|
||||
continue;
|
||||
}
|
||||
const T *pixel = util_image_read(pixels,
|
||||
width, height, depth,
|
||||
components,
|
||||
nx, ny, nz);
|
||||
for(size_t k = 0; k < components; ++k) {
|
||||
accum[k] += pixel[k];
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
const float inv_count = 1.0f / (float)count;
|
||||
for(size_t k = 0; k < components; ++k) {
|
||||
result[k] = T(accum[k] * inv_count);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void util_image_downscale_pixels(const vector<T>& input_pixels,
|
||||
const size_t input_width,
|
||||
const size_t input_height,
|
||||
const size_t input_depth,
|
||||
const size_t components,
|
||||
const float inv_scale_factor,
|
||||
const size_t output_width,
|
||||
const size_t output_height,
|
||||
const size_t output_depth,
|
||||
vector<T> *output_pixels)
|
||||
{
|
||||
const size_t kernel_size = (size_t)(inv_scale_factor + 0.5f);
|
||||
for(size_t z = 0; z < output_depth; ++z) {
|
||||
for(size_t y = 0; y < output_height; ++y) {
|
||||
for(size_t x = 0; x < output_width; ++x) {
|
||||
const float input_x = (float)x * inv_scale_factor,
|
||||
input_y = (float)y * inv_scale_factor,
|
||||
input_z = (float)z * inv_scale_factor;
|
||||
const size_t output_index =
|
||||
(z * output_width * output_height +
|
||||
y * output_width + x) * components;
|
||||
util_image_downscale_sample(input_pixels,
|
||||
input_width, input_height, input_depth,
|
||||
components,
|
||||
kernel_size,
|
||||
input_x, input_y, input_z,
|
||||
&output_pixels->at(output_index));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
template<typename T>
|
||||
void util_image_resize_pixels(const vector<T>& input_pixels,
|
||||
const size_t input_width,
|
||||
const size_t input_height,
|
||||
const size_t input_depth,
|
||||
const size_t components,
|
||||
const float scale_factor,
|
||||
vector<T> *output_pixels,
|
||||
size_t *output_width,
|
||||
size_t *output_height,
|
||||
size_t *output_depth)
|
||||
{
|
||||
/* Early output for case when no scaling is applied. */
|
||||
if(scale_factor == 1.0f) {
|
||||
*output_width = input_width;
|
||||
*output_height = input_height;
|
||||
*output_depth = input_depth;
|
||||
*output_pixels = input_pixels;
|
||||
return;
|
||||
}
|
||||
/* First of all, we calculate output image dimensions.
|
||||
* We clamp them to be 1 pixel at least so we do not generate degenerate
|
||||
* image.
|
||||
*/
|
||||
*output_width = max((size_t)((float)input_width * scale_factor), (size_t)1);
|
||||
*output_height = max((size_t)((float)input_height * scale_factor), (size_t)1);
|
||||
*output_depth = max((size_t)((float)input_depth * scale_factor), (size_t)1);
|
||||
/* Prepare pixel storage for the result. */
|
||||
const size_t num_output_pixels = ((*output_width) *
|
||||
(*output_height) *
|
||||
(*output_depth)) * components;
|
||||
output_pixels->resize(num_output_pixels);
|
||||
if(scale_factor < 1.0f) {
|
||||
const float inv_scale_factor = 1.0f / scale_factor;
|
||||
util_image_downscale_pixels(input_pixels,
|
||||
input_width, input_height, input_depth,
|
||||
components,
|
||||
inv_scale_factor,
|
||||
*output_width, *output_height, *output_depth,
|
||||
output_pixels);
|
||||
} else {
|
||||
/* TODO(sergey): Needs implementation. */
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __UTIL_IMAGE_IMPL_H__ */
|
@ -229,7 +229,7 @@ __forceinline int __btr(int v, int i) {
|
||||
int r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
|
||||
}
|
||||
|
||||
#if defined(__KERNEL_64_BIT__) || defined(__APPLE__)
|
||||
#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
|
||||
__forceinline size_t __bsf(size_t v) {
|
||||
size_t r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r;
|
||||
}
|
||||
@ -271,7 +271,7 @@ __forceinline unsigned int bitscan(unsigned int v) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__KERNEL_64_BIT__) || defined(__APPLE__)
|
||||
#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
|
||||
__forceinline size_t bitscan(size_t v) {
|
||||
#if defined(__KERNEL_AVX2__)
|
||||
#if defined(__KERNEL_64_BIT__)
|
||||
@ -313,7 +313,7 @@ __forceinline unsigned int __bscf(unsigned int& v)
|
||||
return i;
|
||||
}
|
||||
|
||||
#if defined(__KERNEL_64_BIT__) || defined(__APPLE__)
|
||||
#if (defined(__KERNEL_64_BIT__) || defined(__APPLE__)) && !(defined(__ILP32__) && defined(__x86_64__))
|
||||
__forceinline size_t __bscf(size_t& v)
|
||||
{
|
||||
size_t i = bitscan(v);
|
||||
|
@ -89,6 +89,22 @@ int system_cpu_thread_count()
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned short system_cpu_process_groups(unsigned short max_groups,
|
||||
unsigned short *groups)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
unsigned short group_count = max_groups;
|
||||
if(!GetProcessGroupAffinity(GetCurrentProcess(), &group_count, groups)) {
|
||||
return 0;
|
||||
}
|
||||
return group_count;
|
||||
#else
|
||||
(void) max_groups;
|
||||
(void) groups;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) || defined(FREE_WINDOWS)
|
||||
static void __cpuid(int data[4], int selector)
|
||||
{
|
||||
|
@ -30,6 +30,10 @@ int system_cpu_group_thread_count(int group);
|
||||
/* Get total number of threads in all groups. */
|
||||
int system_cpu_thread_count();
|
||||
|
||||
/* Get current process groups. */
|
||||
unsigned short system_cpu_process_groups(unsigned short max_groups,
|
||||
unsigned short *grpups);
|
||||
|
||||
string system_cpu_brand_string();
|
||||
int system_cpu_bits();
|
||||
bool system_cpu_support_sse2();
|
||||
|
@ -195,7 +195,8 @@ void TaskScheduler::init(int num_threads)
|
||||
if(users == 0) {
|
||||
do_exit = false;
|
||||
|
||||
if(num_threads == 0) {
|
||||
const bool use_auto_threads = (num_threads == 0);
|
||||
if(use_auto_threads) {
|
||||
/* automatic number of threads */
|
||||
num_threads = system_cpu_thread_count();
|
||||
}
|
||||
@ -204,7 +205,18 @@ void TaskScheduler::init(int num_threads)
|
||||
/* launch threads that will be waiting for work */
|
||||
threads.resize(num_threads);
|
||||
|
||||
int num_groups = system_cpu_group_count();
|
||||
const int num_groups = system_cpu_group_count();
|
||||
unsigned short num_process_groups;
|
||||
vector<unsigned short> process_groups;
|
||||
int current_group_threads;
|
||||
if(num_groups > 1) {
|
||||
process_groups.resize(num_groups);
|
||||
num_process_groups = system_cpu_process_groups(num_groups,
|
||||
&process_groups[0]);
|
||||
if(num_process_groups == 1) {
|
||||
current_group_threads = system_cpu_group_thread_count(process_groups[0]);
|
||||
}
|
||||
}
|
||||
int thread_index = 0;
|
||||
for(int group = 0; group < num_groups; ++group) {
|
||||
/* NOTE: That's not really efficient from threading point of view,
|
||||
@ -218,9 +230,25 @@ void TaskScheduler::init(int num_threads)
|
||||
group_thread < num_group_threads && thread_index < threads.size();
|
||||
++group_thread, ++thread_index)
|
||||
{
|
||||
/* NOTE: Thread group of -1 means we would not force thread affinity. */
|
||||
int thread_group;
|
||||
if(num_groups == 1) {
|
||||
/* Use default affinity if there's only one CPU group in the system. */
|
||||
thread_group = -1;
|
||||
}
|
||||
else if(use_auto_threads &&
|
||||
num_process_groups == 1 &&
|
||||
num_threads <= current_group_threads)
|
||||
{
|
||||
/* If we fit into curent CPU group we also don't force any affinity. */
|
||||
thread_group = -1;
|
||||
}
|
||||
else {
|
||||
thread_group = group;
|
||||
}
|
||||
threads[thread_index] = new thread(function_bind(&TaskScheduler::thread_run,
|
||||
thread_index + 1),
|
||||
group);
|
||||
thread_group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ CCL_NAMESPACE_BEGIN
|
||||
tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount;
|
||||
tGetActiveProcessorCount *GetActiveProcessorCount;
|
||||
tSetThreadGroupAffinity *SetThreadGroupAffinity;
|
||||
tGetProcessGroupAffinity *GetProcessGroupAffinity;
|
||||
#endif
|
||||
|
||||
static WORD GetActiveProcessorGroupCount_stub()
|
||||
@ -50,6 +51,18 @@ static BOOL SetThreadGroupAffinity_stub(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL GetProcessGroupAffinity_stub(HANDLE hProcess,
|
||||
PUSHORT GroupCount,
|
||||
PUSHORT GroupArray)
|
||||
{
|
||||
if(*GroupCount < 1) {
|
||||
return FALSE;
|
||||
}
|
||||
*GroupCount = 1;
|
||||
GroupArray[0] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool supports_numa()
|
||||
{
|
||||
#ifndef _M_X64
|
||||
@ -72,6 +85,7 @@ void util_windows_init_numa_groups()
|
||||
GetActiveProcessorGroupCount = GetActiveProcessorGroupCount_stub;
|
||||
GetActiveProcessorCount = GetActiveProcessorCount_stub;
|
||||
SetThreadGroupAffinity = SetThreadGroupAffinity_stub;
|
||||
GetProcessGroupAffinity = GetProcessGroupAffinity_stub;
|
||||
return;
|
||||
}
|
||||
HMODULE kernel = GetModuleHandleA("kernel32.dll");
|
||||
@ -79,6 +93,7 @@ void util_windows_init_numa_groups()
|
||||
READ_SYMBOL(GetActiveProcessorGroupCount);
|
||||
READ_SYMBOL(GetActiveProcessorCount);
|
||||
READ_SYMBOL(SetThreadGroupAffinity);
|
||||
READ_SYMBOL(GetProcessGroupAffinity);
|
||||
# undef READ_SUMBOL
|
||||
#endif
|
||||
}
|
||||
|
@ -39,10 +39,14 @@ typedef DWORD tGetActiveProcessorCount(WORD GroupNumber);
|
||||
typedef BOOL tSetThreadGroupAffinity(HANDLE hThread,
|
||||
const GROUP_AFFINITY *GroupAffinity,
|
||||
PGROUP_AFFINITY PreviousGroupAffinity);
|
||||
typedef BOOL tGetProcessGroupAffinity(HANDLE hProcess,
|
||||
PUSHORT GroupCount,
|
||||
PUSHORT GroupArray);
|
||||
|
||||
extern tGetActiveProcessorGroupCount *GetActiveProcessorGroupCount;
|
||||
extern tGetActiveProcessorCount *GetActiveProcessorCount;
|
||||
extern tSetThreadGroupAffinity *SetThreadGroupAffinity;
|
||||
extern tGetProcessGroupAffinity *GetProcessGroupAffinity;
|
||||
#endif
|
||||
|
||||
/* Make sure NUMA and processor groups API is initialized. */
|
||||
|
@ -353,7 +353,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
|
||||
// Release our reference of the DropTarget and it will delete itself eventually.
|
||||
m_dropTarget->Release();
|
||||
}
|
||||
|
||||
::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL);
|
||||
::DestroyWindow(m_hWnd);
|
||||
m_hWnd = 0;
|
||||
}
|
||||
|
@ -861,24 +861,32 @@ void GHOST_WindowX11::icccmSetState(int state)
|
||||
|
||||
int GHOST_WindowX11::icccmGetState(void) const
|
||||
{
|
||||
Atom *prop_ret;
|
||||
struct {
|
||||
CARD32 state;
|
||||
XID icon;
|
||||
} *prop_ret;
|
||||
unsigned long bytes_after, num_ret;
|
||||
Atom type_ret;
|
||||
int format_ret, st;
|
||||
int ret, format_ret;
|
||||
CARD32 st;
|
||||
|
||||
prop_ret = NULL;
|
||||
st = XGetWindowProperty(
|
||||
ret = XGetWindowProperty(
|
||||
m_display, m_window, m_system->m_atom.WM_STATE, 0, 2,
|
||||
False, m_system->m_atom.WM_STATE, &type_ret,
|
||||
&format_ret, &num_ret, &bytes_after, ((unsigned char **)&prop_ret));
|
||||
if ((st == Success) && (prop_ret) && (num_ret == 2))
|
||||
st = prop_ret[0];
|
||||
else
|
||||
if ((ret == Success) && (prop_ret != NULL) && (num_ret == 2)) {
|
||||
st = prop_ret->state;
|
||||
}
|
||||
else {
|
||||
st = NormalState;
|
||||
}
|
||||
|
||||
if (prop_ret)
|
||||
if (prop_ret) {
|
||||
XFree(prop_ret);
|
||||
return (st);
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
void GHOST_WindowX11::netwmMaximized(bool set)
|
||||
|
@ -77,7 +77,8 @@ int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr * /*config*/)
|
||||
return 2;
|
||||
}
|
||||
|
||||
const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, int index)
|
||||
const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
int index)
|
||||
{
|
||||
if (index == 0)
|
||||
return "Linear";
|
||||
@ -87,7 +88,8 @@ const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/, const char *name)
|
||||
OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
const char *name)
|
||||
{
|
||||
if (strcmp(name, "scene_linear") == 0)
|
||||
return COLORSPACE_LINEAR;
|
||||
@ -109,15 +111,17 @@ OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcP
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
|
||||
int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config,
|
||||
const char *name)
|
||||
{
|
||||
OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name);
|
||||
|
||||
if (cs == COLORSPACE_LINEAR)
|
||||
if (cs == COLORSPACE_LINEAR) {
|
||||
return 0;
|
||||
else if (cs == COLORSPACE_SRGB)
|
||||
}
|
||||
else if (cs == COLORSPACE_SRGB) {
|
||||
return 1;
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -131,44 +135,51 @@ int FallbackImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr * /*config*/)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/, int index)
|
||||
const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
int index)
|
||||
{
|
||||
if (index == 0)
|
||||
if (index == 0) {
|
||||
return "sRGB";
|
||||
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/)
|
||||
const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
const char * /*display*/)
|
||||
{
|
||||
return "Default";
|
||||
}
|
||||
|
||||
int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/)
|
||||
int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
const char * /*display*/)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/, int index)
|
||||
const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
const char * /*display*/, int index)
|
||||
{
|
||||
if (index == 0)
|
||||
if (index == 0) {
|
||||
return "Default";
|
||||
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/, const char * /*view*/)
|
||||
const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
const char * /*display*/,
|
||||
const char * /*view*/)
|
||||
{
|
||||
return "sRGB";
|
||||
}
|
||||
|
||||
void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/, float *rgb)
|
||||
void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
float *rgb)
|
||||
{
|
||||
/* Here we simply use the older Blender assumed primaries of
|
||||
* ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute
|
||||
* force stupid, but only plausible option given no color management
|
||||
* system in place.
|
||||
*/
|
||||
/* Here we simply use the older Blender assumed primaries of
|
||||
* ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute
|
||||
* force stupid, but only plausible option given no color management
|
||||
* system in place.
|
||||
*/
|
||||
|
||||
rgb[0] = 0.2126f;
|
||||
rgb[1] = 0.7152f;
|
||||
@ -180,12 +191,14 @@ int FallbackImpl::configGetNumLooks(OCIO_ConstConfigRcPtr * /*config*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, int /*index*/)
|
||||
const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
int /*index*/)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/, const char * /*name*/)
|
||||
OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
const char * /*name*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -213,25 +226,30 @@ void FallbackImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr * /*cs*/)
|
||||
{
|
||||
}
|
||||
|
||||
OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName)
|
||||
OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(
|
||||
OCIO_ConstConfigRcPtr *config,
|
||||
const char *srcName,
|
||||
const char *dstName)
|
||||
{
|
||||
OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
|
||||
OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
|
||||
|
||||
if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB)
|
||||
if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
|
||||
return PROCESSOR_LINEAR_TO_SRGB;
|
||||
else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR)
|
||||
}
|
||||
else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
|
||||
return PROCESSOR_SRGB_TO_LINEAR;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/, OCIO_ConstTransformRcPtr *tfm)
|
||||
OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/,
|
||||
OCIO_ConstTransformRcPtr *tfm)
|
||||
{
|
||||
return (OCIO_ConstProcessorRcPtr*)tfm;
|
||||
}
|
||||
|
||||
void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
|
||||
void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor,
|
||||
OCIO_PackedImageDesc *img)
|
||||
{
|
||||
/* OCIO_TODO stride not respected, channels must be 3 or 4 */
|
||||
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img;
|
||||
@ -253,7 +271,8 @@ void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_Pack
|
||||
}
|
||||
}
|
||||
|
||||
void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
|
||||
void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
|
||||
OCIO_PackedImageDesc *img)
|
||||
{
|
||||
/* OCIO_TODO stride not respected, channels must be 3 or 4 */
|
||||
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img;
|
||||
@ -275,15 +294,19 @@ void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
|
||||
}
|
||||
}
|
||||
|
||||
void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel)
|
||||
void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor,
|
||||
float *pixel)
|
||||
{
|
||||
if (processor == PROCESSOR_LINEAR_TO_SRGB)
|
||||
if (processor == PROCESSOR_LINEAR_TO_SRGB) {
|
||||
linearrgb_to_srgb_v3_v3(pixel, pixel);
|
||||
else if (processor == PROCESSOR_SRGB_TO_LINEAR)
|
||||
}
|
||||
else if (processor == PROCESSOR_SRGB_TO_LINEAR) {
|
||||
srgb_to_linearrgb_v3_v3(pixel, pixel);
|
||||
}
|
||||
}
|
||||
|
||||
void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel)
|
||||
void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor,
|
||||
float *pixel)
|
||||
{
|
||||
if (processor == PROCESSOR_LINEAR_TO_SRGB)
|
||||
linearrgb_to_srgb_v4(pixel, pixel);
|
||||
@ -291,7 +314,8 @@ void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float
|
||||
srgb_to_linearrgb_v4(pixel, pixel);
|
||||
}
|
||||
|
||||
void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel)
|
||||
void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor,
|
||||
float *pixel)
|
||||
{
|
||||
if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
|
||||
processorApplyRGBA(processor, pixel);
|
||||
@ -320,11 +344,12 @@ void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr * /*p*/)
|
||||
|
||||
const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
|
||||
{
|
||||
if (cs == COLORSPACE_LINEAR)
|
||||
if (cs == COLORSPACE_LINEAR) {
|
||||
return "Linear";
|
||||
else if (cs == COLORSPACE_SRGB)
|
||||
}
|
||||
else if (cs == COLORSPACE_SRGB) {
|
||||
return "sRGB";
|
||||
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -343,31 +368,38 @@ OCIO_DisplayTransformRcPtr *FallbackImpl::createDisplayTransform(void)
|
||||
return (OCIO_DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB;
|
||||
}
|
||||
|
||||
void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/)
|
||||
void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/,
|
||||
const char * /*name*/)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/)
|
||||
void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/,
|
||||
const char * /*name*/)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/)
|
||||
void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/,
|
||||
const char * /*name*/)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr * /*dt*/, OCIO_ConstTransformRcPtr * /*et*/)
|
||||
void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr * /*dt*/,
|
||||
OCIO_ConstTransformRcPtr * /*et*/)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr * /*dt*/, OCIO_ConstTransformRcPtr * /*et*/)
|
||||
void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr * /*dt*/,
|
||||
OCIO_ConstTransformRcPtr * /*et*/)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*looks*/)
|
||||
void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/,
|
||||
const char * /*looks*/)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/, bool /*enabled*/)
|
||||
void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/,
|
||||
bool /*enabled*/)
|
||||
{
|
||||
}
|
||||
|
||||
@ -375,11 +407,14 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr * /*dt*/)
|
||||
{
|
||||
}
|
||||
|
||||
OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
|
||||
long chanStrideBytes, long xStrideBytes, long yStrideBytes)
|
||||
OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(
|
||||
float *data,
|
||||
long width, long height, long numChannels,
|
||||
long chanStrideBytes, long xStrideBytes, long yStrideBytes)
|
||||
{
|
||||
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription");
|
||||
|
||||
OCIO_PackedImageDescription *desc =
|
||||
(OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription),
|
||||
"OCIO_PackedImageDescription");
|
||||
desc->data = data;
|
||||
desc->width = width;
|
||||
desc->height = height;
|
||||
@ -387,7 +422,6 @@ OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long
|
||||
desc->chanStrideBytes = chanStrideBytes;
|
||||
desc->xStrideBytes = xStrideBytes;
|
||||
desc->yStrideBytes = yStrideBytes;
|
||||
|
||||
return (OCIO_PackedImageDesc*)desc;
|
||||
}
|
||||
|
||||
@ -401,7 +435,8 @@ OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void)
|
||||
return (OCIO_ExponentTransformRcPtr*)PROCESSOR_UNKNOWN;
|
||||
}
|
||||
|
||||
void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr * /*et*/, const float * /*exponent*/)
|
||||
void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr * /*et*/,
|
||||
const float * /*exponent*/)
|
||||
{
|
||||
}
|
||||
|
||||
@ -414,7 +449,9 @@ OCIO_MatrixTransformRcPtr *FallbackImpl::createMatrixTransform(void)
|
||||
return (OCIO_MatrixTransformRcPtr*)PROCESSOR_UNKNOWN;
|
||||
}
|
||||
|
||||
void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr * /*mt*/, const float * /*m44*/, const float * /*offset4*/)
|
||||
void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr * /*mt*/,
|
||||
const float * /*m44*/,
|
||||
const float * /*offset4*/)
|
||||
{
|
||||
}
|
||||
|
||||
@ -422,7 +459,9 @@ void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr * /*mt*/)
|
||||
{
|
||||
}
|
||||
|
||||
void FallbackImpl::matrixTransformScale(float * /*m44*/, float * /*offset44*/, const float * /*scale4*/)
|
||||
void FallbackImpl::matrixTransformScale(float * /*m44*/,
|
||||
float * /*offset44*/,
|
||||
const float * /*scale4*/)
|
||||
{
|
||||
}
|
||||
|
||||
@ -431,9 +470,11 @@ bool FallbackImpl::supportGLSLDraw(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, OCIO_ConstProcessorRcPtr * /*processor*/,
|
||||
bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/,
|
||||
OCIO_ConstProcessorRcPtr * /*processor*/,
|
||||
OCIO_CurveMappingSettings * /*curve_mapping_settings*/,
|
||||
float /*dither*/, bool /*predivide*/)
|
||||
float /*dither*/,
|
||||
bool /*predivide*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -32,25 +32,24 @@ from bpy_extras import object_utils
|
||||
|
||||
def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
||||
from math import cos, sin, pi
|
||||
from mathutils import Vector, Quaternion
|
||||
from mathutils import Vector, Matrix
|
||||
|
||||
PI_2 = pi * 2.0
|
||||
z_axis = 0.0, 0.0, 1.0
|
||||
pi_2 = pi * 2.0
|
||||
|
||||
verts = []
|
||||
faces = []
|
||||
i1 = 0
|
||||
tot_verts = major_seg * minor_seg
|
||||
for major_index in range(major_seg):
|
||||
quat = Quaternion(z_axis, (major_index / major_seg) * PI_2)
|
||||
matrix = Matrix.Rotation((major_index / major_seg) * pi_2, 3, 'Z')
|
||||
|
||||
for minor_index in range(minor_seg):
|
||||
angle = 2 * pi * minor_index / minor_seg
|
||||
angle = pi_2 * minor_index / minor_seg
|
||||
|
||||
vec = quat * Vector((major_rad + (cos(angle) * minor_rad),
|
||||
0.0,
|
||||
(sin(angle) * minor_rad),
|
||||
))
|
||||
vec = matrix * Vector((major_rad + (cos(angle) * minor_rad),
|
||||
0.0,
|
||||
sin(angle) * minor_rad,
|
||||
))
|
||||
|
||||
verts.extend(vec[:])
|
||||
|
||||
@ -58,7 +57,6 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
||||
i2 = (major_index) * minor_seg
|
||||
i3 = i1 + minor_seg
|
||||
i4 = i2 + minor_seg
|
||||
|
||||
else:
|
||||
i2 = i1 + 1
|
||||
i3 = i1 + minor_seg
|
||||
@ -71,11 +69,7 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
||||
if i4 >= tot_verts:
|
||||
i4 = i4 - tot_verts
|
||||
|
||||
# stupid eekadoodle
|
||||
if i2:
|
||||
faces.extend([i1, i3, i4, i2])
|
||||
else:
|
||||
faces.extend([i2, i1, i3, i4])
|
||||
faces.extend([i1, i3, i4, i2])
|
||||
|
||||
i1 += 1
|
||||
|
||||
@ -83,31 +77,56 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
||||
|
||||
|
||||
def add_uvs(mesh, minor_seg, major_seg):
|
||||
from math import fmod
|
||||
|
||||
mesh.uv_textures.new()
|
||||
uv_data = mesh.uv_layers.active.data
|
||||
polygons = mesh.polygons
|
||||
u_step = 1.0 / major_seg
|
||||
v_step = 1.0 / minor_seg
|
||||
|
||||
# Round UV's, needed when segments aren't divisible by 4.
|
||||
u_init = 0.5 + fmod(0.5, u_step)
|
||||
v_init = 0.5 + fmod(0.5, v_step)
|
||||
|
||||
# Calculate wrapping value under 1.0 to prevent
|
||||
# float precision errors wrapping at the wrong step.
|
||||
u_wrap = 1.0 - (u_step / 2.0)
|
||||
v_wrap = 1.0 - (v_step / 2.0)
|
||||
|
||||
vertex_index = 0
|
||||
|
||||
u = 0.5
|
||||
u_prev = u_init
|
||||
u_next = u_prev + u_step
|
||||
for major_index in range(major_seg):
|
||||
v = 0.5
|
||||
v_prev = v_init
|
||||
v_next = v_prev + v_step
|
||||
for minor_index in range(minor_seg):
|
||||
loops = polygons[vertex_index].loop_indices
|
||||
if minor_index == minor_seg - 1 and major_index == 0:
|
||||
uv_data[loops[1]].uv = (u, v)
|
||||
uv_data[loops[2]].uv = (u + u_step, v)
|
||||
uv_data[loops[0]].uv = (u, v + v_step)
|
||||
uv_data[loops[3]].uv = (u + u_step, v + v_step)
|
||||
uv_data[loops[1]].uv = u_prev, v_prev
|
||||
uv_data[loops[2]].uv = u_next, v_prev
|
||||
uv_data[loops[0]].uv = u_prev, v_next
|
||||
uv_data[loops[3]].uv = u_next, v_next
|
||||
else:
|
||||
uv_data[loops[0]].uv = (u, v)
|
||||
uv_data[loops[1]].uv = (u + u_step, v)
|
||||
uv_data[loops[3]].uv = (u, v + v_step)
|
||||
uv_data[loops[2]].uv = (u + u_step, v + v_step)
|
||||
v = (v + v_step) % 1.0
|
||||
uv_data[loops[0]].uv = u_prev, v_prev
|
||||
uv_data[loops[1]].uv = u_next, v_prev
|
||||
uv_data[loops[3]].uv = u_prev, v_next
|
||||
uv_data[loops[2]].uv = u_next, v_next
|
||||
|
||||
if v_next > v_wrap:
|
||||
v_prev = v_next - 1.0
|
||||
else:
|
||||
v_prev = v_next
|
||||
v_next = v_prev + v_step
|
||||
|
||||
vertex_index += 1
|
||||
u = (u + u_step) % 1.0
|
||||
|
||||
if u_next > u_wrap:
|
||||
u_prev = u_next - 1.0
|
||||
else:
|
||||
u_prev = u_next
|
||||
u_next = u_prev + u_step
|
||||
|
||||
|
||||
class AddTorus(Operator, object_utils.AddObjectHelper):
|
||||
|
@ -428,6 +428,12 @@ class USERPREF_PT_system(Panel):
|
||||
|
||||
col.separator()
|
||||
|
||||
if bpy.app.build_options.cycles:
|
||||
addon = userpref.addons.get("cycles")
|
||||
if addon is not None:
|
||||
addon.preferences.draw_impl(col, context)
|
||||
del addon
|
||||
|
||||
if hasattr(system, "opensubdiv_compute_type"):
|
||||
col.label(text="OpenSubdiv compute:")
|
||||
col.row().prop(system, "opensubdiv_compute_type", text="")
|
||||
|
@ -138,11 +138,11 @@ void AbcCameraReader::readObjectData(Main *bmain, float time)
|
||||
bcam->stereo.convergence_distance = convergence_plane.getValue(sample_sel);
|
||||
}
|
||||
|
||||
const float lens = cam_sample.getFocalLength();
|
||||
const float apperture_x = cam_sample.getHorizontalAperture();
|
||||
const float apperture_y = cam_sample.getVerticalAperture();
|
||||
const float h_film_offset = cam_sample.getHorizontalFilmOffset();
|
||||
const float v_film_offset = cam_sample.getVerticalFilmOffset();
|
||||
const float lens = static_cast<float>(cam_sample.getFocalLength());
|
||||
const float apperture_x = static_cast<float>(cam_sample.getHorizontalAperture());
|
||||
const float apperture_y = static_cast<float>(cam_sample.getVerticalAperture());
|
||||
const float h_film_offset = static_cast<float>(cam_sample.getHorizontalFilmOffset());
|
||||
const float v_film_offset = static_cast<float>(cam_sample.getVerticalFilmOffset());
|
||||
const float film_aspect = apperture_x / apperture_y;
|
||||
|
||||
bcam->lens = lens;
|
||||
@ -150,10 +150,10 @@ void AbcCameraReader::readObjectData(Main *bmain, float time)
|
||||
bcam->sensor_y = apperture_y * 10;
|
||||
bcam->shiftx = h_film_offset / apperture_x;
|
||||
bcam->shifty = v_film_offset / apperture_y / film_aspect;
|
||||
bcam->clipsta = max_ff(0.1f, cam_sample.getNearClippingPlane());
|
||||
bcam->clipend = cam_sample.getFarClippingPlane();
|
||||
bcam->gpu_dof.focus_distance = cam_sample.getFocusDistance();
|
||||
bcam->gpu_dof.fstop = cam_sample.getFStop();
|
||||
bcam->clipsta = max_ff(0.1f, static_cast<float>(cam_sample.getNearClippingPlane()));
|
||||
bcam->clipend = static_cast<float>(cam_sample.getFarClippingPlane());
|
||||
bcam->gpu_dof.focus_distance = static_cast<float>(cam_sample.getFocusDistance());
|
||||
bcam->gpu_dof.fstop = static_cast<float>(cam_sample.getFStop());
|
||||
|
||||
m_object = BKE_object_add_only_object(bmain, OB_CAMERA, m_object_name.c_str());
|
||||
m_object->data = bcam;
|
||||
|
@ -361,7 +361,7 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
|
||||
* object directly and create a new DerivedMesh from that. Also we might need to
|
||||
* create new or delete existing NURBS in the curve.
|
||||
*/
|
||||
DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float time, int /*read_flag*/)
|
||||
DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float time, int /*read_flag*/, const char **/*err_str*/)
|
||||
{
|
||||
ISampleSelector sample_sel(time);
|
||||
const ICurvesSchema::Sample sample = m_curves_schema.getValue(sample_sel);
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
bool valid() const;
|
||||
|
||||
void readObjectData(Main *bmain, float time);
|
||||
DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int);
|
||||
DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int read_flag, const char **err_str);
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define __ABC_CUSTOMDATA_H__
|
||||
|
||||
#include <Alembic/Abc/All.h>
|
||||
#include <Alembic/AbcGeom/All.h>
|
||||
|
||||
struct CustomData;
|
||||
struct MLoop;
|
||||
@ -65,8 +66,8 @@ struct CDStreamConfig {
|
||||
|
||||
float weight;
|
||||
float time;
|
||||
int index;
|
||||
int ceil_index;
|
||||
Alembic::AbcGeom::index_t index;
|
||||
Alembic::AbcGeom::index_t ceil_index;
|
||||
|
||||
CDStreamConfig()
|
||||
: mloop(NULL)
|
||||
|
@ -175,13 +175,13 @@ void AbcExporter::getShutterSamples(double step, bool time_relative,
|
||||
|
||||
/* sample all frame */
|
||||
if (shutter_open == 0.0 && shutter_close == 1.0) {
|
||||
for (double t = 0; t < 1.0; t += step) {
|
||||
for (double t = 0.0; t < 1.0; t += step) {
|
||||
samples.push_back((t + m_settings.frame_start) / time_factor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* sample between shutter open & close */
|
||||
const int nsamples = std::max((1.0 / step) - 1.0, 1.0);
|
||||
const int nsamples = static_cast<int>(std::max((1.0 / step) - 1.0, 1.0));
|
||||
const double time_inc = (shutter_close - shutter_open) / nsamples;
|
||||
|
||||
for (double t = shutter_open; t <= shutter_close; t += time_inc) {
|
||||
@ -216,7 +216,7 @@ void AbcExporter::getFrameSet(double step, std::set<double> &frames)
|
||||
|
||||
getShutterSamples(step, false, shutter_samples);
|
||||
|
||||
for (int frame = m_settings.frame_start; frame <= m_settings.frame_end; ++frame) {
|
||||
for (double frame = m_settings.frame_start; frame <= m_settings.frame_end; frame += 1.0) {
|
||||
for (int j = 0, e = shutter_samples.size(); j < e; ++j) {
|
||||
frames.insert(frame + shutter_samples[j]);
|
||||
}
|
||||
@ -237,9 +237,9 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
|
||||
}
|
||||
|
||||
Scene *scene = m_scene;
|
||||
const int fps = FPS;
|
||||
const double fps = FPS;
|
||||
char buf[16];
|
||||
snprintf(buf, 15, "%d", fps);
|
||||
snprintf(buf, 15, "%f", fps);
|
||||
const std::string str_fps = buf;
|
||||
|
||||
Alembic::AbcCoreAbstract::MetaData md;
|
||||
@ -561,7 +561,7 @@ AbcTransformWriter *AbcExporter::getXForm(const std::string &name)
|
||||
|
||||
void AbcExporter::setCurrentFrame(Main *bmain, double t)
|
||||
{
|
||||
m_scene->r.cfra = std::floor(t);
|
||||
m_scene->r.subframe = t - m_scene->r.cfra;
|
||||
m_scene->r.cfra = static_cast<int>(t);
|
||||
m_scene->r.subframe = static_cast<float>(t) - m_scene->r.cfra;
|
||||
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, m_scene, m_scene->lay);
|
||||
}
|
||||
|
@ -868,53 +868,6 @@ ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings)
|
||||
: AbcObjectReader(object, settings)
|
||||
{
|
||||
m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
|
||||
|
||||
IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
|
||||
m_schema = ipoly_mesh.getSchema();
|
||||
|
||||
get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
|
||||
}
|
||||
|
||||
bool AbcMeshReader::valid() const
|
||||
{
|
||||
return m_schema.valid();
|
||||
}
|
||||
|
||||
void AbcMeshReader::readObjectData(Main *bmain, float time)
|
||||
{
|
||||
Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
|
||||
|
||||
m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
|
||||
m_object->data = mesh;
|
||||
|
||||
const ISampleSelector sample_sel(time);
|
||||
|
||||
DerivedMesh *dm = CDDM_from_mesh(mesh);
|
||||
DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL);
|
||||
|
||||
if (ndm != dm) {
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
|
||||
|
||||
if (m_settings->validate_meshes) {
|
||||
BKE_mesh_validate(mesh, false, false);
|
||||
}
|
||||
|
||||
readFaceSetsSample(bmain, mesh, 0, sample_sel);
|
||||
|
||||
if (has_animations(m_schema, m_settings)) {
|
||||
addCacheModifier();
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_smooth_poly_flag(DerivedMesh *dm)
|
||||
{
|
||||
MPoly *mpolys = dm->getPolyArray(dm);
|
||||
@ -962,6 +915,66 @@ static void *add_customdata_cb(void *user_data, const char *name, int data_type)
|
||||
return cd_ptr;
|
||||
}
|
||||
|
||||
static void get_weight_and_index(CDStreamConfig &config,
|
||||
Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling,
|
||||
size_t samples_number)
|
||||
{
|
||||
Alembic::AbcGeom::index_t i0, i1;
|
||||
|
||||
config.weight = get_weight_and_index(config.time,
|
||||
time_sampling,
|
||||
samples_number,
|
||||
i0,
|
||||
i1);
|
||||
|
||||
config.index = i0;
|
||||
config.ceil_index = i1;
|
||||
}
|
||||
|
||||
static void read_mesh_sample(ImportSettings *settings,
|
||||
const IPolyMeshSchema &schema,
|
||||
const ISampleSelector &selector,
|
||||
CDStreamConfig &config,
|
||||
bool &do_normals)
|
||||
{
|
||||
const IPolyMeshSchema::Sample sample = schema.getValue(selector);
|
||||
|
||||
AbcMeshData abc_mesh_data;
|
||||
abc_mesh_data.face_counts = sample.getFaceCounts();
|
||||
abc_mesh_data.face_indices = sample.getFaceIndices();
|
||||
abc_mesh_data.positions = sample.getPositions();
|
||||
|
||||
read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector);
|
||||
|
||||
do_normals = (abc_mesh_data.face_normals != NULL);
|
||||
|
||||
get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
|
||||
|
||||
if (config.weight != 0.0f) {
|
||||
Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample;
|
||||
schema.get(ceil_sample, Alembic::Abc::ISampleSelector(config.ceil_index));
|
||||
abc_mesh_data.ceil_positions = ceil_sample.getPositions();
|
||||
}
|
||||
|
||||
if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
|
||||
read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
|
||||
}
|
||||
|
||||
if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
|
||||
read_mverts(config, abc_mesh_data);
|
||||
}
|
||||
|
||||
if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
|
||||
read_mpolys(config, abc_mesh_data);
|
||||
}
|
||||
|
||||
if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
|
||||
read_custom_data(schema.getArbGeomParams(), config, selector);
|
||||
}
|
||||
|
||||
/* TODO: face sets */
|
||||
}
|
||||
|
||||
CDStreamConfig get_config(DerivedMesh *dm)
|
||||
{
|
||||
CDStreamConfig config;
|
||||
@ -978,7 +991,54 @@ CDStreamConfig get_config(DerivedMesh *dm)
|
||||
return config;
|
||||
}
|
||||
|
||||
DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag)
|
||||
/* ************************************************************************** */
|
||||
|
||||
AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings)
|
||||
: AbcObjectReader(object, settings)
|
||||
{
|
||||
m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
|
||||
|
||||
IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
|
||||
m_schema = ipoly_mesh.getSchema();
|
||||
|
||||
get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
|
||||
}
|
||||
|
||||
bool AbcMeshReader::valid() const
|
||||
{
|
||||
return m_schema.valid();
|
||||
}
|
||||
|
||||
void AbcMeshReader::readObjectData(Main *bmain, float time)
|
||||
{
|
||||
Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
|
||||
|
||||
m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
|
||||
m_object->data = mesh;
|
||||
|
||||
const ISampleSelector sample_sel(time);
|
||||
|
||||
DerivedMesh *dm = CDDM_from_mesh(mesh);
|
||||
DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL);
|
||||
|
||||
if (ndm != dm) {
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
|
||||
|
||||
if (m_settings->validate_meshes) {
|
||||
BKE_mesh_validate(mesh, false, false);
|
||||
}
|
||||
|
||||
readFaceSetsSample(bmain, mesh, 0, sample_sel);
|
||||
|
||||
if (has_animations(m_schema, m_settings)) {
|
||||
addCacheModifier();
|
||||
}
|
||||
}
|
||||
|
||||
DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
|
||||
{
|
||||
ISampleSelector sample_sel(time);
|
||||
const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel);
|
||||
@ -1003,6 +1063,21 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time,
|
||||
|
||||
settings.read_flag |= MOD_MESHSEQ_READ_ALL;
|
||||
}
|
||||
else {
|
||||
/* If the face count changed (e.g. by triangulation), only read points.
|
||||
* This prevents crash from T49813.
|
||||
* TODO(kevin): perhaps find a better way to do this? */
|
||||
if (face_counts->size() != dm->getNumPolys(dm) ||
|
||||
face_indices->size() != dm->getNumLoops(dm))
|
||||
{
|
||||
settings.read_flag = MOD_MESHSEQ_READ_VERT;
|
||||
|
||||
if (err_str) {
|
||||
*err_str = "Topology has changed, perhaps by triangulating the"
|
||||
" mesh. Only vertices will be read!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
|
||||
config.time = time;
|
||||
@ -1078,44 +1153,40 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star
|
||||
utils::assign_materials(bmain, m_object, mat_map);
|
||||
}
|
||||
|
||||
static void get_weight_and_index(CDStreamConfig &config,
|
||||
Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling,
|
||||
size_t samples_number)
|
||||
/* ************************************************************************** */
|
||||
|
||||
ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
|
||||
{
|
||||
Alembic::AbcGeom::index_t i0, i1;
|
||||
for (int i = 0, e = totedge; i < e; ++i) {
|
||||
MEdge &edge = edges[i];
|
||||
|
||||
config.weight = get_weight_and_index(config.time,
|
||||
time_sampling,
|
||||
samples_number,
|
||||
i0,
|
||||
i1);
|
||||
if (edge.v1 == v1 && edge.v2 == v2) {
|
||||
return &edge;
|
||||
}
|
||||
}
|
||||
|
||||
config.index = i0;
|
||||
config.ceil_index = i1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void read_mesh_sample(ImportSettings *settings,
|
||||
const IPolyMeshSchema &schema,
|
||||
const ISampleSelector &selector,
|
||||
CDStreamConfig &config,
|
||||
bool &do_normals)
|
||||
static void read_subd_sample(ImportSettings *settings,
|
||||
const ISubDSchema &schema,
|
||||
const ISampleSelector &selector,
|
||||
CDStreamConfig &config)
|
||||
{
|
||||
const IPolyMeshSchema::Sample sample = schema.getValue(selector);
|
||||
const ISubDSchema::Sample sample = schema.getValue(selector);
|
||||
|
||||
AbcMeshData abc_mesh_data;
|
||||
abc_mesh_data.face_counts = sample.getFaceCounts();
|
||||
abc_mesh_data.face_indices = sample.getFaceIndices();
|
||||
abc_mesh_data.vertex_normals = N3fArraySamplePtr();
|
||||
abc_mesh_data.face_normals = N3fArraySamplePtr();
|
||||
abc_mesh_data.positions = sample.getPositions();
|
||||
|
||||
read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector);
|
||||
|
||||
do_normals = (abc_mesh_data.face_normals != NULL);
|
||||
|
||||
get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
|
||||
|
||||
if (config.weight != 0.0f) {
|
||||
Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample;
|
||||
schema.get(ceil_sample, Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index)));
|
||||
Alembic::AbcGeom::ISubDSchema::Sample ceil_sample;
|
||||
schema.get(ceil_sample, Alembic::Abc::ISampleSelector(config.ceil_index));
|
||||
abc_mesh_data.ceil_positions = ceil_sample.getPositions();
|
||||
}
|
||||
|
||||
@ -1140,19 +1211,6 @@ void read_mesh_sample(ImportSettings *settings,
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
|
||||
{
|
||||
for (int i = 0, e = totedge; i < e; ++i) {
|
||||
MEdge &edge = edges[i];
|
||||
|
||||
if (edge.v1 == v1 && edge.v2 == v2) {
|
||||
return &edge;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AbcSubDReader::AbcSubDReader(const IObject &object, ImportSettings &settings)
|
||||
: AbcObjectReader(object, settings)
|
||||
{
|
||||
@ -1177,7 +1235,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float time)
|
||||
m_object->data = mesh;
|
||||
|
||||
DerivedMesh *dm = CDDM_from_mesh(mesh);
|
||||
DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL);
|
||||
DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL);
|
||||
|
||||
if (ndm != dm) {
|
||||
dm->release(dm);
|
||||
@ -1216,48 +1274,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float time)
|
||||
}
|
||||
}
|
||||
|
||||
void read_subd_sample(ImportSettings *settings,
|
||||
const ISubDSchema &schema,
|
||||
const ISampleSelector &selector,
|
||||
CDStreamConfig &config)
|
||||
{
|
||||
const ISubDSchema::Sample sample = schema.getValue(selector);
|
||||
|
||||
AbcMeshData abc_mesh_data;
|
||||
abc_mesh_data.face_counts = sample.getFaceCounts();
|
||||
abc_mesh_data.face_indices = sample.getFaceIndices();
|
||||
abc_mesh_data.vertex_normals = N3fArraySamplePtr();
|
||||
abc_mesh_data.face_normals = N3fArraySamplePtr();
|
||||
abc_mesh_data.positions = sample.getPositions();
|
||||
|
||||
get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
|
||||
|
||||
if (config.weight != 0.0f) {
|
||||
Alembic::AbcGeom::ISubDSchema::Sample ceil_sample;
|
||||
schema.get(ceil_sample, Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index)));
|
||||
abc_mesh_data.ceil_positions = ceil_sample.getPositions();
|
||||
}
|
||||
|
||||
if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
|
||||
read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
|
||||
}
|
||||
|
||||
if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
|
||||
read_mverts(config, abc_mesh_data);
|
||||
}
|
||||
|
||||
if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
|
||||
read_mpolys(config, abc_mesh_data);
|
||||
}
|
||||
|
||||
if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
|
||||
read_custom_data(schema.getArbGeomParams(), config, selector);
|
||||
}
|
||||
|
||||
/* TODO: face sets */
|
||||
}
|
||||
|
||||
DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag)
|
||||
DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
|
||||
{
|
||||
ISampleSelector sample_sel(time);
|
||||
const ISubDSchema::Sample sample = m_schema.getValue(sample_sel);
|
||||
@ -1281,6 +1298,21 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time,
|
||||
|
||||
settings.read_flag |= MOD_MESHSEQ_READ_ALL;
|
||||
}
|
||||
else {
|
||||
/* If the face count changed (e.g. by triangulation), only read points.
|
||||
* This prevents crash from T49813.
|
||||
* TODO(kevin): perhaps find a better way to do this? */
|
||||
if (face_counts->size() != dm->getNumPolys(dm) ||
|
||||
face_indices->size() != dm->getNumLoops(dm))
|
||||
{
|
||||
settings.read_flag = MOD_MESHSEQ_READ_VERT;
|
||||
|
||||
if (err_str) {
|
||||
*err_str = "Topology has changed, perhaps by triangulating the"
|
||||
" mesh. Only vertices will be read!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Only read point data when streaming meshes, unless we need to create new ones. */
|
||||
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
|
||||
|
@ -102,19 +102,13 @@ public:
|
||||
|
||||
void readObjectData(Main *bmain, float time);
|
||||
|
||||
DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag);
|
||||
DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
|
||||
|
||||
private:
|
||||
void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
|
||||
const Alembic::AbcGeom::ISampleSelector &sample_sel);
|
||||
};
|
||||
|
||||
void read_mesh_sample(ImportSettings *settings,
|
||||
const Alembic::AbcGeom::IPolyMeshSchema &schema,
|
||||
const Alembic::AbcGeom::ISampleSelector &selector,
|
||||
CDStreamConfig &config,
|
||||
bool &do_normals);
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
class AbcSubDReader : public AbcObjectReader {
|
||||
@ -128,14 +122,9 @@ public:
|
||||
bool valid() const;
|
||||
|
||||
void readObjectData(Main *bmain, float time);
|
||||
DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag);
|
||||
DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
|
||||
};
|
||||
|
||||
void read_subd_sample(ImportSettings *settings,
|
||||
const Alembic::AbcGeom::ISubDSchema &schema,
|
||||
const Alembic::AbcGeom::ISampleSelector &selector,
|
||||
CDStreamConfig &config);
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
void read_mverts(MVert *mverts,
|
||||
|
@ -170,13 +170,13 @@ static Imath::M44d blend_matrices(const Imath::M44d &m0, const Imath::M44d &m1,
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
mat0[i][j] = m0[i][j];
|
||||
mat0[i][j] = static_cast<float>(m0[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
mat1[i][j] = m1[i][j];
|
||||
mat1[i][j] = static_cast<float>(m1[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ private:
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
class CacheFile;
|
||||
struct CacheFile;
|
||||
|
||||
struct ImportSettings {
|
||||
bool do_convert_mat;
|
||||
@ -165,10 +165,11 @@ public:
|
||||
|
||||
virtual void readObjectData(Main *bmain, float time) = 0;
|
||||
|
||||
virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag)
|
||||
virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
|
||||
{
|
||||
(void)time;
|
||||
(void)read_flag;
|
||||
(void)err_str;
|
||||
return dm;
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ void AbcPointsReader::readObjectData(Main *bmain, float time)
|
||||
Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
|
||||
|
||||
DerivedMesh *dm = CDDM_from_mesh(mesh);
|
||||
DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0);
|
||||
DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0, NULL);
|
||||
|
||||
if (ndm != dm) {
|
||||
dm->release(dm);
|
||||
@ -191,7 +191,8 @@ void read_points_sample(const IPointsSchema &schema,
|
||||
N3fArraySamplePtr vnormals;
|
||||
|
||||
if (has_property(prop, "N")) {
|
||||
const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", time);
|
||||
const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(time);
|
||||
const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", itime);
|
||||
|
||||
if (normals_prop) {
|
||||
vnormals = normals_prop.getValue(selector);
|
||||
@ -201,7 +202,7 @@ void read_points_sample(const IPointsSchema &schema,
|
||||
read_mverts(config.mvert, positions, vnormals);
|
||||
}
|
||||
|
||||
DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time, int /*read_flag*/)
|
||||
DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time, int /*read_flag*/, const char **/*err_str*/)
|
||||
{
|
||||
ISampleSelector sample_sel(time);
|
||||
const IPointsSchema::Sample sample = m_schema.getValue(sample_sel);
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
|
||||
void readObjectData(Main *bmain, float time);
|
||||
|
||||
DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag);
|
||||
DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
|
||||
};
|
||||
|
||||
void read_points_sample(const Alembic::AbcGeom::IPointsSchema &schema,
|
||||
|
@ -92,8 +92,7 @@ void AbcTransformWriter::do_write()
|
||||
/* Only apply rotation to root camera, parenting will propagate it. */
|
||||
if (m_object->type == OB_CAMERA && !has_parent_camera(m_object)) {
|
||||
float rot_mat[4][4];
|
||||
unit_m4(rot_mat);
|
||||
rotate_m4(rot_mat, 'X', -M_PI_2);
|
||||
axis_angle_to_mat4_single(rot_mat, 'X', -M_PI_2);
|
||||
mul_m4_m4m4(mat, mat, rot_mat);
|
||||
}
|
||||
|
||||
|
@ -215,14 +215,13 @@ void convert_matrix(const Imath::M44d &xform, Object *ob,
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
r_mat[i][j] = xform[i][j];
|
||||
r_mat[i][j] = static_cast<float>(xform[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (ob->type == OB_CAMERA) {
|
||||
float cam_to_yup[4][4];
|
||||
unit_m4(cam_to_yup);
|
||||
rotate_m4(cam_to_yup, 'X', M_PI_2);
|
||||
axis_angle_to_mat4_single(cam_to_yup, 'X', M_PI_2);
|
||||
mul_m4_m4m4(r_mat, r_mat, cam_to_yup);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ struct CacheReader {
|
||||
using Alembic::Abc::chrono_t;
|
||||
|
||||
class AbcObjectReader;
|
||||
class ImportSettings;
|
||||
struct ImportSettings;
|
||||
|
||||
struct ID;
|
||||
struct Object;
|
||||
|
@ -625,8 +625,8 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
|
||||
CFRA = SFRA;
|
||||
}
|
||||
else if (min_time < max_time) {
|
||||
SFRA = min_time * FPS;
|
||||
EFRA = max_time * FPS;
|
||||
SFRA = static_cast<int>(min_time * FPS);
|
||||
EFRA = static_cast<int>(max_time * FPS);
|
||||
CFRA = SFRA;
|
||||
}
|
||||
}
|
||||
@ -816,7 +816,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return abc_reader->read_derivedmesh(dm, time, read_flag);
|
||||
return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
|
||||
}
|
||||
else if (ISubD::matches(header)) {
|
||||
if (ob->type != OB_MESH) {
|
||||
@ -824,7 +824,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return abc_reader->read_derivedmesh(dm, time, read_flag);
|
||||
return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
|
||||
}
|
||||
else if (IPoints::matches(header)) {
|
||||
if (ob->type != OB_MESH) {
|
||||
@ -832,7 +832,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return abc_reader->read_derivedmesh(dm, time, read_flag);
|
||||
return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
|
||||
}
|
||||
else if (ICurves::matches(header)) {
|
||||
if (ob->type != OB_CURVE) {
|
||||
@ -840,7 +840,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return abc_reader->read_derivedmesh(dm, time, read_flag);
|
||||
return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
|
||||
}
|
||||
|
||||
*err_str = "Unsupported object type: verify object path"; // or poke developer
|
||||
|
@ -73,7 +73,7 @@ struct AnimData *BKE_animdata_copy(struct AnimData *adt, const bool do_action);
|
||||
bool BKE_animdata_copy_id(struct ID *id_to, struct ID *id_from, const bool do_action);
|
||||
|
||||
/* Copy AnimData Actions */
|
||||
void BKE_animdata_copy_id_action(struct ID *id);
|
||||
void BKE_animdata_copy_id_action(struct ID *id, const bool set_newid);
|
||||
|
||||
/* Merge copies of data from source AnimData block */
|
||||
typedef enum eAnimData_MergeCopy_Modes {
|
||||
|
@ -120,7 +120,6 @@ void BKE_constraint_unique_name(struct bConstraint *con, struct ListBase *list);
|
||||
void BKE_constraints_free(struct ListBase *list);
|
||||
void BKE_constraints_free_ex(struct ListBase *list, bool do_id_user);
|
||||
void BKE_constraints_copy(struct ListBase *dst, const struct ListBase *src, bool do_extern);
|
||||
void BKE_constraints_relink(struct ListBase *list);
|
||||
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, void *userdata);
|
||||
void BKE_constraint_free_data(struct bConstraint *con);
|
||||
void BKE_constraint_free_data_ex(struct bConstraint *con, bool do_id_user);
|
||||
|
@ -80,6 +80,7 @@ void id_us_plus(struct ID *id);
|
||||
void id_us_min(struct ID *id);
|
||||
void id_fake_user_set(struct ID *id);
|
||||
void id_fake_user_clear(struct ID *id);
|
||||
void BKE_id_clear_newpoin(struct ID *id);
|
||||
|
||||
void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_in_mainlist, const bool lib_local);
|
||||
bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local);
|
||||
|
@ -307,17 +307,19 @@ bool BKE_animdata_copy_id(ID *id_to, ID *id_from, const bool do_action)
|
||||
return true;
|
||||
}
|
||||
|
||||
void BKE_animdata_copy_id_action(ID *id)
|
||||
void BKE_animdata_copy_id_action(ID *id, const bool set_newid)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
if (adt) {
|
||||
if (adt->action) {
|
||||
id_us_min((ID *)adt->action);
|
||||
adt->action = BKE_action_copy(G.main, adt->action);
|
||||
adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_action_copy(G.main, adt->action)) :
|
||||
BKE_action_copy(G.main, adt->action);
|
||||
}
|
||||
if (adt->tmpact) {
|
||||
id_us_min((ID *)adt->tmpact);
|
||||
adt->tmpact = BKE_action_copy(G.main, adt->tmpact);
|
||||
adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_action_copy(G.main, adt->tmpact)) :
|
||||
BKE_action_copy(G.main, adt->tmpact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -249,6 +249,9 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
|
||||
|
||||
brush_new->id.us = 0;
|
||||
|
||||
/* setting newid is mandatory for complex make_lib_local logic... */
|
||||
ID_NEW_SET(brush, brush_new);
|
||||
|
||||
if (!lib_local) {
|
||||
BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, const View3D *v3d, cons
|
||||
}
|
||||
else if (rv3d->persp == RV3D_ORTHO) {
|
||||
/* orthographic view */
|
||||
int sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
|
||||
float sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
|
||||
params->clipend *= 0.5f; // otherwise too extreme low zbuffer quality
|
||||
params->clipsta = -params->clipend;
|
||||
|
||||
@ -337,6 +337,8 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win
|
||||
viewplane.ymin *= pixsize;
|
||||
viewplane.ymax *= pixsize;
|
||||
|
||||
/* Used for rendering (offset by near-clip with perspective views), passed to RE_SetPixelSize.
|
||||
* For viewport drawing 'RegionView3D.pixsize'. */
|
||||
params->viewdx = pixsize;
|
||||
params->viewdy = params->ycor * pixsize;
|
||||
params->viewplane = viewplane;
|
||||
|
@ -4705,27 +4705,6 @@ bConstraint *BKE_constraint_add_for_object(Object *ob, const char *name, short t
|
||||
|
||||
/* ......... */
|
||||
|
||||
/* helper for BKE_constraints_relink() - call ID_NEW() on every ID reference the constraint has */
|
||||
static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, bool UNUSED(is_reference), void *UNUSED(userdata))
|
||||
{
|
||||
/* ID_NEW() expects a struct with inline "id" member as first
|
||||
* since we've got the actual ID block, let's just inline this
|
||||
* code.
|
||||
*
|
||||
* See ID_NEW(a) in DNA_ID.h
|
||||
*/
|
||||
if ((*idpoin) && (*idpoin)->newid)
|
||||
(*idpoin) = (void *)(*idpoin)->newid;
|
||||
}
|
||||
|
||||
/* Reassign links that constraints have to other data (called during file loading?) */
|
||||
void BKE_constraints_relink(ListBase *conlist)
|
||||
{
|
||||
/* just a wrapper around ID-loop for just calling ID_NEW() on all ID refs */
|
||||
BKE_constraints_id_loop(conlist, con_relink_id_cb, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Run the given callback on all ID-blocks in list of constraints */
|
||||
void BKE_constraints_id_loop(ListBase *conlist, ConstraintIDFunc func, void *userdata)
|
||||
{
|
||||
|
@ -1354,7 +1354,6 @@ static void scene_sort_groups(Main *bmain, Scene *sce)
|
||||
/* test; are group objects all in this scene? */
|
||||
for (ob = bmain->object.first; ob; ob = ob->id.next) {
|
||||
ob->id.tag &= ~LIB_TAG_DOIT;
|
||||
ob->id.newid = NULL; /* newid abuse for GroupObject */
|
||||
}
|
||||
for (base = sce->base.first; base; base = base->next)
|
||||
base->object->id.tag |= LIB_TAG_DOIT;
|
||||
@ -1385,6 +1384,11 @@ static void scene_sort_groups(Main *bmain, Scene *sce)
|
||||
group->gobject = listb;
|
||||
}
|
||||
}
|
||||
|
||||
/* newid abused for GroupObject, cleanup. */
|
||||
for (ob = bmain->object.first; ob; ob = ob->id.next) {
|
||||
ob->id.newid = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void dag_scene_tag_rebuild(Scene *sce)
|
||||
|
@ -382,7 +382,8 @@ bGPDpalette *BKE_gpencil_palette_addnew(bGPdata *gpd, const char *name, bool set
|
||||
sizeof(palette->info));
|
||||
|
||||
/* make this one the active one */
|
||||
if (setactive) {
|
||||
/* NOTE: Always make this active if there's nothing else yet (T50123) */
|
||||
if ((setactive) || (gpd->palettes.first == gpd->palettes.last)) {
|
||||
BKE_gpencil_palette_setactive(gpd, palette);
|
||||
}
|
||||
|
||||
@ -1264,6 +1265,10 @@ void BKE_gpencil_palettecolor_changename(bGPdata *gpd, char *oldname, const char
|
||||
bGPDframe *gpf;
|
||||
bGPDstroke *gps;
|
||||
|
||||
/* Sanity checks (gpd may not be set in the RNA pointers sometimes) */
|
||||
if (ELEM(NULL, gpd, oldname, newname))
|
||||
return;
|
||||
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
@ -1283,6 +1288,10 @@ void BKE_gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name)
|
||||
bGPDframe *gpf;
|
||||
bGPDstroke *gps, *gpsn;
|
||||
|
||||
/* Sanity checks (gpd may not be set in the RNA pointers sometimes) */
|
||||
if (ELEM(NULL, gpd, name))
|
||||
return;
|
||||
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (gps = gpf->strokes.first; gps; gps = gpsn) {
|
||||
|
@ -436,7 +436,6 @@ static void copy_image_packedfiles(ListBase *lb_dst, const ListBase *lb_src)
|
||||
Image *BKE_image_copy(Main *bmain, Image *ima)
|
||||
{
|
||||
Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type);
|
||||
ima->id.newid = &nima->id;
|
||||
|
||||
BLI_strncpy(nima->name, ima->name, sizeof(ima->name));
|
||||
|
||||
|
@ -262,6 +262,14 @@ void id_fake_user_clear(ID *id)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_id_clear_newpoin(ID *id)
|
||||
{
|
||||
if (id->newid) {
|
||||
id->newid->tag &= ~LIB_TAG_NEW;
|
||||
}
|
||||
id->newid = NULL;
|
||||
}
|
||||
|
||||
static int id_expand_local_callback(
|
||||
void *UNUSED(user_data), struct ID *id_self, struct ID **id_pointer, int UNUSED(cd_flag))
|
||||
{
|
||||
@ -325,6 +333,17 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c
|
||||
if (id_copy(bmain, id, &id_new, false)) {
|
||||
id_new->us = 0;
|
||||
|
||||
/* setting newid is mandatory for complex make_lib_local logic... */
|
||||
ID_NEW_SET(id, id_new);
|
||||
Key *key = BKE_key_from_id(id), *key_new = BKE_key_from_id(id);
|
||||
if (key && key_new) {
|
||||
ID_NEW_SET(key, key_new);
|
||||
}
|
||||
bNodeTree *ntree = ntreeFromID(id), *ntree_new = ntreeFromID(id_new);
|
||||
if (ntree && ntree_new) {
|
||||
ID_NEW_SET(ntree, ntree_new);
|
||||
}
|
||||
|
||||
if (!lib_local) {
|
||||
BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
}
|
||||
@ -336,6 +355,8 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c
|
||||
/**
|
||||
* Calls the appropriate make_local method for the block, unless test is set.
|
||||
*
|
||||
* \note Always set ID->newid pointer in case it gets duplicated...
|
||||
*
|
||||
* \param lib_local Special flag used when making a whole library's content local, it needs specific handling.
|
||||
*
|
||||
* \return true if the block can be made local.
|
||||
@ -554,6 +575,7 @@ bool id_copy(Main *bmain, ID *id, ID **newid, bool test)
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Does *not* set ID->newid pointer. */
|
||||
bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
ID *newid = NULL;
|
||||
@ -564,7 +586,7 @@ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
|
||||
if (RNA_property_editable(ptr, prop)) {
|
||||
if (id_copy(CTX_data_main(C), id, &newid, false) && newid) {
|
||||
/* copy animation actions too */
|
||||
BKE_animdata_copy_id_action(id);
|
||||
BKE_animdata_copy_id_action(id, false);
|
||||
/* us is 1 by convention, but RNA_property_pointer_set
|
||||
* will also increment it, so set it to zero */
|
||||
newid->us = 0;
|
||||
@ -1105,9 +1127,6 @@ void *BKE_libblock_copy(Main *bmain, ID *id)
|
||||
memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
|
||||
}
|
||||
|
||||
id->newid = idn;
|
||||
idn->tag |= LIB_TAG_NEW;
|
||||
|
||||
BKE_libblock_copy_data(idn, id, false);
|
||||
|
||||
return idn;
|
||||
@ -1131,8 +1150,6 @@ void *BKE_libblock_copy_nolib(ID *id, const bool do_action)
|
||||
memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
|
||||
}
|
||||
|
||||
id->newid = idn;
|
||||
idn->tag |= LIB_TAG_NEW;
|
||||
idn->us = 1;
|
||||
|
||||
BKE_libblock_copy_data(idn, id, do_action);
|
||||
@ -1646,7 +1663,6 @@ void BKE_library_make_local(
|
||||
const bool do_skip = (id && !BKE_idcode_is_linkable(GS(id->name)));
|
||||
|
||||
for (; id; id = id->next) {
|
||||
id->newid = NULL;
|
||||
id->tag &= ~LIB_TAG_DOIT;
|
||||
|
||||
if (id->lib == NULL) {
|
||||
@ -1846,6 +1862,7 @@ void BKE_library_make_local(
|
||||
}
|
||||
}
|
||||
|
||||
BKE_main_id_clear_newpoins(bmain);
|
||||
BLI_memarena_free(linklist_mem);
|
||||
}
|
||||
|
||||
|
@ -1052,6 +1052,9 @@ void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, con
|
||||
ob_new->id.us = 0;
|
||||
ob_new->proxy = ob_new->proxy_from = ob_new->proxy_group = NULL;
|
||||
|
||||
/* setting newid is mandatory for complex make_lib_local logic... */
|
||||
ID_NEW_SET(ob, ob_new);
|
||||
|
||||
if (!lib_local) {
|
||||
BKE_libblock_remap(bmain, ob, ob_new, ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
}
|
||||
@ -1185,6 +1188,9 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
|
||||
ob->data = target->data;
|
||||
id_us_plus((ID *)ob->data); /* ensures lib data becomes LIB_TAG_EXTERN */
|
||||
|
||||
/* copy vertex groups */
|
||||
defgroup_copy_list(&ob->defbase, &target->defbase);
|
||||
|
||||
/* copy material and index information */
|
||||
ob->actcol = ob->totcol = 0;
|
||||
if (ob->mat) MEM_freeN(ob->mat);
|
||||
|
@ -642,8 +642,7 @@ static void make_duplis_font(const DupliContext *ctx)
|
||||
float rmat[4][4];
|
||||
|
||||
zero_v3(obmat[3]);
|
||||
unit_m4(rmat);
|
||||
rotate_m4(rmat, 'Z', -ct->rot);
|
||||
axis_angle_to_mat4_single(rmat, 'Z', -ct->rot);
|
||||
mul_m4_m4m4(obmat, obmat, rmat);
|
||||
}
|
||||
|
||||
|
@ -220,8 +220,8 @@ RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob)
|
||||
/* preserve relationships between constraints and rigid bodies after duplication */
|
||||
void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc)
|
||||
{
|
||||
ID_NEW(rbc->ob1);
|
||||
ID_NEW(rbc->ob2);
|
||||
ID_NEW_REMAP(rbc->ob1);
|
||||
ID_NEW_REMAP(rbc->ob2);
|
||||
}
|
||||
|
||||
/* ************************************** */
|
||||
|
@ -602,41 +602,41 @@ void set_sca_new_poins_ob(Object *ob)
|
||||
if (act->flag & ACT_NEW) {
|
||||
if (act->type==ACT_EDIT_OBJECT) {
|
||||
bEditObjectActuator *eoa= act->data;
|
||||
ID_NEW(eoa->ob);
|
||||
ID_NEW_REMAP(eoa->ob);
|
||||
}
|
||||
else if (act->type==ACT_SCENE) {
|
||||
bSceneActuator *sca= act->data;
|
||||
ID_NEW(sca->camera);
|
||||
ID_NEW_REMAP(sca->camera);
|
||||
}
|
||||
else if (act->type==ACT_CAMERA) {
|
||||
bCameraActuator *ca= act->data;
|
||||
ID_NEW(ca->ob);
|
||||
ID_NEW_REMAP(ca->ob);
|
||||
}
|
||||
else if (act->type==ACT_OBJECT) {
|
||||
bObjectActuator *oa= act->data;
|
||||
ID_NEW(oa->reference);
|
||||
ID_NEW_REMAP(oa->reference);
|
||||
}
|
||||
else if (act->type==ACT_MESSAGE) {
|
||||
bMessageActuator *ma= act->data;
|
||||
ID_NEW(ma->toObject);
|
||||
ID_NEW_REMAP(ma->toObject);
|
||||
}
|
||||
else if (act->type==ACT_PARENT) {
|
||||
bParentActuator *para = act->data;
|
||||
ID_NEW(para->ob);
|
||||
ID_NEW_REMAP(para->ob);
|
||||
}
|
||||
else if (act->type==ACT_ARMATURE) {
|
||||
bArmatureActuator *aa = act->data;
|
||||
ID_NEW(aa->target);
|
||||
ID_NEW(aa->subtarget);
|
||||
ID_NEW_REMAP(aa->target);
|
||||
ID_NEW_REMAP(aa->subtarget);
|
||||
}
|
||||
else if (act->type==ACT_PROPERTY) {
|
||||
bPropertyActuator *pa= act->data;
|
||||
ID_NEW(pa->ob);
|
||||
ID_NEW_REMAP(pa->ob);
|
||||
}
|
||||
else if (act->type==ACT_STEERING) {
|
||||
bSteeringActuator *sta = act->data;
|
||||
ID_NEW(sta->navmesh);
|
||||
ID_NEW(sta->target);
|
||||
ID_NEW_REMAP(sta->navmesh);
|
||||
ID_NEW_REMAP(sta->target);
|
||||
}
|
||||
}
|
||||
act= act->next;
|
||||
|
@ -186,8 +186,6 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
||||
scen = BKE_libblock_copy(bmain, &sce->id);
|
||||
BLI_duplicatelist(&(scen->base), &(sce->base));
|
||||
|
||||
BKE_main_id_clear_newpoins(bmain);
|
||||
|
||||
id_us_plus((ID *)scen->world);
|
||||
id_us_plus((ID *)scen->set);
|
||||
/* id_us_plus((ID *)scen->gm.dome.warptext); */ /* XXX Not refcounted? see readfile.c */
|
||||
@ -225,7 +223,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
||||
}
|
||||
|
||||
/* copy action and remove animation used by sequencer */
|
||||
BKE_animdata_copy_id_action(&scen->id);
|
||||
BKE_animdata_copy_id_action(&scen->id, false);
|
||||
|
||||
if (type != SCE_COPY_FULL)
|
||||
remove_sequencer_fcurves(scen);
|
||||
@ -317,7 +315,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
||||
|
||||
/* camera */
|
||||
if (type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
|
||||
ID_NEW(scen->camera);
|
||||
ID_NEW_REMAP(scen->camera);
|
||||
}
|
||||
|
||||
/* before scene copy */
|
||||
@ -328,7 +326,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
||||
if (scen->world) {
|
||||
id_us_plus((ID *)scen->world);
|
||||
scen->world = BKE_world_copy(bmain, scen->world);
|
||||
BKE_animdata_copy_id_action((ID *)scen->world);
|
||||
BKE_animdata_copy_id_action((ID *)scen->world, false);
|
||||
}
|
||||
|
||||
if (sce->ed) {
|
||||
|
@ -320,7 +320,8 @@ void BKE_sequencer_free_clipboard(void)
|
||||
/* Manage pointers in the clipboard.
|
||||
* note that these pointers should _never_ be access in the sequencer,
|
||||
* they are only for storage while in the clipboard
|
||||
* notice 'newid' is used for temp pointer storage here, validate on access.
|
||||
* notice 'newid' is used for temp pointer storage here, validate on access (this is safe usage,
|
||||
* since those datablocks are fully out of Main lists).
|
||||
*/
|
||||
#define ID_PT (*id_pt)
|
||||
static void seqclipboard_ptr_free(ID **id_pt)
|
||||
|
@ -587,7 +587,7 @@ static void compensate_rotation_center(const int size, float aspect,
|
||||
|
||||
copy_v2_v2(intended_pivot, pivot);
|
||||
copy_v2_v2(rotated_pivot, pivot);
|
||||
rotate_m2(rotation_mat, +angle);
|
||||
angle_to_mat2(rotation_mat, +angle);
|
||||
sub_v2_v2(rotated_pivot, origin);
|
||||
mul_m2v2(rotation_mat, rotated_pivot);
|
||||
mul_v2_fl(rotated_pivot, scale);
|
||||
@ -967,7 +967,7 @@ static void initialize_track_for_stabilization(StabContext *ctx,
|
||||
|
||||
pos[0] *= aspect;
|
||||
angle = average_angle - atan2f(pos[1],pos[0]);
|
||||
rotate_m2(local_data->stabilization_rotation_base, angle);
|
||||
angle_to_mat2(local_data->stabilization_rotation_base, angle);
|
||||
|
||||
/* Per track baseline value for zoom. */
|
||||
len = len_v2(pos) + SCALE_ERROR_LIMIT_BIAS;
|
||||
|
@ -232,7 +232,6 @@ void mat4_to_size(float r[3], const float M[4][4]);
|
||||
|
||||
void translate_m4(float mat[4][4], float tx, float ty, float tz);
|
||||
void rotate_m4(float mat[4][4], const char axis, const float angle);
|
||||
void rotate_m2(float mat[2][2], const float angle);
|
||||
void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
|
||||
|
||||
void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3]);
|
||||
|
@ -122,8 +122,9 @@ void mat3_to_axis_angle(float axis[3], float *angle, float M[3][3]);
|
||||
void mat4_to_axis_angle(float axis[3], float *angle, float M[4][4]);
|
||||
void quat_to_axis_angle(float axis[3], float *angle, const float q[4]);
|
||||
|
||||
void axis_angle_to_mat3_single(float R[3][3], const char axis, const float angle);
|
||||
void angle_to_mat2(float R[2][2], const float angle);
|
||||
void axis_angle_to_mat3_single(float R[3][3], const char axis, const float angle);
|
||||
void axis_angle_to_mat4_single(float R[4][4], const char axis, const float angle);
|
||||
|
||||
void axis_angle_to_quat_single(float q[4], const char axis, const float angle);
|
||||
|
||||
|
@ -3917,10 +3917,9 @@ void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py
|
||||
float sine, cosine, hyp, hyp1, dx, dy, dz;
|
||||
float mat1[4][4];
|
||||
|
||||
unit_m4(mat);
|
||||
unit_m4(mat1);
|
||||
|
||||
rotate_m4(mat, 'Z', -twist);
|
||||
axis_angle_to_mat4_single(mat, 'Z', -twist);
|
||||
|
||||
dx = px - vx;
|
||||
dy = py - vy;
|
||||
|
@ -1681,53 +1681,47 @@ void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
|
||||
}
|
||||
|
||||
/* TODO: enum for axis? */
|
||||
/**
|
||||
* Rotate a matrix in-place.
|
||||
*
|
||||
* \note To create a new rotation matrix see:
|
||||
* #axis_angle_to_mat4_single, #axis_angle_to_mat3_single, #angle_to_mat2
|
||||
* (axis & angle args are compatible).
|
||||
*/
|
||||
void rotate_m4(float mat[4][4], const char axis, const float angle)
|
||||
{
|
||||
int col;
|
||||
float temp[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float cosine, sine;
|
||||
const float angle_cos = cosf(angle);
|
||||
const float angle_sin = sinf(angle);
|
||||
|
||||
assert(axis >= 'X' && axis <= 'Z');
|
||||
|
||||
cosine = cosf(angle);
|
||||
sine = sinf(angle);
|
||||
switch (axis) {
|
||||
case 'X':
|
||||
for (col = 0; col < 4; col++)
|
||||
temp[col] = cosine * mat[1][col] + sine * mat[2][col];
|
||||
for (col = 0; col < 4; col++) {
|
||||
mat[2][col] = -sine * mat[1][col] + cosine * mat[2][col];
|
||||
mat[1][col] = temp[col];
|
||||
for (int col = 0; col < 4; col++) {
|
||||
float temp = angle_cos * mat[1][col] + angle_sin * mat[2][col];
|
||||
mat[2][col] = -angle_sin * mat[1][col] + angle_cos * mat[2][col];
|
||||
mat[1][col] = temp;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
for (col = 0; col < 4; col++)
|
||||
temp[col] = cosine * mat[0][col] - sine * mat[2][col];
|
||||
for (col = 0; col < 4; col++) {
|
||||
mat[2][col] = sine * mat[0][col] + cosine * mat[2][col];
|
||||
mat[0][col] = temp[col];
|
||||
for (int col = 0; col < 4; col++) {
|
||||
float temp = angle_cos * mat[0][col] - angle_sin * mat[2][col];
|
||||
mat[2][col] = angle_sin * mat[0][col] + angle_cos * mat[2][col];
|
||||
mat[0][col] = temp;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
for (col = 0; col < 4; col++)
|
||||
temp[col] = cosine * mat[0][col] + sine * mat[1][col];
|
||||
for (col = 0; col < 4; col++) {
|
||||
mat[1][col] = -sine * mat[0][col] + cosine * mat[1][col];
|
||||
mat[0][col] = temp[col];
|
||||
for (int col = 0; col < 4; col++) {
|
||||
float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col];
|
||||
mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col];
|
||||
mat[0][col] = temp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rotate_m2(float mat[2][2], const float angle)
|
||||
{
|
||||
mat[0][0] = mat[1][1] = cosf(angle);
|
||||
mat[0][1] = sinf(angle);
|
||||
mat[1][0] = -mat[0][1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale or rotate around a pivot point,
|
||||
* a convenience function to avoid having to do inline.
|
||||
|
@ -1009,6 +1009,13 @@ void mat4_to_axis_angle(float axis[3], float *angle, float mat[4][4])
|
||||
quat_to_axis_angle(axis, angle, q);
|
||||
}
|
||||
|
||||
void axis_angle_to_mat4_single(float mat[4][4], const char axis, const float angle)
|
||||
{
|
||||
float mat3[3][3];
|
||||
axis_angle_to_mat3_single(mat3, axis, angle);
|
||||
copy_m4_m3(mat, mat3);
|
||||
}
|
||||
|
||||
/* rotation matrix from a single axis */
|
||||
void axis_angle_to_mat3_single(float mat[3][3], const char axis, const float angle)
|
||||
{
|
||||
|
@ -7706,6 +7706,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
|
||||
id->lib = main->curlib;
|
||||
id->us = ID_FAKE_USERS(id);
|
||||
id->icon_id = 0;
|
||||
id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
|
||||
|
||||
/* this case cannot be direct_linked: it's just the ID part */
|
||||
if (bhead->code == ID_ID) {
|
||||
|
@ -169,6 +169,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
|
||||
float angle;
|
||||
mat4_to_loc_rot_size(loc, rot, size, mat);
|
||||
mat3_to_vec_roll(rot, NULL, &angle);
|
||||
bone->roll = angle;
|
||||
}
|
||||
copy_v3_v3(bone->head, mat[3]);
|
||||
add_v3_v3v3(bone->tail, bone->head, tail); //tail must be non zero
|
||||
|
@ -33,11 +33,8 @@
|
||||
|
||||
UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP)
|
||||
{
|
||||
unit_m4(x_up_mat4);
|
||||
rotate_m4(x_up_mat4, 'Y', -0.5 * M_PI);
|
||||
|
||||
unit_m4(y_up_mat4);
|
||||
rotate_m4(y_up_mat4, 'X', 0.5 * M_PI);
|
||||
axis_angle_to_mat4_single(x_up_mat4, 'Y', -0.5 * M_PI);
|
||||
axis_angle_to_mat4_single(y_up_mat4, 'X', 0.5 * M_PI);
|
||||
|
||||
unit_m4(z_up_mat4);
|
||||
unit_m4(scale_mat4);
|
||||
|
@ -48,6 +48,8 @@
|
||||
|
||||
#include "util/deg_util_foreach.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace DEG {
|
||||
|
||||
string deg_fcurve_id_name(const FCurve *fcu)
|
||||
@ -153,8 +155,8 @@ void deg_graph_build_finalize(Depsgraph *graph)
|
||||
GHASH_FOREACH_END();
|
||||
|
||||
ID *id = id_node->id;
|
||||
if (id->tag & LIB_TAG_ID_RECALC_ALL &&
|
||||
id->tag & LIB_TAG_DOIT)
|
||||
if ((id->tag & LIB_TAG_ID_RECALC_ALL) &&
|
||||
(id->tag & LIB_TAG_DOIT))
|
||||
{
|
||||
id_node->tag_update(graph);
|
||||
id->tag &= ~LIB_TAG_DOIT;
|
||||
|
@ -370,19 +370,26 @@ SubgraphDepsNode *DepsgraphNodeBuilder::build_subgraph(Group *group)
|
||||
|
||||
void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
|
||||
{
|
||||
if (ob->id.tag & LIB_TAG_DOIT) {
|
||||
IDDepsNode *id_node = m_graph->find_id_node(&ob->id);
|
||||
if (base != NULL) {
|
||||
id_node->layers |= base->lay;
|
||||
}
|
||||
return;
|
||||
}
|
||||
ob->id.tag |= LIB_TAG_DOIT;
|
||||
|
||||
IDDepsNode *id_node = add_id_node(&ob->id);
|
||||
const bool has_object = (ob->id.tag & LIB_TAG_DOIT);
|
||||
IDDepsNode *id_node = (has_object)
|
||||
? m_graph->find_id_node(&ob->id)
|
||||
: add_id_node(&ob->id);
|
||||
/* Update node layers.
|
||||
* Do it for both new and existing ID nodes. This is so because several
|
||||
* bases might be sharing same object.
|
||||
*/
|
||||
if (base != NULL) {
|
||||
id_node->layers |= base->lay;
|
||||
}
|
||||
if (ob == scene->camera) {
|
||||
/* Camera should always be updated, it used directly by viewport. */
|
||||
id_node->layers |= (unsigned int)(-1);
|
||||
}
|
||||
/* Skip rest of components if the ID node was already there. */
|
||||
if (has_object) {
|
||||
return;
|
||||
}
|
||||
ob->id.tag |= LIB_TAG_DOIT;
|
||||
ob->customdata_mask = 0;
|
||||
|
||||
/* Standard components. */
|
||||
|
@ -189,16 +189,23 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
|
||||
/* Transforms props? */
|
||||
if (prop) {
|
||||
const char *prop_identifier = RNA_property_identifier((PropertyRNA *)prop);
|
||||
|
||||
/* TODO(sergey): How to optimize this? */
|
||||
if (strstr(prop_identifier, "location") ||
|
||||
strstr(prop_identifier, "rotation") ||
|
||||
strstr(prop_identifier, "scale"))
|
||||
strstr(prop_identifier, "scale") ||
|
||||
strstr(prop_identifier, "matrix_"))
|
||||
{
|
||||
*type = DEPSNODE_TYPE_TRANSFORM;
|
||||
return true;
|
||||
}
|
||||
else if (strstr(prop_identifier, "data")) {
|
||||
/* We access object.data, most likely a geometry.
|
||||
* Might be a bone tho..
|
||||
*/
|
||||
*type = DEPSNODE_TYPE_GEOMETRY;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ...
|
||||
}
|
||||
else if (ptr->type == &RNA_ShapeKey) {
|
||||
Key *key = (Key *)ptr->id.data;
|
||||
@ -371,8 +378,7 @@ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
|
||||
if (comp_node->type == DEPSNODE_TYPE_GEOMETRY) {
|
||||
IDDepsNode *id_to = to->owner->owner;
|
||||
IDDepsNode *id_from = from->owner->owner;
|
||||
Object *object_to = (Object *)id_to->id;
|
||||
if (id_to != id_from && (object_to->recalc & OB_RECALC_ALL)) {
|
||||
if (id_to != id_from && (id_to->id->tag & LIB_TAG_ID_RECALC_ALL)) {
|
||||
if ((id_from->eval_flags & DAG_EVAL_NEED_CPU) == 0) {
|
||||
id_from->tag_update(this);
|
||||
id_from->eval_flags |= DAG_EVAL_NEED_CPU;
|
||||
|
@ -96,6 +96,10 @@ static int gpencil_editmode_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
|
||||
/* Just toggle editmode flag... */
|
||||
gpd->flag ^= GP_DATA_STROKE_EDITMODE;
|
||||
/* recalculate parent matrix */
|
||||
if (gpd->flag & GP_DATA_STROKE_EDITMODE) {
|
||||
ED_gpencil_reset_layers_parent(gpd);
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, NULL);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
|
||||
|
@ -915,7 +915,7 @@ void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints)
|
||||
/**
|
||||
* Add randomness to stroke
|
||||
* \param gps Stroke data
|
||||
* \param brsuh Brush data
|
||||
* \param brush Brush data
|
||||
*/
|
||||
void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush)
|
||||
{
|
||||
@ -997,6 +997,46 @@ void ED_gpencil_parent_location(bGPDlayer *gpl, float diff_mat[4][4])
|
||||
}
|
||||
}
|
||||
|
||||
/* reset parent matrix for all layers */
|
||||
void ED_gpencil_reset_layers_parent(bGPdata *gpd)
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
float diff_mat[4][4];
|
||||
float cur_mat[4][4];
|
||||
|
||||
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
if (gpl->parent != NULL) {
|
||||
/* calculate new matrix */
|
||||
if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
|
||||
invert_m4_m4(cur_mat, gpl->parent->obmat);
|
||||
}
|
||||
else if (gpl->partype == PARBONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(gpl->parent->pose, gpl->parsubstr);
|
||||
if (pchan) {
|
||||
float tmp_mat[4][4];
|
||||
mul_m4_m4m4(tmp_mat, gpl->parent->obmat, pchan->pose_mat);
|
||||
invert_m4_m4(cur_mat, tmp_mat);
|
||||
}
|
||||
}
|
||||
|
||||
/* only redo if any change */
|
||||
if (!equals_m4m4(gpl->inverse, cur_mat)) {
|
||||
/* first apply current transformation to all strokes */
|
||||
ED_gpencil_parent_location(gpl, diff_mat);
|
||||
for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
|
||||
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
mul_m4_v3(diff_mat, &pt->x);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* set new parent matrix */
|
||||
copy_m4_m4(gpl->inverse, cur_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ******************************************************** */
|
||||
bool ED_gpencil_stroke_minmax(
|
||||
const bGPDstroke *gps, const bool use_select,
|
||||
|
@ -185,6 +185,8 @@ int ED_undo_gpencil_step(struct bContext *C, int step, const char *name);
|
||||
|
||||
/* get difference matrix using parent */
|
||||
void ED_gpencil_parent_location(struct bGPDlayer *gpl, float diff_mat[4][4]);
|
||||
/* reset parent matrix for all layers */
|
||||
void ED_gpencil_reset_layers_parent(struct bGPdata *gpd);
|
||||
|
||||
|
||||
#endif /* __ED_GPENCIL_H__ */
|
||||
|
@ -1005,15 +1005,6 @@ DEF_ICON(MATCAP_23)
|
||||
DEF_ICON(MATCAP_24)
|
||||
|
||||
/* vector icons, VICO_ prefix added */
|
||||
DEF_VICO(VIEW3D_VEC)
|
||||
DEF_VICO(EDIT_VEC)
|
||||
DEF_VICO(EDITMODE_VEC_DEHLT)
|
||||
DEF_VICO(EDITMODE_VEC_HLT)
|
||||
DEF_VICO(DISCLOSURE_TRI_RIGHT_VEC)
|
||||
DEF_VICO(DISCLOSURE_TRI_DOWN_VEC)
|
||||
DEF_VICO(MOVE_UP_VEC)
|
||||
DEF_VICO(MOVE_DOWN_VEC)
|
||||
DEF_VICO(X_VEC)
|
||||
DEF_VICO(SMALL_TRI_RIGHT_VEC)
|
||||
|
||||
DEF_VICO(KEYTYPE_KEYFRAME_VEC)
|
||||
|
@ -181,7 +181,7 @@ enum {
|
||||
UI_BUT_HAS_SEP_CHAR = (1 << 27), /* but->str contains UI_SEP_CHAR, used for key shortcuts */
|
||||
UI_BUT_UPDATE_DELAY = (1 << 28), /* don't run updates while dragging (needed in rare cases). */
|
||||
UI_BUT_TEXTEDIT_UPDATE = (1 << 29), /* when widget is in textedit mode, update value on each char stroke */
|
||||
UI_BUT_SEARCH_UNLINK = (1 << 30), /* show unlink for search button */
|
||||
UI_BUT_VALUE_CLEAR = (1 << 30), /* show 'x' icon to clear/unlink value of text or search button */
|
||||
};
|
||||
|
||||
#define UI_PANEL_WIDTH 340
|
||||
|
@ -1987,22 +1987,29 @@ uiBut *ui_but_drag_multi_edit_get(uiBut *but)
|
||||
/** \name Check to show extra icons
|
||||
*
|
||||
* Extra icons are shown on the right hand side of buttons.
|
||||
* This could (should!) definitely become more generic, but for now this is good enough.
|
||||
* \{ */
|
||||
|
||||
static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but)
|
||||
{
|
||||
BLI_assert(but->type == UI_BTYPE_TEXT);
|
||||
return ((but->flag & UI_BUT_VALUE_CLEAR) && but->drawstr && but->drawstr[0]);
|
||||
}
|
||||
|
||||
static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but)
|
||||
{
|
||||
BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
|
||||
return ((but->editstr == NULL) &&
|
||||
(but->drawstr[0] != '\0') &&
|
||||
(but->flag & UI_BUT_SEARCH_UNLINK));
|
||||
(but->flag & UI_BUT_VALUE_CLEAR));
|
||||
}
|
||||
|
||||
static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but)
|
||||
static bool ui_but_icon_extra_is_visible_search_eyedropper(uiBut *but)
|
||||
{
|
||||
StructRNA *type;
|
||||
short idcode;
|
||||
|
||||
BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_SEARCH_UNLINK));
|
||||
BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_VALUE_CLEAR));
|
||||
|
||||
if (but->rnaprop == NULL) {
|
||||
return false;
|
||||
@ -2011,21 +2018,31 @@ static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but)
|
||||
type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
|
||||
idcode = RNA_type_to_ID_code(type);
|
||||
|
||||
|
||||
return ((but->editstr == NULL) &&
|
||||
(idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode)));
|
||||
}
|
||||
|
||||
uiButExtraIconType ui_but_icon_extra_get(uiBut *but)
|
||||
{
|
||||
if ((but->flag & UI_BUT_SEARCH_UNLINK) == 0) {
|
||||
/* pass */
|
||||
}
|
||||
else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
|
||||
return UI_BUT_ICONEXTRA_UNLINK;
|
||||
}
|
||||
else if (ui_but_icon_extra_is_visible_eyedropper(but)) {
|
||||
return UI_BUT_ICONEXTRA_EYEDROPPER;
|
||||
switch (but->type) {
|
||||
case UI_BTYPE_TEXT:
|
||||
if (ui_but_icon_extra_is_visible_text_clear(but)) {
|
||||
return UI_BUT_ICONEXTRA_CLEAR;
|
||||
}
|
||||
break;
|
||||
case UI_BTYPE_SEARCH_MENU:
|
||||
if ((but->flag & UI_BUT_VALUE_CLEAR) == 0) {
|
||||
/* pass */
|
||||
}
|
||||
else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
|
||||
return UI_BUT_ICONEXTRA_CLEAR;
|
||||
}
|
||||
else if (ui_but_icon_extra_is_visible_search_eyedropper(but)) {
|
||||
return UI_BUT_ICONEXTRA_EYEDROPPER;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return UI_BUT_ICONEXTRA_NONE;
|
||||
|
@ -748,7 +748,7 @@ static int datadropper_poll(bContext *C)
|
||||
if ((CTX_wm_window(C) != NULL) &&
|
||||
(but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
|
||||
(but->type == UI_BTYPE_SEARCH_MENU) &&
|
||||
(but->flag & UI_BUT_SEARCH_UNLINK))
|
||||
(but->flag & UI_BUT_VALUE_CLEAR))
|
||||
{
|
||||
if (prop && RNA_property_type(prop) == PROP_POINTER) {
|
||||
StructRNA *type = RNA_property_pointer_type(&ptr, prop);
|
||||
|
@ -2554,6 +2554,18 @@ void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *bu
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_but_text_clear(bContext *C, uiBut *but, uiHandleButtonData *data)
|
||||
{
|
||||
/* most likely NULL, but let's check, and give it temp zero string */
|
||||
if (!data->str) {
|
||||
data->str = MEM_callocN(1, "temp str");
|
||||
}
|
||||
data->str[0] = 0;
|
||||
|
||||
ui_apply_but_TEX(C, but, data);
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
|
||||
|
||||
/* ************* in-button text selection/editing ************* */
|
||||
|
||||
@ -3820,6 +3832,21 @@ static int ui_do_but_KEYEVT(
|
||||
return WM_UI_HANDLER_CONTINUE;
|
||||
}
|
||||
|
||||
static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, const int mouse_xy[2])
|
||||
{
|
||||
int x = mouse_xy[0], y = mouse_xy[1];
|
||||
rcti icon_rect;
|
||||
|
||||
BLI_assert(ui_but_icon_extra_get(but) != UI_BUT_ICONEXTRA_NONE);
|
||||
|
||||
ui_window_to_block(region, but->block, &x, &y);
|
||||
|
||||
BLI_rcti_rctf_copy(&icon_rect, &but->rect);
|
||||
icon_rect.xmin = icon_rect.xmax - (BLI_rcti_size_y(&icon_rect));
|
||||
|
||||
return BLI_rcti_isect_pt(&icon_rect, x, y);
|
||||
}
|
||||
|
||||
static int ui_do_but_TEX(
|
||||
bContext *C, uiBlock *block, uiBut *but,
|
||||
uiHandleButtonData *data, const wmEvent *event)
|
||||
@ -3833,7 +3860,14 @@ static int ui_do_but_TEX(
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR;
|
||||
|
||||
if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) {
|
||||
ui_but_text_clear(C, but, data);
|
||||
}
|
||||
else {
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
}
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
@ -3854,47 +3888,29 @@ static int ui_do_but_SEARCH_UNLINK(
|
||||
bContext *C, uiBlock *block, uiBut *but,
|
||||
uiHandleButtonData *data, const wmEvent *event)
|
||||
{
|
||||
uiButExtraIconType extra_icon_type;
|
||||
const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
|
||||
const bool has_icon_extra = (extra_icon_type != UI_BUT_ICONEXTRA_NONE);
|
||||
|
||||
/* unlink icon is on right */
|
||||
if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) &&
|
||||
((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
|
||||
(has_icon_extra == true) &&
|
||||
(ui_but_is_mouse_over_icon_extra(data->region, but, &event->x) == true))
|
||||
{
|
||||
ARegion *ar = data->region;
|
||||
rcti rect;
|
||||
int x = event->x, y = event->y;
|
||||
|
||||
ui_window_to_block(ar, but->block, &x, &y);
|
||||
|
||||
BLI_rcti_rctf_copy(&rect, &but->rect);
|
||||
|
||||
rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
|
||||
/* handle click on unlink/eyedropper icon */
|
||||
if (BLI_rcti_isect_pt(&rect, x, y)) {
|
||||
/* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
|
||||
if (event->val == KM_RELEASE) {
|
||||
/* unlink */
|
||||
if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
|
||||
/* most likely NULL, but let's check, and give it temp zero string */
|
||||
if (data->str == NULL) {
|
||||
data->str = MEM_callocN(1, "temp str");
|
||||
}
|
||||
data->str[0] = 0;
|
||||
|
||||
ui_apply_but_TEX(C, but, data);
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
/* eyedropper */
|
||||
else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
|
||||
WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
/* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
|
||||
if (event->val == KM_RELEASE) {
|
||||
/* unlink */
|
||||
if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
|
||||
ui_but_text_clear(C, but, data);
|
||||
}
|
||||
/* eyedropper */
|
||||
else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
|
||||
WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
return ui_do_but_TEX(C, block, but, data, event);
|
||||
}
|
||||
@ -7069,7 +7085,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
|
||||
case UI_BTYPE_TEXT:
|
||||
case UI_BTYPE_SEARCH_MENU:
|
||||
if ((but->type == UI_BTYPE_SEARCH_MENU) &&
|
||||
(but->flag & UI_BUT_SEARCH_UNLINK))
|
||||
(but->flag & UI_BUT_VALUE_CLEAR))
|
||||
{
|
||||
retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
|
||||
if (retval & WM_UI_HANDLER_BREAK) {
|
||||
|
@ -127,7 +127,7 @@ enum {
|
||||
* (e.g. 'x' icon in search menu) - used with ui_but_icon_extra_get */
|
||||
typedef enum uiButExtraIconType {
|
||||
UI_BUT_ICONEXTRA_NONE = 1,
|
||||
UI_BUT_ICONEXTRA_UNLINK,
|
||||
UI_BUT_ICONEXTRA_CLEAR,
|
||||
UI_BUT_ICONEXTRA_EYEDROPPER,
|
||||
} uiButExtraIconType;
|
||||
|
||||
|
@ -1659,7 +1659,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
|
||||
but->rnasearchprop = searchprop;
|
||||
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
|
||||
if (RNA_property_is_unlink(prop)) {
|
||||
but->flag |= UI_BUT_SEARCH_UNLINK;
|
||||
but->flag |= UI_BUT_VALUE_CLEAR;
|
||||
}
|
||||
|
||||
if (RNA_property_type(prop) == PROP_ENUM) {
|
||||
|
@ -851,7 +851,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
|
||||
}
|
||||
else {
|
||||
/* only let users step into an 'unset' state for unlink buttons */
|
||||
data->active = (but->flag & UI_BUT_SEARCH_UNLINK) ? -1 : 0;
|
||||
data->active = (but->flag & UI_BUT_VALUE_CLEAR) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -922,8 +922,8 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (but->flag & UI_BUT_SEARCH_UNLINK) {
|
||||
/* It is valid for _UNLINK flavor to have no active element (it's a valid way to unlink). */
|
||||
else if (but->flag & UI_BUT_VALUE_CLEAR) {
|
||||
/* It is valid for _VALUE_CLEAR flavor to have no active element (it's a valid way to unlink). */
|
||||
but->editstr[0] = '\0';
|
||||
|
||||
return true;
|
||||
|
@ -302,7 +302,10 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
|
||||
break;
|
||||
case UI_ID_LOCAL:
|
||||
if (id) {
|
||||
if (id_make_local(CTX_data_main(C), id, false, false)) {
|
||||
Main *bmain = CTX_data_main(C);
|
||||
if (id_make_local(bmain, id, false, false)) {
|
||||
BKE_main_id_clear_newpoins(bmain);
|
||||
|
||||
/* reassign to get get proper updates/notifiers */
|
||||
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
|
||||
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
|
||||
|
@ -119,6 +119,10 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
|
||||
else
|
||||
but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
|
||||
|
||||
PropertySubType subtype = RNA_property_subtype(prop);
|
||||
if (!(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME) || (block->flag & UI_BLOCK_LIST_ITEM))) {
|
||||
UI_but_flag_enable(but, UI_BUT_VALUE_CLEAR);
|
||||
}
|
||||
if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
|
||||
UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
|
||||
}
|
||||
|
@ -1513,10 +1513,10 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
|
||||
/* draws text and icons for buttons */
|
||||
static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
|
||||
{
|
||||
const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
|
||||
const bool show_menu_icon = ui_but_draw_menu_icon(but);
|
||||
float alpha = (float)wcol->text[3] / 255.0f;
|
||||
char password_str[UI_MAX_DRAW_STR];
|
||||
uiButExtraIconType extra_icon_type;
|
||||
|
||||
ui_but_text_password_hide(password_str, but, false);
|
||||
|
||||
@ -1582,15 +1582,13 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
|
||||
rect->xmax -= (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
|
||||
}
|
||||
|
||||
/* unlink icon for this button type */
|
||||
if ((but->type == UI_BTYPE_SEARCH_MENU) &&
|
||||
((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
|
||||
{
|
||||
/* extra icons, e.g. 'x' icon to clear text or icon for eyedropper */
|
||||
if (extra_icon_type != UI_BUT_ICONEXTRA_NONE) {
|
||||
rcti temp = *rect;
|
||||
|
||||
temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
|
||||
|
||||
if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
|
||||
if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
|
||||
widget_draw_icon(but, ICON_X, alpha, &temp, false);
|
||||
}
|
||||
else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
|
||||
|
@ -2140,7 +2140,7 @@ static float snap_v2_angle(float r[2], const float v[2], const float v_ref[2], f
|
||||
normalize_v2_v2(v_unit, v);
|
||||
angle = angle_signed_v2v2(v_unit, v_ref);
|
||||
angle_delta = (roundf(angle / angle_snap) * angle_snap) - angle;
|
||||
rotate_m2(m2, angle_delta);
|
||||
angle_to_mat2(m2, angle_delta);
|
||||
|
||||
mul_v2_m2v2(r, m2, v);
|
||||
return angle + angle_delta;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user