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 00034 #include "BSP_CSGMesh.h" 00035 #include "MT_assert.h" 00036 #include "CTR_TaggedSetOps.h" 00037 #include "MT_Plane3.h" 00038 #include "BSP_CSGException.h" 00039 00040 // for insert_iterator 00041 #include <iterator> 00042 00043 // for vector reverse 00044 #include <iostream> 00045 #include <algorithm> 00046 using namespace std; 00047 00048 BSP_CSGMesh:: 00049 BSP_CSGMesh( 00050 ) : 00051 MEM_RefCountable() 00052 { 00053 m_verts = NULL; 00054 m_faces = NULL; 00055 m_edges = NULL; 00056 } 00057 00058 BSP_CSGMesh * 00059 BSP_CSGMesh:: 00060 New( 00061 ){ 00062 return new BSP_CSGMesh(); 00063 } 00064 00065 BSP_CSGMesh * 00066 BSP_CSGMesh:: 00067 NewCopy( 00068 ) const { 00069 00070 BSP_CSGMesh *mesh = New(); 00071 if (mesh == NULL) return NULL; 00072 00073 mesh->m_bbox_max = m_bbox_max; 00074 mesh->m_bbox_min = m_bbox_min; 00075 00076 if (m_edges != NULL) { 00077 mesh->m_edges = new vector<BSP_MEdge>(*m_edges); 00078 if (mesh->m_edges == NULL) { 00079 delete mesh; 00080 return NULL; 00081 } 00082 } 00083 if (m_verts != NULL) { 00084 mesh->m_verts = new vector<BSP_MVertex>(*m_verts); 00085 if (mesh->m_verts == NULL) { 00086 if (m_edges != NULL) free(mesh->m_edges); 00087 delete mesh; 00088 return NULL; 00089 } 00090 } 00091 if (m_faces != NULL) { 00092 mesh->m_faces = new vector<BSP_MFace>(*m_faces); 00093 if (mesh->m_faces == NULL) { 00094 delete mesh; 00095 return NULL; 00096 } 00097 } 00098 00099 return mesh; 00100 } 00101 00102 void 00103 BSP_CSGMesh:: 00104 Invert( 00105 ){ 00106 00107 vector<BSP_MFace> & faces = FaceSet(); 00108 00109 vector<BSP_MFace>::const_iterator faces_end = faces.end(); 00110 vector<BSP_MFace>::iterator faces_it = faces.begin(); 00111 00112 for (; faces_it != faces_end; ++faces_it) { 00113 faces_it->Invert(); 00114 } 00115 } 00116 00117 bool 00118 BSP_CSGMesh:: 00119 SetVertices( 00120 vector<BSP_MVertex> *verts 00121 ){ 00122 if (verts == NULL) return false; 00123 00124 // create polygon and edge arrays and reserve some space. 00125 m_faces = new vector<BSP_MFace>; 00126 if (!m_faces) return false; 00127 00128 m_faces->reserve(verts->size()/2); 00129 00130 // previous verts get deleted here. 00131 m_verts = verts; 00132 return true; 00133 } 00134 00135 void 00136 BSP_CSGMesh:: 00137 AddPolygon( 00138 const int * verts, 00139 int num_verts 00140 ){ 00141 MT_assert(verts != NULL); 00142 MT_assert(num_verts >=3); 00143 00144 if (verts == NULL || num_verts <3) return; 00145 00146 // make a polyscone from these vertex indices. 00147 00148 const BSP_FaceInd fi = m_faces->size(); 00149 m_faces->push_back(BSP_MFace()); 00150 BSP_MFace & face = m_faces->back(); 00151 00152 insert_iterator<vector<BSP_VertexInd> > insert_point(face.m_verts,face.m_verts.end()); 00153 copy (verts,verts + num_verts,insert_point); 00154 00155 // compute and store the plane equation for this face. 00156 00157 MT_Plane3 face_plane = FacePlane(fi); 00158 face.m_plane = face_plane; 00159 }; 00160 00161 // assumes that the face already has a plane equation 00162 void 00163 BSP_CSGMesh:: 00164 AddPolygon( 00165 const BSP_MFace &face 00166 ){ 00167 m_faces->push_back(face); 00168 }; 00169 00170 00171 bool 00172 BSP_CSGMesh:: 00173 BuildEdges( 00174 ){ 00175 00176 if (m_faces == NULL) return false; 00177 00178 if (m_edges != NULL) { 00179 DestroyEdges(); 00180 } 00181 00182 m_edges = new vector<BSP_MEdge>; 00183 00184 if (m_edges == NULL) { 00185 return false; 00186 } 00187 00188 00189 //iterate through the face set and add edges for all polygon 00190 //edges 00191 00192 vector<BSP_MFace>::const_iterator f_it_end = FaceSet().end(); 00193 vector<BSP_MFace>::iterator f_it_begin = FaceSet().begin(); 00194 vector<BSP_MFace>::iterator f_it = FaceSet().begin(); 00195 00196 vector<BSP_EdgeInd> dummy; 00197 00198 for (;f_it != f_it_end; ++f_it) { 00199 00200 BSP_MFace & face = *f_it; 00201 00202 int vertex_num = face.m_verts.size(); 00203 BSP_VertexInd prev_vi(face.m_verts[vertex_num-1]); 00204 00205 for (int vert = 0; vert < vertex_num; ++vert) { 00206 00207 BSP_FaceInd fi(size_t (f_it - f_it_begin)); 00208 InsertEdge(prev_vi,face.m_verts[vert],fi,dummy); 00209 prev_vi = face.m_verts[vert]; 00210 } 00211 00212 } 00213 dummy.clear(); 00214 return true; 00215 } 00216 00217 void 00218 BSP_CSGMesh:: 00219 DestroyEdges( 00220 ){ 00221 if ( m_edges != NULL ) { 00222 delete m_edges; 00223 m_edges = NULL; 00224 } 00225 00226 // Run through the vertices 00227 // and clear their edge arrays. 00228 00229 if (m_verts){ 00230 00231 vector<BSP_MVertex>::const_iterator vertex_end = VertexSet().end(); 00232 vector<BSP_MVertex>::iterator vertex_it = VertexSet().begin(); 00233 00234 for (; vertex_it != vertex_end; ++vertex_it) { 00235 vertex_it->m_edges.clear(); 00236 } 00237 } 00238 } 00239 00240 00241 BSP_EdgeInd 00242 BSP_CSGMesh:: 00243 FindEdge( 00244 const BSP_VertexInd & v1, 00245 const BSP_VertexInd & v2 00246 ) const { 00247 00248 vector<BSP_MVertex> &verts = VertexSet(); 00249 vector<BSP_MEdge> &edges = EdgeSet(); 00250 00251 BSP_MEdge e; 00252 e.m_verts[0] = v1; 00253 e.m_verts[1] = v2; 00254 00255 vector<BSP_EdgeInd> &v1_edges = verts[v1].m_edges; 00256 vector<BSP_EdgeInd>::const_iterator v1_end = v1_edges.end(); 00257 vector<BSP_EdgeInd>::const_iterator v1_begin = v1_edges.begin(); 00258 00259 for (; v1_begin != v1_end; ++v1_begin) { 00260 if (edges[*v1_begin] == e) return *v1_begin; 00261 } 00262 00263 return BSP_EdgeInd::Empty(); 00264 } 00265 00266 void 00267 BSP_CSGMesh:: 00268 InsertEdge( 00269 const BSP_VertexInd & v1, 00270 const BSP_VertexInd & v2, 00271 const BSP_FaceInd & f, 00272 vector<BSP_EdgeInd> &new_edges 00273 ){ 00274 00275 MT_assert(!v1.IsEmpty()); 00276 MT_assert(!v2.IsEmpty()); 00277 MT_assert(!f.IsEmpty()); 00278 00279 if (v1.IsEmpty() || v2.IsEmpty() || f.IsEmpty()) { 00280 BSP_CSGException e(e_mesh_error); 00281 throw (e); 00282 } 00283 00284 vector<BSP_MVertex> &verts = VertexSet(); 00285 vector<BSP_MEdge> &edges = EdgeSet(); 00286 00287 BSP_EdgeInd e; 00288 00289 e = FindEdge(v1,v2); 00290 if (e.IsEmpty()) { 00291 // This edge does not exist -- make a new one 00292 00293 BSP_MEdge temp_e; 00294 temp_e.m_verts[0] = v1; 00295 temp_e.m_verts[1] = v2; 00296 00297 e = m_edges->size(); 00298 // set the face index from the edge back to this polygon. 00299 temp_e.m_faces.push_back(f); 00300 00301 m_edges->push_back(temp_e); 00302 00303 // add the edge index to it's vertices 00304 verts[v1].AddEdge(e); 00305 verts[v2].AddEdge(e); 00306 00307 new_edges.push_back(e); 00308 00309 } else { 00310 00311 // edge already exists 00312 // insure that there is no polygon already 00313 // attached to the other side of this edge 00314 // swap the empty face pointer in edge with f 00315 00316 BSP_MEdge &edge = edges[e]; 00317 00318 // set the face index from the edge back to this polygon. 00319 edge.m_faces.push_back(f); 00320 } 00321 } 00322 00323 00324 // geometry access 00326 00327 vector<BSP_MVertex> & 00328 BSP_CSGMesh:: 00329 VertexSet( 00330 ) const { 00331 return *m_verts; 00332 } 00333 00334 vector<BSP_MFace> & 00335 BSP_CSGMesh:: 00336 FaceSet( 00337 ) const { 00338 return *m_faces; 00339 } 00340 00341 vector<BSP_MEdge> & 00342 BSP_CSGMesh:: 00343 EdgeSet( 00344 ) const { 00345 return *m_edges; 00346 } 00347 00348 BSP_CSGMesh:: 00349 ~BSP_CSGMesh( 00350 ){ 00351 if ( m_verts != NULL ) delete m_verts; 00352 if ( m_faces != NULL ) delete m_faces; 00353 if ( m_edges != NULL ) delete m_edges; 00354 } 00355 00356 // local geometry queries. 00358 00359 // face queries 00361 00362 void 00363 BSP_CSGMesh:: 00364 FaceVertices( 00365 const BSP_FaceInd & f, 00366 vector<BSP_VertexInd> &output 00367 ){ 00368 vector<BSP_MFace> & face_set = FaceSet(); 00369 output.insert( 00370 output.end(), 00371 face_set[f].m_verts.begin(), 00372 face_set[f].m_verts.end() 00373 ); 00374 } 00375 00376 00377 void 00378 BSP_CSGMesh:: 00379 FaceEdges( 00380 const BSP_FaceInd & fi, 00381 vector<BSP_EdgeInd> &output 00382 ){ 00383 // take intersection of the edges emminating from all the vertices 00384 // of this polygon; 00385 00386 vector<BSP_MFace> &faces = FaceSet(); 00387 vector<BSP_MEdge> &edges = EdgeSet(); 00388 00389 const BSP_MFace & f = faces[fi]; 00390 00391 // collect vertex edges; 00392 00393 vector<BSP_VertexInd>::const_iterator face_verts_it = f.m_verts.begin(); 00394 vector<BSP_VertexInd>::const_iterator face_verts_end = f.m_verts.end(); 00395 00396 vector< vector<BSP_EdgeInd> > vertex_edges(f.m_verts.size()); 00397 00398 int vector_slot = 0; 00399 00400 for (;face_verts_it != face_verts_end; ++face_verts_it, ++vector_slot) { 00401 VertexEdges(*face_verts_it,vertex_edges[vector_slot]); 00402 } 00403 00404 int prev = vector_slot - 1; 00405 00406 // intersect pairs of edge sets 00407 00408 for (int i = 0; i < vector_slot;i++) { 00409 CTR_TaggedSetOps<BSP_EdgeInd,BSP_MEdge>::IntersectPair(vertex_edges[prev],vertex_edges[i],edges,output); 00410 prev = i; 00411 } 00412 00413 // should always have 3 or more unique edges per face. 00414 MT_assert(output.size() >=3); 00415 00416 if (output.size() < 3) { 00417 BSP_CSGException e(e_mesh_error); 00418 throw(e); 00419 } 00420 }; 00421 00422 // edge queries 00424 00425 void 00426 BSP_CSGMesh:: 00427 EdgeVertices( 00428 const BSP_EdgeInd & e, 00429 vector<BSP_VertexInd> &output 00430 ){ 00431 const vector<BSP_MEdge> &edges = EdgeSet(); 00432 output.push_back(edges[e].m_verts[0]); 00433 output.push_back(edges[e].m_verts[1]); 00434 } 00435 00436 void 00437 BSP_CSGMesh:: 00438 EdgeFaces( 00439 const BSP_EdgeInd & e, 00440 vector<BSP_FaceInd> &output 00441 ){ 00442 00443 vector<BSP_MEdge> & edge_set = EdgeSet(); 00444 output.insert( 00445 output.end(), 00446 edge_set[e].m_faces.begin(), 00447 edge_set[e].m_faces.end() 00448 ); 00449 00450 } 00451 00452 // vertex queries 00454 00455 void 00456 BSP_CSGMesh:: 00457 VertexEdges( 00458 const BSP_VertexInd &v, 00459 vector<BSP_EdgeInd> &output 00460 ){ 00461 00462 vector<BSP_MVertex> & vertex_set = VertexSet(); 00463 output.insert( 00464 output.end(), 00465 vertex_set[v].m_edges.begin(), 00466 vertex_set[v].m_edges.end() 00467 ); 00468 } 00469 00470 void 00471 BSP_CSGMesh:: 00472 VertexFaces( 00473 const BSP_VertexInd &vi, 00474 vector<BSP_FaceInd> &output 00475 ) { 00476 00477 vector<BSP_MEdge> &edges = EdgeSet(); 00478 vector<BSP_MFace> &faces = FaceSet(); 00479 vector<BSP_MVertex> &verts = VertexSet(); 00480 00481 const vector<BSP_EdgeInd> &v_edges = verts[vi].m_edges; 00482 vector<BSP_EdgeInd>::const_iterator e_it = v_edges.begin(); 00483 00484 for (; e_it != v_edges.end(); ++e_it) { 00485 00486 BSP_MEdge &e = edges[*e_it]; 00487 00488 // iterate through the faces of this edge - push unselected 00489 // edges to ouput and then select the edge 00490 00491 vector<BSP_FaceInd>::const_iterator e_faces_end = e.m_faces.end(); 00492 vector<BSP_FaceInd>::iterator e_faces_it = e.m_faces.begin(); 00493 00494 for (;e_faces_it != e_faces_end; ++e_faces_it) { 00495 00496 if (!faces[*e_faces_it].SelectTag()) { 00497 output.push_back(*e_faces_it); 00498 faces[*e_faces_it].SetSelectTag(true); 00499 } 00500 } 00501 } 00502 00503 // deselect selected faces. 00504 vector<BSP_FaceInd>::iterator f_it = output.begin(); 00505 00506 for (; f_it != output.end(); ++f_it) { 00507 faces[*f_it].SetSelectTag(false); 00508 } 00509 } 00510 00511 bool 00512 BSP_CSGMesh:: 00513 SC_Face( 00514 BSP_FaceInd f 00515 ){ 00516 00517 00518 00519 #if 0 00520 { 00521 // check area is greater than zero. 00522 00523 vector<BSP_MVertex> & verts = VertexSet(); 00524 00525 vector<BSP_VertexInd> f_verts; 00526 FaceVertices(f,f_verts); 00527 00528 MT_assert(f_verts.size() >= 3); 00529 00530 BSP_VertexInd root = f_verts[0]; 00531 00532 MT_Scalar area = 0; 00533 00534 for (int i=2; i < f_verts.size(); i++) { 00535 MT_Vector3 a = verts[root].m_pos; 00536 MT_Vector3 b = verts[f_verts[i-1]].m_pos; 00537 MT_Vector3 c = verts[f_verts[i]].m_pos; 00538 00539 MT_Vector3 l1 = b-a; 00540 MT_Vector3 l2 = c-b; 00541 00542 area += (l1.cross(l2)).length()/2; 00543 } 00544 00545 MT_assert(!MT_fuzzyZero(area)); 00546 } 00547 #endif 00548 // Check coplanarity 00549 #if 0 00550 MT_Plane3 plane = FacePlane(f); 00551 00552 const BSP_MFace & face = FaceSet()[f]; 00553 vector<BSP_VertexInd>::const_iterator f_verts_it = face.m_verts.begin(); 00554 vector<BSP_VertexInd>::const_iterator f_verts_end = face.m_verts.end(); 00555 00556 for (;f_verts_it != f_verts_end; ++f_verts_it) { 00557 MT_Scalar dist = plane.signedDistance( 00558 VertexSet()[*f_verts_it].m_pos 00559 ); 00560 00561 MT_assert(fabs(dist) < BSP_SPLIT_EPSILON); 00562 } 00563 #endif 00564 00565 00566 // Check connectivity 00567 00568 vector<BSP_EdgeInd> f_edges; 00569 FaceEdges(f,f_edges); 00570 00571 MT_assert(f_edges.size() == FaceSet()[f].m_verts.size()); 00572 00573 unsigned int i; 00574 for (i = 0; i < f_edges.size(); ++i) { 00575 00576 int matches = 0; 00577 for (unsigned int j = 0; j < EdgeSet()[f_edges[i]].m_faces.size(); j++) { 00578 00579 if (EdgeSet()[f_edges[i]].m_faces[j] == f) matches++; 00580 } 00581 00582 MT_assert(matches == 1); 00583 00584 } 00585 return true; 00586 } 00587 00588 MT_Plane3 00589 BSP_CSGMesh:: 00590 FacePlane( 00591 const BSP_FaceInd & fi 00592 ) const{ 00593 00594 const BSP_MFace & f0 = FaceSet()[fi]; 00595 00596 // Have to be a bit careful here coz the poly may have 00597 // a lot of parallel edges. Should walk round the polygon 00598 // and check length of cross product. 00599 00600 const MT_Vector3 & p1 = VertexSet()[f0.m_verts[0]].m_pos; 00601 const MT_Vector3 & p2 = VertexSet()[f0.m_verts[1]].m_pos; 00602 00603 int face_size = f0.m_verts.size(); 00604 MT_Vector3 n; 00605 00606 for (int i = 2 ; i <face_size; i++) { 00607 const MT_Vector3 & pi = VertexSet()[f0.m_verts[i]].m_pos; 00608 00609 MT_Vector3 l1 = p2-p1; 00610 MT_Vector3 l2 = pi-p2; 00611 n = l1.cross(l2); 00612 MT_Scalar length = n.length(); 00613 00614 if (!MT_fuzzyZero(length)) { 00615 n = n * (1/length); 00616 break; 00617 } 00618 } 00619 return MT_Plane3(n,p1); 00620 } 00621 00622 void 00623 BSP_CSGMesh:: 00624 ComputeFacePlanes( 00625 ){ 00626 00627 int fsize = FaceSet().size(); 00628 int i=0; 00629 for (i = 0; i < fsize; i++) { 00630 00631 FaceSet()[i].m_plane = FacePlane(i); 00632 } 00633 }; 00634 00635 00636 int 00637 BSP_CSGMesh:: 00638 CountTriangles( 00639 ) const { 00640 00641 // Each polygon of n sides can be partitioned into n-3 triangles. 00642 // So we just go through and sum this function of polygon size. 00643 00644 vector<BSP_MFace> & face_set = FaceSet(); 00645 00646 vector<BSP_MFace>::const_iterator face_it = face_set.begin(); 00647 vector<BSP_MFace>::const_iterator face_end = face_set.end(); 00648 00649 int sum = 0; 00650 00651 for (;face_it != face_end; face_it++) { 00652 00653 // Should be careful about degenerate faces here. 00654 sum += face_it->m_verts.size() - 2; 00655 } 00656 00657 return sum; 00658 } 00659