How to convert JSModeller jsonData for uploaded file to JSModeller body to use in JSM.ExportBodyToStl()
Requirement: option to upload stl/obj file, render it and at the end give an option to export to either stl/obj file
https://3dviewer.net/ has the option to upload files but does not have option to export to stl/obj
Problem: cannot get the body of the uploaded file.
// this code is from 3dviewer.net **impoterapp.js**
var processorFunc = JSM.ConvertFileListToJsonData;
if (isUrl) {
processorFunc = JSM.ConvertURLListToJsonData;
}
processorFunc (userFiles, {
onError : function () {
myThis.GenerateError ('No readable file found.');
myThis.SetReadyForTest ();
return;
},
onReady : function (fileNames, jsonData) {
myThis.fileNames = fileNames
// i get the jsonData here
//
// how do i convert jsonData to jsmodeller object
}
});
JSModeller has an export Option here http://kovacsv.github.io/JSModeler/documentation/demo/demonstration.html but all the examples they used here are created with generator function like JSM.LegoBrickGenerator(), JSM.ShapeGenerator (), etc
how do we generate/get/convert an stl/obj file to JSModeller Body ?
as we need to pass body to ExportBodyToStl
example http://kovacsv.github.io/JSModeler/documentation/jsmdoc/index.html#ExportBodyToStl
JSM.ExportBodyToStl (body, 'JSModelerBody', false);
JSM.ExportBodyToObj (body, 'JSModelerBody', false);
above example of exportBody is from http://kovacsv.github.io/JSModeler/documentation/demo/demonstration.html
JSModeler has an own model format called JSM.Model. You can export this model to obj and stl, or to json format. When you import something it generates the json format directly, and there is no way to convert it back to JSM.Model.
By the way I have an unpublished code which converts the json format to stl, I hope it will help you:
function ConvertJsonDataToStl (model)
{
function GetVertex (vertices, index)
{
var result = new JSM.Coord (
parseFloat (vertices[parseInt (index) * 3 + 0]),
parseFloat (vertices[parseInt (index) * 3 + 1]),
parseFloat (vertices[parseInt (index) * 3 + 2])
);
return result;
}
var stl = '';
stl += 'solid Model\n';
var meshId, triangleId, paramId, mesh, vertices, triangle;
var v0, v1, v2, normal;
for (meshId = 0; meshId < model.meshes.length; meshId++) {
mesh = model.meshes[meshId];
vertices = mesh.vertices;
for (triangleId = 0; triangleId < mesh.triangles.length; triangleId++) {
triangle = mesh.triangles[triangleId];
for (paramId = 0; paramId < triangle.parameters.length; paramId += 9) {
mesh = model.meshes[meshId];
v0 = GetVertex (vertices, triangle.parameters[paramId + 0]);
v1 = GetVertex (vertices, triangle.parameters[paramId + 1]);
v2 = GetVertex (vertices, triangle.parameters[paramId + 2]);
normal = JSM.CalculateTriangleNormal (v0, v1, v2);
stl += 'facet normal ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
stl += '\touter loop\n';
stl += '\t\tvertex ' + v0.x + ' ' + v0.y + ' ' + v0.z + '\n';
stl += '\t\tvertex ' + v1.x + ' ' + v1.y + ' ' + v1.z + '\n';
stl += '\t\tvertex ' + v2.x + ' ' + v2.y + ' ' + v2.z + '\n';
stl += '\tendloop\n';
stl += 'endfacet\n';
}
}
}
stl += 'endsolid Model\n';
return stl;
};
Related
I was wondering how to encrypt and decrypt a video with WebCrypto API using AES and a custom key. I have only found this code and only indicates how to encrypt the video but not how to decrypt it, also uses a random key. Thank you in advance.
function processFile(evt) {
var file = evt.target.files[0],
reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result,
iv = crypto.getRandomValues(new Uint8Array(16));
crypto.subtle.generateKey({ 'name': 'AES-CBC', 'length': 256 }, false, ['encrypt', 'decrypt'])
.then(key => crypto.subtle.encrypt({ 'name': 'AES-CBC', iv }, key, data) )
.then(encrypted => {
console.log(encrypted);
alert('The encrypted data is ' + encrypted.byteLength + ' bytes long'); // encrypted is an ArrayBuffer
})
.catch(console.error);
}
reader.readAsArrayBuffer(file);
}
You will find complete examples of how to generate keys, import keys, encrypt and decrypt using AES-GCM here :
https://github.com/diafygi/webcrypto-examples/blob/master/README.md#aes-gcm
You should use GCM as it is an authenticated mode of encryption. There is no stream interface for WebCrypto so you will have to process in chunks, otherwise it’s very straight forward.
You likely want to use ECDH to exchange the AES key. That same page has examples for that as well.
here's a demo that decrypts and plays HLS video using aes-256-cbc:
https://kaizhu256.github.io/node-demo-hls-encrypted/index.html
it was accomplished by hacking the ajax-call in hls.js (https://github.com/video-dev/hls.js/blob/v0.8.9/dist/hls.js) to decrypt the xhr.response before passing it to video-playback:
--- assets.hls.v0.8.9.js 2018-08-04 03:59:42.000000000 +0700
+++ assets.hls.v0.8.9.crypto.js 2018-08-04 03:59:42.000000000 +0700
## -1,3 +1,97 ##
+var local;
+(function () {
+ (function () {
+ local = local || {};
+ local.base64ToBuffer = function (b64, mode) {
+ /*
+ * this function will convert b64 to Uint8Array
+ * https://gist.github.com/wang-bin/7332335
+ */
+ /*globals Uint8Array*/
+ var bff, byte, chr, ii, jj, map64, mod4;
+ b64 = b64 || '';
+ bff = new Uint8Array(b64.length); // 3/4
+ byte = 0;
+ jj = 0;
+ map64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+ mod4 = 0;
+ for (ii = 0; ii < b64.length; ii += 1) {
+ chr = map64.indexOf(b64[ii]);
+ if (chr >= 0) {
+ mod4 %= 4;
+ if (mod4 === 0) {
+ byte = chr;
+ } else {
+ byte = byte * 64 + chr;
+ bff[jj] = 255 & (byte >> ((-2 * (mod4 + 1)) & 6));
+ jj += 1;
+ }
+ mod4 += 1;
+ }
+ }
+ // optimization - create resized-view of bff
+ bff = bff.subarray(0, jj);
+ // mode !== 'string'
+ if (mode !== 'string') {
+ return bff;
+ }
+ // mode === 'string' - browser js-env
+ if (typeof window === 'object' && window && typeof window.TextDecoder === 'function') {
+ return new window.TextDecoder().decode(bff);
+ }
+ // mode === 'string' - node js-env
+ Object.setPrototypeOf(bff, Buffer.prototype);
+ return String(bff);
+ };
+ local.cryptoAes256CbcByteDecrypt = function (key, data, onError, mode) {
+ /*
+ * this function will aes-256-cbc decrypt with the hex-key, Uint8Array data
+ * example usage:
+ key = '0000000000000000000000000000000000000000000000000000000000000000';
+ local.cryptoAes256CbcByteEncrypt(key, new Uint8Array([1,2,3]), function (error, data) {
+ console.assert(!error, error);
+ local.cryptoAes256CbcByteDecrypt(key, data, console.log);
+ });
+ */
+ /*globals Uint8Array*/
+ var cipher, crypto, ii, iv, tmp;
+ // init key
+ tmp = key;
+ key = new Uint8Array(32);
+ for (ii = 0; ii < key.length; ii += 2) {
+ key[ii] = parseInt(tmp.slice(2 * ii, 2 * ii + 2), 16);
+ }
+ // base64
+ if (mode === 'base64') {
+ data = local.base64ToBuffer(data);
+ }
+ if (!(data instanceof Uint8Array)) {
+ data = new Uint8Array(data);
+ }
+ // init iv
+ iv = data.subarray(0, 16);
+ // optimization - create resized-view of data
+ data = data.subarray(16);
+ crypto = typeof window === 'object' && window.crypto;
+ /* istanbul ignore next */
+ if (!(crypto && crypto.subtle && typeof crypto.subtle.importKey === 'function')) {
+ setTimeout(function () {
+ crypto = require('crypto');
+ cipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
+ onError(null, Buffer.concat([cipher.update(data), cipher.final()]));
+ });
+ return;
+ }
+ crypto.subtle.importKey('raw', key, {
+ name: 'AES-CBC'
+ }, false, ['decrypt']).then(function (key) {
+ crypto.subtle.decrypt({ iv: iv, name: 'AES-CBC' }, key, data).then(function (data) {
+ onError(null, new Uint8Array(data));
+ }).catch(onError);
+ }).catch(onError);
+ };
+ }());
+}());
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
## -10919,6 +11013,22 ##
}
stats.loaded = stats.total = len;
var response = { url: xhr.responseURL, data: data };
+ if (data && window.modeMediaEncrypted && window.mediaEncryptedKey) {
+ var self = this;
+ local.cryptoAes256CbcByteDecrypt(
+ window.mediaEncryptedKey,
+ data,
+ function (error, data) {
+ response.data = typeof xhr.response === 'string'
+ ? new TextDecoder().decode(data)
+ : data;
+ stats.loaded = stats.total = data.byteLength;
+ self.callbacks.onSuccess(response, stats, context, xhr);
+ },
+ typeof xhr.response === 'string' && 'base64'
+ );
+ return;
+ }
this.callbacks.onSuccess(response, stats, context, xhr);
} else {
// if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
I have 2 vector layers of which I want only 1 to be selectable for a WFS get feature info layer. OL4 docs tell me there is an opt_layerfilter for the forEachFeatuerAtPixel function.
I’m in a similar situation like this: OpenLayers 3 hasFeatureAtPixel filter for layer.
Due to my lack of JavaScript knowledge I can’t seem to make it work with the following code in OpenLayers 4:
var displayFeatureInfo = function (pixel) {
var features = [];
map.forEachFeatureAtPixel(pixel, {
layerFilter: function (layer) {
return layer.get('name') === 'isochrones';
}
}, function (feature) {
features.push(feature);
});
if (features.length > 0) {
var info = [];
var i, ii;
for (i = 0, ii = features.length; i < ii; ++i) {
info.push('<div id="infobox">' + '<p2>' + 'Isochroon ' + features[i].get('name') + ', locatie ' + features[i].get('facilityid') + '</p2>' + '<p>' + 'aantal lopend: ' + features[i].get('n_pedestrians') + ', fiets: ' + features[i].get('n_bike') + ', ebike: ' + features[i].get('n_ebike') + '<br>' + 'speedpedelec: ' + features[i].get('n_speedpedelec') + ', auto: ' + features[i].get('n_car') + '</p>' + '</div>');
}
document.getElementById('info').innerHTML = info.join(', ') || ' ';
} else {
document.getElementById('info').innerHTML = ' ';
}
};
map.on('click', function (evt) {
displayFeatureInfo(evt.pixel);
});
The layer I want to be selectable is named ‘isochrones’.
It throws me an error “d.call is not a function” when I try to click any vector layer in the map.
Could anyone point me in the right direction?
Looks like you have your args swapped.
The params for forEachFeatureAtPixel are (pixel, callback, options)
You have (pixel, options, callback)
Is this even possible?
function from_country_to_country(country_from, country_to) {
// get the right zone prices
var zone_price = zone_finder(country_to['zone']);
$('#country_to_country').html(country_from['land']);
$('#call').html(formatPrice(country_from[zone_price]) + ' kr/min');
$('#recieve').html(formatPrice(country_from['receive_calls']) + ' kr/min');
$('#send_sms').html(formatPrice(country_from['send_sms']) + ' kr/SMS');
$('#recieve_sms').html(formatPrice(country_from['receive_sms']) + ' kr/SMS');
$('#opening_fee').html(formatPrice(country_from['opening_fee']) + ' kr');
}
function within_the_country(country) {
$('#from_within').html(country['land']);
$('#from_domestic').html(formatPrice(country['domestic']) + ' kr/min');
$('#from_RCF').html(formatPrice(country['receive_calls']) + ' kr/min');
$('#from_send_sms').html(formatPrice(country['send_sms']) + ' kr/SMS');
$('#from_recieve_sms').html(formatPrice(country['receive_sms']) + ' kr/SMS');
$('#from_opening_fee').html(formatPrice(country['opening_fee']) + ' kr');
$('#from_gprs_data').html(formatPrice(country['data_price'])+ ' kr/mb');
}
// Format prices from ex: turns 1 into 1,00
function formatPrice(n) {
if (!isNaN(parseFloat(n))) {
n = parseFloat(n);
n = Math.round(n * 100) / 100
n = n.toFixed(2);
return n;
} else {
// IF WE CAN MAKE "n" NON-APPENDABLE HERE
return n;
}
}
If n is not a number I dont want ' kr/mb' to be appended to the string. I know that I can check if it is a number and if not, dont append. But I have many different suffixes that I append onto the returning string of formatPrice(). So then I will need to check this everywhere. Is there a nice work around to this?
Adjust your formatPrice function to conditionally take in a unit:
function formatPrice(n, unit) {
if(!isNan(...)) {
...
return n + " " + unit;
}
else {
return n;
}
}
formatPrice(500, 'kr/mb');
Attached code takes json as input and i am trying to render data using script so that it comes in a proper format.
we need to modify "json to html.txt" server-side js, so that the output in html from the input json .
attached image shows the output at right side.this output must be in format.
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var statement, i, j, x = "";
statement = {
"Financial statement:":
["NetIncomeLoss = ","- NetIncomeLossAttributableToNoncontrollingInterest","+ ProfitLoss = "," + IncomeLossFromDiscontinuedOperationsNetO..."," + IncomeLossFromContinuingOperationsInclud... = "," + apd_IncomeLossFromContinuingOperationsBeforeTaxes = "," + OperatingIncomeLoss = "," + SalesRevenueNet"," - CostOfGoodsAndServicesSold"," - SellingGeneralAndAdministrativeExpense"," - ResearchAndDevelopmentExpense"," - RestructuringCharges"," + apd_OtherIncomeExpenseNet"," + IncomeLossFromEquityMethodInvestments"," - InterestExpense"," - IncomeTaxExpenseBenefit","EarningsPerShareBasic = ","+ IncomeLossFromContinuingOperationsPerBasicShare","+ IncomeLossFromDiscontinuedOperationsNetOfTaxPerBasicShare","EarningsPerShareDiluted = ","+ IncomeLossFromContinuingOperationsPerDilutedShare","+ IncomeLossFromDiscontinuedOperationsNetO..."],
"2009-12-31":[251.8,5,256.8,0,256.8,340.3,345,2173.5,1568.6,244.1,27.2,0,11.4,26.9,31.6,83.5,1.19e-06,1.19e-06,0,1.16e-06,1.16e-06,0],"2008-12-31":[68.6,5,73.6,-21.4,95,102.1,114.1,2195.3,1629.7,247,33.2,174.2,2.9,24.5,36.5,7.1,3.3e-07,4.3e-07,-1e-07,3.2e-07,4.2e-07,-1e-07]
}
var spaceCount=[];
var financialStatement=[];
var otherColumns = [];
var output = '<table class="table" style="width:100%;"><tr>';
Object.keys(statement).forEach(function (key, i) {
output += '<th><pre>' + key + '</pre></th>';
if (i > 0){
otherColumns.push(key);
}
});
output += '</tr>';
statement[Object.keys(statement)[0]].forEach(function(val, i){
var total = false;
if (val.indexOf('=') > -1){
total = true;
}
var printValue = '<td><pre>' + val + '</pre></td>';
if (total){
printValue = '<td><pre style="font-weight: bold;text-decoration: underline;">' + val + '</pre></td>';
}
otherColumns.forEach(function(key, j){
if (total){
printValue += '<td><pre style="font-weight: bold;text-decoration: underline;">' + statement[key][i] + '</pre></td>';
}
else
{
printValue += '<td><pre>' + statement[key][i] + '</pre></td>';
}
});
output += printValue + '</tr>';
});
output += '</table>';
document.getElementById("demo").innerHTML = output;
</script>
</body>
</html>
I have the following hardcoded JSON:
var myData = [
{"Identifier":1,"Naam":"Van Der Valk","Adres":"Europaweg 218","Postcode":"1238AC","Plaats":"Zoetermeer","Longitude":"4.48822","Latitude":"52.06258", "Status":"Laadpunten Beschikbaar", "lunch":"true", "diner":"true", "meet":"true", "wifi":"true"},
{"Identifier":2,"Naam":"NOT Given","Adres":"NOT Given 1","Postcode":"0000LL","Plaats":"Rotterdam","Longitude":"0.00000","Latitude":"0.00000", "lunch":"false"},
{"Identifier":3,"Naam":"NOT Given","Adres":"NOT Given 6","Postcode":"0000LL","Plaats":"Rotterdam","Longitude":"0.00000","Latitude":"0.00000", "lunch":"false"},
{"Identifier":4,"Naam":"NOT Given","Adres":"NOT Given 1","Postcode":"0000LL","Plaats":"Den Haag","Longitude":"0.00000","Latitude":"0.00000", "lunch":"false"},
{"Identifier":5,"Naam":"plek b met lunch en diner","Adres":"NOT Given 218","Postcode":"0000LL","Plaats":"Zoetermeer","Longitude":"0.00000","Latitude":"0.00000", "lunch":"true", "diner":"true", "wifi":"true"}
];
This json i use in my ios phonegap app.. Each line of code in the Json is a point in the netherlands.. I am trying to build a function which calculates the distance between where the phone is and the lat and long from the json.. eventually these json code needs to come in a ordered list where also the distance are from small to big..
for the distance measurement i Used this:
function haversine() {
$.each(myData, function(index, element) {
var R = 6371; // earth's mean radius in km
var dLat = rad(element.Latitude - lat1);
var dLong = rad(element.Longitude - long1);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(rad(lat1)) * Math.cos(rad(element.Latitude)) * Math.sin(dLong/2) * Math.sin(dLong/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
//var element = document.getElementById('afstand');
//element.innerHTML = 'afstand: ' + d.toFixed(3);
$('.greenfluxlist').append('<li id="' + element.Identifier + '">' + element.Naam + ' ' + element.Plaats + '<p> <br/>' + element.Adres + ',<br/> ' + element.Postcode + ' ' + element.Plaats + '<br/> Status: ' + element.Status + '</p> <span class="ui-li-count">' + d.toFixed(3) + '</span></li>');
});
$('.greenfluxlist').trigger('create');
$('.greenfluxlist').listview('refresh');
//return d.toFixed(3);
}
What my problem now is, how can i build the ordered list, is it possible to get everything into an array and then loop through it or something else, i think there has to be a simple solution but i don't know.
To sort an array, use the sort method.
You should calculate the distance first, then sort the array, and then generate the list. Something like this:
function calculateDistance(element)
{
var R = 6371; // earth's mean radius in km
var dLat = rad(element.Latitude - lat1);
var dLong = rad(element.Longitude - long1);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(rad(lat1)) * Math.cos(rad(element.Latitude)) * Math.sin(dLong/2) * Math.sin(dLong/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
function generateList(data)
{
for(var i=0; i<data.lenght; i++)
{
var element = data[i];
//var element = document.getElementById('afstand');
//element.innerHTML = 'afstand: ' + element.Distance.toFixed(3);
$('.greenfluxlist').append('<li id="' + element.Identifier + '">' + element.Naam + ' ' + element.Plaats + '<p> <br/>' + element.Adres + ',<br/> ' + element.Postcode + ' ' + element.Plaats + '<br/> Status: ' + element.Status + '</p> <span class="ui-li-count">' + element.Distance.toFixed(3) + '</span></li>');
}
}
for(var i=0; i<myData.length; i++)
{
myData[i].Distance = calculateDistance(myData[i]);
}
myData.sort(function(a,b) {
return a.Distance > b.Distance;
});
generateList(myData);