I want to extract all that is visible and correctly placed in the attached image.
Solved! Go to Solution.
Solved by jeremytammik. Go to Solution.
hi
for the text, you can get it with most of the BuiltInParameter (search for "SHEET_ ") https://www.revitapidocs.com/2020/fb011c91-be7e-f737-28c7-3f1e1917a0e0.htm
now for the geometry, i'm not sure if i understand, you mean the box of text or the frame of the sheet?
A Title Block is a Revit Family.
You can Filter and select the elements then work with the selections to retrieve all the Parameters you need:
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> lines = collector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Lines).ToElements();
ICollection<Element> texts = collector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_TextNotes).ToElements();
ICollection<Element> filledRegions = collector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_FilledRegion).ToElements();
//etc.
to be more precise. I want to recreate the sheetview identically to create an exportable document. I managed to extract the content of the views that compose it but at real size and not yet find how to extract the cartridge and its content.
Dear Pierre,
you say you want to recreate the sheet view identically.
For that, I would suggest using the Copy and Paste API.
If you want to access the text and visible geometry to recreate a facsimile outside of Revit, I would suggest following Yien_Chao's good advice and accessing text and geometry separately, e.g., using a filtered element collector for real data and a screen snapshot for the appearance.
Cheers,
Jeremy
I want to create a facsimile outside of Revit, but filtered element collector result lists empty.
FilteredElementCollector collector = new FilteredElementCollector(Doc);
ICollection<Element> lines = collector.OfCategory(BuiltInCategory.OST_Lines).ToElements();
ICollection<Element> texts = collector.OfCategory(BuiltInCategory.OST_TextNotes).ToElements();
ICollection<Element> filledRegions = collector.OfCategory(BuiltInCategory.OST_FilledRegion).ToElements();
foreach (DetailLine line in lines)
{
Curve curve = line.GeometryCurve;
Line LI = (Line) curve;
if (LI != null)
{
TaskDialog.Show("Line", "Start X=" + LI.GetEndPoint(0).X + "Y=" + LI.GetEndPoint(0).Y + "Z=" + LI.GetEndPoint(0).Z + "\n" +
"End X=" + LI.GetEndPoint(1).X + "Y=" + LI.GetEndPoint(1).Y + "Z=" + LI.GetEndPoint(1).Z);
}
}
foreach (TextNote text in texts)
{
}
As always, you can use RevitLookup to analyse the properties and other attributes of the Revit elements you are trying to retrieve with the filtered element collector. That will show you which filters you need to apply to extract the desired elements. If the filter returns no elements,. you are applying too restrictive or downright erroneous filters.
On the FamilyInstance of my ViewSheet, it finds neither OST_Lines nor OST_TextNodes (for the extract the Title Block).
Do you have a filter syntax that could find them ?
Dear Pierre,
The most efficient way to define such a filter is for you to pick the elements you are filtering for and explore their properties using RevitLookup.
This has been explained numerous times in the past:
Best regards,
Jeremy
I have already explored the viewsheet and the associated familyinstance as well as the symbol and the family. None has geometry.
The FamilyDocument of the title block will contain the geometry you would probably have to open the family for editing, it may have various nested annotation symbols that also need to be traversed.
Besides that there is the issue of items such as images and schedules.
Would probably be easier to read the fixed document sequence of a printed xps file. This is an XML file containing path data (mini language) similar to what you get in Xaml and 'Glyphs' entries for text objects (render transforms give their positions). Takes a while to print an XPS but if it is only the title block may be quicker. You would still have to interpret the xml but as difficult to impossible tasks go it is slightly less impossible.
XPS is a zip file, change the extension to Zip and unpack it or alternatively there are namespaces for reading packages for such directly (System.IO.Packaging).
I don't envy your task, I usually just print a pdf when I want a copy of something. HPGL is another historic plotter vector format that could be easily interpreted.
my project is to export a viewsheet in svg format. currently my code export correctly all viewports but I still have the title block (drawing and data) to export. if I understand correctly there is no way to export the title block (curve and position of the data)?
As you've noted Element.Geometry is null for title blocks.
The only approach I know of with the RevitAPI would be to open the title block family (Document.EditFamily) and extract such lines from the plan view within that. As noted above however this family could also contain revision schedule that you can't extract lines from, other nested generic annotation families and images. The parameter text values would not be correct but from the text strings used in Labels and parameter names you can sometimes infer such a relationship (between text locations in your title block family and positions on your ViewSheet in the project). If label has a preview parameter value (which is often the case) then this can't be done. Also the placement of multiple parameters with line breaks etc. in the same label add to complexity. You don't get a description of these with the API (which parameters used in which label).
Ideally this task would be suited to CustomExporter but I believe from previous discussions that this doesn't support ViewSheets.
XLST could potentially be used to convert Xaml path data previously noted to svg (although I know of no existing templates for such).
Another potential long winded option would be to export sheet with only title block showing to DWG and import it on a drafting view to analyse the geometry. Not sure it is a good option but could be done. DWG links favour polylines (any lines of the same layer joined together will be grouped into polylines). Text object positions could only be found be exploding dwg (not sure if there is API function for that).
I confirm that CustomExporter2D does not work on ViewSheets. I will test this approach. Thank you.
// vs = current view (Viewsheet)
Element El = Doc.GetElement(vs.Id);
FamilyInstance FI = null;
foreach (ElementId ElI in El.GetDependentElements(null))
{
Element El1 = El.Document.GetElement(ElI);
FI = El1 as FamilyInstance;
if (FI != null)
break;
}
FamilySymbol FS = FI.Symbol;
Document DocFamily = Doc.EditFamily(FS.Family);
FamilyManager famManager = DocFamily.FamilyManager;
FamilyTypeSet famTypes = famManager.Types;
int nb = famTypes.Size;
FilteredElementCollector collector = new FilteredElementCollector(DocFamily);
ICollection<Element> Elems = collector.ToElements();
foreach (Element ElF in Elems)
{
DetailLine line = ElF as DetailLine;
if (line != null)
{
Curve curve = line.GeometryCurve;
Line LI = (Line)curve;
if (LI != null)
{
double XD = (LI.GetEndPoint(0).X * 25.4 * 12);
double YD = (LI.GetEndPoint(0).Y * 25.4 * 12);
double XF = (LI.GetEndPoint(1).X * 25.4 * 12);
double YF = (LI.GetEndPoint(1).Y * 25.4 * 12);
Deb.Write(" <line x1=\"{0}\" y1=\"{1}\" x2=\"{2}\" y2=\"{3}\" style=\"stroke-width:{4}; stroke:rgb({5}, {6}, {7})\" {8}/>\n",
XD, V - YD, XF, V - YF, 1, 0, 0, 0, "");
}
}
else
TaskDialog.Show("Test", "No Line");
}
This code extract only 33 lines and nothing else. How to have access to the texts position ?
Your code extracts nothing but lines because that is what you have instructed it to do.
You can expand you code to analyse other elements besides lines.
Alternatively, and probably more effectively, you can analyse your family definition document interactively using RevitLookup to discover what other elements it contains.
This family is internal (A0 metric).
How with "Revit Lookup" to explore this family ? (see associated jpg).