View Single Post
Old 6th February 2011, 03:11 PM   #4
mpoirier
Junior Member
Junior member
 
mpoirier's Avatar
 
Join Date: Nov 2008
Location: Pointe-Claire, Quebec, Canada
Posts: 9
Default 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();
}
mpoirier is offline   Reply With Quote