mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Refactor: Cycles: Remove use of RNA C++ API: object.cpp
This one is a little less trivial than the other similar changes recently, because it migrates depsgraph iteration from the RNA API to the C++ depsgraph API, which is a bit more unruly. Previously we passed around `BL::DepsgraphObjectInstance`, now we pass `::Object` and `::DEGObjectIterData`. Another thing to note is the duplication of `ED_mesh_split_faces` into `mesh_split_edges_for_corner_normals`. I did that because we shouldn't call the editors modules from Cycles, and because the splitting logic is much more related to how Cycles decided to upload normals than any Blender-internal logic. Part of #130989
This commit is contained in:
parent
7abf0f32fa
commit
244b154bb6
15 changed files with 382 additions and 295 deletions
|
|
@ -57,6 +57,7 @@ set(LIB
|
|||
PRIVATE bf::blenlib
|
||||
PRIVATE bf::dna
|
||||
PRIVATE bf::imbuf
|
||||
PRIVATE bf::geometry
|
||||
PRIVATE bf::gpu
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::intern::clog
|
||||
|
|
|
|||
|
|
@ -575,7 +575,7 @@ void BlenderSync::sync_particle_hair(
|
|||
if (!b_ob_info.is_real_object_data()) {
|
||||
return;
|
||||
}
|
||||
const ::Object &b_ob = *b_ob_info.real_object.ptr.data_as<::Object>();
|
||||
const ::Object &b_ob = *b_ob_info.real_object;
|
||||
|
||||
/* obtain general settings */
|
||||
if (b_ob.mode == OB_MODE_PARTICLE_EDIT || b_ob.mode == OB_MODE_EDIT) {
|
||||
|
|
@ -1009,7 +1009,7 @@ void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, con
|
|||
|
||||
/* Convert Blender hair to Cycles curves. */
|
||||
const blender::bke::CurvesGeometry &b_curves(
|
||||
static_cast<const ::Curves *>(b_ob_info.object_data.ptr.data)->geometry.wrap());
|
||||
blender::id_cast<const ::Curves *>(b_ob_info.object_data)->geometry.wrap());
|
||||
if (motion) {
|
||||
export_hair_curves_motion(hair, b_curves, motion_step);
|
||||
}
|
||||
|
|
@ -1037,13 +1037,13 @@ void BlenderSync::sync_hair(BObjectInfo &b_ob_info, Hair *hair)
|
|||
new_hair.set_used_shaders(used_shaders);
|
||||
|
||||
if (view_layer.use_hair) {
|
||||
if (b_ob_info.object_data.is_a(&RNA_Curves)) {
|
||||
if (GS(b_ob_info.object_data->name) == ID_CV) {
|
||||
/* Hair object. */
|
||||
sync_hair(&new_hair, b_ob_info, false);
|
||||
}
|
||||
else {
|
||||
/* Particle hair. */
|
||||
::Mesh *b_mesh = object_to_mesh(b_ob_info).ptr.data_as<::Mesh>();
|
||||
::Mesh *b_mesh = object_to_mesh(b_ob_info);
|
||||
|
||||
if (b_mesh) {
|
||||
sync_particle_hair(&new_hair, *b_mesh, b_ob_info, false);
|
||||
|
|
@ -1083,15 +1083,15 @@ void BlenderSync::sync_hair_motion(BObjectInfo &b_ob_info, Hair *hair, const int
|
|||
}
|
||||
|
||||
/* Export deformed coordinates. */
|
||||
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
|
||||
if (b_ob_info.object_data.is_a(&RNA_Curves)) {
|
||||
if (ccl::BKE_object_is_deform_modified(b_ob_info, *b_scene.ptr.data_as<::Scene>(), preview)) {
|
||||
if (GS(b_ob_info.object_data->name) == ID_CV) {
|
||||
/* Hair object. */
|
||||
sync_hair(hair, b_ob_info, true, motion_step);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Particle hair. */
|
||||
::Mesh *b_mesh = object_to_mesh(b_ob_info).ptr.data_as<::Mesh>();
|
||||
::Mesh *b_mesh = object_to_mesh(b_ob_info);
|
||||
if (b_mesh) {
|
||||
sync_particle_hair(hair, *b_mesh, b_ob_info, true, motion_step);
|
||||
free_object_to_mesh(b_ob_info, *b_mesh);
|
||||
|
|
|
|||
|
|
@ -22,22 +22,22 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
static Geometry::Type determine_geom_type(BObjectInfo &b_ob_info, bool use_particle_hair)
|
||||
{
|
||||
if (b_ob_info.object_data.is_a(&RNA_Light)) {
|
||||
if (GS(b_ob_info.object_data->name) == ID_LA) {
|
||||
return Geometry::LIGHT;
|
||||
}
|
||||
|
||||
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
|
||||
if (GS(b_ob_info.object_data->name) == ID_CV || use_particle_hair) {
|
||||
return Geometry::HAIR;
|
||||
}
|
||||
|
||||
if (b_ob_info.object_data.is_a(&RNA_PointCloud)) {
|
||||
if (GS(b_ob_info.object_data->name) == ID_PT) {
|
||||
return Geometry::POINTCLOUD;
|
||||
}
|
||||
|
||||
if (b_ob_info.object_data.is_a(&RNA_Volume) ||
|
||||
if (GS(b_ob_info.object_data->name) == ID_VO ||
|
||||
(b_ob_info.object_data ==
|
||||
object_get_data(b_ob_info.real_object, b_ob_info.use_adaptive_subdivision) &&
|
||||
object_fluid_gas_domain_find(*b_ob_info.real_object.ptr.data_as<::Object>())))
|
||||
object_get_data(*b_ob_info.real_object, b_ob_info.use_adaptive_subdivision) &&
|
||||
object_fluid_gas_domain_find(*b_ob_info.real_object)))
|
||||
{
|
||||
return Geometry::VOLUME;
|
||||
}
|
||||
|
|
@ -88,13 +88,13 @@ Geometry *BlenderSync::sync_geometry(BObjectInfo &b_ob_info,
|
|||
/* Test if we can instance or if the object is modified. */
|
||||
const Geometry::Type geom_type = determine_geom_type(b_ob_info, use_particle_hair);
|
||||
::ID *const b_key_id = (b_ob_info.is_real_object_data() &&
|
||||
BKE_object_is_modified(b_ob_info.real_object)) ?
|
||||
b_ob_info.real_object.ptr.data_as<::ID>() :
|
||||
b_ob_info.object_data.ptr.data_as<::ID>();
|
||||
BKE_object_is_modified(*b_ob_info.real_object)) ?
|
||||
&b_ob_info.real_object->id :
|
||||
b_ob_info.object_data;
|
||||
const GeometryKey key(b_key_id, geom_type);
|
||||
|
||||
/* Find shader indices. */
|
||||
array<Node *> used_shaders = find_used_shaders(*b_ob_info.iter_object.ptr.data_as<::Object>());
|
||||
array<Node *> used_shaders = find_used_shaders(*b_ob_info.iter_object);
|
||||
|
||||
/* Ensure we only sync instanced geometry once. */
|
||||
Geometry *geom = geometry_map.find(key);
|
||||
|
|
@ -160,7 +160,7 @@ Geometry *BlenderSync::sync_geometry(BObjectInfo &b_ob_info,
|
|||
|
||||
geometry_synced.insert(geom);
|
||||
|
||||
geom->name = ustring(b_ob_info.object_data.name().c_str());
|
||||
geom->name = ustring(BKE_id_name(*b_ob_info.object_data));
|
||||
|
||||
/* Store the shaders immediately for the object attribute code. */
|
||||
geom->set_used_shaders(used_shaders);
|
||||
|
|
@ -170,7 +170,7 @@ Geometry *BlenderSync::sync_geometry(BObjectInfo &b_ob_info,
|
|||
return;
|
||||
}
|
||||
|
||||
progress.set_sync_status("Synchronizing object", b_ob_info.real_object.name());
|
||||
progress.set_sync_status("Synchronizing object", BKE_id_name(b_ob_info.real_object->id));
|
||||
|
||||
if (geom_type == Geometry::LIGHT) {
|
||||
Light *light = static_cast<Light *>(geom);
|
||||
|
|
@ -258,16 +258,16 @@ void BlenderSync::sync_geometry_motion(BObjectInfo &b_ob_info,
|
|||
return;
|
||||
}
|
||||
|
||||
if (b_ob_info.object_data.is_a(&RNA_Curves) || use_particle_hair) {
|
||||
if (GS(b_ob_info.object_data->name) == ID_CV || use_particle_hair) {
|
||||
Hair *hair = static_cast<Hair *>(geom);
|
||||
sync_hair_motion(b_ob_info, hair, motion_step);
|
||||
}
|
||||
else if (b_ob_info.object_data.is_a(&RNA_Volume) ||
|
||||
object_fluid_gas_domain_find(*b_ob_info.real_object.ptr.data_as<::Object>()))
|
||||
else if (GS(b_ob_info.object_data->name) == ID_VO ||
|
||||
object_fluid_gas_domain_find(*b_ob_info.real_object))
|
||||
{
|
||||
/* No volume motion blur support yet. */
|
||||
}
|
||||
else if (b_ob_info.object_data.is_a(&RNA_PointCloud)) {
|
||||
else if (GS(b_ob_info.object_data->name) == ID_PT) {
|
||||
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
|
||||
sync_pointcloud_motion(pointcloud, b_ob_info, motion_step);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,7 +220,10 @@ struct ObjectKey {
|
|||
void *ob;
|
||||
bool use_particle_hair;
|
||||
|
||||
ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_, bool use_particle_hair_)
|
||||
ObjectKey(void *parent_,
|
||||
const int id_[OBJECT_PERSISTENT_ID_SIZE],
|
||||
void *ob_,
|
||||
bool use_particle_hair_)
|
||||
: parent(parent_), ob(ob_), use_particle_hair(use_particle_hair_)
|
||||
{
|
||||
if (id_) {
|
||||
|
|
@ -286,7 +289,7 @@ struct ParticleSystemKey {
|
|||
void *ob;
|
||||
int id[OBJECT_PERSISTENT_ID_SIZE];
|
||||
|
||||
ParticleSystemKey(void *ob_, int id_[OBJECT_PERSISTENT_ID_SIZE]) : ob(ob_)
|
||||
ParticleSystemKey(void *ob_, const int id_[OBJECT_PERSISTENT_ID_SIZE]) : ob(ob_)
|
||||
{
|
||||
if (id_) {
|
||||
memcpy(id, id_, sizeof(id));
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
void BlenderSync::sync_light(BObjectInfo &b_ob_info, Light *light)
|
||||
{
|
||||
::Light &b_light = *static_cast<::Light *>(b_ob_info.object_data.ptr.data);
|
||||
::Light &b_light = *blender::id_cast<::Light *>(b_ob_info.object_data);
|
||||
|
||||
light->name = b_light.id.name + 2;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,43 @@
|
|||
#include "BKE_customdata.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
|
||||
#include "GEO_mesh_split_edges.hh"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
void mesh_split_edges_for_corner_normals(::Mesh &mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
const OffsetIndices polys = mesh.faces();
|
||||
const Span<int> corner_edges = mesh.corner_edges();
|
||||
const bke::AttributeAccessor attributes = mesh.attributes();
|
||||
const VArray<bool> mesh_sharp_edges = *attributes.lookup_or_default<bool>(
|
||||
"sharp_edge", bke::AttrDomain::Edge, false);
|
||||
const VArraySpan<bool> sharp_faces = *attributes.lookup<bool>("sharp_face",
|
||||
bke::AttrDomain::Face);
|
||||
|
||||
Array<bool> sharp_edges(mesh.edges_num);
|
||||
mesh_sharp_edges.materialize(sharp_edges);
|
||||
|
||||
threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int face_i : range) {
|
||||
if (!sharp_faces.is_empty() && sharp_faces[face_i]) {
|
||||
for (const int edge : corner_edges.slice(polys[face_i])) {
|
||||
sharp_edges[edge] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask split_mask = IndexMask::from_bools(sharp_edges, memory);
|
||||
if (split_mask.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
geometry::split_edges(mesh, split_mask, {});
|
||||
}
|
||||
|
||||
static void attr_create_motion_from_velocity(Mesh *mesh,
|
||||
const blender::Span<blender::float3> b_attr,
|
||||
const float motion_scale)
|
||||
|
|
@ -802,7 +837,7 @@ static void create_subd_mesh(Scene *scene,
|
|||
const float dicing_rate,
|
||||
const int max_subdivisions)
|
||||
{
|
||||
const ::Object *b_ob = b_ob_info.real_object.ptr.data_as<::Object>();
|
||||
const ::Object *b_ob = b_ob_info.real_object;
|
||||
|
||||
const auto &subsurf_mod = *reinterpret_cast<const ::SubsurfModifierData *>(b_ob->modifiers.last);
|
||||
|
||||
|
|
@ -876,8 +911,9 @@ void BlenderSync::sync_mesh(BObjectInfo &b_ob_info, Mesh *mesh)
|
|||
new_mesh.set_used_shaders(used_shaders);
|
||||
|
||||
if (view_layer.use_surfaces) {
|
||||
object_subdivision_to_mesh(b_ob_info.real_object, new_mesh, preview, use_adaptive_subdivision);
|
||||
const ::Mesh *b_mesh = object_to_mesh(b_ob_info).ptr.data_as<::Mesh>();
|
||||
object_subdivision_to_mesh(
|
||||
*b_ob_info.real_object, new_mesh, preview, use_adaptive_subdivision);
|
||||
const ::Mesh *b_mesh = object_to_mesh(b_ob_info);
|
||||
|
||||
if (b_mesh) {
|
||||
/* Motion blur attribute is relative to seconds, we need it relative to frames. */
|
||||
|
|
@ -951,12 +987,12 @@ void BlenderSync::sync_mesh_motion(BObjectInfo &b_ob_info, Mesh *mesh, const int
|
|||
/* Skip objects without deforming modifiers. this is not totally reliable,
|
||||
* would need a more extensive check to see which objects are animated. */
|
||||
const ::Mesh *b_mesh = nullptr;
|
||||
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
|
||||
if (ccl::BKE_object_is_deform_modified(b_ob_info, *b_scene.ptr.data_as<::Scene>(), preview)) {
|
||||
/* get derived mesh */
|
||||
b_mesh = object_to_mesh(b_ob_info).ptr.data_as<::Mesh>();
|
||||
b_mesh = object_to_mesh(b_ob_info);
|
||||
}
|
||||
|
||||
const std::string ob_name = b_ob_info.real_object.name();
|
||||
const std::string ob_name = BKE_id_name(b_ob_info.real_object->id);
|
||||
|
||||
/* TODO(sergey): Perform preliminary check for number of vertices. */
|
||||
if (b_mesh) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@
|
|||
#include "util/task.h"
|
||||
|
||||
#include "BKE_duplilist.hh"
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_material.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#include "RE_engine.h"
|
||||
|
||||
|
|
@ -30,21 +35,22 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
/* Utilities */
|
||||
|
||||
bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
|
||||
bool BlenderSync::BKE_object_is_modified(::Object &b_ob)
|
||||
{
|
||||
/* test if we can instance or if the object is modified */
|
||||
if (b_ob.type() == BL::Object::type_META) {
|
||||
if (b_ob.type == OB_MBALL) {
|
||||
/* Multi-user and dupli meta-balls are fused, can't instance. */
|
||||
return true;
|
||||
}
|
||||
if (ccl::BKE_object_is_modified(b_ob, b_scene, preview)) {
|
||||
const int settings = preview ? eModifierMode_Realtime : eModifierMode_Render;
|
||||
if ((::BKE_object_is_modified(b_scene.ptr.data_as<::Scene>(), &b_ob) & settings) != 0) {
|
||||
/* modifiers */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* object level material links */
|
||||
for (BL::MaterialSlot &b_slot : b_ob.material_slots) {
|
||||
if (b_slot.link() == BL::MaterialSlot::link_OBJECT) {
|
||||
for (const int i : blender::IndexRange(BKE_object_material_count_eval(&b_ob))) {
|
||||
if (b_ob.matbits[i] != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -54,57 +60,55 @@ bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
|
|||
|
||||
bool BlenderSync::object_is_geometry(BObjectInfo &b_ob_info)
|
||||
{
|
||||
BL::ID b_ob_data = b_ob_info.object_data;
|
||||
::ID *b_ob_data = b_ob_info.object_data;
|
||||
|
||||
if (!b_ob_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const BL::Object::type_enum type = b_ob_info.iter_object.type();
|
||||
const ObjectType type = ObjectType(b_ob_info.iter_object->type);
|
||||
|
||||
if (type == BL::Object::type_VOLUME || type == BL::Object::type_CURVES ||
|
||||
type == BL::Object::type_POINTCLOUD || type == BL::Object::type_LIGHT)
|
||||
{
|
||||
if (type == OB_VOLUME || type == OB_CURVES || type == OB_POINTCLOUD || type == OB_LAMP) {
|
||||
/* Will be exported as geometry. */
|
||||
return true;
|
||||
}
|
||||
|
||||
return b_ob_data.is_a(&RNA_Mesh);
|
||||
return GS(b_ob_data->name) == ID_ME;
|
||||
}
|
||||
|
||||
bool BlenderSync::object_can_have_geometry(BL::Object &b_ob)
|
||||
bool BlenderSync::object_can_have_geometry(::Object &b_ob)
|
||||
{
|
||||
const BL::Object::type_enum type = b_ob.type();
|
||||
const ObjectType type = ObjectType(b_ob.type);
|
||||
switch (type) {
|
||||
case BL::Object::type_MESH:
|
||||
case BL::Object::type_CURVE:
|
||||
case BL::Object::type_SURFACE:
|
||||
case BL::Object::type_META:
|
||||
case BL::Object::type_FONT:
|
||||
case BL::Object::type_CURVES:
|
||||
case BL::Object::type_POINTCLOUD:
|
||||
case BL::Object::type_VOLUME:
|
||||
case OB_MESH:
|
||||
case OB_CURVES_LEGACY:
|
||||
case OB_SURF:
|
||||
case OB_MBALL:
|
||||
case OB_FONT:
|
||||
case OB_CURVES:
|
||||
case OB_POINTCLOUD:
|
||||
case OB_VOLUME:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool BlenderSync::object_is_light(BL::Object &b_ob)
|
||||
bool BlenderSync::object_is_light(::Object &b_ob)
|
||||
{
|
||||
BL::ID b_ob_data = object_get_data(b_ob, true);
|
||||
::ID *b_ob_data = object_get_data(b_ob, true);
|
||||
|
||||
return (b_ob_data && b_ob_data.is_a(&RNA_Light));
|
||||
return (b_ob_data && GS(b_ob_data->name) == ID_LA);
|
||||
}
|
||||
|
||||
bool BlenderSync::object_is_camera(BL::Object &b_ob)
|
||||
bool BlenderSync::object_is_camera(::Object &b_ob)
|
||||
{
|
||||
BL::ID b_ob_data = object_get_data(b_ob, true);
|
||||
::ID *b_ob_data = object_get_data(b_ob, true);
|
||||
|
||||
return (b_ob_data && b_ob_data.is_a(&RNA_Camera));
|
||||
return (b_ob_data && GS(b_ob_data->name) == ID_CA);
|
||||
}
|
||||
|
||||
void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object)
|
||||
void BlenderSync::sync_object_motion_init(::Object &b_parent, ::Object &b_ob, Object *object)
|
||||
{
|
||||
/* Initialize motion blur for object, detecting if it's enabled and creating motion
|
||||
* steps array if so. */
|
||||
|
|
@ -121,9 +125,7 @@ void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob
|
|||
|
||||
const Scene::MotionType need_motion = scene->need_motion();
|
||||
if (need_motion == Scene::MOTION_BLUR) {
|
||||
motion_steps = object_motion_steps(*b_parent.ptr.data_as<::Object>(),
|
||||
*b_ob.ptr.data_as<::Object>(),
|
||||
Object::MAX_MOTION_STEPS);
|
||||
motion_steps = object_motion_steps(b_parent, b_ob, Object::MAX_MOTION_STEPS);
|
||||
if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
|
||||
use_motion_blur = true;
|
||||
}
|
||||
|
|
@ -148,34 +150,32 @@ void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob
|
|||
}
|
||||
}
|
||||
|
||||
Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
||||
BL::DepsgraphObjectInstance &b_instance,
|
||||
Object *BlenderSync::sync_object(::ViewLayer &b_view_layer,
|
||||
::Object &b_ob,
|
||||
::DEGObjectIterData &b_deg_iter_data,
|
||||
const float motion_time,
|
||||
bool use_particle_hair,
|
||||
bool show_lights,
|
||||
BlenderObjectCulling &culling,
|
||||
TaskPool *geom_task_pool)
|
||||
{
|
||||
const bool is_instance = b_instance.is_instance();
|
||||
BL::Object b_ob = b_instance.object();
|
||||
BL::Object b_parent = is_instance ? b_instance.parent() : b_instance.object();
|
||||
BL::Object b_real_object = is_instance ? b_instance.instance_object() : b_ob;
|
||||
const bool is_instance = b_deg_iter_data.dupli_object_current;
|
||||
::Object *b_parent = is_instance ? b_deg_iter_data.dupli_parent : &b_ob;
|
||||
::Object *b_real_object = is_instance ? b_deg_iter_data.dupli_object_current->ob : &b_ob;
|
||||
const bool use_adaptive_subdiv = object_subdivision_type(
|
||||
b_real_object, preview, use_adaptive_subdivision) !=
|
||||
*b_real_object, preview, use_adaptive_subdivision) !=
|
||||
Mesh::SUBDIVISION_NONE;
|
||||
BObjectInfo b_ob_info{
|
||||
b_ob, b_real_object, object_get_data(b_ob, use_adaptive_subdiv), use_adaptive_subdiv};
|
||||
&b_ob, b_real_object, object_get_data(b_ob, use_adaptive_subdiv), use_adaptive_subdiv};
|
||||
const bool motion = motion_time != 0.0f;
|
||||
/*const*/ Transform tfm = get_transform(b_ob.matrix_world());
|
||||
int *persistent_id = nullptr;
|
||||
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
|
||||
/*const*/ Transform tfm = get_transform(b_ob.object_to_world());
|
||||
const int *persistent_id = nullptr;
|
||||
if (is_instance) {
|
||||
persistent_id_array = b_instance.persistent_id();
|
||||
persistent_id = persistent_id_array.data;
|
||||
persistent_id = b_deg_iter_data.dupli_object_current->persistent_id;
|
||||
if (!motion && !b_ob_info.is_real_object_data()) {
|
||||
/* Remember which object data the geometry is coming from, so that we can sync it when the
|
||||
* object has changed. */
|
||||
instance_geometries_by_object[b_ob_info.real_object.ptr.data].insert(b_ob_info.object_data);
|
||||
instance_geometries_by_object[b_ob_info.real_object].insert(b_ob_info.object_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -195,12 +195,15 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
}
|
||||
|
||||
/* Visibility flags for both parent and child. */
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
const bool use_holdout = b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
|
||||
PointerRNA b_ob_rna_ptr = RNA_id_pointer_create(&b_ob.id);
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob_rna_ptr, "cycles");
|
||||
const Base *base_parent = BKE_view_layer_base_find(&b_view_layer, b_parent);
|
||||
const bool use_holdout = ((base_parent->flag & BASE_HOLDOUT) != 0) ||
|
||||
((b_parent->visibility_flag & OB_HOLDOUT) != 0);
|
||||
uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
|
||||
|
||||
if (b_parent.ptr.data != b_ob.ptr.data) {
|
||||
visibility &= object_ray_visibility(b_parent);
|
||||
if (b_parent != &b_ob) {
|
||||
visibility &= object_ray_visibility(*b_parent);
|
||||
}
|
||||
|
||||
/* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
|
||||
|
|
@ -211,8 +214,7 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
#endif
|
||||
|
||||
/* Clear camera visibility for indirect only objects. */
|
||||
const bool use_indirect_only = !use_holdout &&
|
||||
b_parent.indirect_only_get(PointerRNA_NULL, b_view_layer);
|
||||
const bool use_indirect_only = !use_holdout && ((base_parent->flag & BASE_INDIRECT_ONLY) != 0);
|
||||
if (use_indirect_only) {
|
||||
visibility &= ~PATH_RAY_CAMERA;
|
||||
}
|
||||
|
|
@ -254,10 +256,7 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
}
|
||||
|
||||
/* test if we need to sync */
|
||||
bool object_updated = object_map.add_or_update(&object,
|
||||
&b_ob.ptr.data_as<::Object>()->id,
|
||||
&b_parent.ptr.data_as<::Object>()->id,
|
||||
key) ||
|
||||
bool object_updated = object_map.add_or_update(&object, &b_ob.id, &b_parent->id, key) ||
|
||||
(tfm != object->get_tfm());
|
||||
|
||||
/* mesh sync */
|
||||
|
|
@ -267,7 +266,7 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
|
||||
/* special case not tracked by object update flags */
|
||||
|
||||
if (sync_object_attributes(b_instance, object)) {
|
||||
if (sync_object_attributes(b_ob, b_deg_iter_data, object)) {
|
||||
object_updated = true;
|
||||
}
|
||||
|
||||
|
|
@ -276,15 +275,17 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
|
||||
object->set_visibility(visibility);
|
||||
|
||||
object->set_is_shadow_catcher(b_ob.is_shadow_catcher() || b_parent.is_shadow_catcher());
|
||||
object->set_is_shadow_catcher((b_ob.visibility_flag & OB_SHADOW_CATCHER) != 0 ||
|
||||
(b_parent->visibility_flag & OB_SHADOW_CATCHER) != 0);
|
||||
|
||||
object->set_shadow_terminator_shading_offset(b_ob.shadow_terminator_shading_offset());
|
||||
object->set_shadow_terminator_shading_offset(b_ob.shadow_terminator_shading_offset);
|
||||
|
||||
object->set_shadow_terminator_geometry_offset(b_ob.shadow_terminator_geometry_offset());
|
||||
object->set_shadow_terminator_geometry_offset(b_ob.shadow_terminator_geometry_offset);
|
||||
|
||||
float ao_distance = get_float(cobject, "ao_distance");
|
||||
if (ao_distance == 0.0f && b_parent.ptr.data != b_ob.ptr.data) {
|
||||
PointerRNA cparent = RNA_pointer_get(&b_parent.ptr, "cycles");
|
||||
if (ao_distance == 0.0f && b_parent != &b_ob) {
|
||||
PointerRNA b_parent_rna_ptr = RNA_id_pointer_create(&b_parent->id);
|
||||
PointerRNA cparent = RNA_pointer_get(&b_parent_rna_ptr, "cycles");
|
||||
ao_distance = get_float(cparent, "ao_distance");
|
||||
}
|
||||
object->set_ao_distance(ao_distance);
|
||||
|
|
@ -298,16 +299,16 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
object->set_is_bake_target(b_ob_info.real_object == b_bake_target);
|
||||
|
||||
/* sync the asset name for Cryptomatte */
|
||||
BL::Object parent = b_ob.parent();
|
||||
::Object *parent = b_ob.parent;
|
||||
ustring parent_name;
|
||||
if (parent) {
|
||||
while (parent.parent()) {
|
||||
parent = parent.parent();
|
||||
while (parent->parent) {
|
||||
parent = parent->parent;
|
||||
}
|
||||
parent_name = parent.name();
|
||||
parent_name = BKE_id_name(parent->id);
|
||||
}
|
||||
else {
|
||||
parent_name = b_ob.name();
|
||||
parent_name = BKE_id_name(b_ob.id);
|
||||
}
|
||||
object->set_asset_name(parent_name);
|
||||
|
||||
|
|
@ -317,19 +318,21 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
const bool do_sync = object->is_modified() || object_updated ||
|
||||
(object->get_geometry() && object->get_geometry()->is_modified());
|
||||
if (do_sync) {
|
||||
object->name = b_ob.name().c_str();
|
||||
object->set_pass_id(b_ob.pass_index());
|
||||
const BL::Array<float, 4> object_color = b_ob.color();
|
||||
object->set_color(get_float3(object_color));
|
||||
object->name = BKE_id_name(b_ob.id);
|
||||
object->set_pass_id(b_ob.index);
|
||||
const float *object_color = b_ob.color;
|
||||
object->set_color(make_float3(object_color[0], object_color[1], object_color[2]));
|
||||
object->set_alpha(object_color[3]);
|
||||
object->set_tfm(tfm);
|
||||
|
||||
/* dupli texture coordinates and random_id */
|
||||
if (is_instance) {
|
||||
object->set_dupli_generated(0.5f * get_float3(b_instance.orco()) -
|
||||
const float *orco = b_deg_iter_data.dupli_object_current->orco;
|
||||
object->set_dupli_generated(0.5f * make_float3(orco[0], orco[1], orco[2]) -
|
||||
make_float3(0.5f, 0.5f, 0.5f));
|
||||
object->set_dupli_uv(get_float2(b_instance.uv()));
|
||||
object->set_random_id(b_instance.random_id());
|
||||
const float *uv = b_deg_iter_data.dupli_object_current->uv;
|
||||
object->set_dupli_uv(make_float2(uv[0], uv[1]));
|
||||
object->set_random_id(b_deg_iter_data.dupli_object_current->random_id);
|
||||
}
|
||||
else {
|
||||
object->set_dupli_generated(zero_float3());
|
||||
|
|
@ -338,23 +341,19 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
}
|
||||
|
||||
/* Light group and linking. */
|
||||
string lightgroup = b_ob.lightgroup();
|
||||
string lightgroup = b_ob.lightgroup ? b_ob.lightgroup->name : "";
|
||||
if (lightgroup.empty()) {
|
||||
lightgroup = b_parent.lightgroup();
|
||||
lightgroup = b_parent->lightgroup ? b_parent->lightgroup->name : "";
|
||||
}
|
||||
object->set_lightgroup(ustring(lightgroup));
|
||||
|
||||
object->set_light_set_membership(BlenderLightLink::get_light_set_membership(
|
||||
b_parent.ptr.data_as<::Object>(), *b_ob.ptr.data_as<::Object>()));
|
||||
object->set_receiver_light_set(BlenderLightLink::get_receiver_light_set(
|
||||
b_parent.ptr.data_as<::Object>(), *b_ob.ptr.data_as<::Object>()));
|
||||
object->set_shadow_set_membership(BlenderLightLink::get_shadow_set_membership(
|
||||
b_parent.ptr.data_as<::Object>(), *b_ob.ptr.data_as<::Object>()));
|
||||
object->set_blocker_shadow_set(BlenderLightLink::get_blocker_shadow_set(
|
||||
b_parent.ptr.data_as<::Object>(), *b_ob.ptr.data_as<::Object>()));
|
||||
object->set_light_set_membership(BlenderLightLink::get_light_set_membership(b_parent, b_ob));
|
||||
object->set_receiver_light_set(BlenderLightLink::get_receiver_light_set(b_parent, b_ob));
|
||||
object->set_shadow_set_membership(BlenderLightLink::get_shadow_set_membership(b_parent, b_ob));
|
||||
object->set_blocker_shadow_set(BlenderLightLink::get_blocker_shadow_set(b_parent, b_ob));
|
||||
}
|
||||
|
||||
sync_object_motion_init(b_parent, b_ob, object);
|
||||
sync_object_motion_init(*b_parent, b_ob, object);
|
||||
|
||||
if (do_sync || object->motion_is_modified()) {
|
||||
object->tag_update(scene);
|
||||
|
|
@ -362,7 +361,7 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
|
||||
if (is_instance) {
|
||||
/* Sync possible particle data. */
|
||||
sync_dupli_particle(b_parent, b_instance, object);
|
||||
sync_dupli_particle(*b_parent, b_deg_iter_data, b_ob, object);
|
||||
}
|
||||
|
||||
return object;
|
||||
|
|
@ -370,27 +369,29 @@ Object *BlenderSync::sync_object(BL::ViewLayer &b_view_layer,
|
|||
|
||||
extern "C" DupliObject *rna_hack_DepsgraphObjectInstance_dupli_object_get(PointerRNA *ptr);
|
||||
|
||||
static float4 lookup_instance_property(BL::DepsgraphObjectInstance &b_instance,
|
||||
static float4 lookup_instance_property(::Object &ob,
|
||||
::DEGObjectIterData &b_deg_iter_data,
|
||||
const string &name,
|
||||
bool use_instancer)
|
||||
{
|
||||
::Object *ob = (::Object *)b_instance.object().ptr.data;
|
||||
::DupliObject *dupli = nullptr;
|
||||
::Object *dupli_parent = nullptr;
|
||||
|
||||
/* If requesting instance data, check the parent particle system and object. */
|
||||
if (use_instancer && b_instance.is_instance()) {
|
||||
dupli = rna_hack_DepsgraphObjectInstance_dupli_object_get(&b_instance.ptr);
|
||||
dupli_parent = (::Object *)b_instance.parent().ptr.data;
|
||||
if (use_instancer && b_deg_iter_data.dupli_object_current) {
|
||||
dupli = b_deg_iter_data.dupli_object_current;
|
||||
dupli_parent = b_deg_iter_data.dupli_parent;
|
||||
}
|
||||
|
||||
float4 value;
|
||||
BKE_object_dupli_find_rgba_attribute(ob, dupli, dupli_parent, name.c_str(), &value.x);
|
||||
BKE_object_dupli_find_rgba_attribute(&ob, dupli, dupli_parent, name.c_str(), &value.x);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object)
|
||||
bool BlenderSync::sync_object_attributes(::Object &b_ob,
|
||||
::DEGObjectIterData &b_deg_iter_data,
|
||||
Object *object)
|
||||
{
|
||||
/* Find which attributes are needed. */
|
||||
AttributeRequestSet requests = object->get_geometry()->needed_attributes();
|
||||
|
|
@ -415,7 +416,7 @@ bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance
|
|||
|
||||
if (type == SHD_ATTRIBUTE_OBJECT || type == SHD_ATTRIBUTE_INSTANCER) {
|
||||
const bool use_instancer = (type == SHD_ATTRIBUTE_INSTANCER);
|
||||
float4 value = lookup_instance_property(b_instance, real_name, use_instancer);
|
||||
float4 value = lookup_instance_property(b_ob, b_deg_iter_data, real_name, use_instancer);
|
||||
|
||||
/* Try finding the existing attribute value. */
|
||||
ParamValue *param = nullptr;
|
||||
|
|
@ -447,9 +448,9 @@ bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance
|
|||
|
||||
/* Object Loop */
|
||||
|
||||
void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
|
||||
void BlenderSync::sync_objects(::Depsgraph &b_depsgraph,
|
||||
::bScreen *b_screen,
|
||||
BL::SpaceView3D &b_v3d,
|
||||
::View3D *b_v3d,
|
||||
const float motion_time)
|
||||
{
|
||||
/* Task pool for multithreaded geometry sync. */
|
||||
|
|
@ -481,39 +482,50 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
|
|||
|
||||
/* object loop */
|
||||
bool cancel = false;
|
||||
const bool show_lights = BlenderViewportParameters(
|
||||
b_screen, b_v3d.ptr.data_as<::View3D>(), use_developer_ui)
|
||||
.use_scene_lights;
|
||||
const bool show_lights =
|
||||
BlenderViewportParameters(b_screen, b_v3d, use_developer_ui).use_scene_lights;
|
||||
|
||||
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
|
||||
BL::Depsgraph::object_instances_iterator b_instance_iter;
|
||||
::ViewLayer &b_view_layer = *DEG_get_evaluated_view_layer(&b_depsgraph);
|
||||
|
||||
for (b_depsgraph.object_instances.begin(b_instance_iter);
|
||||
b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
|
||||
++b_instance_iter)
|
||||
BKE_view_layer_synced_ensure(b_scene.ptr.data_as<::Scene>(), &b_view_layer);
|
||||
|
||||
::DEGObjectIterSettings deg_iter_settings{};
|
||||
deg_iter_settings.depsgraph = &b_depsgraph;
|
||||
deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
|
||||
DEGObjectIterData deg_iter_data{};
|
||||
deg_iter_data.settings = °_iter_settings;
|
||||
deg_iter_data.graph = deg_iter_settings.depsgraph;
|
||||
deg_iter_data.flag = deg_iter_settings.flags;
|
||||
|
||||
ITER_BEGIN (DEG_iterator_objects_begin,
|
||||
DEG_iterator_objects_next,
|
||||
DEG_iterator_objects_end,
|
||||
°_iter_data,
|
||||
::Object *,
|
||||
b_ob)
|
||||
{
|
||||
BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
|
||||
BL::Object b_ob = b_instance.object();
|
||||
|
||||
/* Viewport visibility. */
|
||||
const bool show_in_viewport = !b_v3d || b_ob.visible_in_viewport_get(b_v3d);
|
||||
const bool show_in_viewport = !b_v3d || BKE_object_is_visible_in_viewport(b_v3d, b_ob);
|
||||
if (show_in_viewport == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Load per-object culling data. */
|
||||
culling.init_object(scene, b_ob);
|
||||
culling.init_object(scene, *b_ob);
|
||||
|
||||
const int ob_visibility = BKE_object_visibility(b_ob, deg_iter_data.eval_mode);
|
||||
|
||||
/* Ensure the object geom supporting the hair is processed before adding
|
||||
* the hair processing task to the task pool, calling .to_mesh() on the
|
||||
* same object in parallel does not work. */
|
||||
const bool sync_hair = b_instance.show_particles() &&
|
||||
object_has_particle_hair(b_ob.ptr.data_as<::Object>());
|
||||
const bool sync_hair = (ob_visibility & OB_VISIBLE_PARTICLES) != 0 &&
|
||||
object_has_particle_hair(b_ob);
|
||||
|
||||
/* Object itself. */
|
||||
if (b_instance.show_self()) {
|
||||
if ((ob_visibility & OB_VISIBLE_SELF) != 0) {
|
||||
sync_object(b_view_layer,
|
||||
b_instance,
|
||||
*b_ob,
|
||||
deg_iter_data,
|
||||
motion_time,
|
||||
false,
|
||||
show_lights,
|
||||
|
|
@ -523,12 +535,22 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
|
|||
|
||||
/* Particle hair as separate object. */
|
||||
if (sync_hair) {
|
||||
sync_object(
|
||||
b_view_layer, b_instance, motion_time, true, show_lights, culling, &geom_task_pool);
|
||||
sync_object(b_view_layer,
|
||||
*b_ob,
|
||||
deg_iter_data,
|
||||
motion_time,
|
||||
true,
|
||||
show_lights,
|
||||
culling,
|
||||
&geom_task_pool);
|
||||
}
|
||||
|
||||
cancel = progress.get_cancel();
|
||||
if (cancel) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ITER_END;
|
||||
|
||||
geom_task_pool.wait_work();
|
||||
|
||||
|
|
@ -536,7 +558,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
|
|||
|
||||
if (!cancel && !motion) {
|
||||
/* After object for world_use_portal. */
|
||||
sync_background_light(b_screen, b_v3d.ptr.data_as<::View3D>());
|
||||
sync_background_light(b_screen, b_v3d);
|
||||
|
||||
/* Handle removed data and modified pointers, as this may free memory, delete Nodes in the
|
||||
* right order to ensure that dependent data is freed after their users. Objects should be
|
||||
|
|
@ -552,11 +574,11 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
|
|||
}
|
||||
}
|
||||
|
||||
void BlenderSync::sync_motion(BL::RenderSettings &b_render,
|
||||
BL::Depsgraph &b_depsgraph,
|
||||
void BlenderSync::sync_motion(::RenderData &b_render,
|
||||
::Depsgraph &b_depsgraph,
|
||||
::bScreen *b_screen,
|
||||
BL::SpaceView3D &b_v3d,
|
||||
BL::RegionView3D &b_rv3d,
|
||||
::View3D *b_v3d,
|
||||
::RegionView3D *b_rv3d,
|
||||
const int width,
|
||||
const int height,
|
||||
void **python_thread_state)
|
||||
|
|
@ -566,8 +588,7 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
|
|||
}
|
||||
|
||||
/* get camera object here to deal with camera switch */
|
||||
::Object *b_cam = get_camera_object(b_v3d.ptr.data_as<::View3D>(),
|
||||
b_rv3d.ptr.data_as<::RegionView3D>());
|
||||
::Object *b_cam = get_camera_object(b_v3d, b_rv3d);
|
||||
|
||||
const int frame_center = b_scene.frame_current();
|
||||
const float subframe_center = b_scene.frame_subframe();
|
||||
|
|
@ -592,7 +613,7 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
|
|||
RE_engine_frame_set(b_engine, frame, subframe);
|
||||
python_thread_state_save(python_thread_state);
|
||||
if (b_cam) {
|
||||
sync_camera_motion(*b_render.ptr.data_as<::RenderData>(), b_cam, width, height, 0.0f);
|
||||
sync_camera_motion(b_render, b_cam, width, height, 0.0f);
|
||||
}
|
||||
sync_objects(b_depsgraph, b_screen, b_v3d);
|
||||
}
|
||||
|
|
@ -638,7 +659,7 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
|
|||
python_thread_state_save(python_thread_state);
|
||||
|
||||
/* Syncs camera motion if relative_time is one of the camera's motion times. */
|
||||
sync_camera_motion(*b_render.ptr.data_as<::RenderData>(), b_cam, width, height, relative_time);
|
||||
sync_camera_motion(b_render, b_cam, width, height, relative_time);
|
||||
|
||||
/* sync object */
|
||||
sync_objects(b_depsgraph, b_screen, b_v3d, relative_time);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "scene/camera.h"
|
||||
|
||||
#include "BLI_bounds.hh"
|
||||
|
||||
#include "blender/object_cull.h"
|
||||
#include "blender/util.h"
|
||||
|
||||
|
|
@ -39,13 +41,14 @@ BlenderObjectCulling::BlenderObjectCulling(Scene *scene, BL::Scene &b_scene)
|
|||
}
|
||||
}
|
||||
|
||||
void BlenderObjectCulling::init_object(Scene *scene, BL::Object &b_ob)
|
||||
void BlenderObjectCulling::init_object(Scene *scene, ::Object &b_ob)
|
||||
{
|
||||
if (!use_scene_camera_cull_ && !use_scene_distance_cull_) {
|
||||
return;
|
||||
}
|
||||
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
PointerRNA b_ob_rna_ptr = RNA_id_pointer_create(&b_ob.id);
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob_rna_ptr, "cycles");
|
||||
|
||||
use_camera_cull_ = use_scene_camera_cull_ && get_boolean(cobject, "use_camera_cull");
|
||||
use_distance_cull_ = use_scene_distance_cull_ && get_boolean(cobject, "use_distance_cull");
|
||||
|
|
@ -56,7 +59,7 @@ void BlenderObjectCulling::init_object(Scene *scene, BL::Object &b_ob)
|
|||
}
|
||||
}
|
||||
|
||||
bool BlenderObjectCulling::test(Scene *scene, BL::Object &b_ob, Transform &tfm)
|
||||
bool BlenderObjectCulling::test(Scene *scene, ::Object &b_ob, Transform &tfm)
|
||||
{
|
||||
if (!use_camera_cull_ && !use_distance_cull_) {
|
||||
return false;
|
||||
|
|
@ -64,9 +67,17 @@ bool BlenderObjectCulling::test(Scene *scene, BL::Object &b_ob, Transform &tfm)
|
|||
|
||||
/* Compute world space bounding box corners. */
|
||||
float3 bb[8];
|
||||
BL::Array<float, 24> boundbox = b_ob.bound_box();
|
||||
std::array<blender::float3, 8> boundbox;
|
||||
if (const std::optional<blender::Bounds<blender::float3>> bounds =
|
||||
BKE_object_boundbox_eval_cached_get(&b_ob))
|
||||
{
|
||||
boundbox = blender::bounds::corners(*bounds);
|
||||
}
|
||||
else {
|
||||
boundbox.fill(blender::float3(0));
|
||||
}
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
const float3 p = make_float3(boundbox[3 * i + 0], boundbox[3 * i + 1], boundbox[3 * i + 2]);
|
||||
const float3 p = make_float3(boundbox[i].x, boundbox[i].y, boundbox[i].z);
|
||||
bb[i] = transform_point(&tfm, p);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ class BlenderObjectCulling {
|
|||
public:
|
||||
BlenderObjectCulling(Scene *scene, BL::Scene &b_scene);
|
||||
|
||||
void init_object(Scene *scene, BL::Object &b_ob);
|
||||
bool test(Scene *scene, BL::Object &b_ob, Transform &tfm);
|
||||
void init_object(Scene *scene, ::Object &b_ob);
|
||||
bool test(Scene *scene, ::Object &b_ob, Transform &tfm);
|
||||
|
||||
private:
|
||||
bool test_camera(Scene *scene, const float3 bb[8]);
|
||||
|
|
|
|||
|
|
@ -9,16 +9,21 @@
|
|||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
|
||||
#include "DNA_particle_types.h"
|
||||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Utilities */
|
||||
|
||||
bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
|
||||
BL::DepsgraphObjectInstance &b_instance,
|
||||
bool BlenderSync::sync_dupli_particle(::Object &b_parent,
|
||||
::DEGObjectIterData &b_deg_iter_data,
|
||||
::Object &b_ob,
|
||||
Object *object)
|
||||
{
|
||||
/* Test if this dupli was generated from a particle system. */
|
||||
BL::ParticleSystem b_psys = b_instance.particle_system();
|
||||
::ParticleSystem *b_psys = b_deg_iter_data.dupli_object_current->particle_system;
|
||||
if (!b_psys) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -31,22 +36,18 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
|
|||
}
|
||||
|
||||
/* don't handle child particles yet */
|
||||
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_instance.persistent_id();
|
||||
const int *persistent_id = b_deg_iter_data.dupli_object_current->persistent_id;
|
||||
|
||||
if (persistent_id[0] >= b_psys.particles.length()) {
|
||||
if (persistent_id[0] >= b_psys->totpart) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* find particle system */
|
||||
const ParticleSystemKey key(b_ob, persistent_id);
|
||||
const ParticleSystemKey key(&b_parent, persistent_id);
|
||||
ParticleSystem *psys;
|
||||
|
||||
const bool first_use = !particle_system_map.is_used(key);
|
||||
const bool need_update = particle_system_map.add_or_update(
|
||||
&psys,
|
||||
&b_ob.ptr.data_as<::Object>()->id,
|
||||
&b_instance.object().ptr.data_as<::Object>()->id,
|
||||
key);
|
||||
const bool need_update = particle_system_map.add_or_update(&psys, &b_parent.id, &b_ob.id, key);
|
||||
|
||||
/* no update needed? */
|
||||
if (!need_update && !object->get_geometry()->is_modified() &&
|
||||
|
|
@ -62,17 +63,18 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
|
|||
}
|
||||
|
||||
/* add particle */
|
||||
BL::Particle b_pa = b_psys.particles[persistent_id[0]];
|
||||
::ParticleData &b_pa = b_psys->particles[persistent_id[0]];
|
||||
Particle pa;
|
||||
|
||||
pa.index = persistent_id[0];
|
||||
pa.age = b_scene.frame_current_final() - b_pa.birth_time();
|
||||
pa.lifetime = b_pa.lifetime();
|
||||
pa.location = get_float3(b_pa.location());
|
||||
pa.rotation = get_float4(b_pa.rotation());
|
||||
pa.size = b_pa.size();
|
||||
pa.velocity = get_float3(b_pa.velocity());
|
||||
pa.angular_velocity = get_float3(b_pa.angular_velocity());
|
||||
pa.age = b_scene.frame_current_final() - b_pa.time;
|
||||
pa.lifetime = b_pa.lifetime;
|
||||
pa.location = make_float3(b_pa.state.co[0], b_pa.state.co[1], b_pa.state.co[2]);
|
||||
pa.rotation = make_float4(
|
||||
b_pa.state.rot[0], b_pa.state.rot[1], b_pa.state.rot[2], b_pa.state.rot[3]);
|
||||
pa.size = b_pa.size;
|
||||
pa.velocity = make_float3(b_pa.state.vel[0], b_pa.state.vel[1], b_pa.state.vel[2]);
|
||||
pa.angular_velocity = make_float3(b_pa.state.ave[0], b_pa.state.ave[1], b_pa.state.ave[2]);
|
||||
|
||||
psys->particles.push_back_slow(pa);
|
||||
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ void BlenderSync::sync_pointcloud(PointCloud *pointcloud, BObjectInfo &b_ob_info
|
|||
new_pointcloud.set_used_shaders(used_shaders);
|
||||
|
||||
/* TODO: add option to filter out points in the view layer. */
|
||||
const ::PointCloud *b_pointcloud = b_ob_info.object_data.ptr.data_as<::PointCloud>();
|
||||
const ::PointCloud *b_pointcloud = blender::id_cast<::PointCloud *>(b_ob_info.object_data);
|
||||
/* Motion blur attribute is relative to seconds, we need it relative to frames. */
|
||||
const bool need_motion = object_need_motion_attribute(b_ob_info, scene);
|
||||
const float motion_scale = (need_motion) ?
|
||||
|
|
@ -231,9 +231,9 @@ void BlenderSync::sync_pointcloud_motion(PointCloud *pointcloud,
|
|||
}
|
||||
|
||||
/* Export deformed coordinates. */
|
||||
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
|
||||
if (ccl::BKE_object_is_deform_modified(b_ob_info, *b_scene.ptr.data_as<::Scene>(), preview)) {
|
||||
/* PointCloud object. */
|
||||
const ::PointCloud *b_pointcloud = b_ob_info.object_data.ptr.data_as<::PointCloud>();
|
||||
const ::PointCloud *b_pointcloud = blender::id_cast<::PointCloud *>(b_ob_info.object_data);
|
||||
export_pointcloud_motion(pointcloud, *b_pointcloud, motion_step);
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph,
|
|||
/* Object */
|
||||
else if (b_id.is_a(&RNA_Object)) {
|
||||
BL::Object b_ob(b_id);
|
||||
const bool can_have_geometry = object_can_have_geometry(b_ob);
|
||||
const bool is_light = !can_have_geometry && object_is_light(b_ob);
|
||||
const bool can_have_geometry = object_can_have_geometry(*b_ob.ptr.data_as<::Object>());
|
||||
const bool is_light = !can_have_geometry && object_is_light(*b_ob.ptr.data_as<::Object>());
|
||||
|
||||
if (b_ob.is_instancer() && b_update.is_updated_shading()) {
|
||||
/* Needed for object color updates on instancer, among other things. */
|
||||
|
|
@ -147,23 +147,24 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph,
|
|||
object_map.set_recalc(b_ob);
|
||||
}
|
||||
|
||||
const bool use_adaptive_subdiv = object_subdivision_type(
|
||||
b_ob, preview, use_adaptive_subdivision) !=
|
||||
const bool use_adaptive_subdiv = object_subdivision_type(*b_ob.ptr.data_as<::Object>(),
|
||||
preview,
|
||||
use_adaptive_subdivision) !=
|
||||
Mesh::SUBDIVISION_NONE;
|
||||
|
||||
/* Need to recompute geometry if the geometry changed, or the transform changed
|
||||
* and using adaptive subdivision. */
|
||||
if (updated_geometry || (updated_transform && use_adaptive_subdiv)) {
|
||||
BL::ID const key = BKE_object_is_modified(b_ob) ?
|
||||
b_ob :
|
||||
object_get_data(b_ob, use_adaptive_subdiv);
|
||||
::ID *key = BKE_object_is_modified(*b_ob.ptr.data_as<::Object>()) ?
|
||||
&b_ob.ptr.data_as<::Object>()->id :
|
||||
object_get_data(*b_ob.ptr.data_as<::Object>(), use_adaptive_subdiv);
|
||||
geometry_map.set_recalc(key);
|
||||
|
||||
/* Sync all contained geometry instances as well when the object changed.. */
|
||||
const map<void *, set<BL::ID>>::const_iterator instance_geometries =
|
||||
const map<void *, set<::ID *>>::const_iterator instance_geometries =
|
||||
instance_geometries_by_object.find(b_ob.ptr.data);
|
||||
if (instance_geometries != instance_geometries_by_object.end()) {
|
||||
for (BL::ID const &geometry : instance_geometries->second) {
|
||||
for (::ID *geometry : instance_geometries->second) {
|
||||
geometry_map.set_recalc(geometry);
|
||||
}
|
||||
}
|
||||
|
|
@ -190,7 +191,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph,
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (object_is_camera(b_ob)) {
|
||||
else if (object_is_camera(*b_ob.ptr.data_as<::Object>())) {
|
||||
shader_map.set_recalc(b_ob);
|
||||
}
|
||||
|
||||
|
|
@ -320,9 +321,16 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
|
|||
if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE ||
|
||||
scene->camera->get_motion_position() == MOTION_POSITION_CENTER)
|
||||
{
|
||||
sync_objects(b_depsgraph, b_screen, b_v3d);
|
||||
sync_objects(*b_depsgraph.ptr.data_as<::Depsgraph>(), b_screen, b_v3d.ptr.data_as<::View3D>());
|
||||
}
|
||||
sync_motion(b_render, b_depsgraph, b_screen, b_v3d, b_rv3d, width, height, python_thread_state);
|
||||
sync_motion(*b_render.ptr.data_as<::RenderData>(),
|
||||
*b_depsgraph.ptr.data_as<::Depsgraph>(),
|
||||
b_screen,
|
||||
b_v3d.ptr.data_as<::View3D>(),
|
||||
b_rv3d.ptr.data_as<::RegionView3D>(),
|
||||
width,
|
||||
height,
|
||||
python_thread_state);
|
||||
|
||||
geometry_synced.clear();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#include "util/map.h"
|
||||
#include "util/set.h"
|
||||
|
||||
struct DEGObjectIterData;
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Background;
|
||||
|
|
@ -108,15 +110,15 @@ class BlenderSync {
|
|||
/* sync */
|
||||
void sync_lights(::Depsgraph &b_depsgraph, bool update_all);
|
||||
void sync_materials(::Depsgraph &b_depsgraph, bool update_all);
|
||||
void sync_objects(BL::Depsgraph &b_depsgraph,
|
||||
void sync_objects(::Depsgraph &b_depsgraph,
|
||||
::bScreen *b_screen,
|
||||
BL::SpaceView3D &b_v3d,
|
||||
::View3D *b_v3d,
|
||||
const float motion_time = 0.0f);
|
||||
void sync_motion(BL::RenderSettings &b_render,
|
||||
BL::Depsgraph &b_depsgraph,
|
||||
void sync_motion(::RenderData &b_render,
|
||||
::Depsgraph &b_depsgraph,
|
||||
::bScreen *b_screen,
|
||||
BL::SpaceView3D &b_v3d,
|
||||
BL::RegionView3D &b_rv3d,
|
||||
::View3D *b_v3d,
|
||||
::RegionView3D *b_rv3d,
|
||||
const int width,
|
||||
const int height,
|
||||
void **python_thread_state);
|
||||
|
|
@ -136,20 +138,23 @@ class BlenderSync {
|
|||
void resolve_view_layer_attributes(Shader *shader, ShaderGraph *graph, ::Depsgraph &b_depsgraph);
|
||||
|
||||
/* Object */
|
||||
Object *sync_object(BL::ViewLayer &b_view_layer,
|
||||
BL::DepsgraphObjectInstance &b_instance,
|
||||
Object *sync_object(::ViewLayer &b_view_layer,
|
||||
::Object &b_ob,
|
||||
::DEGObjectIterData &b_deg_iter_data,
|
||||
const float motion_time,
|
||||
bool use_particle_hair,
|
||||
bool show_lights,
|
||||
BlenderObjectCulling &culling,
|
||||
TaskPool *geom_task_pool);
|
||||
void sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object);
|
||||
void sync_object_motion_init(::Object &b_parent, ::Object &b_ob, Object *object);
|
||||
|
||||
void sync_procedural(BL::Object &b_ob,
|
||||
BL::MeshSequenceCacheModifier &b_mesh_cache,
|
||||
bool has_subdivision);
|
||||
|
||||
bool sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object);
|
||||
bool sync_object_attributes(::Object &b_ob,
|
||||
::DEGObjectIterData &b_deg_iter_data,
|
||||
Object *object);
|
||||
|
||||
/* Volume */
|
||||
void sync_volume(BObjectInfo &b_ob_info, Volume *volume);
|
||||
|
|
@ -199,8 +204,9 @@ class BlenderSync {
|
|||
void sync_background_light(::bScreen *b_screen, ::View3D *b_v3d);
|
||||
|
||||
/* Particles */
|
||||
bool sync_dupli_particle(BL::Object &b_ob,
|
||||
BL::DepsgraphObjectInstance &b_instance,
|
||||
bool sync_dupli_particle(::Object &b_parent,
|
||||
::DEGObjectIterData &b_deg_iter_data,
|
||||
::Object &b_ob,
|
||||
Object *object);
|
||||
|
||||
/* Images. */
|
||||
|
|
@ -208,11 +214,11 @@ class BlenderSync {
|
|||
|
||||
/* util */
|
||||
void find_shader(const ::ID *id, array<Node *> &used_shaders, Shader *default_shader);
|
||||
bool BKE_object_is_modified(BL::Object &b_ob);
|
||||
bool BKE_object_is_modified(::Object &b_ob);
|
||||
bool object_is_geometry(BObjectInfo &b_ob_info);
|
||||
bool object_can_have_geometry(BL::Object &b_ob);
|
||||
bool object_is_light(BL::Object &b_ob);
|
||||
bool object_is_camera(BL::Object &b_ob);
|
||||
bool object_can_have_geometry(::Object &b_ob);
|
||||
bool object_is_light(::Object &b_ob);
|
||||
bool object_is_camera(::Object &b_ob);
|
||||
|
||||
::Object *get_camera_object(::View3D *b_v3d, ::RegionView3D *b_rv3d);
|
||||
::Object *get_dicing_camera_object(::View3D *b_v3d, ::RegionView3D *b_rv3d);
|
||||
|
|
@ -234,7 +240,7 @@ class BlenderSync {
|
|||
set<Geometry *> geometry_motion_synced;
|
||||
set<Geometry *> geometry_motion_attribute_synced;
|
||||
/** Remember which geometries come from which objects to be able to sync them after changes. */
|
||||
map<void *, set<BL::ID>> instance_geometries_by_object;
|
||||
map<void *, set<::ID *>> instance_geometries_by_object;
|
||||
set<float> motion_times;
|
||||
void *world_map;
|
||||
bool world_recalc;
|
||||
|
|
|
|||
|
|
@ -36,35 +36,32 @@
|
|||
#include "BKE_mesh.h"
|
||||
#include "BKE_mesh_types.hh"
|
||||
#include "BKE_mesh_wrapper.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
static inline BL::ID object_get_data(const BL::Object &b_ob, const bool use_adaptive_subdivision)
|
||||
static inline ::ID *object_get_data(const ::Object &b_ob, const bool use_adaptive_subdivision)
|
||||
{
|
||||
::Object *object = reinterpret_cast<::Object *>(b_ob.ptr.data);
|
||||
|
||||
if (!use_adaptive_subdivision && object->type == OB_MESH) {
|
||||
::Mesh *mesh = static_cast<::Mesh *>(object->data);
|
||||
mesh = BKE_mesh_wrapper_ensure_subdivision(mesh);
|
||||
return BL::ID(RNA_id_pointer_create(&mesh->id));
|
||||
if (!use_adaptive_subdivision && b_ob.type == OB_MESH) {
|
||||
return &BKE_mesh_wrapper_ensure_subdivision(static_cast<::Mesh *>(b_ob.data))->id;
|
||||
}
|
||||
|
||||
return BL::ID(RNA_id_pointer_create(reinterpret_cast<ID *>(object->data)));
|
||||
return reinterpret_cast<ID *>(b_ob.data);
|
||||
}
|
||||
|
||||
struct BObjectInfo {
|
||||
/* Object directly provided by the depsgraph iterator. This object is only valid during one
|
||||
* iteration and must not be accessed afterwards. Transforms and visibility should be checked on
|
||||
* this object. */
|
||||
BL::Object iter_object;
|
||||
::Object *iter_object;
|
||||
|
||||
/* This object remains alive even after the object iterator is done. It corresponds to one
|
||||
* original object. It is the object that owns the object data below. */
|
||||
BL::Object real_object;
|
||||
::Object *real_object;
|
||||
|
||||
/* The object-data referenced by the iter object. This is still valid after the depsgraph
|
||||
* iterator is done. It might have a different type compared to object_get_data(real_object). */
|
||||
BL::ID object_data;
|
||||
::ID *object_data;
|
||||
|
||||
/* Object will use adaptive subdivision. */
|
||||
bool use_adaptive_subdivision;
|
||||
|
|
@ -73,17 +70,15 @@ struct BObjectInfo {
|
|||
* geometry instance that does not have a 1-to-1 relationship with an object. */
|
||||
bool is_real_object_data() const
|
||||
{
|
||||
return object_get_data(const_cast<BL::Object &>(real_object), use_adaptive_subdivision) ==
|
||||
object_data;
|
||||
return object_get_data(*real_object, use_adaptive_subdivision) == object_data;
|
||||
}
|
||||
};
|
||||
|
||||
static inline BL::Mesh object_copy_mesh_data(const BObjectInfo &b_ob_info)
|
||||
static inline ::Mesh *object_copy_mesh_data(const BObjectInfo &b_ob_info)
|
||||
{
|
||||
::Object *object = static_cast<::Object *>(b_ob_info.real_object.ptr.data);
|
||||
::Mesh *mesh = BKE_mesh_new_from_object(
|
||||
nullptr, object, false, false, !b_ob_info.use_adaptive_subdivision);
|
||||
return BL::Mesh(RNA_id_pointer_create(&mesh->id));
|
||||
nullptr, b_ob_info.real_object, false, false, !b_ob_info.use_adaptive_subdivision);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
int blender_attribute_name_split_type(ustring name, string *r_real_name);
|
||||
|
|
@ -91,23 +86,25 @@ int blender_attribute_name_split_type(ustring name, string *r_real_name);
|
|||
void python_thread_state_save(void **python_thread_state);
|
||||
void python_thread_state_restore(void **python_thread_state);
|
||||
|
||||
static bool mesh_use_corner_normals(const BObjectInfo &b_ob_info, BL::Mesh &mesh)
|
||||
static bool mesh_use_corner_normals(const BObjectInfo &b_ob_info, ::Mesh *mesh)
|
||||
{
|
||||
return mesh && !b_ob_info.use_adaptive_subdivision &&
|
||||
(static_cast<const ::Mesh *>(mesh.ptr.data)->normals_domain(true) ==
|
||||
blender::bke::MeshNormalDomain::Corner);
|
||||
(mesh->normals_domain(true) == blender::bke::MeshNormalDomain::Corner);
|
||||
}
|
||||
|
||||
static inline BL::Mesh object_to_mesh(BObjectInfo &b_ob_info)
|
||||
void mesh_split_edges_for_corner_normals(::Mesh &mesh);
|
||||
|
||||
static inline ::Mesh *object_to_mesh(BObjectInfo &b_ob_info)
|
||||
{
|
||||
BL::Mesh mesh = (b_ob_info.object_data.is_a(&RNA_Mesh)) ? BL::Mesh(b_ob_info.object_data) :
|
||||
BL::Mesh(PointerRNA_NULL);
|
||||
::Mesh *mesh = (GS(b_ob_info.object_data->name) == ID_ME) ?
|
||||
blender::id_cast<::Mesh *>(b_ob_info.object_data) :
|
||||
nullptr;
|
||||
|
||||
bool use_corner_normals = false;
|
||||
|
||||
if (b_ob_info.is_real_object_data()) {
|
||||
if (mesh) {
|
||||
if (mesh.is_editmode()) {
|
||||
if (mesh->runtime->edit_mesh) {
|
||||
/* Flush edit-mesh to mesh, including all data layers. */
|
||||
mesh = object_copy_mesh_data(b_ob_info);
|
||||
use_corner_normals = mesh_use_corner_normals(b_ob_info, mesh);
|
||||
|
|
@ -130,11 +127,11 @@ static inline BL::Mesh object_to_mesh(BObjectInfo &b_ob_info)
|
|||
|
||||
if (mesh) {
|
||||
if (use_corner_normals) {
|
||||
mesh.split_faces();
|
||||
mesh_split_edges_for_corner_normals(*mesh);
|
||||
}
|
||||
|
||||
if (b_ob_info.use_adaptive_subdivision) {
|
||||
mesh.calc_loop_triangles();
|
||||
mesh->corner_tris();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,8 +144,8 @@ static inline void free_object_to_mesh(BObjectInfo &b_ob_info, ::Mesh &mesh)
|
|||
return;
|
||||
}
|
||||
/* Free mesh if we didn't just use the existing one. */
|
||||
BL::Object object = b_ob_info.real_object;
|
||||
if (object_get_data(object, b_ob_info.use_adaptive_subdivision).ptr.data != &mesh) {
|
||||
::Object *object = b_ob_info.real_object;
|
||||
if (object_get_data(*object, b_ob_info.use_adaptive_subdivision) != &mesh.id) {
|
||||
BKE_id_free(nullptr, &mesh.id);
|
||||
}
|
||||
}
|
||||
|
|
@ -299,12 +296,7 @@ static inline void curvemapping_color_to_array(const ::CurveMapping &cumap,
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool BKE_object_is_modified(BL::Object &self, BL::Scene &scene, bool preview)
|
||||
{
|
||||
return self.is_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false;
|
||||
}
|
||||
|
||||
static inline bool BKE_object_is_deform_modified(BObjectInfo &self, BL::Scene &scene, bool preview)
|
||||
static inline bool BKE_object_is_deform_modified(BObjectInfo &self, ::Scene &scene, bool preview)
|
||||
{
|
||||
if (!self.is_real_object_data()) {
|
||||
/* Comes from geometry nodes, can't use heuristic to guess if it's animated. */
|
||||
|
|
@ -312,8 +304,8 @@ static inline bool BKE_object_is_deform_modified(BObjectInfo &self, BL::Scene &s
|
|||
}
|
||||
|
||||
/* Use heuristic to quickly check if object is potentially animated. */
|
||||
return self.real_object.is_deform_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true :
|
||||
false;
|
||||
const int settings = preview ? eModifierMode_Realtime : eModifierMode_Render;
|
||||
return (::BKE_object_is_deform_modified(&scene, self.real_object) & settings) != 0;
|
||||
}
|
||||
|
||||
static inline int render_resolution_x(const ::RenderData &b_render)
|
||||
|
|
@ -648,17 +640,19 @@ static inline uint object_motion_steps(::Object &b_parent,
|
|||
}
|
||||
|
||||
/* object uses deformation motion blur */
|
||||
static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_ob)
|
||||
static inline bool object_use_deform_motion(::Object &b_parent, ::Object &b_ob)
|
||||
{
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
PointerRNA b_ob_rna_ptr = RNA_id_pointer_create(&b_ob.id);
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob_rna_ptr, "cycles");
|
||||
bool use_deform_motion = get_boolean(cobject, "use_deform_motion");
|
||||
/* If motion blur is enabled for the object we also check
|
||||
* whether it's enabled for the parent object as well.
|
||||
*
|
||||
* This way we can control motion blur from the dupli-group
|
||||
* duplicator much easier. */
|
||||
if (use_deform_motion && b_parent.ptr.data != b_ob.ptr.data) {
|
||||
PointerRNA parent_cobject = RNA_pointer_get(&b_parent.ptr, "cycles");
|
||||
if (use_deform_motion && &b_parent != &b_ob) {
|
||||
PointerRNA b_parent_rna_ptr = RNA_id_pointer_create(&b_parent.id);
|
||||
PointerRNA parent_cobject = RNA_pointer_get(&b_parent_rna_ptr, "cycles");
|
||||
use_deform_motion &= get_boolean(parent_cobject, "use_deform_motion");
|
||||
}
|
||||
return use_deform_motion;
|
||||
|
|
@ -708,24 +702,27 @@ static inline BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b
|
|||
return BL::MeshSequenceCacheModifier(PointerRNA_NULL);
|
||||
}
|
||||
|
||||
static BL::SubsurfModifier object_subdivision_modifier(BL::Object &b_ob, const bool preview)
|
||||
static ::SubsurfModifierData *object_subdivision_modifier(::Object &b_ob, const bool preview)
|
||||
{
|
||||
if (!b_ob.modifiers.empty()) {
|
||||
BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length() - 1];
|
||||
const bool enabled = preview ? mod.show_viewport() : mod.show_render();
|
||||
|
||||
if (enabled && mod.type() == BL::Modifier::type_SUBSURF) {
|
||||
BL::SubsurfModifier subsurf(mod);
|
||||
if (subsurf.use_adaptive_subdivision()) {
|
||||
return subsurf;
|
||||
}
|
||||
}
|
||||
ModifierData *md = static_cast<ModifierData *>(b_ob.modifiers.last);
|
||||
if (!md) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return PointerRNA_NULL;
|
||||
if (md->type != eModifierType_Subsurf) {
|
||||
return nullptr;
|
||||
}
|
||||
const ModifierMode enabled_mode = preview ? eModifierMode_Render : eModifierMode_Realtime;
|
||||
if ((md->mode & enabled_mode) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
SubsurfModifierData *subsurf = reinterpret_cast<SubsurfModifierData *>(md);
|
||||
if ((subsurf->flags & eSubsurfModifierFlag_UseAdaptiveSubdivision) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return subsurf;
|
||||
}
|
||||
|
||||
static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob,
|
||||
static inline Mesh::SubdivisionType object_subdivision_type(::Object &b_ob,
|
||||
const bool preview,
|
||||
const bool use_adaptive_subdivision)
|
||||
{
|
||||
|
|
@ -733,10 +730,10 @@ static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob,
|
|||
return Mesh::SUBDIVISION_NONE;
|
||||
}
|
||||
|
||||
BL::SubsurfModifier subsurf = object_subdivision_modifier(b_ob, preview);
|
||||
::SubsurfModifierData *subsurf = object_subdivision_modifier(b_ob, preview);
|
||||
|
||||
if (subsurf) {
|
||||
if (subsurf.subdivision_type() == BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
|
||||
if (subsurf->subdivType == SUBSURF_TYPE_CATMULL_CLARK) {
|
||||
return Mesh::SUBDIVISION_CATMULL_CLARK;
|
||||
}
|
||||
return Mesh::SUBDIVISION_LINEAR;
|
||||
|
|
@ -745,7 +742,7 @@ static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob,
|
|||
return Mesh::SUBDIVISION_NONE;
|
||||
}
|
||||
|
||||
static inline void object_subdivision_to_mesh(BL::Object &b_ob,
|
||||
static inline void object_subdivision_to_mesh(::Object &b_ob,
|
||||
Mesh &mesh,
|
||||
const bool preview,
|
||||
const bool use_adaptive_subdivision)
|
||||
|
|
@ -755,61 +752,63 @@ static inline void object_subdivision_to_mesh(BL::Object &b_ob,
|
|||
return;
|
||||
}
|
||||
|
||||
BL::SubsurfModifier subsurf = object_subdivision_modifier(b_ob, preview);
|
||||
::SubsurfModifierData *subsurf = object_subdivision_modifier(b_ob, preview);
|
||||
|
||||
if (!subsurf) {
|
||||
mesh.set_subdivision_type(Mesh::SUBDIVISION_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (subsurf.subdivision_type() != BL::SubsurfModifier::subdivision_type_CATMULL_CLARK) {
|
||||
if (subsurf->subdivType != SUBSURF_TYPE_CATMULL_CLARK) {
|
||||
mesh.set_subdivision_type(Mesh::SUBDIVISION_LINEAR);
|
||||
return;
|
||||
}
|
||||
|
||||
mesh.set_subdivision_type(Mesh::SUBDIVISION_CATMULL_CLARK);
|
||||
|
||||
switch (subsurf.boundary_smooth()) {
|
||||
case BL::SubsurfModifier::boundary_smooth_PRESERVE_CORNERS:
|
||||
switch (subsurf->boundary_smooth) {
|
||||
case SUBSURF_BOUNDARY_SMOOTH_PRESERVE_CORNERS:
|
||||
mesh.set_subdivision_boundary_interpolation(Mesh::SUBDIVISION_BOUNDARY_EDGE_AND_CORNER);
|
||||
break;
|
||||
case BL::SubsurfModifier::boundary_smooth_ALL:
|
||||
case SUBSURF_BOUNDARY_SMOOTH_ALL:
|
||||
mesh.set_subdivision_boundary_interpolation(Mesh::SUBDIVISION_BOUNDARY_EDGE_ONLY);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (subsurf.uv_smooth()) {
|
||||
case BL::SubsurfModifier::uv_smooth_NONE:
|
||||
switch (subsurf->uv_smooth) {
|
||||
case SUBSURF_UV_SMOOTH_NONE:
|
||||
mesh.set_subdivision_fvar_interpolation(Mesh::SUBDIVISION_FVAR_LINEAR_ALL);
|
||||
break;
|
||||
case BL::SubsurfModifier::uv_smooth_PRESERVE_CORNERS:
|
||||
case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS:
|
||||
mesh.set_subdivision_fvar_interpolation(Mesh::SUBDIVISION_FVAR_LINEAR_CORNERS_ONLY);
|
||||
break;
|
||||
case BL::SubsurfModifier::uv_smooth_PRESERVE_CORNERS_AND_JUNCTIONS:
|
||||
case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS:
|
||||
mesh.set_subdivision_fvar_interpolation(Mesh::SUBDIVISION_FVAR_LINEAR_CORNERS_PLUS1);
|
||||
break;
|
||||
case BL::SubsurfModifier::uv_smooth_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE:
|
||||
case SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE:
|
||||
mesh.set_subdivision_fvar_interpolation(Mesh::SUBDIVISION_FVAR_LINEAR_CORNERS_PLUS2);
|
||||
break;
|
||||
case BL::SubsurfModifier::uv_smooth_PRESERVE_BOUNDARIES:
|
||||
case SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES:
|
||||
mesh.set_subdivision_fvar_interpolation(Mesh::SUBDIVISION_FVAR_LINEAR_BOUNDARIES);
|
||||
break;
|
||||
case BL::SubsurfModifier::uv_smooth_SMOOTH_ALL:
|
||||
case SUBSURF_UV_SMOOTH_ALL:
|
||||
mesh.set_subdivision_fvar_interpolation(Mesh::SUBDIVISION_FVAR_LINEAR_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint object_ray_visibility(BL::Object &b_ob)
|
||||
static inline uint object_ray_visibility(::Object &b_ob)
|
||||
{
|
||||
uint flag = 0;
|
||||
|
||||
flag |= b_ob.visible_camera() ? PATH_RAY_CAMERA : PathRayFlag(0);
|
||||
flag |= b_ob.visible_diffuse() ? PATH_RAY_DIFFUSE : PathRayFlag(0);
|
||||
flag |= b_ob.visible_glossy() ? PATH_RAY_GLOSSY : PathRayFlag(0);
|
||||
flag |= b_ob.visible_transmission() ? PATH_RAY_TRANSMIT : PathRayFlag(0);
|
||||
flag |= b_ob.visible_shadow() ? PATH_RAY_SHADOW : PathRayFlag(0);
|
||||
flag |= b_ob.visible_volume_scatter() ? PATH_RAY_VOLUME_SCATTER : PathRayFlag(0);
|
||||
flag |= ((b_ob.visibility_flag & OB_HIDE_CAMERA) == 0) ? PATH_RAY_CAMERA : PathRayFlag(0);
|
||||
flag |= ((b_ob.visibility_flag & OB_HIDE_DIFFUSE) == 0) ? PATH_RAY_DIFFUSE : PathRayFlag(0);
|
||||
flag |= ((b_ob.visibility_flag & OB_HIDE_GLOSSY) == 0) ? PATH_RAY_GLOSSY : PathRayFlag(0);
|
||||
flag |= ((b_ob.visibility_flag & OB_HIDE_TRANSMISSION) == 0) ? PATH_RAY_TRANSMIT :
|
||||
PathRayFlag(0);
|
||||
flag |= ((b_ob.visibility_flag & OB_HIDE_SHADOW) == 0) ? PATH_RAY_SHADOW : PathRayFlag(0);
|
||||
flag |= ((b_ob.visibility_flag & OB_HIDE_VOLUME_SCATTER) == 0) ? PATH_RAY_VOLUME_SCATTER :
|
||||
PathRayFlag(0);
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
|
@ -836,7 +835,8 @@ static inline bool object_need_motion_attribute(BObjectInfo &b_ob_info, Scene *s
|
|||
* - Motion attribute expects non-zero time steps.
|
||||
*
|
||||
* Avoid adding motion attributes if the motion blur will enforce 0 motion steps. */
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob_info.real_object.ptr, "cycles");
|
||||
PointerRNA b_ob_rna_ptr = RNA_id_pointer_create(&b_ob_info.real_object->id);
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob_rna_ptr, "cycles");
|
||||
const bool use_motion = get_boolean(cobject, "use_motion_blur");
|
||||
if (!use_motion) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -179,8 +179,7 @@ static void sync_smoke_volume(
|
|||
if (!b_ob_info.is_real_object_data()) {
|
||||
return;
|
||||
}
|
||||
::FluidDomainSettings *b_domain = object_fluid_gas_domain_find(
|
||||
*b_ob_info.real_object.ptr.data_as<::Object>());
|
||||
::FluidDomainSettings *b_domain = object_fluid_gas_domain_find(*b_ob_info.real_object);
|
||||
if (!b_domain) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -222,7 +221,7 @@ static void sync_smoke_volume(
|
|||
}
|
||||
|
||||
unique_ptr<ImageLoader> loader = make_unique<BlenderSmokeLoader>(
|
||||
*b_ob_info.real_object.ptr.data_as<::Object>(), std, clipping);
|
||||
*b_ob_info.real_object, std, clipping);
|
||||
ImageParams params;
|
||||
params.frame = frame;
|
||||
|
||||
|
|
@ -283,7 +282,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
|
|||
static void sync_volume_object(
|
||||
::Main &b_data, ::Scene &b_scene, BObjectInfo &b_ob_info, Scene *scene, Volume *volume)
|
||||
{
|
||||
::Volume &b_volume = *static_cast<::Volume *>(b_ob_info.object_data.ptr.data);
|
||||
::Volume &b_volume = *blender::id_cast<::Volume *>(b_ob_info.object_data);
|
||||
BKE_volume_load(&b_volume, &b_data);
|
||||
|
||||
::VolumeRender &b_render = b_volume.render;
|
||||
|
|
@ -374,7 +373,7 @@ void BlenderSync::sync_volume(BObjectInfo &b_ob_info, Volume *volume)
|
|||
volume->clear(true);
|
||||
|
||||
if (view_layer.use_volumes) {
|
||||
if (b_ob_info.object_data.is_a(&RNA_Volume)) {
|
||||
if (GS(b_ob_info.object_data->name) == ID_VO) {
|
||||
/* Volume object. Create only attributes, bounding mesh will then
|
||||
* be automatically generated later. */
|
||||
sync_volume_object(*b_data.ptr.data_as<::Main>(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue