[Bf-committers] Edge Subdiv Patch 2
Johnny Matthews
johnny.matthews at gmail.com
Wed Jun 8 21:34:50 CEST 2005
Well, I'm not so bright and sent a non-working patch last time. This one
should work :)
Johnny
-------------- next part --------------
? blender-2.37-windows.zip
? config.opts
? cvtres.exe.config
? dist
? edgering.patch
? go.bat
? lib.c
? subdiv.patch
? source/creator/winbuildinfo.h
? source/icons/winblender.res
? tools/__init__.pyc
? tools/scons/__init__.pyc
? tools/scons/bs/__init__.pyc
? tools/scons/bs/bs_arc.pyc
? tools/scons/bs/bs_bincopy.pyc
? tools/scons/bs/bs_clean.pyc
? tools/scons/bs/bs_config.pyc
? tools/scons/bs/bs_default.pyc
? tools/scons/bs/bs_dirs.pyc
? tools/scons/bs/bs_globals.pyc
? tools/scons/bs/bs_libs.pyc
? tools/scons/bs/bs_nsis.pyc
Index: source/blender/include/BIF_editmesh.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/include/BIF_editmesh.h,v
retrieving revision 1.37
diff -u -r1.37 BIF_editmesh.h
--- source/blender/include/BIF_editmesh.h 16 Feb 2005 15:02:58 -0000 1.37
+++ source/blender/include/BIF_editmesh.h 3 Jun 2005 20:05:05 -0000
@@ -156,6 +156,7 @@
extern void xsortvert_flag(int flag);
extern void hashvert_flag(int flag);
extern void subdivideflag(int flag, float rad, int beauty);
+extern void esubdivideflag(int flag, float rad, int beauty, int numcuts);
extern void extrude_mesh(void);
extern void split_mesh(void);
extern void extrude_repeat_mesh(int steps, float offs);
Index: source/blender/src/editmesh_mods.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/editmesh_mods.c,v
retrieving revision 1.52
diff -u -r1.52 editmesh_mods.c
--- source/blender/src/editmesh_mods.c 27 May 2005 09:51:07 -0000 1.52
+++ source/blender/src/editmesh_mods.c 5 Jun 2005 19:25:55 -0000
@@ -973,6 +973,74 @@
}
}
+/*
+ Almostly exactly the same code as faceloop select
+*/
+static void edgering_select(EditEdge *startedge, int select){
+ EditMesh *em = G.editMesh;
+ EditEdge *eed;
+ EditFace *efa;
+ int looking= 1;
+
+ /* in eed->f1 we put the valence (amount of faces in edge) */
+ /* in eed->f2 we put tagged flag as correct loop */
+ /* in efa->f1 we put tagged flag as correct to select */
+
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ eed->f1= 0;
+ eed->f2= 0;
+ }
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ efa->f1= 0;
+ if(efa->h==0) {
+ efa->e1->f1++;
+ efa->e2->f1++;
+ efa->e3->f1++;
+ if(efa->e4) efa->e4->f1++;
+ }
+ }
+
+ // tag startedge OK
+ startedge->f2= 1;
+
+ while(looking) {
+ looking= 0;
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->e4 && efa->f1==0) { // not done quad
+ if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok
+
+ // if edge tagged, select opposing edge and mark face ok
+ if(efa->e1->f2) {
+ efa->e3->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ else if(efa->e2->f2) {
+ efa->e4->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ if(efa->e3->f2) {
+ efa->e1->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ if(efa->e4->f2) {
+ efa->e2->f2= 1;
+ efa->f1= 1;
+ looking= 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* (de)select the edges */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->f2) EM_select_edge(eed, select);
+ }
+}
/* ***************** MAIN MOUSE SELECTION ************** */
// just to have the functions nice together
@@ -992,8 +1060,14 @@
if(G.scene->selectmode & SCE_SELECT_FACE) {
faceloop_select(eed, eed->f & SELECT);
}
- else {
- edgeloop_select(eed, eed->f & SELECT);
+ else if(G.scene->selectmode & SCE_SELECT_EDGE) {
+ if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY))
+ edgering_select(eed, eed->f & SELECT);
+ else if(G.qual & LR_ALTKEY)
+ edgeloop_select(eed, eed->f & SELECT);
+ }
+ else if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+ edgeloop_select(eed, eed->f & SELECT);
}
/* frontbuffer draw of last selected only */
Index: source/blender/src/editmesh_tools.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/editmesh_tools.c,v
retrieving revision 1.51
diff -u -r1.51 editmesh_tools.c
--- source/blender/src/editmesh_tools.c 7 Jun 2005 13:04:31 -0000 1.51
+++ source/blender/src/editmesh_tools.c 8 Jun 2005 19:23:15 -0000
@@ -25,7 +25,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Johnny Matthews.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -59,6 +59,7 @@
#include "BLI_arithb.h"
#include "BLI_editVert.h"
#include "BLI_rand.h"
+#include "BLI_ghash.h"
#include "BKE_displist.h"
#include "BKE_global.h"
@@ -93,8 +94,8 @@
/* local prototypes ---------------*/
void bevel_menu(void);
-
-
+static void free_tagged_edgelist(EditEdge *eed);
+static void free_tagged_facelist(EditFace *efa);
/********* qsort routines *********/
@@ -1959,6 +1960,848 @@
allqueue(REDRAWVIEW3D, 0);
makeDispList(G.obedit);
}
+
+
+/*--------------Edge Based Subdivide------------------*/
+#define EDGENEW 8
+
+static void fill_quad_single(EditFace *efa, struct GHash *gh, int numcuts);
+
+
+static void flipvertarray(EditVert** arr, short size){
+ EditVert *hold;
+ int i;
+
+ for(i=0;i<size/2;i++){
+ hold = arr[i];
+ arr[i] = arr[size-i-1];
+ arr[size-i-1] = hold;
+ }
+}
+static void facecopy(EditFace *source,EditFace *target){
+ UVCOPY(target->tf.uv[0],source->tf.uv[0]);
+ UVCOPY(target->tf.uv[1],source->tf.uv[1]);
+ UVCOPY(target->tf.uv[2],source->tf.uv[2]);
+ UVCOPY(target->tf.uv[3],source->tf.uv[3]);
+
+ target->mat_nr = source->mat_nr;
+ target->tf.flag = source->tf.flag;
+ target->tf.transp = source->tf.transp;
+ target->tf.mode = source->tf.mode;
+ target->tf.tile = source->tf.tile;
+ target->tf.unwrap = source->tf.unwrap;
+ target->tf.tpage = source->tf.tpage;
+ target->flag = source->flag;
+
+}
+
+static void fill_quad_single(EditFace *efa, struct GHash *gh, int numcuts){
+ EditEdge *cedge;
+ EditVert *v[4], **verts;
+ EditFace *hold;
+ short start, end, left, right, vertsize,i;
+
+ v[0] = efa->v1;
+ v[1] = efa->v2;
+ v[2] = efa->v3;
+ v[3] = efa->v4;
+
+ if(efa->e1->f & SELECT) { cedge = efa->e1; start = 0;}
+ else if(efa->e2->f & SELECT) { cedge = efa->e2; start = 1;}
+ else if(efa->e3->f & SELECT) { cedge = efa->e3; start = 2;}
+ else if(efa->e4->f & SELECT) { cedge = efa->e4; start = 3;}
+
+ // Point verts to the array of new verts for cedge
+ verts = BLI_ghash_lookup(gh, cedge);
+ //This is the index size of the verts array
+ vertsize = numcuts+2;
+
+ // Is the original v1 the same as the first vert on the selected edge?
+ // if not, the edge is running the opposite direction in this face so flip
+ // the array to the correct direction
+
+ if(verts[0] != v[start]){flipvertarray(verts,numcuts+2);}
+ end = (start+1)%4;
+ left = (start+2)%4;
+ right = (start+3)%4;
+
+ /*
+ We should have something like this now
+
+ end start
+ 3 2 1 0
+ |---*---*---|
+ | |
+ | |
+ | |
+ -------------
+ left right
+
+ where start,end,left, right are indexes of EditFace->v1, etc (stored in v)
+ and 0,1,2... are the indexes of the new verts stored in verts
+
+ We will fill this case like this or this depending on even or odd cuts
+
+ |---*---*---| |---*---|
+ | / \ | | / \ |
+ | / \ | | / \ |
+ |/ \| |/ \|
+ ------------- ---------
+ */
+
+ // Make center face
+ if(vertsize % 2 == 0){
+ hold = addfacelist(verts[(vertsize-1)/2],verts[((vertsize-1)/2)+1],v[left],v[right], NULL,NULL);
+ }else{
+ hold = addfacelist(verts[(vertsize-1)/2],v[left],v[right],NULL, NULL,NULL);
+ }
+ facecopy(efa,hold);
+
+ // Make side faces
+ for(i=0;i<(vertsize-1)/2;i++){
+ hold = addfacelist(verts[i],verts[i+1],v[right],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ hold = addfacelist(verts[vertsize-2-i],verts[vertsize-1-i],v[left],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ }
+}
+
+static void fill_tri_single(EditFace *efa, struct GHash *gh, int numcuts){
+ EditEdge *cedge;
+ EditVert *v[3], **verts;
+ EditFace *hold;
+ short start, end, op, vertsize,i;
+
+ v[0] = efa->v1;
+ v[1] = efa->v2;
+ v[2] = efa->v3;
+
+ if(efa->e1->f & SELECT) { cedge = efa->e1; start = 0;}
+ else if(efa->e2->f & SELECT) { cedge = efa->e2; start = 1;}
+ else if(efa->e3->f & SELECT) { cedge = efa->e3; start = 2;}
+
+ // Point verts to the array of new verts for cedge
+ verts = BLI_ghash_lookup(gh, cedge);
+ //This is the index size of the verts array
+ vertsize = numcuts+2;
+
+ // Is the original v1 the same as the first vert on the selected edge?
+ // if not, the edge is running the opposite direction in this face so flip
+ // the array to the correct direction
+
+ if(verts[0] != v[start]){flipvertarray(verts,numcuts+2);}
+ end = (start+1)%3;
+ op = (start+2)%3;
+
+ /*
+ We should have something like this now
+
+ end start
+ 3 2 1 0
+ |---*---*---|
+ \ |
+ \ |
+ \ |
+ \ |
+ \ |
+ \ |
+ |op
+
+ where start,end,op are indexes of EditFace->v1, etc (stored in v)
+ and 0,1,2... are the indexes of the new verts stored in verts
+
+ We will fill this case like this or this depending on even or odd cuts
+
+ 3 2 1 0
+ |---*---*---|
+ \ \ \ |
+ \ \ \ |
+ \ \ \ |
+ \ \ \|
+ \ \\|
+ \ |
+ |op
+ */
+
+ // Make side faces
+ for(i=0;i<(vertsize-1);i++){
+ hold = addfacelist(verts[i],verts[i+1],v[op],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ }
+}
+
+static void fill_quad_double_op(EditFace *efa, struct GHash *gh, int numcuts){
+ EditEdge *cedge[2];
+ EditVert *v[4], **verts[2];
+ EditFace *hold;
+ short start, end, left, right, vertsize,i;
+
+ v[0] = efa->v1;
+ v[1] = efa->v2;
+ v[2] = efa->v3;
+ v[3] = efa->v4;
+
+ if(efa->e1->f & SELECT) { cedge[0] = efa->e1; cedge[1] = efa->e3; start = 0;}
+ else if(efa->e2->f & SELECT) { cedge[0] = efa->e2; cedge[1] = efa->e4; start = 1;}
+
+ // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
+ verts[0] = BLI_ghash_lookup(gh, cedge[0]);
+ verts[1] = BLI_ghash_lookup(gh, cedge[1]);
+ //This is the index size of the verts array
+ vertsize = numcuts+2;
+
+ // Is the original v1 the same as the first vert on the selected edge?
+ // if not, the edge is running the opposite direction in this face so flip
+ // the array to the correct direction
+
+ if(verts[0][0] != v[start]){flipvertarray(verts[0],numcuts+2);}
+ end = (start+1)%4;
+ left = (start+2)%4;
+ right = (start+3)%4;
+ if(verts[1][0] != v[left]){flipvertarray(verts[1],numcuts+2);}
+ /*
+ We should have something like this now
+
+ end start
+ 3 2 1 0
+ |---*---*---|
+ | |
+ | |
+ | |
+ |---*---*---|
+ 0 1 2 3
+ left right
+
+ We will fill this case like this or this depending on even or odd cuts
+
+ |---*---*---|
+ | | | |
+ | | | |
+ | | | |
+ |---*---*---|
+ */
+
+ // Make side faces
+ for(i=0;i<vertsize-1;i++){
+ hold = addfacelist(verts[0][i],verts[0][i+1],verts[1][vertsize-2-i],verts[1][vertsize-1-i],NULL,NULL);
+ facecopy(efa,hold);
+ }
+}
+
+
+static void fill_quad_double_adj(EditFace *efa, struct GHash *gh, int numcuts){
+ EditEdge *cedge[2];
+ EditVert *v[4], **verts[2];
+ EditFace *hold;
+ short start, start2, vertsize,i;
+
+ v[0] = efa->v1;
+ v[1] = efa->v2;
+ v[2] = efa->v3;
+ v[3] = efa->v4;
+
+ if(efa->e1->f & SELECT && efa->e2->f & SELECT) {cedge[0] = efa->e1; cedge[1] = efa->e2; start = 0; start2 = 1;}
+ if(efa->e2->f & SELECT && efa->e3->f & SELECT) {cedge[0] = efa->e2; cedge[1] = efa->e3; start = 1; start2 = 2;}
+ if(efa->e3->f & SELECT && efa->e4->f & SELECT) {cedge[0] = efa->e3; cedge[1] = efa->e4; start = 2; start2 = 3;}
+ if(efa->e4->f & SELECT && efa->e1->f & SELECT) {cedge[0] = efa->e4; cedge[1] = efa->e1; start = 3; start2 = 0;}
+
+ // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
+ verts[0] = BLI_ghash_lookup(gh, cedge[0]);
+ verts[1] = BLI_ghash_lookup(gh, cedge[1]);
+ //This is the index size of the verts array
+ vertsize = numcuts+2;
+
+ // Is the original v1 the same as the first vert on the selected edge?
+ // if not, the edge is running the opposite direction in this face so flip
+ // the array to the correct direction
+
+ if(verts[0][0] != v[start]){flipvertarray(verts[0],numcuts+2);}
+ if(verts[1][0] != v[start2]){flipvertarray(verts[1],numcuts+2);}
+ /*
+ We should have something like this now
+
+ end start
+ 3 2 1 0
+ start2 0|---*---*---|
+ | |
+ 1* |
+ | |
+ 2* |
+ | |
+ end2 3|-----------|
+
+ We will fill this case like this or this depending on even or odd cuts
+ |---*---*---|
+ | / / / |
+ * / / |
+ | / / |
+ * / |
+ | / |
+ |-----------|
+ */
+
+ // Make outside tris
+ hold = addfacelist(verts[0][vertsize-2],verts[0][vertsize-1],verts[1][1],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ hold = addfacelist(verts[0][0],verts[1][vertsize-1],v[(start2+2)%4],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ // Make side faces
+
+ for(i=0;i<numcuts;i++){
+ hold = addfacelist(verts[0][i],verts[0][i+1],verts[1][vertsize-1-(i+1)],verts[1][vertsize-1-i],NULL,NULL);
+ facecopy(efa,hold);
+ }
+}
+
+static void fill_tri_double(EditFace *efa, struct GHash *gh, int numcuts){
+ EditEdge *cedge[2];
+ EditVert *v[3], **verts[2];
+ EditFace *hold;
+ short start, start2, vertsize,i;
+
+ v[0] = efa->v1;
+ v[1] = efa->v2;
+ v[2] = efa->v3;
+
+ if(efa->e1->f & SELECT && efa->e2->f & SELECT) {cedge[0] = efa->e1; cedge[1] = efa->e2; start = 0; start2 = 1;}
+ if(efa->e2->f & SELECT && efa->e3->f & SELECT) {cedge[0] = efa->e2; cedge[1] = efa->e3; start = 1; start2 = 2;}
+ if(efa->e3->f & SELECT && efa->e1->f & SELECT) {cedge[0] = efa->e3; cedge[1] = efa->e1; start = 2; start2 = 0;}
+
+ // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
+ verts[0] = BLI_ghash_lookup(gh, cedge[0]);
+ verts[1] = BLI_ghash_lookup(gh, cedge[1]);
+ //This is the index size of the verts array
+ vertsize = numcuts+2;
+
+ // Is the original v1 the same as the first vert on the selected edge?
+ // if not, the edge is running the opposite direction in this face so flip
+ // the array to the correct direction
+
+ if(verts[0][0] != v[start]){flipvertarray(verts[0],numcuts+2);}
+ if(verts[1][0] != v[start2]){flipvertarray(verts[1],numcuts+2);}
+ /*
+ We should have something like this now
+
+ end start
+ 3 2 1 0
+ start2 0|---*---*---|
+ | /
+ 1* /
+ | /
+ 2* /
+ | /
+ end2 3|
+
+ We will fill this case like this or this depending on even or odd cuts
+ |---*---*---|
+ | / / /
+ * / /
+ | / /
+ * /
+ | /
+ |
+ */
+
+ // Make outside tri
+ hold = addfacelist(verts[0][vertsize-2],verts[0][vertsize-1],verts[1][1],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ // Make side faces
+
+ for(i=0;i<numcuts;i++){
+ hold = addfacelist(verts[0][i],verts[0][i+1],verts[1][vertsize-1-(i+1)],verts[1][vertsize-1-i],NULL,NULL);
+ facecopy(efa,hold);
+ }
+}
+
+static void fill_quad_triple(EditFace *efa, struct GHash *gh, int numcuts){
+ EditEdge *cedge[3];
+ EditVert *v[4], **verts[3];
+ EditFace *hold;
+ short start, start2, start3, vertsize, i, repeats;
+
+ v[0] = efa->v1;
+ v[1] = efa->v2;
+ v[2] = efa->v3;
+ v[3] = efa->v4;
+
+ if(!(efa->e1->f & SELECT)) {
+ cedge[0] = efa->e2;
+ cedge[1] = efa->e3;
+ cedge[2] = efa->e4;
+ start = 1;start2 = 2;start3 = 3;
+ }
+ if(!(efa->e2->f & SELECT)) {
+ cedge[0] = efa->e3;
+ cedge[1] = efa->e4;
+ cedge[2] = efa->e1;
+ start = 2;start2 = 3;start3 = 0;
+ }
+ if(!(efa->e3->f & SELECT)) {
+ cedge[0] = efa->e4;
+ cedge[1] = efa->e1;
+ cedge[2] = efa->e2;
+ start = 3;start2 = 0;start3 = 1;
+ }
+ if(!(efa->e4->f & SELECT)) {
+ cedge[0] = efa->e1;
+ cedge[1] = efa->e2;
+ cedge[2] = efa->e3;
+ start = 0;start2 = 1;start3 = 2;
+ }
+ // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
+ verts[0] = BLI_ghash_lookup(gh, cedge[0]);
+ verts[1] = BLI_ghash_lookup(gh, cedge[1]);
+ verts[2] = BLI_ghash_lookup(gh, cedge[2]);
+ //This is the index size of the verts array
+ vertsize = numcuts+2;
+
+ // Is the original v1 the same as the first vert on the selected edge?
+ // if not, the edge is running the opposite direction in this face so flip
+ // the array to the correct direction
+
+ if(verts[0][0] != v[start]) {flipvertarray(verts[0],numcuts+2);}
+ if(verts[1][0] != v[start2]){flipvertarray(verts[1],numcuts+2);}
+ if(verts[2][0] != v[start3]){flipvertarray(verts[2],numcuts+2);}
+ /*
+ We should have something like this now
+
+ start2
+ 3 2 1 0
+ start3 0|---*---*---|3
+ | |
+ 1* *2
+ | |
+ 2* *1
+ | |
+ 3|-----------|0 start
+
+ We will fill this case like this or this depending on even or odd cuts
+ there are a couple of differences. For odd cuts, there is a tri in the
+ middle as well as 1 quad at the bottom (not including the extra quads
+ for odd cuts > 1
+
+ For even cuts, there is a quad in the middle and 2 quads on the bottom
+
+ they are numbered here for clarity
+
+ 1 outer tris and bottom quads
+ 2 inner tri or quad
+ 3 repeating quads
+
+ |---*---*---*---|
+ |1/ / \ \ 1|
+ |/ 3 / \ 3 \|
+ * / 2 \ *
+ | / \ |
+ |/ \ |
+ *---------------*
+ | 3 |
+ | |
+ *---------------*
+ | |
+ | 1 |
+ | |
+ |---------------|
+
+ |---*---*---*---*---|
+ | 1/ / \ \ 1|
+ | / / \ \ |
+ |/ 3 / \ 3 \|
+ * / \ *
+ | / \ |
+ | / 2 \ |
+ |/ \|
+ *-------------------*
+ | |
+ | 3 |
+ | |
+ *-------------------*
+ | |
+ | 1 |
+ | |
+ *-------------------*
+ | |
+ | 1 |
+ | |
+ |-------------------|
+
+ */
+
+ // Make outside tris
+ hold = addfacelist(verts[0][vertsize-2],verts[0][vertsize-1],verts[1][1],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ hold = addfacelist(verts[1][vertsize-2],verts[1][vertsize-1],verts[2][1],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ // Make bottom quad
+ hold = addfacelist(verts[0][0],verts[0][1],verts[2][vertsize-2],verts[2][vertsize-1],NULL,NULL);
+ facecopy(efa,hold);
+ //If it is even cuts, add the 2nd lower quad
+ if(numcuts % 2 == 0){
+ hold = addfacelist(verts[0][1],verts[0][2],verts[2][vertsize-3],verts[2][vertsize-2],NULL,NULL);
+ facecopy(efa,hold);
+ // Also Make inner quad
+ hold = addfacelist(verts[1][numcuts/2],verts[1][(numcuts/2)+1],verts[2][numcuts/2],verts[0][(numcuts/2)+1],NULL,NULL);
+ facecopy(efa,hold);
+ repeats = (numcuts / 2) -1;
+ } else {
+ // Make inner tri
+ hold = addfacelist(verts[1][(numcuts/2)+1],verts[2][(numcuts/2)+1],verts[0][(numcuts/2)+1],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ repeats = ((numcuts+1) / 2)-1;
+ }
+
+ // cuts for 1 and 2 do not have the repeating quads
+ if(numcuts < 3){repeats = 0;}
+ for(i=0;i<repeats;i++){
+ //Make side repeating Quads
+ hold = addfacelist(verts[1][i+1],verts[1][i+2],verts[0][vertsize-i-3],verts[0][vertsize-i-2],NULL,NULL);
+ facecopy(efa,hold);
+ hold = addfacelist(verts[1][vertsize-i-3],verts[1][vertsize-i-2],verts[2][i+1],verts[2][i+2],NULL,NULL);
+ facecopy(efa,hold);
+ }
+ // Do repeating bottom quads
+ for(i=0;i<repeats;i++){
+ if(numcuts % 2 == 1){
+ hold = addfacelist(verts[0][1+i],verts[0][2+i],verts[2][vertsize-3-i],verts[2][vertsize-2-i],NULL,NULL);
+ } else {
+ hold = addfacelist(verts[0][2+i],verts[0][3+i],verts[2][vertsize-4-i],verts[2][vertsize-3-i],NULL,NULL);
+ }
+ facecopy(efa,hold);
+ }
+}
+
+static void fill_quad_quadruple(EditFace *efa, struct GHash *gh, int numcuts){
+ EditVert **verts[4], ***innerverts;
+ short vertsize, i, j;
+ float co[3];
+ EditFace *hold;
+ // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
+ verts[0] = BLI_ghash_lookup(gh, efa->e1);
+ verts[1] = BLI_ghash_lookup(gh, efa->e2);
+ verts[2] = BLI_ghash_lookup(gh, efa->e3);
+ verts[3] = BLI_ghash_lookup(gh, efa->e4);
+
+ //This is the index size of the verts array
+ vertsize = numcuts+2;
+
+ // Is the original v1 the same as the first vert on the selected edge?
+ // if not, the edge is running the opposite direction in this face so flip
+ // the array to the correct direction
+
+ if(verts[0][0] != efa->v1) {flipvertarray(verts[0],numcuts+2);}
+ if(verts[1][0] != efa->v2) {flipvertarray(verts[1],numcuts+2);}
+ if(verts[2][0] == efa->v3) {flipvertarray(verts[2],numcuts+2);}
+ if(verts[3][0] == efa->v4) {flipvertarray(verts[3],numcuts+2);}
+ /*
+ We should have something like this now
+ 1
+
+ 3 2 1 0
+ 0|---*---*---|0
+ | |
+ 1* *1
+ 2 | | 4
+ 2* *2
+ | |
+ 3|---*---*---|3
+ 3 2 1 0
+
+ 3
+ // we will fill a 2 dim array of editvert*s to make filling easier
+ // the innervert order is shown
+
+ 0 0---1---2---3
+ | | | |
+ 1 0---1---2---3
+ | | | |
+ 2 0---1---2---3
+ | | | |
+ 3 0---1---2---3
+
+ */
+ innerverts = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"quad-quad subdiv inner verts outer array");
+ for(i=0;i<numcuts+2;i++){
+ innerverts[i] = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"quad-quad subdiv inner verts inner array");
+ }
+ // first row is e1 last row is e3
+ for(i=0;i<numcuts+2;i++){
+ innerverts[0][i] = verts[0][(numcuts+1)-i];
+ innerverts[numcuts+1][i] = verts[2][(numcuts+1)-i];
+ }
+ for(i=1;i<=numcuts;i++){
+ innerverts[i][0] = verts[1][i];
+ innerverts[i][numcuts+1] = verts[3][i];
+ for(j=1;j<=numcuts;j++){
+ co[0] = ((verts[1][i]->co[0] - verts[3][i]->co[0]) * (j /(float)(numcuts+1))) + verts[3][i]->co[0];
+ co[1] = ((verts[1][i]->co[1] - verts[3][i]->co[1]) * (j /(float)(numcuts+1))) + verts[3][i]->co[1];
+ co[2] = ((verts[1][i]->co[2] - verts[3][i]->co[2]) * (j /(float)(numcuts+1))) + verts[3][i]->co[2];
+ innerverts[i][(numcuts+1)-j] = addvertlist(co);
+ }
+ }
+ // Fill with faces
+ for(i=0;i<numcuts+1;i++){
+ for(j=0;j<numcuts+1;j++){
+ hold = addfacelist(innerverts[i][j+1],innerverts[i][j],innerverts[i+1][j],innerverts[i+1][j+1],NULL,NULL);
+ facecopy(efa,hold);
+ }
+ }
+ // Clean up our dynamic multi-dim array
+ for(i=0;i<numcuts+2;i++){
+ MEM_freeN(innerverts[i]);
+ }
+ MEM_freeN(innerverts);
+}
+
+static void fill_tri_triple(EditFace *efa, struct GHash *gh, int numcuts){
+ EditVert **verts[3], ***innerverts;
+ short vertsize, i, j;
+ float co[3];
+ EditFace *hold;
+ // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
+ verts[0] = BLI_ghash_lookup(gh, efa->e1);
+ verts[1] = BLI_ghash_lookup(gh, efa->e2);
+ verts[2] = BLI_ghash_lookup(gh, efa->e3);
+
+ //This is the index size of the verts array
+ vertsize = numcuts+2;
+
+ // Is the original v1 the same as the first vert on the selected edge?
+ // if not, the edge is running the opposite direction in this face so flip
+ // the array to the correct direction
+
+ if(verts[0][0] != efa->v1) {flipvertarray(verts[0],numcuts+2);}
+ if(verts[1][0] != efa->v2) {flipvertarray(verts[1],numcuts+2);}
+ if(verts[2][0] != efa->v3) {flipvertarray(verts[2],numcuts+2);}
+ /*
+ We should have something like this now
+ 3
+
+ 3 2 1 0
+ 0|---*---*---|3
+ | /
+ 1 1* *2
+ | /
+ 2* *1 2
+ | /
+ 3|/
+ 0
+
+ we will fill a 2 dim array of editvert*s to make filling easier
+
+ 3
+
+ 0 0---1---2---3---4
+ | / | / |/ | /
+ 1 0---1----2---3
+ 1 | / | / | /
+ 2 0----1---2 2
+ | / | /
+ |/ |/
+ 3 0---1
+ | /
+ |/
+ 4 0
+
+ */
+
+ innerverts = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"tri-tri subdiv inner verts outer array");
+ for(i=0;i<numcuts+2;i++){
+ innerverts[i] = MEM_mallocN(sizeof(EditVert*)*((numcuts+2)-i),"tri-tri subdiv inner verts inner array");
+ }
+ //top row is e3 backwards
+ for(i=0;i<numcuts+2;i++){
+ innerverts[0][i] = verts[2][(numcuts+1)-i];
+ }
+
+ for(i=1;i<=numcuts+1;i++){
+ //first vert is from e1, last is from e2
+ innerverts[i][0] = verts[0][i];
+ innerverts[i][(numcuts+1)-i] = verts[1][(numcuts+1)-i];
+ for(j=1;j<(numcuts+1)-i;j++){
+ co[0] = ((verts[0][i]->co[0] - verts[1][(numcuts+1)-i]->co[0]) * (j/(float)((numcuts+1)-i))) + verts[1][(numcuts+1)-i]->co[0];
+ co[1] = ((verts[0][i]->co[1] - verts[1][(numcuts+1)-i]->co[1]) * (j/(float)((numcuts+1)-i))) + verts[1][(numcuts+1)-i]->co[1];
+ co[2] = ((verts[0][i]->co[2] - verts[1][(numcuts+1)-i]->co[2]) * (j/(float)((numcuts+1)-i))) + verts[1][(numcuts+1)-i]->co[2];
+ innerverts[i][((numcuts+1)-i)-j] = addvertlist(co);
+ }
+ }
+ // Now fill the verts with happy little tris :)
+ for(i=0;i<=numcuts+1;i++){
+ for(j=0;j<(numcuts+1)-i;j++){
+ //We always do the first tri
+ hold = addfacelist(innerverts[i][j+1],innerverts[i][j],innerverts[i+1][j],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ //if there are more to come, we do the 2nd
+ if(j+1 <= numcuts-i){
+ hold = addfacelist(innerverts[i+1][j],innerverts[i+1][j+1],innerverts[i][j+1],NULL,NULL,NULL);
+ facecopy(efa,hold);
+ }
+ }
+ }
+
+ // Clean up our dynamic multi-dim array
+ for(i=0;i<numcuts+2;i++){
+ MEM_freeN(innerverts[i]);
+ }
+ MEM_freeN(innerverts);
+}
+
+// This function takes an example edge, the current point to create and
+// the total # of points to create, then creates the point and return the
+// editvert pointer to it.
+static EditVert *subdivideedgenum(EditEdge *edge,int curpoint,int totpoint){
+ float co[3];
+ EditVert *ev;
+ co[0] = (edge->v2->co[0]-edge->v1->co[0])*(curpoint/(float)(totpoint+1))+edge->v1->co[0];
+ co[1] = (edge->v2->co[1]-edge->v1->co[1])*(curpoint/(float)(totpoint+1))+edge->v1->co[1];
+ co[2] = (edge->v2->co[2]-edge->v1->co[2])*(curpoint/(float)(totpoint+1))+edge->v1->co[2];
+
+ ev = addvertlist(co);
+ //ev->f = 0;
+ return ev;
+}
+
+/*
+static void edgecopy(EditEdge *source, EditEdge *target){
+ target->crease = source->crease;
+ target->h = source->h;
+ target->dir = source->dir;
+ target->seam = source->seam;
+}*/
+
+void esubdivideflag(int flag, float rad, int beauty, int numcuts)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *ef;
+ EditEdge *eed, *cedge;
+ EditVert **templist;
+ struct GHash *gh;
+ int i,edgecount,facetype;
+ short cuttype=0;
+
+ //Set faces f1 to 0 cause we need it later
+
+ for(ef=em->faces.first;ef;ef = ef->next){
+ ef->f1 = 0;
+ }
+
+ // We store an array of verts for each edge that is subdivided,
+ // we put this array as a value in a ghash which is keyed by the EditEdge*
+
+ gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+
+ // So for each edge, if it is selected, we allocate an array of size cuts+2
+ // so we can have a place for the v1, the new verts and v2
+ for(eed=em->edges.first;eed;eed = eed->next){
+ if(eed->f & SELECT){
+ templist = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"vertlist");
+ templist[0] = eed->v1;
+ for(i=0;i<numcuts;i++){
+ // This function creates the new vert and returns it back
+ // to the array
+ templist[i+1] = subdivideedgenum(eed,i+1,numcuts);
+
+ //while we are here, we can copy edge info from the original edge
+ cedge = addedgelist(templist[i],templist[i+1],eed);
+ cedge->f2 = EDGENEW;
+ }
+ templist[i+1] = eed->v2;
+ //Do the last edge too
+ cedge = addedgelist(templist[i],templist[i+1],eed);
+ cedge->f2 = EDGENEW;
+ // Now that the edge is subdivided, we can put its verts in the ghash
+ BLI_ghash_insert(gh, eed, templist);
+ }
+ }
+
+ // Now for each face in the mesh we need to figure out How many edges were cut
+ // and which filling method to use for that face
+
+ for(ef = em->faces.first;ef;ef = ef->next){
+ edgecount = 0;
+ facetype = 3;
+ if(ef->e1->f & SELECT) {edgecount++;}
+ if(ef->e2->f & SELECT) {edgecount++;}
+ if(ef->e3->f & SELECT) {edgecount++;}
+ if(ef->v4){
+ facetype = 4;
+ if(ef->e4->f & SELECT){edgecount++;}
+ }
+ printf("facetype - %d, edgecount - %d\n",facetype,edgecount);
+ if(facetype == 4){
+ switch(edgecount){
+ case 0: break;
+ case 1: ef->f1 = SELECT;
+ fill_quad_single(ef, gh, numcuts);
+ break;
+ case 2: ef->f1 = SELECT;
+ // if there are 2, we check if edge 1 and 3 are either both on or off that way
+ // we can tell if the selected pair is Adjacent or Opposite of each other
+ if((ef->e1->f & SELECT && ef->e3->f & SELECT) ||
+ (ef->e2->f & SELECT && ef->e4->f & SELECT)){
+ printf("op\n");
+ fill_quad_double_op(ef, gh, numcuts);
+ }else{
+ printf("adj\n");
+ fill_quad_double_adj(ef, gh, numcuts);
+ }
+ break;
+ case 3: ef->f1 = SELECT;
+ fill_quad_triple(ef, gh, numcuts);
+ break;
+ case 4: ef->f1 = SELECT;
+ fill_quad_quadruple(ef, gh, numcuts);
+ break;
+ }
+ } else {
+ switch(edgecount){
+ case 0: break;
+ case 1: ef->f1 = SELECT;
+ fill_tri_single(ef, gh, numcuts);
+ break;
+ case 2: ef->f1 = SELECT;
+ fill_tri_double(ef, gh, numcuts);
+ break;
+ case 3: ef->f1 = SELECT;
+ fill_tri_triple(ef, gh, numcuts);
+ break;
+ }
+ }
+ }
+
+
+ // Delete Old Faces
+ free_tagged_facelist(em->faces.first);
+ //Delete Old Edges
+ for(eed = em->edges.first;eed;eed = eed->next){
+ if(BLI_ghash_haskey(gh,eed)){
+ eed->f1 = SELECT;
+ } else {
+ eed->f1 = 0;
+ }
+ }
+ free_tagged_edgelist(em->edges.first);
+
+ for(eed = em->edges.first;eed;eed = eed->next){
+ if(eed->f2 & EDGENEW){
+ eed->f |= SELECT;
+ }
+ }
+
+ // Free the ghash and call MEM_freeN on all the value entries to return
+ // that memory
+ BLI_ghash_free(gh, NULL, MEM_freeN);
+
+ /* since this is all on vertex level, flush vertex selection */
+ //EM_select_flush();
+ recalc_editnormals();
+
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ makeDispList(G.obedit);
+}
+
+
static int count_selected_edges(EditEdge *ed)
{
Index: source/blender/src/editobject.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/editobject.c,v
retrieving revision 1.188
diff -u -r1.188 editobject.c
--- source/blender/src/editobject.c 12 May 2005 19:17:12 -0000 1.188
+++ source/blender/src/editobject.c 6 Jun 2005 05:15:59 -0000
@@ -1895,7 +1895,7 @@
extern float doublimit;
float fac;
int nr,ret;
- short randfac;
+ short randfac,numcuts;
if(G.obedit==0) {
if(G.f & G_FACESELECT) {
@@ -2008,9 +2008,9 @@
}
}
else if(G.obedit->type==OB_MESH) {
-
- nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Fractal%x2|Subdivide Smooth%x3|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11");
- if(nr>0) waitcursor(1);
+
+ nr= pupmenu("Specials%t|E-Subdivide%x12|Subdivide%x1|Subdivide Fractal%x2|Subdivide Smooth%x3|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11");
+ //if(nr>0) waitcursor(1);
switch(nr) {
case 1:
@@ -2053,6 +2053,14 @@
break;
case 11:
bevel_menu();
+ break;
+ case 12:
+ numcuts = 1;
+ if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
+ waitcursor(1);
+ esubdivideflag(1, 0.0, editbutflag,numcuts);
+
+ BIF_undo_push("ESubdivide");
break;
}
More information about the Bf-committers
mailing list