Author Topic: command "burst" working .net code  (Read 754 times)

0 Members and 1 Guest are viewing this topic.

nekitip

  • Newt
  • Posts: 21
command "burst" working .net code
« on: January 08, 2019, 04:55:11 PM »
Hi all,
I've found some time, and tried to add some functionality to some old plugin that I use.
I've tried to implement burst functionality (as in command "BURST"). I did find some code examples, such as for explode https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-A853CD73-58A9-4380-B8E2-B3451C94C46B-htm.html and burst (the thing that I'm trying to do) http://adn-cis.org/programmnaya-imitacziya-komandyi-burst.html
However, if that code works, than I've missed some tiny tiny bit somewhere, since I cannot make it work (color remains wrong).

So, I wrote something, and I'm sharing here. The only issue I have, and it's a big one:
-is it safe to copy color the way i did?
I do not see objectid so I know that color is not db resident, but i do see "unmanaged object" pointer (or something). And I'm just recreational developer, so...
Code - vb.net: [Select]
  1. Private Shared Sub fillTextFromText(ByRef blockRef As BlockReference, ByRef textFrom As DBText, ByRef textTo As DBText)
  2.  
  3.             textTo.Height = textFrom.Height
  4.             textTo.Position = textFrom.Position
  5.             textTo.Rotation = textFrom.Rotation
  6.             textTo.TextString = textFrom.TextString
  7.             textTo.TextStyleId = textFrom.TextStyleId
  8.             textTo.WidthFactor = textFrom.WidthFactor
  9.             textTo.VerticalMode = textFrom.VerticalMode
  10.             textTo.HorizontalMode = textFrom.HorizontalMode
  11.             textTo.Normal = textFrom.Normal
  12.             textTo.Thickness = textFrom.Thickness
  13.             textTo.Oblique = textFrom.Oblique
  14.  
  15.             If Not (textFrom.IsDefaultAlignment) Then
  16.                 textTo.AlignmentPoint = textFrom.AlignmentPoint
  17.             End If
  18.  
  19.             textTo.SetPropertiesFrom(textFrom)
  20.  
  21.         End Sub
  22.  
  23.         Private Shared Sub explodeBlock(btr As BlockTableRecord, blockDef As BlockTableRecord, trans As Transaction, blockRef As BlockReference)
  24.             Using explodedObjects As New DBObjectCollection
  25.                 Dim toAddColl As DBObjectCollection = New DBObjectCollection()
  26.                 For Each entId As ObjectId In blockDef
  27.                     If entId.ObjectClass.Name = "AcDbAttributeDefinition" Then
  28.                         Dim attDef As AttributeDefinition = trans.GetObject(entId, OpenMode.ForRead)
  29.  
  30.                         If (attDef.Constant AndAlso Not attDef.Invisible) Then
  31.  
  32.                             If attDef.IsMTextAttributeDefinition Then
  33.                                 Dim text As MText = New MText()
  34.                                 text.CopyFrom(attDef.MTextAttributeDefinition) 'no new, so no dispose?
  35.                                 text.TransformBy(blockRef.BlockTransform)
  36.                                 toAddColl.Add(text)
  37.                             Else
  38.                                 Dim text As DBText = New DBText()
  39.                                 fillTextFromText(blockRef, attDef, text)
  40.                                 text.TransformBy(blockRef.BlockTransform)
  41.                                 toAddColl.Add(text)
  42.                             End If
  43.  
  44.                         End If
  45.                     End If
  46.                 Next
  47.  
  48.                 For Each attRefId As ObjectId In blockRef.AttributeCollection
  49.                     Dim attRef As AttributeReference = trans.GetObject(attRefId, OpenMode.ForRead)
  50.  
  51.                     If attRef.Invisible = False Then
  52.  
  53.                         If attRef.IsMTextAttribute Then
  54.                             Dim mt As MText = attRef.MTextAttribute 'no new, so no dispose?
  55.                             Dim text As MText = New MText()
  56.                             text.CopyFrom(mt)
  57.                             toAddColl.Add(text)
  58.                         Else
  59.                             Dim textD As DBText = New DBText()
  60.                             fillTextFromText(blockRef, attRef, textD)
  61.                             toAddColl.Add(textD)
  62.                         End If
  63.                     End If
  64.                 Next
  65.  
  66.                 blockRef.Explode(explodedObjects)
  67.                 For Each ent As Entity In explodedObjects
  68.                     If Not (ent.GetType = GetType(AttributeDefinition)) Then toAddColl.Add(ent)
  69.                 Next
  70.  
  71.                 For Each ent As Entity In toAddColl
  72.                     If ent.Layer = "0" Then
  73.                         Dim entColOriginal = ent.Color
  74.                         ent.SetPropertiesFrom(blockRef)
  75.                         If entColOriginal.ColorIndex > 0 Then ent.Color = entColOriginal
  76.                     End If
  77.                     'text.TransformBy(blockRef.BlockTransform)
  78.  
  79.                     btr.AppendEntity(ent)
  80.                     trans.AddNewlyCreatedDBObject(ent, True)
  81.                 Next
  82.  
  83.                 'blockRef.UpgradeOpen()
  84.                 'blockRef.Erase()
  85.             End Using
  86.  
  87.         End Sub
  88.  

nekitip

  • Newt
  • Posts: 21
Re: command "burst" working .net code
« Reply #1 on: January 09, 2019, 03:53:30 AM »
...I've also found this code. https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-NET/files/GUID-8ABF5190-C179-4D45-9473-3C78897D352E-htm.html
 It appears to me that color object can be copied with no problem, and, as such, my "burst" .NET code is safe, but... again, I would like to hear other oppinions.

Atook

  • Swamp Rat
  • Posts: 942
Re: command "burst" working .net code
« Reply #2 on: January 09, 2019, 04:42:24 PM »
...It appears to me that color object can be copied with no problem, and, as such, my "burst" .NET code is safe, but... again, I would like to hear other oppinions.

Hey nekitip, I do something similar, .colorindex is just an int property that can be set. You should be fine as long as the color is between 0 and 256.

Code - C#: [Select]
  1. int color;
  2. ...
  3. if (color>=0 && color<=256)
  4. {
  5.   br.ColorIndex = color;
  6. }

nekitip

  • Newt
  • Posts: 21
Re: command "burst" working .net code
« Reply #3 on: January 10, 2019, 02:54:17 AM »
Atook, thank you for your anwser, that seems well safe, and will cover 99% of all colors.
I will play it a little bit, just to see what happens if there are RGB colors, and all of  bylayer, byblock combinations...

Atook

  • Swamp Rat
  • Posts: 942
Re: command "burst" working .net code
« Reply #4 on: January 10, 2019, 02:28:53 PM »
for colorIndex, 0=BYBLOCK and 256=BYLAYER.

for RGB colors, you can use Color.FromRgb(23, 54, 232);

There's a nice primer on it here

nekitip

  • Newt
  • Posts: 21
Re: command "burst" working .net code
« Reply #5 on: January 10, 2019, 03:47:35 PM »
thank you, but check what I found out:
Code: [Select]
Autodesk.AutoCAD.Colors.Color.FromEntityColor(_entity_color_to_copy_from_)It contains a lot more information, and it looks like it can be copied easily.

So, in this particular case, this may be like:
Code - vb.net: [Select]
  1. If ent.Layer = "0" Then
  2.     Dim entColOriginal = ent.Color.EntityColor
  3.     ent.SetPropertiesFrom(blockRef)
  4.     If entColOriginal.ColorIndex > 0 Then ent.Color = Autodesk.AutoCAD.Colors.Color.FromEntityColor(entColOriginal)
  5. End If
  6.  

nekitip

  • Newt
  • Posts: 21
Re: command "burst" working .net code
« Reply #6 on: January 10, 2019, 03:59:30 PM »
and here is complete "burst" working code
use it for good cause :smitten:

Code - vb.net: [Select]
  1.  'copy properties of DBText type objects from one to other
  2.  'this works for DBText, AttRed, AttDef
  3.  Private Shared Sub fillTextFromText(ByRef blockRef As BlockReference, ByRef textFrom As DBText, ByRef textTo As DBText)
  4.  
  5.      textTo.Height = textFrom.Height
  6.      textTo.Position = textFrom.Position
  7.      textTo.Rotation = textFrom.Rotation
  8.      textTo.TextString = textFrom.TextString
  9.      textTo.TextStyleId = textFrom.TextStyleId
  10.      textTo.WidthFactor = textFrom.WidthFactor
  11.      textTo.VerticalMode = textFrom.VerticalMode
  12.      textTo.HorizontalMode = textFrom.HorizontalMode
  13.      textTo.Normal = textFrom.Normal
  14.      textTo.Thickness = textFrom.Thickness
  15.      textTo.Oblique = textFrom.Oblique
  16.      textTo.IsMirroredInX = textFrom.IsMirroredInX
  17.      textTo.IsMirroredInY = textFrom.IsMirroredInY
  18.      textTo.Transparency = textFrom.Transparency
  19.      textTo.Justify = textFrom.Justify
  20.  
  21.      'possible bug in autocad when "MIDDLE" is used; text.rotation sometimes gets to be math.pi, sometimes not, and text is inserted in dwg to zero, no mater position
  22.      'noticed on autocad 2020 (acad2020) dynamic block with flip parameter, and can be produced if parameter is set to justify to Middle, simply by hand in block editor
  23.      'the main issue with this is here: - alignment point is not at its default position, but isdefaultposition flag is not set. It would be expected to be.
  24.      'However, If alignment point if not set during copy (when off 0,0,0), then it will go at zero position od model space.
  25.      'Applying alignment point at any other time is enotaplicable error (and a crash)
  26.      'the current only solution I came to is to check if text is in any nonleft mode and change point only then
  27.      If Not (textFrom.HorizontalMode = TextHorizontalMode.TextLeft) Then
  28.          textTo.AlignmentPoint = textFrom.AlignmentPoint
  29.      End If
  30.  
  31.      'copy colors (all) and layers (only layer 0 is replaced)
  32.      'later, get colors and other from block (overwrite)
  33.      textTo.SetPropertiesFrom(textFrom)
  34.  
  35.  End Sub
  36.  
  37.  Private Shared Sub explodeBlock(btr As BlockTableRecord, blockDef As BlockTableRecord, trans As Transaction, blockRef As BlockReference)
  38.      Using explodedObjects As New DBObjectCollection
  39.          Dim toAddColl As DBObjectCollection = New DBObjectCollection()
  40.  
  41.          For Each entId As ObjectId In blockDef
  42.              If entId.ObjectClass.Name = "AcDbAttributeDefinition" Then
  43.                  Dim attDef As AttributeDefinition = trans.GetObject(entId, OpenMode.ForRead)
  44.  
  45.                  If (attDef.Constant AndAlso Not attDef.Invisible AndAlso attDef.Visible) Then 'maybe no need for visible check here?
  46.  
  47.                      If attDef.IsMTextAttributeDefinition Then
  48.                          Dim text As MText = New MText()
  49.                          text.CopyFrom(attDef.MTextAttributeDefinition) 'no new(), so no need to dispose later?
  50.                          'looks like TransformBy is needed here
  51.                          'in some examples, only point is transformedby
  52.                          text.TransformBy(blockRef.BlockTransform)
  53.                          toAddColl.Add(text)
  54.                      Else
  55.                          Dim text As DBText = New DBText()
  56.                          fillTextFromText(blockRef, attDef, text)
  57.                          'looks like TransformBy is needed here
  58.                          'in some examples, only point is transformedby
  59.                          text.TransformBy(blockRef.BlockTransform)
  60.                          toAddColl.Add(text)
  61.                      End If
  62.  
  63.                  End If
  64.              End If
  65.          Next
  66.  
  67.          For Each attRefId As ObjectId In blockRef.AttributeCollection
  68.              Dim attRef As AttributeReference = trans.GetObject(attRefId, OpenMode.ForRead)
  69.  
  70.              If attRef.Invisible = False AndAlso attRef.Visible Then 'bizzare, but attref in dynblock in visstate can be invisible=false, and visible=false
  71.  
  72.                  If attRef.IsMTextAttribute Then
  73.                      Dim mt As MText = attRef.MTextAttribute 'no new, so no dispose?
  74.                      Dim text As MText = New MText()
  75.                      text.CopyFrom(mt)
  76.                      toAddColl.Add(text)
  77.                  Else
  78.                      Dim textD As DBText = New DBText()
  79.                      fillTextFromText(blockRef, attRef, textD)
  80.                      toAddColl.Add(textD)
  81.                  End If
  82.              End If
  83.          Next
  84.  
  85.          'explode all to single new objects
  86.          'objects need to be added in db, however, filter unvisible objects (if dynamic block)
  87.          blockRef.Explode(explodedObjects)
  88.          For Each ent As Entity In explodedObjects
  89.              If Not (ent.GetType = GetType(AttributeDefinition)) AndAlso ent.Visible Then toAddColl.Add(ent)
  90.          Next
  91.  
  92.          'add all to drawing, and get colors and layer from block (but if color is nonzero, leave color as it was)
  93.          'SetPropertiesFrom will set layers 0 but color is overwritten...
  94.          For Each ent As Entity In toAddColl
  95.              If ent.Layer = "0" Then
  96.                  Dim entColOriginal = ent.Color.EntityColor
  97.                  ent.SetPropertiesFrom(blockRef)
  98.                  If entColOriginal.ColorIndex > 0 Then ent.Color = Autodesk.AutoCAD.Colors.Color.FromEntityColor(entColOriginal)
  99.              End If
  100.  
  101.              btr.AppendEntity(ent)
  102.              trans.AddNewlyCreatedDBObject(ent, True)
  103.          Next
  104.  
  105.          'delete old block (if not, it would show up in drawing at the same place)
  106.          blockRef.UpgradeOpen()
  107.          blockRef.Erase()
  108.      End Using
  109.  
  110.  End Sub
  111.  
  112.  

Atook

  • Swamp Rat
  • Posts: 942
Re: command "burst" working .net code
« Reply #7 on: January 10, 2019, 04:43:34 PM »
thank you, but check what I found out:
Code: [Select]
Autodesk.AutoCAD.Colors.Color.FromEntityColor(_entity_color_to_copy_from_)It contains a lot more information, and it looks like it can be copied easily...
Ohh, nice, perfect for what you wanted! Thanks for sharing.  :-)