+ extend Inventor builder, project curve on mesh

This commit is contained in:
wmayer 2015-04-22 17:15:49 +02:00
parent 197aa0c85c
commit 02b84611b2
4 changed files with 223 additions and 13 deletions

View File

@ -440,6 +440,18 @@ void InventorBuilder::addPointSet(void)
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
@ -591,9 +603,9 @@ void InventorBuilder::addIndexedFaceSet(const std::vector<Vector3f>& points, con
if (points.empty() || indices.size() < 4)
return;
result << " Separator { " << std::endl
<< " ShapeHints {" << std::endl
<< " creaseAngle " << crease << std::endl
<< " }" << std::endl
<< " ShapeHints {" << std::endl
<< " creaseAngle " << crease << std::endl
<< " }" << std::endl
<< " Coordinate3 { " << std::endl
<< " point [ ";
std::vector<Vector3f>::const_iterator it_last_p = points.end()-1;
@ -731,11 +743,11 @@ void InventorBuilder::addNurbsSurface(const std::vector<Base::Vector3f>& control
}
void InventorBuilder::addCylinder(float radius, float height)
{
result << Base::blanks(indent) << "Cylinder {\n"
<< Base::blanks(indent) << " radius " << radius << "\n"
<< Base::blanks(indent) << " height " << height << "\n"
<< Base::blanks(indent) << " parts (SIDES | TOP | BOTTOM)\n"
{
result << Base::blanks(indent) << "Cylinder {\n"
<< Base::blanks(indent) << " radius " << radius << "\n"
<< Base::blanks(indent) << " height " << height << "\n"
<< Base::blanks(indent) << " parts (SIDES | TOP | BOTTOM)\n"
<< Base::blanks(indent) << "}\n";
}
@ -796,4 +808,4 @@ void InventorBuilder::addTransformation(const Vector3f& translation, const Vecto
<< rotationaxis.x << " " << rotationaxis.y << " " << rotationaxis.z
<< " " << fAngle << std::endl;
result << Base::blanks(indent) << "}" << std::endl;
}
}

View File

@ -166,6 +166,8 @@ public:
void endPoints(void);
/// add an SoPointSet node
void addPointSet(void);
/// add an SoLineSet node
void addLineSet(void);
//@}
/** @name Line/Direction handling */

View File

@ -39,6 +39,7 @@
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Edge.hxx>
#endif
#include "Projection.h"
#include "MeshKernel.h"
@ -54,6 +55,7 @@
using namespace MeshCore;
#ifdef FC_USE_OCC
MeshProjection::MeshProjection(const MeshKernel& rMesh)
: _rcMesh(rMesh)
{
@ -262,3 +264,175 @@ void MeshProjection::projectEdgeToEdge( const TopoDS_Edge &aEdge, float fMaxDist
}
#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);
}

View File

@ -25,13 +25,15 @@
#define MESH_PROJECTION_H
#include <vector>
#include <Base/BoundBox.h>
#include <Base/Vector3D.h>
#ifdef FC_USE_OCC
using Base::Vector3f;
#ifdef FC_USE_OCC
class TopoDS_Edge;
class TopoDS_Shape;
#endif
namespace MeshCore
{
@ -40,6 +42,26 @@ class MeshFacetGrid;
class MeshKernel;
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
struct SplitEdge
{
@ -78,8 +100,8 @@ protected:
private:
const MeshKernel& _rcMesh;
};
} // namespace MeshCore
#endif
} // namespace MeshCore
#endif // MESH_PROJECTION_H