From 1af09bf377c953b9dc87889bf4ee7fb4bf02b3ea Mon Sep 17 00:00:00 2001 From: kovacsv Date: Tue, 17 Oct 2023 19:47:00 +0200 Subject: [PATCH] Read lines from obj files. --- source/engine/import/importerobj.js | 82 ++++++++++++++++++-------- test/tests/importerobj_test.js | 90 +++++++++++++++++++++++++++++ test/tests/importeroff_test.js | 8 +++ test/tests/importerply_test.js | 4 ++ test/tests/importerstl_test.js | 4 ++ test/utils/testutils.js | 20 ++++++- 6 files changed, 183 insertions(+), 25 deletions(-) diff --git a/source/engine/import/importerobj.js b/source/engine/import/importerobj.js index 845fcb8..b26dae9 100644 --- a/source/engine/import/importerobj.js +++ b/source/engine/import/importerobj.js @@ -2,6 +2,7 @@ import { Coord2D } from '../geometry/coord2d.js'; import { Coord3D } from '../geometry/coord3d.js'; import { Direction } from '../geometry/geometry.js'; import { ArrayBufferToUtf8String } from '../io/bufferutils.js'; +import { Line } from '../model/line.js'; import { RGBColor, RGBColorFromFloatComponents } from '../model/color.js'; import { PhongMaterial, TextureMap } from '../model/material.js'; import { Mesh } from '../model/mesh.js'; @@ -48,6 +49,11 @@ class ObjMeshConverter }); } + AddLine (line) + { + this.mesh.AddLine (line); + } + AddTriangle (triangle) { this.mesh.AddTriangle (triangle); @@ -213,11 +219,16 @@ export class ImporterObj extends ImporterBase parseFloat (parameters[1]) )); return true; + } else if (keyword === 'l') { + if (parameters.length < 2 || parameters.length % 2 !== 0) { + return true; + } + this.ProcessLineCommand (parameters); } else if (keyword === 'f') { if (parameters.length < 3) { return true; } - this.ProcessFace (parameters); + this.ProcessFaceCommand (parameters); return true; } @@ -375,40 +386,56 @@ export class ImporterObj extends ImporterBase return false; } - ProcessFace (parameters) + ProcessLineCommand (parameters) { - function GetRelativeIndex (index, count) - { - if (index > 0) { - return index - 1; - } else { - return count + index; - } + if (this.currentMeshConverter === null) { + this.AddNewMesh (''); } + let vertices = []; + for (let i = 0; i < parameters.length; i++) { + let vertexIndex = this.GetRelativeIndex (parseInt (parameters[i], 10), this.globalVertices.length); + let meshVertexIndex = this.currentMeshConverter.AddVertex (vertexIndex, this.globalVertices); + if (meshVertexIndex === null) { + this.SetError ('Invalid vertex index.'); + break; + } + vertices.push (meshVertexIndex); + } + + let line = new Line (vertices); + if (this.currentMaterialIndex !== null) { + line.mat = this.currentMaterialIndex; + } + + this.currentMeshConverter.AddLine (line); + } + + ProcessFaceCommand (parameters) + { let vertices = []; let colors = []; let normals = []; let uvs = []; - for (let i = 0; i < parameters.length; i++) { - let vertexParams = parameters[i].split ('/'); - vertices.push (GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length)); - if (this.globalVertices.length === this.globalVertexColors.length) { - colors.push (GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length)); - } - if (vertexParams.length > 1 && vertexParams[1].length > 0) { - uvs.push (GetRelativeIndex (parseInt (vertexParams[1], 10), this.globalUvs.length)); - } - if (vertexParams.length > 2 && vertexParams[2].length > 0) { - normals.push (GetRelativeIndex (parseInt (vertexParams[2], 10), this.globalNormals.length)); - } - } - if (this.currentMeshConverter === null) { this.AddNewMesh (''); } + for (let i = 0; i < parameters.length; i++) { + let vertexParams = parameters[i].split ('/'); + vertices.push (this.GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length)); + if (this.globalVertices.length === this.globalVertexColors.length) { + colors.push (this.GetRelativeIndex (parseInt (vertexParams[0], 10), this.globalVertices.length)); + } + if (vertexParams.length > 1 && vertexParams[1].length > 0) { + uvs.push (this.GetRelativeIndex (parseInt (vertexParams[1], 10), this.globalUvs.length)); + } + if (vertexParams.length > 2 && vertexParams[2].length > 0) { + normals.push (this.GetRelativeIndex (parseInt (vertexParams[2], 10), this.globalNormals.length)); + } + } + for (let i = 0; i < vertices.length - 2; i++) { let v0 = this.currentMeshConverter.AddVertex (vertices[0], this.globalVertices); let v1 = this.currentMeshConverter.AddVertex (vertices[i + 1], this.globalVertices); @@ -460,4 +487,13 @@ export class ImporterObj extends ImporterBase this.currentMeshConverter.AddTriangle (triangle); } } + + GetRelativeIndex (index, count) + { + if (index > 0) { + return index - 1; + } else { + return count + index; + } + } } diff --git a/test/tests/importerobj_test.js b/test/tests/importerobj_test.js index f565c05..cc89e9c 100644 --- a/test/tests/importerobj_test.js +++ b/test/tests/importerobj_test.js @@ -18,6 +18,7 @@ describe ('Obj Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -44,6 +45,7 @@ describe ('Obj Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -76,6 +78,7 @@ describe ('Obj Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -108,6 +111,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'MyMeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -134,6 +138,7 @@ describe ('Obj Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -160,6 +165,7 @@ describe ('Obj Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -186,6 +192,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'MeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -212,6 +219,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'MeshName1', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -223,6 +231,7 @@ describe ('Obj Importer', function () { }, { name : 'MeshName2', + lines : [], triangles : [ { vertices : [0, 0, 1, 1, 0, 1, 1, 1, 1], @@ -249,6 +258,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'MeshName1', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -260,6 +270,7 @@ describe ('Obj Importer', function () { }, { name : 'MeshName2', + lines : [], triangles : [ { vertices : [0, 0, 1, 1, 0, 1, 1, 1, 1], @@ -287,6 +298,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'MeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -314,6 +326,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'MeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -346,6 +359,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'MeshName1', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -357,6 +371,7 @@ describe ('Obj Importer', function () { }, { name : 'MeshName2', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 0, 0, 1], @@ -383,6 +398,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'MeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -415,6 +431,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'Mesh', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -449,6 +466,7 @@ describe ('Obj Importer', function () { meshes : [ { name : 'Mesh', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -628,6 +646,78 @@ describe ('Obj Importer', function () { done (); }); }); + + it ('lines.obj', function (done) { + ImportObjFile ('lines.obj', function (model) { + assert.ok (OV.CheckModel (model)); + assert.deepStrictEqual (ModelToObject (model), { + name : '', + materials : [ + { name : '' } + ], + meshes : [ + { + name : '', + lines : [ + { + vertices : [0, 0, 0, 1, 0, 0], + mat : 0 + }, + { + vertices : [1, 1, 0, 0, 1, 0], + mat : 0 + }, + { + vertices : [0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1], + mat : 0 + } + ], + triangles : [] + } + ] + }); + done (); + }); + }); + + it ('lines_colors.obj', function (done) { + ImportObjFile ('lines_colors.obj', function (model) { + assert.ok (OV.CheckModel (model)); + assert.deepStrictEqual (ModelToObject (model), { + name : '', + materials : [ + { name : 'Red' }, + { name : 'Green' }, + { name : 'Blue' } + ], + meshes : [ + { + name : '', + lines : [ + { + vertices : [0, 0, 0, 1, 0, 0], + mat : 0 + }, + { + vertices : [1, 1, 0, 0, 1, 0], + mat : 0 + }, + { + vertices : [0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1], + mat : 1 + }, + { + vertices : [0, 0, 0, 0, 0, 1], + mat : 2 + } + ], + triangles : [] + } + ] + }); + done (); + }); + }); }); } diff --git a/test/tests/importeroff_test.js b/test/tests/importeroff_test.js index 093330f..352f46d 100644 --- a/test/tests/importeroff_test.js +++ b/test/tests/importeroff_test.js @@ -18,6 +18,7 @@ describe ('Off Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -44,6 +45,7 @@ describe ('Off Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -76,6 +78,7 @@ describe ('Off Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -108,6 +111,7 @@ describe ('Off Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -162,6 +166,7 @@ describe ('Off Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -195,6 +200,7 @@ describe ('Off Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -229,6 +235,7 @@ describe ('Off Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -263,6 +270,7 @@ describe ('Off Importer', function () { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], diff --git a/test/tests/importerply_test.js b/test/tests/importerply_test.js index a5a6fd6..7e7e11d 100644 --- a/test/tests/importerply_test.js +++ b/test/tests/importerply_test.js @@ -18,6 +18,7 @@ describe ('Ply Importer', function() { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -44,6 +45,7 @@ describe ('Ply Importer', function() { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -76,6 +78,7 @@ describe ('Ply Importer', function() { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -108,6 +111,7 @@ describe ('Ply Importer', function() { meshes : [ { name : '', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], diff --git a/test/tests/importerstl_test.js b/test/tests/importerstl_test.js index 870dff0..ea28375 100644 --- a/test/tests/importerstl_test.js +++ b/test/tests/importerstl_test.js @@ -18,6 +18,7 @@ describe ('Stl Importer', function() { meshes : [ { name : 'MeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -44,6 +45,7 @@ describe ('Stl Importer', function() { meshes : [ { name : 'MeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -70,6 +72,7 @@ describe ('Stl Importer', function() { meshes : [ { name : 'MeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], @@ -96,6 +99,7 @@ describe ('Stl Importer', function() { meshes : [ { name : 'MeshName', + lines : [], triangles : [ { vertices : [0, 0, 0, 1, 0, 0, 1, 1, 0], diff --git a/test/utils/testutils.js b/test/utils/testutils.js index 598d53b..b09b666 100644 --- a/test/utils/testutils.js +++ b/test/utils/testutils.js @@ -55,7 +55,7 @@ export function ModelToObject (model) meshes : [] }; - var i, j; + var i, j, k; var material; for (i = 0; i < model.MaterialCount (); i++) { @@ -65,13 +65,29 @@ export function ModelToObject (model) }); } - var mesh, triangle, meshObj, triangleObj; + var mesh, line, triangle, meshObj, lineObj, triangleObj; for (i = 0; i < model.MeshCount (); i++) { mesh = model.GetMesh (i); meshObj = { name : mesh.GetName (), + lines : [], triangles : [] }; + for (j = 0; j < mesh.LineCount (); j++) { + line = mesh.GetLine (j); + lineObj = { + mat : line.mat, + vertices : [] + }; + for (k = 0; k < line.vertices.length; k++) { + lineObj.vertices.push ( + mesh.GetVertex (line.vertices[k]).x, + mesh.GetVertex (line.vertices[k]).y, + mesh.GetVertex (line.vertices[k]).z + ); + } + meshObj.lines.push (lineObj); + } for (j = 0; j < mesh.TriangleCount (); j++) { triangle = mesh.GetTriangle (j); triangleObj = {