(api) 模板记录序列化

pull/346/MERGE
ChenX 5 years ago
parent caa9dbfadc
commit 1c294ece3d

@ -0,0 +1,65 @@
export const ISPROXYKEY = "_isProxy";
/**
* CADObject, `WriteAllObjectRecord`
* ,`Proxy`.
* 使`ISPROXYKEY`.
*
* @param target
* @param property
* @param [descriptor]
*/
export function AutoRecord(
target: { WriteAllObjectRecord: () => void },
property: string,
descriptor?: PropertyDecorator)
{
let privateKey = '__' + property;
Object.defineProperty(target, property,
{
set: function (value)
{
if (value instanceof Array)
{
if (!this[privateKey])
{
if (value[ISPROXYKEY])
this[privateKey] = value;
else
this[privateKey] = new Proxy(value, {
set: (target, key, value, receiver) =>
{
if (Reflect.get(target, key, receiver) !== value)
this.WriteAllObjectRecord();
return Reflect.set(target, key, value, receiver);
}
});
}
else
{
let arr = this[privateKey] as Array<any>;
arr.length = 0;
arr.push(...value);
}
}
else
{
let oldv = this[privateKey];
if (oldv !== value)
{
this.WriteAllObjectRecord();
this[privateKey] = value;
}
}
},
get: function ()
{
return this[privateKey];
},
enumerable: true,
configurable: true
}
);
}

@ -62,7 +62,7 @@ export class CADFiler
obj.WriteFile(this);
}
ReadObject(obj?: CADObject): CADObject
ReadObject<T extends ISerialize = CADObject>(obj?: T): T
{
let className = this.ReadString();
if (className)

@ -151,7 +151,7 @@ export abstract class CADObject
return this._db.hm.UndoData;
}
//写入所有的对象数据 以便还原对象
protected WriteAllObjectRecord()
WriteAllObjectRecord()
{
let undoData = this.UndoRecord();
if (undoData)

@ -15,6 +15,7 @@ import { ObjectId } from './ObjectId';
import { PhysicalMaterialRecord } from './PhysicalMaterialRecord';
import { SymbolTable } from './SymbolTable';
import { SymbolTableRecord } from './SymbolTableRecord';
import { TemplateTable } from './TemplateTable';
import { TextureTableRecord } from './Texture';
import { TextureTable } from './TextureTable';
import { WblockCloneFiler } from './WblockCloneFiler';
@ -29,6 +30,7 @@ export class Database
BlockTable: BlockTable;
MaterialTable: MaterialTable;
TextureTable: TextureTable;
TemplateTable: TemplateTable;
ModelSpace: BlockTableRecord;
DefaultMaterial: PhysicalMaterialRecord;
@ -40,6 +42,7 @@ export class Database
this.ModelSpace = new BlockTableRecord().SetOwnerDatabase(this);
this.MaterialTable = new MaterialTable().SetOwnerDatabase(this);
this.TextureTable = new TextureTable().SetOwnerDatabase(this);
this.TemplateTable = new TemplateTable().SetOwnerDatabase(this);
this.hm = new HistoricManage().SetDefaultDb(this);
@ -85,6 +88,7 @@ export class Database
this.ModelSpace.Destroy();
this.MaterialTable.Destroy();
this.TextureTable.Destroy();
this.TemplateTable.Destroy();
this.hm.Destroy();
this.hm.historyRecord.length = 0;
@ -92,6 +96,7 @@ export class Database
this.ModelSpace.SetOwnerDatabase(this);
this.MaterialTable.SetOwnerDatabase(this);
this.TextureTable.SetOwnerDatabase(this);
this.TemplateTable.SetOwnerDatabase(this);
this.hm.SetOwnerDatabase(this);
this.idIndex = 100;
}
@ -101,12 +106,13 @@ export class Database
FileWrite(): CADFiler
{
let file = new CADFiler();
file.Write(1);//ver;
file.Write(2);//ver;
file.Write(this.idIndex);
this.ModelSpace.WriteFile(file);
this.TextureTable.WriteFile(file);
this.MaterialTable.WriteFile(file);
this.hm.WriteFile(file);
this.TemplateTable.WriteFile(file);
return file;
}
@ -120,6 +126,8 @@ export class Database
this.TextureTable.ReadFile(file);
this.MaterialTable.ReadFile(file);
this.hm.ReadFile(file);
if (ver > 1)
this.TemplateTable.ReadFile(file);
this.SettingDefaultMaterial();

@ -1,13 +1,17 @@
import { Box3, Matrix4, Vector3 } from "three";
import { app } from "../ApplicationServices/Application";
import { arrayClone } from "../Common/ArrayExt";
import { StretchParse } from "../Common/StretchParse";
import { FixIndex } from "../Common/Utils";
import { commandMachine } from "../Editor/CommandMachine";
import { PromptSsgetResult, PromptStatus } from "../Editor/PromptResult";
import { SelectBox, SelectType } from "../Editor/SelectBox";
import { ZeroVec, equaln, equalv3, MoveMatrix, AsVector3 } from "../Geometry/GeUtils";
import { AsVector3, equaln, equalv3, MoveMatrix, ZeroVec } from "../Geometry/GeUtils";
import { HotCMD } from "../Hot/HotCommand";
import { AutoRecord, ISPROXYKEY } from "./AutoRecord";
import { Board } from "./Board";
import { Factory } from "./CADFactory";
import { CADFiler } from "./CADFiler";
import { Entity } from "./Entity";
import { ObjectId } from "./ObjectId";
import { SymbolTableRecord } from "./SymbolTableRecord";
@ -41,22 +45,64 @@ export enum TemplateType
/**
*
*/
@Factory
export class TemplateParam
{
name: string;
expr: string;
value: string | number;
default: string | number;
@AutoRecord name: string;
@AutoRecord expr: string;
type: TemplateParamType;
min: number;
max: number;
/**
* , UpdateParam
*/
@AutoRecord value: string | number;
@AutoRecord default: string | number;
@AutoRecord description: string;
@AutoRecord type: TemplateParamType;
@AutoRecord min: number;
@AutoRecord max: number;
//可选值
option: any[];
@AutoRecord option: any[];
@AutoRecord actions: TemplateAction[];
@AutoRecord parent: TemplateRecord;
actions: TemplateAction[] = [];
constructor()
{
//监听
this.actions = new Proxy([], {
set: (target, key, value, receiver) =>
{
if (Reflect.get(target, key, receiver) !== value)
{
this.WriteAllObjectRecord();
if (value instanceof TemplateAction)
value.parent = this;
}
return Reflect.set(target, key, value, receiver);
},
get: (target, key, receiver) =>
{
if (key === ISPROXYKEY)
return true;
else
return Reflect.get(target, key, receiver);
}
});
}
WriteAllObjectRecord()
{
if (this.parent)
this.parent.WriteAllObjectRecord();
}
/**
* ,.
* ,`this.value = xxx;`
*/
UpdateParam(value: string | number)
{
switch (this.type)
@ -80,43 +126,143 @@ export class TemplateParam
break;
}
}
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFiler)
{
let ver = file.Read();
this.name = file.Read();
this.expr = file.Read();
this.value = file.Read();
this.default = file.Read();
this.description = file.Read();
this.type = file.Read();
this.min = file.Read();
this.max = file.Read();
this.option = file.Read();
let count = file.Read();
this.actions.length = 0;
for (let i = 0; i < count; i++)
this.actions.push(file.ReadObject());
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
file.Write(1);
file.Write(this.name);
file.Write(this.expr);
file.Write(this.value);
file.Write(this.default);
file.Write(this.description);
file.Write(this.type);
file.Write(this.min);
file.Write(this.max);
file.Write(this.option);
file.Write(this.actions.length);
for (let action of this.actions)
{
file.WriteObject(action);
}
}
//#endregion
}
/**
*
*/
@Factory
class TemplateAction
{
parent: TemplateParam;
WriteAllObjectRecord()
{
if (this.parent)
this.parent.WriteAllObjectRecord();
}
Update(paramDiff: number | string)
{
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFiler)
{
let ver = file.Read();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
file.Write(1);
}
//#endregion
}
class TemplateMoveAction
class TemplateMoveAction extends TemplateAction
{
StretchDirection: Vector3;
Entitys: Entity[];
StretchDirection: Vector3 = new Vector3();
Entitys: ObjectId[] = [];
Update(paramDiff: number)
{
let moveMatrix = MoveMatrix(this.StretchDirection.clone().multiplyScalar(paramDiff));
for (let ent of this.Entitys)
for (let id of this.Entitys)
{
let ent = id.Object as Entity;
ent.ApplyMatrix(moveMatrix);
}
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFiler)
{
let ver = file.Read();
this.StretchDirection.fromArray(file.Read());
this.Entitys.length = 0;
let count = file.Read();
for (let i = 0; i < count; i++)
{
this.Entitys.push(file.ReadObjectId());
}
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
file.Write(1);
file.Write(this.StretchDirection.toArray());
file.Write(this.Entitys.length);
for (let ent of this.Entitys)
file.WriteObjectId(ent);
}
//#endregion
}
/**
* Stretch
*/
@Factory
class TemplateStretchGripAction extends TemplateAction
{
StretchDirection: Vector3;
/**
* 2,, `this.WriteAllObjectRecord`;
* .
*/
StretchDirection: Vector3 = new Vector3();
EntityStretchPointMap: { entity: Entity, indexs: number[] }[] = [];
EntityStretchPointMap: { entity: ObjectId, indexs: number[] }[] = [];
Update(dist: number)
{
@ -124,9 +270,45 @@ class TemplateStretchGripAction extends TemplateAction
for (let { entity, indexs } of this.EntityStretchPointMap)
{
entity.MoveStretchPoints(indexs, v);
let ent = entity.Object as Entity;
ent.MoveStretchPoints(indexs, v);
}
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFiler)
{
let ver = file.Read();
super.ReadFile(file);
this.StretchDirection.fromArray(file.Read());
this.EntityStretchPointMap.length = 0;
let count = file.Read() as number;
for (let i = 0; i < count; i++)
{
let entity = file.ReadObjectId();
let indexs = file.Read();
this.EntityStretchPointMap.push({ entity, indexs });
}
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
file.Write(1);
super.WriteFile(file);
file.Write(this.StretchDirection.toArray());
file.Write(this.EntityStretchPointMap.length);
for (let d of this.EntityStretchPointMap)
{
file.WriteObjectId(d.entity);
file.Write(arrayClone(d.indexs));
}
}
//#endregion
}
@ -135,9 +317,13 @@ class TemplateStretchGripAction extends TemplateAction
*/
class TemplateStretchScaleBoxAction extends TemplateAction
{
StretchDirection: Vector3;
/**
* 2,, `this.WriteAllObjectRecord`;
* .
*/
StretchDirection: Vector3 = new Vector3();
EntityStretchData: { entity: Entity, scaleBox: Box3 }[] = [];
EntityStretchData: { entity: ObjectId, scaleBox: Box3 }[] = [];
Update(dist: number)
{
@ -145,9 +331,10 @@ class TemplateStretchScaleBoxAction extends TemplateAction
for (let { entity, scaleBox } of this.EntityStretchData)
{
let pts = entity.GetStretchPoints();
let ocsInv = entity.OCSInv;
let entityBox = entity.BoundingBoxInOCS;
let ent = entity.Object as Entity;
let pts = ent.GetStretchPoints();
let ocsInv = ent.OCSInv;
let entityBox = ent.BoundingBoxInOCS;
let size = entityBox.getSize(new Vector3());
scaleBox = scaleBox.clone();
@ -165,9 +352,46 @@ class TemplateStretchScaleBoxAction extends TemplateAction
stretchIndexs.push(i);
}
entity.MoveStretchPoints(stretchIndexs, v);
ent.MoveStretchPoints(stretchIndexs, v);
}
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFiler)
{
let ver = file.Read();
super.ReadFile(file);
this.StretchDirection.fromArray(file.Read());
this.EntityStretchData.length = 0;
let count = file.Read() as number;
for (let i = 0; i < count; i++)
{
let entity = file.ReadObjectId();
let min = new Vector3().fromArray(file.Read());
let max = new Vector3().fromArray(file.Read());
this.EntityStretchData.push({ entity, scaleBox: new Box3(min, max) });
}
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
file.Write(1);
super.WriteFile(file);
file.Write(this.StretchDirection.toArray());
file.Write(this.EntityStretchData.length);
for (let d of this.EntityStretchData)
{
file.WriteObjectId(d.entity);
file.Write(d.scaleBox.min.toArray());
file.Write(d.scaleBox.max.toArray());
}
}
//#endregion
}
@ -183,15 +407,55 @@ class TemplateStretchSizeBoxAction extends TemplateAction
}
*/
@Factory
export class TemplateRecord extends SymbolTableRecord
{
type: TemplateType;
parent: ObjectId;
children: ObjectId[];
params: TemplateParam[] = [];
@AutoRecord type: TemplateType;
@AutoRecord parent: ObjectId;
@AutoRecord children: ObjectId[] = [];
@AutoRecord params: TemplateParam[];
@AutoRecord objects: ObjectId[] = [];
constructor()
{
super();
//监听
this.params = new Proxy([], {
set: (target, key, value, receiver) =>
{
if (Reflect.get(target, key, receiver) !== value)
{
this.WriteAllObjectRecord();
if (value instanceof TemplateParam)
value.parent = this;
}
return Reflect.set(target, key, value, receiver);
},
get: (target, key, receiver) =>
{
if (key === ISPROXYKEY)
return true;
return Reflect.get(target, key, receiver);
}
});
}
InitSizeParams()
{
for (let paramName of ["L", "W", "H"])
{
let param = new TemplateParam();
param.name = paramName;
param.type = TemplateParamType.Float;
param.value = 0;
this.params.push(param);
}
return this;
}
objects: ObjectId[] = [];
UpdateAllTemplate(newParams: [])
{
for (let i = 0; i < this.params.length; i++)
@ -200,12 +464,20 @@ export class TemplateRecord extends SymbolTableRecord
oldParam.UpdateParam(newParams[i]);
}
}
get Params()
{
return this.params;
}
UpdateParam(name: string, value: any, expr?: string)
{
let param = this.GetParam(name);
if (param)
{
param.UpdateParam(value);
}
}
GetParam(paramName: string)
{
@ -215,6 +487,55 @@ export class TemplateRecord extends SymbolTableRecord
return param;
}
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFiler)
{
let ver = file.Read();
super.ReadFile(file);
this.type = file.Read();
this.parent = file.ReadObjectId();
let count = file.Read() as number;
this.children.length = 0;
for (let i = 0; i < count; i++)
this.children.push(file.ReadObjectId());
count = file.Read();
this.params.length = 0;
for (let i = 0; i < count; i++)
this.params.push(file.ReadObject());
count = file.Read();
this.objects.length = 0;
for (let i = 0; i < count; i++)
this.objects.push(file.ReadObjectId());
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
file.Write(1);
super.WriteFile(file);
file.Write(this.type);
file.WriteObjectId(this.parent);
file.Write(this.children.length);
for (let id of this.children)
file.WriteObjectId(id);
file.Write(this.params.length);
for (let param of this.params)
file.WriteObject(param);
file.Write(this.objects.length);
for (let id of this.objects)
file.WriteObjectId(id);
}
//#endregion
}
@ -260,7 +581,7 @@ export class TestTemplateAction
let params = ["L", "W", "H"];
let paramIndex = 0;
let record = globalThis.record as TemplateRecord
let record = GetDefaultTemplate() as TemplateRecord
let count = 1;
this.time = setInterval(() =>
@ -282,28 +603,18 @@ export class TestTemplateAction
}
}
globalThis.record = new TemplateRecord();
let lParam = new TemplateParam();
lParam.name = "L";
lParam.type = TemplateParamType.Float;
lParam.value = 0;
globalThis.record.params.push(lParam);
let wParam = new TemplateParam();
wParam.name = "W";
wParam.type = TemplateParamType.Float;
wParam.value = 0;
globalThis.record.params.push(wParam);
let hParam = new TemplateParam();
hParam.name = "H";
hParam.type = TemplateParamType.Float;
hParam.value = 0;
globalThis.record.params.push(hParam);
function GetDefaultTemplate()
{
let templates = app.m_Database.TemplateTable.Objects;
if (templates.length === 0)
{
let template = new TemplateRecord().InitSizeParams();
app.m_Database.TemplateTable.Append(template);
return template;
}
else
return templates[0];
}
const SCALEMIN = new Vector3(-0.1, -0.1, -0.1);
const SCALEMAX = new Vector3(1.1, 1.1, 1.1);
@ -351,19 +662,19 @@ export class AddTemplateAction
for (let { ent, indexs } of stretchData.stretchEntityMap)
{
stretchAction.EntityStretchPointMap.push({
entity: ent,
entity: ent.Id,
indexs
});
}
if (stretchData.stretchEntityMap.length > 0)
{
globalThis.record.GetParam(this.name).actions.push(stretchAction);
GetDefaultTemplate().GetParam(this.name).actions.push(stretchAction);
}
moveAction.Entitys = stretchData.moveEntityList;
moveAction.Entitys = stretchData.moveEntityList.map(ent => ent.Id);
if (moveAction.Entitys.length > 0)
{
globalThis.record.GetParam(this.name).actions.push(moveAction);
GetDefaultTemplate().GetParam(this.name).actions.push(moveAction);
}
}
@ -394,7 +705,7 @@ export class AddTemplateAction
scaleBox.min.clamp(SCALEMIN, SCALEMAX);
scaleBox.max.clamp(SCALEMIN, SCALEMAX);
action.EntityStretchData.push({
entity: br,
entity: br.Id,
scaleBox
});
}
@ -402,7 +713,7 @@ export class AddTemplateAction
}
if (action.EntityStretchData.length > 0)
{
globalThis.record.GetParam(this.name).actions.push(action);
GetDefaultTemplate().GetParam(this.name).actions.push(action);
}
}
}
@ -493,9 +804,47 @@ export class TestAction
{
async exec()
{
globalThis.record.UpdateParam("L", <number>globalThis.record.GetParam("L").value + 500);
globalThis.record.UpdateParam("W", <number>globalThis.record.GetParam("W").value + 500);
globalThis.record.UpdateParam("H", <number>globalThis.record.GetParam("H").value + 500);
GetDefaultTemplate().UpdateParam("L", <number>GetDefaultTemplate().GetParam("L").value + 500);
GetDefaultTemplate().UpdateParam("W", <number>GetDefaultTemplate().GetParam("W").value + 500);
GetDefaultTemplate().UpdateParam("H", <number>GetDefaultTemplate().GetParam("H").value + 500);
}
}
export class UpdateAction
{
async exec()
{
let templates = app.m_Database.TemplateTable.Objects;
if (templates.length === 0)
{
app.m_Editor.Prompt("当前不存在模版")
return;
}
let template = globalThis.template = templates[0];
let keyRes = await app.m_Editor.GetKeyWords({
KeyWordList: template.Params.map(p =>
{
return {
key: p.name,
msg: `当前值${p.value}`
}
})
});
if (keyRes.Status === PromptStatus.Keyword)
{
let paramname = keyRes.StringResult;
let param = template.GetParam(paramname);
let newV = await app.m_Editor.GetDistance({ Msg: "新值!", Default: param.value as number });
if (newV.Status === PromptStatus.OK)
{
param.UpdateParam(newV.Distance);
}
}
}
}
@ -503,14 +852,16 @@ export class Clear
{
async exec()
{
globalThis.record.GetParam("L").actions.length = 0;
globalThis.record.GetParam("L").value = 0;
GetDefaultTemplate().GetParam("L").actions.length = 0;
GetDefaultTemplate().GetParam("L").actions.push(new TemplateAction())
GetDefaultTemplate().GetParam("L").value = 0;
}
}
commandMachine.RegisterCommand("al", new AddTemplateAction("L"));
commandMachine.RegisterCommand("aw", new AddTemplateAction("W"));
commandMachine.RegisterCommand("ah", new AddTemplateAction("H"));
commandMachine.RegisterCommand("uu", new UpdateAction());
commandMachine.RegisterCommand("test", new TestAction);
commandMachine.RegisterCommand("clear", new Clear);

@ -1,7 +1,8 @@
import { ObjectId } from "./ObjectId";
import { Factory } from "./CADFactory";
import { ObjectCollection } from "./ObjectCollection";
import { TemplateRecord } from "./TemplateRecord";
export class TemplateTable
@Factory
export class TemplateTable extends ObjectCollection<TemplateRecord>
{
templates: ObjectId[];
}

Loading…
Cancel
Save