Esempio n. 1
1
 /// <summary>
 /// Given an array of edges, weeds out any edges
 /// not present on the desired plane
 /// </summary>
 /// <param name="xyzArray">the array of edges </param>
 /// <param name="normal">normal to the desired plane</param>
 /// <returns>edges on the desired plane</returns>
 public static EdgeArray GetEdgesOnPlane(EdgeArray edgeArray, XYZ normal)
 {
     EdgeArray edgesOnPlane = new EdgeArray();
     for (int i = 0; i < edgeArray.Size; i++) {
         IList<XYZ> xyzArray = edgeArray.get_Item(i).Tessellate();
         if (normal.Equals(GeomUtils.kXAxis)) {
             if (xyzArray[0].X == xyzArray[1].X) {
                 edgesOnPlane.Append(edgeArray.get_Item(i));
             }
         }
         if (normal.Equals(GeomUtils.kYAxis)) {
             if (xyzArray[0].Y == xyzArray[1].Y) {
                 edgesOnPlane.Append(edgeArray.get_Item(i));
             }
         }
         if (normal.Equals(GeomUtils.kZAxis)) {
             if (xyzArray[0].Z == xyzArray[1].Z) {
                 edgesOnPlane.Append(edgeArray.get_Item(i));
             }
         }
     }
     return edgesOnPlane;
 }
Esempio n. 2
0
        /// <summary>
        /// Compute the length and angle data of the edges, then update the parameters with these values
        /// </summary>
        /// <param name="edge_ar">The edges of the curtain panel</param>
        /// <param name="instParams">The parameters which records the length and angle data</param>
        private void SetParams(EdgeArray edge_ar, InstParameters instParams)
        {
            double length4 = 0d;
            double angle3  = 0d;
            double angle4  = 0d;
            Edge   edge1   = edge_ar.get_Item(0);
            Edge   edge2   = edge_ar.get_Item(1);
            Edge   edge3   = edge_ar.get_Item(2);
            double length1 = edge1.ApproximateLength;
            double length2 = edge2.ApproximateLength;
            double length3 = edge3.ApproximateLength;
            double angle1  = AngleBetweenEdges(edge1, edge2);
            double angle2  = AngleBetweenEdges(edge2, edge3);

            if (edge_ar.Size == 3)
            {
                angle3 = AngleBetweenEdges(edge3, edge1);
            }
            else if (edge_ar.Size > 3)
            {
                Edge edge4 = edge_ar.get_Item(3);
                length4 = edge4.ApproximateLength;
                angle3  = AngleBetweenEdges(edge3, edge4);
                angle4  = AngleBetweenEdges(edge4, edge1);
            }

            instParams["Length1"].Set(length1);
            instParams["Length2"].Set(length2);
            instParams["Length3"].Set(length3);
            instParams["Length4"].Set(length4);
            instParams["Angle1"].Set(angle1);
            instParams["Angle2"].Set(angle2);
            instParams["Angle3"].Set(angle3);
            instParams["Angle4"].Set(angle4);
        }
Esempio n. 3
0
        GetEdgesOnPlane(EdgeArray edgeArray, XYZ normal)
        {
            EdgeArray edgesOnPlane = new EdgeArray();

            for (int i = 0; i < edgeArray.Size; i++)
            {
                IList <XYZ> xyzArray = edgeArray.get_Item(i).Tessellate();
                if (normal.Equals(GeomUtils.kXAxis))
                {
                    if (xyzArray[0].X == xyzArray[1].X)
                    {
                        edgesOnPlane.Append(edgeArray.get_Item(i));
                    }
                }
                if (normal.Equals(GeomUtils.kYAxis))
                {
                    if (xyzArray[0].Y == xyzArray[1].Y)
                    {
                        edgesOnPlane.Append(edgeArray.get_Item(i));
                    }
                }
                if (normal.Equals(GeomUtils.kZAxis))
                {
                    if (xyzArray[0].Z == xyzArray[1].Z)
                    {
                        edgesOnPlane.Append(edgeArray.get_Item(i));
                    }
                }
            }
            return(edgesOnPlane);
        }
Esempio n. 4
0
        GetEdgesOnPlaneAtOffset(EdgeArray edgeArray, XYZ normal, double offset)
        {
            EdgeArray edgesAtOffset = new EdgeArray();

            edgeArray = GetEdgesOnPlane(edgeArray, normal);
            for (int i = 0; i < edgeArray.Size; i++)
            {
                IList <XYZ> xyzArray = edgeArray.get_Item(i).Tessellate();
                if (normal.Equals(GeomUtils.kXAxis))
                {
                    if ((xyzArray[0].X == offset))
                    {
                        edgesAtOffset.Append(edgeArray.get_Item(i));
                    }
                }
                if (normal.Equals(GeomUtils.kYAxis))
                {
                    if (xyzArray[0].Y == offset)
                    {
                        edgesAtOffset.Append(edgeArray.get_Item(i));
                    }
                }
                if (normal.Equals(GeomUtils.kZAxis))
                {
                    if (xyzArray[0].Z == offset)
                    {
                        edgesAtOffset.Append(edgeArray.get_Item(i));
                    }
                }
            }
            return(edgesAtOffset);
        }
Esempio n. 5
0
        /// <summary>
        /// Check if the given bottom edge was shared by a trapezoid face with left edge vertical.
        /// </summary>
        /// <param name="hostNormal">Corbel Host face Normal</param>
        /// <param name="corbelBottomFace">Bottom Face of Corbel</param>
        /// <param name="bottomEdge">Given bottom edge to test</param>
        /// <param name="trapezoidFace">Output the trapezoid Face</param>
        /// <param name="topEdge">Output trapezoid top edge</param>
        /// <param name="leftEdge">Output trapezoid left edge</param>
        /// <param name="rightEdge">Output trapezoid right edge</param>
        /// <returns>True if there is a trapezoid face share the given bottom edge, otherwise false.</returns>
        private static bool IsTrapezoid(
            XYZ hostNormal, PlanarFace corbelBottomFace, Edge bottomEdge,
            out PlanarFace trapezoidFace, out Edge topEdge,
            out Edge leftEdge, out Edge rightEdge)
        {
            PlanarFace face1 = bottomEdge.get_Face(0) as PlanarFace;
            PlanarFace face2 = bottomEdge.get_Face(1) as PlanarFace;

            trapezoidFace = face1 == corbelBottomFace ? face2 : face1;

            EdgeArray trapezoidFaceEdges = trapezoidFace.EdgeLoops.get_Item(0);
            XYZ       bottomEdgeDir      = (bottomEdge.Evaluate(1.0) - bottomEdge.Evaluate(0.0)).Normalize();
            int       bottomEdgeIndex    = -1;

            topEdge = null;
            for (int i = 0; i < trapezoidFaceEdges.Size; i++)
            {
                Edge edge    = trapezoidFaceEdges.get_Item(i);
                XYZ  edgeDir = (edge.Evaluate(1.0) - edge.Evaluate(0.0)).Normalize();
                if (edgeDir.IsAlmostEqualTo(bottomEdgeDir) ||
                    edgeDir.IsAlmostEqualTo(-bottomEdgeDir))
                {
                    if (edge.Evaluate(0.0).IsAlmostEqualTo(bottomEdge.Evaluate(0.0)))
                    {
                        bottomEdge      = edge;
                        bottomEdgeIndex = i;
                    }
                    else
                    {
                        topEdge = edge;
                    }
                }
            }

            leftEdge  = trapezoidFaceEdges.get_Item((trapezoidFaceEdges.Size + bottomEdgeIndex - 1) % trapezoidFaceEdges.Size);
            rightEdge = trapezoidFaceEdges.get_Item((bottomEdgeIndex + 1) % trapezoidFaceEdges.Size);

            XYZ  leftEdgeDir        = (leftEdge.Evaluate(1.0) - leftEdge.Evaluate(0.0)).Normalize();
            bool isLeftEdgeVertical = false;

            if (leftEdgeDir.IsAlmostEqualTo(hostNormal) ||
                leftEdgeDir.IsAlmostEqualTo(-hostNormal))
            {
                isLeftEdgeVertical = true;
            }

            XYZ  rightEdgeDir        = (rightEdge.Evaluate(1.0) - rightEdge.Evaluate(0.0)).Normalize();
            bool rightEdgeIsVertical = false;

            if (rightEdgeDir.IsAlmostEqualTo(hostNormal) ||
                rightEdgeDir.IsAlmostEqualTo(-hostNormal))
            {
                rightEdgeIsVertical = true;
            }

            return(isLeftEdgeVertical && !rightEdgeIsVertical);
        }
Esempio n. 6
0
        //在族实例上定位连接点
        private XYZ LocatePointOnFamilyInstance(FamilyInstance fi, Direction dir)
        {
            //找到工井族文件中左边界或右边界的几何体,利用id定位
            Options opt = new Options();

            opt.IncludeNonVisibleObjects = true;//很重要,由于view为null需要将不可见的对象变为可见,否则提取空集
            GeometryElement ge = null;

            switch (dir)
            {
            case (Direction.left):
                ge = welldoc.GetElement(new ElementId(leftId)).get_Geometry(opt);
                break;

            case (Direction.right):
                ge = welldoc.GetElement(new ElementId(rightId)).get_Geometry(opt);
                break;
            }

            //提取集合体上的面元素
            Solid solid = null;

            foreach (GeometryObject obj in ge)
            {
                if (obj is Solid)
                {
                    solid = obj as Solid;
                    break;
                }
            }
            FaceArray fcArr = null;

            if (solid != null)
            {
                fcArr = solid.Faces;
            }

            //找到边界的面,并将面原点的族坐标转换为模型坐标
            Transform trans = null;
            Options   opt1  = new Options();

            opt1.ComputeReferences = false;
            opt1.View = doc.ActiveView;
            GeometryElement geoElement = fi.get_Geometry(opt1);

            foreach (GeometryObject obj in geoElement)   //利用GeometryInstrance的Transform提取坐标转换矩阵
            {
                if (obj is GeometryInstance)
                {
                    GeometryInstance inst = obj as GeometryInstance;
                    trans = inst.Transform;
                    break;
                }
            }

            EdgeArray edArr       = solid.Edges;
            XYZ       planeOrigin = (fcArr.get_Item(0) as PlanarFace).Origin;

            return(trans.OfPoint(new XYZ(planeOrigin.X, planeOrigin.Y + edArr.get_Item(0).ApproximateLength / 2, planeOrigin.Z - edArr.get_Item(1).ApproximateLength / 2)));
        }
Esempio n. 7
0
        /// <summary>
        /// Get a floor's profile.
        /// </summary>
        /// <param name="floor">The floor whose profile you want to get.</param>
        /// <returns>The profile of the floor.</returns>
        private CurveArray GetFloorProfile(Floor floor)
        {
            CurveArray floorProfile = new CurveArray();

            // Structural slab's profile can be found in it's AnalyticalModel.
            if (null != floor.GetAnalyticalModel())
            {
                AnalyticalModel analyticalModel = floor.GetAnalyticalModel();
                IList <Curve>   curveList       = analyticalModel.GetCurves(AnalyticalCurveType.ActiveCurves);
                for (int i = 0; i < curveList.Count; i++)
                {
                    floorProfile.Append(curveList[i]);
                }

                return(floorProfile);
            }

            // Nonstructural floor's profile can be formed through it's Geometry.
            Options aOptions = m_revit.Application.Create.NewGeometryOptions();

            Autodesk.Revit.DB.GeometryElement aElementOfGeometry = floor.get_Geometry(aOptions);
            //GeometryObjectArray geometryObjects = aElementOfGeometry.Objects;
            IEnumerator <GeometryObject> Objects = aElementOfGeometry.GetEnumerator();

            //foreach (GeometryObject o in geometryObjects)
            while (Objects.MoveNext())
            {
                GeometryObject o = Objects.Current;

                Solid solid = o as Solid;
                if (null == solid)
                {
                    continue;
                }

                // Form the floor's profile through solid's edges.
                EdgeArray edges = solid.Edges;
                for (int i = 0; i < (edges.Size) / 3; i++)
                {
                    Edge       edge     = edges.get_Item(i);
                    List <XYZ> xyzArray = edge.Tessellate() as List <XYZ>; // A set of points.
                    for (int j = 0; j < (xyzArray.Count - 1); j++)
                    {
                        Autodesk.Revit.DB.XYZ startPoint = xyzArray[j];
                        Autodesk.Revit.DB.XYZ endPoint   = xyzArray[j + 1];
                        Line line = Line.CreateBound(startPoint, endPoint);

                        floorProfile.Append(line);
                    }
                }
            }
            return(floorProfile);
        }
Esempio n. 8
0
 /// <summary>
 /// Given an array of edges, weeds out any edges
 /// not present at the given offset
 /// </summary>
 /// <param name="edgeArray">the array of edges </param>
 /// <param name="normal">normal to the desired plane</param>
 /// <param name="offset">offset from the plane</param>
 /// <returns>edges on a plane at given offset</returns>
 public static EdgeArray GetEdgesOnPlaneAtOffset(EdgeArray edgeArray, XYZ normal, double offset)
 {
     EdgeArray edgesAtOffset = new EdgeArray();
     edgeArray = GetEdgesOnPlane(edgeArray, normal);
     for (int i = 0; i < edgeArray.Size; i++) {
         IList<XYZ> xyzArray = edgeArray.get_Item(i).Tessellate();
         if (normal.Equals(GeomUtils.kXAxis)) {
             if ((xyzArray[0].X == offset)) {
                 edgesAtOffset.Append(edgeArray.get_Item(i));
             }
         }
         if (normal.Equals(GeomUtils.kYAxis)) {
             if (xyzArray[0].Y == offset) {
                 edgesAtOffset.Append(edgeArray.get_Item(i));
             }
         }
         if (normal.Equals(GeomUtils.kZAxis)) {
             if (xyzArray[0].Z == offset) {
                 edgesAtOffset.Append(edgeArray.get_Item(i));
             }
         }
     }
     return edgesAtOffset;
 }
Esempio n. 9
0
        /// <summary>
        /// check whether the faces of the mass are one-one parallel
        /// </summary>
        /// <param name="faces">
        /// the 6 faces of the mass
        /// </param>
        /// <returns>
        /// if the 6 faces are one-one parallel, return true; otherwise false
        /// </returns>
        private bool IsFacesParallel(FaceArray faces)
        {
            // step1: get the normals of the 6 faces
            List <Utility.Vector4> normals = new List <Utility.Vector4>();

            foreach (Face face in faces)
            {
                EdgeArrayArray edgeArrayArray = face.EdgeLoops;
                EdgeArray      edges          = edgeArrayArray.get_Item(0);

                if (null == edges ||
                    2 > edges.Size)
                {
                    return(false);
                }

                // we use the cross product of 2 non-parallel vectors as the normal
                for (int i = 0; i < edges.Size - 1; i++)
                {
                    Edge edgeA = edges.get_Item(i);
                    Edge edgeB = edges.get_Item(i + 1);

                    // if edgeA & edgeB are parallel, can't compute  the cross product
                    bool isLinesParallel = IsLinesParallel(edgeA, edgeB);

                    if (true == isLinesParallel)
                    {
                        continue;
                    }

                    Utility.Vector4 vec4 = ComputeCrossProduct(edgeA, edgeB);
                    normals.Add(vec4);
                    break;
                }
            }

            // step 2: the 6 normals should be one-one parallel pairs
            if (null == normals ||
                6 != normals.Count)
            {
                return(false);
            }

            bool[] matchedList = new bool[6];
            for (int i = 0; i < matchedList.Length; i++)
            {
                matchedList[i] = false;
            }

            // check whether the normal has another matched parallel normal
            for (int i = 0; i < matchedList.Length; i++)
            {
                if (true == matchedList[i])
                {
                    continue;
                }

                Utility.Vector4 vec4A = normals[i];

                for (int j = 0; j < matchedList.Length; j++)
                {
                    if (j == i ||
                        true == matchedList[j])
                    {
                        continue;
                    }

                    Utility.Vector4 vec4B = normals[j];

                    if (true == IsLinesParallel(vec4A, vec4B))
                    {
                        matchedList[i] = true;
                        matchedList[j] = true;
                        break;
                    }
                }
            }

            // step 3: check each of the 6 normals has matched parallel normal
            for (int i = 0; i < matchedList.Length; i++)
            {
                if (false == matchedList[i])
                {
                    return(false);
                }
            }

            // all the normals have matched parallel normals
            return(true);
        }
Esempio n. 10
0
        /// <summary>
        /// This method parses geometry information of given Corbel to construct the CorbelFrame.
        /// </summary>
        /// <param name="corbel">Given corbel family instance to parse</param>
        /// <returns>CorbelFrame object</returns>
        public static CorbelFrame ParseCorbelGeometry(FamilyInstance corbel)
        {
            // Get Corbel Host information.
            Element   corbelHost     = corbel.Host;
            Reference corbelHostFace = corbel.HostFace;

            PlanarFace hostPlane  = corbelHost.GetGeometryObjectFromReference(corbelHostFace) as PlanarFace;
            XYZ        hostNormal = GetNormalOutside(hostPlane);

            // Extract the faces in Corbel parallel with Corbel host face.
            Solid      corbelSolid      = GetElementSolid(corbel);
            PlanarFace corbelTopFace    = null;
            PlanarFace corbelBottomFace = null;

            foreach (Face face in corbelSolid.Faces)
            {
                PlanarFace planarFace = face as PlanarFace;
                XYZ        normal     = GetNormalOutside(planarFace);
                if (normal.IsAlmostEqualTo(hostNormal))
                {
                    corbelTopFace = planarFace;
                }
                else if (normal.IsAlmostEqualTo(-hostNormal))
                {
                    corbelBottomFace = planarFace;
                }
            }

            // Extract the faces in Corbel Host parallel with Corbel host face.
            Solid      hostSolid      = GetElementSolid(corbelHost);
            PlanarFace hostTopFace    = null;
            PlanarFace hostBottomFace = hostPlane;

            foreach (Face face in hostSolid.Faces)
            {
                PlanarFace planarFace = face as PlanarFace;
                XYZ        normal     = GetNormalOutside(planarFace);
                if (normal.IsAlmostEqualTo(-hostNormal))
                {
                    hostTopFace = planarFace;
                }
            }

            // Parse the side faces to find out the Trapezoid face.
            Edge       topEdge        = null;
            Edge       leftEdge       = null;
            Edge       bottomEdge     = null;
            Edge       rightEdge      = null;
            PlanarFace trapezoidFace  = null;
            int        foundEdgeIndex = -1;
            bool       foundTrapezoid = false;
            EdgeArray  bottomEdges    = corbelBottomFace.EdgeLoops.get_Item(0);

            foreach (Edge edge in bottomEdges)
            {
                bottomEdge = edge;
                foundEdgeIndex++;
                foundTrapezoid = IsTrapezoid(hostNormal, corbelBottomFace, bottomEdge,
                                             out trapezoidFace, out topEdge, out leftEdge, out rightEdge);
                if (foundTrapezoid)
                {
                    break;
                }
            }

            // Check to see if the Trapezoid faces was found.
            if (!foundTrapezoid)
            {
                // Throw if no any trapezoid face in corbel.
                throw new Exception("Didn't find the trapezoid face in corbel [Id:" + corbel.Id + "].");
            }

            Edge depthEdge = bottomEdges.get_Item((foundEdgeIndex + 1) % bottomEdges.Size);

            double hostDepth = GetDistance(hostTopFace, hostBottomFace);

            // Compute the host face cover distance.
            RebarHostData corbelHostData = RebarHostData.GetRebarHostData(corbelHost);
            // Get CoverType of the given host face
            RebarCoverType coverType = corbelHostData.GetCoverType(hostTopFace.Reference);

            // if the host face don't have a CoverType, then try to get the common CoverType.
            if (coverType == null)
            {
                coverType = corbelHostData.GetCommonCoverType();
            }
            // Get the Cover Distance
            double coverDistance = coverType.CoverDistance;

            // Construct the CorbelFrame from the given parsed trapezoid information.
            return(ConstructCorbelFrame(
                       corbel, depthEdge,
                       leftEdge, bottomEdge, rightEdge, topEdge,
                       corbel.Document, trapezoidFace,
                       hostDepth, coverDistance));
        }
Esempio n. 11
0
        /// <summary>
        /// Get a floor's profile.
        /// </summary>
        /// <param name="floor">The floor whose profile you want to get.</param>
        /// <returns>The profile of the floor.</returns>
        private CurveArray GetFloorProfile(Floor floor)
        {
            CurveArray floorProfile = new CurveArray();
            // Structural slab's profile can be found in it's analytical element.
            Document        document        = floor.Document;
            AnalyticalPanel analyticalModel = null;
            AnalyticalToPhysicalAssociationManager relManager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(document);

            if (relManager != null)
            {
                ElementId associatedElementId = relManager.GetAssociatedElementId(floor.Id);
                if (associatedElementId != ElementId.InvalidElementId)
                {
                    Element associatedElement = document.GetElement(associatedElementId);
                    if (associatedElement != null && associatedElement is AnalyticalPanel)
                    {
                        analyticalModel = associatedElement as AnalyticalPanel;
                    }
                }
            }
            if (null != analyticalModel)
            {
                IList <Curve> curveList = analyticalModel.GetOuterContour().ToList();

                for (int i = 0; i < curveList.Count; i++)
                {
                    floorProfile.Append(curveList[i]);
                }

                return(floorProfile);
            }

            // Nonstructural floor's profile can be formed through it's Geometry.
            Options aOptions = m_revit.Application.Create.NewGeometryOptions();

            Autodesk.Revit.DB.GeometryElement aElementOfGeometry = floor.get_Geometry(aOptions);
            //GeometryObjectArray geometryObjects = aElementOfGeometry.Objects;
            IEnumerator <GeometryObject> Objects = aElementOfGeometry.GetEnumerator();

            //foreach (GeometryObject o in geometryObjects)
            while (Objects.MoveNext())
            {
                GeometryObject o = Objects.Current;

                Solid solid = o as Solid;
                if (null == solid)
                {
                    continue;
                }

                // Form the floor's profile through solid's edges.
                EdgeArray edges = solid.Edges;
                for (int i = 0; i < (edges.Size) / 3; i++)
                {
                    Edge       edge     = edges.get_Item(i);
                    List <XYZ> xyzArray = edge.Tessellate() as List <XYZ>; // A set of points.
                    for (int j = 0; j < (xyzArray.Count - 1); j++)
                    {
                        Autodesk.Revit.DB.XYZ startPoint = xyzArray[j];
                        Autodesk.Revit.DB.XYZ endPoint   = xyzArray[j + 1];
                        Line line = Line.CreateBound(startPoint, endPoint);

                        floorProfile.Append(line);
                    }
                }
            }
            return(floorProfile);
        }