# Copying a PShape?

**URL:** <https://discourse.processing.org/t/copying-a-pshape/1081>\
**Category:** Coding Questions\
**Created:** [June 19, 2018, 2:13pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081 "2018-06-19T14:13:40Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Carmine](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/carmine/32/480_2.png) [@Carmine](https://discourse.processing.org/u/Carmine)\
**Post date:** [June 19, 2018, 2:13pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/1 "2018-06-19T14:13:40Z")

</div>

If I want to have several of the same 3D model (.obj file loaded), is there a way to to load it once and then copy that PShape. I want to avoid several calls to loadFile.

-Carmine

---

<div class="post-metadata">

**Author:** ![Stephcraft](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/stephcraft/32/22024_2.png) [@Stephcraft](https://discourse.processing.org/u/Stephcraft)\
**Post date:** [June 19, 2018, 4:21pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/2 "2018-06-19T16:21:10Z")

</div>

```auto
PShape shape;
PShape shape1;
PShape shape2;

void setup() {

// load once
shape = loadShape("path/to/shape.obj");

// Same shape now in 3 PShapes
// Note that if you modify any of shape, shape1 and shape2 they will all be modified
shape1 = shape;
shape2 = shape;

// To avoid to have same instance in 3 variables, use this 'copy' trick
// Put shape as a child in a GROUP shape
shape1 = createShape(GROUP);
shape1.addChild(shape);

shape2 = createShape(GROUP);
shape2.addChild(shape);

}

void draw() {

//If you only need to show 3 of the same shape just call shape multiple times with the same shape
pushMatrix();
translate(0, 0, 0);
shape(shape);
translate(100, 0, 0);
shape(shape);
translate(100, 0, 0);
popMatrix();

}

```

There is no function like shape.copy() for the moment so you can’t entirely copy a PShape.  
If you really want a complete copy, this is the way, but it is slow because we rebuild the shape :

```auto
PShape clone(PShape obj) {
  PShape shape = createShape();
  shape.beginShape();
  
  for(int i=0; i<obj.getVertexCount(); i++) {
    PVector vertex = obj.getVertex(i);

    obj.vertex(vertex.x, vertex.y, vertex.z);
  }

  shape.endShape();

  return shape;
}

```

You will need to iterate `obj.getChildCount()` and `obj.getChild(i).getVertexCount()` if your shape contains child PShape

---

<div class="post-metadata">

**Author:** ![Kevin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kevin/32/2297_2.png) [@Kevin](https://discourse.processing.org/u/Kevin)\
**Post date:** [June 19, 2018, 4:23pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/3 "2018-06-19T16:23:41Z")

</div>

> [@Stephcraft](#):
>
> ```auto
> shape1 = createShape(GROUP); 
> shape1.addChild(shape);
> 
> ```

If you modify `shape`, will that be reflected when you draw `shape1`?

I’m not sure any of the available solutions are better than just loading the file multiple times.

---

<div class="post-metadata">

**Author:** ![Stephcraft](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/stephcraft/32/22024_2.png) [@Stephcraft](https://discourse.processing.org/u/Stephcraft)\
**Post date:** [June 19, 2018, 4:27pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/4 "2018-06-19T16:27:28Z")

</div>

Well a `PShape.copy()` would be the best solution here but it does not exist yet. It really depends on what you want to do, by putting the shape in a GROUP shape you now have acess to shape.translate(), shape.rotate() and shape.scale() whitout affecting the other shapes so it can help in some cases. But I think if you really want to modify a shape reconstruct it is faster than loading it i think.

---

<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:** [June 20, 2018, 4:17pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/5 "2018-06-20T16:17:06Z")

</div>

It looks like there is currently draft code in PShape for using createShape as a copy command, like this:

```
PShape newShape = createShape(oldShape);    

```

> <https://github.com/processing/processing/blob/d363bd3c98b2a0fccd43202b06174ebcca3a213d/core/src/processing/core/PShape.java#L1437-L1458>

---

<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:** [June 20, 2018, 7:58pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/6 "2018-06-20T19:58:56Z")

</div>

`static protected PShape createShape(PApplet parent, PShape src) {`

But they should stop limiting useful methods w/ `private` & `protected`! 👹

---

<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:** [June 20, 2018, 10:42pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/7 "2018-06-20T22:42:28Z")

</div>

I believe (?) the dev team philosophy is to only make public those methods that they intend to support – in general they don’t make public interface that they can’t (or can’t yet) commit to ongoing support for, so that changing things won’t break stuff in ways that makes development harder and generates support tickets about internals.

For those planning to fork Processing and make custom changes who still want to use the full PDE app, the build instructions are on the wiki, here:

> **[processing/processing](https://github.com/processing/processing/wiki/Build-Instructions)**
>
> Source code for the Processing Core and Development Environment (PDE) - processing/processing

I did a full custom build once when I really really wanted a custom `PGraphics` methods for a project and couldn’t get an extended class to integrate due to `createGraphics()`.

Note that for Mac you need to do the building _on_ a Mac.

If you are on Linux, you can even build in a Docker container if you want, like this:

```auto
# Dockerfile for building Processing PDE on Linux using ant/jdk8
FROM frekele/ant:1.10.3-jdk8
WORKDIR /root
RUN apt-get -y install git
# point at your altered fork here:
RUN git clone https://github.com/processing/processing.git --depth 1
WORKDIR /root/processing/build/
RUN ant clean
RUN ant build

```

---

<div class="post-metadata">

**Author:** ![Stephcraft](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/stephcraft/32/22024_2.png) [@Stephcraft](https://discourse.processing.org/u/Stephcraft)\
**Post date:** [June 21, 2018, 12:10am UTC](https://discourse.processing.org/t/copying-a-pshape/1081/8 "2018-06-21T00:10:28Z")

</div>

Here is a hack to access `protected` functions in classes 🙂

```auto
public static class PShapeAcess extends PShape {
  
  public static PShape copyShape(PApplet parent, PShape shape) {
    return createShape(parent, shape);
  }
  
}

PShape shape;
PShape shapeCopy;

public void setup() {
  
  // Copy the shape
  shapeCopy = PShapeAcess.copyShape(this, shape);
}

```

---

<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:** [June 21, 2018, 5:29am UTC](https://discourse.processing.org/t/copying-a-pshape/1081/9 "2018-06-21T05:29:48Z")

</div>

Interesting static copy class hack! The key problem I recall having with trying to extend PGraphics in a non-static way was that `createGraphics()` returned PGraphics – so extending PGraphics with new methods did me no good without also writing my own create method. In this case, however, all we want are PShapes, so the hack fits the bill even though `createShape()` and `loadShape()` would present similar problems if we were trying to add non-static methods.

Here is a full demo sketch of Stephcraft’s PShape copy hack. Keep in mind – protected, not supported, not documented = could break anytime!

```auto
PShape mySquare;
PShape mySquareCopy;

void setup() {
  mySquare = createShape(RECT, 0, 0, 50, 50);
  mySquareCopy = PShapeAccess.copyShape(this, mySquare);
  mySquareCopy.setFill(0);
  shape(mySquare, 10, 10);
  shape(mySquareCopy, 40, 40);
}

static class PShapeAccess extends PShape {
  static PShape copyShape(PApplet parent, PShape src) {
    return createShape(parent, src);
  }
}

```

---

<div class="post-metadata">

**Author:** ![picar](https://avatars.discourse-cdn.com/v4/letter/p/4491bb/32.png) [@picar](https://discourse.processing.org/u/picar)\
**Post date:** [January 15, 2026, 1:54am UTC](https://discourse.processing.org/t/copying-a-pshape/1081/10 "2026-01-15T01:54:09Z")

</div>

Is there any new to this topic yet?

unfortunately, the Hack is nice but not copy things like .setEmissive()

---

<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:** [January 16, 2026, 3:10pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/11 "2026-01-16T15:10:47Z")

</div>

> [@Carmine](#):
>
> If I want to have several of the same 3D model (.obj file loaded), is there a way to to load it once and then copy that PShape. I want to avoid several calls to loadFile.

This was the original question. There were a number of replies providing hacks into the Processing source code to overcome the `protected`, `private` access modifiers they were not completely successful.

> [@picar](#):
>
> Is there any new to this topic yet?

A good question but unfortunately the answer is no, despite this discussion being over 7½ years old the shape copy code is still marked as unapproved.

BUT there is good news I have a non-hackish and simple solution to the original question. To see it in action select the **File | Examples** menu option in the PDE and in the dialog box select the example **Basics | Shape | LoadDisplayOBJ** then **File | SaveAs** so you end up with an editable copy of the example with the OBJ file.

Now replace the entire example code with the sketch code below. and _bingo_ the `rocket.obj` file is only loaded once no matter how many rocket shape you want to create. 😀 👍

```java
/**
 * Load and Display an OBJ Shape.
 *
 * The loadShape() command is used to read simple SVG (Scalable Vector Graphics)
 * files and OBJ (Object) files into a Processing sketch. This example loads an
 * OBJ file of a rocket and displays it to the screen.
 */

PShape rocket, rocket2;
float ry;

public void setup() {
  size(640, 360, P3D);
  rocket = loadOBJ(this, "rocket.obj");
  rocket2 = loadOBJ(this, "rocket.obj");
}

public void draw() {
  background(0);
  lights();
  push();
  translate(width/6, height/2 + 100, -200);
  rotateZ(PI);
  rotateY(ry);
  shape(rocket);
  pop();
  push();
  translate(width*5/6, height/2 + 100, -200);
  rotateZ(PI);
  rotateY(ry*3);
  shape(rocket2);
  pop();
  ry += 0.02;
}

// ###########################################################################
// Load a 3D object from a '.obj' file. If a file is used multiple times it
// only loaded once.
// ###########################################################################

final HashMap<String, PShapeOBJ> OBJMAP = new HashMap<String, PShapeOBJ>();

public PShape loadOBJ(PApplet parent, String filename) {
  PGraphics pg = parent.getGraphics();
  PShapeOBJ obj = OBJMAP.get(filename);
  if (obj == null) { // File has not been previously loaded
    // load the object file
    int dot = filename.lastIndexOf(".");
    String ext = filename.substring(dot+1);
    if (ext.equalsIgnoreCase("obj")) {
      obj = new PShapeOBJ(parent, filename);
      OBJMAP.put(filename, obj);
    }
  }
  if (obj != null) {
    int prevTextureMode = pg.textureMode;
    pg.textureMode = NORMAL;
    PShapeOpenGL p3d = PShapeOpenGL.createShape((PGraphicsOpenGL)pg, obj);
    pg.textureMode = prevTextureMode;
    return p3d;
  }
  return null;
}

```

---

<div class="post-metadata">

**Author:** ![Carmine](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/carmine/32/480_2.png) [@Carmine](https://discourse.processing.org/u/Carmine)\
**Post date:** [January 16, 2026, 3:25pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/12 "2026-01-16T15:25:01Z")

</div>

Hey! I don’t even remember what I was working on at the time. But I wanted to say thank you for taking the time to reply to this 🙂

---

<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:** [January 17, 2026, 9:53am UTC](https://discourse.processing.org/t/copying-a-pshape/1081/14 "2026-01-17T09:53:45Z")

</div>

> [@quark](#):
>
> A good question but unfortunately the answer is no, despite this discussion being over 7½ years old the shape copy code is still marked as unapproved.

This wasn’t meant to be a criticism of the development team. I think that @jeremydouglass had it right with -

> [@jeremydouglass](#):
>
> I believe (?) the dev team philosophy is to only make public those methods that they intend to support – in general they don’t make public interface that they can’t (or can’t yet) commit to ongoing support for, so that changing things won’t break stuff in ways that makes development harder and generates support tickets about internals.

It can always be added to github as a feature request 😇

---

<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:** [January 18, 2026, 10:09pm UTC](https://discourse.processing.org/t/copying-a-pshape/1081/15 "2026-01-18T22:09:20Z")

</div>

> [@quark](#):
>
> It can always be added to github as a feature request 😇

I did a _quick search_ and there are a couple of issues in the old repository:

- [saveShape() for PShape · Issue #5103 · processing/processing · GitHub](https://github.com/processing/processing/issues/5103)
- [https://github.com/processing/processing/issues/1710](https://github.com/processing/processing/issues/1710)

I did not find them in the new Processing 4 repository:

[GitHub - processing/processing4: Source code for Processing, the software sketchbook and Java-based programming language for students, artists, designers, educators, hobbyists, and creative coders. Includes the core library, and editor (PDE)](https://github.com/processing/processing4)

I may certainly have missed something in my search.

Active participation from members is the foundation of this community.  
Let’s help the _Processing Foundation_ and this community by submitting an issue (enhancement).

`:-)`
