# pushMatrix() cannot use push more than 32 times

**URL:** <https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860>\
**Category:** Coding Questions\
**Created:** [July 21, 2019, 11:59am UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860 "2019-07-21T11:59:11Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![mezhaka](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mezhaka/32/5592_2.png) [@mezhaka](https://discourse.processing.org/u/mezhaka)\
**Post date:** [July 21, 2019, 11:59am UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/1 "2019-07-21T11:59:11Z")

</div>

Why is this not a valid patch?  
I get a “RuntimeException: pushMatrix() cannot use push more than 32 times” error in a snippet that seems perfectly valid for me:

```auto
void setup() {
  size(700, 500);
}
        
    
void draw() {
  fill(0);
  rect(0, 0, width, height);
  int N = 33;
  fill(255);
  for (int i = 0; i < N; ++i) {
    pushMatrix();
    translate(0, 15);
    rect(0, 0, 5, 5);
  }
  for (int i = 0; i < N; ++i) {
    popMatrix();
  }
}

```

Is this a known thing? Am I not supposed to use the pushMatrix-translate-popMatrix idiom when I juggle more than 32 objects?

---

<div class="post-metadata">

**Author:** ![InferNova](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/infernova/32/6009_2.png) [@InferNova](https://discourse.processing.org/u/InferNova)\
**Post date:** [July 21, 2019, 12:46pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/2 "2019-07-21T12:46:10Z")

</div>

Hey There !  
Wouldn’t you just keep Push and Pop within `draw()` ? And all objects between them would be affected ?

---

<div class="post-metadata">

**Author:** ![mezhaka](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mezhaka/32/5592_2.png) [@mezhaka](https://discourse.processing.org/u/mezhaka)\
**Post date:** [July 21, 2019, 1:26pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/3 "2019-07-21T13:26:59Z")

</div>

Sorry, I don’t understand your wording. Could you, please, rephrase your answer?

There’s an equal amount of push and pop operations within draw function.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [July 21, 2019, 1:34pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/4 "2019-07-21T13:34:27Z")

</div>

Hello,

From what I have gleaned there is a limit of 32.

[https://forum.processing.org/one/topic/pushmatrix-popmatrix-depth-extension.html](https://forum.processing.org/one/topic/pushmatrix-popmatrix-depth-extension.html)

> <https://github.com/processing/processing/blob/master/core/src/processing/core/PGraphics.java>

  
“static final protected int MATRIX\_STACK\_DEPTH = 32;”

🙂

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [July 21, 2019, 2:05pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/5 "2019-07-21T14:05:25Z")

</div>

> <https://github.com/processing/processing/blob/processing-0269-3.5.3/core/src/processing/core/PGraphics.java#L530-L531>

  

> <https://github.com/processing/processing/blob/processing-0269-3.5.3/core/src/processing/awt/PGraphicsJava2D.java#L85-L86>

  

> <https://github.com/processing/processing/blob/processing-0269-3.5.3/core/src/processing/awt/PGraphicsJava2D.java#L2141-L2149>

```auto
/**
 * Change PGraphics Max Pushes (v1.0)
 * GoToLoop (2019/Jul/21)
 *
 * https://Discourse.Processing.org/t/
 * pushmatrix-cannot-use-push-more-than-32-times/12860/5
 */

import processing.awt.PGraphicsJava2D;
import java.lang.reflect.Field;

static final int PUSHES = 35, DIAM = 8, OFFSET_Y = 15;

void setup() {
  size(100, 550);
  noLoop();

  fill(#FFFF00);
  stroke(#FF0000);

  setMaxPushes((PGraphicsJava2D) getGraphics(), PUSHES);
}

void draw() {
  clear();

  for (int i = 0; i < PUSHES; ++i) {
    pushMatrix();
    translate(0, OFFSET_Y);
    square(0, 0, DIAM);
  }

  for (int i = 0; i < PUSHES; ++i) popMatrix();
}

static final void setMaxPushes(final PGraphicsJava2D pg, final int pushes) {
  try {
    final Field f = PGraphicsJava2D.class.getDeclaredField("transformStack");
    f.setAccessible(true);
    f.set(pg, expand(f.get(pg), abs(pushes)));
  }
  catch (final ReflectiveOperationException ex) {
    throw new RuntimeException(ex);
  }
}

```

---

<div class="post-metadata">

**Author:** ![InferNova](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/infernova/32/6009_2.png) [@InferNova](https://discourse.processing.org/u/InferNova)\
**Post date:** [July 21, 2019, 2:08pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/6 "2019-07-21T14:08:09Z")

</div>

Do not use pushMatrix within the for loops. But only have it within the draw loop.

---

<div class="post-metadata">

**Author:** ![mezhaka](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mezhaka/32/5592_2.png) [@mezhaka](https://discourse.processing.org/u/mezhaka)\
**Post date:** [July 21, 2019, 5:04pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/7 "2019-07-21T17:04:08Z")

</div>

@GoToLoop @glv Thanks for digging it out. Is this a crucial constant? Can we bump it to something higher (e.g. 256)?

I find it a bit odd that I cannot do many transformations. The tutorial here:  
[https://processing.org/tutorials/transform2d/](https://processing.org/tutorials/transform2d/) describes how I can draw a house using push-translate-pop. So if the house has more than 32 parts, this is not possible. Same if I want to translate and draw some elements relative to each other. I redid a bit of my code to use the absolute coordinate system instead, but the idiom is very neat to use, pity I had to give it up.

---

<div class="post-metadata">

**Author:** ![mezhaka](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mezhaka/32/5592_2.png) [@mezhaka](https://discourse.processing.org/u/mezhaka)\
**Post date:** [July 21, 2019, 5:04pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/8 "2019-07-21T17:04:51Z")

</div>

I don’t understand you still – the loops are in the draw function – could you make an example snippet of what you mean?

How do else could you use pushMatrix in the draw to draw more than 32 objects?

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [July 21, 2019, 5:19pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/9 "2019-07-21T17:19:56Z")

</div>

`pushMatrix` and `popMatrix` come as a pair and should not be used in separate loops. This program demonstrates how they might be used correctly.

```auto
float[] x, y, w, h;
int n = 30;

void setup() {
  size(400, 320);
  x = new float[n];
  y = new float[n];
  w = new float[n];
  h = new float[n];
  for (int i = 0; i < n; i++) {
    x[i] = (int) random(10, width - 40);
    y[i] = (int) random(10, height - 40);
    w[i] = (int) random(15, 35);
    h[i] = (int) random(10, 25);
  }
}

void draw() {
  background(0);
  fill(255, 50, 50);
  strokeWeight(2);
  stroke(255, 255, 0);
  for (int i = 0; i < n; ++i) {
    pushMatrix();
    translate(x[i], y[i]);
    rect(0, 0, w[i], h[1]);
    popMatrix();
  }
}

```

---

<div class="post-metadata">

**Author:** ![InferNova](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/infernova/32/6009_2.png) [@InferNova](https://discourse.processing.org/u/InferNova)\
**Post date:** [July 21, 2019, 5:24pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/10 "2019-07-21T17:24:29Z")

</div>

I was thinking about something like this. Still seems to behave correctly?

```auto
void setup() {
  size(700, 500);
}

void draw() {
  fill(0);
  rect(0, 0, width, height);
  int N = 34;
  fill(255);
  pushMatrix();
  for (int i = 0; i < N; ++i) {
    translate(0, 15);
    rect(0, 0, 5, 5);
  }
  popMatrix();
}

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [July 21, 2019, 5:55pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/11 "2019-07-21T17:55:28Z")

</div>

> [@mezhaka](#):
>
> Can we bump it to something higher (e.g. 256)?

Just try it! Change `static final int PUSHES = 35;` to `static final int PUSHES = 256;`. 😉

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [July 21, 2019, 6:25pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/12 "2019-07-21T18:25:40Z")

</div>

Your original example had 32 “nested” push\pops.  
An example in a loop of 2500 push\pops that are NOT nested:

```auto
int inc = 0;

void setup()
  {
  size(1020, 1020, P2D);
  ortho();
  }

void draw()
  {
  background(0);
  noStroke();
  lights();
  fill(255, 255, 0);
  int num= 50;
  for (int i = 0; i< num*num; i++)
    {
    pushMatrix();
    int x = i%num*20+20;
    if (i%num == 0)
      inc ++;  
    int y = inc*20;
    translate(x, y);
    rotate(TAU/8);
    rectMode(CENTER);
    rect(0, 0, 10, 10);
    popMatrix();
    }
  inc = 0;
  println(frameRate);
  }

```

🙂

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [July 21, 2019, 6:50pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/13 "2019-07-21T18:50:42Z")

</div>

Here is another example where they are all rotating:

```auto
int inc = 0;
float th = 0;

void setup()
  {
  size(1020, 1020, P3D);
  ortho();
  }

void draw()
  {
  background(0);
  noStroke();
  lights();
  fill(255, 255, 0);
  th += TAU/300;  
  
  int num= 50;
  for (int i = 0; i< num*num; i++)
    {
    pushMatrix();
    int x = i%num*20+20;
    if (i%num == 0)
      inc ++;  
    int y = inc*20;
    translate(x, y);
    rotateX(th);
    rotateY(th);
// rectMode(CENTER);
// rect(0, 0, 10, 10);
    box(10, 10, 10);
    popMatrix();
    }
  inc = 0;
  //println(frameRate);
  }

```

Over 2500 or so and my frame rates started to drop below 60 fps.

Also, I use println() for debugging but displaying frameRate() every loop you can miss important console messages at start.

This will fix that:

```auto
  if ((frameCount>300) && (frameCount%60 == 0))
    println(frameRate);

```

Example of “messages” when I was using P2D mode when I should have been using P3D.  
Sketch still ran but was a blank screen!

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/c5dc6b94dea5a0ed772a18f30ecc2f81265d518e.png)

🙂

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [July 21, 2019, 8:48pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/14 "2019-07-21T20:48:26Z")

</div>

For those who might wonder how to pull that out in Python Mode, here’s the converted sketch for it: 🐍

```auto
"""
 * Change PGraphics Max Pushes (v1.0)
 * GoToLoop (2019/Jul/21)
 *
 * https://Discourse.Processing.org/t/
 * pushmatrix-cannot-use-push-more-than-32-times/12860/14
"""

PUSHES, DIAM, OFFSET_Y = 35, 8, 15
PUSHES_RANGE = tuple(range(PUSHES))

def setup():
    size(100, 550)
    noLoop()

    fill(0xffFFFF00)
    stroke(0xffFF0000)

    setMaxPushes(this.getGraphics(), PUSHES)

def draw():
    clear()

    for i in PUSHES_RANGE:
        pushMatrix()
        translate(0, OFFSET_Y)
        square(0, 0, DIAM)

    for i in PUSHES_RANGE: popMatrix()

def setMaxPushes(pg, pushes):
    pg.transformStack = expand(pg.transformStack, abs(pushes))

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [July 21, 2019, 9:14pm UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/15 "2019-07-21T21:14:43Z")

</div>

“Wonder is the beginning of wisdom” - Socrates

This post was a classic:

> **[Processing 2.x and 3.x Forum](https://forum.processing.org/two/discussion/comment/17956/#Comment_17956)**
>
> Processing is an electronic sketchbook, a language and a worldwide community. This is its forum.

Thanks! It really helped me at that time.

glv

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [July 24, 2019, 9:53am UTC](https://discourse.processing.org/t/pushmatrix-cannot-use-push-more-than-32-times/12860/16 "2019-07-24T09:53:25Z")

</div>

> [@mezhaka](#):
>
> Am I not supposed to use the pushMatrix-translate-popMatrix idiom when I juggle more than 32 objects?

In your case, you definitely should not.

Here is an example of what you want:

y = 5 + 4 - 2 + 7 - 4 - 5 + 1  
…, then, to pop back to 5 when you are done.

You are doing that like this:

y = 5 push + 4 push - 2 push + 7 push - 4 push - 5 push + 1 pop pop pop pop pop pop  
= 5

…but you could just do this:

y = 5 push + 4 - 2 + 7 - 4 - 5 + 1 pop  
= 5

```auto
pushMatrix();
for (int i = 0; i < N; ++i) {
  translate(0, 15);
  rect(0, 0, 5, 5);
}
popMatrix();

```

Push isn’t for every transformation you make. It saves every place in a transformation stream that you want to **back out to** and re-branch from. You could make 100 story skyscrapers with thousands of complex components per story, and you might only need to push 3 levels deep–(building(floor(window))). The solar system has lots of objects with nested relative rotations, but you don’t push a new level for each object – any satellite of a moon of a moon of a planet around the sun is still only a few levels deep.

```auto
sun
push
  Earth
  push
    moon
    push
       moonsat1
    pop
    push
       moonsat2
    pop
  pop
  push
    spacestation
  pop
pop
push
  Venus
pop

```

So, if there is a wart on a frog on a bump on a log in a hole in the bottom of the sea, you only need to push seven deep – even if there are seven seas, dozens of holes, hundreds of logs … a thousands frogs, and millions of warts. Growing random branches on the logs and pushing 4000 relative frog legs still only takes you to 9 deep.

The matrix stack is also relatively expensive way of tracking transforms if you aren’t doing rotation or scaling–it is heavy duty and general purpose. If you really need to walk and unwind translate statements nested 300 deep–like some kind of relative fractal–consider something like an `ArrayDeque<PVector>`

[https://docs.oracle.com/javase/8/docs/api/java/util/ArrayDeque.html](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayDeque.html)
