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

Dynamic block with constraints

16 REPLIES 16
SOLVED
Reply
Message 1 of 17
安娜hoohoo
955 Views, 16 Replies

Dynamic block with constraints

Hi ,guys!

I wanted the text to always be horizontal, so I added the horizontal constraint, but it didn't work when I used code to insert the dynamic block which from another DWG. I don't quite understand what went wrong.

Any help will be appreciated!!

Anna

The following is my block and code.

hoohoo_0-1656057176564.png

    Public Shared Sub addCutSymbol()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = HostApplicationServices.WorkingDatabase
        Dim ed As Editor = doc.Editor
        Dim GlobalSet As GlobalSettingClass = GlobalSettingClass.GetSetting
        Try
            Using trans As Transaction = db.TransactionManager.StartTransaction
                  BlockTools.ImportBlocksFromDwg(db, AcadTablesDwgPath, "Cut")
                  Dim bt As BlockTable = CType(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                               Dim btr As BlockTableRecord = CType(trans.GetObject(bt("Cut"), OpenMode.ForWrite), BlockTableRecord)
                Dim targetBr As BlockReference = New BlockReference(Point3d.Origin, btr.ObjectId)
                Dim sPoint As Point3d
                Dim ePoint As Point3d
                Dim angle As Double
                Dim ppr As PromptPointResult = ed.GetPoint("请选择剖切符号的起点:")
                If ppr.Status = PromptStatus.OK Then
                    sPoint = ppr.Value
                Else
                    Exit Sub
                End If
                Dim ppr2 As PromptPointResult = ed.GetPoint("请选择剖切符号的终点:")
                If ppr2.Status = PromptStatus.OK Then
                    ePoint = ppr2.Value
                Else
                    Exit Sub
                End If
                Dim pso As PromptStringOptions = New PromptStringOptions("请输入剖切符号:")
                pso.DefaultValue = "A"
                pso.UseDefaultValue = True
                Dim ppr3 As PromptResult = ed.GetString(pso)
                If ppr3.Status <> PromptStatus.OK Then
                    Exit Sub
                End If
                Dim pao As PromptAngleOptions = New PromptAngleOptions("请输入旋转角度:")
                pao.DefaultValue = 0
                pao.UseDefaultValue = True
                Dim par As PromptDoubleResult = ed.GetAngle(pao)
                If par.Status = PromptStatus.OK Then
                    angle = par.value
                Else
                    Exit Sub
                End If
                targetBr.Scale(targetBr.Position, GlobalSet.ScaleValue)
                Dim modelspace As BlockTableRecord = CType(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                modelspace.AppendEntity(targetBr)
                trans.AddNewlyCreatedDBObject(targetBr, True)
                targetBr.Position = GeTools.MidPoint(sPoint, ePoint)
                Dim pc As DynamicBlockReferencePropertyCollection = targetBr.DynamicBlockReferencePropertyCollection
                For Each prop As DynamicBlockReferenceProperty In pc
                    If prop.PropertyName = "A" Then
                        prop.Value = angle
                    End If
                    If prop.PropertyName = "UP X" Then
                        prop.Value = sPoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "UP Y" Then
                        prop.Value = sPoint.Y - targetBr.Position.Y
                    End If
                    If prop.PropertyName = "Down X" Then
                        prop.Value = ePoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "Down Y" Then
                        prop.Value = ePoint.Y - targetBr.Position.Y
                    End If
                Next
                Dim Dic As New Dictionary(Of String, String)
                Dim ac As AttributeCollection = targetBr.AttributeCollection
                For Each aa In ac
                    Dim attRef As AttributeReference = CType(trans.GetObject(aa, OpenMode.ForRead), AttributeReference)
                    Dic(attRef.Tag.ToUpper) = attRef.TextString
                Next
                Dim Dic2 As New Dictionary(Of String, String) From {{"NAME-UP", ppr3.StringResult}, {"NAME-DOWN", ppr3.StringResult}}
                BlockTools.UpdateAttributesInBlock(targetBr.ObjectId, Dic2)
                btr.SynchronizeAttributes
                trans.Commit()

            End Using
        Catch ex As Exception

        End Try

    End Sub

 

 

 

 

16 REPLIES 16
Message 2 of 17
安娜hoohoo
in reply to: 安娜hoohoo

This is what I did with the finished block

hoohoo_0-1656062503443.png

This is what happens when I insert a block of code,the text is not horizontal.

hoohoo_1-1656062552797.png

 

Message 3 of 17
SRSDS
in reply to: 安娜hoohoo

I don't know if this will help, but try changing the attributes before modifying block properties.

Message 4 of 17
norman.yuan
in reply to: 安娜hoohoo

Firstly, following code does nothing:

 

      ... ...
      Dim Dic As New Dictionary(Of String, String)
      Dim ac As AttributeCollection = targetBr.AttributeCollection
      For Each aa In ac
          Dim attRef As AttributeReference = CType(trans.GetObject(aa, OpenMode.ForRead), AttributeReference)
          Dic(attRef.Tag.ToUpper) = attRef.TextString
      Next
      ... ...

because you have not added any attribute to the block reference.

 

Secondly, it seems to me that you did not show all code that is likely doing something affecting the block reference's attributes, especially the 2 lines of code near the end:

 

        ... ...
        BlockTools.UpdateAttributesInBlock(targetBr.ObjectId, Dic2)
        btr.SynchronizeAttributes
        ... ...

If these 2 lines do what their method names imply, then it seems you only added attribute references to the block reference after the block reference's dynamic properties are set (which would effectively changed the block reference's definition to an annonymous BlockTableRecord, not the original BlockTableRecord that is used to create the block reference). Since you did not show the code in these 2 methods, I cannot say whether they do things correctly or not for this particular case. But you should, as the other reply from @SRSDS suggested, add attribute references to the block reference first and then set the dynamic properties, considering the dynamic properties are mainly for controlling how the attributes shows in the block reference.

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 5 of 17
安娜hoohoo
in reply to: SRSDS

I have  changed the attributes before modifying block properties, but it didn't seem to work....Here's the code after I changed it,maybe  I got something wrong..

  Public Shared Sub addCutSymbol()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = HostApplicationServices.WorkingDatabase
        Dim ed As Editor = doc.Editor
        Dim GlobalSet As GlobalSettingClass = GlobalSettingClass.GetSetting
        Try
            Using trans As Transaction = db.TransactionManager.StartTransaction
                '往当前模型空间插入所需块表
                BlockTools.ImportBlocksFromDwg(db, AcadTablesDwgPath, "Cut")
                '打开当前模型块表
                Dim bt As BlockTable = CType(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                '打开当前模型块表记录
                Dim btr As BlockTableRecord = CType(trans.GetObject(bt("Cut"), OpenMode.ForWrite), BlockTableRecord)
                Dim targetBr As BlockReference = New BlockReference(Point3d.Origin, btr.ObjectId)
                Dim sPoint As Point3d
                Dim ePoint As Point3d
                Dim angle As Double
                Dim ppr As PromptPointResult = ed.GetPoint("请选择剖切符号的起点:")
                If ppr.Status = PromptStatus.OK Then
                    sPoint = ppr.Value
                Else
                    Exit Sub
                End If
                Dim ppr2 As PromptPointResult = ed.GetPoint("请选择剖切符号的终点:")
                If ppr2.Status = PromptStatus.OK Then
                    ePoint = ppr2.Value
                Else
                    Exit Sub
                End If
                Dim pso As PromptStringOptions = New PromptStringOptions("请输入剖切符号:")
                pso.DefaultValue = "A"
                pso.UseDefaultValue = True
                Dim ppr3 As PromptResult = ed.GetString(pso)
                If ppr3.Status <> PromptStatus.OK Then
                    Exit Sub
                End If
                Dim pao As PromptAngleOptions = New PromptAngleOptions("请输入旋转角度:")
                pao.DefaultValue = 0
                pao.UseDefaultValue = True
                Dim par As PromptDoubleResult = ed.GetAngle(pao)
                If par.Status = PromptStatus.OK Then
                    angle = par.value
                Else
                    Exit Sub
                End If
                targetBr.Scale(targetBr.Position, GlobalSet.ScaleValue)
                targetBr.Position = GeTools.MidPoint(sPoint, ePoint)
                Dim Dic2 As New Dictionary(Of String, String) From {{"NAME-UP", ppr3.StringResult}, {"NAME-DOWN", ppr3.StringResult}}
                BlockTools.UpdateAttributesInBlock(targetBr, Dic2)
                Dim modelspace As BlockTableRecord = CType(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                modelspace.AppendEntity(targetBr)
                trans.AddNewlyCreatedDBObject(targetBr, True)
                Dim pc As DynamicBlockReferencePropertyCollection = targetBr.DynamicBlockReferencePropertyCollection
                For Each prop As DynamicBlockReferenceProperty In pc
                    If prop.PropertyName = "A" Then
                        prop.Value = angle
                    End If
                    If prop.PropertyName = "UP X" Then
                        prop.Value = sPoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "UP Y" Then
                        prop.Value = sPoint.Y - targetBr.Position.Y
                    End If
                    If prop.PropertyName = "Down X" Then
                        prop.Value = ePoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "Down Y" Then
                        prop.Value = ePoint.Y - targetBr.Position.Y
                    End If
                Next

                btr.SynchronizeAttributes
                trans.Commit()

            End Using
        Catch ex As Exception

        End Try

    End Sub

 

Message 6 of 17
安娜hoohoo
in reply to: norman.yuan

I hadn't realized that this code was useless,  thanks for reminding me!!I have   changed the attributes before modifying block properties, but it didn't seem to work....maybe  I got something wrong...

the code after for the other two methods

  Public Shared Sub addCutSymbol()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = HostApplicationServices.WorkingDatabase
        Dim ed As Editor = doc.Editor
        Dim GlobalSet As GlobalSettingClass = GlobalSettingClass.GetSetting
        Try
            Using trans As Transaction = db.TransactionManager.StartTransaction
                '往当前模型空间插入所需块表
                BlockTools.ImportBlocksFromDwg(db, AcadTablesDwgPath, "Cut")
                '打开当前模型块表
                Dim bt As BlockTable = CType(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                '打开当前模型块表记录
                Dim btr As BlockTableRecord = CType(trans.GetObject(bt("Cut"), OpenMode.ForWrite), BlockTableRecord)
                Dim targetBr As BlockReference = New BlockReference(Point3d.Origin, btr.ObjectId)
                Dim sPoint As Point3d
                Dim ePoint As Point3d
                Dim angle As Double
                Dim ppr As PromptPointResult = ed.GetPoint("请选择剖切符号的起点:")
                If ppr.Status = PromptStatus.OK Then
                    sPoint = ppr.Value
                Else
                    Exit Sub
                End If
                Dim ppr2 As PromptPointResult = ed.GetPoint("请选择剖切符号的终点:")
                If ppr2.Status = PromptStatus.OK Then
                    ePoint = ppr2.Value
                Else
                    Exit Sub
                End If
                Dim pso As PromptStringOptions = New PromptStringOptions("请输入剖切符号:")
                pso.DefaultValue = "A"
                pso.UseDefaultValue = True
                Dim ppr3 As PromptResult = ed.GetString(pso)
                If ppr3.Status <> PromptStatus.OK Then
                    Exit Sub
                End If
                Dim pao As PromptAngleOptions = New PromptAngleOptions("请输入旋转角度:")
                pao.DefaultValue = 0
                pao.UseDefaultValue = True
                Dim par As PromptDoubleResult = ed.GetAngle(pao)
                If par.Status = PromptStatus.OK Then
                    angle = par.value
                Else
                    Exit Sub
                End If
                targetBr.Scale(targetBr.Position, GlobalSet.ScaleValue)
                targetBr.Position = GeTools.MidPoint(sPoint, ePoint)
                Dim Dic2 As New Dictionary(Of String, String) From {{"NAME-UP", ppr3.StringResult}, {"NAME-DOWN", ppr3.StringResult}}
                BlockTools.UpdateAttributesInBlock(targetBr, Dic2)
                Dim modelspace As BlockTableRecord = CType(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                modelspace.AppendEntity(targetBr)
                trans.AddNewlyCreatedDBObject(targetBr, True)
                Dim pc As DynamicBlockReferencePropertyCollection = targetBr.DynamicBlockReferencePropertyCollection
                For Each prop As DynamicBlockReferenceProperty In pc
                    If prop.PropertyName = "A" Then
                        prop.Value = angle
                    End If
                    If prop.PropertyName = "UP X" Then
                        prop.Value = sPoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "UP Y" Then
                        prop.Value = sPoint.Y - targetBr.Position.Y
                    End If
                    If prop.PropertyName = "Down X" Then
                        prop.Value = ePoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "Down Y" Then
                        prop.Value = ePoint.Y - targetBr.Position.Y
                    End If
                Next

                btr.SynchronizeAttributes
                trans.Commit()

            End Using
        Catch ex As Exception

        End Try

    End Sub
 public static void UpdateAttributesInBlock(BlockReference blockRef, Dictionary<string, string> attNameValues)
        {
            try
            {
                //获取块参照对象
                //   BlockReference blockRef = blockRefId.GetObject(OpenMode.ForRead) as BlockReference;
                if (blockRef != null)
                {
                    //遍历块参照中的属性
                    foreach (ObjectId id in blockRef.AttributeCollection)
                    {
                        //获取属性
                        AttributeReference attref = id.GetObject(OpenMode.ForRead) as AttributeReference;
                        //判断是否包含指定的属性名称
                        if (attNameValues.ContainsKey(attref.Tag.ToUpper()))
                        {
                            attref.UpgradeOpen();//切换属性对象为写的状态
                                                 //设置属性值
                            attref.TextString = attNameValues[attref.Tag.ToUpper()].ToString();
                            attref.DowngradeOpen();//为了安全,将属性对象的状态改为读
                        }
                    }
                }
            }
            catch (Exception)
            {

                throw;
            }

        }
 public static class ExtensionMethods
    {
        static RXClass attDefClass = RXClass.GetClass(typeof(AttributeDefinition));
        /// <summary>
        /// 更新块
        /// </summary>
        /// <param name="target"></param>
        public static void SynchronizeAttributes(this BlockTableRecord target)
        {
            if (target == null)
                throw new ArgumentNullException("target");

            Transaction tr = target.Database.TransactionManager.TopTransaction;
            if (tr == null)
                throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions);
            List<AttributeDefinition> attDefs = target.GetAttributes(tr);
            foreach (ObjectId id in target.GetBlockReferenceIds(true, false))
            {
                BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
                br.ResetAttributes(attDefs, tr);
            }
            if (target.IsDynamicBlock)
            {
                target.UpdateAnonymousBlocks();
                foreach (ObjectId id in target.GetAnonymousBlockIds())
                {
                    BlockTableRecord btr = (BlockTableRecord)tr.GetObject(id, OpenMode.ForRead);
                    attDefs = btr.GetAttributes(tr);
                    foreach (ObjectId brId in btr.GetBlockReferenceIds(true, false))
                    {
                        BlockReference br = (BlockReference)tr.GetObject(brId, OpenMode.ForWrite);
                        br.ResetAttributes(attDefs, tr);
                    }
                }
            }
        }

        private static List<AttributeDefinition> GetAttributes(this BlockTableRecord target, Transaction tr)
        {
            List<AttributeDefinition> attDefs = new List<AttributeDefinition>();
            foreach (ObjectId id in target)
            {
                if (id.ObjectClass == attDefClass)
                {
                    AttributeDefinition attDef = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead);
                    attDefs.Add(attDef);
                }
            }
            return attDefs;
        }

        private static void ResetAttributes(this BlockReference br, List<AttributeDefinition> attDefs, Transaction tr)
        {
            List<AttributeDefinition> defsCopy = new List<AttributeDefinition>(attDefs);
            Dictionary<string, string> attValues = new Dictionary<string, string>();
            foreach (ObjectId id in br.AttributeCollection)
            {
                if (!id.IsErased)
                {
                    AttributeReference attRef = (AttributeReference)tr.GetObject(id, OpenMode.ForWrite);
                    AttributeDefinition attDef = attDefs.Find(x => x.Tag == attRef.Tag);
                    if (attDef == null)
                    {
                        attRef.Erase();
                        continue;

                    }
                    String attText = attRef.IsMTextAttribute ? attRef.MTextAttribute.Contents : attRef.TextString;
                    attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
                    attRef.TextString = attText;
                    defsCopy.Remove(attDef);
                }
            }
            foreach (AttributeDefinition attDef in defsCopy)
            {
                AttributeReference attRef = new AttributeReference();
                attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
                if (attDef.Constant)
                    attRef.TextString = attDef.IsMTextAttributeDefinition ? attDef.MTextAttributeDefinition.Contents : attDef.TextString;
                else if (attValues != null && attValues.ContainsKey(attDef.Tag))
                    attRef.TextString = attValues[attDef.Tag.ToUpper()];
                br.AttributeCollection.AppendAttribute(attRef);
                tr.AddNewlyCreatedDBObject(attRef, true);
            }
        }
    }

 

Message 7 of 17
norman.yuan
in reply to: 安娜hoohoo

Why do you need to call the SynchronizeAttributes() extension method after you set the attributes and dynamic properties of the newly inserted block reference? This call simply reset attributes and dynamic properties back of all related block references, which effectively makes the dynamic properties you just set in the newly create block  reference go back to their original status.

 

You can try to remove 

btr.SynchronizeAttributes

from the code to see what happens.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 8 of 17
安娜hoohoo
in reply to: norman.yuan

btr.SynchronizeAttributes like “attsync”~

When I remove this code,attribute is not displayed😭

Like this..

hoohoo_0-1656381914947.png

Could it be that because of those code

BlockTools.ImportBlocksFromDwg(db, AcadTablesDwgPath, "Cut")
Dim bt As BlockTable = CType(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
Dim btr As BlockTableRecord = CType(trans.GetObject(bt("Cut"), OpenMode.ForWrite), BlockTableRecord)
Dim targetBr As BlockReference = New BlockReference(Point3d.Origin, btr.ObjectId)

he has redefined my block, so my constraint doesn't exist, even though it still exists....😞

Message 9 of 17
norman.yuan
in reply to: 安娜hoohoo

OK, I did not look into the method UpdateAttributesInBlock() and assumed you coded it correctly. But, no, that method does not do things correctly. That is, that method would only be useful if the AttributeReferences have been created and appended to the block rerference's AttributeCollection. So, you EITHER add the attributereferences to the blockreference prior to calling UpdateAttributesInBlock(), OR, you do it inside the method. The bottomline is: your code did not create AttributeReference at all, thus you do not see them after your code runs. Again, you do not need "ATTSYNC" type of operation in this case.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 10 of 17
安娜hoohoo
in reply to: norman.yuan

I've tried to insert attributeReference into my code, but it seems to cause some exceptions... Is there something wrong with what I wrote...😭😭I tried many methods but none of them worked..😭

Public Shared Sub addCutSymbol()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = HostApplicationServices.WorkingDatabase
        Dim ed As Editor = doc.Editor
        Dim GlobalSet As GlobalSettingClass = GlobalSettingClass.GetSetting
        Try
            Using trans As Transaction = db.TransactionManager.StartTransaction
                '往当前模型空间插入所需块表
                BlockTools.ImportBlocksFromDwg(db, AcadTablesDwgPath, "Cut")
                '打开当前模型块表
                Dim bt As BlockTable = CType(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                '打开当前模型块表记录
                Dim btr As BlockTableRecord = CType(trans.GetObject(bt("Cut"), OpenMode.ForWrite), BlockTableRecord)
                Dim targetBr As BlockReference = New BlockReference(Point3d.Origin, btr.ObjectId)
                Dim sPoint As Point3d
                Dim ePoint As Point3d
                Dim angle As Double
                Dim ppr As PromptPointResult = ed.GetPoint("请选择剖切符号的起点:")
                If ppr.Status = PromptStatus.OK Then
                    sPoint = ppr.Value
                Else
                    Exit Sub
                End If
                Dim ppr2 As PromptPointResult = ed.GetPoint("请选择剖切符号的终点:")
                If ppr2.Status = PromptStatus.OK Then
                    ePoint = ppr2.Value
                Else
                    Exit Sub
                End If
                Dim pso As PromptStringOptions = New PromptStringOptions("请输入剖切符号:")
                pso.DefaultValue = "A"
                pso.UseDefaultValue = True
                Dim ppr3 As PromptResult = ed.GetString(pso)
                If ppr3.Status <> PromptStatus.OK Then
                    Exit Sub
                End If
                Dim pao As PromptAngleOptions = New PromptAngleOptions("请输入旋转角度:")
                pao.DefaultValue = 0
                pao.UseDefaultValue = True
                Dim par As PromptDoubleResult = ed.GetAngle(pao)
                If par.Status = PromptStatus.OK Then
                    angle = par.value
                Else
                    Exit Sub
                End If
                targetBr.Scale(targetBr.Position, GlobalSet.ScaleValue)
                targetBr.Position = GeTools.MidPoint(sPoint, ePoint)
                'If btr.HasAttributeDefinitions Then
                'For Each aa As ObjectId In btr
                'Dim attDef As AttributeDefinition = CType(aa.GetObject(OpenMode.ForWrite), AttributeDefinition)
                Dim attref As AttributeReference = New AttributeReference
                attref.SetAttributeFromBlock(targetBr.BlockTransform)
                attref.Tag = "NAME-UP"
                attref.TextString = ppr3.StringResult
                'attref.Tag = "NAME-DOWN"
                'attref.TextString = ppr3.StringResult
                targetBr.AttributeCollection.AppendAttribute(attref)
                trans.AddNewlyCreatedDBObject(attref, True)
                'Next
                'End If
                'For Each aa In btr
                'Dim attDef As AttributeDefinition = CType(aa.GetObject(OpenMode.ForWrite), AttributeDefinition)
                'attref.SetAttributeFromBlock(attDef, targetBr.BlockTransform)
                'attref.TextString = attDef.TextString
                'targetBr.AttributeCollection.AppendAttribute(attref)
                'Next
                Dim modelspace As BlockTableRecord = CType(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                modelspace.AppendEntity(targetBr)
                trans.AddNewlyCreatedDBObject(targetBr, True)
                Dim pc As DynamicBlockReferencePropertyCollection = targetBr.DynamicBlockReferencePropertyCollection
                For Each prop As DynamicBlockReferenceProperty In pc
                    If prop.PropertyName = "A" Then
                        prop.Value = angle
                    End If
                    If prop.PropertyName = "UP X" Then
                        prop.Value = sPoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "UP Y" Then
                        prop.Value = sPoint.Y - targetBr.Position.Y
                    End If
                    If prop.PropertyName = "Down X" Then
                        prop.Value = ePoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "Down Y" Then
                        prop.Value = ePoint.Y - targetBr.Position.Y
                    End If
                Next
                'btr.SynchronizeAttributes
                trans.Commit()

            End Using
        Catch ex As Exception
            ed.WriteMessage(ex.Message)
        End Try

    End Sub

 

Message 11 of 17
norman.yuan
in reply to: 安娜hoohoo

It is obvious to me your code does not add AttributeReference correctly: a), you only added one attribute, while you should have added two; 2). you did not create AttributeReference based on the AttributeDefinition in the block definition (technically you can do that, but you should not, in this case); 3) the new AttributeReference you added has not TextHeight set (in case if the current TextStyle does not have its TextHeight set), so the new attribute could be 0 in height, then you may not be able to see it.

 

I do see you commented out a few lines of code that would be actually correct ones for adding AttributeReference. So, I roughly put them here:

 

                targetBr.Scale(targetBr.Position, GlobalSet.ScaleValue)
                targetBr.Position = GeTools.MidPoint(sPoint, ePoint)
                'If btr.HasAttributeDefinitions Then
                For Each aa As ObjectId In btr
                  Dim attDef As AttributeDefinition = TryCast(aa.GetObject(OpenMode.ForWrite), AttributeDefinition)
                  If attDef IsNot Nothing Then
                    Dim attref As AttributeReference = New AttributeReference
                    attref.SetAttributeFromBlock(attDef, targetBr.BlockTransform)
                    If attref.Tag = "NAME-UP" Or attRef.Tag = "NAME_DOWN" Then
                      attref.TextString = ppr3.StringResult
                    End If
                    targetBr.AttributeCollection.AppendAttribute(attref)
                    trans.AddNewlyCreatedDBObject(attref, True)
                   End If
                Next

 

Norman Yuan

Drive CAD With Code

EESignature

Message 12 of 17
安娜hoohoo
in reply to: norman.yuan

Sorry to get back to you now because I went to the hospital yesterday..

Thank you so much for your help!!!!Attribute is displayed!!

I put these code here,because cad reported anerror"eNoDatabase"~

The following is my complete code~

However ,he problem of constraints is not solved...I think  it's something wrong with AutoCAD...

  Public Shared Sub addCutSymbol()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = HostApplicationServices.WorkingDatabase
        Dim ed As Editor = doc.Editor
        Dim GlobalSet As GlobalSettingClass = GlobalSettingClass.GetSetting
        Try
            Using trans As Transaction = db.TransactionManager.StartTransaction
                '往当前模型空间插入所需块表
                BlockTools.ImportBlocksFromDwg(db, AcadTablesDwgPath, "Cut")
                '打开当前模型块表
                Dim bt As BlockTable = CType(trans.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                '打开当前模型块表记录
                Dim btr As BlockTableRecord = CType(trans.GetObject(bt("Cut"), OpenMode.ForWrite), BlockTableRecord)
                Dim targetBr As BlockReference = New BlockReference(Point3d.Origin, btr.ObjectId)
                Dim sPoint As Point3d
                Dim ePoint As Point3d
                Dim angle As Double
                Dim ppr As PromptPointResult = ed.GetPoint("请选择剖切符号的起点:")
                If ppr.Status = PromptStatus.OK Then
                    sPoint = ppr.Value
                Else
                    Exit Sub
                End If
                Dim ppr2 As PromptPointResult = ed.GetPoint("请选择剖切符号的终点:")
                If ppr2.Status = PromptStatus.OK Then
                    ePoint = ppr2.Value
                Else
                    Exit Sub
                End If
                Dim pso As PromptStringOptions = New PromptStringOptions("请输入剖切符号:")
                pso.DefaultValue = "A"
                pso.UseDefaultValue = True
                Dim ppr3 As PromptResult = ed.GetString(pso)
                If ppr3.Status <> PromptStatus.OK Then
                    Exit Sub
                End If
                Dim pao As PromptAngleOptions = New PromptAngleOptions("请输入旋转角度:")
                pao.DefaultValue = 0
                pao.UseDefaultValue = True
                Dim par As PromptDoubleResult = ed.GetAngle(pao)
                If par.Status = PromptStatus.OK Then
                    angle = par.value
                Else
                    Exit Sub
                End If
                targetBr.Scale(targetBr.Position, GlobalSet.ScaleValue)
                targetBr.Position = GeTools.MidPoint(sPoint, ePoint)
                Dim modelspace As BlockTableRecord = CType(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                modelspace.AppendEntity(targetBr)
                trans.AddNewlyCreatedDBObject(targetBr, True)
                If btr.HasAttributeDefinitions Then
                    For Each aa As ObjectId In btr
                        Dim attDef As AttributeDefinition = TryCast(aa.GetObject(OpenMode.ForWrite), AttributeDefinition)
                        If attDef IsNot Nothing Then

                            Dim attref As AttributeReference = New AttributeReference
                            attref.SetAttributeFromBlock(attDef, targetBr.BlockTransform)
                            If attref.Tag = "NAME-UP" Or attref.Tag = "NAME-DOWN" Then
                                attref.TextString = ppr3.StringResult
                            End If
                            targetBr.AttributeCollection.AppendAttribute(attref)
                            trans.AddNewlyCreatedDBObject(attref, True)
                        End If
                    Next
                End If
                Dim pc As DynamicBlockReferencePropertyCollection = targetBr.DynamicBlockReferencePropertyCollection
                For Each prop As DynamicBlockReferenceProperty In pc
                    If prop.PropertyName = "A" Then
                        prop.Value = angle
                    End If
                    If prop.PropertyName = "UP X" Then
                        prop.Value = sPoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "UP Y" Then
                        prop.Value = sPoint.Y - targetBr.Position.Y
                    End If
                    If prop.PropertyName = "Down X" Then
                        prop.Value = ePoint.X - targetBr.Position.X
                    End If
                    If prop.PropertyName = "Down Y" Then
                        prop.Value = ePoint.Y - targetBr.Position.Y
                    End If
                Next
                trans.Commit()

            End Using
        Catch ex As Exception
            ed.WriteMessage(ex.Message)
        End Try

    End Sub

 

 

Message 13 of 17
SRSDS
in reply to: 安娜hoohoo

Hi, can you post the dynamic block.

Message 14 of 17
安娜hoohoo
in reply to: SRSDS

Yes,the following is my block😁

Message 15 of 17
SRSDS
in reply to: 安娜hoohoo

Your angle input might be wrong. Not converting degrees to radians? A redundant input if you already have two points

angle = sPoint.GetVectorTo(ePoint).GetAngleTo(Vector3d.XAxis, Vector3d.ZAxis.Negate()) + Math.PI / 2
If angle > 2 * Math.PI Then angle -= 2 * Math.PI.

 

I still found the text is inverted in some cases. You might need to swap SPoint and EPoint to fix that.

Message 16 of 17
SRSDS
in reply to: SRSDS

The attached block has a chained move action on the attributes which might give you what you are after. 

Message 17 of 17
安娜hoohoo
in reply to: SRSDS

Thanks for your help!!!!!!!! 

I had a busy weekend and I'm sorry I didn't respond to your messages in time.😭

Dynamic Blocks I still have a lot to learn!!😀

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report