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:
authorHans Goudey <h.goudey@me.com>2021-03-16 00:04:51 +0300
committerHans Goudey <h.goudey@me.com>2021-03-16 00:04:51 +0300
commit1cc876f325a1ba70f85081128a9096c0f69929b4 (patch)
tree876b57b649fa23321531e6853a00294662bd39c2
parentf73bef57d9f12844ac455469a638b4fde22f4260 (diff)
Add UV attribute creation to cone node
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc94
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc17
3 files changed, 100 insertions, 13 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
index 756c419c8a6..1fb5144b981 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
@@ -188,6 +188,94 @@ static int face_total(const GeometryNodeMeshCircleFillType fill_type,
return face_total;
}
+static void calculate_uvs(Mesh *mesh,
+ const bool use_top,
+ const bool use_bottom,
+ const int verts_num,
+ const GeometryNodeMeshCircleFillType fill_type)
+{
+ MeshComponent mesh_component;
+ mesh_component.replace(mesh, GeometryOwnershipType::Editable);
+ OutputAttributePtr uv_attribute = mesh_component.attribute_try_get_for_output(
+ "uv", ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2, nullptr);
+ MutableSpan<float2> uvs = uv_attribute->get_span_for_write_only<float2>();
+
+ Array<float2> circle(verts_num);
+ float angle = 0.0f;
+ const float angle_delta = 2.0f * M_PI / static_cast<float>(verts_num);
+ for (const int i : IndexRange(verts_num)) {
+ circle[i].x = std::cos(angle) * 0.225f + 0.25f;
+ circle[i].y = std::sin(angle) * 0.225f + 0.25f;
+ angle += angle_delta;
+ }
+
+ int loop_index = 0;
+ if (use_top) {
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+ for (const int i : IndexRange(verts_num)) {
+ uvs[loop_index++] = circle[i];
+ }
+ }
+ else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ for (const int i : IndexRange(verts_num)) {
+ uvs[loop_index++] = circle[i];
+ uvs[loop_index++] = circle[(i + 1) % verts_num];
+ uvs[loop_index++] = float2(0.25f, 0.25f);
+ }
+ }
+ }
+
+ /* Create side corners and faces. */
+ if (use_top && use_bottom) {
+ const float bottom = (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE) ? 0.0f : 0.5f;
+ /* Quads connect the top and bottom. */
+ for (const int i : IndexRange(verts_num)) {
+ const float vert = static_cast<float>(i);
+ uvs[loop_index++] = float2(vert / verts_num, bottom);
+ uvs[loop_index++] = float2((vert + 1.0f) / verts_num, bottom);
+ uvs[loop_index++] = float2((vert + 1.0f) / verts_num, 1.0f);
+ uvs[loop_index++] = float2(vert / verts_num, 1.0f);
+ }
+ }
+ else {
+ /* Triangles connect the top and bottom section. */
+ if (use_top) {
+ for (const int i : IndexRange(verts_num)) {
+ uvs[loop_index++] = circle[i] + float2(0.5f, 0.0f);
+ uvs[loop_index++] = float2(0.75f, 0.25f);
+ uvs[loop_index++] = circle[(i + 1) % verts_num] + float2(0.5f, 0.0f);
+ }
+ }
+ else {
+ BLI_assert(use_bottom);
+ for (const int i : IndexRange(verts_num)) {
+ uvs[loop_index++] = circle[i];
+ uvs[loop_index++] = circle[(i + 1) % verts_num];
+ uvs[loop_index++] = float2(0.25f, 0.25f);
+ }
+ }
+ }
+
+ /* Create bottom corners and faces. */
+ if (use_bottom) {
+ if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_NGON) {
+ for (const int i : IndexRange(verts_num)) {
+ /* Go backwards because of reversed face normal. */
+ uvs[loop_index++] = circle[verts_num - 1 - i] + float2(0.5f, 0.0f);
+ }
+ }
+ else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) {
+ for (const int i : IndexRange(verts_num)) {
+ uvs[loop_index++] = circle[i] + float2(0.5f, 0.0f);
+ uvs[loop_index++] = float2(0.75f, 0.25f);
+ uvs[loop_index++] = circle[(i + 1) % verts_num] + float2(0.5f, 0.0f);
+ }
+ }
+ }
+
+ uv_attribute.apply_span_and_save();
+}
+
Mesh *create_cylinder_or_cone_mesh(const float radius_top,
const float radius_bottom,
const float depth,
@@ -441,6 +529,10 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
BKE_mesh_calc_normals(mesh);
+ calculate_uvs(mesh, use_top, use_bottom, verts_num, fill_type);
+
+ BLI_assert(BKE_mesh_is_valid(mesh));
+
return mesh;
}
@@ -467,8 +559,6 @@ static void geo_node_mesh_primitive_cone_exec(GeoNodeExecParams params)
Mesh *mesh = create_cylinder_or_cone_mesh(
radius_top, radius_bottom, depth, verts_num, fill_type);
- BLI_assert(BKE_mesh_is_valid(mesh));
-
/* Transform the mesh so that the base of the cone is at the origin. */
transform_mesh(mesh, location + float3(0.0f, 0.0f, depth), rotation, float3(1));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
index 21fa6745d61..4b8b6a35058 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
@@ -83,8 +83,6 @@ static void geo_node_mesh_primitive_cylinder_exec(GeoNodeExecParams params)
transform_mesh(mesh, location, rotation, float3(1));
- BLI_assert(BKE_mesh_is_valid(mesh));
-
params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
index 33af67f8d60..1fd9ab21a40 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
@@ -217,10 +217,10 @@ static void calculate_sphere_faces(MutableSpan<MLoop> loops,
}
}
-static void calculate_uv_attribute(MeshComponent &mesh_component,
- const float segments,
- const float rings)
+static void calculate_uvs(Mesh *mesh, const float segments, const float rings)
{
+ MeshComponent mesh_component;
+ mesh_component.replace(mesh, GeometryOwnershipType::Editable);
OutputAttributePtr uv_attribute = mesh_component.attribute_try_get_for_output(
"uv", ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2, nullptr);
MutableSpan<float2> uvs = uv_attribute->get_span_for_write_only<float2>();
@@ -252,6 +252,8 @@ static void calculate_uv_attribute(MeshComponent &mesh_component,
uvs[loop_index++] = float2((segment + 1.0f) / segments, 1.0f - dy);
uvs[loop_index++] = float2(segment / segments, 1.0f - dy);
}
+
+ uv_attribute.apply_span_and_save();
}
static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const int rings)
@@ -272,6 +274,8 @@ static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const
calculate_sphere_faces(loops, polys, segments, rings);
+ calculate_uvs(mesh, segments, rings);
+
BLI_assert(BKE_mesh_is_valid(mesh));
return mesh;
@@ -294,12 +298,7 @@ static void geo_node_mesh_primitive_uv_sphere_exec(GeoNodeExecParams params)
transform_mesh(mesh, location, rotation, float3(1));
- GeometrySet result_set = GeometrySet::create_with_mesh(mesh);
-
- calculate_uv_attribute(
- result_set.get_component_for_write<MeshComponent>(), segments_num, rings_num);
-
- params.set_output("Geometry", result_set);
+ params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
}
} // namespace blender::nodes