[HM3D Annotation] --HM3D SSD file support; Misc SSD Fixes#1556
[HM3D Annotation] --HM3D SSD file support; Misc SSD Fixes#1556jturner65 merged 12 commits intofacebookresearch:mainfrom
Conversation
6db6032 to
e771709
Compare
mosra
left a comment
There was a problem hiding this comment.
Didn't really go through everything because the colormap/objectID-generating code may need some further work.
| float colorMapOffset, | ||
| float colorMapScale) { | ||
| float colorMapOffset = -1.0f, | ||
| float colorMapScale = -1.0f) { |
There was a problem hiding this comment.
Negative offset and scale also makes sense (for example to flip the colormap), to convey the optionality and that the values are expected to either be both set or both not, I'd use Cr::Containers::Optional<std::pair<float, float>> instead.
Hm, actually, having default values in an internal (PIMPL) API doesn't sound like a good idea. This should have no default values and the default values should be handled in the public Renderer interface instead. That way you also don't need the overload without the offset/scale parameters.
| } | ||
| shader->setColorMapTransformation(colorMapOffset, colorMapScale); | ||
| if ((colorMapOffset >= 0) && (colorMapScale >= 0)) { | ||
| shader->setColorMapTransformation(colorMapOffset, colorMapScale); |
There was a problem hiding this comment.
Hmm... You're not recreating the shader here every time you render, so if you don't set these values every time, it will stay at whatever value it was set to before, instead of the 1.0f/512.0f and 1.0f/256.0f defaults you probably expected, leading to strange different behavior depending on the order in which you switch the colormap visualization.
There was a problem hiding this comment.
As we discussed :) the semantic visualization and the depth visualization each use different instances of TextureVisualizerShader and different compiled frag shader programs. Because of this (that both use cases have their own ShaderProgram and compiled frag shader) they do not "cross-pollinate" their values, so it is reasonable to assume that these values will not need to be reset on subsequent draws.
| */ | ||
| TextureVisualizerShader& setColorMapTexture( | ||
| Corrade::Containers::ArrayView<const Magnum::Vector3ub> colorMap, | ||
| bool wrapEdges, |
There was a problem hiding this comment.
Boolean function parameters are an API smell in languages that don't have the concept of named parameters. I'd expose the Mn::SamplerWrapping type directly.
I'm also not sure about the offset/scale parameters. Why not just let the caller call also setColorMapTransformation()? There the parameters are documented and the responsibility/interaction is clear, now it's a bit unclear how the two functions affect each other.
There was a problem hiding this comment.
I'm also not sure about the offset/scale parameters. Why not just let the caller call also
setColorMapTransformation()? There the parameters are documented and the responsibility/interaction is clear, now it's a bit unclear how the two functions affect each other.
Originally the code was set up to fully instantiate the ShaderProgram through the constructor (including setting these values) instead of having a secondary call to setColorMapTransformation for these individual values. I tried to keep my refactoring to the existing code as minimal as possible, but if you think this should be changed, i'm all for it.
| * the ObjectId texture, resulting value is then used to fetch a color from a | ||
| * color map bound with bindColorMapTexture(). Here we use the Magnum built-in | ||
| * color map: Magnum::DebugTools::ColorMap::turbo(); | ||
| * color map bound with bindColorMapTexture(). Here we use either the Magnum |
There was a problem hiding this comment.
This whole comment is wrong :) Here's no bindColorMapTexture(), only rebindColorMapTexture(), and the shader is also not responsible for picking the Turbo color map anymore, that's supplied via setColorMapTexture().
Skylion007
left a comment
There was a problem hiding this comment.
Looks good with @mosra 's changes.
| if (objectIdToObjectData.find(objectId) == objectIdToObjectData.end()) { | ||
| if (splitMesh && | ||
| (parseResult->objIdsFromPly || parseResult->objPartitionsFromSSD)) { | ||
| std::vector<uint16_t> meshPartitionIds = parseResult->objIdsFromPly |
There was a problem hiding this comment.
not supposed to 😄 that's embarassing. Holy cow that was expensive.
There was a problem hiding this comment.
This is by the way why Containers::Array was made non-copyable -- to prevent accidents like this. And writing an explicit Utility::copy() is annoying enough to make you think twice if you really need to copy :)
| // temporary map keyed by semantic ID and value being actual color for | ||
| // that ID. We need this since we do not know how many, if any, unique | ||
| // colors that do not have Semantic Mappings exist on the mesh | ||
| std::unordered_map<int, Mn::Vector3ub> tmpDestSSDColorMap; |
There was a problem hiding this comment.
Instead of this, why not resize() the colorMapToUse to id + 1 that you're about to insert, and then colorMapToUse[id] = stuff directly? You're copying this to a linear array after anyway so this won't save anything.
There was a problem hiding this comment.
id is different for each vert - can get smaller, so don't want to resize colorMapToUse smaller than it was for some previous vert. Still though, I can get rid of the next step and go directly into the colormap.
There was a problem hiding this comment.
Err, I meant this:
if(colorMapToUse.size() <= id) colorMapToUse.resize(id + 1);
colorMapToUse[id] = stuff;Using a hashmap for something that's basically contiguous indexing doesn't seem right to me :)
| std::pair<Cr::Containers::Array<Mn::UnsignedInt>, std::size_t> out = | ||
| Mn::MeshTools::removeDuplicatesInPlace( | ||
| Cr::Containers::arrayCast<2, char>( | ||
| stridedArrayView(colorsThatBecomeTheColorMap))); |
There was a problem hiding this comment.
I still have a feeling that populating a unique color array could be done directly in the above loop, unifying the handling... :)
There was a problem hiding this comment.
Sure, we could only conditionally build the tmpColorMapToSSDidAndRegionIndex if the ssd mapping exists. If it is empty, it would make a map full of "non-ssd" colors.
Using this code path for this case would be slower than what we are doing now, and less elegant than the solution using the magnum tools.
8310853 to
22ea32d
Compare
9b3bc89 to
22ea32d
Compare
|
This looks like the Simulator is segfaulting or failing some other way when loading the WebGL build. |
eundersander
left a comment
There was a problem hiding this comment.
I left some comments.
| std::vector<uint16_t> partitionIds; | ||
| }; | ||
|
|
||
| Cr::Containers::Optional<InstancePlyData> parsePly( |
There was a problem hiding this comment.
GenericInstanceMeshData looks to be a pretty simple container for mesh data. Would it make sense to keep this class simple and move all your annotation-parsing logic to a separate class and file?
Related: it would help if this class GenericInstanceMeshData had a class-level comment. Its parent class says "Base class for storing mesh asset data including geometry and topology" and I so wouldn't expect such a class to know e.g. the details of region indices in annotation data.
There was a problem hiding this comment.
We have a long-term vision to move more of our core/generic rendering code back into the Magnum repo (e.g. PbrDrawable), so I'm interested to keep our very application-specific code (like annotation-parsing) separate.
There was a problem hiding this comment.
GenericInstanceMeshData looks to be a pretty simple container for mesh data. Would it make sense to keep this class simple and move all your annotation-parsing logic to a separate class and file?
This class was always used for the semantic mesh processing - the annotation code that I added just adds flexibility for different ply formats than just the hard-coded mp3d support.
For long-term handling considerations, i see this class holding only specialized annotation information (if that - i can see a future without it too) while the general mesh data would be handled by GenericMeshData, if not Mn::Trade::MeshData directly.
Related: it would help if this class GenericInstanceMeshData had a class-level comment. Its parent class says "Base class for storing mesh asset data including geometry and topology" and I so wouldn't expect such a class to know e.g. the details of region indices in annotation data.
I can certainly more clearly comment the purpose of this class. Ultimately, from an organizational standpoint, (as I said earlier) it would probably be better if this class only held semantic-specific functionality, expanding on existing whatever MeshData structure ended up being the backbone for this class.
A little bit of redesign/refactor would pay big dividends in this department, but I felt such engineering overhead was beyond the scope of this PR.
There was a problem hiding this comment.
I felt such engineering overhead was beyond the scope of this PR
I will push back a little here on the idea "refactors are out of scope". You're adding nearly 1000 lines of code in this PR. I believe we should view such large changes as opportunities to refactor, rather than piling on more tech debt to an area of code that we already regard as needing refactor.
it would probably be better if this class only held semantic-specific functionality
Consider renaming the class in this case.
There was a problem hiding this comment.
I will push back a little here on the idea "refactors are out of scope". You're adding nearly 1000 lines of code in this PR. I believe we should view such large changes as opportunities to refactor, rather than piling on more tech debt to an area of code that we already regard as needing refactor.
I completely share your concerns, and normally would be in total agreement regarding addressing refactors and tech-debt whenever possible.
However, the support for the Appen annotated hm3d meshes was presented to me as being urgent, and so I approached implementation as the priority. Refactors were restricted to what was necessary to support the new functionality in as generalized a way as possible while not breaking existing code (theoretically) and addressing some of the brittleness inherent in the old designs. There's very little tech debt that's been added - the new functionality is required for hm3d annotation support, so any future reworks are going to need it on some level; some (very small amount) of tech debt has been removed, and, unfortunately a lot of debt remains.
This affected how multiple classes performed their duties:
- Renderer (instance shaders on construction instead of the previous method of create shader on first visualize call, expand colormap support)
- GenericMeshLoading (support multiple vert color formats, support no baked-in ids, better multi-mesh culling support)
- Sim/ResourceManager (create SemanticScene descriptor in resource manager to make available during Semantic Scene mesh load)
Consider renaming the class in this case
Good idea.
22ea32d to
0fcf7c0
Compare
0fcf7c0 to
ebaf56a
Compare
|
Most recent force-push changed how shaders were loading. Loading them in the Renderer constructor (as this PR previously introduced) was not compatible with the current Javascript code protocols, so this mechanism was removed and the existing on-demand instancing is being used instead. |
ab9b613 to
96dc6e1
Compare
mosra
left a comment
There was a problem hiding this comment.
Two minor things + the unresolved color map map issue I asked about on Slack. Other than that looks good :)
| SHIFT-RIGHT: | ||
| Click a mesh to highlight it. | ||
| CTRL-RIGHT: | ||
| CTRL-RIGHT:m |
|
|
||
| std::vector<std::unique_ptr<GenericSemanticMeshData>> | ||
| GenericSemanticMeshData::buildSemanticMeshData( | ||
| const Cr::Containers::Optional<Mn::Trade::MeshData>& srcMeshData, |
There was a problem hiding this comment.
No Optional here please :) The code of the function assumes the optional is non-null anyway.
8c4b416 to
8812142
Compare
Motivation and Context
This PR adds the following functionality for SSD support :
What's left is appropriate bindings and tests.
How Has This Been Tested
Locally C++ and Python tests.
Types of changes
Checklist