diff --git a/.gitattributes b/.gitattributes index b3b5762b..34f3098c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,6 @@ *.vtk filter=lfs diff=lfs merge=lfs -text +*.3dm filter=lfs diff=lfs merge=lfs -text +*.ghx filter=lfs diff=lfs merge=lfs -text +*.gh filter=lfs diff=lfs merge=lfs -text *.ply filter=lfs diff=lfs merge=lfs -text - -_build/* linguist-vendored +_build/* linguist-vendored \ No newline at end of file diff --git a/doc/_static/example_files/additive_gh_logs_v1.gh b/doc/_static/example_files/additive_gh_logs_v1.gh new file mode 100644 index 00000000..920bda39 --- /dev/null +++ b/doc/_static/example_files/additive_gh_logs_v1.gh @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a33e5299ef47b9fa41a879c9edf47dfefd97eeb726269ee1c8494596a5731647 +size 101003042 diff --git a/doc/_static/example_files/subtractive_rh_v1.3dmbak b/doc/_static/example_files/additive_gh_robotic_v1.gh similarity index 53% rename from doc/_static/example_files/subtractive_rh_v1.3dmbak rename to doc/_static/example_files/additive_gh_robotic_v1.gh index 0b942da2..6f746a1b 100644 Binary files a/doc/_static/example_files/subtractive_rh_v1.3dmbak and b/doc/_static/example_files/additive_gh_robotic_v1.gh differ diff --git a/doc/_static/example_files/additive_gh_roof_v1.gh b/doc/_static/example_files/additive_gh_roof_v1.gh new file mode 100644 index 00000000..e6b720c5 --- /dev/null +++ b/doc/_static/example_files/additive_gh_roof_v1.gh @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b56dec5094bdbe5a687c6db612356339dd17770c697646b3d34712e9da8c044 +size 237327819 diff --git a/doc/_static/example_files/additive_rh_logs_v1.3dm b/doc/_static/example_files/additive_rh_logs_v1.3dm new file mode 100644 index 00000000..5c2c1fa0 --- /dev/null +++ b/doc/_static/example_files/additive_rh_logs_v1.3dm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f417c4035f11a6e9596a0ba4efb88368b27aff5c0a274c637feaa45976d07322 +size 14857087 diff --git a/doc/_static/example_files/additive_rh_robotic_v1.3dm b/doc/_static/example_files/additive_rh_robotic_v1.3dm new file mode 100644 index 00000000..cd20bd44 --- /dev/null +++ b/doc/_static/example_files/additive_rh_robotic_v1.3dm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44f72144401650b2031580dec565c2dea574e3d92931ef2f9572cf4842ff028f +size 45227806 diff --git a/doc/_static/example_files/additive_rh_roof_v1.3dm b/doc/_static/example_files/additive_rh_roof_v1.3dm new file mode 100644 index 00000000..4113c129 --- /dev/null +++ b/doc/_static/example_files/additive_rh_roof_v1.3dm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65d709eb21610bc9e4b0dfdb36317673b05a8ea3afe737e0cb8ede0f12daa1da +size 354465899 diff --git a/doc/_static/tutorials/fig_additive_error.png b/doc/_static/tutorials/fig_additive_error.png new file mode 100644 index 00000000..df0b2d02 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_error.png differ diff --git a/doc/_static/tutorials/fig_additive_logs_DFAssembly.png b/doc/_static/tutorials/fig_additive_logs_DFAssembly.png new file mode 100644 index 00000000..ca9c4c1d Binary files /dev/null and b/doc/_static/tutorials/fig_additive_logs_DFAssembly.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic.png b/doc/_static/tutorials/fig_additive_robotic.png new file mode 100644 index 00000000..f361ce30 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_DFassembly.png b/doc/_static/tutorials/fig_additive_robotic_DFassembly.png new file mode 100644 index 00000000..832c9d99 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_DFassembly.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_Error.png b/doc/_static/tutorials/fig_additive_robotic_Error.png new file mode 100644 index 00000000..be827c63 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_Error.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_Seg.png b/doc/_static/tutorials/fig_additive_robotic_Seg.png new file mode 100644 index 00000000..7e22d7d6 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_Seg.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_Viz.png b/doc/_static/tutorials/fig_additive_robotic_Viz.png new file mode 100644 index 00000000..f638b51e Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_Viz.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_export.png b/doc/_static/tutorials/fig_additive_robotic_export.png new file mode 100644 index 00000000..2ce21427 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_export.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_graph_viz.png b/doc/_static/tutorials/fig_additive_robotic_graph_viz.png new file mode 100644 index 00000000..68755f44 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_graph_viz.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_prep.png b/doc/_static/tutorials/fig_additive_robotic_prep.png new file mode 100644 index 00000000..6484c995 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_prep.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_results1.png b/doc/_static/tutorials/fig_additive_robotic_results1.png new file mode 100644 index 00000000..92ed4ad9 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_results1.png differ diff --git a/doc/_static/tutorials/fig_additive_robotic_start.png b/doc/_static/tutorials/fig_additive_robotic_start.png new file mode 100644 index 00000000..4b0875d2 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_robotic_start.png differ diff --git a/doc/_static/tutorials/fig_additive_roof.png b/doc/_static/tutorials/fig_additive_roof.png new file mode 100644 index 00000000..2ae7c7fc Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_DFassembly.png b/doc/_static/tutorials/fig_additive_roof_DFassembly.png new file mode 100644 index 00000000..3371bdf8 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_DFassembly.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_VizGH.png b/doc/_static/tutorials/fig_additive_roof_VizGH.png new file mode 100644 index 00000000..6b6a05e4 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_VizGH.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_error.png b/doc/_static/tutorials/fig_additive_roof_error.png new file mode 100644 index 00000000..27d6d81e Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_error.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_export.png b/doc/_static/tutorials/fig_additive_roof_export.png new file mode 100644 index 00000000..31c9917c Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_export.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_inputs.png b/doc/_static/tutorials/fig_additive_roof_inputs.png new file mode 100644 index 00000000..0db10204 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_inputs.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_legend.png b/doc/_static/tutorials/fig_additive_roof_legend.png new file mode 100644 index 00000000..6e653143 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_legend.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_reg.png b/doc/_static/tutorials/fig_additive_roof_reg.png new file mode 100644 index 00000000..5153f0e2 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_reg.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_seg.png b/doc/_static/tutorials/fig_additive_roof_seg.png new file mode 100644 index 00000000..bd49ee52 Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_seg.png differ diff --git a/doc/_static/tutorials/fig_additive_roof_viz.png b/doc/_static/tutorials/fig_additive_roof_viz.png new file mode 100644 index 00000000..80af413f Binary files /dev/null and b/doc/_static/tutorials/fig_additive_roof_viz.png differ diff --git a/doc/_static/tutorials/help.png b/doc/_static/tutorials/help.png new file mode 100644 index 00000000..86fe9542 Binary files /dev/null and b/doc/_static/tutorials/help.png differ diff --git a/doc/assembly-evaluation.md b/doc/assembly-evaluation.md deleted file mode 100644 index 45249ec7..00000000 --- a/doc/assembly-evaluation.md +++ /dev/null @@ -1,4 +0,0 @@ -(assemblyeval)= -# Assembly evaluation - -/// explain with simple example how to use the segmentation components of diffCheck and why we need them. It can be slit in two parts: single element - full structure \ No newline at end of file diff --git a/doc/assembly-evaluation.rst b/doc/assembly-evaluation.rst new file mode 100644 index 00000000..5cc045af --- /dev/null +++ b/doc/assembly-evaluation.rst @@ -0,0 +1,33 @@ +.. _df-assembly: + +Assembly Evaluation +=================== + +Objective +------------------- + +The goal is to quantify deviations between the CAD model and the scanned data for each element of an assembly. These discrepancies may arise from variations in beam dimensions, placement errors, or beams not being straight, among other factors. At this stage of development, DF only reports the deviations without providing further information on the specific error. + +Case Studies +------------------- + +The following tutorias will guide you through the evaluation of assemblies in timber construction with DF. We tested three assembly study cases: + +1. Roof structure segment crafted by augmented workers and assembled manually. +2. Frame structure with four wood logs connected by CNC-fabricated half-lap cross joints. +3. Spatial structure assembled by two robots and a human. + +.. .. image:: ../_build/_static/tutorials/fig_additive_all.png +.. :alt: Alternative text +.. :width: 800px +.. :align: center + +You can dive deeper into each case by following the respective tutorials: + +.. toctree:: + :maxdepth: 1 + :titlesonly: + + Manual Assembly + + Robotic Assembly diff --git a/doc/documentation.md b/doc/documentation.md index 0ad63e16..4f4335bc 100644 --- a/doc/documentation.md +++ b/doc/documentation.md @@ -15,7 +15,7 @@ invoke documentize ``` and to open the documentation in your browser: ```console -start _build/html/index.html +start _build/index.html ``` If you modify the `doc`s files and refresh the pages updates will be visible. @@ -68,5 +68,4 @@ If you need to add a new page to the [tutorials](tutorials.rst) (e.g. a [new tut ```{eval-rst} .. literalinclude:: tutorials.rst - :language: rst - :lines: 6-14 \ No newline at end of file + :language: rst \ No newline at end of file diff --git a/doc/gh_DFCloudCloudDistance.rst b/doc/gh_DFCloudCloudDistance.rst deleted file mode 100644 index 696313b3..00000000 --- a/doc/gh_DFCloudCloudDistance.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. image:: ../src/gh/components/DF_cloud_cloud_distance/icon.png - :align: left - :width: 40px - -``DFCloudCloudDistance`` component -================================== - -.. ghcomponent_to_rst:: ../src/gh/components/DF_cloud_cloud_distance \ No newline at end of file diff --git a/doc/gh_components.rst b/doc/gh_components.rst index 0b6781d1..08828e02 100644 --- a/doc/gh_components.rst +++ b/doc/gh_components.rst @@ -41,11 +41,6 @@ DF has a Grasshopper_ plugin with a set of components that allows the user to in - .. image:: ../src/gh/components/DF_cloud_uniform_downsample/icon.png - `gh_DFCloudUniformDownsample `_ - * - .. image:: ../src/gh/components/DF_cloud_voxel_downsample/icon.png - - `gh_DFCloudVoxelDownsample `_ - - .. image:: ../src/gh/components/DF_cloud_cloud_distance/icon.png - - `gh_DFCloudCloudDistance `_ - * - .. image:: ../src/gh/components/DF_cloud_mesh_distance/icon.png - `gh_DFCloudMeshDistance `_ - .. image:: ../src/gh/components/DF_csv_exporter/icon.png @@ -83,8 +78,8 @@ DF has a Grasshopper_ plugin with a set of components that allows the user to in * - .. image:: ../src/gh/components/DF_merge_assemblies/icon.png - `gh_DFMergeAssemblies `_ - - - - + - .. image:: ../src/gh/components/DF_cloud_voxel_downsample/icon.png + - `gh_DFCloudVoxelDownsample `_ .. toctree:: @@ -93,7 +88,6 @@ DF has a Grasshopper_ plugin with a set of components that allows the user to in gh_DFBuildAssembly gh_DFCADSegmentator - gh_DFCloudCloudDistance gh_DFCloudMeshDistance gh_DFCloudNormalEstimator gh_DFCloudSizeDownsample diff --git a/doc/index.rst b/doc/index.rst index 3310be26..64497a82 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -151,7 +151,7 @@ The software is developed by the `Laboratory of Timber Construction (IBOIS)`_ an .. toctree:: :hidden: - :maxdepth: 2 + :maxdepth: 4 :caption: Getting Started quickstart diff --git a/doc/manual-assembly.md b/doc/manual-assembly.md new file mode 100644 index 00000000..3689ffd5 --- /dev/null +++ b/doc/manual-assembly.md @@ -0,0 +1,170 @@ +# Manual Assembly + +As study cases for the manual assembly, we fabricated: +1. a roof structure detail connected with half-lap scarf joints and half-lap cross joints that were manually fabricated with Augmented Reality (AR) assistance and assembled with the aid of standard construction tools and equipment. +2. a frame structure with four wood logs connected with half-lap cross joints + +
+ +

+ +

+ + +```{eval-rst} +.. raw:: html + + +``` +--- + +## Steps + +### 1. Input the data +First things first, let's import your cleaned scan and corresponding polysurface model in Rhino. + +

+ +

+ +### 2. Build the DFAssembly +Here we convert the model of our structure into the internal datatype of diffcheck, DFAssembly. + +

+ +

+ +```{hint} +If you are evaluating round sections e.g. logs, you can set the `i_is_roundwood` input to `True` in the `DFBuildAssembly` component. + +

+ +

+ +``` + +> DF's components: +> * [`DFAssebmly`](gh_DFBuildAssembly) + +### 3. Registration of CAD and scan +The registration is the process of aligning the CAD model with the scan. This is done by selecting corresponding points on the CAD model and the scan and find a transformation that minimizes the distance between them. + +

+ +

+ +> DF's components: +> * [`DFBrepToCloud`](gh_DFBrepToCloud) +> * [`DFCloudVoxelDownsample`](gh_DFCloudVoxelDownsample) +> * [`DFCloudNormalEstimator`](gh_DFCloudNormalEstimator) +> * [`DFRANSACGlobalRegistration`](gh_DFRANSACGlobalRegistration) +> * [`DFICPRegistration`](gh_DFICPRegistration) + +### 4. Segmentation of the scan +Once the scan and the CAD model are aligned, we can segment the scan to isolate the parts of the raw point cloud of the scan that corresponds tothe joints. + +

+ +

+ +> DF's components: +> * [`DFCloudNormalSegmentator`](gh_DFCloudNormalSegmentator) +> * [`DFCADSegmentator`](gh_DFCADSegmentator) +> * [`DFColorizeCloud`](gh_DFColorizeCloud) + +### 5. Error computation +At this point we can compute the error between the CAD model and the scan. The error is computed as the distance between the closest point on the CAD model and the scan. The current DF's output metrics are: + +* *distance* : the distance between the closest point on the CAD model and the scan +* *mean* : the mean distance between the closest point on the CAD model and the scan +* *max_deviation* : the maximum distance between the closest point on the CAD model and the scan +* *min_deviation* : the minimum distance between the closest point on the CAD model and the scan +* *std_deviation* : the standard deviation of the distance between the closest point on the CAD model and the scan + +

+ +

+ +> DF's components: +> * [`DFCloudMeshDistance`](gh_DFCloudMeshDistance) + +### 6. Error Visualization +DF allows you to quickly visualize the errors in the Rhino viewport. The color of the points represents the distance between the CAD model and the scan. The color scale can be adjusted to better visualize the error. We also provide a graph that shows the distribution of the errors. + +

+ +

+ +
+
+ subtr detail +
View on the visualization of the analysed clouds on the CAD model itself.
+
+
+ subtr graph +
View of the graph of the corresponding distribution of the total error directly in Rhino.
+
+
+ +> DF's components: +> * [`DFVisualizationSettings`](gh_DFVisualizationSettings) +> * [`DFVisualization`](gh_DFVisualization) + +### 7. Export the results +The results can be also exported in a CSV file for further analysis or documentation. + +

+ +

+ +The CSV contains the values per element for the Roof Case Study (1).. + + +| Beam ID | Min Deviation | Max Deviation | Std Deviation | RMSE | Mean | +|---------|---------------|---------------|---------------|-------|-------| +| 0 | 0.0001 | 0.0899 | 0.0103 | 0.0171| 0.0137| +| 1 | 0 | 0.0263 | 0.0075 | 0.0134| 0.0112| +| 2 | 0 | 0.0176 | 0.0044 | 0.0068| 0.0052| +| 3 | 0 | 0.0258 | 0.0030 | 0.0048| 0.0037| +| 4 | 0 | 0.0192 | 0.0092 | 0.0072| 0.0057| +| 5 | 0 | 0.0711 | 0.0046 | 0.0061| 0.0053| +| ... | ... | ... | ... | ... | ... | + +and for the Frame Case Study (2).. + + +| Beam ID | Min Deviation | Max Deviation | Std Deviation | RMSE | Mean | +|---------|---------------|---------------|---------------|-------|-------| +| 0 | 0 | 0.1066 | 0.0147 | 0.0202| 0.0139| +| 1 | 0 | 0.1448 | 0.0158 | 0.0214| 0.0144| +| 2 | 0 | 0.1155 | 0.024 | 0.0402| 0.0323| +| 3 | 0 | 0.103 | 0.0198 | 0.0333| 0.0267| + + +> DF's components: +> * [`DFCsvExporter`](gh_DFCsvExporter) \ No newline at end of file diff --git a/doc/robotic-assembly.md b/doc/robotic-assembly.md new file mode 100644 index 00000000..87d07705 --- /dev/null +++ b/doc/robotic-assembly.md @@ -0,0 +1,145 @@ +# Robotic Assembly + +As a studycase for the robotic assembly, we fabricated a spatial structure with a total of thirteen elements of square section connected through bolted face lap joints. The setup included two ABB GoFa CRB 15000-5 and a human. + +
+ +

+ +

+ +
+ +```{eval-rst} +.. raw:: html + + +``` + +## Steps + +### 1. Input the data +First things first, let's import your cleaned scan and corresponding polysurface model in Rhino. For this tutorial, we assume that the two are already aligned to each other as the location of the robotically assembled structure is known. + +

+ +

+ + +### 2. Build the DFAssembly +Here we convert the model of our structure into the internal datatype of diffcheck, DFAssembly. + +

+ +

+ +> DF's components: +> * [`DFAssebmly`](gh_DFBuildAssembly) + +### 3.Preparation of CAD and scan data +We get the pointcloud for the CAD, reduce them to decrease the computation time and compute the normals which is necessary for the next step. + +

+ +

+ +```{hint} +We assume that the tranformation between the scan and the CAD model is known. If this is not the case, refer to the Registration step of the [`Manual Assembly`](manual-assembly.md#3-registration-of-cad-and-scan) +``` + +> DF's components: +> * [`DFBrepToCloud`](gh_DFBrepToCloud) +> * [`DFCloudVoxelDownsample`](gh_DFCloudVoxelDownsample) +> * [`DFCloudNormalEstimator`](gh_DFCloudNormalEstimator) + + +### 4. Segmentation of the scan +We segment the scan to isolate the parts of the raw point cloud of the scan that correspond to each beam of the assembly. + +

+ +

+ +> DF's components: +> * [`DFCloudNormalSegmentator`](gh_DFCloudNormalSegmentator) +> * [`DFRemoveStatisticalOutliers`](gh_DFRemoveStatisticalOutliers) +> * [`DFJointSegmentator`](gh_DFJointSegmentator) +> * [`DFColorizeCloud`](gh_DFColorizeCloud) + +### 5. Error computation +At this point we can compute the error between the CAD model and the scan. The error is computed as the distance between the closest point on the CAD model and the scan. The current DF's output metrics are: + +* *distance* : the distance between the closest point on the CAD model and the scan +* *mean* : the mean distance between the closest point on the CAD model and the scan +* *max_deviation* : the maximum distance between the closest point on the CAD model and the scan +* *min_deviation* : the minimum distance between the closest point on the CAD model and the scan +* *std_deviation* : the standard deviation of the distance between the closest point on the CAD model and the scan + +

+ +

+ +> DF's components: +> * [`DFCloudMeshDistance`](gh_DFCloudMeshDistance) + +### 6. Error Visulization +DF allows you to quickly visualize the errors in the Rhino viewport. The color of the points represents the distance between the CAD model and the scan. The color scale can be adjusted to better visualize the error. We also provide a graph that shows the distribution of the errors. + +

+ +

+ +
+
+ subtr detail +
View of the visualization of the mean error for the analysed clouds on the CAD model itself.
+
+
+ subtr graph +
View of the graph of the corresponding distribution of the mean error directly in Rhino.
+
+
+ +> DF's components: +> * [`DFVisualizationSettings`](gh_DFVisualizationSettings) +> * [`DFVisualization`](gh_DFVisualization) + +### 7. Export the results +The results can be also exported in a CSV file for further analysis or documentation. + +

+ +

+ +The CSV contains the values per element.. + + +| Beam ID | Min Deviation | Max Deviation | Std Deviation | RMSE | Mean | +|---------|---------------|---------------|---------------|-------|-------| +| 0 | 0 | 0.024 | 0.0029 | 0.0045| 0.0034| +| 1 | 0 | 0.0239 | 0.0034 | 0.0057| 0.0046| +| 2 | 0 | 0.0316 | 0.0036 | 0.0056| 0.0042| +| 3 | 0 | 0.024 | 0.0069 | 0.0088| 0.0055| +| 4 | 0 | 0.0117 | 0.0029 | 0.0053| 0.0045| +| 5 | 0 | 0.0242 | 0.0045 | 0.0067| 0.0049| +| ... | ... | ... | ... | ... | ... | + +> DF's components: +> * [`DFCsvExporter`](gh_DFCsvExporter) \ No newline at end of file diff --git a/doc/tutorials.rst b/doc/tutorials.rst index cd093a16..74f12266 100644 --- a/doc/tutorials.rst +++ b/doc/tutorials.rst @@ -4,9 +4,9 @@ diffCheck tutorials =================== .. toctree:: - :maxdepth: 1 + :maxdepth: 2 quickstart key-concepts joints-evaluation - assembly-evaluation \ No newline at end of file + assembly-evaluation diff --git a/src/gh/components/DF_cloud_cloud_distance/code.py b/src/gh/components/DF_cloud_cloud_distance/code.py deleted file mode 100644 index 494c2959..00000000 --- a/src/gh/components/DF_cloud_cloud_distance/code.py +++ /dev/null @@ -1,37 +0,0 @@ -#! python3 - -import System - -import Rhino -from ghpythonlib.componentbase import executingcomponent as component - -from Grasshopper.Kernel import GH_RuntimeMessageLevel as RML - -from diffCheck import df_cvt_bindings -from diffCheck import df_error_estimation - - - -class DFCloudCloudDistance(component): - def RunScript(self, - i_cloud_source: System.Collections.Generic.List[Rhino.Geometry.PointCloud], - i_cloud_target: System.Collections.Generic.List[Rhino.Geometry.PointCloud], - i_swap: bool): - if i_cloud_source is None or i_cloud_target is None: - ghenv.Component.AddRuntimeMessage(RML.Warning, "Please provide both objects of type point clouds to compare") # noqa: F821 - return None - - # swap - if i_swap is True: - temp = i_cloud_source - i_cloud_source = i_cloud_target - i_cloud_target = temp - - # conversion - df_cloud_source_list = [df_cvt_bindings.cvt_rhcloud_2_dfcloud(i_cl_s) for i_cl_s in i_cloud_source] - df_cloud_target_list = [df_cvt_bindings.cvt_rhcloud_2_dfcloud(i_cl_t) for i_cl_t in i_cloud_target] - - # calculate distances - o_results = df_error_estimation.df_cloud_2_df_cloud_comparison(df_cloud_source_list, df_cloud_target_list) - - return o_results.distances, o_results.distances_mean, o_results.distances_rmse, o_results.distances_max_deviation, o_results.distances_min_deviation, o_results.distances_sd_deviation, o_results diff --git a/src/gh/components/DF_cloud_cloud_distance/icon.png b/src/gh/components/DF_cloud_cloud_distance/icon.png deleted file mode 100644 index 1ac97510..00000000 Binary files a/src/gh/components/DF_cloud_cloud_distance/icon.png and /dev/null differ diff --git a/src/gh/components/DF_cloud_cloud_distance/metadata.json b/src/gh/components/DF_cloud_cloud_distance/metadata.json deleted file mode 100644 index 27e3c8da..00000000 --- a/src/gh/components/DF_cloud_cloud_distance/metadata.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "name": "DFCloudCloudDistance", - "nickname": "DFC2CDistance", - "category": "diffCheck", - "subcategory": "Analysis", - "description": "Computes the distance between 2 point clouds", - "exposure": 4, - "instanceGuid": "5e90284b-f932-4617-8740-e9c26a95410c", - "ghpython": { - "hideOutput": true, - "hideInput": true, - "isAdvancedMode": true, - "marshalOutGuids": true, - "iconDisplay": 2, - "inputParameters": [ - { - "name": "i_cloud_source", - "nickname": "i_cloud_source", - "description": "The source point cloud.", - "optional": true, - "allowTreeAccess": true, - "showTypeHints": true, - "scriptParamAccess": "list", - "wireDisplay": "default", - "sourceCount": 0, - "typeHintID": "pointcloud" - }, - { - "name": "i_cloud_target", - "nickname": "i_cloud_target", - "description": "The target cloud.", - "optional": false, - "allowTreeAccess": true, - "showTypeHints": true, - "scriptParamAccess": "list", - "wireDisplay": "default", - "sourceCount": 0, - "typeHintID": "pointcloud" - }, - { - "name": "i_swap", - "nickname": "i_swap", - "description": "whether to swap source and target", - "optional": false, - "allowTreeAccess": false, - "showTypeHints": true, - "scriptParamAccess": "item", - "wireDisplay": "default", - "sourceCount": 0, - "typeHintID": "bool" - } - ], - "outputParameters": [ - { - "name": "o_distances", - "nickname": "o_distances", - "description": "list of calculated distances for each point of the source.", - "optional": false, - "sourceCount": 0, - "graft": false - }, - { - "name": "o_mean", - "nickname": "o_mean", - "description": "The mean of the distances.", - "optional": false, - "sourceCount": 0, - "graft": false - }, - { - "name": "o_rmse", - "nickname": "o_rmse", - "description": "root mean squared error between source and target.", - "optional": false, - "sourceCount": 0, - "graft": false - }, - { - "name": "o_max_deviation", - "nickname": "o_max_deviation", - "description": "max deviation between source and target", - "optional": false, - "sourceCount": 0, - "graft": false - }, - { - "name": "o_min_deviation", - "nickname": "o_min_deviation", - "description": "min deviation between source and target", - "optional": false, - "sourceCount": 0, - "graft": false - }, - { - "name": "o_std_deviation", - "nickname": "o_std_deviation", - "description": "standard deviation between source and target.", - "optional": false, - "sourceCount": 0, - "graft": false - }, - { - "name": "o_result", - "nickname": "o_result", - "description": "The result of the distance calculation.", - "optional": false, - "sourceCount": 0, - "graft": false - } - ] - } -} \ No newline at end of file diff --git a/src/gh/diffCheck/diffCheck/df_error_estimation.py b/src/gh/diffCheck/diffCheck/df_error_estimation.py index c047e4fc..7a9776f1 100644 --- a/src/gh/diffCheck/diffCheck/df_error_estimation.py +++ b/src/gh/diffCheck/diffCheck/df_error_estimation.py @@ -128,14 +128,21 @@ def filter_values_based_on_valuetype(self, settings): def is_source_cloud(self): return type(self.source[0]) is diffcheck_bindings.dfb_geometry.DFPointCloud - -def df_cloud_2_df_cloud_comparison(source_list, target_list): +# FIXME: ths is currently broken, we need to fix it +def df_cloud_2_df_cloud_comparison( + assembly: DFAssembly, + df_cloud_source_list: typing.List[diffcheck_bindings.dfb_geometry.DFPointCloud], + df_cloud_target_list: typing.List[diffcheck_bindings.dfb_geometry.DFPointCloud] + ) -> DFVizResults: """ Compute the Euclidean distance for every point of a source pcd to its closest point on a target pointcloud """ - results = DFVizResults(DFAssembly()) - for source, target in zip(source_list, target_list): + results = DFVizResults( + DFAssembly( + [], "cloud-cloud-dummy-dfassembly" + )) + for source, target in zip(df_cloud_source_list, df_cloud_target_list): distances = np.asarray(source.compute_distance(target)) results.add(source, target, distances) @@ -171,9 +178,6 @@ def rh_cloud_2_rh_mesh_comparison( if swap: source_df, target = target, source_df - # FIXME: this is a hack to avoid that the assembly segmentator breaks this - # snippet because it is not stamping the rhino pout cloud with the sanity check - # user string value. sanity_check_value_uncasted = source_rh.GetUserString("df_sanity_scan_check") sanity_check_value = None if sanity_check_value_uncasted is None: diff --git a/src/gh/diffCheck/diffCheck/df_util.py b/src/gh/diffCheck/diffCheck/df_util.py index b928984c..ba35f5e4 100644 --- a/src/gh/diffCheck/diffCheck/df_util.py +++ b/src/gh/diffCheck/diffCheck/df_util.py @@ -163,40 +163,20 @@ def get_doc_2_meters_unitf(): def merge_shared_indexes(original_dict): """ Merge the shared indexes of a dictionary - Assume we have a dictionary with lists of indexes as values. We want to merge the lists that share some indexes, in order to have a dictionary with, for each key, indexes that are not present under other keys. - :param original_dict: the dictionary to merge :return: the merged dictionary """ - merged_dict = {} - index_to_key = {} + new_dict = {} for key, (face, indexes) in original_dict.items(): - merged_indexes = set(indexes) - keys_to_merge = set() - - for index in indexes: - if index in index_to_key: - keys_to_merge.add(index_to_key[index]) - - for merge_key in keys_to_merge: - merged_indexes.update(merged_dict[merge_key][1]) - # del merged_dict[merge_key] - - for index in merged_indexes: - index_to_key[index] = key - - merged_dict[key] = (face, list(merged_indexes)) - - keys_with_duplicates = {} - - for key in merged_dict.keys(): - for other_key, (face, indexes) in merged_dict.items(): - if key in indexes: - if key not in keys_with_duplicates: - keys_with_duplicates[key] = [] - keys_with_duplicates[key].append(other_key) - - return merged_dict + intersection_found = False + for other_key, (other_face, other_indexes) in original_dict.items(): + if key != other_key: + if set(indexes).intersection(set(other_indexes)): + new_dict[key] = (face, list(set(indexes).union(set(other_indexes)))) + intersection_found = True + if not intersection_found: + new_dict[key] = (face, indexes) + return new_dict