任务计划绑定BIM

dev_xd
lj7788@126.com 2025-06-28 16:30:36 +08:00
parent 8bf9907bc1
commit 72b770d626
2 changed files with 289 additions and 57 deletions

View File

@ -9,19 +9,42 @@ function selectFeature(that, featureId) {
} }
} else { } else {
api.Feature.setColor(featureId, "rgba(255,0,255,1)"); api.Feature.setColor(featureId, "rgba(255,0,255,1)");
if (!that.showMode) {
api.Feature.setVisible(featureId, false);
}
that.selectItems.push(featureId); that.selectItems.push(featureId);
} }
} }
function hideFeatures(that) { function hideFeatures(that) {
let tmps = that.allBimData.filter((it) => it.id != that.plan.id); let tmps = that.allBimData.filter((it) => it.id != that.plan.id);
tmps.forEach((it) => { tmps.forEach((it) => {
console.log("hide-->", it.bim);
it.bim.forEach((it) => { it.bim.forEach((it) => {
hideFeature(that, it); hideFeature(that, it);
}); });
}); });
} }
function getHideFeatures(that, checkedKeys) {
let result = [];
let tmps = that.allBimData.filter((it) => it.id != that.plan.id);
tmps.forEach((it) => {
it.bim.forEach((it) => {
result.push(it);
});
});
if (checkedKeys.length > 0) {
tmps = that.allFeatures
.filter((d) => !checkedKeys.includes(d.glid))
.filter((d) => d != "0")
.map((d) => d.featureId);
tmps.forEach((d) => {
result.push(d);
});
}
return result;
}
function hideFeature(that, featureId) { function hideFeature(that, featureId) {
let api = bimSelectionDlgApi; let api = bimSelectionDlgApi;
api.Feature.setVisible(featureId, false); api.Feature.setVisible(featureId, false);
@ -40,18 +63,19 @@ function selectSingle(that) {
} }
function clearAllSelection(that) { function clearAllSelection(that) {
let api = bimSelectionDlgApi; that.$modal.confirm("确定清除所有已选择构件吗?").then(() => {
api.Public.clearHandler(); let api = bimSelectionDlgApi;
that.selectItems.forEach((it) => { that.selectItems.forEach((d) => {
selectFeature(that, it); api.Feature.setColor(d, "rgba(255,255,255,1)");
});
that.selectItems = [];
this.selEl++;
}); });
} }
function initBim(that) { function initBim(that) {
console.log("initBim");
let tmps = that.allBimData.filter((it) => it.id == that.plan.id); let tmps = that.allBimData.filter((it) => it.id == that.plan.id);
if (tmps.length > 0) { if (tmps.length > 0) {
console.log("selected-->", tmps[0].bim);
tmps[0].bim.forEach((it) => { tmps[0].bim.forEach((it) => {
selectFeature(that, it); selectFeature(that, it);
}); });
@ -94,9 +118,9 @@ function partLoadModel(that) {
obj[modelId].join("#"), obj[modelId].join("#"),
(res) => {}, (res) => {},
(res) => { (res) => {
console.log("load part success", res);
that.viewPoint = p; that.viewPoint = p;
that.$message.info("模型加载完成"); that.$message.info("模型加载完成");
that.bimLoaded = true;
that.doMenu(2); that.doMenu(2);
initBim(that); initBim(that);
}, },
@ -106,6 +130,23 @@ function partLoadModel(that) {
); );
} }
} }
if (featureIds.length == 0) {
setTimeout(() => {
that.$refs.tree.setChecked("root", true, true);
}, 1000);
loadModels(that);
let func = () => {
if (that.loadedModelCount == that.models.length) {
setTimeout(() => {
setFeatueShowOrHide(that, []);
}, 1000);
} else {
setTimeout(func, 100);
}
};
func();
}
} }
//构建树形数据 //构建树形数据
@ -137,13 +178,13 @@ function buildTreeData(that) {
getModelFeatures(that, d.lightweightName, node); getModelFeatures(that, d.lightweightName, node);
}); });
that.treeExpendedKeys.push("root"); that.treeExpendedKeys.push("root");
that.$message.info("模型构件信息加载完成");
} }
//获取模型所有构件 //获取模型所有构件
function getModelFeatures(that, modelId, node) { function getModelFeatures(that, modelId, node) {
let tmps = that.allBimData.filter((it) => it.id != that.plan.id); let tmps = that.allBimData.filter((it) => it.id != that.plan.id);
tmps.forEach((it) => { tmps.forEach((it) => {
console.log("hide-->", it.bim);
it.bim.forEach((it) => { it.bim.forEach((it) => {
if (!that.readlyParts.includes(it)) { if (!that.readlyParts.includes(it)) {
that.readlyParts.push(it); that.readlyParts.push(it);
@ -152,18 +193,18 @@ function getModelFeatures(that, modelId, node) {
}); });
//获取模型构件 //获取模型构件
modelTreeAllChild(modelId, "").then((res) => { modelTreeAllChild(modelId, "").then((res) => {
let objs = res.data || [] let objs = res.data || [];
objs.forEach((o) => { objs.forEach((o) => {
o.modelId=modelId o.modelId = modelId;
o.featureId=o.modelId+"^"+o.externalId o.featureId = o.modelId + "^" + o.externalId;
o.name=o.name||''; o.name = o.name || "";
o.name=o.name.replaceAll('"',"").replaceAll("'","").replaceAll('\\',''); o.name = o.name.replaceAll('"', "").replaceAll("'", "").replaceAll("\\", "");
o.info=`[${o.externalId}]${o.groupname}-${o.name}` o.info = `[${o.externalId}]${o.groupname}-${o.name}`;
if(o.externalId == "0"){ if (o.externalId == "0") {
return; return;
} }
let featureId=o.modelId+"^"+o.externalId; let featureId = o.modelId + "^" + o.externalId;
if (!that.allParts.includes(featureId)) { if (!that.allParts.includes(featureId)) {
that.allParts.push(featureId); that.allParts.push(featureId);
} }
@ -188,10 +229,125 @@ function getModelFeatures(that, modelId, node) {
}); });
that.showParts = that.allParts.filter((it) => !that.hideParts.includes(it)); that.showParts = that.allParts.filter((it) => !that.hideParts.includes(it));
} }
//树上点击事件
function onCheckTree(that, node, event) {
let api = bimSelectionDlgApi;
if (that.partLoad) {
that.$refs.tree.setChecked("root", false, true);
that.partLoad = false;
that.models.forEach((it) => {
api.Model.remove(it.modelId);
});
return;
}
if (loadModels(that) > 0) {
let func = () => {
if (that.loadedModelCount == that.models.length) {
setTimeout(() => {
setTreeNodeChecked(that, node, event);
}, 1000);
} else {
setTimeout(func, 100);
}
};
func();
} else {
setTreeNodeChecked(that, node, event);
}
}
//根据选择控制构件的隐藏和显示
function setTreeNodeChecked(that, node, event) {
let api = bimSelectionDlgApi;
let checked = event.checkedNodes.includes(node);
if (node.type == "root") {
if (checked) {
that.models.forEach((it) => {
api.Model.setVisible(it.modelId, true);
api.Model.original(it.modelId);
});
} else {
that.models.forEach((it) => {
api.Model.setVisible(it.modelId, false);
});
}
} else if (node.type == "model") {
if (checked) {
api.Model.setVisible(node.modelId, true);
api.Model.original(node.modelId);
} else {
api.Model.setVisible(node.modelId, false);
}
} else {
api.Model.original(node.modelId);
}
setFeatueShowOrHide(that, event.checkedKeys);
}
//处理构件的隐藏和显示
function setFeatueShowOrHide(that, checkedKeys) {
let api = bimSelectionDlgApi;
//隐藏构件
let hideFeatures = getHideFeatures(that, checkedKeys);
api.Feature.setVisible(hideFeatures.join("#"), false);
//标注已选择的构件
that.selectItems.forEach((it) => {
api.Feature.setColor(it, "rgba(255,0,255,1)");
if (!that.showMode) {
api.Feature.setVisible(it, false);
}
});
api.Feature.setVisible(that.hideParts.join("#"), false);
}
//加载模型
function loadModels(that) {
let api = bimSelectionDlgApi;
let modelIds = that.models.map((it) => it.lightweightName);
let cnt = 0;
that.loadedModelCount = 0;
modelIds.forEach((modelId) => {
if (!api.m_model.has(modelId)) {
cnt++;
that.addModel(modelId);
return;
}
});
return cnt;
}
//框选构件
function boxSelection(that) {
let api = bimSelectionDlgApi;
api.Feature.boxSelect((data) => {
data.forEach((featureId) => {
selectFeature(that, featureId);
});
});
}
//隐藏构件选择
function hideSelection(that) {
let api = bimSelectionDlgApi;
api.Public.clearHandler();
api.Feature.getByEvent(true, (n) => {
if (n && n["id"]) {
let featureId = n.id;
that.hideParts.push(featureId);
api.Feature.setVisible(featureId, false);
that.hideEl++;
}
});
}
export default { export default {
selectSingle, selectSingle,
initBim, initBim,
clearAllSelection, clearAllSelection,
partLoadModel, partLoadModel,
buildTreeData, buildTreeData,
onCheckTree,
boxSelection,
hideSelection,
}; };

View File

@ -23,16 +23,28 @@
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="已关联" name="a2"> <el-tab-pane label="已关联" name="a2">
<div class="sel-list scroll"> <div class="sel-list scroll" :key="selEl">
<div v-for="(it, idx) in getSelectItems(selectItems)" :key="idx" class="div-sel-item"> <div v-for="(it, idx) in getSelectItems(selectItems)" :key="idx" class="div-sel-item">
<el-tooltip placement="bottom" :content="it.info"> <el-tooltip placement="bottom" :content="it.info">
<div class="sel-item-info">{{ it.info }}</div> <div class="sel-item-info">{{ it.info }}</div>
</el-tooltip> </el-tooltip>
<el-button link>删除</el-button> <el-button link @click="delSelectItem(idx)"></el-button>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="已隐藏" name="a3">
<div style="padding: 0px 10px 10px" v-show="hideParts.length > 0">
<el-button @click="delAllDelList"></el-button>
</div>
<div class="sel-list scroll hide-list" :key="hideEl">
<div v-for="(it, idx) in getSelectItems(hideParts)" :key="idx" class="div-sel-item">
<el-tooltip placement="bottom" :content="it.info">
<div class="sel-item-info">{{ it.info }}</div>
</el-tooltip>
<el-button link @click="delHideItem(idx)"></el-button>
</div> </div>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="已隐藏" name="a3"></el-tab-pane>
</el-tabs> </el-tabs>
<div class="div-icon"> <div class="div-icon">
<el-icon v-show="leftExpend" @click="leftExpend = false"><ArrowUpBold /></el-icon> <el-icon v-show="leftExpend" @click="leftExpend = false"><ArrowUpBold /></el-icon>
@ -40,34 +52,39 @@
</div> </div>
</div> </div>
</div> </div>
<div class="footer-box" v-if="models.length > 0"> <div v-show="bimLoaded">
<el-tooltip placement="top" content="主视图"> <div class="footer-box" v-if="models.length > 0">
<div class="footer-btn" @click="doMenu(0)" :class="activeMenu == 0 ? 'is-active' : ''"> <el-tooltip placement="top" content="主视图">
<svg-icon icon-class="home" /> <div class="footer-btn" @click="doMenu(0)" :class="activeMenu == 0 ? 'is-active' : ''">
</div> <svg-icon icon-class="home" />
</el-tooltip> </div>
<el-tooltip placement="top" content="取消所有关联"> </el-tooltip>
<div class="footer-btn" @click="doMenu(1)" :class="activeMenu == 1 ? 'is-active' : ''"> <el-tooltip placement="top" content="取消所有关联">
<svg-icon icon-class="cancel" /> <div class="footer-btn" @click="doMenu(1)" :class="activeMenu == 1 ? 'is-active' : ''">
</div> <svg-icon icon-class="cancel" />
</el-tooltip> </div>
<el-tooltip placement="top" content="点选"> </el-tooltip>
<div class="footer-btn" @click="doMenu(2)" :class="activeMenu == 2 ? 'is-active' : ''"> <el-tooltip placement="top" content="点选">
<svg-icon icon-class="pointselect" /> <div class="footer-btn" @click="doMenu(2)" :class="activeMenu == 2 ? 'is-active' : ''">
</div> <svg-icon icon-class="pointselect" />
</el-tooltip> </div>
<el-tooltip placement="top" content="框选"> </el-tooltip>
<div class="footer-btn" @click="doMenu(3)" :class="activeMenu == 3 ? 'is-active' : ''"> <el-tooltip placement="top" content="框选">
<svg-icon icon-class="boundselect" /> <div class="footer-btn" @click="doMenu(3)" :class="activeMenu == 3 ? 'is-active' : ''">
</div> <svg-icon icon-class="boundselect" />
</el-tooltip> </div>
<el-tooltip placement="top" content="隐藏构件"> </el-tooltip>
<div class="footer-btn" @click="doMenu(4)" :class="activeMenu == 4 ? 'is-active' : ''"> <el-tooltip placement="top" content="隐藏构件">
<svg-icon icon-class="hide" /> <div class="footer-btn" @click="doMenu(4)" :class="activeMenu == 4 ? 'is-active' : ''">
</div> <svg-icon icon-class="hide" />
</el-tooltip> </div>
</el-tooltip>
</div>
</div> </div>
<div class="div-mode">
<el-switch v-model="showMode" class="ml-2" inline-prompt active-text="" inactive-text="" @change="doModeChange" style="--el-switch-off-color: #336699" />
</div>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="show = false">取消</el-button> <el-button @click="show = false">取消</el-button>
@ -86,6 +103,8 @@ export default {
data() { data() {
return { return {
title: "任务计划绑定BIM", title: "任务计划绑定BIM",
bimLoaded: false,
loadedModelCount:0,
show: false, show: false,
partLoad: false, // partLoad: false, //
plan: null, plan: null,
@ -98,6 +117,9 @@ export default {
leftExpend: true, leftExpend: true,
activeMenu: 0, activeMenu: 0,
elId: 0, elId: 0,
selEl: 0,
hideEl: 0,
showMode: true,
selectItems: [], selectItems: [],
allBimData: [], allBimData: [],
treeKey: 0, treeKey: 0,
@ -118,18 +140,47 @@ export default {
} }
}, },
methods: { methods: {
onCheckTree(node, event) {}, delAllDelList() {
getSelectItems() { this.$modal.confirm("确定删除吗?").then(() => {
return this.selectItems.map((it) => { let api = bimSelectionDlgApi;
api.Feature.setVisible(this.hideParts.join("#"), true);
this.hideParts = [];
this.hideEl++;
});
},
delHideItem(idx) {
let api = bimSelectionDlgApi;
let featureId = this.hideParts[idx];
api.Feature.setVisible(featureId, true);
this.hideParts.splice(idx, 1);
this.hideEl++;
},
doModeChange() {
let api = bimSelectionDlgApi;
api.Feature.setVisible(this.selectItems.join("#"), this.showMode);
},
delSelectItem(idx) {
this.$modal.confirm("确定删除吗?").then(() => {
let api = bimSelectionDlgApi;
let featureId = this.selectItems[idx];
api.Feature.setColor(featureId, "rgba(255,255,255,1)");
this.selectItems.splice(idx, 1);
this.selEl++;
});
},
onCheckTree(node, event) {
bimTools.onCheckTree(this, node, event);
},
getSelectItems(items) {
return items.map((it) => {
return this.allFeatures.find((item) => item.featureId == it); return this.allFeatures.find((item) => item.featureId == it);
}); });
}, },
doSave() { doSave() {
updateBimInfo({ updateBimInfo({
id: this.plan.id, id: this.plan.id,
text: JSON.stringify(this.selectItems), text: this.selectItems.length > 0 ? JSON.stringify(this.selectItems) : "",
}).then((res) => { }).then((res) => {
console.log(res);
if (res.success) { if (res.success) {
ElMessage.success("保存成功"); ElMessage.success("保存成功");
this.show = false; this.show = false;
@ -140,20 +191,31 @@ export default {
}); });
}, },
doMenu(index) { doMenu(index) {
this.activeMenu = index; let api = bimSelectionDlgApi;
if (api) {
if ([0, 2, 4].includes(index)) {
api.Feature.closeBoxSelect();
}
}
switch (index) { switch (index) {
case 0: case 0:
this.activeMenu = 0;
this.resetScene(); this.resetScene();
break; break;
case 1: case 1:
bimTools.clearAllSelection(this); bimTools.clearAllSelection(this);
break; break;
case 2: case 2:
this.activeMenu = 2;
bimTools.selectSingle(this); bimTools.selectSingle(this);
break; break;
case 3: case 3:
this.activeMenu = 3;
bimTools.boxSelection(this);
break; break;
case 4: case 4:
this.activeMenu = 4;
bimTools.hideSelection(this);
break; break;
} }
}, },
@ -175,6 +237,12 @@ export default {
this.hideParts = []; this.hideParts = [];
this.readlyParts = []; this.readlyParts = [];
this.allFeatures = []; this.allFeatures = [];
this.bimLoaded = false;
this.partLoad = false;
this.elId = 0;
this.hideEl = 0;
this.showMode = true;
this.loadedModelCount=0
getPlanAllBimInfo(this.plan.projectId).then((res) => { getPlanAllBimInfo(this.plan.projectId).then((res) => {
this.allBimData = (res.data || []).map((it) => { this.allBimData = (res.data || []).map((it) => {
@ -260,15 +328,11 @@ export default {
} else { } else {
bimTools.buildTreeData(this); bimTools.buildTreeData(this);
bimTools.partLoadModel(this); bimTools.partLoadModel(this);
// this.models.forEach((item) => {
// this.addModel(item.lightweightName);
// });
} }
}); });
}, },
addModel(modelId, cb) { addModel(modelId, cb) {
let url = `${window.config.modelUrl}/Tools/output/model/${modelId}/root.glt`; let url = `${window.config.modelUrl}/Tools/output/model/${modelId}/root.glt`;
console.log(modelId, url);
bimSelectionDlgApi.Model.add( bimSelectionDlgApi.Model.add(
url, url,
modelId, modelId,
@ -276,11 +340,12 @@ export default {
() => { () => {
cb && cb(); cb && cb();
console.log("加载模型成功"); console.log("加载模型成功");
this.loadedModelCount++;
setTimeout(() => { setTimeout(() => {
bimSelectionDlgApi.Camera.getViewPort((p) => { bimSelectionDlgApi.Camera.getViewPort((p) => {
this.viewPoint = p; this.viewPoint = p;
this.$message.info("模型加载完成"); this.$message.info("模型加载完成");
bimTools.initBim(this); this.bimLoaded = true;
this.doMenu(2); this.doMenu(2);
}); });
}, 1000); }, 1000);
@ -412,6 +477,9 @@ export default {
padding: 0px 10px 10px; padding: 0px 10px 10px;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
&.hide-list {
height: calc(100% - 40px);
}
.div-sel-item { .div-sel-item {
background-color: #f7f7f975; background-color: #f7f7f975;
position: relative; position: relative;
@ -459,6 +527,14 @@ export default {
} }
} }
} }
.div-mode {
position: absolute;
left: 360px;
top: 75px;
.el-switch__inner {
margin: 0px 4px;
}
}
} }
} }
</style> </style>