public void Sync(Document doc) { var bc = new BuildingGraphClient(@"http://*****:*****@"{ChangeRequest (IsComplete:false){Changes{ParameterName, NewValue, ChangeSource{BIMRevitElementID}}}}"; var vars = new Dictionary <string, object>(); vars.Add("IsComplete", false); var task = Task.Run(() => AsyncContext.Run(() => bc.ExecuteQuery(query, vars))); //after a lot of issues with thread blocking... this was found to be a working interim solution. //see https://msdn.microsoft.com/en-us/magazine/mt238404.aspx for explanation //ideally, we wouldn't block Revit's main thread, but in most cases the query will complete very quickly. //The majority of time spent is in writing the parameter values with Revit which, due to constraints of the Revit API, can only be synchronous. //so not a lot to be gained by making this truly asynchronous foreach (dynamic cr in task.Result.ChangeRequest) { foreach (var cg in cr.Changes) { var peramName = cg.ParameterName.Value; var newValue = cg.NewValue.Value; var elmId = cg.ChangeSource.BIMRevitElementID.Value; var elm = doc.GetElement(new ElementId((int)elmId)); if (elm == null) { continue; } var param = elm.GetParameters((string)peramName).FirstOrDefault(); if (param == null) { continue; } var hlParam = new HLRevitParameter(param); hlParam.Value = newValue; } } var docIdent = HLApps.Revit.Utils.DocUtils.GetDocumentIdent(doc); var docVars = new Dictionary <string, object>(); docVars.Add("modelIdent", docIdent); var modelElementsQuery = @"query($modelIdent:String){ Model (Identity:$modelIdent){ Identity ModelElements { UniqueId AbstractElement { __typename Name } } } }"; var modelElementQResult = bc.ExecuteQuery(modelElementsQuery, docVars); var model = modelElementQResult.Result.Model; }
public void UpdateLocal(StreamMessage message) { //add parameters //get unit and types from schema? _dispatcher.QueueAction((uiapp) => { var doc = uiapp.ActiveUIDocument.Document; var node = message.After.AsNode(); var nodeElement = doc.GetElement(node.Id); if (nodeElement == null) { return; } using (var updatetx = new Transaction(doc, "Update from stream")) { updatetx.Start("Update from stream"); var nodeparamers = node.ExtendedProperties; foreach (var param in nodeElement.Parameters.OfType <Parameter>()) { if (param.IsReadOnly) { continue; } var hp = new HLRevitParameter(param); var paramName = Utils.GetGraphQLCompatibleFieldName(param.Definition.Name); if (nodeparamers.ContainsKey(paramName)) { var incommingValue = nodeparamers[paramName]; var currentValue = MEPGraphUtils.RevitToGraphValue(hp); if (incommingValue != currentValue) { hp.Value = incommingValue; } } } updatetx.Commit(); } }); }
/// <summary> /// Get a dictionary of paramters and values which match those required by the node type /// defined in the schema /// </summary> /// <param name="node"></param> /// <param name="elm"></param> /// <param name="clientMapping"></param> /// <returns></returns> public static Dictionary <string, object> GetNodePropsWithElementProps(Node node, Element elm, IBuildingGraphSchema schema, BuildingGraphMapping clientMapping, bool includeOnlyMappedFields) { var elmParms = node.GetAllProperties(); if (elm != null && elm.Location is LocationPoint) { var lpt = (elm.Location as LocationPoint); var insPt = lpt.Point; if (!elmParms.ContainsKey("Location")) { elmParms.Add("Location", insPt.ToBuildingGraph()); } //if (!elmParms.ContainsKey("LocationRotation")) elmParms.Add("LocationRotation", lpt.Rotation); } else if (elm != null && elm.Location is LocationCurve) { //just start and end points for now var asCurve = (elm.Location as LocationCurve).Curve; var insPt = asCurve.GetEndPoint(0); if (!elmParms.ContainsKey("Location")) { elmParms.Add("Location", insPt.ToBuildingGraph()); } var endPt = asCurve.GetEndPoint(1); if (!elmParms.ContainsKey("LocationEnd")) { elmParms.Add("LocationEnd", endPt.ToBuildingGraph()); } var length = asCurve.Length; if (!elmParms.ContainsKey("length")) { elmParms.Add("Length", length); } var slope = Math.Abs(endPt.Z - insPt.Z) / length; if (!elmParms.ContainsKey("slope")) { elmParms.Add("slope", length); } } IBuildingGraphType bqType = schema != null?schema.GetBuildingGraphType(node.Label) : null; BuildingGraphMappedType clType = clientMapping != null?clientMapping.Types.FirstOrDefault(ct => ct.Name == node.Label) : null; foreach (var param in elm.Parameters.OfType <Parameter>()) { var hp = new HLRevitParameter(param); var paramName = Utils.GetGraphQLCompatibleFieldName(param.Definition.Name); var val = RevitToGraphValue(hp); if (bqType != null && clientMapping != null) { //resolve mapped field name if present if (clType != null) { var mappedFielName = clType.ValueMap.FirstOrDefault(vm => vm.Value == paramName); if (mappedFielName.Value == paramName) { paramName = mappedFielName.Key; } } var paramField = bqType.Fields.FirstOrDefault(fb => fb.Name == paramName); if (includeOnlyMappedFields && paramField == null) { continue; } //attempt to convert units if (val is double) { var fieldUnit = paramField.Args.FirstOrDefault(arg => arg.Name == "unit"); if (fieldUnit == null) { continue; } //var fieldUnitType = schema.GetBuildingGraphType(fieldUnit.TypeName); var unitMapping = clientMapping.Types.FirstOrDefault(tp => tp.Name == fieldUnit.TypeName); var defaultValue = fieldUnit.DefaultValue != null?fieldUnit.DefaultValue.ToString() : string.Empty; if (unitMapping != null && unitMapping.ValueMap.ContainsKey(fieldUnit.DefaultValue.ToString())) { var revitValue = unitMapping.ValueMap[defaultValue]; DisplayUnitType revitUnitTypeEnum; if (Enum.TryParse(revitValue, out revitUnitTypeEnum)) { //var type = Type.GetType(unitMapping.NativeType);// "Namespace.MyClass, MyAssembly"); val = UnitUtils.ConvertFromInternalUnits((double)val, revitUnitTypeEnum); } } } } if (!elmParms.ContainsKey(paramName)) { elmParms.Add(paramName, val); } } return(elmParms); }
/// <summary> /// Creates the element in the model /// </summary> /// <param name="doc"></param> public void CreateLocal(StreamMessage message) { //insert at position? //find space it's in? //find family symbol/type? _dispatcher.QueueAction((uiapp) => { var doc = uiapp.ActiveUIDocument.Document; var node = message.After.AsNode(); var nodeElement = doc.GetElement(node.Id); using (var updatetx = new Transaction(doc, "Update from stream")) { updatetx.Start("Update from stream"); if (node.Labels.Contains("FanCoilUnit")) { if (nodeElement == null) { //create node // //get the space it's in var query = @" query($fcuid:ID!){ FanCoilUnit (Id:$fcuid){ Id ModelElements{ Id UniqueId } Space{ Id } ConnectedTo{ Id Apparent_Load ModelElements{ Id UniqueId } } } }"; var vars = new Dictionary <string, object>(); vars.Add("fcuid", node.Id); var res = _client.ExecuteQuery(query, vars); if (res.FanCoilUnit != null) { var fcu = res.FanCoilUnit[0]; Element modelElm = null; foreach (var modelelemet in fcu.ModelElements) { var id = modelelemet.UniqueId.Value; modelElm = doc.GetElement((string)id); if (modelElm != null) { break; } } if (fcu.Space != null) { var spaceId = fcu.Space.Id.Value; //find space var spaceElm = doc.GetElement((string)spaceId) as SpatialElement; if (spaceElm != null) { //find center MEPRevitNode rv = new MEPRevitNode(spaceElm); var sbopt = new SpatialElementBoundaryOptions(); sbopt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; sbopt.StoreFreeBoundaryFaces = true; SpatialElementGeometryCalculator sg = new SpatialElementGeometryCalculator(doc, sbopt); var spgets = sg.CalculateSpatialElementGeometry(spaceElm); var spgeo = spgets.GetGeometry(); var center = spgeo.ComputeCentroid(); var bbox = spgeo.GetBoundingBox(); var heightOfUnit = 1; var randomOffset = (bbox.Max.X - bbox.Min.X) / 2 * (new Random().NextDouble() - 0.5); var inspoint = new XYZ(center.X + randomOffset, center.Y, bbox.Max.Z - heightOfUnit); FilteredElementCollector famFilter = new FilteredElementCollector(doc); //this is static for this example. We will need to discover the type and pull the family //from a family library service. string familyName = "HL_FanCoilUnit_HotandChilledWaterSoffit3HorizontalRoundConnections"; Family foundFam = famFilter.OfClass(typeof(Family)).ToElements().OfType <Family>().FirstOrDefault(fm => fm.Name == familyName); var fcuSymbol = doc.GetElement(foundFam.GetFamilySymbolIds().FirstOrDefault()) as FamilySymbol; var newElm = doc.Create.NewFamilyInstance(inspoint, fcuSymbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); //var props = MEPGraphUtils.GetNodePropsWithElementProps(new Client.Model.ModelElement(), newElm); //var newnode = _client.Push("ModelElement", props); //_client.Relate(new PendingNode(node), newnode, Client.Model.MEPEdgeTypes.REALIZED_BY, null); var nodeparamers = node.ExtendedProperties; foreach (var param in newElm.Parameters.OfType <Parameter>()) { if (param.IsReadOnly) { continue; } var hp = new HLRevitParameter(param); var paramName = Utils.GetGraphQLCompatibleFieldName(param.Definition.Name); if (nodeparamers.ContainsKey(paramName)) { var incommingValue = nodeparamers[paramName]; var currentValue = MEPGraphUtils.RevitToGraphValue(hp); if (incommingValue != currentValue) { hp.Value = incommingValue; } } } if (fcu.ConnectedTo != null) { string fcuName = "FCU"; Family foundfcuFam = famFilter.OfClass(typeof(Family)).ToElements().OfType <Family>().FirstOrDefault(fm => fm.Name == fcuName); var fcueSymbol = doc.GetElement(foundFam.GetFamilySymbolIds().FirstOrDefault()) as FamilySymbol; var fcuEinspt = inspoint + new XYZ(1, 0, 0); var newFuceElm = doc.Create.NewFamilyInstance(fcuEinspt, fcuSymbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); foreach (var param in newFuceElm.Parameters.OfType <Parameter>()) { if (param.IsReadOnly) { continue; } var hp = new HLRevitParameter(param); var paramName = Utils.GetGraphQLCompatibleFieldName(param.Definition.Name); if (fcu.ConnectedTo[paramName] != null) { var incommingValue = fcu.ConnectedTo[paramName].Value; var currentValue = MEPGraphUtils.RevitToGraphValue(hp); if (incommingValue != currentValue) { hp.Value = incommingValue; } } } } } } } } } updatetx.Commit(); } }); }
public static Dictionary <string, object> GetNodePropsWithElementProps(Node node, Element elm) { var elmParms = node.GetAllProperties(); if (elm != null && elm.Location is Autodesk.Revit.DB.LocationPoint) { var lpt = (elm.Location as Autodesk.Revit.DB.LocationPoint); var insPt = lpt.Point; if (!elmParms.ContainsKey("LocationX")) { elmParms.Add("LocationX", insPt.X); } if (!elmParms.ContainsKey("LocationY")) { elmParms.Add("LocationY", insPt.Y); } if (!elmParms.ContainsKey("LocationZ")) { elmParms.Add("LocationZ", insPt.Z); } //if (!elmParms.ContainsKey("LocationRotation")) elmParms.Add("LocationRotation", lpt.Rotation); } else if (elm != null && elm.Location is Autodesk.Revit.DB.LocationCurve) { //just start and end points for now var insPt = (elm.Location as Autodesk.Revit.DB.LocationCurve).Curve.GetEndPoint(0); if (!elmParms.ContainsKey("LocationX")) { elmParms.Add("LocationX", insPt.X); } if (!elmParms.ContainsKey("LocationY")) { elmParms.Add("LocationY", insPt.Y); } if (!elmParms.ContainsKey("LocationZ")) { elmParms.Add("LocationZ", insPt.Z); } insPt = (elm.Location as Autodesk.Revit.DB.LocationCurve).Curve.GetEndPoint(1); if (!elmParms.ContainsKey("LocationX2")) { elmParms.Add("LocationX2", insPt.X); } if (!elmParms.ContainsKey("LocationY2")) { elmParms.Add("LocationY2", insPt.Y); } if (!elmParms.ContainsKey("LocationZ2")) { elmParms.Add("LocationZ2", insPt.Z); } } foreach (var param in elm.Parameters.OfType <Autodesk.Revit.DB.Parameter>()) { var hp = new HLRevitParameter(param); var val = RevitToGraphValue(hp); if (!elmParms.ContainsKey(param.Definition.Name)) { elmParms.Add(param.Definition.Name, val); } if (!elmParms.ContainsKey(param.Definition.Name)) { elmParms.Add(param.Definition.Name, val); } } return(elmParms); }