+ split file extension from descriptive text of file format to avoid that invalid translation breaks file dialog

+ add method to make image view unclosable for user
+ fix possible crash in MeshAlgorithm::GetMeshBorder
+ fix possible crash in MeshAlgorithm::ConnectLines
This commit is contained in:
wmayer
2015-10-06 17:28:52 +02:00
parent 8284ecc8e8
commit d19ada810f
24 changed files with 278 additions and 253 deletions

View File

@@ -532,13 +532,14 @@ void MeshAlgorithm::GetMeshBorder(unsigned long uFacet, std::list<unsigned long>
{
// find adjacent edge
std::list<std::pair<unsigned long, unsigned long> >::iterator pEI;
for (pEI = openEdges.begin(); pEI != openEdges.end(); pEI++)
for (pEI = openEdges.begin(); pEI != openEdges.end(); ++pEI)
{
if (pEI->first == ulLast)
{
ulLast = pEI->second;
rBorder.push_back(ulLast);
openEdges.erase(pEI);
pEI = openEdges.begin();
break;
}
else if (pEI->second == ulFirst)
@@ -546,6 +547,7 @@ void MeshAlgorithm::GetMeshBorder(unsigned long uFacet, std::list<unsigned long>
ulFirst = pEI->first;
rBorder.push_front(ulFirst);
openEdges.erase(pEI);
pEI = openEdges.begin();
break;
}
}
@@ -1454,125 +1456,117 @@ bool MeshAlgorithm::CutWithPlane (const Base::Vector3f &clBase, const Base::Vect
bool MeshAlgorithm::ConnectLines (std::list<std::pair<Base::Vector3f, Base::Vector3f> > &rclLines,
std::list<std::vector<Base::Vector3f> > &rclPolylines, float fMinEps) const
{
typedef std::list<std::pair<Base::Vector3f, Base::Vector3f> >::iterator TCIter;
typedef std::list<std::pair<Base::Vector3f, Base::Vector3f> >::iterator TCIter;
// square search radius
// const float fMinEps = 1.0e-2f; // := 10 mirometer distance
fMinEps = fMinEps * fMinEps;
// square search radius
// const float fMinEps = 1.0e-2f; // := 10 mirometer distance
fMinEps = fMinEps * fMinEps;
// remove all lines which distance is smaller than epsilon
std::list<TCIter> _clToDelete;
float fToDelDist = fMinEps / 10.0f;
for (TCIter pF = rclLines.begin(); pF != rclLines.end(); pF++)
{
// remove all lines whose distance is smaller than epsilon
std::list<TCIter> _clToDelete;
float fToDelDist = fMinEps / 10.0f;
for (TCIter pF = rclLines.begin(); pF != rclLines.end(); ++pF) {
if (Base::DistanceP2(pF->first, pF->second) < fToDelDist)
_clToDelete.push_back(pF);
}
for (std::list<TCIter>::iterator pI = _clToDelete.begin(); pI != _clToDelete.end(); pI++)
rclLines.erase(*pI);
while (rclLines.size() > 0)
{
TCIter pF;
// new polyline
std::list<Base::Vector3f> clPoly;
// add first line and delete from the list
Base::Vector3f clFront = rclLines.begin()->first; // current start point of the polyline
Base::Vector3f clEnd = rclLines.begin()->second; // current end point of the polyline
clPoly.push_back(clFront);
clPoly.push_back(clEnd);
rclLines.erase(rclLines.begin());
// search for the next line on the begin/end of the polyline and add it
TCIter pFront, pEnd;
do
{
float fFrontMin = fMinEps, fEndMin = fMinEps;
bool bFrontFirst=false, bEndFirst=false;
pFront = rclLines.end();
pEnd = rclLines.end();
for (pF = rclLines.begin(); pF != rclLines.end(); pF++)
{
if (Base::DistanceP2(clFront, pF->first) < fFrontMin)
{
fFrontMin = Base::DistanceP2(clFront, pF->first);
pFront = pF;
bFrontFirst = true;
}
else if (Base::DistanceP2(clEnd, pF->first) < fEndMin)
{
fEndMin = Base::DistanceP2(clEnd, pF->first);
pEnd = pF;
bEndFirst = true;
}
else if (Base::DistanceP2(clFront, pF->second) < fFrontMin)
{
fFrontMin = Base::DistanceP2(clFront, pF->second);
pFront = pF;
bFrontFirst = false;
}
else if (Base::DistanceP2(clEnd, pF->second) < fEndMin)
{
fEndMin = Base::DistanceP2(clEnd, pF->second);
pEnd = pF;
bEndFirst = false;
}
}
if (pFront != rclLines.end())
{
if (bFrontFirst == true)
{
clPoly.push_front(pFront->second);
clFront = pFront->second;
}
else
{
clPoly.push_front(pFront->first);
clFront = pFront->first;
}
rclLines.erase(pFront);
}
if (pEnd != rclLines.end())
{
if (bEndFirst == true)
{
clPoly.push_back(pEnd->second);
clEnd = pEnd->second;
}
else
{
clPoly.push_back(pEnd->first);
clEnd = pEnd->first;
}
rclLines.erase(pEnd);
}
_clToDelete.push_back(pF);
}
while ((pFront != rclLines.end()) || (pEnd != rclLines.end()));
rclPolylines.push_back(std::vector<Base::Vector3f>(clPoly.begin(), clPoly.end()));
}
// remove all polylines with too few length
typedef std::list<std::vector<Base::Vector3f> >::iterator TPIter;
std::list<TPIter> _clPolyToDelete;
for (TPIter pJ = rclPolylines.begin(); pJ != rclPolylines.end(); pJ++)
{
if (pJ->size() == 2) // only one line segment
{
if (Base::DistanceP2(*pJ->begin(), *(pJ->begin() + 1)) <= fMinEps)
_clPolyToDelete.push_back(pJ);
for (std::list<TCIter>::iterator pI = _clToDelete.begin(); pI != _clToDelete.end(); ++pI)
rclLines.erase(*pI);
while (!rclLines.empty()) {
TCIter pF;
// new polyline
std::list<Base::Vector3f> clPoly;
// add first line and delete from the list
Base::Vector3f clFront = rclLines.begin()->first; // current start point of the polyline
Base::Vector3f clEnd = rclLines.begin()->second; // current end point of the polyline
clPoly.push_back(clFront);
clPoly.push_back(clEnd);
rclLines.erase(rclLines.begin());
// search for the next line on the begin/end of the polyline and add it
TCIter pFront, pEnd;
bool bFoundLine;
do {
float fFrontMin = fMinEps, fEndMin = fMinEps;
bool bFrontFirst=false, bEndFirst=false;
pFront = rclLines.end();
pEnd = rclLines.end();
bFoundLine = false;
for (pF = rclLines.begin(); pF != rclLines.end(); ++pF) {
if (Base::DistanceP2(clFront, pF->first) < fFrontMin) {
fFrontMin = Base::DistanceP2(clFront, pF->first);
pFront = pF;
bFrontFirst = true;
}
else if (Base::DistanceP2(clEnd, pF->first) < fEndMin) {
fEndMin = Base::DistanceP2(clEnd, pF->first);
pEnd = pF;
bEndFirst = true;
}
else if (Base::DistanceP2(clFront, pF->second) < fFrontMin) {
fFrontMin = Base::DistanceP2(clFront, pF->second);
pFront = pF;
bFrontFirst = false;
}
else if (Base::DistanceP2(clEnd, pF->second) < fEndMin) {
fEndMin = Base::DistanceP2(clEnd, pF->second);
pEnd = pF;
bEndFirst = false;
}
}
if (pFront != rclLines.end()) {
bFoundLine = true;
if (bFrontFirst) {
clPoly.push_front(pFront->second);
clFront = pFront->second;
}
else {
clPoly.push_front(pFront->first);
clFront = pFront->first;
}
rclLines.erase(pFront);
}
if (pEnd != rclLines.end()) {
bFoundLine = true;
if (bEndFirst) {
clPoly.push_back(pEnd->second);
clEnd = pEnd->second;
}
else {
clPoly.push_back(pEnd->first);
clEnd = pEnd->first;
}
rclLines.erase(pEnd);
}
}
while (bFoundLine);
rclPolylines.push_back(std::vector<Base::Vector3f>(clPoly.begin(), clPoly.end()));
}
}
for (std::list<TPIter>::iterator pK = _clPolyToDelete.begin(); pK != _clPolyToDelete.end(); pK++)
rclPolylines.erase(*pK);
return true;
// remove all polylines with too few length
typedef std::list<std::vector<Base::Vector3f> >::iterator TPIter;
std::list<TPIter> _clPolyToDelete;
for (TPIter pJ = rclPolylines.begin(); pJ != rclPolylines.end(); ++pJ) {
if (pJ->size() == 2) { // only one line segment
if (Base::DistanceP2(*pJ->begin(), *(pJ->begin() + 1)) <= fMinEps)
_clPolyToDelete.push_back(pJ);
}
}
for (std::list<TPIter>::iterator pK = _clPolyToDelete.begin(); pK != _clPolyToDelete.end(); ++pK)
rclPolylines.erase(*pK);
return true;
}
bool MeshAlgorithm::ConnectPolygons(std::list<std::vector<Base::Vector3f> > &clPolyList,

View File

@@ -260,35 +260,35 @@ public:
*/
virtual ~QuadraticFit(){};
/**
* Übertragen der Quadric-Koeffizienten
* @param ulIndex Nummer des Koeffizienten (0..9)
* @return double Wert des Koeffizienten
* Get the quadric coefficients
* @param ulIndex Number of coefficient (0..9)
* @return double value of coefficient
*/
double GetCoeff(unsigned long ulIndex) const;
/**
* Übertragen der Koeffizientan als Referenz
* auf das interne Array
* @return const double& Referenz auf das double-Array
* Get the quadric coefficients as reference to the
* internal array
* @return const double& Reference to the double array
*/
const double& GetCoeffArray() const;
/**
* Aufruf des Fit-Algorithmus
* @return float Qualität des Fits.
* Invocation of fitting algorithm
* @return float Quality of fit.
*/
float Fit();
void CalcZValues(double x, double y, double &dZ1, double &dZ2) const;
/**
* Berechnen der Krümmungswerte der Quadric in einem bestimmten Punkt.
* @param x X-Koordinate
* @param y Y-Koordinate
* @param z Z-Koordinate
* @param rfCurv0 1. Hauptkrümmung
* @param rfCurv1 2. Hauptkrümmung
* @param rkDir0 Richtung der 1. Hauptkrümmung
* @param rkDir1 Richtung der 2. Hauptkrümmung
* Calculate the curvatures of the quadric at a given point.
* @param x X-coordinate
* @param y Y-coordinate
* @param z Z-coordinate
* @param rfCurv0 1. principal curvature
* @param rfCurv1 2. principal curvature
* @param rkDir0 Direction of 1. principal curvature
* @param rkDir1 Direction of 2. principal curvature
* @param dDistance
* @return bool Fehlerfreie Ausfürhung = true, ansonsten false
* @return bool Success = true, otherwise false
*/
bool GetCurvatureInfo(double x, double y, double z,
double &rfCurv0, double &rfCurv1,
@@ -297,32 +297,31 @@ public:
bool GetCurvatureInfo(double x, double y, double z,
double &rfCurv0, double &rfcurv1);
/**
* Aufstellen der Formanmatrix A und Berechnen der Eigenwerte.
* @param dLambda1 Eigenwert 1
* @param dLambda2 Eigenwert 2
* @param dLambda3 Eigenwert 3
* @param clEV1 Eigenvektor 1
* @param clEV2 Eigenvektor 2
* @param clEV3 Eigenvektor 3
* Compute form matrix A and calculate Eigenvalues.
* @param dLambda1 Eigenvalue 1
* @param dLambda2 Eigenvalue 2
* @param dLambda3 Eigenvalue 3
* @param clEV1 Eigenvector 1
* @param clEV2 Eigenvector 2
* @param clEV3 Eigenvector 3
*/
void CalcEigenValues(double &dLambda1, double &dLambda2, double &dLambda3,
Base::Vector3f &clEV1, Base::Vector3f &clEV2, Base::Vector3f &clEV3) const;
protected:
double _fCoeff[ 10 ]; /**< Ziel der Koeffizienten aus dem Fit */
double _fCoeff[ 10 ]; /**< Coefficients of the fit */
};
// -------------------------------------------------------------------------------
/**
* Dies ist ein 2,5D-Ansatz, bei dem zunächst die Ausgleichsebene der Punktmenge (P_i = (x,y,z), i=1,...,n)
* bestimmt wird. Danach wird eine Parametrisierung der Datenpunkte errechnet. Die Datenpunkte
* werden somit bzgl. des lokalen Systems der Ebene dargestellt (P_i = (u,v,w)).
* Durch diese transformierten Punkte wird nun eine quadratische Funktion
* This is an 2.5D approach which first determines the bestfit plane of the point set (P_i = (x,y,z), i=1,...,n)
* to get a parametrisation of the points afterwards. The coordinates of the points with respect to the local
* coordinate system of the plane are determined and then a quadratic polynomial function of the form:
* w = f(u,v) = a*u^2 + b*v^2 + c*u*v + d*u + e*v + f
* berechnet.
* Dieser Ansatz wurde als Alternative für den 3D-Ansatz mit Quadriken entwickelt, da bei
* Quadriken in (vor allem) ebenen Bereichen recht seltsame Artefakte auftreten.
* is deermined.
* This approach was developed as an alternative for the 3D approach with quadrics because
* the latter suffers from strange artifacts in planar areas.
*/
class MeshExport SurfaceFit : public PlaneFit
{
@@ -350,22 +349,20 @@ protected:
// -------------------------------------------------------------------------------
/**
* Hilfs-Klasse für den Quadric-Fit. Beinhaltet die
* partiellen Ableitungen der Quadric und dient zur
* Berechnung der Quadrik-Eigenschaften.
* Helper class for the quadric fit. Includes the
* partial derivates of the quadric and serves for
* calculation of the quadric properties.
*/
class FunctionContainer
{
public:
/**
* Die MGC-Algorithmen arbeiten mit Funktionen dieses
* Types
* WildMagic library uses function with this interface
*/
typedef double (*Function)(double,double,double);
/**
* Der parametrisierte Konstruktor. Erwartet ein Array
* mit den Quadric-Koeffizienten.
* @param pKoef Zeiger auf die Quadric-Parameter
* The constructor expects an array of quadric coefficients.
* @param pKoef Pointer to the quadric coefficients
* (double [10])
*/
FunctionContainer(const double *pKoef)
@@ -374,8 +371,8 @@ public:
pImplSurf = new Wm4::QuadricSurface<double>( dKoeff );
}
/**
* Übernehmen der Quadric-Parameter
* @param pKoef Zeiger auf die Quadric-Parameter
* Apply quadric coefficients
* @param pKoef Pointer to the quadric coefficients
* (double [10])
*/
void Assign( const double *pKoef )
@@ -384,28 +381,28 @@ public:
dKoeff[ ct ] = pKoef[ ct ];
}
/**
* Destruktor. Löscht die ImpicitSurface Klasse
* der MGC-Bibliothek wieder
* Destruktor. Deletes the ImpicitSurface instance
* of the WildMagic library
*/
~FunctionContainer(){ delete pImplSurf; }
/**
* Zugriff auf die Koeffizienten der Quadric
* @param idx Index des Parameters
* @return double& Der Koeffizient
* Access to the quadric coefficients
* @param idx Index to coefficient
* @return double& coefficient
*/
double& operator[](int idx){ return dKoeff[ idx ]; }
/**
* Redirector auf eine Methode der MGC Bibliothek. Ermittelt
* die Hauptkrümmungen und ihre Richtungen im angegebenen Punkt.
* @param x X-Koordinate
* @param y Y-Koordinate
* @param z Z-Koordinate
* @param rfCurv0 1. Hauptkrümmung
* @param rfCurv1 2. Hauptkrümmung
* @param rkDir0 Richtung der 1. Hauptkrümmung
* @param rkDir1 Richtung der 2. Hauptkrümmung
* @param dDistance Ergebnis das die Entfernung des Punktes von der Quadrik angibt.
* @return bool Fehlerfreie Ausfürhung = true, ansonsten false
* Redirector to a method of the WildMagic library. Determines
* the principal curvatures and their directions at the given point.
* @param x X-coordinate
* @param y Y-coordinate
* @param z Z-coordinate
* @param rfCurv0 1. principal curvature
* @param rfCurv1 2. principal curvature
* @param rkDir0 direction of 1. principal curvature
* @param rkDir1 direction of 2. principal curvature
* @param dDistance Gives distances from the point to the quadric.
* @return bool Success = true, otherwise false
*/
bool CurvatureInfo(double x, double y, double z,
double &rfCurv0, double &rfCurv1,
@@ -502,8 +499,8 @@ public:
}
protected:
double dKoeff[ 10 ]; /**< Koeffizienten der Quadric */
Wm4::ImplicitSurface<double> *pImplSurf; /**< Zugriff auf die MGC-Bibliothek */
double dKoeff[ 10 ]; /**< Coefficients of quadric */
Wm4::ImplicitSurface<double> *pImplSurf; /**< Access to the WildMagic library */
private:
/**

View File

@@ -659,7 +659,7 @@ bool MeshFixDeformedFacets::Fixup()
fCosAngles[i] = fCosAngle;
}
// first check for angle > 120°: in this case we swap with the opposite edge
// first check for angle > 120 deg: in this case we swap with the opposite edge
for (int i=0; i<3; i++)
{
float fCosAngle = fCosAngles[i];
@@ -678,7 +678,7 @@ bool MeshFixDeformedFacets::Fixup()
if (done)
continue;
// now check for angle < 30°: in this case we swap with one of the edges the corner is part of
// now check for angle < 30 deg: in this case we swap with one of the edges the corner is part of
for (int j=0; j<3; j++)
{
float fCosAngle = fCosAngles[j];

View File

@@ -328,7 +328,8 @@ public:
};
/**
* The MeshEvalDeformedFacets class searches for deformed facets. A facet is regarded as deformed if an angle is < 30° or > 120°.
* The MeshEvalDeformedFacets class searches for deformed facets. A facet is regarded as deformed
* if an angle is < 30 deg or > 120 deg.
* @see MeshFixDegeneratedFacets
* @author Werner Mayer
*/

View File

@@ -432,7 +432,7 @@ bool MeshGeomFacet::IsDeformed() const
fCosAngle = u * v;
// x < 30° => cos(x) > sqrt(3)/2 or x > 120° => cos(x) < -0.5
// x < 30 deg => cos(x) > sqrt(3)/2 or x > 120 deg => cos(x) < -0.5
if (fCosAngle > 0.86f || fCosAngle < -0.5f)
return true;
}
@@ -748,7 +748,7 @@ void MeshGeomFacet::SubSample (float fStep, std::vector<Base::Vector3f> &rclPoin
}
/**
* Fast Triangle-Triangle Intersection Test by Tomas Möller
* Fast Triangle-Triangle Intersection Test by Tomas Moeller
* http://www.acm.org/jgt/papers/Moller97/tritri.html
* http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/
*/
@@ -771,7 +771,7 @@ bool MeshGeomFacet::IntersectWithFacet(const MeshGeomFacet &rclFacet) const
}
/**
* Fast Triangle-Triangle Intersection Test by Tomas Möller
* Fast Triangle-Triangle Intersection Test by Tomas Moeller
* http://www.acm.org/jgt/papers/Moller97/tritri.html
* http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/
*/

View File

@@ -361,8 +361,8 @@ public:
bool IsDegenerated() const;
/**
* Checks whether the triangle is deformed. The definition of a deformed triangles is not as strong
* as the definition of a degenerated triangle. A triangle is deformed if the maximum angle exceeds 120°
* or the minimum angle falls below 30°.
* as the definition of a degenerated triangle. A triangle is deformed if the maximum angle exceeds 120 deg
* or the minimum angle falls below 30 deg.
* A degenerated triangle is also a deformed triangle.
*/
bool IsDeformed() const;