!625 重构深拷贝

pull/625/MERGE
ChenX 5 years ago
parent 916fa4a2d2
commit bc5a7290e3

@ -33,8 +33,7 @@ export function TemplateOut(template: TemplateRecord, tempDb = new Database(fals
{
template = template.Root;
let idMap = new Map();
let ents = template.Objects.map(obj => obj.Object);
tempDb.WblockCloneObejcts(ents, tempDb.ModelSpace, idMap, DuplicateRecordCloning.Ignore);
tempDb.WblockCloneObejcts([template], tempDb.TemplateTable, idMap, DuplicateRecordCloning.Ignore);
let scs = template.GetTemplateSpaceCS(true);
let scsInv = new Matrix4().getInverse(scs);

@ -182,8 +182,8 @@ export class GangDrill extends Solid3D
this.type = file.Read();
if (ver >= 3)
{
this.FId = file.ReadObjectId();
this.MId = file.ReadObjectId();
this.FId = file.ReadSoftObjectId();
this.MId = file.ReadSoftObjectId();
}
}
WriteFile(file: CADFiler)
@ -193,8 +193,8 @@ export class GangDrill extends Solid3D
file.Write(this._Radius);
file.Write(this._Height);
file.Write(this.type);
file.WriteObjectId(this.FId);
file.WriteObjectId(this.MId);
file.WriteSoftObjectId(this.FId);
file.WriteSoftObjectId(this.MId);
}
}

@ -12,27 +12,32 @@ export class CADFiler
{
database: Database;
private readIndex: number = 0;
constructor(private dataList: any[] = [])
constructor(protected _datas: any[] = [])
{
}
Destroy()
{
delete this.dataList;
delete this._datas;
delete this.readIndex;
}
get Data(): any[]
{
return this.dataList;
return this._datas;
}
set Data(data: any[])
{
this.dataList = data;
this._datas = data;
this.Reset();
}
Clear()
{
this._datas.length = 0;
return this.Reset();
}
Reset()
{
this.readIndex = 0;
@ -41,13 +46,13 @@ export class CADFiler
WriteString(str: string)
{
this.dataList.push(str);
this._datas.push(str);
return this;
}
ReadString(): string
{
return this.dataList[this.readIndex++] as string;
return this._datas[this.readIndex++] as string;
}
WriteObject(obj: ISerialize)
@ -98,33 +103,36 @@ export class CADFiler
Write(data: any)
{
if (data instanceof ObjectId)
this.dataList.push(data.Index);
this._datas.push(data.Index);
else
this.dataList.push(data);
this._datas.push(data);
return this;
}
Read(): any
{
return this.dataList[this.readIndex++];
return this._datas[this.readIndex++];
}
WriteObjectId(id: ObjectId)
//------------------------ID序列化------------------------
/*
Id:
1.:,.
2. :,.
3. :,.
*/
//-------1.普通关联
WriteObjectId(id: ObjectId): this
{
if (id)
this.Write(id.Index);
else
this.Write(0);
return this;
}
WriteHardObjectId(id: ObjectId)
{
return this.WriteObjectId(id);
}
ReadObjectId(): ObjectId
{
let index = this.Read();
@ -132,8 +140,33 @@ export class CADFiler
return this.database.GetObjectId(index, true);
}
//-------2.软关联
WriteSoftObjectId(id: ObjectId): this
{
return this.WriteObjectId(id);
}
ReadSoftObjectId(): ObjectId
{
return this.ReadObjectId();
}
//-------3.硬关联
WriteHardObjectId(id: ObjectId): this
{
return this.WriteObjectId(id);
}
ReadHardObjectId()
{
return this.ReadObjectId();
}
//序列化
ToString()
{
return JSON.stringify(this.dataList);
return JSON.stringify(this._datas);
}
FromString(str: string)
{
this._datas = JSON.parse(str);
}
}

@ -173,18 +173,25 @@ export abstract class CADObject
return false;
}
//复制出一个实体,所有的关联引用全部失效,如有需要,请重新关联.
//复制出一个实体,如果存在关联,则指向原关联实体
Clone(): this
{
let newObject = CADFactory.CreateObject(this.constructor.name) as this;
//备份
let bakId = this.objectId;
this.objectId = undefined;
let file = new CADFiler();
file.database = this._db;
this.WriteFile(file);
file.Reset();
newObject.ReadFile(file);
newObject.objectId = undefined;
newObject._db = undefined;
this.objectId = bakId;
return newObject;
}
@ -195,7 +202,6 @@ export abstract class CADObject
isPrimary = true
): this
{
return this;
}

@ -7,7 +7,6 @@ import { Factory } from './CADFactory';
import { CADFiler } from './CADFiler';
import { CADObject } from './CADObject';
import { DeepCloneFiler } from './DeepCloneFiler';
import { Entity } from './Entity/Entity';
import { GroupTable } from './GroupTable';
import { HistoricManage } from './HistoricManage';
import { IdMaping } from './IdMaping';
@ -15,7 +14,7 @@ import { AmbientLight } from './Lights/AmbientLight';
import { DirectionalLight } from './Lights/DirectionalLight';
import { HemisphereLight } from './Lights/HemisphereLight';
import { MaterialTable } from './MaterialTable';
import { ObjectId } from './ObjectId';
import { ObjectId, RelevancyType } from './ObjectId';
import { PhysicalMaterialRecord } from './PhysicalMaterialRecord';
import { SymbolTable } from './SymbolTable';
import { SymbolTableRecord } from './SymbolTableRecord';
@ -24,7 +23,10 @@ import { TextureTableRecord } from './Texture';
import { TextureTable } from './TextureTable';
import { WblockCloneFiler } from './WblockCloneFiler';
type OwnerContainer = SymbolTable | SymbolTableRecord;
interface OwnerContainer
{
Add(object: any, isCheckObjectCleanly?: boolean): void;
}
@Factory
export class Database
@ -205,52 +207,96 @@ export class Database
objects: CADObject[],
owner: OwnerContainer,
idMap: IdMaping = new Map(),
clonedObjects: CADObject[] = [],
deferXlation = false
): CADObject[]
{
let f = new DeepCloneFiler();
f.CloneObjects(objects, clonedObjects);
this.CheapClone(f, idMap, owner);
return clonedObjects;
let newObjects: CADObject[] = [];
for (let e of objects)
{
let newE = this.DeepCloneObject(f, e, owner, idMap);
if (newE)
newObjects.push(newE);
}
CheapClone(f: DeepCloneFiler, idMap: Map<ObjectId, ObjectId>, owner: OwnerContainer)
{
//对于无法新拷贝的实体,指向原先的对象(需要是软拷贝才行)
for (let [index, objectId] of f.idMaping)
{
if (objectId.Object)
if (!objectId.Object && objectId._RelevancyType === RelevancyType.Soft)
{
objectId.Index = this.idIndex++;
this.idMap.set(objectId.Index, objectId);
idMap.set(this.GetObjectId(index), objectId);
if (owner instanceof BlockTableRecord)
let oldId = this.GetObjectId(index);
if (oldId)
{
let ent = objectId.Object as Entity;
ent.SetDefaultDb(this);
owner.Append(ent, false);
objectId.Index = index;
objectId.Object = oldId.Object;
}
}
}
this.ClearEmptyAssoc(f);
return newObjects;
}
else if (owner instanceof SymbolTable)
/**
*
*/
private ClearEmptyAssoc(f: DeepCloneFiler)
{
let record = objectId.Object as SymbolTableRecord;
if (owner.Has(record.Name))
let tempF = new CADFiler();
tempF.database = this;
for (let [index, objectId] of f.idMaping)
{
console.log("重复的记录名称!");
continue;
if (objectId.Object && objectId.Index !== index)
{
tempF.Clear();
objectId.Object.WriteFile(tempF);
tempF.Reset();
objectId.Object.ReadFile(tempF);
}
owner.Add(record, false);
}
}
else
DeepCloneObject(
filer: DeepCloneFiler,
object: CADObject,
owner: OwnerContainer,
idMap: IdMaping = new Map(),
): CADObject | undefined
{
let oldId = this.GetObjectId(index);
if (oldId)
if (idMap.has(object.Id))
return idMap.get(object.Id).Object;
if (owner instanceof SymbolTable)//应该不能直接拷贝这类型的实体,因为会直接名称重复
return;
filer.Data.length = 0;
filer.Reset();
filer.WriteObject(object);
let newObject = filer.ReadObject();
this.AllocationObjectId(newObject);
owner.Add(newObject, false);
idMap.set(object.Id, newObject.Id);
//拷贝硬绑定对象
while (filer.hardObjectIds.size > 0)
{
objectId.Index = index;
objectId.Object = oldId.Object;
let hardObjectIds = filer.hardObjectIds;
filer.hardObjectIds = new Set();
for (let idIndex of hardObjectIds)
{
let objectId = this.GetObjectId(idIndex, false);
let object = objectId.Object;
if (!object.Owner)
{
console.error("无主?");
}
if (!(object.Owner instanceof SymbolTable))//指向这个对象的时候,通常是命名的块表记录,所以不拷贝它.
this.DeepCloneObject(filer, object, object.Owner.Object as unknown as OwnerContainer, idMap);//指向新对象
}
}
return newObject;
}
/**
@ -267,19 +313,25 @@ export class Database
owner: OwnerContainer,
idMap: IdMaping,
drc: DuplicateRecordCloning
)
): CADObject[]
{
let f = new WblockCloneFiler();
for (let obj of objects)
this.WblockCloneObject(obj, owner, idMap, drc, f);
this.ClearEmptyAssoc(f);
return objects.map(o => idMap.get(o.Id).Object);
}
/**
* WriteHardObjectId
*/
private WblockCloneReferenceObject(object: CADObject, f: WblockCloneFiler, idMap: Map<ObjectId, ObjectId>, drc: DuplicateRecordCloning)
private WblockCloneReferenceObject(
object: CADObject,
f: WblockCloneFiler,
idMap: Map<ObjectId, ObjectId>,
drc: DuplicateRecordCloning)
{
let oldData = f.Data;
f.Data = [];

@ -1,9 +1,13 @@
import { CADFiler } from "./CADFiler";
import { ObjectId } from "./ObjectId";
import { ObjectId, RelevancyType } from "./ObjectId";
export class DeepCloneFiler extends CADFiler
{
idMaping = new Map<number, ObjectId>();
constructor(public idMaping = new Map<number, ObjectId>())
{
super();
}
ReadObjectId()
{
let index = this.Read();
@ -11,9 +15,35 @@ export class DeepCloneFiler extends CADFiler
let id = this.idMaping.get(index);
if (id) return id;
id = new ObjectId();
this.idMaping.set(index, id);
return id;
}
ReadSoftObjectId()
{
let id = this.ReadObjectId();
if (id)
id._RelevancyType = RelevancyType.Soft;
return id;
}
ReadHardObjectId()
{
let id = this.ReadObjectId();
if (id)
id._RelevancyType = RelevancyType.Hard;
return id;
}
hardObjectIds: Set<number> = new Set();
WriteHardObjectId(id: ObjectId)
{
if (id && id.Index >= 100 && !this.idMaping.has(id.Index)) //当存在id时,表示对象正在被拷贝,或者已经拷贝完成
this.hardObjectIds.add(id.Index);
return this.WriteObjectId(id);
}
}

@ -1,5 +1,6 @@
import { Matrix4, Vector3 } from 'three';
import { Board2Regions } from '../../Add-on/BoardEditor/Board2Regions';
import { deserializationBoardData, serializeBoardData } from '../../Add-on/BoardEditor/SerializeBoardData';
import { arrayPushArray } from '../../Common/ArrayExt';
import { EBoardKeyList } from '../../Common/BoardKeyList';
import { UpdateDraw } from '../../Common/Status';
@ -14,8 +15,7 @@ import { Contour } from '../Contour';
import { ObjectId } from '../ObjectId';
import { Shape } from '../Shape';
import { Circle } from './Circle';
import { ExtureContourCurve, ExtrudeSolid } from './Extrude';
import { deserializationBoardData, serializeBoardData } from '../../Add-on/BoardEditor/SerializeBoardData';
import { ExtrudeSolid, ExtureContourCurve } from './Extrude';
export enum BoardType
{
@ -647,6 +647,14 @@ export class Board extends ExtrudeSolid
this._LayerNails = layerNailsBak;
}
Clone(): this
{
let br = super.Clone();
br._DrillList.clear();
br._LayerNails.length = 0;
return br;
}
protected _ReadFile(file: CADFiler)
{
super._ReadFile(file);

@ -400,9 +400,6 @@ export class Entity extends CADObject
/**
* 使.
* .
*
* @param {Matrix4} m
* @memberof Entity
*/
ApplyMatrix(m: Matrix4): this
{
@ -529,7 +526,7 @@ export class Entity extends CADObject
this.Template = file.ReadObjectId();
if (ver > 4)
this.GourpId = file.ReadObjectId();
this.GourpId = file.ReadHardObjectId();
if (ver > 5)
this._Visible = file.Read();
@ -542,7 +539,7 @@ export class Entity extends CADObject
file.Write(this._Color);
file.WriteHardObjectId(this.materialId);
file.Write(this._Matrix.toArray());
file.WriteHardObjectId(this.Template);
file.WriteObjectId(this.Template);
file.WriteHardObjectId(this.GourpId);
file.Write(this._Visible);
}

@ -2,10 +2,31 @@ import { Factory } from "./CADFactory";
import { GroupRecord } from "./GroupTableRecord";
import { ObjectCollection } from "./ObjectCollection";
import { CADFiler } from "./CADFiler";
import { Status } from "../Common/Status";
@Factory
export class GroupTable extends ObjectCollection<GroupRecord>
{
Append(object: GroupRecord, isCheckObjectCleanly = true)
{
let id = super.Append(object, isCheckObjectCleanly);
if (id)
object.Owner = this.Id;
return id;
}
Add(record: GroupRecord, isCheckObjectCleanly = true): Status
{
let id = this.Append(record, isCheckObjectCleanly);
if (id)
return Status.True;
else
return Status.False;
}
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFiler)
{

@ -27,11 +27,13 @@ export class Light extends Entity
{
return super.Position;
}
set Position(v: Vector3)
{
super.Position = v;
this.Update(UpdateDraw.Geometry);
}
get Color()
{
return this._LightColor;

@ -1,5 +1,12 @@
import { CADObject } from './CADObject';
export enum RelevancyType
{
General = 0,
Soft = 1,
Hard = 2,
}
/*
CADObjectId,.
id,.
@ -9,6 +16,7 @@ ObjectId必须使用 Database分配(db里面会存id的列表,以便同时更新
*/
export class ObjectId
{
_RelevancyType = RelevancyType.General;
constructor(private index = 0, private obj?: CADObject)
{
}

@ -96,10 +96,7 @@ export class TemplateRecord extends SymbolTableRecord
get Root(): TemplateRecord
{
if (this.Parent)
return (<TemplateRecord>this.Parent.Object).Root;
else
return this;
return (<TemplateRecord>this.Parent?.Object)?.Root ?? this;
}
private CreateProxyArray(setCallback: (v: any) => void)
@ -127,6 +124,16 @@ export class TemplateRecord extends SymbolTableRecord
});
}
get AllEntitys(): Entity[]
{
let entitys: Entity[] = [];
this.Traverse((t) =>
{
entitys.push(...t.Objects.map(o => o.Object as Entity));
});
return entitys;
}
Traverse(callback: (arg0: this) => void)
{
callback(this);
@ -618,11 +625,11 @@ export class TemplateRecord extends SymbolTableRecord
let ver = file.Read();
super.ReadFile(file);
this.Type = file.Read();
this.Parent = file.ReadObjectId();
this.Parent = file.ReadHardObjectId();
let count = file.Read() as number;
this.Children.length = 0;
for (let i = 0; i < count; i++)
this.Children.push(file.ReadObjectId());
this.Children.push(file.ReadHardObjectId());
count = file.Read();
this.Params.length = 0;
for (let i = 0; i < count; i++)

@ -1,14 +1,6 @@
import { DeepCloneFiler } from "./DeepCloneFiler";
import { ObjectId } from "./ObjectId";
export class WblockCloneFiler extends DeepCloneFiler
{
hardObjectIds: Set<number> = new Set();
WriteHardObjectId(id: ObjectId)
{
if (id && id.Index >= 100 && !this.idMaping.has(id.Index)) //当存在id时,表示对象正在被拷贝,或者已经拷贝完成
this.hardObjectIds.add(id.Index);
return this.WriteObjectId(id);
}
}

@ -78,6 +78,7 @@ export const HotCMD =
// remove itself from a cache
delete cache[module.id];
// setup hot for caller
//@ts-ignore
return makeHotExport(Object.assign({ id: parent.i }, parent));
}
else

@ -8,9 +8,11 @@ import { EBoardKeyList } from '../../../Common/BoardKeyList';
import { TemplateUrls } from '../../../Common/HostUrl';
import { DirectoryId, PostJson, RequestStatus } from '../../../Common/Request';
import { DuplicateRecordCloning } from '../../../Common/Status';
import { StoreageKeys } from '../../../Common/StoreageKeys';
import { Board } from '../../../DatabaseServices/Entity/Board';
import { Entity } from '../../../DatabaseServices/Entity/Entity';
import { PositioningClampSpace } from '../../../DatabaseServices/Template/Positioning/PositioningClampSpace';
import { GetDeepestTemplate, UploadTemplate, GetOnlineTemplate } from '../../../DatabaseServices/Template/TempateUtils';
import { GetDeepestTemplate, GetOnlineTemplate, UploadTemplate } from '../../../DatabaseServices/Template/TempateUtils';
import { TemplateRecord } from '../../../DatabaseServices/Template/TemplateRecord';
import { commandMachine, CommandWrap } from '../../../Editor/CommandMachine';
import { JigUtils } from '../../../Editor/JigUtils';
@ -27,7 +29,6 @@ import { AppToaster } from '../Toaster';
import { GetRoomCabName, IGetRoomInfo } from './GetRoomCabName';
import { TemplateEditor } from './TemplateEditor';
import { TemplateList } from './TemplateList';
import { StoreageKeys } from '../../../Common/StoreageKeys';
export interface INeedUpdateParams
{
@ -197,7 +198,7 @@ export class TemplateManage extends React.Component<{ store?: TempalteEditorStor
let template = await GetOnlineTemplate(this.currentTemplateInfo.id, this.currentProps);
if (!template)
return;
let ens = template.Db.ModelSpace.Entitys as Board[];
let ens = template.Db.ModelSpace.Entitys as Entity[];
let nens = ens.map(e => JigUtils.Draw(e));
let pos = new Vector3();
@ -232,12 +233,17 @@ export class TemplateManage extends React.Component<{ store?: TempalteEditorStor
}
if (ptRes.Status === PromptStatus.OK)
{
nens = app.Database.WblockCloneObejcts(ens, app.Database.ModelSpace, new Map(), DuplicateRecordCloning.Ignore) as Board[];
let newTemp = app.Database.WblockCloneObejcts([template], app.Database.TemplateTable, new Map(), DuplicateRecordCloning.Ignore)[0] as TemplateRecord;
nens = newTemp.Root.AllEntitys;
for (let b of nens)
{
if (b instanceof Board)
{
b.BoardProcessOption[EBoardKeyList.RoomName] = this.option.roomName;
b.BoardProcessOption[EBoardKeyList.CabinetName] = this.option.cabName;
}
}
mtx.setPosition(ptRes.Point.sub(baseP));
for (let e of nens)
e.ApplyMatrix(mtx);
@ -263,14 +269,9 @@ export class TemplateManage extends React.Component<{ store?: TempalteEditorStor
let template = await GetOnlineTemplate(this.currentTemplateInfo.id, this.currentProps);
if (!template)
return;
//临时空间的板件
let ents = template.Objects.map(obj => obj.Object);
//图纸空间的板件
let nents = app.Database.WblockCloneObejcts(ents, app.Database.ModelSpace, new Map(), DuplicateRecordCloning.Ignore) as Board[];
let br = nents[0] as Board;
template = br.Template.Object as TemplateRecord;
template = template.Root;
template = app.Database.WblockCloneObejcts([template], app.Database.TemplateTable, new Map(), DuplicateRecordCloning.Ignore)[0] as TemplateRecord;
let nents = template.Root.AllEntitys;
let seleteBrs = parse.Boards.filter(b => b.Template !== undefined);
@ -278,19 +279,25 @@ export class TemplateManage extends React.Component<{ store?: TempalteEditorStor
{
let process = parse.Boards[0].BoardProcessOption;
for (let b of nents)
{
if (b instanceof Board)
{
b.BoardProcessOption[EBoardKeyList.RoomName] = process[EBoardKeyList.RoomName];
b.BoardProcessOption[EBoardKeyList.CabinetName] = process[EBoardKeyList.CabinetName];
}
}
}
else
{
for (let b of nents)
{
if (b instanceof Board)
{
b.BoardProcessOption[EBoardKeyList.RoomName] = this.option.roomName;
b.BoardProcessOption[EBoardKeyList.CabinetName] = this.option.cabName;
}
}
}
if (parse instanceof ClampSpaceParse)
{

@ -308,7 +308,7 @@ export class UserConfigStore extends Singleton
for (let k of keys)
{
let configs = await this.GetAllConfigs(k, false, init);
await store.Put(StoreName.ConfigData, GetIndexDBID(k), configs);
store.Put(StoreName.ConfigData, GetIndexDBID(k), configs);
}
}

Loading…
Cancel
Save