Author Topic: C3D Parcels via API  (Read 5270 times)

0 Members and 1 Guest are viewing this topic.

StefanDidak

  • Guest
C3D Parcels via API
« on: August 04, 2007, 10:25:02 AM »
Hi Guys!

While creating a TreeView that emulates the behavior of the C3D Prospector view I managed to run into a strange situation where exiting C3D leads to ACAD.EXE to stick around as a zombie process. After narrowing it down it seems to be related to Parcels. In fact, anything relating to parcels.

Take the following code:

Code: [Select]
AcadApplication AppAcad = Application.AcadApplication as AcadApplication;
AeccApplication AppLand = AppAcad.GetInterfaceObject("AeccXUiLand.AeccApplication.5.0") as AeccApplication;
AeccDocument doc = AppLand.ActiveDocument as AeccDocument;
int c = doc.Sites.Item(0).Parcels.Count;

If you place this in a test command and load a doc that has a site with one or more parcels you will get a correct count. Nothing wrong there. Except when you quit C3D. Either the process sticks around and doesn't terminate properly or an error pops up saying:

AutoCAD Error Aborting
INTERNAL ERROR: Attempt to access AeccUiBaseServices after shutdown!


Well, I certainly am not accessing anything after shutdown.

Has anyone done anything with .NET and Parcels in C3D? I'm starting to believe there might be a nasty bug lurking around somewhere and very likely not on my end.



Jeff_M

  • King Gator
  • Posts: 4098
  • C3D user & customizer
Re: C3D Parcels via API
« Reply #1 on: August 04, 2007, 12:18:01 PM »
Hi Stefan,
Have you applied the Service Pack for 2008? This is supposed to be one of the things that SP fixed.

*< ten minutes later>*
I just tested this in C3D2008 with SP1 and do not see the problem. So I guess it did get fixed. :-)

Oh, and it wasn't just Parcels. I think it had to do with the LandUI COM.
« Last Edit: August 04, 2007, 12:19:08 PM by Jeff_M »

StefanDidak

  • Guest
Re: C3D Parcels via API
« Reply #2 on: August 04, 2007, 12:24:44 PM »
Wow, thanks for your quick reply, Jeff.

I've been holding off on SP1 because I didn't want to potentially mess up the dev env but I think that perhaps I should. There definitely are other issues I ran into which are similar (assigning an AeccSurface to a TreeNode Tag without setting the tags to NULL on form closure would also cause ACAD.EXE to go zombie). I'll start making a system image and head for SP1. I'll let you know what the results are.

StefanDidak

  • Guest
Re: C3D Parcels via API
« Reply #3 on: August 04, 2007, 02:11:04 PM »
SP1 certainly does prevent the crash-on-exit after accessing Parcels.

It doesn't solve the very un-NET side effect where if you were to assign Corridor objects, Surfaces, etc. to TreeNode tags and the entire form goes out of scope (even with explicit GC), that after exit the ACAD.EXE turns into a zombie process. Doing a Nodes.Clear() on the entire tree when the form closes prevents that but it's clear that the .NET wrappers do leave a lot to be desired when it comes to proper GC and disposal.

Of course the real fun started when SP1 wouldn't install, complaining the version installed was a British version and not accepting either of the two install CD's. Transferring the license to a laptop and doing a clean install of the neutral version and then SP1 solved that little hick-up. It would've been so cool if the two CD's would just be properly labeled! :-)

Jeff_M

  • King Gator
  • Posts: 4098
  • C3D user & customizer
Re: C3D Parcels via API
« Reply #4 on: August 04, 2007, 06:53:17 PM »
Well, sounds like you had an eventful morning then. I'm glad you got it worked out!

T.Willey

  • Needs a day job
  • Posts: 5251
Re: C3D Parcels via API
« Reply #5 on: August 06, 2007, 11:35:09 AM »
It doesn't solve the very un-NET side effect where if you were to assign Corridor objects, Surfaces, etc. to TreeNode tags and the entire form goes out of scope (even with explicit GC), that after exit the ACAD.EXE turns into a zombie process. Doing a Nodes.Clear() on the entire tree when the form closes prevents that but it's clear that the .NET wrappers do leave a lot to be desired when it comes to proper GC and disposal.
I'm just learning .Net (C#), so this may not apply.  In one of my codes I would set the object to the 'tag' of a tree node, but was told by someone more knowledgeable (Tony T. I think) that I should assign the ObjectId to the 'tag' and then just grab the object again when needed.  I wonder if this would solve your problem?   I tried looking for the post to send you there, but I couldn't find it in a quick search.  If I do I will post the link here.

Edit: Found link here.  It starts at the third paragraph down.
« Last Edit: August 06, 2007, 11:38:16 AM by T.Willey »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

StefanDidak

  • Guest
Re: C3D Parcels via API
« Reply #6 on: August 06, 2007, 01:47:25 PM »
Thanks, T! The solution of using the ID's would certainly be one option. I've currently created my own wrappers for the various types I need to have a selection of and basically look them up once they need to be accessed so the problem is mostly solved.

But as far as the .NET API being very un-.NET, that once again became clear today when I wasted quite a few hours trying to change the color of a layer. I've been doing .NET/C# for so long that it's second nature so I naturally expect to change it like;

Code: [Select]
AcadLayer someLayer = AcadDoc.Layers.Add(layerName);
someLayer.Color = etc.

Which would be a common form of architecting .NET style. Of course there's no Color property, only the AcColor based color (no capital C) and changing the color requires a whole transaction with the DB to get the LayerTableRecord in order to change the actual .Color property there.

The API is certainly a .NET interface, but far from a .NET API as I'd consider it. :-)




sinc

  • Guest
Re: C3D Parcels via API
« Reply #7 on: August 08, 2007, 12:15:54 PM »

The API is certainly a .NET interface, but far from a .NET API as I'd consider it. :-)


Amen to that.  There are big areas where the .NET methods even return COM objects or require COM objects as parameters, and there is nothing in the documentation about this fact.  It really threw me for a loop until I figured out how to identify and deal with this.

StefanDidak

  • Guest
Re: C3D Parcels via API
« Reply #8 on: August 09, 2007, 06:28:26 PM »
Not to mention all the fun VARIANT references to "objects" of which no details are provided. Always fun to have to start in debug mode to figure out a certain object is an array of strings or doubles of a certain length. If you really want to have your head spin around try digging into Corridor objects and creating a hierarchical output that provides data which can be used for mesh-based recreation. Ouch, my neck and head still hurt and I'm not even half done with it. :-)

sinc

  • Guest
Re: C3D Parcels via API
« Reply #9 on: August 09, 2007, 06:56:58 PM »
If you really want to have your head spin around try digging into Corridor objects and creating a hierarchical output that provides data which can be used for mesh-based recreation. Ouch, my neck and head still hurt and I'm not even half done with it. :-)

Unfortunately, that sounds like something that's coming up for me.

I have a bunch of survey tools that I want to build, but a key component to them is that they need to be able to query a corridor for the elevation at any station/offset in the corridor.  For complete access, I also want to be able to either get an array of elevations for all links that exist at that point, or pass a link code and have the API filter the results using the link code and the corridor's overhang correction setting.  Ideally, there would be some simple API calls to a Corridor object to do exactly this, since it's basically what C3D does internally in order to build a surface, but that would make things far too simple...   :-(

StefanDidak

  • Guest
Re: C3D Parcels via API
« Reply #10 on: August 09, 2007, 07:12:45 PM »
Unfortunately, that sounds like something that's coming up for me.
What you need to do sounds even worse. I only have to get 'as much' data out of the corridors for export purposes (with a twist since portions of the data need some processing). On the surface a corridor object looks fairly simple but once you get deep into it things start to feel like a maze. It's the naming of classes and properties that end up being very confusing because there's a lot of repetition of words like "baseline", "featureline", "offsetbaseline", etc. which require a lot of nested loops to get to things and it gets confusing when you get to the "FeatureLine objects in the FeatureLinesCol of the BaselineFeatureLines".

erlking

  • Guest
Re: C3D Parcels via API
« Reply #11 on: September 08, 2007, 03:48:20 AM »
The following code can help you:
AppAcad = nothing
AppLand = nothing
doc = nothing

StefanDidak

  • Guest
Re: C3D Parcels via API
« Reply #12 on: September 08, 2007, 03:47:16 PM »
doc = nothing[/color]
I completely agree on doc = nothing.  Or, rather, ApiDocs = Nothing.Much; :-D

Overall I managed to work around all the nasty odds and ends of the API and will be taking a two month vacation so luckily won't have to deal with it for a while. If you ever get into reconstructing corridor meshes from the parametric corridor data you'll probably want a long vacation too! Here's a good example of API horrors: When you've got a Baseline with an intentional gap in the corridor and check it by looking at:
Code: [Select]
b.BaselineRegions.Item(n).AppliedAssemblies.Countyou'll get a nice fat COM exception. So, logically, the next step would be to;
Code: [Select]
if(b.BaselineRegions.Item(n).AppliedAssemblies == null)same exception. COM horror in a .NET jacket... with holes.

Solution; try-catch... clearly the C3D API prefers developers to be sloppy and over-use it all the time. :-)