Mesh segmentation

This commit is contained in:
wmayer 2012-05-21 15:02:51 +02:00 committed by logari81
parent a87f558125
commit d6b6f6b379
7 changed files with 67 additions and 75 deletions

View File

@ -108,22 +108,12 @@ bool MeshCurvatureCylindricalSegment::TestFacet (const MeshFacet &rclFacet) cons
{
for (int i=0; i<3; i++) {
const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
if (ci.fMaxCurvature > ci.fMinCurvature) {
// convexe
if (fabs(ci.fMinCurvature) > tolerance)
return false;
float diff = ci.fMaxCurvature - curvature;
if (fabs(diff) > tolerance)
return false;
}
else {
// concave
if (fabs(ci.fMaxCurvature) > tolerance)
return false;
float diff = ci.fMinCurvature + curvature;
if (fabs(diff) > tolerance)
return false;
}
float fMax = std::max<float>(fabs(ci.fMaxCurvature), fabs(ci.fMinCurvature));
float fMin = std::min<float>(fabs(ci.fMaxCurvature), fabs(ci.fMinCurvature));
if (fMin > toleranceMin)
return false;
if (fabs(fMax - curvature) > toleranceMax)
return false;
}
return true;
@ -151,9 +141,9 @@ bool MeshCurvatureFreeformSegment::TestFacet (const MeshFacet &rclFacet) const
{
for (int i=0; i<3; i++) {
const CurvatureInfo& ci = info[rclFacet._aulPoints[i]];
if (fabs(ci.fMinCurvature-c2) > tolerance)
if (fabs(ci.fMinCurvature-c2) > toleranceMin)
return false;
if (fabs(ci.fMaxCurvature-c1) > tolerance)
if (fabs(ci.fMaxCurvature-c1) > toleranceMax)
return false;
}

View File

@ -84,53 +84,63 @@ protected:
class MeshExport MeshCurvatureSurfaceSegment : public MeshSurfaceSegment
{
public:
MeshCurvatureSurfaceSegment(const std::vector<CurvatureInfo>& ci, unsigned long minFacets, float tol)
: MeshSurfaceSegment(minFacets), info(ci), tolerance(tol) {}
MeshCurvatureSurfaceSegment(const std::vector<CurvatureInfo>& ci, unsigned long minFacets)
: MeshSurfaceSegment(minFacets), info(ci) {}
protected:
const std::vector<CurvatureInfo>& info;
float tolerance;
};
class MeshExport MeshCurvaturePlanarSegment : public MeshCurvatureSurfaceSegment
{
public:
MeshCurvaturePlanarSegment(const std::vector<CurvatureInfo>& ci, unsigned long minFacets, float tol)
: MeshCurvatureSurfaceSegment(ci, minFacets, tol) {}
: MeshCurvatureSurfaceSegment(ci, minFacets), tolerance(tol) {}
virtual bool TestFacet (const MeshFacet &rclFacet) const;
private:
float tolerance;
};
class MeshExport MeshCurvatureCylindricalSegment : public MeshCurvatureSurfaceSegment
{
public:
MeshCurvatureCylindricalSegment(const std::vector<CurvatureInfo>& ci, unsigned long minFacets, float tol, float radius)
: MeshCurvatureSurfaceSegment(ci, minFacets, tol) { curvature = 1/radius;}
MeshCurvatureCylindricalSegment(const std::vector<CurvatureInfo>& ci, unsigned long minFacets,
float tolMin, float tolMax, float radius)
: MeshCurvatureSurfaceSegment(ci, minFacets), toleranceMin(tolMin), toleranceMax(tolMax) { curvature = 1/radius;}
virtual bool TestFacet (const MeshFacet &rclFacet) const;
private:
float curvature;
float toleranceMin;
float toleranceMax;
};
class MeshExport MeshCurvatureSphericalSegment : public MeshCurvatureSurfaceSegment
{
public:
MeshCurvatureSphericalSegment(const std::vector<CurvatureInfo>& ci, unsigned long minFacets, float tol, float radius)
: MeshCurvatureSurfaceSegment(ci, minFacets, tol) { curvature = 1/radius;}
: MeshCurvatureSurfaceSegment(ci, minFacets), tolerance(tol) { curvature = 1/radius;}
virtual bool TestFacet (const MeshFacet &rclFacet) const;
private:
float curvature;
float tolerance;
};
class MeshExport MeshCurvatureFreeformSegment : public MeshCurvatureSurfaceSegment
{
public:
MeshCurvatureFreeformSegment(const std::vector<CurvatureInfo>& ci, unsigned long minFacets, float tol, float c1, float c2)
: MeshCurvatureSurfaceSegment(ci, minFacets, tol), c1(c1), c2(c2) {}
MeshCurvatureFreeformSegment(const std::vector<CurvatureInfo>& ci, unsigned long minFacets,
float tolMin, float tolMax, float c1, float c2)
: MeshCurvatureSurfaceSegment(ci, minFacets), c1(c1), c2(c2),
toleranceMin(tolMin), toleranceMax(tolMax) {}
virtual bool TestFacet (const MeshFacet &rclFacet) const;
private:
float c1, c2;
float toleranceMin;
float toleranceMax;
};
class MeshExport MeshSurfaceVisitor : public MeshFacetVisitor

View File

@ -44,6 +44,7 @@
#include "Core/TopoAlgorithm.h"
#include "Core/Evaluation.h"
#include "Core/Degeneration.h"
#include "Core/Segmentation.h"
#include "Core/SetOperations.h"
#include "Core/Visitor.h"
@ -1426,48 +1427,21 @@ std::vector<Segment> MeshObject::getSegmentsFromType(MeshObject::Type type, cons
float dev, unsigned long minFacets) const
{
std::vector<Segment> segm;
unsigned long startFacet;
if (this->_kernel.CountFacets() == 0)
return segm;
// reset VISIT flags
MeshCore::MeshAlgorithm cAlgo(this->_kernel);
if (aSegment.isEmpty()) {
cAlgo.ResetFacetFlag(MeshCore::MeshFacet::VISIT);
MeshCore::MeshSegmentAlgorithm finder(this->_kernel);
MeshCore::MeshDistanceSurfaceSegment* surf;
surf = new MeshCore::MeshDistancePlanarSegment(this->_kernel, minFacets, dev);
std::vector<MeshCore::MeshSurfaceSegment*> surfaces;
surfaces.push_back(surf);
finder.FindSegments(surfaces);
const std::vector<MeshCore::MeshSegment>& data = surf->GetSegments();
for (std::vector<MeshCore::MeshSegment>::const_iterator it = data.begin(); it != data.end(); ++it) {
segm.push_back(Segment(const_cast<MeshObject*>(this), *it, false));
}
else {
cAlgo.SetFacetFlag(MeshCore::MeshFacet::VISIT);
cAlgo.ResetFacetsFlag(aSegment.getIndices(), MeshCore::MeshFacet::VISIT);
}
const MeshCore::MeshFacetArray& rFAry = this->_kernel.GetFacets();
MeshCore::MeshFacetArray::_TConstIterator iTri = rFAry.begin();
MeshCore::MeshFacetArray::_TConstIterator iBeg = rFAry.begin();
MeshCore::MeshFacetArray::_TConstIterator iEnd = rFAry.end();
// start from the first not visited facet
cAlgo.CountFacetFlag(MeshCore::MeshFacet::VISIT);
iTri = std::find_if(iTri, iEnd, std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
MeshCore::MeshFacet::VISIT));
startFacet = iTri - iBeg;
while (startFacet != ULONG_MAX) {
// collect all facets of the same geometry
std::vector<unsigned long> indices;
indices.push_back(startFacet);
MeshCore::MeshPlaneVisitor pv(this->_kernel, startFacet, dev, indices);
this->_kernel.VisitNeighbourFacets(pv, startFacet);
iTri = std::find_if(iTri, iEnd, std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
MeshCore::MeshFacet::VISIT));
if (iTri < iEnd)
startFacet = iTri - iBeg;
else
startFacet = ULONG_MAX;
if (indices.size() > minFacets)
segm.push_back(Segment(const_cast<MeshObject*>(this), indices, false));
}
delete surf;
return segm;
}

View File

@ -382,10 +382,10 @@ plane if none of its neighours is coplanar.</UserDocu>
<Documentation>
<UserDocu>getSegmentsByCurvature(list) -> list
The argument list gives a list if tuples where it defines the preferred maximum curvature,
the preferred minumum curvature, the tolerance and the number of minimum faces for the segment.
the preferred minumum curvature, the tolerances and the number of minimum faces for the segment.
Example:
c=(1.0, 0.0, 0.1, 500) # search for a cylinder with radius 1.0
p=(0.0, 0.0, 0.1, 500) # search for a plane
c=(1.0, 0.0, 0.1, 0.1, 500) # search for a cylinder with radius 1.0
p=(0.0, 0.0, 0.1, 0.1, 500) # search for a plane
mesh.getSegmentsByCurvature([c,p])
</UserDocu>
</Documentation>

View File

@ -1399,9 +1399,10 @@ PyObject* MeshPy::getSegmentsByCurvature(PyObject *args)
Py::Tuple t(*it);
float c1 = (float)Py::Float(t[0]);
float c2 = (float)Py::Float(t[1]);
float tol = (float)Py::Float(t[2]);
int num = (int)Py::Int(t[3]);
segm.push_back(new MeshCore::MeshCurvatureFreeformSegment(meshCurv.GetCurvature(), num, tol, c1, c2));
float tol1 = (float)Py::Float(t[2]);
float tol2 = (float)Py::Float(t[3]);
int num = (int)Py::Int(t[4]);
segm.push_back(new MeshCore::MeshCurvatureFreeformSegment(meshCurv.GetCurvature(), num, tol1, tol2, c1, c2));
}
finder.FindSegments(segm);

View File

@ -76,7 +76,7 @@ void Segmentation::accept()
std::vector<MeshCore::MeshSurfaceSegment*> segm;
if (ui->groupBoxCyl->isChecked()) {
segm.push_back(new MeshCore::MeshCurvatureCylindricalSegment
(meshCurv.GetCurvature(), ui->numCyl->value(), ui->tolCyl->value(), ui->radCyl->value()));
(meshCurv.GetCurvature(), ui->numCyl->value(), ui->tol1Cyl->value(), ui->tol2Cyl->value(), ui->radCyl->value()));
}
if (ui->groupBoxSph->isChecked()) {
segm.push_back(new MeshCore::MeshCurvatureSphericalSegment

View File

@ -106,12 +106,12 @@
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Tolerance</string>
<string>Tolerance (Flat)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="tolCyl">
<widget class="QDoubleSpinBox" name="tol1Cyl">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
@ -121,13 +121,30 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Tolerance (Curved)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="tol2Cyl">
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Minimum number of faces</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QSpinBox" name="numCyl">
<property name="maximum">
<number>100000</number>