Add File1.dwg contents to File2.dwg

Add File1.dwg contents to File2.dwg

soari.do
Contributor Contributor
1,538 Views
16 Replies
Message 1 of 17

Add File1.dwg contents to File2.dwg

soari.do
Contributor
Contributor

I have two File1.dwg and File2.dwg with some contents in both of them.

I want to add File1 contents to the contents of File2

please help.  My code is 

public void file2file(string fromFile, string toFile) {

// define souce DB
Database fromDb = new Database(false, true);

// define object collection
ObjectIdCollection acObjIdColl = new ObjectIdCollection();

// Lock the current document
using (fromDb) {
// open source file
fromDb.ReadDwgFile(fromFile, FileOpenMode.OpenForReadAndAllShare, false, null);
// Start a transaction
using (Transaction acTrans = fromDb.TransactionManager.StartTransaction()) {
// Open the Block table record for read
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(fromDb.BlockTableId,
OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for write
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForRead) as BlockTableRecord;

// copy/paste each object
foreach (ObjectId id in fromBtr) {
Entity ent = (Entity)fromTr.GetObject(id, OpenMode.ForWrite);
acObjIdColl.Add(ent.ObjectId);

}

// Save the new objects to the database
acTrans.Commit();
}
// Unlock the document
}


// Create a new drawing to copy the objects to
Database acDbNewDoc = new Database(false, true);
using (acDbNewDoc) {
// open source file
acDbNewDoc.ReadDwgFile(toFile, FileOpenMode.OpenForReadAndAllShare, false, null);
// Start a transaction in the new database
using (Transaction acTrans = acDbNewDoc.TransactionManager.StartTransaction()) {
// Open the Block table for read
BlockTable acBlkTblNewDoc;
acBlkTblNewDoc = acTrans.GetObject(acDbNewDoc.BlockTableId,
OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for read
BlockTableRecord acBlkTblRecNewDoc;
acBlkTblRecNewDoc = acTrans.GetObject(acBlkTblNewDoc[BlockTableRecord.ModelSpace],
OpenMode.ForRead) as BlockTableRecord;
//foreach (Entity id1 in acObjIdColl) {
foreach (Entity nent in acDBObjColl) {
destBtr.AppendEntity(nent);
destTr.AddNewlyCreatedDBObject(nent, true);
}
// Save the copied objects to the database
acTrans.Commit();
}
// Unlock the document
}
// Set the new document current
acDbNewDoc.SaveAs(toFile, DwgVersion.Current);
}

Moderator edit: Put code in code window.

0 Likes
Accepted solutions (1)
1,539 Views
16 Replies
Replies (16)
Message 2 of 17

_gile
Consultant
Consultant
Accepted solution

Hi,

 

First, please use the "Insert/Edit code sample" button (</>) when you paste code so that it is more readable.

 

The code you posted looks like a patchwork of code snippets copied/pasted from multiple sources that seems to never have been tested. It try to use some variable names which have never been declared (fromBtr, formTr, acDbObjCol, destBtr, destTr). Visual Studio alert you for this.

 

_gile_0-1665576238212.png

 
 

 

_gile_3-1665576294779.png

 

This should work:

 

 

        public static void AddFilecontents(string sourceFilename, string targetFileName)
        {
            try
            {
                using (var targetDb = new Database(false, true))
                using (var sourceDb = new Database(false, true))
                {
                    sourceDb.ReadDwgFile(sourceFilename, FileOpenMode.OpenForReadAndAllShare, false, null);
                    targetDb.ReadDwgFile(targetFileName, FileOpenMode.OpenForReadAndAllShare, false, null);
                    var sourceModelSpaceId = SymbolUtilityServices.GetBlockModelSpaceId(sourceDb);
                    var targetModelSpaceId = SymbolUtilityServices.GetBlockModelSpaceId(targetDb);
                    var ids = new ObjectIdCollection();
                    using (var tr = sourceDb.TransactionManager.StartTransaction())
                    {
                        var sourceModelSpace = (BlockTableRecord)tr.GetObject(sourceModelSpaceId, OpenMode.ForRead);
                        foreach (ObjectId id in sourceModelSpace)
                        {
                            ids.Add(id);
                        }
                        tr.Commit();
                    }
                    var mapping = new IdMapping();
                    sourceDb.WblockCloneObjects(ids, targetModelSpaceId, mapping, DuplicateRecordCloning.Ignore, false);
                    targetDb.SaveAs(targetFileName, DwgVersion.Current);
                }
            }
            catch (System.Exception ex)
            {
                Application.ShowAlertDialog(ex.Message);
                var ed = Application.DocumentManager.MdiActiveDocument.Editor;
                ed.WriteMessage($"\n{ex.Message}\n{ex.StackTrace}\n");
            }
        }

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 17

soari.do
Contributor
Contributor

Thank you for the help, it worked.

But the position of the entities are not same as in File1.dwg.

if I use this method in serial for different files, like

AddFilecontents(f1, f2);

AddFilecontents(f3, f2);

f1 contents are overlaped by f3 contents in f2.

Any further suggestion, please...

0 Likes
Message 4 of 17

_gile
Consultant
Consultant

Please, post some simple drawing examples to show what you want.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 17

soari.do
Contributor
Contributor

Please see the attached image

expected.png

0 Likes
Message 6 of 17

soari.do
Contributor
Contributor

presentcode.png

0 Likes
Message 7 of 17

cuongtk2
Advocate
Advocate

AddFilecontents(f1, f2) -> f2 

public static void AddFilecontents(string sourceFilename, string targetFileName, Point3d insertPoint = new Point3d())
        {
            using (var targetDb = new Database(true, false))
            {
                targetDb.ReadDwgFile(targetFileName, System.IO.FileShare.ReadWrite, false, null);
                using (var sourceDb = new Database(true, false))
                {
                    sourceDb.ReadDwgFile(sourceFilename, System.IO.FileShare.ReadWrite, false, null);
                    Matrix3d matrix = Matrix3d.Displacement(insertPoint - Point3d.Origin);
                    targetDb.Insert(matrix, sourceDb, true);
                    targetDb.SaveAs(targetFileName, DwgVersion.Current);
                }    
            }
        }

 

0 Likes
Message 8 of 17

_gile
Consultant
Consultant

@soari.do

The images don't help. The code works with WCS coordinates, keeping the origin (0, 0, 0) of each drawing.

Please provide DWG files so that we can understand the issue.

 

Here's a screencast showing the following command in action.

        [CommandMethod("TEST")]
        public static void Test()
        {
            AddFilecontents(@"B:\Desktop\Drawings\File1.dwg", @"B:\Desktop\Drawings\File3.dwg");
            AddFilecontents(@"B:\Desktop\Drawings\File2.dwg", @"B:\Desktop\Drawings\File3.dwg");
        }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 17

soari.do
Contributor
Contributor

Thank you so much, it helped me a lot, I could adjust the coordinates.

One other issue I faced, which I did not expect.

I coded to remove duplicates, but after removing duplicates, I opened the file and "Select-All" run "Overkill" command, it showed

0 duplicates deleted

8360 overlapping objects or segments deleted. (see image for reference)

I have no idea how to identify and delete overlapping objects.

Please help me to delete overlapping objects using C#.

overlapping.png

0 Likes
Message 10 of 17

k005
Advisor
Advisor

this is so beautiful! I think there should be something like this;

 

Adding X or Y coordinates from outside and collecting the drawings according to this coordinate.

 

There is overlapping in the current code...

 

I am attaching sample dwg.

 

In the example, I gave the value of X coordinate 300. and that should go incrementally. In the form of 300, 600,900, so... Of course, in this case, excessive space of drawing-parts may occur. this is editable. from the drawing.

 

 

0 Likes
Message 11 of 17

soari.do
Contributor
Contributor

Sir, 

the code works fine but some asian characters are not displaying correctly in File2, after copying from File1 to File2. In File2 the text displays as ????, but when I click on it and check the properties, it shows correctly in properties.

Could you kindly suggest how to fix it.

 

Thanks

Rao

0 Likes
Message 12 of 17

soari.do
Contributor
Contributor
Sir,

the code works fine but some asian characters are not displaying correctly in File2, after copying from File1. In File2 the text displays as ????, but when I click on it and check the properties, it shows correctly in properties, but not in model space.

Could you kindly suggest how to fix it.

Thanks
Rao
0 Likes
Message 13 of 17

_gile
Consultant
Consultant

Sorry, I have no idea. I only use Latin characters.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 14 of 17

cuongtk2
Advocate
Advocate

Example:

before:

dwg1: Text style "Standard"  use font txt.shx

dwg2: Text style "Standard"  use font Arial.ttf , dbtext1 content "việt nam"

after import dwg2 to dwg1 :

dbtext1 display content "vi?t nam"  in dwg1, because txt.shx not support Unicode chacrater.

You must note that the font in the textstyle of 2 drawings must be the same.

0 Likes
Message 15 of 17

soari.do
Contributor
Contributor

Thank you sir,

Here is the result, please see attached image.

In properties of both files it shows correctly and property name is also same.

But in model space font is not correctly displaying.

Any further settings suggested.

Please.

Thankyou

Rao

file.png

0 Likes
Message 16 of 17

_gile
Consultant
Consultant

Check the Font of the 'Standard' textstyle in both files.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 17 of 17

soari.do
Contributor
Contributor

Thank you sir, 

I solved in other way.

0 Likes