!48 标注实体(线性,对齐,角度),文字实体,清理CurveUtils

pull/50/head
ChenX 7 years ago
parent 3e50eb9296
commit 7a9b4a7445

@ -3,8 +3,6 @@ import { Vector3 } from 'three';
import { Line } from '../../src/DatabaseServices/Line'; import { Line } from '../../src/DatabaseServices/Line';
import { IntersectLineAndLine, IntersectOption } from '../../src/GraphicsSystem/IntersectWith'; import { IntersectLineAndLine, IntersectOption } from '../../src/GraphicsSystem/IntersectWith';
test('直线相交,共线', () => test('直线相交,共线', () =>
{ {
let l1 = new Line(new Vector3(0, 0, 0), new Vector3(5, 0, 0)); let l1 = new Line(new Vector3(0, 0, 0), new Vector3(5, 0, 0));

@ -1,6 +1,6 @@
import { Vector3 } from 'three';
import { Line } from '../../src/DatabaseServices/Line'; import { Line } from '../../src/DatabaseServices/Line';
import { Vector3 } from 'three';
test('直线参数', () => test('直线参数', () =>

@ -39,17 +39,15 @@ export class DrawAlignedDimension implements Command
let alDim: AlignedDimension | LinearDimension; let alDim: AlignedDimension | LinearDimension;
if (this.DimType === DimensionType.Align) if (this.DimType === DimensionType.Align)
{ {
alDim = new AlignedDimension(startPt, endPt, linePt, startPt.distanceTo(endPt).toFixed(4)); alDim = new AlignedDimension(startPt, endPt, linePt, startPt.distanceTo(endPt) + '');
} }
else else
{ {
alDim = new LinearDimension(startPt, endPt, linePt, startPt.distanceTo(endPt).toFixed(4)); alDim = new LinearDimension(startPt, endPt, linePt, startPt.distanceTo(endPt) + '');
} }
app.m_Database.ModelSpace.Append(alDim); app.m_Database.ModelSpace.Append(alDim);
app.m_Editor.AddNoSnapEntity(alDim);
app.m_Editor.m_CommandStore.Prompt("指定尺寸线位置:"); app.m_Editor.m_CommandStore.Prompt("指定尺寸线位置:");
ptRes = await app.m_Editor.GetPoint({ ptRes = await app.m_Editor.GetPoint({
Msg: "指定尺寸线位置:", Msg: "指定尺寸线位置:",

@ -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();
}
}
}

@ -15,12 +15,12 @@ export class Command_PLTest implements Command
async exec() async exec()
{ {
//this.intersect(); this.splitPolyline();
// this.splitPolyline(); // this.splitPolyline();
// this.splitPolyline(); // this.splitPolyline();
this.splitRec() // this.splitRec()
// this.testGetPointAtParam(); // this.testGetPointAtParam();
} }

@ -2,8 +2,10 @@ import { Vector2, Vector3 } from 'three';
import * as THREE from 'three'; import * as THREE from 'three';
import { CreateBoardUtil } from '../ApplicationServices/mesh/createBoard'; import { CreateBoardUtil } from '../ApplicationServices/mesh/createBoard';
import { angleTo, equaln, equal } from '../Geometry/GeUtils'; import { Line } from '../DatabaseServices/Line';
import { angle, angleTo, midPoint, polar } from '../Geometry/GeUtils';
import { Matrix2 } from '../Geometry/Matrix2'; import { Matrix2 } from '../Geometry/Matrix2';
import { Arc } from '../DatabaseServices/Arc';
export enum ExtendDir export enum ExtendDir
{ {
@ -17,38 +19,7 @@ export function rotateLine(l: Vector3, ang: number)
new Matrix2().setRotate(ang).applyVector(l); new Matrix2().setRotate(ang).applyVector(l);
return l; return l;
} }
//2点加凸度获取圆弧面积
export function getArcArea(startV: THREE.Vector2, endV: THREE.Vector2, bul: number)
{
let arcData = getArcProps(startV, endV, bul);
//圆心角
let circleAng = Math.atan(bul) * 4;
//扇形面积
let fanArea = Math.PI * Math.pow(arcData.rad, 2) * Math.abs(circleAng) / (Math.PI * 2);
let angArea = this.getDeterminant(arcData.startVec, arcData.endVec) / 2;
if (Math.abs(bul) >= 1)
{
return fanArea + Math.abs(angArea);
} else
{
return fanArea - Math.abs(angArea);
}
}
//2点加凸度获取圆弧半径圆心,起始线,终止线
export function getArcProps(startV: THREE.Vector2, endV: THREE.Vector2, bul: number)
{
let arc2d = new CreateBoardUtil.Arc2d(startV, endV, bul);
let centerPt = arc2d.m_Center;
let rad = Math.abs(arc2d.m_Radius);
//起始矢量
let startVec = startV.clone().sub(centerPt);
//终止矢量
let endVec = endV.clone().sub(centerPt);
return {
centerPt, rad, startVec, endVec
};
}
//3点获取圆心 //3点获取圆心
export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3) export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3)
{ {
@ -79,33 +50,7 @@ export function getCircleCenter(pt1: Vector3, pt2: Vector3, pt3: Vector3)
return center; return center;
} }
/**
*
*/
export function getArcAngleBy3Pt(startPt: Vector3, midPt: Vector3, endPt: Vector3)
{
// 圆心
let center = getCircleCenter(startPt, midPt, endPt);
// 起始矢量
let startLine = startPt.clone().sub(center);
// 终止矢量
let endLine = endPt.clone().sub(center);
// 弦
let chord = endPt.clone().sub(startPt);
//起点和圆弧点矢量
let mdStPt = midPt.clone().sub(startPt);
//圆心相对弦所在方向
let centerDir = endLine.clone().cross(chord).normalize();
//圆弧方向
let dir = chord.clone().cross(mdStPt).normalize();
//圆心角
let circleAng = startLine.angleTo(endLine);
if (centerDir.z * dir.z > 0)
{
circleAng = (Math.PI * 2 - Math.abs(circleAng))
}
return circleAng *= (-dir.z);
}
// 弦长+切线获取圆心角 // 弦长+切线获取圆心角
export function getArcAngle(chord: Vector3, tangentLine: Vector3) export function getArcAngle(chord: Vector3, tangentLine: Vector3)
{ {
@ -127,98 +72,6 @@ export function getDeterminant(v1: Vector2, v2: Vector2): number
{ {
return v1.x * v2.y - v1.y * v2.x; return v1.x * v2.y - v1.y * v2.x;
} }
// 获取曲线指定位置的点
export function getPtAtCurveParam(startPt: Vector2, endPt: Vector2, bul: number, segment: number)
{
let pt = new Vector3();
if (bul === 0)
{
pt.set((endPt.x - startPt.x) * segment + startPt.x, (endPt.y - startPt.y) * segment + startPt.y, 0);
}
else
{
let arcData = getArcProps(startPt, endPt, bul);
// 起始线
let startLine = Vec2DTo3D(arcData.startVec);
//圆心角
let circleAng = Math.atan(bul) * 4 * segment;
if (Math.abs(circleAng) > 2 * Math.PI)
circleAng = 2 * Math.PI * Math.sign(bul);
startLine = rotateLine(startLine, circleAng)
pt = Vec2DTo3D(arcData.centerPt);
pt.add(startLine);
}
return pt;
}
//获得曲线长度
export function getCurveLength(startPt: Vector2, endPt: Vector2, bul: number)
{
let dist: number;
if (bul === 0)
{
let line = endPt.clone().sub(startPt);
dist = line.length();
}
else
{
let arcData = getArcProps(startPt, endPt, bul);
// 圆心角
let cirAng = Math.atan(bul) * 4;
dist = Math.abs(arcData.rad) * Math.abs(cirAng);
}
return dist;
}
//点是否在圆弧上
export function isPtOnArc(startPt: Vector2, endPt: Vector2, bul: number, pt: Vector3, isExt = false)
{
let arcData = getArcProps(startPt, endPt, bul);
let rad = Math.abs(arcData.rad);
//圆心到输入点连线
let ptLine = pt.clone().sub(Vec2DTo3D(arcData.centerPt));
if (equaln(ptLine.length(), rad, 1e-7))
{
if (isExt) return true;
let startLine = Vec2DTo3D(arcData.startVec);
let endLine = Vec2DTo3D(arcData.endVec);
let oldCircleAngle = Math.abs(Math.atan(bul) * 4);
if (equal(startLine, ptLine) || equal(endLine, ptLine))
return true;
let cirAng = getArcLineAngle(startLine, ptLine, bul);
if (Math.abs(cirAng) < oldCircleAngle)
return true;
}
return false;
}
// 获得圆弧指定点的弧长和角度
export function getArcPtLenAndAngle(startPt: Vector2, endPt: Vector2, bul: number, pt: Vector3)
{
let arcData = getArcProps(startPt, endPt, bul);
let rad = Math.abs(arcData.rad);
//圆心到输入点连线
let ptLine = pt.clone().sub(Vec2DTo3D(arcData.centerPt));
let startLine = Vec2DTo3D(arcData.startVec);
let cirAng = getArcLineAngle(startLine, ptLine, bul);
return {
len: Math.abs(cirAng) * rad,
angle: cirAng
}
}
// 求圆弧上任一条线的圆心角
export function getArcLineAngle(startLine: Vector3, ptLine: Vector3, bul: number)
{
let cirAng = angleTo(startLine, ptLine);
if (cirAng * bul < 0)
{
cirAng = (Math.PI * 2 - Math.abs(cirAng)) * Math.sign(bul);
}
return cirAng;
}
// 2D 3D点转换 // 2D 3D点转换
export function Vec2DTo3D(pt: Vector2) export function Vec2DTo3D(pt: Vector2)
{ {
@ -228,43 +81,7 @@ export function Vec3DTo2D(pt: Vector3)
{ {
return new Vector2(pt.x, pt.y); return new Vector2(pt.x, pt.y);
} }
//点到曲线上的最近点 export function getLineAndLineAngle(l1: Line, l2: Line)
export function getClosestPt(startPt: Vector2, endPt: Vector2, bul: number, pt: Vector3, isExt: boolean = false, extendDir: ExtendDir = ExtendDir.Both)
{ {
let closestPt: Vector3; return l1.GetFistDeriv(0).angleTo(l2.GetFistDeriv(0));
let closestLen: number;
let segment: number;
//曲线长
let curveLen = getCurveLength(startPt, endPt, bul);
//起点到输入点矢量
let sToPtLine = pt.clone().sub(Vec2DTo3D(startPt));
//起点早终点矢量
let sToELine = Vec2DTo3D(endPt).sub(Vec2DTo3D(startPt));
//到直线上的最近点
if (bul === 0)
{
let angle = sToPtLine.angleTo(sToELine);
if (isNaN(angle))
{
closestPt = pt;
closestLen = closestPt.distanceTo(pt);
return { closestPt, closestLen }
}
let len = sToPtLine.length() * Math.cos(angle);
segment = len / curveLen;
}
else
{
let arcData = getArcPtLenAndAngle(startPt, endPt, bul, pt);
let angle = arcData.angle
if (Math.abs(angle) > Math.PI) angle -= (Math.PI * bul / Math.abs(bul));
segment = angle / (Math.atan(bul) * 4);
}
if (((segment > 1 || segment < -1e-7) && !isExt) ||
(segment > 1 && isExt && extendDir === ExtendDir.Later) ||
(segment < -1e-7 && isExt && extendDir === ExtendDir.Front)) return;
closestPt = getPtAtCurveParam(startPt, endPt, bul, segment);
closestLen = closestPt.distanceTo(pt);
return { closestPt, closestLen }
} }

@ -1,7 +1,7 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { Box3, Matrix4, ShapeGeometry, Vector3, Object3D, Vector2 } from 'three'; import { Box3, Matrix4, ShapeGeometry, Vector3, Object3D, Vector2 } from 'three';
import { ColorMaterial } from '../Common/ColorPalette'; import { ColorMaterial } from '../Common/ColorPalette';
import { getArcAngleBy3Pt, isPtOnArc, rotateLine, Vec3DTo2D, Vec2DTo3D } from '../Common/CurveUtils'; import { rotateLine, Vec3DTo2D, Vec2DTo3D, getCircleCenter } from '../Common/CurveUtils';
import { equal, equaln, polar, angle, midPoint, angleTo2Pi } from '../Geometry/GeUtils'; import { equal, equaln, polar, angle, midPoint, angleTo2Pi } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum'; import { RenderType } from '../GraphicsSystem/Enum';
import { IntersectOption, IntersectArcAndArc, IntersectCircleAndArc, IntersectLineAndArc, reverseIntersectOption, IntersectPolylineAndCurve } from '../GraphicsSystem/IntersectWith'; import { IntersectOption, IntersectArcAndArc, IntersectCircleAndArc, IntersectLineAndArc, reverseIntersectOption, IntersectPolylineAndCurve } from '../GraphicsSystem/IntersectWith';
@ -10,7 +10,6 @@ import { CADFile } from './CADFile';
import { Circle } from './Circle'; import { Circle } from './Circle';
import { Curve } from './Curve'; import { Curve } from './Curve';
import { Line } from './Line'; import { Line } from './Line';
import { getCircleCenter } from './../Common/CurveUtils';
import { Polyline } from './Polyline'; import { Polyline } from './Polyline';
/** /**
* *
@ -150,10 +149,18 @@ export class Arc extends Curve
{ {
return polar(this.Center, this.StartAngle, this.m_Radius) as Vector3; return polar(this.Center, this.StartAngle, this.m_Radius) as Vector3;
} }
set StartPoint(v: Vector3)
{
this.StartAngle = angle(v.clone().sub(this.m_Center));
}
get EndPoint() get EndPoint()
{ {
return polar(this.Center, this.m_EndAngle, this.m_Radius) as Vector3; return polar(this.Center, this.m_EndAngle, this.m_Radius) as Vector3;
} }
set EndPoint(v: Vector3)
{
this.EndAngle = angle(v.clone().sub(this.m_Center));
}
get StartParam() get StartParam()
{ {
return 0; return 0;
@ -415,21 +422,10 @@ export class Arc extends Curve
this.m_StartAngle = angle(pt1.clone().sub(this.Center)); this.m_StartAngle = angle(pt1.clone().sub(this.Center));
this.m_EndAngle = angle(pt3.clone().sub(this.Center)); this.m_EndAngle = angle(pt3.clone().sub(this.Center));
//求出向量p1->p2,p1->p3 //求出向量p1->p2,p1->p3
let p1 = new Vector3(0, 0, 0); let p1 = pt2.clone().sub(pt1);
p1.x = pt2.x - pt1.x; let p2 = pt3.clone().sub(pt1);
p1.y = pt2.y - pt1.y;
let p2 = new Vector3(0, 0, 0); this.m_Clockwise = p1.cross(p2).z < 0;
p2.x = pt3.x - pt1.x;
p2.y = pt3.y - pt1.y;
//叉积
//this.m_Normal = p1.clone().cross(p2).normalize();
let normal = Math.tan(getArcAngleBy3Pt(pt1, pt2, pt3) * 0.25);
if (normal > 0)
{
let startAngle = this.m_StartAngle;
this.m_StartAngle = this.m_EndAngle;
this.m_EndAngle = startAngle;
}
return this; return this;
} }

@ -1,11 +1,12 @@
import { Geometry, Group, Object3D, Vector3 } from 'three'; import { Box3, Geometry, Group, Matrix4, Object3D, Vector3 } from 'three';
import * as THREE from 'three'; import * as THREE from 'three';
import { ColorMaterial } from '../../Common/ColorPalette'; import { angleAndX, getProjectDist, midPoint } from '../../Geometry/GeUtils';
import { rotateLine } from '../../Common/CurveUtils';
import { getProjectDist, midPoint } from '../../Geometry/GeUtils';
import { RenderType } from '../../GraphicsSystem/Enum'; import { RenderType } from '../../GraphicsSystem/Enum';
import { Factory } from '../CADFactory'; import { Factory } from '../CADFactory';
import { CADFile } from '../CADFile';
import { Line } from '../Line';
import { Text } from '../Text/Text';
import { Dimension } from './Dim'; import { Dimension } from './Dim';
/** /**
@ -30,6 +31,7 @@ export class AlignedDimension extends Dimension
this.m_EndPoint = ePt || new Vector3(); this.m_EndPoint = ePt || new Vector3();
this.TextString = text; this.TextString = text;
this.m_linePoint = linePt || new Vector3(); this.m_linePoint = linePt || new Vector3();
this.m_Text = new Text(this.TextPosition, text, this.FONTSIZE, this.TextRotation);
} }
get StartPoint() get StartPoint()
{ {
@ -67,55 +69,63 @@ export class AlignedDimension extends Dimension
this.m_Oblique = v; this.m_Oblique = v;
this.Update(); this.Update();
} }
//返回拉伸出来的2个点,设置拉伸高度,文字位置和旋转角度 Export()
{
//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, 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() GetDimPts()
{ {
let originLine = this.EndPoint.clone().sub(this.StartPoint); let originLine = this.EndPoint.clone().sub(this.StartPoint);
let sToLinePt = this.LinePoint.clone().sub(this.StartPoint); let sToLinePt = this.LinePoint.clone().sub(this.StartPoint);
let dir = Math.sign(originLine.clone().cross(sToLinePt).z); let dir = -Math.sign(originLine.clone().cross(sToLinePt).z);
let h = getProjectDist(sToLinePt, originLine).v;
this.Elevation = getProjectDist(sToLinePt, originLine).v; let oldLine = new Line(this.StartPoint, this.EndPoint);
let newLine = oldLine.GetOffsetCurves(h * dir)[0];
let vec1 = rotateLine(originLine.clone(), Math.PI / 2 * dir).normalize().multiplyScalar(this.Elevation); let extLine = newLine.GetOffsetCurves(this.m_ExtendRatio * dir)[0];
let LinePt1 = this.StartPoint.clone().add(vec1); let endPt1 = newLine.StartPoint;
let LinePt2 = this.EndPoint.clone().add(vec1); let endPt2 = newLine.EndPoint;
let extEndPt1 = extLine.StartPoint;
this.TextPosition = midPoint(LinePt1, LinePt2); let extEndPt2 = extLine.EndPoint;
this.TextRotation = originLine.x ? Math.atan(originLine.y / originLine.x) : Math.PI / 2; let scaleSPt = newLine.GetPointAtDistance(this.ARROWWIDTH);
return [LinePt1, LinePt2] let scaleEPt = newLine.GetPointAtDistance(newLine.Length - this.ARROWWIDTH);
}
getArrowRotation() return [endPt1, endPt2, extEndPt1, extEndPt2, scaleSPt, scaleEPt]
{ }
let dir = this.EndPoint.clone().sub(this.StartPoint); //设置拉伸高度,文字位置和旋转角度
//起始,终止点箭头旋转角度 setTxtPosAndRotation(endPt1: Vector3, endPt2: Vector3)
return dir.x > 0 || (dir.x === 0 && dir.y > 0) ? {
[this.TextRotation, this.TextRotation - Math.PI] let originLine = endPt2.clone().sub(endPt1);
: [this.TextRotation - Math.PI, this.TextRotation]; this.TextRotation = angleAndX(originLine);
this.TextPosition = midPoint(endPt1, endPt2);
} }
InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D InitDrawObject(renderType: RenderType = RenderType.Wireframe): Object3D
{ {
let pts = this.GetDimPts(); 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 geo = new Geometry(); let text = this.m_Text.CreateText(this.TextString);
geo.vertices.push(this.StartPoint, pts[0]); this.setTxtPosAndRotation(pts[0], pts[1]);
let l1 = new THREE.Line(geo, ColorMaterial.GetLineMaterial(3)); this.updateText(text, this.TextPosition, this.TextRotation);
geo = new Geometry();
geo.vertices.push(this.EndPoint, pts[1]);
let l2 = new THREE.Line(geo, ColorMaterial.GetLineMaterial(3));
geo = new Geometry();
geo.vertices.push(pts[0], pts[1]);
let l3 = new THREE.Line(geo, ColorMaterial.GetLineMaterial(3));
let text = this.CreateText();
text.position.copy(this.TextPosition)
this.UpdateObjQuaternion(text, this.TextRotation);
let [startRotation, endRotation] = this.getArrowRotation();
let [startRotation, endRotation] = this.getArrowRotation(this.StartPoint, this.EndPoint);
let arrow1 = this.CreateArrow(pts[0], startRotation); let arrow1 = this.CreateArrow(pts[0], startRotation);
let arrow2 = this.CreateArrow(pts[1], endRotation); let arrow2 = this.CreateArrow(pts[1], endRotation);
let dim = new Group(); let dim = new Group();
dim.add(l1, l2, l3, text, arrow1, arrow2); dim.add(l1, l2, l3, text, arrow1, arrow2);
@ -126,6 +136,7 @@ export class AlignedDimension extends Dimension
let dim = en as THREE.Group; let dim = en as THREE.Group;
let pts = this.GetDimPts(); let pts = this.GetDimPts();
let objs = dim.children as THREE.Mesh[]; let objs = dim.children as THREE.Mesh[];
//三条横线
objs.map((obj: THREE.Line | THREE.Mesh, index: number) => objs.map((obj: THREE.Line | THREE.Mesh, index: number) =>
{ {
if (obj instanceof THREE.Line) if (obj instanceof THREE.Line)
@ -133,7 +144,7 @@ export class AlignedDimension extends Dimension
let geo = obj.geometry as THREE.Geometry; let geo = obj.geometry as THREE.Geometry;
if (index <= 1) if (index <= 1)
{ {
geo.vertices[1].copy(pts[index]); geo.vertices[1].copy(pts[index + 2]);
} }
else else
{ {
@ -144,19 +155,27 @@ export class AlignedDimension extends Dimension
} }
}) })
objs[3].position.copy(this.TextPosition); //更新文字箭头角度
objs[4].position.copy(pts[0]); this.setTxtPosAndRotation(pts[0], pts[1]);
objs[5].position.copy(pts[1]); this.updateText(objs[3], this.TextPosition, this.TextRotation);
this.updateTwoArrows(objs[4], objs[5], pts[0], pts[1]);
} }
ApplyMatrix(m: Matrix4)
{
this.StartPoint.applyMatrix4(m);
this.EndPoint.applyMatrix4(m);
this.LinePoint.applyMatrix4(m);
this.Update();
}
GetSnapPoints(): Array<THREE.Vector3> GetSnapPoints(): Array<THREE.Vector3>
{ {
return [this.StartPoint, this.EndPoint, this.TextPosition, ...this.GetDimPts()]; return [this.StartPoint, this.EndPoint, ...this.GetDimPts(), this.TextPosition];
} }
GetStretchPoints(): Array<THREE.Vector3> GetStretchPoints(): Array<THREE.Vector3>
{ {
return [this.StartPoint, this.EndPoint, this.TextPosition, ...this.GetDimPts()]; return [this.StartPoint, this.EndPoint, ...this.GetDimPts(), this.TextPosition];
} }
MoveStretchPoints(indexList: Array<number>, vec: Vector3) MoveStretchPoints(indexList: Array<number>, vec: Vector3)
{ {
@ -168,6 +187,31 @@ export class AlignedDimension extends Dimension
else else
this.LinePoint = this.LinePoint.add(vec); this.LinePoint = this.LinePoint.add(vec);
} }
//#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();
}
//对象将自身数据写入到文件.
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);
}
//#endregion-----------------------------File End-----------------------------
} }

@ -1,11 +1,11 @@
import { BufferGeometry, Mesh, Quaternion, ShapeGeometry, Vector3 } from 'three'; import { Geometry, Mesh, Object3D, Quaternion, ShapeGeometry, Vector3 } from 'three';
import * as THREE from 'three'; import * as THREE from 'three';
import { ColorMaterial } from '../../Common/ColorPalette'; import { ColorMaterial } from '../../Common/ColorPalette';
import { rotateLine } from '../../Common/CurveUtils';
import { Factory } from '../CADFactory'; import { Factory } from '../CADFactory';
import { Entity } from '../Entity'; import { Entity } from '../Entity';
import { Text } from '../Text/Text';
const f = require("../../../node_modules/three/examples/fonts/helvetiker_regular.typeface.json");
/** /**
* *
@ -17,6 +17,7 @@ const f = require("../../../node_modules/three/examples/fonts/helvetiker_regular
@Factory @Factory
export class Dimension extends Entity export class Dimension extends Entity
{ {
protected m_Text: Text;
//标注高度 //标注高度
private m_Evevation: number = 0; private m_Evevation: number = 0;
private m_Normal: Vector3 = new Vector3(0, 0, 1); private m_Normal: Vector3 = new Vector3(0, 0, 1);
@ -25,18 +26,22 @@ export class Dimension extends Entity
//文本旋转角度 //文本旋转角度
private m_TextRotation: number = 0; private m_TextRotation: number = 0;
private m_HorizontalrRotation: number = 0; private m_HorizontalrRotation: number = 0;
//字体类型 //字体大小
private m_FontFamily: THREE.Font; protected FONTSIZE = 0.2;
private FONTSIZE = 0.1;
//字体粗细 //字体粗细
private PROVISITION = 0.1;
//箭头宽度 //箭头宽度
private ARROWWIDTH = 0.3; protected ARROWWIDTH = 0.3;
// 标注箭头高度 // 标注箭头高度
private ARROWHEIGHT = 0.1; protected ARROWHEIGHT = 0.1;
//精度
protected PRECISION = 2;
protected FONTTODIMDIST: number = 0.1;
protected m_ExtendRatio: number = 0.2;
constructor() constructor()
{ {
super(); super();
this.m_Text = new Text(this.m_TextPosition, "", this.FONTSIZE, this.TextRotation);
} }
get Elevation() get Elevation()
{ {
@ -64,7 +69,7 @@ export class Dimension extends Entity
} }
get TextString() get TextString()
{ {
return this.m_TextString; return parseFloat(this.m_TextString).toFixed(this.PRECISION);
} }
set TextString(v: string) set TextString(v: string)
{ {
@ -86,6 +91,12 @@ export class Dimension extends Entity
{ {
this.m_TextRotation = v; 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 CreateArrow(origin: Vector3, ro: number): THREE.Mesh
{ {
@ -100,32 +111,48 @@ export class Dimension extends Entity
shapeGeo.computeBoundingBox(); shapeGeo.computeBoundingBox();
let arrow = new THREE.Mesh(shapeGeo, ColorMaterial.GetLineMaterial(this.m_Color)); let arrow = new THREE.Mesh(shapeGeo, ColorMaterial.GetLineMaterial(this.m_Color));
arrow.position.copy(origin); arrow.position.copy(origin);
this.UpdateObjQuaternion(arrow, ro); this.updateObjQuaternion(arrow, ro);
return arrow; return arrow;
} }
//加载字体类型 getArrowRotation(sp: Vector3, ep: Vector3)
loadFont()
{ {
let loader = new THREE.FontLoader(); let dir = ep.clone().sub(sp);
this.m_FontFamily = loader.parse(f); //起始,终止点箭头旋转角度
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)
CreateText()
{ {
this.loadFont(); let reviseLine = rotateLine(new Vector3(1), this.TextRotation + Math.PI / 2).multiplyScalar(this.m_Text.Height / 2 + this.FONTTODIMDIST);
let textShape = new BufferGeometry(); v.add(reviseLine);
let shapes: THREE.Shape[] = this.m_FontFamily.generateShapes(this.TextString, this.FONTSIZE, this.PROVISITION); }
let geometry = new THREE.ShapeGeometry(shapes); updateText(text: THREE.Mesh, pos: Vector3, ro: number)
geometry.computeBoundingBox(); {
this.reviseTextPosition(pos);
let moveVecX = rotateLine(new Vector3(1), this.TextRotation).negate().multiplyScalar(this.m_Text.Width / 2);
let moveVecY = rotateLine(new Vector3(0, -1), this.TextRotation).multiplyScalar(this.m_Text.Height / 2);
let p = pos.clone().add(moveVecX);
p.add(moveVecY);
return new THREE.Mesh(geometry, ColorMaterial.GetLineMaterial(this.m_Color)); text.position.copy(p);
this.updateObjQuaternion(text, ro);
} }
//更新对象四元数 //更新对象四元数
UpdateObjQuaternion(text: THREE.Mesh, rot: number) updateObjQuaternion(text: THREE.Mesh, rot: number)
{ {
let q = new Quaternion().setFromAxisAngle(this.Normal, rot); let q = new Quaternion().setFromAxisAngle(this.Normal, rot);
text.quaternion.copy(q); 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,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-----------------------------
} }

@ -5,6 +5,8 @@ import { isBetweenNums } from '../../Common/Utils';
import { midPoint } from '../../Geometry/GeUtils'; import { midPoint } from '../../Geometry/GeUtils';
import { RenderType } from '../../GraphicsSystem/Enum'; import { RenderType } from '../../GraphicsSystem/Enum';
import { AlignedDimension } from './AlignedDimension'; import { AlignedDimension } from './AlignedDimension';
import { Line } from '../Line';
import { Factory } from '../CADFactory';
enum DimDir enum DimDir
{ {
@ -20,6 +22,7 @@ enum DimDir
* @class LinearDimension * @class LinearDimension
* @extends {AlignedDimension} * @extends {AlignedDimension}
*/ */
@Factory
export class LinearDimension extends AlignedDimension export class LinearDimension extends AlignedDimension
{ {
//标注方向 //标注方向
@ -43,42 +46,45 @@ export class LinearDimension extends AlignedDimension
this.m_DimDir = DimDir.V; this.m_DimDir = DimDir.V;
} }
//尺寸线拉伸出的2点 //尺寸线拉伸出的2点
let LinePt1: Vector3; let endPt1: Vector3;
let LinePt2: Vector3; let endPt2: Vector3;
let extPt1: Vector3;
let extPt2: Vector3;
// 水平标注 // 水平标注
if (this.m_DimDir === DimDir.H) if (this.m_DimDir === DimDir.H)
{ {
let startHeight = this.LinePoint.y - this.StartPoint.y; let startHeight = this.LinePoint.y - this.StartPoint.y;
let endHeight = this.LinePoint.y - this.EndPoint.y; let endHeight = this.LinePoint.y - this.EndPoint.y;
LinePt1 = this.StartPoint.clone().setY(this.StartPoint.y + startHeight) endPt1 = this.StartPoint.clone().setY(this.StartPoint.y + startHeight);
LinePt2 = this.EndPoint.clone().setY(this.EndPoint.y + endHeight) 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));
} }
else else
{ {
let startHeight = this.LinePoint.x - this.StartPoint.x; let startHeight = this.LinePoint.x - this.StartPoint.x;
let endHeight = this.LinePoint.x - this.EndPoint.x; let endHeight = this.LinePoint.x - this.EndPoint.x;
LinePt1 = this.StartPoint.clone().setX(this.StartPoint.x + startHeight) endPt1 = this.StartPoint.clone().setX(this.StartPoint.x + startHeight);
LinePt2 = this.EndPoint.clone().setX(this.EndPoint.x + endHeight) 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);
this.TextPosition = midPoint(LinePt1, LinePt2); return [endPt1, endPt2, extPt1, extPt2, scalePt1, scalePt2];
this.TextRotation = this.m_DimDir === DimDir.H ? 0 : Math.PI / 2;
return [LinePt1, LinePt2];
} }
UpdateDrawObjectMaterial(type: RenderType, en: Object3D) setTxtPosAndRotation(endPt1: Vector3, endPt2: Vector3)
{ {
super.UpdateDrawObjectMaterial(type, en); this.TextPosition = midPoint(endPt1, endPt2);
let dim = en as THREE.Group; this.TextRotation = this.m_DimDir === DimDir.H ? 0 : Math.PI / 2;
let pts = this.GetDimPts(); }
let objs = dim.children as THREE.Mesh[]; getArrowRotation(sp: Vector3, ep: Vector3)
this.UpdateObjQuaternion(objs[3], this.TextRotation); {
return this.m_DimDir === DimDir.H ?
let [startRotation, endRotation] = this.getArrowRotation(); [this.TextRotation, this.TextRotation - Math.PI]
: [this.TextRotation - Math.PI, this.TextRotation];
this.UpdateObjQuaternion(objs[4], startRotation);
this.UpdateObjQuaternion(objs[5], endRotation);
} }
} }

@ -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);
// })
}
}

@ -1,31 +1,21 @@
import * as THREE from 'three'; import * as THREE from 'three';
import { Geometry, Matrix4, Object3D, Vector2, Vector3, Box3 } from 'three'; import { Geometry, Matrix4, Object3D, Vector2, Vector3, Box3, Interpolant } from 'three';
import { CreateBoardUtil } from '../ApplicationServices/mesh/createBoard'; import { CreateBoardUtil } from '../ApplicationServices/mesh/createBoard';
import { ColorMaterial } from '../Common/ColorPalette'; import { ColorMaterial } from '../Common/ColorPalette';
import import
{ {
getArcAngleBy3Pt,
getArcArea,
getArcProps,
getArcPtLenAndAngle,
getArcAngle,
getClosestPt,
getCurveLength,
getDeterminant,
getPtAtCurveParam,
isPtOnArc,
rotateLine, rotateLine,
Vec2DTo3D, Vec2DTo3D,
Vec3DTo2D, Vec3DTo2D,
ExtendDir, ExtendDir,
getDeterminant,
} from '../Common/CurveUtils'; } from '../Common/CurveUtils';
import { equal, equaln } from '../Geometry/GeUtils'; import { equal, equaln, updateGeometry, angle } from '../Geometry/GeUtils';
import { RenderType } from '../GraphicsSystem/Enum'; import { RenderType } from '../GraphicsSystem/Enum';
import { Factory } from './CADFactory'; import { Factory } from './CADFactory';
import { CADFile } from './CADFile'; import { CADFile } from './CADFile';
import { Curve, ExtendType } from './Curve'; import { Curve, ExtendType } from './Curve';
import { app } from '../ApplicationServices/Application';
import { angleTo } from './../Geometry/GeUtils'; import { angleTo } from './../Geometry/GeUtils';
import { IntersectOption, IntersectLineAndCircle, IntersectLAndL, IntersectPolylineAndCurve } from '../GraphicsSystem/IntersectWith'; import { IntersectOption, IntersectLineAndCircle, IntersectLAndL, IntersectPolylineAndCurve } from '../GraphicsSystem/IntersectWith';
import { intercept } from 'mobx'; import { intercept } from 'mobx';
@ -135,13 +125,11 @@ export class Polyline extends Curve
let endV = this.m_LineData[i + 1]; let endV = this.m_LineData[i + 1];
area += getDeterminant(startV.pt, endV.pt) / 2 area += getDeterminant(startV.pt, endV.pt) / 2
if (startV.bul < 0)
{ if (startV.bul != 0)
area -= getArcArea(startV.pt, endV.pt, startV.bul);
}
else if (startV.bul > 0)
{ {
area += getArcArea(startV.pt, endV.pt, startV.bul); let arc = new Arc().ParseFromBul(startV.pt, endV.pt, startV.bul);
area += arc.Area * Math.sign(startV.bul);
} }
} }
if (!this.IsClose) if (!this.IsClose)
@ -686,10 +674,10 @@ export class Polyline extends Curve
{ {
if (startV.bul !== 0) if (startV.bul !== 0)
{ {
//获取前面线的圆心角 let arc = new Arc().ParseFromBul(startV.pt, endV.pt, startV.bul);
let insertPtCirAngle = getArcPtLenAndAngle(startV.pt, endV.pt, startV.bul, insertPt).angle; arc.EndPoint = insertPt;
//前面线的凸度调整 //前面线的凸度调整
startV.bul = Math.tan(insertPtCirAngle / 4); startV.bul = Math.tan(arc.AllAngle / 4) * Math.sign(startV.bul);
} }
} }
// 根据交点调整后面线段的凸度和起始点 // 根据交点调整后面线段的凸度和起始点
@ -698,21 +686,9 @@ export class Polyline extends Curve
let bul = 0; let bul = 0;
if (startV.bul !== 0) if (startV.bul !== 0)
{ {
//获取后面线的圆心角 let arc = new Arc().ParseFromBul(startV.pt, endV.pt, startV.bul);
let intPtCirAng; arc.StartPoint = interPt;
//圆心角 bul = Math.tan(arc.AllAngle * 0.25) * Math.sign(startV.bul);
let circleAngle = Math.atan(startV.bul) * 4;
let arcData = getArcProps(startV.pt, endV.pt, startV.bul);
//起始线
let startLine = Vec2DTo3D(arcData.startVec);
//圆心到交点连线
let interLine = interPt.clone().sub(Vec2DTo3D(arcData.centerPt));
let ang = angleTo(startLine, interLine);
intPtCirAng = circleAngle - ang;
bul = Math.tan(intPtCirAng / 4);
} }
// 调整后面线起始点和凸度 // 调整后面线起始点和凸度
startV.pt = Vec3DTo2D(interPt); startV.pt = Vec3DTo2D(interPt);
@ -922,14 +898,14 @@ export class Polyline extends Curve
let pts = tmpPlLine.IntersectWith(insertLine, IntersectOption.OnBothOperands); let pts = tmpPlLine.IntersectWith(insertLine, IntersectOption.OnBothOperands);
//此处为测试代码 // //此处为测试代码
if (pts.length === 0) // if (pts.length === 0)
{ // {
app.m_Database.ModelSpace.Append(insertLine); // app.m_Database.ModelSpace.Append(insertLine);
app.m_Database.ModelSpace.Append(tmpPlLine); // app.m_Database.ModelSpace.Append(tmpPlLine);
pts.push(centerPt); // pts.push(centerPt);
} // }
intPt = pts[0]; intPt = pts[0];
let insLine = intPt.clone().sub(centerPt); let insLine = intPt.clone().sub(centerPt);
circleAngle = angleTo(insLine, radLine); circleAngle = angleTo(insLine, radLine);
@ -1233,18 +1209,10 @@ export class Polyline extends Curve
UpdateDrawObject(type: RenderType, en: Object3D) UpdateDrawObject(type: RenderType, en: Object3D)
{ {
let plObj = en as THREE.Line; let plObj = en as THREE.Line;
let geo = new Geometry();
let geo = plObj.geometry as THREE.Geometry;
geo.dispose();
geo = new Geometry();
plObj.geometry = new Geometry();
geo = plObj.geometry;
let curve = this.CreateCurve(); let curve = this.CreateCurve();
geo.setFromPoints(curve.getPoints(50)); geo.setFromPoints(curve.getPoints(50));
updateGeometry(plObj, geo);
geo.verticesNeedUpdate = true;
geo.computeBoundingSphere();
} }
ApplyMatrix(m: THREE.Matrix4) ApplyMatrix(m: THREE.Matrix4)
{ {

@ -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-----------------------------
}

@ -6,7 +6,6 @@ import { Union } from '../Add-on/CSGUnion';
import { DrawArc } from '../Add-on/DrawArc'; import { DrawArc } from '../Add-on/DrawArc';
import { Command_DrawBoard } from '../Add-on/DrawBoard'; import { Command_DrawBoard } from '../Add-on/DrawBoard';
import { DrawAlignedDimension } from '../Add-on/DrawDim/DrawAlignedDimension'; import { DrawAlignedDimension } from '../Add-on/DrawDim/DrawAlignedDimension';
import { DrawLinearDimension } from '../Add-on/DrawDim/DrawLinearDimension';
import { DrawEllipse } from '../Add-on/DrawEllipse'; import { DrawEllipse } from '../Add-on/DrawEllipse';
import { DrawFloor } from '../Add-on/DrawFloor'; import { DrawFloor } from '../Add-on/DrawFloor';
import { DrawGripStretch } from '../Add-on/DrawGripStretch'; import { DrawGripStretch } from '../Add-on/DrawGripStretch';
@ -46,7 +45,10 @@ import { Command_Trim } from '../Add-on/Trim';
import { Redo, Undo } from '../Add-on/Undo'; import { Redo, Undo } from '../Add-on/Undo';
import { ViewToFront, ViewToRight, ViewToTop } from '../Add-on/ViewChange'; import { ViewToFront, ViewToRight, ViewToTop } from '../Add-on/ViewChange';
import { commandMachine } from './CommandMachine'; import { commandMachine } from './CommandMachine';
import { DrawLinearDimension } from '../Add-on/DrawDim/DrawLinearDimension';
import { DrawLineAngularDimension } from '../Add-on/DrawDim/DrawLineAngularDimension';
import { Command_DimTest } from '../DatabaseServices/Dimension/dimTest';
import { DrawText } from '../Add-on/DrawText';
// import { DrawFloor } from '../Add-on/DrawFloor'; // import { DrawFloor } from '../Add-on/DrawFloor';
// import { RevTarget, SaveTarget } from '../Add-on/RenderTarget'; // import { RevTarget, SaveTarget } from '../Add-on/RenderTarget';
export function registerCommand() export function registerCommand()
@ -86,7 +88,7 @@ export function registerCommand()
commandMachine.RegisterCommand("ys", new ViewToRight()) commandMachine.RegisterCommand("ys", new ViewToRight())
commandMachine.RegisterCommand("tt", new Test()) // commandMachine.RegisterCommand("tt", new Test())
commandMachine.RegisterCommand("grip", new DrawGripStretch()) commandMachine.RegisterCommand("grip", new DrawGripStretch())
@ -137,23 +139,22 @@ export function registerCommand()
commandMachine.RegisterCommand("sl", new TestDrawSpotLight()); commandMachine.RegisterCommand("sl", new TestDrawSpotLight());
commandMachine.RegisterCommand("dal", new DrawAlignedDimension()); commandMachine.RegisterCommand("dal", new DrawAlignedDimension());
commandMachine.RegisterCommand("dli", new DrawLinearDimension()); commandMachine.RegisterCommand("dli", new DrawLinearDimension());
commandMachine.RegisterCommand("dan", new DrawLineAngularDimension());
commandMachine.RegisterCommand("text", new DrawText());
/*******test ↓↓↓*********/
commandMachine.RegisterCommand("tt", new Command_PLTest()); commandMachine.RegisterCommand("tt", new Command_PLTest());
commandMachine.RegisterCommand("tt2", new Command_INsTest()); commandMachine.RegisterCommand("tt2", new Command_INsTest());
commandMachine.RegisterCommand("x", new Command_Export()); commandMachine.RegisterCommand("x", new Command_Export());
commandMachine.RegisterCommand("close", new Command_ClosePt()); commandMachine.RegisterCommand("close", new Command_ClosePt());
//用于测试包围盒 //用于测试包围盒
commandMachine.RegisterCommand("box", new Command_TestBox()); commandMachine.RegisterCommand("box", new Command_TestBox());
commandMachine.RegisterCommand("testoffset", new Command_TestOffset()); commandMachine.RegisterCommand("testoffset", new Command_TestOffset());
//测试标注
commandMachine.RegisterCommand("testdim", new Command_DimTest());
// commandMachine.RegisterCommand("st", new SaveTarget()) // commandMachine.RegisterCommand("st", new SaveTarget())
// commandMachine.RegisterCommand("rt", new RevTarget()) // commandMachine.RegisterCommand("rt", new RevTarget())
} }

@ -1,4 +1,4 @@
import { Matrix4, Vector2, Vector3 } from 'three'; import { Matrix4, Vector2, Vector3, Geometry } from 'three';
import * as THREE from 'three'; import * as THREE from 'three';
import { rotateLine } from '../Common/CurveUtils'; import { rotateLine } from '../Common/CurveUtils';
@ -206,7 +206,42 @@ export function getProjectDist(v1: Vector3, v2: Vector3)
v: dist * Math.sin(ang) v: dist * Math.sin(ang)
} }
} }
//获得输入点在2线组成的4个区间的位置
export function getPtPostion(sp: Vector3, ep: Vector3, c: Vector3, inPt: Vector3)
{
let l1 = sp.clone().sub(c);
let l2 = ep.clone().sub(c);
let l3 = l1.clone().negate();
let l4 = l2.clone().negate();
let inputLine = inPt.clone().sub(c);
let ang1 = angleTo(l1, l2);
let ang2 = Math.PI;
let ang3 = ang2 + Math.abs(ang1);
let inputAng = angleTo(l1, inputLine);
if (ang1 * inputAng < 0)
{
inputAng = (Math.PI * 2 - Math.abs(inputAng));
}
ang1 = Math.abs(ang1);
inputAng = Math.abs(inputAng);
if (inputAng <= ang1)
{
return { sp, ep };
} else if (inputAng > ang1 && inputAng <= ang2)
{
return { sp: c.clone().add(l3), ep }
} else if (inputAng > ang2 && inputAng <= ang3)
{
return { sp: c.clone().add(l3), ep: c.clone().add(l4) }
} else
{
return { sp, ep: c.clone().add(l4) };
}
}
export function angleAndX(v: Vector3 | Vector2)
{
return v.x ? Math.atan(v.y / v.x) : Math.PI / 2;
}
/** /**
* 0-2pi * 0-2pi
* *
@ -219,3 +254,11 @@ export function angleTo2Pi(an: number)
if (an < 0) an += Math.PI * 2 if (an < 0) an += Math.PI * 2
return an; return an;
} }
export function updateGeometry(l: THREE.Line | THREE.Mesh, geometry: Geometry)
{
let geo = l.geometry as THREE.Geometry;
geo.dispose();
l.geometry = geometry;
geometry.verticesNeedUpdate = true;
geometry.computeBoundingSphere();
}

@ -21,7 +21,7 @@ export class Matrix2
return this; return this;
} }
setRotate(theta) setRotate(theta: number): Matrix2
{ {
let el = this.el; let el = this.el;
let c = Math.cos(theta), s = Math.sin(theta); let c = Math.cos(theta), s = Math.sin(theta);

@ -78,7 +78,6 @@ export class LightModal extends React.Component<LightModalProps, LightModalState
} }
handleChangePosition = (e: React.ChangeEvent<HTMLInputElement>) => handleChangePosition = (e: React.ChangeEvent<HTMLInputElement>) =>
{ {
let targetName = e.target.name; let targetName = e.target.name;
let targetValue = e.target.value; let targetValue = e.target.value;
let pos = parseFloat(targetValue); let pos = parseFloat(targetValue);

@ -11,6 +11,7 @@ import { PointLight } from '../../../DatabaseServices/PointLight';
import { Editor } from '../../../Editor/Editor'; import { Editor } from '../../../Editor/Editor';
import { PointPick } from '../../../Editor/PointPick'; import { PointPick } from '../../../Editor/PointPick';
import { LightModal } from './LightModal'; import { LightModal } from './LightModal';
import { Text } from '../../../DatabaseServices/Text/Text';
export class ModalManage export class ModalManage
{ {
@ -53,8 +54,11 @@ export class ModalManage
clear={this.Clear} clear={this.Clear}
update={this.UpdateView} />, update={this.UpdateView} />,
this.m_ModalContainer) this.m_ModalContainer)
this.UpdateModalPosition()
} else if (en && en.userData instanceof Text)
{
en.userData.toggleTextArea();
} }
this.UpdateModalPosition()
} }
UpdateModalPosition() UpdateModalPosition()
{ {
@ -68,36 +72,38 @@ export class ModalManage
if (!dragArea) return; if (!dragArea) return;
dragArea.onmousedown = (e) => dragArea.onmousedown = (e) =>
{ {
//命令栏高度 dragArea.onmousedown = (e) =>
let commandHeight = document.getElementsByClassName("lm_item lm_row")[0].clientHeight;
//底部边界
let maxBottom = window.innerHeight - commandHeight - modal.offsetHeight + downHeight;
modalX = e.clientX - modal.offsetLeft;
modalY = e.clientY - modal.offsetTop;
modal.style.cursor = "move";
document.onmousemove = (e) =>
{ {
let moveX = e.clientX - modalX; //命令栏高度
if (moveX < 0) moveX = 0; let commandHeight = document.getElementsByClassName("lm_item lm_row")[0].clientHeight;
else if //底部边界
(moveX > window.innerWidth - modal.offsetWidth) moveX = window.innerWidth - modal.offsetWidth; let maxBottom = window.innerHeight - commandHeight - modal.offsetHeight + downHeight;
let moveY = e.clientY - modalY;
if (moveY < 40) moveY = 40;
else if (moveY > maxBottom) moveY = maxBottom;
modal.style.left = moveX + "px";
modal.style.top = moveY + "px";
modalX = e.clientX - modal.offsetLeft; modalX = e.clientX - modal.offsetLeft;
modalY = e.clientY - modal.offsetTop; modalY = e.clientY - modal.offsetTop;
modal.style.cursor = "move";
document.onmousemove = (e) =>
{
let moveX = e.clientX - modalX;
if (moveX < 0) moveX = 0;
else if
(moveX > window.innerWidth - modal.offsetWidth) moveX = window.innerWidth - modal.offsetWidth;
let moveY = e.clientY - modalY;
if (moveY < 40) moveY = 40;
else if (moveY > maxBottom) moveY = maxBottom;
modal.style.left = moveX + "px";
modal.style.top = moveY + "px";
modalX = e.clientX - modal.offsetLeft;
modalY = e.clientY - modal.offsetTop;
}
}
document.onmouseup = (e) =>
{
modal.style.cursor = "default";
document.onmousemove = null;
} }
} }
document.onmouseup = (e) =>
{
modal.style.cursor = "default";
document.onmousemove = null;
}
} }
UpdateView() UpdateView()
{ {

@ -76,7 +76,8 @@ export class InputHint extends React.Component<InputHintProps, InputHitState>
{ {
this.m_InputEl.focus(); this.m_InputEl.focus();
} }
this.handleOnChangeIntelliSense(this.m_InputEl.value); //导致上下键切换命令时bug
// this.handleOnChangeIntelliSense(this.m_InputEl.value);
this.handleKeyboardEvent(e); this.handleKeyboardEvent(e);
if (e.keyCode === KeyBoard.Space) if (e.keyCode === KeyBoard.Space)

Loading…
Cancel
Save