Get Points inside Polyline

Hello Dynamo Friends :slight_smile:

I want to get all points that are inside the boundaries of a polyline, but I´m already struggling at getting the polyline geometry from Civil 3D to Dynamo.

Here is my polyline, trying to get the geometry fails.


So I wanted to try my luck with the exploded lines.
There is now an arc that makes troubles.

So how can i make a dynamo polycurve or surface? And whats a good way to later test if my points are inside or outside of this polycurve?
Or should i work with the ACAD objects without transforming to dynamo geometry?

Happy about any advice :slight_smile:

Try filtering out the nulls, and building a new polycurve by joined curves.

From there you can patch to a surface, and test each point for intersection.

Thanks jacob, but dropping the arcs is no option, i have many polylines that contain many arcs…so I think i just will draw new polylines with line segments instead of arcs. Not much fun but as long as it makes this work…

Do you have a sample dataset?

So my guess is that you have selected something which isn’t a curve or arc, as a Polyline should convert just fine unless there is a duplicate point (meaning a line with no length) or a branching polyline (meaning the ACAD object forms a T of some sort). This is what’s indicated by the first error message.

Cleaning that polyline issue up will likely be faster and result in better accuracy than segmenting your curves.

The exploded content (lines and arcs) would fail to convert arcs (for reasons beyond me that hasn’t be implemented…), but you could utilize the AutoCAD PI to get the geometry if that was the route you wanted to go.

Hi
Can you attached example drawing

Thanks for you replies!

I´m still struggling to make a simple surface by patch.
I have created a new polyline without arcs but i get this error: “A planar boundary patch error is found”

Also tried to explode and rebuild the polycurve, same result:

Sample file attached, thanks for the help!
Polyline.dwg (948.0 KB)

Is the geometry scaling set to Medium?

hello @mzjensen

It is set to extra large because before I got these warnings.

At least the converting to dynamo polycurves works now for all of my 4 polylines, but making a surface only works for one.

Got a new Error, API_FAILED :smiley:

File:
Polyline4.dwg (952.7 KB)

Hi Gerhard, does it work if you are in medium scaling…

1 Like

For the time being it is a best practice to ignore the warnings and leave it set to medium. Changing to extra large will often introduce issues with geometry integrity.

3 Likes

Ok, so it was all about the geometry scaling, I was mislead by the warnings :confused:
So thanks to all for solving that problem!

Now as everything is running, the problem is that testing intersection for 10.000 points will take forever.
Is there no other way to check if a point is on a surface?

Are you trying to generate a grid of points on the surface? Or are the points usually more random?

This wasn’t fast, but it did the trick with 100,000 points (so 10x what you quoted).

My recommendation: build the tooling to take the actions on the filtered points after you finding the contained ones, but use a smaller data set (say 100 points) and then enable the full data set and hit run before you go to lunch.

1 Like

Hi,
you can use matplotlib.path

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('Python.Included')
import Python.Included as pyInc
path_py3_lib = pyInc.Installer.EmbeddedPythonHome
sys.path.append(path_py3_lib + r'\Lib\site-packages')

import matplotlib.path as mplPath
import numpy as np

    
polycurve = IN[0]
input_pts = np.array(IN[1])
pointCheck = np.array([(p.X, p.Y) for p in input_pts])

bbPath = mplPath.Path([(c.StartPoint.X, c.StartPoint.Y) for c in polycurve.Curves()])
mask = bbPath.contains_points(pointCheck)

OUT = input_pts[mask]

https://matplotlib.org/stable/api/path_api.html

6 Likes

hi @c.poupin

a question
How can add matplotlib. path to the dynamo so that the code can recognize it

Thanks

Hi @hosneyalaa

actually Matplotlib is not compatible with IP2 (maybe in the future with IPY3 + Ironclad ) you need to use CPython3 engine and install Matplotlib (it’s OOTB in Revit/Civil 2024)

Alternatively, you can use Ray tracing (compatible all Python Engine)

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Ray tracing
def ray_tracing_method(x,y,poly):

    n = len(poly)
    inside = False

    p1x,p1y = poly[0]
    for i in range(n+1):
        p2x,p2y = poly[i % n]
        if y > min(p1y,p2y):
            if y <= max(p1y,p2y):
                if x <= max(p1x,p2x):
                    if p1y != p2y:
                        xints = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
                    if p1x == p2x or x <= xints:
                        inside = not inside
        p1x,p1y = p2x,p2y

    return inside

polycurve = IN[0]
input_pts = IN[1]

polygon = [(c.StartPoint.X, c.StartPoint.Y) for c in polycurve.Curves()]
insidepts = [p for p in input_pts if ray_tracing_method(p.X, p.Y, polygon)]

OUT = insidepts

6 Likes

thank @c.poupin

1 Like