Facet Object


Introduction

The Facet object is a powerful object designed to display faceted surface data. Data can be provided as triangles, quadrilaterals or polygons. Faceted surfaces differ from mesh surfaces in their use of surface normals, and the manner in which they accept colors. Where a mesh surface has a surface normal defined at each vertex, a facet has a normal defined for each face (polygon). This produces distinct facets on the surface. If a mesh surface is given a multi colored material, a color is defined for each vertex. A facet will have a color defined for each face. A facet object is very useful for displaying surfaces that are not smooth, or data represented as cells. A facet object can be created using function
XintView3DCreateFacet.

Figure 10: Cellular data example using a Facet object.


Example

The example below creates a Facet object. Notice that the multi color material that is created has the number of colors based upon the number of facets, not the number of vertices.

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <Xint/View3D.h>

static int GetColor(XintColor4 color) {
	do {
		color[0] = drand48();
		color[1] = drand48();
		color[2] = drand48();
		color[3] = 1.0;
	} while((color[0] + color[1] + color[2]) < 1.3);
}
main(int argc, char **argv) {
	XtAppContext	app_context;
	Widget	toplevel;
	Widget	view;
	XintView3DMaterialAttributes	ma;
	int	i, ii, index;
	int	rows, cols;
	int	num_verts;
	float	x, y, z;
	unsigned int	flags;
	unsigned int	bitmask;
	XintVector3	*verts;
	int	num_indices[1];
	int	**indices;
	int	num_facets;
	XintView3DMaterialColor	color;
	XintView3DMaterial	*material;
	XintView3DObject	*cell;
	static String fallback_resources[] = {
		"*title:Cell Demo",
		"cell*background:#cdc0af",
		"cell*foreground:#104e8b",
		NULL
	};
  
	/* Initialize the application */
	toplevel = XtVaAppInitialize(&app_context, "cell", NULL, 0, &argc, 
		argv, fallback_resources, NULL);
  
	/* Create a viewer */
	view = XtVaCreateWidget("Viewer", xintView3DWidgetClass, toplevel,
		XmNwidth, 500, XmNheight, 500,
		XmNtopAttachment, XmATTACH_FORM,
		XmNleftAttachment, XmATTACH_FORM,
		XmNrightAttachment, XmATTACH_FORM,
		XmNbottomAttachment, XmATTACH_FORM,
		XmNxUnit, "meters", XmNyUnit, "meters",
		XmNzUnit, "meters", XmNaxisOn, False, NULL);

	/* Manage and realize all widgets */
	XtManageChild(view);
	XtRealizeWidget(toplevel);

	/* Create the cellular surface */
	rows = 31;
	cols = 25;
	verts = (XintVector3 *)malloc(rows * cols * sizeof(XintVector3));
	for(index=0, y=0.0, x=0.0, i=0; i<cols; ++i, x+=10.0) {
		for(z=0.0, ii=0; ii<rows; ++ii, z += (6.0 - (drand48() * 4))) {
		    verts[index][0] = x;
		    verts[index][1] = y;
		    verts[index][2] = z;
		    ++index;
		}
	}
	num_verts = index;
	num_facets = (rows-1) * (cols-1);
	num_indices[0] = num_facets * 4;
	indices = (int **)malloc(1 * sizeof(int *));
	indices[0] = (int *)malloc(num_indices[0] * sizeof(int));
	for(index=0, i=0; i<cols-1); ++i) {
		for(ii=0; ii<rows-1); ++ii) {
		    indices[0][index++] = i*(rows) + ii;
		    indices[0][index++] = i*(rows) + ii + 1;
		    indices[0][index++] = (i+1)*(rows) + ii + 1;
		    indices[0][index++] = (i+1)*(rows) + ii;
		}
	}

	cell = XintView3DCreateFacet("Cells", XintOBJECT_FACET_QUADS, 
			num_verts, verts, NULL, num_facets,
			num_indices, indices, False, NULL,
			NULL);

	/* Cellular material */
	color.multi.num_colors = num_facets;
	color.multi.colors = (XintColor4 *)malloc(num_facets * 
		sizeof(XintColor4));

	for(i=0; i<num_facets; ++i) 
		GetColor(color.multi.colors[i]);
	ma.draw_grid = True;
	flags = XintMA_DRAW_GRID;
	material = XintView3DCreateMaterial("CellMaterial1", 
		XintMATERIAL_MULTI_COLOR, &color,
		flags, &ma);

	/* Add the surface and material */
	XintView3DAddObjectAndMaterial(view, cell, material, NULL);

	XtAppMainLoop(app_context);
}

The following is the output of the program.

Figure 11: Output of example program.

Function XintView3DCreateFacet allows the user to specify a normal for each facet on the surface, although this is not normally done. The subroutine will generate the normals automatically if they are not specified. The normal for each facet is simply the surface normal of the polygon that makes the facet.


Materials

All materials that can be applied to Mesh Surfaces can also be applied to Facets. The only difference is that the Materials for Mesh Surfaces are applied per vertex, and the Materials applied to Facets are applied per facet.