diff --git a/src/Add-on/DrawDrilling/DrawDrillingTool.ts b/src/Add-on/DrawDrilling/DrawDrillingTool.ts index c5e627608..23d88312e 100644 --- a/src/Add-on/DrawDrilling/DrawDrillingTool.ts +++ b/src/Add-on/DrawDrilling/DrawDrillingTool.ts @@ -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 = 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) - { - let d = drillent[i] as GangDrill; - d.ApplyMatrix(this.m_Face.OCSInv) - .ApplyMatrix(MoveMatrix(offVec)) - .ApplyMatrix(this.m_Face.OCS); - } + 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 = objId.Object as GangDrill; + d.ApplyMatrix(this.m_Face.OCSInv) + .ApplyMatrix(MoveMatrix(offVec)) + .ApplyMatrix(this.m_Face.OCS); } - drillList.push(...newDrillentList); } - InitTool(f: Face, opt: DrillingOption) + private CheckCollision(drills: ObjectId[][], refDrillList: ObjectId[][]) { - this.m_Face = f; - this.m_Option = opt; - this.m_MoveDistList.length = 0; - this.drillEnts = {}; + 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); + } + } + } } - RendDrill() + private IsCollision(drs1: ObjectId[], drs2: ObjectId[]) { - for (let [k, v] of this.drillMap) + for (let objId of drs1) { - k = null; - for (let drillent of v) + let d1 = objId.Object as GangDrill; + for (let objId1 of drs2) { - (Object.values(drillent) as GangDrill[]).forEach(d => app.m_Database.ModelSpace.Append(d)); + let d2 = objId1.Object as GangDrill; + if (d1.Collise(d2)) + { + 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(); } } diff --git a/src/DatabaseServices/3DSolid/GangDrill.ts b/src/DatabaseServices/3DSolid/GangDrill.ts index 7160aa5a6..995611dfc 100644 --- a/src/DatabaseServices/3DSolid/GangDrill.ts +++ b/src/DatabaseServices/3DSolid/GangDrill.ts @@ -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()); } diff --git a/src/DatabaseServices/Board.ts b/src/DatabaseServices/Board.ts index 1a45234f1..4b5ccd5c8 100644 --- a/src/DatabaseServices/Board.ts +++ b/src/DatabaseServices/Board.ts @@ -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 = 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) + } + } + } } } diff --git a/src/Geometry/DrillParse/Face.ts b/src/Geometry/DrillParse/Face.ts index 8fbe68e85..e0da953f0 100644 --- a/src/Geometry/DrillParse/Face.ts +++ b/src/Geometry/DrillParse/Face.ts @@ -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; diff --git a/src/UI/Components/Board/BoardModal.tsx b/src/UI/Components/Board/BoardModal.tsx index cde60c0b2..6d144e46a 100644 --- a/src/UI/Components/Board/BoardModal.tsx +++ b/src/UI/Components/Board/BoardModal.tsx @@ -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, -} - -//配置属性 -export interface configOption -{ - boardData?: BoardOption; - nailData?: LayerNailOption; - topBoardData?: TBBoardOption; - bottomBoardData?: TBBoardOption; - processData?: BoardProcessOption; + configs: Map, } diff --git a/src/UI/Components/Board/UserConfig.tsx b/src/UI/Components/Board/UserConfig.tsx index 66abfb62f..30947e732 100644 --- a/src/UI/Components/Board/UserConfig.tsx +++ b/src/UI/Components/Board/UserConfig.tsx @@ -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, + configs: Map, } /** @@ -44,10 +57,10 @@ export class UserConfig extends React.Component || new Map(); + let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map || new Map(); //如果名字重复确认是否继续 let isContinue = true; @@ -76,7 +89,7 @@ export class UserConfig extends React.Component; + let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map; brDataMap.delete(currentName); dbstore.Put(StoreName.ConfigData, type, brDataMap); @@ -92,7 +105,7 @@ export class UserConfig extends React.Component; + let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map; let conf = brDataMap.get(k); let store = this.props.store; if (brDataMap && conf) @@ -104,7 +117,7 @@ export class UserConfig extends React.Component || new Map(); + let brDataMap = await dbstore.Get(StoreName.ConfigData, type) as Map || new Map(); this.setState({ configs: brDataMap }); let confNames = Array.from(brDataMap.keys()); diff --git a/src/UI/Store/BoardStore.ts b/src/UI/Store/BoardStore.ts index 3a511db30..6d2216057 100644 --- a/src/UI/Store/BoardStore.ts +++ b/src/UI/Store/BoardStore.ts @@ -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); diff --git a/src/UI/Store/DrillStore.ts b/src/UI/Store/DrillStore.ts index 2a66e52cf..234f5083b 100644 --- a/src/UI/Store/DrillStore.ts +++ b/src/UI/Store/DrillStore.ts @@ -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; - } - } - } }