Add cone generator.
This commit is contained in:
parent
a68902f33b
commit
603d7c8699
@ -6,7 +6,7 @@ import { ArrayToQuaternion, Quaternion } from '../geometry/quaternion.js';
|
|||||||
import { Transformation } from '../geometry/transformation.js';
|
import { Transformation } from '../geometry/transformation.js';
|
||||||
import { ArrayBufferToUtf8String } from '../io/bufferutils.js';
|
import { ArrayBufferToUtf8String } from '../io/bufferutils.js';
|
||||||
import { ArrayToColor } from '../model/color.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 { PhysicalMaterial } from '../model/material.js';
|
||||||
import { Node, NodeType } from '../model/node.js';
|
import { Node, NodeType } from '../model/node.js';
|
||||||
import { Property, PropertyGroup, PropertyType } from '../model/property.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 segments = ValueOrDefault (parameters.segments, 25);
|
||||||
let smooth = ValueOrDefault (parameters.smooth, true);
|
let smooth = ValueOrDefault (parameters.smooth, true);
|
||||||
mesh = GenerateCylinder (genParams, parameters.radius, parameters.height, segments, smooth);
|
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') {
|
} else if (meshContent.type === 'sphere') {
|
||||||
if (parameters.radius === undefined) {
|
if (parameters.radius === undefined) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -41,7 +41,7 @@ import { SetExternalLibLocation, LoadExternalLibrary } from './io/externallibs.j
|
|||||||
import { GetFileName, GetFileExtension, RequestUrl, ReadFile, TransformFileHostUrls, FileSource, FileFormat } from './io/fileutils.js';
|
import { GetFileName, GetFileExtension, RequestUrl, ReadFile, TransformFileHostUrls, FileSource, FileFormat } from './io/fileutils.js';
|
||||||
import { TextWriter } from './io/textwriter.js';
|
import { TextWriter } from './io/textwriter.js';
|
||||||
import { Color, ColorComponentFromFloat, ColorFromFloatComponents, SRGBToLinear, LinearToSRGB, IntegerToHexString, ColorToHexString, HexStringToColor, ArrayToColor, ColorIsEqual } from './model/color.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 { TextureMap, MaterialBase, FaceMaterial, PhongMaterial, PhysicalMaterial, TextureMapIsEqual, TextureIsEqual, MaterialType } from './model/material.js';
|
||||||
import { Mesh } from './model/mesh.js';
|
import { Mesh } from './model/mesh.js';
|
||||||
import { MeshPrimitiveBuffer, MeshBuffer, ConvertMeshToMeshBuffer } from './model/meshbuffer.js';
|
import { MeshPrimitiveBuffer, MeshBuffer, ConvertMeshToMeshBuffer } from './model/meshbuffer.js';
|
||||||
@ -200,6 +200,7 @@ export {
|
|||||||
Generator,
|
Generator,
|
||||||
GeneratorHelper,
|
GeneratorHelper,
|
||||||
GenerateCuboid,
|
GenerateCuboid,
|
||||||
|
GenerateCone,
|
||||||
GenerateCylinder,
|
GenerateCylinder,
|
||||||
GenerateSphere,
|
GenerateSphere,
|
||||||
GeneratePlatonicSolid,
|
GeneratePlatonicSolid,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Coord2D } from '../geometry/coord2d.js';
|
import { Coord2D } from '../geometry/coord2d.js';
|
||||||
import { Coord3D } from '../geometry/coord3d.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 { Mesh } from './mesh.js';
|
||||||
import { Triangle } from './triangle.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)
|
export function GenerateCuboid (genParams, xSize, ySize, zSize)
|
||||||
{
|
{
|
||||||
|
if (!IsPositive (xSize) || !IsPositive (ySize) || !IsPositive (zSize)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
let generator = new Generator (genParams);
|
let generator = new Generator (genParams);
|
||||||
let vertices = [
|
let vertices = [
|
||||||
new Coord2D (0.0, 0.0),
|
new Coord2D (0.0, 0.0),
|
||||||
@ -178,32 +190,73 @@ export function GenerateCuboid (genParams, xSize, ySize, zSize)
|
|||||||
return generator.GetMesh ();
|
return generator.GetMesh ();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GenerateCylinder (genParams, radius, height, segments, smooth)
|
export function GenerateCone (genParams, topRadius, bottomRadius, height, segments, smooth)
|
||||||
{
|
{
|
||||||
function GetCylindricalCoord (radius, angle)
|
if (IsNegative (topRadius) || IsNegative (bottomRadius)) {
|
||||||
{
|
return null;
|
||||||
return new Coord2D (
|
|
||||||
radius * Math.cos (angle),
|
|
||||||
radius * Math.sin (angle)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segments < 3) {
|
if (!IsPositive (height) || segments < 3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isZeroTop = IsZero (topRadius);
|
||||||
|
let isZeroBottom = IsZero (bottomRadius);
|
||||||
|
if (isZeroTop && isZeroBottom) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let generator = new Generator (genParams);
|
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);
|
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 ();
|
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)
|
export function GenerateSphere (genParams, radius, segments, smooth)
|
||||||
{
|
{
|
||||||
function GetSphericalCoord (radius, theta, phi)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +314,7 @@ export function GeneratePlatonicSolid (genParams, type, radius)
|
|||||||
generator.AddVertex (vertex.x, vertex.y, vertex.z);
|
generator.AddVertex (vertex.x, vertex.y, vertex.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsZero (radius)) {
|
if (!IsPositive (radius)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
83
test/testfiles/o3dv/all_shapes.o3dv
Normal file
83
test/testfiles/o3dv/all_shapes.o3dv
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -26,6 +26,24 @@ describe ('Generator', function () {
|
|||||||
assert.ok (OV.IsEqualEps (OV.CalculateVolume (cylinder), Math.PI * 0.5 * 0.5 * 1.0, 0.1));
|
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 () {
|
it ('Sphere with Default Parameters', function () {
|
||||||
const cylinder = OV.GenerateSphere (null, 0.5, 20, false);
|
const cylinder = OV.GenerateSphere (null, 0.5, 20, false);
|
||||||
assert.ok (OV.IsSolid (cylinder));
|
assert.ok (OV.IsSolid (cylinder));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user