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:
Diffstat (limited to 'source/blender/editors/mesh/editmesh_tools.c')
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c262
1 files changed, 218 insertions, 44 deletions
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 35fc5c1e3bc..5d6d9e314f2 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -37,8 +37,6 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include <math.h>
#include <float.h>
-#include "MEM_guardedalloc.h"
-
#include "BLO_sys_types.h" // for intptr_t support
#include "DNA_meshdata_types.h"
@@ -47,6 +45,8 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include "DNA_scene_types.h"
#include "DNA_key_types.h"
+#include "MEM_guardedalloc.h"
+
#include "RNA_define.h"
#include "RNA_access.h"
@@ -59,19 +59,13 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include "BLI_heap.h"
#include "BKE_context.h"
-#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_key.h"
-#include "BKE_library.h"
#include "BKE_mesh.h"
-#include "BKE_object.h"
-#include "BKE_utildefines.h"
#include "BKE_bmesh.h"
#include "BKE_report.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -80,6 +74,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_view3d.h"
+#include "ED_object.h"
#include "mesh_intern.h"
@@ -481,20 +476,19 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
- /*char msg[100];*/
- /*int cnt =*/ removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit"));
- /*XXX this messes up last operator panel
- if(cnt)
- {
- sprintf(msg, "Removed %d vertices", cnt);
- BKE_report(op->reports, RPT_INFO, msg);
- }*/
+ int count = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit"));
+
+ if(count) {
+ recalc_editnormals(em);
- DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+ DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+ }
+ BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count);
BKE_mesh_end_editmesh(obedit->data, em);
+
return OPERATOR_FINISHED;
}
@@ -648,8 +642,7 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op, sh
* This shouldn't be necessary, derived queries should be
* automatically building this data if invalid. Or something.
*/
-// DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
- object_handle_update(scene, obedit);
+ DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
/* individual faces? */
// BIF_TransformSetUndo("Extrude");
@@ -661,7 +654,7 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op, sh
// initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR);
if(transmode=='n') {
mul_m4_v3(obedit->obmat, nor);
- sub_v3_v3v3(nor, nor, obedit->obmat[3]);
+ sub_v3_v3(nor, obedit->obmat[3]);
// BIF_setSingleAxisConstraint(nor, "along normal");
}
// Transform();
@@ -798,6 +791,7 @@ void MESH_OT_extrude(wmOperatorType *ot)
/* properties */
prop= RNA_def_enum(ot->srna, "type", extrude_items, 0, "Type", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_enum_funcs(prop, extrude_itemf);
ot->prop= prop;
}
@@ -1034,11 +1028,11 @@ void MESH_OT_spin(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* props */
- RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, INT_MAX);
+ RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 128);
RNA_def_boolean(ot->srna, "dupli", 0, "Dupli", "Make Duplicates");
RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f);
- RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
}
@@ -1145,7 +1139,7 @@ void MESH_OT_screw(wmOperatorType *ot)
RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 256);
RNA_def_int(ot->srna, "turns", 1, 0, INT_MAX, "Turns", "Turns", 0, 256);
- RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
}
@@ -1447,7 +1441,7 @@ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int
vec1[0]= fac*(float)(0.5-BLI_drand());
vec1[1]= fac*(float)(0.5-BLI_drand());
vec1[2]= fac*(float)(0.5-BLI_drand());
- add_v3_v3v3(co, co, vec1);
+ add_v3_v3(co, vec1);
}
}
@@ -2729,7 +2723,7 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float
}
}
- gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "subdivideedgenum gh");
// If we are knifing, We only need the selected edges that were cut, so deselect if it was not cut
if(beauty & B_KNIFE) {
@@ -3094,21 +3088,21 @@ static void givequadverts(EditFace *efa, EditFace *efa1, EditVert **v1, EditVert
if VTEST(efa1, 1, efa) {
*v3= efa1->v1;
- *v4= efa1->v2;
+ *v4= (efa1->v2 == *v2)? efa1->v3: efa1->v2;
vindex[2]= 0;
- vindex[3]= 1;
+ vindex[3]= (efa1->v2 == *v2)? 2: 1;
}
else if VTEST(efa1, 2, efa) {
*v3= efa1->v2;
- *v4= efa1->v3;
+ *v4= (efa1->v3 == *v2)? efa1->v1: efa1->v3;
vindex[2]= 1;
- vindex[3]= 2;
+ vindex[3]= (efa1->v3 == *v2)? 0: 2;
}
else if VTEST(efa1, 3, efa) {
*v3= efa1->v3;
- *v4= efa1->v1;
+ *v4= (efa1->v1 == *v2)? efa1->v2: efa1->v1;
vindex[2]= 2;
- vindex[3]= 0;
+ vindex[3]= (efa1->v1 == *v2)? 1: 0;
}
else
*v3= *v4= NULL;
@@ -3417,7 +3411,7 @@ void join_triangles(EditMesh *em)
efaa= (EVPtr *)eed->tmp.p;
v1 = v2 = v3 = v4 = NULL;
givequadverts(efaa[0], efaa[1], &v1, &v2, &v3, &v4, vindex);
- if((v1 && v2 && v3 && v4) && (exist_face(em, v1, v2, v3, v4)==0)){ /*exist_face is very slow! Needs to be adressed.*/
+ if((v1 && v2 && v3 && v4) && (exist_face(em, v1, v2, v3, v4)==0)){ /*exist_face is very slow! Needs to be addressed.*/
/*flag for delete*/
eed->f1 |= T2QDELETE;
/*create new quad and select*/
@@ -3657,10 +3651,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], -1);
}
else if(fac1 == 4 && fac2 == 3) {
- if(dir == DIRECTION_CW) {
+ if(dir == DIRECTION_CCW) {
newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], p[0][3], 4+p[1][1]);
newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], -1);
- } else if (dir == DIRECTION_CCW) {
+ } else if (dir == DIRECTION_CW) {
newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][2], 4+p[1][1], p[0][0], p[0][1]);
newFace[1]= EM_face_from_faces(em, face[1], face[0], 4+p[0][2], p[1][0], p[1][1], -1);
@@ -3669,10 +3663,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
}
}
else if(fac1 == 3 && fac2 == 4) {
- if(dir == DIRECTION_CW) {
+ if(dir == DIRECTION_CCW) {
newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], 4+p[1][1], -1);
newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], p[1][3], 4+p[0][1]);
- } else if (dir == DIRECTION_CCW) {
+ } else if (dir == DIRECTION_CW) {
newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][0], p[0][1], 4+p[1][2], -1);
newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], 4+p[0][2]);
@@ -3682,10 +3676,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
}
else if(fac1 == 4 && fac2 == 4) {
- if(dir == DIRECTION_CW) {
+ if(dir == DIRECTION_CCW) {
newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], p[0][3], 4+p[1][1]);
newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], p[1][3], 4+p[0][1]);
- } else if (dir == DIRECTION_CCW) {
+ } else if (dir == DIRECTION_CW) {
newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][2], p[0][3], 4+p[1][1], 4+p[1][2]);
newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][2], p[1][3], 4+p[0][1], 4+p[0][2]);
@@ -3696,7 +3690,7 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
else
return; /* This should never happen */
- if(dir == DIRECTION_CW || (fac1 == 3 && fac2 == 3)) {
+ if(dir == DIRECTION_CCW || (fac1 == 3 && fac2 == 3)) {
verts[0][p[0][1]]->f |= SELECT;
verts[1][p[1][1]]->f |= SELECT;
}
@@ -4091,7 +4085,7 @@ useless:
// populate the SlideVerts
- vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EdgeSlide gh");
look = vertlist;
while(look) {
i=0;
@@ -4259,7 +4253,7 @@ useless:
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
- uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EdgeSlideUV gh");
for(ev=em->verts.first;ev;ev=ev->next) {
ev->tmp.l = 0;
@@ -5162,7 +5156,7 @@ static int blend_from_shape_exec(bContext *C, wmOperator *op)
if(add) {
mul_v3_fl(co, blend);
- add_v3_v3v3(eve->co, eve->co, co);
+ add_v3_v3(eve->co, co);
}
else
interp_v3_v3v3(eve->co, eve->co, co, blend);
@@ -5778,7 +5772,7 @@ static void em_snap_to_center(EditMesh *em)
for (eve=em->verts.first; eve; eve=eve->next) {
if (eve->f & SELECT) {
- add_v3_v3v3(cent, cent, eve->co);
+ add_v3_v3(cent, eve->co);
i++;
}
}
@@ -5863,6 +5857,7 @@ static int merge_exec(bContext *C, wmOperator *op)
if(!count)
return OPERATOR_CANCELLED;
+ recalc_editnormals(em);
BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s.", count, (count==1)?"ex":"ices");
@@ -6174,6 +6169,7 @@ static int region_to_loop(bContext *C, wmOperator *op)
}
em->selectmode = SCE_SELECT_EDGE;
+ CTX_data_tool_settings(C)->selectmode= em->selectmode;
EM_selectmode_set(em);
BKE_mesh_end_editmesh(obedit->data, em);
@@ -7080,6 +7076,184 @@ void MESH_OT_beautify_fill(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+/* ********************** SORT FACES ******************* */
+
+static void permutate(void *list, int num, int size, int *index)
+{
+ void *buf;
+ int len;
+ int i;
+
+ len = num * size;
+
+ buf = MEM_mallocN(len, "permutate");
+ memcpy(buf, list, len);
+
+ for (i = 0; i < num; i++) {
+ memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size);
+ }
+ MEM_freeN(buf);
+}
+
+/* sort faces on view axis */
+static float *face_sort_floats;
+static int float_sort(const void *v1, const void *v2)
+{
+ float x1, x2;
+
+ x1 = face_sort_floats[((int *) v1)[0]];
+ x2 = face_sort_floats[((int *) v2)[0]];
+
+ if( x1 > x2 ) return 1;
+ else if( x1 < x2 ) return -1;
+ return 0;
+}
+
+
+static int sort_faces_exec(bContext *C, wmOperator *op)
+{
+ RegionView3D *rv3d= ED_view3d_context_rv3d(C);
+ View3D *v3d= CTX_wm_view3d(C);
+ Object *ob= CTX_data_edit_object(C);
+ Scene *scene= CTX_data_scene(C);
+ Mesh *me;
+ CustomDataLayer *layer;
+ int i, *index;
+ int event;
+ float reverse = 1;
+ // XXX int ctrl= 0;
+
+ if (!v3d) return OPERATOR_CANCELLED;
+
+ /* This operator work in Object Mode, not in edit mode.
+ * After talk with Cambell we agree that there is no point to port this to EditMesh right now.
+ * so for now, we just exit_editmode and enter_editmode at the end of this function.
+ */
+ ED_object_exit_editmode(C, EM_FREEDATA);
+
+ me= ob->data;
+ if(me->totface==0) {
+ ED_object_enter_editmode(C, 0);
+ return OPERATOR_FINISHED;
+ }
+
+ event= RNA_enum_get(op->ptr, "type");
+
+ // XXX
+ //if(ctrl)
+ // reverse = -1;
+
+ /* create index list */
+ index= (int *)MEM_mallocN(sizeof(int) * me->totface, "sort faces");
+ for (i = 0; i < me->totface; i++) {
+ index[i] = i;
+ }
+
+ face_sort_floats = (float *) MEM_mallocN(sizeof(float) * me->totface, "sort faces float");
+
+ /* sort index list instead of faces itself
+ * and apply this permutation to all face layers
+ */
+ if (event == 5) {
+ /* Random */
+ for(i=0; i<me->totface; i++) {
+ face_sort_floats[i] = BLI_frand();
+ }
+ qsort(index, me->totface, sizeof(int), float_sort);
+ } else {
+ MFace *mf;
+ float vec[3];
+ float mat[4][4];
+ float cur[3];
+
+ if (event == 1)
+ mul_m4_m4m4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */
+ else if (event == 2) { /* sort from cursor */
+ if( v3d && v3d->localvd ) {
+ VECCOPY(cur, v3d->cursor);
+ } else {
+ VECCOPY(cur, scene->cursor);
+ }
+ invert_m4_m4(mat, OBACT->obmat);
+ mul_m4_v3(mat, cur);
+ }
+
+ mf= me->mface;
+
+ for(i=0; i<me->totface; i++, mf++) {
+ if (event==3) {
+ face_sort_floats[i] = ((float)mf->mat_nr)*reverse;
+ } else if (event==4) {
+ /*selected first*/
+ if (mf->flag & ME_FACE_SEL)
+ face_sort_floats[i] = 0.0;
+ else
+ face_sort_floats[i] = reverse;
+ } else {
+ /* find the faces center */
+ add_v3_v3v3(vec, (me->mvert+mf->v1)->co, (me->mvert+mf->v2)->co);
+ if (mf->v4) {
+ add_v3_v3(vec, (me->mvert+mf->v3)->co);
+ add_v3_v3(vec, (me->mvert+mf->v4)->co);
+ mul_v3_fl(vec, 0.25f);
+ } else {
+ add_v3_v3(vec, (me->mvert+mf->v3)->co);
+ mul_v3_fl(vec, 1.0f/3.0f);
+ } /* done */
+
+ if (event == 1) { /* sort on view axis */
+ mul_m4_v3(mat, vec);
+ face_sort_floats[i] = vec[2] * reverse;
+ } else if(event == 2) { /* distance from cursor*/
+ face_sort_floats[i] = len_v3v3(cur, vec) * reverse; /* back to front */
+ }
+ }
+ }
+ qsort(index, me->totface, sizeof(int), float_sort);
+ }
+
+ MEM_freeN(face_sort_floats);
+ for(i = 0; i < me->fdata.totlayer; i++) {
+ layer = &me->fdata.layers[i];
+ permutate(layer->data, me->totface, CustomData_sizeof(layer->type), index);
+ }
+
+ MEM_freeN(index);
+ DAG_id_flush_update(ob->data, OB_RECALC_DATA);
+
+ /* Return to editmode. */
+ ED_object_enter_editmode(C, 0);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_sort_faces(wmOperatorType *ot)
+{
+ static EnumPropertyItem type_items[]= {
+ { 1, "VIEW_AXIS", 0, "View Axis", "" },
+ { 2, "CURSOR_DISTANCE", 0, "Cursor Distance", "" },
+ { 3, "MATERIAL", 0, "Material", "" },
+ { 4, "SELECTION", 0, "Selection", "" },
+ { 5, "RANDOMIZE", 0, "Randomize", "" },
+ { 0, NULL, 0, NULL, NULL }};
+
+ /* identifiers */
+ ot->name= "Sort Faces"; // XXX (Ctrl to reverse)%t|
+ ot->description= "The faces of the active Mesh Object are sorted, based on the current view.";
+ ot->idname= "MESH_OT_sort_faces";
+
+ /* api callbacks */
+ ot->invoke= WM_menu_invoke;
+ ot->exec= sort_faces_exec;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop= RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
+}
+
/********************** Quad/Tri Operators *************************/
static int quads_convert_to_tris_exec(bContext *C, wmOperator *op)