31bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
34 if (b_ob.type() == BL::Object::type_META) {
38 if (ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
44 for (BL::MaterialSlot &b_slot : b_ob.material_slots) {
45 if (b_slot.link() == BL::MaterialSlot::link_OBJECT) {
53bool BlenderSync::object_is_geometry(
BObjectInfo &b_ob_info)
61 const BL::Object::type_enum type = b_ob_info.
iter_object.type();
63 if (type == BL::Object::type_VOLUME || type == BL::Object::type_CURVES ||
64 type == BL::Object::type_POINTCLOUD || type == BL::Object::type_LIGHT)
70 return b_ob_data.is_a(&RNA_Mesh);
73bool BlenderSync::object_can_have_geometry(BL::Object &b_ob)
75 const BL::Object::type_enum type = b_ob.type();
77 case BL::Object::type_MESH:
78 case BL::Object::type_CURVE:
79 case BL::Object::type_SURFACE:
80 case BL::Object::type_META:
81 case BL::Object::type_FONT:
82 case BL::Object::type_CURVES:
83 case BL::Object::type_POINTCLOUD:
84 case BL::Object::type_VOLUME:
91bool BlenderSync::object_is_light(BL::Object &b_ob)
95 return (b_ob_data && b_ob_data.is_a(&RNA_Light));
98bool BlenderSync::object_is_camera(BL::Object &b_ob)
102 return (b_ob_data && b_ob_data.is_a(&RNA_Camera));
105void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob,
Object *
object)
109 array<Transform> motion;
110 object->set_motion(motion);
112 Geometry *geom =
object->get_geometry();
117 int motion_steps = 0;
118 bool use_motion_blur =
false;
124 use_motion_blur =
true;
131 geom->set_use_motion_blur(use_motion_blur);
136 motion[motion_steps / 2] =
object->get_tfm();
139 object->set_motion(motion);
147Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
148 BL::DepsgraphObjectInstance &b_instance,
149 const float motion_time,
150 bool use_particle_hair,
155 const bool is_instance = b_instance.is_instance();
156 BL::Object b_ob = b_instance.object();
157 BL::Object b_parent = is_instance ? b_instance.
parent() : b_instance.object();
158 BL::Object b_real_object = is_instance ? b_instance.instance_object() : b_ob;
160 b_real_object, preview, use_adaptive_subdivision) !=
162 BObjectInfo b_ob_info{
163 b_ob, b_real_object,
object_get_data(b_ob, use_adaptive_subdiv), use_adaptive_subdiv};
164 const bool motion = motion_time != 0.0f;
166 int *persistent_id =
nullptr;
167 BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
169 persistent_id_array = b_instance.persistent_id();
170 persistent_id = persistent_id_array.data;
179 if (!object_is_geometry(b_ob_info)) {
184 if (object_is_light(b_ob)) {
189 else if (culling.
test(scene, b_ob, tfm)) {
195 const bool use_holdout = b_parent.holdout_get(
PointerRNA_NULL, b_view_layer);
198 if (b_parent.ptr.data != b_ob.ptr.data) {
204 if (use_holdout && (layer_flag & view_layer.exclude_layer)) {
210 const bool use_indirect_only = !use_holdout &&
212 if (use_indirect_only) {
213 visibility &= ~PATH_RAY_CAMERA;
217 if (visibility == 0) {
223 TaskPool *object_geom_task_pool = (is_instance) ?
nullptr : geom_task_pool;
226 const ObjectKey key(b_parent, persistent_id, b_ob_info.
real_object, use_particle_hair);
231 object = object_map.find(key);
235 const int time_index =
object->motion_step(motion_time);
236 if (time_index >= 0) {
237 array<Transform> motion =
object->get_motion();
238 motion[time_index] = tfm;
239 object->set_motion(motion);
243 if (object->get_geometry()) {
244 sync_geometry_motion(
245 b_ob_info,
object, motion_time, use_particle_hair, object_geom_task_pool);
253 bool object_updated = object_map.add_or_update(&
object, b_ob, b_parent, key) ||
254 (tfm !=
object->get_tfm());
258 b_ob_info, object_updated, use_particle_hair, object_geom_task_pool);
259 object->set_geometry(geometry);
263 if (sync_object_attributes(b_instance,
object)) {
264 object_updated =
true;
268 object->set_use_holdout(use_holdout);
270 object->set_visibility(visibility);
272 object->set_is_shadow_catcher(b_ob.is_shadow_catcher() || b_parent.is_shadow_catcher());
274 object->set_shadow_terminator_shading_offset(b_ob.shadow_terminator_shading_offset());
276 object->set_shadow_terminator_geometry_offset(b_ob.shadow_terminator_geometry_offset());
278 float ao_distance =
get_float(cobject,
"ao_distance");
279 if (ao_distance == 0.0f && b_parent.ptr.data != b_ob.ptr.data) {
281 ao_distance =
get_float(cparent,
"ao_distance");
283 object->set_ao_distance(ao_distance);
285 const bool is_caustics_caster =
get_boolean(cobject,
"is_caustics_caster");
286 object->set_is_caustics_caster(is_caustics_caster);
288 const bool is_caustics_receiver =
get_boolean(cobject,
"is_caustics_receiver");
289 object->set_is_caustics_receiver(is_caustics_receiver);
291 object->set_is_bake_target(b_ob_info.
real_object == b_bake_target);
294 BL::Object parent = b_ob.parent();
297 while (parent.parent()) {
298 parent = parent.parent();
300 parent_name = parent.name();
303 parent_name = b_ob.name();
305 object->set_asset_name(parent_name);
310 const bool do_sync =
object->is_modified() || object_updated ||
311 (
object->get_geometry() && object->get_geometry()->
is_modified());
313 object->name = b_ob.name().c_str();
314 object->set_pass_id(b_ob.pass_index());
318 object->set_tfm(tfm);
322 object->set_dupli_generated(0.5f *
get_float3(b_instance.orco()) -
324 object->set_dupli_uv(
get_float2(b_instance.uv()));
325 object->set_random_id(b_instance.random_id());
334 string lightgroup = b_ob.lightgroup();
335 if (lightgroup.empty()) {
336 lightgroup = b_parent.lightgroup();
338 object->set_lightgroup(ustring(lightgroup));
346 sync_object_motion_init(b_parent, b_ob,
object);
348 if (do_sync || object->motion_is_modified()) {
349 object->tag_update(scene);
354 sync_dupli_particle(b_parent, b_instance,
object);
371 if (use_instancer && b_instance.is_instance()) {
382bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance,
Object *
object)
385 AttributeRequestSet requests =
object->get_geometry()->needed_attributes();
388 vector<ParamValue> &attributes =
object->attributes;
389 bool changed =
false;
391 for (
int i = attributes.size() - 1;
i >= 0;
i--) {
392 if (!requests.
find(attributes[
i].name())) {
393 attributes.erase(attributes.begin() +
i);
399 for (
const AttributeRequest &req : requests.
requests) {
402 std::string real_name;
405 if (type == BL::ShaderNodeAttribute::attribute_type_OBJECT ||
406 type == BL::ShaderNodeAttribute::attribute_type_INSTANCER)
408 const bool use_instancer = (type == BL::ShaderNodeAttribute::attribute_type_INSTANCER);
412 ParamValue *param =
nullptr;
414 for (
size_t i = 0;
i < attributes.size();
i++) {
416 param = &attributes[
i];
422 const ParamValue new_param(
name, TypeFloat4, 1, &value);
423 assert(new_param.datasize() ==
sizeof(value));
427 attributes.push_back(new_param);
429 else if (!(param->get<
float4>() == value)) {
441void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
442 BL::SpaceView3D &b_v3d,
443 const float motion_time)
449 const bool motion = motion_time != 0.0f;
453 geometry_map.pre_sync();
454 object_map.pre_sync();
455 procedural_map.pre_sync();
456 particle_system_map.pre_sync();
457 motion_times.clear();
460 geometry_motion_synced.clear();
466 instance_geometries_by_object.clear();
470 BlenderObjectCulling culling(scene, b_scene);
474 const bool show_lights = BlenderViewportParameters(b_v3d, use_developer_ui).use_scene_lights;
476 BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
477 BL::Depsgraph::object_instances_iterator b_instance_iter;
479 for (b_depsgraph.object_instances.begin(b_instance_iter);
480 b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
483 BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
484 BL::Object b_ob = b_instance.object();
487 const bool show_in_viewport = !b_v3d || b_ob.visible_in_viewport_get(b_v3d);
488 if (show_in_viewport ==
false) {
498 const bool sync_hair = b_instance.show_particles() && object_has_particle_hair(b_ob);
501 if (b_instance.show_self()) {
502 sync_object(b_view_layer,
508 sync_hair ?
nullptr : &geom_task_pool);
514 b_view_layer, b_instance, motion_time,
true, show_lights, culling, &geom_task_pool);
517 cancel = progress.get_cancel();
522 progress.set_sync_status(
"");
524 if (!cancel && !motion) {
526 sync_background_light(b_v3d);
531 object_map.post_sync();
532 geometry_map.post_sync();
533 particle_system_map.post_sync();
534 procedural_map.post_sync();
538 geometry_motion_synced.clear();
542void BlenderSync::sync_motion(BL::RenderSettings &b_render,
543 BL::Depsgraph &b_depsgraph,
544 BL::SpaceView3D &b_v3d,
545 BL::RegionView3D &b_rv3d,
548 void **python_thread_state)
555 BL::Object b_cam = get_camera_object(b_v3d, b_rv3d);
557 const int frame_center = b_scene.frame_current();
558 const float subframe_center = b_scene.frame_subframe();
559 float frame_center_delta = 0.0f;
564 const float shuttertime = scene->camera->get_shuttertime();
566 frame_center_delta = -shuttertime * 0.5f;
570 frame_center_delta = shuttertime * 0.5f;
573 const float time = frame_center + subframe_center + frame_center_delta;
574 const int frame = (int)
floorf(time);
575 const float subframe = time - frame;
577 b_engine.frame_set(frame, subframe);
580 sync_camera_motion(b_render, b_cam, width, height, 0.0f);
582 sync_objects(b_depsgraph, b_v3d);
589 for (
size_t step = 0;
step < camera_motion_steps;
step++) {
590 motion_times.insert(scene->camera->motion_time(
step));
595 geometry_motion_attribute_synced.clear();
596 for (
Geometry *geom : scene->geometry) {
598 geometry_motion_attribute_synced.insert(geom);
603 for (
const float relative_time : motion_times) {
605 if (relative_time == 0.0f) {
609 LOG_DEBUG <<
"Synchronizing motion for the relative time " << relative_time <<
".";
612 const float shuttertime = scene->motion_shutter_time();
615 const float time = frame_center + subframe_center + frame_center_delta +
616 relative_time * shuttertime * 0.5f;
617 const int frame = (int)
floorf(time);
618 const float subframe = time - frame;
622 b_engine.frame_set(frame, subframe);
626 sync_camera_motion(b_render, b_cam, width, height, relative_time);
629 sync_objects(b_depsgraph, b_v3d, relative_time);
632 geometry_motion_attribute_synced.clear();
638 b_engine.frame_set(frame_center, subframe_center);
bool BKE_object_dupli_find_rgba_attribute(const Object *ob, const DupliObject *dupli, const Object *dupli_parent, const char *name, float r_value[4])
DupliObject * rna_hack_DepsgraphObjectInstance_dupli_object_get(PointerRNA *ptr)
static float4 lookup_instance_property(BL::DepsgraphObjectInstance &b_instance, const string &name, bool use_instancer)
BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name)
vector< AttributeRequest > requests
Attribute * find(ustring name) const
static uint64_t get_shadow_set_membership(const BL::Object &parent, const BL::Object &object)
static uint64_t get_light_set_membership(const BL::Object &parent, const BL::Object &object)
static uint get_receiver_light_set(const BL::Object &parent, const BL::Object &object)
static uint get_blocker_shadow_set(const BL::Object &parent, const BL::Object &object)
void init_object(Scene *scene, BL::Object &b_ob)
bool test(Scene *scene, BL::Object &b_ob, Transform &tfm)
T * resize(const size_t newsize)
BL::ShaderNodeAttribute::attribute_type_enum BlenderAttributeType
static uint object_ray_visibility(BL::Object &b_ob)
static uint object_motion_steps(BL::Object &b_parent, BL::Object &b_ob, const int max_steps=INT_MAX)
static float get_float(PointerRNA &ptr, const char *name)
static bool get_boolean(PointerRNA &ptr, const char *name)
static float3 get_float3(const BL::Array< float, 2 > &array)
static Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob, const bool preview, const bool use_adaptive_subdivision)
static float2 get_float2(const BL::Array< float, 2 > &array)
static CCL_NAMESPACE_BEGIN BL::ID object_get_data(const BL::Object &b_ob, const bool use_adaptive_subdivision)
static Transform get_transform(const BL::Array< float, 16 > &array)
static bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_ob)
#define CCL_NAMESPACE_END
#define assert(assertion)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
VecBase< float, 4 > float4
static uint hash_string(const char *str)
ccl_device_inline uint hash_uint2(const uint kx, const uint ky)
ccl_device_inline float3 object_color(KernelGlobals kg, const int object)
@ ATTR_STD_MOTION_VERTEX_POSITION
@ PATH_RAY_ALL_VISIBILITY
CCL_NAMESPACE_BEGIN ccl_device_inline float2 zero_float2()
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
void python_thread_state_restore(void **python_thread_state)
void python_thread_state_save(void **python_thread_state)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
const PointerRNA PointerRNA_NULL
bool is_real_object_data() const
static const uint MAX_MOTION_STEPS
float motion_time(const int step) const
void wait_work(Summary *stats=nullptr)