Q:

Subdivide a specific face of a geometry. Three.js

Simple question, but I've dealing with it quite a lot. Could anyone think about how could you divide a 3 or 4 vertex face into 2 or more smaller faces?

A:

You probably would have to do that manually, but it seems quite possible to me!
Since three.js always deals with triangles since quads got removed in 2013, you have to think about subdividing triangles. That's where it gets ugly, when you deal with pseudo-4-vertex-faces, because they are built up by two triangles.
With some vector calculation, you definitely could solve the problem, but a lots of work will be required!
I've written a little demo for you. It's by far not perfect, but i hope you get the principle ;)
http://codepen.io/anon/pen/aOjgeL
HTML:
<html>
  <head>
    Subdivision
  </head>
  <body>
    <div class="button">Subdivide faces</div>
    <div id="rotateX">Rotate X</div>
    <div id="rotateY">Rotate Y</div>
    <div id="rotateZ">Rotate Z</div>
    <div id="container"></div>
  </body>
</html>

CSS:
#container {
    height: 400px;
    width: 800px;
    background-color: #feefee;
}
.button {
  background-color: BLACK;
  color: white;
  width: 150px;
  text-align: center;
}
#rotateX  {
  background-color: RED;
  color: white;
  width: 150px;
  text-align: center;
}
#rotateY  {
  background-color: GREEN;
  color: white;
  width: 150px;
  text-align: center;
}
#rotateZ  {
  background-color: BLUE;
  color: white;
  width: 150px;
  text-align: center;
}

Javascript:
var scene, camera, renderer, mesh;
var rotateX, rotateY, rotateZ;

$(document).ready(function(){
    init();
    animate();
});

function init(){
    // Create scene
    scene = new THREE.Scene();

    var container = document.getElementById("container");

    // Create WebGL renderer and add it to the DOM
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(800, 400);
    container.appendChild(renderer.domElement);

    // Create camera, zoom it out from the model and add it to the scene
    camera = new THREE.PerspectiveCamera(45, 800/400, 1, 10000);
    camera.position.set(6, 1, 2);

    // Set background color
    renderer.setClearColor(0xFFFFFF, scene);

    // Add light
    var light = new THREE.PointLight(0xFFFFFF);
    light.position.set(-1, 1, 1);
    scene.add(light);
    var light2 = new THREE.PointLight(0xFFFFFF);
    light2.position.set(1, 1, 1);
    scene.add(light2);
    var light3 = new THREE.PointLight(0xFFFFFF);
    light3.position.set(0, 0, 3);
    light3.intensity = 0.5;
    scene.add(light3);

    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    var material = new THREE.MeshPhongMaterial( {color: 0x000fff, side: THREE.DoubleSide} );
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );

    camera.lookAt(mesh.position);

  var wireframe = new THREE.WireframeHelper(mesh, 0x00ff00);
  scene.add(wireframe);
}

$("#rotateX").click(function(){
  rotateX = (rotateX == true ? false : true);
});

$("#rotateY").click(function(){
  rotateY = (rotateY == true ? false : true);
});

$("#rotateZ").click(function(){
  rotateZ = (rotateZ == true ? false : true);
});

// This is where the magic happens
$(".button").click(function() {
  // Get the wanted face
  var face = mesh.geometry.faces[0];
  // Get the middle between two of the three vectors
  var vector = new THREE.Vector3( (mesh.geometry.vertices[face.b].x + mesh.geometry.vertices[face.c].x) / 2, (mesh.geometry.vertices[face.b].y + mesh.geometry.vertices[face.c].y) / 2, (mesh.geometry.vertices[face.b].z + mesh.geometry.vertices[face.c].z) / 2 );
  // Push vector in vertices array
  mesh.geometry.vertices.push(vector);
  var index = mesh.geometry.vertices.length - 1; // This method of getting the index is not thread safe!
  // Adding first face
  var temp = mesh.geometry.faces[0].b;
  mesh.geometry.faces[0] = new THREE.Face3(mesh.geometry.faces[0].a, index ,mesh.geometry.faces[0].c, mesh.geometry.faces[0].normal, mesh.geometry.faces[0].color, mesh.geometry.faces[0].materialIndex);
  // Adding second face
  mesh.geometry.faces.push( new THREE.Face3(temp, index, mesh.geometry.faces[0].c, mesh.geometry.faces[0].normal, mesh.geometry.faces[0].color, mesh.geometry.faces[0].materialIndex ) );

  mesh.geometry.verticesNeedUpdate = true;
  mesh.geometry.facesNeedUpdate = true;
});

function animate() {
  if(rotateY) mesh.rotateY(0.01);
  if(rotateZ) mesh.rotateZ(0.01);
  if(rotateX) mesh.rotateX(0.01);
  // Render the scene
  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}

