Ok so as I told you the code provided work perfectly in Revit 2016
To make the same approach from the Project document use the following code:
#region Namespaces using System; using System.Text; using System.Linq; using System.Xml; using System.Reflection; using System.ComponentModel; using System.Collections; using System.Collections.Generic; using System.Windows; using System.Windows.Media.Imaging; using System.Windows.Forms; using System.IO; using Autodesk.Revit.ApplicationServices; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Events; using Autodesk.Revit.DB.Architecture; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Electrical; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using Autodesk.Revit.UI.Events; //using Autodesk.Revit.Collections; using Autodesk.Revit.Exceptions; using Autodesk.Revit.Utility; using RvtApplication = Autodesk.Revit.ApplicationServices.Application; using RvtDocument = Autodesk.Revit.DB.Document; #endregion namespace RevitAddinCS2 { [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class ExtCmd : IExternalCommand { #region Cached Variables private static ExternalCommandData _cachedCmdData; public static UIApplication CachedUiApp { get { return _cachedCmdData.Application; } } public static RvtApplication CachedApp { get { return CachedUiApp.Application; } } public static RvtDocument CachedDoc { get { return CachedUiApp.ActiveUIDocument.Document; } } #endregion #region IExternalCommand Members public Result Execute(ExternalCommandData cmdData, ref string msg, ElementSet elemSet) { _cachedCmdData = cmdData; try { FilteredElementCollector fam = new FilteredElementCollector(CachedDoc).OfClass(typeof(Family)); var fams = from family in fam where (family.Name == "ImportedObj_corrected") select family; List<Family> fa= fams.Cast<Family>().ToList(); foreach (Family f in fa) { if (f.IsEditable) { Document familyDoc = CachedDoc.EditFamily(f); //TODO: add your code below. FilteredElementCollector importCAD = new FilteredElementCollector(familyDoc).OfClass(typeof(ImportInstance)); ElementId ImportedObj = importCAD.FirstElementId(); if(AddConnectorToFamily(familyDoc, ImportedObj)) { familyDoc.LoadFamily(CachedDoc,new FamilyOption()); } } } return Result.Succeeded; } catch (Exception ex) { msg = ex.ToString(); return Result.Failed; } } public bool AddConnectorToFamily(Document famDoc, ElementId importedId) { //Connector Values. XYZ connNormal = new XYZ(0, 0, 1); XYZ connDirection = new XYZ(1, 0, 0); XYZ connOrigin = new XYZ(-24.022405238, -59.669659519, 9.583333333); PlanarFace pf = null; Options opts = famDoc.Application.Create.NewGeometryOptions(); opts.DetailLevel = ViewDetailLevel.Fine; opts.ComputeReferences = true; //This is a little redundant. Element e = famDoc.GetElement(importedId); ImportInstance impInst = e as ImportInstance; //To access the Geometry of the Imported DWG block //We need to dig into it a little bit. GeometryElement impGeo = impInst.get_Geometry(opts); foreach (GeometryObject impGeoObj in impGeo) { GeometryInstance symInst = impGeoObj as GeometryInstance; GeometryElement symEle = symInst.SymbolGeometry; using (Transaction t = new Transaction(famDoc, "edit")) { t.Start(); foreach (GeometryObject symObj in symEle) { Solid solid = symObj as Solid; if (solid != null) { FaceArray fa = solid.Faces; foreach (Face f in fa) { pf = f as PlanarFace; if ((pf != null) && (IsParallel(connDirection, pf.FaceNormal))) { if (pf.Origin.IsAlmostEqualTo(connOrigin)) { using (SubTransaction refTrans = new SubTransaction(famDoc)) { refTrans.Start(); ConnectorElement.CreateDuctConnector(famDoc, DuctSystemType.Global, ConnectorProfileType.Round, pf.Reference, pf.EdgeLoops.get_Item(0).get_Item(0)); refTrans.Commit(); } } } } } } t.Commit(); } } famDoc.Save(); return true; } const double _eps = 1.0e-9; /// <summary> /// Check whether two real numbers are equal /// </summary> static public bool IsEqual(double a, double b) { return Math.Abs(a - b) < _eps; } /// <summary> /// Check whether two vectors are parallel /// </summary> static public bool IsParallel(XYZ a, XYZ b) { double angle = a.AngleTo(b); return _eps > angle || IsEqual(angle, Math.PI); } #endregion class FamilyOption : IFamilyLoadOptions { bool IFamilyLoadOptions.OnFamilyFound(bool familyInUse, out bool overwriteParameterValues) { overwriteParameterValues = true; return true; } bool IFamilyLoadOptions.OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues) { source = FamilySource.Family; overwriteParameterValues = true; return true; } } } }
You can follow the modifications I made to adjust your code.
I also make some correction to the Family insertion point.