Example #1
0
void
NurbsTools::downsample_random (vector_vec3d &data, unsigned size)
{
  if (data.size () <= size && size > 0)
    return;

  unsigned s = data.size ();

  vector_vec3d data_tmp;

  for (unsigned i = 0; i < size; i++)
  {
    unsigned rnd = unsigned ((s - 1) * (double (rand ()) / RAND_MAX));
    data_tmp.push_back (data[rnd]);
  }

  data = data_tmp;
}
Example #2
0
void
GlobalOptimization::setCommonBoundary (const vector_vec3d &boundary, const vector_vec2i &nurbs_indices)
{
  if (boundary.empty () || boundary.size () != nurbs_indices.size ())
  {
    printf ("[GlobalOptimization::setCommonBoundary] Error, common boundary empty or size does not match.\n");
    return;
  }
}
Example #3
0
void
NurbsTools::downsample_random (const vector_vec3d &data1, vector_vec3d &data2, unsigned size)
{
  if (data1.size () <= size && size > 0)
  {
    data2 = data1;
    return;
  }

  unsigned s = data1.size ();
  data2.clear ();

  for (unsigned i = 0; i < size; i++)
  {
    unsigned rnd = unsigned (s * (double (rand ()) / RAND_MAX));
    data2.push_back (data1[rnd]);
  }
}
Example #4
0
ON_3dVector
NurbsTools::computeMean (const vector_vec3d &data)
{
  ON_3dVector u(0.0, 0.0, 0.0);

  unsigned s = data.size ();
  double ds = 1.0 / s;

  for (unsigned i = 0; i < s; i++)
    u += (data[i] * ds);

  return u;
}
Example #5
0
Eigen::Vector3d
NurbsTools::computeMean (const vector_vec3d &data)
{
  Eigen::Vector3d u (0.0, 0.0, 0.0);

  unsigned s = unsigned (data.size ());
  double ds = 1.0 / s;

  for (unsigned i = 0; i < s; i++)
    u += (data[i] * ds);

  return u;
}
Example #6
0
void
NurbsTools::pca (const vector_vec3d &data, ON_3dVector &mean, Eigen::Matrix3d &eigenvectors,
		 Eigen::Vector3d &eigenvalues)
{
  if (data.empty ())
  {
    printf ("[NurbsTools::pca] Error, data is empty\n");
    abort ();
  }

  mean = computeMean (data);

  unsigned s = data.size ();

  ON_Matrix Q(3, s);

  for (unsigned i = 0; i < s; i++) {
    Q[0][i] = data[i].x - mean.x;
    Q[1][i] = data[i].y - mean.y;
    Q[2][i] = data[i].z - mean.z;
  }

  ON_Matrix Qt = Q;
  Qt.Transpose();

  ON_Matrix oC;
  oC.Multiply(Q,Qt);

  Eigen::Matrix3d C(3,3);
  for (unsigned i = 0; i < 3; i++) {
      for (unsigned j = 0; j < 3; j++) {
	  C(i,j) = oC[i][j];
      }
  }

  Eigen::SelfAdjointEigenSolver < Eigen::Matrix3d > eigensolver (C);
  if (eigensolver.info () != Eigen::Success)
  {
    printf ("[NurbsTools::pca] Can not find eigenvalues.\n");
    abort ();
  }

  for (int i = 0; i < 3; ++i)
  {
    eigenvalues (i) = eigensolver.eigenvalues () (2 - i);
    if (i == 2)
      eigenvectors.col (2) = eigenvectors.col (0).cross (eigenvectors.col (1));
    else
      eigenvectors.col (i) = eigensolver.eigenvectors ().col (2 - i);
  }
}
Example #7
0
Eigen::Vector3d
NurbsTools::computeVariance (const Eigen::Vector3d &mean, const vector_vec3d &data)
{
  Eigen::Vector3d var (0.0, 0.0, 0.0);

  size_t s = data.size ();
  double ds = 1.0 / double (s);

  for (size_t i = 0; i < s; i++)
  {
    Eigen::Vector3d v = data[i] - mean;
    var += Eigen::Vector3d (v (0) * v (0) * ds, v (1) * v (1) * ds, v (2) * v (2) * ds);
  }

  return var;
}
Example #8
0
unsigned
NurbsTools::getClosestPoint (const Eigen::Vector3d &p, const vector_vec3d &data)
{
  if (data.empty ())
    throw std::runtime_error ("[NurbsTools::getClosestPoint(2d)] Data empty.\n");

  size_t idx = 0;
  double dist2 (DBL_MAX);
  for (size_t i = 0; i < data.size (); i++)
  {
    double d2 = (data[i] - p).squaredNorm ();
    if (d2 < dist2)
    {
      idx = i;
      dist2 = d2;
    }
  }
  return idx;
}
Example #9
0
unsigned
NurbsTools::getClosestPoint (const ON_3dPoint &p, const vector_vec3d &data)
{
  if (data.empty ())
    throw std::runtime_error ("[NurbsTools::getClosestPoint(2d)] Data empty.\n");

  unsigned idx (0);
  double dist2 (DBL_MAX);
  for (unsigned i = 0; i < data.size (); i++)
  {
    ON_3dVector v = (data[i] - p);
    double d2 = ON_DotProduct(v, v);  // Was the squaredNorm in Eigen
    if (d2 < dist2)
    {
      idx = i;
      dist2 = d2;
    }
  }
  return idx;
}
Example #10
0
void
NurbsTools::pca (const vector_vec3d &data, Eigen::Vector3d &mean, Eigen::Matrix3d &eigenvectors,
                 Eigen::Vector3d &eigenvalues)
{
  if (data.empty ())
  {
    printf ("[NurbsTools::pca] Error, data is empty\n");
    abort ();
  }

  mean = computeMean (data);

  unsigned s = unsigned (data.size ());

  Eigen::MatrixXd Q (3, s);

  for (unsigned i = 0; i < s; i++)
    Q.col (i) << (data[i] - mean);

  Eigen::Matrix3d C = Q * Q.transpose ();

  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver (C);
  if (eigensolver.info () != Success)
  {
    printf ("[NurbsTools::pca] Can not find eigenvalues.\n");
    abort ();
  }

  for (int i = 0; i < 3; ++i)
  {
    eigenvalues (i) = eigensolver.eigenvalues () (2 - i);
    if (i == 2)
      eigenvectors.col (2) = eigenvectors.col (0).cross (eigenvectors.col (1));
    else
      eigenvectors.col (i) = eigensolver.eigenvectors ().col (2 - i);
  }
}
Example #11
0
ON_NurbsCurve
FittingCurve::initNurbsCurvePCA (int order, const vector_vec3d &data, int ncps, double rf)
{
  if (data.empty ())
    printf ("[FittingCurve::initNurbsCurvePCA] Warning, no boundary parameters available\n");

  Eigen::Vector3d mean;
  Eigen::Matrix3d eigenvectors;
  Eigen::Vector3d eigenvalues;

  unsigned s = unsigned (data.size ());

  NurbsTools::pca (data, mean, eigenvectors, eigenvalues);

  eigenvalues = eigenvalues / s; // seems that the eigenvalues are dependent on the number of points (???)

  double r = rf * sqrt (eigenvalues (0));

  if (ncps < 2 * order)
    ncps = 2 * order;

  ON_NurbsCurve nurbs = ON_NurbsCurve (3, false, order, ncps);
  nurbs.MakePeriodicUniformKnotVector (1.0 / (ncps - order + 1));

  double dcv = (2.0 * M_PI) / (ncps - order + 1);
  Eigen::Vector3d cv, cv_t;
  for (int j = 0; j < ncps; j++)
  {
    cv (0) = r * sin (dcv * j);
    cv (1) = r * cos (dcv * j);
    cv (2) = 0.0;
    cv_t = eigenvectors * cv + mean;
    nurbs.SetCV (j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2)));
  }

  return nurbs;
}
Example #12
0
void
Triangulation::convertTrimmedSurface2PolygonMesh (const ON_NurbsSurface &nurbs, const ON_NurbsCurve &curve,
        PolygonMesh &mesh, unsigned resolution, vector_vec3d &start,
        vector_vec3d &end)
{
    // copy knots
    if (nurbs.KnotCount (0) <= 1 || nurbs.KnotCount (1) <= 1 || curve.KnotCount () <= 1)
    {
        printf ("[Triangulation::convertTrimmedSurface2PolygonMesh] Warning: ON knot vector empty.\n");
        return;
    }

    mesh.polygons.clear ();

    double x0 = nurbs.Knot (0, 0);
    double x1 = nurbs.Knot (0, nurbs.KnotCount (0) - 1);
    double w = x1 - x0;
    double y0 = nurbs.Knot (1, 0);
    double y1 = nurbs.Knot (1, nurbs.KnotCount (1) - 1);
    double h = y1 - y0;

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    std::vector<pcl::Vertices> polygons;
    createVertices (cloud, x0, y0, 0.0, w, h, resolution, resolution);
    createIndices (polygons, 0, resolution, resolution);

    vector_vec2d points (cloud->size (), Eigen::Vector2d ());
    std::vector<double> params (cloud->size (), 0.0);
    std::vector<bool> pt_is_in (cloud->size (), false);

    std::vector<uint32_t> out_idx;
    pcl::on_nurbs::vector_vec2d out_pc;

    for (unsigned i = 0; i < cloud->size (); i++)
    {
        double err, param;
        Eigen::Vector2d pc, tc;
        pcl::PointXYZ &v = cloud->at (i);
        Eigen::Vector2d vp (v.x, v.y);

        if(curve.Order()==2)
            param = pcl::on_nurbs::FittingCurve2d::inverseMappingO2 (curve, vp, err, pc, tc);
        else
        {
            param = pcl::on_nurbs::FittingCurve2d::findClosestElementMidPoint(curve, vp);
            param = pcl::on_nurbs::FittingCurve2d::inverseMapping(curve, vp, param, err, pc, tc);
        }

        Eigen::Vector3d a (vp (0) - pc (0), vp (1) - pc (1), 0.0);
        Eigen::Vector3d b (tc (0), tc (1), 0.0);
        Eigen::Vector3d z = a.cross (b);

        points[i] = pc;
        params[i] = param;
        pt_is_in[i] = (z (2) >= 0.0);

        end.push_back (Eigen::Vector3d (pc (0), pc (1), 0.0));
        start.push_back (Eigen::Vector3d (pc (0) + tc (0) * 0.01, pc (1) + tc (1) * 0.01, 0.0));
    }

    for (unsigned i = 0; i < polygons.size (); i++)
    {
        unsigned in (0);
        pcl::Vertices &poly = polygons[i];

        std::vector<uint32_t> out_idx_tmp;
        pcl::on_nurbs::vector_vec2d out_pc_tmp;

        for (std::size_t j = 0; j < poly.vertices.size (); j++)
        {
            uint32_t &vi = poly.vertices[j];
            if (pt_is_in[vi])
                in++;
            else
            {
                out_idx_tmp.push_back (vi);
                out_pc_tmp.push_back (points[vi]);
            }
        }

        if (in > 0)
        {
            mesh.polygons.push_back (poly);
            if (in < poly.vertices.size ())
            {
                for (std::size_t j = 0; j < out_idx_tmp.size (); j++)
                {
                    out_idx.push_back (out_idx_tmp[j]);
                    out_pc.push_back (out_pc_tmp[j]);
                }
            }
        }
    }

    for (std::size_t i = 0; i < out_idx.size (); i++)
    {
        pcl::PointXYZ &v = cloud->at (out_idx[i]);
        Eigen::Vector2d &pc = out_pc[i];
        v.x = pc (0);
        v.y = pc (1);
    }

    for (std::size_t i = 0; i < cloud->size (); i++)
    {
        pcl::PointXYZ &v = cloud->at (i);

        double point[3];
        nurbs.Evaluate (v.x, v.y, 0, 3, point);

        v.x = point[0];
        v.y = point[1];
        v.z = point[2];
    }

    for (std::size_t i = 0; i < start.size (); i++)
    {
        Eigen::Vector3d &p1 = start[i];
        Eigen::Vector3d &p2 = end[i];

        double point[3];
        nurbs.Evaluate (p1 (0), p1 (1), 0, 3, point);
        p1 (0) = point[0];
        p1 (1) = point[1];
        p1 (2) = point[2];

        nurbs.Evaluate (p2 (0), p2 (1), 0, 3, point);
        p2 (0) = point[0];
        p2 (1) = point[1];
        p2 (2) = point[2];
    }

    toROSMsg (*cloud, mesh.cloud);
}