{
  "id": "spring_sop",
  "name": "Spring SOP",
  "displayName": "Spring SOP",
  "category": "SOP",
  "subcategory": "Generators",
  "version": "",
  "lastUpdated": "2025-08-07T07:50:09.892Z",
  "sourceFile": "C:\\Program Files\\Derivative\\TouchDesigner\\Samples\\Learn\\OfflineHelp\\https.docs.derivative.ca\\Spring_SOP.htm",
  "url": "",
  "description": "The Spring SOP deforms and moves the input geometry using spring \"forces\" on the edges of polygons and on masses attached to each point.",
  "summary": "The Spring SOP deforms and moves the input geometry using spring \"forces\" on the edges of polygons and on masses attached to each point.",
  "details": "",
  "usage": "",
  "tips": [],
  "warnings": [],
  "parameters": [
    {
      "id": null,
      "name": "Preroll Time",
      "label": "Preroll Time",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "From Derivative\n\t\t\n\t\t\n\t\t\n\t\t\n\t\tJump to navigation\n\t\tJump to search\n\t\t\nThe Spring  deforms and moves the input geometry using spring \"forces\" on the edges of polygons and on masses attached to each point.\t\t\nGeometry is deformed using forces that simulate simple physics on the points and edges. A simulated \"mass\" is assigned to each point. Its primitive edges act as \"springs\" which oppose the forces, and pull the points back toward their original positions. When the springs are stretched by the forces, they try to pull the points back. The points do not stop moving when they return to their original positions, however, but continue to oscillate because of their mass, until the oscillation dies out.\t\t\t\nForces which act upon the points are as follows:\t\t\t\n\nexternal force (gravity)\nwind (similar to external force)\nturbulence (chaotic forces)The greater the drag value, or smaller the mass, the faster the oscillation dies out.\nspringSOP_Class\n\nContents\n \n \n \n \n \n \n \n \n \n\n\n\n\n\n  timepreroll - How many seconds of the simulation to bypass, after the reset time is reached. For example, if you put the number 33 into this field (and reset is at $TSTART), frame one will show the simulation that was at a time of 33 seconds. In other words, the first thirty-two seconds have been bypassed, and the time at thirty-three seconds is shifted to frame one. The first thirty-two seconds must still be calculated in order to compute the status of the points, so you will notice some delay upon reset.\n\n\n\t\t\n  timeinc - The  parameter determines how often to cook the . By default, this parameter is set to 1/$. This means that the  will cook once for every frame. When complex dynamics are involved, the  may require more frequent cooking for increased mathematical accuracy. To get sub-frame accuracy in the cooking, set the  to something smaller than 1/$ . For example, setting the  to 0.5/$ will mean that the  gets cooked twice for every frame.\t\nNote: Never set this parameter greater than 1/$.\n\n\n\t\t\n  accurate - This option makes the nodes move more accurately between frames by calculating their trajectories for fractional frame values.\n\n\n\t\t\n  attractmode -  - Describes how attractor points are assigned to each particle.\n\n all - All point attractors affect all particles (or points). single - When enabled, each particle is assigned a single attractor point, and is affected by only that point. Assignment is done by point number modulo the total number of attractor points.\n\t\t\n  reset - While On resets the spring effect of the .\n\n\n\t\t\n  resetpulse - Instantly reset the spring effect.\n\n\n\n\n\n  external -  - Forces of gravity acting on the points. When drag is zero, the points can accelerate with no limit on their speed.\n\n externalx - externaly - externalz -\n\t\t\n  wind -  - Wind forces acting on the points. Similar to external force. Using wind (and no other forces, such as turbulence), the points will not exceed the wind velocity.\n\n windx - windy - windz -\n\t\t\n  turb -  - The amplitude of turbulent (chaotic) forces along each axis. Use positive values, if any.\n\n turbx - turby - turbz -\n\t\t\n  period - A small period means that the turbulence varies quickly over a small area, while a larger value will cause points close to each other to be affected similarly.\n\n\n\t\t\n  seed - Random number seed for the simulation.\n\n\n\n\n\n  fixed - This is a point group. All points in the point group will remain unaffected by the forces. Also see the Group SOP for notes on how to specify point ranges.\n\n\n\t\t\n  revertfixed - Determines whether or not points in the  group should be moved to the positions of the corresponding points in the Source geometry.\n\n\n\t\t\n  copygroups - Determines if the Spring  should copy groups from the Source geometry at each frame. This lets you specify the name of an animating group in the  field, and the contents of this group will be kept up to date.\n\n\n\t\t\n  domass - When selected, the  is computed for the deforming geometry.\n\n\n\t\t\n  mass -  of each point. Heavier points take longer to get into motion, and longer to stop.\n\n\n\t\t\n  dodrag - When selected, the geometry is deformed by the  attribute.\n\n\n\t\t\n  drag -  of each point.\n\n\n\t\t\n  springbehavior -  - How the springs will behave:\n\n hooke - Springs will work according to Hooke's Law. This is generally more stable than .Hooke's Law: Force = Displacement  Spring constant normalize - Similar to  except that the displacement is normalized to the original length of the Spring.\n\t\t\n  springk - The spring constant. How tight the springs are. Increase this value to make the springs tighter and thus make the object more rigid. As this number becomes higher, the springs can oscillate out of control. Decrease the  if this happens.\n\n\n\t\t\n  tension - The Initial k constant of the geometry before being deformed by the spring operation.\n\n\n\n\n\n  limitpos -  - The points will bounce off the limit planes when it reaches them. The six limit plane fields define a bounding cube. The default settings are one thousand units away, which is very large. Reduce the values to about one to see the effect.\n\n limitposx - limitposy - limitposz -\n\t\t\n  limitneg -  - The points will bounce off the limit planes when it reaches them. The six limit plane fields define a bounding cube. The default settings are one thousand units away, which is very large. Reduce the values to about one to see the effect.\n\n limitnegx - limitnegy - limitnegz -\n\t\t\n  hit -  - Control over what happens when the geometry hits either the six collision planes or the collision object. The options are:\n\n bounce - Geometry will bounce upon contact with the Collision input. stick - Geometry will stick to the Collision input upon contact.\n\t\t\n  gaintan - Friction parameters which can be regarded as energy-loss upon collision. The first parameter affects the energy loss (gain) perpendicular to the surface. 0 means all energy (velocity) is lost, 1 means no energy is lost perpendicular to surface. The second parameter is the energy gain tangent to the surface.\n\n\n\t\t\n  gainnorm - Friction parameters which can be regarded as energy-loss upon collision. The first parameter affects the energy loss (gain) perpendicular to the surface. 0 means all energy (velocity) is lost, 1 means no energy is lost perpendicular to surface. The second parameter is the energy gain tangent to the surface.\n\n\n\n\n\n -\n -\n -\n\nExtra Information for the Spring  can be accessed via an Info CHOP.\n\n\n\n - Number of points in this . - Number of primitives in this . - Number of particles in this . - Time spent in another thread updating geometry data on the  from the 's CPU data. As it is part of another thread, this time is not part of the usual frame time. - Time spent in another thread updating meta surface geometry data (such as metaballs or nurbs) on the  from the 's CPU data. As it is part of another thread, this time is not part of the usual frame time.\n - Number of times the operator has cooked since the process started. - Duration of the last cook in milliseconds. - Frame number when this operator was last cooked relative to the component timeline. - Frame number when this operator was last cooked relative to the absolute time. - Time in milliseconds at which the operator started cooking in the frame it was cooked. - Time in milliseconds at which the operator finished cooking in the frame it was cooked. - 1 if operator was cooked this frame. - Number of warnings in this operator if any. - Number of errors in this operator if any.\nTouchDesigner Build: Latest\\n2021.100002018.28070before 2018.28070\nSOPs\n• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • \n\nA Operator Family that reads, creates and modifies 3D points, polygons, lines, particles, surfaces, spheres and meatballs. Particles and point clouds are now done primarily on the GPU using TOPs.\n\n\n\nThe Frames-per-Second that TouchDesigner's Timeline runs at. Set with project.cookRate.\n\n\n\nEach SOP has a list of Points. Each point has an XYZ 3D position value plus other optional attributes. Each polygon Primitive is defined by a vertex list, which is list of point numbers.\n\n\n\nTo \"pulse\" a parameter is to send it a signal from (1) an exported CHOP channel or (2) a python command or (3) a mouse click that causes a new action to occur immediately. A pulse via python is via the .pulse() function on a pulse-type parameter, such as Reset parameter in a Speed CHOP. A pulse from a CHOP is typically a 0 to 1 to 0 signal in an exported channel.\n\n\n\nAn Operator Family which operate on Channels (a sequence of numbers (Samples)) which are used for animation, audio, mathematics, simulation, logic, UI construction, and data streamed from/to devices and protocols.\n\n\n\nThe Graphics Processing Unit. This is the high-speed, many-core processor of the graphics card/chip that takes geometry, images and data from the CPU and creates images and processed data.\n\n\n\n\n\n\n\n\nRetrieved from \"https://docs.derivative.ca/index.php?title=Spring_SOP&oldid=27192\"\n\t\tCategory: SOPs",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.886Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Preroll Time",
      "label": "Preroll Time",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "From Derivative\n\t\t\n\t\t\n\t\t\n\t\t\n\t\tJump to navigation\n\t\tJump to search\n\t\t\nThe Spring  deforms and moves the input geometry using spring \"forces\" on the edges of polygons and on masses attached to each point.\t\t\nGeometry is deformed using forces that simulate simple physics on the points and edges. A simulated \"mass\" is assigned to each point. Its primitive edges act as \"springs\" which oppose the forces, and pull the points back toward their original positions. When the springs are stretched by the forces, they try to pull the points back. The points do not stop moving when they return to their original positions, however, but continue to oscillate because of their mass, until the oscillation dies out.\t\t\t\nForces which act upon the points are as follows:\t\t\t\n\nexternal force (gravity)\nwind (similar to external force)\nturbulence (chaotic forces)The greater the drag value, or smaller the mass, the faster the oscillation dies out.\nspringSOP_Class\n\nContents\n \n \n \n \n \n \n \n \n \n\n\n\n\n\n  timepreroll - How many seconds of the simulation to bypass, after the reset time is reached. For example, if you put the number 33 into this field (and reset is at $TSTART), frame one will show the simulation that was at a time of 33 seconds. In other words, the first thirty-two seconds have been bypassed, and the time at thirty-three seconds is shifted to frame one. The first thirty-two seconds must still be calculated in order to compute the status of the points, so you will notice some delay upon reset.\n\n\n\t\t\n  timeinc - The  parameter determines how often to cook the . By default, this parameter is set to 1/$. This means that the  will cook once for every frame. When complex dynamics are involved, the  may require more frequent cooking for increased mathematical accuracy. To get sub-frame accuracy in the cooking, set the  to something smaller than 1/$ . For example, setting the  to 0.5/$ will mean that the  gets cooked twice for every frame.\t\nNote: Never set this parameter greater than 1/$.\n\n\n\t\t\n  accurate - This option makes the nodes move more accurately between frames by calculating their trajectories for fractional frame values.\n\n\n\t\t\n  attractmode -  - Describes how attractor points are assigned to each particle.\n\n all - All point attractors affect all particles (or points). single - When enabled, each particle is assigned a single attractor point, and is affected by only that point. Assignment is done by point number modulo the total number of attractor points.\n\t\t\n  reset - While On resets the spring effect of the .\n\n\n\t\t\n  resetpulse - Instantly reset the spring effect.\n\n\n\n\n\n  external -  - Forces of gravity acting on the points. When drag is zero, the points can accelerate with no limit on their speed.\n\n externalx - externaly - externalz -\n\t\t\n  wind -  - Wind forces acting on the points. Similar to external force. Using wind (and no other forces, such as turbulence), the points will not exceed the wind velocity.\n\n windx - windy - windz -\n\t\t\n  turb -  - The amplitude of turbulent (chaotic) forces along each axis. Use positive values, if any.\n\n turbx - turby - turbz -\n\t\t\n  period - A small period means that the turbulence varies quickly over a small area, while a larger value will cause points close to each other to be affected similarly.\n\n\n\t\t\n  seed - Random number seed for the simulation.\n\n\n\n\n\n  fixed - This is a point group. All points in the point group will remain unaffected by the forces. Also see the Group SOP for notes on how to specify point ranges.\n\n\n\t\t\n  revertfixed - Determines whether or not points in the  group should be moved to the positions of the corresponding points in the Source geometry.\n\n\n\t\t\n  copygroups - Determines if the Spring  should copy groups from the Source geometry at each frame. This lets you specify the name of an animating group in the  field, and the contents of this group will be kept up to date.\n\n\n\t\t\n  domass - When selected, the  is computed for the deforming geometry.\n\n\n\t\t\n  mass -  of each point. Heavier points take longer to get into motion, and longer to stop.\n\n\n\t\t\n  dodrag - When selected, the geometry is deformed by the  attribute.\n\n\n\t\t\n  drag -  of each point.\n\n\n\t\t\n  springbehavior -  - How the springs will behave:\n\n hooke - Springs will work according to Hooke's Law. This is generally more stable than .Hooke's Law: Force = Displacement  Spring constant normalize - Similar to  except that the displacement is normalized to the original length of the Spring.\n\t\t\n  springk - The spring constant. How tight the springs are. Increase this value to make the springs tighter and thus make the object more rigid. As this number becomes higher, the springs can oscillate out of control. Decrease the  if this happens.\n\n\n\t\t\n  tension - The Initial k constant of the geometry before being deformed by the spring operation.\n\n\n\n\n\n  limitpos -  - The points will bounce off the limit planes when it reaches them. The six limit plane fields define a bounding cube. The default settings are one thousand units away, which is very large. Reduce the values to about one to see the effect.\n\n limitposx - limitposy - limitposz -\n\t\t\n  limitneg -  - The points will bounce off the limit planes when it reaches them. The six limit plane fields define a bounding cube. The default settings are one thousand units away, which is very large. Reduce the values to about one to see the effect.\n\n limitnegx - limitnegy - limitnegz -\n\t\t\n  hit -  - Control over what happens when the geometry hits either the six collision planes or the collision object. The options are:\n\n bounce - Geometry will bounce upon contact with the Collision input. stick - Geometry will stick to the Collision input upon contact.\n\t\t\n  gaintan - Friction parameters which can be regarded as energy-loss upon collision. The first parameter affects the energy loss (gain) perpendicular to the surface. 0 means all energy (velocity) is lost, 1 means no energy is lost perpendicular to surface. The second parameter is the energy gain tangent to the surface.\n\n\n\t\t\n  gainnorm - Friction parameters which can be regarded as energy-loss upon collision. The first parameter affects the energy loss (gain) perpendicular to the surface. 0 means all energy (velocity) is lost, 1 means no energy is lost perpendicular to surface. The second parameter is the energy gain tangent to the surface.\n\n\n\n\n\n -\n -\n -\n\nExtra Information for the Spring  can be accessed via an Info CHOP.\n\n\n\n - Number of points in this . - Number of primitives in this . - Number of particles in this . - Time spent in another thread updating geometry data on the  from the 's CPU data. As it is part of another thread, this time is not part of the usual frame time. - Time spent in another thread updating meta surface geometry data (such as metaballs or nurbs) on the  from the 's CPU data. As it is part of another thread, this time is not part of the usual frame time.\n - Number of times the operator has cooked since the process started. - Duration of the last cook in milliseconds. - Frame number when this operator was last cooked relative to the component timeline. - Frame number when this operator was last cooked relative to the absolute time. - Time in milliseconds at which the operator started cooking in the frame it was cooked. - Time in milliseconds at which the operator finished cooking in the frame it was cooked. - 1 if operator was cooked this frame. - Number of warnings in this operator if any. - Number of errors in this operator if any.\nTouchDesigner Build: Latest\\n2021.100002018.28070before 2018.28070\nSOPs\n• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • \n\nA Operator Family that reads, creates and modifies 3D points, polygons, lines, particles, surfaces, spheres and meatballs. Particles and point clouds are now done primarily on the GPU using TOPs.\n\n\n\nThe Frames-per-Second that TouchDesigner's Timeline runs at. Set with project.cookRate.\n\n\n\nEach SOP has a list of Points. Each point has an XYZ 3D position value plus other optional attributes. Each polygon Primitive is defined by a vertex list, which is list of point numbers.\n\n\n\nTo \"pulse\" a parameter is to send it a signal from (1) an exported CHOP channel or (2) a python command or (3) a mouse click that causes a new action to occur immediately. A pulse via python is via the .pulse() function on a pulse-type parameter, such as Reset parameter in a Speed CHOP. A pulse from a CHOP is typically a 0 to 1 to 0 signal in an exported channel.\n\n\n\nAn Operator Family which operate on Channels (a sequence of numbers (Samples)) which are used for animation, audio, mathematics, simulation, logic, UI construction, and data streamed from/to devices and protocols.\n\n\n\nThe Graphics Processing Unit. This is the high-speed, many-core processor of the graphics card/chip that takes geometry, images and data from the CPU and creates images and processed data.\n\n\n\n\n\n\n\n\nRetrieved from \"https://docs.derivative.ca/index.php?title=Spring_SOP&oldid=27192\"\n\t\tCategory: SOPs",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.888Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Preroll Time",
      "label": "Preroll Time",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "The Spring  deforms and moves the input geometry using spring \"forces\" on the edges of polygons and on masses attached to each point.\t\t\nGeometry is deformed using forces that simulate simple physics on the points and edges. A simulated \"mass\" is assigned to each point. Its primitive edges act as \"springs\" which oppose the forces, and pull the points back toward their original positions. When the springs are stretched by the forces, they try to pull the points back. The points do not stop moving when they return to their original positions, however, but continue to oscillate because of their mass, until the oscillation dies out.\t\t\t\nForces which act upon the points are as follows:\t\t\t\n\nexternal force (gravity)\nwind (similar to external force)\nturbulence (chaotic forces)The greater the drag value, or smaller the mass, the faster the oscillation dies out.\nspringSOP_Class\n\nContents\n \n \n \n \n \n \n \n \n \n\n\n\n\n\n  timepreroll - How many seconds of the simulation to bypass, after the reset time is reached. For example, if you put the number 33 into this field (and reset is at $TSTART), frame one will show the simulation that was at a time of 33 seconds. In other words, the first thirty-two seconds have been bypassed, and the time at thirty-three seconds is shifted to frame one. The first thirty-two seconds must still be calculated in order to compute the status of the points, so you will notice some delay upon reset.\n\n\n\t\t\n  timeinc - The  parameter determines how often to cook the . By default, this parameter is set to 1/$. This means that the  will cook once for every frame. When complex dynamics are involved, the  may require more frequent cooking for increased mathematical accuracy. To get sub-frame accuracy in the cooking, set the  to something smaller than 1/$ . For example, setting the  to 0.5/$ will mean that the  gets cooked twice for every frame.\t\nNote: Never set this parameter greater than 1/$.\n\n\n\t\t\n  accurate - This option makes the nodes move more accurately between frames by calculating their trajectories for fractional frame values.\n\n\n\t\t\n  attractmode -  - Describes how attractor points are assigned to each particle.\n\n all - All point attractors affect all particles (or points). single - When enabled, each particle is assigned a single attractor point, and is affected by only that point. Assignment is done by point number modulo the total number of attractor points.\n\t\t\n  reset - While On resets the spring effect of the .\n\n\n\t\t\n  resetpulse - Instantly reset the spring effect.\n\n\n\n\n\n  external -  - Forces of gravity acting on the points. When drag is zero, the points can accelerate with no limit on their speed.\n\n externalx - externaly - externalz -\n\t\t\n  wind -  - Wind forces acting on the points. Similar to external force. Using wind (and no other forces, such as turbulence), the points will not exceed the wind velocity.\n\n windx - windy - windz -\n\t\t\n  turb -  - The amplitude of turbulent (chaotic) forces along each axis. Use positive values, if any.\n\n turbx - turby - turbz -\n\t\t\n  period - A small period means that the turbulence varies quickly over a small area, while a larger value will cause points close to each other to be affected similarly.\n\n\n\t\t\n  seed - Random number seed for the simulation.\n\n\n\n\n\n  fixed - This is a point group. All points in the point group will remain unaffected by the forces. Also see the Group SOP for notes on how to specify point ranges.\n\n\n\t\t\n  revertfixed - Determines whether or not points in the  group should be moved to the positions of the corresponding points in the Source geometry.\n\n\n\t\t\n  copygroups - Determines if the Spring  should copy groups from the Source geometry at each frame. This lets you specify the name of an animating group in the  field, and the contents of this group will be kept up to date.\n\n\n\t\t\n  domass - When selected, the  is computed for the deforming geometry.\n\n\n\t\t\n  mass -  of each point. Heavier points take longer to get into motion, and longer to stop.\n\n\n\t\t\n  dodrag - When selected, the geometry is deformed by the  attribute.\n\n\n\t\t\n  drag -  of each point.\n\n\n\t\t\n  springbehavior -  - How the springs will behave:\n\n hooke - Springs will work according to Hooke's Law. This is generally more stable than .Hooke's Law: Force = Displacement  Spring constant normalize - Similar to  except that the displacement is normalized to the original length of the Spring.\n\t\t\n  springk - The spring constant. How tight the springs are. Increase this value to make the springs tighter and thus make the object more rigid. As this number becomes higher, the springs can oscillate out of control. Decrease the  if this happens.\n\n\n\t\t\n  tension - The Initial k constant of the geometry before being deformed by the spring operation.\n\n\n\n\n\n  limitpos -  - The points will bounce off the limit planes when it reaches them. The six limit plane fields define a bounding cube. The default settings are one thousand units away, which is very large. Reduce the values to about one to see the effect.\n\n limitposx - limitposy - limitposz -\n\t\t\n  limitneg -  - The points will bounce off the limit planes when it reaches them. The six limit plane fields define a bounding cube. The default settings are one thousand units away, which is very large. Reduce the values to about one to see the effect.\n\n limitnegx - limitnegy - limitnegz -\n\t\t\n  hit -  - Control over what happens when the geometry hits either the six collision planes or the collision object. The options are:\n\n bounce - Geometry will bounce upon contact with the Collision input. stick - Geometry will stick to the Collision input upon contact.\n\t\t\n  gaintan - Friction parameters which can be regarded as energy-loss upon collision. The first parameter affects the energy loss (gain) perpendicular to the surface. 0 means all energy (velocity) is lost, 1 means no energy is lost perpendicular to surface. The second parameter is the energy gain tangent to the surface.\n\n\n\t\t\n  gainnorm - Friction parameters which can be regarded as energy-loss upon collision. The first parameter affects the energy loss (gain) perpendicular to the surface. 0 means all energy (velocity) is lost, 1 means no energy is lost perpendicular to surface. The second parameter is the energy gain tangent to the surface.\n\n\n\n\n\n -\n -\n -\n\nExtra Information for the Spring  can be accessed via an Info CHOP.\n\n\n\n - Number of points in this . - Number of primitives in this . - Number of particles in this . - Time spent in another thread updating geometry data on the  from the 's CPU data. As it is part of another thread, this time is not part of the usual frame time. - Time spent in another thread updating meta surface geometry data (such as metaballs or nurbs) on the  from the 's CPU data. As it is part of another thread, this time is not part of the usual frame time.\n - Number of times the operator has cooked since the process started. - Duration of the last cook in milliseconds. - Frame number when this operator was last cooked relative to the component timeline. - Frame number when this operator was last cooked relative to the absolute time. - Time in milliseconds at which the operator started cooking in the frame it was cooked. - Time in milliseconds at which the operator finished cooking in the frame it was cooked. - 1 if operator was cooked this frame. - Number of warnings in this operator if any. - Number of errors in this operator if any.\nTouchDesigner Build: Latest\\n2021.100002018.28070before 2018.28070\nSOPs\n• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • \n\nA Operator Family that reads, creates and modifies 3D points, polygons, lines, particles, surfaces, spheres and meatballs. Particles and point clouds are now done primarily on the GPU using TOPs.\n\n\n\nThe Frames-per-Second that TouchDesigner's Timeline runs at. Set with project.cookRate.\n\n\n\nEach SOP has a list of Points. Each point has an XYZ 3D position value plus other optional attributes. Each polygon Primitive is defined by a vertex list, which is list of point numbers.\n\n\n\nTo \"pulse\" a parameter is to send it a signal from (1) an exported CHOP channel or (2) a python command or (3) a mouse click that causes a new action to occur immediately. A pulse via python is via the .pulse() function on a pulse-type parameter, such as Reset parameter in a Speed CHOP. A pulse from a CHOP is typically a 0 to 1 to 0 signal in an exported channel.\n\n\n\nAn Operator Family which operate on Channels (a sequence of numbers (Samples)) which are used for animation, audio, mathematics, simulation, logic, UI construction, and data streamed from/to devices and protocols.\n\n\n\nThe Graphics Processing Unit. This is the high-speed, many-core processor of the graphics card/chip that takes geometry, images and data from the CPU and creates images and processed data.\n\n\n\n\n\n\n\n\nRetrieved from \"https://docs.derivative.ca/index.php?title=Spring_SOP&oldid=27192\"",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.889Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Preroll Time",
      "label": "Preroll Time",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "timepreroll - How many seconds of the simulation to bypass, after the reset time is reached. For example, if you put the number 33 into this field (and reset is at $TSTART), frame one will show the simulation that was at a time of 33 seconds. In other words, the first thirty-two seconds have been bypassed, and the time at thirty-three seconds is shifted to frame one. The first thirty-two seconds must still be calculated in order to compute the status of the points, so you will notice some delay upon reset.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.889Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Time Inc",
      "label": "Time Inc",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "timeinc - The  parameter determines how often to cook the . By default, this parameter is set to 1/$. This means that the  will cook once for every frame. When complex dynamics are involved, the  may require more frequent cooking for increased mathematical accuracy. To get sub-frame accuracy in the cooking, set the  to something smaller than 1/$ . For example, setting the  to 0.5/$ will mean that the  gets cooked twice for every frame.\t\nNote: Never set this parameter greater than 1/$.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.889Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Accurate Moves",
      "label": "Accurate Moves",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "accurate - This option makes the nodes move more accurately between frames by calculating their trajectories for fractional frame values.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.889Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Attractor Use",
      "label": "Attractor Use",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "attractmode -  - Describes how attractor points are assigned to each particle.\n\n all - All point attractors affect all particles (or points). single - When enabled, each particle is assigned a single attractor point, and is affected by only that point. Assignment is done by point number modulo the total number of attractor points.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "All Points",
      "label": "All Points",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "all - All point attractors affect all particles (or points). single - When enabled, each particle is assigned a single attractor point, and is affected by only that point. Assignment is done by point number modulo the total number of attractor points.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Reset",
      "label": "Reset",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "reset - While On resets the spring effect of the .",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Reset Pulse",
      "label": "Reset Pulse",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "resetpulse - Instantly reset the spring effect.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "External Force",
      "label": "External Force",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "external -  - Forces of gravity acting on the points. When drag is zero, the points can accelerate with no limit on their speed.\n\n externalx - externaly - externalz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "X",
      "label": "X",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "externalx - externaly - externalz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Wind",
      "label": "Wind",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "wind -  - Wind forces acting on the points. Similar to external force. Using wind (and no other forces, such as turbulence), the points will not exceed the wind velocity.\n\n windx - windy - windz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "X",
      "label": "X",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "windx - windy - windz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Turbulence",
      "label": "Turbulence",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "turb -  - The amplitude of turbulent (chaotic) forces along each axis. Use positive values, if any.\n\n turbx - turby - turbz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "X",
      "label": "X",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "turbx - turby - turbz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Turb Period",
      "label": "Turb Period",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "period - A small period means that the turbulence varies quickly over a small area, while a larger value will cause points close to each other to be affected similarly.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Seed",
      "label": "Seed",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "seed - Random number seed for the simulation.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Fixed Points",
      "label": "Fixed Points",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "fixed - This is a point group. All points in the point group will remain unaffected by the forces. Also see the Group SOP for notes on how to specify point ranges.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Fixed Points go to Source Positions",
      "label": "Fixed Points go to Source Positions",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "revertfixed - Determines whether or not points in the  group should be moved to the positions of the corresponding points in the Source geometry.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Copy Groups from Source",
      "label": "Copy Groups from Source",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "copygroups - Determines if the Spring  should copy groups from the Source geometry at each frame. This lets you specify the name of an animating group in the  field, and the contents of this group will be kept up to date.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Add Mass Attribute",
      "label": "Add Mass Attribute",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "domass - When selected, the  is computed for the deforming geometry.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Mass",
      "label": "Mass",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "mass -  of each point. Heavier points take longer to get into motion, and longer to stop.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Add Drag Attribute",
      "label": "Add Drag Attribute",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "dodrag - When selected, the geometry is deformed by the  attribute.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Drag",
      "label": "Drag",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "drag -  of each point.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Spring Behavior",
      "label": "Spring Behavior",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "springbehavior -  - How the springs will behave:\n\n hooke - Springs will work according to Hooke's Law. This is generally more stable than .Hooke's Law: Force = Displacement  Spring constant normalize - Similar to  except that the displacement is normalized to the original length of the Spring.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Hooke's Law",
      "label": "Hooke's Law",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "hooke - Springs will work according to Hooke's Law. This is generally more stable than .Hooke's Law: Force = Displacement  Spring constant normalize - Similar to  except that the displacement is normalized to the original length of the Spring.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Spring Constant",
      "label": "Spring Constant",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "springk - The spring constant. How tight the springs are. Increase this value to make the springs tighter and thus make the object more rigid. As this number becomes higher, the springs can oscillate out of control. Decrease the  if this happens.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.890Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Initial Tension",
      "label": "Initial Tension",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "tension - The Initial k constant of the geometry before being deformed by the spring operation.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "+ Limit Plane",
      "label": "+ Limit Plane",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "limitpos -  - The points will bounce off the limit planes when it reaches them. The six limit plane fields define a bounding cube. The default settings are one thousand units away, which is very large. Reduce the values to about one to see the effect.\n\n limitposx - limitposy - limitposz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "X",
      "label": "X",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "limitposx - limitposy - limitposz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "- Limit Plane",
      "label": "- Limit Plane",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "limitneg -  - The points will bounce off the limit planes when it reaches them. The six limit plane fields define a bounding cube. The default settings are one thousand units away, which is very large. Reduce the values to about one to see the effect.\n\n limitnegx - limitnegy - limitnegz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "X",
      "label": "X",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "limitnegx - limitnegy - limitnegz -",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Hit Behavior",
      "label": "Hit Behavior",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "hit -  - Control over what happens when the geometry hits either the six collision planes or the collision object. The options are:\n\n bounce - Geometry will bounce upon contact with the Collision input. stick - Geometry will stick to the Collision input upon contact.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Bounce on Contact",
      "label": "Bounce on Contact",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "bounce - Geometry will bounce upon contact with the Collision input. stick - Geometry will stick to the Collision input upon contact.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Gain Tangent",
      "label": "Gain Tangent",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "gaintan - Friction parameters which can be regarded as energy-loss upon collision. The first parameter affects the energy loss (gain) perpendicular to the surface. 0 means all energy (velocity) is lost, 1 means no energy is lost perpendicular to surface. The second parameter is the energy gain tangent to the surface.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    },
    {
      "id": null,
      "name": "Gain Normal",
      "label": "Gain Normal",
      "group": "General",
      "page": "",
      "type": "float",
      "dataType": "number",
      "style": "",
      "defaultValue": null,
      "minValue": null,
      "maxValue": null,
      "step": null,
      "menuItems": [],
      "menuLabels": [],
      "allowCustom": false,
      "maxLength": null,
      "pattern": null,
      "isArray": false,
      "arraySize": 1,
      "dimensions": 1,
      "description": "gainnorm - Friction parameters which can be regarded as energy-loss upon collision. The first parameter affects the energy loss (gain) perpendicular to the surface. 0 means all energy (velocity) is lost, 1 means no energy is lost perpendicular to surface. The second parameter is the energy gain tangent to the surface.",
      "tooltip": "",
      "help": "",
      "units": "",
      "examples": [],
      "isReadOnly": false,
      "isAdvanced": false,
      "isHidden": false,
      "isAnimatable": true,
      "isExpression": false,
      "isPython": false,
      "dependsOn": [],
      "affects": [],
      "linkedTo": [],
      "expressionLanguage": "",
      "defaultExpression": "",
      "commonExpressions": [],
      "order": 0,
      "isVisible": true,
      "conditionalDisplay": null,
      "isValid": true,
      "validationErrors": [],
      "lastUpdated": "2025-08-07T07:50:09.891Z",
      "rawData": {},
      "sourceElement": null
    }
  ],
  "parameterGroups": {},
  "codeExamples": [],
  "pythonExamples": [],
  "expressions": [],
  "commonInputs": [],
  "commonOutputs": [],
  "relatedOperators": [],
  "workflowPatterns": [],
  "images": [],
  "videos": [],
  "assets": [],
  "keywords": [
    "spring",
    "sop",
    "deforms",
    "moves",
    "input",
    "geometry",
    "using",
    "\"forces\"",
    "edges",
    "polygons"
  ],
  "tags": [
    "SOP",
    "TouchDesigner",
    "Spring SOP"
  ],
  "searchWeight": 1,
  "contentHash": "",
  "processingDate": "2025-08-07T07:50:09.892Z",
  "processingVersion": "1.0.0",
  "isValid": true,
  "validationErrors": []
}