From 674b009f9e40697d2cbdce47eed583fbe9159fbc Mon Sep 17 00:00:00 2001 From: Zoe Date: Thu, 23 Aug 2018 09:44:16 +0800 Subject: [PATCH 1/8] =?UTF-8?q?fix=20#ILS5N=20=E6=9D=BF=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E9=83=BD=E4=B8=8D=E6=88=90=E5=AF=B9=E6=97=B6=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E5=BE=97=E7=A9=BA=E9=97=B4=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Add-on/DrawBoard/DrawClosingStrip.ts | 3 +-- src/Geometry/SpaceParse/GeneralSpaceParse.ts | 15 +++++++++++++-- src/Geometry/SpaceParse/SpaceParse.ts | 7 +------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Add-on/DrawBoard/DrawClosingStrip.ts b/src/Add-on/DrawBoard/DrawClosingStrip.ts index 6f9f4f1bb..f38dc9eaf 100644 --- a/src/Add-on/DrawBoard/DrawClosingStrip.ts +++ b/src/Add-on/DrawBoard/DrawClosingStrip.ts @@ -36,11 +36,10 @@ export class DrawClosingStrip implements Command let spaceParse = new SpaceParse(boardCus); spaceParse.ParseTotalSpace(); - let rot = new Matrix4().extractRotation(spaceParse.SpaceOCS); let totalSpace = spaceParse.TotalSpace; while (true) { - this.buildClosingStrip(totalSpace, rot); + this.buildClosingStrip(totalSpace, spaceParse.SpaceOCS); state = await app.m_Editor.m_ModalManage.Wait(); if (state !== ModalState.Ok) { diff --git a/src/Geometry/SpaceParse/GeneralSpaceParse.ts b/src/Geometry/SpaceParse/GeneralSpaceParse.ts index 64f272a73..f6a7b3479 100644 --- a/src/Geometry/SpaceParse/GeneralSpaceParse.ts +++ b/src/Geometry/SpaceParse/GeneralSpaceParse.ts @@ -40,9 +40,20 @@ export class GeneralSpaceParse extends SpaceParse spliteBoxes.push(box); } } - let spaces = this.MergeSpaces(unionBoxes) as Box3Ext; - spaces && this.SpliteBoxs(spaces, spliteBoxes); + if (unionBoxes.length > 0) + { + let spaces = this.MergeSpaces(unionBoxes) as Box3Ext; + + spaces && this.SpliteBoxs(spaces, spliteBoxes); + } + else if (spliteBoxes.length > 0) + { + //获得总空间后用除第一个空间以外得空间进行切割 + let box = new Box3Ext() + spliteBoxes.reduce((b1, b2) => b1.union(b2), box); + this.SpliteBoxs(box, spliteBoxes.slice(1)); + } } /** diff --git a/src/Geometry/SpaceParse/SpaceParse.ts b/src/Geometry/SpaceParse/SpaceParse.ts index a92639a3c..14ff1647c 100644 --- a/src/Geometry/SpaceParse/SpaceParse.ts +++ b/src/Geometry/SpaceParse/SpaceParse.ts @@ -6,9 +6,6 @@ import { Box3Ext } from "../Box"; /** * 空间分析类 - * 层板 可以只有一块板 - * 其他板必须大于1块板 - * 顶底板,背板必须要有2块左右侧板,可以选择多块板 * //TODO:暂不考虑名称,排钻,封边..... * @export * @class SpaceParse @@ -78,9 +75,7 @@ export class SpaceParse { this.m_Boards.forEach(br => { - let b = br.Clone() as Board; - b.ApplyMatrix(new Matrix4().extractRotation(b.BoardOCSInv)) - let box = b.BoundingBox; + let box = br.GetBoardBoxInMat(this.SpaceOCSInv); this.m_TotalSpace.union(box); }) } From c684a66ca835d72c317cf2c3d2f2002c53e79035 Mon Sep 17 00:00:00 2001 From: ChenX Date: Thu, 23 Aug 2018 10:44:56 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Add-on/DrawBoard/DrawClosingStrip.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Add-on/DrawBoard/DrawClosingStrip.ts b/src/Add-on/DrawBoard/DrawClosingStrip.ts index f38dc9eaf..70b002240 100644 --- a/src/Add-on/DrawBoard/DrawClosingStrip.ts +++ b/src/Add-on/DrawBoard/DrawClosingStrip.ts @@ -18,12 +18,11 @@ export class DrawClosingStrip implements Command private store: ClosingStripStore; async exec() { - let exSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true }); + let exSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true, Filter: { filterTypes: [Board] } }); if (exSsRes.Status === PromptStatus.Cancel) return; - let boardCus = exSsRes.SelectSet.SelectEntityList.filter(en => - en instanceof Board) as Board[]; + let boardCus = exSsRes.SelectSet.SelectEntityList as Board[]; if (boardCus.length > 0) { From c3784044812577b63bc3b1b39d16886eb7ea12fa Mon Sep 17 00:00:00 2001 From: Zoe Date: Thu, 23 Aug 2018 14:21:22 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=95=E5=9D=97?= =?UTF-8?q?=E6=9D=BF=E5=88=86=E6=9E=90=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Geometry/SpaceParse/GeneralSpaceParse.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Geometry/SpaceParse/GeneralSpaceParse.ts b/src/Geometry/SpaceParse/GeneralSpaceParse.ts index f6a7b3479..24883b42c 100644 --- a/src/Geometry/SpaceParse/GeneralSpaceParse.ts +++ b/src/Geometry/SpaceParse/GeneralSpaceParse.ts @@ -49,10 +49,9 @@ export class GeneralSpaceParse extends SpaceParse } else if (spliteBoxes.length > 0) { - //获得总空间后用除第一个空间以外得空间进行切割 let box = new Box3Ext() spliteBoxes.reduce((b1, b2) => b1.union(b2), box); - this.SpliteBoxs(box, spliteBoxes.slice(1)); + this.SpliteBoxs(box, spliteBoxes); } } From cae8e31bcbe9873ad3a419c79f2f1e109137a881 Mon Sep 17 00:00:00 2001 From: Zoe <33168975+ZoeLeee@users.noreply.github.com> Date: Thu, 23 Aug 2018 22:47:39 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A9=BA=E9=97=B4?= =?UTF-8?q?=E5=88=86=E6=9E=90=E5=88=87=E5=89=B2=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Geometry/SpaceParse/GeneralSpaceParse.ts | 9 +++------ src/UI/Components/SourceManage/FilePanel.tsx | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Geometry/SpaceParse/GeneralSpaceParse.ts b/src/Geometry/SpaceParse/GeneralSpaceParse.ts index 24883b42c..c43a9b07d 100644 --- a/src/Geometry/SpaceParse/GeneralSpaceParse.ts +++ b/src/Geometry/SpaceParse/GeneralSpaceParse.ts @@ -105,15 +105,12 @@ export class GeneralSpaceParse extends SpaceParse for (let j = 0; j < spliteBoxes.length; j++) { let bs = box.substract(spliteBoxes[j]); - if (bs.some(b => b === undefined)) - { - debugger; - } + if (bs.length > 0) { boxes.splice(i, 1, ...bs); - i -= (bs.length - 1); - if (i === boxes.length - 1) + i--; + if (i === boxes.length - 1 && j === spliteBoxes.length - 1) { this.m_Spaces.push(...bs); } diff --git a/src/UI/Components/SourceManage/FilePanel.tsx b/src/UI/Components/SourceManage/FilePanel.tsx index 5c965d671..ae7591588 100644 --- a/src/UI/Components/SourceManage/FilePanel.tsx +++ b/src/UI/Components/SourceManage/FilePanel.tsx @@ -171,7 +171,6 @@ export class FilePanel extends React.Component<{ store?: TopPanelStore }, {}> height: 580, border: "1px solid #0e2535", borderRadius: "3px", - flexBasis: 0, flexGrow: 1 } } From fd6b13dec7f24240544a854a8979353753110cd6 Mon Sep 17 00:00:00 2001 From: ChenX Date: Fri, 24 Aug 2018 14:46:42 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=B8=85=E7=90=86?= =?UTF-8?q?=E6=9D=BF=E4=BB=B6=E7=A9=BA=E9=97=B4=E5=88=86=E6=9E=90=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Geometry/boxExt.test.ts | 14 + src/Add-on/DrawBoard/DrawBoardTool.ts | 50 +- src/Common/ArrayExt.ts | 30 +- src/DatabaseServices/Board.ts | 14 + src/Geometry/Box.ts | 73 +- src/Geometry/SpaceParse/GeneralSpaceParse.ts | 670 +++++++----------- .../SpaceParse/PointPickSpaceParse.ts | 13 +- src/Geometry/SpaceParse/SpaceParse.ts | 4 - 8 files changed, 393 insertions(+), 475 deletions(-) create mode 100644 __test__/Geometry/boxExt.test.ts diff --git a/__test__/Geometry/boxExt.test.ts b/__test__/Geometry/boxExt.test.ts new file mode 100644 index 000000000..84ae4bab5 --- /dev/null +++ b/__test__/Geometry/boxExt.test.ts @@ -0,0 +1,14 @@ + +import { Box3Ext } from "../../src/Geometry/Box" +import { Vector3 } from "three"; + +test('盒子相减', () => +{ + let b = new Box3Ext(new Vector3(), new Vector3(100, 100, 100)); + + let b2 = new Box3Ext(new Vector3(200, 0, 0), new Vector3(205, 10, 300)); + + let bs = b.substract(b2, 0); + + expect(bs.length).toBe(0); +}); diff --git a/src/Add-on/DrawBoard/DrawBoardTool.ts b/src/Add-on/DrawBoard/DrawBoardTool.ts index 5c0b604b5..3d9d9ec6e 100644 --- a/src/Add-on/DrawBoard/DrawBoardTool.ts +++ b/src/Add-on/DrawBoard/DrawBoardTool.ts @@ -8,7 +8,7 @@ import { GenerateRaycaster } from '../../Editor/PointPick'; import { PromptStatus } from '../../Editor/PromptResult'; import { Box3Ext } from '../../Geometry/Box'; import { equaln } from '../../Geometry/GeUtils'; -import { GeneralSpaceParse, GeneralSpaceParse2 } from '../../Geometry/SpaceParse/GeneralSpaceParse'; +import { GeneralSpaceParse } from '../../Geometry/SpaceParse/GeneralSpaceParse'; import { PointPickSpaceParse } from '../../Geometry/SpaceParse/PointPickSpaceParse'; import { BoardModal, BoardModalType } from '../../UI/Components/Board/BoardModal'; import { ModalPosition } from '../../UI/Components/Modal/ModalsManage'; @@ -192,32 +192,32 @@ export abstract class DrawBoardTool implements Command let boardCus = exSsRes.SelectSet.SelectEntityList.filter(en => en instanceof Board) as Board[]; - if (boardCus.length > 0) - { - let spaceParse = new GeneralSpaceParse2(boardCus); - spaceParse.SpaceParse(); + // if (boardCus.length > 0) + // { + // let spaceParse = new GeneralSpaceParse2(boardCus); + // spaceParse.SpaceParse(); - if (spaceParse.Spaces.length === 0) - { - app.m_Editor.Prompt("生成板件失败"); - return; - } - let ro = new Matrix4().extractRotation(spaceParse.SpaceOCS); + // if (spaceParse.Spaces.length === 0) + // { + // app.m_Editor.Prompt("生成板件失败"); + // return; + // } + // let ro = new Matrix4().extractRotation(spaceParse.SpaceOCS); - let spaces = spaceParse.Spaces; - for (let box of spaces) - { - this.buildBoard(box, ro, - { - boardConfig: this.store.m_BoardOption, - boardProcess: this.store.m_BoardProcessOption - }); - } - } - else - { - app.m_Editor.Prompt("请选择板件") - } + // let spaces = spaceParse.Spaces; + // for (let box of spaces) + // { + // this.buildBoard(box, ro, + // { + // boardConfig: this.store.m_BoardOption, + // boardProcess: this.store.m_BoardProcessOption + // }); + // } + // } + // else + // { + // app.m_Editor.Prompt("请选择板件") + // } } async selectBox(spaces: Box3Ext[]) diff --git a/src/Common/ArrayExt.ts b/src/Common/ArrayExt.ts index edc2ad0a2..a11aec15f 100644 --- a/src/Common/ArrayExt.ts +++ b/src/Common/ArrayExt.ts @@ -81,7 +81,7 @@ export function arraySortByNumber(arr: Array): Array * @param {(e1, e2) => boolean} [checkFuction] 校验对象相等函数 * @returns {Array} 返回自身 */ -export function arrayRemoveDuplicateBySort(arr: Array, checkFuction: (e1, e2) => boolean = checkEqual): Array +export function arrayRemoveDuplicateBySort(arr: Array, checkFuction: (e1: T, e2: T) => boolean = checkEqual): Array { if (arr.length < 2) return arr; let j = 1; @@ -92,6 +92,34 @@ export function arrayRemoveDuplicateBySort(arr: Array, checkFuction: (e1, return arr; } +/** + * 对排序好的数组进行去重操作 + * @param {(e1, e2) => boolean} [checkFuction] 校验对象相等函数 + * @returns {Array} 返回新数组 + */ +export function arrayRemoveDuplicateBySort2(arr: Array, checkFuction: (e1: T, e2: T) => boolean = checkEqual): Array +{ + if (arr.length < 2) return arr; + + let pre = arr[0], + newArr = [pre], + now: T; + + for (let i = 1, len = arr.length; i < len; i++) + { + now = arr[i]; + if (!checkEqual(now, pre)) + { + newArr.push(now); + pre = now; + } + } + + if (pre !== now) newArr.push(now); + + return newArr; +} + //原地更新数组,注意这个函数并不会比map快. export function arrayMap(arr: Array, mapFunc: (v: T) => T): Array { diff --git a/src/DatabaseServices/Board.ts b/src/DatabaseServices/Board.ts index 04b4cb5de..5ec75369a 100644 --- a/src/DatabaseServices/Board.ts +++ b/src/DatabaseServices/Board.ts @@ -20,6 +20,20 @@ export enum BoardType Behind = 2 //背板 } +//转换板件类型成为空间类型. 0x 1y 2z +export function ConverBoardTypeToSpaceType(type: BoardType): number +{ + switch (type) + { + case BoardType.Layer: + return 2; + case BoardType.Vertical: + return 0; + case BoardType.Behind: + return 1; + } +} + /** * 板件实体 * diff --git a/src/Geometry/Box.ts b/src/Geometry/Box.ts index 47b8a8ac4..0ad9257e3 100644 --- a/src/Geometry/Box.ts +++ b/src/Geometry/Box.ts @@ -1,6 +1,14 @@ import { Vector3, Box3 } from 'three'; -import { BoardType } from '../DatabaseServices/Board'; -import { equaln } from './GeUtils'; + +/** + * 盒子的切割类型 + */ +export enum SplitType +{ + X = 0, + Y = 1, + Z = 2, +} /** * 扩展Box3,添加切割方法,体积等 @@ -11,47 +19,40 @@ import { equaln } from './GeUtils'; */ export class Box3Ext extends Box3 { - //FIXME: 这个类型不应该出现在这里,非必要属性 - //切割类型 - spliteType: BoardType; get Volume() { let size = this.getSize(new Vector3()); return size.x * size.y * size.z; } - substract(b: Box3Ext) + + //每个轴的大小必须大于最小的size + isSolid(minSize = 1) + { + return this.getSize(new Vector3()).toArray().every(x => x > minSize); + } + + substract(b: Box3Ext, spaceType: SplitType) { - let boxes: Box3Ext[] = []; - if (this.intersectsBox(b)) - { - let box1 = this.clone(); - box1.intersect(b); - let max = box1.max; - let min = box1.min; + let interBox = this.clone().intersect(b) as this; + if (interBox.isEmpty() || !interBox.isSolid()) + return [this]; - switch (b.spliteType) - { - case BoardType.Vertical: - boxes = [ - new Box3Ext(min.clone().setX(this.min.x), max.clone().setX(min.x)), - new Box3Ext(min.clone().setX(max.x), max.clone().setX(this.max.x)) - ]; - break; - case BoardType.Behind: - boxes = [ - new Box3Ext(min.clone().setY(this.min.y), max.clone().setY(min.y)), - new Box3Ext(min.clone().setY(max.y), max.clone().setY(this.max.y)) - ]; - break; - case BoardType.Layer: - boxes = [ - new Box3Ext(min.clone().setZ(max.z), max.clone().setZ(this.max.z)), - new Box3Ext(min.clone().setZ(this.min.z), max.clone().setZ(min.z)) - ]; - break; - } - } - return boxes.filter(b => !b.isEmpty() && !equaln(b.Volume, 0, 1e-6)) + let b1Max = this.max.clone().setComponent(spaceType, interBox.min.getComponent(spaceType)); + let b2Min = this.min.clone().setComponent(spaceType, interBox.max.getComponent(spaceType)); + + return [ + new Box3Ext(this.min, b1Max), + new Box3Ext(b2Min, this.max) + ].filter(b => b.isSolid()); + } + clampSpace(b2: Box3Ext, splitType: SplitType) + { + let interBox = this.clone(); + interBox.min.max(b2.min); + interBox.max.min(b2.max); + interBox.min.setComponent(splitType, Math.min(this.max.getComponent(splitType), b2.max.getComponent(splitType))); + interBox.max.setComponent(splitType, Math.max(this.min.getComponent(splitType), b2.min.getComponent(splitType))); + return interBox; } intersectsBox(b: Box3) { diff --git a/src/Geometry/SpaceParse/GeneralSpaceParse.ts b/src/Geometry/SpaceParse/GeneralSpaceParse.ts index c43a9b07d..f32849c8a 100644 --- a/src/Geometry/SpaceParse/GeneralSpaceParse.ts +++ b/src/Geometry/SpaceParse/GeneralSpaceParse.ts @@ -1,8 +1,8 @@ -import { Matrix4, Vector3 } from "three"; -import { arrayLast } from "../../Common/ArrayExt"; -import { Board, BoardType } from "../../DatabaseServices/Board"; -import { Box3Ext } from "../Box"; -import { equaln, MoveMatrix } from "../GeUtils"; +import { Vector3 } from "three"; +import { arrayLast, arrayRemoveDuplicateBySort2 } from "../../Common/ArrayExt"; +import { Board, ConverBoardTypeToSpaceType } from "../../DatabaseServices/Board"; +import { Box3Ext, SplitType } from "../Box"; +import { equaln } from "../GeUtils"; import { SpaceParse } from "./SpaceParse"; /** @@ -24,436 +24,304 @@ export class GeneralSpaceParse extends SpaceParse async SpaceParse() { await super.SpaceParse(); - let unionBoxes: Box3Ext[] = []; - let spliteBoxes: Box3Ext[] = []; - for (let key of this.boardMap.keys()) + let unionBoxCol: Box3Ext[] = []; + let spliteBoxs = new Map(); + for (let [boardType, boards] of this.boardMap) { - let boards = this.boardMap.get(key); - if (boards.length > 1) - { - this.parseBoards(boards, unionBoxes); - } - else if (boards.length === 1) - { - let box = boards[0].GetBoardBoxInMat(this.SpaceOCSInv); - box.spliteType = boards[0].BoardType; - spliteBoxes.push(box); - } - } + let splitType: SplitType = ConverBoardTypeToSpaceType(boardType); + let boardBoxCol = this.ParseBoardBoxOfSortAndCombin(boards, splitType); - if (unionBoxes.length > 0) - { - let spaces = this.MergeSpaces(unionBoxes) as Box3Ext; - - spaces && this.SpliteBoxs(spaces, spliteBoxes); - } - else if (spliteBoxes.length > 0) - { - let box = new Box3Ext() - spliteBoxes.reduce((b1, b2) => b1.union(b2), box); - this.SpliteBoxs(box, spliteBoxes); - } - } - - /** - * 合并空间 - * 最多只会有3个空间 - * @param spaces - * @returns - */ - private MergeSpaces(spaces: Box3Ext[]) - { - if (spaces.length === 0) return undefined; - - let b1 = spaces.shift(); - let isInt = false; - for (let box of spaces) - { - if (b1.intersectsBox(box)) + if (boardBoxCol.length > 1) { - isInt = true; - b1.intersect(box); + let clampBox = boardBoxCol[0].clampSpace(arrayLast(boardBoxCol), splitType); + if (clampBox.isSolid()) + unionBoxCol.push(clampBox); } - } - if (!isInt && spaces.length === 2) - { - b1 = spaces[0]; - let b2 = spaces[1]; - if (b1.intersectsBox(b2)) + else if (boardBoxCol.length === 1) { - return b1.intersect(b2); + spliteBoxs.set(splitType, boardBoxCol[0]); } - return undefined; } - return b1; - } - - /** - *用单块板包围盒切割空间 - */ - private SpliteBoxs(box: Box3Ext, spliteBoxes: Box3Ext[]) - { - if (spliteBoxes.length === 0) - this.m_Spaces = [box]; - else + let allSpaceBox: Box3Ext; + if (unionBoxCol.length === 0) { - let boxes = [box]; - for (let i = 0; i < boxes.length; i++) - { - let box = boxes[i]; - for (let j = 0; j < spliteBoxes.length; j++) - { - let bs = box.substract(spliteBoxes[j]); - - if (bs.length > 0) - { - boxes.splice(i, 1, ...bs); - i--; - if (i === boxes.length - 1 && j === spliteBoxes.length - 1) - { - this.m_Spaces.push(...bs); - } - break; - } - else if (j === spliteBoxes.length - 1) - { - this.m_Spaces.push(box); - } - } - } - } - } - - /** - *分析2个包围盒之间组成的空间包围盒 - * @param {Box3Ext} b1 - * @param {Box3Ext} b2 - * @param {BoardType} boardType - * @returns - */ - private parseBox3(b1: Box3Ext, b2: Box3Ext, boardType: BoardType) - { - switch (boardType) - { - case BoardType.Layer: - return this.getSpace(b1, b2, "z"); - case BoardType.Vertical: - return this.getSpace(b1, b2, "x"); - case BoardType.Behind: - return this.getSpace(b1, b2, "y"); - } - } - - //获取2个盒子之间的空间 - getSpace(b1: Box3Ext, b2: Box3Ext, axis: string) - { - [b1, b2] = b1.min[axis] < b2.min[axis] ? [b1, b2] : [b2, b1]; - let dist = b2.min[axis] - b1.min[axis]; - if (dist <= b1.getSize(new Vector3())[axis]) - { - return new Box3Ext(); - } - let vec = new Vector3(); - vec[axis] = -dist; - b2.applyMatrix4(MoveMatrix(vec)); - if (b1.intersectsBox(b2)) - { - b1.intersect(b2); + allSpaceBox = new Box3Ext(); + spliteBoxs.forEach((box) => { allSpaceBox.union(box) }); } else { - b1.union(b2); + allSpaceBox = unionBoxCol[0]; + for (let i = 1, len = unionBoxCol.length; i < len; i++) + allSpaceBox.intersect(unionBoxCol[i]); } - let vec1 = new Vector3(); - vec1[axis] = b1.getSize(new Vector3())[axis]; - - let vec2 = new Vector3(); - vec2[axis] = dist - b2.getSize(new Vector3())[axis]; - - return new Box3Ext(b1.min.add(vec1), b1.max.add(vec2)); + this.SpliteBoxs(allSpaceBox, spliteBoxs); } - /** - *分析多块板,先合并在排序 - *合并完板多于2块,取最2边的2块板 - * @private - * @param {Board[]} boards - * @param {Box3Ext[]} uniSpaces - * @memberof GeneralSpaceParse - */ - private parseBoards(boards: Board[], uniSpaces: Box3Ext[]) - { - let boxMap: Map = new Map(); - - for (let br of boards) - { - let box = br.GetBoardBoxInMat(this.SpaceOCSInv); - boxMap.set(br, box); - } - - switch (boards[0].BoardType) - { - case BoardType.Layer: - this.sortAndMerge(boards, boxMap, "z"); - break; - case BoardType.Vertical: - this.sortAndMerge(boards, boxMap, "x"); - break; - case BoardType.Behind: - this.sortAndMerge(boards, boxMap, "y"); - } - if (boards.length >= 2) - { - let b1 = boards[0]; - let box1 = boxMap.get(b1).clone(); - let b2 = arrayLast(boards); - let box2 = boxMap.get(b2).clone(); - - let box = this.parseBox3(box1, box2, b1.BoardType); - if (!box.isEmpty()) - { - uniSpaces.push(box); - } - } - } - //排序归并板件 - private sortAndMerge(boards: Board[], boxMap: Map, type: string) + //解析板件的盒子,已经排序并且归并. + private ParseBoardBoxOfSortAndCombin(boardCol: Board[], splitType: SplitType) { - boards.sort((a, b) => boxMap.get(a).min[type] - boxMap.get(b).min[type]); + let boxCol = boardCol.map(b => { return b.GetBoardBoxInMat(this.SpaceOCSInv) }); - for (let i = 0; i < boards.length; i++) + //根据分割类型排序 + boxCol.sort((b1, b2) => { - let b1 = boards[i]; - let box1 = boxMap.get(b1); - for (let j = i + 1; j < boards.length; j++) - { - let b2 = boards[j]; - let box2 = boxMap.get(b2); - if (equaln(box1.min[type], box2.min[type])) - { - let b = box1.clone(); - box1.union(box2) - boards.splice(j, 1); - j--; - } - else - { - i = j - 1; - break; - } - } - } - } - -} + return b1.min.getComponent(splitType) - b2.min.getComponent(splitType); + }); - -/** - *用于分析出全部空间 - * 待完善优化,暂留 - * @export - * @class GeneralSpaceParse2 - * @extends {SpaceParse} - */ -export class GeneralSpaceParse2 extends SpaceParse -{ - get Spaces() - { - return this.m_Spaces; - } - async SpaceParse() - { - super.SpaceParse(); - let unionBoxes: Box3Ext[] = []; - let spliteBoxes: Box3Ext[] = []; - for (let key of this.boardMap.keys()) - { - let boards = this.boardMap.get(key); - if (boards.length > 1) - { - this.parseBoards(boards, unionBoxes, spliteBoxes); - } - else if (boards.length === 1) - { - let box = boards[0].BoundingBox as Box3Ext; - box.spliteType = boards[0].BoardType; - spliteBoxes.push(box); - } - } - this.SpliteBoxs(unionBoxes, spliteBoxes); - } - private SpliteBoxs(boxes: Box3Ext[], spliteBoxes: Box3Ext[]) - { - if (spliteBoxes.length === 0) - this.m_Spaces = boxes; - else - for (let i = 0; i < boxes.length; i++) + //归并盒子 + let boxComCol: Box3Ext[] = arrayRemoveDuplicateBySort2(boxCol, + (b1, b2) => { - let box = boxes[i]; - for (let j = 0; j < spliteBoxes.length; j++) + if ( + //对齐 + equaln( + b1.min.getComponent(splitType), + b2.min.getComponent(splitType), + ) + && + //厚度相等 + equaln( + b1.getSize(new Vector3()).getComponent(splitType), + b2.getSize(new Vector3()).getComponent(splitType) + ) + ) { - let bs = box.substract(spliteBoxes[j]); - if (bs.length > 1) - { - boxes.splice(i, 1, ...bs); - i -= (bs.length - 1); - break; - } - else if (j === spliteBoxes.length - 1) - { - this.m_Spaces.push(box); - } + b1.union(b2); + return true; } + return false; } + ); + return boxComCol; } - //分析2个盒子之间的空间 - private parseBox3(b1: Box3Ext, b2: Box3Ext, boardType: BoardType) - { - let dist: number; - switch (boardType) - { - case BoardType.Layer: - return this.getSpace(b1, b2, "z"); - case BoardType.Vertical: - return this.getSpace(b1, b2, "x"); - case BoardType.Behind: - return this.getSpace(b1, b2, "y"); - } - } - //获取2个盒子之间的空间 - getSpace(b1: Box3Ext, b2: Box3Ext, axis: string) - { - [b1, b2] = b1.min[axis] < b2.min[axis] ? [b1, b2] : [b2, b1]; - let dist = b2.min[axis] - b1.min[axis]; - if (dist <= b1.getSize(new Vector3())[axis]) - { - return new Box3Ext(); - } - let vec = new Vector3(); - vec[axis] = -dist; - b2.applyMatrix4(MoveMatrix(vec)); - if (b1.intersectsBox(b2)) - { - b1.intersect(b2); - } - else - { - b1.union(b2); - } - - let vec1 = new Vector3(); - vec1[axis] = b1.getSize(new Vector3())[axis]; - let vec2 = new Vector3(); - vec2[axis] = dist - b2.getSize(new Vector3())[axis]; - - return new Box3Ext(b1.min.add(vec1), b1.max.add(vec2)); - } - //分析多块板 - private parseBoards(boards: Board[], uniSpaces: Box3Ext[], spliteSPs: Box3Ext[]) + /** + *用单块板包围盒切割空间 + */ + private SpliteBoxs(box: Box3Ext, spliteBoxes: Map) { - let boxMap: Map = new Map(); - - for (let br of boards) - { - let box = br.BoundingBox as Box3Ext; - box.applyMatrix4(new Matrix4().extractRotation(br.BoardOCSInv)); - boxMap.set(br, box); - } - - switch (boards[0].BoardType) - { - case BoardType.Layer: - this.sortAndMerge(boards, boxMap, "z"); - break; - case BoardType.Vertical: - this.sortAndMerge(boards, boxMap, "x"); - break; - case BoardType.Behind: - this.sortAndMerge(boards, boxMap, "y"); - } - - if (boards.length === 1) - { - let box = boxMap.get(boards[0]); - box.spliteType = boards[0].BoardType; - spliteSPs.push(box); - } - if (uniSpaces.length === 0) - { - for (let i = 0; i < boards.length - 1; i++) - { - let b1 = boards[i]; - let box1 = boxMap.get(b1); - - let b2 = boards[i + 1]; - let box2 = boxMap.get(b2).clone(); - let box = this.parseBox3(box1, box2, b1.BoardType) - if (!box.isEmpty()) - { - uniSpaces.push(box); - } - } - } + if (spliteBoxes.size === 0) + this.m_Spaces = [box]; else { - for (let i = 0; i < boards.length - 1; i++) + let orgBoxs = [box]; + for (let [splitType, spBox] of spliteBoxes) { - let b1 = boards[i]; - let box1 = boxMap.get(b1); - let b2 = boards[i + 1]; - let box2 = boxMap.get(b2).clone(); - let box = this.parseBox3(box1.clone(), box2.clone(), b1.BoardType) - if (!box.isEmpty()) - { - if (uniSpaces.every(b => !b.intersectsBox(box))) - { - this.m_Spaces.push(box); - continue; - } - spliteSPs.push(box1) - } - - if (i === boards.length - 2) - { - spliteSPs.push(box2) - } - } - } - - } - //排序归并板件 - private sortAndMerge(boards: Board[], boxMap: Map, type: string) - { - boards.sort((a, b) => boxMap.get(a).min[type] - boxMap.get(b).min[type]); - - for (let i = 0; i < boards.length; i++) - { - let b1 = boards[i]; - let box1 = boxMap.get(b1); - for (let j = i + 1; j < boards.length; j++) - { - let b2 = boards[j]; - let box2 = boxMap.get(b2); - if (equaln(box1.min[type], box2.min[type])) - { - let b = box1.clone(); - box1.union(box2) - boards.splice(j, 1); - j--; - } - else - { - i = j - 1; - break; - } + let remBoxs: Box3Ext[] = []; + for (let b of orgBoxs) + remBoxs.push(...b.substract(spBox, splitType)); + orgBoxs = remBoxs; } + this.m_Spaces = orgBoxs; } } - } +// /** +// *用于分析出全部空间 +// * 待完善优化,暂留 +// * @export +// * @class GeneralSpaceParse2 +// * @extends {SpaceParse} +// */ +// export class GeneralSpaceParse2 extends SpaceParse +// { +// get Spaces() +// { +// return this.m_Spaces; +// } +// async SpaceParse() +// { +// super.SpaceParse(); +// let unionBoxes: Box3Ext[] = []; +// let spliteBoxes: Box3Ext[] = []; +// for (let key of this.boardMap.keys()) +// { +// let boards = this.boardMap.get(key); +// if (boards.length > 1) +// { +// this.parseBoards(boards, unionBoxes, spliteBoxes); +// } +// else if (boards.length === 1) +// { +// let box = boards[0].BoundingBox as Box3Ext; +// spliteBoxes.push(box); +// } +// } +// this.SpliteBoxs(unionBoxes, spliteBoxes); +// } +// private SpliteBoxs(boxes: Box3Ext[], spliteBoxes: Box3Ext[]) +// { +// if (spliteBoxes.length === 0) +// this.m_Spaces = boxes; +// else +// for (let i = 0; i < boxes.length; i++) +// { +// let box = boxes[i]; +// for (let j = 0; j < spliteBoxes.length; j++) +// { +// let bs = box.substract(spliteBoxes[j]); +// if (bs.length > 1) +// { +// boxes.splice(i, 1, ...bs); +// i -= (bs.length - 1); +// break; +// } +// else if (j === spliteBoxes.length - 1) +// { +// this.m_Spaces.push(box); +// } +// } +// } + +// } +// //分析2个盒子之间的空间 +// private parseBox3(b1: Box3Ext, b2: Box3Ext, boardType: BoardType) +// { +// let dist: number; +// switch (boardType) +// { +// case BoardType.Layer: +// return this.getSpace(b1, b2, "z"); +// case BoardType.Vertical: +// return this.getSpace(b1, b2, "x"); +// case BoardType.Behind: +// return this.getSpace(b1, b2, "y"); +// } +// } +// //获取2个盒子之间的空间 +// getSpace(b1: Box3Ext, b2: Box3Ext, axis: string) +// { +// [b1, b2] = b1.min[axis] < b2.min[axis] ? [b1, b2] : [b2, b1]; +// let dist = b2.min[axis] - b1.min[axis]; +// if (dist <= b1.getSize(new Vector3())[axis]) +// { +// return new Box3Ext(); +// } +// let vec = new Vector3(); +// vec[axis] = -dist; +// b2.applyMatrix4(MoveMatrix(vec)); +// if (b1.intersectsBox(b2)) +// { +// b1.intersect(b2); +// } +// else +// { +// b1.union(b2); +// } + +// let vec1 = new Vector3(); +// vec1[axis] = b1.getSize(new Vector3())[axis]; + +// let vec2 = new Vector3(); +// vec2[axis] = dist - b2.getSize(new Vector3())[axis]; + +// return new Box3Ext(b1.min.add(vec1), b1.max.add(vec2)); +// } +// //分析多块板 +// private parseBoards(boards: Board[], uniSpaces: Box3Ext[], spliteSPs: Box3Ext[]) +// { +// let boxMap: Map = new Map(); + +// for (let br of boards) +// { +// let box = br.BoundingBox as Box3Ext; +// box.applyMatrix4(new Matrix4().extractRotation(br.BoardOCSInv)); +// boxMap.set(br, box); +// } + +// switch (boards[0].BoardType) +// { +// case BoardType.Layer: +// this.sortAndMerge(boards, boxMap, "z"); +// break; +// case BoardType.Vertical: +// this.sortAndMerge(boards, boxMap, "x"); +// break; +// case BoardType.Behind: +// this.sortAndMerge(boards, boxMap, "y"); +// } + +// if (boards.length === 1) +// { +// let box = boxMap.get(boards[0]); +// box.spliteType = boards[0].BoardType; +// spliteSPs.push(box); +// } +// if (uniSpaces.length === 0) +// { +// for (let i = 0; i < boards.length - 1; i++) +// { +// let b1 = boards[i]; +// let box1 = boxMap.get(b1); + +// let b2 = boards[i + 1]; +// let box2 = boxMap.get(b2).clone(); +// let box = this.parseBox3(box1, box2, b1.BoardType) +// if (!box.isEmpty()) +// { +// uniSpaces.push(box); +// } +// } +// } +// else +// { +// for (let i = 0; i < boards.length - 1; i++) +// { +// let b1 = boards[i]; +// let box1 = boxMap.get(b1); +// let b2 = boards[i + 1]; +// let box2 = boxMap.get(b2).clone(); +// let box = this.parseBox3(box1.clone(), box2.clone(), b1.BoardType) +// if (!box.isEmpty()) +// { +// if (uniSpaces.every(b => !b.intersectsBox(box))) +// { +// this.m_Spaces.push(box); +// continue; +// } +// spliteSPs.push(box1) +// } + +// if (i === boards.length - 2) +// { +// spliteSPs.push(box2) +// } +// } +// } + +// } +// //排序归并板件 +// private sortAndMerge(boards: Board[], boxMap: Map, type: string) +// { +// boards.sort((a, b) => boxMap.get(a).min[type] - boxMap.get(b).min[type]); + +// for (let i = 0; i < boards.length; i++) +// { +// let b1 = boards[i]; +// let box1 = boxMap.get(b1); +// for (let j = i + 1; j < boards.length; j++) +// { +// let b2 = boards[j]; +// let box2 = boxMap.get(b2); +// if (equaln(box1.min[type], box2.min[type])) +// { +// let b = box1.clone(); +// box1.union(box2) +// boards.splice(j, 1); +// j--; +// } +// else +// { +// i = j - 1; +// break; +// } +// } +// } +// } + +// } diff --git a/src/Geometry/SpaceParse/PointPickSpaceParse.ts b/src/Geometry/SpaceParse/PointPickSpaceParse.ts index 9eacc6ed8..91cb273c4 100644 --- a/src/Geometry/SpaceParse/PointPickSpaceParse.ts +++ b/src/Geometry/SpaceParse/PointPickSpaceParse.ts @@ -79,14 +79,11 @@ export function PointPickSpaceParse(ptVcs: Vector3, view: Viewer, objectCol: Obj if (selectBoardCol.includes(br)) return false; - //根据Orbit的规则,应该是如下过滤. - if (i % 2 === 0) - { - if (br.BoardType === BoardType.Vertical) - return true; - } - else if (br.BoardType === BoardType.Layer) - return true; + //根据Orbit的规则,如果按X轴选择,则不选择层板 + if (i % 2 === 0 && br.BoardType === BoardType.Layer) + return false; + + return true; } return false; } diff --git a/src/Geometry/SpaceParse/SpaceParse.ts b/src/Geometry/SpaceParse/SpaceParse.ts index 14ff1647c..febd17cbb 100644 --- a/src/Geometry/SpaceParse/SpaceParse.ts +++ b/src/Geometry/SpaceParse/SpaceParse.ts @@ -59,13 +59,9 @@ export class SpaceParse { let tmpList = this.boardMap.get(b.BoardType); if (!tmpList) - { this.boardMap.set(b.BoardType, [b]) - } else - { tmpList.push(b); - } } } } From 7269b329a2d2faa7798715d05188a53ef2e7e987 Mon Sep 17 00:00:00 2001 From: ChenX Date: Fri, 24 Aug 2018 16:23:22 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E9=9D=A0=E5=B7=A6=E9=9D=A0=E5=8F=B3=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Add-on/DrawBoard/DrawBoardTool.ts | 2 +- src/Geometry/SpaceParse/GeneralSpaceParse.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Add-on/DrawBoard/DrawBoardTool.ts b/src/Add-on/DrawBoard/DrawBoardTool.ts index 3d9d9ec6e..63ae961c8 100644 --- a/src/Add-on/DrawBoard/DrawBoardTool.ts +++ b/src/Add-on/DrawBoard/DrawBoardTool.ts @@ -60,7 +60,7 @@ export abstract class DrawBoardTool implements Command let ptRes = await app.m_Editor.GetPoint({ Msg: "点选画板区域", AllowNone: true, - KeyWordList: [{ msg: "框选", key: "S" }, { msg: "全选", key: "A" }, { msg: "放弃", key: "U" }] + KeyWordList: [{ msg: "框选", key: "S" }, { msg: "放弃", key: "U" }] }); if (ptRes.Status === PromptStatus.OK) diff --git a/src/Geometry/SpaceParse/GeneralSpaceParse.ts b/src/Geometry/SpaceParse/GeneralSpaceParse.ts index f32849c8a..b3d97b4ce 100644 --- a/src/Geometry/SpaceParse/GeneralSpaceParse.ts +++ b/src/Geometry/SpaceParse/GeneralSpaceParse.ts @@ -24,6 +24,10 @@ export class GeneralSpaceParse extends SpaceParse async SpaceParse() { await super.SpaceParse(); + + if (this.boardMap.size === 0) + return; + let unionBoxCol: Box3Ext[] = []; let spliteBoxs = new Map(); for (let [boardType, boards] of this.boardMap) From f47a2d2fb5add76e983efe916f19767707b5d15a Mon Sep 17 00:00:00 2001 From: ChenX Date: Fri, 24 Aug 2018 17:02:34 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=8F=AA=E6=9C=89?= =?UTF-8?q?=E4=B8=80=E5=9D=97=E6=9D=BF=E7=9A=84=E6=97=B6=E5=80=99=E5=BB=B6?= =?UTF-8?q?=E4=BC=B8=E8=B7=9D=E7=A6=BB=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Geometry/SpaceParse/SpaceParse.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Geometry/SpaceParse/SpaceParse.ts b/src/Geometry/SpaceParse/SpaceParse.ts index febd17cbb..e84d5098f 100644 --- a/src/Geometry/SpaceParse/SpaceParse.ts +++ b/src/Geometry/SpaceParse/SpaceParse.ts @@ -87,11 +87,12 @@ export class SpaceParse if (dtRes.Status === PromptStatus.OK) { let dist = dtRes.Value; + let mat = br.RotateMat; let p1 = new Vector3(0, 0, -br.Thickness).applyMatrix4(mat); - let p2 = new Vector3(br.Width, br.Lenght, -dist).applyMatrix4(mat); + let p2 = new Vector3(br.Width, br.Lenght, -br.Thickness - dist).applyMatrix4(mat); let p3 = new Vector3(0, 0, 0).applyMatrix4(mat); - let p4 = new Vector3(br.Width, br.Lenght, br.Thickness + dist).applyMatrix4(mat); + let p4 = new Vector3(br.Width, br.Lenght, dist).applyMatrix4(mat); this.m_Spaces.push(new Box3Ext().setFromPoints([p1, p2]), new Box3Ext().setFromPoints([p3, p4])); } From 53e6d2d26bcb34e356b2ee2aaabd6f965d489b24 Mon Sep 17 00:00:00 2001 From: ChenX Date: Mon, 27 Aug 2018 11:26:53 +0800 Subject: [PATCH 8/8] =?UTF-8?q?fix=20#IMECK=20=E5=8D=95=E7=82=B9=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E9=80=89=E6=9D=BF,=E7=8E=B0=E5=9C=A8=E5=8F=AA?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E6=9C=80=E8=BF=91=E7=9A=84=E6=9D=BF=E4=BB=B6?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SpaceParse/PointPickSpaceParse.ts | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/Geometry/SpaceParse/PointPickSpaceParse.ts b/src/Geometry/SpaceParse/PointPickSpaceParse.ts index 91cb273c4..68eaaf5c0 100644 --- a/src/Geometry/SpaceParse/PointPickSpaceParse.ts +++ b/src/Geometry/SpaceParse/PointPickSpaceParse.ts @@ -70,30 +70,14 @@ export function PointPickSpaceParse(ptVcs: Vector3, view: Viewer, objectCol: Obj { let edgeP = edgePts[i]; let selectLine = new SelectLine(view, mouseP, edgeP); - selectLine.Select(undefined, { - filterFunction: (obj) => - { - if (obj.userData && obj.userData instanceof Board) - { - let br = obj.userData; - if (selectBoardCol.includes(br)) - return false; - - //根据Orbit的规则,如果按X轴选择,则不选择层板 - if (i % 2 === 0 && br.BoardType === BoardType.Layer) - return false; - - return true; - } - return false; - } - }); + selectLine.Select(undefined, { filterTypes: [Board] }); let brs = selectLine.SelectEntityList as Board[]; + let compareFn = comparePoint(edgeSorts[i]); - brs.sort((b1, b2) => compareFn(view.WorldToScreen(b1.MinPoint), view.WorldToScreen(b2.MinPoint))); - if (brs.length > 0) + brs.sort((b1, b2) => compareFn(view.WorldToScreen(b1.MinPoint), view.WorldToScreen(b2.MinPoint))); + if (brs.length > 0 && selectBoardCol.indexOf(brs[0]) === -1) selectBoardCol.push(brs[0]); } }