Tried to add unary force to goal in Kangaroo, not working, (KangarooSolver.dll &RhinoCommon)

I am trying to start with KangarooSolver.dll. Unery force need to be added. But it is not working.
Did I write it wrong?

//initialize the solver
var PS = new KangarooSolver.PhysicalSystem();
var Goals = new List();

        //get the Mesh points and boundary status
        Point3d[] Pts = M.Vertices.ToPoint3dArray();
        bool[] Naked = M.GetNakedEdgePointStatus();

        for (int i = 0; i < M.Vertices.Count; i++)
            PS.AddParticle(Pts[i], 1); //add a particle for every mesh vertex
            if (Naked[i] == true && i % 10 == 0) 
            { Goals.Add(new KangarooSolver.Goals.Anchor(i, Pts[i], 10000)); }// fix the boundaries strongly in place
          Vector3d vt = new Vector3d(0,0,-1);
          if (Naked[i] == false)
              Goals.Add(new KangarooSolver.Goals.Unary(Pts[i],vt));

        for (int i = 0; i < M.TopologyEdges.Count; i++)
            var Ends = M.TopologyEdges.GetTopologyVertices(i);
            int Start = M.TopologyVertices.MeshVertexIndices(Ends.I)[0];
            int End = M.TopologyVertices.MeshVertexIndices(Ends.J)[0];
            Goals.Add(new KangarooSolver.Goals.Spring(Start, End, 0, 1)); //for each edge, a spring with rest length 0, and strength 1

        int counter = 0;
        double threshold = 1e-6;
            //Step forward, using these goals, with multi-threading on, and stopping if the threshold is reached
            PS.Step(Goals, true, threshold);
        } while (PS.GetvSum() > threshold && counter < 100);
        //GetvSum returns the current kinetic energy
        //always include a counter to prevent it getting stuck forever in case it cannot reach the given threshold

        //replace the mesh vertices with the relaxed ones

        //Output the mesh, and how many iterations it took to converge
        Mesh A = M;
        //B = counter;

Hi tsiddikee,

It looks like the issue here is that the Unary goals have not had their particle indexes assigned.

When the simulation actually runs, it has a list of particles, and each goal has integer indexes dictating which of the particles that goal acts on. However, there are 2 ways of setting these indexes - a manual version and a more automatic one:
When you add a new goal to the Goals list, you can either specify this index directly, or you can just provide the positions of the particles it acts on, and let Kangaroo figure out the topology by calling PhysicalSystem.AssignPIndex before starting to step the simulation. This function takes the positions of each goal, and searches the existing particles to see if there is one in the same place. If there is, the index of that particle becomes the index of the goal, and if not a new particle is added there.

The TensileRelax example you are adapting was using the first method - Have a look at one of the other scripting examples ( or for an example of specifying goals by position instead of directly setting indexes.

I hope this is helpful.


Dear Daniel,
Many thanks for the explanation. It is a big help !
Best regards