saitenheini Posted November 9, 2010 Posted November 9, 2010 Hi folks, I've created some blocks and referenced them to a layer with the following code (C#): myBlock.Layer = strLayerName; Now I want the block to be reference by more than one layer. How can I set the reference of this block to another layer while keeping the current layer reference? Thanks for your help! Cheers, Max. Quote
BlackBox Posted November 9, 2010 Posted November 9, 2010 Now I want the block to be reference by more than one layer. How can I set the reference of this block to another layer while keeping the current layer reference? Simple... Copy the block in place (i.e., same insertion point, scale, etc.) to the desired layer. :wink: Quote
saitenheini Posted November 9, 2010 Author Posted November 9, 2010 Thank you, RenderMan! You were right. It's simple and it works. // Create a circle with a radius Circle r = new Circle(); r.SetDatabaseDefaults(); r.Center = new Point3d(x, y, 0); r.Radius = fltRadius; r.Layer = strLayerName[1]; // Add the new object to the block table record and the transaction btr.AppendEntity(r); acTrans.AddNewlyCreatedDBObject(r, true); Circle rClone = r.Clone() as Circle; rClone.Layer = strLayerName[0]; btr.AppendEntity(rClone); acTrans.AddNewlyCreatedDBObject(rClone, true); But what do I have to do, if I want to copy the complete block to an layer? Quote
BlackBox Posted November 9, 2010 Posted November 9, 2010 Thank you, RenderMan! You're welcome. But what do I have to do, if I want to copy the complete block to an layer? This comment is confusing to me... A block is a single object (one that can be made up of other blocks, components, etc.), but when copied, *should* copy every sub-component. Perhaps this will provide some clarity: http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%20.NET%20Developer's%20Guide/index.html ... See the C# example code at Create and Edit AutoCAD Entities > Create Objects > Edit Named and 2D Objects > Copy Objects > Copy an Object Quote
saitenheini Posted November 9, 2010 Author Posted November 9, 2010 It seems, that this is no reference. I want the block to hide if I freeze the layer. But the Entities of the Block are still visible on other layers. I want the whole block in the first layer (hidden/visible) and several entities of the block in different layers to hide them seperatly. Any ideas? Quote
saitenheini Posted November 9, 2010 Author Posted November 9, 2010 A block is a single object (one that can be made up of other blocks, components, etc.), but when copied, *should* copy every sub-component. I thought of a BlockTableRecord when I wrote "block". This BlockTableRecord has a name but no layer attribute. A Circle e.g. is an entity which has an attribute layer. So I wanted to know if it's possible to assign a BlockTableRecord to an Layer? Maybe get this wrong... Sorry:unsure: Quote
BlackBox Posted November 9, 2010 Posted November 9, 2010 It seems, that this is no reference. I want the block to hide if I freeze the layer. But the Entities of the Block are still visible on other layers.I want the whole block in the first layer (hidden/visible) and several entities of the block in different layers to hide them separately. Any ideas? :: The simple solution :: In order for the block to not be displayed, either: The block and it's sub-components must reside on the same layer (being frozen) Or the additional layers for the block's sub-components also need to be frozen. :: The slightly more complex solution :: Develop an Editor Reactor, such that when the encompassing layer is frozen, the block's Visible Property is set to False (if the block is present within the Blocks Collection). Note - This reactor should also handle when the layer is thawed, such that it should also set the Visible Property to True. Edit: The reference to the 'visible property' comes from the ActiveX COM API, as I do not presently have access to Visual Studio, and the ObjectARX SDK from work. Quote
BlackBox Posted November 9, 2010 Posted November 9, 2010 I thought of a BlockTableRecord when I wrote "block". This BlockTableRecord has a name but no layer attribute.A Circle e.g. is an entity which has an attribute layer. So I wanted to know if it's possible to assign a BlockTableRecord to an Layer? Maybe get this wrong... Sorry:unsure: No... the Blocks Collection (or it's items) cannot be assigned to a specific layer, without the use of a reactor forcing instances inserted into the drawing onto a specific layer. This can be triggered by the CommandEnded Callback function, then make a selection set of all blocks with the desired name(s), then step through the selection set and check for the residing layer, if not a match, change the layer property of the block object itself. Quote
saitenheini Posted November 9, 2010 Author Posted November 9, 2010 Thanks a lot for your advice! I will try that. Quote
BlackBox Posted November 9, 2010 Posted November 9, 2010 Thanks a lot for your advice! I will try that. You're welcome. Be sure to post the finished product, when you're done (to help others). Cheers! Quote
Jeff H Posted November 10, 2010 Posted November 10, 2010 I thought of a BlockTableRecord when I wrote "block". This BlockTableRecord has a name but no layer attribute.A Circle e.g. is an entity which has an attribute layer. So I wanted to know if it's possible to assign a BlockTableRecord to an Layer? Maybe get this wrong... Sorry:unsure: You can think of a BlockTableRecord as a container. ("ModelSpace" "PaperSpace") are also BlockTableRecords. The entites that are owned or in the blocktableRecord have a layer property So a receptacle block(Typical duplex symbol) BlockTableRecord will contain a circle(entity) and 2 lines(entites) which will have a layer property.(Typically you draw on layer 0) The visible entity you see is a BlockReference which is a instance of the entites inside the blocktablerecord will have a layer property(Insert command) If that helps Quote
Jeff H Posted November 10, 2010 Posted November 10, 2010 You can have entites on different layers in a BlockTableRecord, but to freeze a "Block" you must freeze the layer the BlockReference is on So if you create a block using Autocad UI with 3 lines on different layers with different colors. Then insert it on a layer you must freeze that layer. From your code and your post I would guess you are adding your entites to the ModelSpace BlockTableRecord. So a blockreference is just another entity added to the ModelSpace blocktablerecord entity collection. (The ModelSpace BlockTableRecord has additional functionality, properties etc.... layout, viewport etc....) If you would like me to post code that might help show or explain I would be happy to. I guess you prefer C# looking at your post Quote
saitenheini Posted November 10, 2010 Author Posted November 10, 2010 From your code and your post I would guess you are adding your entites to the ModelSpace BlockTableRecord. So a blockreference is just another entity added to the ModelSpace blocktablerecord entity collection. (The ModelSpace BlockTableRecord has additional functionality, properties etc.... layout, viewport etc....) Thanks Jeff! You were right. I created different entities (e.g. cirlce, point) and assigned every entity to a separate layer so that I can freeze and unfreeze them separately. Then I added a blockreference to the BlockTable which refers the blocktablerecord containing the entities and assigned the blockreference to a new layer. So when I freeze the new layer all entities are hidden. This code works for me: // Open the Block table for read BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // Create our new block table record... BlockTableRecord btr = new BlockTableRecord(); // Open the Block table for read BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // Create our new block table record... BlockTableRecord btr = new BlockTableRecord(); // Create a point at (x, y, z) in Model space DBPoint acPoint = new DBPoint(new Point3d(x, y, 0)); acPoint.SetDatabaseDefaults(); acPoint.Layer = strLayerName[0]; // Add the new object to the block table record and the transaction btr.AppendEntity(acPoint); acTrans.AddNewlyCreatedDBObject(acPoint, true); // Create a circle with a radius Circle r = new Circle(); r.SetDatabaseDefaults(); r.Center = new Point3d(x, y, 0); r.Radius = fltRadius; r.Layer = strLayerName[1]; // Add the new object to the block table record and the transaction btr.AppendEntity(r); acTrans.AddNewlyCreatedDBObject(r, true); // Open the Block table record Model space for write BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[blockTableRecord.ModelSpace],OpenMode.ForWrite) as BlockTableRecord; BlockReference br = new BlockReference(Point3d.Origin, btrId); br.Layer = strLayerName[0]; acBlkTblRec.AppendEntity(br); acTrans.AddNewlyCreatedDBObject(br, true); // Commit the transaction to save the new object to the database acTrans.Commit(); Hope this helps someone else, too. Cheers, Max. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.