<p dir="auto">I have a large mesh, which I intend to render without smooth shading. As such, there is no point calculating vertex normals. Normally, this is ok, since I can do:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="geom.computeFaceNormals();
if(smoothShading) geom.computeVertexNormals();"><pre class="notranslate"><code class="notranslate">geom.computeFaceNormals();
if(smoothShading) geom.computeVertexNormals();
</code></pre></div>
<p dir="auto">However, when I do <code class="notranslate">geometry.computeMorphNormals()</code>, it does both steps at once. Could this be sensibly split into two distinct steps?</p>
<p dir="auto">At present, I've just hacked in an impaired version of <code class="notranslate">THREE.Geometry.prototype.computeMorphNormals</code> that doesn't touch vertex normals, but I'm not keen on the code duplication:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
// Calculate only face normals, not morph normals, which is much faster
THREE.Geometry.prototype.computeMorphFaceNormals = function () {

        var i, il, f, fl, face;

        // save original normals
        // - create temp variables on first access
        //   otherwise just copy (for faster repeated calls)

        for ( f = 0, fl = this.faces.length; f &lt; fl; f ++ ) {

                face = this.faces[ f ];

                if ( ! face.__originalFaceNormal ) {

                        face.__originalFaceNormal = face.normal.clone();

                } else {

                        face.__originalFaceNormal.copy( face.normal );

                }

        }

        // use temp geometry to compute face and vertex normals for each morph

        var tmpGeo = new THREE.Geometry();
        tmpGeo.faces = this.faces;

        for ( i = 0, il = this.morphTargets.length; i &lt; il; i ++ ) {

                // create on first access

                if ( ! this.morphNormals[ i ] ) {

                        this.morphNormals[ i ] = {};
                        this.morphNormals[ i ].faceNormals = [];

                        var dstNormalsFace = this.morphNormals[ i ].faceNormals;

                        var faceNormal;

                        for ( f = 0, fl = this.faces.length; f &lt; fl; f ++ ) {

                                face = this.faces[ f ];

                                faceNormal = new THREE.Vector3();
                                dstNormalsFace.push( faceNormal );

                        }

                }

                var morphNormals = this.morphNormals[ i ];

                // set vertices to morph target

                tmpGeo.vertices = this.morphTargets[ i ].vertices;

                // compute morph normals

                tmpGeo.computeFaceNormals();

                // store morph normals

                var faceNormal;

                for ( f = 0, fl = this.faces.length; f &lt; fl; f ++ ) {

                        face = this.faces[ f ];

                        faceNormal = morphNormals.faceNormals[ f ];

                        faceNormal.copy( face.normal );

                }

        }

        // restore original normals

        for ( f = 0, fl = this.faces.length; f &lt; fl; f ++ ) {

                face = this.faces[ f ];

                face.normal = face.__originalFaceNormal;

        }

}"><pre class="notranslate"><span class="pl-c">// Calculate only face normals, not morph normals, which is much faster</span>
<span class="pl-c1">THREE</span><span class="pl-kos">.</span><span class="pl-c1">Geometry</span><span class="pl-kos">.</span><span class="pl-c1">prototype</span><span class="pl-kos">.</span><span class="pl-en">computeMorphFaceNormals</span> <span class="pl-c1">=</span> <span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>

        <span class="pl-k">var</span> <span class="pl-s1">i</span><span class="pl-kos">,</span> <span class="pl-s1">il</span><span class="pl-kos">,</span> <span class="pl-s1">f</span><span class="pl-kos">,</span> <span class="pl-s1">fl</span><span class="pl-kos">,</span> <span class="pl-s1">face</span><span class="pl-kos">;</span>

        <span class="pl-c">// save original normals</span>
        <span class="pl-c">// - create temp variables on first access</span>
        <span class="pl-c">//   otherwise just copy (for faster repeated calls)</span>

        <span class="pl-k">for</span> <span class="pl-kos">(</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-s1">fl</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-s1">f</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">fl</span><span class="pl-kos">;</span> <span class="pl-s1">f</span> <span class="pl-c1">++</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>

                <span class="pl-s1">face</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">[</span> <span class="pl-s1">f</span> <span class="pl-kos">]</span><span class="pl-kos">;</span>

                <span class="pl-k">if</span> <span class="pl-kos">(</span> <span class="pl-c1">!</span> <span class="pl-s1">face</span><span class="pl-kos">.</span><span class="pl-c1">__originalFaceNormal</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>

                        <span class="pl-s1">face</span><span class="pl-kos">.</span><span class="pl-c1">__originalFaceNormal</span> <span class="pl-c1">=</span> <span class="pl-s1">face</span><span class="pl-kos">.</span><span class="pl-c1">normal</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-kos">;</span>

                <span class="pl-kos">}</span> <span class="pl-k">else</span> <span class="pl-kos">{</span>

                        <span class="pl-s1">face</span><span class="pl-kos">.</span><span class="pl-c1">__originalFaceNormal</span><span class="pl-kos">.</span><span class="pl-en">copy</span><span class="pl-kos">(</span> <span class="pl-s1">face</span><span class="pl-kos">.</span><span class="pl-c1">normal</span> <span class="pl-kos">)</span><span class="pl-kos">;</span>

                <span class="pl-kos">}</span>

        <span class="pl-kos">}</span>

        <span class="pl-c">// use temp geometry to compute face and vertex normals for each morph</span>

        <span class="pl-k">var</span> <span class="pl-s1">tmpGeo</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">Geometry</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-s1">tmpGeo</span><span class="pl-kos">.</span><span class="pl-c1">faces</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">;</span>

        <span class="pl-k">for</span> <span class="pl-kos">(</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-s1">il</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">morphTargets</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">il</span><span class="pl-kos">;</span> <span class="pl-s1">i</span> <span class="pl-c1">++</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>

                <span class="pl-c">// create on first access</span>

                <span class="pl-k">if</span> <span class="pl-kos">(</span> <span class="pl-c1">!</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">morphNormals</span><span class="pl-kos">[</span> <span class="pl-s1">i</span> <span class="pl-kos">]</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>

                        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">morphNormals</span><span class="pl-kos">[</span> <span class="pl-s1">i</span> <span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
                        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">morphNormals</span><span class="pl-kos">[</span> <span class="pl-s1">i</span> <span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">faceNormals</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>

                        <span class="pl-k">var</span> <span class="pl-s1">dstNormalsFace</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">morphNormals</span><span class="pl-kos">[</span> <span class="pl-s1">i</span> <span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">faceNormals</span><span class="pl-kos">;</span>

                        <span class="pl-k">var</span> <span class="pl-s1">faceNormal</span><span class="pl-kos">;</span>

                        <span class="pl-k">for</span> <span class="pl-kos">(</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-s1">fl</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-s1">f</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">fl</span><span class="pl-kos">;</span> <span class="pl-s1">f</span> <span class="pl-c1">++</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>

                                <span class="pl-s1">face</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">[</span> <span class="pl-s1">f</span> <span class="pl-kos">]</span><span class="pl-kos">;</span>

                                <span class="pl-s1">faceNormal</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">Vector3</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
                                <span class="pl-s1">dstNormalsFace</span><span class="pl-kos">.</span><span class="pl-en">push</span><span class="pl-kos">(</span> <span class="pl-s1">faceNormal</span> <span class="pl-kos">)</span><span class="pl-kos">;</span>

                        <span class="pl-kos">}</span>

                <span class="pl-kos">}</span>

                <span class="pl-k">var</span> <span class="pl-s1">morphNormals</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">morphNormals</span><span class="pl-kos">[</span> <span class="pl-s1">i</span> <span class="pl-kos">]</span><span class="pl-kos">;</span>

                <span class="pl-c">// set vertices to morph target</span>

                <span class="pl-s1">tmpGeo</span><span class="pl-kos">.</span><span class="pl-c1">vertices</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">morphTargets</span><span class="pl-kos">[</span> <span class="pl-s1">i</span> <span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">vertices</span><span class="pl-kos">;</span>

                <span class="pl-c">// compute morph normals</span>

                <span class="pl-s1">tmpGeo</span><span class="pl-kos">.</span><span class="pl-en">computeFaceNormals</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

                <span class="pl-c">// store morph normals</span>

                <span class="pl-k">var</span> <span class="pl-s1">faceNormal</span><span class="pl-kos">;</span>

                <span class="pl-k">for</span> <span class="pl-kos">(</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-s1">fl</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-s1">f</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">fl</span><span class="pl-kos">;</span> <span class="pl-s1">f</span> <span class="pl-c1">++</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>

                        <span class="pl-s1">face</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">[</span> <span class="pl-s1">f</span> <span class="pl-kos">]</span><span class="pl-kos">;</span>

                        <span class="pl-s1">faceNormal</span> <span class="pl-c1">=</span> <span class="pl-s1">morphNormals</span><span class="pl-kos">.</span><span class="pl-c1">faceNormals</span><span class="pl-kos">[</span> <span class="pl-s1">f</span> <span class="pl-kos">]</span><span class="pl-kos">;</span>

                        <span class="pl-s1">faceNormal</span><span class="pl-kos">.</span><span class="pl-en">copy</span><span class="pl-kos">(</span> <span class="pl-s1">face</span><span class="pl-kos">.</span><span class="pl-c1">normal</span> <span class="pl-kos">)</span><span class="pl-kos">;</span>

                <span class="pl-kos">}</span>

        <span class="pl-kos">}</span>

        <span class="pl-c">// restore original normals</span>

        <span class="pl-k">for</span> <span class="pl-kos">(</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span><span class="pl-kos">,</span> <span class="pl-s1">fl</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">.</span><span class="pl-c1">length</span><span class="pl-kos">;</span> <span class="pl-s1">f</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">fl</span><span class="pl-kos">;</span> <span class="pl-s1">f</span> <span class="pl-c1">++</span> <span class="pl-kos">)</span> <span class="pl-kos">{</span>

                <span class="pl-s1">face</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">faces</span><span class="pl-kos">[</span> <span class="pl-s1">f</span> <span class="pl-kos">]</span><span class="pl-kos">;</span>

                <span class="pl-s1">face</span><span class="pl-kos">.</span><span class="pl-c1">normal</span> <span class="pl-c1">=</span> <span class="pl-s1">face</span><span class="pl-kos">.</span><span class="pl-c1">__originalFaceNormal</span><span class="pl-kos">;</span>

        <span class="pl-kos">}</span>

<span class="pl-kos">}</span></pre></div>
<p dir="auto">FYI I'm working on a parasolid exporter (x_t to begin with). Just posting an issue to avoid duplicating effort or in case anyone wants to discuss / collaborate. I expect to have a PR ready in a few weeks.</p>