forked from bartvdbraak/blender
(Hopefully) last part of Booleans commit.
Please update, compile (make) and test.
This commit is contained in:
parent
d243bfb61e
commit
767bae35f2
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user