[Bf-blender-cvs] [ef631e2cb38] temp-vert-normals-cleanup: Merge branch 'master' into temp-vert-normals-cleanup

Hans Goudey noreply at git.blender.org
Tue Oct 5 19:45:43 CEST 2021


Commit: ef631e2cb388a6e1e7ce814f078ddd3649eb19e9
Author: Hans Goudey
Date:   Tue Oct 5 12:23:33 2021 -0500
Branches: temp-vert-normals-cleanup
https://developer.blender.org/rBef631e2cb388a6e1e7ce814f078ddd3649eb19e9

Merge branch 'master' into temp-vert-normals-cleanup

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



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

diff --cc source/blender/nodes/geometry/nodes/node_geo_input_normal.cc
index bcf39e646b7,5a2495afb9e..14e446b1114
--- a/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc
@@@ -28,19 -28,70 +28,19 @@@ namespace blender::nodes 
  
  static void geo_node_input_normal_declare(NodeDeclarationBuilder &b)
  {
-   b.add_output<decl::Vector>("Normal");
+   b.add_output<decl::Vector>("Normal").field_source();
  }
  
 -static GVArrayPtr mesh_face_normals(const Mesh &mesh,
 -                                    const Span<MVert> verts,
 -                                    const Span<MPoly> polys,
 -                                    const Span<MLoop> loops,
 -                                    const IndexMask mask)
 +static GVArrayPtr mesh_face_normals_gvarray(const Mesh &mesh)
  {
 -  /* Use existing normals to avoid unnecessarily recalculating them, if possible. */
 -  if (!(mesh.runtime.cd_dirty_poly & CD_MASK_NORMAL) &&
 -      CustomData_has_layer(&mesh.pdata, CD_NORMAL)) {
 -    const void *data = CustomData_get_layer(&mesh.pdata, CD_NORMAL);
 -
 -    return std::make_unique<fn::GVArray_For_Span<float3>>(
 -        Span<float3>((const float3 *)data, polys.size()));
 -  }
 -
 -  auto normal_fn = [verts, polys, loops](const int i) -> float3 {
 -    float3 normal;
 -    const MPoly &poly = polys[i];
 -    BKE_mesh_calc_poly_normal(&poly, &loops[poly.loopstart], verts.data(), normal);
 -    return normal;
 -  };
 -
 -  return std::make_unique<
 -      fn::GVArray_For_EmbeddedVArray<float3, VArray_For_Func<float3, decltype(normal_fn)>>>(
 -      mask.min_array_size(), mask.min_array_size(), normal_fn);
 +  Span<float3> face_normals{(float3 *)BKE_mesh_ensure_face_normals(&mesh), mesh.totpoly};
 +  return std::make_unique<fn::GVArray_For_GSpan>(face_normals);
  }
  
 -static GVArrayPtr mesh_vertex_normals(const Mesh &mesh,
 -                                      const Span<MVert> verts,
 -                                      const Span<MPoly> polys,
 -                                      const Span<MLoop> loops,
 -                                      const IndexMask mask)
 +static GVArrayPtr mesh_vert_normals_gvarray(const Mesh &mesh)
  {
 -  /* Use existing normals to avoid unnecessarily recalculating them, if possible. */
 -  if (!(mesh.runtime.cd_dirty_vert & CD_MASK_NORMAL) &&
 -      CustomData_has_layer(&mesh.vdata, CD_NORMAL)) {
 -    const void *data = CustomData_get_layer(&mesh.pdata, CD_NORMAL);
 -
 -    return std::make_unique<fn::GVArray_For_Span<float3>>(
 -        Span<float3>((const float3 *)data, mesh.totvert));
 -  }
 -
 -  /* If the normals are dirty, they must be recalculated for the output of this node's field
 -   * source. Ideally vertex normals could be calculated lazily on a const mesh, but that's not
 -   * possible at the moment, so we take ownership of the results. Sadly we must also create a copy
 -   * of MVert to use the mesh normals API. This can be improved by adding mutex-protected lazy
 -   * calculation of normals on meshes.
 -   *
 -   * Use mask.min_array_size() to avoid calculating a final chunk of data if possible. */
 -  Array<MVert> temp_verts(verts);
 -  Array<float3> normals(verts.size()); /* Use full size for accumulation from faces. */
 -  BKE_mesh_calc_normals_poly_and_vertex(temp_verts.data(),
 -                                        mask.min_array_size(),
 -                                        loops.data(),
 -                                        loops.size(),
 -                                        polys.data(),
 -                                        polys.size(),
 -                                        nullptr,
 -                                        (float(*)[3])normals.data());
 -
 -  return std::make_unique<fn::GVArray_For_ArrayContainer<Array<float3>>>(std::move(normals));
 +  Span<float3> vert_normals{(float3 *)BKE_mesh_ensure_vertex_normals(&mesh), mesh.totvert};
 +  return std::make_unique<fn::GVArray_For_GSpan>(vert_normals);
  }
  
  static const GVArray *construct_mesh_normals_gvarray(const MeshComponent &mesh_component,
diff --cc source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
index 72f130d7fdb,059e6e8680c..61501be7aac
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
@@@ -527,9 -643,59 +643,58 @@@ static void calculate_cone_uvs(Mesh *me
      }
    }
  
+   uv_attribute.save();
+ }
+ 
+ static Mesh *create_vertex_mesh()
+ {
+   /* Returns a mesh with a single vertex at the origin. */
+   Mesh *mesh = BKE_mesh_new_nomain(1, 0, 0, 0, 0);
+   copy_v3_fl3(mesh->mvert[0].co, 0.0f, 0.0f, 0.0f);
 -  const short up[3] = {0, 0, SHRT_MAX};
 -  copy_v3_v3_short(mesh->mvert[0].no, up);
 +  BKE_mesh_normals_tag_dirty(mesh);
+   return mesh;
+ }
  
-   calculate_uvs(mesh, top_is_point, bottom_is_point, verts_num, fill_type);
+ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
+                                    const float radius_bottom,
+                                    const float depth,
+                                    const int circle_segments,
+                                    const int side_segments,
+                                    const int fill_segments,
+                                    const GeometryNodeMeshCircleFillType fill_type)
+ {
+   const ConeConfig config(
+       radius_top, radius_bottom, depth, circle_segments, side_segments, fill_segments, fill_type);
+ 
+   /* Handle the case of a line / single point before everything else to avoid
+    * the need to check for it later. */
+   if (config.top_is_point && config.bottom_is_point) {
+     if (config.height == 0.0f) {
+       return create_vertex_mesh();
+     }
+     const float z_delta = -2.0f * config.height / static_cast<float>(config.side_segments);
+     const float3 start(0.0f, 0.0f, config.height);
+     const float3 delta(0.0f, 0.0f, z_delta);
+     return create_line_mesh(start, delta, config.tot_verts);
+   }
+ 
+   Mesh *mesh = BKE_mesh_new_nomain(
+       config.tot_verts, config.tot_edges, 0, config.get_tot_corners(), config.get_tot_faces());
+   BKE_id_material_eval_ensure_default_slot(&mesh->id);
+ 
+   MutableSpan<MVert> verts{mesh->mvert, mesh->totvert};
+   MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop};
+   MutableSpan<MEdge> edges{mesh->medge, mesh->totedge};
+   MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly};
+ 
+   calculate_cone_vertices(verts, config);
+   calculate_cone_edges(edges, config);
+   calculate_cone_faces(loops, polys, config);
+   calculate_cone_uvs(mesh, config);
+ 
+   BKE_mesh_normals_tag_dirty(mesh);
+ 
+   calculate_cone_uvs(mesh, config);
  
    return mesh;
  }



More information about the Bf-blender-cvs mailing list