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

Dynamic Block Attribute Move

17 REPLIES 17
Reply
Message 1 of 18
Dale.Bartlett
970 Views, 17 Replies

Dynamic Block Attribute Move

Hi All,
I have a problem with using .Net to insert a dynamic block and set the size property. The atrtribute text does not move correctly on insert, but will if manually stretched after the fact. From my research the recommendation is to make sure the attribute definition is marked as "Locked". However this has not solved my problem. I have an attribute definition inside a circle (classic door/window number), both the circle and attribute are included in the Action Selection Set, however only the circle moves correctly. It all works correctly if manually inserted/stretched. Any sage advice very much appreciated.
Regards,
Dale



______________
Yes, I'm Satoshi.
17 REPLIES 17
Message 2 of 18
Anonymous
in reply to: Dale.Bartlett


Try posting the relevant parts of your code.


 

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000
through 2009

href="http://www.acadxtabs.com">http://www.acadxtabs.com

 


 

 


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
Hi
All, I have a problem with using .Net to insert a dynamic block and set the
size property. The atrtribute text does not move correctly on insert, but will
if manually stretched after the fact. From my research the recommendation is
to make sure the attribute definition is marked as "Locked". However this has
not solved my problem. I have an attribute definition inside a circle (classic
door/window number), both the circle and attribute are included in the Action
Selection Set, however only the circle moves correctly. It all works correctly
if manually inserted/stretched. Any sage advice very much appreciated.
Regards, Dale
Message 3 of 18

Hi Tony,
I'm open to any and all comments...
Thanks, Dale

'insert block either dynamic or not
lstrBlockName = "Test"
'create block definition
If bt.Has(lstrBlockName) = True Then
btrDrawobjectBlock = ta.GetObject(bt.Item(lstrBlockName), OpenMode.ForRead)
id = btrDrawobjectBlock.Id
Else
dbDwg = New Database
dbDwg.ReadDwgFile(gstrFolderBlocks & "/" & lstrBlockName & ".dwg", IO.FileShare.Read, True, "")
id = db.Insert(lstrBlockName, dbDwg, False)
End If
lblkDrawObject = New BlockReference(lpntInsertPoint, id)
If lblkDrawObject.IsDynamicBlock = False Then
'MsgBox(lstrBlockName & " is not a dynamic block")
'set scale factor - not used in dynamic block
lblkDrawObject.ScaleFactors = lsclScaleFactor
End If
'set rotation
lblkDrawObject.Rotation = 0
'add entity
btrShedBlock.AppendEntity(lblkDrawObject)
'tell transaction
ta.AddNewlyCreatedDBObject(lblkDrawObject, True)
'Get the dynamic block ref's properties (params)
If lblkDrawObject.IsDynamicBlock = True Then
dynBlkRefProps = lblkDrawObject.DynamicBlockReferencePropertyCollection
For Each dynBlkRefProp In dynBlkRefProps
'Set width and height
Select Case UCase(dynBlkRefProp.PropertyName)
Case UCase("Width")
dynBlkRefProp.Value = ldblPropertyWidthValue
Case UCase("Height")
dynBlkRefProp.Value = ldblPropertyHeightValue
Case UCase("DoorSwingLeft")
dynBlkRefProp.Value = lshtPropertySwingValue
Case UCase("RollerDoorOnOff")
dynBlkRefProp.Value = lstrPropertyRollerDoorValue
Case Else
'MsgBox(dynBlkRefProp.PropertyName)
End Select
Next
End If
'modify the attribute of the block reference
'this will ignore blocks without attributes
btAttRec = ta.GetObject(id, OpenMode.ForRead)
For Each idAtt In btAttRec
Dim ent As Entity
ent = ta.GetObject(idAtt, OpenMode.ForRead)
If TypeOf ent Is AttributeDefinition Then
Dim attDef As AttributeDefinition
attDef = CType(ent, AttributeDefinition)
Dim attRef As New AttributeReference()
attRef.SetAttributeFromBlock(attDef, lblkDrawObject.BlockTransform)
'attRef.Position = ptBase
'set attributes to always horizontal, allowing for shed rotation
attRef.Rotation = 0
'attRef.Tag = attDef.Tag
Select Case UCase(attDef.Tag)
Case UCase("DOORNUM"), UCase("WINNUM")
attRef.TextString = lcDrawObject.DoorWinNumber
End Select
'attRef.Height = attDef.Height
'attRef.FieldLength = attDef.FieldLength
Dim idTmp As ObjectId
idTmp = lblkDrawObject.AttributeCollection.AppendAttribute(attRef)
ta.AddNewlyCreatedDBObject(attRef, True)
End If
Next



______________
Yes, I'm Satoshi.
Message 4 of 18
Anonymous
in reply to: Dale.Bartlett


The news server reformatted your code.

 

Try posting again with the code surrounded by code
tags.


 

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000
through 2009

href="http://www.acadxtabs.com">http://www.acadxtabs.com

 


 

 


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
Hi
Tony, I'm open to any and all comments... Thanks, Dale 'insert block either
dynamic or not lstrBlockName = "Test" 'create block definition If
bt.Has(lstrBlockName) = True Then btrDrawobjectBlock =
ta.GetObject(bt.Item(lstrBlockName), OpenMode.ForRead) id =
btrDrawobjectBlock.Id Else dbDwg = New Database
dbDwg.ReadDwgFile(gstrFolderBlocks & "/" & lstrBlockName & ".dwg",
IO.FileShare.Read, True, "") id = db.Insert(lstrBlockName, dbDwg, False) End
If lblkDrawObject = New BlockReference(lpntInsertPoint, id) If
lblkDrawObject.IsDynamicBlock = False Then 'MsgBox(lstrBlockName & " is
not a dynamic block") 'set scale factor - not used in dynamic block
lblkDrawObject.ScaleFactors = lsclScaleFactor End If 'set rotation
lblkDrawObject.Rotation = 0 'add entity
btrShedBlock.AppendEntity(lblkDrawObject) 'tell transaction
ta.AddNewlyCreatedDBObject(lblkDrawObject, True) 'Get the dynamic block ref's
properties (params) If lblkDrawObject.IsDynamicBlock = True Then
dynBlkRefProps = lblkDrawObject.DynamicBlockReferencePropertyCollection For
Each dynBlkRefProp In dynBlkRefProps 'Set width and height Select Case
UCase(dynBlkRefProp.PropertyName) Case UCase("Width") dynBlkRefProp.Value =
ldblPropertyWidthValue Case UCase("Height") dynBlkRefProp.Value =
ldblPropertyHeightValue Case UCase("DoorSwingLeft") dynBlkRefProp.Value =
lshtPropertySwingValue Case UCase("RollerDoorOnOff") dynBlkRefProp.Value =
lstrPropertyRollerDoorValue Case Else 'MsgBox(dynBlkRefProp.PropertyName) End
Select Next End If 'modify the attribute of the block reference 'this will
ignore blocks without attributes btAttRec = ta.GetObject(id, OpenMode.ForRead)
For Each idAtt In btAttRec Dim ent As Entity ent = ta.GetObject(idAtt,
OpenMode.ForRead) If TypeOf ent Is AttributeDefinition Then Dim attDef As
AttributeDefinition attDef = CType(ent, AttributeDefinition) Dim attRef As New
AttributeReference() attRef.SetAttributeFromBlock(attDef,
lblkDrawObject.BlockTransform) 'attRef.Position = ptBase 'set attributes to
always horizontal, allowing for shed rotation attRef.Rotation = 0 'attRef.Tag
= attDef.Tag Select Case UCase(attDef.Tag) Case UCase("DOORNUM"),
UCase("WINNUM") attRef.TextString = lcDrawObject.DoorWinNumber End Select
'attRef.Height = attDef.Height 'attRef.FieldLength = attDef.FieldLength Dim
idTmp As ObjectId idTmp =
lblkDrawObject.AttributeCollection.AppendAttribute(attRef)
ta.AddNewlyCreatedDBObject(attRef, True) End If Next
Message 5 of 18

Hi Tony,
I couldn't find anything on using code tags, and most samples have lost indenting, so I have attached a txt file instead.
Regards,
Dale



______________
Yes, I'm Satoshi.
Message 6 of 18

Hi All,
Here is a response from ADN support:
Thanks for including the code. I am able to recreate the behavior. If just change the order of some parts it works fine. Please append attributes to BlockReference *before* change dynamic properties, so your block reference will behave as expected.
Thanks Tony and others who may have checked for me. It seems obvious now....
Regards,
Dale



______________
Yes, I'm Satoshi.
Message 7 of 18
Anonymous
in reply to: Dale.Bartlett

I am having this issue with attributes period, regardless of whether or not they are dynamic...



I have noticed that the attributes end up in the correct location in the DXF output...but not in the DWG output...



...and I am appending the attributes to the blockreference BEFORE any change (even w/o a change to them this occurs)...



any insight?
Message 8 of 18
Anonymous
in reply to: Dale.Bartlett


Shared Sub ApplyAttributeDef(ByRef BlockReference As Autodesk.AutoCAD.DatabaseServices.BlockReference)

Dim Block As BlockTableRecord = BlockReference.BlockTableRecord.GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)

If Not Block.HasAttributeDefinitions Then Exit Sub

If Block.Database Is Nothing Then Exit Sub



Dim Trans As Transaction = Block.Database.TransactionManager.StartTransaction

Try

If BlockReference.Database Is Nothing Then Block.Database.AddDBObject(BlockReference)



For Each Id As ObjectId In Block

Dim Ent As Entity = Id.GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)



If TypeOf Ent Is AttributeDefinition Then

Dim AttDef As AttributeDefinition = Ent

Dim AttRef As New AttributeReference



BlockReference.AttributeCollection.AppendAttribute(AttRef)

AttRef.SetPropertiesFrom(AttDef)

AttRef.SetAttributeFromBlock(AttDef, BlockReference.BlockTransform)

Trans.AddNewlyCreatedDBObject(AttRef, True)

End If

Next

Trans.Commit()

Catch ex As Autodesk.AutoCAD.Runtime.Exception

Trans.Abort()

Finally

Trans.Dispose()

End Try

End Sub






The sub is how I am applying the attribute defs, the result I am getting (again, only in DWG output, not in DXF output) is attached.



As you see the visible attribute (text, the number '1' in this case) is does appear...however, it should be centered within the block (rect w/circle inscribed in it). when the blockref is doubleclicked in in the drawing by a user and the value changed (or even left the same), the attribute will 'move' to the correct location!
Message 9 of 18

Hi Askrius,
I have followed your responses to this issue, I have had no reliable success. Do you have a definitive .Net example that has been working consistantly for your project? I had some feedback from ADN with regard the attribute font being found, however that has not resolved the issue. Thanks for any comment.
Regards,
Dale Bartlett



______________
Yes, I'm Satoshi.
Message 10 of 18
Anonymous
in reply to: Dale.Bartlett

Is it an MTEXT attribute?


BlockReference.AttributeCollection.AppendAttribute(AttRef)

AttRef.SetPropertiesFrom(AttDef)

AttRef.SetAttributeFromBlock(AttDef, BlockReference.BlockTransform)

if (attRef.IsMTextAttribute) attRef.UpdateMTextAttribute();
Message 11 of 18

Not MText, traditional single line text MC justified.
Thanks, Dale



______________
Yes, I'm Satoshi.
Message 12 of 18

Hello dbarlett

 
 
 
I am having the same problem. did you find any fix for this please?
Regards,
Jaent 
Message 13 of 18
hgasty1001
in reply to: Dale.Bartlett

Hi,

 

Not tested here, but may be a call to

blkRef.RecordGraphicsModified(True)

before the call to Transaction.AddNewlyCreatedBOject , may help to update the block instance.

 

Gaston Nunez

Message 14 of 18
JanetDavidson
in reply to: hgasty1001

Thanks Gaston,

It didn't help.

Message 15 of 18
hgasty1001
in reply to: JanetDavidson

Can you post the block?, may be it's something related to the way it was created.

 

Gaston Nunez

Message 16 of 18
JanetDavidson
in reply to: hgasty1001

Gaston, Thanks again.

Here is my code to move block to 0,0,0

and I submit the block as well. Thanks again

  <CommandMethod("rrr")> _
    Public Shared Sub vns_Get_And_Bring_TaperedRangeBlock1()
        Dim myobjid As ObjectId = vns_Select_one_object_on_Screen("select one screen")
        Dim Myobjidcol As New ObjectIdCollection
        Myobjidcol.Add(myobjid)
        vns_shift_Multi_Range_Line_block_postion_to_initia​l_origin(Myobjidcol, New Point3d(0, 0, 0))
    End Sub
    Public Shared Sub vns_shift_Multi_Range_Line_block_postion_to_initia​l_origin(ByVal myobjidcol As ObjectIdCollection, ByVal BlockInsrPnt As Point3d)
        Dim mydwg As Document = Application.DocumentManager.MdiActiveDocument
        Dim MYed As Editor = mydwg.Editor
        Dim myDB As Database = mydwg.Database
        Using Tr As Transaction = myDB.TransactionManager.StartTransaction()
            Try
                Dim myBr As BlockReference
                For Each MyObjIditm In myobjidcol
                    myBr = CType(Tr.GetObject(MyObjIditm, OpenMode.ForWrite), BlockReference)
                    myBr.Position = BlockInsrPnt 
                Next
                Tr.Commit()
            Catch ex As System.Exception
                         End Try
        End Using
    End Sub

 

Message 17 of 18
hgasty1001
in reply to: JanetDavidson

Hi,

 

If you just need to move the block reference, the best aproach is to use a 3D transform like this inside a transaction:

 

 

Dim DestPoint As New Point3d

Dim blkRef As BlockReference = promptR.ObjectId.GetObject(OpenMode.ForWrite)

Dim p As Point3d = blkRef.Position

Dim m3D AsNew Matrix3d

 

m3D = Matrix3d.Displacement(p.GetVectorTo(DestPoint)) 

blkRef.TransformBy(m3D)

 

MyTransaction.Commit

 

Gaston Nunez

Message 18 of 18
JanetDavidson
in reply to: hgasty1001

Gaston ,

That was the trick . Good job sir. I need to learn these things. With a small brain it is hard to learn these things.

Thanks again Gaston.

Hope one Day I can make it up to you.Woman Wink

Regards,

Janet.

 

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