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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-02-07 04:27:46 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-02-07 04:27:46 +0300
commit591ab657d609821b891303f638f9a482a8370640 (patch)
treed2989efa86811aef84e9d60301f587e58acfea97 /source/blender/editors/uvedit/uvedit_unwrap_ops.c
parentd3dd4f6a866ed0a28caa1e7c5a5011901d78fdcd (diff)
2.5: UV Editor, more operators.
Border Select Circle Select Pin Select Pinned Unwrap Minimize Stretch Pack Islands Average Islands Scale Snap Cursor Snap Selection
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_unwrap_ops.c')
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c406
1 files changed, 282 insertions, 124 deletions
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index de5838823d1..c7e0dfd7bc7 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -40,6 +40,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
+#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
@@ -53,12 +54,44 @@
#include "PIL_time.h"
#include "ED_mesh.h"
+#include "ED_screen.h"
#include "ED_uvedit.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "uvedit_intern.h"
#include "uvedit_parametrizer.h"
-/* Parametrizer */
+static void ED_uvedit_create_uvs(EditMesh *em)
+{
+#if 0
+ if (em && em->faces.first)
+ EM_add_data_layer(&em->fdata, CD_MTFACE);
+
+ if (!ED_uvedit_test(obedit))
+ return;
+
+ if (G.sima && G.sima->image) /* this is a bit of a kludge, but assume they want the image on their mesh when UVs are added */
+ image_changed(G.sima, G.sima->image);
+
+ /* select new UV's */
+ if ((G.sima==0 || G.sima->flag & SI_SYNC_UVSEL)==0) {
+ EditFace *efa;
+ MTFace *tf;
+ for(efa=em->faces.first; efa; efa=efa->next) {
+ tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ simaFaceSel_Set(efa, tf);
+ }
+ }
+#endif
+}
+
+/****************** Parametrizer Conversion ***************/
+
ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, short fill, short sel)
{
ParamHandle *handle;
@@ -70,13 +103,14 @@ ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit,
handle = param_construct_begin();
- if ((scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0) {
+ if((scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0) {
efa = EM_get_actFace(em, 1);
if (efa) {
float aspx = 1.0f, aspy= 1.0f;
// XXX MTFace *tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
// XXX image_final_aspect(tf->tpage, &aspx, &aspy);
+ // XXX get_space_image_aspect(sima, &aspx, &aspy);
if (aspx!=aspy)
param_aspect_ratio(handle, aspx, aspy);
@@ -159,40 +193,24 @@ ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit,
return handle;
}
-void unwrap_lscm(Scene *scene, Object *obedit, short seamcut)
+/* ******************** unwrap operator **************** */
+
+static int unwrap_exec(bContext *C, wmOperator *op)
{
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
ParamHandle *handle;
- short abf = scene->toolsettings->unwrapper == 1;
- short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
+ int method = RNA_enum_get(op->ptr, "method");
+ int fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
- /* add uvs if there not here */
- if (!ED_uvedit_test(obedit)) {
-#if 0
- if (em && em->faces.first)
- EM_add_data_layer(&em->fdata, CD_MTFACE);
-
- if (!ED_uvedit_test(obedit))
- return;
-
- if (G.sima && G.sima->image) /* this is a bit of a kludge, but assume they want the image on their mesh when UVs are added */
- image_changed(G.sima, G.sima->image);
-
- /* select new UV's */
- if ((G.sima==0 || G.sima->flag & SI_SYNC_UVSEL)==0) {
- EditFace *efa;
- MTFace *tf;
- for(efa=em->faces.first; efa; efa=efa->next) {
- tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- simaFaceSel_Set(efa, tf);
- }
- }
-#endif
- }
+ /* add uvs if they don't exist yet */
+ if(!ED_uvedit_test(obedit))
+ ED_uvedit_create_uvs(em);
- handle = construct_param_handle(scene, em, 0, fillholes, seamcut == 0);
+ handle= construct_param_handle(scene, em, 0, fill_holes, 0);
- param_lscm_begin(handle, PARAM_FALSE, abf);
+ param_lscm_begin(handle, PARAM_FALSE, method == 0);
param_lscm_solve(handle);
param_lscm_end(handle);
@@ -202,151 +220,291 @@ void unwrap_lscm(Scene *scene, Object *obedit, short seamcut)
param_delete(handle);
- if (!seamcut)
- ; // XXX BIF_undo_push("UV unwrap");
-
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
- // XXX allqueue(REDRAWVIEW3D, 0);
- // XXX allqueue(REDRAWIMAGE, 0);
+ return OPERATOR_FINISHED;
}
-void minimize_stretch_tface_uv(Scene *scene, Object *obedit)
+void UV_OT_unwrap(wmOperatorType *ot)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ static EnumPropertyItem method_items[] = {
+ {0, "ANGLE_BASED", "Angle Based", ""},
+ {1, "CONFORMAL", "Conformal", ""},
+ {0, NULL, NULL, NULL}};
+
+ /* identifiers */
+ ot->name= "Unwrap";
+ ot->idname= "UV_OT_unwrap";
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec= unwrap_exec;
+ ot->poll= ED_operator_uvmap;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "method", method_items, 0, "Method", "Unwrapping method. Angle Based usually gives better results than Conformal, while being somewhat slower.");
+ RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry.");
+}
+
+/* ******************** minimize stretch operator **************** */
+
+typedef struct MinStretch {
+ Scene *scene;
+ Object *obedit;
+ EditMesh *em;
ParamHandle *handle;
+ float blend;
double lasttime;
- short doit = 1, escape = 0, val, blend = 0;
- unsigned short event = 0;
- short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
-
- if(!ED_uvedit_test(obedit)) return;
+ int i, iterations;
+ wmTimer *timer;
+} MinStretch;
- handle = construct_param_handle(scene, em, 1, fillholes, 1);
+static void minimize_stretch_init(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ MinStretch *ms;
+ int fill_holes= RNA_boolean_get(op->ptr, "fill_holes");
+
+ ms= MEM_callocN(sizeof(MinStretch), "MinStretch");
+ ms->scene= scene;
+ ms->obedit= obedit;
+ ms->em= em;
+ ms->blend= RNA_float_get(op->ptr, "blend");
+ ms->iterations= RNA_int_get(op->ptr, "iterations");
+ ms->handle= construct_param_handle(scene, em, 1, fill_holes, 1);
+ ms->lasttime= PIL_check_seconds_timer();
+
+ param_stretch_begin(ms->handle);
+ if(ms->blend != 0.0f)
+ param_stretch_blend(ms->handle, ms->blend);
+
+ op->customdata= ms;
+}
- lasttime = PIL_check_seconds_timer();
+static void minimize_stretch_iteration(bContext *C, wmOperator *op, int interactive)
+{
+ MinStretch *ms= op->customdata;
+ ScrArea *sa= CTX_wm_area(C);
- param_stretch_begin(handle);
+ param_stretch_blend(ms->handle, ms->blend);
+ param_stretch_iter(ms->handle);
- while (doit) {
- param_stretch_iter(handle);
+ if(interactive && (PIL_check_seconds_timer() - ms->lasttime > 0.5)) {
+ char str[100];
- while (0) { // XXX qtest()) {
- event= 0; // XXX extern_qread(&val);
+ param_flush(ms->handle);
- if (val) {
-#if 0
- switch (event) {
- case ESCKEY:
- escape = 1;
- case RETKEY:
- case PADENTER:
- doit = 0;
- break;
- case PADPLUSKEY:
- case WHEELUPMOUSE:
- if (blend < 10) {
- blend++;
- param_stretch_blend(handle, blend*0.1f);
- param_flush(handle);
- lasttime = 0.0f;
- }
- break;
- case PADMINUS:
- case WHEELDOWNMOUSE:
- if (blend > 0) {
- blend--;
- param_stretch_blend(handle, blend*0.1f);
- param_flush(handle);
- lasttime = 0.0f;
- }
- break;
- }
-#endif
- }
- else if (0) { // XXX (event == LEFTMOUSE) || (event == RIGHTMOUSE)) {
- escape = 0; // XXX (event == RIGHTMOUSE);
- doit = 0;
- }
+ if(sa) {
+ sprintf(str, "Minimize Stretch. Blend %.2f.", ms->blend);
+ ED_area_headerprint(sa, str);
}
-
- if (!doit)
- break;
- if (PIL_check_seconds_timer() - lasttime > 0.5) {
- char str[100];
+ ms->lasttime = PIL_check_seconds_timer();
- param_flush(handle);
+ DAG_object_flush_update(ms->scene, ms->obedit, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ms->obedit);
+ }
+}
- sprintf(str, "Stretch minimize. Blend %.2f.", blend*0.1f);
- // XXX headerprint(str);
+static void minimize_stretch_exit(bContext *C, wmOperator *op, int cancel)
+{
+ MinStretch *ms= op->customdata;
+ ScrArea *sa= CTX_wm_area(C);
- lasttime = PIL_check_seconds_timer();
- DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
- // XXX if(G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
- // XXX else force_draw(0);
- }
- }
+ if(sa)
+ ED_area_headerprint(sa, NULL);
+ if(ms->timer)
+ WM_event_remove_window_timer(CTX_wm_window(C), ms->timer);
- if (escape)
- param_flush_restore(handle);
+ if(cancel)
+ param_flush_restore(ms->handle);
else
- param_flush(handle);
+ param_flush(ms->handle);
- param_stretch_end(handle);
+ param_stretch_end(ms->handle);
+ param_delete(ms->handle);
- param_delete(handle);
+ DAG_object_flush_update(ms->scene, ms->obedit, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ms->obedit);
- // XXX BIF_undo_push("UV stretch minimize");
+ MEM_freeN(ms);
+ op->customdata= NULL;
+}
- DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+static int minimize_stretch_exec(bContext *C, wmOperator *op)
+{
+ int i, iterations;
+
+ minimize_stretch_init(C, op);
+
+ iterations= RNA_int_get(op->ptr, "iterations");
+ for(i=0; i<iterations; i++)
+ minimize_stretch_iteration(C, op, 0);
+ minimize_stretch_exit(C, op, 0);
+
+ return OPERATOR_FINISHED;
+}
+
+static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ MinStretch *ms;
+
+ minimize_stretch_init(C, op);
+ minimize_stretch_iteration(C, op, 1);
+
+ ms= op->customdata;
+ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ ms->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int minimize_stretch_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ MinStretch *ms= op->customdata;
+
+ switch(event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ minimize_stretch_exit(C, op, 1);
+ return OPERATOR_CANCELLED;
+ case RETKEY:
+ case PADENTER:
+ case LEFTMOUSE:
+ minimize_stretch_exit(C, op, 0);
+ return OPERATOR_FINISHED;
+ case PADPLUSKEY:
+ case WHEELUPMOUSE:
+ if(ms->blend < 0.95f) {
+ ms->blend += 0.1f;
+ ms->lasttime= 0.0f;
+ RNA_float_set(op->ptr, "blend", ms->blend);
+ minimize_stretch_iteration(C, op, 1);
+ }
+ break;
+ case PADMINUS:
+ case WHEELDOWNMOUSE:
+ if(ms->blend > 0.05f) {
+ ms->blend -= 0.1f;
+ ms->lasttime= 0.0f;
+ RNA_float_set(op->ptr, "blend", ms->blend);
+ minimize_stretch_iteration(C, op, 1);
+ }
+ break;
+ case TIMER:
+ if(ms->timer == event->customdata) {
+ double start= PIL_check_seconds_timer();
- // XXX allqueue(REDRAWVIEW3D, 0);
- // XXX allqueue(REDRAWIMAGE, 0);
+ do {
+ minimize_stretch_iteration(C, op, 1);
+ } while(PIL_check_seconds_timer() - start < 0.01);
+ }
+ break;
+ }
+
+ if(ms->iterations && ms->i >= ms->iterations) {
+ minimize_stretch_exit(C, op, 0);
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
-void pack_charts_tface_uv(Scene *scene, Object *obedit)
+static int minimize_stretch_cancel(bContext *C, wmOperator *op)
{
+ minimize_stretch_exit(C, op, 1);
+
+ return OPERATOR_CANCELLED;
+}
+
+void UV_OT_minimize_stretch(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Minimize Stretch";
+ ot->idname= "UV_OT_minimize_stretch";
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec= minimize_stretch_exec;
+ ot->invoke= minimize_stretch_invoke;
+ ot->modal= minimize_stretch_modal;
+ ot->cancel= minimize_stretch_cancel;
+ ot->poll= ED_operator_uvedit;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry.");
+ RNA_def_float(ot->srna, "blend", 0.0f, 0.0f, 1.0f, "Blend", "Blend factor between stretch minimized and original.", 0.0f, 1.0f);
+ RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively.", 0, 100);
+}
+
+/* ******************** pack islands operator **************** */
+
+static int pack_islands_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
ParamHandle *handle;
-
- if(!ED_uvedit_test(obedit)) return;
handle = construct_param_handle(scene, em, 1, 0, 1);
param_pack(handle);
param_flush(handle);
param_delete(handle);
-
- // XXX BIF_undo_push("UV pack islands");
-
+
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
- // XXX allqueue(REDRAWVIEW3D, 0);
- // XXX allqueue(REDRAWIMAGE, 0);
+ return OPERATOR_FINISHED;
}
+void UV_OT_pack_islands(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Pack Islands";
+ ot->idname= "UV_OT_pack_islands";
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec= pack_islands_exec;
+ ot->poll= ED_operator_uvedit;
+}
+
+/* ******************** average islands scale operator **************** */
-void average_charts_tface_uv(Scene *scene, Object *obedit)
+static int average_islands_scale_exec(bContext *C, wmOperator *op)
{
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
ParamHandle *handle;
-
- if(!ED_uvedit_test(obedit)) return;
- handle = construct_param_handle(scene, em, 1, 0, 1);
+ handle= construct_param_handle(scene, em, 1, 0, 1);
param_average(handle);
param_flush(handle);
param_delete(handle);
-
- // XXX BIF_undo_push("UV average island scale");
-
+
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+
+ return OPERATOR_FINISHED;
+}
- // XXX allqueue(REDRAWVIEW3D, 0);
- // XXX allqueue(REDRAWIMAGE, 0);
+void UV_OT_average_islands_scale(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Average Islands Scale";
+ ot->idname= "UV_OT_average_islands_scale";
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec= average_islands_scale_exec;
+ ot->poll= ED_operator_uvedit;
}
-/* LSCM live mode */
+/**************** Live Unwrap *****************/
static ParamHandle *liveHandle = NULL;