Skip to content

Commit

Permalink
Add method in Navisworks to create clashes from clash reports
Browse files Browse the repository at this point in the history
  • Loading branch information
GeorgDangl committed May 23, 2024
1 parent 4c94e83 commit 267db14
Show file tree
Hide file tree
Showing 12 changed files with 548 additions and 81 deletions.
27 changes: 6 additions & 21 deletions src/IPA.Bcfier.App/Controllers/LastOpenedFilesController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using IPA.Bcfier.App.Data;
using IPA.Bcfier.App.Models.Controllers.LastOpenedFiles;
using IPA.Bcfier.App.Services;
using IPA.Bcfier.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
Expand All @@ -14,12 +15,15 @@ public class LastOpenedFilesController : ControllerBase
{
private readonly BcfierDbContext _context;
private readonly SettingsService _settingsService;
private readonly LastOpenedFilesService _lastOpenedFilesService;

public LastOpenedFilesController(BcfierDbContext context,
SettingsService settingsService)
SettingsService settingsService,
LastOpenedFilesService lastOpenedFilesService)
{
_context = context;
_settingsService = settingsService;
_lastOpenedFilesService = lastOpenedFilesService;
}

[HttpGet("")]
Expand Down Expand Up @@ -51,26 +55,7 @@ public async Task<IActionResult> GetLastOpenedFilesAsync([FromQuery]Guid? projec
[ProducesResponseType((int)HttpStatusCode.NoContent)]
public async Task<IActionResult> SetFileAsLastOpened([FromQuery]Guid? projectId, [FromQuery, Required]string filePath)
{
var userName = (await _settingsService.LoadSettingsAsync()).Username;
var existingEntry = await _context.LastOpenedUserFiles
.FirstOrDefaultAsync(louf => louf.ProjectId == projectId
&& louf.UserName == userName
&& louf.FilePath == filePath);
if (existingEntry != null)
{
existingEntry.OpenedAtAtUtc = DateTimeOffset.UtcNow;
}
else
{
_context.LastOpenedUserFiles.Add(new Data.Models.LastOpenedUserFile
{
ProjectId = projectId,
UserName = userName,
FilePath = filePath
});
}

await _context.SaveChangesAsync();
await _lastOpenedFilesService.SetFileAsLastOpenedAsync(projectId, filePath);
return NoContent();
}
}
Expand Down
45 changes: 45 additions & 0 deletions src/IPA.Bcfier.App/Controllers/ViewpointsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,51 @@ await ipcHandler.SendMessageAsync(JsonConvert.SerializeObject(new IpcMessage
return BadRequest();
}

[HttpPost("navisworks-clashes")]
[ProducesResponseType(typeof(ApiError), (int)HttpStatusCode.BadRequest)]
[ProducesResponseType(typeof(List<BcfTopic>), (int)HttpStatusCode.OK)]
public async Task<IActionResult> CreateNavisworksClashDetectionResultIssuesAsync()
{
if (!_navisworksParameters.IsConnectedToNavisworks)
{
return BadRequest(new ApiError("The app is currently not connected to Navisworks"));
}

using var ipcHandler = GetIpcHandler();
await ipcHandler.InitializeAsync();

var correlationId = Guid.NewGuid();
await ipcHandler.SendMessageAsync(JsonConvert.SerializeObject(new IpcMessage
{
CorrelationId = correlationId,
Command = IpcMessageCommand.CreateNavisworksClashDetectionIssues,
Data = null
}));

var hasReceived = false;
var start = DateTime.Now;
// We're waiting up to 20 minutes for the results here - could take a while for large clash results
while (DateTime.UtcNow - start < TimeSpan.FromSeconds(1200) && !hasReceived)
{
if (IpcHandler.ReceivedMessages.TryDequeue(out var message))
{
var ipcMessage = JsonConvert.DeserializeObject<IpcMessage>(message)!;
if (ipcMessage.CorrelationId == correlationId)
{
hasReceived = true;
var bcfViewpoint = JsonConvert.DeserializeObject<List<BcfTopic>>(ipcMessage.Data!)!;
return Ok(bcfViewpoint);
}
else
{
IpcHandler.ReceivedMessages.Enqueue(message);
}
}
}

return BadRequest();
}

private IpcHandler GetIpcHandler()
{
if (_revitParameters.IsConnectedToRevit)
Expand Down
12 changes: 12 additions & 0 deletions src/IPA.Bcfier.Navisworks/IpcNavisworksCommandListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ await _ipcHandler.SendMessageAsync(JsonConvert.SerializeObject(new IpcMessage
});
break;

case IpcMessageCommand.CreateNavisworksClashDetectionIssues:
_navisworksTaskHandler.CreateNavisworksClashIssuesCallbacks.Enqueue(async (data) =>
{
await _ipcHandler.SendMessageAsync(JsonConvert.SerializeObject(new IpcMessage
{
CorrelationId = ipcMessage.CorrelationId,
Command = IpcMessageCommand.NavisworksClashDetectionIssuesCreated,
Data = data
}));
});
break;

case IpcMessageCommand.ShowViewpoint:
_navisworksTaskHandler.ShowViewpointQueueItems.Enqueue(new ShowViewpointQueueItem
{
Expand Down
34 changes: 34 additions & 0 deletions src/IPA.Bcfier.Navisworks/NavisworksTaskQueueHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace IPA.Bcfier.Navisworks
public class NavisworksTaskQueueHandler
{
public Queue<Func<string, Task>> CreateNavisworksViewpointCallbacks { get; } = new Queue<Func<string, Task>>();
public Queue<Func<string, Task>> CreateNavisworksClashIssuesCallbacks { get; } = new Queue<Func<string, Task>>();
public Queue<ShowViewpointQueueItem> ShowViewpointQueueItems { get; } = new Queue<ShowViewpointQueueItem>();
private bool shouldUnregister = false;

Expand All @@ -27,6 +28,13 @@ public void OnIdling(object sender, EventArgs args)
HandleCreateNavisworksViewpointCallback(callback, uiDocument);
}

if (CreateNavisworksClashIssuesCallbacks.Count > 0)
{
var uiDocument = Application.ActiveDocument;
var callback = CreateNavisworksClashIssuesCallbacks.Dequeue();
HandleCreateNavisworksClashIssuesCallback(callback, uiDocument);
}

if (ShowViewpointQueueItems.Count > 0)
{
var uiDocument = Application.ActiveDocument;
Expand Down Expand Up @@ -66,6 +74,32 @@ private void HandleCreateNavisworksViewpointCallback(Func<string, Task> callback
});
}

private void HandleCreateNavisworksClashIssuesCallback(Func<string, Task> callback, Document uiDocument)
{
var viewpointService = new NavisworksViewpointCreationService(uiDocument);
var clashIssues = viewpointService.CreateClashIssues();
var contractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
};
var serializerSettings = new JsonSerializerSettings
{
ContractResolver = contractResolver,
Formatting = Formatting.Indented
};
Task.Run(async () =>
{
if (clashIssues == null)
{
await callback("[]");
}
else
{
await callback(JsonConvert.SerializeObject(clashIssues, serializerSettings));
}
});
}

private void HandleShowNavisworksViewpointCallback(Func<Task>? callback, BcfViewpoint? viewpoint, Document uiDocument)
{
if (callback == null || viewpoint == null)
Expand Down
Loading

0 comments on commit 267db14

Please sign in to comment.