/// <summary> /// Creates BlockReference from the block with the given name. /// Throws ArgumentException if block with such a name does not exist. /// </summary> /// <param name="blockName"></param> /// <param name="insertionPoint"></param> /// <param name="space">The model space or some of the paper spaces</param> /// <param name="blockTable">The block table of the associated drawing in the helper.</param> /// <returns>The BlockReference of the block</returns> private BlockReference CreateBlockReference(string blockName, UnitsValue sourceBlockMeasurementUnits, Point3d insertionPoint, BlockTableRecord space, BlockTable blockTable) { Matrix3d ucs = _ed.CurrentUserCoordinateSystem; BlockReference newBlockReference; //All open objects opened during a transaction are closed at the end of the transaction. using (Transaction transaction = _db.TransactionManager.StartTransaction()) { blockTable.UpgradeOpen(); // If the DWG already contains this block definition we will create a block reference and not a copy of the same definition if (!blockTable.Has(blockName)) { _logger.Error(MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + MethodBase.GetCurrentMethod().Name + " : Block with name '" + blockName + "' does not exist."); transaction.Abort(); throw new ArgumentException("Block with name '" + blockName + "' does not exist."); } BlockTableRecord sourceBlockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[blockName], OpenMode.ForRead); newBlockReference = new BlockReference(insertionPoint, sourceBlockTableRecord.ObjectId); var converter = new MeasurementUnitsConverter(); var scaleFactor = converter.GetScaleRatio(sourceBlockMeasurementUnits, blockTable.Database.Insunits); _ed.CurrentUserCoordinateSystem = Matrix3d.Identity; newBlockReference.TransformBy(ucs); _ed.CurrentUserCoordinateSystem = ucs; newBlockReference.ScaleFactors = new Scale3d(scaleFactor); space.UpgradeOpen(); space.AppendEntity(newBlockReference); transaction.AddNewlyCreatedDBObject(newBlockReference, true); AttributeCollection atcoll = newBlockReference.AttributeCollection; foreach (ObjectId subid in sourceBlockTableRecord) { var entity = (Entity)subid.GetObject(OpenMode.ForRead); var attributeDefinition = entity as AttributeDefinition; if (attributeDefinition != null) { var attributeReference = new AttributeReference(); attributeReference.SetPropertiesFrom(attributeDefinition); attributeReference.Visible = attributeDefinition.Visible; attributeReference.SetAttributeFromBlock(attributeDefinition, newBlockReference.BlockTransform); attributeReference.HorizontalMode = attributeDefinition.HorizontalMode; attributeReference.VerticalMode = attributeDefinition.VerticalMode; attributeReference.Rotation = attributeDefinition.Rotation; attributeReference.Position = attributeDefinition.Position + insertionPoint.GetAsVector(); attributeReference.Tag = attributeDefinition.Tag; attributeReference.FieldLength = attributeDefinition.FieldLength; attributeReference.TextString = attributeDefinition.TextString; attributeReference.AdjustAlignment(_db); atcoll.AppendAttribute(attributeReference); transaction.AddNewlyCreatedDBObject(attributeReference, true); } } transaction.Commit(); } _ed.Regen(); return(newBlockReference); }
/// <summary> /// the source drawig should be drawn as number of /// separate entites with or without attributes. /// Throws NotImplementedException if invoked with .dxf file /// </summary> /// <param name="sourceDrawing"></param> /// <param name="insertionPoint"></param> /// <returns>ObjectID of the Block Def that was imported.</returns> public void ImportDwgAsBlock(string sourceDrawing, Point3d insertionPoint) { Matrix3d ucs = _ed.CurrentUserCoordinateSystem; string blockname = sourceDrawing.Remove(0, sourceDrawing.LastIndexOf("\\", StringComparison.Ordinal) + 1); blockname = blockname.Substring(0, blockname.Length - 4); // remove the extension try { using (_doc.LockDocument()) { using (var inMemoryDb = new Database(false, true)) { #region Load the drawing into temporary inmemory database if (sourceDrawing.LastIndexOf(".dwg", StringComparison.Ordinal) > 0) { inMemoryDb.ReadDwgFile(sourceDrawing, System.IO.FileShare.Read, true, ""); } else if (sourceDrawing.LastIndexOf(".dxf", StringComparison.Ordinal) > 0) { _logger.Error(MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + MethodBase.GetCurrentMethod().Name + " : Tried to invoke the method with .dxf file."); throw new NotImplementedException("Importing .dxf is not supported in this version."); //inMemoryDb.DxfIn("@" + sourceDrawing, System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\log\\import_block_dxf_log.txt"); } else { throw new ArgumentException("This is not a valid drawing."); } #endregion using (var transaction = _db.TransactionManager.StartTransaction()) { BlockTable destDbBlockTable = (BlockTable)transaction.GetObject(_db.BlockTableId, OpenMode.ForRead); BlockTableRecord destDbCurrentSpace = (BlockTableRecord)_db.CurrentSpaceId.GetObject(OpenMode.ForWrite); // If the destination DWG already contains this block definition // we will create a block reference and not a copy of the same definition ObjectId sourceBlockId; if (destDbBlockTable.Has(blockname)) { //BlockTableRecord destDbBlockDefinition = (BlockTableRecord)transaction.GetObject(destDbBlockTable[blockname], OpenMode.ForRead); //sourceBlockId = destDbBlockDefinition.ObjectId; sourceBlockId = transaction.GetObject(destDbBlockTable[blockname], OpenMode.ForRead).ObjectId; // Create a block reference to the existing block definition using (var blockReference = new BlockReference(insertionPoint, sourceBlockId)) { _ed.CurrentUserCoordinateSystem = Matrix3d.Identity; blockReference.TransformBy(ucs); _ed.CurrentUserCoordinateSystem = ucs; var converter = new MeasurementUnitsConverter(); var scaleFactor = converter.GetScaleRatio(inMemoryDb.Insunits, _db.Insunits); blockReference.ScaleFactors = new Scale3d(scaleFactor); destDbCurrentSpace.AppendEntity(blockReference); transaction.AddNewlyCreatedDBObject(blockReference, true); _ed.Regen(); transaction.Commit(); // At this point the Bref has become a DBObject and (can be disposed) and will be disposed by the transaction } return; } //else // There is not such block definition, so we are inserting/creating new one sourceBlockId = _db.Insert(blockname, inMemoryDb, true); BlockTableRecord sourceBlock = (BlockTableRecord)sourceBlockId.GetObject(OpenMode.ForRead); sourceBlock.UpgradeOpen(); sourceBlock.Name = blockname; destDbCurrentSpace.DowngradeOpen(); var sourceBlockMeasurementUnits = inMemoryDb.Insunits; try { CreateBlockReference(sourceBlock.Name, sourceBlockMeasurementUnits, insertionPoint, destDbCurrentSpace, destDbBlockTable); } catch (ArgumentException argumentException) { _logger.Error("Error. Check inner exception.", argumentException); } _ed.Regen(); transaction.Commit(); } } } } catch (Exception exception) { _logger.Error("Error in ImportDrawingAsBlock().", exception); } }