|
我已经创建了一个弧长动态尺寸夹具。
但我无法通过维度的编辑字段设置所需的弧长。
任何输入的值都将被解释为错误(编辑字段的边框变为红色)。
同时,基于AcDbAlignedDimension或AcDbRotatedDimension的任何线性动态维度都非常有用。
我可以将AcDbArcDimension类用作动态维度吗?
我已经为测试创建了一个示例项目,它按中心、起点和终点创建了一个弧。
测试类中dimData()的实现如下所示:
#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:
void releaseDimData();
void updateDimData();
void setEndAngleTo(AcGePoint3d pntEnd);
protected:
#define ARCDIM_OFFSET 20.0
enum stage
{
center = 1,
startpnt,
endpnt
};
stage m_Stage;
AcGePoint3d m_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;
}
void CArcTestJig::updateDimData()
{
if(m_pDimData == NULL || m_pArc == NULL)
return;
if(m_pDimData->length() < 2)
return;
double dRadius = m_pArc->radius();
AcGePoint3d pntCenter = m_pArc->center();
AcGePoint3d pntStart;
m_pArc->getStartPoint(pntStart);
double dStart;
m_pArc->getStartParam(dStart);
AcGePoint3d pntEnd;
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;
}
}
return Acad::eInvalidInput;
}
void CArcTestJig::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::DragStatus CArcTestJig::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();
} |
|