From 048ce513ae2e77869a6d9af781acb03466cefb1f Mon Sep 17 00:00:00 2001 From: ChenX Date: Mon, 25 Feb 2019 16:18:48 +0800 Subject: [PATCH] =?UTF-8?q?WblockClone=E6=94=AF=E6=8C=81=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E5=92=8C=E6=8F=90=E5=89=8D=E6=8B=B7=E8=B4=9D?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 1 + .../__snapshots__/wblockClone.test.ts.snap | 30 +++++------ __test__/FileSystem/wblockClone.test.ts | 54 +++++++++++++++++++ src/DatabaseServices/CADFiler.ts | 9 ++-- src/DatabaseServices/Database.ts | 34 +++++++++--- .../PhysicalMaterialRecord.ts | 12 ++--- src/DatabaseServices/WblockCloneFiler.ts | 19 ++----- src/UI/Components/Asset.tsx | 6 +-- 8 files changed, 113 insertions(+), 52 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 3a0eecc70..2bd808c06 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -38,6 +38,7 @@ ], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", + "smartStep": false, "skipFiles": [ "${workspaceFolder}/node_modules/**/*.js" ] diff --git a/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap b/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap index 254850371..2219236b7 100644 --- a/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap +++ b/__test__/FileSystem/__snapshots__/wblockClone.test.ts.snap @@ -24,7 +24,7 @@ Array [ 1, "TextureTableRecord", 2, - 101, + 100, false, 4, 1, @@ -44,7 +44,7 @@ Array [ 1, "PhysicalMaterialRecord", 2, - 100, + 101, false, 3, 1, @@ -55,10 +55,10 @@ Array [ 0.2, 1, true, - 101, - 101, + 100, + 100, 0.1, - 101, + 100, 0.2, true, true, @@ -94,7 +94,7 @@ Array [ 2, "TextureTableRecord", 2, - 101, + 100, false, 4, 1, @@ -108,7 +108,7 @@ Array [ "CAD/images/bd/bdfb0d6740912fc3217e3f9bfa4c53fd.png", "TextureTableRecord", 2, - 103, + 102, false, 4, 1, @@ -128,7 +128,7 @@ Array [ 2, "PhysicalMaterialRecord", 2, - 100, + 101, false, 3, 1, @@ -139,10 +139,10 @@ Array [ 0.2, 1, true, - 101, - 101, + 100, + 100, 0.1, - 101, + 100, 0.2, true, true, @@ -150,7 +150,7 @@ Array [ "", "PhysicalMaterialRecord", 2, - 102, + 103, false, 3, 1, @@ -161,10 +161,10 @@ Array [ 0.2, 1, true, - 103, - 103, + 102, + 102, 0.1, - 103, + 102, 0.2, true, true, diff --git a/__test__/FileSystem/wblockClone.test.ts b/__test__/FileSystem/wblockClone.test.ts index 8987a4a41..88d00abc9 100644 --- a/__test__/FileSystem/wblockClone.test.ts +++ b/__test__/FileSystem/wblockClone.test.ts @@ -4,6 +4,8 @@ import { DuplicateRecordCloning } from '../../src/Common/Status'; import { PhysicalMaterialRecord } from '../../src/DatabaseServices/PhysicalMaterialRecord'; import { TextureTableRecord } from '../../src/DatabaseServices/Texture'; import { Factory } from '../../src/DatabaseServices/CADFactory'; +import { Entity } from '../../src/DatabaseServices/Entity'; +import { ObjectId } from '../../src/DatabaseServices/ObjectId'; new CADFiler(); @@ -36,4 +38,56 @@ test('wblockClone', () => expect(replaceDb.FileWrite().Data).toMatchSnapshot(); }); +test('循环引用', () => +{ + @Factory + //@ts-ignore + class CircleRef extends Entity + { + constructor() + { + super(); + } + ref: ObjectId; + + setRef(id: ObjectId) + { + this.ref = id; + } + + ReadFile(file: CADFiler) + { + let ver = file.Read(); + super.ReadFile(file); + + this.ref = file.ReadObjectId(); + } + WriteFile(file: CADFiler) + { + file.Write(1); + super.WriteFile(file); + file.WriteHardObjectId(this.ref); + } + } + + let db = new Database(); + + let e1 = new CircleRef(); + let e2 = new CircleRef(); + db.ModelSpace.Append(e1); + db.ModelSpace.Append(e2); + + e1.setRef(e2.Id); + e2.setRef(e1.Id); + + let empDb = new Database(); + empDb.WblockCloneObejcts([e1], empDb.ModelSpace, new Map(), DuplicateRecordCloning.Ignore); + + expect(empDb.ModelSpace.Entitys.length).toBe(2); + + let db2 = new Database(); + db2.WblockCloneObejcts([e1, e2], db2.ModelSpace, new Map(), DuplicateRecordCloning.Ignore); + expect(db2.ModelSpace.Entitys.length).toBe(2); +}); + //file.only diff --git a/src/DatabaseServices/CADFiler.ts b/src/DatabaseServices/CADFiler.ts index 395dcdf87..0ce13fe65 100644 --- a/src/DatabaseServices/CADFiler.ts +++ b/src/DatabaseServices/CADFiler.ts @@ -115,16 +115,17 @@ export class CADFiler this.Write(0); } + WriteHardObjectId(id: ObjectId) + { + return this.WriteObjectId(id); + } + ReadObjectId(): ObjectId { let index = this.Read(); if (this.database) return this.database.GetObjectId(index, true); } - ReadHardId() - { - return this.ReadObjectId(); - } ToString() { diff --git a/src/DatabaseServices/Database.ts b/src/DatabaseServices/Database.ts index 2f6544ae5..0cc941341 100644 --- a/src/DatabaseServices/Database.ts +++ b/src/DatabaseServices/Database.ts @@ -161,24 +161,32 @@ export class Database ) { let f = new WblockCloneFiler(); - for (let obj of objects) - { this.WblockCloneObject(obj, owner, idMap, drc, f); - } + } - let oldDb = objects[0].Db; + /** + * 克隆引用对象 WriteHardObjectId + */ + private WblockCloneReferenceObject(object: CADObject, f: WblockCloneFiler, idMap: Map, drc: DuplicateRecordCloning) + { + let oldData = f.Data; + f.Data = []; - for (let [n, id] of f.hardMaping) + let oldDb = object.Db; + let hardObjectIds = f.hardObjectIds; + f.hardObjectIds = new Set(); + for (let idIndex of hardObjectIds) { - let oldId = oldDb.GetObjectId(n); + let oldId = oldDb.GetObjectId(idIndex); //使用旧的OwnerId得到新的OwnerId,假设所有者都是数据库默认存在的. //TODO: 当OwnerId>100时,表示这个所有者不是数据库里面默认存在的,那么应该将Owner拷贝过来. - let newOwnerId = this.GetObjectId(oldId.Object.Owner.Index);//owner.Db === this + let newOwnerId = this.GetObjectId(oldId.Object.Owner.Index); //owner.Db === this let newOwner = newOwnerId.Object as SymbolTable; - this.WblockCloneObject(oldId.Object, newOwner, idMap, drc, f); } + + f.Data = oldData; } private WblockCloneObject( @@ -189,7 +197,14 @@ export class Database filer: WblockCloneFiler ) { + //克隆的对象有可能被其他的对象依赖并且克隆完毕了. + let cloneId = filer.idMaping.get(object.Id.Index); + if (cloneId && cloneId.Object) + return; + filer.Data.length = 0; + //表示该对象已经被拷贝了,至于成功与否,不重要(参考WblockClone.WriteHardObjectId) + filer.idMaping.set(object.Id.Index, undefined); if (owner instanceof SymbolTable) { let record = object as SymbolTableRecord; @@ -211,6 +226,7 @@ export class Database } filer.WriteObject(record); + this.WblockCloneReferenceObject(record, filer, idMap, drc); filer.Reset(); let newRecord = filer.ReadObject() as SymbolTableRecord; newRecord.Owner = undefined; @@ -227,6 +243,7 @@ export class Database filer.idMaping.set(object.Id.Index, oldRecord.Id); record.WriteFile(filer); + this.WblockCloneReferenceObject(record, filer, idMap, drc); filer.Reset(); //此时重新读取的话,将会得到原先的id,实现id不变 @@ -239,6 +256,7 @@ export class Database } filer.WriteObject(object); + this.WblockCloneReferenceObject(object, filer, idMap, drc); filer.Reset(); let newObject = filer.ReadObject() as SymbolTableRecord; owner.Add(newObject, false); diff --git a/src/DatabaseServices/PhysicalMaterialRecord.ts b/src/DatabaseServices/PhysicalMaterialRecord.ts index 63f009453..76e7182f3 100644 --- a/src/DatabaseServices/PhysicalMaterialRecord.ts +++ b/src/DatabaseServices/PhysicalMaterialRecord.ts @@ -62,10 +62,10 @@ export class PhysicalMaterialRecord extends MaterialTableRecord this.matalness = file.Read(); this.opacity = file.Read(); this.depthTest = file.Read(); - this.map = file.ReadHardId(); - this.bumpMap = file.ReadHardId(); + this.map = file.ReadObjectId(); + this.bumpMap = file.ReadObjectId(); this.bumpScale = file.Read(); - this.roughnessMap = file.ReadHardId(); + this.roughnessMap = file.ReadObjectId(); this.roughness = file.Read(); this.useMap = file.Read(); this.useBumpMap = file.Read(); @@ -83,10 +83,10 @@ export class PhysicalMaterialRecord extends MaterialTableRecord file.Write(this.matalness); file.Write(this.opacity); file.Write(this.depthTest); - file.WriteObjectId(this.map); - file.WriteObjectId(this.bumpMap); + file.WriteHardObjectId(this.map); + file.WriteHardObjectId(this.bumpMap); file.Write(this.bumpScale); - file.WriteObjectId(this.roughnessMap); + file.WriteHardObjectId(this.roughnessMap); file.Write(this.roughness); file.Write(this.useMap); file.Write(this.useBumpMap); diff --git a/src/DatabaseServices/WblockCloneFiler.ts b/src/DatabaseServices/WblockCloneFiler.ts index 4e387229a..33e3b652e 100644 --- a/src/DatabaseServices/WblockCloneFiler.ts +++ b/src/DatabaseServices/WblockCloneFiler.ts @@ -3,21 +3,12 @@ import { ObjectId } from "./ObjectId"; export class WblockCloneFiler extends DeepCloneFiler { - hardMaping = new Map(); - ReadHardId() + hardObjectIds: Set = new Set(); + WriteHardObjectId(id: ObjectId) { - let index = this.Read(); - if (index <= 0) return; + if (id && id.Index > 100 && !this.idMaping.has(id.Index)) //当存在id时,表示对象正在被拷贝,或者已经拷贝完成 + this.hardObjectIds.add(id.Index); - let id = this.idMaping.get(index); - if (id) return id; - - id = new ObjectId(); - this.idMaping.set(index, id); - - if (index > 100) - this.hardMaping.set(index, id); - - return id; + return this.WriteObjectId(id); } } diff --git a/src/UI/Components/Asset.tsx b/src/UI/Components/Asset.tsx index 3fef9b37e..e6ee64f97 100644 --- a/src/UI/Components/Asset.tsx +++ b/src/UI/Components/Asset.tsx @@ -81,11 +81,7 @@ export class Asset extends React.Component<{ material: PhysicalMaterialRecord }, async componentDidMount() { this.removeCall.push(xaop.end(this.props.material, this.props.material.Update, this.UpdateRenderPreview)); - //使用WblockClone时,材质先进来,Texture没进来,导致的显示错误. - setTimeout(() => - { - this.props.material.Update(); - }, 50); + this.UpdateRenderPreview(); } componentWillUnmount()