WblockClone支持循环引用和提前拷贝依赖对象

pull/262/MERGE
ChenX 6 years ago
parent 585cccde37
commit 048ce513ae

@ -38,6 +38,7 @@
], ],
"console": "integratedTerminal", "console": "integratedTerminal",
"internalConsoleOptions": "neverOpen", "internalConsoleOptions": "neverOpen",
"smartStep": false,
"skipFiles": [ "skipFiles": [
"${workspaceFolder}/node_modules/**/*.js" "${workspaceFolder}/node_modules/**/*.js"
] ]

@ -24,7 +24,7 @@ Array [
1, 1,
"TextureTableRecord", "TextureTableRecord",
2, 2,
101, 100,
false, false,
4, 4,
1, 1,
@ -44,7 +44,7 @@ Array [
1, 1,
"PhysicalMaterialRecord", "PhysicalMaterialRecord",
2, 2,
100, 101,
false, false,
3, 3,
1, 1,
@ -55,10 +55,10 @@ Array [
0.2, 0.2,
1, 1,
true, true,
101, 100,
101, 100,
0.1, 0.1,
101, 100,
0.2, 0.2,
true, true,
true, true,
@ -94,7 +94,7 @@ Array [
2, 2,
"TextureTableRecord", "TextureTableRecord",
2, 2,
101, 100,
false, false,
4, 4,
1, 1,
@ -108,7 +108,7 @@ Array [
"CAD/images/bd/bdfb0d6740912fc3217e3f9bfa4c53fd.png", "CAD/images/bd/bdfb0d6740912fc3217e3f9bfa4c53fd.png",
"TextureTableRecord", "TextureTableRecord",
2, 2,
103, 102,
false, false,
4, 4,
1, 1,
@ -128,7 +128,7 @@ Array [
2, 2,
"PhysicalMaterialRecord", "PhysicalMaterialRecord",
2, 2,
100, 101,
false, false,
3, 3,
1, 1,
@ -139,10 +139,10 @@ Array [
0.2, 0.2,
1, 1,
true, true,
101, 100,
101, 100,
0.1, 0.1,
101, 100,
0.2, 0.2,
true, true,
true, true,
@ -150,7 +150,7 @@ Array [
"", "",
"PhysicalMaterialRecord", "PhysicalMaterialRecord",
2, 2,
102, 103,
false, false,
3, 3,
1, 1,
@ -161,10 +161,10 @@ Array [
0.2, 0.2,
1, 1,
true, true,
103, 102,
103, 102,
0.1, 0.1,
103, 102,
0.2, 0.2,
true, true,
true, true,

@ -4,6 +4,8 @@ import { DuplicateRecordCloning } from '../../src/Common/Status';
import { PhysicalMaterialRecord } from '../../src/DatabaseServices/PhysicalMaterialRecord'; import { PhysicalMaterialRecord } from '../../src/DatabaseServices/PhysicalMaterialRecord';
import { TextureTableRecord } from '../../src/DatabaseServices/Texture'; import { TextureTableRecord } from '../../src/DatabaseServices/Texture';
import { Factory } from '../../src/DatabaseServices/CADFactory'; import { Factory } from '../../src/DatabaseServices/CADFactory';
import { Entity } from '../../src/DatabaseServices/Entity';
import { ObjectId } from '../../src/DatabaseServices/ObjectId';
new CADFiler(); new CADFiler();
@ -36,4 +38,56 @@ test('wblockClone', () =>
expect(replaceDb.FileWrite().Data).toMatchSnapshot(); 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 //file.only

@ -115,16 +115,17 @@ export class CADFiler
this.Write(0); this.Write(0);
} }
WriteHardObjectId(id: ObjectId)
{
return this.WriteObjectId(id);
}
ReadObjectId(): ObjectId ReadObjectId(): ObjectId
{ {
let index = this.Read(); let index = this.Read();
if (this.database) if (this.database)
return this.database.GetObjectId(index, true); return this.database.GetObjectId(index, true);
} }
ReadHardId()
{
return this.ReadObjectId();
}
ToString() ToString()
{ {

@ -161,24 +161,32 @@ export class Database
) )
{ {
let f = new WblockCloneFiler(); let f = new WblockCloneFiler();
for (let obj of objects) for (let obj of objects)
{
this.WblockCloneObject(obj, owner, idMap, drc, f); this.WblockCloneObject(obj, owner, idMap, drc, f);
} }
let oldDb = objects[0].Db; /**
* WriteHardObjectId
*/
private WblockCloneReferenceObject(object: CADObject, f: WblockCloneFiler, idMap: Map<ObjectId, ObjectId>, 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,假设所有者都是数据库默认存在的. //使用旧的OwnerId得到新的OwnerId,假设所有者都是数据库默认存在的.
//TODO: 当OwnerId>100时,表示这个所有者不是数据库里面默认存在的,那么应该将Owner拷贝过来. //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; let newOwner = newOwnerId.Object as SymbolTable;
this.WblockCloneObject(oldId.Object, newOwner, idMap, drc, f); this.WblockCloneObject(oldId.Object, newOwner, idMap, drc, f);
} }
f.Data = oldData;
} }
private WblockCloneObject( private WblockCloneObject(
@ -189,7 +197,14 @@ export class Database
filer: WblockCloneFiler filer: WblockCloneFiler
) )
{ {
//克隆的对象有可能被其他的对象依赖并且克隆完毕了.
let cloneId = filer.idMaping.get(object.Id.Index);
if (cloneId && cloneId.Object)
return;
filer.Data.length = 0; filer.Data.length = 0;
//表示该对象已经被拷贝了,至于成功与否,不重要(参考WblockClone.WriteHardObjectId)
filer.idMaping.set(object.Id.Index, undefined);
if (owner instanceof SymbolTable) if (owner instanceof SymbolTable)
{ {
let record = object as SymbolTableRecord; let record = object as SymbolTableRecord;
@ -211,6 +226,7 @@ export class Database
} }
filer.WriteObject(record); filer.WriteObject(record);
this.WblockCloneReferenceObject(record, filer, idMap, drc);
filer.Reset(); filer.Reset();
let newRecord = filer.ReadObject() as SymbolTableRecord; let newRecord = filer.ReadObject() as SymbolTableRecord;
newRecord.Owner = undefined; newRecord.Owner = undefined;
@ -227,6 +243,7 @@ export class Database
filer.idMaping.set(object.Id.Index, oldRecord.Id); filer.idMaping.set(object.Id.Index, oldRecord.Id);
record.WriteFile(filer); record.WriteFile(filer);
this.WblockCloneReferenceObject(record, filer, idMap, drc);
filer.Reset(); filer.Reset();
//此时重新读取的话,将会得到原先的id,实现id不变 //此时重新读取的话,将会得到原先的id,实现id不变
@ -239,6 +256,7 @@ export class Database
} }
filer.WriteObject(object); filer.WriteObject(object);
this.WblockCloneReferenceObject(object, filer, idMap, drc);
filer.Reset(); filer.Reset();
let newObject = filer.ReadObject() as SymbolTableRecord; let newObject = filer.ReadObject() as SymbolTableRecord;
owner.Add(newObject, false); owner.Add(newObject, false);

@ -62,10 +62,10 @@ export class PhysicalMaterialRecord extends MaterialTableRecord
this.matalness = file.Read(); this.matalness = file.Read();
this.opacity = file.Read(); this.opacity = file.Read();
this.depthTest = file.Read(); this.depthTest = file.Read();
this.map = file.ReadHardId(); this.map = file.ReadObjectId();
this.bumpMap = file.ReadHardId(); this.bumpMap = file.ReadObjectId();
this.bumpScale = file.Read(); this.bumpScale = file.Read();
this.roughnessMap = file.ReadHardId(); this.roughnessMap = file.ReadObjectId();
this.roughness = file.Read(); this.roughness = file.Read();
this.useMap = file.Read(); this.useMap = file.Read();
this.useBumpMap = file.Read(); this.useBumpMap = file.Read();
@ -83,10 +83,10 @@ export class PhysicalMaterialRecord extends MaterialTableRecord
file.Write(this.matalness); file.Write(this.matalness);
file.Write(this.opacity); file.Write(this.opacity);
file.Write(this.depthTest); file.Write(this.depthTest);
file.WriteObjectId(this.map); file.WriteHardObjectId(this.map);
file.WriteObjectId(this.bumpMap); file.WriteHardObjectId(this.bumpMap);
file.Write(this.bumpScale); file.Write(this.bumpScale);
file.WriteObjectId(this.roughnessMap); file.WriteHardObjectId(this.roughnessMap);
file.Write(this.roughness); file.Write(this.roughness);
file.Write(this.useMap); file.Write(this.useMap);
file.Write(this.useBumpMap); file.Write(this.useBumpMap);

@ -3,21 +3,12 @@ import { ObjectId } from "./ObjectId";
export class WblockCloneFiler extends DeepCloneFiler export class WblockCloneFiler extends DeepCloneFiler
{ {
hardMaping = new Map<number, ObjectId>(); hardObjectIds: Set<number> = new Set();
ReadHardId() WriteHardObjectId(id: ObjectId)
{ {
let index = this.Read(); if (id && id.Index > 100 && !this.idMaping.has(id.Index)) //当存在id时,表示对象正在被拷贝,或者已经拷贝完成
if (index <= 0) return; this.hardObjectIds.add(id.Index);
let id = this.idMaping.get(index); return this.WriteObjectId(id);
if (id) return id;
id = new ObjectId();
this.idMaping.set(index, id);
if (index > 100)
this.hardMaping.set(index, id);
return id;
} }
} }

@ -81,11 +81,7 @@ export class Asset extends React.Component<{ material: PhysicalMaterialRecord },
async componentDidMount() async componentDidMount()
{ {
this.removeCall.push(xaop.end(this.props.material, this.props.material.Update, this.UpdateRenderPreview)); this.removeCall.push(xaop.end(this.props.material, this.props.material.Update, this.UpdateRenderPreview));
//使用WblockClone时,材质先进来,Texture没进来,导致的显示错误. this.UpdateRenderPreview();
setTimeout(() =>
{
this.props.material.Update();
}, 50);
} }
componentWillUnmount() componentWillUnmount()

Loading…
Cancel
Save