An Issue with Regions

A problem has found me with creating Regions, probably the first one that has come up with accessing Autocad COM objects from Visual Studio VB.Net. There is probably a fix, but for the time the workaround lets me go on. It involves arrays of autocad objects. It is not a general problem that involves all arrays of autocad object types, just the problem visual studio is having reading the output of Addregion. I will document it here including the similar but fixable problem of output of arrays of visual studio data types.

The fixable problem is like this –

sample VBA code from autodesk to create polylines (with intermediate steps removed)

Dim pline2DObj As AcadLWPolyline
Dim get2Dpts As Variant
get2Dpts = pline2DObj.Coordinates

on paste, visual studio informs
‘Variant is no longer a supported type; use the ‘Object’ type instead.

changing get2Dpts to Object does return to the variable without error. At edit time, Visual Studio is recognizing a generic object not an array coming out of the Coordinate property.

Dim get2Dpts As Object

but generates the error if an attempt is made to read the variable
get2Dpts(0)
Option Strict On disallows late binding.

but at runtime, in the immediate window,
? typename(get2dpts)
“Double()”
? typename(get2dpts(0))
“Double”

so visual studio recognizes the returned object as an array of doubles during execution but not before. Turning Option Strict Off (My Project, Compile tab) solves the problem but i have learned a lot about how variables work with it on and dont accept that as a real solution.

more to the point change the variable declaration to an array of doubles.

Dim get2Dpts() As Double

now we get the error at

get2Dpts = pline2DObj.Coordinates
Option Strict On disallows implicit conversions from ‘Object’ to ‘Double()’.

we can fix that and we are done (and the immediate window returns the same object types as before).

get2Dpts = CType(pline2DObj.Coordinates, Double())

now for the currently unfixable problem involving an array of autocad objects instead of an array of doubles –
lets navigate to the autodesk ActiveX Reference Guide and paste in the Sub Example_AddRegion, make the usual fixes and hook up autocad,

    Sub Example_AddRegion()
        ' creates a region from an arc and a line.
        Connect_acad()

        Dim curves(1) As AcadEntity
        Dim centerPoint(2) As Double
        Dim radius, startAngle, endAngle As Double

        centerPoint(0) = 5.0# : centerPoint(1) = 3.0# : centerPoint(2) = 0#
        radius = 2.0#
        startAngle = 0
        endAngle = 3.141592
        curves(0) = acadDoc.ModelSpace.AddArc(centerPoint, radius, startAngle, endAngle)

        ' Define the line
        curves(1) = acadDoc.ModelSpace.AddLine(curves(0).startPoint, curves(0).endPoint)

        ' Create the region
        Dim regionObj As Variant
        regionObj = acadDoc.ModelSpace.AddRegion(curves)
        acadApp.ZoomAll()
    End Sub

Besides the expected Variant problem, i get an error on AddArc return but not AddLine.

Option Strict On disallows implicit conversions from ‘AcadArc’ to ‘AcadEntity’.

fix with

curves(0) = CType(acadDoc.ModelSpace.AddArc(centerPoint, radius, startAngle, endAngle), AcadEntity)

and now the error goes down to addline, fix the same way, except it still does not like the array indexed inside the Addline parameter list.

curves(1) = CType(acadDoc.ModelSpace.AddLine(curves(0).startPoint, curves(0).endPoint), AcadEntity)

i could probably nest two more CTYPE inside, but lets back up and simplify.

       Dim arcobj As AcadArc
        arcobj = acadDoc.ModelSpace.AddArc(centerPoint, radius, startAngle, endAngle)

        Dim lineobj As AcadLine
        lineobj = acadDoc.ModelSpace.AddLine(arcobj.StartPoint, arcobj.EndPoint)

        curves(0) = CType(arcobj, AcadEntity)
        curves(1) = CType(lineobj, AcadEntity)

now the errors are reduced to the variant where AddRegion returns an array of region objects. I cannot solve this at present.

first move

Dim regionObj() As AcadRegion
regionObj = acadDoc.ModelSpace.AddRegion(curves)

this gives the expected error –
Option Strict On disallows implicit convsersions from ‘Object’ to ‘AcadRegion()’.

based on the experience with the Coordinate property of Polyline returning an array of doubles, this should work,

Dim regionobj() As AcadRegion
regionobj = CType(acadDoc.ModelSpace.AddRegion(curves), AcadRegion())

but it errors out at Ctype AFTER it creates the Region, it cannot pass the array of Regions to the object. the error is –

System.InvalidCaseException: ‘Unable to cast object of type ‘System.Object[]’ to type ‘Autocad.AcadRegion[]’.’

Lets change the Dim statement to Object. We get no errors and a successful run,
Dim regionObj As Object
regionObj = acadDoc.ModelSpace.AddRegion(curves)

but we are not accessing the returned variable. any attempt to use properties of a region fail at the intellisense level, there are no properties other than a few generic object properties.

does not happen – regionobj.EntityTransparency = “50”

in runtime at the immediate window –

? typename(regionobj)
“Object()”
?typename(regionobj(0))
“IAcadRegion”

compare to

? typename(get2dpts)
“Double()”
? typename(get2dpts(0))
“Double”

this doesnt help, i still get ‘unable to cast’ exception
Dim regionobj() As IAcadRegion
regionObj = CType(acadDoc.ModelSpace.AddRegion(curves), IAcadRegion())

visual studio only recognizes an array of primitive objects coming out of addregion. I have tried various ways to read the array into an autocad variable and failed.
the workaround is to create the region but not capture it to a variable. use a subroutine to create a new selection set, get the last item in the drawing, read that into a proper variable.

        Dim regionobj As AcadRegion
        acadDoc.ModelSpace.AddRegion(curves)

        Dim ss As AcadSelectionSet
        ss = Add_ss("newss")
        ss.Select(AcSelect.acSelectionSetLast)

        regionobj = CType(ss.Item(0), AcadRegion)
        regionobj.EntityTransparency = "50"

at edit, visual studio recognizes an object coming out of Coordinates property, but at runtime it recognizes the object is actually an array of doubles, and its able to cast the object to an array of doubles at edit.

at edit, visual studio recognizes an object coming out of AddRegion, but at runtime it recognizes the object as an array of objects, and its not able to cast the object to an array of AcadRegions at edit.

thats it. i can not say now there are no problems or how wide it is. its a possibility i did not hit the right combination of keys, or the solution may be some kind of library link to give visual studio enough information to handle the output of addregion.

    Sub Example_AddRegion()
        ' creates a region from an arc and a line.
        Connect_acad()

        Dim curves(1) As AcadEntity
        Dim centerPoint(2) As Double
        Dim radius, startAngle, endAngle As Double

        centerPoint(0) = 5.0# : centerPoint(1) = 3.0# : centerPoint(2) = 0#
        radius = 2.0#
        startAngle = 0
        endAngle = 3.141592

        Dim arcobj As AcadArc
        arcobj = acadDoc.ModelSpace.AddArc(centerPoint, radius, startAngle, endAngle)

        Dim lineobj As AcadLine
        lineobj = acadDoc.ModelSpace.AddLine(arcobj.StartPoint, arcobj.EndPoint)

        curves(0) = CType(arcobj, AcadEntity)
        curves(1) = CType(lineobj, AcadEntity)

        Dim regionobj As AcadRegion
        acadDoc.ModelSpace.AddRegion(curves)

        Dim ss As AcadSelectionSet
        ss = Add_ss("newss")
        ss.Select(AcSelect.acSelectionSetLast)

        regionobj = CType(ss.Item(0), AcadRegion)
        regionobj.EntityTransparency = "50"

        acadApp.ZoomAll()
    End Sub

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.