diff --git a/trimesh/base.py b/trimesh/base.py
index 29b1a6bc..d309124d 100644
--- a/trimesh/base.py
+++ b/trimesh/base.py
@@ -285,7 +285,7 @@ class Trimesh(Geometry):
 
         Returns
         ----------
-        faces : (n,3) int
+        faces : (n, 3) int
           Representing triangles which reference self.vertices
         """
         return self._data.get('faces', np.empty(shape=(0, 3), dtype=int))
@@ -439,9 +439,8 @@ class Trimesh(Geometry):
         values : (n, 3) float
           Points in space
         """
-        self._data['vertices'] = np.asanyarray(values,
-                                               order='C',
-                                               dtype=np.float64)
+        self._data['vertices'] = np.asanyarray(
+            values, order='C', dtype=np.float64)
 
     @caching.cache_decorator
     def vertex_normals(self):
@@ -455,7 +454,7 @@ class Trimesh(Geometry):
 
         Returns
         ----------
-        vertex_normals : (n,3) float
+        vertex_normals : (n, 3) float
           Represents the surface normal at each vertex.
           Where n == len(self.vertices)
         """
@@ -1288,7 +1287,7 @@ class Trimesh(Geometry):
 
         Returns
         ----------
-        adjacency : (n,2) int
+        adjacency : (n, 2) int
           Pairs of faces which share an edge
 
         Examples
@@ -1460,7 +1459,7 @@ class Trimesh(Geometry):
         mesh = trimesh.primitives.Box()
         graph = mesh.vertex_adjacency_graph
         graph.neighbors(0)
-        > [1,2,3,4]
+        > [1, 2, 3, 4]
         """
 
         adjacency_g = graph.vertex_adjacency_graph(mesh=self)
@@ -1485,7 +1484,7 @@ class Trimesh(Geometry):
 
         >>> mesh = trimesh.primitives.Box()
         >>> mesh.vertex_neighbors[0]
-        [1,2,3,4]
+        [1, 2, 3, 4]
         """
         graph = self.vertex_adjacency_graph
         neighbors = [list(graph.neighbors(i)) for
@@ -1674,9 +1673,9 @@ class Trimesh(Geometry):
         # the face index of the largest face in each facet
         index = np.array([i[area_faces[i].argmax()]
                           for i in self.facets])
-        # (n,3) float, unit normal vectors of facet plane
+        # (n, 3) float, unit normal vectors of facet plane
         normals = self.face_normals[index]
-        # (n,3) float, points on facet plane
+        # (n, 3) float, points on facet plane
         origins = self.vertices[self.faces[:, 0][index]]
         # save origins in cache
         self._cache['facets_origin'] = origins
@@ -1732,7 +1731,7 @@ class Trimesh(Geometry):
         normals = self.facets_normal
         origins = self.facets_origin
 
-        # (n,3) convex hull vertices
+        # (n, 3) convex hull vertices
         convex = self.convex_hull.vertices.view(np.ndarray).copy()
 
         # boolean mask for which facets are on convex hull
@@ -2155,24 +2154,6 @@ class Trimesh(Geometry):
         # keep face normals as the haven't changed
         self._cache.clear(exclude=['face_normals'])
 
-    def apply_obb(self):
-        """
-        Apply the oriented bounding box transform to the current mesh.
-
-        This will result in a mesh with an AABB centered at the
-        origin and the same dimensions as the OBB.
-
-        Returns
-        ----------
-        matrix : (4, 4) float
-          Transformation matrix that was applied
-          to mesh to move it into OBB frame
-        """
-        matrix = self.bounding_box_oriented.primitive.transform
-        matrix = np.linalg.inv(matrix)
-        self.apply_transform(matrix)
-        return matrix
-
     def apply_transform(self, matrix):
         """
         Transform mesh by a homogeneous transformation matrix.
@@ -2187,13 +2168,12 @@ class Trimesh(Geometry):
           Homogeneous transformation matrix
         """
         # get c-order float64 matrix
-        matrix = np.asanyarray(matrix,
-                               order='C',
-                               dtype=np.float64)
+        matrix = np.asanyarray(
+            matrix, order='C', dtype=np.float64)
 
         # only support homogeneous transformations
         if matrix.shape != (4, 4):
-            raise ValueError('Transformation matrix must be (4,4)!')
+            raise ValueError('Transformation matrix must be (4, 4)!')
 
         # exit early if we've been passed an identity matrix
         # np.allclose is surprisingly slow so do this test
@@ -2804,7 +2784,7 @@ class Trimesh(Geometry):
 
         Examples
         -----------
-        r = mesh.eval_cached('np.dot(self.vertices, args[0])', [0,0,1])
+        r = mesh.eval_cached('np.dot(self.vertices, args[0])', [0, 0, 1])
         """
 
         statement = str(statement)
diff --git a/trimesh/parent.py b/trimesh/parent.py
index 86a75d3f..39d7b941 100644
--- a/trimesh/parent.py
+++ b/trimesh/parent.py
@@ -95,6 +95,24 @@ class Geometry(ABC):
         # apply_transform will work nicely even on negative scales
         return self.apply_transform(matrix)
 
+    def apply_obb(self):
+        """
+        Apply the oriented bounding box transform to the current mesh.
+
+        This will result in a mesh with an AABB centered at the
+        origin and the same dimensions as the OBB.
+
+        Returns
+        ----------
+        matrix : (4, 4) float
+          Transformation matrix that was applied
+          to mesh to move it into OBB frame
+        """
+        matrix = self.bounding_box_oriented.primitive.transform
+        matrix = np.linalg.inv(matrix)
+        self.apply_transform(matrix)
+        return matrix
+
     @abc.abstractmethod
     def copy(self):
         pass
diff --git a/trimesh/path/segments.py b/trimesh/path/segments.py
index 8b510d68..b1ef6109 100644
--- a/trimesh/path/segments.py
+++ b/trimesh/path/segments.py
@@ -437,6 +437,10 @@ def resample(segments,
     # save index of original segment
     index = []
 
+    tile = np.tile
+    # generate the line indexes ahead of time
+    stacks = util.stack_lines(np.arange(splits.max() + 1))
+
     # loop through each count of unique splits needed
     for split in np.unique(splits):
         # get a mask of which segments need to be split
@@ -444,20 +448,17 @@ def resample(segments,
         # the vector for each incremental length
         increment = vec[mask] / split
         # stack the increment vector into the shape needed
-        v = np.tile(increment, split + 1).reshape((-1, 3))
-        # apply integer multiples of the increment
-        v *= np.tile(np.arange(split + 1),
-                     len(increment)).reshape((-1, 1))
+        v = (tile(increment, split + 1).reshape((-1, 3)) *
+             tile(np.arange(split + 1),
+                  len(increment)).reshape((-1, 1)))
         # stack the origin points correctly
-        o = np.tile(pt1[mask], split + 1).reshape((-1, 3))
+        o = tile(pt1[mask], split + 1).reshape((-1, 3))
         # now get each segment as an (split, 3) polyline
         poly = (o + v).reshape((-1, split + 1, 3))
-        # get indexes to stack polyline into segments
-        stack = util.stack_lines(np.arange(split + 1))
         # save the resulting segments
         # magical slicing is equivalent to:
         # > [p[stack] for p in poly]
-        result.extend(poly[:, stack])
+        result.extend(poly[:, stacks[:split]])
 
         if return_index:
             # get the original index from the mask
@@ -466,13 +467,16 @@ def resample(segments,
             index.append((np.ones((len(poly), split),
                                   dtype=np.int64) *
                           index_original).ravel())
-
         if tol.strict:
             # check to make sure every start and end point
             # from the reconstructed result corresponds
             for original, recon in zip(segments[mask], poly):
                 assert np.allclose(original[0], recon[0])
                 assert np.allclose(original[-1], recon[-1])
+            # make sure stack slicing was OK
+            assert np.allclose(
+                util.stack_lines(np.arange(split + 1)),
+                stacks[:split])
 
     # stack into (n, 2, 3) segments
     result = [np.concatenate(result)]
diff --git a/trimesh/version.py b/trimesh/version.py
index b363ca01..f59ba749 100644
--- a/trimesh/version.py
+++ b/trimesh/version.py
@@ -1,1 +1,1 @@
-__version__ = '3.5.5'
+__version__ = '3.5.6'

AttributeError: 'PointCloud' object has no attribute 'apply_obb'
When i use 
“mesh = trimesh.load(folder + "registeredScene.ply")
Tform = mesh.apply_obb()”
 Statement，system hint AttributeError: 'PointCloud' object has no attribute 'apply_obb'，How can i modify it？Thanks。
diff --git a/tests/test_points.py b/tests/test_points.py
index 3c407a1f..fd8975e6 100644
--- a/tests/test_points.py
+++ b/tests/test_points.py
@@ -190,6 +190,13 @@ class PointsTest(g.unittest.TestCase):
         assert p.vertices.shape == (100, 3)
         assert p.colors.shape == (100, 4)
 
+    def test_obb(self):
+        p = g.get_mesh('points_agisoft.xyz')
+        original = p.bounds.copy()
+        matrix = p.apply_obb()
+        assert matrix.shape == (4, 4)
+        assert not g.np.allclose(p.bounds, original)
+
     def test_remove_close(self):
         # create 100 unique points
         p = g.np.arange(300).reshape((100, 3))

pip install -e .[all]
parse_log_pytest
requirements.txt
pytest pytest-cov
apt-get update apt-get install -y openscad blender
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
autoprop==4.1.0
backports.cached-property==1.0.2
certifi==2021.5.30
chardet==5.0.0
charset-normalizer==2.0.12
colorlog==6.9.0
coverage==6.2
cycler==0.11.0
Cython==3.0.12
decorator==4.4.2
glooey==0.3.6
idna==3.10
imageio==2.15.0
importlib-metadata==4.8.3
iniconfig==1.1.1
jsonschema==3.2.0
kiwisolver==1.3.1
lxml==5.3.1
matplotlib==3.3.4
more-itertools==8.14.0
mpmath==1.3.0
msgpack==1.0.5
networkx==2.5.1
numpy==1.19.5
packaging==21.3
Pillow==8.4.0
pluggy==1.0.0
psutil==7.0.0
py==1.11.0
pycollada==0.8
pyglet==2.0.10
pyparsing==3.1.4
pyrsistent==0.18.0
pytest==7.0.1
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
python-fcl==0.7.0.5
PyWavelets==1.1.1
PyYAML==6.0.1
requests==2.27.1
Rtree==0.9.7
scikit-image==0.17.2
scipy==1.5.4
Shapely==1.8.5.post1
signature_dispatch==1.0.0
six==1.17.0
svg.path==6.2
sympy==1.9
tifffile==2020.9.3
tomli==1.2.3
triangle==20220202
-e git+https://github.com/mikedh/trimesh.git@85ec8303d49fe12ecd1360d4027c378615105ea3#egg=trimesh
typeguard==2.13.3
typing==3.7.4.3
typing_extensions==4.1.1
urllib3==1.26.20
vecrec==0.3.1
xxhash==3.2.0
zipp==3.6.0

name: trimesh
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - autoprop==4.1.0
      - backports-cached-property==1.0.2
      - chardet==5.0.0
      - charset-normalizer==2.0.12
      - colorlog==6.9.0
      - coverage==6.2
      - cycler==0.11.0
      - cython==3.0.12
      - decorator==4.4.2
      - glooey==0.3.6
      - idna==3.10
      - imageio==2.15.0
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - jsonschema==3.2.0
      - kiwisolver==1.3.1
      - lxml==5.3.1
      - matplotlib==3.3.4
      - more-itertools==8.14.0
      - mpmath==1.3.0
      - msgpack==1.0.5
      - networkx==2.5.1
      - numpy==1.19.5
      - packaging==21.3
      - pillow==8.4.0
      - pluggy==1.0.0
      - psutil==7.0.0
      - py==1.11.0
      - pycollada==0.8
      - pyglet==2.0.10
      - pyparsing==3.1.4
      - pyrsistent==0.18.0
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - python-fcl==0.7.0.5
      - pywavelets==1.1.1
      - pyyaml==6.0.1
      - requests==2.27.1
      - rtree==0.9.7
      - scikit-image==0.17.2
      - scipy==1.5.4
      - shapely==1.8.5.post1
      - signature-dispatch==1.0.0
      - six==1.17.0
      - svg-path==6.2
      - sympy==1.9
      - tifffile==2020.9.3
      - tomli==1.2.3
      - triangle==20220202
      - typeguard==2.13.3
      - typing==3.7.4.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - vecrec==0.3.1
      - xxhash==3.2.0
      - zipp==3.6.0
prefix: /opt/conda/envs/trimesh

tests/test_points.py::PointsTest::test_obb
tests/test_points.py::PointsTest::test_empty tests/test_points.py::PointsTest::test_init_arguments tests/test_points.py::PointsTest::test_kmeans tests/test_points.py::PointsTest::test_plane tests/test_points.py::PointsTest::test_pointcloud tests/test_points.py::PointsTest::test_remove_close tests/test_points.py::PointsTest::test_tsp tests/test_points.py::PointsTest::test_vertex_only tests/test_points.py::PointsTest::test_xyz
trimesh/parent.py trimesh/base.py trimesh/version.py trimesh/path/segments.py
trimesh/parent.py trimesh/base.py trimesh/version.py trimesh/path/segments.py