[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49107] trunk/blender/intern/boolop/intern /BOP_CarveInterface.cpp: Boolean modifier: prevent crashes when carve returns bad topology
Sergey Sharybin
sergey.vfx at gmail.com
Sat Jul 21 21:19:46 CEST 2012
Revision: 49107
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49107
Author: nazgul
Date: 2012-07-21 19:19:45 +0000 (Sat, 21 Jul 2012)
Log Message:
-----------
Boolean modifier: prevent crashes when carve returns bad topology
For sure actual issue is in carve's triangulation system which need
to be investigated and fixed. For now only fixed by re-shuffling a
bit existing degenerative faces check and added extra checks there.
Would look into actual fix a bit later.
Modified Paths:
--------------
trunk/blender/intern/boolop/intern/BOP_CarveInterface.cpp
Modified: trunk/blender/intern/boolop/intern/BOP_CarveInterface.cpp
===================================================================
--- trunk/blender/intern/boolop/intern/BOP_CarveInterface.cpp 2012-07-21 16:21:42 UTC (rev 49106)
+++ trunk/blender/intern/boolop/intern/BOP_CarveInterface.cpp 2012-07-21 19:19:45 UTC (rev 49107)
@@ -547,13 +547,32 @@
return 0;
}
-static bool Carve_checkDegeneratedFace(MeshSet<3>::face_t *face)
+static bool Carve_checkDegeneratedFace(std::map<MeshSet<3>::vertex_t*, uint> *vertexToIndex_map, MeshSet<3>::face_t *face)
{
/* only tris and quads for now */
if (face->n_edges == 3) {
+ uint v1, v2, v3;
+
+ v1 = vertexToIndex_map->find(face->edge->prev->vert)->second;
+ v2 = vertexToIndex_map->find(face->edge->vert)->second;
+ v3 = vertexToIndex_map->find(face->edge->next->vert)->second;
+
+ if (v1 == v2 || v2 == v3 || v1 == v3)
+ return true;
+
return triangleArea(face->edge->prev->vert->v, face->edge->vert->v, face->edge->next->vert->v) < DBL_EPSILON;
}
else if (face->n_edges == 4) {
+ uint v1, v2, v3, v4;
+
+ v1 = vertexToIndex_map->find(face->edge->prev->vert)->second;
+ v2 = vertexToIndex_map->find(face->edge->vert)->second;
+ v3 = vertexToIndex_map->find(face->edge->next->vert)->second;
+ v4 = vertexToIndex_map->find(face->edge->next->next->vert)->second;
+
+ if (v1 == v2 || v1 == v3 || v1 == v4 || v2 == v3 || v2 == v4 || v3 == v4)
+ return true;
+
return triangleArea(face->edge->vert->v, face->edge->next->vert->v, face->edge->next->next->vert->v) +
triangleArea(face->edge->prev->vert->v, face->edge->vert->v, face->edge->next->next->vert->v) < DBL_EPSILON;
}
@@ -595,8 +614,14 @@
MeshSet<3>::face_iter face_iter = poly->faceBegin();
for (i = 0; face_iter != poly->faceEnd(); ++face_iter, ++i) {
MeshSet<3>::face_t *f = *face_iter;
+
+ if (Carve_checkDegeneratedFace(&vertexToIndex_map, f))
+ continue;
+
ofaces[oface_num.getAttribute(f)].push_back(i);
+
MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
+
for (; edge_iter != f->end(); ++edge_iter) {
int index = vertexToIndex_map[edge_iter->vert];
vi[index].push_back(i);
@@ -659,36 +684,27 @@
}
}
- bool degenerativeFace = false;
+ // add all information except vertices to the output mesh
+ outputMesh->FaceSet().push_back(BSP_MFace());
+ BSP_MFace& outFace = outputMesh->FaceSet().back();
+ outFace.m_verts.clear();
+ outFace.m_plane.setValue(f->plane.N.v);
+ outFace.m_orig_face = orig;
- if (!result) {
- /* merged triangles are already checked for degenerative quad */
- degenerativeFace = Carve_checkDegeneratedFace(f);
- }
-
- if (!degenerativeFace) {
- // add all information except vertices to the output mesh
- outputMesh->FaceSet().push_back(BSP_MFace());
- BSP_MFace& outFace = outputMesh->FaceSet().back();
- outFace.m_verts.clear();
- outFace.m_plane.setValue(f->plane.N.v);
- outFace.m_orig_face = orig;
-
- // if we merged faces, use the list of common vertices; otherwise
- // use the faces's vertices
- if (result) {
- // make quat using verts stored in result
- outFace.m_verts.push_back(quadverts[0]);
- outFace.m_verts.push_back(quadverts[1]);
- outFace.m_verts.push_back(quadverts[2]);
- outFace.m_verts.push_back(quadverts[3]);
- } else {
- MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
- for (; edge_iter != f->end(); ++edge_iter) {
- //int index = ofacevert_num.getAttribute(f, edge_iter.idx());
- int index = vertexToIndex_map[edge_iter->vert];
- outFace.m_verts.push_back( index );
- }
+ // if we merged faces, use the list of common vertices; otherwise
+ // use the faces's vertices
+ if (result) {
+ // make quat using verts stored in result
+ outFace.m_verts.push_back(quadverts[0]);
+ outFace.m_verts.push_back(quadverts[1]);
+ outFace.m_verts.push_back(quadverts[2]);
+ outFace.m_verts.push_back(quadverts[3]);
+ } else {
+ MeshSet<3>::face_t::edge_iter_t edge_iter = f->begin();
+ for (; edge_iter != f->end(); ++edge_iter) {
+ //int index = ofacevert_num.getAttribute(f, edge_iter.idx());
+ int index = vertexToIndex_map[edge_iter->vert];
+ outFace.m_verts.push_back( index );
}
}
}
More information about the Bf-blender-cvs
mailing list