fixed merge conflicts

This commit is contained in:
Mario Lukas 2017-06-16 16:18:14 +02:00
commit 0b82b6d678
62 changed files with 246964 additions and 23 deletions

View file

@ -39,6 +39,13 @@
<script src="{{ base_url }}/js/jquery-2.1.1.min.js"></script>
<script src="{{ base_url }}/js/modernizr-2.8.3.min.js"></script>
<script type="text/javascript" src="{{ base_url }}/js/highlight.pack.js"></script>
<<<<<<< HEAD
=======
{% if page and page.title == 'Examples' %}
<script src="{{ base_url }}/js/three.js"></script>
<script src="{{ base_url }}/js/PLYLoader.js"></script>
{% endif %}
>>>>>>> master
{%- endblock %}
{%- block extrahead %} {% endblock %}
@ -102,6 +109,12 @@
{% block content %}
{{ page.content }}
{% endblock %}
<<<<<<< HEAD
=======
{% if page and page.title == 'Examples' %}
{% include "scans.html" %}
{% endif %}
>>>>>>> master
</div>
</div>
{%- block footer %}

185
docs-theme/scans.html Normal file
View file

@ -0,0 +1,185 @@
<!-- Div which will hold the Output -->
<div id="WebGL-output">
<div id="loading-indicator">
<div class="sk-three-bounce">
<div class="sk-child sk-bounce1"></div>
<div class="sk-child sk-bounce2"></div>
<div class="sk-child sk-bounce3"></div>
</div>
</div>
</div>
<ul class="example-preview">
<li><img id="duck-example" src="../examples/duck/duck.png"><a href="../examples/duck/duck_pointcloud.ply">Download</a></li><!--
--><li><img id="bear-example" src="../examples/bear/bear.png"><a href="../examples/bear/bear_pointcloud.ply">Download</a></li><!--
--><li><img id="glue-stick-example" src="../examples/glue_stick/glue_stick.png"><a href="../examples/glue_stick/glue_stick_pointcloud.ply">Download</a></li><!--
--><li><img id="sculpture-example" src="../examples/sculpture/sculpture.png"><a href="../examples/sculpture/sculpture_pointcloud.ply">Download</a></li><!--
--><li><img id="seal-example" src="../examples/seal/seal.png"><a href="../examples/seal/seal_pointcloud.ply">Download</a></li>
</ul>
<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
var camera, cameraTarget, scene, renderer;
var cameraDistance = 150;
var loader;
var loadGeometry;
var model;
var indicator = $('#loading-indicator');
indicator.show();
init();
animate();
function init() {
container = document.getElementById( 'WebGL-output' );
camera = new THREE.PerspectiveCamera( 45, container.clientWidth / (container.clientWidth*0.6), 1, 2000 );
camera.position.set( cameraDistance, 0, 0 );
cameraTarget = new THREE.Vector3( 0, 0, 0 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x72645b, 200, 600 );
// Ground
geometry = new THREE.CylinderGeometry( 70, 70, 2, 32 );
material = new THREE.MeshBasicMaterial( {color: 0xDEDEDE} );
turntable = new THREE.Mesh( geometry, material );
turntable.name = "turntable";
scene.add( turntable );
// PLY file
loader = new THREE.PLYLoader();
loader.useColor = true;
loader.colorsNeedUpdate = true;
loadGeometry = function ( geometry ) {
if(model) {
scene.remove(model);
}
var material = new THREE.PointsMaterial({
size: 2,
vertexColors : THREE.VertexColors
});
model = new THREE.Points(geometry, material);
model.rotateX(-Math.PI/2);
model.geometry.computeBoundingSphere();
model.geometry.computeBoundingBox();
camera.position.y = model.geometry.boundingSphere.center.z*1.2;
cameraTarget = new THREE.Vector3( 0, model.geometry.boundingSphere.center.z, 0 );
turntable.position.y = model.geometry.boundingBox.min.z-1;
scene.add( model );
indicator.hide();
};
// Lights
scene.add( new THREE.HemisphereLight( 0x443333, 0x111122 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
addShadowedLight( 0.5, 1, -1, 0xffaa00, 1 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( scene.fog.color );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( container.clientWidth, container.clientWidth*0.6 );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMap.enabled = true;
renderer.shadowMap.renderReverseSided = false;
container.appendChild( renderer.domElement );
// resize
window.addEventListener( 'resize', onWindowResize, false );
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z );
scene.add( directionalLight );
directionalLight.castShadow = true;
var d = 1;
directionalLight.shadow.camera.left = -d;
directionalLight.shadow.camera.right = d;
directionalLight.shadow.camera.top = d;
directionalLight.shadow.camera.bottom = -d;
directionalLight.shadow.camera.near = 1;
directionalLight.shadow.camera.far = 4;
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;
directionalLight.shadow.bias = -0.005;
}
function onWindowResize() {
camera.aspect = container.clientWidth / (container.clientWidth*0.6) ;
camera.updateProjectionMatrix();
renderer.setSize( container.clientWidth, container.clientWidth*0.6 );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var timer = Date.now() * 0.0005;
camera.position.x = Math.sin( timer ) * cameraDistance;
camera.position.z = Math.cos( timer ) * cameraDistance;
camera.lookAt( cameraTarget );
renderer.render( scene, camera );
}
document.getElementById('duck-example').onclick=function() {
indicator.show();
loader.load( '../examples/duck/duck_pointcloud.ply', loadGeometry);
};
document.getElementById('bear-example').onclick=function() {
indicator.show();
loader.load( '../examples/bear/bear_pointcloud.ply', loadGeometry);
};
document.getElementById('glue-stick-example').onclick=function() {
indicator.show();
loader.load( '../examples/glue_stick/glue_stick_pointcloud.ply', loadGeometry);
};
document.getElementById('sculpture-example').onclick=function() {
indicator.show();
loader.load( '../examples/sculpture/sculpture_pointcloud.ply', loadGeometry);
};
document.getElementById('seal-example').onclick=function() {
indicator.show();
loader.load( '../examples/seal/seal_pointcloud.ply', loadGeometry);
};
loader.load( '../examples/duck/duck_pointcloud.ply', loadGeometry);
</script>

View file

@ -1,7 +1,11 @@
#Slack
Use the FabScan Slack channel for direct messaging and chat communication.
This is the fastest way of getting support. For joining write an email to
info@fabscan.org with subject "add me to slack"
This is the fastest way of getting support.
Signup here: [https://fabscan.signup.team](https://fabscan.signup.team)
Or write an email to:
info@fabscan.org with subject "add me to slack"
#Google Group
For general problems and information use the FabScan google group.

View file

@ -67,3 +67,83 @@ img[alt=drawing_450] {
img[alt=browser_logo] {
width: 40px;
}
ul.example-preview {
}
ul.example-preview > li {
width:20%;
margin-left: 0 !important;
padding-left: 0 !important;
list-style: none !important;
display: inline-block;
cursor: pointer;
}
#WebGL-output {
position: relative;
}
#loading-indicator {
position: absolute;
width: 100%;
text-align: center;
top: 40%;
}
.sk-three-bounce {
margin: 5px auto;
text-align: center;
border: 0.2em white;
display: inline-block;
background: white;
padding: 1em 2em;
border-radius: 0.6em;
opacity: 0.6;
}
.sk-three-bounce .sk-child {
width: 20px;
height: 20px;
background-color: #333;
border-radius: 100%;
display: inline-block;
-webkit-animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;
animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;
}
.sk-three-bounce .sk-bounce1 {
-webkit-animation-delay: -0.32s;
animation-delay: -0.32s;
}
.sk-three-bounce .sk-bounce2 {
-webkit-animation-delay: -0.16s;
animation-delay: -0.16s;
}
@-webkit-keyframes sk-three-bounce {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0);
}
40% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes sk-three-bounce {
0%, 80%, 100% {
-webkit-transform: scale(0);
transform: scale(0);
}
40% {
-webkit-transform: scale(1);
transform: scale(1);
}
}}
.spacer{
padding:10px;
}

4
docs/css/font-awesome.min.css vendored Normal file

File diff suppressed because one or more lines are too long

4
docs/examples.md Normal file
View file

@ -0,0 +1,4 @@
### Examples
Here are some examples of scans created with FabScanPi.
Additionally you can find the examples together with derived meshes as .STL files at [Github](https://github.com/mariolukas/FabScanPi-Server/tree/master/docs/examples).

19
docs/examples/README.md Normal file
View file

@ -0,0 +1,19 @@
# FabScan PI - Sample Scans
This folder contains some sample scans made with the FabScan Pi.
![Rubber Duck](/docs/examples/duck/duck_icon.png)
duck - the famous fabscan rubber duck
![Fabscan Bear](/docs/examples/bear/bear_icon.png)
bear - the famous fabscan bear
![Seal Toy](/docs/examples/seal/seal_icon.png)
seal - a rubber seal toy
![Glue Stick](/docs/examples/glue_stick/glue_stick_icon.png)
glue_stick - a red glue stick, typically used for 3D printing
![sculpture](/docs/examples/sculpture/sculpture_icon.png)
sculpture - a sculpture head which was made of plaster

BIN
docs/examples/bear/bear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

BIN
docs/examples/duck/duck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

BIN
docs/examples/seal/seal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -24,6 +24,8 @@ The laser cut files can be found at [https://github.com/mariolukas/FabScan-Case]
#The FabScanPi HAT
**General description**
The FabScan HAT is basically a combination of an Arduino and the old
FabScan Shield for Arduino. It provides all connectors for the hardware
parts (like motors, servos, lasers, LED's etc.) Instead of an USB
@ -34,6 +36,7 @@ flashed automatically by the FabscanPi-Server application.
![drawing_400](images/fabscanpihat.png)
<<<<<<< HEAD
# How to Asselmble the FabScanPi HAT
**Materials & Tools**
@ -53,11 +56,126 @@ flashed automatically by the FabscanPi-Server application.
Use the side cutter to cut two pieces of 3 pins from the male header, like you on the picture above.
#Connecting the Stepper Motor
=======
**How to Assemble the FabScanPi HAT**
* * *
<i class="fa fa-info-circle spacer" aria-hidden="true"></i> _About Soldering_
_If you are soldering for the very fist time, we suggest to read the comic ["Soldering is Easy"](https://mightyohm.com/files/soldercomic/FullSolderComic_EN.pdf) by Mitch Altman (soldering wisdom), Andie Nordgren (comic adaption) and Jeff Keyzer (layout and editing)._
* * *
<iframe width="560" height="315" src="https://www.youtube.com/embed/DogfNxk277Y" frameborder="0" allowfullscreen></iframe>
The FabScanPi HAT will be delivered with the main components already assembled. You only need to install the headers and connectors which fit your demand.
![drawing_400](images\hat_assembly_1.jpg)
Let's start with the female 8-pin headers for the stepper motor controllers. First the two headers which are designated with "Stepper Turn Table". Put one in and flip the pcb to solder the pins on the rear side. Solder one pin first and make sure the header is still in the correct position. A "third hand" tool or a pcb-holder are very helpful for this job.
Now you can select between three options
- **Option A:** Two stepper motor ports for the laser adjustment or
- **Option B:** Two servo connector ports for the laser adjustment or
- **Option C:** Two stepper and two servo connector ports for the lasers (additional headers required)
**Option A:**
Use the remaining four 8-pin femal pin headers and install them on the pcb. You can now use the HAT with three stepper motors (1x turn table, 2x laser control)
![drawing_400](images\hat_assembly_2a.jpg)
**Option B:**
Use an electronics wire cutter to cut off two 3-pin male headers from the long male-header. Put them into the pinholes labeled "Servo opt." You can now use the HAT with one stepper motors (1x turn table) and two servos (2x servo opt.).
![drawing_400](images\hat_assembly_2.jpg)
**Option C:**
If you are unsure about using servos or stepper motors you can install both. Therefore you'll need to buy four 8-pin female headers which are at least 8 mm of height. Install them at the pinholes for the "Stepper Laser 1 and 2". Also cut off two 3-pin male headers from the long male-header. Put them into the pinholes labeled "Servo opt." Now you can use either servo controllers nor the connectors for the servos.
![drawing_400](images\hat_assembly_2b.jpg)
**Connector for the LED-Ring**
The next connector is the JST connector for the RPi-RingLight. Make sure the direction is correct. Fix it and solder the three pins on the rear side of the PCB.
![drawing_400](images\hat_assembly_3.jpg)
**Connectors for the stepper motors**
Here you can use the three 4-port screw terminals if your stepper cables have no connector plug.
![drawing_400](images\hat_assembly_4.jpg)
If the stepper motor cables have an 4-pin female connector you can use three 4-pin male headers (to be cutted off from the long header).
![drawing_400](images\hat_assembly_4a.jpg)
**Connector for Laser(s) and Laser safety switch**
The next connector to be installed is the 6-port screw terminal. It must be soldered into the corresponding pin holes between the JST connector and the 8-pin female header for the table stepper. Later this 6-port terminal will be used to connect the Laser(s) and the Laser safety switch.
![drawing_400](images\hat_assembly_5.jpg)
**Power Connector** (DC- jack)
Now the DC-jack power connector will be installed into three oval pin holes across from the 2x20-pin socket header. Soldering is done from the top side of the PCB.
![drawing_400](images\RPi-FabScan-HAT13.jpg)
**Assembling the Raspberry-Pi Connector**
Now the 2x20-pin socket connector must be installed from the rear side of the PCB (where we only did soldering till now). Soldering of the 2x20-pin connector is done on the front side (where all our parts are placed). This connector is used as interface for the Raspberry-Pi.
![drawing_400](images\hat_assembly_7.jpg)
_Attention: The power connector in this image is soldered in an alternative way. The recommended way
is shown in the image before._
**Mount the 5V DC/DC converter or 5V external Power Source**
Additionally to the 12V DC coming from the power supply the FabScanPi needs 5V DC. Now you have to decide if you want to use a DC/DC converter IC which generates the 5V out of the 12V from the external 12 power supply (common solution).
For the DC/DC converter option you can find further instructions and pictures on the [Watterott electronic website](https://github.com/watterott/RPi-FabScan-HAT/blob/master/hardware/RPi-FabScan-HAT_Assembly.pdf).
If you are using another power supply which is capable of delivering 12V and 5V DC you can connect it as well. Details can be found [here](#5V-EXT).
#Connecting the Stepper Motor(s)
>>>>>>> master
There are different kinds of stepper motos. Mostly with 4 or 6 leads. For
connecting the stepper motor to the FabScanPi HAT you need to know the
corresponding lead pairs of the motor coils. The best way to find out something
about the motor is to have a look at the datasheet of the motor manufacturer.
In the following desciptions the pairs are called (1A, 1B) and (2A, 2B).
In the following desciptions the pairs are called (2B, 1B) and (1A, 2A).
![drawing_300](images/4wires.jpg)
![drawing_300](images/6wires.jpg)
@ -130,7 +248,7 @@ for 1 turntable stepper motor, 1 PiCam and 1 laser.
| (white square) | Ground (GND) |
| 5V | 5V output from regulator to FabScanPi HAT |
For the DC/DC converter option you can find further instructions and pictures on the [Watterott electronic website](https://github.com/watterott/RPi-FabScan-HAT/blob/master/hardware/RPi-FabScan-HAT_Assembly.pdf).
NOTE: For the final stage of constuction a more powerful power supply is needed. At the moment there are no technical specifications available.
@ -144,7 +262,7 @@ NOTE: Make sure you switch on the both power sources at the same time to avoid s
**Option C:**
**Option C:**<a name="5V-EXT"></a>
Connect 12V DC to the HAT (round connector) and connect a 5V DC power source to the 5V pin regulator pin on the HAT. Make sure the 5V power source can provide a current of min. 2.0A for
@ -178,19 +296,19 @@ Even if you use the srew set from Watterott, as given in the *BOM*, here is the
**Screws**
| Type | Length | Qty | Usage |
|------|--------|-----|-------------------------|
| M2 | 16 | 2 | Servo Hitec-HS53 |
| | | 2 | Security Switch |
| | | 1 | 5mW line Laser red |
| M2.5 | 15 | 4 | RaspberryPi |
| M3 | 10 | 4 | Stepper motor |
| | | 4 | RPi-RingLight |
| | | 4 | Turn-table Mounting Hub |
| Type | Length | Qty | Usage |
| ---- | ------ | ---- | ----------------------- |
| M2 | 16 | 2 | Servo Hitec-HS53 |
| | | 2 | Security Switch |
| | | 1 | 5mW line Laser red |
| M2.5 | 15 | 4 | RaspberryPi |
| M3 | 10 | 4 | Stepper motor |
| | | 4 | RPi-RingLight |
| | | 4 | Turn-table Mounting Hub |
**Washers**
| Type | Heigth | Qty | Usage |
|---------|--------|-----|---------------|
| 3.4/4.5 | 1 | 4 | Stepper motor |
| 2.5/4.5 | 3 | 4 | RaspberryPi |
| Type | Heigth | Qty | Usage |
| ------- | ------ | ---- | ------------- |
| 3.4/4.5 | 1 | 4 | Stepper motor |
| 2.5/4.5 | 3 | 4 | RaspberryPi |

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
docs/images/RingLicht_1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
docs/images/RingLicht_2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
docs/images/RingLicht_3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
docs/images/RingLicht_4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

BIN
docs/images/RingLicht_5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
docs/images/RingLicht_6.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

482
docs/js/PLYLoader.js Executable file
View file

@ -0,0 +1,482 @@
/**
* @author Wei Meng / http://about.me/menway
*
* Description: A THREE loader for PLY ASCII files (known as the Polygon File Format or the Stanford Triangle Format).
*
*
* Limitations: ASCII decoding assumes file is UTF-8.
*
* Usage:
* var loader = new THREE.PLYLoader();
* loader.load('./models/ply/ascii/dolphins.ply', function (geometry) {
*
* scene.add( new THREE.Mesh( geometry ) );
*
* } );
*
* If the PLY file uses non standard property names, they can be mapped while
* loading. For example, the following maps the properties
* diffuse_(red|green|blue) in the file to standard color names.
*
* loader.setPropertyNameMapping( {
* diffuse_red: 'red',
* diffuse_green: 'green',
* diffuse_blue: 'blue'
* } );
*
*/
THREE.PLYLoader = function () {
this.propertyNameMapping = {};
};
THREE.PLYLoader.prototype = {
constructor: THREE.PLYLoader,
setPropertyNameMapping: function ( mapping ) {
this.propertyNameMapping = mapping;
},
load: function ( url, callback ) {
var scope = this;
var request = new XMLHttpRequest();
request.addEventListener( 'load', function ( event ) {
var geometry = scope.parse( event.target.response );
scope.dispatchEvent( { type: 'load', content: geometry } );
if ( callback ) callback( geometry );
}, false );
request.addEventListener( 'progress', function ( event ) {
scope.dispatchEvent( { type: 'progress', loaded: event.loaded, total: event.total } );
}, false );
request.addEventListener( 'error', function () {
scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
}, false );
request.open( 'GET', url, true );
request.responseType = "arraybuffer";
request.send( null );
},
bin2str: function (buf) {
var array_buffer = new Uint8Array(buf);
var str = '';
for (var i = 0; i < buf.byteLength; i ++) {
str += String.fromCharCode(array_buffer[i]); // implicitly assumes little-endian
}
return str;
},
isASCII: function( data ) {
var header = this.parseHeader( this.bin2str( data ) );
return header.format === "ascii";
},
parse: function ( data ) {
if ( data instanceof ArrayBuffer ) {
return this.isASCII( data )
? this.parseASCII( this.bin2str( data ) )
: this.parseBinary( data );
} else {
return this.parseASCII( data );
}
},
parseHeader: function ( data ) {
var patternHeader = /ply([\s\S]*)end_header\s/;
var headerText = "";
var headerLength = 0;
var result = patternHeader.exec( data );
if ( result !== null ) {
headerText = result [ 1 ];
headerLength = result[ 0 ].length;
}
var header = {
comments: [],
elements: [],
headerLength: headerLength
};
var lines = headerText.split( '\n' );
var currentElement = undefined;
var lineType, lineValues;
function make_ply_element_property( propertValues, propertyNameMapping ) {
var property = {
type: propertValues[ 0 ]
};
if ( property.type === 'list' ) {
property.name = propertValues[ 3 ];
property.countType = propertValues[ 1 ];
property.itemType = propertValues[ 2 ];
} else {
property.name = propertValues[ 1 ];
}
if ( property.name in propertyNameMapping ) {
property.name = propertyNameMapping[ property.name ];
}
return property;
}
for ( var i = 0; i < lines.length; i ++ ) {
var line = lines[ i ];
line = line.trim()
if ( line === "" ) { continue; }
lineValues = line.split( /\s+/ );
lineType = lineValues.shift()
line = lineValues.join(" ")
switch ( lineType ) {
case "format":
header.format = lineValues[0];
header.version = lineValues[1];
break;
case "comment":
header.comments.push(line);
break;
case "element":
if ( !(currentElement === undefined) ) {
header.elements.push(currentElement);
}
currentElement = Object();
currentElement.name = lineValues[0];
currentElement.count = parseInt( lineValues[1] );
currentElement.properties = [];
break;
case "property":
currentElement.properties.push( make_ply_element_property( lineValues, this.propertyNameMapping ) );
break;
default:
console.log("unhandled", lineType, lineValues);
}
}
if ( !(currentElement === undefined) ) {
header.elements.push(currentElement);
}
return header;
},
parseASCIINumber: function ( n, type ) {
switch ( type ) {
case 'char': case 'uchar': case 'short': case 'ushort': case 'int': case 'uint':
case 'int8': case 'uint8': case 'int16': case 'uint16': case 'int32': case 'uint32':
return parseInt( n );
case 'float': case 'double': case 'float32': case 'float64':
return parseFloat( n );
}
},
parseASCIIElement: function ( properties, line ) {
var values = line.split( /\s+/ );
var element = Object();
for ( var i = 0; i < properties.length; i ++ ) {
if ( properties[i].type === "list" ) {
var list = [];
var n = this.parseASCIINumber( values.shift(), properties[i].countType );
for ( var j = 0; j < n; j ++ ) {
list.push( this.parseASCIINumber( values.shift(), properties[i].itemType ) );
}
element[ properties[i].name ] = list;
} else {
element[ properties[i].name ] = this.parseASCIINumber( values.shift(), properties[i].type );
}
}
return element;
},
parseASCII: function ( data ) {
// PLY ascii format specification, as per http://en.wikipedia.org/wiki/PLY_(file_format)
var geometry = new THREE.Geometry();
var result;
var header = this.parseHeader( data );
var patternBody = /end_header\s([\s\S]*)$/;
var body = "";
if ( ( result = patternBody.exec( data ) ) !== null ) {
body = result [ 1 ];
}
var lines = body.split( '\n' );
var currentElement = 0;
var currentElementCount = 0;
geometry.useColor = true;
for ( var i = 0; i < lines.length; i ++ ) {
var line = lines[ i ];
line = line.trim()
if ( line === "" ) { continue; }
if ( currentElementCount >= header.elements[currentElement].count ) {
currentElement ++;
currentElementCount = 0;
}
var element = this.parseASCIIElement( header.elements[currentElement].properties, line );
this.handleElement( geometry, header.elements[currentElement].name, element );
currentElementCount ++;
}
return this.postProcess( geometry );
},
postProcess: function ( geometry ) {
if ( geometry.useColor ) {
for ( var i = 0; i < geometry.faces.length; i ++ ) {
geometry.faces[i].vertexColors = [
geometry.colors[geometry.faces[i].a],
geometry.colors[geometry.faces[i].b],
geometry.colors[geometry.faces[i].c]
];
}
geometry.elementsNeedUpdate = true;
}
geometry.computeBoundingSphere();
return geometry;
},
handleElement: function ( geometry, elementName, element ) {
if ( elementName === "vertex" ) {
geometry.vertices.push(
new THREE.Vector3( element.x, element.y, element.z )
);
if ( 'red' in element && 'green' in element && 'blue' in element ) {
geometry.useColor = true;
var color = new THREE.Color();
color.setRGB( element.red / 255.0, element.green / 255.0, element.blue / 255.0 );
geometry.colors.push( color );
}
} else if ( elementName === "face" ) {
var vertex_indices = element.vertex_indices;
if ( vertex_indices.length === 3 ) {
geometry.faces.push(
new THREE.Face3( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 2 ] )
);
} else if ( vertex_indices.length === 4 ) {
geometry.faces.push(
new THREE.Face3( vertex_indices[ 0 ], vertex_indices[ 1 ], vertex_indices[ 3 ] ),
new THREE.Face3( vertex_indices[ 1 ], vertex_indices[ 2 ], vertex_indices[ 3 ] )
);
}
}
},
binaryRead: function ( dataview, at, type, little_endian ) {
switch ( type ) {
// corespondences for non-specific length types here match rply:
case 'int8': case 'char': return [ dataview.getInt8( at ), 1 ];
case 'uint8': case 'uchar': return [ dataview.getUint8( at ), 1 ];
case 'int16': case 'short': return [ dataview.getInt16( at, little_endian ), 2 ];
case 'uint16': case 'ushort': return [ dataview.getUint16( at, little_endian ), 2 ];
case 'int32': case 'int': return [ dataview.getInt32( at, little_endian ), 4 ];
case 'uint32': case 'uint': return [ dataview.getUint32( at, little_endian ), 4 ];
case 'float32': case 'float': return [ dataview.getFloat32( at, little_endian ), 4 ];
case 'float64': case 'double': return [ dataview.getFloat64( at, little_endian ), 8 ];
}
},
binaryReadElement: function ( dataview, at, properties, little_endian ) {
var element = Object();
var result, read = 0;
for ( var i = 0; i < properties.length; i ++ ) {
if ( properties[i].type === "list" ) {
var list = [];
result = this.binaryRead( dataview, at + read, properties[i].countType, little_endian );
var n = result[0];
read += result[1];
for ( var j = 0; j < n; j ++ ) {
result = this.binaryRead( dataview, at + read, properties[i].itemType, little_endian );
list.push( result[0] );
read += result[1];
}
element[ properties[i].name ] = list;
} else {
result = this.binaryRead( dataview, at + read, properties[i].type, little_endian );
element[ properties[i].name ] = result[0];
read += result[1];
}
}
return [ element, read ];
},
parseBinary: function ( data ) {
var geometry = new THREE.Geometry();
var header = this.parseHeader( this.bin2str( data ) );
var little_endian = (header.format === "binary_little_endian");
var body = new DataView( data, header.headerLength );
var result, loc = 0;
for ( var currentElement = 0; currentElement < header.elements.length; currentElement ++ ) {
for ( var currentElementCount = 0; currentElementCount < header.elements[currentElement].count; currentElementCount ++ ) {
result = this.binaryReadElement( body, loc, header.elements[currentElement].properties, little_endian );
loc += result[1];
var element = result[0];
this.handleElement( geometry, header.elements[currentElement].name, element );
}
}
return this.postProcess( geometry );
}
};
THREE.EventDispatcher.prototype.apply( THREE.PLYLoader.prototype );

40560
docs/js/three.js Executable file

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,4 @@
<<<<<<< HEAD
### New FabScanPi release with auto calibration (2017-02-01)
A new release of the FabScanPi software with some new exciting features:
@ -16,5 +17,36 @@ We uploaded some FabScan example scans. You can explore them by visiting the exa
### FabScanPi goes slack (2016-07-10)
To improve the communication between FabScanPi users and enhance the support FabScanPi now uses slack. Register at
[https://fabscan.slack.com](https://fabscan.slack.com) and join the FabScanPi community.
=======
[comment]: <> (### New FabScanPi release with auto calibration (2017-02-01)
[comment]: <> (A new release of the FabScanPi software with some new exciting features:)
[comment]: <> ()
[comment]: <> ( * Auto-calibration improves the scan results and simplifies the setup process.)
[comment]: <> ( * Read news from the FabScanPi project to stay informed about new features and improvements.)
[comment]: <> ( * Improved updates allow to update your installation with one click.)
[comment]: <> ()
[comment]: <> (Have fun!)
**First FabScanPi Workshop (2017-03-30)**
On 1th of april 2017 we will provide the first FabScanPi workshop.
It will take place at Watterott electronic? . The workshop will include all the
needed parts to build your own FabScanPi. You will be guided during the whole workshop.
And finally you will get a sneak preview to the nex release of the FabScanPi
software which includes autocalibration!
More information can be found at: https://goo.gl/mC9cHs
**Added some example scans (2017-01-31)**
We uploaded some FabScan example scans. You can explore them by visiting the example page.
[http://mariolukas.github.io/FabScanPi-Server/examples/](http://mariolukas.github.io/FabScanPi-Server/examples/)
**FabScanPi goes slack (2016-07-10)**
To improve the communication between FabScanPi users and enhance the support FabScanPi now uses slack. Register at
[https://fabscan.signup.team](https://fabscan.signup.team) and join the FabScanPi community.
>>>>>>> master
We look forward to welcoming you!

View file

@ -15,7 +15,7 @@ extra_javascript:
theme: readthedocs
theme_dir: docs-theme
extra:
version: 1.0
version: 0.4.0
repo_url: https://github.com/mariolukas/FabScanPi-Server
site_author: Mario Lukas
site_favicon: images/fabscanpi_ICON.png

View file

@ -3,4 +3,4 @@ pillow ==2.7
Pykka >=1.2
numpy >=1.9
semver >=2.0
mock
mock

View file

@ -125,4 +125,3 @@ def params():
return locals()
setup(**params())

View file

@ -170,6 +170,7 @@ class FSScanner(threading.Thread):
"upgrade": {
"available": self._upgrade_available,
"version": self._upgrade_version
}
}

View file

@ -3,7 +3,6 @@ import logging
logger = logging.getLogger(__name__)
class FSScannerFactory(object):
@staticmethod

View file

@ -387,4 +387,4 @@ class ImageProcessor(ImageProcessorInterface):
if ret:
cv2.cornerSubPix(gray, corners, (11,11), (-1, -1), self._criteria)
return corners
return corners

View file

@ -3,7 +3,11 @@ from urllib2 import URLError
from mock import patch
<<<<<<< HEAD
from fabscan.util.FSUpdate import get_latest_version_tag, upgrade_is_available, do_upgrade
=======
from fabscan.util.FSUpdate import get_latest_version_tag, upgrade_is_available
>>>>>>> master
class FSUpdateTestCase(unittest.TestCase):
@ -30,11 +34,14 @@ class FSUpdateTestCase(unittest.TestCase):
self.assertFalse(upgrade_available)
self.assertEqual(upgrade_version, "0.3.1")
<<<<<<< HEAD
@patch('os.system')
def test_do_upgrade(self, system_mock):
do_upgrade()
system_mock.assert_called_once_with('nohup bash -c "sudo apt-get update && sudo apt-get dist-upgrade" > /var/log/fabscanpi/upgrade.log')
=======
>>>>>>> master
if __name__ == '__main__':
unittest.main()