CRhinoCommand::result CCommandSampleTriangulatePolygon::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoGetObject go;
  go.SetCommandPrompt( L"Select closed planar polygon to triangulate" );
  go.SetGeometryFilter( CRhinoGetObject::curve_object );
  go.SetGeometryFilter( CRhinoGetObject::closed_curve );
  go.EnableSubObjectSelect( FALSE );
  go.GetObjects( 1, 1 );
  if( go.CommandResult() != CRhinoCommand::success )
    return go.CommandResult();

  const CRhinoObjRef& ref = go.Object(0);

  ON_3dPointArray vertices;

  const ON_PolylineCurve* pc = ON_PolylineCurve::Cast( ref.Curve() );
  if( pc )
  {
    vertices = pc->m_pline;
  }
  else
  {
    const ON_NurbsCurve* nc = ON_NurbsCurve::Cast( ref.Curve() );
    if( nc )
      nc->IsPolyline( &vertices );
  }

  if( vertices.Count() < 5 )
  {
    RhinoApp().Print( L"Curve not polygon with at least four sides.\n" );
    return CRhinoCommand::nothing;
  }

  int* triangles = (int*)onmalloc( (vertices.Count()-3) * sizeof(int) * 3 );
  if( 0 == triangles )
    return CRhinoCommand::failure; // out of memory
  
  memset( triangles, 0, (vertices.Count()-3) * sizeof(int) * 3 );

  int rc = RhinoTriangulate3dPolygon( vertices.Count()-1, 3, (const double*)vertices.Array(), 3, triangles);
  if( 0 == rc )
  {
    int i;
    for( i = 0; i < vertices.Count()-3; i++ )
    {
      ON_Polyline pline;
      pline.Append( vertices[triangles[i * 3]] );
      pline.Append( vertices[triangles[i * 3 + 1]] );
      pline.Append( vertices[triangles[i * 3 + 2]] );
      pline.Append( pline[0] );
      context.m_doc.AddCurveObject( pline );
    }
    context.m_doc.Redraw();
  }

  onfree( triangles );

  return CRhinoCommand::success;
}
CRhinoCommand::result CCommandSampleWindowPick::RunCommand( const CRhinoCommandContext& context )
{
    CRhinoGetObject go;
    go.SetCommandPrompt( L"Select point cloud" );
    go.SetGeometryFilter( CRhinoGetObject::pointset_object );
    go.EnableSubObjectSelect( false );
    go.GetObjects( 1, 1 );
    if( go.CommandResult() != CRhinoCommand::success )
        return go.CommandResult();

    const CRhinoPointCloudObject* obj = CRhinoPointCloudObject::Cast( go.Object(0).Object() );
    if( 0 == obj )
        return CRhinoCommand::failure;

    const ON_PointCloud& cloud = obj->PointCloud();

    obj->Select( false );
    context.m_doc.Redraw();

    CRhinoGetPoint gp;
    gp.SetCommandPrompt( L"Drag a window to select point cloud points" );
    gp.ConstrainToTargetPlane();
    gp.AcceptNothing();
    gp.SetGetPointCursor( RhinoApp().m_default_cursor );
    gp.Get2dRectangle();
    if( gp.CommandResult() != CRhinoCommand::success )
        return gp.CommandResult();

    ON_SimpleArray<int> indices;
    const int index_count = RhWindowsSelectPointCloudPoints( gp.View(), cloud, gp.Rectangle2d(), indices );
    if( 0 == index_count )
        return CRhinoCommand::nothing;

    int i;
    for( i = 0; i < index_count; i++ )
        obj->SelectSubObject( ON_COMPONENT_INDEX(ON_COMPONENT_INDEX::pointcloud_point, indices[i]), true );
    context.m_doc.Redraw();

    CRhinoGetString gs;
    gs.SetCommandPrompt( L"Press <Enter> to continue" );
    gs.AcceptNothing();
    gs.GetString();

    for( i = 0; i < index_count; i++ )
        obj->SelectSubObject( ON_COMPONENT_INDEX(ON_COMPONENT_INDEX::pointcloud_point, indices[i]), false );
    context.m_doc.Redraw();

    return CRhinoCommand::success;
}
CRhinoCommand::result CCommandSampleRegionPick::RunCommand( const CRhinoCommandContext& context )
{
    CRhinoGetObject go;
    go.SetCommandPrompt( L"Select point cloud" );
    go.SetGeometryFilter( CRhinoGetObject::pointset_object );
    go.EnableSubObjectSelect( false );
    go.GetObjects( 1, 1 );
    if( go.CommandResult() != CRhinoCommand::success )
        return go.CommandResult();

    const CRhinoPointCloudObject* obj = CRhinoPointCloudObject::Cast( go.Object(0).Object() );
    if( 0 == obj )
        return CRhinoCommand::failure;

    const ON_PointCloud& cloud = obj->PointCloud();

    obj->Select( false );
    context.m_doc.Redraw();

    CRhGetRegionPoints gp;
    gp.SetCommandPrompt( L"Click and drag, or repeatedly click to lasso point cloud points. Press Enter when done" );
    gp.AcceptNothing();
    gp.SetGetPointCursor( RhinoApp().m_default_cursor );
    gp.GetPoints();
    if( gp.Result() == CRhinoGet::point )
        return CRhinoCommand::cancel;

    ON_SimpleArray<int> indices;
    const int index_count = RhRegionSelectPointCloudPoints( gp.View(), cloud, gp.m_points, indices );
    if( 0 == index_count )
        return CRhinoCommand::nothing;

    int i;
    for( i = 0; i < index_count; i++ )
        obj->SelectSubObject( ON_COMPONENT_INDEX(ON_COMPONENT_INDEX::pointcloud_point, indices[i]), true );
    context.m_doc.Redraw();

    CRhinoGetString gs;
    gs.SetCommandPrompt( L"Press <Enter> to continue" );
    gs.AcceptNothing();
    gs.GetString();

    for( i = 0; i < index_count; i++ )
        obj->SelectSubObject( ON_COMPONENT_INDEX(ON_COMPONENT_INDEX::pointcloud_point, indices[i]), false );
    context.m_doc.Redraw();

    return CRhinoCommand::success;
}
Esempio n. 4
0
CRhinoCommand::result CCommandNewName::RunCommand( const CRhinoCommandContext& context )
{
	// Select an object to modify
  CRhinoGetObject go;
  go.SetCommandPrompt( L"Select object to change name" );
  go.EnablePreSelect( TRUE );
  go.EnableSubObjectSelect( FALSE );
  go.GetObjects( 1, 1 );
  if( go.CommandResult() != CRhinoCommand::success )
    return go.CommandResult();
 
  // Get the object reference
  const CRhinoObjRef& objref = go.Object(0);
 
  // Get the object
  const CRhinoObject* obj = objref.Object();
  if( !obj )
    return CRhinoCommand::failure;
 
  // Make copy of object attributes. This objects
  // holds an object's user-defined name.
  ON_3dmObjectAttributes obj_attribs = obj->Attributes();
 
  // Prompt for new object name
  CRhinoGetString gs;
  gs.SetCommandPrompt( L"New object name" );
  gs.SetDefaultString( obj_attribs.m_name );
  gs.AcceptNothing( TRUE );
  gs.GetString();
  if( gs.CommandResult() != CRhinoCommand::success )
    return gs.CommandResult();
 
  // Get the string entered by the user
  ON_wString obj_name = gs.String();
  obj_name.TrimLeftAndRight();
 
  // Is name the same?
  if( obj_name.Compare(obj_attribs.m_name) == 0 )
    return CRhinoCommand::nothing;
 
  // Modify the attributes of the object
  obj_attribs.m_name = obj_name;
  context.m_doc.ModifyObjectAttributes( objref, obj_attribs );
 
  return CRhinoCommand::success;

}
CRhinoCommand::result CCommandSampleFindCrvsOnSrf::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoGetObject go;
  go.SetCommandPrompt( L"Select surface" );
  go.SetGeometryFilter( CRhinoGetObject::surface_object );
  go.EnableSubObjectSelect( true );
  go.GetObjects( 1, 1 );
  if( go.CommandResult() != CRhinoCommand::success )
    return go.CommandResult();

  const ON_BrepFace* face = go.Object(0).Face();
  if( 0 == face )
    return CRhinoCommand::failure;

  ON_BoundingBox face_bbox = face->BoundingBox();
  double tol = context.m_doc.AbsoluteTolerance();
  bool bRedraw = false;

  const CRhinoObject* obj = 0;
  CRhinoObjectIterator it( CRhinoObjectIterator::normal_objects, CRhinoObjectIterator::active_and_reference_objects );
  for( obj = it.First(); obj; obj = it.Next() )
  {
    const CRhinoCurveObject* crv_obj = CRhinoCurveObject::Cast( obj );
    if( 0 == crv_obj )
      continue;

    ON_BoundingBox crv_bbox = crv_obj->BoundingBox();
    if( !face_bbox.Includes(crv_bbox) )
      continue;

    if( !IsCurveOnFace(face, crv_obj->Curve(), tol) )
      continue;

    crv_obj->Select( true );
    bRedraw = true;
  }

  if( bRedraw )
    context.m_doc.Redraw();

	return CRhinoCommand::success;
}
CRhinoCommand::result CCommandSampleOrientOnCrv::SelectObjects( CRhinoXformObjectList& object_list )
{
  object_list.Empty();

  CRhinoGetObject get;
  get.SetCommandPrompt( L"Select objects to orient" );
  get.EnablePreSelect();
  get.EnableSubObjectSelect( FALSE );
  get.AcceptNothing();
  get.GetObjects(1, 0);
  
  CRhinoCommand::result rc = get.CommandResult();
  if( rc == CRhinoCommand::success )
  {
    if( object_list.AddObjects( get ) < 1 )
      rc = CRhinoCommand::failure;
  }

  return rc;
}
CRhinoCommand::result CCommandSamplePrePostSelect::RunCommand( const CRhinoCommandContext& context )
{
  double dValue = m_dValue;
  int nValue = m_nValue;

  CRhinoGetObject go;
  go.SetGeometryFilter( CRhinoGetObject::curve_object );
  go.EnableGroupSelect( TRUE );
  go.EnableSubObjectSelect( FALSE );

  /*int d_option_index =*/ go.AddCommandOptionNumber( 
      RHCMDOPTNAME(L"Double"), &dValue, L"Double value", FALSE, 1.0, 99.9 );

  /*int n_option_index =*/ go.AddCommandOptionInteger( 
      RHCMDOPTNAME(L"Integer"), &nValue, L"Integer value", 1, 99 );

  bool bHavePreselectedObjects = false;

  for( ;; )
  {
    CRhinoGet::result res = go.GetObjects( 1, 0 );

    if( res == CRhinoGet::option )
    {
      go.EnablePreSelect( FALSE );
      go.EnableAlreadySelectedObjectSelect( true );
      go.EnableClearObjectsOnEntry( false );
      go.EnableDeselectAllBeforePostSelect( false );
      go.EnableUnselectObjectsOnExit( false );
      continue;
    }

    else if( res != CRhinoGet::object )
      return CRhinoCommand::cancel;

    if( go.ObjectsWerePreSelected() )
    {
      bHavePreselectedObjects = true;
      go.EnablePreSelect( FALSE );
      go.EnableAlreadySelectedObjectSelect( true );
      go.EnableClearObjectsOnEntry( false );
      go.EnableDeselectAllBeforePostSelect( false );
      go.EnableUnselectObjectsOnExit( false );
      continue;
    }

    break;
  }

  if( bHavePreselectedObjects )
  {
    // Normally, pre-selected objects will remain selected, when a
    // command finishes, and post-selected objects will be unselected.
    // This this way of picking, it is possible to have a combination
    // of pre-selected and post-selected. So, to make sure everything
    // "looks the same", lets unselect everything before finishing
    // the command.
    for( int i = 0; i < go.ObjectCount(); i++ )
    {
      const CRhinoObject* object = go.Object(i).Object();
      if( 0 != object )
        object->Select( false );
    }
    context.m_doc.Redraw();
  }

  int object_count = go.ObjectCount();
  m_dValue = dValue;
  m_nValue = nValue;

  RhinoApp().Print( L"Select object count = %d\n", object_count );
  RhinoApp().Print( L"Value of double = %f\n", m_dValue );
  RhinoApp().Print( L"Value of integer = %d\n", m_nValue );

  return CRhinoCommand::success;
}
CRhinoCommand::result CCommandSampleOrientOnSrf::RunCommand( const CRhinoCommandContext& context )
{
  // Select objects to orient
	CRhinoGetObject go;
  go.SetCommandPrompt( L"Select objects to orient" );
  go.EnableSubObjectSelect( FALSE );
  go.EnableGroupSelect( TRUE );
  go.GetObjects( 1, 0 );
  if( go.CommandResult() != CRhinoCommand::success )
    return go.CommandResult();

  // Point to orient from
  CRhinoGetPoint gp;
  gp.SetCommandPrompt( L"Point to orient from" );
  gp.GetPoint();
  if( gp.CommandResult() != CRhinoCommand::success )
    return gp.CommandResult();

  // Define source plane
  CRhinoView* view = gp.View();
  if( 0 == view )
  {
    view = RhinoApp().ActiveView();
    if( 0 == view )
      return CRhinoCommand::failure;
  }
  ON_Plane source_plane( view->Viewport().ConstructionPlane().m_plane );
  source_plane.SetOrigin( gp.Point() );

  // Surface to orient on
  CRhinoGetObject gs;
  gs.SetCommandPrompt( L"Surface to orient on" );
  gs.SetGeometryFilter( CRhinoGetObject::surface_object );
  gs.EnableSubObjectSelect( TRUE );
  gs.EnableDeselectAllBeforePostSelect( false );
  gs.EnableOneByOnePostSelect();
  gs.GetObjects( 1, 1 );
  if( gs.CommandResult() != CRhinoCommand::success )
    return gs.CommandResult();

  const CRhinoObjRef& ref = gs.Object(0);
  // Get selected surface object
  const CRhinoObject* obj = ref.Object();
  if( 0 == obj )
    return CRhinoCommand::failure;
  // Get selected surface (face)
  const ON_BrepFace* face = ref.Face();
  if( 0 == face )
    return CRhinoCommand::failure;
  // Unselect surface
  obj->Select( false );

  // Point on surface to orient to
  gp.SetCommandPrompt( L"Point on surface to orient to" );
  gp.Constrain( *face );
  gp.GetPoint();
  if( gp.CommandResult() != CRhinoCommand::success )
    return gp.CommandResult();

  // Do transformation
  CRhinoCommand::result rc = CRhinoCommand::failure;
  double u = 0.0, v = 0.0;
  if( face->GetClosestPoint(gp.Point(), &u, &v) )
  {
    ON_Plane target_plane;
    if( face->FrameAt(u, v, target_plane) )
    {
      // If the face orientation is opposite
      // of natural surface orientation, then
      // flip the plane's zaxis.
      if( face->m_bRev )
        target_plane.CreateFromFrame( 
            target_plane.origin, 
            target_plane.xaxis, 
            -target_plane.zaxis 
            );

      // Build transformation
      ON_Xform xform;
      xform.Rotation( source_plane, target_plane );

      // Do the transformation. In this example,
      // we will copy the original objects
      bool bDeleteOriginal = false;
      int i;
      for( i = 0; i < go.ObjectCount(); i++ )
        context.m_doc.TransformObject( go.Object(i), xform, bDeleteOriginal );
      context.m_doc.Redraw();
      rc = CRhinoCommand::success;
    }
  }

	return rc;
}
CRhinoCommand::result CCommandSampleUnrollSurface::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoGetObject go;
  go.SetCommandPrompt( L"Select surface or polysurface to unroll" );
  go.SetGeometryFilter( CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object );
  go.EnableSubObjectSelect( FALSE );
  go.GetObjects( 1, 1 );
  if( go.CommandResult() != CRhinoCommand::success )
    return go.CommandResult();

  const CRhinoObject* pObject = go.Object(0).Object();
  const ON_Brep* pBrep = go.Object(0).Brep();
  if( 0 == pObject || 0 == pBrep )
    return CRhinoCommand::failure;

  bool bExplode = false;

  ON_Brep* p3dBrep = 0;
  int i, type = -1;
  if(1 == pBrep->m_F.Count() )
  {
    p3dBrep = pBrep->DuplicateFace( 0, false );
    type = 0;
  }
  else
  {
    p3dBrep = static_cast<ON_Brep*>( pBrep->Duplicate() );
    type = 1;
  }

  if( 0 == p3dBrep )
    return CRhinoCommand::failure;

  p3dBrep->Compact();
  for( i = 0; i < p3dBrep->m_F.Count(); i++ )
    p3dBrep->RebuildEdges( p3dBrep->m_F[i], 0.00001, true, true );
  p3dBrep->ShrinkSurfaces();

  ReverseVReversedSurfaces( p3dBrep );

  CRhinoUnroll Unroller( p3dBrep, context.m_doc.AbsoluteTolerance(), 0.1 );
  int irc = Unroller.PrepareFaces();
  if( 0 == irc )
  {
    bool ok = Unroller.FlattenFaces();
    if( ok )
    {
      int flat_face_count = Unroller.CreateFlatBreps( bExplode, 2.0 );
      if( flat_face_count )
      {
        ON_SimpleArray<ON_Brep*> flat_breps;
        ON_ClassArray< ON_SimpleArray<ON_Curve*> > flat_curves;
        ON_ClassArray< ON_SimpleArray<ON_3dPoint> > flat_points;
        ON_ClassArray< ON_SimpleArray<ON_TextDot*> > flat_dots;
        Unroller.CollectResults( flat_breps, flat_curves, flat_points, flat_dots );

        if( !bExplode && flat_breps.Count() > 1 )
        {
          ON_Brep* pJoinedBrep = ON_Brep::New();
          if( pJoinedBrep )
          {
            for( i = 0; i < flat_breps.Count(); i++ )
            {
              if( flat_breps[i] != 0 )
                pJoinedBrep->Append( *flat_breps[i] );
            }
            int joins = RhinoJoinBrepNakedEdges( *pJoinedBrep );
            flat_breps.Empty();
            flat_breps.Append( pJoinedBrep );
          }
        }

        CRhinoObjectAttributes att = pObject->Attributes();
        att.m_uuid = ON_nil_uuid;
        att.RemoveFromAllGroups();

        for( i = 0; i < flat_breps.Count(); i++ )
        {
          CRhinoBrepObject* flat_obj = new CRhinoBrepObject( att );
          flat_obj->SetBrep( flat_breps[i] );
          if( !context.m_doc.AddObject(flat_obj) )
            delete flat_obj; // Don't leak...
        }
      }
    }

    delete p3dBrep; // Don't leak...
  }

  context.m_doc.Redraw();

  return CRhinoCommand::success;
}
CRhinoCommand::result CCommandSampleRemovePoints::RunCommand( const CRhinoCommandContext& context )
{
    CRhinoGetObject go;
    go.SetCommandPrompt( L"Select point cloud" );
    go.SetGeometryFilter( CRhinoGetObject::pointset_object );
    go.EnableSubObjectSelect( false );
    go.GetObjects( 1, 1 );
    if( go.CommandResult() != CRhinoCommand::success )
        return go.CommandResult();

    const CRhinoObjRef& obj_ref = go.Object(0);
    const CRhinoPointCloudObject* obj = CRhinoPointCloudObject::Cast( obj_ref.Object() );
    if( 0 == obj )
        return CRhinoCommand::failure;

    const ON_PointCloud& cloud = obj->PointCloud();

    obj->Select( false );
    context.m_doc.Redraw();

    CRhGetRegionPoints gp;
    gp.SetCommandPrompt( L"Click and drag, or repeatedly click to lasso point cloud points. Press Enter when done" );
    gp.AcceptNothing();
    gp.SetGetPointCursor( RhinoApp().m_default_cursor );
    gp.GetPoints();
    if( gp.Result() == CRhinoGet::point )
        return CRhinoCommand::cancel;

    ON_SimpleArray<int> indices;
    const int index_count = RhRegionSelectPointCloudPoints( gp.View(), cloud, gp.m_points, indices );
    if( 0 == index_count )
        return CRhinoCommand::nothing;

    indices.QuickSort( &ON_CompareIncreasing<int> );

    const CRhinoObjectAttributes& atts = obj->Attributes();
    bool bColors = cloud.HasPointColors();
    bool bNormals = cloud.HasPointNormals();

    ON_PointCloud new_cloud;
    new_cloud.m_P.SetCapacity( index_count );
    new_cloud.m_P.SetCount( index_count );
    if( bColors )
    {
        new_cloud.m_C.SetCapacity( index_count );
        new_cloud.m_C.SetCount( index_count );
    }
    if( bNormals )
    {
        new_cloud.m_N.SetCapacity( index_count );
        new_cloud.m_N.SetCount( index_count );
    }

    ON_PointCloud dup_cloud( cloud );
    dup_cloud.DestroyHiddenPointArray();

    const int cloud_count = dup_cloud.PointCount();
    int last_point_index = indices[indices.Count() - 1];
    for( int i = cloud_count - 1; i >= 0; i-- )
    {
        if( i == last_point_index )
        {
            int last_array_index = indices.Count() - 1;

            new_cloud.m_P[last_array_index] = dup_cloud.m_P[i];
            if( bColors )
                new_cloud.m_C[last_array_index] = dup_cloud.m_C[i];
            if( bNormals )
                new_cloud.m_N[last_array_index] = dup_cloud.m_N[i];

            dup_cloud.m_P.Remove( i );
            if( bColors )
                dup_cloud.m_C.Remove( i );
            if( bNormals )
                dup_cloud.m_N.Remove( i );

            indices.Remove( last_array_index );

            if( 0 == indices.Count() )
                break;

            last_point_index = indices[indices.Count() - 1];
        }
    }

    CRhinoPointCloudObject* new_cloud_obj = new CRhinoPointCloudObject( atts );
    new_cloud_obj->SetPointCloud( new_cloud );
    new_cloud.Destroy();
    if( context.m_doc.AddObject(new_cloud_obj) )
    {
        new_cloud_obj->Select();
    }
    else
    {
        delete new_cloud_obj;
        return CRhinoCommand::failure;
    }

    dup_cloud.m_P.Shrink();
    if( bColors )
        dup_cloud.m_C.Shrink();
    if( bNormals )
        dup_cloud.m_N.Shrink();

    CRhinoPointCloudObject* dup_cloud_obj = new CRhinoPointCloudObject( atts );
    dup_cloud_obj->SetPointCloud( dup_cloud );
    if( !context.m_doc.ReplaceObject(obj_ref, dup_cloud_obj) )
        delete dup_cloud_obj;

    context.m_doc.Redraw();

    return CRhinoCommand::success;
}