//-----------------------------------------------------------------------------
//----- acrxEntryPoint.cpp
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "resource.h"
//-----------------------------------------------------------------------------
#define szRDS _RXST("")
void ads_regen();
//-----------------------------------------------------------------------------
//----- ObjectARX EntryPoint
class CCreateBlockApp : public AcRxArxApp {
public:
CCreateBlockApp() : AcRxArxApp() {}
virtual AcRx::AppRetCode On_kInitAppMsg(void *pkt) {
AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg(pkt);
return (retCode);
}
virtual AcRx::AppRetCode On_kUnloadAppMsg(void *pkt) {
AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg(pkt);
return (retCode);
}
virtual void RegisterServerComponents() { }
//////////////////////////////////////////////////////////////////////////
// Вариант с AcDbBlockTableRecord::assumeOwnershipOf
//////////////////////////////////////////////////////////////////////////
static void RivilisCreateBlk1()
{
AcDbObjectIdArray ids;
AcString blockName = GetBlockName();
if (blockName.isEmpty())
return;
if (SelectObjects(ids) == 0)
return;
AcDbObjectId idBtr = GetOrCreateBlockDef(blockName);
if (idBtr.isNull())
return;
{
AcDbBlockTableRecordPointer pBtr(idBtr, AcDb::kForWrite);
pBtr->assumeOwnershipOf(ids); // <- Меняем владельца примитивов
}
InsertBlockRef(idBtr);
ads_regen();
}
//////////////////////////////////////////////////////////////////////////
// Вариант с AcDbDatabase::deepCloneObjects
//////////////////////////////////////////////////////////////////////////
static void RivilisCreateBlk2()
{
AcDbObjectIdArray ids;
AcString blockName = GetBlockName();
if (blockName.isEmpty())
return;
if (SelectObjects(ids) == 0)
return;
AcDbObjectId idBtr = GetOrCreateBlockDef(blockName);
if (idBtr.isNull())
return;
AcDbIdMapping mapping;
// Клонируем выбранные примитивы в блок
acdbCurDwg()->deepCloneObjects(ids, idBtr, mapping);
InsertBlockRef(idBtr);
ads_regen();
}
//////////////////////////////////////////////////////////////////////////
// Вариант с AcDbEntity::clone()
//////////////////////////////////////////////////////////////////////////
static void RivilisCreateBlk3()
{
AcDbObjectIdArray ids;
AcString blockName = GetBlockName();
if (blockName.isEmpty())
return;
if (SelectObjects(ids) == 0)
return;
AcDbObjectId idBtr = GetOrCreateBlockDef(blockName);
if (idBtr.isNull())
return;
{
AcDbBlockTableRecordPointer pBtr(idBtr, AcDb::kForWrite);
if (pBtr.openStatus() == Acad::eOk)
{
for (int i = 0; i < ids.length(); i++)
{
AcDbEntityPointer pEnt(ids[i], AcDb::kForRead);
if (pEnt.openStatus() != Acad::eOk)
continue;
// Создаём клоны выбранных примитивов и добавляем их в блок
AcDbEntity *pClone = AcDbEntity::cast(pEnt->clone());
if (pClone)
{
pBtr->appendAcDbEntity(pClone);
pClone->close();
}
}
}
}
InsertBlockRef(idBtr);
ads_regen();
}
//////////////////////////////////////////////////////////////////////////
// Функция возвращает количество выбранных примитивов и заполняет
// ими массив AcDbObjectId
//////////////////////////////////////////////////////////////////////////
static Adesk::Int32 SelectObjects(AcDbObjectIdArray &ids)
{
Adesk::Int32 len = 0;
ads_name ss;
if (acedSSGet(NULL, NULL, NULL, NULL, ss) == RTNORM)
{
acedSSLength(ss, &len);
if (len > 0)
{
ids.setLogicalLength(len);
for (Adesk::Int32 i = 0; i < len; i++)
{
ads_name en; acedSSName(ss, i, en);
AcDbObjectId id; acdbGetObjectId(id, en);
ids[i] = id;
}
}
}
return len;
}
//////////////////////////////////////////////////////////////////////////
// Функция возвращает AcDbObjectId определения блока, заданного именем
// Если блока с таким именем еще не было, то функция его создаёт
//////////////////////////////////////////////////////////////////////////
static AcDbObjectId GetOrCreateBlockDef(AcString name)
{
AcDbBlockTablePointer pTbl(acdbCurDwg(), AcDb::kForRead);
if (pTbl.openStatus() != Acad::eOk)
return AcDbObjectId::kNull;
AcDbObjectId idBtr;
if (pTbl->getAt(name, idBtr) == Acad::eOk)
return idBtr;
if (pTbl->upgradeOpen() == Acad::eOk)
{
AcDbBlockTableRecordPointer pBtr; pBtr.create();
pBtr->setName(name);
pBtr->setExplodable(true);
pBtr->setOrigin(AcGePoint3d::kOrigin);
pTbl->add(idBtr, pBtr);
}
return idBtr;
}
//////////////////////////////////////////////////////////////////////////
// Функция создаёт вставку блока по заданному AcDbObjectId
// определения блока, запрашивая у пользователя точку вставки
//////////////////////////////////////////////////////////////////////////
static void InsertBlockRef(AcDbObjectId idBtr)
{
ads_point p;
if (acedGetPoint(NULL, ACRX_T("\nУкажите точку вставки блока: "), p) == RTNORM)
{
AcDbBlockTableRecordPointer pSpace(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
if (pSpace.openStatus() != Acad::eOk)
return;
AcDbBlockReference *pRef = new AcDbBlockReference(asPnt3d(p), idBtr);
pRef->setDatabaseDefaults(acdbCurDwg());
pSpace->appendAcDbEntity(pRef);
pRef->close();
}
}
//////////////////////////////////////////////////////////////////////////
// Запрашиваем у пользователя имя блока и возвращаем только допустимое
// имя или пустую строку
//////////////////////////////////////////////////////////////////////////
static AcString GetBlockName()
{
AcString blockName;
acedGetString(TRUE, ACRX_T("\nУкажите имя блока: "), blockName);
if (acdbSNValid(blockName, FALSE) != RTNORM)
{
acutPrintf(ACRX_T("\nБлока с таким именем быть не может"));
blockName = ACRX_T("");
}
return blockName;
}
};
//-----------------------------------------------------------------------------
IMPLEMENT_ARX_ENTRYPOINT(CCreateBlockApp)
ACED_ARXCOMMAND_ENTRY_AUTO(CCreateBlockApp, Rivilis, CreateBlk1, CreateBlk1, ACRX_CMD_MODAL, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CCreateBlockApp, Rivilis, CreateBlk2, CreateBlk2, ACRX_CMD_MODAL, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CCreateBlockApp, Rivilis, CreateBlk3, CreateBlk3, ACRX_CMD_MODAL, NULL)