diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-02-15 16:08:06 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-02-15 16:08:06 +0400 |
commit | 428f031237b8ad10a7d85110857167c1d3f57415 (patch) | |
tree | c3ebda9dd4ab5d01fe60301efd630c613819efb2 /intern | |
parent | 77223492fd63f061b145b29bde5790fa1dd58c46 (diff) | |
parent | 3ac1ad5378cbf64f823e53cff393351764e042a8 (diff) |
svn merge ^/trunk/blender -r44076:44118
Diffstat (limited to 'intern')
-rw-r--r-- | intern/audaspace/intern/AUD_SequencerReader.cpp | 2 | ||||
-rw-r--r-- | intern/boolop/CMakeLists.txt | 2 | ||||
-rw-r--r-- | intern/boolop/intern/BOP_CarveInterface.cpp | 141 |
3 files changed, 119 insertions, 26 deletions
diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp index 44df66ccc3a..7c8fe9eef4e 100644 --- a/intern/audaspace/intern/AUD_SequencerReader.cpp +++ b/intern/audaspace/intern/AUD_SequencerReader.cpp @@ -176,6 +176,8 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer) } m_factory->m_volume.read(frame, &volume); + if(m_factory->m_muted) + volume = 0.0f; m_device.setVolume(volume); m_factory->m_orientation.read(frame, q.get()); diff --git a/intern/boolop/CMakeLists.txt b/intern/boolop/CMakeLists.txt index d0870c8da9c..d8e9c0c94d7 100644 --- a/intern/boolop/CMakeLists.txt +++ b/intern/boolop/CMakeLists.txt @@ -23,6 +23,8 @@ # # ***** END GPL LICENSE BLOCK ***** +remove_strict_flags() + set(INC . extern diff --git a/intern/boolop/intern/BOP_CarveInterface.cpp b/intern/boolop/intern/BOP_CarveInterface.cpp index d94c7573a9d..6fc08e52ade 100644 --- a/intern/boolop/intern/BOP_CarveInterface.cpp +++ b/intern/boolop/intern/BOP_CarveInterface.cpp @@ -46,24 +46,31 @@ typedef unsigned int uint; #define MAX(x,y) ((x)>(y)?(x):(y)) #define MIN(x,y) ((x)<(y)?(x):(y)) -static int isFacePlanar(CSG_IFace &face, std::vector<carve::geom3d::Vector> &vertices) +static bool isQuadPlanar(carve::geom3d::Vector &v1, carve::geom3d::Vector &v2, + carve::geom3d::Vector &v3, carve::geom3d::Vector &v4) { - carve::geom3d::Vector v1, v2, v3, cross; + carve::geom3d::Vector vec1, vec2, vec3, cross; - if (face.vertex_number == 4) { - v1 = vertices[face.vertex_index[1]] - vertices[face.vertex_index[0]]; - v2 = vertices[face.vertex_index[3]] - vertices[face.vertex_index[0]]; - v3 = vertices[face.vertex_index[2]] - vertices[face.vertex_index[0]]; + vec1 = v2 - v1; + vec2 = v4 - v1; + vec3 = v3 - v1; + + cross = carve::geom::cross(vec1, vec2); - cross = carve::geom::cross(v1, v2); + float production = carve::geom::dot(cross, vec3); + float magnitude = 1e-6 * cross.length(); - float production = carve::geom::dot(cross, v3); - float magnitude = 1e-6 * cross.length(); + return fabs(production) < magnitude; +} - return fabs(production) < magnitude; +static bool isFacePlanar(CSG_IFace &face, std::vector<carve::geom3d::Vector> &vertices) +{ + if (face.vertex_number == 4) { + return isQuadPlanar(vertices[face.vertex_index[0]], vertices[face.vertex_index[1]], + vertices[face.vertex_index[2]], vertices[face.vertex_index[3]]); } - return 1; + return true; } static void Carve_copyMeshes(std::vector<MeshSet<3>::mesh_t*> &meshes, std::vector<MeshSet<3>::mesh_t*> &new_meshes) @@ -200,30 +207,35 @@ static void Carve_getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> & while(it != meshes.end()) { MeshSet<3>::mesh_t *mesh = *it; - bool isIntersect = false; + bool isAdded = false; RTreeNode<3, Face<3> *> *rtree = RTreeNode<3, Face<3> *>::construct_STR(mesh->faces.begin(), mesh->faces.end(), 4, 4); - std::vector<MeshSet<3>::mesh_t*>::iterator operand_it = operandMeshes.begin(); - std::vector<RTreeNode<3, Face<3> *> *>::iterator tree_it = meshRTree.begin(); - for(; operand_it!=operandMeshes.end(); operand_it++, tree_it++) { - RTreeNode<3, Face<3> *> *operandRTree = *tree_it; + if (rtree->bbox.intersects(otherAABB)) { + bool isIntersect = false; + + std::vector<MeshSet<3>::mesh_t*>::iterator operand_it = operandMeshes.begin(); + std::vector<RTreeNode<3, Face<3> *> *>::iterator tree_it = meshRTree.begin(); + for(; operand_it!=operandMeshes.end(); operand_it++, tree_it++) { + RTreeNode<3, Face<3> *> *operandRTree = *tree_it; - if(operandRTree->bbox.intersects(otherAABB)) { if(Carve_checkMeshSetInterseciton(rtree, operandRTree)) { isIntersect = true; break; } } - } - if(!isIntersect) { - operandMeshes.push_back(mesh); - meshRTree.push_back(rtree); + if(!isIntersect) { + operandMeshes.push_back(mesh); + meshRTree.push_back(rtree); - it = meshes.erase(it); + it = meshes.erase(it); + isAdded = true; + } } - else { + + if (!isAdded) { + delete rtree; it++; } } @@ -239,6 +251,9 @@ static MeshSet<3> *Carve_getIntersectedOperand(std::vector<MeshSet<3>::mesh_t*> std::vector<MeshSet<3>::mesh_t*> operandMeshes; Carve_getIntersectedOperandMeshes(meshes, otherAABB, operandMeshes); + if (operandMeshes.size() == 0) + return NULL; + return Carve_meshSetFromMeshes(operandMeshes); } @@ -259,9 +274,19 @@ static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly, MeshSet<3> *left = Carve_getIntersectedOperand(orig_meshes, otherAABB); + if (!left) { + /* no maniforlds which intersects another object at all */ + return poly; + } + while(orig_meshes.size()) { MeshSet<3> *right = Carve_getIntersectedOperand(orig_meshes, otherAABB); + if (!right) { + /* no more intersecting manifolds which intersects other object */ + break; + } + try { if(left->meshes.size()==0) { delete left; @@ -295,6 +320,15 @@ static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly, } } + /* append all meshes which doesn't have intersection with another operand as-is */ + if (orig_meshes.size()) { + MeshSet<3> *result = Carve_meshSetFromTwoMeshes(left->meshes, orig_meshes); + + delete left; + + return result; + } + return left; } @@ -396,8 +430,63 @@ static MeshSet<3> *Carve_addMesh(CSG_FaceIteratorDescriptor &face_it, return poly; } +static bool checkValidQuad(std::vector<MeshSet<3>::vertex_t> &vertex_storage, uint quad[4]) +{ + carve::geom3d::Vector &v1 = vertex_storage[quad[0]].v; + carve::geom3d::Vector &v2 = vertex_storage[quad[1]].v; + carve::geom3d::Vector &v3 = vertex_storage[quad[2]].v; + carve::geom3d::Vector &v4 = vertex_storage[quad[3]].v; + +#if 0 + /* disabled for now to prevent initially non-planar be triangulated + * in theory this might cause some artifacts if intersections happens by non-planar + * non-concave quad, but in practice it's acceptable */ + if (!isQuadPlanar(v1, v2, v3, v4)) { + /* non-planar faces better not be merged because of possible differences in triangulation + * of non-planar faces in opengl and renderer */ + return false; + } +#endif + + carve::geom3d::Vector edges[4]; + carve::geom3d::Vector normal; + bool normal_set = false; + + edges[0] = v2 - v1; + edges[1] = v3 - v2; + edges[2] = v4 - v3; + edges[3] = v1 - v4; + + for (int i = 0; i < 4; i++) { + int n = i + 1; + + if (n == 4) + n = 0; + + carve::geom3d::Vector current_normal = carve::geom::cross(edges[i], edges[n]); + + if (current_normal.length() > 1e-6) { + if (!normal_set) { + normal = current_normal; + normal_set = true; + } + else if (carve::geom::dot(normal, current_normal) < -1e-6) { + return false; + } + } + } + + if (!normal_set) { + /* normal wasn't set means face is degraded and better merge it in such way */ + return false; + } + + return true; +} + // check whether two faces share an edge, and if so merge them static uint quadMerge(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map, + std::vector<MeshSet<3>::vertex_t> &vertex_storage, MeshSet<3>::face_t *f1, MeshSet<3>::face_t *f2, uint v, uint quad[4]) { @@ -432,7 +521,7 @@ static uint quadMerge(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map, quad[2] = v1[p1]; quad[3] = v2[p2]; - return 1; + return checkValidQuad(vertex_storage, quad); } else if (v1[n1] == v2[p2]) { quad[0] = v1[current]; @@ -440,7 +529,7 @@ static uint quadMerge(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map, quad[2] = v1[n1]; quad[3] = v1[p1]; - return 1; + return checkValidQuad(vertex_storage, quad); } return 0; @@ -539,7 +628,7 @@ static BSP_CSGMesh *Carve_exportMesh(MeshSet<3>* &poly, carve::interpolate::Face if (other_index == fl.size()) continue; // see if the faces share an edge - result = quadMerge(&vertexToIndex_map, f, f2, v, quadverts); + result = quadMerge(&vertexToIndex_map, poly->vertex_storage, f, f2, v, quadverts); // if faces can be merged, then remove the other face // from the current set if (result) { |