Skip to content

Commit b16d661

Browse files
committed
Merge branch 'main' into 39-better-ui-icons-for-grasshopper-components
2 parents 5fbf0c3 + f205939 commit b16d661

File tree

38 files changed

+12378
-3873
lines changed

38 files changed

+12378
-3873
lines changed

assets/img/fig_scheme_softarch.png

138 KB
Loading

doc/_static/fig_scheme_softarch.png

138 KB
Loading

doc/change_log.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

doc/df_architecture.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
11
(df_architecture_guide)=
22
# diffCheck architecture
33

4-
/// more info and details about how the diffCheck architecture works as a plugin
4+
The software architecture of DF is organized into three main sections.
5+
* a) **C++**:
6+
The first foundational portion of the source code is represented by a C++ umbrella library regrouping low-level dependencies such as *Open3d*, *CGAL* and *Cilantro* which power the back-end of the most complex and demanding computational functionalities DF can offer.
7+
* b) **PythonAPI**:
8+
The previous portion portion is wrapped into the second DF's component: an API written in Python 3.9.1 and distributed via PyPI (Python Package Index).
9+
* c) **GHPlugin**:
10+
Finally, the GH Python-based plug-in represents only the top-level visual scripting DF's interface.
11+
12+
Here is a diagram of the software architecture:
13+
14+
<br>
15+
16+
<p align="center">
17+
<img src="_static/fig_scheme_softarch.png" style="background-color: transparent; width: 100%; max-width: 800px;" />
18+
</p>
19+
20+
<br>
21+
22+
With Rhino v.8’s integration of CPython into its .NET ecosystem, we developed a fully Python-based Grasshopper plug-in. Distributed through Rhino’s Yak manager, it requires no extra installations. Inspired by the Compas framework, the plug-in is composed entirely of .ghuser objects, supporting CI practices with automatic component documentation. Additionally, we believe a Python-based plug-in encourages broader contributions, as Python’s simplicity and widespread use make it more accessible to the digital fabrication community.

doc/gh_DFMergeAssemblies.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.. image:: ../src/gh/components/DF_merge_assemblies/icon.png
2+
:align: left
3+
:width: 40px
4+
5+
``DFMergeAssemblies`` component
6+
===============================
7+
8+
.. ghcomponent_to_rst:: ../src/gh/components/DF_merge_assemblies

doc/gh_components.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ DF has a Grasshopper_ plugin with a set of components that allows the user to in
8181
- .. image:: ../src/gh/components/DF_remove_statistical_outliers/icon.png
8282
- `gh_DFRemoveStatisticalOutliers <gh_DFRemoveStatisticalOutliers.html>`_
8383

84+
* - .. image:: ../src/gh/components/DF_merge_assemblies/icon.png
85+
- `gh_DFMergeAssemblies <gh_DFMergeAssemblies.html>`_
86+
-
87+
-
8488

8589

8690
.. toctree::
@@ -113,4 +117,6 @@ DF has a Grasshopper_ plugin with a set of components that allows the user to in
113117
gh_DFPreviewAssembly
114118
gh_DFRemoveBeam
115119
gh_DFColorizeCloud
116-
gh_DFBrepToCloud
120+
gh_DFBrepToCloud
121+
gh_DFRemoveStatisticalOutliers
122+
gh_DFMergeAssemblies

doc/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ The software is developed by the `Laboratory of Timber Construction (IBOIS)`_ an
170170
diffCheck_PythonAPI
171171
dev_documentation
172172
glossary
173-
change_log
174173

175174

176175
.. _Laboratory of Timber Construction (IBOIS): https://www.epfl.ch/labs/ibois/

src/diffCheck/geometry/DFMesh.cc

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,31 +112,67 @@ namespace diffCheck::geometry
112112
Eigen::Vector3d v1 = this->Vertices[triangle[1]];
113113
Eigen::Vector3d v2 = this->Vertices[triangle[2]];
114114
Eigen::Vector3d n = (v1 - v0).cross(v2 - v0);
115-
double normOfNormal = n.norm();
116115
n.normalize();
117116

118-
Eigen::Vector3d projectedPoint = point - n * (n.dot(point - v0)) ;
117+
// Project the point onto the plane of the triangle
118+
Eigen::Vector3d projectedPoint = point - n * (n.dot(point - v0));
119119

120-
double referenceTriangleArea = normOfNormal*0.5;
121-
Eigen::Vector3d n1 = (v1 - v0).cross(projectedPoint - v0);
122-
double area1 = n1.norm()*0.5;
123-
Eigen::Vector3d n2 = (v2 - v1).cross(projectedPoint - v1);
124-
double area2 = n2.norm()*0.5;
125-
Eigen::Vector3d n3 = (v0 - v2).cross(projectedPoint - v2);
126-
double area3 = n3.norm()*0.5;
127-
double res = (area1 + area2 + area3 - referenceTriangleArea) / referenceTriangleArea;
120+
// Compute vectors
121+
Eigen::Vector3d v0v1 = v1 - v0;
122+
Eigen::Vector3d v0v2 = v2 - v0;
123+
Eigen::Vector3d v0p = projectedPoint - v0;
128124

129-
// arbitrary value to avoid false positives (points that, when projected on the triangle, are in it, but that are actually located too far from the mesh to actually belong to it)
130-
double maxProjectionDistance = std::min({(v1 - v0).norm(), (v2 - v1).norm(), (v0 - v2).norm()}) / 2;
125+
// Compute dot products
126+
double dot00 = v0v2.dot(v0v2);
127+
double dot01 = v0v2.dot(v0v1);
128+
double dot02 = v0v2.dot(v0p);
129+
double dot11 = v0v1.dot(v0v1);
130+
double dot12 = v0v1.dot(v0p);
131131

132-
if (std::abs(res) < associationThreshold && (projectedPoint - point).norm() < maxProjectionDistance)
132+
// Compute barycentric coordinates
133+
double invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
134+
double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
135+
double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
136+
137+
// Check if point is in triangle
138+
if ((u >= -associationThreshold) && (v >= -associationThreshold) && (u + v <= 1 + associationThreshold))
133139
{
134-
return true;
140+
// Check if the point is close enough to the face
141+
double maxProjectionDistance = std::min({(v1 - v0).norm(), (v2 - v1).norm(), (v0 - v2).norm()}) ;
142+
if ((projectedPoint - point).norm() < maxProjectionDistance)
143+
{
144+
return true;
145+
}
135146
}
136147
}
137148
return false;
138149
}
139150

151+
std::tuple<Eigen::Vector3d, Eigen::Vector3d> DFMesh::ComputeOBBCenterAndAxis()
152+
{
153+
Eigen::Vector3d center = Eigen::Vector3d::Zero();
154+
Eigen::Vector3d axis = Eigen::Vector3d::Zero();
155+
156+
std::vector<Eigen::Vector3d> tightBoundingBox = this->GetTightBoundingBox();
157+
158+
Eigen::Vector3d deltaFirstDir = tightBoundingBox[1] - tightBoundingBox[0];
159+
Eigen::Vector3d deltaSecondDir = tightBoundingBox[2] - tightBoundingBox[0];
160+
Eigen::Vector3d deltaThirdDir = tightBoundingBox[3] - tightBoundingBox[0];
161+
162+
for (Eigen::Vector3d direction : {deltaFirstDir, deltaSecondDir, deltaThirdDir})
163+
{
164+
if (direction.norm() > axis.norm())
165+
{
166+
axis = direction;
167+
}
168+
}
169+
axis.normalize();
170+
171+
center = tightBoundingBox[0] + deltaFirstDir/2 + deltaSecondDir/2 + deltaThirdDir/2;
172+
173+
return std::make_tuple(center, axis);
174+
}
175+
140176
void DFMesh::LoadFromPLY(const std::string &path)
141177
{
142178
std::shared_ptr<diffCheck::geometry::DFMesh> tempMesh_ptr = diffCheck::io::ReadPLYMeshFromFile(path);

src/diffCheck/geometry/DFMesh.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ namespace diffCheck::geometry
8686
*/
8787
bool IsPointOnFace(Eigen::Vector3d point, double associationThreshold = 0.1);
8888

89+
/**
90+
* @brief Get the center and main axis of oriented boundung box of the mesh. It was developped for the cylinder case, but can be used for other shapes.
91+
*
92+
* @return std::tuple<Eigen::Vector3d, Eigen::Vector3d> the first element is the center of the obb of the mesh, the second element is the main axis of the obb of the mesh
93+
*/
94+
std::tuple<Eigen::Vector3d, Eigen::Vector3d> ComputeOBBCenterAndAxis();
95+
8996
public: ///< I/O loader
9097
/**
9198
* @brief Read a mesh from a file

0 commit comments

Comments
 (0)