By Balaji Ramamoorthy
Here are few ways to lock entities in drawing, so that the user can't move or do any kind of operations to them. It allows some objects to be locked and some not, in same drawing.
The best way to do this is to use overrule. The "AcDbTransformOverrule" can be used to prevent any transformation (Move, Rotate, Scale etc) from affecting the entity. The "AcDbGripOverrule" can be used to remove the default grips that appear on the entity. This will prevent the entity from being grip edited. Here is a sample code snippet to prevent circles in the drawing from getting transformed :
Step 1: Implement a Transform overrule
#include "dbentityoverrule.h"
class CTransformOverrule: public AcDbTransformOverrule
{
public:
static CTransformOverrule* _pTheOverrule;
ACRX_DECLARE_MEMBERS(CTransformOverrule);
bool isApplicable(const AcRxObject* pOverruledSubject) const
{
return true;
}
Acad::ErrorStatus transformBy(
AcDbEntity* pSubject,
const AcGeMatrix3d& xform
)
{
if(pSubject->isA() != AcDbCircle::desc())
return Acad::eOk;
AcDbCircle* pCircle = AcDbCircle::cast(pSubject);
if(pCircle != NULL)
return Acad::eNotApplicable;
return AcDbTransformOverrule::transformBy(pSubject, xform);
}
// Take care about calling "CTransformOverrule::rxInit();"
// in "On_kInitAppMsg" of the arx that uses this overrule.
static void CTransformOverrule::AddOverrule()
{
if(_pTheOverrule != NULL)
return;
_pTheOverrule = new CTransformOverrule();
AcRxOverrule::addOverrule(
AcDbCircle::desc(),
_pTheOverrule,
true
);
CTransformOverrule::setIsOverruling(true);
}
static void CTransformOverrule::RemoveOverrule()
{
if(_pTheOverrule == NULL)
return;
CTransformOverrule::setIsOverruling(false);
AcRxOverrule::removeOverrule(
AcDbCircle::desc(),
_pTheOverrule
);
delete _pTheOverrule;
_pTheOverrule = NULL;
}
};
CTransformOverrule* CTransformOverrule::_pTheOverrule = NULL;
ACRX_NO_CONS_DEFINE_MEMBERS(CTransformOverrule, AcDbTransformOverrule);
Step 2 : Implement a Grip overrule
class CGripOverrule: public AcDbGripOverrule
{
public:
static CGripOverrule* _pTheOverrule;
ACRX_DECLARE_MEMBERS(CGripOverrule);
bool isApplicable(const AcRxObject* pOverruledSubject) const
{
return true;
}
//Add the overrule.
//Take care about calling "CGripOverrule::rxInit();"
// in "On_kInitAppMsg" of the arx that uses this overrule.
static void CGripOverrule::AddOverrule()
{
if(_pTheOverrule != NULL)
return;
_pTheOverrule = new CGripOverrule();
AcRxOverrule::addOverrule(AcDbCircle::desc(), _pTheOverrule, true);
CViewportDrawOverrule::setIsOverruling(true);
}
static void CGripOverrule::RemoveOverrule()
{
if(_pTheOverrule == NULL)
return;
CGripOverrule::setIsOverruling(false);
AcRxOverrule::removeOverrule(AcDbCircle::desc(), _pTheOverrule);
delete _pTheOverrule;
_pTheOverrule = NULL;
}
Acad::ErrorStatus CGripOverrule::getGripPoints(const AcDbEntity* pSubject,
AcGePoint3dArray& gripPoints,
AcDbIntArray & osnapModes,
AcDbIntArray & geomIds)
{
AcDbCircle* pCircle = AcDbCircle::cast(pSubject);
if(pCircle != NULL)
{// Remove the grip points, for a circle
gripPoints.removeAll();
return Acad::eNotApplicable;
}
return AcDbGripOverrule::getGripPoints(pSubject, gripPoints, osnapModes, geomIds);
}
Acad::ErrorStatus CGripOverrule::getGripPoints
(
const AcDbEntity* pSubject,
AcDbGripDataPtrArray& grips,
const double curViewUnitSize,
const int gripSize,
const AcGeVector3d& curViewDir,
const int bitflags
)
{
AcDbCircle* pCircle = AcDbCircle::cast(pSubject);
if(pCircle != NULL)
{// Remove the grip points, for a circle
grips.removeAll();
return Acad::eNotApplicable;
}
return AcDbGripOverrule::getGripPoints
(
pSubject,
grips,
curViewUnitSize,
gripSize,
curViewDir,
bitflags
);
}
};
CGripOverrule* CGripOverrule::_pTheOverrule = NULL;
ACRX_NO_CONS_DEFINE_MEMBERS(CGripOverrule, AcDbGripOverrule);
Step 3 : Ensure that our overrule classes are part of the class hierarchy.
virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt)
{
AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg (pkt) ;
CGripOverrule::rxInit();
CTransformOverrule::rxInit();
acrxBuildClassHierarchy();
return (retCode) ;
}
Step 4 : Add commands to enable / disable the overruling
// Command to enable overruling
static void asdkOverrule_Start(void)
{
CTransformOverrule::AddOverrule();
CGripOverrule::AddOverrule();
}
// Command to disable overruling
static void asdkOverrule_Stop(void)
{
CTransformOverrule::RemoveOverrule();
CGripOverrule::RemoveOverrule();
}
Recent Comments