Announcements

The Autodesk Community Forums has a new look. Read more about what's changed on the Community Announcements board.

Looking for help in creating a Grip Overrule for a specific block

nshupeFMPE3
Advocate

Looking for help in creating a Grip Overrule for a specific block

nshupeFMPE3
Advocate
Advocate

I'm trying to create a grip overrule for a specific type of block and so far I have been running into issues of stack overflowing? I tried to follow this sort of templet while making some changes. 

This is what I have so far

public override bool IsApplicable(RXObject overruledSubject)
        {
            try
            {
                
                if (overruledSubject.GetType() != typeof(BlockReference))
                    return false;
                BlockReference block = overruledSubject as BlockReference;
                return block.IsInstanceOf("Left stretch");//need to make more robust for any panel type

            }
            catch(Autodesk.AutoCAD.Runtime.Exception e)
            {
                return false;
            }
        }

        public override void GetGripPoints(Entity entity, GripDataCollection grips, double curViewUnitSize, int gripSize, Vector3d curViewDir, GetGripPointsFlags bitFlags)
        {
            try
            {
                base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags);
                GripDataCollection borderGrips = ComputeBorderGrips(entity);
                foreach(var t in borderGrips) grips.Add(t);
                
            }
            catch(Exception e)
            {
                base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags);
            }
        }

 

I seem to get stuck in a loop at line 22 where I call base.GetGripPoints(). It then goes to IsApplicable() and loops until a stackoverflow occurs. 

Any help would be greatly appreciated. 

0 Likes
Reply
Accepted solutions (1)
673 Views
6 Replies
Replies (6)

norman.yuan
Mentor
Mentor

You might want to show the code detail of the method

 

BlockReference.IsInstanceOf(string)

 

The other trick you might want to try is to place the IsInstanceOf(string) method call inside the overridden GetGripPoints(), assume IsInstanceOf() does its work correctly:

 

        public override void GetGripPoints(Entity entity, GripDataCollection grips, double curViewUnitSize, int gripSize, Vector3d curViewDir, GetGripPointsFlags bitFlags)
        {
            try
            {
                var blk=entity as BlockReference;
                if (blk != null && blk.IsInstanceOf("xxxxx))
                {
                  // Calculate and add your custom grip here
                }
            }
            finally
            {
                base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags);
            }
        }

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes

nshupeFMPE3
Advocate
Advocate

I was thinking about moving the IsInstanceOf() call to inside GetGrips() but I figured I would like to rule out blocks as soon as possible if they are not an instance of the desired block. 

Here is the code for IsInstanceOf()

public static bool IsInstanceOf(this BlockReference block, string blockName)
        {
            bool answer = false;

            using(Transaction tr = block.Database.TransactionManager.StartOpenCloseTransaction())
            {
                ObjectId btrId = block.IsDynamicBlock ? block.DynamicBlockTableRecord : block.BlockTableRecord;
                var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                answer = Autodesk.AutoCAD.Internal.Utils.WcMatchEx(btr.Name, blockName, true);
                btr.Dispose();
            }
            return answer;
        }

 

0 Likes

norman.yuan
Mentor
Mentor

I assume you did, but ask anyway: did you call Overrule.SetCustomFilter()?

 

Just for the sake of debugging, can you simply make sure your drawing only has a static block reference and you can hard-code its name in the IsInstabceOf() to prove it absolutely works correctly.

 

For the GripOverrule, since it will only take effect when the overruled entity or entities is/are selected, I think, behind of the scene AutoCAD always call GetGripPoints() first and then, based on the overrule filter configuration, does the filtering work (e.g. call IsApplicable() if SetCustomFilter() was called when the overrule is enabled). So, for GripOverrule, I'd think, we can simply ignore the filtering stuff at Overrule level (e.g. not set up any kind of filter) and do our own filtering directly in the GetGripPoints() method.

 

So, at least for the purpose of debugging, you can try to remove filtering from Overrule level and do it directly in the GetGripPoints() as my previous reply suggested. See what happens.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes

nshupeFMPE3
Advocate
Advocate
I did do Overrule.SetCustomFilter() you are correct.
Thank you Norman, I will try your suggestion and report any change.
0 Likes

nshupeFMPE3
Advocate
Advocate
Accepted solution

@norman.yuan looks like I made a mistake and was adding the event handler for the overrule over and over again which I think was causing most my problems. I also moved the block InstanceOf() check like we discussed and I am getting what I was looking for! 

Thanks again!

0 Likes

nshupeFMPE3
Advocate
Advocate

It turns out it also works to check in IsApplicable() if the block is the correct type, which saves you from having to repeat yourself in your overriding multiple methods ie MoveGripPointAt(), GetGripPoints(), etc

0 Likes