/// <summary> /// Converts the Revit elements that have been added to the stream by the user, sends them to /// the Server and the local DB, and creates a commit with the objects. /// </summary> /// <param name="state">StreamState passed by the UI</param> public override async Task <StreamState> SendStream(StreamState state) { ConversionErrors.Clear(); OperationErrors.Clear(); var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(ConnectorRevitUtils.RevitAppName); converter.SetContextDocument(CurrentDoc.Document); var streamId = state.Stream.id; var client = state.Client; var selectedObjects = new List <Element>(); if (state.Filter != null) { selectedObjects = GetSelectionFilterObjects(state.Filter, converter); state.SelectedObjectIds = selectedObjects.Select(x => x.UniqueId).ToList(); } else //selection was by cursor { // TODO: update state by removing any deleted or null object ids selectedObjects = state.SelectedObjectIds.Select(x => CurrentDoc.Document.GetElement(x)).Where(x => x != null).ToList(); } if (!selectedObjects.Any()) { state.Errors.Add(new Exception("There are zero objects to send. Please use a filter, or set some via selection.")); return(state); } converter.SetContextObjects(selectedObjects.Select(x => new ApplicationPlaceholderObject { applicationId = x.UniqueId }).ToList()); var commitObject = new Base(); var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; Execute.PostToUIThread(() => state.Progress.Maximum = selectedObjects.Count()); var convertedCount = 0; var placeholders = new List <Base>(); foreach (var revitElement in selectedObjects) { try { if (revitElement == null) { continue; } if (!converter.CanConvertToSpeckle(revitElement)) { state.Errors.Add(new Exception($"Skipping not supported type: {revitElement.GetType()}, name {revitElement.Name}")); continue; } var conversionResult = converter.ConvertToSpeckle(revitElement); conversionProgressDict["Conversion"]++; UpdateProgress(conversionProgressDict, state.Progress); placeholders.Add(new ApplicationPlaceholderObject { applicationId = revitElement.UniqueId, ApplicationGeneratedId = revitElement.UniqueId }); convertedCount++; //hosted elements will be returned as `null` by the ConvertToSpeckle method //since they are handled when converting their parents if (conversionResult != null) { var category = $"@{revitElement.Category.Name}"; if (commitObject[category] == null) { commitObject[category] = new List <Base>(); } ((List <Base>)commitObject[category]).Add(conversionResult); } } catch (Exception e) { state.Errors.Add(e); } } if (converter.Report.ConversionErrorsCount != 0) { // TODO: Get rid of the custom Error class. It's not needed. ConversionErrors.AddRange(converter.Report.ConversionErrors); state.Errors.AddRange(converter.Report.ConversionErrors); } if (convertedCount == 0) { Globals.Notify("Zero objects converted successfully. Send stopped."); return(state); } Execute.PostToUIThread(() => state.Progress.Maximum = (int)commitObject.GetTotalChildrenCount()); if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(state); } var transports = new List <ITransport>() { new ServerTransport(client.Account, streamId) }; var objectId = await Operations.Send( @object : commitObject, cancellationToken : state.CancellationTokenSource.Token, transports : transports, onProgressAction : dict => UpdateProgress(dict, state.Progress), onErrorAction : (s, e) => { OperationErrors.Add(e); // TODO! state.Errors.Add(e); state.CancellationTokenSource.Cancel(); }, disposeTransports : true ); if (OperationErrors.Count != 0) { Globals.Notify("Failed to send."); state.Errors.AddRange(OperationErrors); return(state); } if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } var actualCommit = new CommitCreateInput() { streamId = streamId, objectId = objectId, branchName = state.Branch.name, message = state.CommitMessage != null ? state.CommitMessage : $"Sent {convertedCount} objects from {ConnectorRevitUtils.RevitAppName}.", sourceApplication = ConnectorRevitUtils.RevitAppName, }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); await state.RefreshStream(); state.PreviousCommitId = commitId; WriteStateToFile(); RaiseNotification($"{convertedCount} objects sent to Speckle 🚀"); } catch (Exception e) { state.Errors.Add(e); Globals.Notify($"Failed to create commit.\n{e.Message}"); } return(state); }
/// <summary> /// Receives a stream and bakes into the existing revit file. /// </summary> /// <param name="state"></param> /// <returns></returns> public override async Task <StreamState> ReceiveStream(StreamState state) { ConversionErrors.Clear(); OperationErrors.Clear(); var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(ConnectorRevitUtils.RevitAppName); converter.SetContextDocument(CurrentDoc.Document); var previouslyReceiveObjects = state.ReceivedObjects; var transport = new ServerTransport(state.Client.Account, state.Stream.id); string referencedObject = state.Commit.referencedObject; if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } //if "latest", always make sure we get the latest commit when the user clicks "receive" if (state.Commit.id == "latest") { var res = await state.Client.BranchGet(state.CancellationTokenSource.Token, state.Stream.id, state.Branch.name, 1); referencedObject = res.commits.items.FirstOrDefault().referencedObject; } var commit = state.Commit; var commitObject = await Operations.Receive( referencedObject, state.CancellationTokenSource.Token, transport, onProgressAction : dict => UpdateProgress(dict, state.Progress), onErrorAction : (s, e) => { OperationErrors.Add(e); state.Errors.Add(e); state.CancellationTokenSource.Cancel(); }, onTotalChildrenCountKnown : count => Execute.PostToUIThread(() => state.Progress.Maximum = count) ); if (OperationErrors.Count != 0) { Globals.Notify("Failed to get commit."); return(state); } if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } // Bake the new ones. Queue.Add(() => { using (var t = new Transaction(CurrentDoc.Document, $"Baking stream {state.Stream.name}")) { var failOpts = t.GetFailureHandlingOptions(); failOpts.SetFailuresPreprocessor(new ErrorEater(converter)); failOpts.SetClearAfterRollback(true); t.SetFailureHandlingOptions(failOpts); t.Start(); var flattenedObjects = FlattenCommitObject(commitObject, converter); // needs to be set for editing to work converter.SetPreviousContextObjects(previouslyReceiveObjects); // needs to be set for openings in floors and roofs to work converter.SetContextObjects(flattenedObjects.Select(x => new ApplicationPlaceholderObject { applicationId = x.applicationId, NativeObject = x }).ToList()); var newPlaceholderObjects = ConvertReceivedObjects(flattenedObjects, converter, state); // receive was cancelled by user if (newPlaceholderObjects == null) { converter.ConversionErrors.Add(new Exception("fatal error: receive cancelled by user")); t.RollBack(); return; } DeleteObjects(previouslyReceiveObjects, newPlaceholderObjects); state.ReceivedObjects = newPlaceholderObjects; t.Commit(); state.Errors.AddRange(converter.ConversionErrors); } }); Executor.Raise(); while (Queue.Count > 0) { //wait to let queue finish } if (converter.ConversionErrors.Any(x => x.Message.Contains("fatal error"))) { // the commit is being rolled back return(null); } try { await state.RefreshStream(); WriteStateToFile(); } catch (Exception e) { WriteStateToFile(); state.Errors.Add(e); Globals.Notify($"Receiving done, but failed to update stream from server.\n{e.Message}"); } return(state); }
public override async Task <StreamState> SendStream(StreamState state) { ConversionErrors.Clear(); OperationErrors.Clear(); var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(Utils.BentleyAppName); if (Control.InvokeRequired) { Control.Invoke(new SetContextDelegate(converter.SetContextDocument), new object[] { Session.Instance }); } else { converter.SetContextDocument(Session.Instance); } var streamId = state.Stream.id; var client = state.Client; var selectedObjects = new List <Object>(); if (state.Filter != null) { if (Control.InvokeRequired) { state.SelectedObjectIds = (List <string>)Control.Invoke(new GetObjectsFromFilterDelegate(GetObjectsFromFilter), new object[] { state.Filter, converter }); } else { state.SelectedObjectIds = GetObjectsFromFilter(state.Filter, converter); } } if (state.SelectedObjectIds.Count == 0 && !ExportGridLines) { RaiseNotification("Zero objects selected; send stopped. Please select some objects, or check that your filter can actually select something."); return(state); } var commitObj = new Base(); var units = Units.GetUnitsFromString(ModelUnits).ToLower(); commitObj["units"] = units; var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; Execute.PostToUIThread(() => state.Progress.Maximum = state.SelectedObjectIds.Count()); int convertedCount = 0; // grab elements from active model var objs = new List <Element>(); #if (OPENROADS || OPENRAIL) bool convertCivilObject = false; var civObjs = new List <NamedModelEntity>(); if (civilElementKeys.Count(x => state.SelectedObjectIds.Contains(x)) > 0) { if (Control.InvokeRequired) { civObjs = (List <NamedModelEntity>)Control.Invoke(new GetCivilObjectsDelegate(GetCivilObjects), new object[] { state }); } else { civObjs = GetCivilObjects(state); } objs = civObjs.Select(x => x.Element).ToList(); convertCivilObject = true; } else { objs = state.SelectedObjectIds.Select(x => Model.FindElementById((ElementId)Convert.ToUInt64(x))).ToList(); } #else objs = state.SelectedObjectIds.Select(x => Model.FindElementById((ElementId)Convert.ToUInt64(x))).ToList(); #endif #if (OPENBUILDINGS) if (ExportGridLines) { // grab grid lines ITFApplication appInst = new TFApplicationList(); if (0 == appInst.GetProject(0, out ITFLoadableProjectList projList) && projList != null) { ITFLoadableProject proj = projList.AsTFLoadableProject; if (null == proj) { return(null); } ITFDrawingGrid drawingGrid = null; if (Control.InvokeRequired) { Control.Invoke((Action)(() => { proj.GetDrawingGrid(false, 0, out drawingGrid); })); } else { proj.GetDrawingGrid(false, 0, out drawingGrid); } if (null == drawingGrid) { return(null); } Base converted; if (Control.InvokeRequired) { converted = (Base)Control.Invoke(new SpeckleConversionDelegate(converter.ConvertToSpeckle), new object[] { drawingGrid }); } else { converted = converter.ConvertToSpeckle(drawingGrid); } if (converted != null) { var containerName = "Grid Systems"; if (commitObj[$"@{containerName}"] == null) { commitObj[$"@{containerName}"] = new List <Base>(); } ((List <Base>)commitObj[$"@{containerName}"]).Add(converted); // not sure this makes much sense here conversionProgressDict["Conversion"]++; UpdateProgress(conversionProgressDict, state.Progress); //gridLine.applicationId = ??; convertedCount++; } } } #endif foreach (var obj in objs) { if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } if (obj == null) { state.Errors.Add(new Exception($"Failed to find local object.")); continue; } var objId = obj.ElementId.ToString(); var objType = obj.ElementType; if (!converter.CanConvertToSpeckle(obj)) { state.Errors.Add(new Exception($"Objects of type ${objType} are not supported")); continue; } // convert obj // try catch to prevent memory access violation crash in case a conversion goes wrong Base converted = null; string containerName = string.Empty; try { var levelCache = Model.GetFileLevelCache(); var objLevel = levelCache.GetLevel(obj.LevelId); var layerName = "Unknown"; if (objLevel != null) { layerName = objLevel.Name; } #if (OPENROADS || OPENRAIL) if (convertCivilObject) { var civilObj = civObjs[objs.IndexOf(obj)]; if (Control.InvokeRequired) { converted = (Base)Control.Invoke(new SpeckleConversionDelegate(converter.ConvertToSpeckle), new object[] { civilObj }); Control.Invoke((Action)(() => { containerName = civilObj.Name == "" ? "Unnamed" : civilObj.Name; })); } else { converted = converter.ConvertToSpeckle(civilObj); containerName = civilObj.Name == "" ? "Unnamed" : civilObj.Name; } } else { if (Control.InvokeRequired) { converted = (Base)Control.Invoke(new SpeckleConversionDelegate(converter.ConvertToSpeckle), new object[] { obj }); } else { converted = converter.ConvertToSpeckle(obj); } containerName = layerName; } #else if (Control.InvokeRequired) { converted = (Base)Control.Invoke(new SpeckleConversionDelegate(converter.ConvertToSpeckle), new object[] { obj }); } else { converted = converter.ConvertToSpeckle(obj); } containerName = layerName; #endif if (converted == null) { state.Errors.Add(new Exception($"Failed to convert object ${objId} of type ${objType}.")); continue; } } catch { state.Errors.Add(new Exception($"Failed to convert object {objId} of type {objType}.")); continue; } /* TODO: adding the feature data and properties per object * foreach (var key in obj.ExtensionDictionary) * { * converted[key] = obj.ExtensionDictionary.GetUserString(key); * } */ if (commitObj[$"@{containerName}"] == null) { commitObj[$"@{containerName}"] = new List <Base>(); } ((List <Base>)commitObj[$"@{containerName}"]).Add(converted); conversionProgressDict["Conversion"]++; UpdateProgress(conversionProgressDict, state.Progress); converted.applicationId = objId; convertedCount++; } Execute.PostToUIThread(() => state.Progress.Maximum = convertedCount); var transports = new List <ITransport>() { new ServerTransport(client.Account, streamId) }; var commitObjId = await Operations.Send( commitObj, state.CancellationTokenSource.Token, transports, onProgressAction : dict => UpdateProgress(dict, state.Progress), onErrorAction : (err, exception) => { Exceptions.Add(exception); } ); if (Exceptions.Count != 0) { RaiseNotification($"Failed to send: \n {Exceptions.Last().Message}"); return(null); } if (convertedCount > 0) { var actualCommit = new CommitCreateInput { streamId = streamId, objectId = commitObjId, branchName = state.Branch.name, message = state.CommitMessage != null ? state.CommitMessage : $"Pushed {convertedCount} elements from {Utils.AppName}.", sourceApplication = Utils.BentleyAppName }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); await state.RefreshStream(); state.PreviousCommitId = commitId; try { PersistAndUpdateStreamInFile(state); } catch (Exception e) { } RaiseNotification($"{convertedCount} objects sent to {state.Stream.name}."); } catch (Exception e) { Globals.Notify($"Failed to create commit.\n{e.Message}"); state.Errors.Add(e); } } else { Globals.Notify($"Did not create commit: no objects could be converted."); } return(state); }
public override async Task <StreamState> ReceiveStream(StreamState state) { ConversionErrors.Clear(); OperationErrors.Clear(); var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(Utils.BentleyAppName); if (converter == null) { RaiseNotification($"Could not find any Kit!"); state.CancellationTokenSource.Cancel(); return(null); } if (Control.InvokeRequired) { Control.Invoke(new SetContextDelegate(converter.SetContextDocument), new object[] { Session.Instance }); } else { converter.SetContextDocument(Session.Instance); } var previouslyReceiveObjects = state.ReceivedObjects; var transport = new ServerTransport(state.Client.Account, state.Stream.id); string referencedObject = state.Commit.referencedObject; if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } //if "latest", always make sure we get the latest commit when the user clicks "receive" if (state.Commit.id == "latest") { var res = await state.Client.BranchGet(state.CancellationTokenSource.Token, state.Stream.id, state.Branch.name, 1); referencedObject = res.commits.items.FirstOrDefault().referencedObject; } var commit = state.Commit; var commitObject = await Operations.Receive( referencedObject, state.CancellationTokenSource.Token, transport, onProgressAction : dict => UpdateProgress(dict, state.Progress), onErrorAction : (s, e) => { OperationErrors.Add(e); state.Errors.Add(e); state.CancellationTokenSource.Cancel(); }, onTotalChildrenCountKnown : count => Execute.PostToUIThread(() => state.Progress.Maximum = count) ); if (OperationErrors.Count != 0) { Globals.Notify("Failed to get commit."); return(state); } if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } var flattenedObjects = FlattenCommitObject(commitObject, converter); List <ApplicationPlaceholderObject> newPlaceholderObjects; if (Control.InvokeRequired) { newPlaceholderObjects = (List <ApplicationPlaceholderObject>)Control.Invoke(new NativeConversionAndBakeDelegate(ConvertAndBakeReceivedObjects), new object[] { flattenedObjects, converter, state }); } else { newPlaceholderObjects = ConvertAndBakeReceivedObjects(flattenedObjects, converter, state); } // receive was cancelled by user if (newPlaceholderObjects == null) { converter.Report.ConversionErrors.Add(new Exception("fatal error: receive cancelled by user")); return(null); } DeleteObjects(previouslyReceiveObjects, newPlaceholderObjects); state.ReceivedObjects = newPlaceholderObjects; state.Errors.AddRange(converter.Report.ConversionErrors); if (converter.Report.ConversionErrors.Any(x => x.Message.Contains("fatal error"))) { // the commit is being rolled back return(null); } try { await state.RefreshStream(); WriteStateToFile(); } catch (Exception e) { WriteStateToFile(); state.Errors.Add(e); Globals.Notify($"Receiving done, but failed to update stream from server.\n{e.Message}"); } return(state); }
public override async Task <StreamState> SendStream(StreamState state) { if (state.Filter != null) { state.SelectedObjectIds = GetSelectedObjects(); } var commitObject = new Base(); var streamId = state.Stream.id; var client = state.Client; // var selectedObjects = new List <Entity>(); //if (state.Filter != null) //{ // selectedObjects = GetSelectionFilterObjects(state.Filter); // state.SelectedObjectIds = selectedObjects.Select(x => x.UniqueId).ToList(); //} //else //selection was by cursor //{ // // TODO: update state by removing any deleted or null object ids //selectedObjects = state.SelectedObjectIds.Select(x => CurrentDoc.Document.GetElement(x)).Where(x => x != null).ToList(); //selectedObjects = state.SelectedObjectIds.Select(TopSolid.Kernel.UI.Selections.CurrentSelections.GetSelectedEntities()).ToString().ToList(); //} // var transports = new List <ITransport>() { new ServerTransport(client.Account, streamId) }; /* successful test for sending a topSolid line created by code ==> TODO same with line drawn graphically * TopSolid.Kernel.G.D3.Point point1 = new TopSolid.Kernel.G.D3.Point(0, 0, 0); * TopSolid.Kernel.G.D3.Point point2 = new TopSolid.Kernel.G.D3.Point(1, 1, 0); * commitObject = ConvertersSpeckleTopSolid.LineToSpeckle(new TopSolid.Kernel.G.D3.Curves.LineCurve(point1, point2)); */ var objectId = await Operations.Send( @object : commitObject, cancellationToken : state.CancellationTokenSource.Token, transports : transports, //onProgressAction: dict => UpdateProgress(dict, state.Progress), onErrorAction : (s, e) => { //OperationErrors.Add(e); // TODO! state.Errors.Add(e); state.CancellationTokenSource.Cancel(); } ); if (OperationErrors.Count != 0) { Globals.Notify("Failed to send."); state.Errors.AddRange(OperationErrors); return(state); } if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } var actualCommit = new CommitCreateInput() { streamId = streamId, objectId = objectId, branchName = state.Branch.name, message = state.CommitMessage != null ? state.CommitMessage : "Hello from TopSolid",//$"Sent {convertedCount} objects from {ConnectorRevitUtils.RevitAppName}.", sourceApplication = TopSolid.Kernel.UI.Application.Name, }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); await state.RefreshStream(); state.PreviousCommitId = commitId; //TO DO : Add the Objects Count //WriteStateToFile(); RaiseNotification($" *insert count* objects sent to Speckle 🚀"); } catch (Exception e) { state.Errors.Add(e); Globals.Notify($"Failed to create commit.\n{e.Message}"); } return(state); }
public override async Task <StreamState> SendStream(StreamState state) { var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(Utils.AutocadAppName); var streamId = state.Stream.id; var client = state.Client; if (state.Filter != null) { state.SelectedObjectIds = GetObjectsFromFilter(state.Filter, converter); } // remove deleted object ids var deletedElements = new List <string>(); foreach (var handle in state.SelectedObjectIds) { if (Doc.Database.TryGetObjectId(Utils.GetHandle(handle), out AcadDb.ObjectId id)) { if (id.IsErased || id.IsNull) { deletedElements.Add(handle); } } } state.SelectedObjectIds = state.SelectedObjectIds.Where(o => !deletedElements.Contains(o)).ToList(); if (state.SelectedObjectIds.Count == 0) { RaiseNotification("Zero objects selected; send stopped. Please select some objects, or check that your filter can actually select something."); return(state); } var commitObj = new Base(); /* Deprecated until we decide whether or not commit objs need units. If so, should add UnitsToSpeckle conversion method to connector * var units = Units.GetUnitsFromString(Doc.Database.Insunits.ToString()); * commitObj["units"] = units; */ var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; Execute.PostToUIThread(() => state.Progress.Maximum = state.SelectedObjectIds.Count()); int convertedCount = 0; bool renamedlayers = false; using (Transaction tr = Doc.Database.TransactionManager.StartTransaction()) { converter.SetContextDocument(Doc); // set context doc here to capture transaction prop foreach (var autocadObjectHandle in state.SelectedObjectIds) { if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } // get the db object from id AcadDb.Handle hn = Utils.GetHandle(autocadObjectHandle); AcadDb.DBObject obj = hn.GetObject(out string type, out string layer); if (obj == null) { state.Errors.Add(new Exception($"Failed to find local object ${autocadObjectHandle}.")); continue; } if (!converter.CanConvertToSpeckle(obj)) { state.Errors.Add(new Exception($"Objects of type ${type} are not supported")); continue; } // convert obj // try catch to prevent memory access violation crash in case a conversion goes wrong Base converted = null; string containerName = string.Empty; try { converted = converter.ConvertToSpeckle(obj); if (converted == null) { state.Errors.Add(new Exception($"Failed to convert object ${autocadObjectHandle} of type ${type}.")); continue; } } catch { state.Errors.Add(new Exception($"Failed to convert object {autocadObjectHandle} of type {type}.")); continue; } /* TODO: adding the extension dictionary / xdata per object * foreach (var key in obj.ExtensionDictionary) * { * converted[key] = obj.ExtensionDictionary.GetUserString(key); * } */ if (obj is BlockReference) { containerName = "Blocks"; } else { // remove invalid chars from layer name string cleanLayerName = Utils.RemoveInvalidDynamicPropChars(layer); containerName = cleanLayerName; if (!cleanLayerName.Equals(layer)) { renamedlayers = true; } } if (commitObj[$"@{containerName}"] == null) { commitObj[$"@{containerName}"] = new List <Base>(); } ((List <Base>)commitObj[$"@{containerName}"]).Add(converted); conversionProgressDict["Conversion"]++; UpdateProgress(conversionProgressDict, state.Progress); converted.applicationId = autocadObjectHandle; convertedCount++; } tr.Commit(); } if (renamedlayers) { RaiseNotification("Replaced illegal chars ./ with - in one or more layer names."); } if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } Execute.PostToUIThread(() => state.Progress.Maximum = convertedCount); var transports = new List <ITransport>() { new ServerTransport(client.Account, streamId) }; var commitObjId = await Operations.Send( commitObj, state.CancellationTokenSource.Token, transports, onProgressAction : dict => UpdateProgress(dict, state.Progress), onErrorAction : (err, exception) => { Exceptions.Add(exception); }, disposeTransports : true ); if (Exceptions.Count != 0) { RaiseNotification($"Failed to send: \n {Exceptions.Last().Message}"); return(null); } if (convertedCount > 0) { var actualCommit = new CommitCreateInput { streamId = streamId, objectId = commitObjId, branchName = state.Branch.name, message = state.CommitMessage != null ? state.CommitMessage : $"Pushed {convertedCount} elements from {Utils.AppName}.", sourceApplication = Utils.AutocadAppName }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); await state.RefreshStream(); state.PreviousCommitId = commitId; PersistAndUpdateStreamInFile(state); RaiseNotification($"{convertedCount} objects sent to {state.Stream.name}."); } catch (Exception e) { Globals.Notify($"Failed to create commit.\n{e.Message}"); state.Errors.Add(e); } } else { Globals.Notify($"Did not create commit: no objects could be converted."); } return(state); }
public override async Task <StreamState> SendStream(StreamState state) { var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(Utils.AutocadAppName); converter.SetContextDocument(Doc); var streamId = state.Stream.id; var client = state.Client; if (state.Filter != null) { state.SelectedObjectIds = GetObjectsFromFilter(state.Filter); } if (state.SelectedObjectIds.Count == 0) { RaiseNotification("Zero objects selected; send stopped. Please select some objects, or check that your filter can actually select something."); return(state); } var commitObj = new Base(); var units = Units.GetUnitsFromString(Doc.Database.Insunits.ToString()); commitObj["units"] = units; var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; Execute.PostToUIThread(() => state.Progress.Maximum = state.SelectedObjectIds.Count()); int convertedCount = 0; bool renamedlayers = false; foreach (var autocadObjectHandle in state.SelectedObjectIds) { if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } // get the db object from id AcadDb.Handle hn = new AcadDb.Handle(Convert.ToInt64(autocadObjectHandle, 16)); AcadDb.DBObject obj = hn.GetObject(out string type, out string layer); string cleanLayerName = Utils.RemoveInvalidDynamicPropChars(layer); if (!cleanLayerName.Equals(layer)) { renamedlayers = true; } if (obj == null) { state.Errors.Add(new Exception($"Failed to find local object ${autocadObjectHandle}.")); continue; } if (!converter.CanConvertToSpeckle(obj)) { state.Errors.Add(new Exception($"Objects of type ${type} are not supported")); continue; } // convert geo to speckle base if (!converter.CanConvertToSpeckle(obj)) { state.Errors.Add(new Exception($"Skipping object {autocadObjectHandle}, {obj.GetType()} type not supported")); continue; } Base converted = converter.ConvertToSpeckle(obj); if (converted == null) { state.Errors.Add(new Exception($"Failed to convert object ${autocadObjectHandle} of type ${type}.")); continue; } conversionProgressDict["Conversion"]++; UpdateProgress(conversionProgressDict, state.Progress); converted.applicationId = autocadObjectHandle; /* TODO: adding the extension dictionary / xdata per object * foreach (var key in obj.ExtensionDictionary) * { * converted[key] = obj.ExtensionDictionary.GetUserString(key); * } */ if (commitObj[$"@{cleanLayerName}"] == null) { commitObj[$"@{cleanLayerName}"] = new List <Base>(); } ((List <Base>)commitObj[$"@{cleanLayerName}"]).Add(converted); convertedCount++; } if (renamedlayers) { RaiseNotification("Replaced illegal chars ./ with - in one or more layer names."); } if (state.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } Execute.PostToUIThread(() => state.Progress.Maximum = convertedCount); var transports = new List <ITransport>() { new ServerTransport(client.Account, streamId) }; var commitObjId = await Operations.Send( commitObj, state.CancellationTokenSource.Token, transports, onProgressAction : dict => UpdateProgress(dict, state.Progress), onErrorAction : (err, exception) => { Exceptions.Add(exception); } ); if (Exceptions.Count != 0) { RaiseNotification($"Failed to send: \n {Exceptions.Last().Message}"); return(null); } var actualCommit = new CommitCreateInput { streamId = streamId, objectId = commitObjId, branchName = state.Branch.name, message = state.CommitMessage != null ? state.CommitMessage : $"Pushed {convertedCount} elements from AutoCAD.", sourceApplication = Utils.AutocadAppName }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); await state.RefreshStream(); state.PreviousCommitId = commitId; PersistAndUpdateStreamInFile(state); RaiseNotification($"{convertedCount} objects sent to {state.Stream.name}."); } catch (Exception e) { Globals.Notify($"Failed to create commit.\n{e.Message}"); state.Errors.Add(e); } return(state); }