AcDbArcDimension as dynamic dimension

2023-07-06 16:48:21 浏览数 (1)

我已经创建了一个弧长动态尺寸夹具。

但我无法通过维度的编辑字段设置所需的弧长。

任何输入的值都将被解释为错误(编辑字段的边框变为红色)。

同时,基于AcDbAlignedDimension或AcDbRotatedDimension的任何线性动态维度都非常有用。

我可以将AcDbArcDimension类用作动态维度吗?

我已经为测试创建了一个示例项目,它按中心、起点和终点创建了一个弧。

测试类中dimData()的实现如下所示:

代码语言:javascript复制
#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();
}

0 人点赞