Copy model Space to another Database

Copy model Space to another Database

carlosrdrzalns
Advocate Advocate
3,590 Views
7 Replies
Message 1 of 8

Copy model Space to another Database

carlosrdrzalns
Advocate
Advocate

Hi there, 

 

I am having problems completing the following instrucción for autoCAD:

 

Given some DWG and a Base Drawing i need to do the following:

create a new directory including copies of the Base drawing with the name of the other DWGs. 

Copy the model space entities from the DWG to the new base DWG with the same name. 

 

I found the command WblockCloneObject() quite interesting to develop the command but i am not able to make it work. From the code below, no error is generated but also no entities have been copied. 

 

I need also to do some copy of the paper space (that is why there is a function called CopyingFromPaperSpace), but that would come later after i have solved this issue. 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using System.Windows;


namespace AYE_SG_ExportacionesCAD_STT
{
    public class Commands
    {

        [CommandMethod("NewCommand")]
        public static void NewCommand()
        {
            DocumentCollection docCol = Application.DocumentManager;
            Document doc = docCol.MdiActiveDocument;
            Database m_database = doc.Database;
            Editor ed = doc.Editor;
            FileInfo[] files = GetDWGFiles(m_database, ed, null);
            string DirectoryPath = CreateDirectory(m_database, ed);
            foreach(FileInfo file in files)
            {
                if (Path.GetFileName(m_database.OriginalFileName)!= file.Name)
                {
                    System.IO.File.Copy(m_database.OriginalFileName, DirectoryPath + @"\" + file.Name, true);
                    CopyModelSpace(file.FullName, ed, DirectoryPath + @"\" + file.Name);
                }
                
            }

        }

        public static string CreateDirectory(Database database, Editor editor)
        {
            string path = Path.GetDirectoryName(database.OriginalFileName)+ @"\NewFiles";
            if (Directory.Exists(path))
            {
                editor.WriteMessage("That Directory Already exist");
                return null;
            }
            try
            {
                DirectoryInfo di = Directory.CreateDirectory(path);
                editor.WriteMessage("\nThe directory was successfully created");
                return path;
            }
            catch
            {
                editor.WriteMessage("\nError creating directory");
                return null;
            }                                   
        }

        public static FileInfo[] GetDWGFiles(Database database, Editor editor, string path)
        {
            if (path == null)
            {
                path = Path.GetDirectoryName(database.OriginalFileName);
            }
             path = Path.GetDirectoryName(database.OriginalFileName);
            DirectoryInfo di = new DirectoryInfo(path);
            FileInfo[] fileInfos = di.GetFiles("*.dwg");
            if(fileInfos!= null )
            {
                return fileInfos;
            }
            else
            {
                return null;
            }            
        }

        public static void CopyingPaperSpace(string sourcefile, string TemplateDatabase, Editor editor, string destinationfileName)
        {
            Database sourcedb = new Database(false, true);
            using (sourcedb)
            {
                try
                {
                    sourcedb.ReadDwgFile(sourcefile, System.IO.FileShare.Read, false, "");
                }
                catch (System.Exception)
                {
                    editor.WriteMessage("\n Unable to read drawing file.");
                }
                using (Transaction sourcetr = sourcedb.TransactionManager.StartTransaction())
                {
                    ObjectId dId;
                    Database destinationdb = new Database(false, true);
                    using (destinationdb){
                        try
                        {
                            destinationdb.ReadDwgFile(TemplateDatabase, FileShare.Read, false, "");
                        }
                        catch(System.Exception)
                        {
                            editor.WriteMessage("\n Unable to read drawing file.");
                        }
                        using (Transaction destinationtr = destinationdb.TransactionManager.StartTransaction())
                        {
                            DBDictionary dlayouts = (DBDictionary)destinationtr.GetObject(destinationdb.LayoutDictionaryId, OpenMode.ForRead);
                            DBDictionary slayouts = (DBDictionary)sourcetr.GetObject(sourcedb.LayoutDictionaryId, OpenMode.ForRead);
                            if (slayouts.Contains("Layout1"))
                            {
                                ObjectIdCollection SourceIds = new ObjectIdCollection();
                                ObjectId sid = slayouts.GetAt("Layout1");
                                Layout slayout = (Layout)sourcetr.GetObject(sid, OpenMode.ForRead);
                                BlockTableRecord bt = (BlockTableRecord)sourcetr.GetObject(slayout.BlockTableRecordId, OpenMode.ForRead);
                                foreach (ObjectId objectId in bt)
                                {
                                    SourceIds.Add(objectId);
                                }
                                BlockReference blkref = CreateBlock(sourcetr, SourceIds, sourcedb);
                                if (blkref == null)
                                {
                                    editor.WriteMessage("\nNo se ha podido crear un bloque a partir del DWG actual ");
                                    return;
                                }
                                SourceIds.Clear();
                                SourceIds.Add(blkref.Id);
                                IdMapping mapping = new IdMapping();
                                if (dlayouts.Contains("DrawingSheet"))
                                {
                                    dId = dlayouts.GetAt("DrawingSheet");
                                    sourcedb.WblockCloneObjects(SourceIds, dId, mapping, DuplicateRecordCloning.Replace, false);
                                    destinationdb.SaveAs(destinationfileName, DwgVersion.Current);
                                }
                                else
                                {
                                    editor.WriteMessage("\nNo se ha encontrado el espacio de papel en el archivo de destino");
                                    return;
                                }

                                
                            }
                        }
                        

                    }


                }
              
            }

        }
        public static void CopyModelSpace(string sourcefile, Editor editor, string destinationfile)
        {
            Database sourcedb = new Database(false, true);
            using (sourcedb)
            {
                try
                {
                    sourcedb.ReadDwgFile(sourcefile, System.IO.FileShare.Read, false, "");
                }
                catch (System.Exception)
                {
                    editor.WriteMessage("\n Unable to read drawing file.");
                }
                using (Transaction sourcetr = sourcedb.TransactionManager.StartTransaction())
                {
                    Database destinationdb = new Database(false, true);
                    using (destinationdb)
                    {
                        try
                        {
                            destinationdb.ReadDwgFile(destinationfile, FileShare.ReadWrite, true, "");
                        }
                        catch (System.Exception)
                        {
                            editor.WriteMessage("\n Unable to read drawing file.");
                        }
                        ObjectId sourceMSId = SymbolUtilityServices.GetBlockModelSpaceId(sourcedb);
                        ObjectId destMSId = SymbolUtilityServices.GetBlockModelSpaceId(destinationdb);
                        ObjectIdCollection SourceIds = new ObjectIdCollection();
                        using (Transaction tr = sourcedb.TransactionManager.StartTransaction())
                        {
                            BlockTableRecord ms = (BlockTableRecord)tr.GetObject(sourceMSId, OpenMode.ForRead);
                            foreach(ObjectId id in ms)
                            {
                                SourceIds.Add(id);
                            }
                            
                        }
                        editor.WriteMessage("\n el numero de objetos en la colección es {0}", SourceIds.Count);
                        using (Transaction desttr = destinationdb.TransactionManager.StartTransaction())
                        {
                            BlockTable destBlockTable = (BlockTable)desttr.GetObject(destinationdb.BlockTableId, OpenMode.ForWrite);
                            BlockTableRecord destBlockTableReord = desttr.GetObject(destBlockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
                            IdMapping mapping = new IdMapping();
                            sourcedb.WblockCloneObjects(SourceIds, destMSId, mapping, DuplicateRecordCloning.Replace, false);
                            desttr.Commit();
                        }
                    }
                }
            }
        }

        public static BlockReference CreateBlock(Transaction tr, ObjectIdCollection Ids, Database db)
        {
            using (tr)
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
                string blkName = "PaperSpaceTemplate";
                if (!bt.Has(blkName))
                {

                
                BlockTableRecord btr = new BlockTableRecord();
                btr.Name = blkName;
                btr.Origin = new Point3d(0, 0, 0);
                ObjectId btrId = bt.Add(btr);
                tr.AddNewlyCreatedDBObject(btr, true);
                foreach(ObjectId id in Ids)
                {
                    Entity dbobj = (Entity)tr.GetObject(id, OpenMode.ForWrite);                   
                    btr.AppendEntity(dbobj);
                    tr.AddNewlyCreatedDBObject(dbobj, true);
                    
                }
                BlockReference blkref = new BlockReference(btr.Origin, btr.ObjectId);
                blkref.ScaleFactors = new Scale3d(1000,1000,1);
                return blkref;
                }
                else
                {
                    return null;
                }
            }
 
        }
       

    }
}

everywhere i found use of WblockCloneObject, one of the databases is the one of the current drawing but that is not my case, i need to copy from a closed drawing into another closed drawing, maybe this could be the problem. The object selection from model space is worrking as i have set some dialog to show quantity of collections and it works fine. 

 

I hope some one here could help me solve this problem. 

Regards. 

0 Likes
Accepted solutions (2)
3,591 Views
7 Replies
Replies (7)
Message 2 of 8

fieldguy
Advisor
Advisor

it's not clear what your final requirement is.  start with copy a dwg file.

string sourcefile = @"source.dwg";
string destfile = @"destination.dwg";
using (Database sourcedb = new Database(false, true))
{
   sourcedb.ReadDwgFile(sourcefile, System.IO.FileShare.Read, false, "");
   sourcedb.SaveAs(destfile, DwgVersion.Current);
}// using sourcedb

 

At this point, you have 2 identical dwg files and nothing has changed in the editor.  

 

0 Likes
Message 3 of 8

_gile
Consultant
Consultant
Accepted solution

Hi,

 

You should have a look at this overload of the Database.Insert method:

https://help.autodesk.com/view/OARX/2019/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_Databas...



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 8

Alexander.Rivilis
Mentor
Mentor

@fieldguy wrote:

it's not clear what your final requirement is.  start with copy a dwg file.

string sourcefile = @"source.dwg";
string destfile = @"destination.dwg";
using (Database sourcedb = new Database(false, true))
{
   sourcedb.ReadDwgFile(sourcefile, System.IO.FileShare.Read, false, "");
   sourcedb.SaveAs(destfile, DwgVersion.Current);
}// using sourcedb

 

At this point, you have 2 identical dwg files and nothing has changed in the editor.  

 


It is easy copy file with static System.IO.File.Copy method.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 5 of 8

carlosrdrzalns
Advocate
Advocate

Thanks all for your reply @Alexander.Rivilis , @_gile , @fieldguy , 

I will writte and example to make things clearer: 

In my current directory I have a file named "AYE_DRAWING_START_FILE", ando other 3 DWGs. Openning "AYE_DRAWING_START_FILE" , i need to create a new directory, then copy the file "AYE_DRAWING_START_FILE" on it as many times as DWGs i have in the previoues directory, and with the name of each DWG. This should be the final result:

 

 

Screenshot_2.png

 

Screenshot_1.png

 

The copy file part of the command it is already solved, with the functions CreateDirectory, GetDWGFiles, and, as @Alexander.Rivilis  says, using System.IO.File.Copy., so i already have my new directory with the files copied on it. 

 

The problem comes when i tried to copy the model space, as i need to copy the model space of a closed DWG (remenber that i have opened "AYE_DRAWING_START_FILE") , "ST150030-AYE-BAS-40-Z11-DRG-SE-0002" of the main directory; on the model space of another closed drawing, "ST150030-AYE-BAS-40-Z11-DRG-SE-0002" of the "NewFiles" Directory. When i tried using WblockCloneObject(), no error are shown but also nothing happens in the new files. 

 

I hope this explanation make things clearer, i will try the @_gile  option. 

 

Thank you. 

Regard. 

0 Likes
Message 6 of 8

carlosrdrzalns
Advocate
Advocate

Trying to use the Database.Insert() method does work but, when i opened the file it request for recovery and some information have been lost. Here is the changed that i have made in the CopyModelSpace() function:

      public static void CopyModelSpace(string sourcefile, Editor editor, string destinationfile)
        {
            Database sourcedb = new Database(false, true);
            using (sourcedb)
            {
                try
                {
                    sourcedb.ReadDwgFile(sourcefile, System.IO.FileShare.Read, false, "");
                }
                catch (System.Exception)
                {
                    editor.WriteMessage("\n Unable to read drawing file.");
                }
                using (Transaction sourcetr = sourcedb.TransactionManager.StartTransaction())
                {
                    Database destinationdb = new Database(false, true);
                    using (destinationdb)
                    {
                        try
                        {
                            destinationdb.ReadDwgFile(destinationfile, FileShare.ReadWrite, true, "");
                        }
                        catch (System.Exception)
                        {
                            editor.WriteMessage("\n Unable to read drawing file.");
                        }
                        destinationdb.Insert(new Matrix3d(), sourcedb, true);
                        destinationdb.SaveAs(destinationfile, DwgVersion.Current);
               
                    }
                }
            }
        }

 

0 Likes
Message 7 of 8

Alexander.Rivilis
Mentor
Mentor
Accepted solution

1. Try to call Database.CloseInput for both databases

2. Remove both transactions as far as you do not use them in your code.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 8 of 8

carlosrdrzalns
Advocate
Advocate

Thanks you so much, but finally i solved it using WblockCloneObjects(), i think that i have opened the destination database only for read and that was the problem. 

The next steps of the commands are taking the contents of and specific paper space, make a block out of it, scale it, and also copy it to the new drawing. This block will then be explode in then new drawing. I has accomplish it, but, when i tried to explode, some of the elements ( viewports) cannot be exploded. Also, if i tried to include the exploding in the code, using ent.explode(objs), and then adding the objs to the BlockTableRecord, but in the paperSpace there is only the blockReference and not the single entities. 

This is the function that i have developed:

public static void CopyPaperSpace(string sourcefile, Editor editor, string destinationfile)
        {
            try
            {


                Database sourcedb = new Database(false, true);
                using (sourcedb)
                {
                    try
                    {
                        sourcedb.ReadDwgFile(sourcefile, System.IO.FileShare.Read, false, "");
                    }
                    catch (System.Exception)
                    {
                        editor.WriteMessage("\n Unable to read drawing file.");
                    }
                    using (Transaction sourcetr = sourcedb.TransactionManager.StartTransaction())
                    {
                        ObjectId dId;
                        DBDictionary slayouts = (DBDictionary)sourcetr.GetObject(sourcedb.LayoutDictionaryId, OpenMode.ForRead);
                        ObjectIdCollection SourceIds = new ObjectIdCollection();
                        if (slayouts.Contains("Layout1"))
                        {
                            ObjectId sid = slayouts.GetAt("Layout1");
                            Layout slayout = (Layout)sourcetr.GetObject(sid, OpenMode.ForRead);
                            BlockTableRecord bt = (BlockTableRecord)sourcetr.GetObject(slayout.BlockTableRecordId, OpenMode.ForWrite);
                            foreach (ObjectId objectId in bt)
                            {
                                Entity ent = (Entity)sourcetr.GetObject(objectId, OpenMode.ForRead);
                                if (ent.Layer != "0")
                                {
                                    SourceIds.Add(objectId);
                                }
                                ent.Dispose();
                            }
                            BlockReference blkref = CreateBlock(SourceIds, sourcedb, editor, bt);
                            sourcetr.AddNewlyCreatedDBObject(blkref, true);
                            if (blkref == null)
                            {
                                editor.WriteMessage("\nNo se ha podido crear un bloque a partir del DWG actual ");
                                return;
                            }
                            SourceIds.Clear();
                            SourceIds.Add(blkref.ObjectId);
                        }
                    
                        Database destinationdb = new Database(false, true);
                        using (destinationdb)
                        {
                            try
                            {
                                destinationdb.ReadDwgFile(destinationfile, FileShare.ReadWrite, true, "");
                            }
                            catch (System.Exception)
                            {
                                editor.WriteMessage("\n Unable to read drawing file.");
                            }
                            using (Transaction destinationtr = destinationdb.TransactionManager.StartTransaction())
                            {
                                DBDictionary dlayouts = (DBDictionary)destinationtr.GetObject(destinationdb.LayoutDictionaryId, OpenMode.ForWrite);
                                
                                    IdMapping mapping = new IdMapping();
                                    if (dlayouts.Contains("DrawingSheet"))
                                    {
                                    dId = dlayouts.GetAt("DrawingSheet");
                                    Layout dlayout = (Layout)destinationtr.GetObject(dId, OpenMode.ForWrite);
                                    BlockTableRecord dbt = (BlockTableRecord)destinationtr.GetObject(dlayout.BlockTableRecordId, OpenMode.ForWrite);
                                    sourcedb.WblockCloneObjects(SourceIds, dbt.ObjectId, mapping, DuplicateRecordCloning.Replace, false);
                                  
                                    ObjectId dblkrefid = mapping.Lookup(SourceIds[0]).Value;
                                    Entity ent = (Entity)destinationtr.GetObject(dblkrefid, OpenMode.ForWrite);
                                    DBObjectCollection objs = new DBObjectCollection();
                                    ent.Explode(objs);
                                    ent.Erase();
                                    foreach (DBObject obj in objs)
                                    {
                                        Entity entity = (Entity)obj;
                                        dbt.AppendEntity(entity);
                                        destinationtr.AddNewlyCreatedDBObject(entity, true);
                                    }
                                    destinationtr.Commit();
                                    destinationdb.SaveAs(destinationfile, DwgVersion.Current);

                                    }
                                    else
                                    {
                                        editor.WriteMessage("\nNo se ha encontrado el espacio de papel en el archivo de destino");
                                        return;
                                    }                               


                                }
                            destinationdb.CloseInput(true);
                            }
                        sourcedb.CloseInput(true);
                        }


                    }

                
            }
            catch (System.Exception exp)
            {
                editor.WriteMessage("\nError al crear el bloque: {0} en {1}, {2}", exp.Message, exp.StackTrace, exp.Source);
                
            }

        }

 

0 Likes