determine edge parameters where curve point will be projected onto a mesh edge

This commit is contained in:
wmayer
2019-06-11 13:25:52 +02:00
parent c883cd6ccd
commit fbafd698ae
4 changed files with 135 additions and 6 deletions

View File

@@ -29,6 +29,9 @@
# include <Bnd_Box.hxx>
# include <BndLib_Add3dCurve.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <BRepBuilderAPI_MakeVertex.hxx>
# include <BRepExtrema_DistShapeShape.hxx>
# include <GCPnts_AbscissaPoint.hxx>
# include <GCPnts_UniformDeflection.hxx>
# include <GCPnts_UniformAbscissa.hxx>
# include <gp_Pln.hxx>
@@ -39,6 +42,7 @@
# include <Geom_Plane.hxx>
# include <BRep_Tool.hxx>
# include <GeomAPI_IntCS.hxx>
# include <Standard_Failure.hxx>
#endif
@@ -733,6 +737,85 @@ void MeshProjection::splitMeshByShape ( const TopoDS_Shape &aShape, float fMaxDi
str.close();
}
bool MeshProjection::findIntersection(const Edge& edgeSegm, const Edge& meshEdge,
const Base::Vector3f& dir, Base::Vector3f& res) const
{
Base::Vector3f planeNormal;
planeNormal = dir.Cross(edgeSegm.cPt2 - edgeSegm.cPt1);
float dist1 = planeNormal.Dot(meshEdge.cPt1 - edgeSegm.cPt1);
float dist2 = planeNormal.Dot(meshEdge.cPt2 - edgeSegm.cPt1);
if (dist1 * dist2 < 0) {
planeNormal = dir.Cross(meshEdge.cPt2 - meshEdge.cPt1);
dist1 = planeNormal.Dot(edgeSegm.cPt1 - meshEdge.cPt1);
dist2 = planeNormal.Dot(edgeSegm.cPt2 - meshEdge.cPt1);
if (dist1 * dist2 < 0) {
// intersection detected
float t = planeNormal.Dot(meshEdge.cPt1 - edgeSegm.cPt1) /
planeNormal.Dot(edgeSegm.cPt2 - edgeSegm.cPt1);
res = edgeSegm.cPt1 * (1-t) + edgeSegm.cPt2 * t;
return true;
}
}
return false;
}
void MeshProjection::findSectionParameters(const TopoDS_Edge& edge, const Base::Vector3f& dir, std::set<double>& parameters) const
{
MeshAlgorithm clAlg( _rcMesh );
float fAvgLen = clAlg.GetAverageEdgeLength();
BRepAdaptor_Curve adapt(edge);
double edgeLen = GCPnts_AbscissaPoint::Length(adapt, Precision::Confusion());
std::vector<Base::Vector3f> polyline;
discretize(edge, polyline, std::max<size_t>(10, static_cast<size_t>(edgeLen/fAvgLen)));
if (polyline.empty())
return;
std::vector<Edge> lines;
Base::Vector3f start = polyline.front();
for (auto it = polyline.begin()+1; it != polyline.end(); ++it) {
Edge line;
line.cPt1 = start;
line.cPt2 = *it;
start = line.cPt2;
lines.push_back(line);
}
const MeshCore::MeshFacetArray& facets = _rcMesh.GetFacets();
const MeshCore::MeshPointArray& points = _rcMesh.GetPoints();
Base::Vector3f res;
for (auto it : facets) {
for (int i=0; i<3; i++) {
Base::Vector3f pt1 = points[it._aulPoints[i]];
Base::Vector3f pt2 = points[it._aulPoints[(i+1)%3]];
Edge line;
line.cPt1 = pt1;
line.cPt2 = pt2;
for (auto jt : lines) {
if (findIntersection(jt, line, dir, res)) {
try {
BRepBuilderAPI_MakeVertex aBuilder(gp_Pnt(res.x,res.y,res.z));
BRepExtrema_DistShapeShape extss(aBuilder.Vertex(), edge);
if (extss.NbSolution() == 1) {
Standard_Real par;
//gp_pnt pnt = extss.PointOnShape2(1);
//Standard_Real par = BRep_Tool::Parameter(aBuilder.Vertex(), edge);
extss.ParOnEdgeS2(1, par);
parameters.insert(par);
break;
}
}
catch (const Standard_Failure&) {
// ignore
}
}
}
}
}
}
void MeshProjection::projectToMesh (const TopoDS_Shape &aShape, float fMaxDist, std::vector<PolyLine>& rPolyLines) const
{
// calculate the average edge length and create a grid