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); } }
/// <summary> /// Set the representation of the curve based on one CurveLoop. /// </summary> /// <param name="curveLoop">The one CurveLoop.</param> public void SetCurveLoop(CurveLoop curveLoop) { Curve = null; CurveLoops = null; if (curveLoop == null) { return; } if (curveLoop.NumberOfCurves() == 1) { Curve = curveLoop.GetCurveLoopIterator().Current; } CurveLoops = new List <CurveLoop>(); CurveLoops.Add(curveLoop); }
/// <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)); }
Result IExternalCommand.Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; FinishForm MainForm = new FinishForm(doc); MainForm.disFElements("New"); MainForm.ShowDialog(); double FT = 0.3048; Phase lastPhase = MainForm.retPhase; ElementId idPhase = lastPhase.Id; //Выбираем элементы в Ревите ICollection <ElementId> selectedElements = uidoc.Selection.GetElementIds(); List <Room> selectedRooms = selectedElements.Select(x => doc.GetElement(x) as Room).ToList(); //Находим граничные элементы помещения //SpatialElementBoundaryOptions options = new SpatialElementBoundaryOptions(); List <IList <IList <BoundarySegment> > > roomBounds = selectedRooms.Select(x => x.GetBoundarySegments(new SpatialElementBoundaryOptions())).ToList(); //foreach (var r in selectedRooms) //{ // roomBounds.Add(r.GetBoundarySegments(options)); //} //Получаем элементы границ и несоединенные кривые List <Element> roomElems = new List <Element>(); List <List <List <Curve> > > disjoinedCurves = new List <List <List <Curve> > >(); foreach (IList <IList <BoundarySegment> > rb in roomBounds) { List <List <Curve> > tempCrvList = new List <List <Curve> >(); foreach (var closedCrv in rb) { List <Curve> tempCCCrvList = new List <Curve>(); foreach (var elem in closedCrv) { tempCCCrvList.Add(elem.GetCurve()); if (doc.GetElement(elem.ElementId) == null)//Если элемент косячный { roomElems.Add(null); } else { roomElems.Add(doc.GetElement(elem.ElementId)); } } tempCrvList.Add(tempCCCrvList); } disjoinedCurves.Add(tempCrvList); } //Соединяем кривые в полилинии List <List <CurveLoop> > joinedCurvesUnfl = new List <List <CurveLoop> >(); foreach (var d in disjoinedCurves) { List <CurveLoop> tempList = d.Select(x => CurveLoop.Create(x)).ToList(); joinedCurvesUnfl.Add(tempList); } //Check the sense of polycurve foreach (var j in joinedCurvesUnfl) { foreach (CurveLoop crv in j) { if (crv.GetPlane().Normal.Z < 0) { crv.Flip(); } } } List <string> getRoomNumbers = new List <string>(); List <List <Room> > repeatedRoomsUnfl = new List <List <Room> >(); int count = 0; foreach (var j in joinedCurvesUnfl) { List <Room> tempList = new List <Room>(); foreach (CurveLoop crv in j) { tempList.Add(selectedRooms.ElementAt(count)); } repeatedRoomsUnfl.Add(tempList); count += 1; } List <Room> repeatedRoomsFl = GenericList <Room> .Flatten(repeatedRoomsUnfl); List <CurveLoop> joinedCurvesFl = GenericList <CurveLoop> .Flatten(joinedCurvesUnfl); List <string> wHeights = new List <string>(); List <Element> wTypes = new List <Element>(); List <Element> allWallTypes = new FilteredElementCollector(doc).OfClass(typeof(WallType)).ToList(); //GlobalParameter OTD_Main; //using (Transaction tryGlobal = new Transaction(doc, "defineGlobal")) //{ // tryGlobal.Start(); // if (GlobalParametersManager.FindByName(doc, "ОТД_Основная") != ElementId.InvalidElementId) // { // OTD_Main = doc.GetElement(GlobalParametersManager.FindByName(doc, "ОТД_Основная")) as GlobalParameter; // } // else // { // OTD_Main = GlobalParameter.Create(doc, "ОТД_Основная", ParameterType.Text); // } // tryGlobal.Commit(); //} string s_OTD_Main = MainForm.wTypeBoxes[0]; //string s_OTD_Main = ((StringParameterValue)OTD_Main.GetValue()).Value; //wTypes.Add(MainForm.wTypeBoxes) foreach (Element wt in allWallTypes) { if (wt.Name == s_OTD_Main) { wTypes.Add(wt); } } //foreach (Room r in repeatedRoomsFl) //{ // //wHeights.Add(r.getP(s_OTD_Main)); // //allWallTypes.Where(x => x.Name == r.getP("setFFF")).ToList(); // foreach (Element wt in allWallTypes) // { // if (wt.Name==r.getP(s_OTD_Main)) // { // wTypes.Add(wt); // } // } //} //Level of each room List <Level> levels = repeatedRoomsFl.Select(x => x.Level).ToList(); //Create offset curve List <CurveLoop> offsetedCurves = new List <CurveLoop>(); DisplayUnitType docLengthUnit = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits; count = 0; foreach (CurveLoop j in joinedCurvesFl) { double valueWith = wTypes[0].get_Parameter(BuiltInParameter.WALL_ATTR_WIDTH_PARAM).AsDouble(); //double value = UnitUtils.Convert(valueWith, DisplayUnitType.DUT_DECIMAL_FEET, docLengthUnit); double value = valueWith / FT; CurveLoop gg = CurveLoop.CreateViaOffset(j, (valueWith * (0.5)), j.GetPlane().Normal); if (repeatedRoomsFl[count].IsPointInRoom(gg.GetCurveLoopIterator().Current.GetEndPoint(0)) == true) { offsetedCurves.Add(gg); } else { //offsetedCurves.Add(gg); try { offsetedCurves.Add(CurveLoop.CreateViaOffset(j, (valueWith * (-0.5)), j.GetPlane().Normal)); } catch (Exception) { } } count += 1; } List <List <Curve> > explodedCurves = new List <List <Curve> >(); foreach (CurveLoop oc in offsetedCurves) { List <Curve> tempList = new List <Curve>(); foreach (Curve i in oc) { tempList.Add(i); } explodedCurves.Add(tempList); } List <Wall> walls = new List <Wall>(); using (Transaction tr = new Transaction(doc, "PerimetralWall")) { tr.Start(); count = 0; foreach (List <Curve> group in explodedCurves) { foreach (Curve crv in group) { Wall w = Wall.Create(doc, crv, wTypes[0].Id, levels[count].Id, 2 / FT, 0, false, false); walls.Add(w); } count += 1; } count = 0; foreach (Wall w in walls) { w.get_Parameter(BuiltInParameter.WALL_ATTR_ROOM_BOUNDING).Set(0); w.get_Parameter(BuiltInParameter.WALL_KEY_REF_PARAM).Set(2); w.DemolishedPhaseId = lastPhase.Id; //w.setP("Помещение", repeatedRoomsFl[count].Number); count += 1; } count = 0; /* * foreach (Element r in roomElems) * { * try * { * JoinGeometryUtils.JoinGeometry(doc, walls[count], r); * } * catch (Exception) * { * * * } * count += 1; * } */ tr.Commit(); } return(Result.Succeeded); }
/// <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; // 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) && MathUtil.IsAlmostEqual(currentRadius, firstArc.Radius))) { 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)) { 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; }
/// <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); }
/// <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(); } }