/// <summary>
        /// Get the hook orient of the top rebar
        /// </summary>
        /// <param name="geomInfo">the rebar geometry support information</param>
        /// <param name="location">the location of top rebar</param>
        /// <returns>the hook orient of the top hook</returns>
        private RebarHookOrientation GetTopHookOrient(RebarGeometry geomInfo, TopRebarLocation location)
        {
            // Top center rebar doesn't need hook.
            if (TopRebarLocation.Center == location)
            {
                throw new Exception("Center top rebar doesn't have any hook.");
            }

            // Get the hook direction, rebar normal and rebar line
            Autodesk.Revit.DB.XYZ hookVec = m_geometry.GetDownDirection();
            Autodesk.Revit.DB.XYZ normal  = geomInfo.Normal;
            Line rebarLine = geomInfo.Curves[0] as Line;

            // get the top start hook orient
            if (TopRebarLocation.Start == location)
            {
                Autodesk.Revit.DB.XYZ curveVec = GeomUtil.SubXYZ(rebarLine.GetEndPoint(1), rebarLine.GetEndPoint(0));
                return(GeomUtil.GetHookOrient(curveVec, normal, hookVec));
            }
            else // get the top end hook orient
            {
                Autodesk.Revit.DB.XYZ curveVec = GeomUtil.SubXYZ(rebarLine.GetEndPoint(0), rebarLine.GetEndPoint(1));
                return(GeomUtil.GetHookOrient(curveVec, normal, hookVec));
            }
        }
示例#2
0
        /// <summary>
        /// Get two vectors, which indicate some edge direction which contain given point,
        /// set the given point as the start point, the other end point of the edge as end
        /// </summary>
        /// <param name="point">a point of the swept profile</param>
        /// <returns>two vectors indicate edge direction</returns>
        protected List <Autodesk.Revit.DB.XYZ> GetRelatedVectors(Autodesk.Revit.DB.XYZ point)
        {
            // Initialize the return vector list.
            List <Autodesk.Revit.DB.XYZ> vectors = new List <Autodesk.Revit.DB.XYZ>();

            // Get all the edge which contain this point.
            // And get the vector from this point to another point
            foreach (Line line in m_edges)
            {
                if (GeomUtil.IsEqual(point, line.GetEndPoint(0)))
                {
                    Autodesk.Revit.DB.XYZ vector = GeomUtil.SubXYZ(line.GetEndPoint(1), line.GetEndPoint(0));
                    vectors.Add(vector);
                }
                if (GeomUtil.IsEqual(point, line.GetEndPoint(1)))
                {
                    Autodesk.Revit.DB.XYZ vector = GeomUtil.SubXYZ(line.GetEndPoint(0), line.GetEndPoint(1));
                    vectors.Add(vector);
                }
            }

            // only two vector(direction) should be found
            if (2 != vectors.Count)
            {
                throw new Exception("a point on swept profile should have only two direction.");
            }

            return(vectors);
        }
        /// <summary>
        /// Create the transverse rebars, according to the location of transverse rebars
        /// </summary>
        /// <param name="location">location of rebar which need to be created</param>
        /// <returns>the created rebar, return null if the creation is unsuccessful</returns>
        public Rebar FillTransverseBar(TransverseRebarLocation location)
        {
            // Get the geometry information which support rebar creation
            RebarGeometry geomInfo = new RebarGeometry();

            switch (location)
            {
            case TransverseRebarLocation.Start: // start transverse rebar
            case TransverseRebarLocation.End:   // end transverse rebar
                geomInfo = m_geometry.GetTransverseRebar(location, m_transverseEndSpacing);
                break;

            case TransverseRebarLocation.Center:// center transverse rebar
                geomInfo = m_geometry.GetTransverseRebar(location, m_transverseCenterSpacing);
                break;
            }

            RebarHookOrientation startHook = RebarHookOrientation.Right;
            RebarHookOrientation endHook   = RebarHookOrientation.Left;

            if (!GeomUtil.IsInRightDir(geomInfo.Normal))
            {
                startHook = RebarHookOrientation.Left;
                endHook   = RebarHookOrientation.Right;
            }

            // create the rebar
            return(PlaceRebars(m_transverseType, m_transverseHookType, m_transverseHookType,
                               geomInfo, startHook, endHook));
        }
示例#4
0
        /// <summary>
        /// Get the geometry information of bottom rebar
        /// </summary>
        /// <returns>the gotten geometry information</returns>
        public RebarGeometry GetBottomRebar()
        {
            // sort the points of the swept profile
            XYZHeightComparer comparer = new XYZHeightComparer();

            m_points.Sort(comparer);

            // Get the normal parameter for bottom rebar creation
            List <Autodesk.Revit.DB.XYZ> directions = GetRelatedVectors(m_points[0]);

            directions.Sort(comparer);
            Autodesk.Revit.DB.XYZ normal = directions[0];

            double offset      = BeamRebarData.BottomOffset;      //offset value of the rebar
            int    rebarNumber = BeamRebarData.BottomRebarNumber; //the number of the rebar
            // the spacing of the rebar
            double spacing = (m_beamWidth - 2 * offset) / (rebarNumber - 1);

            // Get the curve which define the shape of the bottom rebar curve
            List <Autodesk.Revit.DB.XYZ> movedPoints = OffsetPoints(offset);

            Autodesk.Revit.DB.XYZ startPoint = movedPoints[0]; //get the coordinate of startpoint
            //get the coordinate of endpoint
            Autodesk.Revit.DB.XYZ endPoint = GeomUtil.OffsetPoint(startPoint, m_drivingVector, m_beamLength);

            IList <Curve> curves = new List <Curve>(); //the profile of the bottom rebar

            curves.Add(Line.CreateBound(startPoint, endPoint));

            // return the rebar geometry information
            return(new RebarGeometry(normal, curves, rebarNumber, spacing));
        }
示例#5
0
        /// <summary>
        /// Get the geometry information for top rebar
        /// </summary>
        /// <param name="location">indicate where top rebar is placed</param>
        /// <returns>the gotten geometry information</returns>
        public RebarGeometry GetTopRebar(TopRebarLocation location)
        {
            // sort the points of the swept profile
            XYZHeightComparer comparer = new XYZHeightComparer();

            m_points.Sort(comparer);

            // Get the normal parameter for rebar creation
            List <Autodesk.Revit.DB.XYZ> directions = GetRelatedVectors(m_points[3]);

            directions.Sort(comparer);
            Autodesk.Revit.DB.XYZ normal = directions[1];

            double offset           = 0;                            //the offset from the beam surface to the rebar
            double startPointOffset = 0;                            // the offset of start point from swept profile
            double rebarLength      = m_beamLength / 3;             //the length of the rebar
            int    rebarNumber      = BeamRebarData.TopRebarNumber; //the number of the rebar

            // set offset and startPointOffset according to the location of rebar
            switch (location)
            {
            case TopRebarLocation.Start:        // top start rebar
                offset = BeamRebarData.TopEndOffset;
                break;

            case TopRebarLocation.Center:       // top center rebar
                offset           = BeamRebarData.TopCenterOffset;
                startPointOffset = m_beamLength / 3 - 0.5;
                rebarLength      = m_beamLength / 3 + 1;
                break;

            case TopRebarLocation.End:          // top end rebar
                offset           = BeamRebarData.TopEndOffset;
                startPointOffset = m_beamLength * 2 / 3;
                break;

            default:
                throw new Exception("The program should never go here.");
            }

            // Get the curve which define the shape of the top rebar curve
            List <Autodesk.Revit.DB.XYZ> movedPoints = OffsetPoints(offset);

            Autodesk.Revit.DB.XYZ startPoint = movedPoints[movedPoints.Count - 1];

            // offset the start point according startPointOffset
            startPoint = GeomUtil.OffsetPoint(startPoint, m_drivingVector, startPointOffset);
            // get the coordinate of endpoint
            Autodesk.Revit.DB.XYZ endPoint = GeomUtil.OffsetPoint(startPoint, m_drivingVector, rebarLength);
            IList <Curve>         curves   = new List <Curve>(); //the profile of the top rebar

            curves.Add(Line.CreateBound(startPoint, endPoint));

            // the spacing of the rebar
            double spacing = spacing = (m_beamWidth - 2 * offset) / (rebarNumber - 1);

            // return the rebar geometry information
            return(new RebarGeometry(normal, curves, rebarNumber, spacing));
        }
示例#6
0
        /// <summary>
        /// Get the swept profile(face) of the host object(family instance)
        /// </summary>
        /// <param name="solid">the solid reference</param>
        /// <returns>the swept profile</returns>
        private Face GetSweptProfileFace(Solid solid)
        {
            // Get a point on the swept profile from all points in solid
            Autodesk.Revit.DB.XYZ refPoint = new Autodesk.Revit.DB.XYZ(); // the point on swept profile
            foreach (Edge edge in solid.Edges)
            {
                List <XYZ> points = edge.Tessellate() as List <XYZ>; //get end points of the edge
                if (2 != points.Count)                               // make sure all edges are lines
                {
                    throw new Exception("All edge should be line.");
                }

                // get two points of the edge. All points in solid should be transform first
                Autodesk.Revit.DB.XYZ first  = Transform(points[0]); // start point of edge
                Autodesk.Revit.DB.XYZ second = Transform(points[1]); // end point of edge

                // some edges should be parallelled with the driving line,
                // and the start point of that edge should be the wanted point
                Autodesk.Revit.DB.XYZ edgeVector = GeomUtil.SubXYZ(second, first);
                if (GeomUtil.IsSameDirection(edgeVector, m_drivingVector))
                {
                    refPoint = first;
                    break;
                }
                if (GeomUtil.IsOppositeDirection(edgeVector, m_drivingVector))
                {
                    refPoint = second;
                    break;
                }
            }

            // Find swept profile(face)
            Face sweptFace = null; // define the swept face

            foreach (Face face in solid.Faces)
            {
                if (null != sweptFace)
                {
                    break;
                }
                // the swept face should be perpendicular with the driving line
                if (!GeomUtil.IsVertical(face, m_drivingLine, m_transform, null))
                {
                    continue;
                }
                // use the gotted point to get the swept face
                foreach (Autodesk.Revit.DB.XYZ point in face.Triangulate().Vertices)
                {
                    Autodesk.Revit.DB.XYZ pnt = Transform(point); // all points in solid should be transform
                    if (GeomUtil.IsEqual(refPoint, pnt))
                    {
                        sweptFace = face;
                        break;
                    }
                }
            }

            return(sweptFace);
        }
示例#7
0
        /// <summary>
        /// Get the width of the column
        /// </summary>
        /// <returns>the width data</returns>
        private double GetColumnWidth()
        {
            XYZHeightComparer comparer = new XYZHeightComparer();

            m_points.Sort(comparer);

            Autodesk.Revit.DB.XYZ        refPoint   = m_points[0];
            List <Autodesk.Revit.DB.XYZ> directions = GetRelatedVectors(refPoint);

            directions.Sort(comparer);

            return(GeomUtil.GetLength(directions[1]));
        }
示例#8
0
 int IComparer <Autodesk.Revit.DB.XYZ> .Compare(Autodesk.Revit.DB.XYZ first, Autodesk.Revit.DB.XYZ second)
 {
     // first compare z coordinate, then y coordinate, at last x coordinate
     if (GeomUtil.IsEqual(first.Z, second.Z))
     {
         if (GeomUtil.IsEqual(first.Y, second.Y))
         {
             if (GeomUtil.IsEqual(first.X, second.X))
             {
                 return(0);
             }
             return((first.X > second.X) ? 1 : -1);
         }
         return((first.Y > second.Y) ? 1 : -1);
     }
     return((first.Z > second.Z) ? 1 : -1);
 }
示例#9
0
        /// <summary>
        /// get the orient of hook accroding to curve direction, rebar normal and hook direction
        /// </summary>
        /// <param name="curveVec">the curve direction</param>
        /// <param name="normal">rebar normal direction</param>
        /// <param name="hookVec">the hook direction</param>
        /// <returns>the orient of the hook</returns>
        public static RebarHookOrientation GetHookOrient(Autodesk.Revit.DB.XYZ curveVec, Autodesk.Revit.DB.XYZ normal, Autodesk.Revit.DB.XYZ hookVec)
        {
            Autodesk.Revit.DB.XYZ tempVec = normal;

            for (int i = 0; i < 4; i++)
            {
                tempVec = GeomUtil.CrossMatrix(tempVec, curveVec);
                if (GeomUtil.IsSameDirection(tempVec, hookVec))
                {
                    if (i == 0)
                    {
                        return(RebarHookOrientation.Right);
                    }
                    else if (i == 2)
                    {
                        return(RebarHookOrientation.Left);
                    }
                }
            }

            throw new Exception("Can't find the hook orient according to hook direction.");
        }
示例#10
0
        /// <summary>
        /// Offset the points of the swept profile to make the points inside swept profile
        /// </summary>
        /// <param name="offset">indicate how long to offset on two directions</param>
        /// <returns>the offset points</returns>
        protected List <Autodesk.Revit.DB.XYZ> OffsetPoints(double offset)
        {
            // Initialize the offset point list.
            List <Autodesk.Revit.DB.XYZ> points = new List <Autodesk.Revit.DB.XYZ>();

            // Get all points of the swept profile, and offset it in two related direction
            foreach (Autodesk.Revit.DB.XYZ point in m_points)
            {
                // Get two related directions
                List <Autodesk.Revit.DB.XYZ> directions = GetRelatedVectors(point);
                Autodesk.Revit.DB.XYZ        firstDir   = directions[0];
                Autodesk.Revit.DB.XYZ        secondDir  = directions[1];

                // offset the point in two direction
                Autodesk.Revit.DB.XYZ movedPoint = GeomUtil.OffsetPoint(point, firstDir, offset);
                movedPoint = GeomUtil.OffsetPoint(movedPoint, secondDir, offset);

                // add the offset point into the array
                points.Add(movedPoint);
            }

            return(points);
        }
示例#11
0
        /// <summary>
        /// Get the geometry information of the transverse rebar
        /// </summary>
        /// <param name="location">the location of transverse rebar</param>
        /// <param name="spacing">the spacing value of the rebar</param>
        /// <returns>the gotted geometry information</returns>
        public RebarGeometry GetTransverseRebar(TransverseRebarLocation location, double spacing)
        {
            // sort the points of the swept profile
            XYZHeightComparer comparer = new XYZHeightComparer();

            m_points.Sort(comparer);

            // the offset from the column surface to the rebar
            double offset = ColumnRebarData.TransverseOffset;
            //the length of the transverse rebar
            double rebarLength = 0;

            // get the origin and normal parameter for rebar creation
            Autodesk.Revit.DB.XYZ normal = m_drivingVector;
            double curveOffset           = 0;

            //set rebar length and origin according to the location of rebar
            switch (location)
            {
            case TransverseRebarLocation.Start:     // start transverse rebar
                rebarLength = m_columnHeight / 4;
                break;

            case TransverseRebarLocation.Center:    // center transverse rebar
                rebarLength = m_columnHeight / 2;
                curveOffset = m_columnHeight / 4 + (rebarLength % spacing) / 2;
                break;

            case TransverseRebarLocation.End:       // end transverse rebar
                rebarLength = m_columnHeight / 4;
                curveOffset = m_columnHeight - rebarLength + (rebarLength % spacing);
                break;

            default:
                throw new Exception("The program should never go here.");
            }

            // the number of the transverse rebar
            int rebarNumber = (int)(rebarLength / spacing) + 1;
            // get the profile of the transverse rebar
            List <Autodesk.Revit.DB.XYZ> movedPoints = OffsetPoints(offset);

            List <Autodesk.Revit.DB.XYZ> translatedPoints = new List <Autodesk.Revit.DB.XYZ>();

            foreach (Autodesk.Revit.DB.XYZ point in movedPoints)
            {
                translatedPoints.Add(GeomUtil.OffsetPoint(point, m_drivingVector, curveOffset));
            }

            IList <Curve> curves = new List <Curve>(); //the profile of the transverse rebar

            Autodesk.Revit.DB.XYZ first  = translatedPoints[0];
            Autodesk.Revit.DB.XYZ second = translatedPoints[1];
            Autodesk.Revit.DB.XYZ third  = translatedPoints[2];
            Autodesk.Revit.DB.XYZ fourth = translatedPoints[3];
            curves.Add(Line.CreateBound(first, second));
            curves.Add(Line.CreateBound(second, fourth));
            curves.Add(Line.CreateBound(fourth, third));
            curves.Add(Line.CreateBound(third, first));

            // return the rebar geometry information
            return(new RebarGeometry(normal, curves, rebarNumber, spacing));
        }
示例#12
0
        /// <summary>
        /// Get the geometry information of vertical rebar
        /// </summary>
        /// <param name="location">the location of vertical rebar</param>
        /// <param name="rebarNumber">the spacing value of the rebar</param>
        /// <returns>the gotted geometry information</returns>
        public RebarGeometry GetVerticalRebar(VerticalRebarLocation location, int rebarNumber)
        {
            // sort the points of the swept profile
            XYZHeightComparer comparer = new XYZHeightComparer();

            m_points.Sort(comparer);

            // Get the offset and rebar length of rebar
            double offset      = ColumnRebarData.VerticalOffset;
            double rebarLength = m_columnHeight + 3; //the length of rebar

            // Get the start point of the vertical rebar curve
            Autodesk.Revit.DB.XYZ startPoint = m_drivingLine.GetEndPoint(0);

            List <Autodesk.Revit.DB.XYZ> movedPoints = OffsetPoints(offset);

            movedPoints.Sort(comparer);

            Autodesk.Revit.DB.XYZ normal = new Autodesk.Revit.DB.XYZ(); // the normal parameter
            double rebarOffset           = 0;                           // rebar offset, equal to rebarNumber* spacing

            // get the normal, start point and rebar offset of vertical rebar
            switch (location)
            {
            case VerticalRebarLocation.East:   //vertical rebar in east
                normal      = new Autodesk.Revit.DB.XYZ(0, 1, 0);
                rebarOffset = m_columnWidth - 2 * offset;
                startPoint  = movedPoints[1];
                break;

            case VerticalRebarLocation.North: //vertical rebar in north
                normal      = new Autodesk.Revit.DB.XYZ(-1, 0, 0);
                rebarOffset = m_columnLength - 2 * offset;
                startPoint  = movedPoints[3];
                break;

            case VerticalRebarLocation.West: //vertical rebar in west
                normal      = new Autodesk.Revit.DB.XYZ(0, -1, 0);
                rebarOffset = m_columnWidth - 2 * offset;
                startPoint  = movedPoints[2];
                break;

            case VerticalRebarLocation.South: //vertical rebar in south
                normal      = new Autodesk.Revit.DB.XYZ(1, 0, 0);
                rebarOffset = m_columnLength - 2 * offset;
                startPoint  = movedPoints[0];
                break;

            default:
                break;
            }

            double spacing = rebarOffset / rebarNumber; //spacing value of the rebar

            Autodesk.Revit.DB.XYZ endPoint = GeomUtil.OffsetPoint(startPoint, m_drivingVector, rebarLength);

            IList <Curve> curves = new List <Curve>();  //profile of the rebar

            curves.Add(Line.CreateBound(startPoint, endPoint));

            // return the rebar geometry information
            return(new RebarGeometry(normal, curves, rebarNumber, spacing));
        }
示例#13
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="element">the host object, must be family instance</param>
        /// <param name="geoOptions">the geometry option</param>
        public GeometrySupport(FamilyInstance element, Options geoOptions)
        {
            // get the geometry element of the selected element
            Autodesk.Revit.DB.GeometryElement geoElement = element.get_Geometry(new Options());
            IEnumerator <GeometryObject>      Objects    = geoElement.GetEnumerator();

            if (null == geoElement || !Objects.MoveNext())
            {
                throw new Exception("Can't get the geometry of selected element.");
            }

            SweptProfile swProfile = element.GetSweptProfile();

            if (swProfile == null || !(swProfile.GetDrivingCurve() is Line))
            {
                throw new Exception("The selected element driving curve is not a line.");
            }

            // get the driving path and vector of the beam or column
            Line line = swProfile.GetDrivingCurve() as Line;

            if (null != line)
            {
                m_drivingLine   = line; // driving path
                m_drivingVector = GeomUtil.SubXYZ(line.GetEndPoint(1), line.GetEndPoint(0));
            }

            //get the geometry object
            Objects.Reset();
            //foreach (GeometryObject geoObject in geoElement.Objects)
            while (Objects.MoveNext())
            {
                GeometryObject geoObject = Objects.Current;

                //get the geometry instance which contain the geometry information
                GeoInstance instance = geoObject as GeoInstance;
                if (null != instance)
                {
                    //foreach (GeometryObject o in instance.SymbolGeometry.Objects)
                    IEnumerator <GeometryObject> Objects1 = instance.SymbolGeometry.GetEnumerator();
                    while (Objects1.MoveNext())
                    {
                        GeometryObject o = Objects1.Current;

                        // get the solid of beam of column
                        Solid solid = o as Solid;

                        // do some checks.
                        if (null == solid)
                        {
                            continue;
                        }
                        if (0 == solid.Faces.Size || 0 == solid.Edges.Size)
                        {
                            continue;
                        }

                        m_solid = solid;
                        //get the transform value of instance
                        m_transform = instance.Transform;

                        // Get the swept profile curves information
                        if (!GetSweptProfile(solid))
                        {
                            throw new Exception("Can't get the swept profile curves.");
                        }
                        break;
                    }
                }
            }

            // do some checks about profile curves information
            if (null == m_edges)
            {
                throw new Exception("Can't get the geometry edge information.");
            }
            if (4 != m_points.Count)
            {
                throw new Exception("The sample only work for rectangular beams or columns.");
            }
        }
示例#14
0
 /// <summary>
 /// Get the length of driving line
 /// </summary>
 /// <returns>the length of the driving line</returns>
 protected double GetDrivingLineLength()
 {
     return(GeomUtil.GetLength(m_drivingVector));
 }
示例#15
0
 /// <summary>
 /// transform the point to new coordinates
 /// </summary>
 /// <param name="point">the point need to transform</param>
 /// <returns>the changed point</returns>
 protected Autodesk.Revit.DB.XYZ Transform(Autodesk.Revit.DB.XYZ point)
 {
     // only invoke the TransformPoint() method.
     return(GeomUtil.TransformPoint(point, m_transform));
 }