From 84362956d49e9698e6f23eaf356796e140894399 Mon Sep 17 00:00:00 2001
From: Cyrille Henry <nusmuk@users.sourceforge.net>
Date: Tue, 15 Jan 2013 00:49:30 +0000
Subject: split code in diferents files add gimme to all list message to add
 filters add different message to replace the "get" methode add message to
 adapt link length to a % of curent length, so that force decrease with time
 separate messages for link centrer and links ends certainly various other
 minor things

svn path=/trunk/externals/pmpd/; revision=16864
---
 pmpd3d.c         | 4674 ++----------------------------------------------------
 pmpd3d_get.c     |  591 +++++++
 pmpd3d_list.c    | 1111 +++++++++++++
 pmpd3d_set.c     |  457 ++++++
 pmpd3d_stat.c    |  395 +++++
 pmpd3d_tab.c     | 1890 ++++++++++++++++++++++
 pmpd3d_various.c |  502 ++++++
 7 files changed, 5120 insertions(+), 4500 deletions(-)
 create mode 100644 pmpd3d_get.c
 create mode 100644 pmpd3d_list.c
 create mode 100644 pmpd3d_set.c
 create mode 100644 pmpd3d_stat.c
 create mode 100644 pmpd3d_tab.c
 create mode 100644 pmpd3d_various.c

diff --git a/pmpd3d.c b/pmpd3d.c
index 5e19383..a56dcd8 100644
--- a/pmpd3d.c
+++ b/pmpd3d.c
@@ -146,43 +146,16 @@ void pmpd3d_reset(t_pmpd3d *x)
     x->grab = 0;
 }
 
-void pmpd3d_infosL(t_pmpd3d *x)
+void *pmpd3d_new()
 {
-    int i;
-    post("list of mass");
-    post("number, Id, mobile, mass, Damping, positionX Y Z, speedX Y Z, forcesX Y Z");
-    for(i=0; i < x->nb_mass; i++)
-    {
-        post("masse %i: %s, %d, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f",i, x->mass[i].Id->s_name, \
-            x->mass[i].mobile, 1/x->mass[i].invM, x->mass[i].D2, x->mass[i].posX, x->mass[i].posY, \
-            x->mass[i].posZ, x->mass[i].speedX, x->mass[i].speedY, x->mass[i].speedZ, \
-            x->mass[i].forceX, x->mass[i].forceY, x->mass[i].forceZ );
-    }
+    t_pmpd3d *x = (t_pmpd3d *)pd_new(pmpd3d_class);
 
-    post("list of link");
-    post("number, Id, mass1, mass2, K, D, Pow, L, Lmin, Lmax");
-    for(i=0; i < x->nb_link; i++)
-    {    
-        switch (x->link[i].lType)
-        {
-        case 0:
-            post("link %i: %s, %i, %i, %f, %f, %f, %f, %f, %f", i, x->link[i].Id->s_name, \
-                x->link[i].mass1->num, x->link[i].mass2->num, x->link[i].K, x->link[i].D, \
-                x->link[i].Pow, x->link[i].L, x->link[i].Lmin, x->link[i].Lmax);
-            break;
-        case 1:
-            post("tLink %i: %s, %i, %i, %f, %f, %f, %f, %f, %f, %f, %f, %f", i, x->link[i].Id->s_name, \
-                x->link[i].mass1->num, x->link[i].mass2->num, x->link[i].K, x->link[i].D, \
-                x->link[i].Pow, x->link[i].L, x->link[i].Lmin, x->link[i].Lmax, \
-                x->link[i].VX, x->link[i].VY, x->link[i].VZ);
-            break;
-        case 2:
-            post("tabLink %i: %s, %i, %i, %f, %f, %s, %f, %s, %f", i, x->link[i].Id->s_name, \
-                x->link[i].mass1->num, x->link[i].mass2->num, x->link[i].K, x->link[i].D, \
-                x->link[i].arrayK->s_name, x->link[i].K_L, x->link[i].arrayD->s_name, x->link[i].D_L);
-            break;        
-        }
-    }
+    pmpd3d_reset(x);
+    
+    x->main_outlet=outlet_new(&x->x_obj, 0);
+    // x->info_outlet=outlet_new(&x->x_obj, 0); // TODO
+
+    return (void *)x;
 }
 
 void pmpd3d_bang(t_pmpd3d *x)
@@ -545,4479 +518,183 @@ void pmpd3d_tabLink(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
 
 }
 
-void pmpd3d_setK(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_link-1, tmp));
-        x->link[tmp].K = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
-            {
-                x->link[i].K = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setD(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_link-1, tmp));
-        x->link[tmp].D = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
-            {
-                x->link[i].D = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_link-1, tmp));
-        x->link[tmp].L = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
-            {
-                x->link[i].L = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argc == 1 ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_link-1, tmp));
-        x->link[tmp].L = x->link[tmp].mass2->posX - x->link[tmp].mass1->posX;
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argc == 1 ) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
-            {
-                x->link[i].L = x->link[i].mass2->posX - x->link[i].mass1->posX;
-            }
-        }
-    }
-}
-
-/*void pmpd3d_adaptLength(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_link-1, tmp));
-        x->link[tmp].L = mix(x->link[tmp].L,x->link[tmp].distance,atom_getfloatarg(1, argc, argv));
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
-            {
-                x->link[tmp].L = mix(x->link[tmp].L,x->link[tmp].distance,atom_getfloatarg(1, argc, argv));
-            }
-        }
-    }
-}*/
-
-void pmpd3d_setLKTab(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-    t_float K_l = atom_getfloatarg(1, argc, argv);
-    if (K_l <=  0) K_l = 1;
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_link-1, tmp));
-        x->link[tmp].K_L = K_l;
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
-            {
-                x->link[i].K_L = K_l;
-            }
-        }
-    }
-}
-
-void pmpd3d_setLDTab(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-    t_float D_l = atom_getfloatarg(1, argc, argv);
-    if (D_l <=  0) D_l = 1;
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_link-1, tmp));
-        x->link[tmp].D_L = D_l;
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
-            {
-                x->link[i].D_L = D_l;
-            }
-        }
-    }
-}
-
-void pmpd3d_setLinkId(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_SYMBOL ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_link-1, tmp));
-        x->link[tmp].Id = atom_getsymbolarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_SYMBOL ) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
-            {
-                x->link[i].Id = atom_getsymbolarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setMassId(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_SYMBOL ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].Id = atom_getsymbolarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_SYMBOL ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].Id = atom_getsymbolarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_forceX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-// add a force to a specific mass
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].forceX += atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].forceX += atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_forceY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-// add a force to a specific mass
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].forceY += atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].forceY += atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_forceZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-// add a force to a specific mass
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].forceZ += atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].forceZ += atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
+#include "pmpd3d_set.c"
+#include "pmpd3d_get.c"
+#include "pmpd3d_list.c"
+#include "pmpd3d_tab.c"
+#include "pmpd3d_various.c"
+#include "pmpd3d_stat.c"
 
-void pmpd3d_force(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+void pmpd3d_setup(void) 
 {
-// add a force to a specific mass
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].forceX += atom_getfloatarg(1, argc, argv);
-        x->mass[tmp].forceY += atom_getfloatarg(2, argc, argv);
-        x->mass[tmp].forceZ += atom_getfloatarg(3, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].forceX += atom_getfloatarg(1, argc, argv);
-                x->mass[i].forceY += atom_getfloatarg(2, argc, argv);
-                x->mass[i].forceZ += atom_getfloatarg(3, argc, argv);
-            }
-        }
-    }
-}
+ pmpd3d_class = class_new(gensym("pmpd3d"),
+        (t_newmethod)pmpd3d_new,
+        0, sizeof(t_pmpd3d),CLASS_DEFAULT, 0);
 
-void pmpd3d_posX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-// displace a mass to a certain position
-    int tmp, i;
+    class_addbang(pmpd3d_class, pmpd3d_bang);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_reset,           gensym("reset"), 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_mass,            gensym("mass"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_link,            gensym("link"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_tLink,           gensym("tLink"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_tabLink,         gensym("tabLink"), A_GIMME, 0);
+    
+// pmpd3d_set
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setK,            gensym("setK"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setD,            gensym("setD"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setDEnv,         gensym("setDEnv"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setDEnvOffset,   gensym("setDEnvOffset"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setL,            gensym("setL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setLKTab,        gensym("setLKTab"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setLDTab,        gensym("setLDTab"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setLinkId,       gensym("setLinkId"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setMassId,       gensym("setMassId"), A_GIMME, 0);    
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setFixed,        gensym("setFixed"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setMobile,       gensym("setMobile"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedX,       gensym("setSpeedX"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedY,       gensym("setSpeedY"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedZ,       gensym("setSpeedZ"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeed,        gensym("setSpeed"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceX,       gensym("setForceX"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceY,       gensym("setForceY"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceZ,       gensym("setForceZ"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForce,        gensym("setForce"), A_GIMME, 0);
+         
+// pmpd3d_get
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_get,             gensym("get"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPos,       gensym("massesPos"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeeds,    gensym("massesSpeeds"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForces,    gensym("massesForces"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPos,        gensym("linksPos"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnds,       gensym("linksEnds"), A_GIMME, 0);
+
+//pmpd3d_list
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosL,      gensym("massesPosL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsL,   gensym("massesSpeedsL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesL,   gensym("massesForcesL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosXL,     gensym("massesPosXL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsXL,  gensym("massesSpeedsXL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesXL,  gensym("massesForcesXL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosYL,     gensym("massesPosYL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsYL,  gensym("massesSpeedsYL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesYL,  gensym("massesForcesYL"), A_GIMME, 0);    
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosZL,     gensym("massesPosZL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsZL,  gensym("massesSpeedsZL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesZL,  gensym("massesForcesZL"), A_GIMME, 0);
+    
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosNormL,      gensym("massesPosNormL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsNormL,   gensym("massesSpeedsNormL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesNormL,   gensym("massesForcesNormL"), A_GIMME, 0);    
+    
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosL,           	gensym("linksPosL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthL,            gensym("linksLengthL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedL,          gensym("linksPosSpeedL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedL,       gensym("linksLengthSpeedL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosXL,              gensym("linksPosXL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthXL,           gensym("linksLengthXL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedXL,         gensym("linksPosSpeedXL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedXL,      gensym("linksLengthSpeedXL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosYL,              gensym("linksPosYL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthYL,           gensym("linksLengthYL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedYL,         gensym("linksPosSpeedYL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedYL,      gensym("linksLengthSpeedYL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosZL,              gensym("linksPosZL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthZL,           gensym("linksLengthZL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedZL,         gensym("linksPosSpeedZL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedZL,      gensym("linksLengthSpeedZL"), A_GIMME, 0);
+
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosNormL,           gensym("linksPosNormL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthNormL,        gensym("linksLengthNormL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedNormL,      gensym("linksPosSpeedNormL"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedNormL,   gensym("linksLengthSpeedNormL"), A_GIMME, 0);
+    
+// pmpd3d_tab
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosT,      	gensym("massesPosT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsT,   	gensym("massesSpeedsT"),A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesT,  	 	gensym("massesForcesT"),A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosXT,     	gensym("massesPosXT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsXT,  	gensym("massesSpeedsXT"),A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesXT,  	gensym("massesForcesXT"),A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosYT,     	gensym("massesPosYT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsYT,  	gensym("massesSpeedsYT"),A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesYT,  	gensym("massesForcesYT"),A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosZT,     	gensym("massesPosZT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsZT,  	gensym("massesSpeedsZT"),A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesZT,  	gensym("massesForcesZT"),A_GIMME, 0);
+    
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosNormT,      gensym("massesPosNormT"),  A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsNormT,   gensym("massesSpeedsNormT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesNormT,   gensym("massesForcesNormT"), A_GIMME, 0);
+    
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosT,           	gensym("linksPosT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthT,            gensym("linksLengthT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedT,          gensym("linksPosSpeedT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedT,       gensym("linksLengthSpeedT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosXT,              gensym("linksPosXT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthXT,       	gensym("linksLengthXT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedXT,      	gensym("linksPosSpeedXT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedXT,      gensym("linksLengthSpeedXT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosYT,              gensym("linksPosYT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthYT,           gensym("linksLengthYT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedYT,         gensym("linksPosSpeedYT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedYT,      gensym("linksLengthSpeedYT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosZT,              gensym("linksPosZT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthZT,           gensym("linksLengthZT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedZT,         gensym("linksPosSpeedZT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedZT,      gensym("linksLengthSpeedZT"), A_GIMME, 0);
 
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].posX = atom_getfloatarg(1, argc, argv);
-           x->mass[tmp].speedX = 0; 
-        x->mass[tmp].forceX = 0; 
-        
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].posX = atom_getfloatarg(1, argc, argv);
-                x->mass[i].speedX = 0; 
-                x->mass[i].forceX = 0;
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosNormT,               gensym("linksPosNormT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthNormT,            gensym("linksLengthNormT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedNormT,          gensym("linksPosSpeedNormT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedNormT,       gensym("linksLengthSpeedNormT"), A_GIMME, 0);
+    
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEndT,               gensym("linksEndT"),   A_GIMME, 0);
+/*    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd1T,               gensym("linksEnd1T"),  A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd2T,              gensym("linksEnd2T"),  A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEndXT,              gensym("linksEndXT"),  A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd1XT,             gensym("linksEnd1XT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd2XT,             gensym("linksEnd2XT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEndYT,              gensym("linksEndYT"),  A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd1YT,             gensym("linksEnd1YT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd2YT,             gensym("linksEnd2YT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEndZT,              gensym("linksEndZT"),  A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd1ZT,             gensym("linksEnd1ZT"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd2ZT,             gensym("linksEnd2ZT"), A_GIMME, 0);
+*/    
 
-            }
-        }
-    }
-}
+// pmpd3d_various
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_infosL,          gensym("infosL"), 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_infosL,          gensym("print"), 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_force,           gensym("force"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceX,          gensym("forceX"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceY,          gensym("forceY"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceZ,          gensym("forceZ"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_pos,             gensym("pos"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_posX,            gensym("posX"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_posY,            gensym("posY"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_posZ,            gensym("posZ"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_min,             gensym("min"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_max,             gensym("max"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_minX,            gensym("Xmin"), A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxX,            gensym("Xmax"), A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_minY,            gensym("Ymin"), A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxY,            gensym("Ymax"), A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_minZ,            gensym("Zmin"), A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxZ,            gensym("Zmax"), A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPos,          gensym("addPos"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosX,         gensym("addPosX"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosY,         gensym("addPosY"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosZ,         gensym("addPosZ"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_grabMass,        gensym("grabMass"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_closestMass,     gensym("closestMass"), A_GIMME, 0);
+    class_addmethod(pmpd3d_class, (t_method)pmpd3d_adaptLength,     gensym("adaptLength"), A_GIMME, 0);
 
-void pmpd3d_posY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-// displace a mass to a certain position
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].posY = atom_getfloatarg(1, argc, argv);
-           x->mass[tmp].speedY = 0; 
-        x->mass[tmp].forceY = 0; 
-        
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].posY = atom_getfloatarg(1, argc, argv);
-                x->mass[i].speedY = 0; 
-                x->mass[i].forceY = 0;
-            }
-        }
-    }
-}
-
-void pmpd3d_posZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-// displace a mass to a certain position
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].posZ = atom_getfloatarg(1, argc, argv);
-           x->mass[tmp].speedZ = 0; 
-        x->mass[tmp].forceZ = 0; 
-        
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].posZ = atom_getfloatarg(1, argc, argv);
-                x->mass[i].speedZ = 0; 
-                x->mass[i].forceZ = 0;
-            }
-        }
-    }
-}
-
-void pmpd3d_pos(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-// displace a mass to a certain position
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].posX = atom_getfloatarg(1, argc, argv);
-           x->mass[tmp].speedX = 0; 
-        x->mass[tmp].forceX = 0; 
-           x->mass[tmp].posY = atom_getfloatarg(2, argc, argv);
-           x->mass[tmp].speedY = 0; 
-        x->mass[tmp].forceY = 0;
-           x->mass[tmp].posZ = atom_getfloatarg(3, argc, argv);
-           x->mass[tmp].speedZ = 0; 
-        x->mass[tmp].forceZ = 0; 
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].posX = atom_getfloatarg(1, argc, argv);
-                x->mass[i].speedX = 0; 
-                x->mass[i].forceX = 0;
-                x->mass[i].posY = atom_getfloatarg(2, argc, argv);
-                x->mass[i].speedY = 0; 
-                x->mass[i].forceY = 0;
-                x->mass[i].posZ = atom_getfloatarg(3, argc, argv);
-                x->mass[i].speedZ = 0; 
-                x->mass[i].forceZ = 0;
-            }
-        }
-    }
-}
-
-void pmpd3d_minX(t_pmpd3d *x, t_float min)
-{
-    x->minX = min;
-}
-
-void pmpd3d_maxX(t_pmpd3d *x, t_float max)
-{
-    x->maxX = max;
-}
-
-void pmpd3d_minY(t_pmpd3d *x, t_float min)
-{
-    x->minY = min;
-}
-
-void pmpd3d_maxY(t_pmpd3d *x, t_float max)
-{
-    x->maxY = max;
-}
-
-void pmpd3d_minZ(t_pmpd3d *x, t_float min)
-{
-    x->minZ = min;
-}
-
-void pmpd3d_maxZ(t_pmpd3d *x, t_float max)
-{
-    x->maxZ = max;
-}
-
-void pmpd3d_min(t_pmpd3d *x, t_float minX, t_float minY, t_float minZ)
-{
-    x->minX = minX;
-    x->minY = minY;
-    x->minZ = minZ;
-}
-
-void pmpd3d_max(t_pmpd3d *x, t_float maxX, t_float maxY, t_float maxZ)
-{
-    x->maxX = maxX;
-    x->maxY = maxY;
-    x->maxZ = maxZ;
-}
-
-void pmpd3d_setFixed(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( argv[0].a_type == A_FLOAT ) 
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].mobile = 0;
-    }
-    if ( argv[0].a_type == A_SYMBOL )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].mobile = 0;
-            }
-        }
-    }
-}
-
-void pmpd3d_setMobile(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( argv[0].a_type == A_FLOAT )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].mobile = 1;
-    }
-    if ( argv[0].a_type == A_SYMBOL ) 
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].mobile = 1;
-            }
-        }
-    }
-}
-
-void pmpd3d_setD2(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].D2 = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].D2 = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argc == 1 ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            x->mass[i].D2 = atom_getfloatarg(0, argc, argv);
-        }
-    }
-}
-
-void pmpd3d_setD2offset(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].D2offset = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].D2offset = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argc == 1 ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            x->mass[i].D2offset = atom_getfloatarg(0, argc, argv);
-        }
-    }
-}
-
-void pmpd3d_setSpeedX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].speedX = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].speedX = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setSpeedY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].speedY = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].speedY = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setSpeedZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].speedZ = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].speedZ = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setSpeed(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].speedX = atom_getfloatarg(1, argc, argv);
-        x->mass[tmp].speedY = atom_getfloatarg(2, argc, argv);
-        x->mass[tmp].speedZ = atom_getfloatarg(3, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].speedX = atom_getfloatarg(1, argc, argv);
-                x->mass[i].speedY = atom_getfloatarg(2, argc, argv);
-                x->mass[i].speedZ = atom_getfloatarg(3, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_addPosX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].posX += atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].posX += atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_addPosY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].posY += atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].posY += atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_addPosZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].posZ += atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].posZ += atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_addPos(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].posX += atom_getfloatarg(1, argc, argv);
-        x->mass[tmp].posY += atom_getfloatarg(2, argc, argv);
-        x->mass[tmp].posZ += atom_getfloatarg(3, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].posX += atom_getfloatarg(1, argc, argv);
-                x->mass[i].posY += atom_getfloatarg(2, argc, argv);
-                x->mass[i].posZ += atom_getfloatarg(3, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setForceX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].forceX = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].forceX = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setForceY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].forceY = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].forceY = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setForceZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].forceZ = atom_getfloatarg(1, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].forceZ = atom_getfloatarg(1, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_setForce(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int tmp, i;
-
-    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        tmp = atom_getfloatarg(0, argc, argv);
-        tmp = max(0, min( x->nb_mass-1, tmp));
-        x->mass[tmp].forceX = atom_getfloatarg(1, argc, argv);
-        x->mass[tmp].forceY = atom_getfloatarg(2, argc, argv);
-        x->mass[tmp].forceZ = atom_getfloatarg(3, argc, argv);
-    }
-    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            {
-                x->mass[i].forceX = atom_getfloatarg(1, argc, argv);
-                x->mass[i].forceY = atom_getfloatarg(2, argc, argv);
-                x->mass[i].forceZ = atom_getfloatarg(3, argc, argv);
-            }
-        }
-    }
-}
-
-void pmpd3d_get(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i;
-    t_symbol *toget; 
-    t_atom  toout[7];
-    toget = atom_getsymbolarg(0, argc, argv);
-
-    if ( (toget == gensym("massesPos")) && (argv[1].a_type == A_FLOAT) )
-    {
-        i = atom_getfloatarg(1, argc, argv);
-        if ( (i>=0) && (i<x->nb_mass) )
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->mass[i].posX);
-            SETFLOAT(&(toout[2]), x->mass[i].posY);
-            SETFLOAT(&(toout[3]), x->mass[i].posZ);
-            outlet_anything(x->main_outlet, gensym("massesPosNo"), 4, toout);
-        }  
-    }
-    else
-    if ( (toget == gensym("massesPos")) && (argv[1].a_type == A_SYMBOL) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
-            {
-                SETFLOAT(&(toout[0]), i);
-                SETFLOAT(&(toout[1]), x->mass[i].posX);
-                SETFLOAT(&(toout[2]), x->mass[i].posY);
-                SETFLOAT(&(toout[3]), x->mass[i].posZ);
-                outlet_anything(x->main_outlet, gensym("massesPosId"), 4, toout);
-            }
-        } 
-    }
-    else
-    if ( (toget == gensym("massesPos")) && (argc == 1) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->mass[i].posX);
-            SETFLOAT(&(toout[2]), x->mass[i].posY);
-            SETFLOAT(&(toout[3]), x->mass[i].posZ);
-            outlet_anything(x->main_outlet, gensym("massesPos"), 4, toout);
-        } 
-    }
-    else
-    if ( (toget == gensym("massesPosName")) && (argv[1].a_type == A_FLOAT) )
-    {
-        i = atom_getfloatarg(1, argc, argv);
-        if ( (i>=0) && (i<x->nb_mass) )
-        {
-            SETSYMBOL(&(toout[0]), x->mass[i].Id);
-            SETFLOAT(&(toout[1]), x->mass[i].posX);
-            SETFLOAT(&(toout[2]), x->mass[i].posY);
-            SETFLOAT(&(toout[3]), x->mass[i].posZ);
-            outlet_anything(x->main_outlet, gensym("massesPosNameNo"), 4, toout);
-        }  
-    }
-    else
-    if ( (toget == gensym("massesPosName")) && (argv[1].a_type == A_SYMBOL) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
-            {
-                SETSYMBOL(&(toout[0]), x->mass[i].Id);
-                SETFLOAT(&(toout[1]), x->mass[i].posX);
-                SETFLOAT(&(toout[2]), x->mass[i].posY);
-                SETFLOAT(&(toout[3]), x->mass[i].posZ);
-                outlet_anything(x->main_outlet, gensym("massesPosNameId"), 4, toout);
-            }
-        } 
-    }
-    else
-    if ( (toget == gensym("massesPosName")) && (argc == 1) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETSYMBOL(&(toout[0]), x->mass[i].Id);
-            SETFLOAT(&(toout[1]), x->mass[i].posX);
-            SETFLOAT(&(toout[2]), x->mass[i].posY);
-            SETFLOAT(&(toout[3]), x->mass[i].posZ);
-            outlet_anything(x->main_outlet, gensym("massesPosName"), 4, toout);
-        } 
-    }
-    else
-    if ( (toget == gensym("massesSpeeds")) && (argv[1].a_type == A_FLOAT) )
-    {
-        i = atom_getfloatarg(1, argc, argv);
-        if ( (i>=0) && (i<x->nb_mass) )
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->mass[i].speedX);
-            SETFLOAT(&(toout[2]), x->mass[i].speedY);
-            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
-            outlet_anything(x->main_outlet, gensym("massesSpeedsNo"), 4, toout);
-        }  
-    }
-    else
-    if ( (toget == gensym("massesSpeeds")) && (argv[1].a_type == A_SYMBOL) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
-            {
-                SETFLOAT(&(toout[0]), i);
-                SETFLOAT(&(toout[1]), x->mass[i].speedX);
-                SETFLOAT(&(toout[2]), x->mass[i].speedY);
-                SETFLOAT(&(toout[3]), x->mass[i].speedZ);
-                outlet_anything(x->main_outlet, gensym("massesSpeedsId"), 4, toout);
-            }
-        } 
-    }
-    else
-    if ( (toget == gensym("massesSpeeds")) && (argc == 1) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->mass[i].speedX);
-            SETFLOAT(&(toout[2]), x->mass[i].speedY);
-            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
-            outlet_anything(x->main_outlet, gensym("massesSpeeds"), 4, toout);
-        } 
-    }
-    else
-    if ( (toget == gensym("massesSpeedsName")) && (argv[1].a_type == A_FLOAT) )
-    {
-        i = atom_getfloatarg(1, argc, argv);
-        if ( (i>=0) && (i<x->nb_mass) )
-        {
-            SETSYMBOL(&(toout[0]), x->mass[i].Id);
-            SETFLOAT(&(toout[1]), x->mass[i].speedX);
-            SETFLOAT(&(toout[2]), x->mass[i].speedY);
-            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
-            outlet_anything(x->main_outlet, gensym("massesSpeedsNameNo"), 4, toout);
-        }  
-    }
-    else
-    if ( (toget == gensym("massesSpeedsName")) && (argv[1].a_type == A_SYMBOL) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
-            {
-                SETSYMBOL(&(toout[0]), x->mass[i].Id);
-                SETFLOAT(&(toout[1]), x->mass[i].speedX);
-                SETFLOAT(&(toout[2]), x->mass[i].speedY);
-                SETFLOAT(&(toout[3]), x->mass[i].speedZ);
-                outlet_anything(x->main_outlet, gensym("massesSpeedsNameId"), 4, toout);
-            }
-        } 
-    }
-    else
-    if ( (toget == gensym("massesSpeedsName")) && (argc == 1) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETSYMBOL(&(toout[0]), x->mass[i].Id);
-            SETFLOAT(&(toout[1]), x->mass[i].speedX);
-            SETFLOAT(&(toout[2]), x->mass[i].speedY);
-            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
-            outlet_anything(x->main_outlet, gensym("massesSpeedsName"), 4, toout);
-        } 
-    }
-    else
-    if ( (toget == gensym("massesForces")) && (argv[1].a_type == A_FLOAT) )
-    {
-        i = atom_getfloatarg(1, argc, argv);
-        if ( (i>=0) && (i<x->nb_mass) )
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->mass[i].forceX);
-            SETFLOAT(&(toout[2]), x->mass[i].forceY);
-            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
-            outlet_anything(x->main_outlet, gensym("massesForcesNo"), 4, toout);
-        }  
-    }
-    else
-    if ( (toget == gensym("massesForces")) && (argv[1].a_type == A_SYMBOL) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
-            {
-                SETFLOAT(&(toout[0]), i);
-                SETFLOAT(&(toout[1]), x->mass[i].forceX);
-                SETFLOAT(&(toout[2]), x->mass[i].forceY);
-                SETFLOAT(&(toout[3]), x->mass[i].forceZ);
-                outlet_anything(x->main_outlet, gensym("massesForcesId"), 4, toout);
-            }
-        } 
-    }
-    else
-    if ( (toget == gensym("massesForces")) && (argc == 1) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->mass[i].forceX);
-            SETFLOAT(&(toout[2]), x->mass[i].forceY);
-            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
-            outlet_anything(x->main_outlet, gensym("massesForces"), 4, toout);
-        } 
-    }
-    else
-    if ( (toget == gensym("massesForcesName")) && (argv[1].a_type == A_FLOAT) )
-    {
-        i = atom_getfloatarg(1, argc, argv);
-        if ( (i>=0) && (i<x->nb_mass) )
-        {
-            SETSYMBOL(&(toout[0]), x->mass[i].Id);
-            SETFLOAT(&(toout[1]), x->mass[i].forceX);
-            SETFLOAT(&(toout[2]), x->mass[i].forceY);
-            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
-            outlet_anything(x->main_outlet, gensym("massesForcesNameNo"), 4, toout);
-        }
-    }
-    else
-    if ( (toget == gensym("massesForcesName")) && (argv[1].a_type == A_SYMBOL) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
-            {
-                SETSYMBOL(&(toout[0]), x->mass[i].Id);
-                SETFLOAT(&(toout[1]), x->mass[i].forceX);
-                SETFLOAT(&(toout[2]), x->mass[i].forceY);
-                SETFLOAT(&(toout[3]), x->mass[i].forceZ);
-                outlet_anything(x->main_outlet, gensym("massesForcesNameId"), 4, toout);
-            }
-        } 
-    }
-    else
-    if ( (toget == gensym("massesForcesName")) && (argc == 1) )
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETSYMBOL(&(toout[0]), x->mass[i].Id);
-            SETFLOAT(&(toout[1]), x->mass[i].forceX);
-            SETFLOAT(&(toout[2]), x->mass[i].forceY);
-            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
-            outlet_anything(x->main_outlet, gensym("massesForcesName"), 4, toout);
-        } 
-    }
-    else
-    if ( (toget == gensym("linksPos")) && (argv[1].a_type == A_FLOAT) )
-    {
-        i = atom_getfloatarg(1, argc, argv);
-        if ( (i>=0) && (i<x->nb_mass) )
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
-            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
-            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
-            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
-            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
-            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
-            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
-        }
-    }
-    else
-    if ( (toget == gensym("linksPos")) && (argv[1].a_type == A_SYMBOL) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(1,argc,argv) == x->link[i].Id)
-            {
-                SETFLOAT(&(toout[0]), i);
-                SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
-                SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
-                SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
-                SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
-                SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
-                SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
-                outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
-            }
-        } 
-    }
-    else
-    if ( (toget == gensym("linksPos")) && (argc == 1) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
-            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
-            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
-            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
-            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
-            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
-            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
-        } 
-    }
-    else
-    if ( (toget == gensym("linksPosName")) && (argv[1].a_type == A_FLOAT) )
-    {
-        i = atom_getfloatarg(1, argc, argv);
-        if ( (i>=0) && (i<x->nb_mass) )
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
-            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
-            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
-            SETFLOAT(&(toout[3]), x->link[i].mass2->posX);
-            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
-            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
-            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
-        }
-    }
-    else
-    if ( (toget == gensym("linksPosName")) && (argv[1].a_type == A_SYMBOL) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            if ( atom_getsymbolarg(1,argc,argv) == x->link[i].Id)
-            {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
-            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
-            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
-            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
-            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
-            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
-            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
-            }
-        } 
-    }
-    else
-    if ( (toget == gensym("linksPosName")) && (argc == 1) )
-    {
-        for (i=0; i< x->nb_link; i++)
-        {
-            SETFLOAT(&(toout[0]), i);
-            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
-            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
-            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
-            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
-            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
-            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
-            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
-        } 
-    }
-    else
-        error("not get attribute");
-}
-
-void pmpd3d_massesPosXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-    
-    if (argc==0) {
-        for (i=0; i < x->nb_mass; i++)
-        {
-            SETFLOAT(&(pos_list[i]),x->mass[i].posX);
-        }
-        outlet_anything(x->main_outlet, gensym("massesPosXL"),x->nb_mass , pos_list);        
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].posX);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesPosXL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posX);
-        outlet_anything(x->main_outlet, gensym("massesPosXL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesForcesXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
- 
-    if (argc==0) {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETFLOAT(&(pos_list[i]),x->mass[i].forceX);
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesXL"),x->nb_mass , pos_list);          
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].forceX);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesXL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceX);
-        outlet_anything(x->main_outlet, gensym("massesForcesXL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesSpeedsXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-	
-    if (argc==0) {
-		for (i=0; i< x->nb_mass; i++)
-		{
-			SETFLOAT(&(pos_list[i]),x->mass[i].speedX);
-		}
-		outlet_anything(x->main_outlet, gensym("massesSpeedsXL"),x->nb_mass , pos_list);         
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].speedX);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesSpeedsXL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedX);
-        outlet_anything(x->main_outlet, gensym("massesSpeedsXL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesPosXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].posX;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-
-                {
-                    vec[i].w_float = x->mass[j].posX;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesSpeedsXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {        
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].speedX;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].speedX;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesForcesXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].forceX;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].forceX;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesPosYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-    
-    if (argc==0) {
-        for (i=0; i < x->nb_mass; i++)
-        {
-            SETFLOAT(&(pos_list[i]),x->mass[i].posY);
-        }
-        outlet_anything(x->main_outlet, gensym("massesPosYL"),x->nb_mass , pos_list);         
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].posY);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesPosYL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posY);
-        outlet_anything(x->main_outlet, gensym("massesPosYL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesForcesYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
- 
-    if (argc==0) {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETFLOAT(&(pos_list[i]),x->mass[i].forceY);
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesYL"),x->nb_mass , pos_list);          
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].forceY);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesYL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceY);
-        outlet_anything(x->main_outlet, gensym("massesForcesYL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesSpeedsYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-	
-    if (argc==0) {
-		for (i=0; i< x->nb_mass; i++)
-		{
-			SETFLOAT(&(pos_list[i]),x->mass[i].speedY);
-		}
-		outlet_anything(x->main_outlet, gensym("massesSpeedsYL"),x->nb_mass , pos_list);         
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].speedY);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesSpeedsYL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedY);
-        outlet_anything(x->main_outlet, gensym("massesSpeedsYL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesPosYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].posY;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].posY;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesSpeedsYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].speedY;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].speedY;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesForcesYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].forceY;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].forceY;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesPosZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-    
-    if (argc==0) {
-        for (i=0; i < x->nb_mass; i++)
-        {
-            SETFLOAT(&(pos_list[i]),x->mass[i].posZ);
-        }
-        outlet_anything(x->main_outlet, gensym("massesPosZL"),x->nb_mass , pos_list);         
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].posZ);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesPosZL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posZ);
-        outlet_anything(x->main_outlet, gensym("massesPosZL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesForcesZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
- 
-    if (argc==0) {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            SETFLOAT(&(pos_list[i]),x->mass[i].forceZ);
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesZL"),x->nb_mass , pos_list);          
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].forceZ);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesZL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceZ);
-        outlet_anything(x->main_outlet, gensym("massesForcesZL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesSpeedsZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-	
-    if (argc==0) {
-		for (i=0; i< x->nb_mass; i++)
-		{
-			SETFLOAT(&(pos_list[i]),x->mass[i].speedZ);
-		}
-		outlet_anything(x->main_outlet, gensym("massesSpeedsZL"),x->nb_mass , pos_list);         
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-                SETFLOAT(&(pos_list[i]),x->mass[i].speedZ);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesSpeedsZL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedZ);
-        outlet_anything(x->main_outlet, gensym("massesSpeedsZL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesPosZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].posZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].posZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesSpeedsZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].speedZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].speedZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesForcesZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->mass[i].forceZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].forceZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesPosL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[3*x->nb_mass];
-    
-    if (argc==0) {
-		for (i=0; i < x->nb_mass; i++)
-		{
-			SETFLOAT(&(pos_list[3*i]  ),x->mass[i].posX);
-			SETFLOAT(&(pos_list[3*i+1]),x->mass[i].posY);
-			SETFLOAT(&(pos_list[3*i+2]),x->mass[i].posZ);
-		}
-		outlet_anything(x->main_outlet, gensym("massesPosL"),3*x->nb_mass , pos_list);       
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-				SETFLOAT(&(pos_list[3*i]  ),x->mass[i].posX);
-				SETFLOAT(&(pos_list[3*i+1]),x->mass[i].posY);
-				SETFLOAT(&(pos_list[3*i+2]),x->mass[i].posZ);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesPosL"),3*i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posX);
-		SETFLOAT(&(pos_list[1]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posY);
-		SETFLOAT(&(pos_list[2]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posZ);
-			
-        outlet_anything(x->main_outlet, gensym("massesPosL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesForcesL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[3*x->nb_mass];
- 
-    if (argc==0) {
-        for (i=0; i< x->nb_mass; i++) {
-        SETFLOAT(&(pos_list[3*i]  ),x->mass[i].forceX);
-        SETFLOAT(&(pos_list[3*i+1]),x->mass[i].forceY);
-        SETFLOAT(&(pos_list[3*i+2]),x->mass[i].forceZ);
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesL"),3*x->nb_mass , pos_list);          
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-				SETFLOAT(&(pos_list[3*i]  ),x->mass[i].forceX);
-				SETFLOAT(&(pos_list[3*i+1]),x->mass[i].forceY);
-				SETFLOAT(&(pos_list[3*i+2]),x->mass[i].forceZ);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesL"),3*i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceX);
-        SETFLOAT(&(pos_list[1]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceY);
-        SETFLOAT(&(pos_list[2]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceZ);
-        
-        outlet_anything(x->main_outlet, gensym("massesForcesZL"),3 , pos_list);        
-    }
-}
-
-void pmpd3d_massesSpeedsL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[3*x->nb_mass];
-	
-    if (argc==0) {
-		for (i=0; i< x->nb_mass; i++) {
-			SETFLOAT(&(pos_list[3*i]  ),x->mass[i].speedX);
-			SETFLOAT(&(pos_list[3*i+1]),x->mass[i].speedY);
-			SETFLOAT(&(pos_list[3*i+2]),x->mass[i].speedZ);
-		}
-		outlet_anything(x->main_outlet, gensym("massesSpeedsL"),3*x->nb_mass , pos_list);         
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-				SETFLOAT(&(pos_list[3*i]  ),x->mass[i].speedX);
-				SETFLOAT(&(pos_list[3*i+1]),x->mass[i].speedY);
-				SETFLOAT(&(pos_list[3*i+2]),x->mass[i].speedZ);
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesSpeedsL"),3*i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedX);
-        SETFLOAT(&(pos_list[1]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedY);
-        SETFLOAT(&(pos_list[2]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedZ);
-        
-        outlet_anything(x->main_outlet, gensym("massesSpeedsL"),3 , pos_list);        
-    }
-}
-
-void pmpd3d_massesPosT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, (vecsize-2)/3);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[3*i  ].w_float = x->mass[i].posX;
-                vec[3*i+1].w_float = x->mass[i].posY;
-                vec[3*i+2].w_float = x->mass[i].posZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize-2) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].posX;
-                    i++;
-                    vec[i].w_float = x->mass[j].posY;
-                    i++;
-                    vec[i].w_float = x->mass[j].posZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesSpeedsT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, (vecsize-2)/3);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[3*i  ].w_float = x->mass[i].speedX;
-                vec[3*i+1].w_float = x->mass[i].speedY;
-                vec[3*i+2].w_float = x->mass[i].speedZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize-2) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].speedX;
-                    i++;
-                    vec[i].w_float = x->mass[j].speedY;
-                    i++;
-                    vec[i].w_float = x->mass[j].speedZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesForcesT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, (vecsize-2)/3);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[3*i  ].w_float = x->mass[i].forceX;
-                vec[3*i+1].w_float = x->mass[i].forceY;
-                vec[3*i+2].w_float = x->mass[i].forceZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize-2) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = x->mass[j].forceX;
-                    i++;
-                    vec[i].w_float = x->mass[j].forceY;
-                    i++;
-                    vec[i].w_float = x->mass[j].forceZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesPosNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-    
-    if (argc==0) {
-		for (i=0; i< x->nb_mass; i++) {
-			SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].posX)+sqr(x->mass[i].posY)+sqr(x->mass[i].posZ)));
-		}
-    outlet_anything(x->main_outlet, gensym("massesPosNormL"),x->nb_mass , pos_list);
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-				SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].posX)+sqr(x->mass[i].posY)+sqr(x->mass[i].posZ)));
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesPosNormL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-		i=(int)atom_getfloatarg(0, argc, argv);
-		SETFLOAT(&(pos_list[0]),sqrt(sqr(x->mass[i].posX)+sqr(x->mass[i].posY)+sqr(x->mass[i].posZ)));
-        outlet_anything(x->main_outlet, gensym("massesPosNormL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesForcesNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{   
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-    
-    if (argc==0) {
-		for (i=0; i< x->nb_mass; i++) {
-			SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].forceX)+sqr(x->mass[i].forceY)+sqr(x->mass[i].forceZ)));
-		}
-    outlet_anything(x->main_outlet, gensym("massesForcesNormL"),x->nb_mass , pos_list);
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-				SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].forceX)+sqr(x->mass[i].forceY)+sqr(x->mass[i].forceZ)));
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesForcesNormL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-		i=(int)atom_getfloatarg(0, argc, argv);
-        SETFLOAT(&(pos_list[0]),sqrt(sqr(x->mass[i].forceX)+sqr(x->mass[i].forceY)+sqr(x->mass[i].forceZ)));
-        outlet_anything(x->main_outlet, gensym("massesForcesNormL"),1 , pos_list);        
-    }
-}
-
-void pmpd3d_massesSpeedsNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i,j;
-    t_atom pos_list[x->nb_mass];
-    
-    if (argc==0) {
-		for (i=0; i< x->nb_mass; i++) {
-			SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].speedX)+sqr(x->mass[i].speedY)+sqr(x->mass[i].speedZ)));
-		}
-    outlet_anything(x->main_outlet, gensym("massesSpeedsNormL"),x->nb_mass , pos_list);
-    }
-    else
-    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
-        i = 0;
-        j = 0;
-        while  (j < x->nb_mass){
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
-				SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].speedX)+sqr(x->mass[i].speedY)+sqr(x->mass[i].speedZ)));
-                i++;
-            }
-        }
-        outlet_anything(x->main_outlet, gensym("massesSpeedsNormL"),i , pos_list);
-    }
-    else 
-    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
-		i=(int)atom_getfloatarg(0, argc, argv);
-        SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].speedX)+sqr(x->mass[i].speedY)+sqr(x->mass[i].speedZ)));
-        outlet_anything(x->main_outlet, gensym("massesSpeedsNormL"),1 , pos_list);        
-    }
-    
-}
-
-void pmpd3d_massesPosNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = sqrt(sqr(x->mass[i].posX)+sqr(x->mass[i].posY)+sqr(x->mass[i].posZ));
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = sqrt(sqr(x->mass[j].posX)+sqr(x->mass[j].posY)+sqr(x->mass[i].posZ));
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesSpeedsNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = sqrt(sqr(x->mass[i].speedX)+sqr(x->mass[i].speedY)+sqr(x->mass[i].speedZ));
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = sqrt(sqr(x->mass[j].speedX)+sqr(x->mass[j].speedY)+sqr(x->mass[i].speedZ));
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesForcesNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_mass;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = sqrt(sqr(x->mass[i].forceX)+sqr(x->mass[i].forceY)+sqr(x->mass[i].forceZ));
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_mass))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
-                {
-                    vec[i].w_float = sqrt(sqr(x->mass[j].forceX)+sqr(x->mass[j].forceY)+sqr(x->mass[i].forceZ));
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_massesPosMean(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_float sommeX, sommeY, sommeZ, somme;
-    t_int i,j;
-    t_atom mean[4];
-
-    sommeX = 0;
-    sommeY = 0;
-    sommeZ = 0;
-    somme = 0;
-    j = 0;
-    
-    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                sommeX += x->mass[i].posX;
-                sommeY += x->mass[i].posY;
-                sommeZ += x->mass[i].posZ;
-                somme +=  sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
-                j++;
-            }
-        }
-    }
-    else
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-                sommeX += x->mass[i].posX;
-                sommeY += x->mass[i].posY;
-                sommeZ += x->mass[i].posZ;
-                somme +=  sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
-                j++;
-        }
-    }    
-    
-    sommeX /= j;
-    sommeY /= j;
-    sommeZ /= j;
-    somme  /= j;    
-    
-    SETFLOAT(&(mean[0]),sommeX);
-    SETFLOAT(&(mean[1]),sommeY);
-    SETFLOAT(&(mean[2]),sommeZ);
-    SETFLOAT(&(mean[3]),somme);
-    
-    outlet_anything(x->main_outlet, gensym("massesPosMean"),4 , mean);
-}
-
-void pmpd3d_massesPosStd(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_float sommeX, sommeY, sommeZ, somme;
-    t_int i,j;
-    t_float stdX, stdY, stdZ, std;
-    t_atom std_out[4];
-
-    sommeX = 0;
-    sommeY = 0;
-    sommeZ = 0;
-    somme  = 0;
-    stdX = 0;
-    stdY = 0;
-    stdZ = 0;
-    std  = 0;
-    j = 0;
-    
-    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                sommeX += x->mass[i].posX;
-                sommeY += x->mass[i].posY;
-                sommeZ += x->mass[i].posZ;
-                somme +=  sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
-                j++;
-            }
-        }
-        sommeX /= j;
-        sommeY /= j;
-        sommeZ /= j;
-        somme /= j;
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                stdX += sqr(x->mass[i].posX-sommeX);
-                stdY += sqr(x->mass[i].posY-sommeY);
-                stdZ += sqr(x->mass[i].posZ-sommeZ);
-                std  +=  sqr(sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ))-somme);
-            }
-        }        
-    }
-    else
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            sommeX += x->mass[i].posX;
-            sommeY += x->mass[i].posY;
-            sommeZ += x->mass[i].posZ;
-            somme +=  sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
-            j++;
-        }
-        sommeX /= j;
-        sommeY /= j;
-        sommeZ /= j;
-        somme /= j;
-        for (i=0; i< x->nb_mass; i++)
-        {
-            stdX += sqr(x->mass[i].posX-sommeX);
-            stdY += sqr(x->mass[i].posY-sommeY);
-            stdZ += sqr(x->mass[i].posZ-sommeZ);
-            std  += sqr(sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ))-somme);
-        }
-    }    
-    
-    stdX = sqrt(stdX/j);
-    stdY = sqrt(stdY/j);
-    stdZ = sqrt(stdZ/j);
-    std  = sqrt(std /j);    
-
-    SETFLOAT(&(std_out[0]),stdX);
-    SETFLOAT(&(std_out[1]),stdY);
-    SETFLOAT(&(std_out[2]),stdZ);
-    SETFLOAT(&(std_out[3]),std);
-    
-    outlet_anything(x->main_outlet, gensym("massesPosStd"),4 , std_out);
-}
-
-void pmpd3d_massesForcesMean(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_float sommeX, sommeY, sommeZ, somme;
-    t_int i,j;
-    t_atom mean[4];
-
-    sommeX = 0;
-    sommeY = 0;
-    sommeZ = 0;
-    somme = 0;
-    j = 0;
-    
-    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                sommeX += x->mass[i].forceX;
-                sommeY += x->mass[i].forceY;
-                sommeZ += x->mass[i].forceZ;
-                somme +=  sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ)); // force total
-                j++;
-            }
-        }
-    }
-    else
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-                sommeX += x->mass[i].forceX;
-                sommeY += x->mass[i].forceY;
-                sommeZ += x->mass[i].forceZ;
-                somme +=  sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ)); // force
-                j++;
-        }
-    }    
-    
-    sommeX /= j;
-    sommeY /= j;
-    sommeZ /= j;
-    somme  /= j;
-
-    SETFLOAT(&(mean[0]),sommeX);
-    SETFLOAT(&(mean[1]),sommeY);
-    SETFLOAT(&(mean[2]),sommeZ);
-    SETFLOAT(&(mean[3]),somme);
-    
-    outlet_anything(x->main_outlet, gensym("massesForcesMean"),4 , mean);
-}
-
-void pmpd3d_massesForcesStd(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_float sommeX, sommeY, sommeZ, somme;
-    t_int i,j;
-    t_float stdX, stdY, stdZ, std;
-    t_atom std_out[4];
-
-    sommeX = 0;
-    sommeY = 0;
-    sommeZ = 0;
-    somme  = 0;
-    stdX = 0;
-    stdY = 0;
-    stdZ = 0;
-    std  = 0;
-    j = 0;
-    
-    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                sommeX += x->mass[i].forceX;
-                sommeY += x->mass[i].forceY;
-                sommeZ += x->mass[i].forceZ;
-                somme +=  sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ)); // force
-                j++;
-            }
-        }
-        sommeX /= j;
-        sommeY /= j;
-        sommeZ /= j;
-        somme /= j;
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                stdX += sqr(x->mass[i].forceX-sommeX);
-                stdY += sqr(x->mass[i].forceY-sommeY);
-                stdZ += sqr(x->mass[i].forceZ-sommeZ);
-                std  +=  sqr(sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ))-somme);
-            }
-        }        
-    }
-    else
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            sommeX += x->mass[i].forceX;
-            sommeY += x->mass[i].forceY;
-            sommeZ += x->mass[i].forceZ;
-            somme +=  sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ)); 
-            j++;
-        }
-        sommeX /= j;
-        sommeY /= j;
-        sommeZ /= j;
-        somme /= j;
-        for (i=0; i< x->nb_mass; i++)
-        {
-            stdX += sqr(x->mass[i].forceX-sommeX);
-            stdY += sqr(x->mass[i].forceY-sommeY);
-            stdZ += sqr(x->mass[i].forceZ-sommeZ);
-            std  += sqr(sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ))-somme);
-        }
-    }    
-    
-    stdX = sqrt(stdX/j);
-    stdY = sqrt(stdY/j);
-    stdZ = sqrt(stdZ/j);
-    std  = sqrt(std /j);    
-
-    SETFLOAT(&(std_out[0]),stdX);
-    SETFLOAT(&(std_out[1]),stdY);
-    SETFLOAT(&(std_out[2]),stdZ);
-    SETFLOAT(&(std_out[3]),std);
-    
-    outlet_anything(x->main_outlet, gensym("massesForcesStd"),4 , std_out);
-}
-
-void pmpd3d_massesSpeedsMean(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_float sommeX, sommeY, sommeZ, somme;
-    t_int i,j;
-    t_atom mean[4];
-
-    sommeX = 0;
-    sommeY = 0;
-    sommeZ = 0;
-    somme = 0;
-    j = 0;
-    
-    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                sommeX += x->mass[i].speedX;
-                sommeY += x->mass[i].speedY;
-                sommeZ += x->mass[i].speedZ;
-                somme +=  sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ)); // speed total
-                j++;
-            }
-        }
-    }
-    else
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-                sommeX += x->mass[i].speedX;
-                sommeY += x->mass[i].speedY;
-                sommeZ += x->mass[i].speedZ;
-                somme +=  sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ)); // speed
-                j++;
-        }
-    }    
-    
-    sommeX /= j;
-    sommeY /= j;
-    sommeZ /= j;
-    somme  /= j;
-
-    SETFLOAT(&(mean[0]),sommeX);
-    SETFLOAT(&(mean[1]),sommeY);
-    SETFLOAT(&(mean[2]),sommeZ);
-    SETFLOAT(&(mean[3]),somme);
-    
-    outlet_anything(x->main_outlet, gensym("massesSpeedsMean"),4 , mean);
-}
-
-void pmpd3d_massesSpeedsStd(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_float sommeX, sommeY, sommeZ, somme;
-    t_int i,j;
-    t_float stdX, stdY, stdZ, std;
-    t_atom std_out[4];
-
-    sommeX = 0;
-    sommeY = 0;
-    sommeZ = 0;
-    somme  = 0;
-    stdX = 0;
-    stdY = 0;
-    stdZ = 0;
-    std  = 0;
-    j = 0;
-    
-    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                sommeX += x->mass[i].speedX;
-                sommeY += x->mass[i].speedY;
-                sommeZ += x->mass[i].speedZ;
-                somme +=  sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ)); // speed
-                j++;
-            }
-        }
-        sommeX /= j;
-        sommeY /= j;
-        sommeZ /= j;
-        somme /= j;
-        for (i=0; i< x->nb_mass; i++)
-        {
-            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
-            { 
-                stdX += sqr(x->mass[i].speedX-sommeX);
-                stdY += sqr(x->mass[i].speedY-sommeY);
-                stdZ += sqr(x->mass[i].speedZ-sommeZ);
-                std  +=  sqr(sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ))-somme);
-            }
-        }        
-    }
-    else
-    {
-        for (i=0; i< x->nb_mass; i++)
-        {
-            sommeX += x->mass[i].speedX;
-            sommeY += x->mass[i].speedY;
-            sommeZ += x->mass[i].speedZ;
-            somme +=  sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ)); 
-            j++;
-        }
-        sommeX /= j;
-        sommeY /= j;
-        sommeZ /= j;
-        somme /= j;
-        for (i=0; i< x->nb_mass; i++)
-        {
-            stdX += sqr(x->mass[i].speedX-sommeX);
-            stdY += sqr(x->mass[i].speedY-sommeY);
-            stdZ += sqr(x->mass[i].speedZ-sommeZ);
-            std  += sqr(sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ))-somme);
-        }
-    }    
-    
-    stdX = sqrt(stdX/j);
-    stdY = sqrt(stdY/j);
-    stdZ = sqrt(stdZ/j);
-    std  = sqrt(std /j);    
-
-    SETFLOAT(&(std_out[0]),stdX);
-    SETFLOAT(&(std_out[1]),stdY);
-    SETFLOAT(&(std_out[2]),stdZ);
-    SETFLOAT(&(std_out[3]),std);
-    
-    outlet_anything(x->main_outlet, gensym("massesSpeedsStd"),4 , std_out);
-}
-
-// --------------------------------------------
-
-void pmpd3d_linksPosXL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),(x->link[i].mass1->posX + x->link[i].mass2->posX)/2);
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosXL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthXL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),x->link[i].mass2->posX - x->link[i].mass1->posX);
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthXL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosSpeedXL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),(x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2);
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosSpeedXL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthSpeedXL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),x->link[i].mass2->speedX - x->link[i].mass1->speedX);
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthSpeedXL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = (x->link[i].mass1->posX + x->link[i].mass2->posX)/2;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = (x->link[j].mass1->posX + x->link[j].mass2->posX)/2;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->link[i].mass2->posX - x->link[i].mass1->posX;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass2->posX - x->link[j].mass1->posX;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosSpeedXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = (x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = (x->link[j].mass1->speedX + x->link[j].mass2->speedX)/2;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthSpeedXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->link[i].mass2->speedX - x->link[i].mass1->speedX;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass2->speedX - x->link[j].mass1->speedX;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosYL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),(x->link[i].mass1->posY + x->link[i].mass2->posY)/2);
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosYL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthYL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),x->link[i].mass2->posY - x->link[i].mass1->posY);
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthYL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosSpeedYL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),(x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2);
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosSpeedYL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthSpeedYL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),x->link[i].mass2->speedY - x->link[i].mass1->speedY);
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthSpeedYL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = (x->link[i].mass1->posY + x->link[i].mass2->posY)/2;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = (x->link[j].mass1->posY + x->link[j].mass2->posY)/2;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->link[i].mass2->posY - x->link[i].mass1->posY;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass2->posY - x->link[j].mass1->posY;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosSpeedYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = (x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = (x->link[j].mass1->speedY + x->link[j].mass2->speedY)/2;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthSpeedYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->link[i].mass2->speedY - x->link[i].mass1->speedY;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass2->speedY - x->link[j].mass1->speedY;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosZL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),(x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2);
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosZL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthZL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),x->link[i].mass2->posZ - x->link[i].mass1->posZ);
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthZL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosSpeedZL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),(x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2);
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosSpeedZL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthSpeedZL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),x->link[i].mass2->speedZ - x->link[i].mass1->speedZ);
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthSpeedZL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = (x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = (x->link[j].mass1->posZ + x->link[j].mass2->posZ)/2;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->link[i].mass2->posZ - x->link[i].mass1->posZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass2->posZ - x->link[j].mass1->posZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosSpeedZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = (x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = (x->link[j].mass1->speedZ + x->link[j].mass2->speedZ)/2;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthSpeedZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = x->link[i].mass2->speedZ - x->link[i].mass1->speedZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass2->speedZ - x->link[j].mass1->speedZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[3*x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[3*i]  ),(x->link[i].mass2->posX + x->link[i].mass1->posX)/2);
-        SETFLOAT(&(pos_list[3*i+1]),(x->link[i].mass2->posY + x->link[i].mass1->posY)/2);
-        SETFLOAT(&(pos_list[3*i+2]),(x->link[i].mass2->posZ + x->link[i].mass1->posZ)/2);
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosL"),3*x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[3*x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[3*i]  ),x->link[i].mass2->posX - x->link[i].mass1->posX);
-        SETFLOAT(&(pos_list[3*i+1]),x->link[i].mass2->posY - x->link[i].mass1->posY);
-        SETFLOAT(&(pos_list[3*i+2]),x->link[i].mass2->posZ - x->link[i].mass1->posZ);
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthL"),3*x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosSpeedL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[3*x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[3*i]  ),(x->link[i].mass2->speedX + x->link[i].mass1->speedX)/2);
-        SETFLOAT(&(pos_list[3*i+1]),(x->link[i].mass2->speedY + x->link[i].mass1->speedY)/2);
-        SETFLOAT(&(pos_list[3*i+2]),(x->link[i].mass2->speedZ + x->link[i].mass1->speedZ)/2);
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosSpeedL"),3*x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthSpeedL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[3*x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[3*i]  ),x->link[i].mass2->speedX - x->link[i].mass1->speedX);
-        SETFLOAT(&(pos_list[3*i+1]),x->link[i].mass2->speedY - x->link[i].mass1->speedY);
-        SETFLOAT(&(pos_list[3*i+2]),x->link[i].mass2->speedZ - x->link[i].mass1->speedZ);
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthSpeedL"),3*x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, (vecsize-2)/3);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[3*i  ].w_float = (x->link[i].mass2->posX + x->link[i].mass1->posX)/2;
-                vec[3*i+1].w_float = (x->link[i].mass2->posY + x->link[i].mass1->posY)/2;
-                vec[3*i+2].w_float = (x->link[i].mass2->posZ + x->link[i].mass1->posZ)/2;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize-2) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = (x->link[j].mass2->posX + x->link[j].mass1->posX)/2;
-                    i++;
-                    vec[i].w_float = (x->link[j].mass2->posY + x->link[j].mass1->posY)/2;
-                    i++;
-                    vec[i].w_float = (x->link[j].mass2->posZ + x->link[j].mass1->posZ)/2;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, (vecsize-2)/3);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[3*i  ].w_float = x->link[i].mass2->posX - x->link[i].mass1->posX;
-                vec[3*i+1].w_float = x->link[i].mass2->posY - x->link[i].mass1->posY;
-                vec[3*i+2].w_float = x->link[i].mass2->posZ - x->link[i].mass1->posZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize-2) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass2->posX + x->link[j].mass1->posX;
-                    i++;
-                    vec[i].w_float = x->link[j].mass2->posY + x->link[j].mass1->posY;
-                    i++;
-                    vec[i].w_float = x->link[j].mass2->posZ + x->link[j].mass1->posZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosSpeedT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, (vecsize-2)/3);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[3*i  ].w_float = (x->link[i].mass2->speedX + x->link[i].mass1->speedX)/2;
-                vec[3*i+1].w_float = (x->link[i].mass2->speedY + x->link[i].mass1->speedY)/2;
-                vec[3*i+2].w_float = (x->link[i].mass2->speedZ + x->link[i].mass1->speedZ)/2;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize-2) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = (x->link[j].mass2->speedX + x->link[j].mass1->speedX)/2;
-                    i++;
-                    vec[i].w_float = (x->link[j].mass2->speedY + x->link[j].mass1->speedY)/2;
-                    i++;
-                    vec[i].w_float = (x->link[j].mass2->speedZ + x->link[j].mass1->speedZ)/2;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthSpeedT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, (vecsize-2)/3);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[3*i  ].w_float = x->link[i].mass2->speedX - x->link[i].mass1->speedX;
-                vec[3*i+1].w_float = x->link[i].mass2->speedY - x->link[i].mass1->speedY;
-                vec[3*i+2].w_float = x->link[i].mass2->speedZ - x->link[i].mass1->speedZ;
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize-2) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass2->speedX + x->link[j].mass1->speedX;
-                    i++;
-                    vec[i].w_float = x->link[j].mass2->speedY + x->link[j].mass1->speedY;
-                    i++;
-                    vec[i].w_float = x->link[j].mass2->speedZ + x->link[j].mass1->speedZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosNormL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),sqrt( \
-                            sqr((x->link[i].mass1->posX + x->link[i].mass2->posX)/2) + \
-                            sqr((x->link[i].mass1->posY + x->link[i].mass2->posY)/2) + \
-                            sqr((x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2) ));
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosNormL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthNormL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),sqrt( \
-                            sqr(x->link[i].mass2->posX - x->link[i].mass1->posX) + \
-                            sqr(x->link[i].mass2->posY - x->link[i].mass1->posY) + \
-                            sqr(x->link[i].mass2->posZ - x->link[i].mass1->posZ) ));
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthNormL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosSpeedNormL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),sqrt( \
-                            sqr((x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2) + \
-                            sqr((x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2) + \
-                            sqr((x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2) ));
-    }
-    outlet_anything(x->main_outlet, gensym("linksPosSpeedNormL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksLengthSpeedNormL(t_pmpd3d *x)
-{
-    int i;
-    t_atom pos_list[x->nb_link];
-
-    for (i=0; i < x->nb_link; i++)
-    {
-        SETFLOAT(&(pos_list[i]),sqrt( \
-                            sqr(x->link[i].mass2->speedX - x->link[i].mass1->speedX) + \
-                            sqr(x->link[i].mass2->speedY - x->link[i].mass1->speedY) + \
-                            sqr(x->link[i].mass2->speedZ - x->link[i].mass1->speedZ) ));
-    }
-    outlet_anything(x->main_outlet, gensym("linksLengthSpeedNormL"),x->nb_link , pos_list);
-}
-
-void pmpd3d_linksPosNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = sqrt( \
-                            sqr((x->link[i].mass1->posX + x->link[i].mass2->posX)/2) + \
-                            sqr((x->link[i].mass1->posY + x->link[i].mass2->posY)/2) + \
-                            sqr((x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2) );
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[j].w_float = sqrt( \
-                            sqr((x->link[j].mass1->posX + x->link[j].mass2->posX)/2) + \
-                            sqr((x->link[j].mass1->posY + x->link[j].mass2->posY)/2) + \
-                            sqr((x->link[j].mass1->posZ + x->link[j].mass2->posZ)/2) );
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = sqrt( \
-                            sqr(x->link[i].mass2->posX - x->link[i].mass1->posX) + \
-                            sqr(x->link[i].mass2->posY - x->link[i].mass1->posY) + \
-                            sqr(x->link[i].mass2->posZ - x->link[i].mass1->posZ) );
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = sqrt( \
-                            sqr(x->link[j].mass2->posX - x->link[j].mass1->posX) + \
-                            sqr(x->link[j].mass2->posY - x->link[j].mass1->posY) + \
-                            sqr(x->link[j].mass2->posZ - x->link[j].mass1->posZ) );
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksPosSpeedNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = sqrt( \
-                            sqr((x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2) + \
-                            sqr((x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2) + \
-                            sqr((x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2) );
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = sqrt( \
-                            sqr((x->link[j].mass1->speedX + x->link[j].mass2->speedX)/2) + \
-                            sqr((x->link[j].mass1->speedY + x->link[j].mass2->speedY)/2) + \
-                            sqr((x->link[j].mass1->speedZ + x->link[j].mass2->speedZ)/2) );
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksLengthSpeedNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, vecsize);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[i].w_float = sqrt( \
-                            sqr(x->link[i].mass2->speedX - x->link[i].mass1->speedX) + \
-                            sqr(x->link[i].mass2->speedY - x->link[i].mass1->speedY) + \
-                            sqr(x->link[i].mass2->speedZ - x->link[i].mass1->speedZ) );
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = sqrt( \
-                            sqr(x->link[j].mass2->speedX - x->link[j].mass1->speedX) + \
-                            sqr(x->link[j].mass2->speedY - x->link[j].mass1->speedY) + \
-                            sqr(x->link[j].mass2->speedZ - x->link[j].mass1->speedZ) );
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-void pmpd3d_linksEndT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    int i, j, vecsize;
-    t_garray *a;
-    t_word *vec;
-    
-    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {
-            int taille_max = x->nb_link;
-            taille_max = min(taille_max, (vecsize-5)/6);
-            for (i=0; i < taille_max ; i++)
-            {
-                vec[6*i  ].w_float = x->link[i].mass1->posX;
-                vec[6*i+1].w_float = x->link[i].mass1->posY;
-                vec[6*i+2].w_float = x->link[i].mass1->posZ;
-                vec[6*i+3].w_float = x->link[i].mass2->posX;
-                vec[6*i+4].w_float = x->link[i].mass2->posY;
-                vec[6*i+5].w_float = x->link[i].mass2->posZ;
-                
-            }
-            garray_redraw(a);
-        }
-    }
-    else 
-    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
-    {
-        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
-        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
-            pd_error(x, "%s: no such array", tab_name->s_name);
-        else if (!garray_getfloatwords(a, &vecsize, &vec))
-            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
-        else
-        {    
-            i = 0;
-            j = 0;
-            while ((i < vecsize-6) && (j < x->nb_link))
-            {
-                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
-                {
-                    vec[i].w_float = x->link[j].mass1->posX;
-                    i++;
-                    vec[i].w_float = x->link[j].mass1->posY;
-                    i++;
-                    vec[i].w_float = x->link[j].mass1->posZ;
-                    i++;
-                    vec[i].w_float = x->link[j].mass2->posX;
-                    i++;
-                    vec[i].w_float = x->link[j].mass2->posY;
-                    i++;
-                    vec[i].w_float = x->link[j].mass2->posZ;
-                    i++;
-                }
-                j++;
-            }
-            garray_redraw(a);
-        }
-    }
-}
-
-
-//----------------------------------------------
-
-void pmpd3d_grabMass(t_pmpd3d *x, t_float posX, t_float posY, t_float posZ, t_float grab)
-{
-    t_float dist, tmp;
-    t_int i;
-    
-    if (grab == 0)
-        x->grab=0;
-    if ((x->grab == 0)&(grab == 1)&(x->nb_mass > 0))
-    {
-        x->grab=1;
-        x->grab_nb= 0;
-        dist = sqr(x->mass[0].posX - posX) + sqr(x->mass[0].posY - posY) + sqr(x->mass[0].posZ - posZ);
-        for (i=1; i<x->nb_mass; i++)
-        {
-            tmp = sqr(x->mass[i].posX - posX) + sqr(x->mass[i].posY - posY) + sqr(x->mass[i].posZ - posZ);
-            if (tmp < dist)
-            {
-                dist = tmp;
-                x->grab_nb= i;
-            }
-        }
-    }
-    if (x->grab == 1)
-    {
-        x->mass[x->grab_nb].posX = posX;
-        x->mass[x->grab_nb].posY = posY;        
-        x->mass[x->grab_nb].posZ = posZ;        
-    }
-}
-
-void pmpd3d_closestMass(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
-{
-    t_float dist, tmp;
-    t_int i;
-    t_atom std_out[4];
-
-    t_float posX, posY, posZ;
-    posX = atom_getfloatarg(0, argc, argv);
-    posY = atom_getfloatarg(1, argc, argv);    
-    posZ = atom_getfloatarg(2, argc, argv);    
-    if ( (argc == 4)  && (argv[3].a_type == A_SYMBOL) )
-    {
-        //t_symbol *mass_name = atom_getsymbolarg(2, argc, argv);
-        if ((x->nb_mass > 0))
-        {
-            dist = 1000000000;//sqr(x->mass[0].posX - posX) + sqr(x->mass[0].posY - posY);
-            for (i=0; i<x->nb_mass; i++)
-            {
-                if (atom_getsymbolarg(3,argc,argv) == x->mass[i].Id)
-                {
-                    tmp = sqr(x->mass[i].posX - posX) + sqr(x->mass[i].posY - posY) + sqr(x->mass[i].posZ - posZ);
-                    if (tmp < dist)
-                    {
-                        dist = tmp;
-                        x->grab_nb= i;
-                    }
-                }
-            }
-        }
-    }
-    else {
-        if ((x->nb_mass > 0))
-        {
-            dist = sqr(x->mass[0].posX - posX) + sqr(x->mass[0].posY - posY) + sqr(x->mass[0].posZ - posZ);
-            for (i=1; i<x->nb_mass; i++)
-            {
-                tmp = sqr(x->mass[i].posX - posX) + sqr(x->mass[i].posY - posY) + sqr(x->mass[i].posZ - posZ);
-                if (tmp < dist)
-                {
-                    dist = tmp;
-                    x->grab_nb= i;
-                }
-            }
-        }
-    }
-    
-    SETFLOAT(&(std_out[0]),x->grab_nb);
-    SETFLOAT(&(std_out[1]), x->mass[x->grab_nb].posX);
-    SETFLOAT(&(std_out[2]), x->mass[x->grab_nb].posY);
-    SETFLOAT(&(std_out[3]), x->mass[x->grab_nb].posZ);
-    outlet_anything(x->main_outlet, gensym("closestMass"),4,std_out);
-    
-}
-
-void *pmpd3d_new()
-{
-    t_pmpd3d *x = (t_pmpd3d *)pd_new(pmpd3d_class);
-
-    pmpd3d_reset(x);
-    
-    x->main_outlet=outlet_new(&x->x_obj, 0);
-    // x->info_outlet=outlet_new(&x->x_obj, 0); // TODO
-
-    return (void *)x;
-}
-
-void pmpd3d_setup(void) 
-{
- pmpd3d_class = class_new(gensym("pmpd3d"),
-        (t_newmethod)pmpd3d_new,
-        0, sizeof(t_pmpd3d),CLASS_DEFAULT, 0);
-
-    class_addbang(pmpd3d_class, pmpd3d_bang);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_reset,           gensym("reset"), 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_infosL,          gensym("infosL"), 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_infosL,          gensym("print"), 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_mass,            gensym("mass"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_link,            gensym("link"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_tabLink,         gensym("tabLink"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_tLink,           gensym("tLink"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setK,            gensym("setK"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setD,            gensym("setD"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setL,            gensym("setL"), A_GIMME, 0);
-//    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setL,            gensym("adaptLength"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setLKTab,        gensym("setLKTab"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setLDTab,        gensym("setLDTab"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setLinkId,       gensym("setLinkId"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setMassId,       gensym("setMassId"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_pos,             gensym("pos"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_posX,            gensym("posX"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_posY,            gensym("posY"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_posZ,            gensym("posZ"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_force,           gensym("force"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceX,          gensym("forceX"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceY,          gensym("forceY"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_forceZ,          gensym("forceZ"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_minX,            gensym("Xmin"), A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxX,            gensym("Xmax"), A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_minY,            gensym("Ymin"), A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxY,            gensym("Ymax"), A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_minZ,            gensym("Zmin"), A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_maxZ,            gensym("Zmax"), A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_min,             gensym("min"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_max,             gensym("max"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setFixed,        gensym("setFixed"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setMobile,       gensym("setMobile"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setD2,           gensym("setDEnv"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setD2offset,     gensym("setDEnvOffset"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeed,        gensym("setSpeed"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedX,       gensym("setSpeedX"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedY,       gensym("setSpeedY"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setSpeedZ,       gensym("setSpeedZ"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForce,        gensym("setForce"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceX,       gensym("setForceX"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceY,       gensym("setForceY"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_setForceZ,       gensym("setForceZ"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPos,          gensym("addPos"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosX,         gensym("addPosX"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosY,         gensym("addPosY"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_addPosZ,         gensym("addPosZ"), A_GIMME, 0);
-
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_get,             gensym("get"), A_GIMME, 0);
-    
-//    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosL,      gensym("massesPos"), A_GIMME);
-//    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsL,   gensym("massesSpeeds"), A_GIMME);
-//    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesL,   gensym("massesForces"), A_GIMME);
-//    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosL,      gensym("linksPos"), A_GIMME);
-
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosL,      gensym("massesPosL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsL,   gensym("massesSpeedsL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesL,   gensym("massesForcesL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosT,      gensym("massesPosT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsT,   gensym("massesSpeedsT"),A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesT,   gensym("massesForcesT"),A_GIMME, 0);
-    
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosXL,     gensym("massesPosXL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsXL,  gensym("massesSpeedsXL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesXL,  gensym("massesForcesXL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosXT,     gensym("massesPosXT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsXT,  gensym("massesSpeedsXT"),A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesXT,  gensym("massesForcesXT"),A_GIMME, 0);
-    
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosYL,     gensym("massesPosYL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsYL,  gensym("massesSpeedsYL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesYL,  gensym("massesForcesYL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosYT,     gensym("massesPosYT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsYT,  gensym("massesSpeedsYT"),A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesYT,  gensym("massesForcesYT"),A_GIMME, 0);
-        
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosZL,     gensym("massesPosZL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsZL,  gensym("massesSpeedsZL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesZL,  gensym("massesForcesZL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosZT,     gensym("massesPosZT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsZT,  gensym("massesSpeedsZT"),A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesZT,  gensym("massesForcesZT"),A_GIMME, 0);
-
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosNormL,      gensym("massesPosNormL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsNormL,   gensym("massesSpeedsNormL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesNormL,   gensym("massesForcesNormL"), A_GIMME);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosNormT,      gensym("massesPosNormT"),  A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsNormT,   gensym("massesSpeedsNormT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesNormT,   gensym("massesForcesNormT"), A_GIMME, 0);
-    
+// pmpd3d_stat
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosMean,       gensym("massesPosMean"), A_GIMME, 0);
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesPosStd,        gensym("massesPosStd"),A_GIMME, 0);
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesMean,    gensym("massesForecesMean"), A_GIMME, 0);
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesForcesStd,     gensym("massesForcesStd"),A_GIMME, 0);    
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsMean,    gensym("massesSpeedsMean"), A_GIMME, 0);
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_massesSpeedsStd,     gensym("massesSpeedsStd"),A_GIMME, 0);
-    
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosXL,               gensym("linksPosXL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthXL,            gensym("linksLengthXL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedXL,          gensym("linksPosSpeedXL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedXL,       gensym("linksLengthSpeedXL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosXT,               gensym("linksPosXT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthXT,       	 gensym("linksLengthXT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedXT,      	 gensym("linksPosSpeedXT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedXT,       gensym("linksLengthSpeedXT"), A_GIMME, 0);
-    
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosYL,               gensym("linksPosYL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthYL,            gensym("linksLengthYL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedYL,          gensym("linksPosSpeedYL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedYL,       gensym("linksLengthSpeedYL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosYT,               gensym("linksPosYT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthYT,            gensym("linksLengthYT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedYT,          gensym("linksPosSpeedYT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedYT,       gensym("linksLengthSpeedYT"), A_GIMME, 0);
-
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosZL,               gensym("linksPosZL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthZL,            gensym("linksLengthZL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedZL,          gensym("linksPosSpeedZL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedZL,       gensym("linksLengthSpeedZL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosZT,               gensym("linksPosZT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthZT,            gensym("linksLengthZT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedZT,          gensym("linksPosSpeedZT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedZT,       gensym("linksLengthSpeedZT"), A_GIMME, 0);
-    
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosL,               gensym("linksPosL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthL,            gensym("linksLengthL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedL,          gensym("linksPosSpeedL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedL,       gensym("linksLengthSpeedL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosT,               gensym("linksPosT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthT,            gensym("linksLengthT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedT,          gensym("linksPosSpeedT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedT,       gensym("linksLengthSpeedT"), A_GIMME, 0);
-
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosNormL,               gensym("linksPosNormL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthNormL,            gensym("linksLengthNormL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedNormL,          gensym("linksPosSpeedNormL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedNormL,       gensym("linksLengthSpeedNormL"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosNormT,               gensym("linksPosNormT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthNormT,            gensym("linksLengthNormT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedNormT,          gensym("linksPosSpeedNormT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedNormT,       gensym("linksLengthSpeedNormT"), A_GIMME, 0);
-    
-
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEndT,               gensym("linksEndT"),   A_GIMME, 0);
-/*    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd1T,               gensym("linksEnd1T"),  A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd2T,              gensym("linksEnd2T"),  A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEndXT,              gensym("linksEndXT"),  A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd1XT,             gensym("linksEnd1XT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd2XT,             gensym("linksEnd2XT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEndYT,              gensym("linksEndYT"),  A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd1YT,             gensym("linksEnd1YT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd2YT,             gensym("linksEnd2YT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEndZT,              gensym("linksEndZT"),  A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd1ZT,             gensym("linksEnd1ZT"), A_GIMME, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksEnd2ZT,             gensym("linksEnd2ZT"), A_GIMME, 0);
-*/    
-
 /*    class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosMean,           gensym("linksPosMean"), A_GIMME, 0);
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthMean,          gensym("linksLengthMean"), A_GIMME, 0);
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedMean,        gensym("linksPosSpeedMean"), A_GIMME, 0);
@@ -5027,9 +704,6 @@ void pmpd3d_setup(void)
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksPosSpeedStd,         gensym("linksPosSpeedStd"), A_GIMME, 0);
     class_addmethod(pmpd3d_class, (t_method)pmpd3d_linksLengthSpeedStd0,     gensym("linksLengthSpeedStd"), A_GIMME, 0);
 */
-
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_grabMass,            gensym("grabMass"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
-    class_addmethod(pmpd3d_class, (t_method)pmpd3d_closestMass,         gensym("closestMass"), A_GIMME, 0);
-
+    
 }
 
diff --git a/pmpd3d_get.c b/pmpd3d_get.c
new file mode 100644
index 0000000..ba6fdb7
--- /dev/null
+++ b/pmpd3d_get.c
@@ -0,0 +1,591 @@
+void pmpd3d_get(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i;
+    t_symbol *toget; 
+    t_atom  toout[7];
+    toget = atom_getsymbolarg(0, argc, argv);
+
+    if ( (toget == gensym("massesPos")) && (argv[1].a_type == A_FLOAT) )
+    {
+        i = atom_getfloatarg(1, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].posX);
+            SETFLOAT(&(toout[2]), x->mass[i].posY);
+            SETFLOAT(&(toout[3]), x->mass[i].posZ);
+            outlet_anything(x->main_outlet, gensym("massesPosNo"), 4, toout);
+        }  
+    }
+    else
+    if ( (toget == gensym("massesPos")) && (argv[1].a_type == A_SYMBOL) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+            {
+                SETFLOAT(&(toout[0]), i);
+                SETFLOAT(&(toout[1]), x->mass[i].posX);
+                SETFLOAT(&(toout[2]), x->mass[i].posY);
+                SETFLOAT(&(toout[3]), x->mass[i].posZ);
+                outlet_anything(x->main_outlet, gensym("massesPosId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if ( (toget == gensym("massesPos")) && (argc == 1) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].posX);
+            SETFLOAT(&(toout[2]), x->mass[i].posY);
+            SETFLOAT(&(toout[3]), x->mass[i].posZ);
+            outlet_anything(x->main_outlet, gensym("massesPos"), 4, toout);
+        } 
+    }
+    else
+    if ( (toget == gensym("massesPosName")) && (argv[1].a_type == A_FLOAT) )
+    {
+        i = atom_getfloatarg(1, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETSYMBOL(&(toout[0]), x->mass[i].Id);
+            SETFLOAT(&(toout[1]), x->mass[i].posX);
+            SETFLOAT(&(toout[2]), x->mass[i].posY);
+            SETFLOAT(&(toout[3]), x->mass[i].posZ);
+            outlet_anything(x->main_outlet, gensym("massesPosNameNo"), 4, toout);
+        }  
+    }
+    else
+    if ( (toget == gensym("massesPosName")) && (argv[1].a_type == A_SYMBOL) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+            {
+                SETSYMBOL(&(toout[0]), x->mass[i].Id);
+                SETFLOAT(&(toout[1]), x->mass[i].posX);
+                SETFLOAT(&(toout[2]), x->mass[i].posY);
+                SETFLOAT(&(toout[3]), x->mass[i].posZ);
+                outlet_anything(x->main_outlet, gensym("massesPosNameId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if ( (toget == gensym("massesPosName")) && (argc == 1) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETSYMBOL(&(toout[0]), x->mass[i].Id);
+            SETFLOAT(&(toout[1]), x->mass[i].posX);
+            SETFLOAT(&(toout[2]), x->mass[i].posY);
+            SETFLOAT(&(toout[3]), x->mass[i].posZ);
+            outlet_anything(x->main_outlet, gensym("massesPosName"), 4, toout);
+        } 
+    }
+    else
+    if ( (toget == gensym("massesSpeeds")) && (argv[1].a_type == A_FLOAT) )
+    {
+        i = atom_getfloatarg(1, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].speedX);
+            SETFLOAT(&(toout[2]), x->mass[i].speedY);
+            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+            outlet_anything(x->main_outlet, gensym("massesSpeedsNo"), 4, toout);
+        }  
+    }
+    else
+    if ( (toget == gensym("massesSpeeds")) && (argv[1].a_type == A_SYMBOL) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+            {
+                SETFLOAT(&(toout[0]), i);
+                SETFLOAT(&(toout[1]), x->mass[i].speedX);
+                SETFLOAT(&(toout[2]), x->mass[i].speedY);
+                SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+                outlet_anything(x->main_outlet, gensym("massesSpeedsId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if ( (toget == gensym("massesSpeeds")) && (argc == 1) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].speedX);
+            SETFLOAT(&(toout[2]), x->mass[i].speedY);
+            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+            outlet_anything(x->main_outlet, gensym("massesSpeeds"), 4, toout);
+        } 
+    }
+    else
+    if ( (toget == gensym("massesSpeedsName")) && (argv[1].a_type == A_FLOAT) )
+    {
+        i = atom_getfloatarg(1, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETSYMBOL(&(toout[0]), x->mass[i].Id);
+            SETFLOAT(&(toout[1]), x->mass[i].speedX);
+            SETFLOAT(&(toout[2]), x->mass[i].speedY);
+            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+            outlet_anything(x->main_outlet, gensym("massesSpeedsNameNo"), 4, toout);
+        }  
+    }
+    else
+    if ( (toget == gensym("massesSpeedsName")) && (argv[1].a_type == A_SYMBOL) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+            {
+                SETSYMBOL(&(toout[0]), x->mass[i].Id);
+                SETFLOAT(&(toout[1]), x->mass[i].speedX);
+                SETFLOAT(&(toout[2]), x->mass[i].speedY);
+                SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+                outlet_anything(x->main_outlet, gensym("massesSpeedsNameId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if ( (toget == gensym("massesSpeedsName")) && (argc == 1) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETSYMBOL(&(toout[0]), x->mass[i].Id);
+            SETFLOAT(&(toout[1]), x->mass[i].speedX);
+            SETFLOAT(&(toout[2]), x->mass[i].speedY);
+            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+            outlet_anything(x->main_outlet, gensym("massesSpeedsName"), 4, toout);
+        } 
+    }
+    else
+    if ( (toget == gensym("massesForces")) && (argv[1].a_type == A_FLOAT) )
+    {
+        i = atom_getfloatarg(1, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].forceX);
+            SETFLOAT(&(toout[2]), x->mass[i].forceY);
+            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+            outlet_anything(x->main_outlet, gensym("massesForcesNo"), 4, toout);
+        }  
+    }
+    else
+    if ( (toget == gensym("massesForces")) && (argv[1].a_type == A_SYMBOL) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+            {
+                SETFLOAT(&(toout[0]), i);
+                SETFLOAT(&(toout[1]), x->mass[i].forceX);
+                SETFLOAT(&(toout[2]), x->mass[i].forceY);
+                SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+                outlet_anything(x->main_outlet, gensym("massesForcesId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if ( (toget == gensym("massesForces")) && (argc == 1) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].forceX);
+            SETFLOAT(&(toout[2]), x->mass[i].forceY);
+            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+            outlet_anything(x->main_outlet, gensym("massesForces"), 4, toout);
+        } 
+    }
+    else
+    if ( (toget == gensym("massesForcesName")) && (argv[1].a_type == A_FLOAT) )
+    {
+        i = atom_getfloatarg(1, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETSYMBOL(&(toout[0]), x->mass[i].Id);
+            SETFLOAT(&(toout[1]), x->mass[i].forceX);
+            SETFLOAT(&(toout[2]), x->mass[i].forceY);
+            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+            outlet_anything(x->main_outlet, gensym("massesForcesNameNo"), 4, toout);
+        }
+    }
+    else
+    if ( (toget == gensym("massesForcesName")) && (argv[1].a_type == A_SYMBOL) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(1,argc,argv) == x->mass[i].Id)
+            {
+                SETSYMBOL(&(toout[0]), x->mass[i].Id);
+                SETFLOAT(&(toout[1]), x->mass[i].forceX);
+                SETFLOAT(&(toout[2]), x->mass[i].forceY);
+                SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+                outlet_anything(x->main_outlet, gensym("massesForcesNameId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if ( (toget == gensym("massesForcesName")) && (argc == 1) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETSYMBOL(&(toout[0]), x->mass[i].Id);
+            SETFLOAT(&(toout[1]), x->mass[i].forceX);
+            SETFLOAT(&(toout[2]), x->mass[i].forceY);
+            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+            outlet_anything(x->main_outlet, gensym("massesForcesName"), 4, toout);
+        } 
+    }
+    else
+    if ( (toget == gensym("linksPos")) && (argv[1].a_type == A_FLOAT) )
+    {
+        i = atom_getfloatarg(1, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+        }
+    }
+    else
+    if ( (toget == gensym("linksPos")) && (argv[1].a_type == A_SYMBOL) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(1,argc,argv) == x->link[i].Id)
+            {
+                SETFLOAT(&(toout[0]), i);
+                SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+                SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+                SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+                SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+                SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+                SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+                outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+            }
+        } 
+    }
+    else
+    if ( (toget == gensym("linksPos")) && (argc == 1) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+        } 
+    }
+    else
+    if ( (toget == gensym("linksPosName")) && (argv[1].a_type == A_FLOAT) )
+    {
+        i = atom_getfloatarg(1, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+            SETFLOAT(&(toout[3]), x->link[i].mass2->posX);
+            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+        }
+    }
+    else
+    if ( (toget == gensym("linksPosName")) && (argv[1].a_type == A_SYMBOL) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(1,argc,argv) == x->link[i].Id)
+            {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+            }
+        } 
+    }
+    else
+    if ( (toget == gensym("linksPosName")) && (argc == 1) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+            outlet_anything(x->main_outlet, gensym("linksPosNo"), 7, toout);
+        } 
+    }
+    else
+        error("not get attribute");
+}
+
+void pmpd3d_massesPos(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i;
+    t_atom  toout[5];
+
+    if (argv[0].a_type == A_FLOAT) 
+    {
+        i = atom_getfloatarg(0, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].posX);
+            SETFLOAT(&(toout[2]), x->mass[i].posY);
+            SETFLOAT(&(toout[3]), x->mass[i].posZ);
+            outlet_anything(x->main_outlet, gensym("massesPosNo"), 4, toout);
+        }  
+    }
+    else
+    if (argv[0].a_type == A_SYMBOL)
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETSYMBOL(&(toout[0]), atom_getsymbolarg(0,argc,argv));
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                SETFLOAT(&(toout[1]), x->mass[i].posX);
+                SETFLOAT(&(toout[2]), x->mass[i].posY);
+                SETFLOAT(&(toout[3]), x->mass[i].posZ);
+                outlet_anything(x->main_outlet, gensym("massesPosId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if (argc == 0)
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETSYMBOL(&(toout[1]), x->mass[i].Id);
+            SETFLOAT(&(toout[2]), x->mass[i].posX);
+            SETFLOAT(&(toout[3]), x->mass[i].posY);
+            SETFLOAT(&(toout[4]), x->mass[i].posZ);
+            outlet_anything(x->main_outlet, gensym("massesPos"), 5, toout);
+        } 
+    }
+}
+      
+void pmpd3d_massesSpeeds(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i;
+    t_atom  toout[5];
+
+    if (argv[0].a_type == A_FLOAT) 
+    {
+        i = atom_getfloatarg(0, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].speedX);
+            SETFLOAT(&(toout[2]), x->mass[i].speedY);
+            SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+            outlet_anything(x->main_outlet, gensym("massesSpeedsNo"), 4, toout);
+        }  
+    }
+    else
+    if (argv[0].a_type == A_SYMBOL)
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETSYMBOL(&(toout[0]), atom_getsymbolarg(0,argc,argv));
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                SETFLOAT(&(toout[1]), x->mass[i].speedX);
+                SETFLOAT(&(toout[2]), x->mass[i].speedY);
+                SETFLOAT(&(toout[3]), x->mass[i].speedZ);
+                outlet_anything(x->main_outlet, gensym("massesSpeedsId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if (argc == 0)
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETSYMBOL(&(toout[1]), x->mass[i].Id);
+            SETFLOAT(&(toout[2]), x->mass[i].speedX);
+            SETFLOAT(&(toout[3]), x->mass[i].speedY);
+            SETFLOAT(&(toout[4]), x->mass[i].speedZ);
+            outlet_anything(x->main_outlet, gensym("massesSpeeds"), 5, toout);
+        } 
+    }
+}
+
+void pmpd3d_massesForces(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{	
+    int i;
+    t_atom  toout[5];
+
+    if (argv[0].a_type == A_FLOAT) 
+    {
+        i = atom_getfloatarg(0, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->mass[i].forceX);
+            SETFLOAT(&(toout[2]), x->mass[i].forceY);
+            SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+            outlet_anything(x->main_outlet, gensym("massesForcesNo"), 4, toout);
+        }  
+    }
+    else
+    if (argv[0].a_type == A_SYMBOL)
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETSYMBOL(&(toout[0]), atom_getsymbolarg(0,argc,argv));
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                SETFLOAT(&(toout[1]), x->mass[i].forceX);
+                SETFLOAT(&(toout[2]), x->mass[i].forceY);
+                SETFLOAT(&(toout[3]), x->mass[i].forceZ);
+                outlet_anything(x->main_outlet, gensym("massesForcesId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if (argc == 0)
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETSYMBOL(&(toout[1]), x->mass[i].Id);
+            SETFLOAT(&(toout[2]), x->mass[i].forceX);
+            SETFLOAT(&(toout[3]), x->mass[i].forceY);
+            SETFLOAT(&(toout[4]), x->mass[i].forceZ);
+            outlet_anything(x->main_outlet, gensym("massesForces"), 5, toout);
+        } 
+    }
+}
+
+void pmpd3d_linksEnds(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+	int i;
+    t_atom  toout[8];
+    
+    if (argv[0].a_type == A_FLOAT) 
+    {
+        i = atom_getfloatarg(0, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+            SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+            SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+            SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+            SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+            SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+            outlet_anything(x->main_outlet, gensym("linksEndsNo"), 7, toout);
+        }
+    }
+    else
+    if (argv[0].a_type == A_SYMBOL)
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            SETSYMBOL(&(toout[0]), atom_getsymbolarg(0,argc,argv));
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                SETFLOAT(&(toout[1]), x->link[i].mass1->posX);
+                SETFLOAT(&(toout[2]), x->link[i].mass1->posY);
+                SETFLOAT(&(toout[3]), x->link[i].mass1->posZ);
+                SETFLOAT(&(toout[4]), x->link[i].mass2->posX);
+                SETFLOAT(&(toout[5]), x->link[i].mass2->posY);
+                SETFLOAT(&(toout[6]), x->link[i].mass2->posZ);
+                outlet_anything(x->main_outlet, gensym("linksEndsId"), 7, toout);
+            }
+        } 
+    }
+    else
+    if (argc == 0) 
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETSYMBOL(&(toout[1]), x->link[i].Id);
+            SETFLOAT(&(toout[2]), x->link[i].mass1->posX);
+            SETFLOAT(&(toout[3]), x->link[i].mass1->posY);
+            SETFLOAT(&(toout[4]), x->link[i].mass1->posZ);
+            SETFLOAT(&(toout[5]), x->link[i].mass2->posX);
+            SETFLOAT(&(toout[6]), x->link[i].mass2->posY);
+            SETFLOAT(&(toout[7]), x->link[i].mass2->posZ);
+            outlet_anything(x->main_outlet, gensym("linksEnds"), 8, toout);
+        } 
+    }
+}
+
+void pmpd3d_linksPos(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+	int i;
+    t_atom  toout[5];
+    
+    if (argv[0].a_type == A_FLOAT) 
+    {
+        i = atom_getfloatarg(0, argc, argv);
+        if ( (i>=0) && (i<x->nb_mass) )
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETFLOAT(&(toout[1]), (x->link[i].mass1->posX+x->link[i].mass2->posX)/2);
+            SETFLOAT(&(toout[2]), (x->link[i].mass1->posY+x->link[i].mass2->posY)/2);
+            SETFLOAT(&(toout[3]), (x->link[i].mass1->posZ+x->link[i].mass2->posZ)/2);
+            outlet_anything(x->main_outlet, gensym("linksEndsNo"), 4, toout);
+        }
+    }
+    else
+    if (argv[0].a_type == A_SYMBOL)
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            SETSYMBOL(&(toout[0]), atom_getsymbolarg(0,argc,argv));
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(toout[1]), (x->link[i].mass1->posX+x->link[i].mass2->posX)/2);
+				SETFLOAT(&(toout[2]), (x->link[i].mass1->posY+x->link[i].mass2->posY)/2);
+				SETFLOAT(&(toout[3]), (x->link[i].mass1->posZ+x->link[i].mass2->posZ)/2);
+                outlet_anything(x->main_outlet, gensym("linksEndsId"), 4, toout);
+            }
+        } 
+    }
+    else
+    if (argc == 0) 
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            SETFLOAT(&(toout[0]), i);
+            SETSYMBOL(&(toout[1]), x->link[i].Id);
+			SETFLOAT(&(toout[2]), (x->link[i].mass1->posX+x->link[i].mass2->posX)/2);
+			SETFLOAT(&(toout[3]), (x->link[i].mass1->posY+x->link[i].mass2->posY)/2);
+			SETFLOAT(&(toout[4]), (x->link[i].mass1->posZ+x->link[i].mass2->posZ)/2);
+            outlet_anything(x->main_outlet, gensym("linksEnds"), 5, toout);
+        } 
+    }
+}
diff --git a/pmpd3d_list.c b/pmpd3d_list.c
new file mode 100644
index 0000000..e527480
--- /dev/null
+++ b/pmpd3d_list.c
@@ -0,0 +1,1111 @@
+void pmpd3d_massesPosL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[3*x->nb_mass];
+    
+    if (argc==0) {
+		for (i=0; i < x->nb_mass; i++)
+		{
+			SETFLOAT(&(pos_list[3*i]  ),x->mass[i].posX);
+			SETFLOAT(&(pos_list[3*i+1]),x->mass[i].posY);
+			SETFLOAT(&(pos_list[3*i+2]),x->mass[i].posZ);
+		}
+		outlet_anything(x->main_outlet, gensym("massesPosL"),3*x->nb_mass , pos_list);       
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+				SETFLOAT(&(pos_list[3*i]  ),x->mass[i].posX);
+				SETFLOAT(&(pos_list[3*i+1]),x->mass[i].posY);
+				SETFLOAT(&(pos_list[3*i+2]),x->mass[i].posZ);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesPosL"),3*i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posX);
+		SETFLOAT(&(pos_list[1]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posY);
+		SETFLOAT(&(pos_list[2]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posZ);
+			
+        outlet_anything(x->main_outlet, gensym("massesPosL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesForcesL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[3*x->nb_mass];
+ 
+    if (argc==0) {
+        for (i=0; i< x->nb_mass; i++) {
+        SETFLOAT(&(pos_list[3*i]  ),x->mass[i].forceX);
+        SETFLOAT(&(pos_list[3*i+1]),x->mass[i].forceY);
+        SETFLOAT(&(pos_list[3*i+2]),x->mass[i].forceZ);
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesL"),3*x->nb_mass , pos_list);          
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+				SETFLOAT(&(pos_list[3*i]  ),x->mass[i].forceX);
+				SETFLOAT(&(pos_list[3*i+1]),x->mass[i].forceY);
+				SETFLOAT(&(pos_list[3*i+2]),x->mass[i].forceZ);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesL"),3*i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceX);
+        SETFLOAT(&(pos_list[1]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceY);
+        SETFLOAT(&(pos_list[2]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceZ);
+        
+        outlet_anything(x->main_outlet, gensym("massesForcesZL"),3 , pos_list);        
+    }
+}
+
+void pmpd3d_massesSpeedsL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[3*x->nb_mass];
+	
+    if (argc==0) {
+		for (i=0; i< x->nb_mass; i++) {
+			SETFLOAT(&(pos_list[3*i]  ),x->mass[i].speedX);
+			SETFLOAT(&(pos_list[3*i+1]),x->mass[i].speedY);
+			SETFLOAT(&(pos_list[3*i+2]),x->mass[i].speedZ);
+		}
+		outlet_anything(x->main_outlet, gensym("massesSpeedsL"),3*x->nb_mass , pos_list);         
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+				SETFLOAT(&(pos_list[3*i]  ),x->mass[i].speedX);
+				SETFLOAT(&(pos_list[3*i+1]),x->mass[i].speedY);
+				SETFLOAT(&(pos_list[3*i+2]),x->mass[i].speedZ);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesSpeedsL"),3*i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedX);
+        SETFLOAT(&(pos_list[1]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedY);
+        SETFLOAT(&(pos_list[2]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedZ);
+        
+        outlet_anything(x->main_outlet, gensym("massesSpeedsL"),3 , pos_list);        
+    }
+}
+
+void pmpd3d_massesPosXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+    
+    if (argc==0) {
+        for (i=0; i < x->nb_mass; i++)
+        {
+            SETFLOAT(&(pos_list[i]),x->mass[i].posX);
+        }
+        outlet_anything(x->main_outlet, gensym("massesPosXL"),x->nb_mass , pos_list);        
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].posX);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesPosXL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posX);
+        outlet_anything(x->main_outlet, gensym("massesPosXL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesForcesXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+ 
+    if (argc==0) {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(pos_list[i]),x->mass[i].forceX);
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesXL"),x->nb_mass , pos_list);          
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].forceX);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesXL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceX);
+        outlet_anything(x->main_outlet, gensym("massesForcesXL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesSpeedsXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+	
+    if (argc==0) {
+		for (i=0; i< x->nb_mass; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->mass[i].speedX);
+		}
+		outlet_anything(x->main_outlet, gensym("massesSpeedsXL"),x->nb_mass , pos_list);         
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].speedX);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesSpeedsXL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedX);
+        outlet_anything(x->main_outlet, gensym("massesSpeedsXL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesPosYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+    
+    if (argc==0) {
+        for (i=0; i < x->nb_mass; i++)
+        {
+            SETFLOAT(&(pos_list[i]),x->mass[i].posY);
+        }
+        outlet_anything(x->main_outlet, gensym("massesPosYL"),x->nb_mass , pos_list);         
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].posY);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesPosYL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posY);
+        outlet_anything(x->main_outlet, gensym("massesPosYL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesForcesYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+ 
+    if (argc==0) {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(pos_list[i]),x->mass[i].forceY);
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesYL"),x->nb_mass , pos_list);          
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].forceY);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesYL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceY);
+        outlet_anything(x->main_outlet, gensym("massesForcesYL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesSpeedsYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+	
+    if (argc==0) {
+		for (i=0; i< x->nb_mass; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->mass[i].speedY);
+		}
+		outlet_anything(x->main_outlet, gensym("massesSpeedsYL"),x->nb_mass , pos_list);         
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].speedY);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesSpeedsYL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedY);
+        outlet_anything(x->main_outlet, gensym("massesSpeedsYL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesPosZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+    
+    if (argc==0) {
+        for (i=0; i < x->nb_mass; i++)
+        {
+            SETFLOAT(&(pos_list[i]),x->mass[i].posZ);
+        }
+        outlet_anything(x->main_outlet, gensym("massesPosZL"),x->nb_mass , pos_list);         
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].posZ);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesPosZL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].posZ);
+        outlet_anything(x->main_outlet, gensym("massesPosZL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesForcesZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+ 
+    if (argc==0) {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            SETFLOAT(&(pos_list[i]),x->mass[i].forceZ);
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesZL"),x->nb_mass , pos_list);          
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].forceZ);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesZL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].forceZ);
+        outlet_anything(x->main_outlet, gensym("massesForcesZL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesSpeedsZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+	
+    if (argc==0) {
+		for (i=0; i< x->nb_mass; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->mass[i].speedZ);
+		}
+		outlet_anything(x->main_outlet, gensym("massesSpeedsZL"),x->nb_mass , pos_list);         
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+                SETFLOAT(&(pos_list[i]),x->mass[i].speedZ);
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesSpeedsZL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+        SETFLOAT(&(pos_list[0]),x->mass[(int)atom_getfloatarg(0, argc, argv)].speedZ);
+        outlet_anything(x->main_outlet, gensym("massesSpeedsZL"),1 , pos_list);        
+    }
+}
+
+// ---------------------------------------------------------------------
+
+void pmpd3d_massesPosNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+    
+    if (argc==0) {
+		for (i=0; i< x->nb_mass; i++) {
+			SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].posX)+sqr(x->mass[i].posY)+sqr(x->mass[i].posZ)));
+		}
+    outlet_anything(x->main_outlet, gensym("massesPosNormL"),x->nb_mass , pos_list);
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+				SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].posX)+sqr(x->mass[i].posY)+sqr(x->mass[i].posZ)));
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesPosNormL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+		i=(int)atom_getfloatarg(0, argc, argv);
+		SETFLOAT(&(pos_list[0]),sqrt(sqr(x->mass[i].posX)+sqr(x->mass[i].posY)+sqr(x->mass[i].posZ)));
+        outlet_anything(x->main_outlet, gensym("massesPosNormL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesForcesNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{   
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+    
+    if (argc==0) {
+		for (i=0; i< x->nb_mass; i++) {
+			SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].forceX)+sqr(x->mass[i].forceY)+sqr(x->mass[i].forceZ)));
+		}
+    outlet_anything(x->main_outlet, gensym("massesForcesNormL"),x->nb_mass , pos_list);
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+				SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].forceX)+sqr(x->mass[i].forceY)+sqr(x->mass[i].forceZ)));
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesForcesNormL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+		i=(int)atom_getfloatarg(0, argc, argv);
+        SETFLOAT(&(pos_list[0]),sqrt(sqr(x->mass[i].forceX)+sqr(x->mass[i].forceY)+sqr(x->mass[i].forceZ)));
+        outlet_anything(x->main_outlet, gensym("massesForcesNormL"),1 , pos_list);        
+    }
+}
+
+void pmpd3d_massesSpeedsNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_mass];
+    
+    if (argc==0) {
+		for (i=0; i< x->nb_mass; i++) {
+			SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].speedX)+sqr(x->mass[i].speedY)+sqr(x->mass[i].speedZ)));
+		}
+    outlet_anything(x->main_outlet, gensym("massesSpeedsNormL"),x->nb_mass , pos_list);
+    }
+    else
+    if ((argc==1) && (argv[1].a_type == A_SYMBOL)) {
+        i = 0;
+        j = 0;
+        while  (j < x->nb_mass){
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[j].Id) {
+				SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].speedX)+sqr(x->mass[i].speedY)+sqr(x->mass[i].speedZ)));
+                i++;
+            }
+        }
+        outlet_anything(x->main_outlet, gensym("massesSpeedsNormL"),i , pos_list);
+    }
+    else 
+    if ((argc==1) && (argv[0].a_type == A_FLOAT)) {
+		i=(int)atom_getfloatarg(0, argc, argv);
+        SETFLOAT(&(pos_list[i]),sqrt(sqr(x->mass[i].speedX)+sqr(x->mass[i].speedY)+sqr(x->mass[i].speedZ)));
+        outlet_anything(x->main_outlet, gensym("massesSpeedsNormL"),1 , pos_list);        
+    }
+    
+}
+
+// ---------------------------------------------------------------------
+
+void pmpd3d_linksPosL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[3*x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[3*i]  ),(x->link[i].mass2->posX + x->link[i].mass1->posX)/2);
+			SETFLOAT(&(pos_list[3*i+1]),(x->link[i].mass2->posY + x->link[i].mass1->posY)/2);
+			SETFLOAT(&(pos_list[3*i+2]),(x->link[i].mass2->posZ + x->link[i].mass1->posZ)/2);
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosL"),3*x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[3*j]  ),(x->link[i].mass2->posX + x->link[i].mass1->posX)/2);
+				SETFLOAT(&(pos_list[3*j+1]),(x->link[i].mass2->posY + x->link[i].mass1->posY)/2);
+				SETFLOAT(&(pos_list[3*j+2]),(x->link[i].mass2->posZ + x->link[i].mass1->posZ)/2);
+				j++;
+            }
+        }
+  		outlet_anything(x->main_outlet, gensym("linksPosL"), 3*j, pos_list);   
+    }
+}
+
+void pmpd3d_linksLengthL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[3*x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[3*i]  ),x->link[i].mass2->posX - x->link[i].mass1->posX);
+			SETFLOAT(&(pos_list[3*i+1]),x->link[i].mass2->posY - x->link[i].mass1->posY);
+			SETFLOAT(&(pos_list[3*i+2]),x->link[i].mass2->posZ - x->link[i].mass1->posZ);
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthL"),3*x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[3*j]  ),x->link[i].mass2->posX - x->link[i].mass1->posX);
+				SETFLOAT(&(pos_list[3*j+1]),x->link[i].mass2->posY - x->link[i].mass1->posY);
+				SETFLOAT(&(pos_list[3*j+2]),x->link[i].mass2->posZ - x->link[i].mass1->posZ);
+				j++;
+            }
+        }
+  		outlet_anything(x->main_outlet, gensym("linksLengthL"), 3*j, pos_list);   
+    }
+}
+
+void pmpd3d_linksPosSpeedL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[3*x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[3*i]  ),(x->link[i].mass2->speedX + x->link[i].mass1->speedX)/2);
+			SETFLOAT(&(pos_list[3*i+1]),(x->link[i].mass2->speedY + x->link[i].mass1->speedY)/2);
+			SETFLOAT(&(pos_list[3*i+2]),(x->link[i].mass2->speedZ + x->link[i].mass1->speedZ)/2);
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedL"),3*x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[3*j]  ),(x->link[i].mass2->speedX + x->link[i].mass1->speedX)/2);
+				SETFLOAT(&(pos_list[3*j+1]),(x->link[i].mass2->speedY + x->link[i].mass1->speedY)/2);
+				SETFLOAT(&(pos_list[3*j+2]),(x->link[i].mass2->speedZ + x->link[i].mass1->speedZ)/2);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedL"),3*j , pos_list);
+    }
+}
+
+void pmpd3d_linksLengthSpeedL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[3*x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[3*i]  ),x->link[i].mass2->speedX - x->link[i].mass1->speedX);
+			SETFLOAT(&(pos_list[3*i+1]),x->link[i].mass2->speedY - x->link[i].mass1->speedY);
+			SETFLOAT(&(pos_list[3*i+2]),x->link[i].mass2->speedZ - x->link[i].mass1->speedZ);
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedL"),3*x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[3*j]  ),x->link[i].mass2->speedX - x->link[i].mass1->speedX);
+				SETFLOAT(&(pos_list[3*j+1]),x->link[i].mass2->speedY - x->link[i].mass1->speedY);
+				SETFLOAT(&(pos_list[3*j+2]),x->link[i].mass2->speedZ - x->link[i].mass1->speedZ);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedL"),3*j , pos_list);
+    }
+}
+
+void pmpd3d_linksPosXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),(x->link[i].mass1->posX + x->link[i].mass2->posX)/2);
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosXL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),(x->link[i].mass1->posX + x->link[i].mass2->posX)/2);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosXL"),j , pos_list);
+    }
+}
+
+void pmpd3d_linksLengthXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->link[i].mass2->posX - x->link[i].mass1->posX);
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthXL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),x->link[i].mass2->posX - x->link[i].mass1->posX);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksLengthXL"),j , pos_list);
+    }
+}
+
+void pmpd3d_linksPosSpeedXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),(x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2);
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedXL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),(x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedXL"),j , pos_list);
+    }
+}
+
+void pmpd3d_linksLengthSpeedXL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->link[i].mass2->speedX - x->link[i].mass1->speedX);
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedXL"), x->nb_link, pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),x->link[i].mass2->speedX - x->link[i].mass1->speedX);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedXL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksPosYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),(x->link[i].mass1->posY + x->link[i].mass2->posY)/2);
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosYL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),(x->link[i].mass1->posY + x->link[i].mass2->posY)/2);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosYL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksLengthYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->link[i].mass2->posY - x->link[i].mass1->posY);
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthYL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),x->link[i].mass2->posY - x->link[i].mass1->posY);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksLengthYL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksPosSpeedYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),(x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2);
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedYL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),(x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedYL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksLengthSpeedYL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->link[i].mass2->speedY - x->link[i].mass1->speedY);
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedYL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),x->link[i].mass2->speedY - x->link[i].mass1->speedY);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedYL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksPosZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),(x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2);
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosZL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),(x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosZL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksLengthZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->link[i].mass2->posZ - x->link[i].mass1->posZ);
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthZL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),x->link[i].mass2->posZ - x->link[i].mass1->posZ);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksLengthZL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksPosSpeedZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),(x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2);
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedZL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),(x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedZL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksLengthSpeedZL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),x->link[i].mass2->speedZ - x->link[i].mass1->speedZ);
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedZL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),x->link[i].mass2->speedZ - x->link[i].mass1->speedZ);
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedZL"), j, pos_list);
+    }
+}
+
+// ---------------------------------------------------------------------
+
+void pmpd3d_linksPosNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),sqrt( \
+                            sqr((x->link[i].mass1->posX + x->link[i].mass2->posX)/2) + \
+                            sqr((x->link[i].mass1->posY + x->link[i].mass2->posY)/2) + \
+                            sqr((x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2) ));
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosNormL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),sqrt( \
+                            sqr((x->link[i].mass1->posX + x->link[i].mass2->posX)/2) + \
+                            sqr((x->link[i].mass1->posY + x->link[i].mass2->posY)/2) + \
+                            sqr((x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2) ));
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosNormL"), j, pos_list);
+    }		
+}
+
+void pmpd3d_linksLengthNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),sqrt( \
+                            sqr(x->link[i].mass2->posX - x->link[i].mass1->posX) + \
+                            sqr(x->link[i].mass2->posY - x->link[i].mass1->posY) + \
+                            sqr(x->link[i].mass2->posZ - x->link[i].mass1->posZ) ));
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthNormL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),sqrt( \
+                            sqr(x->link[i].mass2->posX - x->link[i].mass1->posX) + \
+                            sqr(x->link[i].mass2->posY - x->link[i].mass1->posY) + \
+                            sqr(x->link[i].mass2->posZ - x->link[i].mass1->posZ) ));
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksLengthNormL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksPosSpeedNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),sqrt( \
+                            sqr((x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2) + \
+                            sqr((x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2) + \
+                            sqr((x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2) ));
+		}
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedNormL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),sqrt( \
+                            sqr((x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2) + \
+                            sqr((x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2) + \
+                            sqr((x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2) ));
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksPosSpeedNormL"), j, pos_list);
+    }
+}
+
+void pmpd3d_linksLengthSpeedNormL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i,j;
+    t_atom pos_list[x->nb_link];
+
+    if (argc==0)
+    {
+		for (i=0; i < x->nb_link; i++)
+		{
+			SETFLOAT(&(pos_list[i]),sqrt( \
+                            sqr(x->link[i].mass2->speedX - x->link[i].mass1->speedX) + \
+                            sqr(x->link[i].mass2->speedY - x->link[i].mass1->speedY) + \
+                            sqr(x->link[i].mass2->speedZ - x->link[i].mass1->speedZ) ));
+		}
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedNormL"),x->nb_link , pos_list);
+	}
+	else 
+	if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+	{
+		j=0;
+		for (i=0; i < x->nb_link; i++)
+        {
+			if (atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+				SETFLOAT(&(pos_list[j]),sqrt( \
+                            sqr((x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2) + \
+                            sqr((x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2) + \
+                            sqr((x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2) ));
+				j++;
+            }
+        }
+		outlet_anything(x->main_outlet, gensym("linksLengthSpeedNormL"), j, pos_list);
+    }
+}
+
diff --git a/pmpd3d_set.c b/pmpd3d_set.c
new file mode 100644
index 0000000..43b58a5
--- /dev/null
+++ b/pmpd3d_set.c
@@ -0,0 +1,457 @@
+void pmpd3d_setK(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_link-1, tmp));
+        x->link[tmp].K = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                x->link[i].K = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setD(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_link-1, tmp));
+        x->link[tmp].D = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                x->link[i].D = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setDEnv(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].D2 = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].D2 = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argc == 1 ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            x->mass[i].D2 = atom_getfloatarg(0, argc, argv);
+        }
+    }
+}
+
+void pmpd3d_setDEnvOffset(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].D2offset = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].D2offset = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argc == 1 ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            x->mass[i].D2offset = atom_getfloatarg(0, argc, argv);
+        }
+    }
+}
+
+void pmpd3d_setL(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_link-1, tmp));
+        x->link[tmp].L = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                x->link[i].L = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argc == 1 ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_link-1, tmp));
+        x->link[tmp].L = x->link[tmp].mass2->posX - x->link[tmp].mass1->posX;
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argc == 1 ) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                x->link[i].L = x->link[i].mass2->posX - x->link[i].mass1->posX;
+            }
+        }
+    }
+}
+
+void pmpd3d_setLKTab(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+    t_float K_l = atom_getfloatarg(1, argc, argv);
+    if (K_l <=  0) K_l = 1;
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_link-1, tmp));
+        x->link[tmp].K_L = K_l;
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                x->link[i].K_L = K_l;
+            }
+        }
+    }
+}
+
+void pmpd3d_setLDTab(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+    t_float D_l = atom_getfloatarg(1, argc, argv);
+    if (D_l <=  0) D_l = 1;
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_link-1, tmp));
+        x->link[tmp].D_L = D_l;
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                x->link[i].D_L = D_l;
+            }
+        }
+    }
+}
+
+void pmpd3d_setLinkId(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_SYMBOL ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_link-1, tmp));
+        x->link[tmp].Id = atom_getsymbolarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_SYMBOL ) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                x->link[i].Id = atom_getsymbolarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setMassId(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_SYMBOL ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].Id = atom_getsymbolarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_SYMBOL ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].Id = atom_getsymbolarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setFixed(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( argv[0].a_type == A_FLOAT ) 
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].mobile = 0;
+    }
+    if ( argv[0].a_type == A_SYMBOL )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].mobile = 0;
+            }
+        }
+    }
+}
+
+void pmpd3d_setMobile(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( argv[0].a_type == A_FLOAT )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].mobile = 1;
+    }
+    if ( argv[0].a_type == A_SYMBOL ) 
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].mobile = 1;
+            }
+        }
+    }
+}
+
+void pmpd3d_setSpeed(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].speedX = atom_getfloatarg(1, argc, argv);
+        x->mass[tmp].speedY = atom_getfloatarg(2, argc, argv);
+        x->mass[tmp].speedZ = atom_getfloatarg(3, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].speedX = atom_getfloatarg(1, argc, argv);
+                x->mass[i].speedY = atom_getfloatarg(2, argc, argv);
+                x->mass[i].speedZ = atom_getfloatarg(3, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setSpeedX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].speedX = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].speedX = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setSpeedY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].speedY = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].speedY = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setSpeedZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].speedZ = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].speedZ = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setForce(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].forceX = atom_getfloatarg(1, argc, argv);
+        x->mass[tmp].forceY = atom_getfloatarg(2, argc, argv);
+        x->mass[tmp].forceZ = atom_getfloatarg(3, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].forceX = atom_getfloatarg(1, argc, argv);
+                x->mass[i].forceY = atom_getfloatarg(2, argc, argv);
+                x->mass[i].forceZ = atom_getfloatarg(3, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setForceX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].forceX = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].forceX = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setForceY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].forceY = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].forceY = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_setForceZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].forceZ = atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].forceZ = atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
diff --git a/pmpd3d_stat.c b/pmpd3d_stat.c
new file mode 100644
index 0000000..cc8cb9c
--- /dev/null
+++ b/pmpd3d_stat.c
@@ -0,0 +1,395 @@
+void pmpd3d_massesPosMean(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    t_float sommeX, sommeY, sommeZ, somme;
+    t_int i,j;
+    t_atom mean[4];
+
+    sommeX = 0;
+    sommeY = 0;
+    sommeZ = 0;
+    somme = 0;
+    j = 0;
+    
+    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                sommeX += x->mass[i].posX;
+                sommeY += x->mass[i].posY;
+                sommeZ += x->mass[i].posZ;
+                somme +=  sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
+                j++;
+            }
+        }
+    }
+    else
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+                sommeX += x->mass[i].posX;
+                sommeY += x->mass[i].posY;
+                sommeZ += x->mass[i].posZ;
+                somme +=  sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
+                j++;
+        }
+    }    
+    
+    sommeX /= j;
+    sommeY /= j;
+    sommeZ /= j;
+    somme  /= j;    
+    
+    SETFLOAT(&(mean[0]),sommeX);
+    SETFLOAT(&(mean[1]),sommeY);
+    SETFLOAT(&(mean[2]),sommeZ);
+    SETFLOAT(&(mean[3]),somme);
+    
+    outlet_anything(x->main_outlet, gensym("massesPosMean"),4 , mean);
+}
+
+void pmpd3d_massesPosStd(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    t_float sommeX, sommeY, sommeZ, somme;
+    t_int i,j;
+    t_float stdX, stdY, stdZ, std;
+    t_atom std_out[4];
+
+    sommeX = 0;
+    sommeY = 0;
+    sommeZ = 0;
+    somme  = 0;
+    stdX = 0;
+    stdY = 0;
+    stdZ = 0;
+    std  = 0;
+    j = 0;
+    
+    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                sommeX += x->mass[i].posX;
+                sommeY += x->mass[i].posY;
+                sommeZ += x->mass[i].posZ;
+                somme +=  sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
+                j++;
+            }
+        }
+        sommeX /= j;
+        sommeY /= j;
+        sommeZ /= j;
+        somme /= j;
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                stdX += sqr(x->mass[i].posX-sommeX);
+                stdY += sqr(x->mass[i].posY-sommeY);
+                stdZ += sqr(x->mass[i].posZ-sommeZ);
+                std  +=  sqr(sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ))-somme);
+            }
+        }        
+    }
+    else
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            sommeX += x->mass[i].posX;
+            sommeY += x->mass[i].posY;
+            sommeZ += x->mass[i].posZ;
+            somme +=  sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ)); // distance au centre
+            j++;
+        }
+        sommeX /= j;
+        sommeY /= j;
+        sommeZ /= j;
+        somme /= j;
+        for (i=0; i< x->nb_mass; i++)
+        {
+            stdX += sqr(x->mass[i].posX-sommeX);
+            stdY += sqr(x->mass[i].posY-sommeY);
+            stdZ += sqr(x->mass[i].posZ-sommeZ);
+            std  += sqr(sqrt(sqr(x->mass[i].posX) + sqr(x->mass[i].posY) + sqr(x->mass[i].posZ))-somme);
+        }
+    }    
+    
+    stdX = sqrt(stdX/j);
+    stdY = sqrt(stdY/j);
+    stdZ = sqrt(stdZ/j);
+    std  = sqrt(std /j);    
+
+    SETFLOAT(&(std_out[0]),stdX);
+    SETFLOAT(&(std_out[1]),stdY);
+    SETFLOAT(&(std_out[2]),stdZ);
+    SETFLOAT(&(std_out[3]),std);
+    
+    outlet_anything(x->main_outlet, gensym("massesPosStd"),4 , std_out);
+}
+
+void pmpd3d_massesForcesMean(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    t_float sommeX, sommeY, sommeZ, somme;
+    t_int i,j;
+    t_atom mean[4];
+
+    sommeX = 0;
+    sommeY = 0;
+    sommeZ = 0;
+    somme = 0;
+    j = 0;
+    
+    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                sommeX += x->mass[i].forceX;
+                sommeY += x->mass[i].forceY;
+                sommeZ += x->mass[i].forceZ;
+                somme +=  sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ)); // force total
+                j++;
+            }
+        }
+    }
+    else
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+                sommeX += x->mass[i].forceX;
+                sommeY += x->mass[i].forceY;
+                sommeZ += x->mass[i].forceZ;
+                somme +=  sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ)); // force
+                j++;
+        }
+    }    
+    
+    sommeX /= j;
+    sommeY /= j;
+    sommeZ /= j;
+    somme  /= j;
+
+    SETFLOAT(&(mean[0]),sommeX);
+    SETFLOAT(&(mean[1]),sommeY);
+    SETFLOAT(&(mean[2]),sommeZ);
+    SETFLOAT(&(mean[3]),somme);
+    
+    outlet_anything(x->main_outlet, gensym("massesForcesMean"),4 , mean);
+}
+
+void pmpd3d_massesForcesStd(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    t_float sommeX, sommeY, sommeZ, somme;
+    t_int i,j;
+    t_float stdX, stdY, stdZ, std;
+    t_atom std_out[4];
+
+    sommeX = 0;
+    sommeY = 0;
+    sommeZ = 0;
+    somme  = 0;
+    stdX = 0;
+    stdY = 0;
+    stdZ = 0;
+    std  = 0;
+    j = 0;
+    
+    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                sommeX += x->mass[i].forceX;
+                sommeY += x->mass[i].forceY;
+                sommeZ += x->mass[i].forceZ;
+                somme +=  sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ)); // force
+                j++;
+            }
+        }
+        sommeX /= j;
+        sommeY /= j;
+        sommeZ /= j;
+        somme /= j;
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                stdX += sqr(x->mass[i].forceX-sommeX);
+                stdY += sqr(x->mass[i].forceY-sommeY);
+                stdZ += sqr(x->mass[i].forceZ-sommeZ);
+                std  +=  sqr(sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ))-somme);
+            }
+        }        
+    }
+    else
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            sommeX += x->mass[i].forceX;
+            sommeY += x->mass[i].forceY;
+            sommeZ += x->mass[i].forceZ;
+            somme +=  sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ)); 
+            j++;
+        }
+        sommeX /= j;
+        sommeY /= j;
+        sommeZ /= j;
+        somme /= j;
+        for (i=0; i< x->nb_mass; i++)
+        {
+            stdX += sqr(x->mass[i].forceX-sommeX);
+            stdY += sqr(x->mass[i].forceY-sommeY);
+            stdZ += sqr(x->mass[i].forceZ-sommeZ);
+            std  += sqr(sqrt(sqr(x->mass[i].forceX) + sqr(x->mass[i].forceY) + sqr(x->mass[i].forceZ))-somme);
+        }
+    }    
+    
+    stdX = sqrt(stdX/j);
+    stdY = sqrt(stdY/j);
+    stdZ = sqrt(stdZ/j);
+    std  = sqrt(std /j);    
+
+    SETFLOAT(&(std_out[0]),stdX);
+    SETFLOAT(&(std_out[1]),stdY);
+    SETFLOAT(&(std_out[2]),stdZ);
+    SETFLOAT(&(std_out[3]),std);
+    
+    outlet_anything(x->main_outlet, gensym("massesForcesStd"),4 , std_out);
+}
+
+void pmpd3d_massesSpeedsMean(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    t_float sommeX, sommeY, sommeZ, somme;
+    t_int i,j;
+    t_atom mean[4];
+
+    sommeX = 0;
+    sommeY = 0;
+    sommeZ = 0;
+    somme = 0;
+    j = 0;
+    
+    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                sommeX += x->mass[i].speedX;
+                sommeY += x->mass[i].speedY;
+                sommeZ += x->mass[i].speedZ;
+                somme +=  sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ)); // speed total
+                j++;
+            }
+        }
+    }
+    else
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+                sommeX += x->mass[i].speedX;
+                sommeY += x->mass[i].speedY;
+                sommeZ += x->mass[i].speedZ;
+                somme +=  sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ)); // speed
+                j++;
+        }
+    }    
+    
+    sommeX /= j;
+    sommeY /= j;
+    sommeZ /= j;
+    somme  /= j;
+
+    SETFLOAT(&(mean[0]),sommeX);
+    SETFLOAT(&(mean[1]),sommeY);
+    SETFLOAT(&(mean[2]),sommeZ);
+    SETFLOAT(&(mean[3]),somme);
+    
+    outlet_anything(x->main_outlet, gensym("massesSpeedsMean"),4 , mean);
+}
+
+void pmpd3d_massesSpeedsStd(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    t_float sommeX, sommeY, sommeZ, somme;
+    t_int i,j;
+    t_float stdX, stdY, stdZ, std;
+    t_atom std_out[4];
+
+    sommeX = 0;
+    sommeY = 0;
+    sommeZ = 0;
+    somme  = 0;
+    stdX = 0;
+    stdY = 0;
+    stdZ = 0;
+    std  = 0;
+    j = 0;
+    
+    if ( (argc >= 1) && (argv[0].a_type == A_SYMBOL) ) 
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                sommeX += x->mass[i].speedX;
+                sommeY += x->mass[i].speedY;
+                sommeZ += x->mass[i].speedZ;
+                somme +=  sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ)); // speed
+                j++;
+            }
+        }
+        sommeX /= j;
+        sommeY /= j;
+        sommeZ /= j;
+        somme /= j;
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            { 
+                stdX += sqr(x->mass[i].speedX-sommeX);
+                stdY += sqr(x->mass[i].speedY-sommeY);
+                stdZ += sqr(x->mass[i].speedZ-sommeZ);
+                std  +=  sqr(sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ))-somme);
+            }
+        }        
+    }
+    else
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            sommeX += x->mass[i].speedX;
+            sommeY += x->mass[i].speedY;
+            sommeZ += x->mass[i].speedZ;
+            somme +=  sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ)); 
+            j++;
+        }
+        sommeX /= j;
+        sommeY /= j;
+        sommeZ /= j;
+        somme /= j;
+        for (i=0; i< x->nb_mass; i++)
+        {
+            stdX += sqr(x->mass[i].speedX-sommeX);
+            stdY += sqr(x->mass[i].speedY-sommeY);
+            stdZ += sqr(x->mass[i].speedZ-sommeZ);
+            std  += sqr(sqrt(sqr(x->mass[i].speedX) + sqr(x->mass[i].speedY) + sqr(x->mass[i].speedZ))-somme);
+        }
+    }    
+    
+    stdX = sqrt(stdX/j);
+    stdY = sqrt(stdY/j);
+    stdZ = sqrt(stdZ/j);
+    std  = sqrt(std /j);    
+
+    SETFLOAT(&(std_out[0]),stdX);
+    SETFLOAT(&(std_out[1]),stdY);
+    SETFLOAT(&(std_out[2]),stdZ);
+    SETFLOAT(&(std_out[3]),std);
+    
+    outlet_anything(x->main_outlet, gensym("massesSpeedsStd"),4 , std_out);
+}
diff --git a/pmpd3d_tab.c b/pmpd3d_tab.c
new file mode 100644
index 0000000..9278cb7
--- /dev/null
+++ b/pmpd3d_tab.c
@@ -0,0 +1,1890 @@
+void pmpd3d_massesPosT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, (vecsize-2)/3);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[3*i  ].w_float = x->mass[i].posX;
+                vec[3*i+1].w_float = x->mass[i].posY;
+                vec[3*i+2].w_float = x->mass[i].posZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize-2) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].posX;
+                    i++;
+                    vec[i].w_float = x->mass[j].posY;
+                    i++;
+                    vec[i].w_float = x->mass[j].posZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesSpeedsT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, (vecsize-2)/3);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[3*i  ].w_float = x->mass[i].speedX;
+                vec[3*i+1].w_float = x->mass[i].speedY;
+                vec[3*i+2].w_float = x->mass[i].speedZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize-2) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].speedX;
+                    i++;
+                    vec[i].w_float = x->mass[j].speedY;
+                    i++;
+                    vec[i].w_float = x->mass[j].speedZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesForcesT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, (vecsize-2)/3);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[3*i  ].w_float = x->mass[i].forceX;
+                vec[3*i+1].w_float = x->mass[i].forceY;
+                vec[3*i+2].w_float = x->mass[i].forceZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize-2) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].forceX;
+                    i++;
+                    vec[i].w_float = x->mass[j].forceY;
+                    i++;
+                    vec[i].w_float = x->mass[j].forceZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesPosXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].posX;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+
+                {
+                    vec[i].w_float = x->mass[j].posX;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesSpeedsXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {        
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].speedX;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].speedX;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesForcesXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].forceX;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].forceX;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesPosYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].posY;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].posY;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesSpeedsYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].speedY;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].speedY;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesForcesYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].forceY;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].forceY;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesPosZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].posZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].posZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesSpeedsZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].speedZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].speedZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesForcesZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->mass[i].forceZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = x->mass[j].forceZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------
+
+void pmpd3d_massesPosNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = sqrt(sqr(x->mass[i].posX)+sqr(x->mass[i].posY)+sqr(x->mass[i].posZ));
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = sqrt(sqr(x->mass[j].posX)+sqr(x->mass[j].posY)+sqr(x->mass[i].posZ));
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesSpeedsNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = sqrt(sqr(x->mass[i].speedX)+sqr(x->mass[i].speedY)+sqr(x->mass[i].speedZ));
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = sqrt(sqr(x->mass[j].speedX)+sqr(x->mass[j].speedY)+sqr(x->mass[i].speedZ));
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_massesForcesNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_mass;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = sqrt(sqr(x->mass[i].forceX)+sqr(x->mass[i].forceY)+sqr(x->mass[i].forceZ));
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_mass))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->mass[j].Id)
+                {
+                    vec[i].w_float = sqrt(sqr(x->mass[j].forceX)+sqr(x->mass[j].forceY)+sqr(x->mass[i].forceZ));
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------
+
+void pmpd3d_linksPosT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, (vecsize-2)/3);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[3*i  ].w_float = (x->link[i].mass2->posX + x->link[i].mass1->posX)/2;
+                vec[3*i+1].w_float = (x->link[i].mass2->posY + x->link[i].mass1->posY)/2;
+                vec[3*i+2].w_float = (x->link[i].mass2->posZ + x->link[i].mass1->posZ)/2;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize-2) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = (x->link[j].mass2->posX + x->link[j].mass1->posX)/2;
+                    i++;
+                    vec[i].w_float = (x->link[j].mass2->posY + x->link[j].mass1->posY)/2;
+                    i++;
+                    vec[i].w_float = (x->link[j].mass2->posZ + x->link[j].mass1->posZ)/2;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, (vecsize-2)/3);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[3*i  ].w_float = x->link[i].mass2->posX - x->link[i].mass1->posX;
+                vec[3*i+1].w_float = x->link[i].mass2->posY - x->link[i].mass1->posY;
+                vec[3*i+2].w_float = x->link[i].mass2->posZ - x->link[i].mass1->posZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize-2) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass2->posX + x->link[j].mass1->posX;
+                    i++;
+                    vec[i].w_float = x->link[j].mass2->posY + x->link[j].mass1->posY;
+                    i++;
+                    vec[i].w_float = x->link[j].mass2->posZ + x->link[j].mass1->posZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksPosSpeedT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, (vecsize-2)/3);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[3*i  ].w_float = (x->link[i].mass2->speedX + x->link[i].mass1->speedX)/2;
+                vec[3*i+1].w_float = (x->link[i].mass2->speedY + x->link[i].mass1->speedY)/2;
+                vec[3*i+2].w_float = (x->link[i].mass2->speedZ + x->link[i].mass1->speedZ)/2;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize-2) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = (x->link[j].mass2->speedX + x->link[j].mass1->speedX)/2;
+                    i++;
+                    vec[i].w_float = (x->link[j].mass2->speedY + x->link[j].mass1->speedY)/2;
+                    i++;
+                    vec[i].w_float = (x->link[j].mass2->speedZ + x->link[j].mass1->speedZ)/2;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthSpeedT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, (vecsize-2)/3);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[3*i  ].w_float = x->link[i].mass2->speedX - x->link[i].mass1->speedX;
+                vec[3*i+1].w_float = x->link[i].mass2->speedY - x->link[i].mass1->speedY;
+                vec[3*i+2].w_float = x->link[i].mass2->speedZ - x->link[i].mass1->speedZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize-2) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass2->speedX + x->link[j].mass1->speedX;
+                    i++;
+                    vec[i].w_float = x->link[j].mass2->speedY + x->link[j].mass1->speedY;
+                    i++;
+                    vec[i].w_float = x->link[j].mass2->speedZ + x->link[j].mass1->speedZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksPosXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = (x->link[i].mass1->posX + x->link[i].mass2->posX)/2;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = (x->link[j].mass1->posX + x->link[j].mass2->posX)/2;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->link[i].mass2->posX - x->link[i].mass1->posX;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass2->posX - x->link[j].mass1->posX;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksPosSpeedXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = (x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = (x->link[j].mass1->speedX + x->link[j].mass2->speedX)/2;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthSpeedXT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->link[i].mass2->speedX - x->link[i].mass1->speedX;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass2->speedX - x->link[j].mass1->speedX;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksPosYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = (x->link[i].mass1->posY + x->link[i].mass2->posY)/2;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = (x->link[j].mass1->posY + x->link[j].mass2->posY)/2;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->link[i].mass2->posY - x->link[i].mass1->posY;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass2->posY - x->link[j].mass1->posY;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksPosSpeedYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = (x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = (x->link[j].mass1->speedY + x->link[j].mass2->speedY)/2;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthSpeedYT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->link[i].mass2->speedY - x->link[i].mass1->speedY;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass2->speedY - x->link[j].mass1->speedY;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksPosZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = (x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = (x->link[j].mass1->posZ + x->link[j].mass2->posZ)/2;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->link[i].mass2->posZ - x->link[i].mass1->posZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass2->posZ - x->link[j].mass1->posZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksPosSpeedZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = (x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = (x->link[j].mass1->speedZ + x->link[j].mass2->speedZ)/2;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthSpeedZT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = x->link[i].mass2->speedZ - x->link[i].mass1->speedZ;
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass2->speedZ - x->link[j].mass1->speedZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------
+
+void pmpd3d_linksPosNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = sqrt( \
+                            sqr((x->link[i].mass1->posX + x->link[i].mass2->posX)/2) + \
+                            sqr((x->link[i].mass1->posY + x->link[i].mass2->posY)/2) + \
+                            sqr((x->link[i].mass1->posZ + x->link[i].mass2->posZ)/2) );
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[j].w_float = sqrt( \
+                            sqr((x->link[j].mass1->posX + x->link[j].mass2->posX)/2) + \
+                            sqr((x->link[j].mass1->posY + x->link[j].mass2->posY)/2) + \
+                            sqr((x->link[j].mass1->posZ + x->link[j].mass2->posZ)/2) );
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = sqrt( \
+                            sqr(x->link[i].mass2->posX - x->link[i].mass1->posX) + \
+                            sqr(x->link[i].mass2->posY - x->link[i].mass1->posY) + \
+                            sqr(x->link[i].mass2->posZ - x->link[i].mass1->posZ) );
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = sqrt( \
+                            sqr(x->link[j].mass2->posX - x->link[j].mass1->posX) + \
+                            sqr(x->link[j].mass2->posY - x->link[j].mass1->posY) + \
+                            sqr(x->link[j].mass2->posZ - x->link[j].mass1->posZ) );
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksPosSpeedNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = sqrt( \
+                            sqr((x->link[i].mass1->speedX + x->link[i].mass2->speedX)/2) + \
+                            sqr((x->link[i].mass1->speedY + x->link[i].mass2->speedY)/2) + \
+                            sqr((x->link[i].mass1->speedZ + x->link[i].mass2->speedZ)/2) );
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = sqrt( \
+                            sqr((x->link[j].mass1->speedX + x->link[j].mass2->speedX)/2) + \
+                            sqr((x->link[j].mass1->speedY + x->link[j].mass2->speedY)/2) + \
+                            sqr((x->link[j].mass1->speedZ + x->link[j].mass2->speedZ)/2) );
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+void pmpd3d_linksLengthSpeedNormT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, vecsize);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[i].w_float = sqrt( \
+                            sqr(x->link[i].mass2->speedX - x->link[i].mass1->speedX) + \
+                            sqr(x->link[i].mass2->speedY - x->link[i].mass1->speedY) + \
+                            sqr(x->link[i].mass2->speedZ - x->link[i].mass1->speedZ) );
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = sqrt( \
+                            sqr(x->link[j].mass2->speedX - x->link[j].mass1->speedX) + \
+                            sqr(x->link[j].mass2->speedY - x->link[j].mass1->speedY) + \
+                            sqr(x->link[j].mass2->speedZ - x->link[j].mass1->speedZ) );
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------
+
+void pmpd3d_linksEndT(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i, j, vecsize;
+    t_garray *a;
+    t_word *vec;
+    
+    if ( (argc==1) && (argv[0].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {
+            int taille_max = x->nb_link;
+            taille_max = min(taille_max, (vecsize-5)/6);
+            for (i=0; i < taille_max ; i++)
+            {
+                vec[6*i  ].w_float = x->link[i].mass1->posX;
+                vec[6*i+1].w_float = x->link[i].mass1->posY;
+                vec[6*i+2].w_float = x->link[i].mass1->posZ;
+                vec[6*i+3].w_float = x->link[i].mass2->posX;
+                vec[6*i+4].w_float = x->link[i].mass2->posY;
+                vec[6*i+5].w_float = x->link[i].mass2->posZ;
+                
+            }
+            garray_redraw(a);
+        }
+    }
+    else 
+    if ( (argc==2) && (argv[0].a_type == A_SYMBOL) && (argv[1].a_type == A_SYMBOL) )
+    {
+        t_symbol *tab_name = atom_getsymbolarg(0, argc, argv);
+        if (!(a = (t_garray *)pd_findbyclass(tab_name, garray_class)))
+            pd_error(x, "%s: no such array", tab_name->s_name);
+        else if (!garray_getfloatwords(a, &vecsize, &vec))
+            pd_error(x, "%s: bad template for tabwrite", tab_name->s_name);
+        else
+        {    
+            i = 0;
+            j = 0;
+            while ((i < vecsize-6) && (j < x->nb_link))
+            {
+                if (atom_getsymbolarg(1,argc,argv) == x->link[j].Id)
+                {
+                    vec[i].w_float = x->link[j].mass1->posX;
+                    i++;
+                    vec[i].w_float = x->link[j].mass1->posY;
+                    i++;
+                    vec[i].w_float = x->link[j].mass1->posZ;
+                    i++;
+                    vec[i].w_float = x->link[j].mass2->posX;
+                    i++;
+                    vec[i].w_float = x->link[j].mass2->posY;
+                    i++;
+                    vec[i].w_float = x->link[j].mass2->posZ;
+                    i++;
+                }
+                j++;
+            }
+            garray_redraw(a);
+        }
+    }
+}
diff --git a/pmpd3d_various.c b/pmpd3d_various.c
new file mode 100644
index 0000000..68346c4
--- /dev/null
+++ b/pmpd3d_various.c
@@ -0,0 +1,502 @@
+
+void pmpd3d_infosL(t_pmpd3d *x)
+{
+    int i;
+    post("list of mass");
+    post("number, Id, mobile, mass, Damping, positionX Y Z, speedX Y Z, forcesX Y Z");
+    for(i=0; i < x->nb_mass; i++)
+    {
+        post("masse %i: %s, %d, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f",i, x->mass[i].Id->s_name, \
+            x->mass[i].mobile, 1/x->mass[i].invM, x->mass[i].D2, x->mass[i].posX, x->mass[i].posY, \
+            x->mass[i].posZ, x->mass[i].speedX, x->mass[i].speedY, x->mass[i].speedZ, \
+            x->mass[i].forceX, x->mass[i].forceY, x->mass[i].forceZ );
+    }
+
+    post("list of link");
+    post("number, Id, mass1, mass2, K, D, Pow, L, Lmin, Lmax");
+    for(i=0; i < x->nb_link; i++)
+    {    
+        switch (x->link[i].lType)
+        {
+        case 0:
+            post("link %i: %s, %i, %i, %f, %f, %f, %f, %f, %f", i, x->link[i].Id->s_name, \
+                x->link[i].mass1->num, x->link[i].mass2->num, x->link[i].K, x->link[i].D, \
+                x->link[i].Pow, x->link[i].L, x->link[i].Lmin, x->link[i].Lmax);
+            break;
+        case 1:
+            post("tLink %i: %s, %i, %i, %f, %f, %f, %f, %f, %f, %f, %f, %f", i, x->link[i].Id->s_name, \
+                x->link[i].mass1->num, x->link[i].mass2->num, x->link[i].K, x->link[i].D, \
+                x->link[i].Pow, x->link[i].L, x->link[i].Lmin, x->link[i].Lmax, \
+                x->link[i].VX, x->link[i].VY, x->link[i].VZ);
+            break;
+        case 2:
+            post("tabLink %i: %s, %i, %i, %f, %f, %s, %f, %s, %f", i, x->link[i].Id->s_name, \
+                x->link[i].mass1->num, x->link[i].mass2->num, x->link[i].K, x->link[i].D, \
+                x->link[i].arrayK->s_name, x->link[i].K_L, x->link[i].arrayD->s_name, x->link[i].D_L);
+            break;        
+        }
+    }
+}
+
+void pmpd3d_force(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].forceX += atom_getfloatarg(1, argc, argv);
+        x->mass[tmp].forceY += atom_getfloatarg(2, argc, argv);
+        x->mass[tmp].forceZ += atom_getfloatarg(3, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].forceX += atom_getfloatarg(1, argc, argv);
+                x->mass[i].forceY += atom_getfloatarg(2, argc, argv);
+                x->mass[i].forceZ += atom_getfloatarg(3, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_forceX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].forceX += atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].forceX += atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_forceY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].forceY += atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].forceY += atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_forceZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// add a force to a specific mass
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].forceZ += atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].forceZ += atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_pos(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// displace a mass to a certain position
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].posX = atom_getfloatarg(1, argc, argv);
+           x->mass[tmp].speedX = 0; 
+        x->mass[tmp].forceX = 0; 
+           x->mass[tmp].posY = atom_getfloatarg(2, argc, argv);
+           x->mass[tmp].speedY = 0; 
+        x->mass[tmp].forceY = 0;
+           x->mass[tmp].posZ = atom_getfloatarg(3, argc, argv);
+           x->mass[tmp].speedZ = 0; 
+        x->mass[tmp].forceZ = 0; 
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].posX = atom_getfloatarg(1, argc, argv);
+                x->mass[i].speedX = 0; 
+                x->mass[i].forceX = 0;
+                x->mass[i].posY = atom_getfloatarg(2, argc, argv);
+                x->mass[i].speedY = 0; 
+                x->mass[i].forceY = 0;
+                x->mass[i].posZ = atom_getfloatarg(3, argc, argv);
+                x->mass[i].speedZ = 0; 
+                x->mass[i].forceZ = 0;
+            }
+        }
+    }
+}
+
+void pmpd3d_posX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// displace a mass to a certain position
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].posX = atom_getfloatarg(1, argc, argv);
+           x->mass[tmp].speedX = 0; 
+        x->mass[tmp].forceX = 0; 
+        
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].posX = atom_getfloatarg(1, argc, argv);
+                x->mass[i].speedX = 0; 
+                x->mass[i].forceX = 0;
+
+            }
+        }
+    }
+}
+
+void pmpd3d_posY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// displace a mass to a certain position
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].posY = atom_getfloatarg(1, argc, argv);
+           x->mass[tmp].speedY = 0; 
+        x->mass[tmp].forceY = 0; 
+        
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].posY = atom_getfloatarg(1, argc, argv);
+                x->mass[i].speedY = 0; 
+                x->mass[i].forceY = 0;
+            }
+        }
+    }
+}
+
+void pmpd3d_posZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+// displace a mass to a certain position
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].posZ = atom_getfloatarg(1, argc, argv);
+           x->mass[tmp].speedZ = 0; 
+        x->mass[tmp].forceZ = 0; 
+        
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].posZ = atom_getfloatarg(1, argc, argv);
+                x->mass[i].speedZ = 0; 
+                x->mass[i].forceZ = 0;
+            }
+        }
+    }
+}
+
+void pmpd3d_min(t_pmpd3d *x, t_float minX, t_float minY, t_float minZ)
+{
+    x->minX = minX;
+    x->minY = minY;
+    x->minZ = minZ;
+}
+
+void pmpd3d_max(t_pmpd3d *x, t_float maxX, t_float maxY, t_float maxZ)
+{
+    x->maxX = maxX;
+    x->maxY = maxY;
+    x->maxZ = maxZ;
+}
+
+void pmpd3d_minX(t_pmpd3d *x, t_float min)
+{
+    x->minX = min;
+}
+
+void pmpd3d_maxX(t_pmpd3d *x, t_float max)
+{
+    x->maxX = max;
+}
+
+void pmpd3d_minY(t_pmpd3d *x, t_float min)
+{
+    x->minY = min;
+}
+
+void pmpd3d_maxY(t_pmpd3d *x, t_float max)
+{
+    x->maxY = max;
+}
+
+void pmpd3d_minZ(t_pmpd3d *x, t_float min)
+{
+    x->minZ = min;
+}
+
+void pmpd3d_maxZ(t_pmpd3d *x, t_float max)
+{
+    x->maxZ = max;
+}
+
+void pmpd3d_addPos(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].posX += atom_getfloatarg(1, argc, argv);
+        x->mass[tmp].posY += atom_getfloatarg(2, argc, argv);
+        x->mass[tmp].posZ += atom_getfloatarg(3, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) && ( argv[2].a_type == A_FLOAT ) && ( argv[3].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].posX += atom_getfloatarg(1, argc, argv);
+                x->mass[i].posY += atom_getfloatarg(2, argc, argv);
+                x->mass[i].posZ += atom_getfloatarg(3, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_addPosX(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].posX += atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].posX += atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_addPosY(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].posY += atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].posY += atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_addPosZ(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int tmp, i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        tmp = atom_getfloatarg(0, argc, argv);
+        tmp = max(0, min( x->nb_mass-1, tmp));
+        x->mass[tmp].posZ += atom_getfloatarg(1, argc, argv);
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_mass; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->mass[i].Id)
+            {
+                x->mass[i].posZ += atom_getfloatarg(1, argc, argv);
+            }
+        }
+    }
+}
+
+void pmpd3d_grabMass(t_pmpd3d *x, t_float posX, t_float posY, t_float posZ, t_float grab)
+{
+    t_float dist, tmp;
+    t_int i;
+    
+    if (grab == 0)
+        x->grab=0;
+    if ((x->grab == 0)&(grab == 1)&(x->nb_mass > 0))
+    {
+        x->grab=1;
+        x->grab_nb= 0;
+        dist = sqr(x->mass[0].posX - posX) + sqr(x->mass[0].posY - posY) + sqr(x->mass[0].posZ - posZ);
+        for (i=1; i<x->nb_mass; i++)
+        {
+            tmp = sqr(x->mass[i].posX - posX) + sqr(x->mass[i].posY - posY) + sqr(x->mass[i].posZ - posZ);
+            if (tmp < dist)
+            {
+                dist = tmp;
+                x->grab_nb= i;
+            }
+        }
+    }
+    if (x->grab == 1)
+    {
+        x->mass[x->grab_nb].posX = posX;
+        x->mass[x->grab_nb].posY = posY;        
+        x->mass[x->grab_nb].posZ = posZ;        
+    }
+}
+
+void pmpd3d_closestMass(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    t_float dist, tmp;
+    t_int i;
+    t_atom std_out[4];
+
+    t_float posX, posY, posZ;
+    posX = atom_getfloatarg(0, argc, argv);
+    posY = atom_getfloatarg(1, argc, argv);    
+    posZ = atom_getfloatarg(2, argc, argv);    
+    if ( (argc == 4)  && (argv[3].a_type == A_SYMBOL) )
+    {
+        //t_symbol *mass_name = atom_getsymbolarg(2, argc, argv);
+        if ((x->nb_mass > 0))
+        {
+            dist = 1000000000;//sqr(x->mass[0].posX - posX) + sqr(x->mass[0].posY - posY);
+            for (i=0; i<x->nb_mass; i++)
+            {
+                if (atom_getsymbolarg(3,argc,argv) == x->mass[i].Id)
+                {
+                    tmp = sqr(x->mass[i].posX - posX) + sqr(x->mass[i].posY - posY) + sqr(x->mass[i].posZ - posZ);
+                    if (tmp < dist)
+                    {
+                        dist = tmp;
+                        x->grab_nb= i;
+                    }
+                }
+            }
+        }
+    }
+    else {
+        if ((x->nb_mass > 0))
+        {
+            dist = sqr(x->mass[0].posX - posX) + sqr(x->mass[0].posY - posY) + sqr(x->mass[0].posZ - posZ);
+            for (i=1; i<x->nb_mass; i++)
+            {
+                tmp = sqr(x->mass[i].posX - posX) + sqr(x->mass[i].posY - posY) + sqr(x->mass[i].posZ - posZ);
+                if (tmp < dist)
+                {
+                    dist = tmp;
+                    x->grab_nb= i;
+                }
+            }
+        }
+    }
+    
+    SETFLOAT(&(std_out[0]),x->grab_nb);
+    SETFLOAT(&(std_out[1]), x->mass[x->grab_nb].posX);
+    SETFLOAT(&(std_out[2]), x->mass[x->grab_nb].posY);
+    SETFLOAT(&(std_out[3]), x->mass[x->grab_nb].posZ);
+    outlet_anything(x->main_outlet, gensym("closestMass"),4,std_out);
+    
+}
+
+void pmpd3d_adaptLength(t_pmpd3d *x, t_symbol *s, int argc, t_atom *argv)
+{
+    int i;
+
+    if ( ( argv[0].a_type == A_FLOAT ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        i = atom_getfloatarg(0, argc, argv);
+        i = max(0, min( x->nb_link-1, i));
+        x->link[i].L = mix(x->link[i].L,x->link[i].distance,atom_getfloatarg(1, argc, argv));
+    }
+    if ( ( argv[0].a_type == A_SYMBOL ) && ( argv[1].a_type == A_FLOAT ) )
+    {
+        for (i=0; i< x->nb_link; i++)
+        {
+            if ( atom_getsymbolarg(0,argc,argv) == x->link[i].Id)
+            {
+                x->link[i].L = mix(x->link[i].L,x->link[i].distance,atom_getfloatarg(1, argc, argv));
+            }
+        }
+    }
+}
+
-- 
cgit v1.2.1