From 96856c75e06791a1307dcc72d95e27561a757bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E4=B8=89?= <940119273@qq.com> Date: Wed, 3 Apr 2024 03:22:27 +0000 Subject: [PATCH] =?UTF-8?q?!2581=20=E4=BC=98=E5=8C=96:ROTATE=E6=97=8B?= =?UTF-8?q?=E8=BD=AC=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BD=BF=E7=94=A8=E2=80=9C?= =?UTF-8?q?C=E2=80=9D=E5=85=B3=E9=94=AE=E5=AD=97=E6=97=B6COPY=E5=AE=9E?= =?UTF-8?q?=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Add-on/Copy.ts | 462 ++++++++++++++++++++++--------------------- src/Add-on/Rotate.ts | 18 +- 2 files changed, 249 insertions(+), 231 deletions(-) diff --git a/src/Add-on/Copy.ts b/src/Add-on/Copy.ts index 949b6e4dc..2d6a7ea8c 100644 --- a/src/Add-on/Copy.ts +++ b/src/Add-on/Copy.ts @@ -1,4 +1,5 @@ import { Intent } from '@blueprintjs/core'; +import { Matrix4 } from 'three'; import { app } from '../ApplicationServices/Application'; import { Log, LogType } from '../Common/Log'; import { DuplicateRecordCloning } from '../Common/Status'; @@ -73,41 +74,7 @@ export class Command_Copy implements Command let ptBase = ptRes.Point; let ptLast = ptBase.clone(); - let oens = ssRes.SelectSet.SelectEntityList; - oens = RemoveRoomAutoGenEntity(oens); - let olds = new Set(oens); - let jens = oens.map(e => JigUtils.Draw(e)); - for (let e of oens) e.DrawObject.visible = true; - - //#region 拷贝实体 - let tempDb = new Database(false, false, true); - let filer = new WblockCloneFiler2(); - let idMap: IdMaping = new Map(); - - let nens = tempDb.WblockCloneObejcts(oens, app.Viewer.isLayout ? tempDb.LayoutSpace : tempDb.ModelSpace, idMap, DuplicateRecordCloning.Ignore, filer) as Entity[]; - let news = new Set(nens); - let idMapRev: IdMaping = new Map(); - for (let [k, v] of idMap) idMapRev.set(v, k); - - for (let e of tempDb.ModelSpace.Entitys) - { - if (news.has(e)) continue; - //板件删除时会清除关联的排钻 我们不想清除 - if (e instanceof Board) - { - e.DrillList.clear(); - e.LayerNails.length = 0; - } - - e.GoodBye(); - tempDb.DeleteId(e.Id.Index);//否则查到引用仍然拷贝 - } - - Purge(tempDb); - PurgeTemplateTreeRoot(tempDb); - //#endregion - - let dbens = app.Viewer.isLayout ? tempDb.LayoutSpace.Entitys : tempDb.ModelSpace.Entitys.concat(tempDb.Lights.Entitys); + const { copyEnts, dbEnts, idMapRev, idMap, oldEntsSet } = GetCopyEntsParam(ssRes.SelectSet.SelectEntityList); while (true) { @@ -120,7 +87,7 @@ export class Command_Copy implements Command { let moveM = MoveMatrix(p.clone().sub(ptLast)); ptLast.copy(p); - for (let e of jens) + for (let e of copyEnts) e.ApplyMatrix(moveM); }, BasePoint: ptRes.Point, @@ -130,232 +97,275 @@ export class Command_Copy implements Command if (ptRes2.Status === PromptStatus.OK) { let moveM = MoveMatrix(ptRes2.Point.sub(ptBase)); + HardCloneObject(dbEnts, moveM, idMapRev, idMap, oldEntsSet); + } + else + break; + } + } +} - let filer2 = new WblockCloneFiler2(); - let idMap2: IdMaping = new Map(); +export function GetCopyEntsParam(originalEnts: Entity[]): { copyEnts: Entity[]; dbEnts: Entity[]; idMapRev: IdMaping; idMap: IdMaping; oldEntsSet: Set; } +{ + originalEnts = RemoveRoomAutoGenEntity(originalEnts); + let oldEntsSet = new Set(originalEnts); + let copyEnts = originalEnts.map(e => JigUtils.Draw(e)); + for (let e of originalEnts) e.DrawObject.visible = true; + + //#region 拷贝实体 + let tempDb = new Database(false, false, true); + let filer = new WblockCloneFiler2(); + let idMap: IdMaping = new Map(); + + let newEnts = tempDb.WblockCloneObejcts(originalEnts, app.Viewer.isLayout ? tempDb.LayoutSpace : tempDb.ModelSpace, idMap, DuplicateRecordCloning.Ignore, filer) as Entity[]; + let newEntsSet = new Set(newEnts); + let idMapRev: IdMaping = new Map(); + for (let [k, v] of idMap) idMapRev.set(v, k); + + for (let e of tempDb.ModelSpace.Entitys) + { + if (newEntsSet.has(e)) continue; + //板件删除时会清除关联的排钻 我们不想清除 + if (e instanceof Board) + { + e.DrillList.clear(); + e.LayerNails.length = 0; + } - let blkRec = app.Viewer.isLayout ? app.Database.LayoutSpace : app.Database.ModelSpace; - let newEns = app.Database.WblockCloneObejcts(dbens, blkRec, idMap2, DuplicateRecordCloning.Ignore, filer2) as Entity[]; + e.GoodBye(); + tempDb.DeleteId(e.Id.Index); //否则查到引用仍然拷贝 + } - let idMap2Rev: IdMaping = new Map(); - for (let [k, v] of idMap2) idMap2Rev.set(v, k); + Purge(tempDb); + PurgeTemplateTreeRoot(tempDb); + //#endregion + let dbEnts = app.Viewer.isLayout ? tempDb.LayoutSpace.Entitys : tempDb.ModelSpace.Entitys.concat(tempDb.Lights.Entitys); + return { copyEnts, dbEnts, idMapRev, idMap, oldEntsSet }; +} - for (let e of newEns) e.ApplyMatrix(moveM); +export function HardCloneObject(dbAllEnts: Entity[], mtx: Matrix4, idMapRev: IdMaping, idMap: IdMaping, oldEntsSet: Set) +{ + let filer2 = new WblockCloneFiler2(); + let idMap2: IdMaping = new Map(); - //新id倒推旧id - function GetOldObjectId(newObjectId: ObjectId) - { - let idTempDb = idMap2Rev.get(newObjectId); - return idMapRev.get(idTempDb); - } - //旧id倒推新id - function GetNewObjectId(oldObjectId: ObjectId) - { - let id = idMap.get(oldObjectId); - return idMap2.get(id); - } + let blkRec = app.Viewer.isLayout ? app.Database.LayoutSpace : app.Database.ModelSpace; + let newEns = app.Database.WblockCloneObejcts(dbAllEnts, blkRec, idMap2, DuplicateRecordCloning.Ignore, filer2) as Entity[]; - //已经修复的排钻 - let repHoled = new Set(); + let idMap2Rev: IdMaping = new Map(); + for (let [k, v] of idMap2) idMap2Rev.set(v, k); - for (let e of newEns) - { - if (e instanceof Board) - { - let oldId = GetOldObjectId(e.Id); - let oldBr = oldId.Object as Board; + for (let e of newEns) e.ApplyMatrix(mtx); - let temp = e.Clone(); + //新id倒推旧id + function GetOldObjectId(newObjectId: ObjectId) + { + let idTempDb = idMap2Rev.get(newObjectId); + return idMapRev.get(idTempDb); + } + //旧id倒推新id + function GetNewObjectId(oldObjectId: ObjectId) + { + let id = idMap.get(oldObjectId); + return idMap2.get(id); + } - for (let id of oldBr.RelevanceKnifs) - { - if (!id || id.IsErase) continue; + //已经修复的排钻 + let repHoled = new Set(); - let br = id.Object as Board;//关联刀默认为板 - if (olds.has(br)) continue;//已经拷贝 + for (let e of newEns) + { + if (e instanceof Board) + { + let oldId = GetOldObjectId(e.Id); + let oldBr = oldId.Object as Board; - if (temp.Subtract([br], [], true)) - e.RelevanceSubtract(br, true);//关联切割重新绑定 - } + let temp = e.Clone(); - for (let id of oldBr.RelevanceMeats) - { - if (!id || id.IsErase) continue; + for (let id of oldBr.RelevanceKnifs) + { + if (!id || id.IsErase) continue; - let br = id.Object as Board;//关联刀默认为板 - if (olds.has(br)) continue;//已经拷贝 + let br = id.Object as Board; //关联刀默认为板 + if (oldEntsSet.has(br)) continue; //已经拷贝 - if (br.Clone().Subtract([e], [], true)) - br.RelevanceSubtract(e, true);//关联切割重新绑定 - } - e.CopyInRenderTpye = userConfig.RenderType; - // oldBr.RelativeHardware; //关联的五金肯定没办法重新关联 - } - else if (e instanceof CylinderHole && e.Type === GangDrillType.Nail)//层板钉 - { - let oldId = GetOldObjectId(e.Id); - let oldE = oldId.Object as CylinderHole; - if (!e.FId || e.FId.IsErase) //立板没拷贝 - { - if (oldE.FId && !oldE.FId.IsErase) - { - let oldBr = oldE.FId.Object as Board; - if (HoleInBoard([e], oldBr)) - { - e.FId = oldBr.Id; - oldBr.AppendNails([e.Id]); - } - } - } + if (temp.Subtract([br], [], true)) + e.RelevanceSubtract(br, true); //关联切割重新绑定 + } - if (!e.MId || e.MId.IsErase)//层板没拷贝 - { - if (oldE.MId && !oldE.MId.IsErase) - { - let oldBr = oldE.MId.Object as Board; - { - e.MId = oldBr.Id; - oldBr.AppendNails([e.Id]); - } - } - } + for (let id of oldBr.RelevanceMeats) + { + if (!id || id.IsErase) continue; - //处理通孔(如果通孔没拷贝,那么移除通孔属性)(这里没有考虑到图纸中的对象可能会组成新的通孔) - if (oldE.OtherHalfTongKong) - { - if (!olds.has(oldE.OtherHalfTongKong.Object as Entity)) - { - e.OtherHalfTongKong = null; - if (e instanceof CylinderHole) - e.Type = GangDrillType.Ymj; - else - (e as ExtrudeHole).isThrough = false; - } - } + let br = id.Object as Board; //关联刀默认为板 + if (oldEntsSet.has(br)) continue; //已经拷贝 + + if (br.Clone().Subtract([e], [], true)) + br.RelevanceSubtract(e, true); //关联切割重新绑定 + } + e.CopyInRenderTpye = userConfig.RenderType; + // oldBr.RelativeHardware; //关联的五金肯定没办法重新关联 + } + else if (e instanceof CylinderHole && e.Type === GangDrillType.Nail) //层板钉 + { + let oldId = GetOldObjectId(e.Id); + let oldE = oldId.Object as CylinderHole; + if (!e.FId || e.FId.IsErase) //立板没拷贝 + { + if (oldE.FId && !oldE.FId.IsErase) + { + let oldBr = oldE.FId.Object as Board; + if (HoleInBoard([e], oldBr)) + { + e.FId = oldBr.Id; + oldBr.AppendNails([e.Id]); } - else if (e instanceof Hole) + } + } + + if (!e.MId || e.MId.IsErase) //层板没拷贝 + { + if (oldE.MId && !oldE.MId.IsErase) + { + let oldBr = oldE.MId.Object as Board; { - if (repHoled.has(e)) continue;//因为我们以编组为单位,所以我们不会选到非编组外的排钻,所以这样是正确的 + e.MId = oldBr.Id; + oldBr.AppendNails([e.Id]); + } + } + } - let groupHoles: Hole[] = []; - if (e.GroupId?.Object) + //处理通孔(如果通孔没拷贝,那么移除通孔属性)(这里没有考虑到图纸中的对象可能会组成新的通孔) + if (oldE.OtherHalfTongKong) + { + if (!oldEntsSet.has(oldE.OtherHalfTongKong.Object as Entity)) + { + e.OtherHalfTongKong = null; + if (e instanceof CylinderHole) + e.Type = GangDrillType.Ymj; + + else + (e as ExtrudeHole).isThrough = false; + } + } + } + else if (e instanceof Hole) + { + if (repHoled.has(e)) continue; //因为我们以编组为单位,所以我们不会选到非编组外的排钻,所以这样是正确的 + + let groupHoles: Hole[] = []; + if (e.GroupId?.Object) + { + let g = e.GroupId.Object as GroupRecord; + if (g.Name) //如果没有名称,那么可能是用户自己编组的 + { + for (let id of g.Entitys) + { + if (id.Object instanceof Hole) { - let g = e.GroupId.Object as GroupRecord; - if (g.Name)//如果没有名称,那么可能是用户自己编组的 - { - for (let id of g.Entitys) - { - if (id.Object instanceof Hole) - { - groupHoles.push(id.Object); - repHoled.add(id.Object);//因为实体在编组里,所以我们肯定它已经被选中拷贝! - } - } - } + groupHoles.push(id.Object); + repHoled.add(id.Object); //因为实体在编组里,所以我们肯定它已经被选中拷贝! } - if (groupHoles.length === 0) - groupHoles.push(e); + } + } + } + if (groupHoles.length === 0) + groupHoles.push(e); - let oldId = GetOldObjectId(e.Id); - let oldHole = oldId.Object as Hole; + let oldId = GetOldObjectId(e.Id); + let oldHole = oldId.Object as Hole; - let fbr = (e.FId?.Object ?? oldHole.FId?.Object) as Board; - let mbr = (e.MId?.Object ?? oldHole.MId?.Object) as Board; + let fbr = (e.FId?.Object ?? oldHole.FId?.Object) as Board; + let mbr = (e.MId?.Object ?? oldHole.MId?.Object) as Board; - if (oldHole.FId && !oldHole.FId.IsErase) - { - if (!olds.has(oldHole.FId.Object as Board))//父亲没拷贝 - { - e.FId = fbr.Id; - fbr.AppendDrillList(mbr.Id, [groupHoles.map(e => e.Id)]); - - if (!HoleInBoard(groupHoles, fbr)) - { - AppToaster.show({ - message: "警告:复制后的排钻不在板上! 请勿复制到其他板上,否则会导致其他板上拆单没有对应的孔位!!!", - intent: Intent.DANGER, - timeout: 10000 - }, "copy_drill_warning"); - } - } - } + if (oldHole.FId && !oldHole.FId.IsErase) + { + if (!oldEntsSet.has(oldHole.FId.Object as Board)) //父亲没拷贝 + { + e.FId = fbr.Id; + fbr.AppendDrillList(mbr.Id, [groupHoles.map(e => e.Id)]); - if (oldHole.MId && !oldHole.MId.IsErase) - { - if (!olds.has(oldHole.MId.Object as Board))//母亲没拷贝 - { - e.MId = mbr.Id; - mbr.AppendDrillList(fbr.Id, [groupHoles.map(e => e.Id)]); - - if (!HoleInBoard(groupHoles, mbr)) - { - AppToaster.show({ - message: "警告:复制后的排钻不在板上! 请勿复制到其他板上,否则会导致其他板上拆单没有对应的孔位!!!", - intent: Intent.DANGER, - timeout: 10000 - }, "copy_drill_warning"); - } - } - } - } - else if (e instanceof HardwareCompositeEntity)//五金 + if (!HoleInBoard(groupHoles, fbr)) { - let oldId = GetOldObjectId(e.Id); - let oldE = oldId.Object as HardwareCompositeEntity; - - for (let id of oldE.RelevanceBoards) - { - if (!id || id.IsErase) continue; - let ent = id.Object; - if (ent instanceof Board)//只复制了五金 却没复制板 - { - if (!olds.has(ent)) - { - e.RelevanceBoards.push(ent.Id); - ent.RelativeHardware.push(e.Id); - } - } - else if (ent instanceof HardwareCompositeEntity) //复合板 - { - if (!olds.has(ent)) - { - e.RelevanceBoards.push(ent.Id); - ent.RelevanceHardware.push(e.Id); - } - } - } + AppToaster.show({ + message: "警告:复制后的排钻不在板上! 请勿复制到其他板上,否则会导致其他板上拆单没有对应的孔位!!!", + intent: Intent.DANGER, + timeout: 10000 + }, "copy_drill_warning"); } - else if (e instanceof HardwareTopline)//顶线不需要 + } + } + + if (oldHole.MId && !oldHole.MId.IsErase) + { + if (!oldEntsSet.has(oldHole.MId.Object as Board)) //母亲没拷贝 + { + e.MId = mbr.Id; + mbr.AppendDrillList(fbr.Id, [groupHoles.map(e => e.Id)]); + + if (!HoleInBoard(groupHoles, mbr)) { + AppToaster.show({ + message: "警告:复制后的排钻不在板上! 请勿复制到其他板上,否则会导致其他板上拆单没有对应的孔位!!!", + intent: Intent.DANGER, + timeout: 10000 + }, "copy_drill_warning"); } - else if (e instanceof ViewportEntity) - { - let oldId = GetOldObjectId(e.Id); - let oldVe = oldId.Object as ViewportEntity; + } + } + } + else if (e instanceof HardwareCompositeEntity) //五金 + { + let oldId = GetOldObjectId(e.Id); + let oldE = oldId.Object as HardwareCompositeEntity; - e.AppendHideObjects(oldVe.HideObjects); - e.AppendShowObjects(oldVe.ShowObjects); - e.UpdateScene(); - } - else if (e instanceof RoomWallBase) + for (let id of oldE.RelevanceBoards) + { + if (!id || id.IsErase) continue; + let ent = id.Object; + if (ent instanceof Board) //只复制了五金 却没复制板 + { + if (!oldEntsSet.has(ent)) { - UpdateWallHolesDataAndUpdateDraw(e); + e.RelevanceBoards.push(ent.Id); + ent.RelativeHardware.push(e.Id); } - else if (e instanceof RoomHolePolyline) + } + else if (ent instanceof HardwareCompositeEntity) //复合板 + { + if (!oldEntsSet.has(ent)) { - let fullCopy = e.RelevancyWalls.length === (e.Points.length - 1) && e.RelevancyWalls.every(id => - { - let oldId = GetOldObjectId(id); - return olds.has(oldId.Object as Entity); - }); - - if (!fullCopy) - e.Erase();//我们现在直接删除它,我们其实应该重新放置它,但是我们没做! + e.RelevanceBoards.push(ent.Id); + ent.RelevanceHardware.push(e.Id); } } } - else - break; + } + else if (e instanceof HardwareTopline) //顶线不需要 + { + } + else if (e instanceof ViewportEntity) + { + let oldId = GetOldObjectId(e.Id); + let oldVe = oldId.Object as ViewportEntity; + + e.AppendHideObjects(oldVe.HideObjects); + e.AppendShowObjects(oldVe.ShowObjects); + e.UpdateScene(); + } + else if (e instanceof RoomWallBase) + { + UpdateWallHolesDataAndUpdateDraw(e); + } + else if (e instanceof RoomHolePolyline) + { + let fullCopy = e.RelevancyWalls.length === (e.Points.length - 1) && e.RelevancyWalls.every(id => + { + let oldId = GetOldObjectId(id); + return oldEntsSet.has(oldId.Object as Entity); + }); + + if (!fullCopy) + e.Erase(); } } } diff --git a/src/Add-on/Rotate.ts b/src/Add-on/Rotate.ts index 601ab6f61..a38dcc080 100644 --- a/src/Add-on/Rotate.ts +++ b/src/Add-on/Rotate.ts @@ -5,6 +5,7 @@ import { Command } from '../Editor/CommandMachine'; import { JigUtils } from '../Editor/JigUtils'; import { PromptStatus } from '../Editor/PromptResult'; import { ZAxis, angle } from '../Geometry/GeUtils'; +import { GetCopyEntsParam, HardCloneObject } from './Copy'; import { UpdateEntityDrawTask } from './UpdateEntityDrawTask'; export class Command_Rotate implements Command @@ -51,7 +52,7 @@ export class Command_Rotate implements Command if (isCopy) { JigUtils.Restore(); - this.Update(pt1, anRes.Distance - refAng, cloneEns, isCopy, true); + this.Update(pt1, anRes.Distance - refAng, ens, isCopy, true); } else this.Update(pt1, anRes.Distance - refAng, ens, isCopy, true); @@ -91,13 +92,20 @@ export class Command_Rotate implements Command let moveMatInv = new Matrix4().getInverse(moveMat); let roMat = new Matrix4().makeRotationAxis(ZAxis.clone().applyMatrix4(app.Editor.UCSMatrix.clone().setPosition(0, 0, 0)), MathUtils.degToRad(an)); let mtx = moveMat.multiply(roMat).multiply(moveMatInv); - for (let en of ens) + + if (isCopy) { - en.ApplyMatrix(mtx); + let { dbEnts, idMapRev, idMap, oldEntsSet } = GetCopyEntsParam(ens); - if (isCopy) - app.Database.ModelSpace.Append(en); + HardCloneObject(dbEnts, mtx, idMapRev, idMap, oldEntsSet); + + ens = dbEnts; + } + for (let en of ens) + { + if (!isCopy) + en.ApplyMatrix(mtx); if (resetUpdate) en.AutoUpdate = true; }