/// <summary> /// Get nested families are nested in Document /// </summary> /// <param name="famDoc"></param> /// <param name="GetNonSharedFamilies"></param> /// <returns></returns> private List <FamilyInfo> GetNestedFamilies(Document famDoc, bool GetNonSharedFamilies) { List <FamilyInfo> fams = new List <FamilyInfo>(); List <Family> fis = new FilteredElementCollector(famDoc) .WhereElementIsNotElementType() .OfClass(typeof(Family)) .Cast <Family>() .ToList(); foreach (Family fam in fis) { if (!fam.IsEditable) { continue; } int IsShared = fam.get_Parameter(BuiltInParameter.FAMILY_SHARED).AsInteger(); if (!GetNonSharedFamilies && IsShared == 0) { continue; } Document nestedFamDoc = famDoc.EditFamily(fam); FamilyInfo nestedFi = new FamilyInfo(nestedFamDoc); fams.Add(nestedFi); nestedFamDoc.Close(false); } return(fams); }
/// <summary> /// Eliminate Ids shift (in case that family is opened from the project or other family) /// Dummy and stupid idea, but this is the best what I invent /// forums.autodesk.com/t5/revit-api-forum/id-of-elements-is-changes-when-a-family-is-opened-from-a-project/ /// </summary> /// <param name="idOffset"></param> public void ApplyIdOffset(FamilyInfo baseFi) { //old id value, id value after renumber Dictionary <int, int> idsRenumbInfo = new Dictionary <int, int>(); int dimsMinCount = Math.Min(this.List_FamilyDimensions.Count, baseFi.List_FamilyDimensions.Count); for (int i = 0; i < dimsMinCount; i++) { idsRenumbInfo.Add(this.List_FamilyDimensions[i].Id, baseFi.List_FamilyDimensions[i].Id); this.List_FamilyDimensions[i].Id = baseFi.List_FamilyDimensions[i].Id; } int refPlanesMinCount = Math.Min(this.List_RefPlanes.Count, baseFi.List_RefPlanes.Count); for (int i = 0; i < refPlanesMinCount; i++) { idsRenumbInfo.Add(this.List_RefPlanes[i].Id, baseFi.List_RefPlanes[i].Id); this.List_RefPlanes[i].Id = baseFi.List_RefPlanes[i].Id; } int curvesMinCount = Math.Min(this.List_Curves.Count, baseFi.List_Curves.Count); for (int i = 0; i < curvesMinCount; i++) { idsRenumbInfo.Add(this.List_Curves[i].Id, baseFi.List_Curves[i].Id); this.List_Curves[i].Id = baseFi.List_Curves[i].Id; } int formsMinCount = Math.Min(this.List_Forms.Count, baseFi.List_Forms.Count); for (int i = 0; i < formsMinCount; i++) { idsRenumbInfo.Add(this.List_Forms[i].Id, baseFi.List_Forms[i].Id); this.List_Forms[i].Id = baseFi.List_Forms[i].Id; int sketchesMinCount = Math.Min( this.List_Forms[i].List_Profiles.Count, baseFi.List_Forms[i].List_Profiles.Count); for (int j = 0; j < sketchesMinCount; j++) { idsRenumbInfo.Add( this.List_Forms[i].List_Profiles[j].Id, baseFi.List_Forms[i].List_Profiles[j].Id); this.List_Forms[i].List_Profiles[j].Id = baseFi.List_Forms[i].List_Profiles[j].Id; } } //next time, I need to renumber Ids in internal references foreach (FamilyDimension fdim in this.List_FamilyDimensions) { fdim.List_ReferenceElementIds = ApplyRenumbering(fdim.List_ReferenceElementIds, idsRenumbInfo); } foreach (Geometry.GeometryCurve curve in this.List_Curves) { curve.List_AdjoinedElementsEnd0 = ApplyRenumbering(curve.List_AdjoinedElementsEnd0, idsRenumbInfo); curve.List_AdjoinedElementsEnd1 = ApplyRenumbering(curve.List_AdjoinedElementsEnd1, idsRenumbInfo); } foreach (Geometry.FamilyGeometryForm form in this.List_Forms) { foreach (Geometry.GeometrySketch sketch in form.List_Profiles) { if (idsRenumbInfo.ContainsKey(sketch.Id)) { sketch.Id = idsRenumbInfo[sketch.Id]; } if (idsRenumbInfo.ContainsKey(sketch.ReferencePlaneId)) { sketch.ReferencePlaneId = idsRenumbInfo[sketch.ReferencePlaneId]; } sketch.List_CurveIds = ApplyRenumbering(sketch.List_CurveIds, idsRenumbInfo); } } }