[c# ORD] how to loop elements within a profile?

how do you find a profile model and loop through the elements inside a given profile model. the GeometricModel doesnt seem to let me get to whats inside these non-indexed models. they dont show up as models in the models collection. any one point me in the right direction?

Parents Reply Children
  • Hi John,

    Typically I get the profile object from an alignment object.  I have a dialog box that populates a listbox with all the alignment names found in the geometric models.  When I select an alignment in the listbox I populate another listbox with the profiles contained in the alignment object.  Finally when I select a profile I get the profile data into the basic PVI format (station, elevation, and curve length). 

    Code for populating the alignment listbox lstAlignments

                ConsensusConnection sdkCon = new Bentley.CifNET.SDK.ConsensusConnection(Session.Instance.GetActiveDgnModel());
                if (sdkCon == null)
                    return;
    
    
                UorPerMaster = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster;
                xFac = UorPerMaster; // * MeterToMaster;
    
                List<GeometricModel> models = sdkCon.GetAllGeometricModels().ToList();
    
                lstData.Items.Add("models count" + " : " + models.Count.ToString());
                    lstData.Items.Add(" Meter to Master = " + MeterToMaster.ToString());
                    lstData.Items.Add(" UorPerMaster = " + UorPerMaster.ToString());
    
                foreach (GeometricModel gm in models)
                {
                    lstData.Items.Add(gm.DgnModel.ModelName + " : " + gm.DgnModel.GetDgnFile().GetFileName());
                    lstData.Items.Add(" align count = " + gm.Alignments.Count().ToString());
                    //gm.GetAlignmentByName()
                    foreach (Alignment align in gm.Alignments)
                    {
                        if (align.IsFinalElement && align.Name != string.Empty)
                        {
                            if (!dictAlignments.Keys.Contains(align.Name))
                            {
                                lstAlignments.Items.Add(align.Name);
                                dictAlignments.Add(align.Name, align);
                            }
                        }
                    }
                }
    

    Code for populating the profile listbox lstProfiles

                string sName = lstAlignments.Text;
    
                if (!dictAlignments.TryGetValue(sName, out Alignment alignFound))
                    return;
    
    
    
                if (alignFound == null)
                    return;
    
                foreach (Profile prof in alignFound.Profiles)
                {
                    if (prof.IsFinalElement && prof.Name != string.Empty)
                    {
                        lstProfiles.Items.Add(prof.Name);
                        dictProfiles.Add(prof.Name, prof);
                    }
                }
    

    Code for sifting through profile object data and getting into the PVI format.  A 3 step process.

            private void lstProfiles_SelectedIndexChangedForum(object sender, EventArgs e)
            {
                lstData.Items.Clear();
                listPRF.Clear();
    
                string sNameA = lstAlignments.Text;
                string sNameP = lstProfiles.Text;
    
                if (!dictAlignments.TryGetValue(sNameA, out Alignment align))
                    return;
    
                if (!dictProfiles.TryGetValue(sNameP, out Profile prof))
                    return;
    
                double sta = 0.0;
                try
                {
                    sta = align.Stationing.StartStation;
                    sta *= MeterToMaster;
                }
                catch
                {
    
                }
    
    
                lstData.Items.Add((sta).ToString());
    
                List<double> verts1 = new List<double>();
                List<double> elevs1 = new List<double>();
                List<double> verts2 = new List<double>();
                List<double> elevs2 = new List<double>();
                List<double> vertsF = new List<double>();
                List<double> elevsF = new List<double>();
                List<double> lensF = new List<double>();
    
                double xPrev = -10000.0;
    
                //---- Step 1 Get LineString vertices
    
                for (int i = 0; i < prof.ProfileGeometry.LineStringVertices.Count(); i++)
                {
                    DPoint3d pt3 = prof.ProfileGeometry.LineStringVertices[i];
    
                    if (pt3.X != xPrev)
                    {
                        double staAdd = sta + pt3.X * MeterToMaster;
                        verts1.Add(staAdd);
                        elevs1.Add(pt3.Y * MeterToMaster);
    
                        lstData.Items.Add(staAdd.ToString("0+00.0000") + "    " + (pt3.Y * MeterToMaster).ToString()); // + "," + (pt3.Z * MeterToMaster).ToString()); // + "," + bulge.ToString());
                    }
                    xPrev = pt3.X;
                }
    
                //---- Step 2 Get vertical curve vertices
    
                LinearPointCollection lpc = prof.ProfileGeometry.GetVerticalControlPoints(VerticalControlPointTypes.Curve_PI);
                lstData.Items.Add("-------------------");
                lstData.Items.Add("count = " + lpc.Count.ToString());
    
                foreach (LinearPoint pt in prof.ProfileGeometry.GetVerticalControlPoints(Bentley.CifNET.LinearGeometry.VerticalControlPointTypes.Curve_PI))
                {
                    double staAdd = sta + pt.Coordinates.X * MeterToMaster;
                    verts2.Add(staAdd);
                    elevs2.Add(pt.Coordinates.Y * MeterToMaster);
    
                    lstData.Items.Add(staAdd.ToString("0+00.0000") + "    " + (pt.Coordinates.Y * MeterToMaster).ToString()); // + ", " + (pt.ChordDistance * MeterToMaster).ToString()); // + "," + bulge.ToString());
                }
                lstData.Items.Add("-------------------");
    
                //---- Step 3 : Proccess data from steps 1 and 2
    
                if (lpc.Count == 0)
                {
                    for (int i = 0; i < verts1.Count - 1; i++)
                    {
                        vertsF.Add(verts1[i]);
                        elevsF.Add(elevs1[i]);
                        lensF.Add(0.0);
                    }
                }
                else
                {
    
                    int jcur = 0;
                    for (int i = 0; i < verts2.Count; i++)
                    {
                        double staCur = verts2[i];
                        double elCur = elevs2[i];
    
                        for (int j = jcur; j < verts1.Count - 1; j++)
                        {
                            double sta1 = verts1[j];
                            double sta2 = verts1[j + 1];
                            if (sta1 < staCur && staCur < sta2)
                            {
                                vertsF.Add(staCur);
                                elevsF.Add(elCur);
                                lensF.Add(sta2 - sta1);
                                jcur = j + 2;
                                j = 100000;
                            }
                            else
                            {
                                vertsF.Add(sta1);
                                elevsF.Add(elevs1[j]);
                                lensF.Add(0.0);
                            }
                        }
    
                        if (i == verts2.Count - 1)   // add pvi's after last curve
                        {
                            for (int j = jcur; j < verts1.Count - 1; j++)
                            {
                                vertsF.Add(verts1[j]);
                                elevsF.Add(elevs1[j]);
                                lensF.Add(0.0);
                            }
                        }
                    }
                }
                vertsF.Add(verts1.Last());
                elevsF.Add(elevs1.Last());
                lensF.Add(0.0);
    
                for (int i = 0; i < vertsF.Count; i++)
                {
                    string sLine = vertsF[i].ToString("0+00.0000") + "    " + elevsF[i].ToString() + "   " + lensF[i].ToString();
                    lstData.Items.Add(sLine);
                    listPRF.Add(new DPoint3d(vertsF[i], elevsF[i], lensF[i]));
                }
            }
    

    I have my own profile object (copied over from my c# Civil 3D code) that I populate with the PVI data from above.  I have a number of functions in my profile object that gets me my desired data from the PVI's.  Here is my dialog box and selected profile

    You also asked about getting profiles from the models.  I've been working on understanding models, viewports, and views.  It's a work in progress.  Here's what I've got when the alignments / profiles are in the file.  Still working on the case when they are in an xref.  The dynamic profile view is active.  Note I'm also investigating the dynamic x-section view too.

            private void _UpdateInfoForum()
            
                lstModels.Items.Clear();
                lstViews.Items.Clear();
    
    
                mActiveDgnFile = Session.Instance.GetActiveDgnFile();
                mActiveModel = Session.Instance.GetActiveDgnModel();
    
                try
                {
                    foreach (ModelIndex mi in mActiveDgnFile.GetModelIndexCollection())
                    {
                        lstModels.Items.Add(mi.Name + " : " + mi.Description);
                    }
    
                    Viewport vp = Session.GetActiveViewport();
                    int ai = vp.ViewNumber;
    
    
                    ConsensusConnectionEdit Connection = Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit.GetActive();
    
                    lstViews.Items.Add("ActiveVPnumber = " + ai.ToString());
                    lstViews.Items.Add("View Name = " + vp.GetViewName());
                    lstViews.Items.Add("Root Model Name = " + vp.GetRootModel().ModelName);
                    lstViews.Items.Add("Root Model Id = " + vp.GetRootModel().GetModelId().ToString());
                    lstViews.Items.Add("VP Type = " + vp.GetType().ToString());
    
                    lstViews.Items.Add("== Elements ========= ");
    
                    foreach (Element elem in vp.GetRootModel().GetElements())
                    {
                        if (vp.GetRootModel().ModelName == "Cross Section")
                        {
                            lstViews.Items.Add(elem.ElementType.ToString());
                            lstViews.Items.Add("++ " + elem.Description);
    
                            if (elem.ElementType == MSElementType.ReferenceAttachment)
                            {
                                DgnAttachment attach = mActiveModel.FindDgnAttachmentByElementId(elem.ElementId);
                                lstViews.Items.Add(attach.AttachFileName);
                                lstViews.Items.Add(attach.GetDgnFile().GetFileName());
                            }
                        }
                        else
                        {
                            if (elem.ElementType == MSElementType.MicroStation)
                                continue;
    
                            if (elem.ElementType == MSElementType.Line)
                                continue;
    
                            if (elem.ElementType == MSElementType.BsplineCurve)
                                continue;
    
                            if (elem.ElementType == MSElementType.ComplexString)
                            {
                                lstViews.Items.Add(elem.ElementType.ToString());
                                lstViews.Items.Add("++ " + elem.Description);
    
                                Profile prf = (elem.ParentElement == null) ? Profile.CreateFromElement(Connection, elem) : Profile.CreateFromElement(Connection, elem.ParentElement);
                                if (prf != null)
                                    lstViews.Items.Add("   prf name = " + prf.Name);
                            }
    
                            if (elem.ElementType == MSElementType.ReferenceAttachment)
                            {
                                DgnAttachment attach = mActiveModel.FindDgnAttachmentByElementId(elem.ElementId);
                                lstViews.Items.Add(attach.AttachFileName);
                                lstViews.Items.Add(attach.GetDgnFile().GetFileName());
                            }
                        }
                    }
                    lstViews.Items.Add("== Elements ========= ");
                }
                catch
                {
                }
            }

    RootModel is the key here.  I sift though all the elements in the RootModel to find the profiles.

    Regards,

    Andrew