I’m trying to place an object at the bottom of a cuboid, but I don’t know how. I manage to put it at the top and in the center, but don’t seem to find a way to put it at the bottom… Does anyone know how?
Construct a point as follows:
X value = (Minimum Point X value + Maximum point X value) /2
Y value = (Minimum Point Y value + Maximum point Y value) /2
Z value = Minimum Point Z value
That will be bottom center of the cuboid.
You can also use this method with the min/max point of a bounding box around any object, technically.
I’m not sure i follow how to connect the nodes (I’m new to Dynamo). This is the script I made earlier about putting an object at roof height.
Assuming your cuboid is aligned to the world axes (at least on the XY plane), then you’ll have 4 points that makeup the bottom surface. Get the 4 corner points with the lowest Z value and get the average of the points.
For a generic case that looks at any surface alignment, check out this recent thread:
Cannot get base of all generic masses - Revit - Dynamo
Geometry.Explode
will convert the solid cuboid into a list of surfaces.Surface.NormalAtParameter
with U and V parameters of 0.5 will give you the normal at the center of each surface.Vector.Z
will give you the Z component of those vectors. This will be a value between -1 (the surface is facing down and therefore the bottom) and 1 (the surface is facing up and therefore the top), where values of zero are vertical (the surfaces are facing out and therefore are sides)List.SortByKey
will now allow you to sort the list of surfaces (from theGeometry.Explode
node) by the key of the respective Z component of their normal. Be sure to use @L2 for both inputs.List.FirstItem
will give you the surface which had the lowest Z component on it’s normal.Surface.PointAtParameter
will now allow you to select a point on that face which you can use to create a family instance (what I think you mean for placing an object), or aSurface.CoordianteSystemAtParameter
can get a coordinate system if you want to position a curve relative to the surface’s orientation, or aCurve.ByParameterLineOnSurface
node can produce a line relative to the surface, or… you have lots of options now.
You can get the bottom surface using a one liner in a python node
OUT = filter(lambda surface: surface.NormalAtParameter().Z == -1, IN[0].Explode())
Edit - Jacob’s method (most facing down normal)
OUT = sorted(IN[0].Explode(), key=lambda surface: surface.NormalAtParameter().Z)[0]