[Back]
menger.c
/*
* Copyright (c) 2000, 2001 Thomas E. Burge. All rights reserved.
*
* Affine (R) is a registered trademark of Thomas E. Burge
*
* THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT WARRANTY OF ANY KIND
* AND WITHOUT ANY GUARANTEE OF MERCHANTABILITY OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
* In no event shall Thomas E. Burge be liable for any indirect or
* consequential damages or loss of data resulting from use or performance
* of this software.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the following copyright notices and this permission notice appear in
* all copies of the software and related documentation:
*
* The Affine (R) Libraries and Tools are
* Copyright (c) 1995-2001 Thomas E. Burge.
* All rights reserved.
* Affine (R) is a registered trademark of Thomas E. Burge.
*
* Also refer to any additional requirements presently set by Pixar
* in regards to the RenderMan (R) Interface Procedures and Protocol.
*
*
* Affine Menger Fractal Tool
*
* FILE: menger.c
*
* DESCRIPTION: Example procedural DSO for PRMan 3.8.
*
* Contains:
*
* History:
* 4-9-01 Added _WIN32 tags and missing init of lod variable. [CBONE01]
*
* References:
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ri.h>
#define ADD_COLOR
#define ADD_STATS
typedef struct _DSO_BOUND {
RtFloat xmin, xmax, ymin, ymax, zmin, zmax;
} DSO_BOUND;
typedef DSO_BOUND *PDSO_BOUND;
typedef struct _DSO_PATCH {
RtFloat x0, y0, z0;
RtFloat x1, y1, z1;
RtFloat x2, y2, z2;
RtFloat x3, y3, z3;
} DSO_PATCH;
typedef DSO_PATCH *PDSO_PATCH;
typedef struct _DSO_PROCPRIM {
RtInt lod;
RtInt remaininglevels;
DSO_BOUND bound;
} DSO_PROCPRIM;
typedef DSO_PROCPRIM *PDSO_PROCPRIM;
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#ifdef _WIN32
#define EXTERN extern _declspec(dllexport)
#else
#define EXTERN extern
#endif
EXTERN RtPointer ConvertParameters(RtString paramstr);
EXTERN RtVoid Subdivide(RtPointer data, RtFloat detail);
EXTERN RtVoid Free(RtPointer data);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
/* Do note that these global values should be moved into an instanced
* structure so that the DSO can be used for more than one object.
*/
#ifdef ADD_COLOR
DSO_BOUND maxbounds;
#endif
#ifdef ADD_STATS
int allocated = 0;
int last = 0;
int line = 0;
int max = 0;
#endif
RtVoid Child( PDSO_PROCPRIM p, int x, int y, int z )
{
PDSO_PROCPRIM data;
DSO_BOUND bound; /* note bound does not need to be malloced. */
RtFloat xl,yl,zl;
data = (PDSO_PROCPRIM)malloc( sizeof( DSO_PROCPRIM) );
if ( !data )
return;
#ifdef ADD_STATS
allocated++;
if ( allocated / 1000 != last )
{
if ( allocated>max)
max = allocated;
printf("%d ",allocated);
last = allocated / 1000;
if ( line++ > 10 )
{
line = 0;
printf("-- %d\n",max);
}
}
#endif
bound = p->bound;
xl = (bound.xmax - bound.xmin)/3;
yl = (bound.ymax - bound.ymin)/3;
zl = (bound.zmax - bound.zmin)/3;
bound.xmin += xl * x;
bound.ymin += yl * y;
bound.zmin += zl * z;
bound.xmax = bound.xmin + xl;
bound.ymax = bound.ymin + yl;
bound.zmax = bound.zmin + zl;
data->remaininglevels = p->remaininglevels - 1;
data->bound = bound;
data->lod = 1;
RiProcedural( (RtPointer)data, (RtFloat*)&bound, Subdivide, Free );
}
RtVoid Subdivide( RtPointer data, RtFloat levelofdetail )
{
PDSO_PROCPRIM p = (PDSO_PROCPRIM)data;
if ( !p )
return;
/* Note that PRMan sets levelofdetail to only integer values and
* stops decreasing the size once it gets down to 4.0, so it is
* never less than 4.0.
*
* Testing it a bit more this does actually appear to be true, so as
* a work around add a lod field to the DSO_PROCPRIM structure
* as a counter from when levelofdetail equaled 4.0.
*/
#if 0
if (levelofdetail<4.0)
printf("lod: %g @ %d\n",levelofdetail, p->remaininglevels);
#endif
if ( levelofdetail <= 4.0 )
p->lod--;
if ( p->remaininglevels && p->lod )
{
Child( p, 0, 0, 0 );
Child( p, 1, 0, 0 );
Child( p, 2, 0, 0 );
Child( p, 0, 1, 0 );
Child( p, 2, 1, 0 );
Child( p, 0, 2, 0 );
Child( p, 1, 2, 0 );
Child( p, 2, 2, 0 );
Child( p, 0, 0, 1 );
Child( p, 2, 0, 1 );
Child( p, 0, 2, 1 );
Child( p, 2, 2, 1 );
Child( p, 0, 0, 2 );
Child( p, 1, 0, 2 );
Child( p, 2, 0, 2 );
Child( p, 0, 1, 2 );
Child( p, 2, 1, 2 );
Child( p, 0, 2, 2 );
Child( p, 1, 2, 2 );
Child( p, 2, 2, 2 );
}
else
{
#define b (p->bound)
DSO_PATCH patch;
#ifdef ADD_COLOR
RtColor color;
#endif
#ifdef ADD_COLOR
color[0] = (b.xmin - maxbounds.xmin)/(maxbounds.xmax - maxbounds.xmin);
color[1] = (b.ymin - maxbounds.ymin)/(maxbounds.ymax - maxbounds.ymin);
color[2] = (b.zmin - maxbounds.zmin)/(maxbounds.zmax - maxbounds.zmin);
RiColor( color );
#endif
/* Front */
patch.x0 = b.xmin; patch.y0 = b.ymax; patch.z0 = b.zmin;
patch.x1 = b.xmax; patch.y1 = b.ymax; patch.z1 = b.zmin;
patch.x2 = b.xmin; patch.y2 = b.ymin; patch.z2 = b.zmin;
patch.x3 = b.xmax; patch.y3 = b.ymin; patch.z3 = b.zmin;
RiPatch( "bilinear", "P", &patch, RI_NULL );
/* Left */
patch.x0 = b.xmin; patch.y0 = b.ymax; patch.z0 = b.zmax;
patch.x1 = b.xmin; patch.y1 = b.ymax; patch.z1 = b.zmin;
patch.x2 = b.xmin; patch.y2 = b.ymin; patch.z2 = b.zmax;
patch.x3 = b.xmin; patch.y3 = b.ymin; patch.z3 = b.zmin;
RiPatch( "bilinear", "P", &patch, RI_NULL );
/* Right */
patch.x0 = b.xmax; patch.y0 = b.ymax; patch.z0 = b.zmin;
patch.x1 = b.xmax; patch.y1 = b.ymax; patch.z1 = b.zmax;
patch.x2 = b.xmax; patch.y2 = b.ymin; patch.z2 = b.zmin;
patch.x3 = b.xmax; patch.y3 = b.ymin; patch.z3 = b.zmax;
RiPatch( "bilinear", "P", &patch, RI_NULL );
/* Top */
patch.x0 = b.xmin; patch.y0 = b.ymax; patch.z0 = b.zmax;
patch.x1 = b.xmax; patch.y1 = b.ymax; patch.z1 = b.zmax;
patch.x2 = b.xmin; patch.y2 = b.ymax; patch.z2 = b.zmin;
patch.x3 = b.xmax; patch.y3 = b.ymax; patch.z3 = b.zmin;
RiPatch( "bilinear", "P", &patch, RI_NULL );
/* Bottom */
patch.x0 = b.xmin; patch.y0 = b.ymin; patch.z0 = b.zmin;
patch.x1 = b.xmax; patch.y1 = b.ymin; patch.z1 = b.zmin;
patch.x2 = b.xmin; patch.y2 = b.ymin; patch.z2 = b.zmax;
patch.x3 = b.xmax; patch.y3 = b.ymin; patch.z3 = b.zmax;
RiPatch( "bilinear", "P", &patch, RI_NULL );
/* Back */
patch.x0 = b.xmax; patch.y0 = b.ymax; patch.z0 = b.zmax;
patch.x1 = b.xmin; patch.y1 = b.ymax; patch.z1 = b.zmax;
patch.x2 = b.xmax; patch.y2 = b.ymin; patch.z2 = b.zmax;
patch.x3 = b.xmin; patch.y3 = b.ymin; patch.z3 = b.zmax;
RiPatch( "bilinear", "P", &patch, RI_NULL );
}
}
RtVoid Free( RtPointer data )
{
(void)data;
if (data)
{
#ifdef ADD_STATS
allocated--;
#endif
free( data );
}
}
RtPointer ConvertParameters( RtString initialstring )
{
PDSO_PROCPRIM p;
int n;
p = (PDSO_PROCPRIM)malloc( sizeof( DSO_PROCPRIM) );
if ( !p )
return NULL;
p->lod = -1;
n = sscanf( initialstring,
"%d %g %g %g %g %g %g\n",
&(p->remaininglevels),
&(p->bound.xmin), &(p->bound.xmax),
&(p->bound.ymin), &(p->bound.ymax),
&(p->bound.zmin), &(p->bound.zmax) );
if ( n != 7 )
{
free( p );
return NULL;
}
#ifdef ADD_COLOR
maxbounds = p->bound;
#endif
#ifdef ADD_STATS
allocated = 0;
last = 0;
line = 0;
max = 0;
#endif
return (RtPointer)p;
}
Makefile.win
#
# Contrib: Chris Bone 4-9-01
# Description: Makefile for Windows provided here untested right now, except by Chris Bone.
#
menger.dll: menger.obj
link.exe prman.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /machine:I386 /out:"menger.dll" /implib:"menger.lib" /libpath:"$(RMANTREE)/lib" menger.obj
menger.obj: menger.c
.c.obj::
cl.exe /nologo /MT /W3 /GX /O2 /I "$(RMANTREE)/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c $<
Makefile.win BMRT2.6
#
# BMRT 2.6 seems to use the Unix .so naming convention.
#
menger.so: menger.obj
link.exe rendrib.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib \
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib \
odbccp32.lib /nologo /dll /incremental:no /machine:I386 /out:"menger.so" \
/implib:"menger.lib" /libpath:"$(RMANTREE)/lib" menger.obj
menger.obj: menger.c
.c.obj::
cl.exe /o menger.so /nologo /MT /W3 /GX /O2 /I "$(RMANTREE)/include" /D "WIN32" /D "NDEBUG" \
/D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c $<
Makefile
# $RCSfile$ $Revision$ $Date$
#
# Copyright (c) 2000 Thomas E. Burge. All rights reserved.
#
# Affine (R) is a registered trademark of Thomas E. Burge
#
# THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT WARRANTY OF ANY KIND
# AND WITHOUT ANY GUARANTEE OF MERCHANTABILITY OR FITNESS FOR A
# PARTICULAR PURPOSE.
#
# In no event shall Thomas E. Burge be liable for any indirect or
# consequential damages or loss of data resulting from use or performance
# of this software.
#
# Permission to use, copy, modify, distribute, and sell this software and
# its documentation for any purpose is hereby granted without fee, provided
# that the following copyright notices and this permission notice appear in
# all copies of the software and related documentation:
#
# The Affine (R) Libraries and Tools are
# Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000 Thomas E. Burge.
# All rights reserved.
# Affine (R) is a registered trademark of Thomas E. Burge.
#
# Also refer to any additional requirements presently set by Pixar
# in regards to the RenderMan (R) Interface Procedures and Protocol.
#
#
# Affine Toolkit
#
# FILE: Makefile for Unix systems. Refer to ../config.mak for
# compiler flags that may differ between flavors of Unix.
#
# PROGRAMS/LIBRARIES: cellbasis.so cellnoiseDSO.so
#
#
#
TOP=../..
#Put all the compiler and linker flags in one place:
include ${TOP}/config.mak
TARGETPATH= ../lib
INCPATHS= -I. -I${TOP}/../../bmrt/include
LIBPATHS= -L${TOP}/lib
LIBS=
HEADERS=
COPTS=
all: menger.so
clean:
-rm ./menger.so ./dsoproc.so
menger.so: menger.o Makefile
ld ${LFLAGS32} ${DSOLFLAGS} -o menger.so menger.o
config.mak.sun
CC= cc
CFLAGS= -g ${INCPATHS}
CFLAGS32=
LFLAGS32=
DSOLFLAGS=-G
COPTS=
AR= ar rc
.c.o:
${CC} -c $< ${CFLAGS} ${CFLAGS32} ${COPTS} ${INCPATH}
menger.rib
##RenderMan RIB
version 3.03
Option "statistics" "endofframe" [3]
Display "menger.tif" "framebuffer" "rgba"
#Display "menger.tif" "file" "rgba"
Format 512 512 1
Clipping 1 100
Projection "perspective" "fov" [18]
Translate 0 0 10
Rotate -15 1 0 0
Rotate 30 0 1 0
WorldBegin
LightSource "distantlight" 1 "intensity" [1] "from" [10 5 -10]
LightSource "ambientlight" 1 "intensity" [0.1]
Surface "plastic"
Procedural "DynamicLoad"
[ "menger.so" "2 -1 1 -1 1 -1 1" ]
[ -1 1 -1 1 -1 1 ]
WorldEnd
[Affine Toolkit]
[RIB Utilities]
[Bitmap Utilities]
[Handy Little Utilities]
[Libraries]
[Using the Libraries]