DynamoDS / Dynamo

Open Source Graphical Programming for Design
https://dynamobim.org
Other
1.74k stars 634 forks source link

Question: Is Parallel Computing / Multithreading for operations on ProtoGeometry objects possible? #5899

Closed hasanayan closed 8 years ago

hasanayan commented 8 years ago

I am working on a ZeroTouchNode that takes a group of object and makes countless surface subtraction using their geometries. Currently the performance is terrible and I am planning to implement parallel computing. Is there a reason I shouldn't? I am guessing once I get the geometry objects from the elements, I will be done with RevitAPI and I can run ProtoGeometry object functions as parallel.

Also, I did not get the part about Dispose()'ing objects used in ZeroTouchPackages. Can you please check if I need to use Dispose anywhere in the following function:

 public Geometry  SplitSurfaceUsingSolidExtraction(Geometry surface, List<Geometry> tools)
        {          
            Geometry result = surface;

            foreach (Solid tool in tools)
            {
                Geometry[] a = ((Surface)result).SubtractFrom(tool);  
                if (a.Length ==0)
                {
                    return null;
                }
                else
                {
                    result =a[0];
                }
            }
            return result;
        }
mjkkirschner commented 8 years ago

using parallel foreach might help, you have to balance the number of threads and size of the jobs. I've tried previously to speed up large numbers of intersections with varying success using parallel foreach and loops.

Yes you need to dispose all intermediate geometry, in this case, that is all geometry objects that were set to result, but were not returned while the loop executes. (since you continually set the value of this variable) The easiest thing to do is to save all these results to another list like oldGeometry, and then dispose this at the end of the function before returning, you can also make sure not to dispose any object that you are about to return.

also, in terms of speed - casting to surface in a tight loop that you are trying to parallelize should be avoided if you can.

hasanayan commented 8 years ago

@mjkkirschner thanks for the comments. I will revisit my code to check the things you have commented on. I have a few questions. Your help really matters especially since you have done this before; 1) how can I prevent casting to Surface in my code? The only option seem using Geometry.Split() method using geometries. But I am not sure about how it works and the size of the result list is variable. I observed four cases; a-Returns a the input surface back when there is no intersection, b-Returns 2 surfaces, 1st being the remainder after the splitting operation, 2nd being the rest of the input surface c-Returns 2 surfaces, but both are the same as the input surface (happens when the tool completely overlaps the input surface) d-Returns 3 surfaces, this happens -sometimes- when my input surface and tool surface are perpendicular to each other and intersecting on the edge. However, my desired resulting surface can be the first or the second.

Can you help me locate the source code of SubtractFrom() and Split() methods? So that I can have a better understanding of the methods.

So can you please tell me is it worth using Geometry.Split(Geometry, Geometry) and checking for all these conditions instead of casting geometry to surface and using Surface.SubtractFrom(Solid)?

ikeough commented 8 years ago

Please post this question to the Dynamo forums