Houdini Algorithmic Live #060 - Quadrilateral Remesh

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] okay hello hello can you hear me okay i think this is online like to start the life okay so um this is 10 p.m in japan time uh hello this is junior horikawa and this is the weekly tutorial live for houdini that i've been doing using algorithmic design method and called as houdini algorithmic life and this is the 60th episode for the live and the topic for today is to create a kind of bit a of a quick and dirty way to do create a quad remesh quadrature remesh a from any kind of geometry that you input which in this case i'm using this kind of vegetable i have this kind of geometry then using either way either a recursive method either using a for loop or a solver to create a quad remesh without using any kind of plugins like these or you could also see it's iterating its smoothness of this quadrature remesh by using a solver as well the thing is uh as you can see it's it is a quadri quadrature any faces that you can create with this method but it's not that clean as compared with other like sophisticated plugins like exercise a quad remesh plugin which is a paid plugin for a houdini to do a quad remission like this but the purpose of this tutorial is just to show some easy process a rather easy process to do to create this kind of a a rematch geometry having these quadratures quad faces from any kind of geometry as a starting point maybe when you want to implement these kind of stuff by yourself and i think the idea could be transferred into a any kind of like software's including like game engines so might be useful in some cases although the quality is like these so um decide if you if you think it's useful or not i'll show you other examples uh for example if it's like a plane or a pig head was it a big head looks like these it's not that bad i think although i still have these kind of a connections which has three size the best quadri mesh has a least number of these uh neigh ring of three but having neighboring a four quad quads is the the best two best situations as much as possible to have these kind of um because if you add the angle for each of the angle for each corners for each neighbors you have 90 degrees and that's the kind of uh angle you really want for the quads but for those because there are three neighbors for at each point you have like 120 degrees for each corner which makes you a kind of a twisted angle like this if it gets more than four then you have less less than 90 degrees so that's kind of uh that also makes the quad face a bit deformed like this part so you do have uh some kind of some parts which have these kind of situations if it's a plane it looks like these if it is sphere looks like these and so on though i found the method could be really useful for some cases so let me show how i can how you can implement this from scratch or any kind of geometry all right so bring this back to the top so let me explain i can do this right so first thing first i think i'll show you the the algorithm that i have used to implement in this one so if you are good enough i mean fluent enough in vex or any kind of programming languages you'll be able to like implement yourself by understanding the underlying algorithm so let me write some sketch here hello everybody so first thing first what i am going to uh what you going to have is this kind of any kind of face that you want to remash okay and initially it could be any kind of could be a grid could be already like rematch with the triangles and so on and the first thing i am going to do with this one to make it quick and dirty i'm going to rely on some of the functions that houdini has which in first of all what i'm going to use is the triangular remesh component node so you can easily create a triangular remesh in houdini with the default component so what i'm going to do is to create this triangular remesh using its default node and probably if you want to create more a gradient like remeshing stuff you could also create use a adaptive remesh options right that's the first step so step one triangle remesh and if you don't want to use the node itself you could i think you could do some other ways it could be a bit more dirty and a bit more slower but making triangular images much easier than quad for sure okay and after you have created the triangular image what i want to do next is to uh first of all i would like to have as much number of like uh quad neighbors as possible like four neighbors for each point as possible meaning as i said if you look from the top like these for each points or inch vertices on the mesh i would like to have four corners for each points like one two three four as much as possible if you have like three neighbors then it will look like something these okay so to avoid having like these it's it's a good idea to have to define some kind of flow on a mesh for example in this kind of mesh if you have a curve like the if you have a curvature like these you can define the flow of this mesh in two ways one is oops one is in this way and one is in this way okay and you can retrieve this kind of direction by checking its principal curvature direction the principal curvature will give you a two direction values one uh in and this way and one in this way based on its curvature on a surface so by using this curvature i'm going to retrieve this directional value and use this flow value in order to define the flow of the mesh and in order to define in which way the quad should be created in which direction the quad should be created okay so step two is to create transceive pull curvature direction now after you have got this curvature it's time to start creating a quad mesh from a triangle and in order to do that what i'm gonna do is to pick the appropriate edge like these and dissolve it by dissolving i mean just delete it like this and by dissolving the edge of two triangles you'll be able to create this quad face now this is when i'm going to use the information of the curvature the principal curvature like which edge to dissolve so what i'm going to def what i'm going to do is to first of all let's bring this back let me undo this a little bit okay so what i'm gonna do is to first of all check for each point like each point okay and then check for uh each neighboring primitives like for example for this points if i have used this point if i have if i'm looking at this point then get the neighboring two primitives in this case either this pair this pair or this pair or this pair and so on like in an order so first of all i'm going to look at these pairs okay and calculate the direction from the center of this triangles to the center of this other triangle in the pair which is which the the direction will be look like these okay now what i'm going to do next is to compare this direction together with this principle direction either this one or this one let's say i'm going to use this this one the larger one and using some kind of using such as a dot product okay so dot let's say this is pv this is uh b one so and calculate dot product between the principal direction and the a direction for each pairs okay and do the same things for all the other pairs like these pairs or these pairs so it could be distraction destruction destruction destruction destruction destruction and destruction okay and you can assume that one of the curve or one of the direction will have the largest dot product the dot product will give you a value in between and negative 1 to positive 1 if the vectors used for this dot product is a unitized vector so what i'm going to do is to find out what's the largest what's the one that's close to 1 which means what's the one which close to parallel to this principle direction so in this case the vector direction which is parallel to this direction could be either this one or this one i mean this is actually give you a negative value but by making like absolute value you will have a volume between zero to one so and there's a chance that the principal curvature will just go this way this way this way this way like it's still the same direction but positive is flipped at some point so uh might be a good idea to make it absolute as a result of the dot product and just check its direction not the negativity of house liberty okay so it could be either this one or this one will be close to one and let's say i found out that this direction is most close to this principle curvatures direction then that's when you want to make this part make this edge dissolved to make a quad and that's for one iteration and after doing this one you do the same thing for all the other points until you can have it until it stops by can't find any like paired triangles anymore so do the same things for all the other edge like deleting these edges edges edges edges and so on okay and although there are some problems still left because at some point uh there are no more like triangle pairs sticking it to each other but there's still some triangles left and the isolated triangles okay so that's the next thing you want to fix for example if you have like a square like t spot and for the neighbor of the square you have this triangle and have a square like these so in this kind of situations you have two triangles it doesn't share its edges by as a pair so there's no way to dissolve its edges and it's connected to a prim a square like these so in this kind of cases what i could do what i could think of is to add a split line in the middle of this square and then dissolve the edge right here and right here okay as a result you'll be able to have one two three four and one two three four edges for each corners and be able to have a quad faces and they ring into each other so i'm going to do this split operation split and collapse operations as well to make as much quad as possible okay so this is step three a dissolving and step four split and collapse okay so after doing all these steps you still have some isolated triangles which could be a situation like these where the triangle is not really even not connected to any triangles even on the point edge point so in this kind of stations it's a bit hard to do the remesh by like split and re dissolving this kind of cases so to make it a bit more falsely converted into a quad i'm going to add a additional step to subdivide all the mesh all together using some something like a bilinear subdivisions meaning i'm going to split all the faces to make as a quad so in this case i'm going to split like these for each quad and for the triangles i'm going to add a center point and split like these so in this bit by doing this you'll be able to have like three quads four triangles and four quads for a already quartz faces and that's the final step for making the quad faces using sub divisions now you might think then it might you you might say you might say then why not just use subdivisions from the first but um if you do that then you'll be able to have a bunch of a lot of number of like uh meshes or quad mesh which have like three neighboring quads or more than three neighboring quads i'll show you what it looks like so if you have the geometry let's say i want to do the remesh for the sphere polygon starting with this kind of okay so this is already triangularly remeshed so if i try to do this subdivide i'm going to use this open subdiv by linear which makes the quad for each triangles if i try to do this looks like these which might be familiar to you if you're using if you ever use the subdivisions now it is still a quad basis but as you can see at some point you have like one two three four five six neighbored polygons and some points you have three polygon neighbors and there are no like four polygon neighbors in this kind of situations and that's not really what i really want but i want to have as much number of that as much number of like four neighbors as possible in these situations so this is the last dirty trick that i'm going to use to make to falsely convert the triangle into a quad okay so that's kind of a reason that i bring this on the last now after doing all these split and subdividing stuff you still need to do something more in order to because at some point you have uh kind of a deformed quad faces like these it it is a quad but it doesn't really look like a square it's kind of a bit deformed so what i want to do next as a final step is to make the deformed geometry close to a square shape as much as possible as um optimization okay so to do this i'm going to do a bit of um how do i say it uh similar to what i do for the force uh implementation or particle based physics simulations i do i am not going to use any vellum or anything i'm just going to do some simple simulations in order to make the face looks like a square so to do this the step looks like these so first of all let's say i have this kind of a kite like shape okay and for each point okay for each point i'm going to rotate each point like three times by the multiplication of 90 degrees meaning i'm going to rotate this first of all 90 degrees which in this case me using the center of the centroid of this geometry so this first point could cut could come something around here and the second point could come somewhere in here by rotating 180 degrees and by rotating 270 degrees the point could come somewhere around here and do the same for other points so for this point i'm going to rotate 90 degrees could come somewhere right here come around here come right here and for the third point which is this one i can i'm going to rotate rotate it 90 degrees 100 degrees and 27 and 80 degrees and last of all for these points rotate 90 degrees 180 degrees and 270 degrees so by doing this one by doing this kind of stuff you'll be able to have like four points at each corner like these okay and after having those four corner points i'm going to get the average point position of all these points so it could be somewhere around here could be somewhere around here could be somewhere around here could be same around here right now this point this cross point will going to be the goal where the corner point would want to go forward for so i'm going to create a directional value going from the corner to this cross corn point i'm not just going to move it by this distance but i'm going to make the distance a bit smaller so that i can slowly move the all edges close to this average and by continuing doing this at at the end you'll be able to have a clean quad face at the end okay so that's kind of a process what i'm going to use to make the each quad be a square as possible to make the as square as possible the reason why i'm using the small step for the moving each point is because each quad is facing like these so it's i think it's a good idea to make it slow to make to go slower so that each one will not affect each other that much in terms of the neighbors okay so that's one of the force that i'm going to implement to make it smooth and out for the quad now this is not um enough in order to make the quad uh clean as clean and much as clean as possible because by just having this one you might run into a situation that a some of the quad remain really small in terms of area like this even though it looks like squares you might having the differences between the area now this the center quad might be really small the quad which connects as a neighbor might be really big now this is also unbalanced so i want to fix that as well so as an additional force in order to move the vertices of each quad what i'm going to do is to first of all get the average area of all the faces which is inside the geometry get the average area so let's say a and you also want to calculate the area for each phase as well and you just want to calculate the differences between the average and the each area of the faces so by just doing the subtraction like a1 minus a n minus a average this will be the difference value okay so if it's too big if it's positive then this means you want to shrink the geometry you want to make this geometry smaller if this negative then that means the the current um area is smaller than the average so that in that case you want to make the faces bigger you want to expand the geometry so looking at the negativity or positivity you want to expand the faces in this direction or shrink the geometry in this direction inward in this case using the same forces for each vertices going into the center or two outward from the center using the value of this difference as uh a strings and this thing as well might be better to make it small uh values because it uh it is all connected to each other so by moving this points at one of the quad it will affect the other neighboring quad so i think it's a good idea to make the four strings small as possible but as to make it bigger you'll be able to have a fast like result but you want to reduce the strength as much as possible to so that the simulations would not like destroy the whole geometry by moving the points too fast okay so that is the final step smoothing and that's kind of all that i'm going to do in order to create a this quick and dirty remesh it that sounds like a lot but if you try to do a more sophisticated remeshing stuff it's going to cost more i think if you look at some some paper for the quadro meshing you'll be able to see what it's like one of the one of the paper that you could look at for the quad remeshing uh let me search for i think it was called as quad cover quadriratural cover okay forgot uh where what's that but um the thing is that there is already a bunch of plugins for quad remesher if you just want those result then i think it's a good idea just you just use these because what i'm going to implement here is just a kind of experiment just kind of a geometrical like practices to understand a bit of the mesh structures and then that's probably it might be not ready for production at all compared to other like sophisticated plugins so that's the reminder and let's start implementing what i have just explained okay so let's do this so first thing first let's um prepare some geometry that i would like to remash i think it's it will be a good idea to have a bunch of like different curvatures so i'm just going to try to create some metal geometry or maybe i could also use like a sample geometry so test geometry like pig head okay i'll just use this big head as a sample geometry okay although this has already been quad remesh so might not really need to do anything for these but let's say let's assume that you don't have this kind of information so first of all i'm going to delete the texture information which is not necessary right now using attribute delete i'm going to delete the texture the material from primitive okay now i'm going to the first step is to rematch this geometry as a triangular shape so remesh i'm just gonna use this is the first step so let's call this first step or step one triangular remesh and this is going to be the base of the quad remesh so it might be it might also be a good idea if you can control the point positions for this triangular mesh but since i'm gonna do it quick and dirty way no i'm just gonna use the result as it is okay so first thing you want to define is the resolutions of the quad of this triangle remesh let's say somewhere around two five star with start with a low res okay after all i am going to use the subdivisions to retrieve the quads later so it's going to have you're going to have a bit more high res result meaning if i use the subdivide now this one still is a bit dirty too dirty as a quad so i'm not going to go straight forward straight to the subdivide but first thing i would like to do is to calculate the principal curvature of this geometry then use that information to dissolve the edge of the triangle using the directional information so it's time to calculate the a principal curvature to do that it might not be a good idea to calculate the curvature from this geometry from this remesh geometry because it has already been a rematch in low res because so the result that you get as a principal curvature might be not accurate enough so i'm going to go back to the original geometry and use this one to estimate the principal curvature i'm going to make this a bit more high res by using another remesh with a bit more low number of less number of target size let's say 0.1 or a point zero seven and so on so that you have enough points to calculate its principal curvatures okay now from this geometry i am going to calculate the curvature using the measure node and then connect it like this and choose the curvature for each point and for the curvature i'm going to use this principle and change this to direction or it could be a vector as well the vector will give you a a amount of curvatures as well but in this case i think just having the direction is fine as a unitized direction because i'm just going to use it for a dot product now you can use either smaller or roger the larger one the smaller one will have you a bit more stre direction which the point will go forward for the straightened face the larger will give you a bit more curved direction more and the smaller and larger is defined by a perpendicular direction so you can i think you can use either way uh in my case i am going to use the smaller okay so that i want to use this flow to dissolve the edge okay to make another as an additional process that i'm gonna what i would like to use and what i would like to do for it at this point is since the original mesh might be a bit too jaggy in some cases which will give you kind of a jaggy a curvature result as well so in those kind of situations i'm going to also blur this geometry a little bit so that the curvature the result of the curvature might not be too accurate but can be really smooth so i'm going to use this attribute blur to blur the positions to smoothen out the positions a little bit and as a result the curvature will be smoother as well so compare with and without this smoothness you can see that the curvature becomes a bit smoother now you can forcefully do the you can forcefully strengthen the blur by increasing this blue iterations which will create a bit more smoother like result like these which it could also be fine because this curvature is just going to be used as a guide which edges to dissolve okay so having more blurring iterations to make the whole curvature smoother might be also be a good idea so i'm gonna go with the 10 for now okay oh hi uh stain slab thank you for the super chat appreciate it now uh after having the smoother high curvature value um it might not be a good idea to keep this blurred result below geometry result as it is because i'm going to i have to use this to refer as a reference for each of the point from this remesh geometry and to do that it needs to have it all the points needs to be in the original position as much as possible so after do after calculating this measure node or curvature i'm going to make the point position back to the original positions by using the point wrangle so this is the deformed geometry and this is the original geometry so reach let's say reshape what i'm going to do is pretty simple we're just referring to the point positions from the second input which is the original point positions p [Music] at pt num and then override the current point position which is this default point position with the reference point position that's it and you'll be able to make the geometry back to the original positions but keep the curvature as the one that i've calculated right here so let's check that curvature direction i can have a marker curvature curvature as a vector okay and let's make this wireframe so it's a bit hard to see you can see that the direction but it's a bit hard to see though let me go back to the flat shaded okay so as you can see the result is good enough if you want to have more smoothen out uh curvature you have you can increase this iterations and see the result see that more more blurring value you have you'll be able to smoothen out the curvature as much as possible now let's keep it as 10 for now okay and i'm gonna make this back to a smooth with shaded okay so now that i have this reference informations what i'm going to do next is to use this one to decide which edge i should resolve for this triangular meshes okay and i have to do one by one iteratively if i do it for one point neighbors then by default there by deciding which edge to dissolve i have to solve it first then go to the next point to calculate the other points okay and probably the order of which points to pick next might be important but i'm going to do it randomly this time to make it as i said quick and dirty so first thing i'm going to do is to use the sort to randomize the point order so that i can pick up the point randomly so i'll make this random these okay now to pick up the point iteratively one by one after doing the resolving the easiest way i could think off is to use the for each feedback loop so i'm going to use this for each number to do that i'm going to set the for loop to a feed package situations for for each end and feedback fetch feedback as a a for each begin which will create a feedback loop node okay and in between then i'm going to create a node to get one of the point one of the random points and then get the neighbors the neighbor polygons for that from that point let's say i'm going to pick this point and get all the primitives and then get the pairs to get the neighboring pairs from those polygons and calculate the direction from the center of the triangles to the neighboring triangles and use this direction with the referenced principal curvature from this geometry to calculate the dot product and if the dot product is the largest then that's the edge that's the pairs that i want to dissolve and that and then after deciding which edge to dissolve i'm going to use a node like dissolve node to dissolve that edge and that's for the one loop and i'm going to continue doing that it iteratively again and again until you don't have any triangle pairs anymore okay so let's try to do that okay i am going to use a and i think it's a good idea it still is a random the right the point order is still random but i think it's a good idea to start from the point which has the largest number of neighbors because i want to reduce the number of neighbors as much as possible until it becomes four okay so thinking like that i can i can first calculate the neighbor count for each point by using like point wrangle let's name this an account and let's calculate the neighbor count by an extra apply to an attribute of each point as an n count calculate the neighbor account neighbor account at p t num all right now look at the geometry spreadsheet you have like from four to nine okay so what i'm going to do here is to start from the point which has the largest number of neighbor count like nine if you have a num so many number of neighbors then by dissolving one of the pairs you'll be able to decrease the neighbor count into [Music] in this case nine minus one and becomes eight okay so making as much number of uh four neighbors as much as much as possible is a good idea so i would like to start by um stop by the dissolving from which has the largest number of neighbor count okay so that's kind of idea so after getting the neighbor count i'm going to reorder the point again using the sword so i might not need to do this sword after all just but just in case i don't know how it works in houdini when you do the like two different kind of sword together i'm not sure if well if this sorting will use the result from the previous order or just just redo the stuff all over again if it does then might not be really necessary but just in case okay so for the point sort i'm going to use the attribute and count which is the neighbor count that i've just created and make it reverse point sort so that it will start from the largest neighbor count just like this so starting from 9 and at 4. okay that's good now's the time to actually do the dissolving part now you can uh you you you can do the dissolving directly inside the like wrangles but instead of doing that i'm going to use the dissolve so in order to use the dissolve node you have to define which edge to dissolve by defining as a group okay in this case you have to define the edge group right here so i'm what i'm going to do is to create some wrangle like an attribute wrangle to look for each point and then dissolve one of the edge and make these edge as a dissolving group and use this dissolve node to dissolve that edge and finally you'll be able to have a result and first result and then go back to the first step and do the same step over over again over and over again until you have no triangle pairs so let's name this group as dissolve edge group currently i don't have any dissolve edge group so it gives you an error it's not a problem okay and for this attribute wrangle let's name this um choose dissolve edge and to choose i need to ha access the principle coverage information so i'm going to connect this geometry that i've created with a curvature i attribute to the second input of this attribute wrangle and for this attribute or angle i am going to change this to a detail because i don't want to simultaneously access to each point because that will mess up the uh calculations you want you don't want to simultaneously parallelly calculate for each point but you just want to go one points at a time okay so for that reason i'm going to set it as a detail all right so it's time to write some first code first step of a code see what i need to do for that okay so here's the ball i am going to create a loop accessing to let me open up the editor okay first of all i'm going to loop all the points look through all the points on the geometry using endpoints and points instead total number of this mesh right and uh in this case i will be the number of the point the point number okay now next thing i would like to do is to get the neighbor informations at each point so end neighbor point list uh using neighbors okay and thing is that i don't really need to do the remeshing or i don't really need to dissolve the edge if the length of the neighbor is the less than three if it's less than three if it's less than equal than three then you don't really want to dissolve the mesh otherwise you're going to the situations that i'm going what i'm talking about is something that look like these so let's say you have square you have square and you have triangle or maybe a bit more other situations you have one square and you have for this point and you have two triangles like these okay this is situations that i'm talking about and this triangle is connected and as at the edge as a neighbor so you could dissolve this edge to make it as a quad but you don't really want to do that because by doing that you are having two quad sharing the two edge at the same time like these which will give you a bit of problem in terms of the mesh structures you'll be able to have you are going to have a bit of problem right here rendering it so if it's less than or equal to three then you want to key even though if this a triangle geometry you don't want to dissolve this kind of stuff you want to keep it as a triangles and leave it to a subdivision subdivisions to make it a crystal quad so doing like these instead of dissolving okay that's one small rule here okay saying okay sorry my thumbnail is blocking the code sorry for that so uh this is what i've been writing writing for i'm using the for loop to accessing each points and get the neighbors list point uh using the neighbors function then checking if the neighbor has less than or equal to three okay if it's less than or equal to three then that's not the point that i want to use for the dissolving so i'm going to skip this by saying return or continue probably continue go to the next point okay hello everybody okay now let's uh try to then get the uh all the neighboring points or all the neighboring like primitives at each point okay so to do that let's let me think that's the best way so first of all i'm going to define the max dot product value starting from zero because i'm going to use the absolute value the negative the minimum value of the dot product will be equal to zero okay and then i'm also going to retrieve the curvature at the point position from the second input okay to do that you can i'm going to name this curve so using the point functions access to the second input the name of the attribute that i want to access is the curvature and actually no this is not the right way to do it but actually what i want to do is to first of all um get the current point position at i iteration when the iteration is equal to i so vector point position bt plus is equal to point zero p at i so this is the current point position for each iterations could be somewhere around here could be somewhere here starting from the neighbor equal to nine in this case and using this point positions i'm going to sample the curvature from the second input which is this one so to do that you can use the function call uv sample from the second input the attribute that i want to sample is curvature and the uv value that i want to use to sample is point position and the actual point position that i want to use for the sampling is pt pass that i've just retrieved now by doing this you'll be able to get the closest curvature value at this at each of the point from this reference geometry right now that i have this point position i am going to um get the neighbor point from each of the neighbors list that i have retrieved right here to see which edge which pairs of the triangles have the largest dot product i mean the close to the principal direction in terms of the its center under center direction so four and i'm going to create another for loop and let me change the first i value to t doesn't really make any changes but just in case because and the sample that i had created previously i make this name this as t so so that i don't get confused too much okay so i'm going to create another for loop in this case i'm going to use i as an iteration value and the number of iterations that i'm going to do for this loop is the number of neighbors so for each neighbors i'm going to create the calculations so let's say i'm going i'm looking at this point and looking at each of the point using the number of neighbor points for this point as a loop iteration number and let's say this is the first iterations this is the first neighbor points what i'm going to do is to use the half edge structures to get the neighbor of this edge from on the right side and the left side okay and if these are triangles i'm going to retrieve the direction connecting the center of each triangles and calculate the dot product and see if it's bigger than the current maximum dot product if it is then update the max product and hopefully that will be the one that i want to dissolve so let's see so retrieve the neighbor information neighbor point numbers and then um as i said i want to use the half edge to retrieve the primitive at the right side and the left side so i'm going to get the half edge information first so let's say i'm going to name the first half edge informations going from the the original point to the neighbor as a previous half edge and from the neighbor to the starting point b as a next half edge or half edge one or half h2 right away so p off edge is the half edge informations going from using the point hedge function at the zero connections with zero geometry informations so t is the first point which is equal to this one which is the current point number and the neighbor nay is the neighboring point number which is this one if you are looking at this one as a t so this is t this is nay okay so this is the first half edge the second half edge you want to get is the point edge neighboring point to a current point position current point number so just make these reversed okay so from each of the half edge you'll be able to retrieve the primitive number as well so that's what you want to do next okay now but before doing that you might also want to check the other stuff as well uh look using the neighbor point like for example in this case this is the current point and this is the neighbor point okay at the neighbor point you also want to retrieve the number of primitives which is attached to this neighbors okay and you want to check if it is if it if the neighbor point if the neighbor primitive uh let's say let's say what i'm gonna do so wait a minute that was too fast okay so forget about that and first thing i want to like do is to get the primitive number out of these half edges so let's name the first primitive number as p prime so h using the h prim function and for the next primitive i'm going to use the same function and hatch okay so by doing this you'll be able to get the primitive number for this one and this one if it's starting point to the end point at the neighbor point using uh using this as a half edge you'll be able to get i think this primitive or this parameter i forgot which one i think it was in clockwise order probably so probably this one and for the half edge going from this one to this one then you'll be able to get this primitive out of this hatch primitive okay now that you have a two primitives you can get the center point from for each point from each triangle primitive and calculate the direction but to do that you may you have to make sure that these neighboring primitives are triangular okay meaning you have three vertices there is a chance that they're you getting the quad phase as well in those cases you want to like skip that phase to calculate because you don't want to dissolve that edge so you want to calculate the lengths of the current points to retrieve the number of edges or number of vertices it has for each primitive so the length of print points will give you a number of vertices for each primitive in this case a pa primitive and if it's equal to three and uh the length of frame points zero next primitive is also equal to three then that's the condition you want to do the you want to calculate the dot product okay okay i think i'm getting the error let's see where that is uh okay 18 18 prime primitive is this what i'm doing wrong nope is this what i'm doing wrong yep okay so let's see what i did wrong here so and p prime edge prem doesn't look wrong but it is see why enable to load shared shader 18 referenced and defined variable p hatch okay spell mistake all right typos okay so if uh the neighboring primitives is has the is triangular with this conditions then that's when you want to calculate the direction going from the one of the center to the other center so let's get the center position for each primitive vector p pass let's see code 2 prim 0 p p prime which will give you a centroid of the primitive next one and pause prim zero p and prim the other centroid now you can calculate the direction going from one of the point to the other point let's also normalize this and plus minus p plus right now after doing this you can now calculate the dot product between the curvature that you have retrieved right here so load dot val is equal to a dot between the direction and the curvature and you want to make sure you are getting the absolute value because could be like a reverse direction 180 degrees reversed so to make sure that i'm just looking at its direction without its or negativity just going to make it positive and just want to retrieve the largest value the largest absolute value as much as possible so if this dot value is bigger than the max dot then i want to update the max dot product to the current dot value and i also want to retrieve the the current point number that i have retrieved and the current neighbor point as a target point so that i can get two points to see which edge is the uh the largest uh which edge should be dissolved so indeed i do need to have a a variable which stores that information so i'm gonna go outside the loop and create two integer parameters integer variables we one is pick source starting with -1 and pick the destination starting with the negative okay going back here if you have found out that the current dot value is larger than the current max dot then the max dot will be updated and also the pick source and pick destination is also be updated in this case the pixels will be updated with the t which is the current point number this one and the pick destination is updated with the current neighbor information which is nay so like this all right okay so and this is all good i think and as soon as you found out as soon as the pick source or pix destination has been found down in this loop then you don't want to you might you can just leave the loop um as soon as possi as soon as it this has been updated you do want to do all the iteration you do want to operate for this loop until it ends because it's just looking at all the neighbors at each one of the point but after after you you have found any point can be used for the dissolving then that's when you want to leave this whole loop and this the parent loop you are looking at each point from the largest number of point uh neighboring number to the lowest so after leaving this loop differ the the children child loop i'm going to check if the pick source has been updated if it's more than zero then that means some number has been applied other than negative one so that's when you want to leave this whole loop so just i'm just going to say break okay now that i have left all those loops it's time to set the edge group to diff say that that's the edge that i want to dissolve which connects with this source number and the destination number so um if the pick source is more than zero more than or equal to zero then set edge group then the name of the edge group that i want to apply is dissolve and connecting pick source point number to the pick destination point number as one okay apply and you probably want to define um when to stop this whole loop this for each loop as well and to do that you can set you can define when to stop by checking if the current pick source is negative if it's negative that means no pixels has been chosen even though i have looked through all the points okay meaning you you couldn't find any like triangle triangular pairs in this in this situations meaning there are no more loops you need to go for there are no more dissolving steps you need to go for so that's the time when you want to stop the whole feedback loop so in that case i'm going to set the detail attribute i'm going to since we are in the detail attribute i can say at i at stop two one okay i gotta use this with inside this stop conditions later but for now let's leave that and going back to this add dissolve and one of the edge must have been dissolved and you can see that i'm gonna start by setting this to iterations equal to one and let's see which edge has been dissolved it's a bit hard to see but one of the edge must have been dissolved and probably this one right here okay and let's also check the go back to this reshape and check its curvature and if it's doing what it does so by looking at this curvature i can see i can see that the flow is going somewhere in this direction somewhere around here okay so this is the direction that we're looking at and using this curvature i have just resolved one of the edge right here and this is if you try to get the direction from the center of this triangles to the center of this neighboring triangles you could kind of see that its direction is pretty similar to its principle curvature i mean curvature direction so that's that's the reason why this edge has been chosen to dissolve for these for this direction it's a bit uh far off maybe this is pretty close but for the other direction is a bit too far off now this was the closest edge this was the closest direction so that's the reason why this edge has been chosen to dissolve okay so that was for the first loop and by increasing the loop iterations you are looking more and uh more and more edges until it finds it no longer finds out the triangle pairs so i'm going to increase the iterations to let's say 100 start see more dissolved edges maybe you can increase more like a thousand and now you see probably you don't really have any triangle pairs anymore like these okay looks good now you can make as you can make this number as much bigger as possible but well which will create the calculation times also bigger so that's when you want to use this stop conditions to stop as soon as you don't find any triangle pairs anymore so if if the detail attribute has the stop integer stop attribute then if it's equal to one then that's the timing when you want to stop this loop so i'm going to create the new node at the starting point let's name this state okay i'm gonna check the detail attribute of this state and if you have the condition attribute called stop and is equal to 1 then that's the time when you want to stop this feedback loop so going into the stop conditions i'm going to refer to that attribute detail attribute so i'm using expressions detail state and stop at zero index if it's equal to one then that's when you want to stop and as you can see by doing that you'll be able to reduce the number of feedback loop like these so the maximum number in this case is 212. so in that case you can increase this iterations as much as possible as much as possible but still be reduced to a minimum number all right that's good so i'm gonna keep this iterations to 10 000 but still you the feedback loop end at 200 right now let's try to change the smoothness of the curvature and see the difference what it creates if i set the blurring iterations to zero then you you start to see a bit more random-ish uh dissolving result it does is still use the the original like curvature so it does refer to a curvature it still does referring to the curvature but the result you get a bit could be a bit more uh randomized in terms of the direction if you make this like 20 the direction might becomes a bit more smoother in terms of the flow probably i'm gonna keep it to maybe 15 okay so that's that and there is one condition i didn't applied for this dissolving edge so i would like to add that as well and i gotta remember what was the condition to use that so let me save this first and open up the editor okay so there is some situations that i want to skip calculating the dot product and let me think what was that conditions about okay so i'm going to go to the sketch here and okay i'm checking out the samples right now and let's so the point has several neighbors like these and this is the t this is the name i'm just gonna call n right and if the neighbor primitive have something like three neighbors three primitive neighbors meaning could be situations like these okay in that case in that case you might not want to dissolve this edge because that will give you by dissolving this one you'll be you're having this kind of situations same as the same reasons as previously the one of the tr one triangle is sharing two edge from the quads which will give you a kind of a irregular mesh which you don't really want so in those cases you don't want to dissolve it you want to skip dissolving that so let's add that condition okay so going back to the code so it's probably that could be somewhere somewhere around here okay and okay probably i also want to [Music] add another uh conditions as well there the case what i was talking about is when the point is at the the center of the mesh okay so but there is a situations that you are looking at the naked edge of the mesh or i mean the unshared edge of the mesh so let's say this is the mesh we are talking about and this is the unshared edge meaning there are no connection in this slide it's empty it's the we call this unshared edge or naked edge okay in those cases the neighbor of this point is either this one this one or this one or this one okay and there is a chance that uh if you look at this point as a neighbor like this is a t and this is a neighbor and currently previously we are getting the two half edge values one for these one for these one for this direction one for this other direction and to retrieve the two top two primitives two neighboring primitives but in this case there are no like neighboring parameters available in this case so as a result what you get as a half edge information like if you get if you try to get the half edge going from t to n you get a half edge value let's say equal to a and if you try to get the half edge from n to t you get the same half edge information called a if you don't have any like neighboring primitive so that's a problem because this this gives you same numbers or which will if you try to get the primitive number out of these half edge you get the same triangle geometry triangle primitive and if you try to get the directions then you get zero and you'll be you're not be able to calculate the dot product using those values so that's also the condition when you want to skip calculating the dot product so there are two conditions you want to skip first of all the first conditions if uh the neighbor point has a three pyramid primitive then you want to skip that so if a lens of first of all let's get the neighbor primitive neighbor neighbor neighbor primitive the neighbor primitives of the neighbor point it's a bit confusing so nay nay prims is equal to point prims zero name naver and if the length of the nave nay prims is equal to three and as well as the the current as well as if the this neighbor primitives include the this primitive number right uh primitive number right here or the frame term number right here if that's the situations then that's when you want to skip calculating so find nay nay nay prims and cream let's see larger than zero and find nay nay frames p prime larger than or equal to zero okay then that's the situations you won't skip this iterations and go to the next one all right so that's one situations and other another situations is if the p h the half edge one and half h two is equal then that's also the situations you want to skip so and edge then also continue okay let's apply in this kind of a small sample you might not get into that kind of situation that much but just let's make sure that we we cover everything we need so i think this is fine let's accept and this is the step to dissolving takes a bit of time but more set step two dissolve now what was the step three now step three is to get one of the situations you could convert the triangles into quad for example in this samples one of the situations that i'm talking about is kind of this one so triangle you have two triangles sharing the same vertices vertex and it is connected to the same quad mesh okay so this three pairs three value three two triangles and one quad pair can be converted into two quads by adding a split line on the center of the squad then dissolve the edge right here and right here then as a result you'll be able to have the two quads from these informations okay so that is to make as much quad face as much as possible before we get it into the subdivisions this one as well you can retrieve these pairs and then add the split line either this way or this way and then dissolve the edge to get two quads okay so that's what i would like to do here let's see how we could do that okay so first thing first let me reset some of the attribute that i have set something like a detail attribute like stop so i'm going to do like attribute delete delete unnecessary attributes so for detail stop for the other one probably don't need the texture v in count positions probably these end count is no more appropriate so i'm also going to delete that okay so clean the attributes up and let's try to do this now for this one as well i'm going i do have to do one by one and find out the problematic pairs where i want to add the split line and dissolve so like i did last time i'm going to use another for each loop pretty similar to this is not going to take that much of a time in terms of the calculation but the things that i'm going to do is pretty similar so feedback loop batch feedback okay starting with the 10 i think it's good now and like what like we did last time with this one in order to stop i'm going to create another new node let's call this state 2. and it's also sorted out the primitive again and to do that i'm would like to recount the the neighbor count so that i i still want to dissolve where the point has the largest neighbor account i i think by doing this first iterations first feedback loop i have reduced the number of neighbors but there are still like neighbors available which has a lot of they've account like these like one two three four five and so on more than four so i'm gonna start with these i'm going to check with these points which have more than four neighbors so to do that pretty much i'm doing the same things i'm first going to calculate innate neighbor counts i'm going to copy this one apply it here and check the geometry spreadsheet for those points so currently the maximum neighbor count is equal to six okay so i also want to sort it out based on those and count so i'm going to do another sort node for the point this sold out based on the end count and there you go going from six to three all right now next thing now that i have those value what i'm going to do is to create another detail attribute attribute triangle make this as a detail and what was i doing um split collapse okay and this is going to be the step three so let's let's through that so like we did last time i'm going to loop through all the points first using the loop through all the points let me open up the code editor again okay so four and i zero and points so previously i was using t as an iteration number currently i'm using i because in the sample i use i that's the only reason okay i'm also going to create a number called pt just replace with the eye and just copy the i value which no it's not that necessary but just to make sure i can i know that this high value is related to the point to have less human errors okay now i'm going to get the neighbors out of all the points at each point so currently if i'm looking at this point i'm going to retrieve all the neighbor points again so int neighbors list is equal to neighbors zero at pt okay and the number uh though the conditions where i want to look at in currently is where the neighbor the number of neighbors equal to or more than four okay if it's if it's three then you don't want to dissolve and collapse anymore so if the length of the neighbors is more than four more than or equal to four you could say more than or equal or just more than four you could skip the number four if the quad if the naval point number is equal to four then you might also want to skip that as well situations like these you have a i mean this is the situations that i'm looking talking about but uh let's see if there's the conditions what i want to talk about [Music] not really i don't see i don't see it don't see much okay maybe well you can maybe i'll show what it's what's the difference between going into equal or more than four or just more than four i'm gonna go with more than four okay now uh first thing i would like to do is to access all the neighbors uh let's i want to look at let's say i'm looking at these ah so this is when the you have two triangles sharing the same points and you have four neighbors so in this kind of uh conditions this point will going to be skipped so the this quad is not going to be split into two and this is not going to be this converted into two mesh the reason why i'm skipping right here is because by doing that you'll be able you are having three quad neighbors at this point but the result that i want is actually having four quad neighbors so that's kind of a reason why i'm skipping this one but since it still is a triangle even though you have four neighbors so it might also be okay you splitting this into a three quads um based on some situations but i didn't really go that far to see if that's good or bad so i'm gonna i'm gonna go with more than four for now and this could be a situations that could match with these situations so you have these two triangles one quads right here and you have five a neighbors so this can be and this situation is could be the one that i would like to do the rematch so and this is actually not like triangles but this is actually a quad because you have four points all right so after having this kind of situations i'm going to loop through all the neighbor points using another loop and length of neighbors okay and get the neighbor value navy point information now i am still going to get the half edge informations okay at one of the points so let's say by looking at looking at this point currently as a pt the first neighbor point let's say this is the first neighbor point right here and what i would like to do is to get the half edge information going from the this center point to the neighbor point so end is equal to point h zero p t neighbor okay and you can actually get the the equivalent uh half edge going from the neighbor to the center previously i was using like a point hedge from naver to pt but there is other way to retrieve the same things that is to use function called hedge next equivalent so equivalent edge one is equal to edge next equiv equivalent zero i attach which is um similar to what we did getting the half edge from the neighbor to the pt okay it doesn't really matter which one you use all right now the next thing i like to do is to since i want to get the the conditions where i have first triangle and then have quads and then the next one becomes triangle so what i'm doing here is [Music] first of all get the the half edge going from this point to let's say um let me think what i did so first of all let's i think i have retrieved this half edge right here then go to the next half edge which is from this point to this point okay and the next thing i'm doing here and doing is to retrieve try to retrieve the the next neighboring edge so to do that the the good idea is to so first get the half edge going from this point to this point then use the equivalent half edge going from this point to this point which belongs to this primitive okay then by using another half edge function called edge half edge next you'll be able to get the clockwise off edge uh next directions so if you if you for this primitive if you're going from this point to this point then the next half edge you can get is this point to this point okay then by using the another equivalent half edge equivalent functions you'll be able to get the half edge going from this point to this point for this triangle mesh okay and using the same half edge next you'll be able to get the half edge from this point to this point which is on top of this primitive so as a result you'll be able to get three edge informations okay by having those three point informations you'll be able to estimate whether those uh each of the primitive has the the met conditions three four three or three three three or three four four so so on if it's if the primitive vertices number is equal to three four three then that's the situations you want to do this split and dissolve and that's kind of reason why i'm using half edge to find out those situations okay i hope it makes sense if i write in the sketch and let's see so starting from the first half edge let's say h1 okay then which belongs to this triangle right here then using the half edge equivalent you'll be able to get this other side half edge let's call this half edge one dash or quote okay and then by using this one by using the next half edge function you'll be able to get the clockwise directional off edge one by one so the next one will be this half edge half edge two inside this primitive okay and by using this half edge two you'll be able to get another equivalent half edge for this next triangle let's call this half edge to quote and this from this half edge to quote you'll be able to get the next half edge which inside this triangle mesh which is half h3 okay as a result you'll be able to have this three types of a half edge which belongs to different primitives but neighbor to each other adhere to each other like these so by using those half edge you you'll be able to get the primitive numbers p1 p2 and p3 and you also be able to get the number of like vertices for those primitive this is equal to three this is equal to four this is equal to three and if it's three four three and that's the situations you want to add the split line and dissolve those lines connecting triangles and quads and as a result you'll be able to get two quads one and two okay which might not be which might not sounds like easy but that's the things that i'm going to do so probably this is one of the good example using hot fetch like what's the half edge for many people ask me what why you use half edge but uh when you're dealing with the meshes it's pretty important mesh structures like in this kind of situations when you you when you want to do the analytical like process so let's see so this is the off uh first equivalent half edge value and let's also let's name this half h1 okay and the next thing i would like to get is the half edge 2 which is the next half edge of this equivalent half edge so you to get that you can use the function called hedge next and for this equivalent of edge one which belongs to the these one belongs to the second primitive this one belongs to the first primitive now do the thing for the third one and equiv off edge to is equal to half edge next equiv zero gotta call this one hatch two and and edge three edge next zero equiv edge two just like that so now i have just retrieved three half edges belongs to different primitive and adhere to each other h1 h2 and h3 right now it's time to retrieve the primitive numbers out of these half edges so let's do that prim 1 is equal to edge prim zero okay i'm getting hungry more thirsty i don't have any water right here okay and do the same for a primitive two to primitive three for half edge two and half edge three okay now i also want to get the vertices numbers for each primitive so int um pt count one is equal to a lens of prim points at prim one do the same for the primitive two and primitive three okay now the condition where we want to get at the split line is if the pt count 1 is equal to three and pt count two is equal to four and pt count three is equal to three three four three right now let's do this so after we have retrieved the point of information we need to in order to dissolve in order to split i think there is a node to split the geometry in houdini as well but it's a bit hard to use something like polysprit in order to use this polysprit node you have to define you have to have a additional node to such as like curves and i'm not sure what kind of types you can set as a split locations maybe a point number if that's all might be easier to do let me test this out um if i have a grid two by two okay and you have zero one two three so let's say i wanna create the split line from the point number one to point number two see how i can do that if i can do that with these nope can this maybe this split location doesn't really allow you to enter any point numbers but you might have to define the curve like a line geometry what's this split from this point to this point enter okay so it says ah some pro seems like you have to define the vertices numbers to use this polysprit and i'm not sure if it's if you can use a [Music] if you can use the what was i trying to say if you can use the attribute there is one called edge group so maybe this can be used edge group let me see i haven't really used this note that much so gotta try this out i'm gonna use the detail and let's say set edge group connecting let me say split connecting one and two but this is not really an edge so might not work okay so did it more really work so instead of using this node i am going to like recreate the mesh we create four uh two meshes out of uh the two triangles so where was i looking at so this one so meaning i am going to create one one two three four quad right here and one two three four quad right here and delete those triangles and quads right here so deleting those three primitives and add those four vertices mesh procedurally using vex that's what i'm gonna do here all right instead of using polysplit node which might be straightforward and might be a good idea all right so let's see what i need to do what i need to do is to retrieve those point informations in order to create those primitive that i need so let's see first thing first i would need to retrieve all those target points which is in this case so this is going to be the first point this is the first point this is the destination uh which comes from the neighbors okay and this is the what was that the um what was it uh the equip hatch to the goal of the h2 so you can also get that this is the goal of the h3 and what we are missing is this point right here and this point right here okay so let's try to retrieve that all right so first thing first i'm going to get the missing points which is the point number of this uh half edge two and half edge three all right so i'm probably for the half h1 as well so meaning i'll be able to get three target points so end destination one the edge this dst point which will give you a destination point from the half edge of h1 do the same for two and three two and three all right now i'm also going to a retrieve the um oh what was i trying to do i'm also going to retrieve the primitive points out of the first primitive which is this one right here so which is going to be this triangle right here is it oh no no actually i want to get this point for this quad so i should use this primitive which is equal to primitive 2 and out of this primitive i want to retrieve this point number so first of all i'm going to get the p point number ira from this primitive to uh prem pts two is equal to prime points zero at prim two okay and just want to retrieve this point so to do that um the easiest way i could think of i mean there are probably several ways you could think of like one one one of the way is to use the half edge two and by using the another hot hedge next you'll be able to get this half edge right here going from this point to this point and get the destination point off this next half edge and you'll be able to get this point so maybe that's much clever so let's do that half edge two two two one two just a two two or two diagonal is equal to half edge next zero edge two okay and you'll be able to get the this point number uh how do i call this destination 4 is h tst point zero h2d or destination 2d i don't mean by two dimensional i mean by two diagonal okay all right so do i have enough information do we i think i'm still missing the this point right here which i'm not sure if i have retrieved somewhere not sure not really sure maybe not so let's also retrieve this one as well you can get that the same way i did for this thing here so which can be a half edge neck you can use the same half edge next functions for this half edge right here which is the half inch one okay so the next half edge for this half edge is it's going to be this one this direction and this by getting the destination point you'll be able to get this point right here also let's call that destination zero and dst zero first of all i'm going to get the half edge so half edge one d is equal to half edge next zero off edge one and then get the destination i'll just go one one d and edge dst point zero of edge one d all right okay now i think i have enough point is to create two quads one for these one for these so let's try this out so [Music] i'm going to create the primitive new premium one new quad one at prim zero poly now i think it has to be counterclockwise or clockwise i forgot which direction let's try this out from clockwise so looking at these one so this is the first point which is equivalent to i or pt so pt comes first the next point let's start with these right hand side here and so the this point right here is destination two d so d is t to d and this point right here is dst one this one dst one and this one right here is dst 1d dst 1d okay so that's one quad another quad new quad 2 is equal to at frame 0. probably starting with the same number pt this way i'm going to connect from this direction so this one right here is dst three so dsd three and then comes this one which is equal to dst two was it dst okay i think so dst 2 and finally comes right here which is dst 2d so dst 2d okay apply and something has been changed i think let's make this limit the number to one for now so that i can see clearly where has been changed okay seems like this right here has been changed somehow is that the situations that we wanted now we also want to delete the unnecessary primitive so if i am adding these primitive then i should remove this two triangles and this quad so let's see i can do it somewhere around here probably so do do do and if no just say remove prim zero so in order to get the primitive number i think i already did these one okay so remove frame frame one and do the same for all these and after i have removed the primitive i can just leave the first loop the the feedback loop at this time so i can just leave the for all the functions by saying return okay that's probably it and let's see what else i need to do in some situations in some situations i might want to [Music] i might want to skip dividing those quads maybe this could be one of the situations when when when you see this quads and if you create a split line right here you see that the it's getting really long triangular face or really long edge diagonal edge right here might not be in that case it might not be really a good idea to add the edge in this direction but might be a good idea to add in this direction which will still create a triangle but can keep the length for each edge as same as much as possible okay so but in that case you need to you might need to add another two quads right here which might be a lot of work to do so i'm just going to skip splitting the edge when the when comparing the diagonal lengths from this edge and this edge and if this this the edge that i'm trying going to trying to split is longer than the other diagonal edge then i'm just going to skip those one to be split it okay you can add your original like custom implementation to make a bit more smarter but in this case in my case i'm just going to skip so to do that i need to get the distance between these diagonal points and these diagonal points so let's do that first float this one is equal to so i do i already have the point enough point numbers so i just need to get the point positions so from this to this from this one is the pt so vector plus one is equal to point p at pt vector 2 which this one right here is a coming from the destination one this one right here so copy this one right here this dst one okay another one vector plus three for this point this is equivalent to a hatch to d or destination 2d so dst to t and the last point positions for the squad right here is equivalent to dsd2 dst2 right now i can calculate the two diagonal distance first let's get the distance between this point to this point where i want to create a split line so distance between the current position one two position three and the other direction distance between the position due to position four now compare those two and if the distance one is smaller than the diagonal distance then that's when i want to split so if this one is smaller than distance two then do the split all right and then after as soon as it has created the split just leave this whole loop this whole function then go to the next feedback loop to find out the next um split positions all right so apply next and see if it's working not sure which one has been splitted at this moment because it's zero so if i increase you start to see something changes right here so let's see okay so i see something happening here so let's check this out okay so this is the previous um situations this is next tuitions so in this case wait what has been changed okay so you have you are having the quads on the center right here connected to this point and you have two triangles connected to this quad and you can see that has been converted into two quads like these okay like these this is just a small step but i think it's useful to make this a whole mesh a bit cleaner you start to see this changes right here as well so this one you have triangle triangle and quad right here and converting this to two quads like these working great all right so continue doing that until it no longer find any like split like we did last time for the fall each loop so going back i'm going to create a stop condition when this thing should stop okay now um so if you could go through all the loop with this one which means this didn't have any like split conditions anymore there so i can just say set or i at stop equal to 1 without using any conditions because if this can go through then which means you couldn't find any split positions right so stop equal to one and that's when you want to stop this free back loop going back to the 4-h and checking the detail attribute of this state 2 node detail state to stop okay we're almost there uh for the hard part hard coding part not one but zero okay so let's check this out let's increase the iterations to 100 and it stops at nine so i think it the stop conditions is working perfect all right now we are almost there uh now we have done as much things that as we could in order to convert the triangles into a quad well as you can see we still have a bit of triangular mesh meshes left out like these isolated triangles probably there are like other ways to collapse and split to make all those quads without using like subdivisions but since this is a quick and dirty way to make it quads what i'm gonna do finally i'm going to use this subdivide node now i'm going to come say this is the step 3 step 3 a split and collapse all right so step four which is easy just subdivide using a open subdiv by linear keep the edge point position as it is and as you can see the result of the mesh you get is in terms of the quad it's looks better than the original like uh subdiv result if you don't uh if you don't dissolve any edges for the triangles just directly connecting the result the triangulated geometry to a subdivide you get something like this but by doing all those operations with the feedback loop you'll be able to get a bit more flow quad result and that's good now you do see some kind of meshes like these which comes from the isolated triangles but we're just gonna go with these for now all right now it looks good but it's not really that clean at all yet because it's too like squared too pointy and the the shape of the quad doesn't really look like a square so the final step or the almost the final step is going to is the one to smoothen out these faces so that it will have the same length of the edge for each quad and then also share the amount around the same area and try to have as much as much as possible to make it as a square shape meaning a 90 degrees at each corner now at some part like these you're not able to have that kind of situations because you are having a three neighbors so one angle will be around 120 degrees so you cannot really get like a 100 90 degrees for each quad but i want to make as much as possible to be able to go closer to a quad square shape and to do that i'm going to do another feedback loop but in this time more of uh based on the idea of a physical particle simulations okay control each point at the simultaneously each in terms of positions okay so this is step four sub divide all right we're almost there and i know that we are doing a lot of coding here yep and this too okay now after doing all these i might also want to get the naked edge points which this one doesn't really have so i think i can just leave it for now and that first thing i would like to get is the normal direction of each primitive which i'm going to use it enter in order to use the algorithm that i showed previously on the sketch so normal create the normal direction for a primitive should like these this will be the axis a rotational axis to rotate each of the point 90 degrees okay and then let's go to create a let's create an attribute to each point i'm gonna say attribute create just gonna call i'm just gonna create an empty attribute each of the point as a vector name as a direction and this direction is going to be used to define which direction should the point move okay starting with zero now all right now uh now i can try to do the steps so you can do either you can use either a feedback loop or like a solver or a for each loop if you just want to get the instant result uh then you i prefer you using a for each loop if you want to get the animation to to show the smoothing happening simultaneously at each frame then i would suggest using a solver either way the things you're going to do is pretty much the same so for now i'm going to use the feedback loop and later on i'm going to show how you can transfer that into silver so this is the 4-h number going to again change this to a feedback loop by changing this feedback each iterations fetch feedback all right now now let's uh so so there are two types of forces that i would like to implement to smoothing out the shape one is this force to make the quad and 90 degrees at the edge as much as possible by getting the average value average point positions by rotating each of the point 90 degrees the multiplication of 90 degrees and use the average and that other way is to use the area and based on the area value move the edge point outward inward so that all the faces share the same area okay now let's do one by one the first thing i would like to do is to apply this one first the to make the quad shape square as much as possible all right so let's do this to do that i am going to access to each of the primitive simultaneously so i'm going to use the primitive wrangle okay then let's name this relax all right so let's start writing code and that's this is going to be the last code that i'm going to write here which is going to be a bit long but uh not that hard than comparing with the uh things that i did previously so don't worry all right so first thing i'd like to do is to for each primitive i would like to get the point positions in an order maybe in clockwise or counterclockwise maybe clockwise to do that i'm good i'm going to get the vertex vertices out of the primitive vertices number out of the primitive so use the prim vertices which will give you a vertex number in a clockwise order i think i think it was a clockwise order so at premium if you use the prim points functions instead you do get the point numbers which belongs to this primitive but it is not in the order of the primitive it might be really random-ish in terms of the order could be zero one two three or zero one two three and so on so but for now i want to get this ordered um vertex numbers or point numbers so i'm going to first get the vertex number then convert the vertex number into a point that's kind of a trick so i'm going to look through all the points get the vertex number then convert it into a point number using vertex point okay so and then get the point position at pt now like i said in the sketch what i want to do is to what i want to do is to let's create some exaggerated geometry like these so for now i'm looking at this primitive number okay and i have just retrieved the point number zero one two or vertex number 0 1.3 okay and let's say i'm looking clockwise okay now at each point starting from zero um i would like to rotate this point positions based on the center point of this primitive could be you gen could be somewhere around here let's say this is the center point okay and using this center point i want to rotate this point at the zero 90 degrees the multiplication of 90 degrees until it loops so in this case 90 degrees rotating somewhere around here 90 degrees again somewhere around here 90 degrees again somewhere around here so in total you have four points from one point okay and what you want to do is to do the same thing for all the other points for this point rotate 90 degrees rotate 90 degrees rotate 90 degrees to 90 degrees and this one as well rotate 90 degrees retain 90 degrees degrees degrees and this one retaining degrees 10 degrees and so on so as a result at each of the locations you have like in total four points numbers at four point positions and with those four points you want to get the average point positions somewhere here over here here somewhere over here and that is the goal position for point zero to go point one to go this point to go and this point to go and this directional value is going to be the force to move the point toward that goal so that's what i would like to do here okay now to do that for each a points i'm going to create a average point position named as apos by copying the current point positions and do the nesting loop accessing to to another vertex um list so do pretty much do the same for loop right here changing the iteration value iteration variable let's say n now the thing is um i want to i don't want to go want to start from n but i will actually want to start the n from i plus one okay so if the i is equal to 2 then i want to start the n from 3 because i want to use this n as a multiplication number for the angle okay so if i have to do like do do like this then i also have to increase the target value or target conditions value because so that the total number of the iterations will be equal to four and in any case okay so that's the second nesting loop now i am going to get the vertex number out of this second nested loop vt vts n then and n value could be more than the length of the bts so if it goes more than the length of with vertices then i have to make it back to zero so i'm going to calculate the remains using the modulus bts vts like these all right now i can get the point number out of this vertex vertex point zero and vt and then i can get the point position and pause point zero p and pt all right now now's the time to create a angle value so that i can calculate the angles i mean rotate the angle rotate the points by 90 degrees okay for each point so let's use the integer account let's create the integer count before i get it into the loop and use this count to define the angle for each points that i'm going to rotate so float angle is equal to pi multiplied by 0.5 which is equivalent to 90 degrees and then multiply by count the first saw the first value the first value for the count is equal to one so this is going to be 90 degrees in the first iterations okay meaning what i'm doing here is to rotating the neighboring point for example if i'm looking at this point right now right here then i am rotating the this point right here okay and if i do the rotations with the positive number it rotates um counterclockwise so this point will be rotating 90 degrees to this direction and comes somewhere around here okay so for the next point for the next next point this one i want to rotate 180 degrees so that it can come somewhere close to this point the original point positions and for the for this point at the top you want to rotate 270 degrees counterclockwise so that it can also comes somewhere around this point so at each iterations you want to increase the angle by 90 degrees so you are i'm going to update the count iterate um increment the count by one at the end of the loop right now okay sorry i forgot to switch back to the knees display so where was i where was i okay i think it was started from here so first of all i have created the average vector positions copying the current point positions okay and then i have created this count value starting from 1 and this will be used to increment the angle okay and what i'm doing here if i visually explain so let's say i'm looking at this primitive this primitive right here okay and start let's say when the i is equal to one the the point the point where i'm looking at is this point let's say let's assume this is the point that i'm looking at okay now after getting the after create getting all those point positions i'm creating this nesting loop starting from n equal i plus 1 meaning the next loop will start i'm still looking at the vertices the number of vertices so looking at the four numbers four points this one but i'm what i'm doing here is starting the loop from i plus one which means if this is the i then this is i plus one okay and until it loops all through so i plus one i plus two i plug three i plus four and in total you have four number of iterations for this nesting loop and the reason why i did why i did like this is because in the first in the first and equals the i plus one for this point i want to rotate i want to move this point somewhere close to this one by rotating 90 degrees counterclockwise from here to here so using the center point of this primitive as an axis together with the normal direction i'm going to rotate this point like this and this the point will come somewhere around here okay and the angle written right here is the value that i'm using to rotate this first point okay now that's when the n is equal to i plus one if the n is equal to i plus two which could be somewhere around here then in this case you want to rotate the point 180 degrees using this point as an axis so 180 degrees so that the point will come to the close to the original point positions retrieve right here to do that you have to increment this angle so what i'm doing here is to multiply 90 degrees value by a integer value called count which is going to be incremented by one at the and the end of this nesting loop starting with one so the first loop you get 90 degrees and the second loop the count becomes two so this becomes 180 degrees and the third loop will become 370 degrees and so on and last you have 360 degrees to be rotated okay so by doing it at any of the nesting loop iterations all the points will be rotated to somewhere close to this original point positions and by adding those point position to this average point positions and divided by four you'll be able to get the average point positions for this point and all the other points by looping through all the points it's using this first loop i hope it makes sense now let's do this now that i have an angle it's time to create the rotational matrix to rotate the point so matrix matte is equal to ident rotate the matte with the angle and the axis that i want to use is the at n the normal direction of the primitive that i have created previously now in order to rotate the point which is what is the point that i want to rotate the point that i want to rotate here is this one this positions right here so let's do that but uh before doing that we want to place the center of this primitive to the 0 0 0 position so that it can rotate using this center point as a center axis so to do that we first need to access the center of this primitive which is at p of the primitive wrangle okay so i am going to i i guess this is the point that i would need to rotate so n plus minus the center which will bring the center of the position center point of the primitive 2d 0 0 0 along with all the edge points then do the rotation using the matrix then add back the center like this all right now after rotated the positions after rotated the point positions i am going to add this to a average point positions and like this no no like this okay okay okay should be okay and actually this is not a loop of four but actually this is this was a loop of three because i only need to rotate three points for each of the points so if i'm looking at this point as original point then the only point that i need to rotate is this one this one and this one i don't really need to rotate this point because it's at the same point positions so so if i make plus one then you are accessing to four points but since i'm just using i uh i'm just accessing to the first neighbor second neighbor and third neighbor and that's it all right so which is good so i'm just rotating 90 degrees 100 degrees and 270 degrees and after leaving this loop you have added the those rotated positions to this average positions that i've copied from the original point positions now to get all the average positions you just now have to divide this by four and that's it okay i'm assuming i am only getting the i'm only accessing to the quad uh since i'm using the subdivided right here i have made sure that all the primitive has four vertices so i think this is okay if you're not really sure then you could also say length of the vts which is equivalent to four so which either way is fine i think maybe it might not be a good idea to hard code for some case you want to implement later right now now that i have to get the average point position which is going to be used as a target point position in order to change its value change each of the point to make it square as possible okay so to do that to use this i'm going first going to create a directional value going into this direction from the current point positions so directions is equal to a plus minus the current point positions okay right now i could also [Music] normalize this one and multiply with a distance of a pass and positions which is pretty much the same as the all the subtractions but the reason why i'm doing here is because i wanted to convert this distance as a power off to to make it more like a force so if it's closer if it's um this determines that if the distance is really far then the fourth you have more force if the distance distance is small then you have less force like a log-like scale which is pretty similar to how you create a spring force for particle based simulations and finally you want to multiply with some coefficient value to control how much you want to apply this force could be in between zero to one maybe one could be too much okay and then direction and then what else okay so that's the direction that i've just created as a force and then finally i'm going to add this attribute at this value as an attribute to each of the point to the direction attribute using add option so i'm not directly going to update the point position at this point because if i do that then if i update one of the primitive then if i'm since we're at the primitive wrangle at the different primitive it's trying to modify its point position as well and that will like collide each other that will like have the confusions to each other which makes the result a bit skewed so first thing i'd like to do is to add all those forces into one point and gather it as a added value and then after adding all those value into a point as an attribute then use that to move the point simultaneously using pointer angle so let's look at the result okay i'm getting the error why is that let's see a 36 undefined initialized variable direction 36. i think i do have this direction why am i getting error invalid source let's see syntax error unexpected end of line 25. this one what else what else reference to undefined variable k okay i didn't create this k as a parameter okay so let's do that float is equal to chf okay coefficient value kind of a strength of uh force okay just just do the job and if you look at the geometry spreadsheet for the point you'll be able to see this direction which is equal to zero which is a bit weird shouldn't be zero should should have some kind of value so i think something is wrong let me check so want to check if the average position has been defined so set point attrib zero a pass at pt pass they have this pt yep let's check so i do have this average point positions and it's different from the current point position so you should be able to get the direction and i k i know why because i have set the coefficient to zero right if i set it to one then i should be having some values for the direction all right so this directional value is going to be used as a force to move the point all right now i'm gonna delete this one now before go and go just actually using this i'm going to test this out with the simple situations just getting one of the primitive and try to do the step for this one just with this single primitive to see how it works okay so i have just calculated the directional value for this single primitive so each point has its own direction like these now what i'm going to do next is to use the point wrangle to move the point toward this direction with this amount so at p plus equal to be at direction and that's it and let's see what happens so i think something has changed okay am i seeing any changes okay i think it is changing but something is not really if i if i change this value i think i should be able to see some changes here's but i don't really see it okay let's see why is that that is because i have to uh because this one already creates the direction so i'm going to ignore this one for now and let's see so i have created direction and by changing i think it's i'm not sure if it's changing that much now to check this a little bit more i am going to make the power to one so you have more exaggerated result so you can see that uh by making the change in the coefficient value it's going from the twist skewed geometry to more like a square geometry and becomes really square at the end so i guess by looking at this you might ask why not then use power off one or just say just use this subtraction as it is but when it connects with other primitives then the power of one might be uh too strong at some cases which might corrupts destroy some geometry shapes so to make it safe to make it a like a spring force further you get the stronger if it's close enough then you get smaller value might be a good idea to make it too but if it's just a single then you don't really need to consider about those because it's not it's not connected to anything but uh and the result i want i want to create something like these the squared mesh okay so it's working i'm just going to bring this point wrangled through here so that i can move the direction i'm gonna remove this one and move points all right and i'm seeing some caches let me reopen this all right now since this is a feedback loop it's going to be it's going to use the reupdated value for each loop so let's see what happens slowly update increasing the value you can see that each of the face trying to become square as much as possible but at the same time it's going to change its the overall shape as well that's not really what we want so although each of the squares is trying to become squares as much square as possible that's good but we don't really want to change the whole shape reference so to keep the whole like geometry profile i'm going to project the point as soon as changing the point positions a little bit using this move points so just going to use this ray node for probably this original mesh or to this subdivide mesh maybe to the original mesh is fine so i'm going to create a no node named as orig and then go back downward accessing to the original mesh by using a object merge let's call it this ridge and accessing to the original geometry then project this point to this primitive so that it doesn't go off the profile with the minimum distance option now if i increase the iterations oops let's start to collapse the reason is because as i said the speed was too fast making the coefficient value equal to one in this case so let's try to make this smaller like point one and now the movement becomes slower it tries to create a bit more smoother result or a better result like .05 much better but it's going to make the calculation slower so you have to have more iterations to have a better result like hundred and so on now this itself will create a square like mesh for each quad which is fine but there's another problem here because those you can see that some of the squares have a smaller area some of the squares has much bigger area and also have some kind of a problem with these situations okay it's not which is not really ideal sometimes the mesh becomes too small and so on that is because i'm missing one another a constraints to keep the area as same as possible as much same as possible to make it pretty uh to make it closer to the average area of all the faces okay so that's the additional force that i would like to implement next all right so going back to the zero iterations going to add a additional force inside this relax to do that i do need to calculate the area beforehand for each faces and also calculate the average throughout the face so measure node and calculate the area for a primitive which will give you these area attribute from 0.02 to 0.001 right now from this i'm going to get the average by using the attribute promote for the area for the primitive come convert it promote it into a detail get the average don't delete the original and name the average area as fa area okay so the average area is currently 0.01 so if the current primitive area is smaller than this then i want to expand the face if it's larger than this average area then i want to shrink the primitive and that's what i want to do in order to keep the area size as much the same as possible for each faces okay and we're gonna do this inside this relax it's not that hard to do for this one and compare with the first force okay so let's go inside and i i'm going to rename this coefficient k which is for the spring and which is for the to make the square so i'm going to name this k1 or k square okay and i'm gonna add another parameter called okay area from zero to one name this little case right so okay square is equal to k square float okay area is equal to chf okay area okay now i have to rename this okay 2k square okay what do we have here initialized variable is it i think it's been initialized i don't know why okay now to re uh also let's also retrieve the average area as well so float average area is equal to detail zero average area right okay so now that i have the average area i could also calculate the differences between the current area and the average area so difference area is equal to a current area sub subtracted by this average area and if it's this positive then you want to shrink because the current area current primitive area is too big compared to the average if it's negative then it's too small you want to expand it all right so having those values going down and calculate another directional value okay so let's call the first one to direction one and the second one has direction two and the direction two will be based on the area and to do it i'm just going to first of all get the directional value going from this center to a no i mean to the current point position to the center so center of the primitive can be retrieved by at p and by subtracting by positions you get the direction value going from the position to the center now if i multiply with the difference area and you will be able to get the if it's positive then that's that means you want to shrink so that's the right direction if it's negative it's going outward so that's the right direction and then you want to [Music] since this is a the area the units of the area is the length multiplied the lengths okay so you could if you want to make the fast like process then you could do quick get the square root but like i said it's a good idea to use the power of 2 the square of the value the directional value to make it as a force so keeping as it is it's fine because this is already a power of two of the lengths okay but addition to that i'm going to multiply by point five to make it a bit smaller and multiply by k half area this point five is not really necessary just based on the balance that i'm looking into the direction one and direction two okay now i have two directions i can add those together direction is equal to direction one and direction two finally added to the point and let's see what happens with these so i have to update this scare square and k area let's update to this point two and point two see what happens by increasing the iterations okay i still see some unwanted result it's not that cling is it i think i'm missing something here let me see i might need to do other step let's see let's see what i need to do okay so i'm checking out what i have written ah okay one of the reason why i'm having this kind of a jagged result is because i'm not resetting the direction value to zero after i have calculated all these because i'm using the add option to increment directional value at each frame it's keeping the last updated direction so that's a bit of problem so i'm going to create an additional point wrangle to reset the directional value reset v at direction is equal to set zero zero zero now this should do the job okay now it's more cleaner now let's try to increase the increase iterations and you can see that it's become cleaner and cleaner by increasing the number of iterations so previously when it was zero it looks like these squarish pointy now if i change this to something like 500 becomes more smoother much nicer iterations i do see some uh some kind of a problem here flipping place flipping plane maybe i can reduce that by making the relax the k 2.1 and okay area to point one as well to make the movement a bit smaller not so much maybe the original remesh parameter might help in this case meaning changing the this value a little bit 0.6 better yeah looks nice so this is kind of a final result that i was looking for creating this green not that clean but uh a desirable quad remeshed result where using these kind of algorithmic process okay so this is the step what was the step number step five was it okay step five step five smooth all right so let me also try this out by increasing the resolutions of this remesh like target size to 0.15 see what it does does need a little bit of calculation time it still creates the quad remesh like these quad surface like these now if you ever have used the plugin like exercise quad remesh like plugins you those plugins will create much cleaner faces so compared to this result so as i said in the previous and initially if you just need a result just use those plugins if you're really curious about the process then this could be a starting point i think yeah let's get this back to 8.25 or 0.26 okay now i'm going to do several more options to make it a bit more flexible first thing i'd like to try out is to change this to a solver so that i can create an animation for this smoothing step right here that i have which is not that necessary but uh just for fun all right so let's do this i'm going to create this and since i'm just going to use the same like network right here it's pretty much pretty easy what i'm gonna do and just copy and paste some of the stuff and that's pretty much it solver create a solver and this is the original mesh that i want to smoothen out now i'm also going to connect the the original geometry to the second input of this solver like these and i'm going to copy all these network inside of feedback loop and just go inside the solver paste it oops connect it like these and from the second input i am having this original geometry so connect it right here and that's pretty much it i think so i'm referring to any other stuff nope not really okay so with these if i play it you can kind of see how it iterates iteratively smooth it out using these functions maybe i can increase the sub steps a little bit to make it go faster yeah just like these so all those uh those two forces are working great i think if i try to make some of the forces to zero like let's say make the area force to zero let's see what happens i'm still seeing a better a good result but as you can see the face area some sometimes the face here is too small compared to the others like these so the second force might really necessary if i try to set the square force to be zero let's see what happens now all the face is having trying to have the same area but now it's totally screwed you don't really see any clean faces anymore it does have the same area but it has also has some problems a lot of problems in terms of this shape so that's not really good so combining those two forces makes really sense i think okay just like this not all not that good result right here but overall looks okay right now i'm going to try i want to try out with all the other geometry other than this one especially with the geometry which has the naked edge or the unshared edge and see if it still works so the easiest one i could think of is to create like a grid so switch between the pick head and the grid and then i'm going to use this for each loop to test out okay i'm now i'm seeing some caches here okay now let's switch to the grid okay might be the grid might be too big so i'll make this grid a smaller let's say two by two two by two okay now i see that sound seems to have some problem here it does it's not really dissolving any edges using this first loop the reason is because because this uh grid is totally flat on xc direction it couldn't calculate any principal curvature direction and that's the reason and let's see where we were calculating the curvature right here so if you look at the geometry spreadsheet for the point you get 0 or none okay if it so if it's all flat you're not be able to get any curvature value so that's a big problem so if you we might need to create the condition when the curvature the length of the curvature is equal to zero or none then we are going to replace that curvature with the other value could be random could be the directional direction value of this edges so on now we're gonna i'm going to get the let's say if the point of this geometry has curvature of zero or none then get one of the neighbor point and use that connection direction connected direction as the curvature and the virtual curvature so that's what i would like to do here first i'm going to create another point wrangle right here now if the length of the curvature is pretty small close to zero or if it's none using is none function you can check if it's none or not then that's when you want to add any additional some random curvatures so what i'm going to do is to get the first neighbor point using the naver function for a pt num then get the point position at that neighbor point point and then get the direction going from this point to the neighbor pulling positions let's also normalize this and use this as a kind of sado curvature it's not really a curvature value but since i do need to dissolve the edges i do need to have some kind of directional value so let's assume that this is a kind of a fake curvature and update the curvature with this direction okay now let's check and now i think i do have some curvature and let's look at the dissolve result and now i see that the edge has been dissolved maybe this is not really creating a clean just i'm going to say yeah better so this is the result of the dissolving and is the result of some fixes for triangles and this is the result of the subdivisions much better than the previous one then going back to this one you can now see its result let's iterate thousand times okay now other problem i see is that the edge has been moved as well edge of this geometry has been moved even though i have this ray node it doesn't really fix the unshared edge positions okay which might be okay at some situations but if you want to keep the edge position as the fit to the original um [Music] unshared edge then you might want to you might need to do additional steps uh to do that so let's think how we could do that okay so to do that first thing first time we need to retrieve the unshared edge from this original geometry i think let's try to get the outline by using the divide node to first of all dissolve all the unshared edges or i mean the shared edges then use something like primitive node to get the outline like these all right so this is going to be the geometry that you want to use to bring those edge points to here okay so probably using another array node uh only for those outer points might just do the job okay so to do that you do need to get the um group informations or you you do need to get the point information which points belongs to the unshared edge so you can get that by going back to somewhere around here somewhere right here creating some group node for the point let's name this snake and disable the base group and instead i'm going to enable this include my edge and check unshared edge as a result you'll be able to create a group for all the points which here which is at the unshared edge at the necked edge okay now going back and create another array node anywhere is fine i think but maybe i'll just do it last and for this one i'm going to move this point then set this to minimum distance again and the point which i want to ray project is naked and this is the collision geometry conveying just a second then connect it right here and as a result you'll be able to get this um edge being connected to the unshaded edge and another problem one last problem i have is this the corner point i do want to keep this corner at the pinpoint right here i don't really like these like and this point being off a little bit from the corner so let's also fix that to do that um i am going to create a point wrangle maybe after a reset and name this ping corner now what i'm going to do is to check the the current point positions coming from here and also define which point is at the corner by having two references one from this one from this corner edge and one from the original mesh coming before doing any smoothing and smoothing so this one so i'm going to compare with this one and this one and check if these current point positions are sharing one of the point on these edge right here now to do this i might want to like dissolve all those points in between which which here's a straight line right here so i don't i think i don't really want to use half those points in between when it's straight so i want to remove that and i think someone told me in some other streaming there's a fast way to do this using some node but i forgot what that is polypath if anybody knows that let me know since i cannot remember what that was i'm just going to do a random way okay to do it i'm going to use the point wrangle dissolve point straight so to do that just get the neighbor points from each point and then see if the dot product between those two direction going from point to the net all those two neighbors is uh equal to one or zero or equal to one or other value okay so end never num and i'm assumed that there's only two neighbor points at each point point nay first point net okay just neighbors forgot okay assume there's only two points so vector position and plus one is equal to point zero p nays zero vector and pause to point zero nays second point then get the direction and plus one minus the current point positions and vector direction two is current point position minus and past two okay oops and then also normalize this because i want to calculate the dot product normalize this then if the dot product of this direction is close to one then that means it's straight so that's the that's the point that i want to remove so if it's close enough to one meaning i could say more than 0.99 then remove that point okay i think i did something wrong so digitally moved nope didn't really removed okay let's see what was wrong with victor maybe ah why am i doing am i using premium it has to be pt num okay now this straight at the point that the straight line has been gone all you only have received a point on the corner okay just connect this and i'm going to connect this one to the second input of this pin corner and i also connect the original geometry which is this one to a third input off this pink corner right here okay almost there now i'm going to retrieve the positions [Music] from the third input so let's say n pass is equal to a point and the point number didn't really change from the first input and the third input so what i can say is two p and btnum okay now i have just reached uh have just received the point positions from this geometry okay and what i'm gonna what i've looked like to check is checking each point at this geometry and get the closest distance between this a naked edge especially with these points corner and if the distance is close to zero then that's the point you want to fix in the that's the point you don't really want to move so going back and to get that information you can use the new point function near point for the second input with the end pass and get the and near positions at npt and calculate the distance between the end pause and the near pause and if the distance is small enough like close to zero then that's the point you want to fix so i'm going to fix the point position to the original and pause positions and as a result okay it's not really changing let's see why hmm i'm not sure if this is working what if i don't have this conditions oh wait a minute i might need to do this after every rain node has been done so i think i'm gonna connect it like here connect it like this connect it like this okay although it's not really changing its positions okay now it does now seems like the distance it's not really maybe point zero one was too small not sure what if i make it point zero one no okay so i guess something must be wrong here ah this one has to be one okay now it's gone okay now i think it's fine by increasing the iteration doesn't really change its corner positions or the side positions i think starting from zero starting from zero slowly increase doesn't really change the side or corner you can just increase which much as much as possible all right looks nice okay so let's uh try to bring this what i have implemented to the solver as well i'm just gonna delete all those stuff inside the solver and re-copy everything because that's easier so so this one can so this is the first input this is the second input third input i mean and this one comes d actually i don't really need to input here because i can get it from the first input so i guess that's the old informations now i'm going to copy all these copy it go inside the solver paste it connect it now the original square comes to the first ray right for the second ray i'm going to connect this and for this pink corner so the first for the second input i'm going to connect this unshared edge right here and for the third input i'm going to connect this original geometry like this and now you'll be able to have the same result as the feedback loop let's see okay so if i play it you can see this moves smoothing out based on the time at some point it just stops like this pretty satisfying i think yeah if you want to make these faster you can always increase the coefficient value for the relax like these point two point two i make it point five and point five should be fine for the grid because it's a simple shape yeah going faster all right so originally the geometry looks like this then make it based on the remesh node right here i have converted into a quad mesh like these and this is the final result that i wanted to show right and by doing this way i think this can be work for any kind of geometry let me check that i'm going to bring another test geometry which i didn't really used yet maybe like a squab see what happens let me make this squat size a little bit smaller like point eight okay and switch this right here and if i play it it's okay well maybe i can increase the size a little bit i do i think i do need a little bit more more number of quads a bit more rematch to 0.15 okay then if i play it create this kind of a quadrature mesh from any input geometry considering the principal curvature and all the other tricks that i'd shown okay so that's it's that is pretty much this is to show some first step process to deal with a quadrature remesh which is not really a perfect solutions at all but as a geometrical process interest maybe this is interesting enough to dig in maybe you could start developing your own custom algorithm based on this one or maybe further from this one and there are a bunch of papers writing about this quad remesh and different method bit more sophisticated method so probably look looking at those is more helpful for you if you want to have more sophisticated result but this could be a starting this um step could be a starting point to understand what you really why you really need current principal curvature for and so on what what do you mean by split and collapse and so on you do need to do similar like steps to do the remesh thing and maybe different algorithm in other papers okay so that's pretty much it um thank you for watching it's been like well this was really long so it's like spend like four hours and yeah i hope you find it interested um not sure if it's it's not really like um like a cool motion graphics or anything it's just some geometrical analyst and analytical stuff so some people might find it really boring but i find it myself it's pretty interesting to do so i wanted to share okay so this is it for this weekly tutorial and i would like to do other other stuff next week with different topic if you're interested please join and if you like the video uh i would love to have your likes and subscriptions if it's possible and i'm also doing a patreon myself so if you are interested in supporting me um i'm all i'm always appreciated you can go from the videos description page of this video for the link and i am also going to upload the file that i have just created in the sessions so that anyone can see download it and use it for your own purposes i don't want study purposes probably and so yeah after i have finished this live stream i'm going to upload the files and you can access to this file from the same video description page of this youtube video and i'm also going to keep this video as an archive so that everyone can watch it later okay uh so i have a question saying what if the mesh is not regular in size after triangulation yeah that could happen uh especially if you use like adaptive remeshing which uh it still still tries to keep the square faces at the same as much as possible but sometimes those forces are not enough to make all four faces at the same size though as a result you'll be able to have a kind of a gradient square size based on this initial triangular mesh so i'm going to show you how it looks like so instead of using some normal remesh i'm going to try to do the adaptive remesh instead which will create this kind of uh illegal triangle of face sizes now this is currently too much in terms of numbers i'm going to reduce it okay this doesn't really reduce the number does it gradation oh maybe i can do it like this okay so now i can see that i see a bunch of a lot of triangles at the these small areas and other big triangles on those areas now let's try with these let's see what happens connect it right here and let's go with the solver now it's taking a little bit of time to initially calculate its dissolving area and subdivisions now most of the time the dissolving part takes a little bit of time as initial setup initial step let's wait a little bit okay now this is the result and if i play with smoothness you can see that you still see some gradient size differences right here which comes from the adaptive mesh it still tries to keep the the area size the same by using the force that i have implemented but there are some limit to that so quick create this kind of a gradient square mesh if that makes sense which could be visually useful for some cases i'm not sure in what cases but but it's i do see a lot of hard stuff going here maybe the steps is too fast in this case if you're having a lot of like collapsed collisions like these you might want to reduce the speed a bit slower for the k especially for those small parts all right i hope it makes sense all right now if you have any more questions i'm happy to answer it if not i would like to end the session right here okay i'm gonna reap make this back to the original mesh make this back to big head let me try with this adaptive big head this may create a bit more cleaner result play yeah i see some problem here maybe i might um one of one of the other reason i could think of why this kind of things happens in a small areas it's because i'm using the average a area to define the how how how fast it should go uh to the specific direction so if you are using adaptive you might want to make the speed as small as possible and also maybe you can increase the power of the forces so if it's smaller then make it much slower like this part make it like four yeah it still creates a bit jaggy edges maybe you might need to reconsider the force for the area in this case in this kind of situations or maybe power off one makes it better somehow wait a minute the one that i did is for the square this is not the one that i wanted to change but actually you can can create the power of two for this area this is what i wanted to change yeah i think it's getting a better result so i hope it answers your questions it looks okay yep clean but i am going to keep this one for now all right so i guess there is no question so i would like to end the tutorial live for this week here thank you for watching and all the comments i really appreciate it and hopefully i'll be able to see you all next week as well i'm gonna try to come up with the other topic that i found interested uh or if you have any topic you want me to cover uh please add some comments to the video then i would consider try to do it as well or you could also ask me at the patreon as well oh let me okay that's pretty much it okay so thank you and good night this is around 2 a.m in japan time it's time to go to sleep okay i'm gonna upload the file before i go to sleep so hopefully you'll be able to get downloaded in a few hours all right goodnight and see all
Info
Channel: Junichiro Horikawa
Views: 347,790
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: s1j732lwsyU
Channel Id: undefined
Length: 233min 40sec (14020 seconds)
Published: Wed May 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.