Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/blender/curves.cpp')
-rw-r--r--intern/cycles/blender/curves.cpp165
1 files changed, 100 insertions, 65 deletions
diff --git a/intern/cycles/blender/curves.cpp b/intern/cycles/blender/curves.cpp
index b01cb85711a..6158ed78598 100644
--- a/intern/cycles/blender/curves.cpp
+++ b/intern/cycles/blender/curves.cpp
@@ -55,7 +55,7 @@ static bool ObtainCacheParticleData(
return false;
Transform tfm = get_transform(b_ob->matrix_world());
- Transform itfm = transform_quick_inverse(tfm);
+ Transform itfm = transform_inverse(tfm);
for (BL::Modifier &b_mod : b_ob->modifiers) {
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
@@ -613,8 +613,6 @@ void BlenderSync::sync_particle_hair(
}
}
-#ifdef WITH_NEW_CURVES_TYPE
-
static std::optional<BL::FloatAttribute> find_curves_radius_attribute(BL::Curves b_curves)
{
for (BL::Attribute &b_attribute : b_curves.attributes) {
@@ -632,6 +630,25 @@ static std::optional<BL::FloatAttribute> find_curves_radius_attribute(BL::Curves
return std::nullopt;
}
+static BL::FloatVectorAttribute find_curves_position_attribute(BL::Curves b_curves)
+{
+ for (BL::Attribute &b_attribute : b_curves.attributes) {
+ if (b_attribute.name() != "position") {
+ continue;
+ }
+ if (b_attribute.domain() != BL::Attribute::domain_POINT) {
+ continue;
+ }
+ if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT_VECTOR) {
+ continue;
+ }
+ return BL::FloatVectorAttribute{b_attribute};
+ }
+ /* The position attribute must exist. */
+ assert(false);
+ return BL::FloatVectorAttribute{b_curves.attributes[0]};
+}
+
template<typename TypeInCycles, typename GetValueAtIndex>
static void fill_generic_attribute(BL::Curves &b_curves,
TypeInCycles *data,
@@ -690,6 +707,21 @@ static void attr_create_motion(Hair *hair, BL::Attribute &b_attribute, const flo
}
}
+static void attr_create_uv(AttributeSet &attributes,
+ BL::Curves &b_curves,
+ BL::Attribute &b_attribute,
+ const ustring name)
+{
+ BL::Float2Attribute b_float2_attribute{b_attribute};
+ Attribute *attr = attributes.add(ATTR_STD_UV, name);
+
+ float2 *data = attr->data_float2();
+ fill_generic_attribute(b_curves, data, ATTR_ELEMENT_CURVE, [&](int i) {
+ BL::Array<float, 2> v = b_float2_attribute.data[i].vector();
+ return make_float2(v[0], v[1]);
+ });
+}
+
static void attr_create_generic(Scene *scene,
Hair *hair,
BL::Curves &b_curves,
@@ -698,12 +730,26 @@ static void attr_create_generic(Scene *scene,
{
AttributeSet &attributes = hair->attributes;
static const ustring u_velocity("velocity");
+ const bool need_uv = hair->need_attribute(scene, ATTR_STD_UV);
+ bool have_uv = false;
for (BL::Attribute &b_attribute : b_curves.attributes) {
const ustring name{b_attribute.name().c_str()};
+ const BL::Attribute::domain_enum b_domain = b_attribute.domain();
+ const BL::Attribute::data_type_enum b_data_type = b_attribute.data_type();
+
if (need_motion && name == u_velocity) {
attr_create_motion(hair, b_attribute, motion_scale);
+ continue;
+ }
+
+ /* Weak, use first float2 attribute as standard UV. */
+ if (need_uv && !have_uv && b_data_type == BL::Attribute::data_type_FLOAT2 &&
+ b_domain == BL::Attribute::domain_CURVE) {
+ attr_create_uv(attributes, b_curves, b_attribute, name);
+ have_uv = true;
+ continue;
}
if (!hair->need_attribute(scene, name)) {
@@ -713,9 +759,6 @@ static void attr_create_generic(Scene *scene,
continue;
}
- const BL::Attribute::domain_enum b_domain = b_attribute.domain();
- const BL::Attribute::data_type_enum b_data_type = b_attribute.data_type();
-
AttributeElement element = ATTR_ELEMENT_NONE;
switch (b_domain) {
case BL::Attribute::domain_POINT:
@@ -795,16 +838,16 @@ static void attr_create_generic(Scene *scene,
}
}
-static float4 hair_point_as_float4(BL::Curves b_curves,
+static float4 hair_point_as_float4(BL::FloatVectorAttribute b_attr_position,
std::optional<BL::FloatAttribute> b_attr_radius,
const int index)
{
- float4 mP = float3_to_float4(get_float3(b_curves.position_data[index].vector()));
- mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.0f;
+ float4 mP = float3_to_float4(get_float3(b_attr_position.data[index].vector()));
+ mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.005f;
return mP;
}
-static float4 interpolate_hair_points(BL::Curves b_curves,
+static float4 interpolate_hair_points(BL::FloatVectorAttribute b_attr_position,
std::optional<BL::FloatAttribute> b_attr_radius,
const int first_point_index,
const int num_points,
@@ -814,8 +857,8 @@ static float4 interpolate_hair_points(BL::Curves b_curves,
const int point_a = clamp((int)curve_t, 0, num_points - 1);
const int point_b = min(point_a + 1, num_points - 1);
const float t = curve_t - (float)point_a;
- return lerp(hair_point_as_float4(b_curves, b_attr_radius, first_point_index + point_a),
- hair_point_as_float4(b_curves, b_attr_radius, first_point_index + point_b),
+ return lerp(hair_point_as_float4(b_attr_position, b_attr_radius, first_point_index + point_a),
+ hair_point_as_float4(b_attr_position, b_attr_radius, first_point_index + point_b),
t);
}
@@ -827,78 +870,84 @@ static void export_hair_curves(Scene *scene,
{
/* TODO: optimize so we can straight memcpy arrays from Blender? */
+ const int num_keys = b_curves.points.length();
+ const int num_curves = b_curves.curves.length();
+
+ hair->resize_curves(num_curves, num_keys);
+
+ float3 *curve_keys = hair->get_curve_keys().data();
+ float *curve_radius = hair->get_curve_radius().data();
+ int *curve_first_key = hair->get_curve_first_key().data();
+ int *curve_shader = hair->get_curve_shader().data();
+
/* Add requested attributes. */
- Attribute *attr_intercept = NULL;
- Attribute *attr_length = NULL;
- Attribute *attr_random = NULL;
+ float *attr_intercept = NULL;
+ float *attr_length = NULL;
+ float *attr_random = NULL;
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
- attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
+ attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT)->data_float();
}
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) {
- attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
+ attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH)->data_float();
}
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
- attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
+ attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM)->data_float();
}
- /* Reserve memory. */
- const int num_keys = b_curves.points.length();
- const int num_curves = b_curves.curves.length();
-
- hair->reserve_curves(num_curves, num_keys);
-
+ BL::FloatVectorAttribute b_attr_position = find_curves_position_attribute(b_curves);
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
/* Export curves and points. */
- vector<float> points_length;
-
for (int i = 0; i < num_curves; i++) {
const int first_point_index = b_curves.curve_offset_data[i].value();
const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
float3 prev_co = zero_float3();
float length = 0.0f;
- if (attr_intercept) {
- points_length.clear();
- points_length.reserve(num_points);
- }
/* Position and radius. */
- for (int i = 0; i < num_points; i++) {
- const float3 co = get_float3(b_curves.position_data[first_point_index + i].vector());
- const float radius = b_attr_radius ? b_attr_radius->data[first_point_index + i].value() :
- 0.0f;
- hair->add_curve_key(co, radius);
-
- if (attr_intercept) {
- if (i > 0) {
+ for (int j = 0; j < num_points; j++) {
+ const int point_offset = first_point_index + j;
+ const float3 co = get_float3(b_attr_position.data[point_offset].vector());
+ const float radius = b_attr_radius ? b_attr_radius->data[point_offset].value() : 0.005f;
+
+ curve_keys[point_offset] = co;
+ curve_radius[point_offset] = radius;
+
+ if (attr_length || attr_intercept) {
+ if (j > 0) {
length += len(co - prev_co);
- points_length.push_back(length);
}
prev_co = co;
+
+ if (attr_intercept) {
+ attr_intercept[point_offset] = length;
+ }
}
}
/* Normalized 0..1 attribute along curve. */
- if (attr_intercept) {
- for (int i = 0; i < num_points; i++) {
- attr_intercept->add((length == 0.0f) ? 0.0f : points_length[i] / length);
+ if (attr_intercept && length > 0.0f) {
+ for (int j = 1; j < num_points; j++) {
+ const int point_offset = first_point_index + j;
+ attr_intercept[point_offset] /= length;
}
}
+ /* Curve length. */
if (attr_length) {
- attr_length->add(length);
+ attr_length[i] = length;
}
/* Random number per curve. */
if (attr_random != NULL) {
- attr_random->add(hash_uint2_to_float(i, 0));
+ attr_random[i] = hash_uint2_to_float(i, 0);
}
/* Curve. */
- const int shader_index = 0;
- hair->add_curve(first_point_index, shader_index);
+ curve_shader[i] = 0;
+ curve_first_key[i] = first_point_index;
}
attr_create_generic(scene, hair, b_curves, need_motion, motion_scale);
@@ -923,6 +972,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motio
int num_motion_keys = 0;
int curve_index = 0;
+ BL::FloatVectorAttribute b_attr_position = find_curves_position_attribute(b_curves);
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
for (int i = 0; i < num_curves; i++) {
@@ -938,7 +988,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motio
int point_index = first_point_index + i;
if (point_index < num_keys) {
- mP[num_motion_keys] = hair_point_as_float4(b_curves, b_attr_radius, point_index);
+ mP[num_motion_keys] = hair_point_as_float4(b_attr_position, b_attr_radius, point_index);
num_motion_keys++;
if (!have_motion) {
@@ -958,7 +1008,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motio
for (int i = 0; i < curve.num_keys; i++) {
const float step = i * step_size;
mP[num_motion_keys] = interpolate_hair_points(
- b_curves, b_attr_radius, first_point_index, num_points, step);
+ b_attr_position, b_attr_radius, first_point_index, num_points, step);
num_motion_keys++;
}
have_motion = true;
@@ -990,15 +1040,6 @@ void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int
export_hair_curves(scene, hair, b_curves, need_motion, motion_scale);
}
}
-#else
-void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step)
-{
- (void)hair;
- (void)b_ob_info;
- (void)motion;
- (void)motion_step;
-}
-#endif
void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Hair *hair)
{
@@ -1010,14 +1051,11 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, H
new_hair.set_used_shaders(used_shaders);
if (view_layer.use_hair) {
-#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves)) {
/* Hair object. */
sync_hair(&new_hair, b_ob_info, false);
}
- else
-#endif
- {
+ else {
/* Particle hair. */
bool need_undeformed = new_hair.need_attribute(scene, ATTR_STD_GENERATED);
BL::Mesh b_mesh = object_to_mesh(
@@ -1064,15 +1102,12 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
/* Export deformed coordinates. */
if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) {
-#ifdef WITH_NEW_CURVES_TYPE
if (b_ob_info.object_data.is_a(&RNA_Curves)) {
/* Hair object. */
sync_hair(hair, b_ob_info, true, motion_step);
return;
}
- else
-#endif
- {
+ else {
/* Particle hair. */
BL::Mesh b_mesh = object_to_mesh(
b_data, b_ob_info, b_depsgraph, false, Mesh::SUBDIVISION_NONE);