Author Topic: equivelent of lisp Osnap function in .net?  (Read 8912 times)

0 Members and 1 Guest are viewing this topic.

LE

  • Guest
Re: equivelent of lisp Osnap function in .net?
« Reply #15 on: November 17, 2007, 01:59:30 PM »
I finally stumbled on what I wanted all along, and it's a lot less complex than I thought.
I believe the equivalent code for this lisp:

(setq Entity (entsel))
(setq MidPoint (osnap (cadr Entity) "mid"))

is

PromptEntityResult selectionRes = ed.GetEntity("Select Entity ");
Point3d pickPt = selectionRes.PickedPoint;
Point3d snapPt = ed.Snap("midpoint", pickPt);



If is not there and cannot be P/Invoke - you can make your own, here is a start, that might help [includes the midpoint and endpoint only]:

Code: [Select]
static public void getosnap(string mode)
{
    Database db = HostApplicationServices.WorkingDatabase;
    Document doc = acadApp.DocumentManager.MdiActiveDocument;
    Editor ed = doc.Editor;

    PromptEntityResult res = ed.GetEntity("\nSelect entity: ");
    if (res.Status != PromptStatus.OK)
        return;
   
    using (Transaction tr = db.TransactionManager.StartTransaction())
    {
        Curve obj = tr.GetObject(res.ObjectId, OpenMode.ForRead, false) as Curve;
        if (obj is Curve)
        {
            Point3d pickPoint = res.PickedPoint;
            Point3d oPoint = obj.GetClosestPointTo(pickPoint, ed.GetCurrentView().ViewDirection, false);

            Point3d sp = obj.StartPoint;
            Point3d ep = obj.EndPoint;
            Point3d pt = new Point3d(); // point to return

            double dx = obj.GetDistAtPoint(oPoint);
            double param = obj.GetParameterAtPoint(oPoint); //where is that point selected?
           
            double sparam = obj.GetParameterAtPoint(sp);
            double eparam = obj.GetParameterAtPoint(ep);

            double xparam = param - sparam;
            double yparam = param - eparam;

            double ds = obj.GetDistanceAtParameter(Math.Abs(xparam));
            double de = obj.GetDistanceAtParameter(Math.Abs(yparam));

            switch (mode.ToUpper())
            {
                case "MIDP":
                    double totlen = obj.GetDistanceAtParameter(obj.EndParam);
                    pt = obj.GetPointAtDist(totlen / 2.0);
                    break;
                case "ENDP":
                    if (ds > de)
                        pt = ep;
                    else
                        pt = sp;
                    break;
            }

            BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
            DBPoint point = new DBPoint(pt);
            point.ColorIndex = 1;
            btr.AppendEntity(point);
            tr.AddNewlyCreatedDBObject(point, true);

        }

        tr.Commit();
    }
}

[CommandMethod("GETOSNAP")]
static public void testosnap()
{
    getosnap("MIDP"); // test
    getosnap("ENDP"); // test
}

Then, you can use the above code to have a function to return the osnap point

Code: [Select]
static public Point3d getosnap(Curve obj, string mode)
{

return pt;
}

Jeff Moran

  • Guest
Re: equivelent of lisp Osnap function in .net?
« Reply #16 on: November 17, 2007, 05:46:09 PM »
Just be aware that is really risky code.

All you are doing is mimicking what happens when the user clicks on that point, and has the MID osnap turned on.

If entities overlap at that point, you may not get the midpoint of the previously-selected entity.  You may get the midpoint of a different entity.

Thanks for your advice!

Being new to C#, I thought it would be a good idea to try to writing code in which I am familiar with, as in something I've done in Lisp. Does that make sense? In a previous post I've included both the finished lisp code and the beginning of C# code for this particular program. I would appreciate any suggestion on how I may improve on that particular code as try writing a version in C#.

Thanks again!
Jeff




sinc

  • Guest
Re: equivelent of lisp Osnap function in .net?
« Reply #17 on: November 18, 2007, 07:58:48 PM »
Here's something that may prove useful.

This is a command in the soon-to-be-released SincpacC3D v1.0.  It lets you select a bunch of objects, and then change them to match the rotation of another selected object.  If the object to match is a linear object such as a polyline or an arc (or Civil-3D Feature Line or Parcel Line), then the routine uses the direction of the linear object at the point that is closest to the user's pick point.

This code uses other code that already exists in the SincpacC3D, so if you want to actually run it, you will need to add this code to the SincpacC3D source code, which can be downloaded from here.

In the very near future, I plan to release a super-improved version of the SincpacC3D, with more than twice as many useful commands as the current version, as well as new-and-improved versions of existing routines, and also integrated Help for all functions.  It provides quick'n'easy solutions to many of the problems people have been complaining about on Autodesk's discussion groups, so I've been trying to get it ready for release as quickly as possible.  It's getting close to being ready, and I hope to have it available within the next few weeks.  But here's a sneak-peak of one of the simpler (but still very useful) routines:

Code: [Select]
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AECC.Interop.Land;
using AutocadUtilities;
using Civil3DUtilities;

namespace SincpacC3D.RotateObjects
{
    public class RotationMatch
    {
        [CommandMethod("ROTATIONMATCH", CommandFlags.UsePickSet)]
        public void RotationMatchCommand()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            C3DUtil c3dUtil = new C3DUtil();
            Database db = Application.DocumentManager.MdiActiveDocument.Database;
            PromptSelectionOptions sPrmpt = new PromptSelectionOptions();
            sPrmpt.MessageForAdding = "\nSelect objects to rotate: ";
            sPrmpt.MessageForRemoval = "\nSelect objects to remove: ";
            PromptSelectionResult ssResult;
            ssResult = ed.GetSelection(sPrmpt);
            if (ssResult.Status == PromptStatus.OK)
            {
                PromptEntityOptions entityOps = new PromptEntityOptions("\nSelect object to match: ");
                PromptEntityResult entityRes = ed.GetEntity(entityOps);
                if (entityRes.Status == PromptStatus.OK)
                {
                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        ObjectId[] objIds = ssResult.Value.GetObjectIds();
                        Entity matchEntity = tr.GetObject(entityRes.ObjectId, OpenMode.ForRead, false) as Entity;
                        double rot = 0;
                        int errorCount = 0;
                        Curve crv = matchEntity as Curve;
                        if (crv != null)
                        {
                            Point3d pickPt = entityRes.PickedPoint;
                            Point3d pointOnCurve = crv.GetClosestPointTo(pickPt, false);
                            rot = CurveUtil.AzimuthAtParam(crv, crv.GetParameterAtPoint(pointOnCurve));
                        }
                        else
                        {
                            try
                            {
                                rot = (double)matchEntity.GetType().GetProperty("Rotation").GetValue(matchEntity, null);
                            }
                            catch
                            {
                                AeccPoint p = matchEntity.AcadObject as AeccPoint;
                                if (p != null)
                                {
                                    rot = p.Rotation;
                                }
                                else
                                {
                                    ed.WriteMessage("\nCould not get rotation for selected object...");
                                }
                            }
                        }

                        foreach (ObjectId oId in objIds)
                        {
                            Entity ent = tr.GetObject(oId, OpenMode.ForWrite, false) as Entity;
                            try
                            {
                                ent.GetType().GetProperty("Rotation").SetValue(ent, rot, null);
                            }
                            catch
                            {
                                Line line = ent as Line;
                                if (line != null)
                                {
                                    LineSegment2d calcLine = new LineSegment2d(line.StartPoint.Convert2d(CurveUtil.PlaneXY), line.EndPoint.Convert2d(CurveUtil.PlaneXY));
                                    double dist = line.Length / 2;
                                    double dX = Math.Cos(rot) * dist;
                                    double dY = Math.Sin(rot) * dist;
                                    Point2d midpoint = calcLine.MidPoint;
                                    Point3d newStart = new Point3d(midpoint.X - dX, midpoint.Y - dY, line.StartPoint.Z);
                                    Point3d newEnd = new Point3d(midpoint.X + dX, midpoint.Y + dY, line.EndPoint.Z);
                                    line.StartPoint = newStart;
                                    line.EndPoint = newEnd;
                                }
                                else
                                {
                                    AeccPoint p = ent.AcadObject as AeccPoint;
                                    if (p != null) p.Rotation = rot;
                                    else ++errorCount;
                                }
                            }
                        }
                        if (errorCount > 0)
                            ed.WriteMessage("\nCould not rotate {0} object(s).", errorCount);
                        tr.Commit();
                    }
                }
            }
        }
    }
}
« Last Edit: November 18, 2007, 08:00:07 PM by sinc »