static int connect_hair_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= NULL; int all = RNA_boolean_get(op->ptr, "all"); if(!ob) return OPERATOR_CANCELLED; if(all) { for(psys=ob->particlesystem.first; psys; psys=psys->next) { connect_hair(scene, ob, psys); } } else { psys = ptr.data; connect_hair(scene, ob, psys); } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); return OPERATOR_FINISHED; }
static int remove_particle_dupliob_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) { BLI_remlink(&part->dupliweights, dw); MEM_freeN(dw); break; } } dw = part->dupliweights.last; if (dw) dw->flag |= PART_DUPLIW_CURRENT; WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, NULL); return OPERATOR_FINISHED; }
static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); 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) { BLI_remlink(&psys->targets, pt); MEM_freeN(pt); break; } } pt = psys->targets.last; if (pt) pt->flag |= PTARGET_CURRENT; DAG_relations_tag_update(bmain); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); return OPERATOR_FINISHED; }
static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); 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) pt->flag &= ~PTARGET_CURRENT; pt = MEM_callocN(sizeof(ParticleTarget), "keyed particle target"); pt->flag |= PTARGET_CURRENT; pt->psys = 1; BLI_addtail(&psys->targets, pt); DAG_relations_tag_update(bmain); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); return OPERATOR_FINISHED; }
static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain= CTX_data_main(C); ParticleSystem *psys; ParticleSettings *part = NULL; Object *ob; PointerRNA ptr; ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); psys = ptr.data; /* add or copy particle setting */ if (psys->part) part= BKE_particlesettings_copy(psys->part); else part= psys_new_settings("ParticleSettings", bmain); ob= ptr.id.data; if (psys->part) psys->part->id.us--; psys->part = part; psys_check_boid_data(psys); DAG_relations_tag_update(bmain); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); return OPERATOR_FINISHED; }
static PTCacheBaker *ptcache_baker_create(bContext *C, wmOperator *op, bool all) { PTCacheBaker *baker = MEM_callocN(sizeof(PTCacheBaker), "PTCacheBaker"); baker->main = CTX_data_main(C); baker->scene = CTX_data_scene(C); baker->bake = RNA_boolean_get(op->ptr, "bake"); baker->render = 0; baker->anim_init = 0; baker->quick_step = 1; if (!all) { PointerRNA ptr = CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Object *ob = ptr.id.data; PointCache *cache = ptr.data; ListBase pidlist; BKE_ptcache_ids_from_object(&pidlist, ob, baker->scene, MAX_DUPLI_RECUR); for (PTCacheID *pid = pidlist.first; pid; pid = pid->next) { if (pid->cache == cache) { baker->pid = *pid; break; } } BLI_freelistN(&pidlist); } return baker; }
static int connect_hair_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= ED_object_context(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); ParticleSystem *psys= NULL; const bool all = RNA_boolean_get(op->ptr, "all"); bool any_connected = false; if (!ob) return OPERATOR_CANCELLED; if (all) { for (psys=ob->particlesystem.first; psys; psys=psys->next) { any_connected |= connect_hair(scene, ob, psys); } } else { psys = ptr.data; any_connected |= connect_hair(scene, ob, psys); } if (!any_connected) { BKE_report(op->reports, RPT_ERROR, "Can't disconnect hair if particle system modifier is disabled"); return OPERATOR_CANCELLED; } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob); return OPERATOR_FINISHED; }
static int ptcache_remove_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Scene *scene= CTX_data_scene(C); Object *ob= ptr.id.data; PointCache *cache= ptr.data; PTCacheID *pid; ListBase pidlist; BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) { if(pid->ptcaches->first == pid->ptcaches->last) continue; /* don't delete last cache */ BLI_remlink(pid->ptcaches, pid->cache); BKE_ptcache_free(pid->cache); *(pid->cache_ptr) = pid->ptcaches->first; break; } } BLI_freelistN(&pidlist); WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); return OPERATOR_FINISHED; }
static int vertex_group_menu_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; uiPopupMenu *pup; uiLayout *layout; pup= uiPupMenuBegin(C, "Vertex Groups", 0); layout= uiPupMenuLayout(pup); uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); if(vgroup_object_in_edit_mode(ob)) { uiItemBooleanO(layout, "Assign to New Group", 0, "OBJECT_OT_vertex_group_assign", "new", 1); if(BLI_countlist(&ob->defbase) && ob->actdef) { uiItemO(layout, "Assign to Group", 0, "OBJECT_OT_vertex_group_assign"); uiItemO(layout, "Remove from Group", 0, "OBJECT_OT_vertex_group_remove_from"); uiItemBooleanO(layout, "Remove from All", 0, "OBJECT_OT_vertex_group_remove_from", "all", 1); } } if(BLI_countlist(&ob->defbase) && ob->actdef) { if(vgroup_object_in_edit_mode(ob)) uiItemS(layout); uiItemO(layout, "Set Active Group", 0, "OBJECT_OT_vertex_group_set_active"); uiItemO(layout, "Remove Group", 0, "OBJECT_OT_vertex_group_remove"); uiItemBooleanO(layout, "Remove All Groups", 0, "OBJECT_OT_vertex_group_remove", "all", 1); } uiPupMenuEnd(C, pup); return OPERATOR_FINISHED; }
static int rule_del_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); 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) { BLI_remlink(&state->rules, rule); MEM_freeN(rule); break; } } rule = state->rules.first; if (rule) rule->flag |= BOIDRULE_CURRENT; DAG_relations_tag_update(bmain); DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); return OPERATOR_FINISHED; }
static int rule_move_down_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; BoidRule *rule; BoidState *state; if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; state = boid_get_current_state(psys->part->boids); for(rule = state->rules.first; rule; rule=rule->next) { if(rule->flag & BOIDRULE_CURRENT && rule->next) { BLI_remlink(&state->rules, rule); BLI_insertlink(&state->rules, rule->next, rule); DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); break; } } return OPERATOR_FINISHED; }
static int object_hook_recenter_exec(bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); int num= RNA_enum_get(op->ptr, "modifier"); Object *ob=NULL; HookModifierData *hmd=NULL; Scene *scene = CTX_data_scene(C); float bmat[3][3], imat[3][3]; if (ptr.data) { /* if modifier context is available, use that */ ob = ptr.id.data; hmd= ptr.data; } else { /* use the provided property */ ob = CTX_data_edit_object(C); hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); } if (!ob || !hmd) { BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); return OPERATOR_CANCELLED; } /* recenter functionality */ copy_m3_m4(bmat, ob->obmat); invert_m3_m3(imat, bmat); sub_v3_v3v3(hmd->cent, scene->cursor, ob->obmat[3]); mul_m3_v3(imat, hmd->cent); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; }
static int object_hook_select_exec(bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_HookModifier); int num= RNA_enum_get(op->ptr, "modifier"); Object *ob=NULL; HookModifierData *hmd=NULL; if (ptr.data) { /* if modifier context is available, use that */ ob = ptr.id.data; hmd= ptr.data; } else { /* use the provided property */ ob = CTX_data_edit_object(C); hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); } if (!ob || !hmd) { BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); return OPERATOR_CANCELLED; } /* select functionality */ object_hook_select(ob, hmd); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); return OPERATOR_FINISHED; }
static int edit_controller_poll(bContext *C) { PointerRNA ptr = CTX_data_pointer_get_type(C, "controller", &RNA_Controller); if (ptr.data && ((ID *)ptr.id.data)->lib) return 0; return 1; }
static int edit_actuator_poll(bContext *C) { PointerRNA ptr = CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator); if (ptr.data && ((ID *)ptr.id.data)->lib) return 0; return 1; }
/************************ add/del boid rule operators *********************/ static int rule_add_exec(bContext *C, wmOperator *op) { PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); ParticleSettings *part = ptr.data; int type= RNA_enum_get(op->ptr, "type"); 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) rule->flag &= ~BOIDRULE_CURRENT; rule = boid_new_rule(type); rule->flag |= BOIDRULE_CURRENT; BLI_addtail(&state->rules, rule); DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); return OPERATOR_FINISHED; }
static int edit_actuator_poll(bContext *C) { PointerRNA ptr = CTX_data_pointer_get_type(C, "actuator", &RNA_Actuator); if (ptr.data && ID_IS_LINKED_DATABLOCK(ptr.id.data)) return 0; return 1; }
static int state_del_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings); ParticleSettings *part = ptr.data; BoidState *state; if (!part || part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; for (state=part->boids->states.first; state; state=state->next) { if (state->flag & BOIDSTATE_CURRENT) { BLI_remlink(&part->boids->states, state); MEM_freeN(state); break; } } /* there must be at least one state */ if (!part->boids->states.first) { state = boid_new_state(part->boids); BLI_addtail(&part->boids->states, state); } else state = part->boids->states.first; state->flag |= BOIDSTATE_CURRENT; DAG_relations_tag_update(bmain); DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); return OPERATOR_FINISHED; }
/************************ add/del boid state operators *********************/ static int state_add_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; ParticleSettings *part; BoidState *state; if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) return OPERATOR_CANCELLED; part = psys->part; for(state=part->boids->states.first; state; state=state->next) state->flag &= ~BOIDSTATE_CURRENT; state = boid_new_state(part->boids); state->flag |= BOIDSTATE_CURRENT; BLI_addtail(&part->boids->states, state); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); return OPERATOR_FINISHED; }
static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Object *ob= ptr.id.data; PointCache *cache= ptr.data; PTCacheID *pid; ListBase pidlist; BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) { *(pid->cache_ptr) = BKE_ptcache_add(pid->ptcaches); break; } } BLI_freelistN(&pidlist); WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); return OPERATOR_FINISHED; }
static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Base *base; int retval= OPERATOR_CANCELLED; for(base=scene->base.first; base; base= base->next) { if(base->object->type==ob->type) { if(base->object!=ob && base->object->data==ob->data) { BLI_freelistN(&base->object->defbase); BLI_duplicatelist(&base->object->defbase, &ob->defbase); base->object->actdef= ob->actdef; DAG_id_flush_update(&base->object->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, base->object); WM_event_add_notifier(C, NC_GEOM|ND_DATA, base->object->data); retval = OPERATOR_FINISHED; } } } return retval; }
static int shape_key_mirror_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; if(!object_shape_key_mirror(C, ob)) return OPERATOR_CANCELLED; return OPERATOR_FINISHED; }
/* ChildOf Constraint - set inverse callback */ static int childof_set_inverse_exec (bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint); Scene *scene= CTX_data_scene(C); Object *ob= ptr.id.data; bConstraint *con= ptr.data; bChildOfConstraint *data= (bChildOfConstraint *)con->data; bPoseChannel *pchan= NULL; /* try to find a pose channel */ // TODO: get from context instead? if (ob && ob->pose) pchan= get_active_posechannel(ob); /* calculate/set inverse matrix */ if (pchan) { float pmat[4][4], cinf; float imat[4][4], tmat[4][4]; /* make copy of pchan's original pose-mat (for use later) */ Mat4CpyMat4(pmat, pchan->pose_mat); /* disable constraint for pose to be solved without it */ cinf= con->enforce; con->enforce= 0.0f; /* solve pose without constraint */ where_is_pose(scene, ob); /* determine effect of constraint by removing the newly calculated * pchan->pose_mat from the original pchan->pose_mat, thus determining * the effect of the constraint */ Mat4Invert(imat, pchan->pose_mat); Mat4MulMat4(tmat, imat, pmat); Mat4Invert(data->invmat, tmat); /* recalculate pose with new inv-mat */ con->enforce= cinf; where_is_pose(scene, ob); } else if (ob) { Object workob; /* use what_does_parent to find inverse - just like for normal parenting. * NOTE: what_does_parent uses a static workob defined in object.c */ what_does_parent(scene, ob, &workob); Mat4Invert(data->invmat, workob.obmat); } else Mat4One(data->invmat); WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob); return OPERATOR_FINISHED; }
static int vertex_group_poll_edit(bContext *C) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; ID *data= (ob)? ob->data: NULL; if(!(ob && !ob->id.lib && data && !data->lib)) return 0; return vgroup_object_in_edit_mode(ob); }
static int limitdistance_reset_exec (bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_LimitDistanceConstraint); /* just set distance to 0.0, which will cause a reset on next recalc */ RNA_float_set(&ptr, "distance", 0.0f); WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); return OPERATOR_FINISHED; }
static int vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Mesh *me= ob->data; if(!ED_mesh_color_remove(C, ob, me)) return OPERATOR_CANCELLED; return OPERATOR_FINISHED; }
static int shape_key_add_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; int from_mix = RNA_boolean_get(op->ptr, "from_mix"); ED_object_shape_key_add(C, scene, ob, from_mix); return OPERATOR_FINISHED; }
static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; Mesh *me= ob->data; if(!ED_mesh_uv_texture_add(C, me, NULL, TRUE)) return OPERATOR_CANCELLED; return OPERATOR_FINISHED; }
static int stretchto_reset_exec (bContext *C, wmOperator *op) { PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_StretchToConstraint); /* just set original length to 0.0, which will cause a reset on next recalc */ RNA_float_set(&ptr, "original_length", 0.0f); WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, NULL); return OPERATOR_FINISHED; }
static int vertex_group_copy_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; vgroup_duplicate(ob); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); return OPERATOR_FINISHED; }