8
8
9
9
import torch
10
10
11
+ from ..common .workaround import symeig3x3
11
12
from .utils import convert_pointclouds_to_tensor , get_point_covariances
12
13
13
14
@@ -19,6 +20,8 @@ def estimate_pointcloud_normals(
19
20
pointclouds : Union [torch .Tensor , "Pointclouds" ],
20
21
neighborhood_size : int = 50 ,
21
22
disambiguate_directions : bool = True ,
23
+ * ,
24
+ use_symeig_workaround : bool = True ,
22
25
) -> torch .Tensor :
23
26
"""
24
27
Estimates the normals of a batch of `pointclouds`.
@@ -33,6 +36,8 @@ def estimate_pointcloud_normals(
33
36
geometry around each point.
34
37
**disambiguate_directions**: If `True`, uses the algorithm from [1] to
35
38
ensure sign consistency of the normals of neighboring points.
39
+ **use_symeig_workaround**: If `True`, uses a custom eigenvalue
40
+ calculation.
36
41
37
42
Returns:
38
43
**normals**: A tensor of normals for each input point
@@ -48,6 +53,7 @@ def estimate_pointcloud_normals(
48
53
pointclouds ,
49
54
neighborhood_size = neighborhood_size ,
50
55
disambiguate_directions = disambiguate_directions ,
56
+ use_symeig_workaround = use_symeig_workaround ,
51
57
)
52
58
53
59
# the normals correspond to the first vector of each local coord frame
@@ -60,6 +66,8 @@ def estimate_pointcloud_local_coord_frames(
60
66
pointclouds : Union [torch .Tensor , "Pointclouds" ],
61
67
neighborhood_size : int = 50 ,
62
68
disambiguate_directions : bool = True ,
69
+ * ,
70
+ use_symeig_workaround : bool = True ,
63
71
) -> Tuple [torch .Tensor , torch .Tensor ]:
64
72
"""
65
73
Estimates the principal directions of curvature (which includes normals)
@@ -88,6 +96,8 @@ def estimate_pointcloud_local_coord_frames(
88
96
geometry around each point.
89
97
**disambiguate_directions**: If `True`, uses the algorithm from [1] to
90
98
ensure sign consistency of the normals of neighboring points.
99
+ **use_symeig_workaround**: If `True`, uses a custom eigenvalue
100
+ calculation.
91
101
92
102
Returns:
93
103
**curvatures**: The three principal curvatures of each point
@@ -133,7 +143,10 @@ def estimate_pointcloud_local_coord_frames(
133
143
# eigenvectors (=principal directions) in an ascending order of their
134
144
# corresponding eigenvalues, while the smallest eigenvalue's eigenvector
135
145
# corresponds to the normal direction
136
- curvatures , local_coord_frames = torch .symeig (cov , eigenvectors = True )
146
+ if use_symeig_workaround :
147
+ curvatures , local_coord_frames = symeig3x3 (cov , eigenvectors = True )
148
+ else :
149
+ curvatures , local_coord_frames = torch .symeig (cov , eigenvectors = True )
137
150
138
151
# disambiguate the directions of individual principal vectors
139
152
if disambiguate_directions :
0 commit comments