开发一个自己的三维建模工具
坐标成都,疫情+高温,出不了门,闲来无聊,给大家分享一个简单的自动化建模实现方案。
要求:通过后端服务实现,输出3DTiles切片
实现思路
一、技术栈分析
目前,GIS行业及相关行业(数字孪生、元宇宙等)进入到当今时代赋予的红利期。不少商业公司正在不断研发和发布自己的三维软件产品,传统的GIS平台软件大厂(易智瑞、超图等)也在三维可视化及应用领域不断发力,包括传统测绘行业也在向实景三维中国转型。
从GISer人的眼中来看,支撑数字孪生和元宇宙应用的技术点无非是:
3D数据模型(底层数据结构&存储逻辑)+三维建模(数据工程&建模技术)+三维应用(软件开发&项目价值)
今天就给大家分享一个Cesium开源技术栈的一环(三维自动建模),通过调用在线建模服务(输入模型底面),实时建模,返回模型切片地址(3dTiles)。
二、技术实现
1、搭建Nodejs+EXpress后端服务环境
需要windows开发环境、Windows服务器环境,依赖包如下:
如果需要mac、linux环境可以自行编译Cesium3DTilesConverter源码
2、开发上传接口
上传的参数:geojson数据集。84坐标系。可以是Cesium前端绘制的Geojson多边形集合。
var geojsons = {
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [……]
};
3、后端Geojson转SHP
引入第三方包:geojson2shp,进行转换操作。
let geojson_data = JSON.parse(data); //前端上传个geojson数据集对象
const options = {
layer: filename, //图层名称
targetCrs: 4326
}
//geojson转shp
convert(geojson_data, shpZip, options);
生成的shp默认是压缩包,需要进行加压缩操作。
let zip = new admZip(shpZip);
zip.extractAllTo(shpPath + filename, true);
4、后端SHP转3DTiles
SHP转3DTiles。
首先在github上直接下载的Cesium3DTilesConverter.exe可执行程序,放到Nodejs运行目录下
代码执行转换操作
// console.log("文件解压完成。");
let cmd = converterPath + `\Converter.exe --format gdal --input ` + shpPath + filename + ` --output ` + outputPath + filename + ` --field height --layer ` + filename;
exec(cmd, function (error, stdout, stderr) {
if (error) {
console.error(error);
}
else {
//记录前端传过来的参数
var str = JSON.stringify(parm);
fs.writeFile(outputPath + filename + "/parm.json", str, function (err, data) {
if (err) {
console.error(err);
}
});
// console.log("success");
res.send({'result': httserver + '/' + filename + '/tileset.json' });//返回最终处理结果 3dtiles切片地址
}
});
5、开发dxf转geojson接口
针对复杂的应用需求,通过前端绘制模型底面多边形的方式不太友好,我们可以选择手动处理得到模型底面的办法。比如根据复杂的建筑设计或装修图纸,提取/绘制房屋底面CAD(转成84坐标),输出dxf文件。
//首先将dxf文件上传到nodejs运行目录 outputPath 下
if (filename.toLowerCase().indexOf('.dxf') > -1) {
const outputPath = path.join(__dirname, 'upload/');
const content = fs.readFileSync(outputPath + filename, 'utf-8')
new DxfParser().parseContent(content)
.then(result => {
let geojson = toGeojson(result);
//cad闭合曲线转成面
if (geojson && geojson.features) {
for (let index = 0; index < geojson.features.length; index++) {
const feature = geojson.features[index];
if (feature && feature.geometry && feature.geometry.type == 'LineString') {
if (feature.geometry.coordinates.length > 2) {
if (feature.geometry.coordinates[0].toString() == feature.geometry.coordinates[feature.geometry.coordinates.length - 1].toString()) {
feature.geometry.type = 'Polygon';
feature.geometry.coordinates = [feature.geometry.coordinates];
} else {
if (polyline2polygon == 'true') { //传入参数,是否将线转成面
feature.geometry.type = 'Polygon';
feature.geometry.coordinates[feature.geometry.coordinates.length] = feature.geometry.coordinates[0];
feature.geometry.coordinates = [feature.geometry.coordinates];
}
}
}
}
}
}
//向前端返回dxf转geojson的结果,最好在前端做数据质检和业务逻辑控制
res.send({
status: true,
message: 'File is uploaded',
data: {
name: filename,
mimetype: dxffile.mimetype,
size: dxffile.size
},
geojson: geojson
});
})
}
三、示例效果
总结
对于中小型的项目应用(三维白模),我们分享这个方案是适合的。如果要进一步提高要求,可以通过自定义Cesium的渲染着色器来实现三维模型的高级可视化,或者改写3DTiles转换工具的代码实现纹理贴图。
这里提出两个更高阶的技术应用,欢迎交流讨论:
1、BIM模型管理的难点:轻量化、分片、按需加载、模型体量太多等
基于Cesium的应用场景:可选择在revit下进行二次开发(数据质检+自动轻量化+ 动态导出模型),动态转换3DTiles切片
2、三维管线自动建模与动态更新
区别于部分GIS平台软件的动态建模路线(本质上也是采用了软件提供的三维对象进行实时渲染)。另一种方式就是事先生成好模型,再加载到GIS引擎或游戏引擎进行渲染。针对Cesium应用,限定三维管线更新频率,可以在后台实时创建三维模型fbx(可借助blender强大的python能力,根据二维管线生成三维管线),动态转换成3DTiles。
更多资讯、合作交流、技术研讨,请关注作者微信:hebinabianyan