A library module from the Persistence of Vision Ray Tracer (POV-Ray) Object Collection.
Perfectly sharp edges are rare in real life. Blunting or rounding-off the edges of ray traced objects brings out specular highlights and other, more subtle lighting effects that can make the difference between “That’s a nice ray-traced scene,” and “Wow!”
Unfortunately, with CSG this task is tedious and time-consuming. The standard include file shapes.inc
has some helpful macros to assist with this task, but they are rather limited. RoundEdge builds upon shapes.inc
and adds some additional objects and functions.
Each italicized n in the filenames represents a decimal digit.
Key Files | |
---|---|
File | Description |
roundedge.html |
The user manual (this document) |
roundedge.inc |
The RoundEdge software |
roundedge.jpg |
Sample output |
roundedge_ nn.jpg |
Illustrations of the various features (30 images) |
roundedge.pov |
A demonstration scene file, which was used to render the sample illustrations in this manual |
README nnnnnn.html |
Important information about using the Object Collection |
Other Files | |
File | Description |
roundedge.css |
A file used by the user manual |
roundedge_description.txt |
A brief description of RoundEdge |
roundedge_keywords.txt |
A list of keywords |
roundedge_prereqs.txt |
Prerequisites (empty file) |
roundedge_thumbnail.jpg |
Sample output |
cc-LGPL-a.png |
Administrative files |
Version nnnnnn.js |
Note: Please compare the contents of the zip archive with the above table to make sure that all 30 illustration files are present; in some previous versions of RoundEdge, some of these files failed to upload. (Do this even if you have a previous version of RoundEdge, as the numbering of the illustrations has changed.) If any illustrations are missing from this archive, they can be generated (after you have unzipped the package) by running POV-Ray with these command line arguments:
+Iroundedge.pov +W240 +H180 Declare=Rad=1 +A0.05 +AM2 +R3 +KFF30 +Oroundedge_
If you are using POV-Ray 3.7, add +FJ Compression=90
to the command line. If you are using POV-Ray 3.5 or 3.6, you will need to convert the illustrations to JPEG format using a separate tool. To match the quality of the other illustrations, use quality 90 and chroma subsampling 1x1,1x1,1x1 or 4:4:4.
Include this file once prior to using any of the features of RoundEdge:
#include "roundedge.inc"
Including the file more than once is harmless, though unnecessary.
The descriptions of the objects assume valid arguments. If the arguments are not valid (for example, a negative radius), then the shape is undefined, with no guarantee of what it will look like or that it will fit anywhere. To assist the user, a warning or error message will be issued.
Requires POV-Ray version 3.5 or later.
All file names in this module and all global and local identifiers defined in roundedge.inc
comply with the Object Collection naming standards, as revised August 2008 and proposed August 2012. The prefixes for this module are “roundedge
” and “RE
,” including any uppercase and lowercase variants; to avoid conflicts, do not declare identifiers that start with these prefixes plus an underscore.
The standard include files functions.inc
, shapes.inc
, and transforms.inc
are used by roundedge.inc
.
An instant blob for the point of intersection of three orthogonal planes. It can be used to patch the Y-shaped seams left by the straight join macros. The joint is at the origin, and the curve faces the positive x-y-z octant. (In the illustration, the
RE_Corner_join()
object has been rotated to match the corner.) To avoid potential coincident surfaces, the object overlaps the origin.
rBlob
:
An instant blob for a vertical cylindrical post joined to a horizontal plane. The intersection of the post’s axis with the plane is at the origin. To avoid potential coincident surfaces, the bottom surface of the join is slightly below the origin.
RPost
: rBlob
:
An instant blob for a vertical hollow cylinder joined to a horizontal plane. The intersection of the cylinder’s axis with the plane is at the origin. To avoid potential coincident surfaces, the join slightly overlaps the hollow cylinder, and bottom surface of the join is slightly below the origin.
RHollow
: rBlob
:
An instant blob for the join between a y-normal plane and a z-normal plane. To avoid potential coincident surfaces, the object overlaps the line of intersection.
These arguments may seem odd, but they were chosen to minimize typing and mental effort.
v_Start
: End_x
:
rBlob
: Dir
: An instant blob for the join between an x-normal plane and a z-normal plane. To avoid potential coincident surfaces, the object overlaps the line of intersection.
These arguments may seem odd, but they were chosen to minimize typing and mental effort.
v_Start
: End_y
:
rBlob
: Dir
: An instant blob for the join between an x-normal plane and a y-normal plane. To avoid potential coincident surfaces, the object overlaps the line of intersection.
These arguments may seem odd, but they were chosen to minimize typing and mental effort.
v_Start
: End_z
:
rBlob
: Dir
:
A toroid mesh that can serve as a rounded edge for scaled cylinders, when it is desired that the edge radius not be scaled with the cylinders. The central curve, the extreme inner curve, and the extreme outer curve are all ellipses (within the resolution of the mesh). Note that a sphere sweep does not satisfy this condition (except for the boundary cases where the ellipses are circles), as the required shape does not have a constant minor radius.
The toroid is oriented horizontally. (In the illustration, it has been rotated 90° about the x-axis for better viewing.) The mesh can be used in CSG differences and intersections.
RxMajor
: RzMajor
: rMinor
: ThetaRes
:
PhiRes
:
The +x, +y, +z octant of a horizontally oriented elliptical toroid, implemented as a mesh. The object is intended to serve as a rounded edge for scaled cylinders, when it is desired that the edge radius not be scaled with the cylinders. The central curve, the extreme inner curve, and the extreme outer curve are all elliptical arcs (within the resolution of the mesh). Note that a sphere sweep does not satisfy this condition (except for the boundary cases where the arcs are circular), as the required shape does not have a constant minor radius.
The mesh is closed, and can be used in CSG differences and intersections. The “flat” surfaces are bowed outward slightly to avoid potential coincident surfaces. (There are still intermittent artifacts resembling coincident surfaces, but I haven’t yet identified the cause.)
RxMajor
: RzMajor
: rMinor
: ThetaRes
:
PhiRes
:
A circle of radius
R
parallel to the y-z plane, swept along the curve y = H
x2 | z = 0.
The user is responsible for clipping and bounding. The objects are prone to floating point error, so an isosurface function, RE_fn_Parabolic_torus()
, is also provided.
H
: R
:
A wrapper for macro
Round_Cylinder()
with several enhancements:
Round_Cylinder_Union()
, this generally results in faster renders. (This feature can be disabled by setting RE_Split_union
to on
.)
A
, B
: ROuter
: rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
A cylinder that is rounded on one end. The resulting object will fit snugly within
cylinder { A, B, ROuter }
.
A
: B
: ROuter
: rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
A cylinder with a hole along the central axis.
The edges of the hole are rounded.
The resulting object will fit snugly within
cylinder { A, B, ROuter }
and snugly around
cylinder { A, B, RInner }
.
A
, B
: ROuter
: RInner
: rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
A cylinder with a hole along the central axis.
The edge of the hole at one end is rounded.
The resulting object will fit snugly within
cylinder { A, B, ROuter }
and snugly around
cylinder { A, B, RInner }
.
A
: B
: ROuter
: RInner
: rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
A cylinder with a hole along the central axis.
The edges of the hole are rounded, and the cylinder is just wide enough to cover the joint between perpendicular rounded boxes of the same edge radius.
The object will fit snugly around
cylinder { A, B, RInner }
.
A
, B
: RInner
: rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
A cylinder with a hole along the central axis.
One edge of the hole is rounded, and the cylinder is just wide enough to cover the joint between perpendicular rounded boxes of the same edge radius.
The object will fit snugly around
cylinder { A, B, RInner }
.
A
: B
: RInner
: rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
A cylinder with a hole along the central axis.
The edges of the cylinder and the hole are rounded.
The resulting object will fit snugly within
cylinder { A, B, ROuter }
and snugly around
cylinder { A, B, RInner }
.
A
, B
: ROuter
: RInner
: rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
A cylinder with a hole along the central axis.
The edges on one side of the cylinder and the hole are rounded.
The resulting object will fit snugly within
cylinder { A, B, ROuter }
and snugly around
cylinder { A, B, RInner }
.
A
: B
: ROuter
: RInner
: rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
The first macro creates a box with all its edges rounded off. The remaining macros create boxes with only some rounded edges. The intent of the partially rounded box macros is to reduce object counts. This can result in significantly faster renders where differences, intersections, or photons are used.
Despite the large number of macros in this section, there are only four basic shapes: the fully rounded box; and three partially rounded boxes that are pre-rotated into various orientations by the macros.
All of the rounded box macros take the same set of arguments:
A
, B
:
rEdge
: Use_merge
:
yes
if the object is to be transparent, no
otherwise.
The resulting object will fit snugly within box { A, B }
.
A wrapper for macro
Round_Box()
with two enhancements:
Round_Box_Union()
, this generally results in faster renders. (This feature can be disabled by setting RE_Split_union
to on
.)
A box with the four edges in the x-direction rounded, like a can of sardines on its side.
A box with the four edges in the y-direction rounded, like a can of sardines.
A box with the four edges in the z-direction rounded, like a can of sardines on its side.
A box with the four corners on the −x side and the eight adjacent edges rounded.
A box with the four corners on the +x side and the eight adjacent edges rounded.
A box with the four corners on the +y side and the eight adjacent edges rounded.
A box with the four corners on the −y side and the eight adjacent edges rounded.
A box with the four corners on the −z side and the eight adjacent edges rounded.
A box with the four corners on the +z side and the eight adjacent edges rounded.
A box with the two top edges in the x-direction rounded.
A box with the two bottom edges in the x-direction rounded.
A box with the two edges in the x-direction on the −z side rounded.
A box with the two edges in the x-direction on the +z side rounded.
A box with the two edges in the y-direction on the −x side rounded.
A box with the two edges in the y-direction on the +x side rounded.
A box with the two edges in the y-direction on the −z side rounded.
A box with the two edges in the y-direction on the +z side rounded.
A box with the two top edges in the z-direction rounded.
A box with the two bottom edges in the z-direction rounded.
A box with the two edges in the z-direction on the −x side rounded.
A box with the two edges in the z-direction on the +x side rounded.
For all of these functions, the default threshold of 0.0 is assumed.
Note: All function arguments (other than x
, y
, and z
) are prefixed with “RE_P
n_
” in roundedge.inc
, in order to avoid a POV-Ray namespace scope feature. In this document, these prefixes are omitted for clarity.
An isosurface blobbing function. This function is based on the formula for the blob primitive, so when it’s used with
f_sphere()
, it gives results identical to the blob primitive (within the limits of the accuracy of the isosurface).
Value
:
Blob
:
Subtract RE_fn_Blob()
of all base functions from 1. For example:
isosurface { function { 1 - RE_fn_Blob (abs(x) + abs(z) - 1, 0.3) - RE_fn_Blob (f_sphere (0, y, z, 0.8), 0.2) } max_gradient 4 / 0.2 contained_by { box { -<2.5, 2, 1>, <2.5, 2, 1> } } }
Another isosurface blobbing function. This function uses an alternate formula that gives smoother curves for some joins than the standard blob formula. Perpendicular planes yield a cylindrical blob with this formula, making it useful in conjunction with the cylinder, sphere, and torus primitives.
Value
:
Blob
:
RE_fn_Blob2()
of all base functions.
RE_fn_Blob2()
always returns a non-negative number, so it is not necessary to check for a negative square root operand unless you are using a negative blob component.
Warning: It has come to my attention that a negative square root operand, in the context of an isosurface, does not raise an exception. If you use a negative blob component without checking that the sum is non-negative, the isosurface can fail silently, without halting the render.
Example:
isosurface { function { 1 - sqrt ( RE_fn_Blob2 (abs(x) + abs(z) - 1, 0.3) + RE_fn_Blob2 (f_sphere (0, y, z, 0.8), 0.2) ) } max_gradient 1.3 / 0.2 contained_by { box { -<2.5, 2, 1>, <2.5, 2, 1> } } }
Note: the max gradient will typically be inversely proportional to the smallest Blob
argument.
blob
primitive?
isosurface
.
RE_fn_Blob()
or RE_fn_Blob2()
instead of the isosurface blobbing methods suggested in the POV-Ray documentation?
RE_fn_Blob()
and RE_fn_Blob2()
match the curves of POV-Ray primitives, allowing primitive and isosurface blob to work together. The primitives can then model the bulk of the object, resulting in dramatically shorter rendering times.
The illustrations for RE_fn_Hole()
and RE_fn_Wheel()
demonstrate seamless joins between RE_fn_Blob2()
blobs and RE_Straight_join_x()
.
A slab with a rounded-edged hole punched through it, equivalent to
RE_Hole (-rMinor*y, rMinor*y,
∞, RMajor - rMinor, rMinor, 1)
.
It is intended for use with isosurface blobs.
RMajor
: rMinor
:
A circle of radius
R
parallel to the y-z plane, swept along the curve y = H
x2 | z = 0. Slower, but better behaved than macro RE_Parabolic_torus()
. Check the message window to determine max_gradient
.
H
: R
:
A merge of a torus and a cylinder, equivalent to
RE_Cylinder (-rMinor*y, rMinor*y, RMajor + rMinor, rMinor, 1)
.
It is intended for use with isosurface blobs.
RMajor
: rMinor
: Note: All function arguments are prefixed with “RE_P
n_
” in roundedge.inc
, in order to avoid a POV-Ray namespace scope feature. In this document, these prefixes are omitted for clarity.
Note: Functions RE_fn_Blob_surface_radius()
and RE_fn_Blob_field_radius()
were originally called RE_fn_Blob_distance()
and RE_fn_Blob_radius()
, respectively. The old names reflect the terminology in the POV-Ray Reference, but I feel the new names are more intuitive and easier to recall. The old function names still work.
Returns the surface radius of a blob component, given the field radius and field strength. The default blob threshold of 1.0 is assumed. Use this function when the exact size of a blob component needs to be known. In the illustration, the size of the opening is matched to the blob.
RField
:
Strength
:
Returns the field radius that yields a blob component of the desired surface radius. The default blob threshold of 1.0 is assumed. Use this function when the exact size of a blob component is important. In the illustration, the blob is matched seamlessly to the half-torus.
RSurface
:
Strength
:
Returns the field strength that yields a blob component of the desired surface radius. The default blob threshold of 1.0 is assumed. Use this function when the exact size of a blob component is important. In the illustration above, the blob is matched seamlessly to the half-torus.
RSurface
:
RField
:
Identifier | Type | Description | Default |
---|---|---|---|
RE_MORE |
float | Slightly greater than one, for avoiding coincident surfaces. | 1.001 |
RE_LESS |
float | Slightly less than one, for avoiding coincident surfaces. | 0.999 |
RE_ABIT |
float | Slightly greater than zero, for avoiding coincident surfaces. | 0.001 |
RE_Split_union |
Boolean | If off , then split_union off will be applied to the various rounded box and rounded cylinder unions. This can result in faster rendering when photons are used. |
off |
If the user finds the default values unsatisfactory, they may be modified prior to using the macros.
Identifier | Type | Description | Value |
---|---|---|---|
ROUNDEDGE_VERSION |
float | The RoundEdge version, in case the caller needs to know. | 1.3 |
Any identifiers in roundedge.inc
that are not documented in this manual are considered “private” or “protected,” and are subject to change or elimination in a future update.
Version | Date | Notes |
---|---|---|
1.0 | September 2, 2008 |
|
1.1 | June 8-9, 2012 (incomplete upload) |
|
1.2 | March 1, 2013 (incomplete upload) |
|
1.3 | June 15, 2013 |
|