[gegl/soc-2011-seamless-clone: 38/49] Add a local copy of poly2tri-c for use by seamless-cloning as a fallback



commit e4190bc36d91e1896cace2214c562ed186bbff66
Author: Barak Itkin <lightningismyname gmail com>
Date:   Sat Aug 11 21:27:33 2012 +0300

    Add a local copy of poly2tri-c for use by seamless-cloning as a fallback

 configure.ac                                       |   25 +-
 libs/Makefile.am                                   |    2 +-
 libs/poly2tri-c/.gitignore                         |    6 +
 libs/poly2tri-c/COPYING                            |   40 +
 libs/poly2tri-c/LICENSE-Poly2Tri-C.txt             |   30 +
 libs/poly2tri-c/LICENSE-Poly2Tri.txt               |   31 +
 libs/poly2tri-c/Makefile.am                        |    9 +
 libs/poly2tri-c/README                             |   13 +
 libs/poly2tri-c/poly2tri-c/Makefile.am             |    4 +
 libs/poly2tri-c/poly2tri-c/p2t/Makefile.am         |   10 +
 libs/poly2tri-c/poly2tri-c/p2t/common/Makefile.am  |    5 +
 libs/poly2tri-c/poly2tri-c/p2t/common/cutils.h     |   67 ++
 .../poly2tri-c/p2t/common/poly2tri-private.h       |   62 ++
 libs/poly2tri-c/poly2tri-c/p2t/common/shapes.c     |  677 +++++++++++++
 libs/poly2tri-c/poly2tri-c/p2t/common/shapes.h     |  262 +++++
 libs/poly2tri-c/poly2tri-c/p2t/common/utils.c      |  114 +++
 libs/poly2tri-c/poly2tri-c/p2t/common/utils.h      |   67 ++
 libs/poly2tri-c/poly2tri-c/p2t/poly2tri.h          |   43 +
 libs/poly2tri-c/poly2tri-c/p2t/sweep/Makefile.am   |    5 +
 .../poly2tri-c/p2t/sweep/advancing_front.c         |  229 +++++
 .../poly2tri-c/p2t/sweep/advancing_front.h         |   92 ++
 libs/poly2tri-c/poly2tri-c/p2t/sweep/cdt.c         |   95 ++
 libs/poly2tri-c/poly2tri-c/p2t/sweep/cdt.h         |  105 ++
 libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep.c       | 1024 ++++++++++++++++++++
 libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep.h       |  282 ++++++
 .../poly2tri-c/p2t/sweep/sweep_context.c           |  319 ++++++
 .../poly2tri-c/p2t/sweep/sweep_context.h           |  137 +++
 libs/poly2tri-c/poly2tri-c/refine/Makefile.am      |    6 +
 libs/poly2tri-c/poly2tri-c/refine/bounded-line.c   |   84 ++
 libs/poly2tri-c/poly2tri-c/refine/bounded-line.h   |   58 ++
 libs/poly2tri-c/poly2tri-c/refine/cdt-flipfix.c    |  159 +++
 libs/poly2tri-c/poly2tri-c/refine/cdt-flipfix.h    |   49 +
 libs/poly2tri-c/poly2tri-c/refine/cdt.c            |  491 ++++++++++
 libs/poly2tri-c/poly2tri-c/refine/cdt.h            |  127 +++
 libs/poly2tri-c/poly2tri-c/refine/circle.c         |   47 +
 libs/poly2tri-c/poly2tri-c/refine/circle.h         |   46 +
 libs/poly2tri-c/poly2tri-c/refine/cluster.c        |  139 +++
 libs/poly2tri-c/poly2tri-c/refine/cluster.h        |   55 ++
 .../poly2tri-c/refine/delaunay-terminator.c        |  529 ++++++++++
 .../poly2tri-c/refine/delaunay-terminator.h        |   71 ++
 libs/poly2tri-c/poly2tri-c/refine/edge.c           |  247 +++++
 libs/poly2tri-c/poly2tri-c/refine/edge.h           |  104 ++
 libs/poly2tri-c/poly2tri-c/refine/line.c           |  102 ++
 libs/poly2tri-c/poly2tri-c/refine/line.h           |   66 ++
 libs/poly2tri-c/poly2tri-c/refine/mesh-action.c    |  228 +++++
 libs/poly2tri-c/poly2tri-c/refine/mesh-action.h    |  170 ++++
 libs/poly2tri-c/poly2tri-c/refine/mesh.c           |  406 ++++++++
 libs/poly2tri-c/poly2tri-c/refine/mesh.h           |  361 +++++++
 libs/poly2tri-c/poly2tri-c/refine/point.c          |  227 +++++
 libs/poly2tri-c/poly2tri-c/refine/point.h          |   99 ++
 libs/poly2tri-c/poly2tri-c/refine/pslg.c           |  105 ++
 libs/poly2tri-c/poly2tri-c/refine/pslg.h           |  115 +++
 libs/poly2tri-c/poly2tri-c/refine/refine.h         |   59 ++
 libs/poly2tri-c/poly2tri-c/refine/refiner.c        |   70 ++
 libs/poly2tri-c/poly2tri-c/refine/refiner.h        |   61 ++
 libs/poly2tri-c/poly2tri-c/refine/rmath.c          |  301 ++++++
 libs/poly2tri-c/poly2tri-c/refine/rmath.h          |  132 +++
 libs/poly2tri-c/poly2tri-c/refine/triangle.c       |  313 ++++++
 libs/poly2tri-c/poly2tri-c/refine/triangle.h       |   94 ++
 libs/poly2tri-c/poly2tri-c/refine/triangulation.h  |   49 +
 libs/poly2tri-c/poly2tri-c/refine/utils.c          |   51 +
 libs/poly2tri-c/poly2tri-c/refine/utils.h          |   88 ++
 libs/poly2tri-c/poly2tri-c/refine/vector2.c        |   84 ++
 libs/poly2tri-c/poly2tri-c/refine/vector2.h        |  101 ++
 libs/poly2tri-c/poly2tri-c/refine/vedge.c          |  228 +++++
 libs/poly2tri-c/poly2tri-c/refine/vedge.h          |  143 +++
 libs/poly2tri-c/poly2tri-c/refine/visibility.c     |  438 +++++++++
 libs/poly2tri-c/poly2tri-c/refine/visibility.h     |   46 +
 libs/poly2tri-c/poly2tri-c/refine/vtriangle.c      |  145 +++
 libs/poly2tri-c/poly2tri-c/refine/vtriangle.h      |   70 ++
 libs/poly2tri-c/poly2tri-c/render/Makefile.am      |    6 +
 libs/poly2tri-c/poly2tri-c/render/mesh-render.c    |  273 ++++++
 libs/poly2tri-c/poly2tri-c/render/mesh-render.h    |  175 ++++
 libs/poly2tri-c/poly2tri-c/render/svg-plot.c       |  204 ++++
 libs/poly2tri-c/poly2tri-c/render/svg-plot.h       |   75 ++
 operations/common/seamless-clone/Makefile.am       |    2 -
 76 files changed, 11044 insertions(+), 10 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 527463f..458b657 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1030,20 +1030,24 @@ AC_SUBST(UMFPACK_LIBS)
 # Check for poly2tri-c
 ######################
 
-AC_ARG_WITH(p2tc, AS_HELP_STRING([--without-p2tc], [build without poly2tri-c support]))
-
 have_p2tc="no"
-if test "x$with_p2tc" != "xno"; then
-  PKG_CHECK_MODULES(P2TC, poly2tri-c >= poly2tri-c_required_version,
-    have_p2tc="yes",
-    have_p2tc="no  (poly2tri-c not found)")
-fi
+PKG_CHECK_MODULES(P2TC, poly2tri-c >= poly2tri-c_required_version,
+  have_p2tc="yes",
+  have_p2tc="yes  (installed poly2tri-c not found, using local version)")
 
 AM_CONDITIONAL(HAVE_P2TC, test "$have_p2tc" = "yes")
 
 AC_SUBST(P2TC_CFLAGS)
 AC_SUBST(P2TC_LIBS)
 
+# If no poly2tri-c version is installed, we should use the local version
+# we have cached in the libs directory
+if test "x$have_p2tc" != "xyes"; then
+  AC_SUBST(P2TC_SRC_DIR, "`cd $srcdir; pwd`/libs/poly2tri-c")
+  AC_SUBST(P2TC_CFLAGS, "-I\"$P2TC_SRC_DIR\"")
+  AC_SUBST(P2TC_LIBS, "-L\"$P2TC_SRC_DIR/poly2tri-c\" -lpoly2tri-c")
+fi
+
 #######################
 # Check for other items
 #######################
@@ -1109,6 +1113,13 @@ gegl/property-types/Makefile
 gegl/opencl/Makefile
 libs/Makefile
 libs/rgbe/Makefile
+libs/poly2tri-c/Makefile
+libs/poly2tri-c/poly2tri-c/Makefile
+libs/poly2tri-c/poly2tri-c/render/Makefile
+libs/poly2tri-c/poly2tri-c/p2t/sweep/Makefile
+libs/poly2tri-c/poly2tri-c/p2t/common/Makefile
+libs/poly2tri-c/poly2tri-c/p2t/Makefile
+libs/poly2tri-c/poly2tri-c/refine/Makefile
 operations/Makefile
 operations/core/Makefile
 operations/common/Makefile
diff --git a/libs/Makefile.am b/libs/Makefile.am
index 933933d..176d347 100644
--- a/libs/Makefile.am
+++ b/libs/Makefile.am
@@ -1 +1 @@
-SUBDIRS = rgbe
+SUBDIRS = rgbe poly2tri-c
diff --git a/libs/poly2tri-c/.gitignore b/libs/poly2tri-c/.gitignore
new file mode 100644
index 0000000..612c816
--- /dev/null
+++ b/libs/poly2tri-c/.gitignore
@@ -0,0 +1,6 @@
+*.la
+*.lo
+*Makefile
+*Makefile.in
+*.deps/
+*.libs/
diff --git a/libs/poly2tri-c/COPYING b/libs/poly2tri-c/COPYING
new file mode 100644
index 0000000..11f143f
--- /dev/null
+++ b/libs/poly2tri-c/COPYING
@@ -0,0 +1,40 @@
+The Poly2Tri-C is a three-part library, where all parts are licensed
+under the same license - The BSD 3-Clause License (also known as "New
+BSD License" or "Modified BSD License"):
+
+  1. Constrained Delaunay Triangulation - Based on the code of Poly2Tri
+     (Poly2Tri is licensed under the same license)
+  2. Delaunay Refinement - New code implemented in this library
+  3. Mesh Rendering - New code implemented in this library
+
+The first part of the library is a port of the Poly2Tri library from C++
+to C (with GLib). This port can be found inside the poly2tri-c/p2t
+directory of this source code distribution.
+
+  Poly2Tri - A 2D constrained Delaunay triangulation library
+  Homepage: http://code.google.com/p/poly2tri/
+  Code License File: LICENSE-Poly2Tri.txt
+
+The second part of the library is an implementaiton of a Delaunay
+Refinement algorithm named "The Terminator" which appears in a paper
+written by Jonathan Richard Shewchuk.
+The implementation of the algorithm in C was done by Barak Itkin, and it
+can be found inside the poly2tri-c/refine directory of this source code
+distribution.
+
+  Algorithm Author:
+    Jonathan Richard Shewchuk
+    http://www.cs.berkeley.edu/~jrs/
+
+  Algorithm Paper:
+    Delaunay Refinement Algorithms for Triangular Mesh Generation
+    http://www.cs.berkeley.edu/~jrs/papers/2dj.pdf
+
+  Code License File: LICENSE-Poly2Tri-C.txt
+
+Finally, the third part of the library contains various techniques to
+render mesh objects as raster/vector images. This part is 'original' and
+is not based on any other reference. This code can be found inside the
+poly2tri-c/render directory of this source code distribution.
+
+  Code License File: LICENSE-Poly2Tri-C.txt
diff --git a/libs/poly2tri-c/LICENSE-Poly2Tri-C.txt b/libs/poly2tri-c/LICENSE-Poly2Tri-C.txt
new file mode 100644
index 0000000..097ab24
--- /dev/null
+++ b/libs/poly2tri-c/LICENSE-Poly2Tri-C.txt
@@ -0,0 +1,30 @@
+Poly2Tri-C Copyright (c) 2011-2012, Barak Itkin
+http://code.google.com/p/poly2tri-c/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+ * Neither the name of Poly2Tri-C nor the names of its contributors may
+   be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/libs/poly2tri-c/LICENSE-Poly2Tri.txt b/libs/poly2tri-c/LICENSE-Poly2Tri.txt
new file mode 100644
index 0000000..79fa687
--- /dev/null
+++ b/libs/poly2tri-c/LICENSE-Poly2Tri.txt
@@ -0,0 +1,31 @@
+
+Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+http://code.google.com/p/poly2tri/
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+ * Neither the name of Poly2Tri nor the names of its contributors may be
+   used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/libs/poly2tri-c/Makefile.am b/libs/poly2tri-c/Makefile.am
new file mode 100644
index 0000000..75990ee
--- /dev/null
+++ b/libs/poly2tri-c/Makefile.am
@@ -0,0 +1,9 @@
+if HAVE_P2TC
+    SUBDIRS =
+else
+    SUBDIRS = poly2tri-c
+    AM_CFLAGS = -I $(CURDIR) $(GLIB_CFLAGS)
+    export AM_CFLAGS
+    AM_LIBS = $(GLIB_LIBS)
+    export AM_LIBS
+endif
diff --git a/libs/poly2tri-c/README b/libs/poly2tri-c/README
new file mode 100644
index 0000000..3f39b14
--- /dev/null
+++ b/libs/poly2tri-c/README
@@ -0,0 +1,13 @@
+========================================================================
+====  Poly2Tri-C: A library for generating, refining and rendering  ====
+====        2-Dimensional Constrained Delaunay Triangulations       ====
+========================================================================
+
+This is a minimal version of the Poly2Tri-C library, required to compile
+the seamless cloning operation. For more information, and in order to
+get the full library, see http://code.google.com/p/poly2tri-c
+
+Poly2Tri-C Version info:
+
+    CURRENT REVISION: b27c5b79df2ffa4e2cb37f9e5536831f16afb11b
+    CACHED ON: August 11th, 2012
diff --git a/libs/poly2tri-c/poly2tri-c/Makefile.am b/libs/poly2tri-c/poly2tri-c/Makefile.am
new file mode 100644
index 0000000..7c67fed
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS = p2t refine render
+noinst_LTLIBRARIES = libpoly2tri-c.la
+libpoly2tri_c_la_LIBADD = p2t/libp2tc.la refine/libp2tc-refine.la render/libp2tc-render.la
+libpoly2tri_c_la_SOURCES =
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/Makefile.am b/libs/poly2tri-c/poly2tri-c/p2t/Makefile.am
new file mode 100644
index 0000000..b14155c
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/Makefile.am
@@ -0,0 +1,10 @@
+SUBDIRS = sweep common
+
+noinst_LTLIBRARIES = libp2tc.la
+
+P2TC_P2T_publicdir = $(P2TC_publicdir)/p2t
+export P2TC_P2T_publicdir
+P2TC_P2T_public_HEADERS = poly2tri.h
+
+libp2tc_la_LIBADD = common/libp2tc-common.la sweep/libp2tc-sweep.la
+libp2tc_la_SOURCES =
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/common/Makefile.am b/libs/poly2tri-c/poly2tri-c/p2t/common/Makefile.am
new file mode 100644
index 0000000..8da3514
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/common/Makefile.am
@@ -0,0 +1,5 @@
+noinst_LTLIBRARIES = libp2tc-common.la
+libp2tc_common_la_SOURCES = cutils.h poly2tri-private.h shapes.c shapes.h utils.c utils.h
+
+P2TC_P2T_COMMON_publicdir = $(P2TC_P2T_publicdir)/common
+P2TC_P2T_COMMON_public_HEADERS = cutils.h poly2tri-private.h shapes.h utils.h
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/common/cutils.h b/libs/poly2tri-c/poly2tri-c/p2t/common/cutils.h
new file mode 100644
index 0000000..596078e
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/common/cutils.h
@@ -0,0 +1,67 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_P2T_CUTILS_H__
+#define	__P2TC_P2T_CUTILS_H__
+
+#include <glib.h>
+#include "poly2tri-private.h"
+
+#ifdef	__cplusplus
+extern "C"
+{
+#endif
+
+#define DEBUG FALSE
+
+  typedef GPtrArray* P2tEdgePtrArray;
+#define edge_index(array,index_) ((P2tEdge*)g_ptr_array_index(array,index_))
+  typedef GPtrArray* P2tPointPtrArray;
+#define point_index(array,index_) ((P2tPoint*)g_ptr_array_index(array,index_))
+  typedef GPtrArray* P2tTrianglePtrArray;
+#define triangle_index(array,index_) ((P2tTriangle*)g_ptr_array_index(array,index_))
+  typedef GPtrArray* P2tNodePtrArray;
+#define node_index(array,index_) ((P2tNode*)g_ptr_array_index(array,index_))
+  typedef GList* P2tTrianglePtrList;
+#define triangle_val(list) ((P2tTriangle*)((list)->data))
+
+#define g_ptr_array_index_cyclic(array,index_) g_ptr_array_index(array,(index_)%((array)->len))
+  
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* CUTILS_H */
+
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/common/poly2tri-private.h b/libs/poly2tri-c/poly2tri-c/p2t/common/poly2tri-private.h
new file mode 100644
index 0000000..0be3193
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/common/poly2tri-private.h
@@ -0,0 +1,62 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_P2T_POLY2TRI_PRIVATE_H__
+#define	__P2TC_P2T_POLY2TRI_PRIVATE_H__
+
+#ifdef	__cplusplus
+extern "C"
+{
+#endif
+
+typedef struct _P2tNode P2tNode;
+typedef struct AdvancingFront_ P2tAdvancingFront;
+typedef struct CDT_ P2tCDT;
+typedef struct _P2tEdge P2tEdge;
+typedef struct _P2tPoint P2tPoint;
+typedef struct _P2tTriangle P2tTriangle;
+typedef struct SweepContext_ P2tSweepContext;
+typedef struct Sweep_ P2tSweep;
+
+typedef struct P2tSweepContextBasin_ P2tSweepContextBasin;
+typedef struct P2tSweepContextEdgeEvent_ P2tSweepContextEdgeEvent;
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* POLY2TRI_PRIVATE_H */
+
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/common/shapes.c b/libs/poly2tri-c/poly2tri-c/p2t/common/shapes.c
new file mode 100644
index 0000000..62fec89
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/common/shapes.c
@@ -0,0 +1,677 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "shapes.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Default constructor does nothing (for performance). */
+
+void
+p2t_point_init (P2tPoint* THIS)
+{
+  THIS->x = 0;
+  THIS->y = 0;
+  THIS->edge_list = g_ptr_array_new ();
+}
+
+P2tPoint*
+p2t_point_new ()
+{
+  P2tPoint* THIS = g_slice_new (P2tPoint);
+  p2t_point_init (THIS);
+  return THIS;
+}
+
+/** Construct using coordinates. */
+
+void
+p2t_point_init_dd (P2tPoint* THIS, double x, double y)
+{
+  THIS->x = x;
+  THIS->y = y;
+  THIS->edge_list = g_ptr_array_new ();
+}
+
+P2tPoint*
+p2t_point_new_dd (double x, double y)
+{
+  P2tPoint* THIS = g_slice_new (P2tPoint);
+  p2t_point_init_dd (THIS, x, y);
+  return THIS;
+}
+
+void
+p2t_point_destroy (P2tPoint* THIS)
+{
+  g_ptr_array_free (THIS->edge_list, TRUE);
+}
+
+void
+p2t_point_free (P2tPoint* THIS)
+{
+  p2t_point_destroy (THIS);
+  g_slice_free (P2tPoint, THIS);
+}
+
+/** Constructor */
+
+void
+p2t_edge_init (P2tEdge* THIS, P2tPoint* p1, P2tPoint* p2)
+{
+  THIS->p = p1;
+  THIS->q = p2;
+  if (p1->y > p2->y)
+    {
+      THIS->q = p1;
+      THIS->p = p2;
+    }
+  else if (p1->y == p2->y)
+    {
+      if (p1->x > p2->x)
+        {
+          THIS->q = p1;
+          THIS->p = p2;
+        }
+      else if (p1->x == p2->x)
+        {
+          /* Repeat points */
+          assert (FALSE);
+        }
+    }
+
+  g_ptr_array_add (THIS->q->edge_list, THIS);
+}
+
+P2tEdge*
+p2t_edge_new (P2tPoint* p1, P2tPoint* p2)
+{
+  P2tEdge* THIS = g_slice_new (P2tEdge);
+  p2t_edge_init (THIS, p1, p2);
+  return THIS;
+}
+
+void
+p2t_edge_destroy (P2tEdge* THIS) { }
+
+void
+p2t_edge_free (P2tEdge* THIS)
+{
+  p2t_edge_destroy (THIS);
+  g_slice_free (P2tEdge, THIS);
+}
+
+P2tTriangle*
+p2t_triangle_new (P2tPoint* a, P2tPoint* b, P2tPoint* c)
+{
+  P2tTriangle *tr = g_new (P2tTriangle, 1);
+  p2t_triangle_init (tr, a, b, c);
+  return tr;
+}
+
+void
+p2t_triangle_init (P2tTriangle* THIS, P2tPoint* a, P2tPoint* b, P2tPoint* c)
+{
+  THIS->points_[0] = a;
+  THIS->points_[1] = b;
+  THIS->points_[2] = c;
+  THIS->neighbors_[0] = NULL;
+  THIS->neighbors_[1] = NULL;
+  THIS->neighbors_[2] = NULL;
+  THIS->constrained_edge[0] = THIS->constrained_edge[1] = THIS->constrained_edge[2] = FALSE;
+  THIS->delaunay_edge[0] = THIS->delaunay_edge[1] = THIS->delaunay_edge[2] = FALSE;
+  THIS->interior_ = FALSE;
+
+}
+/* Update neighbor pointers */
+
+void
+p2t_triangle_mark_neighbor_pt_pt_tr (P2tTriangle* THIS, P2tPoint* p1, P2tPoint* p2, P2tTriangle* t)
+{
+  if ((p1 == THIS->points_[2] && p2 == THIS->points_[1]) || (p1 == THIS->points_[1] && p2 == THIS->points_[2]))
+    THIS->neighbors_[0] = t;
+  else if ((p1 == THIS->points_[0] && p2 == THIS->points_[2]) || (p1 == THIS->points_[2] && p2 == THIS->points_[0]))
+    THIS->neighbors_[1] = t;
+  else if ((p1 == THIS->points_[0] && p2 == THIS->points_[1]) || (p1 == THIS->points_[1] && p2 == THIS->points_[0]))
+    THIS->neighbors_[2] = t;
+  else
+    assert (0);
+}
+
+/* Exhaustive search to update neighbor pointers */
+
+void
+p2t_triangle_mark_neighbor_tr (P2tTriangle* THIS, P2tTriangle *t)
+{
+  if (p2t_triangle_contains_pt_pt (t, THIS->points_[1], THIS->points_[2]))
+    {
+      THIS->neighbors_[0] = t;
+      p2t_triangle_mark_neighbor_pt_pt_tr (t, THIS->points_[1], THIS->points_[2], THIS);
+    }
+  else if (p2t_triangle_contains_pt_pt (t, THIS->points_[0], THIS->points_[2]))
+    {
+      THIS->neighbors_[1] = t;
+      p2t_triangle_mark_neighbor_pt_pt_tr (t, THIS->points_[0], THIS->points_[2], THIS);
+    }
+  else if (p2t_triangle_contains_pt_pt (t, THIS->points_[0], THIS->points_[1]))
+    {
+      THIS->neighbors_[2] = t;
+      p2t_triangle_mark_neighbor_pt_pt_tr (t, THIS->points_[0], THIS->points_[1], THIS);
+    }
+}
+
+/**
+ * Clears all references to all other triangles and points
+ */
+void
+p2t_triangle_clear (P2tTriangle* THIS)
+{
+  int i;
+  P2tTriangle *t;
+  for (i = 0; i < 3; i++)
+    {
+      t = THIS->neighbors_[i];
+      if (t != NULL)
+        {
+          p2t_triangle_clear_neighbor_tr (t, THIS);
+        }
+    }
+  p2t_triangle_clear_neighbors (THIS);
+  THIS->points_[0] = THIS->points_[1] = THIS->points_[2] = NULL;
+}
+
+void
+p2t_triangle_clear_neighbor_tr (P2tTriangle* THIS, P2tTriangle *triangle)
+{
+  if (THIS->neighbors_[0] == triangle)
+    {
+      THIS->neighbors_[0] = NULL;
+    }
+  else if (THIS->neighbors_[1] == triangle)
+    {
+      THIS->neighbors_[1] = NULL;
+    }
+  else
+    {
+      THIS->neighbors_[2] = NULL;
+    }
+}
+
+void
+p2t_triangle_clear_neighbors (P2tTriangle* THIS)
+{
+  THIS->neighbors_[0] = NULL;
+  THIS->neighbors_[1] = NULL;
+  THIS->neighbors_[2] = NULL;
+}
+
+void
+p2t_triangle_clear_delunay_edges (P2tTriangle* THIS)
+{
+  THIS->delaunay_edge[0] = THIS->delaunay_edge[1] = THIS->delaunay_edge[2] = FALSE;
+}
+
+P2tPoint*
+p2t_triangle_opposite_point (P2tTriangle* THIS, P2tTriangle* t, P2tPoint* p)
+{
+  P2tPoint *cw = p2t_triangle_point_cw (t, p);
+  /*double x = cw->x;
+  double y = cw->y;
+  x = p->x;
+  y = p->y;
+  P2tPoint* ham = */p2t_triangle_point_cw (THIS, cw);
+  return p2t_triangle_point_cw (THIS, cw);
+}
+
+/* Legalized triangle by rotating clockwise around point(0) */
+
+void
+p2t_triangle_legalize_pt (P2tTriangle* THIS, P2tPoint *point)
+{
+  THIS->points_[1] = THIS->points_[0];
+  THIS->points_[0] = THIS->points_[2];
+  THIS->points_[2] = point;
+}
+
+/* Legalize triagnle by rotating clockwise around oPoint */
+
+void
+p2t_triangle_legalize_pt_pt (P2tTriangle* THIS, P2tPoint *opoint, P2tPoint *npoint)
+{
+  if (opoint == THIS->points_[0])
+    {
+      THIS->points_[1] = THIS->points_[0];
+      THIS->points_[0] = THIS->points_[2];
+      THIS->points_[2] = npoint;
+    }
+  else if (opoint == THIS->points_[1])
+    {
+      THIS->points_[2] = THIS->points_[1];
+      THIS->points_[1] = THIS->points_[0];
+      THIS->points_[0] = npoint;
+    }
+  else if (opoint == THIS->points_[2])
+    {
+      THIS->points_[0] = THIS->points_[2];
+      THIS->points_[2] = THIS->points_[1];
+      THIS->points_[1] = npoint;
+    }
+  else
+    {
+      assert (0);
+    }
+}
+
+int
+p2t_triangle_index (P2tTriangle* THIS, const P2tPoint* p)
+{
+  if (p == THIS->points_[0])
+    {
+      return 0;
+    }
+  else if (p == THIS->points_[1])
+    {
+      return 1;
+    }
+  else if (p == THIS->points_[2])
+    {
+      return 2;
+    }
+  assert (0);
+}
+
+int
+p2t_triangle_edge_index (P2tTriangle* THIS, const P2tPoint* p1, const P2tPoint* p2)
+{
+  if (THIS->points_[0] == p1)
+    {
+      if (THIS->points_[1] == p2)
+        {
+          return 2;
+        }
+      else if (THIS->points_[2] == p2)
+        {
+          return 1;
+        }
+    }
+  else if (THIS->points_[1] == p1)
+    {
+      if (THIS->points_[2] == p2)
+        {
+          return 0;
+        }
+      else if (THIS->points_[0] == p2)
+        {
+          return 2;
+        }
+    }
+  else if (THIS->points_[2] == p1)
+    {
+      if (THIS->points_[0] == p2)
+        {
+          return 1;
+        }
+      else if (THIS->points_[1] == p2)
+        {
+          return 0;
+        }
+    }
+  return -1;
+}
+
+void
+p2t_triangle_mark_constrained_edge_i (P2tTriangle* THIS, const int index)
+{
+  THIS->constrained_edge[index] = TRUE;
+}
+
+void
+p2t_triangle_mark_constrained_edge_ed (P2tTriangle* THIS, P2tEdge* edge)
+{
+  p2t_triangle_mark_constrained_edge_pt_pt (THIS, edge->p, edge->q);
+}
+
+/* Mark edge as constrained */
+
+void
+p2t_triangle_mark_constrained_edge_pt_pt (P2tTriangle* THIS, P2tPoint* p, P2tPoint* q)
+{
+  if ((q == THIS->points_[0] && p == THIS->points_[1]) || (q == THIS->points_[1] && p == THIS->points_[0]))
+    {
+      THIS->constrained_edge[2] = TRUE;
+    }
+  else if ((q == THIS->points_[0] && p == THIS->points_[2]) || (q == THIS->points_[2] && p == THIS->points_[0]))
+    {
+      THIS->constrained_edge[1] = TRUE;
+    }
+  else if ((q == THIS->points_[1] && p == THIS->points_[2]) || (q == THIS->points_[2] && p == THIS->points_[1]))
+    {
+      THIS->constrained_edge[0] = TRUE;
+    }
+}
+
+/* The point counter-clockwise to given point */
+
+P2tPoint*
+p2t_triangle_point_cw (P2tTriangle* THIS, P2tPoint* point)
+{
+  if (point == THIS->points_[0])
+    {
+      return THIS->points_[2];
+    }
+  else if (point == THIS->points_[1])
+    {
+      return THIS->points_[0];
+    }
+  else if (point == THIS->points_[2])
+    {
+      return THIS->points_[1];
+    }
+  assert (0);
+}
+
+/* The point counter-clockwise to given point */
+
+P2tPoint*
+p2t_triangle_point_ccw (P2tTriangle* THIS, P2tPoint* point)
+{
+  if (point == THIS->points_[0])
+    {
+      return THIS->points_[1];
+    }
+  else if (point == THIS->points_[1])
+    {
+      return THIS->points_[2];
+    }
+  else if (point == THIS->points_[2])
+    {
+      return THIS->points_[0];
+    }
+  assert (0);
+}
+
+/* The neighbor clockwise to given point */
+
+P2tTriangle*
+p2t_triangle_neighbor_cw (P2tTriangle* THIS, P2tPoint* point)
+{
+  if (point == THIS->points_[0])
+    {
+      return THIS->neighbors_[1];
+    }
+  else if (point == THIS->points_[1])
+    {
+      return THIS->neighbors_[2];
+    }
+  return THIS->neighbors_[0];
+}
+
+/* The neighbor counter-clockwise to given point */
+
+P2tTriangle*
+p2t_triangle_neighbor_ccw (P2tTriangle* THIS, P2tPoint* point)
+{
+  if (point == THIS->points_[0])
+    {
+      return THIS->neighbors_[2];
+    }
+  else if (point == THIS->points_[1])
+    {
+      return THIS->neighbors_[0];
+    }
+  return THIS->neighbors_[1];
+}
+
+gboolean
+p2t_triangle_get_constrained_edge_ccw (P2tTriangle* THIS, P2tPoint* p)
+{
+  if (p == THIS->points_[0])
+    {
+      return THIS->constrained_edge[2];
+    }
+  else if (p == THIS->points_[1])
+    {
+      return THIS->constrained_edge[0];
+    }
+  return THIS->constrained_edge[1];
+}
+
+gboolean
+p2t_triangle_get_constrained_edge_cw (P2tTriangle* THIS, P2tPoint* p)
+{
+  if (p == THIS->points_[0])
+    {
+      return THIS->constrained_edge[1];
+    }
+  else if (p == THIS->points_[1])
+    {
+      return THIS->constrained_edge[2];
+    }
+  return THIS->constrained_edge[0];
+}
+
+void
+p2t_triangle_set_constrained_edge_ccw (P2tTriangle* THIS, P2tPoint* p, gboolean ce)
+{
+  if (p == THIS->points_[0])
+    {
+      THIS->constrained_edge[2] = ce;
+    }
+  else if (p == THIS->points_[1])
+    {
+      THIS->constrained_edge[0] = ce;
+    }
+  else
+    {
+      THIS->constrained_edge[1] = ce;
+    }
+}
+
+void
+p2t_triangle_set_constrained_edge_cw (P2tTriangle* THIS, P2tPoint* p, gboolean ce)
+{
+  if (p == THIS->points_[0])
+    {
+      THIS->constrained_edge[1] = ce;
+    }
+  else if (p == THIS->points_[1])
+    {
+      THIS->constrained_edge[2] = ce;
+    }
+  else
+    {
+      THIS->constrained_edge[0] = ce;
+    }
+}
+
+gboolean
+p2t_triangle_get_delunay_edge_ccw (P2tTriangle* THIS, P2tPoint* p)
+{
+  if (p == THIS->points_[0])
+    {
+      return THIS->delaunay_edge[2];
+    }
+  else if (p == THIS->points_[1])
+    {
+      return THIS->delaunay_edge[0];
+    }
+  return THIS->delaunay_edge[1];
+}
+
+gboolean
+p2t_triangle_get_delunay_edge_cw (P2tTriangle* THIS, P2tPoint* p)
+{
+  if (p == THIS->points_[0])
+    {
+      return THIS->delaunay_edge[1];
+    }
+  else if (p == THIS->points_[1])
+    {
+      return THIS->delaunay_edge[2];
+    }
+  return THIS->delaunay_edge[0];
+}
+
+void
+p2t_triangle_set_delunay_edge_ccw (P2tTriangle* THIS, P2tPoint* p, gboolean e)
+{
+  if (p == THIS->points_[0])
+    {
+      THIS->delaunay_edge[2] = e;
+    }
+  else if (p == THIS->points_[1])
+    {
+      THIS->delaunay_edge[0] = e;
+    }
+  else
+    {
+      THIS->delaunay_edge[1] = e;
+    }
+}
+
+void
+p2t_triangle_set_delunay_edge_cw (P2tTriangle* THIS, P2tPoint* p, gboolean e)
+{
+  if (p == THIS->points_[0])
+    {
+      THIS->delaunay_edge[1] = e;
+    }
+  else if (p == THIS->points_[1])
+    {
+      THIS->delaunay_edge[2] = e;
+    }
+  else
+    {
+      THIS->delaunay_edge[0] = e;
+    }
+}
+
+/* The neighbor across to given point */
+
+P2tTriangle*
+p2t_triangle_neighbor_across (P2tTriangle* THIS, P2tPoint* opoint)
+{
+  if (opoint == THIS->points_[0])
+    {
+      return THIS->neighbors_[0];
+    }
+  else if (opoint == THIS->points_[1])
+    {
+      return THIS->neighbors_[1];
+    }
+  return THIS->neighbors_[2];
+}
+
+void
+p2t_triangle_debug_print (P2tTriangle* THIS)
+{
+  printf ("%f,%f ", THIS->points_[0]->x, THIS->points_[0]->y);
+  printf ("%f,%f ", THIS->points_[1]->x, THIS->points_[1]->y);
+  printf ("%f,%f\n", THIS->points_[2]->x, THIS->points_[2]->y);
+}
+
+/* WARNING! the function for sorting a g_ptr_array expects to recieve
+ *          pointers to the pointers (double indirection)! */
+
+gint
+p2t_point_cmp (gconstpointer a, gconstpointer b)
+{
+  P2tPoint *ap = *((P2tPoint**) a), *bp = *((P2tPoint**) b);
+  if (ap->y < bp->y)
+    {
+      return -1;
+    }
+  else if (ap->y == bp->y)
+    {
+      /* Make sure q is point with greater x value */
+      if (ap->x < bp->x)
+        {
+          return -1;
+        }
+      else if (ap->x == bp->x)
+        return 0;
+    }
+  return 1;
+}
+
+/* gboolean operator == (const Point& a, const Point& b) */
+
+gboolean
+p2t_point_equals (const P2tPoint* a, const P2tPoint* b)
+{
+  return a->x == b->x && a->y == b->y;
+}
+
+P2tPoint*
+p2t_triangle_get_point (P2tTriangle* THIS, const int index)
+{
+  return THIS->points_[index];
+}
+
+P2tTriangle*
+p2t_triangle_get_neighbor (P2tTriangle* THIS, const int index)
+{
+  return THIS->neighbors_[index];
+}
+
+gboolean
+p2t_triangle_contains_pt (P2tTriangle* THIS, P2tPoint* p)
+{
+  return p == THIS->points_[0] || p == THIS->points_[1] || p == THIS->points_[2];
+}
+
+gboolean
+p2t_triangle_contains_ed (P2tTriangle* THIS, const P2tEdge* e)
+{
+  return p2t_triangle_contains_pt (THIS, e->p) && p2t_triangle_contains_pt (THIS, e->q);
+}
+
+gboolean
+p2t_triangle_contains_pt_pt (P2tTriangle* THIS, P2tPoint* p, P2tPoint* q)
+{
+  return p2t_triangle_contains_pt (THIS, p) && p2t_triangle_contains_pt (THIS, q);
+}
+
+gboolean
+p2t_triangle_is_interior (P2tTriangle* THIS)
+{
+  return THIS->interior_;
+}
+
+void
+p2t_triangle_is_interior_b (P2tTriangle* THIS, gboolean b)
+{
+  THIS->interior_ = b;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/common/shapes.h b/libs/poly2tri-c/poly2tri-c/p2t/common/shapes.h
new file mode 100644
index 0000000..914b37a
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/common/shapes.h
@@ -0,0 +1,262 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_P2T_SHAPES_H__
+#define __P2TC_P2T_SHAPES_H__
+
+#include <stddef.h>
+#include <assert.h>
+#include <math.h>
+#include "poly2tri-private.h"
+#include "cutils.h"
+
+/**
+ * P2tPoint:
+ * @x: The x coordinate of the point
+ * @y: The y coordinate of the point
+ * @edge_list: The edges this point constitutes an upper ending point
+ *
+ * A struct to represent 2D points with double precision, and to keep track
+ * of the edges this point constitutes an upper ending point
+ */
+struct _P2tPoint
+{
+  /*< public >*/
+  P2tEdgePtrArray edge_list;
+  double x, y;
+};
+
+/**
+ * p2t_point_init_dd:
+ * @THIS: The #P2tPoint to initialize
+ * @x: The desired x coordinate of the point
+ * @y: The desired y coordinate of the point
+ *
+ * A function to initialize a #P2tPoint struct with the given coordinates. The
+ * struct must later be finalized by a call to #p2t_point_destroy
+ */
+void p2t_point_init_dd (P2tPoint* THIS, double x, double y);
+
+/**
+ * p2t_point_new_dd:
+ * @x: The desired x coordinate of the point
+ * @y: The desired y coordinate of the point
+ *
+ * A utility function to alloacte and initialize a #P2tPoint.
+ * See #p2t_point_init_dd. Note that when finished using the point, it must be
+ * freed by a call to #p2t_point_free and can not be freed like regular memory.
+ *
+ * Returns: The allocated and initialized point
+ */
+P2tPoint* p2t_point_new_dd (double x, double y);
+
+/**
+ * p2t_point_init:
+ * @THIS: The #P2tPoint to initialize
+ *
+ * A function to initialize a #P2tPoint struct to (0,0). The struct must later
+ * be finalized by a call to #p2t_point_destroy
+ */
+void p2t_point_init (P2tPoint* THIS);
+
+/**
+ * p2t_point_new:
+ *
+ * A utility function to alloacte and initialize a #P2tPoint.
+ * See #p2t_point_init. Note that when finished using the point, it must be
+ * freed by a call to #p2t_point_free and can not be freed like regular memory.
+ */
+P2tPoint* p2t_point_new ();
+
+/**
+ * p2t_point_destroy:
+ * @THIS: The #P2tPoint whose resources should be freed
+ *
+ * This function will free all the resources allocated by a #P2tPoint, without
+ * freeing the #P2tPoint pointed by @THIS
+ */
+void p2t_point_destroy (P2tPoint* THIS);
+
+/**
+ * p2t_point_free:
+ * @THIS: The #P2tPoint to free
+ *
+ * This function will free all the resources allocated by a #P2tPoint, and will
+ * also free the #P2tPoint pointed by @THIS
+ */
+void p2t_point_free (P2tPoint* THIS);
+
+/**
+ * P2tEdge:
+ * @p: The top right point of the edge
+ * @q: The bottom left point of the edge
+ *
+ * Represents a simple polygon's edge
+ */
+struct _P2tEdge
+{
+  P2tPoint *p, *q;
+};
+
+/**
+ * p2t_edge_init:
+ * @THIS: The #P2tEdge to initialize
+ * @p1: One of the two points that form the edge
+ * @p2: The other point of the two points that form the edge
+ *
+ * A function to initialize a #P2tEdge struct from the given points. The
+ * struct must later be finalized by a call to #p2t_point_destroy.
+ *
+ * Warning: The points must be geometrically not-equal! This means that they
+ * must differ by at least one of their coordinates. Otherwise, a runtime error
+ * would be raised!
+ */
+void p2t_edge_init (P2tEdge* THIS, P2tPoint* p1, P2tPoint* p2);
+
+/**
+ * p2t_edge_new:
+ *
+ * A utility function to alloacte and initialize a #P2tEdge.
+ * See #p2t_edge_init. Note that when finished using the point, it must be freed
+ * by a call to #p2t_point_free and can not be freed like regular memory.
+ *
+ * Returns: The allocated and initialized edge
+ */
+P2tEdge* p2t_edge_new (P2tPoint* p1, P2tPoint* p2);
+
+/**
+ * p2t_edge_destroy:
+ * @THIS: The #P2tEdge whose resources should be freed
+ *
+ * This function will free all the resources allocated by a #P2tEdge, without
+ * freeing the #P2tPoint pointed by @THIS
+ */
+void p2t_edge_destroy (P2tEdge* THIS);
+
+/**
+ * p2t_edge_free:
+ * @THIS: The #P2tEdge to free
+ *
+ * This function will free all the resources allocated by a #P2tEdge, and will
+ * also free the #P2tEdge pointed by @THIS
+ */
+void p2t_edge_free (P2tEdge* THIS);
+
+
+/* Triangle-based data structures are know to have better performance than quad-edge structures
+ * See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
+ *      "Triangulations in CGAL"
+ */
+
+/**
+ * P2tTriangle:
+ * @constrained_edge: Flags to determine if an edge is a Constrained edge
+ * @delaunay_edg: Flags to determine if an edge is a Delauney edge
+ * @points_: Triangle points
+ * @neighbors_: Neighbor list
+ * @interior_: Has this triangle been marked as an interior triangle?
+ *
+ * A data structure for representing a triangle, while keeping information about
+ * neighbor triangles, etc.
+ */
+struct _P2tTriangle
+{
+  /*< public >*/
+  gboolean constrained_edge[3];
+  gboolean delaunay_edge[3];
+
+  /*< private >*/
+  P2tPoint * points_[3];
+  struct _P2tTriangle * neighbors_[3];
+  gboolean interior_;
+};
+
+P2tTriangle* p2t_triangle_new (P2tPoint* a, P2tPoint* b, P2tPoint* c);
+void p2t_triangle_init (P2tTriangle* THIS, P2tPoint* a, P2tPoint* b, P2tPoint* c);
+P2tPoint* p2t_triangle_get_point (P2tTriangle* THIS, const int index);
+P2tPoint* p2t_triangle_point_cw (P2tTriangle* THIS, P2tPoint* point);
+P2tPoint* p2t_triangle_point_ccw (P2tTriangle* THIS, P2tPoint* point);
+P2tPoint* p2t_triangle_opposite_point (P2tTriangle* THIS, P2tTriangle* t, P2tPoint* p);
+
+P2tTriangle* p2t_triangle_get_neighbor (P2tTriangle* THIS, const int index);
+void p2t_triangle_mark_neighbor_pt_pt_tr (P2tTriangle* THIS, P2tPoint* p1, P2tPoint* p2, P2tTriangle* t);
+void p2t_triangle_mark_neighbor_tr (P2tTriangle* THIS, P2tTriangle *t);
+
+void p2t_triangle_mark_constrained_edge_i (P2tTriangle* THIS, const int index);
+void p2t_triangle_mark_constrained_edge_ed (P2tTriangle* THIS, P2tEdge* edge);
+void p2t_triangle_mark_constrained_edge_pt_pt (P2tTriangle* THIS, P2tPoint* p, P2tPoint* q);
+
+int p2t_triangle_index (P2tTriangle* THIS, const P2tPoint* p);
+int p2t_triangle_edge_index (P2tTriangle* THIS, const P2tPoint* p1, const P2tPoint* p2);
+
+P2tTriangle* p2t_triangle_neighbor_cw (P2tTriangle* THIS, P2tPoint* point);
+P2tTriangle* p2t_triangle_neighbor_ccw (P2tTriangle* THIS, P2tPoint* point);
+gboolean p2t_triangle_get_constrained_edge_ccw (P2tTriangle* THIS, P2tPoint* p);
+gboolean p2t_triangle_get_constrained_edge_cw (P2tTriangle* THIS, P2tPoint* p);
+void p2t_triangle_set_constrained_edge_ccw (P2tTriangle* THIS, P2tPoint* p, gboolean ce);
+void p2t_triangle_set_constrained_edge_cw (P2tTriangle* THIS, P2tPoint* p, gboolean ce);
+gboolean p2t_triangle_get_delunay_edge_ccw (P2tTriangle* THIS, P2tPoint* p);
+gboolean p2t_triangle_get_delunay_edge_cw (P2tTriangle* THIS, P2tPoint* p);
+void p2t_triangle_set_delunay_edge_ccw (P2tTriangle* THIS, P2tPoint* p, gboolean e);
+void p2t_triangle_set_delunay_edge_cw (P2tTriangle* THIS, P2tPoint* p, gboolean e);
+
+gboolean p2t_triangle_contains_pt (P2tTriangle* THIS, P2tPoint* p);
+gboolean p2t_triangle_contains_ed (P2tTriangle* THIS, const P2tEdge* e);
+gboolean p2t_triangle_contains_pt_pt (P2tTriangle* THIS, P2tPoint* p, P2tPoint* q);
+void p2t_triangle_legalize_pt (P2tTriangle* THIS, P2tPoint* point);
+void p2t_triangle_legalize_pt_pt (P2tTriangle* THIS, P2tPoint* opoint, P2tPoint* npoint);
+/**
+ * Clears all references to all other triangles and points
+ */
+void p2t_triangle_clear (P2tTriangle* THIS);
+void p2t_triangle_clear_neighbor_tr (P2tTriangle* THIS, P2tTriangle *triangle);
+void p2t_triangle_clear_neighbors (P2tTriangle* THIS);
+void p2t_triangle_clear_delunay_edges (P2tTriangle* THIS);
+
+gboolean p2t_triangle_is_interior (P2tTriangle* THIS);
+void p2t_triangle_is_interior_b (P2tTriangle* THIS, gboolean b);
+
+P2tTriangle* p2t_triangle_neighbor_across (P2tTriangle* THIS, P2tPoint* opoint);
+
+void p2t_triangle_debug_print (P2tTriangle* THIS);
+
+gint p2t_point_cmp (gconstpointer a, gconstpointer b);
+
+/*  gboolean operator == (const Point& a, const Point& b); */
+gboolean p2t_point_equals (const P2tPoint* a, const P2tPoint* b);
+
+#endif
+
+
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/common/utils.c b/libs/poly2tri-c/poly2tri-c/p2t/common/utils.c
new file mode 100644
index 0000000..bc186fc
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/common/utils.c
@@ -0,0 +1,114 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include "utils.h"
+
+/**
+ * Forumla to calculate signed area<br>
+ * Positive if CCW<br>
+ * Negative if CW<br>
+ * 0 if collinear<br>
+ * <pre>
+ * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
+ *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
+ * </pre>
+ */
+P2tOrientation
+p2t_orient2d (P2tPoint* pa, P2tPoint* pb, P2tPoint* pc)
+{
+  double detleft = (pa->x - pc->x) * (pb->y - pc->y);
+  double detright = (pa->y - pc->y) * (pb->x - pc->x);
+  double val = detleft - detright;
+  if (val > -EPSILON && val < EPSILON)
+    {
+      return COLLINEAR;
+    }
+  else if (val > 0)
+    {
+      return CCW;
+    }
+  return CW;
+}
+
+gboolean
+p2t_utils_in_scan_area (P2tPoint* pa, P2tPoint* pb, P2tPoint* pc, P2tPoint* pd)
+{
+#if FALSE
+  double pdx = pd->x;
+  double pdy = pd->y;
+  double adx = pa->x - pdx;
+  double ady = pa->y - pdy;
+  double bdx = pb->x - pdx;
+  double bdy = pb->y - pdy;
+
+  double adxbdy = adx * bdy;
+  double bdxady = bdx * ady;
+  double oabd = adxbdy - bdxady;
+
+  double cdx, cdy;
+  double cdxady, adxcdy, ocad;
+
+  if (oabd <= EPSILON)
+    {
+      return FALSE;
+    }
+
+  cdx = pc->x - pdx;
+  cdy = pc->y - pdy;
+
+  cdxady = cdx * ady;
+  adxcdy = adx * cdy;
+  ocad = cdxady - adxcdy;
+
+  if (ocad <= EPSILON)
+    {
+      return FALSE;
+    }
+
+  return TRUE;
+#else
+  gdouble oadc, oadb = (pa->x - pb->x)*(pd->y - pb->y) - (pd->x - pb->x)*(pa->y - pb->y);
+  if (oadb >= -EPSILON) {
+    return FALSE;
+  }
+
+  oadc = (pa->x - pc->x)*(pd->y - pc->y) - (pd->x - pc->x)*(pa->y - pc->y);
+  if (oadc <= EPSILON) {
+    return FALSE;
+  }
+  return TRUE;
+#endif
+}
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/common/utils.h b/libs/poly2tri-c/poly2tri-c/p2t/common/utils.h
new file mode 100644
index 0000000..18688bb
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/common/utils.h
@@ -0,0 +1,67 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_P2T_UTILS_H__
+#define __P2TC_P2T_UTILS_H__
+
+#include <glib.h>
+#include "poly2tri-private.h"
+#include "cutils.h"
+#include "shapes.h"
+
+#define PI_3div4 (3 * G_PI / 4)
+#define EPSILON  (1e-6)
+
+typedef enum
+{
+  CW, CCW, COLLINEAR
+} P2tOrientation;
+
+/**
+ * Forumla to calculate signed area<br>
+ * Positive if CCW<br>
+ * Negative if CW<br>
+ * 0 if collinear<br>
+ * <pre>
+ * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
+ *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
+ * </pre>
+ */
+P2tOrientation p2t_orient2d (P2tPoint* pa, P2tPoint* pb, P2tPoint* pc);
+
+gboolean p2t_utils_in_scan_area (P2tPoint* pa, P2tPoint* pb, P2tPoint* pc, P2tPoint* pd);
+
+#endif
+
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/poly2tri.h b/libs/poly2tri-c/poly2tri-c/p2t/poly2tri.h
new file mode 100644
index 0000000..d34d5f6
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/poly2tri.h
@@ -0,0 +1,43 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_P2T_POLY2TRI_H__
+#define __P2TC_P2T_POLY2TRI_H__
+
+#include "common/shapes.h"
+#include "sweep/cdt.h"
+
+#endif
+
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/Makefile.am b/libs/poly2tri-c/poly2tri-c/p2t/sweep/Makefile.am
new file mode 100644
index 0000000..5cf18ca
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/Makefile.am
@@ -0,0 +1,5 @@
+noinst_LTLIBRARIES = libp2tc-sweep.la
+libp2tc_sweep_la_SOURCES = advancing_front.c advancing_front.h cdt.c cdt.h sweep.c sweep_context.c sweep_context.h sweep.h
+
+P2TC_P2T_SWEEP_publicdir = $(P2TC_P2T_publicdir)/sweep
+P2TC_P2T_SWEEP_public_HEADERS = advancing_front.h cdt.h sweep_context.h sweep.h
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/advancing_front.c b/libs/poly2tri-c/poly2tri-c/p2t/sweep/advancing_front.c
new file mode 100644
index 0000000..c9ab8f9
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/advancing_front.c
@@ -0,0 +1,229 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "advancing_front.h"
+
+void
+p2t_node_init_pt (P2tNode* THIS, P2tPoint* p)
+{
+  THIS->point = p;
+  THIS->triangle = NULL;
+  THIS->value = p->x;
+  THIS->next = NULL;
+  THIS->prev = NULL;
+}
+
+P2tNode*
+p2t_node_new_pt (P2tPoint* p)
+{
+  P2tNode* THIS = g_slice_new (P2tNode);
+  p2t_node_init_pt (THIS, p);
+  return THIS;
+}
+
+void
+p2t_node_init_pt_tr (P2tNode* THIS, P2tPoint* p, P2tTriangle* t)
+{
+  THIS->point = p;
+  THIS->triangle = t;
+  THIS->value = p->x;
+  THIS->next = NULL;
+  THIS->prev = NULL;
+}
+
+P2tNode*
+p2t_node_new_pt_tr (P2tPoint* p, P2tTriangle* t)
+{
+  P2tNode* THIS = g_slice_new (P2tNode);
+  p2t_node_init_pt_tr (THIS, p, t);
+  return THIS;
+}
+
+void p2t_node_destroy (P2tNode* THIS)
+{
+}
+void p2t_node_free (P2tNode* THIS)
+{
+  p2t_node_destroy (THIS);
+  g_slice_free (P2tNode, THIS);
+}
+
+void
+p2t_advancingfront_init (P2tAdvancingFront* THIS, P2tNode* head, P2tNode* tail)
+{
+  THIS->head_ = head;
+  THIS->tail_ = tail;
+  THIS->search_node_ = head;
+}
+
+P2tAdvancingFront*
+p2t_advancingfront_new (P2tNode* head, P2tNode* tail)
+{
+  P2tAdvancingFront* THIS = g_slice_new (P2tAdvancingFront);
+  p2t_advancingfront_init (THIS, head, tail);
+  return THIS;
+}
+
+void
+p2t_advancingfront_destroy (P2tAdvancingFront* THIS) { }
+
+void
+p2t_advancingfront_free (P2tAdvancingFront* THIS)
+{
+  p2t_advancingfront_destroy (THIS);
+  g_slice_free (P2tAdvancingFront, THIS);
+}
+
+P2tNode*
+p2t_advancingfront_locate_node (P2tAdvancingFront *THIS, const double x)
+{
+  P2tNode* node = THIS->search_node_;
+
+  if (x < node->value)
+    {
+      while ((node = node->prev) != NULL)
+        {
+          if (x >= node->value)
+            {
+              THIS->search_node_ = node;
+              return node;
+            }
+        }
+    }
+  else
+    {
+      while ((node = node->next) != NULL)
+        {
+          if (x < node->value)
+            {
+              THIS->search_node_ = node->prev;
+              return node->prev;
+            }
+        }
+    }
+  return NULL;
+}
+
+P2tNode*
+p2t_advancingfront_find_search_node (P2tAdvancingFront *THIS, const double x)
+{
+  /* TODO: implement BST index */
+  return THIS->search_node_;
+}
+
+P2tNode*
+p2t_advancingfront_locate_point (P2tAdvancingFront *THIS, const P2tPoint* point)
+{
+  const double px = point->x;
+  P2tNode* node = p2t_advancingfront_find_search_node (THIS, px);
+  const double nx = node->point->x;
+
+  if (px == nx)
+    {
+      if (point != node->point)
+        {
+          /* We might have two nodes with same x value for a short time */
+          if (point == node->prev->point)
+            {
+              node = node->prev;
+            }
+          else if (point == node->next->point)
+            {
+              node = node->next;
+            }
+          else
+            {
+              assert (0);
+            }
+        }
+    }
+  else if (px < nx)
+    {
+      while ((node = node->prev) != NULL)
+        {
+          if (point == node->point)
+            {
+              break;
+            }
+        }
+    }
+  else
+    {
+      while ((node = node->next) != NULL)
+        {
+          if (point == node->point)
+            break;
+        }
+    }
+  if (node) THIS->search_node_ = node;
+  return node;
+}
+
+P2tNode*
+p2t_advancingfront_head (P2tAdvancingFront *THIS)
+{
+  return THIS->head_;
+}
+
+void
+AdvancingFront_set_head (P2tAdvancingFront *THIS, P2tNode* node)
+{
+  THIS->head_ = node;
+}
+
+P2tNode*
+p2t_advancingfront_tail (P2tAdvancingFront *THIS)
+{
+  return THIS->tail_;
+}
+
+void
+p2t_advancingfront_set_tail (P2tAdvancingFront *THIS, P2tNode* node)
+{
+  THIS->tail_ = node;
+}
+
+P2tNode*
+p2t_advancingfront_search (P2tAdvancingFront *THIS)
+{
+  return THIS->search_node_;
+}
+
+void
+p2t_advancingfront_set_search (P2tAdvancingFront *THIS, P2tNode* node)
+{
+  THIS->search_node_ = node;
+}
+
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/advancing_front.h b/libs/poly2tri-c/poly2tri-c/p2t/sweep/advancing_front.h
new file mode 100644
index 0000000..43f943e
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/advancing_front.h
@@ -0,0 +1,92 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_P2T_ADVANCING_FRONT_H__
+#define __P2TC_P2T_ADVANCING_FRONT_H__
+
+#include "../common/poly2tri-private.h"
+#include "../common/shapes.h"
+
+/* Advancing front node */
+
+struct _P2tNode
+{
+  P2tPoint* point;
+  P2tTriangle* triangle;
+
+  struct _P2tNode* next;
+  struct _P2tNode* prev;
+
+  double value;
+};
+
+void p2t_node_init_pt (P2tNode* THIS, P2tPoint* p);
+P2tNode* p2t_node_new_pt (P2tPoint* p);
+void p2t_node_init_pt_tr (P2tNode* THIS, P2tPoint* p, P2tTriangle* t);
+P2tNode* p2t_node_new_pt_tr (P2tPoint* p, P2tTriangle* t);
+void p2t_node_destroy (P2tNode* THIS);
+void p2t_node_free (P2tNode* THIS);
+
+/* Advancing front */
+
+struct AdvancingFront_
+{
+  /* private: */
+
+  P2tNode* head_, *tail_, *search_node_;
+
+};
+
+void p2t_advancingfront_init (P2tAdvancingFront* THIS, P2tNode* head, P2tNode* tail);
+P2tAdvancingFront* p2t_advancingfront_new (P2tNode* head, P2tNode* tail);
+
+void p2t_advancingfront_destroy (P2tAdvancingFront* THIS);
+void p2t_advancingfront_free (P2tAdvancingFront* THIS);
+
+P2tNode* p2t_advancingfront_head (P2tAdvancingFront *THIS);
+void AdvancingFront_set_head (P2tAdvancingFront *THIS, P2tNode* node);
+P2tNode* p2t_advancingfront_tail (P2tAdvancingFront *THIS);
+void p2t_advancingfront_set_tail (P2tAdvancingFront *THIS, P2tNode* node);
+P2tNode* p2t_advancingfront_search (P2tAdvancingFront *THIS);
+void p2t_advancingfront_set_search (P2tAdvancingFront *THIS, P2tNode* node);
+
+/** Locate insertion point along advancing front */
+P2tNode* p2t_advancingfront_locate_node (P2tAdvancingFront *THIS, const double x);
+
+P2tNode* p2t_advancingfront_locate_point (P2tAdvancingFront *THIS, const P2tPoint* point);
+
+P2tNode* p2t_advancingfront_find_search_node (P2tAdvancingFront *THIS, const double x);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/cdt.c b/libs/poly2tri-c/poly2tri-c/p2t/sweep/cdt.c
new file mode 100644
index 0000000..738d72e
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/cdt.c
@@ -0,0 +1,95 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cdt.h"
+
+void
+p2t_cdt_init (P2tCDT* THIS, P2tPointPtrArray polyline)
+{
+  THIS->sweep_context_ = p2t_sweepcontext_new (polyline);
+  THIS->sweep_ = p2t_sweep_new ();
+}
+
+P2tCDT*
+p2t_cdt_new (P2tPointPtrArray polyline)
+{
+  P2tCDT* THIS = g_slice_new (P2tCDT);
+  p2t_cdt_init (THIS, polyline);
+  return THIS;
+}
+
+void
+p2t_cdt_destroy (P2tCDT* THIS)
+{
+  p2t_sweepcontext_delete (THIS->sweep_context_);
+  p2t_sweep_free (THIS->sweep_);
+}
+
+void
+p2t_cdt_free (P2tCDT* THIS)
+{
+  p2t_cdt_destroy (THIS);
+  g_slice_free (P2tCDT, THIS);
+}
+
+void
+p2t_cdt_add_hole (P2tCDT *THIS, P2tPointPtrArray polyline)
+{
+  p2t_sweepcontext_add_hole (THIS->sweep_context_, polyline);
+}
+
+void
+p2t_cdt_add_point (P2tCDT *THIS, P2tPoint* point)
+{
+  p2t_sweepcontext_add_point (THIS->sweep_context_, point);
+}
+
+void
+p2t_cdt_triangulate (P2tCDT *THIS)
+{
+  p2t_sweep_triangulate (THIS->sweep_, THIS->sweep_context_);
+}
+
+P2tTrianglePtrArray
+p2t_cdt_get_triangles (P2tCDT *THIS)
+{
+  return p2t_sweepcontext_get_triangles (THIS->sweep_context_);
+}
+
+P2tTrianglePtrList
+p2t_cdt_get_map (P2tCDT *THIS)
+{
+  return p2t_sweepcontext_get_map (THIS->sweep_context_);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/cdt.h b/libs/poly2tri-c/poly2tri-c/p2t/sweep/cdt.h
new file mode 100644
index 0000000..d21b5ed
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/cdt.h
@@ -0,0 +1,105 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_P2T_CDT_H__
+#define __P2TC_P2T_CDT_H__
+
+#include "../common/poly2tri-private.h"
+#include "advancing_front.h"
+#include "sweep_context.h"
+#include "sweep.h"
+
+/**
+ * 
+ * @author Mason Green <mason green gmail com>
+ *
+ */
+
+struct CDT_
+{
+  /*private: */
+
+  /**
+   * Internals
+   */
+
+  P2tSweepContext* sweep_context_;
+  P2tSweep* sweep_;
+
+};
+/**
+ * Constructor - add polyline with non repeating points
+ *
+ * @param polyline
+ */
+void p2t_cdt_init (P2tCDT* THIS, P2tPointPtrArray polyline);
+P2tCDT* p2t_cdt_new (P2tPointPtrArray polyline);
+
+/**
+ * Destructor - clean up memory
+ */
+void p2t_cdt_destroy (P2tCDT* THIS);
+void p2t_cdt_free (P2tCDT* THIS);
+
+/**
+ * Add a hole
+ *
+ * @param polyline
+ */
+void p2t_cdt_add_hole (P2tCDT *THIS, P2tPointPtrArray polyline);
+
+/**
+ * Add a steiner point
+ *
+ * @param point
+ */
+void p2t_cdt_add_point (P2tCDT *THIS, P2tPoint* point);
+
+/**
+ * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
+ */
+void p2t_cdt_triangulate (P2tCDT *THIS);
+
+/**
+ * Get CDT triangles
+ */
+P2tTrianglePtrArray p2t_cdt_get_triangles (P2tCDT *THIS);
+
+/**
+ * Get triangle map
+ */
+P2tTrianglePtrList p2t_cdt_get_map (P2tCDT *THIS);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep.c b/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep.c
new file mode 100644
index 0000000..7680075
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep.c
@@ -0,0 +1,1024 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+
+#include "sweep.h"
+#include "sweep_context.h"
+#include "advancing_front.h"
+#include "../common/utils.h"
+#include "../common/shapes.h"
+
+void
+p2t_sweep_init (P2tSweep* THIS)
+{
+  THIS->nodes_ = g_ptr_array_new ();
+}
+
+P2tSweep*
+p2t_sweep_new ()
+{
+  P2tSweep* THIS = g_new (P2tSweep, 1);
+  p2t_sweep_init (THIS);
+  return THIS;
+}
+
+/**
+ * Destructor - clean up memory
+ */
+void
+p2t_sweep_destroy (P2tSweep* THIS)
+{
+  int i;
+  /* Clean up memory */
+  for (i = 0; i < THIS->nodes_->len; i++)
+    {
+      p2t_node_free (node_index (THIS->nodes_, i));
+    }
+
+  g_ptr_array_free (THIS->nodes_, TRUE);
+}
+
+void
+p2t_sweep_free (P2tSweep* THIS)
+{
+  p2t_sweep_destroy (THIS);
+  g_free (THIS);
+}
+
+/* Triangulate simple polygon with holes */
+
+void
+p2t_sweep_triangulate (P2tSweep *THIS, P2tSweepContext *tcx)
+{
+  p2t_sweepcontext_init_triangulation (tcx);
+  p2t_sweepcontext_create_advancingfront (tcx, THIS->nodes_);
+  /* Sweep points; build mesh */
+  p2t_sweep_sweep_points (THIS, tcx);
+  /* Clean up */
+  p2t_sweep_finalization_polygon (THIS, tcx);
+}
+
+void
+p2t_sweep_sweep_points (P2tSweep *THIS, P2tSweepContext *tcx)
+{
+  int i, j;
+  for (i = 1; i < p2t_sweepcontext_point_count (tcx); i++)
+    {
+      P2tPoint* point = p2t_sweepcontext_get_point (tcx, i);
+      P2tNode* node = p2t_sweep_point_event (THIS, tcx, point);
+      for (j = 0; j < point->edge_list->len; j++)
+        {
+          p2t_sweep_edge_event_ed_n (THIS, tcx, edge_index (point->edge_list, j), node);
+        }
+    }
+}
+
+void
+p2t_sweep_finalization_polygon (P2tSweep *THIS, P2tSweepContext *tcx)
+{
+  /* Get an Internal triangle to start with */
+  P2tTriangle* t = p2t_advancingfront_head (p2t_sweepcontext_front (tcx))->next->triangle;
+  P2tPoint* p = p2t_advancingfront_head (p2t_sweepcontext_front (tcx))->next->point;
+  while (!p2t_triangle_get_constrained_edge_cw (t, p))
+    {
+      t = p2t_triangle_neighbor_ccw (t, p);
+    }
+
+  /* Collect interior triangles constrained by edges */
+  p2t_sweepcontext_mesh_clean (tcx, t);
+}
+
+P2tNode*
+p2t_sweep_point_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* point)
+{
+  P2tNode* node = p2t_sweepcontext_locate_node (tcx, point);
+  P2tNode* new_node = p2t_sweep_new_front_triangle (THIS, tcx, point, node);
+
+  /* Only need to check +epsilon since point never have smaller
+   * x value than node due to how we fetch nodes from the front */
+  if (point->x <= node->point->x + EPSILON)
+    {
+      p2t_sweep_fill (THIS, tcx, node);
+    }
+
+  /*tcx.AddNode(new_node); */
+
+  p2t_sweep_fill_advancingfront (THIS, tcx, new_node);
+  return new_node;
+}
+
+void
+p2t_sweep_edge_event_ed_n (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  tcx->edge_event.constrained_edge = edge;
+  tcx->edge_event.right = (edge->p->x > edge->q->x);
+
+  if (p2t_sweep_is_edge_side_of_triangle (THIS, node->triangle, edge->p, edge->q))
+    {
+      return;
+    }
+
+  /* For now we will do all needed filling
+   * TODO: integrate with flip process might give some better performance
+   *       but for now this avoid the issue with cases that needs both flips and fills
+   */
+  p2t_sweep_fill_edge_event (THIS, tcx, edge, node);
+  p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, edge->p, edge->q, node->triangle, edge->q);
+}
+
+void
+p2t_sweep_edge_event_pt_pt_tr_pt (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle* triangle, P2tPoint* point)
+{
+  P2tPoint *p1, *p2;
+  P2tOrientation o1, o2;
+
+  if (p2t_sweep_is_edge_side_of_triangle (THIS, triangle, ep, eq))
+    {
+      return;
+    }
+
+  p1 = p2t_triangle_point_ccw (triangle, point);
+  o1 = p2t_orient2d (eq, p1, ep);
+  if (o1 == COLLINEAR)
+    {
+      if (p2t_triangle_contains_pt_pt (triangle, eq, p1))
+        {
+          p2t_triangle_mark_constrained_edge_pt_pt (triangle, eq, p1);
+          /* We are modifying the constraint maybe it would be better to
+           * not change the given constraint and just keep a variable for the new constraint
+           */
+          tcx->edge_event.constrained_edge->q = p1;
+          triangle = p2t_triangle_neighbor_across (triangle, point);
+          p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, p1, triangle, p1);
+        }
+      else
+        {
+          g_error ("EdgeEvent - collinear points not supported");
+        }
+      return;
+    }
+
+  p2 = p2t_triangle_point_cw (triangle, point);
+  o2 = p2t_orient2d (eq, p2, ep);
+  if (o2 == COLLINEAR)
+    {
+      if (p2t_triangle_contains_pt_pt (triangle, eq, p2))
+        {
+          p2t_triangle_mark_constrained_edge_pt_pt (triangle, eq, p2);
+          /* We are modifying the constraint maybe it would be better to
+           * not change the given constraint and just keep a variable for the new constraint
+           */
+          tcx->edge_event.constrained_edge->q = p2;
+          triangle = p2t_triangle_neighbor_across (triangle, point);
+          p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, p2, triangle, p2);
+        }
+      else
+        {
+          g_error ("EdgeEvent - collinear points not supported");
+        }
+      return;
+    }
+
+  if (o1 == o2)
+    {
+      /* Need to decide if we are rotating CW or CCW to get to a triangle
+       * that will cross edge */
+      if (o1 == CW)
+        {
+          triangle = p2t_triangle_neighbor_ccw (triangle, point);
+        }
+      else
+        {
+          triangle = p2t_triangle_neighbor_cw (triangle, point);
+        }
+      p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, eq, triangle, point);
+    }
+  else
+    {
+      /* This triangle crosses constraint so lets flippin start! */
+      p2t_sweep_flip_edge_event (THIS, tcx, ep, eq, triangle, point);
+    }
+}
+
+gboolean
+p2t_sweep_is_edge_side_of_triangle (P2tSweep *THIS, P2tTriangle *triangle, P2tPoint* ep, P2tPoint* eq)
+{
+  int index = p2t_triangle_edge_index (triangle, ep, eq);
+
+  if (index != -1)
+    {
+      P2tTriangle *t;
+      p2t_triangle_mark_constrained_edge_i (triangle, index);
+      t = p2t_triangle_get_neighbor (triangle, index);
+      if (t)
+        {
+          p2t_triangle_mark_constrained_edge_pt_pt (t, ep, eq);
+        }
+      return TRUE;
+    }
+  return FALSE;
+}
+
+P2tNode*
+p2t_sweep_new_front_triangle (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* point, P2tNode *node)
+{
+  P2tTriangle* triangle = p2t_triangle_new (point, node->point, node->next->point);
+  P2tNode *new_node;
+
+  p2t_triangle_mark_neighbor_tr (triangle, node->triangle);
+  p2t_sweepcontext_add_to_map (tcx, triangle);
+
+  new_node = p2t_node_new_pt (point);
+  g_ptr_array_add (THIS->nodes_, new_node);
+
+  new_node->next = node->next;
+  new_node->prev = node;
+  node->next->prev = new_node;
+  node->next = new_node;
+
+  if (!p2t_sweep_legalize (THIS, tcx, triangle))
+    {
+      p2t_sweepcontext_map_triangle_to_nodes (tcx, triangle);
+    }
+
+  return new_node;
+}
+
+void
+p2t_sweep_fill (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)
+{
+  P2tTriangle* triangle = p2t_triangle_new (node->prev->point, node->point, node->next->point);
+
+  /* TODO: should copy the constrained_edge value from neighbor triangles
+   *       for now constrained_edge values are copied during the legalize */
+  p2t_triangle_mark_neighbor_tr (triangle, node->prev->triangle);
+  p2t_triangle_mark_neighbor_tr (triangle, node->triangle);
+
+  p2t_sweepcontext_add_to_map (tcx, triangle);
+
+  /* Update the advancing front */
+  node->prev->next = node->next;
+  node->next->prev = node->prev;
+
+  /* If it was legalized the triangle has already been mapped */
+  if (!p2t_sweep_legalize (THIS, tcx, triangle))
+    {
+      p2t_sweepcontext_map_triangle_to_nodes (tcx, triangle);
+    }
+
+}
+
+void
+p2t_sweep_fill_advancingfront (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* n)
+{
+
+  /* Fill right holes */
+  P2tNode* node = n->next;
+
+  while (node->next)
+    {
+      /* if HoleAngle exceeds 90 degrees then break. */
+      if (p2t_sweep_large_hole_dont_fill (THIS, node)) break;
+      p2t_sweep_fill (THIS, tcx, node);
+      node = node->next;
+    }
+
+  /* Fill left holes */
+  node = n->prev;
+
+  while (node->prev)
+    {
+      /* if HoleAngle exceeds 90 degrees then break. */
+      if (p2t_sweep_large_hole_dont_fill (THIS, node)) break;
+      p2t_sweep_fill (THIS, tcx, node);
+      node = node->prev;
+    }
+
+  /* Fill right basins */
+  if (n->next && n->next->next)
+    {
+      double angle = p2t_sweep_basin_angle (THIS, n);
+      if (angle < PI_3div4)
+        {
+          p2t_sweep_fill_basin (THIS, tcx, n);
+        }
+    }
+}
+
+/* True if HoleAngle exceeds 90 degrees. */
+gboolean
+p2t_sweep_large_hole_dont_fill (P2tSweep *THIS, P2tNode* node)
+{
+  P2tNode* nextNode = node->next;
+  P2tNode* prevNode = node->prev;
+  P2tNode *next2Node, *prev2Node;
+  if (! p2t_sweep_angle_exceeds_90_degrees (THIS, node->point, nextNode->point, prevNode->point))
+    return FALSE;
+
+  /* Check additional points on front. */
+  next2Node = nextNode->next;
+  /* "..Plus.." because only want angles on same side as point being added. */
+  if ((next2Node != NULL) && !p2t_sweep_angle_exceeds_plus_90_degrees_or_is_negative (THIS, node->point, next2Node->point, prevNode->point))
+    return FALSE;
+
+  prev2Node = prevNode->prev;
+  /* "..Plus.." because only want angles on same side as point being added. */
+  if ((prev2Node != NULL) && !p2t_sweep_angle_exceeds_plus_90_degrees_or_is_negative (THIS, node->point, nextNode->point, prev2Node->point))
+    return FALSE;
+
+  return TRUE;
+}
+
+gboolean
+p2t_sweep_angle_exceeds_90_degrees(P2tSweep* THIS, P2tPoint* origin, P2tPoint* pa, P2tPoint* pb)
+{
+  gdouble angle = p2t_sweep_angle (THIS, origin, pa, pb);
+  gboolean exceeds90Degrees = ((angle > G_PI_2) || (angle < -G_PI_2));
+  return exceeds90Degrees;
+}
+
+gboolean
+p2t_sweep_angle_exceeds_plus_90_degrees_or_is_negative (P2tSweep* THIS, P2tPoint* origin, P2tPoint* pa, P2tPoint* pb)
+{
+  gdouble angle = p2t_sweep_angle (THIS, origin, pa, pb);
+  gboolean exceedsPlus90DegreesOrIsNegative = (angle > G_PI_2) || (angle < 0);
+  return exceedsPlus90DegreesOrIsNegative;
+}
+
+gdouble
+p2t_sweep_angle (P2tSweep* THIS, P2tPoint* origin, P2tPoint* pa, P2tPoint* pb) {
+  /* Complex plane
+   * ab = cosA +i*sinA
+   * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
+   * atan2(y,x) computes the principal value of the argument function
+   * applied to the complex number x+iy
+   * Where x = ax*bx + ay*by
+   *       y = ax*by - ay*bx
+   */
+  double px = origin->x;
+  double py = origin->y;
+  double ax = pa->x - px;
+  double ay = pa->y - py;
+  double bx = pb->x - px;
+  double by = pb->y - py;
+  double x = ax * by - ay * bx;
+  double y = ax * bx + ay * by;
+  double angle = atan2(x, y);
+  return angle;
+}
+
+double
+p2t_sweep_basin_angle (P2tSweep *THIS, P2tNode* node)
+{
+  double ax = node->point->x - node->next->next->point->x;
+  double ay = node->point->y - node->next->next->point->y;
+  return atan2 (ay, ax);
+}
+
+double
+p2t_sweep_hole_angle (P2tSweep *THIS, P2tNode* node)
+{
+  /* Complex plane
+   * ab = cosA +i*sinA
+   * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
+   * atan2(y,x) computes the principal value of the argument function
+   * applied to the complex number x+iy
+   * Where x = ax*bx + ay*by
+   *       y = ax*by - ay*bx
+   */
+  double ax = node->next->point->x - node->point->x;
+  double ay = node->next->point->y - node->point->y;
+  double bx = node->prev->point->x - node->point->x;
+  double by = node->prev->point->y - node->point->y;
+  return atan2 (ax * by - ay * bx, ax * bx + ay * by);
+}
+
+gboolean
+p2t_sweep_legalize (P2tSweep *THIS, P2tSweepContext *tcx, P2tTriangle *t)
+{
+  int i;
+  /* To legalize a triangle we start by finding if any of the three edges
+   * violate the Delaunay condition */
+  for (i = 0; i < 3; i++)
+    {
+      P2tTriangle *ot;
+
+      if (t->delaunay_edge[i])
+        continue;
+
+      ot = p2t_triangle_get_neighbor (t, i);
+
+      if (ot)
+        {
+          P2tPoint* p = p2t_triangle_get_point (t, i);
+          P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);
+          int oi = p2t_triangle_index (ot, op);
+          gboolean inside;
+
+          /* If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
+           * then we should not try to legalize */
+          if (ot->constrained_edge[oi] || ot->delaunay_edge[oi])
+            {
+              t->constrained_edge[i] = ot->constrained_edge[oi];
+              continue;
+            }
+
+          inside = p2t_sweep_incircle (THIS, p, p2t_triangle_point_ccw (t, p), p2t_triangle_point_cw (t, p), op);
+
+          if (inside)
+            {
+              gboolean not_legalized;
+              /* Lets mark this shared edge as Delaunay */
+              t->delaunay_edge[i] = TRUE;
+              ot->delaunay_edge[oi] = TRUE;
+
+              /* Lets rotate shared edge one vertex CW to legalize it */
+              p2t_sweep_rotate_triangle_pair (THIS, t, p, ot, op);
+
+              /* We now got one valid Delaunay Edge shared by two triangles
+               * This gives us 4 new edges to check for Delaunay */
+
+              /* Make sure that triangle to node mapping is done only one time for a specific triangle */
+              not_legalized = !p2t_sweep_legalize (THIS, tcx, t);
+              if (not_legalized)
+                {
+                  p2t_sweepcontext_map_triangle_to_nodes (tcx, t);
+                }
+
+              not_legalized = !p2t_sweep_legalize (THIS, tcx, ot);
+              if (not_legalized)
+                p2t_sweepcontext_map_triangle_to_nodes (tcx, ot);
+
+              /* Reset the Delaunay edges, since they only are valid Delaunay edges
+               * until we add a new triangle or point.
+               * XXX: need to think about this. Can these edges be tried after we
+               *      return to previous recursive level? */
+              t->delaunay_edge[i] = FALSE;
+              ot->delaunay_edge[oi] = FALSE;
+
+              /* If triangle have been legalized no need to check the other edges since
+               * the recursive legalization will handles those so we can end here.*/
+              return TRUE;
+            }
+        }
+    }
+  return FALSE;
+}
+
+gboolean
+p2t_sweep_incircle (P2tSweep *THIS, P2tPoint* pa, P2tPoint* pb, P2tPoint* pc, P2tPoint* pd)
+{
+  double adx = pa->x - pd->x;
+  double ady = pa->y - pd->y;
+  double bdx = pb->x - pd->x;
+  double bdy = pb->y - pd->y;
+
+  double adxbdy = adx * bdy;
+  double bdxady = bdx * ady;
+  double oabd = adxbdy - bdxady;
+
+  double cdx, cdy;
+  double cdxady, adxcdy, ocad;
+
+  double bdxcdy, cdxbdy;
+  double alift, blift, clift;
+  double det;
+
+  if (oabd <= 0)
+    return FALSE;
+
+  cdx = pc->x - pd->x;
+  cdy = pc->y - pd->y;
+
+  cdxady = cdx * ady;
+  adxcdy = adx * cdy;
+  ocad = cdxady - adxcdy;
+
+  if (ocad <= 0)
+    return FALSE;
+
+  bdxcdy = bdx * cdy;
+  cdxbdy = cdx * bdy;
+
+  alift = adx * adx + ady * ady;
+  blift = bdx * bdx + bdy * bdy;
+  clift = cdx * cdx + cdy * cdy;
+
+  det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
+
+  return det > 0;
+}
+
+void
+p2t_sweep_rotate_triangle_pair (P2tSweep *THIS, P2tTriangle *t, P2tPoint* p, P2tTriangle *ot, P2tPoint* op)
+{
+  P2tTriangle *n1, *n2, *n3, *n4;
+  gboolean ce1, ce2, ce3, ce4;
+  gboolean de1, de2, de3, de4;
+
+  n1 = p2t_triangle_neighbor_ccw (t, p);
+  n2 = p2t_triangle_neighbor_cw (t, p);
+  n3 = p2t_triangle_neighbor_ccw (ot, op);
+  n4 = p2t_triangle_neighbor_cw (ot, op);
+
+  ce1 = p2t_triangle_get_constrained_edge_ccw (t, p);
+  ce2 = p2t_triangle_get_constrained_edge_cw (t, p);
+  ce3 = p2t_triangle_get_constrained_edge_ccw (ot, op);
+  ce4 = p2t_triangle_get_constrained_edge_cw (ot, op);
+
+  de1 = p2t_triangle_get_delunay_edge_ccw (t, p);
+  de2 = p2t_triangle_get_delunay_edge_cw (t, p);
+  de3 = p2t_triangle_get_delunay_edge_ccw (ot, op);
+  de4 = p2t_triangle_get_delunay_edge_cw (ot, op);
+
+  p2t_triangle_legalize_pt_pt (t, p, op);
+  p2t_triangle_legalize_pt_pt (ot, op, p);
+
+  /* Remap delaunay_edge */
+  p2t_triangle_set_delunay_edge_ccw (ot, p, de1);
+  p2t_triangle_set_delunay_edge_cw (t, p, de2);
+  p2t_triangle_set_delunay_edge_ccw (t, op, de3);
+  p2t_triangle_set_delunay_edge_cw (ot, op, de4);
+
+  /* Remap constrained_edge */
+  p2t_triangle_set_constrained_edge_ccw (ot, p, ce1);
+  p2t_triangle_set_constrained_edge_cw (t, p, ce2);
+  p2t_triangle_set_constrained_edge_ccw (t, op, ce3);
+  p2t_triangle_set_constrained_edge_cw (ot, op, ce4);
+
+  /* Remap neighbors
+   * XXX: might optimize the markNeighbor by keeping track of
+   *      what side should be assigned to what neighbor after the
+   *      rotation. Now mark neighbor does lots of testing to find
+   *      the right side. */
+  p2t_triangle_clear_neighbors (t);
+  p2t_triangle_clear_neighbors (ot);
+  if (n1) p2t_triangle_mark_neighbor_tr (ot, n1);
+  if (n2) p2t_triangle_mark_neighbor_tr (t, n2);
+  if (n3) p2t_triangle_mark_neighbor_tr (t, n3);
+  if (n4) p2t_triangle_mark_neighbor_tr (ot, n4);
+  p2t_triangle_mark_neighbor_tr (t, ot);
+}
+
+void
+p2t_sweep_fill_basin (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)
+{
+  if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)
+    {
+      tcx->basin.left_node = node->next->next;
+    }
+  else
+    {
+      tcx->basin.left_node = node->next;
+    }
+
+  /* Find the bottom and right node */
+  tcx->basin.bottom_node = tcx->basin.left_node;
+  while (tcx->basin.bottom_node->next
+         && tcx->basin.bottom_node->point->y >= tcx->basin.bottom_node->next->point->y)
+    {
+      tcx->basin.bottom_node = tcx->basin.bottom_node->next;
+    }
+  if (tcx->basin.bottom_node == tcx->basin.left_node)
+    {
+      /* No valid basin */
+      return;
+    }
+
+  tcx->basin.right_node = tcx->basin.bottom_node;
+  while (tcx->basin.right_node->next
+         && tcx->basin.right_node->point->y < tcx->basin.right_node->next->point->y)
+    {
+      tcx->basin.right_node = tcx->basin.right_node->next;
+    }
+  if (tcx->basin.right_node == tcx->basin.bottom_node)
+    {
+      /* No valid basins */
+      return;
+    }
+
+  tcx->basin.width = tcx->basin.right_node->point->x - tcx->basin.left_node->point->x;
+  tcx->basin.left_highest = tcx->basin.left_node->point->y > tcx->basin.right_node->point->y;
+
+  p2t_sweep_fill_basin_req (THIS, tcx, tcx->basin.bottom_node);
+}
+
+void
+p2t_sweep_fill_basin_req (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)
+{
+  /* if shallow stop filling */
+  if (p2t_sweep_is_shallow (THIS, tcx, node))
+    {
+      return;
+    }
+
+  p2t_sweep_fill (THIS, tcx, node);
+
+  if (node->prev == tcx->basin.left_node && node->next == tcx->basin.right_node)
+    {
+      return;
+    }
+  else if (node->prev == tcx->basin.left_node)
+    {
+      P2tOrientation o = p2t_orient2d (node->point, node->next->point, node->next->next->point);
+      if (o == CW)
+        {
+          return;
+        }
+      node = node->next;
+    }
+  else if (node->next == tcx->basin.right_node)
+    {
+      P2tOrientation o = p2t_orient2d (node->point, node->prev->point, node->prev->prev->point);
+      if (o == CCW)
+        {
+          return;
+        }
+      node = node->prev;
+    }
+  else
+    {
+      /* Continue with the neighbor node with lowest Y value */
+      if (node->prev->point->y < node->next->point->y)
+        {
+          node = node->prev;
+        }
+      else
+        {
+          node = node->next;
+        }
+    }
+
+  p2t_sweep_fill_basin_req (THIS, tcx, node);
+}
+
+gboolean
+p2t_sweep_is_shallow (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)
+{
+  double height;
+
+  if (tcx->basin.left_highest)
+    {
+      height = tcx->basin.left_node->point->y - node->point->y;
+    }
+  else
+    {
+      height = tcx->basin.right_node->point->y - node->point->y;
+    }
+
+  /* if shallow stop filling */
+  if (tcx->basin.width > height)
+    {
+      return TRUE;
+    }
+  return FALSE;
+}
+
+void
+p2t_sweep_fill_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  if (tcx->edge_event.right)
+    {
+      p2t_sweep_fill_right_above_edge_event (THIS, tcx, edge, node);
+    }
+  else
+    {
+      p2t_sweep_fill_left_above_edge_event (THIS, tcx, edge, node);
+    }
+}
+
+void
+p2t_sweep_fill_right_above_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  while (node->next->point->x < edge->p->x)
+    {
+      /* Check if next node is below the edge */
+      if (p2t_orient2d (edge->q, node->next->point, edge->p) == CCW)
+        {
+          p2t_sweep_fill_right_below_edge_event (THIS, tcx, edge, node);
+        }
+      else
+        {
+          node = node->next;
+        }
+    }
+}
+
+void
+p2t_sweep_fill_right_below_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  if (node->point->x < edge->p->x)
+    {
+      if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)
+        {
+          /* Concave */
+          p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node);
+        }
+      else
+        {
+          /* Convex */
+          p2t_sweep_fill_right_convex_edge_event (THIS, tcx, edge, node);
+          /* Retry this one */
+          p2t_sweep_fill_right_below_edge_event (THIS, tcx, edge, node);
+        }
+    }
+}
+
+void
+p2t_sweep_fill_right_concave_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  p2t_sweep_fill (THIS, tcx, node->next);
+  if (node->next->point != edge->p)
+    {
+      /* Next above or below edge? */
+      if (p2t_orient2d (edge->q, node->next->point, edge->p) == CCW)
+        {
+          /* Below */
+          if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)
+            {
+              /* Next is concave */
+              p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node);
+            }
+          else
+            {
+              /* Next is convex */
+            }
+        }
+    }
+
+}
+
+void
+p2t_sweep_fill_right_convex_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  /* Next concave or convex? */
+  if (p2t_orient2d (node->next->point, node->next->next->point, node->next->next->next->point) == CCW)
+    {
+      /* Concave */
+      p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node->next);
+    }
+  else
+    {
+      /* Convex
+       * Next above or below edge? */
+      if (p2t_orient2d (edge->q, node->next->next->point, edge->p) == CCW)
+        {
+          /* Below */
+          p2t_sweep_fill_right_convex_edge_event (THIS, tcx, edge, node->next);
+        }
+      else
+        {
+          /* Above */
+        }
+    }
+}
+
+void
+p2t_sweep_fill_left_above_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  while (node->prev->point->x > edge->p->x)
+    {
+      /* Check if next node is below the edge */
+      if (p2t_orient2d (edge->q, node->prev->point, edge->p) == CW)
+        {
+          p2t_sweep_fill_left_below_edge_event (THIS, tcx, edge, node);
+        }
+      else
+        {
+          node = node->prev;
+        }
+    }
+}
+
+void
+p2t_sweep_fill_left_below_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  if (node->point->x > edge->p->x)
+    {
+      if (p2t_orient2d (node->point, node->prev->point, node->prev->prev->point) == CW)
+        {
+          /* Concave */
+          p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node);
+        }
+      else
+        {
+          /* Convex */
+          p2t_sweep_fill_left_convex_edge_event (THIS, tcx, edge, node);
+          /* Retry this one */
+          p2t_sweep_fill_left_below_edge_event (THIS, tcx, edge, node);
+        }
+    }
+}
+
+void
+p2t_sweep_fill_left_convex_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  /* Next concave or convex? */
+  if (p2t_orient2d (node->prev->point, node->prev->prev->point, node->prev->prev->prev->point) == CW)
+    {
+      /* Concave */
+      p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node->prev);
+    }
+  else
+    {
+      /* Convex
+       * Next above or below edge? */
+      if (p2t_orient2d (edge->q, node->prev->prev->point, edge->p) == CW)
+        {
+          /* Below */
+          p2t_sweep_fill_left_convex_edge_event (THIS, tcx, edge, node->prev);
+        }
+      else
+        {
+          /* Above */
+        }
+    }
+}
+
+void
+p2t_sweep_fill_left_concave_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  p2t_sweep_fill (THIS, tcx, node->prev);
+  if (node->prev->point != edge->p)
+    {
+      /* Next above or below edge? */
+      if (p2t_orient2d (edge->q, node->prev->point, edge->p) == CW)
+        {
+          /* Below */
+          if (p2t_orient2d (node->point, node->prev->point, node->prev->prev->point) == CW)
+            {
+              /* Next is concave */
+              p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node);
+            }
+          else
+            {
+              /* Next is convex */
+            }
+        }
+    }
+
+}
+
+void
+p2t_sweep_flip_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle* t, P2tPoint* p)
+{
+  P2tTriangle* ot = p2t_triangle_neighbor_across (t, p);
+  P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);
+
+  if (ot == NULL)
+    {
+      /* If we want to integrate the fillEdgeEvent do it here
+       * With current implementation we should never get here
+       *throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
+       */
+      assert (0);
+    }
+
+  if (p2t_utils_in_scan_area (p, p2t_triangle_point_ccw (t, p), p2t_triangle_point_cw (t, p), op))
+    {
+      /* Lets rotate shared edge one vertex CW */
+      p2t_sweep_rotate_triangle_pair (THIS, t, p, ot, op);
+      p2t_sweepcontext_map_triangle_to_nodes (tcx, t);
+      p2t_sweepcontext_map_triangle_to_nodes (tcx, ot);
+
+      if (p == eq && op == ep)
+        {
+          if (p2t_point_equals (eq, tcx->edge_event.constrained_edge->q) && p2t_point_equals (ep, tcx->edge_event.constrained_edge->p))
+            {
+              p2t_triangle_mark_constrained_edge_pt_pt (t, ep, eq);
+              p2t_triangle_mark_constrained_edge_pt_pt (ot, ep, eq);
+              p2t_sweep_legalize (THIS, tcx, t);
+              p2t_sweep_legalize (THIS, tcx, ot);
+            }
+          else
+            {
+              /* XXX: I think one of the triangles should be legalized here? */
+            }
+        }
+      else
+        {
+          P2tOrientation o = p2t_orient2d (eq, op, ep);
+          t = p2t_sweep_next_flip_triangle (THIS, tcx, (int) o, t, ot, p, op);
+          p2t_sweep_flip_edge_event (THIS, tcx, ep, eq, t, p);
+        }
+    }
+  else
+    {
+      P2tPoint* newP = p2t_sweep_next_flip_point (THIS, ep, eq, ot, op);
+      p2t_sweep_flip_scan_edge_event (THIS, tcx, ep, eq, t, ot, newP);
+      p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, eq, t, p);
+    }
+}
+
+P2tTriangle*
+p2t_sweep_next_flip_triangle (P2tSweep *THIS, P2tSweepContext *tcx, int o, P2tTriangle *t, P2tTriangle *ot, P2tPoint* p, P2tPoint* op)
+{
+  int edge_index;
+
+  if (o == CCW)
+    {
+      /* ot is not crossing edge after flip */
+      int edge_index = p2t_triangle_edge_index (ot, p, op);
+      ot->delaunay_edge[edge_index] = TRUE;
+      p2t_sweep_legalize (THIS, tcx, ot);
+      p2t_triangle_clear_delunay_edges (ot);
+      return t;
+    }
+
+  /* t is not crossing edge after flip */
+  edge_index = p2t_triangle_edge_index (t, p, op);
+
+  t->delaunay_edge[edge_index] = TRUE;
+  p2t_sweep_legalize (THIS, tcx, t);
+  p2t_triangle_clear_delunay_edges (t);
+  return ot;
+}
+
+P2tPoint*
+p2t_sweep_next_flip_point (P2tSweep *THIS, P2tPoint* ep, P2tPoint* eq, P2tTriangle *ot, P2tPoint* op)
+{
+  P2tOrientation o2d = p2t_orient2d (eq, op, ep);
+  if (o2d == CW)
+    {
+      /* Right */
+      return p2t_triangle_point_ccw (ot, op);
+    }
+  else if (o2d == CCW)
+    {
+      /* Left */
+      return p2t_triangle_point_cw (ot, op);
+    }
+  else
+    {
+      /*throw new RuntimeException("[Unsupported] Opposing point on constrained edge");*/
+      assert (0);
+    }
+}
+
+void
+p2t_sweep_flip_scan_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle *flip_triangle,
+                                P2tTriangle *t, P2tPoint* p)
+{
+  P2tTriangle* ot = p2t_triangle_neighbor_across (t, p);
+  P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);
+
+  if (p2t_triangle_neighbor_across (t, p) == NULL)
+    {
+      /* If we want to integrate the fillEdgeEvent do it here
+       * With current implementation we should never get here
+       *throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
+       */
+      assert (0);
+    }
+
+  if (p2t_utils_in_scan_area (eq, p2t_triangle_point_ccw (flip_triangle, eq), p2t_triangle_point_cw (flip_triangle, eq), op))
+    {
+      /* flip with new edge op->eq */
+      p2t_sweep_flip_edge_event (THIS, tcx, eq, op, ot, op);
+      /* TODO: Actually I just figured out that it should be possible to
+       *       improve this by getting the next ot and op before the the above
+       *       flip and continue the flipScanEdgeEvent here
+       * set new ot and op here and loop back to inScanArea test
+       * also need to set a new flip_triangle first
+       * Turns out at first glance that this is somewhat complicated
+       * so it will have to wait. */
+    }
+  else
+    {
+      P2tPoint* newP = p2t_sweep_next_flip_point (THIS, ep, eq, ot, op);
+      p2t_sweep_flip_scan_edge_event (THIS, tcx, ep, eq, flip_triangle, ot, newP);
+    }
+}
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep.h b/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep.h
new file mode 100644
index 0000000..7105fc4
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep.h
@@ -0,0 +1,282 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Sweep-line, Constrained Delauney Triangulation (CDT) See: Domiter, V. and
+ * Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation',
+ * International Journal of Geographical Information Science
+ *
+ * "FlipScan" Constrained Edge Algorithm invented by Thomas ïhlïn, thahlen gmail com
+ */
+
+#ifndef __P2TC_P2T_SWEEP_H__
+#define __P2TC_P2T_SWEEP_H__
+
+#include "../common/poly2tri-private.h"
+#include "../common/shapes.h"
+
+struct Sweep_
+{
+/* private: */
+P2tNodePtrArray nodes_;
+
+};
+
+void p2t_sweep_init (P2tSweep* THIS);
+P2tSweep* p2t_sweep_new ();
+
+/**
+ * Destructor - clean up memory
+ */
+void p2t_sweep_destroy (P2tSweep* THIS);
+void p2t_sweep_free (P2tSweep* THIS);
+
+/**
+ * Triangulate
+ *
+ * @param tcx
+ */
+void p2t_sweep_triangulate (P2tSweep *THIS, P2tSweepContext *tcx);
+
+/**
+ * Start sweeping the Y-sorted point set from bottom to top
+ *
+ * @param tcx
+ */
+void p2t_sweep_sweep_points (P2tSweep *THIS, P2tSweepContext *tcx);
+
+/**
+ * Find closes node to the left of the new point and
+ * create a new triangle. If needed new holes and basins
+ * will be filled to.
+ *
+ * @param tcx
+ * @param point
+ * @return
+ */
+P2tNode* p2t_sweep_point_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* point);
+
+/**
+ *
+ *
+ * @param tcx
+ * @param edge
+ * @param node
+ */
+void p2t_sweep_edge_event_ed_n (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_edge_event_pt_pt_tr_pt (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle* triangle, P2tPoint* point);
+
+/**
+ * Creates a new front triangle and legalize it
+ *
+ * @param tcx
+ * @param point
+ * @param node
+ * @return
+ */
+P2tNode* p2t_sweep_new_front_triangle (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* point, P2tNode* node);
+
+/**
+ * Adds a triangle to the advancing front to fill a hole.
+ * @param tcx
+ * @param node - middle node, that is the bottom of the hole
+ */
+void p2t_sweep_fill (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node);
+
+/**
+ * Returns true if triangle was legalized
+ */
+gboolean p2t_sweep_legalize (P2tSweep *THIS, P2tSweepContext *tcx, P2tTriangle *t);
+
+/**
+ * <b>Requirement</b>:<br>
+ * 1. a,b and c form a triangle.<br>
+ * 2. a and d is know to be on opposite side of bc<br>
+ * <pre>
+ *                a
+ *                +
+ *               / \
+ *              /   \
+ *            b/     \c
+ *            +-------+
+ *           /    d    \
+ *          /           \
+ * </pre>
+ * <b>Fact</b>: d has to be in area B to have a chance to be inside the circle formed by
+ *  a,b and c<br>
+ *  d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW<br>
+ *  This preknowledge gives us a way to optimize the incircle test
+ * @param a - triangle point, opposite d
+ * @param b - triangle point
+ * @param c - triangle point
+ * @param d - point opposite a
+ * @return true if d is inside circle, false if on circle edge
+ */
+gboolean p2t_sweep_incircle (P2tSweep *THIS, P2tPoint* pa, P2tPoint* pb, P2tPoint* pc, P2tPoint* pd);
+
+/**
+ * Rotates a triangle pair one vertex CW
+ *<pre>
+ *       n2                    n2
+ *  P +-----+             P +-----+
+ *    | t  /|               |\  t |
+ *    |   / |               | \   |
+ *  n1|  /  |n3           n1|  \  |n3
+ *    | /   |    after CW   |   \ |
+ *    |/ oT |               | oT \|
+ *    +-----+ oP            +-----+
+ *       n4                    n4
+ * </pre>
+ */
+void p2t_sweep_rotate_triangle_pair (P2tSweep *THIS, P2tTriangle *t, P2tPoint* p, P2tTriangle *ot, P2tPoint* op);
+
+/**
+ * Fills holes in the Advancing Front
+ *
+ *
+ * @param tcx
+ * @param n
+ */
+void p2t_sweep_fill_advancingfront (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* n);
+
+/* Decision-making about when to Fill hole.
+ * Contributed by ToolmakerSteve2 */
+gboolean p2t_sweep_large_hole_dont_fill (P2tSweep* THIS, P2tNode* node);
+gboolean p2t_sweep_angle_exceeds_90_degrees (P2tSweep* THIS, P2tPoint* origin, P2tPoint* pa, P2tPoint* pb);
+gboolean p2t_sweep_angle_exceeds_plus_90_degrees_or_is_negative (P2tSweep* THIS, P2tPoint* origin, P2tPoint* pa, P2tPoint* pb);
+gdouble  p2t_sweep_angle (P2tSweep* THIS, P2tPoint* origin, P2tPoint* pa, P2tPoint* pb);
+
+/**
+ *
+ * @param node - middle node
+ * @return the angle between 3 front nodes
+ */
+double p2t_sweep_hole_angle (P2tSweep *THIS, P2tNode* node);
+
+/**
+ * The basin angle is decided against the horizontal line [1,0]
+ */
+double p2t_sweep_basin_angle (P2tSweep *THIS, P2tNode* node);
+
+/**
+ * Fills a basin that has formed on the Advancing Front to the right
+ * of given node.<br>
+ * First we decide a left,bottom and right node that forms the
+ * boundaries of the basin. Then we do a reqursive fill.
+ *
+ * @param tcx
+ * @param node - starting node, this or next node will be left node
+ */
+void p2t_sweep_fill_basin (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node);
+
+/**
+ * Recursive algorithm to fill a Basin with triangles
+ *
+ * @param tcx
+ * @param node - bottom_node
+ * @param cnt - counter used to alternate on even and odd numbers
+ */
+void p2t_sweep_fill_basin_req (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node);
+
+gboolean p2t_sweep_is_shallow (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node);
+
+gboolean p2t_sweep_is_edge_side_of_triangle (P2tSweep *THIS, P2tTriangle *triangle, P2tPoint* ep, P2tPoint* eq);
+
+void p2t_sweep_fill_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_fill_right_above_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_fill_right_below_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_fill_right_concave_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_fill_right_convex_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_fill_left_above_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_fill_left_below_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_fill_left_concave_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_fill_left_convex_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node);
+
+void p2t_sweep_flip_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle* t, P2tPoint* p);
+
+/**
+ * After a flip we have two triangles and know that only one will still be
+ * intersecting the edge. So decide which to contiune with and legalize the other
+ *
+ * @param tcx
+ * @param o - should be the result of an orient2d( eq, op, ep )
+ * @param t - triangle 1
+ * @param ot - triangle 2
+ * @param p - a point shared by both triangles
+ * @param op - another point shared by both triangles
+ * @return returns the triangle still intersecting the edge
+ */
+P2tTriangle* p2t_sweep_next_flip_triangle (P2tSweep *THIS, P2tSweepContext *tcx, int o, P2tTriangle *t, P2tTriangle *ot, P2tPoint* p, P2tPoint* op);
+
+/**
+ * When we need to traverse from one triangle to the next we need
+ * the point in current triangle that is the opposite point to the next
+ * triangle.
+ *
+ * @param ep
+ * @param eq
+ * @param ot
+ * @param op
+ * @return
+ */
+P2tPoint* p2t_sweep_next_flip_point (P2tSweep *THIS, P2tPoint* ep, P2tPoint* eq, P2tTriangle *ot, P2tPoint* op);
+
+/**
+ * Scan part of the FlipScan algorithm<br>
+ * When a triangle pair isn't flippable we will scan for the next
+ * point that is inside the flip triangle scan area. When found
+ * we generate a new flipEdgeEvent
+ *
+ * @param tcx
+ * @param ep - last point on the edge we are traversing
+ * @param eq - first point on the edge we are traversing
+ * @param flipTriangle - the current triangle sharing the point eq with edge
+ * @param t
+ * @param p
+ */
+void p2t_sweep_flip_scan_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle *flip_triangle, P2tTriangle *t, P2tPoint* p);
+
+void p2t_sweep_finalization_polygon (P2tSweep *THIS, P2tSweepContext *tcx);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep_context.c b/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep_context.c
new file mode 100644
index 0000000..9ed52d5
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep_context.c
@@ -0,0 +1,319 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sweep_context.h"
+#include "advancing_front.h"
+
+void
+p2t_sweepcontext_basin_init (P2tSweepContextBasin* THIS)
+{
+  p2t_sweepcontext_basin_clear (THIS);
+}
+
+void
+p2t_sweepcontext_basin_clear (P2tSweepContextBasin* THIS)
+{
+  THIS->left_node = NULL;
+  THIS->bottom_node = NULL;
+  THIS->right_node = NULL;
+  THIS->width = 0.0;
+  THIS->left_highest = FALSE;
+}
+
+void
+p2t_sweepcontext_edgeevent_init (P2tSweepContextEdgeEvent* THIS)
+{
+  THIS->constrained_edge = NULL;
+  THIS->right = FALSE;
+}
+
+void
+p2t_sweepcontext_init (P2tSweepContext* THIS, P2tPointPtrArray polyline)
+{
+  int i;
+  THIS->edge_list = g_ptr_array_new ();
+  THIS->triangles_ = g_ptr_array_new ();
+  THIS->map_ = NULL;
+
+  p2t_sweepcontext_basin_init (&THIS->basin);
+  p2t_sweepcontext_edgeevent_init (&THIS->edge_event);
+
+  THIS->points_ = g_ptr_array_sized_new (polyline->len);
+  for (i = 0; i < polyline->len; i++)
+    g_ptr_array_add (THIS->points_, point_index (polyline, i));
+
+  p2t_sweepcontext_init_edges (THIS, THIS->points_);
+}
+
+P2tSweepContext*
+p2t_sweepcontext_new (P2tPointPtrArray polyline)
+{
+  P2tSweepContext* THIS = g_new (P2tSweepContext, 1);
+  p2t_sweepcontext_init (THIS, polyline);
+  return THIS;
+}
+
+void
+p2t_sweepcontext_destroy (P2tSweepContext* THIS)
+{
+  GList* iter;
+  int i;
+  /* Clean up memory */
+
+  p2t_point_free (THIS->head_);
+  p2t_point_free (THIS->tail_);
+  p2t_advancingfront_free (THIS->front_);
+  p2t_node_free (THIS->af_head_);
+  p2t_node_free (THIS->af_middle_);
+  p2t_node_free (THIS->af_tail_);
+
+  g_ptr_array_free (THIS->points_, TRUE);
+  g_ptr_array_free (THIS->triangles_, TRUE);
+
+  for (iter = g_list_first (THIS->map_); iter != NULL; iter = g_list_next (iter))
+    {
+      P2tTriangle* ptr = triangle_val (iter);
+      g_free (ptr);
+    }
+
+  g_list_free (THIS->map_);
+
+  for (i = 0; i < THIS->edge_list->len; i++)
+    {
+      p2t_edge_free (edge_index (THIS->edge_list, i));
+    }
+
+  g_ptr_array_free (THIS->edge_list, TRUE);
+
+}
+
+void
+p2t_sweepcontext_delete (P2tSweepContext* THIS)
+{
+  p2t_sweepcontext_destroy (THIS);
+  g_free(THIS);
+}
+
+void
+p2t_sweepcontext_add_hole (P2tSweepContext *THIS, P2tPointPtrArray polyline)
+{
+  int i;
+  p2t_sweepcontext_init_edges (THIS, polyline);
+  for (i = 0; i < polyline->len; i++)
+    {
+      g_ptr_array_add (THIS->points_, point_index (polyline, i));
+    }
+}
+
+void
+p2t_sweepcontext_add_point (P2tSweepContext *THIS, P2tPoint* point)
+{
+  g_ptr_array_add (THIS->points_, point);
+}
+
+P2tTrianglePtrArray
+p2t_sweepcontext_get_triangles (P2tSweepContext *THIS)
+{
+  return THIS->triangles_;
+}
+
+P2tTrianglePtrList
+p2t_sweepcontext_get_map (P2tSweepContext *THIS)
+{
+  return THIS->map_;
+}
+
+void
+p2t_sweepcontext_init_triangulation (P2tSweepContext *THIS)
+{
+  int i;
+  double xmax = point_index (THIS->points_, 0)->x, xmin = point_index (THIS->points_, 0)->x;
+  double ymax = point_index (THIS->points_, 0)->y, ymin = point_index (THIS->points_, 0)->y;
+  double dx, dy;
+
+  /* Calculate bounds. */
+  for (i = 0; i < THIS->points_->len; i++)
+    {
+      P2tPoint* p = point_index (THIS->points_, i);
+      if (p->x > xmax)
+        xmax = p->x;
+      if (p->x < xmin)
+        xmin = p->x;
+      if (p->y > ymax)
+        ymax = p->y;
+      if (p->y < ymin)
+        ymin = p->y;
+    }
+
+  dx = kAlpha * (xmax - xmin);
+  dy = kAlpha * (ymax - ymin);
+  THIS->head_ = p2t_point_new_dd (xmax + dx, ymin - dy);
+  THIS->tail_ = p2t_point_new_dd (xmin - dx, ymin - dy);
+
+  /* Sort points along y-axis */
+  g_ptr_array_sort (THIS->points_, p2t_point_cmp);
+}
+
+void
+p2t_sweepcontext_init_edges (P2tSweepContext *THIS, P2tPointPtrArray polyline)
+{
+  int i;
+  int num_points = polyline->len;
+  g_ptr_array_set_size (THIS->edge_list, THIS->edge_list->len + num_points); /* C-OPTIMIZATION */
+  for (i = 0; i < num_points; i++)
+    {
+      int j = i < num_points - 1 ? i + 1 : 0;
+      g_ptr_array_add (THIS->edge_list, p2t_edge_new (point_index (polyline, i), point_index (polyline, j)));
+    }
+}
+
+P2tPoint*
+p2t_sweepcontext_get_point (P2tSweepContext *THIS, const int index)
+{
+  return point_index (THIS->points_, index);
+}
+
+void
+p2t_sweepcontext_add_to_map (P2tSweepContext *THIS, P2tTriangle* triangle)
+{
+  THIS->map_ = g_list_append (THIS->map_, triangle);
+}
+
+P2tNode*
+p2t_sweepcontext_locate_node (P2tSweepContext *THIS, P2tPoint* point)
+{
+  /* TODO implement search tree */
+  return p2t_advancingfront_locate_node (THIS->front_, point->x);
+}
+
+void
+p2t_sweepcontext_create_advancingfront (P2tSweepContext *THIS, P2tNodePtrArray nodes)
+{
+  /* Initial triangle */
+  P2tTriangle* triangle = p2t_triangle_new (point_index (THIS->points_, 0), THIS->tail_, THIS->head_);
+
+  THIS->map_ = g_list_append (THIS->map_, triangle);
+
+  THIS->af_head_ = p2t_node_new_pt_tr (p2t_triangle_get_point (triangle, 1), triangle);
+  THIS->af_middle_ = p2t_node_new_pt_tr (p2t_triangle_get_point (triangle, 0), triangle);
+  THIS->af_tail_ = p2t_node_new_pt (p2t_triangle_get_point (triangle, 2));
+  THIS->front_ = p2t_advancingfront_new (THIS->af_head_, THIS->af_tail_);
+
+  /* TODO: More intuitiv if head is middles next and not previous?
+   *       so swap head and tail */
+  THIS->af_head_->next = THIS->af_middle_;
+  THIS->af_middle_->next = THIS->af_tail_;
+  THIS->af_middle_->prev = THIS->af_head_;
+  THIS->af_tail_->prev = THIS->af_middle_;
+}
+
+void
+p2t_sweepcontext_remove_node (P2tSweepContext *THIS, P2tNode* node)
+{
+  g_free (node);
+}
+
+void
+p2t_sweepcontext_map_triangle_to_nodes (P2tSweepContext *THIS, P2tTriangle* t)
+{
+  int i;
+  for (i = 0; i < 3; i++)
+    {
+      if (!p2t_triangle_get_neighbor (t, i))
+        {
+          P2tNode* n = p2t_advancingfront_locate_point (THIS->front_, p2t_triangle_point_cw (t, p2t_triangle_get_point (t, i)));
+          if (n)
+            n->triangle = t;
+        }
+    }
+}
+
+void
+p2t_sweepcontext_remove_from_map (P2tSweepContext *THIS, P2tTriangle* triangle)
+{
+  THIS->map_ = g_list_remove (THIS->map_, triangle);
+}
+
+void
+p2t_sweepcontext_mesh_clean (P2tSweepContext *THIS, P2tTriangle* triangle)
+{
+  int i;
+  if (triangle != NULL && !p2t_triangle_is_interior (triangle))
+    {
+      p2t_triangle_is_interior_b (triangle, TRUE);
+      g_ptr_array_add (THIS->triangles_, triangle);
+      for (i = 0; i < 3; i++)
+        {
+          if (!triangle->constrained_edge[i])
+            p2t_sweepcontext_mesh_clean (THIS, p2t_triangle_get_neighbor (triangle, i));
+        }
+    }
+}
+
+P2tAdvancingFront*
+p2t_sweepcontext_front (P2tSweepContext *THIS)
+{
+  return THIS->front_;
+}
+
+int
+p2t_sweepcontext_point_count (P2tSweepContext *THIS)
+{
+  return THIS->points_->len;
+}
+
+void
+p2t_sweepcontext_set_head (P2tSweepContext *THIS, P2tPoint* p1)
+{
+  THIS->head_ = p1;
+}
+
+P2tPoint*
+p2t_sweepcontext_head (P2tSweepContext *THIS)
+{
+  return THIS->head_;
+}
+
+void
+p2t_sweepcontext_set_tail (P2tSweepContext *THIS, P2tPoint* p1)
+{
+  THIS->tail_ = p1;
+}
+
+P2tPoint*
+p2t_sweepcontext_tail (P2tSweepContext *THIS)
+{
+  return THIS->tail_;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep_context.h b/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep_context.h
new file mode 100644
index 0000000..2c9748f
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/p2t/sweep/sweep_context.h
@@ -0,0 +1,137 @@
+/*
+ * This file is a part of the C port of the Poly2Tri library
+ * Porting to C done by (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_P2T_SWEEP_CONTEXT_H__
+#define __P2TC_P2T_SWEEP_CONTEXT_H__
+
+#include "../common/poly2tri-private.h"
+#include "../common/shapes.h"
+#include "advancing_front.h"
+
+/* Inital triangle factor, seed triangle will extend 30% of
+ * PointSet width to both left and right. */
+#define kAlpha 0.3
+
+struct P2tSweepContextBasin_
+{
+  P2tNode* left_node;
+  P2tNode* bottom_node;
+  P2tNode* right_node;
+  double width;
+  gboolean left_highest;
+};
+
+void p2t_sweepcontext_basin_init (P2tSweepContextBasin* THIS);
+void p2t_sweepcontext_basin_clear (P2tSweepContextBasin* THIS);
+
+struct P2tSweepContextEdgeEvent_
+{
+  P2tEdge* constrained_edge;
+  gboolean right;
+};
+
+void p2t_sweepcontext_edgeevent_init (P2tSweepContextEdgeEvent* THIS);
+
+struct SweepContext_
+{
+  P2tEdgePtrArray edge_list;
+
+  P2tSweepContextBasin basin;
+  P2tSweepContextEdgeEvent edge_event;
+
+  P2tTrianglePtrArray triangles_;
+  P2tTrianglePtrList map_;
+  P2tPointPtrArray points_;
+
+  /** Advancing front */
+  P2tAdvancingFront* front_;
+  /** head point used with advancing front */
+  P2tPoint* head_;
+  /** tail point used with advancing front */
+  P2tPoint* tail_;
+
+  P2tNode *af_head_, *af_middle_, *af_tail_;
+};
+
+/** Constructor */
+void p2t_sweepcontext_init (P2tSweepContext* THIS, P2tPointPtrArray polyline);
+P2tSweepContext* p2t_sweepcontext_new (P2tPointPtrArray polyline);
+
+/** Destructor */
+void p2t_sweepcontext_destroy (P2tSweepContext* THIS);
+void p2t_sweepcontext_delete (P2tSweepContext* THIS);
+
+void p2t_sweepcontext_set_head (P2tSweepContext *THIS, P2tPoint* p1);
+
+P2tPoint* p2t_sweepcontext_head (P2tSweepContext *THIS);
+
+void p2t_sweepcontext_set_tail (P2tSweepContext *THIS, P2tPoint* p1);
+
+P2tPoint* p2t_sweepcontext_tail (P2tSweepContext *THIS);
+
+int p2t_sweepcontext_point_count (P2tSweepContext *THIS);
+
+P2tNode* p2t_sweepcontext_locate_node (P2tSweepContext *THIS, P2tPoint* point);
+
+void p2t_sweepcontext_remove_node (P2tSweepContext *THIS, P2tNode* node);
+
+void p2t_sweepcontext_create_advancingfront (P2tSweepContext *THIS, P2tNodePtrArray nodes);
+
+/** Try to map a node to all sides of this triangle that don't have a neighbor */
+void p2t_sweepcontext_map_triangle_to_nodes (P2tSweepContext *THIS, P2tTriangle* t);
+
+void p2t_sweepcontext_add_to_map (P2tSweepContext *THIS, P2tTriangle* triangle);
+
+P2tPoint* p2t_sweepcontext_get_point (P2tSweepContext *THIS, const int index);
+
+P2tPoint* SweepContext_GetPoints (P2tSweepContext *THIS);
+
+void p2t_sweepcontext_remove_from_map (P2tSweepContext *THIS, P2tTriangle* triangle);
+
+void p2t_sweepcontext_add_hole (P2tSweepContext *THIS, P2tPointPtrArray polyline);
+
+void p2t_sweepcontext_add_point (P2tSweepContext *THIS, P2tPoint* point);
+
+P2tAdvancingFront* p2t_sweepcontext_front (P2tSweepContext *THIS);
+
+void p2t_sweepcontext_mesh_clean (P2tSweepContext *THIS, P2tTriangle* triangle);
+
+P2tTrianglePtrArray p2t_sweepcontext_get_triangles (P2tSweepContext *THIS);
+P2tTrianglePtrList p2t_sweepcontext_get_map (P2tSweepContext *THIS);
+
+void p2t_sweepcontext_init_triangulation (P2tSweepContext *THIS);
+void p2t_sweepcontext_init_edges (P2tSweepContext *THIS, P2tPointPtrArray polyline);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/Makefile.am b/libs/poly2tri-c/poly2tri-c/refine/Makefile.am
new file mode 100644
index 0000000..8701b0d
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/Makefile.am
@@ -0,0 +1,6 @@
+noinst_LTLIBRARIES = libp2tc-refine.la
+
+libp2tc_refine_la_SOURCES = bounded-line.c bounded-line.h cdt.c cdt.h cdt-flipfix.c cdt-flipfix.h circle.c circle.h cluster.c cluster.h delaunay-terminator.c delaunay-terminator.h edge.c edge.h line.c line.h rmath.c rmath.h mesh.c mesh.h mesh-action.c mesh-action.h point.c point.h pslg.c pslg.h refine.h refiner.c refiner.h triangle.c triangle.h triangulation.h utils.c utils.h vector2.c vector2.h vedge.c vedge.h vtriangle.c vtriangle.h visibility.c visibility.h
+
+P2TC_REFINE_publicdir = $(P2TC_publicdir)/refine
+P2TC_REFINE_public_HEADERS = bounded-line.h cdt.h circle.h cluster.h edge.h line.h mesh.h mesh-action.h point.h pslg.h refine.h refiner.h rmath.h triangle.h triangulation.h utils.h vector2.h vedge.h vtriangle.h visibility.h
diff --git a/libs/poly2tri-c/poly2tri-c/refine/bounded-line.c b/libs/poly2tri-c/poly2tri-c/refine/bounded-line.c
new file mode 100644
index 0000000..ad08580
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/bounded-line.c
@@ -0,0 +1,84 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include "bounded-line.h"
+
+P2trBoundedLine*
+p2tr_bounded_line_new (const P2trVector2 *start,
+                       const P2trVector2 *end)
+{
+  P2trBoundedLine* line = g_slice_new (P2trBoundedLine);
+  p2tr_bounded_line_init (line, start, end);
+  return line;
+}
+
+void
+p2tr_bounded_line_init (P2trBoundedLine   *line,
+                        const P2trVector2 *start,
+                        const P2trVector2 *end)
+{
+  /* Traditional line Equation:
+   * y - mx - n = 0   <==>   y = mx + n
+   * Slope Equation:
+   * m = dy / dx
+   * Slope + Traditional:
+   * dx * y - dy * x - dx * n = 0
+   * And the remaining part can be found as
+   * dx * y0 - dy * x0 = dx * n
+   * So the final equation is:
+   * dx * y - dy * x - (dx * y0 - dy * x0) = 0
+   */
+  gdouble dx = end->x - start->x;
+  gdouble dy = end->y - start->y;
+
+  gdouble dxXn = start->y * dx - start->x * dy;
+
+  p2tr_line_init(&line->infinite, -dy, dx, -dxXn);
+
+  p2tr_vector2_copy(&line->start, start);
+  p2tr_vector2_copy(&line->end, end);
+}
+
+gboolean
+p2tr_bounded_line_intersect (const P2trBoundedLine *l1,
+                             const P2trBoundedLine *l2)
+{
+  return p2tr_line_different_sides (&l1->infinite, &l2->start, &l2->end)
+    && p2tr_line_different_sides (&l2->infinite, &l1->start, &l1->end);
+}
+
+void
+p2tr_bounded_line_free (P2trBoundedLine *line)
+{
+  g_slice_free (P2trBoundedLine, line);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/bounded-line.h b/libs/poly2tri-c/poly2tri-c/refine/bounded-line.h
new file mode 100644
index 0000000..577259d
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/bounded-line.h
@@ -0,0 +1,58 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_BOUNDED_LINE_H__
+#define __P2TC_REFINE_BOUNDED_LINE_H__
+
+#include <glib.h>
+#include "vector2.h"
+#include "line.h"
+
+typedef struct
+{
+  P2trLine infinite;
+  P2trVector2 start, end;
+} P2trBoundedLine;
+
+P2trBoundedLine*  p2tr_bounded_line_new       (const P2trVector2 *start,
+                                               const P2trVector2 *end);
+
+void              p2tr_bounded_line_init      (P2trBoundedLine   *line,
+                                               const P2trVector2 *start,
+                                               const P2trVector2 *end);
+
+gboolean          p2tr_bounded_line_intersect (const P2trBoundedLine *l1,
+                                               const P2trBoundedLine *l2);
+
+void              p2tr_bounded_line_free      (P2trBoundedLine *line);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/cdt-flipfix.c b/libs/poly2tri-c/poly2tri-c/refine/cdt-flipfix.c
new file mode 100644
index 0000000..3efeb09
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/cdt-flipfix.c
@@ -0,0 +1,159 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+#include "vedge.h"
+
+#include "cdt-flipfix.h"
+
+
+static P2trEdge*  p2tr_cdt_try_flip  (P2trCDT   *self,
+                                      P2trEdge  *to_flip);
+
+/* This function implements "Lawson's algorithm", also known as "The
+ * diagonal swapping algorithm". This algorithm takes a CDT, and a list
+ * of triangles that were formed by the insertion of a new point into
+ * the triangular mesh, and makes the triangulation a CDT once more. Its
+ * logic is explained below:
+ *
+ *   If a point is added to an existing triangular mesh then
+ *   circumcircles are formed for all new triangles formed. If any of
+ *   the neighbours lie inside the circumcircle of any triangle, then a
+ *   quadrilateral is formed using the triangle and its neighbour. The
+ *   diagonals of this quadrilateral are swapped to give a new
+ *   triangulation. This process is continued till there are no more
+ *   faulty triangles and no more swaps are required.
+ *
+ * The description above may seem slightly inaccurate, as it does not
+ * consider the case were the diagonals can not be swapped since the
+ * quadrilateral is concave (then swapping the diagonals would result
+ * in a diagonal outside the quad, which is undesired).
+ *
+ * However, the description above is accurate. If the opposite point
+ * is inside the circular cut created by the edge, then since the
+ * circular cut is inside the infinite area created by extending the
+ * two other edges of the triangle, therefor the point is also inside
+ * that area - meaning that the quadrilateral is not concave!
+ */
+
+void
+p2tr_cdt_flip_fix (P2trCDT     *self,
+                   P2trVEdgeSet *candidates)
+{
+  P2trEdge *edge;
+  P2trVEdge *vedge;
+
+  while (p2tr_vedge_set_pop (candidates, &vedge))
+    {
+      if (! p2tr_vedge_try_get_and_unref (vedge, &edge))
+        continue;
+
+      if (! edge->constrained
+          /* TODO: we probably don't need this check... */
+          && ! p2tr_edge_is_removed (edge))
+        {
+          /* If the edge is not constrained, then it should be
+           * a part of two triangles */
+          P2trPoint *A  = P2TR_EDGE_START(edge), *B = edge->end;
+          P2trPoint *C1 = p2tr_triangle_get_opposite_point (edge->tri, edge, FALSE);
+          P2trPoint *C2 = p2tr_triangle_get_opposite_point (edge->mirror->tri, edge->mirror, FALSE);
+
+          P2trEdge *flipped = p2tr_cdt_try_flip (self, edge);
+          if (flipped != NULL)
+            {
+              p2tr_vedge_set_add (candidates, p2tr_point_get_edge_to (A, C1, TRUE));
+              p2tr_vedge_set_add (candidates, p2tr_point_get_edge_to (A, C2, TRUE));
+              p2tr_vedge_set_add (candidates, p2tr_point_get_edge_to (B, C1, TRUE));
+              p2tr_vedge_set_add (candidates, p2tr_point_get_edge_to (B, C2, TRUE));
+              p2tr_edge_unref (flipped);
+            }
+        }
+
+      p2tr_edge_unref (edge);
+    }
+}
+
+/**
+ * Try to flip a given edge, If successfull, return the new edge (reffed!),
+ * otherwise return NULL
+ */
+P2trEdge*
+p2tr_cdt_try_flip (P2trCDT   *self,
+                   P2trEdge  *to_flip)
+{
+  /*    C
+   *  / | \
+   * B-----A    to_flip: A->B
+   *  \ | /     to_flip.Tri: ABC
+   *    D
+   */
+  P2trPoint *A, *B, *C, *D;
+  P2trEdge *AB, *CA, *AD, *DB, *BC, *DC;
+
+  g_assert (! to_flip->constrained && ! to_flip->delaunay);
+
+  A = P2TR_EDGE_START (to_flip);
+  B = to_flip->end;
+  C = p2tr_triangle_get_opposite_point (to_flip->tri, to_flip, FALSE);
+  D = p2tr_triangle_get_opposite_point (to_flip->mirror->tri, to_flip->mirror, FALSE);
+
+  AB = to_flip;
+
+  /* Check if the quadriliteral ADBC is concave (because if it is, we
+   * can't flip the edge) */
+  if (p2tr_triangle_circumcircle_contains_point (AB->tri, &D->c) != P2TR_INCIRCLE_IN)
+    return NULL;
+
+  CA = p2tr_point_get_edge_to (C, A, FALSE);
+  AD = p2tr_point_get_edge_to (A, D, FALSE);
+  DB = p2tr_point_get_edge_to (D, B, FALSE);
+  BC = p2tr_point_get_edge_to (B, C, FALSE);
+
+  p2tr_edge_remove (AB);
+
+  DC = p2tr_mesh_new_edge (self->mesh, D, C, FALSE);
+
+  p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh,
+      CA, AD, DC));
+
+  p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh,
+      DB, BC, DC->mirror));
+
+  return DC;
+}
+
+
+
diff --git a/libs/poly2tri-c/poly2tri-c/refine/cdt-flipfix.h b/libs/poly2tri-c/poly2tri-c/refine/cdt-flipfix.h
new file mode 100644
index 0000000..dad11b2
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/cdt-flipfix.h
@@ -0,0 +1,49 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_CDT_FLIPFIX_H__
+#define __P2TC_REFINE_CDT_FLIPFIX_H__
+
+#include <glib.h>
+
+#include "edge.h"
+#include "vedge.h"
+#include "cdt.h"
+#include "utils.h"
+
+/**
+ * Flip-Fix all the virtual edges inside the given set
+ */
+void         p2tr_cdt_flip_fix  (P2trCDT     *self,
+                                 P2trVEdgeSet *candidates);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/cdt.c b/libs/poly2tri-c/poly2tri-c/refine/cdt.c
new file mode 100644
index 0000000..7dc1d11
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/cdt.c
@@ -0,0 +1,491 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <glib.h>
+
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+
+#include "cdt.h"
+#include "visibility.h"
+#include "cdt-flipfix.h"
+
+static gboolean  p2tr_cdt_visible_from_tri        (P2trCDT      *self,
+                                                   P2trTriangle *tri,
+                                                   P2trVector2  *p);
+
+static gboolean  p2tr_cdt_has_empty_circum_circle (P2trCDT      *self,
+                                                   P2trTriangle *tri);
+
+static P2trHashSet* p2tr_cdt_triangulate_fan         (P2trCDT   *self,
+                                                      P2trPoint *center,
+                                                      GList     *edge_pts);
+
+void
+p2tr_cdt_validate_unused (P2trCDT* self)
+{
+  P2trEdge *ed;
+  P2trTriangle *tri;
+  P2trHashSetIter iter;
+
+  p2tr_hash_set_iter_init (&iter, self->mesh->edges);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&ed))
+    {
+      g_assert (ed->mirror != NULL);
+      g_assert (! p2tr_edge_is_removed (ed));
+    }
+
+  p2tr_hash_set_iter_init (&iter, self->mesh->triangles);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&tri))
+    g_assert (! p2tr_triangle_is_removed (tri));
+}
+
+P2trCDT*
+p2tr_cdt_new (P2tCDT *cdt)
+{
+  P2tTrianglePtrArray cdt_tris = p2t_cdt_get_triangles (cdt);
+  GHashTable *point_map = g_hash_table_new (g_direct_hash, g_direct_equal);
+  P2trCDT *rmesh = g_slice_new (P2trCDT);
+  GHashTableIter iter;
+  P2trPoint *pt_iter = NULL;
+
+  P2trVEdgeSet *new_edges = p2tr_vedge_set_new ();
+
+  gint i, j;
+
+  rmesh->mesh = p2tr_mesh_new ();
+  rmesh->outline = p2tr_pslg_new ();
+
+  /* First iteration over the CDT - create all the points */
+  for (i = 0; i < cdt_tris->len; i++)
+  {
+    P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);
+    for (j = 0; j < 3; j++)
+      {
+        P2tPoint *cdt_pt = p2t_triangle_get_point(cdt_tri, j);
+        P2trPoint *new_pt = (P2trPoint*) g_hash_table_lookup (point_map, cdt_pt);
+
+        if (new_pt == NULL)
+          {
+            new_pt = p2tr_mesh_new_point2 (rmesh->mesh, cdt_pt->x, cdt_pt->y);
+            g_hash_table_insert (point_map, cdt_pt, new_pt);
+          }
+      }
+  }
+
+  /* Second iteration over the CDT - create all the edges and find the
+   * outline */
+  for (i = 0; i < cdt_tris->len; i++)
+  {
+    P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);
+
+    for (j = 0; j < 3; j++)
+      {
+        P2tPoint *start = p2t_triangle_get_point (cdt_tri, j);
+        P2tPoint *end = p2t_triangle_get_point (cdt_tri, (j + 1) % 3);
+        int edge_index = p2t_triangle_edge_index (cdt_tri, start, end);
+
+        P2trPoint *start_new = (P2trPoint*) g_hash_table_lookup (point_map, start);
+        P2trPoint *end_new = (P2trPoint*) g_hash_table_lookup (point_map, end);
+
+        if (! p2tr_point_has_edge_to (start_new, end_new))
+          {
+            gboolean constrained = cdt_tri->constrained_edge[edge_index]
+            || cdt_tri->neighbors_[edge_index] == NULL;
+            P2trEdge *edge = p2tr_mesh_new_edge (rmesh->mesh, start_new, end_new, constrained);
+
+            /* If the edge is constrained, we should add it to the
+             * outline */
+            if (constrained)
+              p2tr_pslg_add_new_line(rmesh->outline, &start_new->c,
+                  &end_new->c);
+
+            /* We only wanted to create the edge now. We will use it
+             * later */
+            p2tr_vedge_set_add (new_edges, edge);
+          }
+      }
+  }
+
+  /* Third iteration over the CDT - create all the triangles */
+  for (i = 0; i < cdt_tris->len; i++)
+  {
+    P2tTriangle *cdt_tri = triangle_index (cdt_tris, i);
+
+    P2trPoint *pt1 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 0));
+    P2trPoint *pt2 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 1));
+    P2trPoint *pt3 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 2));
+
+    P2trTriangle *new_tri = p2tr_mesh_new_triangle (rmesh->mesh,
+        p2tr_point_get_edge_to(pt1, pt2, FALSE),
+        p2tr_point_get_edge_to(pt2, pt3, FALSE),
+        p2tr_point_get_edge_to(pt3, pt1, FALSE));
+
+    /* We won't do any usage of the triangle, so just unref it */
+    p2tr_triangle_unref (new_tri);
+  }
+
+  /* And do an extra flip fix */
+  p2tr_cdt_flip_fix (rmesh, new_edges);
+
+  p2tr_vedge_set_free (new_edges);
+
+  /* Now finally unref the points we added into the map */
+  g_hash_table_iter_init (&iter, point_map);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer*)&pt_iter))
+    p2tr_point_unref (pt_iter);
+  g_hash_table_destroy (point_map);
+
+  return rmesh;
+}
+
+void
+p2tr_cdt_free (P2trCDT *self)
+{
+  p2tr_cdt_free_full (self, TRUE);
+}
+
+void
+p2tr_cdt_free_full (P2trCDT* self, gboolean clear_mesh)
+{
+  p2tr_pslg_free (self->outline);
+  if (clear_mesh)
+    p2tr_mesh_clear (self->mesh);
+  p2tr_mesh_unref (self->mesh);
+
+  g_slice_free (P2trCDT, self);
+}
+
+void
+p2tr_cdt_validate_edges (P2trCDT *self)
+{
+  P2trHashSetIter iter;
+  P2trEdge *e;
+
+  p2tr_hash_set_iter_init (&iter, self->mesh->edges);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&e))
+    {
+      if (! e->constrained && e->tri == NULL)
+        p2tr_exception_geometric ("Found a non constrained edge without a triangle");
+
+      if (e->tri != NULL)
+        {
+          gboolean found = FALSE;
+          gint i = 0;
+
+          for (i = 0; i < 3; i++)
+            if (e->tri->edges[i] == e)
+              {
+                found = TRUE;
+                break;
+              }
+
+          if (! found)
+              p2tr_exception_geometric ("An edge has a triangle to which it does not belong!");
+        }
+    }
+}
+
+gboolean
+p2tr_cdt_visible_from_edge (P2trCDT     *self,
+                            P2trEdge    *e,
+                            P2trVector2 *p)
+{
+  P2trBoundedLine line;
+
+  p2tr_bounded_line_init (&line, &P2TR_EDGE_START(e)->c, &e->end->c);
+
+  return p2tr_visibility_is_visible_from_edges (self->outline, p, &line, 1);
+}
+
+static gboolean
+p2tr_cdt_visible_from_tri (P2trCDT      *self,
+                           P2trTriangle *tri,
+                           P2trVector2  *p)
+{
+  P2trBoundedLine lines[3];
+  gint i;
+
+  for (i = 0; i < 3; i++)
+    p2tr_bounded_line_init (&lines[i],
+        &P2TR_EDGE_START(tri->edges[i])->c,
+        &tri->edges[i]->end->c);
+
+  return p2tr_visibility_is_visible_from_edges (self->outline, p, lines, 3);
+}
+
+static gboolean
+p2tr_cdt_has_empty_circum_circle (P2trCDT      *self,
+                                  P2trTriangle *tri)
+{
+  P2trCircle circum;
+  P2trPoint *p;
+  P2trHashSetIter iter;
+
+  p2tr_triangle_get_circum_circle (tri, &circum);
+
+  p2tr_hash_set_iter_init (&iter, self->mesh->points);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&p))
+    {
+      /** TODO: FIXME - is a point on a constrained edge really not a
+       * problem?! */
+      if (p2tr_point_has_constrained_edge (p)
+          /* The points of a triangle can't violate its own empty
+           * circumcircle property */
+          || p == tri->edges[0]->end
+          || p == tri->edges[1]->end
+          || p == tri->edges[2]->end)
+          continue;
+
+      if (! p2tr_circle_test_point_outside(&circum, &p->c)
+          && p2tr_cdt_visible_from_tri (self, tri, &p->c))
+          return FALSE;
+    }
+  return TRUE;
+}
+
+void
+p2tr_cdt_validate_cdt (P2trCDT *self)
+{
+  P2trHashSetIter iter;
+  P2trTriangle *tri;
+
+  p2tr_hash_set_iter_init (&iter, self->mesh->triangles);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&tri))
+    if (! p2tr_cdt_has_empty_circum_circle(self, tri))
+      p2tr_exception_geometric ("Not a CDT!");
+}
+
+P2trPoint*
+p2tr_cdt_insert_point (P2trCDT           *self,
+                       const P2trVector2 *pc,
+                       P2trTriangle      *point_location_guess)
+{
+  P2trTriangle *tri;
+  P2trPoint    *pt;
+  gboolean      inserted = FALSE;
+  gint          i;
+
+  P2TR_CDT_VALIDATE_UNUSED (self);
+
+  if (point_location_guess == NULL)
+    tri = p2tr_mesh_find_point (self->mesh, pc);
+  else
+    tri = p2tr_mesh_find_point_local (self->mesh, pc, point_location_guess);
+
+  if (tri == NULL)
+    p2tr_exception_geometric ("Tried to add point outside of domain!");
+
+  pt = p2tr_mesh_new_point (self->mesh, pc);
+
+  /* If the point falls on a line, we should split the line */
+  for (i = 0; i < 3; i++)
+    {
+      P2trEdge *edge = tri->edges[i];
+      if (p2tr_math_orient2d (& P2TR_EDGE_START(edge)->c,
+              &edge->end->c, pc) == P2TR_ORIENTATION_LINEAR)
+        {
+          GList *parts = p2tr_cdt_split_edge (self, edge, pt), *eIter;
+          for (eIter = parts; eIter != NULL; eIter = eIter->next)
+            p2tr_edge_unref ((P2trEdge*)eIter->data);
+          inserted = TRUE;
+          break;
+        }
+    }
+
+  if (! inserted)
+    /* If we reached this line, then the point is inside the triangle */
+    p2tr_cdt_insert_point_into_triangle (self, pt, tri);
+
+  /* We no longer need the triangle */
+  p2tr_triangle_unref (tri);
+
+  P2TR_CDT_VALIDATE_UNUSED (self);
+  return pt;
+}
+
+/** Insert a point into a triangle. This function assumes the point is
+ * inside the triangle - not on one of its edges and not outside of it.
+ */
+void
+p2tr_cdt_insert_point_into_triangle (P2trCDT      *self,
+                                     P2trPoint    *P,
+                                     P2trTriangle *tri)
+{
+  P2trVEdgeSet *flip_candidates = p2tr_vedge_set_new ();
+
+  P2trPoint *A = tri->edges[0]->end;
+  P2trPoint *B = tri->edges[1]->end;
+  P2trPoint *C = tri->edges[2]->end;
+
+  P2trEdge *CA = tri->edges[0];
+  P2trEdge *AB = tri->edges[1];
+  P2trEdge *BC = tri->edges[2];
+
+  P2trEdge *AP, *BP, *CP;
+
+  p2tr_triangle_remove (tri);
+
+  AP = p2tr_mesh_new_edge (self->mesh, A, P, FALSE);
+  BP = p2tr_mesh_new_edge (self->mesh, B, P, FALSE);
+  CP = p2tr_mesh_new_edge (self->mesh, C, P, FALSE);
+
+  p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh, AB, BP, AP->mirror));
+  p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh, BC, CP, BP->mirror));
+  p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh, CA, AP, CP->mirror));
+
+  p2tr_vedge_set_add (flip_candidates, CP);
+  p2tr_vedge_set_add (flip_candidates, AP);
+  p2tr_vedge_set_add (flip_candidates, BP);
+
+  p2tr_vedge_set_add (flip_candidates, p2tr_edge_ref (CA));
+  p2tr_vedge_set_add (flip_candidates, p2tr_edge_ref (AB));
+  p2tr_vedge_set_add (flip_candidates, p2tr_edge_ref (BC));
+
+  /* Flip fix the newly created triangles to preserve the the
+   * constrained delaunay property. The flip-fix function will unref the
+   * new triangles for us! */
+  p2tr_cdt_flip_fix (self, flip_candidates);
+
+  p2tr_vedge_set_free (flip_candidates);
+}
+
+/**
+ * Triangulate a polygon by creating edges to a center point.
+ * 1. If there is a NULL point in the polygon, two triangles are not
+ *    created (these are the two that would have used it)
+ * 2. THE RETURNED EDGES MUST BE UNREFFED!
+ */
+static P2trVEdgeSet*
+p2tr_cdt_triangulate_fan (P2trCDT   *self,
+                          P2trPoint *center,
+                          GList     *edge_pts)
+{
+  P2trVEdgeSet* fan_edges = p2tr_vedge_set_new ();
+  GList *iter;
+
+  /* We can not triangulate unless at least two points are given */
+  if (edge_pts == NULL || edge_pts->next == NULL)
+    {
+      p2tr_exception_programmatic ("Not enough points to triangulate as"
+          " a star!");
+    }
+
+  for (iter = edge_pts; iter != NULL; iter = iter->next)
+    {
+      P2trPoint *A = (P2trPoint*) iter->data;
+      P2trPoint *B = (P2trPoint*) g_list_cyclic_next (edge_pts, iter)->data;
+      P2trEdge *AB, *BC, *CA;
+
+      if (A == NULL || B == NULL)
+        continue;
+
+      AB = p2tr_point_get_edge_to (A, B, TRUE);
+      BC = p2tr_mesh_new_or_existing_edge (self->mesh, B, center, FALSE);
+      CA = p2tr_mesh_new_or_existing_edge (self->mesh, center, A, FALSE);
+
+      p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh, AB, BC, CA));
+
+      p2tr_vedge_set_add (fan_edges, CA);
+      p2tr_vedge_set_add (fan_edges, BC);
+      p2tr_vedge_set_add (fan_edges, AB);
+    }
+
+  return fan_edges;
+}
+
+GList*
+p2tr_cdt_split_edge (P2trCDT   *self,
+                     P2trEdge  *e,
+                     P2trPoint *C)
+{
+  /*      W
+   *     /|\
+   *    / | \
+   *   /  |  \      E.Mirror.Tri: YXW
+   * X*---*---*Y    E: X->Y
+   *   \  |C /      E.Tri: XYV
+   *    \ | /
+   *     \|/
+   *      V
+   */
+  P2trPoint *X = P2TR_EDGE_START (e), *Y = e->end;
+  P2trPoint *V = (e->tri != NULL) ? p2tr_triangle_get_opposite_point(e->tri, e, FALSE) : NULL;
+  P2trPoint *W = (e->mirror->tri != NULL) ? p2tr_triangle_get_opposite_point (e->mirror->tri, e->mirror, FALSE) : NULL;
+  gboolean   constrained = e->constrained;
+  P2trEdge  *XC, *CY;
+  GList     *fan = NULL, *new_edges = NULL;
+  P2trHashSet *fan_edges;
+
+  P2TR_CDT_VALIDATE_UNUSED (self);
+
+  p2tr_edge_remove (e);
+
+  XC = p2tr_mesh_new_edge (self->mesh, X, C, constrained);
+  CY = p2tr_mesh_new_edge (self->mesh, C, Y, constrained);
+
+  fan = p2tr_utils_new_reversed_pointer_list (4, W, X, V, Y);
+  fan_edges = p2tr_cdt_triangulate_fan (self, C, fan);
+  g_list_free (fan);
+
+  /* Now make this a CDT again
+   * The new triangles will be unreffed by the flip_fix function, which
+   * is good since we receive them with an extra reference!
+   */
+  p2tr_cdt_flip_fix (self, fan_edges);
+  p2tr_hash_set_free (fan_edges);
+
+  if (constrained)
+    {
+      /* If this was a subsegment, then both parts of the subsegment
+       * should exist */
+      if (p2tr_edge_is_removed (XC) || p2tr_edge_is_removed (CY))
+        p2tr_exception_geometric ("Subsegments gone!");
+      else
+        {
+          new_edges = g_list_prepend (new_edges, CY);
+          new_edges = g_list_prepend (new_edges, XC);
+        }
+    }
+  else
+    {
+      p2tr_edge_unref (XC);
+      p2tr_edge_unref (CY);
+    }
+
+  P2TR_CDT_VALIDATE_UNUSED (self);
+
+  return new_edges;
+}
+
diff --git a/libs/poly2tri-c/poly2tri-c/refine/cdt.h b/libs/poly2tri-c/poly2tri-c/refine/cdt.h
new file mode 100644
index 0000000..23455a6
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/cdt.h
@@ -0,0 +1,127 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_CDT_H__
+#define __P2TC_REFINE_CDT_H__
+
+#include <poly2tri-c/p2t/poly2tri.h>
+#include "mesh.h"
+#include "pslg.h"
+
+typedef struct
+{
+  P2trMesh *mesh;
+  P2trPSLG *outline;
+} P2trCDT;
+
+/**
+ * Create a new P2trCDT from an existing P2tCDT. The resulting P2trCDT
+ * does not depend on the original P2tCDT which can be freed
+ * @param cdt A P2tCDT Constrained Delaunay Triangulation
+ * @return A P2trCDT Constrained Delaunay Triangulation
+ */
+P2trCDT*    p2tr_cdt_new       (P2tCDT *cdt);
+
+void        p2tr_cdt_free      (P2trCDT *cdt);
+
+void        p2tr_cdt_free_full (P2trCDT *cdt, gboolean clear_mesh);
+
+/**
+ * Test whether there is a path from the point @ref p to the edge @e
+ * so that the path does not cross any segment of the CDT
+ */
+gboolean    p2tr_cdt_visible_from_edge (P2trCDT     *self,
+                                        P2trEdge    *e,
+                                        P2trVector2 *p);
+
+/**
+ * Make sure that all edges either have two triangles (one on each side)
+ * or that they are constrained. The reason for that is that the
+ * triangulation domain of the CDT is defined by a closed PSLG.
+ */
+void        p2tr_cdt_validate_edges    (P2trCDT *self);
+
+void        p2tr_cdt_validate_unused   (P2trCDT* self);
+
+/**
+ * Make sure the constrained empty circum-circle property holds,
+ * meaning that each triangles circum-scribing circle is either empty
+ * or only contains points which are not "visible" from the edges of
+ * the triangle.
+ */
+void        p2tr_cdt_validate_cdt      (P2trCDT *self);
+
+#if P2TR_CDT_VALIDATE
+#define P2TR_CDT_VALIDATE_EDGES(CDT)  p2tr_cdt_validate_edges(CDT)
+#define P2TR_CDT_VALIDATE_UNUSED(CDT) p2tr_cdt_validate_unused(CDT)
+#define P2TR_CDT_VALIDATE_CDT(CDT)    p2tr_cdt_validate_cdt(CDT)
+#else
+#define P2TR_CDT_VALIDATE_EDGES(CDT)  G_STMT_START { } G_STMT_END
+#define P2TR_CDT_VALIDATE_UNUSED(CDT) G_STMT_START { } G_STMT_END
+#define P2TR_CDT_VALIDATE_CDT(CDT)    G_STMT_START { } G_STMT_END
+#endif
+
+/**
+ * Insert a point into the triangulation while preserving the
+ * constrained delaunay property
+ * @param self The CDT into which the point should be inserted
+ * @param pc The point to insert
+ * @param point_location_guess A triangle which may be near the
+ *        area containing the point (or maybe even contains the point).
+ *        The better the guess is, the faster the insertion will be. If
+ *        such a triangle is unknown, NULL may be passed.
+ */
+P2trPoint*  p2tr_cdt_insert_point      (P2trCDT           *self,
+                                        const P2trVector2 *pc,
+                                        P2trTriangle      *point_location_guess);
+
+/**
+ * Similar to @ref p2tr_cdt_insert_point, but assumes that the point to
+ * insert is located inside the area of the given triangle
+ */
+void        p2tr_cdt_insert_point_into_triangle (P2trCDT      *self,
+                                                 P2trPoint    *pt,
+                                                 P2trTriangle *tri);
+
+/**
+ * Insert a point so that is splits an existing edge, while preserving
+ * the constrained delaunay property. This function assumes that the
+ * point is on the edge itself and between its end-points.
+ * If the edge being split is constrained, then the function returns a
+ * list containing both parts resulted from the splitting. In that case,
+ * THE RETURNED EDGES MUST BE UNREFERENCED!
+ */
+GList*      p2tr_cdt_split_edge (P2trCDT   *self,
+                                 P2trEdge  *e,
+                                 P2trPoint *C);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/circle.c b/libs/poly2tri-c/poly2tri-c/refine/circle.c
new file mode 100644
index 0000000..affb1f6
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/circle.c
@@ -0,0 +1,47 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include "circle.h"
+
+gboolean
+p2tr_circle_test_point_outside (P2trCircle  *circle,
+                                P2trVector2 *pt)
+{
+  gdouble dx = circle->center.x - pt->x;
+  gdouble dy = circle->center.y - pt->y;
+
+  gdouble d_squared = dx * dx + dy * dy;
+  gdouble radius_squared = circle->radius * circle->radius;
+
+  return d_squared > radius_squared;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/circle.h b/libs/poly2tri-c/poly2tri-c/refine/circle.h
new file mode 100644
index 0000000..06bcdc3
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/circle.h
@@ -0,0 +1,46 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_CIRCLE_H__
+#define __P2TC_REFINE_CIRCLE_H__
+
+#include <glib.h>
+#include "vector2.h"
+
+typedef struct {
+  P2trVector2 center;
+  gdouble radius;
+} P2trCircle;
+
+gboolean  p2tr_circle_test_point_outside (P2trCircle *circle, P2trVector2 *pt);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/cluster.c b/libs/poly2tri-c/poly2tri-c/refine/cluster.c
new file mode 100644
index 0000000..3e6ce25
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/cluster.c
@@ -0,0 +1,139 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+
+#include <glib.h>
+#include "utils.h"
+#include "point.h"
+#include "edge.h"
+
+#include "cluster.h"
+
+static gboolean p2tr_cluster_cw_tri_between_is_in_domain (P2trEdge *e1,
+                                                          P2trEdge *e2);
+
+gdouble
+p2tr_cluster_shortest_edge_length (P2trCluster *self)
+{
+  gdouble min_length_sq = G_MAXDOUBLE, temp;
+  GList *iter;
+  
+  for (iter = self->edges.head; iter != NULL; iter = iter->next)
+    {
+      temp = p2tr_edge_get_length_squared ((P2trEdge*)iter->data);
+      min_length_sq = MIN(min_length_sq, temp);
+    }
+  return sqrt (min_length_sq);
+}
+
+/**
+ * Return the edge cluster of the specified edge from the specified end
+ * point. THE EDGES IN THE CLUSTER MUST BE UNREFFED!
+ * @param[in] P The point which is shared between all edges of the cluster
+ * @param[in] E The edge whose cluster should be returned
+ * @return The cluster of @ref E from the point @ref P
+ */
+P2trCluster*
+p2tr_cluster_get_for (P2trPoint   *P,
+                      P2trEdge    *E)
+{
+  P2trCluster *cluster = g_slice_new (P2trCluster);
+  gdouble temp_angle;
+  P2trEdge *current, *next;
+  
+  cluster->min_angle = G_MAXDOUBLE;
+  g_queue_init (&cluster->edges);
+
+  if (P == E->end)
+    E = E->mirror;
+  else if (P != P2TR_EDGE_START (E))
+    p2tr_exception_programmatic ("Unexpected point for the edge!");
+
+  g_queue_push_head (&cluster->edges, p2tr_edge_ref (E));
+
+  current = E;
+  next = p2tr_point_edge_cw (P, current);
+  
+  while (next != g_queue_peek_head (&cluster->edges)
+      && (temp_angle = p2tr_edge_angle_between (current->mirror, next)) <= P2TR_CLUSTER_LIMIT_ANGLE
+      && p2tr_cluster_cw_tri_between_is_in_domain (current, next))
+    {
+      g_queue_push_tail (&cluster->edges, p2tr_edge_ref (next));
+      current = next;
+      next = p2tr_point_edge_cw (P, current);
+      cluster->min_angle = MIN (cluster->min_angle, temp_angle);
+    }
+
+  current = E;
+  next = p2tr_point_edge_ccw(P, current);
+  while (next != g_queue_peek_tail (&cluster->edges)
+      && (temp_angle = p2tr_edge_angle_between (current->mirror, next)) <= P2TR_CLUSTER_LIMIT_ANGLE
+      && p2tr_cluster_cw_tri_between_is_in_domain (next, current))
+    {
+      g_queue_push_head (&cluster->edges, p2tr_edge_ref (next));
+      current = next;
+      next = p2tr_point_edge_ccw (P, current);
+      cluster->min_angle = MIN(cluster->min_angle, temp_angle);
+    }
+
+  return cluster;
+}
+
+/*     ^ e1
+ *    /
+ *   /_ e1.Tri (e2.Mirror.Tri)
+ *  /  |
+ * *---------> e2
+ *
+ * Check if the angle marked is a part of the triangulation
+ * domain
+ */
+static gboolean
+p2tr_cluster_cw_tri_between_is_in_domain (P2trEdge *e1, P2trEdge *e2)
+{
+  if (P2TR_EDGE_START(e1) != P2TR_EDGE_START(e2) || e1->tri != e2->mirror->tri)
+    p2tr_exception_programmatic ("Non clockwise adjacent edges!");
+  return e1->tri != NULL;
+}
+
+void
+p2tr_cluster_free (P2trCluster *self)
+{
+  GList *iter;
+  
+  for (iter = self->edges.head; iter != NULL; iter = iter->next)
+    p2tr_edge_unref ((P2trEdge*)iter->data);
+
+  g_queue_clear (&self->edges);
+  g_slice_free (P2trCluster, self);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/cluster.h b/libs/poly2tri-c/poly2tri-c/refine/cluster.h
new file mode 100644
index 0000000..6eaed8a
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/cluster.h
@@ -0,0 +1,55 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_CLUSTER_H__
+#define __P2TC_REFINE_CLUSTER_H__
+
+#include <glib.h>
+#include "point.h"
+#include "edge.h"
+
+#define P2TR_CLUSTER_LIMIT_ANGLE (G_PI / 6)
+
+typedef struct
+{
+  GQueue   edges;
+  gdouble  min_angle;
+} P2trCluster;
+
+P2trCluster*  p2tr_cluster_get_for              (P2trPoint *P,
+                                                 P2trEdge  *E);
+
+gdouble       p2tr_cluster_shortest_edge_length (P2trCluster *self);
+
+void          p2tr_cluster_free                 (P2trCluster *self);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/delaunay-terminator.c b/libs/poly2tri-c/poly2tri-c/refine/delaunay-terminator.c
new file mode 100644
index 0000000..48ff030
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/delaunay-terminator.c
@@ -0,0 +1,529 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <glib.h>
+
+#include "utils.h"
+#include "rmath.h"
+
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+
+#include "mesh.h"
+#include "cdt.h"
+#include "cluster.h"
+
+#include "vedge.h"
+#include "vtriangle.h"
+
+#include "delaunay-terminator.h"
+
+/* The code in this file is based on the "Delaunay Terminator" algorithm
+ * - an algorithm for refining constrained delaunay triangulations. The
+ * algorithm itself appears in a paper by Jonathan Richard Shewchuk as
+ * described below:
+ *
+ *   Delaunay Refinement Algorithms for Triangular Mesh Generation
+ *   Computational Geometry: Theory and Applications 22(1â3):21â74, May 2002
+ *   Jonathan Richard Shewchuk
+ *   http://www.cs.berkeley.edu/~jrs/papers/2dj.pdf
+ */
+
+gboolean
+p2tr_cdt_test_encroachment_ignore_visibility (const P2trVector2 *w,
+                                              P2trEdge          *e)
+{
+  return p2tr_math_diametral_circle_contains (&P2TR_EDGE_START(e)->c,
+      &e->end->c, w);
+}
+
+gboolean
+p2tr_cdt_is_encroached_by (P2trCDT     *self,
+                           P2trEdge    *e,
+                           P2trVector2 *p)
+{
+  if (! e->constrained)
+      return FALSE;
+
+  return p2tr_cdt_test_encroachment_ignore_visibility (p, e)
+      && p2tr_cdt_visible_from_edge (self, e, p);
+}
+
+
+P2trVEdgeSet*
+p2tr_cdt_get_segments_encroached_by (P2trCDT   *self,
+                                     P2trPoint *v)
+{
+  P2trVEdgeSet *encroached = p2tr_vedge_set_new ();
+  GList *iter;
+
+  for (iter = v->outgoing_edges; iter != NULL; iter = iter->next)
+    {
+      P2trEdge *outEdge = (P2trEdge*) iter->data;
+      P2trTriangle *t = outEdge->tri;
+      P2trEdge *e;
+
+      if (t == NULL)
+          continue;
+
+      e = p2tr_triangle_get_opposite_edge (t, v);
+
+      /* we want the fast check and for new points we don't
+       * use that check... So let's go on the full check
+       * since it's still faster */
+      if (e->constrained && p2tr_cdt_is_encroached (e))
+        p2tr_vedge_set_add2 (encroached, p2tr_vedge_new2 (e));
+    }
+
+  return encroached;
+}
+
+gboolean
+p2tr_cdt_is_encroached (P2trEdge *E)
+{
+  P2trTriangle *T1 = E->tri;
+  P2trTriangle *T2 = E->mirror->tri;
+
+  if (! E->constrained)
+      return FALSE;
+  
+  return (T1 != NULL && p2tr_cdt_test_encroachment_ignore_visibility (&p2tr_triangle_get_opposite_point (T1, E, FALSE)->c, E))
+      || (T2 != NULL && p2tr_cdt_test_encroachment_ignore_visibility (&p2tr_triangle_get_opposite_point (T2, E, FALSE)->c, E));
+}
+
+/* ****************************************************************** */
+/* Now for the algorithm itself                                       */
+/* ****************************************************************** */
+
+static gboolean
+SplitPermitted (P2trDelaunayTerminator *self, P2trEdge *s, gdouble d);
+
+static void
+SplitEncroachedSubsegments (P2trDelaunayTerminator *self, gdouble theta, P2trTriangleTooBig delta);
+
+static void
+NewVertex (P2trDelaunayTerminator *self, P2trPoint *v, gdouble theta, P2trTriangleTooBig delta);
+
+static gdouble
+ShortestEdgeLength (P2trTriangle *tri);
+
+static gboolean
+TolerantIsShorter (P2trEdge *toTest, P2trEdge *reference);
+
+static inline gdouble
+LOG2 (gdouble v);
+
+static gboolean
+TolerantIsPowerOfTwoLength (gdouble length);
+
+static void
+ChooseSplitVertex(P2trEdge *e, P2trVector2 *dst);
+
+
+
+static inline gint
+vtriangle_quality_compare (P2trVTriangle *t1, P2trVTriangle *t2)
+{
+  gdouble a1, a2;
+  P2trTriangle *r1, *r2;
+
+  r1 = p2tr_vtriangle_is_real (t1);
+  r2 = p2tr_vtriangle_is_real (t2);
+
+  /* TODO: untill we make sure that removed triangles will get out
+   * of Qt, we will make the comparision treat removed triangles as
+   * triangles with "less" quality (meaning they are "smaller")
+   */
+  if (!r1 || !r2)
+    return (!r1) ? -1 : (!r2 ? 1 : 0);
+
+  a1 = p2tr_triangle_smallest_non_constrained_angle (r1);
+  a2 = p2tr_triangle_smallest_non_constrained_angle (r2);
+  
+  return (a1 < a2) ? -1 : ((a1 == a2) ? 0 : 1);
+}
+
+P2trDelaunayTerminator*
+p2tr_dt_new (gdouble theta, P2trTriangleTooBig delta, P2trCDT *cdt)
+{
+  P2trDelaunayTerminator *self = g_slice_new (P2trDelaunayTerminator);
+  self->Qt = g_sequence_new (NULL);
+  g_queue_init (&self->Qs);
+  self->delta = delta;
+  self->theta = theta;
+  self->cdt = cdt;
+  return self;
+}
+
+void
+p2tr_dt_free (P2trDelaunayTerminator *self)
+{
+  g_queue_clear (&self->Qs);
+  g_sequence_free (self->Qt);
+  g_slice_free (P2trDelaunayTerminator, self);
+}
+
+static void
+p2tr_dt_enqueue_tri (P2trDelaunayTerminator *self,
+                     P2trTriangle           *tri)
+{
+  g_sequence_insert_sorted (self->Qt, p2tr_vtriangle_new (tri), (GCompareDataFunc)vtriangle_quality_compare, NULL);
+}
+
+static inline gboolean
+p2tr_dt_tri_queue_is_empty (P2trDelaunayTerminator *self)
+{
+  return g_sequence_iter_is_end (g_sequence_get_begin_iter (self->Qt));
+}
+
+static P2trVTriangle*
+p2tr_dt_dequeue_tri (P2trDelaunayTerminator *self)
+{
+  GSequenceIter *first = g_sequence_get_begin_iter (self->Qt);
+
+  /* If we have an empty sequence, return NULL */
+  if (p2tr_dt_tri_queue_is_empty (self))
+    return NULL;
+  else
+    {
+      P2trVTriangle *ret = (P2trVTriangle*) g_sequence_get (first);
+      g_sequence_remove (first);
+      return ret;
+    }
+}
+
+static void
+p2tr_dt_enqueue_segment (P2trDelaunayTerminator *self,
+                         P2trEdge               *E)
+{
+  if (! E->constrained)
+    p2tr_exception_programmatic ("Tried to append a non-segment!");
+
+  g_queue_push_tail (&self->Qs, p2tr_edge_ref (E));
+}
+
+static P2trEdge*
+p2tr_dt_dequeue_segment (P2trDelaunayTerminator *self)
+{
+  if (g_queue_is_empty (&self->Qs))
+    return NULL;
+  else
+    return (P2trEdge*) g_queue_pop_head (&self->Qs);
+}
+
+static gboolean
+p2tr_dt_segment_queue_is_empty (P2trDelaunayTerminator *self)
+{
+  return g_queue_is_empty (&self->Qs);
+}
+
+void
+p2tr_dt_refine (P2trDelaunayTerminator   *self,
+                gint                      max_steps,
+                P2trRefineProgressNotify  on_progress)
+{
+  P2trHashSetIter hs_iter;
+  P2trEdge *s;
+  P2trTriangle *t;
+  P2trVTriangle *vt;
+  gint steps = 0;
+
+  P2TR_CDT_VALIDATE_CDT (self->cdt);
+
+  if (steps++ >= max_steps)
+    return;
+
+  p2tr_hash_set_iter_init (&hs_iter, self->cdt->mesh->edges);
+    while (p2tr_hash_set_iter_next (&hs_iter, (gpointer*)&s))
+    if (s->constrained && p2tr_cdt_is_encroached (s))
+      p2tr_dt_enqueue_segment (self, s);
+
+  SplitEncroachedSubsegments (self, 0, p2tr_refiner_false_too_big);
+  P2TR_CDT_VALIDATE_CDT (self->cdt);
+
+  p2tr_hash_set_iter_init (&hs_iter, self->cdt->mesh->triangles);
+  while (p2tr_hash_set_iter_next (&hs_iter, (gpointer*)&t))
+    if (p2tr_triangle_smallest_non_constrained_angle (t) < self->theta)
+      p2tr_dt_enqueue_tri (self, t);
+
+  if (on_progress != NULL) on_progress ((P2trRefiner*) self, steps, max_steps);
+
+  while (! p2tr_dt_tri_queue_is_empty (self))
+    {
+      vt = p2tr_dt_dequeue_tri (self);
+      t = p2tr_vtriangle_is_real (vt);
+
+      if (t && steps++ < max_steps)
+        {
+          P2trCircle tCircum;
+          P2trVector2 *c;
+          P2trTriangle *triContaining_c;
+          P2trVEdgeSet *E;
+          P2trPoint *cPoint;
+
+          P2TR_CDT_VALIDATE_CDT (self->cdt);
+          p2tr_triangle_get_circum_circle (t, &tCircum);
+          c = &tCircum.center;
+
+          triContaining_c = p2tr_mesh_find_point_local (self->cdt->mesh, c, t);
+
+          /* If no edge is encroached, then this must be
+           * inside the triangulation domain!!! */
+          if (triContaining_c == NULL)
+            p2tr_exception_geometric ("Should not happen! (%f, %f) (Center of (%f,%f)->(%f,%f)->(%f,%f)) is outside the domain!", c->x, c->y,
+            vt->points[0]->c.x, vt->points[0]->c.y,
+            vt->points[1]->c.x, vt->points[1]->c.y,
+            vt->points[2]->c.x, vt->points[2]->c.y);
+
+          /* Now, check if this point would encroach any edge
+           * of the triangulation */
+          p2tr_mesh_action_group_begin (self->cdt->mesh);
+
+          cPoint = p2tr_cdt_insert_point (self->cdt, c, triContaining_c);
+          E = p2tr_cdt_get_segments_encroached_by (self->cdt, cPoint);
+
+          if (p2tr_vedge_set_size (E) == 0)
+            {
+              p2tr_mesh_action_group_commit (self->cdt->mesh);
+              NewVertex (self, cPoint, self->theta, self->delta);
+            }
+          else
+            {
+              P2trVEdge *vSegment;
+              gdouble d;
+
+              p2tr_mesh_action_group_undo (self->cdt->mesh);
+              /* The (reverted) changes to the mesh may have eliminated the
+               * original triangle t. We must restore it manually from
+               * the virtual triangle
+               */
+              t = p2tr_vtriangle_is_real (vt);
+              g_assert (t != NULL);
+
+              d = ShortestEdgeLength (t);
+
+              while (p2tr_vedge_set_pop (E, &vSegment))
+                {
+                  s = p2tr_vedge_get (vSegment);
+                  if (self->delta (t) || SplitPermitted(self, s, d))
+                    p2tr_dt_enqueue_segment (self, s);
+                  p2tr_edge_unref (s);
+                  p2tr_vedge_unref (vSegment);
+                }
+
+              if (! p2tr_dt_segment_queue_is_empty (self))
+                {
+                  p2tr_dt_enqueue_tri (self, t);
+                  SplitEncroachedSubsegments(self, self->theta, self->delta);
+                }
+            }
+
+          p2tr_vedge_set_free (E);
+          p2tr_point_unref (cPoint);
+          p2tr_triangle_unref (triContaining_c);
+      }
+
+      p2tr_vtriangle_unref (vt);
+
+      if (on_progress != NULL) on_progress ((P2trRefiner*) self, steps, max_steps);
+    }
+}
+
+static gboolean
+SplitPermitted (P2trDelaunayTerminator *self, P2trEdge *s, gdouble d)
+{
+  P2trCluster *startCluster = p2tr_cluster_get_for (P2TR_EDGE_START(s), s);
+  P2trCluster *endCluster =   p2tr_cluster_get_for (s->end, s);
+  P2trCluster *S_NOREF;
+  GList *iter;
+  
+  gboolean permitted = FALSE;
+  
+  if (! TolerantIsPowerOfTwoLength (p2tr_edge_get_length (s))
+      /* True when different, meaning both null or both exist */
+      || ((startCluster != NULL) ^ (endCluster == NULL)))
+    {
+      permitted = TRUE;
+    }
+  
+  if (! permitted)
+    {
+      S_NOREF = (startCluster != NULL) ? startCluster : endCluster;
+
+      for (iter = g_queue_peek_head_link (&S_NOREF->edges); iter != NULL; iter = iter->next)
+        if (TolerantIsShorter((P2trEdge*) iter->data, s)) /* e shorter than s */
+          {
+            permitted = TRUE;
+            break;
+          }
+    }
+  
+  if (! permitted)
+    {
+      gdouble rmin = p2tr_edge_get_length(s) * sin(S_NOREF->min_angle / 2);
+      if (rmin >= d)
+        permitted = TRUE;
+    }
+
+  if (startCluster) p2tr_cluster_free (startCluster);
+  if (endCluster) p2tr_cluster_free (endCluster);
+
+  return permitted;
+}
+
+static void
+SplitEncroachedSubsegments (P2trDelaunayTerminator *self, gdouble theta, P2trTriangleTooBig delta)
+{
+  while (! p2tr_dt_segment_queue_is_empty (self))
+  {
+    P2trEdge *s = p2tr_dt_dequeue_segment (self);
+    if (p2tr_hash_set_contains (self->cdt->mesh->edges, s))
+      {
+        P2trVector2 v;
+        P2trPoint *Pv;
+        GList *parts, *iter;
+
+        ChooseSplitVertex (s, &v);
+        Pv = p2tr_mesh_new_point (self->cdt->mesh, &v);
+        
+        /* Update here if using diametral lenses */
+
+        parts = p2tr_cdt_split_edge (self->cdt, s, Pv);
+        
+        NewVertex (self, Pv, theta, delta);
+
+        for (iter = parts; iter != NULL; iter = iter->next)
+          {
+            P2trEdge *e = (P2trEdge*)iter->data;
+            if (p2tr_cdt_is_encroached (e))
+              p2tr_dt_enqueue_segment (self, e);
+            p2tr_edge_unref (e);
+          }
+      }
+    p2tr_edge_unref (s);
+  }
+}
+
+static void
+NewVertex (P2trDelaunayTerminator *self, P2trPoint *v, gdouble theta, P2trTriangleTooBig delta)
+{
+  GList *iter;
+  for (iter = v->outgoing_edges; iter != NULL; iter = iter->next)
+    {
+      P2trEdge *outEdge = (P2trEdge*) iter->data;
+      P2trTriangle *t = outEdge->tri;
+      P2trEdge *e;
+      
+      if (t == NULL)
+          continue;
+
+      e = p2tr_triangle_get_opposite_edge (t, v);
+      
+      /* we want the fast check and for new points we don't
+       * use that check... So let's go on the full check
+       * since it's still faster */
+      if (e->constrained && p2tr_cdt_is_encroached (e))
+        p2tr_dt_enqueue_segment (self, e);
+      else if (delta (t) || p2tr_triangle_smallest_non_constrained_angle (t) < theta)
+        p2tr_dt_enqueue_tri (self, t);
+
+      p2tr_edge_unref (e);
+    }
+}
+
+static gdouble
+ShortestEdgeLength (P2trTriangle *tri)
+{
+  gdouble a1 = p2tr_edge_get_length_squared (tri->edges[0]);
+  gdouble a2 = p2tr_edge_get_length_squared (tri->edges[1]);
+  gdouble a3 = p2tr_edge_get_length_squared (tri->edges[2]);
+  
+  return sqrt (MIN (a1, MIN (a2, a3)));
+}
+
+static gboolean
+TolerantIsShorter (P2trEdge *toTest, P2trEdge *reference)
+{
+  return p2tr_edge_get_length(toTest) < p2tr_edge_get_length(reference) * 1.01;
+}
+
+static inline gdouble
+LOG2 (gdouble v)
+{
+  return log10 (v) / G_LOG_2_BASE_10;
+}
+
+static gboolean
+TolerantIsPowerOfTwoLength (gdouble length)
+{
+  gdouble exp = LOG2 (length);
+  gdouble intpart, frac = modf (exp, &intpart);
+  gdouble distance;
+
+  /* If the length is a negative power of 2, the returned fraction will be
+   * negative */
+  frac = ABS(frac);
+
+  /* Find how close is exp to the closest integer */
+  distance = MIN(frac, 1-frac);
+
+  return distance < 0.05;
+}
+
+static void
+ChooseSplitVertex(P2trEdge *e, P2trVector2 *dst)
+{
+  gdouble sourceLength = p2tr_edge_get_length(e);
+  gdouble newLengthFloor = pow(2, floor(LOG2(sourceLength)));
+  gdouble newLengthCeil = newLengthFloor * 2;
+  gdouble newLength =
+      (sourceLength - newLengthFloor < newLengthCeil - sourceLength)
+      ? newLengthFloor : newLengthCeil;
+  gdouble ratio, resultLength;
+  
+  /* IMPORTANT! DIVIDE BY 2! */
+  newLength /= 2;
+
+  ratio = newLength / sourceLength;
+
+  dst->x = (1 - ratio) * P2TR_EDGE_START(e)->c.x + (ratio) * e->end->c.x;
+  dst->y = (1 - ratio) * P2TR_EDGE_START(e)->c.y + (ratio) * e->end->c.y;
+
+  /* now let's avoid consistency problems */
+  resultLength = sqrt(P2TR_VECTOR2_DISTANCE_SQ(&P2TR_EDGE_START(e)->c, dst));
+  
+  if (! TolerantIsPowerOfTwoLength(resultLength))
+    p2tr_exception_numeric ("Bad rounding!");
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/delaunay-terminator.h b/libs/poly2tri-c/poly2tri-c/refine/delaunay-terminator.h
new file mode 100644
index 0000000..fe0ef5d
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/delaunay-terminator.h
@@ -0,0 +1,71 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_DELAUNAY_TERMINATOR_H__
+#define __P2TC_REFINE_DELAUNAY_TERMINATOR_H__
+
+#include <glib.h>
+#include "cdt.h"
+#include "refiner.h"
+#include "vedge.h"
+
+typedef struct
+{
+  P2trCDT            *cdt;
+  GQueue              Qs;
+  GSequence          *Qt;
+  gdouble             theta;
+  P2trTriangleTooBig  delta;
+} P2trDelaunayTerminator;
+
+gboolean  p2tr_cdt_test_encroachment_ignore_visibility (const P2trVector2 *w,
+                                                        P2trEdge          *e);
+
+gboolean  p2tr_cdt_is_encroached_by (P2trCDT     *self,
+                                     P2trEdge    *e,
+                                     P2trVector2 *p);
+
+P2trVEdgeSet*  p2tr_cdt_get_segments_encroached_by (P2trCDT   *self,
+                                                    P2trPoint *v);
+
+gboolean      p2tr_cdt_is_encroached (P2trEdge *E);
+
+P2trDelaunayTerminator*
+p2tr_dt_new (gdouble theta, P2trTriangleTooBig delta, P2trCDT *cdt);
+
+void p2tr_dt_free (P2trDelaunayTerminator *self);
+
+void p2tr_dt_refine (P2trDelaunayTerminator   *self,
+                     gint                      max_steps,
+                     P2trRefineProgressNotify  on_progress);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/edge.c b/libs/poly2tri-c/poly2tri-c/refine/edge.c
new file mode 100644
index 0000000..a95a6ee
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/edge.c
@@ -0,0 +1,247 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include <glib.h>
+
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+#include "mesh.h"
+
+static void
+p2tr_edge_init (P2trEdge  *self,
+                P2trPoint *start,
+                P2trPoint *end,
+                gboolean   constrained,
+                P2trEdge  *mirror)
+{
+  self->angle       = atan2 (end->c.y - start->c.y,
+                          end->c.x - start->c.x);
+  self->constrained = constrained;
+  self->delaunay    = FALSE;
+  self->end         = end;
+  self->mirror      = mirror;
+  self->refcount    = 0;
+  self->tri         = NULL;
+}
+
+P2trEdge*
+p2tr_edge_new (P2trPoint *start,
+               P2trPoint *end,
+               gboolean   constrained)
+{
+  P2trEdge *self   = g_slice_new (P2trEdge);
+  P2trEdge *mirror = g_slice_new (P2trEdge);
+
+  p2tr_edge_init (self, start, end, constrained, mirror);
+  p2tr_edge_init (mirror, end, start, constrained, self);
+
+  p2tr_point_ref (start);
+  p2tr_point_ref (end);
+  
+  _p2tr_point_insert_edge (start, self);
+  _p2tr_point_insert_edge (end,   mirror);
+
+  return p2tr_edge_ref (self);
+}
+
+P2trEdge*
+p2tr_edge_ref (P2trEdge *self)
+{
+  ++self->refcount;
+  return self;
+}
+
+void
+p2tr_edge_unref (P2trEdge *self)
+{
+  g_assert (self->refcount > 0);
+  if (--self->refcount == 0 && self->mirror->refcount == 0)
+    p2tr_edge_free (self);
+}
+
+gboolean
+p2tr_edge_is_removed (P2trEdge *self)
+{
+  return self->end == NULL; /* This is only true if the edge was removed */
+}
+
+void
+p2tr_edge_remove (P2trEdge *self)
+{
+  P2trMesh *mesh;
+  P2trPoint *start, *end;
+
+  if (p2tr_edge_is_removed (self))
+    return;
+
+  mesh = p2tr_edge_get_mesh (self);
+
+  start = P2TR_EDGE_START(self);
+  end = self->end;
+
+  if (self->tri != NULL)
+    p2tr_triangle_remove (self->tri);
+  if (self->mirror->tri != NULL)
+    p2tr_triangle_remove (self->mirror->tri);
+
+  if (mesh != NULL)
+    {
+      p2tr_mesh_on_edge_removed (mesh, self);
+      p2tr_mesh_unref (mesh); /* The get function reffed it */
+    }
+
+  /* Warning - the code here is not that trivial!
+   * Assuming we would now want to remove `self' and `self->mirror' from
+   * `start' and `end'. If both have exactly one reference, then after
+   * removing the second, the edge struct will be freed before we can
+   * mark it as removed by setting the end points to be NULL! (Marking
+   * it as removed in that case, will be an access to unallocated
+   * memory).
+   * To solve this, we will hold a "ghost" reference to `self' to
+   * prevent freeing from happening until we are done modifying the
+   * struct.
+   */
+   p2tr_edge_ref (self);
+
+  _p2tr_point_remove_edge(start, self);
+  _p2tr_point_remove_edge(end, self->mirror);
+
+  self->end = NULL;
+  self->mirror->end = NULL;
+
+  /* Now release the "ghost" reference */
+  p2tr_edge_unref (self);
+
+  p2tr_point_unref (start);
+  p2tr_point_unref (end);
+}
+
+void
+p2tr_edge_free (P2trEdge *self)
+{
+  g_assert (p2tr_edge_is_removed (self));
+  g_slice_free (P2trEdge, self->mirror);
+  g_slice_free (P2trEdge, self);
+}
+
+void
+p2tr_edge_get_diametral_circle (P2trEdge   *self,
+                                P2trCircle *circle)
+{
+  P2trVector2 radius;
+  
+  p2tr_vector2_center (&self->end->c, &P2TR_EDGE_START(self)->c, &circle->center);
+  p2tr_vector2_sub (&self->end->c, &circle->center, &radius);
+
+  circle->radius = p2tr_vector2_norm (&radius);
+}
+
+P2trMesh*
+p2tr_edge_get_mesh (P2trEdge *self)
+{
+  if (self->end != NULL)
+    return p2tr_point_get_mesh (self->end);
+  else
+    return NULL;
+}
+
+gdouble
+p2tr_edge_get_length (P2trEdge* self)
+{
+  return sqrt (p2tr_math_length_sq2 (&self->end->c, &P2TR_EDGE_START(self)->c));
+}
+
+gdouble
+p2tr_edge_get_length_squared (P2trEdge* self)
+{
+  return p2tr_math_length_sq2 (&self->end->c, &P2TR_EDGE_START(self)->c);
+}
+
+gdouble
+p2tr_edge_angle_between (P2trEdge *e1,
+                         P2trEdge *e2)
+{
+  /* A = E1.angle, a = abs (A)
+   * B = E1.angle, b = abs (B)
+   *
+   * W is the angle we wish to find. Note the fact that we want
+   * to find the angle so that the edges go CLOCKWISE around it.
+   *
+   * Case 1: Signs of A and B agree | Case 2: Signs of A and B disagree
+   *         and A > 0              |         and A > 0
+   *                                |
+   * a = A, b = B                   | a = A, b = -B
+   *             ^^                 |
+   *         E2 //                  |           /
+   *           //\                  |          /
+   *          //b|                  |         /a
+   * - - - - * - |W- - - - - - - -  | - - - - * - - - - 
+   *         ^^a'|                  |       ^^ \\b
+   *         ||_/                   |      // W \\
+   *      E1 ||\                    |  E1 // \_/ \\ E2
+   *        '||a\                   |    //       \\
+   *     - - - - - -                |   //         vv
+   *                                |
+   * W = A' + B = (180 - A) + B     | W = 180 - (a + b) = 180 - (A - B) 
+   * W = 180 - A + B                | W = 180 - A + B
+   * 
+   * By the illustration above, we can see that in general the angle W
+   * can be computed by W = 180 - A + B in every case. The only thing to
+   * note is that the range of the result of the computation is
+   * [180 - 360, 180 + 360] = [-180, +540] so we may need to subtract
+   * 360 to put it back in the range [-180, +180].
+   */
+  gdouble result;
+  
+  if (e1->end != P2TR_EDGE_START(e2))
+    p2tr_exception_programmatic ("The end-point of the first edge isn't"
+        " the end-point of the second edge!");
+
+  result = G_PI - e1->angle + e2->angle;
+  if (result > 2 * G_PI)
+      result -= 2 * G_PI;
+
+  return result;
+}
+
+gdouble
+p2tr_edge_angle_between_positive (P2trEdge *e1,
+                                  P2trEdge *e2)
+{
+  gdouble result = p2tr_edge_angle_between (e1, e2);
+  if (result < 0)
+    return result + 2 * G_PI;
+  else
+    return result;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/edge.h b/libs/poly2tri-c/poly2tri-c/refine/edge.h
new file mode 100644
index 0000000..4e44c44
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/edge.h
@@ -0,0 +1,104 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_EDGE_H__
+#define __P2TC_REFINE_EDGE_H__
+
+#include <glib.h>
+#include "circle.h"
+#include "triangulation.h"
+
+/**
+ * @struct P2trEdge_
+ * A struct for an edge in a triangular mesh
+ */
+struct P2trEdge_
+{
+  /** The end point of this mesh */
+  P2trPoint    *end;
+
+  /** The edge going in the opposite direction from this edge */
+  P2trEdge     *mirror;
+  
+  /** Is this a constrained edge? */
+  gboolean      constrained;
+  
+  /** The triangle where this edge goes clockwise along its outline */
+  P2trTriangle *tri;
+
+  /**
+   * The angle of the direction of this edge. Although it can be
+   * computed anytime using atan2 on the vector of this edge, we cache
+   * it here since it's heavily used and the computation is expensive.
+   * The angle increases as we go CCW, and it's in the range [-PI,+PI]
+   */
+  gdouble       angle;
+  
+  /**
+   * Is this edge a delaunay edge? This field is used by the refinement
+   * algorithm and should not be used elsewhere!
+   */
+  gboolean      delaunay;
+
+  /** A count of references to the edge */
+  guint         refcount;
+};
+
+#define P2TR_EDGE_START(E) ((E)->mirror->end)
+
+P2trEdge*   p2tr_edge_new                  (P2trPoint *start,
+                                            P2trPoint *end,
+                                            gboolean   constrained);
+
+P2trEdge*   p2tr_edge_ref                  (P2trEdge *self);
+
+void        p2tr_edge_unref                (P2trEdge *self);
+
+void        p2tr_edge_free                 (P2trEdge *self);
+
+void        p2tr_edge_remove               (P2trEdge *self);
+
+P2trMesh*   p2tr_edge_get_mesh             (P2trEdge *self);
+
+gboolean    p2tr_edge_is_removed           (P2trEdge *self);
+
+gdouble     p2tr_edge_get_length           (P2trEdge* self);
+
+gdouble     p2tr_edge_get_length_squared   (P2trEdge* self);
+
+gdouble     p2tr_edge_angle_between        (P2trEdge *e1,
+                                            P2trEdge *e2);
+
+gdouble     p2tr_edge_angle_between_positive (P2trEdge *e1,
+                                              P2trEdge *e2);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/line.c b/libs/poly2tri-c/poly2tri-c/refine/line.c
new file mode 100644
index 0000000..d2e0ccf
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/line.c
@@ -0,0 +1,102 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include "line.h"
+
+void
+p2tr_line_init (P2trLine    *line,
+                gdouble      a,
+                gdouble      b,
+                gdouble      c)
+{
+  line->a = a;
+  line->b = b;
+  line->c = c;
+}
+
+gboolean
+p2tr_line_different_sides (const P2trLine    *line,
+                           const P2trVector2 *pt1,
+                           const P2trVector2 *pt2)
+{
+  gdouble side1 = line->a * pt1->x + line->b * pt1->y + line->c;
+  gdouble side2 = line->a * pt2->x + line->b * pt2->y + line->c;
+
+  /* Signs are different if the product is negative */
+  return side1 * side2 < 0;
+}
+
+P2trLineRelation
+p2tr_line_intersection (const P2trLine    *l1,
+                        const P2trLine    *l2,
+                        P2trVector2       *out_intersection)
+{
+  /* In order to find the intersection, we intend to solve
+   * the following set of equations:
+   *
+   *   ( A1 B1 ) ( x ) = ( -C1 )
+   *   ( A2 B2 ) ( y ) = ( -C2 )
+   *
+   * We can simplify the solution using Cramers Rule which
+   * gives the following results:
+   *
+   *   x = (-C1 * B2) - (-C2 * B1) / (A1 * B2 - A2 * B1)
+   *   y = (A1 * -C2) - (A2 * -C1) / (A1 * B2 - A2 * B1)
+   */
+  double d = l1->a * l2->b - l2->a * l1->b;
+
+  /* If the denominator in the result of applying Cramers rule
+   * is zero, then the lines have exactly the same slope, meaning
+   * they are either exactly the same or they are parallel and
+   * never intersect */
+  if (d == 0)
+    {
+      /* We want to check if the offsets of boths the lines are the
+       * same, i.e. whether:  C1 / A1 = C2 / A2
+       * This test can be done without zero division errors if we do
+       * it in like this:     C1 * A2 = C2 * A1
+       */
+      if (l1->c * l2->a == l1->a * l2->c)
+        return P2TR_LINE_RELATION_SAME;
+      else
+        return P2TR_LINE_RELATION_PARALLEL;
+    }
+
+  if (out_intersection != NULL)
+    {
+      out_intersection->x = (-l1->c * l2->b + l2->c * l1->b) / d;
+      out_intersection->y = (l1->a * -l2->c + l2->a * l1->c) / d;
+    }
+
+  return P2TR_LINE_RELATION_INTERSECTING;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/line.h b/libs/poly2tri-c/poly2tri-c/refine/line.h
new file mode 100644
index 0000000..a72813b
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/line.h
@@ -0,0 +1,66 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_LINE_H__
+#define __P2TC_REFINE_LINE_H__
+
+#include <glib.h>
+#include "vector2.h"
+
+/* A line is the equation of the following form:
+ *   a * X + b * Y + c = 0
+ */
+typedef struct {
+  gdouble a, b, c;
+} P2trLine;
+
+typedef enum
+{
+  P2TR_LINE_RELATION_INTERSECTING = 0,
+  P2TR_LINE_RELATION_PARALLEL = 1,
+  P2TR_LINE_RELATION_SAME = 2
+} P2trLineRelation;
+
+void              p2tr_line_init            (P2trLine    *line,
+                                             gdouble      a,
+                                             gdouble      b,
+                                             gdouble      c);
+
+gboolean          p2tr_line_different_sides (const P2trLine    *line,
+                                             const P2trVector2 *pt1,
+                                             const P2trVector2 *pt2);
+
+P2trLineRelation  p2tr_line_intersection    (const P2trLine    *l1,
+                                             const P2trLine    *l2,
+                                             P2trVector2       *out_intersection);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/mesh-action.c b/libs/poly2tri-c/poly2tri-c/refine/mesh-action.c
new file mode 100644
index 0000000..c2ffd9c
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/mesh-action.c
@@ -0,0 +1,228 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include "point.h"
+#include "edge.h"
+#include "mesh.h"
+#include "vedge.h"
+#include "vtriangle.h"
+#include "mesh-action.h"
+
+static P2trMeshAction*
+p2tr_mesh_action_point (P2trPoint *point,
+                        gboolean   added)
+{
+  P2trMeshAction *self = g_slice_new (P2trMeshAction);
+  self->type = P2TR_MESH_ACTION_POINT;
+  self->added = added;
+  self->refcount = 1;
+  self->action.action_point.point = p2tr_point_ref (point);
+  return self;
+}
+
+static void
+p2tr_mesh_action_point_free (P2trMeshAction *self)
+{
+  g_assert (self->type == P2TR_MESH_ACTION_POINT);
+  p2tr_point_unref (self->action.action_point.point);
+  g_slice_free (P2trMeshAction, self);
+}
+
+static void
+p2tr_mesh_action_point_undo (P2trMeshAction *self,
+                             P2trMesh       *mesh)
+{
+  g_assert (self->type == P2TR_MESH_ACTION_POINT);
+  if (self->added)
+    p2tr_point_remove (self->action.action_point.point);
+  else
+    p2tr_mesh_add_point (mesh, self->action.action_point.point);
+}
+
+P2trMeshAction*
+p2tr_mesh_action_new_point (P2trPoint *point)
+{
+  return p2tr_mesh_action_point (point, TRUE);
+}
+
+P2trMeshAction*
+p2tr_mesh_action_del_point (P2trPoint *point)
+{
+  return p2tr_mesh_action_point (point, FALSE);
+}
+
+static P2trMeshAction*
+p2tr_mesh_action_edge (P2trEdge *edge,
+                       gboolean  added)
+{
+  P2trMeshAction *self = g_slice_new (P2trMeshAction);
+  self->type = P2TR_MESH_ACTION_EDGE;
+  self->added = added;
+  self->refcount = 1;
+  self->action.action_edge.vedge = p2tr_vedge_new2 (edge);
+  self->action.action_edge.constrained = edge->constrained;
+  return self;
+}
+
+static void
+p2tr_mesh_action_edge_free (P2trMeshAction *self)
+{
+  g_assert (self->type == P2TR_MESH_ACTION_EDGE);
+  p2tr_vedge_unref (self->action.action_edge.vedge);
+  g_slice_free (P2trMeshAction, self);
+}
+
+static void
+p2tr_mesh_action_edge_undo (P2trMeshAction *self,
+                            P2trMesh       *mesh)
+{
+  g_assert (self->type == P2TR_MESH_ACTION_EDGE);
+
+  if (self->added)
+    p2tr_vedge_remove (self->action.action_edge.vedge);
+  else
+    p2tr_vedge_create (self->action.action_edge.vedge);
+}
+
+P2trMeshAction*
+p2tr_mesh_action_new_edge (P2trEdge *edge)
+{
+  return p2tr_mesh_action_edge (edge, TRUE);
+}
+
+P2trMeshAction*
+p2tr_mesh_action_del_edge (P2trEdge *edge)
+{
+  return p2tr_mesh_action_edge (edge, FALSE);
+}
+
+static P2trMeshAction*
+p2tr_mesh_action_triangle (P2trTriangle *tri,
+                           gboolean      added)
+{
+  P2trMeshAction *self = g_slice_new (P2trMeshAction);
+  self->type = P2TR_MESH_ACTION_TRIANGLE;
+  self->added = added;
+  self->refcount = 1;
+  self->action.action_tri.vtri = p2tr_vtriangle_new (tri);
+  return self;
+}
+
+static void
+p2tr_mesh_action_triangle_free (P2trMeshAction *self)
+{
+  g_assert (self->type == P2TR_MESH_ACTION_TRIANGLE);
+  p2tr_vtriangle_unref (self->action.action_tri.vtri);
+  g_slice_free (P2trMeshAction, self);
+}
+
+static void
+p2tr_mesh_action_triangle_undo (P2trMeshAction *self,
+                                P2trMesh       *mesh)
+{
+  g_assert (self->type == P2TR_MESH_ACTION_TRIANGLE);
+
+  if (self->added)
+    p2tr_vtriangle_remove (self->action.action_tri.vtri);
+  else
+    p2tr_vtriangle_create (self->action.action_tri.vtri);
+}
+
+P2trMeshAction*
+p2tr_mesh_action_new_triangle (P2trTriangle *tri)
+{
+  return p2tr_mesh_action_triangle (tri, TRUE);
+}
+
+P2trMeshAction*
+p2tr_mesh_action_del_triangle (P2trTriangle *tri)
+{
+  return p2tr_mesh_action_triangle (tri, FALSE);
+}
+
+P2trMeshAction*
+p2tr_mesh_action_ref (P2trMeshAction *self)
+{
+  ++self->refcount;
+  return self;
+}
+
+void
+p2tr_mesh_action_free (P2trMeshAction *self)
+{
+  switch (self->type)
+    {
+      case P2TR_MESH_ACTION_POINT:
+        p2tr_mesh_action_point_free (self);
+        break;
+      case P2TR_MESH_ACTION_EDGE:
+        p2tr_mesh_action_edge_free (self);
+        break;
+      case P2TR_MESH_ACTION_TRIANGLE:
+        p2tr_mesh_action_triangle_free (self);
+        break;
+      default:
+        g_assert_not_reached ();
+        break;
+    }
+}
+
+void
+p2tr_mesh_action_unref (P2trMeshAction *self)
+{
+  g_assert (self->refcount > 0);
+  if (--self->refcount == 0)
+    p2tr_mesh_action_free (self);
+}
+
+void
+p2tr_mesh_action_undo (P2trMeshAction *self,
+                       P2trMesh       *mesh)
+{
+  switch (self->type)
+    {
+      case P2TR_MESH_ACTION_POINT:
+        p2tr_mesh_action_point_undo (self, mesh);
+        break;
+      case P2TR_MESH_ACTION_EDGE:
+        p2tr_mesh_action_edge_undo (self, mesh);
+        break;
+      case P2TR_MESH_ACTION_TRIANGLE:
+        p2tr_mesh_action_triangle_undo (self, mesh);
+        break;
+      default:
+        g_assert_not_reached ();
+        break;
+    }
+}
+
diff --git a/libs/poly2tri-c/poly2tri-c/refine/mesh-action.h b/libs/poly2tri-c/poly2tri-c/refine/mesh-action.h
new file mode 100644
index 0000000..cd3e840
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/mesh-action.h
@@ -0,0 +1,170 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_MESH_ACTION_H__
+#define __P2TC_REFINE_MESH_ACTION_H__
+
+#include <glib.h>
+
+/**
+ * \defgroup P2trMeshAction P2trMeshAction - Mesh Action Recording
+ * Action recording state objects for mesh objects. These may be
+ * inspected by code outside of the library, but objects of this type
+ * should not be created or manipulated by external code!
+ * @{
+ */
+
+/**
+ * The type of the geometric primitive affected by a mesh action
+ */
+typedef enum
+{
+  P2TR_MESH_ACTION_POINT,
+  P2TR_MESH_ACTION_EDGE,
+  P2TR_MESH_ACTION_TRIANGLE
+} P2trMeshActionType;
+
+/**
+ * A struct representing any single action on a mesh. A single atomic
+ * action may be the insertion/removal of a point/edge/triangle.
+ *
+ * Note that such an action only treats the direct geometric operation
+ * related to the specific geometric primitve, without any of its
+ * dependencies.
+ *
+ * For example, if removing a point requires the removal of several
+ * edges and triangles, then the removal of each one of those should be
+ * recorded in its own action object.
+ */
+typedef struct P2trMeshAction_
+{
+  /** The type of geometric primitive affected by the action */
+  P2trMeshActionType  type;
+  /** A flag specifying whether the primitive was added or removed */
+  gboolean            added;
+  /** A reference count to the action object */
+  gint                refcount;
+  /** Specific additional information which is needed for each type
+   *  of action */
+  union {
+    /** Information required to undo a point action */
+    struct {
+      /** The point that was added/deleted */
+      P2trPoint *point;
+    } action_point;
+
+    /** Information required to undo an edge action */
+    struct {
+      /** A virtual edge representing the added/deleted edge */
+      P2trVEdge *vedge;
+      /** A flag specifying whether the edge is constrained */
+      gboolean   constrained;
+    } action_edge;
+
+    /** Information required to undo a triangle action */
+    struct {
+      /** A virtual triangle representing the added/deleted triangle */
+      P2trVTriangle *vtri;
+    } action_tri;
+  } action;
+} P2trMeshAction;
+
+/**
+ * Create a new mesh action describing the addition of a new point
+ * @param point The point that is added to the mesh
+ * @return An object representing the point addition action
+ */
+P2trMeshAction*  p2tr_mesh_action_new_point      (P2trPoint      *point);
+
+/**
+ * Create a new mesh action describing the deletion of an existing point
+ * @param point The point that is deleted from the mesh
+ * @return An object representing the point deletion action
+ */
+P2trMeshAction*  p2tr_mesh_action_del_point      (P2trPoint      *point);
+
+/**
+ * Create a new mesh action describing the addition of a new edge
+ * @param edge The edge that is added to the mesh
+ * @return An object representing the edge addition action
+ */
+P2trMeshAction*  p2tr_mesh_action_new_edge       (P2trEdge       *edge);
+
+/**
+ * Create a new mesh action describing the deletion of an existing edge
+ * @param edge The edge that is deleted from the mesh
+ * @return An object representing the edge deletion action
+ */
+P2trMeshAction*  p2tr_mesh_action_del_edge       (P2trEdge       *edge);
+
+/**
+ * Create a new mesh action describing the addition of a triangle
+ * @param tri The triangle that is added to the mesh
+ * @return An object representing the triangle addition action
+ */
+P2trMeshAction*  p2tr_mesh_action_new_triangle   (P2trTriangle   *tri);
+
+/**
+ * Create a new mesh action describing the deletion of an existing
+ * triangle
+ * @param tri The triangle that is deleted from the mesh
+ * @return An object representing the triangle deletion action
+ */
+P2trMeshAction*  p2tr_mesh_action_del_triangle   (P2trTriangle   *tri);
+
+/**
+ * Increase the reference count to this mesh action by 1
+ * @param self The mesh action whose reference count should be increased
+ */
+P2trMeshAction*  p2tr_mesh_action_ref            (P2trMeshAction *self);
+
+/**
+ * Decrease the reference count to this mesh action by 1
+ * @param self The mesh action whose reference count should be decreased
+ */
+void             p2tr_mesh_action_unref          (P2trMeshAction *self);
+
+/**
+ * Free the memory used by a mesh action data structure
+ * @param self The mesh action whose memory should be freed
+ */
+void             p2tr_mesh_action_free           (P2trMeshAction *self);
+
+/**
+ * Undo the action described by the given mesh action object
+ * @param self The mesh action to undo
+ * @param mesh The mesh on which this action was applied
+ */
+void             p2tr_mesh_action_undo           (P2trMeshAction *self,
+                                                  P2trMesh       *mesh);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/mesh.c b/libs/poly2tri-c/poly2tri-c/refine/mesh.c
new file mode 100644
index 0000000..4478178
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/mesh.c
@@ -0,0 +1,406 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include "utils.h"
+
+#include "mesh.h"
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+#include "mesh-action.h"
+
+P2trMesh*
+p2tr_mesh_new (void)
+{
+  P2trMesh *mesh = g_slice_new (P2trMesh);
+
+  mesh->refcount = 1;
+  mesh->edges = p2tr_hash_set_new_default ();
+  mesh->points = p2tr_hash_set_new_default ();
+  mesh->triangles = p2tr_hash_set_new_default ();
+
+  mesh->record_undo = FALSE;
+  g_queue_init (&mesh->undo);
+
+  return mesh;
+}
+
+P2trPoint*
+p2tr_mesh_add_point (P2trMesh  *self,
+                     P2trPoint *point)
+{
+  g_assert (point->mesh == NULL);
+  point->mesh = self;
+  p2tr_mesh_ref (self);
+  p2tr_hash_set_insert (self->points, point);
+
+  if (self->record_undo)
+    g_queue_push_tail (&self->undo, p2tr_mesh_action_new_point (point));
+
+  return p2tr_point_ref (point);
+}
+
+P2trPoint*
+p2tr_mesh_new_point (P2trMesh          *self,
+                     const P2trVector2 *c)
+{
+  return p2tr_mesh_new_point2 (self, c->x, c->y);
+}
+
+P2trPoint*
+p2tr_mesh_new_point2 (P2trMesh *self,
+                      gdouble   x,
+                      gdouble   y)
+{
+  return p2tr_mesh_add_point (self, p2tr_point_new2 (x, y));
+}
+
+P2trEdge*
+p2tr_mesh_add_edge (P2trMesh *self,
+                    P2trEdge *edge)
+{
+  p2tr_hash_set_insert (self->edges, p2tr_edge_ref (edge->mirror));
+  p2tr_hash_set_insert (self->edges, p2tr_edge_ref (edge));
+
+  if (self->record_undo)
+    g_queue_push_tail (&self->undo, p2tr_mesh_action_new_edge (edge));
+
+  return edge;
+}
+
+P2trEdge*
+p2tr_mesh_new_edge (P2trMesh  *self,
+                    P2trPoint *start,
+                    P2trPoint *end,
+                    gboolean   constrained)
+{
+  return p2tr_mesh_add_edge (self, p2tr_edge_new (start, end, constrained));
+}
+
+P2trEdge*
+p2tr_mesh_new_or_existing_edge (P2trMesh  *self,
+                                P2trPoint *start,
+                                P2trPoint *end,
+                                gboolean   constrained)
+{
+  P2trEdge *result = p2tr_point_has_edge_to (start, end);
+  if (result)
+    p2tr_edge_ref (result);
+  else
+    result = p2tr_mesh_new_edge (self, start, end, constrained);
+  return result;
+}
+
+P2trTriangle*
+p2tr_mesh_add_triangle (P2trMesh     *self,
+                        P2trTriangle *tri)
+{
+  p2tr_hash_set_insert (self->triangles, tri);
+
+  if (self->record_undo)
+    g_queue_push_tail (&self->undo, p2tr_mesh_action_new_triangle (tri));
+
+  return p2tr_triangle_ref (tri);
+}
+
+P2trTriangle*
+p2tr_mesh_new_triangle (P2trMesh *self,
+                        P2trEdge *AB,
+                        P2trEdge *BC,
+                        P2trEdge *CA)
+{
+  return p2tr_mesh_add_triangle (self, p2tr_triangle_new (AB, BC, CA));
+}
+
+void
+p2tr_mesh_on_point_removed (P2trMesh  *self,
+                            P2trPoint *point)
+{
+  if (self != point->mesh)
+    p2tr_exception_programmatic ("Point does not belong to this mesh!");
+
+  point->mesh = NULL;
+  p2tr_mesh_unref (self);
+
+  p2tr_hash_set_remove (self->points, point);
+
+  if (self->record_undo)
+    g_queue_push_tail (&self->undo, p2tr_mesh_action_del_point (point));
+
+  p2tr_point_unref (point);
+}
+
+void
+p2tr_mesh_on_edge_removed (P2trMesh *self,
+                           P2trEdge *edge)
+{
+  p2tr_hash_set_remove (self->edges, edge->mirror);
+  p2tr_edge_unref (edge->mirror);
+  p2tr_hash_set_remove (self->edges, edge);
+
+  if (self->record_undo)
+    g_queue_push_tail (&self->undo, p2tr_mesh_action_del_edge (edge));
+
+  p2tr_edge_unref (edge);
+}
+
+void
+p2tr_mesh_on_triangle_removed (P2trMesh     *self,
+                               P2trTriangle *triangle)
+{
+  p2tr_hash_set_remove (self->triangles, triangle);
+
+  if (self->record_undo)
+    g_queue_push_tail (&self->undo, p2tr_mesh_action_del_triangle (triangle));
+
+  p2tr_triangle_unref (triangle);
+}
+
+void
+p2tr_mesh_action_group_begin (P2trMesh *self)
+{
+  g_assert (! self->record_undo);
+  self->record_undo = TRUE;
+}
+
+void
+p2tr_mesh_action_group_commit (P2trMesh *self)
+{
+  GList *iter;
+
+  g_assert (self->record_undo);
+
+  for (iter = self->undo.head; iter != NULL; iter = iter->next)
+    p2tr_mesh_action_unref ((P2trMeshAction*)iter->data);
+  g_queue_clear (&self->undo);
+
+  self->record_undo = FALSE;
+}
+
+void
+p2tr_mesh_action_group_undo (P2trMesh *self)
+{
+  GList *iter;
+
+  g_assert (self->record_undo);
+
+  for (iter = self->undo.tail; iter != NULL; iter = iter->prev)
+    {
+      p2tr_mesh_action_undo ((P2trMeshAction*)iter->data, self);
+      p2tr_mesh_action_unref ((P2trMeshAction*)iter->data);
+    }
+  g_queue_clear (&self->undo);
+
+  self->record_undo = FALSE;
+}
+
+void
+p2tr_mesh_clear (P2trMesh *self)
+{
+  P2trHashSetIter iter;
+  gpointer temp;
+
+  /* While iterating over the sets of points/edges/triangles to remove
+   * all the mesh elements, the sets will be modified by the removal
+   * operation itself. Therefore we can't use a regular iterator -
+   * instead we must look always at the first place */
+  p2tr_hash_set_iter_init (&iter, self->triangles);
+  while (p2tr_hash_set_iter_next (&iter, &temp))
+    {
+      p2tr_triangle_remove ((P2trTriangle*)temp);
+      p2tr_hash_set_iter_init (&iter, self->triangles);
+    }
+
+  p2tr_hash_set_iter_init (&iter, self->edges);
+  while (p2tr_hash_set_iter_next (&iter, &temp))
+    {
+      g_assert (((P2trEdge*)temp)->tri == NULL);
+      p2tr_edge_remove ((P2trEdge*)temp);
+      p2tr_hash_set_iter_init (&iter, self->edges);
+    }
+
+  p2tr_hash_set_iter_init (&iter, self->points);
+  while (p2tr_hash_set_iter_next (&iter, &temp))
+    {
+      g_assert (((P2trPoint*)temp)->outgoing_edges == NULL);
+      p2tr_point_remove ((P2trPoint*)temp);
+      p2tr_hash_set_iter_init (&iter, self->points);
+    }
+}
+
+void
+p2tr_mesh_free (P2trMesh *self)
+{
+  if (self->record_undo)
+    p2tr_mesh_action_group_commit (self);
+
+  p2tr_mesh_clear (self);
+
+  p2tr_hash_set_free (self->points);
+  p2tr_hash_set_free (self->edges);
+  p2tr_hash_set_free (self->triangles);
+
+  g_slice_free (P2trMesh, self);
+}
+
+void
+p2tr_mesh_unref (P2trMesh *self)
+{
+  g_assert (self->refcount > 0);
+  if (--self->refcount == 0)
+    p2tr_mesh_free (self);
+}
+
+P2trMesh*
+p2tr_mesh_ref (P2trMesh *self)
+{
+  ++self->refcount;
+  return self;
+}
+
+P2trTriangle*
+p2tr_mesh_find_point (P2trMesh *self,
+                      const P2trVector2 *pt)
+{
+  gdouble u, v;
+  return p2tr_mesh_find_point2 (self, pt, &u, &v);
+}
+
+P2trTriangle*
+p2tr_mesh_find_point2 (P2trMesh          *self,
+                       const P2trVector2 *pt,
+                       gdouble           *u,
+                       gdouble           *v)
+{
+  P2trHashSetIter iter;
+  P2trTriangle *result;
+  
+  p2tr_hash_set_iter_init (&iter, self->triangles);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*)&result))
+    if (p2tr_triangle_contains_point2 (result, pt, u, v) != P2TR_INTRIANGLE_OUT)
+      return p2tr_triangle_ref (result);
+
+  return NULL;
+}
+
+P2trTriangle*
+p2tr_mesh_find_point_local (P2trMesh          *self,
+                            const P2trVector2 *pt,
+                            P2trTriangle      *initial_guess)
+{
+  gdouble u, v;
+  return p2tr_mesh_find_point_local2 (self, pt, initial_guess, &u, &v);
+}
+
+P2trTriangle*
+p2tr_mesh_find_point_local2 (P2trMesh          *self,
+                             const P2trVector2 *pt,
+                             P2trTriangle      *initial_guess,
+                             gdouble           *u,
+                             gdouble           *v)
+{
+  P2trHashSet *checked_tris;
+  GQueue to_check;
+  P2trTriangle *result = NULL;
+
+  if (initial_guess == NULL)
+    return p2tr_mesh_find_point2(self, pt, u, v);
+
+  checked_tris = p2tr_hash_set_new_default ();
+  g_queue_init (&to_check);
+  g_queue_push_head (&to_check, initial_guess);
+
+  while (! g_queue_is_empty (&to_check))
+    {
+      P2trTriangle *tri = (P2trTriangle*) g_queue_pop_head (&to_check);
+      
+      p2tr_hash_set_insert (checked_tris, tri);
+      if (p2tr_triangle_contains_point2 (tri, pt, u, v) != P2TR_INTRIANGLE_OUT)
+        {
+          result = tri;
+          break;
+        }
+      else
+        {
+          gint i;
+          for (i = 0; i < 3; i++)
+            {
+              P2trTriangle *new_to_check = tri->edges[i]->mirror->tri;
+              if (new_to_check != NULL
+                  && ! p2tr_hash_set_contains (checked_tris, new_to_check))
+                {
+                  p2tr_hash_set_insert (checked_tris, new_to_check);
+                  g_queue_push_tail (&to_check, new_to_check);
+                }
+            }
+        }
+    }
+
+  p2tr_hash_set_free (checked_tris);
+  g_queue_clear (&to_check);
+
+  if (result != NULL)
+    p2tr_triangle_ref (result);
+
+  return result;
+}
+
+void
+p2tr_mesh_get_bounds (P2trMesh    *self,
+                      gdouble     *min_x,
+                      gdouble     *min_y,
+                      gdouble     *max_x,
+                      gdouble     *max_y)
+{
+  gdouble lmin_x = + G_MAXDOUBLE, lmin_y = + G_MAXDOUBLE;
+  gdouble lmax_x = - G_MAXDOUBLE, lmax_y = - G_MAXDOUBLE;
+
+  P2trHashSetIter iter;
+  P2trPoint *pt;
+
+  p2tr_hash_set_iter_init (&iter, self->points);
+  while (p2tr_hash_set_iter_next (&iter, (gpointer*) &pt))
+    {
+      gdouble x = pt->c.x;
+      gdouble y = pt->c.y;
+
+      lmin_x = MIN (lmin_x, x);
+      lmin_y = MIN (lmin_y, y);
+      lmax_x = MAX (lmax_x, x);
+      lmax_y = MAX (lmax_y, y);
+    }
+  *min_x = lmin_x;
+  *min_y = lmin_y;
+  *max_x = lmax_x;
+  *max_y = lmax_y;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/mesh.h b/libs/poly2tri-c/poly2tri-c/refine/mesh.h
new file mode 100644
index 0000000..c814df4
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/mesh.h
@@ -0,0 +1,361 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_MESH_H__
+#define __P2TC_REFINE_MESH_H__
+
+#include <glib.h>
+#include "vector2.h"
+#include "utils.h"
+#include "triangulation.h"
+
+/**
+ * \defgroup P2trMesh P2trMesh - Triangular Meshes
+ * The library is designed to handle triangular meshes which are made
+ * of one continuous region, potentially with holes
+ * @{
+ */
+
+/**
+ * A struct for representing a triangular mesh
+ */
+struct P2trMesh_
+{
+  /**
+   * A hash set containing pointers to all the triangles
+   * (\ref P2trTriangle) in the mesh
+   */
+  P2trHashSet *triangles;
+
+  /**
+   * A hash set containing pointers to all the edges (\ref P2trEdge) in
+   * the mesh
+   */
+  P2trHashSet *edges;
+
+  /**
+   * A hash set containing pointers to all the points (\ref P2trPoint)
+   * in the mesh
+   */
+  P2trHashSet *points;
+
+  /**
+   * A boolean flag specifying whether recording of actions on the
+   * mesh (for allowing to undo them) is taking place right now
+   */
+  gboolean     record_undo;
+
+  /**
+   * A queue stroing all the actions done on the mesh since the begining
+   * of the recording
+   */
+  GQueue       undo;
+
+  /**
+   * Counts the amount of references to the mesh. When this counter
+   * reaches zero, the mesh will be freed
+   */
+  guint        refcount;
+};
+
+/**
+ * Create a new empty mesh
+ * @return The newly created mesh
+ */
+P2trMesh*     p2tr_mesh_new             (void);
+
+/**
+ * Add an existing point to the given mesh
+ * @param self The mesh to add the point to
+ * @param point The point to add
+ * @return The given point
+ */
+P2trPoint*    p2tr_mesh_add_point       (P2trMesh  *self,
+                                         P2trPoint *point);
+
+/**
+ * Create a new point and add it to the given mesh
+ * @param mesh The mesh to add the point to
+ * @param c The coordinates of the point to create
+ * @return The newly created point
+ */
+P2trPoint*    p2tr_mesh_new_point       (P2trMesh          *mesh,
+                                         const P2trVector2 *c);
+
+/**
+ * Create a new point and add it to the given mesh
+ * @param mesh The mesh to add the point to
+ * @param x The X coordinate of the point to create
+ * @param y The Y coordinate of the point to create
+ * @return The newly created point
+ */
+P2trPoint*    p2tr_mesh_new_point2      (P2trMesh  *mesh,
+                                         gdouble    x,
+                                         gdouble    y);
+
+/**
+ * Add an existing edge to the given mesh
+ * @param self The mesh to add the edge to
+ * @param edge The edge to add
+ * @return The given edge
+ */
+P2trEdge*     p2tr_mesh_add_edge        (P2trMesh  *self,
+                                         P2trEdge  *point);
+
+/**
+ * Create a new edge and add it to the given mesh
+ * @param mesh The mesh to add the edge to
+ * @param start The starting point of the edge
+ * @param end The ending point of the edge
+ * @param constrained Specify whether this edge is constrained or not
+ * @return Thew newly created edge
+ */
+P2trEdge*     p2tr_mesh_new_edge        (P2trMesh  *mesh,
+                                         P2trPoint *start,
+                                         P2trPoint *end,
+                                         gboolean   constrained);
+
+/**
+ * This function checks if an edge between two points exists, and if
+ * not it creates it. In both cases the returned edge will be returned
+ * with an extra reference, so it must be unreffed later.
+ * @param self The mesh of the returned edge
+ * @param start The starting point of the returned edge
+ * @param end The ending point of the returned edge
+ * @param constrained Specify whether this edge should be constrained
+ *        or not (in case a new edge is created)
+ * @return An edge between the two points
+ */
+P2trEdge*     p2tr_mesh_new_or_existing_edge (P2trMesh  *self,
+                                              P2trPoint *start,
+                                              P2trPoint *end,
+                                              gboolean   constrained);
+
+/**
+ * Add an existing triangle to the given mesh
+ * @param self The mesh to add the triangle to
+ * @param edge The triangle to add
+ * @return The given triangle
+ */
+P2trTriangle* p2tr_mesh_add_triangle        (P2trMesh     *self,
+                                             P2trTriangle *tri);
+
+/**
+ * Create a new triangle and add it to the given mesh
+ * @param mesh The mesh to add the triangle to
+ * @param AB An edge from the first point of the triangle to the second
+ * @param BC An edge from the second point of the triangle to the third
+ * @param CA An edge from the third point of the triangle to the first
+ */
+P2trTriangle* p2tr_mesh_new_triangle        (P2trMesh *mesh,
+                                             P2trEdge *AB,
+                                             P2trEdge *BC,
+                                             P2trEdge *CA);
+
+/** \internal
+ * This function should be called just before a point is removed from
+ * the mesh. It is used internally to update the mesh and it should not
+ * be called by any code outside of this library.
+ * @param mesh The mesh from which the point is going to be removed
+ * @param point The point which is going to be removed
+*/
+void          p2tr_mesh_on_point_removed    (P2trMesh  *mesh,
+                                             P2trPoint *point);
+
+/** \internal
+ * This function should be called just before an edge is removed from
+ * the mesh. It is used internally to update the mesh and it should not
+ * be called by any code outside of this library.
+ * @param mesh The mesh from which the edge is going to be removed
+ * @param edge The edge which is going to be removed
+*/
+void          p2tr_mesh_on_edge_removed     (P2trMesh *mesh,
+                                             P2trEdge *edge);
+
+/** \internal
+ * This function should be called just before a triangle is removed from
+ * the mesh. It is used internally to update the mesh and it should not
+ * be called by any code outside of this library.
+ * @param mesh The mesh from which the triangle is going to be removed
+ * @param triangle The triangle which is going to be removed
+*/
+void          p2tr_mesh_on_triangle_removed (P2trMesh     *mesh,
+                                             P2trTriangle *triangle);
+
+/**
+ * Begin recording all action performed on a mesh. Recording the
+ * actions performed on a mesh allows choosing later whether to commit
+ * those actions or whether they should be undone.
+ * \warning This function must not be called when recording is already
+ *          taking place!
+ * @param self The mesh whose actions should be recorded
+ */
+void          p2tr_mesh_action_group_begin    (P2trMesh *self);
+
+/**
+ * Terminate the current session of recording mesh actions by
+ * committing all the actions to the mesh
+ * \warning This function must not be called unless recording of
+ *          actions is already taking place!
+ * @param self The mesh whose actions were recorded
+ */
+void          p2tr_mesh_action_group_commit   (P2trMesh *self);
+
+/**
+ * Terminate the current session of recording mesh actions by
+ * undoing all the actions done to the mesh.
+ * \warning This function must not be called unless recording of
+ *          actions is already taking place!
+ * \warning A call to this function may invalidate all references to
+ *          any non virtual geometric primitives! If you plan on using
+ *          this function, consider using virtual data structures!
+ * @param self The mesh whose actions were recorded
+ */
+void          p2tr_mesh_action_group_undo     (P2trMesh *self);
+
+/**
+ * Remove all triangles, edges and points from a mesh
+ * @param mesh The mesh to clear
+ */
+void          p2tr_mesh_clear           (P2trMesh *mesh);
+
+/**
+ * Clear and then free the memory used by a mesh data structure
+ * @param mesh The mesh whose memory should be freed
+ */
+void          p2tr_mesh_free            (P2trMesh *mesh);
+
+/**
+ * Decrease the reference count to this mesh by 1
+ * @param mesh The mesh whose reference count should be decreased
+ */
+void          p2tr_mesh_unref           (P2trMesh *mesh);
+
+/**
+ * Increase the reference count to this mesh by 1
+ * @param mesh The mesh whose reference count should be increased
+ * @return The given mesh (\ref mesh)
+ */
+P2trMesh*     p2tr_mesh_ref             (P2trMesh *mesh);
+
+/**
+ * Find a triangle of the mesh, containing the point at the given
+ * location
+ * @param self The mesh whose triangles should be checked
+ * @param pt The location of the point to test
+ * @return The triangle containing the given point, or NULL if the
+ *         point is outside the triangulation domain
+ */
+P2trTriangle* p2tr_mesh_find_point      (P2trMesh *self,
+                                         const P2trVector2 *pt);
+
+/**
+ * Exactly like \ref p2tr_mesh_find_point, except for the fact that
+ * this variant also returns the UV coordinates of the point inside the
+ * triangle
+ * @param[in] self The mesh whose triangles should be checked
+ * @param[in] pt The location of the point to test
+ * @param[out] u The U coordinate of the point inside the triangle
+ * @param[out] v The V coordinate of the point inside the triangle
+ * @return The triangle containing the given point, or NULL if the
+ *         point is outside the triangulation domain
+ */
+P2trTriangle* p2tr_mesh_find_point2     (P2trMesh          *self,
+                                         const P2trVector2 *pt,
+                                         gdouble           *u,
+                                         gdouble           *v);
+
+/**
+ * Another variant of \ref p2tr_mesh_find_point taking an initial
+ * triangle that the search should begin from its area. The search is
+ * performed first on triangles close to the given triangle, and it
+ * gradually tests farther and farther triangles until it finds the one
+ * containing the given point.
+ *
+ * This way of search should be fast when the approximate area of the
+ * point to find is known, but it will be slower if initial triangle
+ * is not near.
+ *
+ * Note that in this function, triangles are considered near depending
+ * on the length of the chain of neighbor triangles needed to go from
+ * one to the other.
+ *
+ * \warning This function may use memory which is at least linear in
+ *          the amount of triangles to test. Therefor, do not use it
+ *          on large mesh objects unless the initial guess is supposed
+ *          to be good!
+ * @param self The mesh whose triangles should be checked
+ * @param pt The location of the point to test
+ * @param initial_guess An initial guess for which triangle contains
+ *        the point, or is at least near the triangle containing it
+ * @return The triangle containing the given point, or NULL if the
+ *         point is outside the triangulation domain
+ */
+P2trTriangle* p2tr_mesh_find_point_local (P2trMesh *self,
+                                          const P2trVector2 *pt,
+                                          P2trTriangle *initial_guess);
+
+/**
+ * Exactly like \ref p2tr_mesh_find_point_local, except for the fact
+ * that this variant also returns the UV coordinates of the point
+ * inside the triangle
+ * @param[in] self The mesh whose triangles should be checked
+ * @param[in] pt The location of the point to test
+ * @param[in] initial_guess An initial guess for which triangle
+ *            contains the point, or is at least near the triangle
+ *            containing it
+ * @param[out] u The U coordinate of the point inside the triangle
+ * @param[out] v The V coordinate of the point inside the triangle
+ * @return The triangle containing the given point, or NULL if the
+ *         point is outside the triangulation domain
+ */
+P2trTriangle* p2tr_mesh_find_point_local2 (P2trMesh *self,
+                                           const P2trVector2 *pt,
+                                           P2trTriangle *initial_guess,
+                                           gdouble *u,
+                                           gdouble *v);
+
+/**
+ * Find the bounding rectangle containing this mesh.
+ * @param[in] self The mesh whose bounding rectangle should be computed
+ * @param[out] min_x The minimal X coordinate of the mesh
+ * @param[out] min_y The minimal Y coordinate of the mesh
+ * @param[out] max_x The maximal X coordinate of the mesh
+ * @param[out] max_y The maximal Y coordinate of the mesh
+ */
+void          p2tr_mesh_get_bounds        (P2trMesh    *self,
+                                           gdouble     *min_x,
+                                           gdouble     *min_y,
+                                           gdouble     *max_x,
+                                           gdouble     *max_y);
+/** @} */
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/point.c b/libs/poly2tri-c/poly2tri-c/refine/point.c
new file mode 100644
index 0000000..722cab6
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/point.c
@@ -0,0 +1,227 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include "point.h"
+#include "edge.h"
+#include "mesh.h"
+
+P2trPoint*
+p2tr_point_new (const P2trVector2 *c)
+{
+  return p2tr_point_new2 (c->x, c->y);
+}
+
+P2trPoint*
+p2tr_point_new2 (gdouble x, gdouble y)
+{
+  P2trPoint *self = g_slice_new (P2trPoint);
+  
+  self->c.x = x;
+  self->c.y = y;
+  self->mesh = NULL;
+  self->outgoing_edges = NULL;
+  self->refcount = 1;
+
+  return self;
+}
+
+void
+p2tr_point_remove (P2trPoint *self)
+{
+  /* We can not iterate over the list of edges while removing the edges,
+   * because the removal action will modify the list. Instead we will
+   * simply look at the first edge untill the list is emptied. */
+  while (self->outgoing_edges != NULL)
+    p2tr_edge_remove ((P2trEdge*) self->outgoing_edges->data);
+
+  if (self->mesh != NULL)
+    p2tr_mesh_on_point_removed (self->mesh, self);
+}
+
+void
+p2tr_point_free (P2trPoint *self)
+{
+  p2tr_point_remove (self);
+  g_slice_free (P2trPoint, self);
+}
+
+P2trEdge*
+p2tr_point_has_edge_to (P2trPoint *start,
+                        P2trPoint *end)
+{
+  GList *iter;
+  
+  for (iter = start->outgoing_edges; iter != NULL; iter = iter->next)
+    {
+      P2trEdge *edge = (P2trEdge*) iter->data;
+      if (edge->end == end)
+        return edge;
+    }
+  
+  return NULL;
+}
+
+P2trEdge*
+p2tr_point_get_edge_to (P2trPoint *start,
+                        P2trPoint *end,
+                        gboolean   do_ref)
+{
+    P2trEdge* result = p2tr_point_has_edge_to (start, end);
+    if (result == NULL)
+      p2tr_exception_programmatic ("Tried to get an edge that doesn't exist!");
+    else
+      return do_ref ? p2tr_edge_ref (result) : result;
+}
+
+void
+_p2tr_point_insert_edge (P2trPoint *self, P2trEdge *e)
+{
+  GList *iter = self->outgoing_edges;
+
+  /* Remember: Edges are sorted in ASCENDING angle! */
+  while (iter != NULL && ((P2trEdge*)iter->data)->angle < e->angle)
+    iter = iter->next;
+
+  self->outgoing_edges =
+      g_list_insert_before (self->outgoing_edges, iter, e);
+
+  p2tr_edge_ref (e);
+}
+
+void
+_p2tr_point_remove_edge (P2trPoint *self, P2trEdge* e)
+{
+  GList *node;
+  
+  if (P2TR_EDGE_START(e) != self)
+    p2tr_exception_programmatic ("Could not remove the given outgoing "
+        "edge because doesn't start on this point!");
+
+  node = g_list_find (self->outgoing_edges, e);
+  if (node == NULL)
+    p2tr_exception_programmatic ("Could not remove the given outgoing "
+        "edge because it's not present in the outgoing-edges list!");
+
+  self->outgoing_edges = g_list_delete_link (self->outgoing_edges, node);
+
+  p2tr_edge_unref (e);
+}
+
+P2trEdge*
+p2tr_point_edge_ccw (P2trPoint *self,
+                     P2trEdge  *e)
+{
+  GList *node;
+  P2trEdge *result;
+
+  if (P2TR_EDGE_START(e) != self)
+      p2tr_exception_programmatic ("Not an edge of this point!");
+
+  node = g_list_find (self->outgoing_edges, e);
+  if (node == NULL)
+    p2tr_exception_programmatic ("Could not find the CCW sibling edge"
+        "because the edge is not present in the outgoing-edges list!");
+
+  result = (P2trEdge*) g_list_cyclic_next (self->outgoing_edges, node)->data;
+  return p2tr_edge_ref (result);
+}
+
+P2trEdge*
+p2tr_point_edge_cw (P2trPoint* self,
+                    P2trEdge *e)
+{
+  GList *node;
+  P2trEdge *result;
+
+  if (P2TR_EDGE_START(e) != self)
+      p2tr_exception_programmatic ("Not an edge of this point!");
+
+  node = g_list_find (self->outgoing_edges, e);
+  if (node == NULL)
+    p2tr_exception_programmatic ("Could not find the CW sibling edge"
+        "because the edge is not present in the outgoing-edges list!");
+
+  result = (P2trEdge*) g_list_cyclic_prev (self->outgoing_edges, node)->data;
+  return p2tr_edge_ref (result);
+}
+
+gboolean
+p2tr_point_is_fully_in_domain (P2trPoint *self)
+{
+  GList *iter;
+  for (iter = self->outgoing_edges; iter != NULL; iter = iter->next)
+    if (((P2trEdge*) iter->data)->tri == NULL)
+      return FALSE;
+      
+  return TRUE;
+}
+
+gboolean
+p2tr_point_has_constrained_edge (P2trPoint *self)
+{
+  GList *iter;
+  for (iter = self->outgoing_edges; iter != NULL; iter = iter->next)
+    if (((P2trEdge*) iter->data)->constrained)
+      return TRUE;
+      
+  return FALSE;
+}
+
+/**
+ * Increase the reference count of the given input point
+ * @param self - The point to ref
+ * @return The point given
+ */
+P2trPoint*
+p2tr_point_ref (P2trPoint *self)
+{
+  ++self->refcount;
+  return self;
+}
+
+void
+p2tr_point_unref (P2trPoint *self)
+{
+  g_assert (self->refcount > 0);
+  if (--self->refcount == 0)
+    p2tr_point_free (self);
+}
+
+P2trMesh*
+p2tr_point_get_mesh (P2trPoint *self)
+{
+  if (self->mesh)
+    return p2tr_mesh_ref (self->mesh);
+  else
+    return NULL;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/point.h b/libs/poly2tri-c/poly2tri-c/refine/point.h
new file mode 100644
index 0000000..8b968fb
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/point.h
@@ -0,0 +1,99 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_POINT_H__
+#define __P2TC_REFINE_POINT_H__
+
+#include <glib.h>
+#include "vector2.h"
+#include "triangulation.h"
+
+/**
+ * @struct P2trPoint_
+ * A struct for a point in a triangular mesh
+ */
+struct P2trPoint_
+{
+  /** The 2D coordinates of the point */
+  P2trVector2  c;
+
+  /**
+   * A list of edges (@ref P2trEdge) which go out of this point (i.e.
+   * the point is their start point). The edges are sorted by ASCENDING
+   * angle, meaning they are sorted Counter Clockwise */
+  GList       *outgoing_edges;
+
+  /** A count of references to the point */
+  guint        refcount;
+  
+  /** The triangular mesh containing this point */
+  P2trMesh    *mesh;
+};
+
+P2trPoint*  p2tr_point_new                  (const P2trVector2 *c);
+
+P2trPoint*  p2tr_point_new2                 (gdouble x, gdouble y);
+
+P2trPoint*  p2tr_point_ref                  (P2trPoint *self);
+
+void        p2tr_point_unref                (P2trPoint *self);
+
+void        p2tr_point_free                 (P2trPoint *self);
+
+void        p2tr_point_remove               (P2trPoint *self);
+
+P2trEdge*   p2tr_point_has_edge_to          (P2trPoint *start,
+                                             P2trPoint *end);
+
+P2trEdge*   p2tr_point_get_edge_to          (P2trPoint *start,
+                                             P2trPoint *end,
+                                             gboolean   do_ref);
+
+void        _p2tr_point_insert_edge         (P2trPoint *self,
+                                             P2trEdge  *e);
+
+void        _p2tr_point_remove_edge         (P2trPoint *self,
+                                             P2trEdge  *e);
+
+P2trEdge*   p2tr_point_edge_ccw             (P2trPoint *self,
+                                             P2trEdge  *e);
+
+P2trEdge*   p2tr_point_edge_cw              (P2trPoint *self,
+                                             P2trEdge  *e);
+
+gboolean    p2tr_point_is_fully_in_domain   (P2trPoint *self);
+
+gboolean    p2tr_point_has_constrained_edge (P2trPoint *self);
+
+P2trMesh*   p2tr_point_get_mesh             (P2trPoint *self);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/pslg.c b/libs/poly2tri-c/poly2tri-c/refine/pslg.c
new file mode 100644
index 0000000..59f4d0d
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/pslg.c
@@ -0,0 +1,105 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include "pslg.h"
+
+static void
+free_bounded_line_if_not_null (gpointer line)
+{
+  p2tr_bounded_line_free ((P2trBoundedLine*)line);
+}
+
+/* A PSLG which is essentially a set of lines, will be represented by a
+ * hash table. When it will have an entry where both key and value are
+ * a line, it means that this is a new line and therefore should be
+ * freed. When it has an entry where the key is a line and the value is
+ * NULL, it means this is a line that should not be freed.
+ * This behaiour will be acheived by a NULL key free function and a
+ * real free function for values */
+P2trPSLG*
+p2tr_pslg_new (void)
+{
+  return g_hash_table_new_full (NULL, NULL, NULL, free_bounded_line_if_not_null);
+}
+
+void
+p2tr_pslg_add_new_line (P2trPSLG          *pslg,
+                        const P2trVector2 *start,
+                        const P2trVector2 *end)
+{
+  P2trBoundedLine *line = p2tr_bounded_line_new (start, end);
+  /* We would like to free this line, so also add it as a value */
+  g_hash_table_insert (pslg, line, line);
+}
+
+/* Add a line that needs not to be freed */
+void
+p2tr_pslg_add_existing_line (P2trPSLG              *pslg,
+                             const P2trBoundedLine *line)
+{
+  g_hash_table_insert (pslg, (P2trBoundedLine*) line, NULL);
+}
+
+guint
+p2tr_pslg_size (P2trPSLG *pslg)
+{
+  return g_hash_table_size (pslg);
+}
+
+void
+p2tr_pslg_iter_init (P2trPSLGIter *iter,
+                     P2trPSLG     *pslg)
+{
+  g_hash_table_iter_init (iter, pslg);
+}
+
+gboolean
+p2tr_pslg_iter_next (P2trPSLGIter           *iter,
+                     const P2trBoundedLine **line)
+{
+  /* The values are always stored in the key */
+  return g_hash_table_iter_next (iter, (gpointer*)line, NULL);
+}
+
+gboolean
+p2tr_pslg_contains_line (P2trPSLG              *pslg,
+                         const P2trBoundedLine *line)
+{
+  return g_hash_table_lookup_extended (pslg, line, NULL, NULL);
+}
+
+void
+p2tr_pslg_free (P2trPSLG *pslg)
+{
+  g_hash_table_destroy (pslg);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/pslg.h b/libs/poly2tri-c/poly2tri-c/refine/pslg.h
new file mode 100644
index 0000000..ef06bf3
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/pslg.h
@@ -0,0 +1,115 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_PSLG_H__
+#define __P2TC_REFINE_PSLG_H__
+
+#include "utils.h"
+#include "vector2.h"
+#include "line.h"
+#include "bounded-line.h"
+
+typedef P2trHashSet     P2trPSLG;
+typedef P2trHashSetIter P2trPSLGIter;
+
+/**
+ * Create a new PSLG. After finishing to use this PSLG, it should be
+ * freed by calling @ref p2tr_pslg_free
+ * @return A new empty PSLG
+ */
+P2trPSLG* p2tr_pslg_new               (void);
+
+/**
+ * Add a new line to the PSLG, where the line is defined by two given
+ * points.
+ * @param[in] pslg The PSLG
+ * @param[in] start The first edge-point of the new line to add
+ * @param[in] end The second edge-point of the new line to add
+ */
+void      p2tr_pslg_add_new_line      (P2trPSLG          *pslg,
+                                       const P2trVector2 *start,
+                                       const P2trVector2 *end);
+
+/**
+ * Add an existing P2trBoundedLine to the PSLG, so that the line will
+ * not be freed when the PSLG is freed. This line must not be freed
+ * before the PSLG is freed!
+ * @param[in] pslg The PSLG
+ * @param[in] line The existing line to add
+ */
+void      p2tr_pslg_add_existing_line (P2trPSLG              *pslg,
+                                       const P2trBoundedLine *line);
+
+/**
+ * Count how many lines are there in the PSLG
+ * @param[in] pslg The PSLG
+ * @return The amount of lines in the PSLG
+ */
+guint     p2tr_pslg_size              (P2trPSLG *pslg);
+
+/**
+ * Initialize an iterator to iterate over all the lines of the PSLG. The
+ * iterator will remain valid as long as the PSLG is not modified.
+ * @param[out] iter The iterator for this PSLG
+ * @param[in] pslg The PSLG
+ */
+void      p2tr_pslg_iter_init         (P2trPSLGIter *iter,
+                                       P2trPSLG     *pslg);
+
+/**
+ * Advance the iterator to the next line of the PSLG
+ * @param[in] iter The PSLG iterator
+ * @param[out] line The next line of the PSLG
+ * @return TRUE if there was another line, FALSE if the iteration over
+ *         all the lines was finished
+ */
+gboolean  p2tr_pslg_iter_next         (P2trPSLGIter           *iter,
+                                       const P2trBoundedLine **line);
+
+/**
+ * Test whether the PSLG contains this line. The line comparision is
+ * done *by refrence* and not by value, so this function only test if
+ * the line at the given memory location is inside the PSLG.
+ * @param[in] pslg The PSLG
+ * @param[in] line The line to search for
+ * @return TRUE if the line was found in the PSLG, FALSE otherwise
+ */
+gboolean  p2tr_pslg_contains_line     (P2trPSLG              *pslg,
+                                       const P2trBoundedLine *line);
+
+/**
+ * Free a PSLG and all of the resources allocated for it
+ * @param[in] pslg The PSLG to free
+ */
+void      p2tr_pslg_free              (P2trPSLG *pslg);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/refine.h b/libs/poly2tri-c/poly2tri-c/refine/refine.h
new file mode 100644
index 0000000..7828887
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/refine.h
@@ -0,0 +1,59 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_H__
+#define __P2TC_REFINE_H__
+
+#include "utils.h"
+#include "rmath.h"
+
+#include "vector2.h"
+#include "circle.h"
+#include "line.h"
+#include "bounded-line.h"
+#include "pslg.h"
+
+#include "triangulation.h"
+
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+#include "mesh.h"
+
+#include "vedge.h"
+#include "vtriangle.h"
+
+#include "cluster.h"
+#include "cdt.h"
+#include "refiner.h"
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/refiner.c b/libs/poly2tri-c/poly2tri-c/refine/refiner.c
new file mode 100644
index 0000000..92e2c32
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/refiner.c
@@ -0,0 +1,70 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include "cdt.h"
+#include "delaunay-terminator.h"
+#include "refiner.h"
+
+#define P2TR_REFINER_REAL_TYPE P2trDelaunayTerminator
+
+#define P2T_REFINER_TO_IMP(X) ((P2TR_REFINER_REAL_TYPE*)(X))
+#define P2T_IMP_TO_REFINER(X) ((P2trRefiner*)(X))
+
+gboolean
+p2tr_refiner_false_too_big (P2trTriangle *tri)
+{
+  return FALSE;
+}
+
+P2trRefiner*
+p2tr_refiner_new (gdouble             min_angle,
+                  P2trTriangleTooBig  size_control,
+                  P2trCDT            *cdt)
+{
+  return P2T_IMP_TO_REFINER (p2tr_dt_new (min_angle, size_control, cdt));
+}
+
+void
+p2tr_refiner_free (P2trRefiner *self)
+{
+  p2tr_dt_free (P2T_REFINER_TO_IMP (self));
+}
+
+void
+p2tr_refiner_refine (P2trRefiner             *self,
+                     gint                     max_steps,
+                     P2trRefineProgressNotify on_progress)
+{
+  p2tr_dt_refine (P2T_REFINER_TO_IMP (self), max_steps, on_progress);
+}
+
diff --git a/libs/poly2tri-c/poly2tri-c/refine/refiner.h b/libs/poly2tri-c/poly2tri-c/refine/refiner.h
new file mode 100644
index 0000000..ffeba91
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/refiner.h
@@ -0,0 +1,61 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_REFINER_H__
+#define __P2TC_REFINE_REFINER_H__
+
+#include <glib.h>
+#include "cdt.h"
+
+typedef struct P2trRefiner_ P2trRefiner;
+
+
+typedef gboolean (*P2trTriangleTooBig)       (P2trTriangle *tri);
+
+gboolean         p2tr_refiner_false_too_big  (P2trTriangle *tri);
+
+
+typedef void     (*P2trRefineProgressNotify) (P2trRefiner  *refiner,
+                                              int           step_number,
+                                              int           max_steps);
+
+P2trRefiner* p2tr_refiner_new    (gdouble                   min_angle,
+                                  P2trTriangleTooBig        size_control,
+                                  P2trCDT                  *cdt);
+
+void         p2tr_refiner_free   (P2trRefiner              *self);
+
+void         p2tr_refiner_refine (P2trRefiner              *self,
+                                  gint                      max_steps,
+                                  P2trRefineProgressNotify  on_progress);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/rmath.c b/libs/poly2tri-c/poly2tri-c/refine/rmath.c
new file mode 100644
index 0000000..f644eaf
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/rmath.c
@@ -0,0 +1,301 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include <glib.h>
+#include "rmath.h"
+
+gdouble
+p2tr_math_length_sq (gdouble x1, gdouble y1,
+                     gdouble x2, gdouble y2)
+{
+  return P2TR_VECTOR2_DISTANCE_SQ2 (x1, y1, x2, y2);
+}
+
+gdouble
+p2tr_math_length_sq2 (const P2trVector2 *pt1,
+                      const P2trVector2 *pt2)
+{
+  return p2tr_math_length_sq (pt1->x, pt1->y, pt2->x, pt2->y);
+}
+
+static inline gdouble
+p2tr_matrix_det2 (gdouble a00, gdouble a01,
+                  gdouble a10, gdouble a11)
+{
+    return a00 * a11 - a10 * a01;
+}
+
+static inline gdouble
+p2tr_matrix_det3 (gdouble a00, gdouble a01, gdouble a02,
+                  gdouble a10, gdouble a11, gdouble a12,
+                  gdouble a20, gdouble a21, gdouble a22)
+{
+    return
+        + a00 * (a11 * a22 - a21 * a12)
+        - a01 * (a10 * a22 - a20 * a12)
+        + a02 * (a10 * a21 - a20 * a11);
+}
+
+static inline gdouble
+p2tr_matrix_det4 (gdouble a00, gdouble a01, gdouble a02, gdouble a03,
+                  gdouble a10, gdouble a11, gdouble a12, gdouble a13,
+                  gdouble a20, gdouble a21, gdouble a22, gdouble a23,
+                  gdouble a30, gdouble a31, gdouble a32, gdouble a33)
+{
+    return
+        + a00 * p2tr_matrix_det3 (a11, a12, a13,
+                                 a21, a22, a23,
+                                 a31, a32, a33)
+        - a01 * p2tr_matrix_det3 (a10, a12, a13,
+                                  a20, a22, a23,
+                                  a30, a32, a33)
+        + a02 * p2tr_matrix_det3 (a10, a11, a13,
+                                  a20, a21, a23,
+                                  a30, a31, a33)
+        - a03 * p2tr_matrix_det3 (a10, a11, a12,
+                                  a20, a21, a22,
+                                  a30, a31, a32);
+}
+
+void
+p2tr_math_triangle_circumcircle (const P2trVector2 *A,
+                                 const P2trVector2 *B,
+                                 const P2trVector2 *C,
+                                 P2trCircle    *circle)
+{
+  /*       | Ax Bx Cx |
+   * D = + | Ay By Cy | * 2
+   *       | +1 +1 +1 |
+   *
+   *       | Asq Bsq Csq |
+   * X = + | Ay  By  Cy  | / D
+   *       | 1   1   1   |
+   *
+   *       | Asq Bsq Csq |
+   * Y = - | Ax  Bx  Cx  | / D
+   *       | 1   1   1   |
+   */
+  gdouble Asq = P2TR_VECTOR2_LEN_SQ (A);
+  gdouble Bsq = P2TR_VECTOR2_LEN_SQ (B);
+  gdouble Csq = P2TR_VECTOR2_LEN_SQ (C);
+
+  gdouble invD = 1 / (2 * p2tr_matrix_det3 (
+      A->x, B->x, C->x,
+      A->y, B->y, C->y,
+      1,    1,    1));
+
+  circle->center.x = + p2tr_matrix_det3 (
+      Asq,  Bsq,  Csq,
+      A->y, B->y, C->y,
+      1,    1,    1) * invD;
+
+  circle->center.y = - p2tr_matrix_det3 (
+      Asq,  Bsq,  Csq,
+      A->x, B->x, C->x,
+      1,    1,    1) * invD;
+
+  circle->radius = sqrt (P2TR_VECTOR2_DISTANCE_SQ (A, &circle->center));
+}
+
+/* The point in triangle test which is implemented below is based on the
+ * algorithm which appears on:
+ *
+ *    http://www.blackpawn.com/texts/pointinpoly/default.html
+ */
+void
+p2tr_math_triangle_barcycentric (const P2trVector2 *A,
+                                 const P2trVector2 *B,
+                                 const P2trVector2 *C,
+                                 const P2trVector2 *P,
+                                 gdouble           *u,
+                                 gdouble           *v)
+{
+  gdouble dot00, dot01, dot02, dot11, dot12, invDenom;
+
+  /* Compute the vectors offsetted so that A is the origin */
+  P2trVector2 v0, v1, v2;
+  p2tr_vector2_sub(C, A, &v0);
+  p2tr_vector2_sub(B, A, &v1);
+  p2tr_vector2_sub(P, A, &v2);
+
+  /* Compute dot products */
+  dot00 = P2TR_VECTOR2_DOT(&v0, &v0);
+  dot01 = P2TR_VECTOR2_DOT(&v0, &v1);
+  dot02 = P2TR_VECTOR2_DOT(&v0, &v2);
+  dot11 = P2TR_VECTOR2_DOT(&v1, &v1);
+  dot12 = P2TR_VECTOR2_DOT(&v1, &v2);
+
+  /* Compute barycentric coordinates */
+  invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+  *u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+  *v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+}
+
+#define INTRIANGLE_EPSILON 0e-9
+
+P2trInTriangle
+p2tr_math_intriangle (const P2trVector2 *A,
+                      const P2trVector2 *B,
+                      const P2trVector2 *C,
+                      const P2trVector2 *P)
+{
+  gdouble u, v;
+  return p2tr_math_intriangle2 (A, B, C, P, &u, &v);
+}
+
+P2trInTriangle
+p2tr_math_intriangle2 (const P2trVector2 *A,
+                       const P2trVector2 *B,
+                       const P2trVector2 *C,
+                       const P2trVector2 *P,
+                       gdouble           *u,
+                       gdouble           *v)
+{
+  p2tr_math_triangle_barcycentric (A, B, C, P, u, v);
+  
+  /* Check if point is in triangle - i.e. whether (u + v) < 1 and both
+   * u and v are positive */
+  if ((*u >= INTRIANGLE_EPSILON) && (*v >= INTRIANGLE_EPSILON) && (*u + *v < 1 - INTRIANGLE_EPSILON))
+    return P2TR_INTRIANGLE_IN;
+  else if ((*u >= -INTRIANGLE_EPSILON) && (*v >= -INTRIANGLE_EPSILON) && (*u + *v <= 1 + INTRIANGLE_EPSILON))
+    return P2TR_INTRIANGLE_ON;
+  else
+    return P2TR_INTRIANGLE_OUT;
+}
+
+/* The point in triangle circumcircle test, and the 3-point orientation
+ * test, are both based on the work of Jonathan Richard Shewchuk. The
+ * technique used here is described in his paper "Adaptive Precision
+ * Floating-Point Arithmetic and Fast Robust Geometric Predicates"
+ */
+
+#define ORIENT2D_EPSILON 1e-9
+
+P2trOrientation p2tr_math_orient2d (const P2trVector2 *A,
+                                    const P2trVector2 *B,
+                                    const P2trVector2 *C)
+{
+  /* We are trying to compute this determinant:
+   * |Ax Ay 1|
+   * |Bx By 1|
+   * |Cx Cy 1|
+   */
+  gdouble result = p2tr_matrix_det3 (
+      A->x, A->y, 1,
+      B->x, B->y, 1,
+      C->x, C->y, 1
+  );
+
+  if (result > ORIENT2D_EPSILON)
+    return P2TR_ORIENTATION_CCW;
+  else if (result < -ORIENT2D_EPSILON)
+    return P2TR_ORIENTATION_CW;
+  else
+    return P2TR_ORIENTATION_LINEAR;
+}
+
+#define INCIRCLE_EPSILON 1e-9
+
+/* Points must be given in CCW order!!!!! */
+P2trInCircle
+p2tr_math_incircle (const P2trVector2 *A,
+                    const P2trVector2 *B,
+                    const P2trVector2 *C,
+                    const P2trVector2 *D)
+{
+  /* We are trying to compute this determinant:
+   * |Ax Ay Ax^2+Ay^2 1|
+   * |Bx By Bx^2+By^2 1|
+   * |Cx Cy Cx^2+Cy^2 1|
+   * |Dx Dy Dx^2+Dy^2 1|
+   */
+  gdouble result = p2tr_matrix_det4 (
+      A->x, A->y, P2TR_VECTOR2_LEN_SQ(A), 1,
+      B->x, B->y, P2TR_VECTOR2_LEN_SQ(B), 1,
+      C->x, C->y, P2TR_VECTOR2_LEN_SQ(C), 1,
+      D->x, D->y, P2TR_VECTOR2_LEN_SQ(D), 1
+  );
+
+  if (result > INCIRCLE_EPSILON)
+    return P2TR_INCIRCLE_IN;
+  else if (result < INCIRCLE_EPSILON)
+    return P2TR_INCIRCLE_OUT;
+  else
+    return P2TR_INCIRCLE_ON;
+}
+
+/* The point inside diametral-circle test and the point inside diametral
+ * lens test, are both based on the work of Jonathan Richard Shewchuk.
+ * The techniques used here are partially described in his paper
+ * "Delaunay Refinement Algorithms for Triangular Mesh Generation".
+ *
+ * W is inside the diametral circle (lens) of the line XY if and only if
+ * the angle XWY is larger than 90 (120) degrees. We know how to compute
+ * the cosine of that angle very easily like so:
+ *
+ * cos XWY = (WX * WY) / (|WX| * |WY|)
+ *
+ * Since XWY is larger than 90 (120) degrees, cos XWY <= 0 (-0.5) so:
+ *
+ * Diametral Circle               | Diametral Lens
+ * -------------------------------+-----------------------------------
+ * 0 >= (WX * WY) / (|WX| * |WY|) | - 0.5 >= (WX * WY) / (|WX| * |WY|)
+ * 0 >= WX * WY                   | - 0.5 * |WX| * |WY| >= WX * WY
+ */
+
+gboolean
+p2tr_math_diametral_circle_contains (const P2trVector2 *X,
+                                     const P2trVector2 *Y,
+                                     const P2trVector2 *W)
+{
+  P2trVector2 WX, WY;
+
+  p2tr_vector2_sub(X, W, &WX);
+  p2tr_vector2_sub(Y, W, &WY);
+
+  return P2TR_VECTOR2_DOT(&WX, &WY) <= 0;
+}
+
+gboolean
+p2tr_math_diametral_lens_contains (const P2trVector2 *X,
+                                   const P2trVector2 *Y,
+                                   const P2trVector2 *W)
+{
+  P2trVector2 WX, WY;
+
+  p2tr_vector2_sub(X, W, &WX);
+  p2tr_vector2_sub(Y, W, &WY);
+
+  return P2TR_VECTOR2_DOT(&WX, &WY)
+      <= 0.5 * p2tr_vector2_norm(&WX) * p2tr_vector2_norm(&WY);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/rmath.h b/libs/poly2tri-c/poly2tri-c/refine/rmath.h
new file mode 100644
index 0000000..68f9e87
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/rmath.h
@@ -0,0 +1,132 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_MATH_H__
+#define __P2TC_REFINE_MATH_H__
+
+#include <glib.h>
+#include "vector2.h"
+#include "circle.h"
+
+gdouble   p2tr_math_length_sq  (gdouble x1,
+                                gdouble y1,
+                                gdouble x2,
+                                gdouble y2);
+
+gdouble   p2tr_math_length_sq2 (const P2trVector2 *pt1,
+                                const P2trVector2 *pt2);
+
+
+/**
+ * Find the circumscribing circle of a triangle defined by the given
+ * points.
+ * @param[in] A The first vertex of the triangle
+ * @param[in] B The second vertex of the triangle
+ * @param[in] C The third vertex of the triangle
+ * @param[out] circle The circumscribing circle of the triangle
+ */
+void      p2tr_math_triangle_circumcircle (const P2trVector2 *A,
+                                           const P2trVector2 *B,
+                                           const P2trVector2 *C,
+                                           P2trCircle    *circle);
+
+typedef enum
+{
+  P2TR_INTRIANGLE_OUT = -1,
+  P2TR_INTRIANGLE_ON = 0,
+  P2TR_INTRIANGLE_IN = 1
+} P2trInTriangle;
+
+/**
+ * Return the barycentric coordinates of a point inside a triangle. This
+ * means that the computation returns @ref u and @ref v so that the
+ * following equation is satisfied:
+ * {{{ AP = u * AB + v * AC }}}
+ *
+ * @param[in] A The first point of the triangle
+ * @param[in] B The second point of the triangle
+ * @param[in] C The third point of the triangle
+ * @param[in] P The point whose barycentric coordinates should be
+ *              computed
+ * @param[out] u The first barycentric coordinate
+ * @param[out] v The second barycentric coordinate
+ */
+void p2tr_math_triangle_barcycentric (const P2trVector2 *A,
+                                      const P2trVector2 *B,
+                                      const P2trVector2 *C,
+                                      const P2trVector2 *P,
+                                      gdouble           *u,
+                                      gdouble           *v);
+
+P2trInTriangle p2tr_math_intriangle (const P2trVector2 *A,
+                                     const P2trVector2 *B,
+                                     const P2trVector2 *C,
+                                     const P2trVector2 *P);
+
+P2trInTriangle p2tr_math_intriangle2 (const P2trVector2 *A,
+                                      const P2trVector2 *B,
+                                      const P2trVector2 *C,
+                                      const P2trVector2 *P,
+                                      gdouble           *u,
+                                      gdouble           *v);
+
+typedef enum
+{
+  P2TR_ORIENTATION_CW = -1,
+  P2TR_ORIENTATION_LINEAR = 0,
+  P2TR_ORIENTATION_CCW = 1
+} P2trOrientation;
+
+P2trOrientation p2tr_math_orient2d (const P2trVector2 *A,
+                                    const P2trVector2 *B,
+                                    const P2trVector2 *C);
+
+typedef enum
+{
+  P2TR_INCIRCLE_IN,
+  P2TR_INCIRCLE_ON,
+  P2TR_INCIRCLE_OUT
+} P2trInCircle;
+
+P2trInCircle p2tr_math_incircle (const P2trVector2 *A,
+                                 const P2trVector2 *B,
+                                 const P2trVector2 *C,
+                                 const P2trVector2 *D);
+
+gboolean  p2tr_math_diametral_circle_contains (const P2trVector2 *X,
+                                               const P2trVector2 *Y,
+                                               const P2trVector2 *W);
+
+gboolean  p2tr_math_diametral_lens_contains   (const P2trVector2 *X,
+                                               const P2trVector2 *Y,
+                                               const P2trVector2 *W);
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/triangle.c b/libs/poly2tri-c/poly2tri-c/refine/triangle.c
new file mode 100644
index 0000000..ce28dcc
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/triangle.c
@@ -0,0 +1,313 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include <glib.h>
+
+#include "utils.h"
+#include "rmath.h"
+
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+#include "mesh.h"
+
+void
+p2tr_validate_edges_can_form_tri (P2trEdge *AB,
+                                  P2trEdge *BC,
+                                  P2trEdge *CA)
+{
+  if (AB != AB->mirror->mirror ||
+      BC != BC->mirror->mirror ||
+      CA != CA->mirror->mirror)
+    {
+      p2tr_exception_programmatic ("Bad edge mirroring!");
+    }
+
+  if (AB->end != P2TR_EDGE_START(BC)
+      || BC->end != P2TR_EDGE_START(CA)
+      || CA->end != P2TR_EDGE_START(AB))
+    {
+      p2tr_exception_programmatic ("Unexpected edge sequence for a triangle!");
+    }
+
+  if (AB == BC->mirror || BC == CA->mirror || CA == AB->mirror)
+    {
+      p2tr_exception_programmatic ("Repeated edge in a triangle!");
+    }
+}
+
+P2trTriangle*
+p2tr_triangle_new (P2trEdge *AB,
+                   P2trEdge *BC,
+                   P2trEdge *CA)
+{
+  gint i;
+  P2trTriangle *self = g_slice_new (P2trTriangle);
+
+  self->refcount = 0;
+
+#ifndef P2TC_NO_LOGIC_CHECKS
+  p2tr_validate_edges_can_form_tri (AB, BC, CA);
+#endif
+
+  switch (p2tr_math_orient2d(&CA->end->c, &AB->end->c, &BC->end->c))
+    {
+      case P2TR_ORIENTATION_CCW:
+        self->edges[0] = CA->mirror;
+        self->edges[1] = BC->mirror;
+        self->edges[2] = AB->mirror;
+        break;
+
+      case P2TR_ORIENTATION_CW:
+        self->edges[0] = AB;
+        self->edges[1] = BC;
+        self->edges[2] = CA;
+        break;
+
+      case P2TR_ORIENTATION_LINEAR:
+        p2tr_exception_geometric ("Can't make a triangle of linear points!");
+    }
+
+#ifndef P2TC_NO_LOGIC_CHECKS
+  p2tr_validate_edges_can_form_tri (self->edges[0], self->edges[1], self->edges[2]);
+
+  if (p2tr_math_orient2d (&P2TR_TRIANGLE_GET_POINT(self,0)->c,
+                          &P2TR_TRIANGLE_GET_POINT(self,1)->c,
+                          &P2TR_TRIANGLE_GET_POINT(self,2)->c) != P2TR_ORIENTATION_CW)
+    {
+      p2tr_exception_programmatic ("Bad ordering!");
+    }
+#endif
+
+  for (i = 0; i < 3; i++)
+    {
+#ifndef P2TC_NO_LOGIC_CHECKS
+      if (self->edges[i]->tri != NULL)
+        p2tr_exception_programmatic ("This edge is already in use by "
+            "another triangle!");
+#endif
+      self->edges[i]->tri = self;
+      p2tr_edge_ref (self->edges[i]);
+      p2tr_triangle_ref (self);
+    }
+
+  return p2tr_triangle_ref (self);
+}
+
+P2trTriangle*
+p2tr_triangle_ref (P2trTriangle *self)
+{
+  ++self->refcount;
+  return self;
+}
+
+void
+p2tr_triangle_unref (P2trTriangle *self)
+{
+  g_assert (self->refcount > 0);
+  if (--self->refcount == 0)
+    p2tr_triangle_free (self);
+}
+
+void
+p2tr_triangle_free (P2trTriangle *self)
+{
+  g_assert (p2tr_triangle_is_removed (self));
+  g_slice_free (P2trTriangle, self);
+}
+
+void
+p2tr_triangle_remove (P2trTriangle *self)
+{
+  gint i;
+  P2trMesh *mesh;
+  
+  if (p2tr_triangle_is_removed (self))
+    return;
+
+  mesh = p2tr_triangle_get_mesh (self);
+  
+  if (mesh != NULL)
+    {
+      p2tr_mesh_on_triangle_removed (mesh, self);
+      p2tr_mesh_unref (mesh); /* The get function reffed it */
+    }
+
+  for (i = 0; i < 3; i++)
+  {
+    self->edges[i]->tri = NULL;
+    p2tr_edge_unref (self->edges[i]);
+    self->edges[i] = NULL;
+    /* Although we lost reference to the triangle 3 rows above, we must
+     * not unref it untill here since we still use the struct until this
+     * line! */
+    p2tr_triangle_unref (self);
+  }
+}
+
+P2trMesh*
+p2tr_triangle_get_mesh (P2trTriangle *self)
+{
+  if (self->edges[0] != NULL)
+    return p2tr_edge_get_mesh (self->edges[0]);
+  else
+    return NULL;
+}
+
+gboolean 
+p2tr_triangle_is_removed (P2trTriangle *self)
+{
+  return self->edges[0] == NULL;
+}
+
+P2trPoint*
+p2tr_triangle_get_opposite_point (P2trTriangle *self,
+                                  P2trEdge     *e,
+                                  gboolean      do_ref)
+{
+  P2trPoint *pt;
+  if (self->edges[0] == e || self->edges[0]->mirror == e)
+    pt = self->edges[1]->end;
+  else if (self->edges[1] == e || self->edges[1]->mirror == e)
+    pt = self->edges[2]->end;
+  else if (self->edges[2] == e || self->edges[2]->mirror == e)
+    pt = self->edges[0]->end;
+  else
+    p2tr_exception_programmatic ("The edge is not in the triangle!");
+
+  return do_ref ? p2tr_point_ref (pt) : pt;
+}
+
+P2trEdge*
+p2tr_triangle_get_opposite_edge (P2trTriangle *self,
+                                 P2trPoint    *p)
+{
+  if (self->edges[0]->end == p)
+    return p2tr_edge_ref (self->edges[2]);
+  if (self->edges[1]->end == p)
+    return p2tr_edge_ref (self->edges[0]);
+  if (self->edges[2]->end == p)
+    return p2tr_edge_ref (self->edges[1]);
+
+  p2tr_exception_programmatic ("The point is not in the triangle!");
+}
+
+/**
+ * Angles return by this function are always in the range [0,180]
+ */
+gdouble
+p2tr_triangle_get_angle_at (P2trTriangle *self,
+                            P2trPoint    *p)
+{
+  if (p == self->edges[0]->end)
+    return p2tr_edge_angle_between (self->edges[0], self->edges[1]);
+  else if (p == self->edges[1]->end)
+    return p2tr_edge_angle_between (self->edges[1], self->edges[2]);
+  else if (p == self->edges[2]->end)
+    return p2tr_edge_angle_between (self->edges[2], self->edges[0]);
+
+  p2tr_exception_programmatic ("Can't find the point!");
+}
+
+gdouble
+p2tr_triangle_smallest_non_constrained_angle (P2trTriangle *self)
+{
+    gdouble result = G_MAXDOUBLE, angle;
+    
+    if (! self->edges[0]->constrained || !self->edges[1]->constrained)
+      {
+        angle = p2tr_edge_angle_between(self->edges[0], self->edges[1]);
+        result = MIN(result, angle);
+      }
+
+    if (!self->edges[1]->constrained || !self->edges[2]->constrained)
+      {
+        angle = p2tr_edge_angle_between(self->edges[1], self->edges[2]);
+        result = MIN(result, angle);
+      }
+
+    if (!self->edges[2]->constrained || !self->edges[0]->constrained)
+      {
+        angle = p2tr_edge_angle_between(self->edges[2], self->edges[0]);
+        result = MIN(result, angle);
+      }
+
+    return result;
+}
+
+void
+p2tr_triangle_get_circum_circle (P2trTriangle *self,
+                                 P2trCircle   *circle)
+{
+  p2tr_math_triangle_circumcircle (
+      &P2TR_TRIANGLE_GET_POINT(self,0)->c,
+      &P2TR_TRIANGLE_GET_POINT(self,1)->c,
+      &P2TR_TRIANGLE_GET_POINT(self,2)->c,
+      circle);
+}
+
+P2trInCircle
+p2tr_triangle_circumcircle_contains_point (P2trTriangle      *self,
+                                           const P2trVector2  *pt)
+{
+  /* Points must be given in CCW order! */
+  return p2tr_math_incircle (
+      &P2TR_TRIANGLE_GET_POINT(self,2)->c,
+      &P2TR_TRIANGLE_GET_POINT(self,1)->c,
+      &P2TR_TRIANGLE_GET_POINT(self,0)->c,
+      pt);
+}
+
+P2trInTriangle
+p2tr_triangle_contains_point  (P2trTriangle      *self,
+                               const P2trVector2 *pt)
+{
+  return p2tr_math_intriangle (
+      &P2TR_TRIANGLE_GET_POINT(self,0)->c,
+      &P2TR_TRIANGLE_GET_POINT(self,1)->c,
+      &P2TR_TRIANGLE_GET_POINT(self,2)->c,
+      pt);
+}
+
+P2trInTriangle
+p2tr_triangle_contains_point2 (P2trTriangle      *self,
+                               const P2trVector2 *pt,
+                               gdouble           *u,
+                               gdouble           *v)
+{
+  return p2tr_math_intriangle2 (
+      &P2TR_TRIANGLE_GET_POINT(self,0)->c,
+      &P2TR_TRIANGLE_GET_POINT(self,1)->c,
+      &P2TR_TRIANGLE_GET_POINT(self,2)->c,
+      pt, u, v);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/triangle.h b/libs/poly2tri-c/poly2tri-c/refine/triangle.h
new file mode 100644
index 0000000..bb18cfa
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/triangle.h
@@ -0,0 +1,94 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_TRIANGLE_H__
+#define __P2TC_REFINE_TRIANGLE_H__
+
+#include <glib.h>
+#include "rmath.h"
+#include "triangulation.h"
+
+/**
+ * @struct P2trTriangle_
+ * A struct for a triangle in a triangular mesh
+ */
+struct P2trTriangle_
+{
+  P2trEdge* edges[3];
+  
+  guint refcount;
+};
+
+P2trTriangle*   p2tr_triangle_new            (P2trEdge *AB,
+                                              P2trEdge *BC,
+                                              P2trEdge *CA);
+
+P2trTriangle* p2tr_triangle_ref              (P2trTriangle *self);
+
+void        p2tr_triangle_unref              (P2trTriangle *self);
+
+void        p2tr_triangle_free               (P2trTriangle *self);
+
+void        p2tr_triangle_remove             (P2trTriangle *self);
+
+P2trMesh*   p2tr_triangle_get_mesh           (P2trTriangle *self);
+
+gboolean    p2tr_triangle_is_removed         (P2trTriangle *self);
+
+P2trPoint*  p2tr_triangle_get_opposite_point (P2trTriangle *self,
+                                              P2trEdge     *e,
+                                              gboolean      do_ref);
+
+P2trEdge*   p2tr_triangle_get_opposite_edge  (P2trTriangle *self,
+                                              P2trPoint    *p);
+
+gdouble     p2tr_triangle_get_angle_at       (P2trTriangle *self,
+                                              P2trPoint    *p);
+
+gdouble     p2tr_triangle_smallest_non_constrained_angle (P2trTriangle *self);
+
+void        p2tr_triangle_get_circum_circle (P2trTriangle *self,
+                                             P2trCircle   *circle);
+
+P2trInCircle p2tr_triangle_circumcircle_contains_point (P2trTriangle       *self,
+                                                        const P2trVector2  *pt);
+
+P2trInTriangle p2tr_triangle_contains_point  (P2trTriangle      *self,
+                                              const P2trVector2 *pt);
+
+P2trInTriangle p2tr_triangle_contains_point2 (P2trTriangle      *self,
+                                              const P2trVector2 *pt,
+                                              gdouble           *u,
+                                              gdouble           *v);
+
+#define P2TR_TRIANGLE_GET_POINT(tr,index) ((tr)->edges[((index)+3-1)%3]->end)
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/triangulation.h b/libs/poly2tri-c/poly2tri-c/refine/triangulation.h
new file mode 100644
index 0000000..4a93ac0
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/triangulation.h
@@ -0,0 +1,49 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_TRIANGULATION_H__
+#define __P2TC_REFINE_TRIANGULATION_H__
+
+/** \ingroup P2trPoint */
+typedef struct P2trPoint_     P2trPoint;
+/** \ingroup P2trEdge */
+typedef struct P2trEdge_      P2trEdge;
+/** \ingroup P2trTriangle */
+typedef struct P2trTriangle_  P2trTriangle;
+/** \ingroup P2trMesh */
+typedef struct P2trMesh_      P2trMesh;
+
+/** \ingroup P2trVEdge */
+typedef struct P2trVEdge_     P2trVEdge;
+/** \ingroup P2trVTriangle */
+typedef struct P2trVTriangle_ P2trVTriangle;
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/utils.c b/libs/poly2tri-c/poly2tri-c/refine/utils.c
new file mode 100644
index 0000000..d9d7db4
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/utils.c
@@ -0,0 +1,51 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <glib.h>
+
+#include "utils.h"
+
+GList*
+p2tr_utils_new_reversed_pointer_list (int count, ...)
+{
+  int i;
+  va_list args;
+  GList *result = NULL;
+  
+  va_start (args, count);
+  for (i = 0; i < count; i++)
+    result = g_list_prepend (result, va_arg (args, gpointer));
+  va_end (args);
+  
+  return result;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/utils.h b/libs/poly2tri-c/poly2tri-c/refine/utils.h
new file mode 100644
index 0000000..576476f
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/utils.h
@@ -0,0 +1,88 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_UTILS_H__
+#define __P2TC_REFINE_UTILS_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <glib.h>
+
+  /* The code for the Hash Set is partially based on the example given at
+   * http://developer.gnome.org/glib/2.29/glib-Hash-Tables.html
+   */
+
+  typedef GHashTable     P2trHashSet;
+  typedef GHashTableIter P2trHashSetIter;
+
+#define p2tr_hash_set_new_default() g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL)
+#define p2tr_hash_set_new(hash_func, equal_func, destroy) g_hash_table_new_full ((hash_func), (equal_func), (destroy),NULL)
+#define p2tr_hash_set_insert(set,element)                              \
+G_STMT_START                                                           \
+{                                                                      \
+  /* The "obvious" code (presented below) won't work:               */ \
+  /*   g_hash_table_insert ((set), (element), (element))            */ \
+  /* since it will cause double evaluation of (element) which is a  */ \
+  /* problem!                                                       */ \
+  gpointer P2TR_HASH_SET_ELEM = (element);                             \
+  g_hash_table_insert ((set), P2TR_HASH_SET_ELEM, P2TR_HASH_SET_ELEM); \
+}                                                                      \
+G_STMT_END
+#define p2tr_hash_set_contains(set,element) g_hash_table_lookup_extended ((set), (element), NULL, NULL)
+#define p2tr_hash_set_remove(set,element) g_hash_table_remove ((set), (element))
+#define p2tr_hash_set_remove_all(set) g_hash_table_remove_all ((set))
+#define p2tr_hash_set_free(set) g_hash_table_destroy(set)
+#define p2tr_hash_set_size(set) g_hash_table_size(set)
+
+#define p2tr_hash_set_iter_init(iter,hash_set) g_hash_table_iter_init ((iter),(hash_set))
+#define p2tr_hash_set_iter_next(iter,val) g_hash_table_iter_next ((iter),(val),NULL)
+#define p2tr_hash_set_iter_remove(iter) g_hash_table_iter_remove ((iter))
+
+#define g_list_cyclic_prev(list,elem) (((elem)->prev != NULL) ? (elem)->prev : g_list_last ((elem)))
+#define g_list_cyclic_next(list,elem) (((elem)->next != NULL) ? (elem)->next : g_list_first ((elem)))
+
+#define foreach(iter,list) for ((iter) = (list); (iter) != NULL; (iter) = (iter)->next)
+
+#define p2tr_exception_numeric      g_error
+#define p2tr_exception_programmatic g_error
+#define p2tr_exception_geometric    g_error
+
+GList*  p2tr_utils_new_reversed_pointer_list (int count, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/vector2.c b/libs/poly2tri-c/poly2tri-c/refine/vector2.c
new file mode 100644
index 0000000..b6e3359
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/vector2.c
@@ -0,0 +1,84 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include <glib.h>
+#include "vector2.h"
+
+gdouble
+p2tr_vector2_dot (const P2trVector2 *a,
+                  const P2trVector2 *b)
+{
+  return P2TR_VECTOR2_DOT (a, b);
+}
+
+gboolean
+p2tr_vector2_is_same (const P2trVector2 *a,
+                      const P2trVector2 *b)
+{
+  if (a == NULL || b == NULL)
+    return ! ((a == NULL) ^ (b == NULL));
+  else
+    return a->x == b->x && a->y == b->y;
+}
+
+void
+p2tr_vector2_sub (const P2trVector2 *a,
+                  const P2trVector2 *b,
+                  P2trVector2       *dest)
+{
+  dest->x = a->x - b->x;
+  dest->y = a->y - b->y;
+}
+
+void
+p2tr_vector2_center (const P2trVector2 *a,
+                     const P2trVector2 *b,
+                     P2trVector2       *dest)
+{
+  dest->x = (a->x + b->x) * 0.5;
+  dest->y = (a->y + b->y) * 0.5;
+}
+
+gdouble
+p2tr_vector2_norm (const P2trVector2 *v)
+{
+  return sqrt (P2TR_VECTOR2_LEN_SQ (v));
+}
+
+void
+p2tr_vector2_copy (P2trVector2       *dest,
+                   const P2trVector2 *src)
+{
+  dest->x = src->x;
+  dest->y = src->y;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/vector2.h b/libs/poly2tri-c/poly2tri-c/refine/vector2.h
new file mode 100644
index 0000000..0573da2
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/vector2.h
@@ -0,0 +1,101 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TR_REFINE_VECTOR2_H__
+#define __P2TR_REFINE_VECTOR2_H__
+
+#include <glib.h>
+
+/**
+ * \struct P2trVector2
+ * A struct for representing a vector with 2 coordinates (a point in 2D)
+ */
+typedef struct {
+  /** The first coordinate of the vector */
+  gdouble x;
+  /** The second coordinate of the vector */
+  gdouble y;
+} P2trVector2;
+
+#define P2TR_VECTOR2_LEN_SQ2(X, Y)              \
+    ((X) * (X) + (Y) * (Y))
+
+#define P2TR_VECTOR2_LEN_SQ(V)                  \
+    (P2TR_VECTOR2_LEN_SQ2((V)->x, (V)->y))
+
+#define P2TR_VECTOR2_DOT(V1,V2)                 \
+    ((V1)->x * (V2)->x + (V1)->y * (V2)->y)
+
+#define P2TR_VECTOR2_DISTANCE_SQ2(X1,Y1,X2,Y2)  \
+    (P2TR_VECTOR2_LEN_SQ2((X1) - (X2), (Y1) - (Y2)))
+
+#define P2TR_VECTOR2_DISTANCE_SQ(V1,V2)         \
+    (P2TR_VECTOR2_DISTANCE_SQ2((V1)->x, (V1)->y, (V2)->x, (V2)->y))
+
+/** Compute the dot product of two vectors */
+gdouble       p2tr_vector2_dot       (const P2trVector2 *a, const P2trVector2 *b);
+
+/** Check if all the coordinates of the two vectors are the same */
+gboolean      p2tr_vector2_is_same   (const P2trVector2 *a, const P2trVector2 *b);
+
+/**
+ * Compute the difference of two vectors
+ * @param[in] a The vector to subtract from
+ * @param[in] b The vector to be subtracted
+ * @param[out] dest The vector in which the result should be stored
+ */
+void          p2tr_vector2_sub       (const P2trVector2 *a, const P2trVector2 *b, P2trVector2 *dest);
+
+/**
+ * Compute the center point of the edge defined between two points
+ * @param[in] a The first side of the edge
+ * @param[in] b The second side of the edge
+ * @param[out] dest The vector in which the result should be stored
+ */
+void          p2tr_vector2_center    (const P2trVector2 *a, const P2trVector2 *b, P2trVector2 *dest);
+
+/**
+ * Compute the norm of a vector (the length of the line from the origin
+ * to the 2D point it represents)
+ * @param[in] v The vector whose norm should be computed
+ * @return The norm of the vector
+ */
+gdouble       p2tr_vector2_norm      (const P2trVector2 *v);
+
+/**
+ * Copy a vector
+ * @param[out] dest The destination of the copy operation
+ * @param[in] src The vector to copy
+ */
+void          p2tr_vector2_copy      (P2trVector2 *dest, const P2trVector2 *src);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/vedge.c b/libs/poly2tri-c/poly2tri-c/refine/vedge.c
new file mode 100644
index 0000000..74a6a31
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/vedge.c
@@ -0,0 +1,228 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <math.h>
+#include <glib.h>
+
+#include "point.h"
+#include "edge.h"
+#include "vedge.h"
+#include "mesh.h"
+
+static void
+p2tr_vedge_init (P2trVEdge *self,
+                 P2trPoint *start,
+                 P2trPoint *end,
+                 gboolean   constrained)
+{
+  self->start       = start;
+  self->end         = end;
+  self->constrained = constrained;
+  self->refcount    = 0;
+}
+
+P2trVEdge*
+p2tr_vedge_new (P2trPoint *start,
+                P2trPoint *end,
+                gboolean   constrained)
+{
+  P2trVEdge *self = g_slice_new (P2trVEdge);
+
+  p2tr_vedge_init (self, start, end, constrained);
+
+  p2tr_point_ref (start);
+  p2tr_point_ref (end);
+  
+  ++self->refcount;
+  return self;
+}
+
+P2trVEdge*
+p2tr_vedge_new2 (P2trEdge *real)
+{
+  return p2tr_vedge_new (P2TR_EDGE_START (real), real->end,
+      real->constrained);
+}
+
+P2trVEdge*
+p2tr_vedge_ref (P2trVEdge *self)
+{
+  ++self->refcount;
+  return self;
+}
+
+void
+p2tr_vedge_unref (P2trVEdge *self)
+{
+  g_assert (self->refcount > 0);
+  if (--self->refcount == 0)
+    p2tr_vedge_free (self);
+}
+
+P2trEdge*
+p2tr_vedge_is_real (P2trVEdge *self)
+{
+  return p2tr_point_has_edge_to (self->start, self->end);
+}
+
+void
+p2tr_vedge_create (P2trVEdge *self)
+{
+  P2trMesh *mesh;
+  P2trEdge *edge;
+
+  g_assert (! p2tr_vedge_is_real (self));
+
+  mesh = p2tr_vedge_get_mesh (self);
+  if (mesh != NULL)
+    {
+      edge = p2tr_mesh_new_edge (mesh, self->start, self->end, self->constrained);
+      p2tr_mesh_unref (mesh);
+    }
+  else
+    edge = p2tr_edge_new (self->start, self->end, self->constrained);
+
+  p2tr_edge_unref (edge);
+}
+
+void
+p2tr_vedge_remove (P2trVEdge *self)
+{
+  P2trEdge *edge = p2tr_vedge_is_real (self);
+
+  g_assert (edge != NULL);
+
+  p2tr_edge_remove (edge);
+}
+
+void
+p2tr_vedge_free (P2trVEdge *self)
+{
+  p2tr_point_unref (self->start);
+  p2tr_point_unref (self->end);
+  g_slice_free (P2trVEdge, self);
+}
+
+P2trMesh*
+p2tr_vedge_get_mesh (P2trVEdge *self)
+{
+  return p2tr_point_get_mesh (self->end);
+}
+
+P2trEdge*
+p2tr_vedge_get (P2trVEdge *self)
+{
+  return p2tr_point_get_edge_to (self->start, self->end, TRUE);
+}
+
+gboolean
+p2tr_vedge_try_get_and_unref (P2trVEdge  *self,
+                              P2trEdge  **real)
+{
+  P2trEdge *real_one = p2tr_vedge_is_real (self);
+  if (real_one)
+    p2tr_edge_ref (real_one);
+  p2tr_vedge_unref (self);
+  return (*real = real_one) != NULL;
+}
+
+P2trVEdgeSet*
+p2tr_vedge_set_new ()
+{
+  return p2tr_hash_set_new (
+      (GHashFunc)      p2tr_vedge_undirected_hash,
+      (GEqualFunc)     p2tr_vedge_undirected_equals,
+      NULL
+  );
+}
+
+void
+p2tr_vedge_set_add (P2trVEdgeSet *self,
+                   P2trEdge    *to_flip)
+{
+  p2tr_vedge_set_add2 (self, p2tr_vedge_new2 (to_flip));
+  p2tr_edge_unref (to_flip);
+}
+
+void
+p2tr_vedge_set_add2 (P2trVEdgeSet *self,
+                    P2trVEdge   *to_flip)
+{
+  if (p2tr_hash_set_contains (self, to_flip))
+    p2tr_vedge_unref (to_flip);
+  else
+    p2tr_hash_set_insert (self, to_flip);
+}
+
+gboolean
+p2tr_vedge_set_pop (P2trVEdgeSet  *self,
+                   P2trVEdge   **value)
+{
+  P2trHashSetIter iter;
+  p2tr_hash_set_iter_init (&iter, self);
+  if (p2tr_hash_set_iter_next (&iter, (gpointer*) value))
+    {
+      p2tr_hash_set_remove (self, *value);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+guint
+p2tr_vedge_set_size (P2trVEdgeSet *self)
+{
+  return p2tr_hash_set_size (self);
+}
+
+void
+p2tr_vedge_set_free (P2trVEdgeSet *self)
+{
+  g_assert (p2tr_hash_set_size (self) == 0);
+  p2tr_hash_set_free (self);
+}
+
+gboolean
+p2tr_vedge_undirected_equals (const P2trVEdge *e1,
+                              const P2trVEdge *e2)
+{
+  return ((e1 == NULL) == (e2 == NULL)) &&
+      (e1 == e2
+      || (e1->start == e2->start && e1->end == e2->end)
+      || (e1->end == e2->start && e1->start == e2->end));
+}
+
+guint
+p2tr_vedge_undirected_hash (const P2trVEdge *edge)
+{
+  return g_direct_hash (edge->start) ^ g_direct_hash (edge->end);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/vedge.h b/libs/poly2tri-c/poly2tri-c/refine/vedge.h
new file mode 100644
index 0000000..30f0e8f
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/vedge.h
@@ -0,0 +1,143 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_VEDGE_H__
+#define __P2TC_REFINE_VEDGE_H__
+
+#include <glib.h>
+#include "utils.h"
+#include "triangulation.h"
+
+/**
+ * @struct P2trVEdge_
+ * A struct for representing a potential ("virtual") edge in a
+ * triangular mesh
+ */
+struct P2trVEdge_
+{
+  /** The start point of this virtual edge */
+  P2trPoint *start;
+  /** The end point of this virtual edge */
+  P2trPoint *end;
+  /** A flag to make whether this is a constrained edge */
+  gboolean   constrained;
+  /** A count of references to the virtual edge */
+  guint      refcount;
+};
+
+P2trVEdge*  p2tr_vedge_new       (P2trPoint *start,
+                                  P2trPoint *end,
+                                  gboolean   constrained);
+
+P2trVEdge*  p2tr_vedge_new2      (P2trEdge  *real);
+
+P2trVEdge*  p2tr_vedge_ref       (P2trVEdge *self);
+
+void        p2tr_vedge_unref     (P2trVEdge *self);
+
+void        p2tr_vedge_free      (P2trVEdge *self);
+
+P2trMesh*   p2tr_vedge_get_mesh  (P2trVEdge *self);
+
+P2trEdge*   p2tr_vedge_is_real   (P2trVEdge *self);
+
+void        p2tr_vedge_create    (P2trVEdge *self);
+
+void        p2tr_vedge_remove    (P2trVEdge *self);
+
+P2trEdge*   p2tr_vedge_get       (P2trVEdge *self);
+
+/**
+ * Try get a real edge from a virtual edge, and then
+ * unref the virtual edge. IF A MATCHING REAL EDGE IS
+ * RETURNED, IT MUST BE UNREFFED BY THE CALLER!
+ * @param self The virtual edge to test
+ * @param real The place to store the matching real edge
+ * @return TRUE if a real edge was returned, FALSE if no
+ *         matching edge exists.
+ */
+gboolean    p2tr_vedge_try_get_and_unref (P2trVEdge  *self,
+                                          P2trEdge  **real);
+
+/**
+ * A set of edges to flip is basically a hash set, with unique equality
+ * and hashing function to prevent the same edge from appearing twice
+ * in different directions
+ */
+typedef P2trHashSet P2trVEdgeSet;
+
+/**
+ * Create a new flip-set - a set of virtual edges that should possibly
+ * be flipped to restore the Constrained Delaunay property to a
+ * triangulation
+*/
+P2trVEdgeSet* p2tr_vedge_set_new  ();
+
+/**
+ * Add the given edge to the flip set. THE EDGE MUST HAVE BEEN REFFED
+ * BEFORE THE CALL TO THIS FUNCTION!
+ */
+void         p2tr_vedge_set_add  (P2trVEdgeSet  *self,
+                                  P2trEdge      *to_flip);
+
+/**
+ * Add the given virtual edge to the flip set. THE VIRTUAL EDGE MUST
+ * HAVE BEEN REFFED BEFORE THE CALL TO THIS FUNCTION!
+ */
+void         p2tr_vedge_set_add2 (P2trVEdgeSet  *self,
+                                  P2trVEdge     *to_flip);
+
+/**
+ * Try popping a virtual edge from the set. If succeeds, THE RETURNED
+ * VIRTUAL EDGE MUST BE UNREFFED!
+ */
+gboolean     p2tr_vedge_set_pop  (P2trVEdgeSet  *self,
+                                  P2trVEdge    **value);
+
+/**
+ * Returns the amount of virtual edges currently in the set
+ */
+guint        p2tr_vedge_set_size (P2trVEdgeSet  *self);
+
+/**
+ * Free the flip set. IT IS THE REPONSIBILITY OF THE CALLER TO MAKE
+ * SURE NO VIRTUAL EDGES WERE LEFT IN THE SET!
+ */
+void         p2tr_vedge_set_free (P2trVEdgeSet  *self);
+
+gboolean     p2tr_vedge_undirected_equals (const P2trVEdge *e1,
+                                           const P2trVEdge *e2);
+
+guint        p2tr_vedge_undirected_hash   (const P2trVEdge *edge);
+
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/visibility.c b/libs/poly2tri-c/poly2tri-c/refine/visibility.c
new file mode 100644
index 0000000..eab71ed
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/visibility.c
@@ -0,0 +1,438 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Given a polygon "Poly" (a list of bounded lines), a point "P" and a
+ * a planar straight line graph (pslg) "PSLG", the question is if
+ * there is a straight line from "P" to some point in/on "Poly" so that
+ * the line does not intersect any of the lines of "PSLG".
+ *
+ * In this file is an algorithm for answering the above question, and
+ * it's pseudo-code is hereby presented:
+ *
+ * IsVisible(G, Poly, P):
+ * ----------------------
+ * { G = (V,E) - The PSLG where E is the set of edges in the graph   }
+ * { Poly      - A polygon (a list of edges)                         }
+ * { P         - The point we are checking whether is "visible" from }
+ * {             Poly                                                }
+ *
+ * W <- Some point in T (for example, center of weight)
+ *
+ * # A set of edges from @PSLG known to intersect some potential lines
+ * # from @P to @Poly
+ * KnownBlocks <- {}
+ *
+ * # A set of points on @Poly which should be checked whether a line
+ * # from them to @P is not obstructed by any of the edges of @PSLG
+ * SecondPoint <- {W}
+ *
+ * WHILE SecondPoint is not empty:
+ *
+ *   # Pick some point to check
+ *   S <- Some point from SecondPoint
+ *   SecondPoint <- SecondPoint \ {S}
+ *
+ *   PS <- The infinite line going through P and S
+ *
+ *   IF PS intersects @Poly:
+ *
+ *     IF there is an edge B=(u,v) (from E) that intersects PS so that
+ *        the intersection is between @Poly and @P:
+ *
+ *       IF B is not in KnownBlocks:
+ *         # Try new lines going through the end points of this edge
+ *         SecondPoint <- SecondPoint + {u,v}
+ *         KnownBlocks <- KnownBlocks + {B}
+ *
+ *       ELSE:
+ *         # Nothing to do - we already tried/are trying to handle this
+ *         # blocking edge by going around it
+ *       
+ *     ELSE:
+ *       RETURN "Visible"
+ *
+ *   ELSE:
+ *     # PS doesn't help anyway, no matter if it's blocked or not,
+ *     # since it does not reach the polygon
+ *
+ * RETURN "Ocluded"
+ */
+
+#include <glib.h>
+#include "bounded-line.h"
+#include "pslg.h"
+
+
+static gboolean
+find_closest_intersection (P2trPSLG    *pslg,
+                           P2trLine    *line,
+                           P2trVector2 *close_to,
+                           P2trVector2 *dest)
+{
+    gdouble distance_sq = G_MAXDOUBLE;
+    gboolean found = FALSE;
+
+    const P2trBoundedLine *pslg_line = NULL;
+    P2trPSLGIter pslg_iter;
+    P2trVector2 temp;
+
+    p2tr_pslg_iter_init (&pslg_iter, pslg);
+
+    while (p2tr_pslg_iter_next (&pslg_iter, &pslg_line))
+    {
+        if (p2tr_line_intersection (&pslg_line->infinite, line, &temp)
+            == P2TR_LINE_RELATION_INTERSECTING)
+        {
+            gdouble test_distance_sq = P2TR_VECTOR2_DISTANCE_SQ (&temp, close_to);
+
+            found = TRUE;
+
+            if (test_distance_sq < distance_sq)
+            {
+                distance_sq = test_distance_sq;
+            }
+        }
+    }
+
+    if (found && dest != NULL)
+        p2tr_vector2_copy (dest, &temp);
+
+    return found;
+}
+
+static void
+find_point_in_polygon (P2trPSLG    *polygon,
+                       P2trVector2 *out_point)
+{
+    P2trPSLGIter iter;
+    const P2trBoundedLine *line = NULL;
+
+    g_assert (p2tr_pslg_size (polygon) >= 1);
+
+    p2tr_pslg_iter_init (&iter, polygon);
+    p2tr_pslg_iter_next (&iter, &line);
+
+    out_point->x = (line->start.x + line->end.x) / 2;
+    out_point->y = (line->start.y + line->end.y) / 2;
+}
+
+#ifdef EXPERIMENTAL_VISIBILITY
+static P2trBoundedLine*
+pslg_line_intersection (P2trPSLG        *pslg,
+                        P2trBoundedLine *line)
+{
+    P2trPSLGIter iter;
+    P2trBoundedLine *pslg_line = NULL;
+
+    p2tr_pslg_iter_init (&iter, pslg);
+    while (p2tr_pslg_iter_next (&iter, &pslg_line))
+        if (p2tr_bounded_line_intersect (line, pslg_line))
+            return pslg_line;
+
+    return NULL;
+}
+
+gboolean
+p2tr_pslg_visibility_check (P2trPSLG    *pslg,
+                            P2trVector2 *point,
+                            P2trPSLG    *polygon)
+{
+    P2trPSLG *known_blocks;
+    GArray   *second_points;
+    gboolean  found_visibility_path = FALSE;
+
+    /* W <- Some point in T (for example, center of weight) */
+    P2trVector2 W;
+    find_point_in_polygon (polygon, &W);
+
+    /* KnownBlocks <- {} */
+    known_blocks = p2tr_pslg_new ();
+
+    /* SecondPoint <- {W} */
+    second_points   = g_array_new (FALSE, FALSE, sizeof(P2trVector2));
+    g_array_append_val (second_points, W);
+
+    while ((! found_visibility_path) && second_points->len > 0)
+    {
+        P2trVector2 S;
+        P2trBoundedLine PS;
+        P2trVector2 poly_intersection;
+
+        /* S <- Some point from SecondPoint */
+        p2tr_vector2_copy (&S, &g_array_index(second_points, P2trVector2, 0));
+        /* SecondPoint <- SecondPoint \ {S} */
+        g_array_remove_index_fast (second_points, 0);
+
+        /* PS <- The infinite line going through P and S */
+        p2tr_bounded_line_init (&PS, &S, point);
+
+        /* IF PS intersects @Poly */
+        if (find_closest_intersection (polygon, &PS.infinite, point, &poly_intersection))
+        {
+            P2trBoundedLine PS_exact, *B;
+
+            /* IF there is an edge B=(u,v) (from E) that intersects PS */
+            p2tr_bounded_line_init (&PS_exact, point, &poly_intersection);
+            B = pslg_line_intersection (pslg, &PS_exact);
+
+            if (B != NULL)
+            {
+                /* IF B is not in KnownBlocks: */
+                if (! p2tr_pslg_contains_line (known_blocks, B))
+                {
+                    /* SecondPoint <- SecondPoint + {u,v} */
+                    g_array_append_val (second_points, B->start);
+                    g_array_append_val (second_points, B->end);
+                    /* KnownBlocks <- KnownBlocks + {B} */
+                    p2tr_pslg_add_existing_line (known_blocks, B);
+                }
+            }
+            else
+            {
+                found_visibility_path = TRUE;
+            }
+        }
+    }
+
+    g_array_free (second_points, TRUE);
+    p2tr_pslg_free (known_blocks);
+
+    return found_visibility_path;
+}
+#else
+
+/* Refer to the "Ray casting algorithm":
+ *   http://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm
+ */
+static gboolean
+PointIsInsidePolygon (P2trVector2 *vec,
+		      P2trPSLG    *polygon)
+{
+  P2trHashSetIter iter;
+  const P2trBoundedLine *polyline = NULL;
+  int count = 0;
+
+  /* So, if we work on the X axis, what we want to check is how many
+   * segments of the polygon cross the line (-inf,y)->(x,y) */
+  p2tr_pslg_iter_init (&iter, polygon);
+  while (p2tr_pslg_iter_next (&iter, &polyline))
+    {
+      if ((polyline->start.y - vec->y) * (polyline->end.y - vec->y) >= 0)
+        continue; /* The line doesn't cross the horizontal line Y = vec->y */
+      if (MIN (polyline->start.x, polyline->end.x) <= vec->x)
+        count++;
+    }
+  return (count % 2) == 1;
+}
+
+/* If the bounded line intersects the polygon in more than two places,
+ * then the answer is simply NO - the line is not completly outside the
+ * polygon.
+ * Else, if the bounded line intersects the polygon twice, we analyze
+ * its end points and middle point:
+ * - If both end-points are inside/on:
+ *   - Test the midpoint - it it's inside then the line goes inside the
+ *     polygon, otherwise it goes outside (remember, we said it
+ *     intersects the polygon exactly twice!)
+ * - Otherwise, there must be a subsegment of the poly-line which is
+ *   partially inside!
+ * Else, if it intersects exactly once:
+ * - If both end-points are inside/on then it's partially inside.
+ * - If exactly one end-points is inside/on then decide by the middle
+ *   point (if it's partially inside then so is the line)
+ * - If both end-points are outside - CAN'T HAPPEN WITH EXACTLY ONE INTERSECTION!
+ * Else, if it does not intersect:
+ * - Test any point inside the bounded line (end-points, middle points,
+ *   etc.). If it's inside then the bounded line is inside. Otherwise
+ *   it is outside
+ */
+static gboolean
+LineIsOutsidePolygon (P2trBoundedLine *line,
+                      P2trPSLG        *polygon)
+{
+  P2trHashSetIter iter;
+  const P2trBoundedLine *polyline = NULL;
+  P2trVector2 middle;
+  gint intersection_count = 0, inside_count = 0;
+
+  p2tr_pslg_iter_init (&iter, polygon);
+  while (p2tr_pslg_iter_next (&iter, &polyline))
+    {
+      if (p2tr_bounded_line_intersect (polyline, line))
+        if (++intersection_count > 2)
+          return FALSE;
+    }
+
+  inside_count += (PointIsInsidePolygon (&line->start, polygon) ? 1 : 0); 
+  inside_count += (PointIsInsidePolygon (&line->end, polygon) ? 1 : 0); 
+  
+  /* To decrease the chance of numeric errors when working on the edge points of
+   * the line, the point we will test is the middle of the input line */
+  middle.x = (line->start.x + line->end.x) / 2;
+  middle.y = (line->start.y + line->end.y) / 2;
+
+  if (intersection_count == 2)
+    {
+      if (inside_count == 2) return PointIsInsidePolygon (&middle, polygon);
+      else return TRUE;
+    }
+  else if (intersection_count == 1)
+    {
+      if (inside_count == 2) return TRUE;
+      else return PointIsInsidePolygon (&middle, polygon);
+    }
+  else return inside_count > 0;
+}
+
+static gboolean
+TryVisibilityAroundBlock(P2trPSLG        *PSLG,
+                         P2trVector2     *P,
+                         P2trPSLG        *ToSee,
+                         P2trPSLG        *KnownBlocks,
+                         GQueue          *BlocksForTest,
+                         /* Try on the edges of this block */
+                         const P2trBoundedLine *BlockBeingTested,
+                         const P2trVector2     *SideOfBlock)
+{
+  const P2trVector2 *S = SideOfBlock;
+  P2trVector2 ClosestIntersection;
+  P2trBoundedLine PS;
+  
+  p2tr_bounded_line_init (&PS, P, S);
+
+  if (find_closest_intersection (ToSee, &PS.infinite, P, &ClosestIntersection))
+    {
+      P2trPSLGIter iter;
+      P2trBoundedLine PK;
+      const P2trBoundedLine *Segment = NULL;
+      p2tr_bounded_line_init (&PK, P, &ClosestIntersection);
+
+      /* Now we must make sure that the bounded line PK is inside
+       * the polygon, because otherwise it is not considered as a
+       * valid visibility path */
+
+      p2tr_pslg_iter_init (&iter, PSLG);
+      while (p2tr_pslg_iter_next (&iter, &Segment))
+        {
+          if (Segment == BlockBeingTested)
+              continue;
+
+          /* If we have two segments with a shared point,
+           * the point should not be blocked by any of them
+           */
+          if (p2tr_vector2_is_same (SideOfBlock, &(Segment->start))
+              || p2tr_vector2_is_same (SideOfBlock, &(Segment->end)))
+              continue;
+
+          if (p2tr_bounded_line_intersect (Segment, &PK))
+            {
+              if (g_queue_find (BlocksForTest, Segment))
+                {
+                  g_queue_push_tail (BlocksForTest, (P2trBoundedLine*)Segment);
+                }
+              /* obstruction found! */
+              return FALSE;
+            }
+        }
+
+      if (LineIsOutsidePolygon (&PK, PSLG))
+        return FALSE;
+
+      /* No obstruction! */
+      return TRUE;
+    }
+  /* No intersection for this attempt, continue */
+  return FALSE;
+}
+
+/**
+ * Check if a point is "visible" from any one or more of the edges in a
+ * given group.
+ * Formally: Check if there is a line from @ref P to any of the edges in
+ * @ref Edges so that the line does not cross any of the lines of the
+ * PSLG @ref PSLG
+ */
+gboolean
+IsVisibleFromEdges (P2trPSLG    *PSLG,
+                   P2trVector2 *P,
+                   P2trPSLG    *Edges)
+{
+    gboolean  found_visibility_path = FALSE;
+    P2trPSLG *KnownBlocks = p2tr_pslg_new ();
+    GQueue   *BlocksForTest = g_queue_new ();
+
+    P2trVector2 W;
+    find_point_in_polygon (Edges, &W);
+
+    if (TryVisibilityAroundBlock(PSLG, P, Edges, KnownBlocks, BlocksForTest, NULL, &W))
+        found_visibility_path = TRUE;
+
+    while (! g_queue_is_empty (BlocksForTest) && ! found_visibility_path)
+      {
+        const P2trBoundedLine *Block = (P2trBoundedLine*)g_queue_pop_head (BlocksForTest);
+
+        if (p2tr_pslg_contains_line (KnownBlocks, Block))
+            continue;
+        else if (TryVisibilityAroundBlock(PSLG, P, Edges, KnownBlocks, BlocksForTest, Block, &Block->start)
+            || TryVisibilityAroundBlock(PSLG, P, Edges, KnownBlocks, BlocksForTest, Block, &Block->end))
+          {
+            found_visibility_path = TRUE;
+          }
+        else
+            p2tr_pslg_add_existing_line (KnownBlocks, Block);
+      }
+
+    p2tr_pslg_free (KnownBlocks);
+    g_queue_free (BlocksForTest);
+
+    return found_visibility_path;
+}
+#endif
+
+gboolean
+p2tr_visibility_is_visible_from_edges (P2trPSLG              *pslg,
+                                       P2trVector2           *p,
+                                       const P2trBoundedLine *lines,
+                                       guint                  line_count)
+{
+  P2trPSLG *edges = p2tr_pslg_new ();
+  gint i;
+  gboolean result;
+  
+  for (i = 0; i < line_count; i++)
+    p2tr_pslg_add_existing_line (edges, &lines[i]);
+  
+  result = IsVisibleFromEdges (pslg, p, edges);
+  
+  p2tr_pslg_free (edges);
+  return result;
+}
diff --git a/libs/poly2tri-c/poly2tri-c/refine/visibility.h b/libs/poly2tri-c/poly2tri-c/refine/visibility.h
new file mode 100644
index 0000000..3109b9b
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/visibility.h
@@ -0,0 +1,46 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_VISIBILITY_H__
+#define __P2TC_REFINE_VISIBILITY_H__
+
+#include <glib.h>
+
+#include "bounded-line.h"
+#include "vector2.h"
+#include "pslg.h"
+
+gboolean  p2tr_visibility_is_visible_from_edges (P2trPSLG              *pslg,
+                                                 P2trVector2           *p,
+                                                 const P2trBoundedLine *lines,
+                                                 guint                  line_count);
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/refine/vtriangle.c b/libs/poly2tri-c/poly2tri-c/refine/vtriangle.c
new file mode 100644
index 0000000..e213372
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/vtriangle.c
@@ -0,0 +1,145 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+
+#include "point.h"
+#include "edge.h"
+#include "triangle.h"
+#include "mesh.h"
+
+#include "vtriangle.h"
+
+P2trVTriangle*
+p2tr_vtriangle_new (P2trTriangle *tri)
+{
+  P2trVTriangle *self = g_slice_new (P2trVTriangle);
+
+  self->points[0] = p2tr_point_ref (tri->edges[0]->end);
+  self->points[1] = p2tr_point_ref (tri->edges[1]->end);
+  self->points[2] = p2tr_point_ref (tri->edges[2]->end);
+
+  self->refcount = 1;
+
+  return self;
+}
+
+P2trVTriangle*
+p2tr_vtriangle_ref (P2trVTriangle *self)
+{
+  ++self->refcount;
+  return self;
+}
+
+void
+p2tr_vtriangle_unref (P2trVTriangle *self)
+{
+  g_assert (self->refcount > 0);
+  if (--self->refcount == 0)
+    p2tr_vtriangle_free (self);
+}
+
+void
+p2tr_vtriangle_free (P2trVTriangle *self)
+{
+  p2tr_point_unref (self->points[0]);
+  p2tr_point_unref (self->points[1]);
+  p2tr_point_unref (self->points[2]);
+  g_slice_free (P2trVTriangle, self);
+}
+
+P2trMesh*
+p2tr_vtriangle_get_mesh (P2trVTriangle *self)
+{
+  return p2tr_point_get_mesh (self->points[0]);
+}
+
+P2trTriangle*
+p2tr_vtriangle_is_real (P2trVTriangle *self)
+{
+  P2trEdge *e0, *e1, *e2;
+
+  /* The triangle exists if and only if all the edges
+   * still exist and they all are a part of the same
+   * triangle. */
+  if ((e0 = p2tr_point_has_edge_to (self->points[0], self->points[1])) &&
+      (e1 = p2tr_point_has_edge_to (self->points[1], self->points[2])) &&
+      (e2 = p2tr_point_has_edge_to (self->points[2], self->points[0])) &&
+      e0->tri == e1->tri && e1->tri == e2->tri)
+    return e0->tri;
+  else
+    return NULL;
+}
+
+void
+p2tr_vtriangle_create (P2trVTriangle *self)
+{
+  P2trMesh     *mesh;
+  P2trEdge     *e1, *e2, *e3;
+  P2trTriangle *tri;
+
+  g_assert (! p2tr_vtriangle_is_real (self));
+
+  mesh = p2tr_vtriangle_get_mesh (self);
+  e1 = p2tr_point_get_edge_to (self->points[0], self->points[1], FALSE);
+  e2 = p2tr_point_get_edge_to (self->points[1], self->points[2], FALSE);
+  e3 = p2tr_point_get_edge_to (self->points[2], self->points[0], FALSE);
+
+  if (mesh != NULL)
+    {
+      tri = p2tr_mesh_new_triangle (mesh, e1, e2, e3);
+      p2tr_mesh_unref (mesh);
+    }
+  else
+    tri = p2tr_triangle_new (e1, e2, e3);
+
+  p2tr_triangle_unref (tri);
+}
+
+void
+p2tr_vtriangle_remove (P2trVTriangle *self)
+{
+  P2trTriangle *tri = p2tr_vtriangle_is_real (self);
+
+  g_assert (tri != NULL);
+
+  p2tr_triangle_remove (tri);
+}
+
+P2trTriangle*
+p2tr_vtriangle_get (P2trVTriangle *self)
+{
+  P2trTriangle *real = p2tr_vtriangle_is_real (self);
+  g_assert (real != NULL);
+  return p2tr_triangle_ref (real);
+}
+
diff --git a/libs/poly2tri-c/poly2tri-c/refine/vtriangle.h b/libs/poly2tri-c/poly2tri-c/refine/vtriangle.h
new file mode 100644
index 0000000..5e63251
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/refine/vtriangle.h
@@ -0,0 +1,70 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_REFINE_VTRIANGLE_H__
+#define __P2TC_REFINE_VTRIANGLE_H__
+
+#include <glib.h>
+#include "rmath.h"
+#include "triangulation.h"
+
+/**
+ * @struct P2trVTriangle_
+ * A struct for representing a potential ("virtual") triangle
+ * in a triangular mesh
+ */
+struct P2trVTriangle_
+{
+  P2trPoint* points[3];
+  
+  guint refcount;
+};
+
+P2trVTriangle*   p2tr_vtriangle_new          (P2trTriangle  *tri);
+
+P2trVTriangle*   p2tr_vtriangle_ref          (P2trVTriangle *self);
+
+void             p2tr_vtriangle_unref        (P2trVTriangle *self);
+
+void             p2tr_vtriangle_free         (P2trVTriangle *self);
+
+P2trMesh*        p2tr_vtriangle_get_mesh     (P2trVTriangle *self);
+
+P2trTriangle*    p2tr_vtriangle_is_real      (P2trVTriangle *self);
+
+void             p2tr_vtriangle_create       (P2trVTriangle *self);
+
+void             p2tr_vtriangle_remove       (P2trVTriangle *self);
+
+P2trTriangle*    p2tr_vtriangle_get          (P2trVTriangle *self);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/render/Makefile.am b/libs/poly2tri-c/poly2tri-c/render/Makefile.am
new file mode 100644
index 0000000..8c02ec3
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/render/Makefile.am
@@ -0,0 +1,6 @@
+noinst_LTLIBRARIES = libp2tc-render.la
+
+libp2tc_render_la_SOURCES = mesh-render.c mesh-render.h svg-plot.c svg-plot.h
+
+P2TC_RENDER_publicdir = $(P2TC_publicdir)/render
+P2TC_RENDER_public_HEADERS = mesh-render.h svg-plot.h
diff --git a/libs/poly2tri-c/poly2tri-c/render/mesh-render.c b/libs/poly2tri-c/poly2tri-c/render/mesh-render.c
new file mode 100644
index 0000000..13f78db
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/render/mesh-render.c
@@ -0,0 +1,273 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <poly2tri-c/refine/refine.h>
+#include "mesh-render.h"
+
+/* This function implements box logic to see if a point is contained in a
+ * triangles bounding box. This is very useful for cases where there are many
+ * triangles to test against a single point, and most of them aren't even near
+ * it.
+ *
+ * Instead of finding the Xmin, Xmax, Ymin, Ymax and checking if the the point
+ * is outside, just check if the point is on the SAME SIDE compared to all the
+ * points of the triangle.
+ * See http://lightningismyname.blogspot.com/2011/08/quickboxa-quick-point-in-triangle-test.html
+ */
+gboolean
+p2tr_triangle_quick_box_test (P2trTriangle *self,
+                               gdouble       Px,
+                               gdouble       Py)
+{
+  P2trPoint *A = P2TR_TRIANGLE_GET_POINT (self, 0);
+  P2trPoint *B = P2TR_TRIANGLE_GET_POINT (self, 1);
+  P2trPoint *C = P2TR_TRIANGLE_GET_POINT (self, 2);
+
+  register gboolean xPBorder = B->c.x <= Px;
+  register gboolean yPBorder = B->c.y <= Py;
+
+  return (((A->c.x <= Px) == xPBorder) && (xPBorder == (C->c.x <= Px)))
+          || (((A->c.y <= Py) == yPBorder) && (yPBorder == (C->c.y <= Py)));
+}
+
+void
+p2tr_mesh_render_cache_uvt (P2trMesh        *T,
+                            P2trUVT         *dest,
+                            P2trImageConfig *config)
+{
+  p2tr_mesh_render_cache_uvt_exact (T, dest, config->x_samples * config->y_samples, config);
+}
+
+void
+p2tr_mesh_render_cache_uvt_exact (P2trMesh        *T,
+                                  P2trUVT         *dest,
+                                  gint             dest_len,
+                                  P2trImageConfig *config)
+{
+  gint x, y, n = dest_len;
+  P2trUVT *uvt = dest;
+  P2trTriangle *tr_prev = NULL;
+  P2trVector2 pt;
+  
+  pt.x = config->min_x;
+  pt.y = config->min_y;
+
+  uvt->tri = p2tr_mesh_find_point_local2 (T, &pt, NULL, &uvt->u, &uvt->v);
+  if (uvt->tri) p2tr_triangle_unref (uvt->tri);
+  tr_prev = uvt->tri;
+  
+  for (y = 0, pt.y = config->min_y; y < config->y_samples; ++y, pt.y += config->step_y)
+    for (x = 0, pt.x = config->min_x; x < config->x_samples; ++x, pt.x += config->step_x)
+      {
+        if (n-- == 0) return;
+        uvt->tri = p2tr_mesh_find_point_local2 (T, &pt, tr_prev, &uvt->u, &uvt->v);
+        if (uvt->tri) p2tr_triangle_unref (uvt->tri);
+        tr_prev = uvt->tri;
+        ++uvt;
+      }
+}
+
+#define P2TR_USE_BARYCENTRIC(u, v, A, B, C)                            \
+    ((A) + (v) * ((B) - (A)) + (u) * ((C) - (A)))
+
+/**
+ * This is a general macro for using a UVT cache in order to render a
+ * color interpolation triangular mesh. The reason this is a macro and
+ * not a function is to allow using different numeric types for
+ * representing colors
+ * @param uvt_cache The buffer containing the UVT cache of the area to
+ *        render. Should be of type  @ref P2trUVT*
+ * @param uvt_cache_w The width of the area for which the UVT cache was
+ *        created. Should be a positive integer.
+ * @param uvt_cache_h The height of the area for which the UVT cache was
+ *        created. Should be a positive integer.
+ * @param dest The buffer in which the rendering result should be saved.
+ *        Should be of type @ref cformat*
+ * @param n The amount of pixels to render into dest. Should be a
+ *        positive integer.
+ * @param cformat The type of the data inside @ref dest. This can be any
+ *        numeric type (double, float, int, ...)
+ * @param cpp The amount of color channels per pixel, not including the
+ *        alpha channel. Should be a positive integer.
+ * @param pt2col The function which maps mesh points into colors. This
+ *        function should be deterministic!
+ * @param pt2col_user_data An additional parameter to @ref pt2col
+ * @param alpha_last Specifies whether the alpha component should come
+ *        after or before the other color channels. Should be a boolean.
+ */
+#define P2TR_MESH_RENDER_FROM_CACHE(uvt_cache,                         \
+                                    uvt_cache_w,                       \
+                                    uvt_cache_h,                       \
+                                    dest,                              \
+                                    n,                                 \
+                                    cformat,                           \
+                                    cpp,                               \
+                                    pt2col,                            \
+                                    pt2col_user_data,                  \
+                                    alpha_last)                        \
+G_STMT_START                                                           \
+{                                                                      \
+  P2trUVT *uvt_p = (uvt_cache);                                        \
+  guint remain = n;                                                    \
+                                                                       \
+  P2trTriangle *tr_prev = NULL;                                        \
+  guint x, y, i;                                                       \
+  P2trPointToColorFuncC pt2col_c = (P2trPointToColorFuncC) (pt2col); \
+                                                                       \
+  cformat *colA = g_newa (cformat, (cpp));                             \
+  cformat *colB = g_newa (cformat, (cpp));                             \
+  cformat *colC = g_newa (cformat, (cpp));                             \
+                                                                       \
+  cformat *pixel = dest;                                               \
+                                                                       \
+  for (y = 0; y < (uvt_cache_w) && remain > 0; ++y)                    \
+    for (x = 0; x < (uvt_cache_h) && remain > 0; ++x, --remain, ++uvt_p) \
+      {                                                                \
+        P2trTriangle *tr_now = uvt_p->tri;                             \
+                                                                       \
+        /* If we are outside of the triangulation, set alpha to   */   \
+        /* zero and continue */                                        \
+        if (tr_now == NULL)                                            \
+          {                                                            \
+            /* Remember that cpp does not include the alpha! */        \
+            pixel[(alpha_last) ? (cpp) : 0] = 0;                       \
+            pixel += cpp + 1;                                          \
+          }                                                            \
+        else                                                           \
+          {                                                            \
+            gdouble u = uvt_p->u;                                      \
+            gdouble v = uvt_p->v;                                      \
+            /* If the triangle hasn't changed since the previous  */   \
+            /* pixel, then don't sample the color at the vertices */   \
+            /* again, since that is an expensive process!         */   \
+            if (tr_now != tr_prev)                                     \
+              {                                                        \
+                /* Get the points of the triangle in some fixed   */   \
+                /* order, just to make sure that the computation  */   \
+                /* goes the same everywhere                       */   \
+                P2trPoint *A = P2TR_TRIANGLE_GET_POINT (tr_now, 0);    \
+                P2trPoint *B = P2TR_TRIANGLE_GET_POINT (tr_now, 1);    \
+                P2trPoint *C = P2TR_TRIANGLE_GET_POINT (tr_now, 2);    \
+                /* At each point 'X' sample the color into 'colX' */   \
+                pt2col_c (A, (gpointer) colA, pt2col_user_data);       \
+                pt2col_c (B, (gpointer) colB, pt2col_user_data);       \
+                pt2col_c (C, (gpointer) colC, pt2col_user_data);       \
+                /* Set the current triangle */                         \
+                tr_now = tr_prev;                                      \
+              }                                                        \
+                                                                       \
+            /* We are inside the mesh, so set as opaque */             \
+            if (! alpha_last) *pixel++ = (cformat) 1;                  \
+            /* Interpolate the color using barycentric coodinates */   \
+            for (i = 0; i < cpp; ++i)                                  \
+              *pixel++ = (cformat) P2TR_USE_BARYCENTRIC (u, v,         \
+                  colA[i], colB[i], colC[i]);                          \
+            /* We are inside the mesh, so set as opaque */             \
+            if (alpha_last) *pixel++ = (cformat) 1;                    \
+          }                                                            \
+      }                                                                \
+}                                                                      \
+G_STMT_END
+
+#define P2TR_MESH_RENDER(mesh,                                         \
+                         dest,                                         \
+                         config,                                       \
+                         pt2col,                                       \
+                         pt2col_user_data,                             \
+                         cache_render_func)                            \
+G_STMT_START                                                           \
+{                                                                      \
+  gint n = (config)->x_samples * (config)->y_samples;                  \
+  P2trUVT *uvt_cache = g_new (P2trUVT, n);                             \
+                                                                       \
+  p2tr_mesh_render_cache_uvt_exact ((mesh), uvt_cache, n, (config));   \
+  cache_render_func (uvt_cache, (dest), n, (config), (pt2col),         \
+      (pt2col_user_data));                                             \
+                                                                       \
+  g_free (uvt_cache);                                                  \
+}                                                                      \
+G_STMT_END
+
+void
+p2tr_mesh_render_from_cache_f (P2trUVT               *uvt_cache,
+                               gfloat                *dest,
+                               gint                   n,
+                               P2trImageConfig       *config,
+                               P2trPointToColorFuncF  pt2col,
+                               gpointer               pt2col_user_data)
+{
+  P2TR_MESH_RENDER_FROM_CACHE (uvt_cache,
+      config->x_samples, config->y_samples,
+      dest, n, gfloat, config->cpp,
+      pt2col, pt2col_user_data,
+      config->alpha_last);
+}
+
+void
+p2tr_mesh_render_f (P2trMesh              *mesh,
+                    gfloat                *dest,
+                    P2trImageConfig       *config,
+                    P2trPointToColorFuncF  pt2col,
+                    gpointer               pt2col_user_data)
+{
+  P2TR_MESH_RENDER (mesh, dest, config, pt2col, pt2col_user_data,
+      p2tr_mesh_render_from_cache_f);
+}
+
+void
+p2tr_mesh_render_from_cache_b (P2trUVT               *uvt_cache,
+                               guint8                *dest,
+                               gint                   n,
+                               P2trImageConfig       *config,
+                               P2trPointToColorFuncB  pt2col,
+                               gpointer               pt2col_user_data)
+{
+  P2TR_MESH_RENDER_FROM_CACHE (uvt_cache,
+      config->x_samples, config->y_samples,
+      dest, n, guint8, config->cpp,
+      pt2col, pt2col_user_data,
+      config->alpha_last);
+}
+
+void
+p2tr_mesh_render_b (P2trMesh              *mesh,
+                    guint8                *dest,
+                    P2trImageConfig       *config,
+                    P2trPointToColorFuncB  pt2col,
+                    gpointer               pt2col_user_data)
+{
+  P2TR_MESH_RENDER (mesh, dest, config, pt2col, pt2col_user_data,
+      p2tr_mesh_render_from_cache_b);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/render/mesh-render.h b/libs/poly2tri-c/poly2tri-c/render/mesh-render.h
new file mode 100644
index 0000000..9a1d63c
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/render/mesh-render.h
@@ -0,0 +1,175 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TR_RENDER_MESH_RENDER_H__
+#define __P2TR_RENDER_MESH_RENDER_H__
+
+#include <glib.h>
+#include <poly2tri-c/refine/refine.h>
+
+/**
+ * A struct containing the necessary information to render a "color
+ * image" of a triangular mesh, by interpolating "colors" between its
+ * points.
+ * This can in fact be used to interpolate any N-Dimensional value set
+ * along the triangles of a mesh.
+ */
+typedef struct {
+  /** Minimal X and Y coordinates to start sampling at */
+  gdouble min_x, min_y;
+  /** Size of a step (distance between samples) in each axis */
+  gdouble step_x, step_y;
+  /** The amount of samples desired in each axis */
+  guint x_samples, y_samples;
+  /**
+   * The amount of channels per "pixel", both in the destination buffer
+   * and in the colors returned from the matching point-to-color
+   * function. Note that this does not include the alpha channel!
+   */
+  guint cpp;
+  /**
+   * Specifies whether the alpha channel (0 outside the mesh, 1 inside)
+   * should come after or before the the channel colors
+   */
+  gboolean alpha_last;
+} P2trImageConfig;
+
+/**
+ * A function that maps mesh points into colors
+ * @param point The mesh point
+ * @param dest The destination buffer for the color components, where
+ *        each component is one unsigned byte (guint8)
+ * @param user_data Custom data passed as a pointer to the function
+ */
+typedef void (*P2trPointToColorFuncB)   (P2trPoint            *point,
+                                         guint8               *dest,
+                                         gpointer              user_data);
+
+/**
+ * Similar to @ref P2trPointToColorFuncB, but with floating point data
+ * types for each color component
+ */
+typedef void (*P2trPointToColorFuncF)   (P2trPoint            *point,
+                                         gfloat               *dest,
+                                         gpointer              user_data);
+
+/**
+ * A generalization of all the point-to-color functions. This is used
+ * only for type casting inside the library and should not be used
+ * externally.
+ */
+typedef void (*P2trPointToColorFuncC)   (P2trPoint            *point,
+                                         void                 *dest,
+                                         gpointer              user_data);
+
+/**
+ * A struct for caching the barycentric coordinates of a point inside
+ * a triangle. A buffer of these structs is referred to as a UVT cache.
+ */
+typedef struct {
+  gdouble       u;
+  gdouble       v;
+  P2trTriangle *tri;
+} P2trUVT;
+
+/**
+ * Compute the UVT cache for the given mesh for the area and resolution
+ * specified by the image configuration struct. The cache for the point
+ * (min_x + i * step_x, min_y + j * step_y) would be at the index
+ * j * x_samples + i (assuming of course the point is inside the area
+ * described by image configuration struct).
+ */
+void   p2tr_mesh_render_cache_uvt       (P2trMesh             *mesh,
+                                         P2trUVT              *dest,
+                                         P2trImageConfig      *config);
+
+/**
+ * Similar to @ref p2tr_mesh_render_cache_uvt, but cache only the
+ * first @ref dest_len pixels.
+ */
+void   p2tr_mesh_render_cache_uvt_exact (P2trMesh             *mesh,
+                                         P2trUVT              *dest,
+                                         gint                  dest_len,
+                                         P2trImageConfig      *config);
+
+/**
+ * Render a mesh using a UVT cache that was computed for the given
+ * area, together with a point-to-color function.
+ * @param uvt_cache A cache for the given area, computed with
+ *        @ref p2tr_mesh_render_cache_uvt_exact
+ * @param dest The destination buffer for the image
+ * @param dest_len How many pixels to render from the area. The cache
+ *        should contain data for at least this many pixels!
+ * @param config The render configuration struct
+ * @param pt2col A function that receives points in the mesh and returns
+ *        colors. The returned colors should have config->cpp components
+ * @param pt2col_user_data Custom data to pass to @ref pt2col
+ */
+void   p2tr_mesh_render_from_cache_f    (P2trUVT               *uvt_cache,
+                                         gfloat                *dest,
+                                         gint                   dest_len,
+                                         P2trImageConfig       *config,
+                                         P2trPointToColorFuncF  pt2col,
+                                         gpointer               pt2col_user_data);
+
+/**
+ * Render a mesh with the given area and sampling configuration. Same
+ * as first caching @ref p2tr_mesh_render_cache_uvt and then calling
+ * @ref p2tr_mesh_render_cache_uvt_exact with the cache, and finally
+ * freeing the cache
+ */
+void   p2tr_mesh_render_f               (P2trMesh              *mesh,
+                                         gfloat                *dest,
+                                         P2trImageConfig       *config,
+                                         P2trPointToColorFuncF  pt2col,
+                                         gpointer               pt2col_user_data);
+
+/**
+ * See @ref p2tr_mesh_render_from_cache_f
+ */
+void   p2tr_mesh_render_from_cache_b    (P2trUVT               *uvt_cache,
+                                         guint8                *dest,
+                                         gint                   dest_len,
+                                         P2trImageConfig       *config,
+                                         P2trPointToColorFuncB  pt2col,
+                                         gpointer               pt2col_user_data);
+
+/**
+ * See @ref p2tr_mesh_render_f
+ */
+void   p2tr_mesh_render_b               (P2trMesh              *mesh,
+                                         guint8                *dest,
+                                         P2trImageConfig       *config,
+                                         P2trPointToColorFuncB  pt2col,
+                                         gpointer               pt2col_user_data);
+
+#endif
diff --git a/libs/poly2tri-c/poly2tri-c/render/svg-plot.c b/libs/poly2tri-c/poly2tri-c/render/svg-plot.c
new file mode 100644
index 0000000..66f636c
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/render/svg-plot.c
@@ -0,0 +1,204 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <glib.h>
+
+#include <poly2tri-c/refine/triangulation.h>
+
+#include "svg-plot.h"
+
+#define P2TR_SVG_NEWLINE "\n"
+
+void
+p2tr_render_svg_init (FILE              *out,
+                      const P2trVector2 *bottom_left,
+                      const P2trVector2 *top_right)
+{
+  gdouble real_width = top_right->x - bottom_left->x;
+  gdouble real_height = top_right->y - bottom_left->y;
+
+  /* Begin with the header of the document */
+  fprintf (out, "<?xml version=\"1.0\" standalone=\"no\"?>%s",
+      P2TR_SVG_NEWLINE);
+  fprintf (out, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"%s",
+      P2TR_SVG_NEWLINE);
+  fprintf (out, "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\";>%s",
+      P2TR_SVG_NEWLINE);
+
+  fprintf (out, "<svg xmlns=\"http://www.w3.org/2000/svg\"";
+                "     version=\"1.1\"%s", P2TR_SVG_NEWLINE);
+
+  fprintf (out, "     viewBox=\"%f %f %f %f\"%s",
+      + bottom_left->x, - (bottom_left->y + real_height),
+      + real_width,     + real_height,
+      P2TR_SVG_NEWLINE);
+
+  fprintf (out, "     preserveAspectRatio=\"xMidYMid meet\"%s",
+      P2TR_SVG_NEWLINE);
+
+  /* Close the SVG tag */
+  fprintf (out, ">%s", P2TR_SVG_NEWLINE);
+
+  fprintf (out, "<g transform=\"scale(1,-1)\">%s",
+      P2TR_SVG_NEWLINE);
+}
+
+void
+p2tr_render_svg_finish (FILE *out)
+{
+  fprintf (out, "</g>%s", P2TR_SVG_NEWLINE);
+  fprintf (out, "</svg>%s", P2TR_SVG_NEWLINE);
+}
+
+static void
+p2tr_render_svg_style (FILE           *out,
+                       P2trSVGContext *context,
+                       gboolean        no_fill)
+{
+  fprintf (out, "style=\"");
+    {
+      if (context->stroke)
+        {
+          fprintf (out, "stroke: #%02x%02x%02x; stroke-opacity: %f; ",
+              context->stroke_color[0], context->stroke_color[1],
+              context->stroke_color[2], context->stroke_color[3] / 255.0);
+          fprintf (out, "stroke-:width: %f; stroke-linejoin: round; ",
+              context->stroke_width);
+        }
+
+      if (context->fill && ! no_fill)
+        fprintf (out, "fill: #%02x%02x%02x; fill-opacity: %f; ",
+            context->fill_color[0], context->fill_color[1],
+            context->fill_color[2], context->fill_color[3] / 255.0);
+
+      if (context->opacity != 1)
+        fprintf (out, "opacity: %f; ", context->opacity);
+    }
+  fprintf (out, "\"");
+}
+
+void
+p2tr_render_svg_draw_line (FILE              *out,
+                           P2trSVGContext    *context,
+                           const P2trVector2 *start,
+                           const P2trVector2 *end)
+{
+  fprintf (out, "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" ",
+      start->x, start->y, end->x, end->y);
+  p2tr_render_svg_style (out, context, TRUE);
+  fprintf (out, " />%s", P2TR_SVG_NEWLINE);
+}
+
+void
+p2tr_render_svg_draw_triangle (FILE              *out,
+                               P2trSVGContext    *context,
+                               const P2trVector2 *p1,
+                               const P2trVector2 *p2,
+                               const P2trVector2 *p3)
+{
+  fprintf (out, "<polygon points=\"%f,%f %f,%f %f,%f\" ",
+      p1->x, p1->y, p2->x, p2->y, p3->x, p3->y);
+  p2tr_render_svg_style (out, context, FALSE);
+  fprintf (out, " />%s", P2TR_SVG_NEWLINE);
+}
+
+void
+p2tr_render_svg_draw_circle (FILE              *out,
+                             P2trSVGContext    *context,
+                             const P2trVector2 *center,
+                             gdouble            radius)
+{
+  fprintf (out, "<circle cx=\"%f\" cy=\"%f\" r=\"%f\" ",
+      center->x, center->y, radius);
+  p2tr_render_svg_style (out, context, FALSE);
+  fprintf (out, " />%s", P2TR_SVG_NEWLINE);
+}
+
+void
+p2tr_render_svg (P2trMesh *mesh,
+                 FILE     *out)
+{
+  P2trHashSetIter  siter;
+  P2trTriangle    *tr;
+  P2trPoint       *pt;
+
+  /* Colors taken from the Tango Icon Theme color palette */
+  P2trSVGContext  TRI = {
+      TRUE,
+      1,
+      /* Sky Blue 3 */
+      { 32, 74, 135, 255 },
+      TRUE,
+      /* Sky Blue 1 */
+      { 114, 159, 207, 255 },
+      1
+  };
+
+  P2trSVGContext PT = {
+      FALSE,
+      0,
+      /* Orange 3 */
+      { 206, 92, 0, 1 },
+      TRUE,
+      /* Orange 1 */
+      { 245, 121, 0, 255 },
+      1
+  };
+
+  P2trVector2 bottom_left, top_right;
+
+  p2tr_mesh_get_bounds (mesh,
+      &bottom_left.x, &bottom_left.y,
+      &top_right.x,   &top_right.y);
+
+  bottom_left.x -= 10;
+  bottom_left.y -= 10;
+  top_right.x += 10;
+  top_right.y += 10;
+  p2tr_render_svg_init (out, &bottom_left, &top_right);
+
+  p2tr_hash_set_iter_init (&siter, mesh->triangles);
+  while (p2tr_hash_set_iter_next (&siter, (gpointer*)&tr))
+    p2tr_render_svg_draw_triangle (out, &TRI,
+        &P2TR_TRIANGLE_GET_POINT(tr, 0)->c,
+        &P2TR_TRIANGLE_GET_POINT(tr, 1)->c,
+        &P2TR_TRIANGLE_GET_POINT(tr, 2)->c);
+
+  p2tr_hash_set_iter_init (&siter, mesh->points);
+  while (p2tr_hash_set_iter_next (&siter, (gpointer*)&pt))
+    p2tr_render_svg_draw_circle (out, &PT, &pt->c, 1);
+
+  p2tr_render_svg_finish (out);
+}
diff --git a/libs/poly2tri-c/poly2tri-c/render/svg-plot.h b/libs/poly2tri-c/poly2tri-c/render/svg-plot.h
new file mode 100644
index 0000000..a94acd6
--- /dev/null
+++ b/libs/poly2tri-c/poly2tri-c/render/svg-plot.h
@@ -0,0 +1,75 @@
+/*
+ * This file is a part of Poly2Tri-C
+ * (c) Barak Itkin <lightningismyname gmail com>
+ * http://code.google.com/p/poly2tri-c/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __P2TC_RENDER_SVG_PLOT_H__
+#define __P2TC_RENDER_SVG_PLOT_H__
+
+#include <poly2tri-c/refine/refine.h>
+
+typedef guint8 P2trSVGColor[4];
+
+typedef struct
+{
+  gboolean     stroke;
+  gdouble      stroke_width;
+  P2trSVGColor stroke_color;
+  gboolean     fill;
+  P2trSVGColor fill_color;
+  gdouble      opacity;
+} P2trSVGContext;
+
+void p2tr_render_svg_init          (FILE              *out,
+                                    const P2trVector2 *bottom_left,
+                                    const P2trVector2 *top_right);
+
+void p2tr_render_svg_draw_line     (FILE              *out,
+                                    P2trSVGContext    *context,
+                                    const P2trVector2 *start,
+                                    const P2trVector2 *end);
+
+void p2tr_render_svg_draw_triangle (FILE              *out,
+                                    P2trSVGContext    *context,
+                                    const P2trVector2 *p1,
+                                    const P2trVector2 *p2,
+                                    const P2trVector2 *p3);
+
+void p2tr_render_svg_draw_circle   (FILE              *out,
+                                    P2trSVGContext    *context,
+                                    const P2trVector2 *center,
+                                    gdouble            radius);
+
+void p2tr_render_svg_finish        (FILE              *out);
+
+void p2tr_render_svg               (P2trMesh          *mesh,
+                                    FILE              *out);
+
+#endif
diff --git a/operations/common/seamless-clone/Makefile.am b/operations/common/seamless-clone/Makefile.am
index fb3c060..951e75b 100644
--- a/operations/common/seamless-clone/Makefile.am
+++ b/operations/common/seamless-clone/Makefile.am
@@ -18,6 +18,4 @@ seamless_clone_compose_la_SOURCES = seamless-clone-compose.c
 
 opdir = $(libdir)/gegl- GEGL_API_VERSION@
 
-if HAVE_P2TC
 op_LTLIBRARIES = seamless-clone.la seamless-clone-render.la seamless-clone-prepare.la seamless-clone-compose.la
-endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]