Inserting blocks with XYZ and rotation with .NET

Inserting blocks with XYZ and rotation with .NET

ashuthosh07
Observer Observer
817 Views
9 Replies
Message 1 of 10

Inserting blocks with XYZ and rotation with .NET

ashuthosh07
Observer
Observer

Trying to insert multiple blocks at once using their name definition, coordinates, scale and rotation data from an excel. A windows form is created to prompt user to select the excel file then this snippet of code will insert the blocks, reading that file, Code works successfully but blocks are not visible on screen or they are not drawn. what are the necessary changes required in the code. It is able to successfully read excel data and convert the data in the required form but nothing appears on screen. Any help will be appreciated thank you.

 

public static void Blocks(string selectedFile)
        {
            Document document = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            Database database = document.Database;
            Editor editor = document.Editor;

 

            using (Transaction transaction = database.TransactionManager.StartTransaction())
            {
                using (var stream = File.Open(selectedFile, FileMode.Open, FileAccess.Read))
                {
                    using (var reader = ExcelReaderFactory.CreateReader(stream))
                    {
                        DataSet dataset = reader.AsDataSet(new ExcelDataSetConfiguration()
                        {
                            ConfigureDataTable = (_) => new ExcelDataTableConfiguration() { UseHeaderRow = true }
                        });
                        var dataTable = dataset.Tables[0];
                        string columnHeader1 = dataTable.Columns[0].ColumnName;
                        string columnHeader2 = dataTable.Columns[1].ColumnName;
                        string columnHeader3 = dataTable.Columns[2].ColumnName;
                        string columnHeader4 = dataTable.Columns[3].ColumnName;
                        string columnHeader5 = dataTable.Columns[4].ColumnName;

 

                        if (columnHeader1 == "Name" && columnHeader2 == "x,y,z" && columnHeader3 == "Scale_X" && columnHeader4 == "Scale_Y" && columnHeader5 == "Rotation")
                        {

                                 document.LockDocument();
                                BlockTable bt = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;

                                for (int row = 2; row < dataTable.Rows.Count; row++)
                                {
                                    string blockName = dataTable.Rows[row][0].ToString();
                                    double scaleX = Convert.ToDouble(dataTable.Rows[row][2]);
                                    double scaleY = Convert.ToDouble(dataTable.Rows[row][3]);
                                    double rotation = Convert.ToDouble(dataTable.Rows[row][4]);
                                    string coordinatesValue = dataTable.Rows[row][1].ToString();
                                    string[] coordinatesArray = coordinatesValue.Split(',');

 

                                    if (coordinatesArray.Length == 3)
                                    {
                                        double x = Convert.ToDouble(coordinatesArray[0]);
                                        double y = Convert.ToDouble(coordinatesArray[1]);
                                        double z = Convert.ToDouble(coordinatesArray[2]);

 

 

                                    if (bt.Has(blockName))
                                    {

 

                                       // BlockTableRecord btr = transaction.GetObject(database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                                        using (BlockTableRecord btrc = new BlockTableRecord())
                                        {

                                            BlockReference br = new BlockReference(new Point3d(x, y, z), bt[blockName])
                                            {
                                                ScaleFactors = new Scale3d(scaleX, scaleY, 1.0),
                                                Rotation = rotation,

 

                                            };
                                            transaction.GetObject(database.BlockTableId, OpenMode.ForWrite);
                                            btrc.AppendEntity(br);
                                            bt.Add(btrc);
                                           // transaction.AddNewlyCreatedDBObject(br, true);
                                            document.Editor.UpdateScreen();
                                            editor.WriteMessage($"\nBlock {blockName} inserted {row} ");
                                        }
                                    }
                                    else
                                    {
                                        editor.WriteMessage($"\nBlock '{blockName}' not found.");
                                        return;
                                    }

 

 

                                    }
                                }

                        }
                        else
                        {
                            MessageBox.Show("The Excel file is not in the proper format. Please make sure the column headers are correct.", "Excel Format Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }

 

                        }
                    }
                   transaction.Commit();
                }
            }

Accepted solutions (1)
818 Views
9 Replies
Replies (9)
Message 2 of 10

hosneyalaa
Advisor
Advisor

@ashuthosh07 

 

Can you attached example drawing and  example file excel

0 Likes
Message 3 of 10

norman.yuan
Mentor
Mentor

Looking at your code, I am not very certain what you want to do:

 

Inserting a block reference into current space (ModelSpace or PaperSpace), or creating a new block definition and adding a block reference into the new block definition?

 

Since you mentioned "...nothing appears on screen...", I assume you want to insert a block reference into current space. So, if you look into your code carefully here:

    if (bt.Has(blockName))
    {
	// BlockTableRecord btr = transaction.GetObject(database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
	using (BlockTableRecord btrc = new BlockTableRecord())
	{
	   BlockReference br = new BlockReference(new Point3d(x, y, z), bt[blockName])
	   {
              ScaleFactors = new Scale3d(scaleX, scaleY, 1.0),
              Rotation = rotation
	   };
	   transaction.GetObject(database.BlockTableId, OpenMode.ForWrite);
           btrc.AppendEntity(br);
           bt.Add(btrc);
           // transaction.AddNewlyCreatedDBObject(br, true);
           document.Editor.UpdateScreen();
           editor.WriteMessage($"\nBlock {blockName} inserted {row} ");
	 }
      }

 

Why did you comment out the first line code in the "if..." that opens current space for the new block reference to be added? Instead, your code create a new block definition and add the block reference into the block definition (however, the new block definition is not eventually added into block table, because you commented out Transaction.AddNewlyCreatedDBObject()!). So, even you successfully created the new block definition, it would not appear on screen: it is block definition, not a block reference.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 4 of 10

hippe013
Advisor
Advisor
Accepted solution

You need to tell the transaction that you are adding a new object. You have it commented out. 

 

 // transaction.AddNewlyCreatedDBObject(br, true);

 

Also don't know why you are starting on row 2, you should start on row 0, but whatever... 

for (int row = 2; row < dataTable.Rows.Count; row++)

 

The following does appear to be correct. And parts of that shouldn't be done for each row. It should be placed prior to your for loop. 

 

using (BlockTableRecord btrc = new BlockTableRecord())
                                        {

                                            BlockReference br = new BlockReference(new Point3d(x, y, z), bt[blockName])
                                            {
                                                ScaleFactors = new Scale3d(scaleX, scaleY, 1.0),
                                                Rotation = rotation,

 

                                            };
                                            transaction.GetObject(database.BlockTableId, OpenMode.ForWrite);
                                            btrc.AppendEntity(br);
                                            bt.Add(btrc);
                                           // transaction.AddNewlyCreatedDBObject(br, true);
                                            document.Editor.UpdateScreen();
                                            editor.WriteMessage($"\nBlock {blockName} inserted {row} ");
                                        }

 

 

Switching to VB.... 

These two items you should completed outside of a loop and done only once.

Dim bt As BlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead)
Dim btr As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)

 

To add the object is simply the following:  This is done inside the for loop.

Dim br As New BlockReference(New Point3d(x, y, x), bt(blkName)) With
   {.ScaleFactors = New Scale3d(scaleX, scaleY, 1.0),
    .Rotation = rotation}

   btr.AppendEntity(br)
   tr.AddNewlyCreatedDBObject(br, True)

 

And then finally, out side of the loop.

tr.commit

 

 

 

Message 5 of 10

goswami12897
Enthusiast
Enthusiast

Thank you all for replying, I had written the code I realized the mistake I  was doing that I was repeatedly creating a new BlocktableRecord entry I have rectified that and plugin is working fine now all blocks are getting inserted in autocad and civil3D softwares accordingly, the updated code is as follows 

public static void Blocks(string selectedFile)
{
Document document = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
Database database = document.Database;
Editor editor = document.Editor;

using (Transaction transaction = database.TransactionManager.StartTransaction())
{
using (var stream = File.Open(selectedFile, FileMode.Open, FileAccess.Read))
{
using (var reader = ExcelReaderFactory.CreateReader(stream))
{
DataSet dataset = reader.AsDataSet(new ExcelDataSetConfiguration()
{
ConfigureDataTable = (_) => new ExcelDataTableConfiguration() { UseHeaderRow = true }
});
var dataTable = dataset.Tables[0];
string columnHeader1 = dataTable.Columns[0].ColumnName;
string columnHeader2 = dataTable.Columns[1].ColumnName;
string columnHeader3 = dataTable.Columns[2].ColumnName;
string columnHeader4 = dataTable.Columns[3].ColumnName;
string columnHeader5 = dataTable.Columns[4].ColumnName;

if (columnHeader1 == "Block Name" && columnHeader2 == "x" && columnHeader3 == "y" && columnHeader4 == "z" && columnHeader5 == "Rotation")
{
document.LockDocument();
BlockTable bt = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;

for (int row = 0; row < dataTable.Rows.Count; row++)
{
string blockName = dataTable.Rows[row][0].ToString();
double x = Convert.ToDouble(dataTable.Rows[row][1]);
double y = Convert.ToDouble(dataTable.Rows[row][2]);
double z = Convert.ToDouble(dataTable.Rows[row][3]);
double rotation = Convert.ToDouble(dataTable.Rows[row][4]);

if (bt.Has(blockName))
{

BlockTableRecord btr = transaction.GetObject(database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
BlockReference br = new BlockReference(new Point3d(x, y, z), bt[blockName])
{
ScaleFactors = new Scale3d(1.0, 1.0, 1.0),
Rotation = rotation,
};
transaction.GetObject(database.BlockTableId, OpenMode.ForWrite);
btr.AppendEntity(br);
transaction.AddNewlyCreatedDBObject(br, true);
document.Editor.UpdateScreen();
editor.WriteMessage($"\nBlock {blockName} inserted");

}
else
{
editor.WriteMessage($"\nBlock '{blockName}' not found.");
return;
}


}
}


else
{
MessageBox.Show("The Excel file is not in the proper format. Please make sure the column headers are correct.", "Excel Format Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

}
}
transaction.Commit();
}
}

but I am facing one issue that all the angles are coming different from the angles that are in the excel file any solution for it?

 




0 Likes
Message 6 of 10

fieldguy
Advisor
Advisor

are your angles in radians? 

edit > rads = degrees * PI / 180

Message 7 of 10

hippe013
Advisor
Advisor

@ashuthosh07 , @goswami12897 

Please use the code tags when inserting code into your post. 

 

hippe013_0-1694527859685.png

Thank you. 

Message 8 of 10

goswami12897
Enthusiast
Enthusiast

Thanks it worked well

0 Likes
Message 9 of 10

goswami12897
Enthusiast
Enthusiast

Will surely keep that in mind, from next time I am new to this stuff will take some time to gel-up 😅

0 Likes
Message 10 of 10

goswami12897
Enthusiast
Enthusiast

Thank you all for your replies 😇

0 Likes