Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2011-05-09 04:06:48 +00:00
|
|
|
#include "BLI_utildefines.h"
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
|
|
|
|
#include "BLI_ghash.h"
|
|
|
|
|
#include "BLI_memarena.h"
|
|
|
|
|
#include "BLI_blenlib.h"
|
2009-11-23 14:41:22 +00:00
|
|
|
#include "BLI_math.h"
|
2009-09-17 23:05:33 +00:00
|
|
|
#include "BLI_array.h"
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
|
|
|
|
#include "bmesh.h"
|
2010-07-14 22:06:10 +00:00
|
|
|
#include "bmesh_private.h"
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
#include "bmesh_operators_private.h"
|
|
|
|
|
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2011-09-23 12:06:47 +00:00
|
|
|
#define EXT_INPUT 1
|
|
|
|
|
#define EXT_KEEP 2
|
|
|
|
|
#define EXT_DEL 4
|
|
|
|
|
|
2011-10-11 05:18:33 +00:00
|
|
|
#define VERT_MARK 1
|
|
|
|
|
#define EDGE_MARK 1
|
2011-09-23 12:06:47 +00:00
|
|
|
#define FACE_MARK 1
|
2011-10-11 05:18:33 +00:00
|
|
|
#define VERT_NONMAN 2
|
|
|
|
|
#define EDGE_NONMAN 2
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
void bmesh_extrude_face_indiv_exec(BMesh *bm, BMOperator *op)
|
|
|
|
|
{
|
|
|
|
|
BMOIter siter;
|
|
|
|
|
BMIter liter, liter2;
|
|
|
|
|
BMFace *f, *f2, *f3;
|
|
|
|
|
BMLoop *l, *l2, *l3, *l4;
|
|
|
|
|
BMEdge **edges = NULL, *e, *laste;
|
|
|
|
|
BMVert *v, *lastv, *firstv;
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_declare(edges);
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
BMO_ITER(f, &siter, bm, op, "faces", BM_FACE) {
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_empty(edges);
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
i = 0;
|
|
|
|
|
firstv = lastv = NULL;
|
|
|
|
|
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(edges);
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
|
2011-09-12 05:24:45 +00:00
|
|
|
v = BM_Make_Vert(bm, l->v->co, l->v);
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
|
|
|
|
|
if (lastv) {
|
|
|
|
|
e = BM_Make_Edge(bm, lastv, v, l->e, 0);
|
|
|
|
|
edges[i++] = e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lastv = v;
|
|
|
|
|
laste = l->e;
|
|
|
|
|
if (!firstv) firstv = v;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(edges);
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
e = BM_Make_Edge(bm, v, firstv, laste, 0);
|
|
|
|
|
edges[i++] = e;
|
|
|
|
|
|
|
|
|
|
BMO_SetFlag(bm, f, EXT_DEL);
|
|
|
|
|
|
2011-09-06 03:21:55 +00:00
|
|
|
f2 = BM_Make_Ngon(bm, firstv, BM_OtherEdgeVert(edges[0], firstv), edges, f->len, 0);
|
2011-05-24 01:34:28 +00:00
|
|
|
if (!f2) {
|
|
|
|
|
BMO_RaiseError(bm, op, BMERR_MESH_ERROR, "Extrude failed; could not create face");
|
|
|
|
|
BLI_array_free(edges);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
BMO_SetFlag(bm, f2, EXT_KEEP);
|
|
|
|
|
BM_Copy_Attributes(bm, bm, f, f2);
|
|
|
|
|
|
|
|
|
|
l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_FACE, f2);
|
|
|
|
|
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
|
|
|
|
|
BM_Copy_Attributes(bm, bm, l, l2);
|
2011-05-24 01:34:28 +00:00
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
l3 = l->next;
|
|
|
|
|
l4 = l2->next;
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
|
|
|
|
|
f3 = BM_Make_QuadTri(bm, l3->v, l4->v, l2->v, l->v, f, 0);
|
|
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
BM_Copy_Attributes(bm, bm, l->next, bm_firstfaceloop(f3));
|
|
|
|
|
BM_Copy_Attributes(bm, bm, l->next, bm_firstfaceloop(f3)->next);
|
|
|
|
|
BM_Copy_Attributes(bm, bm, l, bm_firstfaceloop(f3)->next->next);
|
|
|
|
|
BM_Copy_Attributes(bm, bm, l, bm_firstfaceloop(f3)->next->next->next);
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
|
|
|
|
|
l2 = BMIter_Step(&liter2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-24 01:34:28 +00:00
|
|
|
BLI_array_free(edges);
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
|
2011-05-24 01:34:28 +00:00
|
|
|
BMO_CallOpf(bm, "del geom=%ff context=%d", EXT_DEL, DEL_ONLYFACES);
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
BMO_Flag_To_Slot(bm, op, "faceout", EXT_KEEP, BM_FACE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void bmesh_extrude_onlyedge_exec(BMesh *bm, BMOperator *op)
|
|
|
|
|
{
|
|
|
|
|
BMOIter siter;
|
|
|
|
|
BMOperator dupeop;
|
|
|
|
|
BMVert *v1, *v2, *v3, *v4;
|
|
|
|
|
BMEdge *e, *e2;
|
|
|
|
|
BMFace *f;
|
|
|
|
|
|
|
|
|
|
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
|
|
|
|
BMO_SetFlag(bm, e, EXT_INPUT);
|
|
|
|
|
BMO_SetFlag(bm, e->v1, EXT_INPUT);
|
|
|
|
|
BMO_SetFlag(bm, e->v2, EXT_INPUT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BMO_InitOpf(bm, &dupeop, "dupe geom=%fve", EXT_INPUT);
|
|
|
|
|
BMO_Exec_Op(bm, &dupeop);
|
|
|
|
|
|
|
|
|
|
e = BMO_IterNew(&siter, bm, &dupeop, "boundarymap", 0);
|
|
|
|
|
for (; e; e=BMO_IterStep(&siter)) {
|
|
|
|
|
e2 = BMO_IterMapVal(&siter);
|
|
|
|
|
e2 = *(BMEdge**)e2;
|
|
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
if (e->l && e->v1 != e->l->v) {
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
v1 = e->v1;
|
|
|
|
|
v2 = e->v2;
|
|
|
|
|
v3 = e2->v2;
|
|
|
|
|
v4 = e2->v1;
|
|
|
|
|
} else {
|
|
|
|
|
v1 = e2->v1;
|
|
|
|
|
v2 = e2->v2;
|
|
|
|
|
v3 = e->v2;
|
|
|
|
|
v4 = e->v1;
|
|
|
|
|
}
|
|
|
|
|
/*not sure what to do about example face, pass NULL for now.*/
|
|
|
|
|
f = BM_Make_QuadTri(bm, v1, v2, v3, v4, NULL, 0);
|
|
|
|
|
|
|
|
|
|
if (BMO_TestFlag(bm, e, EXT_INPUT))
|
|
|
|
|
e = e2;
|
|
|
|
|
|
|
|
|
|
BMO_SetFlag(bm, f, EXT_KEEP);
|
|
|
|
|
BMO_SetFlag(bm, e, EXT_KEEP);
|
|
|
|
|
BMO_SetFlag(bm, e->v1, EXT_KEEP);
|
|
|
|
|
BMO_SetFlag(bm, e->v2, EXT_KEEP);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BMO_Finish_Op(bm, &dupeop);
|
|
|
|
|
|
|
|
|
|
BMO_Flag_To_Slot(bm, op, "geomout", EXT_KEEP, BM_ALL);
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-19 00:33:54 +00:00
|
|
|
void extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
|
|
|
|
|
{
|
|
|
|
|
BMOIter siter;
|
|
|
|
|
BMVert *v, *dupev;
|
|
|
|
|
BMEdge *e;
|
|
|
|
|
|
2009-06-23 05:35:49 +00:00
|
|
|
v = BMO_IterNew(&siter, bm, op, "verts", BM_VERT);
|
2009-05-19 00:33:54 +00:00
|
|
|
for (; v; v=BMO_IterStep(&siter)) {
|
2011-09-12 05:24:45 +00:00
|
|
|
dupev = BM_Make_Vert(bm, v->co, v);
|
2009-05-19 00:33:54 +00:00
|
|
|
|
|
|
|
|
e = BM_Make_Edge(bm, v, dupev, NULL, 0);
|
|
|
|
|
|
|
|
|
|
BMO_SetFlag(bm, e, EXT_KEEP);
|
|
|
|
|
BMO_SetFlag(bm, dupev, EXT_KEEP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BMO_Flag_To_Slot(bm, op, "vertout", EXT_KEEP, BM_VERT);
|
|
|
|
|
BMO_Flag_To_Slot(bm, op, "edgeout", EXT_KEEP, BM_EDGE);
|
|
|
|
|
}
|
|
|
|
|
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
|
|
|
|
|
{
|
2009-02-15 00:47:19 +00:00
|
|
|
BMOperator dupeop, delop;
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
BMOIter siter;
|
2009-02-15 00:47:19 +00:00
|
|
|
BMIter iter, fiter, viter;
|
2011-07-11 09:27:21 +00:00
|
|
|
BMEdge *e, *newedge;
|
2009-02-14 11:58:52 +00:00
|
|
|
BMLoop *l, *l2;
|
2009-03-16 11:38:42 +00:00
|
|
|
BMVert *verts[4], *v, *v2;
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
BMFace *f;
|
2011-07-11 09:27:21 +00:00
|
|
|
int rlen, found, fwd, delorig=0;
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
|
|
|
|
/*initialize our sub-operators*/
|
2009-03-22 23:16:43 +00:00
|
|
|
BMO_Init_Op(&dupeop, "dupe");
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
BMO_Flag_Buffer(bm, op, "edgefacein", EXT_INPUT, BM_EDGE|BM_FACE);
|
2009-03-16 10:12:52 +00:00
|
|
|
|
|
|
|
|
/*if one flagged face is bordered by an unflagged face, then we delete
|
2011-09-23 12:06:47 +00:00
|
|
|
original geometry unless caller explicitly asked to keep it. */
|
|
|
|
|
if (!BMO_Get_Int(op, "alwayskeeporig")) {
|
|
|
|
|
BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
|
|
|
|
|
if (!BMO_TestFlag(bm, e, EXT_INPUT)) continue;
|
|
|
|
|
|
|
|
|
|
found = 0;
|
|
|
|
|
f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, e);
|
|
|
|
|
for (rlen=0; f; f=BMIter_Step(&fiter), rlen++) {
|
|
|
|
|
if (!BMO_TestFlag(bm, f, EXT_INPUT)) {
|
|
|
|
|
found = 1;
|
|
|
|
|
delorig = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-02-15 00:47:19 +00:00
|
|
|
}
|
|
|
|
|
|
2011-09-23 12:06:47 +00:00
|
|
|
if (!found && (rlen > 1)) BMO_SetFlag(bm, e, EXT_DEL);
|
|
|
|
|
}
|
2009-02-15 00:47:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*calculate verts to delete*/
|
2009-05-28 04:41:02 +00:00
|
|
|
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
|
2009-02-15 00:47:19 +00:00
|
|
|
found = 0;
|
|
|
|
|
|
2009-05-28 04:41:02 +00:00
|
|
|
BM_ITER(e, &viter, bm, BM_EDGES_OF_VERT, v) {
|
2011-07-11 09:27:21 +00:00
|
|
|
if (!BMO_TestFlag(bm, e, EXT_INPUT) || !BMO_TestFlag(bm, e, EXT_DEL)){
|
2009-02-15 00:47:19 +00:00
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-05-28 04:41:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(f, &viter, bm, BM_FACES_OF_VERT, v) {
|
|
|
|
|
if (!BMO_TestFlag(bm, f, EXT_INPUT)) {
|
2009-02-15 00:47:19 +00:00
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-02-12 18:05:34 +00:00
|
|
|
}
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
2009-02-15 00:47:19 +00:00
|
|
|
if (!found) {
|
|
|
|
|
BMO_SetFlag(bm, v, EXT_DEL);
|
|
|
|
|
}
|
|
|
|
|
}
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
2009-05-28 04:41:02 +00:00
|
|
|
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
|
2009-02-15 00:47:19 +00:00
|
|
|
if (BMO_TestFlag(bm, f, EXT_INPUT))
|
|
|
|
|
BMO_SetFlag(bm, f, EXT_DEL);
|
|
|
|
|
}
|
2011-09-23 12:06:47 +00:00
|
|
|
|
|
|
|
|
if (delorig) {
|
|
|
|
|
BMO_InitOpf(bm, &delop, "del geom=%fvef context=%d",
|
|
|
|
|
EXT_DEL, DEL_ONLYTAGGED);
|
|
|
|
|
}
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
2009-03-22 23:16:43 +00:00
|
|
|
BMO_CopySlot(op, &dupeop, "edgefacein", "geom");
|
2009-02-15 00:47:19 +00:00
|
|
|
BMO_Exec_Op(bm, &dupeop);
|
2009-06-18 07:11:55 +00:00
|
|
|
|
|
|
|
|
if (bm->act_face && BMO_TestFlag(bm, bm->act_face, EXT_INPUT))
|
|
|
|
|
bm->act_face = BMO_Get_MapPointer(bm, &dupeop, "facemap", bm->act_face);
|
|
|
|
|
|
2009-02-15 00:47:19 +00:00
|
|
|
if (delorig) BMO_Exec_Op(bm, &delop);
|
2009-03-16 09:41:33 +00:00
|
|
|
|
|
|
|
|
/*if not delorig, reverse loops of original faces*/
|
|
|
|
|
if (!delorig) {
|
2009-03-22 23:16:43 +00:00
|
|
|
for (f=BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL); f; f=BMIter_Step(&iter)) {
|
2009-03-16 09:41:33 +00:00
|
|
|
if (BMO_TestFlag(bm, f, EXT_INPUT)) {
|
|
|
|
|
BM_flip_normal(bm, f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-18 07:11:55 +00:00
|
|
|
|
2009-03-22 23:16:43 +00:00
|
|
|
BMO_CopySlot(&dupeop, op, "newout", "geomout");
|
2009-06-23 05:35:49 +00:00
|
|
|
e = BMO_IterNew(&siter, bm, &dupeop, "boundarymap", 0);
|
2009-02-15 00:47:19 +00:00
|
|
|
for (; e; e=BMO_IterStep(&siter)) {
|
2009-03-22 23:16:43 +00:00
|
|
|
if (BMO_InMap(bm, op, "exclude", e)) continue;
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
2009-02-12 18:05:34 +00:00
|
|
|
newedge = BMO_IterMapVal(&siter);
|
|
|
|
|
newedge = *(BMEdge**)newedge;
|
2009-03-14 13:16:35 +00:00
|
|
|
if (!newedge) continue;
|
2011-07-11 09:27:21 +00:00
|
|
|
|
|
|
|
|
/* orient loop to give same normal as a loop of newedge
|
|
|
|
|
if it exists (will be an extruded face),
|
|
|
|
|
else same normal as a loop of e, if it exists */
|
|
|
|
|
if (!newedge->l)
|
|
|
|
|
fwd = !e->l || !(e->l->v == e->v1);
|
|
|
|
|
else
|
|
|
|
|
fwd = (newedge->l->v == newedge->v1);
|
|
|
|
|
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
|
2011-07-11 09:27:21 +00:00
|
|
|
if (fwd) {
|
2009-03-16 09:41:33 +00:00
|
|
|
verts[0] = e->v1;
|
|
|
|
|
verts[1] = e->v2;
|
|
|
|
|
verts[2] = newedge->v2;
|
|
|
|
|
verts[3] = newedge->v1;
|
|
|
|
|
} else {
|
|
|
|
|
verts[3] = e->v1;
|
|
|
|
|
verts[2] = e->v2;
|
|
|
|
|
verts[1] = newedge->v2;
|
|
|
|
|
verts[0] = newedge->v1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*not sure what to do about example face, pass NULL for now.*/
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
f = BM_Make_Quadtriangle(bm, verts, NULL, 4, NULL, 0);
|
2009-02-14 11:58:52 +00:00
|
|
|
|
|
|
|
|
/*copy attributes*/
|
|
|
|
|
l=BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f);
|
|
|
|
|
for (; l; l=BMIter_Step(&iter)) {
|
2009-03-16 09:41:33 +00:00
|
|
|
if (l->e != e && l->e != newedge) continue;
|
2010-07-14 22:06:10 +00:00
|
|
|
l2 = l->radial_next;
|
2009-02-14 11:58:52 +00:00
|
|
|
|
2009-03-16 09:41:33 +00:00
|
|
|
if (l2 == l) {
|
2010-07-14 22:06:10 +00:00
|
|
|
l2 = newedge->l;
|
2009-03-16 09:41:33 +00:00
|
|
|
BM_Copy_Attributes(bm, bm, l2->f, l->f);
|
|
|
|
|
|
|
|
|
|
BM_Copy_Attributes(bm, bm, l2, l);
|
2011-09-12 15:10:59 +00:00
|
|
|
l2 = l2->next;
|
|
|
|
|
l = l->next;
|
2009-03-16 09:41:33 +00:00
|
|
|
BM_Copy_Attributes(bm, bm, l2, l);
|
|
|
|
|
} else {
|
|
|
|
|
BM_Copy_Attributes(bm, bm, l2->f, l->f);
|
|
|
|
|
|
2009-02-14 11:58:52 +00:00
|
|
|
/*copy data*/
|
|
|
|
|
if (l2->v == l->v) {
|
|
|
|
|
BM_Copy_Attributes(bm, bm, l2, l);
|
2011-09-12 15:10:59 +00:00
|
|
|
l2 = l2->next;
|
|
|
|
|
l = l->next;
|
2009-02-14 11:58:52 +00:00
|
|
|
BM_Copy_Attributes(bm, bm, l2, l);
|
|
|
|
|
} else {
|
2011-09-12 15:10:59 +00:00
|
|
|
l2 = l2->next;
|
2009-02-14 11:58:52 +00:00
|
|
|
BM_Copy_Attributes(bm, bm, l2, l);
|
2011-09-12 15:10:59 +00:00
|
|
|
l2 = l2->prev;
|
|
|
|
|
l = l->next;
|
2009-02-14 11:58:52 +00:00
|
|
|
BM_Copy_Attributes(bm, bm, l2, l);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
}
|
2009-02-15 00:47:19 +00:00
|
|
|
|
2009-03-16 11:38:42 +00:00
|
|
|
/*link isolated verts*/
|
2009-06-23 05:35:49 +00:00
|
|
|
v = BMO_IterNew(&siter, bm, &dupeop, "isovertmap", 0);
|
2009-03-16 11:38:42 +00:00
|
|
|
for (; v; v=BMO_IterStep(&siter)) {
|
|
|
|
|
v2 = *((void**)BMO_IterMapVal(&siter));
|
2010-07-14 22:06:10 +00:00
|
|
|
BM_Make_Edge(bm, v, v2, v->e, 1);
|
2009-03-16 11:38:42 +00:00
|
|
|
}
|
|
|
|
|
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
/*cleanup*/
|
2009-03-16 10:12:52 +00:00
|
|
|
if (delorig) BMO_Finish_Op(bm, &delop);
|
2009-02-15 00:47:19 +00:00
|
|
|
BMO_Finish_Op(bm, &dupeop);
|
Replaced unified extrude edges/faces code (the stuff specificaly for
edges/faces,extrudeflag_edgess, not the entire extrude system) with
a bmesh version. This stress-tested the operator api, and I had to
code some new stuff,including:
* An api to iterate over Mapping slots and array slots. It's modeled
after the normal iterator api.
* The ability to copy mapping slots.
* More mapping functions.
* In addition to being able to flag elements in a buffer,
you can now unflag them (much clearer then passing in ~flag
I think).
The extrude edge/faces code has multiple layers. At the top
level is a funtion in editmesh_lib.c, which takes care of selection,
handles mirror modifiers, etc. It calls the extrude operator, which
in turns calls split, which calls dupe/del. Note that split needed
a slot to exclude things from being deleting (e.g. when extruding
a single isolated face).
The basic idea (reflected in original design of split/dupe/del by Briggs)
is to use the split function to do the heavy work of extrude. split spits
out new geometry and mappings from boundary edges, for extrude (it should
also spit out other mappings, but that's for later).
Briggs: you may want to look over this, hopefully I didn't do anything
too evil.
I probably should spend some time going over the 2.5 mesh operators and
cleaning them up, splitting ones that need splitting, etc, and in general
getting them to work properly.
2009-02-12 16:59:51 +00:00
|
|
|
}
|
2011-09-23 12:06:47 +00:00
|
|
|
|
|
|
|
|
/*
|
2011-10-15 14:46:26 +00:00
|
|
|
* Compute higher-quality vertex normals used by solidify.
|
|
|
|
|
* Only considers geometry in the marked solidify region.
|
|
|
|
|
* Note that this does not work so well for non-manifold
|
|
|
|
|
* regions.
|
2011-09-23 12:06:47 +00:00
|
|
|
*/
|
|
|
|
|
static void calc_solidify_normals(BMesh *bm)
|
|
|
|
|
{
|
|
|
|
|
BMIter viter, eiter, fiter;
|
|
|
|
|
BMVert *v;
|
|
|
|
|
BMEdge *e;
|
|
|
|
|
BMFace *f, *f1, *f2;
|
|
|
|
|
float edge_normal[3];
|
2011-10-11 05:18:33 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* Clear indices of verts & edges */
|
|
|
|
|
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
|
|
|
|
|
BM_SetIndex(v, 0);
|
|
|
|
|
}
|
|
|
|
|
BM_ITER(e, &eiter, bm, BM_EDGES_OF_MESH, NULL) {
|
|
|
|
|
BM_SetIndex(e, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(f, &fiter, bm, BM_FACES_OF_MESH, NULL) {
|
|
|
|
|
if (!BMO_TestFlag(bm, f, FACE_MARK)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(e, &eiter, bm, BM_EDGES_OF_FACE, f) {
|
2011-10-15 14:46:26 +00:00
|
|
|
/* Count number of marked faces using e */
|
2011-10-11 05:18:33 +00:00
|
|
|
i = BM_GetIndex(e);
|
|
|
|
|
BM_SetIndex(e, i+1);
|
|
|
|
|
|
2011-10-15 14:46:26 +00:00
|
|
|
/* And mark all edges and vertices on the
|
|
|
|
|
marked faces */
|
2011-10-11 05:18:33 +00:00
|
|
|
BMO_SetFlag(bm, e, EDGE_MARK);
|
|
|
|
|
BMO_SetFlag(bm, e->v1, VERT_MARK);
|
|
|
|
|
BMO_SetFlag(bm, e->v2, VERT_MARK);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(e, &eiter, bm, BM_EDGES_OF_MESH, NULL) {
|
|
|
|
|
if (!BMO_TestFlag(bm, e, EDGE_MARK)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = BM_GetIndex(e);
|
2011-09-23 12:06:47 +00:00
|
|
|
|
2011-10-11 05:18:33 +00:00
|
|
|
if (i == 0 || i > 2) {
|
|
|
|
|
/* Edge & vertices are non-manifold even when considering
|
|
|
|
|
only marked faces */
|
2011-09-23 12:06:47 +00:00
|
|
|
BMO_SetFlag(bm, e, EDGE_NONMAN);
|
|
|
|
|
BMO_SetFlag(bm, e->v1, VERT_NONMAN);
|
|
|
|
|
BMO_SetFlag(bm, e->v2, VERT_NONMAN);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
|
2011-10-11 05:18:33 +00:00
|
|
|
if (BM_Nonmanifold_Vert(bm, v)) {
|
|
|
|
|
BMO_SetFlag(bm, v, VERT_NONMAN);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (BMO_TestFlag(bm, v, VERT_MARK)) {
|
|
|
|
|
zero_v3(v->no);
|
|
|
|
|
}
|
2011-09-23 12:06:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(e, &eiter, bm, BM_EDGES_OF_MESH, NULL) {
|
2011-10-29 11:23:37 +00:00
|
|
|
|
2011-10-15 14:46:26 +00:00
|
|
|
/* If the edge is not part of a the solidify region
|
|
|
|
|
its normal should not be considered */
|
|
|
|
|
if (!BMO_TestFlag(bm, e, EDGE_MARK)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If the edge joins more than two marked faces high
|
|
|
|
|
quality normal computation won't work */
|
|
|
|
|
if (BMO_TestFlag(bm, e, EDGE_NONMAN)) {
|
2011-09-23 12:06:47 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-11 05:18:33 +00:00
|
|
|
f1 = f2 = NULL;
|
2011-09-23 12:06:47 +00:00
|
|
|
|
2011-10-11 05:18:33 +00:00
|
|
|
BM_ITER(f, &fiter, bm, BM_FACES_OF_EDGE, e) {
|
|
|
|
|
if (BMO_TestFlag(bm, f, FACE_MARK)) {
|
|
|
|
|
if (f1 == NULL) {
|
|
|
|
|
f1 = f;
|
|
|
|
|
}
|
2011-10-15 14:46:26 +00:00
|
|
|
else {
|
|
|
|
|
BLI_assert(f2 == NULL);
|
2011-10-11 05:18:33 +00:00
|
|
|
f2 = f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_assert(f1 != NULL);
|
|
|
|
|
|
|
|
|
|
if (f2 != NULL) {
|
2011-10-29 11:23:37 +00:00
|
|
|
const float angle = angle_normalized_v3v3(f1->no, f2->no);
|
2011-09-23 12:06:47 +00:00
|
|
|
|
|
|
|
|
if (angle > 0.0f) {
|
2011-10-15 14:46:26 +00:00
|
|
|
/* two faces using this edge, calculate the edge normal
|
2011-09-23 12:06:47 +00:00
|
|
|
* using the angle between the faces as a weighting */
|
|
|
|
|
add_v3_v3v3(edge_normal, f1->no, f2->no);
|
|
|
|
|
normalize_v3(edge_normal);
|
|
|
|
|
mul_v3_fl(edge_normal, angle);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* can't do anything useful here!
|
|
|
|
|
Set the face index for a vert incase it gets a zero normal */
|
|
|
|
|
BM_SetIndex(e->v1, -1);
|
|
|
|
|
BM_SetIndex(e->v2, -1);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* only one face attached to that edge */
|
|
|
|
|
/* an edge without another attached- the weight on this is
|
|
|
|
|
* undefined, M_PI/2 is 90d in radians and that seems good enough */
|
|
|
|
|
copy_v3_v3(edge_normal, f1->no);
|
|
|
|
|
mul_v3_fl(edge_normal, M_PI/2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
add_v3_v3(e->v1->no, edge_normal);
|
|
|
|
|
add_v3_v3(e->v2->no, edge_normal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* normalize accumulated vertex normals*/
|
|
|
|
|
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
|
2011-10-11 05:18:33 +00:00
|
|
|
if (!BMO_TestFlag(bm, v, VERT_MARK)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-23 12:06:47 +00:00
|
|
|
if (BMO_TestFlag(bm, v, VERT_NONMAN)) {
|
|
|
|
|
/* use standard normals for vertices connected to non-manifold
|
|
|
|
|
edges */
|
|
|
|
|
BM_Vert_UpdateNormal(bm, v);
|
|
|
|
|
}
|
|
|
|
|
else if (normalize_v3(v->no) == 0.0f && BM_GetIndex(v) < 0) {
|
|
|
|
|
/* exceptional case, totally flat. use the normal
|
2011-10-11 05:18:33 +00:00
|
|
|
of any marked face around the vertex */
|
|
|
|
|
BM_ITER(f, &fiter, bm, BM_FACES_OF_VERT, v) {
|
|
|
|
|
if (BMO_TestFlag(bm, f, FACE_MARK)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2011-09-23 12:06:47 +00:00
|
|
|
}
|
2011-10-11 05:18:33 +00:00
|
|
|
copy_v3_v3(v->no, f->no);
|
2011-09-23 12:06:47 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void solidify_add_thickness(BMesh *bm, float dist)
|
|
|
|
|
{
|
|
|
|
|
BMFace *f;
|
|
|
|
|
BMVert *v;
|
|
|
|
|
BMLoop *l;
|
|
|
|
|
BMIter iter, loopIter;
|
|
|
|
|
float *vert_angles = MEM_callocN(sizeof(float) * bm->totvert * 2, "solidify"); /* 2 in 1 */
|
|
|
|
|
float *vert_accum = vert_angles + bm->totvert;
|
|
|
|
|
float angle;
|
|
|
|
|
int i, index;
|
|
|
|
|
float maxdist = dist * sqrtf(3.0f);
|
|
|
|
|
|
|
|
|
|
/* array for passing verts to angle_poly_v3 */
|
|
|
|
|
float **verts = NULL;
|
|
|
|
|
BLI_array_staticdeclare(verts, 16);
|
|
|
|
|
/* array for receiving angles from angle_poly_v3 */
|
|
|
|
|
float *angles = NULL;
|
|
|
|
|
BLI_array_staticdeclare(angles, 16);
|
|
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
|
|
|
|
|
BM_SetIndex(v, i++);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
|
|
|
|
|
if(!BMO_TestFlag(bm, f, FACE_MARK)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(l, &loopIter, bm, BM_LOOPS_OF_FACE, f) {
|
|
|
|
|
BLI_array_append(verts, l->v->co);
|
|
|
|
|
BLI_array_growone(angles);
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-23 13:04:01 +00:00
|
|
|
angle_poly_v3(angles, (const float **)verts, f->len);
|
2011-09-23 12:06:47 +00:00
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
BM_ITER(l, &loopIter, bm, BM_LOOPS_OF_FACE, f) {
|
|
|
|
|
v = l->v;
|
|
|
|
|
index = BM_GetIndex(v);
|
|
|
|
|
angle = angles[i];
|
|
|
|
|
vert_accum[index] += angle;
|
|
|
|
|
vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * angle;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_array_empty(verts);
|
|
|
|
|
BLI_array_empty(angles);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
|
|
|
|
|
index = BM_GetIndex(v);
|
|
|
|
|
if(vert_accum[index]) { /* zero if unselected */
|
|
|
|
|
float vdist = MIN2(maxdist, dist * vert_angles[index] / vert_accum[index]);
|
|
|
|
|
madd_v3_v3fl(v->co, v->no, vdist);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(vert_angles);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void bmesh_solidify_face_region_exec(BMesh *bm, BMOperator *op)
|
|
|
|
|
{
|
|
|
|
|
BMOperator extrudeop;
|
|
|
|
|
BMOperator reverseop;
|
|
|
|
|
float thickness;
|
|
|
|
|
|
|
|
|
|
thickness = BMO_Get_Float(op, "thickness");
|
|
|
|
|
|
|
|
|
|
/* Flip original faces (so the shell is extruded inward) */
|
|
|
|
|
BMO_Init_Op(&reverseop, "reversefaces");
|
|
|
|
|
BMO_CopySlot(op, &reverseop, "geom", "faces");
|
|
|
|
|
BMO_Exec_Op(bm, &reverseop);
|
|
|
|
|
BMO_Finish_Op(bm, &reverseop);
|
|
|
|
|
|
|
|
|
|
/* Extrude the region */
|
|
|
|
|
BMO_InitOpf(bm, &extrudeop, "extrudefaceregion alwayskeeporig=%i", 1);
|
|
|
|
|
BMO_CopySlot(op, &extrudeop, "geom", "edgefacein");
|
|
|
|
|
BMO_Exec_Op(bm, &extrudeop);
|
|
|
|
|
|
|
|
|
|
/* Push the verts of the extruded faces inward to create thickness */
|
|
|
|
|
BMO_Flag_Buffer(bm, &extrudeop, "geomout", FACE_MARK, BM_FACE);
|
2011-10-11 05:18:33 +00:00
|
|
|
calc_solidify_normals(bm);
|
2011-09-23 12:06:47 +00:00
|
|
|
solidify_add_thickness(bm, thickness);
|
|
|
|
|
|
|
|
|
|
BMO_CopySlot(&extrudeop, op, "geomout", "geomout");
|
|
|
|
|
|
|
|
|
|
BMO_Finish_Op(bm, &extrudeop);
|
|
|
|
|
}
|