Message 1 of 11
Selection Set with relational filter
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I cannot create a selection set with a relational filter as such:
Private Sub CConvStart()
Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
Dim values() As TypedValue = { _
New TypedValue(-4, "
New TypedValue(DxfCode.Start, "LWPOLYLINE"), _
New TypedValue(DxfCode.Int16, 1), _
New TypedValue(-4, "AND>"), _
New TypedValue(-4, "
New TypedValue(DxfCode.LayerName, "Layer1"), _
New TypedValue(DxfCode.LayerName, "Layer2"), _
New TypedValue(DxfCode.LayerName, "Layer3"), _
New TypedValue(-4, "OR>") _
}
Dim sfilter As New SelectionFilter(values) ' Create the filter using our values...
'Set the selection options
Dim SelOpts As New PromptSelectionOptions
SelOpts.Keywords.Add("Options")
SelOpts.MessageForAdding = "Select Items to be Processed:"
SelOpts.AllowDuplicates = False
'Make the selection:
Try
Dim res As PromptSelectionResult = ed.GetSelection(SelOpts, sfilter)
Select Case res.Status
Case PromptStatus.OK
Dim SS As Autodesk.AutoCAD.EditorInput.SelectionSet = res.Value
Dim idarray As ObjectId() = SS.GetObjectIds()
Dim db As Database = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database
Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = db.TransactionManager
'start a transaction
Dim myT As Transaction = tm.StartTransaction()
Try
Dim id As ObjectId
For Each id In idarray
Dim dbObj As DBObject = tm.GetObject(id, OpenMode.ForRead, True)
If TypeOf dbObj Is Entity Then
Dim entity As Entity = CType(dbObj, Entity)
ed.WriteMessage((ControlChars.Lf + "You selected: " + entity.GetType().FullName))
End If
Next id
Finally
myT.Dispose()
End Try
Case PromptStatus.Keyword
MsgBox(res.ToString)
Return
Case Else
'Cancelled
Return
End Select
Catch ex As Exception
Return
End Try
End Sub
This will cause an error when the function "ed.GetSelection(SelOpts, sfilter)" is called. The stack trace is:
{System.FormatException}
[System.FormatException]: {System.FormatException}
HelpLink: Nothing
InnerException: Nothing
Message: "Input string was not in a correct format."
Source: "mscorlib"
StackTrace: " at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Int32.Parse(String s, NumberStyles style, IFormatProvider provider)
at System.Convert.ToInt32(String value, IFormatProvider provider)
at System.String.System.IConvertible.ToInt32(IFormatProvider provider)
at System.Convert.ToInt32(Object value, IFormatProvider provider)
at Autodesk.AutoCAD.DatabaseServices.ResultBuffer.TypedValueToResbuf(TypedValue value)
at Autodesk.AutoCAD.DatabaseServices.ResultBuffer..ctor(TypedValue[] values)
at Autodesk.AutoCAD.EditorInput.FilterExtractor.__ctor(FilterExtractor* , SelectionFilter filter)
at Autodesk.AutoCAD.EditorInput.PromptSelectionOptions.Select(SelectionFilter filter)
at Autodesk.AutoCAD.EditorInput.Editor.GetSelection(PromptSelectionOptions options, SelectionFilter filter)
Using reflection, I have walked up the call stack and found the function "TypedValueToResbuf(ByVal value As TypedValue) As resbuf*" which is called from "public unsafe ResultBuffer(params TypedValue[] values)" to be the location of hte fault:
internal static unsafe resbuf* TypedValueToResbuf(TypedValue value)
{
int num1 = value.m_typeCode;
object obj1 = value.m_value;
CultureInfo info1 = CultureInfo.InvariantCulture;
switch (?acdbGroupCodeToType@@$$FYA?AW4DwgDataType@AcDb@@F@Z((short) num1))
{
case 0:
{
return null;
}
case 1:
{
double num6 = Convert.ToDouble(obj1, info1);
resbuf* resbufPtr9 = acutNewRb(num1);
resbufPtr9[8] = (resbuf) num6;
return resbufPtr9;
}
case 2:
{
int num5 = Convert.ToInt32(obj1, info1);
resbuf* resbufPtr8 = acutNewRb(num1);
*(((int*) (resbufPtr8 + 8))) = num5;
return resbufPtr8;
}
case 3:
{
short num4 = Convert.ToInt16(obj1, info1);
resbuf* resbufPtr7 = acutNewRb(num1);
*(((short*) (resbufPtr7 + 8))) = num4;
return resbufPtr7;
}
case 4:
{
byte num3 = Convert.ToByte(obj1, info1);
resbuf* resbufPtr6 = acutNewRb(num1);
*(((short*) (resbufPtr6 + 8))) = num3;
return resbufPtr6;
}
case 5:
{
sbyte modopt(NoSignSpecifiedModifier)* localPtr1;
StringToCIF ocif1;
StringToCIF* ocifPtr1 = StringToCIF.__ctor((StringToCIF* modopt(IsConstModifier) modopt(IsConstModifier)) &ocif1, Convert.ToString(obj1, info1));
try
{
?acutNewString@@$$FYA?AW4ErrorStatus@Acad@@PBDAAPAD@Z(*((sbyte modopt(NoSignSpecifiedModifier) modopt(IsConstModifier)**) ocifPtr1), &localPtr1);
}
fault
{
__CxxCallUnwindDtor((void modopt(CallConvThiscall) *(void*)) __unep@??1StringToCIF@@$$FQAE@XZ, (void*) &ocif1);
}
StringToCIF.__dtor((StringToCIF* modopt(IsConstModifier) modopt(IsConstModifier)) &ocif1);
resbuf* resbufPtr5 = acutNewRb(num1);
*(((int*) (resbufPtr5 + 8))) = localPtr1;
return resbufPtr5;
}
case 6:
{
byte[] buffer1 = (byte[]) obj1;
volatile pinned ref byte local1 = buffer1;
resbuf* resbufPtr1 = acutNewRb(num1);
short num2 = Convert.ToInt16(buffer1.Length);
?acutNewBuffer@@$$FYA?AW4ErrorStatus@Acad@@AAPADI@Z((sbyte modopt(NoSignSpecifiedModifier)** modopt(IsCXXReferenceModifier)) (resbufPtr1 + 12), (uint) num2);
*(((short*) (resbufPtr1 + 8))) = num2;
IntPtr ptr1 = Marshal.UnsafeAddrOfPinnedArrayElement(buffer1, 0);
IntPtr ptr2 = ptr1;
memcpy(ptr2.ToPointer(), *(((int*) (resbufPtr1 + 12))), num2);
return resbufPtr1;
}
case 7:
{
AcDbHandle handle1;
Handle handle2 = (Handle) obj1;
resbuf* resbufPtr3 = acutNewRb(num1);
memcpy(&handle2.mValue, &handle1, 8);
AcDbHandle.copyToOldType((AcDbHandle modopt(IsConstModifier)* modopt(IsConstModifier) modopt(IsConstModifier)) &handle1, (byte*) (resbufPtr3 + 8));
return resbufPtr3;
}
case 8:
case 9:
case 10:
case 11:
{
ObjectId id1 = (ObjectId) obj1;
resbuf* resbufPtr4 = acutNewRb(num1);
Interop.Check(?acdbGetAdsName@@$$FYA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z(($ArrayType$0x41fa7b4e* modopt(IsCXXReferenceModifier)) (resbufPtr4 + 8), *((AcDbObjectId*) &id1)));
return resbufPtr4;
}
case 12:
{
Point3d pointd1 = (Point3d) obj1;
resbuf* resbufPtr2 = acutNewRb(num1);
memcpy(&pointd1, (resbufPtr2 + 8), 0x18);
return resbufPtr2;
}
}
Interop.ThrowExceptionForErrorStatus(0x33);
return null;
}
I can use the selection set calls from interop, but this is not a final solution because I will be generating the interop libraries myself.
So my questions:
1.) What is Autodesk doing to fix this?
2.) Has this issue even been addressed?
I have looked at DOTNETARX, but this resolution still uses the Interop assemblies and the COM function 'SelectOnScreen' which doesn't allow for the Managed Call's "PromptSelectionOptions". It is a workaround, but I would like to see "acdbmgd" fixed.
Private Sub CConvStart()
Dim ed As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
Dim values() As TypedValue = { _
New TypedValue(-4, "
New TypedValue(DxfCode.Int16, 1), _
New TypedValue(-4, "AND>"), _
New TypedValue(-4, "
New TypedValue(DxfCode.LayerName, "Layer2"), _
New TypedValue(DxfCode.LayerName, "Layer3"), _
New TypedValue(-4, "OR>") _
}
Dim sfilter As New SelectionFilter(values) ' Create the filter using our values...
'Set the selection options
Dim SelOpts As New PromptSelectionOptions
SelOpts.Keywords.Add("Options")
SelOpts.MessageForAdding = "Select Items to be Processed:"
SelOpts.AllowDuplicates = False
'Make the selection:
Try
Dim res As PromptSelectionResult = ed.GetSelection(SelOpts, sfilter)
Select Case res.Status
Case PromptStatus.OK
Dim SS As Autodesk.AutoCAD.EditorInput.SelectionSet = res.Value
Dim idarray As ObjectId() = SS.GetObjectIds()
Dim db As Database = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database
Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = db.TransactionManager
'start a transaction
Dim myT As Transaction = tm.StartTransaction()
Try
Dim id As ObjectId
For Each id In idarray
Dim dbObj As DBObject = tm.GetObject(id, OpenMode.ForRead, True)
If TypeOf dbObj Is Entity Then
Dim entity As Entity = CType(dbObj, Entity)
ed.WriteMessage((ControlChars.Lf + "You selected: " + entity.GetType().FullName))
End If
Next id
Finally
myT.Dispose()
End Try
Case PromptStatus.Keyword
MsgBox(res.ToString)
Return
Case Else
'Cancelled
Return
End Select
Catch ex As Exception
Return
End Try
End Sub
This will cause an error when the function "ed.GetSelection(SelOpts, sfilter)" is called. The stack trace is:
{System.FormatException}
[System.FormatException]: {System.FormatException}
HelpLink: Nothing
InnerException: Nothing
Message: "Input string was not in a correct format."
Source: "mscorlib"
StackTrace: " at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Int32.Parse(String s, NumberStyles style, IFormatProvider provider)
at System.Convert.ToInt32(String value, IFormatProvider provider)
at System.String.System.IConvertible.ToInt32(IFormatProvider provider)
at System.Convert.ToInt32(Object value, IFormatProvider provider)
at Autodesk.AutoCAD.DatabaseServices.ResultBuffer.TypedValueToResbuf(TypedValue value)
at Autodesk.AutoCAD.DatabaseServices.ResultBuffer..ctor(TypedValue[] values)
at Autodesk.AutoCAD.EditorInput.FilterExtractor.__ctor(FilterExtractor* , SelectionFilter filter)
at Autodesk.AutoCAD.EditorInput.PromptSelectionOptions.Select(SelectionFilter filter)
at Autodesk.AutoCAD.EditorInput.Editor.GetSelection(PromptSelectionOptions options, SelectionFilter filter)
Using reflection, I have walked up the call stack and found the function "TypedValueToResbuf(ByVal value As TypedValue) As resbuf*" which is called from "public unsafe ResultBuffer(params TypedValue[] values)" to be the location of hte fault:
internal static unsafe resbuf* TypedValueToResbuf(TypedValue value)
{
int num1 = value.m_typeCode;
object obj1 = value.m_value;
CultureInfo info1 = CultureInfo.InvariantCulture;
switch (?acdbGroupCodeToType@@$$FYA?AW4DwgDataType@AcDb@@F@Z((short) num1))
{
case 0:
{
return null;
}
case 1:
{
double num6 = Convert.ToDouble(obj1, info1);
resbuf* resbufPtr9 = acutNewRb(num1);
resbufPtr9[8] = (resbuf) num6;
return resbufPtr9;
}
case 2:
{
int num5 = Convert.ToInt32(obj1, info1);
resbuf* resbufPtr8 = acutNewRb(num1);
*(((int*) (resbufPtr8 + 8))) = num5;
return resbufPtr8;
}
case 3:
{
short num4 = Convert.ToInt16(obj1, info1);
resbuf* resbufPtr7 = acutNewRb(num1);
*(((short*) (resbufPtr7 + 8))) = num4;
return resbufPtr7;
}
case 4:
{
byte num3 = Convert.ToByte(obj1, info1);
resbuf* resbufPtr6 = acutNewRb(num1);
*(((short*) (resbufPtr6 + 8))) = num3;
return resbufPtr6;
}
case 5:
{
sbyte modopt(NoSignSpecifiedModifier)* localPtr1;
StringToCIF ocif1;
StringToCIF* ocifPtr1 = StringToCIF.__ctor((StringToCIF* modopt(IsConstModifier) modopt(IsConstModifier)) &ocif1, Convert.ToString(obj1, info1));
try
{
?acutNewString@@$$FYA?AW4ErrorStatus@Acad@@PBDAAPAD@Z(*((sbyte modopt(NoSignSpecifiedModifier) modopt(IsConstModifier)**) ocifPtr1), &localPtr1);
}
fault
{
__CxxCallUnwindDtor((void modopt(CallConvThiscall) *(void*)) __unep@??1StringToCIF@@$$FQAE@XZ, (void*) &ocif1);
}
StringToCIF.__dtor((StringToCIF* modopt(IsConstModifier) modopt(IsConstModifier)) &ocif1);
resbuf* resbufPtr5 = acutNewRb(num1);
*(((int*) (resbufPtr5 + 8))) = localPtr1;
return resbufPtr5;
}
case 6:
{
byte[] buffer1 = (byte[]) obj1;
volatile pinned ref byte local1 = buffer1;
resbuf* resbufPtr1 = acutNewRb(num1);
short num2 = Convert.ToInt16(buffer1.Length);
?acutNewBuffer@@$$FYA?AW4ErrorStatus@Acad@@AAPADI@Z((sbyte modopt(NoSignSpecifiedModifier)** modopt(IsCXXReferenceModifier)) (resbufPtr1 + 12), (uint) num2);
*(((short*) (resbufPtr1 + 8))) = num2;
IntPtr ptr1 = Marshal.UnsafeAddrOfPinnedArrayElement(buffer1, 0);
IntPtr ptr2 = ptr1;
memcpy(ptr2.ToPointer(), *(((int*) (resbufPtr1 + 12))), num2);
return resbufPtr1;
}
case 7:
{
AcDbHandle handle1;
Handle handle2 = (Handle) obj1;
resbuf* resbufPtr3 = acutNewRb(num1);
memcpy(&handle2.mValue, &handle1, 8);
AcDbHandle.copyToOldType((AcDbHandle modopt(IsConstModifier)* modopt(IsConstModifier) modopt(IsConstModifier)) &handle1, (byte*) (resbufPtr3 + 8));
return resbufPtr3;
}
case 8:
case 9:
case 10:
case 11:
{
ObjectId id1 = (ObjectId) obj1;
resbuf* resbufPtr4 = acutNewRb(num1);
Interop.Check(?acdbGetAdsName@@$$FYA?AW4ErrorStatus@Acad@@AAY01JVAcDbObjectId@@@Z(($ArrayType$0x41fa7b4e* modopt(IsCXXReferenceModifier)) (resbufPtr4 + 8), *((AcDbObjectId*) &id1)));
return resbufPtr4;
}
case 12:
{
Point3d pointd1 = (Point3d) obj1;
resbuf* resbufPtr2 = acutNewRb(num1);
memcpy(&pointd1, (resbufPtr2 + 8), 0x18);
return resbufPtr2;
}
}
Interop.ThrowExceptionForErrorStatus(0x33);
return null;
}
I can use the selection set calls from interop, but this is not a final solution because I will be generating the interop libraries myself.
So my questions:
1.) What is Autodesk doing to fix this?
2.) Has this issue even been addressed?
I have looked at DOTNETARX, but this resolution still uses the Interop assemblies and the COM function 'SelectOnScreen' which doesn't allow for the Managed Call's "PromptSelectionOptions". It is a workaround, but I would like to see "acdbmgd" fixed.