Blender V2.61 - r43446

BSP_CSGMesh.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 
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