vue3+SuperMap iClient3D for Cesium实现模型裁剪功能

本人小白一枚,文章如有问题还请各位大神评论区指出。整体实现是参考SuperMap iClient3D for Cesium的Box裁剪功能源码~

一、主要功能

二、具体实现

1.HTML主要结构

代码如下:

<select v-model="clipMode">
      <option value="clip_behind_all_plane">裁剪包围盒内</option>
      <option value="clip_behind_any_plane">裁剪包围盒外</option>
</select>
<el-button type="primary" @click="clearbox()">清 除</el-button>

2.javascript

代码如下:

<script setup>
import { ref, watch, onBeforeUnmount } from "vue";
import { ElMessage } from "element-plus";
import { useStore } from "vuex";
const store = useStore();
//组件销毁前为避免和其他功能组件冲突需要根据当前功能的不同激活状态进行清除和卸载
onBeforeUnmount(() => {
  if (layers != null) {
    for (var i = 0, j = layers.length; i < j; i++) {
      layers[i].clearCustomClipBox();
    }
    if (editorBox) {
      editorBox.deactivate();
    }
    if (handlerBox.activate == true) {
      handlerBox.clear();
      handlerBox.deactivate();
    }
    viewer.entities.removeAll();
  }
});

var scene = viewer.scene;
let clipMode = ref("clip_behind_all_plane");
let layers = store.state.others.layers3D;
if (layers == null) {
  layerLoad();
} else {
  // 精准定位
  scene.camera.setView({
    destination: {
      x: -1686231.1976311686,
      y: 4995014.670662241,
      z: 3590709.954257436,
    },
    orientation: {
      heading: 3.155708783485583,
      pitch: -0.15948987026566308,
      roll: 6.283185307179586,
    },
  });
  // 设置裁剪线颜色
  setAllLayersClipColor();
  var boxEntity = undefined;

  //交互绘制box
  var handlerBox = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Box);
  var editorBox;

  handlerBox.drawEvt.addEventListener(function (e) {
    boxEntity = e.object;
    var newDim = boxEntity.box.dimensions.getValue();
    var position = boxEntity.position.getValue(0);
    var boxOption = {
      dimensions: newDim,
      position: position,
      clipMode: clipMode.value,
      heading: 0,
    };

    //Box编辑器类,用于对box进行编辑
    editorBox = new Cesium.BoxEditor(viewer, boxEntity);

    editorBox.editEvt.addEventListener(function (e) {
      boxEntity.box.dimensions = e.dimensions;
      boxEntity.position = e.position;
      boxEntity.orientation = e.orientation;

      setClipBox();
    });
    //控制操作Box的entity可见性(0-950米之间可见)
    editorBox.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(
      0,
      950
    );
    editorBox.activate();
    setAllLayersClipOptions(boxOption);

    handlerBox.clear();
    handlerBox.deactivate();
  });
  handlerBox.activate();

  //监听裁剪模式变化
  watch(clipMode, (newval, oldval) => {
    setClipBox();
  });
}
function setClipBox() {
  if (typeof boxEntity == "undefined") {
    return;
  }
  var newDim = boxEntity.box.dimensions.getValue();
  var position = boxEntity.position.getValue(0);

  var heading = 0;
  if (typeof boxEntity.orientation != "undefined") {
    let rotationM3 = Cesium.Matrix3.fromQuaternion(
      boxEntity.orientation._value,
      new Cesium.Matrix3()
    );
    let localFrame = Cesium.Matrix4.fromRotationTranslation(
      rotationM3,
      Cesium.Cartesian3.ZERO,
      new Cesium.Matrix4()
    );
    let inverse = Cesium.Matrix4.inverse(
      Cesium.Transforms.eastNorthUpToFixedFrame(position),
      new Cesium.Matrix4()
    );
    let hprm = Cesium.Matrix4.multiply(
      inverse,
      localFrame,
      new Cesium.Matrix4()
    );
    var rotation = Cesium.Matrix4.getMatrix3(hprm, new Cesium.Matrix3());
    let hpr = Cesium.HeadingPitchRoll.fromQuaternion(
      Cesium.Quaternion.fromRotationMatrix(rotation)
    );
    heading = hpr.heading;
  }

  var boxOptions = {
    dimensions: newDim,
    position: position,
    clipMode: clipMode.value,
    heading: heading,
  };
  setAllLayersClipOptions(boxOptions);
}

function setAllLayersClipColor() {
  for (var i = 0, j = layers.length; i < j; i++) {
    layers[i].clipLineColor = new Cesium.Color(1, 1, 1, 0);
  }
}

function setAllLayersClipOptions(boxOptions) {
  for (var i = 0, j = layers.length; i < j; i++) {
    layers[i].setCustomClipBox(boxOptions);
  }
}
//判断模型图层是否加载
function layerLoad() {
  ElMessage({
    message: "请先添加三维倾斜摄影模型图层!",
    type: "warning",
    duration: 6000,
    showClose: true,
    offset: 80,
    grouping: true,
  });
}
//清除
function clearbox() {
  if (layers == null) {
    layerLoad();
  } else {
    for (var i = 0, j = layers.length; i < j; i++) {
      layers[i].clearCustomClipBox();
    }
    editorBox.deactivate();
    viewer.entities.removeAll();
    handlerBox.clear();
    handlerBox.deactivate();
    handlerBox.activate();
  }
}

</script>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值