.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Issues with IntersectWith AutoCAD 2010

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
mindofcat
4307 Views, 12 Replies

Issues with IntersectWith AutoCAD 2010

Hi all,

 

I'm developing for AutoCAD 2010 using VS 2010 (compilation platform 3.5), and running ObjectARX 2012.

 

So far, everything has worked for me, up till now. I ran into this intersectWith problem last week while attempting to fillet lines.

I was able to find some viable solutions online for filleting lines, but the problem is, when I compile and execute AutoCAD, I get the System.MissingMethodException: Method not found Autodesk.AutoCAD.DatabaseServices.Entity.IntersectWith error message.

 

I have done some extensive searching on this forum, and the closest I came to a solution for intersectwith was a previous post titled "IntersectWith problem" posted by dynamicscope, where Tony Tanzillo offers a solution for AutoCAD 2010 as a workaround. but when I click on the link http://www.caddzone.com/PlatformUtils.vb there is nothing to download.

 

This IntersectWIth problem seems very difficult right now, so I am hoping that somewhere out there, someone has encountered similar situation, and found a viable solution.

 

My big question is, are there any other alternatives for calculating the intersection point between 2 intersecting lines WITHOUT HAVING TO USE the intersectWith() method in AutoCAD 2010 VB.NET? Something that would still work for me even when my code is run in later versions of AutoCAD?

 

Any help or pointers greatly appreciated.

 

Thanks in advance!

12 REPLIES 12
Message 2 of 13
Hallex
in reply to: mindofcat

Try this code this wil fillet polylines with radius of 50.0

change radius to your needs or define it using GetDistance

or GetDouble

       // use this function
        //[System.Security.SuppressUnmanagedCodeSecurity]
        //[DllImport("acad.exe", BestFitMapping = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        //private static extern int acedCmd(System.IntPtr vlist_in);
        // or this one instead
        //[System.Security.SuppressUnmanagedCodeSecurity]
        //[DllImport("acad.exe", EntryPoint = "acedCmd", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        //extern static private int acedCmd(IntPtr resbuf);
        [CommandMethod("FILET")]// borrowed from fenton.webb
        public static void TestFillet()
        {
            Database db = HostApplicationServices.WorkingDatabase;

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;

            Transaction tr = db.TransactionManager.StartTransaction();

            using (tr)
            {

                try
                {
                    // Prompt for the polyline to fillet

                    PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline:");

                    peo.SetRejectMessage("\nSelect polyline only");

                    peo.AddAllowedClass(typeof(Polyline), true);

                    PromptEntityResult per = ed.GetEntity(peo);

                    if (per.Status != PromptStatus.OK)
                    {
                        return;
                    }

                    ObjectId fid = per.ObjectId;

                    DBObject obj1 = tr.GetObject(fid, OpenMode.ForWrite);

                    Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 0);

                    Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("FILLETRAD", 50.0);// Change fillet radius here

                    ResultBuffer buf = new ResultBuffer();

                    buf.Add(new TypedValue(5005, "_FILLET"));

                    buf.Add(new TypedValue(5005, "_P"));

                    buf.Add(new TypedValue(5006, fid));

                    acedCmd(buf.UnmanagedObject);

                    buf.Dispose();

                    Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 1);

                    tr.Commit();


                }
                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    ed.WriteMessage(ex.Message + "\n" + ex.StackTrace);

                }

            }

        }

 

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 3 of 13
Hallex
in reply to: Hallex

And this one is to fillet lines only

        // use this function
        //[System.Security.SuppressUnmanagedCodeSecurity]
        //[DllImport("acad.exe", BestFitMapping = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        //private static extern int acedCmd(System.IntPtr vlist_in);
        // or this one instead
        //[System.Security.SuppressUnmanagedCodeSecurity]
        //[DllImport("acad.exe", EntryPoint = "acedCmd", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        //extern static private int acedCmd(IntPtr resbuf);
        [CommandMethod("FiLINE")]// borrowed from fenton.webb
        public static void TestFillet()
        {
            Database db = HostApplicationServices.WorkingDatabase;

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;

            Transaction tr = db.TransactionManager.StartTransaction();

            using (tr)
            {

                try
                {
                    // Prompt for the polyline to fillet 2 objects

                    PromptEntityOptions peo = new PromptEntityOptions("\nSelect a first line:");

                    peo.SetRejectMessage("\nSelect line  only");

                    peo.AddAllowedClass(typeof(Line), true);

                    PromptEntityResult per = ed.GetEntity(peo);

                    if (per.Status != PromptStatus.OK)  return;

                    ObjectId fid = per.ObjectId;

                    peo.Message = "\nSelect second line:";

                    per = ed.GetEntity(peo);

                    if (per.Status != PromptStatus.OK)  return;

                    ObjectId snd = per.ObjectId;

                    DBObject obj1 = tr.GetObject(fid, OpenMode.ForWrite);

                    DBObject obj2 = tr.GetObject(snd, OpenMode.ForWrite);

                    Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 0);


                    Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("FILLETRAD", 50.0);// Change fillet radius here

                    ResultBuffer buf = new ResultBuffer();

                    buf.Add(new TypedValue(5005, "_FILLET"));

                   // buf.Add(new TypedValue(5005, "_P"));

                    buf.Add(new TypedValue(5006, fid));

                    buf.Add(new TypedValue(5006, snd));

                    acedCmd(buf.UnmanagedObject);

                    buf.Dispose();

                    Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 1);

                    tr.Commit();


                }
                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    ed.WriteMessage(ex.Message + "\n" + ex.StackTrace);

                }

            }

        }

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 4 of 13

This lame discussion host doesn't allow code source files to be attached to posts, so you can find it here:

 

http://www.theswamp.org/index.php?topic=44392.0

 

 

Message 5 of 13
Radioflyer651
in reply to: mindofcat

When I've had this error message in the past, it's had to do with 64 bit versus 32 bit applications.

 

In particular, my application uses the IntersectWith command, and I have to convert the last two arguments to 64 bit integers.  Use 0L (Zero L) instead of Zero alone.

 

I.E:

Line1.IntersectWith(Line2, Intersect.OnBothOperands, ResultArray, 0L, 0L)

 

I'm not sure if that's going to fix it, but it helped me.

 

Richard

Message 6 of 13
mindofcat
in reply to: Hallex

I am overwhelmed with gratitude at the quick and helpful responses I received on this intersectWIth problem; thanks all.

 

The solution posted by Hallex for filleting lines I have just stored away for future use, when I need to build a fillet functionality for SELECTING lines from user input.

 

However, for now, the line objects I need to fillet are stored in memory as DBObjectCollection, and haven't quite been added to a database transaction yet.

 

I do this because I first construct the lines in memory, then I fillet them, and then I use their coordinates to generate a polyline, including the coordinates of the arc created during the filleting process.

 

I am able to accomplish all of this successfully, ecpect that the filletLines function I am using utilizes the IntersectWIth function which just breaks everything. I paste the code I am using below.

 

To solve this intersectWith problem, I am particularly interested in the PlatformUtils.vb class for the Autodesk.AutoCAD.DatabaseServices namespace by Tony Tanzillo (thanks to DiningPhilosopher for providing the link)

 

What is the best way to implement this vb class so that its IntersectWIth method is the one called when I use the IntersectWIth method on a line?

 

Do I just create the PlatformUtils.vb class in the same project as my other vb classes?

 

Many thanks...

 

NB: Here is my filletLines code:

 

 

' Fillet functionality for this class; the lines must intersect with each other
Public Shared Sub filletLines(ByVal rad As Double, ByVal line1 As Line, _
ByVal line2 As Line)

Try
Dim intpts As New Point3dCollection()
' Get the intersection between lines
line1.IntersectWith(line2, Intersect.OnBothOperands, intpts, 0, 0)

' The lines must intersect with each other
If intpts.Count <> 1 Then Return
Dim ip As Point3d = intpts(0)
Dim midp1, midp2 As Point3d

' Compare points for line1, set the midpoint
If Not (line1.StartPoint.Equals(ip)) Then
line1.EndPoint = line1.StartPoint
line1.StartPoint = ip
End If
midp1 = line1.GetPointAtDist(rad)

' Compare points for line2, set the midpoint
If Not (line2.StartPoint.Equals(ip)) Then
line2.EndPoint = line2.StartPoint
line2.StartPoint = ip
End If
midp2 = line2.GetPointAtDist(rad)

' Get point on bisector
Dim midp As New Point3d((midp1.X + midp2.X) / 2.0, _
(midp1.Y + midp2.Y) / 2.0, (midp1.Z + midp2.Z) / 2.0)

' Get angles along lines from intersection
Dim ang1 As Double = angleFromX(ip, midp1)
Dim ang2 As Double = angleFromX(ip, midp2)

' Get bisector angle and then calculate angle between lines
Dim ang As Double = angleFromX(ip, midp)
Dim angc As Double = Math.Abs(ang2 - ang1)

' Get a half of them and then calculate hypotenuse
Dim bis As Double = angc / 2.0
Dim hyp As Double = rad / Math.Sin(bis)

' Calculate the center point of filleting arc
Dim cPoint As Point3d = polarPoint(ip, ang, hyp)

' Calculate another leg of a triangle
Dim dblCat As Double = Math.Sqrt((Math.Pow(hyp, 2)) - (Math.Pow(rad, 2)))

' Calculate start point of arc, end point of arc and define arc
Dim pStart As Point3d = polarPoint(ip, ang1, dblCat)
Dim pEnd As Point3d = polarPoint(ip, ang2, dblCat)
Dim arc As New Arc()

' Define the direction of the arc
If isLeft(midp2, ip, midp1) Then
arc = New Arc(cPoint, rad, angleFromX(cPoint, pEnd), _
angleFromX(cPoint, pStart))
Else : arc = New Arc(cPoint, rad, angleFromX(cPoint, pStart), _
angleFromX(cPoint, pEnd))
End If

' Trim lines by arc
line1.StartPoint = pStart
line2.StartPoint = pEnd

' Update the lines and arc properties for this class
m_line1 = line1
m_line2 = line2
m_arc = arc

Catch ex As Autodesk.AutoCAD.Runtime.Exception
acApp.ShowAlertDialog("Sorry, unable to fillet lines! " & ex.Message)
End Try

End Sub

Message 7 of 13

It looks like there's a missing attribute on the module (I've updated the post on theswamp to include it).

You need to add an <Extension()> attribute to the module, and with that, the methods should be callable as an extension methods of the Entity class.
Message 8 of 13

Still not working. I wonder what I'm missing here. I added the PlatformCompatibilityExtensionMethods module to my project as a module file called PlatformUtils.vb. I even put the <Extension()> tag at the top of the PlatformCompatibilityExtensionMethods module.

 

And then, at the beginning of the cat.vb class file where I'm using IntersectWith, I import PlatformCompatibilityExtensionMethods in order to make it available, and yet, when I compile and run AutoCAD 2010 Mechanical, I get the System.MissingMethodException error message, and it's still saying "Methodnot found: Void Autodesk.AutoCAD.DatabaseServices.Entity.IntersectWith"

 

I don't understand how, even after  bringing in the PlatformCompatibilityExtensionMethods module, my calls to IntersectWIth still point to DatabaseServices.Entity.IntersectWith, and I was assuming that the PlatformUtils.vb module's IntersectWith methods would override the DatabaseServices.Entity.IntersectWith methods?

 

This intersectWith issue is the only problem I am having with my project, and because of it, my filleting fails. With my failing fillet, everything else fails as well.

 

And, since I'm on AutoCAD 2010, replacing the last 2 parameters of IntersectWith with the 2012 variations (IntPtr.Zero, IntPtr.Zero) fails during compile, although it removes the warning message in VSStudio 2010. I tried converting my NET framework from 3.5 to 4.0, but everything just fell apart, so I had to revert back to framework 3.5.

 

Can anybody please help me resolve this intersectWith problem? Is there any other way to find the intersection point of two crossing lines without using the IntersectWith method? My filleting function is perfect, because I use it to return the 2 filletted lines and the resulting arc, which allows me to build a polyline using their coordinates. But this all fails if IntersectWith remains problematic.

 

At this point, I'm willing to try any mathematical variations which could help resolve this intersection point problem.

 

Any suggestions?

 

 

Many thanks in advance...

 

Cat

Message 9 of 13
mindofcat
in reply to: mindofcat

So here's what I've been able to accomplish so far:

 

I was able to figure out how to use the PlatformUtils.vb IntersectWith extension method thus:

 

PlatformCompatibilityExtensionMethods.IntersectWith(line1, line2, Intersect.OnBothOperands, intpts, 0, 0)

 

I used the line of code above to replace line1.IntersectWith(line2, Intersect.OnBothOperands, intpts, 0, 0) in my filletLines() function

 

And this solved the problem of System.MissingMethodException: Method not found, DatabaseServices.Entity.IntersectWith

 

But now I am getting another error message saying "System.Reflection.TargetParameterCountException: Parameter count mismatch" And this error points to the PlatformUtils.vb class, on the IntersectWith method for which I paste below:

 


<Extension()> _
Public Function IntersectWith(ByVal entity As Entity, ByVal other As Entity, ByVal intersectType As Intersect, ByVal points As Point3dCollection) As Integer
Dim start As Integer = points.Count
Dim args As Object() = Nothing
If (IntPtr.Size > 4) Then
args = New Object() {other, intersectType, points, CLng(0), CLng(0)}
Else
args = New Object() {other, intersectType, points, CInt(0), CInt(0)}
End If
PlatformCompatibilityExtensionMethods.intersectWithMethod1.Invoke(entity, args)
Return (points.Count - start)
End Function

 

 

The line in bold is where the exception occurs. This IntersectWith method is from Tony Tanzillo'sworkaround for IntersectWith. Any ideas on how to resolve this?

 

Many thanks,

 

Cat

Message 10 of 13

I don't remember if AutoCAD 2010 is the release where the problem exists, and don't know if the product version you're using has it, or has been patched or something, but the arguments you're providing are the ones I would expect should work (the last two are longs on 64 bit or ints on 32 bit). Check the methods in the object browser and see if the last two arguments accept ints, longs, or System.IntPtr. If the last two arguments are both IntPtrs, then you don't need this fix and can just pass IntPtr.Zero for those arguments.

Too bad whomever it was at Autodesk that was responsible for that major screw-up (creating two, platform-dependent, incompatible versions of the API) can't offer you some help, that is, assuming they haven't been fired. How it was possible for a screw-up of that magnitude to ever make it into the shipping product is somewhere between totally-incomprehensible and mind-boggling.

Message 11 of 13

I checked the databaseServices IntersectWith in my object browser, and I see that the last 2 arguments are Long, so I guess this means the 64-bit patch is required.

 

And this also means I'm stuck with the platformUtils.vb fix... for now, at least. Any idea why this method

 

PlatformCompatibilityExtensionMethods.intersectWithMethod1.Invoke(entity, args)

 

gives me a "System.Reflection.TargetParameterCountException: Parameter count mismatch" error? This is what I been trying to figure out, but it's kind of a trial and error thing for me, and nothing I've tried seems to work.

 

The error msg says that System.Reflection.RuntimeMethodInfo.Invoke() takes 5 arguments -> Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture

 

I'm at a crossroads on how to resolve this. It's been a long journey from filleting lines,only to end up patching up the IntersectWith method, and then getting stuck on the fix for IntersectWIth! But I feel I am almost at the journey's end.

 

Any suggestions on this parameter count thing?

Message 12 of 13

The VB.NET code was converted using Reflector and it didn't do a very good job with it, and there's no compiler error when built the code.

 

I updated the code on theswamp, and it should work, but you don't call those methods directly, you call the methods with the <Extension> attribute (as you originally tried), which you should be able to do via the Entity variable, or by prefixing their names with PlatformCompatiblityExtensionMethods.IntersectWith(....).

Message 13 of 13

DiningPhiloshoper, you're the best out there! 

 

Phew, finally this problem is resolved, your updated code took care of the parameter mismatch issue. All i had to do was replace this:

 

PlatformCompatibilityExtensionMethods.intersectWithMethod1.Invoke(Nothing, (BindingFlags.NonPublic Or BindingFlags.Static), Nothing, args, Nothing)

 

with this:

 

PlatformCompatibilityExtensionMethods.intersectWithMethod1.Invoke(entity, (BindingFlags.NonPublic Or BindingFlags.Static), Nothing, args, Nothing)

 

and the whole thing worked like a charm!

 

Thank you so much, DiningPhilosopher, my gratitude knows no limits for your patience, and all the help you accorded me in resolving this IntersectWith issue.


God bless.


Cat

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost