Work with 3D attributes
Learn how to filter 3D nodes with 3D attributes associated with a 3D object scene layer. 3D attributes are not supported in the Details Panel UI workflow or through Blueprints. The C++ API will be required to use this feature. In this tutorial you'll use the New York building layer and learn:
- How to identify which attributes you want to use in your data
- How to process and give this data to a material
- How to configure the material to use the attribute data to create an interesting visualization of your data
Prerequisites
Before starting this tutorial, you should:
Follow the Add layers C++ API tutorial and have the New York building layer added in your level.
Steps
Select attributes
Before you begin to write code, you need to know the attribute types you plan to use. By default, materials and the shaders that render them only support float and integer types in Unreal Engine. If you want to use an attribute of a different type, such as strings, you will need to convert these attributes into data that can be processed by the shader.
To learn more about Unreal Engine's materials, visit Unreal Engine's documentation.
Navigate to the layer's service URL and examine the field info to identify which attributes the
ArcGIS3DModel
supports.Layer Use dark colors for code blocks Copy In this tutorial, you will use attributes named "CNSTRCT_YR" or "NAME". Find both names after
"fields":[
and see what type of fields are used for those attributes.- "CNSTRCT_YR":
"esri
Field Type Integer" - "NAME":
"esri
Field Type String"
- "CNSTRCT_YR":
Prepare header file and C++ file
Once you know the type of attributes that you will work with, include the necessary headers in .h and .cpp file and prepare for working with two different kinds of attribute types and the editor mode.
Open the API code we created in Add layers C++ API tutorial.
Open your .h file and add the following line.
Use dark colors for code blocks Copy Create an enum
Attribute
Type Use dark colors for code blocks Copy Create the method that will apply the material depending on the "CNSTRCT_YR" and "NAME" data. In this tutorial, you will apply different colors to buildings depending on their built year before or after the year 2000 and materials to some specific buildings.
Use dark colors for code blocks Copy And add the following to enable editor to respond to property changes.
Use dark colors for code blocks Copy Open your .cpp file and add necessary headers to work with 3D attributes.
Use dark colors for code blocks Copy Add the following lines to update ArcGIS Map in the editor Viewport when you select the attribute type.
Use dark colors for code blocks Copy Call
Setup3DAttributes
inCreate
.A r c GISMap() Use dark colors for code blocks Copy
Pass the attribute data to the materials
Depending on which attributes are going to be visualized, the next step is to pass those attributes and their values to the material being used by the layer.
With float, integer and double typed attributes
When setting an attribute that is either a float or an integer you can simply use these lines of code. Doubles can also be passed directly to the shader. However internally they are being converted to a float so expect some loss of precision.
When "CNSTRCT_YR" is the name of the attribute you want to visualize, this code will publish the "CNSTRCT_YR" data for each object in the layer to the material rendering that layer.
In your .cpp file, create the function.
Use dark colors for code blocks Copy In this function, use the following code. When "CNSTRCT_YR" is the name of the attribute you want to visualize, this code will publish the "CNSTRCT_YR" data for each object in the layer to the material rendering that layer.
Use dark colors for code blocks Copy Call
Setup3DAttributes
when attribute type is year.Float A n d Integer Type(Layer) Use dark colors for code blocks Copy
With other typed attributes
The use of the "NAME" attribute poses an issue with how materials work. GPUs generally do not support strings and other non-numeric data types. To use attributes with other types, you need to use the Attribute
callback to convert these types into meaningful integer or floating point values that are compatible with the material.
For example, if you want to highlight the Empire State building, you can pass a float to the material that is equal to 1.0f
when the "NAME" equals "Empire State building" and 0.0f
when it does not. You have the freedom to do this however you see fit in the Attribute
.
In your .h file, create a pointer for the
Attribute
and set it to private.Processor Use dark colors for code blocks Copy Forward declare the
Attribute
andProcessor Attribute
class.Use dark colors for code blocks Copy In your .cpp file, add the necessary header for the
Attribute
.Processor Use dark colors for code blocks Copy Create a function to apply new material to filtered scene nodes.
Use dark colors for code blocks Copy Call
Setup3DAttributes
when attribute type is building name.Other Type(Layer) Use dark colors for code blocks Copy In
Setup3DAttributes
,"NAME" is the name of the attribute you want to visualize. Its attribute type isOther Type esri
, so you will need to configure the AttributeProcessor to pass usable and meaningful values to the material.Field Type String Use dark colors for code blocks Copy The attribute description is the buffer that is output to the material. Make
I
to output either as Building Of Interest 0
or a1
depending on if the buildings NAME is a name of interest.Use dark colors for code blocks Copy Create a function for
For
to take care of converting the attribute buffer into a readable string value.Each String Use dark colors for code blocks Copy Register specific building "NAME" value for
I
.s Building Of Interest Use dark colors for code blocks Copy
Set the material for filtered nodes
You will need to tell the layer which material you are using to render with. This material will later be configured to use the attributes you specified to control how the layer is rendered.
If
Construction
is the name of the material, inYear Renderer.Construction Year Renderer Setup3DAttributes
, use the following lines of code to set theFloat A n d Integer Type Material
in the function to apply new material to filtered scene nodes.Reference Use dark colors for code blocks Copy If
Building
is the name of the material, inName Renderer.Building Name Renderer Setup3DAttributes
, use the following lines of code to set theOther Type Material
.Reference Use dark colors for code blocks Copy
Configure the material to use the attribute data
Now that the material has access to the attribute data from the previous section, you can configure the material to use the attribute data to render the layer accordingly. There are some helper functions provided in the SDK that allow you to easily access the attribute data according to the data's type in the shader. These helper functions, Read
, Read
and Read
output the value of the attribute. Which one you use depends on the type of data being exposed in the shader.
With float, integer and double typed attributes
You can use the attribute processor to convert custom data types into a suitable format that can be read by the GPU. If you don't use the attribute processor to convert data, you can use Read
, Read
or Read
depending on the data. For example, the "CNSTRCT_YR" attribute is an esri
type and doesn't have a negative value, so you should use the Read
helper function to read the data.
Field type | Helper function (without attribute processor) |
---|---|
esriFieldTypeDate | Not supported |
esriFieldTypeDouble | ReadFeatureFloatAttribute |
esriFieldTypeGlobalID | Not supported |
esriFieldTypeGUID | Not supported |
esriFieldTypeInteger | ReadFeatureUnsignedIntegerAttribute, ReadFeatureIntegerAttribute |
esriFieldTypeOID | ReadFeatureUnsignedIntegerAttribute, ReadFeatureIntegerAttribute |
esriFieldTypeSingle | ReadFeatureFloatAttribute |
esriFieldTypeSmallInteger | ReadFeatureUnsignedIntegerAttribute, ReadFeatureIntegerAttribute |
esriFieldTypeString | Not supported |
Construction
is the material that will reference the attribute textures. This material will consume the attribute data and allow you to render different features within the layer according to their individual attribute data.
In the Construction
you need to first get the CNSTRCT_
texture from the layer. Using the CNSTRCT_
value as an input to the shown If
statement, you can render buildings built after the year 2000 in light blue and buildings built before it in yellow.
Here is the result of the work. You can see a majority of the buildings in New York City are built prior to the year 2000 but you can also see a collection of new ones as well.
With other typed attributes (strings, dates, etc...)
You can convert the data to Float32
or Int32
with the attribute processor. Depending on data type, you should use either Read
or Read
helper function. You can also use the attribute processor with float, integer, and double type attributes if you want to process the original data.
In this tutorial, you used "NAME" attribute data to make the "IsBuildingOfInterest" condition output either a 0
or a 1
in Float32
. You used the Read
because the string attribute was converted and exposed to the shader as a float.
Here is the finished product. You can also see in the code a tiled texture was used so that the Empire State Building appeared to have windows.