ObjectArx 实现类似C# 的DrawJig,支持多实体拖动
首先实现接口,因为AcEdJig 仅仅支持单实体进行更新显示,如果用多实体那么就需要一个AcDbEntity 去包装,本次我们换个方式,直接在类中加入AcDbEntity接口,实现subWorldDraw显示多个图元class DrawJig : public AcDbEntity, public AcEdJig {
public:
virtual DragStatus sampler() = 0;
virtual boolupdate() = 0;
virtual bool subWorldDraw(AcGiWorldDraw* mode) = 0;
protected:
AcDbEntity* entity() const final
{
return (AcDbEntity*)this;
}
};下面用一个简单的例子继承测试下
class TestDrrawJig :public DrawJig {
public:
TestDrrawJig() {}
bool startDrag(AcGePoint3d ptCenter);
DragStatus sampler() override;
bool update() override;
bool subWorldDraw(AcGiWorldDraw* mode)override;
AcGePoint2d Point3dTo2d(AcGePoint3d pnt);
AcDbVoidPtrArray CreateEntitys();
AcArray<AcDbEntity*> GetEntities();
private:
AcGePoint3d m_centerPnt;
AcGePoint3d m_curPnt;
AcDbVoidPtrArray m_aryPtr;
};
inline AcEdJig::DragStatus TestDrrawJig::sampler()
{
setUserInputControls((UserInputControls)(AcEdJig::kAccept3dCoordinates
| AcEdJig::kNoNegativeResponseAccepted
| AcEdJig::kNullResponseAccepted));
AcGePoint3d pointTemp;
DragStatus stat = acquirePoint(m_curPnt);
if (pointTemp != m_curPnt)
{
pointTemp = m_curPnt;
}
else if (stat == AcEdJig::kNormal)
{
return AcEdJig::kNoChange;
}
return stat;
}
inline bool TestDrrawJig::update()
{
for (int i = 0; i < m_aryPtr.length(); i++)
{
AcDbEntity* pEnt = (AcDbEntity*)m_aryPtr.at(i);
delete pEnt;
pEnt = NULL;
}
//创建新实体
m_aryPtr = CreateEntitys();
return Adesk::kTrue;
}
inline bool TestDrrawJig::subWorldDraw(AcGiWorldDraw* mode)
{
for (int i = 0; i < m_aryPtr.length(); i++)
{
AcDbEntity* pEnt = (AcDbEntity*)m_aryPtr;
mode->geometry().draw(pEnt);
}
return Adesk::kTrue;
}
inline AcGePoint2d TestDrrawJig::Point3dTo2d(AcGePoint3d pnt)
{
return AcGePoint2d(pnt.x, pnt.y);
}
inline AcDbVoidPtrArray TestDrrawJig::CreateEntitys()
{
AcDbVoidPtrArray aryEnts;
//创建实体
double dist = Point3dTo2d(m_curPnt).distanceTo(Point3dTo2d(m_centerPnt));
AcGeVector2d vec = Point3dTo2d(m_curPnt) - Point3dTo2d(m_centerPnt);
AcGePoint2d pt1, pt2, pt3, pt4;
pt1 = Point3dTo2d(m_curPnt);
pt3 = pt1 - 2 * vec;
vec.rotateBy(PI * 0.5);
pt2 = Point3dTo2d(m_centerPnt) + vec;
pt4 = pt2 - 2 * vec;
AcDbPolyline* poly = new AcDbPolyline;
poly->addVertexAt(0, pt1);
poly->addVertexAt(1, pt2);
poly->addVertexAt(2, pt3);
poly->addVertexAt(3, pt4);
poly->setClosed(Adesk::kTrue);
poly->setColorIndex(1);
aryEnts.append(static_cast<void*>(poly));
AcDbCircle* circle = new AcDbCircle(m_centerPnt, AcGeVector3d::kZAxis, pt1.distanceTo(pt2) * 0.5);
circle->setColorIndex(3);
aryEnts.append(static_cast<void*>(circle));
return aryEnts;
}
inline AcArray<AcDbEntity*> TestDrrawJig::GetEntities()
{
AcArray <AcDbEntity*> ents;
for (int i = 0; i < m_aryPtr.length(); i++) {
ents.append((AcDbEntity*)(m_aryPtr));
}
return ents;
}
inline bool TestDrrawJig::startDrag(AcGePoint3d ptCenter)
{
m_centerPnt = ptCenter;
m_curPnt = ptCenter;
AcString prompt = _T("\n指定角点");
setDispPrompt(prompt);
AcEdJig::DragStatus stat = drag();
if (stat == AcEdJig::kNormal)
{
return true;
}
else
{
return false;
}
}void tsJig()
{
DbTrans tr;
auto btr = tr.CurrentSpace();
auto res = MapleGetPoint();
if (!res.Ok) return;
TestDrrawJig jig;
if (jig.startDrag(res.Value)) {
auto ents = jig.GetEntities();
tr.AddEntities(btr, ents);
}
}这样就可以使用多实体Jig了,与C#的DrawJig 差不多
页:
[1]