/// <summary> /// Update a piece of furniture. /// Return true if anything was changed. /// </summary> bool UpdateBimFurniture( DbFurniture f ) { Document doc = _uiapp.ActiveUIDocument.Document; bool rc = false; if( !_roomUniqueIdDict.ContainsKey( f.RoomId ) ) { Debug.Print( "Furniture instance '{0}' '{1}'" + " with UniqueId {2} belong to a room from" + " a different model, so ignore it.", f.Name, f.Description, f.Id ); return rc; } Element e = doc.GetElement( f.Id ); if( null == e ) { Util.ErrorMsg( string.Format( "Unable to retrieve element '{0}' '{1}' " + "with UniqueId {2}. Are you in the right " + "Revit model?", f.Name, f.Description, f.Id ) ); return rc; } if( !( e is FamilyInstance ) ) { Debug.Print( "Strange, we received an " + "updated '{0}' '{1}' with UniqueId {2}, " + "which we ignore.", f.Name, f.Description, f.Id ); return rc; } // Convert SVG transform from string to int // to XYZ point and rotation in radians // including flipping of Y coordinates. string svgTransform = f.Transform; char[] separators = new char[] { ',', 'R', 'T' }; string[] a = svgTransform.Substring( 1 ).Split( separators ); int[] trxy = a.Select<string, int>( s => int.Parse( s ) ).ToArray(); double r = Util.ConvertDegreesToRadians( Util.SvgFlipY( trxy[0] ) ); XYZ p = new XYZ( Util.ConvertMillimetresToFeet( trxy[1] ), Util.ConvertMillimetresToFeet( Util.SvgFlipY( trxy[2] ) ), 0.0 ); // Check for modified transform LocationPoint lp = e.Location as LocationPoint; XYZ translation = p - lp.Point; double rotation = r - lp.Rotation; bool modifiedTransform = ( 0.01 < translation.GetLength() ) || ( 0.01 < Math.Abs( rotation ) ); // Check for modified properties List<string> modifiedPropertyKeys = new List<string>(); Dictionary<string, string> dbdict = f.Properties; Dictionary<string, string> eldict = Util.GetElementProperties( e ); Debug.Assert( dbdict.Count == eldict.Count, "expected equal dictionary length" ); string key_db; // JavaScript lowercases first char string val_db; // remove prepended "r " or "w " string val_el; foreach( string key in eldict.Keys ) { Parameter pa = e.LookupParameter( key ); Debug.Assert( null != pa, "expected valid parameter" ); if( Util.IsModifiable( pa ) ) { key_db = Util.Uncapitalise( key ); Debug.Assert( dbdict.ContainsKey( key_db ), "expected same keys in Revit model and cloud database" ); val_db = dbdict[key_db].Substring( 2 ); if( StorageType.String == pa.StorageType ) { val_el = pa.AsString() ?? string.Empty; } else { Debug.Assert( StorageType.Integer == pa.StorageType, "expected only string and integer parameters" ); val_el = pa.AsInteger().ToString(); } if( !val_el.Equals( val_db ) ) { modifiedPropertyKeys.Add( key ); } } } if( modifiedTransform || 0 < modifiedPropertyKeys.Count ) { using( Transaction tx = new Transaction( doc ) ) { tx.Start( "Update Furniture and " + "Equipmant Instance Placement" ); if( .01 < translation.GetLength() ) { ElementTransformUtils.MoveElement( doc, e.Id, translation ); } if( .01 < Math.Abs( rotation ) ) { Line axis = Line.CreateBound( lp.Point, lp.Point + XYZ.BasisZ ); ElementTransformUtils.RotateElement( doc, e.Id, axis, rotation ); } foreach( string key in modifiedPropertyKeys ) { Parameter pa = e.LookupParameter( key ); key_db = Util.Uncapitalise( key ); val_db = dbdict[key_db].Substring( 2 ); if( StorageType.String == pa.StorageType ) { pa.Set( val_db ); } else { try { int i = int.Parse( val_db ); pa.Set( i ); } catch( System.FormatException ) { } } } tx.Commit(); rc = true; } } return rc; }
/// <summary> /// Update a piece of furniture. /// Return true if anything was changed. /// </summary> bool UpdateBimFurniture( DbFurniture f) { Document doc = _uiapp.ActiveUIDocument.Document; bool rc = false; if (!_roomUniqueIdDict.ContainsKey(f.RoomId)) { Debug.Print("Furniture instance '{0}' '{1}'" + " with UniqueId {2} belong to a room from" + " a different model, so ignore it.", f.Name, f.Description, f.Id); return(rc); } Element e = doc.GetElement(f.Id); if (null == e) { Util.ErrorMsg(string.Format( "Unable to retrieve element '{0}' '{1}' " + "with UniqueId {2}. Are you in the right " + "Revit model?", f.Name, f.Description, f.Id)); return(rc); } if (!(e is FamilyInstance)) { Debug.Print("Strange, we received an " + "updated '{0}' '{1}' with UniqueId {2}, " + "which we ignore.", f.Name, f.Description, f.Id); return(rc); } // Convert SVG transform from string to int // to XYZ point and rotation in radians // including flipping of Y coordinates. string svgTransform = f.Transform; char[] separators = new char[] { ',', 'R', 'T' }; string[] a = svgTransform.Substring(1).Split(separators); int[] trxy = a.Select <string, int>(s => int.Parse(s)).ToArray(); double r = Util.ConvertDegreesToRadians( Util.SvgFlipY(trxy[0])); XYZ p = new XYZ( Util.ConvertMillimetresToFeet(trxy[1]), Util.ConvertMillimetresToFeet(Util.SvgFlipY(trxy[2])), 0.0); // Check for modified transform LocationPoint lp = e.Location as LocationPoint; XYZ translation = p - lp.Point; double rotation = r - lp.Rotation; bool modifiedTransform = (0.01 < translation.GetLength()) || (0.01 < Math.Abs(rotation)); // Check for modified properties List <string> modifiedPropertyKeys = new List <string>(); Dictionary <string, string> dbdict = f.Properties; Dictionary <string, string> eldict = Util.GetElementProperties(e); Debug.Assert(dbdict.Count == eldict.Count, "expected equal dictionary length"); string key_db; // JavaScript lowercases first char string val_db; // remove prepended "r " or "w " string val_el; foreach (string key in eldict.Keys) { Parameter pa = e.LookupParameter(key); Debug.Assert(null != pa, "expected valid parameter"); if (Util.IsModifiable(pa)) { key_db = Util.Uncapitalise(key); Debug.Assert(dbdict.ContainsKey(key_db), "expected same keys in Revit model and cloud database"); val_db = dbdict[key_db].Substring(2); if (StorageType.String == pa.StorageType) { val_el = pa.AsString() ?? string.Empty; } else { Debug.Assert(StorageType.Integer == pa.StorageType, "expected only string and integer parameters"); val_el = pa.AsInteger().ToString(); } if (!val_el.Equals(val_db)) { modifiedPropertyKeys.Add(key); } } } if (modifiedTransform || 0 < modifiedPropertyKeys.Count) { using (Transaction tx = new Transaction( doc)) { tx.Start("Update Furniture and " + "Equipmant Instance Placement"); if (.01 < translation.GetLength()) { ElementTransformUtils.MoveElement( doc, e.Id, translation); } if (.01 < Math.Abs(rotation)) { Line axis = Line.CreateBound(lp.Point, lp.Point + XYZ.BasisZ); ElementTransformUtils.RotateElement( doc, e.Id, axis, rotation); } foreach (string key in modifiedPropertyKeys) { Parameter pa = e.LookupParameter(key); key_db = Util.Uncapitalise(key); val_db = dbdict[key_db].Substring(2); if (StorageType.String == pa.StorageType) { pa.Set(val_db); } else { try { int i = int.Parse(val_db); pa.Set(i); } catch (System.FormatException) { } } } tx.Commit(); rc = true; } } return(rc); }
/// <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); } } }