Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@jscad/amf-serializer

Package Overview
Dependencies
Maintainers
2
Versions
52
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jscad/amf-serializer - npm Package Compare versions

Comparing version 0.1.1 to 1.0.0-pre-V2.0

212

index.js

@@ -1,72 +0,182 @@

const { ensureManifoldness } = require('@jscad/io-utils')
/*
JSCAD Object to AMF (XML) Format Serialization
## License
Copyright (c) 2018 JSCAD Organization https://github.com/jscad
All code released under MIT license
Notes:
1) CAG conversion to:
none
2) CSG conversion to:
mesh
3) Path2D conversion to:
none
TBD
1) support zip output
*/
const {isCSG} = require('@jscad/csg')
const {ensureManifoldness} = require('@jscad/io-utils')
const {toArray} = require('@jscad/io-utils/arrays')
const stringify = require('onml/lib/stringify')
const mimeType = 'application/amf+xml'
function serialize (CSG, m, options) {
options && options.statusCallback && options.statusCallback({progress: 0})
CSG = ensureManifoldness(CSG)
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'
/** Serialize the give objects to AMF (xml) format.
* @param {Object} [options] - options for serialization
* @param {Object|Array} objects - objects to serialize as AMF
* @returns {Array} serialized contents, AMF format
*/
const serialize = (...params) => {
let options = {}
let objects
if (params.length === 0) {
throw new Error('no arguments supplied to serialize function !')
} else if (params.length === 1) {
// assumed to be object(s)
objects = Array.isArray(params[0]) ? params[0] : params
} else if (params.length > 1) {
options = params[0]
objects = params[1]
}
result += '<object id="0">\n<mesh>\n<vertices>\n'
// make sure we always deal with arrays of objects as inputs
objects = toArray(objects)
CSG.polygons.map(function (p) { // first we dump all vertices of all polygons
for (var i = 0; i < p.vertices.length; i++) {
result += CSGVertextoAMFString(p.vertices[i])
const defaults = {
statusCallback: null,
unit: 'millimeter', // millimeter, inch, feet, meter or micrometer
metadata: null
}
options = Object.assign({}, defaults, options)
options.statusCallback && options.statusCallback({progress: 0})
// construct the contents of the XML
var body = ['amf',
{
unit: options.unit,
version: '1.1'
},
['metadata', {type: 'author'}, 'Created using JSCAD']
]
body = body.concat(translateObjects(objects, options))
// convert the contents to AMF (XML) format
var amf = `<?xml version="1.0" encoding="UTF-8"?>
${stringify(body)}`
options && options.statusCallback && options.statusCallback({progress: 100})
return [amf]
}
const translateObjects = (objects, options) => {
let contents = []
objects.forEach(function (object, i) {
if (isCSG(object) && object.polygons.length > 0) {
object = ensureManifoldness(object)
options.id = i
contents.push(convertCSG(object, options))
}
})
result += '</vertices>\n'
return contents
}
var n = 0
CSG.polygons.map(function (p, i) { // then we dump all polygons
result += '<volume>\n'
if (p.vertices.length < 3) {
return
}
var color = null
if (p.shared && p.shared.color) {
color = p.shared.color
} else if (p.color) {
color = p.color
}
if (color != null) {
if (color.length < 4) color.push(1.0)
result += '<color><r>' + color[0] + '</r><g>' + color[1] + '</g><b>' + color[2] + '</b><a>' + color[3] + '</a></color>'
}
const convertCSG = (object, options) => {
var contents = ['object', {id: options.id}, convertToMesh(object, options)]
return contents
}
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'
const convertToMesh = (object, options) => {
var contents = ['mesh', {}, convertToVertices(object, options)]
contents = contents.concat(convertToVolumes(object, options))
return contents
}
/*
* This section converts each CSG object to a list of vertex / coordinates
*/
const convertToVertices = (object, options) => {
var contents = ['vertices', {}]
let vertices = []
object.polygons.forEach(function (polygon) {
for (let i = 0; i < polygon.vertices.length; i++) {
vertices.push(convertToVertex(polygon.vertices[i], options))
}
n += p.vertices.length
result += '</volume>\n'
options && options.statusCallback && options.statusCallback({progress: 100 * i / CSG.polygons.length})
})
result += '</mesh>\n</object>\n'
result += '</amf>\n'
options && options.statusCallback && options.statusCallback({progress: 100})
return contents.concat(vertices)
}
return [result]
const convertToVertex = (vertex, options) => {
let contents = ['vertex', {}, convertToCoordinates(vertex, options)]
return contents
}
function CSGVectortoAMFString (v) {
return '<x>' + v._x + '</x><y>' + v._y + '</y><z>' + v._z + '</z>'
const convertToCoordinates = (vertex, options) => {
let position = vertex.pos
let contents = ['coordinates', {}, ['x', {}, position._x], ['y', {}, position._y], ['z', {}, position._z]]
return contents
}
function CSGVertextoAMFString (vertex) {
return '<vertex><coordinates>' + CSGVectortoAMFString(vertex.pos) + '</coordinates></vertex>\n'
}
/*
CSG.Vector3D.prototype.toAMFString = function () {
return '<x>' + this._x + '</x><y>' + this._y + '</y><z>' + this._z + '</z>'
* This section converts each CSG object to a list of volumes consisting of indexes into the list of vertices
*/
const convertToVolumes = (object, options) => {
let contents = []
let n = 0
object.polygons.forEach(function (polygon) {
if (polygon.vertices.length < 3) {
return
}
let volume = ['volume', {}]
let color = convertToColor(polygon, options)
let triangles = convertToTriangles(polygon, n)
if (color) {
volume.push(color)
}
volume = volume.concat(triangles)
contents.push(volume)
n += polygon.vertices.length
})
return contents
}
CSG.Vertex.prototype.toAMFString = function () {
return '<vertex><coordinates>' + this.pos.toAMFString() + '</coordinates></vertex>\n'
} */
const convertToColor = (polygon, options) => {
let color = null
if (polygon.shared && polygon.shared.color) {
color = polygon.shared.color
} else if (polygon.color) {
color = polygon.color
}
if (color != null) {
if (color.length < 4) color.push(1.0)
return ['color', {}, ['r', {}, color[0]], ['g', {}, color[1]], ['b', {}, color[2]], ['a', {}, color[3]]]
}
return null
}
const convertToTriangles = (polygon, index) => {
let contents = []
// making sure they are all triangles (triangular polygons)
for (var i = 0; i < polygon.vertices.length - 2; i++) {
let triangle = ['triangle', {}, ['v1', {}, index], ['v2', {}, (index + i + 1)], ['v3', {}, (index + i + 2)]]
contents.push(triangle)
}
return contents
}
module.exports = {

@@ -73,0 +183,0 @@ serialize,

{
"name": "@jscad/amf-serializer",
"version": "0.1.1",
"version": "1.0.0-pre-V2.0",
"description": "Amf serializer for jscad project",

@@ -8,3 +8,3 @@ "repository": "https://github.com/jscad/io",

"scripts": {
"test": "ava './test.js' --verbose --timeout 10000",
"test": "ava './test.js' --verbose --timeout 20000",
"release-patch": "git checkout master && npm version patch && git commit -a -m 'chore(dist): built dist/'; git push origin master --tags ",

@@ -37,9 +37,9 @@ "release-minor": "git checkout master && npm version minor && git commit -a -m 'chore(dist): built dist/'; git push origin master --tags ",

"dependencies": {
"@jscad/io-utils": "^0.1.2",
"sax": "^1.2.1",
"xmldom": "^0.1.27"
"@jscad/csg": "^0.5.3",
"@jscad/io-utils": "^1.0.0-pre-V2.0",
"onml": "^0.4.1"
},
"devDependencies": {
"@jscad/csg": "0.3.6"
"ava": "^0.19.1"
}
}

@@ -6,7 +6,565 @@ const test = require('ava')

test('serialize csg to amf', function (t) {
const input = new CSG.cube()
const expected = [ '<?xml version="1.0" encoding="UTF-8"?>\n<amf>\n<object id="0">\n<mesh>\n<vertices>\n<vertex><coordinates><x>-1</x><y>-1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>-1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>-1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>-1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>-1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>-1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>-1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>-1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>-1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>-1</y><z>-1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>-1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>-1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>1</x><y>1</y><z>1</z></coordinates></vertex>\n<vertex><coordinates><x>-1</x><y>1</y><z>1</z></coordinates></vertex>\n</vertices>\n<volume>\n<triangle><v1>0</v1><v2>1</v2><v3>2</v3></triangle>\n<triangle><v1>0</v1><v2>2</v2><v3>3</v3></triangle>\n</volume>\n<volume>\n<triangle><v1>4</v1><v2>5</v2><v3>6</v3></triangle>\n<triangle><v1>4</v1><v2>6</v2><v3>7</v3></triangle>\n</volume>\n<volume>\n<triangle><v1>8</v1><v2>9</v2><v3>10</v3></triangle>\n<triangle><v1>8</v1><v2>10</v2><v3>11</v3></triangle>\n</volume>\n<volume>\n<triangle><v1>12</v1><v2>13</v2><v3>14</v3></triangle>\n<triangle><v1>12</v1><v2>14</v2><v3>15</v3></triangle>\n</volume>\n<volume>\n<triangle><v1>16</v1><v2>17</v2><v3>18</v3></triangle>\n<triangle><v1>16</v1><v2>18</v2><v3>19</v3></triangle>\n</volume>\n<volume>\n<triangle><v1>20</v1><v2>21</v2><v3>22</v3></triangle>\n<triangle><v1>20</v1><v2>22</v2><v3>23</v3></triangle>\n</volume>\n</mesh>\n</object>\n</amf>\n' ]
const observed = serializer.serialize(input)
const emptyShape = new CSG()
const observed1 = serializer.serialize({}, emptyShape)
t.deepEqual(observed1, expected1)
t.deepEqual(observed, expected)
const testCube = new CSG.cube()
const observed2 = serializer.serialize(testCube)
t.deepEqual(observed2, expected2)
const coloredCube = testCube.setColor([1.0, 0.0, 0.5, 0.8])
const observed3 = serializer.serialize({unit: 'inch'}, coloredCube)
t.deepEqual(observed3, expected3)
})
const expected1 = [
`<?xml version="1.0" encoding="UTF-8"?>
<amf unit=\"millimeter\" version=\"1.1\">
<metadata type=\"author\">Created using JSCAD</metadata>
</amf>
`
]
const expected2 = [
`<?xml version="1.0" encoding="UTF-8"?>
<amf unit=\"millimeter\" version=\"1.1\">
<metadata type=\"author\">Created using JSCAD</metadata>
<object id="0">
<mesh>
<vertices>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
</vertices>
<volume>
<triangle>
<v1>0</v1>
<v2>1</v2>
<v3>2</v3>
</triangle>
<triangle>
<v1>0</v1>
<v2>2</v2>
<v3>3</v3>
</triangle>
</volume>
<volume>
<triangle>
<v1>4</v1>
<v2>5</v2>
<v3>6</v3>
</triangle>
<triangle>
<v1>4</v1>
<v2>6</v2>
<v3>7</v3>
</triangle>
</volume>
<volume>
<triangle>
<v1>8</v1>
<v2>9</v2>
<v3>10</v3>
</triangle>
<triangle>
<v1>8</v1>
<v2>10</v2>
<v3>11</v3>
</triangle>
</volume>
<volume>
<triangle>
<v1>12</v1>
<v2>13</v2>
<v3>14</v3>
</triangle>
<triangle>
<v1>12</v1>
<v2>14</v2>
<v3>15</v3>
</triangle>
</volume>
<volume>
<triangle>
<v1>16</v1>
<v2>17</v2>
<v3>18</v3>
</triangle>
<triangle>
<v1>16</v1>
<v2>18</v2>
<v3>19</v3>
</triangle>
</volume>
<volume>
<triangle>
<v1>20</v1>
<v2>21</v2>
<v3>22</v3>
</triangle>
<triangle>
<v1>20</v1>
<v2>22</v2>
<v3>23</v3>
</triangle>
</volume>
</mesh>
</object>
</amf>
`
]
const expected3 = [
`<?xml version="1.0" encoding="UTF-8"?>
<amf unit=\"inch\" version=\"1.1\">
<metadata type=\"author\">Created using JSCAD</metadata>
<object id="0">
<mesh>
<vertices>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>-1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>-1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
<vertex>
<coordinates>
<x>-1</x>
<y>1</y>
<z>1</z>
</coordinates>
</vertex>
</vertices>
<volume>
<color>
<r>1</r>
<g>0</g>
<b>0.5</b>
<a>0.8</a>
</color>
<triangle>
<v1>0</v1>
<v2>1</v2>
<v3>2</v3>
</triangle>
<triangle>
<v1>0</v1>
<v2>2</v2>
<v3>3</v3>
</triangle>
</volume>
<volume>
<color>
<r>1</r>
<g>0</g>
<b>0.5</b>
<a>0.8</a>
</color>
<triangle>
<v1>4</v1>
<v2>5</v2>
<v3>6</v3>
</triangle>
<triangle>
<v1>4</v1>
<v2>6</v2>
<v3>7</v3>
</triangle>
</volume>
<volume>
<color>
<r>1</r>
<g>0</g>
<b>0.5</b>
<a>0.8</a>
</color>
<triangle>
<v1>8</v1>
<v2>9</v2>
<v3>10</v3>
</triangle>
<triangle>
<v1>8</v1>
<v2>10</v2>
<v3>11</v3>
</triangle>
</volume>
<volume>
<color>
<r>1</r>
<g>0</g>
<b>0.5</b>
<a>0.8</a>
</color>
<triangle>
<v1>12</v1>
<v2>13</v2>
<v3>14</v3>
</triangle>
<triangle>
<v1>12</v1>
<v2>14</v2>
<v3>15</v3>
</triangle>
</volume>
<volume>
<color>
<r>1</r>
<g>0</g>
<b>0.5</b>
<a>0.8</a>
</color>
<triangle>
<v1>16</v1>
<v2>17</v2>
<v3>18</v3>
</triangle>
<triangle>
<v1>16</v1>
<v2>18</v2>
<v3>19</v3>
</triangle>
</volume>
<volume>
<color>
<r>1</r>
<g>0</g>
<b>0.5</b>
<a>0.8</a>
</color>
<triangle>
<v1>20</v1>
<v2>21</v2>
<v3>22</v3>
</triangle>
<triangle>
<v1>20</v1>
<v2>22</v2>
<v3>23</v3>
</triangle>
</volume>
</mesh>
</object>
</amf>
`
]
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc