+ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user