Author Topic: Returning to .NET in AutoCAD (and The Swamp for that matter) after a decade+  (Read 3986 times)

0 Members and 1 Guest are viewing this topic.

AlexFielder

  • Mosquito
  • Posts: 11
Hi folks,

I find myself back in these (extremely helpful) waters after more than a decade away and, I can't help feeling odd that I am seemingly able to reuse code that I last touched using AutoCAD 2010. Am I missing/misunderstanding advancements that have been added in the interim or have things really changed that little in the intervening years?

I am specifically interested in the areas of jigging blocks for insert based on/around this old repo of mine which I recently uploaded to github.com:

https://github.com/AlexFielder/CreateLayouts

Thanks,

Alex.

PS. I used to post here using the vegbruiser account, but that has long-since been wiped off the user list :|

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Welcome back.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

AlexFielder

  • Mosquito
  • Posts: 11
Welcome back.

Thanks John. I guess my question wasn't interesting/specific enough to elicit a response from the more-learned members here. (Quietly shuffles off to reuse a bunch of code that doesn't seem to have needed updating in 10+ years)

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8712
  • AKA Daniel
I think the only change is the addition of accoremgd, so now there’s three(+) modules 
Accoremgd, Acdbmgd and Acmgd. I’m not doing .NET anymore, so I haven’t been keeping track of the changes

n.yuan

  • Bull Frog
  • Posts: 348
The other compatibility change is the famous "FIBER" removal in AutoCAD 2015: it eliminated the pain to having set "FIBER" to 0 in order to debug in pre-Acad2015 versions, but it surely broke some existing application due to the change that a command would not resume/be cancelled when current document is switch away and then switch back.
Of course, no-longer having 32-bit version since Acad2020(?) may force some older apps to be updated.

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Hi Alex,

I put ACAD down for couple years,

so I feel your pain.

The addage 'use it or lose it ' sure does apply to coding !!
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

AlexFielder

  • Mosquito
  • Posts: 11
Thanks for the replies folks. I am aware of the Accoremgd-related changes, so perhaps it hasn't been as long as I thought.  :idiot2:

It's rather odd actually turning this stuff back on in my brain and being honest, seems like the perfect opportunity to pit Bard, ChatGPT (4.0) and CoPilot against one another for those times when I seem to have forgotten something obvious.

Unlike a bunch of the other APIs that Autodesk have (looking at you Inventor) the AutoCAD .NET API seems to take the line of "if it compiles in VS2022 then it will either do what you want or do nothing at all"

 :smitten:

AlexFielder

  • Mosquito
  • Posts: 11
Thanks for the replies folks. I am aware of the Accoremgd-related changes, so perhaps it hasn't been as long as I thought.  :idiot2:

It's rather odd actually turning this stuff back on in my brain and being honest, seems like the perfect opportunity to pit Bard, ChatGPT (4.0) and CoPilot against one another for those times when I seem to have forgotten something obvious.

Unlike a bunch of the other APIs that Autodesk have (looking at you Inventor) the AutoCAD .NET API seems to take the line of "if it compiles in VS2022 then it will either do what you want or do nothing at all"

 :smitten:

Oh, past me... if only you could have known.  :tickedoff:

So it seems that unlike last time I had to work with Dynamic blocks, these ones are a royal pain in the arse.

I have three blocks I am trying to "configure"; one has only attributes so that works fine.

One of the other two has both attributes and dynamic dimensions along with visibility states and resizes/places fine and with some encouragement will change visibility states after placement.

The third block is being a complete pig and although it resizes during and after placement it resolutely refuses to adhere to any of the visibility states.

Even after saving and closing and reopening the drawing these are placed into the third block misbehaves.

I have attached it on the off-chance someone here can see something wrong with it. (I have rebuilt the visibility states and dynamic dimensions today just in case I screwed something up hence the "NewMasonrySupport" name)

fwiw here is my "Insert" method:

Code - C#: [Select]
  1. public void InsertBlock(string blockName, ParametersFromEng parameters, BlockPosition blockPosition, int BlockType, bool? IsSystemDefinition = false)
  2. {
  3.         Point3d NewInsertionPoint;
  4.         Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
  5.         using (Transaction tr = db.TransactionManager.StartTransaction())
  6.         {
  7.                 BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
  8.                 List<BlockReference> insertedBlocks = FindBlockReferencesByName(doc, blockName);
  9.  
  10.                 if (insertedBlocks.Count != 0)
  11.                 {
  12.                         // Sort the list based on the distance from the origin (0, 0)
  13.                         var sortedBlockReferences = insertedBlocks.OrderBy(br => br.Position.DistanceFromOrigin()).ToList();
  14.  
  15.                         if (sortedBlockReferences != null)
  16.                         {
  17.                                 //get the last block in the list and use that as the insertion point for the next block (adding the ParameterContainerSpacingX value to the X value and the ParameterContainerSpacingY value to the y value)
  18.                                 if (blockPosition == BlockPosition.OneMetreAboveOrigin)
  19.                                 {
  20.                                         NewInsertionPoint = sortedBlockReferences.Last().Position + new Vector3d(PlanBlockDefinitionSpacingX, PlanBlockDefinitionSpacingY, 0);  //new Point3d(0, 100, 0);
  21.                                 }
  22.                                 else if (blockPosition == BlockPosition.TwoMetresAboveOrigin)
  23.                                 {
  24.                                         NewInsertionPoint = sortedBlockReferences.Last().Position + new Vector3d(ProfileBlockDefinitionSpacingX, PlanBlockDefinitionSpacingY, 0); //new Point3d(0, 2000, 0);
  25.                                 }
  26.                                 else
  27.                                 {
  28.                                         NewInsertionPoint = sortedBlockReferences.Last().Position + new Vector3d(ParameterContainerSpacingX, 0, 0);
  29.                                 }
  30.  
  31.                         }
  32.                         else
  33.                         {
  34.                                 log.Error("Unable to sort the list of inserted blocks");
  35.                                 throw new System.Exception("Unable to sort the list of inserted blocks");
  36.                         }
  37.                 }
  38.                 else
  39.                 {
  40.                         //no blocks inserted so use the ParameterContainerSpacingX and ParameterContainerSpacingY values to insert the block
  41.                         if (blockPosition == BlockPosition.OneMetreAboveOrigin)
  42.                         {
  43.                                 NewInsertionPoint = new Point3d(0, 1000, 0);
  44.                         }
  45.                         else if (blockPosition == BlockPosition.TwoMetresAboveOrigin)
  46.                         {
  47.                                 NewInsertionPoint = new Point3d(0, 2000, 0);
  48.                         }
  49.                         else
  50.                         {
  51.                                 NewInsertionPoint = Point3d.Origin;
  52.                         }
  53.                 }
  54.  
  55.                 // how this needs to work:
  56.                 //1.- Create the block reference
  57.  
  58.                 //2.- Set its properties(layer, scale, rotation)
  59.  
  60.                 //3.- Append the block reference to the block table record:blkTblRec.AppendEntity(blkRef)
  61.  
  62.                 //4.- Add the newly created object to the database:MyTrans.AddNewlyCreatedDBObject(blkRef, true)
  63.  
  64.                 //5.- Add Attributes if it have
  65.  
  66.                 //6.- Set the dynamic properties including visible state
  67.  
  68.                 //7.- Set the Record Graphics Mofied to true: blkRef.RecordGraphicsModified(true)
  69.  
  70.                 //8.- Update the blocktable record for the anonymous block:blkTblRec.UpdateAnonymousBlock
  71.  
  72.                 //9.- Commit the transaction.
  73. [b]// the important bit starts here //[/b]
  74.                 BlockReference blkRef = new BlockReference(NewInsertionPoint, GetBlockId(db, blockName));
  75.                 blkRef.SetDatabaseDefaults();
  76.                 modelSpace.AppendEntity(blkRef);
  77.                 tr.AddNewlyCreatedDBObject(blkRef, true);
  78.  
  79.                 SetBlockRefAttributeValuesBasedOnParameters(parameters, IsSystemDefinition, tr, blkRef);
  80.  
  81.                 SetBlockRefDynPropsBasedOnParameters(parameters, BlockType, blkRef);
  82.  
  83.                 blkRef.RecordGraphicsModified(true);
  84.                 modelSpace.UpdateAnonymousBlocks();
  85.  
  86.                 doc.SendStringToExecute("regen ", true, false, false);
  87.                 ed.Regen();
  88.                 ed.UpdateScreen();
  89.                 db.Regenmode = true;
  90.                 tm.QueueForGraphicsFlush();
  91.                 tr.Commit();
  92.         }
  93. }

steps 1 thru 9 (commented) came from this post: https://forums.autodesk.com/t5/net/dynamic-blocks-created-with-net-not-keeping-visibility-state/m-p/5217567/highlight/true#M41712

for brevity here is the method I am using to set the attributes:

Code - C#: [Select]
  1. public static void SetBlockRefAttributeValuesBasedOnParameters(ParametersFromEng parameters, bool? IsSystemDefinition, Transaction tr, BlockReference blkRef)
  2. {
  3.         BlockTableRecord blockDefinition = (BlockTableRecord)tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead);
  4.         foreach (ObjectId id in blockDefinition)
  5.         {
  6.  
  7.                 DBObject obj = tr.GetObject(id, OpenMode.ForRead);
  8.                 if (obj is AttributeDefinition attDef)
  9.                 {
  10.                         PropertyInfo[] propertyInfos = null;
  11.                         AttributeReference attRef = new AttributeReference();
  12.                         attRef.SetAttributeFromBlock(attDef, blkRef.BlockTransform);
  13.                         //add a special case for the IsSystemDefinition attribute
  14.                         if (attDef.Tag == "IsSystemDefinition")
  15.                         {
  16.                                 if (IsSystemDefinition != false)
  17.                                 {
  18.                                         attRef.TextString = IsSystemDefinition.ToString();
  19.                                 }
  20.                                 else
  21.                                 {
  22.                                         attRef.TextString = "false";
  23.                                 }
  24.                         }
  25.                         else
  26.                         {
  27.                                 // match each of the properties contained within the parameters object to the attribute tags and set the attribute textstring to the value of said property
  28.                                 propertyInfos = parameters.GetType().GetProperties();
  29.                                 attRef.TextString = propertyInfos.FirstOrDefault(pi => pi.Name == attDef.Tag)?.GetValue(parameters)?.ToString() ?? "default value";
  30.                         }
  31.  
  32.                         blkRef.AttributeCollection.AppendAttribute(attRef);
  33.                         tr.AddNewlyCreatedDBObject(attRef, true);
  34.                 }
  35.         }
  36. }

and here is the method that is setting the dynamic properties:

Code - C#: [Select]
  1. public static void SetBlockRefDynPropsBasedOnParameters(ParametersFromEng parameters, int BlockType, BlockReference blkRef)
  2. {
  3.         DynamicBlockReferencePropertyCollection blockDynProps = blkRef.DynamicBlockReferencePropertyCollection;
  4.  
  5.         if (BlockType != 2) //only for those blocks which have a "Visibility" dynamic property
  6.         {
  7.                 //LookupDynProp = blockDynProps.Cast<DynamicBlockReferenceProperty>().Where(x => x.PropertyName == "Visibility1").Single();
  8.                 //need to add a switch here to set the value based on whether the plan block is normal or one of the corner options.
  9.                 //string StartingVal = LookupDynProp.Value.ToString();
  10.                 //LookupDynProp.Value = "Standard"; // parameters.SystemReference;
  11.                 //LookupDynProp.Value = StartingVal;
  12.                 //LookupDynProp.Value = "Standard";
  13.  
  14.  
  15.                 switch (BlockType)
  16.                 {
  17.                         case 0:
  18.                                 foreach (DynamicBlockReferenceProperty dynProp in blockDynProps)
  19.                                 {
  20.                                         switch (dynProp.PropertyName)
  21.                                         {
  22.                                                 case "Visibility1":
  23.                                                         //set this based on the SystemReference
  24.                                                         dynProp.Value = "Standard";
  25.                                                         break;
  26.                                                 case "AngleCentreToBracketCentre":
  27.                                                         dynProp.Value = parameters.AngleCentreToBracketCentre;
  28.                                                         break;
  29.                                                 case "AngleDepth":
  30.                                                         dynProp.Value = parameters.AngleDepth;
  31.                                                         break;
  32.                                                 case "OptimumAngleLength":
  33.                                                         dynProp.Value = parameters.OptimumAngleLength;
  34.                                                         break;
  35.                                                 case "AngleThickness":
  36.                                                         dynProp.Value = parameters.AngleThickness;
  37.                                                         break;
  38.                                                 case "LeftMitreAngle":
  39.                                                         dynProp.Value = parameters.LeftMitreAngle;
  40.                                                         break;
  41.                                                 case "RightMitreAngle":
  42.                                                         dynProp.Value = parameters.RightMitreAngle;
  43.                                                         break;
  44.                                                 case "WallBracketBendRadius":
  45.                                                         dynProp.Value = parameters.BracketThickness * 2;
  46.                                                         break;
  47.                                                 case "WallBracketDepthOne":
  48.                                                 case "WallBracketDepthTwo" :
  49.                                                 case "WallBracketDepthThree":
  50.                                                 case "WallBracketDepthFour":
  51.                                                         dynProp.Value = parameters.BracketDepth1;
  52.                                                         break;
  53.                                                 case "WallBracketThickness":
  54.                                                         dynProp.Value = parameters.BracketThickness;
  55.                                                         break;
  56.                                                 case "WallBracketWidthOne":
  57.                                                 case "WallBracketWidthTwo":
  58.                                                 case "WallBracketWidthThree":
  59.                                                 case "WallBracketWidthFour":
  60.                                                         dynProp.Value = parameters.BracketWidth;
  61.                                                         break;
  62.                                                 case "WallBracketOneToTwo":
  63.                                                         dynProp.Value = parameters.WallBracketOneToTwo;
  64.                                                         break;
  65.                                                 case "WallBracketTwoToThree":
  66.                                                         dynProp.Value = parameters.WallBracketTwoToThree;
  67.                                                         break;
  68.                                                 case "WallBracketThreeToFour":
  69.                                                         dynProp.Value = parameters.WallBracketThreeToFour;
  70.                                                         break;
  71.                                         }
  72.                                 }
  73.                                 break;
  74.                         case 1:
  75.                                 foreach (DynamicBlockReferenceProperty dynProp in blockDynProps)
  76.                                 {
  77.                                         switch (dynProp.PropertyName)
  78.                                         {
  79.                                                 case "AngleA":
  80.                                                         dynProp.Value = parameters.AngleHeight;
  81.                                                         break;
  82.                                                 case "AngleB":
  83.                                                         dynProp.Value = parameters.AngleDepth;
  84.                                                         break;
  85.                                                 case "AngleBracketd":
  86.                                                         dynProp.Value = parameters.AngleDrop;
  87.                                                         break;
  88.                                                 case "AngleThickness":
  89.                                                         dynProp.Value = parameters.AngleThickness;
  90.                                                         break;
  91.                                                 case "Visibility1":
  92.                                                         //set this based on the SystemReference
  93.                                                         dynProp.Value = "Standard";
  94.                                                         break;
  95.                                                 case "WallBracketD2":
  96.                                                         dynProp.Value = parameters.BracketDepth2;
  97.                                                         break;
  98.                                                 case "WallBracketDepth":
  99.                                                         dynProp.Value = parameters.BracketDepth1;
  100.                                                         break;
  101.                                                 case "WallBracketh":
  102.                                                         dynProp.Value = parameters.BracketFrontHeight;
  103.                                                         break;
  104.                                                 case "WallBracketHeight":
  105.                                                         dynProp.Value = parameters.BracketHeight;
  106.                                                         break;
  107.                                                 case "WallBracketND":
  108.                                                         dynProp.Value = parameters.BracketNotchDepth;
  109.                                                         break;
  110.                                                 case "WallBracketNH":
  111.                                                         dynProp.Value = parameters.BracketNotchHeight;
  112.                                                         break;
  113.                                                 case "WallBracketThickness":
  114.                                                         dynProp.Value = parameters.BracketThickness;
  115.                                                         break;
  116.                                                 case "WallBracketX":
  117.                                                         dynProp.Value = parameters.BracketDepth1;
  118.                                                         break;
  119.                                         }
  120.                                 }
  121.                                 break;
  122.                 }
  123.         }
  124. }