Merged changes in the trunk up to revision 55357.
[blender.git] / source / blender / editors / mesh / editmesh_tools.c
index e82176b..36a1d30 100644 (file)
@@ -34,6 +34,7 @@
 #include "DNA_key_types.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
@@ -5780,3 +5781,130 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot)
                                BMO_SYMMETRIZE_NEGATIVE_X,
                                "Direction", "Which sides to copy from and to");
 }
+
+#ifdef WITH_FREESTYLE
+
+static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op)
+{
+       Object *obedit = CTX_data_edit_object(C);
+       Mesh *me = (Mesh *)obedit->data;
+       BMEditMesh *em = BMEdit_FromObject(obedit);
+       BMEdge *eed;
+       BMIter iter;
+       FreestyleEdge *fed;
+       int clear = RNA_boolean_get(op->ptr, "clear");
+
+       if (em == NULL)
+               return OPERATOR_FINISHED;
+
+       /* auto-enable Freestyle edge mark drawing */
+       if (clear == 0) {
+               me->drawflag |= ME_DRAW_FREESTYLE_EDGE;
+       }
+
+       if (!CustomData_has_layer(&em->bm->edata, CD_FREESTYLE_EDGE)) {
+               BM_data_layer_add(em->bm, &em->bm->edata, CD_FREESTYLE_EDGE);
+       }
+
+       if (clear) {
+               BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+                       if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+                               fed = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_FREESTYLE_EDGE);
+                               fed->flag &= ~FREESTYLE_EDGE_MARK;
+                       }
+               }
+       }
+       else {
+               BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+                       if (BM_elem_flag_test(eed, BM_ELEM_SELECT) && !BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+                               fed = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_FREESTYLE_EDGE);
+                               fed->flag |= FREESTYLE_EDGE_MARK;
+                       }
+               }
+       }
+
+       DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_mark_freestyle_edge(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Mark Freestyle Edge";
+       ot->description = "(un)mark selected edges as Freestyle feature edges";
+       ot->idname = "MESH_OT_mark_freestyle_edge";
+
+       /* api callbacks */
+       ot->exec = edbm_mark_freestyle_edge;
+       ot->poll = ED_operator_editmesh;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+}
+
+static int edbm_mark_freestyle_face_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit = CTX_data_edit_object(C);
+       Mesh *me = (Mesh *)obedit->data;
+       BMEditMesh *em = BMEdit_FromObject(obedit);
+       BMFace *efa;
+       BMIter iter;
+       FreestyleFace *ffa;
+       int clear = RNA_boolean_get(op->ptr, "clear");
+
+       if (em == NULL) return OPERATOR_FINISHED;
+
+       /* auto-enable Freestyle face mark drawing */
+       if (!clear) {
+               me->drawflag |= ME_DRAW_FREESTYLE_FACE;
+       }
+
+       if (!CustomData_has_layer(&em->bm->pdata, CD_FREESTYLE_FACE)) {
+               BM_data_layer_add(em->bm, &em->bm->pdata, CD_FREESTYLE_FACE);
+       }
+
+       if (clear) {
+               BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+                       if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+                               ffa = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_FREESTYLE_FACE);
+                               ffa->flag &= ~FREESTYLE_FACE_MARK;
+                       }
+               }
+       }
+       else {
+               BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+                       if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+                               ffa = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_FREESTYLE_FACE);
+                               ffa->flag |= FREESTYLE_FACE_MARK;
+                       }
+               }
+       }
+
+       DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Mark Freestyle Face";
+       ot->description = "(un)mark selected faces for exclusion from Freestyle feature edge detection";
+       ot->idname = "MESH_OT_mark_freestyle_face";
+
+       /* api callbacks */
+       ot->exec = edbm_mark_freestyle_face_exec;
+       ot->poll = ED_operator_editmesh;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+}
+
+#endif