Example #1
0
        /// <summary>
        /// Gets the first or last riser curve of the run.
        /// </summary>
        /// <param name="last">True to get the last curve, false to get the first.</param>
        /// <returns>The curve.</returns>
        private Curve GetEndCurve(bool last)
        {
            if (m_stairsRun == null)
            {
                throw new NotSupportedException("Stairs run hasn't been constructed yet.");
            }

            // Obtain the footprint boundary of the run.
            CurveLoop boundary = m_stairsRun.GetFootprintBoundary();

            // Find the first or last point on the path
            CurveLoop path      = m_stairsRun.GetStairsPath();
            Curve     pathCurve = path.First <Curve>();
            XYZ       pathPoint = pathCurve.GetEndPoint(last ? 1 : 0);

            // Walk the footprint boundary, and look for a curve whose projection of the target point is equal to the point.
            foreach (Curve boundaryCurve in boundary)
            {
                if (boundaryCurve.Project(pathPoint).XYZPoint.IsAlmostEqualTo(pathPoint))
                {
                    return(boundaryCurve);
                }
            }

            throw new Exception("Unable to find an intersecting boundary curve in the run.");
        }
Example #2
0
        /// <summary>
        /// Gets the first or last riser curve of the run.
        /// </summary>
        /// <param name="last">True to get the last curve, false to get the first.</param>
        /// <returns>The curve.</returns>
        private Curve GetEndCurve(bool last)
        {
            if (m_stairsRun == null)
            {
                throw new NotSupportedException("Stairs run hasn't been constructed yet.");
            }

            // Obtain the footprint boundary
            CurveLoop boundary = m_stairsRun.GetFootprintBoundary();

            // Obtain the endpoint of the stairs path matching the desired end,
            // and find out which curve contains this point.
            CurveLoop path      = m_stairsRun.GetStairsPath();
            Curve     pathCurve = path.First <Curve>();
            XYZ       pathPoint = pathCurve.GetEndPoint(last ? 1 : 0);

            foreach (Curve boundaryCurve in boundary)
            {
                if (boundaryCurve.Project(pathPoint).XYZPoint.IsAlmostEqualTo(pathPoint))
                {
                    return(boundaryCurve);
                }
            }

            throw new Exception("Unable to find an intersecting boundary curve in the run.");
        }
Example #3
0
        /// <summary>
        /// Attempt to create a single curve from a curve loop composed of linear segments.
        /// </summary>
        /// <param name="curveLoop">The curve loop.</param>
        /// <param name="pointXYZs">The original points from which the curve loop was created.</param>
        /// <returns>The curve, if the curve loop is linear, or null.</returns>
        /// <remarks>Note that the routine does not actually check that the curveLoop is composed
        /// of line segments, or that the point array matches the curve loop in any way.</remarks>
        public static Curve CreateCurveFromPolyCurveLoop(CurveLoop curveLoop, IList <XYZ> pointXYZs)
        {
            if (curveLoop == null)
            {
                return(null);
            }

            int numCurves = curveLoop.NumberOfCurves();

            if (numCurves == 0)
            {
                return(null);
            }

            if (numCurves == 1)
            {
                Curve originalCurve = curveLoop.First();
                if (originalCurve != null)
                {
                    return(originalCurve.Clone());
                }
                return(null);
            }

            if (pointXYZs == null)
            {
                return(null);
            }
            int numPoints = pointXYZs.Count;

            // If we are here, we are sure that the number of points must be at least 3.
            XYZ firstPoint   = pointXYZs[0];
            XYZ secondPoint  = pointXYZs[1];
            XYZ vectorToTest = (secondPoint - firstPoint).Normalize();

            bool allAreCollinear = true;

            for (int ii = 2; ii < numPoints; ii++)
            {
                XYZ vectorTmp = (pointXYZs[ii] - firstPoint).Normalize();
                if (!vectorTmp.IsAlmostEqualTo(vectorToTest))
                {
                    allAreCollinear = false;
                    break;
                }
            }

            if (allAreCollinear)
            {
                return(Line.CreateBound(firstPoint, pointXYZs[numPoints - 1]));
            }

            return(null);
        }
Example #4
0
        public static LinearRing ToNtsLinearRing(this CurveLoop _cl)
        {
            var coords = new List <Coordinate>();

            foreach (var c in _cl)
            {
                var co = c.GetEndPoint(0).ToNtsCoord();
                coords.Add(co);
            }
            coords.Add(_cl.First().GetEndPoint(0).ToNtsCoord());
            var lr = new LinearRing(coords.ToArray());

            return(gpr.Reduce(lr) as LinearRing);
        }
Example #5
0
        /// <summary>
        /// Returns the surface which defines the internal shape of the face
        /// </summary>
        /// <param name="lcs">The local coordinate system for the surface.  Can be null.</param>
        /// <returns>The surface which defines the internal shape of the face</returns>
        public override Surface GetSurface(Transform lcs)
        {
            if (SweptCurve == null)
            {
                Importer.TheLog.LogError(Id, "Cannot find the profile curve of this revolved face.", true);
            }

            IFCSimpleProfile simpleProfile = SweptCurve as IFCSimpleProfile;

            if (simpleProfile == null)
            {
                Importer.TheLog.LogError(Id, "Can't handle profile curve of type " + SweptCurve.GetType() + ".", true);
            }

            CurveLoop outerCurve   = simpleProfile.OuterCurve;
            Curve     profileCurve = (outerCurve != null) ? outerCurve.First <Curve>() : null;

            if (profileCurve == null)
            {
                Importer.TheLog.LogError(Id, "Cannot create the profile curve of this revolved surface.", true);
            }

            if (outerCurve.Count() > 1)
            {
                Importer.TheLog.LogError(Id, "Revolved surface has multiple profile curves, ignoring all but first.", false);
            }

            Curve revolvedSurfaceProfileCurve = profileCurve.CreateTransformed(Position);

            if (!RevolvedSurface.IsValidProfileCurve(AxisPosition.Origin, AxisPosition.BasisZ, revolvedSurfaceProfileCurve))
            {
                Importer.TheLog.LogError(Id, "Profile curve is invalid for this revolved surface.", true);
            }

            if (lcs == null)
            {
                return(RevolvedSurface.Create(AxisPosition.Origin, AxisPosition.BasisZ, revolvedSurfaceProfileCurve));
            }

            Curve transformedRevolvedSurfaceProfileCurve = revolvedSurfaceProfileCurve.CreateTransformed(lcs);

            return(RevolvedSurface.Create(lcs.OfPoint(AxisPosition.Origin), lcs.OfVector(AxisPosition.BasisZ), transformedRevolvedSurfaceProfileCurve));
        }
        /// <summary>
        /// Get the local surface transform at a given point on the surface.
        /// </summary>
        /// <param name="pointOnSurface">The point.</param>
        /// <returns>The transform.</returns>
        /// <remarks>This does not include the translation component.</remarks>
        public override Transform GetTransformAtPoint(XYZ pointOnSurface)
        {
            if (!(SweptCurve is IFCSimpleProfile))
            {
                // LOG: ERROR: warn that we only support simple profiles.
                return(null);
            }

            CurveLoop outerCurveLoop = (SweptCurve as IFCSimpleProfile).OuterCurve;

            if (outerCurveLoop == null || outerCurveLoop.Count() != 1)
            {
                // LOG: ERROR
                return(null);
            }

            Curve outerCurve = outerCurveLoop.First();

            if (outerCurve == null)
            {
                // LOG: ERROR
                return(null);
            }

            IntersectionResult result = outerCurve.Project(pointOnSurface);

            if (result == null)
            {
                // LOG: ERROR
                return(null);
            }

            double parameter = result.Parameter;

            Transform atPoint = outerCurve.ComputeDerivatives(parameter, false);

            atPoint.set_Basis(0, atPoint.BasisX.Normalize());
            atPoint.set_Basis(1, atPoint.BasisY.Normalize());
            atPoint.set_Basis(2, atPoint.BasisZ.Normalize());
            atPoint.Origin = pointOnSurface;

            return(atPoint);
        }
        /// <summary>
        /// Get the curve from the Axis representation of the given IfcProduct, transformed to the current local coordinate system.
        /// </summary>
        /// <param name="creator">The IfcProduct that may or may not contain a valid axis curve.</param>
        /// <param name="lcs">The local coordinate system.</param>
        /// <returns>The axis curve, if found, and valid.</returns>
        /// <remarks>In this case, we only allow bounded lines and arcs to be valid axis curves, as per IFC2x3 convention.
        /// The Curve may be contained as either a single Curve in the IFCCurve representation item, or it could be an
        /// open CurveLoop with one item.</remarks>
        private Curve GetAxisCurve(IFCProduct creator, Transform lcs)
        {
            // We need an axis curve to clip the extrusion profiles; if we can't get one, fail
            IFCProductRepresentation productRepresentation = creator.ProductRepresentation;

            if (productRepresentation == null)
            {
                return(null);
            }

            IList <IFCRepresentation> representations = productRepresentation.Representations;

            if (representations == null)
            {
                return(null);
            }

            foreach (IFCRepresentation representation in representations)
            {
                // Go through the list of representations for this product, to find the Axis representation.
                if (representation == null || representation.Identifier != IFCRepresentationIdentifier.Axis)
                {
                    continue;
                }

                IList <IFCRepresentationItem> items = representation.RepresentationItems;
                if (items == null)
                {
                    continue;
                }

                // Go through the list of representation items in the Axis representation, to look for the IfcCurve.
                foreach (IFCRepresentationItem item in items)
                {
                    if (item is IFCCurve)
                    {
                        // We will accept either a bounded Curve of type Line or Arc,
                        // or an open CurveLoop with one curve that satisfies the same condition.
                        IFCCurve ifcCurve  = item as IFCCurve;
                        Curve    axisCurve = ifcCurve.Curve;
                        if (axisCurve == null)
                        {
                            CurveLoop axisCurveLoop = ifcCurve.CurveLoop;
                            if (axisCurveLoop != null && axisCurveLoop.IsOpen() && axisCurveLoop.Count() == 1)
                            {
                                axisCurve = axisCurveLoop.First();
                                if (!(axisCurve is Line || axisCurve is Arc))
                                {
                                    axisCurve = null;
                                }
                            }
                        }

                        if (axisCurve != null)
                        {
                            return(axisCurve.CreateTransformed(lcs));
                        }
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="unscaledLcs">The unscaled local coordinate system for the geometry, if the scaled version isn't supported downstream.</param>
        /// <param name="scaledLcs">The scaled (true) local coordinate system for the geometry.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>The created geometry.</returns>
        protected override IList <GeometryObject> CreateGeometryInternal(
            IFCImportShapeEditScope shapeEditScope, Transform unscaledLcs, Transform scaledLcs, string guid)
        {
            Transform unscaledObjectPosition = (unscaledLcs == null) ? Position : unscaledLcs.Multiply(Position);
            Transform scaledObjectPosition   = (scaledLcs == null) ? Position : scaledLcs.Multiply(Position);

            CurveLoop baseProfileCurve = Directrix.GetCurveLoop();

            if (baseProfileCurve == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(Id, baseProfileCurve, StartParameter, EndParameter);

            if (trimmedDirectrix == null)
            {
                return(null);
            }

            double    startParam  = 0.0; // If the directrix isn't bound, this arbitrary parameter will do.
            Transform originTrf0  = null;
            Curve     firstCurve0 = trimmedDirectrix.First();

            if (firstCurve0.IsBound)
            {
                startParam = firstCurve0.GetEndParameter(0);
            }
            originTrf0 = firstCurve0.ComputeDerivatives(startParam, false);
            if (originTrf0 == null)
            {
                return(null);
            }

            // Note: the computation of the reference Surface Local Transform must be done before the directrix is transform to LCS (because the ref surface isn't)
            //     and therefore the origin is at the start of the curve should be the start of the directrix that lies on the surface.
            //     This is needed to transform the swept area that must be perpendicular to the start of the directrix curve

            Transform referenceSurfaceLocalTransform = ReferenceSurface.GetTransformAtPoint(originTrf0.Origin);

            CurveLoop trimmedDirectrixInLCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, Id, unscaledObjectPosition, scaledObjectPosition);

            // Create the sweep.
            Transform originTrf  = null;
            Curve     firstCurve = trimmedDirectrixInLCS.First();

            //if (firstCurve.IsBound)
            //    startParam = firstCurve.GetEndParameter(0);
            originTrf = firstCurve.ComputeDerivatives(startParam, false);

            Transform unscaledReferenceSurfaceTransform = unscaledObjectPosition.Multiply(referenceSurfaceLocalTransform);
            Transform scaledReferenceSurfaceTransform   = scaledObjectPosition.Multiply(referenceSurfaceLocalTransform);

            Transform profileCurveLoopsTransform = Transform.CreateTranslation(originTrf.Origin);

            profileCurveLoopsTransform.BasisX = scaledReferenceSurfaceTransform.BasisZ;
            profileCurveLoopsTransform.BasisZ = originTrf.BasisX.Normalize();
            profileCurveLoopsTransform.BasisY = profileCurveLoopsTransform.BasisZ.CrossProduct(profileCurveLoopsTransform.BasisX);

            ISet <IList <CurveLoop> > profileCurveLoops = GetTransformedCurveLoops(profileCurveLoopsTransform, profileCurveLoopsTransform);

            if (profileCurveLoops == null || profileCurveLoops.Count == 0)
            {
                return(null);
            }

            SolidOptions           solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
            IList <GeometryObject> myObjs       = new List <GeometryObject>();

            foreach (IList <CurveLoop> loops in profileCurveLoops)
            {
                GeometryObject myObj = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, loops, solidOptions);
                if (myObj != null)
                {
                    myObjs.Add(myObj);
                }
            }

            return(myObjs);
        }
Example #9
0
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The geometry creation scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>The created geometry.</returns>
        protected override IList <GeometryObject> CreateGeometryInternal(
            IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            Transform objectPosition = (lcs == null) ? Position : lcs.Multiply(Position);

            CurveLoop baseProfileCurve = Directrix.GetCurveLoop();

            if (baseProfileCurve == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrix = IFCGeometryUtil.TrimCurveLoop(baseProfileCurve, StartParameter, EndParameter);

            if (trimmedDirectrix == null)
            {
                return(null);
            }

            CurveLoop trimmedDirectrixInLCS = IFCGeometryUtil.CreateTransformed(trimmedDirectrix, objectPosition);

            // Create the sweep.
            double    startParam = 0.0; // If the directrix isn't bound, this arbitrary parameter will do.
            Transform originTrf  = null;
            Curve     firstCurve = trimmedDirectrixInLCS.First();

            if (firstCurve.IsBound)
            {
                startParam = firstCurve.GetEndParameter(0);
            }
            originTrf = firstCurve.ComputeDerivatives(startParam, false);

            if (originTrf == null)
            {
                return(null);
            }

            Transform referenceSurfaceLocalTransform = ReferenceSurface.GetTransformAtPoint(originTrf.Origin);
            Transform referenceSurfaceTransform      = objectPosition.Multiply(referenceSurfaceLocalTransform);

            Transform profileCurveLoopsTransform = Transform.CreateTranslation(originTrf.Origin);

            profileCurveLoopsTransform.BasisX = referenceSurfaceTransform.BasisZ;
            profileCurveLoopsTransform.BasisZ = originTrf.BasisX.Normalize();
            profileCurveLoopsTransform.BasisY = profileCurveLoopsTransform.BasisZ.CrossProduct(profileCurveLoopsTransform.BasisX);

            ISet <IList <CurveLoop> > profileCurveLoops = GetTransformedCurveLoops(profileCurveLoopsTransform);

            if (profileCurveLoops == null || profileCurveLoops.Count == 0)
            {
                return(null);
            }

            SolidOptions           solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
            IList <GeometryObject> myObjs       = new List <GeometryObject>();

            foreach (IList <CurveLoop> loops in profileCurveLoops)
            {
                GeometryObject myObj = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, loops, solidOptions);
                if (myObj != null)
                {
                    myObjs.Add(myObj);
                }
            }

            return(myObjs);
        }
        /// <returns>true if the curve loop is clockwise, false otherwise.</returns>
        private static bool SafeIsCurveLoopClockwise(CurveLoop curveLoop, XYZ dir)
        {
            if (curveLoop == null)
                return false;

            if (curveLoop.IsOpen())
                return false;

            if ((curveLoop.Count() == 1) && !(curveLoop.First().IsBound))
                return false;

            return !curveLoop.IsCounterclockwise(dir);
        }
        void SubDivideSoffits_CreateFireRatedLayers(Document doc)
        {
            try
            {
                #region Get Soffits
                List <Element> Soffits = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).ToElements().Where(m => !(m is ElementType)).ToList();

                #endregion

                //Subdivide
                foreach (Element Soffit in Soffits.Where(m => m.Name.ToLower().Contains("eave")))
                {
                    #region Get Soffit Geometry
                    Options ops = new Options();
                    ops.DetailLevel = ViewDetailLevel.Fine;
                    ops.IncludeNonVisibleObjects = true;
                    GeometryElement Geo = Soffit.get_Geometry(ops);

                    #endregion

                    foreach (var item in Geo)
                    {
                        if (item is Solid)
                        {
                            #region Get one of the Main Faces, it doesn't really matter if it is top or bottom
                            Solid       GSol = item as Solid;
                            List <Face> Fs   = new List <Face>();
                            foreach (Face f in GSol.Faces)
                            {
                                Fs.Add(f);
                            }
                            Face F = Fs.Where(m => m.Area == Fs.Max(a => a.Area)).First();
                            #endregion

                            #region Triangulate the Face with max detail
                            Mesh M = F.Triangulate(1);
                            #endregion

                            #region Create Variables for: the curves that will define the new Soffits, List of Custom Triangle Class, List of Custom Pair of Triangle Class
                            List <List <Curve> > LLC       = new List <List <Curve> >();
                            List <Triangle>      Triangles = new List <Triangle>();
                            List <TrianglePair>  TPairs    = new List <TrianglePair>();

                            #endregion

                            #region Loop Through Triangles & Add Them to the list of My Triangle Class
                            for (int i = 0; i < M.NumTriangles; i++)
                            {
                                List <Curve> LC = new List <Curve>();

                                #region Make List of Curves From Triangle
                                MeshTriangle MT     = M.get_Triangle(i);
                                List <Curve> Curves = new List <Curve>();
                                Curve        C      = Line.CreateBound(MT.get_Vertex(0), MT.get_Vertex(1)) as Curve;
                                Curves.Add(C);
                                C = Line.CreateBound(MT.get_Vertex(1), MT.get_Vertex(2)) as Curve;
                                Curves.Add(C);
                                C = Line.CreateBound(MT.get_Vertex(2), MT.get_Vertex(0)) as Curve;
                                Curves.Add(C);
                                #endregion

                                Triangle T = new Triangle();
                                T.Sides = new List <Curve>();
                                T.Sides = Curves;

                                T.Vertices = new List <XYZ>();
                                T.Vertices.Add(MT.get_Vertex(0));
                                T.Vertices.Add(MT.get_Vertex(1));
                                T.Vertices.Add(MT.get_Vertex(2));
                                Triangles.Add(T);
                            }
                            #endregion

                            #region Loop Through Triangles And Create Trapezoid Pairs To Catch The Segments, Getting Rid of The Shared sides
                            bool GO = true;
                            do
                            {
                                Triangle TKeeper1 = new Triangle();
                                Triangle TKeeper2 = new Triangle();

                                foreach (Triangle T in Triangles)
                                {
                                    TKeeper1 = new Triangle();
                                    foreach (Triangle T2 in Triangles)
                                    {
                                        TKeeper2 = new Triangle();
                                        if (T != T2)
                                        {
                                            if (FindCurvesFacing(T, T2) != null)
                                            {
                                                if (FindCurvesFacing(T, T2)[0].Length == T.Sides.Min(c => c.Length) ||
                                                    FindCurvesFacing(T, T2)[1].Length == T2.Sides.Min(c => c.Length))
                                                {
                                                    continue;
                                                }
                                                Curve[] Cs = FindCurvesFacing(T, T2);
                                                T.Sides.Remove(Cs[0]);
                                                T2.Sides.Remove(Cs[1]);
                                                if (T.Sides.Count() == 2 && T2.Sides.Count() == 2)
                                                {
                                                    TKeeper1 = T;
                                                    TKeeper2 = T2;
                                                    goto ADDANDGOROUND;
                                                }
                                            }
                                        }
                                    }
                                }
                                GO = false;
ADDANDGOROUND:
                                if (GO)
                                {
                                    Triangles.Remove(TKeeper1);
                                    Triangles.Remove(TKeeper2);
                                    TrianglePair TP = new TrianglePair();
                                    TP.T1 = TKeeper1;
                                    TP.T2 = TKeeper2;
                                    TPairs.Add(TP);
                                }
                            } while(GO);

                            #endregion

                            #region Create Curve Loops From Triangle Pairs
                            foreach (TrianglePair TPair in TPairs)
                            {
                                List <Curve> Cs = new List <Curve>();

                                Cs.AddRange(TPair.T1.Sides);
                                Cs.AddRange(TPair.T2.Sides);

                                LLC.Add(Cs);
                            }
                            #endregion

                            double    Offset = Convert.ToDouble(Soffit.LookupParameter("Height Offset From Level").AsValueString());
                            FloorType FT     = (Soffit as Floor).FloorType;
                            Level     Lvl    = doc.GetElement((Soffit as Floor).LevelId) as Level;

                            #region Delete Old Soffit If All Went Well
                            using (Transaction T = new Transaction(doc, "Delete Soffit"))
                            {
                                T.Start();
                                doc.Delete(Soffit.Id);
                                T.Commit();
                            }
                            #endregion

                            #region Sort The Lists of Curves and Create The New Segments
                            foreach (List <Curve> LC in LLC)
                            {
                                List <Curve> LCSorted = new List <Curve>();
                                try
                                {
                                    LCSorted = SortCurvesContiguous(LC, false);
                                }

                                #region Exception Details if Curves Could not be sorted
                                catch (Exception EXC)
                                {
                                    string exmsge = EXC.Message;
                                }

                                #endregion

                                CurveArray CA = new CurveArray();
                                foreach (Curve C in LCSorted)
                                {
                                    CA.Append(C);
                                }

                                using (Transaction T = new Transaction(doc, "Make Segment"))
                                {
                                    T.Start();
                                    Floor newFloor = doc.Create.NewFloor(CA, FT, Lvl, false);
                                    newFloor.LookupParameter("Height Offset From Level").SetValueString(Offset.ToString());
                                    T.Commit();
                                }
                            }
                            #endregion
                        }
                    }
                }
                //refresh collection
                Soffits = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).ToElements().Where(m => !(m is ElementType)).ToList();
                //test soffits for needing fire rating
                foreach (Element Soffit in Soffits.Where(m => m.Name.ToLower().Contains("eave")))
                {
                    #region Get Soffit Geometry
                    Options ops = new Options();
                    ops.DetailLevel = ViewDetailLevel.Fine;
                    ops.IncludeNonVisibleObjects = true;
                    GeometryElement Geo = Soffit.get_Geometry(ops);

                    #endregion

                    foreach (var item in Geo)
                    {
                        if (item is Solid)
                        {
                            #region Find boundary Void Element
                            List <Element> MaybeBoundary  = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).ToElements().Where(m => !(m is ElementType)).ToList();
                            Element        BoundryElement = MaybeBoundary.Where(m => !(m is FloorType) && m.Name == "Boundary").First();

                            #endregion

                            #region Get Intersection of Boundary and eave
                            PolygonAnalyser   com    = new PolygonAnalyser();
                            List <CurveArray> CArray = com.Execute(BoundryElement as Floor, Soffit as Floor);

                            Level L = doc.GetElement(Soffit.LevelId) as Level;

                            #endregion

                            foreach (CurveArray CA in CArray)
                            {
                                #region Sort The Curves
                                IList <Curve> CAL = new List <Curve>();
                                foreach (Curve C in CA)
                                {
                                    CAL.Add(C);
                                }

                                List <Curve> Curves       = SortCurvesContiguous(CAL, false);
                                List <XYZ>   NewCurveEnds = new List <XYZ>();

                                #endregion

                                #region Close the loop if nesesary
                                CurveLoop CL = new CurveLoop();
                                foreach (Curve curv in Curves)
                                {
                                    CL.Append(curv);
                                }
                                if (CL.IsOpen())
                                {
                                    Curves.Add(Line.CreateBound(CL.First().GetEndPoint(0), CL.Last().GetEndPoint(1)) as Curve);
                                }
                                #endregion

                                #region Recreate a Curve Array
                                Curves = SortCurvesContiguous(Curves, false);

                                CurveArray CA2 = new CurveArray();

                                int i = 0;
                                foreach (Curve c in Curves)
                                {
                                    CA2.Insert(c, i);
                                    i += 1;
                                }

                                #endregion

                                #region Create The New Fire Rated Layer element
                                FloorType   ft = new FilteredElementCollector(doc).WhereElementIsElementType().OfCategory(BuiltInCategory.OST_Floors).ToElements().Where(m => m.Name == "Fire Rated Layer").First() as FloorType;
                                Transaction T  = new Transaction(doc, "Fire Rated Layer Creation");
                                try
                                {
                                    T.Start();
                                    Floor  F  = doc.Create.NewFloor(CA2, ft, L, false);
                                    string s  = Soffit.LookupParameter("Height Offset From Level").AsValueString();
                                    double si = Convert.ToDouble(s);
                                    si = si + (Convert.ToDouble(Soffit.LookupParameter("Thickness").AsValueString()));
                                    F.LookupParameter("Height Offset From Level").SetValueString(si.ToString());
                                    T.Commit();
                                }
                                catch (Exception EX)
                                {
                                    T.RollBack();
                                    string EXmsg = EX.Message;
                                }

                                #endregion
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string mesg = ex.Message;
            }
        }
Example #12
0
        /// <summary>
        /// Trims the CurveLoop contained in an IFCCurve by the start and optional end parameter values.
        /// </summary>
        /// <param name="id">The id of the IFC entity containing the directrix, for messaging purposes.</param>
        /// <param name="ifcCurve">The IFCCurve entity containing the CurveLoop to be trimmed.</param>
        /// <param name="startVal">The starting trim parameter.</param>
        /// <param name="origEndVal">The optional end trim parameter.  If not supplied, assume no end trim.</param>
        /// <returns>The original curve loop, if no trimming has been done, otherwise a trimmed copy.</returns>
        private static CurveLoop TrimCurveLoop(int id, IFCCurve ifcCurve, double startVal, double?origEndVal)
        {
            CurveLoop origCurveLoop = ifcCurve.GetTheCurveLoop();

            if (origCurveLoop == null || origCurveLoop.Count() == 0)
            {
                return(null);
            }

            // Trivial case: unbound curve.
            Curve possiblyUnboundCurve = origCurveLoop.First();

            if (!possiblyUnboundCurve.IsBound)
            {
                if (!origEndVal.HasValue)
                {
                    Importer.TheLog.LogError(id, "Can't trim unbound curve with no given end parameter.", true);
                }

                CurveLoop boundCurveLoop = new CurveLoop();
                Curve     boundCurve     = possiblyUnboundCurve.Clone();
                boundCurve.MakeBound(startVal, origEndVal.Value * ifcCurve.ParametericScaling);
                boundCurveLoop.Append(boundCurve);
                return(boundCurveLoop);
            }

            IList <double> curveLengths = new List <double>();
            IList <Curve>  loopCurves   = new List <Curve>();

            double totalParamLength = 0.0;

            bool allLines = true;

            foreach (Curve curve in origCurveLoop)
            {
                if (!(curve is Line))
                {
                    allLines = false;
                }

                double curveLength = curve.GetEndParameter(1) - curve.GetEndParameter(0);
                double currLength  = ScaleCurveLengthForSweptSolid(curve, curveLength);
                loopCurves.Add(curve);
                curveLengths.Add(currLength);
                totalParamLength += currLength;
            }

            double endVal = origEndVal.HasValue ? origEndVal.Value : totalParamLength;
            double eps    = MathUtil.Eps();

            if (!CheckIfTrimParametersAreNeeded(id, ifcCurve, startVal, endVal, totalParamLength))
            {
                return(origCurveLoop);
            }

            // Special cases:
            // if startval = 0 and endval = 1 and we have a polyline, then this likely means that the importing application
            // incorrectly set the extents to be the "whole" curve, when really this is just a portion of the curves
            // (the parametrization is described above).
            // As such, if the totalParamLength is not 1 but startVal = 0 and endVal = 1, we will warn but not trim.
            // This is not a hypothetical case: it occurs in several AllPlan 2017 files at least.
            if (allLines)
            {
                if ((!MathUtil.IsAlmostEqual(totalParamLength, 1.0)) && (MathUtil.IsAlmostZero(startVal) && MathUtil.IsAlmostEqual(endVal, 1.0)))
                {
                    Importer.TheLog.LogWarning(id, "The Start Parameter for the trimming of this curve was set to 0, and the End Parameter was set to 1.  " +
                                               "Most likely, this is an error in the sending application, and the trim extents are being ignored.  " +
                                               "If this trim was intended, please contact Autodesk.", true);
                    return(origCurveLoop);
                }
            }

            int    numCurves       = loopCurves.Count;
            double currentPosition = 0.0;
            int    currCurve       = 0;

            IList <Curve> newLoopCurves = new List <Curve>();

            if (startVal > MathUtil.Eps())
            {
                for (; currCurve < numCurves; currCurve++)
                {
                    if (currentPosition + curveLengths[currCurve] < startVal + eps)
                    {
                        currentPosition += curveLengths[currCurve];
                        continue;
                    }

                    Curve newCurve = loopCurves[currCurve].Clone();
                    if (!MathUtil.IsAlmostEqual(currentPosition, startVal))
                    {
                        double startParam = UnscaleSweptSolidCurveParam(loopCurves[currCurve], startVal - currentPosition);
                        double endParam   = newCurve.GetEndParameter(1);
                        AdjustParamsIfNecessary(newCurve, ref startParam, ref endParam);
                        newCurve.MakeBound(startParam, endParam);
                    }

                    newLoopCurves.Add(newCurve);
                    break;
                }
            }

            if (endVal < totalParamLength - eps)
            {
                for (; currCurve < numCurves; currCurve++)
                {
                    if (currentPosition + curveLengths[currCurve] < endVal - eps)
                    {
                        currentPosition += curveLengths[currCurve];
                        newLoopCurves.Add(loopCurves[currCurve]);
                        continue;
                    }

                    Curve newCurve = loopCurves[currCurve].Clone();
                    if (!MathUtil.IsAlmostEqual(currentPosition + curveLengths[currCurve], endVal))
                    {
                        double startParam = newCurve.GetEndParameter(0);
                        double endParam   = UnscaleSweptSolidCurveParam(loopCurves[currCurve], endVal - currentPosition);
                        AdjustParamsIfNecessary(newCurve, ref startParam, ref endParam);
                        newCurve.MakeBound(startParam, endParam);
                    }

                    newLoopCurves.Add(newCurve);
                    break;
                }
            }

            CurveLoop trimmedCurveLoop = new CurveLoop();

            foreach (Curve curve in newLoopCurves)
            {
                trimmedCurveLoop.Append(curve);
            }
            return(trimmedCurveLoop);
        }