From 6d319a9e802424a0c9f036c23b04809c518244fb Mon Sep 17 00:00:00 2001 From: Zoe Date: Mon, 9 Jul 2018 16:48:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=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/DrawLayerBoard.ts | 4 +- src/Add-on/DrawBoard/DrawVerticalBoard.ts | 2 +- src/Geometry/Box.ts | 44 ++- src/Geometry/SpaceParse/GeneralSpaceParse.ts | 312 ++++++++---------- src/Geometry/SpaceParse/SurroundSpaceParse.ts | 4 +- 5 files changed, 173 insertions(+), 193 deletions(-) diff --git a/src/Add-on/DrawBoard/DrawLayerBoard.ts b/src/Add-on/DrawBoard/DrawLayerBoard.ts index 58c34ff20..b67604f83 100644 --- a/src/Add-on/DrawBoard/DrawLayerBoard.ts +++ b/src/Add-on/DrawBoard/DrawLayerBoard.ts @@ -30,10 +30,10 @@ export class DrawLayerBoard implements Command let board: Board; for (let box of spaceParse.Spaces) { - let size = box.getSize(); + let size = box.getSize(new Vector3()); board = Board.CreateBoard(size.x, size.y, 0.18, BoardType.Layer); - board.ApplyMatrix(MoveMatrix(box.min.add(new Vector3(size.x, 0, size.z / 2)))); + board.ApplyMatrix(MoveMatrix(box.min.clone().add(new Vector3(size.x, 0, size.z / 2)))); app.m_Database.ModelSpace.Append(board); } } diff --git a/src/Add-on/DrawBoard/DrawVerticalBoard.ts b/src/Add-on/DrawBoard/DrawVerticalBoard.ts index b851b864a..f3662724c 100644 --- a/src/Add-on/DrawBoard/DrawVerticalBoard.ts +++ b/src/Add-on/DrawBoard/DrawVerticalBoard.ts @@ -32,7 +32,7 @@ export class DrawVerticalBoard implements Command let board: Board; for (let box of spaceParse.Spaces) { - let size = box.getSize(); + let size = box.getSize(new Vector3()); board = Board.CreateBoard(size.z, size.y, 0.18, BoardType.Vertical); board.ApplyMatrix(MoveMatrix(box.min.add(new Vector3(size.x / 2)))); app.m_Database.ModelSpace.Append(board); diff --git a/src/Geometry/Box.ts b/src/Geometry/Box.ts index e25e32c24..a100588d1 100644 --- a/src/Geometry/Box.ts +++ b/src/Geometry/Box.ts @@ -1,23 +1,55 @@ import * as THREE from 'three'; import { Vector3, Box3 } from 'three'; +import { BoardType } from '../DatabaseServices/Board'; + export class Box3Ext extends THREE.Box3 { + spliteType: BoardType; constructor(min?: Vector3, max?: Vector3) { super(min, max); } - substract(b: Box3) + substract(b: Box3Ext) { + if (this.intersectsBox(b)) + { + let box1 = this.clone(); + box1.intersect(b); + let max = box1.max; + let min = box1.min; + switch (b.spliteType) + { + case BoardType.Vertical: + return [ + new Box3Ext(min.clone().setX(this.min.x), max.clone().setX(max.x)), + new Box3Ext(min.clone().setX(max.x), max.clone().setX(this.max.x)) + ]; + case BoardType.Behind: + return [ + 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)) + ]; + case BoardType.Layer: + return [ + 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)) + ]; + } + } + return []; } - getSize(target?: Vector3) + intersectsBox(b: Box3) { - if (target === undefined) + let isInt = super.intersectsBox(b); + if (isInt) { - target = new Vector3(); + let box1 = this.clone() as Box3Ext; + let size = new Vector3(); + box1.intersect(b).getSize(size); + return size.x * size.y * size.z > 0; } - - return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min); + return false; } } diff --git a/src/Geometry/SpaceParse/GeneralSpaceParse.ts b/src/Geometry/SpaceParse/GeneralSpaceParse.ts index 03b5c50ae..2a5f53db5 100644 --- a/src/Geometry/SpaceParse/GeneralSpaceParse.ts +++ b/src/Geometry/SpaceParse/GeneralSpaceParse.ts @@ -4,12 +4,12 @@ import { SpaceParse } from "./SpaceParse"; import { app } from "../../ApplicationServices/Application"; import { Line } from "../../DatabaseServices/Line"; import { Box3Ext } from "../Box"; -import { MoveMatrix } from "../GeUtils"; +import { MoveMatrix, equal, equaln } from "../GeUtils"; +import { testBox3 } from "../../Add-on/testEntity/TestCurve"; export class GeneralSpaceParse extends SpaceParse { private m_Spaces: Box3Ext[] = []; - get Spaces() { return this.m_Spaces; @@ -17,241 +17,189 @@ export class GeneralSpaceParse extends SpaceParse SpaceParse() { super.SpaceParse(); - let spaces: Box3Ext[] = []; + let unionBoxes: Box3Ext[] = []; + let spliteBoxes: Box3Ext[] = []; for (let key of this.boardMap.keys()) { let boards = this.boardMap.get(key); - if (boards.length > 2) + if (boards.length > 1) { - this.parseBoards(boards, spaces); + this.parseBoards(boards, unionBoxes, spliteBoxes); } - else if (boards.length === 2) + else if (boards.length === 1) { - this.parseTwoBoards(boards[0], boards[1], spaces); + let box = boards[0].BoundingBox as Box3Ext; + box.spliteType = boards[0].BoardType; + spliteBoxes.push(box); } } + this.SpliteBoxs(this.MergeSpaces(unionBoxes), spliteBoxes); + } + private MergeSpaces(spaces: Box3Ext[]) + { + let rets: Box3Ext[] = []; while (spaces.length > 0) { let box = spaces.shift(); - while (true) + let isInt = false; + for (let b of spaces) { - //剩余的 不相交的形状表 remaining - let remSpaces = spaces.filter(b => - { - if (b.intersectsBox(box)) - { - box.intersect(b); - return false; - } - return true; - }); - - //如果c和剩余的轮廓都不相交,那么退出 - if (remSpaces.length === spaces.length) + if (b.intersectsBox(box)) { - this.m_Spaces.push(box); - break; + rets.push(box.clone().intersect(b) as Box3Ext); } - else - spaces = remSpaces; } + if (!isInt) + rets.push(box); } - + return rets; } - //分析2块板 - private parseTwoBoards(br1: Board, br2: Board, space: Box3Ext[]) + private SpliteBoxs(boxes: Box3Ext[], spliteBoxes: Box3Ext[]) + { + if (spliteBoxes.length === 0) + this.m_Spaces = boxes; + else + for (let box of boxes) + { + for (let i = 0; i < spliteBoxes.length; i++) + { + let bs = box.substract(spliteBoxes[i]); + if (bs.length > 0) + { + this.m_Spaces.push(...bs) + break; + } + else if (i === spliteBoxes.length - 1) + { + this.m_Spaces.push(box); + } + } + } + } + //分析2个盒子之间的空间 + private parseTwoBox3(b1: Box3Ext, b2: Box3Ext, boardType: BoardType) { - let b1 = br1.Clone() as Board; - let b2 = br2.Clone() as Board; - - b1.ApplyMatrix(new Matrix4().extractRotation(b1.BoardOCSInv)); - b2.ApplyMatrix(new Matrix4().extractRotation(b2.BoardOCSInv)); - - let minPt1 = b1.MinPoint; - let minPt2 = b2.MinPoint; - let dist: number; - let min1; - let max1; - let min2; - let max2; - - switch (br1.BoardType) + switch (boardType) { case BoardType.Layer: - [this.m_TopBoard, this.m_BottomBoard, b1, b2] = - minPt1.z > minPt2.z ? [br1, br2, b1, b2] : [br2, br1, b2, b1]; - - dist = Math.abs(minPt1.z - minPt2.z) - b2.Thickness; - if (dist <= 0) - return; - - min1 = b1.MinPoint.add(new Vector3(0, 0, -dist)) - max1 = b1.MinPoint.add(new Vector3(b1.Lenght, b1.Width)) - - min2 = b2.Position.add(new Vector3(-b2.Lenght)); - max2 = b2.Position.add(new Vector3(0, b2.Width, dist)) - - break; + return this.getSpace(b1, b2, "z"); case BoardType.Vertical: - [this.m_LeftBoard, this.m_RightBoard, b1, b2] = minPt1.x < minPt2.x ? [br1, br2, b1, b2] : [br2, br1, b2, b1]; - - dist = Math.abs(minPt1.x - minPt2.x) - b1.Thickness; - if (dist <= 0) - return; - min1 = b1.Position; - max1 = min1.clone().add(new Vector3(dist, b1.Width, b1.Lenght)); - - min2 = b2.Position.add(new Vector3(-dist - b2.Thickness)); - max2 = b2.Position.add(new Vector3(- b2.Thickness, b2.Width, b2.Lenght)); - - break; + return this.getSpace(b1, b2, "x"); case BoardType.Behind: - [this.m_FrontBoard, this.m_BehindBoard, b1, b2] = minPt1.y < minPt2.y ? [br1, br2, b1, b2] : [br2, br1, b2, b1]; - - dist = Math.abs(minPt1.y - minPt2.y) - b1.Thickness; - if (dist <= 0) - return; - min1 = b1.Position.add(new Vector3(0, b1.Thickness)); - max1 = b1.MaxPoint.add(new Vector3(0, dist)) - - min2 = b2.Position.add(new Vector3(0, -dist)); - max2 = b2.MaxPoint.add(new Vector3(0, -b2.Thickness)); - - break; - } - - let bBox1 = new Box3Ext(min1, max1); - let bBox2 = new Box3Ext(min2, max2); - - let box: Box3Ext; - - if (bBox1.intersectsBox(bBox2)) - { - box = bBox1.intersect(bBox2) as Box3Ext; + return this.getSpace(b1, b2, "y"); } - else + } + 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]) { - box = bBox1.union(bBox2) as Box3Ext; + return new Box3Ext(); } - - if (!box.isEmpty()) + let vec = new Vector3(); + vec[axis] = -dist; + b2.applyMatrix4(MoveMatrix(vec)); + if (b1.intersectsBox(b2)) { - space.push(box); + b1.intersect(b2); } - } - //分析2个盒子之间的空间 - private parseTwoBox3(b1: Box3Ext, b2: Box3Ext, boardType: BoardType) - { - switch (boardType) + else { - case BoardType.Layer: - [b1, b2] = b1.min.z < b2.min.z ? [b1, b2] : [b2, b1]; - let dist = b2.min.z - b1.min.z; - b2.applyMatrix4(MoveMatrix(new Vector3(0, 0, -dist))); - if (b1.intersectsBox(b2)) - { - b1.intersect(b2); - } - else - { - b1.union(b2); - } - return new Box3Ext(b1.min.add(new Vector3(0, 0, b1.getSize().z)), b1.max.add(new Vector3(0, 0, dist))); - case BoardType.Vertical: - [b1, b2] = b1.min.x < b2.min.x ? [b1, b2] : [b2, b1]; - dist = b2.min.x - b1.min.x; - b2.applyMatrix4(MoveMatrix(new Vector3(-dist))); - if (b1.intersectsBox(b2)) - { - b1.intersect(b2); - } - else - { - b1.union(b2); - } - return new Box3Ext(b1.min.add(new Vector3(b1.getSize().x)), b1.max.add(new Vector3(dist))); - case BoardType.Behind: - [b1, b2] = b1.min.y < b2.min.y ? [b1, b2] : [b2, b1]; - dist = b2.min.y - b1.min.y; - b2.applyMatrix4(MoveMatrix(new Vector3(0, -dist))); - if (b1.intersectsBox(b2)) - { - b1.intersect(b2); - } - else - { - b1.union(b2); - } - return new Box3Ext(b1.min.add(new Vector3(0, b1.getSize().y)), b1.max.add(new Vector3(0, dist))); + 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[], space: Box3Ext[]) + private parseBoards(boards: Board[], uniSpaces: Box3Ext[], spliteSPs: Box3Ext[]) { + let boxMap: Map = new Map(); - let ptMap = new Map(); for (let br of boards) { - let pos = br.Position; - pos.applyMatrix4(new Matrix4().extractRotation(br.BoardOCSInv)); - ptMap.set(br, pos); + let box = br.BoundingBox as Box3Ext; + box.applyMatrix4(new Matrix4().extractRotation(br.BoardOCSInv)); + boxMap.set(br, box); } switch (boards[0].BoardType) { case BoardType.Layer: - boards.sort((a, b) => - { - return ptMap.get(a).z - ptMap.get(b).z - }) + this.sortAndMerge(boards, boxMap, "z"); break; case BoardType.Vertical: - boards.sort((a, b) => - { - return ptMap.get(a).x - ptMap.get(b).x - }) + this.sortAndMerge(boards, boxMap, "x"); break; case BoardType.Behind: - boards.sort((a, b) => - { - return ptMap.get(a).y - ptMap.get(b).y - }) + this.sortAndMerge(boards, boxMap, "y"); } + if (boards.length === 1) + { + let box = boxMap.get(boards[0]); + box.spliteType = boards[0].BoardType; + spliteSPs.push(box); + } for (let i = 0; i < boards.length - 1; i++) { - this.parseTwoBoards(boards[i], boards[i + 1], space); + let b1 = boards[i]; + let b2 = boards[i + 1]; + let box1 = boxMap.get(b1) as Box3Ext; + let box2 = boxMap.get(b2).clone() as Box3Ext; + let box = this.parseTwoBox3(box1, box2, b1.BoardType) + if (!box.isEmpty()) + { + uniSpaces.push(box); + } } } - - private isHasSpace(b1: Board, b2: Board) + //排序归并板件 + private sortAndMerge(boards: Board[], boxMap: Map, type: string) { + boards.sort((a, b) => boxMap.get(a).min[type] - boxMap.get(b).min[type]); - } - 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()[axis]) - { - return new Box3(); - } - let vec = new Vector3(); - vec[axis] = -dist; - b2.applyMatrix4(MoveMatrix(vec)); - if (b1.intersectsBox(b2)) - { - b1.intersect(b2); - } - else + for (let i = 0; i < boards.length; i++) { - b1.union(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(); + if (box1.intersectsBox(box2)) + { + box1.intersect(box2); + let size = box1.getSize(new Vector3()); + if (size.x * size.y * size.z === 0) + { + box1.copy(b.union(box2) as Box3Ext); + } + } + else + { + box1.union(box2) + } + boards.splice(j, 1); + j--; + } + else + { + i = j - 1; + break; + } + } } - - let vec1 = new Vector3(); - vec1[axis] = b1.getSize()[axis] - return new Box3Ext(b1.min.add(vec1), b1.max.add(vec.negate())); } } diff --git a/src/Geometry/SpaceParse/SurroundSpaceParse.ts b/src/Geometry/SpaceParse/SurroundSpaceParse.ts index 90f7cfd43..ffc61dc49 100644 --- a/src/Geometry/SpaceParse/SurroundSpaceParse.ts +++ b/src/Geometry/SpaceParse/SurroundSpaceParse.ts @@ -89,8 +89,8 @@ export class SurroundSpaceParse extends SpaceParse b1.ApplyMatrix(new Matrix4().extractRotation(b1.BoardOCSInv)); b2.ApplyMatrix(new Matrix4().extractRotation(b2.BoardOCSInv)); - [this.m_LeftBoard, this.m_RightBoard] = - b1.Position.x < b2.Position.x ? [lrBoards[0], lrBoards[1]] : [lrBoards[1], lrBoards[0]]; + [this.m_LeftBoard, this.m_RightBoard, b1, b2] = + b1.Position.x < b2.Position.x ? [lrBoards[0], lrBoards[1], b1, b2] : [lrBoards[1], lrBoards[0], b2, b1]; if (this.ParseLRBoards(b1, b2)) {