Mobile app version of vmapp.org
Login or Join
Karen819

: How can I automatically group each shape with the text inside it for a huge collection of rectangles? I have a .dwg (AutoCad file) map full of fields (rectangles) that I'm manipulating with

@Karen819

Posted in: #AdobeIllustrator #Autocad #IllustratorScripting

I have a .dwg (AutoCad file) map full of fields (rectangles) that I'm manipulating with Illustrator. Each rectangle has a text inside it that indicates its number. The problem is that there is no association between the rectangle and its number and that's what I'm trying to do. Also the order or drawing is not the same, when I check the layers.

Is there a way with Illustrator that can group each rectangle to the text inside it and this for all the fields? It is possible manually, but impossible to do it for every single field: about 40,000 rectangles.

I guess the approach should have something to do with "closeness" since it's the only data that tells us the correspondence between a rectangle and its number.

10.01% popularity Vote Up Vote Down


Login to follow query

More posts by @Karen819

1 Comments

Sorted by latest first Latest Oldest Best

 

@Angie364

There is a plugin that can help you do this. You can get it from here: www.wundes.com/JS4AI/index.php
Download the "GroupOverlappingObjects.js" to your Illustrator scripts folder.
It should be someplace like this on PC:

"C:Program FilesAdobeIllustrator CSPresetsScripts"

or Mac

"/Applications/Adobe Illustrator CC 2015/Presets/en_US/Scripts"

Open/reload Illustrator and select all the objects that you wish to group. Then go to:

File > Scripts > GroupOverlappingObjects

A dialog box should appear to tell you how many groups were created. Checking the layers box should show your newly grouped items.

I tested this in Illustrator CC 2015.

Contents of javascript (29/07/2015):

/////////////////////////////////////////////////////////////////
//Group Overlapping (Beta) -- CS, CS2, CS3
//>=--------------------------------------
//
// Groups all overlapping objects in selection into discreet groups.
// The definition for 'overlaping' is based on objects bounding boxes, not their actual geometry.
// Each new groups zOrder is determined by the depth of the front-most object in each group.
// There is no limit to the number of groups created.
// Any non-overlapping objects are ignored.
//
// Note: Currently, this is not very efficient code. It works well on small groups (less than 120 objects)
// and works faster on smaller groupings. Running this on a huge number of objects will likely crash illustrator.
// It serves my purposes, but test it's limits on your machine, and use at your own risk.
// On a 2.53GHz P4, a group of 100 objects took 20 seconds with 2 groups.
//
//
//>=--------------------------------------
// JS code (c) copyright: John Wundes ( john@wundes.com ) wundes.com //copyright full text here: www.wundes.com/js4ai/copyright.txt //////////////////////////////////////////////////////////////////

//this little section is just for testing
//the number of times each function is called.
var testmode = 0;
var t1=t2=t3=t4=t5=t6=t7=0;
var testmsg="";
//
//
//
var go=true;
if(selection.length>120){
go = confirm("You have selected "+selection.length+" objects. It is highly recommended that you select less than 120 objects at a time. Do you want to continue anyway?");

}
if(selection.length>1 && go == true){
var groups=0;
var slen = selection.length;
var hitList= new Array(slen);
var groupArr = new Array(slen);
// for each element in selection
for (var sx=0;sx<slen;sx++){
//t6++; //---------------------------------------------loop tracker
var tArr = new Array(0);
// for each element in selection (again)
for (var si=0;si<slen;si++){
//t7++; //-------------------------------------loop tracker
groupArr[sx] = tArr;
//note each object hits itself once.
if(hitTest(selection[sx],selection[si])){
groupArr[sx].push(selection[si]);
}
}
}

minimize(groupArr);
var zError = 0;
var gaLen = groupArr.length;
for(var each=0;each<gaLen;each++){
if(groupArr[each].length>1){
groupArr[each].sort(sortBy_zOrder);
}
if(zError==1){
alert("cannot read some objects zOrderPosition");
}
//alert("halftime");
for(var each =0;each<gaLen;each++){
t1++; //----------------------------------------------loop tracker
if(groupArr[each].length>1){
groups++;
groupAll(groupArr[each]);
}
}
//
//---all done with main code, now display statistics if you care...
//

testmsg="nObjects processed: "+t1+"nObjects grouped: "+t2+"nObjects ignored: "+(t1-t2);

if(testmode==1){
testmsg+="nn---testmode data---nhits compared: "+t5+"nfunction 'minimize' called: "+t3+
"nitems tested within 'minimize': "+t4;
"nelements: "+t6+
"nelements*elements: "+t7;
}

var x=0;

while(x<selection.length){

if(selection[x].name == "wundes_GO_group"){
selection[x].name = "";
}else{
selection[x].selected = false;
x--;
}
x++;
}
redraw();
alert(groups+" groups created.n----------------"+testmsg);
}


}
//----------------------------------------------------------->
//--------------------------------functions------------------<
//----------------------------------------------------------->
function sortBy_zOrder(a, b) {
if(a.zOrderPosition==undefined){
alert(a.zOrderPosition);
zError = 1;
return 0;
}
var x = Number(a.zOrderPosition);
var y = Number(b.zOrderPosition);


return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

function groupAll(arr){
var tempGroup = arr[0].parent.groupItems.add();

tempGroup.move(arr[0],ElementPlacement.PLACEBEFORE);
var max = arr.length;
for(var i=max-1;i>=0;i--){
t2++; //-----------------------------------------loop tracker
arr[i].move(tempGroup,ElementPlacement.INSIDE);
}
//name the object for selection at end... (will be removed later)
tempGroup.name = "wundes_GO_group";
tempGroup.selected = true;

}
//---------------hitTest functions ---------------
function hitTest(a,b){
var OK=0;
if(isWithinX(a,b) || isWithinX(b,a)){
OK++;
}
if(isWithinY(a,b) || isWithinY(b,a)){
OK++;
}
if (OK<2){
//alert("miss.");
return false;
}else{
//alert("Hit!")
return true;
}
}
function isWithinX(a,b){
var p1 = a.geometricBounds[0];
var p2 = b.geometricBounds[0];
if(p2<=p1 && p1<=p2+b.width){
return true;
}else{
return false;
}
}
function isWithinY(a,b){
var p3 = a.geometricBounds[1];
var p4 = b.geometricBounds[1];
if(p3>=p4 && p4>=(p3-a.height)){
return true;
}
return false;
}

/*
//-----------------------------------OK, finding groups is done, now do the grouping---------------
*/

function itemize(a){
var out="";
return(a.join("n"));
}
function minimize(arr){
for(var e in arr){
t3++; //-----------------------------------------loop tracker
for (ot in arr){
t4++; //-------------------------------------loop tracker
if(arr[e]!=arr[ot]){
//if it's not THIS element,
//test for overlaps
if(overlaps(arr[e],arr[ot])){
merge(arr[e],arr[ot]);
arr[e] = new Array(0);
minimize(arr);
break;
}
}
}
}

}
function merge(a,b){
var alen = a.length;
for (var all=0;all<alen;all++){
if(contains(b,a[all])){
//do nothing
}else{

b.push(a[all]);

}
}

}
function contains(ar,i){
for (var all in ar){
if (ar[all] == i){
return true;
}
}
return false;
}


function overlaps(ar1,ar2){
for (var each in ar1){
t5++; //------------------------------------loop tracker
if(contains(ar2,ar1[each])){//
return true;
}
}
return false;
}

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme