Cleanup: Slightly simplify delaunay triangulation input gathering
Separate allocation of input arrays and assignment to input class. The main purpose is to simplify #111061.
This commit is contained in:
parent
bb2a289a9a
commit
34bf1f6c0c
|
@ -1686,7 +1686,7 @@ static void prepare_need_tri(CDT_data &cd, const IMesh &tm, int t)
|
|||
cd.is_reversed.append(rev);
|
||||
}
|
||||
|
||||
static CDT_data prepare_cdt_input(const IMesh &tm, int t, const Vector<ITT_value> itts)
|
||||
static CDT_data prepare_cdt_input(const IMesh &tm, int t, const Span<ITT_value> itts)
|
||||
{
|
||||
CDT_data ans;
|
||||
BLI_assert(tm.face(t)->plane_populated());
|
||||
|
@ -1718,7 +1718,7 @@ static CDT_data prepare_cdt_input(const IMesh &tm, int t, const Vector<ITT_value
|
|||
static CDT_data prepare_cdt_input_for_cluster(const IMesh &tm,
|
||||
const CoplanarClusterInfo &clinfo,
|
||||
int c,
|
||||
const Vector<ITT_value> itts)
|
||||
const Span<ITT_value> itts)
|
||||
{
|
||||
CDT_data ans;
|
||||
BLI_assert(c < clinfo.tot_cluster());
|
||||
|
@ -2086,13 +2086,11 @@ static Array<Face *> polyfill_triangulate_poly(Face *f, IMeshArena *arena)
|
|||
static Array<Face *> exact_triangulate_poly(Face *f, IMeshArena *arena)
|
||||
{
|
||||
int flen = f->size();
|
||||
CDT_input<mpq_class> cdt_in;
|
||||
cdt_in.vert = Array<mpq2>(flen);
|
||||
cdt_in.face = Array<Vector<int>>(1);
|
||||
cdt_in.face[0].reserve(flen);
|
||||
for (int i : f->index_range()) {
|
||||
cdt_in.face[0].append(i);
|
||||
}
|
||||
Array<mpq2> in_verts(flen);
|
||||
Array<Vector<int>> faces;
|
||||
faces.first().resize(flen);
|
||||
std::iota(faces.first().begin(), faces.first().end(), 0);
|
||||
|
||||
/* Project poly along dominant axis of normal to get 2d coords. */
|
||||
if (!f->plane_populated()) {
|
||||
f->populate_plane(false);
|
||||
|
@ -2108,7 +2106,7 @@ static Array<Face *> exact_triangulate_poly(Face *f, IMeshArena *arena)
|
|||
bool rev = rev1 ^ rev2;
|
||||
for (int i = 0; i < flen; ++i) {
|
||||
int ii = rev ? flen - i - 1 : i;
|
||||
mpq2 &p2d = cdt_in.vert[ii];
|
||||
mpq2 &p2d = in_verts[ii];
|
||||
int k = 0;
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
if (j != axis) {
|
||||
|
@ -2116,6 +2114,11 @@ static Array<Face *> exact_triangulate_poly(Face *f, IMeshArena *arena)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
CDT_input<mpq_class> cdt_in;
|
||||
cdt_in.vert = std::move(in_verts);
|
||||
cdt_in.face = std::move(faces);
|
||||
|
||||
CDT_result<mpq_class> cdt_out = delaunay_2d_calc(cdt_in, CDT_INSIDE);
|
||||
int n_tris = cdt_out.face.size();
|
||||
Array<Face *> ans(n_tris);
|
||||
|
|
|
@ -24,38 +24,38 @@
|
|||
|
||||
namespace blender::io::obj {
|
||||
|
||||
Vector<Vector<int>> fixup_invalid_polygon(Span<float3> vertex_coords,
|
||||
Span<int> face_vertex_indices)
|
||||
Vector<Vector<int>> fixup_invalid_polygon(Span<float3> vert_positions, Span<int> face_verts)
|
||||
{
|
||||
using namespace blender::meshintersect;
|
||||
if (face_vertex_indices.size() < 3) {
|
||||
if (face_verts.size() < 3) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const float3 normal = bke::mesh::face_normal_calc(vertex_coords, face_vertex_indices);
|
||||
const float3 normal = bke::mesh::face_normal_calc(vert_positions, face_verts);
|
||||
float axis_mat[3][3];
|
||||
axis_dominant_v3_to_m3(axis_mat, normal);
|
||||
|
||||
/* Prepare data for CDT. */
|
||||
CDT_input<double> input;
|
||||
input.vert.reinitialize(face_vertex_indices.size());
|
||||
input.face.reinitialize(1);
|
||||
input.face[0].resize(face_vertex_indices.size());
|
||||
for (int64_t i = 0; i < face_vertex_indices.size(); ++i) {
|
||||
input.face[0][i] = i;
|
||||
}
|
||||
input.epsilon = 1.0e-6f;
|
||||
input.need_ids = true;
|
||||
/* Project vertices to 2D. */
|
||||
for (size_t i = 0; i < face_vertex_indices.size(); ++i) {
|
||||
int idx = face_vertex_indices[i];
|
||||
BLI_assert(idx >= 0 && idx < vertex_coords.size());
|
||||
float3 coord = vertex_coords[idx];
|
||||
Array<double2> input_verts(face_verts.size());
|
||||
for (const int i : face_verts.index_range()) {
|
||||
int idx = face_verts[i];
|
||||
BLI_assert(idx >= 0 && idx < vert_positions.size());
|
||||
float2 coord2d;
|
||||
mul_v2_m3v3(coord2d, axis_mat, coord);
|
||||
input.vert[i] = double2(coord2d.x, coord2d.y);
|
||||
mul_v2_m3v3(coord2d, axis_mat, vert_positions[idx]);
|
||||
input_verts[i] = double2(coord2d.x, coord2d.y);
|
||||
}
|
||||
|
||||
Array<Vector<int>> input_faces(1);
|
||||
input_faces.first().resize(input_verts.size());
|
||||
|
||||
std::iota(input_faces.first().begin(), input_faces.first().end(), 0);
|
||||
|
||||
/* Prepare data for CDT. */
|
||||
CDT_input<double> input;
|
||||
input.vert = std::move(input_verts);
|
||||
input.face = std::move(input_faces);
|
||||
input.epsilon = 1.0e-6f;
|
||||
input.need_ids = true;
|
||||
CDT_result<double> res = delaunay_2d_calc(input, CDT_CONSTRAINTS_VALID_BMESH_WITH_HOLES);
|
||||
|
||||
/* Emit new face information from CDT result. */
|
||||
|
@ -77,7 +77,7 @@ Vector<Vector<int>> fixup_invalid_polygon(Span<float3> vertex_coords,
|
|||
else {
|
||||
/* Vertex corresponds to one or more of the input vertices, use it. */
|
||||
idx = res.vert_orig[idx][0];
|
||||
BLI_assert(idx >= 0 && idx < face_vertex_indices.size());
|
||||
BLI_assert(idx >= 0 && idx < face_verts.size());
|
||||
face_verts.append(idx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,32 +52,39 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
|
|||
node->storage = data;
|
||||
}
|
||||
|
||||
static void fill_curve_vert_indices(const OffsetIndices<int> offsets,
|
||||
MutableSpan<Vector<int>> faces)
|
||||
{
|
||||
threading::parallel_for(faces.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
faces[i].resize(offsets[i].size());
|
||||
array_utils::fill_index_range<int>(faces[i], offsets[i].start());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static meshintersect::CDT_result<double> do_cdt(const bke::CurvesGeometry &curves,
|
||||
const CDT_output_type output_type)
|
||||
{
|
||||
const OffsetIndices points_by_curve = curves.evaluated_points_by_curve();
|
||||
const Span<float3> positions = curves.evaluated_positions();
|
||||
|
||||
Array<double2> positions_2d(positions.size());
|
||||
threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
positions_2d[i] = double2(positions[i].x, positions[i].y);
|
||||
}
|
||||
});
|
||||
|
||||
Array<Vector<int>> faces(curves.curves_num());
|
||||
fill_curve_vert_indices(points_by_curve, faces);
|
||||
|
||||
meshintersect::CDT_input<double> input;
|
||||
input.need_ids = false;
|
||||
input.vert.reinitialize(points_by_curve.total_size());
|
||||
input.face.reinitialize(curves.curves_num());
|
||||
input.vert = std::move(positions_2d);
|
||||
input.face = std::move(faces);
|
||||
|
||||
for (const int i_curve : curves.curves_range()) {
|
||||
const IndexRange points = points_by_curve[i_curve];
|
||||
|
||||
for (const int i : points) {
|
||||
input.vert[i] = double2(positions[i].x, positions[i].y);
|
||||
}
|
||||
|
||||
input.face[i_curve].resize(points.size());
|
||||
MutableSpan<int> face_verts = input.face[i_curve];
|
||||
for (const int i : face_verts.index_range()) {
|
||||
face_verts[i] = points[i];
|
||||
}
|
||||
}
|
||||
meshintersect::CDT_result<double> result = delaunay_2d_calc(input, output_type);
|
||||
return result;
|
||||
return delaunay_2d_calc(input, output_type);
|
||||
}
|
||||
|
||||
static meshintersect::CDT_result<double> do_cdt_with_mask(const bke::CurvesGeometry &curves,
|
||||
|
@ -87,34 +94,30 @@ static meshintersect::CDT_result<double> do_cdt_with_mask(const bke::CurvesGeome
|
|||
const OffsetIndices points_by_curve = curves.evaluated_points_by_curve();
|
||||
const Span<float3> positions = curves.evaluated_positions();
|
||||
|
||||
int vert_len = 0;
|
||||
mask.foreach_index([&](const int i) { vert_len += points_by_curve[i].size(); });
|
||||
|
||||
meshintersect::CDT_input<double> input;
|
||||
input.need_ids = false;
|
||||
input.vert.reinitialize(vert_len);
|
||||
input.face.reinitialize(mask.size());
|
||||
|
||||
Array<int> offsets_data(mask.size() + 1);
|
||||
const OffsetIndices points_by_curve_masked = offset_indices::gather_selected_offsets(
|
||||
points_by_curve, mask, offsets_data);
|
||||
|
||||
Array<double2> positions_2d(points_by_curve_masked.total_size());
|
||||
mask.foreach_index(GrainSize(1024), [&](const int src_curve, const int dst_curve) {
|
||||
const IndexRange src_points = points_by_curve[src_curve];
|
||||
const IndexRange dst_points = points_by_curve_masked[dst_curve];
|
||||
|
||||
for (const int i : src_points.index_range()) {
|
||||
const int src = src_points[i];
|
||||
const int dst = dst_points[i];
|
||||
input.vert[dst] = double2(positions[src].x, positions[src].y);
|
||||
positions_2d[dst] = double2(positions[src].x, positions[src].y);
|
||||
}
|
||||
|
||||
input.face[dst_curve].resize(src_points.size());
|
||||
array_utils::fill_index_range<int>(input.face[dst_curve], dst_points.start());
|
||||
});
|
||||
|
||||
meshintersect::CDT_result<double> result = delaunay_2d_calc(input, output_type);
|
||||
return result;
|
||||
Array<Vector<int>> faces(points_by_curve_masked.size());
|
||||
fill_curve_vert_indices(points_by_curve_masked, faces);
|
||||
|
||||
meshintersect::CDT_input<double> input;
|
||||
input.need_ids = false;
|
||||
input.vert = std::move(positions_2d);
|
||||
input.face = std::move(faces);
|
||||
|
||||
return delaunay_2d_calc(input, output_type);
|
||||
}
|
||||
|
||||
static Array<meshintersect::CDT_result<double>> do_group_aware_cdt(
|
||||
|
|
Loading…
Reference in New Issue