public override Value Evaluate(FSharpList<Value> args) { FSharpList<Value> pts = ((Value.List)args[0]).Item; FamilySymbol fs = (FamilySymbol)((Value.Container)args[1]).Item; FamilyInstance ac = null; //if the adapative component already exists, then move the points if (Elements.Any()) { //mutate Element e; //...we attempt to fetch it from the document... if (dynUtils.TryGetElement(this.Elements[0], typeof(FamilyInstance), out e)) { ac = e as FamilyInstance; ac.Symbol = fs; } else { //create ac = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(dynRevitSettings.Doc.Document, fs); Elements[0] = ac.Id; } } else { //create ac = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(dynRevitSettings.Doc.Document, fs); Elements.Add(ac.Id); } if (ac == null) throw new Exception("An adaptive component could not be found or created."); IList<ElementId> placePointIds = new List<ElementId>(); placePointIds = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(ac); if (placePointIds.Count() != pts.Count()) throw new Exception("The input list of points does not have the same number of values required by the adaptive component."); // Set the position of each placement point int i = 0; foreach (ElementId id in placePointIds) { ReferencePoint point = dynRevitSettings.Doc.Document.GetElement(id) as ReferencePoint; XYZ pt = (XYZ)((Value.Container)pts.ElementAt(i)).Item; point.Position = pt; i++; } return Value.NewContainer(ac); }
/// <summary> /// Apppend replication guide to the input parameter based on lacing /// strategy. /// </summary> /// <param name="inputs"></param> /// <returns></returns> protected void AppendReplicationGuides(List<AssociativeNode> inputs) { if (inputs == null || !inputs.Any()) return; switch (ArgumentLacing) { case LacingStrategy.Longest: for (int i = 0; i < inputs.Count(); ++i) { inputs[i] = AstFactory.AddReplicationGuide( inputs[i], new List<int> { 1 }, true); } break; case LacingStrategy.CrossProduct: int guide = 1; for (int i = 0; i < inputs.Count(); ++i) { inputs[i] = AstFactory.AddReplicationGuide( inputs[i], new List<int> { guide }, false); guide++; } break; } }
public override Value Evaluate(FSharpList<Value> args) { if(!args[0].IsList) throw new Exception("A list of UVs is required to place the Adaptive Component."); FSharpList<Value> uvs = ((Value.List)args[0]).Item; var faceRef = ((Value.Container) args[1]).Item as Reference; var f = faceRef == null ? (Face) ((Value.Container) args[1]).Item : (Face)dynRevitSettings.Doc.Document.GetElement(faceRef.ElementId).GetGeometryObjectFromReference(faceRef); var fs = (FamilySymbol)((Value.Container)args[2]).Item; FamilyInstance ac = null; //if the adapative component already exists, then move the points if (Elements.Any()) { //mutate //...we attempt to fetch it from the document... if (dynUtils.TryGetElement(this.Elements[0], out ac)) { ac.Symbol = fs; } else { //create ac = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(dynRevitSettings.Doc.Document, fs); Elements[0] = ac.Id; } } else { //create ac = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(dynRevitSettings.Doc.Document, fs); Elements.Add(ac.Id); } if (ac == null) throw new Exception("An adaptive component could not be found or created."); IList<ElementId> placePointIds = new List<ElementId>(); placePointIds = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(ac); if (placePointIds.Count() != uvs.Count()) throw new Exception("The input list of UVs does not have the same number of values required by the adaptive component."); // Set the position of each placement point int i = 0; foreach (ElementId id in placePointIds) { var uv = (UV)((Value.Container)uvs.ElementAt(i)).Item; var point = dynRevitSettings.Doc.Document.GetElement(id) as ReferencePoint; var peref = dynRevitSettings.Revit.Application.Create.NewPointOnFace(f.Reference, uv); point.SetPointElementReference(peref); i++; } return Value.NewContainer(ac); }
public static Dictionary<string, object> ExportZonesToGBXML(string FilePath, List<ElementId> ZoneIds, List<AbstractFamilyInstance> MassShadingInstances, Boolean Run = false) { // Local variables Boolean IsSuccess = false; string FileName = string.Empty; string Folder = string.Empty; // Check if path and directory valid if (System.String.IsNullOrEmpty(FilePath) || FilePath == "No file selected.") { throw new Exception("No File selected !"); } FileName = Path.GetFileNameWithoutExtension(FilePath); Folder = Path.GetDirectoryName(FilePath); // Check if Directory Exists if (!Directory.Exists(Folder)) { throw new Exception("Folder doesn't exist. Input valid Directory Path!"); } //make RUN? inputs set to True mandatory if (Run == false) { throw new Exception("Set 'Connect' to True!"); } //local varaibles Document RvtDoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument.Document; //enable the analytical model in the document if it isn't already try { PrepareEnergyModel.ActivateEnergyModel(RvtDoc); } catch (Exception) { throw new Exception("Something went wrong when trying to enable the energy model."); } //convert the ElementId wrapper instances to actual Revit ElementId objects List<Autodesk.Revit.DB.ElementId> outZoneIds = ZoneIds.Select(e => new Autodesk.Revit.DB.ElementId(e.InternalId)).ToList(); // get shading Ids List<Autodesk.Revit.DB.ElementId> ShadingIds = new List<Autodesk.Revit.DB.ElementId>(); for (int i = 0; i < MassShadingInstances.Count(); i++) { // make sure input mass is valid as a shading if (MassInstanceUtils.GetMassLevelDataIds(RvtDoc, MassShadingInstances[i].InternalElement.Id).Count() > 0) { throw new Exception("Item " + i.ToString() + " in MassShadingInstances has mass floors assigned. Remove the mass floors and try again."); } ShadingIds.Add(MassShadingInstances[i].InternalElement.Id); } if (ShadingIds.Count != 0) { // Create gbXML with shadings MassGBXMLExportOptions gbXmlExportOptions = new MassGBXMLExportOptions(outZoneIds.ToList(), ShadingIds); // two constructors RvtDoc.Export(Folder, FileName, gbXmlExportOptions); } else { // Create gbXML MassGBXMLExportOptions gbXmlExportOptions = new MassGBXMLExportOptions(outZoneIds.ToList()); // two constructors RvtDoc.Export(Folder, FileName, gbXmlExportOptions); } // if the file exists return success message if not return failed message string path = Path.Combine(Folder, FileName + ".xml"); if (System.IO.File.Exists(path)) { // Modify the xml Program Info element, aithorize the XmlDocument doc = new XmlDocument(); doc.Load(path); // EE: There must be a shorter way ! XmlNode node = doc.DocumentElement; foreach (XmlNode node1 in node.ChildNodes) { foreach (XmlNode node2 in node1.ChildNodes) { if (node2.Name == "ProgramInfo") { foreach (XmlNode childnode in node2.ChildNodes) { if (childnode.Name == "ProductName") { string productname = "Dynamo _ " + childnode.InnerText; childnode.InnerText = productname; } } } } } doc.Save(path); IsSuccess = true; } string message = "Failed to create gbXML file!"; if (IsSuccess) { message = "Success! The gbXML file was created"; } else { path = string.Empty; } return new Dictionary<string, object> { { "report", message}, { "gbXMLPath", path} }; }
public override Value Evaluate(FSharpList<Value> args) { var result = new List<List<FamilyInstance>>(); //"Get an interface to the divided surfaces on this element." //TODO: do we want to select a face instead and try to get //the divided surface that way? DividedSurfaceData dsd = this.SelectedElement.GetDividedSurfaceData(); if (dsd != null) { foreach (Reference r in dsd.GetReferencesWithDividedSurfaces()) { DividedSurface ds = dsd.GetDividedSurfaceForReference(r); GridNode gn = new GridNode(); int u = 0; while (u < ds.NumberOfUGridlines) { var lst = new List<FamilyInstance>(); gn.UIndex = u; int v = 0; while (v < ds.NumberOfVGridlines) { gn.VIndex = v; //"Reports whether a grid node is a "seed node," a node that is associated with one or more tiles." if (ds.IsSeedNode(gn)) { FamilyInstance fi = ds.GetTileFamilyInstance(gn, 0); //put the family instance into the tree lst.Add(fi); } v = v + 1; } //don't add list if it's empty if(lst.Count() > 0) result.Add(lst); u = u + 1; } } this.data = Value.NewList( Utils.SequenceToFSharpList( result.Select( row => Value.NewList( Utils.SequenceToFSharpList( row.Select(Value.NewContainer) ) ) ) ) ); } return data; }
private static List<double> CreateParametersForColors(List<Color> colors) { var parameters = new List<double>(); var step = 1.0 / (colors.Count() - 1); for (var i = 0; i < colors.Count(); i++) { parameters.Add(i * step); } return parameters; }
/// <summary> /// Apppend replication guide to the input parameter based on lacing /// strategy. /// </summary> /// <param name="inputs"></param> /// <returns></returns> private void AppendReplicationGuides(List<AssociativeNode> inputs) { if (inputs == null || !inputs.Any()) return; switch (ArgumentLacing) { case LacingStrategy.Longest: for (int i = 0; i < inputs.Count(); ++i) { if (inputs[i] is ArrayNameNode) { var astNode = NodeUtils.Clone(inputs[i]) as ArrayNameNode; astNode.ReplicationGuides = new List<AssociativeNode>(); var guideNode = new ReplicationGuideNode { RepGuide = AstFactory.BuildIdentifier("1"), IsLongest = true }; astNode.ReplicationGuides.Add(guideNode); inputs[i] = astNode; } } break; case LacingStrategy.CrossProduct: int guide = 1; for (int i = 0; i < inputs.Count(); ++i) { if (inputs[i] is ArrayNameNode) { var astNode = NodeUtils.Clone(inputs[i]) as ArrayNameNode; astNode.ReplicationGuides = new List<AssociativeNode>(); var guideNode = new ReplicationGuideNode { RepGuide = AstFactory.BuildIdentifier(guide.ToString()) }; astNode.ReplicationGuides.Add(guideNode); inputs[i] = astNode; guide++; } } break; } }
public static Dictionary<string, object> SeparateZonesByLevel(List<ElementId> ZoneIds) { //local varaibles Document RvtDoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument.Document; MassZone zone = null; Autodesk.Revit.DB.Level level = null; List<Autodesk.Revit.DB.ElementId> levelIds = new List<Autodesk.Revit.DB.ElementId>(); SortedDictionary<double, Autodesk.Revit.DB.Level> levels = new SortedDictionary<double, Autodesk.Revit.DB.Level>(); //SortedDictionary<double, Autodesk.Revit.DB.ElementId> levels = new SortedDictionary<double, Autodesk.Revit.DB.ElementId>(); SortedDictionary<double, List<ElementId>> SepatatedZones = new SortedDictionary<double, List<ElementId>>(); for (int i = 0; i < ZoneIds.Count(); i++ ) { //try to get MassZone using the ID try { zone = (MassZone)RvtDoc.GetElement(new Autodesk.Revit.DB.ElementId(ZoneIds[i].InternalId)); if (zone == null) throw new Exception(); //find level ID Autodesk.Revit.DB.ElementId levelId = zone.LowerLevelId; // get level element level = (Autodesk.Revit.DB.Level)RvtDoc.GetElement(levelId); // get the elevation for the level double elevation = level.Elevation; // add levels and zones to dictionary based on elevation levels[elevation] = level; if (!SepatatedZones.ContainsKey(elevation)) { // create an empty list as place holder SepatatedZones[elevation] = new List<ElementId>(); } // add zoneId SepatatedZones[elevation].Add(ZoneIds[i]); } catch (Exception) { throw new Exception("Couldn't find a zone object with Id #: " + ZoneIds[i].ToString()); } } //return the levels and zone IDs return new Dictionary<string, object> { {"Levels", levels.Values}, {"ZoneIds", SepatatedZones.Values} }; }
public static Dictionary<string, object> SeparateSrfsByOrientation(List<ElementId> SurfaceIds) { //local varaibles Document RvtDoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument.Document; MassSurfaceData surface = null; Autodesk.DesignScript.Geometry.Vector YAxisVector = Autodesk.DesignScript.Geometry.Vector.YAxis(); double angle2YAxis = 0; // Revit project angle vs real north angle is pretty confusing so I just leave it to YAxis // and users can adjust them based on their project // double projectNorth = RvtDoc.ActiveProjectLocation.get_ProjectPosition(XYZ.Zero).Angle; List<Autodesk.Revit.DB.ElementId> levelIds = new List<Autodesk.Revit.DB.ElementId>(); SortedDictionary<double, List<ElementId>> SepatatedSurfaces = new SortedDictionary<double, List<ElementId>>(); for (int i = 0; i < SurfaceIds.Count(); i++) { //try to get MassZone using the ID try { surface = (MassSurfaceData)RvtDoc.GetElement(new Autodesk.Revit.DB.ElementId(SurfaceIds[i].InternalId)); if (surface == null) throw new Exception(); // get vector for this surface Autodesk.DesignScript.Geometry.Vector srfVector = AnalysisSurfaceVector(SurfaceIds[i]); // project vector to XY plane Autodesk.DesignScript.Geometry.Vector projectedVector = Autodesk.DesignScript.Geometry.Vector.ByCoordinates(srfVector.X, srfVector.Y, 0); // find angle to YAxis //angle2YAxis = Math.Round(projectedVector.AngleBetween(YAxisVector), 3); //AngleBetween is buggy and I already reported it but it is not fixed //I haven't tested this intensively but worked for couple of cases that I tried angle2YAxis = Math.Round(CalculateAngleXY(projectedVector, YAxisVector), 3); if (! SepatatedSurfaces.ContainsKey(angle2YAxis)) { // create an empty list as place holder SepatatedSurfaces[angle2YAxis] = new List<ElementId>(); } // add surfaceId SepatatedSurfaces[angle2YAxis].Add(SurfaceIds[i]); } catch (Exception) { throw new Exception("Couldn't find a surface object with Id #: " + SurfaceIds[i].ToString()); } } //return the levels and zone IDs return new Dictionary<string, object> { {"AngleToYAxis", SepatatedSurfaces.Keys}, {"SurfaceIds", SepatatedSurfaces.Values} }; }