mirror of https://gitee.com/cf-fz/WebCAD.git
!48 标注实体(线性,对齐,角度),文字实体,清理CurveUtils
parent
3e50eb9296
commit
7a9b4a7445
@ -0,0 +1,54 @@
|
|||||||
|
import { Command } from "../../Editor/CommandMachine";
|
||||||
|
import { PromptStatus } from "../../Editor/PromptResult";
|
||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { Line } from "../../DatabaseServices/Line";
|
||||||
|
import { LineAngularDimension } from "../../DatabaseServices/Dimension/LineAngularDimension";
|
||||||
|
import { angleTo } from "../../Geometry/GeUtils";
|
||||||
|
import { getLineAndLineAngle } from "../../Common/CurveUtils";
|
||||||
|
|
||||||
|
export class DrawLineAngularDimension implements Command
|
||||||
|
{
|
||||||
|
async exec()
|
||||||
|
{
|
||||||
|
let enRes = await app.m_Editor.GetEntity({
|
||||||
|
Msg: "请选择圆弧,圆或直线:"
|
||||||
|
});
|
||||||
|
if (enRes.Status !== PromptStatus.OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let startLine = enRes.Entity;
|
||||||
|
if (startLine instanceof Line)
|
||||||
|
{
|
||||||
|
enRes = await app.m_Editor.GetEntity({
|
||||||
|
Msg: "请选择第二条直线"
|
||||||
|
});
|
||||||
|
if (enRes.Status !== PromptStatus.OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let laterLine = enRes.Entity as Line;
|
||||||
|
|
||||||
|
let angle = (getLineAndLineAngle(startLine, laterLine) * 180 / Math.PI) + '';
|
||||||
|
|
||||||
|
let dim = new LineAngularDimension(
|
||||||
|
startLine.StartPoint, startLine.EndPoint,
|
||||||
|
laterLine.StartPoint, laterLine.EndPoint, enRes.Point, angle
|
||||||
|
)
|
||||||
|
app.m_Database.ModelSpace.Append(dim);
|
||||||
|
let resPt = await app.m_Editor.GetPoint({
|
||||||
|
Msg: "指定标注弧线位置",
|
||||||
|
KeyWordList: [{ msg: "多行文字", key: "M" }, { msg: "文字", key: "T" }, { msg: "角度", key: "A" }],
|
||||||
|
Callback: (v) =>
|
||||||
|
{
|
||||||
|
dim.ArcPoint = v;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (resPt.Status === PromptStatus.OK)
|
||||||
|
{
|
||||||
|
dim.ArcPoint = resPt.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
import { app } from '../ApplicationServices/Application';
|
||||||
|
import { Text } from '../DatabaseServices/Text/Text';
|
||||||
|
import { Command } from '../Editor/CommandMachine';
|
||||||
|
import { PromptStatus } from '../Editor/PromptResult';
|
||||||
|
|
||||||
|
export class DrawText implements Command
|
||||||
|
{
|
||||||
|
async exec()
|
||||||
|
{
|
||||||
|
let ptRes = await app.m_Editor.GetPoint({ Msg: "指定文字的起点" });
|
||||||
|
if (ptRes.Status != PromptStatus.OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let startPoint = ptRes.Value;
|
||||||
|
|
||||||
|
let hRes = await app.m_Editor.GetDistance({
|
||||||
|
Msg: "指定高度",
|
||||||
|
BasePoint: startPoint
|
||||||
|
})
|
||||||
|
if (hRes.Status != PromptStatus.OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let height = hRes.Value;
|
||||||
|
|
||||||
|
hRes = await app.m_Editor.GetDistance({
|
||||||
|
Msg: "指定文字旋转角度",
|
||||||
|
BasePoint: startPoint
|
||||||
|
})
|
||||||
|
if (hRes.Status !== PromptStatus.Cancel)
|
||||||
|
{
|
||||||
|
let text = new Text(startPoint, "", height, hRes.Value);
|
||||||
|
app.m_Database.ModelSpace.Append(text);
|
||||||
|
text.toggleTextArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,436 @@
|
|||||||
import { Factory } from "../CADFactory";
|
import * as THREE from 'three';
|
||||||
import { Entity } from "../Entity";
|
import { Geometry, Group, Object3D, Shape, Vector3, Matrix4 } from 'three';
|
||||||
import { Vector3, Object3D } from "three";
|
|
||||||
import { RenderType } from "../../GraphicsSystem/Enum";
|
|
||||||
import * as THREE from "three";
|
|
||||||
import { Dimension } from "./Dim";
|
|
||||||
|
|
||||||
|
import { ColorMaterial } from '../../Common/ColorPalette';
|
||||||
|
import { rotateLine } from '../../Common/CurveUtils';
|
||||||
|
import { angleAndX, angleTo, getPtPostion, updateGeometry } from '../../Geometry/GeUtils';
|
||||||
|
import { RenderType } from '../../GraphicsSystem/Enum';
|
||||||
|
import { IntersectLAndL } from '../../GraphicsSystem/IntersectWith';
|
||||||
|
import { Arc } from '../Arc';
|
||||||
|
import { Factory } from '../CADFactory';
|
||||||
|
import { Line } from '../Line';
|
||||||
|
import { Dimension } from './Dim';
|
||||||
|
import { Curve } from '../Curve';
|
||||||
|
import { Text } from '../Text/Text';
|
||||||
|
import { Entity } from '../Entity';
|
||||||
|
import { CADFile } from '../CADFile';
|
||||||
|
|
||||||
|
@Factory
|
||||||
export class LineAngularDimension extends Dimension
|
export class LineAngularDimension extends Dimension
|
||||||
{
|
{
|
||||||
constructor(spt1, ept1, spt2, ept2, arcpt, text)
|
private m_StartPoint1: Vector3;
|
||||||
|
private m_EndPoint1: Vector3;
|
||||||
|
private m_StartPoint2: Vector3;
|
||||||
|
private m_EndPoint2: Vector3;
|
||||||
|
|
||||||
|
private m_ArcPoint: Vector3;
|
||||||
|
constructor(spt1?: Vector3, ept1?: Vector3, spt2?: Vector3, ept2?: Vector3, arcpt?: Vector3, text?: string)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
|
this.m_StartPoint1 = spt1 || new Vector3();
|
||||||
|
this.m_StartPoint2 = spt2 || new Vector3();
|
||||||
|
this.m_EndPoint1 = ept1 || new Vector3();
|
||||||
|
this.m_EndPoint2 = ept2 || new Vector3();
|
||||||
|
this.m_ArcPoint = arcpt || new Vector3();
|
||||||
|
this.TextString = text || null;
|
||||||
|
}
|
||||||
|
get StartPoint1()
|
||||||
|
{
|
||||||
|
return this.m_StartPoint1;
|
||||||
|
}
|
||||||
|
get StartPoint2()
|
||||||
|
{
|
||||||
|
return this.m_StartPoint2;
|
||||||
|
}
|
||||||
|
get EndPoint1()
|
||||||
|
{
|
||||||
|
return this.m_EndPoint1;
|
||||||
|
}
|
||||||
|
get EndPoint2()
|
||||||
|
{
|
||||||
|
return this.m_EndPoint2;
|
||||||
|
}
|
||||||
|
set StartPoint1(v: Vector3)
|
||||||
|
{
|
||||||
|
this.WriteAllObjectRecord();
|
||||||
|
this.m_StartPoint1 = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
set StartPoint2(v: Vector3)
|
||||||
|
{
|
||||||
|
this.WriteAllObjectRecord();
|
||||||
|
this.m_StartPoint2 = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
set EndPoint1(v: Vector3)
|
||||||
|
{
|
||||||
|
this.WriteAllObjectRecord();
|
||||||
|
this.m_EndPoint1 = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
set EndPoint2(v: Vector3)
|
||||||
|
{
|
||||||
|
this.WriteAllObjectRecord();
|
||||||
|
this.m_EndPoint2 = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
get ArcPoint()
|
||||||
|
{
|
||||||
|
return this.m_ArcPoint;
|
||||||
|
}
|
||||||
|
set ArcPoint(v: Vector3)
|
||||||
|
{
|
||||||
|
this.WriteAllObjectRecord();
|
||||||
|
this.m_ArcPoint = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
get TextString()
|
||||||
|
{
|
||||||
|
return super.TextString + '°'
|
||||||
|
}
|
||||||
|
set TextString(v)
|
||||||
|
{
|
||||||
|
super.TextString = v;
|
||||||
|
}
|
||||||
|
Export()
|
||||||
|
{
|
||||||
|
let { lineStartPt, lineEndPt } = this.getDimLineData();
|
||||||
|
let { arcStartPt, arcEndPt, extSpt, extEpt, scaleSPt, scaleEPt, bul } = this.getDimArcData();
|
||||||
|
|
||||||
|
let arc = new Arc().ParseFromBul(scaleSPt, scaleEPt, bul);
|
||||||
|
let txt = new Text(this.TextPosition, this.TextString, this.FONTSIZE, this.TextRotation);
|
||||||
|
let cus: Entity[] = [arc, txt];
|
||||||
|
if (lineStartPt)
|
||||||
|
{
|
||||||
|
let l1 = new Line(lineStartPt, extSpt);
|
||||||
|
cus.push(l1);
|
||||||
|
}
|
||||||
|
if (lineEndPt)
|
||||||
|
{
|
||||||
|
let l1 = new Line(lineEndPt, extEpt);
|
||||||
|
cus.push(l1);
|
||||||
|
}
|
||||||
|
return cus;
|
||||||
|
}
|
||||||
|
//获得实际的线段起始点,靠近圆心的为起点
|
||||||
|
private getCaclSPtAndEPt()
|
||||||
|
{
|
||||||
|
// 2线交点即为圆心
|
||||||
|
let center = IntersectLAndL(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2);
|
||||||
|
// 获取实际的首尾点,离圆心近的的为起始点
|
||||||
|
let [spt1, ept1] = this.StartPoint1.distanceTo(center) < this.EndPoint1.distanceTo(center) ? [this.StartPoint1, this.EndPoint1] : [this.EndPoint1, this.StartPoint1];
|
||||||
|
let [spt2, ept2] = this.StartPoint2.distanceTo(center) < this.EndPoint2.distanceTo(center) ? [this.StartPoint2, this.EndPoint2] : [this.EndPoint2, this.StartPoint2];
|
||||||
|
return { spt1, ept1, spt2, ept2 };
|
||||||
|
}
|
||||||
|
//获取圆弧的起始点
|
||||||
|
private getDimArcData()
|
||||||
|
{
|
||||||
|
// 2线交点即为圆心
|
||||||
|
let center = IntersectLAndL(this.m_StartPoint1, this.m_EndPoint1, this.m_StartPoint2, this.m_EndPoint2);
|
||||||
|
let rad = this.m_ArcPoint.distanceTo(center);
|
||||||
|
let { ept1, ept2 } = this.getCaclSPtAndEPt();
|
||||||
|
//标注线段的起始端点
|
||||||
|
let { sp, ep } = getPtPostion(ept1, ept2, center, this.m_ArcPoint);
|
||||||
|
|
||||||
|
let l1 = new Line(center, sp);
|
||||||
|
let l2 = new Line(center, ep);
|
||||||
|
|
||||||
|
let seg1 = rad / l1.Length;
|
||||||
|
let seg2 = rad / l2.Length;
|
||||||
|
//标注圆弧起始点
|
||||||
|
let arcStartPt = l1.GetPointAtParam(seg1);
|
||||||
|
let arcEndPt = l2.GetPointAtParam(seg2);
|
||||||
|
|
||||||
|
//直线部分延伸点
|
||||||
|
let l3 = new Line(center, arcStartPt);
|
||||||
|
let l4 = new Line(center, arcEndPt);
|
||||||
|
let extSpt = l3.GetPointAtParam(this.m_ExtendRatio / l3.Length + 1);
|
||||||
|
let extEpt = l4.GetPointAtParam(this.m_ExtendRatio / l4.Length + 1);
|
||||||
|
|
||||||
|
let radLine1 = arcStartPt.clone().sub(center);
|
||||||
|
let radLine2 = arcEndPt.clone().sub(center);
|
||||||
|
let circleAng = angleTo(radLine1, radLine2);
|
||||||
|
let bul = Math.tan(circleAng / 4);
|
||||||
|
let tmpArc = new Arc().ParseFromBul(arcStartPt, arcEndPt, bul);
|
||||||
|
let scaleSPt = tmpArc.GetPointAtDistance(this.ARROWWIDTH);
|
||||||
|
let scaleEPt = tmpArc.GetPointAtDistance(tmpArc.Length - this.ARROWWIDTH);
|
||||||
|
|
||||||
|
return {
|
||||||
|
arcStartPt,
|
||||||
|
arcEndPt,
|
||||||
|
extSpt,
|
||||||
|
extEpt,
|
||||||
|
scaleSPt,
|
||||||
|
scaleEPt,
|
||||||
|
bul,
|
||||||
|
rad,
|
||||||
|
center
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//,设置文字的位置以及旋转角度
|
||||||
|
setTxtPosAndRotation(arcStartPt: Vector3, arcEndPt: Vector3, bul: number)
|
||||||
|
{
|
||||||
|
let tmpArc = new Arc().ParseFromBul(arcStartPt, arcEndPt, bul);
|
||||||
|
this.TextRotation = angleAndX(arcEndPt.clone().sub(arcStartPt));
|
||||||
|
this.TextPosition = tmpArc.GetPointAtParam(0.5);
|
||||||
|
}
|
||||||
|
//获得标注圆弧直线部分起始点
|
||||||
|
private getDimLineStartPt(sp: Vector3, ep: Vector3, center: Vector3, arcPt: Vector3)
|
||||||
|
{
|
||||||
|
let l1 = new Line(sp, ep);
|
||||||
|
let l2 = new Line(center, ep);
|
||||||
|
let par1 = l1.GetParamAtPoint(arcPt);
|
||||||
|
let par2 = l2.GetParamAtPoint(arcPt);
|
||||||
|
|
||||||
|
let lineStartPt: Vector3;
|
||||||
|
if (par1 > 1)
|
||||||
|
{
|
||||||
|
lineStartPt = l1.EndPoint;
|
||||||
|
}
|
||||||
|
else if (par1 < 0 && par2 > 0)
|
||||||
|
{
|
||||||
|
lineStartPt = l1.StartPoint;
|
||||||
|
}
|
||||||
|
else if (par2 < 0)
|
||||||
|
{
|
||||||
|
lineStartPt = center;
|
||||||
|
}
|
||||||
|
return lineStartPt;
|
||||||
|
}
|
||||||
|
//获得两条标注直线的起始点
|
||||||
|
private getDimLineData()
|
||||||
|
{
|
||||||
|
let { spt1, ept1, spt2, ept2 } = this.getCaclSPtAndEPt();
|
||||||
|
let { center, arcStartPt, arcEndPt } = this.getDimArcData();
|
||||||
|
|
||||||
|
let lineStartPt: Vector3 = this.getDimLineStartPt(spt1, ept1, center, arcStartPt);
|
||||||
|
let lineEndPt: Vector3 = this.getDimLineStartPt(spt2, ept2, center, arcEndPt);
|
||||||
|
|
||||||
|
return { lineStartPt, lineEndPt };
|
||||||
|
}
|
||||||
|
drawArc(spt: Vector3, ept: Vector3, center: Vector3, rad: number, bul: number)
|
||||||
|
{
|
||||||
|
let shape = new Shape();
|
||||||
|
|
||||||
|
let arc = new Arc().ParseFromBul(spt, ept, bul);
|
||||||
|
var [startAngle, endAngle] = [arc.StartAngle, arc.EndAngle];
|
||||||
|
shape.absarc(center.x, center.y, rad, startAngle, endAngle, bul < 0);
|
||||||
|
let geo = new THREE.Geometry();
|
||||||
|
geo.setFromPoints(shape.getPoints(60));
|
||||||
|
return new THREE.Line(geo, ColorMaterial.GetLineMaterial(3));
|
||||||
|
}
|
||||||
|
getArrowRotation(sp: Vector3, ep: Vector3)
|
||||||
|
{
|
||||||
|
let [pt1, pt2] = super.getArrowRotation(sp, ep);
|
||||||
|
let originLine = ep.clone().sub(sp);
|
||||||
|
let { spt1, spt2, ept1, ept2 } = this.getCaclSPtAndEPt();
|
||||||
|
let line1 = ept1.clone().sub(spt1);
|
||||||
|
let line2 = ept2.clone().sub(spt2);
|
||||||
|
|
||||||
|
rotateLine(line1, -Math.PI / 2);
|
||||||
|
rotateLine(line2, Math.PI / 2);
|
||||||
|
let angle = angleTo(originLine, line1);
|
||||||
|
let angle1 = angleTo(originLine.negate(), line2);
|
||||||
|
if (Math.abs(angle) >= Math.PI / 2)
|
||||||
|
{
|
||||||
|
angle += Math.PI;
|
||||||
|
}
|
||||||
|
if (Math.abs(angle1) >= Math.PI / 2)
|
||||||
|
{
|
||||||
|
angle1 += Math.PI;
|
||||||
|
}
|
||||||
|
pt1 += angle;
|
||||||
|
pt2 += angle1;
|
||||||
|
//起始,终止点箭头旋转角度
|
||||||
|
return [pt1, pt2]
|
||||||
|
}
|
||||||
|
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
|
||||||
|
{
|
||||||
|
let angDim = new Group();
|
||||||
|
let {
|
||||||
|
arcStartPt,
|
||||||
|
arcEndPt,
|
||||||
|
scaleSPt,
|
||||||
|
scaleEPt,
|
||||||
|
extSpt,
|
||||||
|
extEpt,
|
||||||
|
rad,
|
||||||
|
bul,
|
||||||
|
center
|
||||||
|
} = this.getDimArcData();
|
||||||
|
let { lineStartPt, lineEndPt } = this.getDimLineData();
|
||||||
|
|
||||||
|
let arc = this.drawArc(scaleSPt, scaleEPt, center, rad, bul);
|
||||||
|
|
||||||
|
//文字
|
||||||
|
let text = this.m_Text.CreateText(this.TextString);
|
||||||
|
this.setTxtPosAndRotation(arcStartPt, arcEndPt, bul);
|
||||||
|
this.updateText(text, this.TextPosition, this.TextRotation);
|
||||||
|
|
||||||
|
//箭头
|
||||||
|
let [startRotation, endRotation] = this.getArrowRotation(arcStartPt, arcEndPt);
|
||||||
|
let arrow1 = this.CreateArrow(arcStartPt, startRotation);
|
||||||
|
let arrow2 = this.CreateArrow(arcEndPt, endRotation);
|
||||||
|
|
||||||
|
//直线部分
|
||||||
|
lineStartPt = lineStartPt || extSpt.clone();
|
||||||
|
let l1 = this.drawLine(lineStartPt, extSpt);
|
||||||
|
l1.name = "startline";
|
||||||
|
l1.visible = !lineStartPt.equals(extSpt);
|
||||||
|
|
||||||
|
lineEndPt = lineEndPt || extEpt.clone();
|
||||||
|
let l2 = this.drawLine(lineEndPt, extEpt);
|
||||||
|
l2.name = "endline";
|
||||||
|
l2.visible = !lineEndPt.equals(extEpt);
|
||||||
|
|
||||||
|
angDim.add(arc, text, arrow1, arrow2, l1, l2);
|
||||||
|
return angDim;
|
||||||
|
}
|
||||||
|
//更新标注的直线,切换是否显示该标注线
|
||||||
|
private updateDimLine(l: THREE.Line, spt: Vector3, ept: Vector3)
|
||||||
|
{
|
||||||
|
let geo = l.geometry as Geometry;
|
||||||
|
if (spt)
|
||||||
|
{
|
||||||
|
l.visible = true;
|
||||||
|
geo = l.geometry as Geometry;
|
||||||
|
geo.vertices[0] = spt;
|
||||||
|
geo.vertices[1] = ept;
|
||||||
|
geo.verticesNeedUpdate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateDrawObjectMaterial(type: RenderType, en: Object3D)
|
||||||
|
{
|
||||||
|
let dim = en as THREE.Group;
|
||||||
|
let {
|
||||||
|
arcStartPt,
|
||||||
|
arcEndPt,
|
||||||
|
scaleSPt,
|
||||||
|
scaleEPt,
|
||||||
|
extSpt,
|
||||||
|
extEpt,
|
||||||
|
bul,
|
||||||
|
rad,
|
||||||
|
center
|
||||||
|
} = this.getDimArcData();
|
||||||
|
let { lineStartPt, lineEndPt } = this.getDimLineData();
|
||||||
|
|
||||||
|
let objs = dim.children as Object3D[];
|
||||||
|
|
||||||
|
let geo = this.drawArc(scaleSPt, scaleEPt, center, rad, bul).geometry as Geometry;
|
||||||
|
updateGeometry(objs[0] as THREE.Line, geo);
|
||||||
|
|
||||||
|
this.setTxtPosAndRotation(arcStartPt, arcEndPt, bul);
|
||||||
|
this.updateText(objs[1] as THREE.Mesh, this.TextPosition, this.TextRotation);
|
||||||
|
|
||||||
|
//更新2箭头
|
||||||
|
this.updateTwoArrows(objs[2], objs[3], arcStartPt, arcEndPt);
|
||||||
|
|
||||||
|
let l1 = dim.getObjectByName("startline") as THREE.Line;
|
||||||
|
let l2 = dim.getObjectByName("endline") as THREE.Line;
|
||||||
|
this.updateDimLine(l1, lineStartPt, extSpt);
|
||||||
|
this.updateDimLine(l2, lineEndPt, extEpt);
|
||||||
|
}
|
||||||
|
ApplyMatrix(m: Matrix4)
|
||||||
|
{
|
||||||
|
this.StartPoint1.applyMatrix4(m);
|
||||||
|
this.StartPoint2.applyMatrix4(m);
|
||||||
|
this.EndPoint1.applyMatrix4(m);
|
||||||
|
this.EndPoint2.applyMatrix4(m);
|
||||||
|
this.ArcPoint.applyMatrix4(m);
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
GetSnapPoints(): Array<THREE.Vector3>
|
||||||
|
{
|
||||||
|
let {
|
||||||
|
arcStartPt,
|
||||||
|
arcEndPt,
|
||||||
|
scaleSPt,
|
||||||
|
scaleEPt,
|
||||||
|
extSpt,
|
||||||
|
extEpt,
|
||||||
|
bul
|
||||||
|
} = this.getDimArcData();
|
||||||
|
let pts: Vector3[] = [arcStartPt,
|
||||||
|
arcEndPt,
|
||||||
|
scaleSPt,
|
||||||
|
scaleEPt,
|
||||||
|
extSpt,
|
||||||
|
extEpt]
|
||||||
|
let arcPt = new Arc().ParseFromBul(arcStartPt, arcEndPt, bul).GetPointAtParam(2 / 3);
|
||||||
|
pts.push(arcEndPt, this.StartPoint1, this.StartPoint2, this.EndPoint1, this.EndPoint2, this.TextPosition);
|
||||||
|
return pts;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetStretchPoints(): Array<THREE.Vector3>
|
||||||
|
{
|
||||||
|
//TODO:待完善
|
||||||
|
let {
|
||||||
|
arcStartPt,
|
||||||
|
arcEndPt,
|
||||||
|
bul
|
||||||
|
} = this.getDimArcData();
|
||||||
|
let arcPt = new Arc().ParseFromBul(arcStartPt, arcEndPt, bul).GetPointAtParam(2 / 3);
|
||||||
|
|
||||||
|
let pts: Vector3[] = [this.StartPoint1, this.EndPoint1, this.StartPoint2, this.EndPoint2, this.TextPosition, arcPt];
|
||||||
|
|
||||||
|
return pts;
|
||||||
|
}
|
||||||
|
MoveStretchPoints(indexList: Array<number>, vec: THREE.Vector3)
|
||||||
|
{
|
||||||
|
let i = indexList[0];
|
||||||
|
//TODO:更改文字位置,其余交点拉伸时状态
|
||||||
|
if (i === 4)
|
||||||
|
{
|
||||||
|
this.TextPosition.add(vec);
|
||||||
|
this.ArcPoint.copy(this.TextPosition.clone());
|
||||||
|
}
|
||||||
|
else if (i === 5)
|
||||||
|
{
|
||||||
|
let {
|
||||||
|
arcStartPt,
|
||||||
|
arcEndPt,
|
||||||
|
bul
|
||||||
|
} = this.getDimArcData();
|
||||||
|
let arcPt = new Arc().ParseFromBul(arcStartPt, arcEndPt, bul).GetPointAtParam(2 / 3);
|
||||||
|
this.ArcPoint.copy(arcPt.add(vec));
|
||||||
|
}
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#region -----------------------------File-----------------------------
|
||||||
|
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
|
||||||
|
|
||||||
|
//对象从文件中读取数据,初始化自身
|
||||||
|
ReadFile(file: CADFile)
|
||||||
|
{
|
||||||
|
super.ReadFile(file);
|
||||||
|
let ver = file.Read();//1
|
||||||
|
this.StartPoint1.fromArray(file.Read());
|
||||||
|
this.EndPoint1.fromArray(file.Read());
|
||||||
|
this.StartPoint2.fromArray(file.Read());
|
||||||
|
this.EndPoint2.fromArray(file.Read());
|
||||||
|
this.ArcPoint.fromArray(file.Read());
|
||||||
|
this.TextString = file.Read();
|
||||||
|
}
|
||||||
|
//对象将自身数据写入到文件.
|
||||||
|
WriteFile(file: CADFile)
|
||||||
|
{
|
||||||
|
super.WriteFile(file);
|
||||||
|
file.Write(1);//ver
|
||||||
|
file.Write(this.StartPoint1.toArray());
|
||||||
|
file.Write(this.EndPoint1.toArray());
|
||||||
|
file.Write(this.StartPoint2.toArray());
|
||||||
|
file.Write(this.EndPoint2.toArray());
|
||||||
|
file.Write(this.ArcPoint.toArray());
|
||||||
|
file.Write(this.TextString);
|
||||||
}
|
}
|
||||||
|
//#endregion-----------------------------File End-----------------------------
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
import { Command } from "../../Editor/CommandMachine";
|
||||||
|
import { AlignedDimension } from "./AlignedDimension";
|
||||||
|
import { Vector3 } from "three";
|
||||||
|
import { app } from "../../ApplicationServices/Application";
|
||||||
|
import { LinearDimension } from "./LinearDimension";
|
||||||
|
import { Text } from "../Text/Text";
|
||||||
|
|
||||||
|
export class Command_DimTest implements Command
|
||||||
|
{
|
||||||
|
async exec()
|
||||||
|
{
|
||||||
|
this.export();
|
||||||
|
|
||||||
|
app.m_Viewer.m_bNeedUpdate = true;
|
||||||
|
}
|
||||||
|
export()
|
||||||
|
{
|
||||||
|
let dim = new AlignedDimension(new Vector3(), new Vector3(5), new Vector3(1, 3), "123");
|
||||||
|
dim.GetSnapPoints()
|
||||||
|
app.m_Database.ModelSpace.Append(dim);
|
||||||
|
let cus = dim.Export();
|
||||||
|
cus.forEach(cu =>
|
||||||
|
{
|
||||||
|
app.m_Database.ModelSpace.Append(cu);
|
||||||
|
})
|
||||||
|
// let text = new Text(new Vector3(), "haha", 2.5, 0);
|
||||||
|
// app.m_Database.ModelSpace.Append(text);
|
||||||
|
|
||||||
|
|
||||||
|
// let dim2 = new LinearDimension(new Vector3(), new Vector3(5, 5), new Vector3(1, 7), "123");
|
||||||
|
// // app.m_Database.ModelSpace.Append(dim2);
|
||||||
|
// cus = dim2.Export();
|
||||||
|
// cus.forEach(cu =>
|
||||||
|
// {
|
||||||
|
// // app.m_Database.ModelSpace.Append(cu);
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,253 @@
|
|||||||
|
import { BufferGeometry, Geometry, Matrix4, Object3D, Quaternion, Vector3 } from 'three';
|
||||||
|
import * as THREE from 'three';
|
||||||
|
|
||||||
|
import { app } from '../../ApplicationServices/Application';
|
||||||
|
import { ColorMaterial } from '../../Common/ColorPalette';
|
||||||
|
import { KeyBoard } from '../../Common/KeyEnum';
|
||||||
|
import { updateGeometry } from '../../Geometry/GeUtils';
|
||||||
|
import { RenderType } from '../../GraphicsSystem/Enum';
|
||||||
|
import { Factory } from '../CADFactory';
|
||||||
|
import { CADFile } from '../CADFile';
|
||||||
|
import { Entity } from '../Entity';
|
||||||
|
|
||||||
|
const f = require("../../../node_modules/three/examples/fonts/helvetiker_regular.typeface.json");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字体实体
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @class Text
|
||||||
|
* @extends {Entity}
|
||||||
|
*/
|
||||||
|
@Factory
|
||||||
|
export class Text extends Entity
|
||||||
|
{
|
||||||
|
private m_TextPosition: Vector3;
|
||||||
|
private m_TextString: string;
|
||||||
|
private m_Height: number;
|
||||||
|
private m_TextRotation: number;
|
||||||
|
//字体类型
|
||||||
|
private m_FontFamily: THREE.Font;
|
||||||
|
//字体大小
|
||||||
|
protected FONTSIZE = 0.2;
|
||||||
|
//字体粗细
|
||||||
|
protected PROVISITION = -0.1;
|
||||||
|
Normal: Vector3 = new Vector3(0, 0, 1);
|
||||||
|
m_fontWidth: number;
|
||||||
|
textArea: HTMLTextAreaElement;
|
||||||
|
constructor(pos?: Vector3, str?: string, h?: number, ro?: number)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.m_TextPosition = pos || new Vector3();
|
||||||
|
this.m_TextString = str || "";
|
||||||
|
this.m_Height = h || 0;
|
||||||
|
this.m_TextRotation = ro || 0;
|
||||||
|
this.loadFont();
|
||||||
|
this.initTextArea();
|
||||||
|
}
|
||||||
|
//加载字体类型
|
||||||
|
loadFont()
|
||||||
|
{
|
||||||
|
let loader = new THREE.FontLoader();
|
||||||
|
this.m_FontFamily = loader.parse(f);
|
||||||
|
}
|
||||||
|
initTextArea()
|
||||||
|
{
|
||||||
|
let height = this.worldTOScreenHeight(this.m_Height);
|
||||||
|
let v = this.TextPosition.clone();
|
||||||
|
app.m_Viewer.WorldToScreen(v);
|
||||||
|
|
||||||
|
this.textArea = document.createElement('textarea');
|
||||||
|
this.textArea.rows = 1;
|
||||||
|
this.textArea.cols = this.m_TextString.length + 1;
|
||||||
|
|
||||||
|
this.textArea.style.cssText = `
|
||||||
|
display:none;
|
||||||
|
overflow:hidden;
|
||||||
|
background:#444;
|
||||||
|
color:#fff;
|
||||||
|
font-size:${height}px;
|
||||||
|
position:fixed;
|
||||||
|
left:${v.x}px;
|
||||||
|
top:${v.y - height}px;
|
||||||
|
height:${height}px;
|
||||||
|
line-height:${height}px;
|
||||||
|
resize:none;
|
||||||
|
`;
|
||||||
|
this.textArea.value = this.m_TextString;
|
||||||
|
document.getElementById('Webgl').parentNode.appendChild(this.textArea);
|
||||||
|
}
|
||||||
|
worldTOScreenHeight(h: number)
|
||||||
|
{
|
||||||
|
let heightWCS = app.m_Viewer.m_CameraCtrl.ViewHeight;
|
||||||
|
let radio = this.Height / heightWCS;
|
||||||
|
return window.innerHeight * radio;
|
||||||
|
}
|
||||||
|
RegisterTextAreaEvent()
|
||||||
|
{
|
||||||
|
const confirmText = (e: Event) =>
|
||||||
|
{
|
||||||
|
this.TextString = (e.target as HTMLTextAreaElement).value;
|
||||||
|
this.toggleTextArea();
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
this.textArea.onkeydown = e =>
|
||||||
|
{
|
||||||
|
if (e.keyCode === KeyBoard.Escape)
|
||||||
|
{
|
||||||
|
confirmText(e);
|
||||||
|
}
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.textArea.oninput = (e) =>
|
||||||
|
{
|
||||||
|
let v = (e.target as HTMLTextAreaElement).value;
|
||||||
|
this.textArea.cols = v.length;
|
||||||
|
}
|
||||||
|
this.textArea.onblur = (e) =>
|
||||||
|
{
|
||||||
|
confirmText(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toggleTextArea()
|
||||||
|
{
|
||||||
|
let status = this.textArea.style.display;
|
||||||
|
this.textArea.style.display = status === "block" ? "none" : "block";
|
||||||
|
if (this.textArea.style.display === "block")
|
||||||
|
{
|
||||||
|
this.textArea.focus();
|
||||||
|
this.textArea.value = this.TextString;
|
||||||
|
this.TextString = "";
|
||||||
|
this.RegisterTextAreaEvent();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.textArea.oninput = null;
|
||||||
|
this.textArea.onblur = null;
|
||||||
|
this.textArea.onkeydown = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get TextPosition()
|
||||||
|
{
|
||||||
|
return this.m_TextPosition;
|
||||||
|
}
|
||||||
|
set TextPosition(v: Vector3)
|
||||||
|
{
|
||||||
|
let ucsV = v.clone();
|
||||||
|
app.m_Viewer.WorldToScreen(ucsV);
|
||||||
|
this.textArea.style.left = ucsV.x + "px";
|
||||||
|
this.textArea.style.top = ucsV.y + "px";
|
||||||
|
this.m_TextPosition = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
get TextRotation()
|
||||||
|
{
|
||||||
|
return this.m_TextRotation;
|
||||||
|
}
|
||||||
|
set TextRotation(v: number)
|
||||||
|
{
|
||||||
|
this.m_TextRotation = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
get TextString()
|
||||||
|
{
|
||||||
|
return this.m_TextString;
|
||||||
|
}
|
||||||
|
set TextString(v: string)
|
||||||
|
{
|
||||||
|
this.m_TextString = v;
|
||||||
|
// this.textArea.value = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
get Height()
|
||||||
|
{
|
||||||
|
return this.m_Height;
|
||||||
|
}
|
||||||
|
set Height(v: number)
|
||||||
|
{
|
||||||
|
this.textArea.style.height = v + "px";
|
||||||
|
this.m_Height = v;
|
||||||
|
this.Update();
|
||||||
|
}
|
||||||
|
get Width()
|
||||||
|
{
|
||||||
|
return this.m_fontWidth;
|
||||||
|
}
|
||||||
|
//创建字体对象
|
||||||
|
CreateText(str: string)
|
||||||
|
{
|
||||||
|
let textShape = new BufferGeometry();
|
||||||
|
let shapes: THREE.Shape[] = this.m_FontFamily.generateShapes(str, this.Height, this.PROVISITION);
|
||||||
|
let geometry = new THREE.ShapeGeometry(shapes);
|
||||||
|
geometry.computeBoundingBox();
|
||||||
|
this.m_fontWidth = geometry.boundingBox.max.x;
|
||||||
|
return new THREE.Mesh(geometry, ColorMaterial.GetLineMaterial(this.m_Color));
|
||||||
|
}
|
||||||
|
//更新对象四元数
|
||||||
|
UpdateObjQuaternion(text: THREE.Mesh, rot: number)
|
||||||
|
{
|
||||||
|
let q = new Quaternion().setFromAxisAngle(this.Normal, rot);
|
||||||
|
text.quaternion.copy(q);
|
||||||
|
}
|
||||||
|
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
|
||||||
|
{
|
||||||
|
let text = this.CreateText(this.TextString);
|
||||||
|
text.position.copy(this.TextPosition);
|
||||||
|
this.UpdateObjQuaternion(text, this.TextRotation);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
UpdateDrawObjectMaterial(type: RenderType, en: Object3D)
|
||||||
|
{
|
||||||
|
let text = en as THREE.Mesh;
|
||||||
|
let geo = this.CreateText(this.TextString).geometry as Geometry;
|
||||||
|
updateGeometry(text, geo);
|
||||||
|
|
||||||
|
this.UpdateObjQuaternion(text, this.TextRotation);
|
||||||
|
text.position.copy(this.TextPosition);
|
||||||
|
app.m_Viewer.m_bNeedUpdate = true;
|
||||||
|
}
|
||||||
|
ApplyMatrix(m: Matrix4)
|
||||||
|
{
|
||||||
|
this.TextPosition = this.TextPosition.applyMatrix4(m);
|
||||||
|
}
|
||||||
|
GetSnapPoints(): Array<THREE.Vector3>
|
||||||
|
{
|
||||||
|
return [this.TextPosition];
|
||||||
|
}
|
||||||
|
|
||||||
|
GetStretchPoints(): Array<THREE.Vector3>
|
||||||
|
{
|
||||||
|
return [this.TextPosition];
|
||||||
|
}
|
||||||
|
MoveStretchPoints(indexList: Array<number>, vec: THREE.Vector3)
|
||||||
|
{
|
||||||
|
let i = indexList[0];
|
||||||
|
this.TextPosition = this.TextPosition.add(vec);
|
||||||
|
}
|
||||||
|
//#region -----------------------------File-----------------------------
|
||||||
|
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
|
||||||
|
|
||||||
|
//对象从文件中读取数据,初始化自身
|
||||||
|
ReadFile(file: CADFile)
|
||||||
|
{
|
||||||
|
super.ReadFile(file);
|
||||||
|
let ver = file.Read();//1
|
||||||
|
this.TextPosition.fromArray(file.Read());
|
||||||
|
this.TextString = file.Read();
|
||||||
|
this.Height = file.Read();
|
||||||
|
this.TextRotation = file.Read();
|
||||||
|
|
||||||
|
}
|
||||||
|
//对象将自身数据写入到文件.
|
||||||
|
WriteFile(file: CADFile)
|
||||||
|
{
|
||||||
|
super.WriteFile(file);
|
||||||
|
file.Write(1);//ver
|
||||||
|
file.Write(this.TextPosition.toArray());
|
||||||
|
file.Write(this.TextString);
|
||||||
|
file.Write(this.Height);
|
||||||
|
file.Write(this.TextRotation);
|
||||||
|
}
|
||||||
|
//#endregion-----------------------------File End-----------------------------
|
||||||
|
}
|
Loading…
Reference in new issue