From decbadc2b0a7b456395e0c7a0893535b9391f5a8 Mon Sep 17 00:00:00 2001
From: Tazpn <tazpn@users.sourceforge.net>
Date: Sat, 26 Aug 2006 22:12:00 +0000
Subject: [PATCH] Fix Import/Export of Normals.

---
 MaxNifPlugins_Readme.txt        | 10 +++++-
 NifExport/Mesh.cpp              | 18 ++++++++--
 NifImport/ImportMeshAndSkin.cpp | 59 ++++++++++++++++++++++++++-------
 3 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/MaxNifPlugins_Readme.txt b/MaxNifPlugins_Readme.txt
index 10c7a6b..cfbd87c 100644
--- a/MaxNifPlugins_Readme.txt
+++ b/MaxNifPlugins_Readme.txt
@@ -1,4 +1,4 @@
-                        MaxPlugins 0.2.1
+                        MaxPlugins 0.2.2
                         ================
 
  
@@ -27,6 +27,14 @@
 
     Change log
     ----------
+      0.2.1
+      -----
+    o Exporter
+      - Fix Export of Normal values
+      
+    o Importer
+      - Fix Import of Normal values
+      
       0.2.1
       -----
     o Exporter
diff --git a/NifExport/Mesh.cpp b/NifExport/Mesh.cpp
index dba3ae8..aef4941 100755
--- a/NifExport/Mesh.cpp
+++ b/NifExport/Mesh.cpp
@@ -1,6 +1,7 @@
 #include "pch.h"
 #include "niutils.h"
 #include "iskin.h"
+#include "MeshNormalSpec.h"
 #ifdef USE_BIPED
 #  include <cs/BipedApi.h>
 #endif
@@ -164,8 +165,13 @@ Exporter::Result Exporter::exportMesh(NiNodeRef &ninode, INode *node, TimeValue
       }
       if (!hasvc) vertColors.clear();
    }
-
-	mesh->buildNormals();
+   
+   MeshNormalSpec *specNorms = mesh->GetSpecifiedNormals ();
+   if (NULL != specNorms) {
+      specNorms->CheckNormals();
+   } else {
+      mesh->checkNormals(TRUE);
+   }
 
 	Result result = Ok;
 	while (1)
@@ -254,7 +260,13 @@ int Exporter::addVertex(FaceGroup &grp, int face, int vi, Mesh *mesh, const Matr
 {
    int vidx = mesh->faces[ face ].v[ vi ];
 	Point3 pt = mesh->verts[ vidx ];
-	Point3 norm = getVertexNormal(mesh, face, mesh->getRVertPtr(vidx));
+   Point3 norm;
+
+   MeshNormalSpec *specNorms = mesh->GetSpecifiedNormals ();
+   if (NULL != specNorms)
+      norm = specNorms->GetNormal(face, vi);
+   else
+      norm = getVertexNormal(mesh, face, mesh->getRVertPtr(vidx));
 
 	Point3 uv;
    if (mesh->tVerts && mesh->tvFace) {
diff --git a/NifImport/ImportMeshAndSkin.cpp b/NifImport/ImportMeshAndSkin.cpp
index 846be26..ff29936 100644
--- a/NifImport/ImportMeshAndSkin.cpp
+++ b/NifImport/ImportMeshAndSkin.cpp
@@ -13,6 +13,7 @@ HISTORY:
 #include "stdafx.h"
 #include "MaxNifImport.h"
 #include "istdplug.h"
+#include "MeshNormalSpec.h"
 
 using namespace Niflib;
 
@@ -84,30 +85,64 @@ bool NifImporter::ImportMesh(ImpNode *node, TriObject *o, NiTriBasedGeomRef triG
          }
       }
    }
-   if (removeDegenerateFaces)
-      mesh.RemoveDegenerateFaces();
-   if (removeIllegalFaces)
-      mesh.RemoveIllegalFaces();
-   if (enableAutoSmooth)
-      mesh.AutoSmooth(TORAD(autoSmoothAngle), FALSE, FALSE);
+   // Triangles and texture vertices
+   SetTrangles(mesh, tris);
 
    // Normals
    {
       mesh.checkNormals(TRUE);
       vector<Vector3> n = triGeomData->GetNormals();
-      for (int i=0; i<n.size(); i++){
-         Vector3 v = n[i];
-         mesh.setNormal(i, Point3(v.x, v.y, v.z));
+      if (n.size() > 0)
+      {
+         bool needNormals = false;
+         for (int i=0; i<n.size(); i++){
+            Vector3 v = n[i];
+            Point3 norm(v.x, v.y, v.z);
+            if (norm != mesh.getNormal(i)) {
+               needNormals = true;
+               break;
+            }
+         }
+         if (needNormals)
+         {
+            mesh.SpecifyNormals();
+            MeshNormalSpec *specNorms = mesh.GetSpecifiedNormals ();
+            if (NULL != specNorms)
+            {
+               specNorms->ClearAndFree();
+               specNorms->SetNumFaces(tris.size());
+               specNorms->SetNumNormals(n.size());
+
+               Point3* norms = specNorms->GetNormalArray();
+               for (int i=0; i<n.size(); i++){
+                  Vector3 v = n[i];
+                  norms[i] = Point3(v.x, v.y, v.z);
+               }
+               MeshNormalFace* pFaces = specNorms->GetFaceArray();
+               for (int i=0; i<tris.size(); i++){
+                  Triangle& tri = tris[i];
+                  pFaces[i].SpecifyNormalID(0, tri.v1);
+                  pFaces[i].SpecifyNormalID(1, tri.v2);
+                  pFaces[i].SpecifyNormalID(2, tri.v3);
+               }
+               specNorms->SetAllExplicit(true);
+               specNorms->CheckNormals();
+            }
+         }
       }
    }
 
-   // Triangles and texture vertices
-   SetTrangles(mesh, tris);
-
    ImportVertexColor(node, o, triGeom, triGeomData, tris);
 
    ImportMaterialAndTextures(node, triGeom);
 
+   if (removeDegenerateFaces)
+      mesh.RemoveDegenerateFaces();
+   if (removeIllegalFaces)
+      mesh.RemoveIllegalFaces();
+   if (enableAutoSmooth)
+      mesh.AutoSmooth(TORAD(autoSmoothAngle), FALSE, FALSE);
+
    if (enableSkinSupport)
       ImportSkin(node, triGeom);
 
-- 
GitLab