Community
Civil 3D Customization
Welcome to Autodesk’s AutoCAD Civil 3D Forums. Share your knowledge, ask questions, and explore popular AutoCAD Civil 3D Customization topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[dotNet] Selecting and modifying existing corridor regions

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
Anonymous
721 Views, 4 Replies

[dotNet] Selecting and modifying existing corridor regions

As the title states but, for context, the larger goal is to set targets for the selected region. As I understand that is from a set of the process is involved with BaselineRegion.GetTargets() and .SetTargets() [from this post: Civilized Development). I'm stumbling through the TransientGraphics and something like Editor.PointMonitor and .IsPointInside to highlight but I'm wondering if there not a better way to do this yet. 

 

I've poked around previous threads for something similar and while all this is fine, I don't want the workflow to start by selecting an alignment e.g. select alignment -> pick point -> query station + offset -> find BaselineRegion in CorridorCollection. The dream would be something that functions similarly to the selection tool that is already in civil3D contextual "modify corridor" elements. 

 

https://forums.autodesk.com/t5/civil-3d-customization/dynamically-selecting-corridor-regions/m-p/519...

 

Any help is greatly appreciated!

4 REPLIES 4
Message 2 of 5
Jeff_M
in reply to: Anonymous

@ngwalters, as the last post in the thread you linked mentioned, I did find a way that works quite well. Here is a quick video showing it in action...yes, it's a small corridor but it still functions well with large, complex, corridors as well.

 

 

 

I will try to explain as best I can without posting too much code, as it is rather complex and proprietary.

First, I have the user select a corridor, once selected, I gather information about all of the Baselines and Regions, which includes the Region bounding Polyline and it's vertices. I save the Region data in a simple Class:

    public class PolyRegion
    {
        public BaselineRegion BSRegion;
        public Polyline Polyline;
        public string BaselineName;
        public Point2dCollection Vertices;
    }

I have a custom Extension method for Corridors called GetAllRegionBoundaries to help with this. I also create a small custom form to display the Region/Baseline information in the PointMonitor. Then the meat of the code is in the PointMonitor which checks to see if the current point is A. Inside the corridor geometric extents, and, if it is, loops through the List of PolyRegions looking if it is within one of the saved polylines. If it is in one, then that Polyline is used in a TransientGraphics to display the found region.

 

I hope that makes enough sense to help you get what you need. I wish I could share some code, but mine uses many other custom extension methods that would just be too much to share here. It took me a few weeks of trial and error to get it working as it is now.

I will share the IsPointInside extension method, as I'm fairly certain I found it in a search. Although I did not include the author, as it was posted anonymously.

        /// <summary>
        /// Checks whether a 2d point lies inside a closed, non-curved, Polyline. Must include the pline vertices
        /// </summary>
        /// <param name="poly"></param>
        /// <param name="testpt"></param>
        /// <param name="verts"></param>
        /// <returns>true/false</returns>
        public static bool IsPointInside(this Polyline poly, Point2d testpt, Point2dCollection verts)
        {
            if (!poly.Closed)
            {
                throw new System.ArgumentException("Polyline must be closed!");
            }
            int i, j = 0;
            bool c = false;
            int nvert = verts.Count;
            double testx = testpt.X, testy = testpt.Y;
            for (i = 0, j = nvert - 1; i < nvert; j = i++)
            {
                double vertx = verts[i].X, verty = verts[i].Y;
                double prevx = verts[j].X, prevy = verts[j].Y;
                if (((verty > testy) != (prevy > testy)) &&
                 (testx < (prevx - vertx) * (testy - verty) / (prevy - verty) + vertx))
                    c = !c;
            }
            return c;
        }

Good Luck!

Jeff_M, also a frequent Swamper
EESignature
Message 3 of 5
Jeff_M
in reply to: Anonymous

@ngwalters, as the last post in the thread you linked mentioned, I did find a way that works quite well. Here is a quick video showing it in action...yes, it's a small corridor but it still functions well with large, complex, corridors as well.

 

 

 

I will try to explain as best I can without posting too much code, as it is rather complex and proprietary.

First, I have the user select a corridor, once selected, I gather information about all of the Baselines and Regions, which includes the Region bounding Polyline and it's vertices. I save the Region data in a simple Class:

    public class PolyRegion
    {
        public BaselineRegion BSRegion;
        public Polyline Polyline;
        public string BaselineName;
        public Point2dCollection Vertices;
    }

I have a custom Extension method for Corridors called GetAllRegionBoundaries to help with this. I also create a small custom form to display the Region/Baseline information in the PointMonitor. Then the meat of the code is in the PointMonitor which checks to see if the current point is A. Inside the corridor geometric extents, and, if it is, loops through the List of PolyRegions looking if it is within one of the saved polylines. If it is in one, then that Polyline is used in a TransientGraphics to display the found region.

 

I hope that makes enough sense to help you get what you need. I wish I could share some code, but mine uses many other custom extension methods that would just be too much to share here. It took me a few weeks of trial and error to get it working as it is now.

I will share the IsPointInside extension method, as I'm fairly certain I found it in a search. Although I did not include the author, as it was posted anonymously.

        /// <summary>
        /// Checks whether a 2d point lies inside a closed, non-curved, Polyline. Must include the pline vertices
        /// </summary>
        /// <param name="poly"></param>
        /// <param name="testpt"></param>
        /// <param name="verts"></param>
        /// <returns>true/false</returns>
        public static bool IsPointInside(this Polyline poly, Point2d testpt, Point2dCollection verts)
        {
            if (!poly.Closed)
            {
                throw new System.ArgumentException("Polyline must be closed!");
            }
            int i, j = 0;
            bool c = false;
            int nvert = verts.Count;
            double testx = testpt.X, testy = testpt.Y;
            for (i = 0, j = nvert - 1; i < nvert; j = i++)
            {
                double vertx = verts[i].X, verty = verts[i].Y;
                double prevx = verts[j].X, prevy = verts[j].Y;
                if (((verty > testy) != (prevy > testy)) &&
                 (testx < (prevx - vertx) * (testy - verty) / (prevy - verty) + vertx))
                    c = !c;
            }
            return c;
        }

Good Luck!

Jeff_M, also a frequent Swamper
EESignature
Message 4 of 5
Jeff_M
in reply to: Anonymous

@Anonymous, as the last post in the thread you linked mentioned, I did find a way that works quite well. Here is a quick video showing it in action...yes, it's a small corridor but it still functions well with large, complex, corridors as well. Hmm, the message will not post when the screencast is embedded. Here's a link to it instead: 

https://autode.sk/2uI0Gzv

 

I will try to explain as best I can without posting too much code, as it is rather complex and proprietary.

First, I have the user select a corridor, once selected, I gather information about all of the Baselines and Regions, which includes the Region bounding Polyline and it's vertices. I save the Region data in a simple Class:

    public class PolyRegion
    {
        public BaselineRegion BSRegion;
        public Polyline Polyline;
        public string BaselineName;
        public Point2dCollection Vertices;
    }

I have a custom Extension method for Corridors called GetAllRegionBoundaries to help with this. I also create a small custom form to display the Region/Baseline information in the PointMonitor. Then the meat of the code is in the PointMonitor which checks to see if the current point is A. Inside the corridor geometric extents, and, if it is, loops through the List of PolyRegions looking if it is within one of the saved polylines. If it is in one, then that Polyline is used in a TransientGraphics to display the found region.

 

I hope that makes enough sense to help you get what you need. I wish I could share some code, but mine uses many other custom extension methods that would just be too much to share here. It took me a few weeks of trial and error to get it working as it is now.

I will share the IsPointInside extension method, as I'm fairly certain I found it in a search. Although I did not include the author, as it was posted anonymously.

        /// <summary>
        /// Checks whether a 2d point lies inside a closed, non-curved, Polyline. Must include the pline vertices
        /// </summary>
        /// <param name="poly"></param>
        /// <param name="testpt"></param>
        /// <param name="verts"></param>
        /// <returns>true/false</returns>
        public static bool IsPointInside(this Polyline poly, Point2d testpt, Point2dCollection verts)
        {
            if (!poly.Closed)
            {
                throw new System.ArgumentException("Polyline must be closed!");
            }
            int i, j = 0;
            bool c = false;
            int nvert = verts.Count;
            double testx = testpt.X, testy = testpt.Y;
            for (i = 0, j = nvert - 1; i < nvert; j = i++)
            {
                double vertx = verts[i].X, verty = verts[i].Y;
                double prevx = verts[j].X, prevy = verts[j].Y;
                if (((verty > testy) != (prevy > testy)) &&
                 (testx < (prevx - vertx) * (testy - verty) / (prevy - verty) + vertx))
                    c = !c;
            }
            return c;
        }

Good Luck!

Jeff_M, also a frequent Swamper
EESignature
Message 5 of 5
Anonymous
in reply to: Jeff_M

Thanks Jeff, this helps a ton. I also want to just say thanks for all of the support you give the community, I've been dabbling in programming and LISP for years and always come across posts of yours that never fail wrap everything up in a nice neat bow.

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

Post to forums  

Rail Community


 

Autodesk Design & Make Report