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.

Options

Featurescript. Create a record of edges vs solid bodies.

Alex_PittAlex_Pitt Member Posts: 60 PRO
edited April 7 in Community Support
Can the keys in a map be edges? And can the corresponding value in the map be a Solid Body? (I know that Arrays can contain Solid Bodies.)  I want to create a record (whether it's a map or an array)  that links an edge to a body. So Edge1 belongs to SolidBody1, Edge2 belongs to SolidBody2, Edge3, belongs to SolidBody3 etc. 

I want my feature to do the following:  The user selects some solid bodies (parts) and then some edges. It sorts out which edges belong to what parts and then moves each part along its associated selected edge (spacial translation, distance given by the length of the edge). Sounds pointless I know, but it's a stepping stone for something more useful.
Tagged:

Answers

  • Options
    NeilCookeNeilCooke Moderator, Onshape Employees Posts: 5,417
    Well, in theory you could, since an evaluated query returns a string, however it is not best practice since the returned query is "transient" and upstream features could easily break your feature because the returned transient query may be different. It may work but I wouldn't recommend.

    To sort which selected edges belong to which bodies, you could get all the edges of a body then qIntersect it with your selected edge.
    Senior Director, Technical Services, EMEAI
  • Options
    Alex_PittAlex_Pitt Member Posts: 60 PRO
    Thanks Neil. I will approach maps with caution then, as I'm still at a basic level. So if I fill my map with an evaluated query, it's all strings? I didn't want to use strings, but only solid bodies and edges to fill my map.  Maybe I'll use two Arrays instead; one for the bodies and another for the edges. I did an initial test which simply moved (opTransform'ed) the selected bodies. (I've pasted the body of the script below ) This seemed to work as hoped, allowing me to store the selected solid bodies in an array.
    (Although I am using an evaluated query to fill the array. Maybe it's filling the array with strings to represent each body. I will press on. )

    ____________
    var bodyArray = [];
                for (var part in evaluateQuery(context, definition.whichBodies))
         {
           bodyArray = append(bodyArray,part);
          }
       var bodyArraySize = size(bodyArray);
            
            for(var i = 0; i < bodyArraySize; i+=1)
      { 
      opTransform(context, id + i + "transform1", {
       "bodies" : bodyArray[i],
       "transform" : transform(vector(0, 0, i+1) * 2*inch)
       });
      }

    ______________
    Also, Konst_Sh posted this answer this morning.

    @Alex_Pitt There is a query constructor that creates the subset of entities owned by specified body query: https://cad.onshape.com/FsDoc/library.html#qOwnedByBody-Query-Query
    So edgesOwnedByBody1 = qOwnedByBody(allEdges, queryOfBody1);


  • Options
    Alex_PittAlex_Pitt Member Posts: 60 PRO
    edited April 7
    @konstantin_shiriazdanov Due to a lack of experience, I'm struggling with "qOwnedByBody" as both of its arguments are queries and it returns a query.  I don't have a query for an individual body as my precondition allows the selection of multiple parts. In which case, it will return a bunch of bodies in no particular order, is that right? 

    In the body of the script, I've put my picked bodies into one array and my picked edges in another, so that there's a definite order.

    The hope is to use "for loops" working through the bodies one by one to reorder the edge array to correspond with the body array, to finish with EdgeArray[0] owned by BodyArray[0], EdgeArray[1] owned by BodyArray[1] etc. If no edges have been picked for a particular body, then a "flag" value will be placed in that position of the EdgeArray. If 2 or more edges have been picked for a single body, then one edge only is "chosen" and the others discarded.  There's still a long way to go with this! 
  • Options
    Alex_PittAlex_Pitt Member Posts: 60 PRO
    edited April 7
    I'm using evaluateQuery to create my arrays. "This returns an array of queries for the individual entities in a context which match a specified query. Helpful when you want to count the number of entities or iterate through the list to process each entity separately." So my array entries must be queries for individual entities. This means qOwnedByBody should work for me. I'll persist.
  • Options
    Konst_ShKonst_Sh Member Posts: 42 PRO
    Looping by individual bodies from evaluateQuery and calling qOwnedByBody is the correct approach. There is even more high level standard library function for this though:

  • Options
    Alex_PittAlex_Pitt Member Posts: 60 PRO
    @konstantin_shiriazdanov , thanks. I hope to look at groupEntitiesByBody. I see that it returns a map and takes just one query. 
  • Options
    Konst_ShKonst_Sh Member Posts: 42 PRO
    when you have entities you can get bodies that own those entities with qOwnerBody() query. You need to familiarize yourself with standard library documentation, to see what is possible from the box.
Sign In or Register to comment.