Detail Blog
Nhu.Truong
How to convert text in a link/import DWG file to Revit?
The Revit API does not provide any information about Text objects in a link/import DWG file. This post shares a solution that can read Text objects in a link/import DWG and convert them to Revit.
Problem
The information provided by the ImportInstance (import/link DWG) object, as shown in the image below, does not include any details about Text objects in the DWG file.
In some cases, when additional information about Text in DWG is required, how do we resolve this?
Solution
Using the .dxf format as an intermediate step, then reading data from the .dxf file through Daniel Carvajal's netDXF library to convert the necessary data to Revit will be implemented as follows:
var uiDocument = serviceProvider.GetRequiredService<IRevitContext>().GetUIDocument(); using var transactionGroup = new TransactionGroup(uiDocument.Document); transactionGroup.Start("Export DXF"); using var transaction = new Transaction(uiDocument.Document); transaction.Start("Export DXF"); var importInstance = (ImportInstance)uiDocument.Document.GetElement(uiDocument.Selection.PickObject(ObjectType.Element, SelectionFilter.GetElementFilter<ImportInstance>())); uiDocument.ActiveView.IsolateElementTemporary(importInstance.Id); uiDocument.ActiveView.ConvertTemporaryHideIsolateToPermanent(); transaction.Commit(); var folderPath = Path.GetTempPath(); var fileName = "Example"; uiDocument.Document.Export(folderPath, fileName, new List<ElementId> { uiDocument.ActiveView.Id }, new DXFExportOptions()); transactionGroup.RollBack(); var dxfDocument = netDxf.DxfDocument.Load(Path.Combine(folderPath, $"{fileName}.dxf")); var mTexts = dxfDocument.Blocks.Items.SelectMany(x => x.Entities).OfType<netDxf.Entities.MText>(); var transform = importInstance.GetTotalTransform(); transaction.Start("Create TextNote"); foreach (var mText in mTexts) CreateTextNote(uiDocument.ActiveView, transform, mText); transaction.Commit();
private static void CreateTextNote( View view, Transform transform, netDxf.Entities.MText mText) { var position = new XYZ(mText.Position.X.ToFeet(), mText.Position.Y.ToFeet(), mText.Position.Z.ToFeet()); position = transform.OfPoint(position); var textNoteType = FindOrCreateTextNoteType(view, mText); var textNote = TextNote.Create(view.Document, view.Id, position, mText.Value, textNoteType.Id); ElementTransformUtils.RotateElement(view.Document, textNote.Id, Line.CreateUnbound(position, XYZ.BasisZ), mText.Rotation.ToRadian()); } private static TextNoteType FindOrCreateTextNoteType(View view, netDxf.Entities.MText mText) { var document = view.Document; var collector = new FilteredElementCollector(document); if (collector.OfClass(typeof(TextNoteType)).OfType<TextNoteType>().FirstOrDefault(x => x.Name == mText.Layer.Name) is { } textNoteType) return textNoteType; textNoteType = (TextNoteType)document.GetElement(document.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType)); textNoteType = (TextNoteType)textNoteType.Duplicate(mText.Layer.Name); textNoteType.get_Parameter(BuiltInParameter.LINE_COLOR).Set(mText.Color.R + (mText.Color.G << 8) + (mText.Color.B << 16)); textNoteType.get_Parameter(BuiltInParameter.TEXT_BACKGROUND).Set(1); textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).Set(mText.Style.FontFamilyName); textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set((mText.Style.Height / view.Scale).ToFeet()); textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(mText.Style.WidthFactor); textNoteType.get_Parameter(BuiltInParameter.TEXT_TAB_SIZE).Set(5d.ToFeet()); textNoteType.get_Parameter(BuiltInParameter.LEADER_OFFSET_SHEET).Set(1d.ToFeet()); return textNoteType; }
Result
Conclusion
By using the netDXF library to read the .dxf file after exporting the import/link elements in Revit, we can obtain nearly all the information from the DWG file and easily convert it into native elements in Revit.
However, this solution has limitations; if write permissions on the disk of your current computer are not allowed, you will not be able to use this solution.