Somewhat improved collision detection
This commit is contained in:
parent
b6ec5be295
commit
33b9f37b0b
@ -1145,35 +1145,39 @@ void PrintObject::detect_surfaces_type()
|
||||
bool
|
||||
PrintObject::check_nonplanar_collisions(NonplanarSurface &surface)
|
||||
{
|
||||
Polygons nonplanar_polygon = to_polygons(surface.horizontal_projection());
|
||||
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||
Polygons collider;
|
||||
Polygons nonplanar_polygon = to_polygons(surface.horizontal_projection());
|
||||
//check each layer
|
||||
for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++ idx_layer) {
|
||||
m_print->throw_if_canceled();
|
||||
// BOOST_LOG_TRIVIAL(trace) << "Check nonplanar collisions for region " << region_id << " and layer " << layer->print_z;
|
||||
Layer *layer = m_layers[idx_layer];
|
||||
LayerRegion *layerm = layer->m_regions[region_id];
|
||||
|
||||
// skip if below minimum nonplanar surface
|
||||
if (surface.stats.min.z-layer->height > layer->slice_z) continue;
|
||||
if (surface.stats.min.z > layer->slice_z + layer->height) continue;
|
||||
// break if above nonplanar surface
|
||||
if (surface.stats.max.z < layer->slice_z) break;
|
||||
|
||||
float angle_rad = m_config.nonplanar_layers_angle.value * 3.14159265/180.0;
|
||||
float angle_offset = scale_(layer->height*std::sin(1.57079633-angle_rad)/std::sin(angle_rad));
|
||||
BOOST_LOG_TRIVIAL(trace) << "Check nonplanar collisions for region " << region_id << " and layer " << layer->print_z;
|
||||
|
||||
//debug
|
||||
// SVG svg("svg/collider" + std::to_string(layer->id()) + ".svg");
|
||||
// svg.draw(layerm_slices_surfaces, "blue");
|
||||
// svg.draw(union_ex(diff(collider,nonplanar_polygon)), "red", 0.7f);
|
||||
// svg.draw_outline(collider);
|
||||
// svg.arrows = false;
|
||||
// svg.Close();
|
||||
// float angle_rad = m_config.nonplanar_layers_angle.value * 3.14159265/180.0;
|
||||
// float angle_offset = scale_(layer->height*std::sin(1.57079633-angle_rad)/std::sin(angle_rad));
|
||||
|
||||
//check if current surface collides with previous collider
|
||||
ExPolygons collisions = union_ex(intersection(layerm->slices().surfaces, diff(collider, nonplanar_polygon)));
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
{
|
||||
static int iRun = 0;
|
||||
SVG svg(debug_out_path("Layer-%u-collider-%u_collisions_layer%.2f.svg", layer->id(), iRun++, layer->print_z), get_extents(layerm->slices().surfaces));
|
||||
svg.draw(layerm->slices().surfaces, "blue");
|
||||
svg.draw(collisions, "red", 0.7f);
|
||||
svg.arrows = false;
|
||||
svg.Close();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!collisions.empty()) {
|
||||
double area = 0;
|
||||
for (auto& c : collisions){
|
||||
@ -1182,7 +1186,21 @@ PrintObject::check_nonplanar_collisions(NonplanarSurface &surface)
|
||||
|
||||
//collsion found abort when area > 1.0 mm²
|
||||
if (1.0 < unscale<double>(unscale<double>(area))) {
|
||||
std::cout << "Surface removed: collision on layer " << layer->print_z << "mm (" << unscale<double>(unscale<double>(area)) << " mm²)" << '\n';
|
||||
BOOST_LOG_TRIVIAL(trace) << "Surface removed: collision on layer " << layer->print_z << "mm (" << unscale<double>(unscale<double>(area)) << " mm²)";
|
||||
|
||||
//debug
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
{
|
||||
static int iRun = 0;
|
||||
SVG svg(debug_out_path("Layer-%u-collider-%u_removed_layer%.2f.svg", layer->id(), iRun++, layer->print_z), get_extents(layerm->slices().surfaces));
|
||||
svg.draw(layerm->slices().surfaces, "blue");
|
||||
svg.draw(union_ex(diff(collider,nonplanar_polygon)), "red", 0.7f);
|
||||
svg.draw_outline(collider);
|
||||
svg.arrows = false;
|
||||
svg.Close();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1190,15 +1208,20 @@ PrintObject::check_nonplanar_collisions(NonplanarSurface &surface)
|
||||
if (layer->upper_layer != NULL) {
|
||||
Layer* upper_layer = layer->upper_layer;
|
||||
LayerRegion *upper_layerm = upper_layer->m_regions[region_id];
|
||||
//merge the ofsetted surface to the collider
|
||||
collider= offset(
|
||||
union_(
|
||||
// merge surface to the collider
|
||||
collider = union_(
|
||||
intersection(
|
||||
diff_ex(layerm->slices().surfaces, upper_layerm->slices().surfaces, ApplySafetyOffset::No),
|
||||
nonplanar_polygon,
|
||||
ApplySafetyOffset::No),
|
||||
collider),
|
||||
angle_offset);
|
||||
collider);
|
||||
|
||||
{
|
||||
static int iRun = 0;
|
||||
SVG svg(debug_out_path("Layer-%u-collider-%u_layer%.2f.svg", layer->id(), iRun++, layer->print_z), get_extents(layerm->slices().surfaces));
|
||||
svg.draw_outline(collider, "black", scale_(0.1f));
|
||||
svg.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -886,15 +886,36 @@ PrintObject::find_nonplanar_surfaces()
|
||||
|
||||
// create nonplanar surface from facets
|
||||
NonplanarSurface nf = NonplanarSurface(facets);
|
||||
BOOST_LOG_TRIVIAL(trace) << "Find nonplanar surfaces - moving surfaces by z=" << -tmesh.stats().min.z();
|
||||
BOOST_LOG_TRIVIAL(debug) << "Find nonplanar surfaces - moving surfaces by z=" << -tmesh.stats().min.z();
|
||||
nf.translate(0, 0, -tmesh.stats().min.z());
|
||||
|
||||
// group surfaces and attach all nonplanar surfaces to the PrintObject
|
||||
m_nonplanar_surfaces = nf.group_surfaces();
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
for (size_t id = 0; id < m_nonplanar_surfaces.size(); ++ id) {
|
||||
auto& surface = m_nonplanar_surfaces[id];
|
||||
Surfaces surfaces;
|
||||
surfaces_append(surfaces, surface.horizontal_projection(), SurfaceType::stTopNonplanar);
|
||||
SurfaceCollection c(surfaces);
|
||||
c.export_to_svg(debug_out_path("0_find_nonplanar_surface-%d-initial_layer%.2f.svg", id, surface.stats.min.z).c_str(), true);
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for surfaces that are actually flat
|
||||
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
||||
if((*it).stats.min.z == (*it).stats.max.z) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Find nonplanar surfaces - deleted one surface with same min/max Z height";
|
||||
it = m_nonplanar_surfaces.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
// check if surfaces maintain maximum printing height, if not, erase it
|
||||
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
||||
if((*it).check_max_printing_height(m_config.nonplanar_layers_height.value)) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Find nonplanar surfaces - deleted one surface due to max printing height constraint";
|
||||
it = m_nonplanar_surfaces.erase(it);
|
||||
}else {
|
||||
it++;
|
||||
@ -904,6 +925,7 @@ PrintObject::find_nonplanar_surfaces()
|
||||
// check if surfaces area is not too small
|
||||
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
||||
if((*it).check_surface_area()) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Find nonplanar surfaces - deleted one surface due to print area too small";
|
||||
it = m_nonplanar_surfaces.erase(it);
|
||||
}else {
|
||||
it++;
|
||||
@ -913,6 +935,7 @@ PrintObject::find_nonplanar_surfaces()
|
||||
// check if surfaces areas collide
|
||||
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
||||
if(check_nonplanar_collisions((*it))) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Find nonplanar surfaces - deleted one surface due to collision";
|
||||
it = m_nonplanar_surfaces.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
@ -921,17 +944,19 @@ PrintObject::find_nonplanar_surfaces()
|
||||
|
||||
//nf.debug_output();
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
BOOST_LOG_TRIVIAL(info) << "Find nonplanar surfaces - found " << m_nonplanar_surfaces.size() << " in " << (*it)->name;
|
||||
|
||||
for (size_t id = 0; id < m_nonplanar_surfaces.size(); ++ id) {
|
||||
auto& surface = m_nonplanar_surfaces[id];
|
||||
BOOST_LOG_TRIVIAL(debug) << "Find nonplanar surfaces - surface" << id << " at Z [min=" << surface.stats.min.z << ", max=" << surface.stats.max.z << "]";
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
Surfaces surfaces;
|
||||
surfaces_append(surfaces, surface.horizontal_projection(), SurfaceType::stTopNonplanar);
|
||||
SurfaceCollection c(surfaces);
|
||||
c.export_to_svg(debug_out_path("0_find_nonplanar_surface-%d.svg", id).c_str(), true);
|
||||
}
|
||||
c.export_to_svg(debug_out_path("0_find_nonplanar_surface-%d-final_layer%.2f.svg", id, surface.stats.min.z).c_str(), true);
|
||||
#endif
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "Find nonplanar surfaces - found " << m_nonplanar_surfaces.size() << " in " << (*it)->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user