Save a PShape on Hard Drive (please help)

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)

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

Any ideas?

(too long for an mcve)

Didn’t find anything here: PShape / Reference / Processing.org

What I tried

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

  //-------
  // 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

Thanks to all!

Warm regards,

Chrisir

1 Like

if you just want the mesh

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 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.

2 Likes

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

1 Like

Thank you!

ok, I can save the points as csv.

saving this
cc1

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

loading this

(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?

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

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

Loading 1 :

So 1st I tried load and GROUP and then add 1200 children using addChild :smile:

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 :smile:

Triangle-strip

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.

1 Like

I got a feeling I am reinventing the wheel here…

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)


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;
}
//

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

But the lib is 10 years old…