Hi @fraguada ,
This is my code
Convert 3dm to stl
//using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloRhinoCompute
{
static class Convert3dm
{
public static string Convert3dmToPdf(string data)
{
var decodedData = Convert.FromBase64String(data);
var file3dm = Rhino.FileIO.File3dm.FromByteArray(decodedData);
// create headless doc and add geometry from 3dm file
var doc = Rhino.RhinoDoc.CreateHeadless(null);
foreach (var obj in file3dm.Objects)
{
doc.Objects.Add(obj.Geometry, obj.Attributes);
}
// set "front" view for export
var view = doc.Views.Add("view1", Rhino.Display.DefinedViewportProjection.Front, new System.Drawing.Rectangle(0,0,1,1), false);
doc.Views.ActiveView = view;
// export!
var id = Guid.NewGuid();
string path = Path.GetTempPath();
string filename = Path.Combine(path, "convert3dm_" + id + ".pdf");
if (!doc.Export(filename))
{
throw new InvalidOperationException("Export failed");
}
byte[] bytes = File.ReadAllBytes(filename);
return Convert.ToBase64String(bytes);
}
public static async Task<string> Convert3dmToStl(string data)
{
// Decode base64 data to bytes
var decodedData = Convert.FromBase64String(data);
var file3dm = Rhino.FileIO.File3dm.FromByteArray(decodedData);
// Create a headless Rhino document
var doc = Rhino.RhinoDoc.CreateHeadless(null);
// Add all objects from the 3DM file to the document
foreach (var obj in file3dm.Objects)
{
doc.Objects.Add(obj.Geometry, obj.Attributes);
}
// Generate a unique filename for the STL export
var id = Guid.NewGuid();
string path = Path.GetTempPath();
string filename = Path.Combine(path, "convert3dm_" + id + ".stl");
// Define the STL export options
var stlOptions = new Rhino.FileIO.FileWriteOptions
{
WriteSelectedObjectsOnly = false, // Export all objects in the document
SuppressAllInput = true // Ensure headless export runs without prompts
};
// Export the document as an STL file
if (!doc.WriteFile(filename, stlOptions))
{
throw new InvalidOperationException("Failed to export the document as STL");
}
// Read the STL file into a byte array
byte[] bytes = File.ReadAllBytes(filename);
// Clean up the headless document
doc.Dispose();
// Return the STL file encoded as a Base64 string
return Convert.ToBase64String(bytes);
}
}
}
Plugin.cs
using Rhino.PlugIns;
using Rhino.UI.Forms;
//using System.Management;
namespace HelloRhinoCompute
{
///<summary>
/// <para>Every RhinoCommon .rhp assembly must have one and only one PlugIn-derived
/// class. DO NOT create instances of this class yourself. It is the
/// responsibility of Rhino to create an instance of this class.</para>
/// <para>To complete plug-in information, please also see all PlugInDescription
/// attributes in AssemblyInfo.cs (you might need to click "Project" ->
/// "Show All Files" to see it in the "Solution Explorer" window).</para>
///</summary>
public class HelloRhinoComputePlugIn : Rhino.PlugIns.PlugIn
{
public HelloRhinoComputePlugIn()
{
Instance = this;
}
///<summary>Gets the only instance of the HelloRhinoCommonPlugIn plug-in.</summary>
public static HelloRhinoComputePlugIn Instance
{
get; private set;
}
// You can override methods here to change the plug-in behavior on
// loading and shut down, add options pages to the Rhino _Option command
// and maintain plug-in wide options in a document.
public override PlugInLoadTime LoadTime => PlugInLoadTime.AtStartup;
protected override LoadReturnCode OnLoad(ref string errorMessage)
{
Rhino.RhinoApp.WriteLine("Loading HelloRhinoComputePlugIn!");
// register custom compute endpoints
Rhino.Runtime.HostUtils.RegisterComputeEndpoint("sample", typeof(Convert3dm));
return base.OnLoad(ref errorMessage);
}
}
}
And this should all work fine
I’m having trouble with my Rhinocompute integration so the problem is here
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3DM to STL Converter</title>
<script src="https://files.mcneel.com/rhino3dm/js/rhino3dm.js"></script>
<script src="https://files.mcneel.com/rhinocompute/js/compute.rhino3d.js"></script>
</head>
<body>
<h1>3DM to STL Conversion</h1>
<input type="file" id="upload3dm" accept=".3dm" />
<button id="convertBtn">Convert to STL</button>
<p id="status">Status: Waiting for file upload...</p>
<a id="downloadLink" style="display:none;">Download STL</a>
<script>
// Configure RhinoCompute
RhinoCompute.url = 'http://xx.xx.xx.xx/'; // Your Rhino Compute server URL
RhinoCompute.apiKey = 'xxx'; // Your API key
window.onload = function () {
console.log("Window loaded");
const convertBtn = document.getElementById("convertBtn");
convertBtn.addEventListener("click", handleFileUpload);
};
async function handleFileUpload() {
const fileInput = document.getElementById("upload3dm");
if (fileInput.files.length === 0) {
document.getElementById("status").textContent = "Please upload a 3DM file.";
return;
}
const file = fileInput.files[0];
const reader = new FileReader();
reader.onload = async function (event) {
const fileData = event.target.result;
document.getElementById("status").textContent = "Converting 3DM to STL...";
await convert3dmToStl(fileData);
};
reader.readAsArrayBuffer(file);
}
async function convert3dmToStl(fileBuffer) {
try {
let base64Data = arrayBufferToBase64(fileBuffer);
// Use the correct RhinoCompute method and endpoint
const res = await RhinoCompute.computeFetch('sample/convert3dmtostl-string', [base64Data], true);
// Convert base64 STL back to ArrayBuffer
const stlBuffer = base64ToArrayBuffer(res);
// Create a download link for the STL file
createDownloadLink(stlBuffer, "converted_model.stl");
document.getElementById("status").textContent = "Conversion successful! You can download the STL file.";
} catch (error) {
console.error("Error converting 3DM to STL:", error);
document.getElementById("status").textContent = "Error during conversion: " + error.message;
}
}
function createDownloadLink(stlBuffer, fileName) {
const blob = new Blob([stlBuffer], { type: 'application/sla' });
const url = window.URL.createObjectURL(blob);
const downloadLink = document.getElementById("downloadLink");
downloadLink.href = url;
downloadLink.download = fileName;
downloadLink.style.display = 'block';
downloadLink.textContent = "Download STL";
}
function arrayBufferToBase64(buffer) {
let binary = '';
let bytes = new Uint8Array(buffer);
let len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
function base64ToArrayBuffer(base64) {
let binaryString = window.atob(base64);
let len = binaryString.length;
let bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3DM to STL Converter</title>
<script src="https://files.mcneel.com/rhino3dm/js/rhino3dm.js"></script>
<script src="https://files.mcneel.com/rhinocompute/js/compute.rhino3d.js"></script>
</head>
<body>
<h1>3DM to STL Conversion</h1>
<input type="file" id="upload3dm" accept=".3dm" />
<button id="convertBtn">Convert to STL</button>
<p id="status">Status: Waiting for file upload...</p>
<a id="downloadLink" style="display:none;">Download STL</a>
<script>
// Configure RhinoCompute
RhinoCompute.url = 'http://xx.xx.xx.xx/'; // Your Rhino Compute server URL
RhinoCompute.apiKey = 'xxx'; // Your API key
window.onload = function () {
console.log("Window loaded");
const convertBtn = document.getElementById("convertBtn");
convertBtn.addEventListener("click", handleFileUpload);
};
async function handleFileUpload() {
const fileInput = document.getElementById("upload3dm");
if (fileInput.files.length === 0) {
document.getElementById("status").textContent = "Please upload a 3DM file.";
return;
}
const file = fileInput.files[0];
const reader = new FileReader();
reader.onload = async function (event) {
const fileData = event.target.result;
document.getElementById("status").textContent = "Converting 3DM to STL...";
await convert3dmToStl(fileData);
};
reader.readAsArrayBuffer(file);
}
async function convert3dmToStl(fileBuffer) {
try {
let base64Data = arrayBufferToBase64(fileBuffer);
// Use the correct RhinoCompute method and endpoint
const res = await RhinoCompute.computeFetch('sample/convert3dmtostl-string', [base64Data], true);
// Convert base64 STL back to ArrayBuffer
const stlBuffer = base64ToArrayBuffer(res);
// Create a download link for the STL file
createDownloadLink(stlBuffer, "converted_model.stl");
document.getElementById("status").textContent = "Conversion successful! You can download the STL file.";
} catch (error) {
console.error("Error converting 3DM to STL:", error);
document.getElementById("status").textContent = "Error during conversion: " + error.message;
}
}
function createDownloadLink(stlBuffer, fileName) {
const blob = new Blob([stlBuffer], { type: 'application/sla' });
const url = window.URL.createObjectURL(blob);
const downloadLink = document.getElementById("downloadLink");
downloadLink.href = url;
downloadLink.download = fileName;
downloadLink.style.display = 'block';
downloadLink.textContent = "Download STL";
}
function arrayBufferToBase64(buffer) {
let binary = '';
let bytes = new Uint8Array(buffer);
let len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
function base64ToArrayBuffer(base64) {
let binaryString = window.atob(base64);
let len = binaryString.length;
let bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
</script>
</body>
</html>
While If I do it like this for a pre-existing endpoint it works
let args = [geometry];
// Calculate AreaMassProperties
let areaMassPropertiesEndpoint = 'http://xx/rhino/geometry/areamassproperties/compute-brep';
let areaMassPropertiesResponse = await fetch(areaMassPropertiesEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'RhinoComputeKey': 'xx',
'User-Agent': `compute.rhino3d.js/0.11.0`
},
body: JSON.stringify(args)
});
I get 401 unhautorized but Im using the correct RhinoComputeKey…
Can someone help me sort this out getting angst. Working with the standard endpoint is fine, however when I introduce a custom made plugin endpoint it stops working…
Thanks