3 * ***** BEGIN GPL LICENSE BLOCK *****
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20 * All rights reserved.
22 * The Original Code is: all of this file.
24 * Contributor(s): none yet.
26 * ***** END GPL LICENSE BLOCK *****
29 /** \file bsp/intern/BSP_CSGMesh.cpp
35 #include "BSP_CSGMesh.h"
36 #include "MT_assert.h"
37 #include "CTR_TaggedSetOps.h"
38 #include "MT_Plane3.h"
39 #include "BSP_CSGException.h"
41 // for insert_iterator
63 return new BSP_CSGMesh();
71 BSP_CSGMesh *mesh = New();
72 if (mesh == NULL) return NULL;
74 mesh->m_bbox_max = m_bbox_max;
75 mesh->m_bbox_min = m_bbox_min;
77 if (m_edges != NULL) {
78 mesh->m_edges = new vector<BSP_MEdge>(*m_edges);
79 if (mesh->m_edges == NULL) {
84 if (m_verts != NULL) {
85 mesh->m_verts = new vector<BSP_MVertex>(*m_verts);
86 if (mesh->m_verts == NULL) {
87 if (m_edges != NULL) free(mesh->m_edges);
92 if (m_faces != NULL) {
93 mesh->m_faces = new vector<BSP_MFace>(*m_faces);
94 if (mesh->m_faces == NULL) {
108 vector<BSP_MFace> & faces = FaceSet();
110 vector<BSP_MFace>::const_iterator faces_end = faces.end();
111 vector<BSP_MFace>::iterator faces_it = faces.begin();
113 for (; faces_it != faces_end; ++faces_it) {
121 vector<BSP_MVertex> *verts
123 if (verts == NULL) return false;
125 // create polygon and edge arrays and reserve some space.
126 m_faces = new vector<BSP_MFace>;
127 if (!m_faces) return false;
129 m_faces->reserve(verts->size()/2);
131 // previous verts get deleted here.
142 MT_assert(verts != NULL);
143 MT_assert(num_verts >=3);
145 if (verts == NULL || num_verts <3) return;
147 // make a polyscone from these vertex indices.
149 const BSP_FaceInd fi = m_faces->size();
150 m_faces->push_back(BSP_MFace());
151 BSP_MFace & face = m_faces->back();
153 insert_iterator<vector<BSP_VertexInd> > insert_point(face.m_verts,face.m_verts.end());
154 copy (verts,verts + num_verts,insert_point);
156 // compute and store the plane equation for this face.
158 MT_Plane3 face_plane = FacePlane(fi);
159 face.m_plane = face_plane;
162 // assumes that the face already has a plane equation
166 const BSP_MFace &face
168 m_faces->push_back(face);
177 if (m_faces == NULL) return false;
179 if (m_edges != NULL) {
183 m_edges = new vector<BSP_MEdge>;
185 if (m_edges == NULL) {
190 //iterate through the face set and add edges for all polygon
193 vector<BSP_MFace>::const_iterator f_it_end = FaceSet().end();
194 vector<BSP_MFace>::iterator f_it_begin = FaceSet().begin();
195 vector<BSP_MFace>::iterator f_it = FaceSet().begin();
197 vector<BSP_EdgeInd> dummy;
199 for (;f_it != f_it_end; ++f_it) {
201 BSP_MFace & face = *f_it;
203 int vertex_num = face.m_verts.size();
204 BSP_VertexInd prev_vi(face.m_verts[vertex_num-1]);
206 for (int vert = 0; vert < vertex_num; ++vert) {
208 BSP_FaceInd fi(size_t (f_it - f_it_begin));
209 InsertEdge(prev_vi,face.m_verts[vert],fi,dummy);
210 prev_vi = face.m_verts[vert];
222 if ( m_edges != NULL ) {
227 // Run through the vertices
228 // and clear their edge arrays.
232 vector<BSP_MVertex>::const_iterator vertex_end = VertexSet().end();
233 vector<BSP_MVertex>::iterator vertex_it = VertexSet().begin();
235 for (; vertex_it != vertex_end; ++vertex_it) {
236 vertex_it->m_edges.clear();
245 const BSP_VertexInd & v1,
246 const BSP_VertexInd & v2
249 vector<BSP_MVertex> &verts = VertexSet();
250 vector<BSP_MEdge> &edges = EdgeSet();
256 vector<BSP_EdgeInd> &v1_edges = verts[v1].m_edges;
257 vector<BSP_EdgeInd>::const_iterator v1_end = v1_edges.end();
258 vector<BSP_EdgeInd>::const_iterator v1_begin = v1_edges.begin();
260 for (; v1_begin != v1_end; ++v1_begin) {
261 if (edges[*v1_begin] == e) return *v1_begin;
264 return BSP_EdgeInd::Empty();
270 const BSP_VertexInd & v1,
271 const BSP_VertexInd & v2,
272 const BSP_FaceInd & f,
273 vector<BSP_EdgeInd> &new_edges
276 MT_assert(!v1.IsEmpty());
277 MT_assert(!v2.IsEmpty());
278 MT_assert(!f.IsEmpty());
280 if (v1.IsEmpty() || v2.IsEmpty() || f.IsEmpty()) {
281 BSP_CSGException e(e_mesh_error);
285 vector<BSP_MVertex> &verts = VertexSet();
286 vector<BSP_MEdge> &edges = EdgeSet();
292 // This edge does not exist -- make a new one
295 temp_e.m_verts[0] = v1;
296 temp_e.m_verts[1] = v2;
299 // set the face index from the edge back to this polygon.
300 temp_e.m_faces.push_back(f);
302 m_edges->push_back(temp_e);
304 // add the edge index to it's vertices
305 verts[v1].AddEdge(e);
306 verts[v2].AddEdge(e);
308 new_edges.push_back(e);
312 // edge already exists
313 // insure that there is no polygon already
314 // attached to the other side of this edge
315 // swap the empty face pointer in edge with f
317 BSP_MEdge &edge = edges[e];
319 // set the face index from the edge back to this polygon.
320 edge.m_faces.push_back(f);
328 vector<BSP_MVertex> &
352 if ( m_verts != NULL ) delete m_verts;
353 if ( m_faces != NULL ) delete m_faces;
354 if ( m_edges != NULL ) delete m_edges;
357 // local geometry queries.
358 /////////////////////////
366 const BSP_FaceInd & f,
367 vector<BSP_VertexInd> &output
369 vector<BSP_MFace> & face_set = FaceSet();
372 face_set[f].m_verts.begin(),
373 face_set[f].m_verts.end()
381 const BSP_FaceInd & fi,
382 vector<BSP_EdgeInd> &output
384 // take intersection of the edges emminating from all the vertices
387 vector<BSP_MFace> &faces = FaceSet();
388 vector<BSP_MEdge> &edges = EdgeSet();
390 const BSP_MFace & f = faces[fi];
392 // collect vertex edges;
394 vector<BSP_VertexInd>::const_iterator face_verts_it = f.m_verts.begin();
395 vector<BSP_VertexInd>::const_iterator face_verts_end = f.m_verts.end();
397 vector< vector<BSP_EdgeInd> > vertex_edges(f.m_verts.size());
401 for (;face_verts_it != face_verts_end; ++face_verts_it, ++vector_slot) {
402 VertexEdges(*face_verts_it,vertex_edges[vector_slot]);
405 int prev = vector_slot - 1;
407 // intersect pairs of edge sets
409 for (int i = 0; i < vector_slot;i++) {
410 CTR_TaggedSetOps<BSP_EdgeInd,BSP_MEdge>::IntersectPair(vertex_edges[prev],vertex_edges[i],edges,output);
414 // should always have 3 or more unique edges per face.
415 MT_assert(output.size() >=3);
417 if (output.size() < 3) {
418 BSP_CSGException e(e_mesh_error);
429 const BSP_EdgeInd & e,
430 vector<BSP_VertexInd> &output
432 const vector<BSP_MEdge> &edges = EdgeSet();
433 output.push_back(edges[e].m_verts[0]);
434 output.push_back(edges[e].m_verts[1]);
440 const BSP_EdgeInd & e,
441 vector<BSP_FaceInd> &output
444 vector<BSP_MEdge> & edge_set = EdgeSet();
447 edge_set[e].m_faces.begin(),
448 edge_set[e].m_faces.end()
459 const BSP_VertexInd &v,
460 vector<BSP_EdgeInd> &output
463 vector<BSP_MVertex> & vertex_set = VertexSet();
466 vertex_set[v].m_edges.begin(),
467 vertex_set[v].m_edges.end()
474 const BSP_VertexInd &vi,
475 vector<BSP_FaceInd> &output
478 vector<BSP_MEdge> &edges = EdgeSet();
479 vector<BSP_MFace> &faces = FaceSet();
480 vector<BSP_MVertex> &verts = VertexSet();
482 const vector<BSP_EdgeInd> &v_edges = verts[vi].m_edges;
483 vector<BSP_EdgeInd>::const_iterator e_it = v_edges.begin();
485 for (; e_it != v_edges.end(); ++e_it) {
487 BSP_MEdge &e = edges[*e_it];
489 // iterate through the faces of this edge - push unselected
490 // edges to ouput and then select the edge
492 vector<BSP_FaceInd>::const_iterator e_faces_end = e.m_faces.end();
493 vector<BSP_FaceInd>::iterator e_faces_it = e.m_faces.begin();
495 for (;e_faces_it != e_faces_end; ++e_faces_it) {
497 if (!faces[*e_faces_it].SelectTag()) {
498 output.push_back(*e_faces_it);
499 faces[*e_faces_it].SetSelectTag(true);
504 // deselect selected faces.
505 vector<BSP_FaceInd>::iterator f_it = output.begin();
507 for (; f_it != output.end(); ++f_it) {
508 faces[*f_it].SetSelectTag(false);
522 // check area is greater than zero.
524 vector<BSP_MVertex> & verts = VertexSet();
526 vector<BSP_VertexInd> f_verts;
527 FaceVertices(f,f_verts);
529 MT_assert(f_verts.size() >= 3);
531 BSP_VertexInd root = f_verts[0];
535 for (int i=2; i < f_verts.size(); i++) {
536 MT_Vector3 a = verts[root].m_pos;
537 MT_Vector3 b = verts[f_verts[i-1]].m_pos;
538 MT_Vector3 c = verts[f_verts[i]].m_pos;
543 area += (l1.cross(l2)).length()/2;
546 MT_assert(!MT_fuzzyZero(area));
551 MT_Plane3 plane = FacePlane(f);
553 const BSP_MFace & face = FaceSet()[f];
554 vector<BSP_VertexInd>::const_iterator f_verts_it = face.m_verts.begin();
555 vector<BSP_VertexInd>::const_iterator f_verts_end = face.m_verts.end();
557 for (;f_verts_it != f_verts_end; ++f_verts_it) {
558 MT_Scalar dist = plane.signedDistance(
559 VertexSet()[*f_verts_it].m_pos
562 MT_assert(fabs(dist) < BSP_SPLIT_EPSILON);
567 // Check connectivity
569 vector<BSP_EdgeInd> f_edges;
570 FaceEdges(f,f_edges);
572 MT_assert(f_edges.size() == FaceSet()[f].m_verts.size());
575 for (i = 0; i < f_edges.size(); ++i) {
578 for (unsigned int j = 0; j < EdgeSet()[f_edges[i]].m_faces.size(); j++) {
580 if (EdgeSet()[f_edges[i]].m_faces[j] == f) matches++;
583 MT_assert(matches == 1);
592 const BSP_FaceInd & fi
595 const BSP_MFace & f0 = FaceSet()[fi];
597 // Have to be a bit careful here coz the poly may have
598 // a lot of parallel edges. Should walk round the polygon
599 // and check length of cross product.
601 const MT_Vector3 & p1 = VertexSet()[f0.m_verts[0]].m_pos;
602 const MT_Vector3 & p2 = VertexSet()[f0.m_verts[1]].m_pos;
604 int face_size = f0.m_verts.size();
607 for (int i = 2 ; i <face_size; i++) {
608 const MT_Vector3 & pi = VertexSet()[f0.m_verts[i]].m_pos;
610 MT_Vector3 l1 = p2-p1;
611 MT_Vector3 l2 = pi-p2;
613 MT_Scalar length = n.length();
615 if (!MT_fuzzyZero(length)) {
620 return MT_Plane3(n,p1);
628 int fsize = FaceSet().size();
630 for (i = 0; i < fsize; i++) {
632 FaceSet()[i].m_plane = FacePlane(i);
642 // Each polygon of n sides can be partitioned into n-3 triangles.
643 // So we just go through and sum this function of polygon size.
645 vector<BSP_MFace> & face_set = FaceSet();
647 vector<BSP_MFace>::const_iterator face_it = face_set.begin();
648 vector<BSP_MFace>::const_iterator face_end = face_set.end();
652 for (;face_it != face_end; face_it++) {
654 // Should be careful about degenerate faces here.
655 sum += face_it->m_verts.size() - 2;