枫叶棋语 发表于 2024-11-9 17:28:04

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]
查看完整版本: ObjectArx 实现类似C# 的DrawJig,支持多实体拖动