more tweaks to triangulator. also added a bmeshutils.c file in editors/mesh for ui-related bmesh functions. and made delete only faces use the bmesh del operator, so it can handle ngons.

This commit is contained in:
Joseph Eagar
2009-03-02 02:21:18 +00:00
parent 68341862dd
commit 3faf2b6db7
6 changed files with 194 additions and 28 deletions

View File

@@ -398,7 +398,7 @@ int BM_Validate_Face(BMesh *bm, BMFace *face, FILE *err)
for (i=0; i<V_COUNT(verts); i++) {
for (j=0; j<V_COUNT(verts); j++) {
if (j == 0) continue;
if (j == i) continue;
if (verts[i] == verts[j]) {
fprintf(err, "Found duplicate verts in bmesh face!\n");
fprintf(err, " face ptr: %p, vert: %p\n", face, verts[i]);

View File

@@ -346,7 +346,56 @@ int linecrosses(float *v1, float *v2, float *v3, float *v4)
return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5;
}
int goodline(float (*projectverts)[3], int v1i, int v2i, int nvert, float *outv)
static int goodline_notworking(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMVert *v3,
float (*p)[3], float *outv, int nvert)
{
BMIter iter;
BMLoop *l;
int i, ret = 1;
float r = 0.00001f;
/*cases of a vector being too close to
an axis can cause problems, so this is to
prevent that.*/
for (i=0; i<3; i++) {
p[v1->head.eflag2][i] += r;
p[v2->head.eflag2][i] -= r;
p[v3->head.eflag2][i] += r;
}
//l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f);
//for (; l; l=BMIter_Step(&iter)) {
if (convexangle(p[v1->head.eflag2], p[v2->head.eflag2],
p[v3->head.eflag2])) {
ret = 0;
goto cleanup;
}
for (i=0; i<nvert; i++) {
if (i!=v1->head.eflag2 && i!=v2->head.eflag2 &&
i!=v3->head.eflag2)
{
if (point_in_triangle(p[v3->head.eflag2],
p[v2->head.eflag2], p[v1->head.eflag2],
p[i]))
{
ret = 0;
goto cleanup;
}
}
}
cleanup:
for (i=0; i<3; i++) {
p[v1->head.eflag2][i] -= r;
p[v2->head.eflag2][i] += r;
p[v3->head.eflag2][i] -= r;
}
return ret;
}
static int goodline(float (*projectverts)[3], int v1i, int v2i, int nvert, float *outv)
{
/*the hardcoded stuff here, 0.999 and 1.0001, may be problems
in the future, not sure. - joeedh*/
@@ -404,12 +453,12 @@ int goodline(float (*projectverts)[3], int v1i, int v2i, int nvert, float *outv)
*
*/
static BMLoop *find_ear(BMFace *f, float (*verts)[3], int nvert, float *outv)
static BMLoop *find_ear(BMesh *bm, BMFace *f, float (*verts)[3], int nvert, float *outv)
{
BMVert *v1, *v2, *v3;
BMLoop *bestear = NULL, *l;
float angle, bestangle = 180.0f;
int isear;
int isear, i=0;
l = f->loopbase;
do{
@@ -421,8 +470,9 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], int nvert, float *outv)
if (BM_Edge_Exist(v1, v3)) isear = 0;
if (isear && !goodline(verts, v1->head.eflag2, v3->head.eflag2,
nvert, outv)) isear = 0;
if (isear && !goodline(verts, v1->head.eflag2, v3->head.eflag2, nvert, outv))
isear = 0;
if(isear){
angle = VecAngle3(verts[v1->head.eflag2], verts[v2->head.eflag2], verts[v3->head.eflag2]);
if(!bestear || ABS(angle-40.0f) < bestangle){
@@ -430,7 +480,8 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], int nvert, float *outv)
bestangle = ABS(40.0f-angle);
}
if (angle > 10 && angle < 140) break;
if ((angle > 10 && angle < 140) || i > 5) break;
i += 1;
}
l = (BMLoop*)(l->head.next);
}
@@ -488,7 +539,7 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], int new
done = 0;
while(!done && f->len > 3){
done = 1;
l = find_ear(f, projectverts, nvert, outv);
l = find_ear(bm, f, projectverts, nvert, outv);
if(l) {
done = 0;
f = bmesh_sfme(bm, f, ((BMLoop*)(l->head.prev))->v, ((BMLoop*)(l->head.next))->v, &newl);

View File

@@ -103,7 +103,7 @@ void dissolveverts_exec(BMesh *bm, BMOperator *op)
while (found3) {
found3 = 0;
for (f=BMIter_New(&iter, bm, BM_FACES, NULL); f; f=BMIter_Step(&iter)){
if (BM_Validate_Face(bm, f, stderr)) {
if (!BM_Validate_Face(bm, f, stderr)) {
printf("error.\n");
}

View File

@@ -0,0 +1,108 @@
/* $Id: bmeshutils.c
*
* ***** BEGIN GPL 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.
*
* 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) 2004 by Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Joseph Eagar
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <float.h>
#include "MEM_guardedalloc.h"
#include "PIL_time.h"
#include "BLO_sys_types.h" // for intptr_t support
#include "DNA_mesh_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "DNA_key_types.h"
#include "DNA_windowmanager_types.h"
#include "RNA_types.h"
#include "RNA_define.h"
#include "RNA_access.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
#include "BLI_rand.h"
#include "BLI_ghash.h"
#include "BLI_linklist.h"
#include "BLI_heap.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BKE_bmesh.h"
#include "BKE_report.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "WM_api.h"
#include "WM_types.h"
#include "BMF_Api.h"
#include "ED_mesh.h"
#include "ED_view3d.h"
#include "ED_util.h"
#include "ED_screen.h"
#include "BIF_transform.h"
#include "UI_interface.h"
#include "mesh_intern.h"
#include "bmesh.h"
/*returns 0 on error, 1 on success*/
int EDBM_Finish(BMesh *bm, EditMesh *em, wmOperator *op, bContext *c) {
EditMesh *em2;
char *errmsg;
if (BMO_GetError(bm, &errmsg, NULL)) {
BKE_report(op->reports, RPT_ERROR, errmsg);
BMO_ClearStack(bm);
return 0;
}
em2 = bmesh_to_editmesh(bm);
set_editMesh(em, em2);
MEM_freeN(em2);
BM_Free_Mesh(bm);
return 1;
}

View File

@@ -1147,16 +1147,7 @@ static int delete_mesh_exec(bContext *C, wmOperator *op)
BMO_Finish_Op(bm, &bmop);
if (BMO_GetError(bm, &errmsg, NULL)) {
BKE_report(op->reports, RPT_ERROR, errmsg);
BMO_ClearStack(bm);
return OPERATOR_CANCELLED;
}
em2 = bmesh_to_editmesh(bm);
set_editMesh(em, em2);
MEM_freeN(em2);
BM_Free_Mesh(bm);
if (!EDBM_Finish(bm, em, op, C)) return OPERATOR_CANCELLED;
}
else if(event==6) {
if(!EdgeLoopDelete(em, op))
@@ -1263,16 +1254,24 @@ static int delete_mesh_exec(bContext *C, wmOperator *op)
if(em->selected.first) BLI_freelistN(&(em->selected));
}
else if(event==5) {
BMesh *bm = editmesh_to_bmesh(em);
BMOperator bmop;
EditMesh *em2;
char *errmsg;
str= "Erase Only Faces";
efa= em->faces.first;
while(efa) {
nextvl= efa->next;
if(efa->f & SELECT) {
BLI_remlink(&em->faces, efa);
free_editface(em, efa);
}
efa= nextvl;
}
BMO_Init_Op(&bmop, BMOP_DEL);
BMO_HeaderFlag_To_Slot(bm, &bmop, BMOP_DEL_MULTIN,
BM_SELECT, BM_FACE);
BMO_Set_Int(&bmop, BMOP_DEL_CONTEXT, DEL_ONLYFACES);
BMO_Exec_Op(bm, &bmop);
BMO_Finish_Op(bm, &bmop);
if (!EDBM_Finish(bm, em, op, C)) return OPERATOR_CANCELLED;
}
EM_fgon_flags(em); // redo flags and indices for fgons

View File

@@ -40,9 +40,17 @@
struct bContext;
struct wmOperatorType;
struct ViewContext;
struct BMesh;
#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
/* ******************** bmeshutils.c */
/*called after bmesh tool exec. checks for errors and does conversions.
if any errors are raised by bmesh, it displays the error to the user and
returns 0 (and does not convert). otherwise, it converts the bmesh back
into the editmesh, and returns 1.*/
int EDBM_Finish(struct BMesh *bm, EditMesh *em, struct wmOperator *op, struct bContext *c);
/* ******************** editface.c */
int edgetag_context_check(Scene *scene, EditEdge *eed);