Houdini Algorithmic Live #104 - Developable Surface

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay hello can you hear me can you hear me so this is saturday night um i'd like to start a tutorial live for houdini for this week this is the series called within your algorithmic life and today is 104th episode the topic is about to implement the paper called developability of triangle meshes to create a developable surface from input mesh geometry okay and so today is more like a paper implementation day for me and this is one of the paper that i was into for a long time i wasn't really ready to do the implementation because of the lack of geometrical um knowledge but now i have tried and seems i it seems i have made it um just the central part of the and paper but it seems to work as it should be so i would like to share what i have done so far um what i have implemented from the paper is mainly two things one is to calculate the evaluate the energy in order to create a developer for surface there are two main major energy explained this paper and i'm just going to explain one of the energy implementation on houdini and then another stuff that i have implemented is to [Music] for is the optimization uh in order to find out the best time step to do the optimization okay using a linear search but i don't i what i didn't really look into [Music] those different types of linear search i just implemented my dirty version of my implement linear search so i don't think my optimization stuff is that optimized well but still works for any resolutions of meshes so i'll just tell you that and if you are really into this kind of stuff optimization stuff then you could look into different types of linear search or optimization method to implement for yourself okay and i am also skipping a lot of like tips explained in the paper in order to make uh the best version of uh developable surface in order to like avoid like a flat surface or double surface stick together or pointy uh meshes and so on um so yeah i'm i'm going to skip all those stuff but if you are into it then again after implementing this implementing this essential part of the paper i think you could just add several conditions to make it more developable or more clean mesh okay well i just thought putting the essential part is the most important things in this paper so that's what i'm gonna show you how uh to do that okay so you could go to this webpage on the canon crane website the project is called the vulpability of triangle meshes which is the paper from siggraph 2018. you can download the paper in pdf from here there's a video also as well explaining the the the possibility and the basic method how you're going to calculate energy and there's also a code which you can download to test out for yourself and c plus plus in github which i couldn't build myself on a mac os uh environment so i didn't really i couldn't really tried it out my myself but it will be interesting to see this as well maybe later since it's using live fee live levi gl library for c plus plus which is a geometrical processing library which i never used myself so the code explained in this code and this repository is a bit too much for me maybe i should really look into it in order to create like several conditions explained in the paper but for today we're just looking at the paper to try to implement what it says as an essential stuff right so uh let's look into this and this is kind of a result that we're going to get today first you input the mesh any kind of resolution in any kind of resolutions and i am going to use the solver to implement the one explained in paper and inside the solver you have a bunch of node this is where you are calculating the energy in order to estimate which part should be developed develop a light developer lies in order to make it developable so this is where you calculate the energy and this is where you are doing the optimization using the the dirty linear search implementation that i did okay i'm going to explain it later and using the solver you can see the results step by step on each frame and this is what you're going to get out of the result of implementing the paper and i think it would work in any kind of mesh you could also try with this kind of um rubber toy geometry as well you could it could still work and the speed is pretty decent i think because we're using vex most of the time backs to per do the parallel calculations for each vertices and you see these rich edges become obvious to create a developable surface well there are some stuff which might be hard to use it as a real developable surface so there might be other way to solve this one maybe explain in paper but but just go and this is just the result of the essential implementation of the paper for example if you look at the this part you see that the surface becomes flat so there are some explanation in the paper in order to avoid this kind of uh conditions but us besides that it looks pretty nice in terms of the result so shall we do this i mean after this after implementing the basic stuff you could just go with yourself to make it improved right so going back to the paper we need to know what kind of problem we have out of the base mesh okay in order to solve the problem that we need to know what the problem is and the problem here is how we can make the surface developable developable means a surface that you can unfold to make it a flat surface okay without any distortion so in order to do that you the surface has to have some conditions and that is explained right here if you look at each vertex and if you look at the neighbor points on the specific vertex the normal map this is these points are the normal points the direction of the normal plotted on the sphere and if you if you plot all the normal direction for each neighbor points on top of the sphere um if if it is developable the the overall shape of these normal points become straight line or um the area with the zero area or just a point if it's all flat so it and if there is like curvy surface if it's a curvy surface and if if it's not developable then you'll you'll have some kind of area around here if you if i light it if you enjoy it okay sorry i just i have just okay so if the surface is not developable then what you get is okay how do i draw this thing okay it's not working forget it you get some kind of area we kind you get some kind of polygon on top of the sphere which have some area more than zero so what you want to get is the condition like this for normal distribution which is called as gauss map and in order to do that it explains two ways to calculate the energy in order to achieve this result either this hinge-like condition or a flat surface and you could going into the chapter four it explains exactly how you could calculate the energy so if you are really curious about the the detail of the conditions how it should be made you could you should read the chapter from chapter one to chapter three and the chapter four explains the detail explanation how you could calculate those energy in order to solve in order to make the mesh looks like these condition energy means some kind of a force with in order to move the point to the best position okay so it's more like a direction of the point to move with some kind of um amount right and after you have got this direction in order to move the point you also need to calculate estimate how much you should move to that direction per step and that is decided when you do the optimization part using a linear search so first of all you need you need to what you need to do is to estimate the direction and basic amount in which direction you should move the point to get this developable condition okay and the chapter 4 is explaining how you could calculate this energy and there it explains that it explains that there is two ways to calculate the energy one is to use the combinatorial with by simply looking at each point and pick a pair of meshes which sticks to this point for example if you are looking at this point pick for example pick this mesh part as one with the part and pick this mesh part as another part and calculate the conditions between two meshes in order to check if this is doable for a hinge condition and do the same for all the other pairs like this mesh and all the other mesh with these mesh pairs and these patch pairs mesh pairs and so on so you gotta look for all the pairs which is available on top of this each point now as you can imagine the calculation cost is pretty high for that energy because you have to find all the possible pairs out of each point so that's not ideal for fast optimization for fast calculations so we're going to skip that instead what we are going to look at is the second energy which is a com covariance covariance energy okay this is to estimate this is to give a condition this is the and how that explodes for example if you have a hinge like that where you have a folding angle folding axis like that there is a specific conditions available with this kind of mesh is which is first of all getting the normal direction of each face which belongs to this point so the normal is something like that okay so normal for each for faces get the normal for each faces and if the hinge is developable if this mesh is developable that means all the normal are on top of a specific plane so i'm drawing really bad but if you take this plane out and and if you take these normals out actually then all the normals are on top of the same plane consider this is x and y meaning the normal direction is a made of ax plus b y a or b could be any value but so meaning there are no z axis value used in this normal direction that's what i mean by all the normal direction is inside of the same plane so that's when you get this that's when you uh know that this mesh that you got from this point is um developable meaning foldable unfoldable okay and you could say the same for the flat mesh all in in terms of the flat mesh all the normals are facing upward like that so um any plane could fit if the one of the plane axis is in the same direction okay so that's how you can estimate um that the mesh is developable and you could check the fitness of each normal direction on a plane and if it fits well then the energy is equal to zero meaning you don't have to optimize that if the value is really big then that means if the there is an offset between each normals if the normal is not on the same plane and if the angle is really big then that means there's a lot to fix and the energy becomes really big in order to fix that so that's how it works for the this convey covariance covariance energy and it explains how you could exactly calculate that energy okay so this is where i where it explains uh the conditions so what you need to do is to first of all calculate the [Music] the dot product between the u u is the [Music] the unit normal of the plane which i am explaining the fit plane okay these this fit plane this is you okay and the normal of the surface each phase so if it is perpendicular meaning the dot product will become zero so the energy we can become also zero okay so that's where you want that's the goal in order to achieve the developable surface okay and you are also multiplying with the angle of each face in order to use the angle as a weight because when you are using mesh there is a possibility that one of the face has a really big angle so you are using that angle too kind of uh coordinate the weights like calculating the average or something like that okay and finally you are going to look for the uh minimum when the the result of this value becomes minimum then that's the goal for the covariance energy and in order to get that energy it says it explains here the energy uh i'd like all this forgot um i forgot how you call this in greek word this word can also be expressed as a smallest eigenvalue of three by three normal covariance matrix of this so a is the matrix 3 by 3 matrix and you can calculate this matrix by calculating the outer product of the phase normal multiplied by the angle for each face and add it all together then that becomes the 3x3 matrix and by calculating by getting the eigenvalue of this matrix you'll be able to get around uh three directions with three vector three eigenvectors with three eigenvalues in maximum and the minimum of these eigenvalue is the most fit direction of the fit plane so that's the one you want to get and you want that's the one the associated eigenvector is the one in order for you to calculate the the actual energy in order to optimize uh the gradient uh you know it optimize the developability well i'm not sure if you get that out of what i explained but that's the whole goal so what we need to do is to calculate this stuff okay and calculate estimate the eigenvalue and the eigenvector from three by three matrix and use that to calculate the actual energy as a gradient in order to move the point and you could get that equations going into the chapter chapter b appendix going to be 1 b [Music] 3. so b1 and b3 you will see those equations in order to calculate the actual gradient the direction in order to move the point for the best position for each step okay so that's the goal i don't know if you got it so first thing first what we need to do is to calculate the scholar value for the energy and you could do that by going back to the chapter four and where was it chapter four and this one so this is the first goal right oh yeah thanks for the comment this is called lambda okay so shall we do this enough for the explanation we should start calculating this stuff shall we so let me bring up the geometry node also save the one to the folder for today okay okay okay so um we could test out with different types of geometry uh let's go with the simple stuff first shall we um something like although it i think it is best to do it with a regular shape so maybe we'll just use the test geometry after all like test pick a big head and since we are going to solve the problem on top on top of the triangle meshes like it says in the paper this is the process for the triangle meshes so we can all use this for the quad mesh so let's make it triangle mesh first we can either do it by divide or remesh i think we want to do remesh first because this will create a kind of a uniform triangle shape which is easier for geometrical processing rather than this irregular shape irregular triangle shapes like the size is different there are some directions and so on so the condition for out of this divide node in terms of the geometrical processing in terms of geometrical processing is not that good i think so let's go with the remesh first and make the target size small enough or processing something like that okay now the texture is messed up so let's just delete the material out of this geometry i'm gonna use the attribute delete to delete the material information maybe the uv as well all right okay so let's go with this now what we wanted what we want to do is to calculate the eigenvalue and eigenvector for each point out of this matrix that's explained in chapter 4. is going to be the energy for the developable surface so let's see how we could do that okay i'm gonna put this on the side and see how we could get these information all right well i think the this calculation is pretty simple to do so let's see um first of all we need the normal direction of the face so let's create that using the normal node thank you all for coming and for the comments let me know if i'm doing something weird or something wrong i mean i don't i'm not a professional like engineer or mathematician or anything just doing this as a hobby so i know i i'm doing i think i'm doing something wrong so but so if you find it anything weird or wrong then just just tell me i'm glad to hear that okay so first i'm going to calculate the normal for each faces using the normal node with the primitive option on so that you can get the normal direction for each face which stands for this n i j k i j k stands for the vertex at i so if we are looking at the point i then this will be j this will be k for the first iterations and this will be i this will be j this will be k for the second iterations for each face that belongs to this point so we have in this case one two three four five six seven seven faces meaning you have seven iterations for this equation so you are since we have sigma here we are adding these value seven times for this points okay so which means it makes sense to do the calculation per points right let's do that point wrangle and how do we name this calculate the energy or what do i call well yeah i'll just call calculate energy okay so first thing first we want to get the neighbor primitives for each point so for this points you can get the neighbor primitives the primitive that belongs to the point by using function call point prims all right so in case of this point you get seven primitives all right then let's loop this primitive to do this calculation here okay and as a result what you want to get is the three by three matrix okay so in each iterations you're going to get some kind of three by three matrix value and add it to a global value so let's create a global variable for 3x3 matrix call a make it empty for now three by three so you have nine zeros as an initial value okay now let's go step by step first of all i would like to get this um normal direction for the face so get the face number like that and then get the direction of the normal using trim function at this primitive right now in order to do this calculation the normal vector multiplied by normal transpose of normal vector value which means normally in the paper the vector means the vertical um looks like this so let's call this n and n transpose means you have a b c okay and by multiplying these two values you get a a multiply by a a b a c b a b b [Music] b c a c b c and c okay so [Music] this will become three by three matrix and you could actually calculate this using a function in houdini called outer product which is this one there you go and if you look at the explanations um yeah same as this one you are multiplying u and v transpose to calculate uh this matrix okay so that's the function we want to use here in order to get this value so going back to the x let's call it matrix three temporal a is equal to outer product between a norm and actually there are no way to transpose the vector in back so you can just say norm again and then you will get the value it looks a bit weird but it works like that okay then what you need next is this angle value here so for this face the angle we are mentioning about is this angle right here corresponds to this i value the i point position so if this is j if this is k we what we want to get is the j i k theta same for all the other meshes so in order to do that we need to know the point position for the center and point position for the neighbor points from this primitive so let's get that first we get the num uh corresponding points from this primitive using print points then since this is always a triangle mesh we know that we have three points inside this array at all time and we know that the current point number on this point wrangle also exists inside this point list so let's remove that value out of this pts then we are left out with two points either this one or this one okay now we have point for each point on this neighbor and the center we could start calculating the angle let's get the points on these neighbors one is p t j which is the first point from this list pt k which is the second point from the list then we need to know the actual position for that point so we get the point attribute from each point and we do know the center point which is equal to at p now we have three points it's time to calculate the angle now in order to calculate the angle the angle can be [Music] retrieved by um arc cosine of a vector a c dot a b [Music] and you also want to normalize this how do i normalize this right now and this is or maybe you could say divided by the length of ac multiply by length of a b like that but this is the angle for this theta so let's do that slot angle or theta is equal to a cosine arc cosine of the dot product between the position j minus position i which is the vector from i to j and we also want to normalize this and normalized off position k minus position i a lot of parenthesis now this should be the angle for each faces belongs to this i okay now that we have two values the theta i j k and these outer products three by three matrix products we can now add these value to a global a inside a loop by ta multiplying by theta like that okay and as a result you should be able to get the three by three matrix at this point let's check okay for each point so going into the geometry spreadsheet looking at the point and there you go you are having a three by three matrix okay now i from this matrix you need to get the eigenvalue in order to estimate the energy on top of that point also the eigenvector eigenvector for the gradient so in order to do that we can use another function on x to estimate the eigenvalue using spd decomp this one okay well spd decomposition will keep will decompose the three by three matrix into u s and v and most of the time you you you only use u and s and u will become the list of eigenvectors and s will be the value for the eigenvalues okay combining those two values you'll be able to get those two different values all this svd the comp not always gives you the exact precise information so in order for you to get the precise information the best bet is to make this float value into a double value in order to do that you go to the bindings of this vector angle then change the x position to 64-bit then the float becomes double precision i think that's necessary and i think that was it also explained in the paper that you do need to use the double precisions for this calculation okay so after you have got this matrix 3a it's time to actually calculate the svd decomposition and this is how you use it let's bring this back here so the first input is the matrix and then you get the output parameters like u s and v all right so first of all let's create the empty variable for umv which is a matrix three three by three matrix and the output s is the vector so make it name it as s and make it as an empty variable now it's time to use the sbd d comp the matrix you're going to decompose as the a and the output is u s and b okay after this you'll be able to this function will insert some value to u s and v and let's see how it looks like so for u that is three by three matrix for v that is also three by three matrix and s that is a vector and if you look at it first of all if you look at the s value this is actually the eigenvalue in which and as explained in the paper paper what you want to look for is the minimum of this eigenvalue somewhere let that here the lambda i can also be expressed as the smallest eigenvalue of the three by three normal covariance matrix so you want to get the smallest one meaning in this case the third one is always the smallest if you compare with the left-hand side as 0 as 1 you see that the third the s2 is always the smallest compared to the ones on the left side okay so the z component of this vector value is the one you're looking for and corresponds to this eigenvalue there's also a eigenvector which you could get which corresponds to the normal direction um the closest normal direction to the fit plane to each of the normal of the faces and that can be retrieved by looking at the three by three matrix of u and actually the u looks like this and the one we are looking for as a vectors uh the eigenvectors corresponds to s1 s2 s3 is these so a stands for the x direction d stands for the y direction g stands for the z direction for eigenvalue s1 since we are looking for the smallest eigenvalue which is s3 what we want to look for is this c as an x coordinate f as a y coordinate and i as a z coordinate so that is the these two are the value that we want to look for get out of these sp you could decompose so let's try to get that and try to visualize it to see if looks correct or not all right so the first of all the let's remove these the value for the eigenvalue i'm gonna call it eval sounds like a different method how do i call this this is also can be considered as the amount of energy so i'm gonna just call it e and that is s2 the z com d component of the vector s then vector um eigenvalue eigenvector i'm going to call this e v is from u but what we want to get is [Music] this value here this value here and you could get that by from the 3x3 matrix on houdini by saying so this is this value is xx and this value is x y this value is x z this is y x this is y y this is y z and this is z z so what you want to get is the x c y z and z z component out of this u three by three matrix so [Music] u dot u dot x z u dot y z and u dot z okay so that's the value and this should be the normalized value meaning the length is equal to one this is the unit vector now let's try to check this direction first if it really looks like the normal direction of the plane the fit plane okay for the covariance normal variance so we are going to give this as a attribute as well as the energy as well for the energy i'm gonna call this en okay like that and then let's try to visualize it now now i think it's a bit hard to see with this example if the value is correct or not so i'm gonna try with the more simple geometry like cylinder [Applause] which we could easily estimate what the normal plane uh fit planes normal direction is give a little height a little bit of meshes here and also make it triangular face like that and connect this right here okay and let's try visualizing the ev as a vector make it red okay so it's facing upward so is this correct or not i'm going to make this change the resolution and it doesn't really change the direction now let's consider if this seems like a correct value or not looking from the top view we have a hinge like face a hinge like shape for each point so obviously these are unfoldable meaning developable for sure all the cylinders are like that and if we check that shape on a sketch looks like these something like that okay and consider we are looking at this point on the center okay and looking at each normal phase the face normal looks like this direction and the plane which fits with these normal r something like this or maybe no no sorry that's not correct actually the face that aligns that is that each normal fits is something like that it's a bit hard to see again if you look from the top if you look from the top view the face and it looks like perpendicular to this uh hinge and the normal is facing this way so you can see that the normal is on top of this plane and the normal direction of this plane itself is actually this upward direction so the red arrow that you're seeing right now looks correct okay make sense so this is what you called you here so seems like the estimation is correct and going back to the pig head and let's make the lengths of each eye gain vectors a little bit small each one is actually a best fit planed normal direction okay so and this direction is going to be used for the in order to calculate the gradient meaning the direction and the actual direction in order to optimize the point for to make it developable all right now another things we want to check is the eigenvalue which is the energy that we need to um decrease to in order to make it equal to zero for the best fit that is en so bigger the value is less appeal i mean less developable that point is so let's also visualize that by i don't know maybe using color node ramp from attribute using en now let's make the zero to white and one two red so more more red it is more undevelopable and you can see though you can see it happens where you have a high gaussian curvature i think let's also compare with the measure node which calculates the gaussian curvature curvature curvature for each point and see how it looks like and it's a bit too bright but comparing this and this one you could see some um [Music] some similarities now gaussian curvature has the negative value as well so you're seeing blue and red but if i make this red as well you're gonna get the absolute value colored colored and so compare with this one and this one you get somehow closed close uh estimation so more high gaussian curvature you have less the less developable so making the gaussian curvature close to zero is also a goal as well you could say that right now you know with the checking now that we have got these information as the energy and the uh the eigenvector it's now time to calculate the actual gradient in which direction we should move the point in order to make it less energy less energized as the undevelopable condition to do that um first of all i am going to sum all the energy which belongs to each point right now stands as en and each point i have this en value in 64 precision i want to add all those value together as one value to estimate the total developable energy so less the maximum less the sum of these energy is the better okay so i'm gonna promote it to detail change the name to some en don't delete the original because we might want to use it and we are looking at the energy and as a result we could get the total sum energy like this is this correct i don't no no i don't think so that is because i didn't add it all together i have to make it some so 66.2 now the goal is to make this become close to zero okay so that's the that's the goal for the optimization right now we could gather this as one pack it's time to calculate the the initial gradient the direction uh for the actual energy to for the optimization so first thing first where shall we start first of all i am going to create the empty attribute called gradient which stores the vector value in order to define the movement moving direction and amount for the optimization so tree attribute create call this gradient starts from 0 make a vector value all right now it's time to calculate the gradient with some another vex function and that's when you go to the appendix b 1 and b 3. this one this one right here and this one right here okay all the rest is kind of optional like something like maximum covariance is to make a bit better result but it's a bit more high cost to calculate so i'm gonna skip it for it today and b2 is for the combinatorial energy so we also skipping that as well because what we are using here is the kvar ions energy okay but for this b1 this is general this is going to be used uh for combinatorial energy and covariance energy so first we need to calculate this one then we could start calculating this to estimate the gradient direction okay so shall we do this shall we do this and this is going to be a lot of calculations a lot of vector or matrix calculations so be aware not that hard but a bit confusing so what we want to do again is the calculation for each point okay for each point we want to calculate the direction in order to estimate in which direction the point should move in this step to make it developable now it cannot be optimized in one step you need to have tons of steps to optimize because all the points are moving at the same time so you need to also estimate how much you should move to that direction but that is going to be done in the next step for in order to do the linear search what's the best step how much you should move for each frame now but for now we just need the direction so let's do that using the pointer angle again let's call this radiant car calculate gradient now let's go one by one now first thing first we again are going to calculate the face-wise values just like listed here we have i j k and so on so we need a primitive which belongs to each point so do the same point prims at each point right now and let's also bring up the eigenvector value which in this case the eigenvector is used as x right here x is the eigenvector value which the length is equal to 1 meaning the unit vector so it's called eigenvector value equal to x and get that from the attribute call e b all right okay so let's create a loop to go through the primitives like that okay so first thing first what we want to do is to probably calculate the the area probably and we can calculate the area using the simple cross product function which i'm not sure if this one is correct this is like a cross vector between the normal the face of the normal and the edge between fk and fj which i am which is creating the vector values and output but i think what i what we want as the area here is the scala value so instead of doing like this what i'm gonna do is to first of all get three point position okay one is i one is j and one is k right so in order to do that um i'm going to first of all get the value get the point numbers for each primitive and in this case the order is pretty important the order of i j and k i mean it could either be clockwise or counterclockwise either way is fine but it has to be consistent i mean if you took different triangles and different places and if this one's i this one's j this one's k and in this case if this is i and this is k and this is j in this case this is counterclockwise this is clockwise so we don't want these conditions to happen we always want to have either clockwise or out either counterclockwise so in order to um get the consistent order for the vertices instead of using the prim points i'm going to use instead a prim vertices which will always get the triangular faces vertex order so which is always become in this case clockwise i think so it's a bit dangerous to use pinpoints because it just makes up the order for each face so premier this is at frame like that now we what we want to do next is to convert each vertex number into i j and k and we always want to use i as the current point number which is equal to pt num so let's create that kind of conditions we can't use i i don't want to use i actually instead of using i let's make it t because we want to use i as uh this value here i j k so we want to preserve these i j k characters i mean i want to preserve it so four and n is equal to zero and vts and we can get the vertex number and then we want to convert it into a point number by using vertex point like that then what we want to do is to check if this point number is equal to pt num and if it is equal then we wanna make this point number as i okay so if pt is equal to a point number the current point number then we want to make the i is equal to pt so we have to have i somewhere probably right here as well as j and k okay so if i is equal to p t then j is the next point next vertex point so vts n plus 1 and there's a possibility that this becomes zero so calculate the remains by in this case three because we are looking at the triangles there's only three vertices and we also won't need to convert this into point numbers over text point zero vertex number and do the same for okay which is n plus two then you'll get the value i j k stored and you always get i as a pt number now this once you find out that pt is equal to bt numb then you don't really need to go through all the other iterations for this loop you can just skip it using break all right now that you got a three point numbers for this triangle i j k it's time to calculate these value now in order to solve this first thing first let's get these point position at i j and k so position i you get like that and j and k do the same thing like that well while i'm writing the code if you guys have any questions let me know so you get ijk position for each face in this loop now i think we have enough information to calculate all those stuff let's do that first of all we're going to calculate this area for each face which is pretty simple i mean we could do the measure note to calculate the area for each face but the i realized that the measure node in order to calculate the area is pretty computationally heavy expensive somehow if i run this on inside a little bit the most expensive node out of all the stuff was actually this measure node somehow i don't know why so instead of using measure node i'm just going to calculate it as a vector value using the linear calculation so to do that what you could do in order to calculate the area if you have a triangle like this first you want to get the vector between a and b b and v and also the vector between a and c b a c okay and by calculating the cross products um you get this perpendicular vector and actually the the magnitude of this vector is equal to the area of this square so if you divide it by 2 you get the area of this triangle okay simple as that so we're going to use that um equation formula so i'm going to name this a or d a d a is equal to a cross product between the position j minus position i and position k minus position i and divided by 2 before we gonna get the magnitude of the vector then this will become the area of the triangle associated with the ijk all right so that's that easy now next uh what we want to get is let's see what kind of value we want to get um probably this one a normal value here now if we look at it if we check what will be the unit of this value not the unit but what's the type of this value so this is the scalar so that's that this is the vector value right and this is also the vector value the normal of the face so you get you are calculating the cross product meaning you get a vector value and then you get the transpose of the vector so that means you are pretty much doing the same things as this calculation here meaning you get three by three matrix out of this calculation so as a result you get the three by three matrix as this value all right and for these value which is a delta f j theta i j k delta f fk theta i j k and so on is looking at this first of all this is the a cross product so this is the vector value and you are dividing with a scalar value so the result is a vector value so all of these the type of the value is vector value okay and that is looks like depending on the it says theta so looks like it's dependent on the angle it's not you actually calculating any angle right here but actually based on the angle value for each i j k okay so consider that let's try to remembering that let's try to calculate each of these values we could go from this one probably the three by three matrix value okay so in order to do that let's see what kind of information we need first of all we have this one fk minus fj we also have all sorts of uh directional vector value f stands for the position at that point so in this case position i position j in position k maybe i can just rename it to fi fj fk right looks more similar so let's calculate this one each of these direction first shall we so fk to fj to fk vector f um jk is equal to [Music] f k minus f j vector f and j i is equal to f i minus f j vector f uh i k is equal to f k minus f y right okay now let's calculate this one that is the cross product between f j k and the normal of the primitive do we have the normal of the primitive yes we have calculated right here so we can get it oops we need to remain rename this as well fj fi fk if i alright and where was i so the normal direction of the face is how do we call this just n or gnome yeah no worm is prim zero and which primitive are we looking at this one right here so and that's prim so the result is matrix three let's call this dn is equal to first we're going to calculate this one cross product between the f i k no no f j k and norm and calculate the outer product between this vector and the normal so outer product between the cross product and the normal and finally mult divided by area like that okay make sense and that is for f i okay so these we're looking at this triangle here uh looking from this i if we are if the this is the point number that we are looking at right now and actually we want to do the same calculations for this point and this point the j and k as well because in order to calculate the gradient we are going to calculate the we're going to look for each face and we're going to calculate the gradient at each point on this triangle but at the same time we want to calculate gradient on the other side the f and k as well so in order to do that we need to have the f and k version of this equation which doesn't really say it here but it actually does you do actually need it so let's call this dn as dn i and what we need is the dnf and normal dn jndnk as well and wait a minute we should call this jk wait the subtraction looks wrong here doesn't it this is fk minus fj well looks okay fk minus fj but uh the fj shouldn't come on the right hand side for this calculation i think so we should make it f j minus f i and this will be f i minus f k we're going to think about these theta value later so meaning we are we can rename this to f i j and if k i all right so that it's in the order either clockwise or counterclockwise for these direction okay yeah that should be right and then i'm going to calculate the dnj and dnk okay so d and j we can replace this f j k to the one that doesn't include in here so that is f and k i right and this one is f i j like that okay so everything all of these will create a three by three matrix and each one each one will create the gradient vector evaluator using this equation now next we're going to calculate this theta value okay so let's name this vector d beta i since it says i here and maybe i'll just say t i d t i d t j d t k okay and we're going to calculate each of them okay now this one the one that says f i theta i j k so we're gonna start from this one shall we oh well it's using all these ones first so i'm just gonna calculate the f and k value first so i mean j and k so this one and this one so this becomes this comes later okay so j that is the cross product between the normal and um the vector f i j so um cross product between the norm and f i minus f j so f i minus f j divided by the length of if i n f j so i guess you could just normalize this one as well because that this is this means you are using the normal unit vector okay but let's just follow as it is okay and i assume that this could also be things too but i'll just keep it as this for now right now do the same for dtk i'm just gonna copy these and cross normal fk minus f i and do the same here fk minus fi lengths and finally you are subtracting these value so minus dt j minus b t k like that okay so that's that now i think you have enough information to go for the actual gradient these are the preparation and this is the actual equations that you want to solve in order to get the actual gradient at any vertex i on the just this is the every vertex let lambda be the eigenvalue of the matrix of a i is equal to the with associated eigenvector x and we're going to use this x which we got here then the gradient of lambda with respect to the position fp of any vertex p is this so this is the final gradient value and that is the addition for each face each face on each point so meaning you have multiple faces so you could still use this loop i think and you are calculating the transpose of x and normal of the face which means the dot product okay so the power of two of dot product of these two uh vectors then multiplying with the f p i i j k so since we have it says p that means we are calculating all three points for each face i think okay any and use it for each uh gradient for each point so we gotta store and which gradient used for which point okay then we have two theta um [Music] i j k multiply but this is a scalar value i think this is the angle and this is another dot product which is same as this one and then we have a three by three matrix and you are transposing it and multiply by x which is equal to vector value so as a result you get a vector value [Music] 3 by three matrix multiplied by vector value you get ax plus b y plus c z on the first row and d x plus e y plus f y on the second row as one value and g h plus h y plus i z on the third row so as a result you get vector value having three roles and one column so this will become a vector value and this is also vector value so the result is vector value so this is the vector value all right so what was i it's time to calculate these since we are having the same dot product calculation here let's gather that and make it as a variable i'm going to name this x dot n um to calculate the dot product between the x and the norm all right which will give you the projected links between the x and then not really but uh okay well so we have this one and since we are adding the [Music] all the result on this loop let's give a global variable and as i said you are going to create the actually we don't really need to make it global but we can just add it as a attribute as soon as i create this lambda d lambda okay so i'm going to call this dl stands for g lambda and first of all the left hand side calculation which is the dot product of these x and n which is this x dot n and power of 2 square of x dot n multiply by this is actually a vector value so in houdini we need to bring the vector value on the left hand side uh so we have this value already which is either this one this one or this one but this is f p i j k so in this case what we're going to use is for the i so we are going to calculate three gradient three lambdas dl j dl k okay so for the i we're going to use this one for the theta related value like that so dti d theta i which is this one multiplied by the dot product the square of dot product plus [Music] to multiply by actually we need to also bring the vector value first so we should calculate this value first here so f i n in this case d and i d n i which is the three by three matrix and x as the vector value and since in houdini in order to apply a matrix or transformation matrix to a vector value i think you need to bring the matrix on the right hand side because in houdini the vector is horizontal expressed as horizontal value that's a bit confusing because in a lot of the papers the vectors is expressed as vertical value but in hooding it's not so i think we're going to do like that then as a result you get the vector value out of this calculation which is these then you can multiply with these uh flow value which is multiply by two multiply by theta multiplied by x dot n do we have theta um we don't have theta here yep so we need to recalculate that theta which we have done on caulk energy as well so we're just gonna copy this one bring it here somewhere maybe here we need to change the name to fj fi f k if i all right right in this case the theta is always looking at the angle from the i so i think this is constant we don't really need to calculate the angle for each points i j k we are always looking at this angle for this vertex's vertices even though we change the position to calculate the force the gradient because it says i here okay so that's that and i think this is done and we do the similar calculation for jnk so we're gonna copy this paste it right here and replace some of the variable for example this one this will become dtj this will become dtk and this will become d t d and j this will become dnk and i still have some errors somewhere let's see where that is syntax error and expected on the identifier on lady 48.48 48 where's that right here okay it's fixed not sure where was the problem okay let's save it so hopefully this will be the force value in order to uh the gradient value in order to move the point for the best position for the developability and let's see and what we want to do is to store this gradient into a point as uh and summarize i mean some get the mass addition of these gradient on each point the corresponding point in this case this is for the i this is for the j point this is for the k point so in order to add these gradient values to each point this as an addition i'm going to use a function called setpoint attrib to a gradient attribute to i with this dli as a add option which will apply an addition for these vectors to this gradient attribute and do the same for jnk okay there's that and if it goes all okay you get the gradient vector attribute on each point just like that which shows the direction and maximum force in order to make the point in order to make the mesh uh developable but if you just apply this length this speed directly to each point then the mesh will just craps because these energy is only for only estimated by looking at each neighbors for each point so if by moving each points energy at the same time you need to make it really slow to make everything works at the same time to get the balance you know so shall we visualize this gradient value first as an attribute as a vector value so looking at each point seems like these are the direction in order to make the mesh developable but we cannot really see if this is correct or not so we have to test it out by using some solver or for each loop feedback loop but we could kind of see how it's going to look like on already a developable surface like cylinder in this case you can see that the gradient you no longer see the gradient arrow and if we look at the geometry spreadsheet the gradient is equal to zero meaning there is no need to optimize because this is already optimized as a developable surface so that kind of makes sense so we could assume that this might be correct but let's see in order to check we need to use this gradient actual gradient value in order to to move the point slowly to that direction and recalculate the gradient after moving the points again and move it to that direction slowly as again again again so let's bring these step inside the solver to see it in the animation shall we so [Music] create a solver and i'm gonna copy all these stuff the energy calculation and the gradient calculation to the solver like that okay and then we want to make sure that at each uh step oops this should be on the last each after each calculation is done all the attributes gonna be reset because we don't want to use the leftovers on the first step of this over so let's see what kind of attribute we have we have a sum of the energy which we can resolve it i think we have energy and energy eigenvalue and eigen vector gradient actually i think we can just keep that as it is maybe because these are going to overwritten by the function maybe not the gradient i gotta make sure that the gradient is gonna be reset on each step so i'm gonna create the attribute delete to reset the gradient just in case okay other than that i think it's fine all right so what we want to do is to use the gradient to move the point to that direction so i'm going to use the simple point wrangle to do that update the point attribute with the gradient on each point as you can see if you just use the gradient as it is the just meshes mesh just explodes because the speed is too fast obviously so we're gonna make sure the speed is small enough so that each gradient won't you get the best balance in order to optimize and currently we don't know what's the best value for this time step or speed so let's just try out with a random value like point zero zero zero one for now and let's see what will be the result if i play it now looks like the value did agree nice job looks like it did seem to create some kind of a developable surface that we were looking at looking for and if we cusp the edges with some angles like using the normal for vertices make the angle like 15 degrees you can actually see the edge cusp or edge standing out and looks like we are getting some kind of a developable surface out of this so for this mesh maybe the speed was okay point zero zero zero one though the problem is i think if we increase the speed like 0.06 because more speed you have the faster you get the result but if you make it too fast the problem is you get the noisy result or sometimes it's wiggles because it's moving too fast it's going back and forth if you make it more faster faster and faster and faster now you start to get there is unwanted result that's not really what we want so we're gonna have to make it as fast as possible but not too fast to make the stable optimization so in this case maybe point zero zero zero two might be a good number maybe but still it's still wiggling meaning it cannot find the best result what we want to have is to stop these wiggles and have the fastest result as much as possible so the next step is to estimate what is the best time step for each iteration in each iteration the time step will vary sometimes it could be better for 0.1 for the rod larger mesh maybe on when the mesh becomes close to the developable surface then the time step might become really slow so we got to estimate this value and that is the part where you do the linear search for the optimization and that is explained on the paper where it says numerical optimization here and it explains you could use l p f g s one of the type of linear search uh this could be the best result it says by using this one you could get the best result other than that there is also another type like our mijo wolf line search and so on there are a bunch of line search algorithm although i haven't looked into these stuff myself so what i'm going to implement today as a numeric optimization is the really dirty implementation of the linear search so it's not really based on l p f g s or l me home wolf it's just my own implementation which obviously is not perfect at all but at least it could kind of uh find some sort of time step so and probably you could just edit it or modify it to make it similar to lpfgs or i'll be home will fit line search later by yourself so i'll left that to you guys okay i'll just show you the very basic linear search method using the houdini way using houdini node probably it's better to do online code but i'm just going to use a bunch of nodes to create this kind of a line search to make myself understandable right and there's another like optimization tips explained here like fixing the mesh by flipping the edges like these to meet the dironate conditions or collapse the edges like these one but i'm also going to skip that part as well okay because these topics also takes a bit of time to implement in houdini okay but it's also i think these are also important in terms of the optimization so i'm i might gonna do this in other video as a separate topic probably okay so for the numerical optimization the way that i tackled this problem i'm gonna explain in sketch okay so the way i have tackled to this problem i don't know if i can sketch it correctly but um first of all you get a geometry and you get the direction as a gradient right but what you don't know is how much amount you want to move in the specific frame so what i'm going to do is to repeatedly move this point to this direction with different distance and find the best distance for each step starting from a really big distance like t time step t equal to maybe 1.0 which is pretty fast obviously and it and by moving the point to this direction you get some kind of a new shape and out of this new shape what i'm going to do is to recalculate the energy the new energy i'm gonna call this new e okay and previously you have already calculate the energy and i'm i'm going to call this old energy okay and what i'm going to do is to compare these two energy together the what i mean by old energy and new energy is the sum of all the energy on each point okay so in houdini i have created the attribute like some en so this is the attribute that i'm talking about so if the o n is larger than the new n then that means you are successfully um make this energy smaller okay the what you want to make as a final result is if we have the graph like this and this is the total time step and this is the energy and starting from this energy and what you want to have is the energy equal to zero so you want to move the energy to the uh this direction the below the downward direction it could be like this it could be like this any other way but you don't want to go to this direction upward that means you are increasing the energy but instead you want to decrease the energy somehow so this is the result what you dissolved you want to get a comparison between the old energy and the new energy right but if you make the total the time step too big to move the point too fast the chance is that you get this condition the new energy is big bigger than the old energy that is not the condition we want so in order to avoid that once we get this condition we are going to make this time step smaller let's say multiply by 0.5 and make it 0.5 in the next step and using the new time step we're going to recalculate or re-estimate the new energy like moving the point to this direction create a new uh shape then recalculate the new energy and check the conditioner again if the condition is still too big the new energy is still big then we're going to multiply this time step by point five again and do until this new energy becomes smaller than the old energy once it becomes smaller then that's the time step we want to use uh largest as possible okay could be like 2.2.1 something like that and we're using that time step we're going to move the points and the new energy will be smaller than the old energy okay and that's that is going to be calculated in one iteration of the solver okay once you move the points with the new energy which is lower than the old energy then you are recalculating with the new mesh which will become the all new energy will become only all the energy the previous new energy then do the same step again on the next solver iterations and it you can reset the time step to one again on the next iterations but that takes a bit of too much time so we could estimate that the next time step for the next iteration of the solver could be close to what we have find out on the previous iterations so but we also want to make the time step as big as possible as large as possible so what i'm going to do is to multiply this 0.2 which was declared in the previous iterations by 2 so that it starts to check it starts to search for the time step from point four okay so starting point starting from point four again you're gonna do the same step move in this direction moving to the gradient direction with a time step 0.4 and check if the old energy is bigger than the new energy and if so 0.4 is good if not i'm going to multiply by 0.5 again to get the new point on the new time step now this uh multiplication by 0.5 or multiplication by 0.2 on the next iterations is just my guess so i i don't think this is the best way to do the linear search at all this is not really i don't think this is a good optimization at all honestly but uh it'll do some kind of job i mean at least it won't explode your mesh so still works and i believe by modifying this modifying this um optimization with the algorithm explained in other papers like the bfgs lbfgs then you could make it more precise more maybe a better time step okay but for now making let's just make it essential or basic right so keep that in mind let's find out the best time step shall we all right and another things that i want to mention is right now 0.001 seem to work well with this mesh that's good but once you change the resolutions of the mesh like changing the area of each mesh and so on the best time step will change if i change this to 0.2 then maybe the time step is a bit too slow if i make it high-res like this maybe the time step was too fast okay so that's also the reason you need to look for the best time step for the best optimization okay at least in order to avoid exploding all right that's that and let's see how we do that and that part is i think it's pretty important all right so going back to the solver and i'm gonna gather these uh i'm gonna name this energy calculation [Music] um gradient calculation okay so as i said we need to check a lot of time step inside a single iteration of the solver so what i'm gonna do is to use the for loop several times until it finds the best value okay and i think it's better you use the while loop in vex rather than using a for loop but i think it's easier to see with these using for loops so i'm just going to go this way and to make sure that you have enough iterations i'm gonna make this iterations big enough like a thousand or something because you're gonna eventually you're gonna it's going to stop at some point but for testing i'm gonna limit it to 100 for now and later on i'm going to increase this value let's make a feedback loop do we need it to make a feedback loop yes yes yes just yep self hp back feedback loop all right then i'm going to connect this right here and i want to test the result with a bit more rough geometry so let's make it point one and something like this okay so let's see first thing first um we i would like to have an attribute to store the time step as a global attribute so um we can go outside of solver start creating the attribute that we might going to use and update it i'm going to use the attribute create name this t as a time step for detail float starting from one i guess one is pretty fast so eventually it's going to be smaller at some point probably i don't know maybe it might be okay to start with a really big number but i'll go with one because what i'm gonna do in order to decrease this time step just a simple multiplication so maybe if i use logarithm or something like that maybe this could be really big but since it's just a linear multiplication here so i'm just gonna go with the small enough number like one as a scale speed okay go inside first thing first what we want to do is inside a full loop we would like to test this time step that we have in the detail attribute uh didn't have it where did it go okay we have to connect this here okay so we have this t as a detail attribute here and we want to test if this t is okay to go or not in order to check that i'm just gonna make the simple assumptions just by moving each point to that direction with this speed and recalculate the energy using the same function that i have here so i'm going to use the point wrangle to move the point to that direction with the gradient just like i did previously multiply by t retrieve from the detail like that okay obviously this is too fast but let's check what's the energy is what the energy is so i am going to copy these first calculate the no more of the face and calculate the energy at each point and get the sum of that energy and i think it's a good idea to change the name to something else so let's name this new sum and okay and then let's just go with single iterations for now see what's the result if we look at the geometry spreadsheet at detail as you can see sum n is the old sum of energy and the new sum n is the new sum of the energy and obviously the sum you some energy is bigger which is not optimal which is not good we what we want to have is the one that's smaller than some the old sum energy in order to optimize okay so obviously the t value is too fast we want to make it smaller so how do we do that uh we're going to check this new sum and the old sum inside the loop and if it's smaller than then we're going to update the t value somehow so let's do that by creating the conditional using maybe a detail attribute okay let's make the attribute wrangle and make it as a detail and the old energy is f at en sum or some en was it what's the name samia and the new energy is f at mu sum n okay so and the current t value is f at t so if mu [Music] some new energy is bigger than the old energy that's not good so we're going to update the t value to the t multiplied by 0.5 maybe this is decreasing too fast but let's see if this is okay or not right and else else that means you have find found out the good value for the t at the the largest as possible t value which makes the energy smaller so that means you want to stop the loop so i can create some attribute to indicate that we need to stop the loop at some at this point i'm going to create the integer value for the detail stop to stop the calculation so that means we need to reset the stop somehow somewhere maybe outside the loop somewhere around here so i can just say attribute delete before getting into the loop for the detail to delete the stop attribute just in case all right now we could create a null node somewhere around here to retrieve the stop conditions to check the stop condition i'm going to create a new node here and check if the detail attribute of this stop no stop node is equal to 1 or not if it's equal to 1 then we're going to exit this loop stop stop okay and increase the loop here to 10 and after we have updated the t we could see that the t is decreasing like that at each step if we make the step to 2 this will be like 0.25 but nothing seems to make this optimized that is because we are like adding the point position over and over again we have we have to somehow reset the position in order to test out the best time step at some point so we're going to reset the position to the original position this is this is the original position at the end of each loop okay so to do that i'm going to create the rest position node before going into the loop to remember the original positions and each time we recalculate the energy and recalculate the t value i'm going to reset the position reset the point position which has been used to recalculate the energy to the original position somewhere here so i'm going to use the point wrangle reset position just make the position to the rest position to reset it okay like that by doing this at some point you should see this stop becomes one and you get the best t value at some point hopefully let's increase this to 100 and see where it stops and it says the feedback loop stops at 14 so that's the end of the loop that's when you've found the best t value which it says point zero zero zero two four four four one four one so seems like this value is the largest possible d value for this condition in order to make the new sum energy smaller and if you compare these two yes the new value is actually a bit smaller so looks like this um time step is a good one to go okay now that we have this value we could move this pig head to that direction with this t value using another point wrangle and getting the updated t value from the detail move the point to the gradient multiplied by t and you get some result that should be the that should be equivalent to what you have found on the last energy calculation all right so that's pretty much it and after that um you could reset some of the attribute which is no longer needed for the next iterations especially the new energy stuff after this you don't really need the new sum energy anymore so actually we could keep that as information so but before getting into the global maybe we wanna remove that or each time step or each loop we might want to remove that probably i don't know let's see hmm maybe not maybe not we could keep that but we do need to reset this t a little bit i mean as i said if we keep the t as it is for the next step then the t will only go smaller end making the time step t smaller means the optimization goes slower and slower and slower but we what we want is to make the optimization as fast as possible so we do want to see if there's any chance to increase the time step at some point so to have that kind of chance we want to increase the time step a little bit more on the next iteration of this full solver somewhere to see if the new increased time step could be used in the next iterations it might not be useful but it could be useful so in order to do that i'm going to update the time step t just like that and before going into the testing or the linear search just to make sure you have seen the chances that t could increase now this part if i wrote it like 2 but i don't think 2 is the optimized value for the multiplication so maybe this could be there are some algorithm to define this value as well but uh for now let's just make it simple enough okay so that's that and i think that will do the job let's cover this with the group network and name this line search i'm going to name this duty line search okay and let's see we're going to look at the detail attribute see the changes okay we are missing some our thing here okay somehow we are missing the energy from the detail i don't know why are we missing the output we do have an output i don't know let me just play it and see how it goes if i play it okay start to see some values and you are getting the result the good result and you can see that the time step value t is changing through time like previously it was like .0002 but when it gets more optimized the value becomes smaller and smaller and also you want to check the energy as well how energy changes if you look at the sum energy here use some energy and some energy here the the new sum energy is the current energy actually and if you look at it it's getting smaller and smaller going into zero okay and if when it becomes zero then all the mesh becomes totally developable so that's the goal but uh this probably takes a lot of time to make it going into zero so you gotta kind of uh get the balance uh to see at some point this value stops meaning it's going to converge to some value so that's maybe that's the limitation for this mesh for to make it developable or maybe if you improve the line search maybe you could make it close to zero more and more but for now since the speed is going slower and slower the result you get is going to become the the zero value that we want to have is gonna be slower to get so but at least you don't really see the mesh exploding because we are controlling the time step all right good result nice result and i think that's pretty much it in terms of the basic implementation of this geometry and i have forgotten that make this bigger like 1000 just to make sure we have it searched enough and i guess we could also change these part maybe if i'm multiplying 0.5 as making the speed too slow maybe i can check by multiplying by a little bit bigger value by than 0.5 that will make the speed faster but the cost of calculation might get bigger because it makes a lot of iterations to find out the best time step if you look at it you see that it cost it you need 32 steps to find the best result when you multiply 0.75 if you make it 0.5 you only need 15 so on but if you make it too slow i mean you don't need a lot of feedback but the speed gets too slow too fast so that's not really what you want so you gotta find the best balance in terms of the cpu the calculation cost and the speed of the optimization and i think there the algorithm for these will solve that problem yeah to find out the best uh constant value for these all right but that's my way that's just a this is just a dirty way to implement at least this works if i make it 0.75 the result becomes a bit faster so in this case maybe 0.75 that's a good idea all right so yeah that's it um the result looks promising and there are a lot of stuff you could still implement out of this paper i just have explained the essential part of the paper in order to do the [Music] in order to create the developable surface as you can see they are like mesh cleansing like these or you could also consider the conditions like these like the one that i have implemented will get the result like these but if you want to get the clean result like these you need to change the energy calculations a bit more using this maximum variance somewhere explained maybe somewhere around here and if you also there you also want to come so if you want to also want to solve these you need to additionally add some conditions to the energy and so on for example these conditions as well if you want to avoid this pointy conditions or flat conditions like this which you saw on a rubber toy head you need to add another conditions which is pretty much explained in the appendix so you could check that somewhere like here somewhere right here these are all total gem to look at for discrete uh geometry corporations but for this um live stream i'm just go with this essential part which is pretty much what i needed for myself for the workshop that i'm going to do later okay and that's what i wanted to share today okay well that's pretty much it um let me know how you think about it hopefully you find it somehow interesting maybe that was too much of a implementation of mathematics but um i found this paper really interesting for sure promising for a lot of other usage and the way to read the paper is as well a way to calculate the energy way to optimize using some basically new searching as well so i hope you find somehow interesting as well like i did if you have any comment or feedback let me know i would love to hear that now let me check with other kind of resolutions make it really high-res like that see if it's going to still work so you have really high energy here but you are decreasing energy for sure you can check that as a number here and as a result you are also seeing the developability here so that's good that is good now in the paper it where it explains how you can create the high-res on developability surface it says you should start from the really low res geometry then over time at some point you should subdivide the mesh to have more triangles to make it high res and to calculate the developability as fast as possible so if i want to try that um start with the really raw res geometry my point 1.2 maybe this is two row res i mean at least you should need to be able to see the overall shape that we want to have so 0.15 of this what does it look like okay so this might be good so let's see at what frame this will converge well somewhere around 500 maybe that's taking too much time i'm going to increase the sub step a little bit like 10 that might make the calculation slow but let's see well it's still fast okay so let's say we want to remesh this at well there is a condition that we don't really want which is explained in the paper how to avoid it but we didn't do that today let's just ignore that uh let's say we want to remesh it on 150 frames and go to the next resolution going inside of solver let's create the switch node switch node only if the frame is the multiplication of 150 meaning calculate the remains with 150 and if it's equal to zero then remesh do the remeshing and we want we don't want to make it smoothen out so we want to use the subdivide node which doesn't smooths out which is bilinear okay you can see that the edge cusp is still there and it is creating squares so we don't really need this we don't really want the square so we need to make it triangles but looking at this this might be too much of a triangles to add for one subdivision so instead of using these maybe i'll just implement the mesh by myself using the subdiv loop this is soften the edge so that's not ideal yeah so instead of doing that or [Music] this has the this has the override crease weight attribute okay so this is good crease weight to 10 which will keep the edge cusp so that will do the job i guess okay so only when the frame is the multiplication 150 we are going to subdivide once now this there's funny condition happens here but let's say i'm okay with it okay so let's try see how it goes play and once it becomes frame 150 this will subdivide once okay now it looks how come it becomes really high-res maybe i'm doing something wrong here wow that was scary uh where did i do wrong okay well let me test this with when the frame is equal to equal to 10 huh i'm gonna make it really slow let's reset the simulations three four five six seven eight nine ten what's this loop coming from nope this is obviously wrong what what is this thing what did i do wrong here there is only remesh here right right and what's the deal with hmm funny so this is and this is equal to 10 this will become this will be subdivided wait a minute okay maybe that's it's because i'm using soft step here yeah probably that's the reason okay we'll get it forget about using the sub step and make it like this and instead of making 150 i'm gonna make it like 300 okay and let's check the detail attribute to check how the energy will change over time so once it becomes 300 frames let me see what how it differs so from 298 to 300 seems like the the sum chain drastically uh get decreased i guess that is because the t was big enough to move so i guess i do need to think about how to increase the t value other than the one that i have implemented although looking good starting to get the more high res surface and once it becomes to 600 it you should see a bit more detailed and low energy nice nice really nice and let's also color the surface with the normal map a normal color so that you can see the differences the normal differences between the surfaces or vertices the different color indicates the different surface direction and you could clearly see the change between the surface and this surface pretty much explaining where the edge is in order to create the cut for an unfolded surface um the paper also explains how you could define the unfolding edge and how you could unfold it somewhere around here um but i am not going to do that as well maybe you i'm gonna leave that up to you as well i guess there are other many ways to do that but at least you'll be able to get the edge information so and i need to do that for myself as well i mean i haven't tried it out yet if i found out the method interesting then i'm gonna share this share that as well sometime at least for now i have just implemented this essential part and pretty satisfy for myself okay that's it um thank you very much uh thank you really free of you really um thank you for the comment uh thank you for watching this time that's pretty much it for tonight you could use the same method for all the other geometries um you could try to check that with the sphere as well which could be interesting this might be too low res interesting doesn't really look like a sphere anymore but this is going how it's been optimized for sphere mesh i mean there are also a condition explained in the paper how to resolve these like three points positions or these as well how to resolve these conditions as well explained in the paper so maybe you want to look into that as well but overall looks good okay that's uh okay uh okay cereal siri siri thank you that wrote a comment that's it for tonight i think um [Music] i'm going to as always i'm going to upload the files to the github so that anybody can download it for free i'm going to paste the link of this project to the video description page of this youtube also i'm going to upload the files the same file to the patreon page so if you could support me on a patreon that would also be awesome but anyway you could just download it for free from anywhere okay so that's it thank you [Music] and i think that was a lot of mathematical stuff for tonight not so maybe not so interesting visual wise so some of you might find it really boring but i hope some of you find it interesting at least i did okay um the next i haven't figured out what the topic will be for the next week but probably it's gonna be a bit more visual oriented more easy stuff more faster stuff than this one for sure okay thanks for being patient um i'm going to organize this a little bit and just finish the stream and as i as soon as i finish the streaming see live stream i'm going to upload the file um i don't think i need these i'm going to delete it okay keep this like that the whole surface optimization this is the visualization this is the initial geometry this time we didn't have any parameter to modify so i'm not going to create any global parameters for this one i'm just gonna leave these as it is maybe i could have a parameter for this frame probably yeah what's this this is just for testing i'll keep it um okay all right let me just create a null node and the controller sub divide frame i could have another parameter like how much you want to increase the t time step t for each iterations increment is not the right word i guess because you're multiplying it you're not adding it i don't know oh well i'm just gonna go with this and also time step um how what's the word to make the value decreased i don't know let me let me check the word attenuation really oh i don't know okay oh no maybe dumping is the right word okay the increment is should be more than one so something like that replace this with the time step no the frame copy this value and this one here right lastly this one here time dumping time step dumping there you go okay everything parameterized which i could and i'm going to check if it still works and yes i am going okay that's it that's it that's it so thank you very much for watching okay i got a comment from cereal um i missed beginning i'll watch later for sure thanks um is it like cat feature to unfold surface yeah there is a feature in cat john cat software like rhinoceros to unfold the geometry for sure you could you could probably do that on houdini by using um i don't know what's the best way to use them since the it's assured that it's developable um maybe you could use kinfx but i'm not sure maybe using or uv mapping could also work probably by preserving the area of each triangles okay probably well i have to test it myself and i haven't looked at the paper where it's it's explaining the unfolding part so okay that's it nice okay let me just take a screenshot and i will finish this as this day's achievement all right okay so thank you very much for joining good night everybody and hopefully see you next week with some different topic and for sure the next topic will be much easier one okay i have a comment from goodie f can i ask something not related how you manage windows software like unreal on linux is it sufficient to use mine for them i don't know i haven't used unreal in linux this is macintosh that i'm using right now i'm only most of the time only use mac or windows yeah for unreal i'm using windows so i'm not sure how you could manage learning on linux not sure [Music] good night dude
Info
Channel: Junichiro Horikawa
Views: 40,350
Rating: undefined out of 5
Keywords: houdini, sidefx, live, tutorial, procedural, procedural modeling, parametric modeling, parametric design, parametric, fabrication, digital design, computational design, 3d, design, isosurface, lattice, structure, 3d modeling, modeling, computational, generative, line drawing, drawing, illustration, fractal, reaction diffusion, celullar automata, simulation, trail, particle, vfx, mitosis, magnetic field, field, volume, rendering, computer graphics, visualization, algorithm, motion graphics, graphics, remesh, quad
Id: 5jikaAnrOLo
Channel Id: undefined
Length: 167min 2sec (10022 seconds)
Published: Sat Sep 10 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.