225{
226 const indexed_triangle_set &src = src_mesh.
its;
227 const indexed_triangle_set &dst = dst_mesh.
its;
228 const size_t ntri = src.indices.size();
229 if (src_data.
bitstream.empty() || ntri == 0 || dst.indices.empty() || src_tree.
empty())
230 return {};
231
232
233
234
235
237 src_sel.deserialize(src_data, false);
238 std::vector<int> piece_src;
240 if (patch.indices.empty())
241 return {};
242
243 const auto tri_area2 = [](
const Vec3f &a,
const Vec3f &b,
const Vec3f &c) {
244 return (b - a).cross(c - a).norm();
245 };
246 std::vector<float> src_area2(ntri, 0.f), covered2(ntri, 0.f);
247 for (size_t i = 0; i < ntri; ++i)
248 src_area2[i] = tri_area2(src.vertices[size_t(src.indices[i][0])], src.vertices[size_t(src.indices[i][1])],
249 src.vertices[size_t(src.indices[i][2])]);
250 for (size_t j = 0; j < patch.indices.size() && j < piece_src.size(); ++j) {
251 if (size_t(piece_src[j]) >= ntri)
252 continue;
253 const stl_triangle_vertex_indices &t = patch.indices[j];
254 covered2[size_t(piece_src[j])] += tri_area2(patch.vertices[size_t(t[0])], patch.vertices[size_t(t[1])],
255 patch.vertices[size_t(t[2])]);
256 }
257 std::vector<uint8_t> full(ntri, 0);
258 for (size_t i = 0; i < ntri; ++i)
259 full[i] = (src_area2[i] > 0.f && covered2[i] >= 0.999f * src_area2[i]) ? 1 : 0;
260
261
262 std::vector<int> part_start(ntri + 1, 0);
263 for (size_t j = 0; j < patch.indices.size() && j < piece_src.size(); ++j)
264 if (size_t(piece_src[j]) < ntri && !full[size_t(piece_src[j])])
265 ++part_start[size_t(piece_src[j]) + 1];
266 for (size_t i = 0; i < ntri; ++i)
267 part_start[i + 1] += part_start[i];
268 std::vector<std::array<Vec3f, 3>> part;
269 part.resize(size_t(part_start[ntri]));
270
271
272 {
273 std::vector<int> fill(part_start.begin(), part_start.begin() + ntri);
274 for (size_t j = 0; j < patch.indices.size() && j < piece_src.size(); ++j) {
275 const size_t S = size_t(piece_src[j]);
276 if (S >= ntri || full[S])
277 continue;
278 const stl_triangle_vertex_indices &t = patch.indices[j];
279 part[size_t(fill[S]++)] = { patch.vertices[size_t(t[0])], patch.vertices[size_t(t[1])],
280 patch.vertices[size_t(t[2])] };
281 }
282 }
283
284
285 std::vector<uint8_t> painted(dst.indices.size(), 0);
286 tbb::parallel_for(tbb::blocked_range<size_t>(0, dst.indices.size()),
287 [&](
const tbb::blocked_range<size_t> &
range) {
288 for (size_t i = range.begin(); i < range.end(); ++i) {
289 const stl_triangle_vertex_indices &t = dst.indices[i];
290 const Vec3f centroid = (dst.vertices[size_t(t[0])] + dst.vertices[size_t(t[1])] +
291 dst.vertices[size_t(t[2])]) / 3.f + dst_to_src;
292 size_t hit = 0;
293 Vec3f hit_pos = Vec3f::Zero();
294 if (AABBTreeIndirect::squared_distance_to_indexed_triangle_set(src.vertices, src.indices, src_tree,
295 centroid, hit, hit_pos) < 0.f ||
296 hit >= ntri)
297 continue;
298 if (full[hit]) {
299 painted[i] = 1;
300 continue;
301 }
302 for (int k = part_start[hit]; k < part_start[hit + 1]; ++k)
303 if (point_in_triangle_coplanar(hit_pos, part[size_t(k)])) {
304 painted[i] = 1;
305 break;
306 }
307 }
308 });
309
310 TriangleSelector dst_sel(dst_mesh);
311 for (size_t i = 0; i < painted.size(); ++i)
312 if (painted[i])
314 return dst_sel.serialize();
315}
bool empty() const
Definition AABBTreeIndirect.hpp:111
indexed_triangle_set its
Definition TriangleMesh.hpp:164
Definition TriangleSelector.hpp:75
auto range(Cont &&cont)
Definition libslic3r.h:405
@ ENFORCER
Definition TriangleSelector.hpp:27
std::vector< bool > bitstream
Definition TriangleSelector.hpp:291