Skip to content

Commit

Permalink
Fixed issue with the detection of the correct triangle for endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
ahlers committed Dec 4, 2020
1 parent 9b3075f commit fa0ffec
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 12 deletions.
78 changes: 77 additions & 1 deletion xs/src/libslic3r/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,28 @@ linint(double value, double oldmin, double oldmax, double newmin, double newmax)
return (value - oldmin) * (newmax - newmin) / (oldmax - oldmin) + newmin;
}

bool
point_in_bounding_box(Pointf pt, Pointf v1, Pointf v2, Pointf v3, double epsilon)
{
//check if point is in x range
if (pt.x < std::min({v1.x, v2.x, v3.x}) - epsilon || pt.x > std::max({v1.x, v2.x, v3.x}) + epsilon) {
return false;
}
//check if point is in y range
if (pt.y < std::min({v1.y, v2.y, v3.y}) - epsilon || pt.y > std::max({v1.y, v2.y, v3.y}) + epsilon) {
return false;
}
return true;
}

float
sign(Pointf p1, Pointf p2, Pointf p3)
{
return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
}

bool
Point_in_triangle(Pointf pt, Pointf v1, Pointf v2, Pointf v3)
Point_in_triangle_side(Pointf pt, Pointf v1, Pointf v2, Pointf v3)
{
//Check if point is right of every edge
if (sign(pt, v1, v2) <= 0.0f) return false;
Expand All @@ -360,6 +374,68 @@ Point_in_triangle(Pointf pt, Pointf v1, Pointf v2, Pointf v3)
return true;
}

// bool
// Point_in_triangle_barycentric(Pointf pt, Pointf v1, Pointf v2, Pointf v3)
// {
// double denom = ((v2.y - v3.y)*(v1.x - v3.x) + (v3.x - v2.x)*(v1.y - v3.y));
// double a = ((v2.y - v3.y)*(pt.x - v3.x) + (v3.x - v2.x)*(pt.y - v3.y)) / denom;
// double b = ((v3.y - v1.y)*(pt.x - v3.x) + (v1.x - v3.x)*(pt.y - v3.y)) / denom;
// double c = 1 - a - b;

// return (0 <= a && a <= 1 && 0 <= b && b <= 1 && 0 <= c && c <= 1);
// }

double
distanceSquarePointToSegment(Pointf pt, Pointf v1, Pointf v2)
{
double p1_p2_squareLength = (v2.x - v1.x)*(v2.x - v1.x) + (v2.y - v1.y)*(v2.y - v1.y);
double dotProduct = ((pt.x - v1.x)*(v2.x - v1.x) + (pt.y - v1.y)*(v2.y - v1.y)) / p1_p2_squareLength;
if ( dotProduct < 0 )
{
return (pt.x - v1.x)*(pt.x - v1.x) + (pt.y - v1.y)*(pt.y - v1.y);
}
else if ( dotProduct <= 1 )
{
double p_p1_squareLength = (v1.x - pt.x)*(v1.x - pt.x) + (v1.y - pt.y)*(v1.y - pt.y);
return p_p1_squareLength - dotProduct * dotProduct * p1_p2_squareLength;
}
else
{
return (pt.x - v2.x)*(pt.x - v2.x) + (pt.y - v2.y)*(pt.y - v2.y);
}
}

bool
Point_in_triangle(Pointf pt, Pointf v1, Pointf v2, Pointf v3, double epsilon)
{
const double EPSILON_SQUARE = epsilon*epsilon;

//taken from http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html
//check if pt is in bounding box
if (!point_in_bounding_box(pt,v1,v2,v3,epsilon)){
return false;
}

//check if point is in triangle
if (Point_in_triangle_side(pt,v1,v2,v3)){
//if yes, we trust the test
return true;
} else {
//if no, we dont trust the test and check further
if (distanceSquarePointToSegment(pt,v1,v2) <= EPSILON_SQUARE){
return true;
}
if (distanceSquarePointToSegment(pt,v2,v3) <= EPSILON_SQUARE){
return true;
}
if (distanceSquarePointToSegment(pt,v3,v1) <= EPSILON_SQUARE){
return true;
}
//if everything fails, the point is not in the triangle
return false;
}
}

//https://graphics.stanford.edu/~mdfisher/Code/Engine/Plane.cpp.html
void
Project_point_on_plane(Pointf3 v1, Pointf3 n, Point &pt)
Expand Down
2 changes: 1 addition & 1 deletion xs/src/libslic3r/Geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ double rad2deg_dir(double angle);
double deg2rad(double angle);

double linint(double value, double oldmin, double oldmax, double newmin, double newmax);
bool Point_in_triangle(Pointf pt, Pointf v1, Pointf v2, Pointf v3);
bool Point_in_triangle(Pointf pt, Pointf v1, Pointf v2, Pointf v3, double epsilon);
void Project_point_on_plane(Pointf3 v1, Pointf3 n, Point &pt);
Point* Line_intersection(Point p1, Point p2, Point p3, Point p4);
float triangle_surface(Point p1, Point p2, Point p3);
Expand Down
13 changes: 3 additions & 10 deletions xs/src/libslic3r/LayerRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,27 +368,20 @@ LayerRegion::project_nonplanar_path(ExtrusionPath *path)
for (auto& surface : this->nonplanar_surfaces) {
float distance_to_top = surface.stats.max.z - this->layer()->print_z;
for(auto& facet : surface.mesh) {
//skip if point is outside of the bounding box of the triangle
if (unscale(point.x) < std::min({facet.second.vertex[0].x, facet.second.vertex[1].x, facet.second.vertex[2].x}) ||
unscale(point.x) > std::max({facet.second.vertex[0].x, facet.second.vertex[1].x, facet.second.vertex[2].x}) ||
unscale(point.y) < std::min({facet.second.vertex[0].y, facet.second.vertex[1].y, facet.second.vertex[2].y}) ||
unscale(point.y) > std::max({facet.second.vertex[0].y, facet.second.vertex[1].y, facet.second.vertex[2].y}))
{
continue;
}
//check if point is inside of Triangle
if (Slic3r::Geometry::Point_in_triangle(
Pointf(unscale(point.x),unscale(point.y)),
Pointf(facet.second.vertex[0].x, facet.second.vertex[0].y),
Pointf(facet.second.vertex[1].x, facet.second.vertex[1].y),
Pointf(facet.second.vertex[2].x, facet.second.vertex[2].y)))
Pointf(facet.second.vertex[2].x, facet.second.vertex[2].y),
0.1))
{
Slic3r::Geometry::Project_point_on_plane(Pointf3(facet.second.vertex[0].x,facet.second.vertex[0].y,facet.second.vertex[0].z),
Pointf3(facet.second.normal.x,facet.second.normal.y,facet.second.normal.z),
point);
//Shift down when on lower layer
point.z = point.z - scale_(distance_to_top);
//break;
break;
}
}
}
Expand Down

0 comments on commit fa0ffec

Please sign in to comment.