|
|
|
@ -29,65 +29,55 @@ import * as THREE from 'three';
|
|
|
|
|
创建对象如何撤销和重做?
|
|
|
|
|
db.AppendEntity(ent);
|
|
|
|
|
|
|
|
|
|
当我们删除对象时,尝试只对对象进行标记删除.
|
|
|
|
|
当历史记录被优化时,我们尝试对删除的对象进行彻底删除
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 所有cad对象的基类
|
|
|
|
|
*
|
|
|
|
|
* @class CADObject
|
|
|
|
|
*/
|
|
|
|
|
//所有cad对象的基类
|
|
|
|
|
class CADObject
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* 局部撤销
|
|
|
|
|
*
|
|
|
|
|
* @param {number} type
|
|
|
|
|
* @param {*} data
|
|
|
|
|
* @memberof CADObject
|
|
|
|
|
*/
|
|
|
|
|
ApplyPartialUndo(type: number, data: any)
|
|
|
|
|
|
|
|
|
|
//对象是否已经被删除
|
|
|
|
|
private isErase: boolean = false;
|
|
|
|
|
|
|
|
|
|
get IsErase(): boolean
|
|
|
|
|
{
|
|
|
|
|
return this.isErase;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DataIn(data)
|
|
|
|
|
{
|
|
|
|
|
//-----------------------------File-----------------------------
|
|
|
|
|
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
|
|
|
|
|
|
|
|
|
|
//对象从文件中读取数据,初始化自身
|
|
|
|
|
FileIn(file: CADFile)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
DataOut()
|
|
|
|
|
//对象将自身数据写入到文件.
|
|
|
|
|
FileOut(file: CADFile)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
//局部撤销
|
|
|
|
|
ApplyPartialUndo(file: CADFile)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* cad文件数据
|
|
|
|
|
*
|
|
|
|
|
* @class CADFile
|
|
|
|
|
*/
|
|
|
|
|
//cad文件数据
|
|
|
|
|
class CADFile
|
|
|
|
|
{
|
|
|
|
|
databaseData; //图纸数据
|
|
|
|
|
objectDataCol: any[]; //对象集合
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class HistoricManage
|
|
|
|
|
{
|
|
|
|
|
curIndex: number; //当前执行位置
|
|
|
|
|
historicRecord: CommandHistoricRecord[];//历史记录
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//命令历史记录集合
|
|
|
|
|
class CommandHistoricRecord
|
|
|
|
|
class CommandHistoricRecord extends CADObject
|
|
|
|
|
{
|
|
|
|
|
//命令名称
|
|
|
|
|
commandName: string;
|
|
|
|
|
//历史记录表
|
|
|
|
|
historicCol: CommandHistoricRecord[];
|
|
|
|
|
historicCol: HistoricRecord[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//历史记录
|
|
|
|
@ -98,102 +88,114 @@ class HistoricRecord
|
|
|
|
|
redoData: any;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @class HistoryManager
|
|
|
|
|
*/
|
|
|
|
|
class HistoryManager extends CADObject
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
private curUndoIndex = -1;
|
|
|
|
|
//命令撤销数据列表
|
|
|
|
|
commandUndoData: { cmdName: string, undoData: Map<CADObject, UndoFile> }[] = [];
|
|
|
|
|
|
|
|
|
|
get UndoData(): Map<CADObject, UndoFile>
|
|
|
|
|
class HistoricManage
|
|
|
|
|
{
|
|
|
|
|
m_Db: Database;
|
|
|
|
|
curIndex: number = -1; //当前执行位置
|
|
|
|
|
historicRecord: CommandHistoricRecord[] = [];//历史记录
|
|
|
|
|
get UndoData(): CommandHistoricRecord
|
|
|
|
|
{
|
|
|
|
|
if (this.commandUndoData.length == 0)
|
|
|
|
|
if (this.historicRecord.length == 0)
|
|
|
|
|
{
|
|
|
|
|
this.startCmd("");
|
|
|
|
|
}
|
|
|
|
|
return this.commandUndoData[this.commandUndoData.length - 1].undoData;
|
|
|
|
|
return this.historicRecord[this.historicRecord.length - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startCmd(cmdName: string)
|
|
|
|
|
{
|
|
|
|
|
this.commandUndoData.splice(this.curUndoIndex, this.commandUndoData.length - this.curUndoIndex);
|
|
|
|
|
this.commandUndoData.push({ cmdName: "", undoData: new Map<CADObject, UndoFile>() });
|
|
|
|
|
this.curUndoIndex = this.commandUndoData.length - 1;
|
|
|
|
|
this.historicRecord.splice(this.curIndex, this.historicRecord.length - this.curIndex);
|
|
|
|
|
this.historicRecord.push(new CommandHistoricRecord());
|
|
|
|
|
this.curIndex = this.historicRecord.length - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Undo(cout: number)
|
|
|
|
|
Undo()
|
|
|
|
|
{
|
|
|
|
|
let undoFile = this.commandUndoData[this.curUndoIndex];
|
|
|
|
|
if (!undoFile)
|
|
|
|
|
let historicRec = this.historicRecord[this.curIndex];
|
|
|
|
|
if (!historicRec)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let [obj, data] of undoFile.undoData)
|
|
|
|
|
let recList = historicRec.historicCol;
|
|
|
|
|
for (let i = recList.length; i--;)
|
|
|
|
|
{
|
|
|
|
|
for (let i = data.m_UndoDataList.length; i--;)
|
|
|
|
|
{
|
|
|
|
|
let d = data.m_UndoDataList[i];
|
|
|
|
|
obj.ApplyPartialUndo(d.type, d.undoData);
|
|
|
|
|
}
|
|
|
|
|
let data = recList[i];
|
|
|
|
|
let obj = this.m_Db.getObject(data.objectId);
|
|
|
|
|
obj.ApplyPartialUndo(data.undoData);
|
|
|
|
|
}
|
|
|
|
|
this.curUndoIndex--;
|
|
|
|
|
this.curIndex--;
|
|
|
|
|
}
|
|
|
|
|
Redo(cout: number)
|
|
|
|
|
{
|
|
|
|
|
let undoFile = this.commandUndoData[this.curUndoIndex + 1];
|
|
|
|
|
if (!undoFile)
|
|
|
|
|
let undoData = this.historicRecord[this.curIndex + 1];
|
|
|
|
|
if (!undoData)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for (let [obj, data] of undoFile.undoData)
|
|
|
|
|
for (let rec of undoData.historicCol)
|
|
|
|
|
{
|
|
|
|
|
for (let d of data.m_UndoDataList)
|
|
|
|
|
{
|
|
|
|
|
obj.ApplyPartialUndo(d.type, d.redoData);
|
|
|
|
|
}
|
|
|
|
|
let obj = this.m_Db.getObject(rec.objectId);
|
|
|
|
|
obj.ApplyPartialUndo(rec.redoData);
|
|
|
|
|
}
|
|
|
|
|
this.curUndoIndex++;
|
|
|
|
|
this.curIndex++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Database
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
class Database extends CADObject
|
|
|
|
|
{
|
|
|
|
|
className: "Database";
|
|
|
|
|
hm: HistoricManage;
|
|
|
|
|
//块表记录
|
|
|
|
|
blockTableCol: BlockTableRecord[];
|
|
|
|
|
//材质字典
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
objectCol = new Map<number, CADObject>();
|
|
|
|
|
constructor()
|
|
|
|
|
{
|
|
|
|
|
super();
|
|
|
|
|
this.objectCol.set(0, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getObject(id: number): CADObject
|
|
|
|
|
{
|
|
|
|
|
return this.objectCol.get(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class BlockTableRecord extends CADObject
|
|
|
|
|
{
|
|
|
|
|
//对象池. 管理所有的对象
|
|
|
|
|
objectMap = new Map<number, CADObject>();
|
|
|
|
|
}
|
|
|
|
|
appendObject(obj: CADObject)
|
|
|
|
|
{
|
|
|
|
|
let id = this.objectCol.size;
|
|
|
|
|
this.objectCol.set(id, obj);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* @class UndoFile
|
|
|
|
|
*/
|
|
|
|
|
class UndoFile
|
|
|
|
|
{
|
|
|
|
|
m_UndoDataList: UndoData[] = [];
|
|
|
|
|
this.hm.UndoData.historicCol.push(
|
|
|
|
|
{
|
|
|
|
|
objectId: 0,
|
|
|
|
|
undoData: { type: 1, i: id },//remove
|
|
|
|
|
redoData: { type: 2, i: id },//add
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
ApplyPartialUndo(data)
|
|
|
|
|
{
|
|
|
|
|
switch (data)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
// this.objectCol.get(data.i).IsErase = true;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
// this.objectCol.get(data.i).isErase = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface UndoData
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BlockTableRecord extends CADObject
|
|
|
|
|
{
|
|
|
|
|
type: number;
|
|
|
|
|
undoData: any;
|
|
|
|
|
redoData: any;
|
|
|
|
|
userData?: any;
|
|
|
|
|
objectMap = new Map<number, CADObject>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -218,38 +220,10 @@ interface EntityData
|
|
|
|
|
*/
|
|
|
|
|
class Entity extends CADObject
|
|
|
|
|
{
|
|
|
|
|
protected m_Data: EntityData;
|
|
|
|
|
m_Db: HistoryManager;
|
|
|
|
|
m_Db: Database;
|
|
|
|
|
constructor()
|
|
|
|
|
{
|
|
|
|
|
super();
|
|
|
|
|
this.m_Data = {
|
|
|
|
|
id: -1,
|
|
|
|
|
isErase: false
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get UndoFile(): UndoFile
|
|
|
|
|
{
|
|
|
|
|
if (this.m_Db)
|
|
|
|
|
{
|
|
|
|
|
let undoData = this.m_Db.UndoData;
|
|
|
|
|
if (!undoData.has(this))
|
|
|
|
|
{
|
|
|
|
|
undoData.set(this, new UndoFile());
|
|
|
|
|
}
|
|
|
|
|
return undoData.get(this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WriteUndoData(data: UndoData)
|
|
|
|
|
{
|
|
|
|
|
let undoFile = this.UndoFile;
|
|
|
|
|
if (undoFile)
|
|
|
|
|
{
|
|
|
|
|
undoFile.m_UndoDataList.push(data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -280,35 +254,17 @@ interface LineData extends EntityData
|
|
|
|
|
*/
|
|
|
|
|
class Line extends Entity
|
|
|
|
|
{
|
|
|
|
|
protected m_Data: LineData;
|
|
|
|
|
constructor()
|
|
|
|
|
{
|
|
|
|
|
super();
|
|
|
|
|
this.m_Data.startPoint = [0, 0, 0];
|
|
|
|
|
this.m_Data.endPoint = [0, 0, 0];
|
|
|
|
|
}
|
|
|
|
|
get StartPoint(): number[]
|
|
|
|
|
{
|
|
|
|
|
return this.m_Data.startPoint;
|
|
|
|
|
}
|
|
|
|
|
set StartPoint(value: number[])
|
|
|
|
|
{
|
|
|
|
|
this.WriteUndoData({
|
|
|
|
|
type: LineUndoType.StartPoint,
|
|
|
|
|
undoData: { startPoint: this.m_Data.startPoint },
|
|
|
|
|
redoData: { startPoint: value }
|
|
|
|
|
});
|
|
|
|
|
this.m_Data.startPoint = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ApplyPartialUndo(type, data)
|
|
|
|
|
ApplyPartialUndo(data)
|
|
|
|
|
{
|
|
|
|
|
switch (type)
|
|
|
|
|
switch (data.type)
|
|
|
|
|
{
|
|
|
|
|
case LineUndoType.Full:
|
|
|
|
|
break;
|
|
|
|
|
case LineUndoType.StartPoint:
|
|
|
|
|
this.m_Data.startPoint = data.startPoint;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
@ -357,88 +313,4 @@ class LineAdapter extends EentiyDrawAdapter
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let line = new Line();
|
|
|
|
|
|
|
|
|
|
console.log(line);
|
|
|
|
|
|
|
|
|
|
line.StartPoint = [1, 2, 3];
|
|
|
|
|
|
|
|
|
|
console.log(line);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let db = new HistoryManager();
|
|
|
|
|
|
|
|
|
|
line.m_Db = db;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
line.StartPoint = [3, 3, 3];
|
|
|
|
|
|
|
|
|
|
line.StartPoint = [3, 3, 5];
|
|
|
|
|
|
|
|
|
|
line.StartPoint = [12, 3, 5];
|
|
|
|
|
|
|
|
|
|
db.Undo(1);
|
|
|
|
|
|
|
|
|
|
console.log(line.StartPoint);
|
|
|
|
|
|
|
|
|
|
db.Redo(1);
|
|
|
|
|
|
|
|
|
|
db.startCmd("");
|
|
|
|
|
|
|
|
|
|
console.log(line.StartPoint);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function per()
|
|
|
|
|
{
|
|
|
|
|
for (let i = 0; i < 5000; i++)
|
|
|
|
|
{
|
|
|
|
|
new Line();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function per2()
|
|
|
|
|
{
|
|
|
|
|
for (let i = 0; i < 5000; i++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
line.StartPoint = [3, 3, 3];
|
|
|
|
|
|
|
|
|
|
// console.log(line);
|
|
|
|
|
// line.StartPoint = [3, 3, 5];
|
|
|
|
|
|
|
|
|
|
line.StartPoint = [12, 3, 5];
|
|
|
|
|
// console.log(line);
|
|
|
|
|
|
|
|
|
|
// console.log(db.commandUndoData);
|
|
|
|
|
|
|
|
|
|
db.Undo(1);
|
|
|
|
|
|
|
|
|
|
// console.log(line);
|
|
|
|
|
|
|
|
|
|
db.Redo(1);
|
|
|
|
|
|
|
|
|
|
db.startCmd("");
|
|
|
|
|
|
|
|
|
|
// console.log(line.StartPoint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// per();/*?.*/
|
|
|
|
|
// per2();/*?.*/
|
|
|
|
|
// per2();/*?.*/
|
|
|
|
|
// per2();/*?.*/
|
|
|
|
|
// per2();/*?.*/
|
|
|
|
|
|
|
|
|
|
// // console.log(3);
|
|
|
|
|
|
|
|
|
|
let undoManage = new HistoricManage();
|
|
|
|
|
|
|
|
|
|
let l = new Line();
|
|
|
|
|
|
|
|
|
|
let ms = new BlockTableRecord();
|
|
|
|
|
|
|
|
|
|
}
|