SET(PLATFORM_LINKFLAGS "-pthread")
# Better warnings
- SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Waggregate-return -Wnested-externs -Wdeclaration-after-statement")
+ SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wnested-externs -Wdeclaration-after-statement")
INCLUDE_DIRECTORIES(/usr/include /usr/local/include)
ENDIF(UNIX)
RelativePath="..\..\..\source\blender\editors\interface\interface_regions.c"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\..\source\blender\editors\interface\interface_utils.c"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\..\source\blender\editors\interface\keyval.c"\r
>\r
</File>\r
</Filter>\r
<Filter\r
- Name="space_ipo"\r
+ Name="space_graph"\r
>\r
<File\r
- RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_draw.c"\r
+ RelativePath="..\..\..\source\blender\editors\space_graph\graph_draw.c"\r
>\r
</File>\r
<File\r
- RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_edit.c"\r
+ RelativePath="..\..\..\source\blender\editors\space_graph\graph_edit.c"\r
>\r
</File>\r
<File\r
- RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_header.c"\r
+ RelativePath="..\..\..\source\blender\editors\space_graph\graph_header.c"\r
>\r
</File>\r
<File\r
- RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_intern.h"\r
+ RelativePath="..\..\..\source\blender\editors\space_graph\graph_intern.h"\r
>\r
</File>\r
<File\r
- RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_ops.c"\r
+ RelativePath="..\..\..\source\blender\editors\space_graph\graph_ops.c"\r
>\r
</File>\r
<File\r
- RelativePath="..\..\..\source\blender\editors\space_ipo\ipo_select.c"\r
+ RelativePath="..\..\..\source\blender\editors\space_graph\graph_select.c"\r
>\r
</File>\r
<File\r
- RelativePath="..\..\..\source\blender\editors\space_ipo\space_ipo.c"\r
+ RelativePath="..\..\..\source\blender\editors\space_graph\space_graph.c"\r
>\r
</File>\r
</Filter>\r
RelativePath="..\..\..\source\blender\editors\armature\armature_intern.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\..\source\blender\editors\armature\armature_ops.c"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\..\source\blender\editors\armature\editarmature.c"\r
>\r
RelativePath="..\..\..\source\blender\makesrna\intern\rna_image.c"\r
>\r
</File>\r
- <File\r
- RelativePath="..\..\..\source\blender\makesrna\intern\rna_ipo.c"\r
- >\r
- </File>\r
<File\r
RelativePath="..\..\..\source\blender\makesrna\intern\rna_key.c"\r
>\r
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_image_gen.c"\r
>\r
</File>\r
- <File\r
- RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_ipo_gen.c"\r
- >\r
- </File>\r
<File\r
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_key_gen.c"\r
>\r
PULIB += $(OCGDIR)/blender/ed_info/libed_info.a
PULIB += $(OCGDIR)/blender/ed_buttons/libed_buttons.a
PULIB += $(OCGDIR)/blender/ed_node/libed_node.a
-PULIB += $(OCGDIR)/blender/ed_image/libed_image.a
-PULIB += $(OCGDIR)/blender/ed_ipo/libed_ipo.a
+PULIB += $(OCGDIR)/blender/ed_graph/libed_graph.a
PULIB += $(OCGDIR)/blender/ed_outliner/libed_outliner.a
PULIB += $(OCGDIR)/blender/ed_time/libed_time.a
PULIB += $(OCGDIR)/blender/ed_preview/libed_preview.a
PULIB += $(OCGDIR)/blender/ed_animation/libed_animation.a
PULIB += $(OCGDIR)/blender/ed_transform/libed_transform.a
PULIB += $(OCGDIR)/blender/ed_util/libed_util.a
-PULIB += $(OCGDIR)/blender/ed_uvedit/libed_uvedit.a
PULIB += $(OCGDIR)/blender/ed_datafiles/libed_datafiles.a
+PULIB += $(OCGDIR)/blender/ed_image/libed_image.a
+PULIB += $(OCGDIR)/blender/ed_uvedit/libed_uvedit.a
PULIB += $(OCGDIR)/blender/ed_screen/libed_screen.a
PULIB += $(OCGDIR)/blender/windowmanager/libwindowmanager.a
PULIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a
struct ToolSettings;
struct Image;
struct ImBuf;
+struct EditBone;
+struct bPoseChannel;
struct wmWindow;
struct wmWindowManager;
CTX_DATA_EDIT_IMAGE,
CTX_DATA_EDIT_IMAGE_BUFFER,
- CTX_DATA_SELECTED_NODES
+ CTX_DATA_SELECTED_NODES,
+
+ CTX_DATA_SELECTED_BONES,
+ CTX_DATA_SELECTED_EDITABLE_BONES,
+ CTX_DATA_SELECTED_PCHANS,
+
+ CTX_DATA_ACTIVE_BONE,
+ CTX_DATA_ACTIVE_PCHAN,
};
typedef int bContextDataMember;
int CTX_data_selected_nodes(const bContext *C, ListBase *list);
+struct EditBone *CTX_data_active_bone(const bContext *C);
+int CTX_data_selected_bones(const bContext *C, ListBase *list);
+int CTX_data_selected_editable_bones(const bContext *C, ListBase *list);
+
+struct bPoseChannel *CTX_data_active_pchan(const bContext *C);
+int CTX_data_selected_pchans(const bContext *C, ListBase *list);
+
/* Data Evaluation Context */
float CTX_eval_frame(const bContext *C);
struct GPUNode;
struct GPUNodeStack;
-#define SOCK_IN 1
-#define SOCK_OUT 2
-
/* ************** NODE TYPE DEFINITIONS ***** */
typedef struct bNodeSocketType {
#define V_DECLARE(vec) int _##vec##_count=0; void *_##vec##_tmp
/*this returns the entire size of the array, including any buffering.*/
-#define V_SIZE(vec) ((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec))
+#define V_SIZE(vec) ((signed int)((vec)==NULL ? 0 : MEM_allocN_len(vec) / sizeof(*vec)))
/*this returns the logical size of the array, not including buffering.*/
#define V_COUNT(vec) _##vec##_count
repeat = (strip->flag & ACTSTRIP_USESTRIDE) ? (1.0f) : (strip->repeat);
if (strip->scale == 0.0f) strip->scale= 1.0f;
- scale = fabs(strip->scale); /* scale must be positive (for now) */
+ scale = (float)fabs(strip->scale); /* scale must be positive (for now) */
actlength = strip->actend-strip->actstart;
if (actlength == 0.0f) actlength = 1.0f;
if(cm->curve)
MEM_freeN(cm->curve);
- if(preset == BRUSH_PRESET_SHARP) {
- cm->curve= MEM_callocN(3*sizeof(CurveMapPoint), "curve points");
- cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ if(preset == BRUSH_PRESET_SHARP)
cm->totpoint= 3;
+ if(preset == BRUSH_PRESET_SMOOTH)
+ cm->totpoint= 6;
+ if(preset == BRUSH_PRESET_MAX)
+ cm->totpoint= 2;
+
+
+ cm->curve= MEM_callocN(cm->totpoint*sizeof(CurveMapPoint), "curve points");
+ cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+
+ if(preset == BRUSH_PRESET_SHARP) {
cm->curve[0].x= 0;
cm->curve[0].y= 1;
cm->curve[1].x= 0.33;
cm->curve[2].y= 0;
}
else if(preset == BRUSH_PRESET_SMOOTH) {
- // XXX: todo
+ cm->curve[0].x= 0;
+ cm->curve[0].y= 1;
+ cm->curve[1].x= 0.1;
+ cm->curve[1].y= 0.97553;
+ cm->curve[2].x= 0.3;
+ cm->curve[2].y= 0.79389;
+ cm->curve[3].x= 0.9;
+ cm->curve[3].y= 0.02447;
+ cm->curve[4].x= 0.7;
+ cm->curve[4].y= 0.20611;
+ cm->curve[5].x= 1;
+ cm->curve[5].y= 0;
}
else if(preset == BRUSH_PRESET_MAX) {
- // XXX: todo
+ cm->curve[0].x= 0;
+ cm->curve[0].y= 1;
+ cm->curve[1].x= 1;
+ cm->curve[1].y= 1;
}
curvemapping_changed(b->curve, 0);
{
ListBase list;
- if(func(C, &list))
- return BLI_countlist(&list);
+ if(func(C, &list)) {
+ int tot= BLI_countlist(&list);
+ BLI_freelistN(&list);
+ return tot;
+ }
else
return 0;
}
return ctx_data_pointer_get(C, CTX_DATA_EDIT_IMAGE_BUFFER);
}
+struct EditBone *CTX_data_active_bone(const bContext *C)
+{
+ return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_BONE);
+}
+
+int CTX_data_selected_bones(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, CTX_DATA_SELECTED_BONES, list);
+}
+
+int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, CTX_DATA_SELECTED_EDITABLE_BONES, list);
+}
+
+struct bPoseChannel *CTX_data_active_pchan(const bContext *C)
+{
+ return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_PCHAN);
+}
+
+int CTX_data_selected_pchans(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, CTX_DATA_SELECTED_PCHANS, list);
+}
+
/* data evaluation */
float CTX_eval_frame(const bContext *C)
/* showing RGBA result itself (from compo/sequence) or
like exr, using layers etc */
+/* always returns a single ibuf, also during render progress */
static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser)
{
+ Render *re;
RenderResult *rr= NULL;
- if(iuser->scene)
- rr= RE_GetResult(RE_GetRender(iuser->scene->id.name));
+ if(iuser->scene) {
+ re= RE_GetRender(iuser->scene->id.name);
+ rr= RE_GetResult(re);
+ }
+ if(rr==NULL) return NULL;
- if(rr) {
+ if(RE_RenderInProgress(re)) {
+ ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+
+ /* make ibuf if needed, and initialize it */
+ /* this only gets called when mutex locked */
+ if(ibuf==NULL) {
+ ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, IB_rect, 0);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ }
+ return ibuf;
+ }
+ else {
RenderResult rres;
float *rectf;
unsigned int *rect;
{(1<<20), "layer", 20}
};
+/* Material mode */
+static AdrBit2Path ma_mode_bits[]= {
+// {MA_TRACEBLE, "traceable", 0},
+// {MA_SHADOW, "shadow", 0},
+// {MA_SHLESS, "shadeless", 0},
+// ...
+ {MA_RAYTRANSP, "raytrace_transparency.enabled", 0},
+ {MA_RAYMIRROR, "raytrace_mirror.enabled", 0},
+ {MA_HALO, "halo.enabled", 0}
+};
+
/* ----------------- */
+/* quick macro for returning the appropriate array for adrcode_bitmaps_to_paths() */
+#define RET_ABP(items) \
+ { \
+ *tot= sizeof(items)/sizeof(AdrBit2Path); \
+ return items; \
+ }
+
/* This function checks if a Blocktype+Adrcode combo, returning a mapping table */
static AdrBit2Path *adrcode_bitmaps_to_paths (int blocktype, int adrcode, int *tot)
{
/* Object layers */
- if ((blocktype == ID_OB) && (adrcode == OB_LAY)) {
- *tot= sizeof(ob_layer_bits)/sizeof(AdrBit2Path);
- return ob_layer_bits;
- }
- else if ((blocktype == ID_MA) && (adrcode == MA_MODE)) {
- // XXX to be added...
- }
+ if ((blocktype == ID_OB) && (adrcode == OB_LAY))
+ RET_ABP(ob_layer_bits)
+ else if ((blocktype == ID_MA) && (adrcode == MA_MODE))
+ RET_ABP(ma_mode_bits)
// XXX TODO: add other types...
/* Normal curve */
return NULL;
}
-/* This function makes a copy of a path stored in AdrBit2Path entry, and makes a guardedalloc copy */
-static char *adrcode_bitmap_path_copy (const char *abp_path)
-{
- char *path;
- int len;
-
- /* copy the path */
- len= strlen(abp_path) + 1; // XXX is this safe?
- path= MEM_callocN(len, "Bitflag IPO-Curve RNA-Path");
- memcpy(path, abp_path, len);
-
- return path;
-}
-
/* *************************************************** */
/* ADRCODE to RNA-Path Conversion Code - Standard */
return buf;
}
+/* MTex (Texture Slot) types */
+static char *mtex_adrcodes_to_paths (int adrcode, int *array_index)
+{
+ char *base=NULL, *prop=NULL;
+ static char buf[128];
+
+ /* base part of path */
+ if (adrcode & MA_MAP1) base= "textures[0]";
+ else if (adrcode & MA_MAP2) base= "textures[1]";
+ else if (adrcode & MA_MAP3) base= "textures[2]";
+ else if (adrcode & MA_MAP4) base= "textures[3]";
+ else if (adrcode & MA_MAP5) base= "textures[4]";
+ else if (adrcode & MA_MAP6) base= "textures[5]";
+ else if (adrcode & MA_MAP7) base= "textures[6]";
+ else if (adrcode & MA_MAP8) base= "textures[7]";
+ else if (adrcode & MA_MAP9) base= "textures[8]";
+ else if (adrcode & MA_MAP10) base= "textures[9]";
+ else if (adrcode & MA_MAP11) base= "textures[10]";
+ else if (adrcode & MA_MAP12) base= "textures[11]";
+ else if (adrcode & MA_MAP13) base= "textures[12]";
+ else if (adrcode & MA_MAP14) base= "textures[13]";
+ else if (adrcode & MA_MAP15) base= "textures[14]";
+ else if (adrcode & MA_MAP16) base= "textures[15]";
+ else if (adrcode & MA_MAP17) base= "textures[16]";
+ else if (adrcode & MA_MAP18) base= "textures[17]";
+
+ /* property identifier for path */
+ adrcode= (adrcode & (MA_MAP1-1));
+ switch (adrcode) {
+#if 0 // XXX these are not wrapped in RNA yet!
+ case MAP_OFS_X:
+ poin= &(mtex->ofs[0]); break;
+ case MAP_OFS_Y:
+ poin= &(mtex->ofs[1]); break;
+ case MAP_OFS_Z:
+ poin= &(mtex->ofs[2]); break;
+ case MAP_SIZE_X:
+ poin= &(mtex->size[0]); break;
+ case MAP_SIZE_Y:
+ poin= &(mtex->size[1]); break;
+ case MAP_SIZE_Z:
+ poin= &(mtex->size[2]); break;
+ case MAP_R:
+ poin= &(mtex->r); break;
+ case MAP_G:
+ poin= &(mtex->g); break;
+ case MAP_B:
+ poin= &(mtex->b); break;
+ case MAP_DVAR:
+ poin= &(mtex->def_var); break;
+ case MAP_COLF:
+ poin= &(mtex->colfac); break;
+ case MAP_NORF:
+ poin= &(mtex->norfac); break;
+ case MAP_VARF:
+ poin= &(mtex->varfac); break;
+#endif
+ case MAP_DISP:
+ prop= "warp_factor"; break;
+ }
+
+ /* only build and return path if there's a property */
+ if (prop) {
+ BLI_snprintf(buf, 128, "%s.%s", base, prop);
+ return buf;
+ }
+ else
+ return NULL;
+}
+
/* Texture types */
static char *texture_adrcodes_to_paths (int adrcode, int *array_index)
{
case MA_REF:
return "diffuse_reflection";
+
+ case MA_EMIT:
+ return "emit";
+
+ case MA_AMB:
+ return "ambient";
+
+ case MA_SPEC:
+ return "specularity";
+
+ case MA_HARD:
+ return "specular_hardness";
- // XXX add other types...
- }
-
- return NULL;
-
-#if 0
- case MA_EMIT:
- poin= &(ma->emit); break;
- case MA_AMB:
- poin= &(ma->amb); break;
- case MA_SPEC:
- poin= &(ma->spec); break;
- case MA_HARD:
- poin= &(ma->har); *type= IPO_SHORT; break;
- case MA_SPTR:
- poin= &(ma->spectra); break;
- case MA_IOR:
- poin= &(ma->ang); break;
- case MA_HASIZE:
- poin= &(ma->hasize); break;
- case MA_TRANSLU:
- poin= &(ma->translucency); break;
- case MA_RAYM:
- poin= &(ma->ray_mirror); break;
- case MA_FRESMIR:
- poin= &(ma->fresnel_mir); break;
- case MA_FRESMIRI:
- poin= &(ma->fresnel_mir_i); break;
- case MA_FRESTRA:
- poin= &(ma->fresnel_tra); break;
- case MA_FRESTRAI:
- poin= &(ma->fresnel_tra_i); break;
- case MA_ADD:
- poin= &(ma->add); break;
-
- if (poin == NULL) {
- if (icu->adrcode & MA_MAP1) mtex= ma->mtex[0];
- else if (icu->adrcode & MA_MAP2) mtex= ma->mtex[1];
- else if (icu->adrcode & MA_MAP3) mtex= ma->mtex[2];
- else if (icu->adrcode & MA_MAP4) mtex= ma->mtex[3];
- else if (icu->adrcode & MA_MAP5) mtex= ma->mtex[4];
- else if (icu->adrcode & MA_MAP6) mtex= ma->mtex[5];
- else if (icu->adrcode & MA_MAP7) mtex= ma->mtex[6];
- else if (icu->adrcode & MA_MAP8) mtex= ma->mtex[7];
- else if (icu->adrcode & MA_MAP9) mtex= ma->mtex[8];
- else if (icu->adrcode & MA_MAP10) mtex= ma->mtex[9];
- else if (icu->adrcode & MA_MAP12) mtex= ma->mtex[11];
- else if (icu->adrcode & MA_MAP11) mtex= ma->mtex[10];
- else if (icu->adrcode & MA_MAP13) mtex= ma->mtex[12];
- else if (icu->adrcode & MA_MAP14) mtex= ma->mtex[13];
- else if (icu->adrcode & MA_MAP15) mtex= ma->mtex[14];
- else if (icu->adrcode & MA_MAP16) mtex= ma->mtex[15];
- else if (icu->adrcode & MA_MAP17) mtex= ma->mtex[16];
- else if (icu->adrcode & MA_MAP18) mtex= ma->mtex[17];
+ case MA_SPTR:
+ return "specular_opacity";
+
+ case MA_IOR:
+ return "ior";
+
+ case MA_HASIZE:
+ return "halo.size";
+
+ case MA_TRANSLU:
+ return "translucency";
+
+ case MA_RAYM:
+ return "raytrace_mirror.reflect";
+
+ case MA_FRESMIR:
+ return "raytrace_mirror.fresnel";
+
+ case MA_FRESMIRI:
+ return "raytrace_mirror.fresnel_fac";
+
+ case MA_FRESTRA:
+ return "raytrace_transparency.fresnel";
+
+ case MA_FRESTRAI:
+ return "raytrace_transparency.fresnel_fac";
+
+ case MA_ADD:
+ return "halo.add";
- if (mtex)
- poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
+ default: /* for now, we assume that the others were MTex channels */
+ return mtex_adrcodes_to_paths(adrcode, array_index);
}
-#endif
+ return NULL;
}
/* Camera Types */
case LA_HALOINT:
return "halo_intensity";
+
+ default: /* for now, we assume that the others were MTex channels */
+ return mtex_adrcodes_to_paths(adrcode, array_index);
}
-#if 0 // XXX to be converted
- if (poin == NULL) {
- if (icu->adrcode & MA_MAP1) mtex= la->mtex[0];
- else if (icu->adrcode & MA_MAP2) mtex= la->mtex[1];
- else if (icu->adrcode & MA_MAP3) mtex= la->mtex[2];
- else if (icu->adrcode & MA_MAP4) mtex= la->mtex[3];
- else if (icu->adrcode & MA_MAP5) mtex= la->mtex[4];
- else if (icu->adrcode & MA_MAP6) mtex= la->mtex[5];
- else if (icu->adrcode & MA_MAP7) mtex= la->mtex[6];
- else if (icu->adrcode & MA_MAP8) mtex= la->mtex[7];
- else if (icu->adrcode & MA_MAP9) mtex= la->mtex[8];
- else if (icu->adrcode & MA_MAP10) mtex= la->mtex[9];
- else if (icu->adrcode & MA_MAP11) mtex= la->mtex[10];
- else if (icu->adrcode & MA_MAP12) mtex= la->mtex[11];
- else if (icu->adrcode & MA_MAP13) mtex= la->mtex[12];
- else if (icu->adrcode & MA_MAP14) mtex= la->mtex[13];
- else if (icu->adrcode & MA_MAP15) mtex= la->mtex[14];
- else if (icu->adrcode & MA_MAP16) mtex= la->mtex[15];
- else if (icu->adrcode & MA_MAP17) mtex= la->mtex[16];
- else if (icu->adrcode & MA_MAP18) mtex= la->mtex[17];
-
- if (mtex)
- poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
- }
-#endif // XXX to be converted
+ /* unrecognised adrcode, or not-yet-handled ones! */
+ return NULL;
+}
+
+/* Sound Types */
+static char *sound_adrcodes_to_paths (int adrcode, int *array_index)
+{
+ /* set array index like this in-case nothing sets it correctly */
+ *array_index= 0;
+
+ /* result depends on adrcode */
+ switch (adrcode) {
+ case SND_VOLUME:
+ return "volume";
+ case SND_PITCH:
+ return "pitch";
+ /* XXX Joshua -- I had wrapped panning in rna, but someone commented out, calling it "unused" */
+ /* case SND_PANNING:
+ return "panning"; */
+ case SND_ATTEN:
+ return "attenuation";
+ }
/* unrecognised adrcode, or not-yet-handled ones! */
return NULL;
}
+/* World Types */
+static char *world_adrcodes_to_paths (int adrcode, int *array_index)
+{
+ /* set array index like this in-case nothing sets it correctly */
+ *array_index= 0;
+
+ /* result depends on adrcode */
+ switch (adrcode) {
+ case WO_HOR_R:
+ *array_index= 0; return "horizon_color";
+ case WO_HOR_G:
+ *array_index= 1; return "horizon_color";
+ case WO_HOR_B:
+ *array_index= 2; return "horizon_color";
+ case WO_ZEN_R:
+ *array_index= 0; return "zenith_color";
+ case WO_ZEN_G:
+ *array_index= 1; return "zenith_color";
+ case WO_ZEN_B:
+ *array_index= 2; return "zenith_color";
+
+ case WO_EXPOS:
+ return "exposure";
+
+ case WO_MISI:
+ return "mist.intensity";
+ case WO_MISTDI:
+ return "mist.depth";
+ case WO_MISTSTA:
+ return "mist.start";
+ case WO_MISTHI:
+ return "mist.height";
+
+ /* Star Color is unused -- recommend removal */
+ /* case WO_STAR_R:
+ *array_index= 0; return "stars.color";
+ case WO_STAR_G:
+ *array_index= 1; return "stars.color";
+ case WO_STAR_B:
+ *array_index= 2; return "stars.color"; */
+
+ case WO_STARDIST:
+ return "stars.min_distance";
+ case WO_STARSIZE:
+ return "stars.size";
+
+ default: /* for now, we assume that the others were MTex channels */
+ return mtex_adrcodes_to_paths(adrcode, array_index);
+ }
+
+ return NULL;
+}
+
/* ------- */
/* Allocate memory for RNA-path for some property given a blocktype, adrcode, and 'root' parts of path
case ID_LA: /* lamp */
propname= lamp_adrcodes_to_paths(adrcode, &dummy_index);
break;
+
+ case ID_SO: /* sound */
+ propname= sound_adrcodes_to_paths(adrcode, &dummy_index);
+
+ case ID_WO: /* world */
+ propname= world_adrcodes_to_paths(adrcode, &dummy_index);
/* XXX problematic blocktypes */
case ID_CU: /* curve */
fcurve= fcu;
/* set path */
- fcurve->rna_path= adrcode_bitmap_path_copy(abp->path);
+ fcurve->rna_path= BLI_strdupn(abp->path, strlen(abp->path));
fcurve->array_index= abp->array_index;
/* convert keyframes
/* --------------------- Get Pointer API ----------------------------- */
-/* get texture-slot/mapping channel */
-void *give_mtex_poin (MTex *mtex, int adrcode)
-{
- void *poin= NULL;
-
- switch (adrcode) {
- case MAP_OFS_X:
- poin= &(mtex->ofs[0]); break;
- case MAP_OFS_Y:
- poin= &(mtex->ofs[1]); break;
- case MAP_OFS_Z:
- poin= &(mtex->ofs[2]); break;
- case MAP_SIZE_X:
- poin= &(mtex->size[0]); break;
- case MAP_SIZE_Y:
- poin= &(mtex->size[1]); break;
- case MAP_SIZE_Z:
- poin= &(mtex->size[2]); break;
- case MAP_R:
- poin= &(mtex->r); break;
- case MAP_G:
- poin= &(mtex->g); break;
- case MAP_B:
- poin= &(mtex->b); break;
- case MAP_DVAR:
- poin= &(mtex->def_var); break;
- case MAP_COLF:
- poin= &(mtex->colfac); break;
- case MAP_NORF:
- poin= &(mtex->norfac); break;
- case MAP_VARF:
- poin= &(mtex->varfac); break;
- case MAP_DISP:
- poin= &(mtex->dispfac); break;
- }
-
- /* return pointer */
- return poin;
-}
/* GS reads the memory pointed at in a specific ordering. There are,
* however two definitions for it. I have jotted them down here, both,
/* data is divided into 'blocktypes' based on ID-codes */
switch (GS(id->name)) {
- case ID_WO: /* world channels ----------------------------- */
- {
- World *wo= (World *)id;
-
- switch (icu->adrcode) {
- case WO_HOR_R:
- poin= &(wo->horr); break;
- case WO_HOR_G:
- poin= &(wo->horg); break;
- case WO_HOR_B:
- poin= &(wo->horb); break;
- case WO_ZEN_R:
- poin= &(wo->zenr); break;
- case WO_ZEN_G:
- poin= &(wo->zeng); break;
- case WO_ZEN_B:
- poin= &(wo->zenb); break;
-
- case WO_EXPOS:
- poin= &(wo->exposure); break;
-
- case WO_MISI:
- poin= &(wo->misi); break;
- case WO_MISTDI:
- poin= &(wo->mistdist); break;
- case WO_MISTSTA:
- poin= &(wo->miststa); break;
- case WO_MISTHI:
- poin= &(wo->misthi); break;
-
- case WO_STAR_R:
- poin= &(wo->starr); break;
- case WO_STAR_G:
- poin= &(wo->starg); break;
- case WO_STAR_B:
- poin= &(wo->starb); break;
-
- case WO_STARDIST:
- poin= &(wo->stardist); break;
- case WO_STARSIZE:
- poin= &(wo->starsize); break;
- }
-
- if (poin == NULL) {
- if (icu->adrcode & MA_MAP1) mtex= wo->mtex[0];
- else if (icu->adrcode & MA_MAP2) mtex= wo->mtex[1];
- else if (icu->adrcode & MA_MAP3) mtex= wo->mtex[2];
- else if (icu->adrcode & MA_MAP4) mtex= wo->mtex[3];
- else if (icu->adrcode & MA_MAP5) mtex= wo->mtex[4];
- else if (icu->adrcode & MA_MAP6) mtex= wo->mtex[5];
- else if (icu->adrcode & MA_MAP7) mtex= wo->mtex[6];
- else if (icu->adrcode & MA_MAP8) mtex= wo->mtex[7];
- else if (icu->adrcode & MA_MAP9) mtex= wo->mtex[8];
- else if (icu->adrcode & MA_MAP10) mtex= wo->mtex[9];
- else if (icu->adrcode & MA_MAP11) mtex= wo->mtex[10];
- else if (icu->adrcode & MA_MAP12) mtex= wo->mtex[11];
- else if (icu->adrcode & MA_MAP13) mtex= wo->mtex[12];
- else if (icu->adrcode & MA_MAP14) mtex= wo->mtex[13];
- else if (icu->adrcode & MA_MAP15) mtex= wo->mtex[14];
- else if (icu->adrcode & MA_MAP16) mtex= wo->mtex[15];
- else if (icu->adrcode & MA_MAP17) mtex= wo->mtex[16];
- else if (icu->adrcode & MA_MAP18) mtex= wo->mtex[17];
-
- if (mtex)
- poin= give_mtex_poin(mtex, (icu->adrcode & (MA_MAP1-1)));
- }
- }
- break;
- case ID_SO: /* sound channels ----------------------------- */
- {
- bSound *snd= (bSound *)id;
-
- switch (icu->adrcode) {
- case SND_VOLUME:
- poin= &(snd->volume); break;
- case SND_PITCH:
- poin= &(snd->pitch); break;
- case SND_PANNING:
- poin= &(snd->panning); break;
- case SND_ATTEN:
- poin= &(snd->attenuation); break;
- }
- }
- break;
case ID_PA: /* particle channels ----------------------------- */
{
ParticleSettings *part= (ParticleSettings *)id;
void multires_force_update(Object *ob)
{
- if(ob->derivedFinal) {
+ if(ob && ob->derivedFinal) {
ob->derivedFinal->needsFree =1;
ob->derivedFinal->release(ob->derivedFinal);
ob->derivedFinal = NULL;
/* check for copying links */
for(link= ntree->links.first; link; link= link->next) {
- if(link->fromnode->new_node && link->tonode->new_node) {
+ if(link->fromnode==NULL || link->tonode==NULL);
+ else if(link->fromnode->new_node && link->tonode->new_node) {
nlink= nodeAddLink(newtree, link->fromnode->new_node, NULL, link->tonode->new_node, NULL);
/* sockets were copied in order */
for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) {
/* is sock in use? */
else if(sock->link) {
bNodeLink *link= sock->link;
+
/* this is the test for a cyclic case */
- if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
+ if(link->fromnode==NULL || link->tonode==NULL);
+ else if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
if(link->fromnode->need_exec) {
node->need_exec= 1;
break;
/* ************ READ SCENE ***************** */
+/* patch for missing scene IDs, can't be in do-versions */
+static void composite_patch(bNodeTree *ntree, Scene *scene)
+{
+ bNode *node;
+
+ for(node= ntree->nodes.first; node; node= node->next)
+ if(node->id==NULL && ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE))
+ node->id= &scene->id;
+}
+
+
static void lib_link_scene(FileData *fd, Main *main)
{
Scene *sce;
lib_link_scriptlink(fd, &sce->id, &sce->scriptlink);
- if(sce->nodetree)
+ if(sce->nodetree) {
lib_link_ntree(fd, &sce->id, sce->nodetree);
+ composite_patch(sce->nodetree, sce);
+ }
for(srl= sce->r.layers.first; srl; srl= srl->next) {
srl->mat_override= newlibadr_us(fd, sce->id.lib, srl->mat_override);
/* 2.50: we now always add spacedata for info */
if(sa->spacedata.first==NULL) {
SpaceInfo *sinfo= MEM_callocN(sizeof(SpaceInfo), "spaceinfo");
- sa->spacetype= SPACE_INFO;
+ sa->spacetype= sinfo->spacetype= SPACE_INFO;
BLI_addtail(&sa->spacedata, sinfo);
}
/* add local view3d too */
BMOP_ESUBDIVIDE_FLAG, //beauty flag in esubdivide
BMOP_ESUBDIVIDE_RADIUS,
BMOP_ESUBDIVIDE_SELACTION,
+
+ BMOP_ESUBDIVIDE_CUSTOMFILL_FACES,
+ BMOP_ESUBDIVIDE_CUSTOMFILL_PATTERNS,
+
+ BMOP_ESUBDIVIDE_PERCENT_VERTS,
+ BMOP_ESUBDIVIDE_PERCENT_VALUES,
+
BMOP_ESUBDIVIDE_TOTSLOT,
};
/*
BMOP_OPSLOT_INT,
BMOP_OPSLOT_INT,
BMOP_OPSLOT_FLT,
- BMOP_OPSLOT_INT},
+ BMOP_OPSLOT_INT,
+ BMOP_OPSLOT_PNT_BUF,
+ BMOP_OPSLOT_PNT_BUF,
+ BMOP_OPSLOT_PNT_BUF,
+ BMOP_OPSLOT_FLT},
esubdivide_exec,
BMOP_ESUBDIVIDE_TOTSLOT,
0
#include "BLI_arithb.h"
#include "BLI_rand.h"
+#include "BLI_ghash.h"
#include "DNA_object_types.h"
#include "bmesh.h"
#include "mesh_intern.h"
+#include "subdivideop.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SUBD_SPLIT 1
-#define FACE_NEW 1
-#define MAX_FACE 800
+
+/*I don't think new faces are flagged, currently, but
+ better safe than sorry.*/
+#define FACE_NEW 2
+#define FACE_CUSTOMFILL 4
/*stuff for the flag paramter. note that
what used to live in "beauty" and
collision).*/
#define SELTYPE_INNER 128
-
/*
NOTE: beauty has been renamed to flag!
*/
-/*
-note: this is a pattern-based edge subdivider.
-it tries to match a pattern to edge selections on faces,
-then executes functions to cut them.
-*/
-typedef struct subdpattern {
- int seledges[20]; //selected edges mask, for splitting
-
- /*verts starts at the first new vert cut, not the first vert in the
- face*/
- void (*connectexec)(BMesh *bm, BMFace *face, BMVert **verts,
- int numcuts, int flag, float rad);
- int len; /*total number of verts*/
-} subdpattern;
-
/*generic subdivision rules:
* two selected edges in a face should make a link
v5---v0---v1
*/
+
static void q_2edge_op_split(BMesh *bm, BMFace *face, BMVert **vlist,
int numcuts, int flag, float rad) {
BMFace *nf;
void esubdivide_exec(BMesh *bmesh, BMOperator *op)
{
- BMOpSlot *einput;
- BMEdge *edge, **edges = NULL;
+ V_DECLARE(facedata);
+ V_DECLARE(verts);
V_DECLARE(edges);
+ BMOpSlot *einput, *finput, *pinput;
+ BMEdge *edge, **edges = NULL;
BMFace *face;
BMLoop *nl;
BMVert **verts = NULL;
- V_DECLARE(verts);
BMIter fiter, liter;
+ GHash *customfill_hash;
subdpattern *pat;
- float rad;
- int i, j, matched, a, b, numcuts, flag, selaction;
subd_facedata *facedata = NULL;
- V_DECLARE(facedata);
+ float rad;
+ int i, j, matched, a, b, numcuts, flag, selaction, fillindex;
BMO_Flag_Buffer(bmesh, op, BMOP_ESUBDIVIDE_EDGES, SUBD_SPLIT);
BMO_SetFlag(bmesh, edge, SUBD_SPLIT);
}
+ customfill_hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
+ BLI_ghashutil_ptrcmp);
+
+ /*process custom fill patterns*/
+ finput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_CUSTOMFILL_FACES);
+ pinput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_CUSTOMFILL_PATTERNS);
+ for (i=0; i<finput->len; i++) {
+ face = ((BMFace**)finput->data.p)[i];
+ BMO_SetFlag(bmesh, face, FACE_CUSTOMFILL);
+ BLI_ghash_insert(customfill_hash, face,
+ ((void**)pinput->data.p)[i]);
+ }
+
for (face=BMIter_New(&fiter, bmesh, BM_FACES, NULL);
face; face=BMIter_Step(&fiter)) {
/*figure out which pattern to use*/
- i = 0;
+
V_RESET(edges);
V_RESET(verts);
+ i = 0;
for (nl=BMIter_New(&liter, bmesh, BM_LOOPS_OF_FACE, face);
nl; nl=BMIter_Step(&liter)) {
V_GROW(edges);
i++;
}
+ if (BMO_TestFlag(bmesh, face, FACE_CUSTOMFILL)) {
+ pat = BLI_ghash_lookup(customfill_hash, face);
+ for (i=0; i<pat->len; i++) {
+ matched = 1;
+ for (j=0; j<pat->len; j++) {
+ a = (j + i) % pat->len;
+ if ((!!BMO_TestFlag(bmesh, edges[a], SUBD_SPLIT))
+ != (!!pat->seledges[j])) {
+ matched = 0;
+ break;
+ }
+ }
+ if (matched) {
+ V_GROW(facedata);
+ b = V_COUNT(facedata)-1;
+ facedata[b].pat = pat;
+ facedata[b].start = verts[i];
+ break;
+ }
+ }
+ if (!matched) {
+ /*if no match, append null element to array.*/
+ V_GROW(facedata);
+ }
+
+ /*obvously don't test for other patterns matching*/
+ continue;
+ }
+
for (i=0; i<PLEN; i++) {
pat = patterns[i];
if (pat->len == face->len) {
/*figure out which pattern to use*/
V_RESET(verts);
if (BMO_TestFlag(bmesh, face, SUBD_SPLIT) == 0) continue;
-
+
pat = facedata[i].pat;
if (!pat) continue;
# Bounces make to subdirectories.
SOURCEDIR = source/blender/editors
-DIRS = armature mesh animation object sculpt datafiles transform screen curve gpencil physics preview uvedit space_outliner space_time space_view3d interface util space_api space_ipo space_image space_node space_buttons space_info space_file space_sound space_action space_nla space_script space_text space_sequencer
+DIRS = armature mesh animation object sculpt datafiles transform screen curve gpencil physics preview uvedit space_outliner space_time space_view3d interface util space_api space_graph space_image space_node space_buttons space_info space_file space_sound space_action space_nla space_script space_text space_sequencer
include nan_subdirs.mk
'space_file/SConscript',
'space_image/SConscript',
'space_info/SConscript',
- 'space_ipo/SConscript',
+ 'space_graph/SConscript',
'space_node/SConscript',
'space_outliner/SConscript',
'space_time/SConscript',
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
#include "BKE_action.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
-#include "BKE_global.h"
-#include "BKE_scene.h"
#include "BKE_main.h"
-#include "BKE_node.h"
+#include "BKE_scene.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
#include "WM_types.h"
/* ***************** depsgraph calls and anim updates ************* */
-
-static unsigned int screen_view3d_layers(bScreen *screen)
-{
- if(screen) {
- unsigned int layer= screen->scene->lay; /* as minimum this */
- ScrArea *sa;
-
- /* get all used view3d layers */
- for(sa= screen->areabase.first; sa; sa= sa->next) {
- if(sa->spacetype==SPACE_VIEW3D)
- layer |= ((View3D *)sa->spacedata.first)->lay;
- }
- return layer;
- }
- return 0;
-}
+/* ***************** only these can be called from editors ******** */
/* generic update flush, reads from context Screen (layers) and scene */
/* this is for compliancy, later it can do all windows etc */
Scene *scene= CTX_data_scene(C);
bScreen *screen= CTX_wm_screen(C);
- DAG_scene_flush_update(scene, screen_view3d_layers(screen), 0);
+ DAG_scene_flush_update(scene, ED_screen_view3d_layers(screen), 0);
}
/* flushes changes from object to all relations in scene */
Scene *scene= CTX_data_scene(C);
bScreen *screen= CTX_wm_screen(C);
- DAG_object_update_flags(scene, ob, screen_view3d_layers(screen));
+ DAG_object_update_flags(scene, ob, ED_screen_view3d_layers(screen));
}
-/* results in fully updated anim system */
-/* in future sound should be on WM level, only 1 sound can play! */
-void ED_update_for_newframe(const bContext *C, int mute)
-{
- bScreen *screen= CTX_wm_screen(C);
- Scene *scene= screen->scene;
-
- //extern void audiostream_scrub(unsigned int frame); /* seqaudio.c */
-
- /* this function applies the changes too */
- /* XXX future: do all windows */
- scene_update_for_newframe(scene, screen_view3d_layers(screen)); /* BKE_scene.h */
-
- //if ( (CFRA>1) && (!mute) && (scene->audio.flag & AUDIO_SCRUB))
- // audiostream_scrub( CFRA );
-
- /* 3d window, preview */
- //BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
-
- /* all movie/sequence images */
- //BIF_image_update_frame();
-
- /* composite */
- if(scene->use_nodes && scene->nodetree)
- ntreeCompositTagAnimated(scene->nodetree);
-
- /* update animated texture nodes */
- {
- Tex *tex;
- for(tex= G.main->tex.first; tex; tex= tex->id.next)
- if( tex->use_nodes && tex->nodetree ) {
- ntreeTexTagAnimated( tex->nodetree );
- }
- }
-}
-
/* **************************** animation tool notifiers ******************************** */
/* Send notifiers on behalf of animation editing tools, based on various context info
case ANIM_CHANGED_KEYFRAMES_VALUES:
/* keyframe values changed, so transform may have changed */
// XXX what about other cases? maybe we need general ND_KEYFRAMES or ND_ANIMATION?
- WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+ WM_event_add_notifier(C, NC_OBJECT|ND_KEYS|ND_TRANSFORM, NULL);
break;
- case ANIM_CHANGED_KEYFRAMES_SELECT: // XXX what to do here?
- WM_event_add_notifier(C, NC_SCENE, NULL);
+ case ANIM_CHANGED_KEYFRAMES_SELECT:
+ WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL);
break;
case ANIM_CHANGED_CHANNELS:
// XXX err... check available datatypes in dopesheet first?
{
Object *obact= CTX_data_active_object(C);
- // only update active object for now... more detail to come!
- WM_event_add_notifier(C, NC_OBJECT, obact);
+ switch (data_changed) {
+ case ANIM_CHANGED_KEYFRAMES_VALUES:
+ /* keyframe values changed, so transform may have changed */
+ // XXX what about other cases? maybe we need general ND_KEYFRAMES or ND_ANIMATION?
+ WM_event_add_notifier(C, NC_OBJECT|ND_KEYS|ND_TRANSFORM, obact);
+ break;
+ case ANIM_CHANGED_KEYFRAMES_SELECT:
+ WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, obact);
+ break;
+ case ANIM_CHANGED_CHANNELS:
+ // XXX err... check available datatypes in dopesheet first?
+ // FIXME: this currently doesn't work (to update own view)
+ WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE|ND_BONE_SELECT, obact);
+ break;
+ }
+
+ // XXX for now, at least update own editor!
+ ED_area_tag_redraw(CTX_wm_area(C));
}
break;
/* editarmature.c */
void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep);
-EditBone *armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo);
+
+void ARMATURE_OT_align_bones(struct wmOperatorType *ot);
+void ARMATURE_OT_calculate_roll(struct wmOperatorType *ot);
void POSE_OT_hide(struct wmOperatorType *ot);
void POSE_OT_reveil(struct wmOperatorType *ot);
-
+void POSE_OT_rot_clear(struct wmOperatorType *ot);
+void POSE_OT_loc_clear(struct wmOperatorType *ot);
+void POSE_OT_scale_clear(struct wmOperatorType *ot);
#endif /* ED_ARMATURE_INTERN_H */
#include "armature_intern.h"
+/* ************************** quick tests **********************************/
+
+/* XXX This is a quick test operator to print names of all EditBones in context
+ * that should be removed once tool coding starts...
+ */
+
+static int armature_test_exec (bContext *C, wmOperator *op)
+{
+ printf("EditMode Armature Test: \n");
+
+ printf("\tSelected Bones \n");
+ CTX_DATA_BEGIN(C, EditBone*, ebone, selected_bones)
+ {
+ printf("\t\tEditBone '%s' \n", ebone->name);
+ }
+ CTX_DATA_END;
+
+ printf("\tEditable Bones \n");
+ CTX_DATA_BEGIN(C, EditBone*, ebone, selected_editable_bones)
+ {
+ printf("\t\tEditBone '%s' \n", ebone->name);
+ }
+ CTX_DATA_END;
+
+ printf("\tActive Bone \n");
+ {
+ EditBone *ebone= CTX_data_active_bone(C);
+ if (ebone) printf("\t\tEditBone '%s' \n", ebone->name);
+ else printf("\t\t<None> \n");
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void ARMATURE_OT_test(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Test Context";
+ ot->idname= "ARMATURE_OT_test";
+
+ /* api callbacks */
+ ot->exec= armature_test_exec;
+}
/* ************************** registration **********************************/
/* Both operators ARMATURE_OT_xxx and POSE_OT_xxx here */
void ED_operatortypes_armature(void)
{
+ WM_operatortype_append(ARMATURE_OT_align_bones);
+ WM_operatortype_append(ARMATURE_OT_calculate_roll);
+
WM_operatortype_append(POSE_OT_hide);
WM_operatortype_append(POSE_OT_reveil);
+ WM_operatortype_append(POSE_OT_rot_clear);
+ WM_operatortype_append(POSE_OT_loc_clear);
+ WM_operatortype_append(POSE_OT_scale_clear);
+
+ WM_operatortype_append(ARMATURE_OT_test); // XXX temp test for context iterators... to be removed
}
void ED_keymap_armature(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Armature", 0, 0);
+ ListBase *keymap;
wmKeymapItem *kmi;
+ /* Armature ------------------------ */
+ keymap= WM_keymap_listbase(wm, "Armature", 0, 0);
+
/* only set in editmode armature, by space_view3d listener */
// WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0);
-
+ WM_keymap_add_item(keymap, "ARMATURE_OT_align_bones", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_calculate_roll", NKEY, KM_PRESS, KM_CTRL, 0);
+
+ WM_keymap_add_item(keymap, "ARMATURE_OT_test", TKEY, KM_PRESS, 0, 0); // XXX temp test for context iterators... to be removed
+
+ /* Pose ------------------------ */
/* only set in posemode, by space_view3d listener */
keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
kmi= WM_keymap_add_item(keymap, "POSE_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "invert", 1);
WM_keymap_add_item(keymap, "POSE_OT_reveil", HKEY, KM_PRESS, KM_ALT, 0);
-
+ /*clear pose*/
+ WM_keymap_add_item(keymap, "POSE_OT_rot_clear", RKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_loc_clear", GKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
}
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_object.h"
+#include "BKE_report.h"
#include "BKE_subsurf.h"
#include "BKE_utildefines.h"
#include "BKE_modifier.h"
static void error_libdata() {}
static void BIF_undo_push() {}
static void adduplicate() {}
-static void countall() {}
/* ************* XXX *************** */
/* **************** tools on Editmode Armature **************** */
EditBone *ebo;
for (ebo=edbo->first; ebo; ebo= ebo->next) {
- if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
+ if ((ebo->flag & BONE_CONNECTED) && (ebo->parent)) {
if (ebo->parent->flag & BONE_TIPSEL)
ebo->flag |= BONE_ROOTSEL;
else
ebo->flag &= ~BONE_ROOTSEL;
}
+
if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL))
ebo->flag |= BONE_SELECTED;
else
/* recalc/redraw + cleanup */
waitcursor(0);
-
- countall(); // flush!
BIF_undo_push("Separate Armature");
}
}
}
- countall(); // flushes selection!
+ armature_sync_selection(arm->edbo);
if (direction==BONE_SELECT_PARENT)
BIF_undo_push("Select edit bone parent");
selectconnected_posebonechildren (ob, curBone);
}
- countall(); // flushes selection!
+ // XXX this only counted the number of pose channels selected
+ //countall(); // flushes selection!
BIF_undo_push("Select connected");
}
- countall(); // flushes selection!
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Select connected");
}
/* context: editmode armature */
-EditBone *armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo)
+EditBone *ED_armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo)
{
EditBone *eboflip= NULL;
char name[32];
+ if (ebo == NULL)
+ return NULL;
+
BLI_strncpy(name, ebo->name, sizeof(name));
bone_flip_name(name, 0); // 0 = don't strip off number extensions
for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
if (arm->layer & curBone->layer) {
if (curBone->flag & BONE_SELECTED) {
- next = armature_bone_get_mirrored(arm->edbo, curBone);
+ next = ED_armature_bone_get_mirrored(arm->edbo, curBone);
if (next)
next->flag |= BONE_SELECTED;
}
}
- countall(); // flushes selection!
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Delete bone(s)");
}
/* toggle==0: deselect
-toggle==1: swap (based on test)
-toggle==2: only active tag
-toggle==3: swap (no test)
-*/
+ * toggle==1: swap (based on test)
+ * toggle==2: only active tag
+ * toggle==3: swap (no test)
+ */
void deselectall_armature(Object *obedit, int toggle, int doundo)
{
bArmature *arm= obedit->data;
}
}
- countall(); // flushes selection!
+ armature_sync_selection(arm->edbo);
if (doundo) {
if (sel==1) BIF_undo_push("Select All");
else BIF_undo_push("Deselect All");
return roll;
}
-/* Sets the roll value of selected bones, depending on the mode
- * mode == 0: their z-axes point upwards
- * mode == 1: their z-axes point towards 3d-cursor
- */
-void auto_align_armature(Scene *scene, View3D *v3d, short mode)
+
+/* Set roll value for given bone -> Z-Axis Point up (original method) */
+void auto_align_ebone_zaxisup(Scene *scene, View3D *v3d, EditBone *ebone)
+{
+ float delta[3], curmat[3][3];
+ float xaxis[3]={1.0f, 0.0f, 0.0f}, yaxis[3], zaxis[3]={0.0f, 0.0f, 1.0f};
+ float targetmat[3][3], imat[3][3], diffmat[3][3];
+
+ /* Find the current bone matrix */
+ VecSubf(delta, ebone->tail, ebone->head);
+ vec_roll_to_mat3(delta, 0.0f, curmat);
+
+ /* Make new matrix based on y axis & z-up */
+ VECCOPY(yaxis, curmat[1]);
+
+ Mat3One(targetmat);
+ VECCOPY(targetmat[0], xaxis);
+ VECCOPY(targetmat[1], yaxis);
+ VECCOPY(targetmat[2], zaxis);
+ Mat3Ortho(targetmat);
+
+ /* Find the difference between the two matrices */
+ Mat3Inv(imat, targetmat);
+ Mat3MulMat3(diffmat, imat, curmat);
+
+ // old-method... let's see if using mat3_to_vec_roll is more accurate
+ //ebone->roll = atan2(diffmat[2][0], diffmat[2][2]);
+ mat3_to_vec_roll(diffmat, delta, &ebone->roll);
+}
+
+/* Set roll value for given bone -> Z-Axis point towards cursor */
+void auto_align_ebone_tocursor(Scene *scene, View3D *v3d, EditBone *ebone)
{
Object *obedit= scene->obedit; // XXX get from context
- bArmature *arm= obedit->data;
- EditBone *ebone;
- EditBone *flipbone = NULL;
- float delta[3];
- float curmat[3][3];
float *cursor= give_cursor(scene, v3d);
+ float delta[3], curmat[3][3];
+ float mat[4][4], tmat[4][4], imat[4][4];
+ float rmat[4][4], rot[3];
+ float vec[3];
+
+ /* find the current bone matrix as a 4x4 matrix (in Armature Space) */
+ VecSubf(delta, ebone->tail, ebone->head);
+ vec_roll_to_mat3(delta, ebone->roll, curmat);
+ Mat4CpyMat3(mat, curmat);
+ VECCOPY(mat[3], ebone->head);
+
+ /* multiply bone-matrix by object matrix (so that bone-matrix is in WorldSpace) */
+ Mat4MulMat4(tmat, mat, obedit->obmat);
+ Mat4Invert(imat, tmat);
+
+ /* find position of cursor relative to bone */
+ VecMat4MulVecfl(vec, imat, cursor);
+
+ /* check that cursor is in usable position */
+ if ((IS_EQ(vec[0], 0)==0) && (IS_EQ(vec[2], 0)==0)) {
+ /* Compute a rotation matrix around y */
+ rot[1] = atan2(vec[0], vec[2]);
+ rot[0] = rot[2] = 0.0f;
+ EulToMat4(rot, rmat);
- for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
- if (EBONE_VISIBLE(arm, ebone)) {
- if (arm->flag & ARM_MIRROR_EDIT)
- flipbone = armature_bone_get_mirrored(arm->edbo, ebone);
-
- if ((ebone->flag & BONE_SELECTED) ||
- (flipbone && (flipbone->flag & BONE_SELECTED)))
- {
- /* specific method used to calculate roll depends on mode */
- if (mode == 1) {
- /* Z-Axis point towards cursor */
- float mat[4][4], tmat[4][4], imat[4][4];
- float rmat[4][4], rot[3];
- float vec[3];
-
- /* find the current bone matrix as a 4x4 matrix (in Armature Space) */
- VecSubf(delta, ebone->tail, ebone->head);
- vec_roll_to_mat3(delta, ebone->roll, curmat);
- Mat4CpyMat3(mat, curmat);
- VECCOPY(mat[3], ebone->head);
-
- /* multiply bone-matrix by object matrix (so that bone-matrix is in WorldSpace) */
- Mat4MulMat4(tmat, mat, obedit->obmat);
- Mat4Invert(imat, tmat);
-
- /* find position of cursor relative to bone */
- VecMat4MulVecfl(vec, imat, cursor);
-
- /* check that cursor is in usable position */
- if ((IS_EQ(vec[0], 0)==0) && (IS_EQ(vec[2], 0)==0)) {
- /* Compute a rotation matrix around y */
- rot[1] = atan2(vec[0], vec[2]);
- rot[0] = rot[2] = 0.0f;
- EulToMat4(rot, rmat);
-
- /* Multiply the bone matrix by rotation matrix. This should be new bone-matrix */
- Mat4MulMat4(tmat, rmat, mat);
- Mat3CpyMat4(curmat, tmat);
-
- /* Now convert from new bone-matrix, back to a roll value (in radians) */
- mat3_to_vec_roll(curmat, delta, &ebone->roll);
- }
- }
- else {
- /* Z-Axis Point Up */
- float xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0};
- float targetmat[3][3], imat[3][3], diffmat[3][3];
-
- /* Find the current bone matrix */
- VecSubf(delta, ebone->tail, ebone->head);
- vec_roll_to_mat3(delta, 0.0, curmat);
-
- /* Make new matrix based on y axis & z-up */
- VECCOPY (yaxis, curmat[1]);
-
- Mat3One(targetmat);
- VECCOPY (targetmat[0], xaxis);
- VECCOPY (targetmat[1], yaxis);
- VECCOPY (targetmat[2], zaxis);
- Mat3Ortho(targetmat);
-
- /* Find the difference between the two matrices */
- Mat3Inv(imat, targetmat);
- Mat3MulMat3(diffmat, imat, curmat);
-
- ebone->roll = atan2(diffmat[2][0], diffmat[2][2]);
- }
- }
- }
+ /* Multiply the bone matrix by rotation matrix. This should be new bone-matrix */
+ Mat4MulMat4(tmat, rmat, mat);
+ Mat3CpyMat4(curmat, tmat);
+
+ /* Now convert from new bone-matrix, back to a roll value (in radians) */
+ mat3_to_vec_roll(curmat, delta, &ebone->roll);
}
}
+
+static EnumPropertyItem prop_calc_roll_types[] = {
+ {0, "GLOBALUP", "Z-Axis Up", ""},
+ {1, "CURSOR", "Z-Axis to Cursor", ""},
+ {0, NULL, NULL, NULL}
+};
+
+static int armature_calc_roll_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ View3D *v3d= (View3D *)CTX_wm_space_data(C);
+ Object *ob= CTX_data_edit_object(C);
+ void (*roll_func)(Scene *, View3D *, EditBone *) = NULL;
+
+ /* specific method used to calculate roll depends on mode */
+ switch (RNA_enum_get(op->ptr, "type")) {
+ case 1: /* Z-Axis point towards cursor */
+ roll_func= auto_align_ebone_tocursor;
+ break;
+ default: /* Z-Axis Point Up */
+ roll_func= auto_align_ebone_zaxisup;
+ break;
+ }
+
+ /* recalculate roll on selected bones */
+ CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
+ /* roll func is a callback which assumes that all is well */
+ roll_func(scene, v3d, ebone);
+ }
+ CTX_DATA_END;
+
+
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Recalculate Roll";
+ ot->idname= "ARMATURE_OT_calculate_roll";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = armature_calc_roll_exec;
+ ot->poll = ED_operator_editarmature;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "type", prop_calc_roll_types, 0, "Type", "");
+}
+
/* **************** undo for armatures ************** */
static void undoBones_to_editBones(void *lbuv, void *lbev)
BLI_addtail(arm->edbo, bone);
bone->flag |= BONE_TIPSEL;
- bone->weight= 1.0F;
- bone->dist= 0.25F;
- bone->xwidth= 0.1;
- bone->zwidth= 0.1;
- bone->ease1= 1.0;
- bone->ease2= 1.0;
- bone->rad_head= 0.10;
- bone->rad_tail= 0.05;
+ bone->weight= 1.0f;
+ bone->dist= 0.25f;
+ bone->xwidth= 0.1f;
+ bone->zwidth= 0.1f;
+ bone->ease1= 1.0f;
+ bone->ease2= 1.0f;
+ bone->rad_head= 0.10f;
+ bone->rad_tail= 0.05f;
bone->segments= 1;
bone->layer= arm->layer;
/* no primitive support yet */
add_primitive_bone(scene, v3d, rv3d, newob);
- countall(); // flushes selection!
+ //armature_sync_selection(arm->edbo); // XXX which armature?
if ((newob) && !(U.flag & USER_ADD_EDITMODE)) {
ED_armature_from_edit(scene, obedit);
/* we re-use code for mirror editing... */
flipbone= NULL;
if (arm->flag & ARM_MIRROR_EDIT)
- flipbone= armature_bone_get_mirrored(arm->edbo, ebone);
+ flipbone= ED_armature_bone_get_mirrored(arm->edbo, ebone);
for (a=0; a<2; a++) {
if (a==1) {
}
- countall();
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Add Bone");
}
EditBone *curBone;
EditBone *firstDup=NULL; /* The beginning of the duplicated bones in the edbo list */
- countall(); // flushes selection!
+ armature_sync_selection(arm->edbo); // XXX why is this needed?
/* Select mirrored bones */
if (arm->flag & ARM_MIRROR_EDIT) {
for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
if (EBONE_VISIBLE(arm, curBone)) {
if (curBone->flag & BONE_SELECTED) {
- eBone = armature_bone_get_mirrored(arm->edbo, curBone);
+ eBone = ED_armature_bone_get_mirrored(arm->edbo, curBone);
if (eBone)
eBone->flag |= BONE_SELECTED;
}
}
/* undo + updates */
- countall();
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Merge Bones");
}
}
}
}
- countall();
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Hide Bones");
}
}
}
}
- countall();
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Hide Unselected Bones");
}
}
}
}
- countall();
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Reveal Bones");
}
bone_connect_to_existing_parent(actbone);
if (arm->flag & ARM_MIRROR_EDIT) {
- flipbone = armature_bone_get_mirrored(arm->edbo, actbone);
+ flipbone = ED_armature_bone_get_mirrored(arm->edbo, actbone);
if (flipbone)
bone_connect_to_existing_parent(flipbone);
}
* - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
* then just use actbone. Useful when doing upper arm to spine.
*/
- flipbone = armature_bone_get_mirrored(arm->edbo, selbone);
- flippar = armature_bone_get_mirrored(arm->edbo, actbone);
+ flipbone = ED_armature_bone_get_mirrored(arm->edbo, selbone);
+ flippar = ED_armature_bone_get_mirrored(arm->edbo, actbone);
if (flipbone) {
if (flippar)
}
}
- countall(); /* checks selection */
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Make Parent");
return;
if (EBONE_VISIBLE(arm, ebone)) {
if (ebone->flag & BONE_SELECTED) {
if (arm->flag & ARM_MIRROR_EDIT)
- flipbone = armature_bone_get_mirrored(arm->edbo, ebone);
+ flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
if (flipbone)
editbone_clear_parent(flipbone, val);
}
}
- countall(); // checks selection
+ armature_sync_selection(arm->edbo);
BIF_undo_push("Clear Parent");
}
/* we re-use code for mirror editing... */
flipbone= NULL;
if (arm->flag & ARM_MIRROR_EDIT) {
- flipbone= armature_bone_get_mirrored(arm->edbo, ebone);
+ flipbone= ED_armature_bone_get_mirrored(arm->edbo, ebone);
if (flipbone) {
forked= 0; // we extrude 2 different bones
if (flipbone->flag & (BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED))
if (totbone==1 && first) first->flag |= BONE_ACTIVE;
/* Transform the endpoints */
- countall(); // flushes selection!
+ armature_sync_selection(arm->edbo);
// XXX BIF_TransformSetUndo("Extrude");
// initTransform(TFM_TRANSLATION, CTX_NO_PET);
// Transform();
/* try to find mirrored bone on a != 0 */
if (a) {
if (arm->flag & ARM_MIRROR_EDIT)
- ebone= armature_bone_get_mirrored(arm->edbo, mbone);
+ ebone= ED_armature_bone_get_mirrored(arm->edbo, mbone);
else
ebone= NULL;
}
BIF_undo_push("Switch Direction");
}
-/* editbone alignment */
+/* ***************** EditBone Alignment ********************* */
/* helper to fix a ebone position if its parent has moved due to alignment*/
static void fix_connected_bone(EditBone *ebone)
return;
}
-void align_selected_bones(Scene *scene)
+static int armature_align_bones_exec(bContext *C, wmOperator *op)
{
- Object *obedit= scene->obedit; // XXX get from context
- bArmature *arm= obedit->data;
- EditBone *actbone, *ebone, *selbone;
- EditBone *flipbone, *flippar;
- short allchildbones= 0, foundselbone= 0;
+ Object *ob= CTX_data_edit_object(C);
+ bArmature *arm= (bArmature *)ob->data;
+ EditBone *actbone= CTX_data_active_bone(C);
+ EditBone *actmirb= NULL;
- /* find active bone to align to */
- for (actbone = arm->edbo->first; actbone; actbone=actbone->next) {
- if (arm->layer & actbone->layer) {
- if (actbone->flag & BONE_ACTIVE)
- break;
- }
- }
+ /* there must be an active bone */
if (actbone == NULL) {
- error("Needs an active bone");
- return;
- }
-
- /* find selected bones */
- for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
- if (arm->layer & ebone->layer) {
- if ((ebone->flag & BONE_SELECTED) && (ebone != actbone)) {
- foundselbone++;
- if (ebone->parent != actbone) allchildbones= 1;
- }
- }
- }
- /* abort if no selected bones, and active bone doesn't have a parent to work with instead */
- if (foundselbone==0 && actbone->parent==NULL) {
- error("Need selected bone(s)");
- return;
+ BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone");
+ return OPERATOR_CANCELLED;
+ }
+ else if (arm->flag & ARM_MIRROR_EDIT) {
+ /* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
+ * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
+ * (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
+ * This is useful for arm-chains, for example parenting lower arm to upper arm
+ * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
+ * then just use actbone. Useful when doing upper arm to spine.
+ */
+ actmirb= ED_armature_bone_get_mirrored(arm->edbo, actbone);
+ if (actmirb == NULL)
+ actmirb= actbone;
}
- if (foundselbone==0 && actbone->parent) {
+ /* if there is only 1 selected bone, we assume that that is the active bone,
+ * since a user will need to have clicked on a bone (thus selecting it) to make it active
+ */
+ if (CTX_DATA_COUNT(C, selected_editable_bones) <= 1) {
/* When only the active bone is selected, and it has a parent,
* align it to the parent, as that is the only possible outcome.
*/
- bone_align_to_bone(arm->edbo, actbone, actbone->parent);
-
- if (arm->flag & ARM_MIRROR_EDIT) {
- flipbone = armature_bone_get_mirrored(arm->edbo, actbone);
- if (flipbone)
- bone_align_to_bone(arm->edbo, flipbone, flipbone->parent);
+ if (actbone->parent) {
+ bone_align_to_bone(arm->edbo, actbone, actbone->parent);
+
+ if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
+ bone_align_to_bone(arm->edbo, actmirb, actmirb->parent);
}
}
else {
- /* loop through all editbones, aligning all selected bones to the active bone */
- for (selbone = arm->edbo->first; selbone; selbone=selbone->next) {
- if (arm->layer & selbone->layer) {
- if ((selbone->flag & BONE_SELECTED) && (selbone!=actbone)) {
- /* align selbone to actbone */
- bone_align_to_bone(arm->edbo, selbone, actbone);
-
- if (arm->flag & ARM_MIRROR_EDIT) {
- /* - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
- * (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
- * This is useful for arm-chains, for example parenting lower arm to upper arm
- * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
- * then just use actbone. Useful when doing upper arm to spine.
- */
- flipbone = armature_bone_get_mirrored(arm->edbo, selbone);
- flippar = armature_bone_get_mirrored(arm->edbo, actbone);
-
- if (flipbone) {
- if (flippar)
- bone_align_to_bone(arm->edbo, flipbone, flippar);
- else
- bone_align_to_bone(arm->edbo, flipbone, actbone);
- }
- }
- }
- }
+ /* Align 'selected' bones to the active one
+ * - the context iterator contains both selected bones and their mirrored copies,
+ * so we assume that unselected bones are mirrored copies of some selected bone
+ */
+
+ /* align selected bones to the active one */
+ CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
+ if (ebone->flag & BONE_SELECTED)
+ bone_align_to_bone(arm->edbo, ebone, actbone);
+ else
+ bone_align_to_bone(arm->edbo, ebone, actmirb);
}
+ CTX_DATA_END;
}
+
- countall(); /* checks selection */
- BIF_undo_push("Align bones");
-
- return;
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+
+ return OPERATOR_FINISHED;
}
-/* ***************** Pose tools ********************* */
-
-void clear_armature(Scene *scene, Object *ob, char mode)
+void ARMATURE_OT_align_bones(wmOperatorType *ot)
{
- bPoseChannel *pchan;
- bArmature *arm= ob->data;
+ /* identifiers */
+ ot->name= "Align Bones";
+ ot->idname= "ARMATURE_OT_align_bones";
- /* only clear those channels that are not locked */
- for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if (pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
- if (arm->layer & pchan->bone->layer) {
- switch (mode) {
- case 'r':
- if (pchan->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ)) {
- float eul[3], oldeul[3], quat1[4];
-
- QUATCOPY(quat1, pchan->quat);
- QuatToEul(pchan->quat, oldeul);
- eul[0]= eul[1]= eul[2]= 0.0f;
-
- if (pchan->protectflag & OB_LOCK_ROTX)
- eul[0]= oldeul[0];
- if (pchan->protectflag & OB_LOCK_ROTY)
- eul[1]= oldeul[1];
- if (pchan->protectflag & OB_LOCK_ROTZ)
- eul[2]= oldeul[2];
-
- EulToQuat(eul, pchan->quat);
- /* quaternions flip w sign to accumulate rotations correctly */
- if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) {
- QuatMulf(pchan->quat, -1.0f);
- }
- }
- else {
- pchan->quat[1]=pchan->quat[2]=pchan->quat[3]=0.0F;
- pchan->quat[0]=1.0F;
- }
- break;
- case 'g':
- if ((pchan->protectflag & OB_LOCK_LOCX)==0)
- pchan->loc[0]= 0.0f;
- if ((pchan->protectflag & OB_LOCK_LOCY)==0)
- pchan->loc[1]= 0.0f;
- if ((pchan->protectflag & OB_LOCK_LOCZ)==0)
- pchan->loc[2]= 0.0f;
- break;
- case 's':
- if ((pchan->protectflag & OB_LOCK_SCALEX)==0)
- pchan->size[0]= 1.0f;
- if ((pchan->protectflag & OB_LOCK_SCALEY)==0)
- pchan->size[1]= 1.0f;
- if ((pchan->protectflag & OB_LOCK_SCALEZ)==0)
- pchan->size[2]= 1.0f;
- break;
-
- }
-
- /* the current values from IPO's may not be zero, so tag as unkeyed */
- pchan->bone->flag |= BONE_UNKEYED;
- }
- }
- }
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = armature_align_bones_exec;
+ ot->poll = ED_operator_editarmature;
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
- /* no update for this object, this will execute the action again */
- /* is weak... like for ipo editing which uses ctime now... */
- where_is_pose (scene, ob);
- ob->recalc= 0;
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+/* ***************** Pose tools ********************* */
+
/* helper for function below */
static int clear_active_flag(Object *ob, Bone *bone, void *data)
{
}
+// XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer
static int bone_looper(Object *ob, Bone *bone, void *data,
int (*bone_func)(Object *, Bone *, void *))
{
}
}
- countall();
+ //countall(); // XXX need an equivalent to this...
if (doundo) {
if (selectmode==1) BIF_undo_push("Select All");
break;
}
}
+/* ************* Clear Pose *****************************/
+static int pose_clear_scale_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob= CTX_data_active_object(C);
+
+ /* only clear those channels that are not locked */
+ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) {
+ if ((pchan->protectflag & OB_LOCK_SCALEX)==0)
+ pchan->size[0]= 1.0f;
+ if ((pchan->protectflag & OB_LOCK_SCALEY)==0)
+ pchan->size[1]= 1.0f;
+ if ((pchan->protectflag & OB_LOCK_SCALEZ)==0)
+ pchan->size[2]= 1.0f;
+
+ /* the current values from IPO's may not be zero, so tag as unkeyed */
+ //pchan->bone->flag |= BONE_UNKEYED;
+ }
+ CTX_DATA_END;
+
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void POSE_OT_scale_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Clear Pose Scale";
+ ot->idname= "POSE_OT_scale_clear";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = pose_clear_scale_exec;
+ ot->poll = ED_operator_posemode;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int pose_clear_loc_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob= CTX_data_active_object(C);
+
+ /* only clear those channels that are not locked */
+ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) {
+ if ((pchan->protectflag & OB_LOCK_LOCX)==0)
+ pchan->loc[0]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_LOCY)==0)
+ pchan->loc[1]= 0.0f;
+ if ((pchan->protectflag & OB_LOCK_LOCZ)==0)
+ pchan->loc[2]= 0.0f;
+
+ /* the current values from IPO's may not be zero, so tag as unkeyed */
+ //pchan->bone->flag |= BONE_UNKEYED;
+ }
+ CTX_DATA_END;
+
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void POSE_OT_loc_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Clear Pose Location";
+ ot->idname= "POSE_OT_loc_clear";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = pose_clear_loc_exec;
+ ot->poll = ED_operator_posemode;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int pose_clear_rot_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob= CTX_data_active_object(C);
+
+ /* only clear those channels that are not locked */
+ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) {
+ if (pchan->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ)) {
+ float eul[3], oldeul[3], quat1[4];
+
+ if (pchan->rotmode == PCHAN_ROT_QUAT) {
+ QUATCOPY(quat1, pchan->quat);
+ QuatToEul(pchan->quat, oldeul);
+ }
+ else {
+ VECCOPY(oldeul, pchan->eul);
+ }
+ eul[0]= eul[1]= eul[2]= 0.0f;
+
+ if (pchan->protectflag & OB_LOCK_ROTX)
+ eul[0]= oldeul[0];
+ if (pchan->protectflag & OB_LOCK_ROTY)
+ eul[1]= oldeul[1];
+ if (pchan->protectflag & OB_LOCK_ROTZ)
+ eul[2]= oldeul[2];
+
+ if (pchan->rotmode == PCHAN_ROT_QUAT) {
+ EulToQuat(eul, pchan->quat);
+ /* quaternions flip w sign to accumulate rotations correctly */
+ if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) {
+ QuatMulf(pchan->quat, -1.0f);
+ }
+ }
+ else {
+ VECCOPY(pchan->eul, eul);
+ }
+ }
+ else {
+ if (pchan->rotmode == PCHAN_ROT_QUAT) {
+ pchan->quat[1]=pchan->quat[2]=pchan->quat[3]= 0.0f;
+ pchan->quat[0]= 1.0f;
+ }
+ else {
+ pchan->eul[0]= pchan->eul[1]= pchan->eul[2]= 0.0f;
+ }
+ }
+
+ /* the current values from IPO's may not be zero, so tag as unkeyed */
+ //pchan->bone->flag |= BONE_UNKEYED;
+ }
+ CTX_DATA_END;
+
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+ /* note, notifier might evolve */
+ WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void POSE_OT_rot_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Clear Pose Rotation";
+ ot->idname= "POSE_OT_rot_clear";
+
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = pose_clear_rot_exec;
+ ot->poll = ED_operator_posemode;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+}
/* ************* hide/unhide pose bones ******************* */
static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr)
for (ebo= arm->edbo->first; ebo; ebo=ebo->next) {
/* no layer check, correct mirror is more important */
if (ebo->flag & (BONE_TIPSEL|BONE_ROOTSEL)) {
- eboflip= armature_bone_get_mirrored(arm->edbo, ebo);
+ eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebo);
if (eboflip) {
/* we assume X-axis flipping for now */
static void BIF_undo_push() {}
static void countall() {}
static void add_constraint() {}
-static void select_actionchannel_by_name() {}
static void autokeyframe_pose_cb_func() {}
/* ************* XXX *************** */
-
+/* This function is used to indicate that a bone is selected and needs keyframes inserted */
void set_pose_keys (Object *ob)
{
bArmature *arm= ob->data;
if (ob->pose){
for (chan=ob->pose->chanbase.first; chan; chan=chan->next){
Bone *bone= chan->bone;
- if(bone && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer)) {
- chan->flag |= POSE_KEY;
- }
- else {
+ if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer))
+ chan->flag |= POSE_KEY;
+ else
chan->flag &= ~POSE_KEY;
- }
}
}
}
+/* This function is used to process the necessary updates for */
void ED_armature_enter_posemode(bContext *C, Base *base)
{
Object *ob= base->object;
curbone->flag &= ~BONE_ACTIVE;
pabone->flag |= (BONE_ACTIVE|BONE_SELECTED);
- // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier
- select_actionchannel_by_name (ob->action, pchan->name, 0);
- select_actionchannel_by_name (ob->action, pchan->parent->name, 1);
+ // XXX notifiers need to be sent to other editors to update
break;
}
} else { // BONE_SELECT_CHILD
curbone->flag &= ~BONE_ACTIVE;
chbone->flag |= (BONE_ACTIVE|BONE_SELECTED);
- // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier
- select_actionchannel_by_name (ob->action, pchan->name, 0);
- select_actionchannel_by_name (ob->action, pchan->child->name, 1);
+ // XXX notifiers need to be sent to other editors to update
break;
}
}
DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
}
- // XXX this is evil... this sort of stuff is to be handled in one go as a result of a notifier
- select_actionchannel_by_name(ob->action, name, 1);
+ // XXX notifiers need to be sent to other editors to update
}
}
if (ebo->flag & BONE_SELECTED) {
ebo->layer= lay;
if (arm->flag & ARM_MIRROR_EDIT) {
- flipBone = armature_bone_get_mirrored(arm->edbo, ebo);
+ flipBone = ED_armature_bone_get_mirrored(arm->edbo, ebo);
if (flipBone)
flipBone->layer = lay;
}
#include "BKE_object.h"
#include "BKE_utildefines.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
#include "ED_object.h"
void mouse_nurb(bContext *C, short mval[2], int extend)
{
- Object *obedit= CTX_data_edit_object(C); // XXX
+ Object *obedit= CTX_data_edit_object(C);
ListBase *editnurb= curve_get_editcurve(obedit);
Curve *cu= obedit->data;
ViewContext vc;
}
-// rightmouse_transform();
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
if(nu!=get_actNurb(obedit)) {
set_actNurb(obedit, nu);
struct wmEvent;
struct bContext;
struct Object;
+struct uiMenuItem;
void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid);
void transform_operatortypes(void);
void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts);
void BIF_selectTransformOrientationValue(struct bContext *C, int orientation);
+void BIF_menuTransformOrientation(struct bContext *C, struct uiMenuItem *head, void *arg);
char * BIF_menustringTransformOrientation(const struct bContext *C, char *title); /* the returned value was allocated and needs to be freed after use */
int BIF_countTransformOrientation(const struct bContext *C);
/* --------- anim_deps.c, animation updates -------- */
- /* generic update flush, reads from Context screen (layers) and scene */
+ /* generic update flush, does tagged objects only, reads from Context screen (layers) and scene */
void ED_anim_dag_flush_update(const struct bContext *C);
/* only flush object */
void ED_anim_object_flush_update(const struct bContext *C, struct Object *ob);
- /* flush + do the actual update for all involved objects */
-void ED_update_for_newframe(const struct bContext *C, int mute);
/* pose <-> action syncing */
void ANIM_action_to_pose_sync(struct Object *ob);
void mouse_armature(struct bContext *C, short mval[2], int extend);
struct Bone *get_indexed_bone (struct Object *ob, int index);
float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]);
+EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, EditBone *ebo); // XXX this is needed for populating the context iterators
void transform_armature_mirror_update(struct Object *obedit);
void clear_armature(struct Scene *scene, struct Object *ob, char mode);
#define ED_IMAGE_H
struct SpaceImage;
+struct bContext;
/* space_image.c, exported for transform */
struct Image *ED_space_image(struct SpaceImage *sima);
void ED_space_image_size(struct SpaceImage *sima, int *width, int *height);
void ED_space_image_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy);
+/* image_render.c, export for screen_ops.c, render operator */
+void ED_space_image_output(struct bContext *C);
+
#endif /* ED_IMAGE_H */
void EM_select_edge(struct EditEdge *eed, int sel);
void EM_select_face(struct EditFace *efa, int sel);
void EM_select_face_fgon(struct EditMesh *em, struct EditFace *efa, int val);
+void EM_select_swap(struct EditMesh *em);
+void EM_toggle_select_all(struct EditMesh *em);
void EM_selectmode_flush(struct EditMesh *em);
void EM_deselect_flush(struct EditMesh *em);
void EM_selectmode_set(struct EditMesh *em);
struct wmEvent;
struct bContext;
struct SpaceType;
-struct AreagionType;
+struct Scene;
+struct bScreen;
+struct ARegion;
struct uiBlock;
struct rcti;
/* regions */
-void ED_region_do_listen(ARegion *ar, struct wmNotifier *note);
+void ED_region_do_listen(struct ARegion *ar, struct wmNotifier *note);
void ED_region_do_draw(struct bContext *C, struct ARegion *ar);
void ED_region_exit(struct bContext *C, struct ARegion *ar);
void ED_region_pixelspace(struct ARegion *ar);
void ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
void ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc);
+void ED_screen_set(struct bContext *C, struct bScreen *sc);
+void ED_screen_set_scene(struct bContext *C, struct Scene *scene);
void ED_screen_set_subwinactive(struct wmWindow *win, struct wmEvent *event);
void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
void ED_screen_animation_timer(struct bContext *C, int enable);
-void ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
+int ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
void ED_screen_full_prevspace(struct bContext *C);
+/* anim */
+void ED_update_for_newframe(const struct bContext *C, int mute);
+unsigned int ED_screen_view3d_layers(struct bScreen *screen);
void ED_operatortypes_screen(void);
void ED_keymap_screen(struct wmWindowManager *wm);
int ED_operator_node_active(struct bContext *C);
int ED_operator_ipo_active(struct bContext *C);
int ED_operator_sequencer_active(struct bContext *C);
+int ED_operator_image_active(struct bContext *C);
int ED_operator_object_active(struct bContext *C);
int ED_operator_editmesh(struct bContext *C);
int ED_operator_editarmature(struct bContext *C);
int ED_operator_editcurve(struct bContext *C);
int ED_operator_uvedit(struct bContext *C);
+int ED_operator_uvmap(struct bContext *C);
int ED_operator_posemode(struct bContext *C);
/* undo.c */
void ED_undo_push (struct bContext *C, char *str);
void ED_undo_push_op (struct bContext *C, struct wmOperator *op);
+void ED_undo_pop (struct bContext *C);
void ED_OT_undo (struct wmOperatorType *ot);
void ED_OT_redo (struct wmOperatorType *ot);
/* Struct Declarations */
struct ID;
+struct Main;
struct ListBase;
struct ARegion;
struct wmWindow;
void uiMenuItemVal(uiMenuItem *head, const char *name, int icon, int argval);
-void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value);
-void uiMenuItemBooleanO(uiMenuItem *head, char *opname, char *propname, int value);
+void uiMenuItemEnumO(uiMenuItem *head, int icon, char *opname, char *propname, int value);
+void uiMenuItemBooleanO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value);
void uiMenuItemsEnumO(uiMenuItem *head, char *opname, char *propname);
-void uiMenuItemFloatO(uiMenuItem *head, const char *name, char *opname, char *propname, float value);
-void uiMenuItemO(uiMenuItem *head, char *name, int icon);
+void uiMenuItemIntO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value);
+void uiMenuItemFloatO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, float value);
+void uiMenuItemO(uiMenuItem *head, int icon, char *opname);
void uiMenuItemBooleanR(uiMenuItem *head, struct PointerRNA *ptr, char *propname);
void uiMenuItemEnumR(uiMenuItem *head, struct PointerRNA *ptr, char *propname, int value);
* the uiMenu functions inbetween. If it is a simple confirmation menu
* or similar, popups can be created with a single function call. */
-uiMenuItem *uiPupMenuBegin(const char *title);
+uiMenuItem *uiPupMenuBegin(const char *title, int icon);
void uiPupMenuEnd(struct bContext *C, struct uiMenuItem *head);
void uiPupMenu(struct bContext *C, int maxrow, uiMenuHandleFunc func, void *arg, char *str, ...);
-void uiPupMenuOperator(struct bContext *C, int maxrow, struct wmOperator *op, const char *propname, char *str);
void uiPupMenuOkee(struct bContext *C, char *opname, char *str, ...);
void uiPupMenuSaveOver(struct bContext *C, char *opname, char *filename, ...);
void uiPupMenuNotice(struct bContext *C, char *str, ...);
* Functions used to create popup blocks. These are like popup menus
* but allow using all button types and creating an own layout. */
-uiBlock *uiPupBlockBegin(struct bContext *C, const char *title);
-void uiPupBlockEnd(struct bContext *C, uiBlock *block);
+typedef uiBlock* (*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1);
+
+void uiPupBlock(struct bContext *C, uiBlockCreateFunc func, void *arg);
+void uiPupBlockO(struct bContext *C, uiBlockCreateFunc func, void *arg, char *opname, int opcontext);
/* Blocks
*
void uiBoundsBlock(struct uiBlock *block, int addval);
void uiTextBoundsBlock(uiBlock *block, int addval);
-void uiPopupBoundsBlock(uiBlock *block, int addval);
+void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my);
+void uiMenuPopupBoundsBlock(uiBlock *block, int addvall, int mx, int my);
int uiBlocksGetYMin (ListBase *lb);
int uiBlockGetCol (uiBlock *block);
* - PulldownBut: like MenuBut, but creating a uiBlock (for compatibility).
* - BlockBut: buttons that popup a block with more buttons.
* - KeyevtBut: buttons that can be used to turn key events into values.
- * - PickerButtons: buttons like the color picker (for code sharing). */
-
-typedef uiBlock* (*uiBlockCreateFunc)(struct bContext *C, struct ARegion *ar, void *arg1);
-typedef void (*uiIDPoinFuncFP)(struct bContext *C, char *str, struct ID **idpp);
-
-uiBut *uiDefIDPoinBut(struct uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str,
+ * - PickerButtons: buttons like the color picker (for code sharing).
+ * - AutoButR: RNA property button with type automatically defined. */
+
+#define UI_ID_RENAME 1
+#define UI_ID_BROWSE 2
+#define UI_ID_ADD_NEW 4
+#define UI_ID_OPEN 8
+#define UI_ID_ALONE 16
+#define UI_ID_DELETE 32
+#define UI_ID_LOCAL 64
+#define UI_ID_AUTO_NAME 128
+#define UI_ID_FAKE_USER 256
+#define UI_ID_PIN 512
+#define UI_ID_BROWSE_RENDER 1024
+#define UI_ID_FULL (UI_ID_RENAME|UI_ID_BROWSE|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_ALONE|UI_ID_DELETE|UI_ID_LOCAL)
+
+typedef void (*uiIDPoinFuncFP)(struct bContext *C, char *str, struct ID **idpp);
+typedef void (*uiIDPoinFunc)(struct bContext *C, struct ID *id, int event);
+
+uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str,
short x1, short y1, short x2, short y2, void *idpp, char *tip);
+int uiDefIDPoinButs(uiBlock *block, struct Main *main, struct ID *parid, struct ID **id_p, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events);
uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
+uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int x1, int y1, int x2, int y2);
+int uiDefAutoButsRNA(uiBlock *block, struct PointerRNA *ptr);
+
/* Links
*
* Game engine logic brick links. Non-functional currently in 2.5,
* uiButSetCompleteFunc is for tab completion.
*
* uiBlockSetFunc and uiButSetFunc are callbacks run when a button is used,
- * in case events, operators or RNA are not sufficient to handle the button. */
+ * in case events, operators or RNA are not sufficient to handle the button.
+ *
+ * uiButSetNFunc will free the argument with MEM_freeN. */
typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
+typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
void uiBlockSetFunc (uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2);
void uiButSetFunc (uiBut *but, uiButHandleFunc func, void *arg1, void *arg2);
+void uiButSetNFunc (uiBut *but, uiButHandleNFunc func, void *argN, void *arg2);
void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg);
/* specific defines per space should have higher define values */
struct bTheme;
+struct PointerRNA;
// THE CODERS API FOR THEMES:
// get a 3 byte color, blended and shaded between two other char color pointers
void UI_GetColorPtrBlendShade3ubv(char *cp1, char *cp2, char *col, float fac, int offset);
+// get pointer from RNA pointer
+int UI_GetIconRNA(struct PointerRNA *ptr);
struct ScrArea;
block->safety.ymax= block->maxy+xof;
}
-static void ui_popup_bounds_block(const bContext *C, uiBlock *block)
+static void ui_popup_bounds_block(const bContext *C, uiBlock *block, int menu)
{
+ wmWindow *window= CTX_wm_window(C);
int startx, starty, endx, endy, width, height;
int oldbounds, mx, my, xmax, ymax;
oldbounds= block->bounds;
- /* compute bounds */
+ /* compute mouse position with user defined offset */
ui_bounds_block(block);
- mx= block->minx;
- my= block->miny;
+ mx= window->eventstate->x + block->minx + block->mx;
+ my= window->eventstate->y + block->miny + block->my;
- wm_window_get_size(CTX_wm_window(C), &xmax, &ymax);
+ wm_window_get_size(window, &xmax, &ymax);
/* first we ensure wide enough text bounds */
- block->bounds= 50;
- ui_text_bounds_block(block, block->minx);
+ if(menu) {
+ if(block->flag & UI_BLOCK_LOOP) {
+ block->bounds= 50;
+ ui_text_bounds_block(block, block->minx);
+ }
+ }
/* next we recompute bounds */
block->bounds= oldbounds;
block->dobounds= 2;
}
-/* used for menu popups */
-void uiPopupBoundsBlock(uiBlock *block, int addval)
+/* used for block popups */
+void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
{
block->bounds= addval;
block->dobounds= 3;
+ block->mx= mx;
+ block->my= my;
+}
+
+/* used for menu popups */
+void uiMenuPopupBoundsBlock(uiBlock *block, int addval, int mx, int my)
+{
+ block->bounds= addval;
+ block->dobounds= 4;
+ block->mx= mx;
+ block->my= my;
}
void ui_autofill(uiBlock *block)
/* various properties are being compared here, hopfully sufficient
* to catch all cases, but it is simple to add more checks later */
if(but->retval != oldbut->retval) return 0;
- if(but->poin != oldbut->poin || but->pointype != oldbut->pointype) return 0;
if(but->rnapoin.data != oldbut->rnapoin.data) return 0;
if(but->rnaprop != oldbut->rnaprop)
if(but->rnaindex != oldbut->rnaindex) return 0;
if(but->func != oldbut->func) return 0;
+ if(but->funcN != oldbut->funcN) return 0;
if(oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) return 0;
if(oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) return 0;
+ if(!but->funcN && (but->poin != oldbut->poin || but->pointype != oldbut->pointype)) return 0;
return 1;
}
/* after keymaps! */
if(block->dobounds == 1) ui_bounds_block(block);
else if(block->dobounds == 2) ui_text_bounds_block(block, 0.0f);
- else if(block->dobounds == 3) ui_popup_bounds_block(C, block);
+ else if(block->dobounds) ui_popup_bounds_block(C, block, (block->dobounds == 4));
if(block->autofill) ui_autofill(block);
if(block->minx==0.0 && block->maxx==0.0) uiBoundsBlock(block, 0);
void uiBlockSetButLock(uiBlock *block, int val, char *lockstr)
{
- block->lock |= val;
- if(val) block->lockstr= lockstr;
+ if(val) {
+ block->lock |= val;
+ block->lockstr= lockstr;
+ }
}
void uiBlockClearButLock(uiBlock *block)
WM_operator_properties_free(but->opptr);
MEM_freeN(but->opptr);
}
+ if(but->func_argN) MEM_freeN(but->func_argN);
if(but->active) ui_button_active_cancel(C, but);
if(but->str && but->str != but->strdata) MEM_freeN(but->str);
ui_free_link(but->link);
return but->opptr;
}
-void uiBlockSetHandleFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg, int event), void *arg)
+void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg)
{
block->handle_func= func;
block->handle_func_arg= arg;
}
-void uiBlockSetButmFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg, int but_a2), void *arg)
+void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg)
{
block->butm_func= func;
block->butm_func_arg= arg;
}
-void uiBlockSetFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg1, void *arg2), void *arg1, void *arg2)
+void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
{
block->func= func;
block->func_arg1= arg1;
block->drawextra= func;
}
-void uiButSetFunc(uiBut *but, void (*func)(struct bContext *C, void *arg1, void *arg2), void *arg1, void *arg2)
+void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
{
but->func= func;
but->func_arg1= arg1;
but->func_arg2= arg2;
}
-void uiButSetCompleteFunc(uiBut *but, void (*func)(struct bContext *C, char *str, void *arg), void *arg)
+void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
+{
+ but->funcN= funcN;
+ but->func_argN= argN;
+ but->func_arg2= arg2;
+}
+
+void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg)
{
but->autocomplete_func= func;
but->autofunc_arg= arg;
* ***** END GPL LICENSE BLOCK *****
*/
+#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
typedef struct uiAfterFunc {
struct uiAfterFunc *next, *prev;
- void (*func)(struct bContext*, void *, void *);
+ uiButHandleFunc func;
void *func_arg1;
void *func_arg2;
- void (*handle_func)(struct bContext*, void *arg, int event);
+ uiButHandleNFunc funcN;
+ void *func_argN;
+
+ uiBlockHandleFunc handle_func;
void *handle_func_arg;
int retval;
- void (*butm_func)(struct bContext*, void *arg, int event);
+ uiMenuHandleFunc butm_func;
void *butm_func_arg;
int a2;
* handling is done, i.e. menus are closed, in order to avoid conflicts
* with these functions removing the buttons we are working with */
- if(but->func || block->handle_func || (but->type == BUTM && block->butm_func) || but->opname || but->rnaprop) {
+ if(but->func || but->funcN || block->handle_func || (but->type == BUTM && block->butm_func) || but->opname || but->rnaprop) {
after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
after->func= but->func;
after->func_arg1= but->func_arg1;
after->func_arg2= but->func_arg2;
+ after->funcN= but->funcN;
+ after->func_argN= but->func_argN;
+
after->handle_func= block->handle_func;
after->handle_func_arg= block->handle_func_arg;
after->retval= but->retval;
static void ui_apply_but_funcs_after(bContext *C)
{
- uiAfterFunc *after;
+ uiAfterFunc *afterf, after;
ListBase funcs;
/* copy to avoid recursive calls */
funcs= UIAfterFuncs;
UIAfterFuncs.first= UIAfterFuncs.last= NULL;
- for(after=funcs.first; after; after=after->next) {
- if(after->func)
- after->func(C, after->func_arg1, after->func_arg2);
+ for(afterf=funcs.first; afterf; afterf=after.next) {
+ after= *afterf; /* copy to avoid memleak on exit() */
+ BLI_freelinkN(&funcs, afterf);
+
+ if(after.func)
+ after.func(C, after.func_arg1, after.func_arg2);
+ if(after.funcN)
+ after.funcN(C, after.func_argN, after.func_arg2);
- if(after->handle_func)
- after->handle_func(C, after->handle_func_arg, after->retval);
- if(after->butm_func)
- after->butm_func(C, after->butm_func_arg, after->a2);
+ if(after.handle_func)
+ after.handle_func(C, after.handle_func_arg, after.retval);
+ if(after.butm_func)
+ after.butm_func(C, after.butm_func_arg, after.a2);
- if(after->opname)
- WM_operator_name_call(C, after->opname, after->opcontext, after->opptr);
- if(after->opptr) {
- WM_operator_properties_free(after->opptr);
- MEM_freeN(after->opptr);
+ if(after.opname)
+ WM_operator_name_call(C, after.opname, after.opcontext, after.opptr);
+ if(after.opptr) {
+ WM_operator_properties_free(after.opptr);
+ MEM_freeN(after.opptr);
}
- if(after->rnapoin.data)
- RNA_property_update(C, &after->rnapoin, after->rnaprop);
+ if(after.rnapoin.data)
+ RNA_property_update(C, &after.rnapoin, after.rnaprop);
}
-
- BLI_freelistN(&funcs);
}
static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data)
/* ************* number editing for various types ************* */
+static void but_clamped_range(uiBut *but, float *butmin, float *butmax, float *butrange)
+{
+ /* clamp button range to something reasonable in case
+ * we get -inf/inf from RNA properties */
+ *butmin= MAX2(but->min, -1e4f);
+ *butmax= MIN2(but->max, 1e4f);
+ *butrange= *butmax - *butmin;
+}
+
static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
{
- float butrange;
+ float butrange, butmin, butmax;
if(but->type == BUT_CURVE) {
data->cumap= (CurveMapping*)but->poin;
data->value= data->origvalue;
but->editval= &data->value;
- butrange= (but->max - but->min);
- data->dragfstart= (butrange == 0.0)? 0.0f: (data->value - but->min)/butrange;
+ but_clamped_range(but, &butmin, &butmax, &butrange);
+
+ data->dragfstart= (butrange == 0.0)? 0.0f: (data->value - butmin)/butrange;
data->dragf= data->dragfstart;
}
static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx)
{
- float deler, tempf;
+ float deler, tempf, butmin, butmax, butrange;
int lvalue, temp, changed= 0;
if(mx == data->draglastx)
data->dragstartx= mx; /* ignore mouse movement within drag-lock */
}
+ but_clamped_range(but, &butmin, &butmax, &butrange);
+
deler= 500;
if(!ui_is_but_float(but)) {
- if((but->max-but->min)<100) deler= 200.0;
- if((but->max-but->min)<25) deler= 50.0;
+ if((butrange)<100) deler= 200.0;
+ if((butrange)<25) deler= 50.0;
}
deler /= fac;
- if(ui_is_but_float(but) && but->max-but->min > 11) {
+ if(ui_is_but_float(but) && butrange > 11) {
/* non linear change in mouse input- good for high precicsion */
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002);
- } else if (!ui_is_but_float(but) && but->max-but->min > 129) { /* only scale large int buttons */
+ } else if (!ui_is_but_float(but) && butrange > 129) { /* only scale large int buttons */
/* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004);
} else {
/*no scaling */
data->dragf+= ((float)(mx-data->draglastx))/deler ;
}
-
+
if(data->dragf>1.0) data->dragf= 1.0;
if(data->dragf<0.0) data->dragf= 0.0;
data->draglastx= mx;
- tempf= ( but->min + data->dragf*(but->max-but->min));
+ tempf= (butmin + data->dragf*butrange);
if(!ui_is_but_float(but)) {
if(snap) {
if(snap == 2) {
if(tempf==but->min || tempf==but->max);
- else if(but->max-but->min < 2.10) tempf= 0.01*floor(100.0*tempf);
- else if(but->max-but->min < 21.0) tempf= 0.1*floor(10.0*tempf);
+ else if(butrange < 2.10) tempf= 0.01*floor(100.0*tempf);
+ else if(butrange < 21.0) tempf= 0.1*floor(10.0*tempf);
else tempf= floor(tempf);
}
else {
if(tempf==but->min || tempf==but->max);
- else if(but->max-but->min < 2.10) tempf= 0.1*floor(10*tempf);
- else if(but->max-but->min < 21.0) tempf= floor(tempf);
+ else if(butrange < 2.10) tempf= 0.1*floor(10*tempf);
+ else if(butrange < 21.0) tempf= floor(tempf);
else tempf= 10.0*floor(tempf/10.0);
}
}
static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, int ctrl, int mx)
{
- float deler, f, tempf;
+ float deler, f, tempf, butmin, butmax, butrange;
int temp, lvalue, changed= 0;
+ but_clamped_range(but, &butmin, &butmax, &butrange);
+
if(but->type==NUMSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
else if(but->type==HSVSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
else deler= (but->x2-but->x1- 5.0*but->aspect);
f= (f-data->dragfstart)/10.0 + data->dragfstart;
CLAMP(f, 0.0, 1.0);
- tempf= but->min+f*(but->max-but->min);
+ tempf= butmin + f*butrange;
temp= floor(tempf+.5);
if(ctrl) {
if(click) {
float f, h;
- float tempf;
+ float tempf, butmin, butmax, butrange;
int temp;
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ but_clamped_range(but, &butmin, &butmax, &butrange);
+
tempf= data->value;
temp= (int)data->value;
if(but->type==SLI) f= (float)(mx-but->x1)/(but->x2-but->x1-h);
else f= (float)(mx- (but->x1+but->x2)/2)/((but->x2-but->x1)/2 - h);
- f= but->min+f*(but->max-but->min);
+ f= butmin + f*butrange;
if(!ui_is_but_float(but)) {
if(f<temp) temp--;
data= but->active;
retval= WM_UI_HANDLER_CONTINUE;
+ if(but->flag & UI_BUT_DISABLED)
+ return WM_UI_HANDLER_BREAK;
+
/* handle copy-paste */
if(data->state == BUTTON_STATE_HIGHLIGHT) {
if(ELEM(event->type, CKEY, VKEY) && event->val==KM_PRESS && (event->ctrl || event->oskey)) {
button_tooltip_timer_reset(but);
/* automatic open pulldown block timer */
- if(ELEM5(but->type, BLOCK, MENU, PULLDOWN, HMENU, ICONTEXTROW)) {
+ if(ELEM4(but->type, BLOCK, PULLDOWN, HMENU, ICONTEXTROW)) {
if(!data->autoopentimer) {
int time;
if((/*inside &&*/ !menu->menuretval && retval == WM_UI_HANDLER_CONTINUE) || event->type == TIMER) {
but= ui_but_find_activated(ar);
- if(but)
+ if(but) {
+ ScrArea *ctx_area= CTX_wm_area(C);
+ ARegion *ctx_region= CTX_wm_region(C);
+
+ if(menu->ctx_area) CTX_wm_area_set(C, menu->ctx_area);
+ if(menu->ctx_region) CTX_wm_region_set(C, menu->ctx_region);
+
retval= ui_handle_button_event(C, event, but);
+
+ if(menu->ctx_area) CTX_wm_area_set(C, ctx_area);
+ if(menu->ctx_region) CTX_wm_region_set(C, ctx_region);
+ }
else
retval= ui_handle_button_over(C, event, ar);
}
WM_event_remove_ui_handler(&CTX_wm_window(C)->handlers, ui_handler_popup, ui_handler_remove_popup, menu);
if(temp.menuretval == UI_RETURN_OK) {
- if(temp.popup_func) {
- temp.popup_func(C, temp.op_arg, temp.retvalue);
- }
- else if(temp.op_arg) {
- if(temp.propname)
- RNA_enum_set(temp.op_arg->ptr, temp.propname, temp.retvalue);
- WM_operator_call(C, temp.op_arg);
- }
+ if(temp.popup_func)
+ temp.popup_func(C, temp.popup_arg, temp.retvalue);
+ if(temp.opname)
+ WM_operator_name_call(C, temp.opname, temp.opcontext, NULL);
}
- /* always free operator */
- else if(temp.op_arg)
- WM_operator_free(temp.op_arg);
-
}
else {
/* re-enable tooltips */
{
WM_event_add_ui_handler(NULL, handlers, ui_handler_popup, ui_handler_remove_popup, menu);
}
+
void *func_arg1;
void *func_arg2;
+ uiButHandleNFunc funcN;
+ void *func_argN;
+
void (*embossfunc)(int , int , float, float, float, float, float, int);
void (*sliderfunc)(int , float, float, float, float, float, float, int);
char *lockstr;
float xofs, yofs; // offset to parent button
- int bounds, dobounds; // for doing delayed
+ int bounds, dobounds, mx, my; // for doing delayed
int endblock; // uiEndBlock done?
rctf safety; // pulldowns, to detect outside, can differ per case how it is created
int popup;
void (*popup_func)(struct bContext *C, void *arg, int event);
void *popup_arg;
- /* for operator menus */
- struct wmOperator *op_arg;
- const char *propname;
+
+ /* for operator popups */
+ const char *opname;
+ int opcontext;
+ ScrArea *ctx_area;
+ ARegion *ctx_region;
/* return values */
int butretval;
/* create handle */
handle= MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
+ /* store context for operator */
+ handle->ctx_area= CTX_wm_area(C);
+ handle->ctx_region= CTX_wm_region(C);
+
/* create area region */
ar= ui_add_temporary_region(CTX_wm_screen(C));
#define MENU_ITEM_OPNAME 2
#define MENU_ITEM_OPNAME_BOOL 3
#define MENU_ITEM_OPNAME_ENUM 4
-#define MENU_ITEM_OPNAME_FLOAT 5
-#define MENU_ITEM_RNA_BOOL 6
-#define MENU_ITEM_RNA_ENUM 7
-#define MENU_ITEM_LEVEL 8
-#define MENU_ITEM_LEVEL_OPNAME_ENUM 9
-#define MENU_ITEM_LEVEL_RNA_ENUM 10
-#define MENU_ITEM_SEPARATOR 11
+#define MENU_ITEM_OPNAME_INT 5
+#define MENU_ITEM_OPNAME_FLOAT 6
+#define MENU_ITEM_RNA_BOOL 7
+#define MENU_ITEM_RNA_ENUM 8
+#define MENU_ITEM_LEVEL 9
+#define MENU_ITEM_LEVEL_OPNAME_ENUM 10
+#define MENU_ITEM_LEVEL_RNA_ENUM 11
+#define MENU_ITEM_SEPARATOR 12
struct uiMenuItem {
struct uiMenuItem *next, *prev;
char *opname; /* static string */
char *propname; /* static string */
- int retval, enumval, boolval;
+ int retval, enumval, boolval, intval;
float fltval;
int opcontext;
uiMenuHandleFunc eventfunc;
block->themecol= TH_MENU_ITEM;
block->direction= UI_DOWN;
- width= 50; // fixed with, uiPopupBoundsBlock will compute actual width
+ width= 50; // fixed with, uiMenuPopupBoundsBlock will compute actual width
for(item= head->items.first; item; item= item->next) {
if(0) height+= PUP_LABELH; // XXX sepr line
else height+= MENU_BUTTON_HEIGHT;
}
- startx= info->mx;
- starty= info->my-height+MENU_BUTTON_HEIGHT/2;
+ startx= 0;
+ starty= 0;
/* here we go! */
if(head->name[0]) {
y1 -= MENU_BUTTON_HEIGHT;
}
else if(item->type==MENU_ITEM_OPNAME_BOOL) {
- but= uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
+ but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
RNA_boolean_set(uiButGetOperatorPtrRNA(but), item->propname, item->boolval);
y1 -= MENU_BUTTON_HEIGHT;
name= ui_menu_enumpropname(item->opname, item->propname, item->enumval);
BLI_strncpy(bname, name, sizeof(bname));
- but= uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, bname, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
+ but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, bname, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
RNA_enum_set(uiButGetOperatorPtrRNA(but), item->propname, item->enumval);
y1 -= MENU_BUTTON_HEIGHT;
}
- else if(item->type==MENU_ITEM_OPNAME_FLOAT) {
+ else if(item->type==MENU_ITEM_OPNAME_INT) {
but= uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
+ RNA_int_set(uiButGetOperatorPtrRNA(but), item->propname, item->intval);
+
+ y1 -= MENU_BUTTON_HEIGHT;
+ }
+ else if(item->type==MENU_ITEM_OPNAME_FLOAT) {
+ but= uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, item->name, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, "");
RNA_float_set(uiButGetOperatorPtrRNA(but), item->propname, item->fltval);
y1 -= MENU_BUTTON_HEIGHT;
}
else if(item->type==MENU_ITEM_OPNAME) {
- uiDefIconTextButO(block, BUTM, item->opname, head->opcontext, item->icon, NULL, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL);
+ uiDefIconTextButO(block, BUTM, item->opname, item->opcontext, item->icon, NULL, x1, y1, width+16, MENU_BUTTON_HEIGHT-1, NULL);
y1 -= MENU_BUTTON_HEIGHT;
}
else if(item->type==MENU_ITEM_RNA_BOOL) {
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_RET_1);
uiBlockSetDirection(block, UI_DOWN);
- uiPopupBoundsBlock(block, 1);
+ /* here we set an offset for the mouse position */
+ uiMenuPopupBoundsBlock(block, 1, 0, -height+MENU_BUTTON_HEIGHT/2);
}
else {
/* for a header menu we set the direction automatic */
else
item->icon= ICON_BLANK1;
item->retval= argval;
- item->opcontext= WM_OP_EXEC_REGION_WIN;
+
+ item->opcontext= head->opcontext;
BLI_addtail(&head->items, item);
}
/* regular operator item */
-void uiMenuItemO(uiMenuItem *head, char *name, int icon)
+void uiMenuItemO(uiMenuItem *head, int icon, char *opname)
{
- uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
+ uiMenuItem *item= ui_menu_add_item(head, "", icon, 0);
- item->opname= name; // static!
+ item->opname= opname; // static!
item->type = MENU_ITEM_OPNAME;
}
/* single operator item with property */
-void uiMenuItemEnumO(uiMenuItem *head, char *opname, char *propname, int value)
+void uiMenuItemEnumO(uiMenuItem *head, int icon, char *opname, char *propname, int value)
{
- uiMenuItem *item= ui_menu_add_item(head, "", 0, 0);
+ uiMenuItem *item= ui_menu_add_item(head, "", icon, 0);
item->opname= opname; // static!
item->propname= propname; // static!
}
/* single operator item with property */
-void uiMenuItemFloatO(uiMenuItem *head, const char *name, char *opname, char *propname, float value)
+void uiMenuItemIntO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value)
{
- uiMenuItem *item= ui_menu_add_item(head, name, 0, 0);
+ uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
+
+ item->opname= opname; // static!
+ item->propname= propname; // static!
+ item->intval= value;
+ item->type = MENU_ITEM_OPNAME_INT;
+}
+
+/* single operator item with property */
+void uiMenuItemFloatO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, float value)
+{
+ uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
item->opname= opname; // static!
item->propname= propname; // static!
}
/* single operator item with property */
-void uiMenuItemBooleanO(uiMenuItem *head, char *opname, char *propname, int value)
+void uiMenuItemBooleanO(uiMenuItem *head, const char *name, int icon, char *opname, char *propname, int value)
{
- uiMenuItem *item= ui_menu_add_item(head, "", 0, 0);
+ uiMenuItem *item= ui_menu_add_item(head, name, icon, 0);
item->opname= opname; // static!
item->propname= propname; // static!
RNA_property_enum_items(&ptr, prop, &item, &totitem);
for (i=0; i<totitem; i++)
- uiMenuItemEnumO(head, opname, propname, item[i].value);
+ uiMenuItemEnumO(head, 0, opname, propname, item[i].value);
}
}
/*************************** Popup Menu API **************************/
/* only return handler, and set optional title */
-uiMenuItem *uiPupMenuBegin(const char *title)
+uiMenuItem *uiPupMenuBegin(const char *title, int icon)
{
uiMenuItem *item= MEM_callocN(sizeof(uiMenuItem), "menu start");
item->type = MENU_ITEM_TITLE;
item->opcontext= WM_OP_EXEC_REGION_WIN;
+ item->icon= icon;
/* NULL is no title */
if(title)
MEM_freeN(head);
}
-/* This one will set enum propname, call operator and register it, and free the operator itself,
- call it in op->invoke with returning OPERATOR_RUNNING_MODAL */
-/* Note: propname has to be static */
-void uiPupMenuOperator(bContext *C, int maxrow, wmOperator *op, const char *propname, char *str)
-{
- wmWindow *window= CTX_wm_window(C);
- uiPupMenuInfo info;
- uiPopupBlockHandle *menu;
-
- memset(&info, 0, sizeof(info));
- info.mx= window->eventstate->x;
- info.my= window->eventstate->y;
- info.maxrow= maxrow;
- info.instr= str;
-
- menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PUPMENU, &info);
- menu->popup= 1;
-
- UI_add_popup_handlers(&window->handlers, menu);
- WM_event_add_mousemove(C);
-
- menu->op_arg= op;
- menu->propname= propname;
-}
-
-
/* this one only to be called with operatortype name option */
void uiPupMenu(bContext *C, int maxrow, uiMenuHandleFunc func, void *arg, char *str, ...)
{
BLI_dynstr_free(ds);
}
+/*************************** Popup Block API **************************/
+
+void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, int opcontext)
+{
+ wmWindow *window= CTX_wm_window(C);
+ uiPopupBlockHandle *handle;
+
+ handle= ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
+ handle->popup= 1;
+ handle->opname= opname;
+ handle->opcontext= opcontext;
+
+ UI_add_popup_handlers(&window->handlers, handle);
+ WM_event_add_mousemove(C);
+}
+
+void uiPupBlock(bContext *C, uiBlockCreateFunc func, void *arg)
+{
+ uiPupBlockO(C, func, arg, NULL, 0);
+}
+
--- /dev/null
+/**
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_material_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_context.h"
+#include "BKE_idprop.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "ED_util.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#define DEF_BUT_WIDTH 150
+#define DEF_ICON_BUT_WIDTH 20
+#define DEF_BUT_HEIGHT 20
+
+/*************************** RNA Utilities ******************************/
+
+int UI_GetIconRNA(PointerRNA *ptr)
+{
+ StructRNA *rnatype= ptr->type;
+
+ if(rnatype == &RNA_Scene)
+ return ICON_SCENE_DEHLT;
+ else if(rnatype == &RNA_World)
+ return ICON_WORLD;
+ else if(rnatype == &RNA_Object)
+ return ICON_OBJECT;
+ else if(rnatype == &RNA_Mesh)
+ return ICON_MESH;
+ else if(rnatype == &RNA_MeshVertex)
+ return ICON_VERTEXSEL;
+ else if(rnatype == &RNA_MeshEdge)
+ return ICON_EDGESEL;
+ else if(rnatype == &RNA_MeshFace)
+ return ICON_FACESEL;
+ else if(rnatype == &RNA_MeshTextureFace)
+ return ICON_FACESEL_HLT;
+ else if(rnatype == &RNA_VertexGroup)
+ return ICON_VGROUP;
+ else if(rnatype == &RNA_VertexGroupElement)
+ return ICON_VGROUP;
+ else if(rnatype == &RNA_Curve)
+ return ICON_CURVE;
+ else if(rnatype == &RNA_MetaBall)
+ return ICON_MBALL;
+ else if(rnatype == &RNA_MetaElement)
+ return ICON_OUTLINER_DATA_META;
+ else if(rnatype == &RNA_Lattice)
+ return ICON_LATTICE;
+ else if(rnatype == &RNA_Armature)
+ return ICON_ARMATURE;
+ else if(rnatype == &RNA_Bone)
+ return ICON_BONE_DEHLT;
+ else if(rnatype == &RNA_Camera)
+ return ICON_CAMERA;
+ else if(rnatype == &RNA_LocalLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_AreaLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_SpotLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_SunLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_HemiLamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_Lamp)
+ return ICON_LAMP;
+ else if(rnatype == &RNA_Group)
+ return ICON_GROUP;
+ else if(rnatype == &RNA_ParticleSystem)
+ return ICON_PARTICLES;
+ else if(rnatype == &RNA_ParticleSettings)
+ return ICON_PARTICLES;
+ else if(rnatype == &RNA_Material)
+ return ICON_MATERIAL;
+ else if(rnatype == &RNA_Texture)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_TextureSlot)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_WorldTextureSlot)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_MaterialTextureSlot)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_Image)
+ return ICON_TEXTURE;
+ else if(rnatype == &RNA_Screen)
+ return ICON_SPLITSCREEN;
+ else if(rnatype == &RNA_NodeTree)
+ return ICON_NODE;
+ else if(rnatype == &RNA_Text)
+ return ICON_TEXT;
+ else if(rnatype == &RNA_Sound)
+ return ICON_SOUND;
+ else if(rnatype == &RNA_Brush)
+ return ICON_TPAINT_HLT;
+ else if(rnatype == &RNA_Library)
+ return ICON_LIBRARY_DEHLT;
+ else if(rnatype == &RNA_Action)
+ return ICON_ACTION;
+ else if(rnatype == &RNA_FCurve)
+ return ICON_IPO_DEHLT;
+ //else if(rnatype == &RNA_Ipo)
+ // return ICON_IPO_DEHLT;
+ else if(rnatype == &RNA_Key)
+ return ICON_SHAPEKEY;
+ else if(rnatype == &RNA_Main)
+ return ICON_BLENDER;
+ else if(rnatype == &RNA_Struct)
+ return ICON_RNA;
+ else if(rnatype == &RNA_Property)
+ return ICON_RNA;
+ else if(rnatype == &RNA_BooleanProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_IntProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_FloatProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_StringProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_EnumProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_EnumPropertyItem)
+ return ICON_RNA;
+ else if(rnatype == &RNA_PointerProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_CollectionProperty)
+ return ICON_RNA;
+ else if(rnatype == &RNA_GameObjectSettings)
+ return ICON_GAME;
+ else if(rnatype == &RNA_ScriptLink)
+ return ICON_PYTHON;
+
+ /* modifiers */
+ else if(rnatype == &RNA_SubsurfModifier)
+ return ICON_MOD_SUBSURF;
+ else if(rnatype == &RNA_ArmatureModifier)
+ return ICON_ARMATURE;
+ else if(rnatype == &RNA_LatticeModifier)
+ return ICON_LATTICE;
+ else if(rnatype == &RNA_CurveModifier)
+ return ICON_CURVE;
+ else if(rnatype == &RNA_BuildModifier)
+ return ICON_MOD_BUILD;
+ else if(rnatype == &RNA_MirrorModifier)
+ return ICON_MOD_MIRROR;
+ else if(rnatype == &RNA_DecimateModifier)
+ return ICON_MOD_DECIM;
+ else if(rnatype == &RNA_WaveModifier)
+ return ICON_MOD_WAVE;
+ else if(rnatype == &RNA_HookModifier)
+ return ICON_HOOK;
+ else if(rnatype == &RNA_SoftbodyModifier)
+ return ICON_MOD_SOFT;
+ else if(rnatype == &RNA_BooleanModifier)
+ return ICON_MOD_BOOLEAN;
+ else if(rnatype == &RNA_ParticleInstanceModifier)
+ return ICON_MOD_PARTICLEINSTANCE;
+ else if(rnatype == &RNA_ParticleSystemModifier)
+ return ICON_MOD_PARTICLES;
+ else if(rnatype == &RNA_EdgeSplitModifier)
+ return ICON_MOD_EDGESPLIT;
+ else if(rnatype == &RNA_ArrayModifier)
+ return ICON_MOD_ARRAY;
+ else if(rnatype == &RNA_UVProjectModifier)
+ return ICON_MOD_UVPROJECT;
+ else if(rnatype == &RNA_DisplaceModifier)
+ return ICON_MOD_DISPLACE;
+ else
+ return ICON_DOT;
+}
+
+uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, char *name, int x1, int y1, int x2, int y2)
+{
+ uiBut *but=NULL;
+ const char *propname= RNA_property_identifier(ptr, prop);
+ int arraylen= RNA_property_array_length(ptr, prop);
+
+ switch(RNA_property_type(ptr, prop)) {
+ case PROP_BOOLEAN: {
+ int value, length;
+
+ if(arraylen && index == -1)
+ return NULL;
+
+ length= RNA_property_array_length(ptr, prop);
+
+ if(length)
+ value= RNA_property_boolean_get_index(ptr, prop, index);
+ else
+ value= RNA_property_boolean_get(ptr, prop);
+
+ if(name && strcmp(name, "") == 0)
+ name= (value)? "Enabled": "Disabled";
+
+ but= uiDefButR(block, TOG, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ break;
+ }
+ case PROP_INT:
+ case PROP_FLOAT:
+ if(arraylen && index == -1) {
+ if(RNA_property_subtype(ptr, prop) == PROP_COLOR)
+ but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL);
+ }
+ else
+ but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ break;
+ case PROP_ENUM:
+ but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ break;
+ case PROP_STRING:
+ but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ break;
+ case PROP_POINTER: {
+ PointerRNA pptr;
+ PropertyRNA *nameprop;
+ char *text, *descr, textbuf[256];
+ int icon;
+
+ pptr= RNA_property_pointer_get(ptr, prop);
+
+ if(!pptr.data)
+ return NULL;
+
+ icon= UI_GetIconRNA(&pptr);
+ nameprop= RNA_struct_name_property(&pptr);
+
+ if(nameprop) {
+ text= RNA_property_string_get_alloc(&pptr, nameprop, textbuf, sizeof(textbuf));
+ descr= (char*)RNA_property_ui_description(&pptr, prop);
+ but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+ if(text != textbuf)
+ MEM_freeN(text);
+ }
+ else {
+ text= (char*)RNA_struct_ui_name(&pptr);
+ descr= (char*)RNA_property_ui_description(&pptr, prop);
+ but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+ }
+ break;
+ }
+ case PROP_COLLECTION: {
+ char text[256];
+ sprintf(text, "%d items", RNA_property_collection_length(ptr, prop));
+ but= uiDefBut(block, LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
+ uiButSetFlag(but, UI_BUT_DISABLED);
+ break;
+ }
+ default:
+ but= NULL;
+ break;
+ }
+
+ return but;
+}
+
+int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
+{
+ CollectionPropertyIterator iter;
+ PropertyRNA *iterprop, *prop;
+ PropertySubType subtype;
+ char *name, namebuf[128];
+ int a, length, x= 0, y= 0;
+
+ x= 0;
+ y= 0;
+
+ /* create buttons */
+ uiSetCurFont(block, UI_HELVB);
+ uiDefBut(block, LABEL, 0, (char*)RNA_struct_ui_name(ptr), x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+ y -= DEF_BUT_HEIGHT;
+ uiSetCurFont(block, UI_HELV);
+
+ iterprop= RNA_struct_iterator_property(ptr);
+ RNA_property_collection_begin(ptr, iterprop, &iter);
+
+ for(; iter.valid; RNA_property_collection_next(&iter)) {
+ prop= iter.ptr.data;
+
+ if(strcmp(RNA_property_identifier(ptr, prop), "rna_type") == 0)
+ continue;
+
+ if((length= RNA_property_array_length(ptr, prop))) {
+ name= (char*)RNA_property_ui_name(ptr, prop);
+ uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+ }
+ else
+ length= 1;
+
+ subtype= RNA_property_subtype(ptr, prop);
+
+ name= (char*)RNA_property_ui_name(ptr, prop);
+ uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+
+ uiBlockBeginAlign(block);
+
+ if(length <= 16 && subtype == PROP_MATRIX) {
+ /* matrix layout */
+ int size, row, col, butwidth;
+
+ size= ceil(sqrt(length));
+ butwidth= DEF_BUT_WIDTH*2/size;
+ y -= DEF_BUT_HEIGHT;
+
+ for(a=0; a<length; a++) {
+ col= a%size;
+ row= a/size;
+
+ uiDefAutoButR(block, ptr, prop, a, "", x+butwidth*col, y-row*DEF_BUT_HEIGHT, butwidth, DEF_BUT_HEIGHT-1);
+ }
+
+ y -= DEF_BUT_HEIGHT*(length/size);
+ }
+ else if(length <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) {
+ static char *vectoritem[4]= {"X:", "Y:", "Z:", "W:"};
+ static char *quatitem[4]= {"W:", "X:", "Y:", "Z:"};
+ static char *coloritem[4]= {"R:", "G:", "B:", "A:"};
+ int butwidth;
+
+ butwidth= DEF_BUT_WIDTH*2/length;
+ y -= DEF_BUT_HEIGHT;
+
+ for(a=0; a<length; a++) {
+ if(length == 4 && subtype == PROP_ROTATION)
+ name= quatitem[a];
+ else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION)
+ name= vectoritem[a];
+ else
+ name= coloritem[a];
+
+ uiDefAutoButR(block, ptr, prop, a, name, x+butwidth*a, y, butwidth, DEF_BUT_HEIGHT-1);
+ }
+ y -= DEF_BUT_HEIGHT;
+ }
+ else {
+ if(RNA_property_array_length(ptr, prop)) {
+ sprintf(namebuf, "%d:", a+1);
+ name= namebuf;
+ }
+ else
+ name= "";
+
+ uiDefAutoButR(block, ptr, prop, a, name, x+DEF_BUT_WIDTH, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1);
+ y -= DEF_BUT_HEIGHT;
+ }
+
+ uiBlockEndAlign(block);
+ }
+
+ RNA_property_collection_end(&iter);
+
+ return -y;
+}
+
+/***************************** ID Utilities *******************************/
+
+typedef struct uiIDPoinParams {
+ uiIDPoinFunc func;
+ ID **id_p;
+ short id_code;
+ short browsenr;
+} uiIDPoinParams;
+
+static void idpoin_cb(bContext *C, void *arg_params, void *arg_event)
+{
+ Main *bmain;
+ ListBase *lb;
+ uiIDPoinParams *params= (uiIDPoinParams*)arg_params;
+ uiIDPoinFunc func= params->func;
+ ID **id_p= params->id_p;
+ ID *id= *id_p, *idtest;
+ int nr, event= GET_INT_FROM_POINTER(arg_event);
+
+ bmain= CTX_data_main(C);
+ lb= wich_libbase(bmain, params->id_code);
+
+ switch(event) {
+ case UI_ID_RENAME:
+ if(id) test_idbutton(id->name+2);
+ else return;
+ break;
+ case UI_ID_BROWSE: {
+ if(id==0) id= lb->first;
+ if(id==0) return;
+
+ if(params->browsenr== -2) {
+ /* XXX implement or find a replacement
+ * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, ¶ms->browsenr, do_global_buttons); */
+ return;
+ }
+ if(params->browsenr < 0)
+ return;
+
+ for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) {
+ if(nr==params->browsenr) {
+ if(id == idtest)
+ return;
+
+ *id_p= idtest;
+ break;
+ }
+ }
+ break;
+ }
+ case UI_ID_DELETE:
+ *id_p= NULL;
+ break;
+ case UI_ID_FAKE_USER:
+ if(id) {
+ if(id->flag & LIB_FAKEUSER) id->us++;
+ else id->us--;
+ }
+ else return;
+ break;
+ case UI_ID_PIN:
+ break;
+ case UI_ID_ADD_NEW:
+ break;
+ case UI_ID_OPEN:
+ break;
+ case UI_ID_ALONE:
+ if(!id || id->us < 1)
+ return;
+ break;
+ case UI_ID_LOCAL:
+ if(!id || id->us < 1)
+ return;
+ break;
+ case UI_ID_AUTO_NAME:
+ break;
+ }
+
+ if(func)
+ func(C, *id_p, event);
+}
+
+int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID **id_p, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events)
+{
+ ListBase *lb;
+ uiBut *but;
+ ID *id= *id_p;
+ uiIDPoinParams *params, *dup_params;
+ char *str=NULL, str1[10];
+ int len, oldcol, add_addbutton=0;
+
+ /* setup struct that we will pass on with the buttons */
+ params= MEM_callocN(sizeof(uiIDPoinParams), "uiIDPoinParams");
+ params->id_p= id_p;
+ params->id_code= id_code;
+ params->func= func;
+
+ lb= wich_libbase(bmain, id_code);
+
+ /* create buttons */
+ uiBlockBeginAlign(block);
+ oldcol= uiBlockGetCol(block);
+
+ if(id && id->us>1)
+ uiBlockSetCol(block, TH_BUT_SETTING1);
+
+ if((events & UI_ID_PIN) && *pin_p)
+ uiBlockSetCol(block, TH_BUT_SETTING2);
+
+ /* pin button */
+ if(id && (events & UI_ID_PIN)) {
+ but= uiDefIconButS(block, ICONTOG, (events & UI_ID_PIN), ICON_KEY_DEHLT, x, y ,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, pin_p, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what object is selected");
+ uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_PIN));
+ x+= DEF_ICON_BUT_WIDTH;
+ }
+
+ /* browse menu */
+ if(events & UI_ID_BROWSE) {
+ char *extrastr= NULL;
+
+ if(ELEM4(id_code, ID_MA, ID_TE, ID_BR, ID_PA))
+ add_addbutton= 1;
+
+ if(ELEM8(id_code, ID_SCE, ID_SCR, ID_MA, ID_TE, ID_WO, ID_IP, ID_AC, ID_BR) || id_code == ID_PA)
+ extrastr= "ADD NEW %x 32767";
+ else if(id_code==ID_TXT)
+ extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
+ else if(id_code==ID_SO)
+ extrastr= "OPEN NEW %x 32766";
+
+ /* XXX should be moved out of this function
+ uiBlockSetButLock(block, G.scene->id.lib!=0, "Can't edit external libdata");
+ if( id_code==ID_SCE || id_code==ID_SCR ) uiBlockClearButLock(block); */
+
+ /* XXX should be moved out of this function
+ if(curarea->spacetype==SPACE_BUTS)
+ uiBlockSetButLock(block, id_code!=ID_SCR && G.obedit!=0 && G.buts->mainb==CONTEXT_EDITING, "Cannot perform in EditMode"); */
+
+ if(parid)
+ uiBlockSetButLock(block, parid->lib!=0, "Can't edit external libdata");
+
+ if(lb) {
+ if(id_code!=ID_IM || (events & UI_ID_BROWSE_RENDER))
+ IDnames_to_pupstring(&str, NULL, extrastr, lb, id, ¶ms->browsenr);
+ else
+ IMAnames_to_pupstring(&str, NULL, extrastr, lb, id, ¶ms->browsenr);
+ }
+
+ dup_params= MEM_dupallocN(params);
+ but= uiDefButS(block, MENU, 0, str, x, y, DEF_ICON_BUT_WIDTH, DEF_BUT_HEIGHT, &dup_params->browsenr, 0, 0, 0, 0, "Browse existing choices, or add new");
+ uiButSetNFunc(but, idpoin_cb, dup_params, SET_INT_IN_POINTER(UI_ID_BROWSE));
+ x+= DEF_ICON_BUT_WIDTH;
+
+ uiBlockClearButLock(block);
+
+ MEM_freeN(str);
+ }
+
+ uiBlockSetCol(block, oldcol);
+
+ /* text button with name */
+ if(id) {
+ /* name */
+ if(id->us > 1)
+ uiBlockSetCol(block, TH_BUT_SETTING1);
+
+ /* pinned data? */
+ if((events & UI_ID_PIN) && *pin_p)
+ uiBlockSetCol(block, TH_BUT_SETTING2);
+
+ /* redalert overrides pin color */
+ if(id->us<=0)
+ uiBlockSetCol(block, TH_REDALERT);
+
+ uiBlockSetButLock(block, id->lib!=0, "Can't edit external libdata");
+
+ /* name button */
+ if(GS(id->name)==ID_SCE)
+ strcpy(str1, "SCE:");
+ else if(GS(id->name)==ID_SCE)
+ strcpy(str1, "SCR:");
+ else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
+ strcpy(str1, "NT:");
+ else {
+ str1[0]= id->name[0];
+ str1[1]= id->name[1];
+ str1[2]= ':';
+ str1[3]= 0;
+ }
+
+ if(GS(id->name)==ID_IP) len= 110;
+ else if((y) && (GS(id->name)==ID_AC)) len= 100; // comes from button panel (poselib)
+ else if(y) len= 140; // comes from button panel
+ else len= 120;
+
+ but= uiDefBut(block, TEX, 0, str1,x, y, (short)len, DEF_BUT_HEIGHT, id->name+2, 0.0, 21.0, 0, 0, "Displays current Datablock name. Click to change.");
+ uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_RENAME));
+
+ x+= len;
+
+ uiBlockClearButLock(block);
+
+ /* lib make local button */
+ if(id->lib) {
+ if(id->flag & LIB_INDIRECT) uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_DATALIB */,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Indirect Library Datablock. Cannot change.");
+ else {
+ but= uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_PARLIB */, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0,
+ (events & UI_ID_LOCAL)? "Direct linked Library Datablock. Click to make local.": "Direct linked Library Datablock, cannot make local.");
+ uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE));
+ }
+
+ x+= DEF_ICON_BUT_WIDTH;
+ }
+
+ /* number of users / make local button */
+ if((events & UI_ID_ALONE) && id->us>1) {
+ int butwidth;
+
+ uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't make pinned data single-user");
+
+ sprintf(str1, "%d", id->us);
+ butwidth= (id->us<10)? DEF_ICON_BUT_WIDTH: DEF_ICON_BUT_WIDTH+10;
+
+ but= uiDefBut(block, BUT, 0, str1, x, y, butwidth, DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
+ uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE));
+ x+= butwidth;
+
+ uiBlockClearButLock(block);
+ }
+
+ /* delete button */
+ if(events & UI_ID_DELETE) {
+ uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't unlink pinned data");
+ if(parid && parid->lib);
+ else {
+ but= uiDefIconBut(block, BUT, 0, ICON_X, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Deletes link to this Datablock");
+ uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_DELETE));
+ x+= DEF_ICON_BUT_WIDTH;
+ }
+
+ uiBlockClearButLock(block);
+ }
+
+ /* auto name button */
+ if(events & UI_ID_AUTO_NAME) {
+ if(parid && parid->lib);
+ else {
+ but= uiDefIconBut(block, BUT, 0, ICON_AUTO,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Generates an automatic name");
+ uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_AUTO_NAME));
+ x+= DEF_ICON_BUT_WIDTH;
+ }
+ }
+
+ /* fake user button */
+ if(events & UI_ID_FAKE_USER) {
+ but= uiDefButBitS(block, TOG, LIB_FAKEUSER, 0, "F", x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, &id->flag, 0, 0, 0, 0, "Saves this datablock even if it has no users");
+ uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_FAKE_USER));
+ x+= DEF_ICON_BUT_WIDTH;
+ }
+ }
+ /* add new button */
+ else if(add_addbutton) {
+ uiBlockSetCol(block, oldcol);
+ if(parid) uiBlockSetButLock(block, parid->lib!=0, "Can't edit external libdata");
+ dup_params= MEM_dupallocN(params);
+ but= uiDefButS(block, TOG, 0, "Add New", x, y, 110, DEF_BUT_HEIGHT, &dup_params->browsenr, params->browsenr, 32767.0, 0, 0, "Add new data block");
+ uiButSetNFunc(but, idpoin_cb, dup_params, SET_INT_IN_POINTER(UI_ID_ADD_NEW));
+ x+= 110;
+ }
+
+ uiBlockSetCol(block, oldcol);
+ uiBlockEndAlign(block);
+
+ MEM_freeN(params);
+
+ return x;
+}
+
dx= (v2d->cur.xmax - v2d->cur.xmin) * (float)RNA_float_get(op->ptr, "zoomfacx");
dy= (v2d->cur.ymax - v2d->cur.ymin) * (float)RNA_float_get(op->ptr, "zoomfacy");
- /* only move view on an axis if change is allowed */
- if ((v2d->keepzoom & V2D_LOCKOFS_X)==0) {
+ /* only resize view on an axis if change is allowed */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0) {
v2d->cur.xmin += dx;
v2d->cur.xmax -= dx;
}
- if ((v2d->keepzoom & V2D_LOCKOFS_Y)==0) {
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y)==0) {
v2d->cur.ymin += dy;
v2d->cur.ymax -= dy;
}
}
#endif
-void flipface(EditMesh *em, EditFace *efa)
-{
- if(efa->v4) {
- SWAP(EditVert *, efa->v2, efa->v4);
- SWAP(EditEdge *, efa->e1, efa->e4);
- SWAP(EditEdge *, efa->e2, efa->e3);
- EM_data_interp_from_faces(em, efa, NULL, efa, 0, 3, 2, 1);
- }
- else {
- SWAP(EditVert *, efa->v2, efa->v3);
- SWAP(EditEdge *, efa->e1, efa->e3);
- efa->e2->dir= 1-efa->e2->dir;
- EM_data_interp_from_faces(em, efa, NULL, efa, 0, 2, 1, 3);
- }
-
- if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
- else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
-}
-
-void flip_editnormals(EditMesh *em)
-{
- EditFace *efa;
-
- efa= em->faces.first;
- while(efa) {
- if( efa->f & SELECT ){
- flipface(em, efa);
- }
- efa= efa->next;
- }
-
- /* update vertex normals too */
- recalc_editnormals(em);
-
-}
/* does face centers too */
void recalc_editnormals(EditMesh *em)
#include "BLI_editVert.h"
#include "BLI_ghash.h"
+#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BIF_gl.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
+#include "ED_screen.h"
#include "ED_view3d.h"
#include "mesh_intern.h"
static void BIF_undo_push() {}
static void BIF_undo() {}
static void error() {}
-static int pupmenu() {return 0;}
static int qtest() {return 0;}
/* **** XXX ******** */
float y;
} CutCurve;
-static CutCurve *get_mouse_trail(int *len, char mode, char cutmode, struct GHash *gh)
-{
- return NULL; // XXX
-}
-
/* ******************************************************************** */
/* Knife Subdivide Tool. Subdivides edges intersected by a mouse trail
ESC cancels as expected.
Contributed by Robert Wenzlaff (Det. Thorn).
-*/
-/* prototype */
-static float seg_intersect(struct EditEdge * e, CutCurve *c, int len, char mode, struct GHash *gh);
+ 2.5 revamp:
+ - non modal (no menu before cutting)
+ - exit on mouse release
+ - polygon/segment drawing can become handled by WM cb later
-void KnifeSubdivide(Object *obedit, EditMesh *em, char mode)
-{
- EditEdge *eed;
- EditVert *eve;
- CutCurve *curve;
-
- struct GHash *gh;
- int len=0;
- float isect=0.0;
- short numcuts=1;
- float *scr, co[4];
-
- if (em==NULL) return;
-
- if (EM_nvertices_selected(em) < 2) {
- error("No edges are selected to operate on");
- return;
- }
-
- if (mode==KNIFE_PROMPT) {
- short val= pupmenu("Cut Type %t|Exact Line%x1|Midpoints%x2|Multicut%x3");
- if(val<1) return;
- mode = val; // warning, mode is char, pupmenu returns -1 with ESC
- }
-
- if(mode == KNIFE_MULTICUT) {
-// XXX if(button(&numcuts, 2, 128, "Number of Cuts:")==0) return;
- }
-
- /* XXX Set a knife cursor here */
-
- for(eed=em->edges.first; eed; eed= eed->next) eed->tmp.fp = 0.0; /*store percentage of edge cut for KNIFE_EXACT here.*/
-
- /*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
- gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- for(eve=em->verts.first; eve; eve=eve->next){
- scr = MEM_mallocN(sizeof(float)*2, "Vertex Screen Coordinates");
- VECCOPY(co, eve->co);
- co[3]= 1.0;
-// Mat4MulVec4fl(obedit->obmat, co);
-// XXX project_float(co,scr);
- BLI_ghash_insert(gh, eve, scr);
- eve->f1 = 0; /*store vertex intersection flag here*/
-
- }
-
- curve=get_mouse_trail(&len, TRAIL_MIXED, mode, gh);
-
- if (curve && len && mode){
- eed= em->edges.first;
- while(eed) {
- if( eed->v1->f & eed->v2->f & SELECT ){ // NOTE: uses vertex select, subdiv doesnt do edges yet
- isect=seg_intersect(eed, curve, len, mode, gh);
- if (isect) eed->f2= 1;
- else eed->f2=0;
- eed->tmp.fp= isect;
- //printf("isect=%i\n", isect);
- }
- else {
- eed->f2=0;
- eed->f1=0;
- }
- eed= eed->next;
- }
-
- if(mode==KNIFE_EXACT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD,1,SUBDIV_SELECT_ORIG);
- else if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE,1,SUBDIV_SELECT_ORIG);
- else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE,numcuts,SUBDIV_SELECT_ORIG);
+*/
- eed=em->edges.first;
- while(eed){
- eed->f2=0;
- eed->f1=0;
- eed=eed->next;
- }
- }
- /* Return to old cursor and flags...*/
-
- BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
- if (curve) MEM_freeN(curve);
+#define KNIFE_EXACT 1
+#define KNIFE_MIDPOINT 2
+#define KNIFE_MULTICUT 3
- BIF_undo_push("Knife");
-}
+static EnumPropertyItem knife_items[]= {
+ {KNIFE_EXACT, "EXACT", "Exact", ""},
+ {KNIFE_MIDPOINT, "MIDPOINTS", "Midpoints", ""},
+ {KNIFE_MULTICUT, "MULTICUT", "Multicut", ""},
+ {0, NULL, NULL}
+};
/* seg_intersect() Determines if and where a mouse trail intersects an EditEdge */
int i;
//threshold = 0.000001; /*tolerance for vertex intersection*/
-// XXX threshold = scene->toolsettings->select_thresh / 100;
+ // XXX threshold = scene->toolsettings->select_thresh / 100;
/* Get screen coords of verts */
scr = BLI_ghash_lookup(gh, e->v1);
/* Perp. Distance from point to line */
if (m2!=MAXSLOPE) dist=(y12-m2*x12-b2);/* /sqrt(m2*m2+1); Only looking for */
- /* change in sign. Skip extra math */
+ /* change in sign. Skip extra math */
else dist=x22-x12;
if (i==0) lastdist=dist;
/* Found an intersect, calc intersect point */
if (m1==m2){ /* co-incident lines */
- /* cut at 50% of overlap area*/
+ /* cut at 50% of overlap area*/
x1max=MAX2(x11, x12);
x1min=MIN2(x11, x12);
xi= (MIN2(x2max,x1max)+MAX2(x2min,x1min))/2.0;
if ((m2<=1.0)&&(m2>=-1.0)) perc = (xi-x21)/(x22-x21);
else perc=(yi-y21)/(y22-y21); /*lower slope more accurate*/
//isect=32768.0*(perc+0.0000153); /* Percentage in 1/32768ths */
+
break;
}
}
return(perc);
}
-void LoopMenu(Object *obedit, EditMesh *em) /* Called by KKey */
+
+#define MAX_CUTS 256
+
+static int knife_cut_exec(bContext *C, wmOperator *op)
{
- short ret;
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ ARegion *ar= CTX_wm_region(C);
+ EditEdge *eed;
+ EditVert *eve;
+ CutCurve curve[MAX_CUTS];
+ struct GHash *gh;
+ float isect=0.0;
+ float *scr, co[4];
+ int len=0;
+ short numcuts=1, mode= RNA_int_get(op->ptr, "type");
- ret=pupmenu("Loop/Cut Menu %t|Loop Cut (CTRL-R)%x2|"
- "Knife (Exact) %x3|Knife (Midpoints)%x4|Knife (Multicut)%x5");
-
- switch (ret){
- case 2:
- CutEdgeloop(obedit, em, 1);
- break;
- case 3:
- KnifeSubdivide(obedit, em, KNIFE_EXACT);
- break;
- case 4:
- KnifeSubdivide(obedit, em, KNIFE_MIDPOINT);
- break;
- case 5:
- KnifeSubdivide(obedit, em, KNIFE_MULTICUT);
- break;
+ if (EM_nvertices_selected(em) < 2) {
+ error("No edges are selected to operate on");
+ return OPERATOR_CANCELLED;;
}
+ /* get the cut curve */
+ RNA_BEGIN(op->ptr, itemptr, "path") {
+
+ RNA_float_get_array(&itemptr, "loc", (float *)&curve[len]);
+ len++;
+ if(len>= MAX_CUTS) break;
+ }
+ RNA_END;
+
+ if(len<2) return OPERATOR_CANCELLED;
+
+ /*store percentage of edge cut for KNIFE_EXACT here.*/
+ for(eed=em->edges.first; eed; eed= eed->next)
+ eed->tmp.fp = 0.0;
+
+ /*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
+ gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ for(eve=em->verts.first; eve; eve=eve->next){
+ scr = MEM_mallocN(sizeof(float)*2, "Vertex Screen Coordinates");
+ VECCOPY(co, eve->co);
+ co[3]= 1.0;
+ Mat4MulVec4fl(obedit->obmat, co);
+ project_float(ar, co, scr);
+ BLI_ghash_insert(gh, eve, scr);
+ eve->f1 = 0; /*store vertex intersection flag here*/
+
+ }
+
+ eed= em->edges.first;
+ while(eed) {
+ if( eed->v1->f & eed->v2->f & SELECT ){ // NOTE: uses vertex select, subdiv doesnt do edges yet
+ isect= seg_intersect(eed, curve, len, mode, gh);
+ if (isect!=0.0f) eed->f2= 1;
+ else eed->f2=0;
+ eed->tmp.fp= isect;
+ //printf("isect=%i\n", isect);
+ }
+ else {
+ eed->f2=0;
+ eed->f1=0;
+ }
+ eed= eed->next;
+ }
+
+ if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, 1, SUBDIV_SELECT_ORIG);
+ else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, numcuts, SUBDIV_SELECT_ORIG);
+ else esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD, 1, SUBDIV_SELECT_ORIG);
+
+ eed=em->edges.first;
+ while(eed){
+ eed->f2=0;
+ eed->f1=0;
+ eed=eed->next;
+ }
+
+ BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
+
+ return OPERATOR_FINISHED;
+}
+
+
+void MESH_OT_knife_cut(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ ot->name= "Knife Cut";
+ ot->idname= "MESH_OT_knife_cut";
+
+ ot->invoke= WM_gesture_lines_invoke;
+ ot->modal= WM_gesture_lines_modal;
+ ot->exec= knife_cut_exec;
+
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "type", knife_items, KNIFE_EXACT, "Type", "");
+ prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
+
+ /* internal */
+ RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX);
}
+/* ******************************************************* */
+
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static void selectswap_mesh(EditMesh *em) /* UI level */
+void EM_select_swap(EditMesh *em) /* exported for UV */
{
EditVert *eve;
EditEdge *eed;
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
- selectswap_mesh(em);
+ EM_select_swap(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
return OPERATOR_FINISHED;
/* ******************** (de)select all operator **************** */
+void EM_toggle_select_all(EditMesh *em) /* exported for UV */
+{
+ if(EM_nvertices_selected(em))
+ EM_clear_flag_all(em, SELECT);
+ else
+ EM_set_flag_all(em, SELECT);
+}
+
static int toggle_select_all_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
- if( EM_nvertices_selected(em) ) {
- EM_clear_flag_all(em, SELECT);
- }
- else {
- EM_set_flag_all(em, SELECT);
- }
-
-// if (EM_texFaceCheck())
+ EM_toggle_select_all(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
return OPERATOR_FINISHED;
}
}
/* ************************* SEAMS AND EDGES **************** */
-void editmesh_mark_seam(EditMesh *em, int clear)
+static int editmesh_mark_seam(bContext *C, wmOperator *op)
{
- Mesh *me= NULL; // XXX
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ Mesh *me= ((Mesh *)obedit->data);
EditEdge *eed;
+ int clear = RNA_boolean_get(op->ptr, "clear");
/* auto-enable seams drawing */
if(clear==0) {
}
}
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ return OPERATOR_FINISHED;
}
-void editmesh_mark_sharp(EditMesh *em, int set)
+void MESH_OT_mark_seam(wmOperatorType *ot)
{
- Mesh *me= NULL;
+ /* identifiers */
+ ot->name= "Mark seam";
+ ot->idname= "MESH_OT_mark_seam";
+
+ /* api callbacks */
+ ot->exec= editmesh_mark_seam;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
+}
+
+static int editmesh_mark_sharp(bContext *C, wmOperator *op)
+{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ Mesh *me= ((Mesh *)obedit->data);
+ int set = RNA_boolean_get(op->ptr, "set");
EditEdge *eed;
/* auto-enable sharp edge drawing */
}
}
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_mark_sharp(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Mark sharp";
+ ot->idname= "MESH_OT_mark_sharp";
+
+ /* api callbacks */
+ ot->exec= editmesh_mark_sharp;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "set", 0, "Set", "");
}
void BME_Menu() {
switch(ret)
{
case 1:
- editmesh_mark_seam(em, 0);
+ //editmesh_mark_seam(em, 0);
break;
case 2:
- editmesh_mark_seam(em, 1);
+ //editmesh_mark_seam(em, 1);
break;
case 3:
// edge_rotate_selected(em, 2);
/* **************** VERTEX DEFORMS *************** */
-void vertexsmooth(Object *obedit, EditMesh *em)
+static int smooth_vertex(bContext *C, wmOperator *op)
{
- Scene *scene= NULL; // XXX
+ Scene *scene= CTX_data_scene(C);
+ Object *obedit= CTX_data_edit_object(C);
+ Mesh *me= obedit->data;
+ EditMesh *em= me->edit_mesh;
+
EditVert *eve, *eve_mir = NULL;
EditEdge *eed;
float *adror, *adr, fac;
int teller=0;
ModifierData *md= obedit->modifiers.first;
- if(em==NULL) return;
+ if(em==NULL) return OPERATOR_CANCELLED;
/* count */
eve= em->verts.first;
if(eve->f & SELECT) teller++;
eve= eve->next;
}
- if(teller==0) return;
+ if(teller==0) return OPERATOR_CANCELLED;
adr=adror= (float *)MEM_callocN(3*sizeof(float *)*teller, "vertsmooth");
eve= em->verts.first;
recalc_editnormals(em);
+ 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_smooth_vertex(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Smooth Vertex";
+ ot->idname= "MESH_OT_smooth_vertex";
+
+ /* api callbacks */
+ ot->exec= smooth_vertex;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_UNDO;
}
void vertexnoise(Object *obedit, EditMesh *em)
/* props */
RNA_def_float(ot->srna, "percent", 100.0f, 0.0f, 100.0f, "Percent", "DOC_BROKEN", 0.01f, 100.0f);
}
+
+void flipface(EditMesh *em, EditFace *efa)
+{
+ if(efa->v4) {
+ SWAP(EditVert *, efa->v2, efa->v4);
+ SWAP(EditEdge *, efa->e1, efa->e4);
+ SWAP(EditEdge *, efa->e2, efa->e3);
+ EM_data_interp_from_faces(em, efa, NULL, efa, 0, 3, 2, 1);
+ }
+ else {
+ SWAP(EditVert *, efa->v2, efa->v3);
+ SWAP(EditEdge *, efa->e1, efa->e3);
+ efa->e2->dir= 1-efa->e2->dir;
+ EM_data_interp_from_faces(em, efa, NULL, efa, 0, 2, 1, 3);
+ }
+
+ if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
+ else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
+}
+
+
+static int flip_editnormals(bContext *C, wmOperator *op)
+{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditFace *efa;
+
+ efa= em->faces.first;
+ while(efa) {
+ if( efa->f & SELECT ){
+ flipface(em, efa);
+ }
+ efa= efa->next;
+ }
+
+ /* update vertex normals too */
+ recalc_editnormals(em);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_flip_editnormals(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Flip Normals";
+ ot->idname= "MESH_OT_flip_editnormals";
+
+ /* api callbacks */
+ ot->exec= flip_editnormals;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
-/**
- * $Id:
+ /* $Id:
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-void split_mesh(EditMesh *em)
+static int split_mesh(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
- waitcursor(1);
+ WM_cursor_wait(1);
/* make duplicate first */
adduplicateflag(em, SELECT);
delfaceflag(em, 128);
recalc_editnormals(em);
- waitcursor(0);
+ WM_cursor_wait(0);
+
+ 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_split_mesh(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Split Mesh";
+ ot->idname= "MESH_OT_split_mesh";
+
+ /* api callbacks */
+ ot->exec= split_mesh;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-void extrude_repeat_mesh(RegionView3D *rv3d, Object *obedit, EditMesh *em, int steps, float offs)
+
+static int extrude_repeat_mesh(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+
+ int steps = RNA_int_get(op->ptr,"steps");
+
+ float offs = RNA_float_get(op->ptr,"offset");
+
float dvec[3], tmat[3][3], bmat[3][3], nor[3]= {0.0, 0.0, 0.0};
short a;
EM_fgon_flags(em);
-// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ 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_extrude_repeat(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Extrude Repeat Mesh";
+ ot->idname= "MESH_OT_extrude_repeat";
+
+ /* api callbacks */
+ ot->exec= extrude_repeat_mesh;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, 100.0f, "Offset", "", 0.0f, FLT_MAX);
+ RNA_def_int(ot->srna, "steps", 10, 0, 180, "Steps", "", 0, INT_MAX);
+}
+
void spin_mesh(View3D *v3d, Object *obedit, EditMesh *em, int steps, float degr, float *dvec, int mode)
{
Scene *scene= NULL; // XXX from context!
// XXX option beautyfill */
- waitcursor(0);
+ WM_cursor_wait(0);
EM_select_flush(em);
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
}
+
/*GB*/
/*-------------------------------------------------------------------------------*/
/*--------------------------- Edge Based Subdivide ------------------------------*/
free_editface(em, face[1]);
}
+// XXX ton please check
/* only accepts 1 selected edge, or 2 selected faces */
-void edge_rotate_selected(EditMesh *em, int dir)
+static int edge_rotate_selected(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
+ int dir = RNA_int_get(op->ptr,"dir"); // dir == 2 when clockwise and ==1 for counter CW.
EditEdge *eed;
EditFace *efa;
short edgeCount = 0;
}
}
}
- else error("Select one edge or two adjacent faces");
+ else
+ {
+ error("Select one edge or two adjacent faces");
+ return OPERATOR_CANCELLED;
+ }
}
else if(edgeCount==1) {
for(eed= em->edges.first; eed; eed= eed->next) {
}
}
}
- else error("Select one edge or two adjacent faces");
+ else
+ {
+ error("Select one edge or two adjacent faces");
+ return OPERATOR_CANCELLED;
+ }
/* flush selected vertices (again) to edges/faces */
EM_select_flush(em);
+ 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_edge_rotate_selected(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Rotate Selected Edge";
+ ot->idname= "MESH_OT_edge_rotate_selected";
+
+ /* api callbacks */
+ ot->exec= edge_rotate_selected;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_int(ot->srna, "dir", 1, 1, 2, "Direction", "Clockwise and Counter Clockwise", 1, 2);
}
+
/******************* BEVEL CODE STARTS HERE ********************/
/* XXX old bevel not ported yet */
}
}
-void region_to_loop(EditMesh *em)
+static int region_to_loop(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
EditEdge *eed;
EditFace *efa;
// if (EM_texFaceCheck())
}
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_region_to_loop(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Region to Loop";
+ ot->idname= "MESH_OT_region_to_loop";
+
+ /* api callbacks */
+ ot->exec= region_to_loop;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
static int validate_loop(EditMesh *em, Collection *edgecollection)
else return(2);
}
-void loop_to_region(EditMesh *em)
+static int loop_to_region(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
+
EditFace *efa;
ListBase allcollections={NULL,NULL};
Collection *edgecollection;
// if (EM_texFaceCheck())
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_loop_to_region(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Loop to Region";
+ ot->idname= "MESH_OT_loop_to_region";
+
+ /* api callbacks */
+ ot->exec= loop_to_region;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+// XXX please check if these functions do what you want them to
/* texface and vertex color editmode tools for the face menu */
-void mesh_rotate_uvs(EditMesh *em)
+static int mesh_rotate_uvs(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
EditFace *efa;
short change = 0, ccw;
MTFace *tf;
if (!EM_texFaceCheck(em)) {
error("mesh has no uv/image layers");
- return;
+ return OPERATOR_CANCELLED;
}
ccw = (shift);
if (change) {
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
}
+
+ return OPERATOR_FINISHED;
}
-void mesh_mirror_uvs(EditMesh *em)
+static int mesh_mirror_uvs(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
EditFace *efa;
short change = 0, altaxis;
MTFace *tf;
if (!EM_texFaceCheck(em)) {
error("mesh has no uv/image layers");
- return;
+ return OPERATOR_CANCELLED;
}
altaxis = (shift);
if (change) {
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
}
+ return OPERATOR_FINISHED;
}
-void mesh_rotate_colors(EditMesh *em)
+static int mesh_rotate_colors(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
EditFace *efa;
short change = 0, ccw;
MCol tmpcol, *mcol;
if (!EM_vertColorCheck(em)) {
error("mesh has no color layers");
- return;
+ return OPERATOR_CANCELLED;
}
ccw = (shift);
if (change) {
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
}
+
+ return OPERATOR_FINISHED;
}
-void mesh_mirror_colors(EditMesh *em)
+static int mesh_mirror_colors(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+
EditFace *efa;
short change = 0, altaxis;
MCol tmpcol, *mcol;
if (!EM_vertColorCheck(em)) {
error("mesh has no color layers");
- return;
+ return OPERATOR_CANCELLED;
}
altaxis = (shift);
if (change) {
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
}
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_rotate_uvs(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Rotate UVs";
+ ot->idname= "MESH_OT_rotate_uvs";
+
+ /* api callbacks */
+ ot->exec= mesh_rotate_uvs;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+void MESH_OT_mirror_uvs(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Mirror UVs";
+ ot->idname= "MESH_OT_mirror_uvs";
+
+ /* api callbacks */
+ ot->exec= mesh_mirror_uvs;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+void MESH_OT_rotate_colors(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Rotate Colors";
+ ot->idname= "MESH_OT_rotate_colors";
+
+ /* api callbacks */
+ ot->exec= mesh_rotate_colors;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+void MESH_OT_mirror_colors(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Mirror Colors";
+ ot->idname= "MESH_OT_mirror_colors";
+
+ /* api callbacks */
+ ot->exec= mesh_mirror_colors;
+ ot->poll= ED_operator_editmesh;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
static int subdivide_exec(bContext *C, wmOperator *op)
static int subdivs_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- int items;
- char *menu, *p;
-
- items = 4;
-
- menu= MEM_callocN(items * OP_MAX_TYPENAME, "string");
-
- p= menu + sprintf(menu, "%s %%t", "subdiv");
- p+= sprintf(p, "|%s %%x%d", "simple", 3);
- p+= sprintf(p, "|%s %%x%d", "multi", 2);
- p+= sprintf(p, "|%s %%x%d", "fractal", 1);
- p+= sprintf(p, "|%s %%x%d", "smooth", 0);
-
- uiPupMenuOperator(C, 20, op, "index", menu);
- MEM_freeN(menu);
+ uiMenuItem *head;
+
+ head= uiPupMenuBegin("Subdivision Type", 0);
+ uiMenuItemsEnumO(head, "MESH_OT_subdivs", "type");
+ uiPupMenuEnd(C, head);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_CANCELLED;
}
static int subdivs_exec(bContext *C, wmOperator *op)
{
- switch(RNA_int_get(op->ptr, "index"))
+ switch(RNA_int_get(op->ptr, "type"))
{
- case 3: // simple
+ case 0: // simple
subdivide_exec(C,op);
break;
- case 2: // multi
+ case 1: // multi
subdivide_multi_exec(C,op);
break;
- case 1: // fractal;
+ case 2: // fractal;
subdivide_multi_fractal_exec(C,op);
break;
- case 0: //smooth
+ case 3: //smooth
subdivide_smooth_exec(C,op);
break;
}
void MESH_OT_subdivs(wmOperatorType *ot)
{
+ static EnumPropertyItem type_items[]= {
+ {0, "SIMPLE", "Simple", ""},
+ {1, "MULTI", "Multi", ""},
+ {2, "FRACTAL", "Fractal", ""},
+ {3, "SMOOTH", "Smooth", ""},
+ {0, NULL, NULL}};
+
/* identifiers */
ot->name= "subdivs";
ot->idname= "MESH_OT_subdivs";
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/*props */
- RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000);
+ RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
/* this is temp, the ops are different, but they are called from subdivs, so all the possible props should be here as well*/
RNA_def_int(ot->srna, "number_cuts", 4, 0, 100, "Number of Cuts", "", 0, INT_MAX);
/* ******************* editmesh_loop.c */
-#define KNIFE_PROMPT 0
-#define KNIFE_EXACT 1
-#define KNIFE_MIDPOINT 2
-#define KNIFE_MULTICUT 3
-
#define LOOP_SELECT 1
#define LOOP_CUT 2
+void MESH_OT_knife_cut(struct wmOperatorType *ot);
/* ******************* editmesh_mods.c */
void MESH_OT_loop_select(struct wmOperatorType *ot);
void MESH_OT_vertices_to_sphere(struct wmOperatorType *ot);
void MESH_OT_selection_type(struct wmOperatorType *ot);
void MESH_OT_select_multi_loop(struct wmOperatorType *ot);
+void MESH_OT_mark_seam(struct wmOperatorType *ot);
+void MESH_OT_mark_sharp(struct wmOperatorType *ot);
+void MESH_OT_smooth_vertex(struct wmOperatorType *ot);
+void MESH_OT_flip_editnormals(struct wmOperatorType *ot);
extern EditEdge *findnearestedge(struct ViewContext *vc, int *dist);
extern void EM_automerge(int update);
void MESH_OT_edge_flip(struct wmOperatorType *ot);
void MESH_OT_faces_shade_smooth(struct wmOperatorType *ot);
void MESH_OT_faces_shade_solid(struct wmOperatorType *ot);
+void MESH_OT_split_mesh(struct wmOperatorType *ot);
+void MESH_OT_extrude_repeat(struct wmOperatorType *ot);
+void MESH_OT_edge_rotate_selected(struct wmOperatorType *ot);
+void MESH_OT_loop_to_region(struct wmOperatorType *ot);
+void MESH_OT_region_to_loop(struct wmOperatorType *ot);
+
+void MESH_OT_rotate_uvs(struct wmOperatorType *ot);
+void MESH_OT_mirror_uvs(struct wmOperatorType *ot);
+void MESH_OT_rotate_colors(struct wmOperatorType *ot);
+void MESH_OT_mirror_colors(struct wmOperatorType *ot);
void MESH_OT_delete(struct wmOperatorType *ot);
void ED_operatortypes_mesh(void)
{
WM_operatortype_append(MESH_OT_de_select_all);
- WM_operatortype_append(MESH_OT_bmesh_test);
WM_operatortype_append(MESH_OT_select_more);
WM_operatortype_append(MESH_OT_select_less);
WM_operatortype_append(MESH_OT_select_invert);
WM_operatortype_append(MESH_OT_removedoublesflag);
WM_operatortype_append(MESH_OT_extrude);
WM_operatortype_append(MESH_OT_vertices_to_sphere);
-
+ WM_operatortype_append(MESH_OT_split_mesh);
+ WM_operatortype_append(MESH_OT_extrude_repeat);
+ WM_operatortype_append(MESH_OT_edge_rotate_selected);
+ WM_operatortype_append(MESH_OT_loop_to_region);
+ WM_operatortype_append(MESH_OT_region_to_loop);
+
+ WM_operatortype_append(MESH_OT_rotate_uvs);
+ WM_operatortype_append(MESH_OT_mirror_uvs);
+ WM_operatortype_append(MESH_OT_rotate_colors);
+ WM_operatortype_append(MESH_OT_mirror_colors);
+
WM_operatortype_append(MESH_OT_fill);
WM_operatortype_append(MESH_OT_beauty_fill);
WM_operatortype_append(MESH_OT_convert_quads_to_tris);
WM_operatortype_append(MESH_OT_similar_edge_select);
WM_operatortype_append(MESH_OT_similar_face_select);
WM_operatortype_append(MESH_OT_select_multi_loop);
- WM_operatortype_append(MESH_OT_separate);
+ WM_operatortype_append(MESH_OT_mark_seam);
+ WM_operatortype_append(MESH_OT_mark_sharp);
+ WM_operatortype_append(MESH_OT_smooth_vertex);
+ WM_operatortype_append(MESH_OT_flip_editnormals);
+ WM_operatortype_append(MESH_OT_knife_cut);
}
WM_keymap_add_item(keymap, "MESH_OT_shortest_path_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "MESH_OT_bmesh_test", JKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_random", SPACEKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_vertices_to_sphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT , 0);
-
+
+ WM_keymap_add_item(keymap, "MESH_OT_mark_seam", ONEKEY, KM_PRESS, KM_CTRL , 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_mark_seam", ONEKEY, KM_PRESS, KM_ALT , 0)->ptr,"clear",1);
+
+ WM_keymap_add_item(keymap, "MESH_OT_mark_sharp", TWOKEY, KM_PRESS, KM_CTRL , 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_mark_sharp", TWOKEY, KM_PRESS, KM_ALT , 0)->ptr,"set",1);
+
+ WM_keymap_add_item(keymap, "MESH_OT_smooth_vertex", THREEKEY, KM_PRESS, KM_CTRL , 0);
+
+ WM_keymap_add_item(keymap, "MESH_OT_flip_editnormals", THREEKEY, KM_PRESS, KM_ALT , 0);
+
/* temp hotkeys! */
WM_keymap_add_item(keymap, "MESH_OT_similar_vertex_select", GKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "MESH_OT_similar_edge_select", GKEY, KM_PRESS, KM_SHIFT2|KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_convert_quads_to_tris", TKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_convert_tris_to_quads", JKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_split_mesh", FOURKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_extrude_repeat", FOURKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_edge_rotate_selected", FIVEKEY, KM_PRESS, KM_CTRL, 0);
+
+ WM_keymap_add_item(keymap, "MESH_OT_loop_to_region",SIXKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_region_to_loop",SIXKEY, KM_PRESS, KM_ALT, 0);
+
+ WM_keymap_add_item(keymap, "MESH_OT_rotate_uvs",SEVENKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_mirror_uvs",SEVENKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_rotate_colors",EIGHTKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_mirror_colors",EIGHTKEY, KM_PRESS, KM_ALT, 0);
+
+
+
+
/* add/remove */
WM_keymap_add_item(keymap, "MESH_OT_add_edge_face", FKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "MESH_OT_make_fgon", FKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "MESH_OT_clear_fgon", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
+
+
}
static int object_add_primitive_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- uiMenuItem *head= uiPupMenuBegin("Add Object");
+ uiMenuItem *head= uiPupMenuBegin("Add Object", 0);
uiMenuLevelEnumO(head, "OBJECT_OT_mesh_add", "type");
uiMenuLevelEnumO(head, "OBJECT_OT_curve_add", "type");
- uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_SURF);
- uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_MBALL);
- uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_CAMERA);
- uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_LAMP);
- uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_EMPTY);
- uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_ARMATURE);
- uiMenuItemEnumO(head, "OBJECT_OT_object_add", "type", OB_LATTICE);
+ uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_SURF);
+ uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_MBALL);
+ uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_CAMERA);
+ uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_LAMP);
+ uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_EMPTY);
+ uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_ARMATURE);
+ uiMenuItemEnumO(head, 0, "OBJECT_OT_object_add", "type", OB_LATTICE);
uiPupMenuEnd(C, head);
MEM_freeN(base);
}
-void delete_obj(Scene *scene, View3D *v3d, int ok)
+static int object_delete_exec(bContext *C, wmOperator *op)
{
- Base *base, *nbase;
+ Scene *scene= CTX_data_scene(C);
int islamp= 0;
- if(scene->obedit) return; // XXX get from context
- if(scene->id.lib) return;
-
- for(base= FIRSTBASE; base; base= nbase) {
- nbase= base->next;
-
- if(TESTBASE(v3d, base)) {
- if(ok==0) {
- int shift= 0; // XXX
- /* Shift Del is global delete */
- if (shift) {
- if(!okee("Erase selected Object(s) Globally")) return;
- ok= 2;
- } else {
- if(!okee("Erase selected Object(s)")) return;
- ok= 1;
- }
- }
-
-// ED_view3d_exit_paint_modes(C);
+ if(CTX_data_edit_object(C))
+ return OPERATOR_CANCELLED;
+
+ ED_view3d_exit_paint_modes(C);
- if(base->object->type==OB_LAMP) islamp= 1;
+ CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
- if (ok==2) {
- Scene *scene;
- Base *base_other;
-
- for (scene= G.main->scene.first; scene; scene= scene->id.next) {
- if (scene != scene && !(scene->id.lib)) {
- base_other= object_in_scene( base->object, scene );
- if (base_other) {
- ED_base_object_free_and_unlink( scene, base_other );
- }
- }
- }
- }
-
- /* remove from current scene only */
- ED_base_object_free_and_unlink(scene, base);
- }
+ if(base->object->type==OB_LAMP) islamp= 1;
+
+ /* remove from current scene only */
+ ED_base_object_free_and_unlink(scene, base);
}
+ CTX_DATA_END;
if(islamp) reshadeall_displist(scene); /* only frees displist */
-
-// XXX redraw_test_buttons(OBACT);
- allqueue(REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWDATASELECT, 0);
-// allspace(OOPS_TEST, 0);
- allqueue(REDRAWOOPS, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
DAG_scene_sort(scene);
- ED_anim_dag_flush_update(C);
+ ED_anim_dag_flush_update(C);
+
+ WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, CTX_data_scene(C));
+
+ return OPERATOR_FINISHED;
+}
+void OBJECT_OT_delete(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Delete Objects";
+ ot->idname= "OBJECT_OT_delete";
+
+ /* api callbacks */
+ ot->invoke= WM_operator_confirm;
+ ot->exec= object_delete_exec;
+ ot->poll= ED_operator_scene_editable;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
}
+
static void single_object_users__forwardModifierLinks(void *userData, Object *ob, Object **obpoin)
{
ID_NEW(*obpoin);
int armature_clear= 0;
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
- if ((ob->flag & OB_POSEMODE)) {
- /* only clear pose transforms if:
- * - with a mesh in weightpaint mode, it's related armature needs to be cleared
- * - with clearing transform of object being edited at the time
- */
- if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
- clear_armature(scene, ob, 'g');
- armature_clear= 1; /* silly system to prevent another dag update, so no action applied */
- }
- }
- else if((G.f & G_WEIGHTPAINT)==0) {
+ if((G.f & G_WEIGHTPAINT)==0) {
if ((ob->protectflag & OB_LOCK_LOCX)==0)
ob->loc[0]= ob->dloc[0]= 0.0f;
if ((ob->protectflag & OB_LOCK_LOCY)==0)
int armature_clear= 0;
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
- if ((ob->flag & OB_POSEMODE)) {
- /* only clear pose transforms if:
- * - with a mesh in weightpaint mode, it's related armature needs to be cleared
- * - with clearing transform of object being edited at the time
- */
- if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
- clear_armature(scene, ob, 'r');
- armature_clear= 1; /* silly system to prevent another dag update, so no action applied */
- }
- }
- else if((G.f & G_WEIGHTPAINT)==0) {
+ if((G.f & G_WEIGHTPAINT)==0) {
/* eulers can only get cleared if they are not protected */
if ((ob->protectflag & OB_LOCK_ROTX)==0)
ob->rot[0]= ob->drot[0]= 0.0f;
int armature_clear= 0;
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
- if ((ob->flag & OB_POSEMODE)) {
- /* only clear pose transforms if:
- * - with a mesh in weightpaint mode, it's related armature needs to be cleared
- * - with clearing transform of object being edited at the time
- */
- if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
- clear_armature(scene, ob, 's');
- armature_clear= 1; /* silly system to prevent another dag update, so no action applied */
- }
- }
- else if((G.f & G_WEIGHTPAINT)==0) {
+ &nbs