Base class for model and mesh so they can be handled similarly.

This commit is contained in:
Viktor Kovacs 2021-05-21 09:29:44 +02:00
parent 921c2a9040
commit 55072f6d6d
18 changed files with 127 additions and 233 deletions

View File

@ -25,11 +25,11 @@
<script type="text/javascript" src="../source/io/bufferutils.js"></script>
<script type="text/javascript" src="../source/io/fileutils.js"></script>
<script type="text/javascript" src="../source/model/modelentities.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/model.js"></script>
<script type="text/javascript" src="../source/model/topology.js"></script>
<script type="text/javascript" src="../source/model/enumerator.js"></script>
<script type="text/javascript" src="../source/model/modelutils.js"></script>
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
<script type="text/javascript" src="../source/model/quantities.js"></script>

View File

@ -26,11 +26,11 @@
<script type="text/javascript" src="../source/io/bufferutils.js"></script>
<script type="text/javascript" src="../source/io/fileutils.js"></script>
<script type="text/javascript" src="../source/model/modelentities.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/model.js"></script>
<script type="text/javascript" src="../source/model/topology.js"></script>
<script type="text/javascript" src="../source/model/enumerator.js"></script>
<script type="text/javascript" src="../source/model/modelutils.js"></script>
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
<script type="text/javascript" src="../source/model/quantities.js"></script>

View File

@ -25,11 +25,11 @@
<script type="text/javascript" src="../source/io/bufferutils.js"></script>
<script type="text/javascript" src="../source/io/fileutils.js"></script>
<script type="text/javascript" src="../source/model/modelentities.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/model.js"></script>
<script type="text/javascript" src="../source/model/topology.js"></script>
<script type="text/javascript" src="../source/model/enumerator.js"></script>
<script type="text/javascript" src="../source/model/modelutils.js"></script>
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
<script type="text/javascript" src="../source/model/quantities.js"></script>

View File

@ -25,11 +25,11 @@
<script type="text/javascript" src="../source/io/bufferutils.js"></script>
<script type="text/javascript" src="../source/io/fileutils.js"></script>
<script type="text/javascript" src="../source/model/modelentities.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/model.js"></script>
<script type="text/javascript" src="../source/model/topology.js"></script>
<script type="text/javascript" src="../source/model/enumerator.js"></script>
<script type="text/javascript" src="../source/model/modelutils.js"></script>
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
<script type="text/javascript" src="../source/model/quantities.js"></script>

View File

@ -27,7 +27,7 @@ OV.ExporterStl = class extends OV.ExporterBase
let stlWriter = new OV.TextWriter ();
stlWriter.WriteLine ('solid Model');
OV.EnumerateModelTrianglesWithNormals (model, function (v0, v1, v2, normal) {
OV.EnumerateTrianglesWithNormals (model, function (v0, v1, v2, normal) {
stlWriter.WriteArrayLine (['facet', 'normal', normal.x, normal.y, normal.z]);
stlWriter.Indent (1);
stlWriter.WriteLine ('outer loop');
@ -60,7 +60,7 @@ OV.ExporterStl = class extends OV.ExporterBase
}
stlWriter.WriteUnsignedInteger32 (triangleCount);
OV.EnumerateModelTrianglesWithNormals (model, function (v0, v1, v2, normal) {
OV.EnumerateTrianglesWithNormals (model, function (v0, v1, v2, normal) {
stlWriter.WriteFloat32 (normal.x);
stlWriter.WriteFloat32 (normal.y);
stlWriter.WriteFloat32 (normal.z);

47
source/model/element.js Normal file
View File

@ -0,0 +1,47 @@
OV.Element = class
{
constructor ()
{
this.name = '';
}
GetName ()
{
return this.name;
}
SetName (name)
{
this.name = name;
}
VertexCount ()
{
return 0;
}
NormalCount ()
{
return 0;
}
TextureUVCount ()
{
return 0;
}
TriangleCount ()
{
return 0;
}
EnumerateVertices (onVertex)
{
}
EnumerateTriangles (onTriangle)
{
}
};

View File

@ -1,100 +0,0 @@
OV.Enumerator = class
{
constructor ()
{
}
EnumerateVertices (onVertex)
{
}
EnumerateTriangles (onTriangle)
{
}
};
OV.MeshEnumerator = class extends OV.Enumerator
{
constructor (mesh)
{
super ();
this.mesh = mesh;
}
EnumerateVertices (onVertex)
{
for (let vertexIndex = 0; vertexIndex < this.mesh.VertexCount (); vertexIndex++) {
let vertex = this.mesh.GetVertex (vertexIndex);
onVertex (vertex);
}
}
EnumerateTriangles (onTriangle)
{
for (let triangleIndex = 0; triangleIndex < this.mesh.TriangleCount (); triangleIndex++) {
let triangle = this.mesh.GetTriangle (triangleIndex);
let v0 = this.mesh.GetVertex (triangle.v0);
let v1 = this.mesh.GetVertex (triangle.v1);
let v2 = this.mesh.GetVertex (triangle.v2);
onTriangle (v0, v1, v2);
}
}
};
OV.MeshEnumerator = class extends OV.Enumerator
{
constructor (mesh)
{
super ();
this.mesh = mesh;
}
EnumerateVertices (onVertex)
{
for (let vertexIndex = 0; vertexIndex < this.mesh.VertexCount (); vertexIndex++) {
let vertex = this.mesh.GetVertex (vertexIndex);
onVertex (vertex);
}
}
EnumerateTriangles (onTriangle)
{
for (let triangleIndex = 0; triangleIndex < this.mesh.TriangleCount (); triangleIndex++) {
let triangle = this.mesh.GetTriangle (triangleIndex);
let v0 = this.mesh.GetVertex (triangle.v0);
let v1 = this.mesh.GetVertex (triangle.v1);
let v2 = this.mesh.GetVertex (triangle.v2);
onTriangle (v0, v1, v2);
}
}
};
OV.ModelEnumerator = class extends OV.Enumerator
{
constructor (model)
{
super ();
this.model = model;
}
EnumerateVertices (onVertex)
{
for (let meshIndex = 0; meshIndex < this.model.MeshCount (); meshIndex++) {
let mesh = this.model.GetMesh (meshIndex);
let enumerator = new OV.MeshEnumerator (mesh);
enumerator.EnumerateVertices (onVertex);
}
}
EnumerateTriangles (onTriangle)
{
for (let meshIndex = 0; meshIndex < this.model.MeshCount (); meshIndex++) {
let mesh = this.model.GetMesh (meshIndex);
let enumerator = new OV.MeshEnumerator (mesh);
enumerator.EnumerateTriangles (onTriangle);
}
}
};

View File

@ -1,24 +1,14 @@
OV.Mesh = class
OV.Mesh = class extends OV.Element
{
constructor ()
{
this.name = '';
super ();
this.vertices = [];
this.normals = [];
this.uvs = [];
this.triangles = [];
}
GetName ()
{
return this.name;
}
SetName (name)
{
this.name = name;
}
VertexCount ()
{
return this.vertices.length;
@ -97,4 +87,23 @@ OV.Mesh = class
{
return this.triangles[index];
}
EnumerateVertices (onVertex)
{
for (let vertexIndex = 0; vertexIndex < this.vertices.length; vertexIndex++) {
let vertex = this.vertices[vertexIndex];
onVertex (vertex);
}
}
EnumerateTriangles (onTriangle)
{
for (let triangleIndex = 0; triangleIndex < this.triangles.length; triangleIndex++) {
let triangle = this.triangles[triangleIndex];
let v0 = this.vertices[triangle.v0];
let v1 = this.vertices[triangle.v1];
let v2 = this.vertices[triangle.v2];
onTriangle (v0, v1, v2);
}
}
};

View File

@ -1,22 +1,12 @@
OV.Model = class
OV.Model = class extends OV.Element
{
constructor ()
{
this.name = '';
super ();
this.materials = [];
this.meshes = [];
}
GetName ()
{
return this.name;
}
SetName (name)
{
this.name = name;
}
MaterialCount ()
{
return this.materials.length;
@ -96,10 +86,19 @@ OV.Model = class
return this.meshes[index];
}
Clear ()
EnumerateVertices (onVertex)
{
this.name = '';
this.materials = [];
this.meshes = [];
for (let meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
let mesh = this.meshes[meshIndex];
mesh.EnumerateVertices (onVertex);
}
}
EnumerateTriangles (onTriangle)
{
for (let meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
let mesh = this.meshes[meshIndex];
mesh.EnumerateTriangles (onTriangle);
}
}
};

View File

@ -174,37 +174,24 @@ OV.EnumerateModelVerticesAndTriangles = function (model, callbacks)
}
};
OV.EnumerateModelTrianglesWithNormals = function (model, onTriangle)
OV.EnumerateTrianglesWithNormals = function (element, onTriangle)
{
let enumerator = new OV.ModelEnumerator (model);
enumerator.EnumerateTriangles (function (v0, v1, v2) {
element.EnumerateTriangles (function (v0, v1, v2) {
let normal = OV.CalculateTriangleNormal (v0, v1, v2);
onTriangle (v0, v1, v2, normal);
});
};
OV.GetBoundingBox = function (enumerator)
OV.GetBoundingBox = function (element)
{
let calculator = new OV.BoundingBoxCalculator3D ();
enumerator.EnumerateVertices (function (vertex) {
element.EnumerateVertices (function (vertex) {
calculator.AddPoint (vertex);
});
return calculator.GetBox ();
};
OV.GetMeshBoundingBox = function (mesh)
{
let enumerator = new OV.MeshEnumerator (mesh);
return OV.GetBoundingBox (enumerator);
};
OV.GetModelBoundingBox = function (model)
{
let enumerator = new OV.ModelEnumerator (model);
return OV.GetBoundingBox (enumerator);
};
OV.GetTopology = function (enumerator)
OV.GetTopology = function (element)
{
function GetVertexIndex (vertex, octree, topology)
{
@ -216,11 +203,11 @@ OV.GetTopology = function (enumerator)
return index;
}
let boundingBox = OV.GetBoundingBox (enumerator);
let boundingBox = OV.GetBoundingBox (element);
let octree = new OV.Octree (boundingBox);
let topology = new OV.Topology ();
enumerator.EnumerateTriangles (function (v0, v1, v2) {
element.EnumerateTriangles (function (v0, v1, v2) {
let v0Index = GetVertexIndex (v0, octree, topology);
let v1Index = GetVertexIndex (v1, octree, topology);
let v2Index = GetVertexIndex (v2, octree, topology);
@ -229,19 +216,7 @@ OV.GetTopology = function (enumerator)
return topology;
};
OV.GetMeshTopology = function (mesh)
{
let enumerator = new OV.MeshEnumerator (mesh);
return OV.GetTopology (enumerator);
};
OV.GetModelTopology = function (model)
{
let enumerator = new OV.ModelEnumerator (model);
return OV.GetTopology (enumerator);
};
OV.IsSolid = function (enumerator)
OV.IsSolid = function (element)
{
function GetEdgeOrientationInTriangle (topology, triangleIndex, edgeIndex)
{
@ -261,7 +236,7 @@ OV.IsSolid = function (enumerator)
return null;
}
const topology = OV.GetTopology (enumerator);
const topology = OV.GetTopology (element);
for (let edgeIndex = 0; edgeIndex < topology.edges.length; edgeIndex++) {
const edge = topology.edges[edgeIndex];
if (edge.triangles.length !== 2) {
@ -275,15 +250,3 @@ OV.IsSolid = function (enumerator)
}
return true;
};
OV.IsMeshSolid = function (mesh)
{
let enumerator = new OV.MeshEnumerator (mesh);
return OV.IsSolid (enumerator);
};
OV.IsModelSolid = function (model)
{
let enumerator = new OV.ModelEnumerator (model);
return OV.IsSolid (enumerator);
};

View File

@ -16,47 +16,23 @@ OV.GetTetrahedronSignedVolume = function (v0, v1, v2)
return OV.DotVector3D (v0, OV.CrossVector3D (v1, v2)) / 6.0;
};
OV.CalculateVolume = function (enumerator)
OV.CalculateVolume = function (element)
{
if (!OV.IsSolid (enumerator)) {
if (!OV.IsSolid (element)) {
return null;
}
let volume = 0.0;
enumerator.EnumerateTriangles (function (v0, v1, v2) {
element.EnumerateTriangles (function (v0, v1, v2) {
volume += OV.GetTetrahedronSignedVolume (v0, v1, v2);
});
return volume;
};
OV.CalculateMeshVolume = function (mesh)
{
let enumerator = new OV.MeshEnumerator (mesh);
return OV.CalculateVolume (enumerator);
};
OV.CalculateModelVolume = function (model)
{
let enumerator = new OV.ModelEnumerator (model);
return OV.CalculateVolume (enumerator);
};
OV.CalculateSurfaceArea = function (enumerator)
OV.CalculateSurfaceArea = function (element)
{
let surface = 0.0;
enumerator.EnumerateTriangles (function (v0, v1, v2) {
element.EnumerateTriangles (function (v0, v1, v2) {
surface += OV.GetTriangleArea (v0, v1, v2);
});
return surface;
};
OV.CalculateMeshSurfaceArea = function (mesh)
{
let enumerator = new OV.MeshEnumerator (mesh);
return OV.CalculateSurfaceArea (enumerator);
};
OV.CalculateModelSurfaceArea = function (model)
{
let enumerator = new OV.ModelEnumerator (model);
return OV.CalculateSurfaceArea (enumerator);
};

View File

@ -81,7 +81,7 @@ describe ('Model Utils', function () {
it ('Mesh Bounding Box', function () {
var cube = testUtils.GetCubeMesh ();
let cubeBounds = OV.GetMeshBoundingBox (cube);
let cubeBounds = OV.GetBoundingBox (cube);
assert (OV.CoordIsEqual3D (cubeBounds.min, new OV.Coord3D (0.0, 0.0, 0.0)));
assert (OV.CoordIsEqual3D (cubeBounds.max, new OV.Coord3D (1.0, 1.0, 1.0)));
});
@ -105,18 +105,18 @@ describe ('Model Utils', function () {
OV.FinalizeModel (model, function () { return new OV.Material (); });
let mesh1Bounds = OV.GetMeshBoundingBox (model.GetMesh (0));
let mesh1Bounds = OV.GetBoundingBox (model.GetMesh (0));
assert (OV.CoordIsEqual3D (mesh1Bounds.min, new OV.Coord3D (0.0, 0.0, 0.0)));
assert (OV.CoordIsEqual3D (mesh1Bounds.max, new OV.Coord3D (1.0, 1.0, 0.0)));
let mesh2Bounds = OV.GetMeshBoundingBox (model.GetMesh (1));
let mesh2Bounds = OV.GetBoundingBox (model.GetMesh (1));
assert (OV.CoordIsEqual3D (mesh2Bounds.min, new OV.Coord3D (0.0, 0.0, 1.0)));
assert (OV.CoordIsEqual3D (mesh2Bounds.max, new OV.Coord3D (1.0, 1.0, 1.0)));
});
it ('Tetrahedron Topology Calculation', function () {
let tetrahedron = testUtils.GetModelWithOneMesh (testUtils.GetTetrahedronMesh ());
let topology = OV.GetModelTopology (tetrahedron);
let topology = OV.GetTopology (tetrahedron);
assert.strictEqual (topology.vertices.length, 4);
assert.strictEqual (topology.edges.length, 6);
assert.strictEqual (topology.triangleEdges.length, 4 * 3);
@ -132,7 +132,7 @@ describe ('Model Utils', function () {
it ('Cube Topology Calculation', function () {
let cube = testUtils.GetModelWithOneMesh (testUtils.GetCubeMesh ());
let topology = OV.GetModelTopology (cube);
let topology = OV.GetTopology (cube);
assert.strictEqual (topology.vertices.length, 8);
assert.strictEqual (topology.edges.length, 12 + 6);
assert.strictEqual (topology.triangleEdges.length, 6 * 2 * 3);

View File

@ -5,14 +5,14 @@ describe ('Quantities', function () {
it ('Cube Volume Calculation', function () {
const mesh = testUtils.GetCubeMesh ();
const model = testUtils.GetModelWithOneMesh (mesh);
assert (OV.IsEqual (OV.CalculateMeshVolume (mesh), 1.0));
assert (OV.IsEqual (OV.CalculateModelVolume (model), 1.0));
assert (OV.IsEqual (OV.CalculateVolume (mesh), 1.0));
assert (OV.IsEqual (OV.CalculateVolume (model), 1.0));
});
it ('Cube with Missing Face Volume Calculation', function () {
const mesh = testUtils.GetCubeWithOneMissingFaceMesh ();
const model = testUtils.GetModelWithOneMesh (mesh);
assert.strictEqual (OV.CalculateModelVolume (model), null);
assert.strictEqual (OV.CalculateVolume (model), null);
});
it ('Cube with Wrongly Oriented Triangle Volume Calculation', function () {
@ -38,37 +38,37 @@ describe ('Quantities', function () {
mesh.AddTriangle (new OV.Triangle (4, 5, 6));
mesh.AddTriangle (new OV.Triangle (4, 7, 6));
const model = testUtils.GetModelWithOneMesh (mesh);
assert.strictEqual (OV.CalculateMeshVolume (mesh), null);
assert.strictEqual (OV.CalculateModelVolume (model), null);
assert.strictEqual (OV.CalculateVolume (mesh), null);
assert.strictEqual (OV.CalculateVolume (model), null);
});
it ('Cube Surface Area Calculation', function () {
const mesh = testUtils.GetCubeMesh ();
const model = testUtils.GetModelWithOneMesh (mesh);
assert (OV.IsEqual (OV.CalculateMeshSurfaceArea (mesh), 6.0));
assert (OV.IsEqual (OV.CalculateModelSurfaceArea (model), 6.0));
assert (OV.IsEqual (OV.CalculateSurfaceArea (mesh), 6.0));
assert (OV.IsEqual (OV.CalculateSurfaceArea (model), 6.0));
});
it ('Cube with Missing Face Surface Area Calculation', function () {
const mesh = testUtils.GetCubeWithOneMissingFaceMesh ();
const model = testUtils.GetModelWithOneMesh (mesh);
assert (OV.IsEqual (OV.CalculateMeshSurfaceArea (mesh), 5.0));
assert (OV.IsEqual (OV.CalculateModelSurfaceArea (model), 5.0));
assert (OV.IsEqual (OV.CalculateSurfaceArea (mesh), 5.0));
assert (OV.IsEqual (OV.CalculateSurfaceArea (model), 5.0));
});
it ('Tetrahedron Volume Calculation', function () {
let edgeLength = OV.CoordDistance3D (new OV.Coord3D (1.0, 1.0, 1.0), new OV.Coord3D (-1.0, -1.0, 1.0));
const mesh = testUtils.GetTetrahedronMesh ();
const model = testUtils.GetModelWithOneMesh (mesh);
assert (OV.IsEqual (OV.CalculateMeshVolume (mesh), Math.pow (edgeLength, 3.0) / (6.0 * Math.sqrt (2))));
assert (OV.IsEqual (OV.CalculateModelVolume (model), Math.pow (edgeLength, 3.0) / (6.0 * Math.sqrt (2))));
assert (OV.IsEqual (OV.CalculateVolume (mesh), Math.pow (edgeLength, 3.0) / (6.0 * Math.sqrt (2))));
assert (OV.IsEqual (OV.CalculateVolume (model), Math.pow (edgeLength, 3.0) / (6.0 * Math.sqrt (2))));
});
it ('Tetrahedron Surface Area Calculation', function () {
let edgeLength = OV.CoordDistance3D (new OV.Coord3D (1.0, 1.0, 1.0), new OV.Coord3D (-1.0, -1.0, 1.0));
const mesh = testUtils.GetTetrahedronMesh ();
const model = testUtils.GetModelWithOneMesh (mesh);
assert (OV.IsEqual (OV.CalculateMeshSurfaceArea (mesh), Math.sqrt (3) * Math.pow (edgeLength, 2.0)));
assert (OV.IsEqual (OV.CalculateModelSurfaceArea (model), Math.sqrt (3) * Math.pow (edgeLength, 2.0)));
assert (OV.IsEqual (OV.CalculateSurfaceArea (mesh), Math.sqrt (3) * Math.pow (edgeLength, 2.0)));
assert (OV.IsEqual (OV.CalculateSurfaceArea (model), Math.sqrt (3) * Math.pow (edgeLength, 2.0)));
});
});

View File

@ -119,7 +119,7 @@ module.exports =
var mesh, meshObj, boundingBox;
for (i = 0; i < model.MeshCount (); i++) {
mesh = model.GetMesh (i);
boundingBox = OV.GetMeshBoundingBox (mesh);
boundingBox = OV.GetBoundingBox (mesh);
meshObj = {
name : mesh.GetName (),
vertexCount : mesh.VertexCount (),

View File

@ -21,11 +21,11 @@
"source/io/bufferutils.js",
"source/io/fileutils.js",
"source/model/modelentities.js",
"source/model/element.js",
"source/model/mesh.js",
"source/model/meshbuffer.js",
"source/model/model.js",
"source/model/topology.js",
"source/model/enumerator.js",
"source/model/modelutils.js",
"source/model/modelfinalization.js",
"source/model/quantities.js",

View File

@ -34,11 +34,11 @@
<script type="text/javascript" src="../source/io/bufferutils.js"></script>
<script type="text/javascript" src="../source/io/fileutils.js"></script>
<script type="text/javascript" src="../source/model/modelentities.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/model.js"></script>
<script type="text/javascript" src="../source/model/topology.js"></script>
<script type="text/javascript" src="../source/model/enumerator.js"></script>
<script type="text/javascript" src="../source/model/modelutils.js"></script>
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
<script type="text/javascript" src="../source/model/quantities.js"></script>

View File

@ -34,11 +34,11 @@
<script type="text/javascript" src="../source/io/bufferutils.js"></script>
<script type="text/javascript" src="../source/io/fileutils.js"></script>
<script type="text/javascript" src="../source/model/modelentities.js"></script>
<script type="text/javascript" src="../source/model/element.js"></script>
<script type="text/javascript" src="../source/model/mesh.js"></script>
<script type="text/javascript" src="../source/model/meshbuffer.js"></script>
<script type="text/javascript" src="../source/model/model.js"></script>
<script type="text/javascript" src="../source/model/topology.js"></script>
<script type="text/javascript" src="../source/model/enumerator.js"></script>
<script type="text/javascript" src="../source/model/modelutils.js"></script>
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
<script type="text/javascript" src="../source/model/quantities.js"></script>

View File

@ -30,8 +30,8 @@ OV.ShowQuantitiesDialog = function (model)
OV.RunTaskAsync (function () {
progressDialog.Hide ();
const volume = OV.CalculateModelVolume (model);
const surfaceArea = OV.CalculateModelSurfaceArea (model);
const volume = OV.CalculateVolume (model);
const surfaceArea = OV.CalculateSurfaceArea (model);
let volumeString = '';
if (volume === null) {