Material Tag created by API does not show material data
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi,
This code creates a wall and material tags for each layer. The tag leaders are placed correctly (in the center of each wall layer) but the tags do not show the material data.
Manually making any tweak to the tags (such as moving the leader elbow or text location) will get the tag to properly show the material value, but of course the goal of using the API to create the tags is that they will show the correct data without any manual intervention. I've tried different permutations with transactions to no avail. Any ideas?
public void MakeWallAndTag()
{
Document doc = this.ActiveUIDocument.Document;
List<XYZ> bottomFacesPts = new List<XYZ>();
Wall wall = null;
using (Transaction t = new Transaction(doc, "wall"))
{
t.Start();
doc.ActiveView.DetailLevel = ViewDetailLevel.Fine;
wall = Wall.Create(doc,
Line.CreateBound(XYZ.Zero, new XYZ(10,0,0)),
new FilteredElementCollector(doc).OfClass(typeof(Level)).FirstOrDefault().Id,
false);
wall.WallType = new FilteredElementCollector(doc).OfClass(typeof(WallType)).Cast<WallType>().FirstOrDefault(q => q.Name == "Exterior - Brick on CMU");
t.Commit();
}
using (Transaction t = new Transaction(doc, "Place tag"))
{
t.Start();
List<ElementId> ids = new List<ElementId> { wall.Id };
if (PartUtils.AreElementsValidForCreateParts(doc, ids))
{
PartUtils.CreateParts(doc, ids);
doc.Regenerate();
foreach (ElementId id in ids)
{
if (!PartUtils.HasAssociatedParts(doc, id))
{
continue;
}
ICollection<ElementId> partIds = PartUtils.GetAssociatedParts(doc, id, true, true);
foreach (ElementId partId in partIds)
{
Element part = doc.GetElement(partId);
bottomFacesPts.AddRange(GetBottomFacePoints(part));
}
}
}
t.RollBack();
}
using (Transaction t = new Transaction(doc, "tags"))
{
t.Start();
foreach (XYZ pt in bottomFacesPts)
{
IndependentTag tag = doc.Create.NewTag(doc.ActiveView, wall, true, TagMode.TM_ADDBY_MATERIAL, TagOrientation.Horizontal, pt);
tag.LeaderEnd = pt.Add(new XYZ(0.1, 0, 0));
tag.TagHeadPosition = pt.Add(new XYZ(-2, 0,0));
}
t.Commit();
}
}
public List<XYZ> GetBottomFacePoints(Element e)
{
List<XYZ> resultingPts = new List<XYZ>();
FaceExtractor faceExtractor = new FaceExtractor(e);
FaceArray faces = faceExtractor.Faces;
if (faces.Size == 0) { return resultingPts; }
foreach (Face face in faces)
{
PlanarFace pf = face as PlanarFace;
if (pf == null) { continue; }
if (pf.Normal.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
{
EdgeArrayArray edgeLoops = face.EdgeLoops;
foreach (EdgeArray edgeArray in edgeLoops)
{
foreach (Edge edge in edgeArray)
{
Line line = edge.AsCurve() as Line;
if (line == null)
continue;
if (!line.Direction.IsAlmostEqualTo(XYZ.BasisY) &&
!line.Direction.IsAlmostEqualTo(XYZ.BasisY.Negate()))
continue;
XYZ end0 = line.GetEndPoint(0);
XYZ end1 = line.GetEndPoint(1);
if (end0.X > 1)
continue;
Line ll = Line.CreateBound(end0, end1);
//List<XYZ> points = edge.Tessellate() as List<XYZ>;
resultingPts.Add(ll.Evaluate(0.5, true));
}
}
}
}
return resultingPts;
}
public class FaceExtractor
{
private Element _element;
private Document _doc;
private Autodesk.Revit.ApplicationServices.Application _app;
private Autodesk.Revit.Creation.Application _appCreator;
private Transform _matrix;
private FaceArray _faces;
/// <summary>
/// Gets the transform for element
/// </summary>
public Transform Matrix
{
get { return _matrix; }
}
/// <summary>
/// Gets faces
/// </summary>
public FaceArray Faces
{
get { return _faces; }
}
/// <summary>
/// Default constructor
/// </summary>
/// <param name="element">element</param>
public FaceExtractor(Element element)
{
_element = element;
_doc = element.Document;
_app = _doc.Application;
_appCreator = _app.Create;
GetFaces();
}
/// <summary>
/// Retrieve all faces from the
/// given element's geometry solid.
/// </summary>
private void GetFaces()
{
Options geoOptions = _appCreator.NewGeometryOptions();
geoOptions.ComputeReferences = true;
GeometryElement geoElem = _element.get_Geometry(geoOptions);
_faces = GetFacesFrom(geoElem);
}
/// <summary>
/// Retrieve all faces from the first solid
/// encountered in the given geometry element.
/// </summary>
/// <param name="geoElement">geometry element</param>
/// <returns>faces</returns>
public FaceArray GetFacesFrom(GeometryElement geoElement)
{
foreach (object o in geoElement)
{
Solid geoSolid = o as Solid;
if (null == geoSolid)
{
GeometryInstance instance = o as GeometryInstance;
if (null == instance)
continue;
GeometryElement geoElement2 = instance.SymbolGeometry;
_matrix = instance.Transform;
if (geoElement2 == null)
continue;
if (geoElement2.Count() == 0)
continue;
return GetFacesFrom(geoElement2);
}
FaceArray faces = geoSolid.Faces;
if (faces == null)
continue;
if (faces.Size == 0)
continue;
return geoSolid.Faces;
}
return null;
}
}