Overview
The CRhinoViewport
class has two member functions, GetModelXform()
and SetModelXform()
, that either retrieve or modify the model transformation matrix that is applied to objects before they are drawn. The model transformation matrix is intended to be used for dynamic drawing of objects. Note, the default model transformation matrix is the identity.
Some of the Rhino command that use this technique to dynamically draw transforming objects include the Move, Copy, Scale, and Rotate commands. These commands derive new CRhinoGetPoint
classes and override the virtual DynamicDraw()
member function to draw objects dynamically as the mouse moves during a point picking operation.
Sample
The following is an sample CRhinoGetPoint
-derived class that demonstrates how to dynamically draw transforming objects during a point picking operation. In this sample, the transformation is a simple translation, like used in the Move command.
First, the class declaration…
////////////////////////////////////////////////////////////////////
// CRhinoGetTranslationPoint declaration
class CRhinoGetTranslationPoint : public CRhinoGetPoint
{
public:
CRhinoGetTranslationPoint();
~CRhinoGetTranslationPoint() {}
// CRhinoGetPoint overrides
void SetBasePoint( ON_3dPoint base_point, BOOL bShowDistanceInStatusBar = false );
void OnMouseMove( CRhinoViewport& vp, UINT flags, const ON_3dPoint& pt, const CPoint* p );
void DynamicDraw( HDC hdc, CRhinoViewport& vp, const ON_3dPoint& pt );
// Additional helpers
void AddObject( const CRhinoObject* object );
void CalculateTranslation( const ON_3dPoint& pt, ON_Xform& xform );
private:
ON_3dPoint m_start_point; // starting point of translation
ON_Xform m_xform; // transformation matrix
ON_SimpleArray<const CRhinoObject*> m_objects; //objects to transform
};
////////////////////////////////////////////////////////////////////
// CRhinoGetTranslationPoint definition
CRhinoGetTranslationPoint::CRhinoGetTranslationPoint()
{
m_xform.Identity();
}
void CRhinoGetTranslationPoint::AddObject( const CRhinoObject* object )
{
m_objects.Append( object );
}
void CRhinoGetTranslationPoint::SetBasePoint(
ON_3dPoint base_point,
BOOL bShowDistanceInStatusBar
)
{
m_start_point = base_point;
CRhinoGetPoint::SetBasePoint( base_point, bShowDistanceInStatusBar );
}
void CRhinoGetTranslationPoint::CalculateTranslation(
const ON_3dPoint& pt,
ON_Xform& xform
)
{
ON_3dVector v = pt - m_start_point;
if( v.IsTiny() )
xform.Identity();
else
xform.Translation( v );
}
void CRhinoGetTranslationPoint::OnMouseMove(
CRhinoViewport& vp,
UINT flags,
const ON_3dPoint& pt,
const CPoint* p
)
{
// Everytime the mouse moves, calculate the translation
CalculateTranslation( pt, m_xform );
CRhinoGetPoint::OnMouseMove( vp, flags, pt, p );
}
void CRhinoGetTranslationPoint::DynamicDraw(
HDC hdc,
CRhinoViewport& vp,
const ON_3dPoint& pt
)
{
// Time to draw our objects dynamically
int i, count = m_objects.Count();
if( m_xform.IsIdentity() == false && count > 0 )
{
ON_Color saved_color = vp.DrawColor();
ON_Xform saved_model_xform;
// Save the current model transformation, we will
// need to restore it later
vp.GetModelXform( saved_model_xform );
// Set the model transformation to ours
vp.SetModelXform( m_xform );
// Draw all of the objects in our array
for( i = 0; i < m_objects.Count(); i++ )
{
const CRhinoObject* object = m_objects[i];
if( object == 0 )
continue;
vp.SetDrawColor( object->ObjectDrawColor(TRUE) );
object->Draw( vp );
if( vp.InterruptDrawing() )
break;
}
// Reset modified viewport members
vp.SetModelXform( saved_model_xform );
vp.SetDrawColor( saved_color );
}
// Let the base class do its drawing too
CRhinoGetPoint::DynamicDraw( hdc, vp, pt );
}