# Round-edged box 2

Based on the idea from this post.
A usual geometry, not a buffer one.
Limitation in this version is that smoothness can’t be less than 3, as it uses THREE.SphereGeometry() which has that limitation for its widthSegments parameter.

https://jsfiddle.net/prisoner849/p614jc75/

Criticism is very welcomed.

function RoundEdgedBox(width, height, depth, radius, widthSegments, heightSegments, depthSegments, smoothness) {

width = width || 1;
height = height || 1;
depth = depth || 1;
widthSegments = Math.floor(widthSegments) || 1;
heightSegments = Math.floor(heightSegments) || 1;
depthSegments = Math.floor(depthSegments) || 1;
smoothness = Math.max(3, Math.floor(smoothness) || 3);

let halfWidth = width * .5 - radius;
let halfHeight = height * .5 - radius;
let halfDepth = depth * .5 - radius;

var geometry = new THREE.Geometry();

// corners - 4 eighths of a sphere
var corner1 = new THREE.SphereGeometry(radius, smoothness, smoothness, 0, Math.PI * .5, 0, Math.PI * .5);
corner1.translate(-halfWidth, halfHeight, halfDepth);
var corner2 = new THREE.SphereGeometry(radius, smoothness, smoothness, Math.PI * .5, Math.PI * .5, 0, Math.PI * .5);
corner2.translate(halfWidth, halfHeight, halfDepth);
var corner3 = new THREE.SphereGeometry(radius, smoothness, smoothness, 0, Math.PI * .5, Math.PI * .5, Math.PI * .5);
corner3.translate(-halfWidth, -halfHeight, halfDepth);
var corner4 = new THREE.SphereGeometry(radius, smoothness, smoothness, Math.PI * .5, Math.PI * .5, Math.PI * .5, Math.PI * .5);
corner4.translate(halfWidth, -halfHeight, halfDepth);

geometry.merge(corner1);
geometry.merge(corner2);
geometry.merge(corner3);
geometry.merge(corner4);

// edges - 2 fourths for each dimension
// width
var edge = new THREE.CylinderGeometry(radius, radius, width - radius * 2, smoothness, widthSegments, true, 0, Math.PI * .5);
edge.rotateZ(Math.PI * .5);
edge.translate(0, halfHeight, halfDepth);
var edge2 = new THREE.CylinderGeometry(radius, radius, width - radius * 2, smoothness, widthSegments, true, Math.PI * 1.5, Math.PI * .5);
edge2.rotateZ(Math.PI * .5);
edge2.translate(0, -halfHeight, halfDepth);

// height
var edge3 = new THREE.CylinderGeometry(radius, radius, height - radius * 2, smoothness, heightSegments, true, 0, Math.PI * .5);
edge3.translate(halfWidth, 0, halfDepth);
var edge4 = new THREE.CylinderGeometry(radius, radius, height - radius * 2, smoothness, heightSegments, true, Math.PI * 1.5, Math.PI * .5);
edge4.translate(-halfWidth, 0, halfDepth);

// depth
var edge5 = new THREE.CylinderGeometry(radius, radius, depth - radius * 2, smoothness, depthSegments, true, 0, Math.PI * .5);
edge5.rotateX(-Math.PI * .5);
edge5.translate(halfWidth, halfHeight, 0);
var edge6 = new THREE.CylinderGeometry(radius, radius, depth - radius * 2, smoothness, depthSegments, true, Math.PI * .5, Math.PI * .5);
edge6.rotateX(-Math.PI * .5);
edge6.translate(halfWidth, -halfHeight, 0);

edge.merge(edge2);
edge.merge(edge3);
edge.merge(edge4);
edge.merge(edge5);
edge.merge(edge6);

// sides
// front
var side = new THREE.PlaneGeometry(width - radius * 2, height - radius * 2, widthSegments, heightSegments);
side.translate(0, 0, depth * .5);

// right
var side2 = new THREE.PlaneGeometry(depth - radius * 2, height - radius * 2, depthSegments, heightSegments);
side2.rotateY(Math.PI * .5);
side2.translate(width * .5, 0, 0);

side.merge(side2);

geometry.merge(edge);
geometry.merge(side);

// duplicate and flip
var secondHalf = geometry.clone();
secondHalf.rotateY(Math.PI);
geometry.merge(secondHalf);

// top
var top = new THREE.PlaneGeometry(width - radius * 2, depth - radius * 2, widthSegments, depthSegments);
top.rotateX(-Math.PI * .5);
top.translate(0, height * .5, 0);

// bottom
var bottom = new THREE.PlaneGeometry(width - radius * 2, depth - radius * 2, widthSegments, depthSegments);
bottom.rotateX(Math.PI * .5);
bottom.translate(0, -height * .5, 0);

geometry.merge(top);
geometry.merge(bottom);

geometry.mergeVertices();

return geometry;
}
3 Likes

yup this is it, the geometry here is perfect

1 Like

And I have one more idea about a round-edged box geometry
Just caught it, going home from work ))

The only problem of the solution with the parts of the sphere is that it is not completely symmetrical.

I drew the following structure. To possibly do it with BufferGeometry. By way of
But there are a lot of faces!

1 Like

Yeah, as I used THREE.SphereGeometry(), it’s symmetrical on Y-axis only.
I think, I got what you mean. But we don’t need such precision and complexity.
The concept of this solution is to combine basic geometries and their parts ))

Understood!
But I like to play with structures.

Tried my addon - that could also work.

easier with 3 divisions

1 Like

And this is cool actually. Your work is great

How complex the code for this? If it’s not a secret, could you provide the link to the module and point to the line of code? ))

That’s not very much. I also don’t find it in the addon itself.
But in the preparatory work it is the main part:
http://threejs.hofk.de/sphere/00_hemiSphere_n_part.html
http://threejs.hofk.de/sphere/00_hemiSphere4.html
At http://threejs.hofk.de/ there are two further variants in the middle of the website

It always takes time with me, but these are the main lines of a variant

var rs; // rings
var rvSum; // sum of ring vertices
var vertexCount;
var x, y, z;
var a, b, c;
var ni, nji; // relative i, j
var Alpha;
var sinAlpha;
var cosAlpha;

g = new THREE.Geometry();
rs = 3; // rings

vertexCount = 1 + 2 * rs * ( rs + 1 ) ;

for ( var i = 0; i < vertexCount; i ++ ) {

g.vertices.push( new THREE.Vector3( 0, 0, 0 ) );

}

// vertex 0: pole
g.faces.push( new THREE.Face3( 0, 1, 2 ) );
g.faces.push( new THREE.Face3( 0, 2, 3 ) );
g.faces.push( new THREE.Face3( 0, 3, 4 ) );
g.faces.push( new THREE.Face3( 0, 4, 1 ) );

rvSum = 1; // only vertex 0

for ( var i = 1; i < rs; i ++ ) {

for ( var q = 0; q < 4; q ++ ) {			// quarter ring

for ( var j = 0; j < i + 1 ; j ++ ) {

if ( j === 0 ) {

//  first face in quarter

a = rvSum;
b = a + 4 * i + q;
c = b + 1;

g.faces.push( new THREE.Face3( a, b, c ) );

} else {

//  two faces / vertex

a = j + rvSum;
b = a - 1;
c = a + 4 * i + q;
if ( q === 3 && j === i ) a = a - 4 * i; // connect to first vertex of circle

g.faces.push( new THREE.Face3( a, b, c ) );

// a  from first face
b = c; // from first face
c = b + 1;

if ( q === 3 && j === i ) c = c - 4 * ( i + 1 ); // connect to first vertex of next circle

g.faces.push( new THREE.Face3( a, b, c ) );

}

}

rvSum += i;
}

}

g.vertices[ 0 ].set( 0, radius, 0 ); // pole

rvSum = 1; // only vertex 0

for ( var i = 0; i <= rs; i ++ ) {

ni = i / rs;
Alpha = Math.PI / 2 * ni;
sinAlpha = Math.sin( Alpha );
cosAlpha = Math.cos( Alpha );

for ( var j = 0; j < i * 4; j ++ ) {

nji = j / ( i * 4 );

x = radius * sinAlpha * Math.cos( 2 * Math.PI * nji );
z = - radius * sinAlpha * Math.sin( 2 * Math.PI * nji );

g.vertices[  rvSum + j ].set( x, y, z );

}

rvSum += i * 4;

}
1 Like

Danke schoen!
I’ll look at it as soon as I can )

In the current version of THREEp it is a little bit hidden, I had to search for it myself.

uWed are the used wedges

var wed = g.wedges;
var uWed = g.usedWedges;

With wed = 4 and uWed = 1 you get the required round corner.

view-source:http://sandboxthreep.threejs.hofk.de/THREEp.js

197 in function:
function create() {...
---------------------
538
// faces south hemisphere

...

561 - 605
vIdx = g.southVertex;

for ( var i = bottomS === 0 ? 1 : bottomS; i < topS; i ++ ) {

for ( var w = 0; w < uWed; w ++ ) {

for ( var j = 0; j < i + 1 ; j ++ ) {

if ( j === 0 ) {

//  first face in wedge

a = vIdx;
b = a + uWed * i + w + 2;
c = b - 1;

pushFaceAndUv()

} else {

//  two faces / vertex

a = j + vIdx;
b = a + uWed * i + w + 1;
c = a - 1;

pushFaceAndUv()

// a  from first face
b++; // b from first face
c = b - 1;

pushFaceAndUv()

}

}

vIdx += i;

}

vIdx ++;

}

2075 in  function:
function morphVertices(...
------------------------
2158
function xyzCalculation(...
...
2207
if (  g.style === "complete" && g.squeezeDefault ) {

r = g.radius * g.rAzimuthPole( nji, ni, t );

x = r * Math.cos( theta ) * Math.cos( phi ) + g.radius * g.moveX( nji, ni, t );

y =  r * Math.sin( theta );
y *= ( sn === SOUTH ? g.stretchSouth( nji, nih, t ) : g.stretchNorth( nji, nih, t ) );
y += g.radius * ( sn * g.equatorGap( nji, t ) / 2 + g.moveY( nji, ni, t ) );

z = -r * Math.cos( theta ) * Math.sin( phi ) + g.radius * g.moveZ( nji, ni, t );

}

My mind kinda melts when reading this code. Does it even create the full rounded box, if not what is being discussed here?

For what it’s worth, my attempt can be found at http://webglworkshop.com/demos/fillet/filletBox.html

I use BoxGeometry and convert it to a sphere as an intermediate step.

3 Likes

A very similar idea

i love this one, you actually mapped it!