simple script to output selected object length?

Explorer ,
Nov 16, 2020

Copy link to clipboard

Copied

I make a lot of stencils that become .25" laser cut plates & I need a script to quickly calculate the surface area of the final 3D plate.

 

The total surface area of the 3D plate is: (Front Surface Area) + (Back Surface Area) + (Perimeter*Material Thickness.)

 

The script below will give me the Front + Back, so I'm half way there.

 

I just need help getting the script to output the value normally found in the "Document Info" pallete, under "Objects --> Length"

 

Can anyone assist?

 

Thanks!

/* Save this file with a jsx extension and place in your
Illustrator/Presets/en_US/Scripts folder. You can then
access it from the File > Scripts menu */

var decimalPlaces = 3;

if (app.documents.length > 0) {

	if (app.activeDocument.selection.length < 1) {
		alert('Select a path');
	} else if (app.activeDocument.selection[0].area) {
		// Individual Items
		var objects =  app.activeDocument.selection;
	} else if (app.activeDocument.selection[0].pathItems) {
		// Group/Compound Shape
		var objects = app.activeDocument.selection[0].pathItems;
	} else {
		alert('Please select a path or group.');
	}

	// Collect info
	var totalArea = 0;
	for (var i=0; i<objects.length; i++) {
		if (objects[i].area) {
			var totalArea = totalArea + objects[i].area;
		}
	}

	// Conversions
	var ppi = 72;
	var areaIn = totalArea / ppi / ppi;
	if (areaIn < 0) var areaIn = -areaIn;
	var areaCm = areaIn * 6.4516;
	
		// Display
	alert('Shape Area\n\
	' + areaIn.toFixed(decimalPlaces) + ' in² \
	' + areaIn.toFixed(decimalPlaces) * 2 + ' (in²)2 \n\
	' + areaCm.toFixed(decimalPlaces) + ' cm² \
	' + areaCm.toFixed(decimalPlaces) * 2 + ' (cm²)2 \n\
	' + i + ' shapes');

}

 

 

TOPICS
Feature request, Scripting

Views

134

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

2 Correct Answers

Explorer , Nov 17, 2020
justinleedero Explorer , Nov 17, 2020
This is probably my final update..I added this updated Notice to the header of the script: /* NOTICE: This tool only provides correct values whenthe selection is either a single manifold shape, or a singlemanifold compound shape, with no internal self-intersectinggeometry. Correct selection geometry will export to DXF,import to solidworks & extrude to materialThickness as asingle body, with identical output for area & other values.*/ updated code here:/* Save this file with a jsx extension and p...

Likes

Translate

Translate
Jump to answer Jump to answer
Explorer , Nov 17, 2020
justinleedero Explorer , Nov 17, 2020
Got it working!The script now outputs the 3D surface area for a selected compound path, along with some other useful data.I verified the values are correct by exporting a DXF, & creating a 3D model in solidworks.It would be nice to add a dialog so users can input a 3D Thickness value.  Most of the time I need .25" thickness so hard coded is fine for now. Here's the final code..  Enjoy!/* Save this file with a jsx extension and place in your Illustrator/Presets/en_US/Scripts folder. You can then ...

Likes

Translate

Translate
Jump to answer Jump to answer
Adobe Community Professional ,
Nov 16, 2020

Copy link to clipboard

Copied

to get the length of objects as shown in Document Info, use the length property

 

alert(selection[0].length);

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Explorer ,
Nov 17, 2020

Copy link to clipboard

Copied

Thanks for the quick reply. 

I tried adding your string to my alert output and all it returns is "undefined"

I also tried running it in a new script with no other fucntions.  Still only returns "undefined"

 

Here's a screenshot of the alert output:

shape area.JPG

 

& heres my updated code..   Let me know if you can help me get this going!

/* Save this file with a jsx extension and place in your
Illustrator/Presets/en_US/Scripts folder. You can then
access it from the File > Scripts menu */

var decimalPlaces = 3;

if (app.documents.length > 0) {

	if (app.activeDocument.selection.length < 1) {
		alert('Select a path');
	} else if (app.activeDocument.selection[0].area) {
		// Individual Items
		var objects =  app.activeDocument.selection;
	} else if (app.activeDocument.selection[0].pathItems) {
		// Group/Compound Shape
		var objects = app.activeDocument.selection[0].pathItems;
	} else {
		alert('Please select a path or group.');
	}

	// Collect info
	var totalArea = 0;
	for (var i=0; i<objects.length; i++) {
		if (objects[i].area) {
			var totalArea = totalArea + objects[i].area;
		}
	}

	// Conversions
	var ppi = 72;
	var areaIn = totalArea / ppi / ppi;
	if (areaIn < 0) var areaIn = -areaIn;
	var areaCm = areaIn * 6.4516;
	
		// Display
	alert('Shape Area\n\
	' + areaIn.toFixed(decimalPlaces) + ' in² \
	' + areaIn.toFixed(decimalPlaces) * 2 + ' (in²)2 \n\
	' + areaCm.toFixed(decimalPlaces) + ' cm² \
	' + areaCm.toFixed(decimalPlaces) * 2 + ' (cm²)2 \
	' + selection[0].length + ' Perimeter\n\
	' + i + ' shapes');

}

Thanks!

 

 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Adobe Community Professional ,
Nov 17, 2020

Copy link to clipboard

Copied

what kind of object is 

 

selection[0];

 

?

maybe add another line to your alert like this:

 

alert('Shape Area\n\
	' + areaIn.toFixed(decimalPlaces) + ' in² \
	' + areaIn.toFixed(decimalPlaces) * 2 + ' (in²)2 \n\
	' + areaCm.toFixed(decimalPlaces) + ' cm² \
	' + areaCm.toFixed(decimalPlaces) * 2 + ' (cm²)2 \
	' + selection[0].length + ' Perimeter\n\
	' + 'selection[0].typename = ' + selection[0].typename + '\n' \
	' + i + ' shapes');

 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Explorer ,
Nov 17, 2020

Copy link to clipboard

Copied

Thanks for the reply.

 

The object is a compound path, vectors for a laser cut logo plate.Capture1.JPG

 

Adding this line broke the script:

	' + 'selection[0].typename = ' + selection[0].typename + '\n' \

   error1.JPG

 

I am what is called extreme novice in javascript & I appreciate any additional guidance.

 

Thanks!

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Enthusiast ,
Nov 17, 2020

Copy link to clipboard

Copied

  • The line should be

 

' + 'selection[0].typename = ' + selection[0].typename + '\   

 

  • You're getting "undefined" because a compound path doesn't have a length property. 
  • At a quick glance, "length" of a compound path in Dcoument Info > Objects seems to be the sum of the lengths of the paths in a compound path.  Is that what you want?

 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Adobe Community Professional ,
Nov 17, 2020

Copy link to clipboard

Copied

I posted a generic sample usage. 

 

I think you have to apply it to one of your objects

 

objects[index].length; // you need to provide index

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Explorer ,
Nov 17, 2020

Copy link to clipboard

Copied

I appreciate your guidance & as stated above I am an extreme novice when it comes to scripting.

 

I am unclear what you mean when you say I "need to provide index".

 

can you explain further or show me how & where to insert the code objects[index].length; ?

 

The answer may be obvious to some & I appreaciate you taking the time to explain so I may better understand WTF I'm doing 🙂

 

Thanks again!

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Explorer ,
Nov 17, 2020

Copy link to clipboard

Copied

Got it working!

The script now outputs the 3D surface area for a selected compound path, along with some other useful data.

I verified the values are correct by exporting a DXF, & creating a 3D model in solidworks.

it works!.JPG

solidworks.JPG

It would be nice to add a dialog so users can input a 3D Thickness value.  Most of the time I need .25" thickness so hard coded is fine for now.

 

Here's the final code..  Enjoy!

/* Save this file with a jsx extension and place in your
Illustrator/Presets/en_US/Scripts folder. You can then
access it from the File > Scripts menu */

var decimalPlaces = 3;
var materialThickness = .25;

if (app.documents.length > 0) {

	if (app.activeDocument.selection.length < 1) {
		alert('Select a path');
	} else if (app.activeDocument.selection[0].area) {
		// Individual Items
		var objects =  app.activeDocument.selection;
	} else if (app.activeDocument.selection[0].pathItems) {
		// Group/Compound Shape
		var objects = app.activeDocument.selection[0].pathItems;
	} else {
		alert('Please select a path or group.');
	}

	// Collect area info
	var totalArea = 0;
	for (var i=0; i<objects.length; i++) {
		if (objects[i].area) {
			var totalArea = totalArea + objects[i].area;
		}
	}
	
	// Collect length info
	var totalLength = 0;
	for (var i=0; i<objects.length; i++) {
		if (objects[i].length) {
			var totalLength = totalLength + objects[i].length;
		}
	}

	// Area Conversions
	var ppi = 72;
	var areaIn = totalArea / ppi / ppi;
	if (areaIn < 0) var areaIn = -areaIn;
	var areaCm = areaIn * 6.4516;
	
	// Length Conversions
	var ppi = 72;
	var lengthIn = totalLength / ppi;
	if (lengthIn < 0) var lengthIn = -lengthIn;
	var lengthCm = lengthIn * 6.4516;
	
		// Display
	alert('3D Solid Surface Area Calculator\n\
	' + i + ' Shapes \n\
	' + areaIn.toFixed(decimalPlaces) + ' : Area in² \
	' + areaIn.toFixed(decimalPlaces) * 2 + ' : Area (in²)2 \n\
	' + lengthIn.toFixed(decimalPlaces) + ' : Perimeter Length(in) \
	' + (lengthIn * materialThickness).toFixed(decimalPlaces) + ' : Perimeter Area (in²) \n\
	' + materialThickness + ' : Material Thickness (in) \n\
	' + ((areaIn * 2) + (lengthIn * materialThickness)).toFixed(decimalPlaces) + ' : Total 3D Area (in²)');
	
	
	

}

 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Most Valuable Participant ,
Nov 17, 2020

Copy link to clipboard

Copied

Hi @justinleedero 

 

Attention.
Customers can create files that your script will not interpret properly.

Test file was created with Illu 24.2.1:

https://www.xup.in/dl,51474941/wrong_calculation_CC2020.ai/ 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Explorer ,
Nov 17, 2020

Copy link to clipboard

Copied

Thanks,  I wasnt able to access your test file. ¯\_(ツ)_/¯

 

I added the following notice to the script's header:

 

/* NOTICE: This tool only provides correct values when
the selection is either a single contiguous path, or a single
compound shape. If multiple shapes are selected the tool
will only ouput values for the top shape in the selection.*/

 

For my purposes the tool works perfectly because I am always working with single, manifold, compound shapes -- the type of shape Solidworks can cleanly import & extrude into 3D geometry.  

 

This hacked together script will only provide correct values for the top most object in the selection. If you have multiple shapes selected try creating a single compound shape

 

Its working for my needs & hope others can find it useful &/or adaptable! 

 

Here's my up to date code (output now also includes 3D volume totals as well).

Enjoy!

/* Save this file with a jsx extension and place in your
Illustrator/Presets/en_US/Scripts folder. You can then
access it from the File > Scripts menu */

/* NOTICE: This tool only provides correct values when
the selection is either a single contiguous path, or a single
compound shape. If multiple shapes are selected the tool
will only ouput values for the top shape in the selection.*/

var decimalPlaces = 3;
var materialThickness = .25;

if (app.documents.length > 0) {

	if (app.activeDocument.selection.length < 1) {
		alert('Select a path');
	} else if (app.activeDocument.selection[0].area) {
		// Individual Items
		var objects =  app.activeDocument.selection;
	} else if (app.activeDocument.selection[0].pathItems) {
		// Group/Compound Shape
		var objects = app.activeDocument.selection[0].pathItems;
	} else {
		alert('Please select a path or group.');
	}

	// Collect area info
	var totalArea = 0;
	for (var i=0; i<objects.length; i++) {
		if (objects[i].area) {
			var totalArea = totalArea + objects[i].area;
		}
	}
	
	// Collect length info
	var totalLength = 0;
	for (var i=0; i<objects.length; i++) {
		if (objects[i].length) {
			var totalLength = totalLength + objects[i].length;
		}
	}

	// Area Conversions
	var ppi = 72;
	var areaIn = totalArea / ppi / ppi;
	if (areaIn < 0) var areaIn = -areaIn;
	var areaCm = areaIn * 6.4516;
	
	// Length Conversions
	var ppi = 72;
	var lengthIn = totalLength / ppi;
	if (lengthIn < 0) var lengthIn = -lengthIn;
	var lengthCm = lengthIn * 6.4516;
	
		// Display
	alert('3D Solid Surface Area Calculator\n\
	' + i + ' Shapes \n\
	' + materialThickness + ' : Material Thickness (in) \n\
	' + areaIn.toFixed(decimalPlaces) + ' : Area in² \
	' + areaIn.toFixed(decimalPlaces) * 2 + ' : Area (in²)2 \n\
	' + lengthIn.toFixed(decimalPlaces) + ' : Perimeter Length(in) \
	' + (lengthIn * materialThickness).toFixed(decimalPlaces) + ' : Perimeter Area (in²) \n\
	' + (areaIn * materialThickness).toFixed(decimalPlaces) + ' : 3D Volume (in³)\n\
	' + ((areaIn * 2) + (lengthIn * materialThickness)).toFixed(decimalPlaces) + ' : Total Surface Area (in²)');
	
	
	

}

 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Most Valuable Participant ,
Nov 17, 2020

Copy link to clipboard

Copied

Ok. I see.

xup has now an Adblock adblocker.

 

Try this Dropbox link.

https://www.dropbox.com/s/uvqyuvyz2si9ckt/wrong_calculation_CC2020.ai?dl=0 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Explorer ,
Nov 17, 2020

Copy link to clipboard

Copied

Ok, I see your file is not a single manifold component.  The vectors intersect & so there are actually 2 manifold shapes here.

The script is only returning values for one of these shapes.

 

When I opened your file, I made zero changes & ran the script.  The output values do appear incorrect...

    test file 1.JPG

 

Next, I created a compound shape using this method:

Select all & click the "Unite" button in the Pathfinder Pallet...

unite.jpg

 

After using the "Unite" Command, I ran the script again & this time got the different output values.  This time the values were correct, but only for one of the objects in the selection (the one on the upper left), since there are actually 2 shapes here.

united.JPG

 

The problem with this perticular part is that its not mainfold.  If a laser were to follow these paths to cut a part from plate steel, you would end up with two parts (the upper left, & lower right.).   For this script to work correctly, there must be only 1 single manifold compound shape that would produce only a single manifold 3d component when imported & Extruded in solidworks.

 

When I eliminated one of the objects and ran the script, the correct values are returned, as verified in solidworks.

obj 1.JPGobj1a.JPG

 

 

In conculusion, this script only works on single manifold compound shapes with no internal self-intersecting lines that would result in multiple manifold objects in a real laser cutting situaion..

 

Enjoy!

 

 

 

 

...

 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Explorer ,
Nov 17, 2020

Copy link to clipboard

Copied

This is probably my final update..

I added this updated Notice to the header of the script:

 

/* NOTICE: This tool only provides correct values when
the selection is either a single manifold shape, or a single
manifold compound shape, with no internal self-intersecting
geometry. Correct selection geometry will export to DXF,
import to solidworks & extrude to materialThickness as a
single body, with identical output for area & other values.
*/

 

updated code here:

/* Save this file with a jsx extension and place in your
Illustrator/Presets/en_US/Scripts folder. You can then
access it from the File > Scripts menu */

/* NOTICE: This tool only provides correct values when
the selection is either a single manifold shape, or a single
manifold compound shape, with no internal self-intersecting
geometry. Correct selection geometry will export to DXF,
import to solidworks & extrude to materialThickness as a
single body, with identical output for area & other values.
*/

var decimalPlaces = 3;
var materialThickness = .25;

if (app.documents.length > 0) {

	if (app.activeDocument.selection.length < 1) {
		alert('Select a path');
	} else if (app.activeDocument.selection[0].area) {
		// Individual Items
		var objects =  app.activeDocument.selection;
	} else if (app.activeDocument.selection[0].pathItems) {
		// Group/Compound Shape
		var objects = app.activeDocument.selection[0].pathItems;
	} else {
		alert('Please select a path or group.');
	}

	// Collect area info
	var totalArea = 0;
	for (var i=0; i<objects.length; i++) {
		if (objects[i].area) {
			var totalArea = totalArea + objects[i].area;
		}
	}
	
	// Collect length info
	var totalLength = 0;
	for (var i=0; i<objects.length; i++) {
		if (objects[i].length) {
			var totalLength = totalLength + objects[i].length;
		}
	}

	// Area Conversions
	var ppi = 72;
	var areaIn = totalArea / ppi / ppi;
	if (areaIn < 0) var areaIn = -areaIn;
	var areaCm = areaIn * 6.4516;
	
	// Length Conversions
	var ppi = 72;
	var lengthIn = totalLength / ppi;
	if (lengthIn < 0) var lengthIn = -lengthIn;
	var lengthCm = lengthIn * 6.4516;
	
		// Display
	alert('3D Solid Surface Area Calculator\n\
	' + i + ' Shapes \n\
	' + materialThickness + ' : Material Thickness (in) \n\
	' + areaIn.toFixed(decimalPlaces) + ' : Area in² \
	' + areaIn.toFixed(decimalPlaces) * 2 + ' : Area (in²)2 \n\
	' + lengthIn.toFixed(decimalPlaces) + ' : Perimeter Length(in) \
	' + (lengthIn * materialThickness).toFixed(decimalPlaces) + ' : Perimeter Area (in²) \n\
	' + (areaIn * materialThickness).toFixed(decimalPlaces) + ' : 3D Volume (in³)\n\
	' + ((areaIn * 2) + (lengthIn * materialThickness)).toFixed(decimalPlaces) + ' : Total Surface Area (in²)');
	
	
	

}

 

 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Most Valuable Participant ,
Nov 17, 2020

Copy link to clipboard

Copied

Everything is fine - when you know what you are doing.

And I think you know what you do.

😉

(I do a similar thing at work - we produce CNC-engraved hot stamping tools, but mostly with extremely complex motifs)

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Explorer ,
Nov 17, 2020

Copy link to clipboard

Copied

If I actually knew what I was doing in JS, I would add logic to:

A: Create a dialog for user input of the materialThickness variable.

B: Add logic to detect whether the selected geometry is a manifold.

 

This was a fun little project.. Glad it worked out & hope everyone enjoys!

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Most Valuable Participant ,
Nov 18, 2020

Copy link to clipboard

Copied

A: is easy. There is no need to create a dialog. A simple prompt() is enough.

Replace your line:

var materialThickness = .25;

with:

var materialThickness = prompt ("Insert the material thickness", 0.25, "Material thickness");
if (materialThickness != null && isNaN (materialThickness*1) == false) {
    materialThickness = materialThickness*1;
    };

 

Your point B:

I never tried to detect such things.

Sorry

 

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Most Valuable Participant ,
Nov 22, 2020

Copy link to clipboard

Copied

Today I found this property and I think it would be helpful for your needs:

compoundPath.pathItems[0].polarity

compoundPath.pathItems[1].polarity

and so on …

Likes

Translate

Translate

Report

Report
Reply
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more