From f12fc0344158a2931e0429c488a92a66900bb681 Mon Sep 17 00:00:00 2001 From: ChenX Date: Thu, 5 Sep 2024 07:28:25 +0000 Subject: [PATCH] =?UTF-8?q?!3069=20=E4=BF=AE=E5=A4=8D:=E9=95=9C=E5=83=8F?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E5=90=8E=E6=9D=90=E8=B4=A8=E5=9B=BE=E5=B1=82?= =?UTF-8?q?=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Database/DeepCloneObjects.test.ts | 48 +++++++++++++++++++ src/DatabaseServices/Database.ts | 38 ++++++++++++--- .../Entity/CompositeEntity.ts | 16 +++++++ 3 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 __test__/Database/DeepCloneObjects.test.ts diff --git a/__test__/Database/DeepCloneObjects.test.ts b/__test__/Database/DeepCloneObjects.test.ts new file mode 100644 index 000000000..2430c5140 --- /dev/null +++ b/__test__/Database/DeepCloneObjects.test.ts @@ -0,0 +1,48 @@ +import { Board } from "../../src/DatabaseServices/Entity/Board"; +import { LayerTableRecord } from "../../src/DatabaseServices/LayerTableRecord"; +import { PhysicalMaterialRecord } from "../../src/DatabaseServices/PhysicalMaterialRecord"; + +// 需要放在最后面,否则会循环依赖 +import { Database } from "../../src/DatabaseServices/Database"; + +describe('DeepCloneObjects', () => +{ + const db = new Database(true, true, true); + const br = new Board; + db.ModelSpace.Append(br); + + test('DeepCloneObjects的新实体和原实体图层需相同', () => + { + expect(br.Layer === db.DefaultLayer.Id).toBeTruthy(); // 图层等于默认图层 + const newLayer = new LayerTableRecord(); + newLayer.Name = "新图层1"; + db.LayerTable.Add(newLayer); + br.Layer = newLayer.Id; + + const brs = db.DeepCloneObjects([br], db.ModelSpace) as Board[]; + const newBr = brs[0]; + expect(newBr.Layer === br.Layer).toBeTruthy(); + expect(newBr.Layer === db.DefaultLayer.Id).toBeFalsy(); + + //默认图层被镜像后 应该还在默认图层 + db.LayerTable.Current = newLayer.Id; + br.Layer = db.DefaultLayer.Id; + + let brs2 = db.DeepCloneObjects([br], db.ModelSpace) as Board[]; + expect(brs2[0].Layer === br.Layer).toBeTruthy(); + }); + + test('DeepCloneObjects的新实体和原实体材质需相同', () => + { + expect(br.Material === db.MaterialTable.CurBoardMtl).toBeTruthy(); // 材质等于默认材质 + const newMtl = new PhysicalMaterialRecord(); + newMtl.Name = "新材质1"; + db.MaterialTable.Add(newMtl); + br.Material = newMtl.Id; + + const brs = db.DeepCloneObjects([br], db.ModelSpace) as Board[]; + const newBr = brs[0]; + expect(newBr.Material === br.Material).toBeTruthy(); + expect(newBr.Material === db.MaterialTable.CurBoardMtl).toBeFalsy(); + }); +}); diff --git a/src/DatabaseServices/Database.ts b/src/DatabaseServices/Database.ts index 802309da7..ee87ccd13 100644 --- a/src/DatabaseServices/Database.ts +++ b/src/DatabaseServices/Database.ts @@ -381,10 +381,12 @@ export class Database //#region Clone /** + * 注意:跨图纸拷贝(WblockCloneObjects) 同图纸拷贝(DeppCloneObjects) + * * 单个数据库内克隆对象(objects),并将他们附加到指定的容器对象(owner). * @param objects 被克隆的对象 * @param owner 克隆对象的容器 - * @param idMap id映射 + * @param idMap id映射 oldid->newid * @param deferXlation 指示是否应该进行ID转换 * @returns 新克隆的对象列表 */ @@ -445,11 +447,11 @@ export class Database } } - DeepCloneObject( + private DeepCloneObject( filer: DeepCloneFiler, object: CADObject, owner: OwnerContainer, - idMap: IdMaping = new Map(), + idMap: IdMaping = new Map(),//oldid -> newid ): CADObject | undefined { if (idMap.has(object.Id)) @@ -465,10 +467,22 @@ export class Database if (!(newObject instanceof Light) && newObject instanceof Entity)//Light类的对象不能拷贝绘制 否则出错 newObject.CloneDrawObject(object as Entity); this.AllocationObjectId(newObject); - owner.Add(newObject, false); idMap.set(object.Id, newObject.Id); - //拷贝硬绑定对象 + for (let [index, id] of filer.idMaping) + { + if (!id.Object && index < 100) + { + let oldId = this.GetObjectId(index, false); + if (oldId) + { + id.Index = index; + id.Object = oldId.Object; + } + } + } + + //拷贝硬绑定对象(提前拷贝) while (filer.hardObjectIds.size > 0) { let hardObjectIds = filer.hardObjectIds; @@ -482,16 +496,28 @@ export class Database if (!object.Owner) console.error("无主?"); if (object.Owner.Object instanceof SymbolTable) + { + // idMap.set(objectId, newId); //无用 因为每次都会进这里 //当我们拷贝样式(图层,材质,标注样式,文字样式(这种以Name-Value对应的记录)时,由于名称不能重复,所以拷贝会失败,这时我们把它转换为软引用,我们就可以避免拷贝,并且保持引用正常) - filer.idMaping.get(idIndex)._RelevancyType = RelevancyType.Soft; + //newId._RelevancyType = RelevancyType.Soft;//这句已经没用了 + + let newId = filer.idMaping.get(idIndex); + newId.Index = objectId.Index; + newId.Object = objectId.Object; + } else this.DeepCloneObject(filer, object, object.Owner.Object as unknown as OwnerContainer, idMap);//指向新对象 } } + + owner.Add(newObject, false); + return newObject; } /** + * 注意:跨图纸拷贝(WblockCloneObjects) 同图纸拷贝(DeppCloneObjects) + * * 将来自不同数据库的对象列表拷贝到本数据库中. * 当前支持使用HardId模式来硬关联某个对象,使该对象能够在WblockClone时一起被带过来. * 当前不支持硬关联对象的Owner不是默认的容器. diff --git a/src/DatabaseServices/Entity/CompositeEntity.ts b/src/DatabaseServices/Entity/CompositeEntity.ts index 7808f37ad..3c01fe603 100644 --- a/src/DatabaseServices/Entity/CompositeEntity.ts +++ b/src/DatabaseServices/Entity/CompositeEntity.ts @@ -9,6 +9,7 @@ import { RenderType } from "../../GraphicsSystem/RenderType"; import { AutoRecord } from "../AutoRecord"; import { Factory } from "../CADFactory"; import { CADFiler } from "../CADFiler"; +import { LayerTableRecord } from "../LayerTableRecord"; import { ObjectId } from "../ObjectId"; import { PhysicalMaterialRecord } from "../PhysicalMaterialRecord"; import { DragPointType } from "./DragPointType"; @@ -173,6 +174,21 @@ export abstract class CompositeEntity extends Entity } } + get Layer(): ObjectId + { + return super.Layer; + } + + set Layer(id: ObjectId) + { + super.Layer = id; + for (let e of this.Entitys) + { + if (!e.Db) e.SetDatabase(this.Db); + e.Layer = id; + } + } + SetAllMaterialAtSlot(mtl: ObjectId) { if (this.LockMaterial)