From b70e9bff82891037edce5c4b6390beebd23139d3 Mon Sep 17 00:00:00 2001 From: DamienGilliard <127743632+DamienGilliard@users.noreply.github.com> Date: Fri, 20 Sep 2024 21:32:30 +0200 Subject: [PATCH 01/10] FIX-UPDATE: clustering works at face level and not joint level anymore --- src/diffCheck/segmentation/DFSegmentation.cc | 48 ++++++++++++++------ src/diffCheck/segmentation/DFSegmentation.hh | 2 +- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/diffCheck/segmentation/DFSegmentation.cc b/src/diffCheck/segmentation/DFSegmentation.cc index 52c8400f..5df82bf3 100644 --- a/src/diffCheck/segmentation/DFSegmentation.cc +++ b/src/diffCheck/segmentation/DFSegmentation.cc @@ -95,23 +95,24 @@ namespace diffCheck::segmentation return segments; } - std::shared_ptr DFSegmentation::AssociateClustersToMeshes( + std::vector> DFSegmentation::AssociateClustersToMeshes( std::vector> referenceMesh, std::vector> &clusters, double angleThreshold, double associationThreshold) { - std::shared_ptr unifiedPointCloud = std::make_shared(); + std::vector> jointFaces = std::vector>(); // iterate through the mesh faces given as function argument if (referenceMesh.size() == 0) { DIFFCHECK_WARN("No mesh faces to associate with the clusters. Returning an empty point cloud."); - return unifiedPointCloud; + return std::vector>(); } for (std::shared_ptr face : referenceMesh) { std::shared_ptr correspondingSegment; + std::shared_ptr facePoints = std::make_shared(); // Getting the center of the mesh face Eigen::Vector3d faceCenter = face->Cvt2O3DTriangleMesh()->GetCenter(); @@ -124,7 +125,7 @@ namespace diffCheck::segmentation if (clusters.size() == 0) { DIFFCHECK_WARN("No clusters to associate with the mesh faces. Returning an empty point cloud."); - return unifiedPointCloud; + return std::vector>(); } for (auto segment : clusters) { @@ -160,28 +161,44 @@ namespace diffCheck::segmentation DIFFCHECK_WARN("No segment found for the face. Skipping the face."); continue; } + bool hasColors = correspondingSegment->GetNumColors() > 0; + for (Eigen::Vector3d point : correspondingSegment->Points) { bool pointInFace = false; if (face->IsPointOnFace(point, associationThreshold)) { - unifiedPointCloud->Points.push_back(point); - unifiedPointCloud->Normals.push_back( + std::cout << "Point is on face" << std::endl; + std::cout << point << std::endl; + std::cout << correspondingSegment->Normals[std::distance(correspondingSegment->Points.begin(), std::find(correspondingSegment->Points.begin(), correspondingSegment->Points.end(), point))] << std::endl; + std::cout << correspondingSegment->Colors[std::distance(correspondingSegment->Points.begin(), std::find(correspondingSegment->Points.begin(), correspondingSegment->Points.end(), point))] << std::endl; + std::cout << "pipopu" << std::endl; + facePoints->Points.push_back(point); + std::cout << "pipopou_bis" << std::endl; + facePoints->Normals.push_back( correspondingSegment->Normals[std::distance( correspondingSegment->Points.begin(), std::find(correspondingSegment->Points.begin(), correspondingSegment->Points.end(), point))] ); + std::cout << "pipopou_bis_bis" << std::endl; + if (hasColors) + { + facePoints->Colors.push_back( + correspondingSegment->Colors[std::distance( + correspondingSegment->Points.begin(), + std::find(correspondingSegment->Points.begin(), + correspondingSegment->Points.end(), + point))] + ); + } + std::cout << "pipopououou" << std::endl; } } - // removing points from the segment that are in the face - if (unifiedPointCloud->GetNumPoints() == 0) - { - DIFFCHECK_WARN("No point was associated to this segment. Skipping the segment."); - continue; - } - for(Eigen::Vector3d point : unifiedPointCloud->Points) + + std::cout << "pipopouououou_encore" << std::endl; + for(Eigen::Vector3d point : facePoints->Points) { correspondingSegment->Points.erase( std::remove( @@ -190,8 +207,11 @@ namespace diffCheck::segmentation point), correspondingSegment->Points.end()); } + std::cout << "pipopouououou_encore_bis" << std::endl; + jointFaces.push_back(facePoints); } - return unifiedPointCloud; + std::cout << "pipopouououou_encore_ter" << std::endl; + return jointFaces; } void DFSegmentation::CleanUnassociatedClusters( diff --git a/src/diffCheck/segmentation/DFSegmentation.hh b/src/diffCheck/segmentation/DFSegmentation.hh index 2e325aac..d9a6d913 100644 --- a/src/diffCheck/segmentation/DFSegmentation.hh +++ b/src/diffCheck/segmentation/DFSegmentation.hh @@ -33,7 +33,7 @@ namespace diffCheck::segmentation * @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. * @return std::shared_ptr The unified segments */ - static std::shared_ptr DFSegmentation::AssociateClustersToMeshes( + static std::vector> DFSegmentation::AssociateClustersToMeshes( std::vector> referenceMesh, std::vector> &clusters, double angleThreshold = 0.1, From 7f89981ac4e532a0c032c0dc39d73d558f7eace4 Mon Sep 17 00:00:00 2001 From: DamienGilliard <127743632+DamienGilliard@users.noreply.github.com> Date: Fri, 20 Sep 2024 21:43:28 +0200 Subject: [PATCH 02/10] FIX: diffCheckApp replaced with non-failing one (currently not needed) --- src/diffCheckApp.cc | 135 +------------------------------------------- 1 file changed, 1 insertion(+), 134 deletions(-) diff --git a/src/diffCheckApp.cc b/src/diffCheckApp.cc index cdb7c7d7..abcfc23e 100644 --- a/src/diffCheckApp.cc +++ b/src/diffCheckApp.cc @@ -12,139 +12,6 @@ int main() { - auto initTime = std::chrono::high_resolution_clock::now(); - - std::shared_ptr pcdSrc = std::make_shared(); - - std::vector>> meshSrc = std::vector>>(); - std::vector> segments; - std::vector meshPaths; - - std::string meshesFolderPath = R"(C:\Users\localuser\Desktop\meshes_for_diffCheck\joints\)"; - - for (int i = 1; i <= 3; i++) - { - std::vector> fullJoint; - for (int j = 1; j <= 3; j++) - { - std::string meshPath = meshesFolderPath + std::to_string(i) + "/" + std::to_string(j) + ".ply"; - std::shared_ptr mesh = std::make_shared(); - mesh->LoadFromPLY(meshPath); - fullJoint.push_back(mesh); - } - meshSrc.push_back(fullJoint); - } - - std::string pathPcdSrc = R"(C:\Users\localuser\Desktop\meshes_for_diffCheck\joints\full_beam.ply)"; - - pcdSrc->LoadFromPLY(pathPcdSrc); - - pcdSrc->EstimateNormals(false, 100); - pcdSrc->VoxelDownsample(0.007); - auto intermediateTime = std::chrono::high_resolution_clock::now(); - segments = diffCheck::segmentation::DFSegmentation::NormalBasedSegmentation( - pcdSrc, - 15.0f, - 15, - true, - 50, - 0.5f, - false); - std::cout << "number of segments:" << segments.size()<< std::endl; - - std::vector> unifiedSegments; - for (int i = 0; i < meshSrc.size(); i++) - { - std::shared_ptr unifiedSegment = std::make_shared(); - unifiedSegment = diffCheck::segmentation::DFSegmentation::AssociateClustersToMeshes( - meshSrc[i], - segments, - .2, - .05); - unifiedSegments.push_back(unifiedSegment); - } - - diffCheck::segmentation::DFSegmentation::CleanUnassociatedClusters(segments, - unifiedSegments, - meshSrc, - .2, - .05); - - // Perform a registration per joint - for (int i = 0; i < meshSrc.size(); i++) - { - std::shared_ptr referencePointCloud = std::make_shared(); - for (auto jointFace : meshSrc[i]) - { - std::shared_ptr facePointCloud = jointFace->SampleCloudUniform(1000); - referencePointCloud->Points.insert(referencePointCloud->Points.end(), facePointCloud->Points.begin(), facePointCloud->Points.end()); - } - referencePointCloud->EstimateNormals(false, 100); - - diffCheck::transformation::DFTransformation transformation = diffCheck::registrations::DFRefinedRegistration::O3DICP( - unifiedSegments[i], - referencePointCloud); - - std::cout << "Transformation matrix:" << std::endl; - std::cout << transformation.TransformationMatrix << std::endl; - - diffCheck::visualizer::Visualizer deVisu = diffCheck::visualizer::Visualizer("DiffCheckApp", 1000, 800, 50, 50, false, true, false); - for (int i = 0; i < segments.size(); i++) - { - segments[i]->ApplyTransformation(transformation); - deVisu.AddPointCloud(segments[i]); - } - for (auto joint : meshSrc) - { - for (auto face : joint) - { - deVisu.AddMesh(face); - } - } - deVisu.Run(); - } - - diffCheck::visualizer::Visualizer vis(std::string("DiffCheckApp"), 1000, 800, 50, 50, false, true, false); - for (auto segment : segments) - { - // colorize the segments with random colors - double r = static_cast(rand()) / RAND_MAX; - double g = static_cast(rand()) / RAND_MAX; - double b = static_cast(rand()) / RAND_MAX; - - segment->Colors.clear(); - for (int i = 0; i < segment->Points.size(); i++) - { - segment->Colors.push_back(Eigen::Vector3d(0, 0, 0)); - } - vis.AddPointCloud(segment); - } - for(auto joint : meshSrc) - { - for(auto mesh : joint){vis.AddMesh(mesh);} - } - - int numSegments = unifiedSegments.size(); - - for (int i = 0; i < numSegments; i++) - { - for (int j = 0; j < unifiedSegments[i]->Points.size(); j++) - { - unifiedSegments[i]->Colors.push_back(Eigen::Vector3d((double(numSegments) - double(i))/double(numSegments), 1, double(i) / double(numSegments))); - } - } - for (auto seg : unifiedSegments) - { - vis.AddPointCloud(seg); - } - - auto endTime = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(endTime - initTime); - auto segmentationTime = std::chrono::duration_cast(endTime - intermediateTime); - std::cout << "Total computation time:" << duration.count() << std::endl; - std::cout << "Segmentation time:" << segmentationTime.count() << std::endl; - - vis.Run(); - + std::cout << "Hello, World!" << std::endl; return 0; } \ No newline at end of file From 34077bf1609639438ed6ca4655a0450124348eae Mon Sep 17 00:00:00 2001 From: DamienGilliard <127743632+DamienGilliard@users.noreply.github.com> Date: Fri, 20 Sep 2024 23:52:34 +0200 Subject: [PATCH 03/10] FIX-UPDATE: Joint segmentator component adapted to output the joints as well as the joint faces individually --- .../components/DF_joint_segmentator/code.py | 63 +++++++++---------- .../DF_joint_segmentator/metadata.json | 28 ++++++--- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/gh/components/DF_joint_segmentator/code.py b/src/gh/components/DF_joint_segmentator/code.py index c981706b..4f893eb8 100644 --- a/src/gh/components/DF_joint_segmentator/code.py +++ b/src/gh/components/DF_joint_segmentator/code.py @@ -1,15 +1,15 @@ +"""Extracts the joints from a point cloud.""" #! python3 +import System + import Rhino -import diffCheck from diffCheck import diffcheck_bindings from diffCheck import df_cvt_bindings as df_cvt -from Grasshopper.Kernel import GH_RuntimeMessageLevel as RML from ghpythonlib.componentbase import executingcomponent as component -import System ABSTOL = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance @@ -17,16 +17,18 @@ class DFJointSegmentator(component): def __init__(self): super(DFJointSegmentator, self).__init__() def RunScript(self, - i_clusters: System.Collections.Generic.List[Rhino.Geometry.PointCloud], - i_assembly: diffCheck.df_geometries.DFAssembly, - i_angle_threshold: float, - i_distance_threshold: float): + i_clusters: System.Collections.Generic.List[Rhino.Geometry.PointCloud], + i_assembly, + i_angle_threshold: float, + i_distance_threshold: float, + i_correspondence_distance: float,): if i_angle_threshold is None: i_angle_threshold = 0.1 if i_distance_threshold is None: i_distance_threshold = 0.1 - + if i_correspondence_distance is None: + i_correspondence_distance = 0.005 if len(i_clusters) == 0: raise ValueError("No clusters given.") if not isinstance(i_clusters[0], Rhino.Geometry.PointCloud): @@ -44,41 +46,38 @@ def RunScript(self, face.Faces.ConvertQuadsToTriangles() df_joints[joint.id].append(df_cvt.cvt_rhmesh_2_dfmesh(face)) - ref_rh_joint_clouds = [] + o_reference_point_clouds = [] transforms = [] - rh_joint_segments = [] + all_rh_joint_faces_segments = [] df_cloud_clusters = [df_cvt.cvt_rhcloud_2_dfcloud(cluster) for cluster in i_clusters] - + df_joint_clouds = [] # for each joint, find the corresponding clusters and merge them, generate a reference point cloud, and register the merged clusters to the reference point cloud for df_joint in df_joints: + rh_joint_faces_segments = [] # create the reference point cloud ref_df_joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud() - + df_joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud() for face in df_joint: ref_face_cloud = face.sample_points_uniformly(1000) ref_df_joint_cloud.add_points(ref_face_cloud) - ref_rh_joint_clouds.append(df_cvt.cvt_dfcloud_2_rhcloud(ref_df_joint_cloud)) + o_reference_point_clouds.append(df_cvt.cvt_dfcloud_2_rhcloud(ref_df_joint_cloud)) # find the corresponding clusters and merge them - df_joint_segment = diffcheck_bindings.dfb_segmentation.DFSegmentation.associate_clusters(df_joint, df_cloud_clusters, i_angle_threshold, i_distance_threshold) - diffcheck_bindings.dfb_segmentation.DFSegmentation.clean_unassociated_clusters(df_cloud_clusters, [df_joint_segment], [df_joint], i_angle_threshold, i_distance_threshold) + df_joint_face_segments = diffcheck_bindings.dfb_segmentation.DFSegmentation.associate_clusters(df_joint, df_cloud_clusters, i_angle_threshold, i_distance_threshold) + for df_joint_face_segment in df_joint_face_segments: + df_joint_cloud.add_points(df_joint_face_segment) # register the merged clusters to the reference point cloud - registration = diffcheck_bindings.dfb_registrations.DFRefinedRegistration.O3DICP(df_joint_segment, ref_df_joint_cloud) - res = registration.transformation_matrix - transforms.append(df_cvt.cvt_ndarray_2_rh_transform(res)) - rh_joint_segments.append(df_cvt.cvt_dfcloud_2_rhcloud(df_joint_segment)) - - o_joint_segments = [] - o_transforms = [] - o_reference_point_clouds = [] - for joint_segment, transform, _joint_cloud in zip(rh_joint_segments, transforms, ref_rh_joint_clouds): - if joint_segment.IsValid: - o_joint_segments.append(joint_segment) - o_transforms.append(transform) - o_reference_point_clouds.append(_joint_cloud) - else: - ghenv.Component.AddRuntimeMessage(RML.Warning, "Some joints could not be segmented and were ignored.") # noqa: F821 - - return o_joint_segments, o_transforms, o_reference_point_clouds + transform = diffcheck_bindings.dfb_registrations.DFRefinedRegistration.O3DICP(df_joint_cloud, ref_df_joint_cloud, max_correspondence_distance = i_correspondence_distance) + for df_joint_face_segment in df_joint_face_segments: + df_joint_face_segment.apply_transformation(transform) + rh_joint_faces_segments.append(df_cvt.cvt_dfcloud_2_rhcloud(df_joint_face_segment)) + transforms.append(transform) + df_joint_clouds.append(df_joint_cloud) + all_rh_joint_faces_segments.append(rh_joint_faces_segments) + + o_joint_faces_segments = all_rh_joint_faces_segments + o_joint_segments = [df_cvt.cvt_dfcloud_2_rhcloud(df_joint_cloud) for df_joint_cloud in df_joint_clouds] + + return o_joint_faces_segments, o_joint_segments, o_reference_point_clouds diff --git a/src/gh/components/DF_joint_segmentator/metadata.json b/src/gh/components/DF_joint_segmentator/metadata.json index 987bcdc6..e5289dc8 100644 --- a/src/gh/components/DF_joint_segmentator/metadata.json +++ b/src/gh/components/DF_joint_segmentator/metadata.json @@ -50,8 +50,8 @@ "typeHintID": "float" }, { - "name": "i_association_threshold", - "nickname": "i_association_threshold", + "name": "i_distance_threshold", + "nickname": "i_distance_threshold", "description": "From 0 to infinite. By default 0.1. The closer to 0 the less permissive your point.", "optional": true, "allowTreeAccess": true, @@ -60,21 +60,33 @@ "wireDisplay": "default", "sourceCount": 0, "typeHintID": "float" + }, + { + "name": "i_correspondence_distance", + "nickname": "i_correspondence_distance", + "description": "The maximum correspondence distance for the local ICP registration that re-aligns the joints for per-face analysis of each joint.", + "optional": true, + "allowTreeAccess": true, + "showTypeHints": true, + "scriptParamAccess": "item", + "wireDisplay": "default", + "sourceCount": 0, + "typeHintID": "float" } ], "outputParameters": [ { - "name": "o_joint_segments", - "nickname": "o_joint_segments", - "description": "The extracted joints.", + "name": "o_joint_face_segments", + "nickname": "o_joint_face_segments", + "description": "The individual faces of the extracted joints.", "optional": false, "sourceCount": 0, "graft": false }, { - "name": "o_transforms", - "nickname": "o_transforms", - "description": "The transformations for each joint.", + "name": "o_joint_segments", + "nickname": "o_joint_segments", + "description": "The extracted joints.", "optional": false, "sourceCount": 0, "graft": false From d229d02554848a1900a13d1ef922ed111e18af59 Mon Sep 17 00:00:00 2001 From: DamienGilliard <127743632+DamienGilliard@users.noreply.github.com> Date: Fri, 20 Sep 2024 23:59:09 +0200 Subject: [PATCH 04/10] FIX: Component and metadata clean-up --- src/gh/components/DF_joint_segmentator/code.py | 16 +++++++--------- .../DF_joint_segmentator/metadata.json | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/gh/components/DF_joint_segmentator/code.py b/src/gh/components/DF_joint_segmentator/code.py index 4f893eb8..c5db33b6 100644 --- a/src/gh/components/DF_joint_segmentator/code.py +++ b/src/gh/components/DF_joint_segmentator/code.py @@ -47,37 +47,35 @@ def RunScript(self, df_joints[joint.id].append(df_cvt.cvt_rhmesh_2_dfmesh(face)) o_reference_point_clouds = [] - transforms = [] - all_rh_joint_faces_segments = [] + o_joint_faces_segments = [] df_cloud_clusters = [df_cvt.cvt_rhcloud_2_dfcloud(cluster) for cluster in i_clusters] df_joint_clouds = [] - # for each joint, find the corresponding clusters and merge them, generate a reference point cloud, and register the merged clusters to the reference point cloud + + # for each joint, find the corresponding faces, store them as such but also merge them, generate a reference point cloud, and register the merged clusters to the reference point cloud for df_joint in df_joints: rh_joint_faces_segments = [] + # create the reference point cloud ref_df_joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud() - df_joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud() for face in df_joint: ref_face_cloud = face.sample_points_uniformly(1000) ref_df_joint_cloud.add_points(ref_face_cloud) - o_reference_point_clouds.append(df_cvt.cvt_dfcloud_2_rhcloud(ref_df_joint_cloud)) # find the corresponding clusters and merge them + df_joint_cloud = diffcheck_bindings.dfb_geometry.DFPointCloud() df_joint_face_segments = diffcheck_bindings.dfb_segmentation.DFSegmentation.associate_clusters(df_joint, df_cloud_clusters, i_angle_threshold, i_distance_threshold) for df_joint_face_segment in df_joint_face_segments: df_joint_cloud.add_points(df_joint_face_segment) - # register the merged clusters to the reference point cloud + # register the joint faces to the reference point cloud transform = diffcheck_bindings.dfb_registrations.DFRefinedRegistration.O3DICP(df_joint_cloud, ref_df_joint_cloud, max_correspondence_distance = i_correspondence_distance) for df_joint_face_segment in df_joint_face_segments: df_joint_face_segment.apply_transformation(transform) rh_joint_faces_segments.append(df_cvt.cvt_dfcloud_2_rhcloud(df_joint_face_segment)) - transforms.append(transform) df_joint_clouds.append(df_joint_cloud) - all_rh_joint_faces_segments.append(rh_joint_faces_segments) + o_joint_faces_segments.append(rh_joint_faces_segments) - o_joint_faces_segments = all_rh_joint_faces_segments o_joint_segments = [df_cvt.cvt_dfcloud_2_rhcloud(df_joint_cloud) for df_joint_cloud in df_joint_clouds] return o_joint_faces_segments, o_joint_segments, o_reference_point_clouds diff --git a/src/gh/components/DF_joint_segmentator/metadata.json b/src/gh/components/DF_joint_segmentator/metadata.json index e5289dc8..8ce50c06 100644 --- a/src/gh/components/DF_joint_segmentator/metadata.json +++ b/src/gh/components/DF_joint_segmentator/metadata.json @@ -64,7 +64,7 @@ { "name": "i_correspondence_distance", "nickname": "i_correspondence_distance", - "description": "The maximum correspondence distance for the local ICP registration that re-aligns the joints for per-face analysis of each joint.", + "description": "The maximum correspondence distance for the local ICP registration that re-aligns the joints for per-face analysis of each joint. The default value is 0.005", "optional": true, "allowTreeAccess": true, "showTypeHints": true, From 42f0bd2dbc7c32189a25de5c9e40e24b993540e8 Mon Sep 17 00:00:00 2001 From: DamienGilliard <127743632+DamienGilliard@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:27:39 +0200 Subject: [PATCH 05/10] FIX: Clean unassociated cliusters adds the colors as well --- src/diffCheck/segmentation/DFSegmentation.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/diffCheck/segmentation/DFSegmentation.cc b/src/diffCheck/segmentation/DFSegmentation.cc index 5df82bf3..618cd65b 100644 --- a/src/diffCheck/segmentation/DFSegmentation.cc +++ b/src/diffCheck/segmentation/DFSegmentation.cc @@ -327,6 +327,10 @@ namespace diffCheck::segmentation { completed_segment->Points.push_back(point); completed_segment->Normals.push_back(cluster->Normals[std::distance(cluster->Points.begin(), std::find(cluster->Points.begin(), cluster->Points.end(), point))]); + if (cluster->GetNumColors() > 0) + { + completed_segment->Colors.push_back(cluster->Colors[std::distance(cluster->Points.begin(), std::find(cluster->Points.begin(), cluster->Points.end(), point))]); + } } } std::vector indicesToRemove; From 9045d7bb99a9ce6039e9a3086934c06e3225b09f Mon Sep 17 00:00:00 2001 From: DamienGilliard <127743632+DamienGilliard@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:28:52 +0200 Subject: [PATCH 06/10] FIX-UPDATE: CAD degmentator adapted to reflect changes to segmetation backend for face-level analysis --- src/gh/components/DF_CAD_segmentator/code.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gh/components/DF_CAD_segmentator/code.py b/src/gh/components/DF_CAD_segmentator/code.py index 2e57ca65..3464913f 100644 --- a/src/gh/components/DF_CAD_segmentator/code.py +++ b/src/gh/components/DF_CAD_segmentator/code.py @@ -8,6 +8,7 @@ from diffCheck.diffcheck_bindings import dfb_segmentation +from diffCheck.diffcheck_bindings import dfb_geometry from diffCheck import df_cvt_bindings @@ -18,7 +19,7 @@ def RunScript(self, i_clouds: System.Collections.Generic.IList[Rhino.Geometry.PointCloud], i_assembly, i_angle_threshold: float = 0.1, - i_association_threshold: float = 0.1) -> rg.PointCloud: + i_association_threshold: float = 0.1) -> Rhino.Geometry.PointCloud: if i_clouds is None or i_assembly is None: self.AddRuntimeMessage(RML.Warning, "Please provide a cloud and an assembly to segmentate") @@ -43,12 +44,15 @@ def RunScript(self, df_beams_meshes.append(df_b_mesh_faces) rh_beams_meshes.append(rh_b_mesh_faces) - df_asssociated_cluster = dfb_segmentation.DFSegmentation.associate_clusters( + df_asssociated_cluster = dfb_geometry.DFPointCloud() + df_asssociated_cluster_faces = dfb_segmentation.DFSegmentation.associate_clusters( reference_mesh=df_b_mesh_faces, unassociated_clusters=df_clouds, angle_threshold=i_angle_threshold, association_threshold=i_association_threshold ) + for df_associated_face in df_asssociated_cluster_faces: + df_asssociated_cluster.add_points(df_associated_face) df_clusters.append(df_asssociated_cluster) dfb_segmentation.DFSegmentation.clean_unassociated_clusters( From 6fcea59b2a1bc84a6d5a926545ef77f12212878c Mon Sep 17 00:00:00 2001 From: DamienGilliard <127743632+DamienGilliard@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:31:39 +0200 Subject: [PATCH 07/10] FIX: return value of RunScript of code.py --- src/gh/components/DF_CAD_segmentator/code.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gh/components/DF_CAD_segmentator/code.py b/src/gh/components/DF_CAD_segmentator/code.py index 3464913f..56abc100 100644 --- a/src/gh/components/DF_CAD_segmentator/code.py +++ b/src/gh/components/DF_CAD_segmentator/code.py @@ -65,4 +65,4 @@ def RunScript(self, o_clusters = [df_cvt_bindings.cvt_dfcloud_2_rhcloud(cluster) for cluster in df_clusters] - return o_clusters, rh_beams_meshes + return o_clusters From d120179e0039b98091af24331ae0fd639fe313e7 Mon Sep 17 00:00:00 2001 From: DamienGilliard <127743632+DamienGilliard@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:39:02 +0200 Subject: [PATCH 08/10] FIX: syntax fixes for pre-commit --- src/gh/components/DF_mesh_to_cloud/code.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/gh/components/DF_mesh_to_cloud/code.py b/src/gh/components/DF_mesh_to_cloud/code.py index f3087d84..e7b3f660 100644 --- a/src/gh/components/DF_mesh_to_cloud/code.py +++ b/src/gh/components/DF_mesh_to_cloud/code.py @@ -12,9 +12,15 @@ class DFMeshToCloud(component): - def RunScript(self, i_mesh: Rhino.Geometry.Mesh, i_points: int) -> Rhino.Geometry.PointCloud: - df_mesh = diffCheck.df_cvt_bindings.cvt_rhmesh_2_dfmesh(i_mesh) - df_cloud = df_mesh.sample_points_uniformly(i_points) + def RunScript(self, + i_meshes: System.Collections.Generic.List[Rhino.Geometry.Mesh], + i_points: int) -> Rhino.Geometry.PointCloud: + + if i_meshes is None: + return None + + if i_points is None: + i_points = 1000 rh_mesh = i_meshes[0] for i in range(1, len(i_meshes)): @@ -27,8 +33,6 @@ def RunScript(self, i_mesh: Rhino.Geometry.Mesh, i_points: int) -> Rhino.Geometr df_cloud = df_mesh.sample_points_uniformly(i_points) rgpoints = [Rhino.Geometry.Point3d(p[0], p[1], p[2]) for p in df_cloud.points] # convert the df_cloud to a rhino cloud - - rgpoints = [Rhino.Geometry.Point3d(pt[0], pt[1], pt[2]) for pt in df_cloud.points] rh_cloud = Rhino.Geometry.PointCloud(rgpoints) return [rh_cloud] From 5fa433b770215860c4009f68b3964ac03646ca07 Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Sat, 21 Sep 2024 09:17:39 +0200 Subject: [PATCH 09/10] FIX: cleaning PR --- src/diffCheck/segmentation/DFSegmentation.cc | 11 ----------- src/gh/components/DF_CAD_segmentator/code.py | 5 +++-- src/gh/components/DF_joint_segmentator/code.py | 1 - src/gh/components/DF_joint_segmentator/metadata.json | 2 +- 4 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/diffCheck/segmentation/DFSegmentation.cc b/src/diffCheck/segmentation/DFSegmentation.cc index 618cd65b..37bb549a 100644 --- a/src/diffCheck/segmentation/DFSegmentation.cc +++ b/src/diffCheck/segmentation/DFSegmentation.cc @@ -168,13 +168,7 @@ namespace diffCheck::segmentation bool pointInFace = false; if (face->IsPointOnFace(point, associationThreshold)) { - std::cout << "Point is on face" << std::endl; - std::cout << point << std::endl; - std::cout << correspondingSegment->Normals[std::distance(correspondingSegment->Points.begin(), std::find(correspondingSegment->Points.begin(), correspondingSegment->Points.end(), point))] << std::endl; - std::cout << correspondingSegment->Colors[std::distance(correspondingSegment->Points.begin(), std::find(correspondingSegment->Points.begin(), correspondingSegment->Points.end(), point))] << std::endl; - std::cout << "pipopu" << std::endl; facePoints->Points.push_back(point); - std::cout << "pipopou_bis" << std::endl; facePoints->Normals.push_back( correspondingSegment->Normals[std::distance( correspondingSegment->Points.begin(), @@ -182,7 +176,6 @@ namespace diffCheck::segmentation correspondingSegment->Points.end(), point))] ); - std::cout << "pipopou_bis_bis" << std::endl; if (hasColors) { facePoints->Colors.push_back( @@ -193,11 +186,9 @@ namespace diffCheck::segmentation point))] ); } - std::cout << "pipopououou" << std::endl; } } - std::cout << "pipopouououou_encore" << std::endl; for(Eigen::Vector3d point : facePoints->Points) { correspondingSegment->Points.erase( @@ -207,10 +198,8 @@ namespace diffCheck::segmentation point), correspondingSegment->Points.end()); } - std::cout << "pipopouououou_encore_bis" << std::endl; jointFaces.push_back(facePoints); } - std::cout << "pipopouououou_encore_ter" << std::endl; return jointFaces; } diff --git a/src/gh/components/DF_CAD_segmentator/code.py b/src/gh/components/DF_CAD_segmentator/code.py index 56abc100..f0cc9678 100644 --- a/src/gh/components/DF_CAD_segmentator/code.py +++ b/src/gh/components/DF_CAD_segmentator/code.py @@ -22,7 +22,7 @@ def RunScript(self, i_association_threshold: float = 0.1) -> Rhino.Geometry.PointCloud: if i_clouds is None or i_assembly is None: - self.AddRuntimeMessage(RML.Warning, "Please provide a cloud and an assembly to segmentate") + self.AddRuntimeMessage(RML.Warning, "Please provide a cloud and an assembly to segment.") return None if i_angle_threshold is None: i_angle_threshold = 0.1 @@ -44,13 +44,14 @@ def RunScript(self, df_beams_meshes.append(df_b_mesh_faces) rh_beams_meshes.append(rh_b_mesh_faces) - df_asssociated_cluster = dfb_geometry.DFPointCloud() df_asssociated_cluster_faces = dfb_segmentation.DFSegmentation.associate_clusters( reference_mesh=df_b_mesh_faces, unassociated_clusters=df_clouds, angle_threshold=i_angle_threshold, association_threshold=i_association_threshold ) + + df_asssociated_cluster = dfb_geometry.DFPointCloud() for df_associated_face in df_asssociated_cluster_faces: df_asssociated_cluster.add_points(df_associated_face) df_clusters.append(df_asssociated_cluster) diff --git a/src/gh/components/DF_joint_segmentator/code.py b/src/gh/components/DF_joint_segmentator/code.py index c5db33b6..f1ef57aa 100644 --- a/src/gh/components/DF_joint_segmentator/code.py +++ b/src/gh/components/DF_joint_segmentator/code.py @@ -1,4 +1,3 @@ -"""Extracts the joints from a point cloud.""" #! python3 import System diff --git a/src/gh/components/DF_joint_segmentator/metadata.json b/src/gh/components/DF_joint_segmentator/metadata.json index 8ce50c06..8cc16a32 100644 --- a/src/gh/components/DF_joint_segmentator/metadata.json +++ b/src/gh/components/DF_joint_segmentator/metadata.json @@ -5,7 +5,7 @@ "subcategory": "Segmentation", "description": "Extracts the joints from a point cloud.", "exposure": 4, - "instanceGuid": "fd804928-bf11-43eb-a29f-8afabefa660d", + "instanceGuid": "bf27b323-6b03-42f2-a2de-638aeb2c08f9", "ghpython": { "hideOutput": true, "hideInput": true, From 3c4ef9912fdd2b05f6a5ef056c3d5bbfe53eecce Mon Sep 17 00:00:00 2001 From: Andrea Settimi Date: Sat, 21 Sep 2024 09:33:39 +0200 Subject: [PATCH 10/10] FIX-CAP: minor fixes + convertion to ghtree --- src/gh/components/DF_joint_segmentator/code.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gh/components/DF_joint_segmentator/code.py b/src/gh/components/DF_joint_segmentator/code.py index f1ef57aa..5446b278 100644 --- a/src/gh/components/DF_joint_segmentator/code.py +++ b/src/gh/components/DF_joint_segmentator/code.py @@ -3,6 +3,7 @@ import System import Rhino +import ghpythonlib.treehelpers from diffCheck import diffcheck_bindings from diffCheck import df_cvt_bindings as df_cvt @@ -22,6 +23,8 @@ def RunScript(self, i_distance_threshold: float, i_correspondence_distance: float,): + if i_clusters is None or i_assembly is None: + return None if i_angle_threshold is None: i_angle_threshold = 0.1 if i_distance_threshold is None: @@ -77,4 +80,6 @@ def RunScript(self, o_joint_segments = [df_cvt.cvt_dfcloud_2_rhcloud(df_joint_cloud) for df_joint_cloud in df_joint_clouds] - return o_joint_faces_segments, o_joint_segments, o_reference_point_clouds + o_gh_tree_joint_faces_segments = ghpythonlib.treehelpers.list_to_tree(o_joint_faces_segments) + + return o_gh_tree_joint_faces_segments, o_joint_segments, o_reference_point_clouds