Exemple #1
0
        /// <summary>
        /// 打断两根 X型 T型 相交线段
        /// </summary>
        /// <param name="_line1"></param>
        /// <param name="_line2"></param>
        /// <returns></returns>
        public static List <Line> CutOffTwoIntersetionLines_X_T(Line _line1, Line _line2)
        {
            List <Line> lines            = new List <Line>();
            XYZ         _line1_start     = _line1.GetEndPoint(0);
            XYZ         _line1_end       = _line1.GetEndPoint(1);
            XYZ         _line2_start     = _line2.GetEndPoint(0);
            XYZ         _line2_end       = _line2.GetEndPoint(1);
            XYZ         intersectionPint = GetIntersetionPointFromTwoLines(_line1, _line2);

            //该处需要判断是源于 T型 的存在
            if (!intersectionPint.IsAlmostEqualTo(_line1_start, 0.0001))
            {
                lines.Add(Line.CreateBound(intersectionPint, _line1_start));
            }
            if (!intersectionPint.IsAlmostEqualTo(_line1_end, 0.0001))
            {
                lines.Add(Line.CreateBound(intersectionPint, _line1_end));
            }
            if (!intersectionPint.IsAlmostEqualTo(_line2_start, 0.0001))
            {
                lines.Add(Line.CreateBound(intersectionPint, _line2_start));
            }
            if (!intersectionPint.IsAlmostEqualTo(_line2_end, 0.0001))
            {
                lines.Add(Line.CreateBound(intersectionPint, _line2_end));
            }
            return(lines);
        }
Exemple #2
0
        static public DuctOrientation GetDuctOrientation(ConnectorManager conMngr)
        {
            XYZ    orientation = GetDuctDirection(conMngr);
            double angleToZ    = orientation.AngleTo(XYZ.BasisZ);

            if (orientation.IsAlmostEqualTo(XYZ.BasisZ) || orientation.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
            {
                return(DuctOrientation.StraightVertical);
            }
            else if (orientation.IsAlmostEqualTo(new XYZ(orientation.X, orientation.Y, 0)))
            {
                return(DuctOrientation.Horizontal);
            }
            // угол между Z и вектором от 60 до 120 градусов
            else if (angleToZ > (Math.PI / 3) && angleToZ < (2 * Math.PI / 3))
            {
                return(DuctOrientation.AlmostHorizontal);
            }
            // угол между Z и вектором больше 150 градусов или меньше 30
            else if (angleToZ > (5 * Math.PI / 6) || angleToZ < (Math.PI / 6))
            {
                return(DuctOrientation.AlmostVertical);
            }
            else
            {
                return(DuctOrientation.Angled);
            }
        }
        /// <summary>
        /// Retrieve the room plan view boundary
        /// polygon loops and convert to 2D integer-based.
        /// For optimisation and consistency reasons,
        /// convert all coordinates to integer values in
        /// millimetres. Revit precision is limited to
        /// 1/16 of an inch, which is abaut 1.2 mm, anyway.
        /// </summary>
        static JtLoops GetRoomLoops(Room room)
        {
            SpatialElementBoundaryOptions opt
                = new SpatialElementBoundaryOptions();

            opt.SpatialElementBoundaryLocation =
                SpatialElementBoundaryLocation.Center; // loops closed
            //SpatialElementBoundaryLocation.Finish; // loops not closed

            IList <IList <BoundarySegment> > loops = room.
                                                     GetBoundarySegments(opt);

            int nLoops = loops.Count;

            JtLoops jtloops = new JtLoops(nLoops);

            foreach (IList <BoundarySegment> loop in loops)
            {
                int nSegments = loop.Count;

                JtLoop jtloop = new JtLoop(nSegments);

                XYZ p0 = null; // loop start point
                XYZ p;         // segment start point
                XYZ q = null;  // segment end point

                foreach (BoundarySegment seg in loop)
                {
                    // Todo: handle non-linear curve.
                    // Especially: if two long lines have a
                    // short arc in between them, skip the arc
                    // and extend both lines.

                    p = seg.Curve.GetEndPoint(0);

                    jtloop.Add(new Point2dInt(p));

                    Debug.Assert(null == q || q.IsAlmostEqualTo(p),
                                 "expected last endpoint to equal current start point");

                    q = seg.Curve.GetEndPoint(1);

                    if (_debug_output)
                    {
                        Debug.Print("{0} --> {1}",
                                    Util.PointString(p),
                                    Util.PointString(q));
                    }
                    if (null == p0)
                    {
                        p0 = p; // save loop start point
                    }
                }
                Debug.Assert(q.IsAlmostEqualTo(p0),
                             "expected last endpoint to equal loop start point");

                jtloops.Add(jtloop);
            }
            return(jtloops);
        }
Exemple #4
0
        /// <summary>
        /// 判断两根相交线段 结果为1,则是 L型 or V型;为0,则是X型 or T型, 或不相交; 如果是方向一致的线,1则为首尾相连 线段,2则为重叠
        /// </summary>
        /// <param name="_line1"></param>
        /// <param name="_line2"></param>
        /// <returns></returns>
        public static int is_L_or_V_twolinesoverlap(Line _line1, Line _line2)
        {
            int _intersectCount = 0;
            XYZ _line1_start    = _line1.GetEndPoint(0);
            XYZ _line1_end      = _line1.GetEndPoint(1);
            XYZ _line2_start    = _line2.GetEndPoint(0);
            XYZ _line2_end      = _line2.GetEndPoint(1);

            if (_line1_start.IsAlmostEqualTo(_line2_start, 0.0001))
            {
                _intersectCount += 1;
            }
            if (_line1_end.IsAlmostEqualTo(_line2_start, 0.0001))
            {
                _intersectCount += 1;
            }
            if (_line1_start.IsAlmostEqualTo(_line2_end, 0.0001))
            {
                _intersectCount += 1;
            }
            if (_line1_end.IsAlmostEqualTo(_line2_end, 0.0001))
            {
                _intersectCount += 1;
            }

            return(_intersectCount);
        }
Exemple #5
0
        /// <summary>
        /// Identifies if the curve lies entirely in an XY plane (Z = constant)
        /// </summary>
        /// <param name="curve">The curve.</param>
        /// <returns>True if the curve lies in an XY plane, false otherwise.</returns>
        public static bool IsCurveInXYPlane(Curve curve)
        {
            // quick reject - are endpoints at same Z
            double zDelta = curve.GetEndPoint(1).Z - curve.GetEndPoint(0).Z;

            if (Math.Abs(zDelta) > 1e-05)
            {
                return(false);
            }

            if (!(curve is Line) && !curve.IsCyclic)
            {
                // Create curve loop from curve and connecting line to get plane
                List <Curve> curves = new List <Curve>();
                curves.Add(curve);
                curves.Add(Line.CreateBound(curve.GetEndPoint(1), curve.GetEndPoint(0)));
                CurveLoop curveLoop = CurveLoop.Create(curves);

                XYZ normal = curveLoop.GetPlane().Normal.Normalize();
                if (!normal.IsAlmostEqualTo(XYZ.BasisZ) && !normal.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #6
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);
        }
Exemple #7
0
        public static List <Curve> SplitCurve(Curve c, XYZ p, double shortCurveTolerance, bool preserveDirection = true)
        {
            //only lines are splited, arcs must implemented
            if (c != null &&
                p != null
                //&& c is Line
                && IsPointOnCurve(c, p))
            {
                XYZ cS = GetEndPoint(c, 0);
                XYZ cE = GetEndPoint(c, 1);

                if (!p.IsAlmostEqualTo(cS) && !p.IsAlmostEqualTo(cE) &&
                    (p.DistanceTo(cS) > shortCurveTolerance || DoubleUtilities.IsDoublesEqual(p.DistanceTo(cS), shortCurveTolerance)) &&
                    (p.DistanceTo(cE) > shortCurveTolerance || DoubleUtilities.IsDoublesEqual(p.DistanceTo(cE), shortCurveTolerance)))
                {
                    Curve c1 = null;
                    Curve c2 = null;

                    if (c is Arc)
                    {
                        Arc arc = c as Arc;

                        //XYZ center = arc.Evaluate(0.5, true);

                        XYZ center1 = PushOnCurveByCurve(c, GetEndPoint(c, 0), VectorUtils.GetVectorOfCurve(c), cS.DistanceTo(p) / 2.0);
                        XYZ center2 = PushOnCurveByCurve(c, GetEndPoint(c, 1), VectorUtils.GetVectorOfCurve(c).Negate(), cE.DistanceTo(p) / 2.0);

                        c1 = Arc.Create(cS, p, center1);

                        c2 = Arc.Create(p, cE, center2);
                    }
                    else
                    {
                        if (preserveDirection)
                        {
                            c1 = LineUtils.NewLineBound(cS, p) as Curve;
                            c2 = LineUtils.NewLineBound(p, cE) as Curve;
                        }
                        else
                        {
                            c1 = LineUtils.NewLineBound(p, cS) as Curve;
                            c2 = LineUtils.NewLineBound(p, cE) as Curve;
                        }
                    }

                    if (c1 != null && c2 != null)
                    {
                        return(new List <Curve>()
                        {
                            c1, c2
                        });
                    }
                }
            }

            return(null);
        }
Exemple #8
0
        /// <summary>
        /// Generate and return an SVG path definition to
        /// represent the given room boundary loop, scaled
        /// from the given bounding box to fit into a
        /// 100 x 100 canvas. Actually, the size is
        /// determined by _target_square_size.
        /// </summary>
        string GetSvgPathFrom(
            BoundingBoxXYZ bb,
            IList <BoundarySegment> loop)
        {
            // Determine scaling and offsets to transform
            // from bounding box to (0,0)-(100,100).

            XYZ    pmin  = bb.Min;
            XYZ    pmax  = bb.Max;
            XYZ    vsize = pmax - pmin;
            XYZ    pmid  = pmin + 0.5 * vsize;
            double size  = Math.Max(vsize.X, vsize.Y);
            double scale = _target_square_size / size;

            StringBuilder s = new StringBuilder();

            int nSegments = loop.Count;

            XYZ p0 = null; // loop start point
            XYZ p;         // segment start point
            XYZ q = null;  // segment end point

            foreach (BoundarySegment seg in loop)
            {
                Curve curve = seg.GetCurve();

                // Todo: handle non-linear curve.
                // Especially: if two long lines have a
                // short arc in between them, skip the arc
                // and extend both lines.

                p = curve.GetEndPoint(0);

                Debug.Assert(null == q || q.IsAlmostEqualTo(p),
                             "expected last endpoint to equal current start point");

                q = curve.GetEndPoint(1);

                if (null == p0)
                {
                    p0 = p; // save loop start point

                    s.Append("M"
                             + GetSvgPointFrom(p, pmid, scale));
                }
                s.Append("L"
                         + GetSvgPointFrom(q, pmid, scale));
            }
            s.Append("Z");

            Debug.Assert(q.IsAlmostEqualTo(p0),
                         "expected last endpoint to equal loop start point");

            return(s.ToString());
        }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            // 【获取句柄】
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document   doc   = uidoc.Document;
            // 【获取墙】
            Wall wall = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Wall;

            if (wall != null)
            {
                // 【获取定位线】
                Line wallLine = (wall.Location as LocationCurve).Curve as Line;
                // 【获取方向,用来寻找参照】
                XYZ wallDir = wallLine.Direction;
                // 【获取墙定位线的参照】
                ReferenceArray refArry = new ReferenceArray();
                // 【定义几何选项】
                Options opt = new Options();
                opt.ComputeReferences = true;
                opt.DetailLevel       = ViewDetailLevel.Fine;
                //【获取墙的几何】
                GeometryElement gelem = wall.get_Geometry(opt);
                foreach (GeometryObject gobj in gelem)
                {
                    if (gobj is Solid)
                    {
                        Solid solid = gobj as Solid;
                        if (solid.Volume > 0)
                        {
                            foreach (Face face in solid.Faces)
                            {
                                if (face is PlanarFace)
                                {
                                    XYZ faceDir = face.ComputeNormal(new UV());
                                    //判断是否平行
                                    if (faceDir.IsAlmostEqualTo(wallDir) || faceDir.IsAlmostEqualTo(-wallDir))
                                    {
                                        refArry.Append(face.Reference);
                                        TaskDialog.Show("1", "1");
                                    }
                                }
                            }
                        }
                    }
                }
                Transaction trans = new Transaction(doc, "开始标注");
                trans.Start();
                Dimension dimension = doc.Create.NewDimension(doc.ActiveView, wallLine, refArry);
                trans.Commit();
            }
            return(Result.Succeeded);
        }
Exemple #10
0
        public static List <Curve> GetBoundary(List <CurveArray> polys)
        {
            bool IsSame(Curve crv1, Curve crv2)
            {
                XYZ start1 = crv1.GetEndPoint(0);
                XYZ start2 = crv2.GetEndPoint(0);
                XYZ end1   = crv1.GetEndPoint(1);
                XYZ end2   = crv2.GetEndPoint(1);

                if (start1.IsAlmostEqualTo(start2) && end1.IsAlmostEqualTo(end2) ||
                    start1.IsAlmostEqualTo(end2) && start2.IsAlmostEqualTo(end1))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }

            List <Curve> shatters = new List <Curve>();
            List <Curve> boundary = new List <Curve>();

            foreach (CurveArray poly in polys)
            {
                for (int i = 0; i < poly.Size; i++)
                {
                    shatters.Add(poly.get_Item(i));
                }
            }
            Debug.Print("Shatters in all: " + shatters.Count.ToString());
            for (int i = 0; i < shatters.Count; i++)
            {
                for (int j = 0; j < shatters.Count; j++)
                {
                    if (j != i)
                    {
                        if (IsSame(shatters[i], shatters[j]))
                        {
                            goto a;
                        }
                    }
                }
                boundary.Add(shatters[i]);
                a :;
            }
            Debug.Print("Boundry size: " + boundary.Count.ToString());
            return(boundary);
        }
Exemple #11
0
		/// <summary>
		/// Creates a selection filter that will let faces pass, if their normal vector at (0/0) is 
		/// codirectional or parallel to the given normal vector
		/// </summary>
		/// <param name="doc"></param>
		/// <param name="normal"></param>
		/// <param name="acceptParallel"></param>
		/// <returns></returns>
		public static IReferenceSelectionFilter GetFaceNormalFilter(Document doc, XYZ normal, bool acceptParallel = false)
			{
			XYZ _normal = normal.Normalize ();
			XYZ minusNormal = -1*_normal;
			return GetReferenceFilter ((reference, xyz) =>
			                           	{
			                           	Element element = doc.GetElement (reference);
			                           	Face face = element.GetGeometryObjectFromReference (reference) as Face;
			                           	if (face == null) return false;
			                           	XYZ faceNormal = face.ComputeNormal (UV.Zero);
			                           	bool erg = faceNormal.IsAlmostEqualTo (_normal);
																	if (acceptParallel) erg |= faceNormal.IsAlmostEqualTo(minusNormal);
			                           	return erg;
			                           	});
			}
Exemple #12
0
        public static IList <PlanarFace> ListNearestFace(PlanarFace face, IList <PlanarFace> listFaces)
        {
            IList <PlanarFace> list  = new List <PlanarFace>();
            PlanarFace         face2 = Facelibry.NearestFace(face, listFaces);
            XYZ    point             = Facelibry.CenterPoint(face2);
            double num        = Facelibry.PointToFace(point, face);
            XYZ    faceNormal = face.FaceNormal;
            XYZ    right      = Facelibry.CenterPoint(face);

            foreach (PlanarFace planarFace in listFaces)
            {
                XYZ  xyz  = Facelibry.CenterPoint(planarFace);
                XYZ  xyz2 = xyz - right;
                bool flag = xyz2.IsAlmostEqualTo(new XYZ());
                if (!flag)
                {
                    double num2  = Facelibry.PointToFace(xyz, face);
                    bool   flag2 = num2 <1.02 * num && num2> 0.98 * num;
                    if (flag2)
                    {
                        list.Add(planarFace);
                    }
                }
            }
            return(list);
        }
Exemple #13
0
        public static bool ExtentGeometryChanged(Guid docId, ElementId currentGridId, Outline currentOutline)
        {
            bool changed = false;

            try
            {
                if (gridExtents.ContainsKey(docId))
                {
                    if (gridExtents[docId].ContainsKey(currentGridId))
                    {
                        Outline oldOutline = gridExtents[docId][currentGridId];
                        XYZ     oldMin     = oldOutline.MinimumPoint;
                        XYZ     oldMax     = oldOutline.MaximumPoint;

                        XYZ curMin = currentOutline.MinimumPoint;
                        XYZ curMax = currentOutline.MaximumPoint;

                        if (!oldMin.IsAlmostEqualTo(curMin) || !oldMax.IsAlmostEqualTo(curMax))
                        {
                            changed = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message;
            }
            return(changed);
        }
Exemple #14
0
        /// <summary>
        /// Check if a point is on a line
        /// </summary>
        /// <param name="pt"></param>
        /// <param name="line"></param>
        /// <returns></returns>
        public static bool IsPtOnLine(XYZ pt, Line line)
        {
            XYZ ptStart = line.GetEndPoint(0);
            XYZ ptEnd   = line.GetEndPoint(1);
            XYZ vec1    = (ptStart - pt).Normalize();
            XYZ vec2    = (ptEnd - pt).Normalize();

            if (!vec1.IsAlmostEqualTo(vec2) || pt.IsAlmostEqualTo(ptStart) || pt.IsAlmostEqualTo(ptEnd))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #15
0
        private Room getOtherRoom(Room r1, BoundarySegment seg, XYZ point)
        {
            // we already know what one of the rooms is attached to a boundary segment.
            // this attempts to find the other.
            Curve crv = seg.GetCurve();

            XYZ vector = crv.GetEndPoint(1).Subtract(crv.GetEndPoint(0)).Normalize();

            XYZ otherVector = XYZ.BasisZ;

            if (vector.IsAlmostEqualTo(XYZ.BasisZ))
            {
                otherVector = XYZ.BasisY;
            }
            XYZ perp = vector.CrossProduct(otherVector).Normalize();

            XYZ       testp1    = point.Add(perp.Multiply(0.25));
            XYZ       testp2    = point.Add(perp.Negate().Multiply(0.25));
            Parameter phaseParm = r1.get_Parameter(BuiltInParameter.ROOM_PHASE);
            Phase     p         = _doc.GetElement(phaseParm.AsElementId()) as Phase;

            Room roomP1 = _doc.GetRoomAtPoint(testp1, p);
            Room roomP2 = _doc.GetRoomAtPoint(testp2, p);

            if ((roomP1 != null) && (roomP1.Id != r1.Id))
            {
                return(roomP1);
            }
            if ((roomP2 != null) && (roomP2.Id != r1.Id))
            {
                return(roomP2);
            }

            return(null);
        }
Exemple #16
0
        /// <summary>
        /// Check point in polygon containment by vector crossproduct
        /// Only apply to cw or ccw polycurve array
        /// </summary>
        /// <param name="crvArr"></param>
        /// <param name="pt"></param>
        /// <returns></returns>
        public static bool PointInPoly(CurveArray crvArr, XYZ pt)
        {
            int judgement = 0;
            int counter   = 0;

            foreach (Curve crv in crvArr)
            {
                XYZ ptstart   = crv.GetEndPoint(0);
                XYZ ptend     = crv.GetEndPoint(1);
                XYZ direction = (pt - ptstart).CrossProduct(pt - ptend).Normalize();
                if (direction.IsAlmostEqualTo(new XYZ(0, 0, 1)))
                {
                    judgement += 1;
                }
                counter += 1;
            }
            if (judgement < counter)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Exemple #17
0
        public static void API_rotate(Document doc)
        {
            XYZ pos2  = (tempFi1.Location as LocationPoint).Point;
            XYZ face2 = tempFi1.FacingOrientation;

            using (Transaction trans = new Transaction(doc))
            {
                trans.Start("rotate");
                doc.Delete(tempFi1.Id);
                trans.Commit();
            }
            if (pos1.IsAlmostEqualTo(pos2))
            {
                return;
            }
            else
            {
                //求旋转中心
                XYZ rotateCenter = GetRotateCenter(pos1, face1, pos2, face2);

                double angle = face1.AngleOnPlaneTo(face2, new XYZ(0, 0, 1));

                using (Transaction trans = new Transaction(doc))
                {
                    trans.Start("rotate");
                    //执行模块打的旋转操作
                    //ModuleRotate.RotateOperation(doc, Rotate_CMD.allFi, rotateCenter, angle);
                    trans.Commit();
                }
            }
        }
Exemple #18
0
        public static bool ExtentGeometryChanged(string centralPath, ElementId currentGridId, Outline currentOutline)
        {
            bool changed = false;

            try
            {
                if (gridExtents.ContainsKey(centralPath))
                {
                    if (gridExtents[centralPath].ContainsKey(currentGridId))
                    {
                        Outline oldOutline = gridExtents[centralPath][currentGridId];
                        XYZ     oldMin     = oldOutline.MinimumPoint;
                        XYZ     oldMax     = oldOutline.MaximumPoint;

                        XYZ curMin = currentOutline.MinimumPoint;
                        XYZ curMax = currentOutline.MaximumPoint;

                        if (!oldMin.IsAlmostEqualTo(curMin) || !oldMax.IsAlmostEqualTo(curMax))
                        {
                            changed = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message;
                LogUtil.AppendLog("GridUtils-ExtentGeometryChanged:" + ex.Message);
            }
            return(changed);
        }
Exemple #19
0
        public Particle makeParticleFromXYZ(ElementId eid, double mass, XYZ position, bool fix)
        {
            bool found = false;

            for (int i = 0; i < particles.Count(); ++i)
            {
                if (eid != null && (particles[i].getElementID() != null) && position != null)
                {
                    if (position.IsAlmostEqualTo(particles[i].getPosition()))
                    {
                        found = true;
                        particles[i].setPosition(position);
                        return(particles[i]);
                    }
                }
            }
            if (found == false)//if we did not find one make a new one
            {
                Particle part = new Particle(partID++, eid, mass, position, fix);
                particles.Add(part);
                return(part);
            }

            return(null);
        }
Exemple #20
0
        private FamilyInstanceCreationData GetCreationData(Autodesk.Revit.DB.Curve curve, Autodesk.Revit.DB.XYZ upVector, Autodesk.Revit.DB.Level level, Autodesk.Revit.DB.Structure.StructuralType structuralType, Autodesk.Revit.DB.FamilySymbol symbol)
        {
            //calculate the desired rotation
            //we do this by finding the angle between the z axis
            //and vector between the start of the beam and the target point
            //both projected onto the start plane of the beam.
            var zAxis = new XYZ(0, 0, 1);
            var yAxis = new XYZ(0, 1, 0);

            //flatten the beam line onto the XZ plane
            //using the start's z coordinate
            var start  = curve.GetEndPoint(0);
            var end    = curve.GetEndPoint(1);
            var newEnd = new XYZ(end.X, end.Y, start.Z); //drop end point to plane

            //catch the case where the end is directly above
            //the start, creating a normal with zero length
            //in that case, use the Z axis
            XYZ planeNormal = newEnd.IsAlmostEqualTo(start) ? zAxis : (newEnd - start).Normalize();

            double gamma = upVector.AngleOnPlaneTo(zAxis.IsAlmostEqualTo(planeNormal) ? yAxis : zAxis, planeNormal);

            return(new FamilyInstanceCreationData(curve, symbol, level, structuralType)
            {
                RotateAngle = gamma
            });
        }
Exemple #21
0
        static public Curve Flatten(this Curve curve, double height = 0)
        {
            XYZ firstPoint = curve.GetEndPoint(0);

            firstPoint = new XYZ(firstPoint.X, firstPoint.Y, height);
            XYZ secondPoint = curve.GetEndPoint(1);

            secondPoint = new XYZ(secondPoint.X, secondPoint.Y, height);

            if (firstPoint.IsAlmostEqualTo(secondPoint))
            {
                return(null);
            }

            if (curve is Line)
            {
                return(Line.CreateBound(firstPoint, secondPoint));
            }
            if (curve is Arc)
            {
                XYZ centerPoint = curve.Evaluate(0.5, true);
                centerPoint = new XYZ(centerPoint.X, centerPoint.Y, height);
                return(Arc.Create(firstPoint, secondPoint, centerPoint));
            }

            throw new Exception("THIAGO -> Curve can't be flatten because it is not a line or arc");
        }
Exemple #22
0
        public void Test()
        {
            XYZ2 xyz_1 = new XYZ2(0, 0, 0);
            XYZ2 xyz_2 = new XYZ2(0, 0, 1);
            XYZ2 xyz_3 = new XYZ2(0, 1, 0);

            XYZ a = new XYZ(0, 1.0, 0);

            TaskDialog.Show("xyz", (a.IsAlmostEqualTo(xyz_3)).ToString());

            List <XYZ2> myListXYZ = new List <XYZ2>()
            {
                xyz_1, xyz_2, xyz_3
            };

            XYZ2 xyz_test = new XYZ2(0, 0, 0);

            if (xyz_1 == xyz_test)
            {
                TaskDialog.Show("abc", "Yes");
            }

            if (myListXYZ.Contains(xyz_test))
            {
                TaskDialog.Show("abc", "Yes");
            }
            else
            {
                TaskDialog.Show("abc", "No");
            }
        }
Exemple #23
0
        static private XYZ GetExtendedPoint(XYZ startPosition, PlanarFace targetPlanarFace, double amount = 0.1)
        {
            if (targetPlanarFace != null)
            {
                CurveLoop currentCurveLoop = GetOuterCurveLoop(targetPlanarFace);

                foreach (Curve currentCurve in currentCurveLoop)
                {
                    if (currentCurve.GetEndPoint(0).Z.IsAlmostEqualTo(targetPlanarFace.Origin.Z) && currentCurve.GetEndPoint(1).Z.IsAlmostEqualTo(targetPlanarFace.Origin.Z))
                    {
                        XYZ p0 = startPosition;
                        XYZ p1 = startPosition;

                        if (p0.IsAlmostEqualTo(currentCurve.GetEndPoint(0)))
                        {
                            p1 = currentCurve.GetEndPoint(1);
                        }
                        else
                        {
                            p1 = currentCurve.GetEndPoint(0);
                        }

                        XYZ lineDirection  = Line.CreateBound(p0, p1).Direction;
                        XYZ extendendPoint = p0 + (lineDirection.Negate() * amount);

                        return(extendendPoint);
                    }
                }
            }
            return(startPosition);
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="cur1"></param>
 /// <param name="cur2"></param>
 /// <param name="mergedCur"></param>
 /// <returns></returns>
 public static bool Merge(Bcurve cur1, Bcurve cur2, out Bcurve mergedCur)
 {
     mergedCur = new Bcurve();
     if ((cur1.Id == cur2.Id) && (cur1.Curve is Line) &&
         (cur2.Curve is Line))
     {
         Line lin1 = cur1.Curve as Line;
         Line lin2 = cur2.Curve as Line;
         if ((lin1.Direction.Normalize().IsAlmostEqualTo
                  (lin2.Direction.Normalize())) &&
             (lin1.IsBound) && (lin2.IsBound))
         {
             XYZ lin1s = lin1.GetEndPoint(0);
             XYZ lin1e = lin1.GetEndPoint(1);
             XYZ lin2s = lin2.GetEndPoint(0);
             XYZ lin2e = lin2.GetEndPoint(1);
             if (lin1s.IsAlmostEqualTo(lin2e))
             {
                 mergedCur = new Bcurve
                                 (Line.CreateBound(lin2s, lin1e), cur1);
                 return(true);
             }
             else if (lin1e.IsAlmostEqualTo(lin2s))
             {
                 mergedCur = new Bcurve(
                     Line.CreateBound(lin1s, lin2e), cur1);
                 return(true);
             }
         }
     }
     return(false);
 }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document   doc   = uidoc.Document;
            Wall       wall  = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Wall;

            if (wall != null)
            {
                ReferenceArray refArry = new ReferenceArray();

                Line wallLine = (wall.Location as LocationCurve).Curve as Line;

                XYZ wallDir = ((wall.Location as LocationCurve).Curve as Line).Direction;

                // wallDir = new XYZ(wallDir.Y, -wallDir.X, 0);

                Options opt = new Options();
                opt.ComputeReferences = true;
                opt.DetailLevel       = ViewDetailLevel.Fine;
                GeometryElement gelem = wall.get_Geometry(opt);

                foreach (GeometryObject gobj in gelem)
                {
                    if (gobj is Solid)
                    {
                        Solid solid = gobj as Solid;
                        foreach (Face face in solid.Faces)
                        {
                            if (face is PlanarFace)
                            {
                                XYZ faceDir = face.ComputeNormal(new UV());
                                if (faceDir.IsAlmostEqualTo(wallDir) || faceDir.IsAlmostEqualTo(-wallDir))
                                {
                                    refArry.Append(face.Reference);
                                }
                            }
                        }
                    }
                }
                Transaction trans = new Transaction(doc, "trans");
                trans.Start();
                doc.Create.NewDimension(doc.ActiveView, wallLine, refArry);
                trans.Commit();
            }

            return(Result.Succeeded);
        }
Exemple #26
0
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uiDoc = commandData.Application.ActiveUIDocument;
            Document   doc   = uiDoc.Document;
            FilteredElementCollector coll       = new FilteredElementCollector(doc);
            ElementClassFilter       gridFilter = new ElementClassFilter(typeof(Grid));
            List <Element>           grid       = coll.WherePasses(gridFilter).ToElements().ToList();
            List <Line> gridLines = new List <Line>();
            List <XYZ>  intXyzs   = new List <XYZ>();

            foreach (Grid g in grid)
            {
                gridLines.Add(g.Curve as Line);
            }

            foreach (Line line1 in gridLines)
            {
                foreach (Line line2 in gridLines)
                {
                    XYZ normal1 = line1.Direction;
                    XYZ normal2 = line2.Direction;
                    if (normal1.IsAlmostEqualTo(normal2))
                    {
                        continue;//如果平行,执行下一条
                    }

                    SetComparisonResult intRst = line1.Intersect(line2, out IntersectionResultArray results);
                    if (intRst == SetComparisonResult.Overlap && results.Size == 1)
                    {
                        XYZ tp = results.get_Item(0).XYZPoint;
                        if (intXyzs.Where(m => m.IsAlmostEqualTo(tp)).Count() == 0)
                        {
                            intXyzs.Add(tp);//如果不重复,则添加该交点
                        }
                    }
                }
            }

            Level        level        = doc.GetElement(new ElementId(311)) as Level;
            FamilySymbol familySymbol = doc.GetElement(new ElementId(338370)) as FamilySymbol;

            using (Transaction tr = new Transaction(doc)) {
                tr.Start("Clomn");
                if (!familySymbol.IsActive)
                {
                    familySymbol.Activate();
                }

                foreach (XYZ xyz in intXyzs)
                {
                    FamilyInstance familyInstance =
                        doc.Create.NewFamilyInstance(xyz, familySymbol, level, StructuralType.NonStructural);
                }

                tr.Commit();
            }

            return(Result.Succeeded);
        }
Exemple #27
0
        private List <ModelCurve> DrawInsulLine(MEPCurve e, double stepLength, double height, GraphicsStyle style)
        {
            Curve ductCurve = GeometryUtils.FindDuctCurve(e.ConnectorManager);
            XYZ   pt1 = ductCurve.GetEndPoint(0); XYZ pt2 = ductCurve.GetEndPoint(1);

            // создаем плоскость, на которой будет рисоваться штриховка
            XYZ VOffset;
            XYZ ductVector = GeometryUtils.GetDuctDirection(e.ConnectorManager);

            // Вертикальная линии
            if (ductVector.IsAlmostEqualTo(XYZ.BasisZ) | ductVector.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
            {
                // находим перпендикулярный вектор, нормализуем его и умножаем до нужной длины
                VOffset = (pt2 - pt1).CrossProduct(XYZ.BasisY).Normalize() * (height / 2);
            }
            else
            {
                VOffset = (pt2 - pt1).CrossProduct(XYZ.BasisZ).Normalize() * (height / 2);
            }

            XYZ        UOffset = (pt2 - pt1).Normalize() * (stepLength / 2);
            int        steps   = (int)Math.Floor((pt2 - pt1).GetLength() / UOffset.GetLength());
            List <XYZ> points  = new List <XYZ>();

            points.Add(pt1);
            for (int i = 0; i < steps; i++)
            {
                pt1 = pt1 + UOffset;
                XYZ VOffsetedPt = pt1 + VOffset;
                points.Add(VOffsetedPt);
                VOffset = VOffset.Negate();
            }
            points.Add(pt2);
            ModelCurveCreator mcc = new ModelCurveCreator(doc);

            mcc.LineStyle = style;
            if (points.Count() > 2)
            {
                var array = mcc.MakeModelCurve(points, false);
                return(array);
            }
            else
            {
                return(null);
            }
        }
Exemple #28
0
        private bool IsParallel(Grid grid1, Grid grid2)
        {
            Line line1          = grid1.Curve as Line;
            Line line2          = grid2.Curve as Line;
            XYZ  direction1     = line1.Direction;
            XYZ  backdirection1 = direction1.Negate();
            XYZ  direction2     = line2.Direction;

            if (direction2.IsAlmostEqualTo(direction1) || direction2.IsAlmostEqualTo(backdirection1))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #29
0
        /// <summary>
        /// 找到一个点与所有线段的重合端点线段,并输出重合端点的线段索引值
        /// </summary>
        /// <param name="_i_xyz"></param>
        /// <param name="_Lines"></param>
        /// <param name="Lines"></param>
        /// <returns></returns>
        public static int IsXYZcoincideAllLines(XYZ _i_xyz, List <Line> _Lines, out List <int> list_int)
        {
            list_int = new List <int>();//收集与 i 线段的一个端点重合线段的索引值
            int _count = _Lines.Count;

            for (int k = 0; k < _count; k++)
            {
                XYZ _k_xyz_0 = _Lines[k].GetEndPoint(0);
                XYZ _k_xyz_1 = _Lines[k].GetEndPoint(1);

                if (_i_xyz.IsAlmostEqualTo(_k_xyz_0, 0.0001) || _i_xyz.IsAlmostEqualTo(_k_xyz_1, 0.0001))//判断线段端点是否重合
                {
                    list_int.Add(k);
                }
            }
            return(list_int.Count);
        }
Exemple #30
0
        static public DuctOrientation GetDuctOrientation(ConnectorManager conMngr)
        {
            XYZ orientation = GetDuctDirection(conMngr);

            if (orientation.IsAlmostEqualTo(XYZ.BasisZ) || orientation.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
            {
                return(DuctOrientation.StraightVertical);
            }
            else if (orientation.IsAlmostEqualTo(new XYZ(orientation.X, orientation.Y, 0)))
            {
                return(DuctOrientation.Horizontal);
            }
            else
            {
                return(DuctOrientation.Angled);
            }
        }
Exemple #31
0
        public static Solid CylinderByAxisOriginRadiusHeight(XYZ axis, XYZ origin, double radius, double height)
        {
            // get axis that is perp to axis by first generating random vector
            var zaxis = axis.Normalize();
            var randXyz = new XYZ(1, 0, 0);
            if (axis.IsAlmostEqualTo(randXyz)) randXyz = new XYZ(0, 1, 0);
            var yaxis = zaxis.CrossProduct(randXyz).Normalize();

            // get second axis that is perp to axis
            var xaxis = yaxis.CrossProduct(zaxis);

            // create circle (this is ridiculous, but curve loop doesn't work with a circle - you need two arcs)
            var arc1 = dynRevitSettings.Doc.Application.Application.Create.NewEllipse(origin, radius, radius, xaxis, yaxis, 0, Circle.RevitPI);
            var arc2 = dynRevitSettings.Doc.Application.Application.Create.NewEllipse(origin, radius, radius, xaxis, yaxis, Circle.RevitPI, 2 * Circle.RevitPI);

            // create curve loop from cirle
            var circleLoop = Autodesk.Revit.DB.CurveLoop.Create(new List<Curve>() { arc1, arc2 });

            // extrude the curve and return
            return GeometryCreationUtilities.CreateExtrusionGeometry(new List<Autodesk.Revit.DB.CurveLoop>() { circleLoop }, zaxis, height);
        }
Exemple #32
0
 /// <summary>
 /// Find the list of parallel linear grids via the given direction.
 /// </summary>
 /// <param name="linearGrids">The set of linear grids.</param>
 /// <param name="baseDirection">The given direction.</param>
 /// <returns>The list of parallel grids, containing the anti direction grids.</returns>
 private static List<Grid> FindParallelGrids(IDictionary<XYZ, List<Grid>> linearGrids, XYZ baseDirection)
 {
     List<XYZ> directionList = linearGrids.Keys.ToList();
     List<Grid> parallelGrids = linearGrids[baseDirection];
     foreach (XYZ direction in directionList)
     {
         if (baseDirection.IsAlmostEqualTo(direction))
             continue;
         double dotProduct = direction.DotProduct(baseDirection);
         if (MathUtil.IsAlmostEqual(dotProduct, -1.0))
         {
             parallelGrids = parallelGrids.Union<Grid>(linearGrids[direction]).ToList();
             return parallelGrids;
         }
     }
     return parallelGrids;
 }
Exemple #33
0
        public override Value Evaluate(FSharpList<Value> args)
        {
            var symbol = (FamilySymbol)((Value.Container)args[0]).Item;
            var curves = ((Value.List) args[1]).Item;

            IEnumerable<Tuple<Curve, XYZ>> data;
            if (args[2].IsList)
            {
                var targets = ((Value.List)args[2]).Item;

                if (curves.Count() != targets.Count())
                    throw new Exception("The number of curves and the number of up vectors must be the same.");

                //if we get a list of up vectors, then pair each
                //curve with a corresponding up vector
                data = curves.Zip(targets,
                    (first, second) =>
                        new Tuple<Curve, XYZ>((Curve) ((Value.Container) first).Item,
                            (XYZ) ((Value.Container) second).Item));
            }
            else
            {
                //if we get a single up vector, then pair each
                //curve with that up vector
                data = curves.Select(x=>new Tuple<Curve, XYZ>((Curve)((Value.Container)x).Item,
                            (XYZ)((Value.Container)args[2]).Item));
            }

            var instData = new List<FamilyInstanceCreationData>();

            int count = 0;

            foreach (var pair in data)
            {
                var curve = pair.Item1;
                var target = pair.Item2;

                //calculate the desired rotation
                //we do this by finding the angle between the z axis
                //and vector between the start of the beam and the target point
                //both projected onto the start plane of the beam.

                XYZ zAxis = new XYZ(0, 0, 1);
                XYZ yAxis = new XYZ(0, 1, 0);

                //flatten the beam line onto the XZ plane
                //using the start's z coordinate
                XYZ start = curve.get_EndPoint(0);
                XYZ end = curve.get_EndPoint(1);
                XYZ newEnd = new XYZ(end.X, end.Y, start.Z); //drop end point to plane

                ////use the x axis of the curve's transform
                ////as the normal of the start plane
                //XYZ planeNormal = (curve.get_EndPoint(0) - curve.get_EndPoint(1)).Normalize();

                //catch the case where the end is directly above
                //the start, creating a normal with zero length
                //in that case, use the Z axis
                XYZ planeNormal = newEnd.IsAlmostEqualTo(start) ? zAxis : (newEnd - start).Normalize();

                XYZ target_project = target - target.DotProduct(planeNormal)*planeNormal;
                XYZ z_project = zAxis - zAxis.DotProduct(planeNormal)*planeNormal;

                //double gamma = target_project.AngleTo(z_project);
                double gamma = target.AngleOnPlaneTo(zAxis.IsAlmostEqualTo(planeNormal) ? yAxis : zAxis, planeNormal);

                FamilyInstance instance = null;
                if (this.Elements.Count > count)
                {
                    if (dynUtils.TryGetElement(this.Elements[count], out instance))
                    {
                        if (instance.Symbol != symbol)
                            instance.Symbol = symbol;

                        //update the curve
                        var locCurve = instance.Location as LocationCurve;
                        locCurve.Curve = curve;
                    }
                    else
                    {
                        var beamData = new FamilyInstanceCreationData(curve, symbol, dynRevitSettings.DefaultLevel, StructuralType.Beam)
                            {
                                RotateAngle = gamma
                            };
                        instData.Add(beamData);
                    }
                }
                else
                {
                    var beamData = new FamilyInstanceCreationData(curve, symbol, dynRevitSettings.DefaultLevel, StructuralType.Beam)
                        {
                            RotateAngle = gamma
                        };
                    instData.Add(beamData);
                }

                count++;
            }

            //trim the elements collection
            foreach (var e in this.Elements.Skip(count))
            {
                this.DeleteElement(e);
            }

            FSharpList<Value> results = FSharpList<Value>.Empty;

            if (instData.Any())
            {
                var ids = dynRevitSettings.Doc.Document.Create.NewFamilyInstances2(instData);

                //add our batch-created instances ids'
                //to the elements collection
                ids.ToList().ForEach(x=>Elements.Add(x));
            }

            //add all of the instances
            results = Elements.Aggregate(results, (current, id) => FSharpList<Value>.Cons(Value.NewContainer(dynRevitSettings.Doc.Document.GetElement(id)), current));
            results.Reverse();

            return Value.NewList(results);
        }
 public void CreateModelLine( XYZ p, XYZ q )
 {
     if( p.IsAlmostEqualTo( q ) )
       {
     throw new ArgumentException(
       "Expected two different points." );
       }
       Line line = Line.CreateBound( p, q );
       if( null == line )
       {
     throw new Exception(
       "Geometry line creation failed." );
       }
       _credoc.NewModelCurve( line,
     NewSketchPlanePassLine( line ) );
 }
Exemple #35
0
        public Particle makeParticleFromXYZ(ElementId eid, double mass, XYZ position, bool fix)
        {
            bool found = false;
            for (int i = 0; i < particles.Count(); ++i)
            {
                if (eid != null && (particles[i].getElementID() != null)&& position!=null)
                {
                    if (position.IsAlmostEqualTo(particles[i].getPosition()))
                    {
                        found = true;
                        particles[i].setPosition(position);
                        return particles[i];

                    }
                }
            }
            if (found == false)//if we did not find one make a new one
            {
                Particle part = new Particle(partID++, eid, mass, position, fix);
                particles.Add(part);
                return part;
            }

            return null;
        }
Exemple #36
0
        public Particle getParticleByXYZ(XYZ xyz)
        {
            for (int i = 0; i < particles.Count(); ++i)
            {
                if (xyz != null && particles.Count > 0 && (particles[i].getElementID() != null))
                {
                    if (xyz.IsAlmostEqualTo(particles[i].getPosition()))
                    {
                        return particles[i];

                    }

                }

            }

            return null;
        }
Exemple #37
0
        private static FamilyInstanceCreationData GetCreationData(Autodesk.Revit.DB.Curve curve, Autodesk.Revit.DB.XYZ upVector, Autodesk.Revit.DB.Level level, Autodesk.Revit.DB.Structure.StructuralType structuralType, Autodesk.Revit.DB.FamilySymbol symbol)
        {

            //calculate the desired rotation
            //we do this by finding the angle between the z axis
            //and vector between the start of the beam and the target point
            //both projected onto the start plane of the beam.
            var zAxis = new XYZ(0, 0, 1);
            var yAxis = new XYZ(0, 1, 0);

            //flatten the beam line onto the XZ plane
            //using the start's z coordinate
            var start = curve.GetEndPoint(0);
            var end = curve.GetEndPoint(1);
            var newEnd = new XYZ(end.X, end.Y, start.Z); //drop end point to plane

            //catch the case where the end is directly above
            //the start, creating a normal with zero length
            //in that case, use the Z axis
            XYZ planeNormal = newEnd.IsAlmostEqualTo(start) ? zAxis : (newEnd - start).Normalize();

            double gamma = upVector.AngleOnPlaneTo(zAxis.IsAlmostEqualTo(planeNormal) ? yAxis : zAxis, planeNormal);

            return new FamilyInstanceCreationData(curve, symbol, level, structuralType)
            {
                RotateAngle = gamma
            };

        }
        /// <summary>
        /// Returns a handle for creation of an AdvancedBrep with AdvancedFace and assigns it to the file
        /// </summary>
        /// <param name="exporterIFC">exporter IFC</param>
        /// <param name="element">the element</param>
        /// <param name="options">exporter option</param>
        /// <param name="geomObject">the geometry object</param>
        /// <returns>the handle</returns>
        public static IFCAnyHandle ExportBodyAsAdvancedBrep(ExporterIFC exporterIFC, Element element, BodyExporterOptions options,
            GeometryObject geomObject)
        {
            IFCFile file = exporterIFC.GetFile();
            Document document = element.Document;

            IFCAnyHandle advancedBrep = null;

            try
            {
                if (geomObject is Solid)
                {
                    IList<IFCAnyHandle> edgeLoopList = new List<IFCAnyHandle>();
                    HashSet<IFCAnyHandle> cfsFaces = new HashSet<IFCAnyHandle>();
                    Solid geomSolid = geomObject as Solid;
                    FaceArray faces = geomSolid.Faces;
                    foreach (Face face in faces)
                    {
                        IList<IFCAnyHandle> orientedEdgeList = new List<IFCAnyHandle>();
                        IFCAnyHandle surface = null;

                        // Use SortCurveLoops to collect the outerbound(s) with its list of innerbounds
                        IList<IList<CurveLoop>> curveloopList = ExporterIFCUtils.SortCurveLoops(GetEdgesAsCurveLoops(face));
                        IList<HashSet<IFCAnyHandle>> boundsCollection = new List<HashSet<IFCAnyHandle>>();

                        // loop for each outerloop (and its list of innerloops
                        foreach (IList<CurveLoop> curveloops in curveloopList)
                        {
                            foreach (CurveLoop curveloop in curveloops)
                            {
                                CurveLoopIterator curveloopIter = curveloop.GetCurveLoopIterator();
                                XYZ lastPoint = new XYZ();
                                bool first = true;
                                bool unbounded = false;
                                while (curveloopIter.MoveNext())
                                {
                                    IFCAnyHandle edgeCurve = null;
                                    bool orientation = true;
                                    bool sameSense = true;
                                    Curve currCurve = curveloopIter.Current;
                                    IFCAnyHandle edgeStart = null;
                                    IFCAnyHandle edgeEnd = null;

                                    if (currCurve.IsBound)
                                    {
                                        IFCAnyHandle edgeStartCP = XYZtoIfcCartesianPoint(exporterIFC, currCurve.GetEndPoint(0), true);
                                        edgeStart = IFCInstanceExporter.CreateVertexPoint(file, edgeStartCP);
                                        IFCAnyHandle edgeEndCP = XYZtoIfcCartesianPoint(exporterIFC, currCurve.GetEndPoint(1), true);
                                        edgeEnd = IFCInstanceExporter.CreateVertexPoint(file, edgeEndCP);
                                    }
                                    else
                                    {
                                        unbounded = true;
                                    }

                                    // Detect the sense direction by the continuity of the last point in the previous curve to the first point of the current curve
                                    if (!unbounded)
                                    {
                                        if (first)
                                        {
                                            lastPoint = currCurve.GetEndPoint(1);
                                            sameSense = true;
                                            first = false;
                                        }
                                        else
                                        {
                                            if (lastPoint.IsAlmostEqualTo(currCurve.GetEndPoint(1)))
                                            {
                                                sameSense = false;
                                                lastPoint = currCurve.GetEndPoint(0);
                                            }
                                            else
                                            {
                                                sameSense = true;
                                                lastPoint = currCurve.GetEndPoint(1);
                                            }
                                        }
                                    }

                                    // if the Curve is a line, do the following
                                    edgeCurve = CreateEdgeCurveFromCurve(file, exporterIFC, currCurve, edgeStart, edgeEnd, sameSense);
                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(edgeCurve))
                                        continue;

                                    IFCAnyHandle orientedEdge = IFCInstanceExporter.CreateOrientedEdge(file, edgeCurve, orientation);
                                    orientedEdgeList.Add(orientedEdge);
                                }

                                IFCAnyHandle edgeLoop = IFCInstanceExporter.CreateEdgeLoop(file, orientedEdgeList);
                                edgeLoopList.Add(edgeLoop);     // The list may contain outer edges and inner edges
                            }
                       
                            // Process the edgelooplist
                            bool orientationFB = true; //temp
                            HashSet<IFCAnyHandle> bounds = new HashSet<IFCAnyHandle>();
                            IFCAnyHandle faceOuterBound = IFCInstanceExporter.CreateFaceOuterBound(file, edgeLoopList[0], orientationFB);
                            bounds.Add(faceOuterBound);
                            if (edgeLoopList.Count > 1)
                            {
                                orientationFB = false; //temp
                                // Process inner bound
                                for (int ii = 1; ii < edgeLoopList.Count; ++ii)
                                {
                                    IFCAnyHandle faceBound = IFCInstanceExporter.CreateFaceBound(file, edgeLoopList[ii], orientationFB);
                                    bounds.Add(faceBound);
                                }
                            }
                            // We collect the list of Outerbounds (plus their innerbounds) here 
                            //    to create multiple AdvancedFaces from the same face if there are multiple faceouterbound
                            boundsCollection.Add(bounds);
                        }

                        // process the face now
                        if (face is PlanarFace)
                        {
                            PlanarFace plFace = face as PlanarFace;
                            XYZ plFaceNormal = plFace.Normal;

                            IFCAnyHandle location = XYZtoIfcCartesianPoint(exporterIFC, plFace.Origin, true);
                            IList<double> zaxis = new List<double>();
                            IList<double> refdir = new List<double>();
                            zaxis.Add(0.0);
                            zaxis.Add(0.0);
                            zaxis.Add(UnitUtil.ScaleLength(plFaceNormal.Z));
                            IFCAnyHandle axis = IFCInstanceExporter.CreateDirection(file, zaxis);
                            refdir.Add(UnitUtil.ScaleLength(plFaceNormal.X));
                            refdir.Add(0.0);
                            refdir.Add(0.0);
                            IFCAnyHandle refDirection = IFCInstanceExporter.CreateDirection(file, refdir);
                            IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement3D(file, location, axis, refDirection);
                            surface = IFCInstanceExporter.CreatePlane(file, position);
                        }
                        else if (face is CylindricalFace)
                        {
                            CylindricalFace cylFace = face as CylindricalFace;
                            // get radius-x and radius-y and the position of the origin
                            XYZ rad = UnitUtil.ScaleLength(cylFace.get_Radius(0));
                            double radius = rad.GetLength();
                            IFCAnyHandle location = XYZtoIfcCartesianPoint(exporterIFC, cylFace.Origin, true);

                            IList<double> zaxis = new List<double>();
                            IList<double> refdir = new List<double>();
                            zaxis.Add(0.0);
                            zaxis.Add(0.0);
                            zaxis.Add(UnitUtil.ScaleLength(cylFace.Axis.Z));
                            IFCAnyHandle axis = IFCInstanceExporter.CreateDirection(file, zaxis);
                            refdir.Add(UnitUtil.ScaleLength(cylFace.Axis.X));
                            refdir.Add(0.0);
                            refdir.Add(0.0);
                            IFCAnyHandle refDirection = IFCInstanceExporter.CreateDirection(file, refdir);
                            IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement3D(file, location, axis, refDirection);
                            surface = IFCInstanceExporter.CreateCylindricalSurface(file, position, radius);
                        }

                        else if (face is RevolvedFace)
                        {
                            RevolvedFace revFace = face as RevolvedFace;
                            IFCAnyHandle sweptCurve;

                            IList<double> zaxis = new List<double>();
                            IList<double> refdir = new List<double>();
                            zaxis.Add(0.0);
                            zaxis.Add(0.0);
                            zaxis.Add(UnitUtil.ScaleLength(revFace.Axis.Z));
                            IFCAnyHandle axis = IFCInstanceExporter.CreateDirection(file, zaxis);

                            refdir.Add(UnitUtil.ScaleLength(revFace.Axis.X));
                            refdir.Add(0.0);
                            refdir.Add(0.0);

                            IFCAnyHandle location = XYZtoIfcCartesianPoint(exporterIFC, revFace.Origin, true);

                            Curve curve = revFace.Curve;
                            // If the base curve is an Arc
                            if (curve is Arc)
                            {
                                Arc curveArc = curve as Arc;

                                IFCAnyHandle curveLoc = XYZtoIfcCartesianPoint2D(exporterIFC, curveArc.Center, true);
                                IList<double> direction = new List<double>();
                                direction.Add(UnitUtil.ScaleLength(curveArc.XDirection.X));
                                direction.Add(UnitUtil.ScaleLength(curveArc.YDirection.Y));
                                IFCAnyHandle dir = IFCInstanceExporter.CreateDirection(file, direction);
                                IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement2D(file, curveLoc, null, dir);
                                IFCAnyHandle circle = IFCInstanceExporter.CreateCircle(file, position, UnitUtil.ScaleLength(curveArc.Radius));
                                bool unbounded = false;
                                IFCAnyHandle edgeStart = null;
                                IFCAnyHandle edgeEnd = null;
                                if (curve.IsBound)
                                {
                                    edgeStart = XYZtoIfcCartesianPoint(exporterIFC, curveArc.GetEndPoint(0), true);
                                    edgeEnd = XYZtoIfcCartesianPoint(exporterIFC, curveArc.GetEndPoint(1), true);
                                    if (curveArc.GetEndPoint(0).IsAlmostEqualTo(curveArc.GetEndPoint(1)))
                                        unbounded = true;
                                }
                                else
                                {
                                    unbounded = true;
                                }

                                IFCAnyHandle ifcCurve;
                                string name = "ArcCurveBaseProfile";
                                if (unbounded)
                                    sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, circle);
                                else
                                {
                                    IFCData trim1data = IFCData.CreateIFCAnyHandle(edgeStart);
                                    HashSet<IFCData> trim1 = new HashSet<IFCData>();
                                    trim1.Add(trim1data);
                                    IFCData trim2data = IFCData.CreateIFCAnyHandle(edgeEnd);
                                    HashSet<IFCData> trim2 = new HashSet<IFCData>();
                                    trim2.Add(trim2data);
                                    bool senseAgreement = true;
                                    ifcCurve = IFCInstanceExporter.CreateTrimmedCurve(file, circle, trim1, trim2, senseAgreement, IFCTrimmingPreference.Cartesian);
                                    sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, ifcCurve);
                                }

                            }
                            // If the base curve is an Ellipse
                            else if (curve is Ellipse)
                            {
                                Ellipse curveEllipse = curve as Ellipse;

                                IFCAnyHandle curveLoc = XYZtoIfcCartesianPoint2D(exporterIFC, curveEllipse.Center, true);
                                IList<double> direction = new List<double>();
                                direction.Add(UnitUtil.ScaleLength(curveEllipse.XDirection.X));
                                direction.Add(UnitUtil.ScaleLength(curveEllipse.YDirection.Y));
                                IFCAnyHandle dir = IFCInstanceExporter.CreateDirection(file, direction);
                                IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement2D(file, curveLoc, null, dir);
                                IFCAnyHandle ellipse = IFCInstanceExporter.CreateEllipse(file, position, UnitUtil.ScaleLength(curveEllipse.RadiusX), UnitUtil.ScaleLength(curveEllipse.RadiusY));
                                bool unbounded = false;
                                IFCAnyHandle edgeStart = null;
                                IFCAnyHandle edgeEnd = null;
                                try
                                {
                                    edgeStart = XYZtoIfcCartesianPoint(exporterIFC, curveEllipse.GetEndPoint(0), true);
                                    edgeEnd = XYZtoIfcCartesianPoint(exporterIFC, curveEllipse.GetEndPoint(1), true);
                                    if (curveEllipse.GetEndPoint(0).IsAlmostEqualTo(curveEllipse.GetEndPoint(1)))
                                        unbounded = true;
                                }
                                catch (Exception e)
                                {
                                    if (e is Autodesk.Revit.Exceptions.ArgumentException)
                                    {
                                        unbounded = true;
                                    }
                                    else
                                        throw new ArgumentException("Edge Vertex");
                                }
                                IFCAnyHandle ifcCurve;
                                string name = "EllipseCurveBaseProfile";
                                if (unbounded)
                                    sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, ellipse);
                                else
                                {
                                    IFCData trim1data = IFCData.CreateIFCAnyHandle(edgeStart);
                                    HashSet<IFCData> trim1 = new HashSet<IFCData>();
                                    trim1.Add(trim1data);
                                    IFCData trim2data = IFCData.CreateIFCAnyHandle(edgeEnd);
                                    HashSet<IFCData> trim2 = new HashSet<IFCData>();
                                    trim2.Add(trim2data);
                                    bool senseAgreement = true;
                                    ifcCurve = IFCInstanceExporter.CreateTrimmedCurve(file, ellipse, trim1, trim2, senseAgreement, IFCTrimmingPreference.Cartesian);
                                    sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, ifcCurve);
                                }
                            }
                            // Any other type will be tessellated and is approximated using Polyline
                            else
                            {
                                IList<XYZ> tessCurve = curve.Tessellate();
                                IList<IFCAnyHandle> polylineVertices = new List<IFCAnyHandle>();
                                foreach (XYZ vertex in tessCurve)
                                {
                                    IFCAnyHandle ifcVert = XYZtoIfcCartesianPoint(exporterIFC, vertex, true);
                                    polylineVertices.Add(ifcVert);
                                }
                                string name = "TeseellatedBaseCurveProfile";
                                IFCAnyHandle polyLine = IFCInstanceExporter.CreatePolyline(file, polylineVertices);
                                sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, polyLine);
                            }

                            IFCAnyHandle axisPosition = IFCInstanceExporter.CreateAxis1Placement(file, location, axis);
                            surface = IFCInstanceExporter.CreateSurfaceOfRevolution(file, sweptCurve, null, axisPosition);
                        }
                        else if (face is ConicalFace)
                        {
                            ConicalFace conFace = face as ConicalFace;
                            return null;        // currently does not support this type of face
                        }
                        else if (face is RuledFace)
                        {
                            RuledFace ruledFace = face as RuledFace;
                            return null;        // currently does not support this type of face
                        }
                        else if (face is HermiteFace)
                        {
                            HermiteFace hermFace = face as HermiteFace;
                            return null;        // currently does not support this type of face
                        }

                        // create advancedFace
                        bool sameSenseAF = true; // temp
                        foreach (HashSet<IFCAnyHandle> theFaceBounds in boundsCollection)
                        {
                            IFCAnyHandle advancedFace = IFCInstanceExporter.CreateAdvancedFace(file, theFaceBounds, surface, sameSenseAF);
                            cfsFaces.Add(advancedFace);
                        }
                    }
                    // create advancedBrep
                    IFCAnyHandle closedShell = IFCInstanceExporter.CreateClosedShell(file, cfsFaces);
                    advancedBrep = IFCInstanceExporter.CreateAdvancedBrep(file, closedShell);
                }
                return advancedBrep;
            }
            catch
            {
                return null;
            }
        }
 private static bool IsLoopValid(//double minOpeningValue,
     Face f, XYZ faceNormal,
     XYZ loopNormal, double loopArea)
 {
   return loopArea < f.Area &&
       //loopArea < (minOpeningValue) &&
       (loopNormal.IsAlmostEqualTo(faceNormal)
       || loopNormal.Negate().IsAlmostEqualTo(faceNormal));
 }
        /// <summary>
        /// Checks if two vectors are orthogonal or not.
        /// </summary>
        /// <param name="a">The one vector.</param>
        /// <param name="b">The other vector.</param>
        /// <returns>True if they are orthogonal, false if not.</returns>
        public static bool VectorsAreOrthogonal(XYZ a, XYZ b)
        {
            if (a == null || b == null)
                return false;

            if (a.IsAlmostEqualTo(XYZ.Zero) || b.IsAlmostEqualTo(XYZ.Zero))
                return true;

            double ab = a.DotProduct(b);
            double aa = a.DotProduct(a);
            double bb = b.DotProduct(b);

            return (ab * ab < aa * AngleEps() * bb * AngleEps()) ? true : false;
        }