首页 / 浏览问题 / 组件GIS / 问题详情
请问如何把转换为模型的三维面设置纹理映射,然后显示到场景中?
5EXP 2024年01月22日

请问如何把转换为模型的三维面设置纹理映射,然后显示到场景中?我通过下列代码把三维面的对象转换为模型,但是没有纹理映射效果,模型所在数据集在桌面端打开可以看到材质,但是纹理坐标映射的设置都没有生效,请问有规范或者有效的设置方式吗?(环境为iobjects .net 11i)

 //获取镶嵌的三维面
 DatasetVector dataset = m_workspace.Datasources[0].Datasets["CombinePolygon"] as DatasetVector;
 dataset.IsReadOnly = false;
 Recordset rdRegion = dataset.GetRecordset(false, CursorType.Static);
 //创建三维模型数据集
 DatasetVectorInfo datasetInfo = new DatasetVectorInfo($"{dataset.Name}model", DatasetType.Model);
 DatasetVector newDataset = datasource.Datasets.Create(datasetInfo);
 newDataset.PrjCoordSys = dataset.PrjCoordSys;
 ModelEntityManager manager = new ModelEntityManager(newDataset);

 Layer3DSettingVector layer3DSettingVector = new Layer3DSettingVector();
 layer3DSettingVector.Style.AltitudeMode = AltitudeMode.Absolute;
 Layer3DDataset layer3DDatasetPoint = sceneControl1.Scene.Layers.Add(newDataset, layer3DSettingVector, true);
 layer3DDatasetPoint.IsEditable = true;
 newDataset.Open();
 Recordset recordset = newDataset.GetRecordset(false, CursorType.Dynamic);
 while (!rdRegion.IsEOF)
 {
     GeoRegion3D geometry = rdRegion.GetGeometry() as GeoRegion3D;
     GeoModel3D geoModel = geometry.ConvertToGeoModel3D(true);
     //设置模型纹理贴图
     int nCount = geoModel.Model.GetSkeletonCount(-1); // nCount = 1
     for (int i = 0; i < nCount; i++)
     {
         SkeletonID id = new SkeletonID(-1, 0);
         Skeleton skeleton = geoModel.Model.GetSkeleton(id); // 返回的sk是null
         Material3D material3D = skeleton.Material;
         TextureData textureData = new TextureData();
         textureData.Name = "bianpo.png";
         string strPath = @"E:\Users\34263\Desktop\边坡纹理贴图\bianpo.png";
         textureData.FromFile(strPath);
         material3D.Texture = textureData;
         skeleton.Material = material3D;
         // 更新纹理
         manager.Update(skeleton);
         manager.UpdateDataset();
     }
     // 重新映射纹理
     TextureMapParameter textureMapParameter = new TextureMapParameter();
     textureMapParameter.MappingMode = SuperMap.Realspace.ThreeDDesigner.TextureMappingMode.BOX;
     textureMapParameter.IsRealTexMapSize = true;
     textureMapParameter.IsRealWorldMapSize = true;
     textureMapParameter.MappingModelLength = 200;
     textureMapParameter.MappingModelWidth = 100;
     textureMapParameter.MappingModelWidth = 100;
     try
     {
         ModelBuilder3D.UVWMap(geoModel, textureMapParameter);
         ModelBuilder3D.TextureRemapping(geoModel.Model, geoModel.Model);
         Console.WriteLine("模型纹理更新成功");
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.Message);
     }

     manager.UpdateDataset();

     recordset.AddNew(geoModel);
     recordset.Update();
     rdRegion.MoveNext();
 }

1个回答

您好,

查看您的代码,您是从geoModel取的骨架,但是是在ModelEntityManager进行的更新。

整个过程是从纹理到材质再到骨架,您如果使用Model类,那整个过程都使用Model类中的方法,如果您使用ModelEntityManager类,那整个过程都使用ModelEntityManager中的方法。

以ModelEntityManager类下的方法为例,以下思路提供参考:ModelEntityManager.CreateTextureData创建纹理数据对象,

TextureData.Data或TextureData.Fromfile对返回的对象赋纹理,ModelEntityManager.UpdateTextureData更新指定名称列表的纹理数据, ModelEntityManager.GetMaterial按名称获取指定的材质对象,Material3D.Texture 设置贴图对象,或者直接Material3D.AddTexture对材质赋纹理,ModelEntityManager.UpdateMaterial更新指定名称列表的材质,ModelEntityManager.GetSkeleton按名称获取指定的骨架对象,Skeleton.Material设置材质对象,ModelEntityManager.UpdateSkeleton更新指定名称列表的骨架,ModelEntityManager.UpdateDataset更新数据集中的所有实体对象。

再从数据集获取所有模型对象,ModelBuilder3D.UVWMap 方法 (GeoModel3D, TextureMapParameter)重新计算纹理坐标,再将进行纹理贴图映射后的模型整体更新到数据集中。

建议可以在关键代码处打断点,以便查看程序的状态、变量的赋值和执行流程。

希望能够帮助到您!
435EXP 2024年01月22日
似乎11i不支持ModelEntityManager.CreateTextureData?
您好,

经确认,ModelEntityManager.CreateTextureData于11i已不提供使用,以上流程可直接从Material3D.AddTexture对材质赋纹理步骤开始。
...