Author Topic: 2012 Associative Array Simple Example  (Read 9521 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6144
2012 Associative Array Simple Example
« on: April 14, 2011, 05:29:53 PM »
Very simple and coded to show properties etc......

Just threw things in there and had no idea what it would look like, but who cares just some code to get topic started.

Just thought I get the topic going since it is probably going to be asked


I will edit post later and code in VB.NET


Code adds a Assoc Rectangle and Polar Array to model space

Code - C#: [Select]
  1.   [CommandMethod("RectandPolarAssocArr")]
  2.         public void RectandPolarAssocArr()
  3.         {
  4.             using (Transaction trx = db.TransactionManager.StartTransaction())
  5.             {
  6.                 ObjectIdCollection rectArrayEntitiesIds = new ObjectIdCollection();
  7.                 ObjectIdCollection polarArrayEntitiesIds = new ObjectIdCollection();
  8.  
  9.                 BlockTable bt = (BlockTable)trx.GetObject(db.BlockTableId, OpenMode.ForRead);
  10.                 BlockTableRecord modelSpace = (BlockTableRecord)trx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
  11.                  
  12.                 Circle circle = new Circle(Point3d.Origin, Vector3d.ZAxis, 5);
  13.                 modelSpace.AppendEntity(circle);
  14.                 trx.AddNewlyCreatedDBObject(circle, true);
  15.  
  16.                 Line line = new Line(Point3d.Origin, new Point3d(5, 0, 0));
  17.                 modelSpace.AppendEntity(line);
  18.                 trx.AddNewlyCreatedDBObject(line, true);
  19.  
  20.                 rectArrayEntitiesIds.Add(circle.ObjectId);
  21.                 polarArrayEntitiesIds.Add(line.ObjectId);
  22.  
  23.                 AssocArrayRectangularParameters rectParams = new AssocArrayRectangularParameters()
  24.                 {
  25.                     ColumnCount = 10,
  26.                     ColumnSpacing = 10,
  27.                     RowCount = 10,
  28.                     RowSpacing = 10,
  29.                     RowElevation = 0,
  30.                     LevelCount = 10,
  31.                     LevelSpacing = 10,
  32.                     XAxisDirection = Vector3d.XAxis,
  33.                     YAxisDirection = Vector3d.YAxis,
  34.                     BasePoint = new VertexRef(new Point3d(50, 50, 0)),  
  35.                 } ;
  36.  
  37.                  AssocArray.CreateArray(rectArrayEntitiesIds, rectParams.BasePoint, rectParams);
  38.  
  39.                 AssocArrayPolarParameters polarParams = new AssocArrayPolarParameters()
  40.                 {
  41.                     FillAngle = 360,
  42.                     AngleBetweenItems = 10,
  43.                     ItemCount = 36,
  44.                     RowCount = 10,
  45.                     RowElevation = 10,
  46.                     RowSpacing = 10,
  47.                     Radius = 30,
  48.                     Direction = AssocArrayPolarParameters.ArcDirection.CounterClockwise,
  49.                     StartAngle = 0,
  50.                     RotateItems = true,
  51.  
  52.                    
  53.                 } ;
  54.  
  55.                 AssocArray.CreateArray(polarArrayEntitiesIds, new VertexRef(new Point3d(100, 100, 0)), polarParams);
  56.  
  57.  
  58.  
  59.                 trx.Commit();              
  60.             }
  61.         }
  62.  

****Edit****
Setup like Kerry's from 2011BlockTesting Thread
Code - C#: [Select]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  8.  
  9. [assembly: CommandClass(typeof(AssocArraySamp.MyCommands))]
  10.  
  11. namespace AssocArraySamp
  12. {
  13.  
  14.  
  15.     public class MyCommands
  16.     {
  17.        
  18.         Document doc;
  19.         Database db;
  20.         Editor ed;
  21.    
  22.  
  23.  
  24.           public  MyCommands()
  25.         {
  26.             ActiveDoc = AcadApp.DocumentManager.MdiActiveDocument;
  27.    
  28.         }
  29.        
  30.  
  31.         Document ActiveDoc
  32.         {
  33.             get { return doc; }
  34.             set
  35.             {
  36.                 doc = value;
  37.                 if( doc == null ) {
  38.                     db = null;
  39.                     ed = null;
  40.                 } else {
  41.                     db = doc.Database;
  42.                     ed = doc.Editor;
  43.                 }
  44.             }
  45.         }
  46.  
  47.  


edit:kdub->code formatting using =csharp

« Last Edit: March 02, 2012, 05:43:18 PM by Kerry »

JanetDavidson

  • Mosquito
  • Posts: 17
Re: 2012 Associative Array Simple Example
« Reply #1 on: March 01, 2012, 10:25:16 PM »
Thanks Jeff for this post. Now I used your code to implement an associative polar path array. Kean code crashes on 2012.
I tried to have simple code. but it doesn't work. could I get some help here. Thanks.

Code: [Select]
   <CommandMethod("QQQQ")> _
    Sub sample_assocarraypath()
        Dim myDwg As Document = Application.DocumentManager.MdiActiveDocument
        Dim Db As Database = myDwg.Database
        Using tr As Transaction = Db.TransactionManager.StartTransaction()
            Dim MyArrayEntitiesIds As New ObjectIdCollection()

            Dim bt As BlockTable = DirectCast(tr.GetObject(Db.BlockTableId, OpenMode.ForRead), BlockTable)
            Dim btr As BlockTableRecord = DirectCast(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)

            Dim mycircle As New Circle(New Point3d(-10, 0, 0), New Vector3d(0, 0, 1), 1.0)
            btr.AppendEntity(mycircle)
            tr.AddNewlyCreatedDBObject(mycircle, True)

            Dim myline As New Line(New Point3d(0, 0, 0), New Point3d(100, 100, 0))
            btr.AppendEntity(myline)
            tr.AddNewlyCreatedDBObject(myline, True)

            Dim mymeasurelen As Double = myline.Length

            ' Offset the Circle, Line and Spline by a fixed amount
            Dim offset As Matrix3d = Matrix3d.Displacement(New Vector3d(60, 10, 0))
            mycircle.TransformBy(offset)
            myline.TransformBy(offset)

            MyArrayEntitiesIds.Add(mycircle.ObjectId)
            Dim basept As New VertexRef(mycircle.Center)

            Dim MyArrayParams As New AssocArrayPathParameters With { _
                 .ItemSpacing = 2.51#, _
                 .RowSpacing = 10, _
                 .LevelSpacing = 0, _
                 .ItemCount = 6, _
                 .RowCount = 2, _
                 .LevelCount = 0, _
                 .RowElevation = 0 _
             }

            MyArrayParams.Method = AssocArrayPathParameters.MethodType.Measure
            MyArrayParams.Path = New EdgeRef(myline)

            AssocArray.CreateArray(MyArrayEntitiesIds, basept, MyArrayParams)
            AssocManager.EvaluateTopLevelNetwork(Db, Nothing, 0)

            tr.Commit()
        End Using

Jeff H

  • Needs a day job
  • Posts: 6144
Re: 2012 Associative Array Simple Example
« Reply #2 on: March 02, 2012, 01:07:29 PM »
I guess you are referring to Kean code from here but using developerFusion and needed a little to tweak in while loop that caused an error it worked fine for me.
 
Code - Visual Basic: [Select]
  1.         <CommandMethod("AAP")> _
  2.         Public Sub CreateAssocArrayPath()
  3.             Dim db As Database = Application.DocumentManager.MdiActiveDocument.Database
  4.             Dim tr As Transaction = db.TransactionManager.StartTransaction()
  5.             Using tr
  6.                 Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
  7.                 Dim btr As BlockTableRecord = DirectCast(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
  8.                 ' Add profile entities: a Circle and a Line
  9.                Dim cir As New Circle(New Point3d(-10, 0, 0), New Vector3d(0, 0, 1), 1.0)
  10.                 cir.ColorIndex = 3
  11.                 ' Green
  12.                btr.AppendEntity(cir)
  13.                 tr.AddNewlyCreatedDBObject(cir, True)
  14.                 Dim ln As New Line(New Point3d(-11, -1, 0), New Point3d(-9, 1, 0))
  15.                 ln.ColorIndex = 3
  16.                 ' Green
  17.                btr.AppendEntity(ln)
  18.                 tr.AddNewlyCreatedDBObject(ln, True)
  19.                 ' Add path entity: a Spline, in this case
  20.                Dim fitTol As Double = 0.0
  21.                 Dim order As Integer = 4
  22.                 ' An array of doubles to define the points
  23.                ' in our spline
  24.                Dim ptAr As Double() = New Double() {-6.8447, 0.943, 0, -5.1409, -3.0562, 0, _
  25.                  -2.4095, 2.1049, 0, 3.459, -3.9479, 0, _
  26.                  7.137, 6.3472, 0}
  27.                 ' We'll add the points to a collection
  28.                Dim pts As New Point3dCollection()
  29.  
  30.                 Dim i As Integer = 0, j As Integer = 0
  31.                 While i < ptAr.Length \ 3
  32.                     pts.Add(New Point3d(ptAr(j), ptAr(j + 1), ptAr(j + 2)))
  33.                     i  = 1
  34.                     j  = 3
  35.                 End While
  36.                 ' Create the spline path and add it to the database
  37.                Dim sp As New Spline(pts, order, fitTol)
  38.                 btr.AppendEntity(sp)
  39.                 tr.AddNewlyCreatedDBObject(sp, True)
  40.                 ' Offset the Circle, Line and Spline by a fixed amount
  41.                Dim offset As Matrix3d = Matrix3d.Displacement(New Vector3d(60, 10, 0))
  42.                 cir.TransformBy(offset)
  43.                 ln.TransformBy(offset)
  44.                 sp.TransformBy(offset)
  45.                 Dim srcEnts As New ObjectIdCollection()
  46.                 srcEnts.Add(cir.ObjectId)
  47.                 srcEnts.Add(ln.ObjectId)
  48.                 ' Take the base point as the center of our Circle
  49.                Dim basePt As New VertexRef(cir.Center)
  50.                 ' Set some variables to define parameters for our path
  51.                Dim itemCount As Integer = 6
  52.                 Dim itemSpacing As Double = sp.GetDistanceAtParameter(sp.EndParam) / itemCount
  53.                 Dim rowSpacing As Double = 0.0
  54.                 Dim levelSpacing As Double = 0.0
  55.                 Dim rowCount As Integer = 0
  56.                 Dim levelCount As Integer = 0
  57.                 Dim rowElevation As Double = 0.0
  58.                 ' Create the parameters for our associative path array
  59.                Dim pars As New AssocArrayPathParameters(itemSpacing, rowSpacing, levelSpacing, itemCount, rowCount, levelCount, rowElevation)
  60.                 pars.Method = AssocArrayPathParameters.MethodType.Measure
  61.                 pars.Path = New EdgeRef(sp)
  62.                 ' Create the associative array itself
  63.                Dim array As AssocArray = AssocArray.CreateArray(srcEnts, basePt, pars)
  64.                 ' Evaluate the array
  65.                AssocManager.EvaluateTopLevelNetwork(db, Nothing, 0)
  66.                 tr.Commit()
  67.             End Using
  68.         End Sub
  69.  

JanetDavidson

  • Mosquito
  • Posts: 17
Re: 2012 Associative Array Simple Example
« Reply #3 on: March 02, 2012, 08:06:04 PM »
Thanks Jeff,
That was the code I took.
Still it crashes on my machine.
I am using  Autocad 2012.
Kind of disappointed.
Regards,
Janet.

Jeff H

  • Needs a day job
  • Posts: 6144
Re: 2012 Associative Array Simple Example
« Reply #4 on: March 02, 2012, 08:22:16 PM »
What line and what is the error?

JanetDavidson

  • Mosquito
  • Posts: 17
Re: 2012 Associative Array Simple Example
« Reply #5 on: March 02, 2012, 10:38:02 PM »
Hello Jeff.
I debugged your code and seems this loop doesn't like to finish. Code stuck here.

              While (i < ptAr.Length \ 3)
                    pts.Add(New Point3d(ptAr(j), ptAr(j + 1), ptAr(j + 2)))
                    i = 1
                    j = 3
                End While

and frankly I don't need a spline ( and I don't understand its class either ) .Could you please make a simple line or a pline instead of spline.
Regards,
J.





Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: 2012 Associative Array Simple Example
« Reply #6 on: March 03, 2012, 12:10:17 AM »
Hello Jeff.
I debugged your code and seems this loop doesn't like to finish. Code stuck here.

              While (i < ptAr.Length \ 3)
                    pts.Add(New Point3d(ptAr(j), ptAr(j + 1), ptAr(j + 2)))
                    i = 1
                    j = 3
                End While

and frankly I don't need a spline ( and I don't understand its class either ) .Could you please make a simple line or a pline instead of spline.
Regards,
J.






Yeah, it would seem he has an infinite loop there ....

Try this instead:
Code - Visual Basic: [Select]
  1.  While i < ptAr.Length \ 3
  2.                 pts.Add(New Point3d(ptAr(j), ptAr(j + 1), ptAr(j + 2)))
  3.                 i += 1
  4.                 j += 3
  5.  End While
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

JanetDavidson

  • Mosquito
  • Posts: 17
Re: 2012 Associative Array Simple Example
« Reply #7 on: March 03, 2012, 01:20:05 AM »
Keith that was the trick.
Thanks Both of you. Now I will have fun with this for a while. It was a good Thread Jeff.
Regards,
Janet.

Jeff H

  • Needs a day job
  • Posts: 6144
Re: 2012 Associative Array Simple Example
« Reply #8 on: March 05, 2012, 10:00:21 AM »
Some reason while pasting from IE9 the + signs get removed??

Jeff H

  • Needs a day job
  • Posts: 6144
Re: 2012 Associative Array Simple Example
« Reply #9 on: March 22, 2012, 08:26:58 PM »
Saw this asked here and slapped this together quickly and please pay no attention to style or technique as just threw it together for example.
 
Not sure if there is a different approach but I guess I could look at the massive amount documentation and resources Autodesk publishes.
 
To modify a Associative array you can use AssocArray.GetParameters which returns a AssocArrayParameters object that contains one method AssocArrayParameters.Commit
Quote
  This method commits the changes contained in the AssocArrayParameters object and syncs the changes with the database, so the changes to the array are visible on the screen.
If there is no owner of AssocArrayParameters, no changes are committed.

So do not forget to call commit.
 
Then use the appropriate derived class for modifying the array parameters.
 
Converted first post to VB
Code - Visual Basic: [Select]
  1.  
  2.          <CommandMethod("RectandPolarAssocArr")> _
  3.         Public Sub RectandPolarAssocArr()
  4.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  5.             Dim db As Database = doc.Database
  6.             Dim ed As Editor = doc.Editor
  7.  
  8.             Using trx As Transaction = db.TransactionManager.StartTransaction()
  9.                 Dim rectArrayEntitiesIds As New ObjectIdCollection()
  10.                 Dim polarArrayEntitiesIds As New ObjectIdCollection()
  11.                 Dim bt As BlockTable = DirectCast(trx.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
  12.                 Dim modelSpace As BlockTableRecord = DirectCast(trx.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
  13.                 Dim circle As New Circle(Point3d.Origin, Vector3d.ZAxis, 5)
  14.                 modelSpace.AppendEntity(circle)
  15.                 trx.AddNewlyCreatedDBObject(circle, True)
  16.                 Dim line As New Line(Point3d.Origin, New Point3d(5, 0, 0))
  17.                 modelSpace.AppendEntity(line)
  18.                 trx.AddNewlyCreatedDBObject(line, True)
  19.                 rectArrayEntitiesIds.Add(circle.ObjectId)
  20.                 polarArrayEntitiesIds.Add(line.ObjectId)
  21.                 Dim rectParams As New AssocArrayRectangularParameters() With { _
  22.                  .ColumnCount = 10, _
  23.                  .ColumnSpacing = 10, _
  24.                  .RowCount = 10, _
  25.                  .RowSpacing = 10, _
  26.                  .RowElevation = 0, _
  27.                  .LevelCount = 10, _
  28.                  .LevelSpacing = 10, _
  29.                  .XAxisDirection = Vector3d.XAxis, _
  30.                  .YAxisDirection = Vector3d.YAxis, _
  31.                  .BasePoint = New VertexRef(New Point3d(50, 50, 0)) _
  32.                 }
  33.                 AssocArray.CreateArray(rectArrayEntitiesIds, rectParams.BasePoint, rectParams)
  34.  
  35.                 Dim polarParams As New AssocArrayPolarParameters() With { _
  36.                  .FillAngle = 360, _
  37.                  .AngleBetweenItems = 10, _
  38.                  .ItemCount = 36, _
  39.                  .RowCount = 10, _
  40.                  .RowElevation = 10, _
  41.                  .RowSpacing = 10, _
  42.                  .Radius = 30, _
  43.                  .Direction = AssocArrayPolarParameters.ArcDirection.CounterClockwise, _
  44.                  .StartAngle = 0, _
  45.                  .RotateItems = True _
  46.                 }
  47.                 AssocArray.CreateArray(polarArrayEntitiesIds, New VertexRef(New Point3d(100, 100, 0)), polarParams)
  48.  
  49.                 trx.Commit()
  50.             End Using
  51.         End Sub
  52.  

 
And for modifying the arrays.
 
Code - Visual Basic: [Select]
  1.     <CommandMethod("ModifyRectandPolarAssocArr")> _
  2.         Public Sub ModifyRectandPolarAssocArr()
  3.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  4.             Dim db As Database = doc.Database
  5.             Dim ed As Editor = doc.Editor
  6.  
  7.             Using trx As Transaction = db.TransactionManager.StartTransaction()
  8.                 Dim peo As New PromptEntityOptions(Environment.NewLine & "Select a Array: ")
  9.                 Dim per As PromptEntityResult = ed.GetEntity(peo)
  10.                 If per.Status <> PromptStatus.OK Then
  11.                     Return
  12.                 End If
  13.                 If Not AssocArray.IsAssociativeArray(per.ObjectId) Then
  14.                     Return
  15.                 End If
  16.                 Dim array As AssocArray = AssocArray.GetAssociativeArray(per.ObjectId)
  17.                 If TypeOf array.GetParameters Is AssocArrayPolarParameters Then
  18.                     Dim arrayPolarParam As AssocArrayPolarParameters = array.GetParameters
  19.                     arrayPolarParam.ItemCount = arrayPolarParam.ItemCount / 2
  20.                     arrayPolarParam.RowCount = arrayPolarParam.RowCount / 2
  21.                     arrayPolarParam.RowSpacing = arrayPolarParam.RowSpacing / 2
  22.                     arrayPolarParam.Commit()
  23.                 ElseIf TypeOf array.GetParameters Is AssocArrayRectangularParameters Then
  24.                     Dim arrayRecParam As AssocArrayRectangularParameters = array.GetParameters
  25.                     arrayRecParam.ColumnCount = arrayRecParam.ColumnCount / 2
  26.                     arrayRecParam.RowCount = arrayRecParam.RowCount / 2
  27.                     arrayRecParam.RowSpacing = arrayRecParam.RowSpacing / 2
  28.                     arrayRecParam.Commit()
  29.                 Else
  30.                     Return
  31.                 End If
  32.                 trx.Commit()
  33.             End Using
  34.         End Sub
  35.  

JanetDavidson

  • Mosquito
  • Posts: 17
Re: 2012 Associative Array Simple Example
« Reply #10 on: March 22, 2012, 11:16:33 PM »
Thanks Jeff,
 it works great and now I know how to accees the class.  How about Replacing sub entites ?. I found following code in C# which works great , ATTN code .  After converting to vb. It doesn't work .It has something to do with how to declare   FullSubentityPath()  in vb which I don't know exactly. Could you please take a look at vb code and tell what is wrong with that? Thanks in advance . Janet.


 
Code - C#: [Select]
  1.  
  2.   [CommandMethod("ReplaceItems")]
  3.         public void ReplaceItems()
  4.         {
  5.             Document doc = Application.DocumentManager.MdiActiveDocument;
  6.             Database db = doc.Database;
  7.             Editor ed = doc.Editor;
  8.  
  9.             PromptEntityOptions peo1 = new PromptEntityOptions("\nSelect an Associative Array: ");
  10.            
  11.             PromptEntityResult per1 = ed.GetEntity(peo1);
  12.  
  13.             if (per1.Status != PromptStatus.OK)
  14.                 return;
  15.  
  16.             if (!AssocArray.IsAssociativeArray(per1.ObjectId))
  17.             {
  18.                 ed.WriteMessage("\nNot an Associative Array, please try again...");
  19.                 return;
  20.             }
  21.  
  22.             FullSubentityPath[] paths;
  23.  
  24.             if (AcHelper.SelectNestedEntities("\nSelect array items: ", out paths) != PromptStatus.OK)
  25.                 return;
  26.  
  27.             PromptEntityOptions peo2 = new PromptEntityOptions("\nSelect entity for substitution: ");
  28.  
  29.             PromptEntityResult per2 = ed.GetEntity(peo2);
  30.  
  31.             if (per2.Status != PromptStatus.OK)
  32.                 return;
  33.             PromptPointResult ppr = ed.GetPoint("\nSelect base point: ");
  34.             if (ppr.Status != PromptStatus.OK)
  35.                 return;
  36.             using (Transaction Tx = db.TransactionManager.StartTransaction())
  37.             {
  38.                 AssocArray array = AssocArray.GetAssociativeArray(per1.ObjectId);
  39.                 ItemLocator[] ItemLocators = AssocArray.getItemLocators(paths);
  40.                 ObjectIdCollection substEntities = new ObjectIdCollection();
  41.                 substEntities.Add(per2.ObjectId);
  42.                 VertexRef basePoint = new VertexRef(ppr.Value);
  43.                 array.ReplaceItems(ItemLocators, substEntities, basePoint);
  44.                 AssocManager.EvaluateTopLevelNetwork(db, null, 0);
  45.                 Tx.Commit();
  46.             }
  47.         }
  48.  


Code - C#: [Select]
  1.  
  2. [assembly: CommandClass(typeof(AssocArrayAPI.AcHelper))]
  3. namespace AssocArrayAPI
  4.  
  5.     public class AcHelper
  6.     {
  7.           public static PromptStatus SelectNestedEntities(string prompt, out ObjectIdCollection ids, out FullSubentityPath[] paths)
  8.         {
  9.             Document doc = Application.DocumentManager.MdiActiveDocument;
  10.             Database db = doc.Database;
  11.             Editor ed = doc.Editor;
  12.  
  13.             using (Transaction Tx = db.TransactionManager.StartTransaction())
  14.             {
  15.                 ids = new ObjectIdCollection();
  16.  
  17.                 List<FullSubentityPath> pathsList = new List<FullSubentityPath>();
  18.  
  19.                 PromptNestedEntityOptions pneo = new PromptNestedEntityOptions(prompt);
  20.                 pneo.AllowNone = true;
  21.  
  22.                 // Loop until cancelled or completed
  23.                 while (true)
  24.                 {
  25.                     PromptNestedEntityResult rs = ed.GetNestedEntity(pneo);
  26.  
  27.                     // Return whether the function was cancelled
  28.                     if (rs.Status != PromptStatus.OK)
  29.                     {
  30.                         paths = pathsList.ToArray();
  31.  
  32.                         UnhighlightSubEntities(paths);
  33.  
  34.                         return (rs.Status != PromptStatus.None ? rs.Status : PromptStatus.OK);
  35.                     }
  36.  
  37.                     ids.Add(rs.ObjectId);
  38.  
  39.                     FullSubentityPath path = HighlightSubEntity(rs);
  40.  
  41.                     if (path != FullSubentityPath.Null)
  42.                         pathsList.Add(path);
  43.                 }
  44.             }
  45.         }
  46.  
  47.         public static PromptStatus SelectNestedEntities(string prompt, out FullSubentityPath[] paths)
  48.         {
  49.             ObjectIdCollection ids = new ObjectIdCollection();
  50.  
  51.             return SelectNestedEntities(prompt, out ids, out paths);
  52.         }
  53.          private static FullSubentityPath HighlightSubEntity(PromptNestedEntityResult rs)
  54.         {
  55.             // Extract relevant information from the prompt object
  56.             ObjectId selId = rs.ObjectId;
  57.  
  58.             List<ObjectId> objIds = new List<ObjectId>(rs.GetContainers());
  59.  
  60.             // Reverse the "containers" list
  61.             objIds.Reverse();
  62.  
  63.             // Now append the selected entity
  64.             objIds.Add(selId);
  65.  
  66.             // Retrieve the sub-entity path for this entity
  67.             SubentityId subEnt = new SubentityId(SubentityType.Null, System.IntPtr.Zero);
  68.  
  69.             FullSubentityPath path = new FullSubentityPath(objIds.ToArray(), subEnt);
  70.  
  71.             // Open the outermost container, relying on the open transaction...
  72.             Entity ent = objIds[0].GetObject(OpenMode.ForRead) as Entity;
  73.  
  74.             // ... and highlight the nested entity
  75.             if (ent == null)
  76.                 return FullSubentityPath.Null;
  77.  
  78.             ent.Highlight(path, false);
  79.  
  80.             // Return the sub-entity path for later unhighlighting
  81.             return path;
  82.         }
  83.         private static void UnhighlightSubEntities(FullSubentityPath[] paths)
  84.         {
  85.             foreach (FullSubentityPath path in paths)
  86.             {
  87.                 if (path == FullSubentityPath.Null)
  88.                     continue;
  89.  
  90.                 ObjectId[] ids = path.GetObjectIds();
  91.  
  92.                 Entity ent = ids[0].GetObject(OpenMode.ForRead) as Entity;
  93.  
  94.                 if (ent != null)
  95.                 {
  96.                     ent.Unhighlight(path, false);
  97.                 }
  98.             }
  99.         }
  100.     }
  101. }
  102.  

Code - vb.net: [Select]
  1.  
  2. Imports Autodesk.AutoCAD.DatabaseServices
  3. Imports Autodesk.AutoCAD.ApplicationServices
  4. Imports Autodesk.AutoCAD.EditorInput
  5. Imports Autodesk.AutoCAD.Runtime
  6.  
  7. Public Class Class1
  8.  
  9.     <CommandMethod("ReplaceItems")> _
  10.     Public Sub ReplaceItems()
  11.         Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  12.         Dim db As Database = doc.Database
  13.         Dim ed As Editor = doc.Editor
  14.         Dim peo1 As New PromptEntityOptions(vbLf & "Select an Associative Array: ")
  15.         Dim per1 As PromptEntityResult = ed.GetEntity(peo1)
  16.         If per1.Status <> PromptStatus.OK Then
  17.             Return
  18.         End If
  19.         If Not AssocArray.IsAssociativeArray(per1.ObjectId) Then
  20.             ed.WriteMessage(vbLf & "Not an Associative Array, please try again...")
  21.             Return
  22.         End If
  23.         Dim mypaths As FullSubentityPath()
  24.         If AcHelper.SelectNestedEntities(vbLf & "Select array items: ", mypaths) <> PromptStatus.OK Then
  25.             Return
  26.         End If
  27.         MsgBox(mypaths.Length.ToString)
  28.         Dim peo2 As New PromptEntityOptions(vbLf & "Select entity for substitution: ")
  29.  
  30.         Dim per2 As PromptEntityResult = ed.GetEntity(peo2)
  31.  
  32.         If per2.Status <> PromptStatus.OK Then
  33.             Return
  34.         End If
  35.  
  36.         Dim ppr As PromptPointResult = ed.GetPoint(vbLf & "Select base point: ")
  37.  
  38.         If ppr.Status <> PromptStatus.OK Then
  39.             Return
  40.         End If
  41.         Try
  42.             Using Tx As Transaction = db.TransactionManager.StartTransaction()
  43.                 Dim array As AssocArray = AssocArray.GetAssociativeArray(per1.ObjectId)
  44.                 Dim ItemLocators As ItemLocator() = AssocArray.getItemLocators(mypaths)
  45.                 Dim substEntities As New ObjectIdCollection()
  46.                 substEntities.Add(per2.ObjectId)
  47.                 Dim basePoint As New VertexRef(ppr.Value)
  48.                 array.ReplaceItems(ItemLocators, substEntities, basePoint)
  49.                 AssocManager.EvaluateTopLevelNetwork(db, Nothing, 0)
  50.                 Tx.Commit()
  51.             End Using
  52.         Catch ex As System.Exception
  53.             MsgBox(ex.Message & ex.StackTrace)
  54.         End Try
  55.     End Sub
  56.  
  57.     Public Class AcHelper
  58.         Public Shared Function SelectNestedEntities(ByVal prompt As String, ByVal ids As ObjectIdCollection, ByVal mypaths As FullSubentityPath()) As PromptStatus
  59.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  60.             Dim db As Database = doc.Database
  61.             Dim ed As Editor = doc.Editor
  62.             Using Tx As Transaction = db.TransactionManager.StartTransaction()
  63.                 ids = New ObjectIdCollection()
  64.                 Dim pathsList As New List(Of FullSubentityPath)()
  65.                 Dim pneo As New PromptNestedEntityOptions(prompt)
  66.                 pneo.AllowNone = True
  67.                 ' Loop until cancelled or completed
  68.                 While True
  69.                     Dim rs As PromptNestedEntityResult = ed.GetNestedEntity(pneo)
  70.                     ' Return whether the function was cancelled
  71.                     If rs.Status <> PromptStatus.OK Then
  72.                         mypaths = pathsList.ToArray()
  73.                         UnhighlightSubEntities(mypaths)
  74.                         Return (If(rs.Status <> PromptStatus.None, rs.Status, PromptStatus.OK))
  75.                     End If
  76.                     ids.Add(rs.ObjectId)
  77.                     Dim path As FullSubentityPath = HighlightSubEntity(rs)
  78.  
  79.                     If path <> FullSubentityPath.Null Then
  80.                         pathsList.Add(path)
  81.                     End If
  82.                 End While
  83.             End Using
  84.         End Function
  85.         Public Shared Function SelectNestedEntities(ByVal prompt As String, ByVal mypaths As FullSubentityPath()) As PromptStatus
  86.             Dim ids As New ObjectIdCollection()
  87.             Return SelectNestedEntities(prompt, ids, mypaths)
  88.         End Function
  89.         Private Shared Function HighlightSubEntity(ByVal rs As PromptNestedEntityResult) As FullSubentityPath
  90.             ' Extract relevant information from the prompt object
  91.             Dim selId As ObjectId = rs.ObjectId
  92.             Dim objIds As New List(Of ObjectId)(rs.GetContainers())
  93.             ' Reverse the "containers" list
  94.             objIds.Reverse()
  95.             ' Now append the selected entity
  96.             objIds.Add(selId)
  97.             ' Retrieve the sub-entity path for this entity
  98.             Dim subEnt As New SubentityId(SubentityType.Null, System.IntPtr.Zero)
  99.             Dim path As New FullSubentityPath(objIds.ToArray(), subEnt)
  100.             ' Open the outermost container, relying on the open transaction...
  101.             Dim ent As Entity = TryCast(objIds(0).GetObject(OpenMode.ForRead), Entity)
  102.             ' ... and highlight the nested entity
  103.             If ent Is Nothing Then
  104.                 Return FullSubentityPath.Null
  105.             End If
  106.             ent.Highlight(path, False)
  107.             ' Return the sub-entity path for later unhighlighting
  108.             Return path
  109.         End Function
  110.         Private Shared Sub UnhighlightSubEntities(ByVal mypaths As FullSubentityPath())
  111.             For Each path As FullSubentityPath In mypaths
  112.                 If path = FullSubentityPath.Null Then
  113.                     Continue For
  114.                 End If
  115.                 Dim ids As ObjectId() = path.GetObjectIds()
  116.                 Dim ent As Entity = TryCast(ids(0).GetObject(OpenMode.ForRead), Entity)
  117.                 If ent IsNot Nothing Then
  118.                     ent.Unhighlight(path, False)
  119.                 End If
  120.             Next
  121.         End Sub
  122.     End Class
  123. End Class
  124.  



EDIT-KDUB : code formatting
« Last Edit: March 22, 2012, 11:41:44 PM by Kerry »

Jeff H

  • Needs a day job
  • Posts: 6144
Re: 2012 Associative Array Simple Example
« Reply #11 on: March 23, 2012, 01:26:34 AM »
 
Just did real quick changes to get working and had to do with a function using a  out parameter
 
Code - Visual Basic: [Select]
  1.  
  2.  Imports Autodesk.AutoCAD.DatabaseServices
  3. Imports Autodesk.AutoCAD.ApplicationServices
  4. Imports Autodesk.AutoCAD.EditorInput
  5. Imports Autodesk.AutoCAD.Runtime
  6. Public Class Class1
  7.     <CommandMethod("ReplaceItems")> _
  8.     Public Sub ReplaceItems()
  9.         Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  10.         Dim db As Database = doc.Database
  11.         Dim ed As Editor = doc.Editor
  12.         Dim peo1 As New PromptEntityOptions(vbLf & "Select an Associative Array: ")
  13.         Dim per1 As PromptEntityResult = ed.GetEntity(peo1)
  14.         If per1.Status <> PromptStatus.OK Then
  15.             Return
  16.         End If
  17.         If Not AssocArray.IsAssociativeArray(per1.ObjectId) Then
  18.             ed.WriteMessage(vbLf & "Not an Associative Array, please try again...")
  19.             Return
  20.         End If
  21.         Dim mypaths As New List(Of FullSubentityPath)
  22.         If AcHelper.SelectNestedEntities(vbLf & "Select array items: ", mypaths) <> PromptStatus.OK Then
  23.             Return
  24.         End If
  25.         'MsgBox(mypaths.Length.ToString)
  26.        Dim peo2 As New PromptEntityOptions(vbLf & "Select entity for substitution: ")
  27.         Dim per2 As PromptEntityResult = ed.GetEntity(peo2)
  28.         If per2.Status <> PromptStatus.OK Then
  29.             Return
  30.         End If
  31.         Dim ppr As PromptPointResult = ed.GetPoint(vbLf & "Select base point: ")
  32.         If ppr.Status <> PromptStatus.OK Then
  33.             Return
  34.         End If
  35.         Try
  36.             Using Tx As Transaction = db.TransactionManager.StartTransaction()
  37.                 Dim array As AssocArray = AssocArray.GetAssociativeArray(per1.ObjectId)
  38.                 Dim ItemLocators As ItemLocator() = AssocArray.getItemLocators(mypaths.ToArray)
  39.                 Dim substEntities As New ObjectIdCollection()
  40.                 substEntities.Add(per2.ObjectId)
  41.                 Dim basePoint As New VertexRef(ppr.Value)
  42.                 array.ReplaceItems(ItemLocators, substEntities, basePoint)
  43.                 AssocManager.EvaluateTopLevelNetwork(db, Nothing, 0)
  44.                 Tx.Commit()
  45.             End Using
  46.         Catch ex As System.Exception
  47.             MsgBox(ex.Message & ex.StackTrace)
  48.         End Try
  49.     End Sub
  50.     Public Class AcHelper
  51.         Public Shared Function SelectNestedEntities(ByVal prompt As String, ByRef ids As ObjectIdCollection, ByRef mypaths As List(Of FullSubentityPath)) As PromptStatus
  52.             Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  53.             Dim db As Database = doc.Database
  54.             Dim ed As Editor = doc.Editor
  55.             Using Tx As Transaction = db.TransactionManager.StartTransaction()
  56.                 ids = New ObjectIdCollection()
  57.                 Dim pathsList As New List(Of FullSubentityPath)()
  58.                 Dim pneo As New PromptNestedEntityOptions(prompt)
  59.                 pneo.AllowNone = True
  60.                 ' Loop until cancelled or completed
  61.                While True
  62.                     Dim rs As PromptNestedEntityResult = ed.GetNestedEntity(pneo)
  63.                     ' Return whether the function was cancelled
  64.                    If rs.Status <> PromptStatus.OK Then
  65.                         mypaths = pathsList ''.ToArray()
  66.                        UnhighlightSubEntities(mypaths.ToArray())
  67.                         Return (If(rs.Status <> PromptStatus.None, rs.Status, PromptStatus.OK))
  68.                     End If
  69.                     ids.Add(rs.ObjectId)
  70.                     Dim path As FullSubentityPath = HighlightSubEntity(rs)
  71.                     If path <> FullSubentityPath.Null Then
  72.                         pathsList.Add(path)
  73.                     End If
  74.                 End While
  75.             End Using
  76.         End Function
  77.         Public Shared Function SelectNestedEntities(ByVal prompt As String, ByRef mypaths As List(Of FullSubentityPath)) As PromptStatus
  78.             Dim ids As New ObjectIdCollection()
  79.             Return SelectNestedEntities(prompt, ids, mypaths)
  80.         End Function
  81.         Private Shared Function HighlightSubEntity(ByVal rs As PromptNestedEntityResult) As FullSubentityPath
  82.             ' Extract relevant information from the prompt object
  83.            Dim selId As ObjectId = rs.ObjectId
  84.             Dim objIds As New List(Of ObjectId)(rs.GetContainers())
  85.             ' Reverse the "containers" list
  86.            objIds.Reverse()
  87.             ' Now append the selected entity
  88.            objIds.Add(selId)
  89.             ' Retrieve the sub-entity path for this entity
  90.            Dim subEnt As New SubentityId(SubentityType.Null, System.IntPtr.Zero)
  91.             Dim path As New FullSubentityPath(objIds.ToArray(), subEnt)
  92.             ' Open the outermost container, relying on the open transaction...
  93.            Dim ent As Entity = TryCast(objIds(0).GetObject(OpenMode.ForRead), Entity)
  94.             ' ... and highlight the nested entity
  95.            If ent Is Nothing Then
  96.                 Return FullSubentityPath.Null
  97.             End If
  98.             ent.Highlight(path, False)
  99.             ' Return the sub-entity path for later unhighlighting
  100.            Return path
  101.         End Function
  102.         Private Shared Sub UnhighlightSubEntities(ByVal mypaths As FullSubentityPath())
  103.             For Each path As FullSubentityPath In mypaths
  104.                 If path = FullSubentityPath.Null Then
  105.                     Continue For
  106.                 End If
  107.                 Dim ids As ObjectId() = path.GetObjectIds()
  108.                 Dim ent As Entity = TryCast(ids(0).GetObject(OpenMode.ForRead), Entity)
  109.                 If ent IsNot Nothing Then
  110.                     ent.Unhighlight(path, False)
  111.                 End If
  112.             Next
  113.         End Sub
  114.     End Class
  115. End Class
  116.  

JanetDavidson

  • Mosquito
  • Posts: 17
Re: 2012 Associative Array Simple Example
« Reply #12 on: March 23, 2012, 09:24:12 AM »
As usual, A great Help . Works Perfect. Now I realize those online translators are not trustful.
There were lots of trick you did to make it work.
I really appreciated you time and skills and knowledge.
Regards,
Janet.

Eycki

  • Guest
Re: 2012 Associative Array Simple Example
« Reply #13 on: May 21, 2012, 06:01:03 AM »
Hello, I got some extra questions about the associative array.

Is it possible to select automatically the source entity? This would make things a lot easier for me.

What I want to do is like the Arrayedit (select array),  REPlace (select which object you want to add to array), Basepoint (centroid), Source objects. 
I know there is a replaceitems routine above here. But my knowledge is not good enough to know what exactly I need to change to make it replace the source objects (without the need of selecting a source entity)

EDIT: The easiest option would be to select automatically the source object (Dynamic block in this case) instead of prompting for nested entity.  When I can get this object selected I can have its ObjectID and make changes to attributes and make changes to dynamic properties of the dynamic blocks inside my Associative Array.

Thx in advance!
« Last Edit: May 22, 2012, 05:39:40 AM by Eycki »

Eycki

  • Guest
Re: 2012 Associative Array Simple Example
« Reply #14 on: May 22, 2012, 09:24:27 AM »
Hello, I got some extra questions about the associative array.

Is it possible to select automatically the source entity? This would make things a lot easier for me.

What I want to do is like the Arrayedit (select array),  REPlace (select which object you want to add to array), Basepoint (centroid), Source objects. 
I know there is a replaceitems routine above here. But my knowledge is not good enough to know what exactly I need to change to make it replace the source objects (without the need of selecting a source entity)

EDIT: The easiest option would be to select automatically the source object (Dynamic block in this case) instead of prompting for nested entity.  When I can get this object selected I can have its ObjectID and make changes to attributes and make changes to dynamic properties of the dynamic blocks inside my Associative Array.

Thx in advance!

I solved my problem by getting the nested block references of the selected Associative array which is in fact a block.  Then take the first objectid of the objectidcollection and make changes in attributes and dynamic properties.