Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add WmsRasterOverlay support and UI #670

Merged
merged 11 commits into from
Feb 12, 2024
16 changes: 16 additions & 0 deletions exts/cesium.omniverse/cesium/omniverse/ui/add_menu_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Tileset as CesiumTileset,
PolygonRasterOverlay as CesiumPolygonRasterOverlay,
IonRasterOverlay as CesiumIonRasterOverlay,
WebMapServiceRasterOverlay as CesiumWebMapServiceRasterOverlay,
)
from ..usdUtils import add_globe_anchor_to_prim
from ..bindings import ICesiumOmniverseInterface
Expand Down Expand Up @@ -40,6 +41,11 @@ def __init__(self, cesium_omniverse_interface: ICesiumOmniverseInterface):
show_fn=partial(self._show_add_raster_overlay, context_menu=context_menu, usd_type=CesiumTileset),
onclick_fn=self._add_polygon_raster_overlay,
),
PrimPathWidget.add_button_menu_entry(
"Cesium/Web Map Service Raster Overlay",
show_fn=partial(self._show_add_raster_overlay, context_menu=context_menu, usd_type=CesiumTileset),
onclick_fn=self._add_web_map_service_raster_overlay,
),
]

def destroy(self):
Expand Down Expand Up @@ -72,6 +78,16 @@ def _add_polygon_raster_overlay(self, payload: PrimSelectionPayload):
tileset_prim.GetRasterOverlayBindingRel().AddTarget(polygon_raster_overlay_path)
get_property_window().request_rebuild()

def _add_web_map_service_raster_overlay(self, payload: PrimSelectionPayload):
stage = omni.usd.get_context().get_stage()
for path in payload:
child_path = Sdf.Path(path).AppendPath("web_map_service_raster_overlay")
raster_overlay_path: str = omni.usd.get_stage_next_free_path(stage, child_path, False)
CesiumWebMapServiceRasterOverlay.Define(stage, raster_overlay_path)
tileset_prim = CesiumTileset.Get(stage, path)
tileset_prim.GetRasterOverlayBindingRel().AddTarget(raster_overlay_path)
get_property_window().request_rebuild()

@staticmethod
def _show_add_globe_anchor(objects: dict, context_menu: omni.kit.context_menu, usd_type: Tf.Type) -> bool:
return context_menu.prim_is_type(objects, type=usd_type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@
from .ion_server_attributes_widget import CesiumIonServerAttributesWidget # noqa: F401
from .ion_raster_overlay_attributes_widget import CesiumIonRasterOverlayAttributesWidget # noqa: F401
from .polygon_raster_overlay_attributes_widget import CesiumPolygonRasterOverlayAttributesWidget # noqa: F401
from .web_map_service_raster_overlay_attributes_widget import ( # noqa: F401
CesiumWebMapServiceRasterOverlayAttributesWidget,
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
from typing import List
import omni.ui as ui
from pxr import Sdf
from functools import partial


def update_range(stage, prim_paths, constrain, attr_name):
min_val = max_val = None

for path in prim_paths:
prim = stage.GetPrimAtPath(path)
attr = prim.GetAttribute(constrain["attr"]) if prim else None
if prim and attr:
if constrain["type"] == "minimum":
min_val = attr.Get()
else:
max_val = attr.Get()
break

for path in prim_paths:
prim = stage.GetPrimAtPath(path)
attr = prim.GetAttribute(attr_name) if prim else None
if prim and attr:
val = attr.Get()
if min_val:
val = max(min_val, val)
elif max_val:
val = min(max_val, val)
attr.Set(val)
break


def _build_slider(
Expand All @@ -9,6 +36,7 @@ def _build_slider(
metadata,
property_type,
prim_paths: List[Sdf.Path],
type="float",
additional_label_kwargs={},
additional_widget_kwargs={},
):
Expand All @@ -35,23 +63,45 @@ def _build_slider(
if additional_widget_kwargs:
widget_kwargs.update(additional_widget_kwargs)
with ui.ZStack():
value_widget = UsdPropertiesWidgetBuilder.create_drag_or_slider(
ui.FloatDrag, ui.FloatSlider, **widget_kwargs
)
if type == "float":
value_widget = UsdPropertiesWidgetBuilder.create_drag_or_slider(
ui.FloatDrag, ui.FloatSlider, **widget_kwargs
)
else:
value_widget = UsdPropertiesWidgetBuilder.create_drag_or_slider(
ui.IntDrag, ui.IntSlider, **widget_kwargs
)
mixed_overlay = UsdPropertiesWidgetBuilder.create_mixed_text_overlay()
UsdPropertiesWidgetBuilder.create_control_state(
value_widget=value_widget, mixed_overlay=mixed_overlay, **widget_kwargs
)

if len(additional_widget_kwargs["constrain"]) == 2:
callback = partial(update_range, stage, prim_paths, additional_widget_kwargs["constrain"], attr_name)
model.add_value_changed_fn(lambda m: callback())
return model


def build_slider(min_value, max_value):
def build_slider(min_value, max_value, type="float", constrain={}):
if type not in ["int", "float"]:
raise ValueError("'type' must be 'int' or 'float'")

if len(constrain) not in [0, 2]:
raise ValueError("'constrain' must be empty or a {'attr': ___, 'type': ___} dictionary")
if constrain[1] not in ["minimum", "maximum"]:
raise ValueError("constrain['type'] must be 'minimum' or 'maximum'")

def custom_slider(stage, attr_name, metadata, property_type, prim_paths, *args, **kwargs):
additional_widget_kwargs = {"min": min_value, "max": max_value}
additional_widget_kwargs = {"min": min_value, "max": max_value, "constrain": constrain}
additional_widget_kwargs.update(kwargs)
return _build_slider(
stage, attr_name, metadata, property_type, prim_paths, additional_widget_kwargs=additional_widget_kwargs
stage,
attr_name,
metadata,
property_type,
prim_paths,
additional_widget_kwargs=additional_widget_kwargs,
type=type,
)

return custom_slider
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import logging
from omni.kit.property.usd.custom_layout_helper import CustomLayoutFrame, CustomLayoutGroup, CustomLayoutProperty
from omni.kit.property.usd.usd_property_widget import SchemaPropertiesWidget
from cesium.usd.plugins.CesiumUsdSchemas import (
WebMapServiceRasterOverlay as CesiumWebMapServiceRasterOverlay,
)
from .custom_attribute_widgets import build_slider


class CesiumWebMapServiceRasterOverlayAttributesWidget(SchemaPropertiesWidget):
def __init__(self):
super().__init__(
"Cesium Web Map Service Raster Overlay Settings", CesiumWebMapServiceRasterOverlay, include_inherited=True
)

self._logger = logging.getLogger(__name__)

def clean(self):
super().clean()

def _customize_props_layout(self, props):
frame = CustomLayoutFrame(hide_extra=True)

with frame:
with CustomLayoutGroup("Base URL"):
CustomLayoutProperty("cesium:baseUrl")
with CustomLayoutGroup("Layers"):
CustomLayoutProperty("cesium:layers")
with CustomLayoutGroup("Tile Size"):
CustomLayoutProperty("cesium:tileWidth", build_fn=build_slider(64, 2048, type="int"))
CustomLayoutProperty("cesium:tileHeight", build_fn=build_slider(64, 2048, type="int"))
with CustomLayoutGroup("Zoom Settings"):
CustomLayoutProperty(
"cesium:minimumLevel",
build_fn=build_slider(
0, 30, type="int", constrain={"attr": "cesium:maximumLevel", "type": "maximum"}
),
)
CustomLayoutProperty(
"cesium:maximumLevel",
build_fn=build_slider(
0, 30, type="int", constrain={"attr": "cesium:minimumLevel", "type": "minimum"}
),
)
with CustomLayoutGroup("Rendering"):
CustomLayoutProperty("cesium:alpha", build_fn=build_slider(0, 1))
CustomLayoutProperty("cesium:overlayRenderMethod")
with CustomLayoutGroup("Credit Display"):
CustomLayoutProperty("cesium:showCreditsOnScreen")

return frame.apply(props)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
CesiumIonServerAttributesWidget,
CesiumIonRasterOverlayAttributesWidget,
CesiumPolygonRasterOverlayAttributesWidget,
CesiumWebMapServiceRasterOverlayAttributesWidget,
)
from ..bindings import ICesiumOmniverseInterface

Expand All @@ -29,6 +30,7 @@ def __init__(self, _cesium_omniverse_interface: ICesiumOmniverseInterface):
self._register_ion_server_attributes_widget()
self._register_ion_raster_overlay_attributes_widget()
self._register_polygon_raster_overlay_attributes_widget()
self._register_web_map_service_raster_overlay_attributes_widget()

def destroy(self):
self._unregister_data_attributes_widget()
Expand All @@ -38,6 +40,7 @@ def destroy(self):
self._unregister_ion_server_attributes_widget()
self._unregister_ion_raster_overlay_attributes_widget()
self._unregister_polygon_raster_overlay_attributes_widget()
self._unregister_web_map_service_raster_overlay_attributes_widget()

@staticmethod
def _register_data_attributes_widget():
Expand Down Expand Up @@ -100,6 +103,20 @@ def _unregister_polygon_raster_overlay_attributes_widget():
if window is not None:
window.unregister_widget("prim", "cesiumPolygonRasterOverlay")

@staticmethod
def _register_web_map_service_raster_overlay_attributes_widget():
window = omni.kit.window.property.get_window()
if window is not None:
window.register_widget(
"prim", "cesiumWebMapServiceRasterOverlay", CesiumWebMapServiceRasterOverlayAttributesWidget()
)

@staticmethod
def _unregister_web_map_service_raster_overlay_attributes_widget():
window = omni.kit.window.property.get_window()
if window is not None:
window.unregister_widget("prim", "cesiumWebMapServiceRasterOverlay")

def _register_global_anchor_attributes_widget(self):
window = omni.kit.window.property.get_window()
if window is not None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,20 @@ class PolygonRasterOverlay(RasterOverlay):
@classmethod
def CreateCartographicPolygonBindingRel(cls, *args, **kwargs) -> Any: ...
@classmethod
def CreateCesiumOverlayRenderMethodAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def CreateInvertSelectionAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def Define(cls, *args, **kwargs) -> Any: ...
@classmethod
def Get(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetCartographicPolygonBindingRel(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetCesiumOverlayRenderMethodAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetInvertSelectionAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetSchemaAttributeNames(cls, *args, **kwargs) -> Any: ...
@classmethod
def _GetStaticTfType(cls, *args, **kwargs) -> Any: ...
Expand Down Expand Up @@ -417,6 +425,8 @@ class Tokens(Boost.Python.instance):
@property
def cesiumAnchorPosition(self) -> Any: ...
@property
def cesiumBaseUrl(self) -> Any: ...
@property
def cesiumCartographicPolygonBinding(self) -> Any: ...
@property
def cesiumCulledScreenSpaceError(self) -> Any: ...
Expand Down Expand Up @@ -461,6 +471,10 @@ class Tokens(Boost.Python.instance):
@property
def cesiumGeoreferenceOriginLongitude(self) -> Any: ...
@property
def cesiumHeight(self) -> Any: ...
@property
def cesiumInvertSelection(self) -> Any: ...
@property
def cesiumIonAccessToken(self) -> Any: ...
@property
def cesiumIonAssetId(self) -> Any: ...
Expand All @@ -473,16 +487,22 @@ class Tokens(Boost.Python.instance):
@property
def cesiumIonServerUrl(self) -> Any: ...
@property
def cesiumLayers(self) -> Any: ...
@property
def cesiumLoadingDescendantLimit(self) -> Any: ...
@property
def cesiumMainThreadLoadingTimeLimit(self) -> Any: ...
@property
def cesiumMaximumCachedBytes(self) -> Any: ...
@property
def cesiumMaximumLevel(self) -> Any: ...
@property
def cesiumMaximumScreenSpaceError(self) -> Any: ...
@property
def cesiumMaximumSimultaneousTileLoads(self) -> Any: ...
@property
def cesiumMinimumLevel(self) -> Any: ...
@property
def cesiumOverlayRenderMethod(self) -> Any: ...
@property
def cesiumPreloadAncestors(self) -> Any: ...
Expand All @@ -507,6 +527,8 @@ class Tokens(Boost.Python.instance):
@property
def cesiumUrl(self) -> Any: ...
@property
def cesiumWidth(self) -> Any: ...
@property
def clip(self) -> Any: ...
@property
def ion(self) -> Any: ...
Expand All @@ -515,6 +537,47 @@ class Tokens(Boost.Python.instance):
@property
def url(self) -> Any: ...

class WebMapServiceRasterOverlay(RasterOverlay):
__instance_size__: ClassVar[int] = ...
@classmethod
def __init__(cls, *args, **kwargs) -> None: ...
@classmethod
def CreateBaseUrlAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def CreateHeightAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def CreateLayersAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def CreateMaximumLevelAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def CreateMinimumLevelAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def CreateWidthAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def Define(cls, *args, **kwargs) -> Any: ...
@classmethod
def Get(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetBaseUrlAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetHeightAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetLayersAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetMaximumLevelAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetMinimumLevelAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetSchemaAttributeNames(cls, *args, **kwargs) -> Any: ...
@classmethod
def GetWidthAttr(cls, *args, **kwargs) -> Any: ...
@classmethod
def _GetStaticTfType(cls, *args, **kwargs) -> Any: ...
@classmethod
def __bool__(cls) -> bool: ...
@classmethod
def __reduce__(cls) -> Any: ...

class _CanApplyResult(Boost.Python.instance):
__instance_size__: ClassVar[int] = ...
@classmethod
Expand Down
Loading
Loading