Skip to content

Commit f03a7d3

Browse files
feat: add sophisticated parameter to discard segments that are too far
1 parent bb9b60c commit f03a7d3

File tree

5 files changed

+25
-7
lines changed

5 files changed

+25
-7
lines changed

src/diffCheck/segmentation/DFSegmentation.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ namespace diffCheck::segmentation
100100
std::vector<std::shared_ptr<geometry::DFMesh>> referenceMesh,
101101
std::vector<std::shared_ptr<geometry::DFPointCloud>> &clusters,
102102
double angleThreshold,
103-
double associationThreshold)
103+
double associationThreshold,
104+
double angleAssociationThreshold)
104105
{
105106
std::vector<std::shared_ptr<geometry::DFPointCloud>> faceSegments = std::vector<std::shared_ptr<geometry::DFPointCloud>>();
106107

@@ -271,10 +272,10 @@ namespace diffCheck::segmentation
271272
double currentDistance = (faceCenter - segmentCenter).norm();
272273
double currentAngle = std::abs(sin(acos(faceNormal.dot(faceCenter - segmentCenter))));
273274
// if the distance is smaller than the previous one, update the distance and the corresponding segment
274-
if (std::abs(sin(acos(faceNormal.dot(segmentNormal)))) < angleThreshold && currentDistance < faceDistance && std::abs(1 - currentAngle) < angleThreshold)
275+
if (std::abs(sin(acos(faceNormal.dot(segmentNormal)))) < angleThreshold && currentDistance * (angleAssociationThreshold + std::abs(faceNormal.dot((faceCenter - segmentCenter) / (faceCenter - segmentCenter).norm()))) < faceDistance)
275276
{
276277
correspondingSegment = segment;
277-
faceDistance = currentDistance;
278+
faceDistance = currentDistance * (angleAssociationThreshold + std::abs(faceNormal.dot((faceCenter - segmentCenter) / (faceCenter - segmentCenter).norm())));
278279
}
279280
}
280281

src/diffCheck/segmentation/DFSegmentation.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,16 @@ namespace diffCheck::segmentation
3232
* @param clusters the vector of clusters from cilantro to associate with the mesh faces of the reference mesh
3333
* @param angleThreshold the threshold to consider the a cluster as potential candidate for association. the value passed is the minimum sine of the angles. A value of 0 requires perfect alignment (angle = 0), while a value of 0.1 allows an angle of 5.7 degrees.
3434
* @param associationThreshold the threshold to consider the points of a segment and a mesh face as associable. It is the ratio between the surface of the closest mesh triangle and the sum of the areas of the three triangles that form the rest of the pyramid described by the mesh triangle and the point we want to associate or not. The lower the number, the more strict the association will be and some poinnts on the mesh face might be wrongfully excluded.
35+
* @param angleAssociationThreshold a number to indicate how much distance in the plane of the face should be favored, compared to distance orthogonal to the face normal. If set to 0, any face in the same plane as the face will be considered as having a distance of 0. If set to a high value (e.g. 1000000), no difference will be made between distance in the plane of the face and orthogonal to it. Default is 0.5
3536
* @return std::shared_ptr<geometry::DFPointCloud> The unified segments
3637
*/
3738
static std::vector<std::shared_ptr<geometry::DFPointCloud>> DFSegmentation::AssociateClustersToMeshes(
3839
bool isCylinder,
3940
std::vector<std::shared_ptr<geometry::DFMesh>> referenceMesh,
4041
std::vector<std::shared_ptr<geometry::DFPointCloud>> &clusters,
4142
double angleThreshold = 0.1,
42-
double associationThreshold = 0.1);
43+
double associationThreshold = 0.1,
44+
double angleAssociationThreshold = 0.5);
4345

4446
/** @brief Iterated through clusters and finds the corresponding mesh face. It then associates the points of the cluster that are on the mesh face to the segment already associated with the mesh face.
4547
* @param isCylinder a boolean to indicate if the model is a cylinder. If true, the method will use the GetCenterAndAxis method of the mesh to find the center and axis of the mesh. based on that, we only want points that have normals more or less perpendicular to the cylinder axis.

src/diffCheckBindings.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ PYBIND11_MODULE(diffcheck_bindings, m) {
229229
py::arg("reference_mesh"),
230230
py::arg("unassociated_clusters"),
231231
py::arg("angle_threshold") = 0.1,
232-
py::arg("association_threshold") = 0.1)
232+
py::arg("association_threshold") = 0.1,
233+
py::arg("angle_association_threshold") = 0.5)
233234

234235
.def_static("clean_unassociated_clusters", &diffCheck::segmentation::DFSegmentation::CleanUnassociatedClusters,
235236
py::arg("is_roundwood"),

src/gh/components/DF_CAD_segmentator/code.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ def RunScript(self,
2020
i_clouds: System.Collections.Generic.IList[Rhino.Geometry.PointCloud],
2121
i_assembly,
2222
i_angle_threshold: float = 0.1,
23-
i_association_threshold: float = 0.1):
23+
i_association_threshold: float = 0.1,
24+
i_angle_association_threshold: float = 0.5):
2425

2526
if i_clouds is None or i_assembly is None:
2627
self.AddRuntimeMessage(RML.Warning, "Please provide a cloud and an assembly to segment.")
@@ -49,7 +50,8 @@ def RunScript(self,
4950
reference_mesh=df_b_mesh_faces,
5051
unassociated_clusters=df_clouds,
5152
angle_threshold=i_angle_threshold,
52-
association_threshold=i_association_threshold
53+
association_threshold=i_association_threshold,
54+
angle_association_threshold=i_angle_association_threshold
5355
)
5456

5557
dfb_segmentation.DFSegmentation.clean_unassociated_clusters(

src/gh/components/DF_CAD_segmentator/metadata.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@
6060
"wireDisplay": "default",
6161
"sourceCount": 0,
6262
"typeHintID": "float"
63+
},
64+
{
65+
"name": "i_angle_association_threshold",
66+
"nickname": "i_angle_association_threshold",
67+
"description": "A number to indicate how much distance in the plane of the face should be favored, compared to distance orthogonal to the face normal. Default is 0.5",
68+
"optional": true,
69+
"allowTreeAccess": true,
70+
"showTypeHints": true,
71+
"scriptParamAccess": "item",
72+
"wireDisplay": "default",
73+
"sourceCount": 0,
74+
"typeHintID": "float"
6375
}
6476
],
6577
"outputParameters": [

0 commit comments

Comments
 (0)