+ extend Inventor builder, project curve on mesh
This commit is contained in:
parent
197aa0c85c
commit
02b84611b2
|
@ -440,6 +440,18 @@ void InventorBuilder::addPointSet(void)
|
||||||
result << Base::blanks(indent) << "PointSet { } " << std::endl;
|
result << Base::blanks(indent) << "PointSet { } " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an SoLineSet node after creating an SoCordinate3 node with
|
||||||
|
* beginPoints() and endPoints().
|
||||||
|
* @see startPoints()
|
||||||
|
* @see beginPoints()
|
||||||
|
* @see endPoints()
|
||||||
|
*/
|
||||||
|
void InventorBuilder::addLineSet(void)
|
||||||
|
{
|
||||||
|
result << Base::blanks(indent) << "LineSet { } " << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// text handling
|
// text handling
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,8 @@ public:
|
||||||
void endPoints(void);
|
void endPoints(void);
|
||||||
/// add an SoPointSet node
|
/// add an SoPointSet node
|
||||||
void addPointSet(void);
|
void addPointSet(void);
|
||||||
|
/// add an SoLineSet node
|
||||||
|
void addLineSet(void);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name Line/Direction handling */
|
/** @name Line/Direction handling */
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
# include <TopExp_Explorer.hxx>
|
# include <TopExp_Explorer.hxx>
|
||||||
# include <TopoDS.hxx>
|
# include <TopoDS.hxx>
|
||||||
# include <TopoDS_Edge.hxx>
|
# include <TopoDS_Edge.hxx>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Projection.h"
|
#include "Projection.h"
|
||||||
#include "MeshKernel.h"
|
#include "MeshKernel.h"
|
||||||
|
@ -54,6 +55,7 @@
|
||||||
using namespace MeshCore;
|
using namespace MeshCore;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef FC_USE_OCC
|
||||||
MeshProjection::MeshProjection(const MeshKernel& rMesh)
|
MeshProjection::MeshProjection(const MeshKernel& rMesh)
|
||||||
: _rcMesh(rMesh)
|
: _rcMesh(rMesh)
|
||||||
{
|
{
|
||||||
|
@ -262,3 +264,175 @@ void MeshProjection::projectEdgeToEdge( const TopoDS_Edge &aEdge, float fMaxDist
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
MeshProjection::MeshProjection(const MeshKernel& mesh)
|
||||||
|
: kernel(mesh)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshProjection::~MeshProjection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MeshProjection::bboxInsideRectangle(const Base::BoundBox3f& bbox,
|
||||||
|
const Base::Vector3f& p1,
|
||||||
|
const Base::Vector3f& p2,
|
||||||
|
const Base::Vector3f& view) const
|
||||||
|
{
|
||||||
|
Base::Vector3f dir(p2 - p1);
|
||||||
|
Base::Vector3f base(p1), normal(view % dir);
|
||||||
|
normal.Normalize();
|
||||||
|
|
||||||
|
if (bbox.IsCutPlane(base, normal)) {
|
||||||
|
dir.Normalize();
|
||||||
|
Base::Vector3f cnt(bbox.CalcCenter());
|
||||||
|
|
||||||
|
return (fabs(cnt.DistanceToPlane(p1, dir)) + fabs(cnt.DistanceToPlane(p2, dir))) <=
|
||||||
|
(bbox.CalcDiagonalLength() + (p2 - p1).Length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MeshProjection::isPointInsideDistance (const Base::Vector3f& p1,
|
||||||
|
const Base::Vector3f& p2,
|
||||||
|
const Base::Vector3f& pt) const
|
||||||
|
{
|
||||||
|
// project point on line
|
||||||
|
Base::Vector3f proj, dir(p2 - p1);
|
||||||
|
Base::Vector3f move(pt - p1);
|
||||||
|
proj.ProjToLine(move, dir);
|
||||||
|
proj = pt + proj;
|
||||||
|
return (((p1 - proj) * (p2 - proj)) < 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MeshProjection::connectLines(std::list< std::pair<Base::Vector3f, Base::Vector3f> >& cutLines,
|
||||||
|
const Base::Vector3f& startPoint, const Base::Vector3f& endPoint,
|
||||||
|
std::vector<Base::Vector3f>& polyline) const
|
||||||
|
{
|
||||||
|
const float fMaxDist = float(sqrt(FLOAT_MAX)); // max. length of a gap
|
||||||
|
const float fMinEps = 1.0e-4f;
|
||||||
|
|
||||||
|
polyline.clear();
|
||||||
|
polyline.push_back(startPoint);
|
||||||
|
|
||||||
|
Base::Vector3f curr(startPoint);
|
||||||
|
while ((curr != endPoint) && (!cutLines.empty())) {
|
||||||
|
std::list< std::pair<Base::Vector3f, Base::Vector3f> >::iterator it, pCurr = cutLines.end();
|
||||||
|
|
||||||
|
// get nearest line
|
||||||
|
float fMin = fMaxDist * fMaxDist;
|
||||||
|
|
||||||
|
bool bPos;
|
||||||
|
for (it = cutLines.begin(); it != cutLines.end(); ++it) {
|
||||||
|
float fD1 = Base::DistanceP2(curr, it->first);
|
||||||
|
float fD2 = Base::DistanceP2(curr, it->second);
|
||||||
|
if (std::min<float>(fD1, fD2) < fMin) {
|
||||||
|
pCurr = it;
|
||||||
|
bPos = fD1 < fD2;
|
||||||
|
fMin = std::min<float>(fD1, fD2);
|
||||||
|
if (fMin < fMinEps) // abort because next line already found
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCurr != cutLines.end()) {
|
||||||
|
if (bPos) {
|
||||||
|
if (fMin > fMinEps) // gap, insert point
|
||||||
|
polyline.push_back(pCurr->first);
|
||||||
|
polyline.push_back(pCurr->second);
|
||||||
|
curr = pCurr->second;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (fMin > fMinEps) // gap, insert point
|
||||||
|
polyline.push_back(pCurr->second);
|
||||||
|
polyline.push_back(pCurr->first);
|
||||||
|
curr = pCurr->first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false; // abort because no line was found
|
||||||
|
}
|
||||||
|
|
||||||
|
cutLines.erase(pCurr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MeshProjection::projectLineOnMesh(const MeshFacetGrid& grid,
|
||||||
|
const Base::Vector3f& v1, unsigned long f1,
|
||||||
|
const Base::Vector3f& v2, unsigned long f2,
|
||||||
|
const Base::Vector3f& vd,
|
||||||
|
std::vector<Base::Vector3f>& polyline)
|
||||||
|
{
|
||||||
|
Base::Vector3f dir(v2 - v1);
|
||||||
|
Base::Vector3f base(v1), normal(vd % dir);
|
||||||
|
normal.Normalize();
|
||||||
|
dir.Normalize();
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<unsigned long> facets;
|
||||||
|
|
||||||
|
// special case: start and endpoint inside same facet
|
||||||
|
if (f1 == f2) {
|
||||||
|
polyline.push_back(v1);
|
||||||
|
polyline.push_back(v2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cut all facets between the two endpoints
|
||||||
|
MeshGridIterator gridIter(grid);
|
||||||
|
for (gridIter.Init(); gridIter.More(); gridIter.Next()) {
|
||||||
|
// bbox cuts plane
|
||||||
|
if (bboxInsideRectangle(gridIter.GetBoundBox(), v1, v2, vd))
|
||||||
|
gridIter.GetElements(facets);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(facets.begin(), facets.end());
|
||||||
|
facets.erase(std::unique(facets.begin(), facets.end()), facets.end());
|
||||||
|
|
||||||
|
// cut all facets with plane
|
||||||
|
std::list< std::pair<Base::Vector3f, Base::Vector3f> > cutLine;
|
||||||
|
unsigned long start = 0, end = 0;
|
||||||
|
for (std::vector<unsigned long>::iterator it = facets.begin(); it != facets.end(); ++it) {
|
||||||
|
Base::Vector3f e1, e2;
|
||||||
|
MeshGeomFacet tria = kernel.GetFacet(*it);
|
||||||
|
if (bboxInsideRectangle(tria.GetBoundBox(), v1, v2, vd)) {
|
||||||
|
if (tria.IntersectWithPlane(base, normal, e1, e2)) {
|
||||||
|
if ((*it != f1) && (*it != f2)) {
|
||||||
|
// inside cut line
|
||||||
|
if ((isPointInsideDistance(v1, v2, e1) == false) ||
|
||||||
|
(isPointInsideDistance(v1, v2, e2) == false)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(e1, e2));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (*it == f1) { // start facet
|
||||||
|
if (((e2 - v1) * dir) > 0.0f)
|
||||||
|
cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v1, e2));
|
||||||
|
else
|
||||||
|
cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v1, e1));
|
||||||
|
|
||||||
|
start = it - facets.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*it == f2) { // end facet
|
||||||
|
if (((e2 - v2) * -dir) > 0.0f)
|
||||||
|
cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v2, e2));
|
||||||
|
else
|
||||||
|
cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v2, e1));
|
||||||
|
|
||||||
|
end = it - facets.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectLines(cutLine, v1, v2, polyline);
|
||||||
|
}
|
||||||
|
|
|
@ -25,13 +25,15 @@
|
||||||
#define MESH_PROJECTION_H
|
#define MESH_PROJECTION_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <Base/BoundBox.h>
|
||||||
#include <Base/Vector3D.h>
|
#include <Base/Vector3D.h>
|
||||||
#ifdef FC_USE_OCC
|
|
||||||
using Base::Vector3f;
|
using Base::Vector3f;
|
||||||
|
|
||||||
|
#ifdef FC_USE_OCC
|
||||||
class TopoDS_Edge;
|
class TopoDS_Edge;
|
||||||
class TopoDS_Shape;
|
class TopoDS_Shape;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace MeshCore
|
namespace MeshCore
|
||||||
{
|
{
|
||||||
|
@ -40,6 +42,26 @@ class MeshFacetGrid;
|
||||||
class MeshKernel;
|
class MeshKernel;
|
||||||
class MeshGeomFacet;
|
class MeshGeomFacet;
|
||||||
|
|
||||||
|
class MeshExport MeshProjection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MeshProjection(const MeshKernel&);
|
||||||
|
~MeshProjection();
|
||||||
|
|
||||||
|
bool projectLineOnMesh(const MeshFacetGrid& grid, const Base::Vector3f& p1, unsigned long f1,
|
||||||
|
const Base::Vector3f& p2, unsigned long f2, const Base::Vector3f& view,
|
||||||
|
std::vector<Base::Vector3f>& polyline);
|
||||||
|
protected:
|
||||||
|
bool bboxInsideRectangle (const Base::BoundBox3f& bbox, const Base::Vector3f& p1, const Base::Vector3f& p2, const Base::Vector3f& view) const;
|
||||||
|
bool isPointInsideDistance (const Base::Vector3f& p1, const Base::Vector3f& p2, const Base::Vector3f& pt) const;
|
||||||
|
bool connectLines(std::list< std::pair<Base::Vector3f, Base::Vector3f> >& cutLines, const Base::Vector3f& startPoint,
|
||||||
|
const Base::Vector3f& endPoint, std::vector<Base::Vector3f>& polyline) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const MeshKernel& kernel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef FC_USE_OCC
|
||||||
/// Helper class
|
/// Helper class
|
||||||
struct SplitEdge
|
struct SplitEdge
|
||||||
{
|
{
|
||||||
|
@ -78,8 +100,8 @@ protected:
|
||||||
private:
|
private:
|
||||||
const MeshKernel& _rcMesh;
|
const MeshKernel& _rcMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace MeshCore
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
} // namespace MeshCore
|
||||||
|
|
||||||
#endif // MESH_PROJECTION_H
|
#endif // MESH_PROJECTION_H
|
||||||
|
|
Loading…
Reference in New Issue
Block a user