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