add method to project shape on mesh
This commit is contained in:
@@ -63,7 +63,9 @@ public:
|
||||
);
|
||||
add_varargs_method("projectShapeOnMesh",&Module::projectShapeOnMesh,
|
||||
"Projects a shape onto a mesh with a given maximum distance\n"
|
||||
"projectShapeOnMesh(shape, mesh, float) -> polygon"
|
||||
"projectShapeOnMesh(Shape, Mesh, float) -> polygon\n"
|
||||
"or projects the shape in a given direction\n"
|
||||
"projectShapeOnMesh(Shape, Mesh, Vector) -> list of polygons"
|
||||
);
|
||||
add_varargs_method("wireFromSegment",&Module::wireFromSegment,
|
||||
"Create wire(s) from boundary of segment\n"
|
||||
@@ -205,26 +207,61 @@ private:
|
||||
{
|
||||
PyObject *s, *m;
|
||||
double maxDist;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!O!d", &Part::TopoShapePy::Type, &s,
|
||||
&Mesh::MeshPy::Type, &m,
|
||||
&maxDist))
|
||||
throw Py::Exception();
|
||||
TopoDS_Shape shape = static_cast<Part::TopoShapePy*>(s)->getTopoShapePtr()->getShape();
|
||||
const Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
|
||||
MeshCore::MeshKernel kernel(mesh->getKernel());
|
||||
kernel.Transform(mesh->getTransform());
|
||||
if (PyArg_ParseTuple(args.ptr(), "O!O!d", &Part::TopoShapePy::Type, &s,
|
||||
&Mesh::MeshPy::Type, &m,
|
||||
&maxDist)) {
|
||||
TopoDS_Shape shape = static_cast<Part::TopoShapePy*>(s)->getTopoShapePtr()->getShape();
|
||||
const Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
|
||||
MeshCore::MeshKernel kernel(mesh->getKernel());
|
||||
kernel.Transform(mesh->getTransform());
|
||||
|
||||
MeshProjection proj(kernel);
|
||||
std::vector<MeshProjection::SplitEdge> rSplitEdges;
|
||||
proj.projectToMesh(shape, maxDist, rSplitEdges);
|
||||
MeshProjection proj(kernel);
|
||||
std::vector<MeshProjection::PolyLine> polylines;
|
||||
proj.projectToMesh(shape, maxDist, polylines);
|
||||
|
||||
Py::List list;
|
||||
for (auto it : rSplitEdges) {
|
||||
Py::Vector v(it.cPt);
|
||||
list.append(v);
|
||||
Py::List list;
|
||||
for (auto it : polylines) {
|
||||
Py::List poly;
|
||||
for (auto jt : it.points) {
|
||||
Py::Vector v(jt);
|
||||
poly.append(v);
|
||||
}
|
||||
list.append(poly);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
return list;
|
||||
PyErr_Clear();
|
||||
PyObject *v;
|
||||
if (PyArg_ParseTuple(args.ptr(), "O!O!O!", &Part::TopoShapePy::Type, &s,
|
||||
&Mesh::MeshPy::Type, &m,
|
||||
&Base::VectorPy::Type, &v)) {
|
||||
TopoDS_Shape shape = static_cast<Part::TopoShapePy*>(s)->getTopoShapePtr()->getShape();
|
||||
const Mesh::MeshObject* mesh = static_cast<Mesh::MeshPy*>(m)->getMeshObjectPtr();
|
||||
Base::Vector3d* vec = static_cast<Base::VectorPy*>(v)->getVectorPtr();
|
||||
Base::Vector3f dir = Base::convertTo<Base::Vector3f>(*vec);
|
||||
|
||||
MeshCore::MeshKernel kernel(mesh->getKernel());
|
||||
kernel.Transform(mesh->getTransform());
|
||||
|
||||
MeshProjection proj(kernel);
|
||||
std::vector<MeshProjection::PolyLine> polylines;
|
||||
proj.projectParallelToMesh(shape, dir, polylines);
|
||||
Py::List list;
|
||||
for (auto it : polylines) {
|
||||
Py::List poly;
|
||||
for (auto jt : it.points) {
|
||||
Py::Vector v(jt);
|
||||
poly.append(v);
|
||||
}
|
||||
list.append(poly);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
throw Py::TypeError("Expected arguments are: Shape, Mesh, float or Vector");
|
||||
}
|
||||
Py::Object wireFromSegment(const Py::Tuple& args)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <Mod/Mesh/App/Core/MeshKernel.h>
|
||||
#include <Mod/Mesh/App/Core/Iterator.h>
|
||||
#include <Mod/Mesh/App/Core/Algorithm.h>
|
||||
#include <Mod/Mesh/App/Core/Projection.h>
|
||||
#include <Mod/Mesh/App/Core/Grid.h>
|
||||
#include <Mod/Mesh/App/Mesh.h>
|
||||
|
||||
@@ -57,10 +58,12 @@
|
||||
|
||||
|
||||
using namespace MeshPart;
|
||||
using namespace MeshCore;
|
||||
|
||||
|
||||
|
||||
using MeshCore::MeshKernel;
|
||||
using MeshCore::MeshFacetIterator;
|
||||
using MeshCore::MeshPointIterator;
|
||||
using MeshCore::MeshAlgorithm;
|
||||
using MeshCore::MeshFacetGrid;
|
||||
using MeshCore::MeshFacet;
|
||||
|
||||
CurveProjector::CurveProjector(const TopoDS_Shape &aShape, const MeshKernel &pMesh)
|
||||
: _Shape(aShape), _Mesh(pMesh)
|
||||
@@ -685,21 +688,39 @@ MeshProjection::~MeshProjection()
|
||||
{
|
||||
}
|
||||
|
||||
void MeshProjection::discretize(const TopoDS_Edge& aEdge, std::vector<Base::Vector3f>& polyline) const
|
||||
{
|
||||
BRepAdaptor_Curve clCurve(aEdge);
|
||||
|
||||
Standard_Real fFirst = clCurve.FirstParameter();
|
||||
Standard_Real fLast = clCurve.LastParameter();
|
||||
|
||||
GCPnts_UniformDeflection clDefl(clCurve, 0.01f, fFirst, fLast);
|
||||
if (clDefl.IsDone() == Standard_True) {
|
||||
Standard_Integer nNbPoints = clDefl.NbPoints();
|
||||
for (Standard_Integer i = 1; i <= nNbPoints; i++) {
|
||||
gp_Pnt gpPt = clCurve.Value(clDefl.Parameter(i));
|
||||
polyline.push_back( Base::Vector3f( (float)gpPt.X(), (float)gpPt.Y(), (float)gpPt.Z() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeshProjection::splitMeshByShape ( const TopoDS_Shape &aShape, float fMaxDist ) const
|
||||
{
|
||||
std::vector<SplitEdge> cSplitEdges;
|
||||
projectToMesh( aShape, fMaxDist, cSplitEdges );
|
||||
std::vector<PolyLine> rPolyLines;
|
||||
projectToMesh( aShape, fMaxDist, rPolyLines );
|
||||
|
||||
std::ofstream str("output.asc", std::ios::out | std::ios::binary);
|
||||
str.precision(4);
|
||||
str.setf(std::ios::fixed | std::ios::showpoint);
|
||||
for (std::vector<SplitEdge>::const_iterator it = cSplitEdges.begin();it!=cSplitEdges.end();++it) {
|
||||
str << it->cPt.x << " " << it->cPt.y << " " << it->cPt.z << std::endl;
|
||||
for (std::vector<PolyLine>::const_iterator it = rPolyLines.begin();it!=rPolyLines.end();++it) {
|
||||
for (std::vector<Base::Vector3f>::const_iterator jt = it->points.begin();jt != it->points.end();++jt)
|
||||
str << jt->x << " " << jt->y << " " << jt->z << std::endl;
|
||||
}
|
||||
str.close();
|
||||
}
|
||||
|
||||
void MeshProjection::projectToMesh ( const TopoDS_Shape &aShape, float fMaxDist, std::vector<SplitEdge>& rSplitEdges ) const
|
||||
void MeshProjection::projectToMesh (const TopoDS_Shape &aShape, float fMaxDist, std::vector<PolyLine>& rPolyLines) const
|
||||
{
|
||||
// calculate the average edge length and create a grid
|
||||
MeshAlgorithm clAlg( _rcMesh );
|
||||
@@ -707,7 +728,6 @@ void MeshProjection::projectToMesh ( const TopoDS_Shape &aShape, float fMaxDist,
|
||||
MeshFacetGrid cGrid( _rcMesh, 5.0f*fAvgLen );
|
||||
|
||||
TopExp_Explorer Ex;
|
||||
TopoDS_Shape Edge;
|
||||
|
||||
int iCnt=0;
|
||||
for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next())
|
||||
@@ -717,7 +737,65 @@ void MeshProjection::projectToMesh ( const TopoDS_Shape &aShape, float fMaxDist,
|
||||
|
||||
for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
|
||||
const TopoDS_Edge& aEdge = TopoDS::Edge(Ex.Current());
|
||||
projectEdgeToEdge( aEdge, fMaxDist, cGrid, rSplitEdges );
|
||||
std::vector<SplitEdge> rSplitEdges;
|
||||
projectEdgeToEdge(aEdge, fMaxDist, cGrid, rSplitEdges);
|
||||
PolyLine polyline;
|
||||
polyline.points.reserve(rSplitEdges.size());
|
||||
for (auto it : rSplitEdges)
|
||||
polyline.points.push_back(it.cPt);
|
||||
rPolyLines.push_back(polyline);
|
||||
seq.next();
|
||||
}
|
||||
}
|
||||
|
||||
void MeshProjection::projectParallelToMesh (const TopoDS_Shape &aShape, const Base::Vector3f& dir, std::vector<PolyLine>& rPolyLines) const
|
||||
{
|
||||
// calculate the average edge length and create a grid
|
||||
MeshAlgorithm clAlg(_rcMesh);
|
||||
float fAvgLen = clAlg.GetAverageEdgeLength();
|
||||
MeshFacetGrid cGrid(_rcMesh, 5.0f*fAvgLen);
|
||||
TopExp_Explorer Ex;
|
||||
|
||||
int iCnt=0;
|
||||
for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next())
|
||||
iCnt++;
|
||||
|
||||
Base::SequencerLauncher seq( "Project curve on mesh", iCnt );
|
||||
|
||||
for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
|
||||
const TopoDS_Edge& aEdge = TopoDS::Edge(Ex.Current());
|
||||
std::vector<Base::Vector3f> points;
|
||||
discretize(aEdge, points);
|
||||
|
||||
typedef std::pair<Base::Vector3f, unsigned long> HitPoint;
|
||||
std::vector<HitPoint> hitPoints;
|
||||
typedef std::pair<HitPoint, HitPoint> HitPoints;
|
||||
std::vector<HitPoints> hitPointPairs;
|
||||
for (auto it : points) {
|
||||
Base::Vector3f result;
|
||||
unsigned long index;
|
||||
if (clAlg.NearestFacetOnRay(it, dir, cGrid, result, index)) {
|
||||
hitPoints.push_back(std::make_pair(result, index));
|
||||
|
||||
if (hitPoints.size() > 1) {
|
||||
HitPoint p1 = hitPoints[hitPoints.size()-2];
|
||||
HitPoint p2 = hitPoints[hitPoints.size()-1];
|
||||
hitPointPairs.push_back(std::make_pair(p1, p2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MeshCore::MeshProjection meshProjection(_rcMesh);
|
||||
PolyLine polyline;
|
||||
for (auto it : hitPointPairs) {
|
||||
points.clear();
|
||||
if (meshProjection.projectLineOnMesh(cGrid, it.first.first, it.first.second,
|
||||
it.second.first, it.second.second, dir, points)) {
|
||||
polyline.points.insert(polyline.points.end(), points.begin(), points.end());
|
||||
}
|
||||
}
|
||||
rPolyLines.push_back(polyline);
|
||||
|
||||
seq.next();
|
||||
}
|
||||
}
|
||||
@@ -731,20 +809,7 @@ void MeshProjection::projectEdgeToEdge( const TopoDS_Edge &aEdge, float fMaxDist
|
||||
|
||||
// search the facets in the local area of the curve
|
||||
std::vector<Base::Vector3f> acPolyLine;
|
||||
|
||||
BRepAdaptor_Curve clCurve( aEdge );
|
||||
|
||||
Standard_Real fFirst = clCurve.FirstParameter();
|
||||
Standard_Real fLast = clCurve.LastParameter();
|
||||
|
||||
GCPnts_UniformDeflection clDefl(clCurve, 0.01f, fFirst, fLast);
|
||||
if (clDefl.IsDone() == Standard_True) {
|
||||
Standard_Integer nNbPoints = clDefl.NbPoints();
|
||||
for (Standard_Integer i = 1; i <= nNbPoints; i++) {
|
||||
gp_Pnt gpPt = clCurve.Value(clDefl.Parameter(i));
|
||||
acPolyLine.push_back( Base::Vector3f( (float)gpPt.X(), (float)gpPt.Y(), (float)gpPt.Z() ) );
|
||||
}
|
||||
}
|
||||
discretize(aEdge, acPolyLine);
|
||||
|
||||
MeshAlgorithm(_rcMesh).SearchFacetsFromPolyline( acPolyLine, fMaxDist, rGrid, auFInds);
|
||||
// remove duplicated elements
|
||||
@@ -764,7 +829,9 @@ void MeshProjection::projectEdgeToEdge( const TopoDS_Edge &aEdge, float fMaxDist
|
||||
// sort intersection points by parameter
|
||||
std::map<Standard_Real, SplitEdge> rParamSplitEdges;
|
||||
|
||||
// Standard_Real fFirst, fLast;
|
||||
BRepAdaptor_Curve clCurve(aEdge);
|
||||
Standard_Real fFirst = clCurve.FirstParameter();
|
||||
Standard_Real fLast = clCurve.LastParameter();
|
||||
Handle(Geom_Curve) hCurve = BRep_Tool::Curve( aEdge,fFirst,fLast );
|
||||
|
||||
// bounds of curve
|
||||
|
||||
@@ -167,8 +167,12 @@ public:
|
||||
/// Helper class
|
||||
struct SplitEdge
|
||||
{
|
||||
unsigned long uE0, uE1; /**< start and endpoint of an edge */
|
||||
Base::Vector3f cPt; /**< Point on edge (\a uE0, \a uE1) */
|
||||
unsigned long uE0, uE1; /**< start and endpoint of an edge */
|
||||
Base::Vector3f cPt; /**< Point on edge (\a uE0, \a uE1) */
|
||||
};
|
||||
struct PolyLine
|
||||
{
|
||||
std::vector<Base::Vector3f> points;
|
||||
};
|
||||
|
||||
/// Construction
|
||||
@@ -176,12 +180,17 @@ public:
|
||||
/// Destruction
|
||||
~MeshProjection();
|
||||
|
||||
void discretize(const TopoDS_Edge& aEdge, std::vector<Base::Vector3f>& polyline) const;
|
||||
/**
|
||||
* Searches all edges that intersect with the projected curve \a aShape. Therefore \a aShape must
|
||||
* contain shapes of type TopoDS_Edge, other shape types are ignored. A possible solution is
|
||||
* taken if the distance between the curve point and the projected point is <= \a fMaxDist.
|
||||
*/
|
||||
void projectToMesh (const TopoDS_Shape &aShape, float fMaxDist, std::vector<SplitEdge>& rSplitEdges) const;
|
||||
void projectToMesh (const TopoDS_Shape &aShape, float fMaxDist, std::vector<PolyLine>& rPolyLines) const;
|
||||
/**
|
||||
* Project all edges of the shape onto the mesh using parallel projection.
|
||||
*/
|
||||
void projectParallelToMesh (const TopoDS_Shape &aShape, const Base::Vector3f& dir, std::vector<PolyLine>& rPolyLines) const;
|
||||
/**
|
||||
* Cuts the mesh at the curve defined by \a aShape. This method call @ref projectToMesh() to get the
|
||||
* split the facet at the found points. @see projectToMesh() for more details.
|
||||
|
||||
Reference in New Issue
Block a user