How to create correct referenceArray for further use while creating Dimensions?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I'm facing issues while creating dimension for a window (refer attached family).
Syntax required:
Dimension dim = doc.Create.NewDimension(View view, Line line, ReferenceArray refArray);
Issue:
Not getting any valid references from the geometry. When trying to iterate through the geometry.
- The instance doesn't return any edges that are horizontal, and the length is equal to width of the window. If I remove the conditions for edge length == window width, undesired lines are being returned. Hence throwing exceptions for "invalid number of references" or "invalid direction for dimension".
- Faces returned from the geometry can't be used as reference as no face returns a valid reference. All faces return the reference as null. (refer "Code snippet B")
I spent lot of time but didn't get it. Then I tried to put dimension for a wall using below code (refer "Code snippet A") to validate if I'm implementing the basics correctly. It didn't work. So, I believe that my understanding about the reference and it's uses isn't clear. Can anyone of you explain why it didn't work? Identifying the issue in "code snippet A" would be much easier as it's a small piece of code.
("Code snippet A")
Document doc = commandData.Application.ActiveUIDocument.Document;
Wall wall = new FilteredElementCollector(doc).OfClass(typeof(Wall)).WhereElementIsNotElementType().Cast<Wall>().ToList().FirstOrDefault();
using (Transaction t = new Transaction(doc, "Dimension for Wall"))
{
t.Start();
Line line = (wall.Location as LocationCurve).Curve as Line;
ReferenceArray refArray = new ReferenceArray();
refArray.Append(line.GetEndPointReference(0));
refArray.Append(line.GetEndPointReference(1));
Dimension dim = doc.Create.NewDimension(doc.ActiveView, line, refArray);
t.Commit();
}
return Result.Succeeded;
Most probably once I'm able to put the dimension for wall, I should be able to execute the same for window. Though I've put the code for easy reference. In case, there's something more I should consider while putting dimension for a custom window (family).
"Code snippet B"
FilteredElementCollector _fec = new FilteredElementCollector(doc).OfClass(typeof(FamilyInstance)).WhereElementIsNotElementType();
Options opt = new Options();
List<Curve> lineList = new List<Curve>();
List<Curve> edgeList = new List<Curve>();
List<Face> face_List = new List<Face>();
List<Curve> allLines = new List<Curve>();
ReferenceArray refArray = new ReferenceArray();
foreach (var famInst in _fec.WhereElementIsNotElementType().WhereElementIsNotElementType().Cast<FamilyInstance>().ToList())
{
GeometryElement geoElement = famInst.get_Geometry(opt);
if (geoElement != null)
{
foreach (GeometryObject item in geoElement)
{
if (item is Solid)
{
Solid solid = (item as Solid);
EdgeArray edgeArray = solid.Edges;
foreach (Edge f in edgeArray)
{
edgeList.Add(f.AsCurve());
}
FaceArray faceArray = solid.Faces;
foreach (Face f in faceArray)
{
XYZ faceNormal = f.ComputeNormal(new UV(0, 0));
if ((f is PlanarFace) && (f.Reference != null) && (faceNormal.DotProduct(XYZ.BasisX) == 1 || faceNormal.DotProduct(XYZ.BasisX) == -1))
{
face_List.Add(f);
}
}
edgeList = edgeList.Where(x => x.Length == Width)
.Where(x => x.GetEndPoint(0).Y == x.GetEndPoint(1).Y)
.Where(x => x.GetEndPoint(0).Z == x.GetEndPoint(1).Z).ToList();
allLines.AddRange(edgeList);
}
else if (item is GeometryInstance)
{
GeometryInstance geometryInstance = item as GeometryInstance;
GeometryElement instanceGeoElement = geometryInstance.GetInstanceGeometry();
foreach (GeometryObject geometryObjectInstance in instanceGeoElement)
{
if (geometryObjectInstance is Solid)
{
Solid isolid = (geometryObjectInstance as Solid);
double sa = isolid.SurfaceArea;
if (sa != 0)
{
try
{
EdgeArray edgeArray = new EdgeArray();
edgeArray = isolid.Edges;
foreach (Edge f in edgeArray)
{
if (f.AsCurve() is Line)
{
edgeList.Add(f.AsCurve());
}
}
FaceArray faceArray = isolid.Faces;
foreach (Face f in faceArray)
{
XYZ faceNormal = f.ComputeNormal(new UV(0, 0));
if ((f is PlanarFace) && (f.Reference != null) && (faceNormal.DotProduct(XYZ.BasisX) == 1 || faceNormal.DotProduct(XYZ.BasisX) == -1))
{
face_List.Add(f);
}
}
edgeList = edgeList
.Where(x => x.Length == Width)
.Where(x => x.GetEndPoint(0).Y == x.GetEndPoint(1).Y)
.Where(x => x.GetEndPoint(0).Z == x.GetEndPoint(1).Z).ToList();
allLines.AddRange(edgeList);
}
catch (Exception e)
{
throw;
}
}
}
else
{
try
{
allLines.AddRange(geometryInstance.SymbolGeometry.Where(x => x is Curve).Cast<Curve>().Where(x => x.Length == Width)
.Where(x => (x as Curve).GetEndPoint(0).Y == (x as Curve).GetEndPoint(1).Y)
.Where(x => (x as Curve).GetEndPoint(0).Z == (x as Curve).GetEndPoint(1).Z).ToList());
foreach (Face face in geometryInstance.SymbolGeometry.Where(x => x is Face).Cast<Face>().ToList())
{
XYZ fNormal = face.ComputeNormal(new UV(0, 0));
if ((face is PlanarFace) && (face.Reference != null) && (fNormal.DotProduct(XYZ.BasisX) == 1 || fNormal.DotProduct(XYZ.BasisX) == -1))
{
face_List.Add(face);
}
}
}
catch (Exception)
{
throw;
}
}
}
}
}
}
}
lineList = allLines.ToList();
if (face_List.Count > 2)
{
refArray.Append(face_List.FirstOrDefault().Reference);
refArray.Append(face_List.LastOrDefault().Reference);
Line lineforDim = Line.CreateBound(face_List.FirstOrDefault().Reference.GlobalPoint, face_List.LastOrDefault().Reference.GlobalPoint);
Dimension dim = doc.Create.NewDimension(Elevation, lineforDim, refArray);
}
if (lineList.Count > 0)
{
Curve TopLine = lineList.FirstOrDefault();
Curve BottomLine = lineList.LastOrDefault();
face_List = face_List.Where(x => x.Reference != null).OrderByDescending(x => x.Reference.UVPoint.U).ToList();
refArray.Append(TopLine.Reference);
refArray.Append(BottomLine.Reference);
XYZ pt1 = (TopLine.GetEndPoint(0).X > TopLine.GetEndPoint(1).X) ? TopLine.GetEndPoint(0) : TopLine.GetEndPoint(1);
XYZ pt2 = (BottomLine.GetEndPoint(0).X > TopLine.GetEndPoint(1).X) ? BottomLine.GetEndPoint(0) : BottomLine.GetEndPoint(1);
Line lineforDim = Line.CreateBound(pt1, pt2);
Dimension dim = doc.Create.NewDimension(Elevation, lineforDim, refArray);
}
Thanks for your valuable time!