Add sphere generator.
This commit is contained in:
parent
6169e39450
commit
c1a9cae13f
@ -107,6 +107,14 @@ OV.ImporterO3dv = class extends OV.ImporterBase
|
||||
let smooth = OV.ValueOrDefault (parameters.smooth, true);
|
||||
const mesh = OV.GenerateCylinder (genParams, parameters.radius, parameters.height, segments, smooth);
|
||||
this.model.AddMesh (mesh);
|
||||
} else if (meshContent.type === 'sphere') {
|
||||
if (parameters.radius === undefined) {
|
||||
return;
|
||||
}
|
||||
let segments = OV.ValueOrDefault (parameters.segments, 20);
|
||||
let smooth = OV.ValueOrDefault (parameters.smooth, true);
|
||||
const mesh = OV.GenerateSphere (genParams, parameters.radius, segments, smooth);
|
||||
this.model.AddMesh (mesh);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -58,6 +58,16 @@ OV.Generator = class
|
||||
return this.mesh.AddVertex (coord);
|
||||
}
|
||||
|
||||
AddVertices (vertices)
|
||||
{
|
||||
let indices = [];
|
||||
for (let i = 0; i < vertices.length; i++) {
|
||||
let vertex = vertices[i];
|
||||
indices.push (this.AddVertex (vertex.x, vertex.y, vertex.z));
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
||||
SetCurve (curve)
|
||||
{
|
||||
this.curve = curve;
|
||||
@ -115,7 +125,7 @@ OV.GeneratorHelper = class
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
GenerateExtrude (vertices, height, smooth)
|
||||
GenerateExtrude (vertices, height, curve)
|
||||
{
|
||||
let topPolygon = [];
|
||||
let bottomPolygon = [];
|
||||
@ -124,12 +134,9 @@ OV.GeneratorHelper = class
|
||||
bottomPolygon.push (this.generator.AddVertex (vertex.x, vertex.y, 0.0));
|
||||
topPolygon.push (this.generator.AddVertex (vertex.x, vertex.y, height));
|
||||
}
|
||||
if (smooth) {
|
||||
this.generator.SetCurve (1);
|
||||
}
|
||||
this.GenerateSurfaceBetweenPolygons (bottomPolygon, topPolygon, smooth);
|
||||
this.generator.SetCurve (curve);
|
||||
this.GenerateSurfaceBetweenPolygons (bottomPolygon, topPolygon);
|
||||
this.generator.ResetCurve ();
|
||||
|
||||
this.generator.AddConvexPolygonInverted (bottomPolygon);
|
||||
this.generator.AddConvexPolygon (topPolygon);
|
||||
}
|
||||
@ -151,6 +158,20 @@ OV.GeneratorHelper = class
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
GenerateTriangleFan (startIndices, endIndex)
|
||||
{
|
||||
const vertexCount = startIndices.length;
|
||||
for (let i = 0; i < vertexCount; i++) {
|
||||
const index = i;
|
||||
const nextIndex = (i < vertexCount - 1) ? index + 1 : 0;
|
||||
this.generator.AddTriangle (
|
||||
endIndex,
|
||||
startIndices[index],
|
||||
startIndices[nextIndex]
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
OV.GenerateCuboid = function (genParams, xSize, ySize, zSize)
|
||||
@ -163,7 +184,7 @@ OV.GenerateCuboid = function (genParams, xSize, ySize, zSize)
|
||||
new OV.Coord2D (0.0, ySize),
|
||||
];
|
||||
let helper = new OV.GeneratorHelper (generator);
|
||||
helper.GenerateExtrude (vertices, zSize, false);
|
||||
helper.GenerateExtrude (vertices, zSize, null);
|
||||
return generator.GetMesh ();
|
||||
};
|
||||
|
||||
@ -177,6 +198,10 @@ OV.GenerateCylinder = function (genParams, radius, height, segments, smooth)
|
||||
);
|
||||
}
|
||||
|
||||
if (segments < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let generator = new OV.Generator (genParams);
|
||||
let baseVertices = [];
|
||||
const step = 2.0 * Math.PI / segments;
|
||||
@ -185,6 +210,54 @@ OV.GenerateCylinder = function (genParams, radius, height, segments, smooth)
|
||||
baseVertices.push (cylindrical);
|
||||
}
|
||||
let helper = new OV.GeneratorHelper (generator);
|
||||
helper.GenerateExtrude (baseVertices, height, smooth);
|
||||
helper.GenerateExtrude (baseVertices, height, smooth ? 1 : null);
|
||||
return generator.GetMesh ();
|
||||
};
|
||||
|
||||
OV.GenerateSphere = function (genParams, radius, segments, smooth)
|
||||
{
|
||||
function GetSphericalCoord (radius, theta, phi)
|
||||
{
|
||||
return new OV.Coord3D (
|
||||
radius * Math.sin (theta) * Math.cos (phi),
|
||||
radius * Math.sin (theta) * Math.sin (phi),
|
||||
radius * Math.cos (theta)
|
||||
);
|
||||
}
|
||||
|
||||
if (segments < 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let generator = new OV.Generator (genParams);
|
||||
let helper = new OV.GeneratorHelper (generator);
|
||||
|
||||
generator.SetCurve (smooth ? 1 : null);
|
||||
|
||||
let allLevelVertices = [];
|
||||
let levels = segments + 1;
|
||||
const levelStep = Math.PI / segments;
|
||||
const cylindricalStep = 2.0 * Math.PI / segments;
|
||||
for (let levelIndex = 1; levelIndex < levels - 1; levelIndex++) {
|
||||
let levelVertices = [];
|
||||
let theta = levelIndex * levelStep;
|
||||
for (let cylindricalIndex = 0; cylindricalIndex < segments; cylindricalIndex++) {
|
||||
let phi = cylindricalIndex * cylindricalStep;
|
||||
let vertex = GetSphericalCoord (radius, theta, -phi);
|
||||
levelVertices.push (generator.AddVertex (vertex.x, vertex.y, vertex.z));
|
||||
}
|
||||
if (levelIndex > 1) {
|
||||
helper.GenerateSurfaceBetweenPolygons (allLevelVertices[allLevelVertices.length - 1], levelVertices);
|
||||
}
|
||||
allLevelVertices.push (levelVertices);
|
||||
}
|
||||
|
||||
let topVertex = generator.AddVertex (0.0, 0.0, radius);
|
||||
let bottomVertex = generator.AddVertex (0.0, 0.0, -radius);
|
||||
helper.GenerateTriangleFan (allLevelVertices[0].slice ().reverse (), topVertex);
|
||||
helper.GenerateTriangleFan (allLevelVertices[allLevelVertices.length - 1], bottomVertex);
|
||||
|
||||
generator.ResetCurve ();
|
||||
|
||||
return generator.GetMesh ();
|
||||
};
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
{
|
||||
"materials" : [
|
||||
{
|
||||
"name" : "Material",
|
||||
"color" : [200, 0, 0]
|
||||
}
|
||||
],
|
||||
"meshes" : [
|
||||
{
|
||||
"name" : "Cube",
|
||||
"material" : 0,
|
||||
"type" : "cuboid",
|
||||
"parameters" : {
|
||||
"size_x" : 1.0,
|
||||
"size_y" : 1.0,
|
||||
"size_z" : 1.0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
{
|
||||
"meshes" : [
|
||||
{
|
||||
"type" : "cylinder",
|
||||
"parameters" : {
|
||||
"radius" : 0.5,
|
||||
"height" : 1.0,
|
||||
"segments" : 20,
|
||||
"smooth" : false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"meshes" : [
|
||||
{
|
||||
"type" : "cylinder",
|
||||
"parameters" : {
|
||||
"radius" : 0.5,
|
||||
"height" : 1.0,
|
||||
"segments" : 50
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
45
test/testfiles/o3dv/cylinder_types.o3dv
Normal file
45
test/testfiles/o3dv/cylinder_types.o3dv
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"meshes" : [
|
||||
{
|
||||
"type" : "cylinder",
|
||||
"parameters" : {
|
||||
"radius" : 0.5,
|
||||
"height" : 1.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"type" : "cylinder",
|
||||
"parameters" : {
|
||||
"radius" : 0.8,
|
||||
"height" : 1.2
|
||||
},
|
||||
"transformation" : {
|
||||
"translation" : [2.0, 0.0, 0.0]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type" : "cylinder",
|
||||
"parameters" : {
|
||||
"radius" : 0.5,
|
||||
"height" : 1.0,
|
||||
"smooth" : false,
|
||||
"segments" : 5
|
||||
},
|
||||
"transformation" : {
|
||||
"translation" : [2.0, 2.0, 0.0]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type" : "cylinder",
|
||||
"parameters" : {
|
||||
"radius" : 0.5,
|
||||
"height" : 1.0,
|
||||
"smooth" : false,
|
||||
"segments" : 10
|
||||
},
|
||||
"transformation" : {
|
||||
"translation" : [0.0, 2.0, 0.0]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
10
test/testfiles/o3dv/sphere.o3dv
Normal file
10
test/testfiles/o3dv/sphere.o3dv
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"meshes" : [
|
||||
{
|
||||
"type" : "sphere",
|
||||
"parameters" : {
|
||||
"radius" : 0.5
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
41
test/testfiles/o3dv/sphere_types.o3dv
Normal file
41
test/testfiles/o3dv/sphere_types.o3dv
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"meshes" : [
|
||||
{
|
||||
"type" : "sphere",
|
||||
"parameters" : {
|
||||
"radius" : 0.5
|
||||
}
|
||||
},
|
||||
{
|
||||
"type" : "sphere",
|
||||
"parameters" : {
|
||||
"radius" : 0.8
|
||||
},
|
||||
"transformation" : {
|
||||
"translation" : [2.0, 0.0, 0.0]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type" : "sphere",
|
||||
"parameters" : {
|
||||
"radius" : 0.5,
|
||||
"smooth" : false,
|
||||
"segments" : 5
|
||||
},
|
||||
"transformation" : {
|
||||
"translation" : [2.0, 2.0, 0.0]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type" : "sphere",
|
||||
"parameters" : {
|
||||
"radius" : 0.5,
|
||||
"smooth" : false,
|
||||
"segments" : 10
|
||||
},
|
||||
"transformation" : {
|
||||
"translation" : [0.0, 2.0, 0.0]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -29,8 +29,14 @@ describe ('Generator', function () {
|
||||
});
|
||||
|
||||
it ('Cylinder with Default Parameters', function () {
|
||||
const cylinder = OV.GenerateCylinder (null, 0.5, 1.0, 10, false);
|
||||
const cylinder = OV.GenerateCylinder (null, 0.5, 1.0, 25, false);
|
||||
assert (OV.IsSolid (cylinder));
|
||||
assert (OV.IsEqualEps (OV.CalculateVolume (cylinder), Math.PI * 0.5 * 0.5 * 1.0, 0.1));
|
||||
});
|
||||
});
|
||||
|
||||
it ('Sphere with Default Parameters', function () {
|
||||
const cylinder = OV.GenerateSphere (null, 0.5, 20, false);
|
||||
assert (OV.IsSolid (cylinder));
|
||||
assert (OV.IsEqualEps (OV.CalculateVolume (cylinder), Math.PI * 0.5 * 0.5 * 0.5 * 4.0 / 3.0, 0.1));
|
||||
});
|
||||
});
|
||||
|
||||
@ -29,34 +29,8 @@ describe ('O3dv Importer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it ('cube_with_material.o3dv', function (done) {
|
||||
testFiles.ImportO3dvFile ('cube_with_material.o3dv', function (model) {
|
||||
assert (OV.CheckModel (model));
|
||||
assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), {
|
||||
name : '',
|
||||
materials : [
|
||||
{ name : 'Material' }
|
||||
],
|
||||
meshes : [
|
||||
{
|
||||
name : 'Cube',
|
||||
vertexCount : 8,
|
||||
normalCount : 12,
|
||||
uvCount : 0,
|
||||
triangleCount : 12,
|
||||
boundingBox : {
|
||||
min : [0, 0, 0],
|
||||
max : [1, 1, 1]
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
done ();
|
||||
});
|
||||
});
|
||||
|
||||
it ('cube_transformation.o3dv', function (done) {
|
||||
testFiles.ImportO3dvFile ('cube_transformation.o3dv', function (model) {
|
||||
it ('transformation.o3dv', function (done) {
|
||||
testFiles.ImportO3dvFile ('transformation.o3dv', function (model) {
|
||||
assert (OV.CheckModel (model));
|
||||
assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), {
|
||||
name : '',
|
||||
@ -141,31 +115,5 @@ describe ('O3dv Importer', function () {
|
||||
});
|
||||
done ();
|
||||
});
|
||||
});
|
||||
|
||||
it ('cylinder_non_smooth.o3dv', function (done) {
|
||||
testFiles.ImportO3dvFile ('cylinder_non_smooth.o3dv', function (model) {
|
||||
assert (OV.CheckModel (model));
|
||||
assert.deepStrictEqual (testUtils.ModelToObjectSimple (model), {
|
||||
name : '',
|
||||
materials : [
|
||||
{ name : '' }
|
||||
],
|
||||
meshes : [
|
||||
{
|
||||
name : '',
|
||||
vertexCount : 40,
|
||||
normalCount : 76,
|
||||
uvCount : 0,
|
||||
triangleCount : 76,
|
||||
boundingBox : {
|
||||
min : [-0.5, -0.5, 0],
|
||||
max : [0.5, 0.5, 1]
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
done ();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user