С deepClone () функция, Вы клонируете ломаную линию также как его вершину.
Ключевые концепции Клонирования
Эта секция описывает некоторых из ключевых терминов и концепций, используемых в течение этого обсуждения глубокого клона и клона wblock: запись в файл, монопольное использование, карта ID, и клонирование и шаги трансляции.
Клонирование и Запись в файл
Глубокий клон и операции клона wblock оба объект использования, регистрирующие, чтобы копировать (клонировать) объект. Новый объект создан, который будет клон. Затем, первоначальный объект зарегистрирован из к памяти, используя dwgOut (). Наконец, данные зарегистрированы в к новому клонированному объекту, используя dwgIn ().
Клонирование и Монопольное использование
Отношения между объектами сохранены в объекте как компонент данных AcDbObjectId класса. Имеются четыре различных типа отношений между объектами — жесткие владельцы, мягкие владельцы, жесткие указатели, и мягкие указатели. Например, если Вы создаете примитив, который требует текстового стиля, тот примитив имел бы компонент данных класса AcDbObjectId, который обратится{*отнесется*} к AcDbTextStyleTableRecord, и это было бы зарегистрировано из как жесткий указатель ID.
Путем Вы регистрируете из AcDbObjectId, решает{*определяет*}, как глубокий клон и операции клона wblock используют объект ID. Для подробной информации, см. “ Объектные Ссылки ” на странице 310. Глубоко клон следует интенсивно и мягкие подключения{*связи*} владельца, и клон wblock следует за жестким владельцем и подключениями{*связями*} указателя, как показано в следующем числе{*рисунке*}:
Hard Owner deep clone wblock clone | Hard Pointer wblock clone |
Soft Owner deep clone | Soft Pointer |
Клонирование и Карта ID
Карта ID - механизм для слежения за операцией клона. Карта состоит из пар объектных ID — ID объекта источника (упомянутый как “ ID ключ”) и ID клонированного, или адресат, объект (упомянутый как “ значение ID”). Карта ID также содержит дополнительные пары ID неклонированных объектов, которые необходимы для трансляции ID (см. “ Стадия Трансляции ” на странице 477).
Когда deepCloneObjects () - обратился к некоторым объектам, дополнительные объекты клонировались{*имитируются*} из-за их подключения{*связи*} монопольного использования с первичным набором клонированных{*имитируемых*} объектов. Вы можете смотреть на карту ID, чтобы видеть то, какие дополнительные объекты клонируются.
Клонирование и Трансляция
Глубокий клон и операции клона wblock фактически состоят из двух шагов: клонирование и трансляция. Шаг клонирования - то, где dwgOut () и dwgIn () вызваны, и объекты скопированы. Второй шаг - шаг трансляции, который использует карту ID, чтобы повторно связать все объекты, чтобы отразить новые отношения.
В течение трансляции, все четыре типа объектных ID должны быть оттранслированы. Некоторые объекты клонировались и находятся в карте ID, в то время как другие не клонировались и не в карте. В течение трансляции ID, если пара ID, соответствующая ссылке не найдена в карте ID, одна из двух вещей случается. Если ссылка находится в той же самой базе данных как объект, который является что касается этого, это оставлено один. Иначе, это установлено в NULL. См. “ Стадия Трансляции ” на странице 477.
Типичная операция глубокого клона
Следующая выборка кода показывает типичное использование AcDbDatabase:: deepCloneObjects ().
Инициализировать глубокую операцию клона
1 Получают набор объектов, которые нужно клонировать.
2 Помещенный объектные ID в список (типа AcDbObjectIdArray).
3 Создают новую карту ID (класса AcDbIdMapping) который будет заполнен deepCloneObjects () функция.
4 Называют deepCloneObjects () функцией, проходящей в списке объектов, которые нужно клонировать, объект ID владельца, к которому клонированные объекты должны быть добавлены в конец, и карта ID, созданная в шаге 1.
В этом примере, объект ID владельца - запись таблицы блоков пространства модели.
DeepCloneObjects () функция заполняет карту объекта ID (idMap). Приложение может тогда выполнять итерации через объекты, содержащиеся в карте, используя специальный iterator объект (AcDbIdMappingIter) и исполнять дополнительные операции на тех объектах, типа преобразования каждого объекта некоторой матрицей.
Следующий код показывает типичное использование deepCloneObjects ():
void
cloneSameOwnerObjects()
{
// Step 1: Obtain the set of objects to be cloned.
ads_name sset;
if (acedSSGet(NULL, NULL, NULL, NULL, sset) != RTNORM) {
acutPrintf("\nNothing selected");
return;
}
// Step 2: Add obtained object IDs to list of objects
// to be cloned.
long length;
acedSSLength(sset, &length);
AcDbObjectIdArray objList;
AcDbObjectId ownerId = AcDbObjectId::kNull;
for (int i = 0; i < length; i++) {
ads_name ent;
acedSSName(sset, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
// Check to be sure this has the same owner as the first
// object.
//
AcDbObject *pObj;
acdbOpenObject(pObj, objId, AcDb::kForRead);
if (pObj->ownerId() == ownerId)
objList. append(objId);
else if (i == 0) {
ownerId = pObj->ownerId();
objList. append(objId);
}
pObj->close();
}
acedSSFree(sset);
// Step 3: Get the object ID of the desired owner for
// the cloned objects. We’ll use model space for
// this example.
//
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);
AcDbObjectId modelSpaceId;
pBlockTable->getAt(ACDB_MODEL_SPACE, modelSpaceId);
pBlockTable->close();
// Step 4: Create a new ID map.
//
AcDbIdMapping idMap;
// Step 5: Call deepCloneObjects().
//
acdbHostApplicationServices()->workingDatabase()
->deepCloneObjects(objList, modelSpaceId, idMap);
// Now we can go through the ID map and do whatever we’d
// like to the original and/or clone objects.
//
// For this example, we’ll print out the object IDs of
// the new objects resulting from the cloning process.
//
AcDbIdMappingIter iter(idMap);
for (iter. start(); !iter. done(); iter. next()) {
AcDbIdPair idPair;
iter. getMap(idPair);
if (!idPair. isCloned())
continue;
acutPrintf("\nObjectId is: %Ld", idPair. value().asOldId());
}
}
Клонируемые Объекты от Различных Владельцев
Если Вы клонируемые набор объектов от различных владельцев, вы будете должны делить набор объектных ID в отдельные группы для каждого владельца. (Клонированные объекты и их владельцы должны принадлежать той же самой базе данных.) В примере в этой секции, объекты пространства модели, которые нужно клонировать добавлены к objListMS, и объекты пространства листа, которые нужно клонировать добавлены к objListPS:
objListMS. append(objId);
objListPS. append(objId);
DeepCloneObjects () функция тогда вызвана дважды, используя ту же самую карту ID. Необходимо делать все клонирование, используя единственную карту ID для трансляции ссылки, которая будет сделана должным образом. На первом запросе, deferXlation параметр установлен в kTrue. В секунде (последний) вызывают к deepCloneObjects (), deferXlation значения по умолчанию к kFalse:
acdbHostApplicationServices()->workingDatabase()->DeepCloneObjects (mslist, modelSpaceId, idMap, Adesk::kTrue);
acdbHostApplicationServices()->workingDatabase()->DeepCloneObjects (pslist, paperSpaceId, idMap);
В этой точке клонирование заканчивается и все ссылки оттранслированы. Следующий код глубоко клонирует объекты, принадлежащие различным владельцам:
void
cloneDiffOwnerObjects()
{
// Step 1: Obtain the set of objects to be cloned.
// For the two owners we’ll use model space and
// paper space, so we must perform two acedSSGet() calls.
// calls.
//
acutPrintf("\nSelect entities to be cloned to"
" Model Space");
ads_name ssetMS;
acedSSGet(NULL, NULL, NULL, NULL, ssetMS);
long lengthMS;
acedSSLength(ssetMS, &lengthMS);
acutPrintf("\nSelect entities to be cloned to"
" Paper Space");
ads_name ssetPS;
if (acedSSGet(NULL, NULL, NULL, NULL, ssetPS) != RTNORM && lengthMS == 0)
{
acutPrintf("\nNothing selected");
return;
}
long lengthPS;
acedSSLength(ssetPS, &lengthPS);
// Step 2: Add obtained object IDs to the lists of
// objects to be cloned: one list for objects to
// be owned by model space and one for those to
// be owned by paper space.
AcDbObjectId ownerId = AcDbObjectId::kNull;
// For model space
//
AcDbObjectIdArray objListMS;
for (int i = 0; i < lengthMS; i++) {
ads_name ent;
acedSSName(ssetMS, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
// Check to be sure this has the same owner as the first
// object.
//
AcDbObject *pObj;
acdbOpenObject(pObj, objId, AcDb::kForRead);
if (pObj->ownerId() == ownerId)
objListMS. append(objId);
else if (i == 0) {
ownerId = pObj->ownerId();
objListMS. append(objId);
}
pObj->close();
}
acedSSFree(ssetMS);
// For paper space
//
ownerId = AcDbObjectId::kNull;
AcDbObjectIdArray objListPS;
for (i = 0; i < lengthPS; i++) {
ads_name ent;
acedSSName(ssetPS, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
// Check to be sure this has the same owner as the first
// object.
//
AcDbObject *pObj;
acdbOpenObject(pObj, objId, AcDb::kForRead);
if (pObj->ownerId() == ownerId)
objListPS. append(objId);
else if (i == 0) {
ownerId = pObj->ownerId();
objListPS. append(objId);
}
pObj->close();
}
acedSSFree(ssetPS);
// Step 3: Get the object ID of the desired owners for
// the cloned objects. We’re using model space and
// paper space for this example.
//
AcDbBlockTable *pBlockTable;
|
Из за большого объема этот материал размещен на нескольких страницах:
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 |


