[Bf-blender-cvs] [c9574412c7e] master: Curves: fix some issues with operator to convert to particle system

Jacques Lucke noreply at git.blender.org
Thu Apr 14 12:26:05 CEST 2022


Commit: c9574412c7e3eeb83eccf4819567e88e42747b28
Author: Jacques Lucke
Date:   Thu Apr 14 12:25:54 2022 +0200
Branches: master
https://developer.blender.org/rBc9574412c7e3eeb83eccf4819567e88e42747b28

Curves: fix some issues with operator to convert to particle system

Ref T97171.

Differential Revision: https://developer.blender.org/D14637

===================================================================

M	source/blender/editors/curves/intern/curves_ops.cc

===================================================================

diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc
index 9823a1f18ce..7d07c211542 100644
--- a/source/blender/editors/curves/intern/curves_ops.cc
+++ b/source/blender/editors/curves/intern/curves_ops.cc
@@ -121,147 +121,171 @@ static float4 compute_mface_weights_for_position(const Mesh &mesh,
   return mface_weights;
 }
 
-static int curves_convert_to_particle_system_exec(bContext *C, wmOperator *UNUSED(op))
+static void try_convert_single_object(Object &curves_ob,
+                                      Main &bmain,
+                                      Scene &scene,
+                                      bool *r_could_not_convert_some_curves)
 {
-  Main *bmain = CTX_data_main(C);
-  Scene *scene = CTX_data_scene(C);
-
-  CTX_DATA_BEGIN (C, Object *, curves_ob, selected_objects) {
-    if (curves_ob->type != OB_CURVES) {
-      continue;
-    }
-    Curves &curves_id = *static_cast<Curves *>(curves_ob->data);
-    CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
-    if (curves_id.surface == nullptr) {
-      continue;
-    }
-    Object &surface_ob = *curves_id.surface;
-    if (surface_ob.type != OB_MESH) {
-      continue;
+  if (curves_ob.type != OB_CURVES) {
+    return;
+  }
+  Curves &curves_id = *static_cast<Curves *>(curves_ob.data);
+  CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
+  if (curves_id.surface == nullptr) {
+    return;
+  }
+  Object &surface_ob = *curves_id.surface;
+  if (surface_ob.type != OB_MESH) {
+    return;
+  }
+  Mesh &surface_me = *static_cast<Mesh *>(surface_ob.data);
+
+  const Span<float3> positions_cu = curves.positions();
+  const VArray<int> looptri_indices = curves.surface_triangle_indices();
+  const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&surface_me),
+                                BKE_mesh_runtime_looptri_len(&surface_me)};
+
+  /* Find indices of curves that can be transferred to the old hair system. */
+  Vector<int> curves_indices_to_transfer;
+  for (const int curve_i : curves.curves_range()) {
+    const int looptri_i = looptri_indices[curve_i];
+    if (looptri_i >= 0 && looptri_i < looptris.size()) {
+      curves_indices_to_transfer.append(curve_i);
     }
-    Mesh &surface_me = *static_cast<Mesh *>(surface_ob.data);
-
-    const Span<float3> positions_cu = curves.positions();
-    const VArray<int> looptri_indices = curves.surface_triangle_indices();
-    const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&surface_me),
-                                  BKE_mesh_runtime_looptri_len(&surface_me)};
-
-    /* Find indices of curves that can be transferred to the old hair system. */
-    Vector<int> curves_indices_to_transfer;
-    for (const int curve_i : curves.curves_range()) {
-      const int looptri_i = looptri_indices[curve_i];
-      if (looptri_i >= 0 && looptri_i < looptris.size()) {
-        curves_indices_to_transfer.append(curve_i);
-      }
+    else {
+      *r_could_not_convert_some_curves = true;
     }
+  }
 
-    const int hairs_num = curves_indices_to_transfer.size();
-    if (hairs_num == 0) {
-      continue;
-    }
+  const int hairs_num = curves_indices_to_transfer.size();
+  if (hairs_num == 0) {
+    return;
+  }
 
-    ParticleSystem *particle_system = nullptr;
-    LISTBASE_FOREACH (ParticleSystem *, psys, &surface_ob.particlesystem) {
-      if (STREQ(psys->name, curves_ob->id.name + 2)) {
-        particle_system = psys;
-        break;
-      }
-    }
-    if (particle_system == nullptr) {
-      ParticleSystemModifierData &psmd = *reinterpret_cast<ParticleSystemModifierData *>(
-          object_add_particle_system(bmain, scene, &surface_ob, curves_ob->id.name + 2));
-      particle_system = psmd.psys;
+  ParticleSystem *particle_system = nullptr;
+  LISTBASE_FOREACH (ParticleSystem *, psys, &surface_ob.particlesystem) {
+    if (STREQ(psys->name, curves_ob.id.name + 2)) {
+      particle_system = psys;
+      break;
     }
+  }
+  if (particle_system == nullptr) {
+    ParticleSystemModifierData &psmd = *reinterpret_cast<ParticleSystemModifierData *>(
+        object_add_particle_system(&bmain, &scene, &surface_ob, curves_ob.id.name + 2));
+    particle_system = psmd.psys;
+    particle_system->part->draw_step = 3;
+  }
+
+  ParticleSettings &settings = *particle_system->part;
 
-    ParticleSettings &settings = *particle_system->part;
+  psys_free_particles(particle_system);
+  settings.type = PART_HAIR;
+  settings.totpart = 0;
+  psys_changed_type(&surface_ob, particle_system);
 
-    psys_free_particles(particle_system);
-    settings.type = PART_HAIR;
-    settings.totpart = 0;
-    psys_changed_type(&surface_ob, particle_system);
+  MutableSpan<ParticleData> particles{
+      static_cast<ParticleData *>(MEM_calloc_arrayN(hairs_num, sizeof(ParticleData), __func__)),
+      hairs_num};
 
-    MutableSpan<ParticleData> particles{
-        static_cast<ParticleData *>(MEM_calloc_arrayN(hairs_num, sizeof(ParticleData), __func__)),
-        hairs_num};
+  /* The old hair system still uses #MFace, so make sure those are available on the mesh. */
+  BKE_mesh_tessface_calc(&surface_me);
 
-    /* The old hair system still uses #MFace, so make sure those are available on the mesh. */
-    BKE_mesh_tessface_calc(&surface_me);
+  /* Prepare utility data structure to map hair roots to mfaces. */
+  const Span<int> mface_to_poly_map{
+      static_cast<int *>(CustomData_get_layer(&surface_me.fdata, CD_ORIGINDEX)),
+      surface_me.totface};
+  Array<Vector<int>> poly_to_mface_map(surface_me.totpoly);
+  for (const int mface_i : mface_to_poly_map.index_range()) {
+    const int poly_i = mface_to_poly_map[mface_i];
+    poly_to_mface_map[poly_i].append(mface_i);
+  }
 
-    /* Prepare utility data structure to map hair roots to mfaces. */
-    const Span<int> mface_to_poly_map{
-        static_cast<int *>(CustomData_get_layer(&surface_me.fdata, CD_ORIGINDEX)),
-        surface_me.totface};
-    Array<Vector<int>> poly_to_mface_map(surface_me.totpoly);
-    for (const int mface_i : mface_to_poly_map.index_range()) {
-      const int poly_i = mface_to_poly_map[mface_i];
-      poly_to_mface_map[poly_i].append(mface_i);
+  /* Prepare transformation matrices. */
+  const float4x4 curves_to_world_mat = curves_ob.obmat;
+  const float4x4 surface_to_world_mat = surface_ob.obmat;
+  const float4x4 world_to_surface_mat = surface_to_world_mat.inverted();
+  const float4x4 curves_to_surface_mat = world_to_surface_mat * curves_to_world_mat;
+
+  for (const int new_hair_i : curves_indices_to_transfer.index_range()) {
+    const int curve_i = curves_indices_to_transfer[new_hair_i];
+    const IndexRange points = curves.points_for_curve(curve_i);
+
+    const int looptri_i = looptri_indices[curve_i];
+    const MLoopTri &looptri = looptris[looptri_i];
+    const int poly_i = looptri.poly;
+
+    const float3 &root_pos_cu = positions_cu[points.first()];
+    const float3 root_pos_su = curves_to_surface_mat * root_pos_cu;
+
+    const int mface_i = find_mface_for_root_position(
+        surface_me, poly_to_mface_map[poly_i], root_pos_su);
+    const MFace &mface = surface_me.mface[mface_i];
+
+    const float4 mface_weights = compute_mface_weights_for_position(
+        surface_me, mface, root_pos_su);
+
+    ParticleData &particle = particles[new_hair_i];
+    const int num_keys = points.size();
+    MutableSpan<HairKey> hair_keys{
+        static_cast<HairKey *>(MEM_calloc_arrayN(num_keys, sizeof(HairKey), __func__)), num_keys};
+
+    particle.hair = hair_keys.data();
+    particle.totkey = hair_keys.size();
+    copy_v4_v4(particle.fuv, mface_weights);
+    particle.num = mface_i;
+    /* Not sure if there is a better way to initialize this. */
+    particle.num_dmcache = DMCACHE_NOTFOUND;
+
+    float4x4 hair_to_surface_mat;
+    psys_mat_hair_to_object(
+        &surface_ob, &surface_me, PART_FROM_FACE, &particle, hair_to_surface_mat.values);
+    /* In theory, #psys_mat_hair_to_object should handle this, but it doesn't right now. */
+    copy_v3_v3(hair_to_surface_mat.values[3], root_pos_su);
+    const float4x4 surface_to_hair_mat = hair_to_surface_mat.inverted();
+
+    for (const int key_i : hair_keys.index_range()) {
+      const float3 &key_pos_cu = positions_cu[points[key_i]];
+      const float3 key_pos_su = curves_to_surface_mat * key_pos_cu;
+      const float3 key_pos_ha = surface_to_hair_mat * key_pos_su;
+
+      HairKey &key = hair_keys[key_i];
+      copy_v3_v3(key.co, key_pos_ha);
+      key.time = 100.0f * key_i / (float)(hair_keys.size() - 1);
     }
+  }
 
-    /* Prepare transformation matrices. */
-    const float4x4 curves_to_world_mat = curves_ob->obmat;
-    const float4x4 surface_to_world_mat = surface_ob.obmat;
-    const float4x4 world_to_surface_mat = surface_to_world_mat.inverted();
-    const float4x4 curves_to_surface_mat = world_to_surface_mat * curves_to_world_mat;
+  particle_system->particles = particles.data();
+  particle_system->totpart = particles.size();
+  particle_system->flag |= PSYS_EDITED;
+  particle_system->recalc |= ID_RECALC_PSYS_RESET;
 
-    for (const int new_hair_i : curves_indices_to_transfer.index_range()) {
-      const int curve_i = curves_indices_to_transfer[new_hair_i];
-      const IndexRange points = curves.points_for_curve(curve_i);
-
-      const int looptri_i = looptri_indices[curve_i];
-      const MLoopTri &looptri = looptris[looptri_i];
-      const int poly_i = looptri.poly;
-
-      const float3 &root_pos_cu = positions_cu[points.first()];
-      const float3 root_pos_su = curves_to_surface_mat * root_pos_cu;
-
-      const int mface_i = find_mface_for_root_position(
-          surface_me, poly_to_mface_map[poly_i], root_pos_su);
-      const MFace &mface = surface_me.mface[mface_i];
-
-      const float4 mface_weights = compute_mface_weights_for_position(
-          surface_me, mface, root_pos_su);
-
-      ParticleData &particle = particles[new_hair_i];
-      const int num_keys = points.size();
-      MutableSpan<HairKey> hair_keys{
-          static_cast<HairKey *>(MEM_calloc_arrayN(num_keys, sizeof(HairKey), __func__)),
-          num_keys};
-
-      particle.hair = hair_keys.

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list