From d2b741bebe5e405540750f1b143af6836cd4e9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Thu, 15 Jun 2023 03:38:16 +0200 Subject: [PATCH] Fix #107877: Alembic procedural crashes with point clouds Somehow the implementation for the main function to load point clouds data was missing although everything else to support point clouds was there. Compilers were more than happy to convert the IPointsSchema to another schema type for the compilation to succeed, and the crash occurs because the points schema does not contain the same data as the compiler's chosen schema (in this case an ICurvesSchema). Another crash was found due to the radius array not being properly initialized and left with a size of 0, when Cycles expects a full array. --- intern/cycles/scene/alembic.cpp | 35 ++++++++++++++++++++++++++++ intern/cycles/scene/alembic.h | 4 ++++ intern/cycles/scene/alembic_read.cpp | 2 +- intern/cycles/scene/alembic_read.h | 2 +- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/intern/cycles/scene/alembic.cpp b/intern/cycles/scene/alembic.cpp index 152a520ea61..b5c565dae92 100644 --- a/intern/cycles/scene/alembic.cpp +++ b/intern/cycles/scene/alembic.cpp @@ -611,6 +611,41 @@ void AlembicObject::load_data_in_cache(CachedData &cached_data, data_loaded = true; } +void AlembicObject::load_data_in_cache(CachedData &cached_data, + AlembicProcedural *proc, + const IPointsSchema &schema, + Progress &progress) +{ + /* Only load data for the original Geometry. */ + if (instance_of) { + return; + } + + cached_data.clear(); + + PointsSchemaData data; + data.positions = schema.getPositionsProperty(); + data.radiuses = schema.getWidthsParam(); + data.velocities = schema.getVelocitiesProperty(); + data.time_sampling = schema.getTimeSampling(); + data.num_samples = schema.getNumSamples(); + data.default_radius = proc->get_default_radius(); + data.radius_scale = get_radius_scale(); + + read_geometry_data(proc, cached_data, data, progress); + + if (progress.get_cancel()) { + return; + } + + /* Use the schema as the base compound property to also be able to look for top level properties. + */ + read_attributes(proc, cached_data, schema, {}, get_requested_attributes(), progress); + + cached_data.invalidate_last_loaded_time(true); + data_loaded = true; +} + void AlembicObject::setup_transform_cache(CachedData &cached_data, float scale) { cached_data.transforms.clear(); diff --git a/intern/cycles/scene/alembic.h b/intern/cycles/scene/alembic.h index adb85ac5a5b..dc508a8d0e6 100644 --- a/intern/cycles/scene/alembic.h +++ b/intern/cycles/scene/alembic.h @@ -398,6 +398,10 @@ class AlembicObject : public Node { AlembicProcedural *proc, const Alembic::AbcGeom::ICurvesSchema &schema, Progress &progress); + void load_data_in_cache(CachedData &cached_data, + AlembicProcedural *proc, + const Alembic::AbcGeom::IPointsSchema &schema, + Progress &progress); bool has_data_loaded() const; diff --git a/intern/cycles/scene/alembic_read.cpp b/intern/cycles/scene/alembic_read.cpp index e6f8ed1d4c6..66fc39b8af0 100644 --- a/intern/cycles/scene/alembic_read.cpp +++ b/intern/cycles/scene/alembic_read.cpp @@ -663,8 +663,8 @@ static void read_points_data(CachedData &cached_data, const PointsSchemaData &da if (do_radius) { radius = (*radiuses)[offset + i]; - a_radius.push_back_slow(radius); } + a_radius.push_back_slow(radius * data.radius_scale); a_shader.push_back_slow((int)0); } diff --git a/intern/cycles/scene/alembic_read.h b/intern/cycles/scene/alembic_read.h index cee93467b75..bb1b3de0640 100644 --- a/intern/cycles/scene/alembic_read.h +++ b/intern/cycles/scene/alembic_read.h @@ -110,7 +110,7 @@ void read_geometry_data(AlembicProcedural *proc, const CurvesSchemaData &data, Progress &progress); -/* Data of a ICurvesSchema that we need to read. */ +/* Data of a IPointsSchema that we need to read. */ struct PointsSchemaData { Alembic::AbcGeom::TimeSamplingPtr time_sampling; size_t num_samples;