Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:

  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

How can I make an array of points created by a for loop in featurescript?

emory_krallemory_krall Member Posts: 15 PRO
edited September 12 in Community Support
for (var i = 0; i < numberOfDowels; i += 1)
        {
            opPoint(context, id + ("locationPoint" ~ i), {
                        "point" : toWorld(cSys, vector((fenceDistance + (dowelSpacing * i)), 0 * inch, 0 * inch))
                    });
        }
        var locationPoints is array = evaluateQuery(context, qCreatedBy(id + ("locationPoint" ~ i), EntityType.BODY));

This gives me an error that the variable "i" is not found. If place the variable declaration within the for loop I can't reference it outside the loop, which is what I need to do.



Best Answer

Answers

  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 2,400
    i does not exist once outside the curly braces of the for loop. There are a number of ways you can do this, but it all depends on the rest of the script.

    This is the most elegant way but may fall down if you have other similar loops in your code (due to id hierarchy):
    for (var i = 0; i < numberOfDowels; i += 1)
    {
        opPoint(context, id + i + "locationPoint", {                        
            "point" : toWorld(cSys, vector((fenceDistance + (dowelSpacing * i)), 0 * inch, 0 * inch))
        });
    }
    
    var locationPoints is array = evaluateQuery(context, qCreatedBy(id + ANY_ID + "locationPoint", EntityType.BODY));
    Neil Cooke, Director of Technical Marketing, Onshape Inc.
  • emory_krallemory_krall Member Posts: 15 PRO
    Is "ANY_ID" meant to be used literally? When I try this I get the error "Typecheck canBeId failed"
  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 2,400
    Yes, ANY_ID is a wildcard. Make sure it is spelled out exactly as above. I think you may be safer using the second method.
    Neil Cooke, Director of Technical Marketing, Onshape Inc.
  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 2,400
    Id hierarchy is a little difficult to follow: https://cad.onshape.com/FsDoc/library.html#Id
    Neil Cooke, Director of Technical Marketing, Onshape Inc.
  • emory_krallemory_krall Member Posts: 15 PRO
    Thanks Neil, your second suggestion appears to work for me!
  • emory_krallemory_krall Member Posts: 15 PRO
    There is a typo in the code: "EntityType.Body" should be "EntityType.BODY"
  • NeilCookeNeilCooke Moderator, Onshape Employees Posts: 2,400
    edited September 12
    Yeah, sorry - I hand-typed it from memory. I've edited the post above for anybody else that might copy it.
    Neil Cooke, Director of Technical Marketing, Onshape Inc.
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,380
    I would do this like this:
    const parentId = id + "points";
    for (var i = 0; ...)
    {
        opPoint(context, parentId + toString(i), {...});
    }
    const locationPoints = evauateQuery(context, qCreatedBy(parentId, EntityType.BODY));

    Since ids are hierarchical, if you nest a bunch of child ids under a parent, you can just evaluate a query on the entire parent, and the query will be evaluated for the entire group of ids contained by the parent.

    Note that:
    id + ("points" ~ i)
    creates ids that are like this "rootId > points0" "rootId > points1" "rootId > points2" (where the > is representing the transition of one id component to the next)

    but:
    (id + "points") + toString(i)
    // which is equivalent to:
    const parentId = id + "points";
    parentId + toString(i)
    creates ids that are like this "rootId > points > 0" "rootId > points > 1" "rootId > points > 2".  Then, because the ids are structured in a nice way, you can just do evaluations on parentId ("rootId > points"), and it will capture all of the ids which are children of that.
    Jake Rosenfeld - Modeling Team
Sign In or Register to comment.