pointcloud2 0.2.2__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pointcloud2-0.2.2 → pointcloud2-0.2.3}/PKG-INFO +1 -1
- {pointcloud2-0.2.2 → pointcloud2-0.2.3}/pyproject.toml +1 -1
- {pointcloud2-0.2.2 → pointcloud2-0.2.3}/src/pointcloud2/__init__.py +57 -19
- {pointcloud2-0.2.2 → pointcloud2-0.2.3}/README.md +0 -0
- {pointcloud2-0.2.2 → pointcloud2-0.2.3}/src/pointcloud2/messages.py +0 -0
|
@@ -112,7 +112,53 @@ class PointCloud2:
|
|
|
112
112
|
DUMMY_FIELD_PREFIX = 'unnamed_field'
|
|
113
113
|
|
|
114
114
|
|
|
115
|
-
def
|
|
115
|
+
def _normalize_fields(fields: Iterable[PointFieldMsg | PointFieldDict]) -> list[PointField]:
|
|
116
|
+
"""Convert fields to a list of PointField objects with calculated offsets.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
fields: The fields to normalize.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
A list of PointField objects.
|
|
123
|
+
"""
|
|
124
|
+
normalized_fields = []
|
|
125
|
+
current_offset = 0
|
|
126
|
+
|
|
127
|
+
for field in fields:
|
|
128
|
+
if isinstance(field, dict):
|
|
129
|
+
# PointFieldDict case
|
|
130
|
+
field_datatype = field['datatype']
|
|
131
|
+
field_name = field.get('name', '')
|
|
132
|
+
field_count = field.get('count', 1)
|
|
133
|
+
|
|
134
|
+
# Calculate offset if not provided
|
|
135
|
+
if 'offset' in field:
|
|
136
|
+
field_offset = field['offset']
|
|
137
|
+
current_offset = field_offset
|
|
138
|
+
else:
|
|
139
|
+
field_offset = current_offset
|
|
140
|
+
|
|
141
|
+
# Create PointField object
|
|
142
|
+
normalized_fields.append(
|
|
143
|
+
PointField(
|
|
144
|
+
name=field_name, offset=field_offset, datatype=field_datatype, count=field_count
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Update current_offset for automatic calculation
|
|
149
|
+
if 'offset' not in field:
|
|
150
|
+
datatype_size = FIELD_TYPE_TO_NP[field_datatype].itemsize
|
|
151
|
+
current_offset += field_count * datatype_size
|
|
152
|
+
else:
|
|
153
|
+
# Already a PointField object
|
|
154
|
+
normalized_fields.append(field)
|
|
155
|
+
|
|
156
|
+
return normalized_fields
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def dtype_from_fields(
|
|
160
|
+
fields: Iterable[PointFieldMsg | PointFieldDict], point_step: int | None = None
|
|
161
|
+
) -> np.dtype:
|
|
116
162
|
"""Convert a Iterable of sensor_msgs.msg.PointField messages to a np.dtype.
|
|
117
163
|
|
|
118
164
|
Example:
|
|
@@ -128,11 +174,15 @@ def dtype_from_fields(fields: Iterable[PointFieldMsg], point_step: int | None =
|
|
|
128
174
|
Returns:
|
|
129
175
|
The NumPy dtype.
|
|
130
176
|
"""
|
|
177
|
+
# Normalize fields to PointField objects
|
|
178
|
+
normalized_fields = _normalize_fields(fields)
|
|
179
|
+
|
|
131
180
|
# Create a lists containing the names, offsets and datatypes of all fields
|
|
132
181
|
field_names: list[str] = []
|
|
133
182
|
field_offsets: list[int] = []
|
|
134
183
|
field_datatypes: list[str] = []
|
|
135
|
-
|
|
184
|
+
|
|
185
|
+
for i, field in enumerate(normalized_fields):
|
|
136
186
|
# Datatype as numpy datatype
|
|
137
187
|
datatype = FIELD_TYPE_TO_NP[field.datatype]
|
|
138
188
|
# Name field
|
|
@@ -247,7 +297,7 @@ def read_points(
|
|
|
247
297
|
|
|
248
298
|
def create_cloud(
|
|
249
299
|
header: Any,
|
|
250
|
-
fields:
|
|
300
|
+
fields: Iterable[PointFieldMsg | PointFieldDict],
|
|
251
301
|
points: np.ndarray,
|
|
252
302
|
step: int | None = None,
|
|
253
303
|
) -> PointCloud2:
|
|
@@ -267,21 +317,6 @@ def create_cloud(
|
|
|
267
317
|
Returns:
|
|
268
318
|
The point cloud as PointCloud2 message.
|
|
269
319
|
"""
|
|
270
|
-
# If fields are provided as dictionaries, convert them to a list of PointField objects
|
|
271
|
-
if fields and isinstance(fields[0], dict):
|
|
272
|
-
processed_fields = []
|
|
273
|
-
offset = 0
|
|
274
|
-
for field_dict in fields:
|
|
275
|
-
# Set default values for count and offset if not provided
|
|
276
|
-
count = field_dict.get('count', 1)
|
|
277
|
-
if 'offset' not in field_dict:
|
|
278
|
-
field_dict['offset'] = offset
|
|
279
|
-
|
|
280
|
-
processed_fields.append(PointField(**field_dict))
|
|
281
|
-
itemsize = FIELD_TYPE_TO_NP[field_dict['datatype']].itemsize
|
|
282
|
-
offset += itemsize * count
|
|
283
|
-
fields = processed_fields
|
|
284
|
-
|
|
285
320
|
# Check if input is numpy array
|
|
286
321
|
if isinstance(points, np.ndarray):
|
|
287
322
|
# Check if this is an unstructured array
|
|
@@ -321,12 +356,15 @@ def create_cloud(
|
|
|
321
356
|
array_array = array.array('B')
|
|
322
357
|
array_array.frombytes(casted)
|
|
323
358
|
|
|
359
|
+
# Convert fields to PointField objects if they are dictionaries
|
|
360
|
+
converted_fields = _normalize_fields(fields)
|
|
361
|
+
|
|
324
362
|
# Put everything together
|
|
325
363
|
return PointCloud2(
|
|
326
364
|
header=header,
|
|
327
365
|
height=height,
|
|
328
366
|
width=width,
|
|
329
|
-
fields=
|
|
367
|
+
fields=converted_fields,
|
|
330
368
|
is_bigendian=sys.byteorder != 'little',
|
|
331
369
|
point_step=points.dtype.itemsize,
|
|
332
370
|
row_step=points.dtype.itemsize * width,
|
|
File without changes
|
|
File without changes
|