06/06/2015
Динамически размеры при помощи GripOverrule
Динамические размеры – это простой и интуитивно удобный способ дать возможность пользователю изменять примитивы при редактировании при помощи «ручек». Для того чтобы это работало необходимо установить системную переменную DYNMODE в значение 2 или 3. Если вы хотите изменить обычное поведение редактирования при помощи «ручек» и указать другой размер, что интуитивно и удобно для пользователя – Grip Overrule поможет вам в этом.Для окружности, когда «ручка» выбрана, появляется запрос значения радиуса в динамическом размере. Следующий пример кода меняет стандартное поведение. При выборе «ручки» у пользователя спрашивается диаметр окружности и динамический размер помещается горизонтально в центре окружности. Также в командной строке отображается новое, введенное пользователем, значение диаметра.
Вот так это выглядит при включенном и выключенном Grip Overrule:
Исходный код:
Код - C++: [Выделить]
- #include "dbentityoverrule.h"
- class CMyGripOverrule: public AcDbGripOverrule
- {
- public :
- static CMyGripOverrule* _pTheOverrule;
- ACRX_DECLARE_MEMBERS(CMyGripOverrule);
- static AcDbDimData *mpDimData;
- static void CMyGripOverrule::AddOverrule()
- {
- mpDimData = NULL;
- if (_pTheOverrule != NULL)
- return ;
- _pTheOverrule = new CMyGripOverrule();
- AcRxOverrule::addOverrule(
- AcDbCircle::desc(),
- _pTheOverrule,
- true
- );
- CMyGripOverrule::setIsOverruling(true );
- }
- static void CMyGripOverrule::RemoveOverrule()
- {
- if (_pTheOverrule == NULL)
- return ;
- CMyGripOverrule::setIsOverruling(false );
- AcRxOverrule::removeOverrule(
- AcDbCircle::desc(),
- _pTheOverrule
- );
- delete _pTheOverrule;
- _pTheOverrule = NULL;
- }
- ACDB_PORT Acad::ErrorStatus moveGripPointsAt(
- AcDbEntity* pSubject,
- const AcDbVoidPtrArray& gripAppData,
- const AcGeVector3d& offset,
- const int bitflags)
- {
- if (!pSubject->isKindOf(AcDbCircle::desc()))
- return Acad::eOk;
- AcDbCircle* pCircle = AcDbCircle::cast(pSubject);
- if (pCircle == NULL)
- return Acad::eOk;
- AcGeVector3d normal = pCircle->normal();
- AcGeVector3d horizDir = normal.perpVector();
- AcGePoint3d center = pCircle->center();
- double radius = pCircle->radius();
- AcGePoint3d pt1 = center + radius * horizDir;
- pt1 = pt1 + offset;
- AcGeVector3d radVec = pt1 - center;
- updateDimensions(pCircle, center-radVec, center+radVec);
- AcDbGripOverrule::moveGripPointsAt(
- pSubject,
- gripAppData,
- offset,
- bitflags);
- }
- ACDB_PORT Acad::ErrorStatus getGripPoints(
- const AcDbEntity* pSubject,
- AcDbGripDataPtrArray& grips,
- const double curViewUnitSize,
- const int gripSize,
- const AcGeVector3d& curViewDir,
- const int bitflags
- )
- {
- if (!pSubject->isKindOf(AcDbCircle::desc()))
- return Acad::eOk;
- AcDbCircle* pCircle
- = AcDbCircle::cast(pSubject);
- if (pCircle == NULL)
- return Acad::eOk;
- AcDbGripDataPtrArray oldGrips;
- AcDbGripOverrule::getGripPoints(
- pSubject, oldGrips,
- curViewUnitSize, gripSize,
- curViewDir, bitflags);
- AcDbGripData * pGripData
- = new AcDbGripData(*(oldGrips.at(1)));
- pGripData->setGripPoint(oldGrips.at(1)->gripPoint());
- pGripData->setHotGripDimensionFunc(MyGripHotGripDimensionfunc);
- pGripData->setHoverDimensionFunc(MyHoverGripDimensionfunc);
- pGripData->setCLIPromptFunc(MyGripCLIPromptCallback);
- grips.append(pGripData);
- return Acad::eOk;
- }
- static void gripDimensionCbackFunc(
- AcDbGripData* pGrip,
- const AcDbObjectId& objId,
- double dimScale,
- AcDbDimDataPtrArray& dimDataArr)
- {
- Acad::ErrorStatus es;
- if (pGrip == NULL)
- return ;
- AcDbEntity *pEnt = NULL;
- if (acdbOpenAcDbEntity(
- pEnt, objId,
- AcDb::kForRead) != Acad::eOk)
- return ;
- AcDbCircle *pCircle
- = AcDbCircle::cast(pEnt);
- if (pCircle == NULL) {
- pEnt->close();
- return ;
- }
- AcGeVector3d normal = pCircle->normal();
- AcGeVector3d horizDir = normal.perpVector();
- AcGeVector3d vertDir = normal.crossProduct(horizDir);
- AcGePoint3d center = pCircle->center();
- double radius = pCircle->radius();
- pCircle->close();
- AcDbAlignedDimension *pAlignedDim
- = new AcDbAlignedDimension();
- pAlignedDim->setDatabaseDefaults();
- es = pAlignedDim->setDimsah(true );
- es = pAlignedDim->setDimse1(true );
- es = pAlignedDim->setDimblk1(_T("None" ));
- es = pAlignedDim->setNormal(normal);
- es = pAlignedDim->setElevation(0.0);
- es = pAlignedDim->setHorizontalRotation(0.0);
- es = pAlignedDim->setXLine1Point(center - radius * horizDir);
- es = pAlignedDim->setXLine2Point(center + radius * horizDir);
- es = pAlignedDim->setDimLinePoint(center + 0.5 * radius * horizDir);
- es = pAlignedDim->setDynamicDimension(true );
- es = pAlignedDim->setColorIndex(1);
- AcDbDimData *pDimData
- = new AcDbDimData(pAlignedDim);
- es = pDimData->setOwnerId(objId);
- es = pDimData->setDimFocal(true );
- es = pDimData->setDimEditable(true );
- es = pDimData->setDimRadius(true );
- es = pDimData->setDimHideIfValueIsZero(true );
- es = pDimData->setDimValueFunc(setDimValueCbackFunc);
- es = pDimData->setDimension(pAlignedDim);
- dimDataArr.append(pDimData);
- mpDimData = pDimData;
- }
- bool isApplicable(
- const AcRxObject *pOverruledSubject) const
- {
- if (!pOverruledSubject->isKindOf (AcDbCircle::desc())) return false ;
- return true ;
- }
- static const ACHAR* MyGripCLIPromptCallback
- (AcDbGripData *pGripData)
- {
- return ACRX_T("\nДиаметр окружности: " );
- }
- static void MyGripHotGripDimensionfunc
- (AcDbGripData *pGripData,
- const AcDbObjectId &entId,
- double dimScale,
- AcDbDimDataPtrArray &dimDataArr)
- {
- gripDimensionCbackFunc(pGripData, entId, dimScale, dimDataArr);
- }
- static void MyHoverGripDimensionfunc
- (AcDbGripData *pGripData,
- const AcDbObjectId &entId,
- double dimScale,
- AcDbDimDataPtrArray &dimDataArr)
- {
- gripDimensionCbackFunc(pGripData, entId, dimScale, dimDataArr);
- }
- static AcGeVector3d setDimValueCbackFunc
- (AcDbDimData* pDimData, AcDbEntity* pEnt,
- double newValue, const AcGeVector3d& offset)
- {
- AcGeVector3d newOffset(offset);
- if ((pDimData == NULL) || (pEnt == NULL))
- return newOffset;
- AcDbObjectId objId;
- AcDbCircle *pCir = AcDbCircle::cast(pEnt);
- if (pCir == NULL)
- return newOffset;
- pCir->setRadius(newValue * 0.5);
- return newOffset;
- }
- static bool updateDimensions (AcDbCircle* pCircle, AcGePoint3d xline1Pt, AcGePoint3d xline2Pt)
- {
- if (!pCircle || !mpDimData)
- return false ;
- AcDbObjectId entId = pCircle->objectId();
- AcGeVector3d normal = pCircle->normal();
- AcGeVector3d horizDir = normal.perpVector();
- AcGeVector3d vertDir = normal.crossProduct(horizDir);
- AcGePoint3d center = pCircle->center();
- double radius = pCircle->radius();
- AcDbObjectId ownerId;
- AcDbDimData *pDimData = mpDimData;
- AcDbAlignedDimension *pAlignedDim = AcDbAlignedDimension::cast(pDimData->dimension());
- if (pAlignedDim != NULL)
- {
- pAlignedDim->setXLine1Point(xline1Pt);
- pAlignedDim->setXLine2Point(xline2Pt);
- pAlignedDim->setDimLinePoint(xline1Pt + (xline2Pt - xline1Pt) * 0.5);
- }
- return true ;
- }
- };
- AcDbDimData * CMyGripOverrule::mpDimData = NULL;
- CMyGripOverrule* CMyGripOverrule::_pTheOverrule = NULL;
- ACRX_NO_CONS_DEFINE_MEMBERS( CMyGripOverrule, AcDbGripOverrule);
Источник: http://adndevblog.typepad.com/autocad/2015/06/dynamic-dimension-using-gripoverrule.html
Автор перевода: Александр Ривилис
Обсуждение: http://adn-cis.org/forum/index.php?topic=2774
Опубликовано 06.06.2015