mirror of https://gitee.com/cf-fz/WebCAD.git
!1378 功能: 矩形转层板立板,命令R2B2
parent
e6a71253af
commit
43ab04e521
@ -0,0 +1,121 @@
|
||||
import { Button, Card, H5, Intent } from '@blueprintjs/core';
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component } from 'react';
|
||||
import { app } from '../../../ApplicationServices/Application';
|
||||
import { CheckObjectType } from '../../../Common/CheckoutVaildValue';
|
||||
import { Input5Or4Component, Notes, SetBoardDataBlock } from '../../../UI/Components/Board/BoardCommon';
|
||||
import { BoardModalType } from '../../../UI/Components/Board/BoardModal';
|
||||
import { CommonModal } from '../../../UI/Components/Modal/ModalContainer';
|
||||
import { ModalState } from '../../../UI/Components/Modal/ModalInterface';
|
||||
import { AppToaster } from '../../../UI/Components/Toaster';
|
||||
import { R2B2Store } from '../R2B2Store';
|
||||
import { SelectDrillType } from '../R2BCommon';
|
||||
|
||||
const CabPars = [
|
||||
["depthExpr", "柜深"], ["maxThickness", "最大板厚"],
|
||||
];
|
||||
const ShrinkPars = [
|
||||
["vertialShrink", "立板"], ["layerShrink", "层板"],
|
||||
];
|
||||
|
||||
@observer
|
||||
export class R2b2Panel extends Component<{ store: R2B2Store; }>
|
||||
{
|
||||
render()
|
||||
{
|
||||
const { store } = this.props;
|
||||
return (
|
||||
<CommonModal
|
||||
title="矩形变板件"
|
||||
close={this.close}
|
||||
store={store}
|
||||
type={BoardModalType.R2B2}
|
||||
footerChildren={
|
||||
<>
|
||||
<Button
|
||||
text="确定"
|
||||
intent={Intent.SUCCESS}
|
||||
onClick={this.confirm}
|
||||
/>
|
||||
<Button
|
||||
text="取消"
|
||||
intent={Intent.DANGER}
|
||||
onClick={this.close}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Card className="flex r2b2">
|
||||
<div style={{ width: 250 }}>
|
||||
<H5>柜体参数</H5>
|
||||
<SetBoardDataBlock
|
||||
type={CheckObjectType.R2B}
|
||||
className="flexWrap"
|
||||
pars={CabPars}
|
||||
option={store.option}
|
||||
uiOption={store.UIOption}
|
||||
/>
|
||||
<H5>前缩</H5>
|
||||
<SetBoardDataBlock
|
||||
type={CheckObjectType.R2B}
|
||||
className="flexWrap"
|
||||
pars={ShrinkPars}
|
||||
option={store.option}
|
||||
uiOption={store.UIOption}
|
||||
/>
|
||||
<H5>排钻</H5>
|
||||
<SelectDrillType
|
||||
option={store.option}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: 20,
|
||||
lineHeight: "20px"
|
||||
}}
|
||||
/>
|
||||
<H5>封边</H5>
|
||||
<Input5Or4Component
|
||||
type={CheckObjectType.BR}
|
||||
showDirectionIcon={true}
|
||||
hasCenter={false}
|
||||
optKey=""
|
||||
upKey="sealedUp"
|
||||
downKey="sealedDown"
|
||||
leftKey="sealedLeft"
|
||||
rightKey="sealedRight"
|
||||
option={store.option}
|
||||
isShowEditor={true}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Notes
|
||||
remarks={store.option.remarks}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</CommonModal>
|
||||
);
|
||||
}
|
||||
private close = () =>
|
||||
{
|
||||
app.Editor.ModalManage.Destory();
|
||||
};
|
||||
private confirm = () =>
|
||||
{
|
||||
let error = this.props.store.HasInvailValue();
|
||||
if (error)
|
||||
{
|
||||
AppToaster.show({
|
||||
message: "存在无效数值,请修正",
|
||||
timeout: 3000,
|
||||
intent: Intent.DANGER
|
||||
});
|
||||
return;
|
||||
}
|
||||
app.Editor.ModalManage.DestoryAndExec(
|
||||
{
|
||||
Status: ModalState.Ok,
|
||||
Data: { cname: "矩形变层板立板" }
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
import { observable, toJS } from "mobx";
|
||||
import { begin } from "xaop";
|
||||
import { CheckObjectType, CheckoutValid } from "../../Common/CheckoutVaildValue";
|
||||
import { DataAdapter } from "../../Common/DataAdapter";
|
||||
import { DefaultR2b2Option } from "../../Editor/DefaultConfig";
|
||||
import { userConfig } from "../../Editor/UserConfig";
|
||||
import { IConfigOption } from "../../UI/Components/Board/UserConfig";
|
||||
import { IUiOption } from "../../UI/Store/BoardInterface";
|
||||
import { IConfigStore } from "../../UI/Store/BoardStore";
|
||||
import { IRect2Br2Option } from "./R2bInterface";
|
||||
|
||||
export class R2B2Store implements IConfigStore
|
||||
{
|
||||
@observable configName = "默认";
|
||||
@observable configsNames: string[] = [];
|
||||
@observable option: IRect2Br2Option = { ...DefaultR2b2Option, remarks: Array.from({ length: 12 }, () => ["", ""]) };
|
||||
@observable uiOption: IUiOption<IRect2Br2Option>;
|
||||
constructor()
|
||||
{
|
||||
begin(userConfig, userConfig.SetDrillConfigsEvent, () =>
|
||||
{
|
||||
this.InitDrillType();
|
||||
});
|
||||
}
|
||||
get UIOption(): IUiOption<IRect2Br2Option>
|
||||
{
|
||||
if (!this.uiOption)
|
||||
this.uiOption = DataAdapter.ConvertUIData(this.option);
|
||||
return this.uiOption;
|
||||
}
|
||||
protected InitDrillType()
|
||||
{
|
||||
let drilltypes = [...userConfig.DrillConfigs.keys(), "不排"];
|
||||
if (drilltypes.length > 0)
|
||||
{
|
||||
if (!drilltypes.includes(this.option.drillType))
|
||||
this.option.drillType = drilltypes[0];
|
||||
}
|
||||
}
|
||||
InitOption()
|
||||
{
|
||||
Object.assign(this.option, DefaultR2b2Option, { remarks: Array.from({ length: 12 }, () => ["", ""]) });
|
||||
if (this.uiOption)
|
||||
Object.assign(this.uiOption, DataAdapter.ConvertUIData(this.option));
|
||||
}
|
||||
SaveConfig()
|
||||
{
|
||||
return {
|
||||
option: toJS(this.option)
|
||||
};
|
||||
}
|
||||
UpdateOption(conf: IConfigOption<IRect2Br2Option>)
|
||||
{
|
||||
Object.assign(this.option, conf.option);
|
||||
if (this.uiOption)
|
||||
Object.assign(this.uiOption, DataAdapter.ConvertUIData(conf.option));
|
||||
this.InitDrillType();
|
||||
}
|
||||
HasInvailValue()
|
||||
{
|
||||
return CheckoutValid.HasInvailValue(this.UIOption, CheckObjectType.R2B);
|
||||
}
|
||||
}
|
||||
|
||||
export const r2b2Store = new R2B2Store();
|
@ -0,0 +1,275 @@
|
||||
import { toJS } from "mobx";
|
||||
import { Box3, Matrix4, Object3D, Vector3 } from "three";
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { EBoardKeyList } from "../../Common/BoardKeyList";
|
||||
import { GetRectData } from "../../Common/CurveUtils";
|
||||
import { safeEval } from "../../Common/eval";
|
||||
import { Buy2To3 } from "../../Common/HostUrl";
|
||||
import { Log } from "../../Common/Log";
|
||||
import { FixDigits } from "../../Common/Utils";
|
||||
import { Board } from "../../DatabaseServices/Entity/Board";
|
||||
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
|
||||
import { Command } from "../../Editor/CommandMachine";
|
||||
import { PromptStatus } from "../../Editor/PromptResult";
|
||||
import { isParallelTo, XAxis, YAxis, ZAxis } from "../../Geometry/GeUtils";
|
||||
import { ClampSpaceParseRay } from "../../Geometry/SpaceParse/ClampSpaceParseRay";
|
||||
import { ISpaceParse } from "../../Geometry/SpaceParse/ISpaceParse";
|
||||
import { PointSelectBoards } from "../../Geometry/SpaceParse/PointSelectBoards";
|
||||
import { RenderType } from "../../GraphicsSystem/RenderType";
|
||||
import { AppConfirm } from "../../UI/Components/Common/Confirm";
|
||||
import { BoardType, FaceDirection } from "../../UI/Store/BoardInterface";
|
||||
import { TopPanelStore } from "../../UI/Store/TopPanelStore";
|
||||
import { R2b2Panel } from "./Modals/R2b2";
|
||||
import { r2b2Store } from "./R2B2Store";
|
||||
import { IRect2Br2Option } from "./R2bInterface";
|
||||
|
||||
|
||||
export class Rect2Board implements Command
|
||||
{
|
||||
async exec()
|
||||
{
|
||||
const tpStore = TopPanelStore.GetInstance() as TopPanelStore;
|
||||
|
||||
if (!tpStore.canUse2to3)
|
||||
{
|
||||
let res = await AppConfirm.show({ message: "您还未购买该增值包,前往购买?" });
|
||||
if (res)
|
||||
{
|
||||
window.open(Buy2To3);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let ss = await app.Editor.GetSelection({
|
||||
Msg: "请选择曲线:",
|
||||
UseSelect: true,
|
||||
Filter: { filterTypes: [Polyline] }
|
||||
});
|
||||
if (ss.Status === PromptStatus.Cancel) return;
|
||||
|
||||
let pls = ss.SelectSet.SelectEntityList as Polyline[];
|
||||
|
||||
app.Editor.ModalManage.RenderModal(R2b2Panel, { store: r2b2Store });
|
||||
|
||||
app.Editor.ModalManage.SetCallback(async () =>
|
||||
{
|
||||
await tool.Do(pls, toJS(r2b2Store.option));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const PlCache = new Map<Polyline, Polyline>();
|
||||
|
||||
class Rect2BoardTool2
|
||||
{
|
||||
private spaceParse: ISpaceParse;
|
||||
private _option: IRect2Br2Option;
|
||||
async Do(pls: Polyline[], option: IRect2Br2Option)
|
||||
{
|
||||
for (let [k,] of PlCache)
|
||||
k = null;
|
||||
PlCache.clear();
|
||||
|
||||
//默认认为用户传进来的pls都平行,都在一个平面内
|
||||
if (!pls || pls.length === 0) return;
|
||||
|
||||
this._option = option;
|
||||
|
||||
let ucs = new Matrix4().makeBasis(XAxis, ZAxis, YAxis.clone().negate());
|
||||
let ucsinv = new Matrix4().getInverse(ucs);
|
||||
// pls = pls.filter(pl => CurveInOCS(pl, ucs, ucsinv));
|
||||
|
||||
const clonePls: Polyline[] = [];
|
||||
for (let l of pls)
|
||||
{
|
||||
let cl = l.Clone();
|
||||
clonePls.push(cl);
|
||||
PlCache.set(cl, l);
|
||||
}
|
||||
const totalBrs: Board[] = [];
|
||||
|
||||
for (let pl of clonePls)
|
||||
{
|
||||
const box = pl.BoundingBox;
|
||||
const spaceParse = await this.GetSpaceParse(box);
|
||||
if (!spaceParse.ParseOK)
|
||||
{
|
||||
Log("没有对应的空间");
|
||||
return;
|
||||
}
|
||||
|
||||
pl.ApplyMatrix(spaceParse.SpaceOCSInv);
|
||||
if (!isParallelTo(pl.Normal, ZAxis))
|
||||
{
|
||||
pl.ApplyMatrix(ucsinv);
|
||||
}
|
||||
|
||||
pl.Position = pl.Position.setZ(0);
|
||||
this.ParsePolyline(pl);
|
||||
|
||||
this.spaceParse = spaceParse;
|
||||
|
||||
const size = spaceParse.Size;
|
||||
|
||||
const depth = safeEval(option.depthExpr, { L: size.x, W: size.y, H: size.z });
|
||||
|
||||
totalBrs.push(...this.DrawBoard([pl], depth));
|
||||
}
|
||||
|
||||
totalBrs.forEach(b => app.Database.ModelSpace.Append(b));
|
||||
}
|
||||
private ParsePolyline(pl: Polyline)
|
||||
{
|
||||
let firstDev = pl.GetFistDeriv(0);
|
||||
let size: Vector3;
|
||||
let box: Box3;
|
||||
if (isParallelTo(firstDev, XAxis) || isParallelTo(firstDev, YAxis))
|
||||
{
|
||||
box = pl.BoundingBox;
|
||||
size = box.getSize(new Vector3);
|
||||
}
|
||||
else
|
||||
{
|
||||
let rd = GetRectData(pl);
|
||||
if (rd.isRect)
|
||||
{
|
||||
pl.TempData = rd;
|
||||
box = rd.box;
|
||||
size = rd.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
box = pl.BoundingBox;
|
||||
size = box.getSize(new Vector3);
|
||||
}
|
||||
}
|
||||
pl.__CacheSize__ = size;
|
||||
pl.__CacheBox__ = box;
|
||||
}
|
||||
private async GetSpaceParse(box: Box3)
|
||||
{
|
||||
let center = box.getCenter(new Vector3);
|
||||
const objects: Object3D[] = [];
|
||||
for (let br of app.Database.ModelSpace.Entitys)
|
||||
{
|
||||
if (!br.IsErase && br.Visible && br instanceof Board)
|
||||
{
|
||||
objects.push(br.GetDrawObjectFromRenderType(RenderType.Physical));
|
||||
}
|
||||
}
|
||||
|
||||
app.Viewer.WorldToScreen(center);
|
||||
|
||||
let ptSelect = new PointSelectBoards(center, app.Viewer, objects);
|
||||
|
||||
const SpaceParse = new ClampSpaceParseRay(ptSelect.SelectBoards).SetRay(ptSelect.Ray);
|
||||
await SpaceParse.Parse();
|
||||
|
||||
return SpaceParse;
|
||||
}
|
||||
|
||||
DrawBoard(pls: Polyline[], depth: number)
|
||||
{
|
||||
let maxThickness = this._option.maxThickness;
|
||||
let spaceOCS = this.spaceParse.SpaceOCS;
|
||||
let min = this.spaceParse.SpaceBox.min;
|
||||
const verShrink = this._option.vertialShrink;
|
||||
const layShrink = this._option.layerShrink;
|
||||
const remarks: [string, string][] = [];
|
||||
for (let re of this._option.remarks)
|
||||
if (re[0] && re[1])
|
||||
{
|
||||
remarks.push([...re]);
|
||||
}
|
||||
|
||||
let layers: Board[] = [];
|
||||
let vertials: Board[] = [];
|
||||
|
||||
for (let pl of pls)
|
||||
{
|
||||
let size = pl.__CacheSize__ as Vector3;
|
||||
|
||||
let x = FixDigits(size.x);
|
||||
let y = FixDigits(size.y);
|
||||
|
||||
if (x < 10 || y < 10)
|
||||
{
|
||||
console.log("奇怪的矩形");
|
||||
continue;
|
||||
}
|
||||
let box = pl.__CacheBox__;
|
||||
let minp = box.min.clone();
|
||||
|
||||
let ocs: Matrix4;
|
||||
if (pl.TempData)
|
||||
{
|
||||
ocs = pl.TempData.OCS.clone();
|
||||
minp.applyMatrix4(pl.TempData.OCS);
|
||||
}
|
||||
|
||||
let br: Board;
|
||||
|
||||
let mtx = new Matrix4().makeBasis(XAxis, ZAxis.clone().negate(), YAxis);
|
||||
|
||||
let shrink = 0;
|
||||
|
||||
if (x > y && y <= maxThickness) //层板
|
||||
{
|
||||
br = Board.CreateBoard(x, depth - layShrink, y, BoardType.Layer);
|
||||
br.BoardProcessOption[EBoardKeyList.BigHole] = FaceDirection.Back;
|
||||
mtx.setPosition(new Vector3(x));
|
||||
shrink = layShrink;
|
||||
[minp.x, minp.y, minp.z] = [minp.x + x, minp.z, minp.y];
|
||||
layers.push(br);
|
||||
}
|
||||
else if (x < y && x <= maxThickness)//立板
|
||||
{
|
||||
br = Board.CreateBoard(y, depth - verShrink, x, BoardType.Vertical);
|
||||
[minp.x, minp.y, minp.z] = [minp.x, minp.z, minp.y];
|
||||
vertials.push(br);
|
||||
shrink = verShrink;
|
||||
}
|
||||
|
||||
if (!br) continue;
|
||||
PlCache.get(pl)?.Erase();
|
||||
|
||||
//被旋转的矩形
|
||||
let mtxInv = new Matrix4().getInverse(mtx);
|
||||
if (ocs)
|
||||
br.ApplyMatrix(mtx).ApplyMatrix(ocs).ApplyMatrix(mtxInv);
|
||||
|
||||
minp.y = min.y + shrink;
|
||||
|
||||
let m = new Matrix4().setPosition(minp);
|
||||
br.ApplyMatrix(m);
|
||||
br.ApplyMatrix(spaceOCS);
|
||||
// app.Database.ModelSpace.Append(br);
|
||||
|
||||
br.BoardProcessOption[EBoardKeyList.DrillType] = this._option[EBoardKeyList.DrillType];
|
||||
br.BoardProcessOption.highDrill = new Array(4).fill(this._option[EBoardKeyList.DrillType]);
|
||||
br.BoardProcessOption[EBoardKeyList.UpSealed] = this._option[EBoardKeyList.UpSealed];
|
||||
br.BoardProcessOption[EBoardKeyList.DownSealed] = this._option[EBoardKeyList.DownSealed];
|
||||
br.BoardProcessOption[EBoardKeyList.LeftSealed] = this._option[EBoardKeyList.LeftSealed];
|
||||
br.BoardProcessOption[EBoardKeyList.RightSealed] = this._option[EBoardKeyList.RightSealed];
|
||||
br.BoardProcessOption.remarks = remarks;
|
||||
if (this.spaceParse.Boards.length > 0)
|
||||
{
|
||||
let b = this.spaceParse.Boards[0];
|
||||
br.BoardProcessOption[EBoardKeyList.RoomName] = b.BoardProcessOption[EBoardKeyList.RoomName];
|
||||
br.BoardProcessOption[EBoardKeyList.CabinetName] = b.BoardProcessOption[EBoardKeyList.CabinetName];
|
||||
|
||||
br.BoardProcessOption[EBoardKeyList.BrMat] = b.BoardProcessOption[EBoardKeyList.BrMat];
|
||||
br.BoardProcessOption[EBoardKeyList.Color] = b.BoardProcessOption[EBoardKeyList.Color];
|
||||
br.BoardProcessOption[EBoardKeyList.Mat] = b.BoardProcessOption[EBoardKeyList.Mat];
|
||||
}
|
||||
}
|
||||
|
||||
for (let br of layers)
|
||||
{
|
||||
br.Subtract(vertials);
|
||||
}
|
||||
return [...vertials, ...layers];
|
||||
}
|
||||
}
|
||||
|
||||
const tool = new Rect2BoardTool2();
|
Loading…
Reference in new issue