}
// Start another transaction (three again). This time,
// slice the solid along a plane that is perpendicular
// to the plane we used last time: that is the slice
// we really wanted.
//
pTrans = actrTransactionManager->startTransaction();
assert(pTrans!= NULL);
acutPrintf("\n\n##### Started transaction three."
" ######\n");
moveBy. set(normal[0] * 3.0, normal[1] * 3.0,
normal[2] * 3.0);
normal = vec;
normal. normalize();
sectionPlane. set(center, normal);
pOtherHalf = NULL;
pExtrusion->getSlice(sectionPlane, Adesk::kTrue,
pOtherHalf);
assert(pOtherHalf!= NULL);
mat. setCoordSystem(moveBy, x, y, z);
pOtherHalf->transformBy(mat);
addToDb(pOtherHalf, otherHalfId);
actrTransactionManager
->addNewlyCreatedDBRObject(pOtherHalf);
pOtherHalf->draw();
pExtrusion->draw();
acutPrintf("\nSliced the resulting solid into half"
" along a plane");
acutPrintf("\nperpendicular to the old one and moved"
" one piece.");
// Now, give the user the option to end all the transactions.
//
yes = Adesk::kFalse;
if (getYOrN("\nAbort transaction three? <No> : ",
Adesk::kFalse, yes, interrupted) == Acad::eOk
&& yes == Adesk::kTrue)
{
acutPrintf("\n\n$$$$$$ Aborting transaction"
" three. $$$$$$\n");
actrTransactionManager->abortTransaction();
acutPrintf("\nBack to the un-sliced solid.");
} else {
acutPrintf("\n\n>>>>>> Ending transaction three."
" <<<<<<\n");
actrTransactionManager->endTransaction();
}
yes = Adesk::kFalse;
if (getYOrN("\nAbort transaction two? <No> : ",
Adesk::kFalse, yes, interrupted) == Acad::eOk
&& yes == Adesk::kTrue)
{
acutPrintf("\n\n$$$$$$ Aborting transaction two."
" $$$$$$\n");
actrTransactionManager->abortTransaction();
acutPrintf("\nBack to separate extrusion and"
" cylinder.");
} else {
acutPrintf("\n\n>>>>>> Ending transaction two."
" <<<<<<\n");
actrTransactionManager->endTransaction();
}
yes = Adesk::kFalse;
if (getYOrN("\nAbort transaction one? <No> : ",
Adesk::kFalse, yes, interrupted) == Acad::eOk
&& yes == Adesk::kTrue)
{
acutPrintf("\n\n$$$$$$ Aborting transaction one."
" $$$$$$\n");
actrTransactionManager->abortTransaction();
acutPrintf("\nBack to just the Poly.");
} else {
actrTransactionManager->endTransaction();
acutPrintf("\n\n>>>>>> Ending transaction one."
" <<<<<<\n");
}
}
static Acad::ErrorStatus
createAndPostPoly()
{
int nSides = 0;
while (nSides < 3) {
acedInitGet(INP_NNEG, "");
switch (acedGetInt("\nEnter number of sides: ", &nSides))
{
case RTNORM:
if (nSides < 3)
acutPrintf("\nNeed at least 3 sides.");
break;
default:
return Acad::eInvalidInput;
}
}
ads_point center, startPt, normal;
if (acedGetPoint(NULL, "\nLocate center of polygon: ", center) != RTNORM)
{
return Acad::eInvalidInput;
}
startPt[0] = center[0];
startPt[1] = center[1];
startPt[2] = center[2];
while (asPnt3d(startPt) == asPnt3d(center)) {
switch (acedGetPoint(center, "\nLocate start point of polygon: ", startPt)) {
case RTNORM:
if (asPnt3d(center) == asPnt3d(startPt))
acutPrintf("\nPick a point different"
" from the center.");
break;
default:
return Acad::eInvalidInput;
}
}
// Set the normal to the plane of the polygon to be
// the same as the Z direction of the current UCS,
// (0, 0, 1) since we also got the center and
// start point in the current UCS. (acedGetPoint()
// returns in the current UCS.)
normal[X] = 0.0;
normal[Y] = 0.0;
normal[Z] = 1.0;
acdbUcs2Wcs(normal, normal, Adesk::kTrue);
acdbUcs2Ecs(center, center, normal, Adesk::kFalse);
acdbUcs2Ecs(startPt, startPt, normal, Adesk::kFalse);
double elev = center[2];
AcGePoint2d cen = asPnt2d(center),
start = asPnt2d(startPt);
AcGeVector3d norm = asVec3d(normal);
AsdkPoly *pPoly = new AsdkPoly;
if (pPoly==NULL)
return Acad::eOutOfMemory;
Acad::ErrorStatus es;
if ((es=pPoly->set(cen, start, nSides, norm, "transactPoly",elev))!=Acad::eOk)
return es;
pPoly->setDatabaseDefaults( acdbHostApplicationServices()->workingDatabase());
postToDb(pPoly);
return Acad::eOk;
}
// Extrudes the poly to a given height.
//
static Acad::ErrorStatus
extrudePoly(AsdkPoly* pPoly, double height, AcDbObjectId& savedExtrusionId)
{
Acad::ErrorStatus es = Acad::eOk;
// Explode to a set of lines.
//
AcDbVoidPtrArray lines;
pPoly->explode(lines);
// Create a region from the set of lines.
//
AcDbVoidPtrArray regions;
AcDbRegion::createFromCurves(lines, regions);
assert(regions. length() == 1);
AcDbRegion *pRegion
= AcDbRegion::cast((AcRxObject*)regions[0]);
assert(pRegion!= NULL);
// Extrude the region to create a solid.
//
AcDb3dSolid *pSolid = new AcDb3dSolid;
assert(pSolid!= NULL);
pSolid->extrude(pRegion, height, 0.0);
for (int i = 0; i < lines. length(); i++) {
delete (AcRxObject*)lines[i];
}
for (i = 0; i < regions. length(); i++) {
delete (AcRxObject*)regions[i];
}
// Now we have a solid. Add it to database, then
// associate the solid with a transaction. After
// this, transaction management is in charge of
// maintaining it.
//
pSolid->setPropertiesFrom(pPoly);
addToDb(pSolid, savedExtrusionId);
actrTransactionManager->addNewlyCreatedDBRObject(pSolid);
pSolid->draw();
return Acad::eOk;
}
static Acad::ErrorStatus
getASolid(char* prompt,
AcTransaction* pTransaction,
AcDb::OpenMode mode,
AcDbObjectId checkWithThisId,
AcDb3dSolid*& pSolid)
{
AcDbObject *pObj = NULL;
AcDbObjectId objId;
ads_name ename;
ads_point pickpt;
for (;;) {
switch (acedEntSel(prompt, ename, pickpt)) {
case RTNORM:
AOK(acdbGetObjectId(objId, ename));
if (objId!= checkWithThisId) {
acutPrintf("\n Select the proper"
" solid.");
continue;
}
AOK(pTransaction->getObject(pObj, objId, mode));
assert(pObj!= NULL);
pSolid = AcDb3dSolid::cast(pObj);
if (pSolid == NULL) {
acutPrintf("\nNot a solid. Try again");
AOK(pObj->close());
continue;
}
break;
case RTNONE:
case RTCAN:
return Acad::eInvalidInput;
default:
continue;
}
break;
}
return Acad::eOk;
}
Глава18. Глубокое клонироване
Эта глава описывает глубокие функции аналога, которые копируют объект или любые объекты, принадлежащие скопированному объекту. Это охватывает оба основных случая использования AcDbDatabase::deepCloneObjects() функции, как более продвинутая тема перегрузки deepClone () и wblockClone() функции AcDbObject класса. Редактор функции уведомления реактора, связанные с глубоким аналогом, wblock аналог, и вставка операции также обсуждены.
- Основы глубокого клонирования Реализация deepClone() для Классов пользователя
Основы глубокого клонирования
Глубокие функции клона копируют объект и его ссылки монопольного использования. Любые ссылки указателя игнорируются. Копируют функции клона wblock жесткие владельцы и жесткие указатели и игнорируют мягкие ссылки. В дополнение к копированию этой иерархии находящихся в собственности объектов, и глубокие функции клона и функции клона wblock также обрабатывают ссылки клонированного объекта, трансляция ссылок, чтобы указать на новые объекты в случае необходимости.
Чтобы инициализировать операцию имитации, используйте одну из следующих функций:
AcDbDatabase:: deepCloneObjects ()
AcDbDatabase:: wblock ()
AcDbDatabase:: insert()
AcDbDatabase:: deepCloneObjects () только поддерживает клонирование в пределах единственной{*отдельной*} базы данных. Если Вы должны клонировать объекты между базами данных, использовать или wblock (), вставьте (), или комбинация, и (типа wblock () к временной базе данных, и затем вставьте () что базу данных в существующую базу данных адресата).
При использовании AcDbDatabase:: вставка (), только вставляют к базам данных адресата, которые уже были сформированы. Вы можете получить полностью сформированный (и возможно полностью заполняемый) базу данных адресата, используя текущий рисунок, чтобы формировать новую базу данных с параметром конструктора Adesk:: kTrue или, создавая пустую новую базу данных, используя параметр конструктора Adesk:: kFalse и затем вызывая AcDbDatabase:: readDwgFile () на этом, чтобы заполнить это.
Вообще, чтобы использовать AcDbDatabase:: deepCloneObjects (), AcDbDatabase:: wblock (), или AcDbDatabase:: вставка () функции в вашем коде, Вы не должны знать того, как карта объекта ID заполнена или точно, что случается в течение каждой стадии глубокого клонирования. Если Вы создаете новый класс, и Вы хотите перегрузить AcDbObject:: deepClone () или AcDbObject:: wblockClone () функции, вы будете должны быть знакомыми с подробностями тех функций, которые описаны в “ Реализация deepClone () для Классов пользователя ” на странице 476.
AcDbObject:: deepClone () и AcDbObject:: wblockClone () функции не должен быть вызван{*назван*} непосредственно на заказном объекте в прикладном коде. Они только вызваны как часть цепочки от операции клонирования более высокого уровня.
Использование clone() против deepClone()
AcRxObject::clone() функция клонирует единственный объект. AcDbObject:: deepClone() функция клонирует объект и любые объекты, принадлежащие тому объекту. DeepClone() функция также транслирует ссылки клонированного объекта.
Вообще, deepClone () функция более безопасный из двух функций. Если Вы клонируете простой объект типа эллипса, две функции могут быть эквивалентны. Но если Вы клонируете сложный объект типа ломаной линии, клон () функция не адекватна, потому что это клонирует только объект ломаной линии.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |


