public static Elements.WallByProfile[] WallsFromRevitWall(ADSK.Wall wall, Document doc) { var side_faces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior); if (side_faces.Count != 1) { throw new InvalidOperationException($"This wall has ${(side_faces.Count < 1 ? "not enough" : "too many")} interior faces"); } var wallFace = doc.GetElement(side_faces[0]).GetGeometryObjectFromReference(side_faces[0]); if (!(wallFace is PlanarFace)) { throw new InvalidCastException("This wall does not have planar faces"); } var wallPlane = wallFace as PlanarFace; var profiles = wallPlane.GetProfiles(); var centerline = (wall.Location as LocationCurve).Curve; var line = new ElemGeom.Line(centerline.GetEndPoint(0).ToVector3(true), centerline.GetEndPoint(1).ToVector3(true)); var walls = profiles.Select(p => new WallByProfile(p.Reverse(), Elements.Units.FeetToMeters(wall.Width), line)); return(walls.ToArray()); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { var uiapp = commandData.Application; var uidoc = uiapp.ActiveUIDocument; var doc = uidoc.Document; var sel = uidoc.Selection; var wall = sel.PickObject(ObjectType.Element, doc.GetSelectionFilter(m => m is Wall)).GetElement(doc) as Wall; var facesoutRef = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior); var facesinRef = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior); var faceout = wall.GetGeometryObjectFromReference(facesoutRef.First()) as Face; var facein = wall.GetGeometryObjectFromReference(facesinRef.First()) as Face; var area = default(double); area += faceout.Area; area += facein.Area; area = UnitUtils.ConvertFromInternalUnits(area, DisplayUnitType.DUT_SQUARE_METERS); area = Math.Round(area, 3); MessageBox.Show(area.ToString() + "m^2"); return(Result.Succeeded); }
private WallCollection GetWallInformation(UIDocument uidoc, Document revitDoc, Application app, Wall wall, WallType WallType) { Autodesk.Revit.Creation.Document credoc = revitDoc.Create; Autodesk.Revit.Creation.Application creapp = app.Create; View view = revitDoc.ActiveView; ElementType type = WallType as ElementType; Parameter b = type.get_Parameter((BuiltInParameter.WALL_ATTR_WIDTH_PARAM)); double width = b.AsDouble() / 2; IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior); Element e2 = revitDoc.GetElement(sideFaces[0]); Face face = e2.GetGeometryObjectFromReference(sideFaces[0]) as Face; // The normal of the wall external face. XYZ normal = face.ComputeNormal(new UV(0, 0)); // Offset curve copies for visibility. Transform offset = Transform.CreateTranslation(width * normal); // If the curve loop direction is counter- // clockwise, change its color to RED. // Get edge loops as curve loops. IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops(); // ExporterIFCUtils class can also be used for // non-IFC purposes. The SortCurveLoops method // sorts curve loops (edge loops) so that the // outer loops come first. IList <IList <CurveLoop> > curveLoopLoop = ExporterIFCUtils.SortCurveLoops(curveLoops); List <List <Curve> > Walls = new List <List <Curve> >(); WallCollection WCCC = new WallCollection(); foreach (IList <CurveLoop> curveLoops2 in curveLoopLoop) { foreach (CurveLoop curveLoop2 in curveLoops2) { // Check if curve loop is counter-clockwise. CurveArray curves = creapp.NewCurveArray(); List <Curve> CC = new List <Curve>(); foreach (Curve curve in curveLoop2) { curves.Append(curve.CreateTransformed(offset)); CC.Add(curve.CreateTransformed(offset)); } // Create model lines for an curve loop. Walls.Add(CC); WCCC.AddWall(CC); } } return(WCCC); }
private void SetWindowData(WindowData windowData) { // Collect existing windows List <FamilyInstance> windowElements = _doc.CollectElements <FamilyInstance>(BuiltInCategory.OST_Windows); List <FamilyInstance> newTrims = new List <FamilyInstance>(); _tt.Start(); // Get existing window sizes foreach (FamilyInstance window in windowElements) { // Get the type of window to retrieve it's data Element wnTp = _doc.GetElement(window.GetTypeId()); double winHt = wnTp.get_Parameter(BuiltInParameter.WINDOW_HEIGHT).AsDouble(); double winWd = wnTp.get_Parameter(BuiltInParameter.WINDOW_WIDTH).AsDouble(); HostObject winHost = window.Host as HostObject; Level winLevel = (Level)_doc.GetElement(window.LevelId); XYZ winLocation = ((LocationPoint)window.Location).Point; string newTypeName = $"{windowData.StyleCategory}-{Math.Round((double)((int)winWd * 12))}-{Math.Round((double)((int)winHt * 12))}"; window.Symbol = windowData.Types.FirstOrDefault(type => type.Name == newTypeName) ?? CreateWindowType(windowData.Types[0], windowData.StyleCategory, winWd, winHt); // Create new window trim at window locations on the exterior face of the host wall if on a window of specific size ranges if (windowData.Trim?.Type != null && (winWd > 1.9 && winWd < 5.9) && (winHt > 1.9 && winHt < 5.9)) { IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(winHost, ShellLayerType.Exterior); Face face = _doc.GetElement(sideFaces[0]).GetGeometryObjectFromReference(sideFaces[0]) as Face; UV uvLoc = face.Project(winLocation).UVPoint; XYZ normal = face.ComputeNormal(uvLoc); XYZ refDir = normal.CrossProduct(XYZ.BasisZ); FamilyInstance winTrim = _doc.Create.NewFamilyInstance(winLocation, (FamilySymbol)windowData.Trim.Type, winHost, StructuralType.NonStructural); newTrims.Add(winTrim); // Change the width and height of the newly created trims winTrim.SetParameter("Opening Height", winHt); winTrim.SetParameter("Opening Width", winWd); } } // Setting the parameters for the newly placed window trim if (newTrims.Count > 0) { foreach (FamilyInstance trim in newTrims) { trim.SetParameter("Top Profile", windowData.Trim.TopCategory); trim.SetParameter("Bottom Profile", windowData.Trim.BottomCategory); trim.SetParameter("Side Profile", windowData.Trim.SideCategory); trim.SetParameter("Shutter", windowData.ShutterCategory); trim.SetParameter("Top Key", windowData.KeyCategory); } } _tt.Commit(); }
/// <summary> /// This node will return the interior face or faces for the input host object. This particular method works for walls. /// </summary> /// <param name="hostObject">The host object to retrieve interior faces for.</param> /// <returns></returns> public static IEnumerable <List <Surface> > InteriorSurface(global::Revit.Elements.Element hostObject) { Autodesk.Revit.DB.HostObject internalHost = hostObject.InternalElement as Autodesk.Revit.DB.HostObject; IList <Reference> sideRefs = HostObjectUtils.GetSideFaces(internalHost, ShellLayerType.Interior); List <Autodesk.Revit.DB.Face> exteriorGeometryObjects = new List <Autodesk.Revit.DB.Face>(sideRefs.Select(r => internalHost.GetGeometryObjectFromReference(r)).Cast <Autodesk.Revit.DB.Face>()); return(exteriorGeometryObjects.Select(g => g.ToProtoType(true).ToList())); }
/// <summary> /// Return a `StableRepresentation` for a linked wall's exterior face. /// </summary> public string GetFaceRefRepresentation( Wall wall, Document doc, RevitLinkInstance instance ) { Reference faceRef = HostObjectUtils.GetSideFaces( wall, ShellLayerType.Exterior ).FirstOrDefault(); Reference stRef = faceRef.CreateLinkReference( instance ); string stable = stRef.ConvertToStableRepresentation( doc ); return stable; }
public static Transform getLocalCoordinates(Element element, Boolean isStruct, UIDocument uidoc) { Transform transform = null; int isstruct = 1; if (isStruct == true) { isstruct = -1; } if (element is Wall) { Wall wall = element as Wall; LocationCurve lc = wall.Location as LocationCurve; Line line = lc.Curve as Line; IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior); Face face = uidoc.Document.GetElement(sideFaces[0]).GetGeometryObjectFromReference(sideFaces[0]) as Face; Reference reference = face.Reference; UV uv = new UV(0, 0); XYZ wallfacedir = face.ComputeNormal(uv) as XYZ; XYZ p = line.GetEndPoint(0); XYZ q = line.GetEndPoint(1); XYZ v = q - p; BoundingBoxXYZ bb = wall.get_BoundingBox(null); double minZ = bb.Min.Z; double maxZ = bb.Max.Z; double w = v.GetLength(); double h = maxZ - minZ; XYZ midpoint = p + 0.5 * v; XYZ up = XYZ.BasisZ; XYZ walldir = wallfacedir.CrossProduct(up); transform = Transform.Identity; transform.Origin = new XYZ(midpoint.X, midpoint.Y, 0); transform.BasisX = walldir.Normalize() * isstruct * -1; transform.BasisY = up; transform.BasisZ = wallfacedir * isstruct; } return(transform); }
public void AddFaceBasedFamilyToLinks(Document doc) { ElementId alignedLinkId = new ElementId(125929); // Get symbol ElementId symbolId = new ElementId(126580); FamilySymbol fs = doc.GetElement(symbolId) as FamilySymbol; // Aligned RevitLinkInstance linkInstance = doc.GetElement( alignedLinkId) as RevitLinkInstance; Document linkDocument = linkInstance .GetLinkDocument(); FilteredElementCollector wallCollector = new FilteredElementCollector(linkDocument); wallCollector.OfClass(typeof(Wall)); Wall targetWall = wallCollector.FirstElement() as Wall; Reference exteriorFaceRef = HostObjectUtils.GetSideFaces( targetWall, ShellLayerType.Exterior) .First <Reference>(); Reference linkToExteriorFaceRef = exteriorFaceRef.CreateLinkReference( linkInstance); Line wallLine = (targetWall.Location as LocationCurve).Curve as Line; XYZ wallVector = (wallLine.GetEndPoint(1) - wallLine.GetEndPoint(0)).Normalize(); using (Transaction t = new Transaction(doc)) { t.Start("Add to face"); doc.Create.NewFamilyInstance( linkToExteriorFaceRef, XYZ.Zero, wallVector, fs); t.Commit(); } }
public Face getWallExterior(Wall pickedWall) { // Get the side faces IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(pickedWall, ShellLayerType.Exterior); // access the side face Face face = doc.GetElement(sideFaces[0]) .GetGeometryObjectFromReference(sideFaces[0]) as Face; return(face); }
// Get Profile-------------------------------------------------------------------- public static List <XYZ> Get_Profile(Document doc, Element element) { List <XYZ> list_Profile_point = new List <XYZ>(); try { IList <Reference> sideFaces = null; if (element.Category.Name == "Walls") { sideFaces = HostObjectUtils.GetSideFaces(element as Wall, ShellLayerType.Exterior); } else { sideFaces = HostObjectUtils.GetTopFaces(element as Floor); } Element e2 = doc.GetElement(sideFaces[0]); Face face = e2.GetGeometryObjectFromReference(sideFaces[0]) as Face; // The normal of the wall external face. XYZ normal = face.ComputeNormal(new UV(0, 0)); // Get edge loops as curve loops. IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops(); // ExporterIFCUtils class can also be used for // non-IFC purposes. The SortCurveLoops method // sorts curve loops (edge loops) so that the // outer loops come first. IList <IList <CurveLoop> > curveLoopLoop = ExporterIFCUtils.SortCurveLoops(curveLoops); foreach (IList <CurveLoop> curveLoops2 in curveLoopLoop) { foreach (CurveLoop curveLoop2 in curveLoops2) { // Check if curve loop is counter-clockwise. bool isCCW = curveLoop2.IsCounterclockwise(normal); foreach (Curve curve in curveLoop2) { list_Profile_point.Add(curve.GetEndPoint(0)); } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } return(list_Profile_point); }
public void MirrorWall(Document doc, Wall wall) { Reference reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior).First(); //get one of the wall's major side faces Face face = wall.GetGeometryObjectFromReference(reference) as Face; UV bboxMin = face.GetBoundingBox().Min; //create a plane based on the side face with an offset of 10 in the X & Y directions Plane plane = Plane.CreateByNormalAndOrigin(face.ComputeNormal(bboxMin), face.Evaluate(bboxMin).Add(new XYZ(10, 10, 0))); ElementTransformUtils.MirrorElement(doc, wall.Id, plane); }
/// <summary>Получение наружного Face для стены</summary> /// <param name="wall">Стена</param> /// <param name="shellLayerType">Тип получаемого Face</param> /// <returns></returns> public static Face GetSideFaceFromWall(Wall wall, ShellLayerType shellLayerType) { Face face = null; IList <Reference> sideFaces = null; if (shellLayerType == ShellLayerType.Exterior) { sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior); } if (shellLayerType == ShellLayerType.Interior) { sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior); } if (sideFaces != null) { face = wall.GetGeometryObjectFromReference(sideFaces[0]) as Face; } return(face); }
protected override void SolveInstance(IGH_DataAccess DA) { Autodesk.Revit.DB.HostObject host = null; if (!DA.GetData("Host", ref host) || host is null) { return; } var doc = Revit.ActiveDBDocument; try { var bottom = HostObjectUtils.GetBottomFaces(host).Select(reference => new Types.Face(reference, doc)); DA.SetDataList("Bottom", bottom); } catch (Autodesk.Revit.Exceptions.ArgumentException) { } try { var top = HostObjectUtils.GetTopFaces(host).Select(reference => new Types.Face(reference, doc)); DA.SetDataList("Top", top); } catch (Autodesk.Revit.Exceptions.ArgumentException) { } try { var interior = HostObjectUtils.GetSideFaces(host, ShellLayerType.Interior).Select(reference => new Types.Face(reference, doc)); DA.SetDataList("Interior", interior); } catch (Autodesk.Revit.Exceptions.ArgumentException) { } try { var exterior = HostObjectUtils.GetSideFaces(host, ShellLayerType.Exterior).Select(reference => new Types.Face(reference, doc)); DA.SetDataList("Exterior", exterior); } catch (Autodesk.Revit.Exceptions.ArgumentException) { } }
/// <summary> /// Alternative implementation published January 23, 2015: /// http://thebuildingcoder.typepad.com/blog/2015/01/getting-the-wall-elevation-profile.html /// </summary> public Result Execute2( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; View view = doc.ActiveView; Autodesk.Revit.Creation.Application creapp = app.Create; Autodesk.Revit.Creation.Document credoc = doc.Create; Reference r = uidoc.Selection.PickObject( ObjectType.Element, "Select a wall"); Element e = uidoc.Document.GetElement(r); Wall wall = e as Wall; using (Transaction tx = new Transaction(doc)) { tx.Start("Wall Profile"); // Get the external wall face for the profile IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior); Element e2 = doc.GetElement(sideFaces[0]); Face face = e2.GetGeometryObjectFromReference( sideFaces[0]) as Face; // The normal of the wall external face. XYZ normal = face.ComputeNormal(new UV(0, 0)); // Offset curve copies for visibility. Transform offset = Transform.CreateTranslation( 5 * normal); // If the curve loop direction is counter- // clockwise, change its color to RED. Color colorRed = new Color(255, 0, 0); // Get edge loops as curve loops. IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops(); // ExporterIFCUtils class can also be used for // non-IFC purposes. The SortCurveLoops method // sorts curve loops (edge loops) so that the // outer loops come first. IList <IList <CurveLoop> > curveLoopLoop = ExporterIFCUtils.SortCurveLoops( curveLoops); foreach (IList <CurveLoop> curveLoops2 in curveLoopLoop) { foreach (CurveLoop curveLoop2 in curveLoops2) { // Check if curve loop is counter-clockwise. bool isCCW = curveLoop2.IsCounterclockwise( normal); CurveArray curves = creapp.NewCurveArray(); foreach (Curve curve in curveLoop2) { curves.Append(curve.CreateTransformed(offset)); } // Create model lines for an curve loop. //Plane plane = creapp.NewPlane( curves ); // 2016 Plane plane = curveLoop2.GetPlane(); // 2017 SketchPlane sketchPlane = SketchPlane.Create(doc, plane); ModelCurveArray curveElements = credoc.NewModelCurveArray(curves, sketchPlane); if (isCCW) { foreach (ModelCurve mcurve in curveElements) { OverrideGraphicSettings overrides = view.GetElementOverrides( mcurve.Id); overrides.SetProjectionLineColor( colorRed); view.SetElementOverrides( mcurve.Id, overrides); } } } } tx.Commit(); } return(Result.Succeeded); }
/// <summary> /// Improved implementation by Alexander Ignatovich /// supporting curved wall with curved window, /// second attempt, published April 10, 2015: /// </summary> public Result Execute3( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; View view = doc.ActiveView; Autodesk.Revit.Creation.Application creapp = app.Create; Autodesk.Revit.Creation.Document credoc = doc.Create; Reference r = uidoc.Selection.PickObject( ObjectType.Element, "Select a wall"); Element e = uidoc.Document.GetElement(r); Creator creator = new Creator(doc); Wall wall = e as Wall; if (wall == null) { return(Result.Cancelled); } using (Transaction tx = new Transaction(doc)) { tx.Start("Wall Profile"); // Get the external wall face for the profile // a little bit simpler than in the last // implementation in Execute2. Reference sideFaceReference = HostObjectUtils.GetSideFaces( wall, ShellLayerType.Exterior) .First(); Face face = wall.GetGeometryObjectFromReference( sideFaceReference) as Face; // The plane and normal of the wall external face. XYZ normal = wall.Orientation.Normalize(); Transform ftx = face.ComputeDerivatives(UV.Zero); XYZ forigin = ftx.Origin; XYZ fnormal = ftx.BasisZ; Debug.Print( "wall orientation {0}, face origin {1}, face normal {2}", Util.PointString(normal), Util.PointString(forigin), Util.PointString(fnormal)); // Offset distance. double d = 5; // Offset curve copies for visibility. XYZ voffset = d * normal; Transform offset = Transform.CreateTranslation( voffset); // If the curve loop direction is counter- // clockwise, change its color to RED. Color colorRed = new Color(255, 0, 0); // Get edge loops as curve loops. IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops(); foreach (var curveLoop in curveLoops) { //CurveLoop curveLoopOffset = CurveLoop.CreateViaOffset( // curveLoop, d, normal ); CurveArray curves = creapp.NewCurveArray(); foreach (Curve curve in curveLoop) { curves.Append(curve.CreateTransformed( offset)); } var isCounterClockwize = curveLoop .IsCounterclockwise(normal); // Create model lines for an curve loop if it is made Curve wallCurve = ((LocationCurve)wall.Location).Curve; if (wallCurve is Line) { //Plane plane = creapp.NewPlane( curves ); // 2016 //Plane plane = curveLoopOffset.GetPlane(); // 2017 Plane plane = Plane.CreateByNormalAndOrigin( // 2019 normal, forigin + voffset); Debug.Print( "plane origin {0}, plane normal {1}", Util.PointString(plane.Origin), Util.PointString(plane.Normal)); SketchPlane sketchPlane = SketchPlane.Create(doc, plane); ModelCurveArray curveElements = credoc .NewModelCurveArray(curves, sketchPlane); if (isCounterClockwize) { SetModelCurvesColor(curveElements, view, colorRed); } } else { foreach (var curve in curves.Cast <Curve>()) { var curveElements = creator.CreateModelCurves(curve); if (isCounterClockwize) { SetModelCurvesColor(curveElements, view, colorRed); } } } } tx.Commit(); } return(Result.Succeeded); }
private static List <Polygon> GetProfile(this Autodesk.Revit.DB.Element element) { Document doc = element.Document; List <Polygon> polygons = new List <Polygon>(); IList <Reference> firstSideFaces = null; IList <Reference> secondSideFaces = null; switch (element) { case Wall revitWall: //use host object utils to get the outside face firstSideFaces = HostObjectUtils.GetSideFaces(revitWall, ShellLayerType.Exterior); secondSideFaces = HostObjectUtils.GetSideFaces(revitWall, ShellLayerType.Interior); break; case Autodesk.Revit.DB.Floor revitFloor: firstSideFaces = HostObjectUtils.GetTopFaces(revitFloor); secondSideFaces = HostObjectUtils.GetBottomFaces(revitFloor); break; } Element faceElement = doc.GetElement(firstSideFaces[0]); if (!(faceElement.GetGeometryObjectFromReference(firstSideFaces[0]) is Face exteriorFace) || !(faceElement.GetGeometryObjectFromReference(secondSideFaces[0]) is Face interiorFace)) { return(null); } //this lets us pick the biggest face of the two sides. This is important because we want the shapes to close. 😁 Face face = exteriorFace.Area > interiorFace.Area ? exteriorFace : interiorFace; // get the edges as curve loops and use the IFCUtils to sort them // credit: https://thebuildingcoder.typepad.com/blog/2015/01/getting-the-wall-elevation-profile.html IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops(); //this does the sorting so outside is the first item IList <CurveLoop> loops = ExporterIFCUtils.SortCurveLoops(curveLoops)[0]; for (int i = 0; i < loops.Count; i++) { //here for outermost loop if (i == 0) { var outer = loops[i]; List <Vector3> vertices = new List <Vector3>(); foreach (Autodesk.Revit.DB.Curve c in outer) { vertices.Add(c.GetEndPoint(0).ToVector3()); } polygons.Add(new Polygon(vertices)); } //here for the inner loops (voids) else { var inner = loops[i]; List <Vector3> vertices = new List <Vector3>(); foreach (Autodesk.Revit.DB.Curve c in inner) { vertices.Add(c.GetEndPoint(0).ToVector3()); } Polygon innerPolygon = new Polygon(vertices); polygons.Add(innerPolygon); } } return(polygons); }
public List <EdgeSegment> GetRawData(Room room, double DistanceToWall, double UnitWidth) { //Used to store the wall object. List <EdgeSegment> rSegments = new List <EdgeSegment>(); #region The basics and datas const double er = 0.0001;//used for error correction. Document doc = room.Document; Autodesk.Revit.ApplicationServices.Application app = doc.Application; //get the level height of floor and ceiling //!!!!!current not consider different ceiling height or floor.Need improving. double levelC = room.ClosedShell.GetBoundingBox().Max.Z; double levelF = room.ClosedShell.GetBoundingBox().Min.Z; //Custom input data. double dist2W = DistanceToWall; double unitW = UnitWidth; #endregion //get the boundary segments list IList <IList <BoundarySegment> > boundarys = room.GetBoundarySegments(new SpatialElementBoundaryOptions()); //Loop through all the wall segment needed to oprate on //first layer is each boundary loop(in case a room has multiple boundaries) foreach (IList <BoundarySegment> groupSegments in boundarys) { //The stack is for the segments(one wall can be several segments) //The queue is for the wall after merging the segments. Stack <EdgeSegment> eSegments = new Stack <EdgeSegment>(); List <EdgeSegment> eSegmentsMerged = new List <EdgeSegment>(); //Second layer is the actual segment //in this loop process each segment opening info and log them foreach (BoundarySegment segment in groupSegments) { #region Create the object,get the inner edge of a wall segment EdgeSegment theSeg = new EdgeSegment(); Curve segCrv = segment.GetCurve(); XYZ start = segCrv.GetEndPoint(0); XYZ end = segCrv.GetEndPoint(1); XYZ normal; theSeg.levelC = levelC; theSeg.levelF = levelF; theSeg.start = new XYZ(start.X, start.Y, levelF); theSeg.end = new XYZ(end.X, end.Y, levelF); #endregion //The boundary segment may not be a wall Element wallOrNot = doc.GetElement(segment.ElementId); #region Seperate different category(Wall,Column or others) Categories docCat = doc.Settings.Categories; ElementId idColumn = docCat.get_Item(BuiltInCategory.OST_Columns).Id; ElementId idWall = docCat.get_Item(BuiltInCategory.OST_Walls).Id; //Case 1-A column or the end of a single wall. if ((wallOrNot == null) || (wallOrNot.Category.Id.Equals(idColumn))) { //The room segments always search counterclockwise //Thus compute the normal as follow //Other data is not needed.Treat it as a full wall. XYZ line = end - start; normal = new XYZ(-line.Y, line.X, 0); theSeg.normal = normal / normal.GetLength(); eSegments.Push(theSeg); continue; } //Case 2-Not column or wall.(Most likely curtain)Mark as noPanel. if (!(wallOrNot.Category.Id.Equals(idWall))) { theSeg.NoPanel = true; eSegments.Push(theSeg); continue; } //Case 3-Walls Wall theWall = wallOrNot as Wall; #endregion #region Get the sideface of a wall and get the profile curves IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(theWall, ShellLayerType.Exterior); //get the real face(why so long???) Face face = doc.GetElement(sideFaces[0]) .GetGeometryObjectFromReference(sideFaces[0]) as Face; //get edge loops as curveloops IList <CurveLoop> openLoops = face.GetEdgesAsCurveLoops(); #endregion //Some basic properties of the face. normal = face.ComputeNormal(new UV(0, 0)); Plane plane = Plane.CreateByNormalAndOrigin(normal, start); #region Check if curves are on the inner plane or not. //(Might be on the other side of the wall) //Log the correction vector in correction. Curve checkCurve = openLoops[0].GetEnumerator().Current; plane.Project(checkCurve.GetEndPoint(1), out UV uv, out double dist); Transform correction = Transform.CreateTranslation(new XYZ(0, 0, 0)); if (dist > er) //Same wired reason.See "const double er" up front. { normal = -normal; correction = Transform.CreateTranslation(dist * normal); plane = Plane.CreateByNormalAndOrigin(normal, start); } #endregion //Store all the endpoints and horizontal curves. List <XYZ> points = new List <XYZ>(); List <Curve> hoCrvs = new List <Curve>(); foreach (CurveLoop curveloop in openLoops) { foreach (Curve curve in curveloop) { points.Add(correction.OfPoint(curve.GetEndPoint(0))); //If curve is horizontal,and in the middle range,log it double cSz = curve.GetEndPoint(0).Z; double cEz = curve.GetEndPoint(1).Z; if ((Math.Abs(cSz - cEz) < er) && (cSz > levelF + er) && (cSz < levelC - er)) { hoCrvs.Add(curve.CreateTransformed(correction)); } } } #region Sort pts according to curve direction var tempPts = from point in points where ((point.Z > levelF + er) && (point.Z < levelC - er)) select new XYZ(point.X, point.Y, levelF); List <XYZ> relayPts = tempPts.ToList <XYZ>(); relayPts.Add(start); relayPts.Add(end); var sortPt = from point in relayPts where (segCrv.Distance(point) < er) orderby(point - start).GetLength() select point; List <XYZ> sortPtList = sortPt .Distinct(new PtEqualComparer()) .ToList <XYZ>(); if (!(sortPtList[0] == start)) { sortPtList.Reverse(); } sortPtList.RemoveAt(sortPtList.Count - 1); sortPtList.RemoveAt(0); #endregion #region log the data theSeg.crvList = hoCrvs; theSeg.ptList = sortPtList; theSeg.normal = normal; #endregion //Find insert element(and project on plane) List <ElementId> insertIds = theWall .FindInserts(true, true, true, true).Distinct().ToList(); foreach (ElementId eId in insertIds) { Element currentRoom = doc.GetElement(eId); BoundingBoxXYZ box = currentRoom.get_Geometry(new Options()).GetBoundingBox(); XYZ ept = 0.5 * (box.Max + box.Min); XYZ v = ept - plane.Origin; double signedDist = plane.Normal.DotProduct(v); XYZ eptnew = ept - signedDist * normal; theSeg.insertPts.Add(eptnew); } //Push to the stack. eSegments.Push(theSeg); } #region Merge from segments to walls... //Merge the segments that are on same curve. int segNum = eSegments.Count; EdgeSegment sNew; for (int i = 1; i < segNum; i++) { EdgeSegment s1 = eSegments.Pop(); EdgeSegment s2 = eSegments.Pop(); if (!(s2.MergeWith(s1, out sNew))) { eSegmentsMerged.Add(s1); } eSegments.Push(sNew); } //Compare the final one to the first one again EdgeSegment sf1 = eSegmentsMerged[0]; EdgeSegment sf2 = eSegments.Pop(); if (sf2.MergeWith(sf1, out sNew)) { eSegmentsMerged.RemoveAt(0); } eSegmentsMerged.Add(sNew); //Because the use of stack,the order need to be reversed back. eSegmentsMerged.Reverse(); #endregion #region Set the offset for each corner according to dist2W int wallNum = eSegmentsMerged.Count; eSegmentsMerged.Add(eSegmentsMerged[0]); for (int i = 0; i < wallNum; i++) { EdgeSegment SegCur = eSegmentsMerged[i]; EdgeSegment SegAft = eSegmentsMerged[i + 1]; double angle = SegCur.unitV.AngleOnPlaneTo(SegAft.unitV, XYZ.BasisZ); SegCur.end -= Math.Tan(0.5 * angle) * dist2W * SegCur.unitV; SegAft.start += Math.Tan(0.5 * angle) * (dist2W + UnitUtils.ConvertToInternalUnits(10, DisplayUnitType.DUT_MILLIMETERS)) * SegAft.unitV; } eSegmentsMerged.RemoveAt(eSegmentsMerged.Count - 1); #endregion rSegments.AddRange(eSegmentsMerged); } return(rSegments); }
private Reference GetWallSideFaceRef() { IList <Reference> wallSideFaceRefs = HostObjectUtils.GetSideFaces(Wall, ShellLayerType.Interior); return(wallSideFaceRefs[0]); }
Transform.CreateTranslation(_offset); // 2014 #endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; Options opt = app.Create.NewGeometryOptions(); XyzEqualityComparer comparer = new XyzEqualityComparer(1e-6); #if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES Creator creator = new Creator(doc); Transaction t = new Transaction(doc); t.Start("Create model curve copies of top face edges"); #endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES IList <Face> topFaces = new List <Face>(); int n; int nWalls = 0; //foreach( Element e in uidoc.Selection.Elements ) // 2014 foreach (ElementId id in uidoc.Selection.GetElementIds()) // 2015 { Element e = doc.GetElement(id); Wall wall = e as Wall; if (null == wall) { Debug.Print("Skipped " + Util.ElementDescription(e)); continue; } // Get the side faces IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior); // Access the first side face Element e2 = doc.GetElement(sideFaces[0]); Debug.Assert(e2.Id.Equals(e.Id), "expected side face element to be the wall itself"); Face face = e2.GetGeometryObjectFromReference( sideFaces[0]) as Face; if (null == face) { Debug.Print("No side face found for " + Util.ElementDescription(e)); continue; } // When there are opening such as doors or // windows in the wall, we need to find the // outer loop. // For one possible approach to extract the // outermost loop, please refer to // http://thebuildingcoder.typepad.com/blog/2008/12/2d-polygon-areas-and-outer-loop.html // Determine the outer loop of the side face // by finding the polygon with the largest area XYZ normal; double area, dist, maxArea = 0; EdgeArray outerLoop = null; foreach (EdgeArray ea in face.EdgeLoops) { if (CmdWallProfileArea.GetPolygonPlane( ea.GetPolygon(), out normal, out dist, out area) && Math.Abs(area) > Math.Abs(maxArea)) { maxArea = area; outerLoop = ea; } } n = 0; #if GET_FACES_FROM_OUTER_LOOP // With the outermost loop, calculate the top faces foreach (Edge edge in outerLoop) { // For each edge, get the neighbouring // face and check its normal for (int i = 0; i < 2; ++i) { PlanarFace pf = edge.get_Face(i) as PlanarFace; if (null == pf) { Debug.Print("Skipped non-planar face on " + Util.ElementDescription(e)); continue; } if (Util.PointsUpwards(pf.Normal, 0.9)) { if (topFaces.Contains(pf)) { Debug.Print("Duplicate face on " + Util.ElementDescription(e)); } else { topFaces.Add(pf); ++n; } } } } #endif // GET_FACES_FROM_OUTER_LOOP List <XYZ> sideVertices = outerLoop.GetPolygon(); // Go over all the faces of the wall and // determine which ones fulfill the following // two criteria: (i) planar face pointing // upwards, and (ii) neighbour of the side // face outer loop. Solid solid = wall.get_Geometry(opt) .OfType <Solid>() .First <Solid>(sol => null != sol); foreach (Face f in solid.Faces) { if (IsTopFace(f)) { IList <XYZ> faceVertices = f.Triangulate().Vertices; //if( sideVertices.Exists( v // => faceVertices.Contains<XYZ>( v, comparer ) ) ) //{ // topFaces.Add( f ); // ++n; //} foreach (XYZ v in faceVertices) { if (sideVertices.Contains <XYZ>( v, comparer)) { topFaces.Add(f); ++n; #if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES // Display face for debugging purposes foreach (EdgeArray ea in f.EdgeLoops) { IEnumerable <Curve> curves = ea.Cast <Edge>() .Select <Edge, Curve>( x => x.AsCurve()); foreach (Curve curve in curves) { //creator.CreateModelCurve( curve.get_Transformed( _t ) ); // 2013 creator.CreateModelCurve(curve.CreateTransformed(_t)); // 2014 } } #endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES break; } } } } Debug.Print(string.Format( "{0} top face{1} found on {2} ({3})", n, Util.PluralSuffix(n), Util.ElementDescription(e)), nWalls++); } #if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES t.Commit(); #endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES string s = string.Format( "{0} wall{1} successfully processed", nWalls, Util.PluralSuffix(nWalls)); n = topFaces.Count; TaskDialog.Show("Wall Top Faces", string.Format( "{0} with {1} top face{2}.", s, n, Util.PluralSuffix(n))); return(Result.Succeeded); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; View view = doc.ActiveView; //TaskDialog.Show("Revit", "Hello World"); // Create filters and collect walls/ slabs/ columns id in corresponding collector // walls IList <ElementId> walls_id = new List <ElementId>(); FilteredElementCollector wall_collector = new FilteredElementCollector(doc).OfClass(typeof(Wall)); foreach (Element w in wall_collector) { if (w is Wall) { walls_id.Add(w.Id); } } // columns IList <ElementId> columns_id = new List <ElementId>(); FilteredElementCollector column_collector = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns); foreach (Element c in column_collector) { if (c is FamilyInstance) { columns_id.Add(c.Id); } } // slabs IList <ElementId> slabs_id = new List <ElementId>(); FilteredElementCollector collector = new FilteredElementCollector(doc).OfClass(typeof(Floor)); foreach (Element e in collector) { if (e is Floor) { slabs_id.Add(e.Id); } } //call create parts on walls/ slabs/ columns collectors using (Transaction t = new Transaction(doc, "Create Part")) { t.Start(); // Create parts from the selected element // There is "CreateParts" but no "CreatePart", so needed to use a list containing the one element PartUtils.CreateParts(doc, walls_id); PartUtils.CreateParts(doc, columns_id); PartUtils.CreateParts(doc, slabs_id); t.Commit(); } // start divide parts for walls, columns, slabs foreach (ElementId w_id in walls_id) { ICollection <ElementId> partsList = PartUtils.GetAssociatedParts(doc, w_id, true, true); // Get all levels ICollection <ElementId> levels = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).ToElementIds(); // Create a list of curves which needs to be used in DivideParts but for this example // the divide is being done by levels so the curve list will be empty IList <Curve> curve_list = new List <Curve>(); // Get the host object corresponding to the selected element // HostObject is the parent class for walls, roof, floors, etc. HostObject hostObj = doc.GetElement(w_id) as HostObject; // Get the reference of one of the major faces of the selected element // Will be used to create a sketch plane Reference r = HostObjectUtils.GetSideFaces(hostObj, ShellLayerType.Exterior).First(); using (Transaction t = new Transaction(doc, "Divide Part at Levels")) { t.Start(); //Plane ref_plane = Plane.CreateByNormalAndOrigin(faceNormal, XYZ.Zero); SketchPlane wall_sketchPlane = SketchPlane.Create(doc, r); //SketchPlane sketchPlane = doc.Create.NewSketchPlane(r); // Divide the parts PartUtils.DivideParts(doc, partsList, levels, curve_list, wall_sketchPlane.Id); t.Commit(); } } // since walls and columns are all divided by all levels, so just use the sketch-plane of the last wall element ElementId borrow_from_wall = walls_id[0]; foreach (ElementId c_id in columns_id) { ICollection <ElementId> partsList = PartUtils.GetAssociatedParts(doc, c_id, true, true); ICollection <ElementId> levels = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).ToElementIds(); IList <Curve> curve_list = new List <Curve>(); HostObject hostObj = doc.GetElement(borrow_from_wall) as HostObject; Reference r = HostObjectUtils.GetSideFaces(hostObj, ShellLayerType.Exterior).First(); using (Transaction t = new Transaction(doc, "Divide Part at Levels")) { t.Start(); SketchPlane column_sketchPlane = SketchPlane.Create(doc, r); PartUtils.DivideParts(doc, partsList, levels, curve_list, column_sketchPlane.Id); t.Commit(); } } foreach (ElementId s_id in slabs_id) { //Selection sel = uidoc.Selection; //ISelectionFilter f = new JtElementsOfClassSelectionFilter<Grid>(); //Reference elemRef = sel.PickObject(ObjectType.Element, f, "Pick a grid"); //Grid grid = doc.GetElement(elemRef) as Grid; //ICollection<ElementId> grid_list = new List<ElementId>(); //grid_list.Add(grid.Id); //IList<Curve> gridCurves = grid.GetCurvesInView(DatumExtentType.Model, view); ICollection <ElementId> partsList = PartUtils.GetAssociatedParts(doc, s_id, true, true); // Get all levels ICollection <ElementId> grids = new FilteredElementCollector(doc).OfClass(typeof(Grid)).OfCategory(BuiltInCategory.OST_Grids).ToElementIds(); // Create a list of curves which needs to be used in DivideParts but for this example // the divide is being done by levels so the curve list will be empty IList <Curve> curve_list = new List <Curve>(); HostObject hostObj = doc.GetElement(s_id) as HostObject; Reference r = HostObjectUtils.GetTopFaces(hostObj).First(); using (Transaction t = new Transaction(doc, "Divide Part at Grids")) { t.Start(); //Transaction sketchPlaneTransaction = new Transaction(doc, "Create Sketch Plane"); SketchPlane grid_sketchPlane = SketchPlane.Create(doc, r); //SketchPlane grid_sketchPlane = null; //sketchPlaneTransaction.Commit(); PartUtils.DivideParts(doc, partsList, grids, curve_list, grid_sketchPlane.Id); t.Commit(); } } // Set the view's "Parts Visibility" parameter so that parts are shown Parameter p = doc.ActiveView.get_Parameter(BuiltInParameter.VIEW_PARTS_VISIBILITY); using (Transaction t = new Transaction(doc, "Set View Parameter")) { t.Start(); p.Set(0); // 0 = Show Parts, 1 = Show Original, 2 = Show Both t.Commit(); } //ICollection<ElementId> elementIdsToDivide = new List<ElementId>(); //if (PartUtils.AreElementsValidForCreateParts(doc, slabs_id)) //{ // // AreElementsValidForCreateParts returned true, so the selected element is not a part but it is an element that can be used to create a part. // Transaction createPartTransaction = new Transaction(doc, "Create Part"); // createPartTransaction.Start(); // PartUtils.CreateParts(doc, slabs_id); // create the parts // createPartTransaction.Commit(); // foreach (ElementId e_id in slabs_id) // { // elementIdsToDivide = PartUtils.GetAssociatedParts(doc, e_id, true, true); // }// get the id of the newly created part //} ////else if (pickedElement is Part) ////{ //// // The selected element is a part, so that part will be divided. //// elementIdsToDivide.Add(pickedElement.Id); ////} //// Create geometry that will be used to divide the part. For this example, a new part will be divided from the main part that is one quarter of the face. More complex intelligence could be coded to divide the part based on construction logistics or the properties of the materials being used to create the part. //XYZ pointRight = null; //XYZ pointTop = null; //XYZ pointCorner = null; //XYZ pointCenter = null; //SketchPlane sketchPlane = null; //Plane plane = null; //Options opt = new Options(); //opt.ComputeReferences = true; //foreach (Element e in slabs) //{ // GeometryElement geomElem = e.get_Geometry(opt); // foreach (GeometryObject geomObject in geomElem) // { // if (geomObject is Solid) // get the solid geometry of the selected element // { // Solid solid = geomObject as Solid; // FaceArray faceArray = solid.Faces; // foreach (Face face in faceArray) // { // // find the center of the face // BoundingBoxUV bbox = face.GetBoundingBox(); // UV center = new UV((bbox.Max.U - bbox.Min.U) / 2 + bbox.Min.U, (bbox.Max.V - bbox.Min.V) / 2 + bbox.Min.V); // XYZ faceNormal = face.ComputeNormal(center); // if (faceNormal.IsAlmostEqualTo(XYZ.BasisZ)) // this example is designed to work with a floor or other element with a large face whose normal is in the Z direction // { // Transaction sketchPlaneTransaction = new Transaction(doc, "Create Sketch Plane"); // sketchPlaneTransaction.Start(); // plane = Plane.CreateByNormalAndOrigin(faceNormal, XYZ.Zero); // sketchPlane = SketchPlane.Create(doc, plane); // //sketchPlane = doc.SketchPlane.Create(face as PlanarFace); // sketchPlaneTransaction.Commit(); // pointCenter = face.Evaluate(center); // UV top = new UV((bbox.Max.U - bbox.Min.U) / 2 + bbox.Min.U, bbox.Max.V); // pointTop = face.Evaluate(top); // UV right = new UV(bbox.Max.U, (bbox.Max.V - bbox.Min.V) / 2 + bbox.Min.V); // pointRight = face.Evaluate(right); // UV corner = new UV(bbox.Max.U, bbox.Max.V); // pointCorner = face.Evaluate(corner); // break; // } // } // } // } //} ////Selection sel = uidoc.Selection; ////Reference elemRef = sel.PickObject( ////ObjectType.Element, f, "Pick a grid"); ////Grid grid = doc.GetElement(elemRef) as Grid; //// Create the curves that will be used for the part division. //IList<Curve> curveList = new List<Curve>(); ////Curve curve1 = app.Create.NewLine(pointCenter, pointRight, true); //Curve curve1 = Line.CreateBound(pointCenter, pointRight); //curveList.Add(curve1); ////Curve curve2 = app.Create.NewLine(pointRight, pointCorner, true); //Curve curve2 = Line.CreateBound(pointRight, pointCorner); //curveList.Add(curve2); ////Curve curve3 = app.Create.NewLine(pointCorner, pointTop, true); //Curve curve3 = Line.CreateBound(pointCorner, pointTop); //curveList.Add(curve3); ////Curve curve4 = app.Create.NewLine(pointTop, pointCenter, true); //Curve curve4 = Line.CreateBound(pointTop, pointCenter); //curveList.Add(curve4); //// intersectingReferenceIds will be empty for this example. //ICollection<ElementId> intersectingReferenceIds = new List<ElementId>(); //// Divide the part //Transaction dividePartTransaction = new Transaction(doc, "Divide Part"); //dividePartTransaction.Start(); //PartMaker maker = PartUtils.DivideParts(doc, elementIdsToDivide, intersectingReferenceIds, curveList, sketchPlane.Id); //dividePartTransaction.Commit(); ////ICollection<ElementId> divElems = maker.GetSourceElementIds(); // Get the ids of the divided elements //// Set the view's "Parts Visibility" parameter so that parts are shown //Parameter partVisInView = doc.ActiveView.get_Parameter(BuiltInParameter.VIEW_PARTS_VISIBILITY); //Transaction setPartVizTransaction = new Transaction(doc, "Set View Parameter"); //setPartVizTransaction.Start(); //partVisInView.Set(0); // 0 = Show Parts, 1 = Show Original, 2 = Show Both //setPartVizTransaction.Commit(); ////// Access current selection return(Result.Succeeded); }
public static List<Face> GetWallSideFace(Wall wall, bool isOuterFace) { var refs = HostObjectUtils.GetSideFaces(wall, isOuterFace ? ShellLayerType.Exterior : ShellLayerType.Interior); return refs.Select(rf => wall.GetGeometryObjectFromReference(rf) as Face).Where(obj => obj != null).ToList(); }
/// <summary> /// Improved implementation by Alexander Ignatovich /// supporting curved wall with curved window, /// second attempt, published April 10, 2015: /// </summary> public Result Execute3( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; View view = doc.ActiveView; Autodesk.Revit.Creation.Application creapp = app.Create; Autodesk.Revit.Creation.Document credoc = doc.Create; Reference r = uidoc.Selection.PickObject( ObjectType.Element, "Select a wall"); Element e = uidoc.Document.GetElement(r); Creator creator = new Creator(doc); Wall wall = e as Wall; if (wall == null) { return(Result.Cancelled); } using (Transaction tx = new Transaction(doc)) { tx.Start("Wall Profile"); // Get the external wall face for the profile // a little bit simpler than in the last realization Reference sideFaceReference = HostObjectUtils.GetSideFaces( wall, ShellLayerType.Exterior) .First(); Face face = wall.GetGeometryObjectFromReference( sideFaceReference) as Face; // The normal of the wall external face. XYZ normal = wall.Orientation; // Offset curve copies for visibility. Transform offset = Transform.CreateTranslation( 5 * normal); // If the curve loop direction is counter- // clockwise, change its color to RED. Color colorRed = new Color(255, 0, 0); // Get edge loops as curve loops. IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops(); foreach (var curveLoop in curveLoops) { CurveArray curves = creapp.NewCurveArray(); foreach (Curve curve in curveLoop) { curves.Append(curve.CreateTransformed( offset)); } var isCounterClockwize = curveLoop .IsCounterclockwise(normal); // Create model lines for an curve loop if it is made if (((LocationCurve)wall.Location).Curve is Line) { //Plane plane = creapp.NewPlane( curves ); // 2016 Plane plane = CurveLoop.CreateViaOffset( curveLoop, 5 * normal.GetLength(), normal.Normalize()).GetPlane(); // 2017 SketchPlane sketchPlane = SketchPlane.Create(doc, plane); ModelCurveArray curveElements = credoc .NewModelCurveArray(curves, sketchPlane); if (isCounterClockwize) { SetModelCurvesColor(curveElements, view, colorRed); } } else { foreach (var curve in curves.Cast <Curve>()) { var curveElements = creator.CreateModelCurves(curve); if (isCounterClockwize) { SetModelCurvesColor(curveElements, view, colorRed); } } } } tx.Commit(); } return(Result.Succeeded); }
public void InsertOpening(Document doc, FamilySymbol familySymbol) { Element host = doc.GetElement(HostId); if (host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Walls) { Wall wall = host as Wall; Reference reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior).First(); ElementId levelId = host.LevelId; Face face = host.GetGeometryObjectFromReference(reference) as Face; IntersectionResult intResult = face.Project(LocationPoint); if (intResult == null) { return; // important to prompt user if no face found } double distance = intResult.Distance; if (distance > 0.001) { reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior).First();; } FamilyInstance fi = doc.Create.NewFamilyInstance(reference, LocationPoint, new XYZ(0, 0, 0), familySymbol); Parameter parameter = fi.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM); if (parameter != null) { parameter.Set(levelId); } if (OpeningType == OpeningType.Round) { fi.LookupParameter("D").Set(_cloudOpening.Diameter); fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset); fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid); } if (OpeningType == OpeningType.Rectangular) { fi.LookupParameter("b").Set(_cloudOpening.Width); fi.LookupParameter("h").Set(_cloudOpening.Height); fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset); fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid); } fi.LookupParameter("Depth").Set(Depth); } if (host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Floors) { Floor floor = host as Floor; Reference reference = HostObjectUtils.GetTopFaces(floor).First(); ElementId levelId = host.LevelId; FamilyInstance fi = doc.Create.NewFamilyInstance(reference, LocationPoint, new XYZ(0, 0, 0), familySymbol); Parameter parameter = fi.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM); if (parameter != null) { parameter.Set(levelId); } if (OpeningType == OpeningType.Round) { fi.LookupParameter("D").Set(_cloudOpening.Diameter); fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset); fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid); } if (OpeningType == OpeningType.Rectangular) { fi.LookupParameter("b").Set(_cloudOpening.Width); fi.LookupParameter("h").Set(_cloudOpening.Height); fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset); fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid); } fi.LookupParameter("Depth").Set(Depth); } if (host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Ceilings) { Ceiling ceiling = host as Ceiling; Reference reference = HostObjectUtils.GetTopFaces(ceiling).First(); ElementId levelId = host.LevelId; FamilyInstance fi = doc.Create.NewFamilyInstance(reference, LocationPoint, new XYZ(0, 0, 0), familySymbol); Parameter parameter = fi.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM); if (parameter != null) { parameter.Set(levelId); } if (OpeningType == OpeningType.Round) { fi.LookupParameter("D").Set(_cloudOpening.Diameter); fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset); fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid); } if (OpeningType == OpeningType.Rectangular) { fi.LookupParameter("b").Set(_cloudOpening.Width); fi.LookupParameter("h").Set(_cloudOpening.Height); fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset); fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid); } fi.LookupParameter("Depth").Set(_cloudOpening.Depth); } if (host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Roofs) { Reference reference = null; ExtrusionRoof eRoof = host as ExtrusionRoof; List <Reference> references = HostObjectUtils.GetTopFaces(eRoof).ToList(); foreach (Reference r in references) { Face face = host.GetGeometryObjectFromReference(r) as Face; //bool test = face.IsInside(new UV(LocationPoint.X, LocationPoint.Y)); IntersectionResult intResult = face.Project(LocationPoint); if (intResult == null) { continue; } double distance = intResult.Distance; if (distance < 0.001) { reference = r; } } if (reference == null) { return; } ElementId levelId = host.LevelId; FamilyInstance fi = doc.Create.NewFamilyInstance(reference, LocationPoint, new XYZ(0, 0, 0), familySymbol); Parameter parameter = fi.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM); if (parameter != null) { parameter.Set(levelId); } if (OpeningType == OpeningType.Round) { fi.LookupParameter("D").Set(_cloudOpening.Diameter); fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset); fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid); } if (OpeningType == OpeningType.Rectangular) { fi.LookupParameter("b").Set(_cloudOpening.Width); fi.LookupParameter("h").Set(_cloudOpening.Height); fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset); fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid); } fi.LookupParameter("Depth").Set(_cloudOpening.Depth); } }
public bool DoCreateSockets() { this.LoadSocketsFamilies(ActiveDoc); Document doc = this.ActiveDoc; List <A_Socket> allSockets = CurrentHouse.Floors .SelectMany(f => f.Socket) .ToList(); List <A_Wall> allWalls = CurrentHouse.Floors .SelectMany(f => f.Walls) .ToList(); if (allSockets.Count() == 0) { return(false); } foreach (A_Socket soc in allSockets) { XYZ centerPt = new XYZ (soc.X, soc.Y, soc.Z + BaseLevel.Elevation); XYZ dirPt = new XYZ (0 - soc.Orientation.Y, soc.Orientation.X, 0); ///Get all the face of the host wall. Wall hostWall = allWalls .First(w => w.Uid == soc.Related.Uid).Wall; List <Reference> sideFaces = HostObjectUtils.GetSideFaces (hostWall, ShellLayerType.Exterior) .ToList(); sideFaces.AddRange( HostObjectUtils.GetSideFaces (hostWall, ShellLayerType.Interior) .ToList()); ///Find the face where the socket is located. Reference hostFace = sideFaces .OrderBy(f => centerPt.DistanceTo ((doc.GetElement(f) .GetGeometryObjectFromReference(f) as Face) .Project(centerPt).XYZPoint)) .First(); if (hostFace == null) { continue; } ///Choose the type. Family socFam; switch (soc.Tag) { case "五孔": socFam = AutoSocketFamilies .First(s => (s.Name.Contains("五孔")) && (!s.Name.Contains("防水"))); break; case "五孔防水": socFam = AutoSocketFamilies .First(s => s.Name.Contains("五孔防水")); break; case "网络电视": socFam = AutoSocketFamilies .First(s => s.Name.Contains("网络电视")); break; default: socFam = AutoSocketFamilies .First(s => s.Name.Contains(soc.Tag)); break; } FamilySymbol socSymbol = doc.GetElement (socFam.GetFamilySymbolIds().First()) as FamilySymbol; socSymbol.Activate(); soc.Instance = doc.Create .NewFamilyInstance (hostFace, centerPt, dirPt, socSymbol); ActiveForm.UpdateProgress(socketWorkLoad); } return(true); }