|
|
|
@ -1,131 +1,255 @@
|
|
|
|
|
import * as THREE from 'three';
|
|
|
|
|
import { Matrix4, Vector3 } from 'three';
|
|
|
|
|
import { BufferGeometry, Line, Matrix4, Object3D, Vector3, PerspectiveCamera } from 'three';
|
|
|
|
|
import { app } from '../ApplicationServices/Application';
|
|
|
|
|
import { ColorMaterial } from '../Common/ColorPalette';
|
|
|
|
|
import { DisposeThreeObj } from '../Common/Dispose';
|
|
|
|
|
import { GetPointPrompt } from '../Common/InputState';
|
|
|
|
|
import { Entity } from '../DatabaseServices/Entity';
|
|
|
|
|
import { equaln, fixAngle, polar, SnapPoint } from '../Geometry/GeUtils';
|
|
|
|
|
import { Line as DbLine } from "../DatabaseServices/Line";
|
|
|
|
|
import { BufferGeometryUtils } from '../Geometry/BufferGeometryUtils';
|
|
|
|
|
import { cXAxis, cYAxis, cZAxis, isParallelTo, SnapPoint, midPoint } from '../Geometry/GeUtils';
|
|
|
|
|
import { IntersectLAndLFor3D } from '../GraphicsSystem/IntersectWith';
|
|
|
|
|
import { DrawMode } from '../GraphicsSystem/PreViewer';
|
|
|
|
|
import { PromptBlock } from '../UI/DynamicPrompt/PromptBlock';
|
|
|
|
|
import { DynamicInputManage } from '../UI/DynamicPrompt/DynamicInputManage';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 轴线捕捉模式
|
|
|
|
|
*/
|
|
|
|
|
export enum AxisSnapMode
|
|
|
|
|
{
|
|
|
|
|
Polar = 1,//极轴
|
|
|
|
|
Ortho = 2,//正交
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//捕捉轴
|
|
|
|
|
interface SnapAxis
|
|
|
|
|
{
|
|
|
|
|
BasePoint: THREE.Vector3;//基点
|
|
|
|
|
SnapPoint: THREE.Vector3;//捕捉到的点
|
|
|
|
|
BasePoint: Vector3;//基点
|
|
|
|
|
SnapPoint: Vector3;//捕捉到的点
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//轴线相交数据
|
|
|
|
|
interface SnapIntersect
|
|
|
|
|
{
|
|
|
|
|
IntersectPoint: THREE.Vector3;
|
|
|
|
|
IntersectPoint: Vector3;
|
|
|
|
|
Axis1: SnapAxis;
|
|
|
|
|
Axis2: SnapAxis;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//正交捕捉轴
|
|
|
|
|
const OrthoAxis = [cXAxis, cYAxis, cZAxis];
|
|
|
|
|
const PolarAxis = [cXAxis, new Vector3(1, 1).normalize(), cYAxis, new Vector3(-1, 1).normalize(), cZAxis];
|
|
|
|
|
|
|
|
|
|
//提供点捕捉的服务.
|
|
|
|
|
export class SnapServices
|
|
|
|
|
{
|
|
|
|
|
m_Disabled: boolean = false;//禁用捕捉
|
|
|
|
|
private preLines: THREE.Line[] = []; //前视图绘制的线表
|
|
|
|
|
notSnapEntity = new Set<Entity>();//不参与捕捉的实体列表,这个属性由开发人员维护.
|
|
|
|
|
Disabled: boolean = false;//禁用捕捉
|
|
|
|
|
SnapSize = 15;//捕捉框大小
|
|
|
|
|
private snapPoints: THREE.Vector3[] = [];//捕捉的点列表
|
|
|
|
|
AxisSnapMode = AxisSnapMode.Polar;//极轴捕捉模式
|
|
|
|
|
private m_SupportSnapPoints: Vector3[] = [];//辅助捕捉点WCS
|
|
|
|
|
private m_UCSInv: Matrix4;
|
|
|
|
|
private m_UCS: Matrix4;
|
|
|
|
|
m_AxisPts: Vector3[] = [];
|
|
|
|
|
SnapPoint: Vector3;
|
|
|
|
|
|
|
|
|
|
private m_DynPrompt: PromptBlock;
|
|
|
|
|
//开始捕捉
|
|
|
|
|
Start(prompt: GetPointPrompt)
|
|
|
|
|
{
|
|
|
|
|
if (prompt.BasePoint) this.snapPoints.push(prompt.BasePoint);
|
|
|
|
|
this.m_UCSInv = app.m_Editor.UCSMatrixInv;
|
|
|
|
|
this.m_UCS = app.m_Editor.UCSMatrix;
|
|
|
|
|
|
|
|
|
|
this.InitDynPrompt();
|
|
|
|
|
this.InitCrossCursor();
|
|
|
|
|
this.InitAxisCursor();
|
|
|
|
|
this.InitSquareCursor();
|
|
|
|
|
this.InitBiasCrossCursor();
|
|
|
|
|
this.InitBiasOutline();
|
|
|
|
|
|
|
|
|
|
if (prompt.BasePoint)
|
|
|
|
|
{
|
|
|
|
|
this.m_SupportSnapPoints.push(prompt.BasePoint.clone());
|
|
|
|
|
this.UpdateCrossCursor();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//结束捕捉服务
|
|
|
|
|
Stop()
|
|
|
|
|
{
|
|
|
|
|
this.DestroySnapLine();
|
|
|
|
|
this.snapPoints.length = 0;
|
|
|
|
|
this.m_SupportSnapPoints.length = 0;
|
|
|
|
|
this.m_AxisPts.length = 0;
|
|
|
|
|
this.SnapPoint = undefined;
|
|
|
|
|
|
|
|
|
|
this.m_DynPrompt.Visible = false;
|
|
|
|
|
|
|
|
|
|
this.UpdateCursort();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private UpdateCursort()
|
|
|
|
|
{
|
|
|
|
|
this.UpdateAxisCursor();
|
|
|
|
|
this.UpdateSquareCursor();
|
|
|
|
|
this.UpdateCrossCursor();
|
|
|
|
|
this.UpdateBiasCrossCursor();
|
|
|
|
|
this.UpdateBiasOutline();
|
|
|
|
|
this.UpdateDynPrompt();
|
|
|
|
|
|
|
|
|
|
app.m_Viewer.m_PreViewer.UpdateScreen();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GetSnapPoint()
|
|
|
|
|
/**
|
|
|
|
|
* 返回合适的捕捉点,如果有的话.
|
|
|
|
|
* @returns 捕捉点或空
|
|
|
|
|
*/
|
|
|
|
|
GetSnapPoint(): Vector3 | undefined
|
|
|
|
|
{
|
|
|
|
|
this.DestroySnapLine();
|
|
|
|
|
this.DrawSnapCross();
|
|
|
|
|
this.m_AxisPts.length = 0;
|
|
|
|
|
this.SnapPoint = this.GetEntitySnapPoint() || this.GetAxisSnapPoint();
|
|
|
|
|
|
|
|
|
|
this.UpdateCursort();
|
|
|
|
|
|
|
|
|
|
return this.GetEntitySnapPoint() || this.GetAxisSnapPoint();
|
|
|
|
|
return this.SnapPoint;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------计算函数//-------------------
|
|
|
|
|
//延迟添加辅助的捕捉点
|
|
|
|
|
private m_DelaySupportSnapId;
|
|
|
|
|
|
|
|
|
|
//根据角度进行轴线捕捉,如果存在捕捉,那么返回捕捉点,(极轴捕捉,正交捕捉)
|
|
|
|
|
private AxisSnap(basePoint: THREE.Vector3, fixAn: number): THREE.Vector3
|
|
|
|
|
/**
|
|
|
|
|
* 获得实体捕捉点,夹点,中点,垂点等
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
private GetEntitySnapPoint()
|
|
|
|
|
{
|
|
|
|
|
let ucsInv = app.m_Editor.UCSMatrixInv;
|
|
|
|
|
if (this.Disabled) return;
|
|
|
|
|
if (this.m_DelaySupportSnapId)
|
|
|
|
|
{
|
|
|
|
|
clearTimeout(this.m_DelaySupportSnapId);
|
|
|
|
|
this.m_DelaySupportSnapId = undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let vcsP = app.m_Editor.m_MouseCtrl.m_CurMousePointVCS;
|
|
|
|
|
for (let obj of app.m_Viewer.Scene.children)
|
|
|
|
|
{
|
|
|
|
|
if (obj.userData && obj.userData instanceof Entity)
|
|
|
|
|
{
|
|
|
|
|
let ent = obj.userData;
|
|
|
|
|
if (ent.IsErase || ent.Id === undefined)
|
|
|
|
|
continue;
|
|
|
|
|
for (let p of ent.GetSnapPoints())
|
|
|
|
|
{
|
|
|
|
|
let pv = p.clone();
|
|
|
|
|
app.m_Viewer.WorldToScreen(pv);
|
|
|
|
|
if (SnapPoint(vcsP, pv, this.SnapSize))
|
|
|
|
|
{
|
|
|
|
|
if (!this.m_SupportSnapPoints.some(sp => sp.distanceToSquared(p) < 1e-5))
|
|
|
|
|
{
|
|
|
|
|
this.m_DelaySupportSnapId = setTimeout(() =>
|
|
|
|
|
{
|
|
|
|
|
this.m_SupportSnapPoints.push(p.clone());
|
|
|
|
|
if (this.m_SupportSnapPoints.length > 7)
|
|
|
|
|
this.m_SupportSnapPoints.shift();
|
|
|
|
|
|
|
|
|
|
this.UpdateCrossCursor();
|
|
|
|
|
}, 37);
|
|
|
|
|
}
|
|
|
|
|
return p.clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let bpUCS = basePoint.clone().applyMatrix4(ucsInv);
|
|
|
|
|
let nowUCS = app.m_Editor.m_MouseCtrl.m_CurMousePointWCS.clone().applyMatrix4(ucsInv);
|
|
|
|
|
/**
|
|
|
|
|
* 根据角度进行轴线捕捉,如果存在捕捉,那么返回捕捉点,(极轴捕捉,正交捕捉)
|
|
|
|
|
* @param supportSnapPtUCS 辅助的捕捉点.
|
|
|
|
|
* @param nowPtUCS 需要捕捉点
|
|
|
|
|
* @param snapAn
|
|
|
|
|
* @param [isFirst]
|
|
|
|
|
* @returns snapUCS
|
|
|
|
|
*/
|
|
|
|
|
private AxisSnap(supportSnapPtUCS: Vector3, nowPtUCS: Vector3, isFirst = false): Vector3
|
|
|
|
|
{
|
|
|
|
|
let allowNegateSnap = true;//允许捕捉轴的反方向.
|
|
|
|
|
let allowMouseDistSq = 100;//允许鼠标距离Sq
|
|
|
|
|
let axisVecs = PolarAxis;
|
|
|
|
|
if (this.AxisSnapMode === AxisSnapMode.Ortho)
|
|
|
|
|
{
|
|
|
|
|
axisVecs = OrthoAxis;
|
|
|
|
|
if (isFirst)
|
|
|
|
|
allowMouseDistSq = Infinity;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//相差向量
|
|
|
|
|
let subVec = nowUCS.sub(bpUCS);
|
|
|
|
|
let an = Math.atan2(subVec.y, subVec.x);
|
|
|
|
|
let newan = fixAngle(an, fixAn);
|
|
|
|
|
let nowVCS = app.m_Viewer.WorldToScreen(nowPtUCS.clone().applyMatrix4(this.m_UCS));
|
|
|
|
|
|
|
|
|
|
if (!isNaN(newan))
|
|
|
|
|
let pts: Vector3[] = [supportSnapPtUCS.clone()];
|
|
|
|
|
pts.push(...axisVecs.map(v => supportSnapPtUCS.clone().add(v)));
|
|
|
|
|
for (let p of pts)
|
|
|
|
|
{
|
|
|
|
|
//dis.
|
|
|
|
|
let v0 = new THREE.Vector3(0, 0, 0);
|
|
|
|
|
polar(v0, newan, 1);
|
|
|
|
|
p.applyMatrix4(this.m_UCS);
|
|
|
|
|
app.m_Viewer.WorldToScreen(p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let dis = v0.clone().dot(subVec);
|
|
|
|
|
let minIndex = 0, minP: Vector3, minDist = Infinity;
|
|
|
|
|
|
|
|
|
|
let ucsRo = new Matrix4().extractRotation(app.m_Editor.UCSMatrix);
|
|
|
|
|
v0.multiplyScalar(dis);
|
|
|
|
|
v0.applyMatrix4(ucsRo);
|
|
|
|
|
let l = new DbLine();
|
|
|
|
|
l.StartPoint = pts[0];
|
|
|
|
|
for (let i = 1; i <= axisVecs.length; i++)
|
|
|
|
|
{
|
|
|
|
|
l.EndPoint = pts[i];
|
|
|
|
|
let { closestPt, param } = l.GetClosestAtPoint(nowVCS, true);
|
|
|
|
|
let dist = closestPt.distanceToSquared(nowVCS);
|
|
|
|
|
|
|
|
|
|
return basePoint.clone().add(v0);
|
|
|
|
|
if (dist < minDist && (allowNegateSnap || param > 0))
|
|
|
|
|
{
|
|
|
|
|
minIndex = i;
|
|
|
|
|
minDist = dist;
|
|
|
|
|
minP = closestPt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//#region Z轴捕捉
|
|
|
|
|
let zv = new Vector3(0, 0, 1);
|
|
|
|
|
zv.applyMatrix4(
|
|
|
|
|
new Matrix4().getInverse(
|
|
|
|
|
new Matrix4().extractRotation(app.m_Viewer.Camera.matrix))
|
|
|
|
|
);
|
|
|
|
|
if (equaln(zv.x, 0, 1e-8) && !(equaln(zv.y, 0, 1e-8) || equaln(zv.y, 1, 1e-8)))
|
|
|
|
|
//超过最大间隙
|
|
|
|
|
if (minDist > allowMouseDistSq)
|
|
|
|
|
return undefined;
|
|
|
|
|
|
|
|
|
|
let snapAxis = axisVecs[minIndex - 1];
|
|
|
|
|
//Z轴
|
|
|
|
|
if (isParallelTo(snapAxis, cZAxis))
|
|
|
|
|
{
|
|
|
|
|
let bpVCS = app.m_Viewer.WorldToScreen(basePoint.clone());
|
|
|
|
|
let nowVCS = app.m_Editor.m_MouseCtrl.m_CurMousePointVCS.clone();
|
|
|
|
|
let dir = app.m_Viewer.m_CameraCtrl.Direction;
|
|
|
|
|
let supWcs = supportSnapPtUCS.clone().applyMatrix4(this.m_UCS);
|
|
|
|
|
if (app.m_Viewer.Camera instanceof PerspectiveCamera)
|
|
|
|
|
dir = app.m_Viewer.Camera.position.clone().sub(supWcs);
|
|
|
|
|
|
|
|
|
|
let v = nowVCS.clone().sub(bpVCS);
|
|
|
|
|
an = Math.atan2(v.y, v.x);
|
|
|
|
|
if (Math.abs(v.x) < 8)
|
|
|
|
|
{
|
|
|
|
|
let dir = app.m_Viewer.m_CameraCtrl.Direction;
|
|
|
|
|
let zVecWcs = snapAxis.clone().applyMatrix4(new Matrix4().extractRotation(this.m_UCS));
|
|
|
|
|
|
|
|
|
|
let planVec: Vector3;
|
|
|
|
|
if (Math.abs(dir.x) > Math.abs(dir.y))
|
|
|
|
|
planVec = new Vector3(0, 1, 0);
|
|
|
|
|
else
|
|
|
|
|
planVec = new Vector3(1, 0, 0);
|
|
|
|
|
dir.cross(zVecWcs).cross(zVecWcs);
|
|
|
|
|
|
|
|
|
|
let np = app.m_Viewer.ScreenToWorld(nowVCS, planVec, basePoint);
|
|
|
|
|
return basePoint.clone().setZ(np.z);
|
|
|
|
|
}
|
|
|
|
|
let zp = app.m_Viewer.ScreenToWorld(minP, dir, supWcs).applyMatrix4(this.m_UCSInv);
|
|
|
|
|
return supportSnapPtUCS.clone().setZ(zp.z);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//相差向量
|
|
|
|
|
let subVec = nowPtUCS.clone().sub(supportSnapPtUCS);
|
|
|
|
|
let dis = snapAxis.dot(subVec);
|
|
|
|
|
return supportSnapPtUCS.clone().add(snapAxis.clone().multiplyScalar(dis));
|
|
|
|
|
}
|
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//返回合适的轴线交点,如果不存在交点,那么返回轴线上的点
|
|
|
|
|
private GetAxisSnapPoint()
|
|
|
|
|
{
|
|
|
|
|
//轴线列表
|
|
|
|
|
let snapAxisList: SnapAxis[] = this.snapPoints.map((p) =>
|
|
|
|
|
let snapAxisList: SnapAxis[] = [];
|
|
|
|
|
|
|
|
|
|
let curPUCS = app.m_Editor.m_MouseCtrl.m_CurMousePointWCS.clone().applyMatrix4(this.m_UCSInv);
|
|
|
|
|
for (let i = 0, l = this.m_SupportSnapPoints.length; i < l; i++)
|
|
|
|
|
{
|
|
|
|
|
let snapPoint = this.AxisSnap(p, Math.PI * 0.5);
|
|
|
|
|
return { BasePoint: p, SnapPoint: snapPoint };
|
|
|
|
|
}).filter(a => a.SnapPoint);
|
|
|
|
|
let supWcs = this.m_SupportSnapPoints[i];
|
|
|
|
|
let supUCS = supWcs.clone().applyMatrix4(this.m_UCSInv);
|
|
|
|
|
let snapUCS = this.AxisSnap(supUCS, curPUCS, i === 0);
|
|
|
|
|
if (snapUCS)
|
|
|
|
|
snapAxisList.push({ BasePoint: supWcs, SnapPoint: snapUCS.applyMatrix4(this.m_UCS) });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (snapAxisList.length === 0)
|
|
|
|
|
return;
|
|
|
|
@ -160,29 +284,30 @@ export class SnapServices
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let insData = axisIntersectList[0];
|
|
|
|
|
if (this.AxisSnapMode === AxisSnapMode.Ortho)
|
|
|
|
|
{
|
|
|
|
|
let p = this.AxisSnap(
|
|
|
|
|
this.m_SupportSnapPoints[0].clone().applyMatrix4(this.m_UCSInv),
|
|
|
|
|
insData.IntersectPoint.clone().applyMatrix4(this.m_UCSInv), true)
|
|
|
|
|
.applyMatrix4(this.m_UCS);
|
|
|
|
|
this.m_AxisPts = [insData.Axis1.BasePoint, p, insData.Axis2.BasePoint];
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SnapPoint(app.m_Viewer.WorldToScreen(insData.IntersectPoint.clone()), mouseVcs, this.SnapSize))
|
|
|
|
|
{
|
|
|
|
|
this.preLines.push(
|
|
|
|
|
//交叉轴线
|
|
|
|
|
app.m_Viewer.m_PreViewer.DrawLine(
|
|
|
|
|
[insData.Axis1.BasePoint, insData.IntersectPoint, insData.Axis2.BasePoint],
|
|
|
|
|
ColorMaterial.SnapAxisMaterial
|
|
|
|
|
),
|
|
|
|
|
//X光标
|
|
|
|
|
app.m_Viewer.m_PreViewer.Draw(
|
|
|
|
|
DrawMode.BaisCross,
|
|
|
|
|
this.SnapSize,
|
|
|
|
|
insData.IntersectPoint.clone(),
|
|
|
|
|
ColorMaterial.GetLineMaterial(3),
|
|
|
|
|
true
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
app.m_Viewer.m_PreViewer.UpdateScreen();
|
|
|
|
|
this.m_AxisPts = [insData.Axis1.BasePoint, insData.IntersectPoint, insData.Axis2.BasePoint];
|
|
|
|
|
return insData.IntersectPoint.clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else//如果没有交叉点,那么使用轴线上的点
|
|
|
|
|
{
|
|
|
|
|
if (this.AxisSnapMode === AxisSnapMode.Ortho)
|
|
|
|
|
{
|
|
|
|
|
this.m_AxisPts = [snapAxisList[0].BasePoint, snapAxisList[0].SnapPoint];
|
|
|
|
|
return snapAxisList[0].SnapPoint;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snapAxisList.sort((d1, d2) =>
|
|
|
|
|
{
|
|
|
|
|
return app.m_Viewer.WorldToScreen(d1.SnapPoint.clone()).distanceToSquared(mouseVcs)
|
|
|
|
@ -190,81 +315,188 @@ export class SnapServices
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let snapAxis = snapAxisList[0];
|
|
|
|
|
this.m_AxisPts = [snapAxis.BasePoint, snapAxis.SnapPoint];
|
|
|
|
|
return snapAxis.SnapPoint;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.preLines.push(
|
|
|
|
|
app.m_Viewer.m_PreViewer.DrawLine(
|
|
|
|
|
[snapAxis.BasePoint, snapAxis.SnapPoint],
|
|
|
|
|
ColorMaterial.SnapAxisMaterial
|
|
|
|
|
//#region 绘制
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 十字光标组
|
|
|
|
|
*/
|
|
|
|
|
private m_CrossCursor: Object3D[] = [];
|
|
|
|
|
/**
|
|
|
|
|
* 初始化捕捉光标(十字)
|
|
|
|
|
*/
|
|
|
|
|
private InitCrossCursor()
|
|
|
|
|
{
|
|
|
|
|
if (this.m_CrossCursor.length === 0)
|
|
|
|
|
{
|
|
|
|
|
let preView = app.m_Viewer.m_PreViewer;
|
|
|
|
|
for (let i = 0; i < 7; i++)
|
|
|
|
|
{
|
|
|
|
|
this.m_CrossCursor.push(
|
|
|
|
|
preView.Draw(
|
|
|
|
|
DrawMode.Cross,
|
|
|
|
|
this.SnapSize,
|
|
|
|
|
new Vector3(),
|
|
|
|
|
ColorMaterial.GetLineMaterial(3))
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
app.m_Viewer.m_PreViewer.UpdateScreen();
|
|
|
|
|
return snapAxis.SnapPoint;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//计算图形的捕捉点 如果有 则返回.
|
|
|
|
|
private GetEntitySnapPoint()
|
|
|
|
|
/**
|
|
|
|
|
* 更新所有的十字光标
|
|
|
|
|
*/
|
|
|
|
|
private UpdateCrossCursor()
|
|
|
|
|
{
|
|
|
|
|
if (this.m_Disabled) return;
|
|
|
|
|
let vcsP = app.m_Editor.m_MouseCtrl.m_CurMousePointVCS;
|
|
|
|
|
for (let obj of app.m_Viewer.Scene.children)
|
|
|
|
|
let preView = app.m_Viewer.m_PreViewer;
|
|
|
|
|
for (let i = 0; i < 7; i++)
|
|
|
|
|
{
|
|
|
|
|
if (obj.userData && obj.userData instanceof Entity)
|
|
|
|
|
let l = this.m_CrossCursor[i];
|
|
|
|
|
if (this.m_SupportSnapPoints[i])
|
|
|
|
|
{
|
|
|
|
|
if (this.notSnapEntity.has(obj.userData)) continue;
|
|
|
|
|
if (obj.userData.IsErase) continue;
|
|
|
|
|
if (!obj.userData.Id) continue;
|
|
|
|
|
for (let p of obj.userData.GetSnapPoints())
|
|
|
|
|
{
|
|
|
|
|
let pv = p.clone();
|
|
|
|
|
app.m_Viewer.WorldToScreen(pv);
|
|
|
|
|
if (SnapPoint(vcsP, pv, this.SnapSize))
|
|
|
|
|
{
|
|
|
|
|
if (!this.snapPoints.some(sp => { return sp.distanceToSquared(p) < 1e-5 }))
|
|
|
|
|
{
|
|
|
|
|
this.snapPoints.push(p);
|
|
|
|
|
if (this.snapPoints.length > 7)
|
|
|
|
|
this.snapPoints.shift();
|
|
|
|
|
}
|
|
|
|
|
this.preLines.push(
|
|
|
|
|
app.m_Viewer.m_PreViewer.Draw(
|
|
|
|
|
DrawMode.Square,
|
|
|
|
|
this.SnapSize,
|
|
|
|
|
p.clone(),
|
|
|
|
|
ColorMaterial.GetLineMaterial(3)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
return p.clone();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
l.position.copy(preView.WorldToViewPoint(this.m_SupportSnapPoints[i].clone()));
|
|
|
|
|
l.visible = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
l.visible = false;
|
|
|
|
|
}
|
|
|
|
|
preView.UpdateScreen();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------绘制函数-------------------
|
|
|
|
|
private m_AxisCursor: Line;
|
|
|
|
|
/**
|
|
|
|
|
* 初始化轴线光标
|
|
|
|
|
*/
|
|
|
|
|
private InitAxisCursor()
|
|
|
|
|
{
|
|
|
|
|
if (!this.m_AxisCursor)
|
|
|
|
|
this.m_AxisCursor = app.m_Viewer.m_PreViewer.DrawLine(
|
|
|
|
|
[new Vector3(), new Vector3(), new Vector3()],
|
|
|
|
|
ColorMaterial.SnapAxisMaterial,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
private UpdateAxisCursor()
|
|
|
|
|
{
|
|
|
|
|
if (this.m_AxisPts.length > 0)
|
|
|
|
|
{
|
|
|
|
|
this.m_AxisCursor.visible = true;
|
|
|
|
|
let geo = this.m_AxisCursor.geometry as BufferGeometry;
|
|
|
|
|
BufferGeometryUtils.UpdatePts(geo, this.m_AxisPts.map(p =>
|
|
|
|
|
{
|
|
|
|
|
return app.m_Viewer.m_PreViewer.WorldToViewPoint(p.clone());
|
|
|
|
|
}));
|
|
|
|
|
geo.drawRange.count = this.m_AxisPts.length;
|
|
|
|
|
this.m_AxisCursor.computeLineDistances();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
this.m_AxisCursor.visible = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//绘制所有的十字光标
|
|
|
|
|
private DrawSnapCross()
|
|
|
|
|
//方向光标,用于捕捉实体夹点
|
|
|
|
|
private m_SquareCursor: Line;
|
|
|
|
|
private InitSquareCursor()
|
|
|
|
|
{
|
|
|
|
|
let preView = app.m_Viewer.m_PreViewer;
|
|
|
|
|
for (let snapP of this.snapPoints)
|
|
|
|
|
this.preLines.push(
|
|
|
|
|
preView.Draw(
|
|
|
|
|
DrawMode.Cross,
|
|
|
|
|
this.SnapSize,
|
|
|
|
|
snapP.clone(),
|
|
|
|
|
ColorMaterial.GetLineMaterial(3))
|
|
|
|
|
if (!this.m_SquareCursor)
|
|
|
|
|
this.m_SquareCursor = app.m_Viewer.m_PreViewer.Draw(
|
|
|
|
|
DrawMode.Square, this.SnapSize, new Vector3(),
|
|
|
|
|
ColorMaterial.GetLineMaterial(3)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//销毁绘制的函数
|
|
|
|
|
private DestroySnapLine()
|
|
|
|
|
private UpdateSquareCursor()
|
|
|
|
|
{
|
|
|
|
|
this.preLines.forEach(l =>
|
|
|
|
|
this.UpdateObjectPosition(
|
|
|
|
|
this.m_SquareCursor,
|
|
|
|
|
this.SnapPoint && this.m_AxisPts.length === 0
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private m_BiasCrossCursor: Line;
|
|
|
|
|
//×光标,用于捕捉轴线
|
|
|
|
|
private InitBiasCrossCursor()
|
|
|
|
|
{
|
|
|
|
|
if (!this.m_BiasCrossCursor)
|
|
|
|
|
{
|
|
|
|
|
l.parent.remove(l);
|
|
|
|
|
DisposeThreeObj(l);
|
|
|
|
|
})
|
|
|
|
|
this.preLines.length = 0;
|
|
|
|
|
this.m_BiasCrossCursor = app.m_Viewer.m_PreViewer.Draw(
|
|
|
|
|
DrawMode.BaisCross,
|
|
|
|
|
8,
|
|
|
|
|
new Vector3(),
|
|
|
|
|
ColorMaterial.GetLineMaterial(3)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private UpdateBiasCrossCursor()
|
|
|
|
|
{
|
|
|
|
|
this.UpdateObjectPosition(
|
|
|
|
|
this.m_BiasCrossCursor,
|
|
|
|
|
this.m_AxisPts.length > 0
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private m_BiasOutline: Line;
|
|
|
|
|
//初始化X光标外包围框(虚线),用户显示光标交叉
|
|
|
|
|
private InitBiasOutline()
|
|
|
|
|
{
|
|
|
|
|
if (!this.m_BiasOutline)
|
|
|
|
|
this.m_BiasOutline = app.m_Viewer.m_PreViewer.Draw(
|
|
|
|
|
DrawMode.Square,
|
|
|
|
|
this.SnapSize,
|
|
|
|
|
new Vector3(),
|
|
|
|
|
ColorMaterial.SnapAxisMaterial,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private UpdateBiasOutline()
|
|
|
|
|
{
|
|
|
|
|
this.UpdateObjectPosition(
|
|
|
|
|
this.m_BiasOutline,
|
|
|
|
|
this.m_AxisPts.length > 2
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private UpdateObjectPosition(obj: Object3D, update: boolean)
|
|
|
|
|
{
|
|
|
|
|
if (update)
|
|
|
|
|
{
|
|
|
|
|
obj.visible = true;
|
|
|
|
|
obj.position.copy(
|
|
|
|
|
app.m_Viewer.m_PreViewer.WorldToViewPoint(this.SnapPoint.clone())
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
obj.visible = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitDynPrompt()
|
|
|
|
|
{
|
|
|
|
|
if (!this.m_DynPrompt)
|
|
|
|
|
{
|
|
|
|
|
this.m_DynPrompt = new PromptBlock(DynamicInputManage.GetManage());
|
|
|
|
|
this.m_DynPrompt.Visible = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
UpdateDynPrompt()
|
|
|
|
|
{
|
|
|
|
|
if (this.m_AxisPts.length === 2
|
|
|
|
|
&& isParallelTo(cZAxis,
|
|
|
|
|
this.m_AxisPts[1].clone().sub(this.m_AxisPts[0])
|
|
|
|
|
.applyMatrix4(new Matrix4().extractRotation(this.m_UCSInv))
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
this.m_DynPrompt.Visible = true;
|
|
|
|
|
this.m_DynPrompt.UpdatePrompt("Z轴");
|
|
|
|
|
let vps = this.m_AxisPts.map(p => app.m_Viewer.WorldToScreen(p.clone()));
|
|
|
|
|
this.m_DynPrompt.SetPostion(midPoint(vps[0], vps[1]));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
this.m_DynPrompt.Visible = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
}
|
|
|
|
|