# Cube with rounded edges

**URL:** <https://discourse.processing.org/t/cube-with-rounded-edges/22064>\
**Category:** Coding Questions\
**Created:** [June 22, 2020, 2:54pm UTC](https://discourse.processing.org/t/cube-with-rounded-edges/22064 "2020-06-22T14:54:28Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mesalcode](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mesalcode/32/9284_2.png) [@Mesalcode](https://discourse.processing.org/u/Mesalcode)\
**Post date:** [June 22, 2020, 2:54pm UTC](https://discourse.processing.org/t/cube-with-rounded-edges/22064/1 "2020-06-22T14:54:28Z")

</div>

Hi there! I am working on a mobile quizapp based on rotating a cube. I am currently using this code for drawing a cube:

```auto
  beginShape(QUADS);
  texture(front);
  vertex(-1, -1, 1, 0, 0);
  vertex( 1, -1, 1, 1, 0);
  vertex( 1, 1, 1, 1, 1);
  vertex(-1, 1, 1, 0, 1);
  endShape();
  beginShape(QUADS);
  vertex( 1, -1, -1, 0, 0);
  vertex(-1, -1, -1, 1, 0);
  vertex(-1, 1, -1, 1, 1);
  vertex( 1, 1, -1, 0, 1);
  endShape();
  beginShape(QUADS);
  texture(any);
  vertex(-1, 1, 1, 0, 0);
  vertex( 1, 1, 1, 1, 0);
  vertex( 1, 1, -1, 1, 1);
  vertex(-1, 1, -1, 0, 1);
  endShape();
  beginShape(QUADS);
  texture(any);
  vertex(-1, -1, -1, 0, 0);
  vertex( 1, -1, -1, 1, 0);
  vertex( 1, -1, 1, 1, 1);
  vertex(-1, -1, 1, 0, 1);
  endShape();
  beginShape(QUADS);
  texture(any);
  vertex( 1, -1, 1, 0, 0);
  vertex( 1, -1, -1, 1, 0);
  vertex( 1, 1, -1, 1, 1);
  vertex( 1, 1, 1, 0, 1);
  endShape();
  beginShape(QUADS);
  texture(any);
  vertex(-1, -1, -1, 0, 0);
  vertex(-1, -1, 1, 1, 0);
  vertex(-1, 1, 1, 1, 1);
  vertex(-1, 1, -1, 0, 1);
  endShape();

```

Now I want the cube to look more dynamic. To achieve that, I am trying to round the cube’s edges like in this 3D Model: [https://1drv.ms/u/s!AlgOmiL5mgw21lWz\_pmcUoAcVRY0?e=blu6u0](https://1drv.ms/u/s!AlgOmiL5mgw21lWz_pmcUoAcVRY0?e=blu6u0). Can anyone show me how I can do that? I am not really good with shapes.

---

<div class="post-metadata">

**Author:** ![jb4x](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jb4x/32/789_2.png) [@jb4x](https://discourse.processing.org/u/jb4x)\
**Post date:** [June 22, 2020, 6:27pm UTC](https://discourse.processing.org/t/cube-with-rounded-edges/22064/2 "2020-06-22T18:27:49Z")

</div>

Hello,

You could use Blender to create a cube and bevel the edges the way you want. Then you could export the cube with the .OBJ format and use the [loadShape() function](https://processing.org/reference/loadShape_.html) to import it into your project.

---

<div class="post-metadata">

**Author:** ![Mesalcode](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mesalcode/32/9284_2.png) [@Mesalcode](https://discourse.processing.org/u/Mesalcode)\
**Post date:** [July 5, 2020, 1:14pm UTC](https://discourse.processing.org/t/cube-with-rounded-edges/22064/3 "2020-07-05T13:14:28Z")

</div>

Thanks for the advise, but I already tried that without sucess. I can load the shape, but it behaves weird. It rotates around some weird axes and completely loses it’s form on rotation.

---

<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:** [July 13, 2020, 9:11pm UTC](https://discourse.processing.org/t/cube-with-rounded-edges/22064/4 "2020-07-13T21:11:54Z")

</div>

here is my way…

![Unbenannt](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/3/3f154edc64ec4f374296c52711ee415ce90c3369.png)

first we take a sphere, then we cut out another smaller sphere from its center .

This leaves a hollow sphere.

Now we take the cube and minus the hollow sphere.

When all sizes are chosen correctly, the hollow sphere just cuts off the edges of the cube.

```auto
  // This is where the magic happens
  csgResult = roundedCube();

```

Chrisir

```auto

//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 CSG 
PShape csgResult;

void setup() {
  size(900, 900, P3D);
  // This is where the magic happens
  csgResult = roundedCube(); 
  println("Use mouse to rotate.");
}

void draw() {
  background(0);
  lights();
  translate(width * 0.5, height * 0.5, 0);
  rotateY(map(mouseX, 0, width, -PI, PI));
  rotateX(map(mouseY, 0, height, PI, -PI));

  shape(csgResult);
}

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

PShape roundedCube() {

  PShape csgResult;

  noStroke();

  // JCSG sample code:
  // we use cube and sphere as base geometries
  CSG cube = new Cube(2.78).toCSG();

  CSG sphere1 = new Sphere(3).toCSG(); // outer sphere 
  CSG sphere2 = new Sphere(2.0941, 39, 39).toCSG(); // inner sphere - the smaller this is, the more we cut off from the cube! 
  //CSG sphere2 = new Sphere(1.80941).toCSG(); // the smaller this is, the more we cut off from the cube! 

  // perform difference: this gives a hollow sphere  
  CSG sphere3 = sphere1.difference(sphere2);

  // perform difference again: this gives a cube with rounded edges 
  CSG cubeMinusSphere = cube.difference(sphere3);
  // cubeMinusSphere = sphere.difference(cube);

  // Convert CSG to PShape -> Note: CSG units are small so we scale them up so the shapes are visible in Processing
  csgResult = CSGToPShape(cubeMinusSphere, 45);

  return csgResult;
} //func 

// re-usable function to convert a CSG mesh to a Processing PShape
PShape CSGToPShape(CSG mesh, float scale) {
  // 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();
    polyShape.fill(255, 0, 0); 
    // 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);
    }
    // finish this polygon
    polyShape.endShape();
    //append the child PShape to the parent
    csgResult.addChild(polyShape);
  }
  return csgResult;
}
//

```

---

<div class="post-metadata">

**Author:** ![Mesalcode](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mesalcode/32/9284_2.png) [@Mesalcode](https://discourse.processing.org/u/Mesalcode)\
**Post date:** [July 25, 2020, 4:48pm UTC](https://discourse.processing.org/t/cube-with-rounded-edges/22064/5 "2020-07-25T16:48:12Z")

</div>

Thanks for the attempt, but fortunately I was able to get loading the 3d model working.

But there still is a big problem:

```auto

PShape cubeShape;
PShape secondaryShape;
PImage cubeImage;
PImage blank;
float rotationX;
float rotationY;
float sX, sY;
int childs;
PFont questionFont, optionFont;

void setup(){
  frameRate(60);
  orientation(PORTRAIT);
  fullScreen(P3D);
  shapeMode(CORNER);
  textAlign(CORNER);
  smooth(5);
  cubeShape = loadShape("Abc.obj");
  cubeShape.setFill(color(255));
  cubeShape.setTint(color(255));
  secondaryShape = loadShape("Abc.obj");
  secondaryShape.setFill(color(255));
  secondaryShape.setTint(color(255,255,255));
  cubeImage = loadImage("cubesite_front.PNG");
  childs = cubeShape.getChildCount();
  questionFont = createFont("cube.ttf",7); 
  optionFont = createFont("cube.ttf", 85);
  textureWrap(REPEAT);
  textureMode(IMAGE);
  secondaryShape.setTexture(loadImage("cubesite_any.png"));
  rotationX = 0.0f;
  rotationY = 0.0f;
  editSite(cubeImage, "Test", "Left", "Top", "Right", "Bottom");
  cubeImage = getMirror(cubeImage);
}

void draw(){
  cubeShape.setTexture(cubeImage);
  Runtime runtime = Runtime.getRuntime();
  float usedRam = 1.0f - (float) runtime.freeMemory() / (float) runtime.totalMemory();
  int usedRamPercent = (int) (usedRam*100.0f);
  background(255);
  lights();
  textSize(width/20);
  fill(0,125,255);
  text("Rotation X: " + String.valueOf(degrees(rotationX)).split("\\.")[0]+"°\n"+"Rotation Y: " + String.valueOf(degrees(rotationY)).split("\\.")[0]+"°",width/20,height/20);
  String rightBar = "Touch X: " + String.valueOf(sX) + "\nTouch Y: " + String.valueOf(sY) 
  + "\n\nRAM: " + usedRamPercent + "%"
  + "\nFPS: " + String.valueOf(frameRate).split("\\.")[0];
  text(rightBar,width-width/20-textWidth(rightBar),height/20); 
  textSize(width/20);
  fill(125,25,0);
  text("",width/2,height/7);
  if (rotationX>=TWO_PI||rotationX<=-TWO_PI) rotationX=0;
  if (rotationY>=TWO_PI||rotationY<=-TWO_PI) rotationY=0;
  for (int i = 0; i <childs; i++){
    PShape currentChild = cubeShape.getChild(i); 
    PShape secondaryChild = secondaryShape.getChild(i);
    boolean front = true;
    for (int j = 0; j < currentChild.getVertexCount(); j++){
      PVector currentVector = currentChild.getVertex(j);
      front = !(currentVector.z<0.95);
    }
    pushMatrix();
    translate(width/2,height/2,height/6);
    scale(height/7);
    rotateX(rotationX);
    rotateY(rotationY);
    shape(front ? currentChild : secondaryChild);
    popMatrix();
  }
}
 

PImage getMirror(PImage img) {
  PGraphics pg = createGraphics(img.width, img.height, JAVA2D);
  pg.beginDraw();
  pg.smooth(4);
  pg.scale(-1, 1);
  pg.image(img, -img.width, 0);
  pg.endDraw();
  return pg.get();
}

private void editSite(PImage background, String center, String left, String top, String right, String bottom){ 
  PGraphics siteGraphics = createGraphics(background.width,background.height); 
  imageMode(CORNER); 
  siteGraphics.beginDraw(); 
  siteGraphics.image(background,0,0); 
  siteGraphics.textSize(width/10); 
  fittedText(siteGraphics,center,questionFont,siteGraphics.width/2,siteGraphics.height/2,siteGraphics.width-siteGraphics.width/6,siteGraphics.height-siteGraphics.height/6); 
  siteGraphics.pushMatrix(); 
  siteGraphics.translate(0,0);
  siteGraphics.rotate(-HALF_PI); 
  siteGraphics.textAlign(CENTER, CENTER); 
  siteGraphics.textFont(optionFont); 
  siteGraphics.text(left,-siteGraphics.height/2,siteGraphics.width/6/2); 
  siteGraphics.rotate(PI); 
  siteGraphics.text(right,siteGraphics.height/2,-siteGraphics.width+siteGraphics.width/6/2); 
  siteGraphics.rotate(-HALF_PI); 
  siteGraphics.text(top,siteGraphics.width/2,siteGraphics.height/6/2); 
  siteGraphics.text(bottom,siteGraphics.width/2,siteGraphics.height-siteGraphics.height/6/2); siteGraphics.popMatrix(); 
  siteGraphics.endDraw(); 
  cubeImage = siteGraphics.get(); 
}

private final char NEWLINE = '\n'; private final String SPACE_SEPARATOR = " "; private final String SPLIT_REGEXP= "\\s+"; String breakLines(String input, int maxLineLength) { String[] tokens = input.split(SPLIT_REGEXP); StringBuilder output = new StringBuilder(input.length()); int lineLen = 0; for (int i = 0; i < tokens.length; i++) { String word = tokens[i]; if (lineLen + (SPACE_SEPARATOR + word).length() > maxLineLength) { if (i > 0) output.append(NEWLINE); lineLen = 0; } if (i < tokens.length - 1 && (lineLen + (word + SPACE_SEPARATOR).length() + tokens[i + 1].length() <=maxLineLength)) word += SPACE_SEPARATOR; output.append(word); lineLen += word.length(); } return output.toString();}
void fittedText(PGraphics graphics,String text, PFont font, float posX, float posY, float fitX, float fitY){ 
  text = breakLines(text, 15); 
  graphics.textFont(font); 
  graphics.textAlign(CENTER,CENTER); 
  graphics.textSize(min(font.getSize()*fitX/textWidth(text), fitY)); 
  graphics.textLeading(graphics.textSize*1.1); 
  graphics.text(text, posX, posY);
}

void mousePressed(){
  sX = mouseX;
  sY = mouseY;
}
void mouseDragged(){
  rotationX += (mouseY-sY)*(HALF_PI/(width));
  sY = mouseY;
  rotationY += (mouseX-sX)*(HALF_PI/(width));
  sX = mouseX;
}

```

The above demo code functions perfectly when run via APDE, but the texture is just one solid ugly color when build/run from a windows machine via PDE or Android Studio:

 ![bad](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/c/cb6d6ab0eb11fba03dc656e9c97c97c6b26ff88b.jpeg) ![good](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/5d86a802eee232db3873dc6fd73fd8d5d106b740.jpeg)

Do(es) you/anyone know(s) why this is happening and how I can fix it?

If needed I will upload the model as well if it is relevant!

---

<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:** [July 26, 2020, 8:37pm UTC](https://discourse.processing.org/t/cube-with-rounded-edges/22064/6 "2020-07-26T20:37:48Z")

</div>

I have no idea…

Chrisir

---

<div class="post-metadata">

**Author:** ![Mesalcode](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mesalcode/32/9284_2.png) [@Mesalcode](https://discourse.processing.org/u/Mesalcode)\
**Post date:** [July 26, 2020, 8:38pm UTC](https://discourse.processing.org/t/cube-with-rounded-edges/22064/7 "2020-07-26T20:38:59Z")

</div>

That’s a shame… I can’t understand why this is happening either. What is APDE doing differently?
