29th January 2011, 12:30 PM | #1 |
Junior Member
Junior member
Join Date: Nov 2008
Location: Pointe-Claire, Quebec, Canada
Posts: 9
|
Bill of material for woodworking
Hi,
Does someone have a script for creating a bill of material with dimensions ? I am using AC3D for woodworking projects. All my objects are "boxes" which translate to individual wood parts... From what I can read from the .ac file it seems simple enough, just don't know where to start if I am going to program my own... Thanks, Michel |
30th January 2011, 05:30 AM | #2 |
Administrator
Professional user
Join Date: Jun 2003
Posts: 4,565
|
Re: Bill of material for woodworking
Hi Michel,
If you use File->Export->Second Life Boxes, you'll get a file that contains one line per object. Each line contains the XYZ position of the global bounding box, followed by the width/height/depth of that box. Hopefully this is what you need. |
30th January 2011, 12:22 PM | #3 |
Junior Member
Junior member
Join Date: Nov 2008
Location: Pointe-Claire, Quebec, Canada
Posts: 9
|
Re: Bill of material for woodworking
I put this small jscript together yesterday.
I know it is very crude but it works for me, maybe someone else will find it useful... Code:
var fso = new ActiveXObject("Scripting.FileSystemObject"); var wss = new ActiveXObject("WScript.Shell"); var buffer = ""; var Polygones = new Array(); var polyIndex = 0; var inputFilename = "write_filename_here.ac"; var outputFilename = fso.GetBaseName(inputFilename) + ".txt"; var input = fso.OpenTextFile(inputFilename, 1); while (!input.AtEndOfStream) { var tokens = GetTokens(); switch (tokens[0]) { case "OBJECT": if (tokens[1] == "poly") { var name = "noname"; tokens = GetTokens(); if (tokens[0] == "name") { name = tokens[1]; } var p = new Polygon(name); Polygones[polyIndex] = p; } break; case "numvert": var p = Polygones[polyIndex]; for (var i=0; i < 8; i++) { p.SetCoordinates(GetTokens()); } p.CalcDimensions(); polyIndex++; break; } } input.Close(); Polygones.sort(CompareForPolygons); PrintBOM(); wss.Popup(buffer, 0, "AC3D Bill of Material"); function Polygon(name) { this.name = name; this.xs = new Array(8); this.ys = new Array(8); this.zs = new Array(8); this.xyzIndex = 0; this.dimensions = new Array(3); this.SetCoordinates = setCoordinates; this.CalcDimensions = calcDimensions; } function setCoordinates(tokens) { this.xs[this.xyzIndex] = tokens[0]; this.ys[this.xyzIndex] = tokens[1]; this.zs[this.xyzIndex] = tokens[2]; this.xyzIndex++; } function calcDimensions() { var minX = Math.min(this.xs[0], this.xs[1], this.xs[2], this.xs[3], this.xs[4], this.xs[5], this.xs[6], this.xs[7]); var maxX = Math.max(this.xs[0], this.xs[1], this.xs[2], this.xs[3], this.xs[4], this.xs[5], this.xs[6], this.xs[7]); var minY = Math.min(this.ys[0], this.ys[1], this.ys[2], this.ys[3], this.ys[4], this.ys[5], this.ys[6], this.ys[7]); var maxY = Math.max(this.ys[0], this.ys[1], this.ys[2], this.ys[3], this.ys[4], this.ys[5], this.ys[6], this.ys[7]); var minZ = Math.min(this.zs[0], this.zs[1], this.zs[2], this.zs[3], this.zs[4], this.zs[5], this.zs[6], this.zs[7]); var maxZ = Math.max(this.zs[0], this.zs[1], this.zs[2], this.zs[3], this.zs[4], this.zs[5], this.zs[6], this.zs[7]); this.dimensions[0] = maxX - minX; this.dimensions[1] = maxY - minY; this.dimensions[2] = maxZ - minZ; this.dimensions.sort(CompareForDimensions); } function CompareForDimensions(param1, param2) { var first = parseFloat(param1); var second = parseFloat(param2); if (first == second) return 0; if (first < second) return -1; else return 1; } function CompareForPolygons(param1, param2) { var result = 0; var firstD1 = parseFloat(param1.dimensions[0]); var firstD2 = parseFloat(param1.dimensions[1]); var secondD1 = parseFloat(param2.dimensions[0]); var secondD2 = parseFloat(param2.dimensions[1]); if ((firstD1 == secondD1) && (firstD2 == secondD2)) result = 0; if ((firstD1 < secondD1) || ((firstD1 == secondD1) && (firstD2 < secondD2))) result = -1; if ((firstD1 > secondD1) || ((firstD1 == secondD1) && (firstD2 > secondD2))) result = 1; return result; } function GetTokens() { var textLine = input.ReadLine(); return textLine.split(" "); } function print(Data) { buffer += Data + "\n"; } function PrintBOM() { var output = fso.CreateTextFile(outputFilename, true); for (i = 0; i < polyIndex; i++) { var txt = Polygones[i].name + " : " + Polygones[i].dimensions[0].toFixed(2) + " x " + Polygones[i].dimensions[1].toFixed(2) + " x " + Polygones[i].dimensions[2].toFixed(2); print(txt); output.WriteLine(txt); } output.Close(); } |
6th February 2011, 03:11 PM | #4 |
Junior Member
Junior member
Join Date: Nov 2008
Location: Pointe-Claire, Quebec, Canada
Posts: 9
|
Re: Bill of material for woodworking - New version
Here's a new version of the script.
It group items with same dimensions. Simply drag a ".ac" file on the script to run... Enjoy. Code:
// ================================================= // Generate parts list with dimwnsions from ac file. // // (c)2011 Michel Poirier // ================================================= var fso = new ActiveXObject("Scripting.FileSystemObject"); var Polygons = new Array(); var polyIndex = 0; if (WScript.Arguments.Unnamed.length == 0) { WScript.Echo("Drag AC3D file on script."); WScript.Quit(); } var inputFilename = WScript.Arguments.Unnamed.Item(0); var outputFilename = inputFilename.substr(0, inputFilename.lastIndexOf(".ac")) + ".txt"; var input = fso.OpenTextFile(inputFilename, 1); while (!input.AtEndOfStream) { var tokens = GetTokens(); switch (tokens[0]) { case "OBJECT": if (tokens[1] == "poly") { var name = "noname"; tokens = GetTokens(); if (tokens[0] == "name") { name = tokens[1]; } var p = new Polygon(name); Polygons[polyIndex] = p; } break; case "numvert": var p = Polygons[polyIndex]; for (var i=0; i < 8; i++) { p.SetCoordinates(GetTokens()); } p.CalcDimensions(); p.SortDimensions(); polyIndex++; break; } } input.Close(); Polygons.sort(ComparePolygons); PrintBOM(); WScript.Echo("Parts list writen to " + outputFilename); function Polygon(name) { this.name = name; this.xs = new Array(8); this.ys = new Array(8); this.zs = new Array(8); this.xyzIndex = 0; this.dimensions = new Array(3); this.SetCoordinates = setCoordinates; this.CalcDimensions = calcDimensions; this.SortDimensions = sortDimensions; } function setCoordinates(tokens) { this.xs[this.xyzIndex] = parseFloat(parseFloat(tokens[0]).toFixed(3)); this.ys[this.xyzIndex] = parseFloat(parseFloat(tokens[1]).toFixed(3)); this.zs[this.xyzIndex] = parseFloat(parseFloat(tokens[2]).toFixed(3)); this.xyzIndex++; } function calcDimensions() { var minX = Math.min(this.xs[0], this.xs[1], this.xs[2], this.xs[3], this.xs[4], this.xs[5], this.xs[6], this.xs[7]); var maxX = Math.max(this.xs[0], this.xs[1], this.xs[2], this.xs[3], this.xs[4], this.xs[5], this.xs[6], this.xs[7]); var minY = Math.min(this.ys[0], this.ys[1], this.ys[2], this.ys[3], this.ys[4], this.ys[5], this.ys[6], this.ys[7]); var maxY = Math.max(this.ys[0], this.ys[1], this.ys[2], this.ys[3], this.ys[4], this.ys[5], this.ys[6], this.ys[7]); var minZ = Math.min(this.zs[0], this.zs[1], this.zs[2], this.zs[3], this.zs[4], this.zs[5], this.zs[6], this.zs[7]); var maxZ = Math.max(this.zs[0], this.zs[1], this.zs[2], this.zs[3], this.zs[4], this.zs[5], this.zs[6], this.zs[7]); var dimX = maxX - minX; var dimY = maxY - minY; var dimZ = maxZ - minZ; this.dimensions[0] = parseFloat(dimX.toFixed(3)); this.dimensions[1] = parseFloat(dimY.toFixed(3)) this.dimensions[2] = parseFloat(dimZ.toFixed(3)) } function sortDimensions() { this.dimensions.sort(CompareDimensions); } function CompareDimensions(param1, param2) { var first = parseFloat(param1); var second = parseFloat(param2); var result = param1 - param2; return result; } function ComparePolygons(param1, param2) { var result = 0; var firstD1 = param1.dimensions[0]; var firstD2 = param1.dimensions[1]; var firstD3 = param1.dimensions[2]; var secondD1 = param2.dimensions[0]; var secondD2 = param2.dimensions[1]; var secondD3 = param2.dimensions[2]; switch (true) { case (firstD1 === secondD1) && (firstD2 === secondD2) && (firstD3 === secondD3): result = 0; break; case (firstD1 === secondD1) && (firstD2 === secondD2) && (firstD3 < secondD3): result = -1; break; case (firstD1 === secondD1) && (firstD2 < secondD2): result = -1; break; case (firstD1 < secondD1): result = -1; break; case (firstD1 === secondD1) && (firstD2 === secondD2) && (firstD3 > secondD3): result = 1; break; case (firstD1 === secondD1) && (firstD2 > secondD2): result = 1; break; case (firstD1 > secondD1): result = 1; break; } return result; } function GetTokens() { var textLine = input.ReadLine(); return textLine.split(" "); } function Item(qty, desc) { this.Qty = qty; this.Description = desc; } function GroupPolygones() { var list = new Array(); var i = -1; var p = 0; var q = 0; var oldItem = "old"; var newItem = "new"; while (p < Polygons.length) { newItem = Polygons[p].dimensions[0] + " x " + Polygons[p].dimensions[1] + " x " + Polygons[p].dimensions[2]; if (newItem == oldItem) { q++; list[i].Qty = q; } else { i++; q = 1; list[i] = new Item(q, newItem); oldItem = newItem; } p++; } return list; } function PrintBOM() { var bom = GroupPolygones(); var output = fso.CreateTextFile(outputFilename, true); output.WriteLine("AC3D Bill of Material"); output.WriteLine(); for (i = 0; i < bom.length; i++) { output.WriteLine(bom[i].Qty + " X " + bom[i].Description); } output.Close(); } |
12th February 2011, 10:37 AM | #5 |
Junior Member
Junior member
Join Date: Nov 2008
Location: Pointe-Claire, Quebec, Canada
Posts: 9
|
Re: Bill of material for woodworking
Here's a better version that will work with polygons with more than 6 surfaces, like odd shapes made of plywood... This script only outputs outer dimensions of parts.
The script will popup a regular "File Open" dialog or simply drag a AC3D file on the script itself. |
Tags |
scrip woodwork |
|
|