Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument    uidoc = uiapp.ActiveUIDocument;
            Application   app   = uiapp.Application;
            Document      doc   = uidoc.Document;

            if (null == doc)
            {
                Util.ErrorMsg("Please run this command in a valid"
                              + " Revit project document.");
                return(Result.Failed);
            }

            IEnumerable <ElementId> ids
                = Util.GetSelectedRooms(uidoc);

            if ((null == ids) || (0 == ids.Count()))
            {
                return(Result.Cancelled);
            }

            View view = doc.ActiveView;

            SpatialElementBoundaryOptions seb_opt
                = new SpatialElementBoundaryOptions();

            Dictionary <int, JtLoops> booleanLoops
                = new Dictionary <int, JtLoops>(
                      ids.Count <ElementId>());

            foreach (ElementId id in ids)
            {
                Room room = doc.GetElement(id) as Room;

                JtLoops loops
                    = ClipperRvt.GetRoomOuterBoundaryLoops(
                          room, seb_opt, view);

                if (null == loops) // the room may not be bounded
                {
                    continue;
                }
                booleanLoops.Add(id.IntegerValue, loops);
            }

            JtWindowHandle hwnd = new JtWindowHandle(
                uiapp.MainWindowHandle);

            Util.CreateOutput("room_outer_outline",
                              "Room Outer Outline", doc, hwnd, booleanLoops);

            return(Result.Succeeded);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Unite two collections of boundary
        /// loops into one single one.
        /// </summary>
        public static JtLoops operator +(JtLoops a, JtLoops b)
        {
            int     na  = a.Count;
            int     nb  = b.Count;
            JtLoops sum = new JtLoops(na + nb);

            sum.AddRange(a);
            sum.AddRange(b);
            return(sum);
        }
Exemplo n.º 5
0
        /// <summary>
        /// List all the loops retrieved
        /// from the given element.
        /// </summary>
        internal static void ListLoops(Element e, JtLoops loops)
        {
            int nLoops = loops.Count;

            Debug.Print("{0} has {1}{2}",
                        Util.ElementDescription(e),
                        Util.PluralString(nLoops, "loop"),
                        Util.DotOrColon(nLoops));

            int i = 0;

            foreach (JtLoop loop in loops)
            {
                Debug.Print("  {0}: {1}", i++,
                            loop.ToString());
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Retrieve all plan view boundary loops from
        /// all solids of given element. This initial
        /// version passes each solid encountered in the
        /// given element to the ExtrusionAnalyzer one
        /// at a time, which obviously results in multiple
        /// loops, many of which are contained within the
        /// others. An updated version unites all the
        /// solids first and then uses the ExtrusionAnalyzer
        /// once only to obtain the true outside shadow
        /// contour.
        /// </summary>
        static JtLoops GetPlanViewBoundaryLoopsMultiple(
            Element e,
            ref int nFailures)
        {
            Autodesk.Revit.Creation.Application creapp
                = e.Document.Application.Create;

            JtLoops loops = new JtLoops(1);

            //int nSolids = 0;

            Options opt = new Options();

            GeometryElement geo = e.get_Geometry(opt);

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

                if (e is FamilyInstance)
                {
                    geo = geo.GetTransformed(
                        Transform.Identity);
                }

                //GeometryInstance inst = null;

                foreach (GeometryObject obj in geo)
                {
                    AddLoops(creapp, loops, obj, ref nFailures);

                    //inst = obj as GeometryInstance;
                }

                //if( 0 == nSolids && null != inst )
                //{
                //  geo = inst.GetSymbolGeometry();

                //  foreach( GeometryObject obj in geo )
                //  {
                //    AddLoops( creapp, loops, obj, ref nFailures );
                //  }
                //}
            }
            return(loops);
        }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
0
        //List<Curve> GetCurves( Element e, Options opt )
        //{
        //  GeometryElement geo = e.get_Geometry( opt );

        //  List<Curve> curves = new List<Curve>();
        //  List<Solid> solids = new List<Solid>();

        //  AddCurvesAndSolids( geo, curves, solids );

        //  return curves;
        //}

        //JtLoops GetLoops( Element e, Options opt )
        //{

        //  List<Curve> curves = GetCurves( e, opt );
        //  JtLoops loops = null;
        //  return loops;
        //}

        /// <summary>
        /// Return loops for outer 2D outline
        /// of the given element ids.
        /// - Retrieve geometry curves from edges
        /// - Convert to linear segments and 2D integer coordinates
        /// - Convert to non-intersecting line segments
        /// - Start from left-hand bottom point
        /// - Go down, then right
        /// - Keep following right-mostconection until closed loop is found
        /// </summary>
        public EdgeLoopRetriever(
            Options opt,
            ICollection <ElementId> ids)
        {
            Document doc = opt.View.Document;

            List <Curve> curves = new List <Curve>();
            List <Solid> solids = new List <Solid>();

            foreach (ElementId id in ids)
            {
                curves.Clear();
                solids.Clear();

                // Retrieve element geometry

                Element         e   = doc.GetElement(id);
                GeometryElement geo = e.get_Geometry(opt);
                AddCurvesAndSolids(geo, curves, solids);

                // Extract curves from solids

                AddCurvesFromSolids(curves, solids);

                // Flatten and simplify to line unique segments
                // of non-zero length with 2D integer millimetre
                // coordinates

                JtLineCollection lines = new JtLineCollection(
                    curves);

                // Todo: Chop at each intersection, eliminating
                // all non-endpoint intersections

                // Contour following:
                // Regardless whether loop is closed or not, add it regardless.
                // Remove the line segments forming it and all contained within it.
                // If one endpoint is within and one outside, we have a relevant intersection.
                // Remove the line segment within, and shorten the line segment outside to the lloop edge.

                JtLoops loops = lines.GetOutline();

                _loops.Add(id.IntegerValue, loops);
            }
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Retrieve plan view boundary loops from element
        /// solids using ExtrusionAnalyzer.
        /// </summary>
        static Dictionary <int, JtLoops> GetSolidLoops(
            Document doc,
            ICollection <ElementId> ids)
        {
            Dictionary <int, JtLoops> solidLoops
                = new Dictionary <int, JtLoops>();

            int nFailures;

            foreach (ElementId id in ids)
            {
                Element e = doc.GetElement(id);

                if (e is Dimension)
                {
                    continue;
                }

                Debug.Print(e.Name + " "
                            + id.IntegerValue.ToString());

                nFailures = 0;

                JtLoops loops
                    = CmdUploadRooms.GetSolidPlanViewBoundaryLoops(
                          e, false, ref nFailures);

                if (0 < nFailures)
                {
                    Debug.Print("{0}: {1}",
                                Util.ElementDescription(e),
                                Util.PluralString(nFailures,
                                                  "extrusion analyser failure"));
                }
                CmdUploadRooms.ListLoops(e, loops);

                loops.NormalizeLoops();

                solidLoops.Add(id.IntegerValue, loops);
            }
            return(solidLoops);
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Retrieve all plan view boundary loops from
        /// all solids of the given element geometry
        /// united together.
        /// </summary>
        internal static JtLoops GetPlanViewBoundaryLoopsGeo(
            Autodesk.Revit.Creation.Application creapp,
            GeometryElement geo,
            ref int nFailures)
        {
            Solid union = null;

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

            foreach (GeometryObject obj in geo)
            {
                Solid solid = obj as Solid;

                if (null != solid &&
                    0 < solid.Faces.Size)
                {
                    // Some solids, e.g. in the standard
                    // content 'Furniture Chair - Office'
                    // cause an extrusion analyser failure,
                    // so skip adding those.

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

                    if (null != solid)
                    {
                        if (null == union)
                        {
                            union = solid;
                        }
                        else
                        {
                            try
                            {
                                union = BooleanOperationsUtils
                                        .ExecuteBooleanOperation(union, solid,
                                                                 BooleanOperationsType.Union);
                            }
                            catch (Autodesk.Revit.Exceptions
                                   .InvalidOperationException)
                            {
                                ++nFailures;
                            }
                        }
                    }
                }
            }

            JtLoops loops = new JtLoops(1);

            AddLoops(creapp, loops, union, ref nFailures);

            return(loops);
        }
Exemplo n.º 13
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument    uidoc = uiapp.ActiveUIDocument;
            Application   app   = uiapp.Application;
            Document      doc   = uidoc.Document;

            if (null == doc)
            {
                Util.ErrorMsg("Please run this command in a valid"
                              + " Revit project document.");
                return(Result.Failed);
            }

            ICollection <ElementId> ids
                = Util.GetSelectedElements(uidoc);

            if ((null == ids) || (0 == ids.Count))
            {
                return(Result.Cancelled);
            }

            // Third attempt: create the element 2D outline
            // from element solid faces and meshes in current
            // view by projecting them onto the XY plane and
            // executing 2d Boolean unions on them.

            View view = doc.ActiveView;

            Options opt = new Options
            {
                View = view
            };

            Clipper                   c      = new Clipper();
            VertexLookup              vl     = new VertexLookup();
            List <LineSegment>        curves = new List <LineSegment>();
            Polygons                  union  = new Polygons();
            Dictionary <int, JtLoops> booleanLoops
                = new Dictionary <int, JtLoops>(ids.Count);

            foreach (ElementId id in ids)
            {
                Element         e   = doc.GetElement(id);
                GeometryElement geo = e.get_Geometry(opt);

                c.Clear();
                vl.Clear();
                union.Clear();

                AddToUnion(union, curves, vl, c, geo);

                //AddToUnion( union, vl, c, curves );

                //c.AddPaths( subjects, PolyType.ptSubject, true );
                //c.AddPaths( clips, PolyType.ptClip, true );

                bool succeeded = c.Execute(ClipType.ctUnion, union,
                                           PolyFillType.pftPositive, PolyFillType.pftPositive);

                if (0 == union.Count)
                {
                    Debug.Print(string.Format(
                                    "No outline found for {0} <{1}>",
                                    e.Name, e.Id.IntegerValue));
                }
                else
                {
                    JtLoops loops = ConvertToLoops(union);

                    loops.NormalizeLoops();

                    booleanLoops.Add(id.IntegerValue, loops);
                }
            }

            string filepath = Path.Combine(Util.OutputFolderPath,
                                           doc.Title + "_element_2d_boolean_outline.json");

            JtWindowHandle hwnd = new JtWindowHandle(uiapp.MainWindowHandle);

            string caption = doc.Title + " 2D Booleans";

            Util.ExportLoops(filepath, hwnd, caption,
                             doc, booleanLoops);

            return(Result.Succeeded);
        }
Exemplo n.º 14
0
        GetElementLoops(
            View view,
            ICollection <ElementId> ids)
        {
            Document doc = view.Document;

            Options opt = new Options
            {
                View = view
            };

            Clipper                   c      = new Clipper();
            VertexLookup              vl     = new VertexLookup();
            List <LineSegment>        curves = new List <LineSegment>();
            Polygons                  union  = new Polygons();
            Dictionary <int, JtLoops> booleanLoops
                = new Dictionary <int, JtLoops>(ids.Count);

            foreach (ElementId id in ids)
            {
                c.Clear();
                vl.Clear();
                union.Clear();

                Element e = doc.GetElement(id);

                if (e is Room)
                {
                    IList <IList <BoundarySegment> > boundary
                        = (e as Room).GetBoundarySegments(
                              new SpatialElementBoundaryOptions());

                    // Ignore all loops except first, which is
                    // hopefully outer -- and hopefully the room
                    // does not have several disjunct parts.

                    AddToUnionRoom(union, curves, vl, c, boundary);
                }
                else
                {
                    GeometryElement geo = e.get_Geometry(opt);
                    AddToUnion(union, curves, vl, c, geo);
                }

                //AddToUnion( union, vl, c, curves );

                //c.AddPaths( subjects, PolyType.ptSubject, true );
                //c.AddPaths( clips, PolyType.ptClip, true );

                bool succeeded = c.Execute(ClipType.ctUnion, union,
                                           PolyFillType.pftPositive, PolyFillType.pftPositive);

                if (0 == union.Count)
                {
                    Debug.Print(string.Format(
                                    "No outline found for {0} <{1}>",
                                    e.Name, e.Id.IntegerValue));
                }
                else
                {
                    JtLoops loops = ConvertToLoops(union);

                    loops.NormalizeLoops();

                    booleanLoops.Add(id.IntegerValue, loops);
                }
            }
            return(booleanLoops);
        }
Exemplo n.º 15
0
        //static List<ElementId> GetRoomBoundaryIds(
        //  Room room,
        //  SpatialElementBoundaryOptions seb_opt )
        //{
        //  List<ElementId> ids = null;

        //  IList<IList<BoundarySegment>> sloops
        //    = room.GetBoundarySegments( seb_opt );

        //  if( null != sloops ) // the room may not be bounded
        //  {
        //    Debug.Assert( 1 == sloops.Count, "this add-in "
        //      + "currently supports only rooms with one "
        //      + "single boundary loop" );

        //    ids = new List<ElementId>();

        //    foreach( IList<BoundarySegment> sloop in sloops )
        //    {
        //      foreach( BoundarySegment s in sloop )
        //      {
        //        ids.Add( s.ElementId );
        //      }

        //      // Skip out after first segement loop - ignore
        //      // rooms with holes and disjunct parts

        //      break;
        //    }
        //  }
        //  return ids;
        //}

        /// <summary>
        /// Create a JtLoop representing the 2D outline of
        /// the given room including all its bounding elements
        /// by creating the inner room boundary loop and
        /// uniting it with the bounding elements solid faces
        /// and meshes in the given view, projecting
        /// them onto the XY plane and executing 2D Boolean
        /// unions on them.
        /// </summary>
        public static JtLoops GetRoomOuterBoundaryLoops(
            Room room,
            SpatialElementBoundaryOptions seb_opt,
            View view)
        {
            Document doc = view.Document;

            Options opt = new Options
            {
                View = view
            };

            Clipper            c      = new Clipper();
            VertexLookup       vl     = new VertexLookup();
            List <LineSegment> curves = new List <LineSegment>();
            Polygons           union  = new Polygons();
            JtLoops            loops  = null;

            IList <IList <BoundarySegment> > boundary
                = room.GetBoundarySegments(
                      new SpatialElementBoundaryOptions());

            if (null != boundary) // the room may not be bounded
            {
                Debug.Assert(1 == boundary.Count,
                             "this add-in currently supports only rooms "
                             + "with one single boundary loop");

                // Ignore all loops except first, which is
                // hopefully outer -- and hopefully the room
                // does not have several disjunct parts.
                // Ignore holes in the room and
                // multiple disjunct parts.

                AddToUnionRoom(union, curves, vl, c, boundary);

                // Retrieve bounding elements

                List <ElementId> ids = new List <ElementId>();

                foreach (IList <BoundarySegment> loop in boundary)
                {
                    foreach (BoundarySegment s in loop)
                    {
                        ids.Add(s.ElementId);
                    }

                    // Skip out after first segement loop - ignore
                    // rooms with holes and disjunct parts

                    break;
                }

                foreach (ElementId id in ids)
                {
                    // Skip invalid element ids, generated, for
                    // instance, by a room separator line.

                    if (!id.Equals(ElementId.InvalidElementId))
                    {
                        Element e = doc.GetElement(id);

                        GeometryElement geo = e.get_Geometry(opt);
                        AddToUnion(union, curves, vl, c, geo);

                        bool succeeded = c.Execute(ClipType.ctUnion, union,
                                                   PolyFillType.pftPositive, PolyFillType.pftPositive);

                        if (0 == union.Count)
                        {
                            Debug.Print(string.Format(
                                            "No outline found for {0} <{1}>",
                                            e.Name, e.Id.IntegerValue));
                        }
                    }
                }
                loops = ConvertToLoops(union);

                loops.NormalizeLoops();
            }
            return(loops);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Upload the selected rooms and the furniture
        /// they contain to the cloud database.
        /// </summary>
        public static void UploadRoom(
            IntPtr hwnd,
            Document doc,
            Room room)
        {
            BoundingBoxXYZ bb = room.get_BoundingBox(null);

            if (null == bb)
            {
                Util.ErrorMsg(string.Format("Skipping room {0} "
                                            + "because it has no bounding box.",
                                            Util.ElementDescription(room)));

                return;
            }

            JtLoops roomLoops = GetRoomLoops(room);

            ListLoops(room, roomLoops);

            List <Element> furniture
                = GetFurniture(room);

            // Map symbol UniqueId to symbol loop

            Dictionary <string, JtLoop> furnitureLoops
                = new Dictionary <string, JtLoop>();

            // List of instances referring to symbols

            List <JtPlacement2dInt> furnitureInstances
                = new List <JtPlacement2dInt>(
                      furniture.Count);

            int nFailures;

            foreach (FamilyInstance f in furniture)
            {
                FamilySymbol s = f.Symbol;

                string uid = s.UniqueId;

                if (!furnitureLoops.ContainsKey(uid))
                {
                    nFailures = 0;

                    JtLoops loops = GetSolidPlanViewBoundaryLoops(
                        f, true, ref nFailures);

                    if (0 < nFailures)
                    {
                        Debug.Print("{0}: {1}",
                                    Util.ElementDescription(f),
                                    Util.PluralString(nFailures,
                                                      "extrusion analyser failure"));
                    }
                    ListLoops(f, loops);

                    if (0 < loops.Count)
                    {
                        // Assume first loop is outer one

                        furnitureLoops.Add(uid, loops[0]);
                    }
                }
                furnitureInstances.Add(
                    new JtPlacement2dInt(f));
            }
            IWin32Window revit_window
                = new JtWindowHandle(hwnd);

            string caption = doc.Title
                             + " : " + doc.GetElement(room.LevelId).Name
                             + " : " + room.Name;

            Bitmap bmp = GeoSnoop.DisplayRoom(roomLoops,
                                              furnitureLoops, furnitureInstances);

            GeoSnoop.DisplayImageInForm(revit_window,
                                        caption, false, bmp);

            //DbUpload.DbUploadRoom( room, furniture,
            //  roomLoops, furnitureLoops );
        }
Exemplo n.º 17
0
        /// <summary>
        /// Display room and the furniture contained in it
        /// in a bitmap generated on the fly.
        /// </summary>
        /// <param name="roomLoops">Room boundary loops</param>
        /// <param name="geometryLoops">Family symbol geometry</param>
        /// <param name="familyInstances">Family instances</param>
        public static Bitmap DisplayRoom(
            JtLoops roomLoops,
            Dictionary <string, JtLoop> geometryLoops,
            List <JtPlacement2dInt> familyInstances)
        {
            JtBoundingBox2dInt bbFrom = roomLoops.BoundingBox;

            // Adjust target rectangle height to the
            // displayee loop height.

            int width  = _form_width;
            int height = (int)(width * bbFrom.AspectRatio + 0.5);

            //SizeF fsize = new SizeF( width, height );

            //SizeF scaling = new SizeF( 1, 1 );
            //PointF translation = new PointF( 0, 0 );

            //GetTransform( fsize, bbFrom,
            //  ref scaling, ref translation, true );

            //Matrix transform1 = new Matrix(
            //  new Rectangle(0,0,width,height),
            //  bbFrom.GetParallelogramPoints());
            //transform1.Invert();

            // the bounding box fills the rectangle
            // perfectly and completely, inverted and
            // non-uniformly distorted:

            //Point2dInt pmin = bbFrom.Min;
            //Rectangle rect = new Rectangle(
            //  pmin.X, pmin.Y, bbFrom.Width, bbFrom.Height );
            //Point[] parallelogramPoints = new Point [] {
            //  new Point( 0, 0 ), // upper left
            //  new Point( width, 0 ), // upper right
            //  new Point( 0, height ) // lower left
            //};

            // the bounding box fills the rectangle
            // perfectly and completely, inverted and
            // non-uniformly distorted:

            // Specify transformation target rectangle
            // including a margin.

            int bottom = height - (_margin + _margin);

            Point[] parallelogramPoints = new Point[] {
                new Point(_margin, bottom),         // upper left
                new Point(width - _margin, bottom), // upper right
                new Point(_margin, _margin)         // lower left
            };

            // Transform from native loop coordinate system
            // to target display coordinates.

            Matrix transform = new Matrix(
                bbFrom.Rectangle, parallelogramPoints);

            Bitmap   bmp      = new Bitmap(width, height);
            Graphics graphics = Graphics.FromImage(bmp);

            graphics.Clear(System.Drawing.Color.White);

            DrawLoopsOnGraphics(graphics,
                                roomLoops.GetGraphicsPathLines(), transform);

            if (null != familyInstances)
            {
                List <Point[]> loops = new List <Point[]>(1);
                loops.Add(new Point[] { });

                foreach (JtPlacement2dInt i in familyInstances)
                {
                    Point2dInt v         = i.Translation;
                    Matrix     placement = new Matrix();
                    placement.Rotate(i.Rotation);
                    placement.Translate(v.X, v.Y, MatrixOrder.Append);
                    placement.Multiply(transform, MatrixOrder.Append);
                    loops[0] = geometryLoops[i.SymbolId]
                               .GetGraphicsPathLines();

                    DrawLoopsOnGraphics(graphics, loops, placement);
                }
            }
            return(bmp);
        }