Path two: Get the true center, width, depth and height of the casework
BoundingBoxXYZ bBoxFaminst = famInst.get_BoundingBox(view3D);
//This is where I am calling Bobbys code that I put in a separate public static class SolidsBoundaryBox in a namespace AAA
BoundingBoxXYZ bBoxSolidsOnly = AAA.SolidsBoundaryBox.GetBoundingBoxFromVisibleSolids(famInst, view3D);
//Find familieinstansens boundingboks-center
//= det punkt skal vi bruge som udgangspunkt for beregning af de to punkter, vi vil skyde tilbage fra
XYZ instanceBBoxCenter = bBoxFaminst.Min.Add(bBoxFaminst.Max.Subtract(bBoxFaminst.Min) / 2);
XYZ solidsCenter = bBoxSolidsOnly.Min.Add(bBoxSolidsOnly.Max.Subtract(bBoxSolidsOnly.Min) / 2);
double trueWidth = bBoxSolidsOnly.Max.X - bBoxSolidsOnly.Min.X;
double trueDepth = bBoxSolidsOnly.Max.Y - bBoxSolidsOnly.Min.Y;
double trueHeight = bBoxSolidsOnly.Max.Z - bBoxSolidsOnly.Min.Z;
double trueHalfWidth = trueWidth / 2;
double trueHalfDepth = trueDepth / 2;
double trueHalfHeight = trueHeight / 2;
XYZ basePoint = new XYZ(instanceBBoxCenter.X, instanceBBoxCenter.Y, solidsCenter.Z);
XYZ pointOnLeftSide = GetPointOnCaseworkSide(doc, basePoint, trueWidth, trueDepth,trueHeight, angle, directionTowards.Left, famInst.Id, view3D);
XYZ pointOnBackSide = GetPointOnCaseworkSide(doc, basePoint, trueWidth, trueDepth, trueHeight, angle, directionTowards.Back, famInst.Id, view3D);
XYZ pointOnBottom = GetPointOnCaseworkSide(doc, basePoint, trueWidth, trueDepth, trueHeight, 0, directionTowards.Bottom, famInst.Id, view3D);
XYZ directionVectorWidth = new XYZ(Math.Cos(angle), Math.Sin(angle), 0);
XYZ directionVectorDepth = new XYZ(Math.Cos(angle - (Math.PI / 2)), Math.Sin(angle - (Math.PI / 2)), 0);
XYZ point1OnMiddleOfWidth = pointOnLeftSide.Add(directionVectorWidth.Multiply(trueHalfWidth));
XYZ point2OnMiddleOfWidth = point1OnMiddleOfWidth.Add(directionVectorDepth.Multiply(trueHalfDepth));
XYZ point1OnMiddleOfDepth = pointOnBackSide.Add(directionVectorDepth.Multiply(trueHalfDepth));
XYZ point2OnMiddleOfDepth = point1OnMiddleOfDepth.Add(directionVectorWidth.Multiply(trueHalfWidth));
//True boundingbox Z-value:
double trueZValue = bBoxSolidsOnly.Max.Z - ((bBoxSolidsOnly.Max.Z - bBoxSolidsOnly.Min.Z) / 2);
//Now get the true center point
XYZ trueCenterPoint = GetIntersection(point1OnMiddleOfWidth, point2OnMiddleOfWidth, point1OnMiddleOfDepth, point2OnMiddleOfDepth);
trueCenterPoint = new XYZ(trueCenterPoint.X, trueCenterPoint.Y, trueZValue);
Part three: At this point we have the true center of the casework, and we can use this center as a ray base point for calculating distances
Dictionary<string, XYZ> lstViewDirections = new Dictionary<string, XYZ>();
XYZ vDir = new XYZ(Math.Cos(angle), Math.Sin(angle), 0);
lstViewDirections.Add("Right", vDir);
vDir = new XYZ(Math.Cos(angle + Math.PI), Math.Sin(angle + Math.PI), 0);
lstViewDirections.Add("Left", vDir);
vDir = new XYZ(Math.Cos(angle + (Math.PI / 2)), Math.Sin(angle + (Math.PI / 2)), 0);
lstViewDirections.Add("Back", vDir);
vDir = new XYZ(Math.Cos(angle + Math.PI + (Math.PI / 2)), Math.Sin(angle + Math.PI + (Math.PI / 2)), 0);
lstViewDirections.Add("Front", vDir);
vDir = new XYZ(0, 0, 1);
lstViewDirections.Add("Up", new XYZ(0, 0, 1));
vDir = new XYZ(0, 0, -1);
lstViewDirections.Add("Down", new XYZ(0, 0, -1));
ReferenceWithContext rwc = null;
foreach (KeyValuePair<string, XYZ> kvp in lstViewDirections)
{
XYZ rayDirection = kvp.Value;
List<ElementId> elementIds = new List<ElementId>
{
famInst.Id
};
ExclusionFilter flt = new ExclusionFilter(elementIds);
ReferenceIntersector refIntersector = new ReferenceIntersector(flt, FindReferenceTarget.Element, view3D);
rwc = refIntersector.FindNearest(trueCenterPoint, rayDirection);
Element elem = null;
if (rwc != null)
{
Reference reference = rwc.GetReference();
elem = doc.GetElement(reference);
}
string category;
string name;
double distance;
bool distanceUndefined = false;
string categoryString;
string nameString;
string distanceString;
if (rwc == null | elem == null)
{
category = "Nothing";
distance = 0;
name = "Nothing";
distanceUndefined = true;
}
else
{
category = elem.Category.Name;
name = elem.Name;
distance = rwc.Proximity;
switch (kvp.Key)
{
case "Right":
distance = Math.Abs(distance - trueHalfWidth);
break;
case "Left":
distance = Math.Abs(distance - trueHalfWidth);
break;
case "Back":
distance = Math.Abs(distance - trueHalfDepth);
break;
case "Front":
distance = Math.Abs(distance - trueHalfDepth);
break;
case "Up":
distance = Math.Abs(distance - trueHalfHeight);
break;
case "Down":
distance = Math.Abs(distance - trueHalfHeight);
break;
default:
distance = 0;
distanceUndefined = true;
break;
}
}
if (distanceUndefined)
{
distanceString = string.Concat("Distance = ", "Undefined");
}
else
{
if (distance < 0.000001)
{
distance = 0;
}
//Convert to mm
distance = Math.Round(distance = 304.8 * distance, 0);
distanceString = string.Concat("Distance = ", distance, " mm");
}
switch (kvp.Key)
{
case "Right":
categoryString = string.Concat("RightCat = ", category);
nameString = string.Concat("RightName = ", name);
break;
case "Left":
categoryString = string.Concat("LeftCat = ", category);
nameString = string.Concat("LeftName = ", name);
break;
case "Back":
categoryString = string.Concat("BackCat = ", category);
nameString = string.Concat("BackName = ", name);
break;
case "Front":
categoryString = string.Concat("FrontCat = ", category);
nameString = string.Concat("FrontName = ", name);
break;
case "Up":
categoryString = string.Concat("TopCat = ", category);
nameString = string.Concat("TopName = ", name);
break;
case "Down":
categoryString = string.Concat("BottomCat = ", category);
nameString = string.Concat("BottomName = ", name);
break;
default:
categoryString = "UnknownCat";
nameString = "UnknownName";
break;
}
returnValue = string.Concat(returnValue, "\n", categoryString, " ; ", nameString, " ; ", distanceString);
}
return returnValue;
}
public double GetFamInstAngle(FamilyInstance famInst)
{
LocationPoint locationPoint = famInst.Location as LocationPoint;
double angle;
if (locationPoint == null)
{
LocationCurve lc = famInst.Location as LocationCurve;
if (lc == null)
{
throw new Exception("Failed to get family instance location. Neither Location Point nor Location Curve is defined.");
}
else
{
XYZ insertionPoint = lc.Curve.GetEndPoint(0);
XYZ curveEndPoint = lc.Curve.GetEndPoint(1);
Line lin = lc.Curve as Line;
if (lin == null)
{
throw new Exception("Failed to retrieve the objects orientation. The objects location curve was expected to be a Line.");
}
angle = lin.Direction.AngleTo(new XYZ(1, 0, 0));
}
}
else
{
angle = locationPoint.Rotation;
}
return angle;
}