Skip to content
Merged

Dev #60

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6,523 changes: 6,523 additions & 0 deletions debug/external/OpenJsCad/csg.js

Large diffs are not rendered by default.

340 changes: 340 additions & 0 deletions debug/external/OpenJsCad/formats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,340 @@
/*
## License

Copyright (c) 2014 bebbi (elghatta@gmail.com)
Copyright (c) 2013 Eduard Bespalov (edwbes@gmail.com)
Copyright (c) 2012 Joost Nieuwenhuijse (joost@newhouse.nl)
Copyright (c) 2011 Evan Wallace (http://evanw.github.com/csg.js/)
Copyright (c) 2012 Alexandre Girard (https://github.com/alx)

All code released under MIT license

*/

if(typeof module !== 'undefined') { // used via nodejs
var lib = lib || './';
CSG = require(lib+'csg.js').CSG;
CAG = require(lib+'csg.js').CAG;
}

////////////////////////////////////////////
// X3D Export
////////////////////////////////////////////

CSG.prototype.toX3D = function() {
// materialPolygonLists
// key: a color string (e.g. "0 1 1" for yellow)
// value: an array of strings specifying polygons of this color
// (as space-separated indices into vertexCoords)
var materialPolygonLists = {},
// list of coordinates (as "x y z" strings)
vertexCoords = [],
// map to look up the index in vertexCoords of a given vertex
vertexTagToCoordIndexMap = {};

this.polygons.map(function(p) {
var red = 0,
green = 0,
blue = 1; // default color is blue
if (p.shared && p.shared.color) {
red = p.shared.color[0];
green = p.shared.color[1];
blue = p.shared.color[2];
}

var polygonVertexIndices = [],
numvertices = p.vertices.length,
vertex;
for (var i = 0; i < numvertices; i++) {
vertex = p.vertices[i];
if (!(vertex.getTag() in vertexTagToCoordIndexMap)) {
vertexCoords.push(vertex.pos._x.toString() + " " +
vertex.pos._y.toString() + " " +
vertex.pos._z.toString()
);
vertexTagToCoordIndexMap[vertex.getTag()] = vertexCoords.length - 1;
}
polygonVertexIndices.push(vertexTagToCoordIndexMap[vertex.getTag()]);
}

var polygonString = polygonVertexIndices.join(" ");

var colorString = red.toString() + " " + green.toString() + " " + blue.toString();
if (!(colorString in materialPolygonLists)) {
materialPolygonLists[colorString] = [];
}
// add this polygonString to the list of colorString-colored polygons
materialPolygonLists[colorString].push(polygonString);
});


// create output document
var docType = document.implementation.createDocumentType("X3D",
'ISO//Web3D//DTD X3D 3.1//EN" "http://www.web3d.org/specifications/x3d-3.1.dtd', null);
var exportDoc = document.implementation.createDocument(null, "X3D", docType);
exportDoc.insertBefore(
exportDoc.createProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"'),
exportDoc.doctype);

var exportRoot = exportDoc.getElementsByTagName("X3D")[0];
exportRoot.setAttribute("profile", "Interchange");
exportRoot.setAttribute("version", "3.1");
exportRoot.setAttribute("xsd:noNamespaceSchemaLocation", "http://www.web3d.org/specifications/x3d-3.1.xsd");
exportRoot.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema-instance");

var exportScene = exportDoc.createElement("Scene");
exportRoot.appendChild(exportScene);

/*
For each color, create a shape made of an appropriately colored
material which contains all polygons that are this color.

The first shape will contain the definition of all vertices,
(<Coordinate DEF="coords_mesh"/>), which will be referenced by
subsequent shapes.
*/
var coordsMeshDefined = false;
for (var colorString in materialPolygonLists) {
var polygonList = materialPolygonLists[colorString];
var shape = exportDoc.createElement("Shape");
exportScene.appendChild(shape);

var appearance = exportDoc.createElement("Appearance");
shape.appendChild(appearance);

var material = exportDoc.createElement("Material");
appearance.appendChild(material);
material.setAttribute("diffuseColor", colorString);
material.setAttribute("ambientIntensity", "1.0");

var ifs = exportDoc.createElement("IndexedFaceSet");
shape.appendChild(ifs);
ifs.setAttribute("solid", "true");
ifs.setAttribute("coordIndex", polygonList.join(" -1 ") + " -1");

var coordinate = exportDoc.createElement("Coordinate");
ifs.appendChild(coordinate);
if (coordsMeshDefined) {
coordinate.setAttribute("USE", "coords_mesh");
} else {
coordinate.setAttribute("DEF", "coords_mesh");
coordinate.setAttribute("point", vertexCoords.join(" "));
coordsMeshDefined = true;
}
}

var x3dstring = (new XMLSerializer()).serializeToString(exportDoc);
return new Blob([x3dstring], {
type: "model/x3d+xml"
});
};

////////////////////////////////////////////
// STL Binary Export
////////////////////////////////////////////

// see http://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL
CSG.prototype.toStlBinary = function() {
// first check if the host is little-endian:
var buffer = new ArrayBuffer(4);
var int32buffer = new Int32Array(buffer, 0, 1);
var int8buffer = new Int8Array(buffer, 0, 4);
int32buffer[0] = 0x11223344;
if (int8buffer[0] != 0x44) {
throw new Error("Binary STL output is currently only supported on little-endian (Intel) processors");
}

var numtriangles = 0;
this.polygons.map(function(p) {
var numvertices = p.vertices.length;
var thisnumtriangles = (numvertices >= 3) ? numvertices - 2 : 0;
numtriangles += thisnumtriangles;
});
var headerarray = new Uint8Array(80);
for (var i = 0; i < 80; i++) {
headerarray[i] = 65;
}
var ar1 = new Uint32Array(1);
ar1[0] = numtriangles;
// write the triangles to allTrianglesBuffer:
var allTrianglesBuffer = new ArrayBuffer(50 * numtriangles);
var allTrianglesBufferAsInt8 = new Int8Array(allTrianglesBuffer);
// a tricky problem is that a Float32Array must be aligned at 4-byte boundaries (at least in certain browsers)
// while each triangle takes 50 bytes. Therefore we write each triangle to a temporary buffer, and copy that
// into allTrianglesBuffer:
var triangleBuffer = new ArrayBuffer(50);
var triangleBufferAsInt8 = new Int8Array(triangleBuffer);
// each triangle consists of 12 floats:
var triangleFloat32array = new Float32Array(triangleBuffer, 0, 12);
// and one uint16:
var triangleUint16array = new Uint16Array(triangleBuffer, 48, 1);
var byteoffset = 0;
this.polygons.map(function(p) {
var numvertices = p.vertices.length;
for (var i = 0; i < numvertices - 2; i++) {
var normal = p.plane.normal;
triangleFloat32array[0] = normal._x;
triangleFloat32array[1] = normal._y;
triangleFloat32array[2] = normal._z;
var arindex = 3;
for (var v = 0; v < 3; v++) {
var vv = v + ((v > 0) ? i : 0);
var vertexpos = p.vertices[vv].pos;
triangleFloat32array[arindex++] = vertexpos._x;
triangleFloat32array[arindex++] = vertexpos._y;
triangleFloat32array[arindex++] = vertexpos._z;
}
triangleUint16array[0] = 0;
// copy the triangle into allTrianglesBuffer:
allTrianglesBufferAsInt8.set(triangleBufferAsInt8, byteoffset);
byteoffset += 50;
}
});
return new Blob([headerarray.buffer, ar1.buffer, allTrianglesBuffer], {
type: "application/sla"
});
};

////////////////////////////////////////////
// STL String Export
////////////////////////////////////////////

CSG.prototype.toStlString = function() {
var result = "solid csg.js\n";
this.polygons.map(function(p) {
result += p.toStlString();
});
result += "endsolid csg.js\n";
return result;
};

CSG.Vector3D.prototype.toStlString = function() {
return this._x + " " + this._y + " " + this._z;
};

CSG.Vertex.prototype.toStlString = function() {
return "vertex " + this.pos.toStlString() + "\n";
};

CSG.Polygon.prototype.toStlString = function() {
var result = "";
if (this.vertices.length >= 3) // should be!
{
// STL requires triangular polygons. If our polygon has more vertices, create
// multiple triangles:
var firstVertexStl = this.vertices[0].toStlString();
for (var i = 0; i < this.vertices.length - 2; i++) {
result += "facet normal " + this.plane.normal.toStlString() + "\nouter loop\n";
result += firstVertexStl;
result += this.vertices[i + 1].toStlString();
result += this.vertices[i + 2].toStlString();
result += "endloop\nendfacet\n";
}
}
return result;
};

////////////////////////////////////////////
// DXF Export
////////////////////////////////////////////

CAG.PathsToDxf = function(paths) {
var str = "999\nDXF generated by OpenJsCad\n";
str += " 0\nSECTION\n 2\nHEADER\n";
str += " 0\nENDSEC\n";
str += " 0\nSECTION\n 2\nTABLES\n";
str += " 0\nTABLE\n 2\nLTYPE\n 70\n1\n";
str += " 0\nLTYPE\n 2\nCONTINUOUS\n 3\nSolid Line\n 72\n65\n 73\n0\n 40\n0.0\n";
str += " 0\nENDTAB\n";
str += " 0\nTABLE\n 2\nLAYER\n 70\n1\n";
str += " 0\nLAYER\n 2\nOpenJsCad\n 62\n7\n 6\ncontinuous\n";
str += " 0\nENDTAB\n";
str += " 0\nTABLE\n 2\nSTYLE\n 70\n0\n 0\nENDTAB\n";
str += " 0\nTABLE\n 2\nVIEW\n 70\n0\n 0\nENDTAB\n";
str += " 0\nENDSEC\n";
str += " 0\nSECTION\n 2\nBLOCKS\n";
str += " 0\nENDSEC\n";
str += " 0\nSECTION\n 2\nENTITIES\n";
paths.map(function(path) {
var numpoints_closed = path.points.length + (path.closed ? 1 : 0);
str += " 0\nLWPOLYLINE\n 8\nOpenJsCad\n 90\n" + numpoints_closed + "\n 70\n" + (path.closed ? 1 : 0) + "\n";
for (var pointindex = 0; pointindex < numpoints_closed; pointindex++) {
var pointindexwrapped = pointindex;
if (pointindexwrapped >= path.points.length) pointindexwrapped -= path.points.length;
var point = path.points[pointindexwrapped];
str += " 10\n" + point.x + "\n 20\n" + point.y + "\n 30\n0.0\n";
}
});
str += " 0\nENDSEC\n 0\nEOF\n";
return new Blob([str], {
type: "application/dxf"
});
};

CAG.prototype.toDxf = function() {
var paths = this.getOutlinePaths();
return CAG.PathsToDxf(paths);
};

////////////////////////////////////////////
// AMF Export
////////////////////////////////////////////

CSG.prototype.toAMFString = function(m) {
var result = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<amf"+(m&&m.unit?" unit=\"+m.unit\"":"")+">\n";
for(var k in m) {
result += "<metadata type=\""+k+"\">"+m[k]+"</metadata>\n";
}
result += "<object id=\"0\">\n<mesh>\n<vertices>\n";

this.polygons.map(function(p) { // first we dump all vertices of all polygons
for(var i=0; i<p.vertices.length; i++) {
result += p.vertices[i].toAMFString();
}
});
result += "</vertices>\n";

var n = 0;
this.polygons.map(function(p) { // then we dump all polygons
result += "<volume>\n";
if(p.vertices.length<3)
return;
var r = 1, g = 0.4, b = 1, a = 1, colorSet = false;
if(p.shared && p.shared.color) {
r = p.shared.color[0];
g = p.shared.color[1];
b = p.shared.color[2];
a = p.shared.color[3];
colorSet = true;
} else if(p.color) {
r = p.color[0];
g = p.color[1];
b = p.color[2];
if(p.color.length()>3) a = p.color[3];
colorSet = true;
}
result += "<color><r>"+r+"</r><g>"+g+"</g><b>"+b+"</b>"+(a!==undefined?"<a>"+a+"</a>":"")+"</color>";

for(var i=0; i<p.vertices.length-2; i++) { // making sure they are all triangles (triangular polygons)
result += "<triangle>";
result += "<v1>" + (n) + "</v1>";
result += "<v2>" + (n+i+1) + "</v2>";
result += "<v3>" + (n+i+2) + "</v3>";
result += "</triangle>\n";
}
n += p.vertices.length;
result += "</volume>\n";
});
result += "</mesh>\n</object>\n";
result += "</amf>\n";
return result;
};

CSG.Vector3D.prototype.toAMFString = function() {
return "<x>" + this._x + "</x><y>" + this._y + "</y><z>" + this._z + "</z>";
};

CSG.Vertex.prototype.toAMFString = function() {
return "<vertex><coordinates>" + this.pos.toAMFString() + "</coordinates></vertex>\n";
};

File renamed without changes.
7 changes: 1 addition & 6 deletions debug/viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ body {
right: 210px;
overflow: hidden;
}
svg, .svg-zone, #export-zone {
svg, .svg-zone {
height: 100%;
width: 100%;
}
Expand All @@ -54,11 +54,6 @@ svg line, svg circle, svg path {
svg text {
fill: #0ff;
}
#export-zone {
overflow: scroll;
display: none;
background-color: rgba(255,255,255,.9);
}
.optionpanel {
position: fixed;
left: 20px;
Expand Down
Loading