|
|
|
@ -1,4 +1,3 @@
|
|
|
|
|
|
|
|
|
|
import { ArrayRemove } from '../../src/Common/Utils';
|
|
|
|
|
import { Vector3 } from 'three';
|
|
|
|
|
/*
|
|
|
|
@ -107,7 +106,7 @@ id只有在一个情况下才会更新.跨文档复制时.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//CAD对象工厂,通过注册 和暴露的创建方法,动态创建对象
|
|
|
|
|
class CADFactory
|
|
|
|
|
export class CADFactory
|
|
|
|
|
{
|
|
|
|
|
private constructor() { }
|
|
|
|
|
private objectNameMap = new Map<string, () => CADObject>();
|
|
|
|
@ -128,7 +127,7 @@ class CADFactory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//所有cad对象的基类
|
|
|
|
|
class CADObject
|
|
|
|
|
export class CADObject
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//#region -------------------------DB-------------------------
|
|
|
|
@ -234,7 +233,7 @@ class CADObject
|
|
|
|
|
let index = file.Read();
|
|
|
|
|
if (index >= 0 && this._db)
|
|
|
|
|
{
|
|
|
|
|
return this._db.GetObjectId(index);
|
|
|
|
|
return ObjectId.Create(this._db, index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -246,7 +245,7 @@ CADObject对象拥有Id属性,用来记录引用关系.
|
|
|
|
|
ObjectId必须使用 Database分配(db里面会存id的列表,以便同时更新id指向实体)
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
class ObjectId
|
|
|
|
|
export class ObjectId
|
|
|
|
|
{
|
|
|
|
|
private id: number;
|
|
|
|
|
private obj: CADObject;
|
|
|
|
@ -270,12 +269,12 @@ class ObjectId
|
|
|
|
|
3.对象redo创建时
|
|
|
|
|
4.引用读取时
|
|
|
|
|
*/
|
|
|
|
|
static Create(db: Database, index: number, obj: CADObject): ObjectId
|
|
|
|
|
static Create(db: Database, index: number): ObjectId
|
|
|
|
|
{
|
|
|
|
|
let id = db.GetObjectId(index);
|
|
|
|
|
if (!id)
|
|
|
|
|
{
|
|
|
|
|
id = new ObjectId(index, obj);
|
|
|
|
|
id = new ObjectId(index);
|
|
|
|
|
db.SetObjectId(index, id);
|
|
|
|
|
}
|
|
|
|
|
return id;
|
|
|
|
@ -296,10 +295,15 @@ class ObjectId
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//cad文件数据
|
|
|
|
|
class CADFile
|
|
|
|
|
export class CADFile
|
|
|
|
|
{
|
|
|
|
|
private readIndex: number = 0;
|
|
|
|
|
private dataList: any[] = [];
|
|
|
|
|
|
|
|
|
|
Rest()
|
|
|
|
|
{
|
|
|
|
|
this.readIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
WriteString(str: string)
|
|
|
|
|
{
|
|
|
|
|
this.dataList.push(str);
|
|
|
|
@ -334,12 +338,15 @@ class CADFile
|
|
|
|
|
this.readIndex++;
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
ToString()
|
|
|
|
|
{
|
|
|
|
|
return JSON.stringify(this.dataList);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AppendData extends CADObject
|
|
|
|
|
export class AppendData extends CADObject
|
|
|
|
|
{
|
|
|
|
|
private object: CADObject;
|
|
|
|
|
private cadFile: CADFile;
|
|
|
|
|
constructor(obj: CADObject)
|
|
|
|
|
{
|
|
|
|
@ -350,12 +357,9 @@ class AppendData extends CADObject
|
|
|
|
|
|
|
|
|
|
getObject(db: Database): CADObject
|
|
|
|
|
{
|
|
|
|
|
if (!this.object)
|
|
|
|
|
{
|
|
|
|
|
this.object = this.cadFile.ReadObject(db);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.object;
|
|
|
|
|
let obj = this.cadFile.ReadObject(db);
|
|
|
|
|
this.cadFile.Rest();
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//#region -----------------------------File-----------------------------
|
|
|
|
@ -376,7 +380,7 @@ class AppendData extends CADObject
|
|
|
|
|
{ }
|
|
|
|
|
//#endregion -----------------------------File End-----------------------------
|
|
|
|
|
}
|
|
|
|
|
class RemoveData extends CADObject
|
|
|
|
|
export class RemoveData extends CADObject
|
|
|
|
|
{
|
|
|
|
|
private index: number;
|
|
|
|
|
constructor(index?: number)
|
|
|
|
@ -409,9 +413,9 @@ class RemoveData extends CADObject
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//对象集合.
|
|
|
|
|
class ObjectCollection<T> extends CADObject
|
|
|
|
|
export class ObjectCollection<T> extends CADObject
|
|
|
|
|
{
|
|
|
|
|
private objectCol: CADObject[] = [];
|
|
|
|
|
objectCol: CADObject[] = [];
|
|
|
|
|
|
|
|
|
|
//添加一个对象进入集合,这个集合存在db中,那么将自动分配id.
|
|
|
|
|
Append(obj: CADObject)
|
|
|
|
@ -423,7 +427,6 @@ class ObjectCollection<T> extends CADObject
|
|
|
|
|
obj.InitObjectId(this._db);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this._db && this._db.hm.UndoData)
|
|
|
|
|
{
|
|
|
|
|
let hisRec = new HistoricRecord();
|
|
|
|
@ -468,10 +471,26 @@ class ObjectCollection<T> extends CADObject
|
|
|
|
|
}
|
|
|
|
|
//对象从文件中读取数据,初始化自身
|
|
|
|
|
FileIn(file: CADFile)
|
|
|
|
|
{ }
|
|
|
|
|
{
|
|
|
|
|
super.FileIn(file);
|
|
|
|
|
let cout = file.Read();
|
|
|
|
|
this.objectCol = [];
|
|
|
|
|
for (let i = 0; i < cout; i++)
|
|
|
|
|
{
|
|
|
|
|
let obj = file.ReadObject(this._db);
|
|
|
|
|
this.objectCol.push(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//对象将自身数据写入到文件.
|
|
|
|
|
FileOut(file: CADFile)
|
|
|
|
|
{ }
|
|
|
|
|
{
|
|
|
|
|
super.FileOut(file);
|
|
|
|
|
file.Write(this.objectCol.length);
|
|
|
|
|
for (let obj of this.objectCol)
|
|
|
|
|
{
|
|
|
|
|
file.WriteObject(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//局部撤销
|
|
|
|
|
ApplyPartialUndo(undoData: CADObject)
|
|
|
|
|
{
|
|
|
|
@ -489,7 +508,7 @@ class ObjectCollection<T> extends CADObject
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//命令历史记录集合
|
|
|
|
|
class CommandHistoryRecord extends CADObject
|
|
|
|
|
export class CommandHistoryRecord extends CADObject
|
|
|
|
|
{
|
|
|
|
|
constructor(cmdName: string)
|
|
|
|
|
{
|
|
|
|
@ -527,7 +546,7 @@ class CommandHistoryRecord extends CADObject
|
|
|
|
|
* @class HistoricRecord
|
|
|
|
|
* @extends {CADObject}
|
|
|
|
|
*/
|
|
|
|
|
class HistoricRecord extends CADObject
|
|
|
|
|
export class HistoricRecord extends CADObject
|
|
|
|
|
{
|
|
|
|
|
//指定撤销时所需要的数据
|
|
|
|
|
undoData: CADObject;
|
|
|
|
@ -537,10 +556,10 @@ class HistoricRecord extends CADObject
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//历史记录管理
|
|
|
|
|
class HistoricManage extends CADObject
|
|
|
|
|
export class HistoricManage extends CADObject
|
|
|
|
|
{
|
|
|
|
|
private curIndex: number = -1; //当前执行位置
|
|
|
|
|
private historyRecord: CommandHistoryRecord[] = []; //历史记录
|
|
|
|
|
curIndex: number = -1; //当前执行位置,也就是当前的状态, undo时,撤销当前状态,redo时,应用下一个状态
|
|
|
|
|
historyRecord: CommandHistoryRecord[] = []; //历史记录
|
|
|
|
|
private doing: boolean = false;
|
|
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
@ -553,7 +572,7 @@ class HistoricManage extends CADObject
|
|
|
|
|
{
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
if (this.historyRecord.length === 0)
|
|
|
|
|
if (this.historyRecord.length === 0 || this.curIndex != this.historyRecord.length - 1)
|
|
|
|
|
{
|
|
|
|
|
this.StartCmd("");
|
|
|
|
|
}
|
|
|
|
@ -562,7 +581,8 @@ class HistoricManage extends CADObject
|
|
|
|
|
|
|
|
|
|
StartCmd(cmdName: string)
|
|
|
|
|
{
|
|
|
|
|
this.historyRecord.splice(this.curIndex, this.historyRecord.length - this.curIndex);
|
|
|
|
|
//删除当前状态以后的所有状态
|
|
|
|
|
this.historyRecord.splice(this.curIndex + 1, this.historyRecord.length - (this.curIndex + 1));
|
|
|
|
|
this.historyRecord.push(new CommandHistoryRecord(cmdName));
|
|
|
|
|
this.curIndex = this.historyRecord.length - 1;
|
|
|
|
|
}
|
|
|
|
@ -578,9 +598,9 @@ class HistoricManage extends CADObject
|
|
|
|
|
for (let [id, recList] of historyRec.HistoryList)
|
|
|
|
|
{
|
|
|
|
|
let obj = id.Object;
|
|
|
|
|
for (let rec of recList)
|
|
|
|
|
for (let i = recList.length; i--;)
|
|
|
|
|
{
|
|
|
|
|
obj.ApplyPartialUndo(rec.undoData);
|
|
|
|
|
obj.ApplyPartialUndo(recList[i].undoData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.curIndex--;
|
|
|
|
@ -598,9 +618,9 @@ class HistoricManage extends CADObject
|
|
|
|
|
for (let [id, recList] of historyRec.HistoryList)
|
|
|
|
|
{
|
|
|
|
|
let obj = id.Object;
|
|
|
|
|
for (let i = recList.length; i--;)
|
|
|
|
|
for (let rec of recList)
|
|
|
|
|
{
|
|
|
|
|
obj.ApplyPartialUndo(recList[i].redoData);
|
|
|
|
|
obj.ApplyPartialUndo(rec.redoData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.curIndex++;
|
|
|
|
@ -609,8 +629,7 @@ class HistoricManage extends CADObject
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Database
|
|
|
|
|
export class Database
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
hm: HistoricManage;
|
|
|
|
@ -620,9 +639,6 @@ class Database
|
|
|
|
|
ModelSpace: BlockTableRecord;
|
|
|
|
|
//材质字典...
|
|
|
|
|
|
|
|
|
|
objectCol = new Map<number, CADObject>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private idCout = -1;
|
|
|
|
|
private idMap = new Map<number, ObjectId>();
|
|
|
|
|
|
|
|
|
@ -633,36 +649,29 @@ class Database
|
|
|
|
|
this.hm = new HistoricManage();
|
|
|
|
|
this.hm.SetDefaultDb(this);
|
|
|
|
|
}
|
|
|
|
|
getObject(id: number): CADObject
|
|
|
|
|
{
|
|
|
|
|
return this.objectCol.get(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
appendObject(obj: CADObject)
|
|
|
|
|
FileOut(): CADFile
|
|
|
|
|
{
|
|
|
|
|
let id = this.objectCol.size;
|
|
|
|
|
this.objectCol.set(id, obj);
|
|
|
|
|
let file = new CADFile();
|
|
|
|
|
file.Write(1);//ver;
|
|
|
|
|
file.Write(this.idCout);
|
|
|
|
|
this.ModelSpace.FileOut(file);
|
|
|
|
|
return file;
|
|
|
|
|
}
|
|
|
|
|
ApplyPartialUndo(data)
|
|
|
|
|
FileIn(file: CADFile)
|
|
|
|
|
{
|
|
|
|
|
switch (data)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
// this.objectCol.get(data.i).IsErase = true;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
// this.objectCol.get(data.i).isErase = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
let ver = file.Read();
|
|
|
|
|
this.idCout = file.Read();
|
|
|
|
|
this.ModelSpace.FileIn(file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建一个id,自动递增它的索引号,并且会自动加入到db的id列表中.
|
|
|
|
|
AllocateId(obj: CADObject): ObjectId
|
|
|
|
|
{
|
|
|
|
|
if (obj.Db === this)
|
|
|
|
|
{
|
|
|
|
|
this.idCout++;
|
|
|
|
|
let id = ObjectId.Create(this, this.idCout, obj);
|
|
|
|
|
let id = ObjectId.Create(this, this.idCout);
|
|
|
|
|
id.Object = obj;
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -696,7 +705,7 @@ class Database
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class BlockTableRecord extends ObjectCollection<Entity>
|
|
|
|
|
export class BlockTableRecord extends ObjectCollection<Entity>
|
|
|
|
|
{
|
|
|
|
|
constructor()
|
|
|
|
|
{
|
|
|
|
@ -712,10 +721,14 @@ class BlockTableRecord extends ObjectCollection<Entity>
|
|
|
|
|
}
|
|
|
|
|
//对象从文件中读取数据,初始化自身
|
|
|
|
|
FileIn(file: CADFile)
|
|
|
|
|
{ }
|
|
|
|
|
{
|
|
|
|
|
super.FileIn(file);
|
|
|
|
|
}
|
|
|
|
|
//对象将自身数据写入到文件.
|
|
|
|
|
FileOut(file: CADFile)
|
|
|
|
|
{ }
|
|
|
|
|
{
|
|
|
|
|
super.FileOut(file);
|
|
|
|
|
}
|
|
|
|
|
//局部撤销
|
|
|
|
|
ApplyPartialUndo(file: CADObject)
|
|
|
|
|
{
|
|
|
|
@ -724,26 +737,20 @@ class BlockTableRecord extends ObjectCollection<Entity>
|
|
|
|
|
//#endregion-----------------------------File End-----------------------------
|
|
|
|
|
}
|
|
|
|
|
//所有图元的基类
|
|
|
|
|
class Entity extends CADObject
|
|
|
|
|
export class Entity extends CADObject
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//直线撤销类型
|
|
|
|
|
export enum LineUndoType
|
|
|
|
|
{
|
|
|
|
|
Full = 0,
|
|
|
|
|
StartPoint = 1,
|
|
|
|
|
EndPoint = 2,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//直线对象
|
|
|
|
|
class Line extends Entity
|
|
|
|
|
export class Line extends Entity
|
|
|
|
|
{
|
|
|
|
|
private startPoint: Vector3;
|
|
|
|
|
private endPoint: Vector3;
|
|
|
|
|
constructor()
|
|
|
|
|
{
|
|
|
|
|
super();
|
|
|
|
|
this.startPoint = new Vector3(0, 0, 0);
|
|
|
|
|
this.endPoint = new Vector3(0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------File-----------------------------
|
|
|
|
@ -759,25 +766,20 @@ class Line extends Entity
|
|
|
|
|
FileIn(file: CADFile)
|
|
|
|
|
{
|
|
|
|
|
super.FileIn(file);
|
|
|
|
|
let ver = file.Read();
|
|
|
|
|
this.startPoint.fromArray(file.Read());
|
|
|
|
|
this.endPoint.fromArray(file.Read());
|
|
|
|
|
}
|
|
|
|
|
//对象将自身数据写入到文件.
|
|
|
|
|
FileOut(file: CADFile)
|
|
|
|
|
{
|
|
|
|
|
super.FileOut(file);
|
|
|
|
|
file.Write(1);//ver
|
|
|
|
|
file.Write(this.startPoint.toArray());
|
|
|
|
|
file.Write(this.endPoint.toArray());
|
|
|
|
|
}
|
|
|
|
|
ApplyPartialUndo(data)
|
|
|
|
|
{
|
|
|
|
|
switch (data.type)
|
|
|
|
|
{
|
|
|
|
|
case LineUndoType.Full:
|
|
|
|
|
break;
|
|
|
|
|
case LineUndoType.StartPoint:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//-----------------------------File End-----------------------------
|
|
|
|
|
|
|
|
|
@ -790,61 +792,16 @@ class Line extends Entity
|
|
|
|
|
{
|
|
|
|
|
return this.startPoint.clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get EndPoint(): Vector3
|
|
|
|
|
{
|
|
|
|
|
return this.endPoint;
|
|
|
|
|
}
|
|
|
|
|
set EndPoint(v: Vector3)
|
|
|
|
|
{
|
|
|
|
|
this.endPoint = v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CADFactory.RegisterObject(Line);
|
|
|
|
|
|
|
|
|
|
test('工厂构造实体', () =>
|
|
|
|
|
{
|
|
|
|
|
let l = CADFactory.CreateObject("Line") as Line;
|
|
|
|
|
|
|
|
|
|
expect(l != undefined).toBeTruthy();
|
|
|
|
|
expect(l.ClassName).toBe("Line");
|
|
|
|
|
expect(l.Id).toBeUndefined();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test('id分配', () =>
|
|
|
|
|
{
|
|
|
|
|
let db = new Database();
|
|
|
|
|
let line = new Line();
|
|
|
|
|
let id = db.ModelSpace.Append(line);
|
|
|
|
|
|
|
|
|
|
expect(id != undefined).toBeTruthy();
|
|
|
|
|
expect(id.Object === line).toBeTruthy();
|
|
|
|
|
|
|
|
|
|
db.hm.Undo();
|
|
|
|
|
|
|
|
|
|
expect(id.IsErase).toBeTruthy();
|
|
|
|
|
expect(db.ModelSpace.Cout()).toBe(0);
|
|
|
|
|
|
|
|
|
|
db.hm.Redo();
|
|
|
|
|
|
|
|
|
|
expect(db.ModelSpace.Cout()).toBe(1);
|
|
|
|
|
expect(!id.IsErase).toBeTruthy();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// function createLine()
|
|
|
|
|
// {
|
|
|
|
|
// for (let i = 0; i < 5000; i++)
|
|
|
|
|
// {
|
|
|
|
|
// let l = CADFactory.CreateObject("Line") as Line;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // createLine(); //?.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// function undoRedo()
|
|
|
|
|
// {
|
|
|
|
|
// for (let i = 0; i < 5000; i++)
|
|
|
|
|
// {
|
|
|
|
|
// db.hm.Undo();
|
|
|
|
|
// db.hm.Redo();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // undoRedo(); //?.
|