Skip to content

Commit

Permalink
Obj import refactor and support ngons
Browse files Browse the repository at this point in the history
(single material/mesh per file only at the moment)
  • Loading branch information
andybak committed Jul 6, 2024
1 parent 0c5dc87 commit 8e343f9
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ internal CreateMeshWork(Dictionary<string, Material> materials, string obj,

public void BackgroundWork()
{
successfullyReadMesh = ObjImporter.ImportMeshes(objString, materials, out meshes);
// TODO AB: We need to create mmeshes not MeshVerticesAndTriangles
// successfullyReadMesh = ObjImporter.ImportMeshes(objString, materials, out meshes);
}

public void PostWork()
Expand Down
13 changes: 13 additions & 0 deletions Assets/Scripts/desktop_app/DebugConsole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
Expand Down Expand Up @@ -43,6 +44,7 @@ public class DebugConsole : MonoBehaviour
"flag\n lists/sets feature flags\n" +
"fuse\n fuses all selected meshes into a single mesh.\n" +
"help\n shows this help text\n" +
"import\n insert 3d model (obj, block\n" +
"insert\n insert primitives\n" +
"insertduration <duration>\n sets the mesh insert effect duration (e.g. 0.6).\n" +
"loadfile <path>\n loads a model from the given file (use full path).\n" +
Expand All @@ -63,6 +65,7 @@ public class DebugConsole : MonoBehaviour
public GameObject consoleObject;
public Text consoleOutput;
public InputField consoleInput;
public ObjImportController objImportController;

private string lastCommand = "";

Expand All @@ -73,6 +76,7 @@ public class DebugConsole : MonoBehaviour

public void Start()
{
objImportController = gameObject.GetComponent<ObjImportController>();
consoleOutput.text = "DEBUG CONSOLE\n" +
"Blocks version: " + Config.Instance.version + "\n" +
"For a list of available commands, type 'help'." +
Expand Down Expand Up @@ -190,13 +194,22 @@ private void RunCommand(string command)
case "tut":
CommandTut(parts);
break;
case "import":
CommandImport(parts);
break;
default:
PrintLn("Unrecognized command: " + command);
PrintLn("Type 'help' for a list of commands.");
break;
}
}

private void CommandImport(string[] parts)
{
string userPath = PeltzerMain.Instance.userPath;
objImportController.Import(parts.Skip(1).Select(p => Path.Combine(userPath, p)).ToArray());
}

private void PrintLn(string message)
{
consoleOutput.text += message + "\n";
Expand Down
108 changes: 75 additions & 33 deletions Assets/Scripts/desktop_app/ObjImportController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

using UnityEngine;
using System.IO;
using System.Linq;
using System.Text;
// using System.Windows.Forms;

Expand All @@ -25,7 +26,7 @@
namespace com.google.apps.peltzer.client.desktop_app
{
/// <summary>
/// Responsible for handling the button-click to import obj files from the desktop app, and
/// Responsible for handling the button-click to import obj files from the desktop app, and
/// loading them into the model.
/// </summary>
public class ObjImportController : MonoBehaviour
Expand All @@ -37,14 +38,15 @@ public class ObjImportController : MonoBehaviour
private const float MIN_IMPORTED_OBJ_DISTANCE_FROM_USER = 2.0f;

/// <summary>
/// Handles the button-click to import an obj. Opens up a dialog and in the background, waits for the
/// Either handles the button-click to import an obj. Opens up a dialog and in the background, waits for the
/// user to hit 'ok' with two files selected.
/// or imports the obj files passed in as arguments.
/// </summary>
public void SelectObjToImport()
public void Import(string[] filenames = null)
{
Model model = PeltzerMain.Instance.GetModel();
BackgroundWork openDialog = new OpenFileDialogAndLoadObj(model);
PeltzerMain.Instance.DoPolyMenuBackgroundWork(openDialog);
BackgroundWork work = new LoadObj(model, filenames);
PeltzerMain.Instance.DoPolyMenuBackgroundWork(work);
}

/// <summary>
Expand All @@ -69,51 +71,91 @@ private static string FileToString(string filename)
}
}

class OpenFileDialogAndLoadObj : BackgroundWork
public class LoadObj : BackgroundWork
{
// A reference to the model.
private readonly Model model;
// File contents to be passed from a background thread to a foreground thread.
string mtlFileContents;
string objFileContents;
private string[] filenames;
PeltzerFile peltzerFile;

public OpenFileDialogAndLoadObj(Model model)
public LoadObj(Model model, string[] filenames = null)
{
this.model = model;
this.filenames = filenames;
}

// In the background we perform all the File I/O to get file contents. There are no graceful failures here,
// and there is no feedback to the user in case of failure.
public void BackgroundWork()
{
// OpenFileDialog dialog = new OpenFileDialog();
// dialog.Multiselect = true;
// Expect that the user selected two files, one .obj and one .mtl
// if (dialog.ShowDialog() == DialogResult.OK) {
// if (dialog.FileNames.Length == 1) {
// if (dialog.FileNames[0].EndsWith(".peltzer") || dialog.FileNames[0].EndsWith(".poly")
// || dialog.FileNames[0].EndsWith(".blocks")) {
// byte[] peltzerFileBytes = File.ReadAllBytes(dialog.FileNames[0]);
// PeltzerFileHandler.PeltzerFileFromBytes(peltzerFileBytes, out peltzerFile);
// } else if (dialog.FileNames[0].EndsWith(".obj")) {
// objFileContents = FileToString(dialog.FileNames[0]);
// } else {
// Debug.Log("When selecting only one file for OBJ import, it must have a .obj extension");
// }
// } else if (dialog.FileNames.Length == 2) {
// string objFile = dialog.FileNames[0].EndsWith(".obj") ? dialog.FileNames[0] : dialog.FileNames[1];
// string mtlFile = dialog.FileNames[0].EndsWith(".mtl") ? dialog.FileNames[0] : dialog.FileNames[1];
// if (!objFile.EndsWith(".obj") || !mtlFile.EndsWith(".mtl")) {
// Debug.Log("When selecting two files for OBJ import, one must be .obj and the other .mtl");
// }
if (filenames != null)
{
DoImport(filenames);
}
else
{
// OpenFileDialog dialog = new OpenFileDialog();
// dialog.Multiselect = true;
// // Expect that the user selected two files, one .obj and one .mtl
// if (dialog.ShowDialog() == DialogResult.OK)
// {
// DoImport(dialog.FileNames);
// }

}
}

public void DoImport(string[] filenames)
{
string objFile = null;
string mtlFile = null;

// Should we retire some of these file extensions?
// Does anything other than blocks exist in the wild?
if (filenames.Length == 1 &&
(filenames[0].EndsWith(".peltzer")
|| filenames[0].EndsWith(".poly")
|| filenames[0].EndsWith(".blocks")))
{
byte[] peltzerFileBytes = File.ReadAllBytes(filenames[0]);
PeltzerFileHandler.PeltzerFileFromBytes(peltzerFileBytes, out peltzerFile);
return;
}

if (filenames.Length == 1 && filenames[0].EndsWith(".obj"))
{
objFile = filenames[0];
mtlFile = filenames[0].Replace(".obj", ".mtl");
if (!File.Exists(mtlFile))
{
mtlFile = null;
}
}
else if (filenames.Length == 2)
{
objFile = filenames.FirstOrDefault(f => f.EndsWith(".obj"));
mtlFile = filenames.FirstOrDefault(f => f.EndsWith(".mtl"));
}

// objFileContents = FileToString(objFile);
// mtlFileContents = FileToString(mtlFile);
// } else {
// Debug.Log("Exactly one .obj file or a pair of .obj and .mtl files must be selected for OBJ import");
// }
// }
if (filenames.Length == 2 && mtlFile == null)
{
Debug.Log("When selecting two files for OBJ import, one must be .obj and the other .mtl");
}
else if (objFile == null)
{
Debug.Log("Exactly one .obj file or a pair of .obj and .mtl files must be selected for OBJ import");
}
else
{
objFileContents = FileToString(objFile);
if (mtlFile != null)
{
mtlFileContents = FileToString(mtlFile);
}
}
}

// In the foreground we add the mesh to the model.
Expand Down
Loading

0 comments on commit 8e343f9

Please sign in to comment.