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:
@@ -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]);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
108
source/blender/editors/mesh/bmeshutils.c
Normal file
108
source/blender/editors/mesh/bmeshutils.c
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user