模型合并,拆分,打散是模型编辑中较为常见的功能。近期遇到一些小伙伴咨询在iObjects.NET中中如何实现模型拆分和打散呢?接下来我们就来看看具体的实现思路吧。模型合并可参考该篇文档: iObjects.Net模型合并
一、打散和拆分介绍。
模型打散:有时模型数据子对象太多,可能会导致模型数据中顶点数及三角面过多,此类数据在生成缓存时有时会导致崩溃,此时需要将模型打散后进行操作。实现把模型对象中的每个“子对象”另存为模型对象,保证各个单独模型的尺寸等信息不变。
模型拆分:在完成BIM模型的搭建后,有时需要对诸如层高、墙厚、板厚、平面布置等反复核查,即需要获得模型子对象的对象。通过BIM子对象拆分可以得到这些构件的尺寸,避免自动拆分后造成预制构件尺寸不对,现场无法组装的情况。模型拆分后的对象比模型打散更加精细。
二、重要接口介绍
模型打散:
类 | 属性或方法 | 介绍 |
---|---|---|
Model | GetSkeleton | 获取指定的骨架 |
Model | GetSkeletonCount | 获取骨架数量 |
Model | AddSkeleton | 向精细层添加骨架 |
Model | GetSkeleton | 获取指定的骨架 |
模型拆分:
类 | 属性或方法 | 介绍 |
---|---|---|
ModelEntityManager | SplitSkeleton | 对模型的骨架进行拆分 |
三、实现思路
3.1 模型打散
模型打散没有直接的接口可以用,需要自行通过model.GetSkeleton
获取到原始模型的骨架后,存入一个新的独立的model。具体的步骤如下:
1、获取到原始数据集的记录集,新建一个模型数据集以存储打散后的数据
2、遍历原始记录集,获取到每个对象的model
3、通过model.GetSkeletonCount遍历其中的子对象。
4、通过 model.GetSkeleton获取每一个子对象的骨架。
5、新建model类,将上一步获取到的骨架存入新建的model中。
代码如下:
//获取原始数据集
DatasetVector datasetVector = m_workspace.Datasources[0].Datasets["单个模型"] as DatasetVector;
Recordset recordset = datasetVector.GetRecordset(false, CursorType.Dynamic);
//创建新模型数据集
DatasetVectorInfo datasetVectorInfo = new DatasetVectorInfo();
datasetVectorInfo.Type = DatasetType.Model;
datasetVectorInfo.IsFileCache = false;
datasetVectorInfo.Name = "模型打散706";
m_datasource = m_workspace.Datasources[0];
m_datasource.Datasets.Create(datasetVectorInfo);
DatasetVector datasetVectorNew = m_workspace.Datasources[0].Datasets["模型打散706"] as DatasetVector;
datasetVectorNew.PrjCoordSys = datasetVector.PrjCoordSys;//为新建的数据集赋坐标系
Recordset recordsetNew = datasetVectorNew.GetRecordset(false, CursorType.Dynamic);
recordsetNew.MoveFirst();
recordsetNew.Edit();
recordset.MoveFirst();
for (int i = 0; i < recordset.RecordCount; i++)//遍历记录集
{
GeoModel3D geoModel3D = recordset.GetGeometry() as GeoModel3D;
Model model = geoModel3D.Model;
for (int j = 0; j < model.GetSkeletonCount(-1); j++)//遍历子对象
{
int hh = model.GetSkeletonCount(-1);
SkeletonID skeletonID = new SkeletonID(-1, j);//-1代表LOD层,j代表骨骼编号(即子对象编号)
Skeleton skeletonNew = model.GetSkeleton(skeletonID);
Model modelNew = new Model();
modelNew.Add(skeletonNew);//将骨架存入模型
GeoModel3D geoModelNew = new GeoModel3D(modelNew)
{
Position = geoModel3D.Position,
};
geoModelNew.Position = geoModel3D.Position;
geoModelNew.Model = modelNew;
recordsetNew.AddNew(geoModelNew);//将模型数据集存入新记录集
recordsetNew.Update();
}
recordset.MoveNext();
}
datasetVectorNew.Close();
3.2 模型拆分
模型拆分使用的是ModelBuilder3D.SplitSkeleton()
方法。具体的步骤如下:
1、获取到原始数据集的记录集,新建一个模型数据集以存储拆分后的数据
2、遍历原始记录集,获取到每个对象的model
3、通过ModelBuilder3D.SplitSkeleton()拆分每一个model,并将结果存入新的model
5、将新的model存入新数据集即可。
代码如下:
DatasetVector datasetVector = m_workspace.Datasources[0].Datasets["单个模型"] as DatasetVector;
Recordset recordset = datasetVector.GetRecordset(false, CursorType.Dynamic);
//创建新模型数据集
DatasetVectorInfo datasetVectorInfo = new DatasetVectorInfo();
datasetVectorInfo.Type = DatasetType.Model;
datasetVectorInfo.IsFileCache = false;
datasetVectorInfo.Name = "模型拆分";
m_datasource = m_workspace.Datasources[0];
m_datasource.Datasets.Create(datasetVectorInfo);
DatasetVector datasetVectorNew = m_workspace.Datasources[0].Datasets["模型拆分706114"] as DatasetVector;
datasetVectorNew.PrjCoordSys = datasetVector.PrjCoordSys;
Recordset recordsetNew = datasetVectorNew.GetRecordset(false, CursorType.Dynamic);
recordsetNew.MoveFirst();
recordsetNew.Edit();
recordset.MoveFirst();
for (int i = 0; i < recordset.RecordCount; i++)//遍历记录集
{
GeoModel3D geoModel3D = recordset.GetGeometry() as GeoModel3D;
Model model = geoModel3D.Model;
Model modelNew = new Model();
Boolean result = ModelBuilder3D.SplitSkeleton(model, modelNew, true);//对模型的骨架进行拆分
int count = modelNew.GetSkeletonCount(-1);//获取lod层级为-1的骨架数量
GeoModel3D geoModelNew = new GeoModel3D();
geoModelNew.Model = modelNew;
geoModelNew.Position = geoModel3D.Position;
recordsetNew.AddNew(geoModelNew);//将模型数据集存入新记录集
recordsetNew.Update();
recordset.MoveNext();
}
四、实现效果
接下来让我们在桌面看一下具体的实现效果吧。
首先展示的是原始数据,该数据有1个对象,1个对象中包含了9个子对象。
通过模型打散后将所有的子对象存储成了对象,如下图所示,有9个对象,且每个对象只有一个子对象:
通过模型拆分以后,虽然还是1个对象,但子对象的个数却增加了,变成19个。如下图所示: