Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2006-11-08 23:14:04 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2006-11-08 23:14:04 +0300
commit011f531359102a624126841b7ddf7beb94af1f7e (patch)
treebfb2b4c611f374bf3f2926629952e257ee4886ed
parentcea2b6752bc1f68b829cd24f7611263a98edc897 (diff)
Modified the way booleans preserve face data, and cleaned up some
duplicate code. Also removed redundant files from the bsp module, that where replaced by boolop last year, no sense in updating them for these changes. On the user level things should still work the same, this is only preparation work. Not counting the removed files, -1501 lines of code, not too bad :)
-rw-r--r--intern/boolop/extern/BOP_Interface.h9
-rw-r--r--intern/boolop/intern/BOP_Interface.cpp142
-rw-r--r--intern/boolop/intern/BOP_Material.cpp176
-rw-r--r--intern/boolop/intern/BOP_Material.h80
-rw-r--r--intern/boolop/intern/BOP_MaterialContainer.cpp244
-rw-r--r--intern/boolop/intern/BOP_MaterialContainer.h72
-rw-r--r--intern/boolop/intern/BOP_Mesh.h2
-rwxr-xr-xintern/bsp/extern/CSG_BooleanOps.h73
-rw-r--r--intern/bsp/intern/BSP_CSGHelper.cpp443
-rw-r--r--intern/bsp/intern/BSP_CSGHelper.h99
-rwxr-xr-xintern/bsp/intern/BSP_CSGISplitter.h117
-rwxr-xr-xintern/bsp/intern/BSP_CSGMesh.cpp248
-rwxr-xr-xintern/bsp/intern/BSP_CSGMesh.h95
-rwxr-xr-xintern/bsp/intern/BSP_CSGMeshBuilder.cpp156
-rwxr-xr-xintern/bsp/intern/BSP_CSGMeshBuilder.h74
-rwxr-xr-xintern/bsp/intern/BSP_CSGMeshSplitter.cpp719
-rwxr-xr-xintern/bsp/intern/BSP_CSGMeshSplitter.h205
-rwxr-xr-xintern/bsp/intern/BSP_CSGMesh_CFIterator.h74
-rwxr-xr-xintern/bsp/intern/BSP_CSGNCMeshSplitter.cpp245
-rwxr-xr-xintern/bsp/intern/BSP_CSGNCMeshSplitter.h138
-rwxr-xr-xintern/bsp/intern/BSP_CSGUserData.cpp137
-rwxr-xr-xintern/bsp/intern/BSP_CSGUserData.h136
-rwxr-xr-xintern/bsp/intern/BSP_FragNode.cpp317
-rwxr-xr-xintern/bsp/intern/BSP_FragNode.h125
-rwxr-xr-xintern/bsp/intern/BSP_FragTree.cpp317
-rwxr-xr-xintern/bsp/intern/BSP_FragTree.h141
-rwxr-xr-xintern/bsp/intern/BSP_MeshFragment.cpp281
-rwxr-xr-xintern/bsp/intern/BSP_MeshFragment.h152
-rwxr-xr-xintern/bsp/intern/BSP_MeshPrimitives.cpp8
-rw-r--r--intern/bsp/intern/BSP_MeshPrimitives.h12
-rwxr-xr-xintern/bsp/intern/BSP_Triangulate.cpp254
-rwxr-xr-xintern/bsp/intern/BSP_Triangulate.h130
-rwxr-xr-xintern/bsp/intern/CSG_BooleanOps.cpp56
-rw-r--r--source/blender/blenkernel/BKE_booleanops.h101
-rw-r--r--source/blender/blenkernel/intern/mesh.c3
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenlib/BLI_arithb.h12
-rw-r--r--source/blender/blenlib/intern/arithb.c84
-rw-r--r--source/blender/src/booleanops.c1361
-rw-r--r--source/blender/src/booleanops_mesh.c8
-rw-r--r--source/blender/src/editmesh_tools.c193
41 files changed, 491 insertions, 6750 deletions
diff --git a/intern/boolop/extern/BOP_Interface.h b/intern/boolop/extern/BOP_Interface.h
index 446dd1b79f7..7fe7ae226fd 100644
--- a/intern/boolop/extern/BOP_Interface.h
+++ b/intern/boolop/extern/BOP_Interface.h
@@ -36,18 +36,11 @@
typedef enum EnumBoolOpState {BOP_OK, BOP_NO_SOLID, BOP_ERROR} BoolOpState;
typedef enum EnumBoolOpType {BOP_INTERSECTION=e_csg_intersection, BOP_UNION=e_csg_union, BOP_DIFFERENCE=e_csg_difference} BoolOpType;
-// extern interpolator.
-typedef int (*CSG_InterpolateUserFaceVertexDataFunc)(void *d1, void * d2, void *dnew, float epsilon);
-
BoolOpState BOP_performBooleanOperation(BoolOpType opType,
- CSG_MeshPropertyDescriptor outputProps,
BSP_CSGMesh** outputMesh,
- CSG_MeshPropertyDescriptor obAProps,
CSG_FaceIteratorDescriptor obAFaces,
CSG_VertexIteratorDescriptor obAVertices,
- CSG_MeshPropertyDescriptor obBProps,
CSG_FaceIteratorDescriptor obBFaces,
- CSG_VertexIteratorDescriptor obBVertices,
- CSG_InterpolateUserFaceVertexDataFunc interpFunc);
+ CSG_VertexIteratorDescriptor obBVertices);
#endif
diff --git a/intern/boolop/intern/BOP_Interface.cpp b/intern/boolop/intern/BOP_Interface.cpp
index d069c9d4664..6d1ae56da2d 100644
--- a/intern/boolop/intern/BOP_Interface.cpp
+++ b/intern/boolop/intern/BOP_Interface.cpp
@@ -36,7 +36,6 @@
#include "BOP_Mesh.h"
#include "BOP_Face2Face.h"
#include "BOP_Merge.h"
-#include "BOP_MaterialContainer.h"
#include "BOP_Chrono.h"
//#define DEBUG
@@ -50,18 +49,14 @@ BOP_Face3* BOP_createFace(BOP_Mesh* mesh,
BOP_Index vertex1,
BOP_Index vertex2,
BOP_Index vertex3,
- BOP_Index idxFace);
+ BOP_Index origFace);
void BOP_addMesh(BOP_Mesh* mesh,
BOP_Faces* meshFacesId,
- BOP_MaterialContainer* materials,
- CSG_MeshPropertyDescriptor props,
CSG_FaceIteratorDescriptor& face_it,
CSG_VertexIteratorDescriptor& vertex_it,
bool invert);
-BSP_CSGMesh* BOP_newEmptyMesh(CSG_MeshPropertyDescriptor props);
+BSP_CSGMesh* BOP_newEmptyMesh();
BSP_CSGMesh* BOP_exportMesh(BOP_Mesh* inputMesh,
- BOP_MaterialContainer* materials,
- CSG_MeshPropertyDescriptor props,
bool invert);
void BOP_meshFilter(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp);
void BOP_simplifiedMeshFilter(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp, bool inverted);
@@ -70,27 +65,20 @@ void BOP_meshClassify(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp);
/**
* Performs a generic booleam operation, the entry point for external modules.
* @param opType Boolean operation type BOP_INTERSECTION, BOP_UNION, BOP_DIFFERENCE
- * @param outputProps Output mesh properties
* @param outputMesh Output mesh, the final result (the object C)
- * @param obAProps Object A properties
* @param obAFaces Object A faces list
* @param obAVertices Object A vertices list
- * @param obBProps Object B properties
* @param obBFaces Object B faces list
* @param obBVertices Object B vertices list
* @param interpFunc Interpolating function
* @return operation state: BOP_OK, BOP_NO_SOLID, BOP_ERROR
*/
BoolOpState BOP_performBooleanOperation(BoolOpType opType,
- CSG_MeshPropertyDescriptor outputProps,
BSP_CSGMesh** outputMesh,
- CSG_MeshPropertyDescriptor obAProps,
CSG_FaceIteratorDescriptor obAFaces,
CSG_VertexIteratorDescriptor obAVertices,
- CSG_MeshPropertyDescriptor obBProps,
CSG_FaceIteratorDescriptor obBFaces,
- CSG_VertexIteratorDescriptor obBVertices,
- CSG_InterpolateUserFaceVertexDataFunc interpFunc)
+ CSG_VertexIteratorDescriptor obBVertices)
{
#ifdef DEBUG
cout << "BEGIN BOP_performBooleanOperation" << endl;
@@ -111,15 +99,11 @@ BoolOpState BOP_performBooleanOperation(BoolOpType opType,
// Build C-mesh, the output mesh
BOP_Mesh meshC;
- // Prepare the material container
- BOP_MaterialContainer materials;
- materials.setInterpFunc(interpFunc);
-
// Add A-mesh into C-mesh
- BOP_addMesh(&meshC, &meshAFacesId, &materials, obAProps, obAFaces, obAVertices, invertMeshA);
+ BOP_addMesh(&meshC, &meshAFacesId, obAFaces, obAVertices, invertMeshA);
// Add B-mesh into C-mesh
- BOP_addMesh(&meshC, &meshBFacesId, &materials, obBProps, obBFaces, obBVertices, invertMeshB);
+ BOP_addMesh(&meshC, &meshBFacesId, obBFaces, obBVertices, invertMeshB);
// for now, allow operations on non-manifold (non-solid) meshes
#if 0
@@ -132,7 +116,7 @@ BoolOpState BOP_performBooleanOperation(BoolOpType opType,
invertMeshA, invertMeshB);
// Invert the output mesh if is required
- *outputMesh = BOP_exportMesh(&meshC, &materials, outputProps, invertMeshC);
+ *outputMesh = BOP_exportMesh(&meshC, invertMeshC);
#ifdef DEBUG
cout << "END BOP_performBooleanOperation" << endl;
@@ -324,37 +308,33 @@ void BOP_meshClassify(BOP_Mesh* meshC, BOP_Faces* faces, BOP_BSPTree* bsp)
* @param vertex1 first vertex of the new face
* @param vertex2 second vertex of the new face
* @param vertex3 third vertex of the new face
- * @param idxFace identifier of the new face
+ * @param origFace identifier of the new face
* @return new the new face
*/
BOP_Face3 *BOP_createFace3(BOP_Mesh* mesh,
BOP_Index vertex1,
BOP_Index vertex2,
BOP_Index vertex3,
- BOP_Index idxFace)
+ BOP_Index origFace)
{
MT_Point3 p1 = mesh->getVertex(vertex1)->getPoint();
MT_Point3 p2 = mesh->getVertex(vertex2)->getPoint();
MT_Point3 p3 = mesh->getVertex(vertex3)->getPoint();
MT_Plane3 plane(p1,p2,p3);
- return new BOP_Face3(vertex1, vertex2, vertex3, plane, idxFace);
+ return new BOP_Face3(vertex1, vertex2, vertex3, plane, origFace);
}
/**
* Adds mesh information into destination mesh.
* @param mesh input/output mesh, destination for the new mesh data
* @param meshFacesId output mesh faces, contains an added faces list
- * @param materials used to store material data
- * @param props Properties of the input mesh data
* @param face_it faces iterator
* @param vertex_it vertices iterator
* @param inverted if TRUE adding inverted faces, non-inverted otherwise
*/
void BOP_addMesh(BOP_Mesh* mesh,
BOP_Faces* meshFacesId,
- BOP_MaterialContainer* materials,
- CSG_MeshPropertyDescriptor props,
CSG_FaceIteratorDescriptor& face_it,
CSG_VertexIteratorDescriptor& vertex_it,
bool invert)
@@ -374,46 +354,12 @@ void BOP_addMesh(BOP_Mesh* mesh,
// now for the polygons.
// we may need to decalare some memory for user defined face properties.
- unsigned int sizeFace = props.user_data_size;
- if (sizeFace) {
- face.user_face_data = new char[sizeFace];
- }
- else {
- face.user_face_data = NULL;
- }
-
- unsigned int sizeVertex = props.user_face_vertex_data_size;
- if (sizeVertex) {
- char * fv_data2 = NULL;
- fv_data2 = new char[4 * sizeVertex];
-
- face.user_face_vertex_data[0] = fv_data2;
- face.user_face_vertex_data[1] = fv_data2 + sizeVertex;
- face.user_face_vertex_data[2] = fv_data2 + 2*sizeVertex;
- face.user_face_vertex_data[3] = fv_data2 + 3*sizeVertex;
- }
- else {
- face.user_face_vertex_data[0] = NULL;
- face.user_face_vertex_data[1] = NULL;
- face.user_face_vertex_data[2] = NULL;
- face.user_face_vertex_data[3] = NULL;
- }
- unsigned int idFaceMaterial;
- BOP_Material faceMaterial(sizeFace,sizeVertex);
- BOP_Material* materialHandler;
BOP_Face3 *newface;
while (!face_it.Done(face_it.it)) {
face_it.Fill(face_it.it,&face);
- faceMaterial.setFaceMaterial((char *)face.user_face_data);
- faceMaterial.setFaceVertexMaterial((char *)face.user_face_vertex_data[0]);
- faceMaterial.setOriginalFace(mesh->getNumFaces());
- faceMaterial.setIsQuad(face.vertex_number == 4);
- idFaceMaterial = materials->addMaterial(faceMaterial);
- materialHandler = materials->getMaterial(idFaceMaterial);
-
// Let's not rely on quads being coplanar - especially if they
// are coming out of that soup of code from blender...
if (face.vertex_number == 4){
@@ -423,40 +369,32 @@ void BOP_addMesh(BOP_Mesh* mesh,
face.vertex_index[2] + vtxIndexOffset,
face.vertex_index[0] + vtxIndexOffset,
face.vertex_index[3] + vtxIndexOffset,
- idFaceMaterial);
+ face.orig_face);
meshFacesId->push_back(newface);
mesh->addFace(newface);
- materialHandler->setOriginalFaceVertex(newface->getVertex(0),2);
- materialHandler->setOriginalFaceVertex(newface->getVertex(1),0);
- materialHandler->setOriginalFaceVertex(newface->getVertex(2),3);
newface = BOP_createFace3(mesh,
face.vertex_index[2] + vtxIndexOffset,
face.vertex_index[1] + vtxIndexOffset,
face.vertex_index[0] + vtxIndexOffset,
- idFaceMaterial);
+ face.orig_face);
meshFacesId->push_back(newface);
mesh->addFace(newface);
- materialHandler->setOriginalFaceVertex(newface->getVertex(1),1);
}
else {
newface = BOP_createFace3(mesh,
face.vertex_index[0] + vtxIndexOffset,
face.vertex_index[2] + vtxIndexOffset,
face.vertex_index[3] + vtxIndexOffset,
- idFaceMaterial);
+ face.orig_face);
meshFacesId->push_back(newface);
mesh->addFace(newface);
- materialHandler->setOriginalFaceVertex(newface->getVertex(0),0);
- materialHandler->setOriginalFaceVertex(newface->getVertex(1),2);
- materialHandler->setOriginalFaceVertex(newface->getVertex(2),3);
newface = BOP_createFace3(mesh,
face.vertex_index[0] + vtxIndexOffset,
face.vertex_index[1] + vtxIndexOffset,
face.vertex_index[2] + vtxIndexOffset,
- idFaceMaterial);
+ face.orig_face);
meshFacesId->push_back(newface);
mesh->addFace(newface);
- materialHandler->setOriginalFaceVertex(newface->getVertex(1),1);
}
}
else {
@@ -466,54 +404,37 @@ void BOP_addMesh(BOP_Mesh* mesh,
face.vertex_index[2] + vtxIndexOffset,
face.vertex_index[1] + vtxIndexOffset,
face.vertex_index[0] + vtxIndexOffset,
- idFaceMaterial);
+ face.orig_face);
meshFacesId->push_back(newface);
mesh->addFace(newface);
- materialHandler->setOriginalFaceVertex(newface->getVertex(0),2);
- materialHandler->setOriginalFaceVertex(newface->getVertex(1),1);
- materialHandler->setOriginalFaceVertex(newface->getVertex(2),0);
}
else {
newface = BOP_createFace3(mesh,
face.vertex_index[0] + vtxIndexOffset,
face.vertex_index[1] + vtxIndexOffset,
face.vertex_index[2] + vtxIndexOffset,
- idFaceMaterial);
+ face.orig_face);
meshFacesId->push_back(newface);
mesh->addFace(newface);
- materialHandler->setOriginalFaceVertex(newface->getVertex(0),0);
- materialHandler->setOriginalFaceVertex(newface->getVertex(1),1);
- materialHandler->setOriginalFaceVertex(newface->getVertex(2),2);
}
}
face_it.Step(face_it.it);
}
-
- // delete temporal material data
- if (face.user_face_data)
- delete[] static_cast<char *>(face.user_face_data);
- if (face.user_face_vertex_data)
- delete[] static_cast<char *>(face.user_face_vertex_data[0]);
}
/**
* Returns an empty mesh with the specified properties.
- * @param props Output mesh properties
* @return a new empty mesh
*/
-BSP_CSGMesh* BOP_newEmptyMesh(CSG_MeshPropertyDescriptor props)
+BSP_CSGMesh* BOP_newEmptyMesh()
{
BSP_CSGMesh* mesh = BSP_CSGMesh::New();
if (mesh == NULL) return mesh;
vector<BSP_MVertex>* vertices = new vector<BSP_MVertex>;
- BSP_CSGUserData* faceData = new BSP_CSGUserData(props.user_data_size);
- BSP_CSGUserData* faceVtxData = new BSP_CSGUserData(props.user_face_vertex_data_size);
mesh->SetVertices(vertices);
- mesh->SetFaceData(faceData);
- mesh->SetFaceVertexData(faceVtxData);
return mesh;
}
@@ -521,24 +442,16 @@ BSP_CSGMesh* BOP_newEmptyMesh(CSG_MeshPropertyDescriptor props)
/**
* Exports a BOP_Mesh to a BSP_CSGMesh.
* @param mesh Input mesh
- * @param materials used to reconstruct original faces materials
- * @param props Properties of output mesh
* @param invert if TRUE export with inverted faces, no inverted otherwise
* @return the corresponding new BSP_CSGMesh
*/
BSP_CSGMesh* BOP_exportMesh(BOP_Mesh* mesh,
- BOP_MaterialContainer* materials,
- CSG_MeshPropertyDescriptor props,
bool invert)
{
- BSP_CSGMesh* outputMesh = BOP_newEmptyMesh(props);
+ BSP_CSGMesh* outputMesh = BOP_newEmptyMesh();
if (outputMesh == NULL) return NULL;
- // User data handlers
- BSP_CSGUserData* outputFaceVtxData = &(outputMesh->FaceVertexData());
- BSP_CSGUserData* outputFaceData = &(outputMesh->FaceData());
-
// vtx index dictionary, to translate indeces from input to output.
map<int,unsigned int> dic;
map<int,unsigned int>::iterator itDic;
@@ -549,9 +462,6 @@ BSP_CSGMesh* BOP_exportMesh(BOP_Mesh* mesh,
BOP_Faces faces = mesh->getFaces();
BOP_Vertexs vertexs = mesh->getVertexs();
- // Reserve temporal memory
- char* tmpFaceVtxData = new char[props.user_face_vertex_data_size];
-
for (BOP_IT_Faces face = faces.begin(); face != faces.end(); face++) {
if ((*face)->getTAG()!=BROKEN){
// Add output face
@@ -560,11 +470,8 @@ BSP_CSGMesh* BOP_exportMesh(BOP_Mesh* mesh,
// Copy face
outFace.m_verts.clear();
- outFace.m_fv_data.clear();
outFace.m_plane = (*face)->getPlane();
-
- // Copy face user data from input mesh
- outputFaceData->Duplicate(materials->getFaceMaterial((*face)->getOriginalFace()));
+ outFace.m_orig_face = (*face)->getOriginalFace();
// invert face if is required
if (invert) (*face)->invert();
@@ -587,22 +494,11 @@ BSP_CSGMesh* BOP_exportMesh(BOP_Mesh* mesh,
// The vertex is added
outVtxId = BSP_VertexInd(itDic->second);
}
-
- // Add vertex to output face
- outFace.m_verts.push_back(outVtxId);
- // Add face vertex user data
- char* faceVtxData = materials->getFaceVertexMaterial(mesh,
- (*face)->getOriginalFace(),
- (mesh->getVertex(idVertex))->getPoint(),
- tmpFaceVtxData);
- BSP_UserFVInd userFVInd(outputFaceVtxData->Duplicate((void*) faceVtxData));
- outFace.m_fv_data.push_back(userFVInd);
+ outFace.m_verts.push_back(outVtxId);
}
}
}
- // free temporal memory
- delete[] tmpFaceVtxData;
// Build the mesh edges using topological informtion
outputMesh->BuildEdges();
diff --git a/intern/boolop/intern/BOP_Material.cpp b/intern/boolop/intern/BOP_Material.cpp
deleted file mode 100644
index 01892d2accc..00000000000
--- a/intern/boolop/intern/BOP_Material.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#include "BOP_Material.h"
-#include <iostream>
-using namespace std;
-
-/**
- * Constructs a new material.
- * @param faceWidth face material size in bytes.
- * @param faceVertexWidth verex face material size in bytes.
- */
-BOP_Material::BOP_Material(int faceWidth, int faceVertexWidth)
-{
- m_faceWidth = faceWidth;
- m_faceVertexWidth = faceVertexWidth;
-
- m_faceMaterial = new char[m_faceWidth];
- m_faceVertexMaterial = new char[N_FACE_VERTEX*m_faceVertexWidth];
-}
-
-/**
- * Constructs a new material duplicating the other object data.
- * @param other the other object to copy the data.
- */
-BOP_Material::BOP_Material(const BOP_Material& other)
-{
- m_faceWidth = other.getFaceWidth();
- m_faceVertexWidth = other.getFaceVertexWidth();
-
- m_faceMaterial = new char[m_faceWidth];
- m_faceVertexMaterial = new char[N_FACE_VERTEX*m_faceVertexWidth];
-
- duplicate(other);
-}
-
-/**
- * Destroys a material.
- */
-BOP_Material::~BOP_Material()
-{
- delete[] m_faceMaterial;
- delete[] m_faceVertexMaterial;
-}
-
-/**
- * Duplicates the face material passed by argument.
- * @param faceMaterial pointer to face material data.
- */
-void BOP_Material::setFaceMaterial(char* faceMaterial)
-{
- memcpy(m_faceMaterial, faceMaterial, m_faceWidth);
-}
-
-/**
- * Duplicates the all face vertex materials passed by argument. It's supossed
- * that all face vertex materials positions are consecutive.
- * @param faceVertexMaterial pointer to firts vertex face material.
- */
-void BOP_Material::setFaceVertexMaterial(char* faceVertexMaterial)
-{
- memcpy(m_faceVertexMaterial, faceVertexMaterial, N_FACE_VERTEX*m_faceVertexWidth);
-}
-
-/**
- * Duplicates on i-position the face vertex material passed by argument.
- * @param faceMaterial pointer to face vertex material.
- * @param i destination position of new face vertex material (0<=i<4)
- */
-void BOP_Material::setFaceVertexMaterial(char* faceVertexMaterial, int i)
-{
- if (i>=0&&i<N_FACE_VERTEX)
- memcpy(m_faceVertexMaterial+i*m_faceVertexWidth, faceVertexMaterial, m_faceVertexWidth);
-}
-
-/**
- * Duplicates the other material object data.
- * @param other the other material object.
- */
-void BOP_Material::duplicate(const BOP_Material& other)
-{
- setOriginalFace(other.getOriginalFace());
- setIsQuad(other.isQuad());
- for (int i=0;i<N_FACE_VERTEX;++i)
- setOriginalFaceVertex(other.getOriginalFaceVertex(i),i);
- setFaceMaterial(other.getFaceMaterial());
- setFaceVertexMaterial(other.getFaceVertexMaterial(0));
-}
-
-/**
- * Implements operator =
- */
-BOP_Material& BOP_Material::operator = (const BOP_Material& other)
-{
- if (other.getFaceWidth() == m_faceWidth && other.getFaceVertexWidth() == m_faceVertexWidth)
- duplicate(other);
- return (*this);
-}
-
-/**
- * Returns the original face vertex material using a input vtx id. The input vtx IDs
- * are mapped to output ids, this one is used to obtain the original face vertex
- * material.
- * @param originalFaceVertex input vertex id (0..3)
- * @return pointer to original face vertex material if it exist, NULL otherwise.
- */
-char* BOP_Material::getOriginalFaceVertexMaterial(int originalFaceVertex)
-{
- int N = isQuad() ? 4 : 3;
- int i = 0;
- bool b = false;
- while (i<N&&!b){
- if (m_originalFaceVertices[i]==originalFaceVertex) b = true;
- else i++;
- }
- return b ? getFaceVertexMaterial(i) : m_faceVertexMaterial; /* ton: NULL return crashes... */
-}
-
-/**
- * Returns the face material pointer.
- * @return pointer to face material.
- */
-char* BOP_Material::getFaceMaterial() const
-{
- return m_faceMaterial;
-}
-
-/**
- * Returns the face vertex material at i position.
- * @param i index of face vertex material.
- * @return pointer to face vertex material.
- */
-inline char* BOP_Material::getFaceVertexMaterial(int i) const
-{
- return i>=0&&i<N_FACE_VERTEX ? m_faceVertexMaterial + i*m_faceVertexWidth : NULL;
-}
-
-/**
- * Implements operator <<
- */
-ostream &operator<<(ostream &stream, BOP_Material *m)
-{
- cout << "(" << m->getOriginalFace() << ") < ";
- int N = m->isQuad() ? 4 : 3;
- for (int i=0;i<N;++i) cout << m->getOriginalFaceVertex(i) << " ";
- cout << ">" << endl;
-
- return stream;
-}
diff --git a/intern/boolop/intern/BOP_Material.h b/intern/boolop/intern/BOP_Material.h
deleted file mode 100644
index 079cc614410..00000000000
--- a/intern/boolop/intern/BOP_Material.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BOP_MATERIAL_H
-#define BOP_MATERIAL_H
-
-#include <iostream>
-using namespace std;
-
-#define N_FACE_VERTEX 4
-
-class BOP_Material
-{
-private:
- char* m_faceMaterial;
- char* m_faceVertexMaterial;
- int m_faceWidth;
- int m_faceVertexWidth;
- int m_originalFace;
- int m_originalFaceVertices[N_FACE_VERTEX];
- bool m_isQuad;
-
-public:
- BOP_Material(int faceWidth, int faceVertexWidth);
- BOP_Material(const BOP_Material& other);
- ~BOP_Material();
- void setFaceMaterial(char* faceMaterial);
- void setFaceVertexMaterial(char* faceVertexMaterial);
- void setFaceVertexMaterial(char* faceVertexMaterial, int i);
- void duplicate(const BOP_Material& other);
- BOP_Material& operator = (const BOP_Material& other);
- char* getFaceMaterial() const;
- char* getFaceVertexMaterial(int i) const;
- int getFaceWidth() const { return m_faceWidth; };
- int getFaceVertexWidth() const { return m_faceVertexWidth; };
-
- void setOriginalFace(int originalFace) {m_originalFace = originalFace;};
- int getOriginalFace() const {return m_originalFace;};
- void setOriginalFaceVertex(int originalFaceVertex, int i) {
- if (0<=i&&i<N_FACE_VERTEX) m_originalFaceVertices[i] = originalFaceVertex;
- };
- int getOriginalFaceVertex(int i) const {
- if (0<=i&&i<N_FACE_VERTEX) return m_originalFaceVertices[i];
- else return -1;
- };
- char* getOriginalFaceVertexMaterial(int originalFaceVertex);
- void setIsQuad(bool quad) {m_isQuad = quad;};
- bool isQuad() const {return m_isQuad;};
-
- friend ostream &operator<<(ostream &stream, BOP_Material *m);
-};
-
-#endif
diff --git a/intern/boolop/intern/BOP_MaterialContainer.cpp b/intern/boolop/intern/BOP_MaterialContainer.cpp
deleted file mode 100644
index 6ade5b0649f..00000000000
--- a/intern/boolop/intern/BOP_MaterialContainer.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/**
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#include <iostream>
-#include "BOP_MaterialContainer.h"
-#include "BOP_MathUtils.h"
-#include "MEM_SmartPtr.h"
-
-/**
- * Constructs a new material container.
- */
-BOP_MaterialContainer::BOP_MaterialContainer()
-{
- m_interpFunc = NULL;
-}
-
-/**
- * Destroys a material container.
- */
-BOP_MaterialContainer::~BOP_MaterialContainer()
-{
-}
-
-/**
- * Adds a new material to this container.
- * @param m material material object to add.
- * @return the new material index.
- */
-BOP_Index BOP_MaterialContainer::addMaterial(BOP_Material m)
-{
- m_materialList.push_back(m);
- return m_materialList.size()-1;
-}
-
-/**
- * Updates the interpolation function of this container.
- * @param interpFunc the interpolation function.
- */
-void BOP_MaterialContainer::setInterpFunc(CSG_InterpolateUserFaceVertexDataFunc interpFunc)
-{
- m_interpFunc = interpFunc;
-}
-
-/**
- * Returns the material list.
- * @return
- */
-BOP_Materials& BOP_MaterialContainer::getMaterialList()
-{
- return m_materialList;
-}
-
-/**
- * Returns the material with the specified index.
- * @param index material index.
- * @return material with the specified index.
- */
-BOP_Material* BOP_MaterialContainer::getMaterial(BOP_Index index)
-{
- return index < m_materialList.size() ? &(m_materialList[index]) : NULL;
-}
-
-/**
- * Returns the pointer to face material specified by index.
- * @param index material index.
- * @return pointer to face material.
- */
-char* BOP_MaterialContainer::getFaceMaterial(BOP_Index index)
-{
- if (index < m_materialList.size())
- return m_materialList[index].getFaceMaterial();
- else return NULL;
-}
-
-/**
- * Returns a pointer to face vertex material, if is the material not exist, then
- * returns an interpoled material.
- * @param mesh original mesh data.
- * @param originalFaceIndex index to the original mesh face.
- * @param point point who needs a material.
- * @param faceVertexMaterial pointer to mem region where the material will be
- * saved.
- * @return pointer to the face vertex material.
- */
-char* BOP_MaterialContainer::getFaceVertexMaterial(BOP_Mesh *mesh,
- BOP_Index originalFaceIndex,
- MT_Point3 point,
- char* faceVertexMaterial)
-{
- unsigned int i;
-
- if (originalFaceIndex>=m_materialList.size()) return NULL;
-
- BOP_Material& material = m_materialList[originalFaceIndex];
-
- if (material.isQuad()) {
-
- BOP_Face *face1 = mesh->getFace(material.getOriginalFace());
- BOP_Face *face2 = mesh->getFace(material.getOriginalFace()+1);
-
- if (!face1 || !face2) return NULL;
-
- // Search original point
- for (i=0;i<face1->size();i++) {
- if (point == mesh->getVertex(face1->getVertex(i))->getPoint()) {
- return material.getOriginalFaceVertexMaterial(face1->getVertex(i));
- }
- }
- for (i=0;i<face2->size();i++) {
- if (point == mesh->getVertex(face2->getVertex(i))->getPoint()) {
- return material.getOriginalFaceVertexMaterial(face2->getVertex(i));
- }
- }
- // wich is the half quad where the point is?
- MT_Vector3 N = face1->getPlane().Normal();
- MT_Point3 p0 = mesh->getVertex(face1->getVertex(0))->getPoint();
- MT_Point3 q(p0.x()+N.x(),p0.y()+N.y(),p0.z()+N.z());
- MT_Point3 p2 = mesh->getVertex(face1->getVertex(1))->getPoint();
- MT_Plane3 plane(p0,p2,q);
-
- if (BOP_sign(plane.signedDistance(point))==-1) {
- // first half quad
- faceVertexMaterial = interpolateMaterial(mesh, face1, material, point, faceVertexMaterial);
- }
- else {
- // second half quad
- faceVertexMaterial = interpolateMaterial(mesh, face2, material, point, faceVertexMaterial);
- }
- }
- else {
- BOP_Face *face1 = mesh->getFace(material.getOriginalFace());
-
- if (!face1) return NULL;
-
- // Search original point
- for (i=0;i<face1->size();i++) {
- if (point == mesh->getVertex(face1->getVertex(i))->getPoint())
- return material.getOriginalFaceVertexMaterial(face1->getVertex(i));
- }
-
- faceVertexMaterial = interpolateMaterial(mesh, face1, material, point, faceVertexMaterial);
- }
-
- return faceVertexMaterial;
-}
-
-/**
- * Performs vertex data interpolation.
- * @param mesh original mesh data.
- * @param face face used to interpolate an interior face point material
- * @param material face material, input data for implementation.
- * @param point interpolated point.
- * @param faceVertexMaterial pointer to memory region.
- * @return pointer to face vertex material.
- */
-char* BOP_MaterialContainer::interpolateMaterial(BOP_Mesh* mesh,
- BOP_Face* face,
- BOP_Material& material,
- MT_Point3 point,
- char* faceVertexMaterial)
-{
- // (p1)-----(I)------(p2)
- // \ | /
- // \ | /
- // \ | /
- // \ (point) /
- // \ | /
- // \ | /
- // \ | /
- // (p3)
-
- MT_Point3 p1 = mesh->getVertex(face->getVertex(0))->getPoint();
- MT_Point3 p2 = mesh->getVertex(face->getVertex(1))->getPoint();
- MT_Point3 p3 = mesh->getVertex(face->getVertex(2))->getPoint();
- MT_Point3 I = BOP_4PointIntersect(p1, p2, p3, point);
- MT_Scalar epsilon0 = 1.0-BOP_EpsilonDistance(p1, p2, I);
- MT_Scalar epsilon1 = 1.0-BOP_EpsilonDistance(I, p3, point);
-
- // Interpolate data
- if (m_interpFunc) {
- // temporal data
- char* faceVertexMaterialTemp = new char[material.getFaceVertexWidth()];
-
- (*m_interpFunc)(material.getOriginalFaceVertexMaterial(face->getVertex(0)),
- material.getOriginalFaceVertexMaterial(face->getVertex(1)),
- faceVertexMaterialTemp,
- epsilon0);
-
- (*m_interpFunc)(faceVertexMaterialTemp,
- material.getOriginalFaceVertexMaterial(face->getVertex(2)),
- faceVertexMaterial,
- epsilon1);
-
- // free temporal data
- delete[] faceVertexMaterialTemp;
-
- }
- else faceVertexMaterial = NULL;
-
- // return the result
- return (char*) faceVertexMaterial;
-}
-
-/**
- * Implements operator <<
- */
-ostream &operator<<(ostream &stream, BOP_MaterialContainer *mc)
-{
- stream << "***[ Material List ]***********************************************" << endl;
- BOP_IT_Materials it;
- for (it=mc->getMaterialList().begin();it!=mc->getMaterialList().end();++it) {
- stream << "[" << it - mc->getMaterialList().begin() << "] ";
- stream << &(*it);
- }
- stream << "*******************************************************************" << endl;
- return stream;
-}
diff --git a/intern/boolop/intern/BOP_MaterialContainer.h b/intern/boolop/intern/BOP_MaterialContainer.h
deleted file mode 100644
index c6de4cd96e5..00000000000
--- a/intern/boolop/intern/BOP_MaterialContainer.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BOP_MATERIALCONTAINER_H
-#define BOP_MATERIALCONTAINER_H
-
-#include "BOP_Mesh.h"
-#include "BOP_Material.h"
-#include "BOP_Interface.h"
-#include <vector>
-using namespace std;
-
-typedef vector<BOP_Material> BOP_Materials;
-typedef vector<BOP_Material>::iterator BOP_IT_Materials;
-
-class BOP_MaterialContainer
-{
-private:
- BOP_Materials m_materialList;
- CSG_InterpolateUserFaceVertexDataFunc m_interpFunc;
-
-public:
- BOP_MaterialContainer();
- ~BOP_MaterialContainer();
- BOP_Index addMaterial(BOP_Material m);
- void setInterpFunc(CSG_InterpolateUserFaceVertexDataFunc interpFunc);
- BOP_Materials& getMaterialList();
- BOP_Material* getMaterial(BOP_Index index);
- char* getFaceMaterial(BOP_Index index);
- char* getFaceVertexMaterial(BOP_Mesh *mesh,
- BOP_Index originalFaceIndex,
- MT_Point3 point,
- char* faceVertexMaterial);
-
- friend ostream &operator<<(ostream &stream, BOP_MaterialContainer *mc);
-
-private:
- char* interpolateMaterial(BOP_Mesh* mesh,
- BOP_Face* face,
- BOP_Material& material,
- MT_Point3 point,
- char* faceVertexMaterial);
-};
-
-#endif
diff --git a/intern/boolop/intern/BOP_Mesh.h b/intern/boolop/intern/BOP_Mesh.h
index 557939441fc..f671b9a96c9 100644
--- a/intern/boolop/intern/BOP_Mesh.h
+++ b/intern/boolop/intern/BOP_Mesh.h
@@ -78,7 +78,7 @@ private:
bool testFace(BOP_Face *face);
public:
- BOP_Mesh ();
+ BOP_Mesh();
~BOP_Mesh();
BOP_Index addVertex(MT_Point3 point);
diff --git a/intern/bsp/extern/CSG_BooleanOps.h b/intern/bsp/extern/CSG_BooleanOps.h
index 418b81a62b3..1e862568cda 100755
--- a/intern/bsp/extern/CSG_BooleanOps.h
+++ b/intern/bsp/extern/CSG_BooleanOps.h
@@ -62,9 +62,7 @@ extern "C" {
typedef struct {
int vertex_index[4];
int vertex_number;
-
- void *user_face_vertex_data[4];
- void *user_face_data;
+ int orig_face;
} CSG_IFace;
/**
@@ -82,22 +80,6 @@ typedef struct {
*/
/**
- * Descibes the data stored in a mesh available through the
- * CSG_IFace interface.
- * user_data_size is the number of bytes of user_data associated with each CSG_IFace
- * user_face_vertex_data size is the number of bytes of user data associated with
- * every face vertex tuple.
- * .
- */
-
-typedef struct CSG_MeshPropertyDescriptor{
- unsigned int user_face_vertex_data_size;
- unsigned int user_data_size;
-} CSG_MeshPropertyDescriptor;
-
-
-
-/**
* @section Iterator abstraction.
*
* The CSG module asks blender to fill in an instance of the above
@@ -180,22 +162,6 @@ typedef struct CSG_VertexIteratorDescriptor {
* // deal with low memory exception
* }
*
- * // Describe each mesh operand to the module.
- * // NOTE: example properties!
- * CSG_MeshPropertyDescriptor propA,propB;
- * propA.user_data_size = 0;
- * propA.user_face_vertex_data = 0;
- * propB.user_face_vertex_data = 0;
- * propB.user_data_size = 0;
- *
- * // Get the output properties of the mesh.
- * CSG_MeshPropertyDescriptor output_properties;
- * output_properties = CSG_DescibeOperands(
- * operation,
- * propA,
- * propB
- * );
- *
* // Report to the user if they will loose any data!
* ...
*
@@ -304,40 +270,6 @@ CSG_NewBooleanFunction(
);
/**
- * Describe the operands of a boolean function to the module.
- * The description takes the form of a pair of CSG_MeshPropertyDescriptors
- * one for each input mesh. The operands do not have to have the same
- * properties, for example operandA may have vertex colours but operandB none.
- * In this case the CSG module will choose the lowest common denominator in
- * mesh properies. The function returns a description of
- * the output mesh. You can use this to warn the user that certain properties
- * will be lost. Of course it also describes what fields in the output mesh
- * will contain valid data.
- */
- CSG_MeshPropertyDescriptor
-CSG_DescibeOperands(
- CSG_BooleanOperation * operation,
- CSG_MeshPropertyDescriptor operandA_desciption,
- CSG_MeshPropertyDescriptor operandB_desciption
-);
-
-/**
- * The user data is handled by the BSP modules through
- * the following function which is called whenever the
- * module needs new face vertex properties (when a face is split).
- * d1,d2 are pointers to existing vertex face data. dnew is
- * a pointer to an allocated but unfilled area of user data of
- * size user_face_vertex_data_size in the CSG_MeshPropertyDescriptor
- * returned by a call to the above function. Epsilon is the relative
- * distance (between [0,1]) of the new vertex and the vertex associated
- * with d1. Use epsilon to interpolate the face vertex data in d1 and d2
- * and fill dnew
- */
-
-typedef int (*CSG_InterpolateUserFaceVertexDataFunc)(void *d1, void * d2, void *dnew, float epsilon);
-
-
-/**
* Attempt to perform a boolean operation between the 2 objects of the
* desired type. This may fail due to an internal error or lack of memory.
* In this case 0 is returned, otehrwise 1 is returned indicating success.
@@ -359,8 +291,7 @@ CSG_PerformBooleanOperation(
CSG_FaceIteratorDescriptor obAFaces,
CSG_VertexIteratorDescriptor obAVertices,
CSG_FaceIteratorDescriptor obBFaces,
- CSG_VertexIteratorDescriptor obBVertices,
- CSG_InterpolateUserFaceVertexDataFunc interp_func
+ CSG_VertexIteratorDescriptor obBVertices
);
/**
diff --git a/intern/bsp/intern/BSP_CSGHelper.cpp b/intern/bsp/intern/BSP_CSGHelper.cpp
deleted file mode 100644
index 9c686828a23..00000000000
--- a/intern/bsp/intern/BSP_CSGHelper.cpp
+++ /dev/null
@@ -1,443 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "BSP_CSGHelper.h"
-
-#include "BSP_CSGMesh.h"
-#include "BSP_MeshFragment.h"
-#include "BSP_FragTree.h"
-#include "BSP_CSGMeshSplitter.h"
-#include "BSP_CSGNCMeshSplitter.h"
-#include "BSP_Triangulate.h"
-
-#include "MEM_SmartPtr.h"
-
-
-#include "stdio.h"
-
-
-using namespace std;
-
-BSP_CSGHelper::
-BSP_CSGHelper(
-)
-{
- // nothing to do
-}
-
- bool
-BSP_CSGHelper::
-ComputeOp(
- BSP_CSGMesh * obA,
- BSP_CSGMesh * obB,
- BSP_OperationType op_type,
- 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.
-
- BSP_Classification e_ATreeB,e_BTreeA;
- bool invertA(false),invertB(false);
-
- switch (op_type) {
- case e_intern_csg_union :
- e_ATreeB = e_classified_out;
- e_BTreeA = e_classified_out;
- break;
- case e_intern_csg_intersection :
- e_ATreeB = e_classified_in;
- e_BTreeA = e_classified_in;
- break;
- case e_intern_csg_difference :
- invertA = true;
- e_ATreeB = e_classified_in;
- e_BTreeA = e_classified_in;
- break;
- default :
- return false;
- }
-
- if (invertA) {
- obA->Invert();
- }
-
- if (invertB) {
- obB->Invert();
- }
-
- MEM_SmartPtr<BSP_CSGMesh> obA_copy = obA->NewCopy();
- MEM_SmartPtr<BSP_CSGMesh> obB_copy = obB->NewCopy();
-
- // ok we need yet another copy...
-
- MEM_SmartPtr<BSP_CSGMesh> obA_copy2 = obA->NewCopy();
- MEM_SmartPtr<BSP_CSGMesh> obB_copy2 = obB->NewCopy();
-
- obA_copy->BuildEdges();
- obB_copy->BuildEdges();
-
- // Create a splitter to help chop up the mesh and preserrve.
- // mesh connectivity
-
- MEM_SmartPtr<BSP_CSGMeshSplitter> splitter = new BSP_CSGMeshSplitter(fv_func);
- if (splitter == NULL) return false;
-
- // Create a splitter to help chop the mesh for tree building.
- MEM_SmartPtr<BSP_CSGNCMeshSplitter> nc_splitter = new BSP_CSGNCMeshSplitter();
-
- if (splitter == NULL || nc_splitter == NULL) return false;
-
- // Create a tree for both meshes.
-
- MEM_SmartPtr<BSP_FragTree> treeA = treeA->New(obA,nc_splitter.Ref());
- MEM_SmartPtr<BSP_FragTree> treeB = treeB->New(obB,nc_splitter.Ref());
-
- if (treeA == NULL || treeB == NULL) {
- return false;
- }
-
- // Classify each object wrt the other tree.
-
- MEM_SmartPtr<BSP_MeshFragment> AinB = new BSP_MeshFragment(obA_copy2,e_classified_in);
- MEM_SmartPtr<BSP_MeshFragment> AoutB = new BSP_MeshFragment(obA_copy2,e_classified_out);
- MEM_SmartPtr<BSP_MeshFragment> AonB = new BSP_MeshFragment(obA_copy2,e_classified_on);
-
- treeB->Classify(obA_copy2,AinB,AoutB,AonB,nc_splitter.Ref());
-
- MEM_SmartPtr<BSP_MeshFragment> BinA = new BSP_MeshFragment(obB_copy2,e_classified_in);
- MEM_SmartPtr<BSP_MeshFragment> BoutA = new BSP_MeshFragment(obB_copy2,e_classified_out);
- MEM_SmartPtr<BSP_MeshFragment> BonA = new BSP_MeshFragment(obB_copy2,e_classified_on);
-
- treeA->Classify(obB_copy2,BinA,BoutA,BonA,nc_splitter.Ref());
-
- // Now we need to work what were the spanning polygons from the original mesh.
- // Build a spanning fragment from them and pass split those mothers.
-
- MEM_SmartPtr<BSP_MeshFragment> frag_BTreeA2 = new BSP_MeshFragment(obA_copy,e_BTreeA);
- MEM_SmartPtr<BSP_MeshFragment> AspanningB = new BSP_MeshFragment(obA_copy,e_classified_spanning);
-
- TranslateSplitFragments(AinB.Ref(),AoutB.Ref(),AonB.Ref(),e_BTreeA,AspanningB.Ref(),frag_BTreeA2.Ref());
-
- MEM_SmartPtr<BSP_MeshFragment> frag_ATreeB2 = new BSP_MeshFragment(obB_copy,e_ATreeB);
- MEM_SmartPtr<BSP_MeshFragment> BspanningA = new BSP_MeshFragment(obB_copy,e_classified_spanning);
-
- TranslateSplitFragments(BinA.Ref(),BoutA.Ref(),BonA.Ref(),e_ATreeB,BspanningA.Ref(),frag_ATreeB2.Ref());
-
-
- MEM_SmartPtr<BSP_MeshFragment> frag_ATreeB = new BSP_MeshFragment(obB_copy,e_ATreeB);
- MEM_SmartPtr<BSP_MeshFragment> frag_BTreeA = new BSP_MeshFragment(obA_copy,e_BTreeA);
-
- if (frag_ATreeB == NULL || frag_BTreeA == NULL) return false;
-
- // Pass the spanning polygons of copyB through the tree of copyA.
- treeA->Push(BspanningA,frag_ATreeB,e_ATreeB,e_classified_spanning,true,splitter.Ref());
-
- // Add the result of the push to the fragments we are interested in.
- MergeFrags(frag_ATreeB2.Ref(),frag_ATreeB.Ref());
-
- // Pass the spanning polygons of copyA through the tree of copyB
- treeB->Push(AspanningB,frag_BTreeA,e_BTreeA,e_classified_spanning,false,splitter.Ref());
- MergeFrags(frag_BTreeA2.Ref(),frag_BTreeA.Ref());
-
- // Copy the fragments into a new mesh.
- DuplicateMesh(frag_ATreeB.Ref(),output);
- DuplicateMesh(frag_BTreeA.Ref(),output);
-
- return true;
-
-};
-
- void
-BSP_CSGHelper::
-TranslateSplitFragments(
- const BSP_MeshFragment & in_frag,
- const BSP_MeshFragment & out_frag,
- const BSP_MeshFragment & on_frag,
- BSP_Classification keep,
- BSP_MeshFragment & spanning_frag,
- BSP_MeshFragment & output
-){
-
- // iterate through the 3 input fragments
- // tag the polygons in the output fragments according to
- // the classification of the input frags.
-
- const BSP_CSGMesh *i_mesh = in_frag.Mesh();
- BSP_CSGMesh *o_mesh = output.Mesh();
-
- const vector<BSP_MFace> &i_faces = i_mesh->FaceSet();
- vector<BSP_MFace> &o_faces = o_mesh->FaceSet();
-
- vector<BSP_FaceInd>::const_iterator if_it = in_frag.FaceSet().begin();
- vector<BSP_FaceInd>::const_iterator if_end = in_frag.FaceSet().end();
-
- for (;if_it != if_end; ++if_it) {
- int original_index = i_faces[*if_it].OpenTag();
- if (original_index == -1) {
- // then this face was never split and the original_index is
- // the actual face index.
- original_index = *if_it;
- }
- // tag the output faces with the in flag.
- if (o_faces[original_index].OpenTag() == -1) {
- o_faces[original_index].SetOpenTag(0);
- }
- o_faces[original_index].SetOpenTag(
- o_faces[original_index].OpenTag() | e_classified_in
- );
- }
-
- // same for out fragments.
- if_it = out_frag.FaceSet().begin();
- if_end = out_frag.FaceSet().end();
-
- for (;if_it != if_end; ++if_it) {
- int original_index = i_faces[*if_it].OpenTag();
- if (original_index == -1) {
- // then this face was never split and the original_index is
- // the actual face index.
- original_index = *if_it;
- }
- // tag the output faces with the in flag.
- if (o_faces[original_index].OpenTag() == -1) {
- o_faces[original_index].SetOpenTag(0);
- }
- o_faces[original_index].SetOpenTag(
- o_faces[original_index].OpenTag() | e_classified_out
- );
- }
-
- // on fragments just get set as spanning for now.
-
- if_it = on_frag.FaceSet().begin();
- if_end = on_frag.FaceSet().end();
-
- for (;if_it != if_end; ++if_it) {
- int original_index = i_faces[*if_it].OpenTag();
- if (original_index == -1) {
- // then this face was never split and the original_index is
- // the actual face index.
- original_index = *if_it;
- }
- // tag the output faces with the in flag.
- if (o_faces[original_index].OpenTag() == -1) {
- o_faces[original_index].SetOpenTag(0);
- }
- o_faces[original_index].SetOpenTag(
- o_faces[original_index].OpenTag() | e_classified_spanning
- );
- }
- // now run through the output faces.
- // collect the ones we are interested in into output
- // and collect the spanning faces.
-
- int of_it = 0;
- int of_size = o_faces.size();
-
- for (;of_it < of_size; ++of_it) {
-
- int p_class = o_faces[of_it].OpenTag();
-
- if (p_class == int(keep)) {
- output.FaceSet().push_back(BSP_FaceInd(of_it));
- } else
- if (
- (p_class == (e_classified_in | e_classified_out)) ||
- p_class == e_classified_spanning
- ) {
- spanning_frag.FaceSet().push_back(BSP_FaceInd(of_it));
- }
- }
-}
-
-
- void
-BSP_CSGHelper::
-MergeFrags(
- const BSP_MeshFragment & in,
- BSP_MeshFragment & out
-){
-
- // Add the 2 frags together.
-
- out.FaceSet().insert(
- out.FaceSet().end(),
- in.FaceSet().begin(),
- in.FaceSet().end()
- );
-}
-
-
-
-BSP_CSGHelper::
-~BSP_CSGHelper(
-){
- // nothing to do
-}
-
- void
-BSP_CSGHelper::
-DuplicateMesh(
- const BSP_MeshFragment & frag,
- BSP_CSGMesh & output
-){
-
- // This stuff is a real waste of time.
- // much better to create an output iterator based upon
- // the 2 mesh fragments alone.
-
- vector<BSP_MVertex> & o_verts = output.VertexSet();
- BSP_CSGUserData & o_fv_data = output.FaceVertexData();
- BSP_CSGUserData & o_f_data = output.FaceData();
-
- // A temporary buffer containing the triangulated
- // vertex indices.
-
- vector<int> triangle_indices;
-
- BSP_CSGMesh * i_mesh = frag.Mesh();
-
- if (i_mesh == NULL) return;
-
- vector<BSP_MVertex> & i_verts = i_mesh->VertexSet();
- const vector<BSP_MFace> & i_faces = i_mesh->FaceSet();
- BSP_CSGUserData & i_fv_data = i_mesh->FaceVertexData();
- BSP_CSGUserData & i_f_data = i_mesh->FaceData();
-
- // iterate through the fragment's face set
- const vector<BSP_FaceInd> & frag_faces = frag.FaceSet();
-
- vector<BSP_FaceInd>::const_iterator f_faces_it = frag_faces.begin();
- vector<BSP_FaceInd>::const_iterator f_faces_end = frag_faces.end();
-
- // We need to keep track of which vertices we are selecting.
- vector<int> selected_vi;
-
- BSP_Triangulate triangulator;
-
- for (; f_faces_it != f_faces_end; ++f_faces_it) {
-
- BSP_FaceInd fi = *f_faces_it;
- const BSP_MFace &face = i_faces[fi];
-
- // duplicate the face
- BSP_MFace dup_face(face);
-
- // iterate through the face's vertex indices.
- vector<BSP_VertexInd>::iterator dup_f_verts_it = dup_face.m_verts.begin();
- vector<BSP_VertexInd>::const_iterator dup_f_verts_end = dup_face.m_verts.end();
-
- for (; dup_f_verts_it != dup_f_verts_end; ++dup_f_verts_it) {
-
- if (i_verts[*dup_f_verts_it].SelectTag() == false) {
- // copy this vertex onto the output mesh vertex array.
-
- BSP_VertexInd new_vi(o_verts.size());
- o_verts.push_back(i_verts[*dup_f_verts_it]);
-
- // should kill the old vertices edge ptrs.
- o_verts[new_vi].m_edges.clear();
-
- // set the open tag in the old vert to the new one.
- i_verts[*dup_f_verts_it].SetOpenTag(new_vi);
-
- // select the old vertex
- i_verts[*dup_f_verts_it].SetSelectTag(true);
- selected_vi.push_back(*dup_f_verts_it);
- }
-
- // we have been to this vertex before and there should be
- // a corresponding vertex in the new mesh vertex set.
- *dup_f_verts_it = i_verts[*dup_f_verts_it].OpenTag();
- }
-
- // duplicate the face vertex data for this polygon.
-
- vector<BSP_UserFVInd>::iterator dup_fv_it = dup_face.m_fv_data.begin();
- vector<BSP_UserFVInd>::const_iterator dup_fv_end = dup_face.m_fv_data.end();
-
- for (;dup_fv_it != dup_fv_end; ++dup_fv_it) {
- *dup_fv_it = o_fv_data.Duplicate(i_fv_data[int(*dup_fv_it)]);
- }
-
- triangle_indices.clear();
-
- // Now triangulate the polygon.
- if (!triangulator.Process(
- o_verts,
- dup_face.m_verts,
- dup_face.m_plane,
- triangle_indices
- )) {
- // Sometimes the triangulator can fail for very small
- // polygons or very thing polygons. This should be
- // handled more elegantly but for now we just leave out the
- // polygon from the mesh.
- continue;
- }
-
- // Run through the result and add in the triangle faces.
-
- unsigned int i;
- for (i = 0; i < triangle_indices.size(); i+=3) {
- // duplicate the face data for this face.
- o_f_data.Duplicate(i_f_data[*f_faces_it]);
-
- output.AddSubTriangle(dup_face,&triangle_indices[i]);
- }
- }
-
- // of course we have to deselect the vertices again.
-
- vector<int>::const_iterator selected_vi_it = selected_vi.begin();
- vector<int>::const_iterator selected_vi_end = selected_vi.end();
-
- for (; selected_vi_it != selected_vi_end; ++selected_vi_it) {
- i_verts[*selected_vi_it].SetSelectTag(false);
- }
-}
-
-
-
-
-
-
-
diff --git a/intern/bsp/intern/BSP_CSGHelper.h b/intern/bsp/intern/BSP_CSGHelper.h
deleted file mode 100644
index b6b88422358..00000000000
--- a/intern/bsp/intern/BSP_CSGHelper.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BSP_CSGHELPER_H
-#define BSP_CSGHELPER_H
-
-class BSP_CSGMesh;
-class BSP_MeshFragment;
-
-#include "../extern/CSG_BooleanOps.h"
-#include "BSP_MeshPrimitives.h"
-
-enum BSP_OperationType{
- e_intern_csg_union,
- e_intern_csg_intersection,
- e_intern_csg_difference
-};
-
-class BSP_CSGHelper {
-public :
-
- BSP_CSGHelper(
- );
-
- bool
- ComputeOp(
- BSP_CSGMesh * obA,
- BSP_CSGMesh * obB,
- BSP_OperationType op_type,
- BSP_CSGMesh & output,
- CSG_InterpolateUserFaceVertexDataFunc fv_func
- );
-
-
- ~BSP_CSGHelper(
- );
-
-private:
-
- // Iterate through the fragment,
- // add new vertices to output,
- // map polygons to new vertices.
-
- void
- DuplicateMesh(
- const BSP_MeshFragment & frag,
- BSP_CSGMesh & output
- );
-
- void
- TranslateSplitFragments(
- const BSP_MeshFragment & in_frag,
- const BSP_MeshFragment & out_frag,
- const BSP_MeshFragment & on_frag,
- BSP_Classification keep,
- BSP_MeshFragment & spanning_frag,
- BSP_MeshFragment & output
- );
-
- void
- MergeFrags(
- const BSP_MeshFragment & in,
- BSP_MeshFragment & out
- );
-
-
-
-};
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_CSGISplitter.h b/intern/bsp/intern/BSP_CSGISplitter.h
deleted file mode 100755
index 17392fd07be..00000000000
--- a/intern/bsp/intern/BSP_CSGISplitter.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BSP_CSGISplitter_h
-#define BSP_CSGISplitter_h
-
-class BSP_MeshFragment;
-class BSP_CSGMesh;
-
-class MT_Plane3;
-
-/**
- * This class defines a mesh splitter interface.
- * It embodies the action of splitting a mesh by a plane.
- * Depending on the context of the operation subclasses
- * may wish to define different implementations. For example
- * with building a BSP tree from a mesh, the mesh does not
- * need to be kept consistent, it doesn't matter if the edges
- * are maintained etc. However when pushing polygons through
- * a BSP tree (say for CSG operations)it is important to
- * try and maintain mesh connectivity and thus a different
- * splitter implementation may be needed.
- *
- * This is an abstract interface class.
- */
-
-class BSP_CSGISplitter
-{
-
-public:
-
- /**
- * Split the incoming mesh fragment (frag)
- * by the plane, put the output into (in,out and on)
- * Subclasses should clear the contents of the
- * in_coming fragment.
- */
-
- virtual
- void
- Split(
- const MT_Plane3& plane,
- BSP_MeshFragment *frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
- )= 0;
-
- /**
- * Split the entire mesh with respect to the plane.
- * and place ouput into (in,out and on).
- * Subclasses should clear the contents of the
- * in_coming fragment.
- */
- virtual
- void
- Split(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
- )=0;
-
- virtual
- ~BSP_CSGISplitter(
- ){
- };
-
-protected :
-
- BSP_CSGISplitter(
- ) {
- //nothing to do
- }
-
- BSP_CSGISplitter(
- const BSP_CSGISplitter &
- ) {
- //nothing to do
- }
-};
-
-
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_CSGMesh.cpp b/intern/bsp/intern/BSP_CSGMesh.cpp
index 36f00868240..5da39c8d551 100755
--- a/intern/bsp/intern/BSP_CSGMesh.cpp
+++ b/intern/bsp/intern/BSP_CSGMesh.cpp
@@ -33,7 +33,6 @@
#include "BSP_CSGMesh.h"
#include "MT_assert.h"
#include "CTR_TaggedSetOps.h"
-#include "BSP_MeshFragment.h"
#include "MT_Plane3.h"
#include "BSP_CSGException.h"
@@ -50,8 +49,6 @@ BSP_CSGMesh(
m_verts = NULL;
m_faces = NULL;
m_edges = NULL;
- m_fv_data = NULL;
- m_face_data = NULL;
}
BSP_CSGMesh *
@@ -94,20 +91,6 @@ NewCopy(
return NULL;
}
}
- if (m_fv_data != NULL) {
- mesh->m_fv_data = new BSP_CSGUserData(*m_fv_data);
- if (mesh->m_fv_data == NULL) {
- delete mesh;
- return NULL;
- }
- }
- if (m_face_data != NULL) {
- mesh->m_face_data = new BSP_CSGUserData(*m_face_data);
- if (mesh->m_face_data == NULL) {
- delete mesh;
- return NULL;
- }
- }
return mesh;
}
@@ -145,23 +128,6 @@ SetVertices(
return true;
}
- void
-BSP_CSGMesh::
-SetFaceVertexData(
- BSP_CSGUserData *fv_data
-){
- m_fv_data = fv_data;
-}
-
- void
-BSP_CSGMesh::
-SetFaceData(
- BSP_CSGUserData *f_data
-) {
- m_face_data = f_data;
-}
-
-
void
BSP_CSGMesh::
AddPolygon(
@@ -188,51 +154,6 @@ AddPolygon(
face.m_plane = face_plane;
};
- void
-BSP_CSGMesh::
-AddPolygon(
- const int * verts,
- const int * fv_indices,
- int num_verts
-){
- // This creates a new polygon on the end of the face list.
- AddPolygon(verts,num_verts);
-
- BSP_MFace & face = m_faces->back();
- // now we just fill in the fv indices
-
- if (fv_indices) {
- insert_iterator<vector<BSP_UserFVInd> > insert_point(face.m_fv_data,face.m_fv_data.end());
- copy(fv_indices,fv_indices + num_verts,insert_point);
- } else {
- face.m_fv_data.insert(face.m_fv_data.end(),num_verts,BSP_UserFVInd::Empty());
- }
-}
-
-
- void
-BSP_CSGMesh::
-AddSubTriangle(
- const BSP_MFace &iface,
- const int * index_info
-){
- // This creates a new polygon on the end of the face list.
-
- m_faces->push_back(BSP_MFace());
- BSP_MFace & face = m_faces->back();
-
- face.m_verts.push_back(iface.m_verts[index_info[0]]);
- face.m_verts.push_back(iface.m_verts[index_info[1]]);
- face.m_verts.push_back(iface.m_verts[index_info[2]]);
-
- face.m_fv_data.push_back(iface.m_fv_data[index_info[0]]);
- face.m_fv_data.push_back(iface.m_fv_data[index_info[1]]);
- face.m_fv_data.push_back(iface.m_fv_data[index_info[2]]);
-
- face.m_plane = iface.m_plane;
-}
-
-
// assumes that the face already has a plane equation
void
BSP_CSGMesh::
@@ -420,29 +341,12 @@ EdgeSet(
return *m_edges;
}
- BSP_CSGUserData &
-BSP_CSGMesh::
-FaceVertexData(
-) const {
- return *m_fv_data;
-}
-
- BSP_CSGUserData &
-BSP_CSGMesh::
-FaceData(
-) const {
- return *m_face_data;
-}
-
-
BSP_CSGMesh::
~BSP_CSGMesh(
){
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.
@@ -600,158 +504,6 @@ VertexFaces(
}
}
- void
-BSP_CSGMesh::
-InsertVertexIntoFace(
- BSP_MFace & face,
- const BSP_VertexInd & v1,
- const BSP_VertexInd & v2,
- const BSP_VertexInd & vi,
- CSG_InterpolateUserFaceVertexDataFunc fv_split_func,
- MT_Scalar epsilon
-){
- // We assume that the face vertex data indices
- // are consistent with the vertex inidex data.
-
- // look for v1
- vector<BSP_VertexInd>::iterator result =
- find(face.m_verts.begin(),face.m_verts.end(),v1);
-
- MT_assert(result != face.m_verts.end());
-
- BSP_CSGUserData & fv_data = *m_fv_data;
-
- // now we have to check on either side of the result for the
- // other vertex
-
- vector<BSP_VertexInd>::iterator prev = result - 1;
- if (prev < face.m_verts.begin()) {
- prev = face.m_verts.end() -1;
- }
- if (*prev == v2) {
-
- // so result <=> v2 and prev <=> v1
-
- // create space for new face vertex data
-
- int vf_i = fv_data.Size();
- fv_data.IncSize();
-
- int vf_i2 = prev - face.m_verts.begin();
- int vf_i1 = result - face.m_verts.begin();
-
- (*fv_split_func)(
- fv_data[int(face.m_fv_data[vf_i1])],
- fv_data[int(face.m_fv_data[vf_i2])],
- fv_data[vf_i],
- epsilon
- );
-
- // insert vertex data index.
- face.m_fv_data.insert(face.m_fv_data.begin() + vf_i1,vf_i);
- face.m_verts.insert(result,vi);
-
- return;
- }
-
- vector<BSP_VertexInd>::iterator next = result + 1;
- if (next >= face.m_verts.end()) {
- next = face.m_verts.begin();
- }
- if (*next == v2) {
-
- // so result <=> v1 and next <=> v2
-
- int vf_i = fv_data.Size();
- fv_data.IncSize();
-
- int vf_i2 = int(next - face.m_verts.begin());
- int vf_i1 = int(result - face.m_verts.begin());
-
- (*fv_split_func)(
- fv_data[int(face.m_fv_data[vf_i1])],
- fv_data[int(face.m_fv_data[vf_i2])],
- fv_data[vf_i],
- epsilon
- );
-
- // insert vertex data index.
- face.m_fv_data.insert(face.m_fv_data.begin() + vf_i2,vf_i);
- face.m_verts.insert(next,vi);
-
- return;
- }
-
- // if we get here we are in trouble.
- MT_assert(false);
- BSP_CSGException e(e_mesh_error);
- throw(e);
-}
-
- void
-BSP_CSGMesh::
-SetBBox(
- const MT_Vector3 & min,
- const MT_Vector3 & max
-){
- m_bbox_min = min;
- m_bbox_max = max;
-}
-
-
- void
-BSP_CSGMesh::
-BBox(
- MT_Vector3 &min,
- MT_Vector3 &max
-) const {
- min = m_bbox_min;
- max = m_bbox_max;
-}
-
-
-// Update the BBox
-//////////////////
-
- void
-BSP_CSGMesh::
-UpdateBBox(
-){
- // TODO
-};
-
- void
-BSP_CSGMesh::
-SC_Classification(
- BSP_FaceInd f,
- const MT_Plane3& plane
-){
- const BSP_MFace & face = FaceSet()[f];
-
- vector<BSP_VertexInd>::const_iterator f_verts_it = face.m_verts.begin();
- vector<BSP_VertexInd>::const_iterator f_verts_end = face.m_verts.end();
-
- for (;f_verts_it != f_verts_end; ++f_verts_it) {
-
- const BSP_MVertex & vert = VertexSet()[*f_verts_it];
-
- MT_Scalar dist = plane.signedDistance(
- vert.m_pos
- );
-
- if (fabs(dist) <= BSP_SPLIT_EPSILON ){
- MT_assert(BSP_Classification(vert.OpenTag()) == e_classified_on);
- } else
- if (dist > BSP_SPLIT_EPSILON) {
- MT_assert(BSP_Classification(vert.OpenTag()) == e_classified_out);
- } else
- if (dist < BSP_SPLIT_EPSILON) {
- MT_assert(BSP_Classification(vert.OpenTag()) == e_classified_in);
- }
- }
-}
-
-
bool
BSP_CSGMesh::
SC_Face(
diff --git a/intern/bsp/intern/BSP_CSGMesh.h b/intern/bsp/intern/BSP_CSGMesh.h
index 2d966ffa401..47903520157 100755
--- a/intern/bsp/intern/BSP_CSGMesh.h
+++ b/intern/bsp/intern/BSP_CSGMesh.h
@@ -36,12 +36,10 @@
#include "MEM_SmartPtr.h"
#include "MEM_RefCountPtr.h"
#include "MEM_NonCopyable.h"
-#include "BSP_CSGUserData.h"
#include "../extern/CSG_BooleanOps.h"
class MT_Plane3;
-class BSP_MeshFragment;
class BSP_CSGMesh :
public MEM_NonCopyable,
@@ -61,34 +59,11 @@ public :
);
void
- SetFaceVertexData(
- BSP_CSGUserData *fv_data
- );
-
- void
- SetFaceData(
- BSP_CSGUserData *f_data
- );
-
- void
AddPolygon(
const int * verts,
int num_verts
);
- void
- AddPolygon(
- const int * verts,
- const int * fv_indices,
- int num_verts
- );
-
- void
- AddSubTriangle(
- const BSP_MFace &iface,
- const int * index_info
- );
-
// assumes that the face already has a plane equation
void
AddPolygon(
@@ -142,14 +117,6 @@ public :
EdgeSet(
) const;
- BSP_CSGUserData &
- FaceVertexData(
- ) const;
-
- BSP_CSGUserData &
- FaceData(
- ) const;
-
~BSP_CSGMesh(
);
@@ -213,29 +180,6 @@ public :
) const;
- // Bounding box methods
- ///////////////////////
-
- void
- SetBBox(
- const MT_Vector3 & min,
- const MT_Vector3 & max
- );
-
- void
- BBox(
- MT_Vector3 &min,
- MT_Vector3 &max
- ) const ;
-
- // Update the BBox
- //////////////////
-
- void
- UpdateBBox(
- );
-
-
/**
* Sanity checkers
*/
@@ -248,16 +192,6 @@ public :
);
/**
- * Make sure the polygons vertex classification is correct
- */
-
- void
- SC_Classification(
- BSP_FaceInd f,
- const MT_Plane3&plane
- );
-
- /**
* Return the face plane equation
*/
@@ -285,23 +219,6 @@ public :
CountTriangles(
) const;
- /**
- * Insert a vertex index into a polygon
- * and call the external splitting function to
- * generate a new face vertex property.
- */
-
- void
- InsertVertexIntoFace(
- BSP_MFace & face,
- const BSP_VertexInd & v1,
- const BSP_VertexInd & v2,
- const BSP_VertexInd & vi,
- CSG_InterpolateUserFaceVertexDataFunc fv_split_func,
- MT_Scalar epsilon
- );
-
-
private :
void
@@ -322,18 +239,6 @@ private :
std::vector<BSP_MFace> *m_faces;
std::vector<BSP_MEdge> *m_edges;
- // The face_vertex user data associated with this mesh
-
- 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
-
- BSP_CSGUserData *m_face_data;
-
-
MT_Vector3 m_bbox_min;
MT_Vector3 m_bbox_max;
diff --git a/intern/bsp/intern/BSP_CSGMeshBuilder.cpp b/intern/bsp/intern/BSP_CSGMeshBuilder.cpp
deleted file mode 100755
index 7e5b7e67fe8..00000000000
--- a/intern/bsp/intern/BSP_CSGMeshBuilder.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "BSP_CSGMeshBuilder.h"
-
-
-using namespace std;
-
- MEM_SmartPtr<BSP_CSGMesh>
-BSP_CSGMeshBuilder::
-NewMesh(
- CSG_MeshPropertyDescriptor &props,
- CSG_FaceIteratorDescriptor &face_it,
- CSG_VertexIteratorDescriptor &vertex_it
-) {
-
- MEM_SmartPtr<BSP_CSGMesh> mesh = BSP_CSGMesh::New();
- if (mesh == NULL) return NULL;
-
- MEM_SmartPtr<BSP_CSGUserData> fv_data = new BSP_CSGUserData(props.user_face_vertex_data_size);
- MEM_SmartPtr<BSP_CSGUserData> face_data = new BSP_CSGUserData(props.user_data_size);
-
-
- MEM_SmartPtr<vector<BSP_MVertex> > vertices(new vector<BSP_MVertex>);
- if (vertices == NULL || fv_data == NULL || face_data == NULL) return NULL;
-
- // The size of the vertex data array will be at least the number of faces.
-
- fv_data->Reserve(face_it.num_elements);
- face_data->Reserve(face_it.num_elements);
-
- vertices->reserve(vertex_it.num_elements);
-
- CSG_IVertex vertex;
-
- while (!vertex_it.Done(vertex_it.it)) {
- vertex_it.Fill(vertex_it.it,&vertex);
-
- MT_Point3 pos(vertex.position);
- vertices->push_back(BSP_MVertex(pos));
-
- vertex_it.Step(vertex_it.it);
- }
-
- // pass ownership of the vertices to the mesh.
- mesh->SetVertices(vertices);
-
- // now for the polygons.
-
- CSG_IFace face;
- // we may need to decalare some memory for user defined face properties.
-
- if (props.user_data_size) {
- face.user_face_data = new char[props.user_data_size];
- } else {
- face.user_face_data = NULL;
- }
-
- if (props.user_face_vertex_data_size) {
- char * fv_data2 = NULL;
- fv_data2 = new char[4 * props.user_face_vertex_data_size];
-
- face.user_face_vertex_data[0] = fv_data2;
- face.user_face_vertex_data[1] = fv_data2 + props.user_face_vertex_data_size;
- face.user_face_vertex_data[2] = fv_data2 + 2*props.user_face_vertex_data_size;
- face.user_face_vertex_data[3] = fv_data2 + 3*props.user_face_vertex_data_size;
- } else {
- face.user_face_vertex_data[0] = NULL;
- face.user_face_vertex_data[1] = NULL;
- face.user_face_vertex_data[2] = NULL;
- face.user_face_vertex_data[3] = NULL;
- }
-
-
- int tri_index[3];
- int fv_index[3];
-
- while (!face_it.Done(face_it.it)) {
- face_it.Fill(face_it.it,&face);
-
- // Let's not rely on quads being coplanar - especially if they
- // are coming out of that soup of code from blender...
- if (face.vertex_number == 4) {
- tri_index[0] = face.vertex_index[2];
- tri_index[1] = face.vertex_index[3];
- tri_index[2] = face.vertex_index[0];
-
- fv_index[0] = fv_data->Duplicate(face.user_face_vertex_data[2]);
- fv_index[1] = fv_data->Duplicate(face.user_face_vertex_data[3]);
- fv_index[2] = fv_data->Duplicate(face.user_face_vertex_data[0]);
-
- mesh->AddPolygon(tri_index,fv_index,3);
-
- // bit of an unspoken relationship between mesh face buffer
- // and the face data which I guess should be changed.
- face_data->Duplicate(face.user_face_data);
-
- }
-
- fv_index[0] = fv_data->Duplicate(face.user_face_vertex_data[0]);
- fv_index[1] = fv_data->Duplicate(face.user_face_vertex_data[1]);
- fv_index[2] = fv_data->Duplicate(face.user_face_vertex_data[2]);
-
- mesh->AddPolygon(face.vertex_index,fv_index,3);
- // bit of an unspoken relationship between mesh face buffer
- // and the face data which I guess should be changed.
- face_data->Duplicate(face.user_face_data);
-
-
- face_it.Step(face_it.it);
- }
-
- // give the user face vertex data over to the mesh.
-
- mesh->SetFaceVertexData(fv_data);
- mesh->SetFaceData(face_data);
-
- // that's it
-
- delete[] static_cast<char *>(face.user_face_data);
- delete[] static_cast<char *>(face.user_face_vertex_data[0]);
- return mesh;
-}
-
diff --git a/intern/bsp/intern/BSP_CSGMeshBuilder.h b/intern/bsp/intern/BSP_CSGMeshBuilder.h
deleted file mode 100755
index 8216f972c74..00000000000
--- a/intern/bsp/intern/BSP_CSGMeshBuilder.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BSP_CSGMeshBuilder_h
-#define BSP_CSGMeshBuilder_h
-
-#include "../extern/CSG_BooleanOps.h"
-#include "BSP_CSGMesh.h"
-#include "MEM_NonCopyable.h"
-#include "MEM_SmartPtr.h"
-
-/**
- * This class helps you to build a mesh from 2 seperate vertex/face
- * iterators defined in the external interface of the bsp module.
- * This code should really become party of a generic C++ mesh interface
- * but later...
- */
-
-class BSP_CSGMeshBuilder : public MEM_NonCopyable{
-
-public :
-
- /**
- * Return a new BSP_CSGMesh with the desired props
- * built from the given face and vertex iterators.
- * The iterators are exhausted by this action.
- */
-
- static
- MEM_SmartPtr<BSP_CSGMesh>
- NewMesh(
- CSG_MeshPropertyDescriptor &props,
- CSG_FaceIteratorDescriptor &face_it,
- CSG_VertexIteratorDescriptor &vertex_it
- );
-
-private :
-
- BSP_CSGMeshBuilder(
- );
-
-};
-
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_CSGMeshSplitter.cpp b/intern/bsp/intern/BSP_CSGMeshSplitter.cpp
deleted file mode 100755
index ba3a3150dba..00000000000
--- a/intern/bsp/intern/BSP_CSGMeshSplitter.cpp
+++ /dev/null
@@ -1,719 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "BSP_CSGMeshSplitter.h"
-
-#include "BSP_CSGMesh.h"
-#include "BSP_MeshFragment.h"
-#include "BSP_CSGException.h"
-#include "MT_MinMax.h"
-#include "MT_assert.h"
-
-using namespace std;
-
-
-BSP_CSGMeshSplitter::
-BSP_CSGMeshSplitter(
- CSG_InterpolateUserFaceVertexDataFunc fv_split_func
-) : m_fv_func(fv_split_func)
-{
- // nothing to do
-};
-
- void
-BSP_CSGMeshSplitter::
-Split(
- const MT_Plane3& plane,
- BSP_MeshFragment *frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
-){
- // First classify the vertices and the polygons of the
- // incoming fragment.
- frag->Classify(plane,in_frag,out_frag,on_frag,m_spanning_faces,m_tagged_verts);
-
- SplitImp(*(frag->Mesh()),plane,m_spanning_faces,in_frag,out_frag,on_frag,m_tagged_verts);
-
- m_spanning_faces.clear();
- m_tagged_verts.clear();
-
-}
-
- void
-BSP_CSGMeshSplitter::
-Split(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
-){
- BSP_MeshFragment::Classify(mesh, plane,in_frag,out_frag,on_frag,m_spanning_faces,m_tagged_verts);
-
- SplitImp(mesh,plane,m_spanning_faces,in_frag,out_frag,on_frag,m_tagged_verts);
- m_spanning_faces.clear();
- m_tagged_verts.clear();
-}
-
-BSP_CSGMeshSplitter::
-~BSP_CSGMeshSplitter(
-){
- // nothing to do
-}
-
- void
-BSP_CSGMeshSplitter::
-SplitImp(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- const std::vector<BSP_FaceInd> & spanning_faces,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- std::vector<BSP_VertexInd> & classified_verts
-){
- // Assumes you have already classified the vertices.
- // and generated a set of spanning faces.
-
- vector<BSP_MEdge> & edge_set = mesh.EdgeSet();
- vector<BSP_MVertex> & vertex_set = mesh.VertexSet();
- vector<BSP_MFace> & face_set = mesh.FaceSet();
-
- // Now identify the spanning edges.
- // These can be computed in many ways but probably the most
- // efficient is to select all edges from the vertices of the
- // spanning polygons that cross the plane.
-
- vector<BSP_FaceInd>::const_iterator sface_end = m_spanning_faces.end();
- vector<BSP_FaceInd>::const_iterator sface_it = m_spanning_faces.begin();
-
- for (;sface_it != sface_end; ++sface_it) {
-
- BSP_MFace & sface = face_set[*sface_it];
-
- vector<BSP_VertexInd>::const_iterator sf_vert_end = sface.m_verts.end();
- vector<BSP_VertexInd>::iterator sf_vert_it = sface.m_verts.begin();
-
- for (;sf_vert_it != sf_vert_end; ++sf_vert_it) {
- BSP_MVertex & vert = vertex_set[*sf_vert_it];
-
- if (!vert.SelectTag()) {
- // what classification does this vertex have?
-
- BSP_Classification root_vert_class = BSP_Classification(vert.OpenTag());
-
- // we are only interested in edges whose vertices are in and out.
- if (root_vert_class != e_classified_on) {
-
- BSP_Classification opp_class = e_classified_out;
- if (root_vert_class == e_classified_out) {
- opp_class = e_classified_in;
- }
- // we haven't visited this vertex before so lets
- // analyse it's edges.
-
- vector<BSP_EdgeInd>::const_iterator v_edge_end = vert.m_edges.end();
- vector<BSP_EdgeInd>::iterator v_edge_it = vert.m_edges.begin();
-
- for (; v_edge_it != v_edge_end; ++v_edge_it) {
- BSP_MEdge & edge = edge_set[*v_edge_it];
-
- if (!edge.SelectTag()) {
- // we haven't visited this edge before so check it's
- // end points
-
- // we know that a spanning polygon can have at most
- // 2 on vertices (even at this point where we haven't
- // yet split the edge!) We are interested in edges whose
- // vertices are in and out the plane.
-
- BSP_VertexInd opp_vi = edge.OpVertex(*sf_vert_it);
- if (vertex_set[opp_vi].OpenTag() == opp_class) {
- // we have found an edge !!!!
- m_spanning_edges.push_back(*v_edge_it);
- }
- edge.SetSelectTag(true);
- m_visited_edges.push_back(*v_edge_it);
- }
- }
- }
-
- vert.SetSelectTag(true);
- m_visited_verts.push_back(*sf_vert_it);
- }
- }
- }
-
- // clear the tags we used in the above
-
- unsigned int i;
-
- for (i = 0; i < m_visited_edges.size(); ++i) {
- edge_set[m_visited_edges[i]].SetSelectTag(false);
- }
- for (i=0;i < m_visited_verts.size(); ++i) {
- vertex_set[m_visited_verts[i]].SetSelectTag(false);
- }
- for (i=0; i < m_spanning_faces.size(); ++i) {
- face_set[m_spanning_faces[i]].SetSelectTag(false);
- }
-
- // The spanning edge set constains unique edges. Next we run
- // through the edge set and compute the intersection with the
- // plane --- the edge is guarenteed not to be parallel to the plane!
- // we then split the edge with the new vertex.
-
- // We identify the polygons affected by the split
-
- vector<BSP_EdgeInd>::const_iterator s_edge_end = m_spanning_edges.end();
- vector<BSP_EdgeInd>::iterator s_edge_it = m_spanning_edges.begin();
-
- for (;s_edge_it != s_edge_end; ++s_edge_it) {
-
- const BSP_MEdge & edge = edge_set[*s_edge_it];
-
- const BSP_MVertex &v1 = vertex_set[edge.m_verts[0]];
- const BSP_MVertex &v2 = vertex_set[edge.m_verts[1]];
-
- const MT_Vector3 & ptA = v1.m_pos;
- const MT_Vector3 & ptB = v2.m_pos;
-
- // compute the intersection point of plane and ptA->ptB
- MT_Vector3 v = ptB - ptA;
- MT_Scalar sideA = plane.signedDistance(ptA);
-
- MT_Scalar epsilon = -sideA/plane.Normal().dot(v);
- MT_Vector3 new_p = ptA + (v * epsilon);
-
- // so new_p is the intersection of the plane and the edge.
- // split the edge at new_p
-
- BSP_MVertex new_vert;
- new_vert.m_pos = new_p;
-
- BSP_VertexInd new_vi = SplitEdge(mesh,*s_edge_it,new_vert,epsilon);
-
- // tag the new vertex as 'on' the plane - we use this information
- // to split the affected polygons below.
- vertex_set[new_vi].SetOpenTag(e_classified_on);
-
- // We add it to the tagged verts so we can remove the tag later.
- classified_verts.push_back(new_vi);
- }
-
- // We start with the spanning polygons...
- // not forgetting to add the new polygon fragments to the correct fragment bins.
-
- sface_end = m_spanning_faces.end();
- sface_it = m_spanning_faces.begin();
-
- for (;sface_it != sface_end; ++sface_it) {
-
- BSP_FaceInd f_in,f_out;
-
- SplitPolygon(mesh,*sface_it,f_in,f_out);
- in_frag->FaceSet().push_back(f_in);
- out_frag->FaceSet().push_back(f_out);
- }
-
- // Finally we have to clean up the vertex tags we set on all the vertices
- // There will be some overlap between the vertex sets, so this operation
- // is a tiny bit inefficient.
-
- vector<BSP_VertexInd>::const_iterator v_end = classified_verts.end();
- vector<BSP_VertexInd>::const_iterator v_it = classified_verts.begin();
-
- for (; v_it != v_end; ++v_it) {
- vertex_set[*v_it].SetOpenTag(e_unclassified);
- }
-
- // tidy up the cached arrays.
-
- m_spanning_edges.clear();
- m_visited_edges.clear();
- m_visited_verts.clear();
-
-
- // le fin.
-
-}
-
-
- BSP_VertexInd
-BSP_CSGMeshSplitter::
-SplitEdge(
- BSP_CSGMesh & mesh,
- BSP_EdgeInd ei,
- BSP_MVertex &vertex,
- MT_Scalar epsilon
-){
- vector<BSP_MEdge> & edge_set = mesh.EdgeSet();
- vector<BSP_MVertex> & vertex_set = mesh.VertexSet();
- vector<BSP_MFace> & face_set = mesh.FaceSet();
-
- MT_assert(edge_set.size() > (unsigned int)(ei));
-
- if (edge_set.size() <= (unsigned int)(ei)) {
- BSP_CSGException e(e_param_error);
- throw(e);
- }
-
- // push the vertex onto the vertex array
- BSP_VertexInd new_vi = vertex_set.size();
- vertex_set.push_back(vertex);
- BSP_MVertex & new_v = vertex_set[new_vi];
-
- // copy the edge because the new edge will have
- // exactly the same face set.
-
- BSP_EdgeInd new_ei = edge_set.size();
-
- // Note never use set.push_back(set[i])
- // coz push_back excepts a reference which may become
- // invalid if the set is resized
-
- edge_set.push_back(BSP_MEdge());
- edge_set[new_ei] = edge_set[ei];
- BSP_MEdge & new_e = edge_set[new_ei];
-
- BSP_MEdge &e = edge_set[ei];
-
- // get the edge vertices.
- BSP_MVertex & e_v2 = vertex_set[e.m_verts[1]];
-
- // Remove the split edge from vertex 2.
- // Let's hope that the vertex isn't using this edge for
- // its' open tag!!
-
- BSP_Classification v2_class = BSP_Classification(e_v2.OpenTag());
-
- e_v2.RemoveEdge(ei);
-
- // add the split edge to the new vertex.
- new_v.AddEdge(ei);
-
- // add the new edge to the new vertex.
- new_v.AddEdge(new_ei);
-
- // add the new edge to vertex 2
- e_v2.AddEdge(new_ei);
-
- // Reset the tags for modified vertex.
-
- e_v2.SetOpenTag(v2_class);
-
-
- // Replace the old vertex indices in the new edge.
- new_e.m_verts[0] = new_vi;
- e.m_verts[1] = new_vi;
-
- // Finally add the vertex in the correct position to the
- // neighbouring polygons.
-
- vector<BSP_FaceInd>::iterator neighbour_face_it = e.m_faces.begin();
- vector<BSP_FaceInd>::const_iterator neighbour_face_end = e.m_faces.end();
-
- for (; neighbour_face_it != neighbour_face_end; ++neighbour_face_it) {
-
- mesh.InsertVertexIntoFace(
- face_set[*neighbour_face_it],
- new_e.m_verts[1],
- e.m_verts[0],
- new_vi,
- m_fv_func,
- epsilon
- );
- }
-
- // That should be it (cough)
- return new_vi;
-
-}
-
- void
-BSP_CSGMeshSplitter::
-SplitPolygon(
- BSP_CSGMesh & mesh,
- BSP_FaceInd fi,
- BSP_FaceInd &fin,
- BSP_FaceInd &fout
-){
- vector<BSP_MEdge> & edge_set = mesh.EdgeSet();
- vector<BSP_MVertex> & vertex_set = mesh.VertexSet();
- vector<BSP_MFace> & face_set = mesh.FaceSet();
-
- MT_assert(face_set.size() > (unsigned int)(fi));
- if (face_set.size() <= (unsigned int)(fi)) {
- BSP_CSGException e(e_param_error);
- throw(e);
- }
-
- BSP_MFace & face = face_set[fi];
-
- // Walk throught the vertices of this polygon.
- // generate inside and outside loops.
-
- vector<BSP_VertexInd>::const_iterator f_verts_end = face.m_verts.end();
- vector<BSP_VertexInd>::iterator f_verts_it = face.m_verts.begin();
-
- vector<BSP_UserFVInd>::const_iterator f_fv_data_it = face.m_fv_data.begin();
-
- // NOTE we don't actually duplicate fv data for this face
- // we just duplicate the indices, so both on vertices
- // will share the fv data.
-
- for (;f_verts_it != f_verts_end; ++f_verts_it, ++f_fv_data_it) {
-
- BSP_MVertex & vert = vertex_set[*f_verts_it];
- BSP_Classification v_class = BSP_Classification(vert.OpenTag());
-
- if (v_class == e_classified_in) {
- m_in_loop.push_back(*f_verts_it);
- m_fv_in_loop.push_back(*f_fv_data_it);
- } else
- if (v_class == e_classified_out) {
- m_out_loop.push_back(*f_verts_it);
- m_fv_out_loop.push_back(*f_fv_data_it);
-
- } else
- if (v_class == e_classified_on) {
- m_in_loop.push_back(*f_verts_it);
- m_out_loop.push_back(*f_verts_it);
- m_on_loop.push_back(*f_verts_it);
- m_fv_in_loop.push_back(*f_fv_data_it);
- m_fv_out_loop.push_back(*f_fv_data_it);
- } else {
- // The vertex is unclassified this is an error!
- MT_assert(false);
- BSP_CSGException e(e_split_error);
- throw(e);
- }
- }
-
- if ((m_in_loop.size() == 1) || (m_out_loop.size() == 1)) {
- // Then there was only 1 tagged vertex I guess this is fine
- // but should be reviewed!
-
- // NOT fine - we only ever split spanning polygons.
- MT_assert(false);
- BSP_CSGException e(e_split_error);
- throw(e);
- }
-
- MT_assert(m_in_loop.size() >=3 && m_out_loop.size() >=3 && m_on_loop.size() == 2);
-
- if (m_in_loop.size() <3 || m_out_loop.size() <3 || m_on_loop.size() !=2) {
- BSP_CSGException e(e_split_error);
- throw(e);
- }
- // Now we have 2 seperate vertex loops representing the polygon
- // halves.
-
- // create a new polygon for the out_loop of vertices.
- ////////////////////////////////////////////////////
-
- // Duplicate face data.
-
- mesh.FaceData().Duplicate(fi);
-
- BSP_FaceInd new_fi = face_set.size();
- face_set.push_back(BSP_MFace());
- BSP_MFace & new_f = face_set[new_fi];
-
- // assign plane equation for new face - this is the same as the
- // original of course.
-
- new_f.m_plane = face_set[fi].m_plane;
-
- // note that face may have become invalid because we just been adding
- // more polygons to the array. We can't assign a new reference to the old
- // invlaid one! It will call try and call the assignment operator on
- // the original face!!!! The joys of references! We just use face_set[fi]
- // from now on to be safe
-
- // We need to insert an edge between m_on_loop[0] and m_on_loop[1]
-
- // Make sure the edge does not already exist between these 2 vertices!
- // This can happen if the original mesh has duplicate polygons.
- // We still wire up the new polygons to this edge, which will
- // lead to duplicate polygons in the output -- but algorithm
- // should still work.
- BSP_EdgeInd new_ei = mesh.FindEdge(m_on_loop[0],m_on_loop[1]);
-
- if (new_ei.IsEmpty()) {
-
- // create a new edge.
-
- new_ei = edge_set.size();
- edge_set.push_back(BSP_MEdge());
- BSP_MEdge & new_e = edge_set[new_ei];
-
- new_e.m_verts[0] = m_on_loop[0];
- new_e.m_verts[1] = m_on_loop[1];
-
- // Now tie the edge to it's vertices.
-
- vertex_set[m_on_loop[0]].AddEdge(new_ei);
- vertex_set[m_on_loop[1]].AddEdge(new_ei);
- }
-
- edge_set[new_ei].m_faces.push_back(fi);
- // This next line is a trick we are going to replace it in a moment
- // with new_fi. It means that all the edges of the new polygon have
- // pointers to the old polygon which we can replace.
- edge_set[new_ei].m_faces.push_back(fi);
-
-
- // Replace the old polygons vertex loop with the in_loop of vertices.
-
- face_set[fi].m_verts = m_in_loop;
- new_f.m_verts = m_out_loop;
-
- // Replace the olf fv loops.
- face_set[fi].m_fv_data = m_fv_in_loop;
- new_f.m_fv_data = m_fv_out_loop;
-
-
- // That should be it for the old polygon;
- // For the new polygon we just need to iterate around it's
- // edges and replace pointers to the old polygon with pointers
- // to the new one.
-
- f_verts_end = new_f.m_verts.end();
- f_verts_it = new_f.m_verts.begin();
-
- BSP_VertexInd prev = new_f.m_verts.back();
-
- for (;f_verts_it != f_verts_end; ++f_verts_it) {
- BSP_EdgeInd new_f_ei = mesh.FindEdge(prev,*f_verts_it);
-
- MT_assert(!new_f_ei.IsEmpty());
-
- if (new_f_ei.IsEmpty()) {
- BSP_CSGException e(e_split_error);
- throw(e);
- }
-
- edge_set[new_f_ei].SwapFace(fi,new_fi);
- prev = *f_verts_it;
-
- }
-
- // That should be everything.
-
- fin = fi;
- fout = new_fi;
-
- // clear up cached helpers.
- m_in_loop.clear();
- m_on_loop.clear();
- m_out_loop.clear();
-
- m_fv_in_loop.clear();
- m_fv_out_loop.clear();
-
-}
-
- BSP_FaceInd
-BSP_CSGMeshSplitter::
-TriangulateConvexQuad(
- BSP_CSGMesh & mesh,
- const BSP_FaceInd fi
-){
-
- // we assume that the fi points to a face with
- // exactly 4 vertices.
-
-
- // We are definately going to create a new face
- // so lets make space for it in the face array.
-
- vector<BSP_MFace> & face_set = mesh.FaceSet();
- vector<BSP_MVertex> & vertex_set = mesh.VertexSet();
- vector<BSP_MEdge> & edge_set = mesh.EdgeSet();
-
- if (face_set[fi].m_verts.size() == 3) {
- return BSP_FaceInd::Empty();
- }
-
- // duplicate face data
- mesh.FaceData().Duplicate(fi);
-
- const BSP_FaceInd new_fi = face_set.size();
- face_set.push_back(BSP_MFace());
- BSP_MFace & new_face = face_set[new_fi];
- BSP_MFace & face = face_set[fi];
-
- new_face.m_plane = face.m_plane;
-
- // The internal edges are [0,2] and [1,3]
- // these split the quad into the triangles
- // [0,1,2],[2,3,0] and [0,1,3],[1,2,3] respectively
-
- const MT_Point3 & p0 = vertex_set[face.m_verts[0]].m_pos;
- const MT_Point3 & p1 = vertex_set[face.m_verts[1]].m_pos;
- const MT_Point3 & p2 = vertex_set[face.m_verts[2]].m_pos;
- const MT_Point3 & p3 = vertex_set[face.m_verts[3]].m_pos;
-
- MT_Vector3 e0 = p1 - p0;
- MT_Vector3 e1 = p2 - p1;
- MT_Vector3 e2 = p3 - p2;
- MT_Vector3 e3 = p0 - p3;
-
- MT_Scalar A = (e0.cross(e1)).length2();
- MT_Scalar B = (e2.cross(e3)).length2();
- MT_Scalar C = (e3.cross(e0)).length2();
- MT_Scalar D = (e1.cross(e2)).length2();
-
- MT_Scalar minab = MT_min(A,B);
- MT_Scalar maxab = MT_max(A,B);
-
- MT_Scalar mincd = MT_min(C,D);
- MT_Scalar maxcd = MT_max(C,D);
-
- MT_Scalar ratioab = minab/maxab;
- MT_Scalar ratiocd = mincd/maxcd;
-
- ratioab = MT_abs(1-ratioab);
- ratiocd = MT_abs(1-ratiocd);
-
- vector<BSP_VertexInd> loop1(3),loop2(3);
- vector<BSP_UserFVInd> fv_loop1(3),fv_loop2(3);
-
- if (ratioab < ratiocd) {
- // then use [0,2] as splitting edge.
- loop1[0] = face.m_verts[1];
- loop1[1] = face.m_verts[2];
- loop1[2] = face.m_verts[0];
-
- loop2[0] = face.m_verts[2];
- loop2[1] = face.m_verts[3];
- loop2[2] = face.m_verts[0];
-
- // same for fv indices.
- fv_loop1[0] = face.m_fv_data[1];
- fv_loop1[1] = face.m_fv_data[2];
- fv_loop1[2] = face.m_fv_data[0];
-
- fv_loop2[0] = face.m_fv_data[2];
- fv_loop2[1] = face.m_fv_data[3];
- fv_loop2[2] = face.m_fv_data[0];
-
-
- } else {
- // use [1,3] as splitting edge
- loop1[0] = face.m_verts[0];
- loop1[1] = face.m_verts[1];
- loop1[2] = face.m_verts[3];
-
- loop2[0] = face.m_verts[1];
- loop2[1] = face.m_verts[2];
- loop2[2] = face.m_verts[3];
-
- // same for fv indices.
- fv_loop1[0] = face.m_fv_data[0];
- fv_loop1[1] = face.m_fv_data[1];
- fv_loop1[2] = face.m_fv_data[3];
-
- fv_loop2[0] = face.m_fv_data[1];
- fv_loop2[1] = face.m_fv_data[2];
- fv_loop2[2] = face.m_fv_data[3];
-
- }
-
- // TODO factor out commmon code between here and SplitPolygon.
-
- BSP_EdgeInd new_ei = mesh.FindEdge(loop1[1],loop1[2]);
-
- if (new_ei.IsEmpty()) {
-
- // create a new edge.
-
- new_ei = edge_set.size();
- edge_set.push_back(BSP_MEdge());
- BSP_MEdge & new_e = edge_set[new_ei];
-
- new_e.m_verts[0] = loop1[1];
- new_e.m_verts[1] = loop1[2];
-
- // Now tie the edge to it's vertices.
-
- vertex_set[loop1[1]].AddEdge(new_ei);
- vertex_set[loop1[2]].AddEdge(new_ei);
- }
-
- edge_set[new_ei].m_faces.push_back(fi);
- // This next line is a trick we are going to replace it in a moment
- // with new_fi. It means that all the edges of the new polygon have
- // pointers to the old polygon which we can replace.
- edge_set[new_ei].m_faces.push_back(fi);
-
-
- // Replace the old polygons vertex loop with the in_loop of vertices.
-
- face.m_verts = loop1;
- face.m_fv_data = fv_loop1;
- new_face.m_verts = loop2;
- new_face.m_fv_data = fv_loop2;
-
- // That should be it for the old polygon;
- // For the new polygon we just need to iterate around it's
- // edges and replace pointers to the old polygon with pointers
- // to the new one.
-
- vector<BSP_VertexInd>::const_iterator f_verts_end = new_face.m_verts.end();
- vector<BSP_VertexInd>::const_iterator f_verts_it = new_face.m_verts.begin();
-
- BSP_VertexInd prev = new_face.m_verts.back();
-
- for (;f_verts_it != f_verts_end; ++f_verts_it) {
- BSP_EdgeInd new_f_ei = mesh.FindEdge(prev,*f_verts_it);
-
- MT_assert(!new_f_ei.IsEmpty());
-
- if (new_f_ei.IsEmpty()) {
- BSP_CSGException e(e_split_error);
- throw(e);
- }
-
- edge_set[new_f_ei].SwapFace(fi,new_fi);
- prev = *f_verts_it;
-
- }
- return new_fi;
-}
diff --git a/intern/bsp/intern/BSP_CSGMeshSplitter.h b/intern/bsp/intern/BSP_CSGMeshSplitter.h
deleted file mode 100755
index 44aa4ad949a..00000000000
--- a/intern/bsp/intern/BSP_CSGMeshSplitter.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BSP_CSGMeshSplitter_h
-#define BSP_CSGMeshSplitter_h
-
-class BSP_MeshFragment;
-class MT_Plane3;
-class BSP_CSGMesh;
-
-#include "BSP_MeshPrimitives.h"
-#include "../extern/CSG_BooleanOps.h"
-#include "BSP_CSGISplitter.h"
-
-
-/**
- * This class contains splitting functions for a CSGMesh.
- * The atomic operation of a bsp CSG algorithm is to split
- * a mesh fragment (connected collection of polygons contained
- * in a convex cell) by a plane. It is vital to leave the
- * CSGMesh in a valid state after each such operation
- * this class insures this (or tries it's best!).
- */
-
-
-class BSP_CSGMeshSplitter : public BSP_CSGISplitter
-{
-public :
-
- /// construction
-
- BSP_CSGMeshSplitter(
- CSG_InterpolateUserFaceVertexDataFunc fv_split_func
- );
-
- BSP_CSGMeshSplitter(
- const BSP_CSGMeshSplitter & other
- );
-
- /**
- * @section BSP specific mesh operations.
- * Inherited from BSP_CSGISplitter
- */
-
- /**
- * Split a mesh fragment wrt plane. Generates 3 mesh fragments,
- * in, out and on. Makes sure the mesh is coherent after the
- * operation. The contents of frag are consumed by this oepration.
- */
-
- void
- Split(
- const MT_Plane3& plane,
- BSP_MeshFragment *frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
- );
-
- /// Split the entire mesh with respect to the plane.
-
- void
- Split(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
- );
-
- ~BSP_CSGMeshSplitter(
- );
-
-private :
-
- void
- SplitImp(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- const std::vector<BSP_FaceInd> & spanning_faces,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- std::vector<BSP_VertexInd> & classified_verts
- );
-
-
- /**
- * @section Atomic mesh operations.
- */
-
- /**
- * Add a vertex to the mesh, along
- * a given edge. Leaves the mesh in a valid state.
- * The vertex gets copied onto the back of the
- * current vertex array. It's upto you to insure
- * that the vertex actually lies on the edge and leaves
- * the neighbouring faces convex. Returns the vertex index
- * of the new vertex.
- *
- * epsilon is the relative distance [0,1] of the new
- * vertex from the first vertex of the edge. This is
- * used to intepolate face properties.
- */
-
- BSP_VertexInd
- SplitEdge(
- BSP_CSGMesh & mesh,
- BSP_EdgeInd ei,
- BSP_MVertex &vertex,
- MT_Scalar epsilon
- );
-
- /**
- * Split a polygon along an edge connecting the
- * two tagged (on) vertices of the polygon. It assumes
- * that you have already introduced two new vertex indices
- * into the polygon that point to vertices tagged with
- * {in,out,on} information. It creates a new edge from the
- * 2 on vertices that must be present. It then splits up
- * the polygon into 2 fragments on the inside and outside.
- * It returns 2 indices into the face list. 1 for the inside
- * polygon and 1 for the outside polygon.
- */
-
- void
- SplitPolygon(
- BSP_CSGMesh & mesh,
- BSP_FaceInd fi,
- BSP_FaceInd &fin,
- BSP_FaceInd &fout
- );
-
- /**
- * Triangulate a convex quad (the maximum size polygon
- * resulting from splitting a triangle). This can create up
- * to one new face - which is added to the mesh. Note
- * that this method does not preserve references. It uses
- * the edge which divides the quad into roughly equal triangular
- * areas as the splitting edge. - This should avoid creating
- * degenerate triangles.
- */
-
- BSP_FaceInd
- TriangulateConvexQuad(
- BSP_CSGMesh & mesh,
- const BSP_FaceInd fi
- );
-
-private :
-
- // The function pointer used to split face vertex properties.
-
- CSG_InterpolateUserFaceVertexDataFunc m_fv_func;
-
- /// Cached helpers
-
- /// Split function responsibe for:
- std::vector<BSP_FaceInd> m_spanning_faces;
- std::vector<BSP_VertexInd> m_tagged_verts;
-
- /// SplitImp responsible for:
- std::vector<BSP_EdgeInd> m_spanning_edges;
- // The list of faces affected by splitting the spanning edge set.
- std::vector<BSP_EdgeInd> m_visited_edges;
- std::vector<BSP_VertexInd> m_visited_verts;
-
- /// SplitPolygon responsible for:
- std::vector<BSP_FaceInd> m_in_loop,m_out_loop,m_on_loop;
- std::vector<BSP_UserFVInd> m_fv_in_loop,m_fv_out_loop;
-
-};
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_CSGMesh_CFIterator.h b/intern/bsp/intern/BSP_CSGMesh_CFIterator.h
index f10458655d9..6863bf38cfc 100755
--- a/intern/bsp/intern/BSP_CSGMesh_CFIterator.h
+++ b/intern/bsp/intern/BSP_CSGMesh_CFIterator.h
@@ -46,7 +46,7 @@ struct BSP_CSGMesh_VertexIt {
};
-static
+inline
void
BSP_CSGMesh_VertexIt_Destruct(
CSG_VertexIteratorDescriptor * iterator
@@ -61,7 +61,7 @@ BSP_CSGMesh_VertexIt_Destruct(
};
-static
+inline
int
BSP_CSGMesh_VertexIt_Done(
CSG_IteratorPtr it
@@ -76,7 +76,7 @@ BSP_CSGMesh_VertexIt_Done(
return 1;
};
-static
+inline
void
BSP_CSGMesh_VertexIt_Fill(
CSG_IteratorPtr it,
@@ -88,7 +88,7 @@ BSP_CSGMesh_VertexIt_Fill(
vertex_it->pos->m_pos.getValue(vert->position);
};
-static
+inline
void
BSP_CSGMesh_VertexIt_Step(
CSG_IteratorPtr it
@@ -99,7 +99,7 @@ BSP_CSGMesh_VertexIt_Step(
++(vertex_it->pos);
};
-static
+inline
void
BSP_CSGMesh_VertexIt_Reset(
CSG_IteratorPtr it
@@ -109,7 +109,7 @@ BSP_CSGMesh_VertexIt_Reset(
vertex_it->pos = &vertex_it->mesh->VertexSet()[0];
};
-static
+inline
void
BSP_CSGMeshVertexIt_Construct(
BSP_CSGMesh *mesh,
@@ -141,7 +141,7 @@ struct BSP_CSGMesh_FaceIt {
};
-static
+inline
void
BSP_CSGMesh_FaceIt_Destruct(
CSG_FaceIteratorDescriptor *iterator
@@ -156,7 +156,7 @@ BSP_CSGMesh_FaceIt_Destruct(
};
-static
+inline
int
BSP_CSGMesh_FaceIt_Done(
CSG_IteratorPtr it
@@ -168,15 +168,14 @@ BSP_CSGMesh_FaceIt_Done(
/* also check that vector is not empty */
if (face_it->mesh->FaceSet().size() &&
face_it->pos <= &(*(face_it->mesh->FaceSet().end() -1))) {
- if (face_it->face_triangle + 3 <= face_it->pos->m_verts.size()) {
-
+ if (face_it->face_triangle + 3 <= (int)face_it->pos->m_verts.size()) {
return 0;
}
}
return 1;
};
-static
+inline
void
BSP_CSGMesh_FaceIt_Fill(
CSG_IteratorPtr it,
@@ -193,31 +192,8 @@ BSP_CSGMesh_FaceIt_Fill(
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.
+ face->orig_face = face_it->pos->m_orig_face;
- // 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_it->mesh->FaceVertexData().Copy(
- face->user_face_vertex_data[3],
- face_it->pos->m_fv_data[3]);
-
face->vertex_number = 4;
}
else {
@@ -226,33 +202,13 @@ BSP_CSGMesh_FaceIt_Fill(
face->vertex_index[1] = int(face_it->pos->m_verts[1]);
face->vertex_index[2] = int(face_it->pos->m_verts[2]);
- // 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->orig_face = face_it->pos->m_orig_face;
face->vertex_number = 3;
}
};
-static
+inline
void
BSP_CSGMesh_FaceIt_Step(
CSG_IteratorPtr it
@@ -274,7 +230,7 @@ BSP_CSGMesh_FaceIt_Step(
}
};
-static
+inline
void
BSP_CSGMesh_FaceIt_Reset(
CSG_IteratorPtr it
@@ -285,7 +241,7 @@ BSP_CSGMesh_FaceIt_Reset(
f_it->face_triangle = 0;
};
-static
+inline
void
BSP_CSGMesh_FaceIt_Construct(
BSP_CSGMesh * mesh,
diff --git a/intern/bsp/intern/BSP_CSGNCMeshSplitter.cpp b/intern/bsp/intern/BSP_CSGNCMeshSplitter.cpp
deleted file mode 100755
index 11e8bff6810..00000000000
--- a/intern/bsp/intern/BSP_CSGNCMeshSplitter.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "BSP_CSGNCMeshSplitter.h"
-
-#include "BSP_CSGMesh.h"
-#include "BSP_MeshFragment.h"
-#include "BSP_CSGException.h"
-#include "MT_MinMax.h"
-#include "MT_assert.h"
-#include <vector>
-
-using namespace std;
-
-BSP_CSGNCMeshSplitter::
-BSP_CSGNCMeshSplitter(
-){
- //nothing to do
-}
-
-BSP_CSGNCMeshSplitter::
-BSP_CSGNCMeshSplitter(
- const BSP_CSGNCMeshSplitter & other
-){
- //nothing to do
-};
-
-
- void
-BSP_CSGNCMeshSplitter::
-Split(
- const MT_Plane3& plane,
- BSP_MeshFragment *frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
-){
- // First classify the vertices and the polygons of the
- // incoming fragment.
- frag->Classify(plane,in_frag,out_frag,on_frag,m_spanning_faces,m_tagged_verts);
-
- SplitImp(*(frag->Mesh()),plane,m_spanning_faces,in_frag,out_frag,on_frag,m_tagged_verts);
-
- m_spanning_faces.clear();
- m_tagged_verts.clear();
-}
-
-/// Split the entire mesh with respect to the plane.
-
- void
-BSP_CSGNCMeshSplitter::
-Split(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
-){
- BSP_MeshFragment::Classify(mesh, plane,in_frag,out_frag,on_frag,m_spanning_faces,m_tagged_verts);
-
- SplitImp(mesh,plane,m_spanning_faces,in_frag,out_frag,on_frag,m_tagged_verts);
- m_spanning_faces.clear();
- m_tagged_verts.clear();
-}
-
-
-BSP_CSGNCMeshSplitter::
-~BSP_CSGNCMeshSplitter(
-){
- //nothing to do
-}
-
- void
-BSP_CSGNCMeshSplitter::
-SplitImp(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- const std::vector<BSP_FaceInd> & spanning_faces,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- std::vector<BSP_VertexInd> & classified_verts
-){
-
- // Just iterate through the spanning faces.
- // Identify the spanning 'edges' and create new vertices
- // and split the polygons. We make no attempt to share
- // vertices or preserve edge connectivity or maintain any
- // face properties etc.
-
- // Assumes you have already classified the vertices.
- // and generated a set of spanning faces.
-
- vector<BSP_MVertex> & vertex_set = mesh.VertexSet();
- vector<BSP_MFace> & face_set = mesh.FaceSet();
-
- vector<BSP_FaceInd>::const_iterator sface_end = m_spanning_faces.end();
- vector<BSP_FaceInd>::const_iterator sface_it = m_spanning_faces.begin();
-
- for (;sface_it != sface_end; ++sface_it) {
- BSP_FaceInd f_in,f_out;
- SplitPolygon(plane,mesh,*sface_it,f_in,f_out);
-
- // Use the open tag to store the original index of the face.
- // This is originally -1.
-
- if (face_set[*sface_it].OpenTag() == -1) {
- face_set[f_in].SetOpenTag(*sface_it);
- face_set[f_out].SetOpenTag(*sface_it);
- } else {
- face_set[f_in].SetOpenTag(face_set[*sface_it].OpenTag());
- face_set[f_out].SetOpenTag(face_set[*sface_it].OpenTag());
- }
-
- in_frag->FaceSet().push_back(f_in);
- out_frag->FaceSet().push_back(f_out);
- }
-
- vector<BSP_VertexInd>::const_iterator v_end = classified_verts.end();
- vector<BSP_VertexInd>::const_iterator v_it = classified_verts.begin();
-
- for (; v_it != v_end; ++v_it) {
- vertex_set[*v_it].SetOpenTag(e_unclassified);
- }
-}
-
- void
-BSP_CSGNCMeshSplitter::
-SplitPolygon(
- const MT_Plane3& plane,
- BSP_CSGMesh & mesh,
- BSP_FaceInd fi,
- BSP_FaceInd &fin,
- BSP_FaceInd &fout
-){
-
- vector<BSP_MVertex> & vertex_set = mesh.VertexSet();
- vector<BSP_MFace> & face_set = mesh.FaceSet();
-
- BSP_FaceInd new_fi = face_set.size();
- face_set.push_back(BSP_MFace());
-
- BSP_MFace & face = face_set[fi];
- BSP_MFace &new_face = face_set[new_fi];
-
- vector<BSP_VertexInd>::const_iterator f_verts_it = face.m_verts.begin();
- vector<BSP_VertexInd>::const_iterator f_verts_end = face.m_verts.end();
-
- MT_Point3 ptA = vertex_set[face.m_verts.back()].m_pos;
- BSP_Classification prev_class = BSP_Classification(vertex_set[face.m_verts.back()].OpenTag());
-
- for (; f_verts_it != f_verts_end;++f_verts_it) {
-
- BSP_Classification v_class = BSP_Classification(vertex_set[*f_verts_it].OpenTag());
-
- if (v_class == e_classified_on) {
- m_in_loop.push_back(*f_verts_it);
- m_out_loop.push_back(*f_verts_it);
- prev_class = e_classified_on;
- continue;
- } else
- if (v_class == e_classified_in) {
- m_in_loop.push_back(*f_verts_it);
- } else
- if (v_class == e_classified_out) {
- m_out_loop.push_back(*f_verts_it);
- }
-
- if ((prev_class != e_classified_on) &&
- (prev_class != v_class)) {
- // spanning edge
-
- const MT_Point3 & ptB = vertex_set[*f_verts_it].m_pos;
-
- // compute the intersection point of plane and ptA->ptB
- MT_Vector3 v = ptB - ptA;
- MT_Scalar sideA = plane.signedDistance(ptA);
-
- MT_Scalar epsilon = -sideA/plane.Normal().dot(v);
- MT_Point3 new_p = ptA + (v * epsilon);
-
- BSP_VertexInd new_vi(vertex_set.size());
- vertex_set.push_back(BSP_MVertex(new_p));
-
- m_in_loop.push_back(new_vi);
- m_out_loop.push_back(new_vi);
- }
-
- ptA = vertex_set[*f_verts_it].m_pos;
- prev_class = v_class;
- }
-
- // Ok should have 2 loops 1 representing the in_loop and
- // 1 for the out_loop
-
- new_face.m_verts = m_out_loop;
- face.m_verts = m_in_loop;
-
- new_face.m_plane = face.m_plane;
-
- // we don't bother maintaining any of the other
- // properties.
-
- fin = fi;
- fout = new_fi;
-
- m_in_loop.clear();
- m_out_loop.clear();
-};
-
-
diff --git a/intern/bsp/intern/BSP_CSGNCMeshSplitter.h b/intern/bsp/intern/BSP_CSGNCMeshSplitter.h
deleted file mode 100755
index 407a4c8b46f..00000000000
--- a/intern/bsp/intern/BSP_CSGNCMeshSplitter.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BSP_CSGNCMeshSplitter_h
-#define BSP_CSGNCMeshSplitter_h
-
-class BSP_MeshFragment;
-class MT_Plane3;
-class BSP_CSGMesh;
-
-#include "BSP_MeshPrimitives.h"
-#include "../extern/CSG_BooleanOps.h"
-#include "BSP_CSGISplitter.h"
-
-
-/**
- * This class contains splitting functions for a CSGMesh.
- * The atomic operation of a bsp CSG algorithm is to split
- * a mesh fragment (connected collection of polygons contained
- * in a convex cell) by a plane. This class makes no attempt
- * to maintain edge connectivity in the mesh. It just rips
- * up the polygons. This is fine for tree building.
- */
-
-
-class BSP_CSGNCMeshSplitter : public BSP_CSGISplitter
-{
-public :
-
- /// construction
-
- BSP_CSGNCMeshSplitter(
- );
-
- BSP_CSGNCMeshSplitter(
- const BSP_CSGNCMeshSplitter & other
- );
-
- /**
- * @section BSP specific mesh operations.
- * Inherited from BSP_CSGISplitter
- */
-
- /**
- * Split a mesh fragment wrt plane. Generates 3 mesh fragments,
- * in, out and on. Only splits polygons - not edges, does not maintain
- * connectivity information. The contents of frag are consumed by this oepration.
- */
- void
- Split(
- const MT_Plane3& plane,
- BSP_MeshFragment *frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
- );
-
- /// Split the entire mesh with respect to the plane.
-
- void
- Split(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_MeshFragment *spanning_frag
- );
-
- ~BSP_CSGNCMeshSplitter(
- );
-
-private :
-
- void
- SplitImp(
- BSP_CSGMesh & mesh,
- const MT_Plane3& plane,
- const std::vector<BSP_FaceInd> & spanning_faces,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- std::vector<BSP_VertexInd> & classified_verts
-
- );
-
- void
- SplitPolygon(
- const MT_Plane3 &plane,
- BSP_CSGMesh & mesh,
- BSP_FaceInd fi,
- BSP_FaceInd &fin,
- BSP_FaceInd &fout
- );
-
- /// Cached helpers
-
- /// Split function responsibe for:
- std::vector<BSP_FaceInd> m_spanning_faces;
- std::vector<BSP_VertexInd> m_tagged_verts;
-
- /// SplitPolygon responsible for:
- std::vector<BSP_FaceInd> m_in_loop,m_out_loop,m_on_loop;
-
-};
-
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_CSGUserData.cpp b/intern/bsp/intern/BSP_CSGUserData.cpp
deleted file mode 100755
index fec5ff560e6..00000000000
--- a/intern/bsp/intern/BSP_CSGUserData.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "BSP_CSGUserData.h"
-
-
-
-BSP_CSGUserData::
-BSP_CSGUserData(
- const int width
-):
- m_width (width)
-{
-}
-
-/**
- * Add a new uninitialized record to the end of the
- * array
- */
-
- void
-BSP_CSGUserData::
-IncSize(
-){
- m_data.insert(m_data.end(),m_width,char(0));
-}
-
- int
-BSP_CSGUserData::
-Duplicate(
- void *record
-){
- if (m_width) {
- int output = Size();
- IncSize();
-
- memcpy(&m_data[ m_data.size() - m_width ], record, m_width);
-
- return output;
- }
- return 0;
-}
-
- void
-BSP_CSGUserData::
-Duplicate(
- int record_index
-){
- if (m_width) {
- IncSize();
- memcpy(&m_data[ m_data.size() - m_width ],
- &m_data[ record_index * m_width], m_width);
- }
-}
-
-
- void
-BSP_CSGUserData::
-Copy(
- void *output,
- int pos
-){
- if (m_width) {
- memcpy(output, &m_data[m_width*pos],m_width);
- }
-}
- void
-BSP_CSGUserData::
-Reserve(
- int size
-){
- m_data.reserve(size * m_width);
-}
-
-
-/// Return the width of an individual record
-
- int
-BSP_CSGUserData::
-Width(
-) const{
- return m_width;
-}
-
-
-/// return the current number of records stored in the array.
- int
-BSP_CSGUserData::
-Size(
-) const {
- if (m_width == 0) return 0;
- return m_data.size() / m_width;
-}
-
-
-/// return a pointer to the start of the nth record in the array.
-
- void *
-BSP_CSGUserData::
-operator [] (
- const int pos
-){
- return &m_data[ m_width*pos ];
-}
-
diff --git a/intern/bsp/intern/BSP_CSGUserData.h b/intern/bsp/intern/BSP_CSGUserData.h
deleted file mode 100755
index 8b008b83845..00000000000
--- a/intern/bsp/intern/BSP_CSGUserData.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BSP_CSGUserData_h
-#define BSP_CSGUserData_h
-
-#include <vector>
-
-/**
- * This data represents a continuous block of
- * data of unknown type. This holds the user
- * data during a BSP operation.
- */
-
-class BSP_CSGUserData
-{
-public :
-
- /**
- * width defines the size in bytes of a
- * single element (record) of user data
- */
-
- BSP_CSGUserData(
- const int width
- );
-
- /**
- * Reserve some space in the array
- */
- void
- Reserve(
- int size
- );
-
- /**
- * Add a new uninitialized record to the end of the
- * array
- */
-
- void
- IncSize(
- );
-
- /**
- * duplicate a recod and insert it into the end of the array
- * returns the index of the new record. Make sure that the
- * record does not belong to this buffer as this can cause errors.
- */
-
- int
- Duplicate(
- void *
- );
-
- void
- Duplicate(
- int record_index
- );
-
- /**
- * Copies the record at position pos in the array to the
- * memory pointed to by output
- */
-
- void
- Copy(
- void *output,
- int pos
- );
-
- /// Return the width of an individual record
-
- int
- Width(
- ) const;
-
-
- /// return the current number of records stored in the array.
- int
- Size(
- ) const;
-
-
- /// return a pointer to the start of the nth record in the array.
-
- void *
- operator [] (
- const int pos
- );
-
-private :
-
- /// Private - force use of public constructor only.
-
- BSP_CSGUserData(
- );
-
-
- /// The block of data.
- std::vector<char> m_data;
- /// The width of a record in this array.
- int m_width;
-};
-
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_FragNode.cpp b/intern/bsp/intern/BSP_FragNode.cpp
deleted file mode 100755
index c23b210a700..00000000000
--- a/intern/bsp/intern/BSP_FragNode.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "BSP_CSGMesh.h"
-
-#include "BSP_FragNode.h"
-#include "BSP_CSGISplitter.h"
-
-
-BSP_FragNode::
-BSP_FragNode(
- const MT_Plane3 & plane,
- BSP_CSGMesh *mesh
-):
- m_plane(plane),
- m_in_tree(mesh),
- m_out_tree(mesh)
-{
-}
-
-/**
- * Public methods
- * Should only be called by BSP_FragTree
- */
-
-BSP_FragNode::
-~BSP_FragNode(
-){
- // nothing to do
-}
-
- MEM_SmartPtr<BSP_FragNode>
-BSP_FragNode::
-New(
- const MT_Plane3 & plane,
- BSP_CSGMesh *mesh
-){
- return new BSP_FragNode(plane,mesh);
-}
-
-
- void
-BSP_FragNode::
-Build(
- BSP_MeshFragment *frag,
- BSP_CSGISplitter & splitter
-){
- // we know there must be some polygons still in
- // the fragment otherwise this node would not hve been
- // constructed.
-
- BSP_CSGMesh *mesh = frag->Mesh();
-
- // split the incoming fragment by the plane
- // generating in,out,on fragments which are
- // passed down the in and out trees.
-
- BSP_MeshFragment in_frag(mesh,e_classified_in),out_frag(mesh,e_classified_out);
- MEM_SmartPtr<BSP_MeshFragment> on_frag = new BSP_MeshFragment(mesh,e_classified_on);
- splitter.Split(m_plane,frag,&in_frag,&out_frag,on_frag,NULL);
-
- // We are not interested in the on fragments.
- on_frag.Delete();
-
- m_in_tree.Build(&in_frag,splitter);
- m_out_tree.Build(&out_frag,splitter);
-}
-
- void
-BSP_FragNode::
-Push(
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *output,
- const BSP_Classification keep,
- const bool dominant,
- BSP_CSGISplitter & splitter
-){
- BSP_CSGMesh *mesh = in_frag->Mesh();
-
-
- MEM_SmartPtr<BSP_MeshFragment> inside_frag = new BSP_MeshFragment(mesh,e_classified_in);
- MEM_SmartPtr<BSP_MeshFragment> outside_frag = new BSP_MeshFragment(mesh,e_classified_out);
- MEM_SmartPtr<BSP_MeshFragment> on_frag = new BSP_MeshFragment(mesh,e_classified_on);
-
- // deal with memory exceptions here.
-
- splitter.Split(m_plane,in_frag,inside_frag,outside_frag,on_frag,NULL);
-
- // deal with the on_fragments.
-
- if (on_frag->FaceSet().size()) {
-
- // The on fragment contains polygons that are outside both subtrees and polygons
- // that are inside one or more sub trees. If we are taking the union then we can
- // immediately add that first set of polygons to the ouput. We must then decide what
- // to do with potenially overlapping polygons from both objects. If we assume both
- // objects are closed then we can identify the conflict zones as
- // polygons outside B- and inside B+
- // polygons outside B+ and inside B-
-
- // In these conflict zones we must choose a dominant object this is indicated
- // by the bool parameter to this function. If the object is not dominant then
- // we do nothing inside these conflict zones.
- // The first set should correspond with on polygons from object B with the same
- // orientation as this node. The second corresponding with polygons with opposite
- // orientation.
- // We don't want to replace polygons from A with polygons of opposite orientation
- // from B. So we split up the on polygons of A into 2 sets according to their orientation.
- // We add to output (A- out B-) in B+ and (A+ out B+) in B-
-
-
-#if 1
-
- if (keep == e_classified_out) {
- // we are doing a union operation.
- // Make sure that this is not a leaf node.
- if(m_in_tree.m_node != NULL || m_out_tree.m_node != NULL) {
- BSP_MeshFragment frag_outBneg_outBpos(mesh,e_classified_on);
- BSP_MeshFragment temp1(on_frag.Ref());
- m_in_tree.Push(
- &temp1,&frag_outBneg_outBpos,
- e_classified_out,e_classified_on,
- false,splitter
- );
-
- m_out_tree.Push(
- &frag_outBneg_outBpos,output,e_classified_out,e_classified_on,
- false,splitter
- );
- }
-#if 1
- if (dominant) {
-
- // Here we compute the intersection zones.
- BSP_MeshFragment frag_on_pos(mesh,e_classified_on),frag_on_neg(mesh,e_classified_on);
- on_frag->ClassifyOnFragments(m_plane,&frag_on_pos,&frag_on_neg);
-
- BSP_MeshFragment temp1(mesh,e_classified_in);
-
- // push -ve fragments down inside tree, push result down outside
- m_in_tree.Push(&frag_on_neg,&temp1,e_classified_out,e_classified_on,false,splitter);
- m_out_tree.Push(&temp1,output,e_classified_in,e_classified_on,false,splitter);
- temp1.FaceSet().clear();
-
- // push +ve fragments down outside tree, push result down inside.
- m_out_tree.Push(&frag_on_pos,&temp1,e_classified_out,e_classified_on,false,splitter);
- m_in_tree.Push(&temp1,output,e_classified_in,e_classified_on,false,splitter);
- }
-#endif
- } else if (keep == e_classified_in) {
-
- // we are doing an intersection
-
- // A = on_frag in X+ out X-
- // B = on_frag in X- out X+
- // C = on_frag in X- in X+
-
- // If X+ is NULL then A = F out X-, B = 0, C = F in X-
- // If X- is NULLL then A = 0, B = F out X+ , C = F in X+
- // If both NULL then A = C = 0, B = F
-
- // Conflicts only happen in A and B.
- // negative fragments only in A, positive fragments only in B, anything in C.
- // First compute F in C an add to ouput.
-
- BSP_MeshFragment frag_on_pos(mesh,e_classified_on),frag_on_neg(mesh,e_classified_on);
- on_frag->ClassifyOnFragments(m_plane,&frag_on_pos,&frag_on_neg);
-
- if (m_in_tree.m_node == NULL) {
- if (m_out_tree.m_node == NULL) {
- // pick stuff that points in the same direction as this node
- // only if priority.
- if (dominant) {
- // pass +ve frags into B = F.
- // trick just pass down in tree... just adds to output.
- m_in_tree.Push(&frag_on_pos,output,e_classified_in,e_classified_on,false,splitter);
- }
- } else {
- // A = 0, B= F out X+ , C = F in X+
- if (dominant) {
- // m_out_tree.Push(&frag_on_pos,output,e_classified_out,e_classified_on,false,splitter);
- m_out_tree.Push(on_frag,output,e_classified_in,e_classified_on,false,splitter);
- }
- }
- } else {
- if (m_out_tree.m_node == NULL) {
- // A = F out X-, B=0, C = F in X-
- if (dominant) {
- // m_in_tree.Push(&frag_on_neg,output,e_classified_out,e_classified_on,false,splitter);
- m_in_tree.Push(on_frag,output,e_classified_in,e_classified_on,false,splitter);
- }
- } else {
- // The normals case
- if (dominant) {
- BSP_MeshFragment temp1(mesh,e_classified_on);
- m_out_tree.Push(&frag_on_neg,&temp1,e_classified_in,e_classified_on,false,splitter);
- m_in_tree.Push(&temp1,output,e_classified_out,e_classified_on,false,splitter);
- temp1.FaceSet().clear();
-
- m_in_tree.Push(&frag_on_pos,&temp1,e_classified_in,e_classified_on,false,splitter);
- m_out_tree.Push(&temp1,output,e_classified_out,e_classified_on,false,splitter);
- }
- BSP_MeshFragment temp1(mesh,e_classified_on);
- m_in_tree.Push(on_frag,&temp1,e_classified_in,e_classified_on,false,splitter);
- m_out_tree.Push(&temp1,output,e_classified_in,e_classified_on,false,splitter);
- }
- }
- }
-
-
-#endif
- on_frag.Delete();
- }
-
- m_in_tree.Push(inside_frag,output,keep,e_classified_in,dominant,splitter);
- m_out_tree.Push(outside_frag,output,keep,e_classified_out,dominant,splitter);
-};
-
- void
-BSP_FragNode::
-Classify(
- BSP_MeshFragment * frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_CSGISplitter & splitter
-){
-
- BSP_CSGMesh *mesh = frag->Mesh();
-
- MEM_SmartPtr<BSP_MeshFragment> inside_frag = new BSP_MeshFragment(mesh,e_classified_in);
- MEM_SmartPtr<BSP_MeshFragment> outside_frag = new BSP_MeshFragment(mesh,e_classified_out);
- MEM_SmartPtr<BSP_MeshFragment> frag_on = new BSP_MeshFragment(mesh,e_classified_on);
-
- splitter.Split(m_plane,frag,inside_frag,outside_frag,frag_on,NULL);
-
- // copy the on fragments into the on_frag output.
-
- if (frag_on->FaceSet().size()) {
-
- on_frag->FaceSet().insert(
- on_frag->FaceSet().end(),
- frag_on->FaceSet().begin(),
- frag_on->FaceSet().end()
- );
- }
-
- frag_on.Delete();
-
- // pass everything else down the tree.
-
- m_in_tree.Classify(inside_frag,in_frag,out_frag,on_frag,e_classified_in,splitter);
- m_out_tree.Classify(outside_frag,in_frag,out_frag,on_frag,e_classified_out,splitter);
-}
-
-
-/**
- * Accessor methods
- */
-
- BSP_FragTree &
-BSP_FragNode::
-InTree(
-){
- return m_in_tree;
-}
-
- BSP_FragTree &
-BSP_FragNode::
-OutTree(
-){
- return m_out_tree;
-}
-
- MT_Plane3&
-BSP_FragNode::
-Plane(
-){
- return m_plane;
-}
-
-
-
-
-
diff --git a/intern/bsp/intern/BSP_FragNode.h b/intern/bsp/intern/BSP_FragNode.h
deleted file mode 100755
index ed4b6a9f609..00000000000
--- a/intern/bsp/intern/BSP_FragNode.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BSP_FragNode_h
-#define BSP_FragNode_h
-
-#include "BSP_FragTree.h"
-#include "BSP_MeshFragment.h"
-#include "MT_Plane3.h"
-
-class BSP_CSGISplitter;
-
-class BSP_FragNode : public MEM_NonCopyable
-{
-private:
-
- /**
- * The plane defining this node.
- */
-
- MT_Plane3 m_plane;
-
- /**
- * Children of this node.
- */
-
- BSP_FragTree m_in_tree;
- BSP_FragTree m_out_tree;
-
-private :
-
- BSP_FragNode(
- const MT_Plane3 & plane,
- BSP_CSGMesh *mesh
- );
-
-public :
-
- /**
- * Public methods
- * Should only be called by BSP_FragTree
- */
-
- ~BSP_FragNode(
- );
-
- static
- MEM_SmartPtr<BSP_FragNode>
- New(
- const MT_Plane3 & plane,
- BSP_CSGMesh *mesh
- );
-
- void
- Build(
- BSP_MeshFragment *frag,
- BSP_CSGISplitter & splitter
- );
-
- void
- Push(
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *output,
- const BSP_Classification keep,
- const bool dominant,
- BSP_CSGISplitter & splitter
- );
-
- void
- Classify(
- BSP_MeshFragment * frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_CSGISplitter & splitter
- );
-
- /**
- * Accessor methods
- */
-
- BSP_FragTree &
- InTree(
- );
-
- BSP_FragTree &
- OutTree(
- );
-
- MT_Plane3&
- Plane(
- );
-
-};
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_FragTree.cpp b/intern/bsp/intern/BSP_FragTree.cpp
deleted file mode 100755
index e38bf42d4b5..00000000000
--- a/intern/bsp/intern/BSP_FragTree.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "BSP_FragTree.h"
-
-#include "BSP_FragNode.h"
-#include "BSP_CSGMesh.h"
-#include "BSP_MeshFragment.h"
-#include "MT_Plane3.h"
-#include "BSP_CSGException.h"
-#include <vector>
-#include "BSP_CSGISplitter.h"
-
-using namespace std;
-
- MEM_SmartPtr<BSP_FragTree>
-BSP_FragTree::
-New(
- BSP_CSGMesh *mesh,
- BSP_CSGISplitter & splitter
-){
- if (mesh == NULL) return NULL;
- if (mesh->FaceSet().size() == 0) return NULL;
-
- // This is the external tree construction method
- // (not the internal method!)
- // We need to build a tree root with an initial
- // node based on the mesh rather than a mesh fragment.
-
- // For now we pick an arbitrary polygon for the initial
- // plane.
-
- vector<BSP_MVertex> verts = mesh->VertexSet();
- const BSP_MFace & f0 = mesh->FaceSet()[0];
-
- MT_Plane3 plane = f0.m_plane;
-
- MEM_SmartPtr<BSP_FragTree> output(new BSP_FragTree(mesh));
- MEM_SmartPtr<BSP_FragNode> node(BSP_FragNode::New(plane,mesh));
-
- if (output == NULL || node == NULL) return NULL;
-
- // Generate initial mesh fragments for this plane pass into
- // first node.
-
- BSP_MeshFragment frag_in(mesh,e_classified_in),frag_out(mesh,e_classified_out);
-
- MEM_SmartPtr<BSP_MeshFragment> on_frag = new BSP_MeshFragment(mesh,e_classified_on);
-
- splitter.Split(*mesh,plane,&frag_in,&frag_out,on_frag,NULL);
-
- // We are not interested in the on_frag.
- on_frag.Delete();
-
- // Build the in_tree of the first node(recursive)
- node->InTree().Build(&frag_in,splitter);
-
- // Build the out tree of the first node(recursive)
- node->OutTree().Build(&frag_out,splitter);
-
- output->m_node = node;
-
- return output;
-}
-
- void
-BSP_FragTree::
-Classify(
- BSP_CSGMesh *mesh,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_CSGISplitter & splitter
-){
-
- if (mesh == NULL) return;
- if (mesh->FaceSet().size() == 0) return;
- if (m_node == NULL) return;
-
- BSP_MeshFragment frag_in(mesh,e_classified_in);
- BSP_MeshFragment frag_out(mesh,e_classified_out);
- BSP_MeshFragment frag_on(mesh,e_classified_on);
- BSP_MeshFragment frag_spanning(mesh,e_classified_spanning);
-
- splitter.Split(*mesh,m_node->Plane(),&frag_in,&frag_out,&frag_on,NULL);
-
- if (frag_on.FaceSet().size()) {
-
- on_frag->FaceSet().insert(
- on_frag->FaceSet().end(),
- frag_on.FaceSet().begin(),
- frag_on.FaceSet().end()
- );
-
- frag_on.FaceSet().clear();
- }
-
- // recurse into subtrees.
- m_node->InTree().Classify(&frag_in,in_frag,out_frag,on_frag,e_classified_in,splitter);
- m_node->OutTree().Classify(&frag_out,in_frag,out_frag,on_frag,e_classified_out,splitter);
-
-}
-
-
-
-
-
-BSP_FragTree::
-~BSP_FragTree(
-){
- // nothing to do
-}
-
-BSP_FragTree::
-BSP_FragTree(
- BSP_CSGMesh * mesh
-):
- m_mesh(mesh)
-{
- //nothing to do
-}
-
-BSP_FragTree::
-BSP_FragTree(
-){
- // nothing to do
-}
-
- void
-BSP_FragTree::
-Build(
- BSP_MeshFragment * frag,
- BSP_CSGISplitter & splitter
-){
-
- // Node must be NULL because we are building the tree.
-
- MT_assert(m_node == NULL);
-
- if (frag->FaceSet().size()) {
-
- // choose a plane for the node. The first index in this
- // mesh fragment will do for now.
-
- // choose a random splitting plane
-
- MT_Plane3 plane;
- {
- int rand_index;
-#if 1
- if (frag->FaceSet().size() > 1) {
- rand_index = rand() % frag->FaceSet().size();
- } else {
- rand_index = 0;
- }
-#else
- rand_index = 0;
-#endif
-
- const BSP_MFace & f0 = m_mesh->FaceSet()[frag->FaceSet()[rand_index]];
- plane = f0.m_plane;
- }
-
- // build the node.
- m_node = BSP_FragNode::New(plane,frag->Mesh());
-
- if (m_node == NULL) {
- BSP_CSGException e(e_tree_build_error);
- throw(e);
- }
-
- m_node->Build(frag,splitter);
- }
-}
-
-
- void
-BSP_FragTree::
-Push(
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *output,
- const BSP_Classification keep,
- const BSP_Classification current,
- const bool dominant,
- BSP_CSGISplitter & splitter
-){
-
- if (in_frag->FaceSet().size()) {
-
- if (m_node == NULL) {
-
- // we have reached a leaf node.
- // if the current classification matches
- // the classification we want to keep
- // copy the polygons of the current
- // fragment onto the output
- vector<BSP_FaceInd>::const_iterator in_frag_it = in_frag->FaceSet().begin();
- vector<BSP_FaceInd>::const_iterator in_frag_end = in_frag->FaceSet().end();
-
- if (keep == current || current == e_classified_on) {
- for (;in_frag_it != in_frag_end; ++ in_frag_it) {
- output->FaceSet().push_back(*in_frag_it);
- }
-
- in_frag->FaceSet().clear();
- }
- } else {
-
- m_node->Push(in_frag,output,keep,dominant,splitter);
- }
- }
-}
-
-
- void
-BSP_FragTree::
-Classify(
- BSP_MeshFragment * frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- const BSP_Classification current,
- BSP_CSGISplitter & splitter
-){
-
- if (frag->FaceSet().size()) {
-
- if (m_node == NULL) {
-
- vector<BSP_FaceInd>::const_iterator frag_it = frag->FaceSet().begin();
- vector<BSP_FaceInd>::const_iterator frag_end = frag->FaceSet().end();
-
- BSP_MeshFragment *output;
- if (current == e_classified_in) {
- output = in_frag;
- } else {
- //must be e_classified_out
- output = out_frag;
- }
- // Copy the selected indices into the correct output fragment.
-
- for (;frag_it != frag_end; ++ frag_it) {
- output->FaceSet().push_back(*frag_it);
- }
-
- frag->FaceSet().clear();
- } else {
-
- m_node->Classify(frag,in_frag,out_frag,on_frag,splitter);
- }
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/bsp/intern/BSP_FragTree.h b/intern/bsp/intern/BSP_FragTree.h
deleted file mode 100755
index caf7234d739..00000000000
--- a/intern/bsp/intern/BSP_FragTree.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef BSP_FragTree_h
-#define BSP_FragTree_h
-
-class BSP_FragNode;
-
-#include "MEM_SmartPtr.h"
-#include "MEM_NonCopyable.h"
-#include "BSP_MeshPrimitives.h"
-
-class BSP_CSGMesh;
-class BSP_MeshFragment;
-class BSP_CSGISplitter;
-
-class BSP_FragTree : public MEM_NonCopyable
-{
-public :
-
- /**
- * Create a new BSP_FragTree allocated
- * on the heap for mesh. Note mesh will
- * be divided up by this operation. If you
- * want to retain the original mesh make a copy
- * of it first.
- */
-
- static
- MEM_SmartPtr<BSP_FragTree>
- New(
- BSP_CSGMesh *mesh,
- BSP_CSGISplitter & splitter
- );
-
-
- /**
- * Push a mesh fragment down the tree,
- * splitting the mesh as it goes.
- * upon reaching leaves it puts polygons from fragments
- * of type keep into the output fragment.
- */
-
- void
- Push(
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *output,
- const BSP_Classification keep,
- const BSP_Classification current,
- const bool dominant,
- BSP_CSGISplitter & splitter
- );
-
- void
- Classify(
- BSP_CSGMesh *mesh,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- BSP_CSGISplitter & splitter
- );
-
-
- ~BSP_FragTree(
- );
-
-private :
-
- friend class BSP_FragNode;
-
- BSP_FragTree(
- );
-
- BSP_FragTree(
- BSP_CSGMesh *mesh
- );
-
- void
- Build(
- BSP_MeshFragment * frag,
- BSP_CSGISplitter & splitter
- );
-
-
- void
- Classify(
- BSP_MeshFragment * frag,
- BSP_MeshFragment *in_frag,
- BSP_MeshFragment *out_frag,
- BSP_MeshFragment *on_frag,
- const BSP_Classification current,
- BSP_CSGISplitter & splitter
- );
-
-private :
-
- /**
- * pointer to the mesh for this tree.
- * Tree is only valid whilst mesh is around.
- */
-
- BSP_CSGMesh *m_mesh;
-
- /**
- * The node owned by this tree.
- */
-
- MEM_SmartPtr<BSP_FragNode> m_node;
-
-};
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_MeshFragment.cpp b/intern/bsp/intern/BSP_MeshFragment.cpp
deleted file mode 100755
index cd79078f056..00000000000
--- a/intern/bsp/intern/BSP_MeshFragment.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "BSP_MeshFragment.h"
-
-#include "BSP_CSGMesh.h"
-#include "MT_Plane3.h"
-#include <math.h>
-
-using namespace std;
-
-
-BSP_MeshFragment::
-BSP_MeshFragment(
- BSP_CSGMesh *mesh,
- BSP_Classification classification
-):
- m_mesh(mesh),
- m_classification(classification)
-{
- MT_assert(m_mesh != NULL);
- //nothing to do
-}
-
-const
- vector<BSP_FaceInd> &
-BSP_MeshFragment::
-FaceSet(
-) const {
- return m_faces;
-}
-
- vector<BSP_FaceInd> &
-BSP_MeshFragment::
-FaceSet(
-) {
- return m_faces;
-}
-
- BSP_CSGMesh *
-BSP_MeshFragment::
-Mesh(
-){
- return m_mesh;
-}
-
- BSP_CSGMesh *
-BSP_MeshFragment::
-Mesh(
-) const {
- return m_mesh;
-}
-
- BSP_Classification
-BSP_MeshFragment::
-ClassifyPolygon(
- const MT_Plane3 &plane,
- const BSP_MFace & face,
- std::vector<BSP_MVertex>::const_iterator verts,
- vector<BSP_VertexInd> & visited_verts
-){
-
- vector<BSP_VertexInd>::const_iterator f_vi_end = face.m_verts.end();
- vector<BSP_VertexInd>::const_iterator f_vi_it = face.m_verts.begin();
-
- BSP_Classification p_class = e_unclassified;
-
- int on_count = 0;
-
- for (;f_vi_it != f_vi_end; ++f_vi_it) {
-
- BSP_MVertex & vert = const_cast<BSP_MVertex &>(verts[int(*f_vi_it)]);
-
- if (BSP_Classification(vert.OpenTag()) == e_unclassified)
- {
- MT_Scalar sdistance = plane.signedDistance(vert.m_pos);
- if (fabs(sdistance) <= BSP_SPLIT_EPSILON) {
- // this vertex is on
- vert.SetOpenTag(e_classified_on);
- } else
- if (sdistance > MT_Scalar(0)) {
- vert.SetOpenTag(e_classified_out);
- } else {
- vert.SetOpenTag(e_classified_in);
- }
- visited_verts.push_back(*f_vi_it);
- }
- BSP_Classification v_class = BSP_Classification(vert.OpenTag());
-
- if (v_class == e_classified_on) on_count++;
-
-
- if (p_class == e_unclassified || p_class == e_classified_on) {
- p_class = v_class;
- } else
- if (p_class == e_classified_spanning) {
- } else
- if (p_class == e_classified_in) {
- if (v_class == e_classified_out) {
- p_class = e_classified_spanning;
- }
- } else {
- if (v_class == e_classified_in) {
- p_class = e_classified_spanning;
- }
- }
- }
-
- if (on_count > 2) p_class = e_classified_on;
-
- return p_class;
-}
-
-
-// Classify this mesh fragment with respect
-// to plane. The index sets of this fragment
-// are consumed by this action. Vertices
-// are tagged with a classification enum.
-
- void
-BSP_MeshFragment::
-Classify(
- const MT_Plane3 & plane,
- BSP_MeshFragment * in_frag,
- BSP_MeshFragment * out_frag,
- BSP_MeshFragment * on_frag,
- vector<BSP_FaceInd> & spanning_faces,
- vector<BSP_VertexInd> & visited_verts
-){
-
- vector<BSP_MVertex> & vertex_set = m_mesh->VertexSet();
- vector<BSP_MFace> & face_set = m_mesh->FaceSet();
-
- // Now iterate through the polygons and classify.
-
- vector<BSP_FaceInd>::const_iterator fi_end = m_faces.end();
- vector<BSP_FaceInd>::iterator fi_it = m_faces.begin();
-
- vector<BSP_FaceInd> & face_in_set = in_frag->FaceSet();
- vector<BSP_FaceInd> & face_out_set = out_frag->FaceSet();
- vector<BSP_FaceInd> & face_on_set = on_frag->FaceSet();
-
- for (;fi_it != fi_end; ++fi_it) {
-
- BSP_Classification p_class = ClassifyPolygon(
- plane,
- face_set[*fi_it],
- vertex_set.begin(),
- visited_verts
- );
- // p_class now holds the classification for this polygon.
- // assign to the appropriate bucket.
-
- if (p_class == e_classified_in) {
- face_in_set.push_back(*fi_it);
- } else
- if (p_class == e_classified_out) {
- face_out_set.push_back(*fi_it);
- } else
- if (p_class == e_classified_on) {
- face_on_set.push_back(*fi_it);
- } else {
- spanning_faces.push_back(*fi_it);
- // This is assigned later when we split the polygons in two.
- }
- }
-
- m_faces.clear();
-
-}
-
- void
-BSP_MeshFragment::
-Classify(
- BSP_CSGMesh & mesh,
- const MT_Plane3 & plane,
- BSP_MeshFragment * in_frag,
- BSP_MeshFragment * out_frag,
- BSP_MeshFragment * on_frag,
- vector<BSP_FaceInd> & spanning_faces,
- vector<BSP_VertexInd> & visited_verts
-){
-
- vector<BSP_MVertex> & vertex_set = mesh.VertexSet();
- vector<BSP_MFace> & face_set = mesh.FaceSet();
-
- // Now iterate through the polygons and classify.
-
- int fi_end = mesh.FaceSet().size();
- int fi_it = 0;
-
- vector<BSP_FaceInd> & face_in_set = in_frag->FaceSet();
- vector<BSP_FaceInd> & face_out_set = out_frag->FaceSet();
- vector<BSP_FaceInd> & face_on_set = on_frag->FaceSet();
-
- for (;fi_it != fi_end; ++fi_it) {
-
- BSP_Classification p_class = ClassifyPolygon(
- plane,
- face_set[fi_it],
- vertex_set.begin(),
- visited_verts
- );
- // p_class now holds the classification for this polygon.
- // assign to the appropriate bucket.
-
- if (p_class == e_classified_in) {
- face_in_set.push_back(fi_it);
- } else
- if (p_class == e_classified_out) {
- face_out_set.push_back(fi_it);
- } else
- if (p_class == e_classified_on) {
- face_on_set.push_back(fi_it);
- } else {
- spanning_faces.push_back(fi_it);
- }
- }
-
-}
- void
-BSP_MeshFragment::
-ClassifyOnFragments(
- const MT_Plane3 &plane,
- BSP_MeshFragment *pos_frag,
- BSP_MeshFragment *neg_frag
-){
-
- vector<BSP_MFace> & face_set = m_mesh->FaceSet();
- vector<BSP_FaceInd>::const_iterator fi_end = m_faces.end();
- vector<BSP_FaceInd>::iterator fi_it = m_faces.begin();
-
- MT_Scalar d = plane.Scalar();
-
- for (;fi_it != fi_end; ++fi_it) {
- if (fabs(d + face_set[*fi_it].m_plane.Scalar()) > BSP_SPLIT_EPSILON) {
- pos_frag->FaceSet().push_back(*fi_it);
- } else {
- neg_frag->FaceSet().push_back(*fi_it);
- }
- }
-}
-
-BSP_MeshFragment::
-~BSP_MeshFragment(
-){
-}
-
-
diff --git a/intern/bsp/intern/BSP_MeshFragment.h b/intern/bsp/intern/BSP_MeshFragment.h
deleted file mode 100755
index 8ed3b9010e4..00000000000
--- a/intern/bsp/intern/BSP_MeshFragment.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef NAN_INCLUDED_BSP_MeshFragment_h
-#define NAN_INCLUDED_BSP_MeshFragment_h
-
-#define BSP_SPLIT_EPSILON MT_Scalar(1e-5)
-
-#include <vector>
-#include "BSP_MeshPrimitives.h"
-
-
-class BSP_CSGMesh;
-class MT_Plane3;
-/**
- * This class encodes a collection of polygons from a mesh.
- * This class only remains valid when mesh indices do not change
- * internally and of course whilst the mesh is still around.
- *
- * Polygons in the mesh point back to the unique mesh fragment
- * containing them.
- */
-
-
-class BSP_MeshFragment {
-public:
-
- BSP_MeshFragment(
- BSP_CSGMesh *mesh,
- BSP_Classification classification
- );
-
- std::vector<BSP_FaceInd> &
- FaceSet(
- ) ;
-
- const
- std::vector<BSP_FaceInd> &
- FaceSet(
- ) const ;
-
- BSP_CSGMesh *
- Mesh(
- );
-
- BSP_CSGMesh *
- Mesh(
- ) const;
-
-
- // Classify this mesh fragment with respect
- // to plane. The index sets of this fragment
- // are consumed by this action. Vertices
- // are tagged with a classification enum.
-
- void
- Classify(
- const MT_Plane3 & plane,
- BSP_MeshFragment * in_frag,
- BSP_MeshFragment * out_frag,
- BSP_MeshFragment * on_frag,
- std::vector<BSP_FaceInd> & spanning_faces,
- std::vector<BSP_VertexInd> & visited_verts
- );
-
- // Classify all the vertices and faces of mesh, generate
- // in,out and on mesh fragments.
-
- static
- void
- Classify(
- BSP_CSGMesh & mesh,
- const MT_Plane3 & plane,
- BSP_MeshFragment * in_frag,
- BSP_MeshFragment * out_frag,
- BSP_MeshFragment * on_frag,
- std::vector<BSP_FaceInd> & spanning_faces,
- std::vector<BSP_VertexInd> & visited_verts
- );
-
- // Classify the on fragment into
- // 2 sets, the +ve on frags those whose polygon
- // normals point in the same direction as the plane,
- // and the -ve frag whose normals point in the other direction.
-
- void
- ClassifyOnFragments(
- const MT_Plane3 &plane,
- BSP_MeshFragment *pos_frag,
- BSP_MeshFragment *neg_frag
- );
-
-
- ~BSP_MeshFragment(
- );
-
- /**
- * Sanity checkers.
- */
-
-
-private:
-
- // Classify the polygon wrt to the plane
- static
- BSP_Classification
- ClassifyPolygon(
- const MT_Plane3 &plane,
- const BSP_MFace & face,
- std::vector<BSP_MVertex>::const_iterator verts,
- std::vector<BSP_VertexInd> & visited_verts
- );
-
-private :
-
-
- BSP_CSGMesh * m_mesh;
- BSP_Classification m_classification;
- std::vector<BSP_FaceInd> m_faces;
-};
-
-
-#endif
-
diff --git a/intern/bsp/intern/BSP_MeshPrimitives.cpp b/intern/bsp/intern/BSP_MeshPrimitives.cpp
index c9c4873540b..54db5851be3 100755
--- a/intern/bsp/intern/BSP_MeshPrimitives.cpp
+++ b/intern/bsp/intern/BSP_MeshPrimitives.cpp
@@ -243,7 +243,8 @@ SetOpenTag(
BSP_MFace::
BSP_MFace(
):
- m_open_tag(-1)
+ m_open_tag(-1),
+ m_orig_face(0)
{
// nothing to do
}
@@ -261,11 +262,6 @@ Invert(
m_verts.end()
);
- reverse(
- m_fv_data.begin(),
- m_fv_data.end()
- );
-
// invert the normal
m_plane.Invert();
}
diff --git a/intern/bsp/intern/BSP_MeshPrimitives.h b/intern/bsp/intern/BSP_MeshPrimitives.h
index adfdb57e5f5..d245ed02524 100644
--- a/intern/bsp/intern/BSP_MeshPrimitives.h
+++ b/intern/bsp/intern/BSP_MeshPrimitives.h
@@ -36,21 +36,17 @@
#include "MT_Vector3.h"
#include "MT_Plane3.h"
-class BSP_MeshFragment;
-
#include <vector>
typedef CTR_TaggedIndex<24,0x00ffffff> BSP_VertexInd;
typedef CTR_TaggedIndex<24,0x00ffffff> BSP_EdgeInd;
typedef CTR_TaggedIndex<24,0x00ffffff> BSP_FaceInd;
typedef CTR_TaggedIndex<24,0x00ffffff> BSP_FragInd;
-typedef CTR_TaggedIndex<24,0x00ffffff> BSP_UserFVInd;
typedef std::vector<BSP_VertexInd> BSP_VertexList;
typedef std::vector<BSP_EdgeInd> BSP_EdgeList;
typedef std::vector<BSP_FaceInd> BSP_FaceList;
-typedef std::vector<BSP_UserFVInd> BSP_UserFVDataList;
/**
* Enum representing classification of primitives
@@ -227,13 +223,6 @@ public :
BSP_VertexList m_verts;
- // This is a list of face vertex data indices.
- // Each vertex index in the list has an equivalent
- // index into an array of face vertex data. This data
- // is stored externally - the mesh does not know about it's
- // contents.
-
- BSP_UserFVDataList m_fv_data;
// We also store the plane equation of this
// face. Generating on the fly during tree
// construction can lead to a lot of numerical errors.
@@ -242,6 +231,7 @@ public :
MT_Plane3 m_plane;
int m_open_tag;
+ unsigned int m_orig_face;
BSP_MFace(
);
diff --git a/intern/bsp/intern/BSP_Triangulate.cpp b/intern/bsp/intern/BSP_Triangulate.cpp
deleted file mode 100755
index fbfba62b907..00000000000
--- a/intern/bsp/intern/BSP_Triangulate.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#include <stdio.h>
-
-#include <stdlib.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "MT_Plane3.h"
-#include "BSP_Triangulate.h"
-#include "MT_assert.h"
-
-static const MT_Scalar EPSILON = MT_Scalar(1e-10);
-
-using namespace std;
-
-BSP_Triangulate::
-BSP_Triangulate(
-):
- m_xi(0),
- m_yi(1)
-{
-}
-
-BSP_Triangulate::
-~BSP_Triangulate(
-){
-}
-
-
- MT_Scalar
-BSP_Triangulate::
-Area(
- const vector<BSP_MVertex> &verts,
- const BSP_VertexList &contour
-){
-
- int n = contour.size();
-
- MT_Scalar A(0.0);
-
- for(int p=n-1,q=0; q<n; p=q++)
- {
- A+= verts[contour[p]].m_pos[m_xi]*verts[contour[q]].m_pos[m_yi] -
- verts[contour[q]].m_pos[m_xi]*verts[contour[p]].m_pos[m_yi];
- }
- return A*MT_Scalar(0.5);
-}
-
-/*
- InsideTriangle decides if a point P is Inside of the triangle
- defined by A, B, C.
- Or within an epsilon of it.
-*/
-
- bool
-BSP_Triangulate::
-InsideTriangle(
- MT_Scalar Ax, MT_Scalar Ay,
- MT_Scalar Bx, MT_Scalar By,
- MT_Scalar Cx, MT_Scalar Cy,
- MT_Scalar Px, MT_Scalar Py
-){
- MT_Scalar ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
- MT_Scalar cCROSSap, bCROSScp, aCROSSbp;
-
- ax = Cx - Bx; ay = Cy - By;
- bx = Ax - Cx; by = Ay - Cy;
- cx = Bx - Ax; cy = By - Ay;
- apx= Px - Ax; apy= Py - Ay;
- bpx= Px - Bx; bpy= Py - By;
- cpx= Px - Cx; cpy= Py - Cy;
-
- aCROSSbp = ax*bpy - ay*bpx;
- cCROSSap = cx*apy - cy*apx;
- bCROSScp = bx*cpy - by*cpx;
-
- return ((aCROSSbp >= -EPSILON) && (bCROSScp >= -EPSILON) && (cCROSSap >= -EPSILON));
-};
-
- bool
-BSP_Triangulate::
-Snip(
- const vector<BSP_MVertex> &verts,
- const BSP_VertexList &contour,
- int u,int v,
- int w,int n,
- int *V
-){
- int p;
- MT_Scalar Ax, Ay, Bx, By, Cx, Cy, Px, Py;
-
- Ax = verts[contour[V[u]]].m_pos[m_xi];
- Ay = verts[contour[V[u]]].m_pos[m_yi];
-
- Bx = verts[contour[V[v]]].m_pos[m_xi];
- By = verts[contour[V[v]]].m_pos[m_yi];
-
- Cx = verts[contour[V[w]]].m_pos[m_xi];
- Cy = verts[contour[V[w]]].m_pos[m_yi];
-
- // Snip is passes if the area of the candidate triangle is
- // greater than 2*epsilon
- // And if none of the remaining vertices are inside the polygon
- // or within an epsilon of the boundary,
-
- if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ) return false;
-
- for (p=0;p<n;p++)
- {
- if( (p == u) || (p == v) || (p == w) ) continue;
- Px = verts[contour[V[p]]].m_pos[m_xi];
- Py = verts[contour[V[p]]].m_pos[m_yi];
- if (InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false;
- }
-
- return true;
-}
-
- bool
-BSP_Triangulate::
-Process(
- const vector<BSP_MVertex> &verts,
- const BSP_VertexList &contour,
- const MT_Plane3 &normal,
- std::vector<int> &result
-){
-
- // Choose major axis of normal and assign
- // 'projection' indices m_xi,m_yi;
-
- int maj_axis = normal.Normal().closestAxis();
-
- if (maj_axis == 0) {
- m_xi = 1; m_yi = 2;
- } else
- if (maj_axis == 1) {
- m_xi = 0; m_yi = 2;
- } else {
- m_xi = 0; m_yi = 1;
- }
-
- /* initialize list of Vertices in polygon */
-
- int n = contour.size();
- if ( n < 3 ) return false;
-
- /* we want a counter-clockwise polygon in V */
- /* to true but we also nead to preserve the winding order
- of polygons going into the routine. We keep track of what
- we did with a little bool */
- bool is_flipped = false;
-
- if ( 0.0f < Area(verts,contour) ) {
- for (int v=0; v<n; v++) m_V.push_back(v);
- } else {
- for(int v=0; v<n; v++) m_V.push_back((n-1)-v);
- is_flipped = true;
- }
-
- int nv = n;
-
- /* remove nv-2 Vertices, creating 1 triangle every time */
- int count = 2*nv; /* error detection */
-
- for(int m=0, v=nv-1; nv>2; )
- {
- /* if we loop, it is probably a non-simple polygon */
- if (0 >= (count--))
- {
-#if 0
- int deb = 0;
- for (deb= 0; deb < contour.size(); deb++) {
- cout << verts[contour[deb]].m_pos << "\n";
- }
- cout.flush();
-#endif
- //** Triangulate: ERROR - probable bad polygon!
- m_V.clear();
- return false;
- }
-
- /* three consecutive vertices in current polygon, <u,v,w> */
- int u = v ; if (nv <= u) u = 0; /* previous */
- v = u+1; if (nv <= v) v = 0; /* new v */
- int w = v+1; if (nv <= w) w = 0; /* next */
-
- /* Try and snip this triangle off from the
- current polygon.*/
-
- if ( Snip(verts,contour,u,v,w,nv, &m_V[0]) )
- {
- int a,b,c,s,t;
-
- /* true names of the vertices */
- a = m_V[u]; b = m_V[v]; c = m_V[w];
-
- /* output Triangle indices*/
- if (is_flipped) {
- result.push_back( c );
- result.push_back( b );
- result.push_back( a );
- } else {
- result.push_back( a );
- result.push_back( b );
- result.push_back( c );
- }
-
- m++;
-
- /* remove v from remaining polygon */
- for(s=v,t=v+1;t<nv;s++,t++) m_V[s] = m_V[t]; nv--;
-
- /* resest error detection counter */
- count = 2*nv;
- }
- }
-
- m_V.clear();
- return true;
-}
-
-
diff --git a/intern/bsp/intern/BSP_Triangulate.h b/intern/bsp/intern/BSP_Triangulate.h
deleted file mode 100755
index 858be88419c..00000000000
--- a/intern/bsp/intern/BSP_Triangulate.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * $Id$
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
-
-#ifndef TRIANGULATE_H
-
-
-#define TRIANGULATE_H
-
-/*****************************************************************/
-/** Static class to triangulate any contour/polygon efficiently **/
-/** You should replace Vector2d with whatever your own Vector **/
-/** class might be. Does not support polygons with holes. **/
-/** Uses STL vectors to represent a dynamic array of vertices. **/
-/** This code snippet was submitted to FlipCode.com by **/
-/** John W. Ratcliff (jratcliff@verant.com) on July 22, 2000 **/
-/** I did not write the original code/algorithm for this **/
-/** this triangulator, in fact, I can't even remember where I **/
-/** found it in the first place. However, I did rework it into **/
-/** the following black-box static class so you can make easy **/
-/** use of it in your own code. Simply replace Vector2d with **/
-/** whatever your own Vector implementation might be. **/
-/*****************************************************************/
-
-#include <vector> // Include STL vector class.
-#include "MT_Point3.h"
-#include "BSP_MeshPrimitives.h"
-
-class MT_Plane3;
-
-class BSP_Triangulate
-{
-public:
-
- BSP_Triangulate(
- );
-
- // triangulate a contour/polygon, places results in STL vector
- // as series of triangles. IT uses the major axis of the normal
- // to turn it into a 2d problem.
-
- // Should chaange this to accept a point array and a list of
- // indices into that point array. Result should be indices of those
- // indices.
- //
- // MT_Point3 global_array
- // vector<BSP_VertexInd> polygon
- // result is vector<int> into polygon.
-
- bool
- Process(
- const std::vector<BSP_MVertex> &verts,
- const BSP_VertexList &contour,
- const MT_Plane3 &normal,
- std::vector<int> &result
- );
-
- // compute area of a contour/polygon
- MT_Scalar
- Area(
- const std::vector<BSP_MVertex> &verts,
- const BSP_VertexList &contour
- );
-
- // decide if point Px/Py is inside triangle defined by
- // (Ax,Ay) (Bx,By) (Cx,Cy)
-
- bool
- InsideTriangle(
- MT_Scalar Ax, MT_Scalar Ay,
- MT_Scalar Bx, MT_Scalar By,
- MT_Scalar Cx, MT_Scalar Cy,
- MT_Scalar Px, MT_Scalar Py
- );
-
- ~BSP_Triangulate(
- );
-
-private:
-
- bool
- Snip(
- const std::vector<BSP_MVertex> &verts,
- const BSP_VertexList &contour,
- int u,
- int v,
- int w,
- int n,
- int *V
- );
-
- int m_xi;
- int m_yi;
-
- // Temporary storage
-
- std::vector<int> m_V;
-
-};
-
-
-#endif
-
diff --git a/intern/bsp/intern/CSG_BooleanOps.cpp b/intern/bsp/intern/CSG_BooleanOps.cpp
index 1a3a149adeb..c6f4c5d34d0 100755
--- a/intern/bsp/intern/CSG_BooleanOps.cpp
+++ b/intern/bsp/intern/CSG_BooleanOps.cpp
@@ -39,9 +39,6 @@
#include "../extern/CSG_BooleanOps.h"
#include "BSP_CSGMesh_CFIterator.h"
-#include "BSP_CSGMeshBuilder.h"
-#include "BSP_CSGHelper.h"
-#include "BSP_CSGUserData.h"
#include "MEM_RefCountPtr.h"
#include "../../boolop/extern/BOP_Interface.h"
@@ -52,9 +49,6 @@ using namespace std;
struct BSP_MeshInfo {
BSP_CSGMesh *output_mesh;
- CSG_MeshPropertyDescriptor obA_descriptor;
- CSG_MeshPropertyDescriptor obB_descriptor;
- CSG_MeshPropertyDescriptor output_descriptor;
};
using namespace std;
@@ -74,45 +68,17 @@ CSG_NewBooleanFunction(
return output;
}
- CSG_MeshPropertyDescriptor
-CSG_DescibeOperands(
- CSG_BooleanOperation * operation,
- CSG_MeshPropertyDescriptor operandA_desciption,
- CSG_MeshPropertyDescriptor operandB_desciption
-){
- BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
-
- mesh_info->obA_descriptor = operandA_desciption;
- mesh_info->obB_descriptor = operandB_desciption;
-
- if (
- (operandA_desciption.user_data_size == operandB_desciption.user_data_size) &&
- (operandA_desciption.user_face_vertex_data_size == operandB_desciption.user_face_vertex_data_size)
- ) {
- // Then both operands have the same sets of data we can cope with this!
- mesh_info->output_descriptor.user_data_size = operandA_desciption.user_data_size;
- mesh_info->output_descriptor.user_face_vertex_data_size = operandA_desciption.user_face_vertex_data_size;
- } else {
- // There maybe some common subset of data we can seperate out but for now we just use the
- // default
- mesh_info->output_descriptor.user_data_size = 0;
- mesh_info->output_descriptor.user_face_vertex_data_size = 0;
- }
- 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_InterpolateUserFaceVertexDataFunc interp_func
+ CSG_BooleanOperation *operation,
+ CSG_OperationType op_type,
+ CSG_FaceIteratorDescriptor obAFaces,
+ CSG_VertexIteratorDescriptor obAVertices,
+ CSG_FaceIteratorDescriptor obBFaces,
+ CSG_VertexIteratorDescriptor obBVertices
){
if (operation == NULL) return 0;
BSP_MeshInfo * mesh_info = static_cast<BSP_MeshInfo *>(operation->CSG_info);
@@ -140,15 +106,8 @@ CSG_PerformBooleanOperation(
BoolOpState boolOpResult;
try {
boolOpResult = 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 );
+ obAFaces, obAVertices, obBFaces, obBVertices);
}
catch(...) {
return 0;
@@ -221,3 +180,4 @@ CSG_FreeBooleanOperation(
delete(operation);
}
}
+
diff --git a/source/blender/blenkernel/BKE_booleanops.h b/source/blender/blenkernel/BKE_booleanops.h
index ddc24457ef4..4e98c81c067 100644
--- a/source/blender/blenkernel/BKE_booleanops.h
+++ b/source/blender/blenkernel/BKE_booleanops.h
@@ -32,104 +32,21 @@
#ifndef BKE_BOOLEANOPS_H
#define BKE_BOOLEANOPS_H
-struct Mesh;
struct Object;
struct Base;
-struct CSG_FaceIteratorDescriptor;
-struct CSG_VertexIteratorDescriptor;
-struct CSG_MeshPropertyDescriptor;
+struct DerivedMesh;
-/**
- * Perform a boolean operation between 2 mesh objects and
- * add the result as a new mesh into blender data structures.
- * Assumes you have checked that the 2 objects are infact mesh
- * objects. Returns 1 on success and zero when it encountered
- * a problem. In the latter case no object is added and you should
- * report an appropriate error.
- */
-extern
- int
-NewBooleanMesh(
- struct Base * base,
- struct Base * base_select,
- int op_type
-);
+/* Performs a boolean between two mesh objects, it is assumed that both objects
+ are in fact a mesh object. On success returns 1 and creates a new mesh object
+ into blender data structures. On failure returns 0 and reports an error. */
+int NewBooleanMesh(struct Base *base, struct Base *base_select, int op);
-struct DispListMesh *NewBooleanMeshDLM(struct Object *ob, struct Object *ob_select, int int_op_type);
+/* Performs a boolean between two mesh objects, it is assumed that both objects
+ are in fact mesh object. On success returns a DerivedMesh. On failure
+ returns NULL and reports an error. */
struct DerivedMesh *NewBooleanDerivedMesh(struct Object *ob,
struct Object *ob_select,
- int int_op_type);
-
-/**
- * Functions exposed for use by BKE_booleanops_mesh
- */
-
-/**
- * Returns pointers to new mesh descriptors for
- * the given mesh. Make sure you call FreeMeshDescriptors
- * after calling this function.
- */
-
-extern
- void
-BuildMeshDescriptors(
- struct Object * ob,
- struct CSG_FaceIteratorDescriptor * face_it,
- struct CSG_VertexIteratorDescriptor * vertex_it
-);
-
-extern
- void
-FreeMeshDescriptors(
- struct CSG_FaceIteratorDescriptor * face_it,
- struct CSG_VertexIteratorDescriptor * vertex_it
-);
-
-/**
- * This little function adds a new mesh object
- * to the blender object list. It uses ob to duplicate
- * data as this seems to be easier than cerating a new one.
- * This new oject contains no faces nor vertices.
- */
-
-extern
- struct Object *
-AddNewBlenderMesh(
- struct Base *base
-);
-
-extern
- int
-InterpNoUserData(
- void *d1,
- void *d2,
- void *dnew,
- float epsilon
-);
-
-extern
- int
-InterpFaceVertexData(
- void *d1,
- void *d2,
- void *dnew,
- float epsilon
-);
-
-typedef struct {
- float uv[2];
- float color[4];
-} FaceVertexData;
-
-typedef struct {
- struct Material *material;
-
- /* assorted tface flags */
- void *tpage;
- char flag, transp, faceflag;
- short mode, tile;
-} FaceData;
-
+ int op);
#endif
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 088f5af7e07..1d443be5be2 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -533,7 +533,8 @@ float *mesh_create_orco(Object *ob)
return make_orco_mesh_internal(ob, 0);
}
- /* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0. */
+/* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0.
+ this is necessary to make the if(mface->v4) check for quads work */
#define UVSWAP(t, s) { SWAP(float, t[0], s[0]); SWAP(float, t[1], s[1]); }
void test_index_face(MFace *mface, MCol *mc, TFace *tface, int nr)
{
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 3aa76d11095..f4edda1e823 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -3375,7 +3375,7 @@ static DerivedMesh *booleanModifier_applyModifier(
/* we do a quick sanity check */
if(((Mesh *)ob->data)->totface > 3
&& bmd->object && ((Mesh *)bmd->object->data)->totface > 3) {
- DerivedMesh *result = NewBooleanDerivedMesh(bmd->object, ob,
+ DerivedMesh *result = NewBooleanDerivedMesh(ob, bmd->object,
1 + bmd->operation);
/* if new mesh returned, return it; otherwise there was
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index 275167c276f..35f4a0bc9f9 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -512,6 +512,11 @@ VecCompare(
float *v2,
float limit
);
+ int
+VecEqual(
+ float *v1,
+ float *v2
+);
float
Sqrt3f(
float f
@@ -629,6 +634,13 @@ VecRotToMat3(
extern short IsectLL2Df(float *v1, float *v2, float *v3, float *v4);
extern short IsectLL2Ds(short *v1, short *v2, short *v3, short *v4);
+/* interpolation weights of point in a triangle or quad, v4 may be NULL */
+ void
+InterpWeightsQ3Dfl(
+ float *v1, float *v2, float *v3, float *v4,
+ float *co,
+ float *w
+);
float *
vectoquat(
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index fd3d0be8330..4e8c78729dd 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -1834,6 +1834,11 @@ int VecCompare( float *v1, float *v2, float limit)
return 0;
}
+int VecEqual(float *v1, float *v2)
+{
+ return ((v1[0]==v2[0]) && (v1[1]==v2[1]) && (v1[2]==v2[2]));
+}
+
void CalcNormShort( short *v1, short *v2, short *v3, float *n) /* is also cross product */
{
float n1[3],n2[3];
@@ -2110,6 +2115,85 @@ void MinMax3(float *min, float *max, float *vec)
if(max[2]<vec[2]) max[2]= vec[2];
}
+static void BarycentricWeights(float *v1, float *v2, float *v3, float *co, float *n, float *w)
+{
+ float t00, t01, t10, t11, det, detinv, xn, yn, zn;
+ short i, j;
+
+ /* find best projection of face XY, XZ or YZ: barycentric weights of
+ the 2d projected coords are the same and faster to compute */
+ xn= fabs(n[0]);
+ yn= fabs(n[1]);
+ zn= fabs(n[2]);
+ if(zn>=xn && zn>=yn) {i= 0; j= 1;}
+ else if(yn>=xn && yn>=zn) {i= 0; j= 2;}
+ else {i= 1; j= 2;}
+
+ /* compute determinant */
+ t00= v3[i]-v1[i]; t01= v3[j]-v1[j];
+ t10= v3[i]-v2[i]; t11= v3[j]-v2[j];
+
+ det= t00*t11 - t10*t01;
+
+ if(det == 0.0f) {
+ /* zero area triangle */
+ w[0]= w[1]= w[2]= 1.0f/3.0f;
+ return;
+ }
+
+ /* compute weights */
+ detinv= 1.0/det;
+
+ w[0]= ((co[j]-v3[j])*t10 - (co[i]-v3[i])*t11)*detinv;
+ w[1]= ((co[i]-v3[i])*t01 - (co[j]-v3[j])*t00)*detinv;
+ w[2]= 1.0f - w[0] - w[1];
+}
+
+void InterpWeightsQ3Dfl(float *v1, float *v2, float *v3, float *v4, float *co, float *w)
+{
+ w[0]= w[1]= w[2]= w[3]= 0.0f;
+
+ /* first check for exact match */
+ if(VecEqual(co, v1))
+ w[0]= 1.0f;
+ else if(VecEqual(co, v2))
+ w[1]= 1.0f;
+ else if(VecEqual(co, v3))
+ w[2]= 1.0f;
+ else if(v4 && VecEqual(co, v4))
+ w[3]= 1.0f;
+ else {
+ /* otherwise compute barycentric interpolation weights */
+ float n1[3], n2[3], n[3];
+
+ VecSubf(n1, v1, v3);
+ if (v4) {
+ VecSubf(n2, v2, v4);
+ }
+ else {
+ VecSubf(n2, v2, v3);
+ }
+ Crossf(n, n1, n2);
+
+ /* OpenGL seems to split this way, so we do too */
+ if (v4) {
+ BarycentricWeights(v1, v2, v4, co, n, w);
+
+ if(w[0] < 0.0f) {
+ /* if w[1] is negative, co is on the other side of the v1-v3 edge,
+ so we interpolate using the other triangle */
+ w[0]= 0.0f;
+ BarycentricWeights(v2, v3, v4, co, n, w+1);
+ }
+ else {
+ SWAP(float, w[2], w[3]);
+ }
+ }
+ else
+ BarycentricWeights(v1, v2, v3, co, n, w);
+ }
+}
+
/* ************ EULER *************** */
void EulToMat3( float *eul, float mat[][3])
diff --git a/source/blender/src/booleanops.c b/source/blender/src/booleanops.c
index 8a2d6d4d7f9..11a3577ec0d 100644
--- a/source/blender/src/booleanops.c
+++ b/source/blender/src/booleanops.c
@@ -48,7 +48,6 @@
#include "BKE_booleanops.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_depsgraph.h"
-#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -59,6 +58,8 @@
#include "BIF_toolbox.h"
+#include "BDR_editface.h"
+
#include <math.h>
// TODO check to see how many of these includes are necessary
@@ -68,32 +69,14 @@
#include "BLI_linklist.h"
#include "BLI_memarena.h"
-static void ConvertCSGDescriptorsToDLM(
- DispListMesh *dlm,
- Object *ob,
- CSG_MeshPropertyDescriptor *props,
- CSG_FaceIteratorDescriptor *face_it,
- CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4]);
-
-static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
- Object *ob, CSG_MeshPropertyDescriptor *props,
- CSG_FaceIteratorDescriptor *face_it,
- CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4]);
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/**
* Here's the vertex iterator structure used to walk through
* the blender vertex structure.
*/
typedef struct {
- Object *ob;
Mesh *mesh;
+ Object *ob;
int pos;
} VertexIt;
@@ -102,11 +85,8 @@ typedef struct {
* These describe a blender mesh to the CSG module.
*/
-static
- void
-VertexIt_Destruct(
- CSG_VertexIteratorDescriptor * iterator
-){
+static void VertexIt_Destruct(CSG_VertexIteratorDescriptor * iterator)
+{
if (iterator->it) {
// deallocate memory for iterator
MEM_freeN(iterator->it);
@@ -120,27 +100,20 @@ VertexIt_Destruct(
}
-static
- int
-VertexIt_Done(
- CSG_IteratorPtr it
-){
+static int VertexIt_Done(CSG_IteratorPtr it)
+{
VertexIt * iterator = (VertexIt *)it;
return(iterator->pos >= iterator->mesh->totvert);
}
-
-static
- void
-VertexIt_Fill(
- CSG_IteratorPtr it,
- CSG_IVertex *vert
-){
+static void VertexIt_Fill(CSG_IteratorPtr it, CSG_IVertex *vert)
+{
VertexIt * iterator = (VertexIt *)it;
MVert *verts = iterator->mesh->mvert;
float global_pos[3];
+ /* boolean happens in global space, transform both with obmat */
VecMat4MulVecfl(
global_pos,
iterator->ob->obmat,
@@ -152,30 +125,20 @@ VertexIt_Fill(
vert->position[2] = global_pos[2];
}
-static
- void
-VertexIt_Step(
- CSG_IteratorPtr it
-){
+static void VertexIt_Step(CSG_IteratorPtr it)
+{
VertexIt * iterator = (VertexIt *)it;
iterator->pos ++;
}
-static
- void
-VertexIt_Reset(
- CSG_IteratorPtr it
-){
+static void VertexIt_Reset(CSG_IteratorPtr it)
+{
VertexIt * iterator = (VertexIt *)it;
iterator->pos = 0;
}
-static
- void
-VertexIt_Construct(
- CSG_VertexIteratorDescriptor * output,
- Object *ob
-){
+static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob)
+{
VertexIt *it;
if (output == 0) return;
@@ -205,17 +168,13 @@ VertexIt_Construct(
*/
typedef struct {
- Object *ob;
Mesh *mesh;
int pos;
+ int offset;
} FaceIt;
-
-static
- void
-FaceIt_Destruct(
- CSG_FaceIteratorDescriptor * iterator
-) {
+static void FaceIt_Destruct(CSG_FaceIteratorDescriptor * iterator)
+{
MEM_freeN(iterator->it);
iterator->Done = NULL;
iterator->Fill = NULL;
@@ -224,33 +183,20 @@ FaceIt_Destruct(
iterator->num_elements = 0;
}
-
-static
- int
-FaceIt_Done(
- CSG_IteratorPtr it
-) {
+static int FaceIt_Done(CSG_IteratorPtr it)
+{
// assume CSG_IteratorPtr is of the correct type.
FaceIt * iterator = (FaceIt *)it;
return(iterator->pos >= iterator->mesh->totface);
}
-static
- void
-FaceIt_Fill(
- CSG_IteratorPtr it,
- CSG_IFace *face
-){
+static void FaceIt_Fill(CSG_IteratorPtr it, CSG_IFace *face)
+{
// assume CSG_IteratorPtr is of the correct type.
- FaceIt * face_it = (FaceIt *)it;
- Object *ob = face_it->ob;
+ FaceIt *face_it = (FaceIt *)it;
MFace *mfaces = face_it->mesh->mface;
- TFace *tfaces = face_it->mesh->tface;
- int f_index = face_it->pos;
- MFace *mface = &mfaces[f_index];
- FaceData *fdata = face->user_face_data;
-
- // ignore lines (faces with mface->v3==0)
+ MFace *mface = &mfaces[face_it->pos];
+
face->vertex_index[0] = mface->v1;
face->vertex_index[1] = mface->v2;
face->vertex_index[2] = mface->v3;
@@ -261,59 +207,24 @@ FaceIt_Fill(
face->vertex_number = 3;
}
- fdata->faceflag = mface->flag;
- fdata->material = give_current_material(ob, mface->mat_nr+1);
-
- // pack rgba colors.
- if (tfaces) {
- TFace *tface= &tfaces[f_index];
- int i;
-
- fdata->tpage = tface->tpage;
- fdata->flag = tface->flag;
- fdata->transp = tface->transp;
- fdata->mode = tface->mode;
- fdata->tile = tface->tile;
-
- for (i=0; i<4; i++) {
- FaceVertexData *fvdata= face->user_face_vertex_data[i];
-
- fvdata->uv[0] = tface->uv[i][0];
- fvdata->uv[1] = tface->uv[i][1];
- fvdata->color[0] = (float) ((tface->col[i] >> 24) & 0xff);
- fvdata->color[1] = (float) ((tface->col[i] >> 16) & 0xff);
- fvdata->color[2] = (float) ((tface->col[i] >> 8) & 0xff);
- fvdata->color[3] = (float) ((tface->col[i] >> 0) & 0xff);
- }
- }
+ face->orig_face = face_it->offset + face_it->pos;
}
-
-static
- void
-FaceIt_Step(
- CSG_IteratorPtr it
-) {
+static void FaceIt_Step(CSG_IteratorPtr it)
+{
FaceIt * face_it = (FaceIt *)it;
face_it->pos ++;
}
-static
- void
-FaceIt_Reset(
- CSG_IteratorPtr it
-) {
+static void FaceIt_Reset(CSG_IteratorPtr it)
+{
FaceIt * face_it = (FaceIt *)it;
face_it->pos = 0;
}
-static
- void
-FaceIt_Construct(
- CSG_FaceIteratorDescriptor * output,
- Object * ob
-){
-
+static void FaceIt_Construct(
+ CSG_FaceIteratorDescriptor *output, Object *ob, int offset)
+{
FaceIt *it;
if (output == 0) return;
@@ -323,8 +234,8 @@ FaceIt_Construct(
return ;
}
// assign blender specific variables
- it->ob = ob;
it->mesh = ob->data;
+ it->offset = offset;
it->pos = 0;
// assign iterator function pointers.
@@ -336,1032 +247,346 @@ FaceIt_Construct(
output->it = it;
}
-
-/**
- * Interpolation functions for various user data types.
- */
-
- int
-InterpNoUserData(
- void *d1,
- void *d2,
- void *dnew,
- float epsilon
-) {
- // nothing to do of course.
- return 0;
-}
-
- int
-InterpFaceVertexData(
- void *d1,
- void *d2,
- void *dnew,
- float epsilon
-) {
- /* XXX, passed backwards, should be fixed inside
- * BSP lib I guess.
- */
- FaceVertexData *fv1 = d2;
- FaceVertexData *fv2 = d1;
- FaceVertexData *fvO = dnew;
-
- fvO->uv[0] = (fv2->uv[0] - fv1->uv[0]) * epsilon + fv1->uv[0];
- fvO->uv[1] = (fv2->uv[1] - fv1->uv[1]) * epsilon + fv1->uv[1];
- fvO->color[0] = (fv2->color[0] - fv1->color[0]) * epsilon + fv1->color[0];
- fvO->color[1] = (fv2->color[1] - fv1->color[1]) * epsilon + fv1->color[1];
- fvO->color[2] = (fv2->color[2] - fv1->color[2]) * epsilon + fv1->color[2];
- fvO->color[3] = (fv2->color[3] - fv1->color[3]) * epsilon + fv1->color[3];
-
- return 0;
-}
-
-/**
- * Assumes mesh is valid and forms part of a fresh
- * blender object.
- */
-DispListMesh *NewBooleanMeshDLM(Object *ob, Object *ob_select, int int_op_type)
+static Object *AddNewBlenderMesh(Base *base)
{
- Mesh *me2 = get_mesh(ob_select);
- Mesh *me = get_mesh(ob);
- int free_tface1,free_tface2;
- DispListMesh *dlm = NULL;
-
- float inv_mat[4][4];
- int success = 0;
- // build and fill new descriptors for these meshes
- CSG_VertexIteratorDescriptor vd_1;
- CSG_VertexIteratorDescriptor vd_2;
- CSG_FaceIteratorDescriptor fd_1;
- CSG_FaceIteratorDescriptor fd_2;
-
- CSG_MeshPropertyDescriptor mpd1,mpd2;
-
- // work out the operation they chose and pick the appropriate
- // enum from the csg module.
-
- CSG_OperationType op_type;
-
- if (me == NULL || me2 == NULL) return 0;
-
- if(!me->totface || !me2->totface) return 0;
-
- success = 0;
-
- switch (int_op_type) {
- case 1 : op_type = e_csg_intersection; break;
- case 2 : op_type = e_csg_union; break;
- case 3 : op_type = e_csg_difference; break;
- case 4 : op_type = e_csg_classify; break;
- default : op_type = e_csg_intersection;
- }
-
- // Here is the section where we describe the properties of
- // both meshes to the bsp module.
-
- if (me->mcol != NULL) {
- // Then this mesh has vertex colors only
- // well this is awkward because there is no equivalent
- // test_index_mface just for vertex colors!
- // as a temporary hack we can convert these vertex colors
- // into tfaces do the operation and turn them back again.
-
- // create some memory for the tfaces.
- me->tface = (TFace *)MEM_callocN(sizeof(TFace)*me->totface,"BooleanOps_TempTFace");
- mcol_to_tface(me,1);
- free_tface1 = 1;
- } else {
- free_tface1 = 0;
- }
-
- mpd1.user_face_vertex_data_size = 0;
- mpd1.user_data_size = sizeof(FaceData);
-
- if (me->tface) {
- mpd1.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
-
- // same for mesh2
-
- if (me2->mcol != NULL) {
- // create some memory for the tfaces.
- me2->tface = (TFace *)MEM_callocN(sizeof(TFace)*me2->totface,"BooleanOps_TempTFace");
- mcol_to_tface(me2,1);
- free_tface2 = 1;
- } else {
- free_tface2 = 0;
- }
+ // This little function adds a new mesh object to the blender object list
+ // It uses ob to duplicate data as this seems to be easier than creating
+ // a new one. This new oject contains no faces nor vertices.
+ Mesh *old_me;
+ Base *basen;
+ Object *ob_new;
- mpd2.user_face_vertex_data_size = 0;
- mpd2.user_data_size = sizeof(FaceData);
+ // now create a new blender object.
+ // duplicating all the settings from the previous object
+ // to the new one.
+ ob_new= copy_object(base->object);
- if (me2->tface) {
- mpd2.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
+ // Ok we don't want to use the actual data from the
+ // last object, the above function incremented the
+ // number of users, so decrement it here.
+ old_me= ob_new->data;
+ old_me->id.us--;
- // we map the final object back into object 1's (ob)
- // local coordinate space. For this we need to compute
- // the inverse transform from global to local.
+ // Now create a new base to add into the linked list of
+ // vase objects.
- Mat4Invert(inv_mat,ob_select->obmat);
-
- // make a boolean operation;
- {
- CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
- CSG_MeshPropertyDescriptor output_mpd = CSG_DescibeOperands(bool_op,mpd1,mpd2);
- // analyse the result and choose mesh descriptors accordingly
- int output_type;
- if (output_mpd.user_face_vertex_data_size) {
- output_type = 1;
- } else {
- output_type = 0;
- }
-
- BuildMeshDescriptors(
- ob,
- &fd_1,
- &vd_1
- );
- BuildMeshDescriptors(
- ob_select,
- &fd_2,
- &vd_2
- );
+ basen= MEM_mallocN(sizeof(Base), "duplibase");
+ *basen= *base;
+ BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */
+ basen->object= ob_new;
+ basen->flag &= ~SELECT;
+
+ // Initialize the mesh data associated with this object.
+ ob_new->data= add_mesh();
+ G.totmesh++;
- // perform the operation
+ // Finally assign the object type.
+ ob_new->type= OB_MESH;
- if (output_type == 0) {
-
- success =
- CSG_PerformBooleanOperation(
- bool_op,
- op_type,
- fd_1,vd_1,fd_2,vd_2,
- InterpNoUserData
- );
- } else {
- success =
- CSG_PerformBooleanOperation(
- bool_op,
- op_type,
- fd_1,vd_1,fd_2,vd_2,
- InterpFaceVertexData
- );
- }
+ return ob_new;
+}
- switch( success ) {
- case 1:
- {
- // descriptions of the output;
- CSG_VertexIteratorDescriptor vd_o;
- CSG_FaceIteratorDescriptor fd_o;
-
- dlm = MEM_callocN(sizeof(*dlm),"dlm");
+/* editmode function, will be replaced soon once custom face data arrives */
+void interp_uv_vcol(float *v1, float *v2, float *v3, float *v4, float *co,
+ TFace *tf, TFace *outtf, int j);
- CSG_OutputFaceDescriptor(bool_op,&fd_o);
- CSG_OutputVertexDescriptor(bool_op,&vd_o);
+static void ConvertCSGTFace(
+ DerivedMesh *dm, Mesh *orig_me, int index, int orig_index, int nr,
+ TFace *tface, TFace *orig_tface, float mapmat[][4])
+{
+ float obco[3], *co[4], *orig_co[4];
+ MFace *mface, *orig_mface;
+ int j;
- // iterate through results of operation and insert into new object
+ mface = CDDM_get_face(dm, index);
+ orig_mface = orig_me->mface + orig_index;
- ConvertCSGDescriptorsToDLM(
- dlm,
- NULL,
- &output_mpd,
- &fd_o,
- &vd_o,
- inv_mat
- );
+ *tface = *orig_tface;
- // free up the memory
+ // get the vertex coordinates from the original mesh
+ orig_co[0] = (orig_me->mvert + orig_mface->v1)->co;
+ orig_co[1] = (orig_me->mvert + orig_mface->v2)->co;
+ orig_co[2] = (orig_me->mvert + orig_mface->v3)->co;
+ orig_co[3] = (orig_mface->v4)? (orig_me->mvert + orig_mface->v4)->co: NULL;
- CSG_FreeVertexDescriptor(&vd_o);
- CSG_FreeFaceDescriptor(&fd_o);
- }
- break;
- case -1:
- error("Selected meshes must have faces to perform boolean operations");
- break;
- case -2:
- error("Both meshes must be closed");
- break;
- default:
- error("unknown internal error");
- break;
- }
+ // get the vertex coordinates from the new derivedmesh
+ co[0] = CDDM_get_vert(dm, mface->v1)->co;
+ co[1] = CDDM_get_vert(dm, mface->v2)->co;
+ co[2] = CDDM_get_vert(dm, mface->v3)->co;
+ co[3] = (nr == 4)? CDDM_get_vert(dm, mface->v4)->co: NULL;
- CSG_FreeBooleanOperation(bool_op);
- }
+ for (j = 0; j < nr; j++) {
+ // get coordinate into the space of the original mesh
+ if (mapmat)
+ VecMat4MulVecfl(obco, mapmat, co[j]);
+ else
+ VecCopyf(obco, co[j]);
- // We may need to map back the tfaces to mcols here.
- if (free_tface1) {
- tface_to_mcol(me);
- MEM_freeN(me->tface);
- me->tface = NULL;
+ interp_uv_vcol(orig_co[0], orig_co[1], orig_co[2], orig_co[3], obco,
+ orig_tface, tface, j);
}
- if (free_tface2) {
- tface_to_mcol(me2);
- MEM_freeN(me2->tface);
- me2->tface = NULL;
- }
-
- if (free_tface1 && free_tface2) {
- // then we need to map the output tfaces into mcols
- if (dlm) {
- dlm->mcol = tface_to_mcol_p(dlm->tface, dlm->totface);
- MEM_freeN(dlm->tface);
- dlm->tface = NULL;
- }
- }
-
- FreeMeshDescriptors(&fd_1,&vd_1);
- FreeMeshDescriptors(&fd_2,&vd_2);
-
- return dlm;
}
-DerivedMesh *NewBooleanDerivedMesh(struct Object *ob, struct Object *ob_select,
- int int_op_type)
+/* Iterate over the CSG Output Descriptors and create a new DerivedMesh
+ from them */
+static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
+ CSG_FaceIteratorDescriptor *face_it,
+ CSG_VertexIteratorDescriptor *vertex_it,
+ float parinv[][4],
+ float mapmat[][4],
+ Material **mat,
+ int *totmat,
+ Object *ob1,
+ Object *ob2)
{
- Mesh *me2 = get_mesh(ob_select);
- Mesh *me = get_mesh(ob);
- int free_tface1, free_tface2;
- DerivedMesh *result;
-
- float inv_mat[4][4];
- int success = 0;
- // build and fill new descriptors for these meshes
- CSG_VertexIteratorDescriptor vd_1;
- CSG_VertexIteratorDescriptor vd_2;
- CSG_FaceIteratorDescriptor fd_1;
- CSG_FaceIteratorDescriptor fd_2;
-
- CSG_MeshPropertyDescriptor mpd1, mpd2;
-
- // work out the operation they chose and pick the appropriate
- // enum from the csg module.
-
- CSG_OperationType op_type;
+ DerivedMesh *dm;
+ GHash *material_hash = NULL;
+ Mesh *me1= (Mesh*)ob1->data;
+ Mesh *me2= (Mesh*)ob2->data;
+ int i;
- if(me == NULL || me2 == NULL) return 0;
+ // create a new DerivedMesh
+ dm = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
- if(!me->totface || !me2->totface) return 0;
+ // add tface layers
+ if (me1->mcol)
+ mcol_to_tface(me1, 1);
+ if (me2->mcol)
+ mcol_to_tface(me2, 1);
- success = 0;
-
- switch(int_op_type) {
- case 1 : op_type = e_csg_intersection; break;
- case 2 : op_type = e_csg_union; break;
- case 3 : op_type = e_csg_difference; break;
- case 4 : op_type = e_csg_classify; break;
- default : op_type = e_csg_intersection;
- }
+ if (me1->tface || me2->tface)
+ DM_add_face_layer(dm, LAYERTYPE_TFACE, 0, NULL);
- // Here is the section where we describe the properties of
- // both meshes to the bsp module.
-
- if(me->mcol != NULL) {
- // Then this mesh has vertex colors only
- // well this is awkward because there is no equivalent
- // test_index_mface just for vertex colors!
- // as a temporary hack we can convert these vertex colors
- // into tfaces do the operation and turn them back again.
-
- // create some memory for the tfaces.
- me->tface = (TFace *)MEM_callocN(sizeof(TFace) * me->totface,
- "BooleanOps_TempTFace");
- mcol_to_tface(me, 1);
- free_tface1 = 1;
- } else {
- free_tface1 = 0;
- }
+ // step through the vertex iterators:
+ for (i = 0; !vertex_it->Done(vertex_it->it); i++) {
+ CSG_IVertex csgvert;
+ MVert *mvert = CDDM_get_vert(dm, i);
- mpd1.user_face_vertex_data_size = 0;
- mpd1.user_data_size = sizeof(FaceData);
+ // retrieve a csg vertex from the boolean module
+ vertex_it->Fill(vertex_it->it, &csgvert);
+ vertex_it->Step(vertex_it->it);
- if(me->tface) {
- mpd1.user_face_vertex_data_size = sizeof(FaceVertexData);
+ // we have to map the vertex coordinates back in the coordinate frame
+ // of the resulting object, since it was computed in world space
+ VecMat4MulVecfl(mvert->co, parinv, csgvert.position);
}
-
- // same for mesh2
- if(me2->mcol != NULL) {
- // create some memory for the tfaces.
- me2->tface = (TFace *)MEM_callocN(sizeof(TFace) * me2->totface,
- "BooleanOps_TempTFace");
- mcol_to_tface(me2, 1);
- free_tface2 = 1;
- } else {
- free_tface2 = 0;
+ // a hash table to remap materials to indices
+ if (mat) {
+ material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ *totmat = 0;
}
- mpd2.user_face_vertex_data_size = 0;
- mpd2.user_data_size = sizeof(FaceData);
-
- if(me2->tface) {
- mpd2.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
-
- // we map the final object back into object 1's (ob)
- // local coordinate space. For this we need to compute
- // the inverse transform from global to local.
-
- Mat4Invert(inv_mat, ob_select->obmat);
+ // step through the face iterators
+ for(i = 0; !face_it->Done(face_it->it); i++) {
+ Mesh *orig_me;
+ Object *orig_ob;
+ Material *orig_mat;
+ CSG_IFace csgface;
+ MFace *mface, *orig_mface;
+ TFace *tface, *orig_tface;
+ int orig_index, mat_nr;
- // make a boolean operation;
- {
- CSG_BooleanOperation *bool_op = CSG_NewBooleanFunction();
- CSG_MeshPropertyDescriptor output_mpd = CSG_DescibeOperands(bool_op,
- mpd1, mpd2);
- // analyse the result and choose mesh descriptors accordingly
- int output_type;
- if(output_mpd. user_face_vertex_data_size) {
- output_type = 1;
- } else {
- output_type = 0;
- }
-
- BuildMeshDescriptors(ob, &fd_1, &vd_1);
- BuildMeshDescriptors(ob_select, &fd_2, &vd_2);
-
- // perform the operation
+ // retrieve a csg face from the boolean module
+ face_it->Fill(face_it->it, &csgface);
+ face_it->Step(face_it->it);
- if(output_type == 0) {
- success = CSG_PerformBooleanOperation(bool_op, op_type,
- fd_1, vd_1, fd_2, vd_2,
- InterpNoUserData);
- } else {
- success = CSG_PerformBooleanOperation(bool_op, op_type,
- fd_1, vd_1, fd_2, vd_2,
- InterpFaceVertexData);
+ // find the original mesh and data
+ orig_me = (csgface.orig_face < me1->totface)? me1: me2;
+ orig_ob = (orig_me == me1)? ob1: ob2;
+ orig_index = (orig_me == me1)? csgface.orig_face: csgface.orig_face - me1->totface;
+ orig_mface = orig_me->mface + orig_index;
+ orig_mat= give_current_material(orig_ob, orig_mface->mat_nr+1);
+
+ // set mface
+ mface = CDDM_get_face(dm, i);
+ mface->v1 = csgface.vertex_index[0];
+ mface->v2 = csgface.vertex_index[1];
+ mface->v3 = csgface.vertex_index[2];
+ mface->v4 = (csgface.vertex_number == 4)? csgface.vertex_index[3]: 0;
+ mface->flag = orig_mface->flag;
+
+ // set material, based on lookup in hash table
+ if (mat && orig_mat) {
+ if (!BLI_ghash_haskey(material_hash, orig_mat)) {
+ mat[*totmat] = orig_mat;
+ mat_nr = mface->mat_nr = (*totmat)++;
+ BLI_ghash_insert(material_hash, orig_mat, (void*)mat_nr);
+ }
+ else
+ mface->mat_nr = (int)BLI_ghash_lookup(material_hash, orig_mat);
}
+ else
+ mface->mat_nr = 0;
- switch(success) {
- case 1:
- {
- // descriptions of the output;
- CSG_VertexIteratorDescriptor vd_o;
- CSG_FaceIteratorDescriptor fd_o;
-
- CSG_OutputFaceDescriptor(bool_op, &fd_o);
- CSG_OutputVertexDescriptor(bool_op, &vd_o);
-
- // iterate through results of operation and insert
- // into new object
-
- result = ConvertCSGDescriptorsToDerivedMesh(
- NULL, &output_mpd,
- &fd_o, &vd_o, inv_mat);
+ // set tface
+ if (me1->tface || me2->tface) {
+ tface = DM_get_face_data(dm, i, LAYERTYPE_TFACE);;
- // free up the memory
+ if (orig_me->tface) {
+ orig_tface = orig_me->tface + orig_index;
- CSG_FreeVertexDescriptor(&vd_o);
- CSG_FreeFaceDescriptor(&fd_o);
+ ConvertCSGTFace(dm, orig_me, i, orig_index,
+ csgface.vertex_number, tface, orig_tface,
+ (orig_me == me2)? mapmat: NULL);
}
- break;
- case -1:
- error("Selected meshes must have faces to perform "
- "boolean operations");
- break;
- case -2:
- error("Both meshes must be closed");
- break;
- default:
- error("unknown internal error");
- break;
+ else
+ default_tface(tface);
}
+ else
+ tface = NULL;
- CSG_FreeBooleanOperation(bool_op);
- }
-
- // We may need to map back the tfaces to mcols here.
- if(free_tface1) {
- tface_to_mcol(me);
- MEM_freeN(me->tface);
- me->tface = NULL;
+ test_index_face(mface, NULL, tface, csgface.vertex_number);
}
- if(free_tface2) {
- tface_to_mcol(me2);
- MEM_freeN(me2->tface);
- me2->tface = NULL;
- }
-
- if(free_tface1 && free_tface2) {
- // then we need to map the output tfaces into mcols
- if(result && DM_get_vert_data(result, 0, LAYERTYPE_TFACE)) {
- int i;
- int maxFaces = result->getNumFaces(result);
- if(!DM_get_vert_data(result, 0, LAYERTYPE_MCOL))
- DM_add_vert_layer(result, LAYERTYPE_MCOL, 0, NULL);
+ if (material_hash)
+ BLI_ghash_free(material_hash, NULL, NULL);
- for(i = 0; i < maxFaces; ++i) {
- MCol *mcol = DM_get_vert_data(result, i, LAYERTYPE_MCOL);
- TFace *tface = DM_get_vert_data(result, i, LAYERTYPE_TFACE);
-
- memcpy(mcol, tface->col, sizeof(*mcol) * 4);
- }
- }
- }
-
- FreeMeshDescriptors(&fd_1, &vd_1);
- FreeMeshDescriptors(&fd_2, &vd_2);
+ CDDM_calc_edges(dm);
+ CDDM_calc_normals(dm);
- return result;
+ return dm;
}
-
- int
-NewBooleanMesh(
- struct Base * base,
- struct Base * base_select,
- int int_op_type
-){
- Mesh *me2 = get_mesh(base_select->object);
- Mesh *me = get_mesh(base->object);
- Mesh *me_new = NULL;
- Object *ob, *ob_new = NULL;
- int free_tface1,free_tface2;
-
- float inv_mat[4][4];
- int success = 0;
- // build and fill new descriptors for these meshes
- CSG_VertexIteratorDescriptor vd_1;
- CSG_VertexIteratorDescriptor vd_2;
- CSG_FaceIteratorDescriptor fd_1;
- CSG_FaceIteratorDescriptor fd_2;
-
- CSG_MeshPropertyDescriptor mpd1,mpd2;
-
- // work out the operation they chose and pick the appropriate
- // enum from the csg module.
-
- CSG_OperationType op_type;
-
- if (me == NULL || me2 == NULL) return 0;
-
- if(!me->totface || !me2->totface) return -1;
- success = 0;
-
- switch (int_op_type) {
- case 1 : op_type = e_csg_intersection; break;
- case 2 : op_type = e_csg_union; break;
- case 3 : op_type = e_csg_difference; break;
- case 4 : op_type = e_csg_classify; break;
- default : op_type = e_csg_intersection;
- }
-
- // Here is the section where we describe the properties of
- // both meshes to the bsp module.
-
- if (me->mcol != NULL) {
- // Then this mesh has vertex colors only
- // well this is awkward because there is no equivalent
- // test_index_mface just for vertex colors!
- // as a temporary hack we can convert these vertex colors
- // into tfaces do the operation and turn them back again.
-
- // create some memory for the tfaces.
- me->tface = (TFace *)MEM_callocN(sizeof(TFace)*me->totface,"BooleanOps_TempTFace");
- mcol_to_tface(me,1);
- free_tface1 = 1;
- } else {
- free_tface1 = 0;
- }
-
- mpd1.user_face_vertex_data_size = 0;
- mpd1.user_data_size = sizeof(FaceData);
-
- if (me->tface) {
- mpd1.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
+static void BuildMeshDescriptors(
+ struct Object *ob,
+ int face_offset,
+ struct CSG_FaceIteratorDescriptor * face_it,
+ struct CSG_VertexIteratorDescriptor * vertex_it)
+{
+ VertexIt_Construct(vertex_it,ob);
+ FaceIt_Construct(face_it,ob,face_offset);
+}
- // same for mesh2
+static void FreeMeshDescriptors(
+ struct CSG_FaceIteratorDescriptor *face_it,
+ struct CSG_VertexIteratorDescriptor *vertex_it)
+{
+ VertexIt_Destruct(vertex_it);
+ FaceIt_Destruct(face_it);
+}
- if (me2->mcol != NULL) {
- // create some memory for the tfaces.
- me2->tface = (TFace *)MEM_callocN(sizeof(TFace)*me2->totface,"BooleanOps_TempTFace");
- mcol_to_tface(me2,1);
- free_tface2 = 1;
- } else {
- free_tface2 = 0;
- }
+DerivedMesh *NewBooleanDerivedMesh_intern(
+ struct Object *ob, struct Object *ob_select,
+ int int_op_type, Material **mat, int *totmat)
+{
- mpd2.user_face_vertex_data_size = 0;
- mpd2.user_data_size = sizeof(FaceData);
+ float inv_mat[4][4];
+ float map_mat[4][4];
- if (me2->tface) {
- mpd2.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
+ DerivedMesh *dm = NULL;
+ Mesh *me1 = get_mesh(ob);
+ Mesh *me2 = get_mesh(ob_select);
- ob = base->object;
+ if (me1 == NULL || me2 == NULL) return 0;
+ if (!me1->totface || !me2->totface) return 0;
- // we map the final object back into object 1's (ob)
- // local coordinate space. For this we need to compute
- // the inverse transform from global to local.
-
- Mat4Invert(inv_mat,ob->obmat);
+ // we map the final object back into ob's local coordinate space. For this
+ // we need to compute the inverse transform from global to ob (inv_mat),
+ // and the transform from ob to ob_select for use in interpolation (map_mat)
+ Mat4Invert(inv_mat, ob_select->obmat);
+ Mat4MulMat4(map_mat, ob->obmat, inv_mat);
+ Mat4Invert(inv_mat, ob->obmat);
- // make a boolean operation;
{
- CSG_BooleanOperation * bool_op = CSG_NewBooleanFunction();
- CSG_MeshPropertyDescriptor output_mpd = CSG_DescibeOperands(bool_op,mpd1,mpd2);
- // analyse the result and choose mesh descriptors accordingly
- int output_type;
- if (output_mpd.user_face_vertex_data_size) {
- output_type = 1;
- } else {
- output_type = 0;
+ // interface with the boolean module:
+ //
+ // the idea is, we pass the boolean module verts and faces using the
+ // provided descriptors. once the boolean operation is performed, we
+ // get back output descriptors, from which we then build a DerivedMesh
+
+ CSG_VertexIteratorDescriptor vd_1, vd_2;
+ CSG_FaceIteratorDescriptor fd_1, fd_2;
+ CSG_OperationType op_type;
+ CSG_BooleanOperation *bool_op;
+
+ // work out the operation they chose and pick the appropriate
+ // enum from the csg module.
+ switch (int_op_type) {
+ case 1 : op_type = e_csg_intersection; break;
+ case 2 : op_type = e_csg_union; break;
+ case 3 : op_type = e_csg_difference; break;
+ case 4 : op_type = e_csg_classify; break;
+ default : op_type = e_csg_intersection;
}
- BuildMeshDescriptors(
- base->object,
- &fd_1,
- &vd_1
- );
- BuildMeshDescriptors(
- base_select->object,
- &fd_2,
- &vd_2
- );
+ BuildMeshDescriptors(ob, 0, &fd_1, &vd_1);
+ BuildMeshDescriptors(ob_select, me1->totface, &fd_2, &vd_2);
- // perform the operation
+ bool_op = CSG_NewBooleanFunction();
- if (output_type == 0) {
-
- success =
- CSG_PerformBooleanOperation(
- bool_op,
- op_type,
- fd_1,vd_1,fd_2,vd_2,
- InterpNoUserData
- );
- } else {
- success =
- CSG_PerformBooleanOperation(
- bool_op,
- op_type,
- fd_1,vd_1,fd_2,vd_2,
- InterpFaceVertexData
- );
- }
-
- if (success==1) {
- // descriptions of the output;
+ // perform the operation
+ if (CSG_PerformBooleanOperation(bool_op, op_type, fd_1, vd_1, fd_2, vd_2)) {
CSG_VertexIteratorDescriptor vd_o;
CSG_FaceIteratorDescriptor fd_o;
- DispListMesh dlm;
-
- // need to make sure its zeroed
- memset (&dlm, 0, sizeof (dlm));
-
- // Create a new blender mesh object - using 'base' as
- // a template for the new object.
- ob_new= AddNewBlenderMesh(base);
-
- // get the output descriptors
-
- CSG_OutputFaceDescriptor(bool_op,&fd_o);
- CSG_OutputVertexDescriptor(bool_op,&vd_o);
-
- me_new = ob_new->data;
- // iterate through results of operation and insert into new object
- // see subsurf.c
-
- ConvertCSGDescriptorsToDLM(
- &dlm,
- ob_new,
- &output_mpd,
- &fd_o,
- &vd_o,
- inv_mat
- );
-
- if (dlm.nors) MEM_freeN(dlm.nors);
-
- me_new->mvert = dlm.mvert;
- me_new->medge = dlm.medge;
- me_new->mface = dlm.mface;
- me_new->tface = dlm.tface;
- me_new->mcol = dlm.mcol;
- me_new->totvert = dlm.totvert;
- me_new->totedge = dlm.totedge;
- me_new->totface = dlm.totface;
- // free up the memory
+ CSG_OutputFaceDescriptor(bool_op, &fd_o);
+ CSG_OutputVertexDescriptor(bool_op, &vd_o);
+
+ // iterate through results of operation and insert
+ // into new object
+ dm = ConvertCSGDescriptorsToDerivedMesh(
+ &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, ob, ob_select);
+ // free up the memory
CSG_FreeVertexDescriptor(&vd_o);
CSG_FreeFaceDescriptor(&fd_o);
}
+ else
+ error("Unknown internal error in boolean");
CSG_FreeBooleanOperation(bool_op);
- bool_op = NULL;
-
- }
-
- // We may need to map back the tfaces to mcols here.
- if (free_tface1) {
- tface_to_mcol(me);
- MEM_freeN(me->tface);
- me->tface = NULL;
- }
- if (free_tface2) {
- tface_to_mcol(me2);
- MEM_freeN(me2->tface);
- me2->tface = NULL;
- }
-
- if (free_tface1 && free_tface2) {
- // then we need to map the output tfaces into mcols
- if (me_new) {
- tface_to_mcol(me_new);
- MEM_freeN(me_new->tface);
- me_new->tface = NULL;
- }
- }
-
- FreeMeshDescriptors(&fd_1,&vd_1);
- FreeMeshDescriptors(&fd_2,&vd_2);
- if (ob_new) {
- DAG_object_flush_update(G.scene, ob_new, OB_RECALC_DATA);
+ FreeMeshDescriptors(&fd_1, &vd_1);
+ FreeMeshDescriptors(&fd_2, &vd_2);
}
- return success;
+ return dm;
}
-
- Object *
-AddNewBlenderMesh(
- Base *base
-){
- Mesh *old_me;
- Base *basen;
- Object *ob_new;
-
- // now create a new blender object.
- // duplicating all the settings from the previous object
- // to the new one.
- ob_new= copy_object(base->object);
-
- // Ok we don't want to use the actual data from the
- // last object, the above function incremented the
- // number of users, so decrement it here.
- old_me= ob_new->data;
- old_me->id.us--;
-
- // Now create a new base to add into the linked list of
- // vase objects.
-
- basen= MEM_mallocN(sizeof(Base), "duplibase");
- *basen= *base;
- BLI_addhead(&G.scene->base, basen); /* addhead: anders oneindige lus */
- basen->object= ob_new;
- basen->flag &= ~SELECT;
-
- // Initialize the mesh data associated with this object.
- ob_new->data= add_mesh();
- G.totmesh++;
-
- // Finally assign the object type.
- ob_new->type= OB_MESH;
-
- return ob_new;
-}
-
-/**
- *
- * External interface
- *
- * This function builds a blender mesh using the output information from
- * the CSG module. It declares all the necessary blender cruft and
- * fills in the vertex and face arrays.
- */
- static void
-ConvertCSGDescriptorsToDLM(
- DispListMesh *dlm,
- Object *ob,
- CSG_MeshPropertyDescriptor *props,
- CSG_FaceIteratorDescriptor *face_it,
- CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4]
-){
- FaceVertexData *user_face_vertex_data;
- GHash *material_hash;
- CSG_IVertex vert;
- CSG_IFace face;
- MVert *insert_pos;
- MFace *mfaces;
- TFace *tfaces;
- int fi_insert_pos, nmaterials;
-
- // create some memory for the Iface according to output mesh props.
-
- // initialize the face structure for readback
-
- face.user_face_data = MEM_callocN(sizeof(FaceData),"BooleanOp_IFaceData");
-
- if (props->user_face_vertex_data_size) {
- user_face_vertex_data = MEM_callocN(sizeof(FaceVertexData)*4,"BooleanOp_IFaceData");
- face.user_face_vertex_data[0] = &user_face_vertex_data[0];
- face.user_face_vertex_data[1] = &user_face_vertex_data[1];
- face.user_face_vertex_data[2] = &user_face_vertex_data[2];
- face.user_face_vertex_data[3] = &user_face_vertex_data[3];
- } else {
- user_face_vertex_data = NULL;
- }
-
- // create memory for the vertex array.
-
- dlm->mvert = MEM_callocN(sizeof(MVert) * vertex_it->num_elements,"BooleanOp_VertexArray");
- dlm->mface = MEM_callocN(sizeof(MFace) * face_it->num_elements,"BooleanOp_FaceArray");
-
- if (user_face_vertex_data) {
- dlm->tface = MEM_callocN(sizeof(TFace) * face_it->num_elements,"BooleanOp_TFaceArray");
- } else {
- dlm->tface = NULL;
- }
-
- insert_pos = dlm->mvert;
- mfaces = dlm->mface;
- tfaces = dlm->tface;
-
- fi_insert_pos = 0;
-
- // step through the iterators.
-
- while (!vertex_it->Done(vertex_it->it)) {
- vertex_it->Fill(vertex_it->it,&vert);
-
- // map output vertex into insert_pos
- // and transform at by parinv at the same time.
-
- VecMat4MulVecfl(
- insert_pos->co,
- parinv,
- vert.position
- );
- insert_pos ++;
- vertex_it->Step(vertex_it->it);
- }
-
- dlm->totvert = vertex_it->num_elements;
-
- // a hash table to remap materials to indices with
- material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- nmaterials = 0;
-
- while (!face_it->Done(face_it->it)) {
- MFace *mface = &mfaces[fi_insert_pos];
- FaceData *fdata;
-
- face_it->Fill(face_it->it,&face);
- fdata = face.user_face_data;
-
- // cheat CSG never dumps out quads.
-
- if (face.vertex_number>3) {
- // QUAD
- mface->v1 = face.vertex_index[0];
- mface->v2 = face.vertex_index[1];
- mface->v3 = face.vertex_index[2];
- mface->v4 = face.vertex_index[3];
- }
- else {
- // TRIANGLE
- mface->v1 = face.vertex_index[0];
- mface->v2 = face.vertex_index[1];
- mface->v3 = face.vertex_index[2];
- mface->v4 = 0;
- }
-
- mface->mat_nr = 0;
- mface->flag = fdata->faceflag;
-
- /* HACK, perform material to index mapping using a general
- * hash table, just tuck the int into a void *.
- */
-
- if (ob && !BLI_ghash_haskey(material_hash, fdata->material)) {
- int matnr = nmaterials++;
- BLI_ghash_insert(material_hash, fdata->material, (void*) matnr);
- assign_material(ob, fdata->material, matnr+1);
- }
- mface->mat_nr = (int) BLI_ghash_lookup(material_hash, fdata->material);
-
- // grab the vertex colors and texture cos and dump them into the tface.
-
- if (tfaces) {
- TFace *tface= &tfaces[fi_insert_pos];
- int i;
-
- // copy all the tface settings back
- tface->tpage = fdata->tpage;
- tface->flag = fdata->flag;
- tface->transp = fdata->transp;
- tface->mode = fdata->mode;
- tface->tile = fdata->tile;
-
- for (i=0; i<4; i++) {
- FaceVertexData *fvdata = face.user_face_vertex_data[i];
- float *color = fvdata->color;
-
- tface->uv[i][0] = fvdata->uv[0];
- tface->uv[i][1] = fvdata->uv[1];
- tface->col[i] =
- ((((unsigned int)floor(color[0] + 0.5f)) & 0xff) << 24) |
- ((((unsigned int)floor(color[1] + 0.5f)) & 0xff) << 16) |
- ((((unsigned int)floor(color[2] + 0.5f)) & 0xff) << 8) |
- ((((unsigned int)floor(color[3] + 0.5f)) & 0xff) << 0);
- }
-
- test_index_face(mface, NULL, tface, face.vertex_number);
- } else {
- test_index_face(mface, NULL, NULL, face.vertex_number);
- }
-
- fi_insert_pos++;
- face_it->Step(face_it->it);
- }
-
- BLI_ghash_free(material_hash, NULL, NULL);
-
- dlm->totface = face_it->num_elements;
-
- displistmesh_add_edges(dlm);
-
- mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
-
- // thats it!
- if (user_face_vertex_data) {
- MEM_freeN(user_face_vertex_data);
- }
- MEM_freeN(face.user_face_data);
-}
-
-static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
- Object *ob, CSG_MeshPropertyDescriptor *props,
- CSG_FaceIteratorDescriptor *face_it,
- CSG_VertexIteratorDescriptor *vertex_it,
- float parinv[][4])
+int NewBooleanMesh(Base *base, Base *base_select, int int_op_type)
{
- FaceVertexData *user_face_vertex_data;
- GHash *material_hash;
- CSG_IVertex vert;
- CSG_IFace face;
- DerivedMesh *result;
- int i;
-#if 0
- MFace *mfaces;
- TFace *tfaces;
-#endif
- int fi_insert_pos, nmaterials;
+ Mesh *me_new;
+ int a, maxmat, totmat= 0;
+ Object *ob_new, *ob, *ob_select;
+ Material **mat;
+ DerivedMesh *dm;
- // create some memory for the Iface according to output mesh props.
+ ob= base->object;
+ ob_select= base_select->object;
- // initialize the face structure for readback
-
- face.user_face_data = MEM_callocN(sizeof(FaceData),"BooleanOp_IFaceData");
+ maxmat= ob->totcol + ob_select->totcol;
+ mat= (Material**)MEM_mallocN(sizeof(Material*)*maxmat, "NewBooleanMeshMat");
- if(props->user_face_vertex_data_size) {
- user_face_vertex_data = MEM_callocN(sizeof(FaceVertexData) * 4,
- "BooleanOp_IFaceData");
- face.user_face_vertex_data[0] = &user_face_vertex_data[0];
- face.user_face_vertex_data[1] = &user_face_vertex_data[1];
- face.user_face_vertex_data[2] = &user_face_vertex_data[2];
- face.user_face_vertex_data[3] = &user_face_vertex_data[3];
- } else {
- user_face_vertex_data = NULL;
- }
-
- // create memory for the vertex array.
-
- result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
-
- if(user_face_vertex_data)
- DM_add_face_layer(result, LAYERTYPE_TFACE, 0, NULL);
-
- // step through the iterators.
+ dm= NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, mat, &totmat);
- i = 0;
- while(!vertex_it->Done(vertex_it->it)) {
- MVert *insert_pos = CDDM_get_vert(result, i);
- vertex_it->Fill(vertex_it->it, &vert);
-
- // map output vertex into insert_pos
- // and transform at by parinv at the same time.
-
- VecMat4MulVecfl(insert_pos->co, parinv, vert.position);
-
- vertex_it->Step(vertex_it->it);
- i++;
+ if (dm == NULL) {
+ MEM_freeN(mat);
+ return 0;
}
- // a hash table to remap materials to indices with
- material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- nmaterials = 0;
+ /* create a new blender mesh object - using 'base' as a template */
+ ob_new= AddNewBlenderMesh(base);
+ me_new= ob_new->data;
- fi_insert_pos = 0;
- while(!face_it->Done(face_it->it)) {
- MFace *mface = CDDM_get_face(result, fi_insert_pos);
- FaceData *fdata;
-
- face_it->Fill(face_it->it, &face);
- fdata = face.user_face_data;
-
- // cheat CSG never dumps out quads.
-
- if(face.vertex_number>3) {
- // QUAD
- mface->v1 = face.vertex_index[0];
- mface->v2 = face.vertex_index[1];
- mface->v3 = face.vertex_index[2];
- mface->v4 = face.vertex_index[3];
- } else {
- // TRIANGLE
- mface->v1 = face.vertex_index[0];
- mface->v2 = face.vertex_index[1];
- mface->v3 = face.vertex_index[2];
- mface->v4 = 0;
- }
+ DM_to_mesh(dm, me_new);
+ dm->release(dm);
- mface->mat_nr = 0;
- mface->flag = fdata->faceflag;
-
- /* HACK, perform material to index mapping using a general
- * hash table, just tuck the int into a void *.
- */
-
- if(ob && !BLI_ghash_haskey(material_hash, fdata->material)) {
- int matnr = nmaterials++;
- BLI_ghash_insert(material_hash, fdata->material, (void*)matnr);
- assign_material(ob, fdata->material, matnr + 1);
- }
- mface->mat_nr = (int)BLI_ghash_lookup(material_hash, fdata->material);
-
- // grab the vertex colors and texture cos and dump them into the tface.
-
- if(user_face_vertex_data) {
- TFace *tface = DM_get_face_data(result, fi_insert_pos,
- LAYERTYPE_TFACE);
-
- // copy all the tface settings back
- tface->tpage = fdata->tpage;
- tface->flag = fdata->flag;
- tface->transp = fdata->transp;
- tface->mode = fdata->mode;
- tface->tile = fdata->tile;
-
- for(i = 0; i < 4; i++) {
- FaceVertexData *fvdata = face.user_face_vertex_data[i];
- float *color = fvdata->color;
-
- tface->uv[i][0] = fvdata->uv[0];
- tface->uv[i][1] = fvdata->uv[1];
- tface->col[i] =
- ((((unsigned int)floor(color[0] + 0.5f)) & 0xff) << 24)
- | ((((unsigned int)floor(color[1] + 0.5f)) & 0xff) << 16)
- | ((((unsigned int)floor(color[2] + 0.5f)) & 0xff) << 8)
- | ((((unsigned int)floor(color[3] + 0.5f)) & 0xff) << 0);
- }
+ /* add materials to object */
+ for (a = 0; a < totmat; a++)
+ assign_material(ob_new, mat[a], a+1);
- test_index_face(mface, NULL, tface, face.vertex_number);
- } else {
- test_index_face(mface, NULL, NULL, face.vertex_number);
- }
-
- fi_insert_pos++;
- face_it->Step(face_it->it);
- }
-
- BLI_ghash_free(material_hash, NULL, NULL);
+ MEM_freeN(mat);
- CDDM_calc_edges(result);
+ /* update dag */
+ DAG_object_flush_update(G.scene, ob_new, OB_RECALC_DATA);
- CDDM_calc_normals(result);
-
- // thats it!
- if(user_face_vertex_data) MEM_freeN(user_face_vertex_data);
- MEM_freeN(face.user_face_data);
-
- return result;
-}
-
- void
-BuildMeshDescriptors(
- struct Object *ob,
- struct CSG_FaceIteratorDescriptor * face_it,
- struct CSG_VertexIteratorDescriptor * vertex_it
-){
- VertexIt_Construct(vertex_it,ob);
- FaceIt_Construct(face_it,ob);
+ return 1;
}
-
- void
-FreeMeshDescriptors(
- struct CSG_FaceIteratorDescriptor *face_it,
- struct CSG_VertexIteratorDescriptor *vertex_it
-){
- VertexIt_Destruct(vertex_it);
- FaceIt_Destruct(face_it);
+
+DerivedMesh *NewBooleanDerivedMesh(struct Object *ob, struct Object *ob_select,
+ int int_op_type)
+{
+ return NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, NULL, NULL);
}
diff --git a/source/blender/src/booleanops_mesh.c b/source/blender/src/booleanops_mesh.c
index 1323bbcb17f..d0b40b6eb7e 100644
--- a/source/blender/src/booleanops_mesh.c
+++ b/source/blender/src/booleanops_mesh.c
@@ -99,10 +99,6 @@ MakeCSGMeshFromBlenderBase(
output->m_descriptor.user_face_vertex_data_size = 0;
output->m_descriptor.user_data_size = sizeof(FaceData);
- if (me->tface) {
- output->m_descriptor.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
-
output->base = base;
BuildMeshDescriptors(
@@ -130,10 +126,6 @@ CSG_LoadBlenderMesh(
output->m_descriptor.user_face_vertex_data_size = 0;
output->m_descriptor.user_data_size = sizeof(FaceData);
- if (me->tface) {
- output->m_descriptor.user_face_vertex_data_size = sizeof(FaceVertexData);
- }
-
output->base = NULL;
BuildMeshDescriptors(
diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c
index 86041a22370..8a9b5dc9a31 100644
--- a/source/blender/src/editmesh_tools.c
+++ b/source/blender/src/editmesh_tools.c
@@ -1386,161 +1386,50 @@ static void flipvertarray(EditVert** arr, short size)
}
}
-static int VecEqual(float *a, float *b)
-{
- if( a[0] == b[0] &&
- (a[1] == b[1] &&
- a[2] == b[2])) {
- return 1;
- }
- else {
- return 0;
+void interp_uv_vcol(float *v1, float *v2, float *v3, float *v4, float *co, TFace *tf, TFace *outtf, int j)
+{
+ char *cp0, *cp1, *cp2, *cp3, *col;
+ float *uv, w[4];
+ int i, fac;
+
+ col = (char*)&outtf->col[j];
+ uv = (float*)outtf->uv[j];
+
+ InterpWeightsQ3Dfl(v1, v2, v3, v4, co, w);
+
+ uv[0]= w[0]*tf->uv[0][0] + w[1]*tf->uv[1][0] + w[2]*tf->uv[2][0];
+ uv[1]= w[0]*tf->uv[0][1] + w[1]*tf->uv[1][1] + w[2]*tf->uv[2][1];
+
+ if (v4) {
+ uv[0] += w[3]*tf->uv[3][0];
+ uv[1] += w[3]*tf->uv[3][1];
}
-}
-static void set_uv_vcol(EditFace *efa, float *co, float *uv, char *col)
-{
- EditVert *v1,*v2,*v3,*v4;
- float xn, yn, zn;
- float t00, t01, t10, t11;
- float detsh, u, v, l;
- int fac;
- short i, j;
- char *cp0, *cp1, *cp2;
- char *hold;
-
- //First Check for exact match between co and efa verts
- if(VecEqual(co,efa->v1->co)) {
- uv[0] = efa->tf.uv[0][0];
- uv[1] = efa->tf.uv[0][1];
-
- hold = (char*)&efa->tf.col[0];
- col[0]= hold[0];
- col[1]= hold[1];
- col[2]= hold[2];
- col[3]= hold[3];
- return;
- } else if(VecEqual(co,efa->v2->co)) {
- uv[0] = efa->tf.uv[1][0];
- uv[1] = efa->tf.uv[1][1];
-
- hold = (char*)&efa->tf.col[1];
- col[0]= hold[0];
- col[1]= hold[1];
- col[2]= hold[2];
- col[3]= hold[3];
- return;
- } else if(VecEqual(co,efa->v3->co)) {
- uv[0] = efa->tf.uv[2][0];
- uv[1] = efa->tf.uv[2][1];
-
- hold = (char*)&efa->tf.col[2];
- col[0]= hold[0];
- col[1]= hold[1];
- col[2]= hold[2];
- col[3]= hold[3];
- return;
- } else if(efa->v4 && VecEqual(co,efa->v4->co)) {
- uv[0] = efa->tf.uv[3][0];
- uv[1] = efa->tf.uv[3][1];
-
- hold = (char*)&efa->tf.col[3];
- col[0]= hold[0];
- col[1]= hold[1];
- col[2]= hold[2];
- col[3]= hold[3];
- return;
- }
-
- /* define best projection of face XY, XZ or YZ */
- xn= fabs(efa->n[0]);
- yn= fabs(efa->n[1]);
- zn= fabs(efa->n[2]);
- if(zn>=xn && zn>=yn) {i= 0; j= 1;}
- else if(yn>=xn && yn>=zn) {i= 0; j= 2;}
- else {i= 1; j= 2;}
-
- /* calculate u and v */
- v1= efa->v1;
- v2= efa->v2;
- v3= efa->v3;
-
- t00= v3->co[i]-v1->co[i]; t01= v3->co[j]-v1->co[j];
- t10= v3->co[i]-v2->co[i]; t11= v3->co[j]-v2->co[j];
-
- detsh= 1.0/(t00*t11-t10*t01); /* potential danger */
- t00*= detsh; t01*=detsh;
- t10*=detsh; t11*=detsh;
-
- u= (co[i]-v3->co[i])*t11-(co[j]-v3->co[j])*t10;
- v= (co[j]-v3->co[j])*t00-(co[i]-v3->co[i])*t01;
-
- /* btw; u and v range from -1 to 0 */
-
- /* interpolate */
- l= 1.0+u+v;
- /* outside triangle? */
- /* printf("l: %f u %f v %f\n",l,u,v); */
-
- if(efa->v4 && (v>0.001f)) { /* only check for positive v is OK, that's the diagonal */
- /* printf("outside\n"); */
- /* do it all over, but now with vertex 2 replaced with 4 */
-
- /* calculate u and v */
- v1= efa->v1;
- v4= efa->v4;
- v3= efa->v3;
-
- t00= v3->co[i]-v1->co[i]; t01= v3->co[j]-v1->co[j];
- t10= v3->co[i]-v4->co[i]; t11= v3->co[j]-v4->co[j];
-
- detsh= 1.0/(t00*t11-t10*t01); /* potential danger */
- t00*= detsh; t01*=detsh;
- t10*=detsh; t11*=detsh;
-
- u= (co[i]-v3->co[i])*t11-(co[j]-v3->co[j])*t10;
- v= (co[j]-v3->co[j])*t00-(co[i]-v3->co[i])*t01;
-
- /* btw; u and v range from -1 to 0 */
-
- /* interpolate */
- l= 1.0+u+v;
- uv[0] = (l*efa->tf.uv[2][0] - u*efa->tf.uv[0][0] - v*efa->tf.uv[3][0]);
- uv[1] = (l*efa->tf.uv[2][1] - u*efa->tf.uv[0][1] - v*efa->tf.uv[3][1]);
-
- cp0= (char*)&(efa->tf.col[0]);
- cp1= (char*)&(efa->tf.col[3]);
- cp2= (char*)&(efa->tf.col[2]);
-
- for(i=0; i<4; i++) {
- fac= (int)(l*cp2[i] - u*cp0[i] - v*cp1[i]);
- col[i]= CLAMPIS(fac, 0, 255);
- }
- } else {
- // printf("inside\n");
- //new = l*vertex3_val - u*vertex1_val - v*vertex2_val;
- uv[0] = (l*efa->tf.uv[2][0] - u*efa->tf.uv[0][0] - v*efa->tf.uv[1][0]);
- uv[1] = (l*efa->tf.uv[2][1] - u*efa->tf.uv[0][1] - v*efa->tf.uv[1][1]);
-
- cp0= (char*)&(efa->tf.col[0]);
- cp1= (char*)&(efa->tf.col[1]);
- cp2= (char*)&(efa->tf.col[2]);
-
- for(i=0; i<4; i++) {
- fac= (int)(l*cp2[i] - u*cp0[i] - v*cp1[i]);
- col[i]= CLAMPIS(fac, 0, 255);
- }
+ cp0= (char*)&(tf->col[0]);
+ cp1= (char*)&(tf->col[1]);
+ cp2= (char*)&(tf->col[2]);
+ cp3= (char*)&(tf->col[3]);
+
+ for(i=0; i < 4; i++) {
+ if (v4)
+ fac= (int)(w[0]*cp0[i] + w[1]*cp1[i] + w[2]*cp2[i] + w[3]*cp3[i]);
+ else
+ fac= (int)(w[0]*cp0[i] + w[1]*cp1[i] + w[2]*cp2[i]);
+
+ col[i]= CLAMPIS(fac, 0, 255);
}
}
-static void facecopy(EditFace *source,EditFace *target)
+static void facecopy(EditFace *source, EditFace *target)
{
+ float *v1 = source->v1->co, *v2 = source->v2->co, *v3 = source->v3->co;
+ float *v4 = source->v4? source->v4->co: NULL;
- set_uv_vcol(source,target->v1->co,target->tf.uv[0],(char*)&target->tf.col[0]);
- set_uv_vcol(source,target->v2->co,target->tf.uv[1],(char*)&target->tf.col[1]);
- set_uv_vcol(source,target->v3->co,target->tf.uv[2],(char*)&target->tf.col[2]);
- if(target->v4)
- set_uv_vcol(source,target->v4->co,target->tf.uv[3],(char*)&target->tf.col[3]);
+ interp_uv_vcol(v1, v2, v3, v4, target->v1->co, &source->tf, &target->tf, 0);
+ interp_uv_vcol(v1, v2, v3, v4, target->v2->co, &source->tf, &target->tf, 1);
+ interp_uv_vcol(v1, v2, v3, v4, target->v3->co, &source->tf, &target->tf, 2);
+ if (target->v4)
+ interp_uv_vcol(v1, v2, v3, v4, target->v4->co, &source->tf, &target->tf, 3);
target->mat_nr = source->mat_nr;
target->tf.flag = source->tf.flag&~TF_ACTIVE;
@@ -5253,7 +5142,7 @@ void bevel_menu()
glDrawBuffer(GL_BACK);
}
while(qtest()) {
- unsigned short val=0;
+ short val=0;
event= extern_qread(&val); // extern_qread stores important events for the mainloop to handle
/* val==0 on key-release event */
@@ -5767,7 +5656,7 @@ int EdgeSlide(short immediate, float imperc)
}
if(!immediate) {
while(qtest()) {
- unsigned short val=0;
+ short val=0;
event= extern_qread(&val); // extern_qread stores important events for the mainloop to handle
/* val==0 on key-release event */
@@ -6232,7 +6121,7 @@ void shape_copy_from_lerp(KeyBlock* thisBlock, KeyBlock* fromBlock)
}
while(qtest()) {
- unsigned short val=0;
+ short val=0;
event= extern_qread(&val);
if(val){
if(ELEM3(event, PADENTER, LEFTMOUSE, RETKEY)){
@@ -7235,4 +7124,4 @@ void loop_to_region(void)
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
BIF_undo_push("Edge Loop to Face Region");
-} \ No newline at end of file
+}