[Bf-blender-cvs] [d4099465cdd] master: Cleanup: extract function to snap curves to surface

Jacques Lucke noreply at git.blender.org
Tue Jul 5 15:39:41 CEST 2022


Commit: d4099465cddc2d3ec3653220f6b775ba3ffb3ea0
Author: Jacques Lucke
Date:   Tue Jul 5 15:37:34 2022 +0200
Branches: master
https://developer.blender.org/rBd4099465cddc2d3ec3653220f6b775ba3ffb3ea0

Cleanup: extract function to snap curves to surface

This makes it possible to use this function without having
to call an operator. This is currently used by D14864.

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

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 aca074a1d61..d9f207103ae 100644
--- a/source/blender/editors/curves/intern/curves_ops.cc
+++ b/source/blender/editors/curves/intern/curves_ops.cc
@@ -517,152 +517,167 @@ static bool snap_curves_to_surface_poll(bContext *C)
   return true;
 }
 
+static void snap_curves_to_surface_exec_object(Object &curves_ob,
+                                               const Object &surface_ob,
+                                               const AttachMode attach_mode,
+                                               bool *r_invalid_uvs,
+                                               bool *r_missing_uvs)
+{
+  Curves &curves_id = *static_cast<Curves *>(curves_ob.data);
+  CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
+
+  Mesh &surface_mesh = *static_cast<Mesh *>(surface_ob.data);
+
+  MeshComponent surface_mesh_component;
+  surface_mesh_component.replace(&surface_mesh, GeometryOwnershipType::ReadOnly);
+
+  VArraySpan<float2> surface_uv_map;
+  if (curves_id.surface_uv_map != nullptr) {
+    surface_uv_map = surface_mesh_component
+                         .attribute_try_get_for_read(
+                             curves_id.surface_uv_map, ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2)
+                         .typed<float2>();
+  }
+
+  MutableSpan<float3> positions_cu = curves.positions_for_write();
+  MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write();
+
+  const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh),
+                                           BKE_mesh_runtime_looptri_len(&surface_mesh)};
+
+  const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob};
+
+  switch (attach_mode) {
+    case AttachMode::Nearest: {
+      BVHTreeFromMesh surface_bvh;
+      BKE_bvhtree_from_mesh_get(&surface_bvh, &surface_mesh, BVHTREE_FROM_LOOPTRI, 2);
+      BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh); });
+
+      threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) {
+        for (const int curve_i : curves_range) {
+          const IndexRange points = curves.points_for_curve(curve_i);
+          const int first_point_i = points.first();
+          const float3 old_first_point_pos_cu = positions_cu[first_point_i];
+          const float3 old_first_point_pos_su = transforms.curves_to_surface *
+                                                old_first_point_pos_cu;
+
+          BVHTreeNearest nearest;
+          nearest.index = -1;
+          nearest.dist_sq = FLT_MAX;
+          BLI_bvhtree_find_nearest(surface_bvh.tree,
+                                   old_first_point_pos_su,
+                                   &nearest,
+                                   surface_bvh.nearest_callback,
+                                   &surface_bvh);
+          const int looptri_index = nearest.index;
+          if (looptri_index == -1) {
+            continue;
+          }
+
+          const float3 new_first_point_pos_su = nearest.co;
+          const float3 new_first_point_pos_cu = transforms.surface_to_curves *
+                                                new_first_point_pos_su;
+          const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
+
+          for (float3 &pos_cu : positions_cu.slice(points)) {
+            pos_cu += pos_diff_cu;
+          }
+
+          if (!surface_uv_map.is_empty()) {
+            const MLoopTri &looptri = surface_looptris[looptri_index];
+            const int corner0 = looptri.tri[0];
+            const int corner1 = looptri.tri[1];
+            const int corner2 = looptri.tri[2];
+            const float2 &uv0 = surface_uv_map[corner0];
+            const float2 &uv1 = surface_uv_map[corner1];
+            const float2 &uv2 = surface_uv_map[corner2];
+            const float3 &p0_su = surface_mesh.mvert[surface_mesh.mloop[corner0].v].co;
+            const float3 &p1_su = surface_mesh.mvert[surface_mesh.mloop[corner1].v].co;
+            const float3 &p2_su = surface_mesh.mvert[surface_mesh.mloop[corner2].v].co;
+            float3 bary_coords;
+            interp_weights_tri_v3(bary_coords, p0_su, p1_su, p2_su, new_first_point_pos_su);
+            const float2 uv = attribute_math::mix3(bary_coords, uv0, uv1, uv2);
+            surface_uv_coords[curve_i] = uv;
+          }
+        }
+      });
+      break;
+    }
+    case AttachMode::Deform: {
+      if (surface_uv_map.is_empty()) {
+        *r_missing_uvs = true;
+        break;
+      }
+      using geometry::ReverseUVSampler;
+      ReverseUVSampler reverse_uv_sampler{surface_uv_map, surface_looptris};
+
+      threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) {
+        for (const int curve_i : curves_range) {
+          const IndexRange points = curves.points_for_curve(curve_i);
+          const int first_point_i = points.first();
+          const float3 old_first_point_pos_cu = positions_cu[first_point_i];
+
+          const float2 uv = surface_uv_coords[curve_i];
+          ReverseUVSampler::Result lookup_result = reverse_uv_sampler.sample(uv);
+          if (lookup_result.type != ReverseUVSampler::ResultType::Ok) {
+            *r_invalid_uvs = true;
+            continue;
+          }
+
+          const MLoopTri &looptri = *lookup_result.looptri;
+          const float3 &bary_coords = lookup_result.bary_weights;
+
+          const float3 &p0_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[0]].v].co;
+          const float3 &p1_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[1]].v].co;
+          const float3 &p2_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[2]].v].co;
+
+          float3 new_first_point_pos_su;
+          interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords);
+          const float3 new_first_point_pos_cu = transforms.surface_to_curves *
+                                                new_first_point_pos_su;
+
+          const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
+          for (float3 &pos_cu : positions_cu.slice(points)) {
+            pos_cu += pos_diff_cu;
+          }
+        }
+      });
+      break;
+    }
+  }
+
+  DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
+}
+
 static int snap_curves_to_surface_exec(bContext *C, wmOperator *op)
 {
   const AttachMode attach_mode = static_cast<AttachMode>(RNA_enum_get(op->ptr, "attach_mode"));
 
-  std::atomic<bool> found_invalid_uv = false;
+  bool found_invalid_uvs = false;
+  bool found_missing_uvs = false;
 
   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) {
+    if (curves_id.surface->type != OB_MESH) {
       continue;
     }
-    Mesh &surface_mesh = *static_cast<Mesh *>(surface_ob.data);
-
-    MeshComponent surface_mesh_component;
-    surface_mesh_component.replace(&surface_mesh, GeometryOwnershipType::ReadOnly);
-
-    VArraySpan<float2> surface_uv_map;
-    if (curves_id.surface_uv_map != nullptr) {
-      surface_uv_map = surface_mesh_component
-                           .attribute_try_get_for_read(
-                               curves_id.surface_uv_map, ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2)
-                           .typed<float2>();
-    }
-
-    MutableSpan<float3> positions_cu = curves.positions_for_write();
-    MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write();
-
-    const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh),
-                                             BKE_mesh_runtime_looptri_len(&surface_mesh)};
-
-    const bke::CurvesSurfaceTransforms transforms{*curves_ob, &surface_ob};
-
-    switch (attach_mode) {
-      case AttachMode::Nearest: {
-        BVHTreeFromMesh surface_bvh;
-        BKE_bvhtree_from_mesh_get(&surface_bvh, &surface_mesh, BVHTREE_FROM_LOOPTRI, 2);
-        BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh); });
-
-        threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) {
-          for (const int curve_i : curves_range) {
-            const IndexRange points = curves.points_for_curve(curve_i);
-            const int first_point_i = points.first();
-            const float3 old_first_point_pos_cu = positions_cu[first_point_i];
-            const float3 old_first_point_pos_su = transforms.curves_to_surface *
-                                                  old_first_point_pos_cu;
-
-            BVHTreeNearest nearest;
-            nearest.index = -1;
-            nearest.dist_sq = FLT_MAX;
-            BLI_bvhtree_find_nearest(surface_bvh.tree,
-                                     old_first_point_pos_su,
-                                     &nearest,
-                                     surface_bvh.nearest_callback,
-                                     &surface_bvh);
-            const int looptri_index = nearest.index;
-            if (looptri_index == -1) {
-              continue;
-            }
-
-            const float3 new_first_point_pos_su = nearest.co;
-            const float3 new_first_point_pos_cu = transforms.surface_to_curves *
-                                                  new_first_point_pos_su;
-            const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
-
-            for (float3 &pos_cu : positions_cu.slice(points)) {
-              pos_cu += pos_diff_cu;
-            }
-
-            if (!surface_uv_map.is_empty()) {
-              const MLoopTri &looptri = surface_looptris[looptri_index];
-              const int corner0 = looptri.tri[0];
-              const int corner1 = looptri.tri[1];
-              const int corner2 = looptri.tri[2];
-              const float2 &uv0 = surface_uv_map[corner0];
-              const float2 &

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list