Merge branch 'master' into blender2.8

Conflicts:
	source/blender/blenkernel/intern/depsgraph.c
	source/blender/blenkernel/intern/library_query.c
This commit is contained in:
Bastien Montagne 2017-01-31 10:47:43 +01:00
commit 3e9ade6e31
85 changed files with 1447 additions and 1114 deletions

View File

@ -722,7 +722,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()

View File

@ -453,6 +453,12 @@ if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
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()

View File

@ -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):

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
@ -1185,8 +1187,6 @@ typedef struct KernelIntegrator {
int volume_samples;
float light_inv_rr_threshold;
int pad1;
} KernelIntegrator;
static_assert_align(KernelIntegrator, 16);

View File

@ -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);
@ -111,6 +113,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

View File

@ -43,6 +43,8 @@ public:
int transparent_max_bounce;
bool transparent_shadows;
int ao_bounces;
int volume_max_steps;
float volume_step_size;

View File

@ -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

@ -1 +1 @@
Subproject commit 88158191df4da2109bbfd9b0816d891bbc7fc78b
Subproject commit c93ed11a47b3016cf59711ec16de2e2e94c30e99

@ -1 +1 @@
Subproject commit a746a84f8aaf3a4843eb3f4ce3f5a0464872077a
Subproject commit 371960484a38fc64e0a2635170a41a0d8ab2f6bd

@ -1 +1 @@
Subproject commit 029103debce43110f93295d7633931ec100d3017
Subproject commit a8515cfdfe9a98127b592f36fcbe51b7e23b969a

View File

@ -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 and ob.type == 'MESH' and ob.name != ref.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

View File

@ -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'

View File

@ -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);

View File

@ -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);

View File

@ -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, its 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;

View File

@ -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 {

View File

@ -136,14 +136,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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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';

View File

@ -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);

View File

@ -63,6 +63,7 @@
#include "DNA_world_types.h"
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
#include "BLI_ghash.h"
#include "BLI_linklist_stack.h"
@ -83,11 +84,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 +130,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 +141,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 +162,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 +208,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 +231,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 +251,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 +282,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 +293,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 +321,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 +346,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:
@ -335,39 +356,39 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
SceneRenderLayer *srl;
Base *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 +397,39 @@ 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);
CALLBACK_INVOKE(base->object, IDWALK_CB_USER);
}
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 +439,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 +450,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 +461,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 +541,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 +557,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 +572,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 +582,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 +593,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 +611,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 +626,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 +637,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 +670,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 +678,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 +689,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 +710,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 +718,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 +727,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 +736,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 +746,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 +757,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 +769,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 +789,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 +809,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 +836,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 +854,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 +869,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 +877,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 +888,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 +911,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 +929,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 +965,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 +1069,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 +1100,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 +1129,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 +1180,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 +1257,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 +1285,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);
}
}
}

View File

@ -158,6 +158,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 +173,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 +189,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 +207,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 +220,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... */
@ -434,7 +438,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 +460,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 +689,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 +719,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)

View File

@ -1204,7 +1204,7 @@ void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, con
if (lib_local || is_local) {
if (!is_lib) {
id_clear_lib_data(bmain, &ob->id);
BKE_id_expand_local(&ob->id);
BKE_id_expand_local(bmain, &ob->id);
if (clear_proxy) {
if (ob->proxy_from != NULL) {
ob->proxy_from->proxy = NULL;
@ -2236,18 +2236,6 @@ void BKE_boundbox_minmax(const BoundBox *bb, float obmat[4][4], float r_min[3],
}
}
void BKE_boundbox_scale(struct BoundBox *bb_dst, const struct BoundBox *bb_src, float scale)
{
float cent[3];
BKE_boundbox_calc_center_aabb(bb_src, cent);
for (int i = 0; i < ARRAY_SIZE(bb_dst->vec); i++) {
bb_dst->vec[i][0] = ((bb_src->vec[i][0] - cent[0]) * scale) + cent[0];
bb_dst->vec[i][1] = ((bb_src->vec[i][1] - cent[1]) * scale) + cent[1];
bb_dst->vec[i][2] = ((bb_src->vec[i][2] - cent[2]) * scale) + cent[2];
}
}
/**
* Returns a BBox which each dimensions are at least epsilon.
* \note In case a given dimension needs to be enlarged, its final value will be in [epsilon, 3 * epsilon] range.
@ -2816,45 +2804,6 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc,
return 1;
}
/*
* Test a bounding box for ray intersection
* assumes the ray is already local to the boundbox space
*/
bool BKE_boundbox_ray_hit_check(
const struct BoundBox *bb,
const float ray_start[3], const float ray_normal[3],
float *r_lambda)
{
const int triangle_indexes[12][3] = {
{0, 1, 2}, {0, 2, 3},
{3, 2, 6}, {3, 6, 7},
{1, 2, 6}, {1, 6, 5},
{5, 6, 7}, {4, 5, 7},
{0, 3, 7}, {0, 4, 7},
{0, 1, 5}, {0, 4, 5}};
bool result = false;
int i;
for (i = 0; i < 12 && (!result || r_lambda); i++) {
float lambda;
int v1, v2, v3;
v1 = triangle_indexes[i][0];
v2 = triangle_indexes[i][1];
v3 = triangle_indexes[i][2];
if (isect_ray_tri_v3(ray_start, ray_normal, bb->vec[v1], bb->vec[v2], bb->vec[v3], &lambda, NULL) &&
(!r_lambda || *r_lambda > lambda))
{
result = true;
if (r_lambda) {
*r_lambda = lambda;
}
}
}
return result;
}
static int pc_cmp(const void *a, const void *b)
{
const LinkData *ad = a, *bd = b;

View File

@ -4328,12 +4328,12 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func,
{
ParticleTarget *pt;
func(psys, (ID **)&psys->part, userdata, IDWALK_USER | IDWALK_NEVER_NULL);
func(psys, (ID **)&psys->target_ob, userdata, IDWALK_NOP);
func(psys, (ID **)&psys->parent, userdata, IDWALK_NOP);
func(psys, (ID **)&psys->part, userdata, IDWALK_CB_USER | IDWALK_CB_NEVER_NULL);
func(psys, (ID **)&psys->target_ob, userdata, IDWALK_CB_NOP);
func(psys, (ID **)&psys->parent, userdata, IDWALK_CB_NOP);
for (pt = psys->targets.first; pt; pt = pt->next) {
func(psys, (ID **)&pt->ob, userdata, IDWALK_NOP);
func(psys, (ID **)&pt->ob, userdata, IDWALK_CB_NOP);
}
/* Even though psys->part should never be NULL, this can happen as an exception during deletion.
@ -4343,7 +4343,7 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func,
int p;
for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) {
func(psys, (ID **)&pa->boid->ground, userdata, IDWALK_NOP);
func(psys, (ID **)&pa->boid->ground, userdata, IDWALK_CB_NOP);
}
}
}

View File

@ -974,14 +974,14 @@ void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw)
void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata)
{
func(rbw, (ID **)&rbw->group, userdata, IDWALK_NOP);
func(rbw, (ID **)&rbw->constraints, userdata, IDWALK_NOP);
func(rbw, (ID **)&rbw->effector_weights->group, userdata, IDWALK_NOP);
func(rbw, (ID **)&rbw->group, userdata, IDWALK_CB_NOP);
func(rbw, (ID **)&rbw->constraints, userdata, IDWALK_CB_NOP);
func(rbw, (ID **)&rbw->effector_weights->group, userdata, IDWALK_CB_NOP);
if (rbw->objects) {
int i;
for (i = 0; i < rbw->numbodies; i++) {
func(rbw, (ID **)&rbw->objects[i], userdata, IDWALK_NOP);
func(rbw, (ID **)&rbw->objects[i], userdata, IDWALK_CB_NOP);
}
}
}

View File

@ -992,19 +992,19 @@ void BKE_sca_sensors_id_loop(ListBase *senslist, SCASensorIDFunc func, void *use
bSensor *sensor;
for (sensor = senslist->first; sensor; sensor = sensor->next) {
func(sensor, (ID **)&sensor->ob, userdata, IDWALK_NOP);
func(sensor, (ID **)&sensor->ob, userdata, IDWALK_CB_NOP);
switch (sensor->type) {
case SENS_TOUCH: /* DEPRECATED */
{
bTouchSensor *ts = sensor->data;
func(sensor, (ID **)&ts->ma, userdata, IDWALK_NOP);
func(sensor, (ID **)&ts->ma, userdata, IDWALK_CB_NOP);
break;
}
case SENS_MESSAGE:
{
bMessageSensor *ms = sensor->data;
func(sensor, (ID **)&ms->fromObject, userdata, IDWALK_NOP);
func(sensor, (ID **)&ms->fromObject, userdata, IDWALK_CB_NOP);
break;
}
case SENS_ALWAYS:
@ -1035,7 +1035,7 @@ void BKE_sca_controllers_id_loop(ListBase *contlist, SCAControllerIDFunc func, v
case CONT_PYTHON:
{
bPythonCont *pc = controller->data;
func(controller, (ID **)&pc->text, userdata, IDWALK_NOP);
func(controller, (ID **)&pc->text, userdata, IDWALK_CB_NOP);
break;
}
case CONT_LOGIC_AND:
@ -1056,89 +1056,89 @@ void BKE_sca_actuators_id_loop(ListBase *actlist, SCAActuatorIDFunc func, void *
bActuator *actuator;
for (actuator = actlist->first; actuator; actuator = actuator->next) {
func(actuator, (ID **)&actuator->ob, userdata, IDWALK_NOP);
func(actuator, (ID **)&actuator->ob, userdata, IDWALK_CB_NOP);
switch (actuator->type) {
case ACT_ADD_OBJECT: /* DEPRECATED */
{
bAddObjectActuator *aoa = actuator->data;
func(actuator, (ID **)&aoa->ob, userdata, IDWALK_NOP);
func(actuator, (ID **)&aoa->ob, userdata, IDWALK_CB_NOP);
break;
}
case ACT_ACTION:
{
bActionActuator *aa = actuator->data;
func(actuator, (ID **)&aa->act, userdata, IDWALK_NOP);
func(actuator, (ID **)&aa->act, userdata, IDWALK_CB_NOP);
break;
}
case ACT_SOUND:
{
bSoundActuator *sa = actuator->data;
func(actuator, (ID **)&sa->sound, userdata, IDWALK_NOP);
func(actuator, (ID **)&sa->sound, userdata, IDWALK_CB_NOP);
break;
}
case ACT_EDIT_OBJECT:
{
bEditObjectActuator *eoa = actuator->data;
func(actuator, (ID **)&eoa->ob, userdata, IDWALK_NOP);
func(actuator, (ID **)&eoa->me, userdata, IDWALK_NOP);
func(actuator, (ID **)&eoa->ob, userdata, IDWALK_CB_NOP);
func(actuator, (ID **)&eoa->me, userdata, IDWALK_CB_NOP);
break;
}
case ACT_SCENE:
{
bSceneActuator *sa = actuator->data;
func(actuator, (ID **)&sa->scene, userdata, IDWALK_NOP);
func(actuator, (ID **)&sa->camera, userdata, IDWALK_NOP);
func(actuator, (ID **)&sa->scene, userdata, IDWALK_CB_NOP);
func(actuator, (ID **)&sa->camera, userdata, IDWALK_CB_NOP);
break;
}
case ACT_PROPERTY:
{
bPropertyActuator *pa = actuator->data;
func(actuator, (ID **)&pa->ob, userdata, IDWALK_NOP);
func(actuator, (ID **)&pa->ob, userdata, IDWALK_CB_NOP);
break;
}
case ACT_OBJECT:
{
bObjectActuator *oa = actuator->data;
func(actuator, (ID **)&oa->reference, userdata, IDWALK_NOP);
func(actuator, (ID **)&oa->reference, userdata, IDWALK_CB_NOP);
break;
}
case ACT_CAMERA:
{
bCameraActuator *ca = actuator->data;
func(actuator, (ID **)&ca->ob, userdata, IDWALK_NOP);
func(actuator, (ID **)&ca->ob, userdata, IDWALK_CB_NOP);
break;
}
case ACT_MESSAGE:
{
bMessageActuator *ma = actuator->data;
func(actuator, (ID **)&ma->toObject, userdata, IDWALK_NOP);
func(actuator, (ID **)&ma->toObject, userdata, IDWALK_CB_NOP);
break;
}
case ACT_2DFILTER:
{
bTwoDFilterActuator *tdfa = actuator->data;
func(actuator, (ID **)&tdfa->text, userdata, IDWALK_NOP);
func(actuator, (ID **)&tdfa->text, userdata, IDWALK_CB_NOP);
break;
}
case ACT_PARENT:
{
bParentActuator *pa = actuator->data;
func(actuator, (ID **)&pa->ob, userdata, IDWALK_NOP);
func(actuator, (ID **)&pa->ob, userdata, IDWALK_CB_NOP);
break;
}
case ACT_ARMATURE:
{
bArmatureActuator *aa = actuator->data;
func(actuator, (ID **)&aa->target, userdata, IDWALK_NOP);
func(actuator, (ID **)&aa->subtarget, userdata, IDWALK_NOP);
func(actuator, (ID **)&aa->target, userdata, IDWALK_CB_NOP);
func(actuator, (ID **)&aa->subtarget, userdata, IDWALK_CB_NOP);
break;
}
case ACT_STEERING:
{
bSteeringActuator *sa = actuator->data;
func(actuator, (ID **)&sa->target, userdata, IDWALK_NOP);
func(actuator, (ID **)&sa->navmesh, userdata, IDWALK_NOP);
func(actuator, (ID **)&sa->target, userdata, IDWALK_CB_NOP);
func(actuator, (ID **)&sa->navmesh, userdata, IDWALK_CB_NOP);
break;
}
/* Note: some types seems to be non-implemented? ACT_LAMP, ACT_MATERIAL... */

View File

@ -293,6 +293,10 @@ void isect_ray_aabb_v3_precalc(
bool isect_ray_aabb_v3(
const struct IsectRayAABB_Precalc *data,
const float bb_min[3], const float bb_max[3], float *tmin);
bool isect_ray_aabb_v3_simple(
const float orig[3], const float dir[3],
const float bb_min[3], const float bb_max[3],
float *tmin, float *tmax);
struct NearestRayToAABB_Precalc {
float ray_origin[3];

View File

@ -2309,6 +2309,34 @@ bool isect_ray_aabb_v3(
return true;
}
/*
* Test a bounding box (AABB) for ray intersection
* assumes the ray is already local to the boundbox space
*/
bool isect_ray_aabb_v3_simple(
const float orig[3], const float dir[3],
const float bb_min[3], const float bb_max[3],
float *tmin, float *tmax)
{
double t[7];
float hit_dist[2];
t[1] = (double)(bb_min[0] - orig[0]) / dir[0];
t[2] = (double)(bb_max[0] - orig[0]) / dir[0];
t[3] = (double)(bb_min[1] - orig[1]) / dir[1];
t[4] = (double)(bb_max[1] - orig[1]) / dir[1];
t[5] = (double)(bb_min[2] - orig[2]) / dir[2];
t[6] = (double)(bb_max[2] - orig[2]) / dir[2];
hit_dist[0] = (float)fmax(fmax(fmin(t[1], t[2]), fmin(t[3], t[4])), fmin(t[5], t[6]));
hit_dist[1] = (float)fmin(fmin(fmax(t[1], t[2]), fmax(t[3], t[4])), fmax(t[5], t[6]));
if ((hit_dist[1] < 0 || hit_dist[0] > hit_dist[1]))
return false;
else {
if (tmin) *tmin = hit_dist[0];
if (tmax) *tmax = hit_dist[1];
return true;
}
}
void dist_squared_ray_to_aabb_v3_precalc(
struct NearestRayToAABB_Precalc *data,
const float ray_origin[3], const float ray_direction[3])

View File

@ -4709,12 +4709,12 @@ static void direct_link_latt(FileData *fd, Lattice *lt)
/* ************ READ OBJECT ***************** */
static void lib_link_modifiers__linkModifiers(
void *userData, Object *ob, ID **idpoin, int cd_flag)
void *userData, Object *ob, ID **idpoin, int cb_flag)
{
FileData *fd = userData;
*idpoin = newlibadr(fd, ob->id.lib, *idpoin);
if (*idpoin != NULL && (cd_flag & IDWALK_USER) != 0) {
if (*idpoin != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
id_us_plus_no_lib(*idpoin);
}
}
@ -9308,7 +9308,7 @@ static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
}
static void expand_object_expandModifiers(
void *userData, Object *UNUSED(ob), ID **idpoin, int UNUSED(cd_flag))
void *userData, Object *UNUSED(ob), ID **idpoin, int UNUSED(cb_flag))
{
struct { FileData *fd; Main *mainvar; } *data= userData;

View File

@ -216,6 +216,10 @@ static void anim_change_prop_name(FCurve *fcu,
static void do_version_hue_sat_node(bNodeTree *ntree, bNode *node)
{
if (node->storage == NULL) {
return;
}
/* Make sure new sockets are properly created. */
node_verify_socket_templates(ntree, node);
/* Convert value from old storage to new sockets. */

View File

@ -69,17 +69,21 @@ void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce,
// write bone nodes
bArmature * armature = (bArmature *)ob_arm->data;
ED_armature_to_edit(armature);
bool is_edited = armature->edbo != NULL;
bArmature *arm = (bArmature *)ob_arm->data;
for (Bone *bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) {
if (!is_edited)
ED_armature_to_edit(armature);
for (Bone *bone = (Bone *)armature->bonebase.first; bone; bone = bone->next) {
// start from root bones
if (!bone->parent)
add_bone_node(bone, ob_arm, sce, se, child_objects);
}
ED_armature_from_edit(armature);
ED_armature_edit_free(armature);
if (!is_edited) {
ED_armature_from_edit(armature);
ED_armature_edit_free(armature);
}
}
void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone)

View File

@ -121,7 +121,7 @@ struct BuilderWalkUserData {
static void modifier_walk(void *user_data,
struct Object * /*ob*/,
struct Object **obpoin,
int /*cd_flag*/)
int /*cb_flag*/)
{
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
if (*obpoin) {

View File

@ -2223,7 +2223,7 @@ typedef struct tAnimFilterModifiersContext {
/* dependency walker callback for modifier dependencies */
static void animfilter_modifier_idpoin_cb(void *afm_ptr, Object *ob, ID **idpoin, int UNUSED(cd_flag))
static void animfilter_modifier_idpoin_cb(void *afm_ptr, Object *ob, ID **idpoin, int UNUSED(cb_flag))
{
tAnimFilterModifiersContext *afm = (tAnimFilterModifiersContext *)afm_ptr;
ID *owner_id = &ob->id;

View File

@ -2133,7 +2133,7 @@ enum {
};
static int tag_localizable_looper(
void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int UNUSED(cd_flag))
void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int UNUSED(cb_flag))
{
if (*id_pointer) {
(*id_pointer)->tag &= ~LIB_TAG_DOIT;
@ -2170,12 +2170,12 @@ static void tag_localizable_objects(bContext *C, const int mode)
*/
for (Object *object = bmain->object.first; object; object = object->id.next) {
if ((object->id.tag & LIB_TAG_DOIT) == 0) {
BKE_library_foreach_ID_link(&object->id, tag_localizable_looper, NULL, IDWALK_READONLY);
BKE_library_foreach_ID_link(NULL, &object->id, tag_localizable_looper, NULL, IDWALK_READONLY);
}
if (object->data) {
ID *data_id = (ID *) object->data;
if ((data_id->tag & LIB_TAG_DOIT) == 0) {
BKE_library_foreach_ID_link(data_id, tag_localizable_looper, NULL, IDWALK_READONLY);
BKE_library_foreach_ID_link(NULL, data_id, tag_localizable_looper, NULL, IDWALK_READONLY);
}
}
}

View File

@ -569,7 +569,9 @@ static void initSnappingMode(TransInfo *t)
else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
(obedit == NULL) ) // Object Mode
{
t->tsnap.modeSelect = SNAP_NOT_SELECTED;
/* In "Edit Strokes" mode, Snap tool can perform snap to selected or active objects (see T49632)
* TODO: perform self snap in gpencil_strokes */
t->tsnap.modeSelect = ((t->options & CTX_GPENCIL_STROKES) != 0) ? SNAP_ALL : SNAP_NOT_SELECTED;
}
else {
/* Grid if snap is not possible */
@ -1214,7 +1216,7 @@ bool snapObjectsTransform(
t->tsnap.object_context,
t->scene->toolsettings->snap_mode,
&(const struct SnapObjectParams){
.snap_select = ((t->options & CTX_GPENCIL_STROKES) != 0) ? SNAP_NOT_ACTIVE : t->tsnap.modeSelect,
.snap_select = t->tsnap.modeSelect,
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
},
mval, dist_px, NULL,
@ -1304,7 +1306,7 @@ bool peelObjectsTransform(
t->tsnap.object_context,
mval,
&(const struct SnapObjectParams){
.snap_select = ((t->options & CTX_GPENCIL_STROKES) != 0) ? SNAP_NOT_ACTIVE : t->tsnap.modeSelect,
.snap_select = t->tsnap.modeSelect,
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
},
use_peel_object,

File diff suppressed because it is too large Load Diff

View File

@ -3536,6 +3536,8 @@ void node_light_path(
out float is_transmission_ray,
out float ray_length,
out float ray_depth,
out float diffuse_depth,
out float glossy_depth,
out float transparent_depth,
out float transmission_depth)
{
@ -3548,6 +3550,8 @@ void node_light_path(
is_transmission_ray = 0.0;
ray_length = 1.0;
ray_depth = 1.0;
diffuse_depth = 1.0;
glossy_depth = 1.0;
transparent_depth = 1.0;
transmission_depth = 1.0;
}

View File

@ -96,7 +96,7 @@ static void foreachObjectLink(
{
ArmatureModifierData *amd = (ArmatureModifierData *) md;
walk(userData, ob, &amd->object, IDWALK_NOP);
walk(userData, ob, &amd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -95,10 +95,10 @@ static void foreachObjectLink(
{
ArrayModifierData *amd = (ArrayModifierData *) md;
walk(userData, ob, &amd->start_cap, IDWALK_NOP);
walk(userData, ob, &amd->end_cap, IDWALK_NOP);
walk(userData, ob, &amd->curve_ob, IDWALK_NOP);
walk(userData, ob, &amd->offset_ob, IDWALK_NOP);
walk(userData, ob, &amd->start_cap, IDWALK_CB_NOP);
walk(userData, ob, &amd->end_cap, IDWALK_CB_NOP);
walk(userData, ob, &amd->curve_ob, IDWALK_CB_NOP);
walk(userData, ob, &amd->offset_ob, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -101,7 +101,7 @@ static void foreachObjectLink(
{
BooleanModifierData *bmd = (BooleanModifierData *) md;
walk(userData, ob, &bmd->object, IDWALK_NOP);
walk(userData, ob, &bmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -102,7 +102,7 @@ static void foreachObjectLink(
{
CastModifierData *cmd = (CastModifierData *) md;
walk(userData, ob, &cmd->object, IDWALK_NOP);
walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -214,11 +214,11 @@ static void foreachIDLink(ModifierData *md, Object *ob,
ClothModifierData *clmd = (ClothModifierData *) md;
if (clmd->coll_parms) {
walk(userData, ob, (ID **)&clmd->coll_parms->group, IDWALK_NOP);
walk(userData, ob, (ID **)&clmd->coll_parms->group, IDWALK_CB_NOP);
}
if (clmd->sim_parms && clmd->sim_parms->effector_weights) {
walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_NOP);
walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group, IDWALK_CB_NOP);
}
}

View File

@ -89,7 +89,7 @@ static void foreachObjectLink(
{
CurveModifierData *cmd = (CurveModifierData *) md;
walk(userData, ob, &cmd->object, IDWALK_NOP);
walk(userData, ob, &cmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -124,7 +124,7 @@ static void foreachObjectLink(
ObjectWalkFunc walk, void *userData)
{
DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
walk(userData, ob, &dtmd->ob_source, IDWALK_NOP);
walk(userData, ob, &dtmd->ob_source, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,
@ -163,7 +163,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
/* Only used to check wehther we are operating on org data or not... */
Mesh *me = ob->data;
MVert *mvert;
const bool invert_vgroup = (dtmd->flags & MOD_DATATRANSFER_INVERT_VGROUP) != 0;
@ -176,8 +175,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
BLI_SPACE_TRANSFORM_SETUP(space_transform, ob, dtmd->ob_source);
}
mvert = dm->getVertArray(dm);
if ((me->mvert == mvert) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) {
MVert *mvert = dm->getVertArray(dm);
MEdge *medge = dm->getEdgeArray(dm);
if (((me->mvert == mvert) || (me->medge == medge)) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) {
/* We need to duplicate data here, otherwise setting custom normals, edges' shaprness, etc., could
* modify org mesh, see T43671. */
dm = CDDM_copy(dm);
@ -195,6 +195,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if (BKE_reports_contain(&reports, RPT_ERROR)) {
modifier_setError(md, "%s", BKE_reports_string(&reports, RPT_ERROR));
}
else if ((dtmd->data_types & DT_TYPE_LNOR) && !(me->flag & ME_AUTOSMOOTH)) {
modifier_setError((ModifierData *)dtmd, "Enable 'Auto Smooth' option in mesh settings");
}
else if (dm->getNumVerts(dm) > HIGH_POLY_WARNING || ((Mesh *)(dtmd->ob_source->data))->totvert > HIGH_POLY_WARNING) {
modifier_setError(md, "You are using a rather high poly as source or destination, computation might be slow");
}

View File

@ -132,7 +132,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob,
{
DisplaceModifierData *dmd = (DisplaceModifierData *) md;
walk(userData, ob, &dmd->map_object, IDWALK_NOP);
walk(userData, ob, &dmd->map_object, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob,
@ -140,7 +140,7 @@ static void foreachIDLink(ModifierData *md, Object *ob,
{
DisplaceModifierData *dmd = (DisplaceModifierData *) md;
walk(userData, ob, (ID **)&dmd->texture, IDWALK_USER);
walk(userData, ob, (ID **)&dmd->texture, IDWALK_CB_USER);
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}

View File

@ -153,15 +153,15 @@ static void foreachIDLink(ModifierData *md, Object *ob,
DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
for (; surface; surface = surface->next) {
walk(userData, ob, (ID **)&surface->brush_group, IDWALK_NOP);
walk(userData, ob, (ID **)&surface->init_texture, IDWALK_USER);
walk(userData, ob, (ID **)&surface->brush_group, IDWALK_CB_NOP);
walk(userData, ob, (ID **)&surface->init_texture, IDWALK_CB_USER);
if (surface->effector_weights) {
walk(userData, ob, (ID **)&surface->effector_weights->group, IDWALK_NOP);
walk(userData, ob, (ID **)&surface->effector_weights->group, IDWALK_CB_NOP);
}
}
}
if (pmd->brush) {
walk(userData, ob, (ID **)&pmd->brush->mat, IDWALK_USER);
walk(userData, ob, (ID **)&pmd->brush->mat, IDWALK_CB_USER);
}
}

View File

@ -115,7 +115,7 @@ static void foreachObjectLink(
{
HookModifierData *hmd = (HookModifierData *) md;
walk(userData, ob, &hmd->object, IDWALK_NOP);
walk(userData, ob, &hmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -88,7 +88,7 @@ static void foreachObjectLink(
{
LatticeModifierData *lmd = (LatticeModifierData *) md;
walk(userData, ob, &lmd->object, IDWALK_NOP);
walk(userData, ob, &lmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -74,7 +74,7 @@ static void foreachObjectLink(
ObjectWalkFunc walk, void *userData)
{
MaskModifierData *mmd = (MaskModifierData *)md;
walk(userData, ob, &mmd->ob_arm, IDWALK_NOP);
walk(userData, ob, &mmd->ob_arm, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -119,7 +119,7 @@ static void foreachObjectLink(
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
walk(userData, ob, &mmd->object, IDWALK_NOP);
walk(userData, ob, &mmd->object, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -151,7 +151,7 @@ static void foreachIDLink(ModifierData *md, Object *ob,
{
MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
walk(userData, ob, (ID **)&mcmd->cache_file, IDWALK_USER);
walk(userData, ob, (ID **)&mcmd->cache_file, IDWALK_CB_USER);
}

View File

@ -72,7 +72,7 @@ static void foreachObjectLink(
{
MirrorModifierData *mmd = (MirrorModifierData *) md;
walk(userData, ob, &mmd->mirror_ob, IDWALK_NOP);
walk(userData, ob, &mmd->mirror_ob, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -501,7 +501,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
{
NormalEditModifierData *enmd = (NormalEditModifierData *) md;
walk(userData, ob, &enmd->target, IDWALK_NOP);
walk(userData, ob, &enmd->target, IDWALK_CB_NOP);
}
static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))

View File

@ -127,7 +127,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob,
{
ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
walk(userData, ob, &pimd->ob, IDWALK_NOP);
walk(userData, ob, &pimd->ob, IDWALK_CB_NOP);
}
static int particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *psys, int p)

View File

@ -1075,7 +1075,7 @@ static void foreachObjectLink(
{
ScrewModifierData *ltmd = (ScrewModifierData *) md;
walk(userData, ob, &ltmd->ob_axis, IDWALK_NOP);
walk(userData, ob, &ltmd->ob_axis, IDWALK_CB_NOP);
}
ModifierTypeInfo modifierType_Screw = {

View File

@ -101,8 +101,8 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
{
ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *) md;
walk(userData, ob, &smd->target, IDWALK_NOP);
walk(userData, ob, &smd->auxTarget, IDWALK_NOP);
walk(userData, ob, &smd->target, IDWALK_CB_NOP);
walk(userData, ob, &smd->auxTarget, IDWALK_CB_NOP);
}
static void deformVerts(ModifierData *md, Object *ob,

View File

@ -290,7 +290,7 @@ static void foreachObjectLink(
ObjectWalkFunc walk, void *userData)
{
SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
walk(userData, ob, &smd->origin, IDWALK_NOP);
walk(userData, ob, &smd->origin, IDWALK_CB_NOP);
}
static void updateDepsgraph(ModifierData *md,

View File

@ -152,17 +152,17 @@ static void foreachIDLink(ModifierData *md, Object *ob,
SmokeModifierData *smd = (SmokeModifierData *) md;
if (smd->type == MOD_SMOKE_TYPE_DOMAIN && smd->domain) {
walk(userData, ob, (ID **)&smd->domain->coll_group, IDWALK_NOP);
walk(userData, ob, (ID **)&smd->domain->fluid_group, IDWALK_NOP);
walk(userData, ob, (ID **)&smd->domain->eff_group, IDWALK_NOP);
walk(userData, ob, (ID **)&smd->domain->coll_group, IDWALK_CB_NOP);
walk(userData, ob, (ID **)&smd->domain->fluid_group, IDWALK_CB_NOP);
walk(userData, ob, (ID **)&smd->domain->eff_group, IDWALK_CB_NOP);
if (smd->domain->effector_weights) {
walk(userData, ob, (ID **)&smd->domain->effector_weights->group, IDWALK_NOP);
walk(userData, ob, (ID **)&smd->domain->effector_weights->group, IDWALK_CB_NOP);
}
}
if (smd->type == MOD_SMOKE_TYPE_FLOW && smd->flow) {
walk(userData, ob, (ID **)&smd->flow->noise_texture, IDWALK_USER);
walk(userData, ob, (ID **)&smd->flow->noise_texture, IDWALK_CB_USER);
}
}

View File

@ -92,7 +92,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob,
int i;
for (i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
walk(userData, ob, &umd->projectors[i], IDWALK_NOP);
walk(userData, ob, &umd->projectors[i], IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob,
@ -100,7 +100,7 @@ static void foreachIDLink(ModifierData *md, Object *ob,
{
UVProjectModifierData *umd = (UVProjectModifierData *) md;
walk(userData, ob, (ID **)&umd->image, IDWALK_USER);
walk(userData, ob, (ID **)&umd->image, IDWALK_CB_USER);
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}

View File

@ -221,8 +221,8 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
{
UVWarpModifierData *umd = (UVWarpModifierData *) md;
walk(userData, ob, &umd->object_dst, IDWALK_NOP);
walk(userData, ob, &umd->object_src, IDWALK_NOP);
walk(userData, ob, &umd->object_dst, IDWALK_CB_NOP);
walk(userData, ob, &umd->object_src, IDWALK_CB_NOP);
}
static void uv_warp_deps_object_bone(DagForest *forest, DagNode *obNode,

View File

@ -116,16 +116,16 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
{
WarpModifierData *wmd = (WarpModifierData *) md;
walk(userData, ob, &wmd->object_from, IDWALK_NOP);
walk(userData, ob, &wmd->object_to, IDWALK_NOP);
walk(userData, ob, &wmd->map_object, IDWALK_NOP);
walk(userData, ob, &wmd->object_from, IDWALK_CB_NOP);
walk(userData, ob, &wmd->object_to, IDWALK_CB_NOP);
walk(userData, ob, &wmd->map_object, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WarpModifierData *wmd = (WarpModifierData *) md;
walk(userData, ob, (ID **)&wmd->texture, IDWALK_USER);
walk(userData, ob, (ID **)&wmd->texture, IDWALK_CB_USER);
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}

View File

@ -111,8 +111,8 @@ static void foreachObjectLink(
{
WaveModifierData *wmd = (WaveModifierData *) md;
walk(userData, ob, &wmd->objectcenter, IDWALK_NOP);
walk(userData, ob, &wmd->map_object, IDWALK_NOP);
walk(userData, ob, &wmd->objectcenter, IDWALK_CB_NOP);
walk(userData, ob, &wmd->map_object, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob,
@ -120,7 +120,7 @@ static void foreachIDLink(ModifierData *md, Object *ob,
{
WaveModifierData *wmd = (WaveModifierData *) md;
walk(userData, ob, (ID **)&wmd->texture, IDWALK_USER);
walk(userData, ob, (ID **)&wmd->texture, IDWALK_CB_USER);
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}

View File

@ -126,14 +126,14 @@ static bool dependsOnTime(ModifierData *md)
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_NOP);
walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md;
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_USER);
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}

View File

@ -175,14 +175,14 @@ static bool dependsOnTime(ModifierData *md)
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_NOP);
walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_USER);
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}

View File

@ -325,15 +325,15 @@ static bool dependsOnTime(ModifierData *md)
static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
walk(userData, ob, &wmd->proximity_ob_target, IDWALK_NOP);
walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_NOP);
walk(userData, ob, &wmd->proximity_ob_target, IDWALK_CB_NOP);
walk(userData, ob, &wmd->mask_tex_map_obj, IDWALK_CB_NOP);
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_USER);
walk(userData, ob, (ID **)&wmd->mask_texture, IDWALK_CB_USER);
foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
}

View File

@ -263,7 +263,7 @@ static PyObject *bpy_user_map(PyObject *UNUSED(self), PyObject *args, PyObject *
}
data_cb.id_curr = id;
BKE_library_foreach_ID_link(id, foreach_libblock_id_user_map_callback, &data_cb, IDWALK_NOP);
BKE_library_foreach_ID_link(NULL, id, foreach_libblock_id_user_map_callback, &data_cb, IDWALK_CB_NOP);
if (data_cb.py_id_curr) {
Py_DECREF(data_cb.py_id_curr);

View File

@ -3950,8 +3950,12 @@ static void previews_id_ensure(bContext *C, Scene *scene, ID *id)
}
}
static int previews_id_ensure_callback(void *userdata, ID *UNUSED(self_id), ID **idptr, int UNUSED(cd_flag))
static int previews_id_ensure_callback(void *userdata, ID *UNUSED(self_id), ID **idptr, int cb_flag)
{
if (cb_flag & IDWALK_CB_PRIVATE) {
return IDWALK_RET_NOP;
}
PreviewsIDEnsureData *data = userdata;
ID *id = *idptr;
@ -3984,7 +3988,7 @@ static int previews_ensure_exec(bContext *C, wmOperator *UNUSED(op))
preview_id_data.scene = scene;
id = (ID *)scene;
BKE_library_foreach_ID_link(id, previews_id_ensure_callback, &preview_id_data, IDWALK_RECURSE);
BKE_library_foreach_ID_link(NULL, id, previews_id_ensure_callback, &preview_id_data, IDWALK_RECURSE);
}
/* Check a last time for ID not used (fake users only, in theory), and

@ -1 +1 @@
Subproject commit 6bbb68073bfa11e94bb0b3623db38f847037add7
Subproject commit b11375e89061303401376f7aeae42ac2fd64692a