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

Using a pressure parameter in feature UI, accessing Young's modulus from material properties

Jed_YeiserJed_Yeiser Member Posts: 53 PRO

I'm working on a feature that will A: Create cross sections along a curve from a selection of bodies and B: to calculate the bending stiffness of each cross section, though this may beyond the scope of Featurescript.

I am selecting bodies as part of an array parameter, and then extracting names and material properties in editing logic. My first concern/issue is the isPressure predicate does not seem to work as expected (or I'm using it improperly). I'm getting an error saying that there is no definition passed to isPressure. The docs seem to suggest that typically isPressure takes only a value, but in the std/valueBounds source I'm finding an isPressure that takes both a value and bounds like other predicates used commonly in other feature parameters. I'm importing std/valueBounds directly, but still unable to use a pressure parameter. What am I doing wrong here?

The second piece of this puzzle is accessing Young's modulus data for each material. The data that comes with getProperty(context, {….. "propertyType" : PropertyType.MATERIAL}) only comes with a density and material name. In order to find the Young's modulus, do I need to import my material library and lookup the modulus directly from the library?

Editing logic and feature parameters are below.

Thanks!

FeatureScript 2656;
import(path : "onshape/std/common.fs", version : "2656.0");
import(path : "onshape/std/valueBounds.fs", version : "2656.0");

export const numXsectionBounds = {(unitless) : [3, 50, 200]} as IntegerBoundSpec;
export const youngsBounds = {(megapascal) : [0, 100, 1000000]} as PressureBoundSpec;
export enum XSectEntityType
{
    FACE,
    WIRE
}

export function elFunc(context is Context, id is Id, oldDefinition is map, definition is map, isCreating is boolean) returns map
{
    var updatedDef = definition;
    for (var i = 0; i < size(definition.bodyArray); i += 1)
    {
        var bodyQ = definition.bodyArray[i].bodyQuery;
        var bodyName = getProperty(context, {
                "entity" : bodyQ,
                "propertyType" : PropertyType.NAME
        });
        updatedDef.bodyArray[i].bodyName = bodyName;
        var bodyMaterial = getProperty(context, {
                "entity" : bodyQ,
                "propertyType" : PropertyType.MATERIAL
        });
        
        if (bodyMaterial != undefined)
        {
            println('bodyMaterial -> ' ~ toString(bodyMaterial));
        }
        else
        {
            println(bodyName ~ ' HAS NO MATERIAL DATA');
        }
        
        // add logic here to strip the modulus from the material and assign it to updatedDef.bodyArray[i].modulus
    }
    return updatedDef;
}

annotation { "Feature Type Name" : "EI and Cross Section", "Feature Type Description" : "Takes a wire body as input to create cross section planes along. Takes an array of bodies to use when generating cross section data. Each cross section will be saved as a composite part, etither a collection of wires or faces. Material properties are combined with part geometry to solve for bending stiffness at each cross section. This EI data will appear in a table once the feature has run.", "Editing Logic Function" : "elFunc"  }
export const eiXSect = defineFeature(function(context is Context, id is Id, definition is map)
    precondition
    {

    annotation { "Name" : "Cross section composite body type", "Default": XSectEntityType.FACE, "Description" : "Specifies if the cross section composites should be composed of faces (surfaces) or wires", "UIHint" : UIHint.HORIZONTAL_ENUM }
    definition.xSectType is XSectEntityType;

    annotation { "Name" : "Wire to cross section along", "Filter" : EntityType.BODY && BodyType.WIRE, "MaxNumberOfPicks" : 1, "Description" : "Wire body along which to align and space cross section planes." }
    definition.xSectAlong is Query;
    
    annotation { "Name" : "Bodies", "Item name" : "Body", "Item label template" : "#bodyName"}
    definition.bodyArray is array;
    for (var selBody in definition.bodyArray)
    {
        annotation { "Name" : "Body", "Filter" : EntityType.BODY && BodyType.SOLID, "MaxNumberOfPicks" : 1, "Description" : "Query for the body" }
        selBody.bodyQuery is Query;
        
        annotation { "Name" : "Body name: ", "Description" : "Name of the selected body", "UIHint" : [UIHint.READ_ONLY, UIHint.ALWAYS_HIDDEN]}
        selBody.bodyName is string;
        
        annotation {"Name" : "Young's modulus", "Description" : "Young's modulus for selected body", "UIHint" : UIHint.READ_ONLY}
        isPressure(selBody.modulus, youngsBounds);   
        
    }        
    
    annotation { "Name" : "Number of cross sections", "Description" : "Number of evenly spced locations along selected wire to analyze. This includes endpoints of the wire by default"}
    isInteger(definition.numSections, numXsectionBounds);
    
    annotation { "Name" : "Include endpoints?", "Defult" : true, "Description" : "If yes, planes at endpoints will be included in analysis. If no, endpoints (parameters 0, 1) will not be included"}
    definition.includeEndpoints is boolean;

    annotation { "Name" : "Calculate bending stiffness", "Default" : true, "Description" : "When true, Feature will calculate bending stiffness and neutral axis for each cross section. A table will be created to display this data, and the neutral axis curve will be generated" }
    definition.calcEI is boolean;
    
    annotation { "Name" : "Keep cross sections", "Default" : true, "Description" : "When true, wire bodies for each cross section will be saved as composite parts and labeled accordingly" }
    definition.keepCrossSections is boolean;
    
}

Best Answer

  • Caden_ArmstrongCaden_Armstrong Member Posts: 293 PRO
    Answer ✓

    Not every predicate is supported as an input type for a featurescript. Predicates in general are special functions with some unique rules that are generally used to validate data types. I've run into a similar situation with things like area or volume inputs.

    For the pressure, you can take in a unitless real number and assign the units in the feature body. Just add the units to the label of the input so the user knows.

    As far as I know, only the density is provided from the getProperty call. So yeah, you'll have to make your own lookup table.

    www.smartbenchsoftware.com --- fs.place --- Renaissance
    Custom FeatureScript and Onshape Integrated Applications

Answers

  • Caden_ArmstrongCaden_Armstrong Member Posts: 293 PRO
    Answer ✓

    Not every predicate is supported as an input type for a featurescript. Predicates in general are special functions with some unique rules that are generally used to validate data types. I've run into a similar situation with things like area or volume inputs.

    For the pressure, you can take in a unitless real number and assign the units in the feature body. Just add the units to the label of the input so the user knows.

    As far as I know, only the density is provided from the getProperty call. So yeah, you'll have to make your own lookup table.

    www.smartbenchsoftware.com --- fs.place --- Renaissance
    Custom FeatureScript and Onshape Integrated Applications
Sign In or Register to comment.