| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
This allows keeping its functionality together and gives us the ability to copy it separately when needed, avoiding a copy of the entire surface data. This was the case in `MakeFirstOrderRevolvedSurfaces()` as well as in `SplitInHalf()` -- both of which have been converted to work on the curve data alone.
|
This may avoid copying a few bytes here and there (as in SplitInHalf) but in my opinion it is not worth it. The many curve. and to a lesser extent Curve:: that appear are ugly and cause "churn" see my comment about it here. However if you have an example model where profiling shows that this change causes a significant speed up or is on the critical path we should consider it. |
Sorry, something went wrong.
|
@iscgar Are you saying that SplitInHalf is doing a deep copy of all the trims? That should not be happening, but if it is we should fix it for performance reasons. BTW we don't care about copying the color or handle, that's very minor. My biggest with this issue is that names are important. In Solvespace a curve is a one-dimensional curve either in a plane or in 3d space. A surface is a 2-D surface in 3-D space. We don't want to use curve terminology for a surface data structure - that's just confusing. Second complaint is that this just takes more text to specify a piece of data. Almost every line of the diff is just adding the extra colons and the word "curve" to the code. |
Sorry, something went wrong.
Right now this is indeed only copying a few additional bytes because copying a List<T> is a shallow operation which does not copy the stored items, as List<T> requires an explicit call to .Clear() in order to destroy the items and free the memory. But as I noted in my reply to your comment there, I'm working on reworking the way List<T> and IdList<T> are implemented in order to speed them up and reduce memory usage. This includes making List<T> an owner of its memory and responsible for tracking and releasing it, and therefore a copy of it performs a deep copy of its underlying storage instead of just copying a pointer. As part of that change I also made the following conversions to code that copied List<T>:
In that context, copying the entire SSurface struct can become a heavy operation if there are many edges or trims, and neither of the aforementioned conversions could work in the two cases that are mentioned in the commit message, so I resorted to refactoring the curve data into its own struct in order to allow working on it without running into the potential performance issue.
As I explained above, no deep copy is performed with the existing code.
Both valid points, and I fully accept your reservations (especially in light of @ruevs 's comment in the other PR about avoiding disturbing the existing code as much as possible). However, assuming my reason for making this change seems reasonable, I'm open to suggestions for a better term, or to thinking of other ways to achieve the same result without introducing another nesting level. |
Sorry, something went wrong.
This reverts commit 258c669.
You will not be the first one ;-) with help, ideas and inspiration from: @Evil-Spirit In general keep in mind these when working on performance: Test models to profile with: Last time I profiled (about half an year ago, but nothing performance related has changed since) neither List nor IdList were a bottleneck. For example on this #759 (comment) most of the time was spent on axis aligned bounding boxes :-) A torture test model for IdList is here: and one more: More wisdom from @rpavlik (shallow copy is intentional) #932 (comment) Test and profile with various models in release mode (with optimisations on and debug info for profiling). A debug build is no indication at all about the real performance and bottlenecks. In short - I'm very exited that you have started looking deeply into SolveSpace and am very curious what will come out of it. What platform are you on? |
Sorry, something went wrong.
|
@ruevs thanks for the links to past discussions and ideas! I've seen some of them, but definitely not all of them. I'll make sure to take the information in them into account before I submit my work. I'm on Linux, but I'm also running on Windows every once in a while. |
Sorry, something went wrong.
In `MakeFirstOrderRevolvedSurfaces()` as well as in `SplitInHalf()` a full copy of `SSurface` is made even though only a small part of it is needed. Change the code to copy only the necessary data.
|
I added a different approach to achieve the same result, which hopefully addresses the concerns raised (assuming such a change seems reasonable despite not having an impact on the existing implementation). I intentionally did it by adding a revert commit and then the new approach, so that the two approaches could be compared easily. If the change is acceptable, I'll remove the first two commits. |
Sorry, something went wrong.
|
One possible reason to put the raw Rational Bezier Surface data into a separate struct within SSurface would be to abstract the underlying surface type (later - much much later) so someone could implement other types of surfaces, or just more generalized NURBS surfaces. So if we allowed that, there must be a mathematical word for "the surface that the trim polygon defines a subset of". We'd want to name it that instead of curve (It must not be curve! ;) and maybe use an abbreviation. |
Sorry, something went wrong.
|
I only used Curve because I didn't want to add to the confusion by having a a type named Surface nested inside SSurface, but if an abbreviation is acceptable, the type can just be RationalBezierSurface and the member abbreviated to rbs. But that's assuming we indeed want to go this way instead of just changing the two places where this will become relevant with my other changes. |
Sorry, something went wrong.
Here is a model SSurface::AllPointsIntersecting
and then in:
SSurface::AllPointsIntersectingUntrimmed
ClosestPointTo(p, &u, &v);
Vector tryp = PointAt(tryu, tryv);
As you can see currently the bottleneck is not SplitInHalf but in SSurface::ClosestPointTo -> SSurface::PointAt. Unfortunately nothing can be done about SSurface::PointAt (at least that I can think of). The recursive AllPointsIntersectingUntrimmed that does the SplitInHalf is more interesting. Comenting out the 5 debug lines starting with this one: solvespace/src/srf/raycast.cpp Line 215 in bd7b627 Reduces the loading time from 15.1s to 13.9s on my machine. The critical path is still the same, but a bit faster. @phkahler perhaps we should #ifdef DEBUG those lines? |
Sorry, something went wrong.
|
From a performance perspective, I think optimizing low level data structures is a waste of time. Even the OpenMP stuff is kind of a hack (but a really good one). The real performance problems come from algorithms that are O(n^2) and higher. The fix for those things will be a spatial index to reduce the number of things tested against other things. I've got an index in mind but using that would make the code more complex and harder to fix the bugs we still have in the NURBS code. We're still in the "make it work right" phase but some "make it fast" changes are still OK. BTW a major bottleneck for a lot of things is the silhouette edges being rendered. Turn those of in the GUI ;-) Even the first item in the old wishlist is related to algorithmic complexity. That is still an O(n^2) algorithm. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
This allows keeping its functionality together and gives us the ability to copy it separately when needed, avoiding a copy of the entire surface data.
This was the case in MakeFirstOrderRevolvedSurfaces() as well as in SplitInHalf() -- both of which have been converted to work on the curve data alone.