Repository: BAMWelDX/weldx

Issue:
closed mesh generation for default geometries
update the `util.triangulate_geometry` to (optionally) close the triangulation around all sides for default groove geometries

Discussion:
review-notebook-app[bot]: Check out this pull request on&nbsp; <a href="https://app.reviewnb.com/BAMWelDX/weldx/pull/414"><img align="absmiddle"  alt="ReviewNB" height="28" class="BotMessageButtonImage" src="https://raw.githubusercontent.com/ReviewNB/support/master/images/button_reviewnb.png"/></a> 

 See visual diffs & provide feedback on Jupyter Notebooks. 

---

 <i>Powered by <a href='https://www.reviewnb.com/?utm_source=gh'>ReviewNB</a></i>
codecov[bot]: # [Codecov](https://codecov.io/gh/BAMWelDX/weldx/pull/414?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX) Report
> Merging [#414](https://codecov.io/gh/BAMWelDX/weldx/pull/414?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX) (1512a0e) into [master](https://codecov.io/gh/BAMWelDX/weldx/commit/047d699408d191999bbbda5a77162cc4407264b5?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX) (047d699) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/BAMWelDX/weldx/pull/414/graphs/tree.svg?width=650&height=150&src=pr&token=wdof1qQTsn&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX)](https://codecov.io/gh/BAMWelDX/weldx/pull/414?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX)

```diff
@@           Coverage Diff           @@
##           master     #414   +/-   ##
=======================================
  Coverage   97.27%   97.27%           
=======================================
  Files          87       87           
  Lines        5352     5367   +15     
=======================================
+ Hits         5206     5221   +15     
  Misses        146      146           
```


| [Impacted Files](https://codecov.io/gh/BAMWelDX/weldx/pull/414?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX) | Coverage Δ | |
|---|---|---|
| [weldx/geometry.py](https://codecov.io/gh/BAMWelDX/weldx/pull/414/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX#diff-d2VsZHgvZ2VvbWV0cnkucHk=) | `99.56% <100.00%> (+<0.01%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/BAMWelDX/weldx/pull/414?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/BAMWelDX/weldx/pull/414?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX). Last update [047d699...1512a0e](https://codecov.io/gh/BAMWelDX/weldx/pull/414?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=BAMWelDX).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4bf0cca..99fae28 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,26 @@
 # Release Notes
 
+## 0.4.1 (unreleased)
+
+### added
+
+- `closed_mesh` parameter to `Geometry.spatial_data`
+  and `SpatialData.from_geometry_raster` [[#414]](https://github.com/BAMWelDX/weldx/pull/414)
+
+### removed
+
+### changes
+
+### fixes
+
+### documentation
+
+### ASDF
+
+### deprecations
+
+### dependencies
+
 ## 0.4.0 (13.07.2021)
 
 Release `0.4.0` brings many new major features to `weldx`
diff --git a/weldx/geometry.py b/weldx/geometry.py
index 275e86b..7412c9b 100644
--- a/weldx/geometry.py
+++ b/weldx/geometry.py
@@ -2254,11 +2254,14 @@ class Geometry:
 
     @UREG.wraps(
         None,
-        (None, _DEFAULT_LEN_UNIT, _DEFAULT_LEN_UNIT),
+        (None, _DEFAULT_LEN_UNIT, _DEFAULT_LEN_UNIT, None),
         strict=False,
     )
     def spatial_data(
-        self, profile_raster_width: pint.Quantity, trace_raster_width: pint.Quantity
+        self,
+        profile_raster_width: pint.Quantity,
+        trace_raster_width: pint.Quantity,
+        closed_mesh: bool = True,
     ):
         """Rasterize the geometry and get it as `SpatialData` instance.
 
@@ -2266,10 +2269,12 @@ class Geometry:
 
         Parameters
         ----------
-        profile_raster_width : pint.Quantity
+        profile_raster_width :
             Target distance between the individual points of a profile
-        trace_raster_width : pint.Quantity
+        trace_raster_width :
             Target distance between the individual profiles on the trace
+        closed_mesh :
+            If `True`, the surface of the 3d geometry will be closed
 
         Returns
         -------
@@ -2288,7 +2293,7 @@ class Geometry:
         rasterization = self.rasterize(
             profile_raster_width, trace_raster_width, stack=False
         )
-        return SpatialData.from_geometry_raster(rasterization)
+        return SpatialData.from_geometry_raster(rasterization, closed_mesh)
 
 
 # SpatialData --------------------------------------------------------------------------
@@ -2352,13 +2357,17 @@ class SpatialData:
         return SpatialData(mesh.points, triangles)
 
     @staticmethod
-    def from_geometry_raster(geometry_raster: np.ndarray) -> "SpatialData":
+    def from_geometry_raster(
+        geometry_raster: np.ndarray, closed_mesh: bool = True
+    ) -> "SpatialData":
         """Triangulate rasterized Geometry Profile.
 
         Parameters
         ----------
         geometry_raster : numpy.ndarray
             A single unstacked geometry rasterization.
+        closed_mesh :
+            If `True`, the surface of the 3d geometry will be closed
 
         Returns
         -------
@@ -2374,12 +2383,31 @@ class SpatialData:
             return SpatialData(*ut.triangulate_geometry(geometry_raster))
 
         part_data = [ut.triangulate_geometry(part) for part in geometry_raster]
-
         total_points = []
         total_triangles = []
-        for points, triangulation in part_data:
+        for i, (points, triangulation) in enumerate(part_data):
             total_triangles += (triangulation + len(total_points)).tolist()
+            if closed_mesh:
+                # closes side faces
+                i_p1 = len(total_points)
+                i_p2 = i_p1 + len(geometry_raster[i][0][0]) - 1
+                i_p3 = i_p1 + len(points) - 1
+                i_p4 = i_p3 - len(geometry_raster[i][-1][0]) + 1
+                total_triangles += [[i_p1, i_p2, i_p3], [i_p3, i_p4, i_p1]]
+
+                # closes front and back faces
+                def _triangulate_profile(p_0, p_1):
+                    triangles = []
+                    while p_1 > p_0:
+                        triangles += [[p_0, p_1, p_1 - 1], [p_1 - 1, p_0 + 1, p_0]]
+                        p_0 += 1
+                        p_1 -= 1
+                    return triangles
+
+                total_triangles += _triangulate_profile(i_p1, i_p2)
+                total_triangles += _triangulate_profile(i_p4, i_p3)
             total_points += points.tolist()
+
         return SpatialData(total_points, total_triangles)
 
     def plot(


Test patch:
diff --git a/weldx/tests/test_geometry.py b/weldx/tests/test_geometry.py
index ab3d4c7..cfbb1f5 100644
--- a/weldx/tests/test_geometry.py
+++ b/weldx/tests/test_geometry.py
@@ -2863,7 +2863,7 @@ class TestGeometry:
             instance
 
         """
-        spatial_data = geometry.spatial_data(p_rw, t_rw)
+        spatial_data = geometry.spatial_data(p_rw, t_rw, closed_mesh=False)
         assert len(spatial_data.coordinates.data) == exp_num_points
 
         num_triangles = 0