Creating profile from file

Creating profile from file

Anonymous
Not applicable
5,541 Views
21 Replies
Message 1 of 22

Creating profile from file

Anonymous
Not applicable

 cr_pf_fr_fl.png

Is there any way to call this command without the dialog box. it would be nice to get away from the file selection box by passing it as an argument to a lisp function. Even better if the following box Create Profile - Draw New  could be bypassed? Any thoughts ideas? I know LISP, so would prefer a LISP solution. I have no .net experience. But am willing to experiment if anyone can push me to a specific method available in the API? Thanks in advance.

0 Likes
Accepted solutions (1)
5,542 Views
21 Replies
Replies (21)
Message 2 of 22

Ranjit_Singh
Advisor
Advisor

AFAIK, activeX does not provide any method for this. Not sure about .net

0 Likes
Message 3 of 22

lu_an_jie
Advocate
Advocate

This is .net (c#) sample for creating a profile, based on two points.

        public static void CreateProfileNoSurface(Alignment oAlignment)
        {
            CivilDocument civDoc = CivilApplication.ActiveDocument;

            using (Transaction ts = Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction())
            {

                // use the same layer as the alignment
                ObjectId layerId = oAlignment.LayerId;

                // get the standard style and label set 
                // these calls will fail on templates without a style named "Standard"
                ObjectId styleId = civDoc.Styles.ProfileStyles["Standard"];
                ObjectId labelSetId = civDoc.Styles.LabelSetStyles.ProfileLabelSetStyles["Standard"];

                // create a new empty profile
                ObjectId oProfileId = Profile.CreateByLayout("MyProfile", oAlignment.Id, layerId, styleId, labelSetId);

                // Now add the entities that define the profile.
                Profile oProfile = ts.GetObject(oProfileId, OpenMode.ForRead) as Profile;

                Point2d startPoint = new Point2d(oAlignment.StartingStation, 40);
                Point2d endPoint = new Point2d(oAlignment.EndingStation, -70);
                ProfileTangent oTangent1 = oProfile.Entities.AddFixedTangent(startPoint, endPoint);

                ts.Commit();
            }
        }

 

You can enclose this in a while loop, reading and parsing the text file line and adding entity. You can find plenty of sample of reading and parsing text files in the AutoCAD development  forum. 

 

https://forums.autodesk.com/t5/net/reading-data-from-a-txt-file-using-c/td-p/6005943

Regards

Andreas Luka (Lu An Jie)

http://www.luka-consult.de

Creator of the LX-Stair App for Civil 3D
0 Likes
Message 4 of 22

lu_an_jie
Advocate
Advocate

Do you have a sample file, so I can test some code.

Regards

Andreas Luka (Lu An Jie)

http://www.luka-consult.de

Creator of the LX-Stair App for Civil 3D
0 Likes
Message 5 of 22

Jeff_M
Consultant
Consultant
Accepted solution

Here's some code that shows how this can be done using lisp. You can take this as a starting point to create the function which accepts the file name, profile name, and profile style name. Hope it helps!

(vl-load-com)
(if (setq ss (ssget ":S" '((0 . "AECC_ALIGNMENT"))))
  (progn
    (setq alignment (vlax-ename->vla-object (ssname ss 0)))
    (setq profile (vlax-invoke (vlax-get alignment 'profiles) 'Add "NewProfileFromFile" 2 "Basic")) ;;the 2 is for a FinishGrade profile
    (setq pvis (vlax-get profile 'PVIs))
    (setq f (open "C:\\TestFiles\\Profiledata.txt" "r"));;this file must be in the format defined by C3D for profiles from a file
    (while (setq ln (read-line f))
      (setq data (str2list ln " "))
      (if (= 2 (length data))
	(setq pvi (vlax-invoke pvis 'add (atof (nth 0 data)) (atof (nth 1 data)) 1 nil nil));;the 1 tells C3D this a Tangent PVI
	(setq pvi (vlax-invoke pvis 'add (atof (nth 0 data)) (atof (nth 1 data)) 3 (atof (nth 2 data)) nil));;the 3 tells C3D it is a parabolic VC
	)
      )
    (close f)
    )
  )

;;;str2list by John Uhden, as posted to the adesk customization newsgroup a long time ago
(defun Str2List (str pat / i j n lst)
  (cond
    ((/= (type str)(type pat) 'STR))
    ((= str pat)'(""))
    (T
      (setq i 0 n (strlen pat))
      (while (setq j (vl-string-search pat str i))
        (setq lst (cons (substr str (1+ i)(- j i)) lst)
              i (+ j n)
        )
      )
      (reverse (cons (substr str (1+ i)) lst))
    )
  )
)
    
Jeff_M, also a frequent Swamper
EESignature
Message 6 of 22

Anonymous
Not applicable

Awesome! This definitely gives me everything I need.Smiley Very Happy Thanks!!

0 Likes
Message 7 of 22

treforfjones
Contributor
Contributor

Hi Jeff

I came across your Lisp code with some surprise believing such manipulation of the civil

3d database wasn't possible, a bitter sweet moment, spent last six months learning vb.net.

First question should this still  work in Civil 3d 2018 and if so why does my lisp fall over at this ?

 

(setq profile (vlax-invoke (vlax-get alignment 'profiles) 'Add "NewProfileFromFile" 2 "Basic"))

; error: Civil 3D API: The parameter is incorrect.

I presume it similar to the C# code

ObjectId oProfileId = Profile.CreateByLayout("MyProfile", oAlignment.Id, layerId, styleId, labelSetId);

Any assistance will be greatly appreciated

Kind Regards

Trefor

0 Likes
Message 8 of 22

Jeff_M
Consultant
Consultant
Yes, Trefor, this should still be fine in C3D2018. Does your drawing have the profile style named Basic?
Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 9 of 22

treforfjones
Contributor
Contributor

Hi Jeff

Thanks for the prompt reply

I've enclosed a jpeg of the profile label sets in use ?

cheers

Trefor

 

 

0 Likes
Message 10 of 22

Ranjit_Singh
Advisor
Advisor

The "Basic" in @Jeff_Ms' code is referring to profile style and not label sets. Change the drop-down list above the tree view to either Active Drawing Settings View or Master View, and then look under Profile for the available styles and use one of those styles

prof_styles.png

0 Likes
Message 11 of 22

Jeff_M
Consultant
Consultant

@treforfjones,

The COM API arguments are as follows (from the help file): Profiles.Add(name, profile type, profile style), which is much different than the .NET API counterpart.

Jeff_M, also a frequent Swamper
EESignature
0 Likes
Message 12 of 22

treforfjones
Contributor
Contributor

Hi Jeff

Thanks that code is now working

Have you any similar lisp snippets that convert polylines to alignments

I've spent the last six months learning vb.net. Given your lisp experience

do you think C# is a better bet, long term to learn or

can I achieve a lot more with lisp  ?

cheers

Trefor

 

0 Likes
Message 13 of 22

Jeff_M
Consultant
Consultant

@treforfjones, lisp is limited for use with C3D. All of the API work since C3D 2012 has been for the .NET API. The COM API was last updated/added to in C3D 2012. I much prefer to use c# for .NET development...VB is something I decided to leave back in VBA. 

 

I do still use lisp for small, quick, things, but anything that I want to be fast and powerful I use c#. 

Jeff_M, also a frequent Swamper
EESignature
Message 14 of 22

lu_an_jie
Advocate
Advocate

It doesn't matter which programming language as long it is a .NET language (VB.NET, C# OR F# i.e.). You can even mix and match and creating different libraries in different languages in the same project as long you are targeting the same .NET framework. 

In the Autodesk developer's documentation you can find all the sample code in VB.NET AS WELL AS IN C#. 

Start with whichever language you feel more comfortable personally. The “language part” is something you can learn or re-learn in a matter of 1-3 days. What you are really learning here is the .NET: collections, interfaces, anonymous functions LINQ, MVC, XAML, WPF, Entity Framework and so on and so forth.

 

Here is the C# version for creating a polyline from a single alignment.


Here is same sample code, cha// (C) Copyright 2018 by Andreas Luka using System; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.EditorInput; using Autodesk.Civil.ApplicationServices; using Autodesk.Civil.DatabaseServices; // This line is not mandatory, but improves loading performances [assembly: CommandClass(typeof(LX_PolyLine.MyCommands))] namespace LX_PolyLine { public class MyCommands { // Modal Command with pickfirst selection [CommandMethod("MyGroup", "LX-Polyline", CommandFlags.Modal)] public void AlignToPoly() { // Getting the autodesk database (needed for transaction) Database db = Application.DocumentManager.MdiActiveDocument.Database; // Getting the editor object (needed for error messaging) Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; // Getting the civil document object (need for check of alignments presence) CivilDocument cd = CivilApplication.ActiveDocument; // Getting the list of all alignments in an collection of the ids ObjectIdCollection alignIds = cd.GetAlignmentIds(); // Getting out if there are no alignments in drawing if (alignIds.Count == 0) { ed.WriteMessage("\nNo alignments in drawing."); return; } // Calling function to select a single alignment ObjectId alignId = SelectAlignment(); // Getting out if the selection failes if (alignId == ObjectId.Null) return; // Getting the alignment from his id and creating the polyline using (Transaction tr = db.TransactionManager.StartTransaction()) { try { Alignment align = (Alignment)alignId.GetObject(OpenMode.ForRead); ObjectId plId = align.GetPolyline(); } catch { } tr.Commit(); } } // This function select an Alignment and returns his ObjectId or Null in case of Cancelation or Error public static ObjectId SelectAlignment() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; // Setting ObjectId to Null ObjectId result = ObjectId.Null; // Creating the promt option for a single entity prompt PromptEntityOptions prOptions = new PromptEntityOptions("\nSelect alignment: "); prOptions.SetRejectMessage("...not an Alignment, try again!:"); prOptions.AddAllowedClass(typeof(Alignment), true); // Getting the selected element from the editor PromptEntityResult prResult = ed.GetEntity(prOptions); // Returning the selected alignment's id if (prResult.Status == PromptStatus.OK) result = prResult.ObjectId; return result; } } }

 

Regards

Andreas Luka (Lu An Jie)

http://www.luka-consult.de

Creator of the LX-Stair App for Civil 3D
0 Likes
Message 15 of 22

hosneyalaa
Advisor
Advisor

HI @Jeff_M 

God willing, your health is good

A question ...

I have a road profile

As it is in the picture or drawing

And I wrote in a file notebook
The STATION  AND LEVEL  

OR 

The STATION  AND LEVEL   AND  LENGTH

0 10.406
55 11 21.50
80 9.62 2.38
98.0 9.62

In order to draw it through
Creating profile from file ... Imported and profile drawn

PP.jpg

Capture.JPG

But
When I use the code there is a problem
Could you please
What is the reason? Is writing notepad a mistake

 

Thank you in advance

 

http://www.mediafire.com/file/6qd5vtzgmobmlos/PROFILE+_++CIVIL+2021.dwg/file 

 

 

 

 

0 Likes
Message 16 of 22

Jeff_M
Consultant
Consultant

@hosneyalaa  What problem are you seeing?

Jeff_M, also a frequent Swamper
EESignature
Message 17 of 22

hosneyalaa
Advisor
Advisor

@Jeff_M 

 

 

Command: TEST
Select objects:
; error: AutoCAD.Application: Invalid input
Command:

 

التقاط.PNG 

 

 

(defun c:test ( / ALIGNMENT DATA F LN PROFILE PVI PVIS SS)
(vl-load-com)
(if (setq ss (ssget ":S" '((0 . "AECC_ALIGNMENT"))))
  (progn
    (setq alignment (vlax-ename->vla-object (ssname ss 0)))
    (setq profile (vlax-invoke (vlax-get alignment 'profiles) 'Add "NewProfileFromFile" 2 "Basic")) ;;the 2 is for a FinishGrade profile
    (setq pvis (vlax-get profile 'PVIs))
    (setq	FilePath (getfiled "Select TEXT file to read :"
			   (getvar "dwgprefix")
			   "txt"
			   4
		 )
  )
    (setq f (open FilePath "r"));;this file must be in the format defined by C3D for profiles from a file
    (while (setq ln (read-line f))
      (setq data (str2list ln " "))
      (if (= 2 (length data))
	(setq pvi (vlax-invoke pvis 'add (atof (nth 0 data)) (atof (nth 1 data)) 1 nil nil));;the 1 tells C3D this a Tangent PVI
	(setq pvi (vlax-invoke pvis 'add (atof (nth 0 data)) (atof (nth 1 data)) 3 (atof (nth 2 data)) nil));;the 3 tells C3D it is a parabolic VC
	)
      )
    (close f)
    )
  )
)
;;;str2list by John Uhden, as posted to the adesk customization newsgroup a long time ago
(defun Str2List (str pat / i j n lst)
  (cond
    ((/= (type str)(type pat) 'STR))
    ((= str pat)'(""))
    (T
      (setq i 0 n (strlen pat))
      (while (setq j (vl-string-search pat str i))
        (setq lst (cons (substr str (1+ i)(- j i)) lst)
              i (+ j n)
        )
      )
      (reverse (cons (substr str (1+ i)) lst))
    )
  )
)
    

 

 

 

 

0 10.406
55 11 21.50
80 9.62 2.38
98.0 9.62

 

0 Likes
Message 18 of 22

Jeff_M
Consultant
Consultant

@hosneyalaa Yes, there was an issue due to the vertical curves. You cannot have a VC without 2 tangents, which I did not account for. To solve this, I changed the code so it creates the first and last PVIs before adding the internal PVIs.

 

(defun c:test (/ ALIGNMENT F DATA LN PROFILE PVI PVIS SS)
  (vl-load-com)
  (if (setq ss (ssget ":S" '((0 . "AECC_ALIGNMENT"))))
    (progn
      (setq FilePath (getfiled "Select TEXT file to read :"
			       (getvar "dwgprefix")
			       "txt"
			       4
		     )
      )
      (if filepath
	(progn
	  (setq f (open FilePath "r"))
	  (setq alignment (vlax-ename->vla-object (ssname ss 0)))
	  (setq profile (vlax-invoke (vlax-get alignment 'profiles) 'Add "NewProfileFromFile" 2 "Basic"))
	  ;;the 2 is for a FinishGrade profile
	  (setq pvis (vlax-get profile 'PVIs))
	  ;;this file must be in the format defined by C3D for profiles from a file
	  (while (setq ln (read-line f))
	    (setq data (cons (str2list ln " ") data))
	    )
	  (close f)
	  (setq data (reverse data))
	  ;;create the first and last PVIs before adding the internal PVIs
	  (vlax-invoke pvis 'add (atof (nth 0 (car data))) (atof (nth 1 (car data))) 1 nil nil)
	  (vlax-invoke pvis 'add (atof (nth 0 (last data))) (atof (nth 1 (last data))) 1 nil nil)
	  (setq i 0)
	  (while (< (setq i (1+ i)) (- (length data) 1))
	    (setq d (nth i data))
	    (if (= 2 (length d))
	      (vlax-invoke pvis 'add (atof (nth 0 d)) (atof (nth 1 d)) 1 nil nil)
	      ;;the 1 tells C3D this a Tangent PVI
	      (vlax-invoke pvis 'add (atof (nth 0 d)) (atof (nth 1 d)) 3 (atof (nth 2 d)) nil)
	      ;;the 3 tells C3D it is a parabolic VC
	      )
	    )
	  )
	)
      )
    )
  )

;;;str2list by John Uhden, as posted to the adesk customization newsgroup a long time ago
(defun Str2List	(str pat / i j n lst)
  (cond
    ((/= (type str) (type pat) 'STR))
    ((= str pat) '(""))
    (T
     (setq i 0
	   n (strlen pat)
     )
     (while (setq j (vl-string-search pat str i))
       (setq lst (cons (substr str (1+ i) (- j i)) lst)
	     i	 (+ j n)
       )
     )
     (reverse (cons (substr str (1+ i)) lst))
    )
  )
)
Jeff_M, also a frequent Swamper
EESignature
Message 19 of 22

hosneyalaa
Advisor
Advisor

My teacher mister @Jeff_M 
I am unable to thank you
You are a great person for this problem solving group
Thank you so much

Thank you so much

Thank you so much

Thank you so much

Thank you so much

0 Likes
Message 20 of 22

azhar_abbas9104ZVUC
Explorer
Explorer

VERTICAL FALL TOP AND BOTTOM ELEVATION ISSU

 

0 Likes