Author Topic: Civil3d: Create a polyline based on the profile  (Read 2346 times)

0 Members and 1 Guest are viewing this topic.

Keith Brown

  • Swamp Rat
  • Posts: 601
Civil3d: Create a polyline based on the profile
« on: March 30, 2017, 12:08:29 PM »
I have an alignment, profile, and profile view that I have been able to create via the API.  Instead of placing the profile view into the drawing I really just need the profile line from it.  (Sorry, i do not know the correct terminology.  Civil is not my thing.)


I know that i can get polyline vertice points from sampling the elevation between the starting and ending stations of the profile.  The accuracy of my polyline will depend on my sampling rate.  Is there an easier way?  Is there an api that will allow me to just get the polyline from the profile without having to go thru that?  I understand that using the sampling method will only give me straight sections but if i make my sampling rate small enough i think it will be ok for the client.


Thanks
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Civil3d: Create a polyline based on the profile
« Reply #1 on: March 30, 2017, 12:36:59 PM »
So you just need a LWPolyline showing how the profile looks in a side (profile) view? Or you need the 3dpoly of the alignment with profile elevations? Either way, its not something native in the API. If the former, I have code you could use which uses either 1' or 0.3m increments for vertical curves (also have one that applies a vertical scale and places the pline in a profileview as a trace over the profile which is used in the Sincpac-C3D command: ExtractProfile). If the latter, that is not something I've yet needed.

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Civil3d: Create a polyline based on the profile
« Reply #2 on: March 30, 2017, 12:42:03 PM »
I just need the LWPolyline showing how the profile looks in a side view.  I can then use the polyline to super impose over an elevation view containing other objects.  The polyline start and end params should match up exactly with the polyline that I used to create the alignment/profile/profileview.


I wouldnt mint taking a look at the code if you can share it.  Thanks.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Civil3d: Create a polyline based on the profile
« Reply #3 on: March 30, 2017, 01:02:23 PM »
My intent was to create a PVI (not sure what that stands for!) at every sampled point along the profile using something like this.

Code - C#: [Select]
  1. public Profile AddPVIsToProfile(Profile profile, double sampleRate)
  2. {
  3.     double startingStation = profile.StartingStation;
  4.     double endingStation = profile.EndingStation;
  5.     double position  = 0;
  6.  
  7.     while (position < endingStation)
  8.     {
  9.         profile.CreatePvi(position, profile.ElevationAt(position));
  10.         position += sampleRate;
  11.     }
  12.  
  13.     profile.CreatePvi(endingStation, profile.ElevationAt(endingStation));
  14.  
  15.     return profile;
  16. }
  17.  

Then i can just iterate through the pvi points to get my z elevation starting at the x,y coordinate of my original polyline and move in the direction of the original polyline.  (The original polyline only consists of a start point and an end point.)  I do not see that changing as the polyline will be inserted into an elevation view representing a flat plane with a single start point and endpoint to represent the left and right side of the view. 
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Civil3d: Create a polyline based on the profile
« Reply #4 on: March 30, 2017, 02:18:34 PM »
Any chance of an image showing what you have and what you need to get the polyline for? I'm a bit confused <<<it doesn't take much these days. The PVI is Point of Vertical Intersection. So it's a vertical angle point. Here's what we have for the basic polyline of the profile:
Code - C#: [Select]
  1.         /// <summary>
  2.         /// Creates a polyline from a profile, does not support true vertical curves but tesselates along them at 1', or 0.3m, increments.
  3.         /// </summary>
  4.         /// <param name="profile"></param>
  5.         /// <returns></returns>
  6.         public static Polyline GetPolylineFromProfile(this Profile profile)
  7.         {
  8.             Polyline pline = new Polyline();
  9.  
  10.             var civDoc = CivilApplication.ActiveDocument;
  11.             double tesslationDistance = 1;
  12.             if (civDoc.DrawingUnitsAreMeters()) //this is another simple extension method
  13.                 tesslationDistance = 0.3;
  14.  
  15.             foreach (var pvi in profile.PVIs)
  16.             {
  17.                 switch (pvi.PVIType)
  18.                 {
  19.                     case ProfileEntityType.Circular:
  20.                     case ProfileEntityType.ParabolaAsymmetric:
  21.                     case ProfileEntityType.ParabolaSymmetric:
  22.                         double currentTesslationStation = pvi.VerticalCurve.StartStation;
  23.                         while (currentTesslationStation < pvi.VerticalCurve.EndStation)
  24.                         {
  25.                             double elevAtTesslationStation = profile.ElevationAt(currentTesslationStation);
  26.                             pline.AddVertexAt(pline.NumberOfVertices, new Point2d(currentTesslationStation, elevAtTesslationStation), 0, 0, 0);
  27.                             currentTesslationStation += tesslationDistance;
  28.                         }
  29.                         pline.AddVertexAt(pline.NumberOfVertices, new Point2d(pvi.VerticalCurve.EndStation, pvi.VerticalCurve.EndElevation), 0, 0, 0);
  30.                         break;
  31.                     case ProfileEntityType.None:
  32.                     case ProfileEntityType.Tangent:
  33.                         pline.AddVertexAt(pline.NumberOfVertices, new Point2d(pvi.Station, pvi.Elevation), 0, 0, 0);
  34.                         break;
  35.                     default:
  36.                         break;
  37.                 }
  38.             }
  39.  
  40.             return pline;
  41.         }
  42.  

If the profileview you are placing the polyline in is exaggerated (Vertical scale != Horiz scale), then it's a bit more work.

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Civil3d: Create a polyline based on the profile
« Reply #5 on: March 30, 2017, 03:45:41 PM »
Hi Jeff,


I think that I confused you.  To be more clear, i have a drawing that has piping in it as well as a civil3d surface.  I was able to create an alignment along a section of the piping.  Along with the alignment i created a profile and placed a profile view in an arbitrary location in the drawing.  Using other software that was created, the user can select the polyline that represents the start and end of a piping run and a 3d box will be created around the polyline encompassing all of the piping.  From that box, I create an elevation view drawing and was going to try and match up the profile view with the piping view to show the ground surface in relationship to the piping.  Instead of trying to transform the profile view to match the piping view and get it match up correctly, I instead thought I would just create a 3d polyline above the pipe that matched the contour.  So in reality, i don't really need the profile view, I just need the polyline from it.


So here is what I have and it appears to be working correctly.

Code - C#: [Select]
  1. private void CreatePolyline3dFromProfile(Profile profile, Polyline polyline, double samplingRate)
  2. {
  3.    double startingStation = profile.StartingStation;
  4.    double endingStation = profile.EndingStation;
  5.    double currentLocation;
  6.    
  7.    Vector3d dir = (polyline.EndPoint - polyline.StartPoint).GetNormal();
  8.    Point3dCollection points = new Point3dCollection();
  9.    points.Add(new Point3d(polyline.StartPoint.X, polyline.StartPoint.Y, profile.ElevationAt(startingStation)));
  10.    currentLocation = samplingRate;
  11.    while (currentLocation < endingStation)
  12.    {
  13.       points.Add(new Point3d((startPoint + (dir * currentLocation)).X, (startPoint + (dir * currentLocation)).Y, profile.ElevationAt(currentLocation)));
  14.       currentLocation += samplingRate;
  15.    }
  16.    
  17.    points.Add(new Point3d(polyline.EndPoint.X, polyline.EndPoint.Y, profile.ElevationAt(endingStation)));
  18.    Database db = HostApplicationServices.WorkingDatabase;
  19.    using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
  20.    {
  21.       BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  22.       BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
  23.       Polyline3d poly = new Polyline3d();
  24.       ms.AppendEntity(poly);
  25.       tr.AddNewlyCreatedDBObject(poly, true);
  26.       foreach (Point3d pt in points)
  27.       {
  28.          PolylineVertex3d vertex = new PolylineVertex3d(pt);
  29.          poly.AppendVertex(vertex);
  30.          tr.AddNewlyCreatedDBObject(vertex, true);
  31.       }
  32.  
  33.       tr.Commit();
  34.    }
  35. }
  36.  

As i said i know next to nothing about Civil and hope that I havent fallen into any traps.  The code above works correctly and I can view the polyline and see that it follows the contour exactly.  I also believe that I am adding the start point and end point correctly to the polyline.  We shall see after some testing.

Thanks for your help.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Civil3d: Create a polyline based on the profile
« Reply #6 on: March 30, 2017, 04:01:58 PM »
Here is an image of the result.


Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: Civil3d: Create a polyline based on the profile
« Reply #7 on: March 30, 2017, 04:35:09 PM »
OK, I see what you are doing. Rather than the profile and sampling, you could get the elevations directly from the surface at all locations the polyline crosses the TIN. The TinSurface object has the SampleElevations(curveEntity) method which returns a Point3dCollection that you'd use to create the Poly3d. But, if it's working as is, so be it. :-)