Author Topic: CIVIL 3D - Get profile full contour elevation into plan view  (Read 3355 times)

0 Members and 1 Guest are viewing this topic.

jcoon

  • Newt
  • Posts: 157
CIVIL 3D - Get profile full contour elevation into plan view
« on: February 17, 2017, 01:29:49 PM »
All,

I'm looking at the possibility of doing a utility to place civil points in plan view at station & increment along my alignment. Based on a profile full contour elevation. I'm not sure how I'll do it this, so, I thought check here to see if this make sense. The reason I'm looking at this, was to help our junior  engineers / interns learn hand site grading faster, I thought placing the a full contour location along the alignment might make this go faster. I thought about just using a demo corridor along the profile and then extracting the cl crown points, but that just places the profile elevation at station, where I wanted the full contour elevation location on the alignment. what I found was, many of the interns and junior engineers have never done hand grading, So, how are they going to know if something look right or wrong when they are building a model in C3D until they are done. How do you learn to warp flat grading.

getting started, I'll need to select an alignment, then pick a profile to retrieve the elevations from. The big question for me would be how  would I sample the elevations to find that full contour. would I try querying profile at some increment? or would it be better to try some kind of profile grid intersection with the profile and get the station value for the civil point at align station x,y location point from that intersection. Is there anything in C3D that can do this that I'm not aware of. I thought about the profile report tools, but couldn't find a way to export full contour elevations.

Thanks for any ideas

John






Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: CIVIL 3D - Get profile full contour elevation into plan view
« Reply #1 on: February 17, 2017, 03:00:46 PM »
Hi John, by 'full contour' do you mean you want elevations at all locations a minor/major contour would cross if there were a surface?

Also, do your profiles have vertical Curves? If so, are they typically Circular, ParabolicSymetric, or ParabolicAsymetric?
« Last Edit: February 17, 2017, 08:11:38 PM by Jeff_M »

jcoon

  • Newt
  • Posts: 157
Re: CIVIL 3D - Get profile full contour elevation into plan view
« Reply #2 on: February 18, 2017, 11:30:39 AM »
Hi Jeff,

Good to see he here. Your always a great help. Yes, I'm looking for the minor/major contour locations along the alignment. As for profiles, they will be circular vertical curves. Last night I was thinking that a design profile and profile grid intersection might be the place to start. Could I or should I explode the design profile and do a polyline intersection with the grid and then see if I can then get the station and elevation value from those locations, then I'd write the points at station offset along the alignment. I know I could just insert the demo corridor contours along the alignment and just pick the locations and insert a point at those locations. But if it's not too difficult I thought I try a simple utility to do that for me.

Does the polyline intersection direction sound plausible.

Thanks
John

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: CIVIL 3D - Get profile full contour elevation into plan view
« Reply #3 on: February 18, 2017, 11:49:27 AM »
Exploding a profile results in a block, exploding the block results in line segments, not a polyline. While this method could work, it would be best to calculate the locations of the specific elevations. I have part of a solution that I started a while back, but it only handles tangents. I haven't been able to find/create a formula to calculate the location of a specific elevation on a vertical curve...those I have tried only return a single value, but crest/sag curves could have the same elevation at 2 locations. I can share what I have if you'd like.

Jeff_M

  • King Gator
  • Posts: 4087
  • C3D user & customizer
Re: CIVIL 3D - Get profile full contour elevation into plan view
« Reply #4 on: February 18, 2017, 06:22:20 PM »
I had some time to do more research and testing today John. The following code does what you need...mostly. The points on a circular curve may be slightly off, as I didn't find much in my searches for that type of VC. So I used the same formula for locating the elevation on those as I do for the parabolic curves. And, if you happen to have any asymmetric curves, those are skipped altogether...I've only used these twice in the 40 years I've been designing things, so really don't feel like researching those  ;-)

Here's a pic I took after running the command and then Projecting the points to the ProfileView:


Code - C#: [Select]
  1. //Tool to place Cogo Points along an Alignment at a Profile's even number elevations (120, 121, 122, 123, etc)
  2. // by Jeff Mishler @ Quux Software
  3. // Feb. 18, 2017 Provided as an example of how to get specific elevations of a profile.
  4. // May be freely used and/or modified, providing this header stays intact
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using Autodesk.AutoCAD.Geometry;
  9. using Autodesk.AutoCAD.Runtime;
  10. using Autodesk.Civil.ApplicationServices;
  11. using Autodesk.Civil.DatabaseServices;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15.  
  16.  
  17. namespace Civil3D_Misc_Commands.Profiles
  18. {
  19.     public static class ProfileTools
  20.     {
  21.         [CommandMethod("ProfileLevels")]
  22.         public static void profilelvelscommand()
  23.         {
  24.             Document doc = Application.DocumentManager.MdiActiveDocument;
  25.             Editor ed = doc.Editor;
  26.             Database db = doc.Database;
  27.             CivilDocument civdoc = CivilApplication.ActiveDocument;
  28.             PromptEntityOptions entOpts = new PromptEntityOptions("Select Profile:");
  29.             entOpts.SetRejectMessage("...not a Profile, try again.");
  30.             entOpts.AddAllowedClass(typeof(Profile), true);
  31.             PromptEntityResult entRes = ed.GetEntity(entOpts);
  32.             if (entRes.Status != PromptStatus.OK)
  33.                 return;
  34.             using (Transaction tr = db.TransactionManager.StartTransaction())
  35.             {
  36.                 var prof = (Profile)tr.GetObject(entRes.ObjectId, OpenMode.ForRead);
  37.                 var minElev = Math.Floor(prof.ElevationMin) + 1;
  38.                 var maxElev = Math.Floor(prof.ElevationMax);
  39.                 var profEnts = prof.Entities;
  40.                 var output = new List<ProfileStationElevation>();
  41.                 for (double elev = minElev; elev <= maxElev; elev++)
  42.                 {
  43.                     foreach (ProfileEntity ent in profEnts)
  44.                     {
  45.                         var e1 = ent.StartElevation;
  46.                         var e2 = ent.EndElevation;
  47.                         var lowpt = Math.Min(e1, e2);
  48.                         var highPt = Math.Max(e1, e2);
  49.                         var highlow = double.NaN;
  50.                         var pse = new ProfileStationElevation();
  51.                         var x1 = double.NaN;
  52.                         var x2 = double.NaN;
  53.                         var g1 = double.NaN;
  54.                         var g2 = double.NaN;
  55.                         var L = double.NaN;
  56.  
  57.                         switch (ent.EntityType)
  58.                         {
  59.                             case ProfileEntityType.Tangent:
  60.                                 if (!(elev > lowpt && elev < highPt))
  61.                                     continue;
  62.                                 var l = (elev - e1) / prof.GradeAt(ent.StartStation + 0.01);
  63.                                 pse = new ProfileStationElevation();
  64.                                 pse.Elevation = elev;
  65.                                 pse.Station = ent.StartStation + l;
  66.                                 output.Add(pse);
  67.                                 break;
  68.                             case ProfileEntityType.Circular:
  69.                                 var crvEnt = (ProfileCircular)ent;
  70.                                 highlow = crvEnt.HighLowPointElevation;
  71.                                 lowpt = Math.Min(highlow, lowpt);
  72.                                 highPt = Math.Max(highlow, highPt);
  73.                                 if (!(elev > lowpt && elev < highPt))
  74.                                     continue;
  75.                                 //NEED FORMULA TO CALC LOCATION OF SPECIFIC ELEVATION ON CIRCULAR CURVE, using parabolic calc for now
  76.                                 g1 = crvEnt.GradeIn;
  77.                                 g2 = crvEnt.GradeOut;
  78.                                 L = crvEnt.Length;
  79.  
  80.                                 x1 = ((g1 * L) + Math.Sqrt((L * ((-2 * elev * g1) + (2 * elev * g2) + ((g1 * g1) * L) + (2 * g1 * e1) - (2 * g2 * e1))))) / (g1 - g2);
  81.                                 x2 = ((g1 * L) - Math.Sqrt((L * ((-2 * elev * g1) + (2 * elev * g2) + ((g1 * g1) * L) + (2 * g1 * e1) - (2 * g2 * e1))))) / (g1 - g2);
  82.                                 if (x1 > 0)
  83.                                 {
  84.                                     pse = new ProfileStationElevation();
  85.                                     pse.Station = crvEnt.StartStation + x1;
  86.                                     pse.Elevation = elev;
  87.                                     output.Add(pse);
  88.                                 }
  89.                                 if (x2 > 0)
  90.                                 {
  91.                                     pse = new ProfileStationElevation();
  92.                                     pse.Station = crvEnt.StartStation + x2;
  93.                                     pse.Elevation = elev;
  94.                                     output.Add(pse);
  95.                                 }
  96.                                 break;
  97.                             case ProfileEntityType.ParabolaAsymmetric:
  98.                                 var crvAsymEnt = (ProfileParabolaAsymmetric)ent;
  99.                                 highlow = crvAsymEnt.HighLowPointElevation;
  100.                                 lowpt = Math.Min(highlow, lowpt);
  101.                                 highPt = Math.Max(highlow, highPt);
  102.                                 if (!(elev > lowpt && elev < highPt))
  103.                                     continue;
  104.                                 //NEED FORMULA TO CALC LOCATION OF SPECIFIC ELEVATION ON ASYMMETRICAL PARABOLIC CURVE
  105.                                 break;
  106.                             case ProfileEntityType.ParabolaSymmetric:
  107.                                 var crvSymEnt = (ProfileParabolaSymmetric)ent;
  108.                                 highlow = crvSymEnt.HighLowPointElevation;
  109.                                 lowpt = Math.Min(highlow, lowpt);
  110.                                 highPt = Math.Max(highlow, highPt);
  111.                                 if (!(elev > lowpt && elev < highPt))
  112.                                     continue;
  113.                                 g1 = crvSymEnt.GradeIn;
  114.                                 g2 = crvSymEnt.GradeOut;
  115.                                 L = crvSymEnt.Length;
  116.  
  117.                                 x1 = ((g1 * L) + Math.Sqrt((L * ((-2 * elev * g1) + (2 * elev * g2) + ((g1 * g1) * L) + (2 * g1 * e1) - (2 * g2 * e1))))) / (g1 - g2);
  118.                                 x2 = ((g1 * L) - Math.Sqrt((L * ((-2 * elev * g1) + (2 * elev * g2) + ((g1 * g1) * L) + (2 * g1 * e1) - (2 * g2 * e1))))) / (g1 - g2);
  119.                                 if (x1 > 0)
  120.                                 {
  121.                                     pse = new ProfileStationElevation();
  122.                                     pse.Station = crvSymEnt.StartStation + x1;
  123.                                     pse.Elevation = elev;
  124.                                     output.Add(pse);
  125.                                 }
  126.                                 if (x2 > 0)
  127.                                 {
  128.                                     pse = new ProfileStationElevation();
  129.                                     pse.Station = crvSymEnt.StartStation + x2;
  130.                                     pse.Elevation = elev;
  131.                                     output.Add(pse);
  132.                                 }
  133.                                 break;
  134.                             default:
  135.                                 //SHOULDN'T GET TO HERE
  136.                                 break;
  137.                         }
  138.                     }
  139.                 }
  140.                 output = output.OrderBy(s => s.Station).ToList();
  141.                 var align = (Alignment)tr.GetObject(prof.AlignmentId, OpenMode.ForRead);
  142.                 double east = 0, north = 0;
  143.                 var points = CivilApplication.ActiveDocument.CogoPoints;
  144.                 foreach (var pair in output)
  145.                 {
  146.                     align.PointLocation(pair.Station, 0, ref east, ref north);
  147.                     var pt = points.Add(new Point3d(east, north, pair.Elevation), true);
  148.                     ed.WriteMessage("\nStation: {0}, Elev: {1}", pair.Station.ToStationString(), pair.Elevation.ToString("F2"));
  149.                 }
  150.                 tr.Commit();
  151.             }
  152.         }
  153.  
  154.         public static string ToStationString(this double Value)
  155.         {
  156.             var civdoc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument;
  157.             var stasettings = civdoc.Settings.DrawingSettings.AmbientSettings.Station;
  158.             var stationstring = Value.ToString("F" + stasettings.Precision.Value);
  159.             var symbolposition = stasettings.StationDelimiterPosition.Value;
  160.             switch (stasettings.StationDelimiterPosition.Value)
  161.             {
  162.                 case Autodesk.Civil.StationDelimiterPositionType.Delimiter10:
  163.                     stationstring = stationstring.Insert(stationstring.IndexOf('.') - 1, "+");
  164.                     break;
  165.                 case Autodesk.Civil.StationDelimiterPositionType.Delimiter100:
  166.                     stationstring = stationstring.Insert(stationstring.IndexOf('.') - 2, "+");
  167.                     break;
  168.                 case Autodesk.Civil.StationDelimiterPositionType.Delimiter1000:
  169.                     stationstring = stationstring.Insert(stationstring.IndexOf('.') - 3, "+");
  170.                     break;
  171.                 case Autodesk.Civil.StationDelimiterPositionType.Delimiter10000:
  172.                     stationstring = stationstring.Insert(stationstring.IndexOf('.') - 4, "+");
  173.                     break;
  174.                 case Autodesk.Civil.StationDelimiterPositionType.Delimiter100000:
  175.                     stationstring = stationstring.Insert(stationstring.IndexOf('.') - 5, "+");
  176.                     break;
  177.             }
  178.             return stationstring;
  179.         }
  180.  
  181.     }
  182.     public class ProfileStationElevation
  183.     {
  184.         public double Station = double.NaN;
  185.         public double Elevation = double.NaN;
  186.  
  187.         public ProfileStationElevation()
  188.         {
  189.  
  190.         }
  191.     }
  192.  
  193. }
  194.  
 

« Last Edit: February 18, 2017, 06:28:48 PM by Jeff_M »

jcoon

  • Newt
  • Posts: 157
Re: CIVIL 3D - Get profile full contour elevation into plan view
« Reply #5 on: February 19, 2017, 08:40:46 AM »
Jeff,

It looks like one of my posts didn't work. not sure why.

Wow, this a lot more complex than I was thinking. It's certainly a lot of work. It's going to take me some time to convert from C so I can use it. Still haven't learned C. I don't do enough apps work now to justify it. Thanks so much, Let me give this a try. Your a great help!

John

jmaeding

  • Bull Frog
  • Posts: 304
  • I'm just here for the Shelties.
Re: CIVIL 3D - Get profile full contour elevation into plan view
« Reply #6 on: March 02, 2017, 01:27:25 PM »
I have done that "plot contours for alignment" in both lisp and .net, and also done the "plot contours using some typical section" without a surface. My advice:
Make a tool to generate a 3d pline from a civil3d horizontal and vertical alignment. Then use that 3d pline to make a surface and gen contours.
For typical section, just have that same tool generate the 3d pline at an offset left or right.
You see, to do all this, you must have the following subroutines:
1) find 2d point at some station (and offset) along an alignment
2) find elevation at some station along an alignment and profile
3) make a 3d pline from list of xyz points
Once you have that, simply generate a list of points at say, 5 ft intervals along your alignment, and make a 3d pline from them.
For left/right offsets, just specify an offset val and elevation lift as desired.
In the end, you get nice 3d plines you add as breaklines to a surface.
I cannot sell my tools on this, but I bet smartdraft or one of the other civil3d 3rd parties out there has this.

Isn't it interesting that Civil3d is missing this?
Its because they want you to do corridors or feature lines but both are ill suited for things like precise grading.
There should be an object called an "alignment/profile combo" that lets you do all this, but there ain't, so you gotta make it yourself.
James Maeding