The example “ActivationDeactivationOfElements.gh” features a simplified version of Karamba3D’s “Tension/Compression Eliminator”-component. It repeatedly evaluates a structure and removes all elements with tensile normal force. Starting from an arbitrary structural model the script iteratively removes those elements which are under tension (see fig. 2.4.2.1).
#regionUsingsusingSystem;#r"C:\Program Files\Rhino 8\Plug-ins\Karamba\KarambaCommon.dll"#r"C:\Program Files\Rhino 8\Plug-ins\Karamba\Karamba.gha"usingSystem.Linq;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Drawing;usingRhino;usingRhino.Geometry;usingGrasshopper;usingGrasshopper.Kernel;usingGrasshopper.Kernel.Data;usingGrasshopper.Kernel.Types;usingKaramba.Models;usingKaramba.GHopper.Models;usingKaramba.Utilities;usingKaramba.Loads.Combination;usingKaramba.Elements.States.Selectors;usingKaramba.Geometry;#endregionpublicclassScript_Instance:GH_ScriptInstance{privatevoidRunScript(object Model_in,int maxiter,refobject Model_out,refobject isActive,refobject maxDisp) {var k3d =newKarambaCommon.Toolkit();IReadOnlyList<double> max_disp;IReadOnlyList<Vector3> out_force;IReadOnlyList<double> out_energy;string warning;var model = Model_in asModel;if (model ==null) {thrownewArgumentException("The input in 'Model_in' is not of type karamba.Models.Model!"); } // load case to consider for elimination of elementsstring lcName ="LC0"; // get load-case combinationLoadCaseCombination lcc;model.lcActivation.TryGetLoadCaseCombination(lcName,out lcc); // select load case 0 of load-case combination "LC0"var stateSelector =newStateElement1DSelectorIndex(model, lcc,0); // clone the model and its list of elements to avoid side effects model =model.Clone(); // clone its elements to avoid side effectsmodel.cloneElements(); // do the iteration and remove elements with tensile axial forcesfor (int iter =0; iter < maxiter; iter++) { // create a deform and response object for calculating and retrieving results model =k3d.Algorithms.Analyze(model,newList<string>(){lcName},out max_disp,out out_force,out out_energy,out warning); // check the normal force of each element and deactivate those under tensiondouble N, V, M;bool has_changed =false;foreach (Karamba.Elements.ModelElement elem inmodel.elems) { // retrieve resultant cross section forceselem.resultantCroSecForces(model, stateSelector,0.3,3,out N,out V,out M); // check whether normal force is tensileif (N >0) { // set element inactiveelem.set_is_active(model,false); has_changed =true; } } // leave iteration loop if nothing changedif (!has_changed) break; // rebuild the C++ modelmodel.buildFEModel(); } // update model to its final state model =k3d.Algorithms.Analyze(model,newList<string>(){lcName},out max_disp,out out_force,out out_energy,out warning); // set up list of true/false values that corresponds to the elemment statesList<bool> elem_activity =newList<bool>();foreach (var elem inmodel.elems) {elem_activity.Add(elem.IsActive); } isActive = elem_activity; maxDisp = max_disp; Model_out =newGH_Model(model);Print("Everything OK"); }}```
At the beginning of the script, the input variable Model_in is type-cast to Karamba.Models.Model. If the provided object does not match the expected type, an ArgumentException is thrown.
The load case name is fixed as "LC0" in line 51. The associated LoadCaseCombination object is retrieved from the model in line 54 and utilized in line 56 to create a result selector. This selector extracts the first (and only) load-case item of the load-case combination. In Karamba3D, a load case is equivalent to a load-case combination containing a single load-case item.
To prevent side effects, data must be copied before any modifications occur. Line 59 performs this operation for the Karamba3D model. Since the model contains references to objects, these objects must also be copied. The element activation state is modified within the script, so the list referencing these elements is copied as shown in line 61.
The model is analyzed repeatedly for the specified load-case combination "LC0" in line 67.
In lines 72–82, the algorithm iterates through all elements in the system, extracts their resultant section forces, and deactivates any members under tension (where N ≥0).
The loop terminates when no further changes are detected (line 85) or when the maximum number of iterations is reached. At this point, the model is updated one final time.
An iteration over all elements generates a list of boolean values corresponding to their activation states (lines 96–98). This list is assigned to the output variable in line 100. Finally, line 102 wraps the model containing the final results in a GH_Model wrapper object.