(Hopefully) last part of Booleans commit.

Please update, compile (make) and test.
This commit is contained in:
Alexander Ewering 2005-10-28 20:18:56 +00:00
parent d243bfb61e
commit 767bae35f2
5 changed files with 153 additions and 142 deletions

@ -44,6 +44,10 @@
#include "MEM_SmartPtr.h"
#include "stdio.h"
using namespace std;
BSP_CSGHelper::
@ -62,6 +66,11 @@ ComputeOp(
BSP_CSGMesh & output,
CSG_InterpolateUserFaceVertexDataFunc fv_func
){
printf( "*** ComputeOp ***\n" );
// First work out which parts of polygons we want to keep as we pass stuff
// down the tree.

@ -42,6 +42,7 @@
#include "BSP_CSGException.h"
// for vector reverse
#include <iostream>
#include <algorithm>
using namespace std;
@ -50,7 +51,11 @@ BSP_CSGMesh(
) :
MEM_RefCountable()
{
// nothing to do
m_verts = NULL;
m_faces = NULL;
m_edges = NULL;
m_fv_data = NULL;
m_face_data = NULL;
}
BSP_CSGMesh *
@ -65,34 +70,34 @@ BSP_CSGMesh::
NewCopy(
) const {
MEM_SmartPtr<BSP_CSGMesh> mesh = New();
BSP_CSGMesh *mesh = New();
if (mesh == NULL) return NULL;
mesh->m_bbox_max = m_bbox_max;
mesh->m_bbox_min = m_bbox_min;
if (m_edges != NULL) {
mesh->m_edges = new vector<BSP_MEdge>(m_edges.Ref());
mesh->m_edges = new vector<BSP_MEdge>(*m_edges);
if (mesh->m_edges == NULL) return NULL;
}
if (m_verts != NULL) {
mesh->m_verts = new vector<BSP_MVertex>(m_verts.Ref());
mesh->m_verts = new vector<BSP_MVertex>(*m_verts);
if (mesh->m_verts == NULL) return NULL;
}
if (m_faces != NULL) {
mesh->m_faces = new vector<BSP_MFace>(m_faces.Ref());
mesh->m_faces = new vector<BSP_MFace>(*m_faces);
if (mesh->m_faces == NULL) return NULL;
}
if (m_fv_data != NULL) {
mesh->m_fv_data = new BSP_CSGUserData(m_fv_data.Ref());
mesh->m_fv_data = new BSP_CSGUserData(*m_fv_data);
if (mesh->m_fv_data == NULL) return NULL;
}
if (m_face_data != NULL) {
mesh->m_face_data = new BSP_CSGUserData(m_face_data.Ref());
mesh->m_face_data = new BSP_CSGUserData(*m_face_data);
if (mesh->m_face_data == NULL) return NULL;
}
return mesh.Release();
return mesh;
}
void
@ -113,7 +118,7 @@ Invert(
bool
BSP_CSGMesh::
SetVertices(
MEM_SmartPtr<vector<BSP_MVertex> > verts
vector<BSP_MVertex> *verts
){
if (verts == NULL) return false;
@ -131,7 +136,7 @@ SetVertices(
void
BSP_CSGMesh::
SetFaceVertexData(
MEM_SmartPtr<BSP_CSGUserData> fv_data
BSP_CSGUserData *fv_data
){
m_fv_data = fv_data;
}
@ -139,7 +144,7 @@ SetFaceVertexData(
void
BSP_CSGMesh::
SetFaceData(
MEM_SmartPtr<BSP_CSGUserData> f_data
BSP_CSGUserData *f_data
) {
m_face_data = f_data;
}
@ -276,7 +281,10 @@ BuildEdges(
BSP_CSGMesh::
DestroyEdges(
){
m_edges.Delete();
if ( m_edges != NULL ) {
delete m_edges;
m_edges = NULL;
}
// Run through the vertices
// and clear their edge arrays.
@ -383,42 +391,46 @@ InsertEdge(
BSP_CSGMesh::
VertexSet(
) const {
return m_verts.Ref();
return *m_verts;
}
vector<BSP_MFace> &
BSP_CSGMesh::
FaceSet(
) const {
return m_faces.Ref();
return *m_faces;
}
vector<BSP_MEdge> &
BSP_CSGMesh::
EdgeSet(
) const {
return m_edges.Ref();
return *m_edges;
}
BSP_CSGUserData &
BSP_CSGMesh::
FaceVertexData(
) const {
return m_fv_data.Ref();
return *m_fv_data;
}
BSP_CSGUserData &
BSP_CSGMesh::
FaceData(
) const {
return m_face_data.Ref();
return *m_face_data;
}
BSP_CSGMesh::
~BSP_CSGMesh(
){
// member deletion handled by smart ptr;
if ( m_verts != NULL ) delete m_verts;
if ( m_faces != NULL ) delete m_faces;
if ( m_edges != NULL ) delete m_edges;
if ( m_fv_data != NULL ) delete m_fv_data;
if ( m_face_data != NULL ) delete m_face_data;
}
// local geometry queries.
@ -595,7 +607,7 @@ InsertVertexIntoFace(
MT_assert(result != face.m_verts.end());
BSP_CSGUserData & fv_data = m_fv_data.Ref();
BSP_CSGUserData & fv_data = *m_fv_data;
// now we have to check on either side of the result for the
// other vertex

@ -57,17 +57,17 @@ public :
bool
SetVertices(
MEM_SmartPtr<std::vector<BSP_MVertex> > verts
std::vector<BSP_MVertex> *verts
);
void
SetFaceVertexData(
MEM_SmartPtr<BSP_CSGUserData> fv_data
BSP_CSGUserData *fv_data
);
void
SetFaceData(
MEM_SmartPtr<BSP_CSGUserData> f_data
BSP_CSGUserData *f_data
);
void
@ -318,21 +318,20 @@ private :
BSP_CSGMesh(
);
MEM_SmartPtr< std::vector<BSP_MVertex> > m_verts;
MEM_SmartPtr< std::vector<BSP_MFace> > m_faces;
MEM_SmartPtr< std::vector<BSP_MEdge> > m_edges;
std::vector<BSP_MVertex> *m_verts;
std::vector<BSP_MFace> *m_faces;
std::vector<BSP_MEdge> *m_edges;
// The face_vertex user data associated with this mesh
MEM_SmartPtr<BSP_CSGUserData> m_fv_data;
BSP_CSGUserData *m_fv_data;
// The face user data associated with this mesh -
// This is a buffer that maps directly to the face buffer.
// An index into the faces is alos an index into m_face_data
// for that face
MEM_SmartPtr<BSP_CSGUserData> m_face_data;
BSP_CSGUserData *m_face_data;
MT_Vector3 m_bbox_min;

@ -1,5 +1,4 @@
/**
* $Id$
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@ -42,7 +41,7 @@
*/
struct BSP_CSGMesh_VertexIt {
MEM_RefCountPtr<BSP_CSGMesh> mesh;
BSP_CSGMesh *mesh;
BSP_MVertex * pos;
};
@ -133,7 +132,7 @@ BSP_CSGMeshVertexIt_Construct(
*/
struct BSP_CSGMesh_FaceIt {
MEM_RefCountPtr<BSP_CSGMesh> mesh;
BSP_CSGMesh *mesh;
BSP_MFace *pos;
int face_triangle;
};
@ -181,37 +180,70 @@ BSP_CSGMesh_FaceIt_Fill(
// essentially iterating through a triangle fan here.
const int tri_index = face_it->face_triangle;
face->vertex_index[0] = int(face_it->pos->m_verts[0]);
face->vertex_index[1] = int(face_it->pos->m_verts[tri_index + 1]);
face->vertex_index[2] = int(face_it->pos->m_verts[tri_index + 2]);
if (face_it->pos->m_verts.size()>3) {
// QUAD
face->vertex_index[0] = int(face_it->pos->m_verts[0]);
face->vertex_index[1] = int(face_it->pos->m_verts[1]);
face->vertex_index[2] = int(face_it->pos->m_verts[2]);
face->vertex_index[3] = int(face_it->pos->m_verts[3]);
// Copy the user face data across - this does nothing
// if there was no mesh user data.
// Copy the user face data across - this does nothing
// if there was no mesh user data.
// time to change the iterator type to an integer...
face_it->mesh->FaceData().Copy(
face->user_face_data,
int(face_it->pos - &face_it->mesh->FaceSet()[0])
);
// time to change the iterator type to an integer...
face_it->mesh->FaceData().Copy(
face->user_face_data,
int(face_it->pos - &face_it->mesh->FaceSet()[0]));
// Copy face vertex data across...
// Copy face vertex data across...
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[0],
face_it->pos->m_fv_data[0]);
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[0],
face_it->pos->m_fv_data[0]
);
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[1],
face_it->pos->m_fv_data[1]);
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[1],
face_it->pos->m_fv_data[tri_index + 1]
);
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[2],
face_it->pos->m_fv_data[2]);
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[2],
face_it->pos->m_fv_data[tri_index + 2]
);
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[3],
face_it->pos->m_fv_data[3]);
face->vertex_number = 4;
}
else {
// TRIANGLE
face->vertex_index[0] = int(face_it->pos->m_verts[0]);
face->vertex_index[1] = int(face_it->pos->m_verts[1]);
face->vertex_index[2] = int(face_it->pos->m_verts[2]);
face->vertex_number = 3;
// Copy the user face data across - this does nothing
// if there was no mesh user data.
// time to change the iterator type to an integer...
face_it->mesh->FaceData().Copy(
face->user_face_data,
int(face_it->pos - &face_it->mesh->FaceSet()[0]));
// Copy face vertex data across...
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[0],
face_it->pos->m_fv_data[0]);
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[1],
face_it->pos->m_fv_data[1]);
face_it->mesh->FaceVertexData().Copy(
face->user_face_vertex_data[2],
face_it->pos->m_fv_data[2]);
face->vertex_number = 3;
}
};
static
@ -225,12 +257,12 @@ BSP_CSGMesh_FaceIt_Step(
// safety guard
if (face_it->pos < &(*face_it->mesh->FaceSet().end())) {
if (face_it->face_triangle + 3 < face_it->pos->m_verts.size()) {
(face_it->face_triangle)++;
} else {
//if (face_it->face_triangle + 3 < face_it->pos->m_verts.size()) {
// (face_it->face_triangle)++;
//} else {
face_it->face_triangle = 0;
(face_it->pos) ++;
}
//}
}
};
@ -257,7 +289,7 @@ BSP_CSGMesh_FaceIt_Construct(
output->Step = BSP_CSGMesh_FaceIt_Step;
output->Reset = BSP_CSGMesh_FaceIt_Reset;
output->num_elements = mesh->CountTriangles();
output->num_elements = mesh->FaceSet().size();
BSP_CSGMesh_FaceIt * f_it = new BSP_CSGMesh_FaceIt;
f_it->mesh = mesh;

@ -1,5 +1,4 @@
/**
* $Id$
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@ -45,8 +44,13 @@
#include "BSP_CSGUserData.h"
#include "MEM_RefCountPtr.h"
#include "../../boolop/extern/BOP_Interface.h"
#include <iostream>
using namespace std;
#include "BSP_MeshPrimitives.h";
struct BSP_MeshInfo {
MEM_RefCountPtr<BSP_CSGMesh> output_mesh;
BSP_CSGMesh *output_mesh;
CSG_MeshPropertyDescriptor obA_descriptor;
CSG_MeshPropertyDescriptor obB_descriptor;
CSG_MeshPropertyDescriptor output_descriptor;
@ -96,90 +100,55 @@ CSG_DescibeOperands(
return mesh_info->output_descriptor;
}
/**
* Compute the boolean operation, UNION, INTERSECION or DIFFERENCE
*/
int
CSG_PerformBooleanOperation(
CSG_BooleanOperation * operation,
CSG_OperationType op_type,
CSG_FaceIteratorDescriptor obAFaces,
CSG_VertexIteratorDescriptor obAVertices,
CSG_FaceIteratorDescriptor obBFaces,
CSG_VertexIteratorDescriptor obBVertices,
CSG_BooleanOperation *operation,
CSG_OperationType op_type,
CSG_FaceIteratorDescriptor obAFaces,
CSG_VertexIteratorDescriptor obAVertices,
CSG_FaceIteratorDescriptor obBFaces,
CSG_VertexIteratorDescriptor obBVertices,
CSG_InterpolateUserFaceVertexDataFunc interp_func
){
if (operation == NULL) return 0;
BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
if (mesh_info == NULL) return 0;
bool success = 0;
bool success = 1;
obAFaces.Reset(obAFaces.it);
obBFaces.Reset(obBFaces.it);
obAVertices.Reset(obAVertices.it);
obBVertices.Reset(obBVertices.it);
BoolOpType boolType;
switch( op_type ) {
case e_csg_union:
boolType = BOP_UNION;
break;
case e_csg_difference:
boolType = BOP_DIFFERENCE;
break;
default:
boolType = BOP_INTERSECTION;
break;
}
try {
// Build the individual meshes
MEM_SmartPtr<BSP_CSGMesh> obA =
BSP_CSGMeshBuilder::NewMesh(mesh_info->obA_descriptor,obAFaces,obAVertices);
MEM_SmartPtr<BSP_CSGMesh> obB =
BSP_CSGMeshBuilder::NewMesh(mesh_info->obB_descriptor,obBFaces,obBVertices);
// create an empty vertex array for the output mesh
MEM_SmartPtr<vector<BSP_MVertex> > output_verts(new vector<BSP_MVertex>);
// and some user data arrays matching the output descriptor
MEM_SmartPtr<BSP_CSGUserData> output_f_data = new BSP_CSGUserData(
mesh_info->output_descriptor.user_data_size
);
MEM_SmartPtr<BSP_CSGUserData> output_fv_data = new BSP_CSGUserData(
mesh_info->output_descriptor.user_face_vertex_data_size
);
// create the output mesh!
mesh_info->output_mesh = BSP_CSGMesh::New();
if (
obA == NULL ||
obB == NULL ||
output_verts == NULL ||
mesh_info->output_mesh == NULL ||
output_f_data == NULL ||
output_fv_data == NULL
) {
return 0;
}
mesh_info->output_mesh->SetVertices(output_verts);
mesh_info->output_mesh->SetFaceData(output_f_data);
mesh_info->output_mesh->SetFaceVertexData(output_fv_data);
BSP_CSGHelper helper;
// translate enums!
switch(op_type) {
case e_csg_union :
case e_csg_classify :
success = helper.ComputeOp(obA,obB,e_intern_csg_union,
mesh_info->output_mesh.Ref(),interp_func
);
break;
case e_csg_intersection :
success = helper.ComputeOp(obA,obB,e_intern_csg_intersection,
mesh_info->output_mesh.Ref(),interp_func
);
break;
case e_csg_difference :
success = helper.ComputeOp(obA,obB,e_intern_csg_difference,
mesh_info->output_mesh.Ref(),interp_func
);
break;
default :
success = 0;
}
BOP_performBooleanOperation( boolType,
mesh_info->output_descriptor,
(BSP_CSGMesh**) &(mesh_info->output_mesh),
mesh_info->obB_descriptor,
obBFaces,
obBVertices,
mesh_info->obA_descriptor,
obAFaces,
obAVertices,
interp_func );
}
catch(...) {
return 0;
@ -241,19 +210,9 @@ CSG_FreeBooleanOperation(
){
if (operation != NULL) {
BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
delete (mesh_info->output_mesh);
delete(mesh_info);
delete(operation);
}
}