Go Back   AC3D Forums > Resources > AC3D Scripts and Mods
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Display Modes
Old 29th January 2011, 12:30 PM   #1
mpoirier
Junior Member
Junior member
 
mpoirier's Avatar
 
Join Date: Nov 2008
Location: Pointe-Claire, Quebec, Canada
Posts: 9
Question 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
mpoirier is offline   Reply With Quote
Old 30th January 2011, 05:30 AM   #2
Andy
Administrator
Professional user
 
Andy's Avatar
 
Join Date: Jun 2003
Posts: 4,563
Default 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.
Andy is offline   Reply With Quote
Old 30th January 2011, 12:22 PM   #3
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

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();
}
mpoirier is offline   Reply With Quote
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
Old 12th February 2011, 10:37 AM   #5
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

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.
Attached Files
File Type: zip bom25.zip (1.6 KB, 356 views)
mpoirier is offline   Reply With Quote
Reply

Tags
scrip woodwork

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT -4. The time now is 10:41 PM.


AC3D Forum
(C) Inivis Limited 2020