Add topology calculator.
This commit is contained in:
parent
bdfa2d2b85
commit
f02b660b23
@ -28,6 +28,7 @@
|
||||
<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/modelutils.js"></script>
|
||||
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
|
||||
<script type="text/javascript" src="../source/import/importerutils.js"></script>
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
<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/modelutils.js"></script>
|
||||
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
|
||||
<script type="text/javascript" src="../source/import/importerutils.js"></script>
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
<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/modelutils.js"></script>
|
||||
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
|
||||
<script type="text/javascript" src="../source/import/importerutils.js"></script>
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
<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/modelutils.js"></script>
|
||||
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
|
||||
<script type="text/javascript" src="../source/import/importerutils.js"></script>
|
||||
|
||||
@ -212,3 +212,41 @@ OV.GetMeshBoundingBox = function (mesh)
|
||||
}
|
||||
return calculator.GetBox ();
|
||||
};
|
||||
|
||||
OV.GetModelBoundingBox = function (model)
|
||||
{
|
||||
let calculator = new OV.BoundingBoxCalculator3D ();
|
||||
for (let i = 0; i < model.MeshCount (); i++) {
|
||||
let mesh = model.GetMesh (i);
|
||||
for (let j = 0; j < mesh.VertexCount (); j++) {
|
||||
let vertex = mesh.GetVertex (j);
|
||||
calculator.AddPoint (vertex);
|
||||
}
|
||||
}
|
||||
return calculator.GetBox ();
|
||||
};
|
||||
|
||||
OV.GetModelTopology = function (model)
|
||||
{
|
||||
function GetVertexIndex (vertex, octree, topology)
|
||||
{
|
||||
let index = octree.FindPoint (vertex);
|
||||
if (index === null) {
|
||||
index = topology.AddVertex ();
|
||||
octree.AddPoint (vertex, index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
let boundingBox = OV.GetModelBoundingBox (model);
|
||||
let octree = new OV.Octree (boundingBox);
|
||||
let topology = new OV.Topology ();
|
||||
|
||||
OV.EnumerateModelTriangles (model, function (v0, v1, v2) {
|
||||
let v0Index = GetVertexIndex (v0, octree, topology);
|
||||
let v1Index = GetVertexIndex (v1, octree, topology);
|
||||
let v2Index = GetVertexIndex (v2, octree, topology);
|
||||
topology.AddTriangle (v0Index, v1Index, v2Index);
|
||||
});
|
||||
return topology;
|
||||
};
|
||||
|
||||
138
source/model/topology.js
Normal file
138
source/model/topology.js
Normal file
@ -0,0 +1,138 @@
|
||||
OV.TopologyVertex = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.edges = [];
|
||||
this.triangles = [];
|
||||
}
|
||||
};
|
||||
|
||||
OV.TopologyEdge = class
|
||||
{
|
||||
constructor (vertex1, vertex2)
|
||||
{
|
||||
this.vertex1 = vertex1;
|
||||
this.vertex2 = vertex2;
|
||||
this.triangles = [];
|
||||
}
|
||||
};
|
||||
|
||||
OV.TopologyTriangleEdge = class
|
||||
{
|
||||
constructor (edge, reversed)
|
||||
{
|
||||
this.edge = edge;
|
||||
this.reversed = reversed;
|
||||
}
|
||||
};
|
||||
|
||||
OV.TopologyTriangle = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.triEdge1 = null;
|
||||
this.triEdge2 = null;
|
||||
this.triEdge3 = null;
|
||||
}
|
||||
};
|
||||
|
||||
OV.Topology = class
|
||||
{
|
||||
constructor ()
|
||||
{
|
||||
this.vertices = [];
|
||||
this.edges = [];
|
||||
this.triangleEdges = [];
|
||||
this.triangles = [];
|
||||
this.edgeStartToEndVertexMap = {};
|
||||
}
|
||||
|
||||
AddVertex ()
|
||||
{
|
||||
this.vertices.push (new OV.TopologyVertex ());
|
||||
return this.vertices.length - 1;
|
||||
}
|
||||
|
||||
AddTriangle (vertex1, vertex2, vertex3)
|
||||
{
|
||||
function AddTriangleToVertex (vertices, vertexIndex, triangleIndex)
|
||||
{
|
||||
let vertex = vertices[vertexIndex];
|
||||
vertex.triangles.push (triangleIndex);
|
||||
}
|
||||
|
||||
function AddEdgeToVertex (vertices, triangleEdges, vertexIndex, triangleEdgeIndex)
|
||||
{
|
||||
let vertex = vertices[vertexIndex];
|
||||
let triangleEdge = triangleEdges[triangleEdgeIndex];
|
||||
vertex.edges.push (triangleEdge.edge);
|
||||
}
|
||||
|
||||
function AddTriangleToEdge (edges, triangleEdges, triangleEdgeIndex, triangleIndex)
|
||||
{
|
||||
let triangleEdge = triangleEdges[triangleEdgeIndex];
|
||||
let edge = edges[triangleEdge.edge];
|
||||
edge.triangles.push (triangleIndex);
|
||||
}
|
||||
|
||||
let triangleIndex = this.triangles.length;
|
||||
let triangle = new OV.TopologyTriangle ();
|
||||
triangle.triEdge1 = this.AddTriangleEdge (vertex1, vertex2);
|
||||
triangle.triEdge2 = this.AddTriangleEdge (vertex2, vertex3);
|
||||
triangle.triEdge3 = this.AddTriangleEdge (vertex3, vertex1);
|
||||
|
||||
AddTriangleToVertex (this.vertices, vertex1, triangleIndex);
|
||||
AddTriangleToVertex (this.vertices, vertex2, triangleIndex);
|
||||
AddTriangleToVertex (this.vertices, vertex3, triangleIndex);
|
||||
|
||||
AddEdgeToVertex (this.vertices, this.triangleEdges, vertex1, triangle.triEdge1);
|
||||
AddEdgeToVertex (this.vertices, this.triangleEdges, vertex2, triangle.triEdge2);
|
||||
AddEdgeToVertex (this.vertices, this.triangleEdges, vertex3, triangle.triEdge3);
|
||||
|
||||
AddTriangleToEdge (this.edges, this.triangleEdges, triangle.triEdge1, triangleIndex);
|
||||
AddTriangleToEdge (this.edges, this.triangleEdges, triangle.triEdge2, triangleIndex);
|
||||
AddTriangleToEdge (this.edges, this.triangleEdges, triangle.triEdge3, triangleIndex);
|
||||
|
||||
this.triangles.push (triangle);
|
||||
}
|
||||
|
||||
AddTriangleEdge (vertex1, vertex2)
|
||||
{
|
||||
let startVertex = vertex1;
|
||||
let endVertex = vertex2;
|
||||
let reversed = false;
|
||||
if (vertex2 < vertex1) {
|
||||
startVertex = vertex2;
|
||||
endVertex = vertex1;
|
||||
reversed = true;
|
||||
}
|
||||
|
||||
let edgeIndex = this.AddEdge (startVertex, endVertex);
|
||||
this.triangleEdges.push (new OV.TopologyTriangleEdge (edgeIndex, reversed));
|
||||
return this.triangleEdges.length - 1;
|
||||
}
|
||||
|
||||
AddEdge (startVertex, endVertex)
|
||||
{
|
||||
if (this.edgeStartToEndVertexMap[startVertex] === undefined) {
|
||||
this.edgeStartToEndVertexMap[startVertex] = [];
|
||||
}
|
||||
|
||||
let endVertices = this.edgeStartToEndVertexMap[startVertex];
|
||||
for (let i = 0; i < endVertices.length; i++) {
|
||||
let endVertexItem = endVertices[i];
|
||||
if (endVertexItem.endVertex === endVertex) {
|
||||
return endVertexItem.edgeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
let edgeIndex = this.edges.length;
|
||||
endVertices.push ({
|
||||
endVertex : endVertex,
|
||||
edgeIndex : edgeIndex
|
||||
});
|
||||
|
||||
this.edges.push (new OV.TopologyEdge (startVertex, endVertex));
|
||||
return edgeIndex;
|
||||
}
|
||||
};
|
||||
@ -128,7 +128,7 @@ describe ('Model Utils', function () {
|
||||
return Math.sqrt (areaSquare);
|
||||
}
|
||||
|
||||
var model = testUtils.GetCubeModel ();
|
||||
var model = testUtils.GetModelWithOneMesh (testUtils.GetCubeMesh ());
|
||||
let surface = 0.0;
|
||||
let volume = 0.0;
|
||||
for (let i = 0; i < model.MeshCount (); i++) {
|
||||
@ -146,4 +146,54 @@ describe ('Model Utils', function () {
|
||||
assert (OV.IsEqual (volume, 1.0));
|
||||
assert (OV.IsEqual (surface, 6.0));
|
||||
});
|
||||
|
||||
it ('Tetrahedron Topology Calculation', function () {
|
||||
let tetrahedron = testUtils.GetModelWithOneMesh (testUtils.GetTetrahedronMesh ());
|
||||
let topology = OV.GetModelTopology (tetrahedron);
|
||||
assert.strictEqual (topology.vertices.length, 4);
|
||||
assert.strictEqual (topology.edges.length, 6);
|
||||
assert.strictEqual (topology.triangleEdges.length, 4 * 3);
|
||||
assert.strictEqual (topology.triangles.length, 4);
|
||||
for (let i = 0; i < topology.vertices.length; i++) {
|
||||
assert.strictEqual (topology.vertices[i].edges.length, 3);
|
||||
assert.strictEqual (topology.vertices[i].triangles.length, 3);
|
||||
}
|
||||
for (let i = 0; i < topology.edges.length; i++) {
|
||||
assert.strictEqual (topology.edges[i].triangles.length, 2);
|
||||
}
|
||||
});
|
||||
|
||||
it ('Cube Topology Calculation', function () {
|
||||
let cube = testUtils.GetModelWithOneMesh (testUtils.GetCubeMesh ());
|
||||
let topology = OV.GetModelTopology (cube);
|
||||
assert.strictEqual (topology.vertices.length, 8);
|
||||
assert.strictEqual (topology.edges.length, 12 + 6);
|
||||
assert.strictEqual (topology.triangleEdges.length, 6 * 2 * 3);
|
||||
assert.strictEqual (topology.triangles.length, 6 * 2);
|
||||
|
||||
let verticesWith4Triangles = 0;
|
||||
let verticesWith5Triangles = 0;
|
||||
let verticesWith4Edges = 0;
|
||||
let verticesWith5Edges = 0;
|
||||
for (let i = 0; i < topology.vertices.length; i++) {
|
||||
if (topology.vertices[i].triangles.length == 4) {
|
||||
verticesWith4Triangles += 1;
|
||||
} else if (topology.vertices[i].triangles.length == 5) {
|
||||
verticesWith5Triangles += 1;
|
||||
}
|
||||
if (topology.vertices[i].edges.length == 4) {
|
||||
verticesWith4Edges += 1;
|
||||
} else if (topology.vertices[i].edges.length == 5) {
|
||||
verticesWith5Edges += 1;
|
||||
}
|
||||
}
|
||||
assert.strictEqual (verticesWith4Triangles, 4);
|
||||
assert.strictEqual (verticesWith5Triangles, 4);
|
||||
assert.strictEqual (verticesWith4Edges, 4);
|
||||
assert.strictEqual (verticesWith5Edges, 4);
|
||||
|
||||
for (let i = 0; i < topology.edges.length; i++) {
|
||||
assert.strictEqual (topology.edges[i].triangles.length, 2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -163,12 +163,28 @@ module.exports =
|
||||
return cube;
|
||||
},
|
||||
|
||||
GetCubeModel ()
|
||||
GetTetrahedronMesh ()
|
||||
{
|
||||
var tetrahedron = new OV.Mesh ();
|
||||
|
||||
let a = 1.0;
|
||||
tetrahedron.AddVertex (new OV.Coord3D (+a, +a, +a));
|
||||
tetrahedron.AddVertex (new OV.Coord3D (-a, -a, +a));
|
||||
tetrahedron.AddVertex (new OV.Coord3D (-a, +a, -a));
|
||||
tetrahedron.AddVertex (new OV.Coord3D (+a, -a, -a));
|
||||
tetrahedron.AddTriangle (new OV.Triangle (0, 1, 3));
|
||||
tetrahedron.AddTriangle (new OV.Triangle (0, 2, 1));
|
||||
tetrahedron.AddTriangle (new OV.Triangle (0, 3, 2));
|
||||
tetrahedron.AddTriangle (new OV.Triangle (1, 2, 3));
|
||||
|
||||
return tetrahedron;
|
||||
},
|
||||
|
||||
GetModelWithOneMesh (mesh)
|
||||
{
|
||||
var model = new OV.Model ();
|
||||
var cube = this.GetCubeMesh ();
|
||||
model.AddMesh (cube);
|
||||
model.AddMesh (mesh);
|
||||
OV.FinalizeModel (model, function () { new OV.Material () });
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
"source/model/mesh.js",
|
||||
"source/model/meshbuffer.js",
|
||||
"source/model/model.js",
|
||||
"source/model/topology.js",
|
||||
"source/model/modelutils.js",
|
||||
"source/model/modelfinalization.js",
|
||||
"source/import/importerutils.js",
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
<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/modelutils.js"></script>
|
||||
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
|
||||
<script type="text/javascript" src="../source/import/importerutils.js"></script>
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
<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/modelutils.js"></script>
|
||||
<script type="text/javascript" src="../source/model/modelfinalization.js"></script>
|
||||
<script type="text/javascript" src="../source/import/importerutils.js"></script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user