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

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

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

@ -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,

@ -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

@ -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()
{

@ -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<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,假设所有者都是数据库默认存在的.
//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);

@ -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);

@ -3,21 +3,12 @@ import { ObjectId } from "./ObjectId";
export class WblockCloneFiler extends DeepCloneFiler
{
hardMaping = new Map<number, ObjectId>();
ReadHardId()
hardObjectIds: Set<number> = 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);
}
}

@ -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()

Loading…
Cancel
Save