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: 

2014 C3D pipe label selection

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
jason.cyr13
844 Views, 7 Replies

2014 C3D pipe label selection

Good afternoon everyone.

 

I was fortunate enough to have some help writing the following code that sets all the ambient layers for pipes and structures to what is required for our submissions.  This saves a ton of clicks when data referencing a pipe network into a drawing.  The code is below:

 

[CommandMethod("SETSS")]

        public void SetSanitaryLayers()
        {
            string LaySan = "41-C-SSWR";   

            CivilDocument doc =
                Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument;

            Editor ed =
                    Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

            Database db = Application.DocumentManager.MdiActiveDocument.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                try //moved try within transaction
                {

                    //Get/Set layer names for pipe

                    ed.WriteMessage("\nPipe Object Layer Set to: " +
                        doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.Pipe).LayerName.ToString());

                    //Now change the DrawingSettings.ObjectLayerSettings
                    doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.Pipe).LayerName = LaySan;
                                        
                    ed.WriteMessage("\nPipe Object Layer Now Set to: " +
                        doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.Pipe).LayerName.ToString());


                    //structures

                    ed.WriteMessage("\nStructure Object Layer Set to: " +
                        doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.Structure).LayerName.ToString());

                    //Now change the DrawingSettings.ObjectLayerSettings
                    doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.Structure).LayerName = LaySan;


                    ed.WriteMessage("\nStructure Object Layer Now Set to: " +
                        doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.Structure).LayerName.ToString());


                    //Plan profile

                    ed.WriteMessage("\nPipe/Structure Profile Object Layer Set to: " +
                        doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.PipeOrStructureProfile).LayerName.ToString());

                    //Now change the DrawingSettings.ObjectLayerSettings
                    doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.PipeOrStructureProfile).LayerName = LaySan;

                    ed.WriteMessage("\nPipe/Structure Profile Object Layer Now Set to: " +
                        doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.PipeOrStructureProfile).LayerName.ToString());


                    //Pipe Network Section

                    ed.WriteMessage("\nPipe Network Section Object Layer Set to: " +
                        doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.PipeNetworkSection).LayerName.ToString());

                    //Now change the DrawingSettings.ObjectLayerSettings
                    doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.PipeNetworkSection).LayerName = LaySan;


                    ed.WriteMessage("\nPipe Network Section Object Layer Now Set to: " +
                        doc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting
                        (Autodesk.Civil.Settings.SettingsObjectLayerType.PipeNetworkSection).LayerName.ToString());


                }

                catch (Exception ex)
                {

                    ed.WriteMessage("\nException Message: " + ex.Message.ToString());

                }
                tr.Commit(); //commit transaction
            } //end transaction
        }

 I would like to extend this code by adding the ability to specify a pipe label style and then entering the command to label the pipes. My goal is to place this command on a tool palette to aid in the drafting of our block plan profiles.  I found a couple of suggestions as visual lisp, but I would like to do this in c# and don't have the background to translate between the languages.  

 

Thanks for all of your help.

 

Jason

Tags (3)
7 REPLIES 7
Message 2 of 8
Jeff_M
in reply to: jason.cyr13

Using PromptEntityOptions with the Allowed Class set to Pipe, ed.GetEntity(), and PromptEntityResult, you could allow the user to select a pipe and Create a PipeLabel on that pipe:

PipeLabel.Create(ObjectId pipeId, double ratio, ObjectId labelStyleId)

 I don't have time right now for a full example, but if you need further help just holler and I'll put something together tonight.

Jeff_M, also a frequent Swamper
EESignature
Message 3 of 8
jason.cyr13
in reply to: jason.cyr13

With this method, I'm assuming that all of the options would be coded into the routine? All of the pipe styles are already in the template. An interesting approach. I'm not near a computer now, but I will see if I can get this to work.

 

Thanks!

 

Jason

Message 4 of 8
Jeff_M
in reply to: jason.cyr13

I had a bit of free time and came up with this. Use it or change as desired, but it does work to label individual pipes with a specific style and the default layer.

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil.DatabaseServices.Styles;
using Autodesk.Civil.Settings;

namespace Civil3D_Misc_Commands.Pipes
{
    public class LabelPipes
    {
        [CommandMethod("QxPipeLabel")]
        public void qxpipelabel()
        {
            string stylename = "Standard"; // replace with desired name to use.
                        Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            CivilDocument civdoc = CivilApplication.ActiveDocument;
            ObjectId styleId = ObjectId.Null;
            LabelStyleCollection lblstyles = civdoc.Styles.LabelStyles.PipeLabelStyles.PlanProfileLabelStyles;
            //make sure the style is defined in the drawing
            if (lblstyles.Contains(stylename))
            {
                //it is, so use it
                styleId = lblstyles[stylename];
            }
            else
            {
                //it isn't, use the default for pipe labeling
                styleId = civdoc.Settings.GetSettings<SettingsCmdAddNetworkPlanLabels>().Styles.PipePlanLabelStyleId.Value;
            }
            string layername = civdoc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting(SettingsObjectLayerType.PipeLabeling).LayerName;
            PromptEntityOptions entOpts = new PromptEntityOptions("\nSelect pipe to label:");
            entOpts.SetRejectMessage("...not a Pipe object, try again!");
            entOpts.AddAllowedClass(typeof(Pipe), true);
            PromptEntityResult entRes = ed.GetEntity(entOpts);
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                while (entRes.Status == PromptStatus.OK)
                {
                    ObjectId lblId = PipeLabel.Create(entRes.ObjectId, 0.5, styleId);
                    PipeLabel pipelbl = (PipeLabel)lblId.GetObject(OpenMode.ForWrite);
                    //the Create method does not honor the ObjectLayer setting, so be sure to set the layer.
                    pipelbl.Layer = layername;
                    entRes = ed.GetEntity(entOpts);
                }
                tr.Commit();
            }
        }
    }
}

 

Jeff_M, also a frequent Swamper
EESignature
Message 5 of 8
jason.cyr13
in reply to: Jeff_M

Jeff,

 

Thanks alot.  This is what I was after.  I was reviewing your code so I could better understand what was going on. I realized that I was missing a few references, so I never would have found what I was looking for. Most of the work my group does is Block Plan Profiles that are submitted to the municipality for review/approval.  Can this code be made to label those parts as well.  It works awesome for plan view, and it totally what I am looking for.  The addition of pipes in profile would finish this off.  I also didn't state that up front, sorry about that.

 

I looked through the Autodesk.Civil.DatabaseServices.Part class and saw a method to draw in profile, but nothing that I could label a part with.  There also wasn't an object I could see in Autodesk.Civil.DatabaseServices.Pipe. (with my limited coding abilities.)  Could this routine be made to label both at once, using an IF statement to tell if it's a pipe or profile pipe?

 

Thanks again for all of your help.  I appreciate the time you are spending to help me.

 

Jason

Message 6 of 8
Jeff_M
in reply to: jason.cyr13


@jason.cyr13 wrote:

Jeff,

 

...Can this code be made to label those parts as well. ....

 

Jason


Yep!

 

        public void qxpipelabel()
        {
            string stylename = "Standard"; // replace with desired name to use.
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            CivilDocument civdoc = CivilApplication.ActiveDocument;
            ObjectId styleId = ObjectId.Null;
            LabelStyleCollection lblstyles = civdoc.Styles.LabelStyles.PipeLabelStyles.PlanProfileLabelStyles;
            //make sure the style is defined in the drawing
            if (lblstyles.Contains(stylename))
            {
                //it is, so use it
                styleId = lblstyles[stylename];
            }
            else
            {
                //it isn't, use the default for pipe labeling
                styleId = civdoc.Settings.GetSettings<SettingsCmdAddNetworkPlanLabels>().Styles.PipePlanLabelStyleId.Value;
            }
            string layername = civdoc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting(SettingsObjectLayerType.PipeLabeling).LayerName;
            PromptEntityOptions entOpts = new PromptEntityOptions("\nSelect pipe to label:");
            entOpts.SetRejectMessage("...not a Pipe object, try again!");
            entOpts.AddAllowedClass(typeof(Pipe), true);
            entOpts.AddAllowedClass(typeof(ProfileViewPart), true);
            PromptEntityResult entRes = ed.GetEntity(entOpts);
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                while (entRes.Status == PromptStatus.OK)
                {
                    if (entRes.ObjectId.ObjectClass.DxfName.ToUpper().Contains("PROFILE"))
                    {
                        ProfileViewPart part = (ProfileViewPart)entRes.ObjectId.GetObject(OpenMode.ForRead);
                        Pipe pipe = (Pipe)part.ModelPartId.GetObject(OpenMode.ForRead);
                        ObjectId pvId = ObjectId.Null;
                        foreach (ObjectId id in pipe.GetProfileViewsDisplayingMe())
                        {
                            double sta = 0, off = 0;
                            ProfileView pv = (ProfileView)id.GetObject(OpenMode.ForRead);
                            if (pv.FindStationAndElevationAtXY(entRes.PickedPoint.X, entRes.PickedPoint.Y, ref sta, ref off))
                            {
                                pvId = id;
                                break;
                            }
                        }
                        ObjectId lblId = PipeProfileLabel.Create(entRes.ObjectId, pvId, 0.5, styleId);
                        PipeProfileLabel pipelbl = (PipeProfileLabel)lblId.GetObject(OpenMode.ForWrite);
                        //the Create method does not honor the ObjectLayer setting, so be sure to set the layer.
                        pipelbl.Layer = layername;
                    }
                    else
                    {
                        ObjectId lblId = PipeLabel.Create(entRes.ObjectId, 0.5, styleId);
                        PipeLabel pipelbl = (PipeLabel)lblId.GetObject(OpenMode.ForWrite);
                        //the Create method does not honor the ObjectLayer setting, so be sure to set the layer.
                        pipelbl.Layer = layername;
                    }
                    entRes = ed.GetEntity(entOpts);
                }
                tr.Commit();
            }
        }

 

 

Jeff_M, also a frequent Swamper
EESignature
Message 7 of 8
jason.cyr13
in reply to: Jeff_M

That did the trick!  Thank you! 😄

 

I noticed there was a lot more code to drill down to the profile pipe.  Is that because we have to open the object container before we can check what the pipe is?  That would make the most sense.  The plan pipes don't require that because they are already in the drawing database, but aren't in a separate container.  I get it now.

 

Thanks again!

Jason

 

 

Message 8 of 8
Jeff_M
in reply to: jason.cyr13

Yeah, I don't quite understand why the profilepart object doesn't have a property exposed that says which profile view it is in. So in order to pass the PVId to the PipeProfileLabel.Create() method I had to jump through the hoops you see.
Jeff_M, also a frequent Swamper
EESignature

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

Post to forums  

Rail Community


Autodesk Design & Make Report