Python Tutorials | (back to the list of tutorials) |
The code below shows a method to convert line geometries in a tensile line network by the method ITensileNet.create(lines, fixedPoints). In the code, all the lines and all the points in the file are fed into the method and lines become tension lines creating particles at every end points and points become fixing points if they are on the end points of the lines.
The input Rhino file used in the example is this one below.
add_library('igeo') size(480, 360, IG.GL) IG.open("lines1.3dm") ITensileNet.create(IG.curves(), IG.points())
This image is before applying tension.
The below is after applying tension.
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.open("lines1.3dm") ITensileNet.create(IG.curves(), IG.points()) Gravity(IG.v(0.1, 0, 0)) #gravity toward x direction Attractor(IG.v(7, 7, 7)).clr(1.0, 0, 0) class Gravity(IAgent) : def __init__(self, g) : self.gravity = g def interact(self, agents) : for agent in agents : if isinstance(agent, IParticle) : agent.push(self.gravity) class Attractor(IPointAgent) : def __init__(self, p) : IPointAgent.__init__(self,p) def interact(self, agents) : attraction = -0.05 threshold = 9 for agent in agents : if isinstance(agent, IParticle) : dist = agent.pos().dist(self.pos()) if dist < threshold : frc = self.pos().dif(agent.pos()) frc.len( (threshold - dist) * attraction ) agent.push(frc)
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.open("lines1.3dm") ITensileNet.tension(50) #strength of tension line ITensileNet.friction(0.05) #friction of particles ITensileNet.tolerance(0.01) #tolerance to judge if 2 end points are connected ITensileNet.fixOpenEnd(False) #fixing open end line or not ITensileNet.pointColor(0,0,1.0) #color of particle points ITensileNet.pointLayer("tension node") #layer to put particle points ITensileNet.fixedPointColor(0,1.0,1.0) #color of fixed particle points ITensileNet.fixedPointLayer("fixed node") #layer to put fixed particle points ITensileNet.create(IG.curves(), IG.points())
The input Rhino file used in the example is this one below.
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.open("lines2.3dm") ITensileNet.particleFactory(ParticleFactory())#custom particle class ITensileNet.create(IG.curves(), IG.points()) Gravity(IG.v(0, 0, 0.5)) #gravity toward z class MyBoid(IBoid) : def __init__(self, pos, vel) : IBoid.__init__(self,pos,vel) self.cohesionDist(2) self.cohesionRatio(1) self.separationDist(4) self.separationRatio(2) self.alignmentDist(5) self.alignmentRatio(3) def update(self) : if IRand.pct(2.0) : #random occasion of 2% self.push(IRand.pt(-50,-50,-50,50,50,50)) #random force class ParticleFactory(IParticleFactory): def create(self, pos, vel): return MyBoid(pos,vel) class Gravity(IAgent) : def __init__(self, g) : self.gravity = g def interact(self, agents) : for agent in agents : if isinstance(agent, IParticle) : agent.push(self.gravity)
Initial state.
After simulation.
The input Rhino file used in the example is this one below.
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.open("lines3.3dm") IG.duration(500) ITensileNet.tensionFactory(TensionFactory()) #custom tension class ITensileNet.create(IG.curves(), IG.points()) Gravity(IG.v(0, 0, 5)) #gravity toward z class MyTension(ITensionLine) : def __init__(self, p1, p2, tension) : ITensionLine.__init__(self, p1, p2, tension) def update(self) : if IG.time()%10==0 : p1 = self.pos1().cp() p2 = self.pos2().cp() ICurve(p1, p2).clr(IG.time()*0.002) class TensionFactory(ITensionFactory) : def create(self, p1, p2, tension) : return MyTension(p1,p2,tension) class Gravity(IAgent) : def __init__(self, g) : self.gravity = g def interact(self, agents) : for agent in agents : if isinstance(agent, IParticle) : agent.push(self.gravity)
Initial state.
After simulation.
The code below is putting polygon mesh geometries instead of lines. Using the current two points of a tension line and the previous two points of the line, it forms a rectangular shape. On top of this rectangle, thickness is added creating total eight points and then these eight points are fed into IG.meshBox().
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.open("lines3.3dm") IG.duration(500) ITensileNet.tensionFactory(TensionFactory()) #custom tension class ITensileNet.create(IG.curves(), IG.points()) Gravity(IG.v(0, 0, 5)) #gravity toward z class MyTension(ITensionLine) : def __init__(self, p1, p2, tension) : ITensionLine.__init__(self, p1, p2, tension) self.prevPos1 = None self.prevPos2 = None def update(self) : thickness = 0.8 if IG.time()%15==0 : p1 = self.pos1().cp() p2 = self.pos2().cp() if self.prevPos1 is not None and self.prevPos2 is not None and IRand.pct(80) : if not self.prevPos1.eq(p1) and not self.prevPos2.eq(p2) : #only when moved # mesh slab (box) hdir1 = p2.dif(p1) hdir2 = self.prevPos2.dif(self.prevPos1) vdir1 = p1.dif(self.prevPos1) vdir2 = p2.dif(self.prevPos2) if p1.eq(self.prevPos1) : vdir1 = vdir2 #avoid zero vector if p2.eq(self.prevPos2) : vdir2 = vdir1 #avoid zero vector v1 = p1.cp().add(hdir1.cross(vdir1).len(thickness/2)) v2 = p2.cp().add(hdir1.cross(vdir2).len(thickness/2)) v3 = self.prevPos2.cp().add(hdir2.cross(vdir2).len(thickness/2)) v4 = self.prevPos1.cp().add(hdir2.cross(vdir1).len(thickness/2)) v5 = p1.cp().sub(hdir1.cross(vdir1).len(thickness/2)) v6 = p2.cp().sub(hdir1.cross(vdir2).len(thickness/2)) v7 = self.prevPos2.cp().sub(hdir2.cross(vdir2).len(thickness/2)) v8 = self.prevPos1.cp().sub(hdir2.cross(vdir1).len(thickness/2)) IG.meshBox(v1,v2,v3,v4,v5,v6,v7,v8).clr(IG.time()*0.002) self.prevPos1 = p1 self.prevPos2 = p2 class TensionFactory(ITensionFactory) : def create(self, p1, p2, tension) : return MyTension(p1,p2,tension) class Gravity(IAgent) : def __init__(self, g) : self.gravity = g def interact(self, agents) : for agent in agents : if isinstance(agent, IParticle) : agent.push(self.gravity)