Beispiel #1
0
void
Triangulation::convertSurface2PolygonMesh (const ON_NurbsSurface &nurbs, PolygonMesh &mesh, unsigned resolution)
{
  // copy knots
  if (nurbs.m_knot_capacity[0] <= 1 || nurbs.m_knot_capacity[1] <= 1)
  {
    printf ("[Triangulation::convert] Warning: ON knot vector empty.\n");
    return;
  }

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

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

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

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

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

  toROSMsg (*cloud, mesh.cloud);
}
Beispiel #2
0
void
Triangulation::convertSurface2Vertices (const ON_NurbsSurface &nurbs, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
                                        std::vector<pcl::Vertices> &vertices, unsigned resolution)
{
  // copy knots
  if (nurbs.KnotCount (0) <= 1 || nurbs.KnotCount (1) <= 1)
  {
    printf ("[Triangulation::convertSurface2Vertices] Warning: ON knot vector empty.\n");
    return;
  }

  cloud->clear ();
  vertices.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;

  createVertices (cloud, float (x0), float (y0), 0.0f, float (w), float (h), resolution, resolution);
  createIndices (vertices, 0, resolution, resolution);

  for (auto &v : *cloud)
  {
    double point[9];
    nurbs.Evaluate (v.x, v.y, 1, 3, point);

    v.x = static_cast<float> (point[0]);
    v.y = static_cast<float> (point[1]);
    v.z = static_cast<float> (point[2]);
  }
}
Beispiel #3
0
void
Triangulation::convertSurface2PolygonMesh (const ON_NurbsSurface &nurbs, PolygonMesh &mesh, unsigned resolution)
{
  // copy knots
  if (nurbs.KnotCount (0) <= 1 || nurbs.KnotCount (1) <= 1)
  {
    printf ("[Triangulation::convertSurface2PolygonMesh] Warning: ON knot vector empty.\n");
    return;
  }

  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>);
  mesh.polygons.clear ();
  createVertices (cloud, float (x0), float (y0), 0.0f, float (w), float (h), resolution, resolution);
  createIndices (mesh.polygons, 0, resolution, resolution);

  for (auto &v : *cloud)
  {
    double point[9];
    nurbs.Evaluate (v.x, v.y, 1, 3, point);

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

  toPCLPointCloud2 (*cloud, mesh.cloud);
}
Beispiel #4
0
void
Triangulation::convertCurve2PointCloud (const ON_NurbsCurve &curve, const ON_NurbsSurface &surf,
                                        pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud, unsigned resolution)
{
  // copy knots
  if (curve.m_knot_capacity <= 1)
  {
    printf ("[Triangulation::Convert] Warning: ON knot vector empty.\n");
    return;
  }

  cloud->clear ();

  if (resolution < 2)
    resolution = 2;

  int cp_red = curve.Order () - 2;

  // for each element of the nurbs curve
  for (int i = 1; i < curve.KnotCount () - 1 - cp_red; i++)
  {
    double dr = 1.0 / (resolution - 1);

    double xi0 = curve.m_knot[i];
    double xid = (curve.m_knot[i + 1] - xi0);

    for (unsigned j = 0; j < resolution; j++)
    {
      pcl::PointXYZRGB pt;

      double xi = (xi0 + j * dr * xid);

      double p[3];
      double pp[3];
      curve.Evaluate (xi, 0, 2, pp);
      surf.Evaluate (pp[0], pp[1], 0, 3, p);
      pt.x = p[0];
      pt.y = p[1];
      pt.z = p[2];
      pt.r = 255;
      pt.g = 0;
      pt.b = 0;

      cloud->push_back (pt);
    }

  }
}
Beispiel #5
0
void
visualizeCurve (ON_NurbsCurve &curve, ON_NurbsSurface &surface, pcl::visualization::PCLVisualizer &viewer)
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr curve_cloud (new pcl::PointCloud<pcl::PointXYZRGB>);

  pcl::on_nurbs::Triangulation::convertCurve2PointCloud (curve, surface, curve_cloud, 4);
  for (std::size_t i = 0; i < curve_cloud->size () - 1; i++)
  {
    pcl::PointXYZRGB &p1 = curve_cloud->at (i);
    pcl::PointXYZRGB &p2 = curve_cloud->at (i + 1);
    std::ostringstream os;
    os << "line" << i;
    viewer.removeShape (os.str ());
    viewer.addLine<pcl::PointXYZRGB> (p1, p2, 1.0, 0.0, 0.0, os.str ());
  }

  pcl::PointCloud<pcl::PointXYZRGB>::Ptr curve_cps (new pcl::PointCloud<pcl::PointXYZRGB>);
  for (int i = 0; i < curve.CVCount (); i++)
  {
    ON_3dPoint p1;
    curve.GetCV (i, p1);

    double pnt[3];
    surface.Evaluate (p1.x, p1.y, 0, 3, pnt);
    pcl::PointXYZRGB p2;
    p2.x = float (pnt[0]);
    p2.y = float (pnt[1]);
    p2.z = float (pnt[2]);

    p2.r = 255;
    p2.g = 0;
    p2.b = 0;

    curve_cps->push_back (p2);
  }
  viewer.removePointCloud ("cloud_cps");
  viewer.addPointCloud (curve_cps, "cloud_cps");
}
Beispiel #6
0
ON_2dPoint
FittingSurface::findClosestElementMidPoint (const ON_NurbsSurface &nurbs, const ON_3dPoint &pt)
{
  ON_2dPoint hint;
  ON_3dVector r;
  std::vector<double> elementsU = getElementVector (nurbs, 0);
  std::vector<double> elementsV = getElementVector (nurbs, 1);

  double d_shortest (DBL_MAX);
  for (unsigned i = 0; i < elementsU.size () - 1; i++)
  {
    for (unsigned j = 0; j < elementsV.size () - 1; j++)
    {
      double points[3];
      double d;

      double xi = elementsU[i] + 0.5 * (elementsU[i + 1] - elementsU[i]);
      double eta = elementsV[j] + 0.5 * (elementsV[j + 1] - elementsV[j]);

      nurbs.Evaluate (xi, eta, 0, 3, points);
      r[0] = points[0] - pt[0];
      r[1] = points[1] - pt[1];
      r[2] = points[2] - pt[2];

      d = ON_DotProduct(r,r);

      if ((i == 0 && j == 0) || d < d_shortest)
      {
	d_shortest = d;
	hint[0] = xi;
	hint[1] = eta;
      }
    }
  }

  return hint;
}
Vector2d
FittingSurface::findClosestElementMidPoint (const ON_NurbsSurface &nurbs, const Vector3d &pt)
{
  Vector2d hint;
  Vector3d r;
  std::vector<double> elementsU = getElementVector (nurbs, 0);
  std::vector<double> elementsV = getElementVector (nurbs, 1);

  double d_shortest (DBL_MAX);
  for (unsigned i = 0; i < elementsU.size () - 1; i++)
  {
    for (unsigned j = 0; j < elementsV.size () - 1; j++)
    {
      double points[3];
      double d;

      double xi = elementsU[i] + 0.5 * (elementsU[i + 1] - elementsU[i]);
      double eta = elementsV[j] + 0.5 * (elementsV[j + 1] - elementsV[j]);

      nurbs.Evaluate (xi, eta, 0, 3, points);
      r (0) = points[0] - pt (0);
      r (1) = points[1] - pt (1);
      r (2) = points[2] - pt (2);

      d = r.squaredNorm ();

      if ((i == 0 && j == 0) || d < d_shortest)
      {
        d_shortest = d;
        hint (0) = xi;
        hint (1) = eta;
      }
    }
  }

  return hint;
}
Beispiel #8
0
void
Triangulation::convertSurface2Vertices (const ON_NurbsSurface &nurbs, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
                                        std::vector<pcl::Vertices> &vertices, unsigned resolution)
{
  // copy knots
  if (nurbs.m_knot_capacity[0] <= 1 || nurbs.m_knot_capacity[1] <= 1)
  {
    printf ("[Triangulation::convert] Warning: ON knot vector empty.\n");
    return;
  }

  cloud->clear ();
  vertices.clear ();

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

  createVertices (cloud, x0, y0, 0.0, w, h, resolution, resolution);
  createIndices (vertices, 0, resolution, resolution);

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

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

    v.x = static_cast<float> (point[0]);
    v.y = static_cast<float> (point[1]);
    v.z = static_cast<float> (point[2]);
  }
}
Beispiel #9
0
Vector2d
FittingCylinder::inverseMapping (const ON_NurbsSurface &nurbs, const Vector3d &pt, const Vector2d &hint, double &error,
                                 Vector3d &p, Vector3d &tu, Vector3d &tv, int maxSteps, double accuracy, bool quiet)
{

  double pointAndTangents[9];

  Vector2d current, delta;
  Matrix2d A;
  Vector2d b;
  Vector3d r;
  std::vector<double> elementsU = getElementVector (nurbs, 0);
  std::vector<double> elementsV = getElementVector (nurbs, 1);
  double minU = elementsU[0];
  double minV = elementsV[0];
  double maxU = elementsU[elementsU.size () - 1];
  double maxV = elementsV[elementsV.size () - 1];

  current = hint;

  for (int k = 0; k < maxSteps; k++)
  {

    nurbs.Evaluate (current (0), current (1), 1, 3, pointAndTangents);
    p (0) = pointAndTangents[0];
    p (1) = pointAndTangents[1];
    p (2) = pointAndTangents[2];
    tu (0) = pointAndTangents[3];
    tu (1) = pointAndTangents[4];
    tu (2) = pointAndTangents[5];
    tv (0) = pointAndTangents[6];
    tv (1) = pointAndTangents[7];
    tv (2) = pointAndTangents[8];

    r = p - pt;

    b (0) = -r.dot (tu);
    b (1) = -r.dot (tv);

    A (0, 0) = tu.dot (tu);
    A (0, 1) = tu.dot (tv);
    A (1, 0) = A (0, 1);
    A (1, 1) = tv.dot (tv);

    delta = A.ldlt ().solve (b);

    if (delta.norm () < accuracy)
    {

      error = r.norm ();
      return current;

    }
    else
    {
      current = current + delta;
      if (current (0) < minU)
        current (0) = minU;
      else if (current (0) > maxU)
        current (0) = maxU;

      if (current (1) < minV)
        current (1) = maxV - (minV - current (1));
      else if (current (1) > maxV)
        current (1) = minV + (current (1) - maxV);
    }

  }

  error = r.norm ();

  if (!quiet)
  {
    printf ("[FittingCylinder::inverseMapping] Warning: Method did not converge (%e %d)\n", accuracy, maxSteps);
    printf ("  %f %f ... %f %f\n", hint (0), hint (1), current (0), current (1));
  }

  return current;
}
Beispiel #10
0
void
Triangulation::convertTrimmedSurface2PolygonMesh (const ON_NurbsSurface &nurbs, const ON_NurbsCurve &curve,
                                                  PolygonMesh &mesh, unsigned resolution)
{
  // copy knots
  if (nurbs.m_knot_capacity[0] <= 1 || nurbs.m_knot_capacity[1] <= 1)
  {
    printf ("[Triangulation::convert] Warning: ON knot vector empty.\n");
    return;
  }

  mesh.polygons.clear ();

  double x0 = nurbs.Knot (0, 0);
  double x1 = nurbs.Knot (0, nurbs.m_knot_capacity[0] - 1);
  double w = x1 - x0;
  double y0 = nurbs.Knot (1, 0);
  double y1 = nurbs.Knot (1, nurbs.m_knot_capacity[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);

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

  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++)
    {
      double err;
      Eigen::Vector2d pc, tc;
      uint32_t &vi = poly.vertices[j];
      pcl::PointXYZ &v = cloud->at (vi);
      Eigen::Vector2d vp (v.x, v.y);
      double param = pcl::on_nurbs::FittingCurve2d::findClosestElementMidPoint (curve, vp);
      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);
      if (z (2) >= 0.0)
        in++;
      else
      {
        out_idx_tmp.push_back (vi);
        out_pc_tmp.push_back (pc);
      }
    }

    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[9];
    nurbs.Evaluate (v.x, v.y, 1, 3, point);

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

  toROSMsg (*cloud, mesh.cloud);
}
Beispiel #11
0
ON_2dPoint
FittingSurface::inverseMappingBoundary (const ON_NurbsSurface &nurbs, const ON_3dPoint &pt, int side, double hint,
					double &error, ON_3dPoint &p, ON_3dVector &tu, ON_3dVector &tv, int maxSteps,
					double accuracy, bool quiet)
{

  double pointAndTangents[9];
  double current, delta;
  ON_3dVector r, t;
  ON_2dPoint params;

  current = hint;

  std::vector<double> elementsU = getElementVector (nurbs, 0);
  std::vector<double> elementsV = getElementVector (nurbs, 1);
  double minU = elementsU[0];
  double minV = elementsV[0];
  double maxU = elementsU[elementsU.size () - 1];
  double maxV = elementsV[elementsV.size () - 1];

  for (int k = 0; k < maxSteps; k++)
  {

    switch (side)
    {

      case WEST:

	params[0] = minU;
	params[1] = current;
	nurbs.Evaluate (minU, current, 1, 3, pointAndTangents);
	p[0] = pointAndTangents[0];
	p[1] = pointAndTangents[1];
	p[2] = pointAndTangents[2];
	tu[0] = pointAndTangents[3];
	tu[1] = pointAndTangents[4];
	tu[2] = pointAndTangents[5];
	tv[0] = pointAndTangents[6];
	tv[1] = pointAndTangents[7];
	tv[2] = pointAndTangents[8];

	t = tv; // use tv

	break;
      case SOUTH:

	params[0] = current;
	params[1] = maxV;
	nurbs.Evaluate (current, maxV, 1, 3, pointAndTangents);
	p[0] = pointAndTangents[0];
	p[1] = pointAndTangents[1];
	p[2] = pointAndTangents[2];
	tu[0] = pointAndTangents[3];
	tu[1] = pointAndTangents[4];
	tu[2] = pointAndTangents[5];
	tv[0] = pointAndTangents[6];
	tv[1] = pointAndTangents[7];
	tv[2] = pointAndTangents[8];

	t = tu; // use tu

	break;
      case EAST:

	params[0] = maxU;
	params[1] = current;
	nurbs.Evaluate (maxU, current, 1, 3, pointAndTangents);
	p[0] = pointAndTangents[0];
	p[1] = pointAndTangents[1];
	p[2] = pointAndTangents[2];
	tu[0] = pointAndTangents[3];
	tu[1] = pointAndTangents[4];
	tu[2] = pointAndTangents[5];
	tv[0] = pointAndTangents[6];
	tv[1] = pointAndTangents[7];
	tv[2] = pointAndTangents[8];

	t = tv; // use tv

	break;
      case NORTH:

	params[0] = current;
	params[1] = minV;
	nurbs.Evaluate (current, minV, 1, 3, pointAndTangents);
	p[0] = pointAndTangents[0];
	p[1] = pointAndTangents[1];
	p[2] = pointAndTangents[2];
	tu[0] = pointAndTangents[3];
	tu[1] = pointAndTangents[4];
	tu[2] = pointAndTangents[5];
	tv[0] = pointAndTangents[6];
	tv[1] = pointAndTangents[7];
	tv[2] = pointAndTangents[8];

	t = tu; // use tu

	break;
      default:
	throw std::runtime_error ("[FittingSurface::inverseMappingBoundary] ERROR: Specify a boundary!");

    }

    r[0] = pointAndTangents[0] - pt[0];
    r[1] = pointAndTangents[1] - pt[1];
    r[2] = pointAndTangents[2] - pt[2];

    delta = -0.5 * ON_DotProduct(r,t) / ON_DotProduct(t,t);

    if (fabs (delta) < accuracy)
    {

      error = sqrt(ON_DotProduct(r,r));
      return params;

    }
    else
    {

      current = current + delta;

      bool stop = false;

      switch (side)
      {

	case WEST:
	case EAST:
	  if (current < minV)
	  {
	    params[1] = minV;
	    stop = true;
	  }
	  else if (current > maxV)
	  {
	    params[1] = maxV;
	    stop = true;
	  }

	  break;

	case NORTH:
	case SOUTH:
	  if (current < minU)
	  {
	    params[0] = minU;
	    stop = true;
	  }
	  else if (current > maxU)
	  {
	    params[0] = maxU;
	    stop = true;
	  }

	  break;
      }

      if (stop)
      {
	error = sqrt(ON_DotProduct(r,r));
	return params;
      }

    }

  }

  error = sqrt(ON_DotProduct(r,r));
  if (!quiet)
    printf (
	    "[FittingSurface::inverseMappingBoundary] Warning: Method did not converge! (residual: %f, delta: %f, params: %f %f)\n",
	    error, delta, params[0], params[1]);

  return params;
}
Beispiel #12
0
ON_2dPoint
FittingSurface::inverseMapping (const ON_NurbsSurface &nurbs, const ON_3dPoint &pt, const ON_2dPoint &hint, double &error,
				ON_3dPoint &p, ON_3dVector &tu, ON_3dVector &tv, int maxSteps, double accuracy, bool quiet)
{

  double pointAndTangents[9];

  ON_2dVector current, delta;
  ON_Matrix A(2,2);
  ON_2dVector b;
  ON_3dVector r;
  std::vector<double> elementsU = getElementVector (nurbs, 0);
  std::vector<double> elementsV = getElementVector (nurbs, 1);
  double minU = elementsU[0];
  double minV = elementsV[0];
  double maxU = elementsU[elementsU.size () - 1];
  double maxV = elementsV[elementsV.size () - 1];

  current = hint;

  for (int k = 0; k < maxSteps; k++)
  {

    nurbs.Evaluate (current[0], current[1], 1, 3, pointAndTangents);
    p[0] = pointAndTangents[0];
    p[1] = pointAndTangents[1];
    p[2] = pointAndTangents[2];
    tu[0] = pointAndTangents[3];
    tu[1] = pointAndTangents[4];
    tu[2] = pointAndTangents[5];
    tv[0] = pointAndTangents[6];
    tv[1] = pointAndTangents[7];
    tv[2] = pointAndTangents[8];

    r = p - pt;

    b[0] = -ON_DotProduct(r,tu);
    b[1] = -ON_DotProduct(r,tv);

    A[0][0] = ON_DotProduct(tu,tu);
    A[0][1] = ON_DotProduct(tu,tv);
    A[1][0] = A[0][1];
    A[1][1] = ON_DotProduct(tv,tv);

    Eigen::Vector2d eb(b[0],b[1]);
    Eigen::Vector2d edelta;
    Eigen::Matrix2d eA;

    eA (0, 0) = A[0][0];
    eA (0, 1) = A[0][1];
    eA (1, 0) = A[1][0];
    eA (1, 1) = A[1][1];

    edelta = eA.ldlt ().solve (eb);

    delta[0] = edelta (0);
    delta[1] = edelta (1);

    if (sqrt(ON_DotProduct(delta,delta)) < accuracy)
    {

      error = sqrt(ON_DotProduct(r,r));
      return current;

    }
    else
    {
      current = current + delta;

      if (current[0] < minU)
	current[0] = minU;
      else if (current[0] > maxU)
	current[0] = maxU;

      if (current[1] < minV)
	current[1] = minV;
      else if (current[1] > maxV)
	current[1] = maxV;

    }

  }

  error = sqrt(ON_DotProduct(r,r));
  if (!quiet)
  {
    printf ("[FittingSurface::inverseMapping] Warning: Method did not converge (%e %d)\n", accuracy, maxSteps);
    printf ("  %f %f ... %f %f\n", hint[0], hint[1], current[0], current[1]);
  }

  return current;

}
Vector2d
FittingSurface::inverseMappingBoundary (const ON_NurbsSurface &nurbs, const Vector3d &pt, int side, double hint,
                                        double &error, Vector3d &p, Vector3d &tu, Vector3d &tv, int maxSteps,
                                        double accuracy, bool quiet)
{

  double pointAndTangents[9];
  double current, delta;
  Vector3d r, t;
  Vector2d params;

  current = hint;

  std::vector<double> elementsU = getElementVector (nurbs, 0);
  std::vector<double> elementsV = getElementVector (nurbs, 1);
  double minU = elementsU[0];
  double minV = elementsV[0];
  double maxU = elementsU[elementsU.size () - 1];
  double maxV = elementsV[elementsV.size () - 1];

  for (int k = 0; k < maxSteps; k++)
  {

    switch (side)
    {

      case WEST:

        params (0) = minU;
        params (1) = current;
        nurbs.Evaluate (minU, current, 1, 3, pointAndTangents);
        p (0) = pointAndTangents[0];
        p (1) = pointAndTangents[1];
        p (2) = pointAndTangents[2];
        tu (0) = pointAndTangents[3];
        tu (1) = pointAndTangents[4];
        tu (2) = pointAndTangents[5];
        tv (0) = pointAndTangents[6];
        tv (1) = pointAndTangents[7];
        tv (2) = pointAndTangents[8];

        t = tv; // use tv

        break;
      case SOUTH:

        params (0) = current;
        params (1) = maxV;
        nurbs.Evaluate (current, maxV, 1, 3, pointAndTangents);
        p (0) = pointAndTangents[0];
        p (1) = pointAndTangents[1];
        p (2) = pointAndTangents[2];
        tu (0) = pointAndTangents[3];
        tu (1) = pointAndTangents[4];
        tu (2) = pointAndTangents[5];
        tv (0) = pointAndTangents[6];
        tv (1) = pointAndTangents[7];
        tv (2) = pointAndTangents[8];

        t = tu; // use tu

        break;
      case EAST:

        params (0) = maxU;
        params (1) = current;
        nurbs.Evaluate (maxU, current, 1, 3, pointAndTangents);
        p (0) = pointAndTangents[0];
        p (1) = pointAndTangents[1];
        p (2) = pointAndTangents[2];
        tu (0) = pointAndTangents[3];
        tu (1) = pointAndTangents[4];
        tu (2) = pointAndTangents[5];
        tv (0) = pointAndTangents[6];
        tv (1) = pointAndTangents[7];
        tv (2) = pointAndTangents[8];

        t = tv; // use tv

        break;
      case NORTH:

        params (0) = current;
        params (1) = minV;
        nurbs.Evaluate (current, minV, 1, 3, pointAndTangents);
        p (0) = pointAndTangents[0];
        p (1) = pointAndTangents[1];
        p (2) = pointAndTangents[2];
        tu (0) = pointAndTangents[3];
        tu (1) = pointAndTangents[4];
        tu (2) = pointAndTangents[5];
        tv (0) = pointAndTangents[6];
        tv (1) = pointAndTangents[7];
        tv (2) = pointAndTangents[8];

        t = tu; // use tu

        break;
      default:
        throw std::runtime_error ("[FittingSurface::inverseMappingBoundary] ERROR: Specify a boundary!");

    }

    r (0) = pointAndTangents[0] - pt (0);
    r (1) = pointAndTangents[1] - pt (1);
    r (2) = pointAndTangents[2] - pt (2);

    delta = -0.5 * r.dot (t) / t.dot (t);

    if (fabs (delta) < accuracy)
    {

      error = r.norm ();
      return params;

    }
    else
    {

      current = current + delta;

      bool stop = false;

      switch (side)
      {

        case WEST:
        case EAST:
          if (current < minV)
          {
            params (1) = minV;
            stop = true;
          }
          else if (current > maxV)
          {
            params (1) = maxV;
            stop = true;
          }

          break;

        case NORTH:
        case SOUTH:
          if (current < minU)
          {
            params (0) = minU;
            stop = true;
          }
          else if (current > maxU)
          {
            params (0) = maxU;
            stop = true;
          }

          break;
      }

      if (stop)
      {
        error = r.norm ();
        return params;
      }

    }

  }

  error = r.norm ();
  if (!quiet)
    printf (
            "[FittingSurface::inverseMappingBoundary] Warning: Method did not converge! (residual: %f, delta: %f, params: %f %f)\n",
            error, delta, params (0), params (1));

  return params;
}
Beispiel #14
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);
}
Beispiel #15
0
void
Triangulation::convertTrimmedSurface2PolygonMesh (const ON_NurbsSurface &nurbs, const ON_NurbsCurve &curve,
                                                  PolygonMesh &mesh, unsigned resolution)
{
  // 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, float (x0), float (y0), 0.0f, float (w), float (h), resolution, resolution);
  createIndices (polygons, 0, resolution, resolution);

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

  Eigen::Vector3d a0, a1;
  pcl::on_nurbs::NurbsTools::computeBoundingBox (curve, a0, a1);
  double rScale = 1.0 / pcl::on_nurbs::NurbsTools::computeRScale (a0, a1);

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

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

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

    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;
    pt_is_in[i] = (z (2) >= 0.0);
  }

  for (const auto &poly : polygons)
  {
    unsigned in (0);
    std::vector<uint32_t> out_idx_tmp;
    pcl::on_nurbs::vector_vec2d out_pc_tmp;

    for (const unsigned int &vi : poly.vertices)
    {
      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 = float (pc (0));
    v.y = float (pc (1));
  }

  for (auto &v : *cloud)
  {
    Eigen::Vector3d tu, tv;

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

    v.x = float (point[0]);
    v.y = float (point[1]);
    v.z = float (point[2]);
    //    tu[0] = point[3];
    //    tu[1] = point[4];
    //    tu[2] = point[5];
    //    tv[0] = point[6];
    //    tv[1] = point[7];
    //    tv[2] = point[8];

    // TODO: add normals to mesh
  }

  toPCLPointCloud2 (*cloud, mesh.cloud);
}