コード例 #1
0
        static StlMesh[] ImportSmoothNormals(IEnumerable <Facet> faces, CoordinateSpace modelCoordinateSpace, UpAxis modelUpAxis, IndexFormat indexFormat)
        {
            var facets         = faces as Facet[] ?? faces.ToArray();
            int maxVertexCount = indexFormat == IndexFormat.UInt32 ? MaxFacetsPerMesh32 * 3 : MaxFacetsPerMesh16 * 3;
            int triangleCount  = facets.Length * 3;

            //Dictionary<StlVector3, StlVector3> smoothNormals = new Dictionary<StlVector3, StlVector3>(triangleCount / 2);

            //// In case meshes are split, we need to calculate smooth normals first
            //foreach(var face in faces)
            //{
            //	var x = (StlVector3) face.a;
            //	var y = (StlVector3) face.b;
            //	var z = (StlVector3) face.c;
            //	var normal = face.normal;

            //	if(smoothNormals.ContainsKey(x))
            //		smoothNormals[x] += normal;
            //	else
            //		smoothNormals.Add(x, normal);

            //	if(smoothNormals.ContainsKey(y))
            //		smoothNormals[y] += normal;
            //	else
            //		smoothNormals.Add(y, normal);

            //	if(smoothNormals.ContainsKey(z))
            //		smoothNormals[z] += normal;
            //	else
            //		smoothNormals.Add(z, normal);
            //}

            int numProcs         = Environment.ProcessorCount;
            int concurrencyLevel = numProcs * 2;
            ConcurrentDictionary <StlVector3, StlVector3> smoothNormals = new ConcurrentDictionary <StlVector3, StlVector3>(concurrencyLevel, triangleCount / 2);

            // In case meshes are split, we need to calculate smooth normals first
            Parallel.ForEach(faces, (face) => {
                var x      = face.a;
                var y      = face.b;
                var z      = face.c;
                var normal = face.normal;

                if (smoothNormals.ContainsKey(x))
                {
                    smoothNormals[x] += normal;
                }
                else
                {
                    smoothNormals.TryAdd(x, normal);
                }

                if (smoothNormals.ContainsKey(y))
                {
                    smoothNormals[y] += normal;
                }
                else
                {
                    smoothNormals.TryAdd(y, normal);
                }

                if (smoothNormals.ContainsKey(z))
                {
                    smoothNormals[z] += normal;
                }
                else
                {
                    smoothNormals.TryAdd(z, normal);
                }
            });


            List <StlMesh> meshes = new List <StlMesh>();

            List <StlVector3>            pos = new List <StlVector3>(Math.Min(maxVertexCount, triangleCount));
            List <StlVector3>            nrm = new List <StlVector3>(Math.Min(maxVertexCount, triangleCount));
            List <int>                   tri = new List <int>(triangleCount);
            Dictionary <StlVector3, int> map = new Dictionary <StlVector3, int>();
            int vertex = 0;

            StlVector3[] points = new StlVector3[3];

            foreach (var face in facets)
            {
                if (vertex + 3 > maxVertexCount)
                {
                    var mesh = new StlMesh
                    {
                        vertices    = pos.ToArray(),
                        normals     = nrm.ToArray(),
                        indexFormat = indexFormat
                    };
                    if (modelCoordinateSpace == CoordinateSpace.Right)
                    {
                        tri.Reverse();
                    }
                    mesh.triangles = tri.ToArray();
                    meshes.Add(mesh);

                    vertex = 0;

                    pos.Clear();
                    nrm.Clear();
                    tri.Clear();
                    map.Clear();
                }

                points[0] = face.a;
                points[1] = face.b;
                points[2] = face.c;

                for (int i = 0; i < 3; i++)
                {
                    int index = -1;
                    var hash  = points[i];

                    if (!map.TryGetValue(hash, out index))
                    {
                        if (modelCoordinateSpace == CoordinateSpace.Right)
                        {
                            pos.Add(Stl.ToCoordinateSpace(points[i], CoordinateSpace.Left));
                            nrm.Add(Stl.ToCoordinateSpace(smoothNormals[hash].normalized, CoordinateSpace.Left));
                        }
                        else
                        {
                            pos.Add(points[i]);
                            nrm.Add(smoothNormals[hash].normalized);
                        }

                        tri.Add(vertex);
                        map.Add(hash, vertex++);
                    }
                    else
                    {
                        tri.Add(index);
                    }
                }
            }


            if (vertex > 0)
            {
                var mesh = new StlMesh
                {
                    vertices    = pos.ToArray(),
                    normals     = nrm.ToArray(),
                    indexFormat = indexFormat
                };
                if (modelCoordinateSpace == CoordinateSpace.Right)
                {
                    tri.Reverse();
                }
                mesh.triangles = tri.ToArray();
                meshes.Add(mesh);

                vertex = 0;

                pos.Clear();
                nrm.Clear();
                tri.Clear();
                map.Clear();
            }

            return(meshes.ToArray());
        }
コード例 #2
0
        static StlMesh[] ImportHardNormals(IEnumerable <Facet> faces, CoordinateSpace modelCoordinateSpace, UpAxis modelUpAxis, IndexFormat indexFormat)
        {
            var facets = faces as Facet[] ?? faces.ToArray();
            int faceCount = facets.Length, f = 0;
            int maxFacetsPerMesh = indexFormat == IndexFormat.UInt32 ? MaxFacetsPerMesh32 : MaxFacetsPerMesh16;
            int maxVertexCount   = maxFacetsPerMesh * 3;

            StlMesh[] meshes = new StlMesh[faceCount / maxFacetsPerMesh + 1];

            for (int meshIndex = 0; meshIndex < meshes.Length; meshIndex++)
            {
                int          len = System.Math.Min(maxVertexCount, (faceCount - f) * 3);
                StlVector3[] v   = new StlVector3[len];
                StlVector3[] n   = new StlVector3[len];
                int[]        t   = new int[len];

                for (int it = 0; it < len; it += 3)
                {
                    v[it]     = facets[f].a;
                    v[it + 1] = facets[f].b;
                    v[it + 2] = facets[f].c;

                    n[it]     = facets[f].normal;
                    n[it + 1] = facets[f].normal;
                    n[it + 2] = facets[f].normal;

                    t[it]     = it + 0;
                    t[it + 1] = it + 1;
                    t[it + 2] = it + 2;

                    f++;
                }

                if (modelCoordinateSpace == CoordinateSpace.Right)
                {
                    for (int i = 0; i < len; i += 3)
                    {
                        v[i + 0] = Stl.ToCoordinateSpace(v[i + 0], CoordinateSpace.Left);
                        v[i + 1] = Stl.ToCoordinateSpace(v[i + 1], CoordinateSpace.Left);
                        v[i + 2] = Stl.ToCoordinateSpace(v[i + 2], CoordinateSpace.Left);

                        n[i + 0] = Stl.ToCoordinateSpace(n[i + 0], CoordinateSpace.Left);
                        n[i + 1] = Stl.ToCoordinateSpace(n[i + 1], CoordinateSpace.Left);
                        n[i + 2] = Stl.ToCoordinateSpace(n[i + 2], CoordinateSpace.Left);

                        var a = t[i + 2];
                        t[i + 2] = t[i];
                        t[i]     = a;
                    }
                }

                meshes[meshIndex] = new StlMesh
                {
                    vertices    = v,
                    normals     = n,
                    triangles   = t,
                    indexFormat = indexFormat
                };
            }

            return(meshes);
        }
コード例 #3
0
        public Spine(string key, List <Vertex> points, List <Geometry> geometries, int direction)
        {
            Key        = key;
            Points     = points;
            Geometries = geometries;
            if (Points.Count == 4)
            {
                //Считывание модели из файла
                Model = new StlMesh(StlFile.Load(new FileStream("FullModel.stl", FileMode.Open, FileAccess.Read))
                                    .Triangles);

                int k = 0;

                Up    = new List <Pointes>();
                Down  = new List <Pointes>();
                UpC   = new List <Pointes>();
                DownC = new List <Pointes>();
                using (StreamReader sr = new StreamReader("up.txt"))
                {
                    while (sr.Peek() >= 0)
                    {
                        string   str;
                        string[] strArray;
                        str = sr.ReadLine();

                        strArray = str.Split(' ');
                        Pointes currentPoint = new Pointes();
                        currentPoint.X = float.Parse(strArray[0], NumberStyles.Float, CultureInfo.InvariantCulture);
                        currentPoint.Y = float.Parse(strArray[1], NumberStyles.Float, CultureInfo.InvariantCulture);
                        currentPoint.Z = float.Parse(strArray[2], NumberStyles.Float, CultureInfo.InvariantCulture);
                        Up.Add(currentPoint);
                    }
                }
                using (StreamReader sr = new StreamReader("down.txt"))
                {
                    while (sr.Peek() >= 0)
                    {
                        string   str;
                        string[] strArray;
                        str = sr.ReadLine();

                        strArray = str.Split(' ');
                        Pointes currentPoint = new Pointes();
                        currentPoint.X = float.Parse(strArray[0], NumberStyles.Float, CultureInfo.InvariantCulture);
                        currentPoint.Y = float.Parse(strArray[1], NumberStyles.Float, CultureInfo.InvariantCulture);
                        currentPoint.Z = float.Parse(strArray[2], NumberStyles.Float, CultureInfo.InvariantCulture);
                        Down.Add(currentPoint);
                    }
                }
                using (StreamReader sr = new StreamReader("up_corner.txt"))
                {
                    while (sr.Peek() >= 0)
                    {
                        string   str;
                        string[] strArray;
                        str = sr.ReadLine();

                        strArray = str.Split(' ');
                        Pointes currentPoint = new Pointes();
                        currentPoint.X = float.Parse(strArray[0], NumberStyles.Float, CultureInfo.InvariantCulture);
                        currentPoint.Y = float.Parse(strArray[1], NumberStyles.Float, CultureInfo.InvariantCulture);
                        currentPoint.Z = float.Parse(strArray[2], NumberStyles.Float, CultureInfo.InvariantCulture);
                        UpC.Add(currentPoint);
                    }
                }
                using (StreamReader sr = new StreamReader("down_corner.txt"))
                {
                    while (sr.Peek() >= 0)
                    {
                        string   str;
                        string[] strArray;
                        str = sr.ReadLine();

                        strArray = str.Split(' ');
                        Pointes currentPoint = new Pointes();
                        currentPoint.X = float.Parse(strArray[0], NumberStyles.Float, CultureInfo.InvariantCulture);
                        currentPoint.Y = float.Parse(strArray[1], NumberStyles.Float, CultureInfo.InvariantCulture);
                        currentPoint.Z = float.Parse(strArray[2], NumberStyles.Float, CultureInfo.InvariantCulture);
                        DownC.Add(currentPoint);
                    }
                }
                U = new List <int>();
                foreach (var a in Up)
                {
                    foreach (var b in Model.Vertices)
                    {
                        if (a.X == b.X && a.Y == b.Y && a.Z == b.Z)
                        {
                            U.Add(b.IdInMesh);
                        }
                    }
                }
                D = new List <int>();
                foreach (var a in Down)
                {
                    foreach (var b in Model.Vertices)
                    {
                        if (a.X == b.X && a.Y == b.Y && a.Z == b.Z)
                        {
                            D.Add(b.IdInMesh);
                        }
                    }
                }
                UC = new List <int>();
                foreach (var a in UpC)
                {
                    foreach (var b in Model.Vertices)
                    {
                        if (a.X == b.X && a.Y == b.Y && a.Z == b.Z)
                        {
                            UC.Add(b.IdInMesh);
                        }
                    }
                }
                DC = new List <int>();
                foreach (var a in DownC)
                {
                    foreach (var b in Model.Vertices)
                    {
                        if (a.X == b.X && a.Y == b.Y && a.Z == b.Z)
                        {
                            DC.Add(b.IdInMesh);
                        }
                    }
                }

                //TODO Здесь добавить маркировку точек

                if (direction == 0)
                {
                    //Отражение
                    Model.Vertices = Transformation.ConvertPointsArrayToList(
                        Transformation.ReflectionObject(Transformation.ConvertPointsListToArray(Model.Vertices), true,
                                                        false, false));
                }

                //Масштабирование
                var dy = Vertex.D(Points[2], Points[3]) / Vertex.D(Model.Vertices[_k2], Model.Vertices[_k3]);
                var dx = Vertex.D(Points[2], Points[1]) / Vertex.D(Model.Vertices[_k2], Model.Vertices[_k1]);
                Model.Vertices =
                    Transformation.ConvertPointsArrayToList(
                        Transformation.ScaleObject(Transformation.ConvertPointsListToArray(Model.Vertices), dx, dy,
                                                   dx));

                //Поворот
                double k2 = (Points[0].Y - Points[3].Y) / (Points[0].X - Points[3].X);
                double k1 = (Model.Vertices[_k0].Y - Model.Vertices[_k3].Y) /
                            (Model.Vertices[_k0].X - Model.Vertices[_k3].X);
                double alfa = Math.Atan((k2 - k1) / (1 + k2 * k1));
                Model.Vertices = Transformation.ConvertPointsArrayToList(Transformation.Rotate(alfa,
                                                                                               Transformation.ConvertPointsListToArray(Model.Vertices), 3, 0, 0, 0));

                //Перемещение
                Model.Vertices = Transformation.ConvertPointsArrayToList(Transformation.MoveObject(
                                                                             Transformation.ConvertPointsListToArray(Model.Vertices), Points[3].X - Model.Vertices[_k3].X,
                                                                             Points[3].Y - Model.Vertices[_k3].Y, 0));
            }
        }