增加空间选择,简化空间分析

pull/93/head
Zoe 6 years ago
parent 3f2d3f88e4
commit 007611db7b

@ -1,9 +1,9 @@
import { Vector3 } from 'three';
import { Vector3, Matrix4, Raycaster } from 'three';
import { app } from '../../ApplicationServices/Application';
import { Board, BoardType } from '../../DatabaseServices/Board';
import { Command } from '../../Editor/CommandMachine';
import { PromptStatus } from '../../Editor/PromptResult';
import { MoveMatrix } from '../../Geometry/GeUtils';
import { MoveMatrix, equaln } from '../../Geometry/GeUtils';
import { GeneralSpaceParse } from '../../Geometry/SpaceParse/GeneralSpaceParse';
import { LayerBoardStore, ModalState, LayerPosType, LayerBoardOption } from '../../UI/Store/BoardStore';
import { BoardModalType } from '../../UI/Components/Board/BoardModal';
@ -12,11 +12,138 @@ import { Box3Ext } from '../../Geometry/Box';
export class DrawLayerBoard implements Command
{
async exec()
{
this.SelectBoards();
}
buildBoard(box: Box3Ext, opt: LayerBoardOption, ro: Matrix4)
{
let size = box.getSize(new Vector3());
let width = opt.isTotalWidth ? size.y : parseFloat(opt.width);
let count = parseInt(opt.count);
let type = opt.posType;
let dist = parseFloat(opt.dist);
let frontShrink = parseFloat(opt.frontShrink);
let board = Board.CreateBoard(size.x, width, parseFloat(opt.thickness), BoardType.Layer);
for (let i = 1; i <= count; i++)
{
let b = board.Clone() as Board;
if (type === LayerPosType.Top)
b.ApplyMatrix(MoveMatrix(box.min.clone().add(new Vector3(size.x, frontShrink, size.z - (dist / 100 * i)))));
else if (type === LayerPosType.Bottom)
b.ApplyMatrix(MoveMatrix(box.min.clone().add(new Vector3(size.x, frontShrink, (dist / 100) * i))));
else
b.ApplyMatrix(MoveMatrix(box.min.clone().add(new Vector3(size.x, frontShrink, size.z / (count + 1) * i))));
b.ApplyMatrix(ro);
app.m_Database.ModelSpace.Append(b);
}
}
async selectBox(spaces: Box3Ext[])
{
if (spaces.length === 1)
return spaces[0];
spaces.sort((b1, b2) =>
{
if (equaln(b2.min.z, b1.min.z))
{
return b1.min.y - b2.min.y;
}
return b1.min.z - b2.min.z
});
if (spaces.length > 2)
{
let keyWord = await app.m_Editor.GetKeyWords({
Msg: "输入位置:",
KeyWordList: [{ key: "1", msg: "靠上" }, { key: "2", msg: "靠下" }]
});
if (keyWord.StringResult == "1")
{
spaces = spaces.splice(spaces.length / 2, spaces.length / 2)
}
else if (keyWord.StringResult == "2")
{
spaces = spaces.splice(0, spaces.length / 2)
}
keyWord = await app.m_Editor.GetKeyWords({
Msg: "输入位置:",
KeyWordList: [{ key: "3", msg: "靠前" }, { key: "4", msg: "靠后" }]
});
if (keyWord.StringResult == "3")
{
spaces[0].min.y < spaces[1].min.y ? spaces.pop() : spaces.shift();
}
else if (keyWord.StringResult == "4")
{
spaces[0].min.y > spaces[1].min.y ? spaces.pop() : spaces.shift();
}
}
else
{
if (spaces[0].min.z === spaces[1].min.z)
{
let keyWord = await app.m_Editor.GetKeyWords({
Msg: "输入位置:",
KeyWordList: [{ key: "3", msg: "靠前" }, { key: "4", msg: "靠后" }]
});
if (keyWord.StringResult == "3")
{
spaces[0].min.y < spaces[1].min.y ? spaces.pop() : spaces.shift();
}
else if (keyWord.StringResult == "4")
{
spaces[0].min.y > spaces[1].min.y ? spaces.pop() : spaces.shift();
}
}
else
{
let keyWord = await app.m_Editor.GetKeyWords({
Msg: "输入位置:",
KeyWordList: [{ key: "1", msg: "靠上" }, { key: "2", msg: "靠下" }]
});
if (keyWord.StringResult == "1")
{
spaces = spaces.splice(spaces.length / 2, spaces.length / 2)
}
else if (keyWord.StringResult == "2")
{
spaces = spaces.splice(0, spaces.length / 2)
}
}
}
return spaces[0];
}
async PointSelect()
{
let ptRes = await app.m_Editor.GetPoint({ Msg: "点选画板区域" });
let view = app.m_Viewer;
if (ptRes.Status !== PromptStatus.Cancel)
{
let pt = ptRes.Value;
let raycaster = new Raycaster();
raycaster.setFromCamera({
x: (pt.x / view.Width) * 2 - 1, //-1 到 1 所以 (x-(w/2))/(w/2) =>
y: - (pt.y / view.Height) * 2 + 1 //y轴相反
}, view.Camera);
raycaster.ray.origin.sub(raycaster.ray.direction.clone().multiplyScalar(1e3));
}
}
async SelectBoards()
{
let exSsRes = await app.m_Editor.GetSelection({ Msg: "请选择对象<全部选择>:", UseSelect: true });
if (exSsRes.Status === PromptStatus.Cancel)
return;
let boardCus = exSsRes.SelectSet.SelectEntityList.filter(en =>
en instanceof Board) as Board[];
@ -39,52 +166,21 @@ export class DrawLayerBoard implements Command
return;
}
let opt = store.layerBoardOption;
let ro = new Matrix4().extractRotation(spaceParse.OCS);
for (let box of spaceParse.Spaces)
{
this.buildBoard(box, opt);
}
let spaces = spaceParse.Spaces;
let box = await this.selectBox(spaces);
this.buildBoard(box, opt, ro);
// for (let box of spaceParse.Spaces)
// {
// this.buildBoard(box, opt, ro);
// }
}
else
{
app.m_Editor.m_CommandStore.Prompt("请选择板件")
}
}
buildBoard(box: Box3Ext, opt: LayerBoardOption)
{
let size = box.getSize(new Vector3());
let width = opt.isTotalWidth ? size.y : parseFloat(opt.width);
let count = parseInt(opt.count);
let type = opt.posType;
let dist = parseFloat(opt.dist);
let frontShrink = parseFloat(opt.frontShrink);
let board = Board.CreateBoard(size.x, width, parseFloat(opt.thickness), BoardType.Layer);
switch (type)
{
case LayerPosType.Top:
for (let i = 1; i <= count; i++)
{
let b = board.Clone() as Board;
b.ApplyMatrix(MoveMatrix(box.min.clone().add(new Vector3(size.x, frontShrink, size.z - (dist / 100 * i)))));
app.m_Database.ModelSpace.Append(b);
}
break;
case LayerPosType.Bottom:
for (let i = 1; i <= count; i++)
{
let b = board.Clone() as Board;
b.ApplyMatrix(MoveMatrix(box.min.clone().add(new Vector3(size.x, frontShrink, (dist / 100) * i))));
app.m_Database.ModelSpace.Append(b);
}
break;
case LayerPosType.Mid:
for (let i = 1; i <= count; i++)
{
let b = board.Clone() as Board;
b.ApplyMatrix(MoveMatrix(box.min.clone().add(new Vector3(size.x, frontShrink, size.z / (count + 1) * i))));
app.m_Database.ModelSpace.Append(b);
}
}
}
}

@ -54,7 +54,6 @@ export function PointPick(ptVcs: Vector3, view: Viewer | PreViewer, selectObject
if (pickObj)
return [pickObj];
let selectList = [];
let pCenter = new THREE.Vector2(ptVcs.x, ptVcs.y);
let selectSize = new THREE.Vector2(10, 10);

@ -6,6 +6,8 @@ import { Line } from "../../DatabaseServices/Line";
import { Box3Ext } from "../Box";
import { MoveMatrix, equal, equaln } from "../GeUtils";
import { testBox3 } from "../../Add-on/testEntity/TestCurve";
import { arrayLast } from "../../Common/ArrayExt";
/**
*;
@ -34,13 +36,211 @@ export class GeneralSpaceParse extends SpaceParse
this.parseBoards(boards, unionBoxes, spliteBoxes);
}
else if (boards.length === 1)
{
let b = boards[0].Clone() as Board;
b.ApplyMatrix(new Matrix4().extractRotation(b.BoardOCSInv))
let box = b.BoundingBox;
box.spliteType = boards[0].BoardType;
spliteBoxes.push(box);
}
}
this.SpliteBoxs(this.MergeSpaces(unionBoxes) as Box3Ext, spliteBoxes);
}
private MergeSpaces(spaces: Box3Ext[])
{
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)
{
b1 = spaces[0];
let b2 = spaces[1];
if (b1.intersectsBox(b2))
{
return b1.intersect(b2);
}
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.length > 0)
{
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 b = br.Clone() as Board;
b.ApplyMatrix(new Matrix4().extractRotation(br.BoardOCSInv))
let box = b.BoundingBox;
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<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;
}
}
}
}
}
export class GeneralSpaceParse1 extends SpaceParse
{
private m_Spaces: Box3Ext[] = [];
get Spaces()
{
return this.m_Spaces;
}
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);
this.parseBoards2(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(this.MergeSpaces(unionBoxes), spliteBoxes);
// this.SpliteBoxs(this.MergeSpaces(unionBoxes), spliteBoxes);
this.SpliteBoxs2(unionBoxes, spliteBoxes);
}
private MergeSpaces(spaces: Box3Ext[])
{
@ -91,6 +291,31 @@ export class GeneralSpaceParse extends SpaceParse
}
}
}
private SpliteBoxs2(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)
@ -180,6 +405,81 @@ export class GeneralSpaceParse extends SpaceParse
}
}
}
private parseBoards2(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())
{
box.spliteType = b1.BoardType;
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;
}
box1.spliteType = b1.BoardType;
spliteSPs.push(box1)
}
if (i === boards.length - 2)
{
box2.spliteType = b1.BoardType;
spliteSPs.push(box2)
}
}
}
}
//排序归并板件
private sortAndMerge(boards: Board[], boxMap: Map<Board, Box3Ext>, type: string)
@ -209,4 +509,7 @@ export class GeneralSpaceParse extends SpaceParse
}
}
}
}

@ -35,7 +35,7 @@ export class SpaceParse
get OCS()
{
return this.m_StandardBoard ? this.m_StandardBoard.BoardOCS : new Matrix4();
return this.m_Boards[0].BoardOCS;
}
SpaceParse()
{

Loading…
Cancel
Save