TheSwamp

Code Red => .NET => Topic started by: pjm8765 on March 22, 2017, 11:21:59 AM

Title: What is the difference between a Block and Blockreference
Post by: pjm8765 on March 22, 2017, 11:21:59 AM
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: [Select]
  1.     Public Sub Draw1Lifter(ByVal x As Double, ByVal y As Double, ByRef parent As AcadBlock, ByVal myDocuments As AcadDocumentManagerExample, ByVal strCoreNumber As String)
  2.         Dim insertionPt(2) As Double
  3.         insertionPt(0) = x
  4.         insertionPt(1) = y
  5.         insertionPt(2) = 0
  6.  
  7.         importLifterTemplate(myDocuments)
  8.  
  9.         Dim lifterblkref As AcadBlockReference = parent.InsertBlock(insertionPt, "EasiCADLifter", 1, 1, 1, 0.0)
  10.         lifterblkref.Layer = "SLABOUTLINE"
  11.  
  12.         'Update core number
  13.         Dim props As Object
  14.         props = lifterblkref.GetAttributes
  15.         Dim attr As AcadAttributeReference
  16.  
  17.         For Each attr In props
  18.             If attr.TagString = "LifterCoreNumber" Then
  19.                 attr.TextString = strCoreNumber
  20.                 Exit For
  21.             End If
  22.         Next
  23.     End Sub
  24.  

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: [Select]
  1.     Public Sub importLifterTemplate(ByRef myDocuments As AcadDocumentManagerExample)
  2.         Dim lifterBlock As AcadBlock = Nothing
  3.         Dim insertionPt(2) As Double
  4.  
  5.         If lifterTemplateImported Then Exit Sub
  6.  
  7.         Try
  8.             lifterBlock = myDocuments.ThisDrawing.Blocks.Item("EasiCADLifter")
  9.             lifterBlock.Name = "EasiCADLifterTemp"
  10.  
  11.             Try
  12.                 Dim filepath As String = System.IO.Path.GetDirectoryName(New System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath) + "\\EasiCADLifter.dwg"
  13.                 Dim lifterBlockRef As AcadBlockReference = myDocuments.ThisDrawing.ModelSpace.InsertBlock(insertionPt, filepath, 1, 1, 1, 0.0)
  14.                 lifterBlockRef.Delete()
  15.  
  16.                 ' Delete existing entities from EasiCADLifterTemp block
  17.                 For Each entity As AcadEntity In lifterBlock
  18.                     entity.Delete()
  19.                 Next
  20.  
  21.                 Dim newBlk As AcadBlock = myDocuments.ThisDrawing.Blocks.Item("EasiCADLifter")
  22.                 Dim entities(newBlk.Count - 1) As AcadEntity
  23.                 For index As Integer = 0 To newBlk.Count - 1
  24.                     entities(index) = newBlk.Item(index)
  25.                 Next
  26.                 newBlk.Delete()
  27.  
  28.                 ' Copy all the entities to the block
  29.                 Dim copiedObj As Object = myDocuments.ThisDrawing.CopyObjects(entities, lifterBlock)
  30.             Catch ex1 As System.Exception
  31.                 ' ignored
  32.             End Try
  33.  
  34.             lifterBlock.Name = "EasiCADLifter"
  35.  
  36.             Dim attrCoreNumber As AcadAttribute
  37.             attrCoreNumber = lifterBlock.AddAttribute(75, AcAttributeMode.acAttributeModeNormal, "LifterCoreNumber", insertionPt, "LifterCoreNumber", "")
  38.             attrCoreNumber.Visible = False
  39.  
  40.             ' Refresh drawing
  41.             myDocuments.ThisDrawing.Regen(AcRegenType.acActiveViewport)
  42.         Catch ex As System.Exception
  43.             Dim filepath As String = System.IO.Path.GetDirectoryName(New System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath) + "\\EasiCADLifter.dwg"
  44.             Dim lifterBlockRef As AcadBlockReference = myDocuments.ThisDrawing.ModelSpace.InsertBlock(insertionPt, filepath, 1, 1, 1, 0.0)
  45.             lifterBlockRef.Delete()
  46.  
  47.             Dim attrCoreNumber As AcadAttribute
  48.             lifterBlock = myDocuments.ThisDrawing.Blocks.Item("EasiCADLifter")
  49.             attrCoreNumber = lifterBlock.AddAttribute(75, AcAttributeMode.acAttributeModeNormal, "LifterCoreNumber", insertionPt, "LifterCoreNumber", "")
  50.             attrCoreNumber.Visible = False
  51.         End Try
  52.         lifterTemplateImported = True
  53.     End Sub
  54.  
  55.  

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?
Title: Re: What is the difference between a Block and Blockreference
Post by: Keith Brown on March 22, 2017, 11:50:25 AM
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.
Title: Re: What is the difference between a Block and Blockreference
Post by: Atook on March 22, 2017, 12:06:41 PM
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.
Title: Re: What is the difference between a Block and Blockreference
Post by: pjm8765 on March 22, 2017, 12:18:54 PM
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

Title: Re: What is the difference between a Block and Blockreference
Post by: gile on March 22, 2017, 12:26:27 PM
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.
Title: Re: What is the difference between a Block and Blockreference
Post by: pjm8765 on March 22, 2017, 12:40:06 PM
Thanks ATook...From our viewpoint using the word "instance" would be more accurate.  A reference is a pointer to an instance of a thing.  I've found in my short time working in the engineering trade that the use of correct English is entirely optional (in precast concrete we have shelves that are not flat, cantilevers that don't have a pivot or move, biscuits that are panels and something called a rebated end which is a shelf....I'm sure there are others).  I shouldn't be too critical, we programmers are often just as bad.

I would have hoped for an AcadBlock to have a collection of BlockReferences and an AcadBlockReference to have an explicit link to its Block.  But I'm guessing with the latter that a Block reference is a copy of a Block and therefore independent of it's original parent Block...which makes the use of the term "reference" even less accurate.  C'est la vie
Title: Re: What is the difference between a Block and Blockreference
Post by: Jeff H on March 22, 2017, 12:44:50 PM
Oops a couple of people got in before me so this might be a repeat.


A few points
If you select a BlockReference and look at its properties in AutoCAD or look at its methods and properties, you will notice most are "translational" like position, scale, rotation. You can also have the blockreferences manipulate the layers.


What it boils down to is blockreference just pushes a transformation matrix in the graphics pipeline then calls Draw on the BlockTableRecord  which just iterates through all the entities it contains drawing them with position, scale and rotation applied then it pops the transformation matrix.

AttributesDefinitions inside the BlockDefinition create a AttributeReference for each BlockReference which is then added to collection of AttributeReference for each BlockReference. Thats why attributes can be different.

When you get to dynamic blocks they seem like it would be impossible because if two blockreference's are using the same definition they could only vary in scale, position, rotation, or color, but in they are playing tricks and creating different blockdefinitions for every different set of properties set for the dynamic block.
 
Title: Re: What is the difference between a Block and Blockreference
Post by: dgorsman on March 22, 2017, 02:26:05 PM
Simplest way of looking at it: blocks are almost exactly like XREFs (internally they are virtually identical as well) which use a definition inside the file instead of an external file.  For both its one definition, multiple references.
Title: Re: What is the difference between a Block and Blockreference
Post by: Bobby C. Jones on March 22, 2017, 02:29:31 PM
I work with a group of enterprise developers with no AutoCAD or Revit API experience.  I told them that from a high level a block is to a blockreference as a class is to an object instance; they seemed to grock that pretty well.
Title: Re: What is the difference between a Block and Blockreference
Post by: gile on March 22, 2017, 02:32:31 PM
I work with a group of enterprise developers with no AutoCAD or Revit API experience.  I told them that from a high level a block is to a blockreference as a class is to an object instance; they seemed to grock that pretty well.
I like this one.
Title: Re: What is the difference between a Block and Blockreference
Post by: Keith Brown on March 22, 2017, 02:38:05 PM
I work with a group of enterprise developers with no AutoCAD or Revit API experience.  I told them that from a high level a block is to a blockreference as a class is to an object instance; they seemed to grock that pretty well.
I like this one.


A very good analogy.  I also like JeffH's explanation.
Title: Re: What is the difference between a Block and Blockreference
Post by: gile on March 22, 2017, 03:57:05 PM
I work with a group of enterprise developers with no AutoCAD or Revit API experience.  I told them that from a high level a block is to a blockreference as a class is to an object instance; they seemed to grock that pretty well.
I like this one.


A very good analogy.  I also like JeffH's explanation.

My problem is: most of the time when I tried to explain the difference / relationship between block reference and block definition, my interlocutor had a better knowledge of AutoCAD blocks than of OOP...
Title: Re: What is the difference between a Block and Blockreference
Post by: Bobby C. Jones on March 22, 2017, 04:23:47 PM


My problem is: most of the time when I tried to explain the difference / relationship between block reference and block definition, my interlocutor had a better knowledge of AutoCAD blocks than of OOP...

Yea, you know me!
Title: Re: What is the difference between a Block and Blockreference
Post by: It's Alive! on March 25, 2017, 09:37:18 PM
Also, Block References can 'own' Attribute entities