Blender V2.61 - r43446
|
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