operator renaming for more consistent word ordering (_add/_remmove shold be last...
[blender-staging.git] / source / blender / editors / physics / particle_object.c
index 1dc08a162b75546a59b395b2e7f69b6f5c8427d9..ce740a53db8144cd573f66b7a28830b8f0504468 100644 (file)
@@ -37,7 +37,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_windowmanager_types.h"
 
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_listbase.h"
 
 #include "BKE_context.h"
@@ -69,7 +69,7 @@ static int particle_system_add_exec(bContext *C, wmOperator *op)
        if(!scene || !ob)
                return OPERATOR_CANCELLED;
 
-       object_add_particle_system(scene, ob);
+       object_add_particle_system(scene, ob, NULL);
        WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
        
        return OPERATOR_FINISHED;
@@ -93,11 +93,20 @@ static int particle_system_remove_exec(bContext *C, wmOperator *op)
 {
        Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
        Scene *scene = CTX_data_scene(C);
-
+       int mode_orig = ob->mode;
        if(!scene || !ob)
                return OPERATOR_CANCELLED;
 
        object_remove_particle_system(scene, ob);
+
+       /* possible this isn't the active object
+        * object_remove_particle_system() clears the mode on the last psys
+        * */
+       if(mode_orig & OB_MODE_PARTICLE_EDIT)
+               if((ob->mode & OB_MODE_PARTICLE_EDIT)==0)
+                       if(scene->basact && scene->basact->object==ob)
+                               WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
+
        WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
        
        return OPERATOR_FINISHED;
@@ -257,11 +266,11 @@ static int remove_particle_target_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void PARTICLE_OT_remove_target(wmOperatorType *ot)
+void PARTICLE_OT_target_remove(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Remove Particle Target";
-       ot->idname= "PARTICLE_OT_remove_target";
+       ot->idname= "PARTICLE_OT_target_remove";
        ot->description="Remove the selected particle target.";
        
        /* api callbacks */
@@ -386,6 +395,90 @@ void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/********************** particle dupliweight operators *********************/
+
+static int copy_particle_dupliob_exec(bContext *C, wmOperator *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->flag &= ~PART_DUPLIW_CURRENT;
+                       dw = MEM_dupallocN(dw);
+                       dw->flag |= PART_DUPLIW_CURRENT;
+                       BLI_addhead(&part->dupliweights, dw);
+
+                       WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
+                       break;
+               }
+       }
+       
+       return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_dupliob_copy(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Copy Particle Dupliob";
+       ot->idname= "PARTICLE_OT_dupliob_copy";
+       ot->description="Duplicate the current dupliobject.";
+       
+       /* api callbacks */
+       ot->exec= copy_particle_dupliob_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int remove_particle_dupliob_exec(bContext *C, wmOperator *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_DRAW, NULL);
+       
+       return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_dupliob_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Remove Particle Dupliobject";
+       ot->idname= "PARTICLE_OT_dupliob_remove";
+       ot->description="Remove the selected dupliobject.";
+       
+       /* api callbacks */
+       ot->exec= remove_particle_dupliob_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /************************ move down particle dupliweight operator *********************/
 
 static int dupliob_move_down_exec(bContext *C, wmOperator *op)
@@ -455,7 +548,7 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
                psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
 
                for(k=0,key=pa->hair; k<pa->totkey; k++,key++) {
-                       Mat4MulVecfl(hairmat,key->co);
+                       mul_m4_v3(hairmat,key->co);
                        
                        if(ekey) {
                                ekey->flag &= ~PEK_USE_WCO;
@@ -517,7 +610,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
        ParticleData *pa;
        PTCacheEdit *edit;
        PTCacheEditPoint *point;
-       PTCacheEditKey *ekey;
+       PTCacheEditKey *ekey = NULL;
        HairKey *key;
        BVHTreeFromMesh bvhtree;
        BVHTreeNearest nearest;
@@ -545,7 +638,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
 
        /* convert to global coordinates */
        for (i=0; i<numverts; i++)
-               Mat4MulVecfl (ob->obmat, CDDM_get_vert(dm, i)->co);
+               mul_m4_v3(ob->obmat, CDDM_get_vert(dm, i)->co);
 
        bvhtree_from_mesh_faces(&bvhtree, dm, 0.0, 2, 6);
 
@@ -564,21 +657,21 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
 
                mface = CDDM_get_face(dm,nearest.index);
 
-               VecCopyf(v[0], CDDM_get_vert(dm,mface->v1)->co);
-               VecCopyf(v[1], CDDM_get_vert(dm,mface->v2)->co);
-               VecCopyf(v[2], CDDM_get_vert(dm,mface->v3)->co);
+               copy_v3_v3(v[0], CDDM_get_vert(dm,mface->v1)->co);
+               copy_v3_v3(v[1], CDDM_get_vert(dm,mface->v2)->co);
+               copy_v3_v3(v[2], CDDM_get_vert(dm,mface->v3)->co);
                if(mface->v4) {
-                       VecCopyf(v[3], CDDM_get_vert(dm,mface->v4)->co);
-                       MeanValueWeights(v, 4, nearest.co, pa->fuv);
+                       copy_v3_v3(v[3], CDDM_get_vert(dm,mface->v4)->co);
+                       interp_weights_poly_v3( pa->fuv,v, 4, nearest.co);
                }
                else
-                       MeanValueWeights(v, 3, nearest.co, pa->fuv);
+                       interp_weights_poly_v3( pa->fuv,v, 3, nearest.co);
 
                pa->num = nearest.index;
                pa->num_dmcache = psys_particle_dm_face_lookup(ob,psmd->dm,pa->num,pa->fuv,NULL);
                
                psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
-               Mat4Invert(imat,hairmat);
+               invert_m4_m4(imat,hairmat);
 
                VECSUB(vec, nearest.co, key->co);
 
@@ -589,7 +682,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
 
                for(k=0,key=pa->hair; k<pa->totkey; k++,key++) {
                        VECADD(key->co, key->co, vec);
-                       Mat4MulVecfl(imat,key->co);
+                       mul_m4_v3(imat,key->co);
 
                        if(ekey) {
                                ekey->flag |= PEK_USE_WCO;