Entities wrong when importing multiple DXF files

174 views Asked by At

I have 3 different BlockTableRecord's that I want to update. I am loading external .dxf files that contain the entities for each block definition. Now when I delete the old entities and load in the new ones it works perfectly fine but as soon as I start updating the second (third, etc.) one it uses the entities of the first BlockTableRecord again. It even happens after saving and reloading the whole drawing.

GetPositionBlock() gets the BlockTableRecord I want to update based on its XData. The error is not in this method as it gets the right block to update.

public void Update(string fileName)
{
    using (_doc.LockDocument())
    {
        using Transaction transaction = _dataBase.TransactionManager.StartTransaction())
        {
            BlockTableRecord blockTableRecord = GetPositionBlock();
            // ...delete old entities
            BlockTableRecord externalblock =  GetExternalBlock(fileName);
            ObjectIdCollection objs = new ObjectIdCollection();
            foreach (ObjectId objId in externalBlock)
            {
                objs.Add(objId);
            }
            blockTableRecord.AssumeOwnershipPf(objs);
            transaction.Commit();
        }
    }
}

private BlockTableRecord GetExternalBlock(string fileName)
{
    DBObjectCollection dbObjColleciton = new DBObjectCollection();
    using (Transaction transaction = _doc.TransactionManager.StartTransaction())
    {
        using (Database sourceDb = new Database(false, true))
        {
            sourceDb.DxfIn(fileName, null);
            ObjectId blockId = _dataBase.Insert(Guid.NewGuid().ToString(), sourceDb, false)
            BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockId, OpenMode.ForRead);
            transaction.Commit();
            return blockTableRecord;
        }
    }
}

I double-checked every value. It never uses the same guid, name or anything like that. It seems like the problem lies somewhere in blockId or in _dataBase.Insert(...). It seems as some value is overwritten or set on the first use and after that nothing resets it. Any ideas what could cause this problem? Any hints or help is much appreciated.

1

There are 1 answers

1
Alain On BEST ANSWER

I think your problem is here :

ObjectId blockId = _dataBase.Insert(Guid.NewGuid().ToString(), sourceDb, false)

the _Database object is not the database you are in when using method GetExternalBlock. Personally I would use the WblockCloneObjects Method to get a block from an external drawing. my code:

 public bool GetExternBlok(string filePath, string blockName)
    {
        bool functionReturnValue = true;
        Document doc = Application.DocumentManager.MdiActiveDocument;

        using (DocumentLock  myLock = doc.LockDocument())
        {
            using (Database OpenDb = new Database(false, false))
            {
                OpenDb.ReadDwgFile(filePath, System.IO.FileShare.Read, true, "");
                //readwrite
                ObjectIdCollection sourceidsCollection = new ObjectIdCollection();
                ObjectId sourceBlockId = ObjectId.Null;

                using (Transaction tr = OpenDb.TransactionManager.StartTransaction())
                {

                    BlockTable bt = (BlockTable)tr.GetObject(OpenDb.BlockTableId, OpenMode.ForRead);

                    if (bt.Has(blockName))
                    {
                        sourceidsCollection.Add(bt[blockName]);
                        sourceBlockId = bt[blockName];
                    }

                    if (sourceidsCollection.Count != 0)
                    {
                        Database destdb = doc.Database;
                        IdMapping iMap = new IdMapping();
                        OpenDb.WblockCloneObjects(sourceidsCollection, destdb.BlockTableId, iMap, DuplicateRecordCloning.Replace, false);

                        using (Transaction t = destdb.TransactionManager.StartTransaction())
                        {
                            ObjectId targetBlockId = ObjectId.Null;
                            BlockTable b = (BlockTable)t.GetObject(destdb.BlockTableId, OpenMode.ForRead);

                            if (b.Has(blockName))
                            {
                                targetBlockId = b[blockName];
                            }

                            t.Commit();

                        }
                    }
                    else
                    {
                        functionReturnValue = false;
                    }

                    tr.Commit();

                }
            }
        }
        return functionReturnValue;
    }