Создаем ассоциативный массив с помощью ObjectARX
В этой статье мы рассмотрим возможность создания объекта МАССИВ (Array) используя три класса параметров для создания ассоциативного массива унаследованных от класса AcDbAssocArrayCommonParameters:- AcDbAssocArrayPathParameters
- AcDbAssocArrayPolarParameters
- AcDbAssocArrayRectangularParameters
который может использоваться для изменения параметров ассоциативного Прямоугольного Массива, Массива по Траектории и Кругового Массива независимо от типа массива.
AcDbAssocArrayActionBody– это ассоциативное действие, которое выполняется для управления или позиционирования массива примитивов, основанное на параметрах массива.
Создание массива по траектории:
Этому массиву требуется направляющая кривая и исходный примитив в качестве профиля для прокладывания вдоль кривой. Все массивы представляют собой вставки (анонимных) блоков, которые ссылаются на массив записей таблицы блоков (массив BTR). Массив BTR содержит список примитивов, представляющих элементы массива. По-умолчанию, этот класс представляет массив как экземпляр AcDbBlocReference ссылающийся на исходную запись таблицы блоков (исходный BTR) с учетом смещения элементов массива.
- void createPathArray()
- {
- try
- {
- Acad::ErrorStatus es;
- // Переменные аргументов
- int nVarCount = 0;
- int index = 0;
- Adesk::Boolean isAssociative;
- AcGePoint3d basePoint;
- double itemsapcing = 1.573;
- double rowSpacing = 1.5;
- double levelSpacing = 1;
- int itemCount = 1;
- int rowCount = 1;
- int levelCount = 1;
- double rowElevation = 1;
- int method=0;
- AcDbObjectId profileEntityId;
- AcDbObjectId CurveEntityId;
- AcDbEntity * profileEntity = NULL;
- AcDbEntity * curveEntity = NULL;
- AcDbObjectIdArray profileEntityIdArray;
- AcDbObjectId arrayId;
- AcDbObjectId actionBodyId;
- index = 1;
- isAssociative = Adesk::kTrue;
- basePoint = basePoint.kOrigin;
- Adesk::Boolean isAssoc = isAssociative;
- AcDbVertexRef *basePointVertex = new AcDbVertexRef(basePoint);
- // Создаем примитив профиля
- profileEntity = createEntity(index);
- // Добавляем новый примитив в базу
- Adesk::Boolean rVal = post_to_database(profileEntity, profileEntityId);
- // Создадим траекторию, по которой будет создан массив
- index = 3;
- curveEntity = createEntity(index);
- AcDbLine* path = (AcDbLine*)curveEntity;
- double param1,length;
- path->getEndParam(param1);
- path->getDistAtParam(param1,length);
- itemCount = int(length / itemsapcing);
- // добавляем примитив в базу
- rVal = post_to_database(curveEntity, CurveEntityId);
- if(rVal)
- {
- AcDbSmartObjectPointer<AcDbEntity> profileEntity1(profileEntityId,AcDb::kForRead);
- if(!eOkVerify(profileEntity1.openStatus())) return;
- AcDbSmartObjectPointer<AcDbEntity> curveEntity1(CurveEntityId,AcDb::kForRead);
- if(!eOkVerify(curveEntity1.openStatus())) return ;
- // Добавим id примитива профиля в массив id профилей
- profileEntityIdArray.append(profileEntityId);
- // Создадим объект PathArrayParameters
- AcDbAssocArrayPathParameters *pathParam =
- new AcDbAssocArrayPathParameters(itemsapcing,rowSpacing,
- levelSpacing,itemCount, rowCount,
- levelCount, rowElevation);
- // Код устанавливает траекторию массива
- AcDbEdgeRef edge(curveEntity1);
- es=pathParam->setPath(edge);
- // Выбираем метод Поделить или Измерить
- if(method==1)
- es= pathParam->setMethod(AcDbAssocArrayPathParameters::kDivide);
- else
- es= pathParam->setMethod(AcDbAssocArrayPathParameters::kMeasure);
- // Создаем массив из исходных примитивов
- es = AcDbAssocArrayActionBody::createInstance(profileEntityIdArray,
- *basePointVertex,pathParam,arrayId,actionBodyId);
- // Созданное действие будет автоматически выполнено в конце команды
- //
- // Если мы хотим узнать будет ли успешным вычисление, мы можем явно
- // выполнить вычисление и проверить его статус
- //
- bool beval= AcDbAssocManager::evaluateTopLevelNetwork(arrayId.database());
- if(pathParam != NULL)
- delete pathParam;
- }
- } // try
- catch (...)
- {
- acutPrintf( _T("Перехвачено прерывание: Acad::eUnrecoverableErrors"));
- }
- }
Создание Прямоугольного Массива:
- void createRectArray()
- {
- try
- {
- // Переменные аргументов
- int index = 1;
- double columnSpacing = 10;
- double rowSpacing = 10;
- double levelSpacing = 10;
- int columnCount = 10;
- int rowCount = 10;
- int levelCount = 1;
- double rowElevation = 1;
- double axesAngle = 90;
- double rotation = 0;
- AcGePoint3d basePoint;
- AcDbObjectId profileEntityId;
- AcDbEntity * profileEntity = NULL;
- AcDbObjectIdArray profileEntityIdArray;
- AcDbObjectId arrayId;
- AcDbObjectId actionBodyId;
- basePoint = basePoint.kOrigin;
- AcDbVertexRef basePointVertex(basePoint);
- // Создаем примитив профиля на основе индекса профиля
- profileEntity = createEntity(index);
- // Добавляем новый примитив в базу
- Adesk::Boolean rVal = post_to_database(profileEntity, profileEntityId);
- if(rVal)
- {
- // Добавляем id примитива профиля к массиву id профилей
- profileEntityIdArray.append(profileEntityId);
- // Создаем объект RectangularParameters
- AcDbAssocArrayRectangularParameters *rectParam =
- new AcDbAssocArrayRectangularParameters(columnSpacing,
- rowSpacing,levelSpacing,columnCount,rowCount,
- levelCount,rowElevation,axesAngle);
- // Создаем массив из исходных примитивов
- if(!eOkVerify(AcDbAssocArrayActionBody::createInstance(
- profileEntityIdArray,basePointVertex,rectParam,arrayId,actionBodyId))) return;
- // Созданное действие будет автоматически выполнено в конце команды
- //
- // Если мы хотим узнать будет ли успешным вычисление, мы можем явно
- // выполнить вычисление и проверить его статус
- //
- bool beval = AcDbAssocManager::evaluateTopLevelNetwork(arrayId.database());
- }
- } // try
- catch (...)
- {
- acutPrintf( _T("Перехвачено прерывание: Acad::eUnrecoverableErrors"));
- } // catch
- }
Создание Кругового Массива :
- void createPolarArray()
- {
- Acad::ErrorStatus es;
- try
- {
- // Переменные аргументы
- int NoOfSrcEntities = 2;
- int index = 1;
- double columnSpacing = 0;
- double rowSpacing = 10;
- double levelSpacing = 5;
- int itemCount = 6;
- int rowCount = 2;
- int levelCount = 2;
- double rowElevation = 3;
- double Angle = 90;
- AcGePoint3d basePoint;
- basePoint = basePoint.kOrigin;
- AcDbObjectId profileEntity1Id;
- AcDbObjectId profileEntity2Id;
- AcDbEntity * profileEntity1 = NULL;
- AcDbEntity * profileEntity2 = NULL;
- AcDbObjectIdArray profileEntityIdArray;
- AcDbObjectId arrayId;
- AcDbObjectId actionBodyId;
- AcDbVertexRef *basePointVertex = new AcDbVertexRef(basePoint);
- // Создаем примитив профиля на основе индекса
- profileEntity1 = createEntity(index);
- // Добавляем примитив в базу
- Adesk::Boolean rval = post_to_database(profileEntity1, profileEntity1Id);
- if(rval)
- {
- // Добавляем id примитива профиля в массив id примитивов профилей
- profileEntityIdArray.append(profileEntity1Id);
- // Создаем AssocArrayParameters
- AcDbAssocArrayPolarParameters *polarParam =
- new AcDbAssocArrayPolarParameters (Angle,rowSpacing,levelSpacing,
- itemCount,rowCount,levelCount,rowElevation);
- // Создаем массив из исходных примитивов
- es = AcDbAssocArrayActionBody::createInstance(
- profileEntityIdArray,*basePointVertex,polarParam,arrayId,actionBodyId
- );
- // Созданное действие будет автоматически выполнено в конце команды
- //
- // Если мы хотим узнать будет ли успешным вычисление, мы можем явно
- // выполнить вычисление и проверить его статус
- //
- bool beval = AcDbAssocManager::evaluateTopLevelNetwork(arrayId.database());
- }
- }
- catch(...)
- {
- acutPrintf( _T("Отловлено прерывание: Acad::eUnrecoverableErrors"));
- }
- }
Утилиты и команда:
- #include "eoktest.h"
- #include "dbobjptr2.h"
- #include "AcDbAssocArrayPathParameters.h"
- #include "AcDbAssocArrayActionBody.h"
- #include "AcDbAssocManager.h"
- #include "AcDbAssocArrayRectangularParameters.h"
- #include "AcDbAssocArrayPolarParameters.h"
- /* Вспомогательный метод для создания примитива */
- AcDbEntity* createEntity(int index)
- {
- AcDbEntity* entity = NULL;
- AcGePoint3d startPt(0,0,0);
- AcGePoint3d endPt(20,20,0);
- switch(index)
- {
- /* Профиль 1 */
- case 1:
- {
- AcDbCircle* c = new AcDbCircle(AcGePoint3d(0.0,0.0,0.0),AcGeVector3d(0.0,0.0,1.0),0.5);
- entity = (AcDbEntity*)c;
- break;
- }
- /* Профиль 2 */
- case 2:
- {
- AcDbPolyline *pRect = new AcDbPolyline();
- AcGePoint2d vertex1(startPt.x,startPt.y);
- AcGePoint2d vertex2(endPt.x,startPt.y);
- AcGePoint2d vertex3(endPt.x,endPt.y);
- AcGePoint2d vertex4(startPt.x,endPt.y);
- pRect->addVertexAt(0,vertex1);
- pRect->addVertexAt(1,vertex2);
- pRect->addVertexAt(2,vertex3);
- pRect->addVertexAt(3,vertex4);
- pRect->setClosed(Adesk::kTrue);
- entity = (AcDbEntity*)pRect;
- break;
- }
- /* Путь для МАССИВА по траектории */
- case 3:
- {
- AcDbLine *line = new AcDbLine(startPt,endPt);
- entity = (AcDbEntity*)line;
- break;
- }
- default:
- break;
- }
- return entity;
- }
- /* Вспомогательный метод для добавления примитива в базу */
- bool post_to_database(AcDbEntity* ent, AcDbObjectId& objId)
- {
- AcDbBlockTablePointer pBlockTable(acdbCurDwg(), AcDb::kForRead);
- if (!eOkVerify(pBlockTable.openStatus())) return false;
- AcDbObjectId idModelSpace;
- if (!eOkVerify(pBlockTable->getAt(ACDB_MODEL_SPACE, idModelSpace)))
- return false;
- AcDbBlockTableRecordPointer pSpaceRecord(idModelSpace, AcDb::kForWrite);
- if (!eOkVerify(pSpaceRecord.openStatus())) return false;
- if (!eOkVerify(pSpaceRecord->appendAcDbEntity(objId, ent))) {
- return false;
- }
- return eOkVerify(ent->close());
- }
- void createArray()
- {
- CString prompt = _T("Укажите тип массива: ");
- acedInitGet(0, _T("Траектория Прямоугольный Круговой"));
- ACHAR kword[255]; ACHAR pr[255];
- wsprintf(pr, ACRX_T("%s[Траектория/Прямоугольный/Круговой]: "), prompt);
- if(acedGetKword(pr, kword) == RTNORM)
- {
- if(!_tcscmp(kword,L"Траектория"))
- {
- acutPrintf(_T("Траектория\n"));
- createPathArray();
- }
- else if(!_tcscmp(kword,L"Прямоугольный"))
- {
- acutPrintf(_T("Прямоугольный\n"));
- createRectArray();
- }
- else if(!_tcscmp(kword,L"Круговой"))
- {
- acutPrintf(_T("Круговой\n"));
- createPolarArray();
- }
- else
- {
- acutPrintf(_T("Ошибочный ввод"));
- }
- }
- }
- //******************************************************************************
- extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void *pkt)
- //******************************************************************************
- {
- switch(msg)
- {
- case AcRx::kInitAppMsg:
- acrxDynamicLinker->unlockApplication(pkt);
- acrxDynamicLinker->registerAppMDIAware(pkt);
- acedRegCmds->addCommand(_T("TestCmd"),_T("ARY"),_T("ARY"), ACRX_CMD_TRANSPARENT, createArray);
- break;
- case AcRx::kUnloadAppMsg:
- acedRegCmds->removeGroup(_T("TestCmd"));
- break;
- default:
- break;
- }
- return AcRx::kRetOK;
- }
- #if !defined(_WIN64) && !defined (_AC64)
- #pragma comment(linker, "/export:_acrxGetApiVersion,PRIVATE")
- #pragma comment(linker, "/export:_acrxEntryPoint,PRIVATE")
- #else
- #pragma comment(linker, "/export:acrxGetApiVersion,PRIVATE")
- #pragma comment(linker, "/export:acrxEntryPoint,PRIVATE")
- #endif
Видео создания ассоциативных массивов:
Источник: http://adndevblog.typepad.com/autocad/2016/05/creating-assoc-array-objects-with-objectarx.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=7355
Опубликовано 26.09.2016Отредактировано 26.09.2016 в 23:05:24