mirror of https://gitee.com/cf-fz/WebCAD.git
parent
7ea9f0a093
commit
6052844c2c
@ -1,44 +0,0 @@
|
|||||||
import { PointPick } from "./PointPick";
|
|
||||||
import { PointLight } from "../DatabaseServices/PointLight";
|
|
||||||
import { app } from "../ApplicationServices/Application";
|
|
||||||
import { LightModal } from "../UI/Components/Modal/LightModal";
|
|
||||||
import { ModalPosition } from "../UI/Components/Modal/ModalsManage";
|
|
||||||
import { Text } from "../DatabaseServices/Text/Text";
|
|
||||||
import { Board } from "../DatabaseServices/Board";
|
|
||||||
import { BoardOptionModal } from "../UI/Components/Board/BoardOptionModal";
|
|
||||||
import { Singleton } from "../Common/Singleton";
|
|
||||||
import { TextArea } from "../DatabaseServices/Text/TextArea";
|
|
||||||
import { Entity } from "../DatabaseServices/Entity";
|
|
||||||
|
|
||||||
export class DbClickManager
|
|
||||||
{
|
|
||||||
OnDbClick()
|
|
||||||
{
|
|
||||||
let en = PointPick(app.m_Editor.m_MouseCtrl.m_CurMousePointVCS, app.m_Viewer)[0];
|
|
||||||
//防止双击到Jig对象
|
|
||||||
if (!en || !en.userData
|
|
||||||
|| !(en.userData instanceof Entity)
|
|
||||||
|| !en.userData.Id)
|
|
||||||
return;
|
|
||||||
//双击实体取消选中状态
|
|
||||||
app.m_Editor.m_SelectCtrl.Cancel();
|
|
||||||
|
|
||||||
if (en.userData instanceof PointLight)
|
|
||||||
{
|
|
||||||
app.m_Editor.m_ModalManage.RenderModeless(LightModal, ModalPosition.Right, { selectedObj: en.userData });
|
|
||||||
}
|
|
||||||
else if (en.userData instanceof Text)
|
|
||||||
{
|
|
||||||
let textarea = Singleton.GetInstance(TextArea);
|
|
||||||
textarea.StartEditorText(en);
|
|
||||||
}
|
|
||||||
else if (en.userData instanceof Board)
|
|
||||||
{
|
|
||||||
app.m_Editor.m_ModalManage.RenderModeless(
|
|
||||||
BoardOptionModal,
|
|
||||||
ModalPosition.Right,
|
|
||||||
{ board: en.userData }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,386 @@
|
|||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { arraySortByNumber } from "../../Common/ArrayExt";
|
||||||
|
import { curveLinkGroup, Vec3DTo2D } from "../../Common/CurveUtils";
|
||||||
|
import { KeyWord } from "../../Common/InputState";
|
||||||
|
import { Curve } from "../../DatabaseServices/Curve";
|
||||||
|
import { Point } from "../../DatabaseServices/Point";
|
||||||
|
import { Polyline, PolylineProps } from "../../DatabaseServices/Polyline";
|
||||||
|
import { Spline } from "../../DatabaseServices/Spline";
|
||||||
|
import { equaln, equalv3 } from "../../Geometry/GeUtils";
|
||||||
|
import { Jig } from "../Jig";
|
||||||
|
import { PromptStatus } from "../PromptResult";
|
||||||
|
import { log } from "../../Common/Utils";
|
||||||
|
|
||||||
|
interface IVertex
|
||||||
|
{
|
||||||
|
index: number;
|
||||||
|
point: Point;
|
||||||
|
}
|
||||||
|
export class DBClickPolyline
|
||||||
|
{
|
||||||
|
private entity: Curve;
|
||||||
|
HandlePolyline = async (pl: Polyline) =>
|
||||||
|
{
|
||||||
|
this.entity = pl;
|
||||||
|
|
||||||
|
//默认关键字列表
|
||||||
|
const defaultKW: KeyWord[] = [
|
||||||
|
{ key: "C", msg: "闭合" },
|
||||||
|
{ key: "J", msg: "合并" },
|
||||||
|
{ key: "E", msg: "编辑顶点" },
|
||||||
|
// { key: "F", msg: "拟合" },
|
||||||
|
// { key: "S", msg: "样条曲线" },
|
||||||
|
{ key: "D", msg: "非曲线化" },
|
||||||
|
{ key: "R", msg: "反转" },
|
||||||
|
{ key: "U", msg: "放弃" }
|
||||||
|
];
|
||||||
|
|
||||||
|
//操作记录数,用于撤销双击后的操作
|
||||||
|
let totalRecCount = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
let pl = this.entity as Polyline;
|
||||||
|
|
||||||
|
defaultKW[0].key = pl.CloseMark ? "O" : "C";
|
||||||
|
defaultKW[0].msg = pl.CloseMark ? "打开" : "闭合";
|
||||||
|
|
||||||
|
let res = await app.m_Editor.GetKeyWords({
|
||||||
|
Msg: "请输入选项",
|
||||||
|
KeyWordList: defaultKW
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res.Status !== PromptStatus.Keyword)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let execStatus = PromptStatus.OK;
|
||||||
|
|
||||||
|
switch (res.StringResult)
|
||||||
|
{
|
||||||
|
case "C": //闭合
|
||||||
|
app.m_Database.hm.StartCmd("");
|
||||||
|
totalRecCount++;
|
||||||
|
pl.CloseMark = true;
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
break;
|
||||||
|
case "O": //打开
|
||||||
|
app.m_Database.hm.StartCmd("");
|
||||||
|
totalRecCount++;
|
||||||
|
pl.CloseMark = false;
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
break;
|
||||||
|
case "J": //合并
|
||||||
|
if (!pl.CloseMark)
|
||||||
|
{
|
||||||
|
app.m_Database.hm.StartCmd("");
|
||||||
|
totalRecCount++;
|
||||||
|
execStatus = await this.Join();
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log("无法合并闭合多段线")
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "E": //编辑顶点
|
||||||
|
execStatus = await this.EditorVertex();
|
||||||
|
Jig.Destroy();
|
||||||
|
break;
|
||||||
|
case "D": //非曲线化
|
||||||
|
totalRecCount++;
|
||||||
|
this.TransfromNonCurve();
|
||||||
|
break;
|
||||||
|
case "R": //反转
|
||||||
|
totalRecCount++;
|
||||||
|
app.m_Database.hm.StartCmd("");
|
||||||
|
pl.Reverse();
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
break;
|
||||||
|
case "U": //放弃
|
||||||
|
if (totalRecCount > 0)
|
||||||
|
{
|
||||||
|
totalRecCount--;
|
||||||
|
app.m_Database.hm.Undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
app.m_Editor.UpdateScreen();
|
||||||
|
if (execStatus === PromptStatus.Cancel)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private EditorVertex = async () =>
|
||||||
|
{
|
||||||
|
//编辑顶点关键字列表
|
||||||
|
const editeVertexKW: KeyWord[] = [
|
||||||
|
{ key: "N", msg: "下一个" },
|
||||||
|
{ key: "P", msg: "上一个" },
|
||||||
|
{ key: "B", msg: "打断" },
|
||||||
|
{ key: "I", msg: "插入" },
|
||||||
|
{ key: "M", msg: "移动" },
|
||||||
|
{ key: "S", msg: "拉直" },
|
||||||
|
// { key: "T", msg: "切向" },
|
||||||
|
{ key: "X", msg: "退出" },
|
||||||
|
];
|
||||||
|
|
||||||
|
//顶点位置
|
||||||
|
let vertex: IVertex = {
|
||||||
|
index: 0,
|
||||||
|
point: Jig.Draw(new Point(this.entity.StartPoint))
|
||||||
|
};
|
||||||
|
|
||||||
|
//存储前后顶点索引
|
||||||
|
let indexList: number[] = [];
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
app.m_Editor.UpdateScreen();
|
||||||
|
|
||||||
|
let res = await app.m_Editor.GetKeyWords({
|
||||||
|
Msg: "输入顶点编辑选项",
|
||||||
|
KeyWordList: editeVertexKW
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res.Status !== PromptStatus.Keyword)
|
||||||
|
{
|
||||||
|
return PromptStatus.Cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
let execStatus = PromptStatus.OK;
|
||||||
|
|
||||||
|
switch (res.StringResult)
|
||||||
|
{
|
||||||
|
case "N": //下一个顶点
|
||||||
|
this.ToggleVertex(vertex, true);
|
||||||
|
break;
|
||||||
|
case "P": //上一个
|
||||||
|
this.ToggleVertex(vertex, false);
|
||||||
|
break;
|
||||||
|
case "B": //打断
|
||||||
|
//存入第一个索引
|
||||||
|
indexList.push(vertex.index);
|
||||||
|
execStatus = await this.ExecEditor(vertex, indexList, "B");
|
||||||
|
break;
|
||||||
|
case "I": //插入
|
||||||
|
app.m_Database.hm.StartCmd("");
|
||||||
|
execStatus = await this.ChangeVertex(vertex, false);
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
break;
|
||||||
|
case "M": //移动
|
||||||
|
app.m_Database.hm.StartCmd("");
|
||||||
|
execStatus = await this.ChangeVertex(vertex, true);
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
break;
|
||||||
|
case "S": //拉直
|
||||||
|
indexList.push(vertex.index);
|
||||||
|
execStatus = await this.ExecEditor(vertex, indexList, "S");
|
||||||
|
break
|
||||||
|
case "X": //退出
|
||||||
|
return PromptStatus.None;
|
||||||
|
}
|
||||||
|
if (execStatus === PromptStatus.Cancel)
|
||||||
|
{
|
||||||
|
return PromptStatus.Cancel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private ExecEditor = async (vertex: IVertex, indexList: number[], editorCommand: string) =>
|
||||||
|
{
|
||||||
|
//打断/拉直关键字列表
|
||||||
|
const execKW: KeyWord[] = [
|
||||||
|
{ key: "N", msg: "下一个" },
|
||||||
|
{ key: "P", msg: "上一个" },
|
||||||
|
{ key: "G", msg: "执行" },
|
||||||
|
{ key: "X", msg: "退出" }
|
||||||
|
];
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
let res = await app.m_Editor.GetKeyWords({
|
||||||
|
Msg: "请输入选项",
|
||||||
|
KeyWordList: execKW
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res.Status !== PromptStatus.Keyword)
|
||||||
|
{
|
||||||
|
return PromptStatus.Cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (res.StringResult)
|
||||||
|
{
|
||||||
|
case "N": //下一个顶点
|
||||||
|
this.ToggleVertex(vertex, true);
|
||||||
|
break;
|
||||||
|
case "P": //上一个
|
||||||
|
this.ToggleVertex(vertex, false);
|
||||||
|
break;
|
||||||
|
case "G": //执行
|
||||||
|
this.ExecSAndBCommand(indexList, vertex, editorCommand);
|
||||||
|
case "X": //退出
|
||||||
|
return PromptStatus.None;
|
||||||
|
}
|
||||||
|
app.m_Editor.UpdateScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Join = async () =>
|
||||||
|
{
|
||||||
|
let pl = this.entity as Polyline;
|
||||||
|
let exSsRes = await app.m_Editor.GetSelection({
|
||||||
|
Msg: "请选择对象<全部选择>:",
|
||||||
|
Filter: { filterTypes: [Curve] }
|
||||||
|
});
|
||||||
|
if (exSsRes.Status === PromptStatus.Cancel)
|
||||||
|
return PromptStatus.Cancel;
|
||||||
|
|
||||||
|
let cus = exSsRes.SelectSet.SelectEntityList as Curve[];
|
||||||
|
if (!cus.includes(pl))
|
||||||
|
cus.push(pl);
|
||||||
|
|
||||||
|
let groups = curveLinkGroup(cus);
|
||||||
|
for (let g of groups)
|
||||||
|
{
|
||||||
|
if (!g.includes(pl))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (let cu of g)
|
||||||
|
{
|
||||||
|
if (cu !== pl)
|
||||||
|
{
|
||||||
|
pl.Join(cu);
|
||||||
|
cu.Erase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PromptStatus.OK;
|
||||||
|
}
|
||||||
|
private ToggleVertex(vertex: IVertex, isNext: boolean)
|
||||||
|
{
|
||||||
|
let pl = this.entity as Polyline;
|
||||||
|
isNext ? vertex.index++ : vertex.index--;
|
||||||
|
if (vertex.index < 0)
|
||||||
|
vertex.index = 0;
|
||||||
|
else if (vertex.index > pl.EndParam)
|
||||||
|
vertex.index = pl.EndParam;
|
||||||
|
|
||||||
|
vertex.point.Position = pl.GetPointAtParam(vertex.index);
|
||||||
|
}
|
||||||
|
private Break(indexList: number[])
|
||||||
|
{
|
||||||
|
let pl = this.entity as Polyline;
|
||||||
|
let cus = pl.GetSplitCurves(indexList);
|
||||||
|
pl.Erase();
|
||||||
|
this.entity = null;
|
||||||
|
|
||||||
|
for (let cu of cus)
|
||||||
|
{
|
||||||
|
if (indexList.length === 2)
|
||||||
|
{
|
||||||
|
if (equalv3(cu.StartPoint, pl.GetPointAtParam(Math.min(...indexList))))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!this.entity) this.entity = cu;
|
||||||
|
app.m_Database.ModelSpace.Append(cu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//改变顶点,移动或者插入
|
||||||
|
private ChangeVertex = async (vertex: IVertex, isMove: boolean) =>
|
||||||
|
{
|
||||||
|
let pl = this.entity as Polyline;
|
||||||
|
let ptRes = await app.m_Editor.GetPoint({
|
||||||
|
Msg: "为新顶点指定位置",
|
||||||
|
BasePoint: vertex.point.Position,
|
||||||
|
AllowDrawRubberBand: true
|
||||||
|
})
|
||||||
|
if (ptRes.Status === PromptStatus.Cancel)
|
||||||
|
return PromptStatus.Cancel;
|
||||||
|
|
||||||
|
let newPt = ptRes.Value.clone().applyMatrix4(pl.OCSInv);
|
||||||
|
if (isMove)
|
||||||
|
{
|
||||||
|
pl.SetPointAt(vertex.index, Vec3DTo2D(newPt));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vertex.index++
|
||||||
|
pl.AddVertexAt(vertex.index, Vec3DTo2D(newPt));
|
||||||
|
}
|
||||||
|
vertex.point.Position = ptRes.Value;
|
||||||
|
|
||||||
|
return PromptStatus.OK;
|
||||||
|
}
|
||||||
|
//拉直曲线
|
||||||
|
private StretchStraight(indexList: number[])
|
||||||
|
{
|
||||||
|
let pl = this.entity as Polyline;
|
||||||
|
|
||||||
|
arraySortByNumber(indexList);
|
||||||
|
|
||||||
|
pl.SetBulgeAt(indexList[0], 0);
|
||||||
|
if (indexList.length === 2)
|
||||||
|
pl.RemoveVertexIn(indexList[0], indexList[1]);
|
||||||
|
}
|
||||||
|
private ExecSAndBCommand(indexList: number[], vertex: IVertex, editorCommand: string)
|
||||||
|
{
|
||||||
|
app.m_Database.hm.StartCmd("");
|
||||||
|
if (!equaln(indexList[0], vertex.index))
|
||||||
|
indexList.push(vertex.index);
|
||||||
|
//执行并更新顶点信息
|
||||||
|
if (editorCommand === "B")
|
||||||
|
{
|
||||||
|
//执行打断操作
|
||||||
|
this.Break(indexList);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//执行拉直操作
|
||||||
|
this.StretchStraight(indexList);
|
||||||
|
}
|
||||||
|
vertex.index = indexList[0];
|
||||||
|
vertex.point.Position = this.entity.GetPointAtParam(indexList[0]);
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
}
|
||||||
|
private TransfromNonCurve()
|
||||||
|
{
|
||||||
|
app.m_Database.hm.StartCmd("d");
|
||||||
|
let pl = this.entity;
|
||||||
|
if (pl instanceof Polyline)
|
||||||
|
{
|
||||||
|
for (let i = 0; i < pl.EndParam; i++)
|
||||||
|
{
|
||||||
|
let bul = pl.GetBuilgeAt(i);
|
||||||
|
if (bul !== 0)
|
||||||
|
pl.SetBulgeAt(i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pl instanceof Spline)
|
||||||
|
{
|
||||||
|
let pts = pl.Points;
|
||||||
|
let data: PolylineProps[] = [];
|
||||||
|
for (let p of pts)
|
||||||
|
{
|
||||||
|
data.push({
|
||||||
|
pt: Vec3DTo2D(p),
|
||||||
|
bul: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pl.Erase();
|
||||||
|
this.entity = new Polyline(data);
|
||||||
|
app.m_Database.ModelSpace.Append(this.entity);
|
||||||
|
}
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
}
|
||||||
|
private TransfromSpline()
|
||||||
|
{
|
||||||
|
app.m_Database.hm.StartCmd("s");
|
||||||
|
let pl = this.entity;
|
||||||
|
if (pl instanceof Polyline)
|
||||||
|
{
|
||||||
|
pl.Erase();
|
||||||
|
let pts = pl.GetStretchPoints();
|
||||||
|
let spl = new Spline(pts);
|
||||||
|
app.m_Database.ModelSpace.Append(spl);
|
||||||
|
spl.CloseMark = pl.CloseMark;
|
||||||
|
this.entity = spl;
|
||||||
|
}
|
||||||
|
app.m_Database.hm.EndCmd();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { Singleton } from "../../Common/Singleton";
|
||||||
|
import { Board } from "../../DatabaseServices/Board";
|
||||||
|
import { Entity } from "../../DatabaseServices/Entity";
|
||||||
|
import { PointLight } from "../../DatabaseServices/PointLight";
|
||||||
|
import { Polyline } from "../../DatabaseServices/Polyline";
|
||||||
|
import { Text } from "../../DatabaseServices/Text/Text";
|
||||||
|
import { TextArea } from "../../DatabaseServices/Text/TextArea";
|
||||||
|
import { BoardOptionModal } from "../../UI/Components/Board/BoardOptionModal";
|
||||||
|
import { LightModal } from "../../UI/Components/Modal/LightModal";
|
||||||
|
import { ModalPosition } from "../../UI/Components/Modal/ModalsManage";
|
||||||
|
import { PointPick } from "../PointPick";
|
||||||
|
import { DBClickPolyline } from "./DBClickPolyline";
|
||||||
|
import { commandMachine } from "../CommandMachine";
|
||||||
|
|
||||||
|
export class DbClickManager
|
||||||
|
{
|
||||||
|
OnDbClick = async () =>
|
||||||
|
{
|
||||||
|
let obj3d = PointPick(app.m_Editor.m_MouseCtrl.m_CurMousePointVCS, app.m_Viewer)[0];
|
||||||
|
//防止双击到Jig对象
|
||||||
|
if (!obj3d || !obj3d.userData
|
||||||
|
|| !(obj3d.userData instanceof Entity)
|
||||||
|
|| !obj3d.userData.Id)
|
||||||
|
return;
|
||||||
|
//双击实体取消选中状态
|
||||||
|
app.m_Editor.m_SelectCtrl.Cancel();
|
||||||
|
|
||||||
|
if (obj3d.userData instanceof PointLight)
|
||||||
|
{
|
||||||
|
app.m_Editor.m_ModalManage.RenderModeless(LightModal, ModalPosition.Right, { selectedObj: obj3d.userData });
|
||||||
|
}
|
||||||
|
else if (obj3d.userData instanceof Text)
|
||||||
|
{
|
||||||
|
let textarea = Singleton.GetInstance(TextArea);
|
||||||
|
textarea.StartEditorText(obj3d);
|
||||||
|
}
|
||||||
|
else if (obj3d.userData instanceof Board)
|
||||||
|
{
|
||||||
|
app.m_Editor.m_ModalManage.RenderModeless(
|
||||||
|
BoardOptionModal,
|
||||||
|
ModalPosition.Right,
|
||||||
|
{ board: obj3d.userData }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (obj3d.userData instanceof Polyline)
|
||||||
|
{
|
||||||
|
commandMachine.CommandStart("_pedit");
|
||||||
|
await Singleton.GetInstance(DBClickPolyline).HandlePolyline(obj3d.userData);
|
||||||
|
commandMachine.CommandEnd("_pedit");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//TODO:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in new issue