Atom Posted November 4, 2017 Share Posted November 4, 2017 I have this sweeping kind of hull section that is all quads. I am scattering some geometry to the center of each primitive. I know about the @orient attribute, but I don't know how to construct it to conform to an organic style shape. How can I make my scattered geometry shapes align correctly to the organic topology? Currently I have placement working, but rotation is off. Quote Link to comment Share on other sites More sharing options...
galagast Posted November 4, 2017 Share Posted November 4, 2017 Hey Atom, could you try out the attached file? See if this approach would work for you? I basically processed the incoming mesh in a wrangle. It generated the center points, and directly assigned the vector Up and N attributes to each point for alignment. * Just replace the GEO mesh with your mesh. Or in the case of the above GIF, I used the Test Geometry Pig Head, scaled to 7.5 * H16.0.745 Indie -prim_center.zip 1 Quote Link to comment Share on other sites More sharing options...
Atom Posted November 4, 2017 Author Share Posted November 4, 2017 (edited) Thanks Jeff, That does get my rotation more into the ball park of what I am looking for. I found that deriving direction from point 0 and point 3 gives a better alignment on my particular mesh. But then I am boldly assuming that all primitives are quads (which is my current case). Next step is to leverage the area of the primitive to set @pscale and skip tiny primitives. Although it would be nice to somehow stretch my stamped geo to more closely match the size of the host primitive, such as those long thin strips. Is there a vex bbox function for primitives? Edited November 4, 2017 by Atom Quote Link to comment Share on other sites More sharing options...
konstantin magnus Posted November 4, 2017 Share Posted November 4, 2017 (edited) primuv already is basically a 2d representation of the primitive's footprint. a not-aligned bounding box of each primitive can also be found in the primitives intrinsics called "bounds". if you want to copy and squeeze models onto primitives I would create the copies first, create a "copynum"-attribute and distribute the models with something like this: vector bbox = relbbox(0, @P); int prim = point(0, "copynum", @ptnum); float height = sqrt( primintrinsic(1, "measuredarea", prim) ); @P = primuv(1, "P", prim, set(bbox.x, bbox.z, 0) ); @P += prim_normal(1, prim, {0.5, 0.5, 0}) * bbox.y * height; The bounding box from line 1 is stretched across the primitives from line 2 with primuv in line 4. The approximate height of the copies gets derived from the primitives area size in line 3 and is raised along the primitives normals in line 5. copy_on_prims.hipnc Edited November 4, 2017 by konstantin magnus added screenshot 7 Quote Link to comment Share on other sites More sharing options...
galagast Posted November 5, 2017 Share Posted November 5, 2017 That is an absolutely brilliant approach Konstantin! Reading the code is like hearing a very beautifully composed song! Thank you so much 1 Quote Link to comment Share on other sites More sharing options...
Atom Posted November 5, 2017 Author Share Posted November 5, 2017 (edited) Thanks for the example file Konstantin. That is a really nice implementation. I have been trying to figure out how to modify it. Is there a way to skip some primitives? Is there a way to have a border or edge around each copy? (i.e. inherit pscale) Also, I have over 40 different nurnie, doodads, greeble objects that I want to scatter across my ship hull. In my previous setup I was going to leverage stamping a switch index, but in your setup I am not exactly sure how to achieve that same result... Edited November 5, 2017 by Atom Quote Link to comment Share on other sites More sharing options...
konstantin magnus Posted November 5, 2017 Share Posted November 5, 2017 7 minutes ago, Atom said: Is there a way to skip some primitives? Just blast them before counting. 9 minutes ago, Atom said: Is there a way to have a border or edge around each copy? Apply a fit01() function on bbox. 13 minutes ago, Atom said: I have over 40 different nurnie, doodads, greeble objects Make sure your copies have ongoing "copynum" attributes. 1 Quote Link to comment Share on other sites More sharing options...
Noobini Posted November 5, 2017 Share Posted November 5, 2017 great...now, could someone please explain to me why they aren't symmetrically consistent ? Quote Link to comment Share on other sites More sharing options...
konstantin magnus Posted November 6, 2017 Share Posted November 6, 2017 (edited) 1 hour ago, Noobini said: could someone please explain to me why they aren't symmetrically consistent ? Has to do with the winding of the underlying geometry. Just display the vertex numbers of the target geometry and you will see it's the polygons that are not consistent. It works fine on primitive objects, though (tori, grids etc.). Edited November 6, 2017 by konstantin magnus Quote Link to comment Share on other sites More sharing options...
f1480187 Posted November 6, 2017 Share Posted November 6, 2017 Couple of nice older topics on the subject: 3 Quote Link to comment Share on other sites More sharing options...
Atom Posted November 6, 2017 Author Share Posted November 6, 2017 (edited) 19 hours ago, konstantin magnus said: Make sure your copies have ongoing "copynum" attributes. I guess I still don't understand how the copynum works. The Copy node in the setup has only one input. How would I provide access to my other shapes without a switch? The input does not work like a merge, if I plug a new shape into the Copy, I lose the old shape. Edited November 6, 2017 by Atom Quote Link to comment Share on other sites More sharing options...
galagast Posted November 6, 2017 Share Posted November 6, 2017 (edited) Hey Atom, I took another stab at it. Here's probably one approach to do it. The idea is to create the needed number of copies for each of the pighead's primitives. So for example, if the pighead has 300 primitives, and we have 3 doodads (sphere, box, teapot) to scatter.. we need to have 100 spheres, 100 boxes, and 100 teapots to create. Then inside the loop, I also offset the copynum that is assigned. I still have a couple of other approaches that I would like to try, but for now this might do. H16.0.745 Apprentice - copy_on_prims_v2.rar Edited November 6, 2017 by galagast 1 Quote Link to comment Share on other sites More sharing options...
Atom Posted November 6, 2017 Author Share Posted November 6, 2017 Thanks for that file Jeff, taking a look now. Quote Link to comment Share on other sites More sharing options...
Atom Posted November 6, 2017 Author Share Posted November 6, 2017 (edited) I finally understand what Konstantin's code is doing. With that I was able to use it as fix up after a standard CopyStamp node. Basically just set @P to {0,0,0} on the right side of the CopyStamp, then let Konstantin's fixup code migrate all the copies to their correct locations. This is slow on high poly count objects but it is a start. Next step would be to implement it as instances to recover some performance. ap_stretch_copy_to_primitve_area.hiplc Edited November 7, 2017 by Atom Quote Link to comment Share on other sites More sharing options...
galagast Posted November 7, 2017 Share Posted November 7, 2017 Cool Atom! Yours is now much simpler compared to the last file I uploaded It makes much more sense to generate the copynum from the primitives themselves! Quote Link to comment Share on other sites More sharing options...
MrScienceOfficer Posted November 7, 2017 Share Posted November 7, 2017 Using a for loop rather then copy-stamp(which I believe is no longer a recommended workflow) could be substantially quicker, since it can be compiled and run in parallel. for_loop.hiplc 1 Quote Link to comment Share on other sites More sharing options...
julian johnson Posted November 7, 2017 Share Posted November 7, 2017 Really great, educational stuff on here - thanks to everyone for sharing. I've been trying to look at the flow problem on its own i.e. the fact that primuv is dependent on the winding order of the underlying poly and hence the direction of the fitted object is hard to control (without changing that winding order). Here's a scene that uses anim's (amazing) setup from the linked thread and some additional flowlines to try and conform the fitted geometry to a flow that snaps to the polygon directions. Some very, very coarse coding going on but with some more love (and optimisations) it might make for a nice hybrid. It's very slow at the moment probably because of the copy stamping! flow fit.hipnc 2 Quote Link to comment Share on other sites More sharing options...
Atom Posted November 7, 2017 Author Share Posted November 7, 2017 (edited) Thanks again for the example files! I have added some controls to the system. I can discard some based upon area and increase height of the distributed parts/pieces. I am still trying to add a border around the pieces which kind of works. But when I increase the border the parts/pieces grow from the corner of the primitive. I would like them to remained centered on the primitive instead. I know it is related to the bbox.x and bbox.z values but I am not sure how to calculate the correct result so the part/piece ends up in the center. vector bbox = relbbox(0, @P); int prim = point(0, "copynum", @ptnum); float height = sqrt(primintrinsic(1, "measuredarea", prim)); float range = ch("range"); float range_div2 = range * 0.5; float x = fit01(bbox.x, 0, range)*range; float y = fit01(bbox.y, 0, range); float z = fit01(bbox.z, 0, range)*range; @P = primuv(1, "P", prim, set(x,z, 0) ); @P += prim_normal(1, prim, set(range_div2, range_div2, 0)) * y * (height * ch("mult_height")); ap_stretch_copy_to_primitve_area_110717.hiplc Edited November 7, 2017 by Atom Quote Link to comment Share on other sites More sharing options...
galagast Posted November 7, 2017 Share Posted November 7, 2017 Hey Atom, try this one. The important part behind it is to note the order of operations for scaling the bbox. I hope this helps! H16.0.736 Indie - ap_stretch_copy_to_primitve_area_110717_jeff.rar 2 Quote Link to comment Share on other sites More sharing options...
julian johnson Posted November 7, 2017 Share Posted November 7, 2017 (edited) vector bbox = relbbox(0, @P); int prim = point(0, "copynum", @ptnum); float height = sqrt(primintrinsic(1, "measuredarea", prim)); float range = ch("range"); float range_div2 = range * 0.5; float x = fit01(bbox.x, range, 1-range); float y = fit01(bbox.y, 0, 1); float z = fit01(bbox.z, range, 1-range); @P = primuv(1, "P", prim, set(x,z, 0) ); @P += prim_normal(1, prim, set(range_div2, range_div2, 0)) * y * (height * ch("mult_height")); @Atom if you fit between range and 1-range it scales from the centre.. @galagast didn't realise you'd already solved it! Edited November 7, 2017 by julian johnson Jeff already posted solution! 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.