# Hidden line removal for wireframe obj as PShape

**URL:** https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253
**Category:** Coding Questions
**Created:** [October 8, 2018, 5:28pm UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253 "2018-10-08T17:28:51Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![ffd8](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ffd8/32/815_2.png) [@ffd8](https://discourse.processing.org/u/ffd8)
#### Post date: [October 8, 2018, 5:28pm UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/1 "2018-10-08T17:28:51Z")

</div>

Starting to play with importing an obj file using loadShape() and rendering it as a wireframe.  
Now comes the tricky part… how to do ‘hidden line removal’ (similar to back-face detection, culling… still sorting out exact term here). Essentially, can someone point me in the right direction for doing this filtering or know of a solution from a previous forum discussion? I’ve found a handful of PDFs and presentations presenting algorithms that go over my head in terms of applying within this context… a few such links are:

> **[Hidden-line removal](https://en.wikipedia.org/wiki/Hidden_line_removal)**
>
> Solid objects are usually modeled by polyhedra in a computer representation. A face of a polyhedron is a planar polygon bounded by straight line segments, called edges. Curved surfaces are usually approximated by a polygon mesh. Computer programs for line drawings of opaque objects must be able to decide which edges or which parts of the edges are hidden by an object itself or by other objects. This problem is known as hidden-line removal.
> The first known solution to the hidden-line problem ...

  
[http://www.cs.brandeis.edu/~cs155/Lecture\_14.pdf](http://www.cs.brandeis.edu/~cs155/Lecture_14.pdf)  
[http://csis.pace.edu/~marchese/CG\_Rev/Lect9New/cg\_l9new.htm](http://csis.pace.edu/~marchese/CG_Rev/Lect9New/cg_l9new.htm)  
[http://underpop.free.fr/j/java/developing-games-in-java/1592730051\_ch09lev1sec1.html](http://underpop.free.fr/j/java/developing-games-in-java/1592730051_ch09lev1sec1.html)  

> **[hidden surface elimination using z buffer algorithm](https://www.slideshare.net/rajivagarwal23dei/computer-graphics-28843839)**
>
> Hidden Surface Removal RAJIV AGARWAL BSc(Hons)\[CS\] 115090

Here’s the base code for viewing the obj/PShape as a wireframe.  
Wondering if/how screenX/Y/Z might play a role to solve this?

```auto
 // obj file instance
PShape obj;

public void setup() {
  size(512, 512, P3D);

  // load object
  obj = loadShape("teapot.obj");
}

public void draw() {
  background(0);

  translate(width/2, height/2);
  scale(2);
  rotateZ(PI);
  rotateY(radians(frameCount));

  noFill();
  stroke(255);
  int children = obj.getChildCount();

  beginShape();
  for (int i = 0; i < children; i++) {
    PShape child = obj.getChild(i);

    for (int j = 0; j < child.getVertexCount(); j++) {
      PVector v = child.getVertex(j);
      vertex(v.x, v.y, v.z);
    }
  }
  endShape();
}

```

---

<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: [October 8, 2018, 5:33pm UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/2 "2018-10-08T17:33:35Z")

</div>

Hi ffd8,

Have you tried using `fill(0, 0, 0, 0)`? I think it should work.

---

<div class="post-metadata">

### Author: ![ffd8](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ffd8/32/815_2.png) [@ffd8](https://discourse.processing.org/u/ffd8)
#### Post date: [October 8, 2018, 7:06pm UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/3 "2018-10-08T19:06:42Z")

</div>

Ha interesting – but unfortunately it only placed some black triangles within the shape (could still see past/around them and see plenty of lines in the back).

The ultimate goal is combining with my XYscope library for an efficient 3D object w/ hidden lines removed, so searching for a solution to filter out those PVectors.

---

<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: [October 8, 2018, 7:41pm UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/4 "2018-10-08T19:41:51Z")

</div>

You are getting that weird effect because you are not building the face properly I think.

I had to make a custom shape builder to load a shape and display it properly. The `fill(0, 0, 0, 0)` is working nice with it.

The code:

```auto
import peasy.*;

// obj file instance

myObject obj;
PeasyCam cam;

public void setup() {
  size(512, 512, P3D);
  cam = new PeasyCam(this, 400);

  obj = new myObject("Suzanne.obj");
}

public void draw() {
  background(200, 20, 20);
  
  fill(0, 0, 0, 0);
  stroke(255);
  strokeWeight(1);

  ArrayList<Quad> quads = obj.getQuads();  
  for (int i = 0; i < quads.size(); i++) {
    beginShape(QUADS);
    quads.get(i).createVertex();
    endShape();
  }
  
  ArrayList<Tri> tris = obj.getTris();  
  for (int i = 0; i < tris.size(); i++) {
    beginShape(TRIANGLES);
    tris.get(i).createVertex();
    endShape();
  }
  
}

class myObject {
  private ArrayList<PVector> vertices;
  private ArrayList<Tri> tris;
  private ArrayList<Quad> quads;

  public myObject(String objFile) {
    String[] lines;
    vertices = new ArrayList<PVector>();
    tris = new ArrayList<Tri>();
    quads = new ArrayList<Quad>();

    lines = loadStrings(objFile);
    for (int idx = 0; idx < lines.length; idx++) {
      
      String[] data = split(lines[idx], " ");

      if (data[0].equals("v")) {
        vertices.add(new PVector(float(data[1]), float(data[2]), float(data[3])));         
      } else if (data[0].equals("f")) {
        PVector v0, v1, v2;
        int idx0, idx1, idx2;

        idx0 = int(split(data[1], "/")[0]) - 1;
        idx1 = int(split(data[2], "/")[0]) - 1;
        idx2 = int(split(data[3], "/")[0]) - 1;
        
        printArray(data);
        println(idx0, idx1, idx2);

        v0 = vertices.get(idx0).copy();
        v1 = vertices.get(idx1).copy();
        v2 = vertices.get(idx2).copy();

        if (data.length == 5) {
          PVector v3;
          int idx3;
          idx3 = int(split(data[4], "/")[0]) - 1;
          v3 = vertices.get(idx3).copy();
          quads.add(new Quad(v0, v1, v2, v3));
        } else {
          tris.add(new Tri(v0, v1, v2));
        }
        
      }
      
    }
  }

  public ArrayList<Tri> getTris() {
    return tris;
  }
  
  public ArrayList<Quad> getQuads() {
    return quads;
  }
}

class Tri {
  private PVector[] vertices;

  public Tri(PVector v0, PVector v1, PVector v2) {
    vertices = new PVector[3];
    vertices[0] = v0;
    vertices[1] = v1;
    vertices[2] = v2;
  }

  public void createVertex() {
    vertex(vertices[0].x, vertices[0].y, vertices[0].z);
    vertex(vertices[1].x, vertices[1].y, vertices[1].z);
    vertex(vertices[2].x, vertices[2].y, vertices[2].z);
  }
}

class Quad {
  private PVector[] vertices;

  public Quad(PVector v0, PVector v1, PVector v2, PVector v3) {
    vertices = new PVector[4];
    vertices[0] = v0;
    vertices[1] = v1;
    vertices[2] = v2;
    vertices[3] = v3;
  }

  public void createVertex() {
    vertex(vertices[0].x, vertices[0].y, vertices[0].z);
    vertex(vertices[1].x, vertices[1].y, vertices[1].z);
    vertex(vertices[2].x, vertices[2].y, vertices[2].z);
    vertex(vertices[3].x, vertices[3].y, vertices[3].z);
  }
}

```

You can download a Suzanne wavefront example [here](https://ufile.io/oy6u0)

---

<div class="post-metadata">

### Author: ![ffd8](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ffd8/32/815_2.png) [@ffd8](https://discourse.processing.org/u/ffd8)
#### Post date: [October 8, 2018, 8:37pm UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/5 "2018-10-08T20:37:53Z")

</div>

On screen this looks really promising towards only showing the visible lines… however the hidden lines are still there – being covered up by this fill(0, 0, 0, 0) but not actually filtered from the arrayList. I’m hoping there’s a way (perhaps it requires a shader?) so that at any given rotation of the object, I can ask _are you visible or being “covered” by another line/surface_ and only have the visible ones be part of the beginShape/endShape vertices.

---

<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: [October 8, 2018, 8:41pm UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/6 "2018-10-08T20:41:47Z")

</div>

It is, indeed just a trick to hide them.

To perform what you want to do you would also need to split your lines if they are partially covered. Sounds quite tricky ^^

May I ask what is the goal at the end?

---

<div class="post-metadata">

### Author: ![ffd8](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ffd8/32/815_2.png) [@ffd8](https://discourse.processing.org/u/ffd8)
#### Post date: [October 9, 2018, 10:15am UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/7 "2018-10-09T10:15:05Z")

</div>

Yeah it’s been quite tricky to wrap my head around… so i’m still hopeful someone in this community has already solved it in Processing style w/ PVectors.

Sure sure – the end goal is passing the filtered ArrayList of PVectors through my XYscope library (not shamelessly promoting… just want to extend the fun examples it comes with) – it translates the lines to L/R stereo sound, getting them back as an image on an analog oscilloscope/laser. It works fine as I have it above, but it would look cleaner and possibly sound nicer w/ fewer points once figuring out how to hide the back/hidden lines. In the end, once hopefully finding a solution, I’ll learn it was best not hiding those lines… but I won’t know until seeing/hearing it.

---

<div class="post-metadata">

### Author: ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)
#### Post date: [October 9, 2018, 10:39am UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/8 "2018-10-09T10:39:17Z")

</div>

> [@jb4x](#):
>
> It is, indeed just a trick to hide them.

Yes, nice trick indeed! 👍 btw, your Suzanne link doesn’t work.

---

<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: [October 9, 2018, 10:48am UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/9 "2018-10-09T10:48:49Z")

</div>

Thanks for the link: it should be working now!

---

<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: [October 14, 2018, 5:00am UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/10 "2018-10-14T05:00:35Z")

</div>

If you were trying to resolve this at the graphics level and not  
I believe (untested) that you can set a clipping plane in P3D by defining the frustum.

> Thus, any form inside the clipping planes is rendered and visible; anything outside those planes is not visible. [frustum() / Reference / Processing.org](https://processing.org/reference/frustum_.html)

Also in the graphics buffer direction are libraries like Picking – so you could paint every triangle / face, then check which ones are in the view to get your face list, then use your face list to get your point list or line list.

If you wanted to directly test a bunch of points for visibility from the perspective point, perhaps Box2D raycasting?

- [https://forum.processing.org/two/discussion/24248/how-to-ray-cast-in-box2dprocessing](https://forum.processing.org/two/discussion/24248/how-to-ray-cast-in-box2dprocessing)

A related approach might be to calculate the hemesh HEC\_ConvexHull of your shape to get the exterior (assuming your mesh is convex!) then throw everything away that isn’t on that exterior, then raycast the remaining points to ID what is front-facing, then throw away anything line with a point that didn’t hit.

---

<div class="post-metadata">

### Author: ![ffd8](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ffd8/32/815_2.png) [@ffd8](https://discourse.processing.org/u/ffd8)
#### Post date: [December 9, 2018, 9:44pm UTC](https://discourse.processing.org/t/hidden-line-removal-for-wireframe-obj-as-pshape/4253/11 "2018-12-09T21:44:47Z")

</div>

Thanks for those additional links! (sorry for lag, got sidetracked by other coding). The raycasting w/ box2d sounds the most promising. Indeed, wanting to do this at a pre-rendering level and not just painting over the hidden lines – since the goal is a smaller array of visible points to draw.
