ON_NurbsSurface FittingCylinder::initNurbsCylinderWithAxes (int order, NurbsDataSurface *data, Eigen::Matrix3d &axes) { Eigen::Vector3d mean; unsigned s = unsigned (data->interior.size ()); mean = NurbsTools::computeMean (data->interior); data->mean = mean; Eigen::Vector3d v_max (0.0, 0.0, 0.0); Eigen::Vector3d v_min (DBL_MAX, DBL_MAX, DBL_MAX); for (unsigned i = 0; i < s; i++) { Eigen::Vector3d p (axes.inverse () * (data->interior[i] - mean)); if (p (0) > v_max (0)) v_max (0) = p (0); if (p (1) > v_max (1)) v_max (1) = p (1); if (p (2) > v_max (2)) v_max (2) = p (2); if (p (0) < v_min (0)) v_min (0) = p (0); if (p (1) < v_min (1)) v_min (1) = p (1); if (p (2) < v_min (2)) v_min (2) = p (2); } int ncpsU (order); int ncpsV (2 * order + 4); ON_NurbsSurface nurbs (3, false, order, order, ncpsU, ncpsV); nurbs.MakeClampedUniformKnotVector (0, 1.0); nurbs.MakePeriodicUniformKnotVector (1, 1.0 / (ncpsV - order + 1)); double dcu = (v_max (0) - v_min (0)) / (ncpsU - 1); double dcv = (2.0 * M_PI) / (ncpsV - order + 1); double ry = std::max<double> (std::fabs (v_min (1)), std::fabs (v_max (1))); double rz = std::max<double> (std::fabs (v_min (2)), std::fabs (v_max (2))); Eigen::Vector3d cv_t, cv; for (int i = 0; i < ncpsU; i++) { for (int j = 0; j < ncpsV; j++) { cv (0) = v_min (0) + dcu * i; cv (1) = ry * sin (dcv * j); cv (2) = rz * cos (dcv * j); cv_t = axes * cv + mean; nurbs.SetCV (i, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); } } return nurbs; }
ON_NurbsSurface FittingSurface::initNurbsPCA (int order, NurbsDataSurface *m_data, ON_3dVector z) { ON_3dVector mean; Eigen::Matrix3d eigenvectors; Eigen::Vector3d eigenvalues; unsigned s = m_data->interior.size (); NurbsTools::pca (m_data->interior, mean, eigenvectors, eigenvalues); m_data->mean = mean; //m_data->eigenvectors = (*eigenvectors); bool flip (false); Eigen::Vector3d ez(z[0],z[1],z[2]); if (eigenvectors.col (2).dot (ez) < 0.0) flip = true; eigenvalues = eigenvalues / s; // seems that the eigenvalues are dependent on the number of points (???) ON_3dVector sigma(sqrt(eigenvalues[0]), sqrt(eigenvalues[1]), sqrt(eigenvalues[2])); ON_NurbsSurface nurbs (3, false, order, order, order, order); nurbs.MakeClampedUniformKnotVector (0, 1.0); nurbs.MakeClampedUniformKnotVector (1, 1.0); // +- 2 sigma -> 95,45 % aller Messwerte double dcu = (4.0 * sigma[0]) / (nurbs.Order (0) - 1); double dcv = (4.0 * sigma[1]) / (nurbs.Order (1) - 1); ON_3dVector cv_t, cv; Eigen::Vector3d ecv_t, ecv; Eigen::Vector3d emean(mean[0], mean[1], mean[2]); for (int i = 0; i < nurbs.Order (0); i++) { for (int j = 0; j < nurbs.Order (1); j++) { cv[0] = -2.0 * sigma[0] + dcu * i; cv[1] = -2.0 * sigma[1] + dcv * j; cv[2] = 0.0; ecv (0) = -2.0 * sigma[0] + dcu * i; ecv (1) = -2.0 * sigma[1] + dcv * j; ecv (2) = 0.0; ecv_t = eigenvectors * ecv + emean; cv_t[0] = ecv_t (0); cv_t[1] = ecv_t (1); cv_t[2] = ecv_t (2); if (flip) nurbs.SetCV (nurbs.Order (0) - 1 - i, j, ON_3dPoint (cv_t[0], cv_t[1], cv_t[2])); else nurbs.SetCV (i, j, ON_3dPoint (cv_t[0], cv_t[1], cv_t[2])); } } return nurbs; }
ON_NurbsSurface FittingSurface::initNurbsPCA (int order, NurbsDataSurface *m_data, Eigen::Vector3d z) { Eigen::Vector3d mean; Eigen::Matrix3d eigenvectors; Eigen::Vector3d eigenvalues; unsigned s = m_data->interior.size (); NurbsTools::pca (m_data->interior, mean, eigenvectors, eigenvalues); m_data->mean = mean; m_data->eigenvectors = eigenvectors; bool flip (false); if (eigenvectors.col (2).dot (z) < 0.0) flip = true; eigenvalues = eigenvalues / s; // seems that the eigenvalues are dependent on the number of points (???) Eigen::Vector3d sigma (sqrt (eigenvalues (0)), sqrt (eigenvalues (1)), sqrt (eigenvalues (2))); ON_NurbsSurface nurbs (3, false, order, order, order, order); nurbs.MakeClampedUniformKnotVector (0, 1.0); nurbs.MakeClampedUniformKnotVector (1, 1.0); // +- 2 sigma -> 95,45 % aller Messwerte double dcu = (4.0 * sigma (0)) / (nurbs.Order (0) - 1); double dcv = (4.0 * sigma (1)) / (nurbs.Order (1) - 1); Eigen::Vector3d cv_t, cv; for (int i = 0; i < nurbs.Order (0); i++) { for (int j = 0; j < nurbs.Order (1); j++) { cv (0) = -2.0 * sigma (0) + dcu * i; cv (1) = -2.0 * sigma (1) + dcv * j; cv (2) = 0.0; cv_t = eigenvectors * cv + mean; if (flip) nurbs.SetCV (nurbs.Order (0) - 1 - i, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); else nurbs.SetCV (i, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); } } return nurbs; }
ON_NurbsSurface FittingSurface::initNurbs4Corners (int order, ON_3dPoint ll, ON_3dPoint lr, ON_3dPoint ur, ON_3dPoint ul) { std::map<int, std::map<int, ON_3dPoint> > cv_map; double dc = 1.0 / (order - 1); for (int i = 0; i < order; i++) { double di = dc * i; cv_map[i][0] = ll + (lr - ll) * di; cv_map[0][i] = ll + (ul - ll) * di; cv_map[i][order - 1] = ul + (ur - ul) * di; cv_map[order - 1][i] = lr + (ur - lr) * di; } for (int i = 1; i < order - 1; i++) { for (int j = 1; j < order - 1; j++) { ON_3dPoint du = cv_map[0][j] + (cv_map[order - 1][j] - cv_map[0][j]) * dc * i; ON_3dPoint dv = cv_map[i][0] + (cv_map[i][order - 1] - cv_map[i][0]) * dc * j; cv_map[i][j] = du * 0.5 + dv * 0.5; } } ON_NurbsSurface nurbs (3, false, order, order, order, order); nurbs.MakeClampedUniformKnotVector (0, 1.0); nurbs.MakeClampedUniformKnotVector (1, 1.0); for (int i = 0; i < order; i++) { for (int j = 0; j < order; j++) { nurbs.SetCV (i, j, cv_map[i][j]); } } return nurbs; }
ON_NurbsSurface FittingCylinder::initNurbsPCACylinder (int order, NurbsDataSurface *data) { Eigen::Vector3d mean; Eigen::Matrix3d eigenvectors; Eigen::Vector3d eigenvalues; unsigned s = unsigned (data->interior.size ()); NurbsTools::pca (data->interior, mean, eigenvectors, eigenvalues); data->mean = mean; data->eigenvectors = eigenvectors; eigenvalues = eigenvalues / s; // seems that the eigenvalues are dependent on the number of points (???) Eigen::Vector3d v_max (0.0, 0.0, 0.0); Eigen::Vector3d v_min (DBL_MAX, DBL_MAX, DBL_MAX); for (unsigned i = 0; i < s; i++) { Eigen::Vector3d p (eigenvectors.inverse () * (data->interior[i] - mean)); if (p (0) > v_max (0)) v_max (0) = p (0); if (p (1) > v_max (1)) v_max (1) = p (1); if (p (2) > v_max (2)) v_max (2) = p (2); if (p (0) < v_min (0)) v_min (0) = p (0); if (p (1) < v_min (1)) v_min (1) = p (1); if (p (2) < v_min (2)) v_min (2) = p (2); } int ncpsU (order); int ncpsV (2 * order + 4); ON_NurbsSurface nurbs (3, false, order, order, ncpsU, ncpsV); nurbs.MakeClampedUniformKnotVector (0, 1.0); nurbs.MakePeriodicUniformKnotVector (1, 1.0 / (ncpsV - order + 1)); double dcu = (v_max (0) - v_min (0)) / (ncpsU - 1); double dcv = (2.0 * M_PI) / (ncpsV - order + 1); double ry = std::max<double> (std::fabs (v_min (1)), std::fabs (v_max (1))); double rz = std::max<double> (std::fabs (v_min (2)), std::fabs (v_max (2))); Eigen::Vector3d cv_t, cv; for (int i = 0; i < ncpsU; i++) { for (int j = 0; j < ncpsV; j++) { cv (0) = v_min (0) + dcu * i; cv (1) = ry * sin (dcv * j); cv (2) = rz * cos (dcv * j); cv_t = eigenvectors * cv + mean; nurbs.SetCV (i, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); } } return nurbs; }
ON_NurbsSurface FittingSurface::initNurbsPCABoundingBox (int order, NurbsDataSurface *m_data, ON_3dVector z) { ON_3dVector mean; Eigen::Matrix3d eigenvectors; Eigen::Vector3d eigenvalues; unsigned s = m_data->interior.size (); m_data->interior_param.clear (); NurbsTools::pca (m_data->interior, mean, eigenvectors, eigenvalues); m_data->mean = mean; //m_data->eigenvectors = (*eigenvectors); bool flip (false); Eigen::Vector3d ez(z[0],z[1],z[2]); if (eigenvectors.col (2).dot (ez) < 0.0) flip = true; eigenvalues = eigenvalues / s; // seems that the eigenvalues are dependent on the number of points (???) Eigen::Matrix3d eigenvectors_inv = eigenvectors.inverse (); ON_3dVector v_max(0.0, 0.0, 0.0); ON_3dVector v_min(DBL_MAX, DBL_MAX, DBL_MAX); Eigen::Vector3d emean(mean[0], mean[1], mean[2]); for (unsigned i = 0; i < s; i++) { Eigen::Vector3d eint(m_data->interior[i][0], m_data->interior[i][1], m_data->interior[i][2]); Eigen::Vector3d ep = eigenvectors_inv * (eint - emean); ON_3dPoint p(ep (0), ep (1), ep(2)); m_data->interior_param.push_back (ON_2dPoint(p[0], p[1])); if (p[0] > v_max[0]) v_max[0] = p[0]; if (p[1] > v_max[1]) v_max[1] = p[1]; if (p[2] > v_max[2]) v_max[2] = p[2]; if (p[0] < v_min[0]) v_min[0] = p[0]; if (p[1] < v_min[1]) v_min[1] = p[1]; if (p[2] < v_min[2]) v_min[2] = p[2]; } for (unsigned i = 0; i < s; i++) { ON_2dVector &p = m_data->interior_param[i]; if (v_max[0] > v_min[0] && v_max[0] > v_min[0]) { p[0] = (p[0] - v_min[0]) / (v_max[0] - v_min[0]); p[1] = (p[1] - v_min[1]) / (v_max[1] - v_min[1]); } else { throw std::runtime_error ("[NurbsTools::initNurbsPCABoundingBox] Error: v_max <= v_min"); } } ON_NurbsSurface nurbs (3, false, order, order, order, order); nurbs.MakeClampedUniformKnotVector (0, 1.0); nurbs.MakeClampedUniformKnotVector (1, 1.0); double dcu = (v_max[0] - v_min[0]) / (nurbs.Order (0) - 1); double dcv = (v_max[1] - v_min[1]) / (nurbs.Order (1) - 1); ON_3dPoint cv_t, cv; Eigen::Vector3d ecv_t2, ecv2; Eigen::Vector3d emean2(mean[0],mean[1],mean[2]); for (int i = 0; i < nurbs.Order (0); i++) { for (int j = 0; j < nurbs.Order (1); j++) { cv[0] = v_min[0] + dcu * i; cv[1] = v_min[1] + dcv * j; cv[2] = 0.0; ecv2 (0) = cv[0]; ecv2 (1) = cv[1]; ecv2 (2) = cv[2]; ecv_t2 = eigenvectors * ecv2 + emean2; if (flip) nurbs.SetCV (nurbs.Order (0) - 1 - i, j, cv_t); else nurbs.SetCV (i, j, cv_t); } } return nurbs; }
ON_NurbsSurface FittingSurface::initNurbsPCABoundingBox (int order, NurbsDataSurface *m_data, Eigen::Vector3d z) { Eigen::Vector3d mean; Eigen::Matrix3d eigenvectors; Eigen::Vector3d eigenvalues; unsigned s = m_data->interior.size (); m_data->interior_param.clear (); NurbsTools::pca (m_data->interior, mean, eigenvectors, eigenvalues); m_data->mean = mean; m_data->eigenvectors = eigenvectors; bool flip (false); if (eigenvectors.col (2).dot (z) < 0.0) flip = true; eigenvalues = eigenvalues / s; // seems that the eigenvalues are dependent on the number of points (???) Eigen::Matrix3d eigenvectors_inv = eigenvectors.inverse (); Eigen::Vector3d v_max (0.0, 0.0, 0.0); Eigen::Vector3d v_min (DBL_MAX, DBL_MAX, DBL_MAX); for (unsigned i = 0; i < s; i++) { Eigen::Vector3d p = eigenvectors_inv * (m_data->interior[i] - mean); m_data->interior_param.push_back (Eigen::Vector2d (p (0), p (1))); if (p (0) > v_max (0)) v_max (0) = p (0); if (p (1) > v_max (1)) v_max (1) = p (1); if (p (2) > v_max (2)) v_max (2) = p (2); if (p (0) < v_min (0)) v_min (0) = p (0); if (p (1) < v_min (1)) v_min (1) = p (1); if (p (2) < v_min (2)) v_min (2) = p (2); } for (unsigned i = 0; i < s; i++) { Eigen::Vector2d &p = m_data->interior_param[i]; if (v_max (0) > v_min (0) && v_max (0) > v_min (0)) { p (0) = (p (0) - v_min (0)) / (v_max (0) - v_min (0)); p (1) = (p (1) - v_min (1)) / (v_max (1) - v_min (1)); } else { throw std::runtime_error ("[NurbsTools::initNurbsPCABoundingBox] Error: v_max <= v_min"); } } ON_NurbsSurface nurbs (3, false, order, order, order, order); nurbs.MakeClampedUniformKnotVector (0, 1.0); nurbs.MakeClampedUniformKnotVector (1, 1.0); double dcu = (v_max (0) - v_min (0)) / (nurbs.Order (0) - 1); double dcv = (v_max (1) - v_min (1)) / (nurbs.Order (1) - 1); Eigen::Vector3d cv_t, cv; for (int i = 0; i < nurbs.Order (0); i++) { for (int j = 0; j < nurbs.Order (1); j++) { cv (0) = v_min (0) + dcu * i; cv (1) = v_min (1) + dcv * j; cv (2) = 0.0; cv_t = eigenvectors * cv + mean; if (flip) nurbs.SetCV (nurbs.Order (0) - 1 - i, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); else nurbs.SetCV (i, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); } } return nurbs; }
ON_NurbsSurface FittingSphere::initNurbsSphere (int order, NurbsDataSurface *data, Eigen::Vector3d) { Eigen::Vector3d mean = NurbsTools::computeMean (data->interior); Eigen::Vector3d _min (DBL_MAX, DBL_MAX, DBL_MAX); Eigen::Vector3d _max (-DBL_MAX, -DBL_MAX, -DBL_MAX); for (const auto &i : data->interior) { Eigen::Vector3d p = i - mean; if (p (0) < _min (0)) _min (0) = p (0); if (p (1) < _min (1)) _min (1) = p (1); if (p (2) < _min (2)) _min (2) = p (2); if (p (0) > _max (0)) _max (0) = p (0); if (p (1) > _max (1)) _max (1) = p (1); if (p (2) > _max (2)) _max (2) = p (2); } int ncpsU (order + 2); int ncpsV (2 * order + 4); ON_NurbsSurface nurbs (3, false, order, order, ncpsU, ncpsV); nurbs.MakeClampedUniformKnotVector (0, 1.0); nurbs.MakePeriodicUniformKnotVector (1, 1.0 / (ncpsV - order + 1)); double dcu = (_max (2) - _min (2)) / (ncpsU - 3); double dcv = (2.0 * M_PI) / (ncpsV - order + 1); double rx = std::max<double> (std::fabs (_min (0)), std::fabs (_max (0))); double ry = std::max<double> (std::fabs (_min (1)), std::fabs (_max (1))); Eigen::Vector3d cv_t, cv; for (int i = 1; i < ncpsU - 1; i++) // for (int i = 0; i < ncpsU; i++) { for (int j = 0; j < ncpsV; j++) { cv (0) = rx * sin (dcv * j); cv (1) = ry * cos (dcv * j); cv (2) = _min (2) + dcu * (i - 1); cv_t = cv + mean; nurbs.SetCV (i, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); } } for (int j = 0; j < ncpsV; j++) { // cv (0) = 0.0; // cv (1) = 0.0; cv (0) = 0.01 * rx * sin (dcv * j); cv (1) = 0.01 * ry * cos (dcv * j); cv (2) = _min (2); cv_t = cv + mean; nurbs.SetCV (0, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); } for (int j = 0; j < ncpsV; j++) { // cv (0) = 0.0; // cv (1) = 0.0; cv (0) = 0.01 * rx * sin (dcv * j); cv (1) = 0.01 * ry * cos (dcv * j); cv (2) = _max (2); cv_t = cv + mean; nurbs.SetCV (ncpsU - 1, j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); } return nurbs; }