# Save a PShape on Hard Drive (please help)

**URL:** <https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389>\
**Category:** Libraries\
**Created:** [December 30, 2021, 11:22pm UTC](https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389 "2021-12-30T23:22:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [December 30, 2021, 11:22pm UTC](https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389/1 "2021-12-30T23:22:25Z")

</div>

hello all,

I am generating an PShape from a CSG (with JCSG) and wanted to ask whether I can **save** the PShape in one go.

like (pseudo code)

```auto
PShape myShape;
.......
myShape.save(sketchPath("")+"sample.obj");

```

Any ideas?

(too long for an mcve)

Didn’t find anything here: [PShape / Reference / Processing.org](https://processing.org/reference/PShape.html)

**What I tried**

What I tried is to save a CSG instead PShape: (see link below) (didn’t work)

```auto
  //-------
  // DIRECT COMMANDS 

  else if (key=='s') {

    // make PShape from cubes
    make_csgResult(); // one CORE function
    // save union as stl
    try {
      FileUtil.write(
        Paths.get(sketchPath("sample.obj")), 
        cubeResult.toObjString()
        );
    } 
    catch (IOException ex) {
      ex.printStackTrace();
    }//catch
  } // else if

  //
  else if (key=='l') {
    println("loading");
    //load shape into Processing
    csgResult = loadShape(sketchPath("sample.obj"));
    // change state 
    stateProgram = STATE_SHOW_PSHAPE;
  }

  //-------

```

* * *

**Background:**

For more information about what I mean with making a PShape from CSG :

see [java - Is it possible to use jcsg library with Processing? - Stack Overflow](https://stackoverflow.com/questions/56999816/is-it-possible-to-use-jcsg-library-with-processing)

Thanks to all!

Warm regards,

Chrisir

---

<div class="post-metadata">

**Author:** ![hotfooted](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hotfooted/32/3670_2.png) [@hotfooted](https://discourse.processing.org/u/hotfooted)\
**Post date:** [January 4, 2022, 11:27pm UTC](https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389/2 "2022-01-04T23:27:45Z")

</div>

if you just want the mesh

> <https://twitter.com/hamoid/status/816682493793472512>

a PShape save function is something that has been talked about alot in the past but due to the nature of the PShape it’s a complex beast to wrangle.

note: the library talked about in that tweet is [here](https://n-e-r-v-o-u-s.com/tools/obj/) and can be imported via sketch. I don’t know the details of the PShape you are creating and what properties you need to export so it’s difficult to offer anything more. Best of luck.

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [December 28, 2022, 9:10pm UTC](https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389/4 "2022-12-28T21:10:07Z")

</div>

can you print out all the points? or data points?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [September 28, 2023, 4:52pm UTC](https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389/5 "2023-09-28T16:52:41Z")

</div>

Thank you!

ok, I can save the points as csv.

saving this  
 ![cc1](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/8/3/83b2e145bb16ab420a0f4fe8c6c56e4740fd9323.jpeg)

But when I load it, it’s totally distorted.

loading this

 ![cc2](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/3/4/34a5f93de4f58891ac871605fdbc6c59a7da1cbc.jpeg)

(looks like correct vertices in the triangles but wrong stitches)

**Explanation**

(only code snippets, code is too long)

The initial saved PShape has no vertexes, but 1200 children, each 3 vertexes.

Saving, the generated csv, in the csv, each line holds 3 PVectors (3D).

**How do I save?**

```auto
void makeMarbleTrack() {

  // JCSG code:

  PShape csgResult;

  // red marble track
  CSG cubeMinusSphere = defineRedCSG();

  // staple red
  csgResult = CSGToPShape(cubeMinusSphere, 45, color(255, 0, 0)); // red marble track
  list.add(csgResult);

  // ----------------------------------------------------------------------------------

  // get data and SAVE

  PShape psTest=list.get(0);
  int count = psTest.getChildCount();

  println("children "
    + count);
  int count2 = psTest.getVertexCount();
  println("vertex count "
    + count2
    +"\n--------------------------------");
  String[] listString = new String[count];
  for (int i=0; i<count; i++) {
    PShape child = psTest.getChild(i);

    int count3 = child.getChildCount();
    // println("children " + count3);

    int count4 = child.getVertexCount();
    // println("child vertex count " + count4);

    // for each triangle we want to have three PVectors in ONE line for csv
    String temp="";
    for (int i2 = 0; i2 < child.getVertexCount(); i2++) {
      PVector pv = child.getVertex(i2);
    
      temp += getStringPV(pv)+","; // !!!!!!!!!!!!!
    }//for
    listString[i] = temp;
  }//for

  println("\n--------------------------------");

  saveStrings("list1.csv", listString);

  for (String s1 : listString) {
    print (s1, ";");
  }

  println("\n--------------------------------");

   ....
}

....

String getStringPV(PVector pv) {
  return
    pv.x +","+
    pv.y +","+
    pv.z ;
}

```

When loading BOOM! all goes wrong

 ![cc2](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/3/4/34a5f93de4f58891ac871605fdbc6c59a7da1cbc.jpeg)

=====================================================

**Loading 1 :**

So 1st I tried load and GROUP and then add 1200 children using `addChild `😄

```auto
void makeMarbleTrack() {

  // JCSG code:

  PShape csgResult;
  csgResult = createShape(GROUP);

  String[] loadedFile = loadStrings("list1.csv"); // !!!!

  for (String s1 : loadedFile) {
    println (s1, ";");
    PShape temp=getShapeFromString(s1); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    csgResult.addChild(temp);
  }//for

  list.add(csgResult);

  // ----------------------------------------------------------------------------------

PShape getShapeFromString(String s_) {

  // make one line (String) with 3 3D PVectors to a PShape (triangle)

  PShape temp = createShape();

  String[] items = split(s_, ",");

  // error?
  if (items.length<9) {
    exit();
    return null;
  }

  temp.beginShape(TRIANGLE);
  temp.noStroke();
  temp.fill(255, 0, 0);
  temp.vertex(float(items[0]), float(items[1]), float(items[2]));
  temp.vertex(float(items[3]), float(items[4]), float(items[5]));
  temp.vertex(float(items[6]), float(items[7]), float(items[8]));
  temp.endShape(); // CLOSE ???

  return
    temp;
}

```

* * *

**Loading 2 :**

Next TRY TRIANGLE\_STRIP 😄

Triangle-strip

```auto
void makeMarbleTrack() {

  // JCSG code:

  PShape csgResult;
  csgResult = createShape();

  csgResult.noStroke();
  csgResult.fill(255, 0, 0);

  // NEW
  csgResult.beginShape(TRIANGLE_STRIP); // TRIANGLE_STRIP !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  csgResult.noStroke();
  csgResult.fill(255, 0, 0);

  String[] loadedFile = loadStrings("list1.csv");

  for (String s1 : loadedFile) {

    String[] items = split(s1, ",");

    csgResult.vertex(float(items[0]), float(items[1]), float(items[2]));
    csgResult.vertex(float(items[3]), float(items[4]), float(items[5]));
    csgResult.vertex(float(items[6]), float(items[7]), float(items[8]));

  }//for

  csgResult.endShape();

  list.add(csgResult);

  // ----------------------------------------------------------------------------------

}

```

Also very bad.

Please help.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [October 2, 2023, 9:35am UTC](https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389/6 "2023-10-02T09:35:10Z")

</div>

I got a feeling I am reinventing the wheel here…

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [October 12, 2023, 12:20pm UTC](https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389/7 "2023-10-12T12:20:46Z")

</div>

thanks for that.

unfortunately the resulting obj file could not be read by windows 3D Viewer Program

here is my code

(I hqad to drag the jar “OBJExport.jar” from the lib OBJExport onto my Sketch to make it work)

(the example code works though)

```auto

import nervoussystem.obj.*;

boolean record = false;

import processing.javafx.*;
// import com.hamoid.*;

//https://stackoverflow.com/questions/56999816/is-it-possible-to-use-jcsg-library-with-processing
//https://discourse.processing.org/t/csg-constructive-solid-geometry/12693

// the PShape reference which will contain the converted
PShape csgResult, // red marble track
  csgResult2;// green marble

void setup() {
  //
  size(900, 900, P3D);
  noStroke();

  // JCSG sample code:

  // green marble
  CSG sphere = new Sphere(.60).toCSG();
  // red marble track
  CSG cubeMinusSphere = defineRedCSG();

  // make to PShape
  csgResult = CSGToPShape(cubeMinusSphere, 45, color(255, 0, 0)); // red marble track
  csgResult2 = CSGToPShape(sphere, 45, color(0, 255, 0)); // green marble
}

void draw() {
  //
  if (record) {
    beginRecord("nervoussystem.obj.OBJExport", "filename.obj");
  }

  background(0);
  // lights();

  translate(width * 0.5, height * 0.5, 253);
  rotateY(map(mouseX, 0, width, -PI, PI));
  rotateX(map(mouseY, 0, height, PI, -PI));

  shape(csgResult); // red marble track
  shape(csgResult2);// green marble

  //
  if (record) {
    endRecord();
    record = false;
  }
}

//-----------------------------------------------------------------------------

void keyPressed() {
  record = true;
}

CSG defineRedCSG() {
  // define the red marble track "cubeMinusSphere"

  // we use cube as base geometries (long thin cube for the track)
  CSG cubeMain = new Cube(12, 2, 2).toCSG();

  // this we cut out later
  CSG cube2 = new Cube(12, 2, 2).toCSG();
  cube2 = translateXYZ(cube2, -2.1, 0, 1.14);

  // this we cut out later
  // cyl1 == vertical right
  float cylRadius=.65;
  CSG cyl1 = new Cylinder( cylRadius, cylRadius, 12, 43).toCSG();
  cyl1 = translateXYZ(cyl1, 5, 0, 0);

  // this we cut out later
  // cyl2 == horizontal, long
  CSG cyl2 = new Cylinder( cylRadius, cylRadius, 12, 43).toCSG();
  cyl2 = cyl2.transformed(Transform.unity().rot(0, 90, 0)); // rotate in degrees
  cyl2 = translateXYZ(cyl2, cylRadius+1.2+2.1+1.2+.5, 0, 0);

  // this we cut out later
  // cyl3 == vertical left
  CSG cyl3 = new Cylinder( cylRadius, cylRadius, 22, 43).toCSG();
  cyl3 = translateXYZ(cyl3, -5, 0, -4);

  // perform difference (cut out)
  CSG cubeMinusSphere = cubeMain.difference(cyl1);
  cubeMinusSphere = cubeMinusSphere.difference(cyl2);
  cubeMinusSphere = cubeMinusSphere.difference(cube2);
  cubeMinusSphere = cubeMinusSphere.difference(cyl3);

  return cubeMinusSphere;
}

CSG translateXYZ ( CSG csgItem,
  float x, float y, float z ) {
  // tool for translate
  CSG csgItemNew = csgItem.transformed(Transform.unity().translateX(x));
  csgItemNew = csgItemNew.transformed(Transform.unity().translateY(y));
  csgItemNew = csgItemNew.transformed(Transform.unity().translateZ(z));

  return csgItemNew;
}

PShape CSGToPShape(CSG mesh, float scale, color colPShape) {
  // re-usable function to convert a CSG mesh to a Processing PShape

  // allocate a PShape group
  PShape csgResult = createShape(GROUP);

  // for each CSG polygon (Note: these can have 3,4 or more vertices)
  for (Polygon p : mesh.getPolygons()) {
    // make a child PShape
    PShape polyShape = createShape();
    // begin setting vertices to it
    polyShape.beginShape();
    fill(colPShape);

    // for each vertex in the polygon
    for (Vertex v : p.vertices) {
      // add each (scaled) polygon vertex
      polyShape.vertex((float)v.pos.getX() * scale, (float)v.pos.getY() * scale, (float)v.pos.getZ() * scale);
    }//for
    // finish this polygon

    polyShape.endShape();
    //append the child PShape to the parent
    csgResult.addChild(polyShape);
  }//for

  return csgResult;
}
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [October 15, 2023, 5:46pm UTC](https://discourse.processing.org/t/save-a-pshape-on-hard-drive-please-help/34389/8 "2023-10-15T17:46:05Z")

</div>

> [@Chrisir](#):
>
> unfortunately the resulting obj file could not be read by windows 3D Viewer Program

I also tried to load the file in processing but it doesn’t work

But the lib is 10 years old…
