How would I get the dimensions of a selected object which are scaled to the units set in the document?
So far I’ve got the selected objects with the code below:
var filter = new ObjectEnumeratorSettings {SelectedObjectsFilter = true};
var selectedObjects = RhinoDoc.ActiveDoc.Objects.FindByFilter(filter);
But now I’d like to iterate through the selectedObjects and get the length and width scaled to the documents units. The object may have curvature, so the length and width should be surface length and width.
The plugin is for ship designers, and what I’m trying to do is get the length and width, and will also need to get the curvature of selected parts of the hull. You’re right, in that the length and width should be as if the surface were flattened. The curvature is actually the the highest point along the arc of the surface between two end points i.e.
After speaking with a colleague, I think I’ve got this sorted. To get the length and width I use a bounding box:
if (!(rhinoObject is BrepObject brepObject)) return;
var boundingBox = brepObject.BrepGeometry.GetBoundingBox(true);
var corners = boundingBox.GetCorners();
var minX = corners[0].X;
var minZ = corners[0].Z;
var maxX = corners[2].X;
var maxZ = corners[4].Z;
var boxWidth = maxX - minX;
var boxHeight = maxZ - minZ;
// assume document units are mm
var boxWidthInMeters = boxWidth / 1000;
var boxHeightInMeters = boxHeight / 1000;
I realise that this doesn’t take into account curvature, but this is accurate enough for the moment. Interestingly I had to set accurate to true in the call to BrepGeometry.GetBoundingBox otherwise the bounding box dimensions were wildly inaccurate!
To get the curvature height:
get the center of the bounding box
creating a plane on the center and along the x axis
intersect the object with this plane
get the first intersecting curve
create a line from the curve start point to the end point
divide the curve into 20 segments
for each segment calculate the distance (height) between the curve and the line
get the maximum from the heights
var center = boundingBox.Center;
var centerPlane = new Plane(center, new Vector3d(1, 0, 0));
const double tolerance = 100d;
if (!Intersection.BrepPlane(brepObject.BrepGeometry,
centerPlane,
tolerance,
out var intersectionCurves,
out _))
return;
var curve = intersectionCurves.FirstOrDefault();
if (curve == null) return;
var line = new Line(curve.PointAtStart, curve.PointAtEnd);
var curveParameters = curve.DivideByCount(20, true);
var curveHeights = curveParameters
.Select(curveParameter => curve.PointAt(curveParameter))
.Select(point => line.DistanceTo(point, true))
.ToList();
var maxHeight = curveHeights.Max();
This seems to be giving valid results, but would be interested to know if I’ve missed something?