Blender V2.61 - r43446

LOD_ManMesh2.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include "LOD_ManMesh2.h"
00034 
00035 #include "MT_assert.h"
00036 #include <algorithm>
00037 #include "LOD_MeshException.h"
00038 #include "CTR_TaggedSetOps.h"
00039 #include "CTR_UHeap.h"
00040 #include "LOD_ExternBufferEditor.h"
00041 
00042 
00043 using namespace std;
00044 
00045 LOD_ManMesh2::
00046 LOD_ManMesh2(
00047 ) :
00048     m_bbox_min(0,0,0),
00049     m_bbox_max(0,0,0)
00050 {
00051 }
00052     
00053 
00054     LOD_ManMesh2 *
00055 LOD_ManMesh2::
00056 New(
00057 ){
00058     MEM_SmartPtr<LOD_ManMesh2> output(new LOD_ManMesh2());
00059     if (output == NULL) return NULL;
00060 
00061     // build the vertex, edge and face sets.
00062 
00063     MEM_SmartPtr<vector<LOD_Vertex> > verts(new vector<LOD_Vertex>);
00064     MEM_SmartPtr<vector<LOD_TriFace> > faces(new vector<LOD_TriFace>);
00065     MEM_SmartPtr<vector<LOD_Edge> > edges(new vector<LOD_Edge>);
00066     
00067     if ((faces == NULL) || (edges == NULL) || (verts == NULL)) {
00068         return NULL;
00069     }
00070     
00071     output->m_verts = verts.Release();
00072     output->m_faces = faces.Release();
00073     output->m_edges = edges.Release();
00074 
00075     return output.Release();
00076 }   
00077 
00078 // take ownership of the vertices.
00079 
00080     bool    
00081 LOD_ManMesh2::
00082 SetVertices(
00083     MEM_SmartPtr<vector<LOD_Vertex> > verts
00084 ){
00085 
00086 
00087     // take ownership of vertices
00088     m_verts = verts;
00089 
00090     // create a polygon and edge buffer of half the size 
00091     // and just use the automatic resizing feature of vector<>
00092     // to worry about the dynamic array resizing
00093     
00094     m_faces->clear();
00095     m_edges->clear();
00096 
00097     m_faces->reserve(m_verts->size()/2);
00098     m_edges->reserve(m_verts->size()/2);
00099 
00100     return true;    
00101 
00102 }
00103 
00104     
00105 // add a triangle to the mesh
00106 
00107     void
00108 LOD_ManMesh2::
00109 AddTriangle(
00110     int verts[3]
00111 ) {
00112 
00113     MT_assert(verts[0] < int(m_verts->size()));
00114     MT_assert(verts[1] < int(m_verts->size()));
00115     MT_assert(verts[2] < int(m_verts->size()));
00116 
00117     LOD_TriFace face;
00118     face.m_verts[0] = verts[0];
00119     face.m_verts[1] = verts[1];
00120     face.m_verts[2] = verts[2];
00121 
00122     LOD_FaceInd face_index = m_faces->size();
00123 
00124     m_faces->push_back(face);   
00125 
00126     // now work out if any of the directed edges or their
00127     // companion edges exist already.
00128     // We go through the edges associated with each of the given vertices 
00129 
00130     // the safest thing to do is iterate through each of the edge sets
00131     // check against each of the 2 other triangle edges to see if they are there
00132     
00133     vector<LOD_EdgeInd> new_edges;
00134     new_edges.reserve(3);
00135 
00136     InsertEdge(verts[0],verts[1],face_index,new_edges);
00137     InsertEdge(verts[1],verts[2],face_index,new_edges);
00138     InsertEdge(verts[2],verts[0],face_index,new_edges);
00139 
00140 }
00141     
00142 // Adds the index of any created edges to new_edges
00143 
00144     bool
00145 LOD_ManMesh2::
00146 InsertEdge(
00147     const LOD_VertexInd v1,
00148     const LOD_VertexInd v2,
00149     const LOD_FaceInd f,
00150     vector<LOD_EdgeInd> &new_edges
00151 ){
00152     
00153     MT_assert(!v1.IsEmpty());
00154     MT_assert(!v2.IsEmpty());
00155     MT_assert(!f.IsEmpty());
00156 
00157     vector<LOD_Vertex> &verts = VertexSet();
00158     vector<LOD_Edge> &edges = EdgeSet();
00159     
00160     LOD_EdgeInd e;
00161 
00162     e = FindEdge(v1,v2);
00163 
00164     if (e.IsEmpty()) {
00165         // This edge does not exist -- make a new one 
00166 
00167         LOD_Edge temp_e;
00168         temp_e.m_verts[0] = v1;
00169         temp_e.m_verts[1] = v2;
00170 
00171         e = m_edges->size();
00172 
00173         // set the face ptr for this half-edge
00174         temp_e.m_faces[0] = f;
00175 
00176         m_edges->push_back(temp_e);
00177 
00178         // add the edge index to it's vertices 
00179 
00180         verts[v1].AddEdge(e);
00181         verts[v2].AddEdge(e);
00182 
00183         new_edges.push_back(e);
00184 
00185     } else {
00186 
00187         // edge already exists
00188         // insure that there is no polygon already
00189         // attached to the other side of this edge
00190 
00191         // swap the empty face pointer in edge with f
00192 
00193         LOD_Edge &edge = edges[e];
00194 
00195         edge.SwapFace(LOD_FaceInd::Empty(),f);
00196     }
00197         
00198 
00199     return true;
00200 
00201 }
00202 
00203     void
00204 LOD_ManMesh2::
00205 ConnectTriangle(
00206     LOD_FaceInd fi,
00207     std::vector<LOD_EdgeInd> & new_edges
00208 ){
00209 
00210     vector<LOD_TriFace> &faces = FaceSet();
00211 
00212     MT_assert(!faces[fi].Degenerate());
00213 
00214     LOD_TriFace & face = faces[fi];
00215 
00216     InsertEdge(face.m_verts[0],face.m_verts[1],fi,new_edges);
00217     InsertEdge(face.m_verts[1],face.m_verts[2],fi,new_edges);
00218     InsertEdge(face.m_verts[2],face.m_verts[0],fi,new_edges);
00219 };
00220 
00221 
00222 
00223 
00224 // geometry access
00226 
00227     vector<LOD_Vertex> &
00228 LOD_ManMesh2::
00229 VertexSet(
00230 ) const {
00231     return m_verts.Ref();
00232 }       
00233 
00234     vector<LOD_TriFace> &
00235 LOD_ManMesh2::
00236 FaceSet(
00237 ) const {
00238     return m_faces.Ref();
00239 }
00240 
00241     vector<LOD_Edge> &
00242 LOD_ManMesh2::
00243 EdgeSet(
00244 ) const {
00245     return m_edges.Ref();
00246 };
00247 
00248 LOD_ManMesh2::
00249 ~LOD_ManMesh2(
00250 ){
00251     //auto ptr takes care of vertex arrays etc.
00252 }
00253 
00254     LOD_EdgeInd
00255 LOD_ManMesh2::
00256 FindEdge(
00257     const LOD_VertexInd v1,
00258     const LOD_VertexInd v2
00259 ) {
00260 
00261     vector<LOD_Vertex> &verts = VertexSet();
00262     vector<LOD_Edge> &edges = EdgeSet();
00263 
00264     LOD_Edge e;
00265     e.m_verts[0] = v1;
00266     e.m_verts[1] = v2;
00267     
00268     vector<LOD_EdgeInd> &v1_edges = verts[v1].m_edges;
00269     vector<LOD_EdgeInd>::const_iterator v1_end = v1_edges.end();
00270     vector<LOD_EdgeInd>::iterator v1_begin = v1_edges.begin();
00271 
00272     for (; v1_begin != v1_end; ++v1_begin) {
00273         if (edges[*v1_begin] == e) return *v1_begin;
00274     }
00275     
00276     return LOD_EdgeInd::Empty();
00277 }
00278 
00279 // face queries
00281 
00282     void
00283 LOD_ManMesh2::
00284 FaceVertices(
00285     LOD_FaceInd fi,
00286     vector<LOD_VertexInd> &output
00287 ){  
00288     const vector<LOD_TriFace> &faces = FaceSet();
00289     const LOD_TriFace & f = faces[fi];
00290 
00291     output.push_back(f.m_verts[0]);
00292     output.push_back(f.m_verts[1]);
00293     output.push_back(f.m_verts[2]);
00294 }
00295     
00296     void
00297 LOD_ManMesh2::
00298 FaceEdges(
00299     LOD_FaceInd fi,
00300     vector<LOD_EdgeInd> &output
00301 ){
00302     const vector<LOD_TriFace> &faces = FaceSet();
00303     vector<LOD_Edge> &edges = EdgeSet();
00304     vector<LOD_Vertex> &verts = VertexSet();    
00305 
00306     const LOD_TriFace & f = faces[fi];
00307     // intersect vertex edges
00308 
00309     vector<LOD_EdgeInd> & v0_edges = verts[f.m_verts[0]].m_edges;
00310     vector<LOD_EdgeInd> & v1_edges = verts[f.m_verts[1]].m_edges;
00311     vector<LOD_EdgeInd> & v2_edges = verts[f.m_verts[2]].m_edges;
00312 
00313     CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v0_edges,v1_edges,edges,output);
00314     CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v1_edges,v2_edges,edges,output);
00315     CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v2_edges,v0_edges,edges,output);
00316 
00317     MT_assert(output.size() == 3);
00318     if (output.size() != 3) {
00319         LOD_MeshException e(LOD_MeshException::e_non_manifold);
00320         throw(e);   
00321     }
00322 }
00323     
00324 
00325 // edge queries
00327 
00328     void
00329 LOD_ManMesh2::
00330 EdgeVertices(
00331     LOD_EdgeInd ei,
00332     vector<LOD_VertexInd> &output
00333 ){
00334     const vector<LOD_Edge> &edges = EdgeSet();
00335     const LOD_Edge & e = edges[ei];
00336 
00337     output.push_back(e.m_verts[0]);
00338     output.push_back(e.m_verts[1]);
00339 }
00340 
00341     void
00342 LOD_ManMesh2::
00343 EdgeFaces(
00344     LOD_EdgeInd ei,
00345     vector<LOD_FaceInd> &output
00346 ){
00347     const vector<LOD_Edge> &edges = EdgeSet();
00348     const LOD_Edge & e = edges[ei];
00349 
00350     if (!e.m_faces[0].IsEmpty()) {
00351         output.push_back(e.m_faces[0]);
00352     }
00353     if (!e.m_faces[1].IsEmpty()) {
00354         output.push_back(e.m_faces[1]);
00355     }
00356 }   
00357 
00358 // vertex queries
00360 
00361     void
00362 LOD_ManMesh2::
00363 VertexEdges(
00364     LOD_VertexInd vi,
00365     vector<LOD_EdgeInd> &output
00366 ){
00367     // iterate through the edges of v and push them onto the 
00368     // output
00369     
00370     vector<LOD_Vertex> &verts = VertexSet();
00371 
00372     vector<LOD_EdgeInd> & v_edges = verts[vi].m_edges;
00373     vector<LOD_EdgeInd>::iterator v_it = v_edges.begin();
00374 
00375     for (; v_it != v_edges.end(); ++v_it) {
00376         output.push_back(*v_it);
00377     }   
00378 }
00379 
00380     void
00381 LOD_ManMesh2::
00382 VertexFaces(
00383     LOD_VertexInd vi,
00384     vector<LOD_FaceInd> &output
00385 ){
00386     const vector<LOD_Vertex> &verts = VertexSet();
00387     vector<LOD_Edge> &edges = EdgeSet();
00388     vector<LOD_TriFace> &faces = FaceSet();
00389 
00390     const vector<LOD_EdgeInd> &v_edges = verts[vi].m_edges;
00391     vector<LOD_EdgeInd>::const_iterator e_it = v_edges.begin();
00392 
00393     for (; e_it != v_edges.end(); ++e_it) {
00394 
00395         LOD_Edge &e = edges[*e_it]; 
00396 
00397         if ((!e.m_faces[0].IsEmpty()) && (!faces[e.m_faces[0]].SelectTag())) {
00398             output.push_back(e.m_faces[0]);
00399             faces[e.m_faces[0]].SetSelectTag(true);
00400         }
00401 
00402         if ((!e.m_faces[1].IsEmpty()) && (!faces[e.m_faces[1]].SelectTag())) {
00403             output.push_back(e.m_faces[1]);
00404             faces[e.m_faces[1]].SetSelectTag(true);
00405         }
00406     }
00407 
00408     vector<LOD_FaceInd>::iterator f_it = output.begin();
00409 
00410     for (; f_it != output.end(); ++f_it) {
00411         faces[*f_it].SetSelectTag(false);
00412     }
00413 };
00414         
00415     void
00416 LOD_ManMesh2::
00417 SetBBox(
00418     MT_Vector3 bbox_min,
00419     MT_Vector3 bbox_max
00420 ){
00421     m_bbox_min = bbox_min;
00422     m_bbox_max = bbox_max;
00423 };
00424 
00425     void
00426 LOD_ManMesh2::
00427 SC_TriFace(
00428     LOD_FaceInd f
00429 ){
00430     LOD_TriFace face = (*m_faces)[f];
00431     
00432     // check for unique vertices
00433 
00434     if (
00435         (face.m_verts[0] == face.m_verts[1]) ||
00436         (face.m_verts[1] == face.m_verts[2]) ||
00437         (face.m_verts[2] == face.m_verts[0])
00438     ) {
00439         MT_assert(false);
00440     }   
00441 
00442 }
00443 
00444 
00445     void
00446 LOD_ManMesh2::
00447 SC_EdgeList(
00448     LOD_VertexInd v
00449 ){
00450     vector<LOD_Edge> &edges = EdgeSet();
00451     vector<LOD_Vertex> &verts = VertexSet();
00452 
00453     vector<LOD_EdgeInd>::iterator e_it = verts[v].m_edges.begin();
00454 
00455     for (;e_it != verts[v].m_edges.end(); ++e_it) {
00456         MT_assert( (edges[*e_it].m_verts[0] == v) || (edges[*e_it].m_verts[1] == v));
00457     }               
00458 
00459 };
00460     
00461     void
00462 LOD_ManMesh2::
00463 DeleteVertex(
00464     LOD_ExternBufferEditor & extern_editor,
00465     LOD_VertexInd v
00466 ){
00467 
00468     vector<LOD_Edge> &edges = EdgeSet();
00469     vector<LOD_Vertex> &verts = VertexSet();
00470     vector<LOD_TriFace> &faces = FaceSet();
00471 
00472     // need to update all the edge and polygons pointing to 
00473     // the last vertex in m_verts
00474 
00475     if (verts.size() == 1) {
00476         verts.clear();
00477         return;
00478     }
00479 
00480     LOD_VertexInd last = LOD_VertexInd(size_t(verts.end() - verts.begin() - 1));
00481 
00482     if (!(last == v)) {
00483 
00484         // we asume that v is already disconnected
00485 
00486         vector<LOD_FaceInd> v_faces;
00487         vector<LOD_EdgeInd> v_edges;
00488 
00489         v_faces.reserve(64);
00490         v_edges.reserve(64);
00491 
00492         VertexFaces(last,v_faces);
00493         VertexEdges(last,v_edges);
00494 
00495         // map the faces and edges to look at v 
00496 
00497         vector<LOD_FaceInd>::iterator face_it = v_faces.begin();
00498 
00499         for(; face_it != v_faces.end(); ++face_it) {
00500             faces[*face_it].SwapVertex(last,v);
00501         }
00502         vector<LOD_EdgeInd>::iterator edge_it = v_edges.begin();
00503 
00504         for (; edge_it != v_edges.end(); ++edge_it) {
00505             edges[*edge_it].SwapVertex(last,v);
00506         }
00507 
00508         // copy the last vertex onto v and pop off the back.
00509 
00510         verts[v] = verts[last];
00511 
00512         // tidy external buffer
00513         extern_editor.CopyModifiedFaces(*this,v_faces);
00514     }
00515 
00516     verts.pop_back();   
00517     extern_editor.CopyBackVertex(v);
00518 
00519 
00520 };      
00521 
00522     void
00523 LOD_ManMesh2::
00524 DeleteEdge(
00525     LOD_EdgeInd e,
00526     CTR_UHeap<LOD_Edge> * heap
00527 ){
00528     vector<LOD_Edge> &edges = EdgeSet();
00529     vector<LOD_Vertex> &verts = VertexSet();
00530 
00531     if (edges.size() == 1) {
00532         edges.clear();
00533         return;
00534     }
00535 
00536     LOD_EdgeInd last = LOD_EdgeInd(size_t(edges.end() - edges.begin() - 1));
00537 
00538     if (!(last == e)) {
00539         vector<LOD_EdgeInd> e_verts;
00540         e_verts.reserve(2);
00541         EdgeVertices(last,e_verts);
00542         // something is wrong if there arent two!
00543 
00544         verts[e_verts[0]].SwapEdge(last,e);
00545         verts[e_verts[1]].SwapEdge(last,e);
00546 
00547         // edges[e] should already have been removed from the heap
00548 
00549         MT_assert(edges[e].HeapPos() == -1);
00550 
00551         edges[e] = edges[last];
00552         // also have to swap there heap positions.!!!!!
00553 
00554         heap->HeapVector()[edges[e].HeapPos()] = e;
00555 
00556 
00557     }
00558     edges.pop_back();
00559 };
00560     
00561     void
00562 LOD_ManMesh2::
00563 DeleteFace(
00564     LOD_ExternBufferEditor & extern_editor,
00565     LOD_FaceInd f
00566 ){
00567 
00568     vector<LOD_Edge> &edges = EdgeSet();
00569     vector<LOD_TriFace> &faces = FaceSet();
00570 
00571     if (faces.size() == 1) {
00572         faces.clear();
00573         return;
00574     }
00575 
00576     LOD_FaceInd last = LOD_FaceInd(size_t (faces.end() - faces.begin() - 1));
00577 
00578     if (!(last == f)) {
00579         
00580         // we have to update the edges which point to the last 
00581         // face 
00582 
00583         vector<LOD_EdgeInd> f_edges;
00584         f_edges.reserve(3);
00585 
00586         FaceEdges(last,f_edges);
00587 
00588         vector<LOD_EdgeInd>::iterator edge_it = f_edges.begin();
00589         vector<LOD_EdgeInd>::const_iterator edge_end = f_edges.end();
00590     
00591         for (; edge_it != edge_end; ++edge_it) {
00592             edges[*edge_it].SwapFace(last,f);
00593         }
00594 
00595         faces[f] = faces[last];
00596 
00597     }
00598     faces.pop_back();
00599 
00600     // tidy external buffers
00601     extern_editor.CopyBackFace(f);
00602 };  
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618