We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Is there a way of naming a PShape child?
I can't see anything in a PShape constructor or in PShape methods, but I may be missing something about how shape parameters work -- given that there is a way of retrieving a child by name it seems like there must be a way of naming.
For example, you can use getChild(String target) e.g. getChild("OH")
to retrieve a child by its name. However neither addChild()
nor createShape()
appear to give a way of supplying that name in the first place. How is it done?
I provided a working example below. Child name lookup is particularly convenient in coding using removeChild()
(not shown here) as the index numbers shift when a child is removed.
/**
* How to name a PShape child?
* 2016-09-06
*
* example adapted from processing.org/reference/PShape_addChild_.html
*/
PShape group;
PShape child;
PShape searchIndex;
PShape searchName;
void setup() {
size(200,200);
//// Make a group PShape
group = createShape(GROUP);
println("Group shape = ", group);
//// Make a child shape
child = createShape();
child.beginShape();
child.vertex(-20, -20);
child.vertex(0, -40);
child.vertex(20, -20);
child.endShape();
//// Add child to group
//// HOW TO SPECIFY A NAME?
group.addChild(child);
//// Get child by index
searchIndex = group.getChild(0);
println("Child index search = ", searchIndex);
//// Get child by name
//// see for example: https://processing.org/reference/PShape_getChild_.html
//// ohio = states.getChild("OH");
//// NO NAME SO RETURNS NULL
searchName = group.getChild("");
println("Child name search = ", searchName);
}
void draw() {
background(52);
if(group!=null){
shape(group, width*1/5, height/2);
shape(group.getChild(0), width*2/5, height/2);
}
if(searchIndex!=null){
shape(searchIndex, width*3/5, height/2);
}
if(searchName!=null){
//// NOT CALLED WITHOUT NAME LOOKUP
shape(searchName, width*4/5, height/2);
}
}
Any advice on how to name a child? Sorry if this is obvious and I'm just not finding it.
Answers
I think maybe PShape is a class that is trying to be two things at once. In one mode you can use it to load svg files, and these can contain named children. And in another mode you can use it to store groups of shapes, which it calls children, but you can't name these. getChild by name will work with svg mode, not the other mode.
(We saw someone having a similar but opposite problem yesterday - was using svg mode and trying to get a list of the vertices, which only works in vertices mode)
(In guessing the states in the original example came from an svg file, which is why that worked)
koogs, this observation about svg loading was very helpful. I was confused because I incorrectly assumed that you could name children -- that name metadata could be directly attached to an indexed PShape child (in particular because removeChild() changes the indexes of subsequent children). It looks like that isn't why PShape naming exists or how it works.
PShape
shape
keeps two unsynced lists of subshapes:addChild()
index (int)addName()
hashmap (String).Subshapes can be both indexed children and named or just indexed, or just named.
shape()
.If you
removeChild()
a subshape will still be listed by name. There is noremoveName()
, and there doesn't appear to be a way to remove a name except by deleting the PShape entirely and creating a new one.I've put together a demo here that shows this in action:
So -- there ARE ways to manage named shapes in a created group PShape, although looks like this functionality was really intended for SVG data (named objects need to be added to the children index separately, can't be removed, ect.) Still, interesting. Especially given that PShape doesn't have methods like removeVector() and doesn't have copy(), using child shapes (even a single child shape per group object) is one workaround if you want to create persistent shape objects that are editable in Processing.