CRhinoCommand::result CCommandSampleIntepCrvOnSrf::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoGetObject go; 
  go.SetCommandPrompt( L"Select surface to draw curve on" );
  go.SetGeometryFilter( CRhinoObject::surface_object);
  go.GetObjects( 1, 1 );
  if( go.CommandResult() != CRhinoCommand::success )
    return go.CommandResult();
	 
  const CRhinoObject* obj = go.Object(0).Object();
  const ON_BrepFace* face = go.Object(0).Face();
  if( 0 == obj || 0 == face )
    return CRhinoCommand::failure;

	ON_SimpleArray<ON_2dPoint> points2d(25);

	CRhinoGetPoint gp;
  gp.Constrain( *face, obj->Attributes().m_wire_density );

  for(;;)
  {
    gp.ClearCommandOptions();

    if( points2d.Count() < 1 )
      gp.SetCommandPrompt( L"Start of curve" );
    else if( points2d.Count() == 1 )
      gp.SetCommandPrompt( L"Next point" );
    else 
      gp.SetCommandPrompt( L"Next point. Press Enter when done" );

    gp.AcceptUndo( points2d.Count() > 0 );

		gp.AcceptNothing();

    CRhinoGet::result res = gp.GetPoint();
		
    if( res == CRhinoGet::cancel)
			return CRhinoCommand::cancel;
		
    else if ( res == CRhinoGet::undo)
    {
      points2d.Remove(); // remove last point
      continue;
    }
    else if( res == CRhinoGet::point)
    {
			ON_2dPoint pt;
			if( gp.PointOnSurface(&pt.x, &pt.y) )
      {
        int count = points2d.Count();
        if( count > 0 )
        {
          ON_2dVector v = *points2d.At(count-1) - pt;
          if ( v.IsTiny())
            continue;
        }

			  points2d.Append( pt );
      }
      continue;
		}
		
  	break;
	}
	
  const int count = points2d.Count();
  if( count >  1)
  {
    // Check for closed curve
    int is_closed = 0;
    if( count > 3 )
    {
      ON_2dPoint pt = points2d[0];
      if( pt.DistanceTo(points2d[count-1]) < ON_SQRT_EPSILON )
        is_closed = 1;
    }

    double tol = context.m_doc.AbsoluteTolerance();
    ON_Curve* crv = RhinoInterpolatePointsOnSurface( *face, points2d, is_closed, tol, 1 ); 
    if( crv )
    {
      CRhinoCurveObject* crv_obj = new CRhinoCurveObject();
      crv_obj->SetCurve( crv );
      context.m_doc.AddObject( crv_obj );
      context.m_doc.Redraw();
    }

  	return CRhinoCommand::success;
  }

  return CRhinoCommand::success;
}
Пример #2
0
void
triangulatePoints(InputArrayOfArrays _points2d, InputArrayOfArrays _projection_matrices,
                  OutputArray _points3d)
{
    // check
    size_t nviews = (unsigned) _points2d.total();
    CV_Assert(nviews >= 2 && nviews == _projection_matrices.total());

    // inputs
    size_t n_points;
    vector<Mat_<double> > points2d(nviews);
    vector<Matx34d> projection_matrices(nviews);
    {
        vector<Mat> points2d_tmp;
        _points2d.getMatVector(points2d_tmp);
        n_points = points2d_tmp[0].cols;

        vector<Mat> projection_matrices_tmp;
        _projection_matrices.getMatVector(projection_matrices_tmp);

        // Make sure the dimensions are right
        for(size_t i=0; i<nviews; ++i) {
            CV_Assert(points2d_tmp[i].rows == 2 && points2d_tmp[i].cols == n_points);
            if (points2d_tmp[i].type() == CV_64F)
                points2d[i] = points2d_tmp[i];
            else
                points2d_tmp[i].convertTo(points2d[i], CV_64F);

            CV_Assert(projection_matrices_tmp[i].rows == 3 && projection_matrices_tmp[i].cols == 4);
            if (projection_matrices_tmp[i].type() == CV_64F)
              projection_matrices[i] = projection_matrices_tmp[i];
            else
              projection_matrices_tmp[i].convertTo(projection_matrices[i], CV_64F);
        }
    }

    // output
    _points3d.create(3, n_points, CV_64F);
    cv::Mat points3d = _points3d.getMat();

    // Two view
    if( nviews == 2 )
    {
        const Mat_<double> &xl = points2d[0], &xr = points2d[1];

        const Matx34d & Pl = projection_matrices[0];    // left matrix projection
        const Matx34d & Pr = projection_matrices[1];    // right matrix projection

        // triangulate
        for( unsigned i = 0; i < n_points; ++i )
        {
            Vec3d point3d;
            triangulateDLT( Vec2d(xl(0,i), xl(1,i)), Vec2d(xr(0,i), xr(1,i)), Pl, Pr, point3d );
            for(char j=0; j<3; ++j)
                points3d.at<double>(j, i) = point3d[j];
        }
    }
    else if( nviews > 2 )
    {
        // triangulate
        for( unsigned i=0; i < n_points; ++i )
        {
            // build x matrix (one point per view)
            Mat_<double> x( 2, nviews );
            for( unsigned k=0; k < nviews; ++k )
            {
                points2d.at(k).col(i).copyTo( x.col(k) );
            }

            Vec3d point3d;
            nViewTriangulate( x, projection_matrices, point3d );
            for(char j=0; j<3; ++j)
                points3d.at<double>(j, i) = point3d[j];
        }
    }
}