多空间分析

pull/93/head
Zoe 6 years ago
parent b335036694
commit 6d319a9e80

@ -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);
}
}

@ -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);

@ -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;
}
}

@ -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<Board, Box3Ext> = 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<Board, Box3Ext>, 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()));
}
}

@ -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))
{

Loading…
Cancel
Save