Skip to content

Commit 6caeb85

Browse files
committed
Merge pull request #60 from Microsoft/dev
Dev
2 parents 8030d4c + e639bf6 commit 6caeb85

File tree

20 files changed

+8900
-209
lines changed

20 files changed

+8900
-209
lines changed

debug/external/OpenJsCad/csg.js

Lines changed: 6523 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
/*
2+
## License
3+
4+
Copyright (c) 2014 bebbi ([email protected])
5+
Copyright (c) 2013 Eduard Bespalov ([email protected])
6+
Copyright (c) 2012 Joost Nieuwenhuijse ([email protected])
7+
Copyright (c) 2011 Evan Wallace (http://evanw.github.com/csg.js/)
8+
Copyright (c) 2012 Alexandre Girard (https://github.com/alx)
9+
10+
All code released under MIT license
11+
12+
*/
13+
14+
if(typeof module !== 'undefined') { // used via nodejs
15+
var lib = lib || './';
16+
CSG = require(lib+'csg.js').CSG;
17+
CAG = require(lib+'csg.js').CAG;
18+
}
19+
20+
////////////////////////////////////////////
21+
// X3D Export
22+
////////////////////////////////////////////
23+
24+
CSG.prototype.toX3D = function() {
25+
// materialPolygonLists
26+
// key: a color string (e.g. "0 1 1" for yellow)
27+
// value: an array of strings specifying polygons of this color
28+
// (as space-separated indices into vertexCoords)
29+
var materialPolygonLists = {},
30+
// list of coordinates (as "x y z" strings)
31+
vertexCoords = [],
32+
// map to look up the index in vertexCoords of a given vertex
33+
vertexTagToCoordIndexMap = {};
34+
35+
this.polygons.map(function(p) {
36+
var red = 0,
37+
green = 0,
38+
blue = 1; // default color is blue
39+
if (p.shared && p.shared.color) {
40+
red = p.shared.color[0];
41+
green = p.shared.color[1];
42+
blue = p.shared.color[2];
43+
}
44+
45+
var polygonVertexIndices = [],
46+
numvertices = p.vertices.length,
47+
vertex;
48+
for (var i = 0; i < numvertices; i++) {
49+
vertex = p.vertices[i];
50+
if (!(vertex.getTag() in vertexTagToCoordIndexMap)) {
51+
vertexCoords.push(vertex.pos._x.toString() + " " +
52+
vertex.pos._y.toString() + " " +
53+
vertex.pos._z.toString()
54+
);
55+
vertexTagToCoordIndexMap[vertex.getTag()] = vertexCoords.length - 1;
56+
}
57+
polygonVertexIndices.push(vertexTagToCoordIndexMap[vertex.getTag()]);
58+
}
59+
60+
var polygonString = polygonVertexIndices.join(" ");
61+
62+
var colorString = red.toString() + " " + green.toString() + " " + blue.toString();
63+
if (!(colorString in materialPolygonLists)) {
64+
materialPolygonLists[colorString] = [];
65+
}
66+
// add this polygonString to the list of colorString-colored polygons
67+
materialPolygonLists[colorString].push(polygonString);
68+
});
69+
70+
71+
// create output document
72+
var docType = document.implementation.createDocumentType("X3D",
73+
'ISO//Web3D//DTD X3D 3.1//EN" "http://www.web3d.org/specifications/x3d-3.1.dtd', null);
74+
var exportDoc = document.implementation.createDocument(null, "X3D", docType);
75+
exportDoc.insertBefore(
76+
exportDoc.createProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"'),
77+
exportDoc.doctype);
78+
79+
var exportRoot = exportDoc.getElementsByTagName("X3D")[0];
80+
exportRoot.setAttribute("profile", "Interchange");
81+
exportRoot.setAttribute("version", "3.1");
82+
exportRoot.setAttribute("xsd:noNamespaceSchemaLocation", "http://www.web3d.org/specifications/x3d-3.1.xsd");
83+
exportRoot.setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema-instance");
84+
85+
var exportScene = exportDoc.createElement("Scene");
86+
exportRoot.appendChild(exportScene);
87+
88+
/*
89+
For each color, create a shape made of an appropriately colored
90+
material which contains all polygons that are this color.
91+
92+
The first shape will contain the definition of all vertices,
93+
(<Coordinate DEF="coords_mesh"/>), which will be referenced by
94+
subsequent shapes.
95+
*/
96+
var coordsMeshDefined = false;
97+
for (var colorString in materialPolygonLists) {
98+
var polygonList = materialPolygonLists[colorString];
99+
var shape = exportDoc.createElement("Shape");
100+
exportScene.appendChild(shape);
101+
102+
var appearance = exportDoc.createElement("Appearance");
103+
shape.appendChild(appearance);
104+
105+
var material = exportDoc.createElement("Material");
106+
appearance.appendChild(material);
107+
material.setAttribute("diffuseColor", colorString);
108+
material.setAttribute("ambientIntensity", "1.0");
109+
110+
var ifs = exportDoc.createElement("IndexedFaceSet");
111+
shape.appendChild(ifs);
112+
ifs.setAttribute("solid", "true");
113+
ifs.setAttribute("coordIndex", polygonList.join(" -1 ") + " -1");
114+
115+
var coordinate = exportDoc.createElement("Coordinate");
116+
ifs.appendChild(coordinate);
117+
if (coordsMeshDefined) {
118+
coordinate.setAttribute("USE", "coords_mesh");
119+
} else {
120+
coordinate.setAttribute("DEF", "coords_mesh");
121+
coordinate.setAttribute("point", vertexCoords.join(" "));
122+
coordsMeshDefined = true;
123+
}
124+
}
125+
126+
var x3dstring = (new XMLSerializer()).serializeToString(exportDoc);
127+
return new Blob([x3dstring], {
128+
type: "model/x3d+xml"
129+
});
130+
};
131+
132+
////////////////////////////////////////////
133+
// STL Binary Export
134+
////////////////////////////////////////////
135+
136+
// see http://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL
137+
CSG.prototype.toStlBinary = function() {
138+
// first check if the host is little-endian:
139+
var buffer = new ArrayBuffer(4);
140+
var int32buffer = new Int32Array(buffer, 0, 1);
141+
var int8buffer = new Int8Array(buffer, 0, 4);
142+
int32buffer[0] = 0x11223344;
143+
if (int8buffer[0] != 0x44) {
144+
throw new Error("Binary STL output is currently only supported on little-endian (Intel) processors");
145+
}
146+
147+
var numtriangles = 0;
148+
this.polygons.map(function(p) {
149+
var numvertices = p.vertices.length;
150+
var thisnumtriangles = (numvertices >= 3) ? numvertices - 2 : 0;
151+
numtriangles += thisnumtriangles;
152+
});
153+
var headerarray = new Uint8Array(80);
154+
for (var i = 0; i < 80; i++) {
155+
headerarray[i] = 65;
156+
}
157+
var ar1 = new Uint32Array(1);
158+
ar1[0] = numtriangles;
159+
// write the triangles to allTrianglesBuffer:
160+
var allTrianglesBuffer = new ArrayBuffer(50 * numtriangles);
161+
var allTrianglesBufferAsInt8 = new Int8Array(allTrianglesBuffer);
162+
// a tricky problem is that a Float32Array must be aligned at 4-byte boundaries (at least in certain browsers)
163+
// while each triangle takes 50 bytes. Therefore we write each triangle to a temporary buffer, and copy that
164+
// into allTrianglesBuffer:
165+
var triangleBuffer = new ArrayBuffer(50);
166+
var triangleBufferAsInt8 = new Int8Array(triangleBuffer);
167+
// each triangle consists of 12 floats:
168+
var triangleFloat32array = new Float32Array(triangleBuffer, 0, 12);
169+
// and one uint16:
170+
var triangleUint16array = new Uint16Array(triangleBuffer, 48, 1);
171+
var byteoffset = 0;
172+
this.polygons.map(function(p) {
173+
var numvertices = p.vertices.length;
174+
for (var i = 0; i < numvertices - 2; i++) {
175+
var normal = p.plane.normal;
176+
triangleFloat32array[0] = normal._x;
177+
triangleFloat32array[1] = normal._y;
178+
triangleFloat32array[2] = normal._z;
179+
var arindex = 3;
180+
for (var v = 0; v < 3; v++) {
181+
var vv = v + ((v > 0) ? i : 0);
182+
var vertexpos = p.vertices[vv].pos;
183+
triangleFloat32array[arindex++] = vertexpos._x;
184+
triangleFloat32array[arindex++] = vertexpos._y;
185+
triangleFloat32array[arindex++] = vertexpos._z;
186+
}
187+
triangleUint16array[0] = 0;
188+
// copy the triangle into allTrianglesBuffer:
189+
allTrianglesBufferAsInt8.set(triangleBufferAsInt8, byteoffset);
190+
byteoffset += 50;
191+
}
192+
});
193+
return new Blob([headerarray.buffer, ar1.buffer, allTrianglesBuffer], {
194+
type: "application/sla"
195+
});
196+
};
197+
198+
////////////////////////////////////////////
199+
// STL String Export
200+
////////////////////////////////////////////
201+
202+
CSG.prototype.toStlString = function() {
203+
var result = "solid csg.js\n";
204+
this.polygons.map(function(p) {
205+
result += p.toStlString();
206+
});
207+
result += "endsolid csg.js\n";
208+
return result;
209+
};
210+
211+
CSG.Vector3D.prototype.toStlString = function() {
212+
return this._x + " " + this._y + " " + this._z;
213+
};
214+
215+
CSG.Vertex.prototype.toStlString = function() {
216+
return "vertex " + this.pos.toStlString() + "\n";
217+
};
218+
219+
CSG.Polygon.prototype.toStlString = function() {
220+
var result = "";
221+
if (this.vertices.length >= 3) // should be!
222+
{
223+
// STL requires triangular polygons. If our polygon has more vertices, create
224+
// multiple triangles:
225+
var firstVertexStl = this.vertices[0].toStlString();
226+
for (var i = 0; i < this.vertices.length - 2; i++) {
227+
result += "facet normal " + this.plane.normal.toStlString() + "\nouter loop\n";
228+
result += firstVertexStl;
229+
result += this.vertices[i + 1].toStlString();
230+
result += this.vertices[i + 2].toStlString();
231+
result += "endloop\nendfacet\n";
232+
}
233+
}
234+
return result;
235+
};
236+
237+
////////////////////////////////////////////
238+
// DXF Export
239+
////////////////////////////////////////////
240+
241+
CAG.PathsToDxf = function(paths) {
242+
var str = "999\nDXF generated by OpenJsCad\n";
243+
str += " 0\nSECTION\n 2\nHEADER\n";
244+
str += " 0\nENDSEC\n";
245+
str += " 0\nSECTION\n 2\nTABLES\n";
246+
str += " 0\nTABLE\n 2\nLTYPE\n 70\n1\n";
247+
str += " 0\nLTYPE\n 2\nCONTINUOUS\n 3\nSolid Line\n 72\n65\n 73\n0\n 40\n0.0\n";
248+
str += " 0\nENDTAB\n";
249+
str += " 0\nTABLE\n 2\nLAYER\n 70\n1\n";
250+
str += " 0\nLAYER\n 2\nOpenJsCad\n 62\n7\n 6\ncontinuous\n";
251+
str += " 0\nENDTAB\n";
252+
str += " 0\nTABLE\n 2\nSTYLE\n 70\n0\n 0\nENDTAB\n";
253+
str += " 0\nTABLE\n 2\nVIEW\n 70\n0\n 0\nENDTAB\n";
254+
str += " 0\nENDSEC\n";
255+
str += " 0\nSECTION\n 2\nBLOCKS\n";
256+
str += " 0\nENDSEC\n";
257+
str += " 0\nSECTION\n 2\nENTITIES\n";
258+
paths.map(function(path) {
259+
var numpoints_closed = path.points.length + (path.closed ? 1 : 0);
260+
str += " 0\nLWPOLYLINE\n 8\nOpenJsCad\n 90\n" + numpoints_closed + "\n 70\n" + (path.closed ? 1 : 0) + "\n";
261+
for (var pointindex = 0; pointindex < numpoints_closed; pointindex++) {
262+
var pointindexwrapped = pointindex;
263+
if (pointindexwrapped >= path.points.length) pointindexwrapped -= path.points.length;
264+
var point = path.points[pointindexwrapped];
265+
str += " 10\n" + point.x + "\n 20\n" + point.y + "\n 30\n0.0\n";
266+
}
267+
});
268+
str += " 0\nENDSEC\n 0\nEOF\n";
269+
return new Blob([str], {
270+
type: "application/dxf"
271+
});
272+
};
273+
274+
CAG.prototype.toDxf = function() {
275+
var paths = this.getOutlinePaths();
276+
return CAG.PathsToDxf(paths);
277+
};
278+
279+
////////////////////////////////////////////
280+
// AMF Export
281+
////////////////////////////////////////////
282+
283+
CSG.prototype.toAMFString = function(m) {
284+
var result = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<amf"+(m&&m.unit?" unit=\"+m.unit\"":"")+">\n";
285+
for(var k in m) {
286+
result += "<metadata type=\""+k+"\">"+m[k]+"</metadata>\n";
287+
}
288+
result += "<object id=\"0\">\n<mesh>\n<vertices>\n";
289+
290+
this.polygons.map(function(p) { // first we dump all vertices of all polygons
291+
for(var i=0; i<p.vertices.length; i++) {
292+
result += p.vertices[i].toAMFString();
293+
}
294+
});
295+
result += "</vertices>\n";
296+
297+
var n = 0;
298+
this.polygons.map(function(p) { // then we dump all polygons
299+
result += "<volume>\n";
300+
if(p.vertices.length<3)
301+
return;
302+
var r = 1, g = 0.4, b = 1, a = 1, colorSet = false;
303+
if(p.shared && p.shared.color) {
304+
r = p.shared.color[0];
305+
g = p.shared.color[1];
306+
b = p.shared.color[2];
307+
a = p.shared.color[3];
308+
colorSet = true;
309+
} else if(p.color) {
310+
r = p.color[0];
311+
g = p.color[1];
312+
b = p.color[2];
313+
if(p.color.length()>3) a = p.color[3];
314+
colorSet = true;
315+
}
316+
result += "<color><r>"+r+"</r><g>"+g+"</g><b>"+b+"</b>"+(a!==undefined?"<a>"+a+"</a>":"")+"</color>";
317+
318+
for(var i=0; i<p.vertices.length-2; i++) { // making sure they are all triangles (triangular polygons)
319+
result += "<triangle>";
320+
result += "<v1>" + (n) + "</v1>";
321+
result += "<v2>" + (n+i+1) + "</v2>";
322+
result += "<v3>" + (n+i+2) + "</v3>";
323+
result += "</triangle>\n";
324+
}
325+
n += p.vertices.length;
326+
result += "</volume>\n";
327+
});
328+
result += "</mesh>\n</object>\n";
329+
result += "</amf>\n";
330+
return result;
331+
};
332+
333+
CSG.Vector3D.prototype.toAMFString = function() {
334+
return "<x>" + this._x + "</x><y>" + this._y + "</y><z>" + this._z + "</z>";
335+
};
336+
337+
CSG.Vertex.prototype.toAMFString = function() {
338+
return "<vertex><coordinates>" + this.pos.toAMFString() + "</coordinates></vertex>\n";
339+
};
340+
File renamed without changes.

debug/viewer.css

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ body {
3030
right: 210px;
3131
overflow: hidden;
3232
}
33-
svg, .svg-zone, #export-zone {
33+
svg, .svg-zone {
3434
height: 100%;
3535
width: 100%;
3636
}
@@ -54,11 +54,6 @@ svg line, svg circle, svg path {
5454
svg text {
5555
fill: #0ff;
5656
}
57-
#export-zone {
58-
overflow: scroll;
59-
display: none;
60-
background-color: rgba(255,255,255,.9);
61-
}
6257
.optionpanel {
6358
position: fixed;
6459
left: 20px;

0 commit comments

Comments
 (0)