mesh segmentation algorithm for surfaces
This commit is contained in:
@@ -912,6 +912,55 @@ void CylinderFit::ProjectToCylinder()
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
SphereFit::SphereFit()
|
||||
: _vCenter(0,0,0)
|
||||
, _fRadius(0)
|
||||
{
|
||||
}
|
||||
|
||||
SphereFit::~SphereFit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
float SphereFit::GetRadius() const
|
||||
{
|
||||
if (_bIsFitted)
|
||||
return _fRadius;
|
||||
else
|
||||
return FLOAT_MAX;
|
||||
}
|
||||
|
||||
Base::Vector3f SphereFit::GetCenter() const
|
||||
{
|
||||
if (_bIsFitted)
|
||||
return _vCenter;
|
||||
else
|
||||
return Base::Vector3f();
|
||||
}
|
||||
|
||||
float SphereFit::Fit()
|
||||
{
|
||||
return FLOAT_MAX;
|
||||
}
|
||||
|
||||
float SphereFit::GetDistanceToSphere(const Base::Vector3f &) const
|
||||
{
|
||||
return FLOAT_MAX;
|
||||
}
|
||||
|
||||
float SphereFit::GetStdDeviation() const
|
||||
{
|
||||
return FLOAT_MAX;
|
||||
}
|
||||
|
||||
void SphereFit::ProjectToSphere()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
||||
PolynomialFit::PolynomialFit()
|
||||
{
|
||||
for (int i=0; i<9; i++)
|
||||
|
||||
@@ -406,6 +406,48 @@ protected:
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Approximation of a sphere into a given set of points.
|
||||
*/
|
||||
class MeshExport SphereFit : public Approximation
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construction
|
||||
*/
|
||||
SphereFit();
|
||||
/**
|
||||
* Destruction
|
||||
*/
|
||||
virtual ~SphereFit();
|
||||
float GetRadius() const;
|
||||
Base::Vector3f GetCenter() const;
|
||||
/**
|
||||
* Fit a sphere into the given points. If the fit fails FLOAT_MAX is returned.
|
||||
*/
|
||||
float Fit();
|
||||
/**
|
||||
* Returns the distance from the point \a rcPoint to the fitted sphere. If Fit() has not been
|
||||
* called FLOAT_MAX is returned.
|
||||
*/
|
||||
float GetDistanceToSphere(const Base::Vector3f &rcPoint) const;
|
||||
/**
|
||||
* Returns the standard deviation from the points to the fitted sphere. If Fit() has not been
|
||||
* called FLOAT_MAX is returned.
|
||||
*/
|
||||
float GetStdDeviation() const;
|
||||
/**
|
||||
* Projects the points onto the fitted sphere.
|
||||
*/
|
||||
void ProjectToSphere();
|
||||
|
||||
protected:
|
||||
Base::Vector3f _vCenter; /**< Center of the sphere. */
|
||||
float _fRadius; /**< Radius of the cylinder. */
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Helper class for the quadric fit. Includes the
|
||||
* partial derivates of the quadric and serves for
|
||||
|
||||
@@ -218,8 +218,10 @@ void CylinderSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria)
|
||||
|
||||
bool CylinderSurfaceFit::TestTriangle(const MeshGeomFacet& tria) const
|
||||
{
|
||||
// This is to filter out triangles whose points lie on the cylinder and
|
||||
// that whose normals are more or less parallel to the cylinder axis
|
||||
float dot = axis.Dot(tria.GetNormal());
|
||||
return fabs(dot) < 0.01f;
|
||||
return fabs(dot) < 0.5f;
|
||||
}
|
||||
|
||||
bool CylinderSurfaceFit::Done() const
|
||||
@@ -258,6 +260,7 @@ float CylinderSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
|
||||
// --------------------------------------------------------
|
||||
|
||||
SphereSurfaceFit::SphereSurfaceFit()
|
||||
: fitter(new SphereFit)
|
||||
{
|
||||
center.Set(0,0,0);
|
||||
radius = FLOAT_MAX;
|
||||
@@ -266,25 +269,36 @@ SphereSurfaceFit::SphereSurfaceFit()
|
||||
SphereSurfaceFit::SphereSurfaceFit(const Base::Vector3f& c, float r)
|
||||
: center(c)
|
||||
, radius(r)
|
||||
, fitter(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SphereSurfaceFit::~SphereSurfaceFit()
|
||||
{
|
||||
delete fitter;
|
||||
}
|
||||
|
||||
void SphereSurfaceFit::Initialize(const MeshCore::MeshGeomFacet& tria)
|
||||
{
|
||||
//FIXME
|
||||
if (fitter) {
|
||||
fitter->Clear();
|
||||
fitter->AddPoint(tria._aclPoints[0]);
|
||||
fitter->AddPoint(tria._aclPoints[1]);
|
||||
fitter->AddPoint(tria._aclPoints[2]);
|
||||
}
|
||||
}
|
||||
|
||||
void SphereSurfaceFit::AddTriangle(const MeshCore::MeshGeomFacet& tria)
|
||||
{
|
||||
//FIXME
|
||||
if (fitter) {
|
||||
fitter->AddPoint(tria._aclPoints[0]);
|
||||
fitter->AddPoint(tria._aclPoints[1]);
|
||||
fitter->AddPoint(tria._aclPoints[2]);
|
||||
}
|
||||
}
|
||||
|
||||
bool SphereSurfaceFit::TestTriangle(const MeshGeomFacet& tria) const
|
||||
bool SphereSurfaceFit::TestTriangle(const MeshGeomFacet&) const
|
||||
{
|
||||
// Already handled by GetDistanceToSurface
|
||||
return true;
|
||||
@@ -292,14 +306,24 @@ bool SphereSurfaceFit::TestTriangle(const MeshGeomFacet& tria) const
|
||||
|
||||
bool SphereSurfaceFit::Done() const
|
||||
{
|
||||
//FIXME
|
||||
if (fitter) {
|
||||
return fitter->Done();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
float SphereSurfaceFit::Fit()
|
||||
{
|
||||
//FIXME
|
||||
return 0;
|
||||
if (!fitter)
|
||||
return 0;
|
||||
|
||||
float fit = fitter->Fit();
|
||||
if (fit < FLOAT_MAX) {
|
||||
center = fitter->GetCenter();
|
||||
radius = fitter->GetRadius();
|
||||
}
|
||||
return fit;
|
||||
}
|
||||
|
||||
float SphereSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace MeshCore {
|
||||
|
||||
class PlaneFit;
|
||||
class CylinderFit;
|
||||
class SphereFit;
|
||||
class MeshFacet;
|
||||
typedef std::vector<unsigned long> MeshSegment;
|
||||
|
||||
@@ -89,6 +90,7 @@ class MeshExport AbstractSurfaceFit
|
||||
public:
|
||||
AbstractSurfaceFit(){}
|
||||
virtual ~AbstractSurfaceFit(){}
|
||||
virtual const char* GetType() const = 0;
|
||||
virtual void Initialize(const MeshGeomFacet&) = 0;
|
||||
virtual bool TestTriangle(const MeshGeomFacet&) const = 0;
|
||||
virtual void AddTriangle(const MeshGeomFacet&) = 0;
|
||||
@@ -103,6 +105,7 @@ public:
|
||||
PlaneSurfaceFit();
|
||||
PlaneSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& n);
|
||||
~PlaneSurfaceFit();
|
||||
const char* GetType() const { return "Plane"; }
|
||||
void Initialize(const MeshGeomFacet&);
|
||||
bool TestTriangle(const MeshGeomFacet&) const;
|
||||
void AddTriangle(const MeshGeomFacet&);
|
||||
@@ -122,6 +125,7 @@ public:
|
||||
CylinderSurfaceFit();
|
||||
CylinderSurfaceFit(const Base::Vector3f& b, const Base::Vector3f& a, float r);
|
||||
~CylinderSurfaceFit();
|
||||
const char* GetType() const { return "Cylinder"; }
|
||||
void Initialize(const MeshGeomFacet&);
|
||||
bool TestTriangle(const MeshGeomFacet&) const;
|
||||
void AddTriangle(const MeshGeomFacet&);
|
||||
@@ -142,6 +146,7 @@ public:
|
||||
SphereSurfaceFit();
|
||||
SphereSurfaceFit(const Base::Vector3f& c, float r);
|
||||
~SphereSurfaceFit();
|
||||
const char* GetType() const { return "Sphere"; }
|
||||
void Initialize(const MeshGeomFacet&);
|
||||
bool TestTriangle(const MeshGeomFacet&) const;
|
||||
void AddTriangle(const MeshGeomFacet&);
|
||||
@@ -152,6 +157,7 @@ public:
|
||||
private:
|
||||
Base::Vector3f center;
|
||||
float radius;
|
||||
SphereFit* fitter;
|
||||
};
|
||||
|
||||
class MeshExport MeshDistanceGenericSurfaceFitSegment : public MeshDistanceSurfaceSegment
|
||||
@@ -161,7 +167,7 @@ public:
|
||||
unsigned long minFacets, float tol);
|
||||
virtual ~MeshDistanceGenericSurfaceFitSegment();
|
||||
bool TestFacet (const MeshFacet& rclFacet) const;
|
||||
const char* GetType() const { return "GenericSurfaceFit"; }
|
||||
const char* GetType() const { return fitter->GetType(); }
|
||||
void Initialize(unsigned long);
|
||||
bool TestInitialFacet(unsigned long) const;
|
||||
void AddFacet(const MeshFacet& rclFacet);
|
||||
|
||||
@@ -52,18 +52,19 @@ public:
|
||||
PlaneFitParameter() {}
|
||||
virtual ~PlaneFitParameter() {}
|
||||
virtual std::vector<float> getParameter(FitParameter::Points pts) const {
|
||||
std::vector<float> values;
|
||||
MeshCore::PlaneFit fit;
|
||||
fit.AddPoints(pts);
|
||||
fit.Fit();
|
||||
Base::Vector3f base = fit.GetBase();
|
||||
Base::Vector3f axis = fit.GetNormal();
|
||||
std::vector<float> values;
|
||||
values.push_back(base.x);
|
||||
values.push_back(base.y);
|
||||
values.push_back(base.z);
|
||||
values.push_back(axis.x);
|
||||
values.push_back(axis.y);
|
||||
values.push_back(axis.z);
|
||||
if (fit.Fit() < FLOAT_MAX) {
|
||||
Base::Vector3f base = fit.GetBase();
|
||||
Base::Vector3f axis = fit.GetNormal();
|
||||
values.push_back(base.x);
|
||||
values.push_back(base.y);
|
||||
values.push_back(base.z);
|
||||
values.push_back(axis.x);
|
||||
values.push_back(axis.y);
|
||||
values.push_back(axis.z);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
};
|
||||
@@ -75,6 +76,20 @@ public:
|
||||
virtual ~CylinderFitParameter() {}
|
||||
virtual std::vector<float> getParameter(FitParameter::Points pts) const {
|
||||
std::vector<float> values;
|
||||
MeshCore::CylinderFit fit;
|
||||
fit.AddPoints(pts);
|
||||
if (fit.Fit() < FLOAT_MAX) {
|
||||
Base::Vector3f base = fit.GetBase();
|
||||
Base::Vector3f axis = fit.GetAxis();
|
||||
float radius = fit.GetRadius();
|
||||
values.push_back(base.x);
|
||||
values.push_back(base.y);
|
||||
values.push_back(base.z);
|
||||
values.push_back(axis.x);
|
||||
values.push_back(axis.y);
|
||||
values.push_back(axis.z);
|
||||
values.push_back(radius);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
};
|
||||
@@ -86,6 +101,16 @@ public:
|
||||
virtual ~SphereFitParameter() {}
|
||||
virtual std::vector<float> getParameter(FitParameter::Points pts) const {
|
||||
std::vector<float> values;
|
||||
MeshCore::SphereFit fit;
|
||||
fit.AddPoints(pts);
|
||||
if (fit.Fit() < FLOAT_MAX) {
|
||||
Base::Vector3f base = fit.GetCenter();
|
||||
float radius = fit.GetRadius();
|
||||
values.push_back(base.x);
|
||||
values.push_back(base.y);
|
||||
values.push_back(base.z);
|
||||
values.push_back(radius);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user