In 2008, Stefan Rueffer (currently the Principal User Experience Designer for Softimage) from VCC Perfect Pictures produced this great demo showing his work with ICE.
ICE: Doing an element-wise stretch on an array
I’m not sure “element-wise stretch” is the right terminology, but what I mean is suppose you want to build a new array by repeating the original elements N times. For example, suppose you have the array [1,2], and you want to turn it into [1,1,1,1,2,2,2,2].
Here’s a little ICE technique to do just that:
This tree relies on Divide by Scalar truncating the scalar result to make it an integer.
Softimage 2014 What’s Fixed Word Cloud
Here’s a word cloud for the bugs fixed list. This isn’t the raw word count; I did a few things like adding repeats of the word “Fixed” for every SOFT id number, and repeats of the category name (eg “ICE”) for every fix in that category.
So the size of the word “ICE” is a combination of the number of ICE fixes (32) plus the number of occurrences of the word “ICE” in the bug descriptions (29).

The word “FIXED” is a bit distracting, so here’s a version without it:

Softimage 2014
Aha! Setting DataArray2D with JScript
It came to me this morning while I was lying in the dentist chair.
I almost had it last Thursday.
Hat tip: Ho Chung
//var o = Selection(0)
//var oICEAttrMats = o.ActivePrimitive.AddICEAttribute("MyString", siICENodeDataString, siICENodeStructureArray, siICENodeContextSingleton);
var o = Selection(0);
var a = o.ActivePrimitive.ICEAttributes("MyString");
sa = getSafeArray( [ "a", "b", "c" ] );
//jsa = new VBArray( sa ).toArray();
sa1 = getSafeArray( [sa] );
a.DataArray2D = sa1;
//
// Get a safearray from a JScript array
//
function getSafeArray(jsArr) {
var dict = new ActiveXObject("Scripting.Dictionary");
for (var i = 0; i < jsArr.length; i++)
dict.add(i, jsArr[i]);
return dict.Items();
}
Screenshots of the week
Softimage 2014 documentation splash page…what it might look like

Twister nodes
by Tekano

Setting materials IDs for clusters
by iamVFX

Effect trigger by name
by fabricio.chamon

Fun with ICE: Wheel\
by Andrew Skoblyanoff
Closest location on strand
by Edy Susanto Lim

Closest location on strand
by Vincent Ullmann


Color in the vertex UV coordinates
by Ymt3D
I’m not quite sure, but from the auto-translation I think this ICE tree isn’t working as expected:
“Color in the vertex UV coordinates of the nodes in the sample application point was different vertex colors to break the UV at ICE. · Tell someone smart way more ”

Saturday Snippet: How many operators in Softimage?
Dictionary.Info gives you a list of all members in a particular family.
ops = Application.Dictionary.Info( '',"Operators").split(',')
print len(ops)
for op in ops:
print op
For example, there are 592 operators in 2013 SP1 (and 585 in 2012 SP1).
# 592 # RaiseNurbsCrvDegree # ExtrusionAlongAxis # 4DVectorTo3DVectorNode # CreatePolygon # GetSetSumNode # deformbyspineop2 # weighmapdeformbyspineop2 # GetDistanceBetweenNode # MarkHardEdgeVertex # FCurveNode # BooleanSrfTopo # OldGenerateSampleSetNode # HipIcon # WeightPainter # DirectionToRotationNode # PropWeightMapBySpineOp # BaseRetargetOp # SkeletonUpVector # SkeletonPrefAxis # ReferenceToStringNode # BooleanSrfOp # RemoveNurbsCrvKnot # DeleteParticleOp # MergeDisjointVerticesNode # CenterManip # FillHole # SubtractNode # BlasterOp # NegateNode # CrvOffset # FourSided # DissolveComponent # Cap # 3DVectorTo4DVectorNode # GetClosestPointsNode # FilterEdge # SubdivideEdge # MergePolygonNode # AnimationMarker # ExponentNode # Fixed Length Operator # AddEdge # SrfSwap # SrfDump # OffsetPolygons # ExtractPolygonsOp # SurfaceUVControl # Copy Shape Op # 2DVectorNode # GetArraySizeNode # SortArrayNode # UpVectorDefiner # HairCutOp # DetachPolygonsOp # RotationToScalarNode # Birail2Contours # ToeGuide # GetSetMedianNode # 4x4MatrixNode # Primitive Grid # Primitive Circle # Primitive Arc # Primitive Spiral # IntegerNode # NurbsCrvDeletePoint # HairScaleOp # HSVAToColorNode # ICETree # HLSAToColorNode # Primitive Cylinder # AreParallelNode # ManCharEyeOp # AddNode # VectorTo4x4MatrixNode # CrvDeform # ScalarNode # HairResampleOp # CompoundNode # SimulationStepNode # GetSetSizeNode # Primitive Square # Primitive Octahedron Operator # 3x3MatrixNode # SRTToMatrixNode # MeshSubdivideWithCenter # PrimitivePreSimulationMarker # SrfOffset # SpeechBlendOp # TextToCurveListOp # SimpleIKRetargetOp # TextureOp # Quadrangulate # FrameStepNode # 4x4MatrixToVectorNode # ChestBone # CopyGeo # PopFromArrayNode # SelectCaseNode # ColorNode # InvertPolygonNode # VertexColorChangeDatatype # MotionDerivator # FRBulgeNode # ExtractSubCrvOp # BipedRigSteppingAngle # ShapeNode # UndefinedLocationNode # GetClosestLocationNode # SplitPolygon # SetPositionNode # FingerBladeOp # CurrentTimeNode # SubdividePolygon # Surface curve adaptor # QStretch # 3DVectorTo4x4MatrixNode # Primitive Disc # MatrixToSRTNode # RelaxUVW # UVToLocationNode # CrvPass # CrvExtract # SrfCrvShift # ReinterpretLocationToNewGeometryNode # CrvReparam # TangentOp_cpp # SubtractColorNode # SrfFit # PrimitiveMeshNode # MaximumNode # HairPopOp # ColorToGrayscaleNode # BooleanNode # MoveComponent # SCMFixer # SubdivideLocallyNode # MoveComponentProportional # BlobEncodeTestNode # PropVolume # GetDeterminantNode # CrvExtractSeg # GenerateSampleSetNode # MultiplyByScalarNode # CollapseEdgeNode # ScalarTo3DVectorNode # SplitEdge # HairMergeOp # SquaredLengthNode # TrigonometryNode # SparksOp # GetDataNode # SpringOp # Primitive Dodecahedron Operator # LengthNode # Loft # WeldPoints # QuaternionToAxisAndAngleNode # SortArrayWithKeyNode # TestBackcompNode # RemoveFromArrayNode # Loft # Extrusion # FourSided # PolyMeshPNet # CrvOffset # SrfOffset # SrfFillet # SrfIntersect # SrfMerge # FillHole # CrvFit # CrvExtract # Cap # CrvProject # CurveCreation # CrvNet # Birail # CrvFillet # CrvStitch # CrvMerge # CrvExtractSeg # ExtrusionTwoProfiles # SCMTopology # Revolution # BlendCrv # BlendSrf # CopyOp # GetArrayProductNode # FlexibleEnvelope # 4x4MatrixTo3DVectorNode # SrfSubdivision # TangentOp2_cpp # ModuloNode # BooleanToIntegerNode # ClusterSimpleShapeCombinerOp # CollisionAvoidanceNode # HairGenOp # HairDynamicsOp # 3x3MatrixToVectorNode # CrvSnap # TrimByProjection # SrfStitch # FRTugNode # VectorTo3x3MatrixNode # CurrentFrameNode # SCMFixer2 # Lattice # RevolutionAlongAxis # FilterNode # Bulge # SetData # DelaySetDataNode # ImageCropOp # MultiplyVectorByMatrixNode # CrvPassByPoint # IsSingularNode # IntegerToBooleanNode # SetUserDataMapValueOp # SplitEdgeNode # BlobDecodeTestNode # CopyOp # LockEnvelopeWeights # CrvExtendTo # SrfClean # CrvFillet # CrvStitchToSrf # CrvStitch # CrvMerge # ExtendCrvToPoint # Surface To Surface Curve Adaptor # DicePolygons # AddVertexNode # CurveToCurvePointAdaptor # Modify Envelope Weight Prop Op # Skeleton Controller # BevelComponent # DeformBySpine # SimulateBulletRigidBodiesNode # RotationNode # First Bone Roll Division # Rotation Order # ConstrainCurveIsopoint # Revolution # SrfInverse # HairLockOp # CurveToCurveBoundaryAdaptor # LimitEnvelopeDeformersOp # HairSplitOp # GetArrayAverageNode # SetOneDataNode # InsertSrfKnot # RemoveSrfKnot # CrvProject # BlendNode # LogarithmNode # SrfFillet # EdgeDelete # ExtrudeComponent # AddEdgeNode # SimulateRigidBodiesNode # Spine Curve Operator # GetDataAtPreviousFrameNode # TriangulatePolygonNode # IntegerToScalarNode # Gator # SCMTopology # GetClosestPointToLineSegmentNode # First Bone Roll Division # MergeTopoArrayNode # ExtrudePolygonIslandNode # IsOnGeometryNode # ScalarToRotationNode # ExclusiveOrNode # DeleteComponent # ResizeArrayNode # DeletePointNode # GetAngleBetweenNode # SteppingAngle30Op # SymmetryMap # FlexibleEnvelopeAutoAssign # PropWeightMapBySpineOp # Snip # EditPolygon # GroupGeometryNode # CreateTopoNode # NurbsToMesh # Shear # GradientNode # HyperFlowOp # CameraTxt # PolyUVContourStretchingOnTopOp # BlendCrv # CustomOperator # ColorToHLSANode # QuaternionToRotationNode # FRLiftNode # SplineGenOp # PolygonReduction # ImageSourceOp # AddPolygonNode # IfNode # SimulationMarker # ScalarTo2DVectorNode # GetMinimumInSetNode # InsertInArrayNode # LinearInterpolateNode # ArcTan2Node # StringFilePathNode # SnapFace # HairPuffOp # PrimToNonLocalMatCls # GetElementIndicesNode # SetClusterPropSizeOp # RepeatNode # DisconnectComponentNode # ParTypeClsGenOp # FindInArrayNode # Fold # OldGetGeometrySampleNode # PushOnArrayNode # Birail # TextureOp # SurfacePQ # Cluster # MotionIntegrator # PassThroughNode # Multiply Rotation Operator # Spring # Collapse # QuaternionNode # BridgePolygon # HairUnlockOp # SymmetrizePolygon # FlipUVW # SetUVPropPinInfoOp # ImageFXOp # GetSetOrNode # TurbulenceNode # RGBAToColorNode # ClonePointNode # GetSetAndNode # RotationToEulerNode # SimMotionDerivOp # CompareNode # PointIndexToLocation # MergeTopoNode # MapCompOp2 # DisconnectComponent # BlendTransformNode # Copy Shape Op # GetGeometrySampleNode # MatchUVW # NXDynamicsOp # FlowFieldRenderOp # Push # SoftBodyOp # RaycastNode # FlexibleEnvelopeAutoAssign # OldNurbsCrvDeletePoint # SlicePolygons # VertexColorPainter # PolyMeshPNet # BuildArrayFromConstantNode # AbsoluteValueNode # Cls Shape Combiner Op # ModelingMarker # CrvInverse # SrfShift # CrvShift # OffsetComponents # ExtractEdgeLoopOp # TurnEdgeOp # Fore Arm Roll Division # LogValuesNode # AddPointNode # IDToLocation # ExtrudeComponentAxis # SetEdgeCreaseValueOp # GetSetAverageNode # Primitive Tetrahedron Operator # SrfOpenClose # MixerOp # CloneTopoNode # Bend # Taper # ReserveArrayNode # Surface To Boundary Curve Adaptor # NormalizeNode # Fracture # Primitive Text # InvertNode # RotationToQuaternionNode # InitializeNode # SlicePolygonNode # PrimitivePostSimulationMarker # DeletePolygonNode # ClothOp # ShapeJitter # DotProductNode # SrfPass # MapAdaptOp # Spin # SplineDynamicsOp # Primitive Icosahedron Operator # Primitive Sphere # Extrusion # DivideByScalarNode # FilterPolygon # OLD Cache On File --REPLACEME # TestNode # InvertPolygon # Primitive Cone # Primitive Cube # QuaternionToScalarNode # CacheDataNode # PrimaryShapeMarker # MeshMerge # ICETreeComment # 3DVectorNode # PaintWeight # WeightMap # SrfMerge # AddPointToMiddleOfCurve # GetArrayMaximumNode # Connector_Head # DieNode # DogLeg # CombineLogicNode # 4DVectorNode # CrvClean # CrvOpenClose # PostSimulationMarker # Smooth # WeldEdges # CrossProductNode # Spine PointAt Operator # SrfIntersect # ShrinkWrap # QuadrupedGuideOp # WMCnxOp # DeformHairAdaptor # Revolution # Extrusion # ProjectVectorNode # SrfDeform # TransposeNode # Connector_L # InsertNurbsCrvKnot # BlowUpOp # ClusterCenter # NotNode # CurveKnotAlignTangent # CurveListToMesh # AddColorNode # ScalarTo4DVectorNode # CrvFit # MapCompOp # SrfCrvInverse # Softimage # FacialSoftTissueOp # GetArraySubIndicesNode # EvolveOp # HairClumpOp # HairAttenuateOp # BlendSrf # ScriptedOpHost # AddParticleOp # QuaternionToEulerNode # Heal # MinimumNode # MeshSubdivide # SrfReparam # FRSkullUVsToPtLocsNode # CustomNode # Proportional # Connector_T # PointInVolumeNode # ArePerpendicularNode # RotateVectorNode # BBoxCns # ColorToRGBANode # PolyUVContourStretchingOp # SpinEdge # CompoundNode # Connector_Box # LocalTextureOp # GetClosestPointToLineNode # PropertyXferOp # 3DVectorToScalarNode # StringFilePathSequenceNode # ScalarToQuaternionNode # HairCombOp # PrimitiveSimulationMarker # BasicCollideNode # ExecuteNode # CurveCreation # SecondaryShapeMarker # CrvNet # SetInArrayNode # MultiplyColorByScalarNode # PropWeightMapBySpineOp # ClsKeyWeightMapOp # EulerToQuaternionNode # QuatSpineOp # WhileNode # Weight Maps Mixer Op # GetActionSourceAtFrameNode # Noise # Wave # BallisticSim # VertexColor # Cage Deform Auto Assign # CycleUVW # Proportional # GetArraySumNode # InstanceShapeNode # DynamicsOp # EdgeAdd # FlowFieldOp # BuildArrayNode # PolyUVPackingOp # ExtrudeComponentNormal # SelectInArrayNode # RescaleNode # CacheOnFileNode # RotationToAxisAndAngleNode # DeleteVertexNode # ColorToHSVANode # AddToClsOp # Twist # IslandHealUVWOp # SimulateParticlesNode # MultiplyNode # AxisAndAngleToQuaternionNode # HealUVW # 2DVectorToScalarNode # FirstValidNode # SwitchContextNode # TangentOp2_cpp # StringNode # GetArrayMinimumNode # ClusterToObj # RoundNode # GetMaximumInSetNode # Primitive Torus # HairRotateOp # FilterPoints # FRSkinNode # RandomValueNode # CrvDump # DeleteTrim # PolygonAdd # ClampNode # Randomize # CageDeform # MeshLocalSubdivision # # MeshSrfDeletePoint # TopoTransformNode # CopyUVW # SquareRootNode # HairShatterOp # SetNurbsCrvKnotMultiplicity # HairRecombOp # AxisAndAngleToRotationNode # EulerToRotationNode # BuildArrayFromSetNode # ColorToBrightnessNode # BlendColorNode # 4DVectorToScalarNode # QuaternionInterpolateNode # syCollidePla # syZipper # POXSI # syWind # syProperties # syCollide # syMimic # syCache # syVolume # syTurbulence # sySpring # syPin # sySelfCollide # syPropertiesFlesh # syGravity # syDamp # syCloth # syPropertiesSkin # syNail # syAir # syCollideSph
Friday Flashback #112
Trying and failing to set DataArray2D with JScript
First, let’s use Python to set up two ICE attributes with DataArray2D.
si = Application
from win32com.client import constants as C # win32com.client.constants
oObj = si.Selection(0)
a = oObj.ActivePrimitive.AddICEAttribute("MyString", C.siICENodeDataString, C.siICENodeStructureArray, C.siICENodeContextSingleton)
a.DataArray2D = [["a", "b", "c", "d", "e"]]
a1 = oObj.ActivePrimitive.AddICEAttribute("MyString2", C.siICENodeDataString, C.siICENodeStructureArray, C.siICENodeContextSingleton)
a1.DataArray2D = [["u", "v", "w" ]]
Now, let’s try to set DataArray2D with JScript. As a reminder, here’s how you access the DataArray2D in JScript:
o = Selection(0);
a = o.ActivePrimitive.ICEAttributes("MyString");
x = VBArray( a.DataArray2D ).toArray();
LogMessage( VBArray( x[0] ).toArray() );
// INFO : a,b,c,d,e
Seeing that, you would think that you could set DataArray2D using an array of arrays or maybe an array, but no:
a.DataArray2D = [[ "a", "b", "c" ]]; // WARNING : 3390 - This ICEAttribute doesn't refer to a 2D array: <Attribute: MyString2> // a.DataArray2D = [ "a", "b", "c" ]; // WARNING : 3392 - Invalid offset specified while extracting data from this attribute: <Attribute: MyString2> // <Offset: 110348408> //
At this point, I started wondering if there was anyway at all to do it, so I tried to put back the same value:
a.DataArray2D = a.DataArray2D; // WARNING : 3393 - The input array doesn't match this attribute's data type or structure type: <Attribute: MyString2> //
Ack. Maybe if I converted it to a JScript array…well, at least something finally worked:
a.DataArray2D = VBArray( a.DataArray2D ).toArray();
Copying the DataArray2D from another attribute works too:
a = o.ActivePrimitive.ICEAttributes("MyString");
a1 = o.ActivePrimitive.ICEAttributes("MyString2");
a.DataArray2D = VBArray( a1.DataArray2D ).toArray();
So, based on that, I thought maybe I needed a safearray and things started getting a little hacky:
sa = getSafeArray( [ "a", "b", "c" ] );
jsa = new VBArray( sa ).toArray();
a.DataArray2D = sa;
// WARNING : 3392 - Invalid offset specified while extracting data from this attribute: <Attribute: MyString2>
// <Offset: 110348408>
a.DataArray2D = jsa;
// WARNING : 3392 - Invalid offset specified while extracting data from this attribute: <Attribute: MyString2>
// <Offset: 110348408>
//
// Get a safearray from a JScript array
//
function getSafeArray(jsArr) {
var dict = new ActiveXObject("Scripting.Dictionary");
for (var i = 0; i < jsArr.length; i++)
dict.add(i, jsArr[i]);
return dict.Items();
}
In summary, it doesn’t seem possible to set DataArray2D from JScript.
Setting the DataArray2D attribute in scripting
Last time I tried this, I gave up on JScript (it seemed impossible) and got something to work in Python.
In JScript, I kept getting errors like “# WARNING : 3392 – Invalid offset specified while extracting data from this attributeÈ.
si = Application
from win32com.client import constants as C # win32com.client.constants
oObj = si.Selection(0)
oICEAttrMats = oObj.ActivePrimitive.AddICEAttribute("MyString", C.siICENodeDataString, C.siICENodeStructureArray, C.siICENodeContextSingleton)
oICEAttrMats.DataArray2D = [["a", "b", "c", "d"]]
x = oICEAttrMats.DataArray2D
print x
print len(x)
print len(x[0])
print len(x[0][0])
for d in x[0][0]:
print d
# (((u'a', u'b', u'c', u'd'),),)
# 1
# 1
# 4
# a
# b
# c
# d
See also this Getting DataArray2D attribute values post.


