pull/635/MERGE v0.3.0
ZoeLeeFZ 5 years ago committed by ChenX
parent 8cf6f2fb23
commit 521b17a7ac

@ -4,7 +4,7 @@ import { arrayLast } from "../Common/ArrayExt";
import { EBoardKeyList } from "../Common/BoardKeyList";
import { safeEval } from "../Common/eval";
import { FixedNotZero } from "../Common/Utils";
import { GangDrill, GangDrillType } from "../DatabaseServices/3DSolid/GangDrill";
import { CylinderHole, GangDrillType } from "../DatabaseServices/3DSolid/CylinderHole";
import { LineAngularDimension } from "../DatabaseServices/Dimension/2LineAngularDimension";
import { AlignedDimension } from "../DatabaseServices/Dimension/AlignedDimension";
import { Board } from "../DatabaseServices/Entity/Board";
@ -91,12 +91,12 @@ export class BoardFindModify implements Command
filterTypes.push(AlignedDimension, LineAngularDimension);
if (option.condition.useDrill || option.condition.useNail || option.condition.useWood)
filterTypes.push(GangDrill);
filterTypes.push(CylinderHole);
let brs = (await this.GetBoards(filterTypes))
.filter(en =>
{
if (en instanceof GangDrill)
if (en instanceof CylinderHole)
{
return ((en.Type === GangDrillType.Pxl
|| en.Type === GangDrillType.Ymj

@ -20,8 +20,7 @@ export class FeedingCommand implements Command
if (brRes.Status === PromptStatus.Cancel)
return;
let brs = brRes.SelectSet.SelectEntityList
.filter((br: Board) => br.BoardModeling.length > 0) as Board[];
let brs = brRes.SelectSet.SelectEntityList as Board[];
if (brs.length > 0)
{
let feedingTool = FeedingToolPath.GetInstance() as FeedingToolPath;

@ -1,6 +1,6 @@
import { app } from '../ApplicationServices/Application';
import { arrayRemoveIf } from '../Common/ArrayExt';
import { GangDrill, GangDrillType } from '../DatabaseServices/3DSolid/GangDrill';
import { Hole } from '../DatabaseServices/3DSolid/Hole';
import { Board } from '../DatabaseServices/Entity/Board';
import { Entity } from '../DatabaseServices/Entity/Entity';
import { Light } from '../DatabaseServices/Lights/Light';
@ -8,6 +8,7 @@ import { Command } from '../Editor/CommandMachine';
import { JigUtils } from '../Editor/JigUtils';
import { PromptStatus } from '../Editor/PromptResult';
import { MoveMatrix } from '../Geometry/GeUtils';
import { CylinderHole, GangDrillType } from '../DatabaseServices/3DSolid/CylinderHole';
export class Command_Copy implements Command
{
@ -32,7 +33,7 @@ export class Command_Copy implements Command
,idObjectIdundefined
*/
if (orgEns.some(en => en instanceof Board))
arrayRemoveIf(orgEns, e => e instanceof GangDrill);
arrayRemoveIf(orgEns, e => (e instanceof Hole));
let jigEns = orgEns.map(e => JigUtils.Draw(e));
while (true)
@ -60,7 +61,7 @@ export class Command_Copy implements Command
{
if (en instanceof Board)
en.DrillList.clear();//由于实体的新建的,所以历史记录会自动保存它的最新快照
else if (en instanceof GangDrill && en.Type === GangDrillType.Nail)
else if (en instanceof CylinderHole && en.Type === GangDrillType.Nail)
{
let br1: Board;
let br2: Board;

@ -2,11 +2,10 @@ import { Box3, Vector3 } from "three";
import { app } from "../ApplicationServices/Application";
import { arrayRemoveIf } from "../Common/ArrayExt";
import { copyTextToClipboard } from "../Common/Utils";
import { GangDrill } from "../DatabaseServices/3DSolid/GangDrill";
import { Hole } from "../DatabaseServices/3DSolid/Hole";
import { CADFiler } from "../DatabaseServices/CADFiler";
import { Board } from "../DatabaseServices/Entity/Board";
import { PromptStatus } from "../Editor/PromptResult";
import { deflate } from "../Common/SerializeMaterial";
export class CopyClip
{
@ -18,7 +17,7 @@ export class CopyClip
let ens = ss.SelectEntityList;
if (ens.some(en => en instanceof Board))
arrayRemoveIf(ens, e => e instanceof GangDrill);
arrayRemoveIf(ens, e => (e instanceof Hole));
let basePt: Vector3;

@ -1,5 +1,4 @@
import { Board, BoardType } from "../../DatabaseServices/Entity/Board";
import { GangDrill, GangDrillType } from "../../DatabaseServices/3DSolid/GangDrill";
import { LayerBoardOption, LayerNailOption } from "../../UI/Store/BoardInterface";
import { Matrix4, Vector3 } from "three";
import { MoveMatrix, equalv3 } from "../../Geometry/GeUtils";
@ -7,6 +6,7 @@ import { ObjectId } from "../../DatabaseServices/ObjectId";
import { arrayLast } from "../../Common/ArrayExt";
import { ISpaceParse } from "../../Geometry/SpaceParse/ISpaceParse";
import { app } from "../../ApplicationServices/Application";
import { CylinderHole, GangDrillType } from "../../DatabaseServices/3DSolid/CylinderHole";
enum NailPos
{
Left = 0,
@ -16,7 +16,7 @@ enum NailPos
interface INailProps
{
pos: NailPos;
nail: GangDrill;
nail: CylinderHole;
}
class BuildLayerNailsTool
@ -50,7 +50,7 @@ class BuildLayerNailsTool
if (this.leftBoard)
{
let lNail = GangDrill.CreateCylDrill(rad, nailOpt.length, GangDrillType.Nail);
let lNail = CylinderHole.CreateCylHole(rad, nailOpt.length, GangDrillType.Nail);
lNail.ApplyMatrix(new Matrix4().makeRotationX(Math.PI / 2))
.ApplyMatrix(MoveMatrix(new Vector3(frontDist, br.Height + depth + leftShrink, -rad)));
initNails.push({
@ -61,7 +61,7 @@ class BuildLayerNailsTool
if (this.rightBoard)
{
let rNail = GangDrill.CreateCylDrill(rad, nailOpt.length, GangDrillType.Nail);
let rNail = CylinderHole.CreateCylHole(rad, nailOpt.length, GangDrillType.Nail);
rNail.ApplyMatrix(new Matrix4().makeRotationX(-Math.PI / 2))
.ApplyMatrix(MoveMatrix(new Vector3(frontDist, -depth - rightShrink, -rad)));
initNails.push({
@ -75,7 +75,7 @@ class BuildLayerNailsTool
{
let backShrink = (this.space.Size.y - layerOpt.frontShrink) - br.Width;
let bNail = GangDrill.CreateCylDrill(rad, nailOpt.length, GangDrillType.Nail);
let bNail = CylinderHole.CreateCylHole(rad, nailOpt.length, GangDrillType.Nail);
bNail.ApplyMatrix(new Matrix4().makeRotationY(-Math.PI / 2))
.ApplyMatrix(MoveMatrix(new Vector3(br.Width + depth + backShrink, frontDist, -rad)));
initNails.push({
@ -249,7 +249,7 @@ class BuildLayerNailsTool
let nId: ObjectId;
if (i < oldNailIds.length)
{
let nail = oldNailIds[i].Object as GangDrill;
let nail = oldNailIds[i].Object as CylinderHole;
if (nail.IsErase)
nail.Erase(false);
if (!equalv3(nail.Normal, nailProps[i].nail.Normal))

@ -3,7 +3,7 @@ import { app } from "../../ApplicationServices/Application";
import { Board } from "../../DatabaseServices/Entity/Board";
import { PromptStatus } from "../../Editor/PromptResult";
import { DrawDrillingTool } from "./DrawDrillingTool";
import { GangDrill } from "../../DatabaseServices/3DSolid/GangDrill";
import { CylinderHole } from "../../DatabaseServices/3DSolid/CylinderHole";
enum EDeleteDrillType
{
@ -36,7 +36,7 @@ export class DeleteDrill implements Command
{
case EDeleteDrillType.All:
promptMsg = "<全部删除>选择板件或者排钻进行删除排钻:";
filterTypes = [Board, GangDrill];
filterTypes = [Board, CylinderHole];
break;
case EDeleteDrillType.Face:
promptMsg = "<板件间排钻删除>选择板件,删除板件间关联的排钻:";
@ -48,7 +48,7 @@ export class DeleteDrill implements Command
break;
case EDeleteDrillType.Drills:
promptMsg = "<删除排钻>选择排钻实体进行删除:";
filterTypes = [GangDrill];
filterTypes = [CylinderHole];
break;
default:
break;
@ -62,7 +62,7 @@ export class DeleteDrill implements Command
if (brRes.Status === PromptStatus.OK)
{
let ens = brRes.SelectSet.SelectEntityList as (Board | GangDrill)[];
let ens = brRes.SelectSet.SelectEntityList as (Board | CylinderHole)[];
switch (this.deleteType)
{
case EDeleteDrillType.All:

@ -6,9 +6,8 @@ import { EBoardKeyList } from "../../Common/BoardKeyList";
import { safeEval } from "../../Common/eval";
import { Singleton } from "../../Common/Singleton";
import { FixedNotZero } from "../../Common/Utils";
import { GangDrill, GangDrillType } from "../../DatabaseServices/3DSolid/GangDrill";
import { CylinderHole, GangDrillType } from "../../DatabaseServices/3DSolid/CylinderHole";
import { Board } from "../../DatabaseServices/Entity/Board";
import { Circle } from "../../DatabaseServices/Entity/Circle";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { GroupRecord } from "../../DatabaseServices/GroupTableRecord";
import { ObjectId } from "../../DatabaseServices/ObjectId";
@ -16,24 +15,32 @@ import { IsPointInPolyLine } from "../../DatabaseServices/PointInPolyline";
import { userConfig } from "../../Editor/UserConfig";
import { CollisionDetection } from "../../Geometry/DrillParse/CollisionDetection";
import { Face } from "../../Geometry/DrillParse/Face";
import { equaln, MoveMatrix, ZAxis } from "../../Geometry/GeUtils";
import { equaln, MoveMatrix, ZAxis, isParallelTo, YAxis } from "../../Geometry/GeUtils";
import { FaceDirection } from "../../UI/Store/BoardInterface";
import { DrillingOption, SpacingType } from "../../UI/Store/drillInterface";
import { appCache } from "../../Common/AppCache";
import { StoreageKeys } from "../../Common/StoreageKeys";
import { PostJson, RequestStatus } from "../../Common/Request";
import { TemplateUrls } from "../../Common/HostUrl";
import { inflate, ExtrudeDrillFileIn } from "../../Common/SerializeMaterial";
import { Entity } from "../../DatabaseServices/Entity/Entity";
import { Box3Ext } from "../../Geometry/Box";
import { Line } from "../../DatabaseServices/Entity/Line";
import { ExtrudeHole } from "../../DatabaseServices/3DSolid/ExtrudeHole";
import { Hole } from "../../DatabaseServices/3DSolid/Hole";
export class DrawDrillingTool extends Singleton
{
private m_MoveDistList: number[] = [];
private m_Face: Face;
private m_Option: DrillingOption;
private drillEnts: GangDrill[] = [];
private woodPins: GangDrill[] = [];
private woodPins: CylinderHole[] = [];
private drillEnts: Hole[] = [];
//缓存相同碰撞面的配置
private _configCache: Map<string, DrillingOption> = new Map();
//缓存相同碰撞面得初始排钻
private _drillEntsCache: Map<string, GangDrill[]> = new Map();
private _woodPinsCache: Map<string, GangDrill[]> = new Map();
private _drillEntsCache: Map<string, CylinderHole[]> = new Map();
private _woodPinsCache: Map<string, CylinderHole[]> = new Map();
constructor()
{
super();
@ -57,12 +64,12 @@ export class DrawDrillingTool extends Singleton
}
private GetRuleByFace(f: Face)
{
let length = f.m_Length;
let key = f.drillType + "-" + FixedNotZero(length, 2);
let length = f.Length;
let key = f.DrillType + "-" + FixedNotZero(length, 2);
if (this._configCache.has(key))
return this._configCache.get(key);
const rules = this.GetDrillingConfig(f.drillType);
const rules = this.GetDrillingConfig(f.DrillType);
for (let rule of rules)
{
let startDist = rule.startDist;
@ -86,17 +93,17 @@ export class DrawDrillingTool extends Singleton
let ljgDepth = this.m_Option.wdepth;
//大孔半径
let bigRad = this.m_Option.wbHoleRad;
let pxlEnt: GangDrill;
let pxlEnt: CylinderHole;
if (bigRad)
{
pxlEnt = GangDrill.CreateCylDrill(bigRad, pxlDepth, GangDrillType.WoodPXL);
pxlEnt = CylinderHole.CreateCylHole(bigRad, pxlDepth, GangDrillType.WoodPXL);
pxlEnt.ColorIndex = 6;
this.woodPins.push(pxlEnt);
//将三个实体移动到相应的位置
pxlEnt.ApplyMatrix(new Matrix4().makeRotationX(Math.PI / 2));
}
let ljgEnt = GangDrill.CreateCylDrill(ljgRad, ljgLength + ljgDepth, GangDrillType.Wood);
let ljgEnt = CylinderHole.CreateCylHole(ljgRad, ljgLength + ljgDepth, GangDrillType.Wood);
ljgEnt.ColorIndex = 6;
this.woodPins.push(ljgEnt);
@ -113,51 +120,90 @@ export class DrawDrillingTool extends Singleton
}
}
let isPostive = this.m_Face.m_InterBoard.BoardProcessOption.bigHoleDir === FaceDirection.Front;
let isPostive = this.m_Face.InterBoard.BoardProcessOption.bigHoleDir === FaceDirection.Front;
for (let d of this.woodPins)
{
d.ApplyMatrix(MoveMatrix(ZAxis.clone().multiplyScalar(-ljgLength)));
if (d.Type === GangDrillType.WoodPXL)
{
d.ApplyMatrix(MoveMatrix(
new Vector3(0, isPostive ? this.m_Face.m_Width : pxlDepth)
new Vector3(0, isPostive ? this.m_Face.Width : pxlDepth)
));
}
else
{
//木销位置
let posHeight = safeEval(this.m_Option.woodPinPos, { H: this.m_Face.m_Width });
let posHeight = safeEval(this.m_Option.woodPinPos, { H: this.m_Face.Width });
if (!isNaN(posHeight))
d.ApplyMatrix(MoveMatrix(new Vector3(0, isPostive ? this.m_Face.m_Width - posHeight : posHeight)));
d.ApplyMatrix(MoveMatrix(new Vector3(0, isPostive ? this.m_Face.Width - posHeight : posHeight)));
}
}
}
get CacheKey()
{
let isPostive = this.IsPostive;
return this.m_Face.DrillType + "-" + FixedNotZero(this.m_Face.Length, 2) + "-" + FixedNotZero(this.m_Face.Width, 2) + isPostive + this.m_Face.isEqualType;
}
get IsPostive()
{
return this.m_Face.InterBoard.BoardProcessOption.bigHoleDir === FaceDirection.Front;
}
//初始化排钻实体
private InitDrill()
{
//缓存初始化排钻
let key = this.CacheKey;
if (this._drillEntsCache.has(key))
{
this.drillEnts.push(...this._drillEntsCache.get(key));
}
else
{
//初始化排钻
this._InitDrill();
this._drillEntsCache.set(key, this.drillEnts.slice() as CylinderHole[]);
}
if (this.m_Option.isDrawWood)
{
if (this._woodPinsCache.has(key))
{
this.woodPins.push(...this._woodPinsCache.get(key));
}
else
{
this.InitWoodPins();
this._woodPinsCache.set(key, this.woodPins.slice());
}
}
}
//初始化排钻实体
private _InitDrill()
{
//绘制排钻实体,在WCS0点上.
let pxlDepth = this.m_Option.pxlDepth;
let ljgRad = this.m_Option.ljgRad;
let ljgLength = this.m_Option.ljgLength;
let pxlEnt: GangDrill;
let pxlEnt: CylinderHole;
if (this.m_Option.pxlRad)
{
pxlEnt = GangDrill.CreateCylDrill(this.m_Option.pxlRad, pxlDepth, GangDrillType.Pxl);
pxlEnt = CylinderHole.CreateCylHole(this.m_Option.pxlRad, pxlDepth, GangDrillType.Pxl);
this.drillEnts.push(pxlEnt);
//将三个实体移动到相应的位置
pxlEnt.ApplyMatrix(new Matrix4().makeRotationX(Math.PI / 2));
}
let ljgEnt = GangDrill.CreateCylDrill(ljgRad, ljgLength, GangDrillType.Ljg);
let ljgEnt = CylinderHole.CreateCylHole(ljgRad, ljgLength, GangDrillType.Ljg);
this.drillEnts.push(ljgEnt);
//如果都是侧面,不要预埋件,多个偏心轮
if (!this.m_Face.isEqualType)
{
let ymjEnt = GangDrill.CreateCylDrill(this.m_Option.ymjRad, this.m_Option.ymjDepth, GangDrillType.Ymj);
let ymjEnt = CylinderHole.CreateCylHole(this.m_Option.ymjRad, this.m_Option.ymjDepth, GangDrillType.Ymj);
ymjEnt.ApplyMatrix(new Matrix4().setPosition(new Vector3(0, 0, ljgLength)));
this.drillEnts.push(ymjEnt);
}
@ -172,29 +218,68 @@ export class DrawDrillingTool extends Singleton
}
}
let isPostive = this.m_Face.m_InterBoard.BoardProcessOption.bigHoleDir === FaceDirection.Front;
let isPostive = this.IsPostive;
for (let d of this.drillEnts)
{
d.ApplyMatrix(MoveMatrix(ZAxis.clone().multiplyScalar(-ljgLength)));
if (d.Type === GangDrillType.Pxl)
if ((<CylinderHole>d).Type === GangDrillType.Pxl)
{
//偏心轮下偏距离
let pxlOffestDist = this.m_Option.pxlOffset;
d.ApplyMatrix(MoveMatrix(
new Vector3(0, isPostive ? this.m_Face.m_Width - pxlOffestDist : pxlDepth - pxlOffestDist)
new Vector3(0, this.IsPostive ? this.m_Face.Width - pxlOffestDist : pxlDepth - pxlOffestDist)
));
}
else
{
//连接杆位置
let posHeight = safeEval(this.m_Option.ljgPos, { H: this.m_Face.m_Width });
let posHeight = safeEval(this.m_Option.ljgPos, { H: this.m_Face.Width });
if (!isNaN(posHeight))
d.ApplyMatrix(MoveMatrix(new Vector3(0, isPostive ? this.m_Face.m_Width - posHeight : posHeight)));
d.ApplyMatrix(MoveMatrix(new Vector3(0, isPostive ? this.m_Face.Width - posHeight : posHeight)));
}
}
}
InitDrillTemp(suitableOption: DrillingOption)
{
let key = StoreageKeys.DrillTemp + suitableOption.tempId;
let ens: ExtrudeHole[] = [];
if (appCache.has(key))
{
ens = appCache.get(key);
}
else
{
console.error(key + "没缓存");
return false;
}
if (!ens || ens.length === 0) return false;
this.drillEnts = ens.map(e => e.Clone());
let isPostive = this.IsPostive;
for (let d of this.drillEnts)
{
if (isParallelTo(d.Normal, YAxis))
{
// //偏心轮下偏距离
let pxlOffestDist = -this.m_Option.pxlOffset;
let pos = d.Position;
let box = d.BoundingBox;
if (!this.IsPostive)
pos.add(new Vector3(0, -box.min.y));
else
pos.add(new Vector3(0, this.m_Face.Width - box.max.y));
d.Position = pos.add(new Vector3(0, pxlOffestDist));
}
else
{
let posHeight = safeEval(this.m_Option.ljgPos, { H: this.m_Face.Width });
if (!isNaN(posHeight))
d.ApplyMatrix(MoveMatrix(new Vector3(0, isPostive ? this.m_Face.Width - posHeight : posHeight)));
}
}
return true;
}
//间距等分
private EqulalSpacing()
{
@ -202,12 +287,12 @@ export class DrawDrillingTool extends Singleton
let endDist = this.m_Option.retDist;
let count = this.m_Option.count;
let length = this.m_Face.m_Length;
let length = this.m_Face.Length;
let spacingSize: number;
let caclDist: Function;
//是否从面坐标原点开始算
let isFromOrigin = this.m_Face.IsPositiveFace;
let isFromOrigin = true;
let dir = isFromOrigin ? 1 : -1;//排钻移动方向
@ -215,7 +300,7 @@ export class DrawDrillingTool extends Singleton
if (this.m_Option.isForceDiv)
{
spacingSize = (this.m_Face.m_Length) / (count + 1);
spacingSize = (this.m_Face.Length) / (count + 1);
originDist = spacingSize;
}
else
@ -227,7 +312,7 @@ export class DrawDrillingTool extends Singleton
caclDist = (i) => spacingSize * (i - 1) * dir;
//排钻初始移动距离
this.m_MoveDistList.push(isFromOrigin ? originDist : this.m_Face.m_Length - originDist);
this.m_MoveDistList.push(isFromOrigin ? originDist : this.m_Face.Length - originDist);
//加入从第一个排钻开始的移动距离
for (let i = 2; i <= count; i++)
@ -239,16 +324,16 @@ export class DrawDrillingTool extends Singleton
let startDist = this.m_Option.originDist;
let endDist = this.m_Option.retDist;
let count = this.m_Option.count;
let length = this.m_Face.m_Length;
let length = this.m_Face.Length;
let spacingSize: number;
let caclDist: Function;
//是否从面坐标原点开始算
let isFromOrigin = this.m_Face.IsPositiveFace !== this.m_Option.isFromBack;
let isFromOrigin = !this.m_Option.isFromBack;
let dir = isFromOrigin ? 1 : -1;//排钻移动方向
//排钻初始移动距离
this.m_MoveDistList.push(isFromOrigin ? startDist : this.m_Face.m_Length - startDist);
this.m_MoveDistList.push(isFromOrigin ? startDist : this.m_Face.Length - startDist);
let retDist = length - startDist;
//是否等比例
@ -287,27 +372,23 @@ export class DrawDrillingTool extends Singleton
private BuildDrill()
{
let newDrillentList: ObjectId[][] = [];
for (let i = 0; i < this.m_MoveDistList.length; i++)
let box = new Box3();
this.drillEnts.forEach(e => box.union(e.BoundingBox));
for (let dist of this.m_MoveDistList)
{
let dist = this.m_MoveDistList[i];
if (this.CheckModelingCollision(this.m_Face.m_InterBoard, this.drillEnts[0], dist))
continue;
//检测排钻是否在板件内
if (userConfig.openExactDrill && !this.CheckDrillInBoard(this.m_Face.m_InterBoard, this.drillEnts[0], dist))
if (this.CheckModelingCollision(box, dist))
continue;
let ymjEnt = this.drillEnts.find(e => e.Type === GangDrillType.Ymj);
if (ymjEnt && this.CheckModelingCollision(this.m_Face.m_LocalBoard, ymjEnt, dist))
if (!this.CheckDrillInBoard(dist, box))
continue;
//新的排钻列表
let newDrillEnts: ObjectId[] = [];
for (let d of this.drillEnts)
{
let cloneD = d.Clone();
cloneD.MId = this.m_Face.m_InterBoard.Id;
cloneD.FId = this.m_Face.m_LocalBoard.Id;
cloneD.MId = this.m_Face.InterBoard.Id;
cloneD.FId = this.m_Face.LocalBoard.Id;
cloneD.ApplyMatrix(MoveMatrix(new Vector3(dist)))
.ApplyMatrix(this.m_Face.OCS);
app.Database.ModelSpace.Append(cloneD);
@ -343,8 +424,8 @@ export class DrawDrillingTool extends Singleton
for (let d of this.woodPins)
{
let cloneD = d.Clone();
cloneD.MId = this.m_Face.m_InterBoard.Id;
cloneD.FId = this.m_Face.m_LocalBoard.Id;
cloneD.MId = this.m_Face.InterBoard.Id;
cloneD.FId = this.m_Face.LocalBoard.Id;
cloneD.ApplyMatrix(MoveMatrix(new Vector3(dist)))
.ApplyMatrix(this.m_Face.OCS);
app.Database.ModelSpace.Append(cloneD);
@ -353,39 +434,39 @@ export class DrawDrillingTool extends Singleton
woodPinss.push(newWoodEnts);
}
}
this.ParseDrillList(newDrillentList, woodPinss);
if (newDrillentList.length > 0)
this.ParseDrillList(newDrillentList, woodPinss);
}
//排钻避开造型
private CheckModelingCollision(br: Board, en: GangDrill, dist: number)
private CheckDrillInBoard(dist: number, box: Box3)
{
let mat = br.OCSInv.multiply(this.m_Face.OCS).multiply(MoveMatrix(new Vector3(dist)));
let modelings = br.BoardModeling;
let pos = en.Position.applyMatrix4(mat);
for (let m of modelings)
let br = this.m_Face.InterBoard;
let cu = br.ContourCurve;
if (this.drillEnts[0] instanceof ExtrudeHole)
{
let cu = m.shape.Outline.Curve;
pos.setZ(cu.Position.z);
//排钻在造型内或者和造型碰撞
if (cu.PtInCurve(pos) || cu.IntersectWith(new Circle(pos, en.Radius), 0).length > 0)
{
return m.thickness === br.Thickness || en.Height > br.Thickness - m.thickness;
}
//TODO:先不判断自定义排钻和造型碰撞
return true;
}
else
{
let p = this.drillEnts[0].Position.setX(dist).applyMatrix4(this.m_Face.OCS).applyMatrix4(br.OCSInv).setZ(0);
return IsPointInPolyLine(cu as Polyline, p);
}
return false;
}
private CheckDrillInBoard(br: Board, en: GangDrill, dist: number)
private CheckModelingCollision(box: Box3, dist: number)
{
let cu = br.ContourCurve;
let p = en.Position.setX(dist).applyMatrix4(this.m_Face.OCS).applyMatrix4(br.OCSInv).setZ(0);
return IsPointInPolyLine(cu as Polyline, p);
return [this.m_Face.InterBoard, this.m_Face.LocalBoard].some(b =>
{
let mat = b.OCSInv.multiply(this.m_Face.OCS).multiply(MoveMatrix(new Vector3(dist)));
let bo = box.clone().applyMatrix4(mat) as Box3Ext;
return b.Grooves.some(g => g.BoundingBox.applyMatrix4(b.OCSInv).intersectsBox(bo));
});
}
// 分析当前排钻
private ParseDrillList(drills: ObjectId[][], woodPinss: ObjectId[][])
{
let locaBoard = this.m_Face.m_LocalBoard;
let intBoard = this.m_Face.m_InterBoard;
let locaBoard = this.m_Face.LocalBoard;
let intBoard = this.m_Face.InterBoard;
let refDrillList: ObjectId[][] = [];
//加入本地的板件排钻测试通孔
@ -395,7 +476,7 @@ export class DrawDrillingTool extends Singleton
refDrillList.push(...v.filter(ds => ds.length > 0 && ds[0].Object && !ds[0].IsErase));
}
if (refDrillList.length > 0)
if (refDrillList.length > 0 && drills[0][0].Object instanceof CylinderHole)
{
this.ParseThroughHole(drills, refDrillList, woodPinss);
}
@ -439,16 +520,16 @@ export class DrawDrillingTool extends Singleton
{
let drillent = drills[i];
let isThought = false;
let ymjEnt = (arrayLast(drillent).Object as GangDrill);
let ymjEnt = (arrayLast(drillent).Object as CylinderHole);
let p1 = ymjEnt.Position;
for (let refDrill of refDrillList)
{
if (isThoughtDrillsSet.has(refDrill)) continue;
let refYmjEnt = (arrayLast(refDrill).Object as GangDrill);
let refYmjEnt = (arrayLast(refDrill).Object as CylinderHole);
let p2 = refYmjEnt.Position;
let vec = p2.sub(p1);
if (equaln(vec.length(), this.m_Face.m_LocalBoard.Thickness))
if (equaln(vec.length(), this.m_Face.LocalBoard.Thickness))
{
isThought = true;
isThoughtDrillsSet.add(refDrill);
@ -506,7 +587,7 @@ export class DrawDrillingTool extends Singleton
let boxes: Box3[] = [box];
for (let id of ids)
{
let d = id.Object as GangDrill;
let d = id.Object as CylinderHole;
if (d.Type === GangDrillType.Pxl)
{
boxes.push(d.BoundingBox);
@ -520,7 +601,7 @@ export class DrawDrillingTool extends Singleton
//排钻是不是通孔
const isTK = (ds: ObjectId[]) =>
{
return ds.some(d => (d.Object as GangDrill).Type === GangDrillType.TK);
return ds.some(d => (d.Object as CylinderHole).Type === GangDrillType.TK);
};
for (let i = 0; i < drills.length; i++)
@ -587,20 +668,20 @@ export class DrawDrillingTool extends Singleton
//清理掉已经存在的排钻
this.ClearExitDrilling(brs);
for (let f of checkRes.m_CollisonFaces)
for (let f of checkRes.CollisonFaces)
{
let suitableOption = this.GetRuleByFace(f);
if (!suitableOption)
{
app.Editor.Prompt("长度" + f.m_Length + "没有合适的规则,或者当前配置不存在" + f.drillType + "类型排钻");
app.Editor.Prompt("长度" + f.Length + "没有合适的规则,或者当前配置不存在" + f.DrillType + "类型排钻");
continue;
}
let notGangDist = suitableOption.notGangDist;
//板厚小于设定厚度不排钻,或者排钻数量为0,不允许侧面同侧面
if (f.m_LocalBoard.Thickness < notGangDist
|| f.m_InterBoard.Thickness < notGangDist
|| f.m_Width < notGangDist
|| f.m_Width + 0.5 < f.m_InterBoard.Thickness
if (f.LocalBoard.Thickness < notGangDist
|| f.InterBoard.Thickness < notGangDist
|| f.Width < notGangDist
|| f.Width + 0.5 < f.InterBoard.Thickness
|| suitableOption.count === 0
|| (!suitableOption.canSameType && f.isEqualType)
)
@ -609,20 +690,16 @@ export class DrawDrillingTool extends Singleton
//初始化排钻工具
this.InitTool(f, suitableOption);
//缓存初始化排钻
let isPostive = this.m_Face.m_InterBoard.BoardProcessOption.bigHoleDir === FaceDirection.Front;
let key = f.drillType + "-" + FixedNotZero(f.m_Length, 2) + "-" + FixedNotZero(f.m_Width, 2) + isPostive + f.isEqualType;
if (this._drillEntsCache.has(key))
if (suitableOption.useTemp && suitableOption.tempId)
{
this.drillEnts.push(...this._drillEntsCache.get(key));
let status = this.InitDrillTemp(suitableOption);
if (!status) continue;
}
else
{
//初始化排钻
this.InitDrill();
this._drillEntsCache.set(key, this.drillEnts.slice());
}
let key = this.CacheKey;
if (suitableOption.isDrawWood)
{
if (this._woodPinsCache.has(key))

@ -1,10 +1,10 @@
import { app } from "../../ApplicationServices/Application";
import { GangDrill } from "../../DatabaseServices/3DSolid/GangDrill";
import { Board } from "../../DatabaseServices/Entity/Board";
import { userConfig } from "../../Editor/UserConfig";
import { DrawDrillingTool } from "./DrawDrillingTool";
import { GroupRecord } from "../../DatabaseServices/GroupTableRecord";
import { ObjectId } from "../../DatabaseServices/ObjectId";
import { Hole } from "../../DatabaseServices/3DSolid/Hole";
//禁止触发反应的命令
const ForbidReactorCmd = ['DELETEDRILL', 'PZ', 'ENT', 'ERASE'];
@ -24,7 +24,7 @@ export class DrillingReactor
let holeGroupSet: WeakSet<ObjectId> = new WeakSet();
for (let en of createObjects)
{
if (en instanceof GangDrill)
if (en instanceof Hole)
{
if (!en.GourpId || holeGroupSet.has(en.GourpId))
continue;
@ -50,6 +50,7 @@ export class DrillingReactor
let brs = [...createObjects, ...changeObjects]
.filter(e => !e.IsErase && e instanceof Board) as Board[];
this.StartReactor(brs);
app.Editor.UpdateScreen();
});
}
private GetSurroundBoards(brList: Board[])

@ -0,0 +1,51 @@
import { Board } from "../../DatabaseServices/Entity/Board";
import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Vector3 } from "three";
export function GetHoleCurves(br: Board)
{
let con = br.ContourCurve.Clone() as Polyline;
let cus: Curve[] = [];
if (br.IsSpecialShape)
{
//板构建曲线方向
let dir = Math.sign(br.ContourCurve.Area2);
//让板件轮廓统一逆时针
if (dir < 0)
con.Reverse();
let cs = con.Explode();
while (cs.length > 0)
{
let c = cs.shift();//取第一个
while (true)
{
let deleteCount = 0;
for (let i = 0; i < cs.length; i++)
{
if (!c.Join(cs[i]))
{
deleteCount = cs.splice(0, i).length;
break;
}
}
//如果c和剩余的轮廓都不相交,那么退出
if (deleteCount === 0)
{
cus.push(c);
break;
}
}
}
}
else
{
cus = new Polyline().RectangleFrom2Pt(new Vector3(), new Vector3(br.Width, br.Height)).Explode();
}
return cus;
}

@ -0,0 +1,12 @@
import { Command } from "../../Editor/CommandMachine";
import { app } from "../../ApplicationServices/Application";
import { ModalPosition } from "../../UI/Components/Modal/ModalsManage";
import { DrillingTemplateManage } from "../../UI/Components/Modal/DrillingTemplateManage";
export class ShowDrillingTemplate implements Command
{
async exec()
{
app.Editor.ModalManage.RenderModal(DrillingTemplateManage, ModalPosition.Center, {});
}
}

@ -0,0 +1,131 @@
import { Matrix4, Vector3 } from "three";
import { app } from "../ApplicationServices/Application";
import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole";
import { Circle } from "../DatabaseServices/Entity/Circle";
import { ExtureContourCurve } from "../DatabaseServices/Entity/Extrude";
import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { Command } from "../Editor/CommandMachine";
import { JigUtils } from "../Editor/JigUtils";
import { PromptEntityResult, PromptStatus } from "../Editor/PromptResult";
import { isParallelTo, equalv3 } from "../Geometry/GeUtils";
export class DrawExtrude implements Command
{
async exec()
{
let contour: ExtureContourCurve;
let contourRes: PromptEntityResult;
while (true)
{
contourRes = await app.Editor.GetEntity({
Msg: "选择封闭的轮廓",
Filter: {
filterTypes: [Polyline, Circle],
filterFunction: (obj, en: ExtureContourCurve) => en.IsClose
}
});
if (contourRes.Status === PromptStatus.OK && contourRes.Entity)
{
contour = contourRes.Entity.Clone() as ExtureContourCurve;
break;
}
else if (contourRes.Status === PromptStatus.Cancel)
break;
}
if (!contour) return;
let oldUcs = app.Editor.UCSMatrix;
let en = JigUtils.Draw(new ExtrudeHole());
let appleMat = ExtrudeApplyContour(en, contour);
en.ApplyMatrix(new Matrix4().getInverse(appleMat));
app.Editor.UCSMatrix = contour.OCS.setPosition(new Vector3);
let oldPosition = en.Position;
let basePt: Vector3;
if (contourRes.Entity instanceof Circle)
basePt = contourRes.Entity.Center;
else
basePt = contourRes.Entity.BoundingBox.getCenter(new Vector3);
let distRes = await app.Editor.GetDistance({
Msg: "请输入厚度,或者点取距离",
Default: 1,
BasePoint: basePt,
Callback: (d) =>
{
this.SetHeight(en, d, basePt, oldPosition);
}
});
if (distRes.Status !== PromptStatus.OK)
{
app.Editor.UCSMatrix = oldUcs;
return;
}
this.SetHeight(en, distRes.Distance, basePt, oldPosition);
app.Editor.UCSMatrix = oldUcs;
let radRes = await app.Editor.GetDistance({
Msg: "请输入走刀半径",
Default: 3,
})
if (radRes.Status !== PromptStatus.OK) return;
en.KnifeRadius = radRes.Distance;
app.Database.ModelSpace.Append(en);
contourRes.Entity.Erase();
}
private SetHeight(en: ExtrudeHole, dist: number, basePt: Vector3, oldPosition: Vector3)
{
en.Height = dist;
let nor = en.Normal;
let vNor = app.Viewer.WorldToScreen(nor.clone()).setZ(0);
vNor = vNor.setY(app.Viewer.Height - vNor.y);
let vZero = app.Viewer.WorldToScreen(new Vector3);
vZero = vZero.setY(app.Viewer.Height - vZero.y);
vNor.sub(vZero);
let curPt = app.Editor.MouseCtrl.m_CurMousePointVCS.clone();
curPt = curPt.setY(app.Viewer.Height - curPt.y);
let vBasePt = app.Viewer.WorldToScreen(basePt.clone()).setZ(0);
vBasePt = vBasePt.setY(app.Viewer.Height - vBasePt.y);
let dir = curPt.sub(vBasePt);
if (vNor.angleTo(dir) <= Math.PI / 2)
en.Position = oldPosition;
else
en.Position = oldPosition.clone().add(nor.multiplyScalar(-dist));
}
}
export function ExtrudeApplyContour(ext: ExtrudeHole, contour: ExtureContourCurve): Matrix4 | undefined
{
let applyMatrix: Matrix4;
contour = contour.Clone();
if (equalv3(ext.Normal, contour.Normal))
applyMatrix = ext.OCSInv;
else if (equalv3(
contour.Normal,
new Vector3().setFromMatrixColumn(app.Editor.UCSMatrix, 2)
))
applyMatrix = app.Editor.UCSMatrixInv;
else
applyMatrix = contour.OCSInv;
contour.ApplyMatrix(applyMatrix);
let box = contour.BoundingBox;
contour.Position = contour.Position.sub(box.min);
ext.ContourCurve = contour;
//修正矩阵的基点
applyMatrix.elements[12] -= box.min.x;
applyMatrix.elements[13] -= box.min.y;
applyMatrix.elements[14] -= box.min.z;
return applyMatrix;
}

@ -8,12 +8,16 @@ import { StoreageKeys } from "../../Common/StoreageKeys";
import { ErpParseData } from "./ParseData";
import { ErpRouteInfo } from "./Models/ErpRouteInfo";
import { ErpRoutes } from "./Models/ErpRoutes";
import { Board } from "../../DatabaseServices/Entity/Board";
export class ChaiDan implements Command
{
async exec()
{
let selction = await app.Editor.GetSelection({
UseSelect: true,
Filter: {
filterTypes: [Board]
}
});
if (selction.Status != PromptStatus.OK) return;
let store = BoardStore.GetInstance() as BoardStore;

@ -1,6 +1,6 @@
import { Vector3 } from "three";
import { EBoardKeyList } from "../../Common/BoardKeyList";
import { GangDrillType } from "../../DatabaseServices/3DSolid/GangDrill";
import { GangDrillType } from "../../DatabaseServices/3DSolid/CylinderHole";
import { Board } from "../../DatabaseServices/Entity/Board";
import { Entity } from "../../DatabaseServices/Entity/Entity";
import { ExtrudeSolid } from "../../DatabaseServices/Entity/Extrude";

@ -4,9 +4,10 @@ import { Command } from "../Editor/CommandMachine";
import { PromptStatus } from "../Editor/PromptResult";
import { LookOverBoardInfosModal } from "../UI/Components/Board/LookOverBoardInfos";
import { ModalPosition } from "../UI/Components/Modal/ModalsManage";
import { GangDrill, GangDrillType } from "../DatabaseServices/3DSolid/GangDrill";
import { EBoardKeyList } from "../Common/BoardKeyList";
import { observable } from "mobx";
import { Hole } from "../DatabaseServices/3DSolid/Hole";
import { GangDrillType, CylinderHole } from "../DatabaseServices/3DSolid/CylinderHole";
export interface DrillTypeCount
{
name: string;
@ -14,7 +15,7 @@ export interface DrillTypeCount
}
export class LookOverBoardInfos implements Command
{
@observable private drillTypeMap: Map<string, GangDrill[]> = new Map();
@observable private drillTypeMap: Map<string, Hole[]> = new Map();
async exec()
{
let enRes = await app.Editor.GetSelection({
@ -29,7 +30,7 @@ export class LookOverBoardInfos implements Command
let brsProps = enRes.SelectSet.SelectEntityList as Board[];
//计算排钻个数
const addDrillToMap = (type: string, d: GangDrill) =>
const addDrillToMap = (type: string, d: Hole) =>
{
if (!this.drillTypeMap.has(type))
this.drillTypeMap.set(type, [d]);
@ -53,23 +54,28 @@ export class LookOverBoardInfos implements Command
{
for (let objId of ids)
{
let gd = objId.Object as GangDrill;
let gd = objId.Object;
if (!gd.IsErase)
{
switch (gd.Type)
if (gd instanceof CylinderHole)
switch (gd.Type)
{
case GangDrillType.Ljg:
if (gd.MId && (!gd.MId.IsErase))
{
let br = gd.MId.Object as Board;
let type = br.BoardProcessOption[EBoardKeyList.DrillType];
//todo 需要读取拆单名 从userConfig中读取 如何判断在哪个距离区间
addDrillToMap(type, gd);
}
break;
case GangDrillType.Wood:
addDrillToMap("木销", gd);
break;
}
else
{
case GangDrillType.Ljg:
if (gd.MId && (!gd.MId.IsErase))
{
let br = gd.MId.Object as Board;
let type = br.BoardProcessOption[EBoardKeyList.DrillType];
//todo 需要读取拆单名 从userConfig中读取 如何判断在哪个距离区间
addDrillToMap(type, gd);
}
break;
case GangDrillType.Wood:
addDrillToMap("木销", gd);
break;
//TODO:统计自定义排钻
}
}
}

@ -2,7 +2,6 @@ import { Object3D, Scene, Vector3 } from "three";
import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer";
import { app } from "../ApplicationServices/Application";
import { Sleep } from "../Common/Sleep";
import { GangDrill } from "../DatabaseServices/3DSolid/GangDrill";
import { CADFiler } from "../DatabaseServices/CADFiler";
import { AlignedDimension } from "../DatabaseServices/Dimension/AlignedDimension";
import { Board } from "../DatabaseServices/Entity/Board";
@ -15,6 +14,7 @@ import { RenderType } from "../GraphicsSystem/RenderType";
import { AAType } from "../GraphicsSystem/Viewer";
import { HotCMD } from "../Hot/HotCommand";
import { DisposeThreeObj } from "../Common/Dispose";
import { Hole } from "../DatabaseServices/3DSolid/Hole";
@HotCMD
export class Print implements Command
@ -77,7 +77,7 @@ async function PrintImage(ens: Entity[])
//绘制
for (let e of ens)
{
if (e instanceof GangDrill) continue;
if (e instanceof Hole) continue;
if (e instanceof AlignedDimension)
{
e["OnlyRenderType"] = false;

@ -6,7 +6,7 @@ import { PromptStatus } from "../Editor/PromptResult";
import { Board, BoardType } from "../DatabaseServices/Entity/Board";
import { Matrix4, Math as TMath, Vector3 } from "three";
import { MoveMatrix, isParallelTo, equaln } from "../Geometry/GeUtils";
import { GangDrill } from "../DatabaseServices/3DSolid/GangDrill";
import { CylinderHole } from "../DatabaseServices/3DSolid/CylinderHole";
import { DrawDrillingTool } from "./DrawDrilling/DrawDrillingTool";
import { arrayLast } from "../Common/ArrayExt";
import { AppToaster } from "../UI/Components/Toaster";
@ -133,11 +133,9 @@ export class RotateLayerBoard implements Command
{
this.currentBoard.Width = newWidth;
this.currentBoard.ApplyMatrix(oldBrData.diffMat);
//修正排钻
this.RotateDrillList();
}
/**
*
*
* newTotalWidth-
*/
private RotateNails(angle: number, newTotalWidth: number, oldBrData: IOldBrData)
@ -153,10 +151,10 @@ export class RotateLayerBoard implements Command
this.RotateLeftRightNails(rightNails, singleDist, oldBrData, -angle);
}
/**
*
*
* totalWidth-
* */
private RotateBackNails(backNails: GangDrill[], angle: number, totalWidth: number, oldBrData: IOldBrData)
private RotateBackNails(backNails: CylinderHole[], angle: number, totalWidth: number, oldBrData: IOldBrData)
{
let tanAng = Math.tan(Math.abs(angle));
let sinAng = Math.sin(Math.abs(angle));
@ -186,11 +184,11 @@ export class RotateLayerBoard implements Command
}
}
/**旋转修正左右板的层板钉 */
private RotateLeftRightNails(nails: GangDrill[], singleDist: number, oldBrData: IOldBrData, angle: number)
private RotateLeftRightNails(nails: CylinderHole[], singleDist: number, oldBrData: IOldBrData, angle: number)
{
let pos: Vector3;
let refIndex: number;
let nailMap: Map<string, GangDrill[]> = new Map();
let nailMap: Map<string, CylinderHole[]> = new Map();
let ocsInv = new Matrix4().getInverse(oldBrData.OCS);
for (let i = 0; i < nails.length; i++)
@ -240,7 +238,7 @@ export class RotateLayerBoard implements Command
}
}
/*旧版CAD层板钉排列规则 */
private RotateLeftRightNails2(nails: GangDrill[], oldBrData: IOldBrData, angle: number)
private RotateLeftRightNails2(nails: CylinderHole[], oldBrData: IOldBrData, angle: number)
{
let distMap: Map<string, number> = new Map();
let ocsInv = new Matrix4().getInverse(oldBrData.OCS);
@ -294,15 +292,15 @@ export class RotateLayerBoard implements Command
private ParseNails(oldBrData: IOldBrData)
{
let nails = this.currentBoard.LayerNails;
let backNails: GangDrill[] = [];
let leftNails: GangDrill[] = [];
let rightNails: GangDrill[] = [];
let backNails: CylinderHole[] = [];
let leftNails: CylinderHole[] = [];
let rightNails: CylinderHole[] = [];
let brX = new Vector3().setFromMatrixColumn(oldBrData.OCS, 0);
let brY = new Vector3().setFromMatrixColumn(oldBrData.OCS, 1);
for (let nid of nails)
{
let nail = nid.Object as GangDrill;
let nail = nid.Object as CylinderHole;
if (nail)
{
//层板钉法向量和层板Y轴方向平行,为背板上得层板钉
@ -360,29 +358,4 @@ export class RotateLayerBoard implements Command
frontDist, backDist, count, backNails, leftNails, rightNails
};
}
/**重新计算排钻 */
private RotateDrillList()
{
let drills = this.currentBoard.DrillList;
let needCalcBr: Board[] = [this.currentBoard];
let brY = new Vector3().setFromMatrixColumn(this.currentBoard.OCS, 1);
for (let [brId, ids] of drills)
{
let b = brId.Object as Board;
if (!b || ids.length === 0) continue;
let firstD = ids[0][1].Object as GangDrill;
//当目标板为背板或者立板得排钻连接杆法向量和层板y轴不平行,或者都是层板法向量不平行,直接清理掉排钻
let isClear = b.BoardType === BoardType.Behind ||
(b.BoardType === BoardType.Vertical && !isParallelTo(firstD.Normal, brY)) ||
(b.BoardType === BoardType.Layer && !isParallelTo(b.Normal, this.currentBoard.Normal));
if (isClear)
this.currentBoard.ClearDrillList(brId);
else
needCalcBr.push(b);
}
(DrawDrillingTool.GetInstance() as DrawDrillingTool).StartGangDrill(needCalcBr);
}
}

@ -19,12 +19,13 @@ export class Test implements Command
if (enRes.Status === PromptStatus.OK)
{
let en = enRes.SelectSet.SelectEntityList as Board[];
let en = enRes.SelectSet.SelectEntityList;
for (let e of en)
{
// if (e.IsClockWise) e.ColorIndex = 1;
console.log(Production.GetBoardSplitOrderData(e as Board));
if (e instanceof Board)
console.log(Production.GetBoardSplitOrderData(e));
}
}
}

@ -24,16 +24,16 @@ export class TestCollision implements Command
{
let checkRes = new CollisionDetection(boardCus);
for (let f of checkRes.m_CollisonFaces)
for (let f of checkRes.CollisonFaces)
{
showFace(f);
}
}
else
{
for (let bf of checkRes.m_BoardGeList)
for (let bf of checkRes.BoardGeList)
{
for (let f of bf.m_Faces)
for (let f of bf.Faces)
{
if (f.type !== BoardFaceType.Side)
showFace(f);

@ -16,6 +16,9 @@ class Appcache
return val;
if (val instanceof CADObject)
return val.Clone();
if (Array.isArray(val) && val[0] instanceof CADObject)
return val.slice();
return JSON.parse(JSON.stringify(val));
}
set<T>(key: string, value: T)
@ -26,6 +29,10 @@ class Appcache
{
this._cacheMap.clear();
}
delete(k: string)
{
this._cacheMap.delete(k);
}
}
export const appCache = new Appcache();

@ -13,6 +13,7 @@ export enum DirectoryId
ImgDir = "3", //图片根目录
ToplineDir = "4", //材质根目录
TemplateDir = "5", //材质根目录
DrillingDir = "6", //排钻目录
}
export enum RequestStatus

@ -1,4 +1,4 @@
import { Matrix4, Vector2, Vector3, Box3 } from "three";
import { Matrix4, Vector2, Vector3, Box3, Scene } from "three";
import { app } from "../ApplicationServices/Application";
import { CADFiler } from "../DatabaseServices/CADFiler";
import { Database } from "../DatabaseServices/Database";
@ -9,6 +9,11 @@ import { DuplicateRecordCloning } from "./Status";
import pako from "pako";
import { TemplateRecord } from "../DatabaseServices/Template/TemplateRecord";
import { TemplateParam } from "../DatabaseServices/Template/Param/TemplateParam";
import { Entity } from "../DatabaseServices/Entity/Entity";
import { AAType } from "../GraphicsSystem/Viewer";
import { DisposeThreeObj } from "./Dispose";
import { uploadLogo } from "./Request";
import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole";
export function MaterialOut(material: PhysicalMaterialRecord): string
{
@ -179,3 +184,47 @@ export function GetCurrentViewPreViewImage(restore = true): Blob
}
return dataURItoBlob(url);
}
export function ExtrudeDrillFileIn(data: any[])
{
let f = new CADFiler(data);
let en = new ExtrudeHole();
en.ReadFile(f);
return en;
}
export async function GetEntitysLogo(ens: Entity[])
{
//备份视图
let sceneBak = app.Viewer.Scene;
let aabak = app.Viewer.AAType;
let f = new CADFiler();
app.Viewer.CameraCtrl.WriteFile(f);
//设置视图
app.Viewer.Scene = new Scene();
app.Viewer._AAType = AAType.SMAA;
app.Viewer.CameraCtrl.LookAt(new Vector3(1, 1, -1));
//绘制
for (let e of ens)
app.Viewer.Scene.add(e.DrawObject);
app.Viewer.ZoomAll(false);
let blob = GetCurrentViewPreViewImage(false);
//还原视图
[app.Viewer.Scene, sceneBak] = [sceneBak, app.Viewer.Scene];
app.Viewer._AAType = aabak;
f.Reset();
app.Viewer.CameraCtrl.ReadFile(f);
app.Viewer.OnSize();
DisposeThreeObj(sceneBak);
//上传
let logo = await uploadLogo(blob);
return logo;
}

@ -11,4 +11,6 @@ export enum StoreageKeys
LastOpenFileId = "lastfid",
Uid = "uid",
Goods = "Goods_",
DrillTemp = "drilltemp_",
DrillReactor = "drillRreactor",
}

@ -1,16 +1,13 @@
import { Box3, BufferGeometry, CylinderBufferGeometry, Float32BufferAttribute, LineSegments, Material, Matrix3, Matrix4, Mesh, Object3D, Shape as TShape, Vector3 } from "three";
import { Box3, BufferGeometry, CylinderBufferGeometry, Float32BufferAttribute, LineSegments, Matrix4, Mesh, Object3D, Shape as TShape, Vector3, Matrix3 } from "three";
import { ColorMaterial } from '../../Common/ColorPalette';
import { DisposeThreeObj } from '../../Common/Dispose';
import { FixIndex } from "../../Common/Utils";
import { ObjectSnapMode } from "../../Editor/ObjectSnapMode";
import { RenderType } from "../../GraphicsSystem/RenderType";
import { AutoRecord } from "../AutoRecord";
import { Factory } from '../CADFactory';
import { Factory, CADFactory } from '../CADFactory';
import { CADFiler } from '../CADFiler';
import { Circle } from '../Entity/Circle';
import { ObjectId } from '../ObjectId';
import { Shape } from '../Shape';
import { Solid3D } from "./Solid3D";
import { Hole } from "./Hole";
import { ObjectSnapMode } from "../../Editor/ObjectSnapMode";
import { Circle } from "../Entity/Circle";
export enum GangDrillType
{
@ -26,7 +23,6 @@ export enum GangDrillType
Wood = 4,
/** 通孔 */
TK = 5,
/**木销定位大孔 */
WoodPXL = 6,
}
@ -34,23 +30,20 @@ let TempCircle1 = new Circle();
let TempCircle2 = new Circle();
@Factory
export class GangDrill extends Solid3D
export class CylinderHole extends Hole
{
private _Height: number;
private _Radius: number;
private _Radius: number = 1;
private type: GangDrillType = GangDrillType.Pxl;
@AutoRecord FId: ObjectId;
@AutoRecord MId: ObjectId;
constructor()
{
super();
this._Color = 1;
}
static CreateCylDrill(rad: number, height: number, type: GangDrillType)
static CreateCylHole(radius: number, height: number, type: GangDrillType)
{
let drill = new GangDrill();
drill._Height = height;
drill._Radius = rad;
let drill = new CylinderHole();
drill.Height = height;
drill._Radius = radius;
drill.type = type;
return drill;
}
@ -60,35 +53,37 @@ export class GangDrill extends Solid3D
}
set Type(t: GangDrillType)
{
this.WriteAllObjectRecord();
this.type = t;
}
get Height()
{
return this._Height;
}
set Height(v: number)
{
if (this._Height !== v)
if (this.type !== t)
{
this.WriteAllObjectRecord();
this._EdgeGeometry = null;
this._MeshGeometry = null;
this._Height = v;
this.Update();
this.type = t;
}
}
set Radius(r: number)
{
if (this._Radius !== r)
if (r !== this._Radius)
{
this.WriteAllObjectRecord();
this._EdgeGeometry = null;
this._MeshGeometry = null;
this._EdgeGeometry = null;
this._Radius = r;
this.Update();
}
}
get Height()
{
return super.Height;
}
set Height(v: number)
{
if (this._Height !== v)
{
this._MeshGeometry = null;
this._EdgeGeometry = null;
super.Height = v;
}
}
get Radius()
{
return this._Radius;
@ -98,10 +93,6 @@ export class GangDrill extends Solid3D
let box = new Box3(new Vector3(-this._Radius, -this._Radius, 0), new Vector3(this._Radius, this._Radius, this._Height));
return box.applyMatrix4(this.OCS);
}
Collise(tarDrill: GangDrill): boolean
{
return this.BoundingBox.intersectsBox(tarDrill.BoundingBox);
}
private _MeshGeometry: CylinderBufferGeometry;
private get MeshGeometry()
{
@ -120,7 +111,13 @@ export class GangDrill extends Solid3D
this._EdgeGeometry = FastDrillingEdgeGeometry(this._Radius, this.Height);
return this._EdgeGeometry;
}
GetGripPoints()
{
let cir = new Circle(new Vector3(), this._Radius);
let pts = cir.GetGripPoints();
pts.push(...pts.map(p => p.clone().add(new Vector3(0, 0, this.Height))));
return pts.map(p => p.applyMatrix4(this.OCS));
}
GetObjectSnapPoints(
snapMode: ObjectSnapMode,
pickPoint: Vector3,
@ -141,7 +138,6 @@ export class GangDrill extends Solid3D
}
return pts;
}
InitDrawObject(renderType: RenderType)
{
return this.GetObject3DByRenderType(renderType);
@ -158,43 +154,31 @@ export class GangDrill extends Solid3D
DisposeThreeObj(obj);
obj.add(this.GetObject3DByRenderType(type));
}
UpdateDrawObjectMaterial(type: RenderType, obj: Object3D, material?: Material)
{
let m = obj as LineSegments;
m.material = material || ColorMaterial.GetLineMaterial(this.ColorIndex);
}
protected _ReadFile(file: CADFiler)
{
super._ReadFile(file);
let ver = file.Read();//1
if (ver <= 3)
this._Radius = file.Read();
if (ver <= 4)
{
let shape = new Shape();
shape.ReadFile(file);
this._Radius = (<Circle>(shape.Outline.Curve)).Radius;
}
else
this._Radius = file.Read();
this._Height = file.Read();
this.type = GangDrillType.Pxl;
if (ver >= 2)
//临时兼容旧排钻
this._Height = file.Read();
this.type = file.Read();
if (ver >= 3)
{
this.FId = file.ReadSoftObjectId();
this.MId = file.ReadSoftObjectId();
}
else
{
this.type = file.Read();
}
}
WriteFile(file: CADFiler)
{
super.WriteFile(file);
file.Write(4);//ver
file.Write(5);//ver
file.Write(this._Radius);
file.Write(this._Height);
file.Write(this.type);
file.WriteSoftObjectId(this.FId);
file.WriteSoftObjectId(this.MId);
}
}
@ -235,7 +219,9 @@ export function FastDrillingEdgeGeometry(radius: number, height: number): Buffer
coords.push(p.x, p.y, 0, p.x, p.y, height);//edge
}
geo.setAttribute('position', new Float32BufferAttribute(coords, 3));
geo.addAttribute('position', new Float32BufferAttribute(coords, 3));
cache2.set(key, geo);
return geo;
}
CADFactory.RegisterObjectAlias(CylinderHole, "GangDrill");

@ -2,13 +2,13 @@ import * as THREE from 'three';
import { MeshNormalMaterial, Object3D, Geometry, Vector3, ExtrudeGeometry } from "three";
import { RenderType } from "../../GraphicsSystem/RenderType";
import { CADFiler } from '../CADFiler';
import { Solid3D } from "./Solid3D";
import { Factory } from '../CADFactory';
import { Contour } from '../Contour';
import { Circle } from '../Entity/Circle';
import { Entity } from '../Entity/Entity';
@Factory
export class Cylineder extends Solid3D
export class Cylineder extends Entity
{
private m_Radius: number;
private m_Height: number;

@ -0,0 +1,354 @@
import { BufferGeometry, ExtrudeGeometry, ExtrudeGeometryOptions, Geometry, LineSegments, Matrix3, Matrix4, Mesh, Object3D, Vector3 } from "three";
import { arrayClone, arrayLast, arraySortByNumber } from "../../Common/ArrayExt";
import { ColorMaterial } from "../../Common/ColorPalette";
import { DisposeThreeObj } from "../../Common/Dispose";
import { Vector2ApplyMatrix4 } from "../../Common/Matrix4Utils";
import { ObjectSnapMode } from "../../Editor/ObjectSnapMode";
import { FastWireframe2 } from "../../Geometry/CreateWireframe";
import { EdgesGeometry } from "../../Geometry/EdgeGeometry";
import { equaln, equalv2, equalv3, ZeroVec } from "../../Geometry/GeUtils";
import { RenderType } from "../../GraphicsSystem/RenderType";
import { Factory } from "../CADFactory";
import { CADFiler } from "../CADFiler";
import { Contour } from "../Contour";
import { DragPointType } from "../Entity/DragPointType";
import { ExtureContourCurve } from "../Entity/Extrude";
import { Polyline } from "../Entity/Polyline";
import { Shape } from "../Shape";
import { Hole } from "./Hole";
@Factory
export class ExtrudeHole extends Hole
{
private _contourCurve: ExtureContourCurve = new Polyline();
private _EdgeGeometry: EdgesGeometry;
protected _knifeRadius: number = 3;
get KnifeRadius()
{
return this._knifeRadius;
}
set KnifeRadius(v: number)
{
if (!equaln(v, this._knifeRadius))
{
this.WriteAllObjectRecord();
this._knifeRadius = v;
}
}
get ContourCurve()
{
return this._contourCurve;
}
set ContourCurve(curve: ExtureContourCurve)
{
if (!curve.IsClose) return;
if (curve instanceof Polyline)
{
curve.CloseMark = true;
let pts = curve.LineData;
if (equalv2(pts[0].pt, arrayLast(pts).pt))
pts.pop();
//如果曲线被旋转了,那么修正它的旋转矩阵,避免纹路错误
let ocs = curve.OCS;
if (!equaln(ocs.elements[0], 1))// || ocs.elements[9] || ocs.elements[10]
{
for (let p of pts)
Vector2ApplyMatrix4(ocs, p.pt);
curve.OCS = new Matrix4();
}
curve.ClearDraw();
}
this.WriteAllObjectRecord();
this._contourCurve = curve;
this.CheckContourCurve();
this.Update();
}
CheckContourCurve()
{
let box = this._contourCurve.BoundingBox;
//修正轮廓基点
if (!equalv3(box.min, ZeroVec))
{
this._contourCurve.Position =
this._contourCurve.Position.sub(box.min);
let v = box.min.applyMatrix4(this.OCS.setPosition(ZeroVec));
this._Matrix.setPosition(this.Position.add(v));
}
}
GetObjectSnapPoints(
snapMode: ObjectSnapMode,
pickPoint: Vector3,
lastPoint: Vector3,
viewXform?: Matrix3
): Vector3[]
{
switch (snapMode)
{
case ObjectSnapMode.End:
return this.GetStretchPoints();
case ObjectSnapMode.Mid:
case ObjectSnapMode.Cen:
case ObjectSnapMode.Nea:
case ObjectSnapMode.Ext:
case ObjectSnapMode.Per:
case ObjectSnapMode.Tan:
{
let contour = this.ContourCurve.Clone();
contour.ApplyMatrix(this.OCS);
let pts = contour.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform);
contour.Position = contour.Position.add(this.Normal.multiplyScalar(this.Height));
pts.push(
...contour.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform)
);
return pts;
}
default:
break;
}
return [];
}
get Shape()
{
let contour = Contour.CreateContour(this.ContourCurve.Clone(), false);
return new Shape(contour);
}
get BoundingBoxInOCS()
{
let box = this.ContourCurve.BoundingBox;
box.max.add(new Vector3(0, 0, this.Height));
return box;
}
get BoundingBox()
{
let box = this.ContourCurve.BoundingBox;
box.max.add(new Vector3(0, 0, this.Height));
box.applyMatrix4(this.OCS);
return box;
}
private get EdgeGeometry()
{
if (this._EdgeGeometry)
return this._EdgeGeometry;
this._EdgeGeometry = new EdgesGeometry().FromGeometry(this.MeshGeometry);
return this._EdgeGeometry;
}
private _MeshGeometry: BufferGeometry | Geometry;
private get MeshGeometry()
{
if (this._MeshGeometry)
return this._MeshGeometry;
this._MeshGeometry = this.GeneralMeshGeometry();
return this._MeshGeometry;
}
private GeneralMeshGeometry()
{
let extrudeSettings: ExtrudeGeometryOptions = {
steps: 1,
bevelEnabled: false,
depth: this.Height,
};
let geo = new ExtrudeGeometry(this.ContourCurve.Shape, extrudeSettings);
geo.applyMatrix(this._contourCurve.OCS);
return geo;
}
GetGripOrStretchPoints(dragType: DragPointType)
{
let isGrip = dragType === DragPointType.Grip;
let pts = isGrip ? this.ContourCurve.GetGripPoints() : this.ContourCurve.GetStretchPoints();
let v = new Vector3(0, 0, this.Height);
pts.push(...pts.map(p => p.clone().add(v)));
pts.forEach(p => { p.applyMatrix4(this.OCS) });
return pts;
}
private GetStrectchPointCountList(dragType: DragPointType): number
{
return this.ContourCurve.GetDragPointCount(dragType) * 2;
}
MoveGripOrStretchPoints(indexList: number[], vec: Vector3, dragType: DragPointType)
{
this.WriteAllObjectRecord();
if (dragType === DragPointType.Stretch && indexList.length === this.GetStrectchPointCountList(dragType))
{
this.Position = this.Position.add(vec);
return;
}
arraySortByNumber(indexList);
this.MoveGripOrStretchPointsOnly(indexList, vec, dragType);
this.CheckContourCurve();
this.Update();
}
IsStretchHeight(indexs: number[])
{
let count = this.ContourCurve.GetStretchPoints().length;
if (indexs.length === count)
{
let isF = indexs[0] < count;
return indexs.every(i => isF === (i < count));
}
return false;
}
MoveGripOrStretchPointsOnly(indexList: Array<number>, vec: Vector3, dragType: DragPointType)
{
let stretchCount = this.ContourCurve.GetDragPointCount(dragType);
if (dragType === DragPointType.Stretch)
{
//Move
if (indexList.length === stretchCount * 2)
{
this.Position = this.Position.add(vec);
return;
}
//判断是否拉伸厚度
if (this.IsStretchHeight(indexList))
{
let isFront = indexList[0] < stretchCount;
if (indexList.every(v => v < stretchCount === isFront))
{
//Change thickness
let lvec = vec.clone().applyMatrix4(this.OCSInv.setPosition(ZeroVec));
if (isFront)
{
this.Height -= lvec.z;
//移动位置而不改变内部拉槽
let v = this.Normal.multiplyScalar(lvec.z);
this._Matrix.elements[12] += v.x;
this._Matrix.elements[13] += v.y;
this._Matrix.elements[14] += v.z;
}
else
{
this.Height += lvec.z;
}
return;
}
}
indexList = arrayClone(indexList);
}
//修正点的索引
for (let i = 0; i < indexList.length; i++)
{
let index = indexList[i];
if (index >= stretchCount)
{
index -= stretchCount;
indexList[i] = index;
}
}
indexList = [...new Set(indexList)];
let localVec = vec.clone().applyMatrix4(this.OCSInv.setPosition(ZeroVec));
if (dragType === DragPointType.Grip)
{
if (this.ContourCurve instanceof Polyline
&& indexList.length === 1
&& indexList[0] % 2 === 1)
{
let param = indexList[0] / 2;
if (this.ContourCurve.GetBuilgeAt(Math.floor(param)) === 0)
{
let der = this.ContourCurve.GetFistDeriv(param).normalize();
[der.x, der.y] = [der.y, -der.x];
let d = localVec.dot(der);
localVec.copy(der).multiplyScalar(d);
}
}
this.ContourCurve.MoveGripPoints(indexList, localVec);
}
else
this.ContourCurve.MoveStretchPoints(indexList, localVec);
}
GetGripPoints(): Array<Vector3>
{
return this.GetGripOrStretchPoints(DragPointType.Grip);
}
GetStretchPoints()
{
return this.GetGripOrStretchPoints(DragPointType.Stretch);
}
MoveGripPoints(indexList: number[], vec: Vector3)
{
this.MoveGripOrStretchPoints(indexList, vec, DragPointType.Grip)
}
MoveStretchPoints(indexList: Array<number>, vec: Vector3)
{
this.MoveGripOrStretchPoints(indexList, vec, DragPointType.Stretch);
}
InitDrawObject(renderType: RenderType = RenderType.Wireframe)
{
if (renderType === RenderType.Wireframe)
{
return new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(this.ColorIndex))
}
else if (renderType === RenderType.Conceptual || renderType === RenderType.Physical)
{
return new Object3D().add(
new Mesh(this.MeshGeometry, ColorMaterial.GetConceptualMaterial(this.ColorIndex)),
new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(7))
);
}
else if (renderType === RenderType.Jig)
{
return new Object3D().add(...FastWireframe2(this));
}
}
UpdateDrawObject(renderType: RenderType, obj: Object3D)
{
DisposeThreeObj(obj);
this._EdgeGeometry = undefined;
this._MeshGeometry = undefined;
this.MeshGeometry;
if (renderType === RenderType.Wireframe)
{
let l = obj as LineSegments;
l.geometry = this.EdgeGeometry;
l.material = ColorMaterial.GetLineMaterial(this.ColorIndex);
}
else if (renderType === RenderType.Conceptual || renderType === RenderType.Physical)
{
return obj.add(
new Mesh(this.MeshGeometry, ColorMaterial.GetConceptualMaterial(this.ColorIndex)),
new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(7))
);
}
else if (renderType === RenderType.Jig)
{
obj.add(...FastWireframe2(this));
}
}
ReadFile(file: CADFiler)
{
super.ReadFile(file);
let ver = file.Read();
this._contourCurve = file.ReadObject() as ExtureContourCurve;
this._knifeRadius = file.Read();
this.Update();
}
//对象将自身数据写入到文件.
WriteFile(file: CADFiler)
{
super.WriteFile(file);
file.Write(1);
file.WriteObject(this._contourCurve);
file.Write(this._knifeRadius);
}
}

@ -0,0 +1,51 @@
import { Factory } from '../CADFactory';
import { Entity } from '../Entity/Entity';
import { AutoRecord } from '../AutoRecord';
import { ObjectId } from '../ObjectId';
import { CADFiler } from '../CADFiler';
@Factory
export class Hole extends Entity
{
@AutoRecord FId: ObjectId;
@AutoRecord MId: ObjectId;
protected _Height: number;
get Height()
{
return this._Height;
}
set Height(v: number)
{
if (this._Height !== v)
{
this.WriteAllObjectRecord();
this._Height = v;
this.Update();
}
}
protected _ReadFile(file: CADFiler)
{
super._ReadFile(file);
let ver = file.Read();//1
if (ver <= 4)
{
//临时兼容旧图纸排钻,更新旧图纸后去掉兼容代码
file['readIndex']--;
}
else
{
this._Height = file.Read();
this.FId = file.ReadSoftObjectId();
this.MId = file.ReadSoftObjectId();
}
}
WriteFile(file: CADFiler)
{
super.WriteFile(file);
file.Write(5);//ver
file.Write(this._Height);
file.WriteSoftObjectId(this.FId);
file.WriteSoftObjectId(this.MId);
}
}

@ -1,7 +0,0 @@
import { Factory } from '../CADFactory';
import { Entity } from '../Entity/Entity';
@Factory
export class Solid3D extends Entity
{
}

@ -11,10 +11,10 @@ import { Curve } from "../Entity/Curve";
import { PhysicalMaterialRecord } from '../PhysicalMaterialRecord';
import { IsPointInPolyLine } from '../PointInPolyline';
import { Polyline } from '../Entity/Polyline';
import { Solid3D } from "./Solid3D";
import { Entity } from "../Entity/Entity";
@Factory
export class SweepSolid extends Solid3D
export class SweepSolid extends Entity
{
private _Contour: Polyline;
private _PathCurve: Curve;

@ -479,23 +479,12 @@ export class Board extends ExtrudeSolid
this.WriteAllObjectRecord();
this._SpecOCS.copy(m);
}
get BoundingBox()
{
let box = new Box3Ext(new Vector3(0, 0, 0), new Vector3(this.width, this.height, this.thickness));
box.applyMatrix4(this.OCS);
return box;
}
// get Shape()
// {
// return this.ContourCurve;
// }
// set Shape(s: Shape)
// {
// this.WriteAllObjectRecord();
// // this.m_Shape = s;
// this.UpdateBoardSize();
// this.Update();
// }
get IsRect()
{
return this.isRect;
}
get IsSpecialShape()
{
return !this.isRect;

@ -94,7 +94,10 @@ export class ExtrudeSolid extends Entity
this.knifeRadius = v;
}
}
get BoundingBox()
{
return this.BoundingBoxInOCS.applyMatrix4(this.OCS);
}
get BoundingBoxInOCS(): Box3Ext
{
return new Box3Ext(new Vector3(), new Vector3(this.width, this.height, this.thickness));

@ -51,7 +51,17 @@ export class Shape
this.UpdateShape();
return this.m_Shape;
}
get Position()
{
return this.m_Outline.Curve.Position;
}
set Position(p: Vector3)
{
let vec = p.clone().sub(this.m_Outline.Curve.Position);
this.m_Outline.Curve.Position = p;
for (let h of this.m_Holes)
h.Curve.Position = h.Curve.Position.add(vec);
}
Z0()
{
this.m_Outline.Curve.Z0();

@ -142,6 +142,8 @@ import { commandMachine } from './CommandMachine';
import { EditorLattice } from "../Add-on/LatticeDrawer/EditorLattice";
import { Print } from "../Add-on/Print";
import { AutoHoleFaceSetting } from "../Add-on/AutoHoleFaceSetting";
import { DrawExtrude } from "../Add-on/DrawExtrude";
import { ShowDrillingTemplate } from "../Add-on/DrawDrilling/ShowDrillingTemplate";
export function registerCommand()
{
@ -384,6 +386,9 @@ export function registerCommand()
commandMachine.RegisterCommand("testPl2Pts", new Command_Polyline2Path());
commandMachine.RegisterCommand("editorlattice", new EditorLattice());
commandMachine.RegisterCommand("print", new Print());
commandMachine.RegisterCommand("extrude", new DrawExtrude());
commandMachine.RegisterCommand("drilltemplate", new ShowDrillingTemplate());
RegistCustomCommand();
}

@ -32,6 +32,8 @@ export class UserConfig
let type = localStorage.getItem(StoreageKeys.RenderType);
if (type)
this._renderType = parseFloat(type);
this.openDrillingReactor = !!localStorage.getItem(StoreageKeys.DrillReactor);
}
set RenderType(t: RenderType)
{

@ -8,6 +8,7 @@ import { ExtrudeSolid } from "../DatabaseServices/Entity/Extrude";
import { Shape } from "../DatabaseServices/Shape";
import { FaceDirection } from "../UI/Store/BoardInterface";
import { MoveMatrix } from "./GeUtils";
import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole";
//FIXME: #IWBPB 性能缺陷和BUG. 等待废弃或者改进
export function CreateWireframe(en3D: Board | ExtrudeSolid)
@ -141,3 +142,40 @@ export function FastWireframe(br: ExtrudeSolid, color = 0)
return result;
}
export function FastWireframe2(dr: ExtrudeHole, color = 0)
{
color = color || dr.ColorIndex;
let material = ColorMaterial.GetLineMaterial(color);
let height = dr.Height;
let cu = dr.ContourCurve;
let pts = cu.Shape.getPoints(6);
let geo = new BufferGeometry();
let coords: number[] = [];
let edgeCoords: number[] = [];
for (let p of pts)
{
coords.push(p.x, p.y, 0);
if (p["_mask_"])
edgeCoords.push(p.x, p.y, 0, p.x, p.y, height);
}
for (let p of pts)
coords.push(p.x, p.y, height);
let edgeGeo = new BufferGeometry();
edgeGeo.addAttribute('position', new Float32BufferAttribute(edgeCoords, 3));
geo.addAttribute('position', new Float32BufferAttribute(coords, 3));
let line = new Line(geo, material);
line.applyMatrix(cu.OCS);
let edge = new LineSegments(edgeGeo, material)
edge.applyMatrix(cu.OCS);
let result = [line, edge];
return result;
}

@ -5,7 +5,7 @@ import { Board } from "../../DatabaseServices/Entity/Board";
import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Region } from "../../DatabaseServices/Entity/Region";
import { DrillType } from "../../UI/Store/BoardInterface";
import { equaln, equalv3, rotatePoint, ZAxis } from "../GeUtils";
import { equaln, equalv3, ZAxis } from "../GeUtils";
import { Face } from "./Face";
export enum BoardFaceType
@ -15,11 +15,9 @@ export enum BoardFaceType
}
export class BoardGetFace
{
m_Board: Board;
m_Faces: Face[] = [];
constructor(br: Board)
Faces: Face[] = [];
constructor(public Board: Board)
{
this.m_Board = br;
this.ParseFaces();
}
ParseFaces()
@ -31,56 +29,51 @@ export class BoardGetFace
}
GetTopAndBottomFace()
{
let curve = this.m_Board.ContourCurve;
let box = curve.BoundingBox;
let size = box.getSize(new Vector3());
let curve = this.Board.ContourCurve;
let reg: Region;
let isRect = !this.m_Board.IsSpecialShape;
if (!isRect)
if (this.Board.IsSpecialShape)
reg = Region.CreateFromCurves([curve]);
let thickness = this.m_Board.Thickness;
let ocs = this.m_Board.OCS;
const opt = this.m_Board.BoardProcessOption;
let thickness = this.Board.Thickness;
let ocs = this.Board.OCS;
const opt = this.Board.BoardProcessOption;
//正反面
if (opt.frontDrill)
this.m_Faces.push(new Face({
this.Faces.push(new Face({
type: BoardFaceType.NoSide,
region: reg,
isRect,
localBoard: this.m_Board,
isRect: this.Board.IsRect,
localBoard: this.Board,
isPositiveFace: true,
matrix4: ocs.clone().multiply(
new Matrix4().setPosition(new Vector3(0, 0, thickness))),
length: size.x,
width: size.y
length: this.Board.Width,
width: this.Board.Height
}));
if (opt.backDrill)
{
let mat = GetMirrorMat(ZAxis).setPosition(new Vector3());
this.m_Faces.push(new Face({
this.Faces.push(new Face({
type: BoardFaceType.NoSide,
localBoard: this.m_Board,
isRect,
localBoard: this.Board,
isRect: this.Board.IsRect,
region: reg ? reg.Clone() : undefined,
isPositiveFace: false,
matrix4: new Matrix4().multiplyMatrices(ocs.clone(), mat),
length: size.x,
width: size.y
length: this.Board.Width,
width: this.Board.Height
}));
}
}
GetSideFaces()
{
let con = this.m_Board.ContourCurve.Clone();
let con = this.Board.ContourCurve.Clone();
let inverseZ = con.Area2 < 0;
let cus = con.Explode() as Curve[];
const highDrill = this.m_Board.BoardProcessOption.highDrill.slice();
const highDrill = this.Board.BoardProcessOption.highDrill.slice();
//TODO: #I10I6J 矩形板起始边不是0点时,为解决当矩形板不止4边
if (!this.m_Board.IsSpecialShape && cus.length === 4)
if (!this.Board.IsSpecialShape && cus.length === 4)
{
let index = Math.round(con.GetParamAtPoint(new Vector3()));
highDrill.unshift(...highDrill.splice(highDrill.length - index));
@ -89,19 +82,19 @@ export class BoardGetFace
for (let i = 0; i < cus.length; i++)
{
let cu = cus[i];
let length = cu.Length;
if ((highDrill.length > 0 && highDrill[i] === DrillType.None)
|| equaln(cu.Length, 0)
|| equaln(length, 0)
|| cu instanceof Arc)
continue;
let len = cu.Length;
let mtx = GetSideFaceMtx(cu, inverseZ);
this.m_Faces.push(new Face({
this.Faces.push(new Face({
type: BoardFaceType.Side,
localBoard: this.m_Board,
localBoard: this.Board,
isPositiveFace: true,
matrix4: new Matrix4().multiplyMatrices(this.m_Board.OCS.clone(), mtx),
length: len,
width: this.m_Board.Thickness,
matrix4: new Matrix4().multiplyMatrices(this.Board.OCS.clone(), mtx),
length,
width: this.Board.Thickness,
drillType: highDrill.length > 0 && highDrill[i]
}));
}
@ -110,13 +103,13 @@ export class BoardGetFace
{
let collisionFaces: Face[] = [];
for (let f1 of this.m_Faces)
for (let f1 of this.Faces)
{
for (let f2 of br.m_Faces)
for (let f2 of br.Faces)
{
//都是正面,或者不允许侧面同侧面并且2板件类型不一样就跳过
if (f1.type === f2.type
&& (f1.type === BoardFaceType.NoSide || !bInsEqual || br.m_Board.BoardType !== this.m_Board.BoardType)
&& (f1.type === BoardFaceType.NoSide || !bInsEqual || br.Board.BoardType !== this.Board.BoardType)
)
continue;
//不共面

@ -6,42 +6,40 @@ import { Box3Ext } from "../Box";
export class CollisionDetection
{
private m_Boards: Board[];
m_BoardGeList: BoardGetFace[] = [];
m_CollisonFaces: Face[] = [];
constructor(brs: Board[])
BoardGeList: BoardGetFace[] = [];
CollisonFaces: Face[] = [];
constructor(private _Boards: Board[] = [])
{
this.m_Boards = brs || [];
this.Check();
}
Check()
{
let boxCache: Map<Board, Box3Ext> = new Map();
let ocsInv = this.m_Boards[0].OCSInv;
let ocsInv = this._Boards[0].OCSInv;
for (let b of this.m_Boards)
for (let b of this._Boards)
{
if (b.BoardProcessOption.drillType !== DrillType.None)
{
this.m_BoardGeList.push(new BoardGetFace(b));
this.BoardGeList.push(new BoardGetFace(b));
boxCache.set(b, b.GetBoardBoxInMtx(ocsInv));
}
}
for (let i = 0; i < this.m_BoardGeList.length; i++)
for (let i = 0; i < this.BoardGeList.length; i++)
{
let f = this.m_BoardGeList[i];
let localBox = boxCache.get(f.m_Board);
let f = this.BoardGeList[i];
let localBox = boxCache.get(f.Board);
for (let j = i + 1; j < this.m_BoardGeList.length; j++)
for (let j = i + 1; j < this.BoardGeList.length; j++)
{
let f1 = this.m_BoardGeList[j];
let f1 = this.BoardGeList[j];
let interBox = boxCache.get(f1.m_Board);
let interBox = boxCache.get(f1.Board);
//板件包围盒相交
if (localBox.intersectsBox(interBox, 1e-2))
this.m_CollisonFaces.push(...f.IntersectFace(f1, true));
this.CollisonFaces.push(...f.IntersectFace(f1, true));
}
}
}

@ -1,12 +1,12 @@
import { Matrix4, Vector3 } from "three";
import { MatrixPlanarizere } from "../../Common/Matrix4Utils";
import { Board } from "../../DatabaseServices/Entity/Board";
import { Line } from "../../DatabaseServices/Entity/Line";
import { Region } from "../../DatabaseServices/Entity/Region";
import { BoolOpeartionType } from "../../GraphicsSystem/BoolOperateUtils";
import { Box3Ext } from "../Box";
import { equaln, XAxis } from "../GeUtils";
import { BoardFaceType } from "./BoardGetFace";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
export interface BoardFaceParams
{
@ -23,68 +23,52 @@ export interface BoardFaceParams
export class Face
{
type: BoardFaceType;
m_Length: number;
m_Width: number;
m_Region: Region;
m_LocalBoard: Board;
m_InterBoard: Board; //提供侧面的作为相交面
Length: number;
Width: number;
private _Region: Region;
LocalBoard: Board;
InterBoard: Board; //提供侧面的作为相交面
IsPositiveFace: boolean;
isEqualType: boolean = false;
OCS: Matrix4 = new Matrix4();
m_IsRect: boolean = true;
drillType: string;
IsRect: boolean = true;
DrillType: string;
constructor(parameters?: BoardFaceParams)
{
if (parameters)
{
this.type = parameters.type;
this.m_Region = parameters.region;
this.m_LocalBoard = parameters.localBoard;
this._Region = parameters.region;
this.LocalBoard = parameters.localBoard;
this.IsPositiveFace = parameters.isPositiveFace;
parameters.matrix4 && this.OCS.copy(parameters.matrix4);
this.m_Length = parameters.length;
this.m_Width = parameters.width;
this.OCS = parameters.matrix4;
this.Length = parameters.length;
this.Width = parameters.width;
if (parameters.isRect !== undefined)
this.m_IsRect = parameters.isRect;
this.IsRect = parameters.isRect;
if (parameters.drillType)
this.drillType = parameters.drillType;
this.DrillType = parameters.drillType;
else
this.drillType = this.m_LocalBoard.BoardProcessOption.drillType;
this.DrillType = this.LocalBoard.BoardProcessOption.drillType;
}
}
get IsRect()
{
return this.m_IsRect;
}
get Region()
{
if (!this.m_Region)
this.m_Region = this.BuildRegion();
return this.m_Region;
if (!this._Region)
this._Region = Region.CreateFromCurves([new Polyline().Rectangle(this.Length, this.Width)]);
return this._Region;
}
get OCSInv()
{
return new Matrix4().getInverse(this.OCS);
}
private BuildRegion()
{
let p1 = new Vector3();
let p2 = new Vector3(this.m_Length, 0);
let p3 = new Vector3(this.m_Length, this.m_Width);
let p4 = new Vector3(0, this.m_Width);
let l1 = new Line(p1, p2);
let l2 = new Line(p2, p3);
let l3 = new Line(p3, p4);
let l4 = new Line(p4, p1);
return Region.CreateFromCurves([l1, l2, l3, l4]);
}
Intersect(f: Face): Face[]
{
//获得侧面和非侧面
let [sideFace, noSideFace] = this.type === BoardFaceType.Side ? [this, f] : [f, this];
//布尔面和被布尔面得差异矩阵
let diffMtx = new Matrix4().getInverse(sideFace.OCS).multiply(noSideFace.OCS);
let diffMtx = sideFace.OCSInv.multiply(noSideFace.OCS);
MatrixPlanarizere(diffMtx);
let isSuccess = false;
@ -112,10 +96,10 @@ export class Face
}
else
{
let retBox = new Box3Ext(new Vector3(), new Vector3(sideFace.m_Length, sideFace.m_Width));
let retBox = new Box3Ext(new Vector3(), new Vector3(sideFace.Length, sideFace.Width));
let p1 = new Vector3().setFromMatrixPosition(diffMtx);
let p2 = new Vector3(noSideFace.m_Length, noSideFace.m_Width).applyMatrix4(diffMtx);
let p2 = new Vector3(noSideFace.Length, noSideFace.Width).applyMatrix4(diffMtx);
let box3 = new Box3Ext().setFromPoints([p1, p2]);
if (retBox.intersectsBox(box3))
@ -136,11 +120,11 @@ export class Face
{
let newFace = new Face();
//提供侧面的板件作为相交面
newFace.m_LocalBoard = noSideFace.m_LocalBoard;
newFace.m_InterBoard = sideFace.m_LocalBoard;
newFace.LocalBoard = noSideFace.LocalBoard;
newFace.InterBoard = sideFace.LocalBoard;
newFace.m_Length = sizes[i].x;
newFace.m_Width = sizes[i].y;
newFace.Length = sizes[i].x;
newFace.Width = sizes[i].y;
let min = retBoxs[i].min;
min.applyMatrix4(sideFace.OCS);
@ -149,7 +133,7 @@ export class Face
newFace.OCS = sideFace.OCS.clone().setPosition(min);
newFace.IsPositiveFace = sideFace.IsPositiveFace;
newFace.drillType = sideFace.drillType;
newFace.DrillType = sideFace.DrillType;
//都是侧面
if (this.type === f.type)
newFace.isEqualType = true;

@ -1,16 +1,21 @@
import { Vector3 } from "three";
import { IsRect, equalCurve } from "../../Common/CurveUtils";
import { Matrix4, Vector3 } from "three";
import { equalCurve, IsRect } from "../../Common/CurveUtils";
import { Singleton } from "../../Common/Singleton";
import { Contour } from "../../DatabaseServices/Contour";
import { Board, IModeling } from "../../DatabaseServices/Entity/Board";
import { Circle } from "../../DatabaseServices/Entity/Circle";
import { Curve } from "../../DatabaseServices/Entity/Curve";
import { Line } from "../../DatabaseServices/Entity/Line";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Shape } from "../../DatabaseServices/Shape";
import { ShapeManager } from "../../DatabaseServices/ShapeManager";
import { GetSideFaceMtx } from "../../Geometry/DrillParse/BoardGetFace";
import { isParallelTo, angleTo, XAxis, MoveMatrix } from "../../Geometry/GeUtils";
import { RegionParse, Route } from "../../Geometry/RegionParse";
import { FaceDirection } from "../../UI/Store/BoardInterface";
import { BoolOpeartionType, isTargetCurInOrOnSourceCur } from "../BoolOperateUtils";
import { GetCurveToInDir, OptimizeToolPath, GetOffsetCurves } from "./OptimizeToolPath";
import { OptimizeToolPath, GetCurveToInDir, GetOffsetCurves } from "./OptimizeToolPath";
import { ExtrudeHole } from "../../DatabaseServices/3DSolid/ExtrudeHole";
/**
*
@ -155,13 +160,38 @@ export class FeedingToolPath extends Singleton
/**用于测试走刀路径 */
TestCalcPath(br: Board)
{
let cus = this.CalcPath(br);
let modelings = br.BoardModeling;
let allModeling = GetModelingFromCustomDrill(br);
modelings.push(...allModeling.modeling);
let cus = this.CalcPath(modelings, br.Thickness);
let outline = br.ContourCurve as Polyline;
let dir = Math.sign(outline.Area2);
let sideOutlines: Polyline[] = [];
//优化侧面造型模拟走刀位置
for (let m of allModeling.sideModeling)
{
let c = outline.GetCurveAtIndex(m.dir);
let derv = c.GetFistDeriv(0);
if (dir < 0)
derv.negate();
let mat = MoveMatrix(dir > 0 ? c.StartPoint : c.EndPoint)
.multiply(new Matrix4().makeRotationZ(angleTo(XAxis, derv)))
.multiply(MoveMatrix(new Vector3(0, -br.Thickness)));
m.shape.ApplyMatrix(mat);
let pl = new Polyline().RectangleFrom2Pt(new Vector3(), new Vector3(c.Length, br.Thickness));
pl.ColorIndex = 6;
pl.ApplyMatrix(mat);
sideOutlines.push(pl);
}
cus.push(...this.CalcPath(allModeling.sideModeling, br.Height));
//加入板件轮廓
cus.unshift(br.ContourCurve.Clone());
if (cus.length === 1)
return cus;
//加入造型外轮廓和洞
for (let { shape, thickness } of br.BoardModeling)
for (let { shape, thickness } of modelings)
{
let outline = shape.Outline.Curve.Clone();
outline.Position = outline.Position.setZ(0);
@ -178,19 +208,19 @@ export class FeedingToolPath extends Singleton
}));
}
}
cus.push(...sideOutlines);
return cus;
}
/**
*
* TODO:===ys
*/
CalcPath(br: Board): Curve[]
CalcPath(modelings: IModeling[], thickness: number): Curve[]
{
let cus: Curve[] = [];
let modelings = br.BoardModeling;
for (let m of modelings)
{
cus.push(...this.GetModelFeedPath(br.Thickness, m));
cus.push(...this.GetModelFeedPath(thickness, m));
}
return cus;
}
@ -295,3 +325,90 @@ export class FeedingToolPath extends Singleton
return cons;
}
}
export function GetModelingFromCustomDrill(br: Board)
{
let normal = br.Normal;
let outline = br.ContourCurve as Polyline;
let modeling: IModeling[] = [];
let sideModeling: IModeling[] = [];
for (let [, idss] of br.DrillList)
{
for (let ids of idss)
{
for (let id of ids)
{
if (id ?.Object && !id.Object.IsErase && id.Object instanceof ExtrudeHole)
{
let en = id.Object as ExtrudeHole;
if (en.ContourCurve instanceof Circle)
continue;
let box = en.BoundingBox.applyMatrix4(br.OCSInv);
let max = box.max;
let min = box.min;
let dir: FaceDirection;
let shape = en.Shape;
shape.ApplyMatrix(en.OCS).ApplyMatrix(br.OCSInv);
let thickness: number;
if (isParallelTo(normal, en.Normal))
{
if (min.z > br.Thickness - 1e-6) continue;
if (max.z >= br.Thickness)
{
dir = FaceDirection.Front;
shape.Position = shape.Position.setZ(min.z);
thickness = br.Thickness - min.z;
}
else if (min.z <= 0)
{
dir = FaceDirection.Back;
thickness = max.z;
}
else continue;
if (thickness > 0)
modeling.push({
shape,
thickness,
dir,
knifeRadius: en.KnifeRadius,
addLen: 0,
});
}
else
{
if (min.z <= 0 || max.z >= br.Thickness) continue;
let spt = en.Position.applyMatrix4(br.OCSInv).setZ(0);
if (outline.PtOnCurve(spt)) continue;
let line = new Line(spt, en.Position.add(en.Normal.multiplyScalar(en.Height)).applyMatrix4(br.OCSInv).setZ(0))
let pt = outline.IntersectWith(line, 0)[0];
if (!pt) continue;
let index = Math.floor(outline.GetParamAtPoint(pt));
let thickness = line.StartPoint.distanceTo(pt);
let shape = en.Shape.ApplyMatrix(en.OCS).ApplyMatrix(br.OCSInv);
let vec = line.GetFistDeriv(0).normalize().multiplyScalar(thickness);
shape.Position = shape.Position.add(vec);
let cu = outline.GetCurveAtIndex(index);
shape.ApplyMatrix(new Matrix4().getInverse(GetSideFaceMtx(cu)));
sideModeling.push({
shape,
thickness,
dir: index,
knifeRadius: en.KnifeRadius,
addLen: 0
});
}
}
else break;
}
}
}
return { modeling, sideModeling };
}

@ -1,20 +1,21 @@
import { Matrix4, Vector2, Vector3 } from "three";
import { EBoardKeyList } from "../Common/BoardKeyList";
import { Vector2ApplyMatrix4 } from "../Common/Matrix4Utils";
import { GangDrill, GangDrillType } from "../DatabaseServices/3DSolid/GangDrill";
import { CylinderHole, GangDrillType } from "../DatabaseServices/3DSolid/CylinderHole";
import { Arc } from "../DatabaseServices/Entity/Arc";
import { Board } from "../DatabaseServices/Entity/Board";
import { Board, IModeling } from "../DatabaseServices/Entity/Board";
import { Circle } from "../DatabaseServices/Entity/Circle";
import { Curve } from "../DatabaseServices/Entity/Curve";
import { Line } from "../DatabaseServices/Entity/Line";
import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { Vec2 } from "../Geometry/CheckIntersect";
import { AsVector2, equaln, equalv3, isParallelTo, MoveMatrix } from "../Geometry/GeUtils";
import { GetBoardHighSeal, GetBoardSealingCurves, GetSealedBoardContour as GetSealedBoardContour } from "../GraphicsSystem/CalcEdgeSealing";
import { FeedingToolPath } from "../GraphicsSystem/ToolPath/FeedingToolPath";
import { FeedingToolPath, GetModelingFromCustomDrill } from "../GraphicsSystem/ToolPath/FeedingToolPath";
import { FaceDirection, IHighSealedItem } from "../UI/Store/BoardInterface";
import { Line } from "../DatabaseServices/Entity/Line";
import { Curve } from "../DatabaseServices/Entity/Curve";
import { arrayLast } from "../Common/ArrayExt";
import { userConfig } from "../Editor/UserConfig";
import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole";
/**板件轮廓数据 */
export interface IContourData
@ -33,7 +34,7 @@ export interface IModelingData
{
feeding: IContourData[];
thickness: number;
dir: FaceDirection;
dir: FaceDirection | number;
knifeRadius: number;
}
@ -113,14 +114,16 @@ export namespace Production
originOutlinePtsBul.pts.pop();
originOutlinePtsBul.buls.pop();
let { modeling, sideModeling } = GetBoardModelingData(br, offsetTanslation);
return {
info: GetBoardInfo(br, size),
originOutlin: originOutlinePtsBul,
outline: outlinePtsBul,
sealing: GetBoardSealingData(br),
modeling: GetBoardModelingData(br, offsetTanslation),
modeling,
holes: GetBoardHolesData(br, offsetTanslation),
sideModeling: [],
sideModeling,
offsetTanslation,
};
}
@ -282,42 +285,52 @@ export namespace Production
return sealData;
}
export function GetBoardModelingData(br: Board, offsetTanslation: Vector3): IModelingData[]
export function GetBoardModelingData(br: Board, offsetTanslation: Vector3)
{
const tool = FeedingToolPath.GetInstance() as FeedingToolPath;
const thickness = br.Thickness;
let data: IModelingData[] = [];
for (let m of br.BoardModeling)
const getModelings = (ms: IModeling[], isSide: boolean): IModelingData[] =>
{
let cu = m.shape.Outline.Curve;
if (cu instanceof Circle && cu.Radius < userConfig.modeling2HoleRad + 1e-6)
continue;
m.shape.ApplyMatrix(MoveMatrix(offsetTanslation.clone().negate()));
let feeding = tool.GetModelFeedPath(thickness, m).map(ConverToPolylineAndSplitArc);
if (feeding.length > 0)
data.push({
feeding,
thickness: m.thickness,
dir: m.dir,
knifeRadius: m.knifeRadius,
});
}
return data;
let data: IModelingData[] = [];
for (let m of ms)
{
let cu = m.shape.Outline.Curve;
if (cu instanceof Circle && cu.Radius < userConfig.modeling2HoleRad + 1e-6)
continue;
if (!isSide)
m.shape.ApplyMatrix(MoveMatrix(offsetTanslation.clone().negate()));
let feeding = tool.GetModelFeedPath(thickness, m).map(ConverToPolylineAndSplitArc);
if (feeding.length > 0)
data.push({
feeding,
thickness: m.thickness,
dir: m.dir,
knifeRadius: m.knifeRadius,
});
}
return data;
};
let allModeling = GetModelingFromCustomDrill(br);
let modeling = getModelings([...br.BoardModeling, ...allModeling.modeling], false).filter(f => f.feeding.length > 0);
let sideModeling = getModelings(allModeling.sideModeling, true).filter(f => f.feeding.length > 0);
return { modeling, sideModeling };
}
export function GetBoardHolesData(br: Board, offsetTanslation: Vector3): IBoardHoleInfo
{
let drillList = br.DrillList;
let processData = br.BoardProcessOption;
let data: IBoardHoleInfo = {
frontBackHoles: [],
sideHoles: []
};
let brNormal = br.Normal;
let outline = br.ContourCurve;
let roMat = new Matrix4().extractRotation(br.OCSInv);
for (let [, driss] of drillList)
{
for (let dris of driss)
@ -326,101 +339,11 @@ export namespace Production
{
if (!dId || dId.IsErase)
continue;
let d = dId.Object as GangDrill;
let position = d.Position.applyMatrix4(br.OCSInv);
let holes = data.frontBackHoles;
let face: number;
let isPush = false;
let endPt: Vector3;
let depth = d.Height;
if (d.Type === GangDrillType.Pxl || d.Type === GangDrillType.WoodPXL)
{
if (isParallelTo(d.Normal, brNormal))
{
if (position.x <= 0 || position.x >= br.Width || position.y <= 0 || position.y >= br.Height) continue;
position.sub(offsetTanslation);
face = processData[EBoardKeyList.BigHole];
isPush = true;
}
}
else if (d.Type === GangDrillType.Ljg || d.Type === GangDrillType.Wood)
{
if (!isParallelTo(d.Normal, brNormal))
{
let z = position.z;
if (z <= 0 || z >= br.Thickness) continue;
let line = new Line(position.clone().setZ(0), position.clone().setZ(0).add(d.Normal.multiplyScalar(d.Height).applyMatrix4(roMat)));
let pt = outline.IntersectWith(line, 0)[0];
if (!pt)
{
console.warn("可能有排钻超出板件外");
continue;
}
position = pt.clone().setZ(z);
for (let p of [line.StartPoint, line.EndPoint])
{
if (outline.PtInCurve(p))
{
endPt = p.setZ(z);
break;
}
}
if (!endPt)
{
console.warn("排钻位置有问题");
continue;
}
holes = data.sideHoles;
face = Math.floor(outline.GetParamAtPoint(pt));
isPush = true;
depth = position.distanceTo(endPt);
}
else if (d.Type === GangDrillType.Wood)
{
face = position.z > 0 ? FaceDirection.Front : FaceDirection.Back;
holes = data.frontBackHoles;
if (position.z > 0)
{
let z1 = position.z - d.Height;
if (z1 > 0 && z1 < br.Thickness)
{
depth = br.Thickness - z1;
isPush = true;
}
}
else
{
let z1 = position.z + d.Height;
if (z1 > 0 && z1 < br.Thickness)
{
depth = z1;
isPush = true;
}
}
position.sub(offsetTanslation);
}
}
let d = dId.Object as CylinderHole;
if (d instanceof ExtrudeHole)
ParseExtrudeHoles(d, br, offsetTanslation, data);
else
{
if (isParallelTo(d.Normal, br.Normal))
{
if (position.x <= 0 || position.x >= br.Width || position.y <= 0 || position.y >= br.Height) continue;
position.sub(offsetTanslation);
holes = data.frontBackHoles;
face = !equalv3(d.Normal, brNormal) ? 0 : 1;
isPush = true;
}
}
isPush && holes.push({
type: d.Type,
position,
radius: d.Radius,
depth,
face,
endPt,
});
ParseCylHoles(d, br, offsetTanslation, data);
}
}
}
@ -429,7 +352,7 @@ export namespace Production
{
if (!nid || !nid.Object || nid.IsErase)
continue;
let nail = nid.Object as GangDrill;
let nail = nid.Object as CylinderHole;
if (isParallelTo(nail.Normal, brNormal))
{
let nailPosition = nail.Position.applyMatrix4(br.OCSInv);
@ -466,5 +389,182 @@ export namespace Production
return data;
}
/**分析常规排钻 */
function ParseCylHoles(d: CylinderHole, br: Board, offsetTanslation: Vector3, data: IBoardHoleInfo)
{
let processData = br.BoardProcessOption;
let brNormal = br.Normal;
let roMat = new Matrix4().extractRotation(br.OCSInv);
let outline = br.ContourCurve;
let position = d.Position.applyMatrix4(br.OCSInv);
let holes = data.frontBackHoles;
let face: number;
let isPush = false;
let endPt: Vector3;
let depth = d.Height;
if (d.Type === GangDrillType.Pxl || d.Type === GangDrillType.WoodPXL)
{
if (isParallelTo(d.Normal, brNormal))
{
if (position.x <= 0 || position.x >= br.Width || position.y <= 0 || position.y >= br.Height) return;
position.sub(offsetTanslation);
face = processData[EBoardKeyList.BigHole];
isPush = true;
}
}
else if (d.Type === GangDrillType.Ljg || d.Type === GangDrillType.Wood)
{
if (!isParallelTo(d.Normal, brNormal))
{
let z = position.z;
let line = new Line(position.clone().setZ(0), position.clone().setZ(0).add(d.Normal.multiplyScalar(d.Height).applyMatrix4(roMat)));
let pt = outline.IntersectWith(line, 0)[0];
if (!pt)
{
console.warn("可能有排钻超出板件外");
return;
}
position = pt.clone().setZ(z);
for (let p of [line.StartPoint, line.EndPoint])
{
if (outline.PtInCurve(p))
{
endPt = p.setZ(z);
break;
}
}
if (!endPt)
{
console.warn("排钻位置有问题");
return;
}
holes = data.sideHoles;
face = Math.floor(outline.GetParamAtPoint(pt));
isPush = true;
depth = position.distanceTo(endPt);
}
else if (d.Type === GangDrillType.Wood)
{
face = position.z > 0 ? FaceDirection.Front : FaceDirection.Back;
holes = data.frontBackHoles;
if (position.z > 0)
{
let z1 = position.z - d.Height;
if (z1 > 0 && z1 < br.Thickness)
{
depth = br.Thickness - z1;
isPush = true;
}
}
else
{
let z1 = position.z + d.Height;
if (z1 > 0 && z1 < br.Thickness)
{
depth = z1;
isPush = true;
}
}
position.sub(offsetTanslation);
}
}
else
{
if (isParallelTo(d.Normal, br.Normal))
{
if (position.x <= 0 || position.x >= br.Width || position.y <= 0 || position.y >= br.Height) return;
position.sub(offsetTanslation);
holes = data.frontBackHoles;
face = !equalv3(d.Normal, brNormal) ? 0 : 1;
isPush = true;
}
}
isPush && holes.push({
type: d.Type,
position,
radius: d.Radius,
depth,
face,
endPt,
});
}
/**分析自定义圆柱排钻 */
function ParseExtrudeHoles(d: ExtrudeHole, br: Board, offsetTanslation: Vector3, data: IBoardHoleInfo)
{
let brNormal = br.Normal;
let outline = br.ContourCurve;
let cir = d.ContourCurve;
if (cir instanceof Circle)
{
let diffMtx = br.OCSInv.multiply(d.OCS);
let nor = d.Normal;
let sp = cir.Center.applyMatrix4(diffMtx);
let ep = cir.Center.add(new Vector3(0, 0, d.Height)).applyMatrix4(diffMtx);
if (isParallelTo(nor, brNormal))
{
let z0 = Math.min(sp.z, ep.z);
let z1 = Math.max(sp.z, ep.z);
let p = sp.clone().setZ(0).sub(offsetTanslation);
if (Math.max(z0, 0) < Math.min(z1, br.Thickness) - 1e-6)
{
data.frontBackHoles.push({
type: GangDrillType.Pxl,
position: z0 < 1e-6 ? p : p.setZ(br.Thickness),
radius: cir.Radius,
depth: z0 < 1e-6 ? z1 : br.Thickness - z0,
face: z0 < 1e-6 ? DrillingFace.Back : DrillingFace.Front,
});
}
}
else
{
let oldZ = sp.z;
let [minX, maxX] = sp.x < ep.x ? [sp.x, ep.x] : [ep.x, sp.x];
let [minY, maxY] = sp.y < ep.y ? [sp.y, ep.y] : [ep.y, sp.y];
if (sp.z > cir.Radius
&& sp.z < br.Thickness - cir.Radius
&& Math.max(minX, 0) < Math.min(br.Width, maxX) + 1e-6
&& Math.max(minY, 0) < Math.min(br.Height, maxY) + 1e-6
)
{
sp.setZ(0);
ep.setZ(0);
let line = new Line(sp, ep);
let pt = outline.IntersectWith(line, 0)[0];
if (!pt)
{
console.error("排钻嵌在板件内部");
return;
}
let position = pt.clone().setZ(oldZ);
let endPt: Vector3;
let face = Math.floor(outline.GetParamAtPoint(pt));
for (let p of [line.StartPoint, line.EndPoint])
{
if (outline.PtInCurve(p))
{
endPt = p.setZ(oldZ);
break;
}
}
if (!endPt)
return;
let depth = position.distanceTo(endPt);
data.sideHoles.push({
type: GangDrillType.Ljg,
endPt,
position,
radius: cir.Radius,
depth,
face,
});
}
}
}
}
}

@ -1,8 +1,11 @@
import { Button, Card, Classes, Popover, Position, Radio, RadioGroup, Intent, HTMLSelect } from '@blueprintjs/core';
import { observable } from 'mobx';
import { Button, Card, Checkbox, Classes, Intent, IOptionProps, Popover, Position, Radio, RadioGroup, HTMLSelect } from '@blueprintjs/core';
import { observable, toJS } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { DirUrl, TemplateUrls } from '../../../Common/HostUrl';
import { DirectoryId, PostJson, RequestStatus } from '../../../Common/Request';
import { DrillStore } from '../../Store/DrillStore';
import { end } from 'xaop';
@observer
export class DrillTypeCom extends React.Component<{ store: DrillStore; }, { typeName: string; }>
@ -114,3 +117,138 @@ export class DrillTypeCom extends React.Component<{ store: DrillStore; }, { type
);
}
}
@observer
export class SelectDrillTemp extends React.Component<{ store: DrillStore; }, {}>
{
@observable drillingTempList: IOptionProps[] = [];
@observable drillingDirList: IOptionProps[] = [];
private _dirCache: Map<string, IOptionProps[]> = new Map();
private _fun: Function;
async UNSAFE_componentWillMount()
{
await this.getDirList();
this._fun = end(this.props.store, this.props.store.ChangeRules, async () =>
{
if (this.props.store.m_Option.tempDirId)
await this.getTempList(this.props.store.m_Option.tempDirId);
else
this.drillingTempList.length = 0;
});
}
componentWillUnmount()
{
if (this._fun)
{
this._fun();
this._fun = null;
}
}
render()
{
let option = this.props.store.m_Option;
return (
<div className="drill-temp">
<Checkbox
checked={option.useTemp}
inline={true} label="使用模板"
onChange={async () =>
{
option.useTemp = !option.useTemp;
if (option.useTemp)
await this.getDirList();
}}
/>
{
this.drillingDirList.length > 0 && <select
value={option.tempDirId}
onChange={this.handleChangeDirs}
>
<option value=""></option>
{
this.drillingDirList.map(d => <option value={d.value}>{d.label}</option>)
}
</select>
}
<select
value={option.tempId}
onChange={this.handleChangeTemp}
>
<option value="" ></option>
{
this.drillingTempList.map(d => <option value={d.value}>{d.label}</option>)
}
</select>
</div >
);
}
private getTempList = async (dir_id: string) =>
{
this.props.store.m_Option.tempDirId = dir_id;
if (this._dirCache.has(dir_id))
{
observable(this.drillingTempList).replace(this._dirCache.get(dir_id));
}
else
{
let data = await PostJson(TemplateUrls.list, { dir_id });
if (data.err_code === RequestStatus.Ok && data.modules)
{
observable(this.drillingTempList).replace(data.modules.map(file =>
{
return {
label: file.name,
value: file.module_id
};
}));
this._dirCache.set(dir_id, toJS(this.drillingTempList));
}
}
};
private getDirList = async () =>
{
let data = await PostJson(DirUrl.query, { dir_type: DirectoryId.DrillingDir });
if (data.err_code === RequestStatus.Ok)
{
if (data.dirs.length === 0)
{
this.drillingDirList.length = 0;
await this.getTempList(DirectoryId.DrillingDir);
}
else
{
observable(this.drillingDirList).replace(data.dirs.map(dir =>
{
return {
label: dir.dir_name,
value: dir.dir_id
};
}));
this.drillingDirList.unshift({
label: "/",
value: DirectoryId.DrillingDir
});
if (this.props.store.m_Option.tempDirId)
{
await this.getTempList(this.props.store.m_Option.tempDirId);
}
}
}
};
private handleChangeDirs = async (e: React.FormEvent<HTMLSelectElement>) =>
{
let selectEl = e.target as HTMLSelectElement;
selectEl.options[0].disabled = true;
if (selectEl.value)
await this.getTempList(selectEl.value);
};
private handleChangeTemp = (e: React.FormEvent<HTMLSelectElement>) =>
{
let selectEl = e.target as HTMLSelectElement;
selectEl.options[0].disabled = true;
if (selectEl.value)
this.props.store.m_Option.tempId = selectEl.value;
};
}

@ -1,22 +1,22 @@
import { Button, Checkbox, Classes, HTMLSelect, Icon, Radio, RadioGroup } from '@blueprintjs/core';
import { Button, Checkbox, Classes, Icon, Radio, RadioGroup } from '@blueprintjs/core';
import { inject, observer } from 'mobx-react';
import * as React from 'react';
import * as xaop from 'xaop';
import { app } from '../../../ApplicationServices/Application';
import { CheckObjectType } from '../../../Common/CheckoutVaildValue';
import { safeEval } from '../../../Common/eval';
import { KeyBoard } from '../../../Common/KeyEnum';
import { commandMachine } from '../../../Editor/CommandMachine';
import { SpacingType } from '../../Store/drillInterface';
import { DrillStore } from '../../Store/DrillStore';
import { userConfigStore } from '../../Store/UserConfigStore';
import { ModalState } from '../Modal/ModalsManage';
import { ToasterInput } from '../Toaster';
import { ItemName, SetBoardDataItem } from './BoardCommon';
import { BoardModalType } from './BoardModal';
import { DrillTypeCom, SelectDrillTemp } from './DrillCommon';
import { DrillRulesComponent } from './DrillRules';
import { UserConfig } from './UserConfig';
import { userConfigStore } from '../../Store/UserConfigStore';
import { DrillTypeCom } from './DrillCommon';
import { safeEval } from '../../../Common/eval';
@inject('store')
@observer
@ -52,7 +52,8 @@ export class DrillModal extends React.Component<{ store?: DrillStore; }, {}> {
userConfigStore.SaveConfig(BoardModalType.Dr, this.props.store, false);
app.Editor.ModalManage.Clear();
commandMachine.ExecCommand('PZ');
};
}
UNSAFE_componentWillMount()
{
//注册事件
@ -253,20 +254,9 @@ export class DrillModal extends React.Component<{ store?: DrillStore; }, {}> {
)
}
</div>
<div>
<Checkbox checked={false} inline={true} label="使用模板" />
<HTMLSelect
options={
[
{
label: "模板",
value: ""
}
]
}
/>
</div>
<SelectDrillTemp
store={store}
/>
<h5 className={Classes.HEADING}></h5>
<Checkbox
checked={store.m_Option.isDrawWood}

@ -224,6 +224,17 @@ export const CommandList: ICommand[] = observable([
// enName: "Cylineder",
chDes: "创建三维实体圆柱体",
},
{
icon: IconEnum.Cylinder,
typeId: "i3d",
link: "#",
defaultCustom: "EXTRUDE",
command: "EXTRUDE",
type: "三维",
chName: "拉伸实体",
// enName: "Cylineder",
chDes: "创建三维实体圆柱体",
},
{
icon: IconEnum.DrawAxis,
typeId: "i3d",

@ -0,0 +1,236 @@
import { Button, Card, Checkbox, Classes, ContextMenu, Intent, Menu, MenuItem, Popover, Position } from '@blueprintjs/core';
import { IObservableValue } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { app } from '../../../ApplicationServices/Application';
import { CURRENT_HOST, TemplateUrls } from '../../../Common/HostUrl';
import { MouseKey } from '../../../Common/KeyEnum';
import { PostJson, RequestStatus } from '../../../Common/Request';
import { deflate, ExtrudeDrillFileIn, GetEntitysLogo, inflate } from '../../../Common/SerializeMaterial';
import { CADFiler } from '../../../DatabaseServices/CADFiler';
import { ExtrudeSolid } from '../../../DatabaseServices/Entity/Extrude';
import { TempEditor } from '../../../Editor/TempEditor';
import { IDirectoryProps } from '../SourceManage/CommonPanel';
import { AppToaster } from '../Toaster';
import { DrillingTemplateManage } from './DrillingTemplateManage';
import { ModalPosition } from './ModalsManage';
import { ExtrudeHole } from '../../../DatabaseServices/3DSolid/ExtrudeHole';
import { appCache } from '../../../Common/AppCache';
import { StoreageKeys } from '../../../Common/StoreageKeys';
export interface IDrillTempListProps
{
deleteFun?: (temp: { module_id; }) => void;
dataList?: any[];
select?: (e: React.FormEvent<HTMLInputElement>, data: any) => void;
isRename: IObservableValue<boolean>;
updata: (name: string, dir: IDirectoryProps, call: Function) => void;
getData?: () => void;
info: { id: string; name: string; };
}
@observer
export class DrillingTemplateList extends React.Component<IDrillTempListProps, { isContextMenuOpen: boolean; }> {
private _cameraFiler: CADFiler;
constructor(props)
{
super(props);
this.state = {
isContextMenuOpen: false
};
}
private renderToasterMessage = () =>
{
return (
<div className="flex-between toaster-message">
<span></span>
<div>
<Button text="保存" minimal onClick={this.handleUpdateTemp} />
<Button text="取消" minimal onClick={() =>
{
AppToaster.clear();
}} />
</div>
</div>
);
};
public render()
{
return (
<ul
className="mat-list"
>
{
this.props.dataList.map(temp =>
{
return (
<li
key={temp.module_id}
data-id={temp.module_id}
onMouseDown={(e) => this.handleMounseDown(e, temp)}
style={{
background: this.props.info.id === temp.module_id && "rgba(162, 186, 197, 0.34)",
}}
>
<div>
<img src={`${CURRENT_HOST}/${temp.logo}`} />
</div>
<p title={temp.name}>{temp.name}</p>
<Popover
position={Position.RIGHT}
onOpening={node => node.parentElement.parentElement.style.zIndex = "33"}
content={
<Card>
<p></p>
<div>
<Button style={{ marginRight: 10 }}
className={Classes.POPOVER_DISMISS}
text="取消" />
<Button
className={Classes.POPOVER_DISMISS}
intent={Intent.PRIMARY}
onClick={() => this.props.deleteFun(temp)}
text="确定" />
</div>
</Card>
}
target={<Button
icon="cross"
minimal
/>}
/>
<Checkbox
className={temp.isChecked && "selected"}
inline={true}
checked={temp.isChecked}
onChange={e =>
{
this.props.select(e, temp);
}}
/>
</li>
);
})
}
</ul>
);
}
private handleMounseDown = (e: React.MouseEvent<HTMLElement>, temp: any) =>
{
this.props.info.id = temp.module_id;
this.props.info.name = temp.name;
if (e.button === MouseKey.Right)
{
this.showContextMenu(e, temp);
}
};
//展示右键菜单
private showContextMenu = (e: React.MouseEvent<HTMLElement>, temp: { module_id: string; }) =>
{
ContextMenu.show(
<Menu>
<MenuItem
icon="comment"
text="重命名"
onClick={() => this.props.isRename.set(true)}
/>
<MenuItem
icon="edit"
text="编辑"
onClick={() => this.startEditorTopline(temp)}
/>
</Menu>,
{ left: e.clientX, top: e.clientY },
() => this.setState({ isContextMenuOpen: false }),
);
this.setState({ isContextMenuOpen: true });
e.stopPropagation();
e.preventDefault();
};
private startEditorTopline = async (temp: { module_id: string; }) =>
{
TempEditor.Start();
app.Editor.ModalManage.Clear();
let data = await PostJson(TemplateUrls.detail, { module_id: temp.module_id });
if (data.err_code === RequestStatus.Ok)
{
let files = JSON.parse(inflate(data.modules.file));
let ens = files.map(ExtrudeDrillFileIn) as ExtrudeSolid[];
ens.forEach(e => app.Database.ModelSpace.Append(e));
this._cameraFiler = new CADFiler;
app.Viewer.CameraCtrl.WriteFile(this._cameraFiler);
app.Viewer.ZoomAll();
AppToaster.show({
message: this.renderToasterMessage(),
intent: Intent.PRIMARY,
timeout: 0,
onDismiss: this.exitEditor
});
}
};
private exitEditor = () =>
{
if (!this._cameraFiler) return;
app.Viewer.CameraCtrl.ReadFile(this._cameraFiler);
TempEditor.End();
this._cameraFiler = undefined;
app.Editor.SelectCtrl.Cancel();
app.Editor.ModalManage.RenderModal(DrillingTemplateManage, ModalPosition.Old, {});
};
handleUpdateTemp = async () =>
{
await app.Editor.ModalManage.EndExecingCmd();
let ens = app.Viewer.VisibleEntitys.filter(en => en instanceof ExtrudeHole) as ExtrudeHole[];
if (ens.length > 0)
{
let module_id = this.props.info.id;
let logo = await GetEntitysLogo(ens);
let dataList = [];
//基点移动到基点
for (let en of ens)
{
let vf = new CADFiler();
en.WriteFile(vf);
dataList.push(vf.Data);
}
let filesJson = JSON.stringify(dataList);
let data = await PostJson(TemplateUrls.update, {
module_id,
logo,
file: deflate(filesJson),
zip_type: "gzip",
});
AppToaster.clear();
if (data.err_code === RequestStatus.Ok)
{
//更新缓存的自定义排钻实体
ens = [];
for (let file of dataList)
ens.push(ExtrudeDrillFileIn(file));
appCache.set(StoreageKeys.DrillTemp + module_id, ens);
await this.props.getData();
AppToaster.show({
message: "排钻模板修改成功",
timeout: 1500,
intent: Intent.SUCCESS,
});
}
}
else
{
AppToaster.show({
message: "修改失败,可能当前图上不存在排钻实体,请重试或者取消",
timeout: 1200,
intent: Intent.DANGER,
});
}
};
}

@ -0,0 +1,252 @@
import { Button, Classes, Icon, Intent, MenuItem } from '@blueprintjs/core';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { app } from '../../../ApplicationServices/Application';
import { TemplateUrls } from '../../../Common/HostUrl';
import { DirectoryId, PostJson, RequestStatus, IResponseData } from '../../../Common/Request';
import { deflate, ExtrudeDrillFileIn, GetEntitysLogo, inflate } from '../../../Common/SerializeMaterial';
import { CADFiler } from '../../../DatabaseServices/CADFiler';
import { CommandWrap } from '../../../Editor/CommandMachine';
import { PromptStatus } from '../../../Editor/PromptResult';
import { MoveMatrix } from '../../../Geometry/GeUtils';
import { CommonPanel, IDirectoryProps } from '../SourceManage/CommonPanel';
import { HandleDirComponent } from '../SourceManage/HandleDirComponent';
import { AppToaster } from '../Toaster';
import { DrillingTemplateList } from './DrillingTemplateList';
import { ExtrudeHole } from '../../../DatabaseServices/3DSolid/ExtrudeHole';
@observer
export class DrillingTemplateManage extends React.Component<{}> {
private canCreateTemplate = observable.box(false);
@observable private currentInfo = { id: "", name: "" };
renderNav = () =>
{
return (
<Button
icon="cloud-upload"
style={{
marginRight: 10
}}
text="添加排钻模板"
intent={Intent.SUCCESS}
onClick={this.startCreateDrillingTemp}
/>
)
}
renderMenuItems = () =>
{
return (
<MenuItem icon="cloud-upload" text="创建排钻模板"
onClick={this.startCreateDrillingTemp}
/>
)
}
public render()
{
return (
<div
className={Classes.DIALOG_CONTAINER}
id="commonModal"
>
<div className={Classes.DIALOG + " topline drill-temp"}>
<div
className={Classes.DIALOG_HEADER}
data-id="dragArea"
>
<Icon icon="bold" iconSize={18} />
<h4 className="bp3-heading"></h4>
<Button
aria-label="Close"
minimal
icon="cross"
className={Classes.DIALOG_CLOSE_BUTTON}
onClick={() => app.Editor.ModalManage.Clear()}
/>
</div>
<div
className={Classes.DIALOG_BODY}
>
<CommonPanel
defaultDirId={DirectoryId.DrillingDir}
renderMenuItems={this.renderMenuItems}
renderNav={this.renderNav}
getUrl={TemplateUrls.list}
deleteUrl={TemplateUrls.delete}
clickTree={() =>
{
this.currentInfo.id = "";
}}
maxDirLength={0}
>
<DrillingTemplateList
isRename={this.canCreateTemplate}
updata={this.handleCreateTemplate}
info={this.currentInfo}
/>
{
this.canCreateTemplate.get() && <HandleDirComponent
defualtValue={this.currentInfo.name}
isReset={false}
isOpen={this.canCreateTemplate}
handleFunc={this.handleTemplate}
title="输入排钻名称"
/>
}
</CommonPanel>
</div>
<div className={Classes.DIALOG_FOOTER} >
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button
className={Classes.INTENT_SUCCESS}
text="预览"
disabled={!this.currentInfo.id}
onClick={() => this.drawTemplate(this.currentInfo.id)}
/>
<Button
className={Classes.INTENT_DANGER}
text="取消"
onClick={() => app.Editor.ModalManage.Clear()}
/>
</div>
</div>
</div>
</div >
);
}
handleTemplate = async (name: string, currentDir, callback: Function) =>
{
if (!name.trim())
{
AppToaster.show({
message: "名称不能为空",
intent: Intent.DANGER,
timeout: 1000
});
return;
}
if (this.currentInfo.id)
{
await this.handleRenameTemp(name);
await callback();
}
else
{
if (!currentDir)
{
AppToaster.show({
message: "未知错误,请重试",
timeout: 1000
});
return;
}
CommandWrap(async () =>
{
await this.handleCreateTemplate(name, currentDir, callback);
}, "_uploaddrilling")
}
}
private handleCreateTemplate = async (name: string, currentDir: IDirectoryProps, callback: Function) =>
{
app.Editor.ModalManage.ToggleShow();
app.Editor.MaskManage.Clear();
const reset = () =>
{
app.Editor.ModalManage.ToggleShow();
app.Editor.MaskManage.ShowMask();
this.canCreateTemplate.set(false);
}
let enRes = await app.Editor.GetSelection({
Msg: "排钻模板组件",
Filter: {
filterTypes: [ExtrudeHole],
},
});
if (enRes.Status !== PromptStatus.OK)
{
reset();
return;
};
let ens = enRes.SelectSet.SelectEntityList.map(e => e.Clone()) as ExtrudeHole[];
let ptRes = await app.Editor.GetPoint({
Msg: "指定基点"
})
if (ptRes.Status !== PromptStatus.OK)
{
reset();
return;
}
let logo = await GetEntitysLogo(ens);
let dataList = [];
//基点移动到基点
for (let en of ens)
{
let vf = new CADFiler();
en.ApplyMatrix(MoveMatrix(ptRes.Point.negate()));
en.WriteFile(vf);
dataList.push(vf.Data);
}
let fileJson = JSON.stringify(dataList);
let data = await PostJson(TemplateUrls.create, {
dir_id: currentDir.id,
name,
logo,
file: deflate(fileJson),
zip_type: "gzip",
});
if (data.err_code === RequestStatus.Ok)
{
await callback();
}
reset();
}
handleRenameTemp = async (name: string) =>
{
let data = await PostJson(TemplateUrls.update, {
module_id: this.currentInfo.id,
name
});
if (data.err_code === RequestStatus.Ok)
{
AppToaster.show({
message: "重命名成功",
timeout: 1000
})
}
this.canCreateTemplate.set(false);
}
private drawTemplate = async (module_id: string) =>
{
app.Editor.ModalManage.Clear();
let data = await PostJson(TemplateUrls.detail, { module_id });
if (data.err_code === RequestStatus.Ok)
{
let modules = JSON.parse(inflate(data.modules.file));
for (let module of modules)
{
app.Database.ModelSpace.Append(ExtrudeDrillFileIn(module));
}
app.Editor.UpdateScreen();
}
}
private startCreateDrillingTemp = () =>
{
this.currentInfo.id = "";
this.currentInfo.name = "";
this.canCreateTemplate.set(true);
}
}

@ -32,6 +32,18 @@
.hole {
flex-direction: column;
}
.drill-temp {
display: flex;
overflow: hidden;
&>select {
width: 95px;
overflow: hidden;
height: 20px;
line-height: 20px;
}
}
}
#drillModal .flexWrap>div {

@ -4,6 +4,7 @@ import * as React from 'react';
import { app } from '../../../../ApplicationServices/Application';
import { UserConfig } from '../../../../Editor/UserConfig';
import { safeEval } from '../../../../Common/eval';
import { StoreageKeys } from '../../../../Common/StoreageKeys';
interface IConfigProps
{
@ -17,6 +18,7 @@ export class DrawConfigPanel extends React.Component<IConfigProps, {}> {
const userConfig = this.props.store;
userConfig.openDrillingReactor = !userConfig.openDrillingReactor;
app._drillingReactor.Enable = userConfig.openDrillingReactor;
localStorage.setItem(StoreageKeys.DrillReactor, userConfig.openDrillingReactor ? "1" : "");
}
private toggleAutoCuttingReactor = () =>
{

@ -34,12 +34,13 @@ interface ICommonPanelProps
defaultDirId: string; //根目录ID
renderNav?: () => JSX.Element; //渲染导航栏
renderMenuItems?: () => JSX.Element; //渲染右键菜单项
canDelete: boolean; //是否可以删除数据
canDelete?: boolean; //是否可以删除数据
deleteUrl: string; //删除后端URL
getUrl: string; //获取数据URL
clickTree?: () => void;
delete?: (data) => void;
canOrder?: boolean; //可以排序
maxDirLength?: number; //目录最大层级
}
enum EOrderType
@ -74,6 +75,11 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
};
private _dragId = "";
private nodeEls: HTMLElement[];
static defaultProps = {
maxDirLength: 1,
canOrder: true,
canDelete: true,
};
constructor(props)
{
super(props);
@ -195,7 +201,7 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
ContextMenu.show(
<Menu>
{
(!_nodePath || _nodePath.length <= 1) && <MenuItem
(!_nodePath || _nodePath.length <= this.props.maxDirLength) && <MenuItem
icon="folder-new"
text="新建目录"
onClick={() => this.startHandleDir.set(true)}
@ -490,20 +496,20 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
let deleteMats = this.state.isSelectAll ? this.dataList : [...this.needDeleteData];
return deleteMats.map(m => m[idKey]);
};
if (this.props.defaultDirId === DirectoryId.ImgDir)
return getQuery("image_id");
else if (this.props.defaultDirId === DirectoryId.MaterialDir)
return getQuery("material_id");
else if (this.props.defaultDirId === DirectoryId.ToplineDir)
return getQuery("topline_id");
else if (this.props.defaultDirId === DirectoryId.FileDir)
return getQuery("file_id");
else if (this.props.defaultDirId === DirectoryId.TemplateDir)
return getQuery("module_id");
else
{
console.warn("未知目录id");
return [];
switch (this.props.defaultDirId)
{
case DirectoryId.ImgDir:
return getQuery("image_id");
case DirectoryId.MaterialDir:
return getQuery("material_id");
case DirectoryId.ToplineDir:
return getQuery("topline_id");
case DirectoryId.DrillingDir:
return getQuery("module_id");
case DirectoryId.TemplateDir:
default:
console.warn("未知目录id");
return [];
}
};
//删除数据
@ -525,18 +531,28 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
return query;
};
let query: Object;
if (this.props.defaultDirId === DirectoryId.ImgDir)
query = getQuery("image_id");
else if (this.props.defaultDirId === DirectoryId.MaterialDir)
query = getQuery("material_id");
else if (this.props.defaultDirId === DirectoryId.ToplineDir)
query = getQuery("topline_id");
else if (this.props.defaultDirId === DirectoryId.FileDir)
query = getQuery("file_id");
else if (this.props.defaultDirId === DirectoryId.TemplateDir)
query = getQuery("module_id");
else
console.warn("未知目录id");
switch (this.props.defaultDirId)
{
case DirectoryId.ImgDir:
query = getQuery("image_id");
break;
case DirectoryId.MaterialDir:
query = getQuery("material_id");
break;
case DirectoryId.ToplineDir:
query = getQuery("topline_id");
break;
case DirectoryId.FileDir:
query = getQuery("file_id");
break;
case DirectoryId.TemplateDir:
case DirectoryId.DrillingDir:
query = getQuery("module_id");
break;
default:
console.warn("未知目录id");
break;
}
if (!query) return;
@ -555,7 +571,6 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
if (this.props.defaultDirId === DirectoryId.ImgDir)
return;
let targetId: string;
let el = e.target as HTMLElement;
while (true)
@ -593,6 +608,7 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
query.topline_ids = dataIds;
break;
case DirectoryId.TemplateDir:
case DirectoryId.DrillingDir:
url = TemplateUrls.move;
query.module_ids = dataIds;
break;
@ -710,6 +726,7 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
if (data.err_code === RequestStatus.Ok)
{
this.setState({ nodes: this.parseNodes(data.dirs) });
this.updateNodeEls();
}
else
{
@ -725,25 +742,15 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
}
await this.handleGetData();
}
componentDidMount()
{
// let el = document.getElementsByClassName("bp3-overflow-list")[0];
// console.log('el: ', el);
// if (el)
// el.addEventListener('click', (e) =>
// {
// console.log(e);
// e.stopPropagation();
// });
//监听右键其他位置
this.tree.addEventListener('mousedown', this.handleTreeMouseDown);
this.tree.addEventListener('dragenter', this.handleDragEnterFile);
this.tree.addEventListener('dragleave', this.handleDragLeave);
this.tree.addEventListener("drop", this.handleMoveFiles);
document.addEventListener('dragend', this.handleDragEnd);
this.updateNodeEls();
}
componentWillUnmount()
{
@ -792,7 +799,7 @@ export class CommonPanel extends React.Component<ICommonPanelProps, ICommonPanel
onChange={this.handleSelectAll}
/>
{
this.props.canOrder !== false && <HTMLSelect
this.props.canOrder && <HTMLSelect
defaultValue={this._orderType}
options={[
{

@ -220,7 +220,6 @@ export class FilePanel extends React.Component<{ store?: TopPanelStore; }, {}>
defaultDirId={DirectoryId.FileDir}
renderNav={this.renderNav}
renderMenuItems={this.renderMenuItems}
canDelete={true}
getUrl={FileUrls.list}
deleteUrl={FileUrls.delete}
delete={this.handleDelete}

@ -4,6 +4,7 @@ import { KeyBoard } from '../../../Common/KeyEnum';
import './TexturePanel.less';
import { IObservableValue } from 'mobx';
import { IDirectoryProps } from './CommonPanel';
import { AppToaster } from '../Toaster';
interface IHandleDirProps
{
@ -28,7 +29,18 @@ export class HandleDirComponent extends React.Component<IHandleDirProps, {}>
private onKeydown = async (e) =>
{
if (e.keyCode === KeyBoard.Enter)
{
if (this.inputEl.value.length >= 30)
{
AppToaster.show({
message: "不能超过30个字符",
timeout: 1500,
intent: Intent.DANGER
})
return;
}
await this.props.handleFunc(this.inputEl.value, this.props.currentDir, this.props.getData);
}
else if (e.keyCode === KeyBoard.Escape)
{
this.props.isOpen.set(false);
@ -38,6 +50,15 @@ export class HandleDirComponent extends React.Component<IHandleDirProps, {}>
};
private handleClick = async () =>
{
if (this.inputEl.value.length >= 30)
{
AppToaster.show({
message: "不能超过30个字符",
timeout: 1500,
intent: Intent.DANGER
})
return;
}
await this.props.handleFunc(this.inputEl.value, this.props.currentDir, this.props.getData);
};
componentWillUnmount()

@ -70,7 +70,6 @@ export class MaterialPanel extends React.Component<IMaterialProps, IMaterialStat
defaultDirId={DirectoryId.MaterialDir}
renderNav={() => this.renderNav()}
renderMenuItems={() => this.renderMenuItems()}
canDelete={true}
getUrl={MaterialUrls.get}
deleteUrl={MaterialUrls.delete}
>

@ -373,7 +373,6 @@ export class TemplateManage extends React.Component<{ store?: TempalteEditorStor
defaultDirId={DirectoryId.TemplateDir}
renderNav={this.renderNav}
renderMenuItems={this.renderMenuItems}
canDelete={true}
getUrl={TemplateUrls.list}
deleteUrl={TemplateUrls.delete}
clickTree={() =>

@ -4,6 +4,10 @@
height: 80vh;
min-height: 750px;
.bp3-dialog-body {
overflow: hidden;
}
.bp3-dialog-body>div:first-child {
min-width: 200px;
}
@ -20,3 +24,9 @@
}
}
}
#commonModal .drill-temp {
.bp3-dialog-footer-actions {
width: 100%;
}
}

@ -241,7 +241,6 @@ export class TopllineManage extends React.Component<ITopllineManageProps, ITopll
defaultDirId={DirectoryId.ToplineDir}
renderNav={this.renderNav}
renderMenuItems={this.renderMenuItems}
canDelete={true}
getUrl={ToplineUrls.get}
deleteUrl={ToplineUrls.delete}
clickTree={() =>

@ -6,7 +6,7 @@ import { IconEnum } from "../../IconEnum";
import { DrawingPanel } from "./DrawingPanel";
import { ToolsBlockStore } from "./ToolsBlockStore";
import { RenderPanel } from "./RenderPanel";
import { ThreeDEntityPanel } from "./ThreeDEntityPanel"
import { ThreeDEntityPanel } from "./ThreeDEntityPanel";
import { DimensionPanel } from "./DimensionPanel";
import { FileOperationPanel } from "./FileOperationPanel";
import { TemplateAndModulePanel } from "./TemplateAndModulePanel";
@ -27,7 +27,7 @@ export class TopToolBar extends React.Component<{}, {}>
{ svg: IconEnum.Undo, title: "重做", command: "REDO" },
{ svg: IconEnum.Open, title: "打开", command: "OPEN" },
{ svg: IconEnum.DXF, title: "DXF", command: "DXF" },
]
];
store.iconList.twoD = [
{ svg: IconEnum.Point, title: "点", command: "PT" },
{ svg: IconEnum.Line, title: "直线", command: "L" },
@ -38,7 +38,7 @@ export class TopToolBar extends React.Component<{}, {}>
// { svg: IconEnum.SpLine, title: "样条曲线", command: "SPL" },
{ svg: IconEnum.Region, title: "面域", command: "REG" },
{ svg: IconEnum.Text, title: "文字", command: "TEXT" },
]
];
store.iconList.threeD = [
// { svg: IconEnum.Ball, title: "球体", command: "SP" },//暂时隐藏
// { svg: IconEnum.Cuboid, title: "长方体", command: "BOX" },
@ -46,7 +46,8 @@ export class TopToolBar extends React.Component<{}, {}>
// { svg: IconEnum.Sweep, title: "扫掠", command: "SW" },
// { svg: IconEnum.CSGunion, title: "实体并集", command: "CSGUNION" },
// { svg: IconEnum.CSGintersect, title: "实体差集", command: "CSGSUB" },
]
{ svg: IconEnum.ExtrudeEntity, title: "拉伸实体", command: "EXTRUDE" },
];
store.iconList.brDraw = [
{ svg: IconEnum.DB, title: "单板", command: "DB" },
{ svg: IconEnum.ZYC, title: "左右侧板", command: "ZYC" },
@ -62,7 +63,7 @@ export class TopToolBar extends React.Component<{}, {}>
{ svg: IconEnum.Door, title: "门板", command: "DOOR" },
{ svg: IconEnum.Drawer, title: "抽屉", command: "DRAWER" },
{ svg: IconEnum.Lattice, title: "格子抽", command: "LATTICE" },
]
];
store.iconList.brEdit = [
{ svg: IconEnum.QG, title: "线性切割", command: "QG" },
{ svg: IconEnum.QG2, title: "板件相切", command: "QG2" },
@ -73,7 +74,7 @@ export class TopToolBar extends React.Component<{}, {}>
{ svg: IconEnum.BoardFindModify, title: "查找修改", command: "BOARDFINDMODIFY" },
{ svg: IconEnum.BatchModifyDrillAndSeal, title: "修改板边", command: "BATCHMODIFY" },
{ svg: IconEnum.BBS, title: "批量查看", command: "BBS" },
]
];
store.iconList.dim = [
{ svg: IconEnum.DAL, title: "对齐标注", command: "DAL" },
{ svg: IconEnum.DimContinued, title: "线性标注", command: "DLI" },
@ -84,20 +85,20 @@ export class TopToolBar extends React.Component<{}, {}>
{ svg: IconEnum.AutoDim, title: "柜体标注", command: "AUTODIMBRS" },
{ svg: IconEnum.FastDim, title: "自由标注", command: "FASTDIMBRS" },
{ svg: IconEnum.DelDim, title: "快速删除", command: "DELETEDIM" },
]
];
store.iconList.light = [
{ svg: IconEnum.SpotLamp, title: "射灯", command: "SL" },
{ svg: IconEnum.DownLamp, title: "下照射灯", command: "SL1" },
{ svg: IconEnum.SunLight, title: "点光源", command: "PTL" },
{ svg: IconEnum.ParamPtLight, title: "参数点光源", command: "PTL2" },
{ svg: IconEnum.RectLight, title: "矩形光", command: "RL" },
]
];
store.iconList.drill = [
{ svg: IconEnum.Drill, title: "排钻", command: "PZ" },
{ svg: IconEnum.DeleteDrill, title: "删除排钻", command: "DELETEDRILL" },
{ svg: IconEnum.DrillConfig, title: "排钻配置", command: "DRILLCONFIG" },
{ svg: IconEnum.HideDrill, title: "隐藏排钻", command: "" },
]
];
store.iconList.view = [
{ svg: IconEnum.UCS, title: "UCS", command: "UCS" },
{ svg: IconEnum.TopView, title: "俯视图", command: "FS" },
@ -108,27 +109,28 @@ export class TopToolBar extends React.Component<{}, {}>
{ svg: IconEnum.SouthWest, title: "西南等轴测", command: "SWISO" },
{ svg: IconEnum.ExplosionMap, title: "爆炸图", command: "EXPLOSIONMAP" },
{ svg: IconEnum.Camera, title: "相机模式", command: "CC" },
]
];
store.iconList.visualStyle = [
{ svg: IconEnum.WireframeView, title: "二维线框", command: "WIREFRAME" },
{ svg: IconEnum.ConceptView, title: "概念", command: "CONCEPTUAL" },
{ svg: IconEnum.Reality, title: "真实", command: "PHYSICAL" },
]
];
store.iconList.produce = [
{ svg: IconEnum.SplitOrder, title: "拆单优化", command: "CD" },
{ svg: IconEnum.HistoryOptimize, title: "查看优化", command: "CKYH" },
// { svg: IconEnum.QuotePrice, title: "报价", command: "" },//暂时隐藏
// { svg: IconEnum.ERPManage, title: "ERP", command: "" },
]
];
store.iconList.template = [
{ svg: IconEnum.TemplateDesign, title: "模版设计", command: "TEMPLATEDESIGN" },
]
];
store.iconList.module = [
{ svg: IconEnum.ModuleManage, title: "模块管理", command: "TEMPLATE" },
]
{ svg: IconEnum.HoleModule, title: "排钻模块", command: "DRILLTEMPLATE" },
];
store.iconList.commodity = [
{ svg: IconEnum.CommodityManage, title: "共享模块", command: "TEMPLATESEARCH" },
]
];
store.calcIconNumInTabs();

@ -134,5 +134,7 @@ export enum IconEnum
DrawAxis = "DrawAxis.svg",
CircleWithCrossDottedLine = "CircleWithCrossDottedLine.svg",
CommodityManage = "CommodityManage.svg",
DAL = "DAL.svg"
DAL = "DAL.svg",
HoleModule = "HoleModule.svg",
ExtrudeEntity = "StretchEntity.svg",
}

@ -5,6 +5,14 @@ import { IConfigOption } from "../Components/Board/UserConfig";
import { BoardStore } from "./BoardStore";
import { DrillingOption, SpacingType } from "./drillInterface";
import { userConfig } from "../../Editor/UserConfig";
import { AppToaster } from "../Components/Toaster";
import { Intent } from "@blueprintjs/core";
import { StoreageKeys } from "../../Common/StoreageKeys";
import { ExtrudeHole } from "../../DatabaseServices/3DSolid/ExtrudeHole";
import { PostJson, RequestStatus } from "../../Common/Request";
import { TemplateUrls } from "../../Common/HostUrl";
import { ExtrudeDrillFileIn, inflate } from "../../Common/SerializeMaterial";
import { appCache } from "../../Common/AppCache";
export class DrillStore extends BoardStore
{
@ -23,7 +31,7 @@ export class DrillStore extends BoardStore
private GetDefaultOption()
{
let originOption: DrillingOption = {
version: 1,
version: 2, //排钻模板新版本
startDist: 0,
endDist: 40,
//位置参数
@ -61,6 +69,9 @@ export class DrillStore extends BoardStore
ljgPos: "H*0.5",
woodPinPos: "H*0.5",
canSameType: false,
useTemp: false,
tempId: "",
tempDirId: ""
};
let opt1 = Object.assign({}, originOption);
opt1.count = 1;
@ -103,7 +114,7 @@ export class DrillStore extends BoardStore
this.m_Option = rules[0];
this.rules.length = 0;
this.rules.push(...rules);
this.drillConfig.clear();
this.drillConfig.set("三合一", rules);
this.drillConfig.set("二合一", this.GetDefaultOption().map(opt =>
{
@ -126,6 +137,14 @@ export class DrillStore extends BoardStore
for (let i = 0; i < this.rules.length; i++)
{
let rule = this.rules[i];
if (rule.useTemp && !rule.tempId)
{
AppToaster.show({
message: `${rule.startDist}-${rule.endDist}配置使用模板却没选择模板,请修改`,
timeout: 2000,
intent: Intent.WARNING
}, "err" + i);
}
if (rule.startDist === this.m_Option.startDist && rule.endDist === this.m_Option.endDist)
{
this.m_CurrentRuleIndex = i;
@ -149,6 +168,7 @@ export class DrillStore extends BoardStore
//写入时修改用户当前配置
this.drillConfig.set(this.type, toJS(this.rules));
userConfig.DrillConfigs = this.drillConfig;
this.HandleDrillConfig(this.drillConfig);
}
SaveConfig()
{
@ -164,13 +184,9 @@ export class DrillStore extends BoardStore
UpdateOption(cof: IConfigOption)
{
this.drillConfig.clear();
this.HandleDrillConfig(cof.ruleMap);
for (let [k, v] of cof.ruleMap)
{
//更新旧版本错误数据
for (let cof of v)
{
cof.tYmjRad = Number(cof.tYmjRad);
}
this.drillConfig.set(k, v);
}
if (cof.ruleMap.size > 0)
@ -199,4 +215,43 @@ export class DrillStore extends BoardStore
{
return CheckoutValid.HasInvailValue(this.UIOption, CheckObjectType.DR);
}
/**修正就版本排钻配置,缓存排钻模板 */
async HandleDrillConfig(ruleMap: Map<string, DrillingOption[]>)
{
for (let [, configs] of ruleMap)
{
for (let conf of configs)
{
conf.tYmjRad = Number(conf.tYmjRad);
if (!conf.version || conf.version < 2)
{
conf.useTemp = false;
conf.tempDirId = "";
conf.tempId = "";
}
if (conf.useTemp && conf.tempId)
{
await this.CacheDrillTemp(conf.tempId);
}
}
}
}
async CacheDrillTemp(tempId: string)
{
let key = StoreageKeys.DrillTemp + tempId;
if (appCache.has(key))
return;
let ens: ExtrudeHole[] = [];
let data = await PostJson(TemplateUrls.detail, { module_id: tempId });
if (data.err_code === RequestStatus.Ok)
{
let files = JSON.parse(inflate(data.modules.file));
for (let file of files)
{
ens.push(ExtrudeDrillFileIn(file));
}
appCache.set(key, ens);
}
}
}

@ -100,20 +100,14 @@ export class UserConfigStore extends Singleton
async InitDrillConfig()
{
let config = await this.GetConfig(BoardModalType.Dr);
const drillStore = DrillStore.GetInstance() as DrillStore;
if (config)
{
//修正旧版本线上数值错误问题
for (let [, configs] of config.ruleMap)
{
for (let conf of configs)
{
conf.tYmjRad = Number(conf.tYmjRad);
}
}
drillStore.HandleDrillConfig(config.ruleMap);
userConfig.DrillConfigs = config.ruleMap;
}
else
await userConfigStore.SaveConfig(BoardModalType.Dr, DrillStore.GetInstance(), true);
await userConfigStore.SaveConfig(BoardModalType.Dr, drillStore, true);
}
async InitWinerackConfig()
{

@ -45,4 +45,7 @@ export interface DrillingOption extends IBaseOption
ljgPos: string;//偏心轮位置
woodPinPos: string;//木销位置
canSameType: boolean;
useTemp: boolean; //是否使用模板
tempId: string; //排钻模板id
tempDirId: string; //排钻模板id
}

Loading…
Cancel
Save