コード例 #1
0
    public void Test()
    {
        quality = new QualityOptions()
        {
            MinimumAngle = 5
        };

        Debug.Log("test!");

        List <Vector3> v = new List <Vector3>();

        v.Add(new Vector3(0, 0, 0));
        v.Add(new Vector3(10, 0, 95));
        v.Add(new Vector3(250, 0, 140));
        v.Add(new Vector3(200, 0, 20));
        v.Add(new Vector3(150, 0, 60));

        Generate(v);
    }
コード例 #2
0
        private void Refine()
        {
            if (mesh == null)
            {
                return;
            }

            double area = meshControlView.ParamMaxAreaValue;

            var quality = new QualityOptions();

            if (area > 0 && area < 1)
            {
                quality.MaximumArea = area * statisticView.Statistic.LargestArea;
            }

            quality.MinimumAngle = meshControlView.ParamMinAngleValue;

            double maxAngle = meshControlView.ParamMaxAngleValue;

            if (maxAngle < 180)
            {
                quality.MaximumAngle = maxAngle;
            }

            try
            {
                mesh.Refine(quality, meshControlView.ParamConformDelChecked);

                statisticView.UpdateStatistic(mesh);

                HandleMeshUpdate();
            }
            catch (Exception ex)
            {
                LockOnException();
                DarkMessageBox.Show("Exception - Refine", ex.Message, MessageBoxButtons.OK);
            }

            UpdateLog();
        }
コード例 #3
0
        public static TriangleNet.Mesh GetTriangleMesh(this IPolygonEntity polyEntity, float segmentLength = 0.1F)
        {
            int count = polyEntity.Points.Count;

            var triPolygon = new Polygon();

            for (int i = 0, j = 1; i < count; i++, j = (i + 1) % count)
            {
                var curPoint  = polyEntity.Points[i];
                var nextPoint = polyEntity.Points[j];

                var dis = curPoint.DistanceTo(nextPoint);

                var num = (int)(dis / segmentLength);

                int id       = i + 1;
                var segments = curPoint.SplitToSegments(nextPoint, num).Select(p => new Vertex(p.x, p.y, id)).ToArray();

                for (int m = 0, n = 1; m < segments.Count( ) - 1; m++, n = m + 1)
                {
                    triPolygon.Add(new Segment(segments [m], segments [n], id), 0);
                }
            }

            //等边三角形面积公式 :  S=√3a²/4; √3/4 = 0.443F;
            var area    = 0.443F * segmentLength * segmentLength;// * 1.25F;
            var options = new ConstraintOptions()
            {
                ConformingDelaunay = true
            };
            var quality = new QualityOptions()
            {
                MinimumAngle = 30F, MaximumArea = area
            };                                                                             // 0.2F };

            var triMesh = (TriangleNet.Mesh)triPolygon.Triangulate(options, quality);

            triMesh.Renumber( );

            return(triMesh);
        }
コード例 #4
0
        public static bool Run(bool print = false)
        {
            // Generate the input geometry.
            var poly = CreatePolygon();

            // Set minimum angle quality option.
            var quality = new QualityOptions()
            {
                MinimumAngle = 30.0
            };

            // Generate mesh using the polygons Triangulate extension method.
            var mesh = poly.Triangulate(quality);

            if (print)
            {
                SvgImage.Save(mesh, "example-3.svg", 500);
            }

            return(mesh.Triangles.Count > 0);
        }
コード例 #5
0
        public Region(RegionRule x, int[,] biomeMap)
        {
            Id    = regionCount++;
            biome = x.biome;
            foreach (var edge in x.edges)
            {
                foreach (int direction in startDirections(edge.touchPoint, biomeMap))
                {
                    calculateBounds(edge, direction, biomeMap);
                }
            }
            Simplify();
            if (holes.Count == 0)
            {
                foreach (var edge in x.edges)
                {
                    foreach (int direction in startDirections(edge.touchPoint, biomeMap))
                    {
                        calculateBounds(edge, direction, biomeMap);
                    }
                }
            }
            outerEdge = holes.First().Border;
            holes.RemoveAt(0);
            //holes.ForEach(hole => hole.Border.Reverse());
            var options = new ConstraintOptions()
            {
                ConformingDelaunay = true
            };
            var quality = new QualityOptions()
            {
                MinimumAngle = 25
            };
            var polygon = getPolygon();

            pathMesh     = polygon.Triangulate(options, quality);
            graphicsMesh = polygon.Triangulate();
        }
コード例 #6
0
        public static Mesh GenerateUnityMesh(this TriangleNetMesh triangleNetMesh, QualityOptions options = null)
        {
            if (options != null)
            {
                triangleNetMesh.Refine(options);
            }

            Mesh mesh             = new Mesh();
            var  triangleNetVerts = triangleNetMesh.Vertices.ToList();

            var triangles = triangleNetMesh.Triangles;

            Vector3[] verts     = new Vector3[triangleNetVerts.Count];
            int[]     trisIndex = new int[triangles.Count * 3];

            for (int i = 0; i < verts.Length; i++)
            {
                verts[i] = (Vector3)triangleNetVerts[i];
            }

            int k = 0;

            foreach (var triangle in triangles)
            {
                for (int i = 2; i >= 0; i--)
                {
                    trisIndex[k] = triangleNetVerts.IndexOf(triangle.GetVertex(i));
                    k++;
                }
            }

            mesh.vertices  = verts;
            mesh.triangles = trisIndex;

            mesh.RecalculateBounds();
            mesh.RecalculateNormals();
            return(mesh);
        }
コード例 #7
0
        public void FillPath(Color c, PointF [] path)
        {
            var polygon = new Polygon();

            List <TriangleNet.Geometry.Vertex> V = new List <TriangleNet.Geometry.Vertex>();

            for (int j = 0; j < path.Length; j++)
            {
                V.Add(new TriangleNet.Geometry.Vertex(path[j].X, path[j].Y));
            }
            polygon.AddContour(V);

            if (V.Count >= 3)
            {
                try
                {
                    var options = new ConstraintOptions()
                    {
                    };
                    var quality = new QualityOptions()
                    {
                    };

                    var mesh = polygon.Triangulate(options, quality);

                    foreach (var t in mesh.Triangles)
                    {
                        var A = t.GetVertex(0);
                        var B = t.GetVertex(1);
                        var C = t.GetVertex(2);
                        AddTriangle((float)A.X, (float)A.Y, (float)B.X, (float)B.Y, (float)C.X, (float)C.Y, c);
                    }
                }
                catch (Exception)
                {
                }
            }
        }
コード例 #8
0
        public static Mesh Triangulate(Polyline poly, Plane plane, double min_angle = 0.436332, double max_angle = Math.PI, double max_area = double.MaxValue)
        {
            min_angle = Rhino.RhinoMath.ToDegrees(min_angle);
            max_angle = Rhino.RhinoMath.ToDegrees(max_angle);

            var options = new ConstraintOptions()
            {
                ConformingDelaunay = true
            };
            var quality = new QualityOptions()
            {
                MinimumAngle = min_angle, MaximumAngle = max_angle, MaximumArea = max_area, VariableArea = true
            };

            Contour cnt = ToContour(poly, plane);

            Polygon pgon = new Polygon();

            pgon.Add(cnt);

            var tmesh = pgon.Triangulate(options, quality);

            return(ToRhinoMesh(tmesh));
        }
コード例 #9
0
ファイル: Example5.cs プロジェクト: Geri-Borbas/Triangle.NET
        public static bool Run(bool print = false)
        {
            // Generate the input geometry.
            var poly = CreatePolygon();

            // Define regions (first one defines the area constraint).
            poly.Regions.Add(new RegionPointer(1.5, 0.0, 1, 0.01));
            poly.Regions.Add(new RegionPointer(2.5, 0.0, 2));

            // Set quality and constraint options.
            var options = new ConstraintOptions()
            {
                ConformingDelaunay = true
            };

            var quality = new QualityOptions()
            {
                MinimumAngle = 25.0,
                VariableArea = true
            };

            //quality.UserTest = (t, area) => t.Label == 1 && area > 0.01;

            var mesh = poly.Triangulate(options, quality);

            var smoother = new SimpleSmoother();

            smoother.Smooth(mesh, 5);

            if (print)
            {
                SvgImage.Save(mesh, "example-5.svg", 500);
            }

            return(mesh.Triangles.Count > 0);
        }
コード例 #10
0
//		[Output("Mesh")]
//       public IDXMeshOut MOut;
        #endregion fields & pins

/*		public void Unify(IMesh mesh, ISpread<Vector2D> UniOut, ISpread<int> Indices, I)
 *              {
 *                      var vertices = mesh.Vertices;
 *                      int vCount = vertices.Count;
 *
 *              }
 */
        //called when data for any output pin is requested
        public void Evaluate(int SpreadMax)
        {
            SpreadMax          = SpreadUtils.SpreadMax(Fvert, FInput, FIsH, FMaxAngle, FMinAngle, FMaxArea, FConDel, FSplit, FSteiner, FBmark, FSmooth, FSmoothLimit, Freg, FRegInd, FConSeg);
            FOutput.SliceCount = SpreadMax;
            FVmark.SliceCount  = SpreadMax;
//			FMesh.SliceCount = SpreadMax;
            FRmark.SliceCount = SpreadMax;
            FInd.SliceCount   = SpreadMax;

            int index = 0;

            if (FCal[0])
            {
                List <int> shift = new List <int>();
                shift.Add(0);


                for (int meshID = 0; meshID < SpreadMax; meshID++)
                {
                    var polygon = new Polygon();

                    for (int contourID = 0; contourID < Fvert[meshID].SliceCount; contourID++)
                    {
                        int vertexcount = 0;



                        if (Fvert[meshID][contourID] != 0)
                        {
                            vertexcount = Fvert[meshID][contourID];
                        }
                        else
                        {
                            vertexcount = FInput[meshID].SliceCount;
                        }

                        ISpread <Vertex> vcsSpread = new Spread <Vertex>();
                        vcsSpread.SliceCount = vertexcount;



                        for (int i = 0; i < vertexcount; i++)
                        {
                            vcsSpread[i] = new Vertex(FInput[meshID][index + i].x, FInput[meshID][index + i].y, FBmark[meshID][index + i]);
                        }

                        if (vertexcount > 1)
                        {
                            if (FConSeg[meshID][contourID])
                            {
                                for (int segID = 0; segID < vertexcount - 1; segID++)
                                {
                                    polygon.Add(new Segment(vcsSpread[segID], vcsSpread[segID + 1]), true);
                                }
                            }
                            else
                            {
                                polygon.Add(new Contour(vcsSpread, contourID + 1), FIsH[meshID][contourID]);
                            }
                        }
                        else
                        {
                            polygon.Add(vcsSpread[0]);
                        }



                        index += vertexcount;
                    }

                    var quality = new QualityOptions()
                    {
                        MinimumAngle = FMinAngle[meshID], MaximumAngle = FMaxAngle[meshID], SteinerPoints = FSteiner[meshID]
                    };
                    if (Freg[meshID])
                    {
                        for (int regionID = 0; regionID < FRegInd[meshID].SliceCount; regionID++)
                        {
                            polygon.Regions.Add(new RegionPointer(FRegInd[meshID][regionID].x, FRegInd[meshID][regionID].x, FRegMark[meshID][regionID]));
                        }
                    }
                    else
                    {
                        quality.MaximumArea = FMaxArea[meshID][0];
                    }


                    // Triangulate the polygon
                    var options = new ConstraintOptions()
                    {
                        ConformingDelaunay = FConDel[meshID], SegmentSplitting = FSplit[meshID]
                    };
                    if (FSmooth[meshID])
                    {
                        options = new ConstraintOptions()
                        {
                            ConformingDelaunay = true, SegmentSplitting = FSplit[meshID]
                        }
                    }
                    ;



                    var mesh = polygon.Triangulate(options, quality);

                    if (Freg[meshID])
                    {
                        foreach (var t in mesh.Triangles)
                        {
                            // Set area constraint for all triangles
                            t.Area = FMaxArea[meshID][t.Label - 1];
                        }
                        // Use per triangle area constraint for next refinement
                        quality.VariableArea = true;


                        // Refine mesh to meet area constraint.
                        mesh.Refine(quality, FConDel[meshID]);
                    }

                    // Do some smoothing.
                    if (FSmooth[meshID])
                    {
                        (new SimpleSmoother()).Smooth(mesh, FSmoothLimit[meshID]);
                    }

                    mesh.Renumber();


                    int triangleCount = mesh.Triangles.Count;
                    int SliceOut      = triangleCount * 3;
                    int vertexCount   = mesh.Vertices.Count;



                    var vertices  = mesh.Vertices.ToSpread();
                    var triangles = mesh.Triangles.ToSpread();

                    FRmark[meshID] = new Spread <int>();

                    FInd[meshID].SliceCount = SliceOut;

                    if (FUni[meshID])
                    {
                        shift.Add(shift[meshID] + vertexCount * (Convert.ToInt32(FShift[0])));

                        FOutput[meshID].SliceCount = vertexCount;
                        FVmark[meshID].SliceCount  = vertexCount;
                        FRmark[meshID].SliceCount  = vertexCount;
                        //			FMesh[meshID] = mesh;



                        for (int i = 0; i < triangleCount; i++)
                        {
                            for (int tri = 0; tri < 3; tri++)
                            {
                                FInd[meshID][i * 3 + tri] = triangles[i].GetVertexID(tri) + shift[meshID];
                                if (triangles[i].Label >= FRmark[meshID][triangles[i].GetVertexID(tri)])
                                {
                                    FRmark[meshID][triangles[i].GetVertexID(tri)] = triangles[i].Label;
                                }
                            }
                        }

                        for (int j = 0; j < vertexCount; j++)
                        {
                            FOutput[meshID][j] = new Vector2D(vertices[j].X, vertices[j].Y);
                            FVmark[meshID][j]  = vertices[j].Label;
                        }



/*					List<int> OldIndices = new List<int>();
 *                                      List<int> NewIndices = new List<int>();
 *
 *                                      for (int s=0; s<FConSeg[meshID].SliceCount;s++){
 *                                              if (FConSeg[meshID][s]){
 *                                                      int startindex=0;
 *
 *                                                      int first=0;
 *                                                      for (int u=0; u<s;u++){
 *                                                              startindex+=Fvert[meshID][u];
 *                                                      }
 *
 *                                                      //only check for points on segments, excluding start and end points
 *
 *                                                      for (int segPID=1; segPID<Fvert[meshID][s]-1;segPID++){
 *                                                              int counter=0;
 *                                                              for (int vertID=0;vertID<vertexCount;vertID++){
 *                                                                      if (vertices[vertID].X==FInput[meshID][startindex+segPID].x && vertices[vertID].Y==FInput[meshID][startindex+segPID].y){
 *                                                                              counter++;
 *                                                                              if (counter>1){
 *                                                                                      OldIndices.Add(vertID);
 *                                                                                      NewIndices.Add(first);
 *                                                                              }
 *                                                                              else{
 *                                                                                      first = vertID;
 *                                                                              }
 *                                                                      }
 *                                                              }
 *                                                      }
 *
 *                                              for (int indexID=0; indexID<OldIndices.Count;indexID++){
 *
 *                                                      FInd[meshID].Select(num => num == OldIndices[indexID] ? NewIndices[indexID] : num);
 *                                                      }
 *                                              }
 *                                              }
 */
                        //remove duplicate points which do not belong to any triangle

                        List <int> GarbageIndex = new List <int>();
                        for (int vecID = 0; vecID < FOutput[meshID].SliceCount; vecID++)
                        {
                            bool isPart = false;

                            isPart = FInd[meshID].Contains(vecID);

                            if (!isPart)
                            {
                                GarbageIndex.Add(vecID);
                            }
                        }


                        GarbageIndex.Reverse();
                        for (int vecID = 0; vecID < GarbageIndex.Count; vecID++)
                        {
                            FOutput[meshID].RemoveAt(GarbageIndex[vecID]);
                        }
                        for (int g = 0; g < FInd[meshID].SliceCount; g++)
                        {
                            for (int h = 0; h < GarbageIndex.Count; h++)
                            {
                                if (FInd[meshID][g] >= GarbageIndex[h])
                                {
                                    int r = FInd[meshID][g] - 1;
                                    FInd[meshID][g] = r < 0 ? r + FOutput[meshID].SliceCount : r;
                                }                                 //can be -1?
                            }
                        }
                    }
                    else
                    {
                        shift.Add(shift[meshID] + SliceOut * (Convert.ToInt32(FShift[0])));

                        FOutput[meshID].SliceCount = SliceOut;
                        FVmark[meshID].SliceCount  = SliceOut;
                        FRmark[meshID].SliceCount  = SliceOut;

                        for (int i = 0; i < triangleCount; i++)
                        {
                            for (int tri = 0; tri < 3; tri++)
                            {
                                FOutput[meshID][i * 3 + tri] = new Vector2D(triangles[i].GetVertex(tri).X, triangles[i].GetVertex(tri).Y);
                                FVmark[meshID][i * 3 + tri]  = triangles[i].GetVertex(tri).Label;
                                FRmark[meshID][i * 3 + tri]  = triangles[i].Label;
                                FInd[meshID][i * 3 + tri]    = i * 3 + tri + +shift[meshID];
                            }
                        }
                    }
                }
            }
        }
    }
コード例 #11
0
        private void Triangulate()
        {
            if (input == null)
            {
                return;
            }

            var options = new ConstraintOptions();
            var quality = new QualityOptions();

            if (meshControlView.ParamConformDelChecked)
            {
                options.ConformingDelaunay = true;
            }

            if (meshControlView.ParamQualityChecked)
            {
                quality.MinimumAngle = meshControlView.ParamMinAngleValue;

                double maxAngle = meshControlView.ParamMaxAngleValue;

                if (maxAngle < 180)
                {
                    quality.MaximumAngle = maxAngle;
                }

                // Ignore area constraints on initial triangulation.

                //double area = slMaxArea.Value * 0.01;
                //if (area > 0 && area < 1)
                //{
                //    var size = input.Bounds;
                //    double min = Math.Min(size.Width, size.Height);
                //    mesh.SetOption(Options.MaxArea, area * min);
                //}
            }

            if (meshControlView.ParamConvexChecked)
            {
                options.Convex = true;
            }

            try
            {
                if (meshControlView.ParamSweeplineChecked)
                {
                    mesh = (Mesh)input.Triangulate(options, quality, new SweepLine());
                }
                else
                {
                    mesh = (Mesh)input.Triangulate(options, quality);
                }

                statisticView.UpdateStatistic(mesh);

                HandleMeshUpdate();

                if (meshControlView.ParamQualityChecked)
                {
                    settings.RefineMode = true;
                }
            }
            catch (Exception ex)
            {
                LockOnException();
                DarkMessageBox.Show("Exception - Triangulate", ex.Message, MessageBoxButtons.OK);
            }

            UpdateLog();
        }
コード例 #12
0
 public OutlineTriangulator(int width, int height)
 {
     this.Width      = width;
     this.Height     = height;
     _qualityOptions = new QualityOptions();
 }
コード例 #13
0
ファイル: FEModel.cs プロジェクト: MagmaWorks/Harold
        private Mesh3 meshSlab(Shell slab, List <List <MWPoint3D> > walls)
        {
            Shell  s = slab;
            double z = s.Points.Min(p => p.Z);
            List <List <MWPoint3D> > wallSegments = new List <List <MWPoint3D> >();

            foreach (var w in walls)
            {
                if (Math.Abs(w[0].Z - z) < 1e-5 && Math.Abs(w[1].Z - z) < 1e-5)
                {
                    wallSegments.Add(w);
                }
            }

            // we reorder the walls according to their center X coordinate then center Y coordinate
            wallSegments = wallSegments.OrderBy(seg => 0.5 * (seg[0].X + seg[1].X)).ToList();
            //wallSegments = wallSegments.OrderBy(seg => 0.5 * (seg[0].Y + seg[1].Y)).ToList();
            foreach (var w in wallSegments)
            {
                s.IncludedSegments.Add(new List <MWPoint3D>()
                {
                    new MWPoint3D(w[0].X, w[0].Y, w[0].Z), new MWPoint3D(w[1].X, w[1].Y, w[1].Z)
                });
            }

            List <MWPoint2D> s2D = s.Points.Select(p => new MWPoint2D(p.X, p.Y)).ToList();

            foreach (var b in modelGeo.Beams)
            {
                if (Polygons.isInside(s2D, new MWPoint2D(b.Start.X, b.Start.Y)))
                {
                    if (b.Start.Z == z)
                    {
                        if (!s.IncludedVertices.Contains(b.Start))
                        {
                            s.IncludedVertices.Add(b.Start);
                        }
                    }
                    else if (b.End.Z == z)
                    {
                        if (!s.IncludedVertices.Contains(b.End))
                        {
                            s.IncludedVertices.Add(b.End);
                        }
                    }
                }
            }

            // create mesh using Triangle.NET library
            Polygon      pol       = new Polygon();
            var          res       = NormalizeShell(s);
            GeoTransform transform = res.Item2;
            var          holesN    = s.Holes.Select(h => ApplyGeoTransform(h, transform)).ToList();
            var          segN      = s.IncludedSegments.Select(seg => ApplyGeoTransform(seg, transform)).ToList();
            var          cols      = ApplyGeoTransform(s.IncludedVertices, transform);

            pol.Add(new Contour(res.Item1));

            // holes are added
            for (int j = 0; j < s.Holes.Count; j++)
            {
                pol.Add(new Contour(holesN[j]), true);
            }

            // segments coming from wall meshes are added
            List <Vertex> addedVertices = new List <Vertex>();

            // WARNING : Here are just added the segments with both endpoints new. It might not work every time.
            // If a problem is encountered, it might be worth adding the points as vertices and not as segments.
            for (int j = 0; j < segN.Count; j++)
            {
                //if (!addedVertices.Contains(new Vertex(segN[j][0].X, segN[j][0].Y)) && !addedVertices.Contains(new Vertex(segN[j][1].X, segN[j][1].Y)))
                if (!ContainsVertex(addedVertices, segN[j][0]) && !ContainsVertex(addedVertices, segN[j][1]))
                {
                    pol.Add(new Segment(segN[j][0], segN[j][1]), true);
                    addedVertices.Add(segN[j][0]);
                    addedVertices.Add(segN[j][1]);
                }
                //else if (addedVertices.Contains(new Vertex(segN[j][0].X, segN[j][0].Y)) && addedVertices.Contains(new Vertex(segN[j][1].X, segN[j][1].Y)))
                else if (ContainsVertex(addedVertices, segN[j][0]) && ContainsVertex(addedVertices, segN[j][1]))
                {
                    //Console.WriteLine("Both endpoints already added...");
                }
                //else if (addedVertices.Contains(new Vertex(segN[j][0].X, segN[j][0].Y)))
                else if (ContainsVertex(addedVertices, segN[j][0]))
                {
                    //pol.Add(new Segment(segN[j][0], segN[j][1]), 1);
                    //addedVertices.Add(segN[j][1]);
                }
                //else if (addedVertices.Contains(new Vertex(segN[j][1].X, segN[j][1].Y)))
                else if (ContainsVertex(addedVertices, segN[j][1]))
                {
                    //pol.Add(new Segment(segN[j][0], segN[j][1]), 0);
                    //addedVertices.Add(segN[j][0]);
                }
            }

            // vertices coming from columns are added
            cols.ForEach(c => pol.Add(c));

            //pol.Add(new Segment(new Vertex(segN[0][0].X, segN[0][0].Y), new Vertex(segN[0][1].X, segN[0][1].Y)), true);
            //pol.Add(new Segment(new Vertex(segN[2][0].X, segN[2][0].Y), new Vertex(segN[2][1].X, segN[2][1].Y)), true);
            double maxL    = getMaxDim(s);
            double maxarea = 0.1 / maxL;

            Configuration  config = new Configuration();
            QualityOptions qo     = new QualityOptions()
            {
                MinimumAngle = 15,
                MaximumArea  = maxarea
            };
            //ConstraintOptions co = new ConstraintOptions()
            //{
            //    SegmentSplitting = 1
            //};

            Mesh          MyMesh  = (new GenericMesher()).Triangulate(pol, qo) as Mesh;
            List <Point3> meshPts = deNormalizeMesh(MyMesh.Vertices, s, transform);

            //
            return(new Mesh3(meshPts, MyMesh.Triangles.Select(t =>
                                                              new Face3(MyMesh.Vertices.ToList().IndexOf(t.GetVertex(0)),
                                                                        MyMesh.Vertices.ToList().IndexOf(t.GetVertex(1)),
                                                                        MyMesh.Vertices.ToList().IndexOf(t.GetVertex(2)))).ToList()));
        }
コード例 #14
0
ファイル: FEModel.cs プロジェクト: MagmaWorks/Harold
        private (Mesh3, List <List <MWPoint3D> >) meshWall(Shell wall, List <List <MWPoint3D> > existingPts = null)
        {
            // create mesh using Triangle.NET library
            Shell w = wall.Clone();

            // pre addition of points on the contours
            List <MWPoint3D> refinedPts = new List <MWPoint3D>();

            for (int i = 0; i < w.Points.Count; i++)
            {
                int        k   = i == w.Points.Count - 1 ? 0 : i + 1;
                MWPoint3D  p0  = w.Points[i];
                MWPoint3D  p1  = w.Points[k];
                MWVector3D vec = new MWVector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
                vec = vec.Normalised();
                double dist = Points.Distance3D(p0, p1);
                int    n    = Convert.ToInt32(dist / 0.75) + 1;
                double inc  = dist / n;
                refinedPts.Add(p0);
                for (int j = 1; j < n; j++)
                {
                    MWPoint3D ptAdded = new MWPoint3D(p0.X + j * vec.X * inc, p0.Y + j * vec.Y * inc, p0.Z + j * vec.Z * inc);
                    refinedPts.Add(ptAdded);
                }
            }
            w.Points = refinedPts;

            if (existingPts != null)
            {
                List <MWPoint3D> exPts = existingPts.SelectMany(l => l).ToList();
                for (int i = 0; i < exPts.Count; i++)
                {
                    for (int j = 0; j < w.Points.Count; j++)
                    {
                        int k = j == w.Points.Count - 1 ? 0 : j + 1;
                        if (PointIsOnLine(w.Points[j], w.Points[k], exPts[i]))
                        {
                            w.Points.Insert(k, exPts[i]);
                            j = 0;
                        }
                    }
                }
            }
            Polygon pol      = new Polygon();
            var     res      = NormalizeShell(w);
            var     vertices = res.Item1;

            pol.Add(new Contour(res.Item1));
            for (int i = 0; i < vertices.Count; i++)
            {
                int k = i == res.Item1.Count - 1 ? 0 : i + 1;
                if (Math.Sqrt(Math.Pow(vertices[i].X - vertices[k].X, 2) + Math.Pow(vertices[i].Y - vertices[k].Y, 2)) < 0.15)
                {
                    pol.Add(new Segment(vertices[i], vertices[k]), false);
                }
            }
            GeoTransform transform = res.Item2;

            double maxL    = getMaxDim(w);
            double maxarea = 0.1 / maxL;

            Configuration  config = new Configuration();
            QualityOptions qo     = new QualityOptions()
            {
                MinimumAngle = 20,
                MaximumArea  = maxarea,
            };

            Mesh MyMesh = (new GenericMesher()).Triangulate(pol, qo) as Mesh;

            List <Point3> meshPts = deNormalizeMesh(MyMesh.Vertices, wall, transform);

            // extracting the contour edges for future wall and slab meshing
            double xmax = MyMesh.Vertices.Max(p => p.X);
            double xmin = MyMesh.Vertices.Min(p => p.X);
            double ymax = MyMesh.Vertices.Max(p => p.Y);
            double ymin = MyMesh.Vertices.Min(p => p.Y);

            List <List <int> > edgesPtsIdx = MyMesh.Edges.Select(e =>
                                                                 new List <int>()
            {
                MyMesh.Vertices.ToList().IndexOf(MyMesh.Vertices.Single(p => p.ID == e.P0)),
                MyMesh.Vertices.ToList().IndexOf(MyMesh.Vertices.Single(p => p.ID == e.P1))
            }).ToList();


            List <Edge> edges = MyMesh.Edges.ToList();
            List <List <MWPoint3D> > TBEdges = new List <List <MWPoint3D> >();
            List <Vertex>            lv      = MyMesh.Vertices.ToList();

            for (int i = 0; i < edges.Count; i++)
            {
                bool b1 = lv[edgesPtsIdx[i][0]].X == xmin && lv[edgesPtsIdx[i][1]].X == xmin;
                bool b2 = lv[edgesPtsIdx[i][0]].X == xmax && lv[edgesPtsIdx[i][1]].X == xmax;
                bool b3 = lv[edgesPtsIdx[i][0]].Y == ymin && lv[edgesPtsIdx[i][1]].Y == ymin;
                bool b4 = lv[edgesPtsIdx[i][0]].Y == ymax && lv[edgesPtsIdx[i][1]].Y == ymax;
                if (b1 || b2 || b3 || b4)
                {
                    TBEdges.Add(new List <MWPoint3D>()
                    {
                        new MWPoint3D(meshPts[edgesPtsIdx[i][0]].X, meshPts[edgesPtsIdx[i][0]].Y, meshPts[edgesPtsIdx[i][0]].Z),
                        new MWPoint3D(meshPts[edgesPtsIdx[i][1]].X, meshPts[edgesPtsIdx[i][1]].Y, meshPts[edgesPtsIdx[i][1]].Z)
                    });
                }
            }

            return(new Mesh3(meshPts, MyMesh.Triangles.Select(t =>
                                                              new Face3(MyMesh.Vertices.ToList().IndexOf(t.GetVertex(0)),
                                                                        MyMesh.Vertices.ToList().IndexOf(t.GetVertex(1)),
                                                                        MyMesh.Vertices.ToList().IndexOf(t.GetVertex(2)))).ToList()),
                   TBEdges);
        }
コード例 #15
0
    public static bool Triangulate(List <Vector3> points, List <List <Vector3> > holes, out List <int> outIndices, out List <Vector3> outVertices)
    {
        outVertices = new List <Vector3>();
        outIndices  = new List <int>();

        Polygon poly = new Polygon();

        for (int i = 0; i < points.Count; i++)
        {
            float x = points[i].x;
            float y = points[i].z;
            poly.Add(new Vertex(x, y));

            if (i == points.Count - 1)
            {
                poly.Add(new Segment(new Vertex(x, y), new Vertex(points[0].x, points[0].z)));
            }
            else
            {
                poly.Add(new Segment(new Vertex(x, y), new Vertex(points[i + 1].x, points[i + 1].z)));
            }
        }

        for (int i = 0; i < holes.Count; i++)
        {
            List <Vertex> vertices = new List <Vertex>();
            for (int j = 0; j < holes[i].Count; j++)
            {
                vertices.Add(new Vertex(holes[i][j].x, holes[i][j].z));
            }
            poly.Add(new Contour(vertices), true);
        }
        ConstraintOptions constraints = new ConstraintOptions();
        QualityOptions    quality     = new QualityOptions();

        quality.MinimumAngle = MinimumAngle;
        quality.MaximumArea  = MaximumArea;
        var mesh = poly.Triangulate(constraints, quality);

        foreach (ITriangle t in mesh.Triangles)
        {
            for (int j = 2; j >= 0; j--)
            {
                bool found = false;
                for (int k = 0; k < outVertices.Count; k++)
                {
                    if ((outVertices[k].x == t.GetVertex(j).X) && (outVertices[k].y == t.GetVertex(j).Y))
                    {
                        outIndices.Add(k);
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    outVertices.Add(new Vector3((float)t.GetVertex(j).X, 0, (float)t.GetVertex(j).Y));
                    outIndices.Add(outVertices.Count - 1);
                }
            }
        }

        return(true);
    }
コード例 #16
0
        private void RenderColorPath(float[] path)
        {
            // triangulate polygon into mesh
            var polyVertices = new Vertex[path.Length / 2];
            var dimX         = _graph.DimX;
            var dimY         = _graph.DimY;

            for (var i = 0; i < path.Length / 2; i++)
            {
                polyVertices[i] = new Vertex(dimX.Scale(path[i * 2]), dimY.Scale(path[i * 2 + 1]));
            }

            var polygon = new Polygon();

            polygon.Add(new Contour(polyVertices));

            var options = new ConstraintOptions {
                Convex = false, ConformingDelaunay = false
            };
            var quality = new QualityOptions {
            };

            if (UseCategories)
            {
                quality = new QualityOptions {
                    MaximumArea = 0.002
                }
            }
            ;

            var generatedMesh = polygon.Triangulate(options, quality);


            // convert triangulated mesh into unity mesh
            var triangles = new int[generatedMesh.Triangles.Count * 3];
            var vertices  = new Vector3[generatedMesh.Triangles.Count * 3];
            var colors    = new Color32[vertices.Length];
            var counter   = 0;

            foreach (var triangle in generatedMesh.Triangles)
            {
                var vectors = triangle.vertices;
                triangles[counter + 0] = counter + 0;
                triangles[counter + 1] = counter + 2;
                triangles[counter + 2] = counter + 1;

                vertices[counter + 0] = new Vector3(Convert.ToSingle(vectors[0].x), Convert.ToSingle(vectors[0].y), 0);
                vertices[counter + 1] = new Vector3(Convert.ToSingle(vectors[1].x), Convert.ToSingle(vectors[1].y), 0);
                vertices[counter + 2] = new Vector3(Convert.ToSingle(vectors[2].x), Convert.ToSingle(vectors[2].y), 0);

                if (_useCategories && CategoryAxis == 'x')
                {
                    colors[counter + 0] = GetCategoryColor(vectors[0].x);
                    colors[counter + 1] = GetCategoryColor(vectors[1].x);
                    colors[counter + 2] = GetCategoryColor(vectors[2].x);
                }
                else if (_useCategories && CategoryAxis == 'y')
                {
                    colors[counter + 0] = GetCategoryColor(vectors[0].y);
                    colors[counter + 1] = GetCategoryColor(vectors[1].y);
                    colors[counter + 2] = GetCategoryColor(vectors[2].y);
                }
                else
                {
                    colors[counter + 0] = _color;
                    colors[counter + 1] = _color;
                    colors[counter + 2] = _color;
                }

                counter += 3;
            }

            var mesh = new Mesh();

            _filter.mesh   = mesh;
            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.colors32  = colors;
            mesh.RecalculateBounds();
        }
コード例 #17
0
        private async void RenderPath(float[][] path)
        {
            _currentRenderingCancelSource?.Cancel();
            _currentRenderingCancelSource = new CancellationTokenSource();
            var cancelToken = _currentRenderingCancelSource.Token;

            var triangulationTask = Task.Factory.StartNew(() =>
            {
                try
                {
                    cancelToken.ThrowIfCancellationRequested();

                    // triangulate polygon into mesh
                    var polyVertices = new Vertex[path.Length];

                    for (var i = 0; i < path.Length; i++)
                    {
                        polyVertices[i] = new Vertex(path[i][0], path[i][1]);
                    }

                    cancelToken.ThrowIfCancellationRequested();

                    var polygon = new Polygon();
                    polygon.Add(new Contour(polyVertices));

                    cancelToken.ThrowIfCancellationRequested();

                    var options = new ConstraintOptions {
                        Convex = false, ConformingDelaunay = false
                    };
                    var quality = new QualityOptions {
                    };

                    var result = polygon.Triangulate(options, quality);
                    cancelToken.ThrowIfCancellationRequested();
                    return(result);
                }
                catch (Exception e)
                {
                    Debug.LogError(e.Message);
                    return(null);
                }
            });

            var generatedMesh = await triangulationTask;

            if (cancelToken.IsCancellationRequested || generatedMesh == null)
            {
                return;
            }

            if (generatedMesh.Triangles.Count == 0)
            {
                return;
            }

            // convert triangulated mesh into unity mesh
            var triangles = new int[generatedMesh.Triangles.Count * 3];
            var vertices  = new Vector3[generatedMesh.Triangles.Count * 3];
            var uv        = new Vector2[generatedMesh.Triangles.Count * 3];

            var meshTask = Task.Factory.StartNew(() =>
            {
                var counter = 0;
                double minX = generatedMesh.Triangles.First().vertices[0].x;
                double maxX = generatedMesh.Triangles.First().vertices[0].x;
                double minY = generatedMesh.Triangles.First().vertices[0].y;
                double maxY = generatedMesh.Triangles.First().vertices[0].y;

                foreach (var triangle in generatedMesh.Triangles)
                {
                    var vectors = triangle.vertices;
                    foreach (var vertex in vectors)
                    {
                        minX = Math.Min(minX, vertex.x);
                        maxX = Math.Max(maxX, vertex.x);
                        minY = Math.Min(minY, vertex.y);
                        maxY = Math.Max(maxY, vertex.y);
                    }
                }

                var rangeX = maxX - minX;
                var rangeY = maxY - minY;

                foreach (var triangle in generatedMesh.Triangles)
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        return;
                    }

                    var vectors            = triangle.vertices;
                    triangles[counter + 0] = counter + 0;
                    triangles[counter + 1] = counter + 2;
                    triangles[counter + 2] = counter + 1;

                    vertices[counter + 0] = new Vector3(Convert.ToSingle(vectors[0].x), Convert.ToSingle(vectors[0].y), 0);
                    vertices[counter + 1] = new Vector3(Convert.ToSingle(vectors[1].x), Convert.ToSingle(vectors[1].y), 0);
                    vertices[counter + 2] = new Vector3(Convert.ToSingle(vectors[2].x), Convert.ToSingle(vectors[2].y), 0);

                    uv[counter + 0] = new Vector2(Convert.ToSingle((vectors[0].x - minX) / rangeX), Convert.ToSingle((vectors[0].y - minY) / rangeY));
                    uv[counter + 1] = new Vector2(Convert.ToSingle((vectors[1].x - minX) / rangeX), Convert.ToSingle((vectors[1].y - minY) / rangeY));
                    uv[counter + 2] = new Vector2(Convert.ToSingle((vectors[2].x - minX) / rangeX), Convert.ToSingle((vectors[2].y - minY) / rangeY));

                    counter += 3;
                }
            });

            await meshTask;

            if (cancelToken.IsCancellationRequested)
            {
                return;
            }
            _currentRenderingCancelSource = null;

            var mesh = new Mesh
            {
                vertices  = vertices,
                triangles = triangles,
                uv        = uv
            };

            mesh.RecalculateBounds();
            _meshFilter.mesh = mesh;
        }
コード例 #18
0
    // Use this for initialization
    void Start( )
    {
        var p = new Polygon();

        p.Add(CosSegements(-Size, -Size, Size, -Size, partsNum, 1));
        p.Add(CosSegements(Size, -Size, Size, Size, partsNum, 2));
        p.Add(CosSegements(Size, Size, -Size, Size, partsNum, 3));
        p.Add(CosSegements(-Size, Size, -Size, -Size, partsNum, 4));

        //var polygon = FileProcessor.Read("Assets/Plugins/Data/box_with_a_hole.poly");

        var options = new ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        var quality = new QualityOptions()
        {
            MinimumAngle = 25F, MaximumArea = 0.1F
        };

        var triMesh = (TriangleNet.Mesh)p.Triangulate(options, quality);

        var smoothing = new SimpleSmoother();

        smoothing.Smooth(triMesh);

        triMesh.Refine(quality);

        triMesh.Renumber( );

        int boneIndex0 = 0;
        var bindposes  = new List <Matrix4x4>();
        var bones      = new List <Transform>();

        var fBoneWeights = new List <BoneWeight>();

        var vertexLookup = new Dictionary <Point, Rigidbody>();

        Root = new GameObject( );
        Root.transform.parent        = transform;
        Root.transform.localRotation = Quaternion.identity;

        var voronoi = new StandardVoronoi(triMesh);

        var triAreas = triMesh.Triangles.Sum(t => t.Area());

        Debug.Log("Tri Areas : " + triAreas);

        Debug.Log("Vor Count : " + voronoi.Faces.Count);
        float SumArea = 0F;

        foreach (var face in voronoi.Faces)
        {
            var origins = face.GetAllVertices();
            //var origins = face.EnumerateEdges().Select(e => (Point) e.Origin);

            if (origins.Count() > 0)
            {
                SumArea += origins.Area( );
                var obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);//new GameObject();
                obj.transform.localScale = Vector3.one * 0.005F;
                var renderer = obj.GetComponent <MeshRenderer> ( );
                if (renderer)
                {
                    renderer.enabled = false;
                }

                //obj.GetComponent<SphereCollider> ( ).enabled = false;

                var center        = face.generator;// origins.MassCenter();
                var worldPosition = transform.TransformPoint(new Vector3(( float )center.x, ( float )center.y, 0));
                obj.transform.position = worldPosition;
                obj.transform.parent   = Root.transform;
                bones.Add(obj.transform);
                bindposes.Add(obj.transform.worldToLocalMatrix * transform.localToWorldMatrix);

                var weight = new BoneWeight();

                weight.boneIndex0 = boneIndex0;
                weight.weight0    = 1.0F;
                fBoneWeights.Add(weight);


                var rigidbody = obj.AddComponent <Rigidbody>();
                rigidbody.useGravity    = false;
                rigidbody.interpolation = RigidbodyInterpolation.Interpolate;
                rigidbody.mass          = origins.Area( ) * KGSM;
                rigidbody.drag          = 4;
                rigidbody.angularDrag   = 2;


                rigidbody.constraints ^= RigidbodyConstraints.FreezeRotation;

                //if ( center.y > 1.9 )                    rigidbody.isKinematic = true;
                if (center.y == Size)
                {
                    rigid_Up.Add(rigidbody);
                }
                else if (center.y == -Size)
                {
                    rigid_Down.Add(rigidbody);
                }
                else if (center.x == Size)
                {
                    rigid_Right.Add(rigidbody);
                }
                else if (center.x == -Size)
                {
                    rigid_Left.Add(rigidbody);
                }
                else
                {
                    others.Add(rigidbody);
                }

                All.Add(rigidbody);

                vertexLookup.Add(center, rigidbody);

                boneIndex0++;
            }

            //SkinnedMeshRenderer.BakeMesh
        }

        foreach (var edge in triMesh.Edges)
        {
            var v0       = triMesh.Vertices.ElementAt(edge.P0);
            var v1       = triMesh.Vertices.ElementAt(edge.P1);
            var pt_0     = new Vector2((float)v0.x, (float)v0.y);
            var pt_1     = new Vector2((float)v1.x, (float)v1.y);
            var distance = Vector2.Distance(pt_0, pt_1);

            var rigid_0 = vertexLookup[v0];
            var rigid_1 = vertexLookup[v1];

            var spring = rigid_0.gameObject.AddComponent <SpringJoint>();
            spring.connectedBody = rigid_1;
            spring.minDistance   = distance * .96F;
            spring.maxDistance   = distance * 1.00F;
            spring.spring        = 8F;
            spring.damper        = 0F;
            spring.autoConfigureConnectedAnchor = false;
            spring.enableCollision     = false;
            spring.connectedAnchor     = spring.anchor = Vector3.zero;
            spring.axis                = Vector3.back;
            spring.tolerance           = 0.01F;
            spring.enablePreprocessing = false;
        }

        var vertices = triMesh.Vertices.Select(v => new Vector3((float)v.x, (float)v.y, 0)).ToArray();

        var triangles = triMesh.Triangles.SelectMany(t => t.vertices.Select(v => v.id)).ToArray();//.Reverse()

        var normals = triMesh.Vertices.Select(v => transform.forward);

        var bounds = triMesh.bounds;
        var l      = bounds.Left;
        var b      = bounds.Bottom;
        var w      = bounds.Width;
        var h      = bounds.Height;
        var uvs    = triMesh.Vertices.Select(v => new Vector2(-(float)((v.x - l) / w), (float)((v.y - b) / h))).ToArray();

        Debug.Log(string.Format("Vertices : {0}, Edge : {1}, Segments : {2}, Triangles : {3}, Holes : {4}",
                                triMesh.Vertices.Count, triMesh.Edges.Count( ), triMesh.Segments.Count, triMesh.Triangles.Count, triMesh.Holes.Count));

        var skinnedRenderer = GetComponent <SkinnedMeshRenderer>();

        //var meshFilter = GetComponent<MeshFilter>();
        //if ( !meshFilter )
        //{
        //    meshFilter = gameObject.AddComponent<MeshFilter> ( );
        //}
        var uniMesh = new Mesh();

        uniMesh.vertices  = vertices;
        uniMesh.triangles = triangles;
        uniMesh.uv        = uvs;
        uniMesh.normals   = normals.ToArray( );

        uniMesh.boneWeights = fBoneWeights.ToArray( );
        uniMesh.bindposes   = bindposes.ToArray( );

        skinnedRenderer.sharedMesh = uniMesh;
        skinnedRenderer.bones      = bones.ToArray( );
        skinnedRenderer.rootBone   = Root.transform;

        //GetComponent<MeshCollider> ( ).sharedMesh = uniMesh;
    }
コード例 #19
0
ファイル: Homotopy.cs プロジェクト: mosuem/ariadne
    void set2DMesh(List <Vector3> staticPositions, MPath path2)
    {
        var mesh = meshes[0];

        mesh.Clear();
        var   polygon  = new Polygon();
        var   points   = getPoints(path2);
        var   vertices = ToVertex(points);
        var   contour  = new Contour(vertices);
        Point point    = null;

        for (int i = 0; i < staticPositions.Count; i++)
        {
            if (IsPointInPolygon(staticPositions[i], vertices))
            {
                point = new Point(staticPositions[i].x, staticPositions[i].y);
                UnityEngine.Debug.Log("Is inside");
                break;
            }
            else
            {
                if (IsPointInPolygon(constpoint, vertices))
                {
                    UnityEngine.Debug.Log(constpoint + " Is inside");
                }
            }
        }
        if (point != null)
        {
            polygon.Add(contour, point);
        }
        else
        {
            polygon.Add(contour);
        }
        var options = new ConstraintOptions()
        {
        };
        var quality = new QualityOptions()
        {
            //			MinimumAngle = 25,
            //			MaximumArea = 0.01d
        };
        // Triangulate the polygon
        var            polyMesh      = polygon.Triangulate(options, quality);
        var            polyVertices  = polyMesh.Vertices;
        var            polyTriangles = polyMesh.Triangles;
        List <Vector3> meshVertices  = new List <Vector3> ();
        List <int>     triangles     = getTriangles(polyTriangles, meshVertices);

        mesh.vertices  = meshVertices.ToArray();
        mesh.triangles = triangles.ToArray();
        //		Vector3[] normals = mesh.normals;
        //		for (int i = 0; i < normals.Length; i++)
        //			normals [i] = -normals [i];
        //		mesh.normals = normals;
        //		for (int m = 0; m < mesh.subMeshCount; m++) {
        //			int[] triangles2 = mesh.GetTriangles (m);
        //			for (int i = 0; i < triangles2.Length; i += 3) {
        //				int temp = triangles2 [i + 0];
        //				triangles2 [i + 0] = triangles2 [i + 1];
        //				triangles2 [i + 1] = temp;
        //			}
        //			mesh.SetTriangles (triangles2, m);
        //		}
    }
コード例 #20
0
    public void GeneratePolygon()
    {
        if (lockHeight)
        {
            for (int i = 1; i < points.Count; i++)
            {
                Vector3 vec = points[i];
                vec.y     = points[0].y;
                points[i] = vec;
            }
        }

        if (points.Count < 3)
        {
            return;
        }

        CenterPivot();

        splinePoints.Clear();
        for (int i = 0; i < points.Count; i++)
        {
            //if ((i == 0 || i == points.Count - 2 || i == points.Count - 1) && !true)
            //{
            //    continue;
            //}

            DisplayCatmullRomSpline(i);
        }



        List <Vector3> verticesList = new List <Vector3>();
        List <Vector3> verts        = new List <Vector3>();
        List <int>     indices      = new List <int>();

        verticesList.AddRange(splinePoints.ToArray());


        //Triangulator traingulator = new Triangulator(verts2d.ToArray());
        // indices.AddRange(traingulator.Triangulate());


        Polygon polygon = new Polygon();

        List <Vertex> vertexs = new List <Vertex>();

        for (int i = 0; i < verticesList.Count; i++)
        {
            Vertex vert = new Vertex(verticesList[i].x, verticesList[i].z);
            vert.z = verticesList[i].y;
            vertexs.Add(vert);
        }
        polygon.Add(new Contour(vertexs));

        var options = new ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        var quality = new QualityOptions()
        {
            MinimumAngle = 25, MaximumArea = maximumTriangleSize
        };



        TriangleNet.Mesh mesh = (TriangleNet.Mesh)polygon.Triangulate(options, quality);

        indices.Clear();
        foreach (var triangle in mesh.triangles)
        {
            Vertex vertex = mesh.vertices[triangle.vertices[2].id];

            Vector3 v0 = new Vector3((float)vertex.x, (float)vertex.z, (float)vertex.y);

            vertex = mesh.vertices[triangle.vertices[1].id];
            Vector3 v1 = new Vector3((float)vertex.x, (float)vertex.z, (float)vertex.y);
            vertex = mesh.vertices[triangle.vertices[0].id];
            Vector3 v2 = new Vector3((float)vertex.x, (float)vertex.z, (float)vertex.y);

            indices.Add(verts.Count);
            indices.Add(verts.Count + 1);
            indices.Add(verts.Count + 2);

            verts.Add(v0);
            verts.Add(v1);
            verts.Add(v2);
        }


        Vector3[] vertices = verts.ToArray();
        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i].y += yOffset;
        }

        currentMesh = new Mesh();

        currentMesh.vertices     = vertices;
        currentMesh.subMeshCount = 1;
        currentMesh.SetTriangles(indices, 0);
        Vector2[] uvs = new Vector2[vertices.Length];
        for (int i = 0; i < uvs.Length; i++)
        {
            uvs[i] = new Vector2(vertices[i].x, vertices[i].z) * 0.01f * uvScale;
        }


        Vector3[] normals = new Vector3[vertices.Length];
        for (int i = 0; i < normals.Length; i++)
        {
            normals[i] = Vector3.up;
        }
        Color[] colors = new Color[vertices.Length];
        for (int i = 0; i < colors.Length; i++)
        {
            colors[i] = Color.black;
        }

        currentMesh.uv      = uvs;
        currentMesh.normals = normals;
        currentMesh.colors  = colors;
        currentMesh.RecalculateTangents();
        currentMesh.RecalculateBounds();


        currentMesh.RecalculateTangents();
        currentMesh.RecalculateBounds();
        trianglesGenerated = indices.Count / 3;

        MeshFilter filter = GetComponent <MeshFilter>();

        filter.mesh = currentMesh;

        MeshCollider meshCollider = GetComponent <MeshCollider>();

        if (meshCollider != null)
        {
            meshCollider.sharedMesh = currentMesh;
        }
    }
コード例 #21
0
        public static UnityEngine.Mesh Triangulate2(List <List <Vector3> > polygons)
        {
            UnityEngine.Mesh   m         = new UnityEngine.Mesh();
            List <List <int> > Triangles = new List <List <int> >();
            List <int>         Edges     = new List <int>();
            List <Vector3>     Vertices  = new List <Vector3>();

            ConstraintOptions options = new ConstraintOptions()
            {
                ConformingDelaunay = false
            };
            QualityOptions quality = new QualityOptions()
            {
                MinimumAngle = 25.0
            };

            //if (polygons.Count < 3)
            //        return null;

            var    data        = new List <int>();
            var    polygon     = new Polygon();
            Vertex firstVert   = null;
            Vertex nextVert    = null;
            Vertex currentVert = null;

            /*
             * foreach (var sub in polygons)
             * {
             * if (IsClockwise(sub))
             * {
             *  nextVert = null;
             *  var wist = new List<Vector3>();
             *  for (int i = 0; i < sub.Count; i++)
             *  {
             *    if (nextVert == null)
             *    {
             *      currentVert = new Vertex(sub[i].x, sub[i].y, sub[i].z);
             *      nextVert = new Vertex(sub[i + 1].x, sub[i].y, sub[i + 1].z);
             *    }
             *    else
             *    {
             *      currentVert = nextVert;
             *      if (i == sub.Count - 1)
             *      {
             *        nextVert = firstVert;
             *      }
             *      else
             *      {
             *        nextVert = new Vertex(sub[i + 1].x, sub[i + 1].y, sub[i + 1].z);
             *      }
             *    }
             *
             *    if (i == 0)
             *      firstVert = currentVert;
             *
             *    wist.Add(sub[i]);
             *    polygon.Add(currentVert);
             *    polygon.Add(new Segment(currentVert, nextVert));
             *  }
             * }
             * else
             * {
             *  var cont = new List<Vertex>();
             *  var wist = new List<Vector3>();
             *  for (int i = 0; i < sub.Count; i++)
             *  {
             *    wist.Add(sub[i]);
             *    cont.Add(new Vertex(sub[i].x, sub[i].y, sub[i].z));
             *  }
             *  polygon.Add(new Contour(cont), true);
             * }
             * }
             */


            foreach (var sub in polygons)
            {
                var poly = new Polygon();
                var w    = new List <Vector3>();
                for (int i = 0; i < sub.Count; i++)
                {
                    //w.Add(sub[i]);
                    poly.Add(new Vertex(sub[i].x, sub[i].y, sub[i].z));
                }
                var mesh = poly.Triangulate();

                //crashes
                //var mesh = poly.Triangulate(options, quality);


                foreach (var tri in mesh.Triangles)
                {
                    data.Add(tri.GetVertexID(0));
                    data.Add(tri.GetVertexID(2));
                    data.Add(tri.GetVertexID(1));
                }

                foreach (var edge in mesh.Edges)
                {
                    if (edge.Label == 0)
                    {
                        continue;
                    }

                    Edges.Add(edge.P0);
                    Edges.Add(edge.P1);
                }


                using (var sequenceEnum = mesh.Vertices.GetEnumerator())
                {
                    while (sequenceEnum.MoveNext())
                    {
                        //Vertices.Add(new Vector3((float)sequenceEnum.Current.x, (float)sequenceEnum.Current.z, (float)sequenceEnum.Current.y));
                        Vertices.Add(new Vector3((float)sequenceEnum.Current.x, (float)0, (float)sequenceEnum.Current.y));
                    }
                }

                Triangles.Add(data);
            }


            //smoother mesh with smaller triangles and extra vertices in the middle

            //var mesh = (TriangleNet.Mesh)polygon.Triangulate(options, quality);
            m.SetVertices(Vertices);
            m.subMeshCount = Triangles.Count;
            for (int i = 0; i < Triangles.Count; i++)
            {
                var triangle = Triangles[i];
                m.SetTriangles(triangle, i);
            }

            //m.RecalculateNormals();
            return(m);
        }
コード例 #22
0
        public static UnityEngine.Mesh Mesh(this EPPZ.Geometry.Model.Polygon this_, Color color, TriangulatorType triangulator, string name = "")
        {
            // Create geometry.
            TriangleNet.Geometry.Polygon polygon = this_.TriangleNetPolygon();

            // Triangulate.
            ConstraintOptions options = new ConstraintOptions();
            // ConformingDelaunay
            // Convex
            // SegmentSplitting
            QualityOptions quality = new QualityOptions();
            // MinimumAngle
            // MaximumArea
            // UserTest
            // VariableArea
            // SteinerPoints
            IMesh triangulatedMesh = polygon.Triangulate(options, quality, TriangulatorForType(triangulator));

            // Counts.
            int vertexCount   = triangulatedMesh.Vertices.Count;
            int triangleCount = triangulatedMesh.Triangles.Count;

            // Mesh store.
            Vector3[]  _vertices  = new Vector3[vertexCount];
            Vector2[]  _uv        = new Vector2[vertexCount];
            Vector3[]  _normals   = new Vector3[vertexCount];
            Color[]    _colors    = new Color[vertexCount];
            List <int> _triangles = new List <int>();           // Size may vary

            // Vertices.
            int index = 0;

            foreach (TriangleNet.Geometry.Vertex eachVertex in triangulatedMesh.Vertices)
            {
                _vertices[index] = new Vector3(
                    (float)eachVertex.X,
                    (float)eachVertex.Y,
                    0.0f                     // As of 2D
                    );

                _uv[index]      = _vertices[index];
                _normals[index] = Vector3.forward;
                _colors[index]  = color;

                index++;
            }

            // Triangles.
            foreach (TriangleNet.Topology.Triangle eachTriangle in triangulatedMesh.Triangles)
            {
                // Get vertices.
                Point P2 = eachTriangle.GetVertex(2);
                Point P1 = eachTriangle.GetVertex(1);
                Point P0 = eachTriangle.GetVertex(0);

                // Get centroid.
                Vector2 centroid = new Vector2(
                    (float)(P2.X + P1.X + P0.X) / 3.0f,
                    (float)(P2.Y + P1.Y + P0.Y) / 3.0f
                    );

                // Add only if centroid contained.
                if (this_.ContainsPoint(centroid) || skipCentroidTest)
                {
                    _triangles.Add(P2.ID);
                    _triangles.Add(P1.ID);
                    _triangles.Add(P0.ID);
                }
            }

            // Create / setup mesh.
            Mesh mesh = new Mesh();

            mesh.vertices     = _vertices;
            mesh.uv           = _uv;
            mesh.normals      = _normals;
            mesh.colors       = _colors;
            mesh.subMeshCount = 1;
            mesh.SetTriangles(_triangles.ToArray(), 0);
            mesh.name = name;

            return(mesh);
        }
コード例 #23
0
ファイル: Example4.cs プロジェクト: a5rGithub/triangle.net-1
        public static Mesh RefineRegions()
        {
            // Generate the input geometry.
            var poly = new Polygon();

            var center = new Point(0, 0);

            // Three concentric circles.
            poly.Add(Example2.Circle(1.0, center, 0.1, 1), center);
            poly.Add(Example2.Circle(2.0, center, 0.1, 2));
            poly.Add(Example2.Circle(3.0, center, 0.3, 3));

            // Define regions.
            poly.Regions.Add(new RegionPointer(1.5, 0.0, 1));
            poly.Regions.Add(new RegionPointer(2.5, 0.0, 2));

            // Set quality and constraint options.
            var options = new ConstraintOptions()
            {
                ConformingDelaunay = true
            };
            var quality = new QualityOptions()
            {
                MinimumAngle = 25.0
            };

            // Generate mesh.
            var mesh = (Mesh)poly.Triangulate(options, quality);

            var smoother = new SimpleSmoother();

            // Smooth mesh and re-apply quality options.
            smoother.Smooth(mesh);
            mesh.Refine(quality);

            // Calculate mesh quality
            var statistic = new QualityMeasure();

            statistic.Update(mesh);

            // Use the minimum triangle area for region refinement
            double area = 1.75 * statistic.AreaMinimum;

            foreach (var t in mesh.Triangles)
            {
                // Set area constraint for all triangles in region 1
                if (t.Label == 1)
                {
                    t.Area = area;
                }
            }

            // Use per triangle area constraint for next refinement
            quality.VariableArea = true;

            // Refine mesh to meet area constraint.
            mesh.Refine(quality);

            // Smooth once again.
            smoother.Smooth(mesh);

            return(mesh);
        }
コード例 #24
0
 /// <summary>
 /// Triangulates a polygon, applying quality and constraint options.
 /// </summary>
 /// <param name="polygon">Polygon instance.</param>
 /// <param name="options">Constraint options.</param>
 /// <param name="quality">Quality options.</param>
 /// <param name="triangulator">The triangulation algorithm.</param>
 public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality,
                                 ITriangulator triangulator)
 {
     return((new GenericMesher(triangulator)).Triangulate(polygon, options, quality));
 }
コード例 #25
0
 /// <summary>
 /// Triangulates a polygon, applying quality options.
 /// </summary>
 /// <param name="polygon">Polygon instance.</param>
 /// <param name="quality">Quality options.</param>
 public static IMesh Triangulate(this IPolygon polygon, QualityOptions quality)
 {
     return((new GenericMesher()).Triangulate(polygon, null, quality));
 }
コード例 #26
0
        private void RenderGradientPath(float[] path)
        {
            // triangulate polygon into mesh
            var polyVertices = new Vertex[path.Length / 2];
            var dimX         = _graph.DimX;
            var dimY         = _graph.DimY;

            for (var i = 0; i < path.Length / 2; i++)
            {
                polyVertices[i] = new Vertex(dimX.Scale(path[i * 2]), dimY.Scale(path[i * 2 + 1]));
            }

            var polygon = new Polygon();

            polygon.Add(new Contour(polyVertices));

            var options = new ConstraintOptions {
                Convex = false, ConformingDelaunay = false
            };
            // restrict maximumarea to allow proper vertex-colouring of gradients
            var quality = new QualityOptions {
                MaximumArea = 0.005
            };
            var generatedMesh = polygon.Triangulate(options, quality);

            // quick hack: gradient cannot expand outside of graph bounds [-0.5, 0.5]
            float min, max;

            if (GradientAxis == 'x')
            {
                min = dimX.Scale(MinGradient);
                max = dimX.Scale(MaxGradient);
            }
            else
            {
                min = dimY.Scale(MinGradient);
                max = dimY.Scale(MaxGradient);
            }

            var range = max - min;

            // convert triangulated mesh into unity mesh
            var triangles = new int[generatedMesh.Triangles.Count * 3];
            var vertices  = new Vector3[generatedMesh.Triangles.Count * 3];
            var colors    = new Color32[vertices.Length];
            var counter   = 0;

            foreach (var triangle in generatedMesh.Triangles)
            {
                var vectors = triangle.vertices;

                triangles[counter + 0] = counter + 0;
                triangles[counter + 1] = counter + 2;
                triangles[counter + 2] = counter + 1;

                vertices[counter + 0] = new Vector3(Convert.ToSingle(vectors[0].x), Convert.ToSingle(vectors[0].y), 0);
                vertices[counter + 1] = new Vector3(Convert.ToSingle(vectors[1].x), Convert.ToSingle(vectors[1].y), 0);
                vertices[counter + 2] = new Vector3(Convert.ToSingle(vectors[2].x), Convert.ToSingle(vectors[2].y), 0);

                if (GradientAxis == 'x')
                {
                    colors[counter + 0] = GetGradient((vectors[0].x - min) / range);
                    colors[counter + 1] = GetGradient((vectors[1].x - min) / range);
                    colors[counter + 2] = GetGradient((vectors[2].x - min) / range);
                }
                else
                {
                    colors[counter + 0] = GetGradient((vectors[0].y - min) / range);
                    colors[counter + 1] = GetGradient((vectors[1].y - min) / range);
                    colors[counter + 2] = GetGradient((vectors[2].y - min) / range);
                }

                counter += 3;
            }

            var mesh = new Mesh();

            _filter.mesh   = mesh;
            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.colors32  = colors;
            mesh.RecalculateBounds();
        }
コード例 #27
0
 /// <summary> Triangulates a polygon, applying quality and constraint options. </summary>
 /// <param name="polygon">Polygon.</param>
 /// <param name="options">Constraint options.</param>
 /// <param name="quality">Quality options.</param>
 public static Mesh Triangulate(this Polygon polygon, ConstraintOptions options, QualityOptions quality)
 {
     return(new Dwyer()
            .Triangulate(polygon.Points)
            .ApplyConstraints(polygon, options, quality));
 }
コード例 #28
0
 /// <summary>
 /// Triangulates a polygon, applying quality and constraint options.
 /// </summary>
 /// <param name="options">Constraint options.</param>
 /// <param name="quality">Quality options.</param>
 internal static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality)
 {
     return((new GenericMesher()).Triangulate(polygon, options, quality));
 }
コード例 #29
0
        public static void Tessellate(float minAngle, float maxAngle, float meshAreaFactor, float largestTriangleAreaFactor, int smoothIterations, IList <Vector2> vertices, IList <Edge> edges, IList <int> indices)
        {
            if (vertices.Count < 3)
            {
                return;
            }

            largestTriangleAreaFactor = Mathf.Clamp01(largestTriangleAreaFactor);

            var polygon = new Polygon(vertices.Count);

            for (int i = 0; i < vertices.Count; ++i)
            {
                Vector2 position = vertices[i];
                polygon.Add(new Vertex(position.x, position.y, 1));
            }

            for (int i = 0; i < edges.Count; ++i)
            {
                Edge edge = edges[i];
                polygon.Add(new Segment(polygon.Points[edge.index1], polygon.Points[edge.index2]));
            }

            var mesh      = polygon.Triangulate();
            var statistic = new Statistic();

            statistic.Update((UnityEngine.Experimental.U2D.TriangleNet.Mesh)mesh, 1);

            var maxAreaToApply = (double)Mathf.Max((float)statistic.LargestArea * largestTriangleAreaFactor, (float)(statistic.MeshArea * meshAreaFactor));
            var qualityOptions = new QualityOptions()
            {
                SteinerPoints = 0
            };

            if (maxAreaToApply > 0f)
            {
                qualityOptions.MaximumArea = maxAreaToApply;
            }

            qualityOptions.MinimumAngle = minAngle;
            qualityOptions.MaximumAngle = maxAngle;

            mesh.Refine(qualityOptions, false);
            mesh.Renumber();

            if (smoothIterations > 0)
            {
                try
                {
                    var smoother = new SimpleSmoother();
                    smoother.Smooth(mesh, smoothIterations);
                }
                catch (System.Exception)
                {
                    Debug.Log(TextContent.smoothMeshError);
                }
            }

            vertices.Clear();
            edges.Clear();
            indices.Clear();

            foreach (Vertex vertex in mesh.Vertices)
            {
                vertices.Add(new Vector2((float)vertex.X, (float)vertex.Y));
            }

            foreach (ISegment segment in mesh.Segments)
            {
                edges.Add(new Edge(segment.P0, segment.P1));
            }

            foreach (ITriangle triangle in mesh.Triangles)
            {
                int id0 = triangle.GetVertexID(0);
                int id1 = triangle.GetVertexID(1);
                int id2 = triangle.GetVertexID(2);

                if (id0 < 0 || id1 < 0 || id2 < 0 || id0 >= vertices.Count || id1 >= vertices.Count || id2 >= vertices.Count)
                {
                    continue;
                }

                indices.Add(id0);
                indices.Add(id2);
                indices.Add(id1);
            }
        }
コード例 #30
0
 /// <summary> Triangulates a polygon, applying quality and constraint options. </summary>
 /// <param name="polygon">Polygon.</param>
 /// <param name="options">Constraint options.</param>
 /// <param name="quality">Quality options.</param>
 /// <param name="triangulator">The triangulation algorithm.</param>
 public static Mesh Triangulate(this Polygon polygon, ConstraintOptions options, QualityOptions quality,
                                ITriangulator triangulator)
 {
     return(triangulator
            .Triangulate(polygon.Points)
            .ApplyConstraints(polygon, options, quality));
 }