A renderer for projecting 3D information (e.g. apparent ridges) onto 2D and doing neccessary pre- and postprocessing to produce drawable elements ready for graphics/imaging frameworks. Uses the pinhole camera model, with camera fixed at (0,0,0) pointing toward +z.

Constructor

new(_mesh:Mesh, w:Int, h:Int)

New render

Parameters:

_mesh

the mesh to be rendered

w

width of the canvas

h

height of the canvas

Variables

@:value(false)didPrecompute:Bool = false

Were the mesh properties necessary for computing apparent ridges already computed? If false, Render.apparentRidges() will call Mesh.precompute() when itself is called for the first time, and set this flag to true. If you transformed or otherwise mutated the mesh, set this flag to false again. (Or explicitly call the mesh's computeXxxxx() methods)

@:value(1000)focal:Float = 1000

Focal length of the camera

height:Int

Height of the canvas

lines:Array<Line>

Array of generated lines for drawing

mesh:Mesh

The mesh to be rendered

polylines:Array<Polyline>

Array of generated polylines for drawing, populated by Render.buildPolylines()

width:Int

Width of the canvas

Methods

@:value({ cull : 2 })apparentRidges(thresh:Float, cull:Float = 2):Void

Plot the apparent ridges of the mesh. This calls Mesh.apparentRidges() with appropriate parameters, and is usually where the heavy computation happens. If the Render.didPrecompute flag indicates that the necessary mesh properties have not yet been computed, those will also be calculated here. Populates the Render.lines list.

Parameters:

thresh

apparent ridge threshold

cull

what to do with occluded ridges. Negative values => display hidden ridges (much faster). Non-negative => use (software) raycasting to cull hidden ridges, with the argument as a multiplier to the raycaster "tolerance" (see Mesh.visible())

@:value({ fFactor : 1.25, zFactor : 1.5 })autoPlace(zFactor:Float = 1.5, fFactor:Float = 1.25):Void

Automatically put the mesh at a nice distance and scale for viewing. Tweak the two arguments to adjust how "strong" the perspective is

Parameters:

zFactor

multiplier for z distance

fFactor

multiplier for focal length

@:value({ epsilon : 1 })buildPolylines(epsilon:Float = 1):Void

Connect line segments into continous polylines. Populates the Render.polylines list. Uses a custom (novel?) scanline-like algorithm to solve this problem (relatively) efficiently. See the source comment for details.

Parameters:

epsilon

the maximum endpoint x difference for two segments with matched endpoint y coordiante to be considered connectable

clear():Void

Clear the rendering, emptying Render.lines and Render.polylines.

edges():Void

Simply plot all edges in the mesh (e.g. for sanity checking) Edges shared by multiple faces will be repeated, since Mesh does not keep a separate list for edges. Populates the Render.lines list.

scaleRotateTranslate(sx:Float, sy:Float, sz:Float, rx:Float, ry:Float, rz:Float, dx:Float, dy:Float, dz:Float):Void

First scale the mesh, then rotate the mesh in X-Y-Z order, and finally translate the mesh. A convenient alternative to Render.transform(), covering common use cases.

Parameters:

sx

scale along the x axis

sy

scale along the y axis

sz

scale along the z axis

rx

rotation around the x axis

ry

rotation around the y axis

rz

rotation around the z axis

dx

translation along the x axis

dy

translation along the y axis

dz

translation along the z axis

See also:

setFocal(f:Float):Void

Set the focal length of the camera

Parameters:

f

focal length

setVerbose(v:Int):Void

Set verbosity level

Parameters:

v

0 => no log, 1 => log progress

transform(mat4x4:Array<Float>):Void

Transform the mesh with a custom 4x4 transformation matrix, to place it at desired a position and angle.

Parameters:

mat4x4

a flat, row-major 16 element array

See also:

vertices():Void

Simply plot all vertices in the mesh (e.g. for sanity checking) Each vertex is plotted as an "X" using two short Lines. Populates the Render.lines list.