客户端剖切功能

dev_xd
lj7788@126.com 2025-09-10 17:38:34 +08:00
parent 8a6183fdc1
commit bdda89d737
4 changed files with 234 additions and 100 deletions

View File

@ -142,9 +142,6 @@ function addClipModel(api, bimCfg, modelId, cb, models) {
} }
if (bimCfg.clientApi ) { if (bimCfg.clientApi ) {
url = `/bimdata/Tools/output/model/${modelId}/root.glt`; url = `/bimdata/Tools/output/model/${modelId}/root.glt`;
if (modelInfo) {
//direction = modelInfo.bimCfg.direction;
}
} }
console.log("加载模型:" + url); console.log("加载模型:" + url);
api.Model.add( api.Model.add(
@ -204,7 +201,7 @@ function addModel(api, bimCfg, modelId, cb, models) {
} }
if (bimCfg.clientApi ) { if (bimCfg.clientApi ) {
url = `/bimdata/Tools/output/model/${modelId}/root.glt`; url = `/bimdata/Tools/output/model/${modelId}/root.glt`;
if (modelInfo) { if (modelInfo && bimCfg.showGis) {
direction = modelInfo.bimCfg.direction; direction = modelInfo.bimCfg.direction;
} }
} }
@ -254,7 +251,7 @@ function addModel(api, bimCfg, modelId, cb, models) {
function setDefaultViewPoint(api, bimCfg, pt) { function setDefaultViewPoint(api, bimCfg, pt) {
if (pt) { if (pt) {
if (bimCfg.clientApi) { if (bimCfg.clientApi && bimCfg.showGis) {
if (bimCfg.clientApi) { if (bimCfg.clientApi) {
if (pt["position"] && pt["heading"] && pt["pitch"]) { if (pt["position"] && pt["heading"] && pt["pitch"]) {
api.Camera.SetCamera(pt.position, pt.heading, pt.pitch); api.Camera.SetCamera(pt.position, pt.heading, pt.pitch);
@ -346,12 +343,12 @@ function initModelPosition(that, api) {
that.hideParts.push(it); that.hideParts.push(it);
}); });
} }
setTimeout(() => { // setTimeout(() => {
api.Model.location(modelId); // api.Model.location(modelId);
setTimeout(() => { // setTimeout(() => {
that.resetScene(); // that.resetScene();
}, 1000); // }, 1000);
}, 1000); // }, 1000);
} }
initHideParts(that, api); initHideParts(that, api);
}); });
@ -387,17 +384,18 @@ function resetScene(that, api) {
api.Camera.stopImmersiveRoam(); api.Camera.stopImmersiveRoam();
} }
} catch (e) { } } catch (e) { }
api.Model.location(api.m_model.keys().toArray()[0]);
if (!that.bimCfg.clientApi) { if (!that.bimCfg.clientApi) {
api.Plugin.deleteMiniMap(); api.Plugin.deleteMiniMap();
} }
api.Model.location(that.models[0].modelId);
if (that.viewPoint) { if (that.viewPoint) {
if (that.viewPoint.world) { if (that.viewPoint.world) {
if (!that.bimCfg.clientApi) { if (!that.bimCfg.clientApi) {
api.Camera.setViewPort(that.viewPoint); api.Camera.setViewPort(that.viewPoint);
} }
} else { } else {
if (that.bimCfg.clientApi) { if (that.bimCfg.clientApi && that.bimCfg.showGis) {
let pt = that.viewPoint; let pt = that.viewPoint;
api.Camera.SetCamera(pt.position, pt.heading, pt.pitch); api.Camera.SetCamera(pt.position, pt.heading, pt.pitch);
} }

View File

@ -208,7 +208,6 @@ function measurementArea(that) {
api.Public.clearHandler(); api.Public.clearHandler();
api.Measurement.clearAllTrace(); api.Measurement.clearAllTrace();
api.Feature.getByEvent(true, (n) => { api.Feature.getByEvent(true, (n) => {
console.log(n);
if (n && n["id"]) { if (n && n["id"]) {
let featureId = n.id; let featureId = n.id;
let modelId = featureId.split("^")[0]; let modelId = featureId.split("^")[0];
@ -301,11 +300,11 @@ function getModels(that) {
function closeClientClipping(that) { function closeClientClipping(that) {
let api = bimBriefingApi; let api = bimBriefingApi;
if (that.clipState && that.clip) { if (that.clipState && that.clip) {
that.models.forEach(it => { if (that.bimCfg.showGis) {
that.models.forEach((it) => {
api.Model.setVisible(it.modelId, true); api.Model.setVisible(it.modelId, true);
api.Model.setVisible("clip" + it.modelId, false); api.Model.setVisible("clip" + it.modelId, false);
}); });
if (that.bimCfg.showGis) {
api.Public.setGisState(true); api.Public.setGisState(true);
api.viewer.terrainProvider = Cesium.createWorldTerrain({ api.viewer.terrainProvider = Cesium.createWorldTerrain({
requestVertexNormals: true, //开启地形光照 requestVertexNormals: true, //开启地形光照
@ -321,15 +320,23 @@ function closeClientClipping(that) {
//剖切 -- 客户端渲染 //剖切 -- 客户端渲染
function initClientClipping(that) { function initClientClipping(that) {
let api = bimBriefingApi; let api = bimBriefingApi;
that.models.forEach(it => { let models = that.models.map((it) => it.modelId);
if (that.bimCfg.showGis) {
that.models.forEach((it) => {
api.Model.setVisible(it.modelId, false); api.Model.setVisible(it.modelId, false);
api.Model.setVisible("clip" + it.modelId, true); api.Model.setVisible("clip" + it.modelId, true);
}); });
if (that.bimCfg.showGis) { if (that.bimCfg.showGis) {
api.Public.setGisState(false) api.Public.setGisState(false);
} }
let models = that.models.map((it) => "clip" + it.modelId); models = that.models.map((it) => "clip" + it.modelId);
api.Model.location(models[0]); api.Model.location(models[0]);
} else {
let featureIds = (that.hideParts || []).map((it) => it.featureId);
if (featureIds.length > 0) {
api.Feature.setVisible(featureIds.join("#"), false);
}
}
closeClientClipping(that); closeClientClipping(that);
that.$message.info("鼠标左键点击轴线进行操作!"); that.$message.info("鼠标左键点击轴线进行操作!");
that.clipState = true; that.clipState = true;
@ -345,15 +352,13 @@ function initClientClipping(that) {
outline: !0, outline: !0,
outlineColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.WHITE,
planeColor: Cesium.Color.WHITE.withAlpha(0.1), planeColor: Cesium.Color.WHITE.withAlpha(0.1),
scalar: [1, 1, 1] scalar: [1, 1, 1],
}, },
HelperLineWidth: 10, HelperLineWidth: 10,
}); });
} }
//剖切 -- 服务端渲染 //剖切 -- 服务端渲染
function initClipping(that) { function initClipping(that) {
console.log("---->initClipping")
let api = bimBriefingApi; let api = bimBriefingApi;
api.Public.clearHandler(); api.Public.clearHandler();
api.Measurement.clearAllTrace(); api.Measurement.clearAllTrace();
@ -362,13 +367,44 @@ function initClipping(that) {
//that.clipShow(); //that.clipShow();
return; return;
} }
hideFeature(that);
api.Model.clipByBox(getModels(that)); api.Model.clipByBox(getModels(that));
} }
function hideFeature(that) {
let api = bimBriefingApi;
let featureIds = (that.hideParts || []).map((it) => it.featureId);
if (featureIds.length > 0) {
api.Feature.setVisible(featureIds.join("#"), false);
}
}
function actorVisibleClient(that) {
hideFeature(that);
let api = bimBriefingApi;
api.Public.Event("LEFT_CLICK",res=>{
api.Feature.GetFeatureByEvent(res.position,n=>{
if (n && n["id"]) {
let featureId = n.id;
let modelId = featureId.split("^")[0];
api.Feature.setVisible(featureId, false);
that.hideFeatureIds.push({
show: false,
id: featureId.split("^")[1],
modelId: modelId,
featureId: featureId,
});
}
});
});
}
//构件隐藏 //构件隐藏
function actorVisible(that) { function actorVisible(that) {
let api = bimBriefingApi; let api = bimBriefingApi;
that.hideFeatureIds = []; that.hideFeatureIds = [];
if (that.isClient) {
actorVisibleClient(that);
return;
}
api.Feature.getByEvent(true, (n) => { api.Feature.getByEvent(true, (n) => {
if (n && n["id"]) { if (n && n["id"]) {
let featureId = n.id; let featureId = n.id;
@ -422,5 +458,5 @@ export default {
actorVisible, actorVisible,
actorShow, actorShow,
clearEvent, clearEvent,
closeClientClipping closeClientClipping,
}; };

View File

@ -12,15 +12,30 @@
模型结构树 模型结构树
</div> </div>
<div class="model-tree scroll"> <div class="model-tree scroll">
<el-tree :key="treeKey" ref="tree" :default-expanded-keys="treeExpendedKeys" :props="{ <el-tree
:key="treeKey"
ref="tree"
:default-expanded-keys="treeExpendedKeys"
:props="{
children: 'children', children: 'children',
label: 'title', label: 'title',
}" node-key="key" @check="onCheckTree" :load="loadNode" lazy show-checkbox></el-tree> }"
node-key="key"
@check="onCheckTree"
:load="loadNode"
lazy
show-checkbox
></el-tree>
</div> </div>
</div> </div>
</div> </div>
</transition> </transition>
<img :src="leftSrc" class="toSafety-fixed-left-img" @click="arrowRetract" id="arrowLeft" /> <img
:src="leftSrc"
class="toSafety-fixed-left-img"
@click="arrowRetract"
id="arrowLeft"
/>
</div> </div>
<div class="div-right" :class="{ isShow: leftShow, isHide: !leftShow }"> <div class="div-right" :class="{ isShow: leftShow, isHide: !leftShow }">
@ -37,15 +52,22 @@
{{ attributeInformation }} {{ attributeInformation }}
</div> </div>
<div class="model-property-nav" v-if="propertyLoad == 'end'"> <div class="model-property-nav" v-if="propertyLoad == 'end'">
<el-radio-group v-model="selPropertyType" size="small" fill="#6cf"> <el-radio-group
v-model="selPropertyType"
size="small"
fill="#6cf"
>
<el-radio-button label="att">属性</el-radio-button> <el-radio-button label="att">属性</el-radio-button>
<el-radio-button label="type">类型</el-radio-button> <el-radio-button label="type">类型</el-radio-button>
</el-radio-group> </el-radio-group>
</div> </div>
<div class="model-property-list" v-if="propertyLoad == 'end'"> <div class="model-property-list" v-if="propertyLoad == 'end'">
<div v-for="(item, index) in selPropertyType == 'att' <div
v-for="(item, index) in selPropertyType == 'att'
? propertyAttr ? propertyAttr
: propertyType" :key="index"> : propertyType"
:key="index"
>
<div class="group-info"> <div class="group-info">
<svg-icon icon-class="info" /> <svg-icon icon-class="info" />
<span>{{ item.name }}</span> <span>{{ item.name }}</span>
@ -67,11 +89,20 @@
<span>{{ item.name }}</span> <span>{{ item.name }}</span>
</div> </div>
<table class="model-property-table my-table"> <table class="model-property-table my-table">
<tr v-for="(item2, index2) in item.data" :key="index2 + '-' + index"> <tr
<th width="50%" :class="'txt' + selectMenu + item2.name"> v-for="(item2, index2) in item.data"
:key="index2 + '-' + index"
>
<th
width="50%"
:class="'txt' + selectMenu + item2.name"
>
{{ item2.name }} {{ item2.name }}
</th> </th>
<td width="50%" :class="'txt' + selectMenu + item2.name"> <td
width="50%"
:class="'txt' + selectMenu + item2.name"
>
{{ item2.value }} {{ item2.value }}
<span v-if="index == 0"></span> <span v-if="index == 0"></span>
<span v-if="index == 1"><sup>2</sup></span> <span v-if="index == 1"><sup>2</sup></span>
@ -108,16 +139,31 @@
</div> </div>
</div> </div>
<template v-if="selectMenu == 6"> <template v-if="selectMenu == 6">
<el-button type="primary" @click="clearAllHide" class="clear-all-btn">清除所有</el-button> <el-button
type="primary"
@click="clearAllHide"
class="clear-all-btn"
>清除所有</el-button
>
<div class="hide-list scroll"> <div class="hide-list scroll">
<div v-for="(item, index) in hideFeatureIds" :key="index" class="hide-item"> <div
v-for="(item, index) in hideFeatureIds"
:key="index"
class="hide-item"
>
<div class="hide-item-state"> <div class="hide-item-state">
{{ item.show ? "隐藏" : "显示" }} {{ item.show ? "隐藏" : "显示" }}
</div> </div>
<el-switch v-model="item.show" @change="changeSwitch(item)"></el-switch> <el-switch
v-model="item.show"
@change="changeSwitch(item)"
></el-switch>
<div class="hide-item-id">{{ item.id }}</div> <div class="hide-item-id">{{ item.id }}</div>
<div class="hide-item-delete"> <div class="hide-item-delete">
<i class="el-icon-delete command" @click="deleteFeature(item)" /> <i
class="el-icon-delete command"
@click="deleteFeature(item)"
/>
</div> </div>
</div> </div>
</div> </div>
@ -145,16 +191,30 @@
<svg-icon icon-class="info" /> <svg-icon icon-class="info" />
<span>当前进度</span> <span>当前进度</span>
</div> </div>
<el-progress :text-inside="true" :stroke-width="26" color="#37A685" :percentage="70" /> <el-progress
:text-inside="true"
:stroke-width="26"
color="#37A685"
:percentage="70"
/>
</div> </div>
</div> </div>
</div> </div>
</transition> </transition>
<img :src="rightSrc" class="toSafety-fixed-right-img" @click="arrowRetract" id="arrowRight" /> <img
:src="rightSrc"
class="toSafety-fixed-right-img"
@click="arrowRetract"
id="arrowRight"
/>
</div> </div>
<div class="div-tools"> <div class="div-tools">
<div class="tool-item" :class="{ 'is-selected': selectMenu == 0 }" @click="doSelectMenu(0)"> <div
class="tool-item"
:class="{ 'is-selected': selectMenu == 0 }"
@click="doSelectMenu(0)"
>
<el-tooltip content="默认视点" placement="top"> <el-tooltip content="默认视点" placement="top">
<div class="icon"> <div class="icon">
<svg-icon icon-class="home" /> <svg-icon icon-class="home" />
@ -162,7 +222,11 @@
</el-tooltip> </el-tooltip>
</div> </div>
<div class="tool-item" :class="{ 'is-selected': selectMenu == 1 }" @click="doSelectMenu(1)"> <div
class="tool-item"
:class="{ 'is-selected': selectMenu == 1 }"
@click="doSelectMenu(1)"
>
<el-tooltip content="构建测量" placement="top"> <el-tooltip content="构建测量" placement="top">
<div class="icon"> <div class="icon">
<svg-icon icon-class="size2" /> <svg-icon icon-class="size2" />
@ -170,7 +234,12 @@
</el-tooltip> </el-tooltip>
</div> </div>
<div class="tool-item" :class="{ 'is-selected': selectMenu == 2 }" @click="doSelectMenu(2)" v-if="1 == 2"> <div
class="tool-item"
:class="{ 'is-selected': selectMenu == 2 }"
@click="doSelectMenu(2)"
v-if="1 == 2"
>
<el-tooltip content="构建面积" placement="top"> <el-tooltip content="构建面积" placement="top">
<div class="icon"> <div class="icon">
<svg-icon icon-class="area2" /> <svg-icon icon-class="area2" />
@ -178,7 +247,12 @@
</el-tooltip> </el-tooltip>
</div> </div>
<div class="tool-item" :class="{ 'is-selected': selectMenu == 3 }" @click="doSelectMenu(3)" v-if="1 == 2"> <div
class="tool-item"
:class="{ 'is-selected': selectMenu == 3 }"
@click="doSelectMenu(3)"
v-if="1 == 2"
>
<el-tooltip content="构建体积" placement="top"> <el-tooltip content="构建体积" placement="top">
<div class="icon"> <div class="icon">
<svg-icon icon-class="volume" /> <svg-icon icon-class="volume" />
@ -186,7 +260,11 @@
</el-tooltip> </el-tooltip>
</div> </div>
<div class="tool-item" :class="{ 'is-selected': selectMenu == 4 }" @click="doSelectMenu(4)"> <div
class="tool-item"
:class="{ 'is-selected': selectMenu == 4 }"
@click="doSelectMenu(4)"
>
<el-tooltip content="距离测量" placement="top"> <el-tooltip content="距离测量" placement="top">
<div class="icon"> <div class="icon">
<svg-icon icon-class="distance" /> <svg-icon icon-class="distance" />
@ -194,7 +272,11 @@
</el-tooltip> </el-tooltip>
</div> </div>
<div class="tool-item" :class="{ 'is-selected': selectMenu == 5 }" @click="doSelectMenu(5)"> <div
class="tool-item"
:class="{ 'is-selected': selectMenu == 5 }"
@click="doSelectMenu(5)"
>
<el-tooltip content="剖切" placement="top"> <el-tooltip content="剖切" placement="top">
<div class="icon"> <div class="icon">
<svg-icon icon-class="sectioning" /> <svg-icon icon-class="sectioning" />
@ -202,7 +284,11 @@
</el-tooltip> </el-tooltip>
</div> </div>
<div class="tool-item" :class="{ 'is-selected': selectMenu == 6 }" @click="doSelectMenu(6)"> <div
class="tool-item"
:class="{ 'is-selected': selectMenu == 6 }"
@click="doSelectMenu(6)"
>
<el-tooltip content="构建隐藏" placement="top"> <el-tooltip content="构建隐藏" placement="top">
<div class="icon"> <div class="icon">
<svg-icon icon-class="hide" /> <svg-icon icon-class="hide" />
@ -210,7 +296,11 @@
</el-tooltip> </el-tooltip>
</div> </div>
<div class="tool-item" :class="{ 'is-selected': selectMenu == 7 }" @click="doSelectMenu(7)"> <div
class="tool-item"
:class="{ 'is-selected': selectMenu == 7 }"
@click="doSelectMenu(7)"
>
<el-tooltip content="构建属性" placement="top"> <el-tooltip content="构建属性" placement="top">
<div class="icon"> <div class="icon">
<svg-icon icon-class="attribute" /> <svg-icon icon-class="attribute" />
@ -578,7 +668,6 @@ export default {
}) })
.then((d) => { .then((d) => {
this.models = (d.rows || []).map((it) => { this.models = (d.rows || []).map((it) => {
//it.lightweightName="4864687928672606640";
it.modelId = it.lightweightName; it.modelId = it.lightweightName;
it.bimCfg = this.$tryToJson(it.bimConfig || "{}", {}); it.bimCfg = this.$tryToJson(it.bimConfig || "{}", {});
it.visible = false; it.visible = false;
@ -589,16 +678,24 @@ export default {
if (this.models.length == 0) { if (this.models.length == 0) {
this.$message.error("暂无模型,请先关联模型"); this.$message.error("暂无模型,请先关联模型");
} else { } else {
if (this.bimCfg.clientApi) { if (this.bimCfg.clientApi && this.bimCfg.showGis) {
bimTools.loadClipModel(window.bimBriefingApi, bimTools.loadClipModel(
window.bimBriefingApi,
this.bimCfg, this.bimCfg,
this.models, this.models,
(hideParts) => { (hideParts) => {
this.clipHideParts = hideParts; this.clipHideParts = hideParts;
bimTools.hideParts(window.bimBriefingApi, hideParts); bimTools.hideParts(window.bimBriefingApi, hideParts);
}); this.addModelList();
} }
);
} else {
this.addModelList();
}
}
});
},
addModelList() {
bimTools.addModelList( bimTools.addModelList(
window.bimBriefingApi, window.bimBriefingApi,
this.bimCfg, this.bimCfg,
@ -614,11 +711,13 @@ export default {
bimTools.hideParts(window.bimBriefingApi, hideParts); bimTools.hideParts(window.bimBriefingApi, hideParts);
this.modelLoaded = true; this.modelLoaded = true;
bimTools.initLoadModel(this, bimBriefingApi); bimTools.initLoadModel(this, bimBriefingApi);
this.resetScene(); //this.resetScene();
setTimeout(() => { setTimeout(() => {
if (!this.bimCfg.clientApi) {
this.resetScene();
}
this.doSelectMenu(7); this.doSelectMenu(7);
}, 4000); }, 4000);
}, 1000); }, 1000);
} }
); );
@ -631,10 +730,7 @@ export default {
}, 3000); }, 3000);
}); });
this.treeKey++; this.treeKey++;
}
});
}, },
loadModelTree() { loadModelTree() {
this.modelTrees = [ this.modelTrees = [
{ {
@ -1093,7 +1189,6 @@ export default {
} }
.my-table { .my-table {
td, td,
th { th {
font-size: 20px; font-size: 20px;

View File

@ -456,7 +456,9 @@ public class ProProjectInfoSubdeptsUsersController extends BaseController
}else{ }else{
userPost = StringUtils.eqObj(user.getUserPost(), UserPostEnums.BZZ.getCode())?user.getCraftPostName()+UserPostEnums.BZZ.getInfo():user.getCraftPostName(); userPost = StringUtils.eqObj(user.getUserPost(), UserPostEnums.BZZ.getCode())?user.getCraftPostName()+UserPostEnums.BZZ.getInfo():user.getCraftPostName();
} }
userMap.put("userPostName",userPost); userMap.put("userPostName",("4".equals(user.getSubDeptType())?"分包":"")+userPost);
userMap.put("subDeptType",user.getSubDeptType());
userMap.put("subDeptTypeName",user.getSubDeptTypeName());
userMap.put("state",false); userMap.put("state",false);
userList.add(userMap); userList.add(userMap);
} }
@ -485,7 +487,10 @@ public class ProProjectInfoSubdeptsUsersController extends BaseController
userMap.put("userId",user.getUserId()); userMap.put("userId",user.getUserId());
userMap.put("userName",user.getUserName()); userMap.put("userName",user.getUserName());
userMap.put("userPhone",Convert.toStr(user.getUserPhone(),"")); userMap.put("userPhone",Convert.toStr(user.getUserPhone(),""));
userMap.put("userPostName",StringUtils.eqObj(user.getUserPost(), UserPostEnums.BZZ.getCode())?user.getCraftPostName()+UserPostEnums.BZZ.getInfo():user.getCraftPostName()); userMap.put("userPostName",("4".equals(user.getSubDeptType())?"分包":"")+
(StringUtils.eqObj(user.getUserPost(), UserPostEnums.BZZ.getCode())?user.getCraftPostName()+UserPostEnums.BZZ.getInfo():user.getCraftPostName()));
userMap.put("subDeptType",user.getSubDeptType());
userMap.put("subDeptTypeName",user.getSubDeptTypeName());
userMap.put("state",false); userMap.put("state",false);
userList.add(userMap); userList.add(userMap);
} }