So heres the full blueprint:
And the necissary parts from the python script:
geom = wkb.loads(df['geom'][i], hex=True)
for index, poly in enumerate(geom.geoms):
holeList = []
for holeNum in range(shapely.get_num_interior_rings(poly)):
holeList.append(EnsureOrientation(shapely.get_coordinates(shapely.get_interior_ring(poly,holeNum)))) # Interior Rings (Holes)
latLong = EnsureOrientation(shapely.get_coordinates(shapely.get_exterior_ring(poly))) # Exterior Ring (Main Polygon)
This seperates the a Multipolygon into singular polygons, ensuring they are rotated counterclockwise for the “Append Simple Extrude Polygon” To function as expected.
polyCoords = []
for point in latLong:
polyCoords.append(unreal.Vector2D(point[0],point[1])) # Convert points to unreal vector
blueprint = EAL.load_asset('/Game/StartUpBlueprints/Test.Test')
EAL (Editor Asset Library)
This loads the blueprint we want
spawnedBlueprint = ELL.spawn_actor_from_object(blueprint, (0,0,0))
spawnedBlueprint.set_folder_path('/Temp/')
spawnedBlueprint.set_actor_label(str(int(Group)) + "_" + str(df['Identifier'][i])+"_Temp")
This spawns the blueprint in the world
spawnedBlueprint.call_method("SpawnPolygon",
tuple([polyCoords, # Lat Long Coordinates
df['height'][i]*330, # Height; Multiply Stories by 3.3m (Unreal uses centimeters)
colour[1:], # Colour; Remove Hashtag from colour
str(int(Group)) + "_" + str(df['Indetifier'][i]) + "_" + str(index), # Name; Index value included for MultiPolygons with more than one Polygon
str(int(Group))]))
This calls the Custom Event " Spawn Polygon" Within the blueprint
for hole in holeList:
holeCoords =[]
for point in hole:
holeCoords.append(unreal.Vector2D(point[0],point[1])) # Convert points to unreal vector
spawnedBlueprint.call_method("Add Hole",tuple([holeCoords]))
This calls the custom event “Add Hole” within the blueprint
spawnedBlueprint.call_method("FindZ")
This calls the custom event “FindZ” withing the blueprint
To take you through the blueprint:
When the blueprint is created “Set Tileset” is called to find the Cesium World Terrain from within the construction script
Then Spawn Polygon is called from Python, this sets all the input variables, goes through each point in the polygon and converts the points from Lat Long to Unreal. Once the points have been converted a Generated Dynamic Mesh actor is spawned in the world, and a simple extrude polygon is appended to the actor.
Afterwards, if neccisary, “Add Hole” is called from the python script, which finds a dynamic mesh in the world, converts the Lat Long coordinates to Unreal coordinates, appends a simple extrude polygon to it, sets the simple extrude polygon as the only mesh, and then applies a mesh Boolean to the Main Extruded Polygon created during “Spawn Polygon” to create a hole within it.
Finally “Call Z” is called from python. This takes the points from the main polygon (“Spawn Polygon”), adds a Z Value to them (999999, which is the inital value of both Lowest Ground Value and Inital Lowest Ground Value) and then calls Sample Height Most detalied. On completion of Sample Height Most Detalied, it should be going through each result, breaking up the CesiumSampleHeightResult, transforming the result to Unreal Coordinates, and then checking to see if that result is lower than the Lowest ground value we already have.
From my understanding of how Sample Height Most detailed words, the input z value is ignored and if it fails that input z value is passed back out. This should result in some massive Z value when converted into unreal coordinates and not impact the Lowest Ground Value check.
Once All results have been gone through, It checks to see whether a lowest ground value has been found, and moves (transforms) the main polygon to the ground. Then it checks to see there isnt a duplicate of the polygon we are adding, if there is, it deletes the one currently saved.
The Main polygon is then turned into a Static Mesh, a material is added to it and it is saved.
There isn’t anything wrong with how the python or blueprint is working (minus the obvious), as I’ve already ran this with a line trace instead of the Sample Heights Most Detailed and everything worked in that script as intended.
Please let me know whether there is anything else you need me to explain.