dilan Posted April 17 Posted April 17 Hi. I can't pass the second argument, a list of 3D points. Point format: (list (list x1 y1 z1) (list x2 y2 z2)...) Where am I missing something? The code itself: using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.Linq; public class LispFunctions { [LispFunction("CountPointsInsidePolyline")] public static int CountPointsInsidePolyline(ResultBuffer resBuf) { // Get the current document and editor Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; try { // Check input arguments if (resBuf == null) { throw new ArgumentNullException(nameof(resBuf), "No arguments provided"); } TypedValue[] argsArray = resBuf.AsArray(); // Check the number of arguments (should be exactly 2) if (argsArray.Length != 2) { throw new ArgumentException("Exactly 2 arguments required: polyline and point list"); } // Get the polyline if (!(argsArray[0].Value is ObjectId polylineId)) { throw new ArgumentException("First argument must be a polyline"); } // Get the point list List<Point3d> points = new List<Point3d>(); if (argsArray[1].Value is ResultBuffer pointsBuffer) { foreach (TypedValue value in pointsBuffer) { if (value.TypeCode == (int)LispDataType.ListBegin) { ResultBuffer coordBuffer = value.Value as ResultBuffer; if (coordBuffer != null && coordBuffer.AsArray().Length >= 3) { double[] coords = coordBuffer.AsArray() .Take(3) .Select(c => Convert.ToDouble(c.Value)) .ToArray(); points.Add(new Point3d(coords[0], coords[1], coords[2])); } } else if (value.TypeCode == (int)LispDataType.Point3d) { points.Add((Point3d)value.Value); } } } else { throw new ArgumentException("Second argument must be a point list"); } int count = 0; using (Transaction tr = db.TransactionManager.StartTransaction()) { try { // Get the polyline Entity entity = tr.GetObject(polylineId, OpenMode.ForRead) as Entity; if (entity == null || !IsClosedPolyline(entity)) { throw new ArgumentException("Object is not a closed polyline"); } if (!(entity is Curve curve)) { throw new ArgumentException("Object is not a curve"); } // Get 2D polygon for checking List<Point2d> polygon = GetPolygonPoints(curve, tr); // Check each point foreach (Point3d pt in points) { Point2d checkPoint = new Point2d(pt.X, pt.Y); if (IsPointInPolygon(polygon, checkPoint)) count++; } tr.Commit(); return count; } catch { tr.Abort(); throw; } } } catch (System.Exception ex) { ed.WriteMessage($"\nError: {ex.Message}"); return 0; } } private static bool IsClosedPolyline(Entity entity) { switch (entity) { case Polyline pl: return pl.Closed; case Polyline2d pl2d: return pl2d.Closed; default: return false; } } private static List<Point2d> GetPolygonPoints(Curve curve, Transaction tr) { List<Point2d> points = new List<Point2d>(); if (curve is Polyline pl) { for (int i = 0; i < pl.NumberOfVertices; i++) { Point3d pt3d = pl.GetPoint3dAt(i); points.Add(new Point2d(pt3d.X, pt3d.Y)); } } else if (curve is Polyline2d pl2d) { foreach (ObjectId vxId in pl2d) { Vertex2d vx = tr.GetObject(vxId, OpenMode.ForRead) as Vertex2d; if (vx != null) { Point3d pt3d = vx.Position; points.Add(new Point2d(pt3d.X, pt3d.Y)); } } } return points; } private static bool IsPointInPolygon(List<Point2d> polygon, Point2d point) { bool inside = false; int count = polygon.Count; for (int i = 0, j = count - 1; i < count; j = i++) { if (((polygon[i].Y > point.Y) != (polygon[j].Y > point.Y)) && (point.X < (polygon[j].X - polygon[i].X) * (point.Y - polygon[i].Y) / (polygon[j].Y - polygon[i].Y) + polygon[i].X)) { inside = !inside; } } return inside; } } Quote
Danielm103 Posted April 17 Posted April 17 The system is going to convert those lists into points for you, in your typed value, just check that the type is Point3d from pyrx import Rx, Ge, Gi, Gs, Db, Ap, Ed, Ax import traceback @Ap.LispFunction() def countPointsInsidePolyline(buffer): try: points = [] for type, value in buffer: if type == Rx.LispType.kPoint3d: points.append(value) return len(points) except Exception as err: traceback.print_exception(err) (countPointsInsidePolyline '(1.0 2.0 3.0) '(1.0 2.0 3.0)) returns 2 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.