Code Red > .NET

What is the difference between a Block and Blockreference

(1/3) > >>

pjm8765:
Another newbie question that my designers can't answer.  Both are collections of entities (lines, polylines, circles, text etc), but I can find nothing online that explains the difference, why one would be chosen over the other and how they interrelate.  The code I have inherited mixes them interchangeably.

By way of an example, I have some code that creates a BlockReference:


--- Code - vb.net: ---    Public Sub Draw1Lifter(ByVal x As Double, ByVal y As Double, ByRef parent As AcadBlock, ByVal myDocuments As AcadDocumentManagerExample, ByVal strCoreNumber As String)        Dim insertionPt(2) As Double        insertionPt(0) = x        insertionPt(1) = y        insertionPt(2) = 0         importLifterTemplate(myDocuments)         Dim lifterblkref As AcadBlockReference = parent.InsertBlock(insertionPt, "EasiCADLifter", 1, 1, 1, 0.0)        lifterblkref.Layer = "SLABOUTLINE"         'Update core number        Dim props As Object        props = lifterblkref.GetAttributes        Dim attr As AcadAttributeReference         For Each attr In props            If attr.TagString = "LifterCoreNumber" Then                attr.TextString = strCoreNumber                Exit For            End If        Next    End Sub 
But prior to that it calls a subroutine called importLifterTemplate which passes the AcadDocument variable 'myDocuments' by reference.  This is picking up a Block called 'EasiCADLifter' and then manipulating it using an Blockreference 'EasiCADLifterTemp' :



--- Code - vb.net: ---    Public Sub importLifterTemplate(ByRef myDocuments As AcadDocumentManagerExample)        Dim lifterBlock As AcadBlock = Nothing        Dim insertionPt(2) As Double         If lifterTemplateImported Then Exit Sub         Try            lifterBlock = myDocuments.ThisDrawing.Blocks.Item("EasiCADLifter")            lifterBlock.Name = "EasiCADLifterTemp"             Try                Dim filepath As String = System.IO.Path.GetDirectoryName(New System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath) + "\\EasiCADLifter.dwg"                Dim lifterBlockRef As AcadBlockReference = myDocuments.ThisDrawing.ModelSpace.InsertBlock(insertionPt, filepath, 1, 1, 1, 0.0)                lifterBlockRef.Delete()                 ' Delete existing entities from EasiCADLifterTemp block                For Each entity As AcadEntity In lifterBlock                    entity.Delete()                Next                 Dim newBlk As AcadBlock = myDocuments.ThisDrawing.Blocks.Item("EasiCADLifter")                Dim entities(newBlk.Count - 1) As AcadEntity                For index As Integer = 0 To newBlk.Count - 1                    entities(index) = newBlk.Item(index)                Next                newBlk.Delete()                 ' Copy all the entities to the block                Dim copiedObj As Object = myDocuments.ThisDrawing.CopyObjects(entities, lifterBlock)            Catch ex1 As System.Exception                ' ignored            End Try             lifterBlock.Name = "EasiCADLifter"             Dim attrCoreNumber As AcadAttribute            attrCoreNumber = lifterBlock.AddAttribute(75, AcAttributeMode.acAttributeModeNormal, "LifterCoreNumber", insertionPt, "LifterCoreNumber", "")            attrCoreNumber.Visible = False             ' Refresh drawing            myDocuments.ThisDrawing.Regen(AcRegenType.acActiveViewport)        Catch ex As System.Exception            Dim filepath As String = System.IO.Path.GetDirectoryName(New System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath) + "\\EasiCADLifter.dwg"            Dim lifterBlockRef As AcadBlockReference = myDocuments.ThisDrawing.ModelSpace.InsertBlock(insertionPt, filepath, 1, 1, 1, 0.0)            lifterBlockRef.Delete()             Dim attrCoreNumber As AcadAttribute            lifterBlock = myDocuments.ThisDrawing.Blocks.Item("EasiCADLifter")            attrCoreNumber = lifterBlock.AddAttribute(75, AcAttributeMode.acAttributeModeNormal, "LifterCoreNumber", insertionPt, "LifterCoreNumber", "")            attrCoreNumber.Visible = False        End Try        lifterTemplateImported = True    End Sub  
Now when I talk to my designers, they tell me that they use Layers to differentiate different parts of a drawing, not Blocks.  There are a few of the older hands that have used Blocks for metadata...and none of them have heard of a BlockReference.  I can see the blocks on the drawing and view their attributes using BATTMAN, so why is this code using a BlockReference?

I'm going to have to identify this product, just in case the people who wrote this and support it are reading this.  It's called FloorCAD, whom we bought the code off a couple of years ago and is an automation tool that helps designers build precast concrete hollowcore flooring. 

A secondary question I have is about the hierarchy in a document.  I can't find anything that provides an overview of the hierarchy of the contents of a drawing on the web.  Anyone got anything helpful?

Keith Brown:
Here is my quick explanation.  There are others that are much smarter than me that will have better answers.


An autocad drawing is essentially a database that has something called a BlockTable.  The BlockTable is a container for BlockTableRecords.  Model Space is a block table record, paper space is a block table record, any block that you create is a block table record.  So, you have a block that has not been inserted into a drawing but it exists as a block table record.  When you insert that block into the drawing you are not inserting the block table record but instead you are inserting a block reference.  That is an entity that references the block table record.  This is why if you update the block and regen your drawing all instances of that block are updated.

Atook:
Another way of wording it is that a Block is a block definition and a BlockReference is ... well a reference to that block definition. When users insert blocks, they're mostly dealing with block references. If a user wants to see a block definition (ie Block) they have to use the Block Editor. When a block definition is changed, all references in the database/dwg to that block change to the new definition.

To make it more confusing, most cad users refer to BlockReferences as 'blocks'. BlockReference is more a programming term than an end user term.

Hope that helps.

pjm8765:
So a Block is an artefact/construct and each Block reference is an instance of that artefact.  Except that in the tool I'm working with there is a 1 to 1 relationship...normally a designer would build a widget as a block and use it many times...thinking in print here.

Ta very much Keith, the shadow of ignorance is clearing at last...P

gile:
Hi,

In addition to what Keith and Atook said, a block definition (BlockTableRecord .NET type) is a non graphical object as a layer or a dimstyle.
As BlockTableRecord, LayerTableRecord, DimStyleTableRecord (and some others) derive from the same abstract class : SymbolTableRecord, and all are contained in tables deriving from SymbolTable (Blocktable, LayerTable, DimStyleTable, ...).

A block reference (BlockReference .NET type) is a graphical entity as a line or an aligned dimension (all derive from the Entity abstract type). when you insert a block in the model space, the paper space or another block definition (all these containers are BlockTableRecord instances) you create an entity which is only a reference to a block definition: it displays the same set of entities as in the block definiton geometrically transformed (rotated, scaled, displaced).

The relationship between inserted block reference and their block definition can be compared to the relationship between dimensions and their dimension style: if you modify the non graphical records, either the block definition or the dimmension style, this will affect all graphical entities (either block references or dimensions) which refer to them.

Navigation

[0] Message Index

[#] Next page

Go to full version