patterncsharpMinor
Get every information about the Reservation
Viewed 0 times
thereservationeverygetaboutinformation
Problem
I'm developing a plugin for Revit (a software to make 3D buildings).
The goal is simple to understand. When there is an intersection between a Wall and a Duct I create an object called Reservation at this location. I need to extract the Curve of the Ducts and the Faces of the Walls in order to calculate this intersection.
My algorithm is working fine and fast with a small building (3 Ducts, 10 Walls and 8 intersections) But when I want to launch it on a real project (around 10 000 Ducts) the code is way too slow due to many ForEach loops. Here is the sample which cause the issue:
```
foreach (Duct d in ducts)
{
Curve ductCurve = FindDuctCurve(d);
curves.Add(ductCurve);
foreach (Wall w in walls)
{
wallFaces = FindWallFace(w);
foreach (Curve c in curves)
{
foreach (Face f in wallFaces)
{
foreach (KeyValuePair pair in FindInterWalls(c, f, walls))
{
Reservation.Res res = new Reservation.Res();
res.RoundCenter = new XYZ(Math.Round(pair.Key.X), Math.Round(pair.Key.Y), Math.Round(pair.Key.Z));
res.WallWidth = pair.Value.Width;
bool containsItemX = resList.Any(itemX => itemX.RoundCenter.DistanceTo(res.RoundCenter) < res.WallWidth + 1);
if (containsItemX == false)
{
res.AssociatedWall = pair.Value;
res.Radius = 1;
res.AssociatedDuct = d;
res.Center = pair.Key;
resList.Add(res);
model.Reservations.Add(new Reservation { ResList = resLi
The goal is simple to understand. When there is an intersection between a Wall and a Duct I create an object called Reservation at this location. I need to extract the Curve of the Ducts and the Faces of the Walls in order to calculate this intersection.
My algorithm is working fine and fast with a small building (3 Ducts, 10 Walls and 8 intersections) But when I want to launch it on a real project (around 10 000 Ducts) the code is way too slow due to many ForEach loops. Here is the sample which cause the issue:
```
foreach (Duct d in ducts)
{
Curve ductCurve = FindDuctCurve(d);
curves.Add(ductCurve);
foreach (Wall w in walls)
{
wallFaces = FindWallFace(w);
foreach (Curve c in curves)
{
foreach (Face f in wallFaces)
{
foreach (KeyValuePair pair in FindInterWalls(c, f, walls))
{
Reservation.Res res = new Reservation.Res();
res.RoundCenter = new XYZ(Math.Round(pair.Key.X), Math.Round(pair.Key.Y), Math.Round(pair.Key.Z));
res.WallWidth = pair.Value.Width;
bool containsItemX = resList.Any(itemX => itemX.RoundCenter.DistanceTo(res.RoundCenter) < res.WallWidth + 1);
if (containsItemX == false)
{
res.AssociatedWall = pair.Value;
res.Radius = 1;
res.AssociatedDuct = d;
res.Center = pair.Key;
resList.Add(res);
model.Reservations.Add(new Reservation { ResList = resLi
Solution
I hope I have understood this now.
Instead of iterating over all the
now we iterate once over all of the
then we need to adjust the remaining code to use the
Instead of iterating over all the
Duct items and adding each iteration the related Curve to curves you should create another class like public class DuctCurev
{
public Duct TheDuct {get; private set; }
public Curve TheCurve {get; private set; }
public DuctCurve(Duct duct, Curve curve)
{
TheDuct = duct;
TheCurve = curve;
}
}now we iterate once over all of the
Duct's and find the related Curve which we will add to a List like so List ductCurves = new List();
foreach (Duct d in ducts)
{
ductCurves.Add(d, FindDuctCurve(d));
}then we need to adjust the remaining code to use the
ductCurves and use the ! operator instead of using containsItemX == false like soforeach (Wall w in walls)
{
wallFaces = FindWallFace(w);
foreach (DuctCurve dc in ductCurves)
{
foreach (Face f in wallFaces)
{
foreach (KeyValuePair pair in FindInterWalls(dc.Curve, f, walls))
{
Reservation.Res res = new Reservation.Res();
res.RoundCenter = new XYZ(Math.Round(pair.Key.X), Math.Round(pair.Key.Y), Math.Round(pair.Key.Z));
res.WallWidth = pair.Value.Width;
bool containsItemX = resList.Any(itemX => itemX.RoundCenter.DistanceTo(res.RoundCenter) < res.WallWidth + 1);
if (!containsItemX)
{
res.AssociatedWall = pair.Value;
res.Radius = 1;
res.AssociatedDuct = dc.Duct;
res.Center = pair.Key;
resList.Add(res);
model.Reservations.Add(new Reservation { ResList = resList });
}
}
}
}
}Code Snippets
public class DuctCurev
{
public Duct TheDuct {get; private set; }
public Curve TheCurve {get; private set; }
public DuctCurve(Duct duct, Curve curve)
{
TheDuct = duct;
TheCurve = curve;
}
}List<DuctCurve> ductCurves = new List<DuctCurve>();
foreach (Duct d in ducts)
{
ductCurves.Add(d, FindDuctCurve(d));
}foreach (Wall w in walls)
{
wallFaces = FindWallFace(w);
foreach (DuctCurve dc in ductCurves)
{
foreach (Face f in wallFaces)
{
foreach (KeyValuePair<XYZ, Wall> pair in FindInterWalls(dc.Curve, f, walls))
{
Reservation.Res res = new Reservation.Res();
res.RoundCenter = new XYZ(Math.Round(pair.Key.X), Math.Round(pair.Key.Y), Math.Round(pair.Key.Z));
res.WallWidth = pair.Value.Width;
bool containsItemX = resList.Any(itemX => itemX.RoundCenter.DistanceTo(res.RoundCenter) < res.WallWidth + 1);
if (!containsItemX)
{
res.AssociatedWall = pair.Value;
res.Radius = 1;
res.AssociatedDuct = dc.Duct;
res.Center = pair.Key;
resList.Add(res);
model.Reservations.Add(new Reservation { ResList = resList });
}
}
}
}
}Context
StackExchange Code Review Q#132195, answer score: 3
Revisions (0)
No revisions yet.