Moving Curve and Surface Grips
C++
Summary: Demonstrates how to move curve and surface object grips.
Question
How to move the control points of a curve or surface object using the Rhino SDK?
Answer
The curve and surface grips you see on the screen, after running Rhino's PointsOn command, are represented by CRhinoGripObject-derived objects. To move a grip object, you have to do a few things:
- Get a CRhinoGripObject. You can use a CRhinoGetObject object to do this.
- Call CRhinoGripObject::MoveGrip to transform the grip's location.
- Call CRhinoGripObject::Owner to get the grips owning CRhinoObject object.
- Call CRhinoObject::NewObject to create a new CRhinoObject object based on the new grip location.
- Call CRhinoDoc::ReplaceObject to replace the original owning object with the new one.
The following sample code demonstrates this. Note, this sample uses a CRhinoXformObjectList object to make maintain the list of grips and grip owners easier.
C++
CRhinoCommand::result CCommandMoveGrips::RunCommand( const CRhinoCommandContext& context ) { CRhinoGetObject go; go.SetCommandPrompt( L"Select grips to move" ); go.SetGeometryFilter( CRhinoGetObject::grip_object ); go.GetObjects( 1, 0 ); if( go.CommandResult() != success ) return go.CommandResult(); CRhinoXformObjectList xform_list; if( xform_list.AddObjects(go, true) < 1 ) return failure; CRhinoGetPoint gp; gp.SetCommandPrompt( L"Point to move from" ); gp.GetPoint(); if( gp.CommandResult() != success ) return gp.CommandResult(); ON_3dPoint from = gp.Point(); gp.SetCommandPrompt( L"Point to move to" ); gp.SetBasePoint( from ); gp.DrawLineFromPoint( from, TRUE ); gp.GetPoint(); if( gp.CommandResult() != success ) return gp.CommandResult(); ON_3dPoint to = gp.Point(); ON_Xform xform; xform.Translation( to - from ); if( xform.IsValid() ) { // Transform the grip objects int i; for( i = 0; i < xform_list.m_grips.Count(); i++ ) xform_list.m_grips[i]->MoveGrip( xform ); // Replace the old owner with a new one for( i = 0; i < xform_list.m_grip_owners.Count(); i++ ) { CRhinoObject* old_object = xform_list.m_grip_owners[i]; if( old_object ) { CRhinoObject* new_object = old_object->m_grips->NewObject(); if( new_object ) context.m_doc.ReplaceObject( CRhinoObjRef(old_object), new_object, true ); } } context.m_doc.Redraw(); } return success; }
VB.NET
Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result Dim go As New MRhinoGetObject go.SetCommandPrompt("Select grips to move") go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.grip_object) go.GetObjects(1, 0) If (go.CommandResult() <> IRhinoCommand.result.success) Then Return go.CommandResult() End If Dim list As New MRhinoXformObjectList If (list.AddObjects(go, True) < 1) Then Return IRhinoCommand.result.failure End If Dim gp As New MRhinoGetPoint gp.SetCommandPrompt("Point to move from") gp.GetPoint() If (gp.CommandResult() <> IRhinoCommand.result.success) Then Return gp.CommandResult() End If Dim pt_start As On3dPoint = gp.Point() gp.SetCommandPrompt("Point to move to") gp.SetBasePoint(pt_start) gp.DrawLineFromPoint(pt_start, True) gp.GetPoint() If (gp.CommandResult() <> IRhinoCommand.result.success) Then Return gp.CommandResult() End If Dim pt_end As On3dPoint = gp.Point() Dim xform As New OnXform xform.Translation(pt_end - pt_start) If xform.IsValid() Then Dim i As Integer = 0 For i = 0 To list.m_grips.Length - 1 list.m_grips(i).MoveGrip(xform) Next For i = 0 To list.m_grip_owners.Length - 1 Dim old_object As MRhinoObject = list.m_grip_owners(i) Dim new_Object As MRhinoObject = old_object.m_grips.NewObject() If (new_Object IsNot Nothing) Then context.m_doc.ReplaceObject(New MRhinoObjRef(old_object), new_Object, True) End If Next context.m_doc.Redraw() End If Return IRhinoCommand.result.success End Function