Files
-
- 3 MB
- Download
Introduction
This article is designed to give an overview of FME's 3D capabilities by leading you through an extended exercise to work with a 3D city model.
In this example, we will work with an Autodesk 3DS model of a city to add separate textures to the roofs and the walls, allowing for more realistic viewing. We will write out this model to 3D PDF for viewing.
Step-by-step Instructions
1. Read Autodesk 3ds Source Data
The Interopolis 3D model is a simple Autodesk 3DS file of a small section of a fictional downtown. Add a reader to the canvas.
- Format: Autodesk 3DS
- Dataset: interopolis.3ds
-
Parameters:
-
Move to World Coordinate System: Yes
- This will cause FME to read the .wld and .prj files and move our city model to Texas State Plane.
-
Move to World Coordinate System: Yes
The source 3DS model viewed in the FME Data Inspector.
2. Disaggregate the Single Mesh
This model has a single feature containing every building in a single mesh, we need to separate the buildings into their own features so that we can give each building an ID for our final CityGML. Add the Deaggregator transformer to break down the mesh into its aggregates.
3. Count the Buildings
We will give each building an ID number. We will need to further deaggregate our features before we can apply textures, and the ID numbers will help us put them back together later.
Using the Counter, set:
- Count: BuildingID
4. Convert Buildings from Single Mesh Surface into MultiSurface Geometries
The buildings are currently stored as a single mesh surface, and will not meet our needs, as we want to apply separate textures for roofs and walls. We can use the GeometryCoercer to convert buildings into MultiSurface geometries, which consist of several faces aggregated into a single feature.
Add a GeometryCoercer and set:
- Geometry Type: fme_composite_surface
5. Deaggregate the MultiSurfaces
Now that the buildings are comprised of multiple faces, we can disaggregate the MutliSurfaces with the Deaggregator into individual features and set different appearances for different parts of the building.
Set the following Deaggregator parameters to create individual solids from each composite solid.:
- Split Composites: Yes
- Explode Instances: Yes
This step is important for the next step so that we can filter features through the Planar port in the PlanarityFilter. For a feature to be planar, a geometry must have all its points situated on the same plane, so we need to split composites and explode instances to create these planes.
6. Separate the Roofs from the Walls
Next, we need to separate the roofs from the walls to apply separate textures to them. We can do this by using the PlanarityFilter to compute surface normals and then the TestFilter to filter out the roofs and the walls based on those surface normals.
6.1 Compute Surface Normals
Next we will expose the surface normal attribute for Z (_surfaceNormalZ) that we will need to filter for in order to differentiate the roof surfaces and the walls in the next step. Luckily this neighborhood does not have peaked roofs!
In the PlanarityFilter, select:
-
Surface Normal Output:
- Expose Surface Normal: Yes.
6.2 Filter out the Roofs and the Walls
Next in the TestFilter transformer, we will use the surface normals to determine whether the face is a wall or a roof. Generally, a wall should have a _surfaceNormalZ of 0, a roof should have a _surfaceNormalZ of 1, and the ground, a _surfaceNormalZ of -1. However, since we don’t have a base surface for the buildings (they are like open upside-down boxes), we want everything that is not a wall to be the roof. So we will use the parameters in the table below:
| Test Condition | Output Port | |
| If | _surfaceNormalZ > 1e-5 _surfaceNormalZ < -1e-5 |
Roof |
| Else | <All Other Conditions> | Wall |
When entering in the test conditions, for the Left Value, you can use the down arrow, and select the Attribute Value: ‘_surfaceNormalZ’.
The test conditions for the Output Port: Roof.
7. Add Two Textures Using Two JPEG Files
7.1 Add a JPEG file for the roofs:
Now we need to bring the textures into the workspace. Select one of the three roof textures as your source dataset and add the first JPEG reader to your workspace.
7.2 Add a JPEG file for the walls:
For the second JPEG reader, we want to bring in wall textures. Pick one of the three images for wall textures in the source data.
8. Add the Textures to the Walls and the Roofs
We will use two AppearanceSetters to add an appearance, or raster texture, to the roofs and to the walls respectively.
Connect the Roof texture, the JPEG roof feature type, to the APPEARANCE port of the AppearanceSetter, and the ROOF port from the TestFilter to the GEOMETRY port of the AppearanceSetter. In other words, the AppearanceSetter for the roof is informed by the geometry of the roof, and the appearance of the roof texture.
Do the same thing for the walls. Connect the JPEG wall feature type to the Appearance port, and the Wall port of the TestFilter to the Geometry port of the AppearanceSetter.
Adding textures to the roofs and the walls should look something like this.
9. Aggregate the Features
Now that we have applied the appearances to each surface, we want to merge the surfaces together so that we have a single feature per building again.
With the Aggregator transformer, set:
-
Group Processing: Enabled
- Group By: BuildingID
10. Set the Geometry Type to Composite Surface for Faster Processing
After grouping the faces back together, we now have multi-surface geometry. This geometry type is easy to work with in FME because it can be broken down into individual faces, but before writing to 3D formats, we want each building to be treated as a single, complete 3D object, to improve efficiency.
Using the GeometryCoercer, set:
- Geometry Type: fme_composite_surface
This step ensures each building is recognized as a single, complete 3D object when written out, rather than processing each surface separately.
11. Write Out to 3D PDF
Add the 3D PDF reader and set the output location and file name, then run the translation. If you wish to run the translation more than once, remember to close your PDF output between runs.
Completed Workspace
Results
Congratulations! You have successfully converted a 3DS city model of Interopolis, added a separate roof and wall textures, and written out a 3D PDF.
Here is one possible output, using roof texture 1, and wall texture 1 in 3D PDF.
Here is a close up of a different wall texture (texture 3) in 3D PDF.
Data Attribution
Data used in this article originates from open data made available by the City of Austin, Texas. It contains data licensed under the Public Domain Dedication License - City of Austin.