API add surface as a Hide Boundaries

API add surface as a Hide Boundaries

Dexterel
Collaborator Collaborator
2,418 Views
8 Replies
Message 1 of 9

API add surface as a Hide Boundaries

Dexterel
Collaborator
Collaborator

In Civil 3D we can add a surface as a hide boundary.

How can I do this using Civil API?

I try Surface.BoundariesDefinition.AddBoundaries() method but it does not support this functionality.

0 Likes
Accepted solutions (1)
2,419 Views
8 Replies
Replies (8)
Message 2 of 9

hippe013
Advisor
Advisor

I was able to create a hide boundary using the following:

 

<CommandMethod("SurfaceAddHideBoundary")>
 Public Sub CmdSurfaceAddHideBoundary()
   GetCurrent() 'Get aDoc, ed & db

   Dim opts As New PromptEntityOptions(vbCrLf + "Select Surface: ")
opts.SetRejectMessage(vbCrLf + "Must be a Surface: ") opts.AddAllowedClass(GetType(TinSurface), True) Dim res As PromptEntityResult = ed.GetEntity(opts) If res.Status = PromptStatus.OK Then Dim surfId As ObjectId = res.ObjectId opts = New PromptEntityOptions(vbCrLf + "Select Polyline: ") opts.SetRejectMessage(vbCrLf + "Must be a Polyline: ") opts.AddAllowedClass(GetType(Polyline), True) res = ed.GetEntity(opts) If res.Status = PromptStatus.OK Then Dim objIdCol As New ObjectIdCollection From {res.ObjectId} Using tr As Transaction = db.TransactionManager.StartTransaction Dim surf As TinSurface = tr.GetObject(surfId, OpenMode.ForWrite)
surf.BoundariesDefinition.AddBoundaries(objIdCol, 0.1, SurfaceBoundaryType.Hide, True) surf.Rebuild() tr.Commit()
End Using End If End If End Sub
Message 3 of 9

Dexterel
Collaborator
Collaborator
Thank you for your replay, but you totally miss the point.
I don't want to add a polyLine or pointCollection as a boundary's.
I need to add a surface as a Hide Boundary.
In Civil you can do this. If you select add Boundaries type hide( first image), at command line you can chose to select a Surface (please see second image).
I need to duplicate this behavior using API.
0 Likes
Message 4 of 9

Dexterel
Collaborator
Collaborator

Maybe it's not possible using the available methods in Civil API.

A confirmation would be welcome for me to stop looking for this and start the workaround.

0 Likes
Message 5 of 9

hippe013
Advisor
Advisor

Wouldn't that just simply be to extract the outer boundary of one surface and add that polyline to the boundary definitions of another as a hide boundary? 

0 Likes
Message 6 of 9

Dexterel
Collaborator
Collaborator

almost, but it does not work if my surface has holes in it.

I will need to identify if boundary is show or hide and I don't have a good idea how to do this.

0 Likes
Message 7 of 9

lu_an_jie
Advocate
Advocate

You are on the right track but you also need to process the information from the BoundaryDefinitions of the surface.

I  am working on a sample code, I may finish it tomorrow evening

Regards

Andreas Luka (Lu An Jie)

http://www.luka-consult.de

Creator of the LX-Stair App for Civil 3D
Message 8 of 9

lu_an_jie
Advocate
Advocate
Accepted solution
using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;


using Autodesk.Civil;
using Autodesk.Civil.DatabaseServices;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices.Styles;

namespace ALC_SurfaceBoundery
{
    public class MyCommands
    {
        public static ObjectId SelectSurface()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            ObjectId result = ObjectId.Null;

            PromptEntityOptions entOpts = new PromptEntityOptions("\nSelect surface: ");
            entOpts.SetRejectMessage("...not a surface, try again!:");
            entOpts.AddAllowedClass(typeof(TinSurface), true);

            PromptEntityResult entRes = ed.GetEntity(entOpts);

            if (entRes.Status == PromptStatus.OK) result = entRes.ObjectId;

            return result;
        }


        [CommandMethod("alcSurfaceBounderyFromSurface")]
        public void alcSB()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            CivilDocument civdoc = CivilApplication.ActiveDocument;
            Database db = Application.DocumentManager.MdiActiveDocument.Database;
            Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;

            ed.WriteMessage("\nFirst surface:");
            ObjectId idSurface1= SelectSurface();
            if (idSurface1 == ObjectId.Null) return;

            ed.WriteMessage("\nSecond surface:");
            ObjectId idSurface2 = SelectSurface();
            if (idSurface2 == ObjectId.Null) return;

            using (Transaction trans = tm.StartTransaction())
            {
                try
                {
                    TinSurface s1 = tm.GetObject(idSurface1, OpenMode.ForWrite) as TinSurface;
                    TinSurface s2 = tm.GetObject(idSurface2, OpenMode.ForRead) as TinSurface;
                    ObjectIdCollection objIdCol1 = new ObjectIdCollection ();

                    // list all boundaries off surface 2 from definition 
                    if (s2.BoundariesDefinition.Count > 0)
                    {
                        for (int i = 0; i < s2.BoundariesDefinition.Count; i++)
                        {
                            SurfaceOperationAddBoundary soab = s2.BoundariesDefinition[i];

                            ed.WriteMessage("\n {0}, Type {1}, ", soab.Name.ToString(), soab.BoundaryType.ToString());
                            foreach (SurfaceBoundary sb in soab)
                            {
                                Point3dCollection v = sb.Vertices;
                                ed.WriteMessage(" Vertices: {0}", v.Count);
                                for (int j = 0; j < v.Count; j++)
                                {
                                    ed.WriteMessage("\n" + v[j].ToString());
                                }
                            }

                        }
                    }

                    // check for outer boundery in the Surface defenitions
                    bool isOuterBounderyDefined = false;
                    if (s2.BoundariesDefinition.Count > 0)
                    {
                        for (int i = 0; i < s2.BoundariesDefinition.Count; i++)
                        {
                            SurfaceOperationAddBoundary soab = s2.BoundariesDefinition[i];

                            if (soab[0].BoundaryType == SurfaceBoundaryType.Outer)
                            {
                                Point3dCollection v = soab[0].Vertices;
                                isOuterBounderyDefined = true;
                                // add the vertices as hide boundery to surface 1
                                s1.BoundariesDefinition.AddBoundaries(v, 0.1, SurfaceBoundaryType.Hide, true);
                                ed.WriteMessage("\nOuter boundary found");
                                break;
                            }
                        }
                    }

                    if (!isOuterBounderyDefined)
                    {
                        ed.WriteMessage("\nNo outer boundary found, will be created by Extract Border");

                        // extracte border from surface 2 and add as  hide boundary to surface 1

                        // create a new style called 'example style':
                        ObjectId idStyle = civdoc.Styles.SurfaceStyles.Add("Extraction");

                        // modify the style to display boundaries, exterior only:
                        SurfaceStyle ss = idStyle.GetObject(OpenMode.ForWrite) as SurfaceStyle;
                        ss.GetDisplayStylePlan(SurfaceDisplayStyleType.Boundary).Visible = true;
                        ss.BoundaryStyle.DisplayExteriorBoundaries = true;
                        ss.BoundaryStyle.DisplayInteriorBoundaries = false;

                        // assign this style to the  surface 
                        ObjectId idCurrent = s2.StyleId;
                        s2.StyleId = idStyle;

                        //extract the exterior border
                        ObjectIdCollection borders = s2.ExtractBorder(SurfaceExtractionSettingsType.Plan);
                        s1.BoundariesDefinition.AddBoundaries(borders, 0.1, SurfaceBoundaryType.Hide, true);

                        // change back the style
                        s2.StyleId = idStyle;
                        civdoc.Styles.SurfaceStyles.Remove("Extraction");
                    }


                    // process show and hide boundaries
                    if (s2.BoundariesDefinition.Count > 0)
                    {
                        for (int i = 0; i < s2.BoundariesDefinition.Count; i++)
                        {
                            if (s2.BoundariesDefinition[i].BoundaryType == SurfaceBoundaryType.Hide)
                            {
                                Point3dCollection v = s2.BoundariesDefinition[i][0].Vertices;
                                // add the vertices as show boundery to surface 1
                                ed.WriteMessage("\n Innner boundary (hole) found with {0} vertices", v.Count);
                                for (int j = 0; j < v.Count; j++)
                                {
                                    ed.WriteMessage("\n"  + v[j].ToString());
                                }
                                s1.BoundariesDefinition.AddBoundaries(v, 0.1, SurfaceBoundaryType.Show, true);
                            }
                            if (s2.BoundariesDefinition[i].BoundaryType == SurfaceBoundaryType.Show)
                            {
                                Point3dCollection v = s2.BoundariesDefinition[i][0].Vertices;
                                // add the vertices as show boundery to surface 1
                                ed.WriteMessage("\n innner boundary (island) found with {0} verices", v.Count);
                                s1.BoundariesDefinition.AddBoundaries(v, 0.1, SurfaceBoundaryType.Hide, true);
                            }
                        }
                    }

                    s1.Rebuild();

                }
                catch
                {
                    ed.WriteMessage("\n Does not work");
                }
                trans.Commit();
            }

        }
    }
}

With surfaces that has polylines as boundaries it works well, but I could not figure out yet how to handle if your surface for creating the boundary is also build by surfaces as boundaries. 

Regards

Andreas Luka (Lu An Jie)

http://www.luka-consult.de

Creator of the LX-Stair App for Civil 3D
Message 9 of 9

Dexterel
Collaborator
Collaborator

Thank you so much. Your code dose not really work as expected.

I work with civil 3D for server years and didn't know you can show interior or exterior boundaries only. I learn something very valuable today.

Your Surface Style is all I need, it`s amazing.

 

 

 

                        ObjectId idStyle = civdoc.Styles.SurfaceStyles.Add("HideBoundaries");
                        SurfaceStyle ss = idStyle.GetObject(OpenMode.ForWrite) as SurfaceStyle;
                        ss.GetDisplayStylePlan(SurfaceDisplayStyleType.Boundary).Visible = true;
                        ss.BoundaryStyle.DisplayExteriorBoundaries = false;
                        ss.BoundaryStyle.DisplayInteriorBoundaries = true;

 

0 Likes