Use full file format names in export dialog.
This commit is contained in:
parent
6bb94d2ac7
commit
b4f10e2ca1
@ -136,6 +136,21 @@ OV.AddRangeSlider = function (parentElement, min, max)
|
||||
return slider;
|
||||
};
|
||||
|
||||
OV.AddSelect = function (parentElement, options, selectedIndex, onChange)
|
||||
{
|
||||
let select = OV.AddDomElement (parentElement, 'select', 'ov_select');
|
||||
for (let option of options) {
|
||||
OV.AddDomElement (select, 'option', null, option);
|
||||
}
|
||||
select.selectedIndex = selectedIndex;
|
||||
if (onChange) {
|
||||
select.addEventListener ('change', () => {
|
||||
onChange (select.selectedIndex);
|
||||
});
|
||||
}
|
||||
return select;
|
||||
};
|
||||
|
||||
OV.AddToggle = function (parentElement, className)
|
||||
{
|
||||
function UpdateStatus (toggle, status)
|
||||
|
||||
@ -55,13 +55,16 @@
|
||||
<p>
|
||||
<table>
|
||||
<tr>
|
||||
<th colspan="2">Format</th>
|
||||
<th>Format</th>
|
||||
<th>Extension</th>
|
||||
<th>Type</th>
|
||||
<th>Import</th>
|
||||
<th>Export</th>
|
||||
<th>Source</th>
|
||||
<th>Comment</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Wavefront</td>
|
||||
<td>obj</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -70,6 +73,7 @@
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3D Studio</td>
|
||||
<td>3ds</td>
|
||||
<td>binary</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -78,6 +82,7 @@
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">Stereolithography</td>
|
||||
<td rowspan="2">stl</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -93,6 +98,7 @@
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">Polygon File Format</td>
|
||||
<td rowspan="2">ply</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -108,21 +114,24 @@
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">gltf</td>
|
||||
<td>text (.gltf)</td>
|
||||
<td rowspan="2">glTF</td>
|
||||
<td>gltf</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
<td class="center green">✓</td>
|
||||
<td>Native</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>binary (.glb)</td>
|
||||
<td>glb</td>
|
||||
<td>binary</td>
|
||||
<td class="center green">✓</td>
|
||||
<td class="center green">✓</td>
|
||||
<td>Native</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">Object File Format</td>
|
||||
<td rowspan="2">off</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -138,6 +147,7 @@
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rhinoceros 3D</td>
|
||||
<td>3dm</td>
|
||||
<td>binary</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -146,6 +156,7 @@
|
||||
<td>experimental</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">Filmbox</td>
|
||||
<td rowspan="2">fbx</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -161,6 +172,7 @@
|
||||
<td>experimental</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Collada</td>
|
||||
<td>dae</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -169,6 +181,7 @@
|
||||
<td>experimental</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Virtual Reality Modeling Language</td>
|
||||
<td>wrl</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -177,6 +190,7 @@
|
||||
<td>experimental</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3D Manufacturing Format</td>
|
||||
<td>3mf</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
@ -185,6 +199,7 @@
|
||||
<td>experimental</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Industry Foundation Classes</td>
|
||||
<td>ifc</td>
|
||||
<td>text</td>
|
||||
<td class="center green">✓</td>
|
||||
|
||||
@ -128,6 +128,14 @@ input.ov_checkbox:checked
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
select.ov_select
|
||||
{
|
||||
color: var(--ov_dialog_foreground_color);
|
||||
background: var(--ov_dialog_background_color);
|
||||
padding: 3px;
|
||||
border: 1px solid var(--ov_border_color);
|
||||
}
|
||||
|
||||
input.ov_slider
|
||||
{
|
||||
height: 1px;
|
||||
|
||||
@ -96,19 +96,6 @@ div.ov_dialog div.ov_dialog_options
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_select
|
||||
{
|
||||
margin: 20px 0px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_select div.ov_dialog_select_option
|
||||
{
|
||||
width: 40px;
|
||||
margin-right: 5px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_file_list
|
||||
{
|
||||
max-height: 105px;
|
||||
@ -177,6 +164,24 @@ div.ov_dialog div.ov_dialog_row
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_row_name
|
||||
{
|
||||
width: 30%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.ov_dialog div.ov_dialog_row_value
|
||||
{
|
||||
width: 70%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.ov_dialog select.ov_select
|
||||
{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.ov_popup
|
||||
{
|
||||
color: var(--ov_dialog_foreground_color);
|
||||
|
||||
@ -1,190 +1,73 @@
|
||||
OV.ExportType =
|
||||
{
|
||||
Model : 1,
|
||||
Image : 2
|
||||
Model : 0,
|
||||
Image : 1
|
||||
};
|
||||
|
||||
OV.ExportDialog = class
|
||||
OV.ExporterUI = class
|
||||
{
|
||||
constructor (callbacks)
|
||||
constructor (name)
|
||||
{
|
||||
this.callbacks = callbacks;
|
||||
this.model = null;
|
||||
this.exportFormats = [
|
||||
{
|
||||
name : 'obj',
|
||||
formats : [
|
||||
{ name : 'text', type: OV.ExportType.Model, format : OV.FileFormat.Text, extension : 'obj' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'stl',
|
||||
formats : [
|
||||
{ name : 'text', type: OV.ExportType.Model, format : OV.FileFormat.Text, extension : 'stl' },
|
||||
{ name : 'binary', type: OV.ExportType.Model, format : OV.FileFormat.Binary, extension : 'stl' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'ply',
|
||||
formats : [
|
||||
{ name : 'text', type: OV.ExportType.Model, format : OV.FileFormat.Text, extension : 'ply' },
|
||||
{ name : 'binary', type: OV.ExportType.Model, format : OV.FileFormat.Binary, extension : 'ply' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'gltf',
|
||||
formats : [
|
||||
{ name : 'text', type: OV.ExportType.Model, format : OV.FileFormat.Text, extension : 'gltf' },
|
||||
{ name : 'binary', type: OV.ExportType.Model, format : OV.FileFormat.Binary, extension : 'glb' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'off',
|
||||
formats : [
|
||||
{ name : 'text', type: OV.ExportType.Model, format : OV.FileFormat.Text, extension : 'off' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : '3dm',
|
||||
formats : [
|
||||
{ name : 'binary', type: OV.ExportType.Model, format : OV.FileFormat.Binary, extension : '3dm' }
|
||||
]
|
||||
},
|
||||
{
|
||||
name : 'png',
|
||||
formats : [
|
||||
{ name : 'current size', type: OV.ExportType.Image, width : null, height : null, extension : 'png' },
|
||||
{ name : 'fixed size (1920x1080)', type: OV.ExportType.Image, width : 1920, height : 1080, extension : 'png' }
|
||||
]
|
||||
}
|
||||
];
|
||||
this.formatParameters = {
|
||||
exportFormatButtonDivs : [],
|
||||
formatSettingsDiv : null,
|
||||
selectedFormat : null
|
||||
};
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
Show (model, viewer)
|
||||
GetType ()
|
||||
{
|
||||
if (model === null) {
|
||||
let messageDialog = OV.ShowMessageDialog (
|
||||
'Export Failed',
|
||||
'Please load a model before exporting.',
|
||||
null
|
||||
);
|
||||
this.callbacks.onDialog (messageDialog);
|
||||
return;
|
||||
}
|
||||
|
||||
let mainDialog = new OV.ButtonDialog ();
|
||||
let contentDiv = mainDialog.Init ('Export', [
|
||||
{
|
||||
name : 'Close',
|
||||
subClass : 'outline',
|
||||
onClick () {
|
||||
mainDialog.Hide ();
|
||||
}
|
||||
},
|
||||
{
|
||||
name : 'Export',
|
||||
onClick : () => {
|
||||
let selectedFormat = this.formatParameters.selectedFormat;
|
||||
if (selectedFormat === null) {
|
||||
return;
|
||||
}
|
||||
mainDialog.Hide ();
|
||||
this.ExportFormat (model, viewer);
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
let text = 'Select a format from the below list to export your model. Please note that the export can take several second.';
|
||||
OV.AddDiv (contentDiv, 'ov_dialog_section', text);
|
||||
|
||||
let exportFormatSelect = OV.AddDiv (contentDiv, 'ov_dialog_select');
|
||||
this.formatParameters.formatSettingsDiv = OV.AddDiv (contentDiv, 'ov_dialog_section ov_dialog_options');
|
||||
for (let i = 0; i < this.exportFormats.length; i++) {
|
||||
let exportFormat = this.exportFormats[i];
|
||||
let exportFormatButton = OV.AddDiv (exportFormatSelect, 'ov_button outline ov_dialog_select_option', exportFormat.name);
|
||||
this.formatParameters.exportFormatButtonDivs.push (exportFormatButton);
|
||||
exportFormatButton.addEventListener ('click', () => {
|
||||
this.OnExportFormatSelect (i);
|
||||
});
|
||||
}
|
||||
this.OnExportFormatSelect (0);
|
||||
|
||||
mainDialog.Show ();
|
||||
this.callbacks.onDialog (mainDialog);
|
||||
return null;
|
||||
}
|
||||
|
||||
OnExportFormatSelect (exportFormatIndex)
|
||||
GetName ()
|
||||
{
|
||||
OV.ClearDomElement (this.formatParameters.formatSettingsDiv);
|
||||
for (let i = 0; i < this.formatParameters.exportFormatButtonDivs.length; i++) {
|
||||
let exportFormatButtonDiv = this.formatParameters.exportFormatButtonDivs[i];
|
||||
if (i === exportFormatIndex) {
|
||||
exportFormatButtonDiv.classList.remove ('outline');
|
||||
} else {
|
||||
exportFormatButtonDiv.classList.add ('outline');
|
||||
}
|
||||
}
|
||||
|
||||
let exportFormat = this.exportFormats[exportFormatIndex];
|
||||
for (let i = 0; i < exportFormat.formats.length; i++) {
|
||||
let format = exportFormat.formats[i];
|
||||
let formatDiv = OV.AddDiv (this.formatParameters.formatSettingsDiv, 'ov_dialog_row');
|
||||
let formatInput = OV.AddRadioButton (formatDiv, 'format', format.name, format.name, () => {
|
||||
this.formatParameters.selectedFormat = format;
|
||||
});
|
||||
if (i === 0) {
|
||||
formatInput.checked = true;
|
||||
this.formatParameters.selectedFormat = format;
|
||||
}
|
||||
}
|
||||
return this.name;
|
||||
}
|
||||
|
||||
ExportFormat (model, viewer)
|
||||
GenerateParametersUI (parametersDiv)
|
||||
{
|
||||
let selectedFormat = this.formatParameters.selectedFormat;
|
||||
if (selectedFormat === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedFormat.type === OV.ExportType.Model) {
|
||||
let progressDialog = new OV.ProgressDialog ();
|
||||
progressDialog.Init ('Exporting Model');
|
||||
progressDialog.Show ();
|
||||
OV.RunTaskAsync (() => {
|
||||
let exporter = new OV.Exporter ();
|
||||
exporter.Export (model, selectedFormat.format, selectedFormat.extension, {
|
||||
onError : () => {
|
||||
}
|
||||
};
|
||||
|
||||
OV.ModelExporterUI = class extends OV.ExporterUI
|
||||
{
|
||||
constructor (name, format, extension)
|
||||
{
|
||||
super (name);
|
||||
this.format = format;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
GetType ()
|
||||
{
|
||||
return OV.ExportType.Model;
|
||||
}
|
||||
|
||||
ExportModel (model, onDialog)
|
||||
{
|
||||
let progressDialog = new OV.ProgressDialog ();
|
||||
progressDialog.Init ('Exporting Model');
|
||||
progressDialog.Show ();
|
||||
|
||||
OV.RunTaskAsync (() => {
|
||||
let exporter = new OV.Exporter ();
|
||||
exporter.Export (model, this.format, this.extension, {
|
||||
onError : () => {
|
||||
progressDialog.Hide ();
|
||||
},
|
||||
onSuccess : (files) => {
|
||||
if (files.length === 0) {
|
||||
progressDialog.Hide ();
|
||||
},
|
||||
onSuccess : (files) => {
|
||||
if (files.length === 0) {
|
||||
progressDialog.Hide ();
|
||||
} else if (files.length === 1) {
|
||||
progressDialog.Hide ();
|
||||
let file = files[0];
|
||||
OV.DownloadArrayBufferAsFile (file.GetBufferContent (), file.GetName ());
|
||||
} else if (files.length > 1) {
|
||||
progressDialog.Hide ();
|
||||
this.ShowExportedFiles (files);
|
||||
}
|
||||
} else if (files.length === 1) {
|
||||
progressDialog.Hide ();
|
||||
let file = files[0];
|
||||
OV.DownloadArrayBufferAsFile (file.GetBufferContent (), file.GetName ());
|
||||
} else if (files.length > 1) {
|
||||
progressDialog.Hide ();
|
||||
let filesDialog = this.ShowExportedFiles (files);
|
||||
onDialog (filesDialog);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (selectedFormat.type === OV.ExportType.Image) {
|
||||
let url = null;
|
||||
if (selectedFormat.width === null || selectedFormat.height === null) {
|
||||
let size = viewer.GetImageSize ();
|
||||
url = viewer.GetImageAsDataUrl (size.width, size.height);
|
||||
} else {
|
||||
url = viewer.GetImageAsDataUrl (selectedFormat.width, selectedFormat.height);
|
||||
}
|
||||
OV.DownloadUrlAsFile (url, 'model.' + selectedFormat.extension);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ShowExportedFiles (files)
|
||||
@ -215,6 +98,130 @@ OV.ExportDialog = class
|
||||
}
|
||||
|
||||
dialog.Show ();
|
||||
this.callbacks.onDialog (dialog);
|
||||
return dialog;
|
||||
}
|
||||
};
|
||||
|
||||
OV.ImageExporterUI = class extends OV.ExporterUI
|
||||
{
|
||||
constructor (name, extension)
|
||||
{
|
||||
super (name);
|
||||
this.extension = extension;
|
||||
this.sizeSelect = null;
|
||||
this.sizes = [
|
||||
{ name : 'Current size', value : null },
|
||||
{ name : '1280 x 720', value : [1280, 720] },
|
||||
{ name : '1920 x 1080', value : [1920, 1080] }
|
||||
];
|
||||
}
|
||||
|
||||
GetType ()
|
||||
{
|
||||
return OV.ExportType.Image;
|
||||
}
|
||||
|
||||
GenerateParametersUI (parametersDiv)
|
||||
{
|
||||
function AddParameterSelect (parametersDiv, name, values, defaultIndex)
|
||||
{
|
||||
let parameterRow = OV.AddDiv (parametersDiv, 'ov_dialog_row');
|
||||
OV.AddDiv (parameterRow, 'ov_dialog_row_name', name);
|
||||
let parameterValueDiv = OV.AddDiv (parameterRow, 'ov_dialog_row_value');
|
||||
return OV.AddSelect (parameterValueDiv, values, defaultIndex);
|
||||
}
|
||||
|
||||
let sizeNames = this.sizes.map (size => size.name);
|
||||
this.sizeSelect = AddParameterSelect (parametersDiv, 'Image size', sizeNames, 1);
|
||||
}
|
||||
|
||||
ExportImage (viewer)
|
||||
{
|
||||
let selectedSize = this.sizes[this.sizeSelect.selectedIndex];
|
||||
let url = null;
|
||||
if (selectedSize.value === null) {
|
||||
let size = viewer.GetImageSize ();
|
||||
url = viewer.GetImageAsDataUrl (size.width, size.height);
|
||||
} else {
|
||||
url = viewer.GetImageAsDataUrl (selectedSize.value[0], selectedSize.value[1]);
|
||||
}
|
||||
OV.DownloadUrlAsFile (url, 'model.' + this.extension);
|
||||
}
|
||||
};
|
||||
|
||||
OV.ExportDialog = class
|
||||
{
|
||||
constructor (callbacks)
|
||||
{
|
||||
this.callbacks = callbacks;
|
||||
this.selectedExporter = null;
|
||||
this.parametersDiv = null;
|
||||
|
||||
this.exporters = [
|
||||
new OV.ModelExporterUI ('Wavefront (.obj)', OV.FileFormat.Text, 'obj'),
|
||||
new OV.ModelExporterUI ('Stereolithography Text (.stl)', OV.FileFormat.Text, 'stl'),
|
||||
new OV.ModelExporterUI ('Stereolithography Binary (.stl)', OV.FileFormat.Binary, 'stl'),
|
||||
new OV.ModelExporterUI ('Polygon File Format Text (.ply)', OV.FileFormat.Text, 'ply'),
|
||||
new OV.ModelExporterUI ('Polygon File Format Binary (.ply)', OV.FileFormat.Binary, 'ply'),
|
||||
new OV.ModelExporterUI ('glTF Text (.gltf)', OV.FileFormat.Text, 'gltf'),
|
||||
new OV.ModelExporterUI ('glTF Binary (.glb)', OV.FileFormat.Binary, 'glb'),
|
||||
new OV.ModelExporterUI ('Object File Format Text (.off)', OV.FileFormat.Text, 'off'),
|
||||
new OV.ModelExporterUI ('Rhinoceros 3D (.3dm)', OV.FileFormat.Binary, '3dm'),
|
||||
new OV.ImageExporterUI ('PNG Image (.png)', 'png')
|
||||
];
|
||||
}
|
||||
|
||||
Show (model, viewer)
|
||||
{
|
||||
let mainDialog = new OV.ButtonDialog ();
|
||||
let contentDiv = mainDialog.Init ('Export', [
|
||||
{
|
||||
name : 'Close',
|
||||
subClass : 'outline',
|
||||
onClick () {
|
||||
mainDialog.Hide ();
|
||||
}
|
||||
},
|
||||
{
|
||||
name : 'Export',
|
||||
onClick : () => {
|
||||
mainDialog.Hide ();
|
||||
this.ExportFormat (model, viewer);
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
let text = 'Select the format from the list below, and adjust the settings of the selected format.';
|
||||
OV.AddDiv (contentDiv, 'ov_dialog_section', text);
|
||||
|
||||
let formatRow = OV.AddDiv (contentDiv, 'ov_dialog_row');
|
||||
this.parametersDiv = OV.AddDiv (contentDiv);
|
||||
let formatNames = this.exporters.map (exporter => exporter.GetName ());
|
||||
let defaultFormatIndex = 6;
|
||||
OV.AddSelect (formatRow, formatNames, defaultFormatIndex, (selectedIndex) => {
|
||||
this.OnFormatSelected (selectedIndex);
|
||||
});
|
||||
this.OnFormatSelected (defaultFormatIndex);
|
||||
|
||||
mainDialog.Show ();
|
||||
this.callbacks.onDialog (mainDialog);
|
||||
}
|
||||
|
||||
OnFormatSelected (selectedIndex)
|
||||
{
|
||||
OV.ClearDomElement (this.parametersDiv);
|
||||
this.selectedExporter = this.exporters[selectedIndex];
|
||||
this.selectedExporter.GenerateParametersUI (this.parametersDiv);
|
||||
}
|
||||
|
||||
ExportFormat (model, viewer)
|
||||
{
|
||||
if (this.selectedExporter.GetType () === OV.ExportType.Model) {
|
||||
this.selectedExporter.ExportModel (model, (filesDialog) => {
|
||||
this.callbacks.onDialog (filesDialog);
|
||||
});
|
||||
} else if (this.selectedExporter.GetType () === OV.ExportType.Image) {
|
||||
this.selectedExporter.ExportImage (viewer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user