Hi,
I am working on a component in C# in Visual Studio and am running to a bit of an optimization problem I don’t quite know how to approach. The component runs an operation on a brep input with item access - the subtractFrom
input in the code snippet below - with a set of breps with list access - the subtractWith
input. I am trying to improve compute times when working with very large data sets, specifically when the breps with list access stay the same but I feed in more than one brep into the subtractFrom
input with item access, which I believe causes grasshopper’s automatic list matching to duplicate some calculations unnecessarily.
Specifically what I am trying to improve is when I am converting the list of subtractWith
breps to my custom class BrepBB
in the solve instance in the code below. The constructor that I am using calculates a bounding box for the brep and holds it alongside the brep so that I don’t have to compute it over and over later in the script. That in itself isn’t a problem, but the problem is that when I am inputting a list into subtractFrom
which I’ve only given item access, the BrepBB
constructor that is being fed the data from subtractWith
is being duplicated for every item in the subtractFrom
list. If the subtractFrom
input has 1000 items in it, I beileive the constructor is being run 999 more times than necessary due to longest list data matching or similar.
What I would like to do instead is have the breps converted to my BrepBB
class immediately on input and before any longest list matching or the like is done in the component so that the constructor can just run a single time per data input. I considered giving the subtractFrom
data list access, but I am running the code multi-threaded and that would put all of the calculations onto a single thread with how it is currenlty opperating.
I hope all of that made sense. If anyone know how this is done, It would be greatly appreciated!
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
{
pManager.AddBrepParameter("Subtract From", "A", "Set to subtract from.", GH_ParamAccess.item);
pManager.AddBrepParameter("Subtract With", "B", "Set to subtract with.", GH_ParamAccess.list);
pManager.AddNumberParameter("Tolerance", "T", "Subtraction tolerance", GH_ParamAccess.item, DocumentTolerance());
pManager.AddBooleanParameter("Strict", "S", "True to check for true interesection, false to only check bounding boxes", GH_ParamAccess.item, false);
pManager.AddBooleanParameter("Accurate Bounding", "C", "true to compute accurate bounding boxes", GH_ParamAccess.item, false);
}
/// <summary>
/// Registers all the output parameters for this component.
/// </summary>
protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
{
pManager.AddBrepParameter("Result", "R", "Subtraction result.", GH_ParamAccess.list);
}
protected override void SolveInstance(IGH_DataAccess DA)
{
if (InPreSolve)
{
//Fist Pass; collect input data
Brep subtractFromTemp = new Brep();
DA.GetData(0, ref subtractFromTemp);
List<Brep> subtractWithTemp = new List<Brep>();
DA.GetDataList(1, subtractWithTemp);
double tol = DocumentTolerance();
DA.GetData(2, ref tol);
bool strict = new bool();
DA.GetData(3, ref strict);
bool accurate = new bool();
DA.GetData(4, ref accurate);
BrepBB subtractFrom = new BrepBB(subtractFromTemp, accurate);
List<BrepBB> subtractWith = new List<BrepBB>();
{
foreach (Brep b in subtractWithTemp)
{
subtractWith.Add(new BrepBB(b, accurate)); //this code runs more than necessary
}
}
//Queue up the task
Task<SolveResults> task = Task.Run(() => ComputeDifference(subtractFrom, subtractWith, tol, strict, accurate), CancelToken);
TaskList.Add(task);
return;
}
if (!GetSolveResults(DA, out SolveResults result))
{
//Compute right here; collect input data
Brep subtractFromTemp = new Brep();
DA.GetData(0, ref subtractFromTemp);
List<Brep> subtractWithTemp = new List<Brep>();
DA.GetDataList(1, subtractWithTemp);
double tol = DocumentTolerance();
DA.GetData(2, ref tol);
bool strict = new bool();
DA.GetData(3, ref strict);
bool accurate = new bool();
DA.GetData(4, ref accurate);
BrepBB subtractFrom = new BrepBB(subtractFromTemp, accurate);
List<BrepBB> subtractWith = new List<BrepBB>();
{
foreach (Brep b in subtractWithTemp)
{
subtractWith.Add(new BrepBB(b, accurate)); //this code runs more than necessary
}
}
//Compute results on given data
result = ComputeDifference(subtractFrom, subtractWith, tol, strict, accurate);
}
//Set output data
if (result != null)
{
List<Brep> brepResults = new List<Brep>();
foreach(BrepBB brepResult in result.Subtracted)
{
brepResults.Add(brepResult.Brep);
}
DA.SetDataList("Result", brepResults);
}
}