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..63ae961c8 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'; @@ -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) @@ -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/Add-on/DrawBoard/DrawClosingStrip.ts b/src/Add-on/DrawBoard/DrawClosingStrip.ts index 6f9f4f1bb..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) { @@ -36,11 +35,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/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 22ab4dd1e..c0cc5646f 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 64f272a73..b3d97b4ce 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,429 +24,308 @@ export class GeneralSpaceParse extends SpaceParse async SpaceParse() { await 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); - } - else if (boards.length === 1) - { - let box = boards[0].GetBoardBoxInMat(this.SpaceOCSInv); - box.spliteType = boards[0].BoardType; - spliteBoxes.push(box); - } - } - let spaces = this.MergeSpaces(unionBoxes) as Box3Ext; - - spaces && this.SpliteBoxs(spaces, spliteBoxes); - } - /** - * 合并空间 - * 最多只会有3个空间 - * @param spaces - * @returns - */ - private MergeSpaces(spaces: Box3Ext[]) - { - if (spaces.length === 0) return undefined; + if (this.boardMap.size === 0) + return; - let b1 = spaces.shift(); - let isInt = false; - for (let box of spaces) + let unionBoxCol: Box3Ext[] = []; + let spliteBoxs = new Map(); + for (let [boardType, boards] of this.boardMap) { - if (b1.intersectsBox(box)) + let splitType: SplitType = ConverBoardTypeToSpaceType(boardType); + let boardBoxCol = this.ParseBoardBoxOfSortAndCombin(boards, splitType); + + 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 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.some(b => b === undefined)) - { - debugger; - } - if (bs.length > 0) - { - boxes.splice(i, 1, ...bs); - i -= (bs.length - 1); - if (i === boxes.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)) + let allSpaceBox: Box3Ext; + if (unionBoxCol.length === 0) { - 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 boxComCol: Box3Ext[] = arrayRemoveDuplicateBySort2(boxCol, + (b1, b2) => { - 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 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 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 orgBoxs = [box]; + for (let [splitType, spBox] of spliteBoxes) { - 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..68eaaf5c0 100644 --- a/src/Geometry/SpaceParse/PointPickSpaceParse.ts +++ b/src/Geometry/SpaceParse/PointPickSpaceParse.ts @@ -70,33 +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的规则,应该是如下过滤. - if (i % 2 === 0) - { - if (br.BoardType === BoardType.Vertical) - return true; - } - else if (br.BoardType === BoardType.Layer) - 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]); } } diff --git a/src/Geometry/SpaceParse/SpaceParse.ts b/src/Geometry/SpaceParse/SpaceParse.ts index a92639a3c..e84d5098f 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 @@ -62,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); - } } } } @@ -78,9 +71,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); }) } @@ -96,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])); } 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 } }