Uploading 3D-File to Shapediver within a custom viewer fails

Hello there

I’m importing 3D Files to Shapediver. (.stl), in my own custom viewer, using the viewer v3 API:

I seem to have a Problem in my code, which I sadly have been unable to fix thus far. even when using the same code, as the one from the youtube Tutorial:
(https://www.youtube.com/watch?v=hjYaumOhons)

In the File-selection prompt I can at first only select .pdf and .svg files.
I change to all files, select the .stl file, and upload it.

The upload fails with the message:
`

Error Parameter(6db50cc1-ed62-4a9f-b8d1-7659cb412e76).upload: Error uploading FileParameter, type of data () is not a valid type. Has to be application/3dm,application/3ds,application/ai,application/amf,application/dgn,application/dwg,application/dxf,application/fbx,application/iges,application/off,application/pdf,application/ply,application/skp,application/sla,application/slc,application/step,application/vda,application/wavefront-obj,application/x-3ds,application/x-autocad,application/x-dxf,drawing/x-dxf,image/svg+xml,image/vnd.dxf,image/x-3ds,image/x-autocad,image/x-dxf,model/3mf,model/iges,model/obj,model/stl,model/vnd.3dm,x-world/x-3dmf,zz-application/zz-winassoc-dxf.

`

given .stl is not one of the filetypes provided within the Objects.format, I was wondering whether I am using the wrong Fileupload method. However, there only seems to be one function for this (as far as I can tell)
Also the error specifically mentiones .stl as one of the accepted formats.
I doubt that I have a problem within my model, as the upload on the shapediver-Plattform works perfectly.

This is my function which I call for the creation of the upload button:

const createFileParameterElement = (
  session: ISessionApi,
  paramObject: IParameterApi<File | Blob | string>,
  parentDiv: HTMLDivElement
  ) => {
    const paramDiv = createParamDiv(paramObject, parentDiv);

    const inputElement = document.createElement("input") as HTMLInputElement;
    paramDiv.appendChild(inputElement);
    inputElement.type = "file";
    inputElement.accept = paramObject.format!.join(','); // 

    inputElement.onchange = async () => {
      if(!inputElement.files || !inputElement.files[0]) return;
      paramObject.value = inputElement.files[0];
      await session.customize();
    };
    
};

Has anyone an idea whats wrong? :slight_smile:

Thanks in advance!

Did you try to open the model directly on the ShapeDiver platform and check what happens there? Are you uploading your models to the Rhino 7 system? In Rhino 6, the ShapeDiver plugin can not import stl files, so that might be an issue.

If everything works as expected in the ShapeDiver platform, then our team will look at your code and see if an issue happens there.

Im am using the Rhino 7 backend.
On the Platform (https://shapediver.com/app/m/) it works as expected.
If you want to try it yourselfes, it’s the py_gripper333 model: ShapeDiver

This is my code. I could also provide a code-box, when necessary.

const createParamDiv = (
  paramObject: IParameterApi<any>,
  parentDiv: HTMLDivElement
) => {
  const paramDiv = document.createElement("div") as HTMLDivElement;
  parentDiv.appendChild(paramDiv);

  const label = document.createElement("label") as HTMLLabelElement;
  paramDiv.appendChild(label);
  label.innerText = paramObject.name;

  return paramDiv;
};

const createFileParameterElement = (
  session: ISessionApi,
  paramObject: IParameterApi<File | Blob | string>,
  parentDiv: HTMLDivElement
  ) => {
    const paramDiv = createParamDiv(paramObject, parentDiv);

    const inputElement = document.createElement("input") as HTMLInputElement;
    paramDiv.appendChild(inputElement);
    inputElement.type = "file";
    inputElement.accept = paramObject.format!.join(','); // 

    inputElement.onchange = async () => {
      if(!inputElement.files || !inputElement.files[0]) return;
      paramObject.value = inputElement.files[0];
      await session.customize();
    };
    
};


Thanks!

Hello @Philip7!

First of all, thanks for watching the youtube video. I hope it helped you so far!

The issue you are facing here is that you have to set the mimeType of the file you are uploading. Otherwise our backend doesn’t have any indication which file type this is (as can be seen by the error that you get).

Here is a bit more advanced example for the file upload. I tested this with your model and this works now as expected.

Cheers, Michael

1 Like

Thank you Michael for getting back to me!
Indeed, the tutorial has been very helpful, especially since web and Grasshopper development are very different. Having someone do an example is invaluable!

Your example solved my problem. thank you!

For future readers, the crucial part (in my case) is to add:

let fileWithMimeType = file;
if (!fileWithMimeType.type)
  fileWithMimeType = new File([file], file.name, {
    type: guessMimeTypeFromFilename(file.name)[0]
  });

fileInputParameter.value = fileWithMimeType;

instead of paramObject.value = inputElement.files[0];

guessMimeTypeFromFilename can be imported from "shapediver/viewer.utils.mime-type";

1 Like