diff --git a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap index c542ce8cf..ae314398f 100644 --- a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap +++ b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap @@ -54,13 +54,13 @@ exports[`复杂极限刀半径 3`] = `"2928.44167"`; exports[`复杂极限刀半径: 走刀数量 1`] = `3`; -exports[`复杂造型01 1`] = `"39413.77528"`; +exports[`复杂造型01 1`] = `"39413.77526"`; -exports[`复杂造型01 2`] = `"15808.94716"`; +exports[`复杂造型01 2`] = `"15808.94715"`; exports[`复杂造型01 3`] = `"4413.31745"`; -exports[`复杂造型01 4`] = `"1482.45521"`; +exports[`复杂造型01 4`] = `"1482.45520"`; exports[`复杂造型01 5`] = `"838.79070"`; diff --git a/__test__/Fillet/__snapshots__/polyline.test.ts.snap b/__test__/Fillet/__snapshots__/polyline.test.ts.snap index 2619b4686..0b0552137 100644 --- a/__test__/Fillet/__snapshots__/polyline.test.ts.snap +++ b/__test__/Fillet/__snapshots__/polyline.test.ts.snap @@ -18,12 +18,12 @@ exports[`双圆多段线倒角 8`] = `1200.7933322000163`; exports[`多段线闭合标志首尾有弧 1`] = `1357.0494514094473`; -exports[`多段线闭合标志首尾有弧 2`] = `1357.0494514094478`; +exports[`多段线闭合标志首尾有弧 2`] = `1357.0494514094473`; exports[`多段线闭合标志首尾有弧 3`] = `1357.049451409447`; exports[`多段线闭合标志首尾有弧 4`] = `1357.0494514094473`; -exports[`多段线首尾倒角有圆弧 1`] = `1682.5946408278244`; +exports[`多段线首尾倒角有圆弧 1`] = `1682.5946408278242`; exports[`多段线首尾倒角有圆弧 2`] = `1682.5946408278246`; diff --git a/__test__/JiajuImport/testxml2json.ts b/__test__/JiajuImport/testxml2json.ts new file mode 100644 index 000000000..7f86e99bd --- /dev/null +++ b/__test__/JiajuImport/testxml2json.ts @@ -0,0 +1,121 @@ +import * as fs from "fs-extra-plus"; +import { JSDOM } from "jsdom"; +import * as path from "path"; + +global.DOMParser = new JSDOM().window.DOMParser; +let xmlParser = new DOMParser(); + +let str = fs.readFileSync(path.resolve(__dirname, "./OrderBom.xml"), "utf-8"); + +let xmlDoc = xmlParser.parseFromString(str, "text/xml"); +let bomRoot = xmlDoc.children[0];//Bom +bomRoot.tagName;//? + +let json = xml2json(bomRoot); + +for (let i = 0; i < bomRoot.children.length; i++) +{ + let el = bomRoot.children.item(i); + el.tagName;//? + + if (el.tagName === "Products")//模型列表 + { + for (let j = 0; j < el.children.length; j++) + { + let productEl = el.children.item(j);//模型(里面有板( 柜子?)) + let categoryName = productEl.getAttribute("CategoryName");//? + let name = productEl.getAttribute("Name");//? + let roomId = productEl.getAttribute("RoomID"); //? + let pid = productEl.getAttribute("PID"); //? + let typeId = productEl.getAttribute("TypeID"); //? + + for (let i = 0; i < productEl.attributes.length; i++) + { + const att = productEl.attributes.item(i); + att.name;//? + att.value;//? + } + + //CategoryName ChannelID Coordinate Coordinate_Parent Name OrderID PID Pos Pos_Parent RoomID Rot Rot_Parent TypeID + + if (typeId === "") + { + let paramTable = getElementsByDepth(productEl, "ParamTable"); + let productss = getElementsByDepth(productEl, "Products"); + for (let products of productss) + for (let product of getElementsByDepth(products, "Product")) + { + console.log(product.tagName);//? + + let BoardMode = product.getAttribute("BoardMode"); + if (BoardMode) + { + console.log(BoardMode); + } + for (let i = 0; i < product.attributes.length; i++) + { + const att = product.attributes.item(i); + att.name;//? + att.value;//? + } + } + } + else if (typeId === "XianTiao") + { + console.log(); + + for (let k = 0; k < productEl.children.length; k++) + { + let item = productEl.children.item(k); + item.tagName;//? + if (item.tagName === "") + { + + } + else if (item.tagName === "Product") + { + + } + } + } + } + } +} + +function xml2json(el: Element, obj = {}) +{ + for (let i = 0; i < el.attributes.length; i++) + { + const att = el.attributes.item(i); + obj[att.name] = att.value; + } + + for (let i = 0; i < el.children.length; i++) + { + let cel = el.children.item(i); + let tagName = cel.tagName; + let arr = obj[tagName]; + if (arr) + arr.push(xml2json(cel)); + else + obj[tagName] = [xml2json(cel)]; + } + return obj; +} + +function getElementsByDepth(el: Element, tagname: string, depth: number = 1, res: Element[] = []) +{ + depth--; + + let children = el.children; + for (let i = 0; i < children.length; i++) + { + if (children[i].tagName === tagname) + { + res.push(children[i]); + if (depth > 0) + getElementsByDepth(children[i], tagname, depth, res); + } + } + return res; +}; diff --git a/package.json b/package.json index 58b114ed5..a908f448f 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@types/flatbush": "^3.3.0", "@types/html-webpack-plugin": "^3.2.6", "@types/jest": "^27.5.2", + "@types/jsdom": "^20.0.0", "@types/node": "^17.0.41", "@types/pako": "^1.0.4", "@types/polylabel": "^1.0.5", diff --git a/src/Add-on/JiaJu/Import/JiaJuImport.ts b/src/Add-on/JiaJu/Import/JiaJuImport.ts new file mode 100644 index 000000000..2ba9e6e32 --- /dev/null +++ b/src/Add-on/JiaJu/Import/JiaJuImport.ts @@ -0,0 +1,353 @@ +import { Intent } from "@blueprintjs/core"; +import { Box3, Matrix4, Vector3 } from "three"; +import { app } from "../../../ApplicationServices/Application"; +import { EBoardKeyList } from "../../../Common/BoardKeyList"; +import { FileSystem } from "../../../Common/FileSystem"; +import { JigMoveEntity } from "../../../Common/JigMove"; +import { Contour } from "../../../DatabaseServices/Contour"; +import { Database } from "../../../DatabaseServices/Database"; +import { Arc } from "../../../DatabaseServices/Entity/Arc"; +import { Board } from "../../../DatabaseServices/Entity/Board"; +import { Entity } from "../../../DatabaseServices/Entity/Entity"; +import { Line } from "../../../DatabaseServices/Entity/Line"; +import { Polyline } from "../../../DatabaseServices/Entity/Polyline"; +import { HardwareCompositeEntity } from "../../../DatabaseServices/Hardware/HardwareCompositeEntity"; +import { Shape } from "../../../DatabaseServices/Shape"; +import { TemplateRecord } from "../../../DatabaseServices/Template/TemplateRecord"; +import { Command, CommandWrap } from "../../../Editor/CommandMachine"; +import { equaln, XAxis, YAxis, ZAxis } from "../../../Geometry/GeUtils"; +import { AppToaster } from "../../../UI/Components/Toaster"; +import { BoardType, FaceDirection, LinesType } from "../../../UI/Store/BoardInterface"; +import { CuttingBoardByBoard } from "../../BoardCutting/CuttingUtils2"; +import { IBoardRectHoleType, SetBrHighHoleTypeFromRectHoleType } from "../../DrawDrilling/HoleUtils"; + + +let _xmlParse: DOMParser; +export function xmlStr2Json(xmlStr: string) +{ + if (!_xmlParse) _xmlParse = new DOMParser; + let xmlDoc = _xmlParse.parseFromString(xmlStr, "text/xml"); + return xml2json(xmlDoc.children[0]); +} + +function xml2json(el: Element, obj = {}) +{ + for (let i = 0; i < el.attributes.length; i++) + { + const att = el.attributes.item(i); + obj[att.name] = att.value; + } + + for (let i = 0; i < el.children.length; i++) + { + let cel = el.children.item(i); + let tagName = cel.tagName; + let arr = obj[tagName]; + if (arr) + arr.push(xml2json(cel)); + else + obj[tagName] = [xml2json(cel)]; + } + return obj; +} + +export class Command_JiaJuImport implements Command +{ + async exec() + { + FileSystem.ChooseFile({ + filter: ".xml", + multiple: false, + callback: async (files) => + { + for (let i = 0; i < files.length; i++) + { + let xmlFile = files.item(i); + await ImportJiajuFile(xmlFile); + } + } + }); + } +} + +export async function ImportJiajuFile(xmlFile: File) +{ + let xmlStr = await xmlFile.text(); + try + { + let jsonObj = xmlStr2Json(xmlStr); + await ImportJiaJuData(jsonObj as JiaJu.Bom); + } + catch (error) + { + AppToaster.show({ + message: `${xmlFile.name}导入失败!`, + timeout: 5000, + intent: Intent.WARNING, + }); + } +} + +export async function ImportJiaJuData(bom: JiaJu.Bom) +{ + CommandWrap(async () => + { + new JiaJuParse(bom, app.Database).Do(); + + let ents = app.CommandReactor._createObejcts.filter(obj => obj instanceof Entity) as Entity[]; + + let brs = ents.filter(en => en instanceof Board) as Board[]; + let hws = ents.filter(en => en instanceof HardwareCompositeEntity).filter(hw => (hw as HardwareCompositeEntity).HardwareOption.isHole) as HardwareCompositeEntity[]; + + if (ents.length === 0) + return true; + + let box = new Box3; + for (let en of ents) + box.union(en.BoundingBox); + + app.Editor.GetPointServices.snapServices.FilterEntitys = new Set(ents); + let ok = await JigMoveEntity(ents, box.isEmpty() ? undefined : box.min); + app.Editor.GetPointServices.snapServices.FilterEntitys = undefined; + + if (ok) + { + if (brs.length !== 0) + { + app.Editor.Prompt("开始计算薄背板拉槽!"); + let bbrs: Board[] = []; + let allBrs: Board[] = []; + for (let br of brs) + { + if (br.IsKnife)//br.BoardType === BoardType.Behind + bbrs.push(br); + else + allBrs.push(br); + } + + CuttingBoardByBoard(allBrs, bbrs); + } + + //直接调用五金挖孔 + await app._hardwareCuttingReactor.StartReactor(hws, new Set); + } + return !ok; + }, "JiaJuImport"); + +} + +/** + */ +class JiaJuParse +{ + RoomIdNameMap = new Map(); + + constructor( + public bom: JiaJu.Bom, + public curDb: Database, + ) + { + + } + + Do() + { + this.ParseRoomNameMap(); + for (let ps of this.bom.Products[0].Product) + this.ParseProduct(ps);//第一层 + } + + ParseRoomNameMap() + { + for (let room of this.bom.Rooms[0].Room) + this.RoomIdNameMap.set(room.ID, room.Name); + } + + ParseProduct(product: JiaJu.ProductBase, parentName: string = "", parentRoomName: string = ""): TemplateRecord | Entity + { + if (product.ObjType === "Board")//(product as JiaJu.EntityProduct).BoardMode + { + return this.ParseBoardParseBoard(product as JiaJu.EntityProduct, parentRoomName, parentName); + } + else if (product.ObjType === "Cabinet" || product.ObjType === "CabinetDoor" || product.ObjType === "Group")//组 + // || product.TypeID === "" || product.TypeID === "GuiTi" + { + parentRoomName = this.RoomIdNameMap.get((product as JiaJu.ModelProduct).RoomID) ?? parentRoomName; + parentName = product.Name ?? parentName; + + let template = new TemplateRecord().InitBaseParams(); + template.Name = parentName; + this.curDb.TemplateTable.Add(template); + + for (let p of (product as JiaJu.ModelProduct).Products[0].Product) + { + let obj = this.ParseProduct(p, parentName, parentRoomName); + if (obj instanceof Entity) + template.Objects.push(obj.Id); + else if (obj instanceof TemplateRecord) + template.Children.push(obj.Id); + } + + return template; + } + + else if (product.ObjType === "Decoration")//装饰品 五金(拉手 铰链?) + { + } + else if (product.ObjType === "TopLine")//顶线 + { + } + else if (product.ObjType === "SweepLine")// + { + } + } + + //解析板件实体 + ParseBoardParseBoard(entityProduct: JiaJu.EntityProduct, roomName: string, cabName: string): Board + { + let paramTable = entityProduct.ParamTable[0]; + + let br = new Board(); + br.Name = entityProduct.Name ?? paramTable.NAME ?? ""; + br.BoardProcessOption[EBoardKeyList.Mat] = paramTable.MTL_NAME ?? ""; + br.BoardProcessOption[EBoardKeyList.BrMat] = paramTable.MTL_NAME ?? ""; + br.BoardProcessOption[EBoardKeyList.RoomName] = roomName; + br.BoardProcessOption[EBoardKeyList.CabinetName] = cabName; + + //outline + let outline = entityProduct.OutLines[0]; + let path = outline.Path[0]; + + br.ContourCurve = JiajuPath2Polyline(path); + + let modelPth = outline.ModelPath[0]; + br.Thickness = parseFloat(modelPth.GeCurve[0].EndZ); + + //holes + if (outline.Hole) + { + let holes: Polyline[] = []; + for (let hole of outline.Hole) + if (hole.GeCurve) + holes.push(JiajuPath2Polyline(hole)); + + if (holes.length) + { + br.BoardModeling = holes.map(h => + { + return { + shape: new Shape(Contour.CreateContour(h)), + thickness: br.Thickness, + dir: FaceDirection.Front, + addLen: 0, + addWidth: 0, + addDepth: 0, + knifeRadius: 3, + }; + }); + } + } + + //板件类型 + let roMat = new Matrix4; + if (entityProduct.BoardMode === "SIDEBOARD") + { + br.SetBoardType(BoardType.Vertical); + br.ColorIndex = 11; + roMat = br.RotateMat; + } + else if (entityProduct.BoardMode === "HORIZONTALBOARD") + { + br.SetBoardType(BoardType.Layer); + br.ColorIndex = 2; + } + else + { + br.SetBoardType(BoardType.Behind); + br.ColorIndex = 3; + roMat.makeBasis(ZAxis, XAxis, YAxis); + } + + + let lineIsRev = equaln(parseFloat(paramTable.MTL_DIR), 90, 0.1);//竖纹 + //纹路 + if (br.BoardType === BoardType.Behind) + br.BoardProcessOption.lines = lineIsRev ? LinesType.Reverse : LinesType.Positive; + else + br.BoardProcessOption.lines = lineIsRev ? LinesType.Positive : LinesType.Reverse; + + //排钻 + const holeType: IBoardRectHoleType = { + up: equaln(parseFloat(paramTable.LINK_UP), 1, 0.1) ? "三合一" : "不排", + down: equaln(parseFloat(paramTable.LINK_DOWN), 1, 0.1) ? "三合一" : "不排", + left: equaln(parseFloat(paramTable.LINK_LEFT), 1, 0.1) ? "三合一" : "不排", + right: equaln(parseFloat(paramTable.LINK_RIGHT), 1, 0.1) ? "三合一" : "不排", + }; + SetBrHighHoleTypeFromRectHoleType(br, holeType); + + //封边 + let edgeType = equaln(parseFloat(paramTable.EDGE), 1, 0.1); + if (edgeType)//三薄一厚 + { + br.BoardProcessOption.sealedDown = "1"; + br.BoardProcessOption.sealedUp = "1"; + br.BoardProcessOption.sealedLeft = "1"; + br.BoardProcessOption.sealedRight = "1"; + + if (br.BoardType === BoardType.Layer) + br.BoardProcessOption.sealedDown = "2"; + else if (br.BoardType === BoardType.Vertical) + br.BoardProcessOption.sealedLeft = "2"; + } + else//全厚 === 2? + { + br.BoardProcessOption.sealedDown = "2"; + br.BoardProcessOption.sealedUp = "2"; + br.BoardProcessOption.sealedLeft = "2"; + br.BoardProcessOption.sealedRight = "2"; + } + + //坐标系变换 + //旋转 + br.ApplyMatrix(roMat); + + //左后下 + let box = br.BoundingBox; + br.Move(box.min.setY(box.max.y).negate()); + + //位置 + let mtx = new Matrix4().fromArray(entityProduct.Coordinate.split(",").map(parseFloat)); + br.ApplyMatrix(mtx); + + this.curDb.ModelSpace.Append(br); + return br; + } +} + + +function JiajuPath2Polyline(path: JiaJu.Path) +{ + let cus: (Line | Arc)[] = []; + for (let geCurve of path.GeCurve) + { + let p1 = new Vector3(parseFloat(geCurve.StartX), parseFloat(geCurve.StartY)); + let p2 = new Vector3(parseFloat(geCurve.EndX), parseFloat(geCurve.EndY)); + + if (geCurve.GeCurveType === "Seg") + cus.push(new Line(p1, p2)); + else + { + let arc = new Arc(new Vector3(parseFloat(geCurve.ArcCenX), parseFloat(geCurve.ArcCenY), parseFloat(geCurve.ArcCenZ))); + arc.Radius = arc.Center.distanceTo(p1); + arc.IsClockWise = false; + arc.StartAngle = arc.GetAngleAtPoint(p1); + arc.EndAngle = arc.GetAngleAtPoint(p2); + cus.push(arc); + } + } + + let polyline = Polyline.Combine(cus, 1e-3); + polyline.CloseMark = true; + + return polyline; +} diff --git a/src/Add-on/JiaJu/Import/JiaJuInterface.ts b/src/Add-on/JiaJu/Import/JiaJuInterface.ts new file mode 100644 index 000000000..7e5c48abf --- /dev/null +++ b/src/Add-on/JiaJu/Import/JiaJuInterface.ts @@ -0,0 +1,215 @@ +//ref: https://quicktype.io/typescript +namespace JiaJu +{ + export interface Bom + { + Rooms: Rooms[];//房间信息 + Orders: Order[];//订单信息 + Products: [Products];//产品模型集合 + Other: []; //扩展节点 + } + + + type Rot = string;//四元数 0,0,0,0 + + export interface Rooms + { + Room: Room[]; + } + + export interface Room + { + ID: string; + Name: string; + Path: Path[]; + } + + export interface Order + { + } + + export interface Products + { + Product: ModelProduct[]; + } + + //类别名称(在Produce中) + export enum CategoryName + { + Empty = "", + 衣柜 = "衣柜", + } + + export interface ProductBase + { + CategoryName: CategoryName;//类别名称 + ChannelID: string;//求导编码 + PID: string;//模型实例ID + OrderID: string; + TypeID: "" | "XianTiao" | "GuiTi";//类型识别码 太复杂了 + ObjType: "CabinetDoor" | "Cabinet" | "Group" | + "Board" | "Decoration" | "TopLine" | "SweepLine"; + TypeLabel: string; + + Name: string;//名称 + + //位置相关 + Coordinate: string;//世界坐标 + Coordinate_Parent: string; + Pos: string;//世界点坐标 + Pos_Parent: string;//相对点坐标 + Rot: Rot;//世界坐标旋转 + Rot_Parent: Rot;//相对旋转 + } + + //模型(第一层) + export interface ModelProduct extends ProductBase + { + RoomID: string;//房间ID + + ParamTable: ModelParamTable[]; + Products: [ModelProducts]; + } + + //模型参数表(第一层) + export interface ModelParamTable + { + CODE: string; + D: string; + DATE: Date; + EXTEND_BACK: string; + EXTEND_DOWN: string; + EXTEND_FRONT: string; + EXTEND_LEFT: string; + EXTEND_RIGHT: string; + EXTEND_UP: string; + FRAME_ID: string; + H: string; + HIDE_FLAG: string; + ID: string; + IS_QUOTED: string; + MTL: string; + MTL_BASE: string; + MTL_BYOWNER: string; + MTL_DIR: string; + MTL_NAME: string; + MTL_SALENAME: string; + NAME: string; + OPEN_STATUS: string; + PRO_NOTES: string; + QUOTE_CODE: string; + RD: string; + RH: string; + RW: string; + SALES_MARKET: string; + SERIESID: string; + SPRAY_MATRIAL: string; + STD: string; + W: string; + YG_AZBZ: string; + YG_SJBZ: string; + YG_TJZJ_H: string; + YG_TJZJ_H1: string; + } + + export interface ModelProducts + { + Product: EntityProduct[]; + } + + export interface EntityProduct extends ProductBase + { + BoardMode?: "SIDEBOARD" | "FORWARDBOARD" | "HORIZONTALBOARD";//板类型 + + ParamTable: EntityParamTable[]; + OutLines?: OutLine[]; + } + + export interface OutLine + { + Path: Path[]; + ModelPath: Path[];//拉伸轮廓 + Hole?: Path[]; + } + + export interface Path + { + GeCurve: GeCurve[]; + } + + export interface GeCurve + { + End: string; + EndX: string; + EndY: string; + EndZ: string; + GeCurveType: GeCurveType; + Start: string; + StartX: string; + StartY: string; + StartZ: string; + + //圆弧 + ArcCenX: string; + ArcCenY: string; + ArcCenZ: string; + + ArcCen: string;//xyz + } + + export enum GeCurveType + { + Seg = "Seg", + Arc = "Arc",//逆时针 + } + + + export interface EntityParamTable + { + CODE: string; + D: string; + EXTEND_BACK: string; + EXTEND_DOWN: string; + EXTEND_FRONT: string; + EXTEND_LEFT: string; + EXTEND_RIGHT: string; + EXTEND_UP: string; + FRAME_ID?: string; + H: string; + HANDLE_ANG?: string; + HANDLE_HEIGHT?: string; + HANDLE_HOLECOUNT?: string; + HANDLE_PITCHROW?: string; + HANDLE_TYPE?: string; + HANDLE_YVALUE?: string; + HIDE_FLAG: string; + ID: string; + IS_QUOTED: string; + MTL: string; + MTL_BYOWNER: string; + MTL_DIR: string; + NAME: string; + OPEN_STATUS: string; + PRO_NOTES: string; + QUOTE_CODE: string; + RD: string; + RH: string; + RW: string; + STD: string; + W: string; + ABNORMAL?: string; + DISP_BORDER?: string; + EDGE?: string; + LINK_DOWN?: string; + LINK_LEFT?: string; + LINK_RIGHT?: string; + LINK_UP?: string; + MTL_BASE?: string; + MTL_NAME?: string; + MTL_SALENAME?: string; + MTL_SIDE?: string; + SALES_MARKET?: string; + YG_AZBZ?: string; + YG_SJBZ?: string; + } +} diff --git a/src/ApplicationServices/Application.ts b/src/ApplicationServices/Application.ts index bda1cda6f..1eea08871 100644 --- a/src/ApplicationServices/Application.ts +++ b/src/ApplicationServices/Application.ts @@ -6,6 +6,7 @@ import { HardwareCuttingReactor } from '../Add-on/BoardCutting/HardwareCuttingRe import { DrillingReactor } from '../Add-on/DrawDrilling/DrillingReactor'; import { DwgDxfImport } from '../Add-on/DXFLoad'; import { AppendUserInfo } from '../Add-on/ExportData'; +import { ImportJiajuFile } from '../Add-on/JiaJu/Import/JiaJuImport'; import { ImportKJLData } from '../Add-on/KJL/Import/KJLImport'; import { CommandNames } from '../Common/CommandNames'; import { IsDev } from '../Common/Deving'; @@ -339,6 +340,7 @@ export class ApplicationService { let cadfiles: File[] = []; let jsonFiles: File[] = []; + let xmlFiles: File[] = []; for (let i = 0; i < e.dataTransfer.files.length; i++) { let f = e.dataTransfer.files.item(i); @@ -353,6 +355,11 @@ export class ApplicationService e.preventDefault(); jsonFiles.push(f); } + else if (ext === ".XML") + { + e.preventDefault(); + xmlFiles.push(f); + } } const exec = async () => @@ -376,6 +383,13 @@ export class ApplicationService await ImportKJLData(obj); } } + if (xmlFiles.length) + { + for (let xmlFile of xmlFiles) + { + ImportJiajuFile(xmlFile); + } + } }; exec(); diff --git a/src/Common/CommandNames.ts b/src/Common/CommandNames.ts index 8ed9a9438..86016fa32 100644 --- a/src/Common/CommandNames.ts +++ b/src/Common/CommandNames.ts @@ -6,6 +6,7 @@ export enum CommandNames KJLCongfig = "KJLCONFIG", KJLMaterialMap = "KJLMATERIALMAP", Clearkjltoken = "CLEARKJLTOKEN", + JiaJuImport = "JIAJUIMPORT", Group = "GROUP", DXFImport = "DXF", DWGImport = "DWG", diff --git a/src/DatabaseServices/Entity/Entity.ts b/src/DatabaseServices/Entity/Entity.ts index 3b3727644..05c09cf94 100644 --- a/src/DatabaseServices/Entity/Entity.ts +++ b/src/DatabaseServices/Entity/Entity.ts @@ -2,7 +2,7 @@ import { Material, Matrix3, Matrix4, MeshStandardMaterial, Object3D, Vector3 } f import { iaop } from 'xaop'; import { HostApplicationServices } from '../../ApplicationServices/HostApplicationServices'; import { DisposeThreeObj, Object3DRemoveAll } from '../../Common/Dispose'; -import { matrixIsCoplane, MatrixPlanarizere } from '../../Common/Matrix4Utils'; +import { matrixIsCoplane, MatrixPlanarizere, tempMatrix1 } from '../../Common/Matrix4Utils'; import { UpdateDraw } from '../../Common/Status'; import { ObjectSnapMode } from '../../Editor/ObjectSnapMode'; import { Box3Ext } from '../../Geometry/Box'; @@ -194,17 +194,8 @@ export class Entity extends CADObject Move(v: Vec3) { if (equaln(v.x, 0) && equaln(v.y, 0) && equaln(v.z, 0)) return; - - this.WriteAllObjectRecord(); - - this._Matrix.elements[12] += v.x; - this._Matrix.elements[13] += v.y; - this._Matrix.elements[14] += v.z; - - this._SpaceOCS.elements[12] += v.x; - this._SpaceOCS.elements[13] += v.y; - this._SpaceOCS.elements[14] += v.z; - this.Update(UpdateDraw.Matrix); + tempMatrix1.identity().setPosition(v.x, v.y, v.z); + this.ApplyMatrix(tempMatrix1); return this; } @@ -214,14 +205,7 @@ export class Entity extends CADObject let moveY = pt.y - this._Matrix.elements[13]; let moveZ = pt.z - this._Matrix.elements[14]; - if (moveX === 0 && moveY === 0 && moveZ === 0) return; - - this.WriteAllObjectRecord(); - this._Matrix.setPosition(pt); - this._SpaceOCS.elements[12] += moveX; - this._SpaceOCS.elements[13] += moveY; - this._SpaceOCS.elements[14] += moveZ; - this.Update(UpdateDraw.Matrix); + this.Move({ x: moveX, y: moveY, z: moveZ }); } get Z() { return this._Matrix.elements[14]; } diff --git a/src/DatabaseServices/Entity/Polyline.ts b/src/DatabaseServices/Entity/Polyline.ts index 41621d514..40c756d0c 100644 --- a/src/DatabaseServices/Entity/Polyline.ts +++ b/src/DatabaseServices/Entity/Polyline.ts @@ -1363,6 +1363,21 @@ export class Polyline extends Curve return box; } + SetPtsBuls(pts: Vector2[], buls: number[]) + { + this.WriteAllObjectRecord(); + this._LineData.length = 0; + for (let i = 0; i < pts.length; i++) + { + let pt = pts[i]; + let bul = buls[i]; + + this._LineData.push({ pt, bul }); + } + this.Update(); + return this; + } + /** * 得到曲线有用的点表和凸度(闭合曲线首尾重复) */ diff --git a/src/Editor/CommandRegister.ts b/src/Editor/CommandRegister.ts index dec028ee1..b20fffb4a 100644 --- a/src/Editor/CommandRegister.ts +++ b/src/Editor/CommandRegister.ts @@ -136,6 +136,7 @@ import { Command_Group, Command_UnGroup } from "../Add-on/Group"; import { Command_HideSelected, Command_HideUnselected, Command_ShowAll, Command_SwitchDoor, SelectAll, ShowHideSelectPanel } from "../Add-on/HideSelected"; import { Command_Insert } from "../Add-on/Insert"; import { Command_INsTest } from "../Add-on/instest"; +import { Command_JiaJuImport } from "../Add-on/JiaJu/Import/JiaJuImport"; import { Command_Join } from "../Add-on/Join"; import { Command_KJLImport } from "../Add-on/KJL/Import/KJLImport"; import { ClearKjlToken, KjlExport } from "../Add-on/KJL/KjlExport"; @@ -281,6 +282,9 @@ export function registerCommand() commandMachine.RegisterCommand(CommandNames.KJLExport, new KjlExport()); commandMachine.RegisterCommand(CommandNames.Clearkjltoken, new ClearKjlToken()); + //嘉居 + commandMachine.RegisterCommand(CommandNames.JiaJuImport, new Command_JiaJuImport()); + //编组 commandMachine.RegisterCommand(CommandNames.Group, new Command_Group()); commandMachine.RegisterCommand(CommandNames.UnGroup, new Command_UnGroup()); diff --git a/src/UI/Components/CommandPanel/CommandList.ts b/src/UI/Components/CommandPanel/CommandList.ts index 263c25082..8e5988fa8 100644 --- a/src/UI/Components/CommandPanel/CommandList.ts +++ b/src/UI/Components/CommandPanel/CommandList.ts @@ -2129,6 +2129,15 @@ export const CommandList: ICommand[] = [ chName: "清除酷家乐令牌", chDes: "清除酷家乐令牌", }, + { + typeId: "util", + link: `#`, + defaultCustom: "JJ", + command: CommandNames.JiaJuImport, + type: "工具", + chName: "嘉居导入", + chDes: "从嘉居导入数据", + }, { typeId: "util", link: `#`,