/// <summary> /// Update an existing element's location /// </summary> /// <param name="geometry">New Location Point or Curve</param> public void SetLocation(Geometry geometry) { TransactionManager.Instance.EnsureInTransaction(Application.Document.Current.InternalDocument); if (this.InternalElement.Location is Autodesk.Revit.DB.LocationPoint) { if (geometry is Autodesk.DesignScript.Geometry.Point) { Autodesk.DesignScript.Geometry.Point point = geometry as Autodesk.DesignScript.Geometry.Point; Autodesk.Revit.DB.LocationPoint pt = this.InternalElement.Location as Autodesk.Revit.DB.LocationPoint; pt.Point = point.ToRevitType(true); } else { throw new Exception(Properties.Resources.PointRequired); } } else if (this.InternalElement.Location is Autodesk.Revit.DB.LocationCurve && geometry is Curve) { if (geometry is Curve) { Curve dynamoCurve = geometry as Curve; Autodesk.Revit.DB.LocationCurve curve = this.InternalElement.Location as Autodesk.Revit.DB.LocationCurve; curve.Curve = dynamoCurve.ToRevitType(true); } else { throw new Exception(Properties.Resources.CurveRequired); } } else { throw new Exception(Properties.Resources.InvalidElementLocation); } TransactionManager.Instance.TransactionTaskDone(); }
public static List <Curve> IntersectWithCurve(global::Revit.Elements.Room room, Curve curve) { List <Curve> curveList = null; Autodesk.Revit.DB.Architecture.Room internalRoom = (Autodesk.Revit.DB.Architecture.Room)room.InternalElement; Autodesk.Revit.DB.GeometryElement roomGeometryElement = internalRoom.ClosedShell; foreach (GeometryObject geoObj in roomGeometryElement) { if (geoObj is Autodesk.Revit.DB.Solid) { Autodesk.Revit.DB.Solid geoSolid = geoObj as Autodesk.Revit.DB.Solid; Autodesk.Revit.DB.SolidCurveIntersection intersectingCurve = geoSolid.IntersectWithCurve(curve.ToRevitType(), new SolidCurveIntersectionOptions()); curveList = intersectingCurve.Select(c => c.ToProtoType()).ToList(); } } return(curveList); }
/// <summary> /// Create a Revit Floor given it's curve outline and Level /// </summary> /// <param name="outline">The outline.</param> /// <param name="floorType">Type of the floor.</param> /// <param name="level">The level.</param> /// <param name="structural">if set to <c>true</c> [structural].</param> /// <returns> /// The floor /// </returns> public static SlopedFloor ByOutlineTypeAndLevel(Autodesk.DesignScript.Geometry.PolyCurve outline, Revit.Elements.FloorType floorType, Revit.Elements.Level level, bool structural) { Utils.Log(string.Format("SlopedFloor.ByOutlineTypeAndLevel started...", "")); try { var profile = new CurveArray(); Autodesk.DesignScript.Geometry.Plane plane = Autodesk.DesignScript.Geometry.Plane.ByBestFitThroughPoints( outline.Curves().Cast <Autodesk.DesignScript.Geometry.Curve>().Select(x => x.StartPoint)); Vector normal = plane.Normal; if (normal.Dot(Vector.ZAxis()) <= 0) { normal = normal.Reverse(); } Autodesk.DesignScript.Geometry.Point origin = plane.Origin; Autodesk.DesignScript.Geometry.Point end = origin.Add(normal); Autodesk.DesignScript.Geometry.Point projection = Autodesk.DesignScript.Geometry.Point.ByCoordinates(end.X, end.Y, -1000); end = Autodesk.DesignScript.Geometry.Point.ByCoordinates(end.X, end.Y, end.Z + 1000); Autodesk.DesignScript.Geometry.Point intersection = null; var result = plane.Intersect(Autodesk.DesignScript.Geometry .Line.ByStartPointEndPoint(end, projection)); if (result.Length > 0) { intersection = result[0] as Autodesk.DesignScript.Geometry.Point; } else { var message = "Couldn't find intersection"; Utils.Log(string.Format("ERROR: SlopedFloor.ByOutlineTypeAndLevel {0}", message)); throw new Exception(message); } Autodesk.DesignScript.Geometry.Curve temp = Autodesk.DesignScript.Geometry.Line.ByBestFitThroughPoints(new Autodesk.DesignScript.Geometry.Point[] { origin, intersection }); PolyCurve flat = PolyCurve.ByJoinedCurves(outline.PullOntoPlane(Autodesk.DesignScript.Geometry.Plane.XY() .Offset(temp.StartPoint.Z)).Explode().Cast <Autodesk.DesignScript.Geometry.Curve>().ToList()); Autodesk.DesignScript.Geometry.Curve flatLine = temp.PullOntoPlane(Autodesk.DesignScript.Geometry.Plane.XY().Offset(temp.StartPoint.Z)); if (Math.Abs(Math.Abs(plane.Normal.Dot(Vector.ZAxis())) - 1) < 0.00001) { var f = Revit.Elements.Floor.ByOutlineTypeAndLevel(flat, floorType, level); f.InternalElement.Parameters.Cast <Autodesk.Revit.DB.Parameter>() .First(x => x.Id.IntegerValue.Equals(Autodesk.Revit.DB.BuiltInParameter.FLOOR_PARAM_IS_STRUCTURAL)) .Set(structural ? 1 : 0); plane.Dispose(); flatLine.Dispose(); flat.Dispose(); origin.Dispose(); end.Dispose(); projection.Dispose(); intersection.Dispose(); temp.Dispose(); return(new SlopedFloor(f.InternalElement as Autodesk.Revit.DB.Floor)); } double slope = (temp.EndPoint.Z - temp.StartPoint.Z) / flatLine.Length; foreach (Autodesk.DesignScript.Geometry.Curve c in flat.Curves()) { profile.Append(c.ToRevitType()); } Autodesk.Revit.DB.Line slopeArrow = flatLine.ToRevitType() as Autodesk.Revit.DB.Line; var ft = floorType.InternalElement as Autodesk.Revit.DB.FloorType; var lvl = level.InternalElement as Autodesk.Revit.DB.Level; var floor = new SlopedFloor(profile, slopeArrow, slope, ft, lvl, structural); floor.Level = level; floor.Floortype = floorType; floor.Structural = structural; //DocumentManager.Regenerate(); plane.Dispose(); flatLine.Dispose(); flat.Dispose(); origin.Dispose(); end.Dispose(); projection.Dispose(); intersection.Dispose(); temp.Dispose(); Utils.Log(string.Format("SlopedFloor.ByOutlineTypeAndLevel completed.", "")); return(floor); } catch (Exception ex) { Utils.Log(string.Format("ERROR: SlopedFloor.ByOutlineTypeAndLevel {0}", ex.Message)); throw ex; } }
public static Dictionary <string, object> ByRoom(string familyTemplatePath, global::Revit.Elements.Room room, string materialName, global::Revit.Elements.Category category, string subcategory = "") { //variables global::Revit.Elements.Element famInstance = null; Autodesk.Revit.DB.FamilyInstance internalFam = null; bool fileFound = false; //the current document Autodesk.Revit.DB.Document doc = DocumentManager.Instance.CurrentDBDocument; UIApplication uiapp = new UIApplication(doc.Application); //convert the room to an Autodesk.Revit.DB representation Autodesk.Revit.DB.Architecture.Room internalRoom = (Autodesk.Revit.DB.Architecture.Room)room.InternalElement; string name = internalRoom.Name; //we close all of the families because we need to swap documents foreach (Document d in uiapp.Application.Documents) { if (d.IsFamilyDocument) { d.Close(false); } } //create the new family document in the background and store it in memory Document familyDocument = uiapp.Application.NewFamilyDocument(familyTemplatePath); //instantiate a material element id and try to get the material that was specified ElementId material = null; FilteredElementCollector materialCollector = new FilteredElementCollector(familyDocument).OfClass(typeof(Autodesk.Revit.DB.Material)); foreach (var m in materialCollector) { if (m.Name.ToLower().Replace(" ", "") == materialName.ToLower().Replace(" ", "")) { material = m.Id; } } //close Dynamo's open transaction, we need to do this because we open a new Revit API transaction in the family document (This is document switching) TransactionManager.Instance.ForceCloseTransaction(); //start creating the families. Transaction trans = new Transaction(familyDocument, "Generate Families Ya'll"); trans.Start(); //set the family category Autodesk.Revit.DB.Category familyCategory = familyDocument.Settings.Categories.get_Item(category.Name); familyDocument.OwnerFamily.FamilyCategory = familyCategory; //get the subcategory for the solids Autodesk.Revit.DB.Category subCategory = null; foreach (Autodesk.Revit.DB.Category c in familyCategory.SubCategories) { if (c.Name.ToLower() == subcategory.ToLower()) { subCategory = c; } } //get the height of the thing double height = room.Height; //get the curves IList <IList <BoundarySegment> > boundary = internalRoom.GetBoundarySegments(new SpatialElementBoundaryOptions()); //generate a plane Autodesk.Revit.DB.Plane revitPlane = Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(Vector.ZAxis().ToXyz(), new XYZ(0, 0, 0)); Autodesk.Revit.DB.SketchPlane sketchPlane = SketchPlane.Create(familyDocument, revitPlane); //the curve arrays to generate solids and voids in family CurveArray curveArray = new CurveArray(); CurveArrArray curveArrArray = new CurveArrArray(); CurveArray curveArrayVoid = new CurveArray(); CurveArrArray curveArrArrayVoid = new CurveArrArray(); //to perform the cut action on the solid with the voids CombinableElementArray ceArray = new CombinableElementArray(); //transform bizness Point roomCentroid = room.BoundingBox.ToCuboid().Centroid(); Point locationPoint = Point.ByCoordinates(roomCentroid.X, roomCentroid.Y, 0); CoordinateSystem oldCS = CoordinateSystem.ByOrigin(locationPoint); CoordinateSystem newCS = CoordinateSystem.ByOrigin(0, 0, 0); //flag to step through the boundaries. int flag = 0; while (flag < boundary.Count) { //the first set of curves is the solid's boundary if (flag == 0) { //generate the solid form which is the first item in the boundary segments. foreach (BoundarySegment b in boundary[flag]) { Autodesk.DesignScript.Geometry.Curve c = b.GetCurve().ToProtoType(); Autodesk.DesignScript.Geometry.Curve movedCurve = c.Transform(oldCS, newCS) as Autodesk.DesignScript.Geometry.Curve; curveArray.Append(movedCurve.ToRevitType()); } curveArrArray.Append(curveArray); Extrusion solidExtrusion = familyDocument.FamilyCreate.NewExtrusion(true, curveArrArray, sketchPlane, height); if (material != null) { //Set the material Autodesk.Revit.DB.Parameter matParam = solidExtrusion.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM); matParam.Set(material); } //try to set the subcategory if (subCategory != null) { solidExtrusion.Subcategory = subCategory; } } //subsequent lists of curves are representative of the voids else { //clear the curves from the collection for all items after the second one. (index 2+) if (!curveArrayVoid.IsEmpty) { curveArrayVoid.Clear(); curveArrArrayVoid.Clear(); ceArray.Clear(); } //generate the void form foreach (BoundarySegment b in boundary[flag]) { Autodesk.DesignScript.Geometry.Curve c = b.GetCurve().ToProtoType(); Autodesk.DesignScript.Geometry.Curve movedCurve = c.Transform(oldCS, newCS) as Autodesk.DesignScript.Geometry.Curve; curveArrayVoid.Append(movedCurve.ToRevitType()); } curveArrArrayVoid.Append(curveArrayVoid); Extrusion voidExtrusion = familyDocument.FamilyCreate.NewExtrusion(false, curveArrArrayVoid, sketchPlane, height); //try to combine things foreach (Extrusion genericForm in new FilteredElementCollector(familyDocument).OfClass(typeof(Extrusion)) .Cast <Extrusion>()) { ceArray.Append(genericForm); } //to add the void to the solid familyDocument.CombineElements(ceArray); } flag++; } familyDocument.Regenerate(); trans.Commit(); Autodesk.Revit.DB.Family fam = null; //build the temporary path string familyFilePath = Path.GetTempPath() + name + ".rfa"; SaveAsOptions opt = new SaveAsOptions(); opt.OverwriteExistingFile = true; familyDocument.SaveAs(familyFilePath, opt); familyDocument.Close(false); TransactionManager.Instance.ForceCloseTransaction(); Transaction trans2 = new Transaction(doc, "Attempting to place or update Room family instances."); trans2.Start(); IFamilyLoadOptions loadOptions = new FamilyImportOptions(); bool variable = true; loadOptions.OnFamilyFound(true, out variable); doc.LoadFamily(familyFilePath, loadOptions, out fam); FamilySymbol familySymbol = (FamilySymbol)doc.GetElement(fam.GetFamilySymbolIds().First()); //try to find if it is placed already FilteredElementCollector col = new FilteredElementCollector(doc); //get built in category from user viewable category BuiltInCategory myCatEnum = (BuiltInCategory)Enum.Parse(typeof(BuiltInCategory), category.Id.ToString()); foreach (Autodesk.Revit.DB.Element e in col.WhereElementIsNotElementType().OfCategory(myCatEnum).ToElements()) { Autodesk.Revit.DB.FamilySymbol type = (FamilySymbol)doc.GetElement(e.GetTypeId()); if (type.FamilyName.Equals(name)) { fileFound = true; internalFam = e as Autodesk.Revit.DB.FamilyInstance; } } //place families that are not placed if (fileFound == false) { if (!familySymbol.IsActive) { familySymbol.Activate(); } internalFam = doc.Create.NewFamilyInstance(new XYZ(roomCentroid.X, roomCentroid.Y, 0), familySymbol, internalRoom.Level, StructuralType.NonStructural); } trans2.Commit(); //delete the temp file File.Delete(familyFilePath); //cast to Dynamo type for output and location updating (if necessary) famInstance = internalFam.ToDSType(true); if (fileFound) { famInstance.SetLocation(locationPoint); } //returns the outputs var outInfo = new Dictionary <string, object> { { "familyInstance", famInstance } }; return(outInfo); }