# MeshTools: adding generateSmoothNormals() and some more things #229

Merged
merged 9 commits into from May 28, 2019

## Conversation

Projects
3 participants
Owner

### mosra commented Feb 19, 2018 • edited

 Stashing my brain here so I don't forget the particulars. Started out as a discussion on the DART integration PR (mosra/magnum-integration#29), with the following code snippet, extracted from DART itself, with a goal to make this testable: ```static Eigen::Vector3d normalFromVertex(const dart::dynamics::SoftBodyNode* bn, const Eigen::Vector3i& face, std::size_t v) { const Eigen::Vector3d& v0 = bn->getPointMass(face[v])->getLocalPosition(); const Eigen::Vector3d& v1 = bn->getPointMass(face[(v+1)%3])->getLocalPosition(); const Eigen::Vector3d& v2 = bn->getPointMass(face[(v+2)%3])->getLocalPosition(); const Eigen::Vector3d dv1 = v1-v0; const Eigen::Vector3d dv2 = v2-v0; const Eigen::Vector3d n = dv1.cross(dv2); double weight = n.norm()/(dv1.norm()*dv2.norm()); weight = std::max( -1.0, std::min( 1.0, weight) ); return n.normalized() * asin(weight); } static void computeNormals(std::vector& normals, const dart::dynamics::SoftBodyNode* bn) { for(std::size_t i=0; igetNumFaces(); ++i) { const Eigen::Vector3i& face = bn->getFace(i); for(std::size_t j=0; j<3; ++j) normals[face[j]] += normalFromVertex(bn, face, j); } for(std::size_t i=0; i

Merged

### mosra added some commits Apr 13, 2019

``` MeshTools: make a version of duplicate() not dependent on std::vector. ```
```Provide a version taking StridedArrayView instead, taking an arbitrary
view and also arbitrary index type. Also introduce duplicateInto() which
doesn't even allocate, but rather writes the output to pre-existing
location.```
``` 61397af ```
``` MeshTools: de-STL-ify generateFlatNormals(). ```
```Also move it to a new GenerateNormals.h header so we can easily add
generateSmoothNormals() to it. The old API and header is deprecated and
will be removed in the future. I can't be bothered rewriting the old
code using the new thing, so it's preserved there as a mausoleum until
it gets finally nuked from the orbit.```
``` 1de258a ```
``` MeshTools: ability to generate flat normals in compile(). ```
``` d20a17c ```
``` MeshTools: minor cleanup. ```
``` 7b24161 ```
``` MeshTools: added generateSmoothNormals(). ```
`This was a *fun* algorithmic exercise. Seriously.`
``` a4310b9 ```
``` MeshTools: Primitives are now always needed for the tests. ```
`The new generateSmoothNormals() needs it.`
``` 247dff2 ```

### mosra added some commits May 27, 2019

``` MeshTools: benchmark generate{Flat,Smooth}Normals(). ```
```There's some room for improvement so I want to be able to see the
difference.```
``` 32da5d7 ```
``` MeshTools: cache angles and cross product in generateSmoothNormals(). ```
```It allocates one more array, but that speeds up the calculation to twice
as fast. Before the benchmark was around 1 ms for flat normals and 12 ms
for smooth, now it's 6 ms for smooth. There is probably more I could do
(I feel like I could save at least one more normalization), however this
is good enough for now.```
``` ba048cd ```
``` MeshTools: ability to generate smooth normals in compile(). ```
``` 5d2cf7e ```

Owner Author

### mosra commented May 27, 2019

 This was a fun algorithmic exercise -- and I dare to say the implementation is much more efficient than what DART is attempting to do in the above snippet. Waiting on the CIs to get green, then it goes to master! @costashatz I don't really remember the original discussion, is there any place in `DartIntegration` where this could get used?
Contributor

### costashatz commented May 28, 2019

 @costashatz I don't really remember the original discussion, is there any place in `DartIntegration` where this could get used? Yes of course! It can be used for the Soft objects: right now, we are creating the faces twice, see here. I am putting it on my TO-DO list.. Thanks for reminding..
Owner Author

### mosra commented May 28, 2019

 As you said there, that would still need to implement some facet orientation fixer, right? Or did DART get fixed in the meantime? The thing igl uses (paper) is our method is very simple but by simple they mean it depends on the whole of Embree 😅 ... so I guess we would need to implement something actually simple. Another option I can think of is, instead of duplicating all faces, making the Phong shader optionally double-sided, but that would be even less performant I think.

### mosra merged commit `5d2cf7e` into master May 28, 2019 3 of 4 checks passed

#### 3 of 4 checks passed

continuous-integration/travis-ci/push The Travis CI build is in progress
Details
continuous-integration/appveyor/branch AppVeyor build succeeded
Details
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

# Codecov Report

Merging #229 into master will decrease coverage by `2.96%`.
The diff coverage is `97.2%`.

```@@            Coverage Diff             @@
##           master     #229      +/-   ##
==========================================
- Coverage    74.3%   71.34%   -2.97%
==========================================
Files         346      347       +1
Lines       16430    17542    +1112
==========================================
+ Hits        12209    12515     +306
- Misses       4221     5027     +806```
Impacted Files Coverage Δ
src/Magnum/MeshTools/CompressIndices.cpp `93.75% <ø> (-2.68%)` ⬇️
src/Magnum/MeshTools/Compile.h `100% <100%> (ø)`
src/Magnum/MeshTools/Duplicate.h `100% <100%> (ø)` ⬆️
src/Magnum/MeshTools/Compile.cpp `79.31% <94%> (+4.78%)` ⬆️
src/Magnum/MeshTools/GenerateNormals.cpp `98.71% <98.71%> (ø)`
src/Magnum/DebugTools/BufferData.cpp `80% <0%> (-20%)` ⬇️
src/Magnum/Audio/Source.h `82.85% <0%> (-17.15%)` ⬇️
src/Magnum/GL/Implementation/RendererState.h `33.33% <0%> (-16.67%)` ⬇️
src/Magnum/Trade/CameraData.cpp `83.33% <0%> (-16.67%)` ⬇️
src/Magnum/GL/AbstractShaderProgram.h `75% <0%> (-16.31%)` ⬇️
... and 130 more

`Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`