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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pointcloud2
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: PointCloud2 lib for non ROS environments
5
5
  Author: Marko Bausch
6
6
  Author-email: Marko Bausch <60338487+mrkbac@users.noreply.github.com>
@@ -21,7 +21,7 @@ classifiers = [
21
21
  "License :: OSI Approved :: MIT License",
22
22
  ]
23
23
 
24
- version = "0.2.2"
24
+ version = "0.2.3"
25
25
 
26
26
  [project.urls]
27
27
  Source = "https://github.com/mrkbac/pointcloud2"
@@ -112,7 +112,53 @@ class PointCloud2:
112
112
  DUMMY_FIELD_PREFIX = 'unnamed_field'
113
113
 
114
114
 
115
- def dtype_from_fields(fields: Iterable[PointFieldMsg], point_step: int | None = None) -> np.dtype:
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
- for i, field in enumerate(fields):
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: Sequence[PointFieldMsg | PointFieldDict],
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=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