Constructive Solid Geometry:
The 'hyperfun' Package

Paul Murrell
The University of Auckland
November 2022

Suppose we want to create a shape like this ...

One approach is to use 3D GUI software

Two problems:

  • 3D GUI software is hard to learn.
  • Code is better anyway!

The HyperFun Project

A language and interpreter for creating 3D scenes.

my_model(x[3], a[1])
{
  my_model = x[2];
}





          

  array d[3];
  array vertex[3];
  d = [5, 5, 5];
  vertex[1] = -d[1];
  vertex[2] = -d[2];
  vertex[3] = -d[3];
  cube = hfBlock(x, vertex, 2*d[1], 2*d[2], 2*d[3]);


          

  array centre[3];
  r = .8;
  centre = [2, 2, 5];
  threeA = hfSphere(x, centre, r);
  centre = [0, 0, 5];
  threeB = hfSphere(x, centre, r);
  centre = [-2, -2, 5];
  threeC = hfSphere(x, centre, r);
  three = threeA | threeB | threeC;
          

my_model(x[3], a[1]) 
{

  ...

  my_model = cube \ three
}


          

  centre = [0, 0, 0];
  trim = hfSphere(x, centre, .975*sqrt(2*d[1]*d[1]));







          

my_model(x[3], a[1]) 
{

  ...

  my_model = cube \ three \ ~trim
}


          

The HyperFun Project

  • Code-based model description
  • Function Representation of 3D shapes
  • "FRep" library of predefined shapes
  • Constructive solid geometry

Three remaining problems:

  • Bespoke HyperFun (toy) language
    => hard to write
  • C source code plus Windows-only executable
    => hard to install/run
    => hard to extend
  • The hyperfun.org web site is no longer available!
    => hard to access!

The 'hyperfun' Package

An R package interface to HyperFun

library(hyperfun)
cube <- hfBlock(dx=10, dy=10, dz=10)
r <- 0.8
three <- hfSphere(c(2, 0, -2), c(2, 0, -2), 5, r=r)
trim <- hfSphere(r=.975*sqrt(2*5^2))
dice <- cube - three - !trim
hfp(dice)

hfSphere()
  HF_24_1(x[3], a[1])
  {
    array center[3];
    center = [0, 0, 0];
    sphere = hfSphere(x, center, 1);
    HF_24_1 = sphere;
  }
hfBlock() - hfSphere()
  HF_25_1(x[3], a[1])
  {
    array vertex[3];
    vertex = [-0.5, -0.5, -0.5];
    block = hfBlock(x, vertex, 1, 1, 1);
    HF_25_1 = block;
  }
  HF_26_1(x[3], a[1])
  {
    array center[3];
    center = [0, 0, 0];
    sphere = hfSphere(x, center, 1);
    HF_26_1 = sphere;
  }
  HF_27_1(x[3], a[1])
  {
    HF_27_1 = HF_25_1(x, a) \ HF_26_1(x, a);
  }
  my_model(x[3], a[1])
  {
    my_model = HF_27_1(x, a);
  }
hfDice <- function(d) {
    cube <- hfBlock(dx=d, dy=d, dz=d)
    r <- 8/d
    three <- hfSphere(c(d/5, 0, -d/5), c(d/5, 0, -d/5), d/2, r=r)
    trim <- hfSphere(r=.975*sqrt(2*(d/2)^2))
    cube - three - !trim
}
hfp(hfDice(10))

f <- function(xyz) xyz[2]
xzPlane <- hfR(f)
hfp(xzPlane)

hfR(f)
  HF_44_1(x[3], a[1])
  {
    object = hfR(x, 3);
    HF_44_1 = object;
  }
library(mvtnorm)
f <- function(xyz) {
    xyz[2] - 10*dmvnorm(sqrt(xyz[1]^2 + xyz[3]^2)/2)
}
gaussian <- hfR(f)
hfp(gaussian)

The 'hyperfun' Package

  • R package
    => easy to access
    => easy to install/run
  • R language interface
    => easy to write
  • hfR() function
    => easy to extend
    => access to R functions

Applications

Conclusion

'hyperfun' brings together several concepts and technologies that are useful for creating 3D scenes.

  • Constructive Solid Geometry
  • Function Representation
  • Hyperfun
  • R

Resources

https://github.com/pmur002/hyperfun

Acknowledgements

The HyperFun Project
hyperfun.org (dead link)
paulbourke.net/dataformats/hyperfun/

Jack Wong extended the support for FRep library shapes in 'hyperfun' as part of his BSc Hons project.