-
Notifications
You must be signed in to change notification settings - Fork 635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DYN-2538 Generate single RenderPackage per Node #11395
DYN-2538 Generate single RenderPackage per Node #11395
Conversation
…ng the description field
… render package per node vs per node return obj
…labels vs the cryptic use of Description.
… public prop with Helix types
…usage of the color methods in IRenderPackage
…or methods in tessellation calls. If Detected, revert changes to render package and generate a new render package with legacy methods per IGraphicItem.
@aparajit-pratap one downside of marking this PR as a draft is that the tests do not run - we'd have to modify the code that runs on the self serve pull job - and I think it makes use of https://github.com/microsoft/PowerShellForGitHub ... I gave up once I got that far. |
@saintentropy it would be good to run the wpf visualization test jobs - there are versions of that job that run with warp and another that runs on a real GPU - these do image comparisons so should be useful. |
} | ||
} | ||
|
||
private void GetTessellationDataFromGraphicItem(Guid outputPortId, IGraphicItem graphicItem, IRenderPackage package, string labelKey) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think package
should be passed as a ref
parameter as it can be assigned a new object inside the function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely! Good catch
@saintentropy thanks for addressing the review comments and adding inline documentation. Also thanks for clearer names for the new APIs. I have just two remaining questions, then LGTM. |
Hi @aparajit-pratap Added some of fixes from the comments and a lot more tests |
I also added the single item label fix. The regression was introduced in this PR -> #10989. That PR also added the non-functional DisplayLabel node back into core so this PR fixes both the node and the label regression. |
@saintentropy when I saw your visualization tests I remembered you could also add image comparison tests that @mjkkirschner introduced here https://github.com/DynamoDS/Dynamo/blob/master/src/VisualizationTests/HelixImageComparisonTests.cs. This could be especially useful for the texture map graph you showed with the 3 surfaces. It doesn't have to be in this PR, can be a separate one as we discussed. |
try | ||
{ | ||
p.AppendMeshVertexColorRange(testColors); | ||
} | ||
catch(Exception e) | ||
{ | ||
Assert.AreEqual(e.GetType(), typeof(Exception)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assert.ThrowsException<Exception>(() => p.AppendMeshVertexColorRange(testColors));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are these exceptions dealt with in Dynamo in a real situation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the exceptions (my new ones and the old ones) within the RenderPacakge
implementation are caught here -> https://github.com/DynamoDS/Dynamo/blob/master/src/DynamoCore/Scheduler/UpdateRenderPackageAsyncTask.cs#L303. The net affect is that the node does not display geometry in the background preview.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only difference in the new implementation is the specific handling of the LegacyRenderPackageMethodException
{ | ||
p.AppendLineVertexColorRange(testColors); | ||
} | ||
catch (Exception e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make these exceptions thrown be more specific? In the implementation I mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I can cover these in the next PR as I add more test coverage.
Purpose
Note: I was cleaning up my Dynamo git stash over the holiday break and this was too good to leave on the shelf. This builds on some work that @LongNguyenP, @Dewb, @aparajit-pratap, and I looked at a while back. I picked up and fixed the regressions we noted previously.
The purpose of this PR is a performance and memory optimization for the render pipeline. The main architectural change is modifying the assumption that we generate a single
RenderPackage
object per every individual return object for a node. Instead we aggregate all node tessellation data into a singleRenderPackage
recursively. This improves tessellation performance as theHelixRenderPackage
is a large .NET object with a non-trivial init time in addition to a large saving in memory; specifically one render package with all the tessellation data is much smaller then many render packages with partial tessellation data. This approach also creates performance benefit and memory savings when the tessellated data is added to the Helix scene. Processing one RenderPackage perAggregateRenderPackages
call is dramatically more efficient than multiple render packages as there are numerous collection interactions and temporary allocation. In code, this change was enabled by generating the RenderPackage first inGetRenderPackagesFromMirrorData
before the recursive loop to fill the render package data. Previously it was generated within the loop.There are a few things that require changes to support features which assumed a single item = a single RenderPackage.
Labels (ie the labels that appear in the scene context by selecting items in the node preview). The existing implementation encoded label information in the
Description
property of theRenderPackage
. That encoding was not well documented making it nearly impossible to add labels to the your own tessellation method overrides. Here I introduce a new interface,IRenderLabels
, which provides methods on the render package to add label data and placement. The new underlying storage implementation matches the existingLabelPlaces
data structure in theHelixWatch3DViewModel
so that adding labels requires much less string parsing and processing.Texture maps. The original texture map implementation in the
Colors
andColorStride
property assumed only one texture map per the mesh geometry in theRenderPackage
. To support aggregation of multiple mesh geometries within a singleRenderPackage
with unique textures, I introduce a new interface,IRenderPackageSupplement
, which supports adding lists of Colors and ColorStrides along with their associated mesh vertex ranges. TheColors
andColorStride
property as well as theSetColors
method are marked as obsolete with notes to use the new methods in theIRenderPackageSupplement
.Color adding methods on
IRenderPackage
. While methods to add vertex color likeAddPointVertexColor
still work fine with this change, when utilized in tessellation calls, methods likeApplyPointVertexColors
overwrite the previous data vs appending. That can cause data loss as they are currently used. I introduce new methods toIRenderPackageSupplement
likeInsertPointVertexColorRange
andAppendPointVertexColorRange
to allow additions without overwriting existing data. The old methods are also marked as obsolete with notes to use the new methods in theIRenderPackageSupplement
. The GeometryColor nodes are updated to use the new methods.These new features are being introduced with a minor release and not Dynamo 3.0. While we can update the tessellation implementation in Dynamo and Dynamo integrations, Third Party tessellation functions also need to stay working. For each of the Obsolete methods above I introduced an Exception to allow the
GetRenderPackagesFromMirrorData
implementation to detect their usage. Specifically withinIRenderPackageSupplement
there is a booleanAllowLegacyColorOperations
that can be set to false which will cause theLegacyRenderPackageMethodException
to be thrown when the obsolete methods are called. In that case, we roll back any changes to theRenderPackage
that occurred within theTesselate
call and generate a newRenderPackage
withAllowLegacyColorOperations
set to true and re-Tesselate. This individual render package is added to the RenderPackageCache and the outer loop resumes. In the transition to Dynamo 3.0, the obsolete methods can be removed as well as this fallback.Todo
Examples
PointsNew.mp4
PointsOld.mp4
LinesNew.mp4
LinesOld.mp4
For most point and curve tessellation the speed and memory improvement will be linear based on the number of tessellated items. However for meshes the speed and memory improvement is dramatic. The original implementation would take exponentially longer to add mesh geometry to the scene depending on the number of items. This refactor restores performance to a linear relationship
Declarations
Check these if you believe they are true
*.resx
filesReviewers
@mjkkirschner @aparajit-pratap @QilongTang