Recursion based on pathnumber C#

Hi everyone,

I am working on a pathnumber based subdivision these days.
The idea is the following:

A tree of meshFaces :
{0} = no subdivison
{1} = 1 time subdivide
{2} = 2 times subdivide

I got it mostly working when I use a meshplane,just some rectanlges do not subdivide all of the 4:
grafik

But the strange thing is that the same code on a meshsphere throws an index out of array exception
Or propably its not strange and my attempt is just really poor

My main code is this:

for (int k = 0; k < meshTree.BranchCount; k++)
    {
      for (int i = 0; i < meshTree.BranchCount; i++)
      {
        //get PathNumber
        char[] charsToTrim = { '{','}'};
        string path = meshTree.Path(i).ToString();
        string pathNumber = path.Trim(charsToTrim);
        int pth = int.Parse(pathNumber);
        //subdivide
        if (pth > 0)
        {
          for (int j = 0;  j < meshTree.Branch(i).Count;  j++)
          {
            meshTree.AddRange(MakeSubD(meshTree.Branch(i)[j]), new GH_Path(pth - 1));
            meshTree.Branch(i).RemoveAt(j);
          }
        }
      }
    }

    A = meshTree;

Maybe someone has the patience to help me with that one.


Thanks everyone and have a nice weekend!

20200208_SubdivideMeshPathForum.gh (10.7 KB)

It is because mesh spheres have triangle faces at the poles. Your code only accounts for quad faces so when it hits a triangle face and your code gets to Mesh face3 which calls face3.Vertices.Add(msh.Vertices[3]); there is no Vertice[3] for it. You need to either omit triangle faces or make a condition for them.

1 Like

Thank you Michael!

I should defenitly do more exception handling.

Probably doing the same in vs would have been easier to debug, stepping in the code.next time will try this before ask here.

Thanks again!

Do you maybe also know how to remove the Meshface I subdivided from the tree, so that they arent overlaying?

for (int j = 0;  j < meshTree.Branch(i).Count;  j++)
          {
            meshTree.AddRange(MakeSubD(meshTree.Branch(i)[j]), new GH_Path(pth - 1));
            meshTree.Branch(i).RemoveAt(j); // how to remove it here?
          }

Thanks!

See attached (and modify it accordingly with regard the grid - if you are after Meshes, Surface pieces, cats, dogs etc etc).

Recursive_DivideGrid_EntryLevel_V1A.gh (118.6 KB)

1 Like

Thanks Peter, that’s it!

I need to get my head wrapped around the move in the void function. I’ll play around with that this weekend, hopefully I can understand it .

Here’s the next step on that (a good challenge on LINQ matters and the likes):

Go from this:

To that:

Then imagine that you want to do a “sheet” like combo from all the distorted pieces. So you need to add “diaphragms” so to speak. These are (a) main (with regard module to module [footprint defined by the x, y, pos by 0-xc, 0-yc values]) and (b) secondary (what happens inside the module: the results of the recursive Divide() Method). Here’s the main ones:

So be brave and do it (prior that read what LINQ is about).

PS: A void Method returns nothing. So it has sense if stuff inside is declared public (or privet in some class). By accident this is the way to go in recursion in order to avoid locomotive size Method calls. For some mysterious reasons NASA gurus recommend avoiding recursion at any cost.

PS: In this case the divList is public (and the Loop, Loops) so is not very clear what the public policy is all about. But in other cases you may have lot’s of related vars …

… like in this Solve() Method (related with some freaky truss) where 22 variables are involved:

Hey Peter,

thanks for the hints!
In order to understand the void thingy I am trying to do some other stuff on meshes.
Crashing Rhino constantly, but I am on the way, hehe.

If you can wrap your head into changing recursion with iterations as the Dark Lord says, you will have less stack overflows. Unfortunately C# doesn’t support tail recursion out of the box but there’s Trampolining

Given the opportunity, here’s an entry level veeeeeeeery simple thingy (using the trampoline moniker rather optimistically) with regard bounce solving - but in real life Dcurr and Tcurr are implicitly known meaning that the if comparisons are not like the ones used (life sucks).

Recursion_BounceTrampoline_V1.gh (51.7 KB)

You could even try the most simplest of tests and a very popular one as well.

Compute the Nth number in the Fibonacci sequence recursively and iteratively and the difference is huge.
In general recursion does not perform well under many iterations because It produces many method calls, causing your stack memory to suffer some serious pain. Methods are always saved on the stack when called upon. While in a iterative solution you will only need to allocate your method a single time on the stack. The rest will depend on the complexity time that your algorithm is running at.

For example:

int64_t FibonnacciIterative(int n)
{
	if (n == 0 || n == 1) return n;

	int64_t a=0, b=1, c=1;
	for (int i = 0; i < n; i++)
	{
		a = b;
		b = c;
		c = a + b;
	}
	return a;
}


int64_t FibonnaciRecursive(int n)
{
	if (n == 0 || n == 1) return n;

	return fibonnaciRecursive(n - 1) + fibonnaciRecursive(n - 2);
}

computing the 50th term:

Capture

So the recursive version takes almost 1 minute while the iterative one is basically instantaneous…

Is it?

See attached (for Plan C).

Recursion_FiboNumber_V1.gh (7.7 KB)

Very elegant indeed, thanks for introducing it. No need to save so much junk on the stack.

 ulong FactorialTailRecursive(ulong n, ulong a=1)
  {
    if (n == 0) return a;    
    return FactorialTailRecursive(n - 1, n * a);  
  }
  
  ulong FactorialRecursive(ulong n)
  {
    if (n == 1) return n ;   
    return FactorialRecursive(n - 1)*n;  
  }

slicing out FactorialTailRecursive(4,1) would be


1. 4,4
2. 3,12
3. 2,24
4. 1,24
5. 0,24 --> returns 24. 

As another fun fact… C# took 7.6 min to compute the 50th fibonacci term recursively against the 51.9 seconds of C++

Thats why I love C++ , maybe soon I will try to certify myself in that beautiful language

If you are after games then C++ makes some sense. If you are in AEC stick to C#. If you are after dollars marry a rich girl, buy a proper Lambo (a Balboni, what else?) and forget all that.

1 Like

Peter, both would be good to have.

Marry a rich girl or write them transpilers that do C# to C++?