public static Solid CreateSphereAt(XYZ center, double radius)
        {
            Frame frame = new Frame(center,
                                    XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ);

            // Create a vertical half-circle loop;
            // this must be in the frame location.

            Arc arc = Arc.Create(
                center - radius * XYZ.BasisZ,
                center + radius * XYZ.BasisZ,
                center + radius * XYZ.BasisX);

            Line line = Line.CreateBound(
                arc.GetEndPoint(1),
                arc.GetEndPoint(0));

            CurveLoop halfCircle = new CurveLoop();

            halfCircle.Append(arc);
            halfCircle.Append(line);

            List <CurveLoop> loops = new List <CurveLoop>(1);

            loops.Add(halfCircle);

            return(GeometryCreationUtilities
                   .CreateRevolvedGeometry(
                       frame, loops, 0, 2 * Math.PI));
        }
            // Here's a snippet.
            // It was uploaded to the preview release:
            // https://feedback.autodesk.com/project/forum/thread.html?cap=cb0fd5af18bb49b791dfa3f5efc[…]01b3deb82a76}&topid={9C3D609F-0A86-4766-BB12-6315F49BCF03}

            /*
             * Sample - Edit Floor Sketch.cs
             * Created by SharpDevelop.
             * User: t_matva
             * Date: 11/17/2020
             * Time: 11:18 AM
             *
             * To change this template use Tools | Options | Coding | Edit Standard Headers.
             */
            //using System;
            //using Autodesk.Revit.UI;
            //using Autodesk.Revit.DB;
            //using Autodesk.Revit.UI.Selection;
            //using System.Collections.Generic;
            //using System.Linq;
            //​
            //namespace Sample
            //{
            //    [Autodesk.Revit.Attributes.Transaction( Autodesk.Revit.Attributes.TransactionMode.Manual )]
            //    [Autodesk.Revit.DB.Macros.AddInId( "994A64E6-839B-4C1F-B473-1E7C614A5455" )]
            //    public partial class ThisDocument
            //    {
            //      private void Module_Startup( object sender, EventArgs e )
            //      {
            //      }
            //​
            //      private void Module_Shutdown( object sender, EventArgs e )
            //      {
            //      }
            //​
            //      #region Revit Macros generated code
            //      private void InternalStartup()
            //      {
            //        this.Startup += new System.EventHandler( Module_Startup );
            //        this.Shutdown += new System.EventHandler( Module_Shutdown );
            //      }
            //      #endregion

            public void CreateFloor(Document doc)
            {
                Curve left  = Line.CreateBound(new XYZ(0, 0, 0), new XYZ(0, 100, 0));
                Curve upper = Line.CreateBound(new XYZ(0, 100, 0), new XYZ(100, 100, 0));
                Curve right = Line.CreateBound(new XYZ(100, 100, 0), new XYZ(100, 0, 0));
                Curve lower = Line.CreateBound(new XYZ(100, 0, 0), new XYZ(0, 0, 0));

                CurveLoop floorProfile = new CurveLoop();

                floorProfile.Append(left);
                floorProfile.Append(upper);
                floorProfile.Append(right);
                floorProfile.Append(lower);

                ElementId levelId = Level.GetNearestLevelId(doc, 0.0);

                using (Transaction transaction = new Transaction(doc))
                {
                    transaction.Start("Create floor");
                    ElementId floorTypeId = Floor.GetDefaultFloorType(doc, false);
                    Floor     floor       = Floor.Create(doc,
                                                         new List <CurveLoop>()
                    {
                        floorProfile
                    },
                                                         floorTypeId, levelId);
                    transaction.Commit();
                }
            }
Beispiel #3
0
        /// <summary>
        /// Create a centerbased cylinder, only on X, Y, Z three axes forward direction
        /// </summary>
        /// <param name="center">The given cylinder center</param>
        /// <param name="bottomradius">The given cylinder's bottom radius</param>
        /// <param name="height">The given cylinder's height</param>
        /// <param name="cylinderdirection">Cylinder's extrusion direction</param>
        /// <returns>The created cylinder</returns>
        public Solid CreateCenterbasedCylinder(XYZ center, double bottomradius, double height, CylinderDirection cylinderdirection)
        {
            double halfheight   = height / 2.0;
            XYZ    bottomcenter = new XYZ(
                cylinderdirection == CylinderDirection.BasisX ? center.X - halfheight : center.X,
                cylinderdirection == CylinderDirection.BasisY ? center.Y - halfheight : center.Y,
                cylinderdirection == CylinderDirection.BasisZ ? center.Z - halfheight : center.Z);
            XYZ topcenter = new XYZ(
                cylinderdirection == CylinderDirection.BasisX ? center.X + halfheight : center.X,
                cylinderdirection == CylinderDirection.BasisY ? center.Y + halfheight : center.Y,
                cylinderdirection == CylinderDirection.BasisZ ? center.Z + halfheight : center.Z);

            CurveLoop sweepPath = new CurveLoop();

            sweepPath.Append(Line.CreateBound(bottomcenter,
                                              topcenter));

            List <CurveLoop> profileloops = new List <CurveLoop>();
            CurveLoop        profileloop  = new CurveLoop();
            Ellipse          cemiEllipse1 = Ellipse.Create(bottomcenter, bottomradius, bottomradius,
                                                           cylinderdirection == CylinderDirection.BasisX ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisX,
                                                           cylinderdirection == CylinderDirection.BasisZ ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisZ,
                                                           -Math.PI, 0);
            Ellipse cemiEllipse2 = Ellipse.Create(bottomcenter, bottomradius, bottomradius,
                                                  cylinderdirection == CylinderDirection.BasisX ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisX,
                                                  cylinderdirection == CylinderDirection.BasisZ ? Autodesk.Revit.DB.XYZ.BasisY : Autodesk.Revit.DB.XYZ.BasisZ,
                                                  0, Math.PI);

            profileloop.Append(cemiEllipse1);
            profileloop.Append(cemiEllipse2);
            profileloops.Add(profileloop);

            return(GeometryCreationUtilities.CreateSweptGeometry(sweepPath, 0, 0, profileloops));
        }
        public void solidBeamFinder(Document doc, XYZ startOfInterest, double solidHeight, out List <ElementId> beamIds)
        {
            beamIds = new List <ElementId>();
            double radius = 0.1;

            XYZ arcCenter = new XYZ(startOfInterest.X, startOfInterest.Y, startOfInterest.Z);

            //Build a solid cylinder
            // Create a vertical half-circle loop in the frame location.
            List <CurveLoop> curveloops = new List <CurveLoop>();
            CurveLoop        circle     = new CurveLoop();

            circle.Append(Arc.Create(arcCenter, radius, 0, Math.PI, XYZ.BasisX, XYZ.BasisY));
            circle.Append(Arc.Create(arcCenter, radius, Math.PI, 2 * Math.PI, XYZ.BasisX, XYZ.BasisY));
            curveloops.Add(circle);

            Solid cylinder = GeometryCreationUtilities.CreateExtrusionGeometry(curveloops, XYZ.BasisZ, (solidHeight));
            //PaintSolid(commandData, cylinder, 5);
            //Find beam
            IEnumerable <Element> beams = new FilteredElementCollector(doc)
                                          .OfClass(typeof(FamilyInstance))
                                          .OfCategory(BuiltInCategory.OST_StructuralFraming)
                                          .WherePasses(new ElementIntersectsSolidFilter(cylinder));

            if (beams.Count() > 0)
            {
                foreach (Element e in beams)
                {
                    beamIds.Add(e.Id);
                }
            }
        }
        /// <summary>
        /// Create and return a solid sphere with
        /// a given radius and centre point.
        /// </summary>
        public static Solid CreateSphereAt(XYZ centre, double radius)
        {
            // Use the standard global coordinate system
            // as a frame, translated to the sphere centre.

            Frame frame = new Frame(centre,
                                    XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ);

            // Create a vertical half-circle loop;
            // this must be in the frame location.

            Arc arc = Arc.Create(
                centre - radius * XYZ.BasisZ,
                centre + radius * XYZ.BasisZ,
                centre + radius * XYZ.BasisX);

            Line line = Line.CreateBound(
                arc.GetEndPoint(1),
                arc.GetEndPoint(0));

            CurveLoop halfCircle = new CurveLoop();

            halfCircle.Append(arc);
            halfCircle.Append(line);

            List <CurveLoop> loops = new List <CurveLoop>(1);

            loops.Add(halfCircle);

            return(GeometryCreationUtilities
                   .CreateRevolvedGeometry(
                       frame, loops, 0, 2 * Math.PI));
        }
Beispiel #6
0
        /// <summary>
        /// Find the nearby walls on specific point and in specific height
        /// </summary>
        /// <param name="point">The given point</param>
        /// <param name="height">The given height</param>
        /// <param name="radius">The radius in which walls can be detected</param>
        /// <returns>The detection result</returns>
        private FilteredElementCollector nearbyWallsFilter(XYZ point, double height, double radius)
        {
            // build cylindrical shape around wall endpoint
            List <CurveLoop> curveloops = new List <CurveLoop>();
            CurveLoop        circle     = new CurveLoop();

            circle.Append(Arc.Create(point, radius
                                     , 0, Math.PI,
                                     XYZ.BasisX, XYZ.BasisY));
            circle.Append(Arc.Create(point, radius
                                     , Math.PI, 2 * Math.PI,
                                     XYZ.BasisX, XYZ.BasisY));
            curveloops.Add(circle);

            Solid wallEndCylinder =
                GeometryCreationUtilities.CreateExtrusionGeometry(curveloops, XYZ.BasisZ, height);

            // Iterate document to find walls
            FilteredElementCollector collector = new FilteredElementCollector(m_doc);

            collector.OfCategory(BuiltInCategory.OST_Walls);

            // Apply geometric filter
            ElementIntersectsSolidFilter testElementIntersectsSolidFilter =
                new ElementIntersectsSolidFilter(wallEndCylinder);

            collector.WherePasses(testElementIntersectsSolidFilter);

            return(collector);
        }
        public static Solid Box( )
        {
            XYZ btmLeft  = new XYZ(-0.5, -0.5, 0);
            XYZ topRight = new XYZ(0.5, 0.5, 0);
            XYZ btmRight = new XYZ(topRight.X, btmLeft.Y, 0);
            XYZ topLeft  = new XYZ(btmLeft.X, topRight.Y, 0);

            Curve btm   = Line.CreateBound(btmLeft, btmRight) as Curve;
            Curve right = Line.CreateBound(btmRight, topRight) as Curve;
            Curve top   = Line.CreateBound(topRight, topLeft) as Curve;
            Curve left  = Line.CreateBound(topLeft, btmLeft) as Curve;

            CurveLoop crvLoop = new CurveLoop();

            crvLoop.Append(btm);
            crvLoop.Append(right);
            crvLoop.Append(top);
            crvLoop.Append(left);

            IList <CurveLoop> cl = new List <CurveLoop>();

            cl.Add(crvLoop);

            Solid box = GeometryCreationUtilities.CreateExtrusionGeometry(cl, XYZ.BasisZ, 1);

            return(box);
        }
        public static Solid Sphere()
        {
            XYZ    center = new XYZ(0, 0, 0.5);
            double radius = 0.75;
            // Use the standard global coordinate system
            // as a frame, translated to the sphere bottom.
            Frame frame = new Frame(center, XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ);

            // Create a vertical half-circle loop;
            // this must be in the frame location.
            XYZ start    = center - radius * XYZ.BasisZ;
            XYZ end      = center + radius * XYZ.BasisZ;
            XYZ XyzOnArc = center + radius * XYZ.BasisX;

            Arc arc = Arc.Create(start, end, XyzOnArc);

            Line line = Line.CreateBound(arc.GetEndPoint(1), arc.GetEndPoint(0));

            CurveLoop halfCircle = new CurveLoop();

            halfCircle.Append(arc);
            halfCircle.Append(line);

            List <CurveLoop> loops = new List <CurveLoop>(1);

            loops.Add(halfCircle);

            return(GeometryCreationUtilities.CreateRevolvedGeometry(frame, loops, 0, 2 * Math.PI));
        }
        /// <summary>
        /// Creates an Analytiocal Panel
        /// </summary>
        /// <param name="revitDoc">Revit documenr</param>
        /// <returns></returns>
        public static AnalyticalPanel CreateAMPanel(Document revitDoc)
        {
            AnalyticalPanel analyticalPanel = null;

            using (Transaction transaction = new Transaction(revitDoc, "Create Analytical Panel"))
            {
                transaction.Start();

                //create curveloop which will be assigned to the analytical panel
                CurveLoop profileloop = new CurveLoop();
                profileloop.Append(Line.CreateBound(
                                       new XYZ(0, 0, 0), new XYZ(5, 0, 0)));
                profileloop.Append(Line.CreateBound(
                                       new XYZ(5, 0, 0), new XYZ(5, 5, 0)));
                profileloop.Append(Line.CreateBound(
                                       new XYZ(5, 5, 0), new XYZ(0, 5, 0)));
                profileloop.Append(Line.CreateBound(
                                       new XYZ(0, 5, 0), new XYZ(0, 0, 0)));

                //create the AnalyticalPanel
                analyticalPanel = AnalyticalPanel.Create(revitDoc, profileloop);

                analyticalPanel.StructuralRole = AnalyticalStructuralRole.StructuralRoleFloor;
                analyticalPanel.AnalyzeAs      = AnalyzeAs.SlabOneWay;

                transaction.Commit();
            }

            return(analyticalPanel);
        }
        /// <summary>
        /// creates an AnalyticalOpening element which will be placed on the AnalyticalPanel
        /// with id = panelId
        /// </summary>
        public static AnalyticalOpening CreateAMOpening(Document revitDoc, ElementId panelId)
        {
            if (panelId == ElementId.InvalidElementId)
            {
                return(null);
            }

            AnalyticalOpening opening = null;

            using (Transaction transaction = new Transaction(revitDoc, "Create Analytical Opening"))
            {
                transaction.Start();

                //create the curveLoop for the AnalyticalOpening element
                CurveLoop profileloop = new CurveLoop();
                profileloop.Append(Line.CreateBound(
                                       new XYZ(1, 1, 0), new XYZ(2, 1, 0)));
                profileloop.Append(Line.CreateBound(
                                       new XYZ(2, 1, 0), new XYZ(2, 2, 0)));
                profileloop.Append(Line.CreateBound(
                                       new XYZ(2, 2, 0), new XYZ(-1, 2, 0)));
                profileloop.Append(Line.CreateBound(
                                       new XYZ(-1, 2, 0), new XYZ(1, 1, 0)));

                if (AnalyticalOpening.IsCurveLoopValidForAnalyticalOpening(profileloop, revitDoc, panelId))
                {
                    //create the AnalyticalOpening
                    opening = AnalyticalOpening.Create(revitDoc, profileloop, panelId);
                }

                transaction.Commit();
            }
            return(opening);
        }
Beispiel #11
0
 private void AddCurveToLoopInternal(CurveLoop curveLoop, Curve curve, bool initialReverse, bool tryReversed)
 {
     try
     {
         if (tryReversed != initialReverse)
         {
             curveLoop.Append(curve.CreateReversed());
         }
         else
         {
             curveLoop.Append(curve);
         }
     }
     catch (Exception ex)
     {
         if (ex.Message.Contains("not contiguous"))
         {
             if (!tryReversed)
             {
                 AddCurveToLoopInternal(curveLoop, curve, initialReverse, true);
             }
             else
             {
                 throw ex;
             }
         }
     }
 }
Beispiel #12
0
        //Build solid
        public void incrementIntercetor(Document doc, XYZ startOfInterest, Parameter zOffsetVar, out ElementId columnId, out ElementId beamId)
        {
            columnId = null;
            beamId   = null;

            double radius  = 0;
            double limit   = 0.75;
            double zOffset = zOffsetVar.AsDouble();
            //lower arc center
            double centerZ   = (startOfInterest.Z + zOffset) - 0.25;
            XYZ    arcCenter = new XYZ(startOfInterest.X, startOfInterest.Y, centerZ);

            //Build a solid cylinder
            for (radius = .125; radius < limit; radius = radius + 0.1)
            {
                // Create a vertical half-circle loop in the frame location.
                List <CurveLoop> curveloops = new List <CurveLoop>();
                CurveLoop        circle     = new CurveLoop();
                circle.Append(Arc.Create(arcCenter, radius, 0, Math.PI, XYZ.BasisX, XYZ.BasisY));
                circle.Append(Arc.Create(arcCenter, radius, Math.PI, 2 * Math.PI, XYZ.BasisX, XYZ.BasisY));
                curveloops.Add(circle);

                Solid cylinder = GeometryCreationUtilities.CreateExtrusionGeometry(curveloops, XYZ.BasisZ, (0.25));
                //PaintSolid(commandData, cylinder, 5);
                //Find column
                IEnumerable <Element> columns = new FilteredElementCollector(doc)
                                                .OfClass(typeof(FamilyInstance))
                                                .OfCategory(BuiltInCategory.OST_StructuralColumns)
                                                .WherePasses(new ElementIntersectsSolidFilter(cylinder));

                if (columns.Count() > 0)
                {
                    foreach (Element e in columns)
                    {
                        FamilyInstance fi = e as FamilyInstance;
                        FamilySymbol   fs = fi.Symbol;
                        columnId = e.Id;
                    }
                    break;
                }

                //Find beam
                IEnumerable <Element> beams = new FilteredElementCollector(doc)
                                              .OfClass(typeof(FamilyInstance))
                                              .OfCategory(BuiltInCategory.OST_StructuralFraming)
                                              .WherePasses(new ElementIntersectsSolidFilter(cylinder));

                if (beams.Count() > 0)
                {
                    foreach (Element e in beams)
                    {
                        FamilyInstance fi = e as FamilyInstance;
                        FamilySymbol   fs = fi.Symbol;
                        beamId = e.Id;
                    }
                    break;
                }
            }
            //End of loop
        }
Beispiel #13
0
        /// <summary>
        /// Create a centerbased box
        /// </summary>
        /// <param name="center">The given box center</param>
        /// <param name="edgelength">The given box's edge length</param>
        /// <returns>The created box</returns>
        public Solid CreateCenterbasedBox(XYZ center, double edgelength)
        {
            double halfedgelength = edgelength / 2.0;

            List <CurveLoop> profileloops = new List <CurveLoop>();
            CurveLoop        profileloop  = new CurveLoop();

            profileloop.Append(Line.CreateBound(
                                   new XYZ(center.X - halfedgelength, center.Y - halfedgelength, center.Z - halfedgelength),
                                   new XYZ(center.X - halfedgelength, center.Y + halfedgelength, center.Z - halfedgelength)));
            profileloop.Append(Line.CreateBound(
                                   new XYZ(center.X - halfedgelength, center.Y + halfedgelength, center.Z - halfedgelength),
                                   new XYZ(center.X + halfedgelength, center.Y + halfedgelength, center.Z - halfedgelength)));
            profileloop.Append(Line.CreateBound(
                                   new XYZ(center.X + halfedgelength, center.Y + halfedgelength, center.Z - halfedgelength),
                                   new XYZ(center.X + halfedgelength, center.Y - halfedgelength, center.Z - halfedgelength)));
            profileloop.Append(Line.CreateBound(
                                   new XYZ(center.X + halfedgelength, center.Y - halfedgelength, center.Z - halfedgelength),
                                   new XYZ(center.X - halfedgelength, center.Y - halfedgelength, center.Z - halfedgelength)));
            profileloops.Add(profileloop);

            XYZ extrusiondir = new XYZ(0, 0, 1); // orthogonal

            double extrusiondist = edgelength;

            return(GeometryCreationUtilities.CreateExtrusionGeometry(profileloops, extrusiondir, extrusiondist));
        }
Beispiel #14
0
        /// <summary>
        ///     Converts the CurveArray to the CurveLoop.
        /// </summary>
        /// <param name="curves"></param>
        /// <returns></returns>
        public static CurveLoop ToCurveLoop <T>(this IEnumerable <T> curves) where T : Curve
        {
            var newCurves = curves.ToList();

            if (curves == null || newCurves.Count == 0)
            {
                throw new NullReferenceException(nameof(newCurves));
            }

            var results = new CurveLoop();
            var endPt   = newCurves[0]?.GetEndPoint(1);

            results.Append(newCurves[0]);

            newCurves[0] = null;

            // If computing count equals curveLoop count, it should break.
            // Because, the curveLoop cannot find valid curve to append.
            var count = 0;

            while (count < newCurves.Count && results.Count() < newCurves.Count)
            {
                for (var i = 0; i < newCurves.Count; i++)
                {
                    if (newCurves[i] == null)
                    {
                        continue;
                    }

                    var p0 = newCurves[i].GetEndPoint(0);

                    var p1 = newCurves[i].GetEndPoint(1);

                    if (p0.IsAlmostEqualTo(endPt))
                    {
                        endPt = p1;

                        results.Append(newCurves[i]);

                        newCurves[i] = null;
                    }

                    // The curve should be reversed.
                    else if (p1.IsAlmostEqualTo(endPt))
                    {
                        endPt = p0;

                        results.Append(newCurves[i].CreateReversed());

                        newCurves[i] = null;
                    }
                }

                count++;
            }

            return(results);
        }
Beispiel #15
0
        static public CurveLoop CreateCurveLoop(this Curve firstCurve, Curve secondCurve)
        {
            CurveLoop curveLoop = new CurveLoop();

            curveLoop.Append(firstCurve.CreateReversed());
            curveLoop.Append(Line.CreateBound(firstCurve.GetEndPoint(0), secondCurve.GetEndPoint(0)));
            curveLoop.Append(secondCurve);
            curveLoop.Append(Line.CreateBound(secondCurve.GetEndPoint(1), firstCurve.GetEndPoint(1)));

            return(curveLoop);
        }
Beispiel #16
0
        public static CurveLoop CreateCurveLoop(List <XYZ> pts)
        {
            int       n         = pts.Count;
            CurveLoop curveLoop = new CurveLoop();

            for (int i = 1; i < n; ++i)
            {
                curveLoop.Append(Line.CreateBound(pts[i - 1], pts[i]));
            }
            curveLoop.Append(Line.CreateBound(pts[n], pts[0]));
            return(curveLoop);
        }
Beispiel #17
0
 public static Solid CreateSphereAt(XYZ centre, double radius)
 {
     Frame coordinateFrame = new Frame(centre, XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ);
     Arc arc = Arc.Create(centre - radius * XYZ.BasisZ, centre + radius * XYZ.BasisZ, centre + radius * XYZ.BasisX);
     Line curve = Line.CreateBound(arc.GetEndPoint(1), arc.GetEndPoint(0));
     CurveLoop curveLoop = new CurveLoop();
     curveLoop.Append(arc);
     curveLoop.Append(curve);
     List<CurveLoop> list = new List<CurveLoop>(1);
     list.Add(curveLoop);
     return GeometryCreationUtilities.CreateRevolvedGeometry(coordinateFrame, list, 0.0, 6.2831853071795862);
 }
Beispiel #18
0
        public static IList <Solid> CreateSolid(Document doc, FamilyInstance familyInstance, Transform transform)
        {
            IList <Solid> solids = new List <Solid>();

            try
            {
                Curve    curve      = GetCurvemaxfamily(familyInstance);
                Element  ele        = doc.GetElement(familyInstance.Id);
                string[] parameters = new string[]
                {
                    "DIM_WWF_YY",
                    "DIM_LENGTH"
                };
                Parameter   pa          = LookupElementParameter(ele, parameters);
                double      lengthcurve = pa.AsDouble();
                XYZ         starpointfa = new XYZ(lengthcurve / 2, 0, 0);
                XYZ         endpointfa  = new XYZ(-lengthcurve / 2, 0, 0);
                XYZ         startpoint  = transform.OfPoint(starpointfa);
                XYZ         endpoint    = transform.OfPoint(endpointfa);
                XYZ         norm        = new XYZ((startpoint.X - endpoint.X), (startpoint.Y - endpoint.Y), (startpoint.Z - endpoint.Z));
                Plane       plane       = Plane.CreateByNormalAndOrigin(norm, startpoint);
                Transaction newtran     = new Transaction(doc, "ss");
                newtran.Start();
                SketchPlane stk       = SketchPlane.Create(doc, plane);
                XYZ         pt1       = startpoint.Add(0.01 * plane.XVec).Add(0.01 * plane.YVec);
                XYZ         pt2       = startpoint.Add(0.01 * plane.YVec);
                XYZ         pt3       = startpoint.Add(-0.01 * plane.YVec);
                XYZ         pt4       = startpoint.Add(0.01 * plane.XVec).Add(-0.01 * plane.YVec);
                XYZ         pt5       = (-1) * norm;
                Line        lineleft  = Line.CreateBound(pt1, pt2);
                Line        linetop   = Line.CreateBound(pt2, pt3);
                Line        lineright = Line.CreateBound(pt3, pt4);
                Line        linebot   = Line.CreateBound(pt4, pt1);
                CurveLoop   profile   = new CurveLoop();
                profile.Append(lineleft);
                profile.Append(linetop);
                profile.Append(lineright);
                profile.Append(linebot);
                IList <CurveLoop> listloop1 = new List <CurveLoop>();
                listloop1.Add(profile);
                Solid solid = GeometryCreationUtilities.CreateExtrusionGeometry(listloop1, pt5, lengthcurve);
                newtran.Commit();
                solids.Add(solid);
            }
            catch
            {
                solids = null;
            }
            return(solids);
        }
Beispiel #19
0
        public static Solid CreateSphereAt(XYZ centre, double radius)
        {
            Frame     frame     = new Frame(centre, XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ);
            Arc       arc       = Arc.Create(centre - radius * XYZ.BasisZ, centre + radius * XYZ.BasisZ, centre + radius * XYZ.BasisX);
            Line      line      = Line.CreateBound(arc.GetEndPoint(1), arc.GetEndPoint(0));
            CurveLoop curveLoop = new CurveLoop();

            curveLoop.Append(arc);
            curveLoop.Append(line);
            return(GeometryCreationUtilities.CreateRevolvedGeometry(frame, new List <CurveLoop>(1)
            {
                curveLoop
            }, 0.0, 6.2831853071795862));
        }
Beispiel #20
0
        private static Solid CreateSphereAt(XYZ centre, double radius)
        {
            Frame     frame     = new Frame(centre, XYZ.get_BasisX(), XYZ.get_BasisY(), XYZ.get_BasisZ());
            Arc       arc       = Arc.Create(XYZ.op_Subtraction(centre, XYZ.op_Multiply(radius, XYZ.get_BasisZ())), XYZ.op_Addition(centre, XYZ.op_Multiply(radius, XYZ.get_BasisZ())), XYZ.op_Addition(centre, XYZ.op_Multiply(radius, XYZ.get_BasisX())));
            Line      bound     = Line.CreateBound(((Curve)arc).GetEndPoint(1), ((Curve)arc).GetEndPoint(0));
            CurveLoop curveLoop = new CurveLoop();

            curveLoop.Append((Curve)arc);
            curveLoop.Append((Curve)bound);
            List <CurveLoop> curveLoopList = new List <CurveLoop>(1);

            curveLoopList.Add(curveLoop);
            return(GeometryCreationUtilities.CreateRevolvedGeometry(frame, (IList <CurveLoop>)curveLoopList, 0.0, 2.0 * Math.PI));
        }
Beispiel #21
0
        private DirectShape RunBuilding(Document doc, Way building, Dictionary <long?, OsmGeo> allNodes)
        {
            var points = this.geometryService.GetPointsFromNodes(building.Nodes, allNodes);

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

            var curveLoop = new CurveLoop();

            for (int i = 0; i < points.Count - 1; i++)
            {
                Line line = Line.CreateBound(points[i], points[i + 1]);
                curveLoop.Append(line);
            }

            var heightTag  = building.Tags.FirstOrDefault(tag => tag.Key == "height");
            var heightFeet = UnitUtils.ConvertToInternalUnits(3, DisplayUnitType.DUT_METERS);

            if (double.TryParse(heightTag.Value, out double heightMeters))
            {
                heightFeet = UnitUtils.ConvertToInternalUnits(heightMeters, DisplayUnitType.DUT_METERS);
            }

            return(shapeService.Build(doc, new List <CurveLoop> {
                curveLoop
            }, heightFeet, new ElementId(BuiltInCategory.OST_GenericModel)));
        }
        public static Autodesk.Revit.DB.CurveLoop ToRevitType(this Autodesk.DesignScript.Geometry.PolyCurve pcrv,
                                                              bool performHostUnitConversion = true)
        {
            if (!pcrv.IsClosed)
            {
                throw new Exception("The input PolyCurve must be closed");
            }

            Autodesk.DesignScript.Geometry.Curve[] crvs = null;
            if (performHostUnitConversion)
            {
                pcrv = pcrv.InHostUnits();
                crvs = pcrv.Curves();
                pcrv.Dispose();
            }
            else
            {
                crvs = pcrv.Curves();
            }

            var cl = new CurveLoop();

            foreach (Autodesk.DesignScript.Geometry.Curve curve in crvs)
            {
                using (var nc = curve.ToNurbsCurve())
                {
                    Autodesk.Revit.DB.Curve converted = nc.ToRevitType(false);
                    cl.Append(converted);
                }
            }

            crvs.ForEach(x => x.Dispose());

            return(cl);
        }
        private static void CreateFilledRegion(Document doc, SpatialObjectWrapper so)
        {
            try
            {
                var filledRegionType = new FilteredElementCollector(doc).OfClass(typeof(FilledRegionType)).FirstElementId();
                if (filledRegionType == null || filledRegionType == ElementId.InvalidElementId)
                {
                    return;
                }

                var curves = new List <CurveLoop>();
                var loop   = new CurveLoop();
                foreach (var curve in so.Room2D.FloorBoundary.GetCurves(so.Level.Elevation))
                {
                    //doc.Create.NewDetailCurve(doc.ActiveView, curve);
                    loop.Append(curve);
                }
                curves.Add(loop);

                FilledRegion.Create(doc, filledRegionType, doc.ActiveView.Id, curves);
            }
            catch (Exception e)
            {
                _logger.Fatal(e);
            }
        }
Beispiel #24
0
        public void CropAroundRoom(Room room, View view) //This provides the required shape now how to combine with the offset and tie into wall thickness
        {
            if (view != null)
            {
                IList <IList <BoundarySegment> > segments = room.GetBoundarySegments(new SpatialElementBoundaryOptions());

                if (null != segments) //the room may not be bound
                {
                    foreach (IList <BoundarySegment> segmentList in segments)
                    {
                        CurveLoop loop = new CurveLoop();
                        foreach (BoundarySegment boundarySegment in segmentList)
                        {
                            List <XYZ> points = boundarySegment.GetCurve().Tessellate().ToList();
                            for (int ip = 0; ip < points.Count - 1; ip++)
                            {
                                Line l = Line.CreateBound(points[ip], points[ip + 1]);
                                loop.Append(l);
                            }
                        }
                        ViewCropRegionShapeManager vcrShapeMgr = view.GetCropRegionShapeManager();
                        bool cropValid = vcrShapeMgr.IsCropRegionShapeValid(loop);
                        if (cropValid)
                        {
                            vcrShapeMgr.SetCropShape(loop);
                            break; // if more than one set of boundary segments for room, crop around the first one
                        }
                    }
                }
            }
        }
Beispiel #25
0
        private DirectShape RunBuilding(Document doc, Way building, Dictionary <long?, OsmGeo> allNodes)
        {
            var points = new List <XYZ>();

            foreach (var nodeId in building.Nodes)
            {
                var geometry = allNodes[nodeId];
                if (geometry is Node node)
                {
                    var coords = coordService.GetRevitCoords((double)node.Latitude, (double)node.Longitude);
                    points.Add(coords);
                }
            }

            var curveLoop = new CurveLoop();

            for (int i = 0; i < points.Count - 1; i++)
            {
                Line line = Line.CreateBound(points[i], points[i + 1]);
                curveLoop.Append(line);
            }

            var heightTag  = building.Tags.FirstOrDefault(tag => tag.Key == "height");
            var heightFeet = UnitUtils.ConvertToInternalUnits(3, DisplayUnitType.DUT_METERS);

            if (double.TryParse(heightTag.Value, out double heightMeters))
            {
                heightFeet = UnitUtils.ConvertToInternalUnits(heightMeters, DisplayUnitType.DUT_METERS);
            }

            return(shapeService.Build(doc, new List <CurveLoop> {
                curveLoop
            }, heightFeet, new ElementId(BuiltInCategory.OST_GenericModel)));
        }
Beispiel #26
0
        /***************************************************/

        private static void AddLoop(this BRepBuilder brep, BRepBuilderGeometryId face, XYZ normal, ICurve curve, bool external)
        {
            CurveLoop cl = new CurveLoop();

            foreach (ICurve sp in curve.ISubParts())
            {
                foreach (Curve cc in sp.IToRevitCurves())
                {
                    cl.Append(cc);
                }
            }

            if (external != cl.IsCounterclockwise(normal))
            {
                cl.Flip();
            }

            BRepBuilderGeometryId loop = brep.AddLoop(face);

            foreach (Curve cc in cl)
            {
                BRepBuilderGeometryId edge = brep.AddEdge(BRepBuilderEdgeGeometry.Create(cc));
                brep.AddCoEdge(loop, edge, false);
            }

            brep.FinishLoop(loop);
        }
Beispiel #27
0
        /// <summary>
        /// Construct a Revit FilledRegion element by Curves
        /// </summary>
        /// <param name="view">View to place filled region on</param>
        /// <param name="boundary">Boundary curves</param>
        /// <param name="regionType">Region Type</param>
        /// <returns></returns>
        public static FilledRegion ByCurves(Revit.Elements.Views.View view, IEnumerable <Autodesk.DesignScript.Geometry.Curve> boundary, FilledRegionType regionType)
        {
            Autodesk.Revit.DB.FilledRegionType type = regionType.InternalRevitElement;

            CurveLoop loop = new CurveLoop();

            foreach (Autodesk.DesignScript.Geometry.Curve curve in boundary)
            {
                loop.Append(curve.ToRevitType());
            }

            if (loop.IsOpen())
            {
                throw new Exception(Properties.Resources.CurveLoopNotClosed);
            }

            Autodesk.Revit.DB.View revitView = (Autodesk.Revit.DB.View)view.InternalElement;

            if (!view.IsAnnotationView())
            {
                throw new Exception(Properties.Resources.ViewDoesNotSupportAnnotations);
            }

            return(new FilledRegion(revitView, type.Id, new List <CurveLoop>()
            {
                loop
            }));
        }
        /// <summary>
        /// 调整viewPlan的尺寸并贴合选中房间
        /// change a viewPlan to fix the selected room
        /// </summary>
        /// <param name="view"></param>
        /// <param name="tran"></param>
        /// <param name="viewOffseet"></param>
        public void ChangeViewFitRoom(ViewPlan view, Transaction tran, double viewOffseet)
        {
            if (view == null)
            {
                TaskDialog.Show("viewIsNull", "Can't find the type of View.");
                return;
            }

            //获得并设定房间的边界设定,并获取其边界集
            DocSet.uidoc.ActiveView = view;
            SpatialElementBoundaryOptions opt = new SpatialElementBoundaryOptions();

            opt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center;//房间边界设定,能变更获取的边界位置
            IList <IList <BoundarySegment> > segments = DocSet.selRoom.GetBoundarySegments(opt);

            if (segments == null)
            {
                TaskDialog.Show("segementsIsNull", "can't get the BoundarySegment of room");
                return;
            }


            ViewCropRegionShapeManager vcrShanpMgr = view.GetCropRegionShapeManager();

            CurveLoop loop = new CurveLoop();

            foreach (IList <BoundarySegment> segmentList in segments)
            {
                foreach (BoundarySegment segment in segmentList)
                {
                    Curve curve = segment.GetCurve();
                    loop.Append(curve);
                }


                bool cropValid = vcrShanpMgr.IsCropRegionShapeValid(loop);
                if (cropValid)
                {
                    //默认矩形
                    //TaskDialog.Show("cropValid", "the crop is shape Valid");
                    tran.Start("change the view crop region");
                    vcrShanpMgr.SetCropShape(loop);
                    tran.Commit();
                    tran.Start("Remove Crop Region Shape");
                    vcrShanpMgr.RemoveCropRegionShape();
                    tran.Commit();
                    //TaskDialog.Show("ChangeView", "ChangeViewdone");
                    break;
                }
            }

            tran.Start("loop offset");
            //TaskDialog.Show("!!!", "changeloop!");
            loop = CurveLoop.CreateViaOffset(vcrShanpMgr.GetCropShape().First(), -1 * viewOffseet / 300, new XYZ(0, 0, 1));
            vcrShanpMgr.SetCropShape(loop);
            tran.Commit();

            DocSet.uidoc.ActiveView = view;
        }
Beispiel #29
0
        private Solid FindCeilingSolid(Element ceiling)
        {
            Solid ceilingSolid = null;

            try
            {
                var opt = m_app.Application.Create.NewGeometryOptions();
                opt.ComputeReferences        = true;
                opt.IncludeNonVisibleObjects = true;

                var geomElem = ceiling.get_Geometry(opt);
                foreach (var obj in geomElem)
                {
                    var solid = obj as Solid;
                    if (null != solid)
                    {
                        if (solid.Volume > 0)
                        {
                            ceilingSolid = solid;
                            break;
                        }
                        else
                        {
                            var curveLoopList = new List <CurveLoop>();
                            XYZ normal        = null;
                            foreach (Face face in solid.Faces)
                            {
                                if (face.EdgeLoops.Size > 0)
                                {
                                    normal = face.ComputeNormal(new UV(0, 0));
                                    foreach (EdgeArray edgeArray in face.EdgeLoops)
                                    {
                                        var curveLoop = new CurveLoop();
                                        foreach (Edge edge in edgeArray)
                                        {
                                            curveLoop.Append(edge.AsCurve());
                                        }
                                        curveLoopList.Add(curveLoop);
                                    }
                                }
                            }
                            var extrusion = GeometryCreationUtilities.CreateExtrusionGeometry(curveLoopList, normal, 1);
                            if (extrusion.Volume > 0)
                            {
                                ceilingSolid = extrusion;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Could not find the solid of the ceiling.\n" + ex.Message, "FindCeilingSolid", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            return(ceilingSolid);
        }
Beispiel #30
0
        private IList <CurveLoop> CreateProfileCurveLoopsForDirectrix(Curve directrix, out double startParam)
        {
            startParam = 0.0;

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

            if (directrix.IsBound)
            {
                startParam = directrix.GetEndParameter(0);
            }

            Transform originTrf = directrix.ComputeDerivatives(startParam, false);

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

            // The X-dir of the transform of the start of the directrix will form the normal of the disk.
            // We are not using the origin in Plane.CreateByNormalAndOrigin because that has
            // limits of [-30K,30K].
            Plane diskPlaneAxes = Plane.CreateByNormalAndOrigin(originTrf.BasisX, XYZ.Zero);

            IList <CurveLoop> profileCurveLoops = new List <CurveLoop>();

            CurveLoop diskOuterCurveLoop = new CurveLoop();

            diskOuterCurveLoop.Append(Arc.Create(originTrf.Origin, Radius, 0, Math.PI, diskPlaneAxes.XVec, diskPlaneAxes.YVec));
            diskOuterCurveLoop.Append(Arc.Create(originTrf.Origin, Radius, Math.PI, 2.0 * Math.PI, diskPlaneAxes.XVec, diskPlaneAxes.YVec));
            profileCurveLoops.Add(diskOuterCurveLoop);

            if (InnerRadius.HasValue)
            {
                CurveLoop diskInnerCurveLoop = new CurveLoop();
                diskInnerCurveLoop.Append(Arc.Create(originTrf.Origin, InnerRadius.Value, 0, Math.PI, diskPlaneAxes.XVec, diskPlaneAxes.YVec));
                diskInnerCurveLoop.Append(Arc.Create(originTrf.Origin, InnerRadius.Value, Math.PI, 2.0 * Math.PI, diskPlaneAxes.XVec, diskPlaneAxes.YVec));
                profileCurveLoops.Add(diskInnerCurveLoop);
            }

            return(profileCurveLoops);
        }
Beispiel #31
0
        public static Plane GetPlaneFromCurve(Curve c, bool planarOnly)
        {
            //find the plane of the curve and generate a sketch plane
            double period = c.IsBound ? 0.0 : (c.IsCyclic ? c.Period : 1.0);

            var p0 = c.IsBound ? c.Evaluate(0.0, true) : c.Evaluate(0.0, false);
            var p1 = c.IsBound ? c.Evaluate(0.5, true) : c.Evaluate(0.25 * period, false);
            var p2 = c.IsBound ? c.Evaluate(1.0, true) : c.Evaluate(0.5 * period, false);

            if (IsLineLike(c))
            {
                XYZ norm = null;

                //keep old plane computations
                if (System.Math.Abs(p0.Z - p2.Z) < Tolerance)
                {
                    norm = XYZ.BasisZ;
                }
                else
                {
                    var v1 = p1 - p0;
                    var v2 = p2 - p0;

                    var p3 = new XYZ(p2.X, p2.Y, p0.Z);
                    var v3 = p3 - p0;
                    norm = v1.CrossProduct(v3);
                    if (norm.IsZeroLength())
                    {
                        norm = v2.CrossProduct(XYZ.BasisY);
                    }
                    norm = norm.Normalize();
                }

                return new Plane(norm, p0);

            }

            var cLoop = new CurveLoop();
            cLoop.Append(c.Clone());
            if (cLoop.HasPlane())
            {
                return cLoop.GetPlane();
            }
            if (planarOnly)
                return null;

            // Get best fit plane using tesselation
            var points = c.Tessellate().Select(x => x.ToPoint(false));

            var bestFitPlane =
                Autodesk.DesignScript.Geometry.Plane.ByBestFitThroughPoints(points);

            return bestFitPlane.ToPlane(false);
        }
Beispiel #32
0
        /// <summary>
        /// Create a copy of a curve loop with a given transformation applied.
        /// </summary>
        /// <param name="origLoop">The original curve loop.</param>
        /// <param name="trf">The transform.</param>
        /// <returns>The transformed loop.</returns>
        public static CurveLoop CreateTransformed(CurveLoop origLoop, Transform trf)
        {
            if (origLoop == null)
                return null;

            CurveLoop newLoop = new CurveLoop();
            foreach (Curve curve in origLoop)
            {
                newLoop.Append(curve.CreateTransformed(trf));
            }
            return newLoop;
        }
Beispiel #33
0
        /// <summary>
        /// A PolyCurve is not a curve, this is a special extension method to convert to a Revit CurveLoop
        /// </summary>
        /// <param name="pcrv"></param>
        /// <returns></returns>
        public static Autodesk.Revit.DB.CurveLoop ToRevitType(this Autodesk.DesignScript.Geometry.PolyCurve pcrv)
        {
            if (!pcrv.IsClosed)
            {
                throw new Exception("The input PolyCurve must be closed");
            }

            var cl = new CurveLoop();

            var crvs = pcrv.Curves();

            foreach (Autodesk.DesignScript.Geometry.Curve curve in crvs)
            {
                Autodesk.Revit.DB.Curve converted = curve.ToNurbsCurve().ToRevitType();
                cl.Append(converted);
            }

            return cl;

        }
Beispiel #34
0
        public static Autodesk.Revit.DB.CurveLoop ToRevitType(this Autodesk.DesignScript.Geometry.PolyCurve pcrv,
            bool performHostUnitConversion = true)
        {
            if (!pcrv.IsClosed)
            {
                throw new Exception("The input PolyCurve must be closed");
            }

            pcrv = performHostUnitConversion ? pcrv.InHostUnits() : pcrv;

            var cl = new CurveLoop();
            var crvs = pcrv.Curves();

            foreach (Autodesk.DesignScript.Geometry.Curve curve in crvs)
            {
                Autodesk.Revit.DB.Curve converted = curve.ToNurbsCurve().ToRevitType(false);
                cl.Append(converted);
            }

            return cl;
        }
      // This routine may return null geometry for one of three reasons:
      // 1. Invalid input.
      // 2. No IfcMaterialLayerUsage.
      // 3. The IfcMaterialLayerUsage isn't handled.
      // If the reason is #1 or #3, we want to warn the user.  If it is #2, we don't.  Pass back shouldWarn to let the caller know.
      private IList<GeometryObject> CreateGeometryFromMaterialLayerUsage(IFCImportShapeEditScope shapeEditScope, Transform extrusionPosition,
          IList<CurveLoop> loops, XYZ extrusionDirection, double currDepth, out ElementId materialId, out bool shouldWarn)
      {
         IList<GeometryObject> extrusionSolids = null;
         materialId = ElementId.InvalidElementId;

         try
         {
            shouldWarn = true;  // Invalid input.

            // Check for valid input.
            if (shapeEditScope == null ||
                extrusionPosition == null ||
                loops == null ||
                loops.Count() == 0 ||
                extrusionDirection == null ||
                !Application.IsValidThickness(currDepth))
               return null;

            IFCProduct creator = shapeEditScope.Creator;
            if (creator == null)
               return null;

            shouldWarn = false;  // Missing, empty, or optimized out IfcMaterialLayerSetUsage - valid reason to stop.

            IIFCMaterialSelect materialSelect = creator.MaterialSelect;
            if (materialSelect == null)
               return null;

            IFCMaterialLayerSetUsage materialLayerSetUsage = materialSelect as IFCMaterialLayerSetUsage;
            if (materialLayerSetUsage == null)
               return null;

            IFCMaterialLayerSet materialLayerSet = materialLayerSetUsage.MaterialLayerSet;
            if (materialLayerSet == null)
               return null;

            IList<IFCMaterialLayer> materialLayers = materialLayerSet.MaterialLayers;
            if (materialLayers == null || materialLayers.Count == 0)
               return null;

            // Optimization: if there is only one layer, use the standard method, with possibly an overloaded material.
            ElementId baseMaterialId = GetMaterialElementId(shapeEditScope);
            if (materialLayers.Count == 1)
            {
               IFCMaterial oneMaterial = materialLayers[0].Material;
               if (oneMaterial == null)
                  return null;

               materialId = oneMaterial.GetMaterialElementId();
               if (materialId != ElementId.InvalidElementId)
               {
                  // We will not override the material of the element if the layer material has no color.
                  if (Importer.TheCache.MaterialsWithNoColor.Contains(materialId))
                     materialId = ElementId.InvalidElementId;
               }

               return null;
            }

            // Anything below here is something we should report to the user, with the exception of the total thickness
            // not matching the extrusion thickness.  This would require more analysis to determine that it is actually
            // an error condition.
            shouldWarn = true;

            IList<IFCMaterialLayer> realMaterialLayers = new List<IFCMaterialLayer>();
            double totalThickness = 0.0;
            foreach (IFCMaterialLayer materialLayer in materialLayers)
            {
               double depth = materialLayer.LayerThickness;
               if (MathUtil.IsAlmostZero(depth))
                  continue;

               if (depth < 0.0)
                  return null;

               realMaterialLayers.Add(materialLayer);
               totalThickness += depth;
            }

            // Axis3 means that the material layers are stacked in the Z direction.  This is common for floor slabs.
            bool isAxis3 = (materialLayerSetUsage.Direction == IFCLayerSetDirection.Axis3);

            // For elements extruded in the Z direction, if the extrusion layers don't have the same thickness as the extrusion,
            // this could be one of two reasons:
            // 1. There is a discrepancy between the extrusion depth and the material layer set usage calculated depth.
            // 2. There are multiple extrusions in the body definition.
            // In either case, we will use the extrusion geometry over the calculated material layer set usage geometry.
            // In the future, we may decide to allow for case #1 by passing in a flag to allow for this.
            if (isAxis3 && !MathUtil.IsAlmostEqual(totalThickness, currDepth))
            {
               shouldWarn = false;
               return null;
            }

            int numLayers = realMaterialLayers.Count();
            if (numLayers == 0)
               return null;
            // We'll use this initial value for the Axis2 case, so read it here.
            double baseOffsetForLayer = materialLayerSetUsage.Offset;

            // Needed for Axis2 case only.  The axisCurve is the curve defined in the product representation representing
            // a base curve (an axis) for the footprint of the element.
            Curve axisCurve = null;

            // The oriented cuve list represents the 4 curves of supported Axis2 footprint in the following order:
            // 1. curve along length of object closest to the first material layer with the orientation of the axis curve
            // 2. connecting end curve
            // 3. curve along length of object closest to the last material layer with the orientation opposite of the axis curve
            // 4. connecting end curve.
            IList<Curve> orientedCurveList = null;

            if (!isAxis3)
            {
               // Axis2 means that the material layers are stacked inthe Y direction.  This is by definition for IfcWallStandardCase,
               // which has a local coordinate system whose Y direction is orthogonal to the length of the wall.
               if (materialLayerSetUsage.Direction == IFCLayerSetDirection.Axis2)
               {
                  axisCurve = GetAxisCurve(creator, extrusionPosition);
                  if (axisCurve == null)
                     return null;

                  orientedCurveList = GetOrientedCurveList(loops, axisCurve, extrusionPosition.BasisZ, baseOffsetForLayer, totalThickness);
                  if (orientedCurveList == null)
                     return null;
               }
               else
                  return null;    // Not handled.
            }

            extrusionSolids = new List<GeometryObject>();

            bool positiveOrientation = (materialLayerSetUsage.DirectionSense == IFCDirectionSense.Positive);

            // Always extrude in the positive direction for Axis2.
            XYZ materialExtrusionDirection = (positiveOrientation || !isAxis3) ? extrusionDirection : -extrusionDirection;

            // Axis2 repeated values.
            // The IFC concept of offset direction is reversed from Revit's.
            XYZ normalDirectionForAxis2 = positiveOrientation ? -extrusionPosition.BasisZ : extrusionPosition.BasisZ;
            bool axisIsCyclic = (axisCurve == null) ? false : axisCurve.IsCyclic;
            double axisCurvePeriod = axisIsCyclic ? axisCurve.Period : 0.0;

            Transform curveLoopTransform = Transform.Identity;

            IList<CurveLoop> currLoops = null;
            double depthSoFar = 0.0;

            for (int ii = 0; ii < numLayers; ii++)
            {
               IFCMaterialLayer materialLayer = materialLayers[ii];

               // Ignore 0 thickness layers.  No need to warn.
               double depth = materialLayer.LayerThickness;
               if (MathUtil.IsAlmostZero(depth))
                  continue;

               // If the thickness is non-zero but invalid, fail.
               if (!Application.IsValidThickness(depth))
                  return null;

               double extrusionDistance = 0.0;
               if (isAxis3)
               {
                  // Offset the curve loops if necessary, using the base extrusionDirection, regardless of the direction sense
                  // of the MaterialLayerSetUsage.
                  double offsetForLayer = positiveOrientation ? baseOffsetForLayer + depthSoFar : baseOffsetForLayer - depthSoFar;
                  if (!MathUtil.IsAlmostZero(offsetForLayer))
                  {
                     curveLoopTransform.Origin = offsetForLayer * extrusionDirection;

                     currLoops = new List<CurveLoop>();
                     foreach (CurveLoop loop in loops)
                     {
                        CurveLoop newLoop = CurveLoop.CreateViaTransform(loop, curveLoopTransform);
                        if (newLoop == null)
                           return null;

                        currLoops.Add(newLoop);
                     }
                  }
                  else
                     currLoops = loops;

                  extrusionDistance = depth;
               }
               else
               {
                  // startClipCurve, firstEndCapCurve, endClipCurve, secondEndCapCurve.
                  Curve[] outline = new Curve[4];
                  double[][] endParameters = new double[4][];

                  double startClip = depthSoFar;
                  double endClip = depthSoFar + depth;

                  outline[0] = orientedCurveList[0].CreateOffset(startClip, normalDirectionForAxis2);
                  outline[1] = orientedCurveList[1].Clone();
                  outline[2] = orientedCurveList[2].CreateOffset(totalThickness - endClip, normalDirectionForAxis2);
                  outline[3] = orientedCurveList[3].Clone();

                  for (int jj = 0; jj < 4; jj++)
                  {
                     outline[jj].MakeUnbound();
                     endParameters[jj] = new double[2];
                     endParameters[jj][0] = 0.0;
                     endParameters[jj][1] = 0.0;
                  }

                  // Trim/Extend the curves so that they make a closed loop.
                  for (int jj = 0; jj < 4; jj++)
                  {
                     IntersectionResultArray resultArray = null;
                     outline[jj].Intersect(outline[(jj + 1) % 4], out resultArray);
                     if (resultArray == null || resultArray.Size == 0)
                        return null;

                     int numResults = resultArray.Size;
                     if ((numResults > 1 && !axisIsCyclic) || (numResults > 2))
                        return null;

                     UV intersectionPoint = resultArray.get_Item(0).UVPoint;
                     endParameters[jj][1] = intersectionPoint.U;
                     endParameters[(jj + 1) % 4][0] = intersectionPoint.V;

                     if (numResults == 2)
                     {
                        // If the current result is closer to the end of the curve, keep it.
                        UV newIntersectionPoint = resultArray.get_Item(1).UVPoint;

                        int endParamIndex = (jj % 2);
                        double newParamToCheck = newIntersectionPoint[endParamIndex];
                        double oldParamToCheck = (endParamIndex == 0) ? endParameters[jj][1] : endParameters[(jj + 1) % 4][0];
                        double currentEndPoint = (endParamIndex == 0) ?
                            orientedCurveList[jj].GetEndParameter(1) : orientedCurveList[(jj + 1) % 4].GetEndParameter(0);

                        // Put in range of [-Period/2, Period/2].
                        double newDist = (currentEndPoint - newParamToCheck) % axisCurvePeriod;
                        if (newDist < -axisCurvePeriod / 2.0) newDist += axisCurvePeriod;
                        if (newDist > axisCurvePeriod / 2.0) newDist -= axisCurvePeriod;

                        double oldDist = (currentEndPoint - oldParamToCheck) % axisCurvePeriod;
                        if (oldDist < -axisCurvePeriod / 2.0) oldDist += axisCurvePeriod;
                        if (oldDist > axisCurvePeriod / 2.0) oldDist -= axisCurvePeriod;

                        if (Math.Abs(newDist) < Math.Abs(oldDist))
                        {
                           endParameters[jj][1] = newIntersectionPoint.U;
                           endParameters[(jj + 1) % 4][0] = newIntersectionPoint.V;
                        }
                     }
                  }

                  CurveLoop newCurveLoop = new CurveLoop();
                  for (int jj = 0; jj < 4; jj++)
                  {
                     if (endParameters[jj][1] < endParameters[jj][0])
                     {
                        if (!outline[jj].IsCyclic)
                           return null;
                        endParameters[jj][1] += Math.Floor(endParameters[jj][0] / axisCurvePeriod + 1.0) * axisCurvePeriod;
                     }

                     outline[jj].MakeBound(endParameters[jj][0], endParameters[jj][1]);
                     newCurveLoop.Append(outline[jj]);
                  }

                  currLoops = new List<CurveLoop>();
                  currLoops.Add(newCurveLoop);

                  extrusionDistance = currDepth;
               }

               // Determine the material id.
               IFCMaterial material = materialLayer.Material;
               ElementId layerMaterialId = (material == null) ? ElementId.InvalidElementId : material.GetMaterialElementId();

               // The second option here is really for Referencing.  Without a UI (yet) to determine whether to show the base
               // extusion or the layers for objects with material layer sets, we've chosen to display the base material if the layer material
               // has no color information.  This means that the layer is assigned the "wrong" material, but looks better on screen.
               // We will reexamine this decision (1) for the Open case, (2) if there is UI to toggle between layers and base extrusion, or
               // (3) based on user feedback.
               if (layerMaterialId == ElementId.InvalidElementId || Importer.TheCache.MaterialsWithNoColor.Contains(layerMaterialId))
                  layerMaterialId = baseMaterialId;

               SolidOptions solidOptions = new SolidOptions(layerMaterialId, shapeEditScope.GraphicsStyleId);

               // Create the extrusion for the material layer.
               GeometryObject extrusionSolid = GeometryCreationUtilities.CreateExtrusionGeometry(
                   currLoops, materialExtrusionDirection, extrusionDistance, solidOptions);
               if (extrusionSolid == null)
                  return null;

               extrusionSolids.Add(extrusionSolid);
               depthSoFar += depth;
            }
         }
         catch
         {
            // Ignore the specific exception, but let the user know there was a problem processing the IfcMaterialLayerSetUsage.
            shouldWarn = true;
            return null;
         }

         return extrusionSolids;
      }
        private static IList<CurveLoop> GetBoundaryLoopsFromBaseCurve(Wall wallElement, 
            IList<IList<IFCConnectedWallData>> connectedWalls,
            Curve baseCurve,
            Curve trimmedCurve,
            double unscaledWidth,
            double scaledDepth)
        {
            // If we don't have connected wall information, we can't clip them away.  Abort.
            if (connectedWalls == null)
                return null;

            Curve axisCurve = MaybeStretchBaseCurve(baseCurve, trimmedCurve);
            if (axisCurve == null)
                return null;

            // Create the extruded wall minus the wall joins.
            Solid baseSolid = CreateWallEndClippedWallGeometry(wallElement, connectedWalls, axisCurve, unscaledWidth, scaledDepth);
            if (baseSolid == null)
                return null;

            // Get the one face pointing in the -Z direction.  If there are multiple, abort.
            IList<CurveLoop> boundaryLoops = new List<CurveLoop>();
            foreach (Face potentialBaseFace in baseSolid.Faces)
            {
                if (potentialBaseFace is PlanarFace)
                {
                    PlanarFace planarFace = potentialBaseFace as PlanarFace;
                    if (planarFace.Normal.IsAlmostEqualTo(-XYZ.BasisZ))
                    {
                        if (boundaryLoops.Count > 0)
                            return null;

                        try
                        {
                            foreach (EdgeArray edgeLoop in planarFace.EdgeLoops)
                            {
                                bool hasCurve = false;
                                CurveLoop curveLoop = new CurveLoop();
                                foreach (Edge edge in edgeLoop)
                                {
                                    Curve edgeCurve = edge.AsCurveFollowingFace(planarFace);
                                    if (edgeCurve == null)
                                        return null;

                                    curveLoop.Append(edgeCurve);
                                    hasCurve = true;
                                }

                                if (!hasCurve)
                                    return null;

                                boundaryLoops.Add(curveLoop);
                            }
                        }
                        catch
                        {
                            return null;
                        }
                    }
                }
            }

            return boundaryLoops;
        }
Beispiel #37
0
        /// <summary>
        /// Create Hatch
        /// </summary>
        /// <param name="hatch"></param>
        /// <returns></returns>
        public static Element Create(this Grevit.Types.Hatch hatch)
        {
            // Get all Filled region types
            FilteredElementCollector collector = new FilteredElementCollector(GrevitBuildModel.document).OfClass(typeof(Autodesk.Revit.DB.FilledRegionType));
            
            // Get the View to place the hatch on
            Element viewElement = GrevitBuildModel.document.GetElementByName(typeof(Autodesk.Revit.DB.View), hatch.view);

            // Get the hatch pattern name and set it to solid if the hatch pattern name is invalid
            string patternname = (hatch.pattern == null || hatch.pattern == string.Empty) ? patternname = "Solid fill" : hatch.pattern;

            // Get the fill pattern element and filled region type
            FillPatternElement fillPatternElement = FillPatternElement.GetFillPatternElementByName(GrevitBuildModel.document, FillPatternTarget.Drafting, patternname);
            FilledRegionType filledRegionType = collector.FirstElement() as FilledRegionType;

            // Setup a new curveloop for the outline
            CurveLoop curveLoop = new CurveLoop();
            List<CurveLoop> listOfCurves = new List<CurveLoop>();

            // Get a closed loop from the grevit points
            for (int i = 0; i < hatch.outline.Count; i++)
            {
                int j = i + 1;
                Grevit.Types.Point p1 = hatch.outline[i];
                if (j == hatch.outline.Count) j = 0;
                Grevit.Types.Point p2 = hatch.outline[j];

                Curve cn = Autodesk.Revit.DB.Line.CreateBound(p1.ToXYZ(), p2.ToXYZ());
                curveLoop.Append(cn);
            }

            listOfCurves.Add(curveLoop);
            
            // Create a filled region from the loop
            return FilledRegion.Create(GrevitBuildModel.document, filledRegionType.Id, viewElement.Id, listOfCurves);

        }
      /// <summary>
      /// Creates an open or closed CurveLoop from a list of vertices.
      /// </summary>
      /// <param name="pointXYZs">The list of vertices.</param>
      /// <param name="points">The optional list of IFCAnyHandles that generated the vertices, used solely for error reporting.</param>
      /// <param name="id">The id of the IFCAnyHandle associated with the CurveLoop.</param>
      /// <param name="closeCurve">True if the loop needs a segment between the last point and the first point.</param>
      /// <returns>The new curve loop.</returns>
      /// <remarks>If closeCurve is true, there will be pointsXyz.Count line segments.  Otherwise, there will be pointsXyz.Count-1.</remarks>
      public static CurveLoop CreatePolyCurveLoop(IList<XYZ> pointXYZs, IList<IFCAnyHandle> points, int id, bool closeCurve)
      {
         int numPoints = pointXYZs.Count;
         if (numPoints < 2)
         {
            // TODO: log warning
            return null;
         }

         IList<int> badIds = new List<int>();

         // The input polycurve loop may or may not repeat the start/end point.
         // wasAlreadyClosed checks if the point was repeated.
         bool wasAlreadyClosed = pointXYZs[0].IsAlmostEqualTo(pointXYZs[numPoints - 1]);

         bool wasClosed = closeCurve ? true : wasAlreadyClosed;

         // We expect at least 3 points if the curve is closed, 2 otherwise.
         int numMinPoints = wasAlreadyClosed ? 4 : (closeCurve ? 3 : 2);
         if (numPoints < numMinPoints)
         {
            // TODO: log warning
            return null;
         }

         // Check distance between points; remove too-close points, and warn if result is non-collinear.
         // Always include first point.
         IList<XYZ> finalPoints = new List<XYZ>();
         finalPoints.Add(pointXYZs[0]);
         int numNewPoints = 1;

         int numPointsToCheck = closeCurve ? numPoints + 1 : numPoints;
         for (int ii = 1; ii < numPointsToCheck; ii++)
         {
            int nextIndex = (ii % numPoints);
            int nextNextIndex = (nextIndex == numPoints-1 && wasAlreadyClosed) ? 1 : ((ii + 1) % numPoints);
            
            // Only check if the last segment overlaps the first segment if we have a closed curve.
            bool doSegmentOverlapCheck = (ii < numPointsToCheck - 1) || wasClosed;
            if (LineSegmentIsTooShort(finalPoints[numNewPoints - 1], pointXYZs[nextIndex]) || 
               (doSegmentOverlapCheck && LineSegmentsOverlap(finalPoints[numNewPoints - 1], pointXYZs[nextIndex], pointXYZs[nextNextIndex])))
            {
               if (points != null)
                  badIds.Add(points[nextIndex].StepId);
               else
                  badIds.Add(nextIndex + 1);
            }
            else
            {
               finalPoints.Add(pointXYZs[nextIndex]);
               numNewPoints++;
            }
         }

         // Check final segment; if too short, delete 2nd to last point instead of the last.
         if (wasClosed)
         {
            if (numNewPoints < 4)
               return null;

            bool isClosed = finalPoints[numNewPoints - 1].IsAlmostEqualTo(finalPoints[0]);  // Do we have a closed loop now?
            if (wasClosed && !isClosed)   // If we had a closed loop, and now we don't, fix it up.
            {
               // Presumably, the second-to-last point had to be very close to the last point, or we wouldn't have removed the last point.
               // So instead of creating a too-short segment, we replace the last point of the new point list with the last point of the original point list.
               finalPoints[numNewPoints - 1] = pointXYZs[numPoints - 1];

               // Now we have to check that we didn't inadvertently make a "too-short" segment.
               for (int ii = numNewPoints - 1; ii > 0; ii--)
               {
                  if (IFCGeometryUtil.LineSegmentIsTooShort(finalPoints[ii], finalPoints[ii - 1]))
                  {
                     // TODO: log this removal.
                     finalPoints.RemoveAt(ii - 1); // Remove the intermediate point, not the last point.
                     numNewPoints--;
                  }
                  else
                     break;   // We are in the clear, unless we removed too many points - we've already checked the rest of the loop.
               }
            }

            if (numNewPoints < 4)
               return null;
         }

         // This can be a very common warning, so we will restrict to verbose logging.
         if (Importer.TheOptions.VerboseLogging)
         {
            if (badIds.Count > 0)
            {
               int count = badIds.Count;
               string msg = null;
               if (count == 1)
               {
                  msg = "Polyline had 1 point that was too close to one of its neighbors, removing point: #" + badIds[0] + ".";
               }
               else
               {
                  msg = "Polyline had " + count + " points that were too close to one of their neighbors, removing points:";
                  foreach (int badId in badIds)
                     msg += " #" + badId;
                  msg += ".";
               }
               Importer.TheLog.LogWarning(id, msg, false);
            }
         }

         if (numNewPoints < numMinPoints)
         {
            if (Importer.TheOptions.VerboseLogging)
            {
               string msg = "PolyCurve had " + numNewPoints + " point(s) after removing points that were too close, expected at least " + numMinPoints + ", ignoring.";
               Importer.TheLog.LogWarning(id, msg, false);
            }
            return null;
         }

         CurveLoop curveLoop = new CurveLoop();
         for (int ii = 0; ii < numNewPoints - 1; ii++)
            curveLoop.Append(Line.CreateBound(finalPoints[ii], finalPoints[ii + 1]));

         return curveLoop;
      }
Beispiel #39
0
        /// <summary>
        /// Returns a CurveLoop that has potentially been trimmed.
        /// </summary>
        /// <param name="origCurveLoop">The original curve loop.</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>
        public static CurveLoop TrimCurveLoop(CurveLoop origCurveLoop, double startVal, double? origEndVal)
        {
            // Trivial case: no trimming.
            if (!origEndVal.HasValue && MathUtil.IsAlmostZero(startVal))
                return origCurveLoop;

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

            double totalParamLength = 0.0;
            foreach (Curve curve in origCurveLoop)
            {
                double currLength = ScaleCurveLengthForSweptSolid(curve, curve.GetEndParameter(1) - curve.GetEndParameter(0));
                loopCurves.Add(curve);
                curveLengths.Add(currLength);
                totalParamLength += currLength;
            }

            double endVal = origEndVal.HasValue ? origEndVal.Value : totalParamLength;

            // This check allows for some leniency in the setting of startVal and endVal; we assume that if the parameter range
            // is equal, that an offset value is OK.
            if (MathUtil.IsAlmostEqual(endVal - startVal, totalParamLength))
                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 + MathUtil.Eps())
                    {
                        currentPosition += curveLengths[currCurve];
                        continue;
                    }

                    Curve newCurve = loopCurves[currCurve].Clone();
                    if (!MathUtil.IsAlmostEqual(currentPosition, startVal))
                        newCurve.MakeBound(UnscaleSweptSolidCurveParam(loopCurves[currCurve], startVal - currentPosition), newCurve.GetEndParameter(1));

                    newLoopCurves.Add(newCurve);
                    break;
                }
            }

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

                    Curve newCurve = loopCurves[currCurve].Clone();
                    if (!MathUtil.IsAlmostEqual(currentPosition + curveLengths[currCurve], endVal))
                        newCurve.MakeBound(newCurve.GetEndParameter(0), UnscaleSweptSolidCurveParam(loopCurves[currCurve], endVal - currentPosition));

                    newLoopCurves.Add(newCurve);
                    break;
                }
            }

            CurveLoop trimmedCurveLoop = new CurveLoop();
            foreach (Curve curve in loopCurves)
                trimmedCurveLoop.Append(curve);
            return trimmedCurveLoop;
        }
        /// <summary>
        /// Get the curve or CurveLoop representation of IFCCurve, as a CurveLoop.  This will have a value, as long as Curve or CurveLoop do.
        /// </summary>
        public CurveLoop GetCurveLoop()
        {
            if (CurveLoop != null)
                return CurveLoop;
            if (Curve == null)
                return null;

            CurveLoop curveAsCurveLoop = new CurveLoop();
            curveAsCurveLoop.Append(Curve);
            return curveAsCurveLoop;
        }
Beispiel #41
0
        private CurveLoop CreateFilletedRectangleCurveLoop(XYZ[] corners, double filletRadius)
        {
            int sz = corners.Count();
            if (sz != 4)
                return null;

            XYZ[] radii = new XYZ[4] { 
                new XYZ( corners[0].X + filletRadius, corners[0].Y + filletRadius, 0.0 ),
                new XYZ( corners[1].X - filletRadius, corners[1].Y + filletRadius, 0.0 ),
                new XYZ( corners[2].X - filletRadius, corners[2].Y - filletRadius, 0.0 ),
                new XYZ( corners[3].X + filletRadius, corners[3].Y - filletRadius, 0.0 ),
            };

            XYZ[] fillets = new XYZ[8] { 
                new XYZ( corners[0].X, corners[0].Y + filletRadius, 0.0 ),
                new XYZ( corners[0].X + filletRadius, corners[0].Y, 0.0 ),
                new XYZ( corners[1].X - filletRadius, corners[1].Y, 0.0 ),
                new XYZ( corners[1].X, corners[1].Y + filletRadius, 0.0 ),
                new XYZ( corners[2].X, corners[2].Y - filletRadius, 0.0 ),
                new XYZ( corners[2].X - filletRadius, corners[2].Y, 0.0 ),
                new XYZ( corners[3].X + filletRadius, corners[3].Y, 0.0 ),
                new XYZ( corners[3].X, corners[3].Y - filletRadius, 0.0 )
            };

            CurveLoop curveLoop = new CurveLoop();
            for (int ii = 0; ii < 4; ii++)
            {
                curveLoop.Append(Line.CreateBound(fillets[ii * 2 + 1], fillets[(ii * 2 + 2) % 8]));
                double startAngle = Math.PI * ((ii + 3) % 4) / 2;
                curveLoop.Append(CreateXYArc(radii[(ii + 1) % 4], filletRadius, startAngle, startAngle + Math.PI / 2));
            }

            return curveLoop;
        }
Beispiel #42
0
        private void ProcessIFCCircleProfileDef(IFCAnyHandle profileDef)
        {
            bool found = false;
            double radius = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "Radius", out found);
            if (!found)
                return;

            if (radius < MathUtil.Eps())
            {
                IFCImportFile.TheLog.LogError(Id, "IfcCircleProfileDef has invalid radius: " + radius + ", ignoring.", false);
                return;
            }

            // Some internal routines want CurveLoops with bounded components.  Split to avoid problems.
            OuterCurve = new CurveLoop();
            OuterCurve.Append(CreateXYArc(XYZ.Zero, radius, 0, Math.PI));
            OuterCurve.Append(CreateXYArc(XYZ.Zero, radius, Math.PI, 2 * Math.PI));

            if (IFCAnyHandleUtil.IsSubTypeOf(profileDef, IFCEntityType.IfcCircleHollowProfileDef))
            {
                double wallThickness = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "WallThickness", 0.0);
                if (wallThickness > MathUtil.Eps() && wallThickness < radius)
                {
                    double innerRadius = radius - wallThickness;

                    CurveLoop innerCurve = new CurveLoop();
                    innerCurve.Append(CreateXYArc(XYZ.Zero, innerRadius, 0, Math.PI));
                    innerCurve.Append(CreateXYArc(XYZ.Zero, innerRadius, Math.PI, 2 * Math.PI));

                    InnerCurves.Add(innerCurve);
                }
            }
        }
Beispiel #43
0
        private void ProcessIFCEllipseProfileDef(IFCAnyHandle profileDef)
        {
            bool found = false;
            double radiusX = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "SemiAxis1", out found);
            if (!found)
                return;

            double radiusY = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "SemiAxis2", out found);
            if (!found)
                return;
            
            // Some internal routines want CurveLoops with bounded components.  Split to avoid problems.
            OuterCurve = new CurveLoop();
            OuterCurve.Append(CreateXYEllipse(XYZ.Zero, radiusX, radiusY, 0, Math.PI));
            OuterCurve.Append(CreateXYEllipse(XYZ.Zero, radiusX, radiusY, Math.PI, 2 * Math.PI));
        }
        private IList<GeometryObject> SplitSweptDiskIntoValidPieces(CurveLoop trimmedDirectrixInWCS, IList<CurveLoop> profileCurveLoops, SolidOptions solidOptions)
        {
           // If we have 0 or 1 curves, there is nothing we can do here.
           int numCurves = trimmedDirectrixInWCS.Count();
           if (numCurves < 2)
              return null;

           // We will attempt to represent the original description in as few pieces as possible.  
           IList<Curve> directrixCurves = new List<Curve>();
           foreach (Curve directrixCurve in trimmedDirectrixInWCS)
           {
              if (directrixCurve == null)
              {
                 numCurves--;
                 if (numCurves < 2)
                    return null;
                 continue;
              }
              directrixCurves.Add(directrixCurve);
           }

           IList<GeometryObject> sweptDiskPieces = new List<GeometryObject>();

           // We will march along the directrix one curve at a time, trying to build a bigger piece of the sweep.  At the point that we throw an exception,
           // we will take the last biggest piece and start over.
           CurveLoop currentCurveLoop = new CurveLoop();
           Solid bestSolidSoFar = null;
           double pathAttachmentParam = directrixCurves[0].GetEndParameter(0);

           for (int ii = 0; ii < numCurves; ii++)
           {
              currentCurveLoop.Append(directrixCurves[ii]);
              try
              {
                 Solid currentSolid = GeometryCreationUtilities.CreateSweptGeometry(currentCurveLoop, 0, pathAttachmentParam, profileCurveLoops,
                    solidOptions);
                 bestSolidSoFar = currentSolid;
              }
              catch
              {
                 if (bestSolidSoFar != null)
                 {
                    sweptDiskPieces.Add(bestSolidSoFar);
                    bestSolidSoFar = null;
                 }
              }

              // This should only happen as a result of the catch loop above.  We want to protect against the case where one or more pieces of the sweep 
              // are completely invalid.
              while (bestSolidSoFar == null && (ii < numCurves))
              {
                 try
                 {
                    currentCurveLoop = new CurveLoop();
                    currentCurveLoop.Append(directrixCurves[ii]);
                    profileCurveLoops = CreateProfileCurveLoopsForDirectrix(directrixCurves[ii], out pathAttachmentParam);

                    Solid currentSolid = GeometryCreationUtilities.CreateSweptGeometry(currentCurveLoop, 0, pathAttachmentParam, profileCurveLoops,
                       solidOptions);
                    bestSolidSoFar = currentSolid;
                    break;
                 }
                 catch
                 {
                    ii++;
                 }
              }
           }

           return sweptDiskPieces;
        }
Beispiel #45
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, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>Zero or more created geometries.</returns>
        protected override IList<GeometryObject> CreateGeometryInternal(
              IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            Transform sweptDiskPosition = (lcs == null) ? Transform.Identity : lcs;

            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, sweptDiskPosition);

            // Create the disk.
            Transform originTrf = null;
            double startParam = 0.0; // If the directrix isn't bound, this arbitrary parameter will do.
            foreach (Curve curve in trimmedDirectrixInLCS)
            {
                if (curve.IsBound)
                    startParam = curve.GetEndParameter(0);
                originTrf = curve.ComputeDerivatives(startParam, false);
                break;
            }

            if (originTrf == null)
                return null;

            // The X-dir of the transform of the start of the directrix will form the normal of the disk.
            Plane diskPlane = new Plane(originTrf.BasisX, originTrf.Origin);

            IList<CurveLoop> profileCurveLoops = new List<CurveLoop>();

            CurveLoop diskOuterCurveLoop = new CurveLoop();
            diskOuterCurveLoop.Append(Arc.Create(diskPlane, Radius, 0, Math.PI));
            diskOuterCurveLoop.Append(Arc.Create(diskPlane, Radius, Math.PI, 2.0 * Math.PI));
            profileCurveLoops.Add(diskOuterCurveLoop);
            
            if (InnerRadius.HasValue)
            {
                CurveLoop diskInnerCurveLoop = new CurveLoop();
                diskInnerCurveLoop.Append(Arc.Create(diskPlane, InnerRadius.Value, 0, Math.PI));
                diskInnerCurveLoop.Append(Arc.Create(diskPlane, InnerRadius.Value, Math.PI, 2.0 * Math.PI));
                profileCurveLoops.Add(diskInnerCurveLoop);
            }

            SolidOptions solidOptions = new SolidOptions(GetMaterialElementId(shapeEditScope), shapeEditScope.GraphicsStyleId);
            Solid sweptDiskSolid = GeometryCreationUtilities.CreateSweptGeometry(trimmedDirectrixInLCS, 0, startParam, profileCurveLoops,
                solidOptions);

            IList<GeometryObject> myObjs = new List<GeometryObject>();
            if (sweptDiskSolid != null)
                myObjs.Add(sweptDiskSolid);
            return myObjs;
        }
Beispiel #46
0
 private void AddCurveToLoopInternal(CurveLoop curveLoop, Curve curve, bool initialReverse, bool tryReversed)
 {
     try
     {
         if (tryReversed != initialReverse)
             curveLoop.Append(curve.CreateReversed());
         else
             curveLoop.Append(curve);
     }
     catch (Exception ex)
     {
         if (ex.Message.Contains("not contiguous"))
         {
             if (!tryReversed)
                 AddCurveToLoopInternal(curveLoop, curve, initialReverse, true);
             else
                 throw ex;
         }
     }
 }
      /// <summary>
      /// Return a solid corresponding to the volume represented by boundingBoxXYZ. 
      /// </summary>
      /// <param name="lcs">The local coordinate system of the bounding box; if null, assume the Identity transform.</param>
      /// <param name="boundingBoxXYZ">The bounding box.</param>
      /// <param name="solidOptions">The options for creating the solid.  Allow null to mean default.</param>
      /// <returns>A solid of the same size and orientation as boundingBoxXYZ, or null if boundingBoxXYZ is invalid or null.</returns>
      /// <remarks>We don't do any checking on the input transform, which could have non-uniform scaling and/or mirroring.
      /// This could potentially lead to unexpected results, which we can examine if and when such cases arise.</remarks>
      public static Solid CreateSolidFromBoundingBox(Transform lcs, BoundingBoxXYZ boundingBoxXYZ, SolidOptions solidOptions)
      {
         // Check that the bounding box is valid.
         if (boundingBoxXYZ == null || !boundingBoxXYZ.Enabled)
            return null;

         try
         {
            // Create a transform based on the incoming local coordinate system and the bounding box coordinate system.
            Transform bboxTransform = (lcs == null) ? boundingBoxXYZ.Transform : lcs.Multiply(boundingBoxXYZ.Transform);

            XYZ[] profilePts = new XYZ[4];
            profilePts[0] = bboxTransform.OfPoint(boundingBoxXYZ.Min);
            profilePts[1] = bboxTransform.OfPoint(new XYZ(boundingBoxXYZ.Max.X, boundingBoxXYZ.Min.Y, boundingBoxXYZ.Min.Z));
            profilePts[2] = bboxTransform.OfPoint(new XYZ(boundingBoxXYZ.Max.X, boundingBoxXYZ.Max.Y, boundingBoxXYZ.Min.Z));
            profilePts[3] = bboxTransform.OfPoint(new XYZ(boundingBoxXYZ.Min.X, boundingBoxXYZ.Max.Y, boundingBoxXYZ.Min.Z));

            XYZ upperRightXYZ = bboxTransform.OfPoint(boundingBoxXYZ.Max);

            // If we assumed that the transforms had no scaling, 
            // then we could simply take boundingBoxXYZ.Max.Z - boundingBoxXYZ.Min.Z.
            // This code removes that assumption.
            XYZ origExtrusionVector = new XYZ(boundingBoxXYZ.Min.X, boundingBoxXYZ.Min.Y, boundingBoxXYZ.Max.Z) - boundingBoxXYZ.Min;
            XYZ extrusionVector = bboxTransform.OfVector(origExtrusionVector);

            double extrusionDistance = extrusionVector.GetLength();
            XYZ extrusionDirection = extrusionVector.Normalize();

            CurveLoop baseLoop = new CurveLoop();

            for (int ii = 0; ii < 4; ii++)
            {
               baseLoop.Append(Line.CreateBound(profilePts[ii], profilePts[(ii + 1) % 4]));
            }

            IList<CurveLoop> baseLoops = new List<CurveLoop>();
            baseLoops.Add(baseLoop);

            if (solidOptions == null)
               return GeometryCreationUtilities.CreateExtrusionGeometry(baseLoops, extrusionDirection, extrusionDistance);
            else
               return GeometryCreationUtilities.CreateExtrusionGeometry(baseLoops, extrusionDirection, extrusionDistance, solidOptions);
         }
         catch
         {
            return null;
         }
      }
        private static IList<CurveLoop> CoarsenCurveLoops(IList<CurveLoop> origCurveLoops)
        {
            // Coarsen loop unless we are at the Highest level of detail.
            if (ExporterCacheManager.ExportOptionsCache.LevelOfDetail >= 4)
                return origCurveLoops;

            IList<CurveLoop> modifiedLoops = new List<CurveLoop>();
            foreach (CurveLoop curveLoop in origCurveLoops)
            {
                // We don't really know if the original CurveLoop is valid, so attempting to create a copy may result in exceptions.
                // Protect against this for each individual loop.
                try
                {
                    if (curveLoop.Count() <= 24)
                    {
                        modifiedLoops.Add(curveLoop);
                        continue;
                    }

                    bool modified = false;
                    XYZ lastFirstPt = null;
                    Line lastLine = null;

                    IList<Curve> newCurves = new List<Curve>();
                    foreach (Curve curve in curveLoop)
                    {
                        // Set lastLine to be the first line in the loop, if it exists.
                        // In addition, Revit may have legacy curve segments that are too short.  Don't process them.
                        if (!(curve is Line))
                        {
                            // Break the polyline, if it existed.
                            if (lastLine != null)
                                newCurves.Add(lastLine);

                            lastLine = null;
                            lastFirstPt = null;
                            newCurves.Add(curve);
                            continue;
                        }

                        if (lastLine == null)
                        {
                            lastLine = curve as Line;
                            lastFirstPt = lastLine.GetEndPoint(0);
                            continue;
                        }

                        // If we are here, we have two lines in a row.  See if they are almost collinear.
                        XYZ currLastPt = curve.GetEndPoint(1);

                        Line combinedLine = null;

                        // If the combined curve is too short, don't merge.
                        if (currLastPt.DistanceTo(lastFirstPt) > ExporterCacheManager.Document.Application.ShortCurveTolerance)
                        {
                            combinedLine = Line.CreateBound(lastFirstPt, currLastPt);

                            XYZ currMidPt = curve.GetEndPoint(0);
                            IntersectionResult result = combinedLine.Project(currMidPt);

                            // If the absolute distance is greater than 1", or 1% of either line length, use both.
                            double dist = result.Distance;
                            if ((dist > 1.0 / 12.0) || (dist / (lastLine.Length) > 0.01) || (dist / (curve.Length) > 0.01))
                                combinedLine = null;
                        }

                        if (combinedLine == null)
                        {
                            newCurves.Add(lastLine);

                            lastLine = curve as Line;
                            lastFirstPt = lastLine.GetEndPoint(0);

                            continue;
                        }

                        // The combined line is now the last line.
                        lastLine = combinedLine;
                        modified = true;
                    }

                    if (modified)
                    {
                        if (lastLine != null)
                            newCurves.Add(lastLine);

                        CurveLoop modifiedCurveLoop = new CurveLoop();
                        foreach (Curve modifiedCurve in newCurves)
                            modifiedCurveLoop.Append(modifiedCurve);

                        modifiedLoops.Add(modifiedCurveLoop);
                    }
                    else
                    {
                        modifiedLoops.Add(curveLoop);
                    }
                }
                catch
                {
                    // If we run into any trouble, use the original loop.  
                    // TODO: this may end up failing in the ValidateCurves check that follows, so we may just skip entirely.
                    modifiedLoops.Add(curveLoop);
                }
            }

            return modifiedLoops;
        }
Beispiel #49
0
        private CurveLoop CreatePolyCurveLoop(XYZ[] corners)
        {
            int sz = corners.Count();
            if (sz == 0)
                return null;

            CurveLoop curveLoop = new CurveLoop();
            for (int ii = 0; ii < sz; ii++)
                curveLoop.Append(Line.CreateBound(corners[ii], corners[(ii + 1) % sz]));
            return curveLoop;
        }
Beispiel #50
0
        // In certain cases, Revit can't handle unbounded circles and ellipses.  Create a CurveLoop with the curve split into two segments.
        private CurveLoop CreateCurveLoopFromUnboundedCyclicCurve(Curve innerCurve)
        {
            if (innerCurve == null)
                return null;

            if (!innerCurve.IsCyclic)
                return null;

            // We don't know how to handle anything other than circles or ellipses with a period of 2PI.
            double period = innerCurve.Period;
            if (!MathUtil.IsAlmostEqual(period, Math.PI * 2.0))
                return null;

            double startParam = innerCurve.IsBound ? innerCurve.GetEndParameter(0) : 0.0;
            double endParam = innerCurve.IsBound ? innerCurve.GetEndParameter(1) : period;

            // Not a closed curve.
            if (!MathUtil.IsAlmostEqual(endParam - startParam, period))
                return null;

            Curve firstCurve = innerCurve.Clone();
            if (firstCurve == null)
                return null;

            Curve secondCurve = innerCurve.Clone();
            if (secondCurve == null)
                return null;

            firstCurve.MakeBound(0, period / 2.0);
            secondCurve.MakeBound(period / 2.0, period);

            CurveLoop innerCurveLoop = new CurveLoop();
            innerCurveLoop.Append(firstCurve);
            innerCurveLoop.Append(secondCurve);
            return innerCurveLoop;
        }
        private static CurveLoop GetFaceBoundary(Face face, EdgeArray faceBoundary, XYZ baseLoopOffset,
            bool polygonalOnly, out FaceBoundaryType faceBoundaryType)
        {
            faceBoundaryType = FaceBoundaryType.Polygonal;
            CurveLoop currLoop = new CurveLoop();
            foreach (Edge faceBoundaryEdge in faceBoundary)
            {
                Curve edgeCurve = faceBoundaryEdge.AsCurveFollowingFace(face);
                Curve offsetCurve = (baseLoopOffset != null) ? MoveCurve(edgeCurve, baseLoopOffset) : edgeCurve;
                if (!(offsetCurve is Line))
                {
                    if (polygonalOnly)
                    {
                        IList<XYZ> tessPts = offsetCurve.Tessellate();
                        int numTessPts = tessPts.Count;
                        for (int ii = 0; ii < numTessPts - 1; ii++)
                        {
                            Line line = Line.get_Bound(tessPts[ii], tessPts[ii + 1]);
                            currLoop.Append(line);
                        }
                    }
                    else
                    {
                        currLoop.Append(offsetCurve);
                    }

                    if (offsetCurve is Arc)
                        faceBoundaryType = FaceBoundaryType.LinesAndArcs;
                    else
                        faceBoundaryType = FaceBoundaryType.Complex;
                }
                else
                    currLoop.Append(offsetCurve);
            }
            return currLoop;
        }
Beispiel #52
0
        private void ProcessIFCArbitraryOpenProfileDef(IFCAnyHandle profileDef)
        {
            IFCAnyHandle curveHnd = IFCAnyHandleUtil.GetInstanceAttribute(profileDef, "Curve");
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(curveHnd))
            {
                IFCImportFile.TheLog.LogNullError(IFCEntityType.IfcArbitraryOpenProfileDef);
                return;
            }

            IFCCurve profileIFCCurve = IFCCurve.ProcessIFCCurve(curveHnd);
            CurveLoop profileCurveLoop = profileIFCCurve.CurveLoop;
            if (profileCurveLoop == null)
            {
                Curve profileCurve = profileIFCCurve.Curve;
                if (profileCurve != null)
                {
                    profileCurveLoop = new CurveLoop();
                    profileCurveLoop.Append(profileCurve);
                }
            }


            if ((profileCurveLoop != null) && IFCAnyHandleUtil.IsSubTypeOf(profileDef, IFCEntityType.IfcCenterLineProfileDef))
            {
                double? thickness = IFCAnyHandleUtil.GetDoubleAttribute(profileDef, "Thickness");
                if (!thickness.HasValue)
                {
                    //LOG: ERROR: IfcCenterLineProfileDef has no thickness defined.
                    return;
                }

                Plane plane = null;
                try
                {
                    plane = profileCurveLoop.GetPlane();
                }
                catch
                {
                    //LOG: ERROR: Curve for IfcCenterLineProfileDef is non-planar.
                    return;
                }

                double thicknessVal = IFCUnitUtil.ScaleLength(thickness.Value);
                profileCurveLoop = null;
                try
                {
                    profileCurveLoop = CurveLoop.CreateViaThicken(profileCurveLoop, thicknessVal, plane.Normal);
                }
                catch
                {
                }
            }

            if (profileCurveLoop != null)
                OuterCurve = profileCurveLoop;
            else
            {
                //LOG: ERROR: Invalid outer curve in IfcArbitraryOpenProfileDef.
                return;
            }
        }
Beispiel #53
0
        /// <summary>
        /// Creates an open or closed CurveLoop from a list of vertices.
        /// </summary>
        /// <param name="pointXYZs">The list of vertices.</param>
        /// <param name="points">The optional list of IFCAnyHandles that generated the vertices, used solely for error reporting.</param>
        /// <param name="id">The id of the IFCAnyHandle associated with the CurveLoop.</param>
        /// <param name="isClosedLoop">True if the vertices represent a closed loop, false if not.</param>
        /// <returns>The new curve loop.</returns>
        /// <remarks>If isClosedLoop is true, there will be pointsXyz.Count line segments.  Otherwise, there will be pointsXyz.Count-1.</remarks>
        public static CurveLoop CreatePolyCurveLoop(IList<XYZ> pointXYZs, IList<IFCAnyHandle> points, int id, bool isClosedLoop)
        {
            int numPoints = pointXYZs.Count;
            if (numPoints < 2)
                return null;

            IList<int> badIds = new List<int>();

            int numMinPoints = isClosedLoop ? 3 : 2;
            
            // Check distance between points; remove too-close points, and warn if result is non-collinear.
            // Always include first point.
            IList<XYZ> finalPoints = new List<XYZ>();
            finalPoints.Add(pointXYZs[0]);
            int numNewPoints = 1;
            for (int ii = 1; ii < numPoints; ii++)
            {
                if (IFCGeometryUtil.LineSegmentIsTooShort(finalPoints[numNewPoints - 1], pointXYZs[ii]))
                {
                    if (points != null)
                        badIds.Add(points[ii].StepId);
                    else
                        badIds.Add(ii+1);
                }
                else
                {
                    finalPoints.Add(pointXYZs[ii]);
                    numNewPoints++;
                }
            }

            // Check final segment; if too short, delete 2nd to last point.
            if (isClosedLoop)
            {
                if (IFCGeometryUtil.LineSegmentIsTooShort(finalPoints[numNewPoints - 1], pointXYZs[0]))
                {
                    finalPoints.RemoveAt(numNewPoints - 1);
                    numNewPoints--;
                }
            }

            // This can be a very common warning, so we will restrict to verbose logging.
            if (Importer.TheOptions.VerboseLogging)
            {
                if (badIds.Count > 0)
                {
                    int count = badIds.Count;
                    string msg = null;
                    if (count == 1)
                    {
                        msg = "Polyline had 1 point that was too close to one of its neighbors, removing point: #" + badIds[0] + ".";
                    }
                    else
                    {
                        msg = "Polyline had " + count + " points that were too close to one of their neighbors, removing points:";
                        foreach (int badId in badIds)
                            msg += " #" + badId;
                        msg += ".";
                    }
                    IFCImportFile.TheLog.LogWarning(id, msg, false);
                }
            }

            if (numNewPoints < numMinPoints)
            {
                if (Importer.TheOptions.VerboseLogging)
                {
                    string msg = "PolyCurve had " + numNewPoints + " point(s) after removing points that were too close, expected at least " + numMinPoints + ", ignoring.";
                    IFCImportFile.TheLog.LogWarning(id, msg, false);
                }
                return null;
            }

            CurveLoop curveLoop = new CurveLoop();
            for (int ii = 0; ii < numNewPoints - 1; ii++)
                curveLoop.Append(Line.CreateBound(finalPoints[ii], finalPoints[ii + 1]));
            if (isClosedLoop)
                curveLoop.Append(Line.CreateBound(finalPoints[numNewPoints - 1], finalPoints[0]));

            return curveLoop;
        }
      protected override void Process(IFCAnyHandle ifcCurve)
      {
         base.Process(ifcCurve);

         bool found = false;

         bool sameSense = IFCImportHandleUtil.GetRequiredBooleanAttribute(ifcCurve, "SenseAgreement", out found);
         if (!found)
            sameSense = true;

         IFCAnyHandle basisCurve = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcCurve, "BasisCurve", true);
         IFCCurve ifcBasisCurve = IFCCurve.ProcessIFCCurve(basisCurve);
         if (ifcBasisCurve == null || (ifcBasisCurve.Curve == null && ifcBasisCurve.CurveLoop == null))
         {
            // LOG: ERROR: Error processing BasisCurve # for IfcTrimmedCurve #.
            return;
         }
         if (ifcBasisCurve.Curve == null)
         {
            // LOG: ERROR: Expected a single curve, not a curve loop for BasisCurve # for IfcTrimmedCurve #.
            return;
         }

         IFCData trim1 = ifcCurve.GetAttribute("Trim1");
         if (trim1.PrimitiveType != IFCDataPrimitiveType.Aggregate)
         {
            // LOG: ERROR: Invalid data type for Trim1 attribute for IfcTrimmedCurve #.
            return;
         }
         IFCData trim2 = ifcCurve.GetAttribute("Trim2");
         if (trim2.PrimitiveType != IFCDataPrimitiveType.Aggregate)
         {
            // LOG: ERROR: Invalid data type for Trim1 attribute for IfcTrimmedCurve #.
            return;
         }

         IFCTrimmingPreference trimPreference = IFCEnums.GetSafeEnumerationAttribute<IFCTrimmingPreference>(ifcCurve, "MasterRepresentation", IFCTrimmingPreference.Parameter);

         double param1 = 0.0, param2 = 0.0;
         try
         {
            GetTrimParameters(trim1, trim2, ifcBasisCurve, trimPreference, out param1, out param2);
         }
         catch (Exception ex)
         {
            Importer.TheLog.LogError(ifcCurve.StepId, ex.Message, false);
            return;
         }

         Curve baseCurve = ifcBasisCurve.Curve;
         if (baseCurve.IsCyclic)
         {
            if (!sameSense)
               MathUtil.Swap(ref param1, ref param2);

            if (param2 < param1)
               param2 = MathUtil.PutInRange(param2, param1 + Math.PI, 2 * Math.PI);

            if (param2 - param1 > 2.0 * Math.PI - MathUtil.Eps())
            {
               Importer.TheLog.LogWarning(ifcCurve.StepId, "IfcTrimmedCurve length is greater than 2*PI, leaving unbound.", false);
               Curve = baseCurve;
               return;
            }

            Curve = baseCurve.Clone();

            try
            {
               Curve.MakeBound(param1, param2);
            }
            catch (Exception ex)
            {
               if (ex.Message.Contains("too small"))
               {
                  Curve = null;
                  Importer.TheLog.LogError(Id, "curve length is invalid, ignoring.", false);
                  return;
               }
               else
                  throw ex;
            }
         }
         else
         {
            if (MathUtil.IsAlmostEqual(param1, param2))
            {
               Importer.TheLog.LogError(Id, "Param1 = Param2 for IfcTrimmedCurve #, ignoring.", false);
               return;
            }

            if (param1 > param2 - MathUtil.Eps())
            {
               Importer.TheLog.LogWarning(Id, "Param1 > Param2 for IfcTrimmedCurve #, reversing.", false);
               MathUtil.Swap(ref param1, ref param2);
               return;
            }

            Curve copyCurve = baseCurve.Clone();

            double length = param2 - param1;
            if (length <= IFCImportFile.TheFile.Document.Application.ShortCurveTolerance)
            {
               string lengthAsString = IFCUnitUtil.FormatLengthAsString(length);
               Importer.TheLog.LogError(Id, "curve length of " + lengthAsString + " is invalid, ignoring.", false);
               return;
            }

            copyCurve.MakeBound(param1, param2);
            if (sameSense)
            {
               Curve = copyCurve;
            }
            else
            {
               Curve = copyCurve.CreateReversed();
            }
         }

         CurveLoop = new CurveLoop();
         CurveLoop.Append(Curve);
      }
Beispiel #55
0
        private void ProcessIFCCShapeProfileDef(IFCAnyHandle profileDef)
        {
            bool found = false;
            double depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "Depth", out found);
            if (!found)
                return;

            double width = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "Width", out found);
            if (!found)
                return;

            double wallThickness = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "WallThickness", out found);
            if (!found)
                return;

            double girth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "Girth", out found);
            if (!found)
                return;

            // Optional parameters
            double centerOptX = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "CentreOfGravityInX", 0.0);
            double innerRadius = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "InternalFilletRadius", 0.0);

            bool hasFillet = !MathUtil.IsAlmostZero(innerRadius);
            double outerRadius = hasFillet ? innerRadius + wallThickness : 0.0;

            XYZ[] cShapePoints = new XYZ[12] {
                new XYZ(width/2.0 + centerOptX, -depth/2.0+girth, 0.0),
                new XYZ(width/2.0 + centerOptX, -depth/2.0, 0.0),
                new XYZ(-width/2.0 + centerOptX, -depth/2.0, 0.0),
                new XYZ(-width/2.0 + centerOptX, depth/2.0, 0.0),
                new XYZ(width/2.0 + centerOptX, depth/2.0, 0.0),
                new XYZ(width/2.0 + centerOptX, -(-depth/2.0+girth), 0.0),
                new XYZ(width/2.0 - wallThickness, -(-depth/2.0+girth), 0.0),
                new XYZ(width/2.0 - wallThickness, depth/2.0 - wallThickness, 0.0),
                new XYZ(-width/2.0 + wallThickness, depth/2.0 - wallThickness, 0.0),
                new XYZ(-width/2.0 + wallThickness, -depth/2.0 + wallThickness, 0.0),
                new XYZ(width/2.0 - wallThickness, -depth/2.0 + wallThickness, 0.0),
                new XYZ(width/2.0 + centerOptX - wallThickness, -depth/2.0+girth, 0.0)
            };

            OuterCurve = new CurveLoop();
            if (hasFillet)
            {
                XYZ[] cFilletPoints = new XYZ[16] {
                    new XYZ(cShapePoints[1][0], cShapePoints[1][1] + outerRadius, 0.0),
                    new XYZ(cShapePoints[1][0] - outerRadius, cShapePoints[1][1], 0.0),
                    new XYZ(cShapePoints[2][0] + outerRadius, cShapePoints[2][1], 0.0),
                    new XYZ(cShapePoints[2][0], cShapePoints[2][1] + outerRadius, 0.0),
                    new XYZ(cShapePoints[3][0], cShapePoints[3][1] - outerRadius, 0.0),
                    new XYZ(cShapePoints[3][0] + outerRadius, cShapePoints[3][1], 0.0),
                    new XYZ(cShapePoints[4][0] - outerRadius, cShapePoints[4][1], 0.0),
                    new XYZ(cShapePoints[4][0], cShapePoints[4][1] - outerRadius, 0.0),
                    new XYZ(cShapePoints[7][0], cShapePoints[7][1] - innerRadius, 0.0),
                    new XYZ(cShapePoints[7][0] - innerRadius, cShapePoints[7][1], 0.0),
                    new XYZ(cShapePoints[8][0] + innerRadius, cShapePoints[8][1], 0.0),
                    new XYZ(cShapePoints[8][0], cShapePoints[8][1] - innerRadius, 0.0),
                    new XYZ(cShapePoints[9][0], cShapePoints[9][1] + innerRadius, 0.0),
                    new XYZ(cShapePoints[9][0] + innerRadius, cShapePoints[9][1], 0.0),
                    new XYZ(cShapePoints[10][0] - innerRadius, cShapePoints[10][1], 0.0),
                    new XYZ(cShapePoints[10][0], cShapePoints[10][1] + innerRadius, 0.0)
                };

                // shared for inner and outer.
                XYZ[] cFilletCenters = new XYZ[4] {
                    new XYZ(cShapePoints[1][0] - outerRadius, cShapePoints[1][1] + outerRadius, 0.0),
                    new XYZ(cShapePoints[2][0] + outerRadius, cShapePoints[2][1] + outerRadius, 0.0),
                    new XYZ(cShapePoints[3][0] + outerRadius, cShapePoints[3][1] - outerRadius, 0.0),
                    new XYZ(cShapePoints[4][0] - outerRadius, cShapePoints[4][1] - outerRadius, 0.0)
                };

                // flip outers not inners.
                double[][] cRange = new double[4][] {
                    new double[2] { 3*Math.PI/2.0, 2.0*Math.PI },
                    new double[2] { Math.PI, 3*Math.PI/2.0 },
                    new double[2] { Math.PI/2.0, Math.PI },
                    new double[2] { 0.0, Math.PI/2.0 }
                };

                OuterCurve.Append(Line.CreateBound(cShapePoints[0], cFilletPoints[0]));
                for (int ii = 0; ii < 3; ii++)
                {
                    OuterCurve.Append(CreateReversedXYArc(cFilletCenters[ii], outerRadius, cRange[ii][0], cRange[ii][1]));

                    OuterCurve.Append(Line.CreateBound(cFilletPoints[2 * ii + 1], cFilletPoints[2 * ii + 2]));

                    OuterCurve.Append(CreateReversedXYArc(cFilletCenters[3], outerRadius, cRange[3][0], cRange[3][1]));

                    OuterCurve.Append(Line.CreateBound(cFilletPoints[7], cShapePoints[5]));
                    OuterCurve.Append(Line.CreateBound(cShapePoints[5], cShapePoints[6]));
                    OuterCurve.Append(Line.CreateBound(cShapePoints[6], cFilletPoints[8]));

                    for (int jj = 0; jj < 3; ii++)
                    {
                        OuterCurve.Append(CreateXYArc(cFilletCenters[3 - jj], innerRadius, cRange[3 - jj][0], cRange[3 - jj][1]));
                        OuterCurve.Append(Line.CreateBound(cFilletPoints[2 * jj + 9], cFilletPoints[2 * jj + 10]));
                    }

                    OuterCurve.Append(CreateXYArc(cFilletCenters[0], innerRadius, cRange[0][0], cRange[0][1]));

                    OuterCurve.Append(Line.CreateBound(cFilletPoints[15], cShapePoints[11]));
                    OuterCurve.Append(Line.CreateBound(cShapePoints[11], cShapePoints[0]));
                }
            }
            else
            {
                OuterCurve = CreatePolyCurveLoop(cShapePoints);
            }
        }
Beispiel #56
0
        private void ProcessIFCZShapeProfileDef(IFCAnyHandle profileDef)
        {
            bool found = false;
            double flangeWidth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "FlangeWidth", out found);
            if (!found)
                return;

            double depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "Depth", out found);
            if (!found)
                return;

            double webThickness = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "WebThickness", out found);
            if (!found)
                return;

            double flangeThickness = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "FlangeThickness", out found);
            if (!found)
                return;

            double filletRadius = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "FilletRadius", 0.0);
            bool hasFillet = !MathUtil.IsAlmostZero(filletRadius);

            double edgeRadius = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "EdgeRadius", 0.0);
            bool hasEdgeRadius = !MathUtil.IsAlmostZero(edgeRadius);

            XYZ[] zShapePoints = new XYZ[8] {
                new XYZ(-webThickness/2.0, -depth/2.0, 0.0),
                new XYZ(flangeWidth - webThickness/2.0, -depth/2.0, 0.0),
                new XYZ(flangeWidth - webThickness/2.0, flangeThickness - depth/2.0, 0.0),
                new XYZ(webThickness/2.0, flangeThickness - depth/2.0, 0.0),
                new XYZ(webThickness/2.0, depth/2.0, 0.0),
                new XYZ(webThickness/2.0 - flangeWidth, depth/2.0, 0.0),
                new XYZ(webThickness/2.0 - flangeWidth, depth/2.0 - flangeThickness, 0.0),
                new XYZ(-webThickness/2.0, depth/2.0 - flangeThickness, 0.0)
            };
   
            // need to flip fillet arcs.
            XYZ[] zFilletPoints = new XYZ[4] {
                new XYZ(zShapePoints[3][0] + filletRadius, zShapePoints[3][1], 0.0),
                new XYZ(zShapePoints[3][0], zShapePoints[3][1] + filletRadius, 0.0),
                new XYZ(zShapePoints[7][0] - filletRadius, zShapePoints[7][1], 0.0),
                new XYZ(zShapePoints[7][0], zShapePoints[7][1] - filletRadius, 0.0)
            };

            XYZ[] zFilletCenters = new XYZ[2] {
                new XYZ(zShapePoints[3][0] + filletRadius, zShapePoints[3][1] + filletRadius, 0.0),
                new XYZ(zShapePoints[7][0] - filletRadius, zShapePoints[7][1] - filletRadius, 0.0),
            };

            double[][] filletRange = new double[2][] {
                new double[2] { Math.PI, 3*Math.PI/2.0 },
                new double[2] { 0.0, Math.PI/2.0 }
            };
   
            // do not flip edge arcs.
            XYZ[] zEdgePoints = new XYZ[4] {
                new XYZ(zShapePoints[2][0], zShapePoints[2][1] - edgeRadius, 0.0),
                new XYZ(zShapePoints[2][0] - edgeRadius, zShapePoints[2][1], 0.0),
                new XYZ(zShapePoints[6][0], zShapePoints[6][1] + edgeRadius, 0.0),
                new XYZ(zShapePoints[6][0] + edgeRadius, zShapePoints[6][1], 0.0)
            };

            XYZ[] zEdgeCenters = new XYZ[2] {
                new XYZ(zShapePoints[2][0] - edgeRadius, zShapePoints[2][1] - edgeRadius, 0.0),
                new XYZ(zShapePoints[6][0] + edgeRadius, zShapePoints[6][1] + edgeRadius, 0.0)
            };

            double[][] edgeRange = new double[2][] {
                new double[2] { 0.0, Math.PI/2.0 },
                new double[2] { Math.PI, 3*Math.PI/2.0 }
            };

            OuterCurve = new CurveLoop();

            OuterCurve.Append(Line.CreateBound(zShapePoints[0], zShapePoints[1]));
   
            XYZ zNextStart = null;
            if (hasEdgeRadius)
            {
                OuterCurve.Append(Line.CreateBound(zShapePoints[1], zEdgePoints[0]));
                OuterCurve.Append(CreateXYArc(zEdgeCenters[0], edgeRadius, edgeRange[0][0], edgeRange[0][1]));
                zNextStart = zEdgePoints[1];
            }
            else
            {
                OuterCurve.Append(Line.CreateBound(zShapePoints[1], zShapePoints[2]));
                zNextStart = zShapePoints[2];
            }
   
            if (hasFillet)
            {
                OuterCurve.Append(Line.CreateBound(zNextStart, zFilletPoints[0]));

                OuterCurve.Append(CreateReversedXYArc(zFilletCenters[0], filletRadius, filletRange[0][0], filletRange[0][1]));
                zNextStart = zFilletPoints[1];
            }
            else
            {
                OuterCurve.Append(Line.CreateBound(zNextStart, zShapePoints[3]));
                zNextStart = zShapePoints[3];
            }

            OuterCurve.Append(Line.CreateBound(zNextStart, zShapePoints[4]));
            OuterCurve.Append(Line.CreateBound(zShapePoints[4], zShapePoints[5]));

            if (hasEdgeRadius)
            {
                OuterCurve.Append(Line.CreateBound(zShapePoints[5], zEdgePoints[2]));
                OuterCurve.Append(CreateXYArc(zEdgeCenters[1], edgeRadius, edgeRange[1][0], edgeRange[1][1]));
                zNextStart = zEdgePoints[3];
            }
            else
            {
                OuterCurve.Append(Line.CreateBound(zShapePoints[5], zShapePoints[6]));
                zNextStart = zShapePoints[6];
            }
   
            if (hasFillet)
            {
                OuterCurve.Append(Line.CreateBound(zNextStart, zFilletPoints[2]));

                OuterCurve.Append(CreateReversedXYArc(zFilletCenters[1], filletRadius, filletRange[1][0], filletRange[1][1]));
                zNextStart = zFilletPoints[3];
            }
            else
            {
                OuterCurve.Append(Line.CreateBound(zNextStart, zShapePoints[7]));
                zNextStart = zShapePoints[7];
            }

            OuterCurve.Append(Line.CreateBound(zNextStart, zShapePoints[0]));
        }
        private IList<CurveLoop> CreateProfileCurveLoopsForDirectrix(Curve directrix, out double startParam)
        {
           startParam = 0.0;

           if (directrix == null)
              return null;

           if (directrix.IsBound)
              startParam = directrix.GetEndParameter(0);

           Transform originTrf = directrix.ComputeDerivatives(startParam, false);

           if (originTrf == null)
              return null;

           // The X-dir of the transform of the start of the directrix will form the normal of the disk.
           Plane diskPlane = new Plane(originTrf.BasisX, originTrf.Origin);

           IList<CurveLoop> profileCurveLoops = new List<CurveLoop>();

           CurveLoop diskOuterCurveLoop = new CurveLoop();
           diskOuterCurveLoop.Append(Arc.Create(diskPlane, Radius, 0, Math.PI));
           diskOuterCurveLoop.Append(Arc.Create(diskPlane, Radius, Math.PI, 2.0 * Math.PI));
           profileCurveLoops.Add(diskOuterCurveLoop);

           if (InnerRadius.HasValue)
           {
              CurveLoop diskInnerCurveLoop = new CurveLoop();
              diskInnerCurveLoop.Append(Arc.Create(diskPlane, InnerRadius.Value, 0, Math.PI));
              diskInnerCurveLoop.Append(Arc.Create(diskPlane, InnerRadius.Value, Math.PI, 2.0 * Math.PI));
              profileCurveLoops.Add(diskInnerCurveLoop);
           }

           return profileCurveLoops;
        }
Beispiel #58
0
        private void ProcessIFCLShapeProfileDef(IFCAnyHandle profileDef)
        {
            bool found = false;
            double depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "Depth", out found);
            if (!found)
                return;

            double thickness = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "Thickness", out found);
            if (!found)
                return;

            double width = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "Width", depth);

            double filletRadius = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "FilletRadius", 0.0);
            bool filletedCorner = !MathUtil.IsAlmostZero(filletRadius);

            double edgeRadius = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "EdgeRadius", 0.0);
            bool filletedEdge = !MathUtil.IsAlmostZero(edgeRadius);
            if (filletedEdge && (thickness < edgeRadius - MathUtil.Eps()))
            {
                // LOG: WARN: IFC: In IfcLShapeProfileDef (#id), edgeRadius (value) >= thickness (value), ignoring."
                filletedEdge = false;
            }
            bool fullFilletedEdge = (filletedEdge && MathUtil.IsAlmostEqual(thickness, edgeRadius));

            double centerOptX = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "CentreOfGravityInX", 0.0);

            double centerOptY = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "CentreOfGravityInY", centerOptX);

            // TODO: use leg slope
            double legSlope = IFCImportHandleUtil.GetOptionalScaledAngleAttribute(profileDef, "LegSlope", 0.0);
   
            XYZ lOrig = new XYZ(-width/2.0+centerOptX, -depth/2.0+centerOptY, 0.0);
            XYZ lLR = new XYZ(lOrig[0] + width, lOrig[1], 0.0);
            XYZ lLRPlusThickness = new XYZ(lLR[0], lLR[1] + thickness, 0.0);
            XYZ lCorner = new XYZ(lOrig[0] + thickness, lOrig[1] + thickness, 0.0);
            XYZ lULPlusThickness = new XYZ(lOrig[0] + thickness, lOrig[1] + depth, 0.0);
            XYZ lUL = new XYZ(lULPlusThickness[0] - thickness, lULPlusThickness[1], 0.0);

            // fillet modifications.
            double[] edgeRanges = new double[2];
            XYZ lLREdgeCtr = null, lULEdgeCtr = null;
            XYZ lLRStartFillet = null, lLREndFillet = null;
            XYZ lULStartFillet = null, lULEndFillet = null;

            if (filletedEdge)
            {
                lLREdgeCtr = new XYZ(lLRPlusThickness[0] - edgeRadius, lLRPlusThickness[1] - edgeRadius, 0.0);
                lULEdgeCtr = new XYZ(lULPlusThickness[0] - edgeRadius, lULPlusThickness[1] - edgeRadius, 0.0);

                lLRStartFillet = new XYZ(lLRPlusThickness[0], lLRPlusThickness[1] - edgeRadius, 0.0);
                lLREndFillet = new XYZ(lLRPlusThickness[0] - edgeRadius, lLRPlusThickness[1], 0.0);

                lULStartFillet = new XYZ(lULPlusThickness[0], lULPlusThickness[1] - edgeRadius, 0.0);
                lULEndFillet = new XYZ(lULPlusThickness[0] - edgeRadius, lULPlusThickness[1], 0.0);

                edgeRanges[0] = 0.0; edgeRanges[1] = Math.PI / 2.0;
            }

            XYZ lLRCorner = null, lULCorner = null, lFilletCtr = null;
            double[] filletRange = new double[2];
            if (filletedCorner)
            {
                lLRCorner = new XYZ(lCorner[0] + filletRadius, lCorner[1], lCorner[2]);
                lULCorner = new XYZ( lCorner[0], lCorner[1] + filletRadius, lCorner[2]);
                lFilletCtr = new XYZ(lCorner[0] + filletRadius, lCorner[1] + filletRadius, lCorner[2]);
                
                filletRange[0] = Math.PI; filletRange[1] = 3.0 * Math.PI / 2;
            }

            OuterCurve = new CurveLoop();

            OuterCurve.Append(Line.CreateBound(lOrig, lLR));

            XYZ startCornerPoint = null, endCornerPoint = null;
            if (filletedEdge)
            {
                startCornerPoint = lLREndFillet;
                endCornerPoint = lULStartFillet;
            }
            else
            {
                startCornerPoint = lLRPlusThickness;
                endCornerPoint = lULPlusThickness;
            }

            if (filletedEdge)
            {
                if (!fullFilletedEdge)
                {
                    OuterCurve.Append(Line.CreateBound(lLR, lLRStartFillet));
                }

                OuterCurve.Append(CreateXYArc(lLREdgeCtr, edgeRadius, edgeRanges[0], edgeRanges[1]));
            }
            else
            {
                OuterCurve.Append(Line.CreateBound(lLR, startCornerPoint));
            }

            if (filletedCorner)
            {
                OuterCurve.Append(Line.CreateBound(startCornerPoint, lLRCorner));
                OuterCurve.Append(CreateReversedXYArc(lFilletCtr, filletRadius, filletRange[0], filletRange[1]));
                OuterCurve.Append(Line.CreateBound(lULCorner, endCornerPoint));
            }
            else
            {
                OuterCurve.Append(Line.CreateBound(startCornerPoint, lCorner));
                OuterCurve.Append(Line.CreateBound(lCorner, endCornerPoint));
            }

            if (filletedEdge)
            {
                OuterCurve.Append(CreateXYArc(lULEdgeCtr, edgeRadius, edgeRanges[0], edgeRanges[1]));
                if (!fullFilletedEdge)
                {
                    OuterCurve.Append(Line.CreateBound(lULEndFillet, lUL));
                }
            }
            else
            {
                OuterCurve.Append(Line.CreateBound(endCornerPoint, lUL));
            }

            OuterCurve.Append(Line.CreateBound(lUL, lOrig));
        }
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            Transform lcs = (ObjectLocation != null) ? ObjectLocation.TotalTransform : Transform.Identity;

            // 2015+: create cone(s) for the direction of flow.
            CurveLoop rightTrangle = new CurveLoop();
            const double radius = 0.5/12.0;
            const double height = 1.5/12.0;

            SolidOptions solidOptions = new SolidOptions(ElementId.InvalidElementId, GraphicsStyleId);
            
            Frame coordinateFrame = new Frame(lcs.Origin, lcs.BasisX, lcs.BasisY, lcs.BasisZ);
            
            // The origin is at the base of the cone for everything but source - then it is at the top of the cone.
            XYZ pt1 = FlowDirection == IFCFlowDirection.Source ? lcs.Origin - height * lcs.BasisZ : lcs.Origin;
            XYZ pt2 = pt1 + radius * lcs.BasisX;
            XYZ pt3 = pt1 + height * lcs.BasisZ;
            
            rightTrangle.Append(Line.CreateBound(pt1, pt2));
            rightTrangle.Append(Line.CreateBound(pt2, pt3));
            rightTrangle.Append(Line.CreateBound(pt3, pt1));
            IList<CurveLoop> curveLoops = new List<CurveLoop>();
            curveLoops.Add(rightTrangle);

            Solid portArrow = GeometryCreationUtilities.CreateRevolvedGeometry(coordinateFrame, curveLoops, 0.0, Math.PI * 2.0, solidOptions);

            Solid oppositePortArrow = null;
            if (FlowDirection == IFCFlowDirection.SourceAndSink)
            {
                Frame oppositeCoordinateFrame = new Frame(lcs.Origin, -lcs.BasisX, lcs.BasisY, -lcs.BasisZ);
                CurveLoop oppositeRightTrangle = new CurveLoop();
                
                XYZ oppPt2 = pt1 - radius * lcs.BasisX;
                XYZ oppPt3 = pt1 - height * lcs.BasisZ;
                oppositeRightTrangle.Append(Line.CreateBound(pt1, oppPt2));
                oppositeRightTrangle.Append(Line.CreateBound(oppPt2, oppPt3));
                oppositeRightTrangle.Append(Line.CreateBound(oppPt3, pt1));
                IList<CurveLoop> oppositeCurveLoops = new List<CurveLoop>();
                oppositeCurveLoops.Add(oppositeRightTrangle);

                oppositePortArrow = GeometryCreationUtilities.CreateRevolvedGeometry(oppositeCoordinateFrame, oppositeCurveLoops, 0.0, Math.PI * 2.0, solidOptions);
            }

            if (portArrow != null)
            {
                IList<GeometryObject> geomObjs = new List<GeometryObject>();

                geomObjs.Add(portArrow);
                if (oppositePortArrow != null)
                    geomObjs.Add(oppositePortArrow);

                DirectShape directShape = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, geomObjs);
                if (directShape != null)
                {
                    CreatedGeometry = geomObjs;
                    CreatedElementId = directShape.Id;
                }
                else
                    Importer.TheLog.LogCreationError(this, null, false);
            }
        }
Beispiel #60
0
        private void ProcessIFCIShapeProfileDef(IFCAnyHandle profileDef)
        {
            bool found = false;
            double width = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "OverallWidth", out found);
            if (!found)
                return;

            double depth = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "OverallDepth", out found);
            if (!found)
                return;

            double webThickness = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "WebThickness", out found);
            if (!found)
                return;

            double flangeThickness = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(profileDef, "FlangeThickness", out found);
            if (!found)
                return;

            double filletRadius = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(profileDef, "FilletRadius", 0.0);
            bool hasFillet = !MathUtil.IsAlmostZero(filletRadius);

            // take advantage of X/Y symmetries below.
            XYZ[] iShapePoints = new XYZ[12] {
                new XYZ(-width/2.0, -depth/2.0, 0.0),
                new XYZ(width/2.0, -depth/2.0, 0.0),
                new XYZ(width/2.0, -depth/2.0 + flangeThickness, 0.0),
                new XYZ(webThickness/2.0, -depth/2.0 + flangeThickness, 0.0),

                new XYZ(webThickness/2.0, -(-depth/2.0 + flangeThickness), 0.0),
                new XYZ(width/2.0, -(-depth/2.0 + flangeThickness), 0.0),
                new XYZ(width/2.0, depth/2.0, 0.0),
                new XYZ(-width/2.0, depth/2.0, 0.0),

                new XYZ(-width/2.0,  -(-depth/2.0 + flangeThickness), 0.0),
                new XYZ(-webThickness/2.0,  -(-depth/2.0 + flangeThickness), 0.0),
                new XYZ(-webThickness/2.0,  -depth/2.0 + flangeThickness, 0.0),
                new XYZ(-width/2.0,  -depth/2.0 + flangeThickness, 0.0)
            };
   
            if (hasFillet)
            {
                OuterCurve = new CurveLoop();
                XYZ[] iFilletPoints = new XYZ[8] {
                    new XYZ(iShapePoints[3][0] + filletRadius, iShapePoints[3][1], 0.0),
                    new XYZ(iShapePoints[3][0], iShapePoints[3][1] + filletRadius, 0.0),
                    new XYZ(iShapePoints[4][0], iShapePoints[4][1] - filletRadius, 0.0),
                    new XYZ(iShapePoints[4][0] + filletRadius, iShapePoints[4][1], 0.0),
                    new XYZ(iShapePoints[9][0] - filletRadius, iShapePoints[9][1], 0.0),
                    new XYZ(iShapePoints[9][0], iShapePoints[9][1] - filletRadius, 0.0),
                    new XYZ(iShapePoints[10][0], iShapePoints[10][1] + filletRadius, 0.0),
                    new XYZ(iShapePoints[10][0] - filletRadius, iShapePoints[10][1], 0.0)
                };

                XYZ[] iFilletCtr = new XYZ[4] {
                    new XYZ(iShapePoints[3][0] + filletRadius, iShapePoints[3][1] + filletRadius, 0.0),
                    new XYZ(iShapePoints[4][0] + filletRadius, iShapePoints[4][1] - filletRadius, 0.0),
                    new XYZ(iShapePoints[9][0] - filletRadius, iShapePoints[9][1] - filletRadius, 0.0),
                    new XYZ(iShapePoints[10][0] - filletRadius, iShapePoints[10][1] + filletRadius, 0.0)
                };

                // need to flip all fillets.
                double[][] filletRanges = new double[4][] {
                    new double[2] { Math.PI, 3.0*Math.PI/2 },
                    new double[2] { Math.PI/2.0, Math.PI },
                    new double[2] { 0, Math.PI/2.0 },
                    new double[2] { 3.0*Math.PI/2, 2.0*Math.PI }
                };

                OuterCurve.Append(Line.CreateBound(iShapePoints[0], iShapePoints[1]));
                OuterCurve.Append(Line.CreateBound(iShapePoints[1], iShapePoints[2]));
                OuterCurve.Append(Line.CreateBound(iShapePoints[2], iFilletPoints[0]));

                OuterCurve.Append(CreateReversedXYArc(iFilletCtr[0], filletRadius, filletRanges[0][0], filletRanges[0][1]));
      
                OuterCurve.Append(Line.CreateBound(iFilletPoints[1], iFilletPoints[2]));
                
                OuterCurve.Append(CreateReversedXYArc(iFilletCtr[1], filletRadius, filletRanges[1][0], filletRanges[1][1]));

                OuterCurve.Append(Line.CreateBound(iFilletPoints[3], iShapePoints[5]));
                OuterCurve.Append(Line.CreateBound(iShapePoints[5], iShapePoints[6]));
                OuterCurve.Append(Line.CreateBound(iShapePoints[6], iShapePoints[7]));
                OuterCurve.Append(Line.CreateBound(iShapePoints[7], iShapePoints[8]));
                OuterCurve.Append(Line.CreateBound(iShapePoints[8], iFilletPoints[4]));

                OuterCurve.Append(CreateReversedXYArc(iFilletCtr[2], filletRadius, filletRanges[2][0], filletRanges[2][1]));

                OuterCurve.Append(Line.CreateBound(iFilletPoints[5], iFilletPoints[6]));

                OuterCurve.Append(CreateReversedXYArc(iFilletCtr[3], filletRadius, filletRanges[3][0], filletRanges[3][1]));

                OuterCurve.Append(Line.CreateBound(iFilletPoints[7], iShapePoints[11]));
                OuterCurve.Append(Line.CreateBound(iShapePoints[11], iShapePoints[0]));
            }
            else
            {
                OuterCurve = CreatePolyCurveLoop(iShapePoints);
            }
        }