|
|
|
@ -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)
|
|
|
|
|
{
|
|
|
|
|
if (b1.intersectsBox(box))
|
|
|
|
|
{
|
|
|
|
|
isInt = true;
|
|
|
|
|
b1.intersect(box);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!isInt && spaces.length === 2)
|
|
|
|
|
let unionBoxCol: Box3Ext[] = [];
|
|
|
|
|
let spliteBoxs = new Map<SplitType, Box3Ext>();
|
|
|
|
|
for (let [boardType, boards] of this.boardMap)
|
|
|
|
|
{
|
|
|
|
|
b1 = spaces[0];
|
|
|
|
|
let b2 = spaces[1];
|
|
|
|
|
if (b1.intersectsBox(b2))
|
|
|
|
|
{
|
|
|
|
|
return b1.intersect(b2);
|
|
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return b1;
|
|
|
|
|
}
|
|
|
|
|
let splitType: SplitType = ConverBoardTypeToSpaceType(boardType);
|
|
|
|
|
let boardBoxCol = this.ParseBoardBoxOfSortAndCombin(boards, splitType);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*用单块板包围盒切割空间
|
|
|
|
|
*/
|
|
|
|
|
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)
|
|
|
|
|
if (boardBoxCol.length > 1)
|
|
|
|
|
{
|
|
|
|
|
this.m_Spaces.push(box);
|
|
|
|
|
let clampBox = boardBoxCol[0].clampSpace(arrayLast(boardBoxCol), splitType);
|
|
|
|
|
if (clampBox.isSolid())
|
|
|
|
|
unionBoxCol.push(clampBox);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*分析2个包围盒之间组成的空间包围盒
|
|
|
|
|
* @param {Box3Ext} b1
|
|
|
|
|
* @param {Box3Ext} b2
|
|
|
|
|
* @param {BoardType} boardType
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
private parseBox3(b1: Box3Ext, b2: Box3Ext, boardType: BoardType)
|
|
|
|
|
{
|
|
|
|
|
switch (boardType)
|
|
|
|
|
else if (boardBoxCol.length === 1)
|
|
|
|
|
{
|
|
|
|
|
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");
|
|
|
|
|
spliteBoxs.set(splitType, boardBoxCol[0]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
*分析多块板,先合并在排序
|
|
|
|
|
*合并完板多于2块,取最2边的2块板
|
|
|
|
|
* @private
|
|
|
|
|
* @param {Board[]} boards
|
|
|
|
|
* @param {Box3Ext[]} uniSpaces
|
|
|
|
|
* @memberof GeneralSpaceParse
|
|
|
|
|
*/
|
|
|
|
|
private parseBoards(boards: Board[], uniSpaces: Box3Ext[])
|
|
|
|
|
{
|
|
|
|
|
let boxMap: Map<Board, Box3Ext> = new Map();
|
|
|
|
|
|
|
|
|
|
for (let br of boards)
|
|
|
|
|
{
|
|
|
|
|
let box = br.GetBoardBoxInMat(this.SpaceOCSInv);
|
|
|
|
|
boxMap.set(br, box);
|
|
|
|
|
allSpaceBox = unionBoxCol[0];
|
|
|
|
|
for (let i = 1, len = unionBoxCol.length; i < len; i++)
|
|
|
|
|
allSpaceBox.intersect(unionBoxCol[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
this.SpliteBoxs(allSpaceBox, spliteBoxs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (boards.length >= 2)
|
|
|
|
|
//解析板件的盒子,已经排序并且归并.
|
|
|
|
|
private ParseBoardBoxOfSortAndCombin(boardCol: Board[], splitType: SplitType)
|
|
|
|
|
{
|
|
|
|
|
let b1 = boards[0];
|
|
|
|
|
let box1 = boxMap.get(b1).clone();
|
|
|
|
|
let b2 = arrayLast(boards);
|
|
|
|
|
let box2 = boxMap.get(b2).clone();
|
|
|
|
|
let boxCol = boardCol.map(b => { return b.GetBoardBoxInMat(this.SpaceOCSInv) });
|
|
|
|
|
|
|
|
|
|
let box = this.parseBox3(box1, box2, b1.BoardType);
|
|
|
|
|
if (!box.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
uniSpaces.push(box);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//排序归并板件
|
|
|
|
|
private sortAndMerge(boards: Board[], boxMap: Map<Board, Box3Ext>, type: string)
|
|
|
|
|
//根据分割类型排序
|
|
|
|
|
boxCol.sort((b1, b2) =>
|
|
|
|
|
{
|
|
|
|
|
boards.sort((a, b) => boxMap.get(a).min[type] - boxMap.get(b).min[type]);
|
|
|
|
|
return b1.min.getComponent(splitType) - b2.min.getComponent(splitType);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
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 boxComCol: Box3Ext[] = arrayRemoveDuplicateBySort2(boxCol,
|
|
|
|
|
(b1, b2) =>
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
if (
|
|
|
|
|
//对齐
|
|
|
|
|
equaln(
|
|
|
|
|
b1.min.getComponent(splitType),
|
|
|
|
|
b2.min.getComponent(splitType),
|
|
|
|
|
)
|
|
|
|
|
&&
|
|
|
|
|
//厚度相等
|
|
|
|
|
equaln(
|
|
|
|
|
b1.getSize(new Vector3()).getComponent(splitType),
|
|
|
|
|
b2.getSize(new Vector3()).getComponent(splitType)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
i = j - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
b1.union(b2);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return boxComCol;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*用于分析出全部空间
|
|
|
|
|
* 待完善优化,暂留
|
|
|
|
|
* @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())
|
|
|
|
|
private SpliteBoxs(box: Box3Ext, spliteBoxes: Map<SplitType, Box3Ext>)
|
|
|
|
|
{
|
|
|
|
|
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 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<Board, Box3Ext> = 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<Board, Box3Ext>, 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--;
|
|
|
|
|
}
|
|
|
|
|
if (spliteBoxes.size === 0)
|
|
|
|
|
this.m_Spaces = [box];
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
i = j - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let orgBoxs = [box];
|
|
|
|
|
for (let [splitType, spBox] of spliteBoxes)
|
|
|
|
|
{
|
|
|
|
|
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<Board, Box3Ext> = 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<Board, Box3Ext>, 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;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
|