Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c7a0256
Initial plan
Copilot Jan 2, 2026
05b5fd1
Add MakerPrompt.Shared.ShapeIt project with CADability integration
Copilot Jan 2, 2026
7d19dc4
Add web and MAUI renderers with Blazor CAD component
Copilot Jan 2, 2026
06d3831
Address code review feedback: add IDisposable, fix event leaks, impro…
Copilot Jan 2, 2026
3ea3eb8
Initial plan
Copilot Jan 2, 2026
d91ee78
Add BrailleRAP core engine with models and services
Copilot Jan 2, 2026
54cbb05
Add BrailleRAP UI page with navigation and localization
Copilot Jan 2, 2026
dc7eaad
Update README with BrailleRAP feature documentation
Copilot Jan 2, 2026
7153e46
Add CAD page with navigation and move component to Shared
Copilot Jan 2, 2026
fe5fa77
Address code review feedback: extract magic constants and fix icon class
Copilot Jan 2, 2026
7a1a253
Add multi-language support and improve Braille visualizer
Copilot Jan 2, 2026
94bf944
Add BrailleRAP translations to all language resource files
Copilot Jan 2, 2026
3e8c1da
Remove temporary files from repository
Copilot Jan 2, 2026
5e93f68
Fix Braille preview not showing - add event handlers for input changes
Copilot Jan 2, 2026
dd6a17e
Merge pull request #12 from akinbender/copilot/add-braillerap-page-ba…
akinbender Jan 2, 2026
4b544d6
Initial plan
Copilot Jan 2, 2026
dd38d7d
Add MakerPrompt.Shared.ShapeIt project with CADability integration
Copilot Jan 2, 2026
040386c
Add web and MAUI renderers with Blazor CAD component
Copilot Jan 2, 2026
4db0dd0
Address code review feedback: add IDisposable, fix event leaks, impro…
Copilot Jan 2, 2026
09053c8
Add CAD page with navigation and move component to Shared
Copilot Jan 2, 2026
302521a
Merge branch 'copilot/add-shapeit-cad-integration' of https://github.…
akinbender Jan 2, 2026
c3f4262
offf
akinbender Jan 2, 2026
853f810
Implement primitive creation tools (Box, Sphere, Cylinder, Cone) with…
Copilot Jan 2, 2026
84c4c85
Fix "No model is loaded" error by auto-initializing document on load
Copilot Jan 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MakerPrompt.Blazor/MakerPrompt.Blazor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

<ItemGroup>
<ProjectReference Include="..\MakerPrompt.Shared\MakerPrompt.Shared.csproj" />
<ProjectReference Include="..\MakerPrompt.Shared.ShapeIt\MakerPrompt.Shared.ShapeIt.csproj" />
</ItemGroup>

</Project>
5 changes: 5 additions & 0 deletions MakerPrompt.Blazor/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Globalization;
using MakerPrompt.Blazor;
using MakerPrompt.Blazor.Services;
using MakerPrompt.Shared.ShapeIt;
using MakerPrompt.Shared.Utils;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
Expand All @@ -11,6 +12,10 @@
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.RegisterMakerPromptSharedServices<AppConfigurationService, WebSerialService>();
builder.Services.AddShapeItForMakerPrompt();

// Override the default NullSceneRenderer with the web-based renderer for Blazor
builder.Services.AddScoped<MakerPrompt.Shared.ShapeIt.Rendering.ISceneRenderer, WebCadSceneRenderer>();

var host = builder.Build();
const string defaultCulture = "en-US";
Expand Down
63 changes: 63 additions & 0 deletions MakerPrompt.Blazor/Services/WebCadSceneRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using MakerPrompt.Shared.ShapeIt.Rendering;
using Microsoft.JSInterop;

namespace MakerPrompt.Blazor.Services;

/// <summary>
/// Web-based CAD scene renderer using a dedicated Web Worker and OffscreenCanvas.
/// </summary>
public class WebCadSceneRenderer : ISceneRenderer
{
private readonly IJSRuntime _jsRuntime;
private bool _initialized;

public WebCadSceneRenderer(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}

public async Task InitializeAsync(CancellationToken ct = default)
{
if (_initialized)
return;

// Initialize the CAD renderer with a canvas element
// The canvas ID would need to be provided by the component using this renderer
_initialized = true;
await Task.CompletedTask;
}

public async Task RenderAsync(SceneSnapshot snapshot, CancellationToken ct = default)
{
if (!_initialized)
throw new InvalidOperationException("Renderer not initialized. Call InitializeAsync first.");

// Send scene snapshot to the web worker via JS interop
await _jsRuntime.InvokeVoidAsync("cadRenderer.render", snapshot);
}

public async Task SetCameraAsync(CameraState camera, CancellationToken ct = default)
{
if (!_initialized)
throw new InvalidOperationException("Renderer not initialized. Call InitializeAsync first.");

// Send camera state to the web worker via JS interop
await _jsRuntime.InvokeVoidAsync("cadRenderer.setCamera", camera);
}

public async ValueTask DisposeAsync()
{
if (_initialized)
{
try
{
await _jsRuntime.InvokeVoidAsync("cadRenderer.dispose");
}
catch
{
// Ignore errors during disposal
}
_initialized = false;
}
}
}
72 changes: 72 additions & 0 deletions MakerPrompt.Blazor/wwwroot/cadRendererInterop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// CAD Renderer JavaScript Interop
// Bridges Blazor C# with the CAD Web Worker

window.cadRenderer = {
worker: null,
canvas: null,

initialize: async function(canvasId) {
console.log('Initializing CAD renderer for canvas:', canvasId);

// Get canvas element
this.canvas = document.getElementById(canvasId);
if (!this.canvas) {
console.error('Canvas not found:', canvasId);
return false;
}

// Create and initialize worker
try {
this.worker = new Worker('makerpromptCadWorker.js');

// Wait for initialization
return new Promise((resolve) => {
this.worker.addEventListener('message', function handler(e) {
if (e.data.type === 'initialized') {
this.removeEventListener('message', handler);
resolve(e.data.success);
}
});

// Send init message
this.worker.postMessage({ type: 'init', data: { canvasId } });
});
} catch (error) {
console.error('Failed to create CAD worker:', error);
return false;
}
},

render: function(sceneSnapshot) {
if (!this.worker) {
console.error('CAD worker not initialized');
return;
}

this.worker.postMessage({
type: 'render',
data: sceneSnapshot
});
},

setCamera: function(cameraState) {
if (!this.worker) {
console.error('CAD worker not initialized');
return;
}

this.worker.postMessage({
type: 'setCamera',
data: cameraState
});
},

dispose: function() {
if (this.worker) {
this.worker.postMessage({ type: 'dispose' });
this.worker.terminate();
this.worker = null;
}
this.canvas = null;
}
};
15 changes: 15 additions & 0 deletions MakerPrompt.Blazor/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,28 @@
</div>
<script src="_content/MakerPrompt.Shared/lib/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="_content/MakerPrompt.Shared/lib/gcode-viewer/_bundles/gcode-viewer.min.js"></script>
<script src="cadRendererInterop.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
<script>navigator.serviceWorker.register('service-worker.js');</script>
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};

// Helper function for downloading files
window.downloadFile = function(filename, base64Content, mimeType) {
const bytes = Uint8Array.from(atob(base64Content), c => c.charCodeAt(0));
const blob = new Blob([bytes], { type: mimeType });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
};
</script>
</body>

Expand Down
37 changes: 37 additions & 0 deletions MakerPrompt.Blazor/wwwroot/makerpromptCadWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// MakerPrompt CAD Worker
// Dedicated worker for non-blocking WebGL CAD rendering using OffscreenCanvas

self.addEventListener('message', function(e) {
const { type, data } = e.data;

switch(type) {
case 'init':
// Initialize WebGL context with OffscreenCanvas
console.log('CAD Worker: Initializing...');
self.postMessage({ type: 'initialized', success: true });
break;

case 'render':
// Render scene snapshot
console.log('CAD Worker: Rendering scene with', data.nodes?.length || 0, 'nodes');
self.postMessage({ type: 'rendered', success: true });
break;

case 'setCamera':
// Update camera state
console.log('CAD Worker: Setting camera');
self.postMessage({ type: 'cameraSet', success: true });
break;

case 'dispose':
// Cleanup resources
console.log('CAD Worker: Disposing...');
self.postMessage({ type: 'disposed', success: true });
break;

default:
console.warn('CAD Worker: Unknown message type', type);
}
});

console.log('MakerPrompt CAD Worker loaded');
1 change: 1 addition & 0 deletions MakerPrompt.MAUI/MakerPrompt.MAUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@

<ItemGroup>
<ProjectReference Include="..\MakerPrompt.Shared\MakerPrompt.Shared.csproj" />
<ProjectReference Include="..\MakerPrompt.Shared.ShapeIt\MakerPrompt.Shared.ShapeIt.csproj" />
</ItemGroup>

</Project>
8 changes: 8 additions & 0 deletions MakerPrompt.MAUI/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Microsoft.Extensions.Logging;
using MakerPrompt.Shared.Utils;
using MakerPrompt.Shared.ShapeIt;
using MakerPrompt.Shared.ShapeIt.Rendering;
using Microsoft.AspNetCore.Builder;
using MakerPrompt.MAUI.Services;

Expand Down Expand Up @@ -35,6 +37,12 @@ public static MauiApp CreateMauiApp()
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
builder.Services.RegisterMakerPromptSharedServices<AppConfigurationService, SerialService>();

// Register ShapeIt CAD services
builder.Services.AddShapeItForMakerPrompt();
// Override with MAUI-specific renderer
builder.Services.AddScoped<ISceneRenderer, MauiCadSceneRenderer>();

return builder.Build();
}
}
Expand Down
34 changes: 34 additions & 0 deletions MakerPrompt.MAUI/Services/MauiCadSceneRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using MakerPrompt.Shared.ShapeIt.Rendering;

namespace MakerPrompt.MAUI.Services;

/// <summary>
/// MAUI stub renderer for CAD scenes.
/// This is a minimal implementation placeholder for future MAUI-specific rendering.
/// </summary>
public class MauiCadSceneRenderer : ISceneRenderer
{
public Task InitializeAsync(CancellationToken ct = default)
{
// TODO: Implement MAUI-specific initialization
return Task.CompletedTask;
}

public Task RenderAsync(SceneSnapshot snapshot, CancellationToken ct = default)
{
// TODO: Implement MAUI-specific rendering
return Task.CompletedTask;
}

public Task SetCameraAsync(CameraState camera, CancellationToken ct = default)
{
// TODO: Implement MAUI-specific camera handling
return Task.CompletedTask;
}

public ValueTask DisposeAsync()
{
// TODO: Implement MAUI-specific cleanup
return ValueTask.CompletedTask;
}
}
Loading