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:

elmentwisestretch

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).
whatsfixed2014

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

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
2014docs

Twister nodes
by Tekano
Capture_twister_nodes

Setting materials IDs for clusters
by iamVFX
Snpi9lH

Effect trigger by name
by fabricio.chamon
effect_trigger_by_name

Fun with ICE: Wheel\
by Andrew Skoblyanoff

Closest location on strand
by Edy Susanto Lim
closest_strandPos02
Closest location on strand
by Vincent Ullmann
result
tree

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 ”
BF5WaJ_CAAA3hg1

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

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.