diff --git a/src/Common/Matrix4Utils.ts b/src/Common/Matrix4Utils.ts index b5c39fec4..240b0cdc8 100644 --- a/src/Common/Matrix4Utils.ts +++ b/src/Common/Matrix4Utils.ts @@ -50,13 +50,20 @@ export function matrixIsCoplane(matrixFrom: Matrix4, matrixTo: Matrix4, fuzz = 1 return equaln(pt.z, 0, fuzz); } -//构造缩放矩阵 +//构造缩放矩阵 等比例 export function matrixScale(scale: number, center?: Vector3) { - let scaleMat = new Matrix4().makeScale(scale, scale, scale); - if (center) - scaleMat.setPosition(center.clone().multiplyScalar(1 - scale)); - return scaleMat; + let scaleMtx = new Matrix4().makeScale(scale, scale, scale); + if (center) scaleMtx.setPosition(center.clone().multiplyScalar(1 - scale)); + return scaleMtx; +} + +//缩放矩阵 不等比例 +export function MakeScaleMatrix(scaleX: number, scaleY: number, scaleZ: number, center?: Vector3) +{ + let scaleMtx = new Matrix4().makeScale(scaleX, scaleY, scaleZ); + if (center) scaleMtx.setPosition(center.clone().applyMatrix4(scaleMtx).sub(center).negate()); + return scaleMtx; } /** diff --git a/src/DatabaseServices/Entity/Entity.ts b/src/DatabaseServices/Entity/Entity.ts index e1ca480f3..566fd7582 100644 --- a/src/DatabaseServices/Entity/Entity.ts +++ b/src/DatabaseServices/Entity/Entity.ts @@ -32,8 +32,8 @@ export class Entity extends CADObject * 该实体的只有一个渲染类型,任何渲染类型都一个样 */ protected OnlyRenderType = false; - protected HasEdgeRenderType = false; - protected HasPlaceFaceRenderType = false; + protected HasEdgeRenderType = false;//拥有封边检查绘制模式 + protected HasPlaceFaceRenderType = false;//拥有排版面绘制模式 protected _CacheDrawObject = new Map(); //材质id diff --git a/src/DatabaseServices/Entity/EntityRef.ts b/src/DatabaseServices/Entity/EntityRef.ts index 5d2468523..9103967df 100644 --- a/src/DatabaseServices/Entity/EntityRef.ts +++ b/src/DatabaseServices/Entity/EntityRef.ts @@ -3,6 +3,7 @@ import { ConverMaterial2, ParseBoxUrl, ParseFBXUrl, UE_FBX_LOADER } from "../../ import { BoxLine } from "../../Add-on/testEntity/TestBoundaryBox"; import { ColorMaterial } from "../../Common/ColorPalette"; import { DisposeThreeObj, Object3DRemoveAll } from "../../Common/Dispose"; +import { UpdateDraw } from "../../Common/Status"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { Box3Ext } from "../../Geometry/Box"; import { equalv3 } from "../../Geometry/GeUtils"; @@ -57,6 +58,24 @@ export class EntityRef extends Entity size.clone().multiplyScalar(0.5).add(this._Center)); } + CloneDrawObject(from: this) + { + for (let [type, obj] of from._CacheDrawObject) + { + let oldUserDaata = obj.userData; + obj.traverse(o => o.userData = {}); + let newObj = obj.clone(); + obj.userData = oldUserDaata; + // obj.userData.IsClone = true;//因为这个实体不需要修改内部的geom 所以我们可以复用她 + + newObj.matrix = this._Matrix; + newObj.userData = { Entity: this }; + // newObj.userData.IsClone = true; //因为这个实体不需要修改内部的geom 所以我们可以复用她 + this._CacheDrawObject.set(type, newObj); + } + this.NeedUpdateFlag = UpdateDraw.None; + } + ApplyScaleMatrix(m: Matrix4) { this.WriteAllObjectRecord(); diff --git a/src/Editor/TranstrolControl/TransformServices.ts b/src/Editor/TranstrolControl/TransformServices.ts index 5c541d247..723a601e7 100644 --- a/src/Editor/TranstrolControl/TransformServices.ts +++ b/src/Editor/TranstrolControl/TransformServices.ts @@ -5,7 +5,7 @@ import { CommandNames } from '../../Common/CommandNames'; import { DisposeThreeObj } from '../../Common/Dispose'; import { InputState } from '../../Common/InputState'; import { MouseKey } from '../../Common/KeyEnum'; -import { MakeRotateMatrix4 } from '../../Common/Matrix4Utils'; +import { MakeRotateMatrix4, MakeScaleMatrix, matrixScale } from '../../Common/Matrix4Utils'; import { UpdateDraw } from '../../Common/Status'; import { CommandHistoryRecord } from '../../DatabaseServices/CommandHistoryRecord'; import { Curve } from '../../DatabaseServices/Entity/Curve'; @@ -31,6 +31,8 @@ import { RotateGizmo } from './RotateGizmo'; import { ScaleGizmo } from './ScaleGizmo'; import { TranslateGizmo } from './TranslateGizmo'; +const minScale = 0.3; + export enum TransMode { Move = 0, @@ -145,7 +147,22 @@ export class TransformServicess implements EditorService { await this.StartRotate(axes.AxtiveIndex); } - + else if (axes instanceof ScaleGizmo) + { + if (index >= 0 && index < 3) + { + await this.StartAxisScale(index); + } + else if (index === AxisType.Origin) + { + await this.StarScale(); + } + else if (index > 3 && index < 7) + { + index = index - 4; + await this.StartFaceScale(index); + } + } return true; } @@ -605,6 +622,277 @@ export class TransformServicess implements EditorService app.Editor.UcsServices.Visible = bakVis; } + //轴缩放 + private async StartAxisScale(index: AxisType) + { + await CommandWrap(async () => + { + let bakVis = app.Editor.UcsServices.Visible; + app.Editor.UcsServices.Visible = false; + + let bakGrid = app.Viewer.GripScene.visible; + app.Viewer.GripScene.visible = false; + + let bakUCS = app.Editor.UCSMatrix; + app.Editor.UCSMatrix = this._Matrix; //合理的UCS是关键,当用户转动视图时,我们也应该给予正确的UCS UP:看起来又不需要? 因为我们有Z捕捉 + + let bakSnapMode = app.Editor.GetPointServices.snapServices.SnapModeEnable; + app.Editor.GetPointServices.snapServices.SnapModeEnable = 0; + + let bakSnapAxisMode = app.Editor.GetPointServices.snapServices.AxisSnapMode; //TODO:按下F3 F8时,坑爹的userconfig.Upload会刷新捕捉模式,导致自定义捕捉模式失效 + app.Editor.GetPointServices.snapServices.AxisSnapMode = AxisSnapMode.Custom; + + let bakLength = app.Viewer.PreViewer.Cursor.LineLength2D; + app.Viewer.PreViewer.Cursor.LineLength2D = 10; + + let timer = setTimeout(() => + { + app.Editor.MouseCtrl.EnableMouseUpDoit = true; //响应鼠标抬起就绘制 + }, 150); + + let mtxInv = new Matrix4().getInverse(this._Matrix); + + let pos = new Vector3().setFromMatrixColumn(this._Matrix, 3); + let axis = new Vector3().setFromMatrixColumn(this._Matrix, index); //正常指向 + let mouseP = PtCPToAxis(pos, pos.clone().add(axis), app.Editor.MouseCtrl._CurMousePointVCS).cp; + app.Editor.GetPointServices.snapServices.CustomAxis = [[XAxis, YAxis, ZAxis][index]]; + + let jigEns = this._Ents.map(e => JigUtils.Draw(e)); + + for (let e of this._Ents) + e.DrawObject.visible = false; + + mouseP.applyMatrix4(mtxInv); + for (let i = 0; i < 3; i++) + if (i !== index) + mouseP.setComponent(i, 0); + mouseP.applyMatrix4(this._Matrix); + + let distance: number; + let scaleVector = new Vector3(1, 1, 1); + let scaleRes = await this._Editor.GetDistance({ + Msg: "输入缩放比例:", + BasePoint: mouseP, + CalcDistance: (baseP, pt) => + { + if (!distance) + distance = baseP.distanceTo(pos); + return pt.distanceTo(pos) / distance; + }, + Callback: (scale) => + { + if (equaln(scale, 0)) return; + scaleVector.setComponent(index, scale); + JigUtils.Restore(); + + for (let e of jigEns) + { + let OCS = e.OCS; + let OCSInv = e.OCSInv; + e.ApplyMatrix(OCSInv); + e.ApplyMatrix(MakeScaleMatrix(scaleVector.x, scaleVector.y, scaleVector.z, e.BoundingBox.getCenter(new Vector3))); + e.ApplyMatrix(OCS); + } + } + }); + + clearTimeout(timer); + app.Editor.MouseCtrl.EnableMouseUpDoit = false; //响应鼠标抬起就绘制 + + if (scaleRes.Status === PromptStatus.OK) + { + let scale = scaleRes.Distance; + scaleVector.setComponent(index, scale); + + for (let e of this._Ents) + { + let OCS = e.OCS; + let OCSInv = e.OCSInv; + e.ApplyMatrix(OCSInv); + e.ApplyMatrix(MakeScaleMatrix(scaleVector.x, scaleVector.y, scaleVector.z, e.BoundingBox.getCenter(new Vector3))); + e.ApplyMatrix(OCS); + } + } + + for (let e of this._Ents) + e.DrawObject.visible = true; + app.Viewer.PreViewer.Cursor.LineLength2D = bakLength; + app.Viewer.GripScene.visible = true; + app.Editor.GetPointServices.snapServices.AxisSnapMode = bakSnapAxisMode; + app.Editor.GetPointServices.snapServices.SnapModeEnable = bakSnapMode; + app.Editor.UCSMatrix = bakUCS; + app.Viewer.GripScene.visible = bakGrid; + app.Editor.UcsServices.Visible = bakVis; + }, CommandNames.Scale); + } + + //面缩放 + private async StartFaceScale(index: AxisType) + { + await CommandWrap(async () => + { + let bakGrid = app.Viewer.GripScene.visible; + app.Viewer.GripScene.visible = false; + + let bakUCS = app.Editor.UCSMatrix; + + let bakSnapMode = app.Editor.GetPointServices.snapServices.SnapModeEnable; + app.Editor.GetPointServices.snapServices.SnapModeEnable = 0; + + let bakSnapAxisMode = app.Editor.GetPointServices.snapServices.AxisSnapMode; //TODO:按下F3 F8时,坑爹的userconfig.Upload会刷新捕捉模式,导致自定义捕捉模式失效 + app.Editor.GetPointServices.snapServices.AxisSnapMode = AxisSnapMode.Custom; + + let timer = setTimeout(() => + { + app.Editor.MouseCtrl.EnableMouseUpDoit = true; //响应鼠标抬起就绘制 + }, 150); + + for (let e of this._Ents) + e.DrawObject.visible = false; + + let pos = new Vector3().setFromMatrixColumn(this._Matrix, 3); + let axis = new Vector3().setFromMatrixColumn(this._Matrix, index); + + let z = axis; + let x = new Vector3().setFromMatrixColumn(this._Matrix, FixIndex(index + 1, 3)); + let y = new Vector3().setFromMatrixColumn(this._Matrix, FixIndex(index + 2, 3)); + let ucsRo = new Matrix4().makeBasis(x, y, z); + let ucsMtx = ucsRo.clone().setPosition(pos); + let sizeOrg = this._Ents[0].BoundingBoxInOCS.getSize(new Vector3); + app.Editor.UCSMatrix = ucsMtx; + + let mouseP = app.Editor.MouseCtrl._CurMousePointWCS.clone(); + let jigEns = this._Ents.map(e => JigUtils.Draw(e)); + + let ptRes = await this._Editor.GetRectPoint({ + Msg: "指定位置或者输入距离:", + BasePoint: mouseP, + Callback: (p1UCS, p2UCS) => + { + //转化到实体坐标系上的距离 + let sizeNew = p2UCS.clone().sub(p1UCS).applyMatrix4(ucsRo); + let scaleVec = this.GetScaleVector(sizeNew, sizeOrg); + + JigUtils.Restore(); + for (let e of jigEns) + { + let OCS = e.OCS; + let OCSInv = e.OCSInv; + e.ApplyMatrix(OCSInv); + e.ApplyMatrix(MakeScaleMatrix(scaleVec.x, scaleVec.y, scaleVec.z, e.BoundingBox.getCenter(new Vector3))); + e.ApplyMatrix(OCS); + } + } + }); + clearTimeout(timer); + app.Editor.MouseCtrl.EnableMouseUpDoit = false; //响应鼠标抬起就绘制 + + if (ptRes.Status === PromptStatus.OK) + { + let sizeNew = ptRes.Point2UCS.sub(ptRes.Point1UCS).applyMatrix4(ucsRo); + let scaleVec = this.GetScaleVector(sizeNew, sizeOrg); + + for (let e of this._Ents) + { + let OCS = e.OCS; + let OCSInv = e.OCSInv; + e.ApplyMatrix(OCSInv); + e.ApplyMatrix(MakeScaleMatrix(scaleVec.x, scaleVec.y, scaleVec.z, e.BoundingBox.getCenter(new Vector3))); + e.ApplyMatrix(OCS); + } + } + + for (let e of this._Ents) + e.DrawObject.visible = true; + app.Viewer.GripScene.visible = true; + app.Editor.GetPointServices.snapServices.AxisSnapMode = bakSnapAxisMode; + app.Editor.GetPointServices.snapServices.SnapModeEnable = bakSnapMode; + app.Editor.UCSMatrix = bakUCS; + app.Viewer.GripScene.visible = bakGrid; + }, CommandNames.Scale); + } + + //整体缩放 + private async StarScale() + { + await CommandWrap(async () => + { + let bakSnapMode = app.Editor.GetPointServices.snapServices.SnapModeEnable; + app.Editor.GetPointServices.snapServices.SnapModeEnable = 0; + + let bakSnapAxisMode = app.Editor.GetPointServices.snapServices.AxisSnapMode; //TODO:按下F3 F8时,坑爹的userconfig.Upload会刷新捕捉模式,导致自定义捕捉模式失效 + app.Editor.GetPointServices.snapServices.AxisSnapMode = AxisSnapMode.None; + + let bakLength = app.Viewer.PreViewer.Cursor.LineLength2D; + app.Viewer.PreViewer.Cursor.LineLength2D = 10; + + let timer = setTimeout(() => + { + app.Editor.MouseCtrl.EnableMouseUpDoit = true; //响应鼠标抬起就绘制 + }, 150); + + for (let e of this._Ents) + e.DrawObject.visible = false; + + let pos = new Vector3().setFromMatrixColumn(this._Matrix, 3); + + let size = this._Ents[0].BoundingBox.getSize(new Vector3).divideScalar(2); + let mouseP: number; + let jigEns = this._Ents.map(e => JigUtils.Draw(e)); + let scaleRes = await this._Editor.GetDistance({ + Msg: "输入缩放比例:", + BasePoint: pos, + CalcDistance: (pos, p) => + { + if (!mouseP) + mouseP = p.distanceTo(pos); + if (p.distanceTo(pos) < mouseP) + return p.distanceTo(pos) / mouseP; + else + return (p.distanceTo(pos) - mouseP) / size.distanceTo(new Vector3) + 1; + }, + Callback: (distance) => + { + if (equaln(distance, 0)) return; + JigUtils.Restore(); + let mtx = matrixScale(distance, pos); + for (let en of jigEns) + en.ApplyMatrix(mtx); + } + }); + + clearTimeout(timer); + app.Editor.MouseCtrl.EnableMouseUpDoit = false; //响应鼠标抬起就绘制 + + if (scaleRes.Status === PromptStatus.OK) + { + let mtx = matrixScale(scaleRes.Distance, pos); + for (let en of this._Ents) + en.ApplyMatrix(mtx); + } + + for (let en of this._Ents) + en.DrawObject.visible = true; + app.Viewer.PreViewer.Cursor.LineLength2D = bakLength; + app.Viewer.GripScene.visible = true; + app.Editor.GetPointServices.snapServices.AxisSnapMode = bakSnapAxisMode; + app.Editor.GetPointServices.snapServices.SnapModeEnable = bakSnapMode; + }, CommandNames.Scale); + } + + private GetScaleVector(vector: Vector3, size: Vector3) + { + let scaleVector = new Vector3(vector.x / size.x + 1, vector.y / size.y + 1, vector.z / size.z + 1); + scaleVector.x = scaleVector.x < minScale ? minScale : scaleVector.x; + scaleVector.y = scaleVector.y < minScale ? minScale : scaleVector.y; + scaleVector.z = scaleVector.z < minScale ? minScale : scaleVector.z; + + scaleVector.x = scaleVector.x < 0.3 ? 0.3 : scaleVector.x; + scaleVector.y = scaleVector.y < 0.3 ? 0.3 : scaleVector.y; + scaleVector.z = scaleVector.z < 0.3 ? 0.3 : scaleVector.z; + return scaleVector; + } + private InitAxes(preView: PreViewer) { for (let a of this._CtrlAxes)