| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #ifndef MESH_APPROXIMATION_H
|
| | #define MESH_APPROXIMATION_H
|
| |
|
| | #include <Mod/Mesh/App/WildMagic4/Wm4QuadricSurface.h>
|
| | #ifndef MESH_GLOBAL_H
|
| | # include <Mod/Mesh/MeshGlobal.h>
|
| | #endif
|
| | #include <algorithm>
|
| | #include <limits>
|
| | #include <list>
|
| | #include <set>
|
| | #include <vector>
|
| |
|
| | #include <Base/BoundBox.h>
|
| | #include <Base/Matrix.h>
|
| | #include <Base/Vector3D.h>
|
| |
|
| |
|
| | namespace Wm4
|
| | {
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | template<class Real>
|
| | class PolynomialSurface: public ImplicitSurface<Real>
|
| | {
|
| | public:
|
| | explicit PolynomialSurface(const Real afCoeff[6])
|
| | {
|
| | for (int i = 0; i < 6; i++) {
|
| | m_afCoeff[i] = afCoeff[i];
|
| | }
|
| | }
|
| |
|
| |
|
| | Real F(const Vector3<Real>& rkP) const override
|
| | {
|
| | return (
|
| | m_afCoeff[0] * rkP.X() * rkP.X() + m_afCoeff[1] * rkP.Y() * rkP.Y()
|
| | + m_afCoeff[2] * rkP.X() + m_afCoeff[3] * rkP.Y() + m_afCoeff[4] * rkP.X() * rkP.Y()
|
| | + m_afCoeff[5] - rkP.Z()
|
| | );
|
| | }
|
| |
|
| |
|
| | Real FX(const Vector3<Real>& rkP) const override
|
| | {
|
| | return (Real)(2.0 * m_afCoeff[0] * rkP.X() + m_afCoeff[2] + m_afCoeff[4] * rkP.Y());
|
| | }
|
| | Real FY(const Vector3<Real>& rkP) const override
|
| | {
|
| | return (Real)(2.0 * m_afCoeff[1] * rkP.Y() + m_afCoeff[3] + m_afCoeff[4] * rkP.X());
|
| | }
|
| | Real FZ(const Vector3<Real>& ) const override
|
| | {
|
| | return (Real)-1.0;
|
| | }
|
| |
|
| |
|
| | Real FXX(const Vector3<Real>& ) const override
|
| | {
|
| | return (Real)(2.0 * m_afCoeff[0]);
|
| | }
|
| | Real FXY(const Vector3<Real>& ) const override
|
| | {
|
| | return (Real)(m_afCoeff[4]);
|
| | }
|
| | Real FXZ(const Vector3<Real>& ) const override
|
| | {
|
| | return (Real)0.0;
|
| | }
|
| | Real FYY(const Vector3<Real>& ) const override
|
| | {
|
| | return (Real)(2.0 * m_afCoeff[1]);
|
| | }
|
| | Real FYZ(const Vector3<Real>& ) const override
|
| | {
|
| | return (Real)0.0;
|
| | }
|
| | Real FZZ(const Vector3<Real>& ) const override
|
| | {
|
| | return (Real)0.0;
|
| | }
|
| |
|
| | private:
|
| | Real m_afCoeff[6];
|
| | };
|
| |
|
| | }
|
| |
|
| | namespace MeshCore
|
| | {
|
| | class MeshPointArray;
|
| |
|
| | |
| | |
| |
|
| | class MeshExport Approximation
|
| | {
|
| | public:
|
| | |
| | |
| |
|
| | Approximation();
|
| | |
| | |
| |
|
| | virtual ~Approximation();
|
| | |
| | |
| |
|
| | void AddPoint(const Base::Vector3f& point);
|
| | |
| | |
| |
|
| | void AddPoints(const std::vector<Base::Vector3f>& points);
|
| | |
| | |
| |
|
| | void AddPoints(const std::set<Base::Vector3f>& points);
|
| | |
| | |
| |
|
| | void AddPoints(const std::list<Base::Vector3f>& points);
|
| | |
| | |
| |
|
| | void AddPoints(const MeshPointArray& points);
|
| | |
| | |
| |
|
| | const std::list<Base::Vector3f>& GetPoints() const
|
| | {
|
| | return _vPoints;
|
| | }
|
| | |
| | |
| | |
| |
|
| | Base::Vector3f GetGravity() const;
|
| | |
| | |
| | |
| |
|
| | std::size_t CountPoints() const;
|
| | |
| | |
| |
|
| | void Clear();
|
| | |
| | |
| | |
| |
|
| | float GetLastResult() const;
|
| | |
| | |
| | |
| |
|
| | virtual float Fit() = 0;
|
| | |
| | |
| |
|
| | bool Done() const;
|
| |
|
| | protected:
|
| | |
| | |
| |
|
| | void GetMgcVectorArray(std::vector<Wm4::Vector3<double>>& rcPts) const;
|
| |
|
| | Approximation(const Approximation&) = default;
|
| | Approximation(Approximation&&) = default;
|
| | Approximation& operator=(const Approximation&) = default;
|
| | Approximation& operator=(Approximation&&) = default;
|
| |
|
| | protected:
|
| |
|
| | std::list<Base::Vector3f> _vPoints;
|
| | bool _bIsFitted {false};
|
| | float _fLastResult {std::numeric_limits<float>::max()};
|
| |
|
| | };
|
| |
|
| |
|
| |
|
| | |
| | |
| |
|
| | class MeshExport PlaneFit: public Approximation
|
| | {
|
| | public:
|
| | PlaneFit();
|
| | Base::Vector3f GetBase() const;
|
| | Base::Vector3f GetDirU() const;
|
| | Base::Vector3f GetDirV() const;
|
| | |
| | |
| | |
| |
|
| | Base::Vector3f GetNormal() const;
|
| | |
| | |
| | |
| |
|
| | float Fit() override;
|
| | |
| | |
| | |
| |
|
| | float GetDistanceToPlane(const Base::Vector3f& rcPoint) const;
|
| | |
| | |
| | |
| |
|
| | float GetStdDeviation() const;
|
| | |
| | |
| | |
| |
|
| | float GetSignedStdDeviation() const;
|
| | |
| | |
| |
|
| | void ProjectToPlane();
|
| | |
| | |
| |
|
| | void Dimension(float& length, float& width) const;
|
| | |
| | |
| | |
| | |
| |
|
| | std::vector<Base::Vector3f> GetLocalPoints() const;
|
| | |
| | |
| | |
| | |
| |
|
| | Base::BoundBox3f GetBoundings() const;
|
| |
|
| | protected:
|
| |
|
| | Base::Vector3f _vBase;
|
| | Base::Vector3f _vDirU;
|
| | Base::Vector3f _vDirV;
|
| | Base::Vector3f _vDirW;
|
| |
|
| | };
|
| |
|
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | class MeshExport QuadraticFit: public Approximation
|
| | {
|
| | public:
|
| | QuadraticFit() = default;
|
| | |
| | |
| | |
| | |
| |
|
| | double GetCoeff(std::size_t ulIndex) const;
|
| | |
| | |
| | |
| | |
| |
|
| | const double& GetCoeffArray() const;
|
| | |
| | |
| | |
| |
|
| | float Fit() override;
|
| |
|
| | void CalcZValues(double x, double y, double& dZ1, double& dZ2) const;
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | bool GetCurvatureInfo(
|
| | double x,
|
| | double y,
|
| | double z,
|
| | double& rfCurv0,
|
| | double& rfCurv1,
|
| | Base::Vector3f& rkDir0,
|
| | Base::Vector3f& rkDir1,
|
| | double& dDistance
|
| | );
|
| |
|
| | bool GetCurvatureInfo(double x, double y, double z, double& rfCurv0, double& rfcurv1);
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | void CalcEigenValues(
|
| | double& dLambda1,
|
| | double& dLambda2,
|
| | double& dLambda3,
|
| | Base::Vector3f& clEV1,
|
| | Base::Vector3f& clEV2,
|
| | Base::Vector3f& clEV3
|
| | ) const;
|
| |
|
| | private:
|
| | double _fCoeff[10] {};
|
| | };
|
| |
|
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | class MeshExport SurfaceFit: public PlaneFit
|
| | {
|
| | public:
|
| | SurfaceFit();
|
| |
|
| | bool GetCurvatureInfo(
|
| | double x,
|
| | double y,
|
| | double z,
|
| | double& rfCurv0,
|
| | double& rfCurv1,
|
| | Base::Vector3f& rkDir0,
|
| | Base::Vector3f& rkDir1,
|
| | double& dDistance
|
| | );
|
| | bool GetCurvatureInfo(double x, double y, double z, double& rfCurv0, double& rfcurv1);
|
| | float Fit() override;
|
| | double Value(double x, double y) const;
|
| | void GetCoefficients(double& a, double& b, double& c, double& d, double& e, double& f) const;
|
| | |
| | |
| | |
| |
|
| | void Transform(std::vector<Base::Vector3f>&) const;
|
| | void Transform(std::vector<Base::Vector3d>&) const;
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | std::vector<Base::Vector3d> toBezier(
|
| | double umin = 0.0,
|
| | double umax = 1.0,
|
| | double vmin = 0.0,
|
| | double vmax = 1.0
|
| | ) const;
|
| |
|
| | private:
|
| | double PolynomFit();
|
| | double _fCoeff[10];
|
| | };
|
| |
|
| |
|
| |
|
| | |
| | |
| |
|
| | class MeshExport CylinderFit: public Approximation
|
| | {
|
| | public:
|
| | CylinderFit();
|
| | float GetRadius() const;
|
| | Base::Vector3f GetBase() const;
|
| | void SetInitialValues(const Base::Vector3f&, const Base::Vector3f&);
|
| | |
| | |
| | |
| |
|
| | Base::Vector3f GetAxis() const;
|
| | |
| | |
| |
|
| | Base::Vector3f GetInitialAxisFromNormals(const std::vector<Base::Vector3f>& n) const;
|
| | |
| | |
| |
|
| | float Fit() override;
|
| | |
| | |
| | |
| |
|
| | float GetDistanceToCylinder(const Base::Vector3f& rcPoint) const;
|
| | |
| | |
| | |
| |
|
| | float GetStdDeviation() const;
|
| | |
| | |
| |
|
| | void ProjectToCylinder();
|
| | |
| | |
| | |
| |
|
| | void GetBounding(Base::Vector3f& bottom, Base::Vector3f& top) const;
|
| |
|
| | private:
|
| | Base::Vector3f _vBase;
|
| | Base::Vector3f _vAxis;
|
| | float _fRadius {0};
|
| | bool _initialGuess {false};
|
| | };
|
| |
|
| |
|
| |
|
| | |
| | |
| |
|
| | class MeshExport SphereFit: public Approximation
|
| | {
|
| | public:
|
| | SphereFit();
|
| | float GetRadius() const;
|
| | Base::Vector3f GetCenter() const;
|
| | |
| | |
| |
|
| | float Fit() override;
|
| | |
| | |
| | |
| |
|
| | float GetDistanceToSphere(const Base::Vector3f& rcPoint) const;
|
| | |
| | |
| | |
| |
|
| | float GetStdDeviation() const;
|
| | |
| | |
| |
|
| | void ProjectToSphere();
|
| |
|
| | private:
|
| | Base::Vector3f _vCenter;
|
| | float _fRadius {0};
|
| | };
|
| |
|
| |
|
| |
|
| | |
| | |
| | |
| | |
| |
|
| | class FunctionContainer
|
| | {
|
| | public:
|
| | |
| | |
| |
|
| | using Function = double (*)(double, double, double);
|
| | |
| | |
| | |
| | |
| |
|
| |
|
| | explicit FunctionContainer(const double* pKoef)
|
| | {
|
| | Assign(pKoef);
|
| | pImplSurf = new Wm4::QuadricSurface<double>(dKoeff);
|
| | }
|
| |
|
| |
|
| | FunctionContainer(const FunctionContainer&) = delete;
|
| | FunctionContainer(FunctionContainer&&) = delete;
|
| | FunctionContainer& operator=(const FunctionContainer&) = delete;
|
| | FunctionContainer& operator=(FunctionContainer&&) = delete;
|
| |
|
| | |
| | |
| | |
| | |
| |
|
| | void Assign(const double* pKoef)
|
| | {
|
| | for (long ct = 0; ct < 10; ct++) {
|
| | dKoeff[ct] = pKoef[ct];
|
| | }
|
| | }
|
| | |
| | |
| | |
| |
|
| | ~FunctionContainer()
|
| | {
|
| | delete pImplSurf;
|
| | }
|
| | |
| | |
| | |
| | |
| |
|
| | double& operator[](int idx)
|
| | {
|
| | return dKoeff[idx];
|
| | }
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | bool CurvatureInfo(
|
| | double x,
|
| | double y,
|
| | double z,
|
| | double& rfCurv0,
|
| | double& rfCurv1,
|
| | Wm4::Vector3<double>& rkDir0,
|
| | Wm4::Vector3<double>& rkDir1,
|
| | double& dDistance
|
| | )
|
| | {
|
| | (void)dDistance;
|
| | return pImplSurf->ComputePrincipalCurvatureInfo(
|
| | Wm4::Vector3<double>(x, y, z),
|
| | rfCurv0,
|
| | rfCurv1,
|
| | rkDir0,
|
| | rkDir1
|
| | );
|
| | }
|
| |
|
| | Base::Vector3f GetGradient(double x, double y, double z) const
|
| | {
|
| | Wm4::Vector3<double> grad = pImplSurf->GetGradient(Wm4::Vector3<double>(x, y, z));
|
| | return Base::Vector3f(
|
| | static_cast<float>(grad.X()),
|
| | static_cast<float>(grad.Y()),
|
| | static_cast<float>(grad.Z())
|
| | );
|
| | }
|
| |
|
| | Base::Matrix4D GetHessian(double x, double y, double z) const
|
| | {
|
| | Wm4::Matrix3<double> hess = pImplSurf->GetHessian(Wm4::Vector3<double>(x, y, z));
|
| | Base::Matrix4D cMat;
|
| | cMat.setToUnity();
|
| | cMat[0][0] = hess[0][0];
|
| | cMat[0][1] = hess[0][1];
|
| | cMat[0][2] = hess[0][2];
|
| | cMat[1][0] = hess[1][0];
|
| | cMat[1][1] = hess[1][1];
|
| | cMat[1][2] = hess[1][2];
|
| | cMat[2][0] = hess[2][0];
|
| | cMat[2][1] = hess[2][1];
|
| | cMat[2][2] = hess[2][2];
|
| | return cMat;
|
| | }
|
| |
|
| | bool CurvatureInfo(double x, double y, double z, double& rfCurv0, double& rfCurv1)
|
| | {
|
| | double dQuot = Fz(x, y, z);
|
| | double zx = -(Fx(x, y, z) / dQuot);
|
| | double zy = -(Fy(x, y, z) / dQuot);
|
| |
|
| | double zxx = -(2.0 * (dKoeff[5] + dKoeff[6] * zx * zx + dKoeff[8] * zx)) / dQuot;
|
| | double zyy = -(2.0 * (dKoeff[5] + dKoeff[6] * zy * zy + dKoeff[9] * zy)) / dQuot;
|
| | double zxy = -(dKoeff[6] * zx * zy + dKoeff[7] + dKoeff[8] * zy + dKoeff[9] * zx) / dQuot;
|
| |
|
| | double dNen = 1 + zx * zx + zy * zy;
|
| | double dNenSqrt = sqrt(dNen);
|
| | double K = (zxx * zyy - zxy * zxy) / (dNen * dNen);
|
| | double H = 0.5
|
| | * ((1.0 + zx * zx - 2 * zx * zy * zxy + (1.0 + zy * zy) * zxx)
|
| | / (dNenSqrt * dNenSqrt * dNenSqrt));
|
| |
|
| | double dDiscr = sqrt(fabs(H * H - K));
|
| | rfCurv0 = H - dDiscr;
|
| | rfCurv1 = H + dDiscr;
|
| |
|
| | return true;
|
| | }
|
| |
|
| |
|
| | double F(double x, double y, double z)
|
| | {
|
| | return (
|
| | dKoeff[0] + dKoeff[1] * x + dKoeff[2] * y + dKoeff[3] * z + dKoeff[4] * x * x
|
| | + dKoeff[5] * y * y + dKoeff[6] * z * z + dKoeff[7] * x * y + dKoeff[8] * x * z
|
| | + dKoeff[9] * y * z
|
| | );
|
| | }
|
| |
|
| |
|
| | double Fx(double x, double y, double z)
|
| | {
|
| | return (dKoeff[1] + 2.0 * dKoeff[4] * x + dKoeff[7] * y + dKoeff[8] * z);
|
| | }
|
| | double Fy(double x, double y, double z)
|
| | {
|
| | return (dKoeff[2] + 2.0 * dKoeff[5] * y + dKoeff[7] * x + dKoeff[9] * z);
|
| | }
|
| | double Fz(double x, double y, double z)
|
| | {
|
| | return (dKoeff[3] + 2.0 * dKoeff[6] * z + dKoeff[8] * x + dKoeff[9] * y);
|
| | }
|
| |
|
| |
|
| | double Fxx(double x, double y, double z)
|
| | {
|
| | (void)x;
|
| | (void)y;
|
| | (void)z;
|
| | return (2.0 * dKoeff[4]);
|
| | }
|
| | double Fxy(double x, double y, double z)
|
| | {
|
| | (void)x;
|
| | (void)y;
|
| | (void)z;
|
| | return (dKoeff[7]);
|
| | }
|
| | double Fxz(double x, double y, double z)
|
| | {
|
| | (void)x;
|
| | (void)y;
|
| | (void)z;
|
| | return (dKoeff[8]);
|
| | }
|
| | double Fyy(double x, double y, double z)
|
| | {
|
| | (void)x;
|
| | (void)y;
|
| | (void)z;
|
| | return (2.0 * dKoeff[5]);
|
| | }
|
| | double Fyz(double x, double y, double z)
|
| | {
|
| | (void)x;
|
| | (void)y;
|
| | (void)z;
|
| | return (dKoeff[9]);
|
| | }
|
| | double Fzz(double x, double y, double z)
|
| | {
|
| | (void)x;
|
| | (void)y;
|
| | (void)z;
|
| | return (2.0 * dKoeff[6]);
|
| | }
|
| |
|
| | private:
|
| | double dKoeff[10];
|
| | Wm4::ImplicitSurface<double>* pImplSurf;
|
| |
|
| | private:
|
| | |
| | |
| |
|
| | FunctionContainer() = default;
|
| | };
|
| |
|
| | class MeshExport PolynomialFit: public Approximation
|
| | {
|
| | public:
|
| | PolynomialFit();
|
| |
|
| | float Fit() override;
|
| | float Value(float x, float y) const;
|
| |
|
| | private:
|
| | float _fCoeff[9];
|
| | };
|
| |
|
| | }
|
| |
|
| | #endif
|
| |
|