.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

About insert a block to a new database

13 REPLIES 13
SOLVED
Reply
Message 1 of 14
swaywood
1242 Views, 13 Replies

About insert a block to a new database

Hi:

i have a dwg "A". and in the dwg "A", there are some blocks like blk1,blk2.

and in my blockview form, i newed a databse db1.

and i want to insert the blk1 into the db1 modelspace.

but when i append the blockreference to the db1 modelspace, acad show the error "ewrongdatabase",i found the databse is exist and the space is also exist, the only thing is it is not saved to a dwg file.

did anyone do this? or could anybody give me a simple demo for this?

regards

swaywood

13 REPLIES 13
Message 2 of 14
norman.yuan
in reply to: swaywood

Without seeing your code, all is a guessing game. Let me guess:

 

You have a drawing "A" opening, with a few block DEFINITION defined. You want to create one block reference based on one of the block definition in another drawing database. So, you creates an instance of a block reference, and try to append it into the modelspace of another drawomg (the side database). 

 

If this is what you do, it is so obvious: the block reference created is a REFERENCE to one fo the block definitions in drawing "A", which cannot live in other database, thus the error.

 

You need to recreate/copy the block definition into the other drawing/database, and then create block referense THERE.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 14
fieldguy
in reply to: swaywood
Message 4 of 14
swaywood
in reply to: norman.yuan

hi yuan:

here is the test code, please help me.

    private void Test(string dwgName = "d:\\A.DWG", string blockName = "blk1")
    {
      //load the A DWG
      Database dbTemp = new Database(false, true);
      dbTemp.ReadDwgFile(dwgName, FileShare.Read, true, null);
      dbTemp.CloseInput(true);

      //i want to insert a block from A DWG into the new dwg i newed
      using (Database desDB = new Database(false, true))
      using (Transaction trans = desDB.TransactionManager.StartTransaction())
      {
        ObjectId spaceId = desDB.GetModelSpaceId();
        ObjectId btrId = desDB.Insert(blockName, dbTemp, false);
        trans.Commit();
      }
    }

 

Message 5 of 14
phliberato
in reply to: swaywood

   public static class BlockUtils
    {
        public static void TestInsertBlock()
        {
            ////Use this code to copy block from another database and create and insert one blockreference in the current drawing

            Database db = HostApplicationServices.WorkingDatabase;

            //Put your file path here
            string dwgFileBlocks = "c:\\........";

            //Name of block
            string blockName = "blockName";

            //Point to insert block
            Point3d blockReferencePoint = new Point3d(0, 0, 0);

            string erro;
            ObjectId blocoId = GetBlockIdWithCopyBlockTableRecord(db, dwgFileBlocks, blockName, out erro);

            if (!blocoId.IsNull)
            {
                BlockReference blockReference = new BlockReference(blockReferencePoint, blocoId);
                InsertBlockReference(db, blockReference);
            }
            else
            {
                Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;
                ed.WriteMessage(Environment.NewLine + erro);
            }
        }

        public static ObjectId GetBlockIdWithCopyBlockTableRecord(Database pToDatabase, string pDwgFileBlocks, string pBlockName, out String pErro)
        {
            pErro = null;

            using (Transaction trans = pToDatabase.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)trans.GetObject(pToDatabase.BlockTableId, OpenMode.ForWrite, false);

                if (!bt.Has(pBlockName))
                {
                    if (!CopyBlockTableRecord(bt, pDwgFileBlocks, pBlockName, out pErro))
                        return ObjectId.Null;
                }

                ObjectId objectId = bt[pBlockName];

                trans.Commit();

                return objectId;
            }
        }

        private static bool CopyBlockTableRecord(BlockTable pBlockTable, string pDwgFileBlocks, string pBlockName, out String pErro)
        {
            pErro = null;

            if (!File.Exists(pDwgFileBlocks))
            {
                pErro = string.Format("File '{0}' not found", pDwgFileBlocks);
                return false;
            }

            Database dbSource = new Database(false, true);

            try
            {
                dbSource.ReadDwgFile(pDwgFileBlocks, FileOpenMode.OpenForReadAndReadShare, true, "");
            }
            catch
            {
                pErro = String.Format("Can't read file '{0}'", pDwgFileBlocks);
                return false;
            }

            using (Transaction transSource = dbSource.TransactionManager.StartTransaction())
            {
                BlockTable btSource = (BlockTable)transSource.GetObject(dbSource.BlockTableId, OpenMode.ForRead);

                if (!btSource.Has(pBlockName))
                {
                    pErro = string.Format("Block '{0}' not found", pBlockName);
                    transSource.Commit();

                    return false;
                }

                ObjectIdCollection listIds = new ObjectIdCollection();
                listIds.Add(btSource[pBlockName]);

                IdMapping mapping = new IdMapping();
                dbSource.WblockCloneObjects(listIds, pBlockTable.ObjectId, mapping, DuplicateRecordCloning.Ignore, false);

                transSource.Commit();

                return true;
            }
        }

        public static void InsertBlockReference(Database pToDatabase, BlockReference pBlockReference)
        {
            using (Transaction trans = pToDatabase.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)trans.GetObject(pToDatabase.BlockTableId, OpenMode.ForWrite, false);
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false);

                btr.AppendEntity(pBlockReference);
                trans.AddNewlyCreatedDBObject(pBlockReference, true);

                BlockTableRecord blockTableRecordCopy = (BlockTableRecord)trans.GetObject(pBlockReference.BlockTableRecord, OpenMode.ForRead);

                IEnumerable<ObjectId> listAttributes = blockTableRecordCopy.GetAttributes();

                foreach (ObjectId id in listAttributes)
                {
                    AttributeDefinition attributeDefinition = (AttributeDefinition)trans.GetObject(id, OpenMode.ForRead);

                    AttributeReference attributeReference = new AttributeReference();
                    attributeReference.SetAttributeFromBlock(attributeDefinition, pBlockReference.BlockTransform);

                    pBlockReference.AttributeCollection.AppendAttribute(attributeReference);
                    trans.AddNewlyCreatedDBObject(attributeReference, true);
                }

                trans.Commit();
            }

        }
Message 6 of 14
swaywood
in reply to: phliberato

Hi,

thank you for your reply,

but i am not to want to import a blockdef  and insert a blockref to 'current database'.

i want to new a database DB by code.

and import a blockdef and insert a blockref to 'DB'.

Message 7 of 14
SENL1362
in reply to: swaywood

What about changing this line in the 'DB' you want:
Database db = HostApplicationServices.WorkingDatabase;new Database(false, true);

...

    ObjectId blocoId = GetBlockIdWithCopyBlockTableRecord(db, dwgFileBlocks, blockName, out erro);

...

db.SaveAs(...)

 

Message 8 of 14
phliberato
in reply to: SENL1362

Try this code:

 

    public static void TestInsertBlockNewDatabase()
        {
            ////Use this code to copy block from another database and create and insert one blockreference in the current drawing
           
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
             using (doc.LockDocument())
             {
                 using (Database db = new Database(true, false))
                 {
                     //Put your file path here
                     string dwgFileBlocks = "c:\\........";

                     string dwgToSave = "c:\\........";

                     //Name of block
                     string blockName = "blockName";

                     //Point to insert block
                     Point3d blockReferencePoint = new Point3d(0, 0, 0);

                     string error;
                     ObjectId blocoId = GetBlockIdWithCopyBlockTableRecord(db, dwgFileBlocks, blockName, out error);

                     if (!blocoId.IsNull)
                     {
                         BlockReference blockReference = new BlockReference(blockReferencePoint, blocoId);
                         InsertBlockReference(db, blockReference);

                         db.SaveAs(dwgToSave, true, DwgVersion.AC1024, null);
                     }
                     else
                     {
                         Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;
                         ed.WriteMessage(Environment.NewLine + error);
                     }
                 }

             }

        }
Message 9 of 14
swaywood
in reply to: phliberato

Hi phliberato,

    thanks so much, it's really works. i found the key method is as following

 

Database dbSource = new Database(false, true)

Database db = new Database(true, false)

 

i do not know the difference between the two lines.

regards

swaywood

 

 

             

Message 10 of 14
phliberato
in reply to: swaywood

The first parameter (buildDefaultDWG) is True when you are creating a new Database. If you are using ReadDwgFile you need to pass False.
The second parameter (noDocumento) is intended to indicate that the Database DWG file has no associated Document window.

 

Regards

Message 11 of 14
kdub_nz
in reply to: swaywood


swaywood wrote:

 

 

Database dbSource = new Database(false, true)

Database db = new Database(true, false)

 

i do not know the difference between the two lines.             

 

From the ObjectARX SDK

From arxmgd.chm  

new Database snip_20160113103632.png

 

 

From arxref.chm

new Database arx snip_20160113103632.png

 

 

 

 

 

 

 


// Called Kerry in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

Message 12 of 14
BKSpurgeon
in reply to: phliberato

This answer was heaven sent because I just made a screen dump of the ObjectARX managed class reference guide to ask that very question - and Kerry Brown seems to have also done that!

 

Notice the second parameter - could anybody please clarify what is meant by it:

 

  • "The second parameter (noDocumento) is intended to indicate that the Database DWG file has no associated Document window."
  • "System.boolean specifying whether o rnot to associate this database to the current document"

With all the help in the world, i still do not understand what is meant by the second parameter - any clarifications would be extremely appreciated.

 

rgds

 

BK

 

 

 

more info on the datbase constructor

Message 13 of 14
kdub_nz
in reply to: BKSpurgeon

I can't recall seeing a definitive description of the full technical meaning of the noDocument parameter.

 

These may help in a small way.

 

http://adndevblog.typepad.com/autocad/2012/07/using-readdwgfile-with-net-attachxref-or-objectarx-acd...

 

http://adndevblog.typepad.com/autocad/2012/07/enoinputfiler-exception-when-using-readdwgfile.html

 

 


// Called Kerry in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

Message 14 of 14
kdub_nz
in reply to: kdub_nz

 

and this gives couple more breadcrumbs.

 Document-Independent Databases

 

http://docs.autodesk.com/ACDMAC/2015/ENU/Mac_Lightsaber_Dev_Help/Developer%20Guide/files/GUID-FEA5A1...


// Called Kerry in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost