コード例 #1
0
        /// <summary>
        /// Return polygon loops representing the size
        /// and location of given sheet and all the
        /// viewports it contains, regardless of type.
        /// </summary>
        static JtLoops GetSheetViewportLoops(
            SheetModelCollections modelCollections,
            ViewSheet sheet)
        {
            Document doc = sheet.Document;

            List <Viewport> viewports = sheet
                                        .GetAllViewports()
                                        .Select <ElementId, Viewport>(
                id => doc.GetElement(id) as Viewport)
                                        .ToList <Viewport>();

            int n = viewports.Count;

            modelCollections.ViewsInSheet[sheet.Id]
                = new List <ViewData>(n);

            JtLoops sheetViewportLoops = new JtLoops(n + 1);

            // sheet.get_BoundingBox( null ) returns (-100,-100),(100,100)

            BoundingBoxUV bb = sheet.Outline;                  // model coordinates (0,0), (2.76,1.95)

            JtBoundingBox2dInt ibb = new JtBoundingBox2dInt(); // millimeters (0,0),(840,...)

            ibb.ExpandToContain(new Point2dInt(bb.Min));
            ibb.ExpandToContain(new Point2dInt(bb.Max));

            JtLoop loop = new JtLoop(ibb.Corners);

            sheetViewportLoops.Add(loop);

            foreach (Viewport vp in viewports)
            {
                XYZ center = vp.GetBoxCenter(); // not used

                Outline outline = vp.GetBoxOutline();

                ibb.Init();

                ibb.ExpandToContain(
                    new Point2dInt(outline.MinimumPoint));

                ibb.ExpandToContain(
                    new Point2dInt(outline.MaximumPoint));

                loop = new JtLoop(ibb.Corners);

                sheetViewportLoops.Add(loop);

                ViewData d = new ViewData();
                d.Id = vp.ViewId;
                d.ViewportBoundingBox = loop.BoundingBox;

                modelCollections.ViewsInSheet[sheet.Id].Add(
                    d);
            }
            return(sheetViewportLoops);
        }
コード例 #2
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;

            //IWin32Window revit_window
            //  = new JtWindowHandle(
            //    ComponentManager.ApplicationWindow ); // pre-2020

            IWin32Window revit_window
                = new JtWindowHandle(uiapp.MainWindowHandle); // 2020

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

            // Interactive sheet selection.

            FrmSelectSheets form = new FrmSelectSheets(doc);

            if (DialogResult.OK == form.ShowDialog(
                    revit_window))
            {
                List <ViewSheet> sheets
                    = form.GetSelectedSheets();

                int n = sheets.Count;

                string caption = Util.PluralString(
                    n, "Sheet") + " Selected";

                string msg = string.Join(", ",
                                         sheets.Select <Element, string>(
                                             e => Util.SheetDescription(e))) + ".";

                // Determine all floor plan views displayed
                // in the selected sheets.

                Dictionary <View, int> views
                    = new Dictionary <View, int>(
                          new ElementEqualityComparer());

                int nFloorPlans = 0;

                foreach (ViewSheet sheet in sheets)
                {
                    foreach (View v in sheet.GetAllPlacedViews()
                             .Select <ElementId, View>(id =>
                                                       doc.GetElement(id) as View))
                    {
                        if (!views.ContainsKey(v))
                        {
                            if (IsFloorPlan(v))
                            {
                                ++nFloorPlans;
                            }
                            views.Add(v, 0);
                        }
                        ++views[v];
                    }
                }

                msg += (1 == n)
          ? "\nIt contains"
          : "\nThey contain";

                n = views.Count;

                msg += string.Format(
                    " {0} including {1}: ",
                    Util.PluralString(n, "view"),
                    Util.PluralString(nFloorPlans,
                                      "floor plan"));

                msg += string.Join(", ",
                                   views.Keys.Select <Element, string>(
                                       e => e.Name)) + ".";

                Util.InfoMsg2(caption, msg, false);

                // Determine all categories occurring
                // in the views displayed by the sheets.

                List <Category> categories
                    = new List <Category>(
                          new CategoryCollector(views.Keys).Keys);

                // Sort categories alphabetically by name
                // to display them in selection form.

                categories.Sort(
                    delegate(Category c1, Category c2)
                {
                    return(string.Compare(c1.Name, c2.Name));
                });

                // Interactive category selection.

                FrmSelectCategories form2
                    = new FrmSelectCategories(categories);

                if (DialogResult.OK == form2.ShowDialog(
                        revit_window))
                {
                    categories = form2.GetSelectedCategories();

                    n = categories.Count;

                    caption = Util.PluralString(n, "Category")
                              + " Selected";

                    msg = string.Join(", ",
                                      categories.Select <Category, string>(
                                          e => e.Name)) + ".";

                    Util.InfoMsg2(caption, msg, false);

                    // Convert category list to a dictionary for
                    // more effective repeated lookup.
                    //
                    //Dictionary<ElementId, Category> catLookup =
                    //  categories.ToDictionary<Category, ElementId>(
                    //    c => c.Id );
                    //
                    // No, much better: set up a reusable element
                    // filter for the categories of interest:

                    ElementFilter categoryFilter
                        = new LogicalOrFilter(categories
                                              .Select <Category, ElementCategoryFilter>(
                                                  c => new ElementCategoryFilter(c.Id))
                                              .ToList <ElementFilter>());

                    // Instantiate a container for all
                    // cloud data repository content.

                    SheetModelCollections modelCollections
                        = new SheetModelCollections(
                              DbUpload.GetProjectInfo(doc).Id);

                    foreach (ViewSheet sheet in sheets)
                    {
                        // Define preview form caption.

                        caption = "Sheet and Viewport Loops - "
                                  + Util.SheetDescription(sheet);

                        // This is currently not used for anything.

                        ListSheetAndViewTransforms(sheet);

                        // Determine the polygon loops representing
                        // the size and location of given sheet and
                        // the viewports it contains.

                        JtLoops sheetViewportLoops
                            = GetSheetViewportLoops(
                                  modelCollections, sheet);

                        // Determine graphics for family instances,
                        // their symbols and other BIM parts.

                        GetBimGraphics(modelCollections,
                                       sheet, categoryFilter);

                        // Display sheet and viewports with the
                        // geometry retrieved in a temporary GeoSnoop
                        // form generated on the fly for debugging
                        // purposes.

                        Bitmap bmp = GeoSnoop.DisplaySheet(
                            sheet.Id, sheetViewportLoops,
                            modelCollections);

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

                        // Upload data to the cloud database.

                        DbUpload.DbUploadSheet(sheet,
                                               sheetViewportLoops, modelCollections);
                    }
                    DbUpdater.SetLastSequence();
                }
            }
            return(Result.Succeeded);
        }
コード例 #3
0
        /// <summary>
        /// Determine the visible elements belonging to the
        /// specified categories in the views displayed by
        /// the given sheet and return their graphics and
        /// instance placements.
        /// Ignore all but the first geometry loop retrieved.
        /// </summary>
        /// <param name="modelCollections">Data container</param>
        /// <param name="sheet">The view sheet</param>
        /// <param name="categoryFilter">The desired categories</param>
        static void GetBimGraphics(
            SheetModelCollections modelCollections,
            ViewSheet sheet,
            ElementFilter categoryFilter)
        {
            bool list_ignored_elements = false;

            Document doc = sheet.Document;

            Autodesk.Revit.Creation.Application creapp
                = doc.Application.Create;

            Options opt = new Options();

            // There is no need and no possibility to set
            // the detail level when retrieving view geometry.
            // An attempt to specify the detail level will
            // cause writing the opt.View property to throw
            // "DetailLevel is already set. When DetailLevel
            // is set view-specific geometry can't be
            // extracted."
            //
            //opt.DetailLevel = ViewDetailLevel.Coarse;

            Debug.Print(sheet.Name);

            foreach (ViewPlan v in sheet.GetAllPlacedViews()
                     .Select <ElementId, View>(id =>
                                               doc.GetElement(id) as View)
                     .OfType <ViewPlan>()
                     .Where <ViewPlan>(v => IsFloorPlan(v)))
            {
                Debug.Print("  " + v.Name);

                modelCollections.BimelsInViews.Add(
                    v.Id, new List <ObjData>());

                opt.View = v;

                JtBoundingBox2dInt bimelBb
                    = new JtBoundingBox2dInt();

                FilteredElementCollector els
                    = new FilteredElementCollector(doc, v.Id)
                      .WherePasses(categoryFilter);

                foreach (Element e in els)
                {
                    GeometryElement geo = e.get_Geometry(opt);

                    FamilyInstance f = e as FamilyInstance;

                    if (null != f)
                    {
                        LocationPoint lp = e.Location
                                           as LocationPoint;

                        // Simply ignore family instances that
                        // have no location point or no location at
                        // all, e.g. panel.
                        // No, we should not ignore them, but
                        // treat tham as non-transformable parts.

                        if (null == lp)
                        {
                            if (list_ignored_elements)
                            {
                                Debug.Print(string.Format(
                                                "    ...  {0} has no location",
                                                e.Name));
                            }
                            f = null;

                            geo = geo.GetTransformed(
                                Transform.Identity);
                        }
                        else
                        {
                            FamilySymbol s = f.Symbol;

                            if (modelCollections.Symbols.ContainsKey(s.Id))
                            {
                                if (list_ignored_elements)
                                {
                                    Debug.Print("    ... symbol already handled "
                                                + e.Name + " --> " + s.Name);
                                }

                                // Symbol already defined, just add instance

                                JtPlacement2dInt placement
                                    = new JtPlacement2dInt(f);

                                // Expand bounding box around all BIM
                                // elements, ignoring the size of the
                                // actual geometry, assuming is is small
                                // in comparison and the insertion point
                                // lies within it.

                                bimelBb.ExpandToContain(
                                    placement.Translation);

                                InstanceData d = new InstanceData();
                                d.Id        = f.Id;
                                d.Symbol    = f.Symbol.Id;
                                d.Placement = placement;

                                modelCollections.BimelsInViews[v.Id]
                                .Add(d);

                                continue;
                            }

                            // Retrieve family instance geometry
                            // transformed back to symbol definition
                            // coordinate space by inverting the
                            // family instance placement transformation

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

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

                            geo = geo.GetTransformed(t * r);
                        }
                    }

                    int nEmptySolids    = 0;
                    int nNonEmptySolids = 0;
                    int nCurves         = 0;
                    int nOther          = 0;

                    foreach (GeometryObject obj in geo)
                    {
                        // This was true before calling GetTransformed.
                        //Debug.Assert( obj is Solid || obj is GeometryInstance, "expected only solids and instances" );

                        // This was true before calling GetTransformed.
                        //Debug.Assert( ( obj is GeometryInstance ) == ( e is FamilyInstance ), "expected all family instances to have geometry instance" );

                        Debug.Assert(obj is Solid || obj is Line || obj is Arc, "expected only solids, lines and arcs after calling GetTransformed on instances");

                        // Todo: handle arcs, e.g. tessellate

                        Debug.Assert(Visibility.Visible == obj.Visibility, "expected only visible geometry objects");

                        Debug.Assert(obj.IsElementGeometry, "expected only element geometry");
                        //bool isElementGeometry = obj.IsElementGeometry;

                        Solid solid = obj as Solid;

                        if (null != solid)
                        {
                            if (0 < solid.Edges.Size)
                            {
                                ++nNonEmptySolids;
                            }
                            else
                            {
                                ++nEmptySolids;
                            }
                        }
                        else if (obj is Curve)
                        {
                            ++nCurves;
                        }
                        else
                        {
                            ++nOther;
                        }
                    }

                    Debug.Print("    {0}: {1} non-emtpy solids, "
                                + "{2} empty, {3} curves, {4} other",
                                e.Name, nNonEmptySolids, nEmptySolids,
                                nCurves, nOther);

                    JtLoops loops = null;

                    if (1 == nNonEmptySolids &&
                        0 == nEmptySolids + nCurves + nOther)
                    {
                        int nFailures = 0;

                        loops = CmdUploadRooms
                                .GetPlanViewBoundaryLoopsGeo(
                            creapp, geo, ref nFailures);
                    }
                    else
                    {
                        double z     = double.MinValue;
                        bool   first = true;

                        foreach (GeometryObject obj in geo)
                        {
                            // Do we need the graphics style?
                            // It might give us horrible things like
                            // colours etc.

                            ElementId id = obj.GraphicsStyleId;

                            //Debug.Print( "      " + obj.GetType().Name );

                            Solid solid = obj as Solid;

                            if (null == solid)
                            {
                                #region Debug code to ensure horizontal co-planar curves
#if DEBUG
                                Debug.Assert(obj is Line || obj is Arc, "expected only lines and arcs here");

                                Curve c = obj as Curve;

                                if (first)
                                {
                                    z = c.GetEndPoint(0).Z;

                                    Debug.Assert(Util.IsEqual(z, c.GetEndPoint(1).Z),
                                                 "expected a plan view with all Z values equal");

                                    first = false;
                                }
                                else
                                {
                                    Debug.Assert(Util.IsEqual(z, c.GetEndPoint(0).Z),
                                                 "expected a plan view with all Z values equal");

                                    Debug.Assert(Util.IsEqual(z, c.GetEndPoint(1).Z),
                                                 "expected a plan view with all Z values equal");
                                }

                                Debug.Print("      {0} {1}",
                                            obj.GetType().Name,
                                            Util.CurveEndpointString(c));
#endif // DEBUG
                                #endregion // Debug code to ensure horizontal co-planar curves
                            }
                            else if (1 == solid.Faces.Size)
                            {
                                Debug.Print(
                                    "      solid with 1 face");

                                foreach (Face face in solid.Faces)
                                {
                                    #region Debug code to print out face edges
#if DEBUG
                                    foreach (EdgeArray loop in
                                             face.EdgeLoops)
                                    {
                                        foreach (Edge edge in loop)
                                        {
                                            // This returns the curves already
                                            // correctly oriented:

                                            Curve c = edge
                                                      .AsCurveFollowingFace(face);

                                            Debug.Print("        {0}: {1} {2}",
                                                        edge.GetType().Name,
                                                        c.GetType().Name,
                                                        Util.CurveEndpointString(c));
                                        }
                                    }
#endif // DEBUG
                                    #endregion // Debug code to print out face edges

                                    if (null == loops)
                                    {
                                        loops = new JtLoops(1);
                                    }
                                    loops.Add(CmdUploadRooms.GetLoop(
                                                  creapp, face));
                                }
                            }
                            else
                            {
                                #region Debug code for exceptional cases
#if DEBUG_2
                                Debug.Assert(1 >= solid.Faces.Size, "expected at most one visible face in plan view for my simple solids");

                                int n = solid.Edges.Size;

                                if (0 < n)
                                {
                                    Debug.Print(
                                        "      solid with {0} edges", n);

                                    Face[] face2 = new Face[] { null, null };
                                    Face   face  = null;

                                    foreach (Edge edge in solid.Edges)
                                    {
                                        if (null == face2[0])
                                        {
                                            face2[0] = edge.GetFace(0);
                                            face2[1] = edge.GetFace(1);
                                        }
                                        else if (null == face)
                                        {
                                            if (face2.Contains <Face>(edge.GetFace(0)))
                                            {
                                                face = edge.GetFace(0);
                                            }
                                            else if (face2.Contains <Face>(edge.GetFace(1)))
                                            {
                                                face = edge.GetFace(1);
                                            }
                                            else
                                            {
                                                Debug.Assert(false,
                                                             "expected all edges to belong to one face");
                                            }
                                        }
                                        else
                                        {
                                            Debug.Assert(face == edge.GetFace(0) ||
                                                         face == edge.GetFace(1),
                                                         "expected all edges to belong to one face");
                                        }

                                        Curve c = edge.AsCurve();

                                        // This returns the curves already
                                        // correctly oriented:

                                        //Curve curve = e.AsCurveFollowingFace(
                                        //  face );

                                        Debug.Print("        {0}: {1} {2}",
                                                    edge.GetType().Name,
                                                    c.GetType().Name,
                                                    Util.CurveEndpointString(c));
                                    }
                                }
#endif // DEBUG
                                #endregion // Debug code for exceptional cases
                            }
                        }
                    }

                    // Save the part or instance and
                    // the geometry retrieved for it.
                    // This is where we drop all geometry but
                    // the first loop.

                    if (null != loops)
                    {
                        GeomData gd = new GeomData();
                        gd.Loop = loops[0];

                        if (null == f)
                        {
                            // Add part with absolute geometry

                            gd.Id = e.Id;

                            modelCollections.BimelsInViews[v.Id].Add(
                                gd);

                            // Expand bounding box around all BIM
                            // elements.

                            bimelBb.ExpandToContain(
                                gd.Loop.BoundingBox);
                        }
                        else
                        {
                            // Define symbol and add instance

                            JtPlacement2dInt placement
                                = new JtPlacement2dInt(f);

                            InstanceData id = new InstanceData();
                            id.Id        = f.Id;
                            id.Symbol    = f.Symbol.Id;
                            id.Placement = placement;

                            modelCollections.BimelsInViews[v.Id].Add(
                                id);

                            gd.Id = f.Symbol.Id;

                            modelCollections.Symbols.Add(
                                f.Symbol.Id, gd);

                            // Expand bounding box around all BIM
                            // elements.

                            JtBoundingBox2dInt bb     = gd.Loop.BoundingBox;
                            Point2dInt         vtrans = placement.Translation;
                            bimelBb.ExpandToContain(bb.Min + vtrans);
                            bimelBb.ExpandToContain(bb.Max + vtrans);
                        }
                    }
                }

                // Set up BIM bounding box for this view

                modelCollections.ViewsInSheet[sheet.Id].Find(
                    v2 => v2.Id.IntegerValue.Equals(
                        v.Id.IntegerValue)).BimBoundingBox
                    = bimelBb;
            }
        }
コード例 #4
0
ファイル: GeoSnoop.cs プロジェクト: vdubya/RoomEditorApp
        /// <summary>
        /// Display sheet, the views it contains, the BIM
        /// parts and  family instances they display in a
        /// temporary form generated on the fly.
        /// </summary>
        /// <param name="owner">Owner window</param>
        /// <param name="caption">Form caption</param>
        /// <param name="modal">Modal versus modeless</param>
        /// <param name="roomLoops">Sheet and viewport boundary loops</param>
        /// <param name="geometryLoopss">Family symbol and part geometry</param>
        /// <param name="familyInstances">Family instances</param>
        public static Bitmap DisplaySheet(
            ElementId sheetId,
            JtLoops sheetViewportLoops,
            SheetModelCollections modelCollections)
        {
            // Source rectangle.

            JtBoundingBox2dInt bbFrom = sheetViewportLoops
                                        .BoundingBox;

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

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

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

            int top    = 0;
            int left   = 0;
            int bottom = height - (_margin + _margin);

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

            // Transform from native loop coordinate system
            // (sheet) to target display coordinates form).

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

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

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

            // Display sheet and viewport rectangles.

            DrawLoopsOnGraphics(graphics,
                                sheetViewportLoops.GetGraphicsPathLines(),
                                transformSheetBbToForm);

            // Iterate over the views and display the
            // elements for each one appropriately
            // scaled and translated to fit.

            List <ViewData> views = modelCollections
                                    .ViewsInSheet[sheetId];

            Dictionary <ElementId, GeomData> geometryLookup
                = modelCollections.Symbols;

            Matrix             transformBimToViewport;
            JtBoundingBox2dInt bbTo;
            JtLoop             loop;

            foreach (ViewData view in views)
            {
                ElementId vid = view.Id;

                if (!modelCollections.BimelsInViews
                    .ContainsKey(vid))
                {
                    // This is not a floor plan view, so
                    // we have nothing to display in it.

                    continue;
                }

                // Determine transform from model space in mm
                // to the viewport associated with this view.

                bbFrom = view.BimBoundingBox;
                bbTo   = view.ViewportBoundingBox;

                Debug.Print(view.ToString());

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

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

                // Specify transformation target rectangle
                // including a margin, and center the target
                // rectangle vertically.

                top    = bbTo.Min.Y + _margin2;
                left   = bbTo.Min.X + _margin2;
                bottom = bbTo.Max.Y - _margin2;
                width  = bbTo.Width - (_margin2 + _margin2);

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

                // Transform from native loop coordinate system
                // (sheet) to target display coordinates form).

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

                // Retrieve the list of BIM elements
                // displayed in this view.

                List <ObjData> bimels = modelCollections
                                        .BimelsInViews[vid];

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

                Matrix placement = new Matrix();

                foreach (ObjData bimel in bimels)
                {
                    placement.Reset();

                    InstanceData inst = bimel as InstanceData;

                    if (null != inst)
                    {
                        loop = geometryLookup[inst.Symbol].Loop;
                        Point2dInt v = inst.Placement.Translation;
                        placement.Rotate(inst.Placement.Rotation);
                        placement.Translate(v.X, v.Y, MatrixOrder.Append);
                    }
                    else
                    {
                        Debug.Assert(bimel is GeomData, "expected part with geometry");

                        loop = ((GeomData)bimel).Loop;
                    }
                    loops[0] = loop.GetGraphicsPathLines();

                    placement.Multiply(transformBimToViewport, MatrixOrder.Append);
                    placement.Multiply(transformSheetBbToForm, MatrixOrder.Append);

                    DrawLoopsOnGraphics(graphics, loops, placement);
                }
            }
            return(bmp);
        }
コード例 #5
0
ファイル: DbUpload.cs プロジェクト: vdubya/RoomEditorApp
        /// <summary>
        /// Upload model, sheet, views it contains and
        /// their BIM elements to a CouchDB data repository.
        /// </summary>
        static public void DbUploadSheet(
            ViewSheet sheet,
            JtLoops sheetViewportLoops,
            SheetModelCollections modelCollections)
        {
            bool pre_existing = false;

            RoomEditorDb  rdb = new RoomEditorDb();
            CouchDatabase db  = rdb.Db;

            // Sheet

            Document doc = sheet.Document;

            Element e = GetProjectInfo(doc);

            DbModel dbModel = GetDbModel(db, e);

            DbSheet dbSheet = rdb.GetOrCreate <DbSheet>(
                ref pre_existing, sheet.UniqueId);

            dbSheet.Description = Util.SheetDescription(sheet);
            dbSheet.Name        = sheet.Name;
            dbSheet.ModelId     = e.UniqueId;
            dbSheet.Width       = sheetViewportLoops[0].BoundingBox.Width;
            dbSheet.Height      = sheetViewportLoops[0].BoundingBox.Height;

            dbSheet = pre_existing
        ? db.UpdateDocument <DbSheet>(dbSheet)
        : db.CreateDocument <DbSheet>(dbSheet);

            // Symbols

            Dictionary <ElementId, GeomData> geometryLookup
                = modelCollections.Symbols;

            foreach (KeyValuePair <ElementId, GeomData> p
                     in geometryLookup)
            {
                ElementId id = p.Key;

                e = doc.GetElement(id);

                DbSymbol symbol = rdb.GetOrCreate <DbSymbol>(
                    ref pre_existing, e.UniqueId);

                symbol.Description = Util.ElementDescription(e);
                symbol.Name        = e.Name;
                symbol.Loop        = p.Value.Loop.SvgPath;

                symbol = pre_existing
          ? db.UpdateDocument <DbSymbol>(symbol)
          : db.CreateDocument <DbSymbol>(symbol);
            }

            // Views and BIM elements

            List <ViewData> views = modelCollections
                                    .ViewsInSheet[sheet.Id];

            View               view;
            DbView             dbView;
            DbBimel            dbBimel;
            DbInstance         dbInstance = null;
            DbPart             dbPart     = null;
            JtBoundingBox2dInt bbFrom;
            JtBoundingBox2dInt bbTo;

            foreach (ViewData viewData in views)
            {
                ElementId vid = viewData.Id;

                if (!modelCollections.BimelsInViews
                    .ContainsKey(vid))
                {
                    // This is not a floor plan view, so
                    // we have nothing to display in it.

                    continue;
                }

                view = doc.GetElement(vid) as View;

                dbView = rdb.GetOrCreate <DbView>(
                    ref pre_existing, view.UniqueId);

                dbView.Description = Util.ElementDescription(view);
                dbView.Name        = view.Name;
                dbView.SheetId     = dbSheet.Id;

                bbFrom = viewData.BimBoundingBox;
                bbTo   = viewData.ViewportBoundingBox;

                dbView.X      = bbTo.Min.X;
                dbView.Y      = bbTo.Min.Y;
                dbView.Width  = bbTo.Width;
                dbView.Height = bbTo.Height;

                dbView.BimX      = bbFrom.Min.X;
                dbView.BimY      = bbFrom.Min.Y;
                dbView.BimWidth  = bbFrom.Width;
                dbView.BimHeight = bbFrom.Height;

                dbView = pre_existing
          ? db.UpdateDocument <DbView>(dbView)
          : db.CreateDocument <DbView>(dbView);

                // Retrieve the list of BIM elements
                // displayed in this view.

                List <ObjData> bimels = modelCollections
                                        .BimelsInViews[vid];

                foreach (ObjData bimel in bimels)
                {
                    e = doc.GetElement(bimel.Id);

                    InstanceData inst = bimel as InstanceData;

                    if (null != inst)
                    {
                        dbInstance = rdb.GetOrCreate <DbInstance>(
                            ref pre_existing, e.UniqueId);

                        dbInstance.SymbolId = doc.GetElement(
                            inst.Symbol).UniqueId;

                        dbInstance.Transform = inst.Placement
                                               .SvgTransform;

                        dbBimel = dbInstance;
                    }
                    else
                    {
                        Debug.Assert(bimel is GeomData,
                                     "expected part with geometry");

                        dbPart = rdb.GetOrCreate <DbPart>(
                            ref pre_existing, e.UniqueId);

                        dbPart.Loop = ((GeomData)bimel).Loop
                                      .SvgPath;

                        dbBimel = dbPart;
                    }
                    dbBimel.Description = Util.ElementDescription(e);
                    dbBimel.Name        = e.Name;
                    JtUidSet uids = new JtUidSet(dbBimel.ViewIds);
                    uids.Add(view.UniqueId);
                    dbBimel.ViewIds    = uids.Uids;
                    dbBimel.Properties = Util.GetElementProperties(e);

                    if (null != inst)
                    {
                        dbInstance = pre_existing
              ? db.UpdateDocument <DbInstance>(dbInstance)
              : db.CreateDocument <DbInstance>(dbInstance);
                    }
                    else
                    {
                        dbPart = pre_existing
              ? db.UpdateDocument <DbPart>(dbPart)
              : db.CreateDocument <DbPart>(dbPart);
                    }
                }
            }
        }
コード例 #6
0
ファイル: GeoSnoop.cs プロジェクト: mtumminello/RoomEditorApp
    /// <summary>
    /// Display sheet, the views it contains, the BIM 
    /// parts and  family instances they display in a 
    /// temporary form generated on the fly.
    /// </summary>
    /// <param name="owner">Owner window</param>
    /// <param name="caption">Form caption</param>
    /// <param name="modal">Modal versus modeless</param>
    /// <param name="roomLoops">Sheet and viewport boundary loops</param>
    /// <param name="geometryLoopss">Family symbol and part geometry</param>
    /// <param name="familyInstances">Family instances</param>
    public static Bitmap DisplaySheet(
      ElementId sheetId,
      JtLoops sheetViewportLoops,
      SheetModelCollections modelCollections )
    {
      // Source rectangle.
 
      JtBoundingBox2dInt bbFrom = sheetViewportLoops
        .BoundingBox;

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

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

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

      int top = 0;
      int left = 0;
      int bottom = height - ( _margin + _margin );

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

      // Transform from native loop coordinate system
      // (sheet) to target display coordinates form).

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

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

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

      // Display sheet and viewport rectangles.

      DrawLoopsOnGraphics( graphics,
        sheetViewportLoops.GetGraphicsPathLines(),
        transformSheetBbToForm );

      // Iterate over the views and display the 
      // elements for each one appropriately 
      // scaled and translated to fit.

      List<ViewData> views = modelCollections
        .ViewsInSheet[sheetId];

      Dictionary<ElementId, GeomData> geometryLookup 
        = modelCollections.Symbols;

      Matrix transformBimToViewport;
      JtBoundingBox2dInt bbTo;
      JtLoop loop;

      foreach( ViewData view in views )
      {
        ElementId vid = view.Id;

        if( !modelCollections.BimelsInViews
          .ContainsKey( vid ) )
        {
          // This is not a floor plan view, so
          // we have nothing to display in it.

          continue;
        }

        // Determine transform from model space in mm
        // to the viewport associated with this view.

        bbFrom = view.BimBoundingBox;
        bbTo = view.ViewportBoundingBox;

        Debug.Print( view.ToString() );

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

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

        // Specify transformation target rectangle 
        // including a margin, and center the target 
        // rectangle vertically.

        top = bbTo.Min.Y + _margin2;
        left = bbTo.Min.X + _margin2;
        bottom = bbTo.Max.Y - _margin2;
        width = bbTo.Width - (_margin2 + _margin2);

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

        // Transform from native loop coordinate system
        // (sheet) to target display coordinates form).

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

        // Retrieve the list of BIM elements  
        // displayed in this view.

        List<ObjData> bimels = modelCollections
          .BimelsInViews[vid];

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

        Matrix placement = new Matrix();

        foreach( ObjData bimel in bimels )
        {
          placement.Reset();

          InstanceData inst = bimel as InstanceData;

          if( null != inst )
          {
            loop = geometryLookup[inst.Symbol].Loop;
            Point2dInt v = inst.Placement.Translation;
            placement.Rotate( inst.Placement.Rotation );
            placement.Translate( v.X, v.Y, MatrixOrder.Append );
          }
          else
          {
            Debug.Assert( bimel is GeomData, "expected part with geometry" );

            loop = ((GeomData) bimel).Loop;
          }
          loops[0] = loop.GetGraphicsPathLines();

          placement.Multiply( transformBimToViewport, MatrixOrder.Append );
          placement.Multiply( transformSheetBbToForm, MatrixOrder.Append );

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