Add cone generator.

This commit is contained in:
kovacsv 2022-01-18 23:19:21 +01:00
parent a68902f33b
commit 603d7c8699
5 changed files with 182 additions and 20 deletions

View File

@ -6,7 +6,7 @@ import { ArrayToQuaternion, Quaternion } from '../geometry/quaternion.js';
import { Transformation } from '../geometry/transformation.js';
import { ArrayBufferToUtf8String } from '../io/bufferutils.js';
import { ArrayToColor } from '../model/color.js';
import { GenerateCuboid, GenerateCylinder, GeneratePlatonicSolid, GenerateSphere, GeneratorParams } from '../model/generator.js';
import { GenerateCone, GenerateCuboid, GenerateCylinder, GeneratePlatonicSolid, GenerateSphere, GeneratorParams } from '../model/generator.js';
import { PhysicalMaterial } from '../model/material.js';
import { Node, NodeType } from '../model/node.js';
import { Property, PropertyGroup, PropertyType } from '../model/property.js';
@ -111,6 +111,13 @@ export class ImporterO3dv extends ImporterBase
let segments = ValueOrDefault (parameters.segments, 25);
let smooth = ValueOrDefault (parameters.smooth, true);
mesh = GenerateCylinder (genParams, parameters.radius, parameters.height, segments, smooth);
} else if (meshContent.type === 'cone') {
if (parameters.top_radius === undefined || parameters.bottom_radius === undefined || parameters.height === undefined) {
return;
}
let segments = ValueOrDefault (parameters.segments, 25);
let smooth = ValueOrDefault (parameters.smooth, true);
mesh = GenerateCone (genParams, parameters.top_radius, parameters.bottom_radius, parameters.height, segments, smooth);
} else if (meshContent.type === 'sphere') {
if (parameters.radius === undefined) {
return;

View File

@ -41,7 +41,7 @@ import { SetExternalLibLocation, LoadExternalLibrary } from './io/externallibs.j
import { GetFileName, GetFileExtension, RequestUrl, ReadFile, TransformFileHostUrls, FileSource, FileFormat } from './io/fileutils.js';
import { TextWriter } from './io/textwriter.js';
import { Color, ColorComponentFromFloat, ColorFromFloatComponents, SRGBToLinear, LinearToSRGB, IntegerToHexString, ColorToHexString, HexStringToColor, ArrayToColor, ColorIsEqual } from './model/color.js';
import { GeneratorParams, Generator, GeneratorHelper, GenerateCuboid, GenerateCylinder, GenerateSphere, GeneratePlatonicSolid } from './model/generator.js';
import { GeneratorParams, Generator, GeneratorHelper, GenerateCuboid, GenerateCone, GenerateCylinder, GenerateSphere, GeneratePlatonicSolid } from './model/generator.js';
import { TextureMap, MaterialBase, FaceMaterial, PhongMaterial, PhysicalMaterial, TextureMapIsEqual, TextureIsEqual, MaterialType } from './model/material.js';
import { Mesh } from './model/mesh.js';
import { MeshPrimitiveBuffer, MeshBuffer, ConvertMeshToMeshBuffer } from './model/meshbuffer.js';
@ -200,6 +200,7 @@ export {
Generator,
GeneratorHelper,
GenerateCuboid,
GenerateCone,
GenerateCylinder,
GenerateSphere,
GeneratePlatonicSolid,

View File

@ -1,6 +1,6 @@
import { Coord2D } from '../geometry/coord2d.js';
import { Coord3D } from '../geometry/coord3d.js';
import { IsZero } from '../geometry/geometry.js';
import { IsPositive, IsNegative, IsZero } from '../geometry/geometry.js';
import { Mesh } from './mesh.js';
import { Triangle } from './triangle.js';
@ -164,8 +164,20 @@ export class GeneratorHelper
}
}
function GetCylindricalCoord (radius, angle)
{
return new Coord2D (
radius * Math.cos (angle),
radius * Math.sin (angle)
);
}
export function GenerateCuboid (genParams, xSize, ySize, zSize)
{
if (!IsPositive (xSize) || !IsPositive (ySize) || !IsPositive (zSize)) {
return null;
}
let generator = new Generator (genParams);
let vertices = [
new Coord2D (0.0, 0.0),
@ -178,32 +190,73 @@ export function GenerateCuboid (genParams, xSize, ySize, zSize)
return generator.GetMesh ();
}
export function GenerateCylinder (genParams, radius, height, segments, smooth)
export function GenerateCone (genParams, topRadius, bottomRadius, height, segments, smooth)
{
function GetCylindricalCoord (radius, angle)
{
return new Coord2D (
radius * Math.cos (angle),
radius * Math.sin (angle)
);
if (IsNegative (topRadius) || IsNegative (bottomRadius)) {
return null;
}
if (segments < 3) {
if (!IsPositive (height) || segments < 3) {
return null;
}
let isZeroTop = IsZero (topRadius);
let isZeroBottom = IsZero (bottomRadius);
if (isZeroTop && isZeroBottom) {
return null;
}
let generator = new Generator (genParams);
let baseVertices = [];
const step = 2.0 * Math.PI / segments;
for (let i = 0; i < segments; i++) {
let cylindrical = GetCylindricalCoord (radius, i * step);
baseVertices.push (cylindrical);
}
let helper = new GeneratorHelper (generator);
helper.GenerateExtrude (baseVertices, height, smooth ? 1 : null);
const step = 2.0 * Math.PI / segments;
const curve = (smooth ? 1 : null);
let topPolygon = [];
if (isZeroTop) {
topPolygon.push (generator.AddVertex (0.0, 0.0, height));
} else {
for (let i = 0; i < segments; i++) {
let topVertex = GetCylindricalCoord (topRadius, i * step);
topPolygon.push (generator.AddVertex (topVertex.x, topVertex.y, height));
}
}
let bottomPolygon = [];
if (isZeroBottom) {
bottomPolygon.push (generator.AddVertex (0.0, 0.0, 0.0));
} else {
for (let i = 0; i < segments; i++) {
let bottomVertex = GetCylindricalCoord (bottomRadius, i * step);
bottomPolygon.push (generator.AddVertex (bottomVertex.x, bottomVertex.y, 0.0));
}
}
if (isZeroTop) {
generator.SetCurve (curve);
helper.GenerateTriangleFan (bottomPolygon, topPolygon[0]);
generator.ResetCurve ();
generator.AddConvexPolygonInverted (bottomPolygon);
} else if (isZeroBottom) {
generator.SetCurve (curve);
helper.GenerateTriangleFan (topPolygon.slice ().reverse (), bottomPolygon[0]);
generator.ResetCurve ();
generator.AddConvexPolygon (topPolygon);
} else {
generator.SetCurve (curve);
helper.GenerateSurfaceBetweenPolygons (bottomPolygon, topPolygon);
generator.ResetCurve ();
generator.AddConvexPolygonInverted (bottomPolygon);
generator.AddConvexPolygon (topPolygon);
}
return generator.GetMesh ();
}
export function GenerateCylinder (genParams, radius, height, segments, smooth)
{
return GenerateCone (genParams, radius, radius, height, segments, smooth);
}
export function GenerateSphere (genParams, radius, segments, smooth)
{
function GetSphericalCoord (radius, theta, phi)
@ -215,7 +268,7 @@ export function GenerateSphere (genParams, radius, segments, smooth)
);
}
if (segments < 3) {
if (!IsPositive (radius) || segments < 3) {
return null;
}
@ -261,7 +314,7 @@ export function GeneratePlatonicSolid (genParams, type, radius)
generator.AddVertex (vertex.x, vertex.y, vertex.z);
}
if (IsZero (radius)) {
if (!IsPositive (radius)) {
return null;
}

View File

@ -0,0 +1,83 @@
{
"root" : 0,
"nodes" : [
{
"children" : [1, 2, 3, 4]
},
{
"transformation" : {
"translation" : [0.0, 0.0, 0.0]
},
"mesh" : 0
},
{
"transformation" : {
"translation" : [2.0, 0.0, 0.0]
},
"mesh" : 1
},
{
"transformation" : {
"translation" : [4.0, 0.0, 0.0]
},
"mesh" : 2
},
{
"transformation" : {
"translation" : [6.0, 0.0, 0.0]
},
"mesh" : 3
}
],
"materials" : [
{
"name" : "Blue",
"color" : [0, 0, 200]
}
],
"meshes" : [
{
"name" : "Cube",
"type" : "cuboid",
"material" : 0,
"parameters" : {
"size_x" : 1.0,
"size_y" : 1.0,
"size_z" : 1.0
}
},
{
"name" : "Cylinder",
"type" : "cylinder",
"material" : 0,
"parameters" : {
"radius" : 0.5,
"height" : 1.0,
"segments" : 25,
"smooth" : true
}
},
{
"name" : "Sphere",
"type" : "sphere",
"material" : 0,
"parameters" : {
"radius" : 0.5,
"segments" : 25,
"smooth" : true
}
},
{
"name" : "Cone",
"type" : "cone",
"material" : 0,
"parameters" : {
"top_radius" : 0.2,
"bottom_radius" : 0.5,
"height" : 1.0,
"segments" : 25,
"smooth" : true
}
}
]
}

View File

@ -26,6 +26,24 @@ describe ('Generator', function () {
assert.ok (OV.IsEqualEps (OV.CalculateVolume (cylinder), Math.PI * 0.5 * 0.5 * 1.0, 0.1));
});
it ('Cone with Default Parameters', function () {
const cone = OV.GenerateCone (null, 0.2, 0.5, 1.0, 20, false);
assert.ok (OV.IsSolid (cone));
assert.ok (OV.IsEqualEps (OV.CalculateVolume (cone), Math.PI / 3.0 * 1.0 * (0.2 * 0.2 + 0.2 * 0.5 + 0.5 * 0.5), 0.1));
});
it ('Cone Zero Top', function () {
const cone = OV.GenerateCone (null, 0.0, 0.5, 1.0, 20, false);
assert.ok (OV.IsSolid (cone));
assert.ok (OV.IsEqualEps (OV.CalculateVolume (cone), 0.5 * 0.5 * Math.PI * 1.0 / 3.0, 1.0));
});
it ('Cone Zero Bottom', function () {
const cone = OV.GenerateCone (null, 0.5, 0.0, 1.0, 20, false);
assert.ok (OV.IsSolid (cone));
assert.ok (OV.IsEqualEps (OV.CalculateVolume (cone), 0.5 * 0.5 * Math.PI * 1.0 / 3.0, 1.0));
});
it ('Sphere with Default Parameters', function () {
const cylinder = OV.GenerateSphere (null, 0.5, 20, false);
assert.ok (OV.IsSolid (cylinder));