!182 重构`Text`和`Dimension`实体

Merge pull request !182 from ChenX/reTextAndDimension
pull/183/MERGE
ChenX 6 years ago
parent 19a42dc7fb
commit fca8afd868

@ -124,7 +124,7 @@ const config: webpack.Configuration = {
filepath: getpath(`${outputDir}/dll.js`),
},
{
filepath: "./node_modules/three/build/three.js",
filepath: "./node_modules/three/build/three.min.js",
},
{
filepath: "./node_modules//three/examples/js/libs/inflate.min.js",

@ -0,0 +1,87 @@
import { Matrix4, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application";
import { LineAngularDimension } from "../../DatabaseServices/Dimension/2LineAngularDimension";
import { Line } from "../../DatabaseServices/Line";
import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult";
import { isParallelTo } from "../../Geometry/GeUtils";
export class Command_Draw2LineAngularDim
{
async exec()
{
let l1Res = await app.m_Editor.GetEntity({
Filter: {
filterTypes: [Line]
}
});
if (l1Res.Status !== PromptStatus.OK) return;
let l2Res = await app.m_Editor.GetEntity({
Filter: {
filterTypes: [Line],
filterFunction: (obj, ent) =>
{
return ent !== l1Res.Entity;
}
}
});
if (l2Res.Status !== PromptStatus.OK) return;
let l1 = l1Res.Entity as Line;
let l2 = l2Res.Entity as Line;
//ocs
let derv1 = l1.GetFistDeriv(0).normalize();
let derv2 = l2.GetFistDeriv(0).normalize();
if (isParallelTo(derv1, derv2))
{
app.m_Editor.Prompt("两直线平行!");
return;
}
let norm = derv1.clone().cross(derv2);
let ocs: Matrix4;
for (const mat of [app.m_Editor.UCSMatrix, l1.OCS, l2.OCS])
{
if (isParallelTo(
new Vector3().setFromMatrixColumn(mat, 2),
norm
))
{
ocs = mat.clone().setPosition(l1.StartPoint);
break;
}
}
if (!ocs)
{
app.m_Editor.Prompt("绘制的标注实体和当前的UCS坐标系不一致,绘制失败.");
return;
}
let dim = new LineAngularDimension();
dim.ApplyMatrix(ocs);
dim.UpdateDimData(
l1.StartPoint,
l1.EndPoint,
l2.StartPoint,
l2.EndPoint,
l2Res.Point
);
JigUtils.Draw(dim);
let ptRes = await app.m_Editor.GetPoint({
Callback: (p) =>
{
dim.UpdateDimData(undefined, undefined, undefined, undefined, p);
}
});
if (ptRes.Status === PromptStatus.OK)
app.m_Database.ModelSpace.Append(dim);
}
}

@ -16,59 +16,49 @@ export class DrawAlignedDimension implements Command
protected DimType = DimensionType.Align;
async exec()
{
app.m_Editor.Prompt("请指定第一条尺寸线原点:");
let ptRes = await app.m_Editor.GetPoint({ Msg: "请指定第一条尺寸线原点:" });
if (ptRes.Status != PromptStatus.OK)
{
return;
}
let startPt = ptRes.Value;
let footPt1 = ptRes.Value;
app.m_Editor.Prompt("请输入第二条尺寸线原点:");
ptRes = await app.m_Editor.GetPoint({
Msg: "请输入第二条尺寸线原点:",
BasePoint: startPt,
BasePoint: footPt1,
AllowDrawRubberBand: true,
KeyWordList: [{ msg: "多行文字", key: "M" }, { msg: "文字", key: "T" }, { msg: "角度", key: "A" }]
// KeyWordList: [{ msg: "多行文字", key: "M" }, { msg: "文字", key: "T" }, { msg: "角度", key: "A" }]
});
let footPt2 = ptRes.Value;
if (ptRes.Status != PromptStatus.OK)
{
return;
}
let endPt = ptRes.Value;
let linePt = endPt.clone();
let alDim: AlignedDimension | LinearDimension;
if (this.DimType === DimensionType.Align)
{
alDim = new AlignedDimension(startPt, endPt, linePt, startPt.distanceTo(endPt) + '');
}
alDim = new AlignedDimension();
else
{
alDim = new LinearDimension(startPt, endPt, linePt, startPt.distanceTo(endPt) + '');
}
alDim = new LinearDimension();
alDim.ApplyMatrix(app.m_Editor.UCSMatrix);
alDim.FootP1 = footPt1;
alDim.ArmP1 = footPt1;
alDim.FootP2 = footPt2;
alDim.ArmP2 = footPt2;
JigUtils.Draw(alDim);
app.m_Editor.Prompt("指定尺寸线位置:");
ptRes = await app.m_Editor.GetPoint({
Msg: "指定尺寸线位置:",
KeyWordList: [{ msg: "多行文字", key: "M" }, { msg: "文字", key: "T" }, { msg: "角度", key: "A" }],
Callback: (v) =>
{
alDim.LinePoint = v;
}
// KeyWordList: [{ msg: "多行文字", key: "M" }, { msg: "文字", key: "T" }, { msg: "角度", key: "A" }],
Callback: (v) => { alDim.TextPosition = v; }
});
if (ptRes.Status == PromptStatus.OK)
{
alDim.LinePoint = ptRes.Value;
alDim.TextPosition = ptRes.Value;
app.m_Database.ModelSpace.Append(alDim);
}
else if (ptRes.Status == PromptStatus.Keyword)
{
if (ptRes.StringResult == "U")
{
}
}
}
}

@ -1,54 +0,0 @@
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;
}
}
}
}

@ -1,59 +1,8 @@
import { app } from '../../ApplicationServices/Application';
import { matrixAlignCoordSys } from '../../Common/Matrix4Utils';
import { Board } from '../../DatabaseServices/Board';
import { Polyline } from '../../DatabaseServices/Polyline';
import { Region } from '../../DatabaseServices/Region';
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { BoardGetFace } from '../../Geometry/DrillParse/BoardGetFace';
import { MoveMatrix } from '../../Geometry/GeUtils';
import { Vector3, Matrix4 } from 'three';
import { Line } from '../../DatabaseServices/Line';
export class Test implements Command
{
async exec()
{
this.execBoard();
}
async execBoard()
{
let b1 = Board.CreateBoard(1200, 600, 18, 0);
let b2 = Board.CreateBoard(1200, 600, 18, 1);
let b3 = Board.CreateBoard(1200, 600, 18, 2);
// b1.ApplyMatrix(new Matrix4().makeRotationAxis(new Vector3(1, 100), Math.PI / 2));
let rotate = new Matrix4().makeRotationX(Math.PI / 2).multiply(new Matrix4().makeRotationY(Math.PI / 2));
b1.ApplyMatrix(MoveMatrix(new Vector3(1000, 1000, 1000)))
b2.ApplyMatrix(MoveMatrix(new Vector3(1000, 1000, 1000)))
b3.ApplyMatrix(MoveMatrix(new Vector3(1000, 1000, 1000)))
b1.ApplyMatrix(rotate)
b2.ApplyMatrix(rotate)
b3.ApplyMatrix(rotate)
let getfaces = new BoardGetFace(b1);
let getfaces1 = new BoardGetFace(b2);
// getfaces.IntersectFace(getfaces1);
let getfaces2 = new BoardGetFace(b3);
// getfaces1.IntersectFace(getfaces2);
}
execReg()
{
let en = new Vector3(0, 1200, 0)
let len = 600;
let thickness = 18;
let p1 = new Vector3();
let p2 = new Vector3(len, 0);
let p3 = new Vector3(len, thickness)
let p4 = new Vector3(0, thickness);
let l1 = new Line(p1, p2);
let l2 = new Line(p2, p3);
let l3 = new Line(p3, p4);
let l4 = new Line(p4, p1);
let region = Region.CreateFromCurves([l1, l2, l3, l4]);
app.m_Database.ModelSpace.Append(region);
let mat = new Matrix4().setPosition(en)
.multiply(new Matrix4().makeRotationX(-Math.PI / 2));
region.ApplyMatrix(mat)
}
}

@ -15,6 +15,8 @@ import { Viewer } from '../GraphicsSystem/Viewer';
import { appUi } from '../UI/Layout/ApplicationLayout';
import { layoutOnsizeEvent } from '../UI/Layout/LayoutOnSizeEventManage';
import { DownPanelStore } from '../UI/Store/DownPanelStore';
import { end } from 'xaop';
import { Entity } from '../DatabaseServices/Entity';
export var app: ApplicationService
@ -40,6 +42,11 @@ export class ApplicationService
this.m_Viewer.renderDatabase(this.m_Database);
layoutOnsizeEvent.register("Webgl", () => this.m_Viewer.onSize());
end((new Entity()).AsyncUpdated, () =>
{
this.m_Viewer.m_bNeedUpdate = true;
});
//性能测试
// new RenderPerformanceStatus(this.m_Viewer);
//相机控制

@ -54,4 +54,3 @@ export class MathUtils
};
}

@ -178,6 +178,7 @@ export function ToFixed(v: number, fractionDigits: number = 5)
export function GetEntity(obj: Object3D): Entity | undefined
{
if (obj)
return obj.userData.Entity;
}

@ -3,7 +3,7 @@ import { Box3, Matrix4, Object3D, Shape, ShapeGeometry, Vector2, Vector3 } from
import { ColorMaterial } from '../Common/ColorPalette';
import { getCircleCenter, getTanPtsOnArcOrCircle, Vec2DTo3D } from '../Common/CurveUtils';
import { matrixSetVector } from '../Common/Matrix4Utils';
import { Status } from '../Common/Status';
import { Status, UpdateDraw } from '../Common/Status';
import { ObjectSnapMode } from '../Editor/ObjectSnapMode';
import { angle, angleTo2Pi, equaln, equalv3, midPoint, MoveMatrix, polar } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum';
@ -59,13 +59,11 @@ export class Arc extends Curve
get Center()
{
return new Vector3().setFromMatrixPosition(this.m_Matrix);
return this.Position;
}
set Center(v: Vector3)
{
this.WriteAllObjectRecord();
this.m_Matrix.setPosition(v);
this.Update();
this.Position = v;
}
get Normal()
@ -130,7 +128,12 @@ export class Arc extends Curve
}
set IsClockWise(v: boolean)
{
if (v !== this.m_Clockwise)
{
this.WriteAllObjectRecord();
this.m_Clockwise = v;
this.Update();
}
}
get StartAngle()

@ -336,12 +336,16 @@ export class Circle extends Curve
}
GetClosestPointTo(pt: Vector3, extend: boolean): Vector3
{
pt = pt.clone().applyMatrix4(this.OCSInv).setZ(0).applyMatrix4(this.OCS);
if (equaln(pt.distanceToSquared(this.Center), 0, 1e-10))
return this.GetPointAtParam(0);
let l = new Line(this.Center, pt);
let pts = l.IntersectWith(this, IntersectOption.ExtendBoth);
let ptIns = pt.distanceTo(pts[0]) < pt.distanceTo(pts[1]) ? pts[0] : pts[1];
return ptIns;
pts.sort((p1, p2) =>
{
return p1.distanceToSquared(pt) - p2.distanceToSquared(pt);
});
return pts[0];
}
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化

@ -0,0 +1,218 @@
import { Math as TMath, Mesh, Object3D, Vector3, Line as TLine } from "three";
import { arrayRemoveDuplicateBySort, arraySortByNumber } from "../../Common/ArrayExt";
import { ColorMaterial } from "../../Common/ColorPalette";
import { FixedNotZero, FixIndex } from "../../Common/Utils";
import { BufferGeometryUtils } from "../../Geometry/BufferGeometryUtils";
import { angle, equalv3 } from "../../Geometry/GeUtils";
import { RenderType } from "../../GraphicsSystem/Enum";
import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
import { Arc } from "../Arc";
import { Factory } from "../CADFactory";
import { CADFile } from "../CADFile";
import { Entity } from "../Entity";
import { Line } from "../Line";
import { Text, TextAligen } from "../Text/Text";
/**
* 线
*/
@Factory
export class LineAngularDimension extends Entity
{
private m_Text = new Text();
private m_Arc = new Arc();
constructor(
protected m_L1StartPoint = new Vector3(), //第一条直线的起点
protected m_L1EndPoint = new Vector3(), //第一条直线的终点
protected m_L2StartPoint = new Vector3(), //第二条直线的起点
protected m_L2EndPoint = new Vector3(),
protected m_DimPoint = new Vector3(), //标注位置
)
{
super();
this.m_Text.TextAligen = TextAligen.Down;
}
UpdateDimData(
l1sp: Vector3, l1ep: Vector3, l2sp: Vector3, l2ep: Vector3, dimp: Vector3
)
{
for (let [p, pn] of [
[this.m_L1StartPoint, l1sp],
[this.m_L1EndPoint, l1ep],
[this.m_L2StartPoint, l2sp],
[this.m_L2EndPoint, l2ep],
[this.m_DimPoint, dimp],
])
{
if (pn)
{
pn = pn.clone().applyMatrix4(this.OCSInv);
p.copy(pn);
}
}
this.Update();
}
//#region 动态拽拖
GetGripPoints(): Array<Vector3>
{
return [
this.m_L1StartPoint,
this.m_L1EndPoint,
this.m_L2StartPoint,
this.m_L2EndPoint,
this.m_DimPoint,
].map(p =>
{
return p.clone().applyMatrix4(this.OCS)
});
}
MoveGripPoints(indexList: number[], vec: Vector3)
{
let arr = [
this.m_L1StartPoint,
this.m_L1EndPoint,
this.m_L2StartPoint,
this.m_L2EndPoint,
this.m_DimPoint,
];
let ocsinv = this.OCSInv.clone().setPosition(new Vector3());
vec = vec.clone().applyMatrix4(ocsinv);
for (let i of indexList)
arr[i].add(vec);
this.Update();
}
//#endregion
//#region 绘制
Clone(): this
{
let ent = super.Clone();
ent.m_Text.CopyFrom(this.m_Text);
ent.m_Arc.CopyFrom(this.m_Arc);
for (let [type, obj] of ent.m_DrawEntity)
{
let [arrow1, arrow2, line, textObj] = obj.children;
(<TLine>line).geometry = (<TLine>line).geometry.clone();
}
return ent;
}
Explode()
{
//为了避免Text对象没有被更新.
this.Draw();
return [
this.m_Arc.Clone().ApplyMatrix(this.OCS),
this.m_Text.Clone().ApplyMatrix(this.OCS)
];
}
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
{
let obj = new Object3D();
let colorMaterial = ColorMaterial.GetBasicMaterial(this.ColorIndex);
let line = this.m_Arc.Draw();
let arrow1 = new Mesh(BufferGeometryUtils.ArrowGeometry(), colorMaterial);
let arrow2 = new Mesh(BufferGeometryUtils.ArrowGeometry(), colorMaterial);
let arrowSize = 10;
arrow1.scale.set(arrowSize, arrowSize, arrowSize);
arrow2.scale.set(arrowSize, arrowSize, arrowSize);
obj.add(arrow1, arrow2, line, this.m_Text.Draw());
this.UpdateDrawObject(renderType, obj);
return obj;
}
UpdateDrawObject(type: RenderType, obj: Object3D)
{
let [arrow1, arrow2, line, textObj] = obj.children;
let l1 = new Line(this.m_L1StartPoint, this.m_L1EndPoint);
let l2 = new Line(this.m_L2StartPoint, this.m_L2EndPoint);
let insP = l1.IntersectWith(l2, IntersectOption.ExtendBoth)[0];
if (insP)
{
this.m_Arc.Center = insP;
this.m_Arc.Radius = insP.distanceTo(this.m_DimPoint);
let ans = [this.m_L1StartPoint, this.m_L1EndPoint, this.m_L2StartPoint, this.m_L2EndPoint]
.map(p =>
{
if (equalv3(p, insP))
return NaN;
return angle(p.clone().sub(insP));
}).filter(a => !isNaN(a));
arraySortByNumber(ans);
arrayRemoveDuplicateBySort(ans);
let dimAn = angle(this.m_DimPoint.clone().sub(insP));
for (let i = 0; i < ans.length; i++)
{
let ni = FixIndex(i + 1, ans.length);
this.m_Arc.StartAngle = ans[ni];
this.m_Arc.EndAngle = ans[i];
if (this.m_Arc.ParamOnCurve(this.m_Arc.GetParamAtAngle(dimAn)))
{
obj.remove(line);
obj.remove(textObj);
obj.add(this.m_Arc.Draw());
arrow1.position.copy(this.m_Arc.StartPoint);
arrow1.rotation.z = this.m_Arc.GetFistDerivAngle(0) + Math.PI / 2;
arrow2.position.copy(this.m_Arc.EndPoint);
arrow2.rotation.z = this.m_Arc.GetFistDerivAngle(1) - Math.PI / 2;
this.m_Text.TextString = FixedNotZero(TMath.radToDeg(this.m_Arc.AllAngle), 2);
this.m_Text.Position = this.m_Arc.GetPointAtParam(0.5);
this.m_Text.TextRotation = this.m_Arc.GetAngleAtParam(0.5) % (Math.PI) - Math.PI / 2;
obj.add(this.m_Text.Draw());
return;
}
}
}
}
//#endregion
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFile)
{
super.ReadFile(file);
let ver = file.Read();
this.m_L1StartPoint.fromArray(file.Read());
this.m_L1EndPoint.fromArray(file.Read());
this.m_L2StartPoint.fromArray(file.Read());
this.m_L2EndPoint.fromArray(file.Read());
this.m_DimPoint.fromArray(file.Read());
this.Update();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFile)
{
super.WriteFile(file);
file.Write(1);
file.Write(this.m_L1StartPoint.toArray());
file.Write(this.m_L1EndPoint.toArray());
file.Write(this.m_L2StartPoint.toArray());
file.Write(this.m_L2EndPoint.toArray());
file.Write(this.m_DimPoint.toArray());
}
//#endregion
}

@ -1,210 +1,239 @@
import { Box3, Geometry, Group, Matrix4, Object3D, Vector3 } from 'three';
import * as THREE from 'three';
import { angleAndX, getProjectDist, midPoint } from '../../Geometry/GeUtils';
import { RenderType } from '../../GraphicsSystem/Enum';
import { Factory } from '../CADFactory';
import { CADFile } from '../CADFile';
import { Line } from '../Line';
import { Text } from '../Text/Text';
import { Dimension } from './Dim';
import { BufferGeometry, Mesh, Object3D, Vector3 } from "three";
import { ColorMaterial } from "../../Common/ColorPalette";
import { FixedNotZero } from "../../Common/Utils";
import { ObjectSnapMode } from "../../Editor/ObjectSnapMode";
import { BufferGeometryUtils } from "../../Geometry/BufferGeometryUtils";
import { angle, angleAndX, midPoint } from "../../Geometry/GeUtils";
import { RenderType } from "../../GraphicsSystem/Enum";
import { Factory } from "../CADFactory";
import { CADFile } from "../CADFile";
import { Entity } from "../Entity";
import { Line } from "../Line";
import { Text, TextAligen } from "../Text/Text";
import THREE = require("three");
/**
*
*
*
* (线 LinearDimension)
* @export
* @class AlignedDimension
* @extends {Dimension}
* @extends {Entity}
*/
@Factory
export class AlignedDimension extends Dimension
export class AlignedDimension extends Entity
{
private m_StartPoint: Vector3;
private m_EndPoint: Vector3;
//尺寸线位置点
private m_linePoint: Vector3;
private m_Oblique: number = 0;
constructor(sPt?: Vector3, ePt?: Vector3, linePt?: Vector3, text?: string)
private m_Text = new Text();
constructor(
//针脚
protected m_FootP1: Vector3 = new Vector3(),
protected m_FootP2: Vector3 = new Vector3(),
//肩膀
protected m_ArmP1: Vector3 = new Vector3(),
protected m_ArmP2: Vector3 = new Vector3()
)
{
super();
this.m_StartPoint = sPt || new Vector3();
this.m_EndPoint = ePt || new Vector3();
this.TextString = text;
this.m_linePoint = linePt || new Vector3();
this.m_Text = new Text(this.TextPosition, text, "yahei", 3, this.TextRotation);
this.m_Text.TextAligen = TextAligen.Down;
}
get StartPoint()
set FootP1(v: Vector3)
{
return this.m_StartPoint;
this.m_FootP1.copy(v).applyMatrix4(this.OCSInv);
this.Update();
}
set StartPoint(v: Vector3)
get FootP1()
{
this.m_StartPoint = v;
return this.m_FootP1.clone().applyMatrix4(this.OCS);
}
set FootP2(v: Vector3)
{
this.m_FootP2.copy(v).applyMatrix4(this.OCSInv);
this.Update();
}
get EndPoint()
get FootP2()
{
return this.m_EndPoint;
return this.m_FootP2.clone().applyMatrix4(this.OCS);
}
set EndPoint(v: Vector3)
set ArmP1(v: Vector3)
{
this.m_EndPoint = v;
this.m_ArmP1.copy(v).applyMatrix4(this.OCSInv);
this.Update();
}
get LinePoint()
get ArmP1()
{
return this.m_linePoint;
return this.m_ArmP1.clone().applyMatrix4(this.OCS);
}
set LinePoint(v: Vector3)
set ArmP2(v: Vector3)
{
this.m_linePoint = v;
this.m_ArmP2.copy(v).applyMatrix4(this.OCSInv);
this.Update();
}
get Oblique()
get ArmP2()
{
return this.m_Oblique;
return this.m_ArmP2.clone().applyMatrix4(this.OCS);
}
set Oblique(v: number)
get TextPosition()
{
this.m_Oblique = v;
return midPoint(this.m_ArmP1, this.m_ArmP2).applyMatrix4(this.OCS);
}
set TextPosition(p: Vector3)
{
p = p.clone().applyMatrix4(this.OCSInv);
let l = new Line(this.m_ArmP1.clone(), this.m_ArmP2.clone());
let cp = l.GetClosestPointTo(p, true);
let v = p.clone().sub(cp);
this.m_ArmP1.add(v);
this.m_ArmP2.add(v);
this.Update();
}
Explode()
{
//TODO:箭头实体
let [ept1, ept2, extEndPt1, extEndPt2, scaleSPt, scaleEPt] = this.GetDimPts();
let l1 = new Line(this.StartPoint, extEndPt1);
let l2 = new Line(this.EndPoint, extEndPt2);
let l3 = new Line(scaleSPt, scaleEPt);
let txt = new Text(this.TextPosition, this.TextString, "yahei", this.m_Text.Height, this.TextRotation);
return [l1, l2, l3, txt];
}
get BoundingBox(): Box3
{
let pts = this.GetDimPts();
pts.push(this.StartPoint, this.EndPoint);
return new Box3().setFromPoints(pts);;
}
//返回拉伸出来的2个点,
GetDimPts()
{
let originLine = this.EndPoint.clone().sub(this.StartPoint);
let sToLinePt = this.LinePoint.clone().sub(this.StartPoint);
let dir = -Math.sign(originLine.clone().cross(sToLinePt).z);
let h = getProjectDist(sToLinePt, originLine).v;
let oldLine = new Line(this.StartPoint, this.EndPoint);
let newLine = oldLine.GetOffsetCurves(h * dir)[0];
let extLine = newLine.GetOffsetCurves(this.m_ExtendRatio * dir)[0];
let endPt1 = newLine.StartPoint;
let endPt2 = newLine.EndPoint;
let extEndPt1 = extLine.StartPoint;
let extEndPt2 = extLine.EndPoint;
let scaleSPt = newLine.GetPointAtDistance(this.ARROWWIDTH);
let scaleEPt = newLine.GetPointAtDistance(newLine.Length - this.ARROWWIDTH);
return [endPt1, endPt2, extEndPt1, extEndPt2, scaleSPt, scaleEPt]
}
//设置拉伸高度,文字位置和旋转角度
setTxtPosAndRotation(endPt1: Vector3, endPt2: Vector3)
{
let originLine = endPt2.clone().sub(endPt1);
this.TextRotation = angleAndX(originLine);
this.TextPosition = midPoint(endPt1, endPt2);
this.UpdateText();
return [
new Line(this.FootP1, this.ArmP1),
new Line(this.ArmP2, this.ArmP1),
new Line(this.ArmP2, this.FootP2),
this.m_Text.Clone().ApplyMatrix(this.OCS)
];
}
Clone(): this
{
let ent = super.Clone();
ent.m_Text.CopyFrom(this.m_Text);
for (let [type, obj] of ent.m_DrawEntity)
{
let [line, arrow1, arrow2, textObj] = obj.children;
let l = line as THREE.Line;
l.geometry = l.geometry.clone();
}
return ent;
}
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
{
let pts = this.GetDimPts();
let l1 = this.drawLine(this.StartPoint, pts[2]);
let l2 = this.drawLine(this.EndPoint, pts[3]);
let l3 = this.drawLine(pts[0], pts[1]);
let obj = new Object3D();
let colorMaterial = ColorMaterial.GetLineMaterial(this.ColorIndex);
let line = new THREE.Line(
BufferGeometryUtils.CreateFromPts([this.m_FootP1, this.m_FootP2, this.m_ArmP1, this.m_ArmP2]),
colorMaterial
);
let text = this.m_Text.CreateText(this.TextString);
this.setTxtPosAndRotation(pts[0], pts[1]);
this.updateText(text, this.TextPosition, this.TextRotation);
let arrow1 = new Mesh(BufferGeometryUtils.ArrowGeometry(), colorMaterial);
let arrow2 = new Mesh(BufferGeometryUtils.ArrowGeometry(), colorMaterial);
let [startRotation, endRotation] = this.getArrowRotation(this.StartPoint, this.EndPoint);
let arrow1 = this.CreateArrow(pts[0], startRotation);
let arrow2 = this.CreateArrow(pts[1], endRotation);
obj.add(line, arrow1, arrow2, this.m_Text.Draw());
let dim = new Group();
dim.add(l1, l2, l3, text, arrow1, arrow2);
this.UpdateDrawObject(renderType, obj);
return dim;
return obj;
}
UpdateDrawObjectMaterial(type: RenderType, en: Object3D)
{
let dim = en as THREE.Group;
let pts = this.GetDimPts();
let objs = dim.children as THREE.Mesh[];
//三条横线
objs.map((obj: THREE.Line | THREE.Mesh, index: number) =>
{
if (obj instanceof THREE.Line)
{
let geo = obj.geometry as THREE.Geometry;
if (index <= 1)
UpdateDrawObject(type: RenderType, obj: Object3D)
{
geo.vertices[1].copy(pts[index + 2]);
let [line, arrow1, arrow2, textObj] = obj.children;
BufferGeometryUtils.UpdatePts((<THREE.Line>line).geometry as BufferGeometry, [this.m_FootP1, this.m_ArmP1, this.m_ArmP2, this.m_FootP2]);
let arrowSize = 10;
arrow1.scale.set(arrowSize, arrowSize, arrowSize);
arrow2.scale.set(arrowSize, arrowSize, arrowSize);
let armV = this.m_ArmP1.clone().sub(this.m_ArmP2);
let armAn = angle(armV);
arrow1.position.copy(this.m_ArmP1);
arrow1.rotation.z = armAn - Math.PI / 2;
arrow2.position.copy(this.m_ArmP2);
arrow2.rotation.z = armAn + Math.PI / 2;
this.UpdateText();
obj.remove(obj.children[3]);
obj.add(this.m_Text.Draw());
}
else
UpdateText()
{
geo.vertices[0].copy(pts[0]);
geo.vertices[1].copy(pts[1]);
}
geo.verticesNeedUpdate = true;
let armV = this.m_ArmP1.clone().sub(this.m_ArmP2);
this.m_Text.TextString = FixedNotZero(this.m_ArmP1.distanceTo(this.m_ArmP2), 2);
this.m_Text.Position = midPoint(this.m_ArmP1, this.m_ArmP2);
this.m_Text.TextRotation = angleAndX(armV);
}
})
//更新文字箭头角度
this.setTxtPosAndRotation(pts[0], pts[1]);
this.updateText(objs[3], this.TextPosition, this.TextRotation);
this.updateTwoArrows(objs[4], objs[5], pts[0], pts[1]);
}
GetGripPoints(): Array<THREE.Vector3>
/**
*
* @param snapMode ()
* @param pickPoint const
* @param lastPoint const
* @returns object snap points
*/
GetObjectSnapPoints(
snapMode: ObjectSnapMode,
pickPoint: Vector3,
lastPoint: Vector3
): Vector3[]
{
return [this.StartPoint, this.EndPoint, ...this.GetDimPts(), this.TextPosition];
return [];
}
GetStretchPoints(): Array<THREE.Vector3>
GetGripPoints(): Array<Vector3>
{
return [this.StartPoint, this.EndPoint, ...this.GetDimPts(), this.TextPosition];
return [this.m_FootP1, this.m_FootP2, this.m_ArmP1, this.m_ArmP2, midPoint(this.m_ArmP1, this.m_ArmP2)].map(p =>
{
return p.clone().applyMatrix4(this.OCS)
});
}
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
MoveGripPoints(indexList: number[], vec: Vector3)
{
if (indexList.length === 1)
{
let i = indexList[0];
if (i === 4)
{
let index = indexList[0];
if (index == 0)
this.StartPoint = this.StartPoint.add(vec);
else if (index === 1)
this.EndPoint = this.EndPoint.add(vec);
else
this.LinePoint = this.LinePoint.add(vec);
this.WriteAllObjectRecord();
let p = this.TextPosition.add(vec).applyMatrix4(this.OCSInv);
let l = new Line(this.m_ArmP1, this.m_ArmP2);
let cp = l.GetClosestPointTo(p, true);
let v = p.clone().sub(cp);
this.m_ArmP1.add(v);
this.m_ArmP2.add(v);
this.Update();
}
}
}
//#region -----------------------------File-----------------------------
//#region -------------------------File-------------------------
//对象应该实现dataIn和DataOut的方法,为了对象的序列化和反序列化
//对象从文件中读取数据,初始化自身
ReadFile(file: CADFile)
{
super.ReadFile(file);
let ver = file.Read();//1
this.m_StartPoint.fromArray(file.Read());
this.m_EndPoint.fromArray(file.Read());
this.m_linePoint.fromArray(file.Read());
this.TextString = file.Read();
let ver = file.Read();
this.m_ArmP1.fromArray(file.Read());
this.m_ArmP2.fromArray(file.Read());
this.m_FootP1.fromArray(file.Read());
this.m_FootP2.fromArray(file.Read());
this.Update();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFile)
{
super.WriteFile(file);
file.Write(1);//ver
file.Write(this.m_StartPoint.toArray());
file.Write(this.m_EndPoint.toArray());
file.Write(this.m_linePoint.toArray());
file.Write(this.TextString);
file.Write(1);
file.Write(this.m_ArmP1.toArray());
file.Write(this.m_ArmP2.toArray());
file.Write(this.m_FootP1.toArray());
file.Write(this.m_FootP2.toArray());
}
//#endregion-----------------------------File End-----------------------------
//#endregion
}

@ -1,158 +0,0 @@
import { Geometry, Mesh, Object3D, Quaternion, ShapeGeometry, Vector3 } from 'three';
import * as THREE from 'three';
import { ColorMaterial } from '../../Common/ColorPalette';
import { Factory } from '../CADFactory';
import { Entity } from '../Entity';
import { Text } from '../Text/Text';
import { rotatePoint } from '../../Geometry/GeUtils';
/**
*
*
* @export
* @class Dimension
* @extends {Entity}
*/
@Factory
export class Dimension extends Entity
{
protected m_Text: Text;
//标注高度
private m_Evevation: number = 0;
private m_Normal: Vector3 = new Vector3(0, 0, 1);
private m_TextPosition: Vector3 = new Vector3();
private m_TextString: string = null;
//文本旋转角度
private m_TextRotation: number = 0;
private m_HorizontalrRotation: number = 0;
//字体大小
protected FONTSIZE = 30;
//字体粗细
//箭头宽度
protected ARROWWIDTH = 0.3;
// 标注箭头高度
protected ARROWHEIGHT = 0.1;
//精度
protected PRECISION = 2;
protected FONTTODIMDIST: number = 0.1;
protected m_ExtendRatio: number = 0.2;
constructor()
{
super();
this.m_Text = new Text(this.m_TextPosition, "", "yahei", 3, this.TextRotation);
}
get Elevation()
{
return this.m_Evevation;
}
set Elevation(v: number)
{
this.m_Evevation = v;
}
get HorizontalRotation()
{
return this.m_HorizontalrRotation;
}
set HorizontalRotation(v: number)
{
this.m_HorizontalrRotation = v;
}
get Normal()
{
return this.m_Normal;
}
set Normal(v: Vector3)
{
this.m_Normal = v
}
get TextString()
{
return parseFloat(this.m_TextString).toFixed(this.PRECISION);
}
set TextString(v: string)
{
this.m_TextString = v;
}
get TextPosition()
{
return this.m_TextPosition;
}
set TextPosition(v: Vector3)
{
this.m_TextPosition = v;
}
get TextRotation()
{
return this.m_TextRotation;
}
set TextRotation(v: number)
{
this.m_TextRotation = v;
}
protected drawLine(spt: Vector3, ept: Vector3)
{
let geo = new Geometry();
geo.vertices.push(spt, ept);
return new THREE.Line(geo, ColorMaterial.GetLineMaterial(3));
}
// 创建箭头
CreateArrow(origin: Vector3, ro: number): THREE.Mesh
{
let x = 0;
let y = 0;
let arrowShape = new THREE.Shape();
arrowShape.moveTo(x, y);
arrowShape.lineTo(x + this.ARROWWIDTH, y + this.ARROWHEIGHT / 2);
arrowShape.lineTo(x + this.ARROWWIDTH, y - this.ARROWHEIGHT / 2);
arrowShape.lineTo(x, y);
let shapeGeo = new ShapeGeometry(arrowShape);
shapeGeo.computeBoundingBox();
let arrow = new THREE.Mesh(shapeGeo, ColorMaterial.GetBasicMaterial(this.m_Color));
arrow.position.copy(origin);
this.updateObjQuaternion(arrow, ro);
return arrow;
}
getArrowRotation(sp: Vector3, ep: Vector3)
{
let dir = ep.clone().sub(sp);
//起始,终止点箭头旋转角度
return dir.x > 0 || (dir.x === 0 && dir.y > 0) ?
[this.TextRotation, this.TextRotation - Math.PI]
: [this.TextRotation - Math.PI, this.TextRotation];
}
reviseTextPosition(v: Vector3)
{
let reviseLine = rotatePoint(new Vector3(1), this.TextRotation + Math.PI / 2).multiplyScalar(this.m_Text.Height / 2 + this.FONTTODIMDIST);
v.add(reviseLine);
}
updateText(text: THREE.Mesh, pos: Vector3, ro: number)
{
this.reviseTextPosition(pos);
let moveVecX = rotatePoint(new Vector3(1), this.TextRotation).negate().multiplyScalar(3 / 2);
let moveVecY = rotatePoint(new Vector3(0, -1), this.TextRotation).multiplyScalar(this.m_Text.Height / 2);
let p = pos.clone().add(moveVecX);
p.add(moveVecY);
text.position.copy(p);
this.updateObjQuaternion(text, ro);
}
//更新对象四元数
updateObjQuaternion(text: THREE.Mesh, rot: number)
{
let q = new Quaternion().setFromAxisAngle(this.Normal, rot);
text.quaternion.copy(q);
}
updateTwoArrows(aw1: Object3D, aw2: Object3D, spt: Vector3, ept: Vector3)
{
//更新两箭头
let [startRotation, endRotation] = this.getArrowRotation(spt, ept);
aw1.position.copy(spt);
aw2.position.copy(ept);
this.updateObjQuaternion(aw1 as THREE.Mesh, startRotation);
this.updateObjQuaternion(aw2 as THREE.Mesh, endRotation);
}
}

@ -1,425 +0,0 @@
import * as THREE from 'three';
import { Geometry, Group, Object3D, Shape, Vector3 } from 'three';
import { ColorMaterial } from '../../Common/ColorPalette';
import { angleAndX, angleTo, getPtPostion, updateGeometry, rotatePoint } from '../../Geometry/GeUtils';
import { RenderType } from '../../GraphicsSystem/Enum';
import { IntersectLAndLFor3D } from '../../GraphicsSystem/IntersectWith';
import { Arc } from '../Arc';
import { Factory } from '../CADFactory';
import { CADFile } from '../CADFile';
import { Entity } from '../Entity';
import { Line } from '../Line';
import { Text } from '../Text/Text';
import { Dimension } from './Dim';
@Factory
export class LineAngularDimension extends Dimension
{
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();
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;
}
Explode()
{
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, "yahei", 3, 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 = IntersectLAndLFor3D(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 = IntersectLAndLFor3D(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);
rotatePoint(line1, -Math.PI / 2);
rotatePoint(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);
}
GetGripPoints(): 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-----------------------------
}

@ -1,87 +1,53 @@
import { Vector3 } from 'three';
import { isBetweenNums } from '../../Common/Utils';
import { midPoint } from '../../Geometry/GeUtils';
import { Factory } from '../CADFactory';
import { Line } from '../Line';
import { AlignedDimension } from './AlignedDimension';
import { Vector3 } from "three";
import { isBetweenNums } from "../../Common/Utils";
import { Factory } from "../CADFactory";
import { AlignedDimension } from "./AlignedDimension";
enum DimDir
{
//水平
/**
*
*/
H = 0,
//垂直
/**
*
*/
V = 1
}
/**
* 线
*
* @export
* @class LinearDimension
* @extends {AlignedDimension}
*/
@Factory
export class LinearDimension extends AlignedDimension
{
//标注方向
private m_DimDir = DimDir.H;
constructor(sPt?: Vector3, ePt?: Vector3, linePt?: Vector3, text?: string)
get TextPosition()
{
super(sPt, ePt, linePt, text);
return super.TextPosition;
}
GetDimPts()
set TextPosition(p: Vector3)
{
// 传入点是否在两点x或者y之间
let isBetweenX = isBetweenNums(this.StartPoint.x, this.EndPoint.x, this.LinePoint.x);
let isBeteenY = isBetweenNums(this.StartPoint.y, this.EndPoint.y, this.LinePoint.y);
p = p.clone().applyMatrix4(this.OCSInv);
let bit = 0;//x 1 y 2
if (isBetweenNums(this.m_FootP1.x, this.m_FootP2.x, p.x))
bit |= 1;
if (isBetweenNums(this.m_FootP1.y, this.m_FootP2.y, p.y))
bit |= 2;
if (isBetweenX && !(isBeteenY && this.m_DimDir === DimDir.V))
{
if (bit === 1)
this.m_DimDir = DimDir.H;
}
else if (isBeteenY)
{
else if (bit === 2)
this.m_DimDir = DimDir.V;
}
//尺寸线拉伸出的2点
let endPt1: Vector3;
let endPt2: Vector3;
let extPt1: Vector3;
let extPt2: Vector3;
// 水平标注
if (this.m_DimDir === DimDir.H)
{
let startHeight = this.LinePoint.y - this.StartPoint.y;
let endHeight = this.LinePoint.y - this.EndPoint.y;
endPt1 = this.StartPoint.clone().setY(this.StartPoint.y + startHeight);
endPt2 = this.EndPoint.clone().setY(this.EndPoint.y + endHeight);
extPt1 = endPt1.clone().setY(endPt1.y + this.m_ExtendRatio * Math.sign(startHeight));
extPt2 = endPt2.clone().setY(endPt2.y + this.m_ExtendRatio * Math.sign(endHeight));
this.m_ArmP1.copy(this.m_FootP1).setY(p.y);
this.m_ArmP2.copy(this.m_FootP2).setY(p.y);
}
else
{
let startHeight = this.LinePoint.x - this.StartPoint.x;
let endHeight = this.LinePoint.x - this.EndPoint.x;
endPt1 = this.StartPoint.clone().setX(this.StartPoint.x + startHeight);
endPt2 = this.EndPoint.clone().setX(this.EndPoint.x + endHeight);
extPt1 = endPt1.clone().setX(endPt1.x + this.m_ExtendRatio * Math.sign(startHeight));
extPt2 = endPt2.clone().setX(endPt2.x + this.m_ExtendRatio * Math.sign(endHeight));
}
let l = new Line(endPt1, endPt2);
let scalePt1 = l.GetPointAtDistance(this.ARROWWIDTH);
let scalePt2 = l.GetPointAtDistance(l.Length - this.ARROWWIDTH);
return [endPt1, endPt2, extPt1, extPt2, scalePt1, scalePt2];
}
setTxtPosAndRotation(endPt1: Vector3, endPt2: Vector3)
{
this.TextPosition = midPoint(endPt1, endPt2);
this.TextRotation = this.m_DimDir === DimDir.H ? 0 : Math.PI / 2;
this.m_ArmP1.copy(this.m_FootP1).setX(p.x);
this.m_ArmP2.copy(this.m_FootP2).setX(p.x);
}
getArrowRotation(sp: Vector3, ep: Vector3)
{
return this.m_DimDir === DimDir.H ?
[this.TextRotation, this.TextRotation - Math.PI]
: [this.TextRotation - Math.PI, this.TextRotation];
this.Update();
}
}

@ -1,15 +0,0 @@
import { Factory } from "../CADFactory";
import { Entity } from "../Entity";
import { Vector3, Object3D } from "three";
import { RenderType } from "../../GraphicsSystem/Enum";
import * as THREE from "three";
import { Dimension } from "./Dim";
@Factory
export class RadialDimension extends Dimension
{
constructor(center, endPt, leaderLength, text)
{
super();
}
}

@ -1,36 +0,0 @@
import { Vector3 } from "three";
import { app } from "../../ApplicationServices/Application";
import { Command } from "../../Editor/CommandMachine";
import { AlignedDimension } from "./AlignedDimension";
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.GetGripPoints()
app.m_Database.ModelSpace.Append(dim);
let cus = dim.Explode();
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);
// })
}
}

@ -10,6 +10,7 @@ import { CADObject } from './CADObject';
import { ObjectId } from './ObjectId';
import { ObjectSnapMode } from '../Editor/ObjectSnapMode';
import { UpdateDraw } from '../Common/Status';
import { iaop } from 'xaop';
/**
* Entity ,.
@ -88,7 +89,7 @@ export class Entity extends CADObject
{
this.WriteAllObjectRecord();
this.m_Matrix.setPosition(v);
this.Update();
this.Update(UpdateDraw.Matrix);
}
get OCSInv(): Matrix4
@ -194,6 +195,15 @@ export class Entity extends CADObject
}
}
/**
* .
* Application,.
*/
@iaop
AsyncUpdated()
{
}
/**
* ,,
*
@ -330,7 +340,10 @@ export class Entity extends CADObject
for (let [type, obj] of this.m_DrawEntity)
{
let oldD = obj.userData;
obj.userData = {};
obj.traverse(o =>
{
o.userData = {};
});
let newObj = obj.clone();
obj.userData = oldD;

@ -1,14 +1,21 @@
import * as THREE from 'three';
import { Geometry, Math, Object3D, Vector3 } from 'three';
import { Math, Object3D, Vector3, Matrix4 } from 'three';
import { ColorMaterial } from '../../Common/ColorPalette';
import { setRotationOnAxis } from '../../Common/Matrix4Utils';
import { MoveMatrix, updateGeometry } from '../../Geometry/GeUtils';
import { MoveMatrix } from '../../Geometry/GeUtils';
import { RenderType } from '../../GraphicsSystem/Enum';
import { Factory } from '../CADFactory';
import { CADFile } from '../CADFile';
import { Entity } from '../Entity';
import { FontLoader } from './FontLoader';
export enum TextAligen
{
LeftTop = 3, Top = 1, RightTop = 5,
LeftMid = 2, Mid = 0, RightMid = 4,
LeftDown = 10, Down = 8, RightDown = 12,
}
/**
*
*
@ -19,11 +26,10 @@ import { FontLoader } from './FontLoader';
@Factory
export class Text extends Entity
{
private m_TextString: string;
private m_Height: number;
private m_TextString: string; //文字显示文本
private m_Height: number; //文字高度
private m_TextRotation: number;//角度
private m_NeedUpdate = true;
private m_Align: TextAligen = TextAligen.LeftDown;
constructor(pos?: Vector3, str?: string, public m_FontName: string = "songti", h?: number, ro?: number)
{
super();
@ -33,16 +39,6 @@ export class Text extends Entity
this.m_Height = h || 60;
this.m_TextRotation = ro || 0;
}
get TextPosition()
{
return new Vector3().setFromMatrixPosition(this.m_Matrix);
}
set TextPosition(v: Vector3)
{
this.WriteAllObjectRecord();
this.m_Matrix.setPosition(v);
}
get TextRotation()
{
return this.m_TextRotation;
@ -51,8 +47,7 @@ export class Text extends Entity
{
this.WriteAllObjectRecord();
this.m_TextRotation = v;
setRotationOnAxis(this.m_Matrix, this.Normal, Math.degToRad(v));
this.Update();
this.UpdateTranslate();
}
get TextString()
{
@ -61,10 +56,19 @@ export class Text extends Entity
set TextString(v: string)
{
this.WriteAllObjectRecord();
if (v !== this.m_TextString)
{
this.m_TextString = v;
this.m_NeedUpdate = true;
this.Update();
}
}
set TextAligen(al: TextAligen)
{
this.m_Align = al;
this.UpdateTranslate();
}
get Height()
{
return this.m_Height;
@ -76,39 +80,95 @@ export class Text extends Entity
this.Update();
}
//创建字体对象
CreateText(str: string)
async AsyncUpdateDrawObject(obj: THREE.Object3D)
{
if (this.m_NeedUpdate)
let mesh = obj.children[0] as THREE.Mesh;
if (mesh)
{
if (mesh.geometry)
mesh.geometry.dispose();
}
else
mesh = new THREE.Mesh();
let f = FontLoader.GetLoader(this.m_FontName);
let shapes: THREE.Shape[] = f.Font.generateShapes(str, this.Height);
await f.LoadGlyphs(this.TextString);
await f.AwaitLoaded();
let shapes: THREE.Shape[] = f.Font.generateShapes(this.m_TextString, this.Height);
let geometry = new THREE.ShapeGeometry(shapes);
geometry.computeBoundingBox();
this.m_NeedUpdate = false;
return new THREE.Mesh(geometry, ColorMaterial.GetBasicMaterial(this.m_Color));
mesh.geometry = geometry;
mesh.material = ColorMaterial.GetBasicMaterial(this.ColorIndex);
mesh.matrixAutoUpdate = false;
if (obj.children.length === 0)
obj.add(mesh);
this.UpdateTranslate();
this.AsyncUpdated();
}
else
//TODO: FIXME 应该避免一直重载这个迭代.
UpdateTranslate()
{
return this.m_DrawEntity.get(RenderType.Wireframe) as THREE.Mesh;
for (let [type, obj] of this.m_DrawEntity)
{
if (obj.children.length === 1)
{
let mesh = obj.children[0] as THREE.Mesh;
let box = mesh.geometry.boundingBox;
let p = new Vector3();
if (this.m_Align & TextAligen.LeftMid)
p.x = box.min.x;
else if (this.m_Align & TextAligen.RightMid)
p.x = box.max.x;
else
p.x = (box.min.x + box.max.x) / 2;
if (this.m_Align & TextAligen.Top)
p.y = box.max.y;
else if (this.m_Align & TextAligen.Down)
p.y = box.min.y;
else
p.y = (box.min.y + box.max.y) / 2;
mesh.matrix = new Matrix4().makeRotationZ(this.TextRotation).multiply(
new Matrix4().setPosition(p.negate())
);
}
}
}
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
{
let text = this.CreateText(this.TextString);
return text;
let g = new THREE.Object3D();
this.AsyncUpdateDrawObject(g);
return g;
}
UpdateDrawObject(type: RenderType, obj: Object3D)
{
this.AsyncUpdateDrawObject(obj);
}
UpdateDrawObjectMaterial(type: RenderType, en: Object3D)
{
}
GetGripPoints(): Array<THREE.Vector3>
{
return [this.TextPosition];
return [this.Position];
}
MoveGripPoints(indexList: number[], vec: Vector3)
{
if (indexList.length === 1)
this.Position = this.Position.add(vec);
}
GetStretchPoints(): Array<THREE.Vector3>
{
return [this.TextPosition];
return [this.Position];
}
MoveStretchPoints(indexList: Array<number>, vec: THREE.Vector3)
{
@ -122,24 +182,22 @@ export class Text extends Entity
{
super.ReadFile(file);
let ver = file.Read();//1
this.TextPosition.fromArray(file.Read());
this.TextString = file.Read();
this.m_TextString = file.Read();
this.Height = file.Read();
this.TextRotation = file.Read();
this.m_FontName = file.Read();
this.m_Align = file.Read();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFile)
{
super.WriteFile(file);
file.Write(1);//ver
file.Write(this.TextPosition.toArray());
file.Write(this.TextString);
file.Write(this.m_TextString);
file.Write(this.Height);
file.Write(this.TextRotation);
file.Write(this.m_FontName);
file.Write(this.m_Align);
}
//#endregion-----------------------------File End-----------------------------
}

@ -54,7 +54,7 @@ export class TextArea
this.m_EditoringObject = textObj;
this.RegisterEvent();
this.m_TextPosition = text.TextPosition;
this.m_TextPosition = text.Position;
this.m_TextHeight = text.Height;
this.m_TextRotation = text.TextRotation;
this.m_CurrentValue = text.TextString;

@ -22,15 +22,15 @@ export class CommandMachine
this.CommandStart(cmdName);
app.m_Editor.m_SelectCtrl.RestState();
let abort: boolean = true;
try
{
abort = await this.m_CommandList.get(cmdName).exec();
}
catch (error)
{
app.m_Editor.Prompt("抱歉,命令造成了错误,请联系开发人员.");
console.error(error, error.stack);
}
// try
// {
// }
// catch (error)
// {
// app.m_Editor.Prompt("抱歉,命令造成了错误,请联系开发人员.");
// console.error(error, error.stack);
// }
this.CommandEnd(cmdName, abort);
}
else

@ -20,7 +20,6 @@ import { DrawSingleBoard } from '../Add-on/DrawBoard/DrawSingleBoard';
import { DrawTopBottomBoard } from '../Add-on/DrawBoard/DrawTopBottomBoard';
import { DrawVerticalBoard } from '../Add-on/DrawBoard/DrawVerticalBoard';
import { DrawAlignedDimension } from '../Add-on/DrawDim/DrawAlignedDimension';
import { DrawLineAngularDimension } from '../Add-on/DrawDim/DrawLineAngularDimension';
import { DrawLinearDimension } from '../Add-on/DrawDim/DrawLinearDimension';
import { DrawEllipse } from '../Add-on/DrawEllipse';
import { DrawFloor } from '../Add-on/DrawFloor';
@ -75,7 +74,6 @@ import { TestDrawSpotLight } from '../Add-on/testEntity/TestDrawSpotLight';
import { Command_Trim } from '../Add-on/Trim';
import { Redo, Undo } from '../Add-on/Undo';
import { ViewToFront, ViewToRight, ViewToTop, ViewToLeft } from '../Add-on/ViewChange';
import { Command_DimTest } from '../DatabaseServices/Dimension/dimTest';
import { commandMachine } from './CommandMachine';
import { DrawCylineder } from '../Add-on/DrawCylinder';
import { Command_TestPointPickParse } from '../Add-on/TestPointPickParse';
@ -93,6 +91,7 @@ import { Singleton } from '../Common/Singleton';
import { CommandServer } from '../DatabaseServices/CommandServer';
import { ICommand } from '../UI/Components/CommandPanel/CommandList';
import { ChangeColor } from '../Add-on/ChangeColor';
import { Command_Draw2LineAngularDim } from '../Add-on/DrawDim/Draw2LineAngularDim';
export function registerCommand()
{
commandMachine.RegisterCommand("b", new DrawBox())
@ -194,7 +193,8 @@ export function registerCommand()
commandMachine.RegisterCommand("sl", new TestDrawSpotLight());
commandMachine.RegisterCommand("dal", new DrawAlignedDimension());
commandMachine.RegisterCommand("dli", new DrawLinearDimension());
commandMachine.RegisterCommand("dan", new DrawLineAngularDimension());
commandMachine.RegisterCommand("dan", new Command_Draw2LineAngularDim());
commandMachine.RegisterCommand("text", new DrawText());
commandMachine.RegisterCommand("int", new IntersectionOperation());
commandMachine.RegisterCommand("union", new UnionOperation());
@ -230,9 +230,6 @@ export function registerCommand()
commandMachine.RegisterCommand("close", new Command_ClosePt());
//用于测试包围盒
commandMachine.RegisterCommand("box", new Command_TestBox());
//测试标注
commandMachine.RegisterCommand("testdim", new Command_DimTest());
//阵列
commandMachine.RegisterCommand("array", new Command_Array());

@ -1,8 +1,9 @@
import { BufferGeometry, Vector3, BufferAttribute } from "three";
import { BufferGeometry, Vector3, BufferAttribute, ShapeGeometry } from "three";
import THREE = require("three");
export class BufferGeometryUtils
export namespace BufferGeometryUtils
{
static CreateFromPts(pts: Vector3[]): BufferGeometry
export function CreateFromPts(pts: Vector3[]): BufferGeometry
{
let geo = new BufferGeometry();
let positions = new Float32Array(pts.length * 3);
@ -10,10 +11,27 @@ export class BufferGeometryUtils
return geo;
}
static UpdatePts(geo: BufferGeometry, pts: Vector3[])
export function UpdatePts(geo: BufferGeometry, pts: Vector3[])
{
let bf = geo.getAttribute("position") as BufferAttribute;
bf.copyVector3sArray(pts);
bf.needsUpdate = true;
}
let arrowGeometry: ShapeGeometry;
export function ArrowGeometry()
{
if (arrowGeometry)
return arrowGeometry;
else
{
let arrowShape = new THREE.Shape();
arrowShape.lineTo(-0.5, -1.8);
arrowShape.lineTo(0.5, -1.8);
arrowGeometry = new ShapeGeometry(arrowShape);
arrowGeometry.computeBoundingBox();
return arrowGeometry;
}
}
}

@ -24,7 +24,7 @@ function orientation(p: Vec2, q: Vec2, r: Vec2): number
// for details of below formula.
let val = (q.y - p.y) * (r.x - q.x) -
(q.x - p.x) * (r.y - q.y);
if (val == 0)
if (val === 0)
return 0; // colinear
return (val > 0) ? 1 : 2; // clock or counterclock wise
}

@ -246,6 +246,7 @@ export function angleAndX(v: Vector3 | Vector2)
{
return v.x ? Math.atan(v.y / v.x) : Math.PI / 2;
}
/**
* 0-2pi
*

@ -37,7 +37,7 @@ export class Viewer
//前置渲染
m_PreViewer: PreViewer;
m_bUsePass = true;
m_bUsePass = false;
m_RenderPass: RenderPass;
m_OutlinePass: OutlinePass;
m_Composer: EffectComposer;

@ -22,7 +22,7 @@ export class DownPanelStore
@observable useDynInput: boolean = true;
@observable showToolBar: boolean = true;
@observable useDynSnap: boolean = true;
@observable usePass: boolean = true;
@observable usePass: boolean = false;
@observable useOrtho: boolean = false;
@observable fontName: string = "songti";
private constructor()

Loading…
Cancel
Save