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