.NET

Reply
Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 11 of 24 (325 Views)

Re: overrule is really confusing ....

09-07-2012 03:47 PM in reply to: JanetDavidson

Yes, I am he.

 

Sure, if you post a .cs file that compiles without errors I'll try it.

Distinguished Contributor
JanetDavidson
Posts: 139
Registered: ‎08-23-2011
Message 12 of 24 (299 Views)

Re: overrule is really confusing ....

09-08-2012 10:40 PM in reply to: DiningPhilosopher

Hello Again DP.

After 14 hours struggling I finally converted it to C#. Now behavior is completely different. Before in VB I just had crash

on Distance Command. Now I have crash whenever I snap to block. I really hope and beg for your help Tony.

I know you always have a trick in your sleeve.

:womanwink:

Thanks

Janet

 P.S. I renamed file  extension to .txt , website  doens't allow extension .cs to be uploaded.

 

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 13 of 24 (295 Views)

Re: overrule is really confusing ....

09-09-2012 12:03 AM in reply to: JanetDavidson

Hi Janet.

 

Before I even look at that code, I would ask that you fix the obvious bug and try it again.

 

The bug I'm referring to is the line shown in red below (I renamed the function from Go_Get_blahblahblah...). In that line of code, you're creating a new Line object, but not doing anything with it, and not disposing it, which will probably crash AutoCAD.

 

public static bool GetExplodedEnts( BlockReference myBlock, ref List<Entity> ListEnts )
{
   DBObjectCollection MyDBObjColl = new DBObjectCollection();
   {
      myBlock.Explode( MyDBObjColl );
      Line Line1 = new Line();
      foreach( DBObject mydbobj in MyDBObjColl )
      {
         if( mydbobj is Line )
         {
            Line1 = mydbobj as Line;
            Autodesk.AutoCAD.DatabaseServices.Polyline MyPolyLine1 = new Autodesk.AutoCAD.DatabaseServices.Polyline();
            MyPolyLine1.SetDatabaseDefaults();
            MyPolyLine1.AddVertexAt( 0, new Point2d( Line1.StartPoint.X, Line1.StartPoint.Y ), 0, 200, 200 );
            MyPolyLine1.AddVertexAt( 1, new Point2d( Line1.EndPoint.X + 3000, Line1.EndPoint.Y + 3000 ), 0, 200, 200 );
            MyPolyLine1.Closed = true;
            ListEnts.Add( MyPolyLine1 );
         }
         else
         {
            mydbobj.Dispose();
         }
      }
   }
   return true;
}

 That bug is almost certain to crash AutoCAD.

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 14 of 24 (283 Views)

Re: overrule is really confusing ....

09-09-2012 05:42 AM in reply to: JanetDavidson

Hi Janet - There's a few more problems with the code you posted, and they are also in the original VB code as well. 

 

First, have a look at the documentation for AcGiDrawable::worldDraw() (In the native ObjectARX docs) and make note of what the return value means. Why does your WorldDraw() return false?

 

public override bool WorldDraw( Drawable drawable, WorldDraw Wd )
{
   BlockReference myBlock = drawable as BlockReference;
   if( ( myBlock.Database != null ) )
   {
      List<Entity> ListEnts = new List<Entity>();
      if( !GetExplodedEnts( myBlock, ListEnts ) )
      {
         return false;
      }
      foreach( Entity Ent in ListEnts )
      {
         Ent.WorldDraw( Wd );
         Ent.Dispose();
      }
   }
   // base.WorldDraw(drawable, Wd);
   return true;
}

Next, your Go_Get_Overruled_exploded_entities_from_this_block() method misuses Try/Catch, by catching any exception that's raised, and without regards for what the exception is or what caused it, your method simply returns False. That's kind of like saying 'I don't care what went wrong, I just want it to work', but it will never work until you find out what went wrong, which that kind of mis-use of Try/Catch prevents. If there's no exception, then that same method always returns True, regardless of whether it added anything to the list or not, which is also not correct.

 

Lastly, your GetObjectSnapPoints() overload uses Try/Catch with an empty catch block :manmad:. That's the same as using On Error Resume Next in VBA, and is something you should never do, because it simply hides exceptions from you, making it nearly impossible to debug your code. When you are writing/testing/debugging code, you can put a statement in an otherwise-empty Catch block that displays the exception that was caught, but you should never use Try/Catch with an empty catch block in production code, without being completely sure what exception will be caught.

 

So, as it stands your code has quite a few problems that you need to fix before I would try to run it,.

Distinguished Contributor
JanetDavidson
Posts: 139
Registered: ‎08-23-2011
Message 15 of 24 (277 Views)

Re: overrule is really confusing ....

09-09-2012 08:08 AM in reply to: DiningPhilosopher

Hello  DP, I really appreciate all these time you spent for teaching me(us). What you are doing here for us is like a father doing for their kids. I am/was you fan alwasy.

I did what you asked and thanks for tips. I had all those catches in my original code but they never been hit. I just removed them from this sample code to make it shorter. I put them back but they never been catch.

Regard with New LIne. You are winner . I forgot it totally. But still doesn't change anything.

I checked document and this is what it says :

 

A return value of Adesk::kFalse indicates that the 3D GS must
call viewportDraw() in order to obtain the complete geometry
and attribute set for this drawable.

 

Frankly, don't understand it . But I changed it to True as you mentioned . Nothing changed.

By the way If you want to yell at me . It is OK. I know you yell to make students learn better. I am ready.

( Reminds me those Chinese KungFu movies when the master kicks  student :womanlol: )

 

So HELP

Janet.

 

 

 

Valued Mentor
jeff
Posts: 330
Registered: ‎05-12-2009
Message 16 of 24 (258 Views)

Re: overrule is really confusing ....

09-09-2012 01:50 PM in reply to: JanetDavidson

Hi Janet,

 

I only looked quickly but a IntPtr has a method ToInt32().

Not sure you can use Convert.ToInt32(gsSelectionMark) try gsSelectionMark.ToInt32() instead.

 

 

You can also find your answers @ TheSwamp
Distinguished Contributor
JanetDavidson
Posts: 139
Registered: ‎08-23-2011
Message 17 of 24 (243 Views)

Re: overrule is really confusing ....

09-09-2012 06:12 PM in reply to: jeff

Jeff,

Thanks. After I applied your advice now it acts like my VB version.

Thanks for your time to look into my problem .Still when I do a distance command it crashes.

Tony is on this as well .We are lucky. Huh!

Cheers,

Janet.

 

 

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 18 of 24 (236 Views)

Re: overrule is really confusing ....

09-09-2012 06:54 PM in reply to: JanetDavidson

Jeff already dropped a hint about what the problem is, but I think it's better for you to learn how to find the problem yourself. So, I'll try to show you how to to do that.

One major problem with developing AutoCAD plugins in .NET is that AutoCAD does not always catch exceptions that are thrown by managed code when the managed code is called from lower-level native APIs, overrules being one such case. So, to find out if AutoCAD is crashing as a result of an exception being raised by your overridden overrule methods, you need to wrap them in a try/catch block, and display a message in the catch block, like this:

 

public override void GetObjectSnapPoints( Entity e, ObjectSnapModes snapMode, System.IntPtr gsSelectionMark, 
            Point3d pickPoint, Point3d lastPoint, Matrix3d viewTransform, Point3dCollection snapPoints, 
            IntegerCollection geometryIds, Matrix3d insertionMat )
{
   try
   {
      BlockReference myBlock = e as BlockReference;
      List<Entity> ListEnts = new List<Entity>();
      if( !toverrule.GetExplodedEnts( myBlock, ListEnts ) )
      {
         return;
      }
      foreach( Entity SubEnt in ListEnts )
      {
         SubEnt.GetObjectSnapPoints( snapMode, gsSelectionMark.ToInt32(), pickPoint, lastPoint, viewTransform, snapPoints, geometryIds, insertionMat );
         SubEnt.Dispose();
      }
   }
   catch( System.Exception ex )
   {
      Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage( 
         "\n****** Exception: {0}\n\n\n", ex.ToString() 
      );
   }
}

// The same method, except using the try/catch diagnostics in debug builds only:

public override void GetObjectSnapPoints( Entity e, ObjectSnapModes snapMode, System.IntPtr gsSelectionMark, Point3d pickPoint, 
               Point3d lastPoint, Matrix3d viewTransform, Point3dCollection snapPoints, 
               IntegerCollection geometryIds, Matrix3d insertionMat )
{
#if DEBUG
   try
   {
#endif
      BlockReference myBlock = e as BlockReference;
      List<Entity> ListEnts = new List<Entity>();
      if( !toverrule.GetExplodedEnts( myBlock, ListEnts ) )
      {
         return;
      }
      foreach( Entity SubEnt in ListEnts )
      {
         SubEnt.GetObjectSnapPoints( snapMode, gsSelectionMark.ToInt32(), pickPoint, lastPoint, viewTransform, snapPoints, geometryIds, insertionMat );
         SubEnt.Dispose();
      }
#if DEBUG
   }
   catch( System.Exception ex )
   {
      Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage( 
            "\n****** Exception: {0}\n\n\n", ex.ToString() 
      );
   }
#endif
}

 

If you replace your GetOsnapPoints() override with one of the two shown above, then you will see why your code is crashing. Jeff already suggested the remedy, so I'll leave the rest to you.

 

Distinguished Contributor
JanetDavidson
Posts: 139
Registered: ‎08-23-2011
Message 19 of 24 (227 Views)

Re: overrule is really confusing ....

09-09-2012 08:57 PM in reply to: DiningPhilosopher

Tony, Thank you again for your time. VB version had only Distance Command problem. That is why I continued this thread and asked for help ,when I converted it to C# for your consideration the new bug happened ( because of my low experience in c# ,  and Jeff remedy put it back to  state, which Distance command crashes the program ,now it behaves  like VB version.

 

I used your suggested Function to see, if it shows the reason it crashes, when we do distance command , but still it doesn't show what is the problem is . You can try it , use the block,submitted  and apply overule and try to make a distance between two  new thick polylines.

 

originally in my code had a [ ref ] for ListEnts, which in your revised version it was removed.

 Below is what I had originally

if (!toverrule.GetExplodedEnts(myBlock,ref ListEnts))

and this is your revised one

if (!toverrule.GetExplodedEnts(myBlock,ref ListEnts))

 

I had to put ref back to make the code work properly

 

Attached please find latest version including  your funciton and Jeff remedy. But still crashes on Distance command between two overruled Polylines, and doesn't show what the reason is.

 

Thanks

Janet.

 

 

 

Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 20 of 24 (213 Views)

Re: overrule is really confusing ....

09-09-2012 11:16 PM in reply to: JanetDavidson

HI Janet. 

 

You'll need to provide some details on your config where the code crashes.

 

First, what release of AutoCAD are you using?

 

Second, what running osnap modes are set, and if you're using immediate osnap, which ones are they for the first and second points?

Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.