Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 27 additions & 14 deletions src/diffCheck/segmentation/DFSegmentation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,23 +95,24 @@ namespace diffCheck::segmentation
return segments;
}

std::shared_ptr<geometry::DFPointCloud> DFSegmentation::AssociateClustersToMeshes(
std::vector<std::shared_ptr<geometry::DFPointCloud>> DFSegmentation::AssociateClustersToMeshes(
std::vector<std::shared_ptr<geometry::DFMesh>> referenceMesh,
std::vector<std::shared_ptr<geometry::DFPointCloud>> &clusters,
double angleThreshold,
double associationThreshold)
{
std::shared_ptr<geometry::DFPointCloud> unifiedPointCloud = std::make_shared<geometry::DFPointCloud>();
std::vector<std::shared_ptr<geometry::DFPointCloud>> jointFaces = std::vector<std::shared_ptr<geometry::DFPointCloud>>();

// 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<std::shared_ptr<geometry::DFPointCloud>>();
}
for (std::shared_ptr<diffCheck::geometry::DFMesh> face : referenceMesh)
{
std::shared_ptr<geometry::DFPointCloud> correspondingSegment;
std::shared_ptr<geometry::DFPointCloud> facePoints = std::make_shared<geometry::DFPointCloud>();

// Getting the center of the mesh face
Eigen::Vector3d faceCenter = face->Cvt2O3DTriangleMesh()->GetCenter();
Expand All @@ -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<std::shared_ptr<geometry::DFPointCloud>>();
}
for (auto segment : clusters)
{
Expand Down Expand Up @@ -160,28 +161,35 @@ 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(
facePoints->Points.push_back(point);
facePoints->Normals.push_back(
correspondingSegment->Normals[std::distance(
correspondingSegment->Points.begin(),
std::find(correspondingSegment->Points.begin(),
correspondingSegment->Points.end(),
point))]
);
if (hasColors)
{
facePoints->Colors.push_back(
correspondingSegment->Colors[std::distance(
correspondingSegment->Points.begin(),
std::find(correspondingSegment->Points.begin(),
correspondingSegment->Points.end(),
point))]
);
}
}
}
// 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)

for(Eigen::Vector3d point : facePoints->Points)
{
correspondingSegment->Points.erase(
std::remove(
Expand All @@ -190,8 +198,9 @@ namespace diffCheck::segmentation
point),
correspondingSegment->Points.end());
}
jointFaces.push_back(facePoints);
}
return unifiedPointCloud;
return jointFaces;
}

void DFSegmentation::CleanUnassociatedClusters(
Expand Down Expand Up @@ -307,6 +316,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<int> indicesToRemove;
Expand Down
2 changes: 1 addition & 1 deletion src/diffCheck/segmentation/DFSegmentation.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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<geometry::DFPointCloud> The unified segments
*/
static std::shared_ptr<geometry::DFPointCloud> DFSegmentation::AssociateClustersToMeshes(
static std::vector<std::shared_ptr<geometry::DFPointCloud>> DFSegmentation::AssociateClustersToMeshes(
std::vector<std::shared_ptr<geometry::DFMesh>> referenceMesh,
std::vector<std::shared_ptr<geometry::DFPointCloud>> &clusters,
double angleThreshold = 0.1,
Expand Down
135 changes: 1 addition & 134 deletions src/diffCheckApp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,139 +12,6 @@

int main()
{
auto initTime = std::chrono::high_resolution_clock::now();

std::shared_ptr<diffCheck::geometry::DFPointCloud> pcdSrc = std::make_shared<diffCheck::geometry::DFPointCloud>();

std::vector<std::vector<std::shared_ptr<diffCheck::geometry::DFMesh>>> meshSrc = std::vector<std::vector<std::shared_ptr<diffCheck::geometry::DFMesh>>>();
std::vector<std::shared_ptr<diffCheck::geometry::DFPointCloud>> segments;
std::vector<std::string> meshPaths;

std::string meshesFolderPath = R"(C:\Users\localuser\Desktop\meshes_for_diffCheck\joints\)";

for (int i = 1; i <= 3; i++)
{
std::vector<std::shared_ptr<diffCheck::geometry::DFMesh>> fullJoint;
for (int j = 1; j <= 3; j++)
{
std::string meshPath = meshesFolderPath + std::to_string(i) + "/" + std::to_string(j) + ".ply";
std::shared_ptr<diffCheck::geometry::DFMesh> mesh = std::make_shared<diffCheck::geometry::DFMesh>();
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<std::shared_ptr<diffCheck::geometry::DFPointCloud>> unifiedSegments;
for (int i = 0; i < meshSrc.size(); i++)
{
std::shared_ptr<diffCheck::geometry::DFPointCloud> unifiedSegment = std::make_shared<diffCheck::geometry::DFPointCloud>();
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<diffCheck::geometry::DFPointCloud> referencePointCloud = std::make_shared<diffCheck::geometry::DFPointCloud>();
for (auto jointFace : meshSrc[i])
{
std::shared_ptr<diffCheck::geometry::DFPointCloud> 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<double>(rand()) / RAND_MAX;
double g = static_cast<double>(rand()) / RAND_MAX;
double b = static_cast<double>(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<std::chrono::milliseconds>(endTime - initTime);
auto segmentationTime = std::chrono::duration_cast<std::chrono::milliseconds>(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;
}
13 changes: 9 additions & 4 deletions src/gh/components/DF_CAD_segmentator/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@


from diffCheck.diffcheck_bindings import dfb_segmentation
from diffCheck.diffcheck_bindings import dfb_geometry

from diffCheck import df_cvt_bindings

Expand All @@ -18,10 +19,10 @@ 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")
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
Expand All @@ -43,12 +44,16 @@ 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_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)

dfb_segmentation.DFSegmentation.clean_unassociated_clusters(
Expand All @@ -61,4 +66,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
Loading