<h5 dir="auto">Description of the problem</h5>
<p dir="auto">I seems that DirectGeometry.fromGeometry creates duplicate vertices. In <a href="https://github.com/mrdoob/three.js/blob/dev/src/core/DirectGeometry.js#L170">this</a> line of code vertices are created when looping through faces, not vertices. This result in duplicate vertices.</p>
<p dir="auto">I think this is unintended, or am I missing something?.</p>
<p dir="auto">This problem effects BufferGeometry (via fromGeometry) and means the WebGL renderer needs to do ~6x as much work.</p>
<p dir="auto">Working example:</p>
<ul dir="auto">
<li><a href="http://jsfiddle.net/wassname/rvg3gv8o/1/" rel="nofollow">JSFiddle</a></li>
</ul>
<p dir="auto">To replicate this, convert a geometry to buffer geometry and back again. Then compare the vertices as below:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// extract from jsfiddle
var bufferGeom = new THREE.BufferGeometry()
bufferGeom.fromGeometry(geometry)

var newGeom = geometry.clone()
newGeom.fromBufferGeometry(bufferGeom)

if (newGeom.vertices.length != geometry.vertices.length) {
  console.error('The new geometry has ', newGeom.vertices.length, 'vertices while the geometry only had ', geometry.vertices.length)
}"><pre class="notranslate"><span class="pl-c">// extract from jsfiddle</span>
<span class="pl-k">var</span> <span class="pl-s1">bufferGeom</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-c1">THREE</span><span class="pl-kos">.</span><span class="pl-c1">BufferGeometry</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
<span class="pl-s1">bufferGeom</span><span class="pl-kos">.</span><span class="pl-en">fromGeometry</span><span class="pl-kos">(</span><span class="pl-s1">geometry</span><span class="pl-kos">)</span>

<span class="pl-k">var</span> <span class="pl-s1">newGeom</span> <span class="pl-c1">=</span> <span class="pl-s1">geometry</span><span class="pl-kos">.</span><span class="pl-en">clone</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
<span class="pl-s1">newGeom</span><span class="pl-kos">.</span><span class="pl-en">fromBufferGeometry</span><span class="pl-kos">(</span><span class="pl-s1">bufferGeom</span><span class="pl-kos">)</span>

<span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">newGeom</span><span class="pl-kos">.</span><span class="pl-c1">vertices</span><span class="pl-kos">.</span><span class="pl-c1">length</span> <span class="pl-c1">!=</span> <span class="pl-s1">geometry</span><span class="pl-kos">.</span><span class="pl-c1">vertices</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">error</span><span class="pl-kos">(</span><span class="pl-s">'The new geometry has '</span><span class="pl-kos">,</span> <span class="pl-s1">newGeom</span><span class="pl-kos">.</span><span class="pl-c1">vertices</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">,</span> <span class="pl-s">'vertices while the geometry only had '</span><span class="pl-kos">,</span> <span class="pl-s1">geometry</span><span class="pl-kos">.</span><span class="pl-c1">vertices</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">)</span>
<span class="pl-kos">}</span></pre></div>
<h5 dir="auto">Three.js version</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> Dev</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> r75</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> ...</li>
</ul>
<h5 dir="auto">Browser</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> All of them</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Chrome</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Firefox</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Internet Explorer</li>
</ul>
<h5 dir="auto">OS</h5>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> All of them</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Windows</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Linux</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> Android</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> IOS</li>
</ul>
<h5 dir="auto">Hardware Requirements (graphics card, VR Device, ...)</h5>
<p dir="auto">NA</p>
<p dir="auto">I miss the wireframe feature on BufferGeometry based objects like Planes (e.g. webgl_geometry_extrude_shapes2.html). I'm not sure why it was removed.</p>
<p dir="auto">So I tried to put it back in. I added some code in "WebGLRenderer.js" to "renderBufferDirect" and it worked as expected:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="
    var offsets = geometry.offsets;

    if ( offsets.length === 0 ) {

+       if ( material.wireframe ) {
+           
+           if ( updateBuffers ) {
+
+               setupVertexAttributes( material, programAttributes, geometryAttributes, 0 );
+               
+               var webglLineBuffer = _gl.createBuffer();
+               var lineArray = new Uint16Array( index.array.length * 2 );
+               var f, fl, offset_line = 0;
+               
+               for ( f = 0, fl = index.array.length; f &lt; fl; f ++ ) {
+                   lineArray[ offset_line ]     = index.array[f];
+                   lineArray[ offset_line + 1 ] = index.array[f+1];
+                   
+                   lineArray[ offset_line + 2 ] = index.array[f+1];
+                   lineArray[ offset_line + 3 ] = index.array[f+2];
+                   
+                   lineArray[ offset_line + 4 ] = index.array[f+2];
+                   lineArray[ offset_line + 5 ] = index.array[f];
+                   
+                   offset_line += 6;
+                   f += 2;
+               }
+               
+               _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, webglLineBuffer );
+               _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, _gl.DYNAMIC_DRAW );
+
+           }
+
+           _gl.drawElements( _gl.LINES, lineArray.length, type, 0 );
+       } else {

            if ( updateBuffers ) {

                setupVertexAttributes( material, programAttributes, geometryAttributes, 0 );
                _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );

            }

            _gl.drawElements( _gl.TRIANGLES, index.array.length, type, 0 );
+       }

        _this.info.render.calls ++;
        _this.info.render.vertices += index.array.length; // not really true, here vertices can be shared
        _this.info.render.faces += index.array.length / 3;

    } else {"><pre class="notranslate"><code class="notranslate">
    var offsets = geometry.offsets;

    if ( offsets.length === 0 ) {

+       if ( material.wireframe ) {
+           
+           if ( updateBuffers ) {
+
+               setupVertexAttributes( material, programAttributes, geometryAttributes, 0 );
+               
+               var webglLineBuffer = _gl.createBuffer();
+               var lineArray = new Uint16Array( index.array.length * 2 );
+               var f, fl, offset_line = 0;
+               
+               for ( f = 0, fl = index.array.length; f &lt; fl; f ++ ) {
+                   lineArray[ offset_line ]     = index.array[f];
+                   lineArray[ offset_line + 1 ] = index.array[f+1];
+                   
+                   lineArray[ offset_line + 2 ] = index.array[f+1];
+                   lineArray[ offset_line + 3 ] = index.array[f+2];
+                   
+                   lineArray[ offset_line + 4 ] = index.array[f+2];
+                   lineArray[ offset_line + 5 ] = index.array[f];
+                   
+                   offset_line += 6;
+                   f += 2;
+               }
+               
+               _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, webglLineBuffer );
+               _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, _gl.DYNAMIC_DRAW );
+
+           }
+
+           _gl.drawElements( _gl.LINES, lineArray.length, type, 0 );
+       } else {

            if ( updateBuffers ) {

                setupVertexAttributes( material, programAttributes, geometryAttributes, 0 );
                _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );

            }

            _gl.drawElements( _gl.TRIANGLES, index.array.length, type, 0 );
+       }

        _this.info.render.calls ++;
        _this.info.render.vertices += index.array.length; // not really true, here vertices can be shared
        _this.info.render.faces += index.array.length / 3;

    } else {
</code></pre></div>
<p dir="auto">This is probably not the best place to put this creation of the lineArray and it's certainly not the only place where this has to be done. But it doesn't look very complicated.</p>
<p dir="auto">Unfortunately I'm not deep enough into this code to do it myself without breaking something important. Nevertheless I would love to see wireframe resurrected :-)</p>