add mesh app root

This commit is contained in:
Stewart Allen 2021-12-16 19:11:52 -05:00
commit 1dc7119f2b
19 changed files with 479 additions and 18 deletions

90
app.js
View file

@ -10,7 +10,7 @@ const fs = require('fs');
const uglify = require('uglify-es');
const moment = require('moment');
const agent = require('express-useragent');
const license = require_fresh('./src/license.js');
const license = require_fresh('./src/add/license.js');
const version = license.VERSION || "rogue";
const fileCache = {};
@ -61,8 +61,10 @@ function init(mod) {
mod.add(handleOptions);
mod.add(fullpath({
"/kiri" : redir("/kiri/", 301),
"/mesh" : redir("/mesh/", 301),
"/meta" : redir("/meta/", 301),
"/kiri/index.html" : redir("/kiri/", 301),
"/mesh/index.html" : redir("/mesh/", 301),
"/meta/index.html" : redir("/meta/", 301)
}));
mod.add(handleVersion);
@ -81,6 +83,8 @@ function init(mod) {
mod.add(rewriteHtmlVersion);
mod.static("/src/", "src");
mod.static("/obj/", "web/obj");
mod.static("/font/", "web/font");
mod.static("/mesh/", "web/mesh");
mod.static("/moto/", "web/moto");
mod.static("/meta/", "web/meta");
mod.static("/kiri/", "web/kiri");
@ -218,12 +222,12 @@ function initModule(mod, file, dir) {
const script = {
kiri : [
"kiri",
"main/kiri",
"ext/three",
"ext/three-bgu",
"ext/three-svg",
"ext/jszip",
"license",
"add/license",
"ext/clip2", // work.test
"ext/tween",
"ext/fsave",
@ -287,11 +291,11 @@ const script = {
"@icons"
].map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p),
worker : [
"kiri",
"main/kiri",
"ext/three",
"ext/pngjs",
"ext/jszip",
"license",
"add/license",
"ext/clip2",
"ext/earcut",
"add/array",
@ -339,8 +343,8 @@ const script = {
"kiri/worker"
].map(p => `src/${p}.js`),
minion : [
"kiri",
"license",
"main/kiri",
"add/license",
"ext/clip2",
"ext/earcut",
"add/array",
@ -365,8 +369,8 @@ const script = {
"kiri/minion"
].map(p => `src/${p}.js`),
engine : [
"kiri",
"license",
"main/kiri",
"add/license",
"ext/three",
"add/array",
"add/three",
@ -396,7 +400,7 @@ const script = {
].map(p => `src/${p}.js`),
meta : [
"ext/three",
"license",
"add/license",
"ext/tween",
"ext/fsave",
"ext/earcut",
@ -420,8 +424,63 @@ const script = {
"moto/db",
"moto/ui",
"kiri/catalog",
"meta"
].map(p => `src/${p}.js`)
"main/meta"
].map(p => `src/${p}.js`),
mesh : [
"main/mesh",
"ext/three",
"ext/three-bgu",
"ext/three-svg",
"ext/jszip",
"add/license",
"ext/clip2",
"ext/tween",
"ext/fsave",
"ext/earcut",
"ext/base64",
"add/array",
"add/three",
"geo/base",
"geo/point",
"geo/points",
"geo/slope",
"geo/line",
"geo/bounds",
"geo/polygon",
"geo/polygons",
"geo/mesh",
// "moto/kv",
// "moto/ajax",
"moto/ctrl",
// "moto/pack",
"moto/space",
"moto/load-3mf",
"moto/load-obj",
"moto/load-stl",
"moto/load-svg",
"moto/load-url",
"moto/load-file",
"moto/broker",
"moto/db",
// "kiri/ui",
// "kiri/do",
// "kiri/lang",
// "kiri/lang-en",
"kiri/catalog",
// "kiri/slice",
// "kiri/layers",
// "kiri/client",
// "kiri/stack",
// "kiri/stacks",
// "kiri/widget",
// "kiri/print",
// "kiri/codec",
// "kiri/conf",
// "kiri/main",
// "kiri/init",
// "kiri/export",
// "kiri/tools",
].map(p => `src/${p}.js`),
};
// prevent caching of specified modules
@ -461,7 +520,7 @@ function handleSetup(req, res, next) {
function handleVersion(req, res, next) {
let vstr = oversion || version;
if (req.app.path === "/kiri/" && req.url.indexOf(vstr) < 0) {
if (["/kiri/","/mesh/"].indexOf(req.app.path) >= 0 && req.url.indexOf(vstr) < 0) {
if (req.url.indexOf("?") > 0) {
return http.redirect(res, `${req.url},ver:${vstr}`);
} else {
@ -489,7 +548,7 @@ function handleOptions(req, res, next) {
function handleWasm(req, res, next) {
let [root, file] = req.app.path.split('/').slice(1);
let ext = (file || '').split('.')[1];
let path = `${dir}/wasm/${file}`;
let path = `${dir}/src/wasm/${file}`;
let mod = lastmod(path);
if (root === 'wasm' && ext === 'wasm' && mod) {
@ -587,6 +646,7 @@ function prepareScripts() {
generateIcons();
generateDevices();
code.meta = concatCode(script.meta);
code.mesh = concatCode(script.mesh);
code.kiri = concatCode(script.kiri);
code.worker = concatCode(script.worker);
code.minion = concatCode(script.minion);
@ -795,7 +855,7 @@ function cookieValue(cookie,key) {
}
function rewriteHtmlVersion(req, res, next) {
if (req.app.path === "/kiri/") {
if (["/kiri/","/mesh/"].indexOf(req.app.path) >= 0) {
let real_write = res.write;
let real_end = res.end;
res.write = function() {

1
src/main/mesh.js Normal file
View file

@ -0,0 +1 @@
console.log('mesh loaded');

1
web/font Symbolic link
View file

@ -0,0 +1 @@
../node_modules/@fortawesome/fontawesome-free/

View file

@ -1 +0,0 @@
../../node_modules/@fortawesome/fontawesome-free/

View file

@ -15,8 +15,8 @@
<link rel="icon" href="/kiri/favicon.ico">
<link rel="apple-touch-icon" href="/kiri/favicon-mobile.png">
<link rel="stylesheet" type="text/css" href="/kiri/index.css?{{version}}">
<link href="fa/css/all.min.css" rel="stylesheet">
<script src="fa/js/all.min.js" crossorigin="anonymous"></script>
<link href="/font/css/all.min.css" rel="stylesheet">
<script src="/font/js/all.min.js" crossorigin="anonymous"></script>
<script src="/code/kiri.js?{{version}}"></script>
</head>
<body>

354
web/mesh/index.css Normal file
View file

@ -0,0 +1,354 @@
:root {
--fg-gray: #495057;
--bg-gray: rgba(0,0,0,0.25);
--gradbar: linear-gradient(to right, #ddd, #666, #ddd);
--holdbar: linear-gradient(to top, rgba(100,100,100,0.1), rgba(255,255,255,1), rgba(100,100,100,0.1));
--holdbar-sf: linear-gradient(to top, rgba(200,200,200,0.1), rgba(255,255,255,1), rgba(200,200,200,0.1)) !important;
--highlight: rgba(126,153,183,0.4);
--main-color: rgba(126,153,183,1);
}
@font-face {
font-family: 'Russo One';
src: url('ext/russo-one.ttf');
}
a, a:hover, a:visited {
border: none;
color: inherit;
text-decoration: none;
}
#app {
position: fixed;
overflow: hidden;
font-weight: normal;
font-family: sans-serif;
font-size: larger;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
#app-name {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
z-index: 50;
}
#app-name, #app-mode-name, #app-acct {
cursor: pointer;
}
#app-mode-name {
border-bottom: 2px dotted grey;
}
#app,div {
display: flex;
padding: 0;
border: 0;
margin: 0;
}
#gsbox {
width: 40px;
height: 40px;
padding-right: 15px;
position: fixed;
display: none;
}
div {
position: relative;
}
button.yellow {
background-color: #eda;
border: 1px solid rgba(0,0,255,0.5);
}
button.yellow:hover {
background-color: #eea;
}
button {
display: flex;
border: 1px solid #ccc;
border-radius: 3px;
background-color: #eee;
padding: 2px 7px 3px 7px;
margin: 1px 1px 2px;
cursor: pointer;
text-transform: capitalize;
}
button:hover {
background-color: var(--main-color);
color: white;
}
button[load] {
width: 100%;
text-align: left;
}
button[del] {
margin-left: 5px;
}
input {
background-color: #eeeeeed6;
margin-bottom: 1px;
text-align: right;
border: 1px solid #bbb;
padding-top: 0;
padding-bottom: 0;
margin-top: 1px;
position: relative;
}
input:focus {
color: #495057;
background-color: #fff;
border-color: #6C7F94;
outline: 0;
box-shadow: 0 0 0 0.2rem rgb(0 123 255 / 10%);
}
input[disabled] {
background-color: #ddd;
color: #000;
border-width: 1px;
}
input[type="range"] {
width: 85px;
background-color: transparent;
}
input[type=range]::-moz-focus-outer {
border: 0;
}
input[type="checkbox"] + .color {
z-index: 10000;
width: 15px;
height: 15px;
border: 1px solid rgba(0,0,0,0.1);
border-radius: 3px;
display: inline-block;
pointer-events: none;
margin: 2px;
}
input[type="checkbox"]:not(:checked) + .color {
border: 1px solid blue;
background-color: rgba(255,255,255,0.5) !important;
}
input[type="checkbox"].color {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
width: 100%;
height: 100%;
}
select, textarea, button, input, a {
outline: none;
}
textarea {
overflow: scroll;
}
select {
border: 1px solid #bbb;
background-color: rgba(255,255,255,0.5);
border-radius: 3px;
}
th, tr, td, span, div, label, button {
user-select: none;
}
th, tr, td, label {
white-space: nowrap;
}
.noselect {
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.hide {
display: none !important;
}
.noshow {
display: none;
}
.grid {
display: grid;
}
.frow {
flex-direction: row;
}
.f-col {
flex-direction: column;
}
.auto {
flex-basis: auto;
}
.basis-50 {
flex-basis: 50%;
}
.grow {
flex-grow: 1;
}
.a-start {
align-items: flex-start;
}
.a-center {
align-items: center;
}
.a-end {
align-items: flex-end;
}
.a-stretch {
align-items: stretch;
}
.j-start {
justify-content: flex-start;
}
.j-center {
justify-content: center;
}
.j-end {
justify-content: flex-end;
}
.space-around {
justify-content: space-around;
}
.space-between {
justify-content: space-between;
}
.center {
text-align: center;
}
.middle {
display: flex;
align-items: center;
justify-content: center;
}
.t-just {
text-align: justify;
}
.t-right {
text-align: right;
}
.russo {
font-family: 'Russo One', sans-serif;
}
.overy {
overflow-y: auto;
}
.mh0 {
min-height: 0;
}
.mh35 {
max-height: 35%;
}
.mh85 {
max-height: 85%;
}
:-moz-any() {
overflow-x: hidden !important;
overflow-y: hidden !important;
}
:-moz-any() {
overflow-x: scroll !important;
overflow-y: scroll !important;
margin-right: -14px !important;
margin-bottom: -14px !important;
}
#curtain {
top: 0;
left: 0;
right: 0;
bottom: 0;
position: fixed;
background-color: #fff;
font-family: 'Russo One', sans-serif;
z-index: 11;
}
#tracker {
top: 0;
left: 0;
right: 0;
bottom: 0;
position: absolute;
display: none;
z-index: 101;
}
#container {
position: fixed;
z-index: -1;
width: 100%;
height: 100%;
}
#container canvas {
width: 100%;
height: 100%;
overflow: hidden;
}
#top {
font-family: 'Russo One', sans-serif;
background-color: rgba(255,255,255,0.75);
padding: 3px;
z-index: 15;
}
#top > div {
margin: 0 5px 0 5px;
}
#modal {
display: none;
position: fixed;
z-index: 20;
top: 50%;
left: 0px;
right: 0px;
bottom: 0px;
height: 300px;
transform: translateY(-50%);
background-color: var(--bg-gray);
border-bottom: 1px solid black;
border-top: 1px solid black;
overflow: hidden;
}
#modal > div {
position: absolute;
transform: translateX(50%) translateY(-50%);
right: 50%;
top: 50%;
}
.mdialog {
display: none;
padding: 10px;
min-height: 20px;
font-size: smaller;
background-color: #fff;
}
#gdpr {
position: absolute;
display: none;
bottom: 10px;
right: 10px;
z-index: 1000;
padding: 20px;
border-radius: 5px;
border: 1px solid black;
background-color: white;
}
#gdpr a {
text-decoration: underline;
}
#gotit {
font-weight: bold;
font-size: larger;
padding: 5px 20px 5px 20px;
margin-left: 10px;
}
#fps {
position: fixed;
font-size: 10px;
bottom: 5px;
right: 5px;
color: #000;
}

46
web/mesh/index.html Normal file
View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="author" content="Stewart Allen">
<meta name="keywords" content="3d,mesh,editor,stl,obj,3mf" />
<meta name="copyright" content="stewart allen [sa@grid.space]">
<meta name="description" content="Browser-based 3D Mesh Editor">
<meta property="og:description" content="Mesh:Tool is browser-based 3D Mesh Editor">
<meta property="og:title" content="Browser-based 3D Mesh Editor">
<meta property="og:type" content="website">
<meta property="og:url" content="https://grid.space/mesh/">
<meta property="og:image" content="https://static.grid.space/img/logo_km_og.png">
<title>Mesh:Tool</title>
<link rel="icon" href="/kiri/favicon.ico">
<link rel="apple-touch-icon" href="/kiri/favicon-mobile.png">
<link rel="stylesheet" type="text/css" href="/kiri/index.css?{{version}}">
<link href="/font/css/all.min.css" rel="stylesheet">
<script src="/font/js/all.min.js" crossorigin="anonymous"></script>
<script src="/code/mesh.js?{{version}}"></script>
</head>
<body>
<div id="app" class="f-col">
<div id="curtain" class="j-center a-center"><img id="gsbox"/>loading...</div>
<div id="container"></div>
<div id="tracker"></div>
<div id="top-sep"></div>
<div id="top" class="f-row">
</div>
<div id="gdpr" class="noshow">
<p>this site uses <A href="/privacy.html" target="privacy">cookies</a> to preserve application preferences</p>
<button id="gotit" class="f-col j-center">got it</button>
</div>
<div id="tool-info" class="noshow"></div>
<div id="fps" class="noshow"></div>
<div id="alert-area">
<div id="alert-border">
<div id="alert-text">alerts<br>alerts<br>alerts</div>
</div>
</div>
<div id="top-slider" class="f-col grow">
<input id="anim-slider" type="range" min="0" max="1000" value="0"></input>
</div>
</div>
</body>
</html>