Wednesday, February 06, 2013

Getting Civil 3D Objects From XREFs

While not advised, it is possible to get Civil 3D objects from an XREF. I’m not sure of the ramifications of modifying object after getting them in this manner, but one is able to read the Civil 3D object’s information. The code below goes and gets a variety of objects from an XREF and returns their ObjectIds. I even limit the returned values based on the layer they are on.

   1:          private static void FindObjectsInXREF(GraphNode root, string layerName, string xrefName, out List<ObjectId> polyObjIds)

   2:          {

   3:              polyObjIds = new List<ObjectId>();

   4:              for (int o = 0; o < root.NumOut; o++)

   5:              {

   6:                  XrefGraphNode child = root.Out(o) as XrefGraphNode;

   7:                  if (child.XrefStatus == XrefStatus.Resolved && child.Name == xrefName)

   8:                  {

   9:                      BlockTableRecord bl = child.BlockTableRecordId.GetObject(OpenMode.ForRead) as BlockTableRecord;

  10:                      foreach (ObjectId objId in bl)

  11:                      {

  12:                          Autodesk.AutoCAD.DatabaseServices.Entity ent = objId.GetObject(OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Entity;

  13:                          Type entType = ent.GetType();

  14:                          if (ent.Layer == xrefName + "|" + layerName && (entType == typeof(Polyline) || 

  15:                                                                          entType == typeof(Polyline) || 

  16:                                                                          entType == typeof(Alignment) || 

  17:                                                                          entType == typeof(Polyline3d) || 

  18:                                                                          entType == typeof(Polyline2d)))

  19:                          {

  20:                              polyObjIds.Add(objId);

  21:                          }

  22:                      }

  23:                  }

  24:              }

  25:          }


Tuesday, February 05, 2013

Select Viewport

Here’s some code to select a viewport. I’ve made an extension to the Editor class. this way I can easily call it from other code. Most of the rest of the code was taken from an internet search when I was coding for viewport selection. I’m unsure of the original source, although a search of words finds it in numerous locations.

        public static ObjectId SelectViewport(this Editor ed, string promptString)
ObjectId viewportObjId = ObjectId.Null;
PromptEntityOptions opt = new PromptEntityOptions("\n" + promptString);
opt.SetRejectMessage("\nObject must be a viewport.\n");
opt.AddAllowedClass(typeof(Viewport), true);
//next lines are to allow for non-rectangular viewport selection
opt.AddAllowedClass(typeof(Circle), true);
opt.AddAllowedClass(typeof(Polyline), true);
opt.AddAllowedClass(typeof(Polyline2d), true);
opt.AddAllowedClass(typeof(Polyline3d), true);
opt.AddAllowedClass(typeof(Ellipse), true);
opt.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Region), true);
opt.AddAllowedClass(typeof(Spline), true);
opt.AddAllowedClass(typeof(Face), true);
PromptEntityResult viewportResult = ed.GetEntity(opt);

if (viewportResult.Status == PromptStatus.OK)
Entity ent = viewportResult.ObjectId.GetObject(OpenMode.ForRead) as Entity;
// It is a rectangular viewport.
if (ent.GetType() == typeof(Viewport))
viewportObjId = viewportResult.ObjectId;
else if (true)
//Viewport is non-rectangular, attempt to get it from the selected clip entity
ObjectId vpId = LayoutManager.Current.GetNonRectangularViewportIdFromClipId(viewportResult.ObjectId);
if (vpId != ObjectId.Null)
viewportObjId = vpId;
return viewportObjId;

It also provides a nice example to limit different types of objects during selection. Just remove the opt.AddAllowedClass(typeof(Spline), true);  you don’t need and add the classes you want the user to select. It makes it easy so you have to worry less about the user selecting the wrong type of object. Just make sure to provide the error warning message first.


Blog Widget by LinkWithin