.NET

Reply
Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 1 of 14 (261 Views)
Accepted Solution

Copy Problems

261 Views, 13 Replies
03-19-2014 09:00 AM

I want to create a command, it could copy the contents of another drawing to the current drawing directly, not XERF, Is there anyone can give me a simple example?
Thanks very much

*Expert Elite*
_gile
Posts: 2,078
Registered: ‎04-29-2006
Message 2 of 14 (255 Views)

Re : Copy Problems

03-19-2014 09:35 AM in reply to: HelloWorlddd

Have a look at the Database.WblockCloneObjects() method.

Gilles Chanteau
*Expert Elite*
_gile
Posts: 2,078
Registered: ‎04-29-2006
Message 3 of 14 (230 Views)

Re : Copy Problems

03-20-2014 12:06 AM in reply to: _gile

Here's a little sample

 

        public static ObjectIdCollection ImportModelSpace(string filename)
        {
            if (!File.Exists(filename))
                throw new FileNotFoundException("File not found", filename);

            Database targetDb = HostApplicationServices.WorkingDatabase;
            ObjectId owner = SymbolUtilityServices.GetBlockModelSpaceId(targetDb);
            IdMapping idMap = new IdMapping();

            using (Database sourceDb = new Database())
            {
                sourceDb.ReadDwgFile(filename, FileShare.Read, false, "");
                using (Transaction tr = sourceDb.TransactionManager.StartTransaction())
                {
                    BlockTableRecord mSpace = (BlockTableRecord)tr.GetObject(
                        SymbolUtilityServices.GetBlockModelSpaceId(sourceDb), OpenMode.ForRead);
                    ObjectIdCollection ids = new ObjectIdCollection(mSpace.Cast<ObjectId>().ToArray());
                    sourceDb.WblockCloneObjects(ids, owner, idMap, DuplicateRecordCloning.Ignore, false);
                    tr.Commit();
                }
            }
            return new ObjectIdCollection(
                idMap
                .Cast<IdPair>()
                .Where(p => p.IsCloned)
                .Select(p => p.Value)
                .ToArray());
        }

 

Gilles Chanteau
Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 4 of 14 (215 Views)

Re : Copy Problems

03-20-2014 07:53 AM in reply to: _gile

I think the code is still a little complicated for me,


Can you help me achieve the following process?  It will be a better way.

 

For example, there is a source drawing which contains a BlockReference called tstrm in the D drive,
Then execute custom command in the new drawing, this target block above will be copied to the new drawings.

Attachment has the source drawings


Extremely grateful

demo.PNG

*Expert Elite*
_gile
Posts: 2,078
Registered: ‎04-29-2006
Message 5 of 14 (210 Views)

Re : Copy Problems

03-20-2014 09:05 AM in reply to: HelloWorlddd

Do you want to add the block reference to the target model space or only import the block definition in the target block table ?

Gilles Chanteau
Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 6 of 14 (206 Views)

Re : Copy Problems

03-20-2014 09:23 AM in reply to: _gile

I do not quite understand the difference between these two
But the result I want is equivalent to using Autocad COPY command , just like copy the graphics to a new drawing, the graphics is same with the old one.

 

The new command that I want to get will work as below:

1,Exceute the command,

2,Automatic drawing that graphics at my specified position, in fact this step the program will access the source drawing and then copy that graphics

 

This small command will save some time during copy, just like select target object and so on

*Expert Elite*
_gile
Posts: 2,078
Registered: ‎04-29-2006
Message 7 of 14 (200 Views)

Re : Copy Problems

03-20-2014 10:16 AM in reply to: HelloWorlddd

First, IMO, if you want to make autoCAD customization, especially with a as sophisticated technology as .NET, you must, above all, master the autoCAD basics as the difference between a block definition (BlockTableRecord) and an insertion of this definition (BlockReference).

 

The AutoCAD COPY command do not allow to copy a graphic object between different drawing (either between two spaces). This can be done with the Windows clipboard technology (Copy/Paste commands) which is tolerate by AutoCAD.

The "AutoCAD way" to do what you describe is using the DesignCenter to import the block definition from another drawing and insert a reference of this block in the model space or elsewhere. This can be done programmatically using the WblockCloneObjects() method as shown upper.

 

You can find a method to import a block definition from an external drawing in this recent thread (reply #7):

http://forums.autodesk.com/t5/NET/How-to-include-extension-dictionary-in-block-inserted-using/td-p/4...

Gilles Chanteau
Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 8 of 14 (158 Views)

Re : Copy Problems

03-23-2014 05:56 AM in reply to: _gile

Thank you very much, I have a learn about WBlockCloneObjects() method in the AutoCAD Developer Guide, it works well.

but I am not very unstudand about your ImportBlock() method, this one has some problem.
Can you fix my code? Just let it work,

 

For example:
filePath=@"D:\SourceDwg\sourceDrawing.dwg"
BlockName="tstrm"
The Block will be import at origin

 

The above attachment has the drawing.

Blow is code,

using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;

[assembly: CommandClass(typeof(AutocadCommandCollection.test6))]


namespace AutocadCommandCollection
{

    class test6
    {

        [CommandMethod("test6")]


        public static void CopyFrom()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;

            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                ObjectId Id = ImportBlock(@"D:\SourceDwg\sourceDrawing.dwg", "tstrm");
                BlockTableRecord btr = (BlockTableRecord)acTrans.GetObject(Id, OpenMode.ForRead);
                acBlkTbl.Add(btr);
                acTrans.AddNewlyCreatedDBObject(btr, true);

                acTrans.Commit();
            }
        }




        private static ObjectId ImportBlock(string fileName, string blockName)
        {
            if (!File.Exists(fileName))
                throw new FileNotFoundException("File not found", fileName);

            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database targetDb = acDoc.Database;
            ObjectId owner = targetDb.BlockTableId;

            using (Database sourceDb = new Database())
            {
                sourceDb.ReadDwgFile(fileName, System.IO.FileShare.Read, false, "");
                using (Transaction tr = sourceDb.TransactionManager.StartOpenCloseTransaction())
                {
                    BlockTable bt = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
                    if (!bt.Has(blockName))
                        return ObjectId.Null;

                    ObjectId id = bt[blockName];
                    ObjectIdCollection ids = new ObjectIdCollection();
                    ids.Add(id);
                    IdMapping idMap = new IdMapping();
                    sourceDb.WblockCloneObjects(ids, owner, idMap, DuplicateRecordCloning.Ignore, false);
                    return idMap[id].IsCloned ? idMap[id].Value : ObjectId.Null;
                }
            }
        }

    }

}

 

 

Valued Contributor
HelloWorlddd
Posts: 87
Registered: ‎05-03-2013
Message 9 of 14 (151 Views)

Re : Copy Problems

03-23-2014 06:45 AM in reply to: HelloWorlddd

I think I finally find the new block after run the code above, the block is existing int the BlockTable or maybe, I can find it throuht the Insert Block drop down list of the Insert Menu.

But It doesn't show as same as the old one after insert manully, I just want Insert the Block in the new drawing, It will be same with the old one.

Can you help me? Very thanks

Picture.PNG

*Expert Elite*
_gile
Posts: 2,078
Registered: ‎04-29-2006
Message 10 of 14 (138 Views)

Re : Copy Problems

03-23-2014 12:21 PM in reply to: HelloWorlddd
        private void ImportBlockReference(string blockName, string filenName)
        {
            if (!File.Exists(filenName))
                throw new FileNotFoundException("File not found", filenName);

            Database targetDb = HostApplicationServices.WorkingDatabase;
            ObjectId owner = SymbolUtilityServices.GetBlockModelSpaceId(targetDb);

            using (Database sourceDb = new Database(false, true))
            {
                sourceDb.ReadDwgFile(filenName, FileShare.ReadWrite, false, "");
                using (Transaction tr = sourceDb.TransactionManager.StartTransaction())
                {
                    BlockTable bt = (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
                    if (!bt.Has(blockName))
                        throw new ArgumentException("Block definition not found", blockName);

                    ObjectIdCollection ids = new ObjectIdCollection();

                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead);
                    ObjectId mSpaceId = SymbolUtilityServices.GetBlockModelSpaceId(sourceDb);
                    foreach (ObjectId id in btr.GetBlockReferenceIds(true, false))
                    {
                        BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForRead);
                        if (br.OwnerId == mSpaceId)
                        {
                            ids.Add(id);
                            break;
                        }
                    }

                    if (ids.Count == 0)
                        throw new ArgumentException("Block reference not found", blockName);

                    IdMapping idMap = new IdMapping();
                    sourceDb.WblockCloneObjects(ids, owner, idMap, DuplicateRecordCloning.Ignore, false);
                }
            }
        }

 

Gilles Chanteau

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community