+4

Drawing Polygon with CuttingEars algorithm

Anonymous 10 years ago 0
This discussion was imported from CodePlex

Darkounet789 wrote at 2014-02-05 11:00:

Hi there !

I'm very new to Helix3D (even WPF...) and I've a newby question about a way to draw polygons from scratch. I just can't figure out how the function AddPolygonByCuttingEars should be used ^^" Here is my current code :
var visualMesh = new MeshVisual3D();
var geometry = new GeometryModel3D();
var meshbuilder = new MeshBuilder(false,false);
var polygon = new[]
{
        new Point(1, 1),
        new Point(1, 2),
        new Point(4, 3),
        new Point(2, 1),
        new Point(1.5, 1.5)
};
var polygon3D = new[]
{
        new Point3D(1, 1,0),
        new Point3D(1, 2,0),
        new Point3D(4, 3,0),
        new Point3D(2, 1,0),
        new Point3D(1.5, 1.5,0)
};

var result = CuttingEarsTriangulator.Triangulate(polygon);
/* 1 */
//meshbuilder.AddPolygon(polygon3D);
/* 2 */
//meshbuilder.AddPolygon(result);
/* 3 */
meshbuilder.AddPolygonByCuttingEars(result);
geometry.Geometry = meshbuilder.ToMesh();
geometry.Material = MaterialHelper.CreateMaterial(Colors.OrangeRed);
visualMesh.Content = geometry;
this.Viewport3D.Children.Add(visualMesh);
The polygons are /convex/ -edited- -> concave !.
  1. The flatten Polygon3D only appear with false, false as attributes of the MeshBuilder constructor, otherwise I get a 'System.InvalidOperationException' in HelixToolkit.Wpf.dll. However some faces are upside down and the shape is finally not /convex/ -edited- -> concave ! =s
  2. meshbuilder.AddPolygon(result) line works, but no shapes appears... even with true, true in the MeshBuilder constructor.
  3. With meshbuilder.AddPolygonByCuttingEars(result); I get a 'System.ArgumentOutOfRangeException' in mscorlib.dll, and I don't really know why...
I'me sure I'm doing it wrong, if someone could explain how it should work or lead me to a working example of the cutting ears function usages, it would be great !

Thank you in advance for your answers !

/ Edit /
I said convex, of course, they are concave ^^" sorry !

Darkounet789 wrote at 2014-02-06 11:21:

Hi !

I think I got it ! I just drawn each triangle by using the indexes given by the cuttingears algorithm. I don't know if it's the right way to do it, but it works ^^.
var visualMesh = new MeshVisual3D();
var geometry = new GeometryModel3D();
var meshbuilder = new MeshBuilder(true, true);
var polygon = new PointCollection()
{
      new Point(1, 1),
      new Point(1, 2),
      new Point(2, 3),
      new Point(3, 2),
      new Point(4, 4),
      new Point(4, 2),
      new Point(3, 1)
};

var result = CuttingEarsTriangulator.Triangulate(polygon);

List<int> tri = new List<int>();
for (int i = 0; i < result.Count; i++)
{
      tri.Add(result[i]);
      if (tri.Count == 3)
      {
            Console.WriteLine("Triangle " + (i / 3).ToString() + " : " + tri[0].ToString() + ", " + tri[1].ToString() + ", " + tri[2].ToString());
            meshbuilder.AddTriangle(new Point3D(polygon[tri[0]].X, polygon[tri[0]].Y, 0),
                new Point3D(polygon[tri[1]].X, polygon[tri[1]].Y, 0),
                new Point3D(polygon[tri[2]].X, polygon[tri[2]].Y, 0));
            tri.Clear();
      }
}

geometry.Geometry = meshbuilder.ToMesh();
geometry.Material = MaterialHelper.CreateMaterial(Colors.OrangeRed);
visualMesh.Content = geometry;
                    
this.Viewport3D.Children.Add(visualMesh);
However, I encounter and new issue... the triangles I'm drawing are one-sided. Only the upper side of the face is rendered. Is there a way to make the triangles double-sided ?

/ FIXED / : I didn't know I had to set a backmaterial. I discovered that in an another topic ^^

Darkounet789 wrote at 2014-02-13 16:03:

Hey everybody !

You shouldn't use the code I wrote in my previous posts. Instead of this, I now use this couple of functions to fill a polygon with triangles.
//Support for 2D polygons

        public static MeshGeometry3D FillPolygon(Polygon p)
        {
            List<Point3D> pts3D = new List<Point3D>();
            foreach (var point in p.Points)
            {
                pts3D.Add(new Point3D(point.X, point.Y, 0));
            }
            Polygon3D p3 = new Polygon3D(pts3D);
            return FillPolygon(p3);
        }

//For 3D polygons

        public static MeshGeometry3D FillPolygon(Polygon3D p3)
        {
            var meshBuilder = new MeshBuilder(false, false);

            Polygon polygon = p3.Flatten();
            var triangleIndexes = CuttingEarsTriangulator.Triangulate(polygon.Points);

            meshBuilder.Append(p3.Points, triangleIndexes);
            return meshBuilder.ToMesh();
        }
The Append method of the MeshBuilder made my day...

Feel free to reuse !