Renamed create_face_neighbors_index() to its_face_edge_ids().

Renamed its_create_neighbors_index() / its_create_neighbors_index_par() to its_face_neighbors() / its_face_neighbors_par().
New variant of its_face_edge_ids() to create edge IDs from face neighbors.
Fixed some incorrect use of _NDEBUG, it should be NDEBUG.
PrintObject::slice_support_volumes() returns newly Polygons, which are cheaper than ExPolygons.
Updated SeamPlacer and SupportMaterial to use regions defined as Polygons, not ExPolygons.
TriangleSelector::get_facets_strict() returning a patch with T-joints retriangulated.
New slice_mesh_slabs() - slicing projections of a triangle patch into top / bottom layers of slices, for MMU top / bottom segmentation.
TriangleMeshSlicer - use 64 mutexes instead of one when scattering sliced triangles into layers. This makes a big difference on modern many core desktop computers.
When applying MM segmented regions to input regions, the split regions are now re-merged with 10x higher positive offset epsilon to avoid creating gaps.
When testing for existence of paint-on supports or seam, use a more efficient has_facets() test, which does not deserialize into the expensive TriangleSelector tree structure.
GLIndexedVertexArray newly uses Eigen::AlignedBox<float, 3> for efficiency instead of our double based BoundingBoxf3.
Improved MMU painting refresh speed by optimizing generation of the vertex buffers.
Refactored MMU segmentation - projection of painted surfaces from top / bottom.
	1) Parallelized.
	2) Using the new slice_mesh_slabs() instead of projecting one triangle by the other and merging them with Clipper.
This commit is contained in:
Vojtech Bubnik 2021-06-20 15:21:12 +02:00
parent d08a70478e
commit 0d70a2be69
23 changed files with 1357 additions and 489 deletions

View file

@ -39,16 +39,6 @@ LayerPtrs new_layers(
return out;
}
template<typename LayerContainer>
static inline std::vector<float> zs_from_layers(const LayerContainer &layers)
{
std::vector<float> zs;
zs.reserve(layers.size());
for (const Layer *l : layers)
zs.emplace_back((float)l->slice_z);
return zs;
}
//FIXME The admesh repair function may break the face connectivity, rather refresh it here as the slicing code relies on it.
// This function will go away once we get rid of admesh from ModelVolume.
static indexed_triangle_set get_mesh_its_fix_mesh_connectivity(TriangleMesh mesh)
@ -604,14 +594,18 @@ static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCance
if (! layer_split)
continue;
// Split LayerRegions by by_extruder regions.
// layer_range.painted_regions are sorted by extruder ID and parent PrintObject region ID.
auto it_painted_region = layer_range.painted_regions.begin();
for (int region_id = 0; region_id < int(layer->region_count()); ++ region_id)
if (LayerRegion &layerm = *layer->get_region(region_id); ! layerm.slices.surfaces.empty()) {
assert(layerm.region().print_object_region_id() == region_id);
const BoundingBox bbox = get_extents(layerm.slices.surfaces);
assert(it_painted_region < layer_range.painted_regions.end());
// Find the first it_painted_region which overrides this region.
for (; layer_range.volume_regions[it_painted_region->parent].region->print_object_region_id() < region_id; ++ it_painted_region)
assert(it_painted_region < layer_range.painted_regions.end());
assert(&layerm.region() == it_painted_region->region && layerm.region().print_object_region_id() == region_id);
assert(it_painted_region != layer_range.painted_regions.end());
assert(it_painted_region != layer_range.painted_regions.end());
assert(layer_range.volume_regions[it_painted_region->parent].region == &layerm.region());
// 1-based extruder ID
bool self_trimmed = false;
int self_extruder_id = -1;
@ -619,7 +613,7 @@ static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCance
if (ByExtruder &segmented = by_extruder[extruder_id - 1]; segmented.bbox.defined && bbox.overlap(segmented.bbox)) {
// Find the target region.
for (; int(it_painted_region->extruder_id) < extruder_id; ++ it_painted_region)
assert(it_painted_region < layer_range.painted_regions.end());
assert(it_painted_region != layer_range.painted_regions.end());
assert(layer_range.volume_regions[it_painted_region->parent].region == &layerm.region() && int(it_painted_region->extruder_id) == extruder_id);
//FIXME Don't trim by self, it is not reliable.
if (&layerm.region() == it_painted_region->region) {
@ -669,7 +663,7 @@ static inline void apply_mm_segmentation(PrintObject &print_object, ThrowOnCance
ByRegion &src = by_region[region_id];
if (src.needs_merge)
// Multiple regions were merged into one.
src.expolygons = offset2_ex(src.expolygons, float(scale_(EPSILON)), - float(scale_(EPSILON)));
src.expolygons = offset2_ex(src.expolygons, float(scale_(10 * EPSILON)), - float(scale_(10 * EPSILON)));
layer->get_region(region_id)->slices.set(std::move(src.expolygons), stInternal);
}
}
@ -701,7 +695,7 @@ void PrintObject::slice_volumes()
std::vector<float> slice_zs = zs_from_layers(m_layers);
Transform3d trafo = this->trafo();
trafo.pretranslate(Vec3d(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0));
trafo.pretranslate(Vec3d(- unscale<double>(m_center_offset.x()), - unscale<double>(m_center_offset.y()), 0));
std::vector<std::vector<ExPolygons>> region_slices = slices_to_regions(this->model_object()->volumes, *m_shared_regions, slice_zs,
slice_volumes_inner(
print->config(), this->config(), trafo,
@ -812,12 +806,12 @@ void PrintObject::slice_volumes()
BOOST_LOG_TRIVIAL(debug) << "Slicing volumes - make_slices in parallel - end";
}
std::vector<ExPolygons> PrintObject::slice_support_volumes(const ModelVolumeType model_volume_type) const
std::vector<Polygons> PrintObject::slice_support_volumes(const ModelVolumeType model_volume_type) const
{
auto it_volume = this->model_object()->volumes.begin();
auto it_volume_end = this->model_object()->volumes.end();
for (; it_volume != it_volume_end && (*it_volume)->type() != model_volume_type; ++ it_volume) ;
std::vector<ExPolygons> slices;
std::vector<Polygons> slices;
if (it_volume != it_volume_end) {
// Found at least a single support volume of model_volume_type.
std::vector<float> zs = zs_from_layers(this->layers());
@ -831,16 +825,18 @@ std::vector<ExPolygons> PrintObject::slice_support_volumes(const ModelVolumeType
for (; it_volume != it_volume_end; ++ it_volume)
if ((*it_volume)->type() == model_volume_type) {
std::vector<ExPolygons> slices2 = slice_volume(*(*it_volume), zs, params, throw_on_cancel_callback);
if (slices.empty())
slices = std::move(slices2);
else if (! slices2.empty()) {
if (slices.empty()) {
slices.reserve(slices2.size());
for (ExPolygons &src : slices2)
slices.emplace_back(to_polygons(std::move(src)));
} else if (!slices2.empty()) {
if (merge_layers.empty())
merge_layers.assign(zs.size(), false);
for (size_t i = 0; i < zs.size(); ++ i) {
if (slices[i].empty())
slices[i] = std::move(slices2[i]);
slices[i] = to_polygons(std::move(slices2[i]));
else if (! slices2[i].empty()) {
append(slices[i], std::move(slices2[i]));
append(slices[i], to_polygons(std::move(slices2[i])));
merge_layers[i] = true;
merge = true;
}
@ -848,7 +844,7 @@ std::vector<ExPolygons> PrintObject::slice_support_volumes(const ModelVolumeType
}
}
if (merge) {
std::vector<ExPolygons*> to_merge;
std::vector<Polygons*> to_merge;
to_merge.reserve(zs.size());
for (size_t i = 0; i < zs.size(); ++ i)
if (merge_layers[i])
@ -857,7 +853,7 @@ std::vector<ExPolygons> PrintObject::slice_support_volumes(const ModelVolumeType
tbb::blocked_range<size_t>(0, to_merge.size()),
[&to_merge](const tbb::blocked_range<size_t> &range) {
for (size_t i = range.begin(); i < range.end(); ++ i)
*to_merge[i] = union_ex(*to_merge[i]);
*to_merge[i] = union_(*to_merge[i]);
});
}
}