Skip to content

Commit 068b601

Browse files
committed
Merge branch 'p_and_q' into 'main'
(GH-710) Add various wp.transform syntax operations for loading and storing See merge request omniverse/warp!1321
2 parents f940332 + 411594b commit 068b601

9 files changed

Lines changed: 1043 additions & 35 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
- Add a [publications list](https://github.com/NVIDIA/warp/blob/main/PUBLICATIONS.md) of academic and research projects
3636
leveraging Warp ([GH-686](https://github.com/NVIDIA/warp/issues/686)).
3737
- Add `wp.map()` function to map a function over arrays, add math operators for Warp arrays ([GH-694](https://github.com/NVIDIA/warp/issues/694)).
38+
- Add various `wp.transform` syntax operations for loading and storing ([GH-710](https://github.com/NVIDIA/warp/issues/710)).
3839

3940
### Removed
4041

docs/modules/functions.rst

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,15 +1496,28 @@ Quaternion Math
14961496

14971497
Transformations
14981498
---------------
1499-
.. py:function:: transformation(pos: Vector[3,Float], rot: Quaternion[Float], dtype: Float) -> Transformation[Float]
1499+
.. py:function:: transformation(p: Vector[3,Float], q: Quaternion[Float], dtype: Float) -> Transformation[Float]
15001500
15011501
.. hlist::
15021502
:columns: 8
15031503

15041504
* Kernel
15051505
* Differentiable
15061506

1507-
Construct a rigid-body transformation with translation part ``pos`` and rotation ``rot``.
1507+
Construct a rigid-body transformation with translation part ``p`` and rotation ``q``.
1508+
1509+
1510+
.. py:function:: transformation(*args: Float, dtype: Float) -> Transformation[Float]
1511+
:noindex:
1512+
:nocontentsentry:
1513+
1514+
.. hlist::
1515+
:columns: 8
1516+
1517+
* Kernel
1518+
* Differentiable
1519+
1520+
Construct a spatial transfom vector of given dtype.
15081521

15091522

15101523
.. py:function:: transform_identity(dtype: Float) -> transformf
@@ -1543,6 +1556,30 @@ Transformations
15431556
Return the rotational part of a transform ``xform``.
15441557

15451558

1559+
.. py:function:: transform_set_translation(xform: Transformation[Float], p: Vector[3,Float]) -> None
1560+
1561+
.. hlist::
1562+
:columns: 8
1563+
1564+
* Kernel
1565+
* Python
1566+
* Differentiable
1567+
1568+
Set the translational part of a transform ``xform``.
1569+
1570+
1571+
.. py:function:: transform_set_rotation(xform: Transformation[Float], q: Quaternion[Float]) -> None
1572+
1573+
.. hlist::
1574+
:columns: 8
1575+
1576+
* Kernel
1577+
* Python
1578+
* Differentiable
1579+
1580+
Set the rotational part of a transform ``xform``.
1581+
1582+
15461583
.. py:function:: transform_multiply(a: Transformation[Float], b: Transformation[Float]) -> Transformation[Float]
15471584
15481585
.. hlist::

warp/builtins.py

Lines changed: 173 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,48 @@ def transformation_value_func(arg_types: Mapping[str, type], arg_values: Mapping
16581658
if arg_types is None:
16591659
return transformation(dtype=Float)
16601660

1661+
dtype = arg_values.get("dtype", None)
1662+
1663+
variadic_arg_types = arg_types.get("args", ())
1664+
variadic_arg_count = len(variadic_arg_types)
1665+
if variadic_arg_count == 0:
1666+
# Zero-initialization, e.g.: `wp.transform()`, `wp.transformation(dtype=wp.float16)`.
1667+
if dtype is None:
1668+
dtype = float32
1669+
elif variadic_arg_count == 1:
1670+
# Initialization by filling a value, e.g.: `wp.transform(123)`,
1671+
# `wp.transformation(123)`.
1672+
value_type = strip_reference(variadic_arg_types[0])
1673+
if dtype is None:
1674+
dtype = value_type
1675+
elif not warp.types.scalars_equal(value_type, dtype):
1676+
raise RuntimeError(
1677+
f"the value used to fill this transform is expected to be of the type `{dtype.__name__}`"
1678+
)
1679+
elif variadic_arg_count == 7:
1680+
# Initializing by value, e.g.: `wp.transform(1, 2, 3, 4, 5, 6, 7)`.
1681+
try:
1682+
value_type = scalar_infer_type(variadic_arg_types)
1683+
except RuntimeError:
1684+
raise RuntimeError("all values given when constructing a transform must have the same type") from None
1685+
1686+
if dtype is None:
1687+
dtype = value_type
1688+
elif not warp.types.scalars_equal(value_type, dtype):
1689+
raise RuntimeError(
1690+
f"all values used to initialize this transform are expected to be of the type `{dtype.__name__}`"
1691+
)
1692+
1693+
if dtype is None:
1694+
raise RuntimeError("could not infer the `dtype` argument when calling the `wp.transform()` function")
1695+
1696+
return transformation(dtype=dtype)
1697+
1698+
1699+
def transformation_pq_value_func(arg_types: Mapping[str, type], arg_values: Mapping[str, Any]):
1700+
if arg_types is None:
1701+
return transformation(dtype=Float)
1702+
16611703
try:
16621704
value_type = float_infer_type(arg_types)
16631705
except RuntimeError:
@@ -1692,14 +1734,30 @@ def transformation_dispatch_func(input_types: Mapping[str, type], return_type: A
16921734

16931735
add_builtin(
16941736
"transformation",
1695-
input_types={"pos": vector(length=3, dtype=Float), "rot": quaternion(dtype=Float), "dtype": Float},
1737+
input_types={"p": vector(length=3, dtype=Float), "q": quaternion(dtype=Float), "dtype": Float},
16961738
defaults={"dtype": None},
1697-
value_func=transformation_value_func,
1739+
value_func=transformation_pq_value_func,
16981740
export_func=lambda input_types: {k: v for k, v in input_types.items() if k != "dtype"},
16991741
dispatch_func=transformation_dispatch_func,
17001742
native_func="transform_t",
17011743
group="Transformations",
1702-
doc="Construct a rigid-body transformation with translation part ``pos`` and rotation ``rot``.",
1744+
doc="Construct a rigid-body transformation with translation part ``p`` and rotation ``q``.",
1745+
export=False,
1746+
)
1747+
1748+
1749+
add_builtin(
1750+
"transformation",
1751+
input_types={"*args": Float, "dtype": Float},
1752+
defaults={"dtype": None},
1753+
variadic=True,
1754+
initializer_list_func=lambda arg_types, arg_values: len(arg_types.get("args", ())) > 1,
1755+
value_func=transformation_value_func,
1756+
export_func=lambda input_types: {k: v for k, v in input_types.items() if k not in ("dtype")},
1757+
dispatch_func=transformation_dispatch_func,
1758+
native_func="transform_t",
1759+
doc="Construct a spatial transfom vector of given dtype.",
1760+
group="Spatial Math",
17031761
export=False,
17041762
)
17051763

@@ -1751,6 +1809,40 @@ def transform_identity_dispatch_func(input_types: Mapping[str, type], return_typ
17511809
group="Transformations",
17521810
doc="Return the rotational part of a transform ``xform``.",
17531811
)
1812+
add_builtin(
1813+
"transform_set_translation",
1814+
input_types={"xform": transformation(dtype=Float), "p": vector(length=3, dtype=Float)},
1815+
value_type=None,
1816+
group="Transformations",
1817+
doc="Set the translational part of a transform ``xform``.",
1818+
)
1819+
add_builtin(
1820+
"transform_set_rotation",
1821+
input_types={"xform": transformation(dtype=Float), "q": quaternion(dtype=Float)},
1822+
value_type=None,
1823+
group="Transformations",
1824+
doc="Set the rotational part of a transform ``xform``.",
1825+
)
1826+
# performs a copy internally if wp.config.enable_vector_component_overwrites is True
1827+
add_builtin(
1828+
"transform_set_translation_copy",
1829+
input_types={"xform": transformation(dtype=Float), "p": vector(length=3, dtype=Float)},
1830+
value_type=transformation(dtype=Float),
1831+
group="Transformations",
1832+
doc="Set the translational part of a transform ``xform``.",
1833+
hidden=True,
1834+
export=False,
1835+
)
1836+
# performs a copy internally if wp.config.enable_vector_component_overwrites is True
1837+
add_builtin(
1838+
"transform_set_rotation_copy",
1839+
input_types={"xform": transformation(dtype=Float), "q": quaternion(dtype=Float)},
1840+
value_type=transformation(dtype=Float),
1841+
group="Transformations",
1842+
doc="Set the rotational part of a transform ``xform``.",
1843+
hidden=True,
1844+
export=False,
1845+
)
17541846
add_builtin(
17551847
"transform_multiply",
17561848
input_types={"a": transformation(dtype=Float), "b": transformation(dtype=Float)},
@@ -5868,6 +5960,16 @@ def vector_index_dispatch_func(input_types: Mapping[str, type], return_type: Any
58685960
group="Utility",
58695961
skip_replay=True,
58705962
)
5963+
# implements &transformation[index]
5964+
add_builtin(
5965+
"index",
5966+
input_types={"a": transformation(dtype=Float), "i": int},
5967+
value_func=vector_index_value_func,
5968+
dispatch_func=vector_index_dispatch_func,
5969+
hidden=True,
5970+
group="Utility",
5971+
skip_replay=True,
5972+
)
58715973
# implements &(*vector)[index]
58725974
add_builtin(
58735975
"indexref",
@@ -5888,6 +5990,16 @@ def vector_index_dispatch_func(input_types: Mapping[str, type], return_type: Any
58885990
group="Utility",
58895991
skip_replay=True,
58905992
)
5993+
# implements &(*transformation)[index]
5994+
add_builtin(
5995+
"indexref",
5996+
input_types={"a": transformation(dtype=Float), "i": int},
5997+
value_func=vector_index_value_func,
5998+
dispatch_func=vector_index_dispatch_func,
5999+
hidden=True,
6000+
group="Utility",
6001+
skip_replay=True,
6002+
)
58916003

58926004

58936005
# implements vector[index] = value
@@ -5909,6 +6021,15 @@ def vector_index_dispatch_func(input_types: Mapping[str, type], return_type: Any
59096021
export=False,
59106022
group="Utility",
59116023
)
6024+
# implements transformation[index] = value
6025+
add_builtin(
6026+
"assign_inplace",
6027+
input_types={"a": transformation(dtype=Scalar), "i": int, "value": Scalar},
6028+
value_type=None,
6029+
hidden=True,
6030+
export=False,
6031+
group="Utility",
6032+
)
59126033

59136034

59146035
def vector_assign_value_func(arg_types: Mapping[str, type], arg_values: Mapping[str, Any]):
@@ -5934,6 +6055,15 @@ def vector_assign_value_func(arg_types: Mapping[str, type], arg_values: Mapping[
59346055
group="Utility",
59356056
)
59366057

6058+
# implements transformation[index] = value, performs a copy internally if wp.config.enable_vector_component_overwrites is True
6059+
add_builtin(
6060+
"assign_copy",
6061+
input_types={"a": transformation(dtype=Scalar), "i": int, "value": Scalar},
6062+
value_func=vector_assign_value_func,
6063+
hidden=True,
6064+
group="Utility",
6065+
)
6066+
59376067
# implements vector[idx] += scalar
59386068
add_builtin(
59396069
"add_inplace",
@@ -5954,6 +6084,26 @@ def vector_assign_value_func(arg_types: Mapping[str, type], arg_values: Mapping[
59546084
group="Utility",
59556085
)
59566086

6087+
# implements transformation[idx] += scalar
6088+
add_builtin(
6089+
"add_inplace",
6090+
input_types={"a": transformation(dtype=Float), "i": int, "value": Float},
6091+
value_type=None,
6092+
hidden=True,
6093+
export=False,
6094+
group="Utility",
6095+
)
6096+
6097+
# implements transformation.p += vec3
6098+
add_builtin(
6099+
"transform_add_inplace",
6100+
input_types={"a": transformation(dtype=Float), "value": vector(length=3, dtype=Float)},
6101+
value_type=None,
6102+
hidden=True,
6103+
export=False,
6104+
group="Utility",
6105+
)
6106+
59576107
# implements vector[idx] -= scalar
59586108
add_builtin(
59596109
"sub_inplace",
@@ -5974,6 +6124,26 @@ def vector_assign_value_func(arg_types: Mapping[str, type], arg_values: Mapping[
59746124
group="Utility",
59756125
)
59766126

6127+
# implements transformation[idx] -= scalar
6128+
add_builtin(
6129+
"sub_inplace",
6130+
input_types={"a": transformation(dtype=Scalar), "i": int, "value": Scalar},
6131+
value_type=None,
6132+
hidden=True,
6133+
export=False,
6134+
group="Utility",
6135+
)
6136+
6137+
# implements transformation.p -= vec3
6138+
add_builtin(
6139+
"transform_sub_inplace",
6140+
input_types={"a": transformation(dtype=Float), "value": vector(length=3, dtype=Float)},
6141+
value_type=None,
6142+
hidden=True,
6143+
export=False,
6144+
group="Utility",
6145+
)
6146+
59776147

59786148
def matrix_index_row_value_func(arg_types: Mapping[str, type], arg_values: Mapping[str, Any]):
59796149
mat_type = arg_types["a"]

0 commit comments

Comments
 (0)