public override Value Evaluate(FSharpList <Value> args) { Curve curve = (Curve)((Value.Container)args[0]).Item; double thickness = ((Value.Number)args[1]).Item; XYZ normal = (XYZ)((Value.Container)args[2]).Item; Autodesk.Revit.DB.CurveLoop thickenLoop = Autodesk.Revit.DB.CurveLoop.CreateViaThicken(curve.Clone(), thickness, normal); if (thickenLoop == null) { throw new Exception("Could not offset curve"); } CurveLoopIterator CLiter = thickenLoop.GetCurveLoopIterator(); Curve result = null; //relying heavily on the order of curves in the resulting curve loop, based on internal implemen for (int index = 0; CLiter.MoveNext(); index++) { if (index == 2) { result = CLiter.Current.Clone(); } } if (result == null) { throw new Exception("Could not offset curve"); } return(Value.NewContainer(result)); }
public static IEnumerable <Curve> ToCurves(this CurveLoop curveLoop) { List <Curve> curveArray = new List <Curve>(); CurveLoopIterator curveLoopIterator = curveLoop.GetCurveLoopIterator(); while (curveLoopIterator.MoveNext()) { yield return(curveLoopIterator.Current); } }
public override Value Evaluate(FSharpList <Value> args) { Autodesk.Revit.DB.CurveLoop curveLoop = (Autodesk.Revit.DB.CurveLoop)((Value.Container)args[0]).Item; CurveLoopIterator CLiter = curveLoop.GetCurveLoopIterator(); List <Curve> listCurves = new List <Curve>(); for (; CLiter.MoveNext();) { listCurves.Add(CLiter.Current.Clone()); } var result = FSharpList <Value> .Empty; for (int indexCurve = listCurves.Count - 1; indexCurve > -1; indexCurve--) { result = FSharpList <Value> .Cons(Value.NewContainer(listCurves[indexCurve]), result); } return(Value.NewList(result)); }
/// <summary> /// Returns the surface which defines the internal shape of the face /// </summary> /// <param name="lcs">The local coordinate system for the surface. Can be null.</param> /// <returns>The surface which defines the internal shape of the face</returns> public override Surface GetSurface(Transform lcs) { Curve sweptCurve = null; // Get the RuledSurface which is used to create the geometry from the brepbuilder if (!(SweptCurve is IFCSimpleProfile)) { return(null); } else { // Currently there is no easy way to get the curve from the IFCProfile, so for now we assume that // the SweptCurve is an IFCSimpleProfile and its outer curve only contains one curve, which is the // profile curve that we want IFCSimpleProfile simpleSweptCurve = SweptCurve as IFCSimpleProfile; CurveLoop outerCurve = simpleSweptCurve.OuterCurve; if (outerCurve == null) { return(null); } CurveLoopIterator it = outerCurve.GetCurveLoopIterator(); sweptCurve = it.Current; } // Position/transform the Curve first according to the lcs of the IfcSurfaceOfLinearExtrusion sweptCurve = sweptCurve.CreateTransformed(Position); // Create the second profile curve by translating the first one in the extrusion direction Curve profileCurve2 = sweptCurve.CreateTransformed(Transform.CreateTranslation(ExtrudedDirection.Multiply(Depth))); if (lcs == null) { return(RuledSurface.Create(sweptCurve, profileCurve2)); } Curve transformedProfileCurve1 = sweptCurve.CreateTransformed(lcs); Curve transformedProfileCurve2 = profileCurve2.CreateTransformed(lcs); return(RuledSurface.Create(transformedProfileCurve1, transformedProfileCurve2)); }
public FloorsCFBRRequest(UIApplication uiApp, String text) { MainUI uiForm = BARevitTools.Application.thisApp.newMainUi; UIDocument uidoc = uiApp.ActiveUIDocument; FloorType selectedFloorType = null; //Get the name of the floor type selected in the MainUI string selectedFloorTypeName = uiForm.floorsCFBRSelectFloorTypeComboBox.Text.ToString(); //Create lists to use locally from the rooms selected from the MainUI, the collection of floor types, and to store newly created floors. List <Room> roomElements = uiForm.floorsCFBRRoomsList; List <FloorType> floorTypes = RVTGetElementsByCollection.DocumentFloorTypes(uiApp); List <Floor> newFloors = new List <Floor>(); //First, make sure the user is running the tool from a plan view if (uidoc.ActiveView.GetType().ToString() != "Autodesk.Revit.DB.ViewPlan") { MessageBox.Show("Please run from a plan view"); } else { //If they are int a plan view, start a transaction Transaction t1 = new Transaction(uidoc.Document, "CreateFloorsByRoom"); t1.Start(); //Cycle through the floor types in the project until the one with a name matching the one selected in the MainUI is found foreach (FloorType floorType in floorTypes) { if (floorType.Name.ToString() == selectedFloorTypeName) { selectedFloorType = floorType; break; } else { continue; } } try { //Generate new GeometryOptions to allow evaluation of room volumes that may not be visible. Options geomOptions = new Options(); geomOptions.IncludeNonVisibleObjects = true; //For each room that was selected with the MainUI... foreach (Room room in roomElements) { //Create a new iterable list for the CurveLoops reprsenting the edges of the room boundary IList <CurveLoop> faceCurveLoops = null; //Get the level associated with the room for floor creation Level roomLevel = room.Level; //Get the geometry of the room GeometryElement roomGeomElements = room.get_Geometry(geomOptions); Solid roomSolid = null; //Cycle through the geometry associated with the room until the solid form is found foreach (GeometryObject geom in roomGeomElements) { if (geom.GetType().ToString() == "Autodesk.Revit.DB.Solid") { roomSolid = geom as Solid; break; } } //If the solid form of the room was found, continue if (roomSolid != null) { //Get the faces of the solid FaceArray solidFaces = roomSolid.Faces; foreach (PlanarFace solidFace in solidFaces) { //Check the direction of the face normal XYZ faceNormal = solidFace.FaceNormal; //If the face normal faced down, it is a bottom face. Because the room cannot be split into multiple portions, //and a split level room is unlikely, it is safe to select the first downward face. if (faceNormal.Z == -1) { //Get the edges of the face as curve loops faceCurveLoops = solidFace.GetEdgesAsCurveLoops(); break; } } } //If the face's curve loops were retrieved, continue if (faceCurveLoops.Count != 0) { try { //Make a new CurveArray from the loops CurveArray curveArray = new CurveArray(); foreach (CurveLoop cloop in faceCurveLoops) { CurveLoopIterator cLoopIter = cloop.GetCurveLoopIterator(); while (cLoopIter.MoveNext()) { curveArray.Append(cLoopIter.Current); } } //The new floow will require the CurveArray, FloorType, Level, and boolean for making it structural (false for this tool's purpose) Floor newFloor = uidoc.Document.Create.NewFloor(curveArray, selectedFloorType, roomLevel, false); //After making the floor, add it to the list of new floors created newFloors.Add(newFloor); } catch { //If the room had more than one edge loop, such as another room was enveloped by the selected room, the operation will fail because the API only allows one loop MessageBox.Show(string.Format("Floor could not be made for {0}, which is likely due to the room having more than one boundary loop. The Revit API only allows for one contiuous loop.", room.Number.ToString())); } } } t1.Commit(); //Provide some feedback to the MainUI uiForm.floorsCFBRDoneLabel.Visible = true; uiForm.floorsCFBRRoomsList = new List <Room>(); } catch { t1.RollBack(); } //If the user wanted to offset the floors by their thickness, this will offset the newly made and collected floors if (uiForm.floorsCFBROffsetFinishFloorCheckBox.Checked) { Transaction t2 = new Transaction(uidoc.Document, "ElevateFloors"); t2.Start(); try { //Cycle through the list of new floors foreach (Floor floor in newFloors) { //Make a new set of geometry options Options geomOptions = new Options(); geomOptions.IncludeNonVisibleObjects = true; //Get the floor geometry and the bounding box of the geometry GeometryElement floorGeometry = floor.get_Geometry(geomOptions); BoundingBoxXYZ floorBBox = floorGeometry.GetBoundingBox(); //Use the minimum and maximum Z coordinates from the bounding box to determine the floor thickness because that's not natively supported in the Revit API double bBoxMinZ = floorBBox.Min.Z; double bBoxMaxZ = floorBBox.Max.Z; double floorThickness = bBoxMaxZ - bBoxMinZ; //Move the floor up with a translation in the Z axis by the thickness value XYZ translation = new XYZ(0, 0, floorThickness); ElementTransformUtils.MoveElement(uidoc.Document, floor.Id, translation); } t2.Commit(); } catch { t2.RollBack(); } } } }
/// <summary> /// Create a curve representation of this IFCCompositeCurve from a curveloop /// </summary> /// <param name="curveLoop">The curveloop</param> /// <returns>A Revit curve that is made by appending every curve in the given curveloop, if possible</returns> private Curve ConvertCurveLoopIntoSingleCurve(CurveLoop curveLoop) { if (curveLoop == null) { return(null); } CurveLoopIterator curveIterator = curveLoop.GetCurveLoopIterator(); Curve firstCurve = curveIterator.Current; Curve returnCurve = null; double vertexEps = IFCImportFile.TheFile.Document.Application.VertexTolerance; // We only connect the curves if they are Line, Arc or Ellipse if (!((firstCurve is Line) || (firstCurve is Arc) || (firstCurve is Ellipse))) { return(null); } XYZ firstStartPoint = firstCurve.GetEndPoint(0); Curve currentCurve = null; if (firstCurve is Line) { Line firstLine = firstCurve as Line; while (curveIterator.MoveNext()) { currentCurve = curveIterator.Current; if (!(currentCurve is Line)) { return(null); } Line currentLine = currentCurve as Line; if (!(firstLine.Direction.IsAlmostEqualTo(currentLine.Direction))) { return(null); } } returnCurve = Line.CreateBound(firstStartPoint, currentCurve.GetEndPoint(1)); } else if (firstCurve is Arc) { Arc firstArc = firstCurve as Arc; XYZ firstCurveNormal = firstArc.Normal; while (curveIterator.MoveNext()) { currentCurve = curveIterator.Current; if (!(currentCurve is Arc)) { return(null); } XYZ currentStartPoint = currentCurve.GetEndPoint(0); XYZ currentEndPoint = currentCurve.GetEndPoint(1); Arc currentArc = currentCurve as Arc; XYZ currentCenter = currentArc.Center; double currentRadius = currentArc.Radius; XYZ currentNormal = currentArc.Normal; // We check if this circle is similar to the first circle by checking that they have the same center, same radius, // and lie on the same plane if (!(currentCenter.IsAlmostEqualTo(firstArc.Center, vertexEps) && MathUtil.IsAlmostEqual(currentRadius, firstArc.Radius, vertexEps))) { return(null); } if (!MathUtil.IsAlmostEqual(Math.Abs(currentNormal.DotProduct(firstCurveNormal)), 1)) { return(null); } } // If all of the curve segments are part of the same circle, then the returning curve will be a circle bounded // by the start point of the first curve and the end point of the last curve. XYZ lastPoint = currentCurve.GetEndPoint(1); if (lastPoint.IsAlmostEqualTo(firstStartPoint, vertexEps)) { firstCurve.MakeUnbound(); } else { double startParameter = firstArc.GetEndParameter(0); double endParameter = firstArc.Project(lastPoint).Parameter; if (endParameter < startParameter) { endParameter += Math.PI * 2; } firstCurve.MakeBound(startParameter, endParameter); } returnCurve = firstCurve; } else if (firstCurve is Ellipse) { Ellipse firstEllipse = firstCurve as Ellipse; double radiusX = firstEllipse.RadiusX; double radiusY = firstEllipse.RadiusY; XYZ xDirection = firstEllipse.XDirection; XYZ yDirection = firstEllipse.YDirection; XYZ firstCurveNormal = firstEllipse.Normal; while (curveIterator.MoveNext()) { currentCurve = curveIterator.Current; if (!(currentCurve is Ellipse)) { return(null); } XYZ currentStartPoint = currentCurve.GetEndPoint(0); XYZ currentEndPoint = currentCurve.GetEndPoint(1); Ellipse currentEllipse = currentCurve as Ellipse; XYZ currentCenter = currentEllipse.Center; double currentRadiusX = currentEllipse.RadiusX; double currentRadiusY = currentEllipse.RadiusY; XYZ currentXDirection = currentEllipse.XDirection; XYZ currentYDirection = currentEllipse.YDirection; XYZ currentNormal = currentEllipse.Normal; if (!MathUtil.IsAlmostEqual(Math.Abs(currentNormal.DotProduct(firstCurveNormal)), 1)) { return(null); } // We determine whether this ellipse is the same as the initial ellipse by checking if their centers and corresponding // radiuses as well as radius directions are the same or permutations of each other. if (!currentCenter.IsAlmostEqualTo(firstEllipse.Center)) { return(null); } // Checks if the corresponding radius and radius direction are the same if (MathUtil.IsAlmostEqual(radiusX, currentRadiusX)) { if (!(MathUtil.IsAlmostEqual(radiusY, currentRadiusY) && currentXDirection.IsAlmostEqualTo(xDirection) && currentYDirection.IsAlmostEqualTo(yDirection))) { return(null); } } // Checks if the corresponding radiuses and radius directions are permutations of each other else if (MathUtil.IsAlmostEqual(radiusX, currentRadiusY)) { if (!(MathUtil.IsAlmostEqual(radiusY, currentRadiusX) && currentXDirection.IsAlmostEqualTo(yDirection) && currentYDirection.IsAlmostEqualTo(xDirection))) { return(null); } } else { return(null); } } // If all of the curve segments are part of the same ellipse then the returning curve will be the ellipse whose start point is the start // point of the first curve and the end point is the end point of the last curve XYZ lastPoint = currentCurve.GetEndPoint(1); if (lastPoint.IsAlmostEqualTo(firstStartPoint)) { firstCurve.MakeUnbound(); } else { double startParameter = firstEllipse.GetEndParameter(0); double endParameter = firstEllipse.Project(lastPoint).Parameter; if (endParameter < startParameter) { endParameter += Math.PI * 2; } firstCurve.MakeBound(startParameter, endParameter); } returnCurve = firstCurve; } return(returnCurve); }
public override FScheme.Value Evaluate(FSharpList <FScheme.Value> args) { Autodesk.Revit.DB.CurveLoop cl = (Autodesk.Revit.DB.CurveLoop)((FScheme.Value.Container)args[0]).Item; if (cl == null) { throw new InvalidOperationException("No curve loop"); } Autodesk.Revit.DB.Plane plane = cl.GetPlane(); if (plane == null) { throw new InvalidOperationException("Curve loop is not planar"); } var mcs = new System.Collections.Generic.List <Autodesk.Revit.DB.ModelCurve>(); var listCurves = new System.Collections.Generic.List <Curve> (); CurveLoopIterator CLiter = cl.GetCurveLoopIterator(); for (; CLiter.MoveNext();) { listCurves.Add(CLiter.Current.Clone()); } int numCurves = listCurves.Count; Autodesk.Revit.DB.SketchPlane sp = null; for (int index = 0; index < numCurves; index++) { //instead of changing Revit curve keep it "as is" //user might have trouble modifying curve in Revit if it is off the sketch plane Autodesk.Revit.DB.ModelCurve mc = null; if (this.Elements.Any() && index < this.Elements.Count) { bool needsRemake = false; if (dynUtils.TryGetElement(this.Elements[index], out mc)) { ElementId idSpUnused = ModelCurve.resetSketchPlaneMethod(mc, listCurves[index], plane, out needsRemake); if (idSpUnused != ElementId.InvalidElementId && index == numCurves - 1) { this.DeleteElement(idSpUnused); } if (!needsRemake) { if (!mc.GeometryCurve.IsBound && listCurves[index].IsBound) { listCurves[index] = listCurves[index].Clone(); listCurves[index].MakeUnbound(); } ModelCurve.setCurveMethod(mc, listCurves[index]); // mc.GeometryCurve = c; } else { this.DeleteElement(this.Elements[index]); } } else { needsRemake = true; } if (needsRemake) { if (sp == null) { sp = dynRevitSettings.Doc.Document.IsFamilyDocument ? dynRevitSettings.Doc.Document.FamilyCreate.NewSketchPlane(plane) : dynRevitSettings.Doc.Document.Create.NewSketchPlane(plane); } if (dynRevitUtils.GetPlaneFromCurve(listCurves[index], true) == null) { mc = this.UIDocument.Document.IsFamilyDocument ? this.UIDocument.Document.FamilyCreate.NewModelCurve(listCurves[index], sp) : this.UIDocument.Document.Create.NewModelCurve(listCurves[index], sp); ModelCurve.setCurveMethod(mc, listCurves[index]); } else { mc = this.UIDocument.Document.IsFamilyDocument ? this.UIDocument.Document.FamilyCreate.NewModelCurve(listCurves[index], sp) : this.UIDocument.Document.Create.NewModelCurve(listCurves[index], sp); } if (index < this.Elements.Count) { this.Elements[index] = mc.Id; } else { this.Elements.Add(mc.Id); } if (mc.SketchPlane.Id != sp.Id && index == numCurves - 1) { //THIS BIZARRE as Revit could use different existing SP, so if Revit had found better plane this sketch plane has no use this.DeleteElement(sp.Id); } } } else { if (sp == null) { sp = dynRevitSettings.Doc.Document.IsFamilyDocument ? dynRevitSettings.Doc.Document.FamilyCreate.NewSketchPlane(plane) : dynRevitSettings.Doc.Document.Create.NewSketchPlane(plane); } if (dynRevitUtils.GetPlaneFromCurve(listCurves[index], true) == null) { mc = this.UIDocument.Document.IsFamilyDocument ? this.UIDocument.Document.FamilyCreate.NewModelCurve(listCurves[index], sp) : this.UIDocument.Document.Create.NewModelCurve(listCurves[index], sp); ModelCurve.setCurveMethod(mc, listCurves[index]); } else { mc = this.UIDocument.Document.IsFamilyDocument ? this.UIDocument.Document.FamilyCreate.NewModelCurve(listCurves[index], sp) : this.UIDocument.Document.Create.NewModelCurve(listCurves[index], sp); } this.Elements.Add(mc.Id); if (mc.SketchPlane.Id != sp.Id && index == numCurves - 1) { //found better plane this.DeleteElement(sp.Id); } } if (mc != null) { mcs.Add(mc); } } FSharpList <FScheme.Value> results = FSharpList <FScheme.Value> .Empty; foreach (var mc in mcs) { results = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(mc), results); } return(FScheme.Value.NewList(Utils.SequenceToFSharpList(results.Reverse()))); }
/// <summary> /// 在房间X的中心创建四个方向的立面 /// Create four Elevations on the center of the "X" of the selRoom /// </summary> /// <param name="elevationOffset"></param> /// <param name="FloorThickness"></param> public void CreateElevations(double elevationOffset, double FloorThickness) { int i = 0;//循环用 //获取立面的familytype Get the familyType of Elevation FilteredElementCollector collector = new FilteredElementCollector(DocSet.doc); collector.OfClass(typeof(ViewFamilyType)); var viewFamilyTypes = from elem in collector let type = elem as ViewFamilyType where type.ViewFamily == ViewFamily.Elevation select type; ElementId viewTypeId; if (viewFamilyTypes.Count() > 0) { viewTypeId = viewFamilyTypes.First().Id; } else { return; } using (Transaction tran = new Transaction(DocSet.doc)) { //房间的"X"的交点 LocationPoint pt = DocSet.selRoom.Location as LocationPoint; tran.Start("newElvation"); ElevationMarker marker = ElevationMarker.CreateElevationMarker(DocSet.doc, viewTypeId, pt.Point, 50); for (; i < 4; i++) { ViewSection sv = marker.CreateElevation(DocSet.doc, DocSet.doc.ActiveView.Id, i); //设定立面的 远剪裁偏移 sv.get_Parameter(BuiltInParameter.VIEWER_BOUND_OFFSET_FAR).SetValueString("10000"); //设定每个立面的名称 XYZ normal = null;//法向量 string elevationName = "ELE -"; switch (i) { case 0: elevationName += " West " + _SoANumber; normal = new XYZ(-1, 0, 0); sv.get_Parameter(BuiltInParameter.VIEW_DESCRIPTION).Set("ELEVATION WEST"); break; case 1: elevationName += " North" + _SoANumber; normal = new XYZ(0, 1, 0); sv.get_Parameter(BuiltInParameter.VIEW_DESCRIPTION).Set("ELEVATION NORTH"); break; case 2: elevationName += " East" + _SoANumber; normal = new XYZ(1, 0, 0); sv.get_Parameter(BuiltInParameter.VIEW_DESCRIPTION).Set("ELEVATION EAST"); break; case 3: elevationName += " South" + _SoANumber; normal = new XYZ(0, -1, 0); sv.get_Parameter(BuiltInParameter.VIEW_DESCRIPTION).Set("ELEVATION SOUTH"); break; } sv.ViewName = elevationName; //不能删 必须先保存修改才能获取上面的元素 tran.Commit(); tran.Start("change elevation crop shape"); //小指型房间专用修改 if (cbSpRoom.IsChecked == true) { if (i == 1 || i == 2) { normal = -normal; } spRoomElevationChange(sv, elevationOffset, normal, FloorThickness); } else { //修改立面底边的高度 XYZ pt1 = null; XYZ pt2 = null; XYZ pt3 = null; XYZ pt4 = null; sv.CropBoxActive = true; ViewCropRegionShapeManager vcrShanpMgr = sv.GetCropRegionShapeManager(); CurveLoop loop = vcrShanpMgr.GetCropShape().First(); CurveLoopIterator iterator = loop.GetCurveLoopIterator(); //分辨点的位置 while (iterator.MoveNext()) { Curve curve = iterator.Current; XYZ pt0 = curve.GetEndPoint(0); if (-1 < pt0.Z - pt.Point.Z && pt0.Z - pt.Point.Z < 1) { if (pt1 == null) { pt1 = pt0; } else { pt2 = pt0; } } else { if (pt3 == null) { pt3 = pt0; } else { pt4 = pt0; } } } //重新生成一个边界框 //TaskDialog.Show("1", pt1.ToString() + "\n" + pt2.ToString() + "\n" + pt3.ToString() + "\n" + pt4.ToString()); pt1 = new XYZ(pt1.X, pt1.Y, pt1.Z + FloorThickness / 300); pt2 = new XYZ(pt2.X, pt2.Y, pt1.Z); Line lineBottom = Line.CreateBound(pt1, pt2); Line lineRight = Line.CreateBound(pt2, pt4); Line lineTop = Line.CreateBound(pt4, pt3); Line lineLeft = Line.CreateBound(pt3, pt1); CurveLoop profile = new CurveLoop(); profile.Append(lineBottom); profile.Append(lineRight); profile.Append(lineTop); profile.Append(lineLeft); profile = CurveLoop.CreateViaOffset(profile, elevationOffset / 300, -normal); vcrShanpMgr.SetCropShape(profile); } } tran.Commit(); } }