Skip to content

Commit

Permalink
Fix import when shapes are not split into several .obj files.
Browse files Browse the repository at this point in the history
  • Loading branch information
julienkay committed Sep 1, 2022
1 parent 55d9872 commit b5b8208
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 27 deletions.
86 changes: 63 additions & 23 deletions Assets/Editor/MobileNeRFImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,19 @@ private static string GetFeatureTextureAssetPath(string objName, int shapeNum, i
return path;
}

private static string GetObjAssetPath(string objName, int i, int j) {
string path = $"{GetBasePath(objName)}/OBJs/shape{i}_{j}.obj";
private static string GetObjBaseAssetPath(string objName) {
string path = $"{GetBasePath(objName)}/OBJs/";
Directory.CreateDirectory(Path.GetDirectoryName(path));
return path;
}

private static string GetObjAssetPath(string objName, int i, int j, bool splitShapes) {
string path;
if (splitShapes) {
path = $"{GetBasePath(objName)}/OBJs/shape{i}_{j}.obj";
} else {
path = $"{GetBasePath(objName)}/OBJs/shape{i}.obj";
}
Directory.CreateDirectory(Path.GetDirectoryName(path));
return path;
}
Expand All @@ -218,8 +229,13 @@ private static string GetShaderAssetPath(string objName) {
return path;
}

private static string GetDefaultMaterialAssetPath(string objName, int i, int j) {
string path = $"{GetBasePath(objName)}/OBJs/Materials/shape{i}_{j}-defaultMat.mat";
private static string GetDefaultMaterialAssetPath(string objName, int i, int j, bool splitShapes) {
string path;
if (splitShapes) {
path = $"{GetBasePath(objName)}/OBJs/Materials/shape{i}_{j}-defaultMat.mat";
} else {
path = $"{GetBasePath(objName)}/OBJs/Materials/shape{i}-defaultMat.mat";
}
Directory.CreateDirectory(Path.GetDirectoryName(path));
return path;
}
Expand Down Expand Up @@ -395,18 +411,29 @@ private static async Task DonloadPNGsAsync(MNeRFScene scene, Mlp mlp) {
/// </summary>
private static bool CopyOBJsFromPath(string path, Mlp mlp) {
string objName = new DirectoryInfo(path).Name;
int totalOBJs = mlp.ObjNum * 8;

string[] objPaths = Directory.GetFiles(path, "shape*_*.obj", SearchOption.TopDirectoryOnly);
if (objPaths.Length != totalOBJs) {
EditorUtility.DisplayDialog(ImportErrorTitle, $"Invalid number of 3D models found. Expected: {mlp.ObjNum}. Actual: {objPaths.Length}", OK);
string[] objPaths = Directory.GetFiles(path, "shape*.obj", SearchOption.TopDirectoryOnly);
bool splitShapes = AreOBJsSplit(path);
int numSplitShapes = GetNumSplitShapes(splitShapes);

if (splitShapes && objPaths.Length != mlp.ObjNum * 8) {
EditorUtility.DisplayDialog(ImportErrorTitle, $"Invalid number of shape files found. Expected: {mlp.ObjNum * 8}. Actual: {objPaths.Length}", OK);
return false;
} else if (!splitShapes && objPaths.Length != mlp.ObjNum) {
EditorUtility.DisplayDialog(ImportErrorTitle, $"Invalid number of shape files found. Expected: {mlp.ObjNum }. Actual: {objPaths.Length}", OK);
return false;
}

for (int i = 0; i < mlp.ObjNum; i++) {
for (int j = 0; j < 8; j++) {
string objPath = Path.Combine(path, $"shape{i}_{j}.obj");
string objAssetPath = GetObjAssetPath(objName, i, j);
for (int j = 0; j < numSplitShapes; j++) {
string objPath;
if (splitShapes) {
objPath = Path.Combine(path, $"shape{i}_{j}.obj");
} else {
objPath = Path.Combine(path, $"shape{i}.obj");
}

string objAssetPath = GetObjAssetPath(objName, i, j, splitShapes);

if (!File.Exists(objPath)) {
EditorUtility.DisplayDialog(ImportErrorTitle, $"Required .obj file not found: {objPath}", OK);
Expand All @@ -424,14 +451,28 @@ private static bool CopyOBJsFromPath(string path, Mlp mlp) {
return true;
}

private static bool AreOBJsSplit(string path) {
if (Directory.GetFiles(path, "shape*_*.obj", SearchOption.TopDirectoryOnly).Length > 0) {
return true;
} else if (Directory.GetFiles(path, "shape*.obj", SearchOption.TopDirectoryOnly).Length > 0) {
return false;
} else {
return false;
}
}

private static int GetNumSplitShapes(bool splitShapes) {
return splitShapes ? 8 : 1;
}

/// <summary>
/// Downloads the 3D models for the given MobileNeRF demo scene.
/// </summary>
private static async Task DownloadOBJsAsync(MNeRFScene scene, Mlp mlp) {
for (int i = 0; i < mlp.ObjNum; i++) {
for (int j = 0; j < 8; j++) {
string objUrl = GetOBJUrl(scene, i, j);
string objAssetPath = GetObjAssetPath(scene.String(), i, j);
string objAssetPath = GetObjAssetPath(scene.String(), i, j, splitShapes: true);

if (File.Exists(objAssetPath)) {
continue;
Expand All @@ -444,20 +485,17 @@ private static async Task DownloadOBJsAsync(MNeRFScene scene, Mlp mlp) {
}

private static void ProcessOBJs(string objName, Mlp mlp) {
for (int i = 0; i < mlp.ObjNum; i++) {
for (int j = 0; j < 8; j++) {
string objAssetPath = GetObjAssetPath(objName, i, j);
bool splitShapes = AreOBJsSplit(GetObjBaseAssetPath(objName));
int numSplitShapes = GetNumSplitShapes(splitShapes);

// model settings - one material per shape (each has individual feature textures)
ModelImporter modelImport = AssetImporter.GetAtPath(objAssetPath) as ModelImporter;
modelImport.materialLocation = ModelImporterMaterialLocation.External;
modelImport.materialName = ModelImporterMaterialName.BasedOnModelNameAndMaterialName;
AssetDatabase.ImportAsset(objAssetPath);
for (int i = 0; i < mlp.ObjNum; i++) {
for (int j = 0; j < numSplitShapes; j++) {
string objAssetPath = GetObjAssetPath(objName, i, j, splitShapes);

// create material
string shaderAssetPath = GetShaderAssetPath(objName);
Shader mobileNeRFShader = AssetDatabase.LoadAssetAtPath<Shader>(shaderAssetPath);
string materialAssetPath = GetDefaultMaterialAssetPath(objName, i, j);
string materialAssetPath = GetDefaultMaterialAssetPath(objName, i, j, splitShapes);
Material material = AssetDatabase.LoadAssetAtPath<Material>(materialAssetPath);
material.shader = mobileNeRFShader;

Expand Down Expand Up @@ -573,10 +611,12 @@ private static StringBuilder toBiasList(double[] biases) {
}

private static void CreatePrefab(string objName, Mlp mlp) {
bool splitShapes = AreOBJsSplit(GetObjBaseAssetPath(objName));
int numSplitShapes = GetNumSplitShapes(splitShapes);
GameObject prefabObject = new GameObject(objName);
for (int i = 0; i < mlp.ObjNum; i++) {
for (int j = 0; j < 8; j++) {
GameObject shapeModel = AssetDatabase.LoadAssetAtPath<GameObject>(GetObjAssetPath(objName, i, j));
for (int j = 0; j < numSplitShapes; j++) {
GameObject shapeModel = AssetDatabase.LoadAssetAtPath<GameObject>(GetObjAssetPath(objName, i, j, splitShapes));
GameObject shape = GameObject.Instantiate(shapeModel);
shape.name = shape.name.Replace("(Clone)", "");
shape.transform.SetParent(prefabObject.transform, false);
Expand Down
11 changes: 8 additions & 3 deletions Assets/Editor/ObjImportProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
using UnityEditor;

/// <summary>
/// MobileNeRFs don't use normals, so we disable trying to read them when importing .obj files
/// This is not strictly necessary, but prevents the warnings showing in the console.
/// Custom import settings for MobileNeRF OBJs.
/// </summary>
public class ObjImportProcessor : AssetPostprocessor {
private void OnPreprocessModel() {
Regex objPattern = new Regex("shape[0-9]_[0-9].obj");
Regex objPattern = new Regex(@"shape.*\.obj");

if (objPattern.IsMatch(assetPath)) {
ModelImporter modelImporter = assetImporter as ModelImporter;
// MobileNeRFs don't use normals, so we disable trying to read them when importing .obj files
// This is not strictly necessary, but prevents the warnings showing in the console.
modelImporter.importTangents = ModelImporterTangents.None;
modelImporter.importNormals = ModelImporterNormals.None;

// one material per shape (each has individual feature textures)
modelImporter.materialLocation = ModelImporterMaterialLocation.External;
modelImporter.materialName = ModelImporterMaterialName.BasedOnModelNameAndMaterialName;
}
}
}
2 changes: 1 addition & 1 deletion Assets/Editor/PNGImportProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class PNGImportProcessor : AssetPostprocessor {

private void OnPreprocessTexture() {
Regex featureTexturePattern = new Regex("shape[0-9].pngfeat[0-9].png");
Regex featureTexturePattern = new Regex(@"shape[0-9].pngfeat[0-9]\.png");
if (featureTexturePattern.IsMatch(assetPath)) {
TextureImporter textureImporter = assetImporter as TextureImporter;
textureImporter.maxTextureSize = 4096;
Expand Down

0 comments on commit b5b8208

Please sign in to comment.