以下示例演示如何创建自定义对象捕捉模式: #include "rxobject.h"
#include "ads.h"
#include "adslib.h"
#include "dbmain.h"
#include "dbents.h"
#include "dbosnap.h"
#include "acedinpt.h"
// Socket Osnap mode protocol extension class.
//
class AcmeSocketInfo : public AcDbCustomOsnapInfo {
public:
ACRX_DECLARE_MEMBERS(AcmeSocketInfo);
virtual Acad::ErrorStatus
getOsnapInfo(
AcDbEntity* pickedObject,
int gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcArray<AcGePoint3d>& snapPoints,
AcArray<int>& geomIdsForPts,
AcArray<AcGeCurve3d>& snapCurves,
AcArray<int>& geomIdsForLines)
};
// This class is registered with AcRx, to be used by the host
// application to look up entity class-specific implementations.
//
ACRX_NO_CONS_DEFINE_MEMBERS(AcmeSocketInfo,AcDbCustomOsnapInfo);
Acad::ErrorStatus
AcmeSocketInfo::getOsnapInfo(
AcDbEntity*,
int,
const AcGePoint3d&,
const AcGePoint3d&,
const AcGePoint3d&,
AcArray<AcGePoint3d>& snapPoints,
AcArray<int>& geomIdsForPts,
AcArray<AcGeCurve3d>& snapCurves,
AcArray<int>& geomIdsForLines)
{
// Associate with AcDbEntity to define default behavior.
//
snapPoints.setLogicalLength(0);
geomIdsForPts.setLogicalLength(0);
snapLiness.setLogicalLength(0);
geomIdsForLines.setLogicalLength(0);
}
// Socket Osnap mode protocol extension object for AcDbLine.
//
class AcmeSocketForLine : public AcmeSocketInfo {
public:
virtual Acad::ErrorStatus
getOsnapInfo(
AcDbEntity* pickedObject,
int gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcArray<AcGePoint3d>& snapPoints,
AcArray<int>& geomIdsForPts,
AcArray<AcGeCurve3d>& snapCurves,
AcArray<int>& geomIdsForLines)
};
Acad::ErrorStatus
AcmeSocketForLine::getOsnapInfo(
AcDbEntity* pickedObject,
int,
const AcGePoint3d& pickPoint,
const AcGePoint3d&,
const AcGeMatrix3d& viewXform,
AcArray<AcGePoint3d>& snapPoints,
AcArray<int>& geomIdsForPts,
AcArray<AcGeCurve3d>& snapCurves,
AcArray<int>& geomIdsForLines)
{
// Protocol extension ensures that the following assertion
// is always true, but check in non-production versions
// just to be safe.
//
ASSERT(pickedObject->isKindOf(AcDbLine::desc()));
// In production, a hard cast is fastest.
AcDbLine* lineEnt = (AcDbLine*)pickedObject;
// Do computation using AcDbLine protocol, pickPoint, and
// viewXform. For example, if you want to find the closest
// socket to the pick point and return just that, set
// snapPoints and geomIdsForPts accordingly.
// But this isn't an AutoSnap mode...
//
snapLiness.setLogicalLength(0);
geomIdsForLines.setLogicalLength(0);
}
// Actual protocol extension objects
//
static AcmeSocketInfo* pDefaultSocketInfo = NULL;
static AcmeSocketForLine* pSocketForLine = NULL;
// "SOCket" Osnap mode glyph object
//
class AcmeSocketGlyph : public AcGiGlyph
{
public:
virtual Acad::ErrorStatus
setLocation(const AcGePoint3d& dcsPoint);
virtual void
viewportDraw(AcGiViewportDraw* vportDrawContext);
private:
AcGePoint3d mCurDcsLoc;
};
Acad::ErrorStatus
AcmeSocketGlyph::setLocation(const AcGePoint3d& dcsPoint)
{
mCurDCSLoc = dcsPoint;
}
// These variables are extremely transient, and are
// made static to save constructor/destructor cost.
static AcGePoint2d& sPixelArea;
AcArray<AcGePoint3d> sSegmentPoints[2];
void
AcmeSocketGlyph::viewportDraw(AcGiViewportDraw* vportDrawContext)
{
// Taking mCurDCSLoc, the pixel size, and the AutoSnap
// marker size into account, plus anything else, such as socket
// orientation, draw the glyph.
// If this ASSERT fails, then the pixel size is really position-
// dependent.
//
ASSERT(!vportDrawContext->viewport()->isPerspective());
vportDrawContext->viewport()->
getNumPixelsInUnitSquare(
AcGePoint3d::kOrigin, pixelArea);
double halfGlyphSizeInDCS =
acdbCustomOsnapManager->osnapGlyphSize() * pixelArea.x / 2.0;
// Draw an asterisk with 4 segments.
//
sSegmentPoints[0].set(
mCurDCSLoc.x-halfGlyphSizeInDCS,
mCurDCSLoc.y-halfGlyphSizeInDCS, 0.0);
sSegmentPoints[1].set(
mCurDCSLoc.x+halfGlyphSizeInDCS,
mCurDCSLoc.y+halfGlyphSizeInDCS, 0.0);
vportDrawContext->geometry().polylineDc(
2, &(sSegmentPoints[0]));
sSegmentPoints[0].set(
mCurDCSLoc.x-halfGlyphSizeInDCS,
mCurDCSLoc.y+halfGlyphSizeInDCS, 0.0);
sSegmentPoints[1].set(
mCurDCSLoc.x+halfGlyphSizeInDCS,
mCurDCSLoc.y-halfGlyphSizeInDCS, 0.0);
vportDrawContext->geometry().polylineDc(
2, &(sSegmentPoints[0]));
sSegmentPoints[0].set(
mCurDCSLoc.x-halfGlyphSizeInDCS,
mCurDCSLoc.y, 0.0);
sSegmentPoints[1].set(
mCurDCSLoc.x+halfGlyphSizeInDCS,
mCurDCSLoc.y, 0.0);
vportDrawContext->geometry().polylineDc(
2, &(sSegmentPoints[0]));
sSegmentPoints[0].set(
mCurDCSLoc.x,
mCurDCSLoc.y-halfGlyphSizeInDCS, 0.0);
sSegmentPoints[1].set(
mCurDCSLoc.x,
mCurDCSLoc.y+halfGlyphSizeInDCS, 0.0);
vportDrawContext->geometry().polylineDc(
2, &(sSegmentPoints[0]));
};
AcmeSocketGlyph* pSocketGlyph = NULL;
// Master object for the socket custom Osnap mode.
//
class AcmeSocketMode : public AcDbCustomOsnapMode {
public:
virtual const char*
localModeString() const {return "SOCket"};
virtual const char*
globalModeString() const {return "SOCket"};
virtual const AcRxClass*
entityOsnapClass() const {return AcmeSocketInfo::desc());
virtual AcGiGlyph*
glyph() const {return pSocketGlyph;);
virtual const char*
tooltipString() const {return "Socket to Me?" };
};
static AcmeSocketMode* pSocketMode = NULL;
/* ================ ObjectARX application interface ============ */
extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void*) {
switch(msg) {
case AcRx::kInitAppMsg:
// Register the class.
//
AcmeSocketInfo::rxInit();
acrxBuildClassHierarchy();
pDefaultSocketInfo = new AcmeSocketInfo;
AcDbEntity::desc()->addX(AcmeSocketInfo::desc(),
pDefaultSocketInfo);
pSocketForLine = new AcmeSocketForLine;
AcDbLine::desc()->addX(AcmeSocketInfo::desc(),
pSocketForLine);
};
// Create the glyph object to be returned by the socket
// mode object.
//
pSocketGlyph = new AcmeSocketGlyph;
// Create and register the custom Osnap Mode
pSocketMode = new AcmeSocketMode;
acdbCustomOsnapManager->addCustomOsnapMode(pSocketMode);
// The socket Osnap mode is now plugged in and ready to
// use.
//
break;
case AcRx::kUnloadAppMsg:
// Clean up.
acdbCustomOsnapManager->removeCustomOsnapMode(pSocketMode);
delete pSocketMode;
// Unregister, then delete the protocol extension object.
//
AcDbEntity::desc()->delX(AcmeSocketInfo::desc());
delete pDefaultSocketInfo;
AcDbLine::desc()->delX(AcmeSocketInfo::desc());
delete pSocketForLine;
// Remove the protocol extension class definition.
//
acrxClassDictionary->remove("AcmeSocketInfo");
break;
default:
// Between the initialization and termination of the
// application, all registered objects will be directly
// invoked as needed. No commands or AutoLISP
// expressions are necessary.
//
break;
}
return AcRx::kRetOK;
}
|
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-10-29 17:08
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.