Skip to content

Commit 884239d

Browse files
committed
refactor: optimize bounding box calculations by transforming corners individually
- handle OrientedBoundingBox
1 parent cc98ce4 commit 884239d

File tree

2 files changed

+60
-39
lines changed

2 files changed

+60
-39
lines changed

source/RevitDevTool/Visualization/Helpers/RenderHelper.cs

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -361,21 +361,24 @@ public static void MapMeshGridBuffer(RenderingBufferStorage buffer, Mesh mesh, d
361361
/// using its associated transformation matrix before being processed.</param>
362362
public static void MapBoundingBoxSurfaceBuffer(RenderingBufferStorage buffer, BoundingBoxXYZ box)
363363
{
364-
var minPoint = box.Transform.OfPoint(box.Min);
365-
var maxPoint = box.Transform.OfPoint(box.Max);
366-
367-
XYZ[] corners =
364+
// Generate 8 corners in LOCAL coordinate system first
365+
XYZ[] localCorners =
368366
[
369-
new(minPoint.X, minPoint.Y, minPoint.Z),
370-
new(maxPoint.X, minPoint.Y, minPoint.Z),
371-
new(maxPoint.X, maxPoint.Y, minPoint.Z),
372-
new(minPoint.X, maxPoint.Y, minPoint.Z),
373-
new(minPoint.X, minPoint.Y, maxPoint.Z),
374-
new(maxPoint.X, minPoint.Y, maxPoint.Z),
375-
new(maxPoint.X, maxPoint.Y, maxPoint.Z),
376-
new(minPoint.X, maxPoint.Y, maxPoint.Z)
367+
new(box.Min.X, box.Min.Y, box.Min.Z), // 0: min corner
368+
new(box.Max.X, box.Min.Y, box.Min.Z), // 1
369+
new(box.Max.X, box.Max.Y, box.Min.Z), // 2
370+
new(box.Min.X, box.Max.Y, box.Min.Z), // 3
371+
new(box.Min.X, box.Min.Y, box.Max.Z), // 4
372+
new(box.Max.X, box.Min.Y, box.Max.Z), // 5
373+
new(box.Max.X, box.Max.Y, box.Max.Z), // 6: max corner
374+
new(box.Min.X, box.Max.Y, box.Max.Z) // 7
377375
];
378376

377+
// Transform each corner individually to world coordinates
378+
XYZ[] corners = localCorners
379+
.Select(corner => box.Transform.OfPoint(corner))
380+
.ToArray();
381+
379382
int[] triangles =
380383
[
381384
0, 1, 2, 2, 3, 0, // bottom face
@@ -431,21 +434,24 @@ public static void MapBoundingBoxSurfaceBuffer(RenderingBufferStorage buffer, Bo
431434
/// vertex positions.</param>
432435
public static void MapBoundingBoxEdgeBuffer(RenderingBufferStorage buffer, BoundingBoxXYZ box)
433436
{
434-
var minPoint = box.Transform.OfPoint(box.Min);
435-
var maxPoint = box.Transform.OfPoint(box.Max);
436-
437-
XYZ[] corners =
437+
// Generate 8 corners in LOCAL coordinate system first
438+
XYZ[] localCorners =
438439
[
439-
new(minPoint.X, minPoint.Y, minPoint.Z),
440-
new(maxPoint.X, minPoint.Y, minPoint.Z),
441-
new(maxPoint.X, maxPoint.Y, minPoint.Z),
442-
new(minPoint.X, maxPoint.Y, minPoint.Z),
443-
new(minPoint.X, minPoint.Y, maxPoint.Z),
444-
new(maxPoint.X, minPoint.Y, maxPoint.Z),
445-
new(maxPoint.X, maxPoint.Y, maxPoint.Z),
446-
new(minPoint.X, maxPoint.Y, maxPoint.Z)
440+
new(box.Min.X, box.Min.Y, box.Min.Z), // 0: min corner
441+
new(box.Max.X, box.Min.Y, box.Min.Z), // 1
442+
new(box.Max.X, box.Max.Y, box.Min.Z), // 2
443+
new(box.Min.X, box.Max.Y, box.Min.Z), // 3
444+
new(box.Min.X, box.Min.Y, box.Max.Z), // 4
445+
new(box.Max.X, box.Min.Y, box.Max.Z), // 5
446+
new(box.Max.X, box.Max.Y, box.Max.Z), // 6: max corner
447+
new(box.Min.X, box.Max.Y, box.Max.Z) // 7
447448
];
448449

450+
// Transform each corner individually to world coordinates
451+
var corners = localCorners
452+
.Select(corner => box.Transform.OfPoint(corner))
453+
.ToArray();
454+
449455
int[] edges =
450456
[
451457
0, 1, 1, 2, 2, 3, 3, 0, // bottom face

source/RevitDevTool/Visualization/Server/BoundingBoxVisualizationServer.cs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,37 @@ public sealed class BoundingBoxVisualizationServer : VisualizationServer<Boundin
4747
{
4848
if (VisualizeGeometries.Count == 0) return null;
4949

50-
var minPoints = VisualizeGeometries
51-
.Select(box => box.Min)
52-
.OrderBy(point => point.X)
53-
.ThenBy(point => point.Y)
54-
.ThenBy(point => point.Z);
55-
var maxPoints = VisualizeGeometries
56-
.Select(box => box.Max)
57-
.OrderByDescending(point => point.X)
58-
.ThenByDescending(point => point.Y)
59-
.ThenByDescending(point => point.Z);
60-
var minPoint = minPoints.FirstOrDefault();
61-
var maxPoint = maxPoints.FirstOrDefault();
62-
if (minPoint is null || maxPoint is null)
63-
return new Outline(XYZ.Zero, XYZ.Zero);
50+
var allTransformedPoints = new List<XYZ>();
6451

65-
return new Outline(minPoint, maxPoint);
52+
foreach (var box in VisualizeGeometries)
53+
{
54+
// Generate all 8 corners in local coordinate system and transform them
55+
XYZ[] localCorners =
56+
[
57+
new(box.Min.X, box.Min.Y, box.Min.Z),
58+
new(box.Max.X, box.Min.Y, box.Min.Z),
59+
new(box.Max.X, box.Max.Y, box.Min.Z),
60+
new(box.Min.X, box.Max.Y, box.Min.Z),
61+
new(box.Min.X, box.Min.Y, box.Max.Z),
62+
new(box.Max.X, box.Min.Y, box.Max.Z),
63+
new(box.Max.X, box.Max.Y, box.Max.Z),
64+
new(box.Min.X, box.Max.Y, box.Max.Z)
65+
];
66+
67+
var transformedCorners = localCorners
68+
.Select(corner => box.Transform.OfPoint(corner));
69+
allTransformedPoints.AddRange(transformedCorners);
70+
}
71+
72+
// Find actual min/max from all transformed points
73+
var minX = allTransformedPoints.Min(p => p.X);
74+
var minY = allTransformedPoints.Min(p => p.Y);
75+
var minZ = allTransformedPoints.Min(p => p.Z);
76+
var maxX = allTransformedPoints.Max(p => p.X);
77+
var maxY = allTransformedPoints.Max(p => p.Y);
78+
var maxZ = allTransformedPoints.Max(p => p.Z);
79+
80+
return new Outline(new XYZ(minX, minY, minZ), new XYZ(maxX, maxY, maxZ));
6681
}
6782

6883
public override void RenderScene(Autodesk.Revit.DB.View view, DisplayStyle displayStyle)

0 commit comments

Comments
 (0)