The name of this video is 3D surface matrix attractor pinch. So this is the last in our series of 3D surface attractor videos. In this one we're going to look at how we could use a attractor point to pinch the underlying grid of the matrix. So how to get the grid itself to be attracted to a point location. Now there's a couple of problems associated with this. One is that, not only do I need to have those points, those grid points, pulled towards that attractor point, but I also have to have them remain on the surface if I want to maintain the integrity of that initial base geometry. Let's look at our code. Looks pretty much like the other ones, but then it has a whole section that changes within the loop. So, how we do this, what we're going to do is we've added this pulled point code and what I'm going do is find the distance between each point within the matrix, let's say if I had a point on a corner here. So I'm going to find the distance to that attractor point and I'm going to use the pull point function, to find a point between those two points based on that distance. But then I'm also going to have to divide that distance by something, So because I'm using a distance as a load between the two points and finding a new point between them again, that point is then going to be up in the air between those two points. So I'm going to have to relocate that point onto the surface. So that's the second step in the problem. The other problem too is that if I want to maintain the boundary of my base geometry, I'm not going to want those edge points to change, I'm going to want them to just stay where they are so I can maintain that, the integrity of that boundary. Let's take a look at how we do that. So here's my pulled point function, which we went over earlier under functions and that we've used in a couple of codes, it just takes two points and two load values. Within this loop, I'm going to find the distance between the attractor point and the point within the matrix. Here what I'm saying is if i is zero or if i is at its maximum, these are my edge conditions and the same for j. When j is zero or j is at the maximum, those then are my points on my edges. So if we have those conditions, then just let the point p equal to itself. So keep the point where it is. That's all those lines of code are doing in that conditional. They're just testing to see If it's an edge point. If it's an edge point, just keep it where it is. If it's not an edge point, then set it equal to uphold point, that's using the attractor point, it's using the current point within the matrix. It's putting a one load on the attractor point and then it's putting a load based on the distance value. In this case, I've divided it by four on the matrix point. So it's pulling it closer to the matrix point. Then we're going just add that new point here. If we turn on here we can. So we're adding our original points and then we're adding these new loaded points, pulled points. Let's go ahead and run that. So select the surface, select the attractor point, ( 8, 8) interval. Now let's unhide our surface. So here we can see this is our original points which are still on our surface and then we have these new points which are, I can see they're being pulled towards that attractor point, but they're all off of the surface. I could still use them like that, but I don't want to. I want to have them back on that surface and that'll introduce us to a new function. If you want I could run this again so we can see that a little clearer. I'll actually turn off that the original point grid and we'll just run the new point grid. It's there, now you can see there it's working. It's pinching the grid, but they're either above or below that surface. Also my edge points are staying on that edge where they should be. Let's see how we can get the points on the surface. So I can use a function called BRepClosestPoint. Now if you haven't heard the term BRep before, what that refers to is Boundary Representation, which is another term for a NURB surface and BRepClosestPoint takes the surface in and then it takes the point that I'm testing and it's returning something called a closest point. Now, we want to look at this function and the help, because it returns things in an unusual way. We have seen this before, I think in the centroid function. The centroid returns a series of elements in a list. This one's unique in terms of one we haven't seen before is that, it returns a list of things which also contain tuples or lists too and so we can see how to access those. As the parameters is just taking that surface and it's taking a point, I've given it that and then what I want to get back from it is the 3D point on the surface. So that's being held in index value 0. In order to get that, I need to write it in this way. What I'm doing is just replacing the point here, with this closest point that's being returned in index 0. So that's just returning the point value and then I'm going to plot that out. So let's see what that does. Now, you can see my points are now on that surface. Now let's create some geometry with this. Go back down here to my loop and let's create our bottom curve, because we haven't created our top matrici yet or our surface normal matrici. So it's creating, its working, it's creating that pinched geometry. Now we can't create our top curb yet because we don't have our surface normal matrici yet, so we have to look at that here. We cannot undo this. There's one thing I need to change. This was originally our u, v parameter. The problem with that is that our u, v parameter's changed. It's no longer this up here because the point has been repositioned, so where my u, v parameter for this point is, is now a different in a different location. Well, if we look at our BRepClosestPoint function again, we'll see that in its second index slot, it returns the parameter value of that closest point that it's found. So it has that u, v parameter as a tuple right there. Now all I need to do is replace this u, v here, with closest point, but not index 1, which is the 3D point. I need it to be index or excuse me, not index 0, I needed to be index 1, which is the u, v parameter. So it's adding those points and it'll add a line here, so let's run that before we create geometry and make sure it's working. Attractor point. Yes, now it's creating its vector normals at those u, v points on that surface, now we can turn on rest of this code here and even at our loft surface back. So we're creating a pinch geometry. Now if I change that value, the divider that I have in the distance here, this value, if that gets to be a lower number, then I'm going to create a less severe pinch. If I input a higher number, then a more severe pinch.