Compare commits
393 Commits
uiTable
...
render-lay
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cf64c69c5f | ||
![]() |
bccea8d399 | ||
![]() |
f4ebb35a73 | ||
![]() |
698c29aa40 | ||
![]() |
d4eace7479 | ||
![]() |
73bb3d4d77 | ||
![]() |
6714f6ae2f | ||
e58359c26f | |||
8dbd961a3e | |||
![]() |
cb3daaf355 | ||
6d4f75a123 | |||
c3e2faaad5 | |||
5ad5bb235b | |||
5908382011 | |||
627566cb9a | |||
![]() |
0412b0d296 | ||
71c8db2a0c | |||
![]() |
1e69c9e1c8 | ||
![]() |
16385ae285 | ||
![]() |
2b04710d61 | ||
![]() |
35fb0e341b | ||
![]() |
83fea5307b | ||
![]() |
6644ff25f2 | ||
![]() |
7f2da487a6 | ||
520ced4ad5 | |||
41ba828131 | |||
![]() |
79924fce49 | ||
![]() |
865a0de03d | ||
4a84884e99 | |||
7203aa24f9 | |||
9fb97e3f85 | |||
0ee52a5741 | |||
6cdb3845a3 | |||
8a22429db2 | |||
![]() |
eaf9748f23 | ||
![]() |
a8ce1c98fe | ||
![]() |
5a9cd6a14d | ||
![]() |
fa2bf9381b | ||
![]() |
e1b13c0fa7 | ||
![]() |
85f7ad95ed | ||
![]() |
bd0367d1e6 | ||
b1b5ded37f | |||
0e3ba7cf41 | |||
d85295534b | |||
e148661d8d | |||
9f67367f0a | |||
6f1bdaab9d | |||
![]() |
fbb9bffe1b | ||
33e456b0ce | |||
47b21dd4c6 | |||
9a22b32e7e | |||
57ac20d5b7 | |||
8641fa1397 | |||
9e2dca933e | |||
b12d2fb922 | |||
e572cf1239 | |||
f695c9861f | |||
c1057ac196 | |||
b1add8e5bd | |||
3b71d5c0ae | |||
feb588060a | |||
86747ff180 | |||
92a2b444b0 | |||
0ccfa297f9 | |||
6144721778 | |||
![]() |
003c64757d | ||
![]() |
0b834c4fd9 | ||
6edfa73f5c | |||
![]() |
7f10a889e3 | ||
![]() |
d4e0557cf1 | ||
2e8be8ac6b | |||
8e05a5bf8c | |||
64b4a3185c | |||
57573df0d3 | |||
4935e2449b | |||
7493a2b3c0 | |||
ba551014f8 | |||
13399d471e | |||
![]() |
3ab8895610 | ||
fd089843b3 | |||
eca2f918a7 | |||
0651227c4a | |||
160c643131 | |||
fb61711b1a | |||
![]() |
a19607ca56 | ||
![]() |
0526088819 | ||
c231c29afa | |||
fa19940dc6 | |||
92258f3678 | |||
85194046e6 | |||
be72d7a9f5 | |||
adb422e500 | |||
75a4c836d6 | |||
242715b843 | |||
81db4d2b43 | |||
641828bf85 | |||
![]() |
f6b66e76e1 | ||
![]() |
dd4c638c0d | ||
![]() |
71d7c57997 | ||
![]() |
835f9742e6 | ||
481785f153 | |||
581b0c9a4f | |||
![]() |
a6191d0e27 | ||
![]() |
6064ffdc83 | ||
![]() |
c955b77f7d | ||
![]() |
a0e4ae5d37 | ||
a90622ce93 | |||
326516c9d7 | |||
b3690cdecd | |||
![]() |
7f498b4bde | ||
![]() |
fb5682412d | ||
c4c3951c4f | |||
75d6a30cc2 | |||
![]() |
887fc0ff6d | ||
![]() |
64b07e866a | ||
3e9ade6e31 | |||
![]() |
52e1728a12 | ||
b5682a6fdd | |||
![]() |
910f16576d | ||
60e387f5e3 | |||
85174329d9 | |||
b997914f80 | |||
a928a9c1e1 | |||
d07e2416db | |||
b841d60bf8 | |||
a50b173952 | |||
4e1025376e | |||
bc4aeefe82 | |||
eadfd901ad | |||
fbd28d375a | |||
4443bad30a | |||
997a210b08 | |||
![]() |
5fa0315a75 | ||
![]() |
a35a66f702 | ||
![]() |
f35d38e5a7 | ||
![]() |
45b9dee8bd | ||
![]() |
8605eb9c97 | ||
![]() |
1bfc6e79ee | ||
![]() |
f51c34185e | ||
f2e217938e | |||
106f415ddd | |||
b86e5a9fbf | |||
12bac207c7 | |||
![]() |
3da834e83c | ||
![]() |
dce8ef49ff | ||
08675b94ef | |||
ba4a30c71b | |||
4580ace4c1 | |||
62f2c44ffb | |||
505ff16dbf | |||
318ee2e8c1 | |||
167ab03f36 | |||
cdff659036 | |||
e15c16f11c | |||
6c23a1b8b9 | |||
b99491caf7 | |||
cf6ca226fa | |||
dead79a16a | |||
88b0b22914 | |||
cd596fa1c7 | |||
d6f965b99c | |||
15b253c082 | |||
744f26b612 | |||
ba116c8e9c | |||
c64c901535 | |||
e4e1900012 | |||
11abb13483 | |||
fb2f95c91a | |||
bfe3b967fa | |||
5bf60530e5 | |||
436f1e3345 | |||
![]() |
2081dac93b | ||
![]() |
86887fe1c5 | ||
0330741548 | |||
![]() |
29669db7d7 | ||
![]() |
84b18162cf | ||
efa401b086 | |||
bce9e80d82 | |||
4c416aea3b | |||
![]() |
c1742b88a4 | ||
![]() |
8d04f49d0e | ||
![]() |
9b7b9d6ae9 | ||
![]() |
8f673cb40c | ||
![]() |
4c43dddeb7 | ||
fcd5880d12 | |||
92e5dfbeed | |||
![]() |
40aa8a1c79 | ||
![]() |
51f77a10eb | ||
9023abbf27 | |||
5ef2f21963 | |||
67bef6bcf6 | |||
d812e0cb64 | |||
9e48cafd6d | |||
fd69ba2255 | |||
c441eb27ea | |||
331f721725 | |||
f14e1da5aa | |||
3c3c52a74b | |||
00c3c6824d | |||
ac58a7fa19 | |||
![]() |
18cf3e1a38 | ||
![]() |
290e080db4 | ||
01527197aa | |||
b91edd61d0 | |||
![]() |
e346927111 | ||
![]() |
dd61b7d346 | ||
64f5afdb89 | |||
![]() |
99e8618202 | ||
![]() |
e5482f986c | ||
ced20b74e5 | |||
e29a6f739d | |||
72ff78a951 | |||
e4de6e87e1 | |||
95e9790704 | |||
8ea09252c8 | |||
![]() |
212e5d60d3 | ||
4cbfaa6f3f | |||
1ad842d432 | |||
a7d5cabd4e | |||
57f937ad5a | |||
![]() |
8a6c689f30 | ||
605695de61 | |||
d84df351d0 | |||
c5ed943479 | |||
![]() |
673a149e87 | ||
efa46d7db0 | |||
bbbb8405b6 | |||
![]() |
f8e4999656 | ||
![]() |
1edabaee72 | ||
![]() |
8a8e5055e3 | ||
![]() |
adcb6a1b90 | ||
![]() |
971aa5f838 | ||
![]() |
caf59d3709 | ||
![]() |
bd14352a01 | ||
![]() |
32662bc95d | ||
76dead8603 | |||
![]() |
550446bade | ||
![]() |
10db593060 | ||
![]() |
03fc433e18 | ||
![]() |
597cafb873 | ||
![]() |
53eabca4e8 | ||
![]() |
096f251122 | ||
![]() |
b3ce0625c6 | ||
![]() |
ef7dc52b53 | ||
![]() |
74ba736fc4 | ||
![]() |
78b630844b | ||
![]() |
b1ff8e8703 | ||
![]() |
216273d9e9 | ||
e6bba9fa3a | |||
![]() |
fd99d52448 | ||
![]() |
c36cdb92d6 | ||
![]() |
9ddb221aab | ||
![]() |
5ff3dd5d97 | ||
![]() |
d2f97224b5 | ||
![]() |
10754500b0 | ||
![]() |
8a3dd31658 | ||
![]() |
911c31c201 | ||
![]() |
c21e00683c | ||
![]() |
0ad3979a6c | ||
![]() |
c4e34a84e0 | ||
![]() |
baad441362 | ||
![]() |
533965db73 | ||
33ca692256 | |||
![]() |
988024063f | ||
![]() |
07d571ea22 | ||
![]() |
0fba4655bf | ||
e954a6b8bc | |||
306711c7ab | |||
382ade4c29 | |||
2c3d9f2762 | |||
ddd95b9712 | |||
a94b4c2ff0 | |||
fd7f78d89f | |||
![]() |
d97c6c36b8 | ||
![]() |
051f0a0b15 | ||
![]() |
a80d94c289 | ||
![]() |
4180ca9b92 | ||
![]() |
6d68195a9b | ||
![]() |
345eb6f7cc | ||
![]() |
ec65bc6e76 | ||
![]() |
b00cfb77cd | ||
![]() |
70ddef82b7 | ||
8c3a98e583 | |||
89d99b6b77 | |||
1ceeac2cab | |||
![]() |
d89274e83a | ||
![]() |
a771249d7d | ||
c8162c5a2c | |||
![]() |
143c869bd0 | ||
![]() |
33ee18ad6f | ||
![]() |
d16bfecde1 | ||
![]() |
2ad2b23911 | ||
![]() |
052b45ac2a | ||
![]() |
551852f4ca | ||
c9c0d6c24f | |||
![]() |
1020914980 | ||
![]() |
9f333a0889 | ||
![]() |
7e57905385 | ||
ca4618bdbf | |||
2cf79f41fe | |||
![]() |
6933bb4e9a | ||
![]() |
b5d41b1d71 | ||
![]() |
71e5e87f01 | ||
5333b2aa00 | |||
c990364559 | |||
624f3c254f | |||
![]() |
d80372c9f4 | ||
![]() |
7bd56f207d | ||
![]() |
ac6019e079 | ||
![]() |
ac80793592 | ||
![]() |
f8dd25afb8 | ||
0c4776280d | |||
![]() |
3bdd555159 | ||
![]() |
36c34b96b3 | ||
![]() |
caed6aad4b | ||
![]() |
b89b1b58b2 | ||
fe0df0a972 | |||
![]() |
e758b9d869 | ||
![]() |
2fa175eb8a | ||
![]() |
2c55b4cbc8 | ||
![]() |
66bc0616fc | ||
![]() |
eae6e02759 | ||
![]() |
7ba2a5feb5 | ||
![]() |
280da49595 | ||
![]() |
ee6214dc80 | ||
![]() |
c51a32554e | ||
![]() |
95e183b7f4 | ||
![]() |
a9cc4d0c5c | ||
![]() |
4d998fb373 | ||
![]() |
5e79ebce13 | ||
![]() |
52c4adc4df | ||
![]() |
c8978b160d | ||
![]() |
5c22ade95a | ||
![]() |
d550554d0c | ||
![]() |
18ee712bf1 | ||
![]() |
a6cf5cfe9c | ||
![]() |
0abcddf470 | ||
![]() |
1abef41657 | ||
![]() |
51984897d8 | ||
![]() |
a508029fbc | ||
![]() |
619cbca39f | ||
![]() |
72bd463127 | ||
![]() |
42bb135480 | ||
![]() |
9d2b6b56ac | ||
![]() |
d4cebc998b | ||
![]() |
60aa0b5b15 | ||
![]() |
f59b6ff410 | ||
![]() |
57a5f2ef44 | ||
![]() |
a3fd4274cf | ||
![]() |
0da8957bc5 | ||
![]() |
75b7a25014 | ||
![]() |
29961ad597 | ||
![]() |
3f9432b76a | ||
![]() |
59fbc6db8d | ||
![]() |
c75e7516c3 | ||
![]() |
b7a42fe69f | ||
![]() |
3839afe03d | ||
![]() |
c96c3c8bbe | ||
![]() |
ef6a35b0af | ||
![]() |
df8d4299a2 | ||
![]() |
6fdd6f7d7c | ||
![]() |
dddf38dc42 | ||
![]() |
3c3c818d1b | ||
![]() |
a2e81fa2e9 | ||
![]() |
866b3268a5 | ||
![]() |
97109b654e | ||
![]() |
6e6750a06a | ||
![]() |
8146a4498a | ||
![]() |
3acb83c6f4 | ||
![]() |
d0ef44218e | ||
![]() |
4ad8789a38 | ||
![]() |
1db50e9a88 | ||
![]() |
87330b4729 | ||
![]() |
2b09fb3f30 | ||
![]() |
d085e62693 | ||
![]() |
89d20732a1 | ||
![]() |
bc2321025b | ||
![]() |
52fdf5d06c | ||
![]() |
63780823a7 | ||
![]() |
f304e2e273 | ||
![]() |
84d94fc06f | ||
![]() |
25f1e97408 | ||
![]() |
d2b91a1c7c | ||
![]() |
3c65f2f542 | ||
![]() |
b4799b23ec | ||
![]() |
91d7c345d4 | ||
![]() |
bc66ca246c | ||
![]() |
477fc97bd5 | ||
![]() |
58acb05061 | ||
![]() |
cb11ab9b09 | ||
![]() |
8d55fe9899 | ||
![]() |
dc3154b29f | ||
![]() |
34520c0ffc |
@@ -242,6 +242,8 @@ endif()
|
||||
option(WITH_PLAYER "Build Player" OFF)
|
||||
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ${_init_OPENCOLORIO})
|
||||
|
||||
option(WITH_CLAY_ENGINE "Enable New Clay engine (Breaks Mac and Intel compatibility)" ON)
|
||||
|
||||
# Compositor
|
||||
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
|
||||
|
||||
@@ -722,7 +724,7 @@ if(NOT WITH_BOOST)
|
||||
macro(set_and_warn
|
||||
_setting _val)
|
||||
if(${${_setting}})
|
||||
message(STATUS "'WITH_BOOST' is disabled: forceing 'set(${_setting} ${_val})'")
|
||||
message(STATUS "'WITH_BOOST' is disabled: forcing 'set(${_setting} ${_val})'")
|
||||
endif()
|
||||
set(${_setting} ${_val})
|
||||
endmacro()
|
||||
|
@@ -787,7 +787,7 @@ CXXFLAGS_BACK=$CXXFLAGS
|
||||
if [ "$USE_CXX11" = true ]; then
|
||||
WARNING "C++11 is now mandatory for blender2.8, this *should* go smoothly with any very recent distribution.
|
||||
However, if you are experiencing linking errors (also when building Blender itself), please try the following:
|
||||
* Re-run this script with `--build-all --force-all` options.
|
||||
* Re-run this script with '--build-all --force-all' options.
|
||||
* Ensure your gcc version is at the very least 4.8, if possible you should really rather use gcc-5.1 or above.
|
||||
|
||||
Please note that until the transition to C++11-built libraries if completed in your distribution, situation will
|
||||
|
@@ -45,7 +45,7 @@ macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${TESTS_OUTPUT_DIR}"
|
||||
INCLUDE_DIRECTORIES "${TEST_INC}")
|
||||
if(${DO_ADD_TEST})
|
||||
add_test(${NAME}_test ${TESTS_OUTPUT_DIR}/${NAME}_test)
|
||||
add_test(NAME ${NAME}_test COMMAND ${TESTS_OUTPUT_DIR}/${NAME}_test WORKING_DIRECTORY $<TARGET_FILE_DIR:blender>)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
@@ -416,14 +416,7 @@ function(setup_liblinks
|
||||
target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
|
||||
if(WIN32 AND NOT UNIX)
|
||||
file_list_suffix(OPENSUBDIV_LIBRARIES_DEBUG "${OPENSUBDIV_LIBRARIES}" "_d")
|
||||
target_link_libraries_debug(${target} "${OPENSUBDIV_LIBRARIES_DEBUG}")
|
||||
target_link_libraries_optimized(${target} "${OPENSUBDIV_LIBRARIES}")
|
||||
unset(OPENSUBDIV_LIBRARIES_DEBUG)
|
||||
else()
|
||||
target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
if(WITH_OPENVDB)
|
||||
target_link_libraries(${target} ${OPENVDB_LIBRARIES} ${TBB_LIBRARIES})
|
||||
@@ -573,6 +566,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
|
||||
bf_editor_space_userpref
|
||||
bf_editor_space_view3d
|
||||
bf_editor_space_clip
|
||||
bf_editor_space_collections
|
||||
|
||||
bf_editor_transform
|
||||
bf_editor_util
|
||||
@@ -604,6 +598,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
|
||||
bf_modifiers
|
||||
bf_bmesh
|
||||
bf_gpu
|
||||
bf_draw
|
||||
bf_blenloader
|
||||
bf_blenkernel
|
||||
bf_physics
|
||||
|
@@ -446,10 +446,20 @@ if(WITH_MOD_CLOTH_ELTOPO)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
|
||||
set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include)
|
||||
set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib)
|
||||
set(OPENSUBDIV_LIBRARIES ${OPENSUBDIV_LIBPATH}/osdCPU.lib ${OPENSUBDIV_LIBPATH}/osdGPU.lib)
|
||||
find_package(OpenSubdiv)
|
||||
set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include)
|
||||
set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib)
|
||||
set(OPENSUBDIV_LIBRARIES optimized ${OPENSUBDIV_LIBPATH}/osdCPU.lib
|
||||
optimized ${OPENSUBDIV_LIBPATH}/osdGPU.lib
|
||||
debug ${OPENSUBDIV_LIBPATH}/osdCPU_d.lib
|
||||
debug ${OPENSUBDIV_LIBPATH}/osdGPU_d.lib
|
||||
)
|
||||
set(OPENSUBDIV_HAS_OPENMP TRUE)
|
||||
set(OPENSUBDIV_HAS_TBB FALSE)
|
||||
set(OPENSUBDIV_HAS_OPENCL TRUE)
|
||||
set(OPENSUBDIV_HAS_CUDA FALSE)
|
||||
set(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK TRUE)
|
||||
set(OPENSUBDIV_HAS_GLSL_COMPUTE TRUE)
|
||||
windows_find_package(OpenSubdiv)
|
||||
endif()
|
||||
|
||||
if(WITH_SDL)
|
||||
|
@@ -62,7 +62,7 @@ def _parse_command_line():
|
||||
num_resumable_chunks = None
|
||||
current_resumable_chunk = None
|
||||
|
||||
# TODO(sergey): Add some nice error ptins if argument is not used properly.
|
||||
# TODO(sergey): Add some nice error prints if argument is not used properly.
|
||||
idx = 0
|
||||
while idx < len(argv) - 1:
|
||||
arg = argv[idx]
|
||||
|
@@ -638,6 +638,20 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
items=enum_texture_limit
|
||||
)
|
||||
|
||||
cls.ao_bounces = IntProperty(
|
||||
name="AO Bounces",
|
||||
default=0,
|
||||
description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
|
||||
min=0, max=1024,
|
||||
)
|
||||
|
||||
cls.ao_bounces_render = IntProperty(
|
||||
name="AO Bounces Render",
|
||||
default=0,
|
||||
description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
|
||||
min=0, max=1024,
|
||||
)
|
||||
|
||||
# Various fine-tuning debug flags
|
||||
|
||||
def devices_update_callback(self, context):
|
||||
|
@@ -1038,10 +1038,11 @@ class CyclesWorld_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
light = context.world.light_settings
|
||||
scene = context.scene
|
||||
|
||||
row = layout.row()
|
||||
sub = row.row()
|
||||
sub.active = light.use_ambient_occlusion
|
||||
sub.active = light.use_ambient_occlusion or scene.render.use_simplify
|
||||
sub.prop(light, "ao_factor", text="Factor")
|
||||
row.prop(light, "distance", text="Distance")
|
||||
|
||||
@@ -1613,6 +1614,13 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
|
||||
row.active = cscene.use_distance_cull
|
||||
row.prop(cscene, "distance_cull_margin", text="Distance")
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.prop(cscene, "ao_bounces")
|
||||
|
||||
col = split.column()
|
||||
col.prop(cscene, "ao_bounces_render")
|
||||
|
||||
def draw_device(self, context):
|
||||
scene = context.scene
|
||||
layout = self.layout
|
||||
|
@@ -927,6 +927,13 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
|
||||
|
||||
mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental);
|
||||
|
||||
/* Disable adaptive subdivision while baking as the baking system
|
||||
* currently doesnt support the topology and will crash.
|
||||
*/
|
||||
if(scene->bake_manager->get_baking()) {
|
||||
mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
|
||||
}
|
||||
|
||||
BL::Mesh b_mesh = object_to_mesh(b_data,
|
||||
b_ob,
|
||||
b_scene,
|
||||
|
@@ -1352,6 +1352,9 @@ void BlenderSession::update_resumable_tile_manager(int num_samples)
|
||||
VLOG(1) << "Samples range start is " << range_start_sample << ", "
|
||||
<< "number of samples to render is " << range_num_samples;
|
||||
|
||||
scene->integrator->start_sample = range_start_sample;
|
||||
scene->integrator->tag_update(scene);
|
||||
|
||||
session->tile_manager.range_start_sample = range_start_sample;
|
||||
session->tile_manager.range_num_samples = range_num_samples;
|
||||
}
|
||||
|
@@ -640,7 +640,8 @@ static ShaderNode *add_node(Scene *scene,
|
||||
image->filename.string(),
|
||||
image->builtin_data,
|
||||
get_image_interpolation(b_image_node),
|
||||
get_image_extension(b_image_node));
|
||||
get_image_extension(b_image_node),
|
||||
image->use_alpha);
|
||||
}
|
||||
}
|
||||
image->color_space = (NodeImageColorSpace)b_image_node.color_space();
|
||||
@@ -686,7 +687,8 @@ static ShaderNode *add_node(Scene *scene,
|
||||
env->filename.string(),
|
||||
env->builtin_data,
|
||||
get_image_interpolation(b_env_node),
|
||||
EXTENSION_REPEAT);
|
||||
EXTENSION_REPEAT,
|
||||
env->use_alpha);
|
||||
}
|
||||
}
|
||||
env->color_space = (NodeImageColorSpace)b_env_node.color_space();
|
||||
@@ -823,7 +825,8 @@ static ShaderNode *add_node(Scene *scene,
|
||||
point_density->filename.string(),
|
||||
point_density->builtin_data,
|
||||
point_density->interpolation,
|
||||
EXTENSION_CLIP);
|
||||
EXTENSION_CLIP,
|
||||
true);
|
||||
}
|
||||
node = point_density;
|
||||
|
||||
|
@@ -322,6 +322,15 @@ void BlenderSync::sync_integrator()
|
||||
integrator->volume_samples = volume_samples;
|
||||
}
|
||||
|
||||
if(b_scene.render().use_simplify()) {
|
||||
if(preview) {
|
||||
integrator->ao_bounces = get_int(cscene, "ao_bounces");
|
||||
}
|
||||
else {
|
||||
integrator->ao_bounces = get_int(cscene, "ao_bounces_render");
|
||||
}
|
||||
}
|
||||
|
||||
if(integrator->modified(previntegrator))
|
||||
integrator->tag_update(scene);
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "scene.h"
|
||||
#include "curves.h"
|
||||
|
||||
#include "util_algorithm.h"
|
||||
#include "util_debug.h"
|
||||
#include "util_foreach.h"
|
||||
#include "util_logging.h"
|
||||
|
@@ -109,6 +109,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
||||
/* intersect scene */
|
||||
Intersection isect;
|
||||
uint visibility = path_state_ray_visibility(kg, state);
|
||||
if(state->bounce > kernel_data.integrator.ao_bounces) {
|
||||
visibility = PATH_RAY_SHADOW;
|
||||
ray->t = kernel_data.background.ao_distance;
|
||||
}
|
||||
bool hit = scene_intersect(kg,
|
||||
*ray,
|
||||
visibility,
|
||||
@@ -292,6 +296,9 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
||||
|
||||
break;
|
||||
}
|
||||
else if(state->bounce > kernel_data.integrator.ao_bounces) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup shading */
|
||||
shader_setup_from_ray(kg,
|
||||
@@ -627,6 +634,11 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg,
|
||||
lcg_state = lcg_state_init(rng, &state, 0x51633e2d);
|
||||
}
|
||||
|
||||
if(state.bounce > kernel_data.integrator.ao_bounces) {
|
||||
visibility = PATH_RAY_SHADOW;
|
||||
ray.t = kernel_data.background.ao_distance;
|
||||
}
|
||||
|
||||
bool hit = scene_intersect(kg, ray, visibility, &isect, &lcg_state, difl, extmax);
|
||||
#else
|
||||
bool hit = scene_intersect(kg, ray, visibility, &isect, NULL, 0.0f, 0.0f);
|
||||
@@ -769,6 +781,9 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg,
|
||||
|
||||
break;
|
||||
}
|
||||
else if(state.bounce > kernel_data.integrator.ao_bounces) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup shading */
|
||||
shader_setup_from_ray(kg, &sd, &isect, &ray);
|
||||
|
@@ -30,7 +30,7 @@ ccl_device_inline void kernel_path_trace_setup(KernelGlobals *kg,
|
||||
|
||||
int num_samples = kernel_data.integrator.aa_samples;
|
||||
|
||||
if(sample == 0) {
|
||||
if(sample == kernel_data.integrator.start_sample) {
|
||||
*rng_state = hash_int_2d(x, y);
|
||||
}
|
||||
|
||||
|
@@ -1143,6 +1143,8 @@ typedef struct KernelIntegrator {
|
||||
int max_transmission_bounce;
|
||||
int max_volume_bounce;
|
||||
|
||||
int ao_bounces;
|
||||
|
||||
/* transparent */
|
||||
int transparent_min_bounce;
|
||||
int transparent_max_bounce;
|
||||
@@ -1186,7 +1188,8 @@ typedef struct KernelIntegrator {
|
||||
|
||||
float light_inv_rr_threshold;
|
||||
|
||||
int pad1;
|
||||
int start_sample;
|
||||
int pad1, pad2, pad3;
|
||||
} KernelIntegrator;
|
||||
static_assert_align(KernelIntegrator, 16);
|
||||
|
||||
|
@@ -258,12 +258,14 @@ static bool image_equals(ImageManager::Image *image,
|
||||
const string& filename,
|
||||
void *builtin_data,
|
||||
InterpolationType interpolation,
|
||||
ExtensionType extension)
|
||||
ExtensionType extension,
|
||||
bool use_alpha)
|
||||
{
|
||||
return image->filename == filename &&
|
||||
image->builtin_data == builtin_data &&
|
||||
image->interpolation == interpolation &&
|
||||
image->extension == extension;
|
||||
image->extension == extension &&
|
||||
image->use_alpha == use_alpha;
|
||||
}
|
||||
|
||||
int ImageManager::add_image(const string& filename,
|
||||
@@ -305,7 +307,8 @@ int ImageManager::add_image(const string& filename,
|
||||
filename,
|
||||
builtin_data,
|
||||
interpolation,
|
||||
extension))
|
||||
extension,
|
||||
use_alpha))
|
||||
{
|
||||
if(img->frame != frame) {
|
||||
img->frame = frame;
|
||||
@@ -377,7 +380,8 @@ void ImageManager::remove_image(int flat_slot)
|
||||
void ImageManager::remove_image(const string& filename,
|
||||
void *builtin_data,
|
||||
InterpolationType interpolation,
|
||||
ExtensionType extension)
|
||||
ExtensionType extension,
|
||||
bool use_alpha)
|
||||
{
|
||||
size_t slot;
|
||||
|
||||
@@ -387,7 +391,8 @@ void ImageManager::remove_image(const string& filename,
|
||||
filename,
|
||||
builtin_data,
|
||||
interpolation,
|
||||
extension))
|
||||
extension,
|
||||
use_alpha))
|
||||
{
|
||||
remove_image(type_index_to_flattened_slot(slot, (ImageDataType)type));
|
||||
return;
|
||||
@@ -403,7 +408,8 @@ void ImageManager::remove_image(const string& filename,
|
||||
void ImageManager::tag_reload_image(const string& filename,
|
||||
void *builtin_data,
|
||||
InterpolationType interpolation,
|
||||
ExtensionType extension)
|
||||
ExtensionType extension,
|
||||
bool use_alpha)
|
||||
{
|
||||
for(size_t type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
|
||||
for(size_t slot = 0; slot < images[type].size(); slot++) {
|
||||
@@ -411,7 +417,8 @@ void ImageManager::tag_reload_image(const string& filename,
|
||||
filename,
|
||||
builtin_data,
|
||||
interpolation,
|
||||
extension))
|
||||
extension,
|
||||
use_alpha))
|
||||
{
|
||||
images[type][slot]->need_load = true;
|
||||
break;
|
||||
|
@@ -61,11 +61,13 @@ public:
|
||||
void remove_image(const string& filename,
|
||||
void *builtin_data,
|
||||
InterpolationType interpolation,
|
||||
ExtensionType extension);
|
||||
ExtensionType extension,
|
||||
bool use_alpha);
|
||||
void tag_reload_image(const string& filename,
|
||||
void *builtin_data,
|
||||
InterpolationType interpolation,
|
||||
ExtensionType extension);
|
||||
ExtensionType extension,
|
||||
bool use_alpha);
|
||||
ImageDataType get_image_metadata(const string& filename, void *builtin_data, bool& is_linear);
|
||||
|
||||
void device_update(Device *device,
|
||||
|
@@ -43,6 +43,8 @@ NODE_DEFINE(Integrator)
|
||||
SOCKET_INT(transparent_max_bounce, "Transparent Max Bounce", 7);
|
||||
SOCKET_BOOLEAN(transparent_shadows, "Transparent Shadows", false);
|
||||
|
||||
SOCKET_INT(ao_bounces, "AO Bounces", 0);
|
||||
|
||||
SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024);
|
||||
SOCKET_FLOAT(volume_step_size, "Volume Step Size", 0.1f);
|
||||
|
||||
@@ -62,6 +64,7 @@ NODE_DEFINE(Integrator)
|
||||
SOCKET_INT(mesh_light_samples, "Mesh Light Samples", 1);
|
||||
SOCKET_INT(subsurface_samples, "Subsurface Samples", 1);
|
||||
SOCKET_INT(volume_samples, "Volume Samples", 1);
|
||||
SOCKET_INT(start_sample, "Start Sample", 0);
|
||||
|
||||
SOCKET_BOOLEAN(sample_all_lights_direct, "Sample All Lights Direct", true);
|
||||
SOCKET_BOOLEAN(sample_all_lights_indirect, "Sample All Lights Indirect", true);
|
||||
@@ -111,6 +114,13 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
||||
kintegrator->transparent_max_bounce = transparent_max_bounce + 1;
|
||||
kintegrator->transparent_min_bounce = transparent_min_bounce + 1;
|
||||
|
||||
if(ao_bounces == 0) {
|
||||
kintegrator->ao_bounces = INT_MAX;
|
||||
}
|
||||
else {
|
||||
kintegrator->ao_bounces = ao_bounces - 1;
|
||||
}
|
||||
|
||||
/* Transparent Shadows
|
||||
* We only need to enable transparent shadows, if we actually have
|
||||
* transparent shaders in the scene. Otherwise we can disable it
|
||||
@@ -152,6 +162,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
||||
kintegrator->mesh_light_samples = mesh_light_samples;
|
||||
kintegrator->subsurface_samples = subsurface_samples;
|
||||
kintegrator->volume_samples = volume_samples;
|
||||
kintegrator->start_sample = start_sample;
|
||||
|
||||
if(method == BRANCHED_PATH) {
|
||||
kintegrator->sample_all_lights_direct = sample_all_lights_direct;
|
||||
|
@@ -43,6 +43,8 @@ public:
|
||||
int transparent_max_bounce;
|
||||
bool transparent_shadows;
|
||||
|
||||
int ao_bounces;
|
||||
|
||||
int volume_max_steps;
|
||||
float volume_step_size;
|
||||
|
||||
@@ -64,6 +66,7 @@ public:
|
||||
int mesh_light_samples;
|
||||
int subsurface_samples;
|
||||
int volume_samples;
|
||||
int start_sample;
|
||||
|
||||
bool sample_all_lights_direct;
|
||||
bool sample_all_lights_indirect;
|
||||
|
@@ -263,7 +263,8 @@ ImageTextureNode::~ImageTextureNode()
|
||||
image_manager->remove_image(filename.string(),
|
||||
builtin_data,
|
||||
interpolation,
|
||||
extension);
|
||||
extension,
|
||||
use_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +463,8 @@ EnvironmentTextureNode::~EnvironmentTextureNode()
|
||||
image_manager->remove_image(filename.string(),
|
||||
builtin_data,
|
||||
interpolation,
|
||||
EXTENSION_REPEAT);
|
||||
EXTENSION_REPEAT,
|
||||
use_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1381,7 +1383,8 @@ PointDensityTextureNode::~PointDensityTextureNode()
|
||||
image_manager->remove_image(filename.string(),
|
||||
builtin_data,
|
||||
interpolation,
|
||||
EXTENSION_CLIP);
|
||||
EXTENSION_CLIP,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -157,7 +157,7 @@ void TileManager::set_samples(int num_samples_)
|
||||
divider >>= 1;
|
||||
}
|
||||
|
||||
state.total_pixel_samples = pixel_samples + get_num_effective_samples() * params.width*params.height;
|
||||
state.total_pixel_samples = pixel_samples + (uint64_t)get_num_effective_samples() * params.width*params.height;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -54,12 +54,23 @@ if(WITH_CYCLES_OPENSUBDIV)
|
||||
endif()
|
||||
list(APPEND ALL_CYCLES_LIBRARIES
|
||||
${BOOST_LIBRARIES}
|
||||
${PNG_LIBRARIES}
|
||||
${JPEG_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${TIFF_LIBRARY}
|
||||
${OPENIMAGEIO_LIBRARIES}
|
||||
${OPENEXR_LIBRARIES}
|
||||
)
|
||||
|
||||
include_directories(${INC})
|
||||
|
||||
link_directories(${BOOST_LIBPATH})
|
||||
link_directories(${OPENIMAGEIO_LIBPATH})
|
||||
link_directories(${OPENIMAGEIO_LIBPATH}
|
||||
${BOOST_LIBPATH}
|
||||
${PNG_LIBPATH}
|
||||
${JPEG_LIBPATH}
|
||||
${ZLIB_LIBPATH}
|
||||
${TIFF_LIBPATH}
|
||||
${OPENEXR_LIBPATH})
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
|
||||
|
@@ -1316,10 +1316,12 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
|
||||
// During development:
|
||||
// try 4.x compatibility profile
|
||||
// try 3.3 compatibility profile
|
||||
// fall back to 3.0 if needed
|
||||
//
|
||||
// Final Blender 2.8:
|
||||
// try 4.x core profile
|
||||
// try 3.3 core profile
|
||||
// no fallbacks
|
||||
|
||||
@@ -1332,7 +1334,28 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
|
||||
# error // must specify either core or compat at build time
|
||||
#endif
|
||||
|
||||
GHOST_Context *context = new GHOST_ContextGLX(
|
||||
GHOST_Context *context;
|
||||
|
||||
for (int minor = 5; minor >= 0; --minor) {
|
||||
context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
m_visualInfo,
|
||||
(GLXFBConfig)m_fbconfig,
|
||||
profile_mask,
|
||||
4, minor,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
}
|
||||
|
||||
context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
@@ -1346,27 +1369,26 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else {
|
||||
else
|
||||
delete context;
|
||||
|
||||
// since that failed try 3.0 (mostly for Mesa, which doesn't implement compatibility profile)
|
||||
context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
m_visualInfo,
|
||||
(GLXFBConfig)m_fbconfig,
|
||||
0, // no profile bit
|
||||
3, 0,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
// since that failed try 3.0 (mostly for Mesa, which doesn't implement compatibility profile)
|
||||
context = new GHOST_ContextGLX(
|
||||
m_wantStereoVisual,
|
||||
m_wantNumOfAASamples,
|
||||
m_window,
|
||||
m_display,
|
||||
m_visualInfo,
|
||||
(GLXFBConfig)m_fbconfig,
|
||||
0, // no profile bit
|
||||
3, 0,
|
||||
GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
|
||||
GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY);
|
||||
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
}
|
||||
if (context->initializeDrawingContext())
|
||||
return context;
|
||||
else
|
||||
delete context;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
7
make.bat
7
make.bat
@@ -22,7 +22,7 @@ set MUST_CLEAN=
|
||||
set NOBUILD=
|
||||
set TARGET=
|
||||
set WINDOWS_ARCH=
|
||||
|
||||
set TESTS_CMAKE_ARGS=
|
||||
:argv_loop
|
||||
if NOT "%1" == "" (
|
||||
|
||||
@@ -35,6 +35,8 @@ if NOT "%1" == "" (
|
||||
if "%1" == "debug" (
|
||||
set BUILD_TYPE=Debug
|
||||
REM Build Configurations
|
||||
) else if "%1" == "with_tests" (
|
||||
set TESTS_CMAKE_ARGS=-DWITH_GTESTS=On
|
||||
) else if "%1" == "full" (
|
||||
set TARGET=Full
|
||||
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% ^
|
||||
@@ -204,7 +206,7 @@ if "%TARGET%"=="" (
|
||||
goto HELP
|
||||
)
|
||||
|
||||
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%WINDOWS_ARCH%"
|
||||
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%WINDOWS_ARCH%" %TESTS_CMAKE_ARGS%
|
||||
if NOT EXIST %BUILD_DIR%\nul (
|
||||
mkdir %BUILD_DIR%
|
||||
)
|
||||
@@ -284,6 +286,7 @@ goto EOF
|
||||
echo - showhash ^(Show git hashes of source tree^)
|
||||
echo.
|
||||
echo Configuration options
|
||||
echo - with_tests ^(enable building unit tests^)
|
||||
echo - debug ^(Build an unoptimized debuggable build^)
|
||||
echo - packagename [newname] ^(override default cpack package name^)
|
||||
echo - x86 ^(override host autodetect and build 32 bit code^)
|
||||
|
@@ -14,7 +14,7 @@
|
||||
height="640"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.91 r13725"
|
||||
inkscape:version="0.91 r"
|
||||
version="1.0"
|
||||
sodipodi:docname="blender_icons.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
@@ -28201,7 +28201,7 @@
|
||||
xlink:href="#linearGradient37542-29"
|
||||
id="linearGradient17610"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
|
||||
gradientTransform="matrix(-1,0,0,1,865.01833,131.0342)"
|
||||
x1="392.0101"
|
||||
y1="224.99998"
|
||||
x2="392.0101"
|
||||
@@ -28263,7 +28263,7 @@
|
||||
xlink:href="#linearGradient37542-29-7"
|
||||
id="linearGradient17610-0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1,0,0,1,461.01011,-167)"
|
||||
gradientTransform="translate(128.00098,130.98191)"
|
||||
x1="392.0101"
|
||||
y1="224.99998"
|
||||
x2="392.0101"
|
||||
@@ -28402,7 +28402,7 @@
|
||||
x2="228.5468"
|
||||
y1="118.91647"
|
||||
x1="228.5468"
|
||||
gradientTransform="matrix(1.180548,0,0,0.90042534,265.27784,265.13062)"
|
||||
gradientTransform="matrix(1.180548,0,0,0.90042534,265.83288,265.61628)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient17838"
|
||||
xlink:href="#linearGradient319-36-40-2"
|
||||
@@ -28433,7 +28433,7 @@
|
||||
x2="228.5468"
|
||||
y1="118.91647"
|
||||
x1="228.5468"
|
||||
gradientTransform="matrix(1.180548,0,0,0.90042534,223.26222,270.47438)"
|
||||
gradientTransform="matrix(1.180548,0,0,0.90042534,223.81726,270.99473)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient17872"
|
||||
xlink:href="#linearGradient319-36-40-2-4"
|
||||
@@ -29073,7 +29073,7 @@
|
||||
xlink:href="#linearGradient27854-0-6-9"
|
||||
id="linearGradient17162"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,1,-1,0,782.48614,-14.46331)"
|
||||
gradientTransform="matrix(0,1,-1,0,783.04118,-13.977664)"
|
||||
x1="388.86502"
|
||||
y1="244.02"
|
||||
x2="391.43173"
|
||||
@@ -29083,7 +29083,7 @@
|
||||
xlink:href="#linearGradient37542-29-7-8"
|
||||
id="linearGradient17165"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,1,-1,0,782.48614,-14.46331)"
|
||||
gradientTransform="matrix(0,1,-1,0,783.04118,-13.977664)"
|
||||
x1="368.97806"
|
||||
y1="249.99998"
|
||||
x2="393.85385"
|
||||
@@ -29113,7 +29113,7 @@
|
||||
xlink:href="#linearGradient37542-29-1"
|
||||
id="linearGradient17185"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-1,-1,0,740.48614,764.46331)"
|
||||
gradientTransform="matrix(0,-1,-1,0,741.04118,764.98366)"
|
||||
x1="409.93588"
|
||||
y1="249.99998"
|
||||
x2="385.11514"
|
||||
@@ -31349,17 +31349,17 @@
|
||||
objecttolerance="10000"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.274018"
|
||||
inkscape:cx="519.70993"
|
||||
inkscape:cy="325.90484"
|
||||
inkscape:zoom="14.413868"
|
||||
inkscape:cx="480.24726"
|
||||
inkscape:cy="269.95478"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1005"
|
||||
inkscape:window-x="-2"
|
||||
inkscape:window-y="27"
|
||||
inkscape:snap-nodes="false"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1020"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="30"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-bbox="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
@@ -31369,14 +31369,16 @@
|
||||
inkscape:snap-intersection-grid-guide="false"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:bbox-paths="false"
|
||||
inkscape:snap-global="false"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-bbox-midpoints="false"
|
||||
inkscape:snap-grids="true"
|
||||
inkscape:snap-grids="false"
|
||||
inkscape:snap-to-guides="false"
|
||||
inkscape:snap-page="false"
|
||||
units="pt"
|
||||
inkscape:snap-center="false"
|
||||
inkscape:snap-object-midpoints="true">
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-midpoints="false"
|
||||
inkscape:snap-others="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid17394"
|
||||
@@ -88001,37 +88003,37 @@
|
||||
<g
|
||||
style="display:inline;enable-background:new"
|
||||
id="ICON_COLLAPSEMENU"
|
||||
transform="translate(279.8665,506.92392)">
|
||||
transform="translate(280,508)">
|
||||
<rect
|
||||
y="111"
|
||||
x="103"
|
||||
height="16"
|
||||
width="16"
|
||||
id="rect24489-7-4"
|
||||
style="opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0;fill:#b3b3b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.79999995;marker:none;enable-background:accumulate" />
|
||||
<rect
|
||||
style="fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79452544;stroke-opacity:1"
|
||||
id="rect29842"
|
||||
width="11.816368"
|
||||
height="2.1883197"
|
||||
x="105.18671"
|
||||
y="-116.88043"
|
||||
width="11.209318"
|
||||
height="2.1883163"
|
||||
x="105.39484"
|
||||
y="-116.60292"
|
||||
transform="scale(1,-1)" />
|
||||
<rect
|
||||
style="fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79452544;stroke-opacity:1;display:inline;enable-background:new"
|
||||
style="display:inline;fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79452544;stroke-opacity:1;enable-background:new"
|
||||
id="rect29842-4"
|
||||
width="11.816368"
|
||||
height="2.1883197"
|
||||
x="105.31538"
|
||||
y="-120.80865"
|
||||
width="11.191971"
|
||||
height="2.2056611"
|
||||
x="105.41944"
|
||||
y="-120.61786"
|
||||
transform="scale(1,-1)" />
|
||||
<rect
|
||||
style="fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79452544;stroke-opacity:1;display:inline;enable-background:new"
|
||||
style="display:inline;fill:#ececec;fill-opacity:1;stroke:#141414;stroke-width:0.79500002;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;enable-background:new"
|
||||
id="rect29842-4-5"
|
||||
width="11.816368"
|
||||
height="2.1883197"
|
||||
x="105.41832"
|
||||
y="-124.71391"
|
||||
width="11.22666"
|
||||
height="2.2056642"
|
||||
x="105.38363"
|
||||
y="-124.60985"
|
||||
transform="scale(1,-1)" />
|
||||
</g>
|
||||
<g
|
||||
@@ -89360,17 +89362,18 @@
|
||||
y="69" />
|
||||
<g
|
||||
id="g17605"
|
||||
transform="translate(-1.5467961,-0.48613592)">
|
||||
transform="translate(-0.99177519,0.03419629)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccccc"
|
||||
style="fill:url(#linearGradient17610);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 472.51758,370.53516 -1.04688,0.0312 0.0371,9.96875 1.00977,0 3.95117,-3.70704 -5.3e-4,3.72852 3.1119,0 0,-10.01758 -3.1119,0 5.3e-4,3.73242 z"
|
||||
transform="translate(-404.00822,-298.0342)"
|
||||
id="path11011-6"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 72.839729,82.521675 2.731705,0 0,-10.016275 -2.731705,0 L 72.84,76.59374 68.51011,72.5 67.4632,72.53125 67.5,82.49999 68.51011,82.5 72.84,78.43749 z"
|
||||
style="fill:url(#linearGradient17610);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path11011-6" />
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
style="fill:none;stroke:url(#linearGradient17612);stroke-width:0.91056824px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 73.7503,81.408784 0,-7.99274 0.910568,-6.3e-5"
|
||||
d="m 73.368723,81.408784 0,-7.99274 1.292145,-6.3e-5"
|
||||
id="path10830-6"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
@@ -89397,17 +89400,18 @@
|
||||
y="69" />
|
||||
<g
|
||||
id="g17605-3"
|
||||
transform="translate(-1.5467961,-0.48613592)">
|
||||
transform="translate(-1.9392553,-0.11820549)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccccccccc"
|
||||
style="fill:url(#linearGradient17610-0);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 520.5,370.48242 -4.01758,3.80078 -6.6e-4,-3.79492 -3.04231,0 0,10.01563 3.04231,0 6.6e-4,-3.79297 4.01758,3.77148 1.01172,0 0.0371,-9.96875 z"
|
||||
transform="matrix(-1,0,0,1,589.01109,-297.98191)"
|
||||
id="path11011-6-2"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 72.839729,82.521675 2.731705,0 0,-10.016275 -2.731705,0 L 72.84,76.59374 68.51011,72.5 67.4632,72.53125 67.5,82.49999 68.51011,82.5 72.84,78.43749 z"
|
||||
style="fill:url(#linearGradient17610-0);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path11011-6-2" />
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccc"
|
||||
style="fill:none;stroke:url(#linearGradient17612-5);stroke-width:0.91056824px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 74.660868,81.408784 0,-7.99274 -0.910568,-6.3e-5"
|
||||
d="m 74.660868,81.408784 0,-7.99274 -1.220453,-6.3e-5"
|
||||
id="path10830-6-2"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
|
||||
inkscape:export-xdpi="90"
|
||||
@@ -89432,16 +89436,16 @@
|
||||
y="-546"
|
||||
transform="matrix(0,-1,-1,0,0,0)" />
|
||||
<path
|
||||
style="fill:url(#linearGradient17165);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 533.51953,371.46094 0,3.04042 3.79492,5.9e-4 -3.77343,4.01953 0,1.01172 9.96875,0.0352 0.0312,-1.04688 -3.80274,-4.01953 3.79688,-5.9e-4 0,-3.04042 z"
|
||||
id="path11011-6-2-1"
|
||||
style="fill:url(#linearGradient17165);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 532.96447,373.70707 0,-2.7317 10.01627,0 0,2.7317 -4.08834,-2.7e-4 4.09374,4.32989 -0.0312,1.04691 -9.96874,-0.0368 -1e-5,-1.01011 4.06251,-4.32989 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc"
|
||||
id="path11013-5-7-1"
|
||||
d="m 541.73615,378.0468 -3.75,-4 -3.75,4"
|
||||
d="m 542.29119,378.53246 -3.75,-4 -3.75,4"
|
||||
style="fill:none;stroke:url(#linearGradient17162);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
@@ -89449,8 +89453,8 @@
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
|
||||
id="path10830-6-2-8"
|
||||
d="m 542.11634,371.83103 -8.26386,0 -6e-5,0.90043"
|
||||
style="fill:none;stroke:url(#linearGradient17838);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
|
||||
d="m 542.67138,372.31669 -8.26386,0 -6e-5,1.20843"
|
||||
style="display:inline;fill:none;stroke:url(#linearGradient17838);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;enable-background:new"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
<g
|
||||
@@ -89464,16 +89468,16 @@
|
||||
y="-504"
|
||||
transform="matrix(0,1,-1,0,0,0)" />
|
||||
<path
|
||||
style="fill:url(#linearGradient17185);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 501.50977,371.4375 -9.96875,0.0352 0,1.01172 3.69336,3.93554 -3.71485,-0.005 0,3.13033 10.01563,0 0,-3.13033 -3.7168,0.007 3.72266,-3.9375 z"
|
||||
id="path11011-6-8"
|
||||
style="fill:url(#linearGradient17185);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 490.96446,376.29293 0,2.7317 10.01628,0 0,-2.7317 -4.08834,2.7e-4 4.09374,-4.32989 -0.0312,-1.04691 -9.96874,0.0368 -10e-6,1.01011 4.06251,4.32989 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc"
|
||||
id="path11013-5-6"
|
||||
d="m 492.23615,371.9532 7.5,0"
|
||||
d="m 492.79119,372.47355 7.5,0"
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
@@ -89481,8 +89485,8 @@
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="C:\Documents and Settings\Tata\Pulpit\BLENDER ICONSET\Kopia blender\.blender\icons\jendrzych's iconset.png"
|
||||
id="path10830-6-2-8-8"
|
||||
d="m 500.10071,377.17478 -8.26386,0 -6e-5,0.90043"
|
||||
style="fill:none;stroke:url(#linearGradient17872);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;display:inline;enable-background:new"
|
||||
d="m 500.65575,377.29722 -8.26386,0 -6e-5,1.29834"
|
||||
style="display:inline;fill:none;stroke:url(#linearGradient17872);stroke-width:0.92071104px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;enable-background:new"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
</g>
|
||||
<g
|
||||
|
Before Width: | Height: | Size: 4.4 MiB After Width: | Height: | Size: 4.4 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Submodule release/datafiles/locale updated: 88158191df...c93ed11a47
Submodule release/scripts/addons updated: a746a84f8a...371960484a
Submodule release/scripts/addons_contrib updated: 029103debc...a8515cfdfe
@@ -103,9 +103,9 @@ def add_object_align_init(context, operator):
|
||||
return location * rotation
|
||||
|
||||
|
||||
def object_data_add(context, obdata, operator=None, use_active_layer=True, name=None):
|
||||
def object_data_add(context, obdata, operator=None, name=None):
|
||||
"""
|
||||
Add an object using the view context and preference to to initialize the
|
||||
Add an object using the view context and preference to initialize the
|
||||
location, rotation and layer.
|
||||
|
||||
:arg context: The context to use.
|
||||
@@ -117,52 +117,24 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
|
||||
:arg name: Optional name
|
||||
:type name: string
|
||||
:return: the newly created object in the scene.
|
||||
:rtype: :class:`bpy.types.ObjectBase`
|
||||
:rtype: :class:`bpy.types.Object`
|
||||
"""
|
||||
scene = context.scene
|
||||
layer = context.render_layer
|
||||
scene_collection = context.scene_collection
|
||||
|
||||
# ugh, could be made nicer
|
||||
for ob in scene.objects:
|
||||
ob.select = False
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
if name is None:
|
||||
name = "Object" if obdata is None else obdata.name
|
||||
|
||||
obj_new = bpy.data.objects.new(name, obdata)
|
||||
|
||||
base = scene.objects.link(obj_new)
|
||||
base.select = True
|
||||
|
||||
v3d = None
|
||||
if context.space_data and context.space_data.type == 'VIEW_3D':
|
||||
v3d = context.space_data
|
||||
|
||||
if v3d and v3d.local_view:
|
||||
base.layers_from_view(context.space_data)
|
||||
|
||||
if operator is not None and any(operator.layers):
|
||||
base.layers = operator.layers
|
||||
else:
|
||||
if use_active_layer:
|
||||
if v3d and v3d.local_view:
|
||||
base.layers[scene.active_layer] = True
|
||||
else:
|
||||
if v3d and not v3d.lock_camera_and_layers:
|
||||
base.layers = [True if i == v3d.active_layer
|
||||
else False for i in range(len(v3d.layers))]
|
||||
else:
|
||||
base.layers = [True if i == scene.active_layer
|
||||
else False for i in range(len(scene.layers))]
|
||||
else:
|
||||
if v3d:
|
||||
base.layers_from_view(context.space_data)
|
||||
|
||||
if operator is not None:
|
||||
operator.layers = base.layers
|
||||
scene_collection.objects.link(obj_new)
|
||||
obj_new.select_set(action='SELECT')
|
||||
|
||||
obj_new.matrix_world = add_object_align_init(context, operator)
|
||||
|
||||
obj_act = scene.objects.active
|
||||
obj_act = layer.objects.active
|
||||
|
||||
# XXX
|
||||
# caused because entering edit-mode does not add a empty undo slot!
|
||||
@@ -174,8 +146,8 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
|
||||
_obdata = bpy.data.meshes.new(name)
|
||||
obj_act = bpy.data.objects.new(_obdata.name, _obdata)
|
||||
obj_act.matrix_world = obj_new.matrix_world
|
||||
scene.objects.link(obj_act)
|
||||
scene.objects.active = obj_act
|
||||
scene_collection.objects.link(obj_act)
|
||||
layer.objects.active = obj_act
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
# need empty undo step
|
||||
bpy.ops.ed.undo_push(message="Enter Editmode")
|
||||
@@ -185,7 +157,7 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
obj_act.select = True
|
||||
obj_act.select_set(action='SELECT')
|
||||
scene.update() # apply location
|
||||
# scene.objects.active = obj_new
|
||||
|
||||
@@ -200,16 +172,14 @@ def object_data_add(context, obdata, operator=None, use_active_layer=True, name=
|
||||
bpy.ops.object.join() # join into the active.
|
||||
if obdata:
|
||||
bpy.data.meshes.remove(obdata)
|
||||
# base is freed, set to active object
|
||||
base = scene.object_bases.active
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
else:
|
||||
scene.objects.active = obj_new
|
||||
layer.objects.active = obj_new
|
||||
if context.user_preferences.edit.use_enter_edit_mode:
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
||||
return base
|
||||
return obj_new
|
||||
|
||||
|
||||
class AddObjectHelper:
|
||||
@@ -230,12 +200,6 @@ class AddObjectHelper:
|
||||
name="Rotation",
|
||||
subtype='EULER',
|
||||
)
|
||||
layers = BoolVectorProperty(
|
||||
name="Layers",
|
||||
size=20,
|
||||
subtype='LAYER',
|
||||
options={'HIDDEN', 'SKIP_SAVE'},
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
|
@@ -330,7 +330,6 @@ kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', shift=True)
|
||||
kmi.properties.unselected = True
|
||||
kmi = km.keymap_items.new('object.hide_render_clear', 'H', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.keymap_items.new('object.hide_render_set', 'H', 'PRESS', ctrl=True)
|
||||
kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS')
|
||||
kmi = km.keymap_items.new('object.delete', 'X', 'PRESS')
|
||||
kmi.properties.use_global = False
|
||||
kmi = km.keymap_items.new('object.delete', 'X', 'PRESS', shift=True)
|
||||
|
@@ -384,7 +384,6 @@ kmi = km.keymap_items.new('object.hide_view_clear', 'H', 'PRESS', shift=True, ct
|
||||
kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', ctrl=True)
|
||||
kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', alt=True)
|
||||
kmi.properties.unselected = True
|
||||
kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS')
|
||||
kmi = km.keymap_items.new('object.delete', 'BACK_SPACE', 'PRESS')
|
||||
kmi = km.keymap_items.new('object.delete', 'DEL', 'PRESS')
|
||||
kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
|
||||
|
@@ -232,7 +232,7 @@ class CLIP_OT_track_to_empty(Operator):
|
||||
ob = None
|
||||
|
||||
ob = bpy.data.objects.new(name=track.name, object_data=None)
|
||||
ob.select = True
|
||||
ob.select_set(action='SELECT')
|
||||
context.scene.objects.link(ob)
|
||||
context.scene.objects.active = ob
|
||||
|
||||
@@ -506,7 +506,7 @@ object's movement caused by this constraint"""
|
||||
# XXX, should probably use context.selected_editable_objects
|
||||
# since selected objects can be from a lib or in hidden layer!
|
||||
for ob in scene.objects:
|
||||
if ob.select:
|
||||
if ob.select_set(action='SELECT'):
|
||||
self._bake_object(scene, ob)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
@@ -62,28 +62,66 @@ class SCENE_OT_freestyle_fill_range_by_selection(bpy.types.Operator):
|
||||
m = linestyle.alpha_modifiers[self.name]
|
||||
else:
|
||||
m = linestyle.thickness_modifiers[self.name]
|
||||
# Find the source object
|
||||
# Find the reference object
|
||||
if m.type == 'DISTANCE_FROM_CAMERA':
|
||||
source = scene.camera
|
||||
ref = scene.camera
|
||||
matrix_to_camera = ref.matrix_world.inverted()
|
||||
elif m.type == 'DISTANCE_FROM_OBJECT':
|
||||
if m.target is None:
|
||||
self.report({'ERROR'}, "Target object not specified")
|
||||
return {'CANCELLED'}
|
||||
source = m.target
|
||||
ref = m.target
|
||||
target_location = ref.location
|
||||
else:
|
||||
self.report({'ERROR'}, "Unexpected modifier type: " + m.type)
|
||||
return {'CANCELLED'}
|
||||
# Find selected mesh objects
|
||||
selection = [ob for ob in scene.objects if ob.select and ob.type == 'MESH' and ob.name != source.name]
|
||||
if selection:
|
||||
# Compute the min/max distance between selected mesh objects and the source
|
||||
# Find selected vertices in editmesh
|
||||
ob = bpy.context.active_object
|
||||
if ob.type == 'MESH' and ob.mode == 'EDIT' and ob.name != ref.name:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
selected_verts = [v for v in bpy.context.active_object.data.vertices if v.select]
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
# Compute the min/max distance from the reference to mesh vertices
|
||||
min_dist = sys.float_info.max
|
||||
max_dist = -min_dist
|
||||
for ob in selection:
|
||||
for vert in ob.data.vertices:
|
||||
dist = (ob.matrix_world * vert.co - source.location).length
|
||||
if m.type == 'DISTANCE_FROM_CAMERA':
|
||||
ob_to_cam = matrix_to_camera * ob.matrix_world
|
||||
for vert in selected_verts:
|
||||
# dist in the camera space
|
||||
dist = (ob_to_cam * vert.co).length
|
||||
min_dist = min(dist, min_dist)
|
||||
max_dist = max(dist, max_dist)
|
||||
elif m.type == 'DISTANCE_FROM_OBJECT':
|
||||
for vert in selected_verts:
|
||||
# dist in the world space
|
||||
dist = (ob.matrix_world * vert.co - target_location).length
|
||||
min_dist = min(dist, min_dist)
|
||||
max_dist = max(dist, max_dist)
|
||||
# Fill the Range Min/Max entries with the computed distances
|
||||
m.range_min = min_dist
|
||||
m.range_max = max_dist
|
||||
return {'FINISHED'}
|
||||
# Find selected mesh objects
|
||||
selection = [ob for ob in scene.objects if ob.select_get() and ob.type == 'MESH' and ob.name != source.name]
|
||||
if selection:
|
||||
# Compute the min/max distance from the reference to mesh vertices
|
||||
min_dist = sys.float_info.max
|
||||
max_dist = -min_dist
|
||||
if m.type == 'DISTANCE_FROM_CAMERA':
|
||||
for ob in selection:
|
||||
ob_to_cam = matrix_to_camera * ob.matrix_world
|
||||
for vert in ob.data.vertices:
|
||||
# dist in the camera space
|
||||
dist = (ob_to_cam * vert.co).length
|
||||
min_dist = min(dist, min_dist)
|
||||
max_dist = max(dist, max_dist)
|
||||
elif m.type == 'DISTANCE_FROM_OBJECT':
|
||||
for ob in selection:
|
||||
for vert in ob.data.vertices:
|
||||
# dist in the world space
|
||||
dist = (ob.matrix_world * vert.co - target_location).length
|
||||
min_dist = min(dist, min_dist)
|
||||
max_dist = max(dist, max_dist)
|
||||
# Fill the Range Min/Max entries with the computed distances
|
||||
m.range_min = min_dist
|
||||
m.range_max = max_dist
|
||||
|
@@ -81,16 +81,18 @@ class SelectPattern(Operator):
|
||||
# Can be pose bones or objects
|
||||
for item in items:
|
||||
if pattern_match(item.name, self.pattern):
|
||||
item.select = True
|
||||
|
||||
# hrmf, perhaps there should be a utility function for this.
|
||||
if is_ebone:
|
||||
item.select = True
|
||||
item.select_head = True
|
||||
item.select_tail = True
|
||||
if item.use_connect:
|
||||
item_parent = item.parent
|
||||
if item_parent is not None:
|
||||
item_parent.select_tail = True
|
||||
else:
|
||||
item.select_set(action='SELECT')
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -136,7 +138,7 @@ class SelectCamera(Operator):
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
scene.objects.active = camera
|
||||
camera.hide = False
|
||||
camera.select = True
|
||||
camera.select_set(action='SELECT')
|
||||
return {'FINISHED'}
|
||||
|
||||
return {'CANCELLED'}
|
||||
@@ -202,7 +204,7 @@ class SelectHierarchy(Operator):
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
for obj in select_new:
|
||||
obj.select = True
|
||||
obj.select_set(action='SELECT')
|
||||
|
||||
scene.objects.active = act_new
|
||||
return {'FINISHED'}
|
||||
@@ -644,8 +646,8 @@ class MakeDupliFace(Operator):
|
||||
ob_new.use_dupli_faces_scale = True
|
||||
ob_new.dupli_faces_scale = 1.0 / SCALE_FAC
|
||||
|
||||
ob_inst.select = True
|
||||
ob_new.select = True
|
||||
ob_inst.select_set(action='SELECT')
|
||||
ob_new.select_set(action='SELECT')
|
||||
|
||||
def execute(self, context):
|
||||
self._main(context)
|
||||
@@ -664,7 +666,7 @@ class IsolateTypeRender(Operator):
|
||||
|
||||
for obj in context.visible_objects:
|
||||
|
||||
if obj.select:
|
||||
if obj.select_get():
|
||||
obj.hide_render = False
|
||||
else:
|
||||
if obj.type == act_type:
|
||||
@@ -1029,8 +1031,8 @@ class LodGenerate(Operator):
|
||||
for level in ob.lod_levels[1:]:
|
||||
level.object.hide = level.object.hide_render = True
|
||||
|
||||
lod.select = False
|
||||
ob.select = True
|
||||
lod.select_set(action='DESELECT')
|
||||
ob.select_set(action='SELECT')
|
||||
scene.objects.active = ob
|
||||
|
||||
return {'FINISHED'}
|
||||
|
@@ -63,7 +63,7 @@ class CopyRigidbodySettings(Operator):
|
||||
# deselect all but mesh objects
|
||||
for o in context.selected_objects:
|
||||
if o.type != 'MESH':
|
||||
o.select = False
|
||||
o.select_set(action='DESELECT')
|
||||
elif o.rigid_body is None:
|
||||
# Add rigidbody to object!
|
||||
scene.objects.active = o
|
||||
@@ -125,7 +125,7 @@ class BakeToKeyframes(Operator):
|
||||
# filter objects selection
|
||||
for obj in context.selected_objects:
|
||||
if not obj.rigid_body or obj.rigid_body.type != 'ACTIVE':
|
||||
obj.select = False
|
||||
obj.select_set(action='DESELECT')
|
||||
|
||||
objects = context.selected_objects
|
||||
|
||||
@@ -258,7 +258,7 @@ class ConnectRigidBodies(Operator):
|
||||
ob.location = loc
|
||||
context.scene.objects.link(ob)
|
||||
context.scene.objects.active = ob
|
||||
ob.select = True
|
||||
ob.select_set(action='SELECT')
|
||||
|
||||
bpy.ops.rigidbody.constraint_add()
|
||||
con_obj = context.active_object
|
||||
@@ -303,7 +303,7 @@ class ConnectRigidBodies(Operator):
|
||||
# restore selection
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
for obj in objects:
|
||||
obj.select = True
|
||||
obj.select_set(action='SELECT')
|
||||
scene.objects.active = obj_act
|
||||
return {'FINISHED'}
|
||||
else:
|
||||
|
@@ -29,6 +29,7 @@ if "bpy" in locals():
|
||||
|
||||
_modules = [
|
||||
"properties_animviz",
|
||||
"properties_collection",
|
||||
"properties_constraint",
|
||||
"properties_data_armature",
|
||||
"properties_data_bone",
|
||||
@@ -69,6 +70,7 @@ _modules = [
|
||||
"space_graph",
|
||||
"space_image",
|
||||
"space_info",
|
||||
"space_collections",
|
||||
"space_logic",
|
||||
"space_nla",
|
||||
"space_node",
|
||||
|
128
release/scripts/startup/bl_ui/properties_collection.py
Normal file
128
release/scripts/startup/bl_ui/properties_collection.py
Normal file
@@ -0,0 +1,128 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
from bpy.types import Panel, UIList
|
||||
|
||||
|
||||
class CollectionButtonsPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "collection"
|
||||
|
||||
|
||||
class COLLECTION_PT_context_collection(CollectionButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
space = context.space_data
|
||||
|
||||
collection = context.layer_collection
|
||||
name = collection.name
|
||||
if name == 'Master Collection':
|
||||
layout.label(text=name, icon='COLLAPSEMENU')
|
||||
else:
|
||||
layout.prop(collection, "name", text="", icon='COLLAPSEMENU')
|
||||
|
||||
|
||||
class COLLECTION_UL_objects(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
# assert(isinstance(item, bpy.types.Object)
|
||||
ob = item
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
layout.label(ob.name, icon_value=icon)
|
||||
|
||||
elif self.layout_type == 'GRID':
|
||||
layout.alignment = 'CENTER'
|
||||
layout.label("", icon_value=icon)
|
||||
|
||||
|
||||
class COLLECTION_PT_objects(CollectionButtonsPanel, Panel):
|
||||
bl_label = "Objects"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
collection = context.scene_collection
|
||||
|
||||
row = layout.row()
|
||||
row.template_list("COLLECTION_UL_objects", "name", collection, "objects", collection.objects, "active_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("collections.objects_add", icon='ZOOMIN', text="")
|
||||
col.operator("collections.objects_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("collections.objects_select", text="Select")
|
||||
row.operator("collections.objects_deselect", text="Deselect")
|
||||
|
||||
|
||||
def template_engine_settings(col, settings, name, use_icon_view=False):
|
||||
icons = {
|
||||
False: 'ZOOMIN',
|
||||
True: 'X',
|
||||
}
|
||||
|
||||
use_name = "{0}_use".format(name)
|
||||
use = getattr(settings, use_name)
|
||||
|
||||
row = col.row()
|
||||
col = row.column()
|
||||
col.active = use
|
||||
|
||||
if use_icon_view:
|
||||
col.template_icon_view(settings, name)
|
||||
else:
|
||||
col.prop(settings, name)
|
||||
|
||||
row.prop(settings, "{}_use".format(name), text="", icon=icons[use], emboss=False)
|
||||
|
||||
|
||||
class COLLECTION_PT_clay_settings(CollectionButtonsPanel, Panel):
|
||||
bl_label = "Render Settings"
|
||||
COMPAT_ENGINES = {'BLENDER_CLAY'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return scene and (scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
collection = context.layer_collection
|
||||
settings = collection.get_engine_settings()
|
||||
|
||||
col = layout.column()
|
||||
template_engine_settings(col, settings, "type")
|
||||
template_engine_settings(col, settings, "matcap_icon", use_icon_view=True)
|
||||
template_engine_settings(col, settings, "matcap_rotation")
|
||||
template_engine_settings(col, settings, "matcap_hue")
|
||||
template_engine_settings(col, settings, "matcap_saturation")
|
||||
template_engine_settings(col, settings, "matcap_value")
|
||||
template_engine_settings(col, settings, "ssao_factor_cavity")
|
||||
template_engine_settings(col, settings, "ssao_factor_edge")
|
||||
template_engine_settings(col, settings, "ssao_distance")
|
||||
template_engine_settings(col, settings, "ssao_attenuation")
|
||||
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
bpy.utils.register_module(__name__)
|
@@ -469,8 +469,86 @@ class SceneButtonsPanel:
|
||||
bl_context = "scene"
|
||||
|
||||
|
||||
class SCENE_PT_game_physics(SceneButtonsPanel, Panel):
|
||||
bl_label = "Physics"
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(gs, "physics_engine", text="Engine")
|
||||
if gs.physics_engine != 'NONE':
|
||||
layout.prop(gs, "physics_gravity", text="Gravity")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics Steps:")
|
||||
sub = col.column(align=True)
|
||||
sub.prop(gs, "physics_step_max", text="Max")
|
||||
sub.prop(gs, "physics_step_sub", text="Substeps")
|
||||
col.prop(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Logic Steps:")
|
||||
col.prop(gs, "logic_step_max", text="Max")
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Physics Deactivation:")
|
||||
sub = col.row(align=True)
|
||||
sub.prop(gs, "deactivation_linear_threshold", text="Linear Threshold")
|
||||
sub.prop(gs, "deactivation_angular_threshold", text="Angular Threshold")
|
||||
sub = col.row()
|
||||
sub.prop(gs, "deactivation_time", text="Time")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
|
||||
sub = col.column()
|
||||
sub.active = gs.use_occlusion_culling
|
||||
sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
|
||||
|
||||
else:
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics Steps:")
|
||||
col.prop(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Logic Steps:")
|
||||
col.prop(gs, "logic_step_max", text="Max")
|
||||
|
||||
|
||||
class SCENE_PT_game_physics_obstacles(SceneButtonsPanel, Panel):
|
||||
bl_label = "Obstacle Simulation"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(gs, "obstacle_simulation", text="Type")
|
||||
if gs.obstacle_simulation != 'NONE':
|
||||
layout.prop(gs, "level_height")
|
||||
layout.prop(gs, "show_obstacle_simulation")
|
||||
|
||||
|
||||
class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
|
||||
bl_label = "Navigation mesh"
|
||||
bl_label = "Navigation Mesh"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@@ -484,7 +562,7 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
|
||||
|
||||
rd = context.scene.game_settings.recast_data
|
||||
|
||||
layout.operator("mesh.navmesh_make", text="Build navigation mesh")
|
||||
layout.operator("mesh.navmesh_make", text="Build Navigation Mesh")
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Rasterization:")
|
||||
@@ -656,83 +734,6 @@ class WORLD_PT_game_mist(WorldButtonsPanel, Panel):
|
||||
layout.prop(world.mist_settings, "intensity", text="Minimum Intensity")
|
||||
|
||||
|
||||
class WORLD_PT_game_physics(WorldButtonsPanel, Panel):
|
||||
bl_label = "Physics"
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(gs, "physics_engine", text="Engine")
|
||||
if gs.physics_engine != 'NONE':
|
||||
layout.prop(gs, "physics_gravity", text="Gravity")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics Steps:")
|
||||
sub = col.column(align=True)
|
||||
sub.prop(gs, "physics_step_max", text="Max")
|
||||
sub.prop(gs, "physics_step_sub", text="Substeps")
|
||||
col.prop(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Logic Steps:")
|
||||
col.prop(gs, "logic_step_max", text="Max")
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="Physics Deactivation:")
|
||||
sub = col.row(align=True)
|
||||
sub.prop(gs, "deactivation_linear_threshold", text="Linear Threshold")
|
||||
sub.prop(gs, "deactivation_angular_threshold", text="Angular Threshold")
|
||||
sub = col.row()
|
||||
sub.prop(gs, "deactivation_time", text="Time")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(gs, "use_occlusion_culling", text="Occlusion Culling")
|
||||
sub = col.column()
|
||||
sub.active = gs.use_occlusion_culling
|
||||
sub.prop(gs, "occlusion_culling_resolution", text="Resolution")
|
||||
|
||||
else:
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics Steps:")
|
||||
col.prop(gs, "fps", text="FPS")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Logic Steps:")
|
||||
col.prop(gs, "logic_step_max", text="Max")
|
||||
|
||||
|
||||
class WORLD_PT_game_physics_obstacles(WorldButtonsPanel, Panel):
|
||||
bl_label = "Obstacle Simulation"
|
||||
COMPAT_ENGINES = {'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.world and scene.render.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
gs = context.scene.game_settings
|
||||
|
||||
layout.prop(gs, "obstacle_simulation", text="Type")
|
||||
if gs.obstacle_simulation != 'NONE':
|
||||
layout.prop(gs, "level_height")
|
||||
layout.prop(gs, "show_obstacle_simulation")
|
||||
|
||||
|
||||
class DataButtonsPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
|
@@ -106,7 +106,7 @@ class MaterialButtonsPanel:
|
||||
class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -1052,5 +1052,25 @@ class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel):
|
||||
_context_path = "material"
|
||||
_property_type = bpy.types.Material
|
||||
|
||||
|
||||
class MATERIAL_PT_clay_settings(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Matcap"
|
||||
COMPAT_ENGINES = {'BLENDER_CLAY'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout;
|
||||
settings = context.material.clay_settings
|
||||
# layout.template_icon_view(settings, "matcap_icon")
|
||||
# layout.prop(settings, "type")
|
||||
# layout.prop(settings, "matcap_rotation")
|
||||
# layout.prop(settings, "matcap_hue")
|
||||
# layout.prop(settings, "matcap_saturation")
|
||||
# layout.prop(settings, "matcap_value")
|
||||
# layout.prop(settings, "ssao_factor_cavity")
|
||||
# layout.prop(settings, "ssao_factor_edge")
|
||||
# layout.prop(settings, "ssao_distance")
|
||||
# layout.prop(settings, "ssao_attenuation")
|
||||
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
bpy.utils.register_module(__name__)
|
||||
|
@@ -377,7 +377,7 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel):
|
||||
sub.active = rd.use_stamp_note
|
||||
sub.prop(rd, "stamp_note_text", text="")
|
||||
if rd.use_sequencer:
|
||||
layout.label("Sequencer")
|
||||
layout.label("Sequencer:")
|
||||
layout.prop(rd, "use_stamp_strip_meta")
|
||||
|
||||
|
||||
@@ -584,5 +584,24 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
|
||||
sub.prop(rd, "bake_user_scale", text="User Scale")
|
||||
|
||||
|
||||
class RENDER_PT_clay(RenderButtonsPanel, Panel):
|
||||
bl_label = "Default Clay"
|
||||
COMPAT_ENGINES = {'BLENDER_CLAY'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout;
|
||||
settings = context.scene.active_engine_settings
|
||||
layout.template_icon_view(settings, "matcap_icon")
|
||||
layout.prop(settings, "matcap_rotation")
|
||||
layout.prop(settings, "matcap_hue")
|
||||
layout.prop(settings, "matcap_saturation")
|
||||
layout.prop(settings, "matcap_value")
|
||||
layout.prop(settings, "ssao_factor_cavity")
|
||||
layout.prop(settings, "ssao_factor_edge")
|
||||
layout.prop(settings, "ssao_distance")
|
||||
layout.prop(settings, "ssao_attenuation")
|
||||
layout.prop(settings, "ssao_samples")
|
||||
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
bpy.utils.register_module(__name__)
|
||||
|
@@ -35,7 +35,7 @@ class RenderLayerButtonsPanel:
|
||||
|
||||
class RENDERLAYER_UL_renderlayers(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
# assert(isinstance(item, bpy.types.SceneRenderLayer)
|
||||
# assert(isinstance(item, bpy.types.SceneLayer)
|
||||
layer = item
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
layout.prop(layer, "name", text="", icon_value=icon, emboss=False)
|
||||
@@ -48,7 +48,7 @@ class RENDERLAYER_UL_renderlayers(UIList):
|
||||
class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
|
||||
bl_label = "Layer List"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME', 'BLENDER_CLAY'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -62,7 +62,7 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
|
||||
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
col.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)
|
||||
col.template_list("RENDERLAYER_UL_renderlayers", "", scene, "render_layers", scene.render_layers, "active_index", rows=2)
|
||||
|
||||
col = row.column()
|
||||
sub = col.column(align=True)
|
||||
@@ -71,103 +71,6 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
|
||||
col.prop(rd, "use_single_layer", icon_only=True)
|
||||
|
||||
|
||||
class RENDERLAYER_PT_layer_options(RenderLayerButtonsPanel, Panel):
|
||||
bl_label = "Layer"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
rd = scene.render
|
||||
rl = rd.layers.active
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(scene, "layers", text="Scene")
|
||||
col.label(text="")
|
||||
col.prop(rl, "light_override", text="Lights")
|
||||
col.prop(rl, "material_override", text="Material")
|
||||
|
||||
col = split.column()
|
||||
col.prop(rl, "layers", text="Layer")
|
||||
col.prop(rl, "layers_zmask", text="Mask Layer")
|
||||
|
||||
layout.separator()
|
||||
layout.label(text="Include:")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(rl, "use_zmask")
|
||||
row = col.row()
|
||||
row.prop(rl, "invert_zmask", text="Negate")
|
||||
row.active = rl.use_zmask
|
||||
col.prop(rl, "use_all_z")
|
||||
|
||||
col = split.column()
|
||||
col.prop(rl, "use_solid")
|
||||
col.prop(rl, "use_halo")
|
||||
col.prop(rl, "use_ztransp")
|
||||
|
||||
col = split.column()
|
||||
col.prop(rl, "use_sky")
|
||||
col.prop(rl, "use_edge_enhance")
|
||||
col.prop(rl, "use_strand")
|
||||
if bpy.app.build_options.freestyle:
|
||||
row = col.row()
|
||||
row.prop(rl, "use_freestyle")
|
||||
row.active = rd.use_freestyle
|
||||
|
||||
|
||||
class RENDERLAYER_PT_layer_passes(RenderLayerButtonsPanel, Panel):
|
||||
bl_label = "Passes"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER'}
|
||||
|
||||
@staticmethod
|
||||
def draw_pass_type_buttons(box, rl, pass_type):
|
||||
# property names
|
||||
use_pass_type = "use_pass_" + pass_type
|
||||
exclude_pass_type = "exclude_" + pass_type
|
||||
# draw pass type buttons
|
||||
row = box.row()
|
||||
row.prop(rl, use_pass_type)
|
||||
row.prop(rl, exclude_pass_type, text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
rd = scene.render
|
||||
rl = rd.layers.active
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop(rl, "use_pass_combined")
|
||||
col.prop(rl, "use_pass_z")
|
||||
col.prop(rl, "use_pass_vector")
|
||||
col.prop(rl, "use_pass_normal")
|
||||
col.prop(rl, "use_pass_uv")
|
||||
col.prop(rl, "use_pass_mist")
|
||||
col.prop(rl, "use_pass_object_index")
|
||||
col.prop(rl, "use_pass_material_index")
|
||||
col.prop(rl, "use_pass_color")
|
||||
|
||||
col = split.column()
|
||||
col.prop(rl, "use_pass_diffuse")
|
||||
self.draw_pass_type_buttons(col, rl, "specular")
|
||||
self.draw_pass_type_buttons(col, rl, "shadow")
|
||||
self.draw_pass_type_buttons(col, rl, "emit")
|
||||
self.draw_pass_type_buttons(col, rl, "ambient_occlusion")
|
||||
self.draw_pass_type_buttons(col, rl, "environment")
|
||||
self.draw_pass_type_buttons(col, rl, "indirect")
|
||||
self.draw_pass_type_buttons(col, rl, "reflection")
|
||||
self.draw_pass_type_buttons(col, rl, "refraction")
|
||||
|
||||
|
||||
class RENDERLAYER_UL_renderviews(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
# assert(isinstance(item, bpy.types.SceneRenderView)
|
||||
|
41
release/scripts/startup/bl_ui/space_collections.py
Normal file
41
release/scripts/startup/bl_ui/space_collections.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
from bpy.types import Header, Menu
|
||||
|
||||
|
||||
class COLLECTIONS_HT_header(Header):
|
||||
bl_space_type = 'COLLECTION_MANAGER'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.template_header()
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("collections.collection_new", text="", icon='NEW')
|
||||
row.operator("collections.override_new", text="", icon='LINK_AREA')
|
||||
row.operator("collections.collection_link", text="", icon='LINKED')
|
||||
row.operator("collections.collection_unlink", text="", icon='UNLINKED')
|
||||
row.operator("collections.delete", text="", icon='X')
|
||||
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
bpy.utils.register_module(__name__)
|
@@ -93,7 +93,8 @@ class OUTLINER_MT_view(Menu):
|
||||
layout.separator()
|
||||
layout.operator("outliner.show_active")
|
||||
|
||||
layout.operator("outliner.show_one_level")
|
||||
layout.operator("outliner.show_one_level", text="Show One Level")
|
||||
layout.operator("outliner.show_one_level", text="Hide One Level").open = False
|
||||
layout.operator("outliner.show_hierarchy")
|
||||
|
||||
layout.separator()
|
||||
|
@@ -435,15 +435,9 @@ class SEQUENCER_MT_strip(Menu):
|
||||
layout.operator("sequencer.crossfade_sounds")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("sequencer.meta_make")
|
||||
layout.operator("sequencer.meta_separate")
|
||||
|
||||
#if (ed && (ed->metastack.first || (ed->act_seq && ed->act_seq->type == SEQ_META))) {
|
||||
# uiItemS(layout);
|
||||
# uiItemO(layout, NULL, 0, "sequencer.meta_toggle");
|
||||
#}
|
||||
|
||||
layout.separator()
|
||||
layout.operator("sequencer.reload", text="Reload Strips")
|
||||
layout.operator("sequencer.reload", text="Reload Strips and Adjust Length").adjust_length = True
|
||||
|
@@ -634,7 +634,6 @@ class VIEW3D_MT_select_object(Menu):
|
||||
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
|
||||
layout.operator("object.select_random", text="Random")
|
||||
layout.operator("object.select_mirror", text="Mirror")
|
||||
layout.operator("object.select_by_layer", text="Select All by Layer")
|
||||
layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...")
|
||||
layout.operator("object.select_camera", text="Select Camera")
|
||||
|
||||
@@ -1311,15 +1310,6 @@ class VIEW3D_MT_object(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
if is_local_view:
|
||||
layout.operator_context = 'EXEC_REGION_WIN'
|
||||
layout.operator("object.move_to_layer", text="Move out of Local View")
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
else:
|
||||
layout.operator("object.move_to_layer", text="Move to Layer...")
|
||||
|
||||
layout.menu("VIEW3D_MT_object_showhide")
|
||||
|
||||
layout.operator_menu_enum("object.convert", "target")
|
||||
|
||||
|
||||
@@ -1597,17 +1587,6 @@ class VIEW3D_MT_object_quick_effects(Menu):
|
||||
layout.operator("object.quick_fluid")
|
||||
|
||||
|
||||
class VIEW3D_MT_object_showhide(Menu):
|
||||
bl_label = "Show/Hide"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("object.hide_view_clear", text="Show Hidden")
|
||||
layout.operator("object.hide_view_set", text="Hide Selected").unselected = False
|
||||
layout.operator("object.hide_view_set", text="Hide Unselected").unselected = True
|
||||
|
||||
|
||||
class VIEW3D_MT_make_single_user(Menu):
|
||||
bl_label = "Make Single User"
|
||||
|
||||
@@ -3167,6 +3146,74 @@ class VIEW3D_PT_viewport_debug(Panel):
|
||||
col.row(align=True).prop(view, "debug_background", expand=True)
|
||||
|
||||
|
||||
class VIEW3D_PT_collections_editor(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_label = "Collections"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.space_data
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layer = context.render_layer
|
||||
active_collection = context.layer_collection
|
||||
|
||||
col = layout.column()
|
||||
box = col.box()
|
||||
|
||||
index = -1
|
||||
for collection in layer.collections:
|
||||
index = self._draw_layer_collection(box, index, active_collection, collection, True, True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("collections.collection_new", text="", icon='NEW')
|
||||
row.operator("collections.override_new", text="", icon='LINK_AREA')
|
||||
row.operator("collections.collection_link", text="", icon='LINKED')
|
||||
row.operator("collections.collection_unlink", text="", icon='UNLINKED')
|
||||
row.operator("collections.delete", text="", icon='X')
|
||||
|
||||
def _draw_layer_collection(self, box, index, active_collection, collection, is_active, is_draw, depth=0):
|
||||
index += 1
|
||||
nested_collections = collection.collections
|
||||
|
||||
if is_draw:
|
||||
row = box.row()
|
||||
row.active = is_active
|
||||
is_collection_selected = (collection == active_collection)
|
||||
|
||||
if is_collection_selected:
|
||||
sub_box = row.box()
|
||||
row = sub_box.row()
|
||||
|
||||
row.label(text="{0}{1}{2}".format(
|
||||
" " * depth,
|
||||
u'\u21b3 ' if depth else "",
|
||||
collection.name))
|
||||
|
||||
row.prop(collection, "hide", text="", emboss=False)
|
||||
row.prop(collection, "hide_select", text="", emboss=False)
|
||||
|
||||
row.operator("collections.select", text="", icon='BLANK1' if is_collection_selected else 'HAND', emboss=False).collection_index=index
|
||||
|
||||
if nested_collections:
|
||||
row.prop(collection, "is_unfolded", text="", emboss=False)
|
||||
else:
|
||||
row.label(icon='BLANK1')
|
||||
|
||||
if not collection.is_unfolded:
|
||||
is_draw = False
|
||||
|
||||
is_active &= not collection.hide
|
||||
|
||||
for nested_collection in nested_collections:
|
||||
index = self._draw_layer_collection(box, index, active_collection, nested_collection, is_active, is_draw, depth + 1)
|
||||
|
||||
return index
|
||||
|
||||
|
||||
class VIEW3D_PT_grease_pencil(GreasePencilDataPanel, Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
|
@@ -18,7 +18,7 @@ bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
for obj in selection:
|
||||
|
||||
obj.select = True
|
||||
obj.select_set(action='SELECT')
|
||||
|
||||
# some exporters only use the active object
|
||||
scene.objects.active = obj
|
||||
@@ -31,7 +31,7 @@ for obj in selection:
|
||||
## Can be used for multiple formats
|
||||
# bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
|
||||
|
||||
obj.select = False
|
||||
obj.select_set(action='DESELECT')
|
||||
|
||||
print("written:", fn)
|
||||
|
||||
@@ -39,4 +39,4 @@ for obj in selection:
|
||||
scene.objects.active = obj_active
|
||||
|
||||
for obj in selection:
|
||||
obj.select = True
|
||||
obj.select_set(action='SELECT')
|
||||
|
@@ -67,7 +67,7 @@ def main(context, event):
|
||||
# now we have the object under the mouse cursor,
|
||||
# we could do lots of stuff but for the example just select.
|
||||
if best_obj is not None:
|
||||
best_obj.select = True
|
||||
best_obj.select_set(action='SELECT')
|
||||
context.scene.objects.active = best_obj
|
||||
|
||||
|
||||
|
@@ -100,6 +100,7 @@ add_subdirectory(windowmanager)
|
||||
add_subdirectory(blenkernel)
|
||||
add_subdirectory(blenlib)
|
||||
add_subdirectory(bmesh)
|
||||
add_subdirectory(draw)
|
||||
add_subdirectory(render)
|
||||
add_subdirectory(blenfont)
|
||||
add_subdirectory(blentranslation)
|
||||
|
@@ -39,14 +39,10 @@ set(INC
|
||||
|
||||
set(INC_SYS
|
||||
${ALEMBIC_INCLUDE_DIRS}
|
||||
${BOOST_INCLUDE_DIR}
|
||||
${HDF5_INCLUDE_DIRS}
|
||||
${OPENEXR_INCLUDE_DIRS}
|
||||
)
|
||||
if(APPLE OR WIN32)
|
||||
list(APPEND INC_SYS
|
||||
${BOOST_INCLUDE_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
intern/abc_archive.cc
|
||||
|
@@ -341,7 +341,7 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
|
||||
|
||||
void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx)
|
||||
{
|
||||
Base *base = static_cast<Base *>(m_scene->base.first);
|
||||
BaseLegacy *base = static_cast<BaseLegacy *>(m_scene->base.first);
|
||||
|
||||
while (base) {
|
||||
Object *ob = base->object;
|
||||
@@ -366,7 +366,7 @@ void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx)
|
||||
|
||||
void AbcExporter::createTransformWritersFlat()
|
||||
{
|
||||
Base *base = static_cast<Base *>(m_scene->base.first);
|
||||
BaseLegacy *base = static_cast<BaseLegacy *>(m_scene->base.first);
|
||||
|
||||
while (base) {
|
||||
Object *ob = base->object;
|
||||
@@ -445,7 +445,7 @@ void AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupl
|
||||
|
||||
void AbcExporter::createShapeWriters(EvaluationContext *eval_ctx)
|
||||
{
|
||||
Base *base = static_cast<Base *>(m_scene->base.first);
|
||||
BaseLegacy *base = static_cast<BaseLegacy *>(m_scene->base.first);
|
||||
|
||||
while (base) {
|
||||
Object *ob = base->object;
|
||||
|
@@ -45,6 +45,7 @@ int BLF_init(int points, int dpi);
|
||||
void BLF_exit(void);
|
||||
void BLF_default_dpi(int dpi);
|
||||
void BLF_default_set(int fontid);
|
||||
int BLF_default(void); /* get default font ID so we can pass it to other functions */
|
||||
|
||||
void BLF_cache_clear(void);
|
||||
|
||||
@@ -64,6 +65,16 @@ void BLF_aspect(int fontid, float x, float y, float z);
|
||||
void BLF_position(int fontid, float x, float y, float z);
|
||||
void BLF_size(int fontid, int size, int dpi);
|
||||
|
||||
/* goal: small but useful color API */
|
||||
void BLF_color4ubv(int fontid, const unsigned char rgba[4]);
|
||||
void BLF_color3ubv(int fontid, const unsigned char rgb[3]);
|
||||
void BLF_color3ubv_alpha(int fontid, const unsigned char rgb[3], unsigned char alpha);
|
||||
void BLF_color3ub(int fontid, unsigned char r, unsigned char g, unsigned char b);
|
||||
void BLF_color4fv(int fontid, const float rgba[4]);
|
||||
void BLF_color3f(int fontid, float r, float g, float b);
|
||||
void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha);
|
||||
/* also available: UI_FontThemeColor(fontid, colorid) */
|
||||
|
||||
/* Set a 4x4 matrix to be multiplied before draw the text.
|
||||
* Remember that you need call BLF_enable(BLF_MATRIX)
|
||||
* to enable this.
|
||||
@@ -125,27 +136,11 @@ void BLF_width_and_height(int fontid, const char *str, size_t len, float *r_widt
|
||||
*/
|
||||
float BLF_fixed_width(int fontid) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
/* and this two function return the width and height
|
||||
* of the string, using the default font and both value
|
||||
* are multiplied by the aspect of the font.
|
||||
*/
|
||||
void BLF_width_and_height_default(const char *str, size_t len, float *r_width, float *r_height) ATTR_NONNULL();
|
||||
float BLF_width_default(const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
|
||||
float BLF_height_default(const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
|
||||
|
||||
/* Set rotation for default font. */
|
||||
void BLF_rotation_default(float angle);
|
||||
|
||||
/* Enable/disable options to the default font. */
|
||||
void BLF_enable_default(int option);
|
||||
void BLF_disable_default(int option);
|
||||
|
||||
/* By default, rotation and clipping are disable and
|
||||
* have to be enable/disable using BLF_enable/disable.
|
||||
*/
|
||||
void BLF_rotation(int fontid, float angle);
|
||||
void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax);
|
||||
void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax);
|
||||
void BLF_wordwrap(int fontid, int wrap_width);
|
||||
|
||||
#if BLF_BLUR_ENABLE
|
||||
|
@@ -50,7 +50,6 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BLF_api.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
@@ -176,6 +175,12 @@ void BLF_default_set(int fontid)
|
||||
}
|
||||
}
|
||||
|
||||
int BLF_default()
|
||||
{
|
||||
ASSERT_DEFAULT_SET;
|
||||
return global_font_default;
|
||||
}
|
||||
|
||||
int BLF_load(const char *name)
|
||||
{
|
||||
FontBLF *font;
|
||||
@@ -359,24 +364,6 @@ void BLF_disable(int fontid, int option)
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_enable_default(int option)
|
||||
{
|
||||
FontBLF *font = blf_get(global_font_default);
|
||||
|
||||
if (font) {
|
||||
font->flags |= option;
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_disable_default(int option)
|
||||
{
|
||||
FontBLF *font = blf_get(global_font_default);
|
||||
|
||||
if (font) {
|
||||
font->flags &= ~option;
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_aspect(int fontid, float x, float y, float z)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
@@ -466,6 +453,70 @@ void BLF_blur(int fontid, int size)
|
||||
}
|
||||
#endif
|
||||
|
||||
void BLF_color4ubv(int fontid, const unsigned char rgba[4])
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
||||
if (font) {
|
||||
font->color[0] = rgba[0];
|
||||
font->color[1] = rgba[1];
|
||||
font->color[2] = rgba[2];
|
||||
font->color[3] = rgba[3];
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_color3ubv_alpha(int fontid, const unsigned char rgb[3], unsigned char alpha)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
||||
if (font) {
|
||||
font->color[0] = rgb[0];
|
||||
font->color[1] = rgb[1];
|
||||
font->color[2] = rgb[2];
|
||||
font->color[3] = alpha;
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_color3ubv(int fontid, const unsigned char rgb[3])
|
||||
{
|
||||
BLF_color3ubv_alpha(fontid, rgb, 255);
|
||||
}
|
||||
|
||||
void BLF_color3ub(int fontid, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
||||
if (font) {
|
||||
font->color[0] = r;
|
||||
font->color[1] = g;
|
||||
font->color[2] = b;
|
||||
font->color[3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_color4fv(int fontid, const float rgba[4])
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
||||
if (font) {
|
||||
rgba_float_to_uchar(font->color, rgba);
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
|
||||
{
|
||||
float rgba[4];
|
||||
copy_v3_v3(rgba, rgb);
|
||||
rgba[3] = alpha;
|
||||
BLF_color4fv(fontid, rgba);
|
||||
}
|
||||
|
||||
void BLF_color3f(int fontid, float r, float g, float b)
|
||||
{
|
||||
float rgba[4] = { r, g, b, 1.0f };
|
||||
BLF_color4fv(fontid, rgba);
|
||||
}
|
||||
|
||||
void BLF_draw_default(float x, float y, float z, const char *str, size_t len)
|
||||
{
|
||||
ASSERT_DEFAULT_SET;
|
||||
@@ -485,15 +536,6 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l
|
||||
BLF_draw_ascii(global_font_default, str, len); /* XXX, use real length */
|
||||
}
|
||||
|
||||
void BLF_rotation_default(float angle)
|
||||
{
|
||||
FontBLF *font = blf_get(global_font_default);
|
||||
|
||||
if (font) {
|
||||
font->angle = angle;
|
||||
}
|
||||
}
|
||||
|
||||
static void blf_draw_gl__start(FontBLF *font)
|
||||
{
|
||||
/*
|
||||
@@ -517,10 +559,6 @@ static void blf_draw_gl__start(FontBLF *font)
|
||||
if (font->flags & BLF_ROTATION) /* radians -> degrees */
|
||||
gpuRotateAxis(RAD2DEG(font->angle), 'Z');
|
||||
|
||||
float temp_color[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, temp_color); /* TODO(merwin): new BLF_color function? */
|
||||
rgba_float_to_uchar(font->color, temp_color);
|
||||
|
||||
#ifndef BLF_STANDALONE
|
||||
VertexFormat *format = immVertexFormat();
|
||||
unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
|
||||
@@ -698,14 +736,6 @@ void BLF_width_and_height(int fontid, const char *str, size_t len, float *r_widt
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_width_and_height_default(const char *str, size_t len, float *r_width, float *r_height)
|
||||
{
|
||||
ASSERT_DEFAULT_SET;
|
||||
|
||||
BLF_size(global_font_default, global_font_points, global_font_dpi);
|
||||
BLF_width_and_height(global_font_default, str, len, r_width, r_height);
|
||||
}
|
||||
|
||||
float BLF_width_ex(
|
||||
int fontid, const char *str, size_t len,
|
||||
struct ResultBLF *r_info)
|
||||
@@ -736,14 +766,6 @@ float BLF_fixed_width(int fontid)
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float BLF_width_default(const char *str, size_t len)
|
||||
{
|
||||
ASSERT_DEFAULT_SET;
|
||||
|
||||
BLF_size(global_font_default, global_font_points, global_font_dpi);
|
||||
return BLF_width(global_font_default, str, len);
|
||||
}
|
||||
|
||||
float BLF_height_ex(
|
||||
int fontid, const char *str, size_t len,
|
||||
struct ResultBLF *r_info)
|
||||
@@ -807,15 +829,6 @@ float BLF_ascender(int fontid)
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float BLF_height_default(const char *str, size_t len)
|
||||
{
|
||||
ASSERT_DEFAULT_SET;
|
||||
|
||||
BLF_size(global_font_default, global_font_points, global_font_dpi);
|
||||
|
||||
return BLF_height(global_font_default, str, len);
|
||||
}
|
||||
|
||||
void BLF_rotation(int fontid, float angle)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
@@ -837,18 +850,6 @@ void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax)
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax)
|
||||
{
|
||||
FontBLF *font = blf_get(global_font_default);
|
||||
|
||||
if (font) {
|
||||
font->clip_rec.xmin = xmin;
|
||||
font->clip_rec.ymin = ymin;
|
||||
font->clip_rec.xmax = xmax;
|
||||
font->clip_rec.ymax = ymax;
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_wordwrap(int fontid, int wrap_width)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
@@ -933,8 +933,6 @@ void blf_font_free(FontBLF *font)
|
||||
|
||||
static void blf_font_fill(FontBLF *font)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
font->aspect[0] = 1.0f;
|
||||
font->aspect[1] = 1.0f;
|
||||
font->aspect[2] = 1.0f;
|
||||
@@ -942,9 +940,15 @@ static void blf_font_fill(FontBLF *font)
|
||||
font->pos[1] = 0.0f;
|
||||
font->angle = 0.0f;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
for (int i = 0; i < 16; i++)
|
||||
font->m[i] = 0;
|
||||
|
||||
/* annoying bright color so we can see where to add BLF_color calls */
|
||||
font->color[0] = 255;
|
||||
font->color[1] = 255;
|
||||
font->color[2] = 0;
|
||||
font->color[3] = 255;
|
||||
|
||||
font->clip_rec.xmin = 0.0f;
|
||||
font->clip_rec.xmax = 0.0f;
|
||||
font->clip_rec.ymin = 0.0f;
|
||||
|
@@ -98,6 +98,10 @@ void BLF_thumb_preview(
|
||||
|
||||
blf_font_size(font, (unsigned int)MAX2(font_size_min, font_size_curr), dpi);
|
||||
|
||||
/* font->glyph_cache remains NULL if blf_font_size() failed to set font size */
|
||||
if (!font->glyph_cache)
|
||||
break;
|
||||
|
||||
/* decrease font size each time */
|
||||
font_size_curr -= (font_size_curr / font_shrink);
|
||||
font_shrink += 1;
|
||||
|
@@ -172,8 +172,6 @@ typedef enum DMDirtyFlag {
|
||||
|
||||
/* check this with modifier dependsOnNormals callback to see if normals need recalculation */
|
||||
DM_DIRTY_NORMALS = 1 << 2,
|
||||
|
||||
DM_MESH_BATCH_CACHE = 1 << 3,
|
||||
} DMDirtyFlag;
|
||||
|
||||
typedef struct DerivedMesh DerivedMesh;
|
||||
|
91
source/blender/blenkernel/BKE_collection.h
Normal file
91
source/blender/blenkernel/BKE_collection.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Dalai Felinto
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __BKE_COLLECTION_H__
|
||||
#define __BKE_COLLECTION_H__
|
||||
|
||||
/** \file blender/blenkernel/BKE_collection.h
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_iterator.h"
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Iterator;
|
||||
struct SceneCollection;
|
||||
struct Object;
|
||||
struct Base;
|
||||
struct Main;
|
||||
struct Scene;
|
||||
|
||||
struct SceneCollection *BKE_collection_add(struct Scene *scene, struct SceneCollection *sc_parent, const char *name);
|
||||
bool BKE_collection_remove(struct Scene *scene, struct SceneCollection *sc);
|
||||
struct SceneCollection *BKE_collection_master(struct Scene *scene);
|
||||
void BKE_collection_master_free(struct Scene *scene);
|
||||
void BKE_collection_object_add(struct Scene *scene, struct SceneCollection *sc, struct Object *object);
|
||||
void BKE_collection_object_add_from(struct Scene *scene, struct Object *ob_src, struct Object *ob_dst);
|
||||
void BKE_collection_object_remove(struct Main *bmain, struct Scene *scene, struct SceneCollection *sc, struct Object *object, const bool free_us);
|
||||
void BKE_collections_object_remove(struct Main *bmain, struct Scene *scene, struct Object *object, const bool free_us);
|
||||
|
||||
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
|
||||
typedef void (*BKE_scene_collections_Cb)(struct SceneCollection *ob, void *data);
|
||||
|
||||
void BKE_scene_collections_callback(struct Scene *scene, BKE_scene_collections_Cb callback, void *data);
|
||||
void BKE_scene_objects_callback(struct Scene *scene, BKE_scene_objects_Cb callback, void *data);
|
||||
|
||||
/* iterators */
|
||||
void BKE_scene_collections_Iterator_begin(struct Iterator *iter, void *data_in);
|
||||
void BKE_scene_collections_Iterator_next(struct Iterator *iter);
|
||||
void BKE_scene_collections_Iterator_end(struct Iterator *iter);
|
||||
|
||||
void BKE_scene_objects_Iterator_begin(struct Iterator *iter, void *data_in);
|
||||
void BKE_scene_objects_Iterator_next(struct Iterator *iter);
|
||||
void BKE_scene_objects_Iterator_end(struct Iterator *iter);
|
||||
|
||||
#define FOREACH_SCENE_COLLECTION(scene, _sc) \
|
||||
ITER_BEGIN(BKE_scene_collections_Iterator_begin, \
|
||||
BKE_scene_collections_Iterator_next, \
|
||||
BKE_scene_collections_Iterator_end, \
|
||||
scene, _sc)
|
||||
|
||||
#define FOREACH_SCENE_COLLECTION_END \
|
||||
ITER_END
|
||||
|
||||
#define FOREACH_SCENE_OBJECT(scene, _ob) \
|
||||
ITER_BEGIN(BKE_scene_objects_Iterator_begin, \
|
||||
BKE_scene_objects_Iterator_next, \
|
||||
BKE_scene_objects_Iterator_end, \
|
||||
scene, _ob)
|
||||
|
||||
#define FOREACH_SCENE_OBJECT_END \
|
||||
ITER_END
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BKE_COLLECTION_H__ */
|
@@ -40,12 +40,16 @@ extern "C" {
|
||||
struct ARegion;
|
||||
struct bScreen;
|
||||
struct CacheFile;
|
||||
struct LayerCollection;
|
||||
struct ListBase;
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct Base;
|
||||
struct PointerRNA;
|
||||
struct ReportList;
|
||||
struct Scene;
|
||||
struct SceneCollection;
|
||||
struct SceneLayer;
|
||||
struct ScrArea;
|
||||
struct SpaceLink;
|
||||
struct View3D;
|
||||
@@ -166,6 +170,7 @@ struct SpaceAction *CTX_wm_space_action(const bContext *C);
|
||||
struct SpaceInfo *CTX_wm_space_info(const bContext *C);
|
||||
struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C);
|
||||
struct SpaceClip *CTX_wm_space_clip(const bContext *C);
|
||||
struct SpaceCollections *CTX_wm_space_collections(const bContext *C);
|
||||
|
||||
void CTX_wm_manager_set(bContext *C, struct wmWindowManager *wm);
|
||||
void CTX_wm_window_set(bContext *C, struct wmWindow *win);
|
||||
@@ -239,6 +244,9 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
|
||||
|
||||
struct Main *CTX_data_main(const bContext *C);
|
||||
struct Scene *CTX_data_scene(const bContext *C);
|
||||
struct LayerCollection *CTX_data_layer_collection(const bContext *C);
|
||||
struct SceneCollection *CTX_data_scene_collection(const bContext *C);
|
||||
struct SceneLayer *CTX_data_scene_layer(const bContext *C);
|
||||
struct ToolSettings *CTX_data_tool_settings(const bContext *C);
|
||||
|
||||
const char *CTX_data_mode_string(const bContext *C);
|
||||
|
@@ -33,6 +33,7 @@
|
||||
* \author nzc
|
||||
*/
|
||||
|
||||
struct BaseLegacy;
|
||||
struct Base;
|
||||
struct EvaluationContext;
|
||||
struct Group;
|
||||
@@ -44,8 +45,8 @@ void BKE_group_free(struct Group *group);
|
||||
struct Group *BKE_group_add(struct Main *bmain, const char *name);
|
||||
struct Group *BKE_group_copy(struct Main *bmain, struct Group *group);
|
||||
void BKE_group_make_local(struct Main *bmain, struct Group *group, const bool lib_local);
|
||||
bool BKE_group_object_add(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
|
||||
bool BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
|
||||
bool BKE_group_object_add(struct Group *group, struct Object *ob);
|
||||
bool BKE_group_object_unlink(struct Group *group, struct Object *ob);
|
||||
struct Group *BKE_group_object_find(struct Group *group, struct Object *ob);
|
||||
bool BKE_group_object_exists(struct Group *group, struct Object *ob);
|
||||
bool BKE_group_object_cyclic_check(struct Main *bmain, struct Object *object, struct Group *group);
|
||||
|
217
source/blender/blenkernel/BKE_layer.h
Normal file
217
source/blender/blenkernel/BKE_layer.h
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Dalai Felinto
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __BKE_LAYER_H__
|
||||
#define __BKE_LAYER_H__
|
||||
|
||||
/** \file blender/blenkernel/BKE_layer.h
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BKE_collection.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TODO_LAYER_SYNC /* syncing of SceneCollection and LayerCollection trees*/
|
||||
#define TODO_LAYER_SYNC_FILTER /* syncing of filter_objects across all trees */
|
||||
#define TODO_LAYER_OVERRIDE /* CollectionOverride */
|
||||
#define TODO_LAYER_CONTEXT /* get/set current (context) SceneLayer */
|
||||
#define TODO_LAYER_BASE /* BaseLegacy to Base related TODO */
|
||||
#define TODO_LAYER_OPERATORS /* collection mamanger and property panel operators */
|
||||
#define TODO_LAYER_DEPSGRAPH /* placeholder for real Depsgraph fix */
|
||||
#define TODO_LAYER /* generic todo */
|
||||
|
||||
struct CollectionEngineSettings;
|
||||
struct LayerCollection;
|
||||
struct ID;
|
||||
struct ListBase;
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct Base;
|
||||
struct RenderEngine;
|
||||
struct Scene;
|
||||
struct SceneCollection;
|
||||
struct SceneLayer;
|
||||
|
||||
struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name);
|
||||
|
||||
bool BKE_scene_layer_remove(struct Main *bmain, struct Scene *scene, struct SceneLayer *sl);
|
||||
|
||||
void BKE_scene_layer_free(struct SceneLayer *sl);
|
||||
|
||||
void BKE_scene_layer_engine_set(struct SceneLayer *sl, const char *engine);
|
||||
|
||||
void BKE_scene_layer_selected_objects_tag(struct SceneLayer *sl, const int tag);
|
||||
|
||||
struct SceneLayer *BKE_scene_layer_find_from_collection(struct Scene *scene, struct LayerCollection *lc);
|
||||
struct Base *BKE_scene_layer_base_find(struct SceneLayer *sl, struct Object *ob);
|
||||
void BKE_scene_layer_base_deselect_all(struct SceneLayer *sl);
|
||||
void BKE_scene_layer_base_select(struct SceneLayer *sl, struct Base *selbase);
|
||||
void BKE_scene_layer_base_flag_recalculate(struct SceneLayer *sl);
|
||||
|
||||
void BKE_scene_layer_engine_settings_recalculate(struct SceneLayer *sl);
|
||||
void BKE_scene_layer_engine_settings_update(struct SceneLayer *sl);
|
||||
|
||||
void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc);
|
||||
|
||||
struct LayerCollection *BKE_layer_collection_active(struct SceneLayer *sl);
|
||||
|
||||
int BKE_layer_collection_count(struct SceneLayer *sl);
|
||||
|
||||
int BKE_layer_collection_findindex(struct SceneLayer *sl, struct LayerCollection *lc);
|
||||
|
||||
struct LayerCollection *BKE_collection_link(struct SceneLayer *sl, struct SceneCollection *sc);
|
||||
|
||||
void BKE_collection_unlink(struct SceneLayer *sl, struct LayerCollection *lc);
|
||||
|
||||
bool BKE_scene_layer_has_collection(struct SceneLayer *sl, struct SceneCollection *sc);
|
||||
bool BKE_scene_has_object(struct Scene *scene, struct Object *ob);
|
||||
|
||||
/* syncing */
|
||||
|
||||
void BKE_layer_sync_new_scene_collection(struct Scene *scene, const struct SceneCollection *sc_parent, struct SceneCollection *sc);
|
||||
void BKE_layer_sync_object_link(struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
|
||||
void BKE_layer_sync_object_unlink(struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
|
||||
|
||||
/* override */
|
||||
|
||||
void BKE_collection_override_datablock_add(struct LayerCollection *lc, const char *data_path, struct ID *id);
|
||||
|
||||
/* engine settings */
|
||||
typedef void (*CollectionEngineSettingsCB)(struct RenderEngine *engine, struct CollectionEngineSettings *ces);
|
||||
struct CollectionEngineSettings *BKE_layer_collection_engine_get(struct LayerCollection *lc, const char *engine_name);
|
||||
void BKE_layer_collection_engine_settings_callback_register(struct Main *bmain, const char *engine_name, CollectionEngineSettingsCB func);
|
||||
void BKE_layer_collection_engine_settings_callback_free(void);
|
||||
void BKE_layer_collection_engine_settings_create(struct ListBase *lb, const char *engine_name);
|
||||
void BKE_layer_collection_engine_settings_free(struct ListBase *lb);
|
||||
|
||||
void BKE_collection_engine_property_add_float(struct CollectionEngineSettings *ces, const char *name, float value);
|
||||
void BKE_collection_engine_property_add_int(struct CollectionEngineSettings *ces, const char *name, int value);
|
||||
struct CollectionEngineProperty *BKE_collection_engine_property_get(struct CollectionEngineSettings *ces, const char *name);
|
||||
int BKE_collection_engine_property_value_get_int(struct CollectionEngineSettings *ces, const char *name);
|
||||
float BKE_collection_engine_property_value_get_float(struct CollectionEngineSettings *ces, const char *name);
|
||||
void BKE_collection_engine_property_value_set_int(struct CollectionEngineSettings *ces, const char *name, int value);
|
||||
void BKE_collection_engine_property_value_set_float(struct CollectionEngineSettings *ces, const char *name, float value);
|
||||
bool BKE_collection_engine_property_use_get(struct CollectionEngineSettings *ces, const char *name);
|
||||
void BKE_collection_engine_property_use_set(struct CollectionEngineSettings *ces, const char *name, bool value);
|
||||
|
||||
/* iterators */
|
||||
|
||||
void BKE_selected_objects_Iterator_begin(Iterator *iter, void *data_in);
|
||||
void BKE_selected_objects_Iterator_next(Iterator *iter);
|
||||
void BKE_selected_objects_Iterator_end(Iterator *iter);
|
||||
|
||||
void BKE_visible_objects_Iterator_begin(Iterator *iter, void *data_in);
|
||||
void BKE_visible_objects_Iterator_next(Iterator *iter);
|
||||
void BKE_visible_objects_Iterator_end(Iterator *iter);
|
||||
|
||||
void BKE_visible_bases_Iterator_begin(Iterator *iter, void *data_in);
|
||||
void BKE_visible_bases_Iterator_next(Iterator *iter);
|
||||
void BKE_visible_bases_Iterator_end(Iterator *iter);
|
||||
|
||||
#define FOREACH_SELECTED_OBJECT(sl, _ob) \
|
||||
ITER_BEGIN(BKE_selected_objects_Iterator_begin, \
|
||||
BKE_selected_objects_Iterator_next, \
|
||||
BKE_selected_objects_Iterator_end, \
|
||||
sl, _ob)
|
||||
|
||||
#define FOREACH_SELECTED_OBJECT_END \
|
||||
ITER_END
|
||||
|
||||
#define FOREACH_VISIBLE_OBJECT(sl, _ob) \
|
||||
ITER_BEGIN(BKE_visible_objects_Iterator_begin, \
|
||||
BKE_visible_objects_Iterator_next, \
|
||||
BKE_visible_objects_Iterator_end, \
|
||||
sl, _ob)
|
||||
|
||||
#define FOREACH_VISIBLE_OBJECT_END \
|
||||
ITER_END
|
||||
|
||||
|
||||
#define FOREACH_VISIBLE_BASE(sl, _object_base) \
|
||||
ITER_BEGIN(BKE_visible_bases_Iterator_begin, \
|
||||
BKE_visible_bases_Iterator_next, \
|
||||
BKE_visible_bases_Iterator_end, \
|
||||
sl, _object_base)
|
||||
|
||||
#define FOREACH_VISIBLE_BASE_END \
|
||||
ITER_END
|
||||
|
||||
|
||||
#define FOREACH_OBJECT(sl, _ob) \
|
||||
{ \
|
||||
Base *base; \
|
||||
for (base = sl->object_bases.first; base; base = base->next) { \
|
||||
_ob = base->object;
|
||||
|
||||
#define FOREACH_OBJECT_END \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FOREACH_OBJECT_FLAG(scene, sl, flag, _ob) \
|
||||
{ \
|
||||
IteratorBeginCb func_begin; \
|
||||
IteratorCb func_next, func_end; \
|
||||
void *data_in; \
|
||||
\
|
||||
if (flag == SELECT) { \
|
||||
func_begin = &BKE_selected_objects_Iterator_begin; \
|
||||
func_next = &BKE_selected_objects_Iterator_next; \
|
||||
func_end = &BKE_selected_objects_Iterator_end; \
|
||||
data_in = sl; \
|
||||
} \
|
||||
else { \
|
||||
func_begin = BKE_scene_objects_Iterator_begin; \
|
||||
func_next = BKE_scene_objects_Iterator_next; \
|
||||
func_end = BKE_scene_objects_Iterator_end; \
|
||||
data_in = scene; \
|
||||
} \
|
||||
ITER_BEGIN(func_begin, func_next, func_end, data_in, _ob)
|
||||
|
||||
|
||||
#define FOREACH_OBJECT_FLAG_END \
|
||||
ITER_END \
|
||||
}
|
||||
|
||||
/* temporary hacky solution waiting for final depsgraph evaluation */
|
||||
#define DEG_OBJECT_ITER(sl_, ob_) \
|
||||
{ \
|
||||
/* temporary solution, waiting for depsgraph update */ \
|
||||
BKE_scene_layer_engine_settings_update(sl); \
|
||||
\
|
||||
/* flush all the data to objects*/ \
|
||||
Base *base_; \
|
||||
for (base_ = sl->object_bases.first; base_; base_ = base_->next) { \
|
||||
ob_ = base_->object; \
|
||||
ob_->base_flag = base_->flag;
|
||||
|
||||
#define DEG_OBJECT_ITER_END \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BKE_LAYER_H__ */
|
@@ -86,7 +86,7 @@ bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const boo
|
||||
bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
|
||||
bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test);
|
||||
void id_sort_by_name(struct ListBase *lb, struct ID *id);
|
||||
void BKE_id_expand_local(struct ID *id);
|
||||
void BKE_id_expand_local(struct Main *bmain, struct ID *id);
|
||||
void BKE_id_copy_ensure_local(struct Main *bmain, struct ID *old_id, struct ID *new_id);
|
||||
|
||||
bool new_id(struct ListBase *lb, struct ID *id, const char *name);
|
||||
@@ -105,6 +105,9 @@ void BKE_main_free(struct Main *mainvar);
|
||||
void BKE_main_lock(struct Main *bmain);
|
||||
void BKE_main_unlock(struct Main *bmain);
|
||||
|
||||
void BKE_main_relations_create(struct Main *bmain);
|
||||
void BKE_main_relations_free(struct Main *bmain);
|
||||
|
||||
struct BlendThumbnail *BKE_main_thumbnail_from_imbuf(struct Main *bmain, struct ImBuf *img);
|
||||
struct ImBuf *BKE_main_thumbnail_to_imbuf(struct Main *bmain, struct BlendThumbnail *data);
|
||||
void BKE_main_thumbnail_create(struct Main *bmain);
|
||||
|
@@ -36,25 +36,28 @@ struct Main;
|
||||
|
||||
/* Tips for the callback for cases it's gonna to modify the pointer. */
|
||||
enum {
|
||||
IDWALK_NOP = 0,
|
||||
IDWALK_NEVER_NULL = (1 << 0),
|
||||
IDWALK_NEVER_SELF = (1 << 1),
|
||||
IDWALK_CB_NOP = 0,
|
||||
IDWALK_CB_NEVER_NULL = (1 << 0),
|
||||
IDWALK_CB_NEVER_SELF = (1 << 1),
|
||||
|
||||
/**
|
||||
* Indicates whether this is direct (i.e. by local data) or indirect (i.e. by linked data) usage.
|
||||
* \note Object proxies are half-local, half-linked...
|
||||
*/
|
||||
IDWALK_INDIRECT_USAGE = (1 << 2),
|
||||
IDWALK_CB_INDIRECT_USAGE = (1 << 2),
|
||||
|
||||
/** That ID is used as mere sub-data by its owner
|
||||
* (only case currently: those f***ing nodetrees in materials etc.).
|
||||
* This means callback shall not *do* anything, only use this as informative data if it needs it. */
|
||||
IDWALK_CB_PRIVATE = (1 << 3),
|
||||
|
||||
/**
|
||||
* Adjusts #ID.us reference-count.
|
||||
* \note keep in sync with 'newlibadr_us' use in readfile.c
|
||||
*/
|
||||
IDWALK_USER = (1 << 8),
|
||||
/**
|
||||
* Ensure #ID.us is at least 1 on use.
|
||||
*/
|
||||
IDWALK_USER_ONE = (1 << 9),
|
||||
IDWALK_CB_USER = (1 << 8),
|
||||
/** Ensure #ID.us is at least 1 on use. */
|
||||
IDWALK_CB_USER_ONE = (1 << 9),
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -68,17 +71,19 @@ enum {
|
||||
*
|
||||
* \return a set of flags to control further iteration (0 to keep going).
|
||||
*/
|
||||
typedef int (*LibraryIDLinkCallback) (void *user_data, struct ID *id_self, struct ID **id_pointer, int cd_flag);
|
||||
typedef int (*LibraryIDLinkCallback) (void *user_data, struct ID *id_self, struct ID **id_pointer, int cb_flag);
|
||||
|
||||
/* Flags for the foreach function itself. */
|
||||
enum {
|
||||
IDWALK_NOP = 0,
|
||||
IDWALK_READONLY = (1 << 0),
|
||||
IDWALK_RECURSE = (1 << 1), /* Also implies IDWALK_READONLY. */
|
||||
};
|
||||
|
||||
/* Loop over all of the ID's this datablock links to. */
|
||||
void BKE_library_foreach_ID_link(struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
|
||||
void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const int cd_flag);
|
||||
void BKE_library_foreach_ID_link(
|
||||
struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag);
|
||||
void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const int cb_flag);
|
||||
|
||||
int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used);
|
||||
|
||||
|
@@ -51,6 +51,8 @@ extern "C" {
|
||||
struct EvaluationContext;
|
||||
struct Library;
|
||||
struct MainLock;
|
||||
struct GHash;
|
||||
struct BLI_mempool;
|
||||
|
||||
/* Blender thumbnail, as written on file (width, height, and data as char RGBA). */
|
||||
/* We pack pixel data after that struct. */
|
||||
@@ -59,6 +61,22 @@ typedef struct BlendThumbnail {
|
||||
char rect[0];
|
||||
} BlendThumbnail;
|
||||
|
||||
/* Structs caching relations between data-blocks in a given Main. */
|
||||
typedef struct MainIDRelationsEntry {
|
||||
struct MainIDRelationsEntry *next;
|
||||
/* WARNING! for user_to_used, that pointer is really an ID** one, but for used_to_user, it’s only an ID* one! */
|
||||
struct ID **id_pointer;
|
||||
int usage_flag; /* Using IDWALK_ enums, in BKE_library_query.h */
|
||||
} MainIDRelationsEntry;
|
||||
|
||||
typedef struct MainIDRelations {
|
||||
struct GHash *id_user_to_used;
|
||||
struct GHash *id_used_to_user;
|
||||
|
||||
/* Private... */
|
||||
struct BLI_mempool *entry_pool;
|
||||
} MainIDRelations;
|
||||
|
||||
typedef struct Main {
|
||||
struct Main *next, *prev;
|
||||
char name[1024]; /* 1024 = FILE_MAX */
|
||||
@@ -111,6 +129,11 @@ typedef struct Main {
|
||||
/* Evaluation context used by viewport */
|
||||
struct EvaluationContext *eval_ctx;
|
||||
|
||||
/* Must be generated, used and freed by same code - never assume this is valid data unless you know
|
||||
* when, who and how it was created.
|
||||
* Used by code doing a lot of remapping etc. at once to speed things up. */
|
||||
struct MainIDRelations *relations;
|
||||
|
||||
struct MainLock *lock;
|
||||
} Main;
|
||||
|
||||
|
@@ -32,6 +32,7 @@
|
||||
struct Batch;
|
||||
struct Mesh;
|
||||
|
||||
void BKE_mesh_batch_cache_dirty(struct Mesh *me);
|
||||
void BKE_mesh_batch_cache_free(struct Mesh *me);
|
||||
struct Batch *BKE_mesh_batch_cache_get_all_edges(struct Mesh *me);
|
||||
struct Batch *BKE_mesh_batch_cache_get_all_triangles(struct Mesh *me);
|
||||
|
@@ -106,8 +106,8 @@ typedef enum {
|
||||
} ModifierTypeFlag;
|
||||
|
||||
/* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */
|
||||
typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cd_flag);
|
||||
typedef void (*IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cd_flag);
|
||||
typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin, int cb_flag);
|
||||
typedef void (*IDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag);
|
||||
typedef void (*TexWalkFunc)(void *userData, struct Object *ob, struct ModifierData *md, const char *propname);
|
||||
|
||||
typedef enum ModifierApplyFlag {
|
||||
|
@@ -687,6 +687,13 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
|
||||
}
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Node Tree
|
||||
*/
|
||||
|
||||
void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, const int layer_index);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Shader Nodes
|
||||
*/
|
||||
|
@@ -35,12 +35,13 @@ extern "C" {
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
|
||||
struct Base;
|
||||
struct BaseLegacy;
|
||||
struct EvaluationContext;
|
||||
struct Scene;
|
||||
struct Object;
|
||||
struct BoundBox;
|
||||
struct View3D;
|
||||
struct SceneLayer;
|
||||
struct SoftBody;
|
||||
struct BulletSoftBody;
|
||||
struct MovieClip;
|
||||
@@ -89,9 +90,9 @@ struct Object *BKE_object_add_only_object(
|
||||
int type, const char *name)
|
||||
ATTR_NONNULL(1) ATTR_RETURNS_NONNULL;
|
||||
struct Object *BKE_object_add(
|
||||
struct Main *bmain, struct Scene *scene,
|
||||
struct Main *bmain, struct Scene *scene, struct SceneLayer *sl,
|
||||
int type, const char *name)
|
||||
ATTR_NONNULL(1, 2) ATTR_RETURNS_NONNULL;
|
||||
ATTR_NONNULL(1, 2, 3) ATTR_RETURNS_NONNULL;
|
||||
void *BKE_object_obdata_add_from_type(
|
||||
struct Main *bmain,
|
||||
int type, const char *name)
|
||||
@@ -136,14 +137,9 @@ void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float
|
||||
/* possibly belong in own moduke? */
|
||||
struct BoundBox *BKE_boundbox_alloc_unit(void);
|
||||
void BKE_boundbox_init_from_minmax(struct BoundBox *bb, const float min[3], const float max[3]);
|
||||
bool BKE_boundbox_ray_hit_check(
|
||||
const struct BoundBox *bb,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float *r_lambda);
|
||||
void BKE_boundbox_calc_center_aabb(const struct BoundBox *bb, float r_cent[3]);
|
||||
void BKE_boundbox_calc_size_aabb(const struct BoundBox *bb, float r_size[3]);
|
||||
void BKE_boundbox_minmax(const struct BoundBox *bb, float obmat[4][4], float r_min[3], float r_max[3]);
|
||||
void BKE_boundbox_scale(struct BoundBox *bb_dst, const struct BoundBox *bb_src, float scale);
|
||||
struct BoundBox *BKE_boundbox_ensure_minimum_dimensions(
|
||||
struct BoundBox *bb, struct BoundBox *bb_temp, const float epsilon);
|
||||
|
||||
@@ -206,6 +202,7 @@ void BKE_object_eval_uber_transform(struct EvaluationContext *eval_ctx,
|
||||
void BKE_object_eval_uber_data(struct EvaluationContext *eval_ctx,
|
||||
struct Scene *scene,
|
||||
struct Object *ob);
|
||||
void BKE_object_eval_shading(struct EvaluationContext *eval_ctx, struct Object *ob);
|
||||
|
||||
void BKE_object_handle_data_update(struct EvaluationContext *eval_ctx,
|
||||
struct Scene *scene,
|
||||
@@ -259,7 +256,7 @@ typedef enum eObjectSet {
|
||||
|
||||
struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter);
|
||||
struct LinkNode *BKE_object_groups(struct Object *ob);
|
||||
void BKE_object_groups_clear(struct Scene *scene, struct Base *base, struct Object *object);
|
||||
void BKE_object_groups_clear(struct Object *object);
|
||||
|
||||
struct KDTree *BKE_object_as_kdtree(struct Object *ob, int *r_tot);
|
||||
|
||||
|
@@ -384,7 +384,7 @@ void psys_get_birth_coords(struct ParticleSimulationData *sim, struct ParticleDa
|
||||
void particle_system_update(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, const bool use_render_params);
|
||||
|
||||
/* Callback format for performing operations on ID-pointers for particle systems */
|
||||
typedef void (*ParticleSystemIDFunc)(struct ParticleSystem *psys, struct ID **idpoin, void *userdata, int cd_flag);
|
||||
typedef void (*ParticleSystemIDFunc)(struct ParticleSystem *psys, struct ID **idpoin, void *userdata, int cb_flag);
|
||||
|
||||
void BKE_particlesystem_id_loop(struct ParticleSystem *psys, ParticleSystemIDFunc func, void *userdata);
|
||||
|
||||
|
@@ -53,7 +53,7 @@ struct RigidBodyOb *BKE_rigidbody_copy_object(struct Object *ob);
|
||||
struct RigidBodyCon *BKE_rigidbody_copy_constraint(struct Object *ob);
|
||||
|
||||
/* Callback format for performing operations on ID-pointers for rigidbody world. */
|
||||
typedef void (*RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw, struct ID **idpoin, void *userdata, int cd_flag);
|
||||
typedef void (*RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw, struct ID **idpoin, void *userdata, int cb_flag);
|
||||
|
||||
void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata);
|
||||
|
||||
|
@@ -77,9 +77,9 @@ void sca_move_controller(struct bController *cont_to_move, struct Object *ob, in
|
||||
void sca_move_actuator(struct bActuator *act_to_move, struct Object *ob, int move_up);
|
||||
|
||||
/* Callback format for performing operations on ID-pointers for sensors/controllers/actuators. */
|
||||
typedef void (*SCASensorIDFunc)(struct bSensor *sensor, struct ID **idpoin, void *userdata, int cd_flag);
|
||||
typedef void (*SCAControllerIDFunc)(struct bController *controller, struct ID **idpoin, void *userdata, int cd_flag);
|
||||
typedef void (*SCAActuatorIDFunc)(struct bActuator *actuator, struct ID **idpoin, void *userdata, int cd_flag);
|
||||
typedef void (*SCASensorIDFunc)(struct bSensor *sensor, struct ID **idpoin, void *userdata, int cb_flag);
|
||||
typedef void (*SCAControllerIDFunc)(struct bController *controller, struct ID **idpoin, void *userdata, int cb_flag);
|
||||
typedef void (*SCAActuatorIDFunc)(struct bActuator *actuator, struct ID **idpoin, void *userdata, int cb_flag);
|
||||
|
||||
void BKE_sca_sensors_id_loop(struct ListBase *senslist, SCASensorIDFunc func, void *userdata);
|
||||
void BKE_sca_controllers_id_loop(struct ListBase *contlist, SCAControllerIDFunc func, void *userdata);
|
||||
|
@@ -38,10 +38,11 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct AviCodecData;
|
||||
struct Base;
|
||||
struct BaseLegacy;
|
||||
struct EvaluationContext;
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct Base;
|
||||
struct QuicktimeCodecData;
|
||||
struct RenderData;
|
||||
struct SceneRenderLayer;
|
||||
@@ -61,7 +62,7 @@ struct Main;
|
||||
_base; \
|
||||
_base = _setlooper_base_step(&_sce_iter, _base)
|
||||
|
||||
struct Base *_setlooper_base_step(struct Scene **sce_iter, struct Base *base);
|
||||
struct BaseLegacy *_setlooper_base_step(struct Scene **sce_iter, struct BaseLegacy *base);
|
||||
|
||||
void free_avicodecdata(struct AviCodecData *acd);
|
||||
void free_qtcodecdata(struct QuicktimeCodecData *acd);
|
||||
@@ -70,13 +71,15 @@ void BKE_scene_free(struct Scene *sce);
|
||||
void BKE_scene_init(struct Scene *sce);
|
||||
struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
|
||||
|
||||
void BKE_scene_remove_rigidbody_object(struct Scene *scene, struct Object *ob);
|
||||
|
||||
/* base functions */
|
||||
struct Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
|
||||
struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
|
||||
struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
|
||||
void BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
|
||||
struct BaseLegacy *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
|
||||
struct BaseLegacy *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
|
||||
struct BaseLegacy *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
|
||||
void BKE_scene_base_unlink(struct Scene *sce, struct BaseLegacy *base);
|
||||
void BKE_scene_base_deselect_all(struct Scene *sce);
|
||||
void BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
|
||||
void BKE_scene_base_select(struct Scene *sce, struct BaseLegacy *selbase);
|
||||
|
||||
/* Scene base iteration function.
|
||||
* Define struct here, so no need to bother with alloc/free it.
|
||||
@@ -90,10 +93,14 @@ typedef struct SceneBaseIter {
|
||||
} SceneBaseIter;
|
||||
|
||||
int BKE_scene_base_iter_next(struct EvaluationContext *eval_ctx, struct SceneBaseIter *iter,
|
||||
struct Scene **scene, int val, struct Base **base, struct Object **ob);
|
||||
struct Scene **scene, int val, struct BaseLegacy **base, struct Object **ob);
|
||||
|
||||
void BKE_scene_base_flag_to_objects(struct Scene *scene);
|
||||
void BKE_scene_base_flag_from_objects(struct Scene *scene);
|
||||
void BKE_scene_base_flag_sync_from_base(struct BaseLegacy *base);
|
||||
void BKE_scene_base_flag_sync_from_object(struct BaseLegacy *base);
|
||||
void BKE_scene_object_base_flag_sync_from_base(struct Base *base);
|
||||
void BKE_scene_object_base_flag_sync_from_object(struct Base *base);
|
||||
|
||||
void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
|
||||
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);
|
||||
|
@@ -85,6 +85,7 @@ set(SRC
|
||||
intern/camera.c
|
||||
intern/cdderivedmesh.c
|
||||
intern/cloth.c
|
||||
intern/collection.c
|
||||
intern/collision.c
|
||||
intern/colortools.c
|
||||
intern/constraint.c
|
||||
@@ -157,6 +158,7 @@ set(SRC
|
||||
intern/pbvh_bmesh.c
|
||||
intern/pointcache.c
|
||||
intern/property.c
|
||||
intern/layer.c
|
||||
intern/report.c
|
||||
intern/rigidbody.c
|
||||
intern/sca.c
|
||||
@@ -214,6 +216,7 @@ set(SRC
|
||||
BKE_ccg.h
|
||||
BKE_cdderivedmesh.h
|
||||
BKE_cloth.h
|
||||
BKE_collection.h
|
||||
BKE_collision.h
|
||||
BKE_colortools.h
|
||||
BKE_constraint.h
|
||||
@@ -274,6 +277,7 @@ set(SRC
|
||||
BKE_pbvh.h
|
||||
BKE_pointcache.h
|
||||
BKE_property.h
|
||||
BKE_layer.h
|
||||
BKE_report.h
|
||||
BKE_rigidbody.h
|
||||
BKE_sca.h
|
||||
|
@@ -2216,6 +2216,12 @@ static void mesh_calc_modifiers(
|
||||
}
|
||||
}
|
||||
|
||||
/* Some modifiers, like datatransfer, may generate those data as temp layer, we do not want to keep them,
|
||||
* as they are used by display code when available (i.e. even if autosmooth is disabled). */
|
||||
if (!do_loop_normals && CustomData_has_layer(&finaldm->loopData, CD_NORMAL)) {
|
||||
CustomData_free_layers(&finaldm->loopData, CD_NORMAL, finaldm->numLoopData);
|
||||
}
|
||||
|
||||
#ifdef WITH_GAMEENGINE
|
||||
/* NavMesh - this is a hack but saves having a NavMesh modifier */
|
||||
if ((ob->gameflag & OB_NAVMESH) && (finaldm->type == DM_TYPE_CDDM)) {
|
||||
@@ -2551,6 +2557,15 @@ static void editbmesh_calc_modifiers(
|
||||
/* same as mesh_calc_modifiers (if using loop normals, poly nors have already been computed). */
|
||||
if (!do_loop_normals) {
|
||||
dm_ensure_display_normals(*r_final);
|
||||
|
||||
/* Some modifiers, like datatransfer, may generate those data, we do not want to keep them,
|
||||
* as they are used by display code when available (i.e. even if autosmooth is disabled). */
|
||||
if (CustomData_has_layer(&(*r_final)->loopData, CD_NORMAL)) {
|
||||
CustomData_free_layers(&(*r_final)->loopData, CD_NORMAL, (*r_final)->numLoopData);
|
||||
}
|
||||
if (r_cage && CustomData_has_layer(&(*r_cage)->loopData, CD_NORMAL)) {
|
||||
CustomData_free_layers(&(*r_cage)->loopData, CD_NORMAL, (*r_cage)->numLoopData);
|
||||
}
|
||||
}
|
||||
|
||||
/* add an orco layer if needed */
|
||||
|
@@ -283,7 +283,7 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
|
||||
/* tweak the object ordering to trick depsgraph into making MotionPath calculations run faster */
|
||||
static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
|
||||
{
|
||||
Base *base, *baseNext;
|
||||
BaseLegacy *base, *baseNext;
|
||||
MPathTarget *mpt;
|
||||
|
||||
/* make sure our temp-tag isn't already in use */
|
||||
@@ -321,7 +321,7 @@ static void motionpaths_calc_update_scene(Scene *scene)
|
||||
BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, scene->lay);
|
||||
}
|
||||
else { /* otherwise we can optimize by restricting updates */
|
||||
Base *base, *last = NULL;
|
||||
BaseLegacy *base, *last = NULL;
|
||||
|
||||
/* only stuff that moves or needs display still */
|
||||
DAG_scene_update_flags(G.main, scene, scene->lay, true, false);
|
||||
|
@@ -239,7 +239,7 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
|
||||
if (lib_local || is_local) {
|
||||
if (!is_lib) {
|
||||
id_clear_lib_data(bmain, &brush->id);
|
||||
BKE_id_expand_local(&brush->id);
|
||||
BKE_id_expand_local(bmain, &brush->id);
|
||||
|
||||
/* enable fake user by default */
|
||||
id_fake_user_set(&brush->id);
|
||||
|
@@ -205,7 +205,7 @@ float BKE_cachefile_time_offset(CacheFile *cache_file, const float time, const f
|
||||
/* TODO(kevin): replace this with some depsgraph mechanism, or something similar. */
|
||||
void BKE_cachefile_clean(Scene *scene, CacheFile *cache_file)
|
||||
{
|
||||
for (Base *base = scene->base.first; base; base = base->next) {
|
||||
for (BaseLegacy *base = scene->base.first; base; base = base->next) {
|
||||
Object *ob = base->object;
|
||||
|
||||
ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache);
|
||||
@@ -215,7 +215,9 @@ void BKE_cachefile_clean(Scene *scene, CacheFile *cache_file)
|
||||
|
||||
if (cache_file == mcmd->cache_file) {
|
||||
#ifdef WITH_ALEMBIC
|
||||
CacheReader_free(mcmd->reader);
|
||||
if (mcmd->reader != NULL) {
|
||||
CacheReader_free(mcmd->reader);
|
||||
}
|
||||
#endif
|
||||
mcmd->reader = NULL;
|
||||
mcmd->object_path[0] = '\0';
|
||||
@@ -231,7 +233,9 @@ void BKE_cachefile_clean(Scene *scene, CacheFile *cache_file)
|
||||
|
||||
if (cache_file == data->cache_file) {
|
||||
#ifdef WITH_ALEMBIC
|
||||
CacheReader_free(data->reader);
|
||||
if (data->reader != NULL) {
|
||||
CacheReader_free(data->reader);
|
||||
}
|
||||
#endif
|
||||
data->reader = NULL;
|
||||
data->object_path[0] = '\0';
|
||||
|
@@ -853,7 +853,7 @@ static Object *camera_multiview_advanced(Scene *scene, Object *camera, const cha
|
||||
}
|
||||
|
||||
if (name[0] != '\0') {
|
||||
Base *base = BKE_scene_base_find_by_name(scene, name);
|
||||
BaseLegacy *base = BKE_scene_base_find_by_name(scene, name);
|
||||
if (base) {
|
||||
return base->object;
|
||||
}
|
||||
|
@@ -2408,36 +2408,46 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
|
||||
int numLoops = source->numLoopData;
|
||||
int numPolys = source->numPolyData;
|
||||
|
||||
/* NOTE: Don't copy tessellation faces if not requested explicitly. */
|
||||
|
||||
/* ensure these are created if they are made on demand */
|
||||
source->getVertDataArray(source, CD_ORIGINDEX);
|
||||
source->getEdgeDataArray(source, CD_ORIGINDEX);
|
||||
source->getTessFaceDataArray(source, CD_ORIGINDEX);
|
||||
source->getPolyDataArray(source, CD_ORIGINDEX);
|
||||
|
||||
/* this initializes dm, and copies all non mvert/medge/mface layers */
|
||||
DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
|
||||
DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges,
|
||||
faces_from_tessfaces ? numTessFaces : 0,
|
||||
numLoops, numPolys);
|
||||
dm->deformedOnly = source->deformedOnly;
|
||||
dm->cd_flag = source->cd_flag;
|
||||
dm->dirty = source->dirty;
|
||||
|
||||
/* Tessellation data is never copied, so tag it here. */
|
||||
dm->dirty |= DM_DIRTY_TESS_CDLAYERS;
|
||||
|
||||
CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
|
||||
CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
|
||||
CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
|
||||
|
||||
/* now add mvert/medge/mface layers */
|
||||
cddm->mvert = source->dupVertArray(source);
|
||||
cddm->medge = source->dupEdgeArray(source);
|
||||
cddm->mface = source->dupTessFaceArray(source);
|
||||
|
||||
CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
|
||||
CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
|
||||
CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
|
||||
|
||||
if (!faces_from_tessfaces)
|
||||
if (!faces_from_tessfaces) {
|
||||
DM_DupPolys(source, dm);
|
||||
else
|
||||
}
|
||||
else {
|
||||
source->getTessFaceDataArray(source, CD_ORIGINDEX);
|
||||
CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
|
||||
|
||||
cddm->mface = source->dupTessFaceArray(source);
|
||||
CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
|
||||
|
||||
CDDM_tessfaces_to_faces(dm);
|
||||
}
|
||||
|
||||
cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
|
||||
cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
|
||||
|
455
source/blender/blenkernel/intern/collection.c
Normal file
455
source/blender/blenkernel/intern/collection.c
Normal file
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Dalai Felinto
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/blenkernel/intern/collection.c
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_iterator.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLT_translation.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/**
|
||||
* Add a collection to a collection ListBase and syncronize all render layers
|
||||
* The ListBase is NULL when the collection is to be added to the master collection
|
||||
*/
|
||||
SceneCollection *BKE_collection_add(Scene *scene, SceneCollection *sc_parent, const char *name)
|
||||
{
|
||||
SceneCollection *sc_master = BKE_collection_master(scene);
|
||||
SceneCollection *sc = MEM_callocN(sizeof(SceneCollection), "New Collection");
|
||||
|
||||
if (!name) {
|
||||
name = DATA_("New Collection");
|
||||
}
|
||||
|
||||
if (!sc_parent) {
|
||||
sc_parent = sc_master;
|
||||
}
|
||||
|
||||
BLI_strncpy(sc->name, name, sizeof(sc->name));
|
||||
BLI_uniquename(&sc_master->scene_collections, sc, DATA_("Collection"), '.', offsetof(SceneCollection, name), sizeof(sc->name));
|
||||
|
||||
BLI_addtail(&sc_parent->scene_collections, sc);
|
||||
|
||||
BKE_layer_sync_new_scene_collection(scene, sc_parent, sc);
|
||||
return sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the collection items recursively
|
||||
*/
|
||||
static void collection_free(SceneCollection *sc)
|
||||
{
|
||||
for (LinkData *link = sc->objects.first; link; link = link->next) {
|
||||
id_us_min(link->data);
|
||||
}
|
||||
BLI_freelistN(&sc->objects);
|
||||
|
||||
for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
|
||||
id_us_min(link->data);
|
||||
}
|
||||
BLI_freelistN(&sc->filter_objects);
|
||||
|
||||
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
|
||||
collection_free(nsc);
|
||||
}
|
||||
BLI_freelistN(&sc->scene_collections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink the collection recursively
|
||||
* return true if unlinked
|
||||
*/
|
||||
static bool collection_remlink(SceneCollection *sc_parent, SceneCollection *sc_gone)
|
||||
{
|
||||
for (SceneCollection *sc = sc_parent->scene_collections.first; sc; sc = sc->next)
|
||||
{
|
||||
if (sc == sc_gone) {
|
||||
BLI_remlink(&sc_parent->scene_collections, sc_gone);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (collection_remlink(sc, sc_gone)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively remove any instance of this SceneCollection
|
||||
*/
|
||||
static void layer_collection_remove(SceneLayer *sl, ListBase *lb, const SceneCollection *sc)
|
||||
{
|
||||
LayerCollection *lc = lb->first;
|
||||
while(lc) {
|
||||
if (lc->scene_collection == sc) {
|
||||
BKE_layer_collection_free(sl, lc);
|
||||
BLI_remlink(lb, lc);
|
||||
|
||||
LayerCollection *lc_next = lc->next;
|
||||
MEM_freeN(lc);
|
||||
lc = lc_next;
|
||||
|
||||
/* only the "top-level" layer collections may have the
|
||||
* same SceneCollection in a sibling tree.
|
||||
*/
|
||||
if (lb != &sl->layer_collections) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
layer_collection_remove(sl, &lc->layer_collections, sc);
|
||||
lc = lc->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a collection from the scene, and syncronize all render layers
|
||||
*/
|
||||
bool BKE_collection_remove(Scene *scene, SceneCollection *sc)
|
||||
{
|
||||
SceneCollection *sc_master = BKE_collection_master(scene);
|
||||
|
||||
/* the master collection cannot be removed */
|
||||
if (sc == sc_master) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* unlink from the respective collection tree */
|
||||
if (!collection_remlink(sc_master, sc)) {
|
||||
BLI_assert(false);
|
||||
}
|
||||
|
||||
/* clear the collection items */
|
||||
collection_free(sc);
|
||||
|
||||
/* check all layers that use this collection and clear them */
|
||||
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
layer_collection_remove(sl, &sl->layer_collections, sc);
|
||||
BKE_scene_layer_base_flag_recalculate(sl);
|
||||
sl->active_collection = 0;
|
||||
}
|
||||
|
||||
MEM_freeN(sc);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the master collection
|
||||
*/
|
||||
SceneCollection *BKE_collection_master(Scene *scene)
|
||||
{
|
||||
return scene->collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free (or release) any data used by the master collection (does not free the master collection itself).
|
||||
* Used only to clear the entire scene data since it's not doing re-syncing of the LayerCollection tree
|
||||
*/
|
||||
void BKE_collection_master_free(Scene *scene){
|
||||
collection_free(BKE_collection_master(scene));
|
||||
}
|
||||
|
||||
static void collection_object_add(Scene *scene, SceneCollection *sc, Object *ob)
|
||||
{
|
||||
BLI_addtail(&sc->objects, BLI_genericNodeN(ob));
|
||||
id_us_plus((ID *)ob);
|
||||
BKE_layer_sync_object_link(scene, sc, ob);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add object to collection
|
||||
*/
|
||||
void BKE_collection_object_add(Scene *scene, SceneCollection *sc, Object *ob)
|
||||
{
|
||||
if (BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) {
|
||||
/* don't add the same object twice */
|
||||
return;
|
||||
}
|
||||
collection_object_add(scene, sc, ob);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add object to all collections that reference objects is in
|
||||
* (used to copy objects)
|
||||
*/
|
||||
void BKE_collection_object_add_from(Scene *scene, Object *ob_src, Object *ob_dst)
|
||||
{
|
||||
SceneCollection *sc;
|
||||
FOREACH_SCENE_COLLECTION(scene, sc)
|
||||
{
|
||||
if (BLI_findptr(&sc->objects, ob_src, offsetof(LinkData, data))) {
|
||||
collection_object_add(scene, sc, ob_dst);
|
||||
}
|
||||
}
|
||||
FOREACH_SCENE_COLLECTION_END
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove object from collection
|
||||
*/
|
||||
void BKE_collection_object_remove(Main *bmain, Scene *scene, SceneCollection *sc, Object *ob, const bool free_us)
|
||||
{
|
||||
|
||||
LinkData *link = BLI_findptr(&sc->objects, ob, offsetof(LinkData, data));
|
||||
|
||||
if (link == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_remlink(&sc->objects, link);
|
||||
MEM_freeN(link);
|
||||
|
||||
TODO_LAYER_SYNC_FILTER; /* need to remove all instances of ob in scene collections -> filter_objects */
|
||||
BKE_layer_sync_object_unlink(scene, sc, ob);
|
||||
|
||||
if (free_us) {
|
||||
BKE_libblock_free_us(bmain, ob);
|
||||
}
|
||||
else {
|
||||
id_us_min(&ob->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove object from all collections of scene
|
||||
*/
|
||||
void BKE_collections_object_remove(Main *bmain, Scene *scene, Object *ob, const bool free_us)
|
||||
{
|
||||
BKE_scene_remove_rigidbody_object(scene, ob);
|
||||
|
||||
SceneCollection *sc;
|
||||
FOREACH_SCENE_COLLECTION(scene, sc)
|
||||
{
|
||||
BKE_collection_object_remove(bmain, scene, sc, ob, free_us);
|
||||
}
|
||||
FOREACH_SCENE_COLLECTION_END
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Iteractors */
|
||||
/* scene collection iteractor */
|
||||
|
||||
typedef struct SceneCollectionsIteratorData {
|
||||
Scene *scene;
|
||||
void **array;
|
||||
int tot, cur;
|
||||
} SceneCollectionsIteratorData;
|
||||
|
||||
static void scene_collection_callback(SceneCollection *sc, BKE_scene_collections_Cb callback, void *data)
|
||||
{
|
||||
callback(sc, data);
|
||||
|
||||
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
|
||||
scene_collection_callback(nsc, callback, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void scene_collections_count(SceneCollection *UNUSED(sc), void *data)
|
||||
{
|
||||
int *tot = data;
|
||||
(*tot)++;
|
||||
}
|
||||
|
||||
static void scene_collections_build_array(SceneCollection *sc, void *data)
|
||||
{
|
||||
SceneCollection ***array = data;
|
||||
**array = sc;
|
||||
(*array)++;
|
||||
}
|
||||
|
||||
static void scene_collections_array(Scene *scene, SceneCollection ***collections_array, int *tot)
|
||||
{
|
||||
SceneCollection *sc = BKE_collection_master(scene);
|
||||
SceneCollection **array;
|
||||
|
||||
*collections_array = NULL;
|
||||
*tot = 0;
|
||||
|
||||
if (scene == NULL)
|
||||
return;
|
||||
|
||||
scene_collection_callback(sc, scene_collections_count, tot);
|
||||
|
||||
if (*tot == 0)
|
||||
return;
|
||||
|
||||
*collections_array = array = MEM_mallocN(sizeof(SceneCollection *) * (*tot), "SceneCollectionArray");
|
||||
scene_collection_callback(sc, scene_collections_build_array, &array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use this in non-performance critical situations
|
||||
* (it iterates over all scene collections twice)
|
||||
*/
|
||||
void BKE_scene_collections_Iterator_begin(Iterator *iter, void *data_in)
|
||||
{
|
||||
Scene *scene = data_in;
|
||||
SceneCollectionsIteratorData *data = MEM_callocN(sizeof(SceneCollectionsIteratorData), __FUNCTION__);
|
||||
|
||||
data->scene = scene;
|
||||
iter->data = data;
|
||||
|
||||
scene_collections_array(scene, (SceneCollection ***)&data->array, &data->tot);
|
||||
BLI_assert(data->tot != 0);
|
||||
|
||||
data->cur = 0;
|
||||
iter->current = data->array[data->cur];
|
||||
iter->valid = true;
|
||||
}
|
||||
|
||||
void BKE_scene_collections_Iterator_next(struct Iterator *iter)
|
||||
{
|
||||
SceneCollectionsIteratorData *data = iter->data;
|
||||
|
||||
if (++data->cur < data->tot) {
|
||||
iter->current = data->array[data->cur];
|
||||
}
|
||||
else {
|
||||
iter->valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_scene_collections_Iterator_end(struct Iterator *iter)
|
||||
{
|
||||
SceneCollectionsIteratorData *data = iter->data;
|
||||
|
||||
if (data) {
|
||||
if (data->array) {
|
||||
MEM_freeN(data->array);
|
||||
}
|
||||
MEM_freeN(data);
|
||||
}
|
||||
iter->valid = false;
|
||||
}
|
||||
|
||||
|
||||
/* scene objects iteractor */
|
||||
|
||||
typedef struct SceneObjectsIteratorData {
|
||||
GSet *visited;
|
||||
LinkData *link;
|
||||
Iterator scene_collection_iter;
|
||||
} SceneObjectsIteratorData;
|
||||
|
||||
void BKE_scene_objects_Iterator_begin(Iterator *iter, void *data_in)
|
||||
{
|
||||
Scene *scene = data_in;
|
||||
SceneObjectsIteratorData *data = MEM_callocN(sizeof(SceneObjectsIteratorData), __FUNCTION__);
|
||||
iter->data = data;
|
||||
|
||||
/* lookup list ot make sure each object is object called once */
|
||||
data->visited = BLI_gset_ptr_new(__func__);
|
||||
|
||||
/* we wrap the scenecollection iterator here to go over the scene collections */
|
||||
BKE_scene_collections_Iterator_begin(&data->scene_collection_iter, scene);
|
||||
|
||||
SceneCollection *sc = data->scene_collection_iter.current;
|
||||
iter->current = sc->objects.first;
|
||||
|
||||
if (iter->current == NULL) {
|
||||
BKE_scene_objects_Iterator_next(iter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next unique object
|
||||
*/
|
||||
static LinkData *object_base_next(GSet *gs, LinkData *link)
|
||||
{
|
||||
if (link == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LinkData *link_next = link->next;
|
||||
if (link_next) {
|
||||
Object *ob = link_next->data;
|
||||
if (!BLI_gset_haskey(gs, ob)) {
|
||||
BLI_gset_add(gs, ob);
|
||||
return link_next;
|
||||
}
|
||||
else {
|
||||
return object_base_next(gs, link_next);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void BKE_scene_objects_Iterator_next(Iterator *iter)
|
||||
{
|
||||
SceneObjectsIteratorData *data = iter->data;
|
||||
LinkData *link = object_base_next(data->visited, data->link);
|
||||
|
||||
if (link) {
|
||||
data->link = link;
|
||||
iter->current = link->data;
|
||||
}
|
||||
else {
|
||||
/* if this is the last object of this ListBase look at the next SceneCollection */
|
||||
SceneCollection *sc;
|
||||
BKE_scene_collections_Iterator_next(&data->scene_collection_iter);
|
||||
do {
|
||||
sc = data->scene_collection_iter.current;
|
||||
/* get the first unique object of this collection */
|
||||
LinkData *new_link = object_base_next(data->visited, sc->objects.first);
|
||||
if (new_link) {
|
||||
data->link = new_link;
|
||||
iter->current = data->link->data;
|
||||
return;
|
||||
}
|
||||
BKE_scene_collections_Iterator_next(&data->scene_collection_iter);
|
||||
} while (data->scene_collection_iter.valid);
|
||||
|
||||
if (!data->scene_collection_iter.valid) {
|
||||
iter->valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_scene_objects_Iterator_end(Iterator *iter)
|
||||
{
|
||||
SceneObjectsIteratorData *data = iter->data;
|
||||
if (data) {
|
||||
BKE_scene_collections_Iterator_end(&data->scene_collection_iter);
|
||||
BLI_gset_free(data->visited, NULL);
|
||||
MEM_freeN(data);
|
||||
}
|
||||
}
|
@@ -514,7 +514,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
|
||||
// collision object will exclude self
|
||||
Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, int layer, unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
|
||||
{
|
||||
Base *base;
|
||||
BaseLegacy *base;
|
||||
Object **objs;
|
||||
GroupObject *go;
|
||||
unsigned int numobj= 0, maxobj= 100;
|
||||
@@ -596,7 +596,7 @@ ListBase *get_collider_cache(Scene *scene, Object *self, Group *group)
|
||||
}
|
||||
else {
|
||||
Scene *sce_iter;
|
||||
Base *base;
|
||||
BaseLegacy *base;
|
||||
|
||||
/* add objects in same layer in scene */
|
||||
for (SETLOOPER(scene, sce_iter, base)) {
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_sound.h"
|
||||
@@ -814,6 +815,14 @@ struct SpaceClip *CTX_wm_space_clip(const bContext *C)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct SpaceCollections *CTX_wm_space_collections(const bContext *C)
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
if (sa && sa->spacetype == SPACE_COLLECTIONS)
|
||||
return sa->spacedata.first;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
|
||||
{
|
||||
C->wm.manager = wm;
|
||||
@@ -836,8 +845,9 @@ void CTX_wm_window_set(bContext *C, wmWindow *win)
|
||||
void CTX_wm_screen_set(bContext *C, bScreen *screen)
|
||||
{
|
||||
C->wm.screen = screen;
|
||||
if (C->wm.screen)
|
||||
C->data.scene = C->wm.screen->scene;
|
||||
if (C->wm.screen) {
|
||||
CTX_data_scene_set(C, C->wm.screen->scene);
|
||||
}
|
||||
C->wm.area = NULL;
|
||||
C->wm.region = NULL;
|
||||
}
|
||||
@@ -896,6 +906,62 @@ Scene *CTX_data_scene(const bContext *C)
|
||||
return C->data.scene;
|
||||
}
|
||||
|
||||
SceneLayer *CTX_data_scene_layer(const bContext *C)
|
||||
{
|
||||
SceneLayer *sl;
|
||||
|
||||
if (ctx_data_pointer_verify(C, "render_layer", (void *)&sl)) {
|
||||
return sl;
|
||||
}
|
||||
else {
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
sl = BLI_findlink(&scene->render_layers, scene->active_layer);
|
||||
BLI_assert(sl);
|
||||
return sl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is tricky. Sometimes the user overrides the render_layer
|
||||
* but not the scene_collection. In this case what to do?
|
||||
*
|
||||
* If the scene_collection is linked to the SceneLayer we use it.
|
||||
* Otherwise we fallback to the active one of the SceneLayer.
|
||||
*/
|
||||
LayerCollection *CTX_data_layer_collection(const bContext *C)
|
||||
{
|
||||
SceneLayer *sl = CTX_data_scene_layer(C);
|
||||
LayerCollection *lc;
|
||||
|
||||
if (ctx_data_pointer_verify(C, "layer_collection", (void *)&lc)) {
|
||||
if (BKE_scene_layer_has_collection(sl, lc->scene_collection)) {
|
||||
return lc;
|
||||
}
|
||||
}
|
||||
|
||||
/* fallback */
|
||||
return BKE_layer_collection_active(sl);
|
||||
}
|
||||
|
||||
SceneCollection *CTX_data_scene_collection(const bContext *C)
|
||||
{
|
||||
SceneCollection *sc;
|
||||
if (ctx_data_pointer_verify(C, "scene_collection", (void *)&sc)) {
|
||||
if (BKE_scene_layer_has_collection(CTX_data_scene_layer(C), sc)) {
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
|
||||
LayerCollection *lc = CTX_data_layer_collection(C);
|
||||
if (lc) {
|
||||
return lc->scene_collection;
|
||||
}
|
||||
|
||||
/* fallback */
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
return BKE_collection_master(scene);
|
||||
}
|
||||
|
||||
int CTX_data_mode_enum(const bContext *C)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
|
@@ -488,7 +488,7 @@ static void scene_setSubframe(Scene *scene, float subframe)
|
||||
|
||||
static int surface_getBrushFlags(DynamicPaintSurface *surface, const Scene *scene)
|
||||
{
|
||||
Base *base = NULL;
|
||||
BaseLegacy *base = NULL;
|
||||
GroupObject *go = NULL;
|
||||
Object *brushObj = NULL;
|
||||
ModifierData *md = NULL;
|
||||
@@ -5780,7 +5780,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
|
||||
* Loop through surface's target paint objects and do painting
|
||||
*/
|
||||
{
|
||||
Base *base = NULL;
|
||||
BaseLegacy *base = NULL;
|
||||
GroupObject *go = NULL;
|
||||
Object *brushObj = NULL;
|
||||
ModifierData *md = NULL;
|
||||
|
@@ -209,7 +209,7 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
|
||||
ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
|
||||
EffectorWeights *weights, bool for_simulation)
|
||||
{
|
||||
Base *base;
|
||||
BaseLegacy *base;
|
||||
unsigned int layer= ob_src->lay;
|
||||
ListBase *effectors = NULL;
|
||||
|
||||
|
@@ -130,18 +130,11 @@ static bool group_object_add_internal(Group *group, Object *ob)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BKE_group_object_add(Group *group, Object *object, Scene *scene, Base *base)
|
||||
bool BKE_group_object_add(Group *group, Object *object)
|
||||
{
|
||||
if (group_object_add_internal(group, object)) {
|
||||
if ((object->flag & OB_FROMGROUP) == 0) {
|
||||
|
||||
if (scene && base == NULL)
|
||||
base = BKE_scene_base_find(scene, object);
|
||||
|
||||
object->flag |= OB_FROMGROUP;
|
||||
|
||||
if (base)
|
||||
base->flag |= OB_FROMGROUP;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -208,18 +201,12 @@ bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group)
|
||||
return group_object_cyclic_check_internal(object, group);
|
||||
}
|
||||
|
||||
bool BKE_group_object_unlink(Group *group, Object *object, Scene *scene, Base *base)
|
||||
bool BKE_group_object_unlink(Group *group, Object *object)
|
||||
{
|
||||
if (group_object_unlink_internal(group, object)) {
|
||||
/* object can be NULL */
|
||||
if (object && BKE_group_object_find(NULL, object) == NULL) {
|
||||
if (scene && base == NULL)
|
||||
base = BKE_scene_base_find(scene, object);
|
||||
|
||||
object->flag &= ~OB_FROMGROUP;
|
||||
|
||||
if (base)
|
||||
base->flag &= ~OB_FROMGROUP;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
924
source/blender/blenkernel/intern/layer.c
Normal file
924
source/blender/blenkernel/intern/layer.c
Normal file
@@ -0,0 +1,924 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Dalai Felinto
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/blenkernel/intern/layer.c
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.h"
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/* prototype */
|
||||
struct CollectionEngineSettingsCB_Type;
|
||||
static void layer_collection_free(SceneLayer *sl, LayerCollection *lc);
|
||||
static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc);
|
||||
static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc);
|
||||
static void collection_engine_settings_create(ListBase *lb, struct CollectionEngineSettingsCB_Type *ces_type);
|
||||
static void layer_collection_create_engine_settings(LayerCollection *lc);
|
||||
static void object_bases_Iterator_next(Iterator *iter, const int flag);
|
||||
|
||||
/* RenderLayer */
|
||||
|
||||
/**
|
||||
* Add a new renderlayer
|
||||
* by default, a renderlayer has the master collection
|
||||
*/
|
||||
SceneLayer *BKE_scene_layer_add(Scene *scene, const char *name)
|
||||
{
|
||||
if (!name) {
|
||||
name = DATA_("Render Layer");
|
||||
}
|
||||
|
||||
SceneLayer *sl = MEM_callocN(sizeof(SceneLayer), "Scene Layer");
|
||||
sl->flag |= SCENE_LAYER_RENDER;
|
||||
|
||||
BLI_addtail(&scene->render_layers, sl);
|
||||
|
||||
/* unique name */
|
||||
BLI_strncpy_utf8(sl->name, name, sizeof(sl->name));
|
||||
BLI_uniquename(&scene->render_layers, sl, DATA_("SceneLayer"), '.', offsetof(SceneLayer, name), sizeof(sl->name));
|
||||
|
||||
SceneCollection *sc = BKE_collection_master(scene);
|
||||
layer_collection_add(sl, &sl->layer_collections, sc);
|
||||
|
||||
return sl;
|
||||
}
|
||||
|
||||
bool BKE_scene_layer_remove(Main *bmain, Scene *scene, SceneLayer *sl)
|
||||
{
|
||||
const int act = BLI_findindex(&scene->render_layers, sl);
|
||||
|
||||
if (act == -1) {
|
||||
return false;
|
||||
}
|
||||
else if ( (scene->render_layers.first == scene->render_layers.last) &&
|
||||
(scene->render_layers.first == sl))
|
||||
{
|
||||
/* ensure 1 layer is kept */
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_remlink(&scene->render_layers, sl);
|
||||
|
||||
BKE_scene_layer_free(sl);
|
||||
MEM_freeN(sl);
|
||||
|
||||
scene->active_layer = 0;
|
||||
/* TODO WORKSPACE: set active_layer to 0 */
|
||||
|
||||
for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
|
||||
if (sce->nodetree) {
|
||||
BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free (or release) any data used by this SceneLayer (does not free the SceneLayer itself).
|
||||
*/
|
||||
void BKE_scene_layer_free(SceneLayer *sl)
|
||||
{
|
||||
sl->basact = NULL;
|
||||
BLI_freelistN(&sl->object_bases);
|
||||
|
||||
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
|
||||
layer_collection_free(NULL, lc);
|
||||
}
|
||||
BLI_freelistN(&sl->layer_collections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the render engine of a renderlayer
|
||||
*/
|
||||
void BKE_scene_layer_engine_set(SceneLayer *sl, const char *engine)
|
||||
{
|
||||
BLI_strncpy_utf8(sl->engine, engine, sizeof(sl->engine));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag all the selected objects of a renderlayer
|
||||
*/
|
||||
void BKE_scene_layer_selected_objects_tag(SceneLayer *sl, const int tag)
|
||||
{
|
||||
for (Base *base = sl->object_bases.first; base; base = base->next) {
|
||||
if ((base->flag & BASE_SELECTED) != 0) {
|
||||
base->object->flag |= tag;
|
||||
}
|
||||
else {
|
||||
base->object->flag &= ~tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool find_scene_collection_in_scene_collections(ListBase *lb, const LayerCollection *lc)
|
||||
{
|
||||
for (LayerCollection *lcn = lb->first; lcn; lcn = lcn->next) {
|
||||
if (lcn == lc) {
|
||||
return true;
|
||||
}
|
||||
if (find_scene_collection_in_scene_collections(&lcn->layer_collections, lc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the SceneLayer a LayerCollection belongs to
|
||||
*/
|
||||
SceneLayer *BKE_scene_layer_find_from_collection(Scene *scene, LayerCollection *lc)
|
||||
{
|
||||
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
if (find_scene_collection_in_scene_collections(&sl->layer_collections, lc)) {
|
||||
return sl;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Base */
|
||||
|
||||
Base *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
|
||||
{
|
||||
return BLI_findptr(&sl->object_bases, ob, offsetof(Base, object));
|
||||
}
|
||||
|
||||
void BKE_scene_layer_base_deselect_all(SceneLayer *sl)
|
||||
{
|
||||
Base *base;
|
||||
|
||||
for (base = sl->object_bases.first; base; base = base->next) {
|
||||
base->flag &= ~BASE_SELECTED;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_scene_layer_base_select(struct SceneLayer *sl, Base *selbase)
|
||||
{
|
||||
sl->basact = selbase;
|
||||
if ((selbase->flag & BASE_SELECTABLED) != 0) {
|
||||
selbase->flag |= BASE_SELECTED;
|
||||
}
|
||||
}
|
||||
|
||||
static void scene_layer_object_base_unref(SceneLayer* sl, Base *base)
|
||||
{
|
||||
base->refcount--;
|
||||
|
||||
/* It only exists in the RenderLayer */
|
||||
if (base->refcount == 0) {
|
||||
if (sl->basact == base) {
|
||||
sl->basact = NULL;
|
||||
}
|
||||
|
||||
BLI_remlink(&sl->object_bases, base);
|
||||
MEM_freeN(base);
|
||||
}
|
||||
}
|
||||
|
||||
static void layer_collection_base_flag_recalculate(LayerCollection *lc, const bool tree_is_visible, const bool tree_is_selectable)
|
||||
{
|
||||
bool is_visible = tree_is_visible && ((lc->flag & COLLECTION_VISIBLE) != 0);
|
||||
/* an object can only be selected if it's visible */
|
||||
bool is_selectable = tree_is_selectable && is_visible && ((lc->flag & COLLECTION_SELECTABLE) != 0);
|
||||
|
||||
for (LinkData *link = lc->object_bases.first; link; link = link->next) {
|
||||
Base *base = link->data;
|
||||
|
||||
if (is_visible) {
|
||||
base->flag |= BASE_VISIBLED;
|
||||
}
|
||||
else {
|
||||
base->flag &= ~BASE_VISIBLED;
|
||||
}
|
||||
|
||||
if (is_selectable) {
|
||||
base->flag |= BASE_SELECTABLED;
|
||||
}
|
||||
else {
|
||||
base->flag &= ~BASE_SELECTABLED;
|
||||
}
|
||||
}
|
||||
|
||||
for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
|
||||
layer_collection_base_flag_recalculate(lcn, is_visible, is_selectable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-evaluate the ObjectBase flags for SceneLayer
|
||||
*/
|
||||
void BKE_scene_layer_base_flag_recalculate(SceneLayer *sl)
|
||||
{
|
||||
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
|
||||
layer_collection_base_flag_recalculate(lc, true, true);
|
||||
}
|
||||
|
||||
/* if base is not selectabled, clear select */
|
||||
for (Base *base = sl->object_bases.first; base; base = base->next) {
|
||||
if ((base->flag & BASE_SELECTABLED) == 0) {
|
||||
base->flag &= ~BASE_SELECTED;
|
||||
}
|
||||
}
|
||||
|
||||
BKE_scene_layer_engine_settings_recalculate(sl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag Scene Layer to recalculation
|
||||
*
|
||||
* Temporary function, waiting for real depsgraph
|
||||
*/
|
||||
void BKE_scene_layer_engine_settings_recalculate(struct SceneLayer *sl)
|
||||
{
|
||||
sl->flag |= SCENE_LAYER_ENGINE_DIRTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-calculate the engine settings for all the objects in SceneLayer
|
||||
*
|
||||
* Temporary function, waiting for real depsgraph
|
||||
*/
|
||||
void BKE_scene_layer_engine_settings_update(struct SceneLayer *sl)
|
||||
{
|
||||
if ((sl->flag & SCENE_LAYER_ENGINE_DIRTY) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* do the complete settings update */
|
||||
TODO_LAYER_DEPSGRAPH;
|
||||
|
||||
sl->flag &= ~SCENE_LAYER_ENGINE_DIRTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base if existent, or create it if necessary
|
||||
* Always bump the refcount
|
||||
*/
|
||||
static Base *object_base_add(SceneLayer *sl, Object *ob)
|
||||
{
|
||||
Base *base;
|
||||
base = BKE_scene_layer_base_find(sl, ob);
|
||||
|
||||
if (base == NULL) {
|
||||
base = MEM_callocN(sizeof(Base), "Object Base");
|
||||
|
||||
/* do not bump user count, leave it for SceneCollections */
|
||||
base->object = ob;
|
||||
BLI_addtail(&sl->object_bases, base);
|
||||
}
|
||||
base->refcount++;
|
||||
return base;
|
||||
}
|
||||
|
||||
/* LayerCollection */
|
||||
|
||||
/**
|
||||
* When freeing the entire SceneLayer at once we don't bother with unref
|
||||
* otherwise SceneLayer is passed to keep the syncing of the LayerCollection tree
|
||||
*/
|
||||
static void layer_collection_free(SceneLayer *sl, LayerCollection *lc)
|
||||
{
|
||||
if (sl) {
|
||||
for (LinkData *link = lc->object_bases.first; link; link = link->next) {
|
||||
scene_layer_object_base_unref(sl, link->data);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_freelistN(&lc->object_bases);
|
||||
BLI_freelistN(&lc->overrides);
|
||||
BKE_layer_collection_engine_settings_free(&lc->engine_settings);
|
||||
|
||||
for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
|
||||
layer_collection_free(sl, nlc);
|
||||
}
|
||||
|
||||
BLI_freelistN(&lc->layer_collections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free (or release) LayerCollection from SceneLayer
|
||||
* (does not free the LayerCollection itself).
|
||||
*/
|
||||
void BKE_layer_collection_free(SceneLayer *sl, LayerCollection *lc)
|
||||
{
|
||||
layer_collection_free(sl, lc);
|
||||
}
|
||||
|
||||
/* LayerCollection */
|
||||
|
||||
/**
|
||||
* Recursively get the collection for a given index
|
||||
*/
|
||||
static LayerCollection *collection_from_index(ListBase *lb, const int number, int *i)
|
||||
{
|
||||
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
|
||||
if (*i == number) {
|
||||
return lc;
|
||||
}
|
||||
|
||||
(*i)++;
|
||||
|
||||
LayerCollection *lc_nested = collection_from_index(&lc->layer_collections, number, i);
|
||||
if (lc_nested) {
|
||||
return lc_nested;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active collection
|
||||
*/
|
||||
LayerCollection *BKE_layer_collection_active(SceneLayer *sl)
|
||||
{
|
||||
int i = 0;
|
||||
return collection_from_index(&sl->layer_collections, sl->active_collection, &i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively get the count of collections
|
||||
*/
|
||||
static int collection_count(ListBase *lb)
|
||||
{
|
||||
int i = 0;
|
||||
for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
|
||||
i += collection_count(&lc->layer_collections) + 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of collections
|
||||
* (including all the nested collections)
|
||||
*/
|
||||
int BKE_layer_collection_count(SceneLayer *sl)
|
||||
{
|
||||
return collection_count(&sl->layer_collections);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively get the index for a given collection
|
||||
*/
|
||||
static int index_from_collection(ListBase *lb, LayerCollection *lc, int *i)
|
||||
{
|
||||
for (LayerCollection *lcol = lb->first; lcol; lcol = lcol->next) {
|
||||
if (lcol == lc) {
|
||||
return *i;
|
||||
}
|
||||
|
||||
(*i)++;
|
||||
|
||||
int i_nested = index_from_collection(&lcol->layer_collections, lc, i);
|
||||
if (i_nested != -1) {
|
||||
return i_nested;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return -1 if not found
|
||||
*/
|
||||
int BKE_layer_collection_findindex(SceneLayer *sl, LayerCollection *lc)
|
||||
{
|
||||
int i = 0;
|
||||
return index_from_collection(&sl->layer_collections, lc, &i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Link a collection to a renderlayer
|
||||
* The collection needs to be created separately
|
||||
*/
|
||||
LayerCollection *BKE_collection_link(SceneLayer *sl, SceneCollection *sc)
|
||||
{
|
||||
LayerCollection *lc = layer_collection_add(sl, &sl->layer_collections, sc);
|
||||
sl->active_collection = BKE_layer_collection_findindex(sl, lc);
|
||||
return lc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink a collection base from a renderlayer
|
||||
* The corresponding collection is not removed from the master collection
|
||||
*/
|
||||
void BKE_collection_unlink(SceneLayer *sl, LayerCollection *lc)
|
||||
{
|
||||
BKE_layer_collection_free(sl, lc);
|
||||
BKE_scene_layer_base_flag_recalculate(sl);
|
||||
|
||||
BLI_remlink(&sl->layer_collections, lc);
|
||||
MEM_freeN(lc);
|
||||
sl->active_collection = 0;
|
||||
}
|
||||
|
||||
static void layer_collection_object_add(SceneLayer *sl, LayerCollection *lc, Object *ob)
|
||||
{
|
||||
Base *base = object_base_add(sl, ob);
|
||||
|
||||
/* only add an object once - prevent SceneCollection->objects and
|
||||
* SceneCollection->filter_objects to add the same object */
|
||||
|
||||
if (BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data))) {
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_addtail(&lc->object_bases, BLI_genericNodeN(base));
|
||||
|
||||
BKE_scene_layer_base_flag_recalculate(sl);
|
||||
}
|
||||
|
||||
static void layer_collection_object_remove(SceneLayer *sl, LayerCollection *lc, Object *ob)
|
||||
{
|
||||
Base *base;
|
||||
base = BKE_scene_layer_base_find(sl, ob);
|
||||
|
||||
LinkData *link = BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data));
|
||||
BLI_remlink(&lc->object_bases, link);
|
||||
MEM_freeN(link);
|
||||
|
||||
scene_layer_object_base_unref(sl, base);
|
||||
}
|
||||
|
||||
static void layer_collection_objects_populate(SceneLayer *sl, LayerCollection *lc, ListBase *objects)
|
||||
{
|
||||
for (LinkData *link = objects->first; link; link = link->next) {
|
||||
layer_collection_object_add(sl, lc, link->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void layer_collection_populate(SceneLayer *sl, LayerCollection *lc, SceneCollection *sc)
|
||||
{
|
||||
layer_collection_objects_populate(sl, lc, &sc->objects);
|
||||
layer_collection_objects_populate(sl, lc, &sc->filter_objects);
|
||||
|
||||
for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
|
||||
layer_collection_add(sl, &lc->layer_collections, nsc);
|
||||
}
|
||||
}
|
||||
|
||||
static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc)
|
||||
{
|
||||
LayerCollection *lc = MEM_callocN(sizeof(LayerCollection), "Collection Base");
|
||||
BLI_addtail(lb, lc);
|
||||
|
||||
lc->scene_collection = sc;
|
||||
lc->flag = COLLECTION_VISIBLE + COLLECTION_SELECTABLE + COLLECTION_FOLDED;
|
||||
|
||||
layer_collection_create_engine_settings(lc);
|
||||
layer_collection_populate(sl, lc, sc);
|
||||
return lc;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* See if render layer has the scene collection linked directly, or indirectly (nested)
|
||||
*/
|
||||
bool BKE_scene_layer_has_collection(struct SceneLayer *sl, struct SceneCollection *sc)
|
||||
{
|
||||
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
|
||||
if (find_layer_collection_by_scene_collection(lc, sc) != NULL) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the object is in any of the scene layers of the scene
|
||||
*/
|
||||
bool BKE_scene_has_object(Scene *scene, Object *ob)
|
||||
{
|
||||
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
Base *base = BKE_scene_layer_base_find(sl, ob);
|
||||
if (base) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Syncing */
|
||||
|
||||
static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc)
|
||||
{
|
||||
if (lc->scene_collection == sc) {
|
||||
return lc;
|
||||
}
|
||||
|
||||
for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
|
||||
LayerCollection *found = find_layer_collection_by_scene_collection(nlc, sc);
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new LayerCollection for all the SceneLayers that have sc_parent
|
||||
*/
|
||||
void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc_parent, SceneCollection *sc)
|
||||
{
|
||||
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
|
||||
LayerCollection *lc_parent = find_layer_collection_by_scene_collection(lc, sc_parent);
|
||||
if (lc_parent) {
|
||||
layer_collection_add(sl, &lc_parent->layer_collections, sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a corresponding ObjectBase to all the equivalent LayerCollection
|
||||
*/
|
||||
void BKE_layer_sync_object_link(Scene *scene, SceneCollection *sc, Object *ob)
|
||||
{
|
||||
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
|
||||
LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
|
||||
if (found) {
|
||||
layer_collection_object_add(sl, found, ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the equivalent object base to all layers that have this collection
|
||||
* also remove all reference to ob in the filter_objects
|
||||
*/
|
||||
void BKE_layer_sync_object_unlink(Scene *scene, SceneCollection *sc, Object *ob)
|
||||
{
|
||||
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
|
||||
LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
|
||||
if (found) {
|
||||
layer_collection_object_remove(sl, found, ob);
|
||||
}
|
||||
}
|
||||
BKE_scene_layer_base_flag_recalculate(sl);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Override */
|
||||
|
||||
/**
|
||||
* Add a new datablock override
|
||||
*/
|
||||
void BKE_collection_override_datablock_add(LayerCollection *UNUSED(lc), const char *UNUSED(data_path), ID *UNUSED(id))
|
||||
{
|
||||
TODO_LAYER_OVERRIDE;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Engine Settings */
|
||||
|
||||
ListBase R_engines_settings_callbacks = {NULL, NULL};
|
||||
|
||||
typedef struct CollectionEngineSettingsCB_Type {
|
||||
struct CollectionEngineSettingsCB_Type *next, *prev;
|
||||
|
||||
char name[MAX_NAME]; /* engine name */
|
||||
|
||||
CollectionEngineSettingsCB callback;
|
||||
|
||||
} CollectionEngineSettingsCB_Type;
|
||||
|
||||
static void create_engine_settings_layer_collection(LayerCollection *lc, CollectionEngineSettingsCB_Type *ces_type)
|
||||
{
|
||||
if (BKE_layer_collection_engine_get(lc, ces_type->name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
collection_engine_settings_create(&lc->engine_settings, ces_type);
|
||||
|
||||
for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
|
||||
create_engine_settings_layer_collection(lcn, ces_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void create_engines_settings_scene(Scene *scene, CollectionEngineSettingsCB_Type *ces_type)
|
||||
{
|
||||
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
|
||||
create_engine_settings_layer_collection(lc, ces_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_layer_collection_engine_settings_callback_register(
|
||||
Main *bmain, const char *engine_name, CollectionEngineSettingsCB func)
|
||||
{
|
||||
CollectionEngineSettingsCB_Type *ces_type;
|
||||
|
||||
/* cleanup in case it existed */
|
||||
ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name));
|
||||
|
||||
if (ces_type) {
|
||||
BLI_remlink(&R_engines_settings_callbacks, ces_type);
|
||||
MEM_freeN(ces_type);
|
||||
}
|
||||
|
||||
ces_type = MEM_callocN(sizeof(CollectionEngineSettingsCB_Type), "collection_engine_type");
|
||||
BLI_strncpy_utf8(ces_type->name, engine_name, sizeof(ces_type->name));
|
||||
ces_type->callback = func;
|
||||
BLI_addtail(&R_engines_settings_callbacks, ces_type);
|
||||
|
||||
if (bmain) {
|
||||
/* populate all of the collections of the scene with those settings */
|
||||
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
|
||||
create_engines_settings_scene(scene, ces_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_layer_collection_engine_settings_callback_free(void)
|
||||
{
|
||||
BLI_freelistN(&R_engines_settings_callbacks);
|
||||
}
|
||||
|
||||
static void collection_engine_settings_create(ListBase *lb, CollectionEngineSettingsCB_Type *ces_type)
|
||||
{
|
||||
/* create callback data */
|
||||
CollectionEngineSettings *ces = MEM_callocN(sizeof(CollectionEngineSettings), "Collection Engine Settings");
|
||||
BLI_strncpy_utf8(ces->name, ces_type->name, sizeof(ces->name));
|
||||
BLI_addtail(lb, ces);
|
||||
|
||||
/* call callback */
|
||||
ces_type->callback(NULL, ces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a CollectionEngineSettings
|
||||
*
|
||||
* Usually we would pass LayerCollection->engine_settings
|
||||
* But depsgraph uses this for Object->collection_settings
|
||||
*/
|
||||
void BKE_layer_collection_engine_settings_create(ListBase *lb, const char *engine_name)
|
||||
{
|
||||
CollectionEngineSettingsCB_Type *ces_type;
|
||||
ces_type = BLI_findstring(&R_engines_settings_callbacks, engine_name, offsetof(CollectionEngineSettingsCB_Type, name));
|
||||
BLI_assert(ces_type);
|
||||
collection_engine_settings_create(lb, ces_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the CollectionEngineSettings ListBase
|
||||
*
|
||||
* Usually we would pass LayerCollection->engine_settings
|
||||
* But depsgraph uses this for Object->collection_settings
|
||||
*/
|
||||
void BKE_layer_collection_engine_settings_free(ListBase *lb)
|
||||
{
|
||||
for (CollectionEngineSettings *cse = lb->first; cse; cse = cse->next) {
|
||||
BLI_freelistN(&cse->properties);
|
||||
}
|
||||
BLI_freelistN(lb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the render settings for a single LayerCollection
|
||||
*/
|
||||
static void layer_collection_create_engine_settings(LayerCollection *lc)
|
||||
{
|
||||
CollectionEngineSettingsCB_Type *ces_type;
|
||||
for (ces_type = R_engines_settings_callbacks.first; ces_type; ces_type = ces_type->next) {
|
||||
create_engine_settings_layer_collection(lc, ces_type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return layer collection engine settings for specified engine
|
||||
*/
|
||||
CollectionEngineSettings *BKE_layer_collection_engine_get(LayerCollection *lc, const char *engine_name)
|
||||
{
|
||||
CollectionEngineSettings *ces;
|
||||
ces = BLI_findstring(&lc->engine_settings, engine_name, offsetof(CollectionEngineSettings, name));
|
||||
return ces;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Engine Settings Properties */
|
||||
|
||||
void BKE_collection_engine_property_add_float(CollectionEngineSettings *ces, const char *name, float value)
|
||||
{
|
||||
CollectionEnginePropertyFloat *prop;
|
||||
prop = MEM_callocN(sizeof(CollectionEnginePropertyFloat), "collection engine settings float");
|
||||
prop->data.type = COLLECTION_PROP_TYPE_FLOAT;
|
||||
BLI_strncpy_utf8(prop->data.name, name, sizeof(prop->data.name));
|
||||
prop->value = value;
|
||||
BLI_addtail(&ces->properties, prop);
|
||||
}
|
||||
|
||||
void BKE_collection_engine_property_add_int(CollectionEngineSettings *ces, const char *name, int value)
|
||||
{
|
||||
CollectionEnginePropertyInt *prop;
|
||||
prop = MEM_callocN(sizeof(CollectionEnginePropertyInt), "collection engine settings int");
|
||||
prop->data.type = COLLECTION_PROP_TYPE_INT;
|
||||
BLI_strncpy_utf8(prop->data.name, name, sizeof(prop->data.name));
|
||||
prop->value = value;
|
||||
BLI_addtail(&ces->properties, prop);
|
||||
}
|
||||
|
||||
CollectionEngineProperty *BKE_collection_engine_property_get(CollectionEngineSettings *ces, const char *name)
|
||||
{
|
||||
return BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
|
||||
}
|
||||
|
||||
int BKE_collection_engine_property_value_get_int(CollectionEngineSettings *ces, const char *name)
|
||||
{
|
||||
CollectionEnginePropertyInt *prop;
|
||||
prop = (CollectionEnginePropertyInt *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
|
||||
return prop->value;
|
||||
}
|
||||
|
||||
float BKE_collection_engine_property_value_get_float(CollectionEngineSettings *ces, const char *name)
|
||||
{
|
||||
CollectionEnginePropertyFloat *prop;
|
||||
prop = (CollectionEnginePropertyFloat *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
|
||||
return prop->value;
|
||||
}
|
||||
|
||||
void BKE_collection_engine_property_value_set_int(CollectionEngineSettings *ces, const char *name, int value)
|
||||
{
|
||||
CollectionEnginePropertyInt *prop;
|
||||
prop = (CollectionEnginePropertyInt *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
|
||||
prop->value = value;
|
||||
prop->data.flag |= COLLECTION_PROP_USE;
|
||||
}
|
||||
|
||||
void BKE_collection_engine_property_value_set_float(CollectionEngineSettings *ces, const char *name, float value)
|
||||
{
|
||||
CollectionEnginePropertyFloat *prop;
|
||||
prop = (CollectionEnginePropertyFloat *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
|
||||
prop->value = value;
|
||||
prop->data.flag |= COLLECTION_PROP_USE;
|
||||
}
|
||||
|
||||
bool BKE_collection_engine_property_use_get(CollectionEngineSettings *ces, const char *name)
|
||||
{
|
||||
CollectionEngineProperty *prop;
|
||||
prop = (CollectionEngineProperty *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
|
||||
return ((prop->flag & COLLECTION_PROP_USE) != 0);
|
||||
}
|
||||
|
||||
void BKE_collection_engine_property_use_set(CollectionEngineSettings *ces, const char *name, bool value)
|
||||
{
|
||||
CollectionEngineProperty *prop;
|
||||
prop = (CollectionEngineProperty *)BLI_findstring(&ces->properties, name, offsetof(CollectionEngineProperty, name));
|
||||
|
||||
if (value) {
|
||||
prop->flag |= COLLECTION_PROP_USE;
|
||||
}
|
||||
else {
|
||||
prop->flag &= ~COLLECTION_PROP_USE;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Iterators */
|
||||
|
||||
static void object_bases_Iterator_begin(Iterator *iter, void *data_in, const int flag)
|
||||
{
|
||||
SceneLayer *sl = data_in;
|
||||
Base *base = sl->object_bases.first;
|
||||
|
||||
/* when there are no objects */
|
||||
if (base == NULL) {
|
||||
iter->valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
iter->valid = true;
|
||||
iter->data = base;
|
||||
|
||||
if ((base->flag & flag) == 0) {
|
||||
object_bases_Iterator_next(iter, flag);
|
||||
}
|
||||
else {
|
||||
iter->current = base;
|
||||
}
|
||||
}
|
||||
|
||||
static void object_bases_Iterator_next(Iterator *iter, const int flag)
|
||||
{
|
||||
Base *base = ((Base *)iter->data)->next;
|
||||
|
||||
while (base) {
|
||||
if ((base->flag & flag) != 0) {
|
||||
iter->current = base;
|
||||
iter->data = base;
|
||||
return;
|
||||
}
|
||||
base = base->next;
|
||||
}
|
||||
|
||||
iter->current = NULL;
|
||||
iter->valid = false;
|
||||
}
|
||||
|
||||
static void objects_Iterator_begin(Iterator *iter, void *data_in, const int flag)
|
||||
{
|
||||
object_bases_Iterator_begin(iter, data_in, flag);
|
||||
|
||||
if (iter->valid) {
|
||||
iter->current = ((Base *)iter->current)->object;
|
||||
}
|
||||
}
|
||||
|
||||
static void objects_Iterator_next(Iterator *iter, const int flag)
|
||||
{
|
||||
object_bases_Iterator_next(iter, flag);
|
||||
|
||||
if (iter->valid) {
|
||||
iter->current = ((Base *)iter->current)->object;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_selected_objects_Iterator_begin(Iterator *iter, void *data_in)
|
||||
{
|
||||
objects_Iterator_begin(iter, data_in, BASE_SELECTED);
|
||||
}
|
||||
|
||||
void BKE_selected_objects_Iterator_next(Iterator *iter)
|
||||
{
|
||||
objects_Iterator_next(iter, BASE_SELECTED);
|
||||
}
|
||||
|
||||
void BKE_selected_objects_Iterator_end(Iterator *UNUSED(iter))
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
void BKE_visible_objects_Iterator_begin(Iterator *iter, void *data_in)
|
||||
{
|
||||
objects_Iterator_begin(iter, data_in, BASE_VISIBLED);
|
||||
}
|
||||
|
||||
void BKE_visible_objects_Iterator_next(Iterator *iter)
|
||||
{
|
||||
objects_Iterator_next(iter, BASE_VISIBLED);
|
||||
}
|
||||
|
||||
void BKE_visible_objects_Iterator_end(Iterator *UNUSED(iter))
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
void BKE_visible_bases_Iterator_begin(Iterator *iter, void *data_in)
|
||||
{
|
||||
object_bases_Iterator_begin(iter, data_in, BASE_VISIBLED);
|
||||
}
|
||||
|
||||
void BKE_visible_bases_Iterator_next(Iterator *iter)
|
||||
{
|
||||
object_bases_Iterator_next(iter, BASE_VISIBLED);
|
||||
}
|
||||
|
||||
void BKE_visible_bases_Iterator_end(Iterator *UNUSED(iter))
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
@@ -76,6 +76,7 @@
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_mempool.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "BLI_threads.h"
|
||||
@@ -273,8 +274,12 @@ void BKE_id_clear_newpoin(ID *id)
|
||||
}
|
||||
|
||||
static int id_expand_local_callback(
|
||||
void *UNUSED(user_data), struct ID *id_self, struct ID **id_pointer, int UNUSED(cd_flag))
|
||||
void *UNUSED(user_data), struct ID *id_self, struct ID **id_pointer, int cb_flag)
|
||||
{
|
||||
if (cb_flag & IDWALK_CB_PRIVATE) {
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
/* Can hapen that we get unlinkable ID here, e.g. with shapekey referring to itself (through drivers)...
|
||||
* Just skip it, shape key can only be either indirectly linked, or fully local, period.
|
||||
* And let's curse one more time that stupid useless shapekey ID type! */
|
||||
@@ -288,9 +293,9 @@ static int id_expand_local_callback(
|
||||
/**
|
||||
* Expand ID usages of given id as 'extern' (and no more indirect) linked data. Used by ID copy/make_local functions.
|
||||
*/
|
||||
void BKE_id_expand_local(ID *id)
|
||||
void BKE_id_expand_local(Main *bmain, ID *id)
|
||||
{
|
||||
BKE_library_foreach_ID_link(id, id_expand_local_callback, NULL, 0);
|
||||
BKE_library_foreach_ID_link(bmain, id, id_expand_local_callback, NULL, IDWALK_READONLY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,7 +304,7 @@ void BKE_id_expand_local(ID *id)
|
||||
void BKE_id_copy_ensure_local(Main *bmain, ID *old_id, ID *new_id)
|
||||
{
|
||||
if (ID_IS_LINKED_DATABLOCK(old_id)) {
|
||||
BKE_id_expand_local(new_id);
|
||||
BKE_id_expand_local(bmain, new_id);
|
||||
BKE_id_lib_local_paths(bmain, old_id->lib, new_id);
|
||||
}
|
||||
}
|
||||
@@ -326,7 +331,7 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c
|
||||
if (lib_local || is_local) {
|
||||
if (!is_lib) {
|
||||
id_clear_lib_data_ex(bmain, id, id_in_mainlist);
|
||||
BKE_id_expand_local(id);
|
||||
BKE_id_expand_local(bmain, id);
|
||||
}
|
||||
else {
|
||||
ID *id_new;
|
||||
@@ -1252,6 +1257,10 @@ void BKE_main_free(Main *mainvar)
|
||||
}
|
||||
}
|
||||
|
||||
if (mainvar->relations) {
|
||||
BKE_main_relations_free(mainvar);
|
||||
}
|
||||
|
||||
BLI_spin_end((SpinLock *)mainvar->lock);
|
||||
MEM_freeN(mainvar->lock);
|
||||
DEG_evaluation_context_free(mainvar->eval_ctx);
|
||||
@@ -1268,6 +1277,78 @@ void BKE_main_unlock(struct Main *bmain)
|
||||
BLI_spin_unlock((SpinLock *) bmain->lock);
|
||||
}
|
||||
|
||||
|
||||
static int main_relations_create_cb(void *user_data, ID *id_self, ID **id_pointer, int cb_flag)
|
||||
{
|
||||
MainIDRelations *rel = user_data;
|
||||
|
||||
if (*id_pointer) {
|
||||
MainIDRelationsEntry *entry, **entry_p;
|
||||
|
||||
entry = BLI_mempool_alloc(rel->entry_pool);
|
||||
if (BLI_ghash_ensure_p(rel->id_user_to_used, id_self, (void ***)&entry_p)) {
|
||||
entry->next = *entry_p;
|
||||
}
|
||||
else {
|
||||
entry->next = NULL;
|
||||
}
|
||||
entry->id_pointer = id_pointer;
|
||||
entry->usage_flag = cb_flag;
|
||||
*entry_p = entry;
|
||||
|
||||
entry = BLI_mempool_alloc(rel->entry_pool);
|
||||
if (BLI_ghash_ensure_p(rel->id_used_to_user, *id_pointer, (void ***)&entry_p)) {
|
||||
entry->next = *entry_p;
|
||||
}
|
||||
else {
|
||||
entry->next = NULL;
|
||||
}
|
||||
entry->id_pointer = (ID **)id_self;
|
||||
entry->usage_flag = cb_flag;
|
||||
*entry_p = entry;
|
||||
}
|
||||
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
/** Generate the mappings between used IDs and their users, and vice-versa. */
|
||||
void BKE_main_relations_create(Main *bmain)
|
||||
{
|
||||
ListBase *lbarray[MAX_LIBARRAY];
|
||||
ID *id;
|
||||
int a;
|
||||
|
||||
if (bmain->relations != NULL) {
|
||||
BKE_main_relations_free(bmain);
|
||||
}
|
||||
|
||||
bmain->relations = MEM_mallocN(sizeof(*bmain->relations), __func__);
|
||||
bmain->relations->id_used_to_user = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
|
||||
bmain->relations->id_user_to_used = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
|
||||
bmain->relations->entry_pool = BLI_mempool_create(sizeof(MainIDRelationsEntry), 128, 128, BLI_MEMPOOL_NOP);
|
||||
|
||||
for (a = set_listbasepointers(bmain, lbarray); a--; ) {
|
||||
for (id = lbarray[a]->first; id; id = id->next) {
|
||||
BKE_library_foreach_ID_link(NULL, id, main_relations_create_cb, bmain->relations, IDWALK_READONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_main_relations_free(Main *bmain)
|
||||
{
|
||||
if (bmain->relations) {
|
||||
if (bmain->relations->id_used_to_user) {
|
||||
BLI_ghash_free(bmain->relations->id_used_to_user, NULL, NULL);
|
||||
}
|
||||
if (bmain->relations->id_user_to_used) {
|
||||
BLI_ghash_free(bmain->relations->id_user_to_used, NULL, NULL);
|
||||
}
|
||||
BLI_mempool_destroy(bmain->relations->entry_pool);
|
||||
MEM_freeN(bmain->relations);
|
||||
bmain->relations = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a raw .blend file thumbnail data from given image.
|
||||
*
|
||||
@@ -1623,6 +1704,53 @@ void BKE_main_id_clear_newpoins(Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void library_make_local_copying_check(ID *id, GSet *loop_tags, MainIDRelations *id_relations, GSet *done_ids)
|
||||
{
|
||||
if (BLI_gset_haskey(done_ids, id)) {
|
||||
return; /* Already checked, nothing else to do. */
|
||||
}
|
||||
|
||||
MainIDRelationsEntry *entry = BLI_ghash_lookup(id_relations->id_used_to_user, id);
|
||||
BLI_gset_insert(loop_tags, id);
|
||||
for (; entry != NULL; entry = entry->next) {
|
||||
ID *par_id = (ID *)entry->id_pointer; /* used_to_user stores ID pointer, not pointer to ID pointer... */
|
||||
|
||||
/* Shapekeys are considered 'private' to their owner ID here, and never tagged (since they cannot be linked),
|
||||
* so we have to switch effective parent to their owner. */
|
||||
if (GS(par_id->name) == ID_KE) {
|
||||
par_id = ((Key *)par_id)->from;
|
||||
}
|
||||
|
||||
if (par_id->lib == NULL) {
|
||||
/* Local user, early out to avoid some gset querying... */
|
||||
continue;
|
||||
}
|
||||
if (!BLI_gset_haskey(done_ids, par_id)) {
|
||||
if (BLI_gset_haskey(loop_tags, par_id)) {
|
||||
/* We are in a 'dependency loop' of IDs, this does not say us anything, skip it.
|
||||
* Note that this is the situation that can lead to archipelagoes of linked data-blocks
|
||||
* (since all of them have non-local users, they would all be duplicated, leading to a loop of unused
|
||||
* linked data-blocks that cannot be freed since they all use each other...). */
|
||||
continue;
|
||||
}
|
||||
/* Else, recursively check that user ID. */
|
||||
library_make_local_copying_check(par_id, loop_tags, id_relations, done_ids);
|
||||
}
|
||||
|
||||
if (par_id->tag & LIB_TAG_DOIT) {
|
||||
/* This user will be fully local in future, so far so good, nothing to do here but check next user. */
|
||||
}
|
||||
else {
|
||||
/* This user won't be fully local in future, so current ID won't be either. And we are done checking it. */
|
||||
id->tag &= ~LIB_TAG_DOIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_gset_add(done_ids, id);
|
||||
BLI_gset_remove(loop_tags, id, NULL);
|
||||
}
|
||||
|
||||
/** Make linked datablocks local.
|
||||
*
|
||||
* \param bmain Almost certainly G.main.
|
||||
@@ -1633,11 +1761,10 @@ void BKE_main_id_clear_newpoins(Main *bmain)
|
||||
/* Note: Old (2.77) version was simply making (tagging) datablocks as local, without actually making any check whether
|
||||
* they were also indirectly used or not...
|
||||
*
|
||||
* Current version uses regular id_make_local callback, which is not super-efficient since this ends up
|
||||
* duplicating some IDs and then removing original ones (due to missing knowledge of which ID uses some other ID).
|
||||
*
|
||||
* However, we now have a first check that allows us to use 'direct localization' of a lot of IDs, so performances
|
||||
* are now *reasonably* OK.
|
||||
* Current version uses regular id_make_local callback, with advanced pre-processing step to detect all cases of
|
||||
* IDs currently indirectly used, but which will be used by local data only once this function is finished.
|
||||
* This allows to avoid any uneeded duplication of IDs, and hence all time lost afterwards to remove
|
||||
* orphaned linked data-blocks...
|
||||
*/
|
||||
void BKE_library_make_local(
|
||||
Main *bmain, const Library *lib, GHash *old_to_new_ids, const bool untagged_only, const bool set_fake)
|
||||
@@ -1648,9 +1775,12 @@ void BKE_library_make_local(
|
||||
|
||||
LinkNode *todo_ids = NULL;
|
||||
LinkNode *copied_ids = NULL;
|
||||
LinkNode *linked_loop_candidates = NULL;
|
||||
MemArena *linklist_mem = BLI_memarena_new(512 * sizeof(*todo_ids), __func__);
|
||||
|
||||
BKE_main_relations_create(bmain);
|
||||
|
||||
GSet *done_ids = BLI_gset_ptr_new(__func__);
|
||||
|
||||
/* Step 1: Detect datablocks to make local. */
|
||||
for (a = set_listbasepointers(bmain, lbarray); a--; ) {
|
||||
id = lbarray[a]->first;
|
||||
@@ -1660,16 +1790,25 @@ void BKE_library_make_local(
|
||||
const bool do_skip = (id && !BKE_idcode_is_linkable(GS(id->name)));
|
||||
|
||||
for (; id; id = id->next) {
|
||||
ID *ntree = (ID *)ntreeFromID(id);
|
||||
|
||||
id->tag &= ~LIB_TAG_DOIT;
|
||||
if (ntree != NULL) {
|
||||
ntree->tag &= ~LIB_TAG_DOIT;
|
||||
}
|
||||
|
||||
if (id->lib == NULL) {
|
||||
id->tag &= ~(LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW);
|
||||
}
|
||||
/* The check on the fourth line (LIB_TAG_PRE_EXISTING) is done so its
|
||||
* possible to tag data you don't want to be made local, used for
|
||||
* appending data, so any libdata already linked wont become local
|
||||
* (very nasty to discover all your links are lost after appending).
|
||||
/* The check on the fourth line (LIB_TAG_PRE_EXISTING) is done so its possible to tag data you don't want to
|
||||
* be made local, used for appending data, so any libdata already linked wont become local (very nasty
|
||||
* to discover all your links are lost after appending).
|
||||
* Also, never ever make proxified objects local, would not make any sense. */
|
||||
/* Some more notes:
|
||||
* - Shapekeys are never tagged here (since they are not linkable).
|
||||
* - Nodetrees used in materials etc. have to be tagged manually, since they do not exist in Main (!).
|
||||
* This is ok-ish on 'make local' side of things (since those are handled by their 'owner' IDs),
|
||||
* but complicates slightly the pre-processing of relations between IDs at step 2... */
|
||||
else if (!do_skip && id->tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT | LIB_TAG_NEW) &&
|
||||
ELEM(lib, NULL, id->lib) &&
|
||||
!(GS(id->name) == ID_OB && ((Object *)id)->proxy_from != NULL) &&
|
||||
@@ -1677,13 +1816,32 @@ void BKE_library_make_local(
|
||||
{
|
||||
BLI_linklist_prepend_arena(&todo_ids, id, linklist_mem);
|
||||
id->tag |= LIB_TAG_DOIT;
|
||||
|
||||
/* Tag those nasty non-ID nodetrees, but do not add them to todo list, making them local is handled
|
||||
* by 'owner' ID. This is needed for library_make_local_copying_check() to work OK at step 2. */
|
||||
if (ntree != NULL) {
|
||||
ntree->tag |= LIB_TAG_DOIT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Linked ID that we won't be making local (needed info for step 2, see below). */
|
||||
BLI_gset_add(done_ids, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 2: Check which datablocks we can directly make local (because they are only used by already, or future,
|
||||
* local data), others will need to be duplicated and further processed later. */
|
||||
BKE_library_indirectly_used_data_tag_clear(bmain);
|
||||
* local data), others will need to be duplicated. */
|
||||
GSet *loop_tags = BLI_gset_ptr_new(__func__);
|
||||
for (LinkNode *it = todo_ids; it; it = it->next) {
|
||||
library_make_local_copying_check(it->link, loop_tags, bmain->relations, done_ids);
|
||||
BLI_assert(BLI_gset_size(loop_tags) == 0);
|
||||
}
|
||||
BLI_gset_free(loop_tags, NULL);
|
||||
BLI_gset_free(done_ids, NULL);
|
||||
|
||||
/* Next step will most likely add new IDs, better to get rid of this mapping now. */
|
||||
BKE_main_relations_free(bmain);
|
||||
|
||||
/* Step 3: Make IDs local, either directly (quick and simple), or using generic process,
|
||||
* which involves more complex checks and might instead create a local copy of original linked ID. */
|
||||
@@ -1693,10 +1851,10 @@ void BKE_library_make_local(
|
||||
|
||||
if (id->tag & LIB_TAG_DOIT) {
|
||||
/* We know all users of this object are local or will be made fully local, even if currently there are
|
||||
* some indirect usages. So instead of making a copy that se'll likely get rid of later, directly make
|
||||
* some indirect usages. So instead of making a copy that we'll likely get rid of later, directly make
|
||||
* that data block local. Saves a tremendous amount of time with complex scenes... */
|
||||
id_clear_lib_data_ex(bmain, id, true);
|
||||
BKE_id_expand_local(id);
|
||||
BKE_id_expand_local(bmain, id);
|
||||
id->tag &= ~LIB_TAG_DOIT;
|
||||
}
|
||||
else {
|
||||
@@ -1732,6 +1890,9 @@ void BKE_library_make_local(
|
||||
/* Step 4: We have to remap local usages of old (linked) ID to new (local) id in a separated loop,
|
||||
* as lbarray ordering is not enough to ensure us we did catch all dependencies
|
||||
* (e.g. if making local a parent object before its child...). See T48907. */
|
||||
/* TODO This is now the biggest step by far (in term of processing time). We may be able to gain here by
|
||||
* using again main->relations mapping, but... this implies BKE_libblock_remap & co to be able to update
|
||||
* main->relations on the fly. Have to think about it a bit more, and see whether new code is OK first, anyway. */
|
||||
for (LinkNode *it = copied_ids; it; it = it->next) {
|
||||
id = it->link;
|
||||
|
||||
@@ -1750,6 +1911,53 @@ void BKE_library_make_local(
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: Keeping both version of the code (old one being safer, since it still has checks against unused IDs)
|
||||
* for now, we can remove old one once it has been tested for some time in master... */
|
||||
#if 1
|
||||
/* Step 5: proxy 'remapping' hack. */
|
||||
for (LinkNode *it = copied_ids; it; it = it->next) {
|
||||
/* Attempt to re-link copied proxy objects. This allows appending of an entire scene
|
||||
* from another blend file into this one, even when that blend file contains proxified
|
||||
* armatures that have local references. Since the proxified object needs to be linked
|
||||
* (not local), this will only work when the "Localize all" checkbox is disabled.
|
||||
* TL;DR: this is a dirty hack on top of an already weak feature (proxies). */
|
||||
if (GS(id->name) == ID_OB && ((Object *)id)->proxy != NULL) {
|
||||
Object *ob = (Object *)id;
|
||||
Object *ob_new = (Object *)id->newid;
|
||||
bool is_local = false, is_lib = false;
|
||||
|
||||
/* Proxies only work when the proxified object is linked-in from a library. */
|
||||
if (ob->proxy->id.lib == NULL) {
|
||||
printf("Warning, proxy object %s will loose its link to %s, because the "
|
||||
"proxified object is local.\n", id->newid->name, ob->proxy->id.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib);
|
||||
|
||||
/* We can only switch the proxy'ing to a made-local proxy if it is no longer
|
||||
* referred to from a library. Not checking for local use; if new local proxy
|
||||
* was not used locally would be a nasty bug! */
|
||||
if (is_local || is_lib) {
|
||||
printf("Warning, made-local proxy object %s will loose its link to %s, "
|
||||
"because the linked-in proxy is referenced (is_local=%i, is_lib=%i).\n",
|
||||
id->newid->name, ob->proxy->id.name, is_local, is_lib);
|
||||
}
|
||||
else {
|
||||
/* we can switch the proxy'ing from the linked-in to the made-local proxy.
|
||||
* BKE_object_make_proxy() shouldn't be used here, as it allocates memory that
|
||||
* was already allocated by BKE_object_make_local_ex() (which called BKE_object_copy_ex). */
|
||||
ob_new->proxy = ob->proxy;
|
||||
ob_new->proxy_group = ob->proxy_group;
|
||||
ob_new->proxy_from = ob->proxy_from;
|
||||
ob_new->proxy->proxy_from = ob_new;
|
||||
ob->proxy = ob->proxy_from = ob->proxy_group = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
LinkNode *linked_loop_candidates = NULL;
|
||||
|
||||
/* Step 5: remove datablocks that have been copied to be localized and are no more used in the end...
|
||||
* Note that we may have to loop more than once here, to tackle dependencies between linked objects... */
|
||||
bool do_loop = true;
|
||||
@@ -1800,6 +2008,8 @@ void BKE_library_make_local(
|
||||
|
||||
if (!is_local) {
|
||||
if (!is_lib) { /* Not used at all, we can free it! */
|
||||
BLI_assert(!"Unused linked data copy remaining from MakeLibLocal process, should not happen anymore");
|
||||
printf("\t%s (from %s)\n", id->name, id->lib->id.name);
|
||||
BKE_libblock_free(bmain, id);
|
||||
it->link = NULL;
|
||||
do_loop = true;
|
||||
@@ -1813,7 +2023,7 @@ void BKE_library_make_local(
|
||||
|
||||
/* Grrrrrrr... those half-datablocks-stuff... grrrrrrrrrrr...
|
||||
* Here we have to also tag them as potential candidates, otherwise they would falsy report
|
||||
* ID they used as 'directly used' in fourth step. */
|
||||
* ID they used as 'directly used' in sixth step. */
|
||||
ID *ntree = (ID *)ntreeFromID(id);
|
||||
if (ntree != NULL) {
|
||||
ntree->tag |= LIB_TAG_DOIT;
|
||||
@@ -1838,6 +2048,7 @@ void BKE_library_make_local(
|
||||
/* Note: in theory here we are only handling datablocks forming exclusive linked dependency-cycles-based
|
||||
* archipelagos, so no need to check again after we have deleted one, as done in previous step. */
|
||||
if (id->tag & LIB_TAG_DOIT) {
|
||||
BLI_assert(!"Unused linked data copy remaining from MakeLibLocal process (archipelago case), should not happen anymore");
|
||||
/* Object's deletion rely on valid ob->data, but ob->data may have already been freed here...
|
||||
* Setting it to NULL may not be 100% correct, but should be safe and do the work. */
|
||||
if (GS(id->name) == ID_OB) {
|
||||
@@ -1858,6 +2069,7 @@ void BKE_library_make_local(
|
||||
it->link = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BKE_main_id_clear_newpoins(bmain);
|
||||
BLI_memarena_free(linklist_mem);
|
||||
|
@@ -63,10 +63,12 @@
|
||||
#include "DNA_world_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist_stack.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_library.h"
|
||||
@@ -83,11 +85,12 @@
|
||||
#define FOREACH_FINALIZE _finalize
|
||||
#define FOREACH_FINALIZE_VOID FOREACH_FINALIZE: (void)0
|
||||
|
||||
#define FOREACH_CALLBACK_INVOKE_ID_PP(_data, id_pp, cb_flag) \
|
||||
#define FOREACH_CALLBACK_INVOKE_ID_PP(_data, id_pp, _cb_flag) \
|
||||
CHECK_TYPE(id_pp, ID **); \
|
||||
if (!((_data)->status & IDWALK_STOP)) { \
|
||||
const int _flag = (_data)->flag; \
|
||||
ID *old_id = *(id_pp); \
|
||||
const int callback_return = (_data)->callback((_data)->user_data, (_data)->self_id, id_pp, cb_flag | (_data)->cd_flag); \
|
||||
const int callback_return = (_data)->callback((_data)->user_data, (_data)->self_id, id_pp, _cb_flag | (_data)->cb_flag); \
|
||||
if (_flag & IDWALK_READONLY) { \
|
||||
BLI_assert(*(id_pp) == old_id); \
|
||||
} \
|
||||
@@ -128,7 +131,7 @@ enum {
|
||||
typedef struct LibraryForeachIDData {
|
||||
ID *self_id;
|
||||
int flag;
|
||||
int cd_flag;
|
||||
int cb_flag;
|
||||
LibraryIDLinkCallback callback;
|
||||
void *user_data;
|
||||
int status;
|
||||
@@ -139,19 +142,19 @@ typedef struct LibraryForeachIDData {
|
||||
} LibraryForeachIDData;
|
||||
|
||||
static void library_foreach_rigidbodyworldSceneLooper(
|
||||
struct RigidBodyWorld *UNUSED(rbw), ID **id_pointer, void *user_data, int cd_flag)
|
||||
struct RigidBodyWorld *UNUSED(rbw), ID **id_pointer, void *user_data, int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_modifiersForeachIDLink(
|
||||
void *user_data, Object *UNUSED(object), ID **id_pointer, int cd_flag)
|
||||
void *user_data, Object *UNUSED(object), ID **id_pointer, int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
@@ -160,44 +163,44 @@ static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con), ID
|
||||
bool is_reference, void *user_data)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
|
||||
const int cd_flag = is_reference ? IDWALK_USER : IDWALK_NOP;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
|
||||
const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_particlesystemsObjectLooper(
|
||||
ParticleSystem *UNUSED(psys), ID **id_pointer, void *user_data, int cd_flag)
|
||||
ParticleSystem *UNUSED(psys), ID **id_pointer, void *user_data, int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_sensorsObjectLooper(
|
||||
bSensor *UNUSED(sensor), ID **id_pointer, void *user_data, int cd_flag)
|
||||
bSensor *UNUSED(sensor), ID **id_pointer, void *user_data, int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_controllersObjectLooper(
|
||||
bController *UNUSED(controller), ID **id_pointer, void *user_data, int cd_flag)
|
||||
bController *UNUSED(controller), ID **id_pointer, void *user_data, int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_actuatorsObjectLooper(
|
||||
bActuator *UNUSED(actuator), ID **id_pointer, void *user_data, int cd_flag)
|
||||
bActuator *UNUSED(actuator), ID **id_pointer, void *user_data, int cb_flag)
|
||||
{
|
||||
LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cd_flag);
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pointer, cb_flag);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
@@ -206,7 +209,7 @@ static void library_foreach_nla_strip(LibraryForeachIDData *data, NlaStrip *stri
|
||||
{
|
||||
NlaStrip *substrip;
|
||||
|
||||
FOREACH_CALLBACK_INVOKE(data, strip->act, IDWALK_USER);
|
||||
FOREACH_CALLBACK_INVOKE(data, strip->act, IDWALK_CB_USER);
|
||||
|
||||
for (substrip = strip->strips.first; substrip; substrip = substrip->next) {
|
||||
library_foreach_nla_strip(data, substrip);
|
||||
@@ -229,14 +232,14 @@ static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *
|
||||
/* only used targets */
|
||||
DRIVER_TARGETS_USED_LOOPER(dvar)
|
||||
{
|
||||
FOREACH_CALLBACK_INVOKE_ID(data, dtar->id, IDWALK_NOP);
|
||||
FOREACH_CALLBACK_INVOKE_ID(data, dtar->id, IDWALK_CB_NOP);
|
||||
}
|
||||
DRIVER_TARGETS_LOOPER_END
|
||||
}
|
||||
}
|
||||
|
||||
FOREACH_CALLBACK_INVOKE(data, adt->action, IDWALK_USER);
|
||||
FOREACH_CALLBACK_INVOKE(data, adt->tmpact, IDWALK_USER);
|
||||
FOREACH_CALLBACK_INVOKE(data, adt->action, IDWALK_CB_USER);
|
||||
FOREACH_CALLBACK_INVOKE(data, adt->tmpact, IDWALK_CB_USER);
|
||||
|
||||
for (nla_track = adt->nla_tracks.first; nla_track; nla_track = nla_track->next) {
|
||||
for (nla_strip = nla_track->strips.first; nla_strip; nla_strip = nla_strip->next) {
|
||||
@@ -249,23 +252,28 @@ static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *
|
||||
|
||||
static void library_foreach_mtex(LibraryForeachIDData *data, MTex *mtex)
|
||||
{
|
||||
FOREACH_CALLBACK_INVOKE(data, mtex->object, IDWALK_NOP);
|
||||
FOREACH_CALLBACK_INVOKE(data, mtex->tex, IDWALK_USER);
|
||||
FOREACH_CALLBACK_INVOKE(data, mtex->object, IDWALK_CB_NOP);
|
||||
FOREACH_CALLBACK_INVOKE(data, mtex->tex, IDWALK_CB_USER);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
|
||||
{
|
||||
FOREACH_CALLBACK_INVOKE(data, paint->brush, IDWALK_USER);
|
||||
FOREACH_CALLBACK_INVOKE(data, paint->palette, IDWALK_USER);
|
||||
FOREACH_CALLBACK_INVOKE(data, paint->brush, IDWALK_CB_USER);
|
||||
FOREACH_CALLBACK_INVOKE(data, paint->palette, IDWALK_CB_USER);
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
static void library_foreach_ID_as_subdata_link(
|
||||
ID *id, LibraryIDLinkCallback callback, void *user_data, int flag, LibraryForeachIDData *data)
|
||||
ID **id_pp, LibraryIDLinkCallback callback, void *user_data, int flag, LibraryForeachIDData *data)
|
||||
{
|
||||
/* Needed e.g. for callbacks handling relationships... This call shall be absolutely readonly. */
|
||||
ID *id = *id_pp;
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(data, id_pp, IDWALK_CB_PRIVATE);
|
||||
BLI_assert(id == *id_pp);
|
||||
|
||||
if (flag & IDWALK_RECURSE) {
|
||||
/* Defer handling into main loop, recursively calling BKE_library_foreach_ID_link in IDWALK_RECURSE case is
|
||||
* troublesome, see T49553. */
|
||||
@@ -275,8 +283,10 @@ static void library_foreach_ID_as_subdata_link(
|
||||
}
|
||||
}
|
||||
else {
|
||||
BKE_library_foreach_ID_link(id, callback, user_data, flag);
|
||||
BKE_library_foreach_ID_link(NULL, id, callback, user_data, flag);
|
||||
}
|
||||
|
||||
FOREACH_FINALIZE_VOID;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,7 +294,7 @@ static void library_foreach_ID_as_subdata_link(
|
||||
*
|
||||
* \note: May be extended to be recursive in the future.
|
||||
*/
|
||||
void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
|
||||
void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
|
||||
{
|
||||
LibraryForeachIDData data;
|
||||
int i;
|
||||
@@ -312,9 +322,21 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
#define CALLBACK_INVOKE(check_id_super, cb_flag) \
|
||||
FOREACH_CALLBACK_INVOKE(&data, check_id_super, cb_flag)
|
||||
|
||||
do {
|
||||
for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) {
|
||||
data.self_id = id;
|
||||
data.cd_flag = ID_IS_LINKED_DATABLOCK(id) ? IDWALK_INDIRECT_USAGE : 0;
|
||||
data.cb_flag = ID_IS_LINKED_DATABLOCK(id) ? IDWALK_CB_INDIRECT_USAGE : 0;
|
||||
|
||||
if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY)) {
|
||||
/* Note that this is minor optimization, even in worst cases (like id being an object with lots of
|
||||
* drivers and constraints and modifiers, or material etc. with huge node tree),
|
||||
* but we might as well use it (Main->relations is always assumed valid, it's responsability of code
|
||||
* creating it to free it, especially if/when it starts modifying Main database). */
|
||||
MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->id_user_to_used, id);
|
||||
for (; entry != NULL; entry = entry->next) {
|
||||
FOREACH_CALLBACK_INVOKE_ID_PP(&data, entry->id_pointer, entry->usage_flag);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
if (adt) {
|
||||
@@ -325,7 +347,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
case ID_LI:
|
||||
{
|
||||
Library *lib = (Library *) id;
|
||||
CALLBACK_INVOKE(lib->parent, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(lib->parent, IDWALK_CB_NOP);
|
||||
break;
|
||||
}
|
||||
case ID_SCE:
|
||||
@@ -333,41 +355,41 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
Scene *scene = (Scene *) id;
|
||||
ToolSettings *toolsett = scene->toolsettings;
|
||||
SceneRenderLayer *srl;
|
||||
Base *base;
|
||||
BaseLegacy *legacy_base;
|
||||
|
||||
CALLBACK_INVOKE(scene->camera, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(scene->world, IDWALK_USER);
|
||||
CALLBACK_INVOKE(scene->set, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(scene->clip, IDWALK_USER);
|
||||
CALLBACK_INVOKE(scene->camera, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(scene->world, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(scene->set, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(scene->clip, IDWALK_CB_USER);
|
||||
if (scene->nodetree) {
|
||||
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
|
||||
library_foreach_ID_as_subdata_link((ID *)scene->nodetree, callback, user_data, flag, &data);
|
||||
library_foreach_ID_as_subdata_link((ID **)&scene->nodetree, callback, user_data, flag, &data);
|
||||
}
|
||||
/* DO NOT handle scene->basact here, it's doubling with the loop over whole scene->base later,
|
||||
* since basact is just a pointer to one of those items. */
|
||||
CALLBACK_INVOKE(scene->obedit, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(scene->obedit, IDWALK_CB_NOP);
|
||||
|
||||
for (srl = scene->r.layers.first; srl; srl = srl->next) {
|
||||
FreestyleModuleConfig *fmc;
|
||||
FreestyleLineSet *fls;
|
||||
|
||||
if (srl->mat_override) {
|
||||
CALLBACK_INVOKE(srl->mat_override, IDWALK_USER);
|
||||
CALLBACK_INVOKE(srl->mat_override, IDWALK_CB_USER);
|
||||
}
|
||||
if (srl->light_override) {
|
||||
CALLBACK_INVOKE(srl->light_override, IDWALK_USER);
|
||||
CALLBACK_INVOKE(srl->light_override, IDWALK_CB_USER);
|
||||
}
|
||||
for (fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
|
||||
if (fmc->script) {
|
||||
CALLBACK_INVOKE(fmc->script, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(fmc->script, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
for (fls = srl->freestyleConfig.linesets.first; fls; fls = fls->next) {
|
||||
if (fls->group) {
|
||||
CALLBACK_INVOKE(fls->group, IDWALK_USER);
|
||||
CALLBACK_INVOKE(fls->group, IDWALK_CB_USER);
|
||||
}
|
||||
if (fls->linestyle) {
|
||||
CALLBACK_INVOKE(fls->linestyle, IDWALK_USER);
|
||||
CALLBACK_INVOKE(fls->linestyle, IDWALK_CB_USER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -376,38 +398,59 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
Sequence *seq;
|
||||
SEQP_BEGIN(scene->ed, seq)
|
||||
{
|
||||
CALLBACK_INVOKE(seq->scene, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(seq->scene_camera, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(seq->clip, IDWALK_USER);
|
||||
CALLBACK_INVOKE(seq->mask, IDWALK_USER);
|
||||
CALLBACK_INVOKE(seq->sound, IDWALK_USER);
|
||||
CALLBACK_INVOKE(seq->scene, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(seq->scene_camera, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(seq->clip, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(seq->mask, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(seq->sound, IDWALK_CB_USER);
|
||||
for (SequenceModifierData *smd = seq->modifiers.first; smd; smd = smd->next) {
|
||||
CALLBACK_INVOKE(smd->mask_id, IDWALK_USER);
|
||||
CALLBACK_INVOKE(smd->mask_id, IDWALK_CB_USER);
|
||||
}
|
||||
}
|
||||
SEQ_END
|
||||
}
|
||||
|
||||
CALLBACK_INVOKE(scene->gpd, IDWALK_USER);
|
||||
CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER);
|
||||
|
||||
for (base = scene->base.first; base; base = base->next) {
|
||||
CALLBACK_INVOKE(base->object, IDWALK_USER);
|
||||
for (legacy_base = scene->base.first; legacy_base; legacy_base = legacy_base->next) {
|
||||
CALLBACK_INVOKE(legacy_base->object, IDWALK_CB_USER);
|
||||
}
|
||||
|
||||
SceneCollection *sc;
|
||||
FOREACH_SCENE_COLLECTION(scene, sc)
|
||||
{
|
||||
for (LinkData *link = sc->objects.first; link; link = link->next) {
|
||||
CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
|
||||
}
|
||||
|
||||
for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
|
||||
CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
|
||||
}
|
||||
}
|
||||
FOREACH_SCENE_COLLECTION_END
|
||||
|
||||
SceneLayer *sl;
|
||||
for (sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
for (Base *base = sl->object_bases.first; base; base = base->next) {
|
||||
CALLBACK_INVOKE(base->object, IDWALK_NOP);
|
||||
}
|
||||
}
|
||||
|
||||
for (TimeMarker *marker = scene->markers.first; marker; marker = marker->next) {
|
||||
CALLBACK_INVOKE(marker->camera, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(marker->camera, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
if (toolsett) {
|
||||
CALLBACK_INVOKE(toolsett->skgen_template, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(toolsett->skgen_template, IDWALK_CB_NOP);
|
||||
|
||||
CALLBACK_INVOKE(toolsett->particle.scene, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(toolsett->particle.object, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(toolsett->particle.shape_object, IDWALK_CB_NOP);
|
||||
|
||||
CALLBACK_INVOKE(toolsett->particle.scene, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(toolsett->particle.object, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(toolsett->particle.shape_object, IDWALK_NOP);
|
||||
library_foreach_paint(&data, &toolsett->imapaint.paint);
|
||||
CALLBACK_INVOKE(toolsett->imapaint.stencil, IDWALK_USER);
|
||||
CALLBACK_INVOKE(toolsett->imapaint.clone, IDWALK_USER);
|
||||
CALLBACK_INVOKE(toolsett->imapaint.canvas, IDWALK_USER);
|
||||
CALLBACK_INVOKE(toolsett->imapaint.stencil, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(toolsett->imapaint.clone, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(toolsett->imapaint.canvas, IDWALK_CB_USER);
|
||||
|
||||
if (toolsett->vpaint) {
|
||||
library_foreach_paint(&data, &toolsett->vpaint->paint);
|
||||
@@ -417,7 +460,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
}
|
||||
if (toolsett->sculpt) {
|
||||
library_foreach_paint(&data, &toolsett->sculpt->paint);
|
||||
CALLBACK_INVOKE(toolsett->sculpt->gravity_object, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(toolsett->sculpt->gravity_object, IDWALK_CB_NOP);
|
||||
}
|
||||
if (toolsett->uvsculpt) {
|
||||
library_foreach_paint(&data, &toolsett->uvsculpt->paint);
|
||||
@@ -428,7 +471,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
BKE_rigidbody_world_id_loop(scene->rigidbody_world, library_foreach_rigidbodyworldSceneLooper, &data);
|
||||
}
|
||||
|
||||
CALLBACK_INVOKE(scene->gm.dome.warptext, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(scene->gm.dome.warptext, IDWALK_CB_NOP);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -439,75 +482,75 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
ParticleSystem *psys;
|
||||
|
||||
/* Object is special, proxies make things hard... */
|
||||
const int data_cd_flag = data.cd_flag;
|
||||
const int proxy_cd_flag = (object->proxy || object->proxy_group) ? IDWALK_INDIRECT_USAGE : 0;
|
||||
const int data_cb_flag = data.cb_flag;
|
||||
const int proxy_cb_flag = (object->proxy || object->proxy_group) ? IDWALK_CB_INDIRECT_USAGE : 0;
|
||||
|
||||
/* object data special case */
|
||||
data.cd_flag |= proxy_cd_flag;
|
||||
data.cb_flag |= proxy_cb_flag;
|
||||
if (object->type == OB_EMPTY) {
|
||||
/* empty can have NULL or Image */
|
||||
CALLBACK_INVOKE_ID(object->data, IDWALK_USER);
|
||||
CALLBACK_INVOKE_ID(object->data, IDWALK_CB_USER);
|
||||
}
|
||||
else {
|
||||
/* when set, this can't be NULL */
|
||||
if (object->data) {
|
||||
CALLBACK_INVOKE_ID(object->data, IDWALK_USER | IDWALK_NEVER_NULL);
|
||||
CALLBACK_INVOKE_ID(object->data, IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
|
||||
}
|
||||
}
|
||||
data.cd_flag = data_cd_flag;
|
||||
data.cb_flag = data_cb_flag;
|
||||
|
||||
CALLBACK_INVOKE(object->parent, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->track, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->parent, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(object->track, IDWALK_CB_NOP);
|
||||
/* object->proxy is refcounted, but not object->proxy_group... *sigh* */
|
||||
CALLBACK_INVOKE(object->proxy, IDWALK_USER);
|
||||
CALLBACK_INVOKE(object->proxy_group, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->proxy, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(object->proxy_group, IDWALK_CB_NOP);
|
||||
|
||||
/* Special case!
|
||||
* Since this field is set/owned by 'user' of this ID (and not ID itself), it is only indirect usage
|
||||
* if proxy object is linked... Twisted. */
|
||||
if (object->proxy_from) {
|
||||
data.cd_flag = ID_IS_LINKED_DATABLOCK(object->proxy_from) ? IDWALK_INDIRECT_USAGE : 0;
|
||||
data.cb_flag = ID_IS_LINKED_DATABLOCK(object->proxy_from) ? IDWALK_CB_INDIRECT_USAGE : 0;
|
||||
}
|
||||
CALLBACK_INVOKE(object->proxy_from, IDWALK_NOP);
|
||||
data.cd_flag = data_cd_flag;
|
||||
CALLBACK_INVOKE(object->proxy_from, IDWALK_CB_NOP);
|
||||
data.cb_flag = data_cb_flag;
|
||||
|
||||
CALLBACK_INVOKE(object->poselib, IDWALK_USER);
|
||||
CALLBACK_INVOKE(object->poselib, IDWALK_CB_USER);
|
||||
|
||||
data.cd_flag |= proxy_cd_flag;
|
||||
data.cb_flag |= proxy_cb_flag;
|
||||
for (i = 0; i < object->totcol; i++) {
|
||||
CALLBACK_INVOKE(object->mat[i], IDWALK_USER);
|
||||
CALLBACK_INVOKE(object->mat[i], IDWALK_CB_USER);
|
||||
}
|
||||
data.cd_flag = data_cd_flag;
|
||||
data.cb_flag = data_cb_flag;
|
||||
|
||||
CALLBACK_INVOKE(object->gpd, IDWALK_USER);
|
||||
CALLBACK_INVOKE(object->dup_group, IDWALK_USER);
|
||||
CALLBACK_INVOKE(object->gpd, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(object->dup_group, IDWALK_CB_USER);
|
||||
|
||||
if (object->pd) {
|
||||
CALLBACK_INVOKE(object->pd->tex, IDWALK_USER);
|
||||
CALLBACK_INVOKE(object->pd->f_source, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->pd->tex, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(object->pd->f_source, IDWALK_CB_NOP);
|
||||
}
|
||||
/* Note that ob->effect is deprecated, so no need to handle it here. */
|
||||
|
||||
if (object->pose) {
|
||||
bPoseChannel *pchan;
|
||||
|
||||
data.cd_flag |= proxy_cd_flag;
|
||||
data.cb_flag |= proxy_cb_flag;
|
||||
for (pchan = object->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
CALLBACK_INVOKE(pchan->custom, IDWALK_USER);
|
||||
CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER);
|
||||
BKE_constraints_id_loop(&pchan->constraints, library_foreach_constraintObjectLooper, &data);
|
||||
}
|
||||
data.cd_flag = data_cd_flag;
|
||||
data.cb_flag = data_cb_flag;
|
||||
}
|
||||
|
||||
if (object->rigidbody_constraint) {
|
||||
CALLBACK_INVOKE(object->rigidbody_constraint->ob1, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->rigidbody_constraint->ob2, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->rigidbody_constraint->ob1, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(object->rigidbody_constraint->ob2, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
if (object->lodlevels.first) {
|
||||
LodLevel *level;
|
||||
for (level = object->lodlevels.first; level; level = level->next) {
|
||||
CALLBACK_INVOKE(level->source, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(level->source, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,10 +562,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
}
|
||||
|
||||
if (object->soft) {
|
||||
CALLBACK_INVOKE(object->soft->collision_group, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->soft->collision_group, IDWALK_CB_NOP);
|
||||
|
||||
if (object->soft->effector_weights) {
|
||||
CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,10 +578,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
case ID_ME:
|
||||
{
|
||||
Mesh *mesh = (Mesh *) id;
|
||||
CALLBACK_INVOKE(mesh->texcomesh, IDWALK_USER);
|
||||
CALLBACK_INVOKE(mesh->key, IDWALK_USER);
|
||||
CALLBACK_INVOKE(mesh->texcomesh, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(mesh->key, IDWALK_CB_USER);
|
||||
for (i = 0; i < mesh->totcol; i++) {
|
||||
CALLBACK_INVOKE(mesh->mat[i], IDWALK_USER);
|
||||
CALLBACK_INVOKE(mesh->mat[i], IDWALK_CB_USER);
|
||||
}
|
||||
|
||||
/* XXX Really not happy with this - probably texface should rather use some kind of
|
||||
@@ -550,7 +593,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
MTexPoly *txface = (MTexPoly *)mesh->pdata.layers[i].data;
|
||||
|
||||
for (int j = 0; j < mesh->totpoly; j++, txface++) {
|
||||
CALLBACK_INVOKE(txface->tpage, IDWALK_USER_ONE);
|
||||
CALLBACK_INVOKE(txface->tpage, IDWALK_CB_USER_ONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -560,7 +603,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
MTFace *tface = (MTFace *)mesh->fdata.layers[i].data;
|
||||
|
||||
for (int j = 0; j < mesh->totface; j++, tface++) {
|
||||
CALLBACK_INVOKE(tface->tpage, IDWALK_USER_ONE);
|
||||
CALLBACK_INVOKE(tface->tpage, IDWALK_CB_USER_ONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -571,17 +614,17 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
case ID_CU:
|
||||
{
|
||||
Curve *curve = (Curve *) id;
|
||||
CALLBACK_INVOKE(curve->bevobj, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(curve->taperobj, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(curve->textoncurve, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(curve->key, IDWALK_USER);
|
||||
CALLBACK_INVOKE(curve->bevobj, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(curve->taperobj, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(curve->textoncurve, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(curve->key, IDWALK_CB_USER);
|
||||
for (i = 0; i < curve->totcol; i++) {
|
||||
CALLBACK_INVOKE(curve->mat[i], IDWALK_USER);
|
||||
CALLBACK_INVOKE(curve->mat[i], IDWALK_CB_USER);
|
||||
}
|
||||
CALLBACK_INVOKE(curve->vfont, IDWALK_USER);
|
||||
CALLBACK_INVOKE(curve->vfontb, IDWALK_USER);
|
||||
CALLBACK_INVOKE(curve->vfonti, IDWALK_USER);
|
||||
CALLBACK_INVOKE(curve->vfontbi, IDWALK_USER);
|
||||
CALLBACK_INVOKE(curve->vfont, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(curve->vfontb, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(curve->vfonti, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(curve->vfontbi, IDWALK_CB_USER);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -589,7 +632,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
{
|
||||
MetaBall *metaball = (MetaBall *) id;
|
||||
for (i = 0; i < metaball->totcol; i++) {
|
||||
CALLBACK_INVOKE(metaball->mat[i], IDWALK_USER);
|
||||
CALLBACK_INVOKE(metaball->mat[i], IDWALK_CB_USER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -604,9 +647,9 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
}
|
||||
if (material->nodetree) {
|
||||
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
|
||||
library_foreach_ID_as_subdata_link((ID *)material->nodetree, callback, user_data, flag, &data);
|
||||
library_foreach_ID_as_subdata_link((ID **)&material->nodetree, callback, user_data, flag, &data);
|
||||
}
|
||||
CALLBACK_INVOKE(material->group, IDWALK_USER);
|
||||
CALLBACK_INVOKE(material->group, IDWALK_CB_USER);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -615,26 +658,26 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
Tex *texture = (Tex *) id;
|
||||
if (texture->nodetree) {
|
||||
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
|
||||
library_foreach_ID_as_subdata_link((ID *)texture->nodetree, callback, user_data, flag, &data);
|
||||
library_foreach_ID_as_subdata_link((ID **)&texture->nodetree, callback, user_data, flag, &data);
|
||||
}
|
||||
CALLBACK_INVOKE(texture->ima, IDWALK_USER);
|
||||
CALLBACK_INVOKE(texture->ima, IDWALK_CB_USER);
|
||||
if (texture->env) {
|
||||
CALLBACK_INVOKE(texture->env->object, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(texture->env->ima, IDWALK_USER);
|
||||
CALLBACK_INVOKE(texture->env->object, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(texture->env->ima, IDWALK_CB_USER);
|
||||
}
|
||||
if (texture->pd)
|
||||
CALLBACK_INVOKE(texture->pd->object, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(texture->pd->object, IDWALK_CB_NOP);
|
||||
if (texture->vd)
|
||||
CALLBACK_INVOKE(texture->vd->object, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(texture->vd->object, IDWALK_CB_NOP);
|
||||
if (texture->ot)
|
||||
CALLBACK_INVOKE(texture->ot->object, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(texture->ot->object, IDWALK_CB_NOP);
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_LT:
|
||||
{
|
||||
Lattice *lattice = (Lattice *) id;
|
||||
CALLBACK_INVOKE(lattice->key, IDWALK_USER);
|
||||
CALLBACK_INVOKE(lattice->key, IDWALK_CB_USER);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -648,7 +691,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
}
|
||||
if (lamp->nodetree) {
|
||||
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
|
||||
library_foreach_ID_as_subdata_link((ID *)lamp->nodetree, callback, user_data, flag, &data);
|
||||
library_foreach_ID_as_subdata_link((ID **)&lamp->nodetree, callback, user_data, flag, &data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -656,7 +699,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
case ID_CA:
|
||||
{
|
||||
Camera *camera = (Camera *) id;
|
||||
CALLBACK_INVOKE(camera->dof_ob, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(camera->dof_ob, IDWALK_CB_NOP);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -667,14 +710,14 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
* (see also foreach_libblock_id_users_callback).
|
||||
*/
|
||||
Key *key = (Key *) id;
|
||||
CALLBACK_INVOKE_ID(key->from, IDWALK_NOP);
|
||||
CALLBACK_INVOKE_ID(key->from, IDWALK_CB_NOP);
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_SCR:
|
||||
{
|
||||
bScreen *screen = (bScreen *) id;
|
||||
CALLBACK_INVOKE(screen->scene, IDWALK_USER_ONE);
|
||||
CALLBACK_INVOKE(screen->scene, IDWALK_CB_USER_ONE);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -688,7 +731,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
}
|
||||
if (world->nodetree) {
|
||||
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
|
||||
library_foreach_ID_as_subdata_link((ID *)world->nodetree, callback, user_data, flag, &data);
|
||||
library_foreach_ID_as_subdata_link((ID **)&world->nodetree, callback, user_data, flag, &data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -696,7 +739,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
case ID_SPK:
|
||||
{
|
||||
Speaker *speaker = (Speaker *) id;
|
||||
CALLBACK_INVOKE(speaker->sound, IDWALK_USER);
|
||||
CALLBACK_INVOKE(speaker->sound, IDWALK_CB_USER);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -705,7 +748,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
Group *group = (Group *) id;
|
||||
GroupObject *gob;
|
||||
for (gob = group->gobject.first; gob; gob = gob->next) {
|
||||
CALLBACK_INVOKE(gob->ob, IDWALK_USER_ONE);
|
||||
CALLBACK_INVOKE(gob->ob, IDWALK_CB_USER_ONE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -714,9 +757,9 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *) id;
|
||||
bNode *node;
|
||||
CALLBACK_INVOKE(ntree->gpd, IDWALK_USER);
|
||||
CALLBACK_INVOKE(ntree->gpd, IDWALK_CB_USER);
|
||||
for (node = ntree->nodes.first; node; node = node->next) {
|
||||
CALLBACK_INVOKE_ID(node->id, IDWALK_USER);
|
||||
CALLBACK_INVOKE_ID(node->id, IDWALK_CB_USER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -724,9 +767,9 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
case ID_BR:
|
||||
{
|
||||
Brush *brush = (Brush *) id;
|
||||
CALLBACK_INVOKE(brush->toggle_brush, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(brush->clone.image, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(brush->paint_curve, IDWALK_USER);
|
||||
CALLBACK_INVOKE(brush->toggle_brush, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(brush->clone.image, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(brush->paint_curve, IDWALK_CB_USER);
|
||||
library_foreach_mtex(&data, &brush->mtex);
|
||||
library_foreach_mtex(&data, &brush->mask_mtex);
|
||||
break;
|
||||
@@ -735,10 +778,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
case ID_PA:
|
||||
{
|
||||
ParticleSettings *psett = (ParticleSettings *) id;
|
||||
CALLBACK_INVOKE(psett->dup_group, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->dup_ob, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->bb_ob, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->collision_group, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->dup_group, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(psett->dup_ob, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(psett->bb_ob, IDWALK_CB_NOP);
|
||||
CALLBACK_INVOKE(psett->collision_group, IDWALK_CB_NOP);
|
||||
|
||||
for (i = 0; i < MAX_MTEX; i++) {
|
||||
if (psett->mtex[i]) {
|
||||
@@ -747,16 +790,16 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
}
|
||||
|
||||
if (psett->effector_weights) {
|
||||
CALLBACK_INVOKE(psett->effector_weights->group, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->effector_weights->group, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
if (psett->pd) {
|
||||
CALLBACK_INVOKE(psett->pd->tex, IDWALK_USER);
|
||||
CALLBACK_INVOKE(psett->pd->f_source, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->pd->tex, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(psett->pd->f_source, IDWALK_CB_NOP);
|
||||
}
|
||||
if (psett->pd2) {
|
||||
CALLBACK_INVOKE(psett->pd2->tex, IDWALK_USER);
|
||||
CALLBACK_INVOKE(psett->pd2->f_source, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(psett->pd2->tex, IDWALK_CB_USER);
|
||||
CALLBACK_INVOKE(psett->pd2->f_source, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
if (psett->boids) {
|
||||
@@ -767,11 +810,11 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
for (rule = state->rules.first; rule; rule = rule->next) {
|
||||
if (rule->type == eBoidRuleType_Avoid) {
|
||||
BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule;
|
||||
CALLBACK_INVOKE(gabr->ob, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(gabr->ob, IDWALK_CB_NOP);
|
||||
}
|
||||
else if (rule->type == eBoidRuleType_FollowLeader) {
|
||||
BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule;
|
||||
CALLBACK_INVOKE(flbr->ob, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(flbr->ob, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -787,19 +830,19 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
MovieTrackingTrack *track;
|
||||
MovieTrackingPlaneTrack *plane_track;
|
||||
|
||||
CALLBACK_INVOKE(clip->gpd, IDWALK_USER);
|
||||
CALLBACK_INVOKE(clip->gpd, IDWALK_CB_USER);
|
||||
|
||||
for (track = tracking->tracks.first; track; track = track->next) {
|
||||
CALLBACK_INVOKE(track->gpd, IDWALK_USER);
|
||||
CALLBACK_INVOKE(track->gpd, IDWALK_CB_USER);
|
||||
}
|
||||
for (object = tracking->objects.first; object; object = object->next) {
|
||||
for (track = object->tracks.first; track; track = track->next) {
|
||||
CALLBACK_INVOKE(track->gpd, IDWALK_USER);
|
||||
CALLBACK_INVOKE(track->gpd, IDWALK_CB_USER);
|
||||
}
|
||||
}
|
||||
|
||||
for (plane_track = tracking->plane_tracks.first; plane_track; plane_track = plane_track->next) {
|
||||
CALLBACK_INVOKE(plane_track->image, IDWALK_USER);
|
||||
CALLBACK_INVOKE(plane_track->image, IDWALK_CB_USER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -814,7 +857,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
for (mask_spline = mask_layer->splines.first; mask_spline; mask_spline = mask_spline->next) {
|
||||
for (i = 0; i < mask_spline->tot_point; i++) {
|
||||
MaskSplinePoint *point = &mask_spline->points[i];
|
||||
CALLBACK_INVOKE_ID(point->parent.id, IDWALK_USER);
|
||||
CALLBACK_INVOKE_ID(point->parent.id, IDWALK_CB_USER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -832,14 +875,14 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
}
|
||||
if (linestyle->nodetree) {
|
||||
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
|
||||
library_foreach_ID_as_subdata_link((ID *)linestyle->nodetree, callback, user_data, flag, &data);
|
||||
library_foreach_ID_as_subdata_link((ID **)&linestyle->nodetree, callback, user_data, flag, &data);
|
||||
}
|
||||
|
||||
for (lsm = linestyle->color_modifiers.first; lsm; lsm = lsm->next) {
|
||||
if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
|
||||
LineStyleColorModifier_DistanceFromObject *p = (LineStyleColorModifier_DistanceFromObject *)lsm;
|
||||
if (p->target) {
|
||||
CALLBACK_INVOKE(p->target, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -847,7 +890,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
|
||||
LineStyleAlphaModifier_DistanceFromObject *p = (LineStyleAlphaModifier_DistanceFromObject *)lsm;
|
||||
if (p->target) {
|
||||
CALLBACK_INVOKE(p->target, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -855,7 +898,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
|
||||
LineStyleThicknessModifier_DistanceFromObject *p = (LineStyleThicknessModifier_DistanceFromObject *)lsm;
|
||||
if (p->target) {
|
||||
CALLBACK_INVOKE(p->target, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(p->target, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -866,7 +909,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
bAction *act = (bAction *) id;
|
||||
|
||||
for (TimeMarker *marker = act->markers.first; marker; marker = marker->next) {
|
||||
CALLBACK_INVOKE(marker->camera, IDWALK_NOP);
|
||||
CALLBACK_INVOKE(marker->camera, IDWALK_CB_NOP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -889,7 +932,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
|
||||
break;
|
||||
|
||||
}
|
||||
} while ((id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL));
|
||||
}
|
||||
|
||||
FOREACH_FINALIZE:
|
||||
if (data.ids_handled) {
|
||||
@@ -907,13 +950,13 @@ FOREACH_FINALIZE:
|
||||
/**
|
||||
* re-usable function, use when replacing ID's
|
||||
*/
|
||||
void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cd_flag)
|
||||
void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cb_flag)
|
||||
{
|
||||
if (cd_flag & IDWALK_USER) {
|
||||
if (cb_flag & IDWALK_CB_USER) {
|
||||
id_us_min(id_src);
|
||||
id_us_plus(id_dst);
|
||||
}
|
||||
else if (cd_flag & IDWALK_USER_ONE) {
|
||||
else if (cb_flag & IDWALK_CB_USER_ONE) {
|
||||
id_us_ensure_real(id_dst);
|
||||
}
|
||||
}
|
||||
@@ -943,7 +986,7 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id
|
||||
/* Could be the following, but simpler to just always say 'yes' here. */
|
||||
#if 0
|
||||
return ELEM(id_type_used, ID_ME, ID_CU, ID_MB, ID_LT, ID_SPK, ID_AR, ID_LA, ID_CA, /* obdata */
|
||||
ID_OB, ID_MA, ID_GD, ID_GR, ID_TE, ID_TXT, ID_SO, ID_MC, ID_IM, ID_AC
|
||||
ID_OB, ID_MA, ID_GD, ID_GR, ID_TE, ID_PA, ID_TXT, ID_SO, ID_MC, ID_IM, ID_AC
|
||||
/* + constraints, modifiers and game logic ID types... */);
|
||||
#else
|
||||
return true;
|
||||
@@ -1047,7 +1090,7 @@ static int foreach_libblock_id_users_callback(void *user_data, ID *self_id, ID *
|
||||
(iter->id->tag & LIB_TAG_EXTRAUSER) ? 1 : 0, (iter->id->tag & LIB_TAG_EXTRAUSER_SET) ? 1 : 0,
|
||||
(cb_flag & IDWALK_INDIRECT_USAGE) ? 1 : 0);
|
||||
#endif
|
||||
if (cb_flag & IDWALK_INDIRECT_USAGE) {
|
||||
if (cb_flag & IDWALK_CB_INDIRECT_USAGE) {
|
||||
iter->count_indirect++;
|
||||
}
|
||||
else {
|
||||
@@ -1078,7 +1121,7 @@ int BKE_library_ID_use_ID(ID *id_user, ID *id_used)
|
||||
iter.curr_id = id_user;
|
||||
iter.count_direct = iter.count_indirect = 0;
|
||||
|
||||
BKE_library_foreach_ID_link(iter.curr_id, foreach_libblock_id_users_callback, (void *)&iter, IDWALK_NOP);
|
||||
BKE_library_foreach_ID_link(NULL, iter.curr_id, foreach_libblock_id_users_callback, (void *)&iter, IDWALK_READONLY);
|
||||
|
||||
return iter.count_direct + iter.count_indirect;
|
||||
}
|
||||
@@ -1107,7 +1150,7 @@ static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked)
|
||||
}
|
||||
iter.curr_id = id_curr;
|
||||
BKE_library_foreach_ID_link(
|
||||
id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_NOP);
|
||||
bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY);
|
||||
|
||||
is_defined = ((check_linked ? iter.count_indirect : iter.count_direct) != 0);
|
||||
}
|
||||
@@ -1158,7 +1201,7 @@ void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, boo
|
||||
continue;
|
||||
}
|
||||
iter.curr_id = id_curr;
|
||||
BKE_library_foreach_ID_link(id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_NOP);
|
||||
BKE_library_foreach_ID_link(bmain, id_curr, foreach_libblock_id_users_callback, &iter, IDWALK_READONLY);
|
||||
|
||||
is_defined = (iter.count_direct != 0 && iter.count_indirect != 0);
|
||||
}
|
||||
@@ -1235,7 +1278,8 @@ void BKE_library_unused_linked_data_set_tag(Main *bmain, const bool do_init_tag)
|
||||
/* Unused ID (so far), no need to check it further. */
|
||||
continue;
|
||||
}
|
||||
BKE_library_foreach_ID_link(id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_NOP);
|
||||
BKE_library_foreach_ID_link(
|
||||
bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1262,7 +1306,8 @@ void BKE_library_indirectly_used_data_tag_clear(Main *bmain)
|
||||
/* Local or non-indirectly-used ID (so far), no need to check it further. */
|
||||
continue;
|
||||
}
|
||||
BKE_library_foreach_ID_link(id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_NOP);
|
||||
BKE_library_foreach_ID_link(
|
||||
bmain, id, foreach_libblock_used_linked_data_tag_clear_cb, &do_loop, IDWALK_READONLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -71,6 +71,7 @@
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_cachefile.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_fcurve.h"
|
||||
@@ -158,6 +159,10 @@ enum {
|
||||
|
||||
static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id_p, int cb_flag)
|
||||
{
|
||||
if (cb_flag & IDWALK_CB_PRIVATE) {
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
IDRemap *id_remap_data = user_data;
|
||||
ID *old_id = id_remap_data->old_id;
|
||||
ID *new_id = id_remap_data->new_id;
|
||||
@@ -169,14 +174,14 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
|
||||
}
|
||||
|
||||
if (*id_p && (*id_p == old_id)) {
|
||||
const bool is_indirect = (cb_flag & IDWALK_INDIRECT_USAGE) != 0;
|
||||
const bool is_indirect = (cb_flag & IDWALK_CB_INDIRECT_USAGE) != 0;
|
||||
const bool skip_indirect = (id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0;
|
||||
/* Note: proxy usage implies LIB_TAG_EXTERN, so on this aspect it is direct,
|
||||
* on the other hand since they get reset to lib data on file open/reload it is indirect too...
|
||||
* Edit Mode is also a 'skip direct' case. */
|
||||
const bool is_obj = (GS(id->name) == ID_OB);
|
||||
const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id));
|
||||
const bool is_never_null = ((cb_flag & IDWALK_NEVER_NULL) && (new_id == NULL) &&
|
||||
const bool is_never_null = ((cb_flag & IDWALK_CB_NEVER_NULL) && (new_id == NULL) &&
|
||||
(id_remap_data->flag & ID_REMAP_FORCE_NEVER_NULL_USAGE) == 0);
|
||||
const bool skip_never_null = (id_remap_data->flag & ID_REMAP_SKIP_NEVER_NULL_USAGE) != 0;
|
||||
|
||||
@@ -185,7 +190,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
|
||||
id->name, old_id->name, old_id, new_id ? new_id->name : "<NONE>", new_id, skip_indirect);
|
||||
#endif
|
||||
|
||||
if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && (cb_flag & IDWALK_NEVER_NULL)) {
|
||||
if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && (cb_flag & IDWALK_CB_NEVER_NULL)) {
|
||||
id->tag |= LIB_TAG_DOIT;
|
||||
}
|
||||
|
||||
@@ -203,10 +208,10 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
|
||||
else {
|
||||
BLI_assert(0);
|
||||
}
|
||||
if (cb_flag & IDWALK_USER) {
|
||||
if (cb_flag & IDWALK_CB_USER) {
|
||||
id_remap_data->skipped_refcounted++;
|
||||
}
|
||||
else if (cb_flag & IDWALK_USER_ONE) {
|
||||
else if (cb_flag & IDWALK_CB_USER_ONE) {
|
||||
/* No need to count number of times this happens, just a flag is enough. */
|
||||
id_remap_data->status |= ID_REMAP_IS_USER_ONE_SKIPPED;
|
||||
}
|
||||
@@ -216,13 +221,13 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
|
||||
*id_p = new_id;
|
||||
DAG_id_tag_update_ex(id_remap_data->bmain, id_self, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
|
||||
}
|
||||
if (cb_flag & IDWALK_USER) {
|
||||
if (cb_flag & IDWALK_CB_USER) {
|
||||
id_us_min(old_id);
|
||||
/* We do not want to handle LIB_TAG_INDIRECT/LIB_TAG_EXTERN here. */
|
||||
if (new_id)
|
||||
new_id->us++;
|
||||
}
|
||||
else if (cb_flag & IDWALK_USER_ONE) {
|
||||
else if (cb_flag & IDWALK_CB_USER_ONE) {
|
||||
id_us_ensure_real(new_id);
|
||||
/* We cannot affect old_id->us directly, LIB_TAG_EXTRAUSER(_SET) are assumed to be set as needed,
|
||||
* that extra user is processed in final handling... */
|
||||
@@ -238,7 +243,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
|
||||
|
||||
/* Some reamapping unfortunately require extra and/or specific handling, tackle those here. */
|
||||
static void libblock_remap_data_preprocess_scene_base_unlink(
|
||||
IDRemap *r_id_remap_data, Scene *sce, Base *base, const bool skip_indirect, const bool is_indirect)
|
||||
IDRemap *r_id_remap_data, Scene *sce, BaseLegacy *base, const bool skip_indirect, const bool is_indirect)
|
||||
{
|
||||
if (skip_indirect && is_indirect) {
|
||||
r_id_remap_data->skipped_indirect++;
|
||||
@@ -254,6 +259,22 @@ static void libblock_remap_data_preprocess_scene_base_unlink(
|
||||
}
|
||||
}
|
||||
|
||||
/* Some remapping unfortunately require extra and/or specific handling, tackle those here. */
|
||||
static void libblock_remap_data_preprocess_scene_object_unlink(
|
||||
IDRemap *r_id_remap_data, Scene *sce, Object *ob, const bool skip_indirect, const bool is_indirect)
|
||||
{
|
||||
if (skip_indirect && is_indirect) {
|
||||
r_id_remap_data->skipped_indirect++;
|
||||
r_id_remap_data->skipped_refcounted++;
|
||||
}
|
||||
else {
|
||||
BKE_collections_object_remove(r_id_remap_data->bmain, sce, ob, false);
|
||||
if (!is_indirect) {
|
||||
r_id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
|
||||
{
|
||||
switch (GS(r_id_remap_data->id->name)) {
|
||||
@@ -268,7 +289,16 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
|
||||
/* In case we are unlinking... */
|
||||
if (!r_id_remap_data->old_id) {
|
||||
/* ... everything from scene. */
|
||||
Base *base, *base_next;
|
||||
Object *ob_iter;
|
||||
FOREACH_SCENE_OBJECT(sce, ob_iter)
|
||||
{
|
||||
libblock_remap_data_preprocess_scene_object_unlink(
|
||||
r_id_remap_data, sce, ob_iter, skip_indirect, is_indirect);
|
||||
}
|
||||
FOREACH_SCENE_OBJECT_END
|
||||
|
||||
|
||||
BaseLegacy *base, *base_next;
|
||||
for (base = sce->base.first; base; base = base_next) {
|
||||
base_next = base->next;
|
||||
libblock_remap_data_preprocess_scene_base_unlink(
|
||||
@@ -278,8 +308,11 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
|
||||
else if (GS(r_id_remap_data->old_id->name) == ID_OB) {
|
||||
/* ... a specific object from scene. */
|
||||
Object *old_ob = (Object *)r_id_remap_data->old_id;
|
||||
Base *base = BKE_scene_base_find(sce, old_ob);
|
||||
|
||||
libblock_remap_data_preprocess_scene_object_unlink(
|
||||
r_id_remap_data, sce, old_ob, skip_indirect, is_indirect);
|
||||
|
||||
BaseLegacy *base = BKE_scene_base_find(sce, old_ob);
|
||||
if (base) {
|
||||
libblock_remap_data_preprocess_scene_base_unlink(
|
||||
r_id_remap_data, sce, base, skip_indirect, is_indirect);
|
||||
@@ -325,7 +358,7 @@ static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain,
|
||||
}
|
||||
if (new_ob == NULL) { /* We need to remove NULL-ified groupobjects... */
|
||||
for (Group *group = bmain->group.first; group; group = group->id.next) {
|
||||
BKE_group_object_unlink(group, NULL, NULL, NULL);
|
||||
BKE_group_object_unlink(group, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -338,23 +371,17 @@ static void libblock_remap_data_postprocess_group_scene_unlink(Main *UNUSED(bmai
|
||||
{
|
||||
/* Note that here we assume no object has no base (i.e. all objects are assumed instanced
|
||||
* in one scene...). */
|
||||
for (Base *base = sce->base.first; base; base = base->next) {
|
||||
if (base->flag & OB_FROMGROUP) {
|
||||
Object *ob = base->object;
|
||||
for (BaseLegacy *base = sce->base.first; base; base = base->next) {
|
||||
Object *ob = base->object;
|
||||
if (ob->flag & OB_FROMGROUP) {
|
||||
Group *grp = BKE_group_object_find(NULL, ob);
|
||||
|
||||
if (ob->flag & OB_FROMGROUP) {
|
||||
Group *grp = BKE_group_object_find(NULL, ob);
|
||||
|
||||
/* Unlinked group (old_id) is still in bmain... */
|
||||
if (grp && (&grp->id == old_id || grp->id.us == 0)) {
|
||||
grp = BKE_group_object_find(grp, ob);
|
||||
}
|
||||
if (!grp) {
|
||||
ob->flag &= ~OB_FROMGROUP;
|
||||
}
|
||||
/* Unlinked group (old_id) is still in bmain... */
|
||||
if (grp && (&grp->id == old_id || grp->id.us == 0)) {
|
||||
grp = BKE_group_object_find(grp, ob);
|
||||
}
|
||||
if (!(ob->flag & OB_FROMGROUP)) {
|
||||
base->flag &= ~OB_FROMGROUP;
|
||||
if (!grp) {
|
||||
ob->flag &= ~OB_FROMGROUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -434,7 +461,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
|
||||
#endif
|
||||
r_id_remap_data->id = id;
|
||||
libblock_remap_data_preprocess(r_id_remap_data);
|
||||
BKE_library_foreach_ID_link(id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
|
||||
BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
|
||||
}
|
||||
else {
|
||||
i = set_listbasepointers(bmain, lb_array);
|
||||
@@ -456,7 +483,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
|
||||
r_id_remap_data->id = id_curr;
|
||||
libblock_remap_data_preprocess(r_id_remap_data);
|
||||
BKE_library_foreach_ID_link(
|
||||
id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
|
||||
NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -685,13 +712,17 @@ void BKE_libblock_relink_ex(
|
||||
}
|
||||
}
|
||||
|
||||
static int id_relink_to_newid_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cd_flag)
|
||||
static int id_relink_to_newid_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cb_flag)
|
||||
{
|
||||
if (cb_flag & IDWALK_CB_PRIVATE) {
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
ID *id = *id_pointer;
|
||||
if (id) {
|
||||
/* See: NEW_ID macro */
|
||||
if (id->newid) {
|
||||
BKE_library_update_ID_link_user(id->newid, id, cd_flag);
|
||||
BKE_library_update_ID_link_user(id->newid, id, cb_flag);
|
||||
*id_pointer = id->newid;
|
||||
}
|
||||
else if (id->tag & LIB_TAG_NEW) {
|
||||
@@ -711,7 +742,7 @@ void BKE_libblock_relink_to_newid(ID *id)
|
||||
if (ID_IS_LINKED_DATABLOCK(id))
|
||||
return;
|
||||
|
||||
BKE_library_foreach_ID_link(id, id_relink_to_newid_looper, NULL, 0);
|
||||
BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0);
|
||||
}
|
||||
|
||||
void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id)
|
||||
|
@@ -111,6 +111,12 @@ void BKE_material_free(Material *ma)
|
||||
|
||||
BKE_icon_id_delete((ID *)ma);
|
||||
BKE_previewimg_free(&ma->preview);
|
||||
|
||||
for (MaterialEngineSettings *mes = ma->engines_settings.first; mes; mes = mes->next) {
|
||||
if (mes->data)
|
||||
MEM_SAFE_FREE(mes->data);
|
||||
}
|
||||
BLI_freelistN(&ma->engines_settings);
|
||||
}
|
||||
|
||||
void BKE_material_init(Material *ma)
|
||||
@@ -248,6 +254,8 @@ Material *BKE_material_copy(Main *bmain, Material *ma)
|
||||
|
||||
BLI_listbase_clear(&man->gpumaterial);
|
||||
|
||||
/* TODO Duplicate Engine Settings and set runtime to NULL */
|
||||
|
||||
BKE_id_copy_ensure_local(bmain, &ma->id, &man->id);
|
||||
|
||||
return man;
|
||||
@@ -279,6 +287,8 @@ Material *localize_material(Material *ma)
|
||||
man->nodetree = ntreeLocalize(ma->nodetree);
|
||||
|
||||
BLI_listbase_clear(&man->gpumaterial);
|
||||
|
||||
/* TODO Duplicate Engine Settings and set runtime to NULL */
|
||||
|
||||
return man;
|
||||
}
|
||||
@@ -1698,6 +1708,7 @@ void copy_matcopybuf(Material *ma)
|
||||
matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, G.main, false);
|
||||
matcopybuf.preview = NULL;
|
||||
BLI_listbase_clear(&matcopybuf.gpumaterial);
|
||||
/* TODO Duplicate Engine Settings and set runtime to NULL */
|
||||
matcopied = 1;
|
||||
}
|
||||
|
||||
|
@@ -316,7 +316,7 @@ bool BKE_mball_is_basis_for(Object *ob1, Object *ob2)
|
||||
void BKE_mball_properties_copy(Scene *scene, Object *active_object)
|
||||
{
|
||||
Scene *sce_iter = scene;
|
||||
Base *base;
|
||||
BaseLegacy *base;
|
||||
Object *ob;
|
||||
MetaBall *active_mball = (MetaBall *)active_object->data;
|
||||
int basisnr, obnr;
|
||||
@@ -359,27 +359,25 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
|
||||
*/
|
||||
Object *BKE_mball_basis_find(Scene *scene, Object *basis)
|
||||
{
|
||||
Scene *sce_iter = scene;
|
||||
Base *base;
|
||||
Object *ob, *bob = basis;
|
||||
Object *bob = basis;
|
||||
int basisnr, obnr;
|
||||
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
|
||||
SceneBaseIter iter;
|
||||
EvaluationContext *eval_ctx = G.main->eval_ctx;
|
||||
|
||||
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
|
||||
|
||||
BKE_scene_base_iter_next(eval_ctx, &iter, &sce_iter, 0, NULL, NULL);
|
||||
while (BKE_scene_base_iter_next(eval_ctx, &iter, &sce_iter, 1, &base, &ob)) {
|
||||
if ((ob->type == OB_MBALL) && !(base->flag & OB_FROMDUPLI)) {
|
||||
if (ob != bob) {
|
||||
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
|
||||
for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
|
||||
for (Base *base = sl->object_bases.first; base; base = base->next) {
|
||||
Object *ob = base->object;
|
||||
if ((ob->type == OB_MBALL) && !(base->flag & OB_FROMDUPLI)) {
|
||||
if (ob != bob) {
|
||||
BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
|
||||
|
||||
/* object ob has to be in same "group" ... it means, that it has to have same base of its name */
|
||||
if (STREQ(obname, basisname)) {
|
||||
if (obnr < basisnr) {
|
||||
basis = ob;
|
||||
basisnr = obnr;
|
||||
/* object ob has to be in same "group" ... it means, that it has to have same base of its name */
|
||||
if (STREQ(obname, basisname)) {
|
||||
if (obnr < basisnr) {
|
||||
basis = ob;
|
||||
basisnr = obnr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user