[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12224] branches/bmesh/source/blender: -> Make Face Edge tool
Geoffrey Bantle
hairbat at yahoo.com
Sun Oct 7 22:36:47 CEST 2007
Revision: 12224
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12224
Author: briggs
Date: 2007-10-07 22:36:47 +0200 (Sun, 07 Oct 2007)
Log Message:
-----------
-> Make Face Edge tool
Return of the fkey 'make face edge tool'.
As always, selecting two vertices will make an edge. Selecting
three or four verts/edges will make a quad. Additionally selecting a single
closed loop of edges will create an n-gon.
Still to do:
-add back in the 'fix faces' call at the end to generate proper smooth flag
for generated face
-add a 'fuse faces' tool bound to this hotkey. This will replace both the
'join triangles' functionality of the current f-key implementation as well
as the f-gon creation (replace with n-gons)
Modified Paths:
--------------
branches/bmesh/source/blender/blenkernel/BKE_bmesh.h
branches/bmesh/source/blender/blenkernel/intern/BME_structure.c
branches/bmesh/source/blender/blenkernel/intern/BME_tools.c
branches/bmesh/source/blender/include/editbmesh.h
branches/bmesh/source/blender/src/editbmesh_tools.c
branches/bmesh/source/blender/src/space.c
Modified: branches/bmesh/source/blender/blenkernel/BKE_bmesh.h
===================================================================
--- branches/bmesh/source/blender/blenkernel/BKE_bmesh.h 2007-10-07 17:40:11 UTC (rev 12223)
+++ branches/bmesh/source/blender/blenkernel/BKE_bmesh.h 2007-10-07 20:36:47 UTC (rev 12224)
@@ -159,7 +159,7 @@
struct BME_CycleNode *BME_disk_getpointer(struct BME_Edge *e, struct BME_Vert *v);
struct BME_Edge *BME_disk_next_edgeflag(struct BME_Edge *e, struct BME_Vert *v, int eflag, int tflag);
int BME_disk_count_edgeflag(struct BME_Vert *v, int eflag, int tflag);
-int BME_disk_existedge(struct BME_Vert *v1, struct BME_Vert *v2);
+struct BME_Edge *BME_disk_existedge(struct BME_Vert *v1, struct BME_Vert *v2);
/*RADIAL CYCLE*/
struct BME_Loop *BME_radial_nextloop(struct BME_Loop *l);
@@ -242,4 +242,5 @@
/*Multimode tools*/
void BME_duplicate(struct BME_Mesh *bm);
void BME_extrude_mesh(struct BME_Mesh *bm, int type);
+int BME_make_edgeface(struct BME_Mesh *bm);
#endif
Modified: branches/bmesh/source/blender/blenkernel/intern/BME_structure.c
===================================================================
--- branches/bmesh/source/blender/blenkernel/intern/BME_structure.c 2007-10-07 17:40:11 UTC (rev 12223)
+++ branches/bmesh/source/blender/blenkernel/intern/BME_structure.c 2007-10-07 20:36:47 UTC (rev 12224)
@@ -557,7 +557,7 @@
return count;
}
-int BME_disk_existedge(BME_Vert *v1, BME_Vert *v2){
+BME_Edge *BME_disk_existedge(BME_Vert *v1, BME_Vert *v2){
BME_CycleNode *diskbase;
BME_Edge *curedge;
int i, len=0;
@@ -567,11 +567,11 @@
len = BME_cycle_length(diskbase);
for(i=0,curedge=v1->edge;i<len;i++,curedge = BME_disk_nextedge(curedge,v1)){
- if(BME_verts_in_edge(v1,v2,curedge)) return 1;
+ if(BME_verts_in_edge(v1,v2,curedge)) return curedge;
}
}
- return 0;
+ return NULL;
}
int BME_disk_hasedge(BME_Vert *v, BME_Edge *e){
Modified: branches/bmesh/source/blender/blenkernel/intern/BME_tools.c
===================================================================
--- branches/bmesh/source/blender/blenkernel/intern/BME_tools.c 2007-10-07 17:40:11 UTC (rev 12223)
+++ branches/bmesh/source/blender/blenkernel/intern/BME_tools.c 2007-10-07 20:36:47 UTC (rev 12224)
@@ -34,12 +34,17 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
#include "DNA_object_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_scene_types.h"
#include "BKE_global.h"
#include "BKE_depsgraph.h"
@@ -850,3 +855,257 @@
BLI_ghash_free(ehash,NULL, NULL); //check usage!
}
+int convex(float *v1, float *v2, float *v3, float *v4)
+{
+ float nor[3], nor1[3], nor2[3], vec[4][2];
+
+ /* define projection, do both trias apart, quad is undefined! */
+ CalcNormFloat(v1, v2, v3, nor1);
+ CalcNormFloat(v1, v3, v4, nor2);
+ nor[0]= ABS(nor1[0]) + ABS(nor2[0]);
+ nor[1]= ABS(nor1[1]) + ABS(nor2[1]);
+ nor[2]= ABS(nor1[2]) + ABS(nor2[2]);
+
+ if(nor[2] >= nor[0] && nor[2] >= nor[1]) {
+ vec[0][0]= v1[0]; vec[0][1]= v1[1];
+ vec[1][0]= v2[0]; vec[1][1]= v2[1];
+ vec[2][0]= v3[0]; vec[2][1]= v3[1];
+ vec[3][0]= v4[0]; vec[3][1]= v4[1];
+ }
+ else if(nor[1] >= nor[0] && nor[1]>= nor[2]) {
+ vec[0][0]= v1[0]; vec[0][1]= v1[2];
+ vec[1][0]= v2[0]; vec[1][1]= v2[2];
+ vec[2][0]= v3[0]; vec[2][1]= v3[2];
+ vec[3][0]= v4[0]; vec[3][1]= v4[2];
+ }
+ else {
+ vec[0][0]= v1[1]; vec[0][1]= v1[2];
+ vec[1][0]= v2[1]; vec[1][1]= v2[2];
+ vec[2][0]= v3[1]; vec[2][1]= v3[2];
+ vec[3][0]= v4[1]; vec[3][1]= v4[2];
+ }
+
+ /* linetests, the 2 diagonals have to instersect to be convex */
+ if( IsectLL2Df(vec[0], vec[2], vec[1], vec[3]) > 0 ) return 1;
+ return 0;
+}
+
+
+static BME_Poly *add_quadtri(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v3, BME_Vert *v4){
+ BME_Poly *nf;
+ BME_Edge *edar[4];
+ edar[0] = edar[1] = edar[2] = edar[3] = NULL;
+
+
+ edar[0] = BME_disk_existedge(v1,v2);
+ if(edar[0] == NULL) edar[0] = BME_ME(bm,v1,v2);
+ edar[1] = BME_disk_existedge(v2,v3);
+ if(edar[1] == NULL) edar[1] = BME_ME(bm,v2,v3);
+ if(v4){
+ edar[2] = BME_disk_existedge(v3,v4);
+ if(edar[2] == NULL) edar[2] = BME_ME(bm,v3,v4);
+ edar[3] = BME_disk_existedge(v4,v1);
+ if(edar[3] == NULL) edar[3] = BME_ME(bm,v4,v1);
+ }
+ else{
+ edar[2] = BME_disk_existedge(v3,v1);
+ if(edar[2]==NULL) edar[2] = BME_ME(bm,v3,v1);
+ }
+ if(v4) nf = BME_MF(bm,v1,v2,edar,4);
+ else nf = BME_MF(bm,v1,v2,edar,3);
+ return nf;
+}
+
+/*finds out if any of the faces connected to any of the verts have all other vertices in varr as well. */
+static int exist_face_overlaps(BME_Mesh *bm, BME_Vert **varr, int len){
+ BME_Edge *curedge;
+ BME_Loop *curloop, *l;
+ int i;
+ /*loop through every face in every vert, if it contains all vertices in varr, its an overlap*/
+ for(i=0;i<len;i++){
+ if(varr[i]->edge){
+ curedge = varr[i]->edge;
+ do{
+ if(curedge->loop){
+ curloop = curedge->loop;
+ do{
+ int amount = 0;
+ /*if amount of 'visited' verts == len then we have an overlap*/
+ l = curloop->f->loopbase;
+ do{
+ if(BME_SELECTED(l->v)) amount++;
+ l = l->next;
+ }while(l != curloop->f->loopbase);
+ if(amount >= len){
+ if(len == curloop->f->len) return 2; //existface
+ else return 1; //overlap
+ }
+ curloop = BME_radial_nextloop(curloop);
+ }while(curloop != curedge->loop);
+ }
+ curedge = BME_disk_nextedge(curedge,varr[i]);
+ }while(curedge!=varr[i]->edge);
+ }
+ }
+ return 0;
+}
+
+
+/* precondition; 4 vertices selected, check for 4 edges and create face */
+static BME_Poly *addface_from_edges(BME_Mesh *bm)
+{
+ BME_Edge *e, *eedar[4]={NULL, NULL, NULL, NULL};
+ BME_Vert *v1=NULL, *v2=NULL, *v3=NULL, *v4=NULL;
+ int a;
+
+ /* find the 4 edges */
+ for(e=BME_first(bm,BME_EDGE);e;e=BME_next(bm,BME_EDGE,e)){
+ if(BME_SELECTED(e)) {
+ if(eedar[0]==NULL) eedar[0]= e;
+ else if(eedar[1]==NULL) eedar[1]= e;
+ else if(eedar[2]==NULL) eedar[2]= e;
+ else eedar[3]= e;
+ }
+ }
+
+ if(eedar[3]) {
+ /* first 2 points */
+ v1= eedar[0]->v1;
+ v2= eedar[0]->v2;
+
+ /* find the 2 edges connected to first edge */
+ for(a=1; a<4; a++) {
+ if( eedar[a]->v1 == v2) v3= eedar[a]->v2;
+ else if(eedar[a]->v2 == v2) v3= eedar[a]->v1;
+ else if( eedar[a]->v1 == v1) v4= eedar[a]->v2;
+ else if(eedar[a]->v2 == v1) v4= eedar[a]->v1;
+ }
+
+ /* verify if last edge exists */
+ if(v3 && v4) {
+ for(a=1; a<4; a++) {
+ if( eedar[a]->v1==v3 && eedar[a]->v2==v4) break;
+ if( eedar[a]->v2==v3 && eedar[a]->v1==v4) break;
+ }
+ if(a!=4) {
+ return add_quadtri(bm,v1,v2,v3,v4,4);
+ }
+ }
+ }
+ return NULL;
+}
+
+static BME_Poly *make_ngon_from_selected(BME_Mesh *bm){
+
+ BME_Edge *e, **edar;
+ BME_Poly *nf= NULL;
+ int i, edsel=0;
+
+ for(e=BME_first(bm,BME_EDGE);e;e=BME_next(bm,BME_EDGE,e)){
+ if(BME_SELECTED(e)) edsel++;
+ }
+ edar = MEM_callocN(sizeof(BME_Edge*)*edsel,"Add edgeface Ngon array");
+ i = 0;
+ for(e=BME_first(bm,BME_EDGE);e;e=BME_next(bm,BME_EDGE,e)){
+ if(BME_SELECTED(e)){
+ edar[i] = e;
+ i++;
+ }
+ }
+ nf = BME_MF(bm,edar[0]->v1,edar[0]->v2,edar,edsel);
+ if(edar) MEM_freeN(edar);
+ return nf;
+}
+
+int BME_make_edgeface(BME_Mesh *bm){
+
+ BME_Vert *v, *newface[4];
+ BME_Edge *e, **edar=NULL, *halt;
+ BME_Loop *l;
+ BME_Poly *f, *nf=NULL;
+ int i, amount=0, facesel=0;
+
+
+ if(bm->selectmode & SCE_SELECT_EDGE){
+ /* in edge mode finding selected vertices means flushing down edge codes... */
+ /* can't make face with only edge selection info... */
+ BME_selectmode_set(bm);
+ }
+
+ /*special exception here.... if there is one or more faces selected, we want to fuse them into one face*/
+ for(f=BME_first(bm,BME_POLY);f;f=BME_next(bm,BME_POLY,f)){
+ /*if all vertices of the face are selected, we need to mark it, and count. Run a seperate function on it to fuse faces*/
+ l=f->loopbase;
+ do{
+ if(BME_SELECTED(l->v)) amount++;
+ l=l->next;
+ }while(l!=f->loopbase);
+
+ if(amount == f->len) facesel++;
+ }
+
+ //insert face fusing code here in case facesel > 1. if == 1, error.
+
+ amount = 0;
+ /*we make special excepton for quads and tris, only require vertex information to make them. For n-gons we need closed loop of edges.*/
+ for(v=BME_first(bm,BME_VERT);v;v=BME_next(bm,BME_VERT,v)){
+ if(BME_SELECTED(v)){
+ if(amount == 4){
+ nf = make_ngon_from_selected(bm);
+ break;
+ }
+ newface[amount] = v;
+ amount++;
+ }
+ }
+
+ if(!nf){
+ /*if amount == 2, create edge*/
+ if(amount == 2){
+ if(!(BME_disk_existedge(newface[0],newface[1]))) BME_ME(bm,newface[0],newface[1]);
+ }
+ /*if amount == 3, triangle...*/
+ else if(amount == 3){
+ if(exist_face_overlaps(bm,newface,3) == 0) add_quadtri(bm,newface[0],newface[1],newface[2],NULL);
+ }
+ /*if amount == 4, quad...*/
+ else if(amount == 4){
+ if(exist_face_overlaps(bm,newface,4) == 0){
+ /* if 4 edges exist, we just create the face, convex or not */
+ nf= addface_from_edges(bm);
+ if(nf==NULL) {
+ if( convex(newface[0]->co, newface[1]->co, newface[2]->co, newface[3]->co) ) {
+ nf= add_quadtri(bm, newface[0], newface[1], newface[2], newface[3]);
+ }
+ else if( convex(newface[0]->co, newface[2]->co, newface[3]->co, newface[1]->co) ) {
+ nf= add_quadtri(bm, newface[0], newface[2], newface[3], newface[1]);
+ }
+ else if( convex(newface[0]->co, newface[2]->co, newface[1]->co, newface[3]->co) ) {
+ nf= add_quadtri(bm, newface[0], newface[2], newface[1], newface[3]);
+ }
+ else if( convex(newface[1]->co, newface[2]->co, newface[3]->co, newface[0]->co) ) {
+ nf= add_quadtri(bm, newface[1], newface[2], newface[3], newface[0]);
+ }
+ else if( convex(newface[1]->co, newface[3]->co, newface[0]->co, newface[2]->co) ) {
+ nf= add_quadtri(bm, newface[1], newface[3], newface[0], newface[2]);
+ }
+ else if( convex(newface[1]->co, newface[3]->co, newface[2]->co, newface[0]->co) ) {
+ nf= add_quadtri(bm, newface[1], newface[3], newface[2], newface[0]);
+ }
+ return -1;
+ }
+ }
+ return -1;;
+ }
+ }
+
+ if(nf) {
+ BME_select_poly(bm,nf, 1);
+ //fix_new_face(efa); fix me!
+ //recalc_editnormals(); fix me too!
+
+ }
+}
+
+
+
Modified: branches/bmesh/source/blender/include/editbmesh.h
===================================================================
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list