Пример #1
0
        public void PolygonEarClipping()
        {
            /*             6 --- 1
             *           /     /
             *        /     /
             *      5     2
             *        \     \
             *           \     \
             *             4 --- 3
             */
            var vertices = new List <Pnt>
            {
                new Pnt(double.NaN, double.NaN, double.NaN),   // Dummy vertex to test indexing
                new Pnt(1.0, -1.0, -0.0),
                new Pnt(-0.2, 0.0, 0.0),
                new Pnt(1.0, 1.0, 0.0),
                new Pnt(0.0, 1.0, 0.0),
                new Pnt(-1.0, 0.0, 0.0),
                new Pnt(0.0, -1.0, -0.0),
            };

            var indices = new List <int>
            {
                1, 2, 3, 4, 5, 6
            };

            var expected = new List <int>
            {
                1, 6, 5,
                5, 4, 3,
                5, 3, 2,
                5, 2, 1
            };

            var triangulator = new EarClippingTriangulator();
            var result       = triangulator.DoTriangulation(vertices, indices);

            Assert.NotNull(result);
            Assert.That(expected.SequenceEqual(result));

            // Change direction
            indices = new List <int>
            {
                6, 5, 4, 3, 2, 1
            };

            expected = new List <int>
            {
                1, 6, 5,
                5, 4, 3,
                5, 3, 2,
                5, 2, 1
            };

            result = triangulator.DoTriangulation(vertices, indices);
            Assert.NotNull(result);
            Assert.That(expected.SequenceEqual(result));
        }
Пример #2
0
        //--------------------------------------------------------------------------------------------------

        public static bool Import(string fileName, out IEnumerable <Body> bodies, bool singleBody)
        {
            bodies = null;

            using var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            var vertices = new List <Pnt>();

            var currentObject  = ObjectDescription.Create();
            var objectDescList = new List <ObjectDescription>();

            var reader = new ObjAsciiReader(fs);

            // Read
            string cmd;

            while (reader.MoveNext(out cmd))
            {
                switch (cmd)
                {
                case "o":
                case "g":
                    if (currentObject.Indices.Count != 0)
                    {
                        objectDescList.Add(currentObject);
                    }
                    currentObject = ObjectDescription.Create();
                    reader.GetObjectOrGroup(out currentObject.Name);
                    break;

                case "v":
                    if (!reader.GetVertex(out var vertex))
                    {
                        return(false);
                    }
                    vertices.Add(vertex);
                    break;

                case "f":
                case "fo":
                    if (!reader.GetFace(out var indices))
                    {
                        continue;
                    }

                    // Negative indices must be correctly re-assigned
                    // -1 => vertices.Count
                    // -2 => vertices.Count-1
                    for (int i = 0; i < indices.Length; i++)
                    {
                        if (indices[i] < 0)
                        {
                            indices[i] = vertices.Count + (indices[i] + 1);
                        }
                    }

                    if (indices.Length == 3)
                    {
                        currentObject.Indices.AddRange(indices.Take(3).Select(index => index - 1));     // Correct lower bound (from 1 to 0)
                    }
                    else
                    {
                        var triangulator = new EarClippingTriangulator();
                        var result       = triangulator.DoTriangulation(vertices, indices.Select(index => index - 1)); // Correct lower bound (from 1 to 0)
                        if (result != null)
                        {
                            currentObject.Indices.AddRange(result);
                        }
                    }

                    break;
                }
            }

            if (currentObject.Indices.Count != 0)
            {
                objectDescList.Add(currentObject);
            }

            _CreateFaces(objectDescList, vertices);

            bodies = _CreateBodies(objectDescList, Path.GetFileNameWithoutExtension(fileName), singleBody);

            // Cleanup
            fs.Close();

            return(true);
        }
Пример #3
0
        //--------------------------------------------------------------------------------------------------

        bool IBodyImporter.DoImport(string fileName, out IEnumerable <Body> bodies)
        {
            bodies = null;
            try
            {
                using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    var vertices = new List <Pnt>();

                    var currentObject  = ObjectDescription.Create();
                    var objectDescList = new List <ObjectDescription>();

                    var reader = new ObjAsciiReader(fs);

                    // Read
                    string cmd;
                    while (reader.MoveNext(out cmd))
                    {
                        switch (cmd)
                        {
                        case "o":
                        case "g":
                            if (currentObject.Indices.Count != 0)
                            {
                                objectDescList.Add(currentObject);
                            }
                            currentObject = ObjectDescription.Create();
                            reader.GetObjectOrGroup(out currentObject.Name);
                            break;

                        case "v":
                            if (!reader.GetVertex(out var vertex))
                            {
                                return(false);
                            }
                            vertices.Add(vertex);
                            break;

                        case "f":
                        case "fo":
                            if (!reader.GetFace(out var indices))
                            {
                                continue;
                            }

                            // Negative indices must be correctly re-assigned
                            // -1 => vertices.Count
                            // -2 => vertices.Count-1
                            for (int i = 0; i < indices.Length; i++)
                            {
                                if (indices[i] < 0)
                                {
                                    indices[i] = vertices.Count + (indices[i] + 1);
                                }
                            }

                            if (indices.Length == 3)
                            {
                                currentObject.Indices.AddRange(indices.Take(3).Select(index => index - 1));   // Correct lower bound (from 1 to 0)
                            }
                            else
                            {
                                var triangulator = new EarClippingTriangulator();
                                var result       = triangulator.DoTriangulation(vertices, indices.Select(index => index - 1)); // Correct lower bound (from 1 to 0)
                                if (result != null)
                                {
                                    currentObject.Indices.AddRange(result);
                                }
                            }

                            break;
                        }
                    }
                    if (currentObject.Indices.Count != 0)
                    {
                        objectDescList.Add(currentObject);
                    }

                    // Create Faces
                    foreach (var objectDesc in objectDescList)
                    {
                        // Extract used vertices
                        var usedVertices = new List <Pnt>();
                        var indexMap     = new Dictionary <int, int>();
                        for (int index = 0; index < objectDesc.Indices.Count; index++)
                        {
                            int newIndex;
                            int oldIndex = objectDesc.Indices[index];
                            if (!indexMap.TryGetValue(oldIndex, out newIndex))
                            {
                                newIndex = usedVertices.Count;
                                usedVertices.Add(vertices[oldIndex]);
                                indexMap.Add(oldIndex, newIndex);
                            }

                            objectDesc.Indices[index] = newIndex;
                        }

                        // Create shape
                        objectDesc.Face = TriangulationHelper.CreateFaceFromTriangulation(new TriangulationData(objectDesc.Indices.ToArray(), usedVertices.ToArray()));
                    }

                    // Create bodies
                    var    bodyList = new List <Body>();
                    string bodyName = Path.GetFileNameWithoutExtension(fileName);
                    if (Settings.ImportSingleBody)
                    {
                        var compound = new TopoDS_Compound();
                        var builder  = new BRep_Builder();
                        builder.MakeCompound(compound);
                        foreach (var objectDesc in objectDescList)
                        {
                            builder.Add(compound, objectDesc.Face);
                        }
                        var body = Body.Create(Mesh.Create(compound));
                        body.Name = bodyName;
                        bodyList.Add(body);
                    }
                    else
                    {
                        int index = 1;
                        foreach (var objectDesc in objectDescList)
                        {
                            var body = Body.Create(Mesh.Create(objectDesc.Face));
                            if (!objectDesc.Name.IsNullOrWhiteSpace())
                            {
                                body.Name = objectDesc.Name;
                            }
                            else
                            {
                                body.Name = $"{bodyName}_{index++}";
                            }
                            bodyList.Add(body);
                        }
                    }

                    bodies = bodyList;

                    // Cleanup
                    fs.Close();
                }

                return(true);
            }
            catch (Exception e)
            {
                Messages.Exception($"Exception occured while importing {fileName}.", e);
                return(false);
            }
        }