Somewhat improved collision detection
This commit is contained in:
parent
b6ec5be295
commit
33b9f37b0b
@ -1145,36 +1145,40 @@ void PrintObject::detect_surfaces_type()
|
|||||||
bool
|
bool
|
||||||
PrintObject::check_nonplanar_collisions(NonplanarSurface &surface)
|
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) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
Polygons collider;
|
Polygons collider;
|
||||||
Polygons nonplanar_polygon = to_polygons(surface.horizontal_projection());
|
|
||||||
//check each layer
|
//check each layer
|
||||||
for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++ idx_layer) {
|
for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++ idx_layer) {
|
||||||
m_print->throw_if_canceled();
|
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];
|
Layer *layer = m_layers[idx_layer];
|
||||||
LayerRegion *layerm = layer->m_regions[region_id];
|
LayerRegion *layerm = layer->m_regions[region_id];
|
||||||
|
|
||||||
//skip if below minimum nonplanar surface
|
// 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
|
// break if above nonplanar surface
|
||||||
if (surface.stats.max.z < layer->slice_z) break;
|
if (surface.stats.max.z < layer->slice_z) break;
|
||||||
|
|
||||||
float angle_rad = m_config.nonplanar_layers_angle.value * 3.14159265/180.0;
|
BOOST_LOG_TRIVIAL(trace) << "Check nonplanar collisions for region " << region_id << " and layer " << layer->print_z;
|
||||||
float angle_offset = scale_(layer->height*std::sin(1.57079633-angle_rad)/std::sin(angle_rad));
|
|
||||||
|
|
||||||
//debug
|
// float angle_rad = m_config.nonplanar_layers_angle.value * 3.14159265/180.0;
|
||||||
// SVG svg("svg/collider" + std::to_string(layer->id()) + ".svg");
|
// float angle_offset = scale_(layer->height*std::sin(1.57079633-angle_rad)/std::sin(angle_rad));
|
||||||
// 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();
|
|
||||||
|
|
||||||
//check if current surface collides with previous collider
|
//check if current surface collides with previous collider
|
||||||
ExPolygons collisions = union_ex(intersection(layerm->slices().surfaces, diff(collider, nonplanar_polygon)));
|
ExPolygons collisions = union_ex(intersection(layerm->slices().surfaces, diff(collider, nonplanar_polygon)));
|
||||||
|
|
||||||
if (!collisions.empty()){
|
#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;
|
double area = 0;
|
||||||
for (auto& c : collisions){
|
for (auto& c : collisions){
|
||||||
area += c.area();
|
area += c.area();
|
||||||
@ -1182,7 +1186,21 @@ PrintObject::check_nonplanar_collisions(NonplanarSurface &surface)
|
|||||||
|
|
||||||
//collsion found abort when area > 1.0 mm²
|
//collsion found abort when area > 1.0 mm²
|
||||||
if (1.0 < unscale<double>(unscale<double>(area))) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1190,15 +1208,20 @@ PrintObject::check_nonplanar_collisions(NonplanarSurface &surface)
|
|||||||
if (layer->upper_layer != NULL) {
|
if (layer->upper_layer != NULL) {
|
||||||
Layer* upper_layer = layer->upper_layer;
|
Layer* upper_layer = layer->upper_layer;
|
||||||
LayerRegion *upper_layerm = upper_layer->m_regions[region_id];
|
LayerRegion *upper_layerm = upper_layer->m_regions[region_id];
|
||||||
//merge the ofsetted surface to the collider
|
// merge surface to the collider
|
||||||
collider= offset(
|
collider = union_(
|
||||||
union_(
|
|
||||||
intersection(
|
intersection(
|
||||||
diff_ex(layerm->slices().surfaces, upper_layerm->slices().surfaces, ApplySafetyOffset::No),
|
diff_ex(layerm->slices().surfaces, upper_layerm->slices().surfaces, ApplySafetyOffset::No),
|
||||||
nonplanar_polygon,
|
nonplanar_polygon,
|
||||||
ApplySafetyOffset::No),
|
ApplySafetyOffset::No),
|
||||||
collider),
|
collider);
|
||||||
angle_offset);
|
|
||||||
|
{
|
||||||
|
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
|
// create nonplanar surface from facets
|
||||||
NonplanarSurface nf = NonplanarSurface(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());
|
nf.translate(0, 0, -tmesh.stats().min.z());
|
||||||
|
|
||||||
// group surfaces and attach all nonplanar surfaces to the PrintObject
|
// group surfaces and attach all nonplanar surfaces to the PrintObject
|
||||||
m_nonplanar_surfaces = nf.group_surfaces();
|
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
|
// check if surfaces maintain maximum printing height, if not, erase it
|
||||||
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
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)) {
|
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);
|
it = m_nonplanar_surfaces.erase(it);
|
||||||
}else {
|
}else {
|
||||||
it++;
|
it++;
|
||||||
@ -904,6 +925,7 @@ PrintObject::find_nonplanar_surfaces()
|
|||||||
// check if surfaces area is not too small
|
// check if surfaces area is not too small
|
||||||
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
||||||
if((*it).check_surface_area()) {
|
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);
|
it = m_nonplanar_surfaces.erase(it);
|
||||||
}else {
|
}else {
|
||||||
it++;
|
it++;
|
||||||
@ -913,6 +935,7 @@ PrintObject::find_nonplanar_surfaces()
|
|||||||
// check if surfaces areas collide
|
// check if surfaces areas collide
|
||||||
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
for (NonplanarSurfaces::iterator it = m_nonplanar_surfaces.begin(); it!=m_nonplanar_surfaces.end();) {
|
||||||
if(check_nonplanar_collisions((*it))) {
|
if(check_nonplanar_collisions((*it))) {
|
||||||
|
BOOST_LOG_TRIVIAL(trace) << "Find nonplanar surfaces - deleted one surface due to collision";
|
||||||
it = m_nonplanar_surfaces.erase(it);
|
it = m_nonplanar_surfaces.erase(it);
|
||||||
} else {
|
} else {
|
||||||
it++;
|
it++;
|
||||||
@ -921,17 +944,19 @@ PrintObject::find_nonplanar_surfaces()
|
|||||||
|
|
||||||
//nf.debug_output();
|
//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) {
|
for (size_t id = 0; id < m_nonplanar_surfaces.size(); ++ id) {
|
||||||
auto& surface = m_nonplanar_surfaces[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 surfaces;
|
||||||
surfaces_append(surfaces, surface.horizontal_projection(), SurfaceType::stTopNonplanar);
|
surfaces_append(surfaces, surface.horizontal_projection(), SurfaceType::stTopNonplanar);
|
||||||
SurfaceCollection c(surfaces);
|
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
|
#endif
|
||||||
|
}
|
||||||
BOOST_LOG_TRIVIAL(info) << "Find nonplanar surfaces - found " << m_nonplanar_surfaces.size() << " in " << (*it)->name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user