Skip to content
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

Combine nodes #151

Merged
merged 6 commits into from
Aug 1, 2016
Merged

Combine nodes #151

merged 6 commits into from
Aug 1, 2016

Conversation

lasalvavida
Copy link
Contributor

Adds stage to flatten node hierarchies where possible. Reciprocating saw screenshot attached for comparison.

saw-comparison

@lilleyse Could you look at this when you get a chance?

@pjcozzi
Copy link
Contributor

pjcozzi commented Jul 31, 2016

@lasalvavida does this replace #51? Is any of this code based on #51?

Have you tested on a variety of models, including ones where some sub-trees can be combined and some can't?

@lasalvavida
Copy link
Contributor Author

No, none of this is based on #51. I'm pretty sure I've handled all of the edge cases. I used reciprocating saw as an example here because CAD models typically have repeated meshes/overlapping mesh data which are the two cases where primitives can't be transformed and passed up the node tree.

I have tested on:
Cesium Balloon,
Cesium Milk Truck,
2 Cylinder Engine,
Buggy,
BrainStem,
Reciprocating Saw

"mime": "1.3.4",
"mkdirp": "0.5.1",
"object-values": "1.0.0",
"promise": "7.1.1",
"underscore": "^1.8.3",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the carets from these.

@lilleyse
Copy link
Contributor

lilleyse commented Aug 1, 2016

Testing looks good from my end too.

@lasalvavida
Copy link
Contributor Author

Updated

@lilleyse lilleyse merged commit 08c9e4e into master Aug 1, 2016
@lilleyse lilleyse deleted the combine-nodes branch August 1, 2016 19:04
@lasalvavida lasalvavida mentioned this pull request Aug 1, 2016
1 task
'use strict';
var Cesium = require('cesium');
var jp = require('jsonpath');
var _ = require('underscore');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mramato is it standard practice to use the name _ here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, yes. It's the same idea as using $ for jquery, which I also hate. That being said, I would strongly suggest not depending on underscore, there is absolutely no reason that I know of to use it over native JavaScript functions.

Copy link
Contributor

@pjcozzi pjcozzi Aug 2, 2016 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does have a deep comparison _.equals which is really what I'm using it for. We have rewritten that function so many times in this library, I figured it might be best to try to consolidate it to a third party utility.

@mramato I'm fine with using a different node module for deep equals, rolling our own or just keeping underscore, whatever you think is best practice here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also _.range is useful for generating indices.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Underscore is an old, traditionally browser-based library meant to make up for missing features of the browser API and incompatibility from platform to platform. For Node.js, there is only a single platform and 99% of functionality is either directly supported by the native API or is otherwise only a couple of lines of code. Here's an article that tries to lay out some examples: https://www.reindex.io/blog/you-might-not-need-underscore/ That article does use some ES2015 examples, which technically we can't use yet, but it's really just shorthand for stuff that can be done in ES5 already. We should never use a library if there is an equivalent native API already available, it just makes the code slower and less uniform.

As for equals, I don't see it actually being called anywhere in this PR, but if we really need a deep equality function, something like https://www.npmjs.com/package/deep-equal is probably a better choice. Also, if we are only using deep-equal in tests, then there's already jasimine.toEqual and assert.equals

Normally, we avoid generic deep comparisons in our code and prefer implementing custom equals functions directly (such as Matrix4.equals for example) because they are way faster. If we need to compare completely unknown blobs, then of course we may need to have generic comparisons, but since gltf is a known schema, I'm not sure of why that would be the case.

Copy link
Contributor Author

@lasalvavida lasalvavida Aug 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using _.isEqual and _.find to search for duplicate primitives in an array. That was something else -> optimizing array searching.

I'll take a look around though and see if there's some better choices for that as well. ES2015 will resolve this, but for now we will need some other utility.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than deep-equals, I'm not sure why we would need any other libraries. .find is just a for loop with a break statement. It provides no benefit. We already have binarySearch in Cesium if your arrays are sorted. If they aren't sorted, then there is no "optimized" search method; it's always a linear search.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, you're right. I thought maybe they were doing a randomized search, which is more optimal than linear for non-sorted data, but it is just linear.

@pjcozzi
Copy link
Contributor

pjcozzi commented Aug 1, 2016

@tfili can you please review the test cases in combineNodesSpec.js and see if we missed any from your experience with COLLADA?

@pjcozzi
Copy link
Contributor

pjcozzi commented Aug 1, 2016

Consider adding one more unit tests that is more like a "system test" that tests several scenarios within one node hierarchy where some sub-trees can be combined and some can't. Verify that it is as aggressive as possible above and below the roots of the sub-trees that can't be merged into their parent.

Along these lines, can siblings be merged, e.g.,?

n0
|
+- n1
|
+- n2
|
+- n3

If n3 can't be merged into n0, for example, can n1 and n2 be combined (assuming compatibility) so that n0 only has two children?

@lasalvavida
Copy link
Contributor Author

If n1 and n2 can be combined, their meshes will be transformed and passed to n0. Then n1 and n2 will have no children and no meshes, so they will be removed and n0 will have one child: n3.

@@ -0,0 +1,367 @@
'use strict';
var Cesium = require('cesium');
var jp = require('jsonpath');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variable names should always match module names.

@pjcozzi
Copy link
Contributor

pjcozzi commented Aug 2, 2016 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants