首页 / 浏览问题 / 组件GIS / 问题详情
iobjectsdotnet开发,重新计算法线报错
17EXP 2025年08月27日

使用产品:supermap-iobjectsdotnet-10.1.0

操作系统:win10 x64

调用重新计算法线方法对SuperMap.Data.Model对象进行法线计算,打断点的这一行,程序报错。

1个回答

您好,

请截全您的代码片段,无法确定 skeleton 变量是如何进行赋值的,初步判断是源数据传入的不正确,请尝试将源数据集写死为已存在的在桌面端新建的模型数据集,查看该方法是否有效。

查看到您使用的是 10i 版本的组件产品,该版本产品在9月30日之后全面停止支持,请尽快升级,参考生命周期公告: https://www.supermap.com/support/#/productlifecycle
1,380EXP 2025年08月27日
                    Skeleton skeleton = new Skeleton();
                    skeleton.Name = geometryid + "_skeleton";
                    double[] doublevertice = new double[vertice.Count];
                    for (int i = 0; i < vertice.Count; i++)
                        doublevertice[i] = (double)(vertice[i] * m_scale);

                    skeleton.SetVertices(doublevertice);
                    skeleton.VertexIndexes = indexes.ToArray();

                    List<float> normalsArray = new List<float>();
                    for (int i = 0; i < indexes.Count; i++)
                    {
                        SuperMap.Data.Point3D p = normalslist[indexes[i]];
                        normalsArray.Add((float)p.X);
                        normalsArray.Add((float)p.Y);
                        normalsArray.Add((float)p.Z);
                    }
                    skeleton.Normals = normalsArray.ToArray();

                    //材质
                    var matParams = m_materialsList[materialid];
                    string guid = "mtl_" + Guid.NewGuid().ToString();
                    Material3D material3D = new Material3D();
                    material3D.Name = geometryid + "_mtl"; ;
                    material3D.Name = guid;

                    if (matParams.TextureName != "")
                    {
                        TextureData texturedata = new TextureData();
                        texturedata.Name = "tex_" + Guid.NewGuid().ToString();
                        texturedata.FromFile(matParams.TextureName);

                        List<float> uvCoor = new List<float>();
                        for (int i = 0; i < indexes.Count; i++)
                        {
                            SuperMap.Data.Point2D p = uvslist[indexes[i]];
                            uvCoor.Add((float)p.X);
                            uvCoor.Add((float)p.Y);
                        }

                        List<float[]> textureCoords = new List<float[]>();
                        textureCoords.Add(uvCoor.ToArray());
                        skeleton.TextureCoords = textureCoords;

                        int[] TextureIndexes = new int[indexes.Count];
                        for (int i = 0; i < indexes.Count; i++)
                        {
                            TextureIndexes[i] = i;
                        }
                        skeleton.TextureIndexes = TextureIndexes;
                        material3D.Texture = texturedata;
                    }
                    else
                    {
                        material3D.MaterialColor = System.Drawing.Color.FromArgb(Convert.ToInt32(matParams.Alpha * 255), Convert.ToInt32(matParams.Red * 255),
                        Convert.ToInt32(matParams.Green * 255), Convert.ToInt32(matParams.Blue * 255));
                    }
                    skeleton.Material = material3D;

                    Model model = new Model();
                    model.Add(skeleton);

                    //重新计算法线和移除重复点顺序调换之后,生成数据集的数据量变大了
                    Model ReComputeNormalModel = new Model();
                    bool f = ModelBuilder3D.ReComputeNormal(model, ReComputeNormalModel, NormalComputeMode.AngleWeight, 0);

                    Model RemoveDuplicateVertex = new Model();
                    int vertexcount = ModelBuilder3D.RemoveDuplicateVertex2(ReComputeNormalModel, RemoveDuplicateVertex);

                    int skeletoncount = RemoveDuplicateVertex.GetSkeletonCount(-1);
                    for (int i = 0; i < skeletoncount; i++)
                    {
                        SkeletonID id = new SkeletonID(-1, i);
                        double[] matrix = null;
                        Skeleton sk = RemoveDuplicateVertex.GetSkeleton(id, ref matrix);
                        sk.Name = geometryid + "_skeleton";
                        m_dicSkeleton3D.Add(geometryid, sk);
                    }

我这个代码是2021年写的,当时一直没问题,最近一年没用了,什么都没改过,就出bug了

我把这4行代码注释掉就能正常使用,但是法线有问题。。。。。

Model ReComputeNormalModel = new Model();
bool f = ModelBuilder3D.ReComputeNormal(model, ReComputeNormalModel, NormalComputeMode.AngleWeight, 0);
Model RemoveDuplicateVertex = new Model();
int vertexcount = ModelBuilder3D.RemoveDuplicateVertex2(ReComputeNormalModel, RemoveDuplicateVertex);

您好,

请尝试先移除重复顶点再重新计算法线,确保法线计算基于最终的顶点结构,避免索引错乱。如果修改后运行仍有问题,请附上报错详细截图。

先移除重复顶点再重新计算法线,无法生成数据集,最终保存的数据集里面没有数据记录,程序运行的时候一直报错,请看图

...