# Problem dividing face of a WETriangleMesh (bug in toxiclibs ?)

**URL:** https://discourse.processing.org/t/problem-dividing-face-of-a-wetrianglemesh-bug-in-toxiclibs/7790
**Category:** Libraries
**Created:** [January 24, 2019, 3:20pm UTC](https://discourse.processing.org/t/problem-dividing-face-of-a-wetrianglemesh-bug-in-toxiclibs/7790 "2019-01-24T15:20:46Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![solub](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/solub/32/333_2.png) [@solub](https://discourse.processing.org/u/solub)
#### Post date: [January 24, 2019, 3:20pm UTC](https://discourse.processing.org/t/problem-dividing-face-of-a-wetrianglemesh-bug-in-toxiclibs/7790/1 "2019-01-24T15:20:46Z")

</div>

Dear all,

In the following example code I’m trying to add 3 new faces on top of one of the original 4 faces of a tetrahedron mesh. The mesh vertices are connected by springs.

My problem is that **the vertices of the newly added faces don’t match the original tetrahedron** , as if they were disconnected from the mesh (top grey 3D triangle).

![](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/18a25b8ebfe3f4b682f8ee4a72f71a7493b0cf64.png)

It is all the more surprising that the newly added springs _that share the same vertices positions_ DO fit the tetrahedron (top 3 red lines)

I would really appreciate if someone could help me find what’s wrong with this example sketch

```auto
import toxi.geom.*;
import toxi.geom.mesh.*;
import toxi.geom.mesh.subdiv.*;
import toxi.physics3d.*;
import toxi.physics3d.behaviors.*;
import toxi.physics3d.constraints.*;
import toxi.processing.*;

import peasy.*;

VerletPhysics3D physics;
WETriangleMesh mesh;
ToxiclibsSupport gfx;

PeasyCam cam;

void setup() {
    perspective(60 * DEG_TO_RAD, width/float(height), 2, 6000);
    size(690, 460, P3D);
    smooth(8);
        
    cam = new PeasyCam(this, 150);
    
    physics = new VerletPhysics3D();
    physics.setDrag(1.1);
    physics.setWorldBounds(new AABB(new Vec3D(), new Vec3D(width, height, height)));
    
    mesh = new WETriangleMesh();
    gfx = new ToxiclibsSupport(this);

            
    //Create 4 particles to form a tetrahedron        
    for (int i = 0; i < 4; i++) {
        VerletParticle3D p = new VerletParticle3D(Vec3D.randomVector());
        physics.addParticle(p);
        physics.addBehavior(new AttractionBehavior3D(p, 10, -4));
    }
        
    //Adding springs between particles
    for (VerletParticle3D p1 : physics.particles) {
        for (VerletParticle3D p2 : physics.particles) {
            if (p1 != p2) {
                VerletSpring3D s = new VerletSpring3D(p1, p2, 60, .1);
                physics.addSpring(s);
            }
        }
    }

    //Adding faces between the 4 particles
    VerletParticle3D p1 = physics.particles.get(0);
    VerletParticle3D p2 = physics.particles.get(1);
    VerletParticle3D p3 = physics.particles.get(2);
    VerletParticle3D p4 = physics.particles.get(3);
    
    mesh.addFace(p1, p2, p3);
    mesh.addFace(p1, p3, p4); 
    mesh.addFace(p1, p2, p4);     
    mesh.addFace(p2, p3, p4);
}
    
    
void draw(){
    background(30);
    
    
    //Update physics
    physics.update();
        
    
    //Update mesh vertices by moving them to the current position of their associated particles
    for (int i = 0, num = physics.particles.size(); i < num; i++) {
        mesh.getVertexForID(i).set(physics.particles.get(i));
    }

    
    //Draw springs
    for (int i = 0, num = physics.springs.size(); i < num; i++) {
        stroke(255, 30, 30);
        strokeWeight(1);
        line(physics.springs.get(i).a.x(), physics.springs.get(i).a.y(), physics.springs.get(i).a.z(),  
        physics.springs.get(i).b.x(), physics.springs.get(i).b.y(), physics.springs.get(i).b.z());
    }

   
    //Display WETriangle mesh
    noStroke();
    fill(255, 200);
    gfx.mesh(mesh);
}
    

   
           
   
        
void keyReleased(){
    
    //Selecting first face + computing its centroid
    Face f = mesh.getFaces().get(0);
    VerletParticle3D centroid = new VerletParticle3D(new Triangle3D(f.a, f.b, f.c).computeCentroid());
    
    // 3 vertices of the the first face
    VerletParticle3D a = physics.particles.get(physics.particles.indexOf(f.a));
    VerletParticle3D b = physics.particles.get(physics.particles.indexOf(f.b));
    VerletParticle3D c = physics.particles.get(physics.particles.indexOf(f.c));

    CreateFaces(a, b, c, centroid);
}
           

    
void CreateFaces(VerletParticle3D a, VerletParticle3D b, VerletParticle3D c, VerletParticle3D n) {
    
    //Add centroid to physics + set repulsive behavior
    physics.addParticle(n);
    physics.addBehavior(new AttractionBehavior3D(n, 10, -4));
    
    //Attach springs between the face vertices and the centroid
    VerletSpring3D s1 = new VerletSpring3D(a, n, 40, .1);
    VerletSpring3D s2 = new VerletSpring3D(b, n, 40, .1);
    VerletSpring3D s3 = new VerletSpring3D(c, n, 40, .1);
    
    physics.addSpring(s1);
    physics.addSpring(s2);
    physics.addSpring(s3);
    
    //Remove original face
    mesh.removeFace(mesh.getFaces().get(0));
    
    
    //Add faces of the newly formed tetrahedron to the mesh
    mesh.addFace(n, a, b);
    mesh.addFace(n, b, c);
    mesh.addFace(n, a, c);
}

```

---

<div class="post-metadata">

### Author: ![solub](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/solub/32/333_2.png) [@solub](https://discourse.processing.org/u/solub)
#### Post date: [February 12, 2019, 7:46pm UTC](https://discourse.processing.org/t/problem-dividing-face-of-a-wetrianglemesh-bug-in-toxiclibs/7790/2 "2019-02-12T19:46:07Z")

</div>

It seems the vertices and edges of a mesh in toxiclibs need to be updated (re-indexed) every time a face is added.

`mesh.rebuildIndex();`

This single line fixed the issue.

> **Script**
>
> ```auto
> import toxi.geom.*;
> import toxi.geom.mesh.*;
> import toxi.geom.mesh.subdiv.*;
> import toxi.physics3d.*;
> import toxi.physics3d.behaviors.*;
> import toxi.physics3d.constraints.*;
> import toxi.processing.*;
> 
> import peasy.*;
> 
> VerletPhysics3D physics;
> WETriangleMesh mesh;
> ToxiclibsSupport gfx;
> 
> PeasyCam cam;
> 
> void setup() {
> perspective(60 * DEG_TO_RAD, width/float(height), 2, 6000);
> size(690, 460, P3D);
> smooth(8);
>         
> cam = new PeasyCam(this, 150);
>     
> physics = new VerletPhysics3D();
> physics.setDrag(1.1);
> physics.setWorldBounds(new AABB(new Vec3D(), new Vec3D(width, height, height)));
>     
> mesh = new WETriangleMesh();
> gfx = new ToxiclibsSupport(this);
> 
>             
> //Create 4 particles to form a tetrahedron        
> for (int i = 0; i < 4; i++) {
> VerletParticle3D p = new VerletParticle3D(Vec3D.randomVector());
> physics.addParticle(p);
> physics.addBehavior(new AttractionBehavior3D(p, 10, -4));
> }
>         
> //Adding springs between particles
> for (VerletParticle3D p1 : physics.particles) {
> for (VerletParticle3D p2 : physics.particles) {
> if (p1 != p2) {
> VerletSpring3D s = new VerletSpring3D(p1, p2, 60, .1);
> physics.addSpring(s);
> }
> }
> }
> 
> //Adding faces between the 4 particles
> VerletParticle3D p1 = physics.particles.get(0);
> VerletParticle3D p2 = physics.particles.get(1);
> VerletParticle3D p3 = physics.particles.get(2);
> VerletParticle3D p4 = physics.particles.get(3);
>     
> mesh.addFace(p1, p2, p3);
> mesh.addFace(p1, p3, p4); 
> mesh.addFace(p1, p2, p4);     
> mesh.addFace(p2, p3, p4);
> }
>     
>     
> void draw(){
> background(30);
>     
>     
> //Update physics
> physics.update();
>         
>     
> //Update mesh vertices by moving them to the current position of their associated particles
> for (int i = 0, num = physics.particles.size(); i < num; i++) {
> mesh.getVertexForID(i).set(physics.particles.get(i));
> }
> 
>     
> //Draw springs
> for (int i = 0, num = physics.springs.size(); i < num; i++) {
> stroke(255, 30, 30);
> strokeWeight(1);
> line(physics.springs.get(i).a.x(), physics.springs.get(i).a.y(), physics.springs.get(i).a.z(),  
> physics.springs.get(i).b.x(), physics.springs.get(i).b.y(), physics.springs.get(i).b.z());
> }
> 
>    
> //Display WETriangle mesh
> noStroke();
> fill(255, 200);
> gfx.mesh(mesh);
> }
>     
> 
>    
>            
>    
>         
> void keyReleased(){
>     
> //Selecting first face + computing its centroid
> Face f = mesh.getFaces().get(0);
> VerletParticle3D centroid = new VerletParticle3D(new Triangle3D(f.a, f.b, f.c).computeCentroid());
>     
> // 3 vertices of the the first face
> VerletParticle3D a = physics.particles.get(physics.particles.indexOf(f.a));
> VerletParticle3D b = physics.particles.get(physics.particles.indexOf(f.b));
> VerletParticle3D c = physics.particles.get(physics.particles.indexOf(f.c));
> 
> CreateFaces(a, b, c, centroid);
> }
>            
> 
>     
> void CreateFaces(VerletParticle3D a, VerletParticle3D b, VerletParticle3D c, VerletParticle3D n) {
>     
> //Re-index mesh vertices & edges
> mesh.rebuildIndex();
>   
> //Add centroid to physics + set repulsive behavior
> physics.addParticle(n);
> physics.addBehavior(new AttractionBehavior3D(n, 10, -4));
>     
> //Attach springs between the face vertices and the centroid
> VerletSpring3D s1 = new VerletSpring3D(a, n, 40, .1);
> VerletSpring3D s2 = new VerletSpring3D(b, n, 40, .1);
> VerletSpring3D s3 = new VerletSpring3D(c, n, 40, .1);
>     
> physics.addSpring(s1);
> physics.addSpring(s2);
> physics.addSpring(s3);
>     
> //Remove original face
> mesh.removeFace(mesh.getFaces().get(0));
>     
>     
> //Add faces of the newly formed tetrahedron to the mesh
> mesh.addFace(n, a, b);
> mesh.addFace(n, b, c);
> mesh.addFace(n, a, c);
> }
> 
> ```
