Hi,
the workflow of a certain very frequently used design involves using the measure-command and mirroring a set of dynamic blocks. After the design is finished some dynamic block attribute values are extracted (dataextraction) and delivered to the customer.
The first problem is that the dynamic block [MYBLOCK] we are using has a custom rotation attribute [R1]. The block has many more custom attributes/properties as well as normal attributes. When the block is inserted with measure (with alignment to the measure path enabled) the block is rotated [R2]. When this is done the block appears correctly inserted, but the R1 value is still 0 when it should be R2 and R2 should be 0. This leads to incorrect values in the dataextraction table even though everything looks ok.
Correcting the block rotation to 0 was fairly easy but how do I use c# to edit a specific dynamic block attribute?
The second problem is that when the blocks are mirrored their scales change. What is the command to set a blocks scale? Should I use transform methods (scale with the inverse value of the block scale)? autodesk transform
I've come so far that I have a ObjectIdCollection with all the block ID's that need to be checked for and here is what should be done (somewhat simplified)
I am aware that we could use more sophisticated and not so error prone methods to achieve what I described, but solving this with coding is also educational for me. All pointers are greatly appreciated!
- F
PS. First timer here, so please be very detailed in your answers 😃
Solved! Go to Solution.
Solved by BKSpurgeon. Go to Solution.
I feel that posting your code would help yield a solution otherwise things are a guessing game to troubleshoot:
Nevertheless this post should answer your first question at the very least:
Perhaps post more details?
Hi,
Please show the relevant code in order people here can help you.
Some tips:
ATTSYNC Command
Gaston Nunez
Thanks for showing interest! The code I've managed to get together is below. There is one method, which is not given/explained. GetDynamicBlocksByName simply returns the objectids as an objectCollection. This code was written by somebody else: https://www.theswamp.org/index.php?topic=31859.0
By now I've found the classes etc I need to edit the things I think I need to edit, but I've run into an unexpected problem. The dynamic block is set to scale uniformly. This means that when a block with scalefactors 1,1,1 is mirrored over a "vertical" line the scale is shown as -1,(1),(1). The parenthesis mean that they are not editable via properties. This same behavior can be tested by mirroring a block over a "horizontal" line. This also leads to scalefactors -1,(1),(1) even though they ought to be something like 1,(-1),(1) imho...
Because of the uniform scale setting some of the block's functionality still seems to be affected by the negative x-scale even after setting the x-scale to 1. I believe this is due to the uniform scale setting regardless of that the y-scale is supposedly 1 after mirroring.
Another strange thing is that the code is supposed to leave all the "inj"-blocks selected after the code is run. The code is also supposed to check if a blocks x-scale doesn't equal 1 and change it the block scalefactors to 1,1,1. Some blocks (when the original block is first mirrored over a vertical and then a horizontal line) still has a x-scalefactor of -1. When I run the command again nothing changes...
Am I trying to edit the wrong properties? Should I used 2d-scalefactors? Am I missing something fundamental? All tips and comments are appreciated!
The math in the code is not entirely correct and does not result in what I'm trying to do so please don't mind the errors nor the unnecessary namespaces 😃
using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using System.Collections.Generic;
using Autodesk.AutoCAD.Internal;
namespace resetinjek { public class MyCommands { [CommandMethod("resetinj", CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)] public void resetinjek() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; string blkName = "inj"; ObjectIdCollection blockSet = GetDynamicBlocksByName(blkName); ObjectId[] blockSetArray =new ObjectId[blockSet.Count]; blockSet.CopyTo(blockSetArray, 0); double xscale, yscale, brot; Scale3d scale1 = new Scale3d(1, 1, 1); foreach (ObjectId blockId in blockSet) { Database db = blockId.Database; using (Transaction trans = db.TransactionManager.StartTransaction()) { BlockReference blockRef = trans.GetObject(blockId, OpenMode.ForWrite) as BlockReference; brot = blockRef.Rotation; xscale = blockRef.ScaleFactors.X; yscale = blockRef.ScaleFactors.Y; if (brot != 0) { blockRef.Rotation = 0; DynamicBlockReferencePropertyCollection properties = blockRef.DynamicBlockReferencePropertyCollection; foreach (DynamicBlockReferenceProperty property in properties) { if (xscale != 1) { blockRef.ScaleFactors = scale1; } if (property.PropertyName == "Direction") { if (xscale < 0) { brot += Math.PI; //adds 180 degrees to "Direction" } property.Value = (double)property.Value + brot; } } } trans.Commit(); } } Utils.SelectObjects(blockSetArray); }
I think you've muddled the nesting of the if statements?? -- try this code below - i made some changes so i hope it ports back to what you're trying to do:
in any case, it's scaling and rotating when I tried it -- no problem whatsoever.
please excuse me if i'm incorrect - but perhaps also make sure if you've defined a "direction" property in the dynamic block.
in short looks like the nesting of the if statements is causing the problem.
i hope this helps.
[CommandMethod("resetinj", CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)]
public void resetinjek()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
string blkName = "resetinj";
ObjectIdCollection blockSet = GetDynamicBlocksByName(blkName);
ObjectId[] blockSetArray =new ObjectId[blockSet.Count];
blockSet.CopyTo(blockSetArray, 0);
double xscale, yscale, brot;
Scale3d scale1 = new Scale3d(1, 1, 1);
foreach (ObjectId blockId in blockSet)
{
Database db = blockId.Database;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
BlockReference blockRef = trans.GetObject(blockId, OpenMode.ForWrite) as BlockReference;
brot = blockRef.Rotation;
xscale = blockRef.ScaleFactors.X;
yscale = blockRef.ScaleFactors.Y;
if (brot != 0)
{
blockRef.Rotation = 0;
}
if (xscale != 1)
{
blockRef.ScaleFactors = scale1;
}
DynamicBlockReferencePropertyCollection properties = blockRef.DynamicBlockReferencePropertyCollection;
foreach (DynamicBlockReferenceProperty property in properties)
{
// have you created the direction property in the dynamic block???
if (property.PropertyName == "Direction")
{
if (xscale < 0)
{
brot += Math.PI; //adds 180 degrees to "Direction"
}
property.Value = (double)property.Value + brot;
}
}
trans.Commit();
}
}
Autodesk.AutoCAD.Internal.Utils.SelectObjects(blockSetArray);
}
Can't find what you're looking for? Ask the community or share your knowledge.