diff --git a/__test__/Geometry/__snapshots__/intersect.test.ts.snap b/__test__/Geometry/__snapshots__/intersect.test.ts.snap index 4674cea9c..776168a64 100644 --- a/__test__/Geometry/__snapshots__/intersect.test.ts.snap +++ b/__test__/Geometry/__snapshots__/intersect.test.ts.snap @@ -1,5 +1,127 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`三维空间圆圆相交测试 1`] = ` +Array [ + Vector3 { + "x": 3.8465654731285666, + "y": -0.48984005103149847, + "z": 0.3777515851723183, + }, + Vector3 { + "x": 4.518686772594938, + "y": -2.26435797895917, + "z": -0.09066385360916496, + }, +] +`; + +exports[`三维空间圆圆相交测试 2`] = ` +Array [ + Vector3 { + "x": 1.25, + "y": -4.841229182759271, + "z": 0, + }, + Vector3 { + "x": 1.25, + "y": 4.841229182759271, + "z": 0, + }, +] +`; + +exports[`三维空间圆圆相交测试 3`] = ` +Array [ + Vector3 { + "x": 1.25, + "y": 0, + "z": -4.841229182759271, + }, + Vector3 { + "x": 1.25, + "y": 0, + "z": 4.841229182759271, + }, +] +`; + +exports[`三维空间圆圆相交测试 4`] = ` +Array [ + Vector3 { + "x": 0, + "y": -11.313088368701884, + "z": -9.556275638274851, + }, + Vector3 { + "x": 0, + "y": -9.579281670837858, + "z": -2.8986776905615708, + }, +] +`; + +exports[`三维空间圆圆相交测试 5`] = `Array []`; + +exports[`三维空间直线和圆相交测试 1`] = ` +Array [ + Vector3 { + "x": 7.265045456946406, + "y": 0, + "z": 1.5147084845720027, + }, + Vector3 { + "x": 3.9357458826357803, + "y": 0, + "z": 4.789429377336553, + }, +] +`; + +exports[`三维空间直线和圆相交测试 2`] = ` +Array [ + Vector3 { + "x": -3.622627029705465, + "y": -3.4462404738565997, + "z": 0, + }, + Vector3 { + "x": -3.622627029705464, + "y": 3.446240473856601, + "z": 0, + }, +] +`; + +exports[`三维空间直线和圆相交测试 3`] = ` +Array [ + Vector3 { + "x": 9.796270630192112, + "y": -13.16305455920182, + "z": 4.841809080303142, + }, + Vector3 { + "x": 9.796270630192113, + "y": -6.270573611488619, + "z": 4.841809080303142, + }, +] +`; + +exports[`三维空间直线和圆相交测试 4`] = ` +Array [ + Vector3 { + "x": 12.384261138056765, + "y": -13.16305455920182, + "z": 6.346016491847222, + }, + Vector3 { + "x": 12.384261138056765, + "y": -6.27057361148862, + "z": 6.346016491847221, + }, +] +`; + exports[`三维空间直线相交测试 1`] = ` Vector3 { "x": 5, @@ -17,3 +139,31 @@ Vector3 { "z": 5, } `; + +exports[`直线和圆相切 1`] = ` +Array [ + Vector3 { + "x": 34450.21257120082, + "y": 3606.7814824644443, + "z": 0, + }, +] +`; + +exports[`相交测试 1`] = ` +Vector3 { + "x": 0.5, + "y": 0, + "z": 0, +} +`; + +exports[`相交测试 2`] = `undefined`; + +exports[`相交测试 3`] = ` +Vector3 { + "x": 0.5, + "y": 5, + "z": 0, +} +`; diff --git a/src/Add-on/Trim.ts b/src/Add-on/Trim.ts index 13b221ac0..107f97b15 100644 --- a/src/Add-on/Trim.ts +++ b/src/Add-on/Trim.ts @@ -8,8 +8,9 @@ import { Curve } from '../DatabaseServices/Curve'; import { Line } from '../DatabaseServices/Line'; import { Polyline } from '../DatabaseServices/Polyline'; import { Command } from '../Editor/CommandMachine'; -import { PromptStatus } from '../Editor/PromptResult'; -import { SelectBox } from '../Editor/SelectBox'; +import { Jig } from '../Editor/Jig'; +import { PromptSsgetResult, PromptStatus } from '../Editor/PromptResult'; +import { SelectBox, SelectType } from '../Editor/SelectBox'; import { IntersectOption } from '../GraphicsSystem/IntersectWith'; export class Command_Trim implements Command @@ -27,53 +28,96 @@ export class Command_Trim implements Command //剪刀对象 let kniefCus = knifeSsRes.SelectSet.SelectEntityList as Curve[]; - kniefCus.forEach(c => c.UpdateJigMaterial()); - while (true) { + // kniefCus.forEach(c => c.UpdateJigMaterial(6)); + let lastCurves: Curve[] = []; + //选择裁剪的对象. let trSsRes = await app.m_Editor.GetSelection({ Msg: "请选择被切割对象:", Once: true, - Filter: { filterTypes: [Curve] }, + Filter: { + filterTypes: [Curve], + }, + SelectType: SelectType.C, Callback: (res) => { - console.log(res); + Jig.End(); + for (let c of lastCurves) + c.RestoreJigMaterial(); + + lastCurves = res.SelectSet.SelectEntityList as Curve[]; + let cuMap = this.JigTrim(res, kniefCus); + + for (let [c, cus] of cuMap) + { + c.UpdateJigMaterial(); + for (let c of cus) + Jig.Draw(c); + } + app.m_Editor.UpdateScreen(); } }); + + for (let c of lastCurves) + c.RestoreJigMaterial(); + // for (let c of kniefCus) + // c.RestoreJigMaterial(); + if (trSsRes.Status === PromptStatus.Cancel || trSsRes.Status === PromptStatus.None) break; if (!trSsRes.SelectSet) continue; - for (let s of trSsRes.SelectSet.SelectSetList) + let newCus = this.JigTrim(trSsRes, kniefCus, false); + for (let [c, cus] of newCus) { - for (let obj of s.m_SelectList) + c.Erase(); + let len = kniefCus.length; + arrayRemove(kniefCus, c); + if (kniefCus.length !== len) + kniefCus.push(...cus); + for (let c of cus) + app.m_Database.ModelSpace.Append(c); + } + + app.m_Editor.UpdateScreen(); + } + + // kniefCus.forEach(c => c.RestoreJigMaterial()); + } + + private JigTrim(trSsRes: PromptSsgetResult, kniefCus: Curve[], isJig = true) + { + + let resCus: Map = new Map(); + for (let s of trSsRes.SelectSet.SelectSetList) + { + for (let obj of s.m_SelectList) + { + let cu = obj.userData as Curve; + if (s instanceof SelectBox) { - let cu = obj.userData as Curve; - if (s instanceof SelectBox) - { - let isKniefSelect = kniefCus.indexOf(cu) > -1;//被切割者自身也是刀. - let isPolyline = cu instanceof Polyline; //被切割者是多段线 - if (!cu || (isKniefSelect && !isPolyline)) //如果对象被第一轮选中,那么不切割它 - continue; - - let newCus: Curve[] = []; - if (cu instanceof Polyline) - newCus = this.TrimPolyline(cu, kniefCus, s); - else if (cu instanceof Circle || cu instanceof Arc || cu instanceof Line) - newCus = this.TrimCurve(cu, kniefCus, s); - - newCus.forEach(c => { app.m_Database.ModelSpace.Append(c) }); - } - cu.Erase(); - arrayRemove(kniefCus, cu); + let isKniefSelect = kniefCus.indexOf(cu) > -1;//被切割者自身也是刀. + let isPolyline = cu instanceof Polyline; //被切割者是多段线 + if (!cu || (isKniefSelect && !isPolyline)) //如果对象被第一轮选中,那么不切割它 + continue; + + let newCus: Curve[] = []; + if (cu instanceof Polyline && (kniefCus.includes(cu) || kniefCus.length === 0)) + newCus = this.TrimPolyline(cu, kniefCus, s); + else if (cu instanceof Circle || cu instanceof Arc || cu instanceof Line || cu instanceof Polyline) + newCus = this.TrimCurve(cu, kniefCus, s); + + resCus.set(cu, newCus); } } } - kniefCus.forEach(c => c.RestoreJigMaterial()); + return resCus; } + //得到曲线和刀曲线的切割点表 private GetIntersetPoints(kniefCus: Curve[], cu: Curve, thisCurve = cu) { @@ -94,7 +138,7 @@ export class Command_Trim implements Command * @param selBox * @param [isSelect] 是否已经被选中 */ - TrimCurve(curve: Line | Circle | Arc, kniefCus: Curve[], selBox: SelectBox, thisCurve: Curve = curve, insSelfPts: Vector3[] = []): Curve[] + TrimCurve(curve: Line | Circle | Arc | Polyline, kniefCus: Curve[], selBox: SelectBox, thisCurve: Curve = curve, insSelfPts: Vector3[] = []): Curve[] { //求交 let intPts = this.GetIntersetPoints(kniefCus, curve, thisCurve); diff --git a/src/Common/InputState.ts b/src/Common/InputState.ts index 84205bf11..8bfdac800 100644 --- a/src/Common/InputState.ts +++ b/src/Common/InputState.ts @@ -1,6 +1,7 @@ import { Vector3 } from 'three'; import { PromptEntityResult, PromptSsgetResult } from '../Editor/PromptResult'; import { Filter } from '../Editor/SelectFilter'; +import { SelectType } from '../Editor/SelectBox'; /** * 控制器的状态,按位表示. @@ -74,5 +75,6 @@ export interface GetSelectionPrompt extends GetAnyPrompt Once?: boolean;//只选一次 UseSelect?: boolean;//使用当前已经选中的实体. Filter?: Filter; + SelectType?: SelectType; Callback?: (res: PromptSsgetResult) => void; } diff --git a/src/DatabaseServices/Curve.ts b/src/DatabaseServices/Curve.ts index 2f982b97c..7e835257b 100644 --- a/src/DatabaseServices/Curve.ts +++ b/src/DatabaseServices/Curve.ts @@ -164,12 +164,12 @@ export abstract class Curve extends Entity m.material = ColorMaterial.GetLineMaterial(this.m_Color); } - UpdateJigMaterial() + UpdateJigMaterial(color = 8) { for (let [type, en] of this.m_DrawEntity) { let l = en as Line; - l.material = ColorMaterial.GetLineMaterial(8); + l.material = ColorMaterial.GetLineMaterial(color); } } } diff --git a/src/DatabaseServices/Entity.ts b/src/DatabaseServices/Entity.ts index 557729217..c50579455 100644 --- a/src/DatabaseServices/Entity.ts +++ b/src/DatabaseServices/Entity.ts @@ -210,7 +210,7 @@ export class Entity extends CADObject * * @memberof Entity */ - UpdateJigMaterial() + UpdateJigMaterial(color = 8) { } RestoreJigMaterial() diff --git a/src/Editor/GetSelectionServices.ts b/src/Editor/GetSelectionServices.ts index 1d9874a1a..01ef59a05 100644 --- a/src/Editor/GetSelectionServices.ts +++ b/src/Editor/GetSelectionServices.ts @@ -8,6 +8,7 @@ import { PromptSsgetResult, PromptStatus } from './PromptResult'; import { SelectPick } from './SelectPick'; import { Filter } from './SelectFilter'; import { SelectSet } from './SelectSet'; +import { SelectType } from './SelectBox'; /** * 提供选择状态的服务. ed.Ssget @@ -38,6 +39,9 @@ export class SsgetServiecs set.Filter(prompt.Filter); selectCtrl.UpdateView(); } + if (prompt.SelectType) + selectCtrl.SelectType = prompt.SelectType; + //如果使用当前选择,并且已经存在选择对象,那么直接返回. if (prompt.UseSelect && set.SelectEntityList.length > 0) { @@ -55,10 +59,11 @@ export class SsgetServiecs Filter: prompt.Filter, Callback: (res) => { - if (res.Entity && prompt.Callback) + if (prompt.Callback) { - let ssEnt = new SelectPick(this.m_Editor.m_App.m_Viewer, res.Point); - ssEnt.m_SelectList.push(res.Entity.Draw(RenderType.Wireframe)); + let ssEnt = new SelectPick(this.m_Editor.m_App.m_Viewer, this.m_Editor.m_MouseCtrl.m_CurMousePointVCS); + if (res.Entity) + ssEnt.m_SelectList.push(res.Entity.Draw(RenderType.Wireframe)); let set = new SelectSet(); set.AddSelect(ssEnt); prompt.Callback({ Status: PromptStatus.OK, SelectSet: set }); @@ -166,6 +171,7 @@ export class SsgetServiecs this.promisResolve(res); this.m_Editor.m_SelectCtrl.Cancel(); this.m_Editor.m_SelectCtrl.m_Filter = undefined; + this.m_Editor.m_SelectCtrl.SelectType = SelectType.None; } private m_AwaitRemoveCalls: Function[] = []; diff --git a/src/Editor/PromptResult.ts b/src/Editor/PromptResult.ts index 478ce93b0..b188809de 100644 --- a/src/Editor/PromptResult.ts +++ b/src/Editor/PromptResult.ts @@ -1,10 +1,8 @@ import * as THREE from 'three'; import { Vector3 } from 'three'; - import { Entity } from '../DatabaseServices/Entity'; import { SelectSet } from './SelectSet'; - export enum PromptStatus { None = 0, @@ -83,4 +81,3 @@ export class PromptSsgetResult extends PromptResult { SelectSet?: SelectSet; } - diff --git a/src/Editor/SelectControls.ts b/src/Editor/SelectControls.ts index 9547ffe6a..24645d13a 100644 --- a/src/Editor/SelectControls.ts +++ b/src/Editor/SelectControls.ts @@ -30,6 +30,7 @@ export class SelectControls implements EditorService private m_Viewer: Viewer; private m_SelectSet: SelectSet = new SelectSet(); m_Filter: Filter; + private m_SelectType: SelectType = SelectType.None; constructor(view: Viewer, ed: Editor) { @@ -42,6 +43,11 @@ export class SelectControls implements EditorService { return this.m_SelectSet; } + set SelectType(type: SelectType) + { + this.m_SelectType = type; + this.m_SelectCss.selectType = type; + } RegisterEvent() { let ed = this.m_Editor; @@ -145,7 +151,10 @@ export class SelectControls implements EditorService SelectByCss() { let selectBox = new SelectBox(this.m_Viewer, this.m_SelectCss.start, this.m_SelectCss.end); - selectBox.m_SelectType = this.m_SelectCss.end.x > this.m_SelectCss.start.x ? SelectType.W : SelectType.C; + if (this.m_SelectType !== SelectType.None) + selectBox.m_SelectType = this.m_SelectType; + else + selectBox.m_SelectType = this.m_SelectCss.end.x > this.m_SelectCss.start.x ? SelectType.W : SelectType.C; selectBox.Select(undefined, this.m_Filter); return selectBox; } diff --git a/src/UI/JsPlugin/SelectMarquee.ts b/src/UI/JsPlugin/SelectMarquee.ts index b7746dc89..d11631fea 100644 --- a/src/UI/JsPlugin/SelectMarquee.ts +++ b/src/UI/JsPlugin/SelectMarquee.ts @@ -1,5 +1,6 @@ import * as THREE from 'three'; import { Viewer } from '../../GraphicsSystem/Viewer'; +import { SelectType } from '../../Editor/SelectBox'; //矩形选框 export class SelectMarquee @@ -13,8 +14,9 @@ export class SelectMarquee dom: HTMLElement; width: number; height: number; + viewer: Viewer; + selectType: SelectType = SelectType.None; - viewer: Viewer constructor(view: Viewer) { this.viewer = view; @@ -55,7 +57,16 @@ export class SelectMarquee this.dom.style.width = this.width + "px" this.dom.style.height = this.height + "px" - if (this.start.x > this.end.x) + let type = this.selectType; + if (this.selectType === SelectType.None) + { + if (this.start.x > this.end.x) + type = SelectType.C; + else + type = SelectType.W; + } + + if (type === SelectType.C) { this.dom.style.background = this.leftColor; this.dom.style.border = this.leftBorder; @@ -76,4 +87,4 @@ export class SelectMarquee this.end.set(x, y) this.Update() } -} \ No newline at end of file +}