Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2009-09-10 07:59:12 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-09-10 07:59:12 +0400
commit4c072f85d98d6ae7f1322314f8da8b3f2fb40f7d (patch)
tree41ef4c5a250cd770f2c20fe4ed83c3f92f56334a /source/blender
parentb0a1904d33a1c097a8e8fd56fe9b3c1d3a34ca55 (diff)
commit of transform pinning patch by Fabian Fricke (frigi). wip hotkey is enter/alt-enter to pin/unpin verts. pinned verts aren't affected by transform, e.g. grab, rotate, etc. this could probably work nicer for proportional editing, but that can be done later. also the UI for this probably needs reviewing and feedback. still, very nice patch by Fabian, something I for one will probably find very useful :)
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/bmesh/bmesh.h1
-rw-r--r--source/blender/bmesh/bmesh_marking.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c45
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c2
-rw-r--r--source/blender/editors/include/ED_mesh.h3
-rw-r--r--source/blender/editors/include/UI_resources.h3
-rw-r--r--source/blender/editors/interface/resources.c7
-rw-r--r--source/blender/editors/mesh/bmesh_tools.c121
-rw-r--r--source/blender/editors/mesh/mesh_intern.h2
-rw-r--r--source/blender/editors/mesh/mesh_ops.c10
-rw-r--r--source/blender/editors/space_view3d/drawobject.c151
-rw-r--r--source/blender/editors/transform/transform_conversions.c3
-rw-r--r--source/blender/makesdna/DNA_mesh_types.h2
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c5
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c10
18 files changed, 368 insertions, 9 deletions
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index e3518e77477..fac86f79e23 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -109,6 +109,7 @@ struct EditMesh;
#define BM_SMOOTH (1<<5)
#define BM_ACTIVE (1<<6)
#define BM_NONORMCALC (1<<7)
+#define BM_PINNED (1<<8)
typedef struct BMHeader {
struct BMHeader *next, *prev;
diff --git a/source/blender/bmesh/bmesh_marking.h b/source/blender/bmesh/bmesh_marking.h
index c7bf6c263aa..5b390bb8a01 100644
--- a/source/blender/bmesh/bmesh_marking.h
+++ b/source/blender/bmesh/bmesh_marking.h
@@ -8,6 +8,12 @@ typedef struct BMEditSelection
void *data;
} BMEditSelection;
+/* pinning code */
+void BM_Pin(BMesh *bm, void *element, int pin);
+void BM_Pin_Vert(BMesh *bm, BMVert *v, int pin);
+void BM_Pin_Edge(BMesh *bm, BMEdge *e, int pin);
+void BM_Pin_Face(BMesh *bm, BMFace *f, int pin);
+
/*geometry hiding code*/
void BM_Hide(BMesh *bm, void *element, int hide);
void BM_Hide_Vert(BMesh *bm, BMVert *v, int hide);
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index 25e863e7de2..d57f00ce608 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -542,6 +542,7 @@ int BMFlags_To_MEFlags(void *element) {
BMHeader *h = element;
int f = 0;
+ if (h->flag & BM_PINNED) f |= ME_PIN;
if (h->flag & BM_HIDDEN) f |= ME_HIDE;
if (h->type == BM_FACE) {
@@ -571,6 +572,7 @@ int BMFlags_To_MEFlags(void *element) {
*/
int MEFlags_To_BMFlags(int flag, int type) {
int f = 0;
+ if (flag & ME_PIN) f |= BM_PINNED;
if (type == BM_FACE) {
if (flag & ME_FACE_SEL) f |= BM_SELECT;
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 3a622bd0bbb..3d6a02e1160 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -532,6 +532,51 @@ void BM_validate_selections(BMesh *em)
}
}
+/***************** Pinning **************/
+
+#define SETPIN(ele) pin ? BM_SetHFlag(ele, BM_PINNED) : BM_ClearHFlag(ele, BM_PINNED);
+
+
+void BM_Pin_Vert(BMesh *bm, BMVert *v, int pin)
+{
+ SETPIN(v);
+}
+
+void BM_Pin_Edge(BMesh *bm, BMEdge *e, int pin)
+{
+ SETPIN(e->v1);
+ SETPIN(e->v2);
+}
+
+void BM_Pin_Face(BMesh *bm, BMFace *f, int pin)
+{
+ BMIter vfiter;
+ BMVert *vf;
+
+ BM_ITER(vf, &vfiter, bm, BM_VERTS_OF_FACE, f) {
+ SETPIN(vf);
+ }
+}
+
+void BM_Pin(BMesh *bm, void *element, int pin)
+{
+ BMHeader *h = element;
+
+ switch (h->type) {
+ case BM_VERT:
+ BM_Pin_Vert(bm, element, pin);
+ break;
+ case BM_EDGE:
+ BM_Pin_Edge(bm, element, pin);
+ break;
+ case BM_FACE:
+ BM_Pin_Face(bm, element, pin);
+ break;
+ }
+}
+
+
+
/***************** Mesh Hiding stuff *************/
#define SETHIDE(ele) hide ? BM_SetHFlag(ele, BM_HIDDEN) : BM_ClearHFlag(ele, BM_HIDDEN);
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index ed2c2f20789..317d36dad0f 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -194,8 +194,6 @@ void BM_Compute_Normals(BMesh *bm)
unsigned int maxlength = 0;
float (*projectverts)[3];
- //return;
-
/*first, find out the largest face in mesh*/
for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){
if (BM_TestHFlag(f, BM_HIDDEN))
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 8847c9fa52c..9dde4bfd83d 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -111,6 +111,9 @@ void EDBM_editselection_plane(struct BMEditMesh *em, float *plane, struct BMEdit
void EDBM_editselection_normal(float *normal, struct BMEditSelection *ese);
int EDBM_vertColorCheck(struct BMEditMesh *em);
+void EDBM_pin_mesh(struct BMEditMesh *em, int swap);
+void EDBM_unpin_mesh(struct BMEditMesh *em, int swap);
+
void EDBM_hide_mesh(struct BMEditMesh *em, int swap);
void EDBM_reveal_mesh(struct BMEditMesh *em);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 1ae3634c73b..6e7814ad0f8 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -202,6 +202,9 @@ enum {
TH_DOPESHEET_CHANNELOB,
TH_DOPESHEET_CHANNELSUBOB,
+
+ TH_PIN,
+ TH_PIN_OPAC,
};
/* XXX WARNING: previous is saved in file, so do not change order! */
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 8aaede7515a..d21aabb5e2d 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -355,6 +355,10 @@ char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
case TH_DOPESHEET_CHANNELSUBOB:
cp= ts->ds_subchannel;
break;
+ case TH_PIN:
+ cp= ts->pin; break;
+ case TH_PIN_OPAC:
+ cp= &ts->pin_opac; break;
}
}
@@ -475,6 +479,9 @@ void ui_theme_init_userdef(void)
SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80); // alpha 80 is not meant editable, used for wire+action draw
+
+ SETCOL(btheme->tv3d.pin, 115, 171, 209, 255);
+ btheme->tv3d.pin_opac = 40;
/* space buttons */
diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c
index 990198c9216..e02707c7a67 100644
--- a/source/blender/editors/mesh/bmesh_tools.c
+++ b/source/blender/editors/mesh/bmesh_tools.c
@@ -1703,6 +1703,127 @@ void MESH_OT_edge_rotate(wmOperatorType *ot)
RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CW, "direction", "direction to rotate edge around.");
}
+/* pinning code */
+
+/* swap is 0 or 1, if 1 it pins not selected */
+void EDBM_pin_mesh(BMEditMesh *em, int swap)
+{
+ BMIter iter;
+ BMHeader *h;
+ int itermode;
+
+ if(em==NULL) return;
+
+ if (em->selectmode & SCE_SELECT_VERTEX)
+ itermode = BM_VERTS_OF_MESH;
+ else if (em->selectmode & SCE_SELECT_EDGE)
+ itermode = BM_EDGES_OF_MESH;
+ else
+ itermode = BM_FACES_OF_MESH;
+
+ BM_ITER(h, &iter, em->bm, itermode, NULL) {
+ if (BM_TestHFlag(h, BM_SELECT) ^ swap)
+ BM_Pin(em->bm, h, 1);
+ }
+
+ EDBM_selectmode_flush(em);
+}
+
+static int pin_mesh_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit= CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
+ Mesh *me= ((Mesh *)obedit->data);
+
+ me->drawflag |= ME_DRAW_PINS;
+
+ EDBM_pin_mesh(em, RNA_boolean_get(op->ptr, "unselected"));
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_pin(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Pin Selection";
+ ot->idname= "MESH_OT_pin";
+
+ /* api callbacks */
+ ot->exec= pin_mesh_exec;
+ ot->poll= ED_operator_editmesh;
+ ot->description= "Pin (un)selected vertices, edges or faces.";
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Pin unselected rather than selected.");
+}
+
+/* swap is 0 or 1, if 1 it unhides not selected */
+void EDBM_unpin_mesh(BMEditMesh *em, int swap)
+{
+ BMIter iter;
+ BMHeader *ele;
+ int i, types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
+ int sels[3] = {1, !(em->selectmode & SCE_SELECT_VERTEX), !(em->selectmode & SCE_SELECT_VERTEX | SCE_SELECT_EDGE)};
+ int itermode;
+
+ if(em==NULL) return;
+
+ if (em->selectmode & SCE_SELECT_VERTEX)
+ itermode = BM_VERTS_OF_MESH;
+ else if (em->selectmode & SCE_SELECT_EDGE)
+ itermode = BM_EDGES_OF_MESH;
+ else
+ itermode = BM_FACES_OF_MESH;
+
+ BM_ITER(ele, &iter, em->bm, itermode, NULL) {
+ if (BM_TestHFlag(ele, BM_SELECT) ^ swap)
+ BM_Pin(em->bm, ele, 0);
+ }
+
+ EDBM_selectmode_flush(em);
+}
+
+static int unpin_mesh_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit= CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
+ Mesh *me= ((Mesh *)obedit->data);
+
+ EDBM_unpin_mesh(em, RNA_boolean_get(op->ptr, "unselected"));
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_unpin(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Unpin Selection";
+ ot->idname= "MESH_OT_unpin";
+ ot->description= "Unpin (un)selected vertices, edges or faces.";
+
+ /* api callbacks */
+ ot->exec= unpin_mesh_exec;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Unpin unselected rather than selected.");
+}
+
+
/* swap is 0 or 1, if 1 it hides not selected */
void EDBM_hide_mesh(BMEditMesh *em, int swap)
{
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 0c2131e8098..37803d4c00a 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -205,6 +205,8 @@ void MESH_OT_select_inverse(struct wmOperatorType *ot);
void MESH_OT_select_non_manifold(struct wmOperatorType *ot);
void MESH_OT_select_linked(struct wmOperatorType *ot);
void MESH_OT_select_linked_pick(struct wmOperatorType *ot);
+void MESH_OT_pin(struct wmOperatorType *ot);
+void MESH_OT_unpin(struct wmOperatorType *ot);
void MESH_OT_hide(struct wmOperatorType *ot);
void MESH_OT_reveal(struct wmOperatorType *ot);
void MESH_OT_select_by_number_vertices(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 1498f3573f1..9570ae16a4b 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -204,6 +204,8 @@ static int specials_invoke(bContext *C, wmOperator *op, wmEvent *event)
uiItemO(layout, "Remove Doubles", 0, "MESH_OT_remove_doubles");
uiItemO(layout, "Hide", 0, "MESH_OT_hide");
uiItemO(layout, "Reveal", 0, "MESH_OT_reveal");
+ uiItemO(layout, "Pin", 0, "MESH_OT_pin");
+ uiItemO(layout, "Unpin", 0, "MESH_OT_unpin");
uiItemO(layout, "Select Inverse", 0, "MESH_OT_select_inverse");
uiItemO(layout, NULL, 0, "MESH_OT_flip_normals");
uiItemO(layout, "Smooth", 0, "MESH_OT_vertices_smooth");
@@ -248,6 +250,8 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_select_linked_pick);
WM_operatortype_append(MESH_OT_select_random);
WM_operatortype_append(MESH_OT_selection_type);
+ WM_operatortype_append(MESH_OT_pin);
+ WM_operatortype_append(MESH_OT_unpin);
WM_operatortype_append(MESH_OT_hide);
WM_operatortype_append(MESH_OT_reveal);
WM_operatortype_append(MESH_OT_select_by_number_vertices);
@@ -396,6 +400,12 @@ void ED_keymap_mesh(wmWindowManager *wm)
/* selection mode */
WM_keymap_add_item(keymap, "MESH_OT_selection_type", TABKEY, KM_PRESS, KM_CTRL, 0);
+ /* pin */
+ WM_keymap_add_item(keymap, "MESH_OT_pin", RETKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_pin", RETKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1);
+ WM_keymap_add_item(keymap, "MESH_OT_unpin", RETKEY, KM_PRESS, KM_ALT, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_unpin", RETKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "unselected", 1);
+
/* hide */
WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "unselected", 1);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 114d1fb503a..d432cac248f 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -1528,6 +1528,62 @@ static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
glEnd();
}
+/* check if all verts of the face are pinned */
+static int check_pinned_face(BMesh *bm, BMFace *efa)
+{
+ BMIter vfiter;
+ BMVert *v;
+ int vcount = 0;
+
+ BM_ITER(v, &vfiter, bm, BM_VERTS_OF_FACE, efa) {
+ if(BM_TestHFlag(v, BM_PINNED)) vcount ++;
+ }
+
+ if( vcount == efa->len) return 1;
+ return 0;
+}
+
+static void draw_dm_vert_pins__mapFunc(void *userData, int index, float *co)
+{
+ struct {BMEditMesh *em; Mesh *me;} *data = userData;
+ BMVert *eve = EDBM_get_vert_for_index(data->em, index);
+ BMFace *fv;
+ BMIter fviter;
+ float vsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
+ int small=0;
+
+ if (!BM_TestHFlag(eve, BM_HIDDEN)) {
+ if (BM_TestHFlag(eve, BM_PINNED)) {
+ BM_ITER(fv, &fviter, data->em->bm, BM_FACES_OF_VERT, eve) {
+ small += check_pinned_face(data->em->bm, fv);
+ }
+ if(small == 0) {
+ bglEnd();
+ glPointSize(vsize*1.5);
+ glBegin(GL_POINTS);
+ glVertex3fv(co);
+ }
+ else {
+ bglEnd();
+ glPointSize(vsize*0.5);
+ glBegin(GL_POINTS);
+ glVertex3fv(co);
+ }
+ }
+ }
+}
+
+static void draw_dm_vert_pins(BMEditMesh *em, DerivedMesh *dm, Mesh *me)
+{
+ struct { BMEditMesh *em; Mesh *me;} data;
+
+ data.em = em;
+ data.me = me;
+
+ dm->foreachMappedVert(dm, draw_dm_vert_pins__mapFunc, &data);
+ glEnd();
+}
+
/* Draw verts with color set based on selection */
static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
@@ -1661,6 +1717,55 @@ static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm)
dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em);
}
+/* Draw only pinned edges */
+static int draw_dm_edges_pins__setDrawOptions(void *userData, int index)
+{
+ struct {BMEditMesh *em; Mesh *me;} *data = userData;
+
+ BMEdge *eed = EDBM_get_edge_for_index(data->em, index);
+ BMIter feiter;
+ BMFace *fe;
+
+ int fcount, fpcount = 0;
+ int pin = 0;
+
+ /* If pinned faces are drawn then only draw pinned edges at the borders.
+ This looks way better and the user still has all the info he needs. */
+ if(data->me->drawflag & ME_DRAW_PINS) {
+ if( BM_TestHFlag(eed->v1, BM_PINNED) && BM_TestHFlag(eed->v2, BM_PINNED) ) {
+ pin = 1;
+
+ fcount = 0;
+ BM_ITER(fe, &feiter, data->em->bm, BM_FACES_OF_EDGE, eed) {
+ fcount ++;
+ fpcount += check_pinned_face(data->em->bm, fe);
+ }
+ }
+ }
+ else {
+ pin = BM_TestHFlag(eed->v1, BM_PINNED) && BM_TestHFlag(eed->v2, BM_PINNED);
+ }
+
+ if( !BM_TestHFlag(eed, BM_HIDDEN)) {
+ /* Edges with at least one adherent pinned face are considered borders.
+ If there are more than two adherent faces overall of which at least two are pinned it's also consideres a border. */
+ if( fpcount == 2 && fcount <= 2) {
+ return 0; }
+ else {
+ return pin; }
+ }
+}
+
+static void draw_dm_edges_pins(BMEditMesh *em, DerivedMesh *dm, Mesh *me)
+{
+ struct { BMEditMesh *em; Mesh *me;} data;
+
+ data.em = em;
+ data.me = me;
+
+ dm->drawMappedEdges(dm, draw_dm_edges_pins__setDrawOptions, &data);
+}
+
/* Draw only sharp edges */
static int draw_dm_edges_sharp__setDrawOptions(void *userData, int index)
{
@@ -1678,18 +1783,35 @@ static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm)
* return 2 for the active face so it renders with stipple enabled */
static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *drawSmooth_r)
{
- struct { unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; } *data = userData;
+ struct { unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} *data = userData;
BMFace *efa = EDBM_get_face_for_index(data->em, index);
unsigned char *col;
+ BMIter vfiter;
+ BMVert *v;
+ int vcount, pin=0;
+ int opac = UI_GetThemeValue(TH_PIN_OPAC);
if (!BM_TestHFlag(efa, BM_HIDDEN)) {
+
+ /* Check if all verts of a face are pinned. If so, then display it in a darker shade. */
+ if(data->me->drawflag & ME_DRAW_PINS)
+ pin = check_pinned_face(data->em->bm, efa);
+
if (efa == data->efa_act) {
- glColor4ubv(data->cols[2]);
+ if(pin==0) { glColor4ubv(data->cols[2]); }
+ else {
+ col = data->cols[2];
+ glColor4ub(col[0]-col[0]*0.9, col[1]-col[1]*0.9, col[2]-col[2]*0.9, opac*2.55);
+ }
+
return 2; /* stipple */
} else {
col = data->cols[BM_TestHFlag(efa, BM_SELECT)?1:0];
if (col[3]==0) return 0;
- glColor4ubv(col);
+
+ if(pin==0) { glColor4ubv(col); }
+ else { glColor4ub(col[0]-col[0]*0.9, col[1]-col[1]*0.9, col[2]-col[2]*0.9, opac*2.55); }
+
return 1;
}
}
@@ -1698,15 +1820,16 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *dra
/* also draws the active face */
static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
- unsigned char *selCol, unsigned char *actCol, BMFace *efa_act)
+ unsigned char *selCol, unsigned char *actCol, BMFace *efa_act, Mesh *me)
{
- struct { unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; } data;
+ struct { unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} data;
data.cols[0] = baseCol;
data.em = em;
data.cols[1] = selCol;
data.cols[2] = actCol;
data.efa_act = efa_act;
+ data.me = me;
dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
}
@@ -2168,7 +2291,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
if CHECK_OB_DRAWTEXTURE(v3d, dt)
col1[3] = 0;
- draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
+ draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me);
glDisable(GL_BLEND);
glDepthMask(1); // restore write in zbuffer
@@ -2183,7 +2306,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
glEnable(GL_BLEND);
glDepthMask(0); // disable write in zbuffer, needed for nice transp
- draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
+ draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me);
glDisable(GL_BLEND);
glDepthMask(1); // restore write in zbuffer
@@ -2224,6 +2347,16 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
if(me->drawflag & ME_DRAWBWEIGHTS) {
draw_dm_bweights(em, scene, cageDM);
}
+
+ if(me->drawflag & ME_DRAW_PINS) {
+ UI_ThemeColor(TH_PIN);
+ glLineWidth(2);
+
+ draw_dm_edges_pins(em, cageDM, me);
+
+ glColor3ub(0,0,0);
+ glLineWidth(1);
+ }
draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act);
}
@@ -2240,6 +2373,10 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
UI_ThemeColor(TH_NORMAL);
draw_dm_vert_normals(em, scene, cageDM);
}
+ if(me->drawflag & ME_DRAW_PINS) {
+ UI_ThemeColor(TH_PIN);
+ draw_dm_vert_pins(em, cageDM, me);
+ }
if(me->drawflag & (ME_DRAW_EDGELEN|ME_DRAW_FACEAREA|ME_DRAW_EDGEANG))
draw_em_measure_stats(v3d, rv3d, ob, em, &scene->unit);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index f7acab46c4b..22d12477624 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2281,6 +2281,9 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
if(propmode || selstate[a]) {
VertsToTransData(t, tob, bm, eve);
+ /* pinned */
+ if(BM_TestHFlag(eve,BM_PINNED)) tob->flag |= TD_SKIP;
+
/* selected */
if(selstate[a]) tob->flag |= TD_SELECTED;
diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h
index 52323913ee4..74e0a25a26f 100644
--- a/source/blender/makesdna/DNA_mesh_types.h
+++ b/source/blender/makesdna/DNA_mesh_types.h
@@ -162,6 +162,8 @@ typedef struct TFace {
#define ME_DRAW_FACEAREA (1 << 11)
#define ME_DRAW_EDGEANG (1 << 12)
+#define ME_DRAW_PINS (1 << 13)
+
/* old global flags:
#define G_DRAWEDGES (1 << 18)
#define G_DRAWFACES (1 << 7)
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 27cd63fd7db..9bd495b1e39 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -210,6 +210,7 @@ typedef struct PartialVisibility {
#define ME_SPHERETEST 2
#define ME_SPHERETEMP 4
#define ME_HIDE 16
+#define ME_PIN 64
#define ME_VERT_MERGED (1<<6)
/* medge->flag (1=SELECT)*/
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 100f55ffe33..54d03fe085f 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -218,6 +218,9 @@ typedef struct ThemeSpace {
char hpad[3];
char pad[4];
+
+ char pin[4];
+ int pin_opac;
} ThemeSpace;
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 5f47b3d1d95..c930f59fe35 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -1412,6 +1412,11 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Face Area", "Displays the area of selected faces");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+ prop= RNA_def_property(srna, "draw_pins", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAW_PINS);
+ RNA_def_property_ui_text(prop, "Draw Pins", "Displays pinned mesh elements");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
+
rna_def_texmat_common(srna, "rna_Mesh_texspace_editable");
RNA_api_mesh(srna);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 946aa1cd682..d169edd65dd 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -679,6 +679,16 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+ prop= RNA_def_property(srna, "pin", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Pin", "");
+ RNA_def_property_update(prop, NC_WINDOW, NULL);
+
+ prop= RNA_def_property(srna, "pin_opac", PROP_INT, PROP_PERCENTAGE);
+ RNA_def_property_range(prop, 0, 100);
+ RNA_def_property_ui_text(prop, "Pin Face Opacity", "");
+ RNA_def_property_update(prop, NC_WINDOW, NULL);
}
static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)