[Bf-blender-cvs] [2d1be6bda7a] new-object-types: Merge branch 'master' into new-object-types
Brecht Van Lommel
noreply at git.blender.org
Wed Feb 26 12:40:53 CET 2020
Commit: 2d1be6bda7afab652e24907a683971f2a5011ffe
Author: Brecht Van Lommel
Date: Wed Feb 26 12:11:59 2020 +0100
Branches: new-object-types
https://developer.blender.org/rB2d1be6bda7afab652e24907a683971f2a5011ffe
Merge branch 'master' into new-object-types
===================================================================
===================================================================
diff --cc intern/cycles/blender/blender_curves.cpp
index 641f267e2f4,fe0f8f3b88a..a9ba277e8b8
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@@ -1154,186 -1154,10 +1154,189 @@@ void BlenderSync::sync_particle_hair
}
}
+static float4 hair_point_as_float4(BL::HairPoint b_point)
+{
+ float4 mP = float3_to_float4(get_float3(b_point.co()));
+ mP.w = b_point.radius();
+ return mP;
+}
+
+static float4 interpolate_hair_points(BL::Hair b_hair,
+ const int first_point_index,
+ const int num_points,
+ const float step)
+{
+ const float curve_t = step * (num_points - 1);
+ 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_hair.points[first_point_index + point_a]),
+ hair_point_as_float4(b_hair.points[first_point_index + point_b]),
+ t);
+}
+
+static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
+{
+ /* TODO: optimize so we can straight memcpy arrays from Blender? */
+
+ /* Add requested attributes. */
+ Attribute *attr_intercept = NULL;
+ Attribute *attr_random = NULL;
+
+ if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
+ attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
+ }
+ if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
+ attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
+ }
+
+ /* Reserve memory. */
+ const int num_keys = b_hair.points.length();
+ const int num_curves = b_hair.curves.length();
+
+ if (num_curves > 0) {
+ VLOG(1) << "Exporting curve segments for hair " << hair->name;
+ }
+
+ hair->reserve_curves(num_curves, num_keys);
+
+ /* Export curves and points. */
+ vector<float> points_length;
+
+ BL::Hair::curves_iterator b_curve_iter;
+ for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
+ BL::HairCurve b_curve = *b_curve_iter;
+ const int first_point_index = b_curve.first_point_index();
+ const int num_points = b_curve.num_points();
+
+ float3 prev_co = make_float3(0.0f, 0.0f, 0.0f);
+ 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++) {
+ BL::HairPoint b_point = b_hair.points[first_point_index + i];
+
+ const float3 co = get_float3(b_point.co());
+ const float radius = b_point.radius();
+ hair->add_curve_key(co, radius);
+
+ if (attr_intercept) {
+ if (i > 0) {
+ length += len(co - prev_co);
+ points_length.push_back(length);
+ }
+ prev_co = co;
+ }
+ }
+
+ /* 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);
+ }
+ }
+
+ /* Random number per curve. */
+ if (attr_random != NULL) {
+ attr_random->add(hash_uint2_to_float(b_curve.index(), 0));
+ }
+
+ /* Curve. */
+ const int shader_index = 0;
+ hair->add_curve(first_point_index, shader_index);
+ }
+}
+
+static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_step)
+{
+ VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
+ << motion_step;
+
+ /* Find or add attribute. */
+ Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
+ bool new_attribute = false;
+
+ if (!attr_mP) {
+ VLOG(1) << "Creating new motion vertex position attribute";
+ attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
+ new_attribute = true;
+ }
+
+ /* Export motion keys. */
+ const int num_keys = hair->curve_keys.size();
+ float4 *mP = attr_mP->data_float4() + motion_step * num_keys;
+ bool have_motion = false;
+ int num_motion_keys = 0;
+ int curve_index = 0;
+
+ BL::Hair::curves_iterator b_curve_iter;
+ for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
+ BL::HairCurve b_curve = *b_curve_iter;
+ const int first_point_index = b_curve.first_point_index();
+ const int num_points = b_curve.num_points();
+
+ Hair::Curve curve = hair->get_curve(curve_index);
+ curve_index++;
+
+ if (num_points == curve.num_keys) {
+ /* Number of keys matches. */
+ for (int i = 0; i < num_points; i++) {
+ int point_index = first_point_index + i;
+
+ if (point_index < num_keys) {
+ mP[num_motion_keys] = hair_point_as_float4(b_hair.points[point_index]);
+ num_motion_keys++;
+
+ if (!have_motion) {
+ /* TODO: use epsilon for comparison? Was needed for particles due to
+ * transform, but ideally should not happen anymore. */
+ float4 curve_key = float3_to_float4(hair->curve_keys[i]);
+ curve_key.w = hair->curve_radius[i];
+ have_motion = !(mP[i] == curve_key);
+ }
+ }
+ }
+ }
+ else {
+ /* Number of keys has changed. Generate an interpolated version
+ * to preserve motion blur. */
+ const float step_size = curve.num_keys > 1 ? 1.0f / (curve.num_keys - 1) : 0.0f;
+ for (int i = 0; i < curve.num_keys; i++) {
+ const float step = i * step_size;
+ mP[num_motion_keys] = interpolate_hair_points(b_hair, first_point_index, num_points, step);
+ num_motion_keys++;
+ }
+ have_motion = true;
+ }
+ }
+
+ /* In case of new attribute, we verify if there really was any motion. */
+ if (new_attribute) {
+ export_hair_motion_validate_attribute(hair, motion_step, num_motion_keys, have_motion);
+ }
+}
+
+/* Hair object. */
+void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step)
+{
+ /* Convert Blender hair to Cycles curves. */
+ BL::Hair b_hair(b_ob.data());
+ if (motion) {
+ export_hair_curves_motion(hair, b_hair, motion_step);
+ }
+ else {
+ export_hair_curves(scene, hair, b_hair);
+ }
+}
+
- void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Geometry *geom)
+ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph,
+ BL::Object b_ob,
+ Geometry *geom,
+ const vector<Shader *> &used_shaders)
{
Hair *hair = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom) : NULL;
Mesh *mesh = (geom->type == Geometry::MESH) ? static_cast<Mesh *>(geom) : NULL;
@@@ -1351,22 -1175,18 +1354,25 @@@
oldtriangles.steal_data(mesh->triangles);
}
+ geom->clear();
+ geom->used_shaders = used_shaders;
+
if (view_layer.use_hair && scene->curve_system_manager->use_curves) {
- /* Particle hair. */
- bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED);
- BL::Mesh b_mesh = object_to_mesh(
- b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
-
- if (b_mesh) {
- sync_particle_hair(geom, b_mesh, b_ob, false);
- free_object_to_mesh(b_data, b_ob, b_mesh);
+ if (b_ob.type() == BL::Object::type_HAIR) {
+ /* Hair object. */
+ sync_hair(hair, b_ob, false);
+ assert(mesh == NULL);
+ }
+ else {
+ /* Particle hair. */
+ bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED);
+ BL::Mesh b_mesh = object_to_mesh(
+ b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
+
+ if (b_mesh) {
+ sync_particle_hair(geom, b_mesh, b_ob, false);
+ free_object_to_mesh(b_data, b_ob, b_mesh);
+ }
}
}
diff --cc intern/cycles/blender/blender_geometry.cpp
index 24d56c5a56c,304b3d18e27..03d1f220dca
--- a/intern/cycles/blender/blender_geometry.cpp
+++ b/intern/cycles/blender/blender_geometry.cpp
@@@ -118,16 -117,14 +118,14 @@@ Geometry *BlenderSync::sync_geometry(BL
geometry_synced.insert(geom);
- geom->clear();
- geom->used_shaders = used_shaders;
geom->name = ustring(b_ob_data.name().c_str());
- if (use_particle_hair) {
+ if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) {
- sync_hair(b_depsgraph, b_ob, geom);
+ sync_hair(b_depsgraph, b_ob, geom, used_shaders);
}
- else if (object_fluid_gas_domain_find(b_ob)) {
+ else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
Mesh *mesh = static_cast<Mesh *>(geom);
- sync_volume(b_ob, mesh);
+ sync_volume(b_ob, mesh, used_shaders);
}
else {
Mesh *mesh = static_cast<Mesh *>(geom);
diff --cc intern/cycles/blender/blender_volume.cpp
index 1f167217063,ae70e60d60e..6ecc195c98a
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@@ -117,16 -84,11 +117,19 @@@ void BlenderSync::sync_volume(BL::Objec
{
bool old_has_voxel_attributes = mesh->has_voxel_attributes();
+ mesh->clear();
+ mesh->used_shaders = used_shaders;
+
- /* Smoke domain. */
- sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
+ /* TODO: support disabling volumes in view layer. */
+ if (b_ob.type() == BL::Object::type_VOLUME) {
+ /* Volume object. Create only attributes, bounding mesh will then
+ * be automatically generated later. */
+ sync_volume_object(b_data, b_ob, scene, mesh);
+ }
+ else {
+ /* Smoke domain. */
+ sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
+ }
/* Tag update. */
bool rebuild = (old_has_voxel_attributes != mesh->has_voxel_attributes());
diff --cc source/blender/alembic/intern/abc_writer_curves.cc
index 00000000000,bb9109dc025..3ab9b365a72
mode 000000,100644..100644
--- a/source/blender/alembic/intern/abc_writer_curves.cc
+++ b/source/blende
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list