Транзакции и генерирование графики
Вы можете нас e AcTransactionManager::queueForGraphicsFlush () и AcTransactionManager:: flushGraphics () чтобы рисовать примитивы по требованию, даже если они связаны с транзакциями, и некоторые транзакции активны, который подразумевал бы, что модификация на примитивах не совершена{*передана*} базе данных. AcTransactionManager::queueForGraphicsFlush () стоит в очереди, все приемлемые примитивы, связанные со всеми транзакциями для графической модификации и AcTransactionManager:: flushGraphics () рисуют их. Вы можете также использовать AcDbEntity::draw() чтобы рисовать индивидуальный примитив. Это помогает Вам видеть частность
Примитив на экране без того, чтобы ожидать до конца наиболее удаленной транзакции, когда все модификации к всем примитивам рис. Использование AcTransactionManager::enableGraphicsFlush () чтобы позволять или отключить рисунок примитивов. Когда команда концы, Вы оставляете контроль относительно графического генерирования, и это автоматически позволяется.
Реакторы Транзакции
Операционный менеджер имеет список реакторов, через которые это уведомляет клиентов относительно событий, уместных операционной модели. В настоящее время, имеются четыре события, которые посылают уведомление:
virtual void
transactionStarted( int& numTransactions);
virtual void
transactionEnded( int& numTransactions);
virtual void
transactionAborted( int& numTransactions);
virtual void
endCalledOnOutermostTransaction( int& numTransactions);
Первые три уведомления обстреляны, когда любая транзакция, включая вложенные, начата, закончена, или прервана. Вы можете использовать эти уведомления в конъюнкции с
AcTransactionManager::numActiveTransactions () чтобы определить транзакцию, которая является уместной уведомлению. Например, если запрос к AcTransactionManager::numActiveTransactions () возвращает нуль в
Ваша перегрузка AcTransactionReactor:: transactionEnded () или AcTransactionReactor:: transactionAborted (), Вы знаете, что наиболее удаленная транзакция заканчивается или прерывание выполнения.
EndCalledOnOutermostTransaction () уведомление сообщает о начале передающегося{*совершающегося*} процесса всех модификаций, сделанных во всех транзакциях. Вы можете использовать этот повторный вызов, чтобы делать любую необходимую работу уборки прежде, чем передают{*совершают*}, начинает.
Параметр во всех уведомлениях представляет число транзакций, которые являются активными плюс те, которые закончили успешно. Это не включает транзакции, которые были начаты и прерваны.
Пример вложенных транзакций
Следующий пример включает три вложенных транзакции. Последовательность событий следует.
Создавать вложенные транзакции
1 Создают многоугольник и переносят это к базе данных.
2 Транзакция Начала 1:
- Выбирают многоугольник и получают указатель на это. Откройте это для чтения. Создают вытесненное твердое использование многоугольник. Создают цилиндр в середине расширенного{*продленного*} многоугольника.
3 Транзакция Начала 2: Вычтите цилиндр от вытеснения (создает отверстие в середине твердых).
4 Транзакция Начала 3:
- Сектор форма в половине по X/Z плану и перемещению это по X оси, так что Вы можете рассматривать эти две части. Прерывают транзакцию? Ответ да.
5 Транзакции Начала 3 (снова): Сектор форма в половине по Y/Z плану и перемещению это по Y.
6 Конечных Транзакции 3.
7 Конечных Транзакции 2.
ОБРАТИТЕ ВНИМАНИЕ, прерываетесь ли Вы в этой точке, транзакции 2 и 3 оба отменены. Если Вы прерываете содержащую транзакцию, все вложенные транзакции прерваны, даже если они были успешно закончены.
8 Конечных Транзакции 1.
Следующее - код для этого примера:
void
transactCommand()
{
Adesk::Boolean interrupted;
Acad::ErrorStatus es = Acad::eOk;
AcDbObjectId savedCylinderId, savedExtrusionId;
// Create a poly and post it to the database.
//
acutPrintf("\nCreating a poly...Please supply the"
" required input.");
if ((es = createAndPostPoly()) != Acad::eOk)
return;
// Start a transaction.
//
AcTransaction *pTrans = actrTransactionManager->startTransaction();
assert(pTrans!= NULL);
acutPrintf("\n\n###### Started transaction one." " ######\n");
// Select the poly and extrude it.
//
AcDbObject *pObj = NULL;
AsdkPoly *pPoly = NULL;
AcDb3dSolid *pSolid = NULL;
AcDbObjectId objId;
ads_name ename;
ads_point pickpt;
for (;;) {
switch (acedEntSel("\nSelect a polygon: ", ename, pickpt))
{
case RTNORM:
acdbGetObjectId(objId, ename);
if ((es = pTrans->getObject(pObj, objId, AcDb::kForRead)) != Acad::eOk)
{
acutPrintf("\nFailed to obtain an object"
" through transaction.");
actrTransactionManager->abortTransaction();
return;
}
assert(pObj!= NULL);
pPoly = AsdkPoly::cast(pObj);
if (pPoly == NULL) {
acutPrintf("\nNot a polygon. Try again");
continue;
}
break;
case RTNONE:
case RTCAN:
actrTransactionManager->abortTransaction();
return;
default:
continue;
}
break;
}
// Now that a poly is created, convert it to a region
// and extrude it.
//
acutPrintf("\nWe will be extruding the poly.");
AcGePoint2d c2d = pPoly->center();
ads_point pt;
pt[0] = c2d[0]; pt[1] = c2d[1]; pt[2] = pPoly->elevation();
acdbEcs2Ucs(pt, pt, asDblArray(pPoly->normal()),Adesk::kFalse);
double height;
if (acedGetDist(pt, "\nEnter Extrusion height: ", &height) != RTNORM)
{
actrTransactionManager->abortTransaction();
return;
}
if ((es = extrudePoly(pPoly, height, savedExtrusionId)) != Acad::eOk) {
actrTransactionManager->abortTransaction();
return;
}
// Create a cylinder at the center of the polygon of
// the same height as the extruded poly.
//
double radius = (pPoly->startPoint() - pPoly->center()).length() * 0.5;
pSolid = new AcDb3dSolid;
assert(pSolid!= NULL);
pSolid->createFrustum(height, radius, radius, radius);
AcGeMatrix3d mat(AcGeMatrix3d::translation(
pPoly->elevation()*pPoly->normal())*
AcGeMatrix3d::planeToWorld(pPoly->normal()));
pSolid->transformBy(mat);
// Move it up again by half the height along
// the normal.
//
AcGeVector3d x(1, 0, 0), y(0, 1, 0), z(0, 0, 1);
AcGePoint3d moveBy(pPoly->normal()[0] * height * 0.5,
pPoly->normal()[1] * height * 0.5,
pPoly->normal()[2] * height * 0.5);
mat. setCoordSystem(moveBy, x, y, z);
pSolid->transformBy(mat);
addToDb(pSolid, savedCylinderId);
actrTransactionManager->addNewlyCreatedDBRObject(pSolid);
pSolid->draw();
acutPrintf("\nCreated a cylinder at the center of"
" the poly.");
// Start another transaction. Ask the user to select
// the extruded solid followed by selecting the
// cylinder. Make a hole in the extruded solid by
// subtracting the cylinder from it.
//
pTrans = actrTransactionManager->startTransaction();
assert(pTrans!= NULL);
acutPrintf("\n\n###### Started transaction two." " ######\n");
AcDb3dSolid *pExtrusion, *pCylinder;
if ((es = getASolid("\nSelect the extrusion: ", pTrans,
AcDb::kForWrite, savedExtrusionId, pExtrusion))
!= Acad::eOk)
{
actrTransactionManager->abortTransaction();
actrTransactionManager->abortTransaction();
return;
}
assert(pExtrusion!= NULL);
if ((es = getASolid("\nSelect the cylinder: ", pTrans,
AcDb::kForWrite, savedCylinderId, pCylinder))
!= Acad::eOk)
{
actrTransactionManager->abortTransaction();
actrTransactionManager->abortTransaction();
return;
}
assert(pCylinder!= NULL);
pExtrusion->booleanOper(AcDb::kBoolSubtract, pCylinder);
pExtrusion->draw();
acutPrintf("\nSubtracted the cylinder from the"
" extrusion.");
// At this point, the cylinder is a NULL solid. Erase it.
//
assert(pCylinder->isNull());
pCylinder->erase();
// Start another transaction and slice the resulting
// solid into two halves.
//
pTrans = actrTransactionManager->startTransaction();
assert(pTrans!= NULL);
acutPrintf("\n\n##### Started transaction three."
" ######\n");
AcGeVector3d vec, normal;
AcGePoint3d sp, center;
pPoly->getStartPoint(sp);
pPoly->getCenter(center);
vec = sp - center;
normal = pPoly->normal().crossProduct(vec);
normal. normalize();
AcGePlane sectionPlane(center, normal);
AcDb3dSolid *pOtherHalf = NULL;
pExtrusion->getSlice(sectionPlane, Adesk::kTrue,
pOtherHalf);
assert(pOtherHalf!= NULL);
// Move the other half three times the vector length
// along the vector.
//
moveBy. set(vec[0] * 3.0, vec[1] * 3.0, vec[2] * 3.0);
mat. setCoordSystem(moveBy, x, y, z);
pOtherHalf->transformBy(mat);
AcDbObjectId otherHalfId;
addToDb(pOtherHalf, otherHalfId);
actrTransactionManager->addNewlyCreatedDBRObject(pOtherHalf);
pOtherHalf->draw();
pExtrusion->draw();
acutPrintf("\nSliced the resulting solid into half"
" and moved one piece.");
// Now abort transaction three, to return to the hole in
// the extrusion.
//
Adesk::Boolean yes = Adesk::kTrue;
if (getYOrN("\nLet’s abort transaction three, yes?"
" [Y] : ", Adesk::kTrue, yes, interrupted) == Acad::eOk
&& yes == Adesk::kTrue)
{
acutPrintf("\n\n$$$$$$ Aborting transaction"
" three. $$$$$$\n");
actrTransactionManager->abortTransaction();
acutPrintf("\nBack to the un-sliced solid.");
pExtrusion->draw();
char option[256];
acedGetKword("\nHit any key to continue.", option);
} else {
acutPrintf("\n\n>>>>>> Ending transaction three."
" <<<<<<\n");
actrTransactionManager->endTransaction();
|
Из за большого объема этот материал размещен на нескольких страницах:
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 |


