Skip to content

Instantly share code, notes, and snippets.

@jonbro
Created March 5, 2014 15:13
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonbro/9369169 to your computer and use it in GitHub Desktop.
Save jonbro/9369169 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Globalization;
using ClipperLib;
using TriangleNet.Geometry;
using Polygon = System.Collections.Generic.List<ClipperLib.IntPoint>;
using Polygons = System.Collections.Generic.List<System.Collections.Generic.List<ClipperLib.IntPoint>>;
// alternately could use this
// https://github.com/speps/LibTessDotNet
public class PolyToMesh{
private float multiplier = 10000;
private Polygons subject = new Polygons();
private Polygons clips = new Polygons();
public void AddSubject(List<Vector2> poly){
AddPoints (poly, subject);
}
public void AddClip(List<Vector2> poly){
AddPoints (poly, clips);
}
void AddPoints(List<Vector2> poly, Polygons list){
list.Add(new Polygon(poly.Count));
foreach (Vector2 point in poly) {
list [list.Count - 1].Add (new IntPoint (point.x * multiplier, point.y * multiplier));
}
}
public Mesh GetMesh(){
// build the clipper
PolyTree PTsolution = new PolyTree ();
Clipper c = new Clipper();
c.AddPaths (subject, PolyType.ptSubject, true);
c.AddPaths (clips, PolyType.ptClip, true);
c.Execute (ClipType.ctDifference, PTsolution, PolyFillType.pftEvenOdd, PolyFillType.pftPositive);
// build the triangle mesh
// then need to convert the solution into a mesh that can be displayed
TriangleNet.Mesh tmesh = new TriangleNet.Mesh ();
TriangleNet.Geometry.InputGeometry input = new TriangleNet.Geometry.InputGeometry ();
AddContourAndChildren (PTsolution, input, 0);
tmesh.Triangulate(input);
// convert the mesh to a unity mesh
Vector2[] uv;
Color32[] cs;
Vector3[] vertices;
Vector3[] normals;
Mesh mesh = new Mesh();
mesh.name = "Display mesh";
mesh.hideFlags = HideFlags.HideAndDontSave;
vertices = new Vector3[tmesh.Vertices.Count()];
normals = new Vector3[vertices.Count()];
uv = new Vector2[tmesh.Vertices.Count()];
TriangleNet.Data.Vertex[] tVertices = tmesh.Vertices.ToArray ();
int[] tri = new int[tmesh.Triangles.Count()*3];
Debug.Log (vertices.Count());
Debug.Log (normals.Count());
for(int i=0;i<vertices.Count();i++){
vertices[i] = new Vector3((float)tVertices[i].X, (float)tVertices[i].Y, 0);
uv[i] = new Vector2((float)tVertices[i].X, (float)tVertices[i].Y);
normals [i] = (new Vector3(0,1,1)).normalized;
}
for(int i=0;i<tmesh.Triangles.Count();i++){
tri[0+i*3] = tmesh.Triangles.ElementAt(i).P0;
tri[2+i*3] = tmesh.Triangles.ElementAt(i).P1;
tri[1+i*3] = tmesh.Triangles.ElementAt(i).P2;
}
mesh.vertices = vertices;
normals = mesh.normals;
mesh.triangles = tri;
mesh.uv = uv;
return mesh;
}
int AddContourAndChildren(PolyNode pt, InputGeometry ig, int EdgeMarker){
int startIndexMark = ig.Count;
int indexMarker = startIndexMark;
if (pt.Contour.Count > 0) {
float avgX = 0;
float avgY = 0;
foreach (ClipperLib.IntPoint p in pt.Contour) {
int nextMarker = ((indexMarker - startIndexMark + 1) % pt.Contour.Count + startIndexMark);
ig.AddPoint ((float)p.X/multiplier, (float)p.Y/multiplier, EdgeMarker-1);
ig.AddSegment (indexMarker, ((indexMarker-startIndexMark + 1)%pt.Contour.Count+startIndexMark), EdgeMarker-1);
avgX += p.X;
avgY += p.Y;
indexMarker++;
}
if (pt.IsHole) {
// this method won't work for adding concave polygons
ig.AddHole (avgX / (indexMarker+1 - startIndexMark)/100f, avgY / (indexMarker+1 - startIndexMark)/100f);
}
}
foreach (PolyNode ptc in pt.Childs) {
EdgeMarker++;
EdgeMarker = AddContourAndChildren (ptc, ig, EdgeMarker);
}
return EdgeMarker;
}
}
@AShim3D
Copy link

AShim3D commented Feb 21, 2017

line 102: replace "/100f" with "/multiplier"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment