Пример #1
0
        void ReconstructWallByCurve
        (
            DB.Document doc,
            ref DB.Wall element,

            Rhino.Geometry.Curve curve,
            Optional <DB.WallType> type,
            Optional <DB.Level> level,
            Optional <double> height,
            [Optional] DB.WallLocationLine locationLine,
            [Optional] bool flipped,
            [Optional, NickName("J")] bool allowJoins,
            [Optional] DB.Structure.StructuralWallUsage structuralUsage
        )
        {
#if REVIT_2020
            if
            (
                !(curve.IsLinear(Revit.VertexTolerance * Revit.ModelUnits) || curve.IsArc(Revit.VertexTolerance * Revit.ModelUnits) || curve.IsEllipse(Revit.VertexTolerance * Revit.ModelUnits)) ||
                !curve.TryGetPlane(out var axisPlane, Revit.VertexTolerance * Revit.ModelUnits) ||
                axisPlane.ZAxis.IsParallelTo(Rhino.Geometry.Vector3d.ZAxis, Revit.AngleTolerance) == 0
            )
            {
                ThrowArgumentException(nameof(curve), "Curve must be a horizontal line, arc or ellipse curve.");
            }
#else
            if
            (
                !(curve.IsLinear(Revit.VertexTolerance * Revit.ModelUnits) || curve.IsArc(Revit.VertexTolerance * Revit.ModelUnits)) ||
                !curve.TryGetPlane(out var axisPlane, Revit.VertexTolerance * Revit.ModelUnits) ||
                axisPlane.ZAxis.IsParallelTo(Rhino.Geometry.Vector3d.ZAxis, Revit.AngleTolerance) == 0
            )
            {
                ThrowArgumentException(nameof(curve), "Curve must be a horizontal line or arc curve.");
            }
#endif

            SolveOptionalType(ref type, doc, DB.ElementTypeGroup.WallType, nameof(type));

            bool levelIsEmpty = SolveOptionalLevel(doc, curve, ref level, out var bbox);

            // Curve
            var levelPlane = new Rhino.Geometry.Plane(new Rhino.Geometry.Point3d(0.0, 0.0, level.Value.GetHeight() * Revit.ModelUnits), Rhino.Geometry.Vector3d.ZAxis);
            if (!TryGetCurveAtPlane(curve, levelPlane, out var centerLine))
            {
                ThrowArgumentException(nameof(curve), "Failed to project curve in the level plane.");
            }

            // Height
            if (!height.HasValue)
            {
                height = type.GetValueOrDefault()?.GetCompoundStructure()?.SampleHeight *Revit.ModelUnits ?? LiteralLengthValue(6.0);
            }

            if (height.Value < 0.1 * Revit.ModelUnits)
            {
                ThrowArgumentException(nameof(height), $"Height minimum value is {0.1 * Revit.ModelUnits} {Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem}");
            }
            else if (height.Value > 3000 * Revit.ModelUnits)
            {
                ThrowArgumentException(nameof(height), $"Height maximum value is {3000 * Revit.ModelUnits} {Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem}");
            }

            // LocationLine
            if (locationLine != DB.WallLocationLine.WallCenterline)
            {
                double offsetDist        = 0.0;
                var    compoundStructure = type.Value.GetCompoundStructure();
                if (compoundStructure == null)
                {
                    switch (locationLine)
                    {
                    case DB.WallLocationLine.WallCenterline:
                    case DB.WallLocationLine.CoreCenterline:
                        break;

                    case DB.WallLocationLine.FinishFaceExterior:
                    case DB.WallLocationLine.CoreExterior:
                        offsetDist = type.Value.Width / +2.0;
                        break;

                    case DB.WallLocationLine.FinishFaceInterior:
                    case DB.WallLocationLine.CoreInterior:
                        offsetDist = type.Value.Width / -2.0;
                        break;
                    }
                }
                else
                {
                    if (!compoundStructure.IsVerticallyHomogeneous())
                    {
                        compoundStructure = DB.CompoundStructure.CreateSimpleCompoundStructure(compoundStructure.GetLayers());
                    }

                    offsetDist = compoundStructure.GetOffsetForLocationLine(locationLine);
                }

                if (offsetDist != 0.0)
                {
                    centerLine = centerLine.CreateOffset(flipped ? -offsetDist : offsetDist, DB.XYZ.BasisZ);
                }
            }

            // Type
            ChangeElementTypeId(ref element, type.Value.Id);

            DB.Wall newWall = null;
            if (element is DB.Wall previousWall && previousWall.Location is DB.LocationCurve locationCurve && centerLine.IsSameKindAs(locationCurve.Curve))
            {
                newWall = previousWall;

                locationCurve.Curve = centerLine;
            }
Пример #2
0
        void ReconstructWallByCurve
        (
            DB.Document doc,
            ref DB.Wall element,

            Rhino.Geometry.Curve curve,
            Optional <DB.WallType> type,
            Optional <DB.Level> level,
            [Optional] double height,
            [Optional] DB.WallLocationLine locationLine,
            [Optional] bool flipped,
            [Optional, NickName("J")] bool allowJoins,
            [Optional] DB.Structure.StructuralWallUsage structuralUsage
        )
        {
            var scaleFactor = 1.0 / Revit.ModelUnits;

#if REVIT_2020
            if
            (
                ((curve = curve.ChangeUnits(scaleFactor)) is null) ||
                !(curve.IsLinear(Revit.VertexTolerance) || curve.IsArc(Revit.VertexTolerance) || curve.IsEllipse(Revit.VertexTolerance)) ||
                !curve.TryGetPlane(out var axisPlane, Revit.VertexTolerance) ||
                axisPlane.ZAxis.IsParallelTo(Rhino.Geometry.Vector3d.ZAxis) == 0
            )
            {
                ThrowArgumentException(nameof(curve), "Curve must be a horizontal line, arc or ellipse curve.");
            }
#else
            if
            (
                ((curve = curve.ChangeUnits(scaleFactor)) is null) ||
                !(curve.IsLinear(Revit.VertexTolerance) || curve.IsArc(Revit.VertexTolerance)) ||
                !curve.TryGetPlane(out var axisPlane, Revit.VertexTolerance) ||
                axisPlane.ZAxis.IsParallelTo(Rhino.Geometry.Vector3d.ZAxis) == 0
            )
            {
                ThrowArgumentException(nameof(curve), "Curve must be a horizontal line or arc curve.");
            }
#endif

            SolveOptionalType(ref type, doc, DB.ElementTypeGroup.WallType, nameof(type));

            bool levelIsEmpty = SolveOptionalLevel(doc, curve, ref level, out var bbox);

            height *= scaleFactor;
            if (height < Revit.VertexTolerance)
            {
                height = type.GetValueOrDefault()?.GetCompoundStructure()?.SampleHeight ?? LiteralLengthValue(6.0) / Revit.ModelUnits;
            }

            // Axis
            var levelPlane = new Rhino.Geometry.Plane(new Rhino.Geometry.Point3d(0.0, 0.0, level.Value.Elevation), Rhino.Geometry.Vector3d.ZAxis);
            curve = Rhino.Geometry.Curve.ProjectToPlane(curve, levelPlane);

            var centerLine = curve.ToHost();

            // LocationLine
            if (locationLine != DB.WallLocationLine.WallCenterline)
            {
                double offsetDist        = 0.0;
                var    compoundStructure = type.Value.GetCompoundStructure();
                if (compoundStructure == null)
                {
                    switch (locationLine)
                    {
                    case DB.WallLocationLine.WallCenterline:
                    case DB.WallLocationLine.CoreCenterline:
                        break;

                    case DB.WallLocationLine.FinishFaceExterior:
                    case DB.WallLocationLine.CoreExterior:
                        offsetDist = type.Value.Width / +2.0;
                        break;

                    case DB.WallLocationLine.FinishFaceInterior:
                    case DB.WallLocationLine.CoreInterior:
                        offsetDist = type.Value.Width / -2.0;
                        break;
                    }
                }
                else
                {
                    if (!compoundStructure.IsVerticallyHomogeneous())
                    {
                        compoundStructure = DB.CompoundStructure.CreateSimpleCompoundStructure(compoundStructure.GetLayers());
                    }

                    offsetDist = compoundStructure.GetOffsetForLocationLine(locationLine);
                }

                if (offsetDist != 0.0)
                {
                    centerLine = centerLine.CreateOffset(flipped ? -offsetDist : offsetDist, DB.XYZ.BasisZ);
                }
            }

            // Type
            ChangeElementTypeId(ref element, type.Value.Id);

            DB.Wall newWall = null;
            if (element is DB.Wall previousWall && previousWall.Location is DB.LocationCurve locationCurve && centerLine.IsSameKindAs(locationCurve.Curve))
            {
                newWall = previousWall;

                locationCurve.Curve = centerLine;
            }
Пример #3
0
        void ReconstructWallByProfile
        (
            DB.Document doc,
            ref DB.Wall element,

            IList <Rhino.Geometry.Curve> profile,
            Optional <DB.WallType> type,
            Optional <DB.Level> level,
            [Optional] DB.WallLocationLine locationLine,
            [Optional] bool flipped,
            [Optional, NickName("J")] bool allowJoins,
            [Optional] DB.Structure.StructuralWallUsage structuralUsage
        )
        {
            foreach (var boundary in profile)
            {
                if
                (
                    !boundary.IsClosed ||
                    !boundary.TryGetPlane(out var boundaryPlane, Revit.VertexTolerance) ||
                    !boundaryPlane.ZAxis.IsPerpendicularTo(Rhino.Geometry.Vector3d.ZAxis)
                )
                {
                    ThrowArgumentException(nameof(boundary), "Boundary must be a vertical planar closed curve.");
                }
            }

            SolveOptionalType(ref type, doc, DB.ElementTypeGroup.WallType, nameof(type));
            SolveOptionalLevel(doc, profile, ref level, out var bbox);

            foreach (var curve in profile)
            {
                curve.RemoveShortSegments(Revit.ShortCurveTolerance * Revit.ModelUnits);
            }
            var boundaries = profile.SelectMany(x => GeometryEncoder.ToCurveMany(x)).SelectMany(CurveExtension.ToBoundedCurves).ToList();

            // LocationLine
            if (locationLine != DB.WallLocationLine.WallCenterline)
            {
                double offsetDist        = 0.0;
                var    compoundStructure = type.Value.GetCompoundStructure();
                if (compoundStructure == null)
                {
                    switch (locationLine)
                    {
                    case DB.WallLocationLine.WallCenterline:
                    case DB.WallLocationLine.CoreCenterline:
                        break;

                    case DB.WallLocationLine.FinishFaceExterior:
                    case DB.WallLocationLine.CoreExterior:
                        offsetDist = type.Value.Width / +2.0;
                        break;

                    case DB.WallLocationLine.FinishFaceInterior:
                    case DB.WallLocationLine.CoreInterior:
                        offsetDist = type.Value.Width / -2.0;
                        break;
                    }
                }
                else
                {
                    if (!compoundStructure.IsVerticallyHomogeneous())
                    {
                        compoundStructure = DB.CompoundStructure.CreateSimpleCompoundStructure(compoundStructure.GetLayers());
                    }

                    offsetDist = compoundStructure.GetOffsetForLocationLine(locationLine);
                }

                if (offsetDist != 0.0)
                {
                    profile[0].TryGetPlane(out var plane);
                    var translation = DB.Transform.CreateTranslation((plane.Normal * (flipped ? -offsetDist : offsetDist)).ToXYZ());
                    for (int b = 0; b < boundaries.Count; ++b)
                    {
                        boundaries[b] = boundaries[b].CreateTransformed(translation);
                    }
                }
            }

            var newWall = DB.Wall.Create
                          (
                doc,
                boundaries,
                type.Value.Id,
                level.Value.Id,
                structuralUsage != DB.Structure.StructuralWallUsage.NonBearing
                          );

            // Walls are created with the last LocationLine used in the Revit editor!!
            //newWall.get_Parameter(BuiltInParameter.WALL_KEY_REF_PARAM).Set((int) WallLocationLine.WallCenterline);

            var parametersMask = new DB.BuiltInParameter[]
            {
                DB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM,
                DB.BuiltInParameter.ELEM_FAMILY_PARAM,
                DB.BuiltInParameter.ELEM_TYPE_PARAM,
                DB.BuiltInParameter.WALL_KEY_REF_PARAM,
                DB.BuiltInParameter.WALL_USER_HEIGHT_PARAM,
                DB.BuiltInParameter.WALL_BASE_CONSTRAINT,
                DB.BuiltInParameter.WALL_BASE_OFFSET,
                DB.BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT,
                DB.BuiltInParameter.WALL_STRUCTURAL_USAGE_PARAM
            };

            ReplaceElement(ref element, newWall, parametersMask);

            if (newWall != null)
            {
                newWall.get_Parameter(DB.BuiltInParameter.WALL_BASE_CONSTRAINT).Set(level.Value.Id);
                newWall.get_Parameter(DB.BuiltInParameter.WALL_BASE_OFFSET).Set(bbox.Min.Z / Revit.ModelUnits - level.Value.Elevation);
                newWall.get_Parameter(DB.BuiltInParameter.WALL_KEY_REF_PARAM).Set((int)locationLine);
                if (structuralUsage == DB.Structure.StructuralWallUsage.NonBearing)
                {
                    newWall.get_Parameter(DB.BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).Set(0);
                }
                else
                {
                    newWall.get_Parameter(DB.BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).Set(1);
                    newWall.get_Parameter(DB.BuiltInParameter.WALL_STRUCTURAL_USAGE_PARAM).Set((int)structuralUsage);
                }

                if (newWall.Flipped != flipped)
                {
                    newWall.Flip();
                }

                // Setup joins in a last step
                if (allowJoins)
                {
                    joinedWalls.Add(newWall);
                }
                else
                {
                    DB.WallUtils.DisallowWallJoinAtEnd(newWall, 0);
                    DB.WallUtils.DisallowWallJoinAtEnd(newWall, 1);
                }
            }
        }