AcDbArcDimension as dynamic dimension

AcDbArcDimension as dynamic dimension

Anonymous
Not applicable
567 Views
2 Replies
Message 1 of 3

AcDbArcDimension as dynamic dimension

Anonymous
Not applicable

Hello.

I have created Jig with an arc length dynamic dimension.

But I'm unable to set the desired arc length through the edit field of the dimension.

Any entered value is interpreted as an error (frame of the edit field turns red).

At the same time, any linear dynamic dimension based on AcDbAlignedDimension or AcDbRotatedDimension works wonderful.

Can I use the class AcDbArcDimension as dynamic dimension?

 

I have created sample project for test,  which creates an arc by center, start and end points.

The implementation of the dimData() in test class looks folows:

 

There is one small problem: If we remove the comments on the call pArcDim->setDynamicDimension(true), the field for editing dimension value always change its location on (0,0,0).

 

Full text of the source code :

 

ArcTestJig.h

Spoiler
#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();

 ArcTestJig.cpp

Spoiler
#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 Likes
568 Views
2 Replies
Replies (2)
Message 2 of 3

tbrammer
Advisor
Advisor

To move the dynamic edit control to a different point simply do this:

 

AcDbDimDataPtrArray* CArcTestJig::dimData(const double dimScale) {

   ...

    AcGePoint3d pt;
    m_pArc->getStartPoint(pt);
    pArcDim->setTextPosition(pt);
    pArcDim->setDynamicDimension(true);

   ...

}

 

Unfortunately I didn't find a solution for your main problem. Maybe This  might help you.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

0 Likes
Message 3 of 3

Anonymous
Not applicable

Thanks for the help.

Really, setTextPosition() call changes the position of the edit field.

0 Likes