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

Repeatedly Insert Block

35 REPLIES 35
SOLVED
Reply
Message 1 of 36
vince1327
4529 Views, 35 Replies

Repeatedly Insert Block

Hey everyone,

 

So i've been able to successfully import a single block at a time into an active drawing, now i'm trying to insert the same block multiple times to essentially create a layout within the drawing. How would i go about inserting a selected block "x" amount of times. For a better idea of where i'm stuck, i've commented a bit of code below with a better explanation.  What i've got so far is this:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DataExtraction;
using Autodesk.AutoCAD.Colors;
using DB_Extraction;
using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;

namespace CHTEST
{
public class CHTEST1
{
// This is the name of my command

[Autodesk.AutoCAD.Runtime.CommandMethod("CHTEST")]

public void CHTEST1()
{
{

Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
Point3d pMax = new Point3d();
string comp = "C:\\ACADSTUFF\\test.dwg";
// int numsprink = 5;

Transaction tr = doc.TransactionManager.StartTransaction();
using (DocumentLock acLckDoc = doc.LockDocument())

try
{

//Check to see if the layer CH-TST already exists, if so use it, if not create it and then use it
string sLayerName1 = "CH-TST";

LayerTable acLyrTbl1; acLyrTbl1 = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
LayerTableRecord acLyrTblRec;

if (acLyrTbl1.Has(sLayerName1) == false)
{
acLyrTblRec = new LayerTableRecord();
// Assign the layer a name
acLyrTblRec.Name = sLayerName1;

// Upgrade the Layer table for write
if (acLyrTbl1.IsWriteEnabled == false) acLyrTbl1.UpgradeOpen();

// Append the new layer to the Layer table and the transaction
acLyrTbl1.Add(acLyrTblRec);
tr.AddNewlyCreatedDBObject(acLyrTblRec, true);
}
else
{
// Open the layer if it already exists for write
acLyrTblRec = tr.GetObject(acLyrTbl1[sLayerName1], OpenMode.ForWrite) as LayerTableRecord;

}


//This partwill import the selected dwg into modelspace and activate it
string dwgName = HostApplicationServices.Current.FindFile(comp, acadApp.DocumentManager.MdiActiveDocument.Database, FindFileHint.Default);

Database db1 = new Database(false, false);

db1.ReadDwgFile(dwgName, System.IO.FileShare.Read, true, "");

ObjectId BlkId;

BlkId = doc.Database.Insert(dwgName, db1, false);

BlockTable bt = (BlockTable)tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead, true);

BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);


//ideally this next section will iterate the import process "x" amount of times and allow for effetive block placement!

// Below is part of some code that i had used to copy a paperspace layout "x" amount of times. I understand the iteration part but am not sure how to apply it to a block. I don't know how to reference the block that i intend to insert and then have it populate "x" amount of times.
/*
for (int i = 1; i <= numLayouts; i++)
{
lm.CopyLayout("Layout1", "SP-" + i.ToString());
Layout layout = (Layout)trx.GetObject(lm.GetLayoutId("SP-" + i.ToString()), OpenMode.ForWrite);

}

*/


//FACSPR7

 

 

BlockReference bref = new BlockReference(pMax, BlkId);

bref.Layer = "CH-TST";

btr.AppendEntity(bref);

tr.AddNewlyCreatedDBObject(bref, true);

bref.ExplodeToOwnerSpace();

bref.Erase();

tr.Commit();


}
catch
{
MessageBox.Show("Failed to read the DWG from the refence folder, are you sure it is present?");
}
finally
{
tr.Dispose();
}

 


}

}
}

}

 

 

 

35 REPLIES 35
Message 2 of 36
VB_Autocad_guy
in reply to: vince1327

Can you clarify a bit? I'll give it a try. But maybe I'm missing your point. 

 

You could just use the same command basically block insert several times and them DB commit when you're done. 

Or just create several instances of a blockreference. Or you can use the copy object command. 

 

Instead of Insert MText entity like in the code below insert a BlockReference Entity

( Dim myBRef As BlockReference)

 

I got this code from:

AutoCAD® .NET Basics, Part I
Stephen Preston – Autodesk Inc

 

Hope you don't mind I'm using VB.NET

 

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices

    Public Class Class1
        <CommandMethod("HelloWorld")> _
        Public Sub MyMethod()
            ' Some variable definitions
            Dim DB As Database
            Dim BT As BlockTable
            Dim MS As BlockTableRecord
            ' Start a transaction to edit the DWG database
            Using trans As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartT()
                ransaction()
                ' Open ModelSpace BlockTableRecord ready to add entity
                DB = Application.DocumentManager.MdiActiveDocument.Database
                BT = trans.GetObject(DB.BlockTableId, OpenMode.ForRead)
                MS = trans.GetObject(BT(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                ' Create a new MText entity and set its text
                Dim txt As MText = New MText
                txt.Contents = "Hello World from VB.NET"
' Add the MText to ModelSpace MS.AppendEntity(txt)
' Add the Mtext to the transaction trans.AddNewlyCreatedDBObject(txt, True)
' Commit transaction so changes persist in the DWG trans.Commit() End Using End Sub End Class

 





Message 3 of 36
vince1327
in reply to: VB_Autocad_guy

For clarification, i can already insert a block, i essentially need to have an argument for my command in which i can specify a positive integer. So if i select the block i want to insert, it will ask me how for how many i would like to insert. I've got pretty much everything downpact except how to insert a block "x" amount of times over. I was thinking of two possible ways. 1.) This would involve just running the command i've posted "x" amount of times, but i'm unsure of the syntax or where to begin. 2.) Copy the block i've chosen to insert "x" amount of times -1. However, i'm still unsure of the syntax or where to begin. From a logic point of view i understand what i have to do, i've got a good amount of experience programming in a variety of languages however this AutoCAD API never ceases to confuse me. What you've posted below makes sense, but im looking more for a way to achieve what you've posted "x" amount of times.

 

Thanks!

Message 4 of 36
cincir
in reply to: vince1327

vince1327 can you tell me ; do you want to insert a block definition x number of times or do you want to create a blockreference of a block definition you have x number of times. maybe i got you wrong but just to be clear :

- do we aggree that a block definition is a blocktablerecord in blocktable symbol table that has entities in it?

- do we aggree that a blockreference is a like an entity that references a blocktablerecord.

 

i mean the block definition is the blueprint while the blockreference is the actual objects in the drawing.

 

as i said before maybe i got you wrong (if so please discard this post) but you want to insert objects to the drawing. so instead of inserting blocktablerecord s xnumber of times try to insert blockreferences of that blocktablerecord x number of times.

 

if that is what you mean please confirm for code example.

Message 5 of 36
vince1327
in reply to: cincir

Hi Cincir,

 

I'm new to AutoCAD overall and i've just spoken with one of our designers who has indeed confirmed what you've said. I'm looking to insert blockreferences of my block "x" number of times. The AutoCAD API is tricky to learn and is sometimes a bit confusing so i appreciate your time trying to help me find what i'm looking for. If you have an example of how to do this, it would be amazing!

 

Thanks

 

Message 6 of 36
cincir
in reply to: vince1327

[CommandMethod("CreateBlockReference")]

public void CreateBlockReference()

{

Document acDoc = Application.DocumentManager.MdiActiveDocument;

Editor acEd = acDoc.Editor;

 

PromptStringOptions acPSO = new PromptStringOptions("Enter the name of block you want to insert:");

PromptResult acPR = acEd.GetString(acPSO);

 

if (acPR.Status == PromptStatus.OK)

{

using (Transaction acTrans = acDoc.TransactionManager.StartTransaction())

{

BlockTable acBlkTbl = acTrans.GetObject(acDoc.Database.BlockTableId, OpenMode.ForRead) as BlockTable;

if (acBlkTbl.Has(acPR.StringResult) == true) // Our BlockTable has block definition that we enter

{

ObjectId acBlockId = acTrans.GetObject(acBlkTbl[acPR.StringResult],OpenMode.ForRead);

 

PromptIntegerOptions acPIO = new PromptInterOptions("Enter the number of times block will be inserted:");

acPIO.AllowNegative = false;

acPIO.AllowZero = false;

PromptIntegerResult acPIR = acEd.GetInteger(acPIO);

 

if (acPIR.Status == PromptStatus.OK)

{

BlockTableRecord acBlkTblRec = acTrans.GetObject(BlockTableRecord.ModelSpace,OpenMode.ForWrite) as BlockTableRecord;

 

Point3d pCenter = new Point3d(0,0,0);

Vector3d vOffset = new Vector3d(10,0,0);

 

for (int i = 0;i < acPIR.Value ; i++)

{

BlockReference acBR = new BlockReference(pCenter , acBlockId);

acBlkTblRec.AppendEntity(acBR);

acTrans.AddNewlyCreatedObject(acBR,true);

pCenter += vOffset;

}

}

}

 

acTrans.Commit();

}

}

}

 

i just wrote it i mean didnt copy-paste so may have syntax errors. feel free to ask questions for this or other stuff.

 

good luck.

Message 7 of 36
VB_Autocad_guy
in reply to: cincir

Like Cincir said: 

 

For each Block Reference use 

.AppendEntity 

.AddNewlyCreatedObject

 

Those are your guys. 

 

It's sure good to hear I'm not the only one who thinks the Autocad API is confusing. 

 

Message 8 of 36
vince1327
in reply to: vince1327

Thanks for the help so far! I'm just stuck on one line below. I get this error in VS 2010 "

Error 1 Cannot implicitly convert type 'Autodesk.AutoCAD.DatabaseServices.BlockTable' to 'Autodesk.AutoCAD.DatabaseServices.ObjectId'" How do i re-arrange this to work?

 

Thanks

 

 

namespace TEST
{
public class TEST
{
// This is the name of my command

[Autodesk.AutoCAD.Runtime.CommandMethod("CHTEST")]

public void TEST()
{
Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Editor acEd = acDoc.Editor;
string comp = "C:\\ACADSTUFF\\test.dwg";

PromptStringOptions acPSO = new PromptStringOptions("Enter the name of block you want to insert:");
PromptResult acPR = acEd.GetString(acPSO);

if (acPR.Status == PromptStatus.OK)
{
using (Transaction acTrans = acDoc.TransactionManager.StartTransaction())
{
BlockTable acBlkTbl = acTrans.GetObject(acDoc.Database.BlockTableId, OpenMode.ForRead) as BlockTable;
if (acBlkTbl.Has(acPR.StringResult) == true) // Our BlockTable has block definition that we enter
{

ObjectId acBlockId = (BlockTable)acTrans.GetObject(acBlkTbl[acPR.StringResult], OpenMode.ForRead);


//ObjectId acBlockId = (BlockTableRecord)acTrans.GetObject(btr[acPR.StringResult], OpenMode.ForWrite);
//ObjectId acBlockId = acTrans.GetObject(acBlkTbl[acPR.StringResult],OpenMode.ForRead);

PromptIntegerOptions acPIO = new PromptIntegerOptions("Enter the number of times block will be inserted:");
acPIO.AllowNegative = false;
acPIO.AllowZero = false;
PromptIntegerResult acPIR = acEd.GetInteger(acPIO);

if (acPIR.Status == PromptStatus.OK)
{

BlockTable bt = (BlockTable)acTrans.GetObject(acDoc.Database.BlockTableId, OpenMode.ForRead, true);
BlockTableRecord acBlkTblRec = (BlockTableRecord)acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

Point3d pCenter = new Point3d(0, 0, 0);
Vector3d vOffset = new Vector3d(10, 0, 0);

for (int i = 0; i < acPIR.Value; i++)
{
BlockReference acBR = new BlockReference(pCenter, acBlockId);
acBlkTblRec.AppendEntity(acBR);
acTrans.AddNewlyCreatedDBObject(acBR, true);
pCenter += vOffset;
}
}
}

acTrans.Commit();
}
}
}
}

}

Message 9 of 36
VB_Autocad_guy
in reply to: vince1327

Hmm.... 

ObjectId acBlockId = (BlockTable)acTrans.GetObject(acBlkTbl[acPR.StringResult], OpenMode.ForRead);

 

Why don't you skip that last line of code? 

Just use: BlockReference acBR = new BlockReference(pCenter, myBlockTable(BlockName));

 

That way you don't have to worry about the object conflict your coming across. 

And as long as a block with that name exists your fine. 

 

Okay so maybe this doesn't help at all. But I figure at least try to excercise my programming brain muscle to make it stronger 🙂

 

Good Luck!

 

Maybe this will help:

Public Function ModelSpaceInsertBlock(ByVal InsPt As Geometry.Point3d, _
	ByVal BlockName As String, ByVal XScale As Double, _
	ByVal YScale As Double, ByVal ZScale As Double) As DatabaseServices.ObjectId
		Dim myBlkID As ObjectId = ObjectId.Null
		Try

			Dim myDwg As Document = Application.DocumentManager.MdiActiveDocument
			Using myTrans As Transaction = myDwg.TransactionManager.StartTransaction

				'Open the database for Write
				Dim myBT As BlockTable = myDwg.Database.BlockTableId.GetObject(OpenMode.ForRead)
				Dim myModelSpace As BlockTableRecord = myBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)

				'Insert the Block
				Dim myBlockDef As BlockTableRecord = myBT(BlockName).GetObject(OpenMode.ForRead)
				Dim myBlockRef As New DatabaseServices.BlockReference(InsPt, myBT(BlockName))
				myBlockRef.ScaleFactors = New Geometry.Scale3d(XScale, YScale, ZScale)

				myModelSpace.AppendEntity(myBlockRef)
				myTrans.AddNewlyCreatedDBObject(myBlockRef, True)
				myBlkID = myBlockRef.ObjectId

				'Append Attribute References to the BlockReference
				Dim myAttColl As DatabaseServices.AttributeCollection
				Dim myEntID As ObjectId
				Dim myEnt As DatabaseServices.Entity
				myAttColl = myBlockRef.AttributeCollection
				For Each myEntID In myBlockDef
					myEnt = myEntID.GetObject(OpenMode.ForWrite)
					If TypeOf myEnt Is DatabaseServices.AttributeDefinition Then
						Dim myAttDef As DatabaseServices.AttributeDefinition = CType(myEnt, AttributeDefinition)
						Dim myAttRef As New DatabaseServices.AttributeReference
						myAttRef.SetAttributeFromBlock(myAttDef, myBlockRef.BlockTransform)
						myAttColl.AppendAttribute(myAttRef)
						myTrans.AddNewlyCreatedDBObject(myAttRef, True)
					End If
				Next

				'Commit the Transaction
				myTrans.Commit()
			End Using
		Catch ex As Exception
			myBlkID = ObjectId.Null
		End Try

		Return myBlkID
	End Function

 

 

I also found this snippet in C#

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

namespace BlockInsertion
{
    public class Class1
    {
        [CommandMethod("Test")]
        public void Test()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            // Get the block name
            PromptStringOptions pso = new PromptStringOptions("\nEnter block name: ");
            PromptResult pr = ed.GetString(pso);
            if (pr.Status == PromptStatus.OK)
            {
                // Start a transaction
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    // Test if block exists in the block table
                    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                    if (!bt.Has(pr.StringResult))
                    {
                        ed.WriteMessage("\nBlock not found.");
                    }
                    else
                    {
                        ObjectId id = bt[pr.StringResult];

                        // Get insertion point
                        PromptPointOptions ppo = new PromptPointOptions("\nSpecify insertion point: ");
                        PromptPointResult ppr = ed.GetPoint(ppo);
                        if (ppr.Status == PromptStatus.OK)
                        {
                            Point3d pt = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);

                            // Create a block reference
                            BlockReference br = new BlockReference(pt, id);

                            // Get Model space
                            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                            // Add the block reference to Model space
                            btr.AppendEntity(br);
                            tr.AddNewlyCreatedDBObject(br, true);
                        }
                    }

                    // Commit the transaction
                    tr.Commit();
                }
            }
        }
    }
}

 

Message 10 of 36
cincir
in reply to: VB_Autocad_guy

ObjectId acBlockId = acTrans.GetObject(acBlkTbl[acPR.StringResult],OpenMode.ForRead);

 

change this line to

 

ObjectId acBlockId = acBlkTbl[acPR.StringResult];

 

as i said before i just typed it not copy - paste. 

Message 11 of 36
vince1327
in reply to: cincir

Thanks a million, i've got it up and running so far, I really do appreciate everyone's help. I have just one last question that may be a bit unrealted, however here goes. When I create my new block reference and append it, it imports on the layer it was on in it's original DWG. How do i specify it to import onto a layer of my choosing. I've tried this already:

 

for (int i = 0; i < quantity; i++)
{

BlockReference bref = new BlockReference(pCenter, BlkId);

bref.Layer = "CH-SPR";

btr.AppendEntity(bref);

tr.AddNewlyCreatedDBObject(bref, true);

pCenter += vOffset;

bref.ExplodeToOwnerSpace();

bref.Erase();

 

}

}
catch
{
MessageBox.Show("Failed to read the DWG from the refence folder, are you sure it is present?");
}
finally
{
tr.Commit();
this.Close();
}

 

Thanks again

Vince

Message 12 of 36
cincir
in reply to: vince1327

what is wrong with your code. it will work if there is a layer named like that. bu you have to set the attributereferences' layer to that only if they exist.if you want to assign LayerId property of the object you must first get your layertablerecord first like this 

LayerTable acLayerTbl = acTrans.GetObject(acCurDB.LayerTableId,OpenMode.ForRead) as LayerTable;

ObjectId acLayerId = ObjectId.Null;
if (acLayerTbl.Has("SomeLayerName"))
{
    acLayerId = acLayerTbl["SomeLayerName"];
}
else
{
    LayerTableRecord acLayerTblRec = new LayerTableRecord();
    acLayerTblRec.Name = "SomeLayerName";
    acLayerTbl.UpgradeOpen();
    acLayerId = acLayerTbl.Add(acLyerTblRec);
    acTrans.AddNewlyCreatedObject(acLayerTblRec,true);
}

acBlkRef.LayerId = acLayerId;

 use this aproach if you want to check if there is the layer you want to assign and create if not.

 

Message 13 of 36
vince1327
in reply to: cincir

Hey Cincir,

 

I've actually create the layer beforehand and can verify that it exists...the code looks like below. I'm not sure why it won't import onto the CH-SPR layer though, this has been one of those small things on my list for weeks now and it's driving me mad.

 

Transaction tr = doc.TransactionManager.StartTransaction();
using (DocumentLock acLckDoc = doc.LockDocument())

try
{

//Check to see if the layer CH-SPR already exists, if so use it, if not create it and then use it
string sLayerName1 = "CH-SPR";

LayerTable acLyrTbl1; acLyrTbl1 = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
LayerTableRecord acLyrTblRec;

if (acLyrTbl1.Has(sLayerName1) == false)
{
acLyrTblRec = new LayerTableRecord();
// Assign the layer a name
acLyrTblRec.Name = sLayerName1;

// Upgrade the Layer table for write
if (acLyrTbl1.IsWriteEnabled == false) acLyrTbl1.UpgradeOpen();

// Append the new layer to the Layer table and the transaction
acLyrTbl1.Add(acLyrTblRec);
tr.AddNewlyCreatedDBObject(acLyrTblRec, true);
}
else
{
// Open the layer if it already exists for write
acLyrTblRec = tr.GetObject(acLyrTbl1[sLayerName1], OpenMode.ForWrite) as LayerTableRecord;

}


//This function will import the selected dwg into modelspace and activate it
if (comboBox1.Text == "FACSPR7")
{
comp = "C:\\ACADSTUFF\\FACSPR7.dwg";

}
if (comboBox1.Text == "FACSPR1")
{
comp = "C:\\ACADSTUFF\\FACSPR1.dwg";

}
if (comboBox1.Text == "FACSPR17")
{
comp = "C:\\ACADSTUFF\\FACSPR17.dwg";

}
if (comboBox1.Text == "FACSPR22")
{
comp = "C:\\ACADSTUFF\\FACSPR22.dwg";

}
if (comboBox1.Text == "FACSPR31")
{
comp = "C:\\ACADSTUFF\\FACSPR31.dwg";

}

string dwgName = HostApplicationServices.Current.FindFile(comp, acadApp.DocumentManager.MdiActiveDocument.Database, FindFileHint.Default);

Database db1 = new Database(false, false);

db1.ReadDwgFile(dwgName, System.IO.FileShare.Read, true, "");

ObjectId BlkId;

BlkId = doc.Database.Insert(dwgName, db1, false);

BlockTable bt = (BlockTable)tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead, true);

BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

int quantity = Convert.ToInt32(numericUpDown1.Value);
Point3d pCenter = new Point3d(0, 0, 0);
Vector3d vOffset = new Vector3d(1000, 0, 0);

for (int i = 0; i < quantity; i++)
{

BlockReference bref = new BlockReference(pCenter, BlkId);

bref.Layer = "CH-SPR";

btr.AppendEntity(bref);

tr.AddNewlyCreatedDBObject(bref, true);

pCenter += vOffset;

bref.ExplodeToOwnerSpace();

bref.Erase();

 

}

}
catch
{
MessageBox.Show("Failed to read the DWG from the refence folder, are you sure it is present?");
}
finally
{
tr.Commit();
this.Close();
}

 


}

}

private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{

}

private void pictureBox1_Click(object sender, EventArgs e)
{

}
}

}

Message 14 of 36
cincir
in reply to: vince1327

vince1327 you are assigning layer to the blockref then erase it after exploding so the individual entities' layers that comprise the block definition must be set in order to accomplish this task. Do you have to explode them?

Message 15 of 36
vince1327
in reply to: cincir

Hey Cincir,

 

The reason that i'm exploding them to ownerspace is because that is the only way that I can get them to show up on the actual drawing. Is there another way?

 

Cheers

Message 16 of 36
cincir
in reply to: vince1327

comment the explodetomodelspce and erase lines and see what will you get 🙂 

Message 17 of 36
vince1327
in reply to: cincir

Cool, so that brough it in as a block reference on the correct layer. The problem though is that I need all the attributes that it would normally have if it was exploded...So right now i'm stuck at crossroads...I can have it brought in and explode it, but it's in the wrong layer...or I could bring it into the correct layer as a block reference but not have any of my attributes...is there a middle ground somewhere. Can i explode it and then transfer it to the correct layer?

 

 

Thanks so much!

Message 18 of 36
cincir
in reply to: vince1327

you are at the wrong tides. your blockreference can have all the attributedefinitions as your blockdefinition as attributereference. 😉

Message 19 of 36
vince1327
in reply to: cincir

hey cincir, i'm not sure what you mean by this...sorry i'm actually very new to this and sometimes the terminology along with the api are very confusing. How do i implement the attributereference that you're talking about?

Message 20 of 36
cincir
in reply to: vince1327

BlkId = doc.Database.Insert(dwgName, db1, false);
BlockTable bt = (BlockTable)tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead, true);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

int quantity = Convert.ToInt32(numericUpDown1.Value);
Point3d pCenter = new Point3d(0, 0, 0);
Vector3d vOffset = new Vector3d(1000, 0, 0);

BlockTableRecord acBlkDef = acTrans.GetObject(BlkId,OpenMode.ForRead) as BlockTableRecord;

for (int i = 0; i < quantity; i++)
{
   BlockReference bref = new BlockReference(pCenter, BlkId);
   
   if (acBlkDef.HasAttributeDefinitions)
   {
      foreach(ObjectId acAttId in acBlkDef)
      {
         Entity acTempEnt = (Entity)acTrans.GetObject(acAttId,OpenMode.ForRead);
         if (acTempEnt is AttributeDefinition)
         {
             AttributeReference acAttRef = new AttributeReference();
              acAttRef.SetAttributeFromBlock((AttributeDefinition)acTempEnt,bref.BlockTransform);
             acAttRef.Layer = "CH-SPR";
             bref.AttributeCollection.AppendAttribute(acAttRef);
             acTrans.AddNewlyCreatedDBObject(acAttRef,true);  
         }
         
      }
   }
   
   bref.Layer = "CH-SPR";
   btr.AppendEntity(bref);
   tr.AddNewlyCreatedDBObject(bref, true);
   pCenter += vOffset;
}

 it is hard to write code without Visual Studio Intellisence 🙂

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