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.

remove a body in featurescript

rooiejorisrooiejoris OS Professional Posts: 16 PRO
As I start always: I am not a programmer, but I think I want something fairly simple:

I want to remove all bodies with a volume smaller than X
the println works so the condition works as well, I just can't get it done that it actually deletes the bodies.

FeatureScript 2260;//import(path : "onshape/std/common.fs", version : "2260.0");
import(path : "onshape/std/geometry.fs", version : "993.0");

annotation { "Feature Type Name" : "remove_larger_volume" }
export const myFeature = defineFeature(function(context is Context, id is Id, definition is map)
    precondition

    {
        // Define the parameters of the feature type
                //println("dit is het begin");
    }
    {
        println("start");
        setVariable(context, "test", 1); // test

        // Define the function's action
        for (var part in evaluateQuery(context, qAllModifiableSolidBodies()))
        {
            //var partName = getProperty(context, { "entity" : part, "propertyType" : PropertyType.NAME } );
            var volume = evVolume(context, { "entities" : part });
            //volume = volume;
                println(volume);
            

            if (volume <= 0.0002 *meter*meter*meter) {
                println("tada");
                opDeleteBodies(context, id + "deleteBodies1", {
                        "entities" : entity
                });
            }

        }
        println("end");

    });

documentation says something with opDeleteBodies, but I can't figure the right arguments/values/whatever


you can see the script in the second tab of 
https://cad.onshape.com/documents/bced954384551d9a45056666/w/1c4ec0f34b9d2439e54967bb/e/efbe92356f7e4fdb9a7ffea8?renderMode=0&uiState=65cc8eb5ce42ed723b91737c

thanks in advance...!!

cheers / joris

Best Answer

  • Konst_ShKonst_Sh Member Posts: 51 PRO
    edited February 15 Answer ✓
    when in the loop every context operation with id should have unique id, so you need to use iterator variable to build the id:
    for (var i, part in evaluateQuery(context, qAllModifiableSolidBodies()))
    {
    opDeleteBodies(context, id + ("deleteBodies" ~ i), { "entities" : entity });
    }

    At some moment you will want to perform multiple operation in the loop, in this case it might be more handy to construct the id of the whole iteration first:

    for (var i, part in evaluateQuery(context, qAllModifiableSolidBodies()))
    {
    const id = id + "iteration" + i; // the id from the outer scope is shadowed here for the scope of the for loop
    opDeleteBodies(context, id + "deleteBodies", { "entities" : entity });
    //another op_ functions with id here
    }
    Also in your case I would do it in slightly another way:

    const toDelete = evaluateQuery(context, qAllModifiableSolidBodies())->filter(function(body){
       const volume = evVolume(context, { "entities" : body});
       return volume <= 0.0002 *meter*meter*meter;
    })
    ->qUnion();
    if(!isQueryEmpty(context, toDelete)) {
       opDeleteBodies(context, id + "deleteBodies", {
          "entities" : toDelete
       });
    }
    else{
       println("No bodies below the volume limit");
    }


Answers

  • eric_pestyeric_pesty Member Posts: 1,887 PRO
    Have you tried using" "entities" : part in the opDeleteBodies (instead of entity)? I think that should work as it should be the same entity you just did "evVolume" on...
  • rooiejorisrooiejoris OS Professional Posts: 16 PRO
    Yes, But then I get a warning: @opDeleteBodies: Duplicate id in context: F27r4Cn5tpu5qC7_6.deleteBodies1
  • Konst_ShKonst_Sh Member Posts: 51 PRO
    edited February 15 Answer ✓
    when in the loop every context operation with id should have unique id, so you need to use iterator variable to build the id:
    for (var i, part in evaluateQuery(context, qAllModifiableSolidBodies()))
    {
    opDeleteBodies(context, id + ("deleteBodies" ~ i), { "entities" : entity });
    }

    At some moment you will want to perform multiple operation in the loop, in this case it might be more handy to construct the id of the whole iteration first:

    for (var i, part in evaluateQuery(context, qAllModifiableSolidBodies()))
    {
    const id = id + "iteration" + i; // the id from the outer scope is shadowed here for the scope of the for loop
    opDeleteBodies(context, id + "deleteBodies", { "entities" : entity });
    //another op_ functions with id here
    }
    Also in your case I would do it in slightly another way:

    const toDelete = evaluateQuery(context, qAllModifiableSolidBodies())->filter(function(body){
       const volume = evVolume(context, { "entities" : body});
       return volume <= 0.0002 *meter*meter*meter;
    })
    ->qUnion();
    if(!isQueryEmpty(context, toDelete)) {
       opDeleteBodies(context, id + "deleteBodies", {
          "entities" : toDelete
       });
    }
    else{
       println("No bodies below the volume limit");
    }


  • rooiejorisrooiejoris OS Professional Posts: 16 PRO
    THANKS A LOT! It works...!

    thanks for the explanation, I will try to understand it more, but if you don't program that much it is a bit dazzling.
    I didn't try the suggestions for the for loop, but tried you suggestion.

    Also in your case I would do it in slightly another way:

    const toDelete = evaluateQuery(context, qAllModifiableSolidBodies())->filter(function(body){
       const volume = evVolume(context, { "entities" : body});
       return volume <= 0.0002 *meter*meter*meter;
    })
    ->qUnion();
    if(!isQueryEmpty(context, toDelete)) {
       opDeleteBodies(context, id + "deleteBodies", {
          "entities" : toDelete
       });
    }
    else{
       println("No bodies below the volume limit");
    }




    Didn't work first, but that was because I didn't import the right things in the beginning:

    this works:
    import(path : "onshape/std/common.fs", version : "2260.0");
    //import(path : "onshape/std/geometry.fs", version : "993.0");

    this doesn't
    //import(path : "onshape/std/common.fs", version : "2260.0");
    import(path : "onshape/std/geometry.fs", version : "993.0");

    and this also not
    import(path : "onshape/std/common.fs", version : "2260.0");
    import(path : "onshape/std/geometry.fs", version : "993.0");

    thanks again!!

    cheers / joris

  • Konst_ShKonst_Sh Member Posts: 51 PRO
    Imports from STD of version 993 are very old, the functions that are used in last example were not there yet so importing the latest version of geometry.fs and using the latest version in FeatureScript ____;  is a generally good practice.
Sign In or Register to comment.