示例#1
0
        /// <summary>
        /// Retrieve the room plan view boundary
        /// polygon loops and convert to 2D integer-based.
        /// For optimisation and consistency reasons,
        /// convert all coordinates to integer values in
        /// millimetres. Revit precision is limited to
        /// 1/16 of an inch, which is abaut 1.2 mm, anyway.
        /// </summary>
        static JtLoops GetRoomLoops(Room room)
        {
            SpatialElementBoundaryOptions opt
                = new SpatialElementBoundaryOptions();

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

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

            int nLoops = loops.Count;

            JtLoops jtloops = new JtLoops(nLoops);

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

                JtLoop jtloop = new JtLoop(nSegments);

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

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

                    p = seg.GetCurve().GetEndPoint(0);

                    jtloop.Add(new Point2dInt(p));

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

                    q = seg.GetCurve().GetEndPoint(1);

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

                jtloops.Add(jtloop);
            }
            return(jtloops);
        }
示例#2
0
        /// <summary>
        /// Return the outline loops of all the line segments
        /// </summary>
        public JtLoops GetOutline()
        {
            JtLoops loops = new JtLoops(1);

            while (0 < Count)
            {
                // Outline route taken so far

                List <Point2dInt> route = new List <Point2dInt>(1);

                // Start at minimum point

                route.Add(Keys.Min());

                // Recursively search until a closed outline is found

                bool closed = GetOutlineRecursion(route);

                loops.Add(new JtLoop(route.ToArray()));

                if (closed)
                {
                    // Eliminate all line segments entirely enclosed.
                    // Truncate line segments partially enclosed and remove the inner part.
                    // A line segment might cut through the entire loop, with both endpoints outside.
                }
            }
            return(loops);
        }
示例#3
0
        /// <summary>
        /// Convert Clipper polygons to JtLoops
        /// </summary>
        JtLoops ConvertToLoops(Polygons union)
        {
            JtLoops loops = new JtLoops(union.Count);
            JtLoop  loop  = new JtLoop(union.First <Polygon>().Count);

            foreach (Polygon poly in union)
            {
                loop.Clear();
                foreach (IntPoint p in poly)
                {
                    loop.Add(new Point2dInt(
                                 (int)p.X, (int)p.Y));
                }
                loops.Add(loop);
            }
            return(loops);
        }
示例#4
0
        /// <summary>
        /// Add all plan view boundary loops from
        /// given solid to the list of loops.
        /// The creation application argument is used to
        /// reverse the extrusion analyser output curves
        /// in case they are badly oriented.
        /// </summary>
        /// <returns>Number of loops added</returns>
        static int AddLoops(
            Autodesk.Revit.Creation.Application creapp,
            JtLoops loops,
            GeometryObject obj,
            ref int nExtrusionAnalysisFailures)
        {
            int nAdded = 0;

            Solid solid = obj as Solid;

            if (null != solid &&
                0 < solid.Faces.Size)
            {
                //Plane plane = new Plane(XYZ.BasisX,
                //  XYZ.BasisY, XYZ.Zero); // 2016

                Plane plane = Plane.CreateByOriginAndBasis(
                    XYZ.Zero, XYZ.BasisX, XYZ.BasisY); // 2017

                ExtrusionAnalyzer extrusionAnalyzer = null;

                try
                {
                    extrusionAnalyzer = ExtrusionAnalyzer.Create(
                        solid, plane, XYZ.BasisZ);
                }
                catch (Autodesk.Revit.Exceptions
                       .InvalidOperationException)
                {
                    ++nExtrusionAnalysisFailures;
                    return(nAdded);
                }

                Face face = extrusionAnalyzer
                            .GetExtrusionBase();

                loops.Add(GetLoop(creapp, face));

                ++nAdded;
            }
            return(nAdded);
        }
示例#5
0
        /// <summary>
        /// Retrieve all plan view boundary loops from
        /// all solids of given element united together.
        /// If the element is a family instance, transform
        /// its loops from the instance placement
        /// coordinate system back to the symbol
        /// definition one.
        /// If no geometry can be determined, use the
        /// bounding box instead.
        /// </summary>
        internal static JtLoops GetSolidPlanViewBoundaryLoops(
            Element e,
            bool transformInstanceCoordsToSymbolCoords,
            ref int nFailures)
        {
            Autodesk.Revit.Creation.Application creapp
                = e.Document.Application.Create;

            JtLoops loops = null;

            Options opt = new Options();

            GeometryElement geo = e.get_Geometry(opt);

            if (null != geo)
            {
                Document doc = e.Document;

                if (e is FamilyInstance)
                {
                    if (transformInstanceCoordsToSymbolCoords)
                    {
                        // Retrieve family instance geometry
                        // transformed back to symbol definition
                        // coordinate space by inverting the
                        // family instance placement transformation

                        LocationPoint lp = e.Location
                                           as LocationPoint;

                        Transform t = Transform.CreateTranslation(
                            -lp.Point);

                        Transform r = Transform.CreateRotationAtPoint(
                            XYZ.BasisZ, -lp.Rotation, lp.Point);

                        geo = geo.GetTransformed(t * r);
                    }
                    else
                    {
                        Debug.Assert(
                            1 == geo.Count <GeometryObject>(),
                            "expected as single geometry instance");

                        Debug.Assert(
                            geo.First <GeometryObject>() is GeometryInstance,
                            "expected as single geometry instance");

                        geo = (geo.First <GeometryObject>()
                               as GeometryInstance).GetInstanceGeometry();
                    }
                }

                loops = GetPlanViewBoundaryLoopsGeo(
                    creapp, geo, ref nFailures);
            }
            if (null == loops || 0 == loops.Count)
            {
                Debug.Print(
                    "Unable to determine geometry for "
                    + Util.ElementDescription(e)
                    + "; using bounding box instead.");

                BoundingBoxXYZ bb;

                if (e is FamilyInstance)
                {
                    bb = (e as FamilyInstance).Symbol
                         .get_BoundingBox(null);
                }
                else
                {
                    bb = e.get_BoundingBox(null);
                }
                JtLoop loop = new JtLoop(4);
                loop.Add(new Point2dInt(bb.Min));
                loop.Add(new Point2dInt(bb.Max.X, bb.Min.Y));
                loop.Add(new Point2dInt(bb.Max));
                loop.Add(new Point2dInt(bb.Min.X, bb.Max.Y));
                loops.Add(loop);
            }
            return(loops);
        }