!138 排钻碰撞检测,删除板件时删除排钻,重排

Merge pull request !138 from ZoeLeeFZ/drill_opt
pull/138/MERGE
ChenX 6 years ago
parent d2cd59eee8
commit c4736685d9

@ -1,36 +1,30 @@
import { Matrix4, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application";
import { arrayLast } from "../../Common/ArrayExt";
import { Singleton } from "../../Common/Singleton";
import { operationExpReg } from "../../Common/Utils";
import { GangDrill } from "../../DatabaseServices/3DSolid/GangDrill";
import { Board } from "../../DatabaseServices/Board";
import { ObjectId } from "../../DatabaseServices/ObjectId";
import { CollisionDetection } from "../../Geometry/DrillParse/CollisionDetection";
import { Face } from "../../Geometry/DrillParse/Face";
import { cZAxis, MoveMatrix, equaln } from "../../Geometry/GeUtils";
import { cZAxis, equaln, MoveMatrix } from "../../Geometry/GeUtils";
import { DrillingOption, SpacingType } from "../../UI/Components/Board/drillInterface";
import { Singleton } from "../../Common/Singleton";
import { DrillStore } from "../../UI/Store/DrillStore";
import { PXLFaceType } from "../../UI/Store/BoardInterface";
import { operationExpReg } from "../../Common/Utils";
interface DrillEnts
{
pxl?: GangDrill;
ljg?: GangDrill;
ymj?: GangDrill;
}
import { DrillStore } from "../../UI/Store/DrillStore";
export class DrawDrillingTool
{
private m_MoveDistList: number[] = [];
private m_Face: Face;
private m_Option: DrillingOption;
private drillEnts: DrillEnts = {};
private drillMap: Map<Board, DrillEnts[]> = new Map();
GetDrillingConfig()
private drillEnts: GangDrill[] = [];
private GetDrillingConfig()
{
//TODO:完善用户配置类,暂用store得数据进行测试
return Singleton.GetInstance(DrillStore).rules;
}
GetRuleByFace(f: Face): DrillingOption
private GetRuleByFace(f: Face): DrillingOption
{
const rules = this.GetDrillingConfig();
let length = f.m_Length;
@ -42,8 +36,8 @@ export class DrawDrillingTool
return rule;
}
}
//初始化排钻实体,排钻数组中偏心轮优先push;
InitDrill()
//初始化排钻实体
private InitDrill()
{
//绘制排钻实体,在WCS0点上.
let pxlDepth = parseFloat(this.m_Option.pxlDepth);
@ -52,30 +46,25 @@ export class DrawDrillingTool
let pxlEnt = GangDrill.CreateCylDrill(parseFloat(this.m_Option.pxlRad), pxlDepth);
this.drillEnts.pxl = pxlEnt;
this.drillEnts.push(pxlEnt);
//将三个实体移动到相应的位置
pxlEnt.ApplyMatrix(new Matrix4().makeRotationX(Math.PI / 2));
let ljgEnt = GangDrill.CreateCylDrill(ljgRad, ljgLength);
this.drillEnts.push(ljgEnt);
//如果都是侧面,不要预埋件
if (!this.m_Face.isEqualType)
{
let ymjEnt = GangDrill.CreateCylDrill(parseFloat(this.m_Option.ymjRad), parseFloat(this.m_Option.ymjDepth));
ymjEnt.ApplyMatrix(new Matrix4().setPosition(new Vector3(0, 0, ljgLength)));
this.drillEnts.ymj = ymjEnt;
this.drillEnts.push(ymjEnt);
}
else
{
ljgEnt.Height = ljgLength * 2;
}
this.drillEnts.ljg = ljgEnt;
for (let i in this.drillEnts)
for (let d of this.drillEnts)
{
let d = this.drillEnts[i];
d.ApplyMatrix(MoveMatrix(cZAxis.clone().multiplyScalar(-ljgLength)));
if (d === pxlEnt)
{
@ -110,14 +99,13 @@ export class DrawDrillingTool
}
//间距等分
EqulalSpacing()
private EqulalSpacing()
{
let startDist = parseFloat(this.m_Option.originDist);
let endDist = parseFloat(this.m_Option.retDist);
let count = parseInt(this.m_Option.count);
let length = this.m_Face.m_Length;
let ljgRad = parseFloat(this.m_Option.ljgRad);
let spacingSize: number;
let caclDist: Function;
@ -149,7 +137,7 @@ export class DrawDrillingTool
this.m_MoveDistList[i - 1] = caclDist(i) + this.m_MoveDistList[0];
}
//32倍数
Multiple32()
private Multiple32()
{
let startDist = parseFloat(this.m_Option.originDist);
let endDist = parseFloat(this.m_Option.retDist);
@ -192,64 +180,111 @@ export class DrawDrillingTool
this.m_MoveDistList[i - 1] = caclDist(i) + this.m_MoveDistList[0];
}
}
GetMoveDist()
private GetMoveDist()
{
if (this.m_Option.spacing === SpacingType.Multiple32)
this.Multiple32();
else
this.EqulalSpacing();
}
BuildDrill()
private BuildDrill()
{
let newDrillentList: DrillEnts[] = [];
let newDrillentList: ObjectId[][] = [];
for (let dist of this.m_MoveDistList)
{
//新的排钻列表
let newDrillEnt: DrillEnts = {};
for (let i in this.drillEnts)
let newDrillEnts: ObjectId[] = []
for (let d of this.drillEnts)
{
let d = this.drillEnts[i] as GangDrill;
let cloneD = d.Clone();
cloneD.ApplyMatrix(MoveMatrix(new Vector3(dist)))
.ApplyMatrix(this.m_Face.OCS);
newDrillEnt[i] = cloneD;
app.m_Database.ModelSpace.Append(cloneD);
newDrillEnts.push(cloneD.Id);
}
newDrillentList.push(newDrillEnt);
newDrillentList.push(newDrillEnts);
}
this.ParseThroughHole(newDrillentList);
this.ParseDrillList(newDrillentList);
}
ParseThroughHole(newDrillentList: DrillEnts[])
// 分析当前排钻
private ParseDrillList(drills: ObjectId[][])
{
//获得板件上存在的排钻
let localBoard = this.m_Face.m_LocalBoard;
let drillList = this.drillMap.get(localBoard);
if (!drillList)
let locaBoard = this.m_Face.m_LocalBoard;
let intBoard = this.m_Face.m_InterBoard;
//如果都是侧面,直接加入
if (this.m_Face.isEqualType)
{
this.SaveDrillToBoard(locaBoard, intBoard, drills);
return;
}
let oldLcDrIdList = locaBoard.DrillList.get(intBoard.Id);
//面已经排钻了,去掉旧的添加新的
if (oldLcDrIdList)
{
locaBoard.ClearDrillList(intBoard.Id);
intBoard.ClearDrillList(locaBoard.Id);
}
let refDrillList: ObjectId[][] = [];
//加入本地的板件排钻测试通孔
for (let [, v] of locaBoard.DrillList)
{
refDrillList.push(...v);
}
if (refDrillList.length > 0)
{
this.ParseThroughHole(drills, refDrillList);
}
//加入相交板件测试碰撞
for (let [, v] of intBoard.DrillList)
{
drillList = [];
this.drillMap.set(localBoard, drillList);
refDrillList.push(...v);
}
//碰撞检测
this.CheckCollision(drills, refDrillList);
//分析结束,排钻存入板件
this.SaveDrillToBoard(locaBoard, intBoard, drills);
}
//保存排钻到板件
private SaveDrillToBoard(lBr: Board, iBr: Board, drs: ObjectId[][])
{
//分析结束,排钻存入板件
lBr.AppendDrillList(iBr.Id, drs);
iBr.AppendDrillList(lBr.Id, drs);
}
private ParseThroughHole(drills: ObjectId[][], refDrillList: ObjectId[][])
{
//分析通孔
if (!this.m_Face.isEqualType && drillList.length > 0)
if (!this.m_Face.isEqualType)
{
for (let drillent of newDrillentList)
for (let drillent of drills)
{
let isThought = false;
let p1 = drillent.ymj.Position;
for (let refDrill of drillList)
let ymjEnt = (arrayLast(drillent).Object as GangDrill);
let p1 = ymjEnt.Position;
for (let refDrill of refDrillList)
{
let p2 = refDrill.ymj.Position;
let refYmjEnt = (arrayLast(refDrill).Object as GangDrill);
let p2 = refYmjEnt.Position;
let vec = p2.sub(p1);
if (equaln(vec.length(), localBoard.Thickness))
if (equaln(vec.length(), this.m_Face.m_LocalBoard.Thickness))
{
isThought = true;
//通孔偏移
if (!this.m_Option.tIsOffset)
{
drillent.ymj.Radian = parseFloat(this.m_Option.tYmjRad)
refDrill.ymj.Radian = parseFloat(this.m_Option.tYmjRad)
ymjEnt.Radian = parseFloat(this.m_Option.tYmjRad)
refYmjEnt.Radian = parseFloat(this.m_Option.tYmjRad)
}
break;
}
@ -259,39 +294,60 @@ export class DrawDrillingTool
if (isThought && this.m_Option.tIsOffset)
{
let offdist = parseFloat(this.m_Option.tHoleOffset);
let offVec = new Vector3(offdist);
for (let i in drillent)
this.MoveDrillEnts(drillent, offdist);
}
}
}
}
private MoveDrillEnts(drillent: ObjectId[], dist: number, dir = 1)
{
let offVec = new Vector3(dist * dir);
for (let objId of drillent)
{
let d = drillent[i] as GangDrill;
let d = objId.Object as GangDrill;
d.ApplyMatrix(this.m_Face.OCSInv)
.ApplyMatrix(MoveMatrix(offVec))
.ApplyMatrix(this.m_Face.OCS);
}
}
private CheckCollision(drills: ObjectId[][], refDrillList: ObjectId[][])
{
for (let ds of drills)
{
for (let refDr of refDrillList)
{
if (this.IsCollision(ds, refDr))
{
let offsetDist = parseFloat(this.m_Option.collsionDist);
this.MoveDrillEnts(ds, offsetDist, this.m_Face.IsPositiveFace ? 1 : -1);
}
}
drillList.push(...newDrillentList);
}
InitTool(f: Face, opt: DrillingOption)
{
this.m_Face = f;
this.m_Option = opt;
this.m_MoveDistList.length = 0;
this.drillEnts = {};
}
RendDrill()
private IsCollision(drs1: ObjectId[], drs2: ObjectId[])
{
for (let objId of drs1)
{
for (let [k, v] of this.drillMap)
let d1 = objId.Object as GangDrill;
for (let objId1 of drs2)
{
k = null;
for (let drillent of v)
let d2 = objId1.Object as GangDrill;
if (d1.Collise(d2))
{
(Object.values(drillent) as GangDrill[]).forEach(d => app.m_Database.ModelSpace.Append(d));
return true;
}
}
this.drillMap.clear();
}
return false;
}
private InitTool(f: Face, opt: DrillingOption)
{
this.m_Face = f;
this.m_Option = opt;
this.m_MoveDistList.length = 0;
this.drillEnts.length = 0;
}
StartGangDrill(brs: Board[])
{
@ -328,15 +384,13 @@ export class DrawDrillingTool
if (f.isEqualType)
{
//只需旋转偏心轮
delete this.drillEnts.ljg;
this.drillEnts.pop();
this.drillEnts.pxl.ApplyMatrix(new Matrix4().makeRotationY(Math.PI));
this.drillEnts[0].ApplyMatrix(new Matrix4().makeRotationY(Math.PI));
this.BuildDrill();
}
}
this.RendDrill();
}
}

@ -36,7 +36,17 @@ export class GangDrill extends Solid3D
{
return (this.m_Shape.Outline.Curve as Circle).Radius;
}
CreateGeometry()
get BoundingBox()
{
let box = this.m_Shape.BoundingBox;
box.expandByPoint(new Vector3(0, 0, this.m_Height));
return box.applyMatrix4(this.OCS);
}
Collise(tarDrill: GangDrill): boolean
{
return this.BoundingBox.intersectsBox(tarDrill.BoundingBox);
}
CreateGeometry(): ExtrudeGeometry
{
let extrudeSettings = {
bevelEnabled: false,
@ -44,7 +54,7 @@ export class GangDrill extends Solid3D
};
return new ExtrudeGeometry(this.m_Shape.Shape, extrudeSettings)
}
InitDrawObject(renderType: RenderType): Object3D
InitDrawObject(renderType: RenderType)
{
return new THREE.Mesh(this.CreateGeometry(), new MeshNormalMaterial());
}

@ -9,6 +9,7 @@ import { CADFile } from './CADFile';
import { Contour } from './Contour';
import { Entity } from './Entity';
import { Line } from './Line';
import { ObjectId } from './ObjectId';
import { DbPhysicalMaterial } from './PhysicalMaterial';
import { Shape } from './Shape';
@ -52,7 +53,8 @@ export class Board extends Entity
private m_BoardType: BoardType;
private m_Name = "";
m_BoardProcessOption: BoardProcessOption = {};
//板件排钻表,与之碰撞板件为key
private m_DrillList: Map<ObjectId, ObjectId[][]> = new Map();
constructor(shape?: Shape, thickness?: number)
{
super();
@ -93,6 +95,50 @@ export class Board extends Entity
// board.ColorIndex = boardType + 1;
return board;
}
get DrillList()
{
return this.m_DrillList;
}
AppendDrillList(k: ObjectId, drs: ObjectId[][])
{
this.WriteAllObjectRecord();
let drillList = this.m_DrillList.get(k);
if (!drillList)
{
this.m_DrillList.set(k, drs);
}
else
drillList.push(...drs);
}
ClearDrillList(k: ObjectId)
{
this.WriteAllObjectRecord();
let idList = this.m_DrillList.get(k);
if (idList)
{
for (let drillents of idList)
{
for (let objId of drillents)
{
if (!objId.IsErase)
objId.Object.Erase();
}
}
idList.length = 0;
this.m_DrillList.delete(k);
}
}
Erase()
{
for (const [id,] of this.m_DrillList)
{
this.ClearDrillList(id);
let br = id.Object as Board;
br.ClearDrillList(this.Id);
}
this.m_DrillList.clear();
super.Erase();
}
get RotateMat()
{
let roMat = new Matrix4();
@ -336,6 +382,27 @@ export class Board extends Entity
this.m_BoardType = file.Read();
this.m_Name = file.Read();
this.m_BoardProcessOption = JSON.parse(file.Read());
//读取排钻列表
this.m_DrillList.clear();
let size = file.Read();
for (let i = 0; i < size; i++)
{
let id = this.ReadObjectId(file);
let drIdList: ObjectId[][] = [];
let count = file.Read();
for (let i = 0; i < count; i++)
{
let drIDs: ObjectId[] = [];
let count1 = file.Read();
for (let j = 0; j < count1; j++)
{
drIDs.push(this.ReadObjectId(file));
}
drIdList.push(drIDs);
}
this.m_DrillList.set(id, drIdList);
}
this.Update();
}
WriteFile(file: CADFile)
@ -350,5 +417,21 @@ export class Board extends Entity
file.Write(this.m_BoardType);
file.Write(this.m_Name);
file.Write(JSON.stringify(this.m_BoardProcessOption));
//写入排钻列表
file.Write(this.m_DrillList.size);
for (let [id, idList] of this.m_DrillList)
{
this.WriteObjectId(file, id);
file.Write(idList.length);
for (let ids of idList)
{
file.Write(ids.length);
for (let id of ids)
{
this.WriteObjectId(file, id)
}
}
}
}
}

@ -44,6 +44,10 @@ export class Face
this.m_IsRect = opt.isRect ? opt.isRect : true;
}
}
get ID()
{
return this.m_LocalBoard.Id.Index.toString() + "-" + this.m_InterBoard.Id.Index.toString();
}
get IsRect()
{
return this.m_IsRect;

@ -4,7 +4,6 @@ import * as React from 'react';
import * as xaop from 'xaop';
import { app } from '../../../ApplicationServices/Application';
import { KeyBoard } from '../../../Common/KeyEnum';
import { BoardOption, BoardProcessOption, LayerNailOption, TBBoardOption } from '../../Store/BoardInterface';
import { BehindBoardStore, BoardStore, ClosingStripStore, LayerBoardStore, SideBoardStore, SingleBoardStore, TopBottomBoardStore, VerticalBoardStore } from '../../Store/BoardStore';
import { ModalState } from '../Modal/ModalsManage';
import { BehindBoardModal } from './BehindBoardModal';
@ -15,7 +14,7 @@ import { LayerBoardModal } from './LayerBoardModal';
import { LeftRightBoardModal } from './leftRightBoardModal';
import { SingleBoardModal } from './SingleBoardModal';
import { TopBottomBoardModal } from './TopBottomBoardModal';
import { UserConfig } from './UserConfig';
import { IConfigOption, UserConfig } from './UserConfig';
import { VerticalBoardModal } from './VerticalBoardModal';
export enum BoardModalType
@ -38,17 +37,7 @@ export interface BoardModalProps
export interface BoardModalState
{
configName: string,
configs: Map<string, configOption>,
}
//配置属性
export interface configOption
{
boardData?: BoardOption;
nailData?: LayerNailOption;
topBoardData?: TBBoardOption;
bottomBoardData?: TBBoardOption;
processData?: BoardProcessOption;
configs: Map<string, IConfigOption>,
}

@ -3,12 +3,25 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { arrayLast } from '../../../Common/ArrayExt';
import { IndexedDbStore, StoreName } from '../../../IndexedDb/IndexedDbStore';
import { BoardModalProps, configOption } from './BoardModal';
import { BoardModalProps } from './BoardModal';
import { BoardOption, LayerNailOption, TBBoardOption, BoardProcessOption } from '../../Store/BoardInterface';
import { DrillingOption } from './drillInterface';
//保存的配置
export interface IConfigOption
{
boardData?: BoardOption;
nailData?: LayerNailOption;
topBoardData?: TBBoardOption;
bottomBoardData?: TBBoardOption;
processData?: BoardProcessOption;
rules?: DrillingOption[];
}
interface UserConfigState
{
configName: string,
configs: Map<string, configOption>,
configs: Map<string, IConfigOption>,
}
/**
@ -44,10 +57,10 @@ export class UserConfig extends React.Component<BoardModalProps, UserConfigState
let type = this.props.type;
//新的配置
let newConfig: configOption = brStore.SaveConfig();
let newConfig: IConfigOption = brStore.SaveConfig();
//获取数据库中对应板类型的配置
let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map<string, configOption> || new Map();
let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map<string, IConfigOption> || new Map();
//如果名字重复确认是否继续
let isContinue = true;
@ -76,7 +89,7 @@ export class UserConfig extends React.Component<BoardModalProps, UserConfigState
//删除数据库中的对应项
let dbstore = await IndexedDbStore.CADStore();
let type = this.props.type;
let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map<string, configOption>;
let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map<string, IConfigOption>;
brDataMap.delete(currentName);
dbstore.Put(StoreName.ConfigData, type, brDataMap);
@ -92,7 +105,7 @@ export class UserConfig extends React.Component<BoardModalProps, UserConfigState
this.setState({ configName: k });
let dbstore = await IndexedDbStore.CADStore();
let type = this.props.type;
let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map<string, configOption>;
let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map<string, IConfigOption>;
let conf = brDataMap.get(k);
let store = this.props.store;
if (brDataMap && conf)
@ -104,7 +117,7 @@ export class UserConfig extends React.Component<BoardModalProps, UserConfigState
{
let dbstore = await IndexedDbStore.CADStore();
let type = this.props.type;
let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map<string, configOption> || new Map();
let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map<string, IConfigOption> || new Map();
this.setState({ configs: brDataMap });
let confNames = Array.from(brDataMap.keys());

@ -2,9 +2,9 @@
import { observable, toJS } from 'mobx';
import { app } from '../../ApplicationServices/Application';
import { BoardType } from '../../DatabaseServices/Board';
import { configOption } from '../Components/Board/BoardModal';
import { ModalState } from '../Components/Modal/ModalsManage';
import { BehindBoardOption, BehindHeightPositon, BoardOption, BoardProcessOption, BrRelativePos, ClosingStripOption, ComposingType, DrillType, LayerBoardOption, LayerNailOption, LinesType, PXLFaceType, SideBoardOption, SingleBoardOption, StripType, TBBoardOption, VerticalBoardOption } from './BoardInterface';
import { IConfigOption } from '../Components/Board/UserConfig';
export class BoardStore
{
@ -56,12 +56,12 @@ export class BoardStore
SaveConfig()
{
//新的配置
let newConfig: configOption = {};
let newConfig: IConfigOption = {};
newConfig.boardData = toJS(this.m_BoardOption);
newConfig.processData = toJS(this.m_BoardProcessOption);
return newConfig;
}
UpdateOption(cof: configOption)
UpdateOption(cof: IConfigOption)
{
Object.assign(this.m_BoardOption, cof.boardData);
Object.assign(this.m_BoardProcessOption, cof.processData);
@ -136,12 +136,12 @@ export class TopBottomBoardStore extends BoardStore
SaveConfig()
{
let newConfig: configOption = {};
let newConfig: IConfigOption = {};
newConfig.topBoardData = toJS(this.topBoardOption);
newConfig.bottomBoardData = toJS(this.bottomBoardOption);
return newConfig;
}
UpdateOption(cof: configOption)
UpdateOption(cof: IConfigOption)
{
Object.assign(this.topBoardOption, cof.topBoardData);
Object.assign(this.bottomBoardOption, cof.bottomBoardData);
@ -222,7 +222,7 @@ export class LayerBoardStore extends BoardStore
newConfig.nailData = toJS(this.layerNailOption);
return newConfig;
}
UpdateOption(cof: configOption)
UpdateOption(cof: IConfigOption)
{
super.UpdateOption(cof);
Object.assign(this.layerNailOption, cof.nailData);

@ -1,7 +1,8 @@
import { observable } from "mobx";
import { observable, toJS } from "mobx";
import { Face } from "../../Geometry/DrillParse/Face";
import { DrillingOption, DrillType, SpacingType } from "../Components/Board/drillInterface";
import { BoardStore } from "./BoardStore";
import { IConfigOption } from "../Components/Board/UserConfig";
export class DrillStore extends BoardStore
{
@ -102,8 +103,6 @@ export class DrillStore extends BoardStore
}
SaveRuleOption()
{
//TODO:暂存本地内存
//是否存在一样的起始距离
let hasEqualRule = true;
//插入位置
@ -131,6 +130,19 @@ export class DrillStore extends BoardStore
Object.assign(this.rules[this.m_CurrentRuleIndex], this.m_BoardOption);
}
}
SaveConfig()
{
//新的配置
let newConfig: IConfigOption = {};
this.SaveRuleOption();
newConfig.rules = toJS(this.rules);
return newConfig;
}
UpdateOption(cof: IConfigOption)
{
observable(this.rules).replace(cof.rules);
this.ChangeRules(0);
}
ChangeRules(i)
{
this.m_CurrentRuleIndex = i;
@ -142,18 +154,4 @@ export class DrillStore extends BoardStore
this.m_CurrentRuleIndex -= 1;
this.ChangeRules(this.m_CurrentRuleIndex);
}
GetRuleByFace(f: Face): DrillingOption
{
const rules = this.rules;
let length = f.m_Length;
for (let rule of rules)
{
let startDist = parseFloat(rule.startDist);
let endDist = parseFloat(rule.endDist);
if (length - 1e-6 < endDist && length + 1e-6 >= startDist)
{
return rule;
}
}
}
}

Loading…
Cancel
Save