Skip to content

Commit

Permalink
improve projection of points onto mesh
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Jun 27, 2019
1 parent c5e400c commit 115ff01
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/Mod/MeshPart/App/CurveProjector.cpp
Expand Up @@ -854,6 +854,26 @@ void MeshProjection::projectOnMesh(const std::vector<Base::Vector3f>& pointsIn,
float fAvgLen = clAlg.GetAverageEdgeLength();
MeshFacetGrid cGrid(_rcMesh, 5.0f*fAvgLen);

// get all boundary points and edges of the mesh
std::vector<Base::Vector3f> boundaryPoints;
std::vector<MeshCore::MeshGeomEdge> boundaryEdges;

const MeshCore::MeshFacetArray& facets = _rcMesh.GetFacets();
const MeshCore::MeshPointArray& points = _rcMesh.GetPoints();
for (auto it : facets) {
for (int i=0; i<3; i++) {
if (!it.HasNeighbour(i)) {
boundaryPoints.push_back(points[it._aulPoints[i]]);

MeshCore::MeshGeomEdge edge;
edge._bBorder = true;
edge._aclPoints[0] = points[it._aulPoints[i]];
edge._aclPoints[1] = points[it._aulPoints[(i+1)%3]];
boundaryEdges.push_back(edge);
}
}
}

Base::SequencerLauncher seq( "Project points on mesh", pointsIn.size() );

for (auto it : pointsIn) {
Expand All @@ -869,6 +889,36 @@ void MeshProjection::projectOnMesh(const std::vector<Base::Vector3f>& pointsIn,
pointsOut.push_back(result);
}
}
else {
// go through the boundary points and check if the point can be directly projected
// onto one of them
auto boundaryPnt = std::find_if(boundaryPoints.begin(), boundaryPoints.end(),
[&it, &dir](const Base::Vector3f& pnt)->bool {
Base::Vector3f vec = pnt - it;
float angle = vec.GetAngle(dir);
return angle < 1e-6f;
});

if (boundaryPnt != boundaryPoints.end()) {
pointsOut.push_back(*boundaryPnt);
}
else {
// go through the boundary edges and check if the point can be directly projected
// onto one of them
Base::Vector3f result1, result2;
for (auto jt : boundaryEdges) {
jt.ClosestPointsToLine(it, dir, result1, result2);
float dot = (result1-jt._aclPoints[0]).Dot(result1-jt._aclPoints[1]);
//float distance = Base::Distance(result1, result2);
Base::Vector3f vec = result1 - it;
float angle = vec.GetAngle(dir);
if (dot <= 0 && angle < 1e-6f) {
pointsOut.push_back(result1);
break;
}
}
}
}

seq.next();
}
Expand Down

0 comments on commit 115ff01

Please sign in to comment.