* 实现依赖收集,提前更新
* 实现模板倒角动作
* 测试模块旋转
* 修正旋转空间时的模版尺寸更新
* 使等分空间可用
* 实现旋转空间定位
* 加入设计说明和模版空间坐标系获取
* 重构变量定义和变量继承
* 实现DIV和POS变量
* 更新基础参数列表
* 相对定位的实现
* 增加模版切割类型
* 增加模版树更新
pull/411/MERGE
ChenX 5 years ago
parent 4637ed011c
commit 2fdae68905

@ -425,7 +425,7 @@ export class FilletUtils
};
}
findNearestPt(pts: Vector3[], target: Vector3): Vector3
FindNearestPt(pts: Vector3[], target: Vector3): Vector3
{
let res = pts[0];
let dis = Infinity;
@ -455,7 +455,7 @@ export class FilletUtils
if (ipts.length > 2)//超过2个则有可能有多余交点
//找最近点
ipts = [this.findNearestPt(ipts, brResPt), this.findNearestPt(ipts, ptResPt)]
ipts = [this.FindNearestPt(ipts, brResPt), this.FindNearestPt(ipts, ptResPt)]
if (ipts.length !== 2)
return "倒角失败!交点个数异常.";

@ -16,7 +16,7 @@ export class TemplateAction
if (this.parent)
this.parent.WriteAllObjectRecord();
}
Update(paramDiff: number | string)
Update(paramDiff: number | string, newValue: number | string)
{
}
//#region -------------------------File-------------------------

@ -0,0 +1,64 @@
import { Factory } from "../../CADFactory";
import { TemplateAction } from "./TemplateAction";
import { CADFiler } from "../../CADFiler";
import { ObjectId } from "../../ObjectId";
import { Board } from "../../Entity/Board";
import { FilletUtils } from "../../../Add-on/FilletUtils";
import { PromptEntityResult } from "../../../Editor/PromptResult";
import { Polyline } from "../../Entity/Polyline";
import { Circle } from "../../Entity/Circle";
@Factory
export class TemplateFilletAction extends TemplateAction
{
constructor(protected _FilletEntity?: ObjectId,
protected _CurveParam1?: number,
protected _CurveParam2?: number
)
{
super();
}
Update(paramDiff: number | string, newValue: number | string)
{
if (this._FilletEntity.IsErase) return;
let br = this._FilletEntity.Object as Board;
let cu = br.ContourCurve;
if (cu instanceof Circle)
return;
let fillet = new FilletUtils();
fillet.FilletRadius = newValue as number;
let p1 = cu.GetPointAtParam(this._CurveParam1);
let p2 = cu.GetPointAtParam(this._CurveParam2);
let res1 = new PromptEntityResult(cu, p1);
let res2 = new PromptEntityResult(cu, p2);
let fres = fillet.FilletPolyLineSelf(res1, res2);
if (fres)
br.ContourCurve = fres.cu1 as Polyline;
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFiler)
{
let ver = file.Read();
this._FilletEntity = file.ReadObjectId();
this._CurveParam1 = file.Read();
this._CurveParam2 = file.Read();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
file.Write(1);
file.WriteObjectId(this._FilletEntity);
file.Write(this._CurveParam1);
file.Write(this._CurveParam2);
}
}

@ -1,33 +0,0 @@
import { app } from "../../../ApplicationServices/Application";
import { FixIndex } from "../../../Common/Utils";
import { TemplateRecord } from "../TemplateRecord";
import { GetDefaultTemplate } from "../TemplateTest";
export class TestTemplateAction
{
time;
exec()
{
if (this.time)
{
clearInterval(this.time);
this.time = undefined;
return;
}
let params = ["L", "W", "H"];
let paramIndex = 0;
let record = GetDefaultTemplate() as TemplateRecord;
let count = 1;
this.time = setInterval(() =>
{
count++;
if (count === 100)
{
count = 0;
paramIndex = FixIndex(paramIndex + 1, 3);
}
let param = record.GetParam(params[paramIndex]);
param.UpdateParam(Math.abs(count * 10 - 500));
app.Editor.UpdateScreen();
}, 16);
}
}

@ -5,6 +5,7 @@ import { CADFiler } from "../../CADFiler";
import { TemplateRecord } from "../TemplateRecord";
import { TemplateAction } from "../Action/TemplateAction";
import { TemplateParamType } from "./TemplateParamType";
import { eval2 } from "../../../Common/eval";
/**
*
@ -12,9 +13,15 @@ import { TemplateParamType } from "./TemplateParamType";
@Factory
export class TemplateParam
{
/**
*
* (js) `_`,`$`.
*/
@AutoRecord name: string;
@AutoRecord expr: string;
/** 表达式 使用js引起求值(暂时) */
@AutoRecord expr: string | number = "";
/**
* ,
* , UpdateParam
*/
@AutoRecord value: string | number;
@ -55,6 +62,7 @@ export class TemplateParam
if (this.parent)
this.parent.WriteAllObjectRecord();
}
/**
* ,.
* ,`this.value = xxx;`
@ -72,7 +80,7 @@ export class TemplateParam
{
let diff = newV - oldV;
for (let a of this.actions)
a.Update(diff);
a.Update(diff, newV);
this.value = newV;
}
break;
@ -82,6 +90,43 @@ export class TemplateParam
break;
}
}
/**
*
* @param vardefines
* @param paramMap .()
*/
EvalUpdate(vardefines: Object, paramMap: Map<string, TemplateParam>, evaled: Set<TemplateParam>, update = true): number
{
if (this.expr === "") return this.value as number;
if (evaled.has(this)) return this.value as number;
let value = parseFloat(this.expr as string);
if (isNaN(value))
{
//依赖收集 提前更新
let keywords = (<string>this.expr).split(/[\s(){}=+-/*/,%;]/).filter(s => s.length > 0);
for (let key of keywords)
{
if (key !== this.name && paramMap.has(key))
paramMap.get(key).EvalUpdate(vardefines, paramMap, evaled, update);
}
value = eval2(this.expr as string, vardefines);
}
else
this.expr = "";
vardefines[this.name] = value;
if (update)
this.UpdateParam(value);
evaled.add(this);
return value;
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身

@ -12,15 +12,18 @@ export interface PositioningParam
count?: number;
}
/**
* ()
*/
@Factory
export class Positioning implements ISerialize
{
SpaceCS: Matrix4;//空间坐标系
SpaceBox: Box3;//有可能不存在
SpaceSize: Vector3;//有可能不存在
/**
*
* ( SpaceCS SpaceBox SpaceSize)
*/
async Positioning(param?: PositioningParam)
{

@ -41,7 +41,8 @@ export class PositioningClampSpace extends Positioning
if (parse.m_ParseOK)
{
this.SpaceCS = parse.m_SpaceOCS;
this.SpaceBox = parse.m_SpaceBox;
let p = parse.m_SpaceBox.min.clone().applyMatrix4(this.SpaceCS);
this.SpaceCS.setPosition(p);
this.SpaceSize = parse.Size;
}
else

@ -1,3 +1,4 @@
import { Matrix4, Vector3, Math, Box3 } from "three";
import { AutoRecord, ISPROXYKEY } from "../AutoRecord";
import { Factory } from "../CADFactory";
import { CADFiler } from "../CADFiler";
@ -8,16 +9,29 @@ import { SymbolTableRecord } from "../SymbolTableRecord";
import { TemplateParam } from "./Param/TemplateParam";
import { TemplateParamType } from "./Param/TemplateParamType";
import { Positioning } from "./Positioning/Positioning";
import { TemplateType } from "./TemplateType";
import { TemplateSplitType, TemplateType } from "./TemplateType";
/**
*
* ,,
* ###
* ,,
*
* : L W H RX RY RZ X Y Z
* : _ $
*
* #### .
* expr,(value).,.
* ,expr.(valueexpr).
*
* `DIV`,`LWH`,()
*
* ,,(,)
*
*/
@Factory
export class TemplateRecord extends SymbolTableRecord
{
@AutoRecord Type: TemplateType;
@AutoRecord SplitType = TemplateSplitType.None;
@AutoRecord Parent: ObjectId;
@AutoRecord Children: ObjectId[];
@AutoRecord Params: TemplateParam[];
@ -27,63 +41,48 @@ export class TemplateRecord extends SymbolTableRecord
{
super();
//监听
this.Params = new Proxy([], {
set: (target, key, value, receiver) =>
this.Params = this.CreateProxyArray(
value =>
{
if (Reflect.get(target, key, receiver) !== value)
if (value instanceof TemplateParam)
value.parent = this;
}
);
this.Objects = this.CreateProxyArray(
value =>
{
if (value instanceof ObjectId && value.Object instanceof Entity)
{
this.WriteAllObjectRecord();
if (value instanceof TemplateParam)
value.parent = this;
if (!this.Id)
console.warn("请先加模版添加到Database后在进行操作!");
value.Object.Template = this.Id;
}
return Reflect.set(target, key, value, receiver);
},
get: (target, key, receiver) =>
{
if (key === ISPROXYKEY)
return true;
return Reflect.get(target, key, receiver);
}
});
this.Objects = new Proxy([], {
set: (target, key, value, receiver) =>
);
this.Children = this.CreateProxyArray(
value =>
{
if (Reflect.get(target, key, receiver) !== value)
if (value instanceof ObjectId && value.Object instanceof TemplateRecord)
{
if (this.WriteAllObjectRecord())
{
if (value instanceof ObjectId && value.Object instanceof Entity)
{
if (!this.Id)
console.warn("请先加模版添加到Database后在进行操作!");
value.Object.Template = this.Id;
}
}
if (!this.Id)
console.warn("请先加模版添加到Database后在进行操作!");
value.Object.Parent = this.Id;
}
return Reflect.set(target, key, value, receiver);
},
get: (target, key, receiver) =>
{
if (key === ISPROXYKEY)
return true;
return Reflect.get(target, key, receiver);
}
});
);
}
this.Children = new Proxy([], {
private CreateProxyArray(setCallback: (v: any) => void)
{
return new Proxy([], {
set: (target, key, value, receiver) =>
{
if (Reflect.get(target, key, receiver) !== value)
{
if (this.WriteAllObjectRecord())
{
if (value instanceof ObjectId && value.Object instanceof TemplateRecord)
{
if (!this.Id)
console.warn("请先加模版添加到Database后在进行操作!");
value.Object.Parent = this.Id;
}
}
this.WriteAllObjectRecord();
setCallback(value);
}
return Reflect.set(target, key, value, receiver);
},
@ -96,26 +95,40 @@ export class TemplateRecord extends SymbolTableRecord
});
}
/**
*
*/
get NodeDepth()
Traverse(callback: (arg0: this) => void)
{
let parent = this.Parent;
let depth = 0;
while (parent)
callback(this);
for (let c of this.Children)
{
depth++;
let template = parent.Object as TemplateRecord;
parent = template.Parent;
let template = c.Object as TemplateRecord;
template.Traverse(callback);
}
return depth;
}
private _NodeDepthCache: number;
/** 节点深度,根节点=0 */
get NodeDepth()
{
if (this._NodeDepthCache !== undefined)
return this._NodeDepthCache;
if (!this.Parent) return 0;
let parentTemplate = this.Parent.Object as TemplateRecord;
this._NodeDepthCache = parentTemplate.NodeDepth + 1;
return this._NodeDepthCache;
}
/** 模版定位 */
get Positioning(): Positioning
{
return this.positioning;
}
/**
* ,使.
*/
set Positioning(p: Positioning)
{
this.WriteAllObjectRecord();
@ -123,14 +136,18 @@ export class TemplateRecord extends SymbolTableRecord
this.positioning = p;
}
static SizeParamName = ["L", "W", "H"];
InitSizeParams(length = 0, width = 0, height = 0)
//#region param
static BaseParamName = ["L", "W", "H",
"PX", "PY", "PZ",
"RX", "RY", "RZ"];
/** 初始化基础参数 */
InitBaseParams()
{
let size = [length, width, height];
for (let i = 0; i < 3; i++)
for (let paramName of TemplateRecord.BaseParamName)
{
let paramName = TemplateRecord.SizeParamName[i];
let value = size[i];
let value = 0;
let param = new TemplateParam();
param.name = paramName;
param.type = TemplateParamType.Float;
@ -140,148 +157,337 @@ export class TemplateRecord extends SymbolTableRecord
return this;
}
get LParam()
{
return this.GetParam("L");
}
get WParam()
{
return this.GetParam("W");
}
get HParam()
{
return this.GetParam("H");
}
get LParam() { return this.Params[0]; }
get WParam() { return this.Params[1]; }
get HParam() { return this.Params[2]; }
get PXParam() { return this.Params[3]; }
get PYParam() { return this.Params[4]; }
get PZParam() { return this.Params[5]; }
get RXParam() { return this.Params[6]; }
get RYParam() { return this.Params[7]; }
get RZParam() { return this.Params[8]; }
UpdateAllTemplate(newParams: [])
{
for (let i = 0; i < this.Params.length; i++)
{
let oldParam = this.Params[i];
oldParam.UpdateParam(newParams[i]);
}
}
/**
*
* ,,
*/
UpdateParam(name: string, value: any, expr?: string)
{
let param = this.GetParam(name);
if (param)
{
param.UpdateParam(value);
}
}
GetParam(paramName: string)
GetParam(paramName: string): TemplateParam | undefined
{
for (let param of this.Params)
{
if (param.name === paramName)
return param;
}
return this.Params.find(param => param.name === paramName);
}
/**
*
//#endregion param
/**
* UI,,API.
* see `UpdateTemplateTree`
*
*
*
* ### (,)
*
* - ()()
* ,,.
*
* - [](mobx),`positioning`.
* `positioning`. `LWH`,`XYZ`.
*
* - ()使,,便.
* 使,.
*
* - ():
* .{RX RY RZ}
* ,使,~.()
*
* ###
*
* - `LWH``positioning`,.
*
* - (),().
*
*/
async UpdateTemplate(params?: {}, recursion = false)
private async Update()
{
if (!params)
params = this.GetParentParams();
else
{
let newParams = {};
for (let key in params)
{
if (key[0] !== "@")
newParams["_" + key] = params[key];
else
newParams[key] = params[key];
}
params = newParams;
}
let vardefines = this.GetParameterDefinition(false);
let brs = this.Objects.filter(id => !id.IsErase).map(id => id.Object as Board);
let evaled = new Set<TemplateParam>();
let spaceCS = this.GetTemplateSpaceCS(false);
let spaceSize: Vector3;
let paramMap = new Map<string, TemplateParam>();
for (let param of this.Params)
paramMap.set(param.name, param);
for (let br of brs)
br.ApplyMatrix(br.SpaceOCSInv);
//#region 1.定位(坐标系和大小)
let objs = this.Objects.filter(id => !id.IsErase).map(id => id.Object as Board);
if (this.positioning)
{
await this.positioning.Positioning();
if (!this.positioning.SpaceCS)
return;//出事故
let p = this.positioning.SpaceBox.min.applyMatrix4(this.positioning.SpaceCS);
this.positioning.SpaceCS.setPosition(p);
for (let ent of objs)
{
// let m = ent.SpaceOCSInv.multiply(this.positioning.SpaceCS);
ent.ApplyMatrix(ent.SpaceOCSInv);
ent.ApplyMatrix(this.positioning.SpaceCS);
}
spaceCS = this.positioning.SpaceCS;
spaceSize = this.positioning.SpaceSize;
if (this.positioning.SpaceSize)
{
this.LParam.UpdateParam(this.positioning.SpaceSize.x);
this.WParam.UpdateParam(this.positioning.SpaceSize.y);
this.HParam.UpdateParam(this.positioning.SpaceSize.z);
}
spaceCS = this.RotateSpaceCS(vardefines, evaled, spaceCS, spaceSize);
//更新LWH(通过定位空间)
this.LParam.UpdateParam(spaceSize.x);
this.WParam.UpdateParam(spaceSize.y);
this.HParam.UpdateParam(spaceSize.z);
}
else
{
this.LParam.EvalUpdate(vardefines, paramMap, evaled);
this.WParam.EvalUpdate(vardefines, paramMap, evaled);
this.HParam.EvalUpdate(vardefines, paramMap, evaled);
this.PXParam.EvalUpdate(vardefines, paramMap, evaled);
this.PYParam.EvalUpdate(vardefines, paramMap, evaled);
this.PZParam.EvalUpdate(vardefines, paramMap, evaled);
let l = this.LParam.value as number;
let w = this.WParam.value as number;
let h = this.HParam.value as number;
spaceSize = new Vector3(l, w, h);
//保持SpaceCS
for (let ent of objs)
//相对定位. use PX PY pZ
let baseP = new Vector3(this.PXParam.value as number, this.PYParam.value as number, this.PZParam.value as number);
baseP.applyMatrix4(spaceCS);
spaceCS.setPosition(baseP);
if (!this.Parent)
{
ent.SpaceOCS = this.positioning.SpaceCS;
this.PXParam.value = 0;
this.PXParam.expr = "";
this.PYParam.value = 0;
this.PYParam.expr = "";
this.PZParam.value = 0;
this.PZParam.expr = "";
}
spaceCS = this.RotateSpaceCS(vardefines, evaled, spaceCS, spaceSize);
//更新LWH(通过定位空间)
this.LParam.UpdateParam(spaceSize.x);
this.WParam.UpdateParam(spaceSize.y);
this.HParam.UpdateParam(spaceSize.z);
}
if (recursion)
vardefines["L"] = spaceSize.x;
vardefines["W"] = spaceSize.y;
vardefines["H"] = spaceSize.z;
//#endregion
//#region 3.应用更新到定位空间
//变换到新的模版空间
for (let br of brs)
br.ApplyMatrix(spaceCS);
//#endregion
//更新其他参数变量 Eval local params
for (const param of this.Params)
{
//广度优先
let updateStack = [...this.Children];
let childrenCount = this.Children.length;
let index = 0;
while (updateStack.length > 0)
param.EvalUpdate(vardefines, paramMap, evaled);
}
//保持SpaceCS
for (let ent of brs)
{
ent.SpaceOCS = spaceCS;
}
//Cache
this._CacheParamVars = vardefines;
this._CacheSpaceCS = spaceCS;
}
/**
* ,,SpaceSizeSpaceCS
*/
private RotateSpaceCS(vardefines: any, evaled: Set<TemplateParam>, spaceCS: Matrix4, spaceSize: Vector3)
{
this.RXParam.EvalUpdate(vardefines, this.Params, evaled);
this.RYParam.EvalUpdate(vardefines, this.Params, evaled);
this.RZParam.EvalUpdate(vardefines, this.Params, evaled);
//use RX RY RZ
let rx = Math.degToRad(this.RXParam.value as number);
let ry = Math.degToRad(this.RYParam.value as number);
let rz = Math.degToRad(this.RZParam.value as number);
if (rx !== 0 || ry !== 0 || rz !== 0)
{
let mrx = new Matrix4().makeRotationX(rx);
let mry = new Matrix4().makeRotationY(ry);
let mrz = new Matrix4().makeRotationZ(rz);
let mro = mrz.multiply(mry.multiply(mrx));
let roSpace = mro.multiply(spaceCS);
let roSpaceInv = mrx.getInverse(roSpace); //变量复用
let transfromToRoSpace = roSpaceInv.multiply(spaceCS);
let box = new Box3(new Vector3(), spaceSize.clone());
box.applyMatrix4(transfromToRoSpace);
box.getSize(spaceSize);
let baseP = box.min.clone().applyMatrix4(roSpace);
roSpace.setPosition(baseP);
//更新LWH(通过定位空间)
this.LParam.UpdateParam(spaceSize.x);
this.WParam.UpdateParam(spaceSize.y);
this.HParam.UpdateParam(spaceSize.z);
spaceCS = roSpace;
}
return spaceCS;
}
/** 以广度搜索优先更新节点树 */
async UpdateTemplateTree()
{
let stack: TemplateRecord[] = [this];
await this.Update();
while (stack.length > 0)
{
let template = stack.pop();
//计算DIV(给子空间使用)
if (template.Children.length > 0 && template.SplitType !== TemplateSplitType.None)
{
if (index < childrenCount)
let vardefines = (<TemplateRecord>template.Children[0].Object).GetParameterDefinition();
vardefines._DIV = 0;
let sum = 0;
for (let c of template.Children)
{
params["index"] = index;
params["childrenCount"] = childrenCount;
let ctemplate = c.Object as TemplateRecord;
let param = ctemplate.Params[template.SplitType];
sum += param.EvalUpdate(vardefines, [], new Set(), false);
}
else
let sumDiv = 0;
vardefines._DIV = 1;
for (let c of template.Children)
{
delete params["index"];
delete params["childrenCount"];
let ctemplate = c.Object as TemplateRecord;
let param = ctemplate.Params[template.SplitType];
sum += param.EvalUpdate(vardefines, [], new Set(), false);
}
let id = updateStack.shift();
let template = id.Object as TemplateRecord;
await template.UpdateTemplate(params);
updateStack.push(...template.Children);
let divCount = sum - sumDiv;
if (divCount > 0)
template._CacheParamVars.DIV = (template.Params[template.SplitType].value as number - sum) / divCount;
template._CacheParamVars.POS = 0;
}
for (let c of template.Children)
{
let ctemplate = c.Object as TemplateRecord;
stack.push(ctemplate);
await ctemplate.Update();
index++;
if (template._CacheParamVars.DIV !== undefined)//更新POS
template._CacheParamVars.POS += ctemplate.Params[template.SplitType].value as number;
}
}
}
private GetParentParams()
/** 缓存本节点的变量定义值,当子层需要本层的参数时,可以直接获取 */
private _CacheParamVars: any;
private _CacheSpaceCS: Matrix4;
/**
* .()
* @param [useCache=true] ,使,()
* @returns
*/
private GetParameterDefinition(useCache = true): any
{
let params = {};
let parent = this.Parent;
let index = 1;
while (parent)
if (this._CacheParamVars && useCache)
return this._CacheParamVars;
let vars = this.GetParentParams();
for (const param of this.Params)
{
let parentTemplate = parent.Object as TemplateRecord;
let frontStr = new Array(index).fill("_").join();
for (let param of parentTemplate.Params)
params[frontStr + param.name] = param.value;
if (index === 1)
{
let recordIndex = parentTemplate.Children.indexOf(this.Id);
}
parent = parentTemplate.Parent;
if (!parent)
vars[param.name] = param.value;
if (!this.Parent)
vars["$" + param.name] = param.value;//root
}
this._CacheParamVars = vars;
return vars;
}
/**
*
* - ,`_`
* - `$`
*
* @returns
*/
private GetParentParams(): Object
{
if (!this.Parent) return {};
let parent = this.Parent.Object as TemplateRecord;
let params = parent.GetParameterDefinition();
let newParams = {};
for (let key in params)
{
if (key[0] !== "$")
newParams["_" + key] = params[key];
else
newParams[key] = params[key];
}
params = newParams;
return params;
}
/**
*
* - 使
* - 使
*
* -
*
* @param [useCache=true] ,使,()
*/
private GetTemplateSpaceCS(useCache = true): Matrix4
{
if (useCache && this._CacheSpaceCS)
return this._CacheSpaceCS.clone();
if (this.Parent)
{
let template = this.Parent.Object as TemplateRecord;
return template.GetTemplateSpaceCS();
}
for (let brId of this.Objects)
{
if (brId.Object && !brId.IsErase)
{
for (let param of parentTemplate.Params)
params["@" + param.name] = param.value;
let br = brId.Object as Board;
return br.SpaceOCS;
}
index++;
}
return params;
return new Matrix4();
}
//#region -------------------------File-------------------------
@ -307,11 +513,14 @@ export class TemplateRecord extends SymbolTableRecord
this.Objects.push(file.ReadObjectId());
this.positioning = file.ReadObject();
if (ver > 1)
this.SplitType = file.Read();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
file.Write(1);
file.Write(2);
super.WriteFile(file);
file.Write(this.Type);
file.WriteObjectId(this.Parent);
@ -326,6 +535,8 @@ export class TemplateRecord extends SymbolTableRecord
file.WriteObjectId(id);
file.WriteObject(this.positioning);
file.Write(this.SplitType);
}
//#endregion
}

@ -15,39 +15,22 @@ import { TemplateStretchScaleBoxAction } from "./Action/TemplateStretchScaleBoxA
import { TemplateRecord } from "./TemplateRecord";
import { ClampSpaceParse } from "../../Geometry/SpaceParse/ClampSpaceParse";
import { PositioningClampSpace } from "./Positioning/PositioningClampSpace";
/**
*
*/
function ParamRegister(params: {}, name: string, value: string, isRoot = false)
{
params[name] = value;
if (isRoot)
params["@" + name] = value;
}
/**
*
*/
function ParameterBecomeFater(params: {})
{
let nparams = {};
for (let name in params)
{
if (name[0] === "@")
nparams[name] = params[name];
else
nparams["_" + name] = params[name];
}
return nparams;
}
import { Sleep } from "../../Common/Sleep";
import { TemplateSplitType } from "./TemplateType";
import { TemplateParam } from "./Param/TemplateParam";
import { TemplateParamType } from "./Param/TemplateParamType";
import { FilletUtils } from "../../Add-on/FilletUtils";
import { Polyline } from "../Entity/Polyline";
import { Line } from "../Entity/Line";
import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
import { TemplateFilletAction } from "./Action/TemplateFilletAction";
export function GetDefaultTemplate()
{
let templates = app.Database.TemplateTable.Objects;
if (templates.length === 0)
{
let template = new TemplateRecord().InitSizeParams();
let template = new TemplateRecord().InitBaseParams();
app.Database.TemplateTable.Append(template);
return template;
}
@ -178,6 +161,7 @@ export class AutoTempateSizeAction
//归0?
let keyRes = await app.Editor.GetKeyWords({
Msg: "自动将所有的板件移动到0点后初始化动作?",
KeyWordList: [
{ key: "Y", msg: "是" },
{ key: "N", msg: "否" },
@ -214,7 +198,14 @@ export class AutoTempateSizeAction
//上缩
let topBox = new Box3(box.min.clone().add(new Vector3(-1, -1, size.z / 2)), box.max.clone().add(v));
let template = new TemplateRecord().InitSizeParams();
let template = new TemplateRecord().InitBaseParams();
let rParam = new TemplateParam();
rParam.name = "R";
rParam.value = 0;
rParam.type = TemplateParamType.Float;
template.Params.push(rParam);
app.Database.TemplateTable.Append(template);
template.GetParam("L").value = size.x;
template.GetParam("W").value = size.y;
@ -343,8 +334,8 @@ export class UpdateTemplate
if (newV.Status === PromptStatus.OK)
{
param.UpdateParam(newV.Distance);
template.UpdateTemplate(undefined, true);
param.expr = newV.Distance;
await template.UpdateTemplateTree();
}
}
else
@ -353,6 +344,41 @@ export class UpdateTemplate
}
}
class UpdateTemplateRo
{
async exec()
{
let enRes = await app.Editor.GetSelection({
Msg: "选择要修改的模版:",
Once: true,
Filter: {
filterFunction: (obj, ent) =>
{
return ent.Template !== undefined;
}
}
});
if (enRes.Status !== PromptStatus.OK) return;
let template = enRes.SelectSet.SelectEntityList[0].Template.Object as TemplateRecord;
let ros = [0, 90, 180, 270, 0];
for (let param of [template.RXParam, template.RYParam, template.RZParam])
{
for (let r of ros)
{
param.expr = r;
await template.UpdateTemplateTree();
app.Editor.UpdateScreen();
await Sleep(1000);
}
}
}
}
export class UpdateParam2
{
timer;
@ -395,7 +421,7 @@ export class UpdateParam2
param.UpdateParam(param.value as number - 150);
}
template.UpdateTemplate(undefined, true);
template.UpdateTemplateTree();
app.Editor.UpdateScreen();
index++;
}, 16)
@ -447,7 +473,7 @@ export class TemplateAttach
let positioning = new PositioningClampSpace();
positioning.FromSpaceParse(parse);
template.Positioning = positioning;
await template.UpdateTemplate();//单独更新 不继承
await template.UpdateTemplateTree();//单独更新 不继承
let tbrs = brs.filter(br => br.Template !== undefined);
if (tbrs.length === 0)
@ -471,13 +497,172 @@ export class TemplateAttach
}
}
export class TemplateAttach2
{
async exec()
{
let enRes = await app.Editor.GetEntity({
Msg: "选择附加的模版",
NotNone: true,
Filter: {
filterFunction: (obj, ent) =>
{
return ent.Template !== undefined;
}
}
});
if (enRes.Status !== PromptStatus.OK) return;
let e = enRes.Entity;
let template = e.Template.Object as TemplateRecord;
let selectSpace = new PointSelectSpaceClamp();
selectSpace.Enable = EnableSelectType.Stretch;
await selectSpace.Select();
if (!selectSpace.ParseOK)
{
app.Editor.Prompt("未能分析出有效空间!");
return;
}
let parse = selectSpace.SpaceParse as ClampSpaceParse;
let brs = parse.m_Boards;
let positioning = new PositioningClampSpace();
positioning.FromSpaceParse(parse);
let tbrs = brs.filter(br => br.Template !== undefined);
if (tbrs.length === 0)
{
app.Editor.Prompt("选取的空间不存在模版!");
}
else
{
tbrs.sort((b1, b2) =>
{
let t1 = b1.Template.Object as TemplateRecord;
let t2 = b2.Template.Object as TemplateRecord;
return t2.NodeDepth - t1.NodeDepth;
});
let templateSpace = new TemplateRecord().InitBaseParams();
templateSpace.SplitType = TemplateSplitType.Z;
templateSpace.Positioning = positioning;
app.Database.TemplateTable.Append(templateSpace);
let template1 = new TemplateRecord().InitBaseParams();
template1.LParam.expr = "_L";
template1.WParam.expr = "_W";
template1.HParam.expr = "_DIV";
template1.PZParam.expr = "_POS";
let template2 = template1.Clone();
app.Database.TemplateTable.Append(template1);
app.Database.TemplateTable.Append(template2);
template.LParam.expr = "_L";
template.WParam.expr = "_W";
template.HParam.expr = "_DIV";
template.PZParam.expr = "_POS";
templateSpace.Children.push(template1.Id);
templateSpace.Children.push(template.Id);
templateSpace.Children.push(template2.Id);
let templateSource = tbrs[0].Template.Object as TemplateRecord;
templateSource.Children.push(templateSpace.Id);
await templateSpace.UpdateTemplateTree();
}
}
}
export class TemplateAddFilletAction
{
async exec()
{
let brRes = await app.Editor.GetEntity({
Msg: "选择附加的模版",
NotNone: true,
Filter: {
filterFunction: (obj, ent) =>
{
if (ent instanceof Board)
return ent.Template !== undefined;
return false;
}
}
});
if (brRes.Status !== PromptStatus.OK) return;
//------1.画辅助线
let ptRes = await app.Editor.GetPoint({
BasePoint: brRes.Point,
AllowDrawRubberBand: true,
AllowNone: true,
Msg: "选择下一个点:"
});
if (ptRes.Status === PromptStatus.Cancel)
return;
//------2.倒角
let fillet = new FilletUtils();
fillet.FilletRadius = 100;
let fres = fillet.FilletBoard(brRes, ptRes);
if (fres instanceof Polyline)
{
let br = brRes.Entity as Board;
br.ContourCurve = fres;
let brContour = fres;
//------1.求交
let brResPt = brRes.Point.clone().applyMatrix4(br.OCSInv).setZ(0);
let ptResPt = ptRes.Point.clone().applyMatrix4(br.OCSInv).setZ(0);
let l = new Line(brResPt, ptResPt);
let ipts = l.IntersectWith(brContour, IntersectOption.ExtendThis);
if (ipts.length > 2)//超过2个则有可能有多余交点
//找最近点
ipts = [fillet.FindNearestPt(ipts, brResPt), fillet.FindNearestPt(ipts, ptResPt)]
if (ipts.length !== 2)
return "倒角失败!交点个数异常.";
let param1 = brContour.GetParamAtPoint(ipts[0]);
let param2 = brContour.GetParamAtPoint(ipts[1]);
let filletAction = new TemplateFilletAction(br.Id, param1, param2);
let template = br.Template.Object as TemplateRecord;
let rParam = template.GetParam("R");
rParam.actions.push(filletAction);
}
else
app.Editor.Prompt(fres);
}
}
commandMachine.RegisterCommand("Attach", new TemplateAttach());
commandMachine.RegisterCommand("Attach2", new TemplateAttach2());
commandMachine.RegisterCommand("templateAddFilletAction", new TemplateAddFilletAction());
commandMachine.RegisterCommand("al", new AddTemplateAction("L"));
commandMachine.RegisterCommand("aw", new AddTemplateAction("W"));
commandMachine.RegisterCommand("ah", new AddTemplateAction("H"));
commandMachine.RegisterCommand("uu", new UpdateTemplate());
commandMachine.RegisterCommand("uur", new UpdateTemplateRo());
commandMachine.RegisterCommand("uuu", new UpdateParam2());
commandMachine.RegisterCommand("clear", new Clear);

@ -11,3 +11,11 @@ export enum TemplateType
//阵列模版
Array
}
export enum TemplateSplitType
{
None = -1,
X = 0,
Y = 1,
Z = 2,
}

Loading…
Cancel
Save