Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        /// <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));
        }
Esempio n. 5
0
        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(); }
                }
            }
        }
Esempio n. 6
0
        /// <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);
        }
Esempio n. 7
0
        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();
            }
        }