void WM_check(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); /* wm context */ if (wm == NULL) { wm = CTX_data_main(C)->wm.first; CTX_wm_manager_set(C, wm); } if (wm == NULL || BLI_listbase_is_empty(&wm->windows)) { return; } if (!G.background) { /* case: fileread */ if ((wm->initialized & WM_INIT_WINDOW) == 0) { WM_keymap_init(C); WM_autosave_init(wm); } /* case: no open windows at all, for old file reads */ wm_window_add_ghostwindows(wm); } /* case: fileread */ /* note: this runs in bg mode to set the screen context cb */ if ((wm->initialized & WM_INIT_WINDOW) == 0) { ED_screens_initialize(wm); wm->initialized |= WM_INIT_WINDOW; } }
static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; MDeformVert *dv; BPoint *bp; int a, tot; if (BLI_listbase_is_empty(&obedit->defbase) || lt->dvert == NULL) { BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object"); return OPERATOR_CANCELLED; } if (!RNA_boolean_get(op->ptr, "extend")) { ED_lattice_flags_set(obedit, 0); } dv = lt->dvert; tot = lt->pntsu * lt->pntsv * lt->pntsw; for (a = 0, bp = lt->def; a < tot; a++, bp++, dv++) { if (bp->hide == 0) { if (dv->dw == NULL) { bp->f1 |= SELECT; } } } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); return OPERATOR_FINISHED; }
/* Remove the given bone-group (expects 'virtual' index (+1 one, used by active_group etc.)) * index might be invalid ( < 1), in which case it will be find from grp. */ void BKE_pose_remove_group(bPose *pose, bActionGroup *grp, const int index) { bPoseChannel *pchan; int idx = index; if (idx < 1) { idx = BLI_findindex(&pose->agroups, grp) + 1; } BLI_assert(idx > 0); /* adjust group references (the trouble of using indices!): * - firstly, make sure nothing references it * - also, make sure that those after this item get corrected */ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->agrp_index == idx) pchan->agrp_index = 0; else if (pchan->agrp_index > idx) pchan->agrp_index--; } /* now, remove it from the pose */ BLI_freelinkN(&pose->agroups, grp); if (pose->active_group >= idx) { const bool has_groups = !BLI_listbase_is_empty(&pose->agroups); pose->active_group--; if (pose->active_group == 0 && has_groups) { pose->active_group = 1; } else if (pose->active_group < 0 || !has_groups) { pose->active_group = 0; } } }
/* helper - add NLA Tracks to empty (and selected) AnimData blocks */ bool nlaedit_add_tracks_empty(bAnimContext *ac) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; bool added = false; /* get a list of the selected AnimData blocks in the NLA */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS); ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); /* check if selected AnimData blocks are empty, and add tracks if so... */ for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ale->adt; /* sanity check */ BLI_assert(adt->flag & ADT_UI_SELECTED); /* ensure it is empty */ if (BLI_listbase_is_empty(&adt->nla_tracks)) { /* add new track to this AnimData block then */ add_nlatrack(adt, NULL); added = true; } } /* cleanup */ ANIM_animdata_freelist(&anim_data); return added; }
static void ui_node_sock_name(bNodeSocket *sock, char name[UI_MAX_NAME_STR]) { if (sock->link && sock->link->fromnode) { bNode *node = sock->link->fromnode; char node_name[UI_MAX_NAME_STR]; if (node->type == NODE_GROUP) { if (node->id) BLI_strncpy(node_name, node->id->name + 2, UI_MAX_NAME_STR); else BLI_strncpy(node_name, N_(node->typeinfo->ui_name), UI_MAX_NAME_STR); } else BLI_strncpy(node_name, node->typeinfo->ui_name, UI_MAX_NAME_STR); if (BLI_listbase_is_empty(&node->inputs) && node->outputs.first != node->outputs.last) { BLI_snprintf(name, UI_MAX_NAME_STR, "%s | %s", IFACE_(node_name), IFACE_(sock->link->fromsock->name)); } else { BLI_strncpy(name, IFACE_(node_name), UI_MAX_NAME_STR); } } else if (sock->type == SOCK_SHADER) BLI_strncpy(name, IFACE_("None"), UI_MAX_NAME_STR); else BLI_strncpy(name, IFACE_("Default"), UI_MAX_NAME_STR); }
static void vpaint_proj_dm_map_cosnos_update( struct VertProjHandle *vp_handle, ARegion *ar, const float mval_fl[2]) { struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl}; Scene *scene = vp_handle->scene; Object *ob = vp_handle->ob; Mesh *me = ob->data; DerivedMesh *dm; /* quick sanity check - we shouldn't have to run this if there are no modifiers */ BLI_assert(BLI_listbase_is_empty(&ob->modifiers) == false); dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); /* highly unlikely this will become unavailable once painting starts (perhaps with animated modifiers) */ if (LIKELY(dm->foreachMappedVert)) { copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX); dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, DM_FOREACH_USE_NORMAL); } dm->release(dm); }
static int rna_KeyingSet_active_ksPath_editable(PointerRNA *ptr) { KeyingSet *ks = (KeyingSet *)ptr->data; /* only editable if there are some paths to change to */ return (BLI_listbase_is_empty(&ks->paths) == false) ? PROP_EDITABLE : 0; }
/* Draw Scene-Markers in time window */ void ED_markers_draw(const bContext *C, int flag) { ListBase *markers = ED_context_get_markers(C); View2D *v2d; TimeMarker *marker; Scene *scene; int select_pass; int v2d_clip_range_x[2]; float font_width_max; /* cache values */ float ypixels, xscale, yscale; if (markers == NULL || BLI_listbase_is_empty(markers)) { return; } scene = CTX_data_scene(C); v2d = UI_view2d_fromcontext(C); if (flag & DRAW_MARKERS_MARGIN) { const unsigned char shade[4] = {0, 0, 0, 16}; glColor4ubv(shade); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glRectf(v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y); glDisable(GL_BLEND); } /* no time correction for framelen! space is drawn with old values */ ypixels = BLI_rcti_size_y(&v2d->mask); UI_view2d_scale_get(v2d, &xscale, &yscale); glScalef(1.0f / xscale, 1.0f, 1.0f); /* x-bounds with offset for text (adjust for long string, avoid checking string width) */ font_width_max = (10 * UI_DPI_FAC) / xscale; v2d_clip_range_x[0] = v2d->cur.xmin - (sizeof(marker->name) * font_width_max); v2d_clip_range_x[1] = v2d->cur.xmax + font_width_max; /* loop [unselected, selected] */ for (select_pass = 0; select_pass <= SELECT; select_pass += SELECT) { /* unselected markers are drawn at the first time */ for (marker = markers->first; marker; marker = marker->next) { if ((marker->flag & SELECT) == select_pass) { /* bounds check */ if ((marker->frame >= v2d_clip_range_x[0]) && (marker->frame <= v2d_clip_range_x[1])) { draw_marker(v2d, marker, scene->r.cfra, flag, ypixels, xscale, yscale); } } } } glScalef(xscale, 1.0f, 1.0f); }
static void wm_init_reports(bContext *C) { ReportList *reports = CTX_wm_reports(C); BLI_assert(!reports || BLI_listbase_is_empty(&reports->list)); BKE_reports_init(reports, RPT_STORE); }
/* Paste the variables in the buffer to the given FCurve */ bool ANIM_driver_vars_paste(ReportList *reports, FCurve *fcu, bool replace) { ChannelDriver *driver = (fcu) ? fcu->driver : NULL; ListBase tmp_list = {NULL, NULL}; /* sanity checks */ if (BLI_listbase_is_empty(&driver_vars_copybuf)) { BKE_report(reports, RPT_ERROR, "No driver variables in clipboard to paste"); return false; } if (ELEM(NULL, fcu, fcu->driver)) { BKE_report(reports, RPT_ERROR, "Cannot paste driver variables without a driver"); return false; } /* 1) Make a new copy of the variables in the buffer - these will get pasted later... */ driver_variables_copy(&tmp_list, &driver_vars_copybuf); /* 2) Prepare destination array */ if (replace) { DriverVar *dvar, *dvarn; /* Free all existing vars first - We aren't retaining anything */ for (dvar = driver->variables.first; dvar; dvar = dvarn) { dvarn = dvar->next; driver_free_variable_ex(driver, dvar); } BLI_listbase_clear(&driver->variables); } /* 3) Add new vars */ if (driver->variables.last) { DriverVar *last = driver->variables.last; DriverVar *first = tmp_list.first; last->next = first; first->prev = last; driver->variables.last = tmp_list.last; } else { driver->variables.first = tmp_list.first; driver->variables.last = tmp_list.last; } #ifdef WITH_PYTHON /* since driver variables are cached, the expression needs re-compiling too */ if (driver->type == DRIVER_TYPE_PYTHON) driver->flag |= DRIVER_FLAG_RENAMEVAR; #endif return true; }
/* not region itself */ void BKE_area_region_free(SpaceType *st, ARegion *ar) { uiList *uilst; if (st) { ARegionType *art = BKE_regiontype_from_id(st, ar->regiontype); if (art && art->free) art->free(ar); if (ar->regiondata) printf("regiondata free error\n"); } else if (ar->type && ar->type->free) ar->type->free(ar); if (ar->v2d.tab_offset) { MEM_freeN(ar->v2d.tab_offset); ar->v2d.tab_offset = NULL; } if (!BLI_listbase_is_empty(&ar->panels)) { Panel *pa, *pa_next; for (pa = ar->panels.first; pa; pa = pa_next) { pa_next = pa->next; if (pa->activedata) { MEM_freeN(pa->activedata); } MEM_freeN(pa); } } for (uilst = ar->ui_lists.first; uilst; uilst = uilst->next) { if (uilst->dyn_data) { uiListDyn *dyn_data = uilst->dyn_data; if (dyn_data->items_filter_flags) { MEM_freeN(dyn_data->items_filter_flags); } if (dyn_data->items_filter_neworder) { MEM_freeN(dyn_data->items_filter_neworder); } MEM_freeN(dyn_data); } if (uilst->properties) { IDP_FreeProperty(uilst->properties); MEM_freeN(uilst->properties); } } BLI_freelistN(&ar->ui_lists); BLI_freelistN(&ar->ui_previews); BLI_freelistN(&ar->panels_category); BLI_freelistN(&ar->panels_category_active); }
/* Copy the given driver's variables to the buffer */ bool ANIM_driver_vars_copy(ReportList *reports, FCurve *fcu) { /* sanity checks */ if (ELEM(NULL, fcu, fcu->driver)) { BKE_report(reports, RPT_ERROR, "No driver to copy variables from"); return false; } if (BLI_listbase_is_empty(&fcu->driver->variables)) { BKE_report(reports, RPT_ERROR, "Driver has no variables to copy"); return false; } /* clear buffer */ ANIM_driver_vars_copybuf_free(); /* copy over the variables */ driver_variables_copy(&driver_vars_copybuf, &fcu->driver->variables); return (BLI_listbase_is_empty(&driver_vars_copybuf) == false); }
static int copy_particle_systems_poll(bContext *C) { Object *ob; if (!ED_operator_object_active_editable(C)) return false; ob = ED_object_active_context(C); if (BLI_listbase_is_empty(&ob->particlesystem)) return false; return true; }
/* basic vertex data functions */ bool BKE_mball_minmax(MetaBall *mb, float min[3], float max[3]) { MetaElem *ml; INIT_MINMAX(min, max); for (ml = mb->elems.first; ml; ml = ml->next) { minmax_v3v3_v3(min, max, &ml->x); } return (BLI_listbase_is_empty(&mb->elems) == false); }
static int vert_select_ungrouped_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); Mesh *me = ob->data; if (BLI_listbase_is_empty(&ob->defbase) || (me->dvert == NULL)) { BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object"); return OPERATOR_CANCELLED; } paintvert_select_ungrouped(ob, RNA_boolean_get(op->ptr, "extend"), true); ED_region_tag_redraw(CTX_wm_region(C)); return OPERATOR_FINISHED; }
static unsigned int *imb_thread_cache_get_tile(ImThreadTileCache *cache, ImBuf *ibuf, int tx, int ty) { ImThreadTile *ttile, lookuptile; ImGlobalTile *gtile, *replacetile; int toffs = ibuf->xtiles * ty + tx; /* test if it is already in our thread local cache */ if ((ttile = cache->tiles.first)) { /* check last used tile before going to hash */ if (ttile->ibuf == ibuf && ttile->tx == tx && ttile->ty == ty) return ibuf->tiles[toffs]; /* find tile in hash */ lookuptile.ibuf = ibuf; lookuptile.tx = tx; lookuptile.ty = ty; if ((ttile = BLI_ghash_lookup(cache->tilehash, &lookuptile))) { BLI_remlink(&cache->tiles, ttile); BLI_addhead(&cache->tiles, ttile); return ibuf->tiles[toffs]; } } /* not found, have to do slow lookup in global cache */ if (BLI_listbase_is_empty(&cache->unused)) { ttile = cache->tiles.last; replacetile = ttile->global; BLI_remlink(&cache->tiles, ttile); BLI_ghash_remove(cache->tilehash, ttile, NULL, NULL); } else { ttile = cache->unused.first; replacetile = NULL; BLI_remlink(&cache->unused, ttile); } BLI_addhead(&cache->tiles, ttile); BLI_ghash_insert(cache->tilehash, ttile, ttile); gtile = imb_global_cache_get_tile(ibuf, tx, ty, replacetile); ttile->ibuf = gtile->ibuf; ttile->tx = gtile->tx; ttile->ty = gtile->ty; ttile->global = gtile; return ibuf->tiles[toffs]; }
/* Free strokes belonging to a gp-frame */ bool free_gpencil_strokes(bGPDframe *gpf) { bGPDstroke *gps, *gpsn; bool changed = (BLI_listbase_is_empty(&gpf->strokes) == false); /* free strokes */ for (gps = gpf->strokes.first; gps; gps = gpsn) { gpsn = gps->next; /* free stroke memory arrays, then stroke itself */ if (gps->points) MEM_freeN(gps->points); BLI_freelinkN(&gpf->strokes, gps); } return changed; }
void removeSnapPoint(TransInfo *t) { if (t->tsnap.status & MULTI_POINTS) { updateSelectedSnapPoint(t); if (t->tsnap.selectedPoint) { BLI_freelinkN(&t->tsnap.points, t->tsnap.selectedPoint); if (BLI_listbase_is_empty(&t->tsnap.points)) { t->tsnap.status &= ~MULTI_POINTS; } t->tsnap.selectedPoint = NULL; } } }
/* before even getting in the bake function we check for some basic errors */ static bool bake_objects_check(Main *bmain, Object *ob, ListBase *selected_objects, ReportList *reports, const bool is_selected_to_active) { CollectionPointerLink *link; /* error handling and tag (in case multiple materials share the same image) */ BKE_main_id_tag_idcode(bmain, ID_IM, false); if (is_selected_to_active) { int tot_objects = 0; if (!bake_object_check(ob, reports)) return false; for (link = selected_objects->first; link; link = link->next) { Object *ob_iter = (Object *)link->ptr.data; if (ob_iter == ob) continue; if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL) == false) { BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh or can't be converted to a mesh (Curve, Text, Surface or Metaball)", ob_iter->id.name + 2); return false; } tot_objects += 1; } if (tot_objects == 0) { BKE_report(reports, RPT_ERROR, "No valid selected objects"); return false; } } else { if (BLI_listbase_is_empty(selected_objects)) { BKE_report(reports, RPT_ERROR, "No valid selected objects"); return false; } for (link = selected_objects->first; link; link = link->next) { if (!bake_object_check(link->ptr.data, reports)) return false; } } return true; }
/* Given a KeyingSet and context info, validate Keying Set's paths. * This is only really necessary with relative/built-in KeyingSets * where their list of paths is dynamically generated based on the * current context info. * * Returns 0 if succeeded, otherwise an error code: eModifyKey_Returns */ short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks) { /* sanity check */ if (ks == NULL) return 0; /* if relative Keying Sets, poll and build up the paths */ if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) { KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo); /* clear all existing paths * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself */ BKE_keyingset_free(ks); /* get the associated 'type info' for this KeyingSet */ if (ksi == NULL) return MODIFYKEY_MISSING_TYPEINFO; /* TODO: check for missing callbacks! */ /* check if it can be used in the current context */ if (ksi->poll(ksi, C)) { /* if a list of data sources are provided, run a special iterator over them, * otherwise, just continue per normal */ if (dsources) RKS_ITER_overrides_list(ksi, C, ks, dsources); else ksi->iter(ksi, C, ks); /* if we don't have any paths now, then this still qualifies as invalid context */ // FIXME: we need some error conditions (to be retrieved from the iterator why this failed!) if (BLI_listbase_is_empty(&ks->paths)) return MODIFYKEY_INVALID_CONTEXT; } else { /* poll callback tells us that KeyingSet is useless in current context */ // FIXME: the poll callback needs to give us more info why return MODIFYKEY_INVALID_CONTEXT; } } /* succeeded; return 0 to tag error free */ return 0; }
static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle) { wmWindow *win = CTX_wm_window(C); bScreen *sc = CTX_wm_screen(C); ui_region_temp_remove(C, sc, handle->region); /* reset to region cursor (only if there's not another menu open) */ if (BLI_listbase_is_empty(&sc->regionbase)) { ED_region_cursor_set(win, CTX_wm_area(C), CTX_wm_region(C)); /* in case cursor needs to be changed again */ WM_event_add_mousemove(C); } if (handle->scrolltimer) { WM_event_remove_timer(CTX_wm_manager(C), win, handle->scrolltimer); } }
/* delete the last stroke of the given frame */ void gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf) { bGPDstroke *gps = (gpf) ? gpf->strokes.last : NULL; int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */ /* error checking */ if (ELEM(NULL, gpf, gps)) return; /* free the stroke and its data */ MEM_freeN(gps->points); BLI_freelinkN(&gpf->strokes, gps); /* if frame has no strokes after this, delete it */ if (BLI_listbase_is_empty(&gpf->strokes)) { gpencil_layer_delframe(gpl, gpf); gpencil_layer_getframe(gpl, cfra, 0); } }
void BLI_end_threads(ListBase *threadbase) { ThreadSlot *tslot; /* only needed if there's actually some stuff to end * this way we don't end up decrementing thread_levels on an empty threadbase * */ if (threadbase && (BLI_listbase_is_empty(threadbase) == false)) { for (tslot = threadbase->first; tslot; tslot = tslot->next) { if (tslot->avail == 0) { pthread_join(tslot->pthread, NULL); } } BLI_freelistN(threadbase); } thread_levels--; if (thread_levels == 0) MEM_set_lock_callback(NULL, NULL); }
static void vpaint_proj_dm_map_cosnos_update(struct Depsgraph *depsgraph, struct VertProjHandle *vp_handle, ARegion *ar, const float mval_fl[2]) { struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl}; Object *ob = vp_handle->ob; Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); Mesh *me = ob->data; CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH_ORIGINDEX; Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); /* quick sanity check - we shouldn't have to run this if there are no modifiers */ BLI_assert(BLI_listbase_is_empty(&ob->modifiers) == false); copy_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX); BKE_mesh_foreach_mapped_vert( me_eval, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, MESH_FOREACH_USE_NORMAL); }
static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) { const Editing *ed = BKE_sequencer_editing_get(scene, false); const int frame_sta = PSFRA; const int frame_end = PEFRA + 1; glEnable(GL_BLEND); /* draw darkened area outside of active timeline * frame range used is preview range or scene range */ UI_ThemeColorShadeAlpha(TH_BACK, -25, -100); if (frame_sta < frame_end) { glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)frame_sta, v2d->cur.ymax); glRectf((float)frame_end, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); } else { glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); } UI_ThemeColorShade(TH_BACK, -60); /* thin lines where the actual frames are */ fdrawline(frame_sta, v2d->cur.ymin, frame_sta, v2d->cur.ymax); fdrawline(frame_end, v2d->cur.ymin, frame_end, v2d->cur.ymax); if (ed && !BLI_listbase_is_empty(&ed->metastack)) { MetaStack *ms = ed->metastack.last; glColor4ub(255, 255, 255, 8); glRectf(ms->disp_range[0], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax); UI_ThemeColorShade(TH_BACK, -40); fdrawline(ms->disp_range[0], v2d->cur.ymin, ms->disp_range[0], v2d->cur.ymax); fdrawline(ms->disp_range[1], v2d->cur.ymin, ms->disp_range[1], v2d->cur.ymax); } glDisable(GL_BLEND); }
void wm_clear_default_size(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; /* wm context */ if (wm == NULL) { wm = CTX_data_main(C)->wm.first; CTX_wm_manager_set(C, wm); } if (wm == NULL || BLI_listbase_is_empty(&wm->windows)) { return; } for (win = wm->windows.first; win; win = win->next) { win->sizex = 0; win->sizey = 0; win->posx = 0; win->posy = 0; } }
void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src) { EditBone *ebone_src; EditBone *ebone_dst; BLI_assert(BLI_listbase_is_empty(lb_dst)); for (ebone_src = lb_src->first; ebone_src; ebone_src = ebone_src->next) { ebone_dst = MEM_dupallocN(ebone_src); if (ebone_dst->prop) { ebone_dst->prop = IDP_CopyProperty(ebone_dst->prop); } ebone_src->temp.ebone = ebone_dst; BLI_addtail(lb_dst, ebone_dst); } /* set pointers */ for (ebone_dst = lb_dst->first; ebone_dst; ebone_dst = ebone_dst->next) { if (ebone_dst->parent) { ebone_dst->parent = ebone_dst->parent->temp.ebone; } } }
/* helper for find_nearest_fcurve_vert() - get the best match to use */ static tNearestVertInfo *get_best_nearest_fcurve_vert(ListBase *matches) { tNearestVertInfo *nvi = NULL; short found = 0; /* abort if list is empty */ if (BLI_listbase_is_empty(matches)) return NULL; /* if list only has 1 item, remove it from the list and return */ if (BLI_listbase_is_single(matches)) { /* need to remove from the list, otherwise it gets freed and then we can't return it */ return BLI_pophead(matches); } /* try to find the first selected F-Curve vert, then take the one after it */ for (nvi = matches->first; nvi; nvi = nvi->next) { /* which mode of search are we in: find first selected, or find vert? */ if (found) { /* just take this vert now that we've found the selected one * - we'll need to remove this from the list so that it can be returned to the original caller */ BLI_remlink(matches, nvi); return nvi; } else { /* if vert is selected, we've got what we want... */ if (nvi->sel) found = 1; } } /* if we're still here, this means that we failed to find anything appropriate in the first pass, * so just take the first item now... */ return BLI_pophead(matches); }
/* Select or deselect all MetaElements */ static int mball_select_all_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); MetaBall *mb = (MetaBall *)obedit->data; MetaElem *ml; int action = RNA_enum_get(op->ptr, "action"); if (BLI_listbase_is_empty(mb->editelems)) return OPERATOR_CANCELLED; if (action == SEL_TOGGLE) { action = SEL_SELECT; for (ml = mb->editelems->first; ml; ml = ml->next) { if (ml->flag & SELECT) { action = SEL_DESELECT; break; } } } switch (action) { case SEL_SELECT: BKE_mball_select_all(mb); break; case SEL_DESELECT: BKE_mball_deselect_all(mb); break; case SEL_INVERT: BKE_mball_select_swap(mb); break; } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); return OPERATOR_FINISHED; }
/** * called on startup, (context entirely filled with NULLs) * or called for 'New File' * both startup.blend and userpref.blend are checked * the optional parameter custom_file points to an alternative startup page * custom_file can be NULL */ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const char *custom_file) { ListBase wmbase; char startstr[FILE_MAX]; char prefstr[FILE_MAX]; int success = 0; /* Indicates whether user preferences were really load from memory. * * This is used for versioning code, and for this we can not rely on from_memory * passed via argument. This is because there might be configuration folder * exists but it might not have userpref.blend and in this case we fallback to * reading home file from memory. * * And in this case versioning code is to be run. */ bool read_userdef_from_memory = true; /* options exclude eachother */ BLI_assert((from_memory && custom_file) == 0); if ((G.f & G_SCRIPT_OVERRIDE_PREF) == 0) { BKE_BIT_TEST_SET(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_SCRIPT_AUTOEXEC); } BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); UI_view2d_zoom_cache_reset(); G.relbase_valid = 0; if (!from_memory) { const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); if (custom_file) { BLI_strncpy(startstr, custom_file, FILE_MAX); if (cfgdir) { BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { prefstr[0] = '\0'; } } else if (cfgdir) { BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { startstr[0] = '\0'; prefstr[0] = '\0'; from_memory = 1; } } /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); if (!from_memory) { if (BLI_access(startstr, R_OK) == 0) { success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); } if (BLI_listbase_is_empty(&U.themes)) { if (G.debug & G_DEBUG) printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr); success = 0; } } if (success == 0 && custom_file && reports) { BKE_reportf(reports, RPT_ERROR, "Could not read '%s'", custom_file); /*We can not return from here because wm is already reset*/ } if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL, true); if (BLI_listbase_is_empty(&wmbase)) { wm_clear_default_size(C); } BKE_tempdir_init(U.tempdir); #ifdef WITH_PYTHON_SECURITY /* use alternative setting for security nuts * otherwise we'd need to patch the binary blob - startup.blend.c */ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; #endif } /* check new prefs only after startup.blend was finished */ if (!from_memory && BLI_exists(prefstr)) { int done = BKE_read_file_userdef(prefstr, NULL); if (done != BKE_READ_FILE_FAIL) { read_userdef_from_memory = false; printf("Read new prefs: %s\n", prefstr); } } /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; /* check userdef before open window, keymaps etc */ wm_init_userdef(C, read_userdef_from_memory); /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ G.main->name[0] = '\0'; /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ if (!G.background) GPU_default_lights(); /* XXX */ G.save_over = 0; // start with save preference untitled.blend G.fileflags &= ~G_FILE_AUTOPLAY; /* disable autoplay in startup.blend... */ wm_file_read_post(C, true); return true; }