Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/bsp/intern/BSP_Triangulate.cpp')
-rwxr-xr-xintern/bsp/intern/BSP_Triangulate.cpp249
1 files changed, 249 insertions, 0 deletions
diff --git a/intern/bsp/intern/BSP_Triangulate.cpp b/intern/bsp/intern/BSP_Triangulate.cpp
new file mode 100755
index 00000000000..a78b8ff0a92
--- /dev/null
+++ b/intern/bsp/intern/BSP_Triangulate.cpp
@@ -0,0 +1,249 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdio.h>
+
+#include <stdlib.h>
+#include "MT_Plane3.h"
+#include "BSP_Triangulate.h"
+#include "MT_assert.h"
+
+static const MT_Scalar EPSILON = MT_Scalar(1e-10);
+
+using namespace std;
+
+BSP_Triangulate::
+BSP_Triangulate(
+):
+ m_xi(0),
+ m_yi(1)
+{
+}
+
+BSP_Triangulate::
+~BSP_Triangulate(
+){
+}
+
+
+ MT_Scalar
+BSP_Triangulate::
+Area(
+ const vector<BSP_MVertex> &verts,
+ const BSP_VertexList &contour
+){
+
+ int n = contour.size();
+
+ MT_Scalar A(0.0);
+
+ for(int p=n-1,q=0; q<n; p=q++)
+ {
+ A+= verts[contour[p]].m_pos[m_xi]*verts[contour[q]].m_pos[m_yi] -
+ verts[contour[q]].m_pos[m_xi]*verts[contour[p]].m_pos[m_yi];
+ }
+ return A*MT_Scalar(0.5);
+}
+
+/*
+ InsideTriangle decides if a point P is Inside of the triangle
+ defined by A, B, C.
+ Or within an epsilon of it.
+*/
+
+ bool
+BSP_Triangulate::
+InsideTriangle(
+ MT_Scalar Ax, MT_Scalar Ay,
+ MT_Scalar Bx, MT_Scalar By,
+ MT_Scalar Cx, MT_Scalar Cy,
+ MT_Scalar Px, MT_Scalar Py
+){
+ MT_Scalar ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
+ MT_Scalar cCROSSap, bCROSScp, aCROSSbp;
+
+ ax = Cx - Bx; ay = Cy - By;
+ bx = Ax - Cx; by = Ay - Cy;
+ cx = Bx - Ax; cy = By - Ay;
+ apx= Px - Ax; apy= Py - Ay;
+ bpx= Px - Bx; bpy= Py - By;
+ cpx= Px - Cx; cpy= Py - Cy;
+
+ aCROSSbp = ax*bpy - ay*bpx;
+ cCROSSap = cx*apy - cy*apx;
+ bCROSScp = bx*cpy - by*cpx;
+
+ return ((aCROSSbp >= -EPSILON) && (bCROSScp >= -EPSILON) && (cCROSSap >= -EPSILON));
+};
+
+ bool
+BSP_Triangulate::
+Snip(
+ const vector<BSP_MVertex> &verts,
+ const BSP_VertexList &contour,
+ int u,int v,
+ int w,int n,
+ int *V
+){
+ int p;
+ MT_Scalar Ax, Ay, Bx, By, Cx, Cy, Px, Py;
+
+ Ax = verts[contour[V[u]]].m_pos[m_xi];
+ Ay = verts[contour[V[u]]].m_pos[m_yi];
+
+ Bx = verts[contour[V[v]]].m_pos[m_xi];
+ By = verts[contour[V[v]]].m_pos[m_yi];
+
+ Cx = verts[contour[V[w]]].m_pos[m_xi];
+ Cy = verts[contour[V[w]]].m_pos[m_yi];
+
+ // Snip is passes if the area of the candidate triangle is
+ // greater than 2*epsilon
+ // And if none of the remaining vertices are inside the polygon
+ // or within an epsilon of the boundary,
+
+ if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ) return false;
+
+ for (p=0;p<n;p++)
+ {
+ if( (p == u) || (p == v) || (p == w) ) continue;
+ Px = verts[contour[V[p]]].m_pos[m_xi];
+ Py = verts[contour[V[p]]].m_pos[m_yi];
+ if (InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false;
+ }
+
+ return true;
+}
+
+ bool
+BSP_Triangulate::
+Process(
+ const vector<BSP_MVertex> &verts,
+ const BSP_VertexList &contour,
+ const MT_Plane3 &normal,
+ std::vector<int> &result
+){
+
+ // Choose major axis of normal and assign
+ // 'projection' indices m_xi,m_yi;
+
+ int maj_axis = normal.Normal().closestAxis();
+
+ if (maj_axis == 0) {
+ m_xi = 1; m_yi = 2;
+ } else
+ if (maj_axis == 1) {
+ m_xi = 0; m_yi = 2;
+ } else {
+ m_xi = 0; m_yi = 1;
+ }
+
+ /* initialize list of Vertices in polygon */
+
+ int n = contour.size();
+ if ( n < 3 ) return false;
+
+ /* we want a counter-clockwise polygon in V */
+ /* to true but we also nead to preserve the winding order
+ of polygons going into the routine. We keep track of what
+ we did with a little bool */
+ bool is_flipped = false;
+
+ if ( 0.0f < Area(verts,contour) ) {
+ for (int v=0; v<n; v++) m_V.push_back(v);
+ } else {
+ for(int v=0; v<n; v++) m_V.push_back((n-1)-v);
+ is_flipped = true;
+ }
+
+ int nv = n;
+
+ /* remove nv-2 Vertices, creating 1 triangle every time */
+ int count = 2*nv; /* error detection */
+
+ for(int m=0, v=nv-1; nv>2; )
+ {
+ /* if we loop, it is probably a non-simple polygon */
+ if (0 >= (count--))
+ {
+#if 0
+ int deb = 0;
+ for (deb= 0; deb < contour.size(); deb++) {
+ cout << verts[contour[deb]].m_pos << "\n";
+ }
+ cout.flush();
+#endif
+ //** Triangulate: ERROR - probable bad polygon!
+ m_V.clear();
+ return false;
+ }
+
+ /* three consecutive vertices in current polygon, <u,v,w> */
+ int u = v ; if (nv <= u) u = 0; /* previous */
+ v = u+1; if (nv <= v) v = 0; /* new v */
+ int w = v+1; if (nv <= w) w = 0; /* next */
+
+ /* Try and snip this triangle off from the
+ current polygon.*/
+
+ if ( Snip(verts,contour,u,v,w,nv,m_V.begin()) )
+ {
+ int a,b,c,s,t;
+
+ /* true names of the vertices */
+ a = m_V[u]; b = m_V[v]; c = m_V[w];
+
+ /* output Triangle indices*/
+ if (is_flipped) {
+ result.push_back( c );
+ result.push_back( b );
+ result.push_back( a );
+ } else {
+ result.push_back( a );
+ result.push_back( b );
+ result.push_back( c );
+ }
+
+ m++;
+
+ /* remove v from remaining polygon */
+ for(s=v,t=v+1;t<nv;s++,t++) m_V[s] = m_V[t]; nv--;
+
+ /* resest error detection counter */
+ count = 2*nv;
+ }
+ }
+
+ m_V.clear();
+ return true;
+}
+
+