• 【BIM】BIMFACE中创建矢量文本[下篇]


    背景

    上一篇文章中,我们通过threejs创建了矢量文本,并添加到了bimface场景中,但是仅仅加入到场景中并不是我们的目的,我们的目的是把这种矢量文本加到指定的构件或者空间上,以此标识该构件或空间所代表的含义,接下来就将我们创建的矢量文本添加到目标构件或空间上。

    思路

    在三维空间中,标识一个物体的位置信息,通常是通过世界坐标的形式,世界坐标由三个数字组成,分别代表X、Y、Z轴方向的坐标,那么如果要将创建的矢量文本加入到指定位置,就需要设置矢量文本的坐标,在threejs中,任何Mesh都有position属性,只要将该属性设置到构件所在的位置即可。在bimface中,任何一个构件都有自己的坐标,只要获取到构件的坐标并设置到矢量文本的position属性,就可以了。

    实践

    这里我们以绘制的空间为例,首先需要通过getRoomProperty获取模型中空间的属性以及边界信息,这些信息是绘制空间的必要条件,通过该接口可以获取到boundaryheight等信息,boundary描述了空间的边界,而height描述了该边界的垂直高度,由此便构成了一个封闭的空间。此外,还有两个核心参数,minPtmaxPt,计算矢量文本的位置就是通过这两个核心变量以及height来确定的,如下图

    计算出坐标后,还需要控制矢量文本的大小,因为相对于空间块太大或太小都不合适,所以文本的宽度大概是空间顶面的80%即可。经过测算(不一定准确),计算方式就是最大点和最小点的坐标距离的10%作为矢量文本的宽度。核心代码如下:

    
    // 验证矢量文本3D展示
    function loadText() {
        var loader = new THREE.FontLoader();
        loader.load('fonts/FZDaBiaoSong-B06S_Regular.json', function (font) {
            var xMid, text;
            var textShape = new THREE.BufferGeometry();
            var color = 0xff0009;
            var matDark = new THREE.LineBasicMaterial({
                color: color,
                side: THREE.DoubleSide
            });
    
            var matLite = new THREE.MeshBasicMaterial({
                color: color,
                transparent: true,
                wireframe: false,
                opacity: 0.9,
                side: THREE.DoubleSide
            });
    
            var message = "数字运维";
    
            // 参数列表:文本 | 字体大小 | 
            var shapes = font.generateShapes(message, 640, 2);
            var geometry = new THREE.ShapeGeometry(shapes);
    
            geometry.computeBoundingBox();
            xMid = - 0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x);
            geometry.translate(xMid, 0, 0);
            geometry.rotateX(0);
    
            textShape.fromGeometry(geometry);
            text = new THREE.Mesh(textShape, matLite);
    
            let id = '2794723';
            viewer.getRoomProperty(id, (data) => {
                let height = 4000;
                let min = data.minPt;
                let max = data.maxPt;
    
                console.log("min:", min);
                console.log("max:", max);
    
                // 计算顶面中心点坐标
                let centerX = (min.x + max.x) / 2;
                let centerY = (min.y + max.y) / 2;
                let centerZ = height;
                
                // 创建空间
                viewer.createRoom(data.boundary, height, id);
    
                // 设置矢量文本的世界坐标
                text.position.z = centerZ;
                text.position.x = centerX
                text.position.y = centerY;
                var group = new THREE.Group();
                group.add(text);
                viewer.addExternalObject("text", group);
                viewer.render();
            });
        });
    }
    

    上述代码和上一篇文章的不同之处就是在设置矢量文本坐标的时候,有些差别。

    效果

    矢量

    扩展

    目前为止,我们完成了将矢量文本加入到三维模型场景中的指定构件平面上,但是这个矢量文本是一个二维的,那如果我想让文本富有立体感,在Z轴方向有高度,该怎么办呢?其实很简单,我们构造矢量文本Mesh的时候,采用的是ShapeGeometry,我们只需要将ShapeGeometry替换成ExtrudeGeometry,同时设置下amount参数即可。代码做如下修改:

    // 参数列表:文本 | 字体大小 | 
    var shapes = font.generateShapes(message, 640, 2);
    var geometry = new THREE.ExtrudeGeometry(shapes,{amount:100});
    

    以下是富有立体感的矢量文本效果:

    立体效果

    作者:悠扬的牧笛
    地址:https://www.cnblogs.com/xhb-bky-blog/p/12459135.html
    声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

  • 相关阅读:
    可怕的用户习惯
    编程5年了,养成的臭脾气
    从5楼到9楼
    Google(10|9)大黄金定律
    如果我们也有Lab
    心情有点烦乱
    [zz]万能类型boost::any
    [zz]GDB调试精粹及使用实例
    [zz]sqlalchemy使用
    sqlalchemy实际使用
  • 原文地址:https://www.cnblogs.com/xhb-bky-blog/p/12459135.html
Copyright © 2020-2023  润新知