Fatal Error when using Solid3d.GetSection

Fatal Error when using Solid3d.GetSection

zputman
Explorer Explorer
1,354 Views
6 Replies
Message 1 of 7

Fatal Error when using Solid3d.GetSection

zputman
Explorer
Explorer

When using the Solid3d.GetSection method with a plane that doesn't intersect the solid or only intersects the solid at a point or line, I get a Region object that throws System.AccessViolationException on most of its properties.  The documentation says I should get null.

 

Anyone else getting this?  Is there a way of testing the Region object that doesn't throw the exception (which needs extra measures to catch because it is a Corrupted State Exception)?  The Region.IsNull property also throws the exception, so no go there...

 

Meanwhile, I have worked around this by offsetting the plane slightly into the solid and checking the bounds of the solid before trying the method.  These countermeasures break however if the solid has gaps, is small, doesn't line up with the coordinate system, etc...

 

Forgot to mention: I am using AutoCAD 2016

0 Likes
Accepted solutions (1)
1,355 Views
6 Replies
Replies (6)
Message 2 of 7

ActivistInvestor
Mentor
Mentor

@zputman wrote:

When using the Solid3d.GetSection method with a plane that doesn't intersect the solid or only intersects the solid at a point or line, I get a Region object that throws System.AccessViolationException on most of its properties.  The documentation says I should get null.

 

Anyone else getting this?  Is there a way of testing the Region object that doesn't throw the exception (which needs extra measures to catch because it is a Corrupted State Exception)?  The Region.IsNull property also throws the exception, so no go there...

 

Meanwhile, I have worked around this by offsetting the plane slightly into the solid and checking the bounds of the solid before trying the method.  These countermeasures break however if the solid has gaps, is small, doesn't line up with the coordinate system, etc...

 

Forgot to mention: I am using AutoCAD 2016


According to the native docs for AcDb3dSolid::getSection():

  

If the solid has no ShapeManager object, or the plane doesn't intersect the solid, or the intersection is not a valid region (for example, it intersects at a point, along a bounding face of the solid, and so on), then sectionRegion will be set to NULL and Acad::eOk will be returned.

 

According to what I see in the disassembly for the Solid3d.GetSection() method, the only thing it does is check the errorstatus returned by AcDb3dSolid::getSection(), and doesn't bother checking to see if the pointer to the AcDbRegion is NULL, and just returns a managed wrapper with a null pointer to an unmanaged object.

 

I don't know if we can call that a bug or not, but it seems that it could have been handled better (e.g, throw an exception if an AcDbRegion wasn't created).

 

In any case, this should tell you what you need to know:

 

 

Region region = solid3d.GetSection(....)

if(region.UnmanagedObject != IntPtr.Zero)
{
   // Got a valid region.
}
else
{
    // something went wrong.
}

 

 

 

Message 3 of 7

FRFR1426
Collaborator
Collaborator

I had the same problem with Solid3d.Slice() which is similar to Solid3d.Section() in a recent project. I ended up to call the SLICE command with Editor.Command() this way:

 

ed.Command(
   "_SLICE", 
  solid3dId, 
  "", 
  "_S", // Surface
 surfaceId,
  "_B" // (keep Both solids). We cannot select the side, so we keep both
);

You can do the same with the SECTION command and the 3 points option. To get the region which will be may be created, you can put an handler on the Database.ObjectAppended event before calling the command and remove it after.

 

The problem with the Solid3d method is that if the slice/section fails, AutoCAD  crashes soon after. But may be it was because I've not think to the clever way of testing if the object is valid proposed by @ActivistInvestor

Maxence DELANNOY
Manager
Add-ins development for Autodesk software products
http://wiip.fr
Message 4 of 7

zputman
Explorer
Explorer

@Activist_Investor wrote:

@zputman wrote:

When using the Solid3d.GetSection method with a plane that doesn't intersect the solid or only intersects the solid at a point or line, I get a Region object that throws System.AccessViolationException on most of its properties.  The documentation says I should get null.

 

Anyone else getting this?  Is there a way of testing the Region object that doesn't throw the exception (which needs extra measures to catch because it is a Corrupted State Exception)?  The Region.IsNull property also throws the exception, so no go there...

 

Meanwhile, I have worked around this by offsetting the plane slightly into the solid and checking the bounds of the solid before trying the method.  These countermeasures break however if the solid has gaps, is small, doesn't line up with the coordinate system, etc...

 

Forgot to mention: I am using AutoCAD 2016


According to the native docs for AcDb3dSolid::getSection():

  

If the solid has no ShapeManager object, or the plane doesn't intersect the solid, or the intersection is not a valid region (for example, it intersects at a point, along a bounding face of the solid, and so on), then sectionRegion will be set to NULL and Acad::eOk will be returned.

 

According to what I see in the disassembly for the Solid3d.GetSection() method, the only thing it does is check the errorstatus returned by AcDb3dSolid::getSection(), and doesn't bother checking to see if the pointer to the AcDbRegion is NULL, and just returns a managed wrapper with a null pointer to an unmanaged object.

 

I don't know if we can call that a bug or not, but it seems that it could have been handled better (e.g, throw an exception if an AcDbRegion wasn't created).

 

In any case, this should tell you what you need to know:

 

 

Region region = solid3d.GetSection(....)

if(region.UnmanagedObject != IntPtr.Zero)
{
   // Got a valid region.
}
else
{
    // something went wrong.
}

 

 

 


I tried this and the Region.UnmanagedObject is not zero for me and it still has the AccessViolationExceptions and it crashes AutoCAD.

0 Likes
Message 5 of 7

Alexander.Rivilis
Mentor
Mentor
Accepted solution

@zputman wrote:
... Forgot to mention: I am using AutoCAD 2016 ...

This bug was fixed in AutoCAD 2017.  With AutoCAD 2017 in this situation exception eNoIntersections is thrown:

 

0_1517d2_61cce49b_orig.png

 

In AutoCAD 2016 as workaround you can use Section.GenerateSectionGeometry. Example: http://through-the-interface.typepad.com/through_the_interface/2008/05/sectioning-an-a.html 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 6 of 7

ActivistInvestor
Mentor
Mentor

@zputman wrote:

 

 


I tried this and the Region.UnmanagedObject is not zero for me and it still has the AccessViolationExceptions and it crashes AutoCAD.


That's a different bug altogether.  According to the code I saw, and the simple test I did, GetRegions() tried to create a managed wrapper for a Region, and that failed (the managed runtime doesn't allow it), so that isn't the problem. In your case, it is returning something, but it's not usable

Message 7 of 7

zputman
Explorer
Explorer

The section I was looking at was probably touching the solid at a point, so maybe that is why it returned an unusable region instead of a wrapper around a null pointer.  It looks like my best options are to upgrade AutoCAD or to use the Section class instead.  For now, I will keep with my countermeasures since they will probably work every time for my current use case and revisit this code when we upgrade so it works more generally.

 

Thanks everyone for your help!

0 Likes