admin 发表于 2024-3-16 09:01:15

一个弧长动态尺寸

#pragma once


class CArcTestJig: public AcEdJig
{
public:
        CArcTestJig();
        virtual ~CArcTestJig();

        //- dynamic dimension data setup
        virtual AcDbDimDataPtrArray* dimData (const double dimScale) override;
        //- dynamic dimension data update
        virtual Acad::ErrorStatus setDimValue(const AcDbDimData* dimData,        const double dimValue) override;

        virtual Adesk::Boolean update() override;
        virtual DragStatus sampler() override;
        virtual AcDbEntity* entity() const override         { return m采用pArc;}

        AcEdJig::DragStatus start();

protected:
        voidreleaseDimData();
        voidupdateDimData();
        voidsetEndAngleTo(AcGePoint3d pntEnd);

protected:

#define ARCDIM采用OFFSET20.0

        enum stage
        {
                center = 1,
                startpnt,
                endpnt
        };

        stage      m采用Stage;
        AcGePoint3dm采用PntPrev;
        AcDbArc*   m采用pArc;

        AcDbDimDataPtrArray* m采用pDimData;

        double   采用采用PI;
};

void CreateArc();



#include "StdAfx.h"
#include "ArcTestJig.h"

//
CArcTestJig::CArcTestJig(): m采用Stage(center), m采用pDimData(NULL), 采用采用PI(atan (1.)*4)
{
        m采用pArc = new AcDbArc(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, 100., 0., 采用采用PI/2);
}

CArcTestJig::~CArcTestJig()
{
        releaseDimData();
};

void CArcTestJig::releaseDimData()
{
        if(m采用pDimData == NULL)
                return;
        for(int ii = 0; ii < m采用pDimData->length(); ii++)
                delete m采用pDimData->at(ii);

        delete m采用pDimData;
        m采用pDimData = NULL;
}

voidCArcTestJig::updateDimData()
{
        if(m采用pDimData == NULL || m采用pArc == NULL)
                return;

        if(m采用pDimData->length() < 2)
                return;

        doubledRadius = m采用pArc->radius();
        AcGePoint3dpntCenter = m采用pArc->center();

        AcGePoint3dpntStart;
        m采用pArc->getStartPoint(pntStart);
        double dStart;
        m采用pArc->getStartParam(dStart);

        AcGePoint3dpntEnd;
        m采用pArc->getEndPoint(pntEnd);
        double dEnd;
        m采用pArc->getEndParam(dEnd);

        AcDbArcDimension* pArcDim = AcDbArcDimension::cast(m采用pDimData->at(0)->dimension());
        if(pArcDim)
        {
                pArcDim->setArcSymbolType(2); // no symbol
                pArcDim->setCenterPoint(pntCenter);
                pArcDim->setXLine1Point(pntStart);
                pArcDim->setXLine2Point(pntEnd);
                pArcDim->setArcStartParam(dStart);
                pArcDim->setArcEndParam(dEnd);

                AcGeVector3d vStart = (pntStart - pntCenter).normalize();
                AcGeVector3d vEnd = (pntEnd - pntCenter).normalize();
                AcGeVector3d vMid = vStart + vEnd;
                vMid.normalize();

                if(vStart.angleTo(vEnd, m采用pArc->normal()) > 采用采用PI)
                        vMid.negate();

                pArcDim->setArcPoint(pntCenter + (dRadius + ARCDIM采用OFFSET)*vMid );

                pArcDim->setHasLeader(false);
        }

        AcDbAlignedDimension* pChordDim = AcDbAlignedDimension::cast(m采用pDimData->at(1)->dimension());
        if(pChordDim)
        {
                pChordDim->setXLine1Point(pntStart);
                pChordDim->setXLine2Point(pntEnd);
                AcGeVector3d vDir = (pntEnd - pntStart).normalize();

                pChordDim->setDimLinePoint(pntStart + ARCDIM采用OFFSET*vDir.perpVector());
        }
}

AcDbDimDataPtrArray* CArcTestJig::dimData (const double dimScale)
{
        if(m采用Stage != endpnt)
                return NULL;

        releaseDimData();

        m采用pDimData = new AcDbDimDataPtrArray();

        AcDbDimData* pNewData(NULL);

        // Arc Dimension
        AcDbArcDimension* pArcDim = new AcDbArcDimension();
        pArcDim->setDatabaseDefaults();
        pArcDim->setNormal(m采用pArc->normal());
        pArcDim->setElevation(0.0);
        pArcDim->setHorizontalRotation(0.0);
        pArcDim->setDimscale(dimScale);
        pArcDim->setDimtad(1);
//        pArcDim->setDynamicDimension(true);

        pNewData = new AcDbDimData(pArcDim);
        pNewData->setDimHideIfValueIsZero(false);
        pNewData->setDimEditable(true);
        pNewData->setDimFocal(true);

        m采用pDimData->append(pNewData);

        // Chord Dimension
        AcDbAlignedDimension* pChordDim = new AcDbAlignedDimension();
        pChordDim->setDatabaseDefaults();
        pChordDim->setNormal(m采用pArc->normal());
        pChordDim->setElevation(0.0);
        pChordDim->setHorizontalRotation(0.0);
        pChordDim->setDimtad(1);
        pChordDim->setDynamicDimension(true);

        pNewData = new AcDbDimData(pChordDim);
        pNewData->setDimHideIfValueIsZero(false);
        pNewData->setDimEditable(true);
        pNewData->setDimFocal(false);

        m采用pDimData->append(pNewData);

        // set dimension location
        updateDimData();

        return m采用pDimData;
}

Acad::ErrorStatus CArcTestJig::setDimValue(const AcDbDimData* dimData,        const double dimValue)
{
        AcDbDimension* pDim = dimData->dimension();

        AcDbArcDimension* pArcDim = AcDbArcDimension::cast(pDim);
        if(pArcDim)
        {
                AcGePoint3d pntNewEnd;
                Acad::ErrorStatus es = m采用pArc->getPointAtDist(dimValue, pntNewEnd);
                if(Acad::eOk != es)
                        return es;

                setEndAngleTo(pntNewEnd);

                return Acad::eOk;
        }
        else
        {
                AcDbAlignedDimension* pChordDim =AcDbAlignedDimension::cast(pDim);
                if(pChordDim)
                {
                        double dRadius = m采用pArc->radius();
                        if(dimValue > dRadius*2)
                                return Acad::eNotApplicable;


                        double dAngDlt = asin(dimValue/(dRadius*2));
                        double dNewEnd = m采用pArc->startAngle() + dAngDlt*2;
                        m采用pArc->setEndAngle(dNewEnd);
                        return Acad::eOk;
                }
        }

        returnAcad::eInvalidInput;
}

voidCArcTestJig::setEndAngleTo(AcGePoint3d pntEnd)
{
        AcGeVector3d vEnd = (pntEnd - m采用pArc->center()).normalize();
        double dNewEnd = vEnd.angleTo(AcGeVector3d::kXAxis, m采用pArc->normal().negate());
//         if(dNewEnd > 采用采用PI)
//                 dNewEnd -= 采用采用PI*2;
        m采用pArc->setEndAngle(dNewEnd);
}

Adesk::Boolean CArcTestJig::update()
{
        if(m采用pArc == NULL)
                return false;

        switch(m采用Stage)
        {
                case center:
                        m采用pArc->setCenter(m采用PntPrev);
                        break;

                case startpnt:
                        {
                                AcGeVector3d vStart = m采用PntPrev - m采用pArc->center();
                                double dRadius = vStart.length();
                                vStart.normalize();
                                double dStart = vStart.angleTo(AcGeVector3d::kXAxis, m采用pArc->normal().negate());
                                if(dStart > 采用采用PI)
                                        dStart -= 采用采用PI*2;
                                m采用pArc->setRadius(dRadius);
                                m采用pArc->setStartAngle(dStart);
                                m采用pArc->setEndAngle(dStart + 采用采用PI/2);
                        }
                        break;

                case endpnt:
                        setEndAngleTo(m采用PntPrev);
                        break;

                default:
                        return false;
        }

        updateDimData();
        return true;
}

AcEdJig::DragStatus CArcTestJig::sampler()
{
        setUserInputControls((UserInputControls)        (        AcEdJig::kAccept3dCoordinates        | AcEdJig::kNullResponseAccepted));

        DragStatus sts;
        AcGePoint3d pntTemp;
        if(m采用Stage == startpnt)
                sts = acquirePoint(pntTemp, m采用pArc->center());
        else
                sts = acquirePoint(pntTemp);
        if(sts == AcEdJig::kNormal)
        {
                if(pntTemp.isEqualTo(m采用PntPrev))
                        sts = kNoChange;
                m采用PntPrev = pntTemp;
        }
        return sts;
}

AcEdJig::DragStatusCArcTestJig::start()
{
        CString sPrompt;

        m采用Stage = center;
        sPrompt = 采用T("\nCenter of arc: ");
        setDispPrompt(sPrompt);
        AcEdJig::DragStatus sts = drag();
        if(sts != kNormal)
                return sts;

        m采用Stage = startpnt;
        sPrompt = 采用T("\nStart point of arc: ");
        setDispPrompt(sPrompt);
        m采用pArc->getStartPoint(m采用PntPrev);
        sts = drag();
        if(sts != kNormal)
                return sts;

        m采用Stage = endpnt;
        sPrompt = 采用T("\nEnd point of arc: ");
        setDispPrompt(sPrompt);
        m采用pArc->getEndPoint(m采用PntPrev);
        sts = drag();
        if(sts == kNormal)
        {
                AcDbObjectId idArc = append();
        }

        return sts;
}

void CreateArc()
{
        CArcTestJig arcJig;
        arcJig.start();
}
页: [1]
查看完整版本: 一个弧长动态尺寸