Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
205 lines (179 sloc) 7.48 KB
<!DOCTYPE html>
<html>
<head>
<style>
html {
font-family: sans-serif;
height: 100%;
}
.field {
margin-left: 10px;
margin-right: 10px;
margin-top: 10px;
margin-bottom: 10px;
}
.output {
margin-left: 10px;
margin-right: 10px;
margin-top: 10px;
margin-bottom: 20px;
}
.buttonpane {
margin-top: 20px;
margin-bottom: 20px;
}
.helptext {
margin-top: 5px;
font-size: small;
font-style: italic;
}
textarea {
font-family: monospace;
font-size: 14px;
margin-top: 10px;
width: 75%;
max-width: 100%;
height: 300px;
white-space: pre;
word-wrap: normal;
}
label {
font-weight: bold;
font-size: 14px;
}
input, select {
margin-top: 5px;
</style>
</head>
<body>
<h2>OBJ to C++ Converter</h2>
Upload an OBJ file to convert it to C++ code for use with the <a href="https://github.com/menehune23/projection" target="_blank">Arduino Projection library</a>
<div class="helptext">
Requires a modern browser with HTML 5 compatibility
</div>
<div class="field">
<label>OBJ File</label>
<br/>
<div id="file_div">
<input id="obj_file" type="file" accept=".obj" onchange="enableConvert()">
</div>
</div>
<div class="field">
<label>Tabs</label>
<br/>
<select id="tab_sel">
<option value="&#9;">Tab</option>
<option value=" ">1 space</option>
<option value=" ">2 spaces</option>
<option value=" ">3 spaces</option>
<option value=" " selected>4 spaces</option>
<option value=" ">5 spaces</option>
<option value=" ">6 spaces</option>
<option value=" ">7 spaces</option>
<option value=" ">8 spaces</option>
<option value=" ">9 spaces</option>
<option value=" ">10 spaces</option>
</select>
</div>
<div class="output">
<div class="buttonpane">
<input id="convert_button" type="button" value="Convert" onclick="convertFile()" disabled="true">
<input id="clear_button" type="button" value="Clear" onclick="clearFile()">
</div>
<label>C++ Code</label>
<div class="helptext">
Click text area to select code
</div>
<textarea id="cpp_text" readonly="true" onclick="this.select()"></textarea>
</div>
<script>
// Enables convert button
function enableConvert() {
document.getElementById("convert_button").disabled = false;
}
// Clears file input and C++ text
function clearFile() {
// Reset file input
document.getElementById("file_div").innerHTML = document.getElementById("file_div").innerHTML;
// Reset C++ text
document.getElementById("cpp_text").innerHTML = "";
// Disable convert button
document.getElementById("convert_button").disabled = true;
}
// Loads OBJ file and converts it to C++ code
function convertFile() {
if (!window.FileReader) {
alert("This browser does not support HTML 5!");
return;
}
var file = document.getElementById("obj_file").files[0];
if (file) {
// Create a reader
var reader = new FileReader();
reader.onload = function(e) {
document.getElementById("cpp_text").innerHTML = parseFile(e.target.result);
}
// Read file
reader.readAsText(file);
} else {
alert("Error loading file!");
}
}
// Parses OBJ file contents and returns C++ code
function parseFile(content) {
var lines = content.split("\n");
var line;
var verts = "point3 vertices[] = {\n";
var indices = "lineIndices[] = {\n";
var numVerts = 0;
var numIndices = 0;
var tabSel = document.getElementById("tab_sel");
var tab = tabSel.options[tabSel.selectedIndex].value;
var edges = {};
for (var i = 0; i < lines.length; i++) {
line = lines[i];
switch (line.substr(0, 2))
{
// Add new vertex
case "v ":
verts += tab + "{ " + line.substr(2).replace(new RegExp(" ", "g"), ", ") + " },\n";
numVerts++;
break;
// Add new face lines
case "l ":
case "f ":
face = line.substr(2).split(" ");
for (var v = 0; v < face.length; v++)
{
// Get endpoints
// According to https://en.wikipedia.org/wiki/Wavefront_.obj_file#Face_elements
// Only first part before first slash (/), is the vertex we care about.
var e0 = face[v].split('/')[0] - 1;
var e1 = face[(v == face.length - 1) ? 0 : (v + 1)].split('/')[0] - 1;
// Include if edge not already seen
if (!(edges[e0 + "," + e1] || edges[e1 + "," + e0])) {
indices += tab + e0 + ", " + e1 + ",\n";
numIndices += 2;
edges[e0 + "," + e1] = true;
}
}
break;
}
}
// Check if nothing to return
if (numVerts == 0 || numIndices == 0) {
return "";
}
// Get proper data type for number of vertices and indices
var numVertType = (numVerts > 255) ? "unsigned int" : "byte";
var numIndType = (numIndices > 255) ? "unsigned int" : "byte";
// Close up arrays
verts = verts.substr(0, verts.length - 2) + "\n};";
indices = numVertType + " " + indices.substr(0, indices.length - 2) + "\n};";
return "// Model vertices\nconst " + numVertType + " NUM_VERTICES = " + numVerts + ";\n" + verts + "\n\n" +
"// Model line indices\n// Each pair of indices defines a line\nconst " + numIndType + " NUM_INDICES = " +
numIndices + ";\n" + indices + "\n";
}
</script>
</body>
</html>
You can’t perform that action at this time.