Applying materials
For optimum performance, materials are best used at the segment level, though it is also possible to apply them to individual entities or subentities. Before using a material palette to decorate geometry, it must defined in a portfolio and the portfolio must be set as active on the segment. Portfolios inherit from parent to child segment, so a single portfolio can be shared as long as it is made active at some point in the hierarchical ancestry.
The HPS::MaterialMappingControl allows you to set materials "by index". This is a convenient way to apply many materials to a set of objects, or to reuse materials in different parts of your scene using the same palette. The alternative would be to set materials individually using HPS::MaterialKit, which is fine when you only need to apply a single material. Otherwise, you would need to keep a reference to the material and pass it between scopes in order to apply it in another part of the scene. Material palettes solve this problem because the materials contained within them are accessible through a portfolio.
Applying materials at various levels
Although setting materials at the segment level is the recommended way to apply materials for highest performance, you may find you need finer control over how they are applied. This section discusses how materials are applied at various levels of granularity.
Assigning materials at the segment level
Assigning a material to a segment is similar to setting a simple color on a segment: all geometry within the segment and its subsegments will also inherit the material. To assign a material this way, you need to use a material palette. Material palettes are like an array in that the materials within are indexed by insertion position. To assign a material at the segment level, use one of the Set*MaterialByIndex variants:
If you only want to set a simple color on a segment without bothering to set up a HPS::MaterialKit, Visualize offers a simplified interface to achieve this. A segment-level color means that all geometry in a particular segment will have that color. Faces, edges, and vertices can be colored in this way. Using the HPS::MaterialMappingControl, you can set segment-level color with the following code:
Assigning materials at the geometry level
Materials can be set for individual geometry if the geometry is a shell or mesh. Setting a material on a particular shell or mesh requires using a HPS::MaterialMappingKit. You can set any material property on a HPS::MaterialMappingKit, but for this example, we'll keep it simple and just set color. To do this, build a kit and apply it to the particular shell key that you want to be different:
Setting material at the geometry level does incur a performance penalty relative to setting materials at the segment level.
Assigning materials to individual faces and vertices
If you need even finer control over materials, Visualize also allows you to apply them at the subentity level. To do this, you'll need two arrays: one that defines the indices of the faces you'd like to color and another array that indexes the material palette itself. In the following snippet, materials 0, 1, and 2 are applied to shell faces 0, 1, and 2 respectively:
Setting materials on individual edges is not supported.
Examples showing how to color specific faces
Often, it is desirable to color a specific face to distinguish it from other faces in the same object. Faces on a shell can be individually colored, however, as mentioned previously, individual faces of cylinders and spheres cannot. Consider the shell pictured below, which is composed of five faces:
Now, assume the fourth face needs to be highlighted. Using the shell key, Visualize only needs the face number and the color that is desired. In the code below, note that the fourth face is being altered using the parameter '3'. This is because shell face lists are always zero-based.
Proceeding with this example, it is becomes relatively simple to assign arbitrary colors to arbitrary faces. Use the alternative version of SetFaceColors that accepts a face index array and a color array.
It is also possible to set color on a range of faces. For instance, to change color on the first three faces, call SetFaceColors with the start face index and the number of faces to color.
NOTE: To set face colors that are partially or fully transparent, the use of a material palette is required. See the discussion on this topic here.
Example showing how to color vertices
Color can be applied to individual vertices in a shell or mesh. There are many ways to do this using any of the SetVertexColors overloads. In the example below, the color of the first four vertices of the shell have been modified, as specified in the vertexIndices array. The vertexIndices array contains the specified colors. The vertex color will override any color set on the face at a higher level.
Using textures as materials
Textures are used as materials in the same way that HPS::RGBAColor-defined materials are. Load and define the texture as discussed on this page. Once the texture is loaded and named, use the name to define the material. After you have the name, the process is as simple as assigning it to a material:
Note that when texturing faces, you are still required to apply the texture coordinates to the vertices as if you were texturing a whole shell. In Visualize, there is no way to programmatically apply an alpha value to a texture. If your texture requires alpha transparency, it must be baked in to the texture itself. Fractional material index values are not supported for textures.
Interpolating materials
Note that the materialIndices array above is a float array. Using a float array enables colors to be interpolated across faces. For example, if you have two materials defined and a strip of shell faces, you can use the array to specify a fractional color for the intermediate faces. Here, red and yellow are used to form a color strip: