示例#1
0
        /// <summary>
        /// Repeatedly check database status and raise
        /// external event when updates are pending.
        /// Relinquish control and wait for timeout
        /// period between each attempt. Run in a
        /// separate thread.
        /// </summary>
        static void CheckForPendingDatabaseChanges()
        {
            while (null != _event)
            {
                ++_nLoopCount;

                Debug.Assert(null != _event,
                             "expected non-null external event");

                if (null != _event)
                {
                    break;
                }

                if (_event.IsPending)
                {
                    Util.Log(string.Format(
                                 "CheckForPendingDatabaseChanges loop {0} - "
                                 + "database update event is pending",
                                 _nLoopCount));
                }
                else
                {
                    using (JtTimer pt = new JtTimer(
                               "CheckForPendingDatabaseChanges"))
                    {
                        ++_nCheckCount;

                        Util.Log(string.Format(
                                     "CheckForPendingDatabaseChanges loop {0} - "
                                     + "check for changes {1}",
                                     _nLoopCount, _nCheckCount));

                        RoomEditorDb rdb = new RoomEditorDb();

                        if (rdb.LastSequenceNumberChanged(
                                DbUpdater.LastSequence))
                        {
                            _event.Raise();

                            ++_nUpdatesRequested;

                            Util.Log(string.Format(
                                         "database update pending event raised {0} times",
                                         _nUpdatesRequested));

                            #region Obsolete attempts that failed
                            // Move the mouse in case the user does
                            // not. Otherwise, it may take a while
                            // before Revit forwards the event Raise
                            // to the event handler Execute method.

                            // Just moving the mouse is not enough:

                            //System.Drawing.Point p = Cursor.Position;
                            //Cursor.Position = new System.Drawing
                            //  .Point( p.X + 1, p.Y );
                            //Cursor.Position = p;

                            // This did not work either:

                            //[DllImport( "user32.dll" )]
                            //static extern IntPtr SetFocus(
                            //  IntPtr hwnd );

                            //IWin32Window revit_window
                            //  = new JtWindowHandle(
                            //    ComponentManager.ApplicationWindow );
                            //IntPtr hwnd = SetFocus( revit_window.Handle );
                            //IntPtr hwnd2 = SetFocus( hwnd );
                            //Debug.Print( "set to rvt {0} --> {1} --> {2}",
                            //  revit_window.Handle, hwnd, hwnd2 );

                            // Try SendKeys?
                            #endregion // Obsolete attempts that failed

                            // Set focus to Revit for a moment.
                            // Otherwise, it may take a while before
                            // Revit forwards the event Raise to the
                            // event handler Execute method.

                            IntPtr hBefore = GetForegroundWindow();

                            SetForegroundWindow(
                                ComponentManager.ApplicationWindow);

                            SetForegroundWindow(hBefore);
                        }
                    }
                }

                // Wait a moment and relinquish control before
                // next check for pending database updates.

                Thread.Sleep(_timeout);
            }
        }
示例#2
0
        /// <summary>
        /// Apply all current cloud database
        /// changes to the BIM.
        /// </summary>
        public void UpdateBim()
        {
            Util.Log("UpdateBim begin");

            using (JtTimer pt = new JtTimer("UpdateBim"))
            {
                Document doc = _uiapp.ActiveUIDocument.Document;

                // Retrieve all room unique ids in model:

                FilteredElementCollector rooms
                    = new FilteredElementCollector(doc)
                      .OfClass(typeof(SpatialElement))
                      .OfCategory(BuiltInCategory.OST_Rooms);

                IEnumerable <string> roomUniqueIds
                    = rooms.Select <Element, string>(
                          e => e.UniqueId);

                // Convert to a dictionary for faster lookup:

                _roomUniqueIdDict
                    = new Dictionary <string, int>(
                          roomUniqueIds.Count());

                foreach (string s in roomUniqueIds)
                {
                    _roomUniqueIdDict.Add(s, 1);
                }

                //string ids = "?keys=[%22" + string.Join(
                //  "%22,%22", roomUniqueIds ) + "%22]";

                // Retrieve all furniture transformations
                // after the last sequence number:

                CouchDatabase db = new RoomEditorDb().Db;

                ChangeOptions opt = new ChangeOptions();

                opt.IncludeDocs = true;
                opt.Since       = LastSequence;
                opt.View        = "roomedit/map_room_to_furniture";

                // I tried to add a filter to this view, but
                // that is apparently not supported by the
                // CouchDB or DreamSeat GetChanges functionality.
                //+ ids; // failed attempt to filter view by room id keys

                // Specify filter function defined in
                // design document to get updates
                //opt.Filter =

                CouchChanges <DbFurniture> changes
                    = db.GetChanges <DbFurniture>(opt);

                CouchChangeResult <DbFurniture>[] results
                    = changes.Results;

                foreach (CouchChangeResult <DbFurniture> result
                         in results)
                {
                    UpdateBimFurniture(result.Doc);

                    LastSequence = result.Sequence;
                }
            }
            Util.Log("UpdateBim end");
        }
示例#3
0
        /// <summary>
        /// Upload model, level, room and furniture data
        /// to an IrisCouch hosted CouchDB data repository.
        /// </summary>
        static public void DbUploadRoom(
            Room room,
            List <Element> furniture,
            JtLoops roomLoops,
            Dictionary <string, JtLoop> furnitureLoops)
        {
            CouchDatabase db = new RoomEditorDb().Db;

            Document doc = room.Document;

            Element projectInfo = GetProjectInfo(doc);

            DbModel dbModel = GetDbModel(db, projectInfo);

            Element level = doc.GetElement(room.LevelId);

            string uid = level.UniqueId;

            DbLevel dbLevel;

            if (db.DocumentExists(uid))
            {
                dbLevel = db.GetDocument <DbLevel>(uid);

                Debug.Assert(
                    dbLevel.Id.Equals(level.UniqueId),
                    "expected equal ids");

                dbLevel.Description = Util.ElementDescription(
                    level);

                dbLevel.Name    = level.Name;
                dbLevel.ModelId = projectInfo.UniqueId;

                dbLevel = db.UpdateDocument <DbLevel>(
                    dbLevel);
            }
            else
            {
                dbLevel = new DbLevel(uid);

                dbLevel.Description = Util.ElementDescription(
                    level);

                dbLevel.Name    = level.Name;
                dbLevel.ModelId = projectInfo.UniqueId;

                dbLevel = db.CreateDocument <DbLevel>(
                    dbLevel);
            }

            uid = room.UniqueId;

            DbRoom dbRoom;

            if (db.DocumentExists(uid))
            {
                dbRoom = db.GetDocument <DbRoom>(uid);

                Debug.Assert(
                    dbRoom.Id.Equals(room.UniqueId),
                    "expected equal ids");

                dbRoom.Description = Util.ElementDescription(
                    room);

                dbRoom.Name    = room.Name;
                dbRoom.LevelId = level.UniqueId;
                dbRoom.Loops   = roomLoops.SvgPath;
                dbRoom.ViewBox = roomLoops.BoundingBox.SvgViewBox;

                dbRoom = db.UpdateDocument <DbRoom>(dbRoom);
            }
            else
            {
                dbRoom = new DbRoom(uid);

                dbRoom.Description = Util.ElementDescription(
                    room);

                dbRoom.Name    = room.Name;
                dbRoom.LevelId = level.UniqueId;
                dbRoom.Loops   = roomLoops.SvgPath;
                dbRoom.ViewBox = roomLoops.BoundingBox.SvgViewBox;

                dbRoom = db.CreateDocument <DbRoom>(dbRoom);
            }

            foreach (KeyValuePair <string, JtLoop> p in furnitureLoops)
            {
                uid = p.Key;
                Element e = doc.GetElement(uid);
                if (db.DocumentExists(uid))
                {
                    DbSymbol symbol = db.GetDocument <DbSymbol>(
                        uid);

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

                    symbol = db.UpdateDocument <DbSymbol>(symbol);
                }
                else
                {
                    DbSymbol symbol = new DbSymbol(uid);

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

                    symbol = db.CreateDocument <DbSymbol>(symbol);
                }
            }

            foreach (FamilyInstance f in furniture)
            {
                uid = f.UniqueId;
                if (db.DocumentExists(uid))
                {
                    DbFurniture dbf = db.GetDocument <DbFurniture>(
                        uid);

                    dbf.Description = Util.ElementDescription(f);
                    dbf.Name        = f.Name;
                    dbf.RoomId      = room.UniqueId;
                    dbf.Properties  = Util.GetElementProperties(f);
                    dbf.SymbolId    = f.Symbol.UniqueId;
                    dbf.Transform   = new JtPlacement2dInt(f)
                                      .SvgTransform;

                    dbf = db.UpdateDocument <DbFurniture>(dbf);
                }
                else
                {
                    DbFurniture dbf = new DbFurniture(uid);

                    dbf.Description = Util.ElementDescription(f);
                    dbf.Name        = f.Name;
                    dbf.RoomId      = room.UniqueId;
                    dbf.Properties  = Util.GetElementProperties(f);
                    dbf.SymbolId    = f.Symbol.UniqueId;
                    dbf.Transform   = new JtPlacement2dInt(f)
                                      .SvgTransform;

                    dbf = db.CreateDocument <DbFurniture>(dbf);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Wait far a moment before requerying database.
        /// </summary>
        //static Stopwatch _stopwatch = null;

        void OnIdling(
            object sender,
            IdlingEventArgs ea)
        {
            using (JtTimer pt = new JtTimer("OnIdling"))
            {
                // Use with care! This loads the CPU:

                ea.SetRaiseWithoutDelay();

                ++_counter;

                if (0 == (_counter % _update_interval))
                {
                    if (0 == (_counter % _message_interval))
                    {
                        Util.Log(string.Format(
                                     "OnIdling called {0} times",
                                     _counter));
                    }

                    // Have we waited long enough since the last attempt?

                    //if( null == _stopwatch
                    //  || _stopwatch.ElapsedMilliseconds > 500 )

                    RoomEditorDb rdb = new RoomEditorDb();
                    //int n = rdb.LastSequenceNumber;

                    if (rdb.LastSequenceNumberChanged(
                            DbUpdater.LastSequence))
                    {
                        UIApplication uiapp = sender as UIApplication;
                        Document      doc   = uiapp.ActiveUIDocument.Document;

                        Util.Log("furniture update begin");

                        //FilteredElementCollector rooms
                        //  = new FilteredElementCollector( doc )
                        //    .OfClass( typeof( SpatialElement ) )
                        //    .OfCategory( BuiltInCategory.OST_Rooms );

                        //IEnumerable<string> roomUniqueIds
                        //  = rooms.Select<Element, string>(
                        //    e => e.UniqueId );

                        //CouchDatabase db = rdb.Db;

                        //ChangeOptions opt = new ChangeOptions();

                        //opt.IncludeDocs = true;
                        //opt.Since = CmdUpdate.LastSequence;
                        //opt.View = "roomedit/map_room_to_furniture";

                        //CouchChanges<DbFurniture> changes
                        //  = db.GetChanges<DbFurniture>( opt );

                        //CouchChangeResult<DbFurniture>[] results
                        //  = changes.Results;

                        //DbUpdater updater = new DbUpdater(
                        //  doc, roomUniqueIds );

                        //foreach( CouchChangeResult<DbFurniture> result
                        //  in results )
                        //{
                        //  updater.UpdateBimFurniture( result.Doc );

                        //  CmdUpdate.LastSequence = result.Sequence;
                        //}

                        DbUpdater updater = new DbUpdater(uiapp);

                        updater.UpdateBim();

                        Util.Log("furniture update end");

                        //  _stopwatch = new Stopwatch();
                        //  _stopwatch.Start();
                        //}
                        //catch( Exception ex )
                        //{
                        //  //uiapp.Application.WriteJournalComment

                        //  Debug.Print(
                        //    "Room Editor: an error occurred "
                        //    + "executing the OnIdling event:\r\n"
                        //    + ex.ToString() );

                        //  Debug.WriteLine( ex );
                        //}
                    }
                }
            }
        }
示例#5
0
        /// <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);
                    }
                }
            }
        }