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.
¯\_(ツ)_/¯
Let it work like a charm.
Mustafa Salaheldin


Digital Integration Manager, DuPod
Facebook |
Twitter |
LinkedIn