diff options
Diffstat (limited to 'intern/decimation/intern/LOD_MeshPrimitives.cpp')
-rw-r--r-- | intern/decimation/intern/LOD_MeshPrimitives.cpp | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/intern/decimation/intern/LOD_MeshPrimitives.cpp b/intern/decimation/intern/LOD_MeshPrimitives.cpp new file mode 100644 index 00000000000..147e107cb4b --- /dev/null +++ b/intern/decimation/intern/LOD_MeshPrimitives.cpp @@ -0,0 +1,407 @@ +/** + * $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 "LOD_MeshPrimitives.h" + +#include "MT_assert.h" +#include "LOD_MeshException.h" +#include <algorithm> + +using namespace std; + +// Vertex Methods +///////////////// + +LOD_Vertex:: +LOD_Vertex( +) : + pos (MT_Vector3()), + m_select_tag(false) +{ +}; + + bool +LOD_Vertex:: +RemoveEdge( + LOD_EdgeInd e +){ + + vector<LOD_EdgeInd>::iterator result = find(m_edges.begin(),m_edges.end(),e); + if (result == m_edges.end()) { + return false; + } + LOD_EdgeInd last = m_edges.back(); + m_edges.pop_back(); + if (m_edges.empty()) return true; + + *result = last; + return true; +}; + + void +LOD_Vertex:: +AddEdge( + LOD_EdgeInd e +){ + m_edges.push_back(e); +}; + + void +LOD_Vertex:: +SwapEdge( + LOD_EdgeInd e_old, + LOD_EdgeInd e_new +){ + + vector<LOD_EdgeInd>::iterator result = + find(m_edges.begin(),m_edges.end(),e_old); + if (result == m_edges.end()) { + MT_assert(false); + LOD_MeshException e(LOD_MeshException::e_search_error); + throw(e); + } + + *result = e_new; +}; + + bool +LOD_Vertex:: +SelectTag( +) const { + return m_select_tag; +}; + + void +LOD_Vertex:: +SetSelectTag( + bool tag +){ + m_select_tag = tag; +}; + + bool +LOD_Vertex:: +Degenerate( +){ + return m_edges.empty(); +} + + void +LOD_Vertex:: +CopyPosition( + float *float_ptr +){ + pos.getValue(float_ptr); +} + + + +// Edge Methods +/////////////// + +LOD_Edge:: +LOD_Edge ( +) { + m_verts[0] = m_verts[1] = LOD_VertexInd::Empty(); + m_faces[0] = m_faces[1] = LOD_FaceInd::Empty(); +} + + bool +LOD_Edge:: +operator == ( + LOD_Edge & rhs +) { + // edges are the same if their vertex indices are the + // same!!! Other properties are not checked + + int matches = 0; + + if (this->m_verts[0] == rhs.m_verts[0]) { + ++matches; + } + if (this->m_verts[1] == rhs.m_verts[0]) { + ++matches; + } + if (this->m_verts[0] == rhs.m_verts[1]) { + ++matches; + } + if (this->m_verts[1] == rhs.m_verts[1]) { + ++matches; + } + + if (matches >= 2) { + return true; + } + return false; +} + +// Elementary helper methods +//////////////////////////// + + LOD_FaceInd +LOD_Edge:: +OpFace( + LOD_FaceInd f +) const { + if (f == m_faces[0]) { + return m_faces[1]; + } else + if (f == m_faces[1]) { + return m_faces[0]; + } else { + MT_assert(false); + LOD_MeshException e(LOD_MeshException::e_search_error); + throw(e); + + return LOD_FaceInd::Empty(); + } +} + + void +LOD_Edge:: +SwapFace( + LOD_FaceInd old_f, + LOD_FaceInd new_f +) { + if (old_f == m_faces[0]) { + m_faces[0] = new_f; + } else + if (old_f == m_faces[1]) { + m_faces[1] = new_f; + } else { + MT_assert(false); + + LOD_MeshException e(LOD_MeshException::e_search_error); + throw(e); + } +} + + +// return the half edge face - the half edge is defined +// by the {vertex,edge} tuple. + + LOD_FaceInd +LOD_Edge:: +HalfEdgeFace( + LOD_VertexInd vi +){ + if (vi == m_verts[0]) return m_faces[0]; + if (vi == m_verts[1]) return m_faces[1]; + MT_assert(false); + + LOD_MeshException e(LOD_MeshException::e_search_error); + throw(e); + + return LOD_FaceInd::Empty(); +} + + + LOD_VertexInd +LOD_Edge:: +OpVertex( + LOD_VertexInd vi +) { + if (vi == m_verts[0]) return m_verts[1]; + if (vi == m_verts[1]) return m_verts[0]; + MT_assert(false); + + LOD_MeshException e(LOD_MeshException::e_search_error); + throw(e); + + return LOD_VertexInd::Empty(); +} + +// replace the vertex v_old with vertex v_new +// error if v_old is not one of the original vertices + + void +LOD_Edge:: +SwapVertex( + LOD_VertexInd v_old, + LOD_VertexInd v_new +) { + if (v_old == m_verts[0]) { + m_verts[0] = v_new; + } else + if (v_old == m_verts[1]) { + m_verts[1] = v_new; + } else { + + MT_assert(false); + + LOD_MeshException e(LOD_MeshException::e_search_error); + throw(e); + } + if(m_verts[0] == m_verts[1]) { + MT_assert(false); + + LOD_MeshException e(LOD_MeshException::e_non_manifold); + throw(e); + } + +} + + bool +LOD_Edge:: +SelectTag( +) const { + return bool(m_verts[1].Tag() & 0x1); +}; + + void +LOD_Edge:: +SetSelectTag( + bool tag +) { + m_verts[1].SetTag(int(tag)); +}; + + int +LOD_Edge:: +OpenTag( +) const { + return m_faces[0].Tag(); +} + + void +LOD_Edge:: +SetOpenTag( + int tag +) { + m_faces[0].SetTag(tag); +} + + bool +LOD_Edge:: +Degenerate( +) const { + return ( + (m_faces[0].IsEmpty() && m_faces[1].IsEmpty()) || + (m_verts[0] == m_verts[1]) + ); +}; + +// TriFace Methods +////////////////// + +LOD_TriFace:: +LOD_TriFace( +) { + m_verts[0] = m_verts[1] = m_verts[2] = LOD_VertexInd::Empty(); +} + +// Elementary helper methods +//////////////////////////// + + void +LOD_TriFace:: +SwapVertex( + LOD_VertexInd old_v, + LOD_VertexInd new_v +) { + // could save branching here... + + if (m_verts[0] == old_v) { + m_verts[0] = new_v; + } else + if (m_verts[1] == old_v) { + m_verts[1] = new_v; + } else + if (m_verts[2] == old_v) { + m_verts[2] = new_v; + } else { + MT_assert(false); + + LOD_MeshException excep(LOD_MeshException::e_search_error); + throw(excep); + } +} + + bool +LOD_TriFace:: +SelectTag( +) const { + return bool(m_verts[1].Tag() & 0x1); +}; + + void +LOD_TriFace:: +SetSelectTag( + bool tag +) { + m_verts[1].SetTag(int(tag)); +}; + + int +LOD_TriFace:: +OpenTag( +) { + return m_verts[2].Tag(); +} + + void +LOD_TriFace:: +SetOpenTag( + int tag +) { + m_verts[2].SetTag(tag); +} + + bool +LOD_TriFace:: +Degenerate( +) { + + return ( + (m_verts[0] == m_verts[1]) || + (m_verts[1] == m_verts[2]) || + (m_verts[2] == m_verts[0]) + ); +} + + void +LOD_TriFace:: +CopyVerts( + int * index_ptr +){ + index_ptr[0] = m_verts[0]; + index_ptr[1] = m_verts[1]; + index_ptr[2] = m_verts[2]; +}; + + + + + + + + + |