• [转]使用 AcDbMultiModesGripPE 夹点上下文菜单


    篇一:使用 AcDbMultiModesGripPE 夹点上下文菜单

    作者 Balaji Ramamoorthy

    原链接 http://adndevblog.typepad.com/autocad/2013/12/grip-context-menu-using-acdbmultimodesgrippe.html

    这是一个使用 AcDbMultiModesGripPE 为自定义实体实现夹点上下文菜单的示例项目。它演示了使用多模式夹点来获取与自定义实体相关的输入。

    为了让它变得有趣,我创建了一个类似于树的自定义实体。它的夹点上下文菜单显示两种模式 - “春季”和“冬季”。创建树自定义实体后,当夹点变热时将出现上下文菜单。选择“春天”将确保树有叶子,选择“冬天”将使树脱落叶子。

    在这种情况下,模式与夹点编辑无关,并且由于我们不希望夹点在单击时开始拖动,因此将模式的动作类型设置为命令。选择模式后,AutoCAD 将调用该命令。在命令实现中,我们确保树根据选择的模式更新其显示。我希望在当前模式旁边有一个复选标记,但 API 目前没有办法做到这一点,我们的工程团队为它创建了一个愿望清单项目。

    这是相关代码,完整的示例项目可以从下面的链接下载:

    示例项目下载 multimodegrip_simplesample

    图片展示

    // Header
    // TreeMultiModesGripPE.h
     
    #pragma once
     
    #include "dbMultiModesGrip.h"
     
    class AdskTreeMultiModesGripPE : public AcDbMultiModesGripPE
    {
    private:
        static AcDbMultiModesGripPE::GripMode _currentGripMode;
        static AcDbObjectId _lastModifiedEntId;
     
    public:
        ACRX_DECLARE_MEMBERS(AdskTreeMultiModesGripPE);
     
        AdskTreeMultiModesGripPE();
        ~AdskTreeMultiModesGripPE();
        static AcDbObjectId getLastModifiedEntId();
     
        virtual bool getGripModes(AcDbEntity* pThis, 
                                  AcDbGripData* pGripData, 
                                  AcArray<GripMode>& modes, 
                                  unsigned int& curMode) const;
     
        virtual unsigned int mode(AcDbEntity* pThis, 
                                  AcDbGripData* pGripData) const;
     
        virtual AcDbMultiModesGripPE::GripMode modeEx(
                    AcDbEntity* pThis, 
                    AcDbGripData* pGripData) const;
     
        virtual bool setMode(
                    AcDbEntity* pThis, 
                    AcDbGripData* pGripData, 
                    unsigned int newMode);
     
        virtual AcDbMultiModesGripPE::GripType gripType(
                AcDbEntity* pThis, AcDbGripData* pGripData) const;
     
        virtual void reset(AcDbEntity* pThis);
    };
     
     
    // Implementation
    // TreeMultiModesGripPE.cpp
     
    #include "StdAfx.h"
    #include "dbMultiModesGrip.h"
    #include "TreeMultiModesGripPE.h"
    #include "AdskTree.h"
     
    ACRX_CONS_DEFINE_MEMBERS(AdskTreeMultiModesGripPE, 
                             AcDbMultiModesGripPE, 1);
     
    AcDbMultiModesGripPE::GripMode 
                        AdskTreeMultiModesGripPE::_currentGripMode;
     
    AcDbObjectId AdskTreeMultiModesGripPE::_lastModifiedEntId 
                                            = AcDbObjectId::kNull;
     
    AdskTreeMultiModesGripPE::AdskTreeMultiModesGripPE()
    {
        // Default grip mode
        _currentGripMode.Mode = 0;
        _currentGripMode.DisplayString = AcString("Spring");
    }
     
    AdskTreeMultiModesGripPE::~AdskTreeMultiModesGripPE()
    {
    }
     
    // Returns the possible grip modes
    bool AdskTreeMultiModesGripPE::getGripModes(
                                    AcDbEntity* pThis, 
                                    AcDbGripData* pGripData, 
                                    AcArray<GripMode>& modes, 
                                    unsigned int& curMode) const 
    {
        GripMode gripMode1;
        gripMode1.Mode = 0;
        gripMode1.DisplayString = AcString("Spring");
        gripMode1.ActionType = GripActionType::kCommand;
        gripMode1.CommandString = AcString("ModeSwitchCmd ");
     
        modes.append(gripMode1);
     
        GripMode gripMode2;
        gripMode2.Mode = 1;
        gripMode2.DisplayString = AcString("Winter");
        gripMode2.ActionType = GripActionType::kCommand;
        gripMode2.CommandString = AcString("ModeSwitchCmd ");
     
        modes.append(gripMode2);
     
        curMode = 0;
     
        return true;
    }
     
    // Gets the current mode identifier.
    unsigned int AdskTreeMultiModesGripPE::mode(
                                    AcDbEntity* pThis, 
                                    AcDbGripData* pGripData) const
    {
        return _currentGripMode.Mode; 
    }
     
    // Return the current mode.
    AcDbMultiModesGripPE::GripMode 
        AdskTreeMultiModesGripPE::modeEx(
                AcDbEntity* pThis, AcDbGripData* pGripData) const 
    {
        return _currentGripMode;
    }
     
    // Sets the current mode.
    bool AdskTreeMultiModesGripPE::setMode(
                AcDbEntity* pThis, 
                AcDbGripData* pGripData, 
                unsigned int newMode)
    {
        _currentGripMode.Mode = newMode;
     
        AcDbObjectId entId = pThis->id();
        AdskTree *pTree = AdskTree::cast(pThis);
     
        switch(newMode)
        {
            case 0:
                acutPrintf(ACRX_T("\nSpring season, growing leaves !"));
     
                _currentGripMode.DisplayString = AcString("Spring"); 
                pTree->setSeason(AcString("Spring"));
                // For graphics update
                _lastModifiedEntId = pTree->id();
     
                break;
     
            case 1:
                acutPrintf(ACRX_T("\nWinter season, shedding leaves !"));
     
                _currentGripMode.DisplayString = AcString("Winter");
                pTree->setSeason(AcString("Winter"));
                // For graphics update
                _lastModifiedEntId = pTree->id();
     
                break;
        }
        return true;
    }
     
    // Gets the grip type of a given grip.
    AcDbMultiModesGripPE::GripType 
    AdskTreeMultiModesGripPE::gripType(
                AcDbEntity* pThis, AcDbGripData* pGripData) const 
    {
        return AcDbMultiModesGripPE::GripType::kPrimary;  
    }
     
    // To retrieve the objectId of the tree entity 
    // for graphics update
    AcDbObjectId AdskTreeMultiModesGripPE::getLastModifiedEntId()
    {
        return _lastModifiedEntId;
    }
     
    // resets current mode to default 
    void AdskTreeMultiModesGripPE::reset(AcDbEntity* pThis)
    {
        _currentGripMode.Mode = 0;
        _currentGripMode.DisplayString = AcString("Spring");
    }
     
     
     
    // Header for custom entity
    // AsdkTree.h
     
    #pragma once
     
    #ifdef MULTIMODEGRIPSIMPLESAMPLE_MODULE
    #define DLLIMPEXP __declspec(dllexport)
    #else
    #define DLLIMPEXP
    #endif
     
    //-----------------------------------------------------------------------------
    #include "dbmain.h"
     
    //-----------------------------------------------------------------------------
    class DLLIMPEXP AdskTree : public AcDbEntity 
    {
     
    public:
        ACRX_DECLARE_MEMBERS(AdskTree) ;
     
    protected:
        static Adesk::UInt32 kCurrentVersionNumber ;
     
    private:
        AcGePoint3d _basePoint;
        AcString _season;
     
        void BuildSubTree(
            AcGeLineSeg3d *pMainBranch, 
            int level, 
            AcGiWorldDraw *mode, 
            Adesk::Boolean flower = Adesk::kFalse);
     
    public:
        AdskTree () ;
        virtual ~AdskTree () ;
     
        // Sets the season status
        void setSeason(AcString season);
     
        // Sets the insertion point
        void setBasePoint(AcGePoint3d basePoint);
     
        //----- AcDbObject protocols
        //- Dwg Filing protocol
        virtual Acad::ErrorStatus 
                        dwgOutFields (AcDbDwgFiler *pFiler) const ;
        virtual Acad::ErrorStatus 
                            dwgInFields (AcDbDwgFiler *pFiler) ;
     
        //----- AcDbEntity protocols
        //- Graphics protocol
    protected:
        virtual Adesk::Boolean subWorldDraw (AcGiWorldDraw *mode) ;
        virtual Acad::ErrorStatus 
                        subTransformBy(const AcGeMatrix3d& xform);
     
        //- Grip points protocol
        virtual Acad::ErrorStatus subGetGripPoints (
                                    AcDbGripDataPtrArray &grips, 
                                    const double curViewUnitSize, 
                                    const int gripSize, 
                                    const AcGeVector3d &curViewDir, 
                                    const int bitflags) const ;
     
        virtual Acad::ErrorStatus subMoveGripPointsAt (
            const AcDbVoidPtrArray &gripAppData, 
            const AcGeVector3d &offset, const int bitflags) ;
    };
     
    #ifdef MULTIMODEGRIPSIMPLESAMPLE_MODULE
    ACDB_REGISTER_OBJECT_ENTRY_AUTO(AdskTree)
    #endif
     
     
    // Implementation of the custom entity
    // AdskTree.cpp 
     
    #include "StdAfx.h"
    #include "AdskTree.h"
     
    Adesk::UInt32 AdskTree::kCurrentVersionNumber =1 ;
     
    ACRX_DXF_DEFINE_MEMBERS (
        AdskTree, AcDbEntity,
        AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 
        AcDbProxyEntity::kNoOperation, ADSKTREE,
    ADSKMULTIMODEGRIPSIMPLESAMPLEAPP
    |Product Desc:     A description for your object
    |Company:          Your company name
    |WEB Address:      Your company WEB site address
    )
     
    AdskTree::AdskTree () : AcDbEntity () 
    {
        _basePoint = AcGePoint3d::kOrigin; 
        _season = AcString("Spring");
    }
     
    AdskTree::~AdskTree () 
    {
    }
     
    //----- AcDbObject protocols
    //- Dwg Filing protocol
    Acad::ErrorStatus AdskTree::dwgOutFields(AcDbDwgFiler *pFiler) 
                                                        const {
        assertReadEnabled () ;
        //----- Save parent class information first.
        Acad::ErrorStatus es =AcDbEntity::dwgOutFields (pFiler) ;
        if ( es != Acad::eOk )
            return (es) ;
        //----- Object version number needs to be saved first
        if ( (es =pFiler->writeUInt32 
                (AdskTree::kCurrentVersionNumber)) != Acad::eOk )
            return (es) ;
     
        //----- Output params
        pFiler->writePoint3d(_basePoint);
     
        return (pFiler->filerStatus ()) ;
    }
     
    Acad::ErrorStatus AdskTree::dwgInFields(AcDbDwgFiler *pFiler)
    {
        assertWriteEnabled () ;
        //----- Read parent class information first.
        Acad::ErrorStatus es =AcDbEntity::dwgInFields (pFiler) ;
        if ( es != Acad::eOk )
            return (es) ;
        //----- Object version number needs to be read first
        Adesk::UInt32 version =0 ;
        if ( (es =pFiler->readUInt32 (&version)) != Acad::eOk )
            return (es) ;
        if ( version > AdskTree::kCurrentVersionNumber )
            return (Acad::eMakeMeProxy) ;
     
        //----- Read params
        pFiler->readPoint3d(&_basePoint);
     
        return (pFiler->filerStatus ()) ;
    }
     
     
    //----- AcDbEntity protocols
    Adesk::Boolean AdskTree::subWorldDraw (AcGiWorldDraw *mode) 
    {
        assertReadEnabled () ;
     
        AcGeLineSeg3d mainBranch(
            _basePoint, 
            AcGePoint3d(_basePoint.x,_basePoint.y+10.0,_basePoint.z));
     
        AcDbLine *pLine1 = new AcDbLine(
                mainBranch.startPoint(), mainBranch.endPoint());
        mode->geometry().draw(pLine1);
        delete pLine1;
     
        int level = 0;
        BuildSubTree(&mainBranch, level, mode);
     
        return (AcDbEntity::subWorldDraw (mode)) ;
    }
     
    void AdskTree::setBasePoint(AcGePoint3d basePoint)
    {
        _basePoint = basePoint;
    }
     
    void AdskTree::setSeason(AcString season)
    {
        _season = season;
    }
     
    void AdskTree::BuildSubTree(AcGeLineSeg3d *pMainBranch, 
                                int level, 
                                AcGiWorldDraw *mode, 
                                Adesk::Boolean flower)
    {
        if(mode->isDragging() && level >= 2)
            return; // Light weight for dragging
     
        if(level >= 3)
        {
            if(_season == AcString("Spring"))
            {
                AcDbCircle *pLeaf = new AcDbCircle(
                    pMainBranch->endPoint(), 
                    AcGeVector3d::kZAxis, 
                    pMainBranch->length() * 0.2); 
     
                if(flower)
                    pLeaf->setColorIndex(1);
                else
                    pLeaf->setColorIndex(2); 
                mode->geometry().draw(pLeaf);
                delete pLeaf;
            }
            return;
        }
     
        int subLevel = level + 1;
        AcGePoint3d sp = AcGePoint3d::kOrigin;
        AcGePoint3d ep = AcGePoint3d::kOrigin;
        AcGeInterval intrvl;
        pMainBranch->getInterval(intrvl, sp, ep);
        double len = pMainBranch->length();
     
        AcGePoint3dArray pts;
        pMainBranch->getSamplePoints(5, pts);
     
        const double PI = 3.1415926535897932385;
        int cnt = 1;
        if(level == 0)
            cnt = 2;
        for(;cnt < 5; cnt++)
        {
            AcGeVector3d dir = pMainBranch->direction().normalize(); 
            AcGePoint3d refPt1 = pts[cnt];
     
            if(cnt == 4)
            {
                AcGePoint3d refPt2 = refPt1 + (len * 0.5) * dir;
     
                AcGeLineSeg3d branch1(refPt1, refPt2);
                AcDbLine *pBranchLine1 = new AcDbLine(refPt1, refPt2);
                mode->geometry().draw(pBranchLine1);
                delete pBranchLine1;
                BuildSubTree(&branch1, subLevel, mode, Adesk::kTrue);
            }
            else
            {
                AcGePoint3d refPt2 = refPt1 + 
                    (len * 0.5) * dir.transformBy(
                    AcGeMatrix3d::rotation(    PI * 0.25, 
                                            AcGeVector3d::kZAxis, 
                                            refPt1
                                           ));
     
                AcGeLineSeg3d branch1(refPt1, refPt2);
                AcDbLine *pBranchLine1 = new AcDbLine(refPt1, refPt2);
                mode->geometry().draw(pBranchLine1);
                delete pBranchLine1;
                BuildSubTree(&branch1, subLevel, mode);
     
                dir = pMainBranch->direction().normalize(); 
                refPt2 = refPt1 + (len * 0.5) * 
                    dir.transformBy(AcGeMatrix3d::rotation(
                    -PI * 0.25, AcGeVector3d::kZAxis, refPt1));
     
                AcGeLineSeg3d branch2(refPt1, refPt2);
                AcDbLine *pBranchLine2 = new AcDbLine(refPt1, refPt2);
                mode->geometry().draw(pBranchLine2);
                delete pBranchLine2;
                BuildSubTree(&branch2, subLevel, mode);
            }
        }
    }
     
    Acad::ErrorStatus AdskTree::subGetGripPoints ( 
        AcDbGripDataPtrArray &grips, 
        const double curViewUnitSize, 
        const int gripSize,  
        const AcGeVector3d &curViewDir, 
        const int bitflags ) const 
    {
        assertReadEnabled () ;
     
        AcDbGripData *pGripData = new AcDbGripData();
        pGripData->setGripPoint(_basePoint);
        grips.append(pGripData);
     
        return Acad::eOk;
    }
     
    Acad::ErrorStatus AdskTree::subMoveGripPointsAt (
        const AcDbVoidPtrArray &gripAppData, 
        const AcGeVector3d &offset,
        const int bitflags) 
    {
        assertWriteEnabled () ;
     
        _basePoint += offset;
     
        return Acad::eOk;
    }
     
    Acad::ErrorStatus AdskTree::subTransformBy(
                                        const AcGeMatrix3d& xform)
    {
        assertWriteEnabled();
        _basePoint.transformBy(xform);
        return (AcDbEntity::subTransformBy(xform));
    }
     
     
     
    // acrxEntryPoint.cpp
    // Usage 
     
    #include "resource.h"
    #include "AdskTree.h"
     
    #include "stdafx.h"
    #include "dbMultiModesGrip.h"
    #include "TreeMultiModesGripPE.h"
     
    static AdskTreeMultiModesGripPE *pMyMultiModeGrips = NULL;
     
    #define szRDS _RXST("Adsk")
     
    //----- ObjectARX EntryPoint
    class CMultiModeGripSimpleSampleApp : public AcRxArxApp {
     
    public:
        CMultiModeGripSimpleSampleApp () : AcRxArxApp () {}
     
        virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
            // TODO: Load dependencies here
     
            // You *must* call On_kInitAppMsg here
            AcRx::AppRetCode retCode 
                                =AcRxArxApp::On_kInitAppMsg(pkt) ;
     
            AdskTreeMultiModesGripPE::rxInit();
            AdskTree::rxInit();
            acrxBuildClassHierarchy();
     
            // TODO: Add your initialization code here
            if(pMyMultiModeGrips == NULL)
            {
                pMyMultiModeGrips = new AdskTreeMultiModesGripPE();
                AdskTree::desc()->addX(
                                    AcDbMultiModesGripPE::desc(), 
                                    pMyMultiModeGrips);
            }
     
            return (retCode) ;
        }
     
        virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
            // TODO: Add your code here
     
            // You *must* call On_kUnloadAppMsg here
            AcRx::AppRetCode retCode 
                            = AcRxArxApp::On_kUnloadAppMsg (pkt) ;
     
            // TODO: Unload dependencies here
            if(pMyMultiModeGrips != NULL)
            {
                delete pMyMultiModeGrips;
                pMyMultiModeGrips = NULL;
            }
            return (retCode) ;
        }
     
        virtual void RegisterServerComponents () {
        }
     
     
        // "Tree" command to create a tree
        static void AdskMultiModeGripSimpleSampleTREE(void)
        {
            ads_point pt;
            if (RTNORM != acedGetPoint(
                        NULL, L"\nSelect tree base point: ", pt))
                return;
     
            AcGePoint3d insertionPt = asPnt3d( pt );
     
            AdskTree *pTree = new AdskTree();
            pTree->setDatabaseDefaults();
            pTree->setBasePoint(insertionPt);
            PostToDb(pTree);
        }
     
        // Add the entity to DB
        static Acad::ErrorStatus PostToDb(AcDbEntity* pEnt)
        {
            AcDbDatabase *pDb 
                = acdbHostApplicationServices()->workingDatabase();
            AcDbObjectId objId;
     
            Acad::ErrorStatus      es;
            AcDbBlockTable*        pBlockTable;
            AcDbBlockTableRecord*  pSpaceRecord;
     
            pDb->getBlockTable(pBlockTable, AcDb::kForRead);
            pBlockTable->getAt( ACDB_MODEL_SPACE, 
                                pSpaceRecord, 
                                AcDb::kForWrite);
            es = pSpaceRecord->appendAcDbEntity(objId, pEnt);
            es = pEnt->close();
            es = pSpaceRecord->close();
            es = pBlockTable->close();
     
            return es;
        }
     
        // Command to update the graphics after the 
        // grip mode was changed. 
        // This will ensure a graphics is in sync with the
        // mode selected 
        static void AdskMultiModeGripSimpleSampleModeSwitchCmd(void)
        {
            AcDbObjectId entId 
                = AdskTreeMultiModesGripPE::getLastModifiedEntId(); 
     
            AcApDocument *pActiveDoc 
                            = acDocManager->mdiActiveDocument();
            AcDbDatabase *pDb = pActiveDoc->database();
     
            if(entId.isNull())
                return;
     
            AcDbEntity* pEnt = NULL;
            acdbOpenAcDbEntity(pEnt, entId, AcDb::kForWrite);
            pEnt->recordGraphicsModified();
            pEnt->close();
            acedUpdateDisplay();
        }
    } ;
     
    //-----------------------------------------------------------------------------
    IMPLEMENT_ARX_ENTRYPOINT(CMultiModeGripSimpleSampleApp)
     
    ACED_ARXCOMMAND_ENTRY_AUTO(CMultiModeGripSimpleSampleApp, 
                               AdskMultiModeGripSimpleSample, 
                               TREE, 
                               TREE, 
                               ACRX_CMD_TRANSPARENT, 
                               NULL)
    ACED_ARXCOMMAND_ENTRY_AUTO(CMultiModeGripSimpleSampleApp, 
                               AdskMultiModeGripSimpleSample, 
                               ModeSwitchCmd, 
                               ModeSwitchCmd, 
                               ACRX_CMD_TRANSPARENT,
                               NULL) 
    

    篇二:使自定义实体 GripMode 感知

    作者 Balaji Ramamoorthy

    原链接 http://adndevblog.typepad.com/autocad/2014/02/making-custom-entity-gripmode-aware.html

    这是一个实现嵌入式多段线的自定义实体的示例项目。 自定义实体通过实现“subMoveGripPointsAt”方法 GripMode 来启用对嵌入式实体进行操作的 GripMode。 在附件项目中,自定义实体的夹点模式与嵌入式多段线的夹点模式相同,但如果您的自定义实体有多个嵌入式实体,您可以扩展实现以在相似的线上为自定义实体公开更多的 GripModes。

    这是相关代码的一部分,示例项目可以从这里下载:

    示例项目下载 multimodegrip_embeddedpolyline

    //ContainerEntity.h 
     
    // Custom grip app data to identify the grips 
    class MyGripAppData : public AcDbObject
    {
    public:
       ACRX_DECLARE_MEMBERS(MyGripAppData) ;
     
       Adesk::UInt32 m_GripNumber;
     
       MyGripAppData(){ m_GripNumber = 0; }
     
       MyGripAppData(int gripNumber){ m_GripNumber = gripNumber; }
    };
     
    // Container custom entity that embeds a polyline
    class DLLIMPEXP AdskContainerEntity : public AcDbEntity 
    {
     
    public:
        ACRX_DECLARE_MEMBERS(AdskContainerEntity) ;
     
    protected:
        static Adesk::UInt32 kCurrentVersionNumber ;
     
    public:
        AdskContainerEntity () ;
        virtual ~AdskContainerEntity () ;
     
        AcDbPolyline *m_pPolyline; // Embedded Polyline
     
        // GripMode for use in "subMoveGripPointsAt" 
        // which is GripMode aware. 
        Adesk::UInt32 m_pCurrentGripMode; 
     
        // To remove or to add after depending on the GripMode
        Adesk::UInt32 m_iVertexNumber;    
     
        // Coordinates of the new vertex point to 
        // add if the GripMode is "Add Vertex"
        AcGePoint2d m_NewVertexCoord;     
     
    protected:
        virtual Adesk::Boolean subWorldDraw (AcGiWorldDraw *mode) ;
        virtual Acad::ErrorStatus subTransformBy
                                    (const AcGeMatrix3d& xform);
     
        Acad::ErrorStatus dwgInFields (AcDbDwgFiler *pFiler);
        Acad::ErrorStatus dwgOutFields (AcDbDwgFiler *pFiler) const;
     
        //- Grip points protocol
        virtual Acad::ErrorStatus subGetGripPoints (
                                    AcDbGripDataPtrArray &grips, 
                                    const double curViewUnitSize, 
                                    const int gripSize, 
                                    const AcGeVector3d &curViewDir, 
                                    const int bitflags) const ;
     
        virtual Acad::ErrorStatus subMoveGripPointsAt(
                                const AcDbVoidPtrArray& gripAppData, 
                                const AcGeVector3d& offset, 
                                const int bitflags);
    };
     
     
    // ContainerEntity.cpp : Implementation of AdskContainerEntity
     
    AdskContainerEntity::AdskContainerEntity () : AcDbEntity () 
    {
        m_pPolyline = NULL;
        m_pCurrentGripMode = 0;
        m_iVertexNumber = 0;
    }
     
    AdskContainerEntity::~AdskContainerEntity () 
    {
        if (m_pPolyline)
        {
            delete m_pPolyline;
            m_pPolyline = 0;
        }
    }
     
    Acad::ErrorStatus AdskContainerEntity::dwgInFields
                                            (AcDbDwgFiler *pFiler) 
    {
        assertWriteEnabled () ;
     
        Acad::ErrorStatus es = AcDbEntity::dwgInFields (pFiler) ;
        if ( es != Acad::eOk )
            return (es) ;
     
        Adesk::UInt32 version =0 ;
        if ( (es =pFiler->readUInt32 (&version)) != Acad::eOk )
            return (es) ;
     
        if ( version > AdskContainerEntity::kCurrentVersionNumber)
            return (Acad::eMakeMeProxy) ;
     
        // Read params
        Adesk::UInt32 numVerts = 0;
        pFiler->readUInt32(&numVerts);
     
        AcGePoint3dArray points;
        for(int i = 0; i < numVerts; i++)
        {
            AcGePoint3d pt;
            pFiler->readPoint3d(&pt);
            points.append(pt);
        }
     
        if (m_pPolyline)
        {
            delete m_pPolyline;
            m_pPolyline = 0;
        }
     
        m_pPolyline = new AcDbPolyline(numVerts);         
        m_pPolyline->setDatabaseDefaults();
     
        for(int i = 0; i < numVerts; i++)
        {
            AcGePoint3d pt(points[i]);
            m_pPolyline->addVertexAt(i, AcGePoint2d(pt.x, pt.y));
        }
     
        return (pFiler->filerStatus ()) ;
    }
     
     
    Acad::ErrorStatus AdskContainerEntity::dwgOutFields 
                                    (AcDbDwgFiler *pFiler) const 
    {
        assertReadEnabled () ;
     
        Acad::ErrorStatus es = AcDbEntity::dwgOutFields (pFiler) ;
        if ( es != Acad::eOk )
            return (es) ;
     
        if ( (es =pFiler->writeUInt32 
            (AdskContainerEntity::kCurrentVersionNumber)) 
                                                    != Acad::eOk )
            return (es) ;
     
        // Output params
        if(m_pPolyline)
        {
            Adesk::UInt32 numVerts = m_pPolyline->numVerts();
     
            pFiler->writeUInt32(numVerts);
     
            for(int i = 0; i < numVerts; i++)
            {
                AcGePoint3d pt;
                m_pPolyline->getPointAt(i, pt);
                pFiler->writePoint3d(pt); 
            }
        }
     
        return (pFiler->filerStatus ()) ;
    }
     
    Adesk::Boolean AdskContainerEntity::subWorldDraw 
                                            (AcGiWorldDraw *mode) 
    {
        assertReadEnabled () ;
     
        // Draw the polyline
        if(m_pPolyline)
            mode->geometry().pline (*m_pPolyline);
     
        return (AcDbEntity::subWorldDraw (mode)) ;
    }
     
    Acad::ErrorStatus AdskContainerEntity::subGetGripPoints(
                         AcDbGripDataPtrArray &grips, 
                         const double curViewUnitSize, 
                         const int gripSize,  
                         const AcGeVector3d &curViewDir, 
                         const int bitflags ) const 
    {
        assertReadEnabled () ;
     
        // Return the vertices of the embedded polyline as 
        // grip points
        if(m_pPolyline)
        {
            Adesk::UInt32 numVerts = m_pPolyline->numVerts();
            for(int i = 0; i < numVerts; i++)
            {
                AcGePoint3d pt;
                m_pPolyline->getPointAt(i, pt);
     
                AcDbGripData * pGripData = new AcDbGripData();
                pGripData->setAppData(new MyGripAppData(i));
                pGripData->setGripPoint(pt); 
                grips.append(pGripData);
            }
        }
        return Acad::eOk;
    }
     
    // Grip mode aware implementation of subMoveGripPointsAt
    // Depending on the current grip mode, it stretches / adds or
    // removes vertices from the embedded polyline
     Acad::ErrorStatus AdskContainerEntity::subMoveGripPointsAt(
                             const AcDbVoidPtrArray& gripAppData, 
                             const AcGeVector3d& offset, 
                             const int bitflags)
     {
        assertWriteEnabled () ;
     
        if(m_pPolyline)
        {
            switch(m_pCurrentGripMode)
            {
                case 0: // Stretch 
                {
                    for (int i = 0; i < gripAppData.length(); i++)
                    {
                        MyGripAppData *pMyGripAppData 
                            = static_cast<MyGripAppData *>
                                            (gripAppData.at(i));
                        if(pMyGripAppData != NULL)
                        {
                            int num = pMyGripAppData->m_GripNumber;
     
                            AcGePoint3d pt;
                            m_pPolyline->getPointAt(num, pt);
     
                            AcGeMatrix3d mat 
                                        = AcGeMatrix3d::kIdentity;
                            mat = mat.translation(offset);
     
                            pt = pt.transformBy(mat);
     
                            m_pPolyline->setPointAt(
                                    num, AcGePoint2d(pt.x, pt.y));
                        }
                    }
                    break;
                }
     
                case 1: // Add Vertex
                {
                    m_pPolyline->addVertexAt(
                        m_iVertexNumber+1, 
                        AcGePoint2d(m_NewVertexCoord.x, 
                                    m_NewVertexCoord.y)
                                            );
     
                    // Reset to default GripMode
                    m_pCurrentGripMode = 0; 
                    break;
                }
     
                case 2: // Remove Vertex
                {
                    if(m_iVertexNumber < m_pPolyline->numVerts())
                        m_pPolyline->removeVertexAt(m_iVertexNumber); 
     
                    // Reset to default GripMode
                    m_pCurrentGripMode = 0; 
                    break;
                }
            }
        }
        return Acad::eOk;
     }
     
    Acad::ErrorStatus AdskContainerEntity::subTransformBy(const AcGeMatrix3d& xform)
    {
        assertWriteEnabled();
     
        // Transform the polyline
        if(m_pPolyline)
            m_pPolyline->transformBy(xform);
     
        return (AcDbEntity::subTransformBy(xform));
    }
     
     
    // ContainerEntityMultiModesGripPE.h
     
    #include "dbMultiModesGrip.h"
     
    // GripModePE implementation for the custom entity
    // This exposes 3 gripmodes. 
    // Stretch vertex
    // Add Vertex
    // Remove Vertex
    class AdskContainerEntityMultiModesGripPE : public AcDbMultiModesGripPE
    {
    private:
        static AcDbMultiModesGripPE::GripMode _currentGripMode;
     
    public:
        ACRX_DECLARE_MEMBERS(AdskContainerEntityMultiModesGripPE);
     
        AdskContainerEntityMultiModesGripPE();
        ~AdskContainerEntityMultiModesGripPE();
     
        static AcDbObjectId getLastModifiedEntId();
        static Adesk::UInt32 getVertexNumberToAdd();
     
        virtual bool getGripModes(    AcDbEntity* pThis, 
                                    AcDbGripData* pGripData, 
                                    AcArray<GripMode>& modes, 
                                    unsigned int& curMode
                                 ) const;
     
        virtual unsigned int mode(    AcDbEntity* pThis, 
                                    AcDbGripData* pGripData
                                 ) const;
     
        virtual AcDbMultiModesGripPE::GripMode modeEx(
                AcDbEntity* pThis, AcDbGripData* pGripData) const;
     
        virtual bool setMode(    AcDbEntity* pThis, 
                                AcDbGripData* pGripData, 
                                unsigned int newMode);
     
        virtual AcDbMultiModesGripPE::GripType gripType(
                AcDbEntity* pThis, AcDbGripData* pGripData) const;
     
        virtual void reset(AcDbEntity* pThis);
    };
     
    // ContainerEntityMultiModesGripPE.cpp
    // GripModePE implementation for the custom entity
    // This exposes 3 gripmodes. 
    // Stretch vertex
    // Add Vertex
    // Remove Vertex
     
    AdskContainerEntityMultiModesGripPE::
                            AdskContainerEntityMultiModesGripPE()
    {
        // Default grip mode : Stretch Vertex
        _currentGripMode.Mode = 0;
        _currentGripMode.DisplayString = AcString("Stretch Vertex");
    }
     
    AdskContainerEntityMultiModesGripPE::
                            ~AdskContainerEntityMultiModesGripPE()
    {
    }
     
    // Returns the possible grip modes
    // Stretch vertex
    // Add Vertex
    // Remove Vertex
    bool AdskContainerEntityMultiModesGripPE::getGripModes(
                                    AcDbEntity* pThis, 
                                    AcDbGripData* pGripData, 
                                    AcArray<GripMode>& modes, 
                                    unsigned int& curMode) const 
    {
        // "Stretch Vertex" mode
        GripMode gripMode1;
        gripMode1.Mode = 0;
        gripMode1.DisplayString = AcString("Stretch Vertex");
        gripMode1.ActionType = AcDbMultiModesGripPE::kDragOn;
     
        modes.append(gripMode1);
     
        // "Add Vertex" mode
        GripMode gripMode2;
        gripMode2.Mode = 1;
        gripMode2.DisplayString = AcString("Add Vertex");
        gripMode2.ActionType = AcDbMultiModesGripPE::kImmediate;
     
        modes.append(gripMode2);
     
        // "Remove Vertex" mode to be available only if there are 
        // more than 2 vertices in the polyline.
        AdskContainerEntity *pContEnt 
                               = AdskContainerEntity::cast(pThis);
        if(pContEnt->m_pPolyline != NULL)
        {
            if(pContEnt->m_pPolyline->numVerts() > 2)
            {
                GripMode gripMode3;
                gripMode3.Mode = 2;
                gripMode3.DisplayString = AcString("Remove Vertex");
                gripMode3.ActionType 
                            = AcDbMultiModesGripPE::kImmediate;
     
                modes.append(gripMode3);
            }
        }
     
        // "Stretch Vertex" is the current mode
        curMode = 0;
     
        return true;
    }
     
    // Gets the current mode identifier.
    unsigned int AdskContainerEntityMultiModesGripPE::mode(
                AcDbEntity* pThis, AcDbGripData* pGripData) const
    {
        return _currentGripMode.Mode; 
    }
     
    // Return the current mode.
    AcDbMultiModesGripPE::GripMode 
    AdskContainerEntityMultiModesGripPE::modeEx(
                AcDbEntity* pThis, AcDbGripData* pGripData) const 
    {
        return _currentGripMode;
    }
     
    // Sets the current mode.
    bool AdskContainerEntityMultiModesGripPE::setMode(
                    AcDbEntity* pThis, 
                    AcDbGripData* pGripData, unsigned int newMode)
    {
        bool retStatus = true;
     
        _currentGripMode.Mode = newMode;
     
        AcDbObjectId entId = pThis->id();
        AdskContainerEntity *pContEnt 
                                = AdskContainerEntity::cast(pThis);
        pContEnt->m_pCurrentGripMode = newMode;
     
        switch(newMode)
        {
            case 0:
            {
                _currentGripMode.DisplayString 
                                     = AcString("Stretch Vertex"); 
                break;
            }
     
            case 1:
            {
                _currentGripMode.DisplayString 
                                         = AcString("Add Vertex");
     
                // Create a temporary copy of the embedded Polyline for jigging purposes
                AcDbPolyline *pPolyTemp = AcDbPolyline::cast(pContEnt->m_pPolyline->clone());
     
                MyGripAppData *pMyGripAppData = static_cast<MyGripAppData *>(pGripData->appData());
                if(pMyGripAppData != NULL)
                {
                    // Adding vertex requires a Jig
                    PolyLineVertexAddJig *pPolyAddVertedJig 
                        = new PolyLineVertexAddJig(
                          pPolyTemp, pMyGripAppData->m_GripNumber);
                    AcEdJig::DragStatus status = pPolyAddVertedJig->doIt();
                    if(status != AcEdJig::kCancel)
                    {
                        pContEnt->m_iVertexNumber 
                                    = pMyGripAppData->m_GripNumber;
                        pContEnt->m_NewVertexCoord 
                               = pPolyAddVertedJig->AddedVertex();
                    }
                    else
                    {
                        // Cancel setting the GripMode as the 
                        // Jig was canceled 
                        retStatus = false; 
                    }
     
                    delete pPolyAddVertedJig;
                }
     
                break;
            }
     
            case 2:
            {
                _currentGripMode.DisplayString 
                                      = AcString("Remove Vertex");
     
                MyGripAppData *pMyGripAppData 
                    = static_cast<MyGripAppData *>(
                                            pGripData->appData());
                if(pMyGripAppData != NULL)
                {
                    pContEnt->m_iVertexNumber 
                                   = pMyGripAppData->m_GripNumber;
                }
                break;
            }
        }
     
        return retStatus;
    }
     
    // Gets the grip type of a given grip.
    AcDbMultiModesGripPE::GripType 
        AdskContainerEntityMultiModesGripPE::gripType(
                AcDbEntity* pThis, AcDbGripData* pGripData) const 
    {
        return AcDbMultiModesGripPE::kPrimary;  
    }
     
    // resets current mode to default 
    void AdskContainerEntityMultiModesGripPE::reset(AcDbEntity* pThis)
    {
        _currentGripMode.Mode = 0;
        _currentGripMode.DisplayString = AcString("Stretch Vertex");
    }
     
     
    // PolyLineVertexAddJig.h
    // Polyline jig for adding a new vertex
     
    class PolyLineVertexAddJig : public AcEdJig
    {
    public:
        PolyLineVertexAddJig();
        ~PolyLineVertexAddJig();
        PolyLineVertexAddJig(
                  AcDbPolyline *pPoly, Adesk::UInt32 vertexToAdd);
     
        AcEdJig::DragStatus doIt();
        virtual DragStatus sampler();
        virtual Adesk::Boolean update();
     
        AcGePoint2d AddedVertex();
     
        virtual AcDbEntity* entity() const;
     
    private:
        AcDbPolyline *m_pPoly;
        Adesk::UInt32 m_nVertexToAdd;
     
        AcGePoint3d vertexPointTemp;
        AcGePoint3d vertexPoint;
     
        Adesk::Boolean addNew;
    };
     
    // PolyLineVertexAddJig.cpp
     
    #include "StdAfx.h"
    #include "PolyLineVertexAddJig.h"
     
    PolyLineVertexAddJig::PolyLineVertexAddJig()
    {
        m_pPoly = NULL;
        vertexPointTemp = AcGePoint3d::kOrigin;
        vertexPoint = AcGePoint3d::kOrigin;
        addNew = Adesk::kTrue;
    }
     
    PolyLineVertexAddJig::PolyLineVertexAddJig(
                   AcDbPolyline *pPoly, Adesk::UInt32 vertexToAdd)
    {
        // Polyline to jig
        m_pPoly = pPoly;
     
        // Index to mark the position of the new vertex
        m_nVertexToAdd = vertexToAdd;
     
        // To keep track of the coordinates during jigging
        vertexPointTemp = AcGePoint3d::kOrigin;
        vertexPoint = AcGePoint3d::kOrigin;
     
        // To know if we already added a vertex during jigging
        addNew = Adesk::kTrue;
    }
     
    PolyLineVertexAddJig::~PolyLineVertexAddJig()
    {
        // Cleanup
        if(m_pPoly)
        {
            delete m_pPoly;
            m_pPoly = NULL;
        }
    }
     
    // Start the jig
    AcEdJig::DragStatus PolyLineVertexAddJig::doIt()
    {
        AcEdJig::DragStatus stat = AcEdJig::kCancel;
     
        if(m_pPoly)
        {
            setDispPrompt(ACRX_T("\n Select vertex point : "));
            stat = drag();
        }
     
        return stat;
    }
     
    AcEdJig::DragStatus PolyLineVertexAddJig::sampler()
    {
        DragStatus stat;
        setUserInputControls((UserInputControls)
            (AcEdJig::kAccept3dCoordinates
             | AcEdJig::kNoNegativeResponseAccepted
             | AcEdJig::kNoZeroResponseAccepted));
     
        // Get a point input for the coordinates
        stat = acquirePoint(vertexPoint);
        if (vertexPointTemp != vertexPoint)
            vertexPointTemp = vertexPoint;
        else if (stat == AcEdJig::kNormal)
            return AcEdJig::kNoChange;
     
        return stat;
    }
     
    Adesk::Boolean PolyLineVertexAddJig::update()
    {
        if(m_pPoly)
        {
            if(addNew)
            {// First time, add a new vertex
                m_pPoly->addVertexAt(
                    m_nVertexToAdd+1, 
                    AcGePoint2d(vertexPoint.x, vertexPoint.y));
            }
            else
            { // Update the coordinates of the 
              // previously added vertex
                if(m_nVertexToAdd < m_pPoly->numVerts())
                {
                    m_pPoly->setPointAt(
                        m_nVertexToAdd+1, 
                        AcGePoint2d(vertexPoint.x, vertexPoint.y));
                }
            }
        }
     
        if(addNew)
            addNew = Adesk::kFalse;
     
        return Adesk::kTrue;
    }
     
    AcDbEntity* PolyLineVertexAddJig::entity() const
    {
        return m_pPoly;
    }
     
    // To get the coordinates of the vertex added by this jig
    AcGePoint2d PolyLineVertexAddJig::AddedVertex()
    {
        return AcGePoint2d(vertexPoint.x, vertexPoint.y);
    }
    
  • 相关阅读:
    Android实战项目——家庭记账本(六)
    Android实战项目——家庭记账本(五)
    周总结(十五)
    Android实战项目——家庭记账本(四)
    Auto-Encoder(自编码器)原理
    Android实战项目——家庭记账本(三)
    Android实战项目——家庭记账本(二)
    Android实战项目——家庭记账本(一)
    Android实战项目——家庭记账本设计思路
    防止或减少过拟合的方式(二)——Dropout
  • 原文地址:https://www.cnblogs.com/edata/p/16062438.html
Copyright © 2020-2023  润新知