2016-06-06 1 views
0

그래서이 npm 패키지를 사용하고 있습니다 : node-stlJavaScript로 STL 파일의 테두리 상자를 계산하십시오

그리고 그 위대한 작품. 그러나 정규식 구문, 수학 및 기하학적 계산은 다소 혼란 스럽습니다. 특히 모두 동시에.

기본적으로 내가 성취하고자하는 것은 STL의 경계 상자를 계산하는 스크립트를 확장하는 것입니다.

여기에는 구문 분석되거나 읽히는 STL의 볼륨과 무게를 계산하는 주 파일이 있습니다.

var fs = require('fs'); 

// Vertex 
function Vertex (v1,v2,v3) { 
    this.v1 = Number(v1); 
    this.v2 = Number(v2); 
    this.v3 = Number(v3); 
} 

// Vertex Holder 
function VertexHolder (vertex1,vertex2,vertex3) { 
    this.vert1 = vertex1; 
    this.vert2 = vertex2; 
    this.vert3 = vertex3; 
} 

// transforming a Node.js Buffer into a V8 array buffer 
function _toArrayBuffer (buffer) { 
    var 
    ab = new ArrayBuffer(buffer.length), 
    view = new Uint8Array(ab); 

    for (var i = 0; i < buffer.length; ++i) { 
     view[i] = buffer[i]; 
    } 
    return ab; 
} 

// calculation of the triangle volume 
// source: http://stackoverflow.com/questions/6518404/how-do-i-calculate-the-volume-of-an-object-stored-in-stl-files 
function _triangleVolume (vertexHolder) { 
    var 
    v321 = Number(vertexHolder.vert3.v1 * vertexHolder.vert2.v2 * vertexHolder.vert1.v3), 
    v231 = Number(vertexHolder.vert2.v1 * vertexHolder.vert3.v2 * vertexHolder.vert1.v3), 
    v312 = Number(vertexHolder.vert3.v1 * vertexHolder.vert1.v2 * vertexHolder.vert2.v3), 
    v132 = Number(vertexHolder.vert1.v1 * vertexHolder.vert3.v2 * vertexHolder.vert2.v3), 
    v213 = Number(vertexHolder.vert2.v1 * vertexHolder.vert1.v2 * vertexHolder.vert3.v3), 
    v123 = Number(vertexHolder.vert1.v1 * vertexHolder.vert2.v2 * vertexHolder.vert3.v3); 
    return Number(1.0/6.0)*(-v321 + v231 + v312 - v132 - v213 + v123); 
} 

// parsing an STL ASCII string 
function _parseSTLString (stl) { 
    var totalVol = 0; 
    // yes, this is the regular expression, matching the vertexes 
    // it was kind of tricky but it is fast and does the job 
    var vertexes = stl.match(/facet\s+normal\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+outer\s+loop\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+endloop\s+endfacet/g); 

    vertexes.forEach(function (vert) { 
     var preVertexHolder = new VertexHolder(); 
     vert.match(/vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s/g).forEach(function (vertex, i) { 
      var tempVertex = vertex.replace('vertex', '').match(/[-+]?[0-9]*\.?[0-9]+/g); 
      var preVertex = new Vertex(tempVertex[0],tempVertex[1],tempVertex[2]); 
      preVertexHolder['vert'+(i+1)] = preVertex; 
     }); 
     var partVolume = _triangleVolume(preVertexHolder); 
     totalVol += Number(partVolume); 
    }) 

    var volumeTotal = Math.abs(totalVol)/1000; 
    return { 
     volume: volumeTotal,  // cubic cm 
     weight: volumeTotal * 1.04 // gm 
    } 
} 

// parsing an STL Binary File 
// (borrowed some code from here: https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/STLLoader.js) 
function _parseSTLBinary (buf) { 
    buf = _toArrayBuffer(buf); 

    var 
    headerLength = 80, 
    dataOffset  = 84, 
    faceLength  = 12*4 + 2, 
    le = true; // is little-endian 

    var 
    dvTriangleCount = new DataView(buf, headerLength, 4), 
    numTriangles = dvTriangleCount.getUint32(0, le), 
    totalVol  = 0; 

    for (var i = 0; i < numTriangles; i++) { 
     var 
     dv   = new DataView(buf, dataOffset + i*faceLength, faceLength), 
     normal  = new Vertex(dv.getFloat32(0, le), dv.getFloat32(4, le), dv.getFloat32(8, le)), 
     vertHolder = new VertexHolder(); 
     for(var v = 3; v < 12; v+=3) { 
      var vert = new Vertex(dv.getFloat32(v*4, le), dv.getFloat32((v+1)*4, le), dv.getFloat32((v+2)*4, le)); 
      vertHolder['vert'+(v/3)] = vert; 
     } 
     totalVol += _triangleVolume(vertHolder); 
    } 

    var volumeTotal = Math.abs(totalVol)/1000; 
    return { 
     volume: volumeTotal,  // cubic cm 
     weight: volumeTotal * 1.04 // gm 
    } 
} 

// NodeStl 
// ======= 
// > var stl = NodeStl(__dirname + '/myCool.stl'); 
// > console.log(stl.volume + 'cm^3'); 
// > console.log(stl.weight + 'gm'); 
function NodeStl (stlPath) { 
    var 
    buf = fs.readFileSync(stlPath), 
    isAscii = true; 

    for (var i=0, len=buf.length; i<len; i++) { 
     if (buf[i] > 127) { isAscii=false; break; } 
    } 

    if (isAscii) 
     return _parseSTLString(buf.toString()); 
    else 
     return _parseSTLBinary(buf); 
} 

module.exports = NodeStl; 

누구든지이 도움을받을 수 있다면 좋을 것입니다. 나는 그것이 단순한 것처럼 느낀다. 그냥 다른 방향 (x, y, z)의 최대/최소를 알아야하고 경계 상자를 계산할 수 있습니다.

그러나 x, y 및 z의 최대/최소값이 여기에 있는지 이해하지 못합니다. 아이디어가 있으면 대답하십시오.

답변

1

새로운 지점을 만들었습니다 https://github.com/johannesboyne/node-stl/tree/boundingbox 적용된 알고리즘이 작동하는지 확인해 주시겠습니까?

보다도, 요하네스

편집 : 분기가 안정 경우 -> 내가 v.0.1.0에 밀어 것입니다 작동합니다 (아직 0.0.1 왜 모르는)

+0

감사합니다 많이!! 이 stl 파일을 사용했습니다. http://www.thingiverse.com/thing:1607628 예를 들면 다음과 같습니다. X에서 6cm (길이) y를 4.5 cm (폭) Z에서 5cm (heigth) 그래서 : 큐라와 STL 파서 다른 온라인 사이트에서 나는 consistenly 다음 (I 선택한 추정 mm)를 가지고 상충되는 문제가있는 것 같아요. 마찬가지로 : http://www.thingiverse.com/thing:972317 센티미터로 : 7.62 x/7.62 y/13.6 z – Aman

+0

기본적으로 작동하지 않으므로 STL에서 적용 알고리즘과 다른 숫자를 알려줍니다. – Aman

+0

예! 미안 해요, 제 솔루션은 쓰레기 였어요! : D 나는 더 나은 해결책을 찾았습니다! 2 분! – johannesboyne

관련 문제