Commit 4013a0d4 authored by Carmen Bahia's avatar Carmen Bahia

Merge branch 'master' of gitlab.com:osp-kitchen/workshop_esad-amiens_giants

parents 2a7b040c 97c2c93e
......@@ -2,3 +2,4 @@ venv/
*.pyc
output/
public/
.DS_Store
......@@ -9,67 +9,96 @@ Category: mapping (! category is meant to be single)
Tags: maps, command line, vector, dithering, (! tags are multiple)
-->
# Name of the tool
LEOCAD.
# LEOCAD
## Lego constructions
![](images/BigLeocad.png)
![](images/Tool1.png)
![](images/STSPLeocad.png)
![](images/ToolsLeocad.png)
![](images/Stellarleo1.png)
![](images/Stellarleo2.png)
![](images/Leocadlog.png)
![](images/Leocadlog2.png)
![](images/Leocadlog3.png)
## Subtitle, tagline, whatever descibes best the tool
Lego constructions.
* Who is developing the tool?
* Is the tool under active development?
Yes.
* When did the development of the tool start? / How old is the software?
1998.
* Does the tool have a Wikipedia page?
No.
* What is the tool made for?
3D Lego constructions, and export it as images or videos.
* Who is the tool made for?
Both adults and children.
* Wat is the license of the tool?
GNU General Public. GPLV2.
* Is it possible to contribute to the tool? How? How many people are contributing?
Yes, by creating or using a custom library.
* What does the tool cost? Is it a one time payment or a subscription model?
Nothing.
* Are there tools alike? What makes this tool different?
LDRAW - It's a software where all contributors can build there own bricks to import it on Leocad.
* Does the tool have a Graphical Interface?
Yes.
* Is the interface clear?
Yes, very easy to use, it's designed to allow new users creating models without spending so much time to understand it.
* Is the interface looking like other applications or is it custom made?
It looks like other constructions softwares interfaces.
* Does the tool have a command line interface / can you use the tool from the commandline?
No.
* Can you automate the tool? Does the tool have a scripting interface / API?
Not sure. You can import your own library but maybe not change anything else.
* What are the filetypes the tool can read?
LDR and MPD files.
* What are the filetypes the tool can generate / export?
LDR and MPD files too, and 3d studio; Bricklink; collada; CSV; HTML; POV RAY; Wavefront.
* Is there an official documentation and if so where?
Yes, on the website and github.
www.leocad.org
* For which operating systems is this tool available?
Windows, Linux, MacOS.
......@@ -76,3 +76,13 @@ No, it is a programming framework.
* For which operating systems is this tool available?
Applications made with Electron can be run on Linux, Mac and Windows. It's one of the essential features of the tool.
To test Electron I wrapped the TTX-inspector developed for the ['Dirty Variables' workshop](https://gitlab.constantvzw.org/osp/workshop.dirty-variables/tree/master/inspector) into an application.
![](images/electron-A.png)
![](images/electron-B.png)
![](images/electron-C.png)
![](images/electron-D.png)
\ No newline at end of file
......@@ -14,75 +14,98 @@ Tags: maps, command line, vector, dithering, (! tags are multiple)
## VectoriaL EditingG
![](images/mona.svg)
* Who is developing the tool?
Ted Gould, Bryce Harrington, Nathan Hurst, MenTaLguY
and many different people on list below > https://inkscape.org/fr/credits/
and many different people on list below https://inkscape.org/fr/credits/
* Is the tool under active development?
It seems not, but developer are working to improve it
* When did the development of the tool start? / How old is the software?
It start in 2003 (a fork of Sodipodi)
* Does the tool have a Wikipedia page?
https://fr.wikipedia.org/wiki/Inkscape
* What is the tool made for?
Drawing, vectorial editing
* Who is the tool made for?
for graphic designers, artists or every person wich are interest in it, ab d all people with a computer
For graphic designers, artists or every person wich are interest in it, ab d all people with a computer
* Wat is the license of the tool?
GPL License / GNU GENERAL PUBLIC LICENSE
* Is it possible to contribute to the tool? How? How many people are contributing?
Yes, by writing Core Inkscape code, writing inkscape extensions, packaging inkscape, testing it, reporting bugs, translating inkscape software and website and promote it
* What does the tool cost? Is it a one time payment or a subscription model?
It cost nothing, to my knowledge
* Are there tools alike? What makes this tool different?
Yes it is like Adobe Illustrator, CorelDRAW
* Does the tool have a Graphical Interface?
yes
* Is the interface clear?
yes
* Is the interface looking like other applications or is it custom made?
It look like some "old" application coming back from past or future
* Does the tool have a command line interface / can you use the tool from the commandline?
yes, but mightbe not on mac
* Can you automate the tool? Does the tool have a scripting interface / API?
maybe but for now i don't know how
* What are the filetypes the tool can read?
PNG, SVG, JPEG, ...
* What are the filetypes the tool can generate / export?
SVG
* Is there an official documentation and if so where?
https://inkscape.org/fr/apprendre/
* For which operating systems is this tool available?
Windows, mac OS, Linux / GNU
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Glyph</title>
<style>
.controls {
position: fixed;
top: 0;
right: 0;
left: 0;
padding: 10px;
background: #efefef;
}
body {
padding-top: 20px;
}
</style>
</head>
<body>
<section class="controls">
<!-- <label>Font file:
<input type="file" id="font-selector" />
</label> -->
<button id="select-font">Select a TTX</button>
<button id="reload-font">Reload font</button>
<button id="export-canvas">Export Canvas</button>
<select id="glyph-selector"></select>
</section>
<canvas id="canvas" width="1000" height="1000"></canvas>
<script src="ttxInspector.js"></script>
</body>
</html>
\ No newline at end of file
const { app, BrowserWindow } = require('electron')
const path = require('path')
const url = require('url')
function createWindow() {
win = new BrowserWindow({ width: 800, height: 600 })
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createWindow()
}
})
\ No newline at end of file
{
"name": "tutorial",
"version": "0.1.0",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"devDependencies": {
"electron": "^1.8.4"
}
}
const fs = require('fs');
const { dialog } = require('electron').remote
var font;
class Font {
constructor(xml) {
this.xml = xml;
let parser = new DOMParser();
this.dom = parser.parseFromString(xml, 'text/xml');
}
table(name) { return this.dom.querySelector(name) };
glyphs() { return this.table('glyf').querySelectorAll('TTGlyph'); };
glyph(name) { return this.table('glyf').querySelector(`TTGlyph[name="${name}"]`); };
variations() { return this.table('fvar'); };
glyphVariations() { return this.table('gvar').querySelectorAll('glyphVariations'); };
glyphVariation(name) { return this.table('gvar').querySelector(`glyphVariations[glyph="${name}"]`); };
delta(name, point) { return this.glyphVariation(name).querySelectorAll(`delta[pt="${point}"]`); };
contours(name) { return this.glyph(name).querySelectorAll('contour'); };
}
function deriveCurvePoint(p1, p2) {
return {
'x': p1.x + .5 * (p2.x - p1.x),
'y': p1.y + .5 * (p2.y - p1.y),
'on': false,
'derived': true
};
}
function drawGlyph(name, font) {
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
var glyph = font.glyph(name);
var xmin = glyph.getAttribute('xMin'),
xmax = glyph.getAttribute('xMax'),
ymin = glyph.getAttribute('yMin'),
ymax = glyph.getAttribute('yMax'),
glyphWidth = xmax - xmin,
glyphHeight = ymax - ymin;
prepareCanvas = (ctx) => {
ctx.transform(1, 0, 0, -1, 0, canvas.height);
ctx.translate((canvas.width - glyphWidth) / 2 - xmin, (canvas.height - glyphHeight) / 2);
};
ctx.save();
prepareCanvas(ctx);
var glyphTTYPoints = [];
font.contours(name).forEach(contour => {
ctx.beginPath();
var contourTTYPoints = [];
var curvepoints = [];
contour.querySelectorAll('pt').forEach((point) => {
var x = parseInt(point.getAttribute('x')),
y = parseInt(point.getAttribute('y')),
on = (point.getAttribute('on') === "1") ? true : false;
contourTTYPoints.push({
'x': x,
'y': y,
'on': on
});
});
var prevPoint = contourTTYPoints[contourTTYPoints.length - 1];
for (var i = 0; i < contourTTYPoints.length; i++) {
var point = contourTTYPoints[i];
if (!point.on) {
if (!prevPoint.on) {
curvepoints.push(deriveCurvePoint(point, prevPoint));
} else if (i === 0) {
curvepoints.push(prevPoint);
}
}
curvepoints.push(point);
prevPoint = point;
}
if (!curvepoints[curvepoints.length - 1].on) {
curvepoints.push(curvepoints[0]);
}
for (var i = 0; i < curvepoints.length; i++) {
var p = curvepoints[i];
if (p.on) {
if (i === 0) {
ctx.moveTo(p.x, p.y);
} else {
ctx.lineTo(p.x, p.y);
}
} else {
var cp = p,
p = curvepoints[i + 1];
ctx.quadraticCurveTo(cp.x, cp.y, p.x, p.y);
i++;
}
}
ctx.closePath();
ctx.stroke();
glyphTTYPoints = glyphTTYPoints.concat(contourTTYPoints);
});
// Mark points
ctx.save();
ctx.strokeStyle = 'darkblue';
ctx.fillStyle = 'darkblue'
glyphTTYPoints.forEach((p, k) => {
ctx.beginPath();
ctx.arc(p.x, p.y, 3, 0, 2 * Math.PI, false);
if (p.on) {
ctx.fill();
} else {
ctx.stroke();
}
ctx.save();
ctx.strokeStyle = 'orange';
ctx.fillStyle = 'orange';
font.delta(name, k).forEach((d) => {
var x = p.x, y = p.y, dx = parseInt(d.getAttribute('x')), dy = parseInt(d.getAttribute('y'));
if (dx !== 0 || dy !== 0) {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + dx, y + dy);
ctx.stroke();
arrowHead(ctx, x + dx, y + dy, calcAngle(dx, dy), 10);
}
ctx.beginPath();
ctx.arc(x + dx, y + dy, 2, 0, Math.PI * 2, false);
ctx.fill();
});
ctx.restore();
});
ctx.restore();
ctx.restore();
}
function fillGlyphSelector(selected) {
var glyphSelector = document.getElementById('glyph-selector');
while (glyphSelector.firstChild) {
glyphSelector.removeChild(glyphSelector.firstChild);
}
font.glyphs().forEach((glyph) => {
var option = document.createElement('option');
option.value = glyph.getAttribute('name');
option.appendChild(document.createTextNode(option.value));
if (selected && option.value === selected) {
option.selected = true;
}
glyphSelector.appendChild(option);
});
}
function arrowHead(ctx, x, y, angle, size) {
ctx.save();
ctx.translate(x, y);
// ctx.arc(0, 0, 10, 0, 2 * Math.PI, false);
// // ctx.stroke();
ctx.rotate(angle + Math.PI * .75);
ctx.scale(size / 10, size / 10);
ctx.beginPath();
ctx.moveTo(3, 10);
ctx.lineTo(0, 0);
ctx.lineTo(10, 3);
// ctx.endPath();
ctx.stroke();
ctx.restore();
}
function calcAngle(dx, dy) {
return Math.atan(dy / dx) + ((dx < 0) ? Math.PI : 0);
}
function loadTTX(path) {
const xml = fs.readFileSync(path);
font = new Font(xml);
const selectedGlyph = localStorage.getItem('TTXInspectoreSelectedGlyph');
fillGlyphSelector(selectedGlyph);
if (selectedGlyph) {
drawGlyph(selectedGlyph, font);
}
}
function loadFont() {
var paths = dialog.showOpenDialog({ properties: ['openFile'], filters: [{ name: 'ttx', extensions: ['ttx'] }] });
if (paths && paths.length > 0) {
const path = paths[0];
localStorage.setItem('TTXInspectorFontPath', path);
localStorage.removeItem('TTXInspectoreSelectedGlyph');
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
loadTTX(path);
}
}
function loadFromStorage() {
const path = localStorage.getItem('TTXInspectorFontPath')
if (path) {
loadTTX(path);
}
}
document.getElementById('select-font').addEventListener('click', loadFont);
document.getElementById('glyph-selector').addEventListener('change', function () {
var value = this.value;
localStorage.setItem('TTXInspectoreSelectedGlyph', value);
drawGlyph(value, font);
});
document.getElementById('export-canvas').addEventListener('click', () => {
const canvas = document.getElementById('canvas'),
path = dialog.showSaveDialog({});
reader = new FileReader();
reader.onload = function () {
fs.writeFileSync(path, Buffer.from(this.result));
}
if (path) {
canvas.toBlob((blob) => {
reader.readAsArrayBuffer(blob);
}, 'image/png');
}
});
document.getElementById('reload-font').addEventListener('click', loadFromStorage);
loadFromStorage();
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment