static int mask_layer_move_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *mask_layer = BLI_findlink(&mask->masklayers, mask->masklay_act); MaskLayer *mask_layer_other; int direction = RNA_enum_get(op->ptr, "direction"); if (!mask_layer) return OPERATOR_CANCELLED; if (direction == -1) { mask_layer_other = mask_layer->prev; if (!mask_layer_other) return OPERATOR_CANCELLED; BLI_remlink(&mask->masklayers, mask_layer); BLI_insertlinkbefore(&mask->masklayers, mask_layer_other, mask_layer); mask->masklay_act--; } else if (direction == 1) { mask_layer_other = mask_layer->next; if (!mask_layer_other) return OPERATOR_CANCELLED; BLI_remlink(&mask->masklayers, mask_layer); BLI_insertlinkafter(&mask->masklayers, mask_layer_other, mask_layer); mask->masklay_act++; } return OPERATOR_FINISHED; }
static int strip_modifier_move_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Sequence *seq = BKE_sequencer_active_get(scene); char name[MAX_NAME]; int direction; SequenceModifierData *smd; RNA_string_get(op->ptr, "name", name); direction = RNA_enum_get(op->ptr, "direction"); smd = BKE_sequence_modifier_find_by_name(seq, name); if (!smd) return OPERATOR_CANCELLED; if (direction == SEQ_MODIFIER_MOVE_UP) { if (smd->prev) { BLI_remlink(&seq->modifiers, smd); BLI_insertlinkbefore(&seq->modifiers, smd->prev, smd); } } else if (direction == SEQ_MODIFIER_MOVE_DOWN) { if (smd->next) { BLI_remlink(&seq->modifiers, smd); BLI_insertlinkafter(&seq->modifiers, smd->next, smd); } } BKE_sequence_invalidate_cache(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; }
/* Adds a marker to list of cfra elems */ static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel) { CfraElem *ce, *cen; /* should this one only be considered if it is selected? */ if ((only_sel) && ((marker->flag & SELECT) == 0)) return; /* insertion sort - try to find a previous cfra elem */ for (ce = lb->first; ce; ce = ce->next) { if (ce->cfra == marker->frame) { /* do because of double keys */ if (marker->flag & SELECT) ce->sel = marker->flag; return; } else if (ce->cfra > marker->frame) { break; } } cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem"); if (ce) BLI_insertlinkbefore(lb, ce, cen); else BLI_addtail(lb, cen); cen->cfra = marker->frame; cen->sel = marker->flag; }
static void move_modifier(ListBase *lb, LineStyleModifier *modifier, int direction) { BLI_remlink(lb, modifier); if (direction > 0) BLI_insertlinkbefore(lb, modifier->prev, modifier); else BLI_insertlinkafter(lb, modifier->next, modifier); }
void multiresModifier_join(Object *ob) { Base *base = NULL; int highest_lvl = 0; /* First find the highest level of subdivision */ base = FIRSTBASE; while(base) { if(TESTBASELIB_BGMODE(v3d, base) && base->object->type==OB_MESH) { ModifierData *md; for(md = base->object->modifiers.first; md; md = md->next) { if(md->type == eModifierType_Multires) { int totlvl = ((MultiresModifierData*)md)->totlvl; if(totlvl > highest_lvl) highest_lvl = totlvl; /* Ensure that all updates are processed */ multires_force_update(base->object); } } } base = base->next; } /* No multires meshes selected */ if(highest_lvl == 0) return; /* Subdivide all the displacements to the highest level */ base = FIRSTBASE; while(base) { if(TESTBASELIB_BGMODE(v3d, base) && base->object->type==OB_MESH) { ModifierData *md = NULL; MultiresModifierData *mmd = NULL; for(md = base->object->modifiers.first; md; md = md->next) { if(md->type == eModifierType_Multires) mmd = (MultiresModifierData*)md; } /* If the object didn't have multires enabled, give it a new modifier */ if(!mmd) { md = base->object->modifiers.first; while(md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform) md = md->next; mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires); BLI_insertlinkbefore(&base->object->modifiers, md, mmd); modifier_unique_name(&base->object->modifiers, mmd); } if(mmd) multiresModifier_subdivide(mmd, base->object, highest_lvl - mmd->totlvl, 0, 0); } base = base->next; } }
/* move layer up */ static void gp_ui_layer_up_cb(bContext *C, void *gpd_v, void *gpl_v) { bGPdata *gpd = gpd_v; bGPDlayer *gpl = gpl_v; BLI_remlink(&gpd->layers, gpl); BLI_insertlinkbefore(&gpd->layers, gpl->prev, gpl); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); }
int ED_object_gpencil_modifier_move_up(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md) { if (md->prev) { BLI_remlink(&ob->greasepencil_modifiers, md); BLI_insertlinkbefore(&ob->greasepencil_modifiers, md->prev, md); } return 1; }
static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) { /* find first edge to the right of eed, and insert eed before that */ ScanFillEdge *ed; float fac, fac1, x, y; if (sc->edge_first == NULL) { sc->edge_first = sc->edge_last = eed; eed->prev = eed->next = NULL; return 1; } x = eed->v1->xy[0]; y = eed->v1->xy[1]; fac1 = eed->v2->xy[1] - y; if (fac1 == 0.0f) { fac1 = 1.0e10f * (eed->v2->xy[0] - x); } else { fac1 = (x - eed->v2->xy[0]) / fac1; } for (ed = sc->edge_first; ed; ed = ed->next) { if (ed->v2 == eed->v2) { return false; } fac = ed->v2->xy[1] - y; if (fac == 0.0f) { fac = 1.0e10f * (ed->v2->xy[0] - x); } else { fac = (x - ed->v2->xy[0]) / fac; } if (fac > fac1) { break; } } if (ed) { BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed, eed); } else { BLI_addtail((ListBase *)&(sc->edge_first), eed); } return true; }
/* add a new gp-frame to the given layer */ bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe) { bGPDframe *gpf = NULL, *gf = NULL; short state = 0; /* error checking (neg frame only if they are not allowed in Blender!) */ if (gpl == NULL) return NULL; /* allocate memory for this frame */ gpf = MEM_callocN(sizeof(bGPDframe), "bGPDframe"); gpf->framenum = cframe; /* find appropriate place to add frame */ if (gpl->frames.first) { for (gf = gpl->frames.first; gf; gf = gf->next) { /* check if frame matches one that is supposed to be added */ if (gf->framenum == cframe) { state = -1; break; } /* if current frame has already exceeded the frame to add, add before */ if (gf->framenum > cframe) { BLI_insertlinkbefore(&gpl->frames, gf, gpf); state = 1; break; } } } /* check whether frame was added successfully */ if (state == -1) { printf("Error: Frame (%d) existed already for this layer. Using existing frame\n", cframe); /* free the newly created one, and use the old one instead */ MEM_freeN(gpf); /* return existing frame instead... */ BLI_assert(gf != NULL); gpf = gf; } else if (state == 0) { /* add to end then! */ BLI_addtail(&gpl->frames, gpf); } /* return frame */ return gpf; }
static void verify_socket_template_list(bNodeTree *ntree, bNode *node, int in_out, ListBase *socklist, bNodeSocketTemplate *stemp_first) { bNodeSocket *sock; bNodeSocketTemplate *stemp; /* no inputs anymore? */ if(stemp_first==NULL) { while(socklist->first) { sock = (bNodeSocket*)socklist->first; if (!(sock->flag & SOCK_DYNAMIC)) nodeRemoveSocket(ntree, node, socklist->first); } } else { /* step by step compare */ stemp= stemp_first; while(stemp->type != -1) { stemp->sock= verify_socket_template(ntree, node, in_out, socklist, stemp); stemp++; } /* leftovers are removed */ while(socklist->first) { sock = (bNodeSocket*)socklist->first; if (!(sock->flag & SOCK_DYNAMIC)) nodeRemoveSocket(ntree, node, socklist->first); } /* and we put back the verified sockets */ stemp= stemp_first; if (socklist->first) { /* some dynamic sockets left, store the list start * so we can add static sockets infront of it. */ sock = socklist->first; while(stemp->type != -1) { /* put static sockets infront of dynamic */ BLI_insertlinkbefore(socklist, sock, stemp->sock); stemp++; } } else { while(stemp->type != -1) { BLI_addtail(socklist, stemp->sock); stemp++; } } } }
static void add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode) { ModifierData *md=NULL; HookModifierData *hmd = NULL; float cent[3]; int tot, ok, *indexar; char name[32]; ok = object_hook_index_array(obedit, &tot, &indexar, name, cent); if (!ok) return; // XXX error("Requires selected vertices or active Vertex Group"); if (mode==OBJECT_ADDHOOK_NEWOB && !ob) { ob = add_hook_object_new(scene, obedit); /* transform cent to global coords for loc */ mul_v3_m4v3(ob->loc, obedit->obmat, cent); } md = obedit->modifiers.first; while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) { md = md->next; } hmd = (HookModifierData*) modifier_new(eModifierType_Hook); BLI_insertlinkbefore(&obedit->modifiers, md, hmd); BLI_snprintf(hmd->modifier.name, sizeof(hmd->modifier.name), "Hook-%s", ob->id.name+2); modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd); hmd->object= ob; hmd->indexar= indexar; copy_v3_v3(hmd->cent, cent); hmd->totindex= tot; BLI_strncpy(hmd->name, name, sizeof(hmd->name)); /* matrix calculus */ /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ /* (parentinv ) */ where_is_object(scene, ob); invert_m4_m4(ob->imat, ob->obmat); /* apparently this call goes from right to left... */ mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL, NULL, NULL, NULL, NULL, NULL); DAG_scene_sort(bmain, scene); }
static int shape_key_move_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; int type= RNA_enum_get(op->ptr, "type"); Key *key= ob_get_key(ob); if(key) { KeyBlock *kb, *kb_other; int shapenr_act= ob->shapenr-1; int shapenr_swap= shapenr_act + type; kb= BLI_findlink(&key->block, shapenr_act); if((type==-1 && kb->prev==NULL) || (type==1 && kb->next==NULL)) { return OPERATOR_CANCELLED; } for(kb_other= key->block.first; kb_other; kb_other= kb_other->next) { if(kb_other->relative == shapenr_act) { kb_other->relative += type; } else if(kb_other->relative == shapenr_swap) { kb_other->relative -= type; } } if(type==-1) { /* move back */ kb_other= kb->prev; BLI_remlink(&key->block, kb); BLI_insertlinkbefore(&key->block, kb_other, kb); ob->shapenr--; } else { /* move next */ kb_other= kb->next; BLI_remlink(&key->block, kb); BLI_insertlinkafter(&key->block, kb_other, kb); ob->shapenr++; } } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; }
static void voronoi_insertEvent(VoronoiProcess *process, VoronoiEvent *event) { VoronoiEvent *current_event = process->queue.first; while (current_event) { if (current_event->site[1] < event->site[1]) { break; } if (current_event->site[1] == event->site[1]) { event->site[1] -= VORONOI_EPS; } current_event = current_event->next; } BLI_insertlinkbefore(&process->queue, current_event, event); }
/* add a new gp-frame to the given layer */ bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe) { bGPDframe *gpf, *gf; short state = 0; /* error checking */ if ((gpl == NULL) || (cframe <= 0)) return NULL; /* allocate memory for this frame */ gpf = MEM_callocN(sizeof(bGPDframe), "bGPDframe"); gpf->framenum = cframe; /* find appropriate place to add frame */ if (gpl->frames.first) { for (gf = gpl->frames.first; gf; gf = gf->next) { /* check if frame matches one that is supposed to be added */ if (gf->framenum == cframe) { state = -1; break; } /* if current frame has already exceeded the frame to add, add before */ if (gf->framenum > cframe) { BLI_insertlinkbefore(&gpl->frames, gf, gpf); state = 1; break; } } } /* check whether frame was added successfully */ if (state == -1) { MEM_freeN(gpf); printf("Error: frame (%d) existed already for this layer\n", cframe); } else if (state == 0) { /* add to end then! */ BLI_addtail(&gpl->frames, gpf); } /* return frame */ return gpf; }
void sca_move_controller(bController *cont_to_move, Object *ob, int move_up) { bController *cont, *tmp; int val; val = move_up ? 1 : 2; /* make sure this controller belongs to this object */ cont= ob->controllers.first; while (cont) { if (cont == cont_to_move) break; cont= cont->next; } if (!cont) return; /* move up */ if (val == 1 && cont->prev) { /* locate the controller that has the same state mask but is earlier in the list */ tmp = cont->prev; while (tmp) { if (tmp->state_mask & cont->state_mask) break; tmp = tmp->prev; } if (tmp) { BLI_remlink(&ob->controllers, cont); BLI_insertlinkbefore(&ob->controllers, tmp, cont); } } /* move down */ else if (val == 2 && cont->next) { tmp = cont->next; while (tmp) { if (tmp->state_mask & cont->state_mask) break; tmp = tmp->next; } BLI_remlink(&ob->controllers, cont); BLI_insertlinkafter(&ob->controllers, tmp, cont); } }
static short addedgetoscanvert(ScFillVert *sc, EditEdge *eed) { /* find first edge to the right of eed, and insert eed before that */ EditEdge *ed; float fac,fac1,x,y; if(sc->first==0) { sc->first= sc->last= eed; eed->prev= eed->next=0; return 1; } x= eed->v1->co[cox]; y= eed->v1->co[coy]; fac1= eed->v2->co[coy]-y; if(fac1==0.0) { fac1= 1.0e10*(eed->v2->co[cox]-x); } else fac1= (x-eed->v2->co[cox])/fac1; ed= sc->first; while(ed) { if(ed->v2==eed->v2) return 0; fac= ed->v2->co[coy]-y; if(fac==0.0) { fac= 1.0e10*(ed->v2->co[cox]-x); } else fac= (x-ed->v2->co[cox])/fac; if(fac>fac1) break; ed= ed->next; } if(ed) BLI_insertlinkbefore((ListBase *)&(sc->first), ed, eed); else BLI_addtail((ListBase *)&(sc->first),eed); return 1; }
static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km) { wmKeyMapDiffItem *kmdi; wmKeyMapItem *kmi_remove, *kmi_add; for(kmdi=diff_km->diff_items.first; kmdi; kmdi=kmdi->next) { /* find item to remove */ kmi_remove = NULL; if(kmdi->remove_item) { kmi_remove = wm_keymap_find_item_equals(km, kmdi->remove_item); if(!kmi_remove) kmi_remove = wm_keymap_find_item_equals_result(km, kmdi->remove_item); } /* add item */ if(kmdi->add_item) { /* only if nothing to remove or item to remove found */ if(!kmdi->remove_item || kmi_remove) { kmi_add = wm_keymap_item_copy(kmdi->add_item); kmi_add->flag |= KMI_USER_MODIFIED; if(kmi_remove) { kmi_add->flag &= ~KMI_EXPANDED; kmi_add->flag |= (kmi_remove->flag & KMI_EXPANDED); kmi_add->id = kmi_remove->id; BLI_insertlinkbefore(&km->items, kmi_remove, kmi_add); } else { keymap_item_set_id(km, kmi_add); BLI_addtail(&km->items, kmi_add); } } } /* remove item */ if(kmi_remove) { wm_keymap_item_free(kmi_remove); BLI_freelinkN(&km->items, kmi_remove); } } }
static int constraint_move_up_exec (bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint); Object *ob= ptr.id.data; bConstraint *con= ptr.data; if (con->prev) { ListBase *conlist= get_active_constraints(ob); bConstraint *prevCon= con->prev; /* insert the nominated constraint before the one that used to be before it */ BLI_remlink(conlist, con); BLI_insertlinkbefore(conlist, prevCon, con); WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }
void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up) { bActuator *act, *tmp; int val; val = move_up ? 1 : 2; /* make sure this actuator belongs to this object */ act= ob->actuators.first; while (act) { if (act == act_to_move) break; act= act->next; } if (!act) return; /* move up */ if (val == 1 && act->prev) { /* locate the first visible actuators before this one */ for (tmp = act->prev; tmp; tmp=tmp->prev) { if (tmp->flag & ACT_VISIBLE) break; } if (tmp) { BLI_remlink(&ob->actuators, act); BLI_insertlinkbefore(&ob->actuators, tmp, act); } } /* move down */ else if (val == 2 && act->next) { /* locate the first visible actuators after this one */ for (tmp=act->next; tmp; tmp=tmp->next) { if (tmp->flag & ACT_VISIBLE) break; } if (tmp) { BLI_remlink(&ob->actuators, act); BLI_insertlinkafter(&ob->actuators, tmp, act); } } }
/************************ move up/down boid state operators *********************/ static int state_move_up_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); ParticleSettings *part = ptr.data; BoidSettings *boids; BoidState *state; if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; boids = part->boids; for (state = boids->states.first; state; state=state->next) { if (state->flag & BOIDSTATE_CURRENT && state->prev) { BLI_remlink(&boids->states, state); BLI_insertlinkbefore(&boids->states, state->prev, state); break; } } return OPERATOR_FINISHED; }
/* ******************** INTERFACE ******************* */ void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up) { bSensor *sens, *tmp; int val; val = move_up ? 1 : 2; /* make sure this sensor belongs to this object */ sens= ob->sensors.first; while (sens) { if (sens == sens_to_move) break; sens= sens->next; } if (!sens) return; /* move up */ if (val == 1 && sens->prev) { for (tmp=sens->prev; tmp; tmp=tmp->prev) { if (tmp->flag & SENS_VISIBLE) break; } if (tmp) { BLI_remlink(&ob->sensors, sens); BLI_insertlinkbefore(&ob->sensors, tmp, sens); } } /* move down */ else if (val == 2 && sens->next) { for (tmp=sens->next; tmp; tmp=tmp->next) { if (tmp->flag & SENS_VISIBLE) break; } if (tmp) { BLI_remlink(&ob->sensors, sens); BLI_insertlinkafter(&ob->sensors, tmp, sens); } } }
static void sort_alpha_id(ListBase *lb, ID *id) { ID *idtest; /* insert alphabetically */ if(lb->first!=lb->last) { BLI_remlink(lb, id); idtest= lb->first; while(idtest) { if(BLI_strcasecmp(idtest->name, id->name)>0 || idtest->lib) { BLI_insertlinkbefore(lb, idtest, id); break; } idtest= idtest->next; } /* as last */ if(idtest==NULL) { BLI_addtail(lb, id); } } }
static int dupliob_move_up_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; ParticleSettings *part; ParticleDupliWeight *dw; if (!psys) return OPERATOR_CANCELLED; part = psys->part; for (dw=part->dupliweights.first; dw; dw=dw->next) { if (dw->flag & PART_DUPLIW_CURRENT && dw->prev) { BLI_remlink(&part->dupliweights, dw); BLI_insertlinkbefore(&part->dupliweights, dw->prev, dw); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL); break; } } return OPERATOR_FINISHED; }
/************************ move up/down boid rule operators *********************/ static int rule_move_up_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); ParticleSettings *part = ptr.data; BoidRule *rule; BoidState *state; if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; state = boid_get_current_state(part->boids); for (rule = state->rules.first; rule; rule=rule->next) { if (rule->flag & BOIDRULE_CURRENT && rule->prev) { BLI_remlink(&state->rules, rule); BLI_insertlinkbefore(&state->rules, rule->prev, rule); DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); break; } } return OPERATOR_FINISHED; }
static int target_move_up_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= ptr.data; Object *ob = ptr.id.data; ParticleTarget *pt; if (!psys) return OPERATOR_CANCELLED; pt = psys->targets.first; for (; pt; pt=pt->next) { if (pt->flag & PTARGET_CURRENT && pt->prev) { BLI_remlink(&psys->targets, pt); BLI_insertlinkbefore(&psys->targets, pt->prev, pt); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); break; } } return OPERATOR_FINISHED; }
ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type) { ModifierData *md=NULL, *new_md=NULL; ModifierTypeInfo *mti = modifierType_getInfo(type); /* only geometry objects should be able to get modifiers [#25291] */ if(!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to Object '%s'", ob->id.name+2); return NULL; } if(mti->flags&eModifierTypeFlag_Single) { if(modifiers_findByType(ob, type)) { BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed"); return NULL; } } if(type == eModifierType_ParticleSystem) { /* don't need to worry about the new modifier's name, since that is set to the number * of particle systems which shouldn't have too many duplicates */ new_md = object_add_particle_system(scene, ob, name); } else { /* get new modifier data to add */ new_md= modifier_new(type); if(mti->flags&eModifierTypeFlag_RequiresOriginalData) { md = ob->modifiers.first; while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) md = md->next; BLI_insertlinkbefore(&ob->modifiers, md, new_md); } else BLI_addtail(&ob->modifiers, new_md); if(name) BLI_strncpy(new_md->name, name, sizeof(new_md->name)); /* make sure modifier data has unique name */ modifier_unique_name(&ob->modifiers, new_md); /* special cases */ if(type == eModifierType_Softbody) { if(!ob->soft) { ob->soft= sbNew(scene); ob->softflag |= OB_SB_GOAL|OB_SB_EDGES; } } else if(type == eModifierType_Collision) { if(!ob->pd) ob->pd= object_add_collision_fields(0); ob->pd->deflect= 1; DAG_scene_sort(bmain, scene); } else if(type == eModifierType_Surface) DAG_scene_sort(bmain, scene); else if(type == eModifierType_Multires) /* set totlvl from existing MDISPS layer if object already had it */ multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob); } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); return new_md; }
static void loop_sync(bNodeTree *ntree, int sync_in_out) { bNodeSocket *sock, *sync, *nsync, *mirror; ListBase *sync_lb; if (sync_in_out==SOCK_IN) { sock = ntree->outputs.first; sync = ntree->inputs.first; sync_lb = &ntree->inputs; } else { sock = ntree->inputs.first; sync = ntree->outputs.first; sync_lb = &ntree->outputs; } /* NB: the sock->storage pointer is used here directly to store the own_index int * out the mirrored socket counterpart! */ while (sock) { /* skip static and internal sockets on the sync side (preserves socket order!) */ while (sync && ((sync->flag & SOCK_INTERNAL) || !(sync->flag & SOCK_DYNAMIC))) sync = sync->next; if (sync && !(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) { if (sock->storage==NULL) { /* if mirror index is 0, the sockets is newly added and a new mirror must be created. */ mirror = node_group_expose_socket(ntree, sock, sync_in_out); /* store the mirror index */ sock->storage = SET_INT_IN_POINTER(mirror->own_index); mirror->storage = SET_INT_IN_POINTER(sock->own_index); /* move mirror to the right place */ BLI_remlink(sync_lb, mirror); if (sync) BLI_insertlinkbefore(sync_lb, sync, mirror); else BLI_addtail(sync_lb, mirror); } else { /* look up the mirror socket */ for (mirror=sync; mirror; mirror=mirror->next) if (mirror->own_index == GET_INT_FROM_POINTER(sock->storage)) break; /* make sure the name is the same (only for identification by user, no deeper meaning) */ BLI_strncpy(mirror->name, sock->name, sizeof(mirror->name)); /* fix the socket order if necessary */ if (mirror != sync) { BLI_remlink(sync_lb, mirror); BLI_insertlinkbefore(sync_lb, sync, mirror); } else sync = sync->next; } } sock = sock->next; } /* remaining sockets in sync_lb are leftovers from deleted sockets, remove them */ while (sync) { nsync = sync->next; if (!(sync->flag & SOCK_INTERNAL) && (sync->flag & SOCK_DYNAMIC)) node_group_remove_socket(ntree, sync, sync_in_out); sync = nsync; } }
static void scanfill(PolyFill *pf, int mat_nr) { ScFillVert *sc = NULL, *sc1; EditVert *eve,*v1,*v2,*v3; EditEdge *eed,*nexted,*ed1,*ed2,*ed3; float miny = 0.0; int a,b,verts, maxface, totface; short nr, test, twoconnected=0; nr= pf->nr; /* PRINTS verts= pf->verts; eve= fillvertbase.first; while(eve) { printf("vert: %x co: %f %f\n",eve,eve->co[cox],eve->co[coy]); eve= eve->next; } eed= filledgebase.first; while(eed) { printf("edge: %x verts: %x %x\n",eed,eed->v1,eed->v2); eed= eed->next; } */ /* STEP 0: remove zero sized edges */ eed= filledgebase.first; while(eed) { if(eed->v1->co[cox]==eed->v2->co[cox]) { if(eed->v1->co[coy]==eed->v2->co[coy]) { if(eed->v1->f==255 && eed->v2->f!=255) { eed->v2->f= 255; eed->v2->tmp.v= eed->v1->tmp.v; } else if(eed->v2->f==255 && eed->v1->f!=255) { eed->v1->f= 255; eed->v1->tmp.v= eed->v2->tmp.v; } else if(eed->v2->f==255 && eed->v1->f==255) { eed->v1->tmp.v= eed->v2->tmp.v; } else { eed->v2->f= 255; eed->v2->tmp.v = eed->v1->tmp.v; } } } eed= eed->next; } /* STEP 1: make using FillVert and FillEdge lists a sorted ScFillVert list */ sc= scdata= (ScFillVert *)MEM_callocN(pf->verts*sizeof(ScFillVert),"Scanfill1"); eve= fillvertbase.first; verts= 0; while(eve) { if(eve->xs==nr) { if(eve->f!= 255) { verts++; eve->f= 0; /* flag for connectedges later on */ sc->v1= eve; sc++; } } eve= eve->next; } qsort(scdata, verts, sizeof(ScFillVert), vergscdata); eed= filledgebase.first; while(eed) { nexted= eed->next; eed->f= 0; BLI_remlink(&filledgebase,eed); /* commented all of this out, this I have no idea for what it is for, probably from ancient past */ /* it does crash blender, since it uses mixed original and new vertices (ton) */ // if(eed->v1->f==255) { // v1= eed->v1; // while((eed->v1->f == 255) && (eed->v1->tmp.v != v1)) // eed->v1 = eed->v1->tmp.v; // } // if(eed->v2->f==255) { // v2= eed->v2; // while((eed->v2->f == 255) && (eed->v2->tmp.v != v2)) // eed->v2 = eed->v2->tmp.v; // } if(eed->v1!=eed->v2) addedgetoscanlist(eed,verts); eed= nexted; } /* sc= scdata; for(a=0;a<verts;a++) { printf("\nscvert: %x\n",sc->v1); eed= sc->first; while(eed) { printf(" ed %x %x %x\n",eed,eed->v1,eed->v2); eed= eed->next; } sc++; }*/ /* STEP 2: FILL LOOP */ if(pf->f==0) twoconnected= 1; /* (temporal) security: never much more faces than vertices */ totface= 0; maxface= 2*verts; /* 2*verts: based at a filled circle within a triangle */ sc= scdata; for(a=0;a<verts;a++) { /* printf("VERTEX %d %x\n",a,sc->v1); */ ed1= sc->first; while(ed1) { /* set connectflags */ nexted= ed1->next; if(ed1->v1->h==1 || ed1->v2->h==1) { BLI_remlink((ListBase *)&(sc->first),ed1); BLI_addtail(&filledgebase,ed1); if(ed1->v1->h>1) ed1->v1->h--; if(ed1->v2->h>1) ed1->v2->h--; } else ed1->v2->f= 1; ed1= nexted; } while(sc->first) { /* for as long there are edges */ ed1= sc->first; ed2= ed1->next; /* commented out... the ESC here delivers corrupted memory (and doesnt work during grab) */ /* if(callLocalInterruptCallBack()) break; */ if(totface>maxface) { /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */ a= verts; break; } if(ed2==0) { sc->first=sc->last= 0; /* printf("just 1 edge to vert\n"); */ BLI_addtail(&filledgebase,ed1); ed1->v2->f= 0; ed1->v1->h--; ed1->v2->h--; } else { /* test rest of vertices */ v1= ed1->v2; v2= ed1->v1; v3= ed2->v2; /* this happens with a serial of overlapping edges */ if(v1==v2 || v2==v3) break; /* printf("test verts %x %x %x\n",v1,v2,v3); */ miny = ( (v1->co[coy])<(v3->co[coy]) ? (v1->co[coy]) : (v3->co[coy]) ); /* miny= MIN2(v1->co[coy],v3->co[coy]); */ sc1= sc+1; test= 0; for(b=a+1;b<verts;b++) { if(sc1->v1->f==0) { if(sc1->v1->co[coy] <= miny) break; if(testedgeside(v1->co,v2->co,sc1->v1->co)) if(testedgeside(v2->co,v3->co,sc1->v1->co)) if(testedgeside(v3->co,v1->co,sc1->v1->co)) { /* point in triangle */ test= 1; break; } } sc1++; } if(test) { /* make new edge, and start over */ /* printf("add new edge %x %x and start again\n",v2,sc1->v1); */ ed3= BLI_addfilledge(v2, sc1->v1); BLI_remlink(&filledgebase, ed3); BLI_insertlinkbefore((ListBase *)&(sc->first), ed2, ed3); ed3->v2->f= 1; ed3->f= 2; ed3->v1->h++; ed3->v2->h++; } else { /* new triangle */ /* printf("add face %x %x %x\n",v1,v2,v3); */ addfillface(v1, v2, v3, mat_nr); totface++; BLI_remlink((ListBase *)&(sc->first),ed1); BLI_addtail(&filledgebase,ed1); ed1->v2->f= 0; ed1->v1->h--; ed1->v2->h--; /* ed2 can be removed when it's an old one */ if(ed2->f==0 && twoconnected) { BLI_remlink((ListBase *)&(sc->first),ed2); BLI_addtail(&filledgebase,ed2); ed2->v2->f= 0; ed2->v1->h--; ed2->v2->h--; } /* new edge */ ed3= BLI_addfilledge(v1, v3); BLI_remlink(&filledgebase, ed3); ed3->f= 2; ed3->v1->h++; ed3->v2->h++; /* printf("add new edge %x %x\n",v1,v3); */ sc1= addedgetoscanlist(ed3, verts); if(sc1) { /* ed3 already exists: remove */ /* printf("Edge exists\n"); */ ed3->v1->h--; ed3->v2->h--; if(twoconnected) ed3= sc1->first; else ed3= 0; while(ed3) { if( (ed3->v1==v1 && ed3->v2==v3) || (ed3->v1==v3 && ed3->v2==v1) ) { BLI_remlink((ListBase *)&(sc1->first),ed3); BLI_addtail(&filledgebase,ed3); ed3->v1->h--; ed3->v2->h--; break; } ed3= ed3->next; } } } } /* test for loose edges */ ed1= sc->first; while(ed1) { nexted= ed1->next; if(ed1->v1->h<2 || ed1->v2->h<2) { BLI_remlink((ListBase *)&(sc->first),ed1); BLI_addtail(&filledgebase,ed1); if(ed1->v1->h>1) ed1->v1->h--; if(ed1->v2->h>1) ed1->v2->h--; } ed1= nexted; } } sc++; } MEM_freeN(scdata); }
/* Add given channel into (active) group * - assumes that channel is not linked to anything anymore * - always adds at the end of the group */ void action_groups_add_channel(bAction *act, bActionGroup *agrp, FCurve *fcurve) { /* sanity checks */ if (ELEM(NULL, act, agrp, fcurve)) return; /* if no channels anywhere, just add to two lists at the same time */ if (BLI_listbase_is_empty(&act->curves)) { fcurve->next = fcurve->prev = NULL; agrp->channels.first = agrp->channels.last = fcurve; act->curves.first = act->curves.last = fcurve; } /* if the group already has channels, the F-Curve can simply be added to the list * (i.e. as the last channel in the group) */ else if (agrp->channels.first) { /* if the group's last F-Curve is the action's last F-Curve too, * then set the F-Curve as the last for the action first so that * the lists will be in sync after linking */ if (agrp->channels.last == act->curves.last) act->curves.last = fcurve; /* link in the given F-Curve after the last F-Curve in the group, * which means that it should be able to fit in with the rest of the * list seamlessly */ BLI_insertlinkafter(&agrp->channels, agrp->channels.last, fcurve); } /* otherwise, need to find the nearest F-Curve in group before/after current to link with */ else { bActionGroup *grp; /* firstly, link this F-Curve to the group */ agrp->channels.first = agrp->channels.last = fcurve; /* step through the groups preceding this one, finding the F-Curve there to attach this one after */ for (grp = agrp->prev; grp; grp = grp->prev) { /* if this group has F-Curves, we want weave the given one in right after the last channel there, * but via the Action's list not this group's list * - this is so that the F-Curve is in the right place in the Action, * but won't be included in the previous group */ if (grp->channels.last) { /* once we've added, break here since we don't need to search any further... */ BLI_insertlinkafter(&act->curves, grp->channels.last, fcurve); break; } } /* if grp is NULL, that means we fell through, and this F-Curve should be added as the new first * since group is (effectively) the first group. Thus, the existing first F-Curve becomes the * second in the chain, etc. etc. */ if (grp == NULL) BLI_insertlinkbefore(&act->curves, act->curves.first, fcurve); } /* set the F-Curve's new group */ fcurve->grp = agrp; }
static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) { ScanFillVertLink *scdata; ScanFillVertLink *sc = NULL, *sc1; ScanFillVert *eve, *v1, *v2, *v3; ScanFillEdge *eed, *eed_next, *ed1, *ed2, *ed3; unsigned int a, b, verts, maxface, totface; const unsigned short nr = pf->nr; bool twoconnected = false; /* PRINTS */ #if 0 verts = pf->verts; for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { printf("vert: %x co: %f %f\n", eve, eve->xy[0], eve->xy[1]); } for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) { printf("edge: %x verts: %x %x\n", eed, eed->v1, eed->v2); } #endif /* STEP 0: remove zero sized edges */ if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) { for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) { if (equals_v2v2(eed->v1->xy, eed->v2->xy)) { if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) { eed->v2->f = SF_VERT_ZERO_LEN; eed->v2->tmp.v = eed->v1->tmp.v; } else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) { eed->v1->f = SF_VERT_ZERO_LEN; eed->v1->tmp.v = eed->v2->tmp.v; } else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) { eed->v1->tmp.v = eed->v2->tmp.v; } else { eed->v2->f = SF_VERT_ZERO_LEN; eed->v2->tmp.v = eed->v1; } } } } /* STEP 1: make using FillVert and FillEdge lists a sorted * ScanFillVertLink list */ sc = scdata = MEM_mallocN(sizeof(*scdata) * pf->verts, "Scanfill1"); verts = 0; for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { if (eve->poly_nr == nr) { if (eve->f != SF_VERT_ZERO_LEN) { verts++; eve->f = SF_VERT_NEW; /* flag for connectedges later on */ sc->vert = eve; sc->edge_first = sc->edge_last = NULL; /* if (even->tmp.v == NULL) eve->tmp.u = verts; */ /* Note, debug print only will work for curve polyfill, union is in use for mesh */ sc++; } } } qsort(scdata, verts, sizeof(ScanFillVertLink), vergscdata); if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) { for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) { eed_next = eed->next; BLI_remlink(&sf_ctx->filledgebase, eed); /* This code is for handling zero-length edges that get * collapsed in step 0. It was removed for some time to * fix trunk bug #4544, so if that comes back, this code * may need some work, or there will have to be a better * fix to #4544. * * warning, this can hang on un-ordered edges, see: [#33281] * for now disable 'BLI_SCANFILL_CALC_REMOVE_DOUBLES' for ngons. */ if (eed->v1->f == SF_VERT_ZERO_LEN) { v1 = eed->v1; while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) && (eed->v1 != eed->v1->tmp.v)) eed->v1 = eed->v1->tmp.v; } if (eed->v2->f == SF_VERT_ZERO_LEN) { v2 = eed->v2; while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) && (eed->v2 != eed->v2->tmp.v)) eed->v2 = eed->v2->tmp.v; } if (eed->v1 != eed->v2) { addedgetoscanlist(scdata, eed, verts); } } } else { for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) { eed_next = eed->next; BLI_remlink(&sf_ctx->filledgebase, eed); if (eed->v1 != eed->v2) { addedgetoscanlist(scdata, eed, verts); } } } #if 0 sc = sf_ctx->_scdata; for (a = 0; a < verts; a++) { printf("\nscvert: %x\n", sc->vert); for (eed = sc->edge_first; eed; eed = eed->next) { printf(" ed %x %x %x\n", eed, eed->v1, eed->v2); } sc++; } #endif /* STEP 2: FILL LOOP */ if (pf->f == SF_POLY_NEW) twoconnected = true; /* (temporal) security: never much more faces than vertices */ totface = 0; if (flag & BLI_SCANFILL_CALC_HOLES) { maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */ } else { maxface = verts - 2; /* when we don't calc any holes, we assume face is a non overlapping loop */ } sc = scdata; for (a = 0; a < verts; a++) { /* printf("VERTEX %d index %d\n", a, sc->vert->tmp.u); */ /* set connectflags */ for (ed1 = sc->edge_first; ed1; ed1 = eed_next) { eed_next = ed1->next; if (ed1->v1->edge_tot == 1 || ed1->v2->edge_tot == 1) { BLI_remlink((ListBase *)&(sc->edge_first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); if (ed1->v1->edge_tot > 1) ed1->v1->edge_tot--; if (ed1->v2->edge_tot > 1) ed1->v2->edge_tot--; } else { ed1->v2->f = SF_VERT_AVAILABLE; } } while (sc->edge_first) { /* for as long there are edges */ ed1 = sc->edge_first; ed2 = ed1->next; /* commented out... the ESC here delivers corrupted memory (and doesnt work during grab) */ /* if (callLocalInterruptCallBack()) break; */ if (totface >= maxface) { /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */ a = verts; break; } if (ed2 == NULL) { sc->edge_first = sc->edge_last = NULL; /* printf("just 1 edge to vert\n"); */ BLI_addtail(&sf_ctx->filledgebase, ed1); ed1->v2->f = SF_VERT_NEW; ed1->v1->edge_tot--; ed1->v2->edge_tot--; } else { /* test rest of vertices */ ScanFillVertLink *best_sc = NULL; float best_angle = 3.14f; float miny; bool firsttime = false; v1 = ed1->v2; v2 = ed1->v1; v3 = ed2->v2; /* this happens with a serial of overlapping edges */ if (v1 == v2 || v2 == v3) break; /* printf("test verts %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */ miny = min_ff(v1->xy[1], v3->xy[1]); sc1 = sc + 1; for (b = a + 1; b < verts; b++, sc1++) { if (sc1->vert->f == SF_VERT_NEW) { if (sc1->vert->xy[1] <= miny) break; if (testedgeside(v1->xy, v2->xy, sc1->vert->xy)) { if (testedgeside(v2->xy, v3->xy, sc1->vert->xy)) { if (testedgeside(v3->xy, v1->xy, sc1->vert->xy)) { /* point is in triangle */ /* because multiple points can be inside triangle (concave holes) */ /* we continue searching and pick the one with sharpest corner */ if (best_sc == NULL) { /* even without holes we need to keep checking [#35861] */ best_sc = sc1; } else { float angle; /* prevent angle calc for the simple cases only 1 vertex is found */ if (firsttime == false) { best_angle = angle_v2v2v2(v2->xy, v1->xy, best_sc->vert->xy); firsttime = true; } angle = angle_v2v2v2(v2->xy, v1->xy, sc1->vert->xy); if (angle < best_angle) { best_sc = sc1; best_angle = angle; } } } } } } } if (best_sc) { /* make new edge, and start over */ /* printf("add new edge %d %d and start again\n", v2->tmp.u, best_sc->vert->tmp.u); */ ed3 = BLI_scanfill_edge_add(sf_ctx, v2, best_sc->vert); BLI_remlink(&sf_ctx->filledgebase, ed3); BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed2, ed3); ed3->v2->f = SF_VERT_AVAILABLE; ed3->f = SF_EDGE_INTERNAL; ed3->v1->edge_tot++; ed3->v2->edge_tot++; } else { /* new triangle */ /* printf("add face %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */ addfillface(sf_ctx, v1, v2, v3); totface++; BLI_remlink((ListBase *)&(sc->edge_first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); ed1->v2->f = SF_VERT_NEW; ed1->v1->edge_tot--; ed1->v2->edge_tot--; /* ed2 can be removed when it's a boundary edge */ if (((ed2->f == SF_EDGE_NEW) && twoconnected) /* || (ed2->f == SF_EDGE_BOUNDARY) */) { BLI_remlink((ListBase *)&(sc->edge_first), ed2); BLI_addtail(&sf_ctx->filledgebase, ed2); ed2->v2->f = SF_VERT_NEW; ed2->v1->edge_tot--; ed2->v2->edge_tot--; } /* new edge */ ed3 = BLI_scanfill_edge_add(sf_ctx, v1, v3); BLI_remlink(&sf_ctx->filledgebase, ed3); ed3->f = SF_EDGE_INTERNAL; ed3->v1->edge_tot++; ed3->v2->edge_tot++; /* printf("add new edge %x %x\n", v1, v3); */ sc1 = addedgetoscanlist(scdata, ed3, verts); if (sc1) { /* ed3 already exists: remove if a boundary */ /* printf("Edge exists\n"); */ ed3->v1->edge_tot--; ed3->v2->edge_tot--; for (ed3 = sc1->edge_first; ed3; ed3 = ed3->next) { if ((ed3->v1 == v1 && ed3->v2 == v3) || (ed3->v1 == v3 && ed3->v2 == v1)) { if (twoconnected /* || (ed3->f == SF_EDGE_BOUNDARY) */) { BLI_remlink((ListBase *)&(sc1->edge_first), ed3); BLI_addtail(&sf_ctx->filledgebase, ed3); ed3->v1->edge_tot--; ed3->v2->edge_tot--; } break; } } } } } /* test for loose edges */ for (ed1 = sc->edge_first; ed1; ed1 = eed_next) { eed_next = ed1->next; if (ed1->v1->edge_tot < 2 || ed1->v2->edge_tot < 2) { BLI_remlink((ListBase *)&(sc->edge_first), ed1); BLI_addtail(&sf_ctx->filledgebase, ed1); if (ed1->v1->edge_tot > 1) ed1->v1->edge_tot--; if (ed1->v2->edge_tot > 1) ed1->v2->edge_tot--; } } /* done with loose edges */ } sc++; } MEM_freeN(scdata); BLI_assert(totface <= maxface); return totface; }