clog boy
2018-11-19, 01:27 PM
I'm trying to write an auto dimensioning plugin for Revit, and have been breaking my head all morning over one hurdle.
Basically what I want to do is get all mullions that run in a certain direction (vertical or otherwise), and get references from all faces perpendicular to that direction.
FilteredElementCollector mullions = new FilteredElementCollector(doc, wall.CurtainGrid.GetMullionIds())
.OfCategory(BuiltInCategory.OST_CurtainWallMullions);
Options options = new Options();
options.ComputeReferences = true;
options.View = doc.ActiveView;
options.IncludeNonVisibleObjects = true;
List<Face> validFaces = new List<Face>();
foreach (Mullion m in mullions)
{
if ((richting == Richting.horizontaal && m.LocationCurve.GetEndPoint(0).Z == m.LocationCurve.GetEndPoint(1).Z)
|| (richting == Richting.verticaal && m.LocationCurve.GetEndPoint(0).Z != m.LocationCurve.GetEndPoint(1).Z))
{
GeometryElement ge = m.get_Geometry(options);
foreach (GeometryInstance gi in ge)
{
GeometryElement ige = gi.GetInstanceGeometry();
foreach (GeometryObject igo in ige)
{
Solid s = igo as Solid;
if (s != null)
{
FaceArray faces = s.Faces;
foreach (Face fa in faces)
{
if ((richting == Richting.horizontaal && fa.ComputeNormal(new UV(0, 0)).Z != 0)
|| (richting == Richting.verticaal && fa.ComputeNormal(new UV(0, 0)).Z == 0))
{
validFaces.Add(fa);
}
}
}
}
}
}
}
I then want to get certain references for sot elevations (the top and bottom mullion face of the entire curtain wall) using this code:
Richting richting = Richting.horizontaal;
List<Face> faces = ValidFaces(wall, richting);
BoundingBoxXYZ bb = wall.get_BoundingBox(doc.ActiveView);
Reference r;
if (faces != null)
{
foreach (Face fa in faces)
{
foreach (EdgeArray ea in fa.EdgeLoops)
{
foreach (Edge e in ea)
{
XYZ pt = e.AsCurve().GetEndPoint(0);
if (pt.Z == bb.Min.Z || pt.Z == bb.Max.Z)
{
r = e.Reference;
XYZ origin = pt;
XYZ bend = new XYZ(pt.X + 0.5, pt.Y + 0.5, pt.Z);
XYZ end = new XYZ(pt.X + 1, pt.Y + 1, pt.Z);
XYZ refpt = pt;
using (Transaction tx = new Transaction(doc, "Kozijnmaatvoering"))
{
tx.Start();
SpotDimension sd = doc.Create.NewSpotElevation(doc.ActiveView, r, origin, bend, end, refpt, true);
tx.Commit();
}
break;
}
}
}
}
}
("Richting" means direction, I've made an enum object to make my code branching more readable).
The code reaches the command to create the new spot elevation without errors, and I do manage to extract a reference from the face. But the spot elevation is not visible. Can anyone tell me what I'm doing wrong?
EDIT: I realize that the topic title isn't accurate anymore, but I edited the post a couple of times after some more research.
Basically what I want to do is get all mullions that run in a certain direction (vertical or otherwise), and get references from all faces perpendicular to that direction.
FilteredElementCollector mullions = new FilteredElementCollector(doc, wall.CurtainGrid.GetMullionIds())
.OfCategory(BuiltInCategory.OST_CurtainWallMullions);
Options options = new Options();
options.ComputeReferences = true;
options.View = doc.ActiveView;
options.IncludeNonVisibleObjects = true;
List<Face> validFaces = new List<Face>();
foreach (Mullion m in mullions)
{
if ((richting == Richting.horizontaal && m.LocationCurve.GetEndPoint(0).Z == m.LocationCurve.GetEndPoint(1).Z)
|| (richting == Richting.verticaal && m.LocationCurve.GetEndPoint(0).Z != m.LocationCurve.GetEndPoint(1).Z))
{
GeometryElement ge = m.get_Geometry(options);
foreach (GeometryInstance gi in ge)
{
GeometryElement ige = gi.GetInstanceGeometry();
foreach (GeometryObject igo in ige)
{
Solid s = igo as Solid;
if (s != null)
{
FaceArray faces = s.Faces;
foreach (Face fa in faces)
{
if ((richting == Richting.horizontaal && fa.ComputeNormal(new UV(0, 0)).Z != 0)
|| (richting == Richting.verticaal && fa.ComputeNormal(new UV(0, 0)).Z == 0))
{
validFaces.Add(fa);
}
}
}
}
}
}
}
I then want to get certain references for sot elevations (the top and bottom mullion face of the entire curtain wall) using this code:
Richting richting = Richting.horizontaal;
List<Face> faces = ValidFaces(wall, richting);
BoundingBoxXYZ bb = wall.get_BoundingBox(doc.ActiveView);
Reference r;
if (faces != null)
{
foreach (Face fa in faces)
{
foreach (EdgeArray ea in fa.EdgeLoops)
{
foreach (Edge e in ea)
{
XYZ pt = e.AsCurve().GetEndPoint(0);
if (pt.Z == bb.Min.Z || pt.Z == bb.Max.Z)
{
r = e.Reference;
XYZ origin = pt;
XYZ bend = new XYZ(pt.X + 0.5, pt.Y + 0.5, pt.Z);
XYZ end = new XYZ(pt.X + 1, pt.Y + 1, pt.Z);
XYZ refpt = pt;
using (Transaction tx = new Transaction(doc, "Kozijnmaatvoering"))
{
tx.Start();
SpotDimension sd = doc.Create.NewSpotElevation(doc.ActiveView, r, origin, bend, end, refpt, true);
tx.Commit();
}
break;
}
}
}
}
}
("Richting" means direction, I've made an enum object to make my code branching more readable).
The code reaches the command to create the new spot elevation without errors, and I do manage to extract a reference from the face. But the spot elevation is not visible. Can anyone tell me what I'm doing wrong?
EDIT: I realize that the topic title isn't accurate anymore, but I edited the post a couple of times after some more research.