Merge branch 'blender-v3.6-release'

This commit is contained in:
Hans Goudey
2023-06-23 12:13:43 -04:00
2 changed files with 66 additions and 10 deletions

View File

@@ -180,6 +180,33 @@ static void split_vertex_per_fan(const int vertex,
}
}
/** Assign the newly created vertex duplicates to the loose edges around this vertex. */
static void reassign_loose_edge_verts(const int vertex,
const int start_offset,
const Span<int> fans,
const Span<int> fan_sizes,
const BoundedBitSpan loose_edges,
MutableSpan<int2> edges)
{
int fan_start = 0;
/* We don't need to create a new vertex for the last fan. That fan can just be connected to the
* original vertex. */
for (const int i : fan_sizes.index_range().drop_back(1)) {
const int new_vert = start_offset + i;
for (const int edge_i : fans.slice(fan_start, fan_sizes[i])) {
if (loose_edges[edge_i]) {
if (edges[edge_i][0] == vertex) {
edges[edge_i][0] = new_vert;
}
else if (edges[edge_i][1] == vertex) {
edges[edge_i][1] = new_vert;
}
}
}
fan_start += fan_sizes[i];
}
}
/**
* Get the index of the adjacent edge to a loop connected to a vertex. In other words, for the
* given polygon return the unique edge connected to the given vertex and not on the given loop.
@@ -334,7 +361,8 @@ void split_edges(Mesh &mesh,
const OffsetIndices polys = mesh.polys();
const Array<int> orig_corner_edges = mesh.corner_edges();
IndexMaskMemory memory;
const IndexMask loose_edges = IndexMask::from_bits(mesh.loose_edges().is_loose_bits, memory);
const bke::LooseEdgeCache &loose_edges_cache = mesh.loose_edges();
const IndexMask loose_edges = IndexMask::from_bits(loose_edges_cache.is_loose_bits, memory);
MutableSpan<int> corner_edges = mesh.corner_edges_for_write();
@@ -345,12 +373,14 @@ void split_edges(Mesh &mesh,
}
});
/* Step 1: Split the edges. */
/* Split corner edge indices and update the edge to corner map. This step does not take into
* account future deduplication of the new edges, but is necessary in order to calculate the
* new fans around each vertex. */
mask.foreach_index([&](const int edge_i) {
split_edge_per_poly(edge_i, edge_offsets[edge_i], edge_to_loop_map, corner_edges);
});
/* Step 1.5: Update topology information (can't parallelize). */
/* Update vertex to edge map with new vertices from duplicated edges. */
mask.foreach_index([&](const int edge_i) {
const int2 &edge = edges[edge_i];
for (const int duplicate_i : IndexRange(edge_offsets[edge_i], num_edge_duplicates[edge_i])) {
@@ -361,7 +391,8 @@ void split_edges(Mesh &mesh,
MutableSpan<int> corner_verts = mesh.corner_verts_for_write();
/* Step 2: Calculate vertex fans. */
/* Calculate vertex fans by reordering the vertex to edge maps. Fans are the the ordered
* groups of consecutive edges between consecutive faces looping around a vertex. */
Array<Vector<int>> vertex_fan_sizes(mesh.totvert);
threading::parallel_for(IndexRange(mesh.totvert), 512, [&](IndexRange range) {
for (const int vert : range) {
@@ -379,7 +410,7 @@ void split_edges(Mesh &mesh,
}
});
/* Step 2.5: Calculate offsets for next step. */
/* Calculate result indices per source vertex as offsets for parallelizing the next step. */
Array<int> vert_offsets(mesh.totvert);
int total_verts_num = mesh.totvert;
for (const int vert : IndexRange(mesh.totvert)) {
@@ -391,7 +422,7 @@ void split_edges(Mesh &mesh,
total_verts_num += vertex_fan_sizes[vert].size() - 1;
}
/* Step 3: Split the vertices.
/* Split the vertices into their duplicates so that each fan has its own result vertex.
* Build a map from each new vertex to an old vertex to use for transferring attributes later. */
const int new_verts_num = total_verts_num - mesh.totvert;
Array<int> new_to_old_verts_map(new_verts_num);
@@ -411,6 +442,7 @@ void split_edges(Mesh &mesh,
}
});
/* Create deduplicated new edges based on the corner vertices at each polygon. */
VectorSet<OrderedEdge> new_edges;
new_edges.reserve(new_edges_size + loose_edges.size());
for (const int i : polys.index_range()) {
@@ -423,6 +455,7 @@ void split_edges(Mesh &mesh,
}
loose_edges.foreach_index([&](const int64_t i) { new_edges.add(OrderedEdge(edges[i])); });
/* Build a map of old to new edges for transferring attributes. */
Array<int> new_to_old_edges_map(new_edges.size());
auto index_mask_to_indices = [&](const IndexMask &mask, MutableSpan<int> indices) {
for (const int i : mask.index_range()) {
@@ -440,10 +473,28 @@ void split_edges(Mesh &mesh,
}
}
/* Step 5: Resize the mesh to add the new vertices and rebuild the edges. */
/* Resize the mesh to add the new vertices and rebuild the edges. */
add_new_vertices(mesh, new_to_old_verts_map);
add_new_edges(mesh, new_edges.as_span().cast<int2>(), new_to_old_edges_map, propagation_info);
/* Connect loose edges to duplicated vertices. */
if (loose_edges_cache.count > 0) {
MutableSpan<int2> new_edges_span = mesh.edges_for_write();
threading::parallel_for(should_split_vert.index_range(), 512, [&](IndexRange range) {
for (const int vert : range) {
if (!should_split_vert[vert]) {
continue;
}
reassign_loose_edge_verts(vert,
vert_offsets[vert],
vert_to_edge_map[vert],
vertex_fan_sizes[vert],
loose_edges_cache.is_loose_bits,
new_edges_span);
}
});
}
BKE_mesh_tag_edges_split(&mesh);
}

View File

@@ -701,6 +701,9 @@ bool Custom::matches(const bNodeSocket &socket) const
if (socket.type != SOCK_CUSTOM) {
return false;
}
if (!STREQ(socket.typeinfo->idname, idname_)) {
return false;
}
return true;
}
@@ -709,10 +712,12 @@ bool Custom::can_connect(const bNodeSocket &socket) const
return sockets_can_connect(*this, socket) && STREQ(socket.idname, idname_);
}
bNodeSocket &Custom::update_or_build(bNodeTree & /*ntree*/,
bNode & /*node*/,
bNodeSocket &socket) const
bNodeSocket &Custom::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const
{
if (!STREQ(socket.typeinfo->idname, idname_)) {
return this->build(ntree, node);
}
this->set_common_flags(socket);
return socket;
}