示例#1
0
        //--------------------------------------------------------------------------------------------------

        static void _CreateFaces(List <ObjectDescription> objectDescList, List <Pnt> vertices)
        {
            // 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(), null));
            }
        }
示例#2
0
    private void BuildMesh()
    {
        int[] indices = TriangulationHelper.Triangulate2D(_polygonCollider2D.points);

        Vector3[] vertices = new Vector3[_polygonCollider2D.points.Length];
        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i] = _polygonCollider2D.points[i] + _polygonCollider2D.offset;
        }

        if (_meshFilter.sharedMesh == null)
        {
            _meshFilter.sharedMesh = new Mesh();
        }

        if (_meshFilter.sharedMesh.vertices != vertices)
        {
            _meshFilter.sharedMesh.vertices  = vertices;
            _meshFilter.sharedMesh.triangles = indices;
            _meshFilter.sharedMesh.RecalculateNormals();
            _meshFilter.sharedMesh.RecalculateBounds();
            _meshRenderer.sortingOrder = _orderInLayer;

            _meshFilter.sharedMesh.name      = "geometry";
            _meshFilter.sharedMesh.hideFlags = HideFlags.HideAndDontSave;
        }
    }
示例#3
0
    private void OnDrawGizmos()
    {
        PolygonCollider2D polygonCollider2D = this.gameObject.GetComponent <PolygonCollider2D>();

        int[] indices = TriangulationHelper.Triangulate2D(polygonCollider2D.points);

        Vector3[] vertices = new Vector3[polygonCollider2D.points.Length];
        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i] = polygonCollider2D.points[i] + polygonCollider2D.offset;
        }

        MeshFilter meshFilter = this.gameObject.GetComponent <MeshFilter>();

        MeshRenderer meshRenderer = this.gameObject.GetComponent <MeshRenderer>();

        if (meshFilter.sharedMesh == null || meshFilter.sharedMesh.vertices.Length != vertices.Length)
        {
            meshFilter.sharedMesh = new Mesh();
        }

        meshFilter.sharedMesh.vertices  = vertices;
        meshFilter.sharedMesh.triangles = indices;
        meshFilter.sharedMesh.RecalculateNormals();
        meshFilter.sharedMesh.RecalculateBounds();
        meshRenderer.sortingOrder = _orderInLayer;

        meshFilter.sharedMesh.name      = "geometry";
        meshFilter.sharedMesh.hideFlags = HideFlags.HideAndDontSave;
    }
示例#4
0
        //--------------------------------------------------------------------------------------------------

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

                    // Binary or Ascii?
                    var tempBuffer = new byte[80];
                    fs.Read(tempBuffer, 0, 80);

                    var header = Encoding.ASCII.GetString(tempBuffer).TrimStart(' ');
                    if (header.StartsWith("solid", StringComparison.InvariantCultureIgnoreCase))
                    {
                        reader = new StlAsciiReader();
                    }
                    else
                    {
                        reader = new StlBinaryReader();
                    }
                    var predictedTriangleCount = reader.Init(fs);

                    // Read facets
                    var vertices = new List <Pnt>(predictedTriangleCount * 3);
                    while (reader.MoveNext())
                    {
                        vertices.Add(reader.CurrentVertices[0]);
                        vertices.Add(reader.CurrentVertices[1]);
                        vertices.Add(reader.CurrentVertices[2]);
                    }

                    // Create Shape
                    var face = TriangulationHelper.CreateFaceFromTriangulation(new TriangulationData(null, vertices.ToArray()));
                    var body = Body.Create(Mesh.Create(face));
                    body.Name = Path.GetFileNameWithoutExtension(fileName);

                    bodies = new[] { body };

                    // Cleanup
                    fs.Close();
                }

                return(true);
            }
            catch (Exception e)
            {
                Messages.Exception($"Exception occured while importing {fileName}.", e);
                return(false);
            }
        }
        private static void AddVertexToTriangulation(int vertexId, List <SortedVertex> vertices, HullEdgesList convexHull,
                                                     TriangulationGraph graph)
        {
            FixTriangulationIteratively(vertexId, vertices, convexHull, HullEdge.IterationDirections.Right,
                                        (v1, v2) => TriangulationHelper.CrossProduct(v1, v2) > -DelaunayTriangulationValidator.Eps,
                                        (left, right, outer) => FixTriangulation(left, right, outer, vertices, graph));

            var hullVertex = FixTriangulationIteratively(vertexId, vertices, convexHull, HullEdge.IterationDirections.Left,
                                                         (v1, v2) => TriangulationHelper.CrossProduct(v1, v2) < DelaunayTriangulationValidator.Eps,
                                                         (left, right, outer) => FixTriangulation(right, left, outer, vertices, graph));

            convexHull[convexHull[vertexId].Right].Set(HullEdge.IterationDirections.Left, vertexId);
            convexHull[hullVertex].Set(HullEdge.IterationDirections.Right, vertexId);
        }
        /// <summary>
        /// Returns a trajectory created from input file
        /// </summary>
        public virtual IEnumerable <IPoint> GetTrajectory(string inputFilePath)
        {
            var inputData        = LoadInputData(inputFilePath) as InputData;
            var trajectoryPoints = new List <IPoint>();
            var timesCollection  = inputData.PropagationTime;

            OutputData = new List <string>();
            foreach (var time in timesCollection)
            {
                var position = TriangulationHelper.GetPosition(inputData.Receivers, time, PublicFields.Error) as TwoDimensialPoint;
                if (position != null)
                {
                    (OutputData as List <string>).Add($"{position.XPosition.ToString("0.00000000", CultureInfo.InvariantCulture)}{PublicFields.PositionSeparator}{position.YPosition.ToString("0.00000000", CultureInfo.InvariantCulture)}");
                    trajectoryPoints.Add(position);
                }
            }

            return(trajectoryPoints);
        }
        private static void FixTriangulation(int left, int right, int outer, IReadOnlyList <SortedVertex> vertices,
                                             TriangulationGraph graph)
        {
            var recursionStack = new Edge[vertices.Count];

            recursionStack[0] = new Edge(left, right);
            var stackSize = 1;

            while (stackSize > 0)
            {
                left  = recursionStack[stackSize - 1].Vertex1;
                right = recursionStack[stackSize - 1].Vertex2;
                --stackSize;

                var inner = graph[new Edge(Mathf.Min(left, right), Mathf.Max(left, right))].Min();

                if (DelaunayTriangulationValidator.Validate(left, right, outer, inner, vertices))
                {
                    graph[new Edge(right, outer)].Insert(left);
                    graph[new Edge(left, outer)].Insert(right);

                    if (right < left)
                    {
                        TriangulationHelper.Swap(ref left, ref right);
                    }
                    graph[new Edge(left, right)].Insert(outer);
                    continue;
                }

                graph[new Edge(right, outer)].Replace(left, inner);
                graph[new Edge(left, outer)].Replace(right, inner);

                graph[new Edge(Mathf.Min(inner, left), Mathf.Max(inner, left))].Replace(right, outer);
                graph[new Edge(Mathf.Min(inner, right), Mathf.Max(inner, right))].Replace(left, outer);

                graph.Remove(new Edge(Mathf.Min(left, right), Mathf.Max(left, right)));

                recursionStack[stackSize++] = new Edge(left, inner);
                recursionStack[stackSize++] = new Edge(inner, right);
            }
        }
示例#8
0
    private void UpdateMesh(bool initialize = false)
    {
        if (!initialize)
        {
            if (!_meshRenderer.isVisible)
            {
                return;
            }
            if (_settleScale <= 0)
            {
                return;
            }
        }

        Vector2[] pathPoints = GetPathPoints();

        _polygonCollider2D.points = pathPoints;

        int[] indices = TriangulationHelper.Triangulate2D(pathPoints);

        Vector3[] vertices    = new Vector3[pathPoints.Length];
        int       vertexCount = vertices.Length;

        for (int i = 0; i < vertexCount; i++)
        {
            vertices[i] = pathPoints[i];
        }

        Mesh mesh = _meshFilter.sharedMesh;

        // Update mesh
        if (mesh.vertexCount == 0 || mesh.vertexCount == vertexCount)
        {
            mesh.vertices  = vertices;
            mesh.triangles = indices;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
        }
    }
示例#9
0
        public static bool Export(IEnumerable <Body> bodies, string fileName, bool binaryFormat)
        {
            var sumTriangleCount = 0;
            var triangulations   = new List <TriangulationData>();

            foreach (var body in bodies)
            {
                var shape = body.Shape.GetTransformedBRep();
                if (shape == null)
                {
                    continue;
                }

                var triangulation = TriangulationHelper.GetTriangulation(shape, false);
                if (triangulation.TriangleCount == 0)
                {
                    continue;
                }

                triangulations.Add(triangulation);
                sumTriangleCount += triangulation.TriangleCount;
            }

            if (sumTriangleCount == 0)
            {
                return(false);
            }

            IStlWriter writer;

            if (binaryFormat)
            {
                writer = new StlBinaryWriter();
            }
            else
            {
                writer = new StlAsciiWriter();
            }
            writer.Init("Written by Macad3D STL-Export", sumTriangleCount);

            foreach (var triangulation in triangulations)
            {
                var index = 0;
                for (int triangle = 0; triangle < triangulation.TriangleCount; triangle++)
                {
                    // Get vertices
                    var vertex1 = triangulation.Vertices[triangulation.Indices[index]];
                    var vertex2 = triangulation.Vertices[triangulation.Indices[index + 1]];
                    var vertex3 = triangulation.Vertices[triangulation.Indices[index + 2]];
                    index += 3;

                    // Calculate normal of facet
                    var vec1   = new Vec(vertex1, vertex2);
                    var vec2   = new Vec(vertex1, vertex3);
                    var normal = vec1.Crossed(vec2);
                    if (normal.SquareMagnitude() > gp.Resolution)
                    {
                        normal.Normalize();
                    }
                    else
                    {
                        normal = default;
                    }

                    // Write out facet
                    writer.AddFacet(normal, vertex1, vertex2, vertex3);
                }
            }

            return(writer.WriteToFile(fileName));
        }
示例#10
0
        public static bool Export(string fileName, IEnumerable <Body> bodies, bool smoothEdges)
        {
            ObjAsciiWriter writer = new ObjAsciiWriter();

            writer.Init("Written by Macad3D OBJ-Export");

            var indexOffset = 1;                           // OBJ list index starts with 1
            var vertexMap   = new Dictionary <Pnt, int>(); // Written vertex to resulting index
            var indexList   = new List <int>();

            foreach (var body in bodies)
            {
                var shape = body.Shape.GetTransformedBRep();
                if (shape == null)
                {
                    continue;
                }

                var triangulation = TriangulationHelper.GetTriangulation(shape, false);
                if (triangulation.TriangleCount == 0)
                {
                    continue;
                }

                writer.AddObject(body.Name);

                if (smoothEdges) // Export smooth edges
                {
                    for (var vtxIndex = 0; vtxIndex < triangulation.Vertices.Length; vtxIndex++)
                    {
                        var vertex = triangulation.Vertices[vtxIndex];
                        int newIndex;
                        if (!vertexMap.TryGetValue(vertex, out newIndex))
                        {
                            writer.AddVertex(vertex);
                            newIndex = vertexMap.Count + indexOffset;
                            vertexMap.Add(vertex, newIndex);
                        }

                        indexList.Add(newIndex);
                    }

                    for (int i = 0; i < triangulation.Indices.Length; i += 3)
                    {
                        writer.AddFace(indexList[triangulation.Indices[i]], indexList[triangulation.Indices[i + 1]], indexList[triangulation.Indices[i + 2]]);
                    }
                }
                else // Export face by face
                {
                    foreach (var vertex in triangulation.Vertices)
                    {
                        writer.AddVertex(vertex);
                    }

                    for (int i = 0; i < triangulation.Indices.Length; i += 3)
                    {
                        writer.AddFace(triangulation.Indices[i] + indexOffset, triangulation.Indices[i + 1] + indexOffset, triangulation.Indices[i + 2] + indexOffset);
                    }
                }


                indexOffset += smoothEdges ? vertexMap.Count : triangulation.Vertices.Length;
                vertexMap.Clear(); // Don't share vertices between objects
                indexList.Clear();
            }

            return(writer.WriteToFile(fileName));
        }
示例#11
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);
            }
        }
 /// <summary>
 /// ctor
 /// </summary>
 public TwoDimensialTracker()
 {
     TriangulationHelper = new TriangulationHelper();
 }