diff --git a/intern/cycles/blender/pointcloud.cpp b/intern/cycles/blender/pointcloud.cpp index cba0c7d23a0..920bcd01fae 100644 --- a/intern/cycles/blender/pointcloud.cpp +++ b/intern/cycles/blender/pointcloud.cpp @@ -15,17 +15,6 @@ CCL_NAMESPACE_BEGIN -template -static void fill_generic_attribute(BL::PointCloud &b_pointcloud, - TypeInCycles *data, - const GetValueAtIndex &get_value_at_index) -{ - const int num_points = b_pointcloud.points.length(); - for (int i = 0; i < num_points; i++) { - data[i] = get_value_at_index(i); - } -} - static void attr_create_motion(PointCloud *pointcloud, BL::Attribute &b_attribute, const float motion_scale) @@ -63,6 +52,11 @@ static void copy_attributes(PointCloud *pointcloud, const bool need_motion, const float motion_scale) { + const int num_points = b_pointcloud.points.length(); + if (num_points == 0) { + return; + } + AttributeSet &attributes = pointcloud->attributes; static const ustring u_velocity("velocity"); for (BL::Attribute &b_attribute : b_pointcloud.attributes) { @@ -81,56 +75,60 @@ static void copy_attributes(PointCloud *pointcloud, switch (b_data_type) { case BL::Attribute::data_type_FLOAT: { BL::FloatAttribute b_float_attribute{b_attribute}; + const float *src = static_cast(b_float_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); - fill_generic_attribute( - b_pointcloud, data, [&](int i) { return b_float_attribute.data[i].value(); }); + std::copy(src, src + num_points, data); break; } case BL::Attribute::data_type_BOOLEAN: { BL::BoolAttribute b_bool_attribute{b_attribute}; + const bool *src = static_cast(b_bool_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); - fill_generic_attribute( - b_pointcloud, data, [&](int i) { return (float)b_bool_attribute.data[i].value(); }); + for (int i = 0; i < num_points; i++) { + data[i] = float(src[i]); + } break; } case BL::Attribute::data_type_INT: { BL::IntAttribute b_int_attribute{b_attribute}; + const int *src = static_cast(b_int_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat, element); float *data = attr->data_float(); - fill_generic_attribute( - b_pointcloud, data, [&](int i) { return (float)b_int_attribute.data[i].value(); }); + for (int i = 0; i < num_points; i++) { + data[i] = float(src[i]); + } break; } case BL::Attribute::data_type_FLOAT_VECTOR: { BL::FloatVectorAttribute b_vector_attribute{b_attribute}; + const float(*src)[3] = static_cast(b_vector_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeVector, element); float3 *data = attr->data_float3(); - fill_generic_attribute(b_pointcloud, data, [&](int i) { - BL::Array v = b_vector_attribute.data[i].vector(); - return make_float3(v[0], v[1], v[2]); - }); + for (int i = 0; i < num_points; i++) { + data[i] = make_float3(src[i][0], src[i][1], src[i][2]); + } break; } case BL::Attribute::data_type_FLOAT_COLOR: { BL::FloatColorAttribute b_color_attribute{b_attribute}; + const float(*src)[4] = static_cast(b_color_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeRGBA, element); float4 *data = attr->data_float4(); - fill_generic_attribute(b_pointcloud, data, [&](int i) { - BL::Array v = b_color_attribute.data[i].color(); - return make_float4(v[0], v[1], v[2], v[3]); - }); + for (int i = 0; i < num_points; i++) { + data[i] = make_float4(src[i][0], src[i][1], src[i][2], src[i][3]); + } break; } case BL::Attribute::data_type_FLOAT2: { BL::Float2Attribute b_float2_attribute{b_attribute}; + const float(*src)[2] = static_cast(b_float2_attribute.data[0].ptr.data); Attribute *attr = attributes.add(name, TypeFloat2, element); float2 *data = attr->data_float2(); - fill_generic_attribute(b_pointcloud, data, [&](int i) { - BL::Array v = b_float2_attribute.data[i].vector(); - return make_float2(v[0], v[1]); - }); + for (int i = 0; i < num_points; i++) { + data[i] = make_float2(src[i][0], src[i][1]); + } break; } default: @@ -140,7 +138,7 @@ static void copy_attributes(PointCloud *pointcloud, } } -static std::optional find_radius_attribute(BL::PointCloud b_pointcloud) +static const float *find_radius_attribute(BL::PointCloud b_pointcloud) { for (BL::Attribute &b_attribute : b_pointcloud.attributes) { if (b_attribute.name() != "radius") { @@ -149,12 +147,16 @@ static std::optional find_radius_attribute(BL::PointCloud b_ if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT) { continue; } - return BL::FloatAttribute{b_attribute}; + BL::FloatAttribute b_float_attribute{b_attribute}; + if (b_float_attribute.data.length() == 0) { + return nullptr; + } + return static_cast(b_float_attribute.data[0].ptr.data); } - return std::nullopt; + return nullptr; } -static BL::FloatVectorAttribute find_position_attribute(BL::PointCloud b_pointcloud) +static const float (*find_position_attribute(BL::PointCloud b_pointcloud))[3] { for (BL::Attribute &b_attribute : b_pointcloud.attributes) { if (b_attribute.name() != "position") { @@ -163,11 +165,15 @@ static BL::FloatVectorAttribute find_position_attribute(BL::PointCloud b_pointcl if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT_VECTOR) { continue; } - return BL::FloatVectorAttribute{b_attribute}; + BL::FloatVectorAttribute b_float3_attribute{b_attribute}; + if (b_float3_attribute.data.length() == 0) { + return nullptr; + } + return static_cast(b_float3_attribute.data[0].ptr.data); } /* The position attribute must exist. */ assert(false); - return BL::FloatVectorAttribute{b_pointcloud.attributes[0]}; + return nullptr; } static void export_pointcloud(Scene *scene, @@ -176,34 +182,37 @@ static void export_pointcloud(Scene *scene, const bool need_motion, const float motion_scale) { - /* TODO: optimize so we can straight memcpy arrays from Blender? */ + const int num_points = b_pointcloud.points.length(); + pointcloud->resize(num_points); - /* Add requested attributes. */ - Attribute *attr_random = NULL; - if (pointcloud->need_attribute(scene, ATTR_STD_POINT_RANDOM)) { - attr_random = pointcloud->attributes.add(ATTR_STD_POINT_RANDOM); + const float(*b_attr_position)[3] = find_position_attribute(b_pointcloud); + float3 *points = pointcloud->get_points().data(); + std::cout << sizeof(*points) << '\n'; + + for (int i = 0; i < num_points; i++) { + points[i] = make_float3(b_attr_position[i][0], b_attr_position[i][1], b_attr_position[i][2]); } - /* Reserve memory. */ - const int num_points = b_pointcloud.points.length(); - pointcloud->reserve(num_points); + const float *b_attr_radius = find_radius_attribute(b_pointcloud); + float *radius = pointcloud->get_radius().data(); + if (b_attr_radius) { + std::copy(b_attr_radius, b_attr_radius + num_points, radius); + } + else { + std::fill(radius, radius + num_points, 0.01f); + } - BL::FloatVectorAttribute b_attr_position = find_position_attribute(b_pointcloud); - std::optional b_attr_radius = find_radius_attribute(b_pointcloud); + int *shader = pointcloud->get_shader().data(); + std::fill(shader, shader + num_points, 0); - /* Export points. */ - for (int i = 0; i < num_points; i++) { - const float3 co = get_float3(b_attr_position.data[i].vector()); - const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.01f; - pointcloud->add_point(co, radius); - - /* Random number per point. */ - if (attr_random != NULL) { - attr_random->add(hash_uint2_to_float(i, 0)); + if (pointcloud->need_attribute(scene, ATTR_STD_POINT_RANDOM)) { + Attribute *attr_random = pointcloud->attributes.add(ATTR_STD_POINT_RANDOM); + float *data = attr_random->data_float(); + for (int i = 0; i < num_points; i++) { + data[i] = hash_uint2_to_float(i, 0); } } - /* Export attributes */ copy_attributes(pointcloud, b_pointcloud, need_motion, motion_scale); } @@ -230,12 +239,13 @@ static void export_pointcloud_motion(PointCloud *pointcloud, const array &pointcloud_points = pointcloud->get_points(); const int b_points_num = b_pointcloud.points.length(); - BL::FloatVectorAttribute b_attr_position = find_position_attribute(b_pointcloud); - std::optional b_attr_radius = find_radius_attribute(b_pointcloud); + const float(*b_attr_position)[3] = find_position_attribute(b_pointcloud); + const float *b_attr_radius = find_radius_attribute(b_pointcloud); for (int i = 0; i < std::min(num_points, b_points_num); i++) { - const float3 P = get_float3(b_attr_position.data[i].vector()); - const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.01f; + const float3 P = make_float3( + b_attr_position[i][0], b_attr_position[i][1], b_attr_position[i][2]); + const float radius = b_attr_radius ? b_attr_radius[i] : 0.01f; mP[i] = make_float4(P.x, P.y, P.z, radius); have_motion = have_motion || (P != pointcloud_points[i]); }