/** * $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 #include #ifdef HAVE_CONFIG_H #include #endif #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 &verts, const BSP_VertexList &contour ){ int n = contour.size(); MT_Scalar A(0.0); for(int p=n-1,q=0; q= -EPSILON) && (bCROSScp >= -EPSILON) && (cCROSSap >= -EPSILON)); }; bool BSP_Triangulate:: Snip( const vector &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 &verts, const BSP_VertexList &contour, const MT_Plane3 &normal, std::vector &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; v2; ) { /* 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, */ 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[0]) ) { 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