PDA

View Full Version : Proxymodeling (project wip)


Haamu
02-19-2007, 07:28 PM
EDIT 27.8.2007
newest version http://koti.mbnet.fi/sinko/host/proxymodeler_0_3_2.zip
documentation awkwardly not included...found in first release somewhere in the thread.
check my last post for more info
--------------------------------

First of, I would really appreciate if you'd take time reading the whole post. I could really use some pointers, ideas and opinions on this one.

This is something I have wanted to do ever since zbrush was released. My biggest script project yet and likely the most difficult thing I've ever done. The basic idea is to use existing mesh to produce a new one with clean topology. In itself that is nothing new, there are few tools for that already, but they appear to be really cumbersome to be used in large scale (although there are few relatively new ones that I haven't checked, might even be wrong). Not sure if proxymodeling is suitable term for it but it sounds quite fitting :)

To the point then:
Some months ago I got an idea that insead of brutely drawing lines along the surface, I should focus on points of interest and let the script handle all the intermediates. Again probably not all original idea, but I have yet to see proper implementation (again please prove me wrong).

The script is not yet stable or very ergonomic to use so I won't post it just yet, but you can probably get the basic idea how it works here.
http://i114.photobucket.com/albums/n255/idlegoo/constdemo.png

It is all based on projection. All interaction happens on the object's surface. Here's a quick breakup

Anchors:
Anchors are the point helpers seen in the pickture. They are divided into the actual anchors(green) and intermediate guides that control the flow of the splines (blue). These are obviously the highend controls of the whole system.

Surface splines:
Conform to the surface and provide visual feedback in real time (patches are sometimes too heavy to be functional in real time in their current state). Quite complex method is used to calculate the path. Might be too complex even, that's why I post this here now :)

Patches:
plain polymesh, no gimmicky. Follows the splinepaths as closely as possible and uses simplified method of the surface splines to get the intermediates. Mesh density can be dynamically changed.

Script structure:
frame engine:
The whole thing is based on quite complicated arrays and dependencies, anchors being on top and patches on the bottom. Anchors are lined up as splines and patches are defined by exactly four splines. Surprisingly keeping this thing together has been the biggest challenge and timewaster of this project.

Surface evaluation:
First I planned to use very basic brute force vectormaths to produce the paths along the surface, but it appears to be way too slow when dealing with the extreme meshes produces by scanners and sculpting programs.

Currently the main engine uses a system where a function sort of crawls along the surface until it meets an intermediate point, constantly intersecting the mesh with rays. Every new point is adjusted to match an underlying bezier splinepath and further adjusted to the surface tangent, then a ray is cast along its normal (using raymeshgridintersect). This is surprisingly fast method, but has certain drawbacks that I'm now trying to overcome.

This is also something I might need help with. Basicly I'm asking for other concepts like this, or ways to optimize purely mathematical solutions.

There is one possible way to make my own method more fluent. Currently, if intersection fails the script basicly starts probing the surface, namely casting series of rays in different angles until suitable match is found. This obviously takes quite some time on more complex meshes.

What I'd deem most ideal is a circular intersection like this, but so far I haven't found any efficient way to do it (start from red arrow and move along yellow line until intersetion is found)
http://i114.photobucket.com/albums/n255/idlegoo/projdemo.png

Currently I'm working to get this thing more user friendly and ergonomic. Using it now involves lots of clicking and moving around which really is not what I'm aiming for. After all the whole idea behind this is to optimize a mesh as swiftly and easily as possible, yet maintaining high control over the mesh.


Thanks for your interest. I'm open for any suggestions/ideas/opinions/concepts...
If I wasn't clear with something, I'll gladly post more info/examples/code snipplets.

Wahooney
02-21-2007, 09:39 AM
Could you post a video of the workflow of this tool? I'm not 100% sure how it works.

Dmaxer
02-21-2007, 01:19 PM
dont think I could help out on this one but I think this is a cool idea and would like to see this running once you got it working as you want :) keep up the good work dude

d3coy
02-21-2007, 09:41 PM
Hey Capt,

Pretty ambitious project, awesome to see this stuff at such an early stage, thanks for sharing :) Like Wahooney, I'm not completely sure how you're script is working, so I'm just going to assume quite a few things from what I gather from your post. My understanding of your system is this: green anchors control the proxy cage, splines are calculated along the mesh between these anchors, and the blue anchors in between the green influence the spline for more control. Polymesh "patches" are then created for every 4 green anchors (or 4 splines), and when subdivided, the new topology uses the splines as a guide. And I guess the big problem is calculating the path of the spline as it crawls along the surface in between green anchors.

Since the crawling method is slow and the whole point of this script is to use approximations instead of brute force, maybe this will work: Using the z vectors of the green anchors (which if surface constrained will also be the face normal of the underlying face), you can average the two vectors together, invert it, translate its position to be right between the two anchors, then offset it outwards by say... 3/4 the distance between the anchors. This will yield a vector you can use to shoot a ray back into the mesh, yielding a point on the mesh that is exactly between the two anchors. This method is also scalable, in that you could have a spinner dictate how many refinements to make on the spline in between the anchors. For say, 5 samples, the vector extrapolated from the two original anchors would be weighted according to where it fell along the spline so that it pointed more intelligently, and during the translation phase of the vector, it would simply increment upwards along the length of the spline in 6ths, since we're using 5 samples. Some drawbacks would of course be the resulting rays returning points on the geometry you weren't intending, such as in areas where other geometry occludes the area where you are doing the approximation, but with a sufficient number of green control points, tight spots shouldn't be a problem. Blue anchors in between green ones could be used to further influence the vectors extrapolated from the green.

This is just the method that came to me from one read-through... but if someone can think of a method that doesn't involve rays (or uses them more efficiently), that'd be awesome.

I would think that the above method would be able to be manipulated in real time... using a change handler on all the anchors. So long as only one anchor is being manipulated at a time.

Haamu
02-22-2007, 06:55 PM
Ah yes, video is a good idea.
LinkLink (http://koti.mbnet.fi/sinko/host/projdemo2.avi) (xvid codec required)
Just showing some basic functions there, it became a bit more unstable than usual when I did some major structural changes. Also missing a delete function (I deleted it , hehhe :p), it was quite horribly messing up the undo buffer which caused quite severe stability issues.

Actually the crawling method is not all that slow. I would be willing to bet that any method that casts substantial amount of rays will have performance issues. Your method is might actually be usable for certain things and quite significantly faster than mine, but I believe it approximates a little too much. My goal is to be able to handle any kind of geomerty in reasonable amount of time and interactivity, which has indeed proven to be quite challenging. Like you said, the biggest issue is that any given approximation method has a chance to intersect unwanted geometry, so I'm currently just trying to minimize that risk, not necessarely aiming for real time performance, which is not usually needed.

Although I'm trying to manage with as few amount of anchors as possible so the process is most efficient, eventually it will get quite difficult as the complexity increases. Today I had an idea that I could go beyond just anchors and introduce other kinds of control objects like section planes and curves, booleans and the like. Either directly or automating the anchorplacements. Yea, I've got some figuring out to do :wip:

Rivendale
02-23-2007, 05:36 AM
Hey Capt_Suicide, that looks really interesting, nice idea. Could turn into something really useful I think if it can be made simple to use. I havn't got any direct code ideas right now but I will follow your project with interest.

cheers,
CML

Haamu
02-24-2007, 10:12 PM
I just had pretty wild idea. I could actually store entire mesh into a voxel grid, same kind of system that makes raymeshgridintersect so fast. Originally the brute force system failed because I could not find any way to effectively focus the processing on the vectors of interest (hence 'brute force' :)). Now, if I have predefined chunks of mesh, I can nicely select those by intersecting array of rays between the anchors. Or even a simple plane intersection, where bezier paths are not required (patches). Then it would be just plain maths to get the paths. If I'm right, that would first of all speed this significantly, and secondly make it close to error safe. It seems very functional idea now, but I'm pretty sure I'll hit the wall at some point :).

That aside, I've been looking into simplifying the controls. There are some callbacks that might be helpful, and I could turn some of the functions into keyboard driven macroscripts. I still have to see what kind of shortcut functionality can be acchieved in maxscript alone, but I'm pretty sure I can make the interface MUCH simpler.

Now I'm on a short vacation though. I'll see to this more closely when I come back :)

JHaywood
02-24-2007, 10:36 PM
I'll also be watching the progress of this tool. It looks very promising. I don't have anything to add right now, other than to say you can probably cut down on the number of clicks required to set the anchors by using something like a "set new anchor" mode than can toggle on and off. While it's on, the user creates new anchors just by clicking on the mesh. But I realize you're concentrating more on functionality right now, and will most likely work on usability later on.

I started creating something similar a while ago using splines and patches, but gave up at a certain point because of my limited MaxScript experience at the time. Keep posting updates, I'm eager to see how this developes.

EDIT:
Looks like you posted while I was writing my own. I see you're thinking about UI improvements already. Groovy. :)

Haamu
03-02-2007, 06:34 PM
Righto...as it appears, the voxel method is really heavy to initialize so I will stick to crawling for now. I tried to state all the edges in the mesh as vectors and cut those into fitting chucks that are then stored in the voxels. I even got it working, but the process takes few seconds even on meshes with ~1500 faces and on larger ones it hogs up quite a bit of memory. Would be neat to know how raymeshgridintersect handles the grid.

Anyway, I finally got some sense into the delete function (how hard can that be :)) and made it possible to copy anchors by shift clicking. It seems to be quite easy to make interface changes now that the basic structure is mostly functional.

arketip
03-03-2007, 06:16 PM
Hello,

This is what i think about the concept:

Your goal is to be able to clean up an 3D object. In your method the user adds free points to the surface of the hires object. The intermediate points are calculated by the script and follow the surface of this object.

The main advantage of this is that you only have to choose some points in order to define the global structure.
The current inconvenience is the connection of points, it is necessary to make something very similar of the construction of a face.
At this stage, we can wonder what it brings with regard to a classic construction which follows the surface (with polyboost for example), or with a subdivision surface (nurms, turbosmooth)
If I understood well, this leads to some interesting differences:
1) The surface is behaving like a patch: the change of subdivision simplifies the surface without damaging the volume. That's the big advantage of patches.
2) Contrary to a subdivision surfaces or a patch, here the surface always follows the HIRES object.

Effectively it would be a great tool for cleaning up an object!
However the current way of building patches is a little bit slow.
The ideal would be a system of automatic faces construction. Indeed points being already situated on a surface which exists: there is no ambiguity. It is their position which decides in which way the squads are structured.
I don't have any idea if it is the direction you want.
You can also divide this in several steps if the real time is an issue...

Rivendale
03-04-2007, 03:18 PM
Hey I agree a bit with Arketip that the connection of dummys is what is hindering it from being relally simple. One option could be to have a setting to create those connections automatically as you place the points. Another thing could be to "paint" in the connections so at least you do not need to manually select the points to connect.

cheers,
CML

Haamu
03-07-2007, 06:48 PM
...However the current way of building patches is a little bit slow.
The ideal would be a system of automatic faces construction. Indeed points being already situated on a surface which exists: there is no ambiguity. It is their position which decides in which way the squads are structured.
I don't have any idea if it is the direction you want.
You can also divide this in several steps if the real time is an issue...

I'm not exactly sure what you mean. If you mean the spline connections should be handled solely by anchor position data, then of course it's an option, but currently I have absolutely no idea how I would do such thing. The risk of incorrect connections is way too high in any way that comes to my mind. Still, all automation is a huge plus if proven stable enough.

I'm very aware that the interface is lacking several fundamental tools, and not by any means should the interface seen in the video considered more than clumsy link to the internal functions. A mere placeholder so to say.
on my to-do list currently:
target weld
shift-click/drag copying for splines (already possible for anchors)
anchor grouping
more selection tools
more than one node movable at a time.
overall better interface for patches
section cut

section cut is already in the works, and while it didn't feel important at the very first stages of development, I think this one will be one of the key features of this tool set. I'm not quite sure if I can use it directly for patch creation, but as a guide for anchors, it will be a great time saver.

I still have to make occasional changes to the frame structure, but overall it seems very usable already. I've been trying to come up with a replacement for the crawling method, mostly actual geometric calculations, but it always seems to fail on the relative slowness of the polyop/meshop methods. As in, the function would otherwise be very usable, but it takes too much time to read the mesh, even if it's just single face per execution. It actually wokred pretty well on low poly meshes, but when there are 15k tris or more it really starts to crawl. SDK might handle this much better than script, but I don't really have the time to start learning that.

Apart from wasting several days of time and noticing the crawling method is actually very good and easy, I didn't really accomplish anything last week :). I'm focusing on the interface from now on. I'll post a video of the section thingy when I get it done.

Haamu
03-29-2007, 06:30 PM
Beh, that took a while. I effectively had to rewrite the entire core to get the sections tool to work with adequate efficiency. Originally I had to implement yet another branch in the hierarchy, which made the datahandling really clumsy. Now every node actually remember their relations to others in the structure. It didn't really make it work any faster, but seriously simplified further scripting.

Also I replaced most of the patch-hanlding procedures with much more efficient ones. Unifying the patches was the most hideously complex and processor intensive function in the whole thing and it suddenly became completely unnecessary :thumbsup: as the patches completely lost their dependance to the neighbouring patches. Instead they get all the information from the splines that they are connected to.

Bottom line is that everything is much more functional. I'll make some kind of video of it when I have time.


Although I still think the interface is lacking hideously, working with it feels almost comfortable now. My biggest headache is selecting multiple objects. I'm still using an endless loop with pickobject() for single nodes, but when I need to select multiple nodes the loop must exit and enter a #selectionsetchanged callback. This causes many problems, most of which are not all that severe, but potentially VERY uncomfortable for (potential) end users, I don't mind that too much myself :). I could probably do everything with a callback, but the beauty in pickobject is that I can enter different 'modes' by testing keyboard.controlpressed/altpressed/shiftpressed inside the filteing function, and of course easily filter what I want to manipulate. If someone can think of any way to do area selection without breaking pickobject() that would help ENORMOUSLY.

Everything else aside. I have found that this kind of tool is extremely simple and swift to use on general and broad shapes, but high definition areas (fingers, ears, eyelids and such) definitely call for different measures. I believe I'll have to fall back to the kind of paint-interface that all the 'topology brush' implementations have. Also making something like this fully interactive might be quite enormous task and since I'm kind of sick of scripting already (:) it has kept me distracted from modeling for way too long) I'm gonna settle with sort of 'one shot meshes'. Still there will be heavy aim for automation and evaluation instead of painting every polygon individually.

Matt-Clark
03-29-2007, 09:12 PM
I don' know if you've seen this, could be of interest.. there's a piece of software in development called Topogun just for this sort of thing. You might get some ideas for your tools watching the videos or joining the beta. Looks like ZBrush 3 has similar retopology tools too.

http://www.topogun.com/

Haamu
03-31-2007, 11:43 AM
Ohh, thanks for that. It's very good to see that other third parties have taken this as their mission, but still I must say that I was somewhat disappointed after watching the demos there. I would have expected much more innovative solutions for a would be commercial (?), standalone program. I still do realise it is on mere beta stage, I only hope to hear good things from their direction.

However, after checking that I did realise I also need a set of basic polygonal tools as well, and even gave it a brief look. I was quite pleasantly surprised how ridiculously easy it was to lock all editing on another object's surface, simply using when construct and some simple raycasting. Moving masses of vertices at the same time will be trickier though, but I think I already have a clear idea how that could be done.

Haamu
04-17-2007, 06:35 PM
Ops, forgot to update. So here's how it looks now:
http://koti.mbnet.fi/sinko/host/proxyfinal.avi

It's still quite stiff and extremely buggy, but I have kind of stopped the development for now. I'm seriously not much of a scripter and this is taking way too much of my time to be worth it. Well, it's still awesome modelling concept, but I really have to get busy with my self promotional work (CG portfolio), otherwise I'm never getting any job :p.

In the video, few times the nodes seem to lag far behind from the cursor. This is not because the script is slow, it's a bug or more precisely a missing feature. Originally the nodes were places with simple ray cast on first hit, but I replaced that with something more sophisticated because it was too easy to accidently 'pull' a node from far side of the model to the front. The new system is executed every time the mouse moves and currently shifts towards the mouse by one unit at a time (it's supposed to normalize that to the view distance).

The funky ball appearing to the corner during section editing is my little virtual trackball :). It's remarkably ergonomic and accurate way to rotate stuff, but once again my code is a bit flawed and tends to be jumpy and laggy. That can be fixed thought, but as said I don't have time.

My attempts to create a freeform patch have all failed so far. My evaluator functions seem to be too inaccurate for the things I intended this for, and there are other technical difficulties as well. Pity though, because it might have been the most multifunctional and capable tool for this script.

It's all still way too unstable for release, but you can request a copy if you wish to press your luck with it :). I'll resume this at some point, but likely not anytime soon.

Oh, hey. One thing I really have had problems with is calculating the closest point (or intersection point) between 2 bezier splines (with multiple segments). Please tell me if you know any decently accurate and computationally cheap ways to do that.

RappyBMX
06-05-2007, 08:29 PM
sorry to hear that...about the script...i was looking foword to this script.... me liked it allot :D... but know I'm disappointed :(... still can i get a copy of the script ?

BakerCo
06-06-2007, 12:54 AM
I second that this was a killer project. Any chance of getting a copy?

-Baker

I look forward to you resuming this project.

Haamu
06-17-2007, 06:27 PM
Uhh, sorry. Haven't paid too much attention to this corner of the forum in a while :). Sure, I'll post something when I have a chance.

Haamu
06-29-2007, 07:04 PM
So yep. Here it is then. Took a while cause I had to find a spot to write some instructions to bundle with it. Don't expect too much though, it's clearly not suitable for anything except maybe testing.
http://koti.mbnet.fi/sinko/host/const3.zip
Tested only in max8. Extract to 3dsmax/scripts folder. Documents file included in const3 folder. And of course use at your own risk.

Btw, it's not encrypted so feel free to laugh at my messy code :)

BakerCo
06-29-2007, 07:12 PM
Hey thanks a million man this actually works better than you said and you code 20 times better than me so thanks for the open source factor as well much appreciated and I hope you don't give up on finishing this tool it is very cool.

-Baker

So yep. Here it is then. Took a while cause I had to find a spot to write some instructions to bundle with it. Don't expect too much though, it's clearly not suitable for anything except maybe testing.
http://koti.mbnet.fi/sinko/host/const3.zip
Tested only in max8. Extract to 3dsmax/scripts folder. Documents file included in const3 folder. And of course use at your own risk.

Btw, it's not encrypted so feel free to laugh at my messy code :)

Haamu
06-30-2007, 06:37 PM
Heh, I'm glad you can find it useful.

Few things I forgot to mention though.
The script should be active when you delete nodes from the structure (which can be done by just normally deleting stuff), otherwise it will get corrupted. There's a callback function that handles cleanup after deletion and it is shut down with the script. I think it persists if the scrip crashes, but not when you manually close it.

Loft sections can be freely deleted from the loft. Changes are taken into account the next time said mesh is updated. You can also add a section anywhere in the loft, it should be placed in the right spot automaticly. If not, delete and try again.

The blue masternode does not serve any purpose yet. Hide it if it's in the way. If you delete it, it will just be added again next time the script is run.

Haamu
08-11-2007, 06:37 PM
Just a quick fix for surface lock, it was starting to bug me so had to improve. Other than that, nothing really interesting going on. Still don't have time. I do have plenty of ideas for improvements though.

changes:
-surface lock now works with MULTIPLE VERTICES selected, note that it still work only with vertices, not edges/faces :) (was very simple fix really, funny I didn't think of it earlier)
-works also with cut tool now
-fixed minor bugs where rays were assumed to hit, thus causing crash.
-added "view" as conform option, projects vertices along othrographic depth axis of the active viewport

http://koti.mbnet.fi/sinko/host/proxymodeler_0_3_1.zip

oh and seems I forgot to add the cleaner callback (cleanup2.ms) into this one so you need to get it from the previous file.

Haamu
08-27-2007, 07:52 PM
another quick fix, probably last one before I do another rewrite, don't know when yet.
http://koti.mbnet.fi/sinko/host/proxymodeler_0_3_2.zip

-surface lock works with all subobject levels now

Yah kinda small update, but adds significan comfort :)
Think it's time for a little feedback round. I'm totally disappointed with patch evaluator for the most part and will probably overhaul the system and interface quite completely. Will aim for more freeform and less restricted way to do things.

We've been through some talk about technical things, but haven't heard too much practical feedback. As said I don't really use the patch part at all, but I do very often rely to the surface lock, conform and loft meshes. Love that part :arteest:. New system will rely on drawing flowlines more freely and using less restricted control points.

Now my request would be to throw in some wild suggestions for tools that you'd love to have in your mesh optimization/general proxybased modeling workflow. I'm thinking about new concepts here. Tell me something I haven't thought of :).

Cral
08-27-2007, 08:30 PM
looks damn sweet you script. I also really don't like the way like drawing lines etc. Your scripts looks already very cool. :thumbsup:

Haamu
01-29-2008, 03:26 PM
As it appears, max9 and probably 10 as well handle few things a bit differently which cause it to crash if "show end result" is used. I think polyop used to always refer to baseobject prior that. Another thing that I have noticed is that in max9 pickpoint() doesn't take clicks into account if the mouse moves (bug?), which makes it total pain to use with a tablet and that makes my patch handler even more useless :). Then there's the new way "when" contruct is handled which caused a slight hit in surface lock functionality (used to be continuous, now only on mouse up). Haven't woked my way out some of that, but the surface lock should work fine with "show end result" now (update in attachments).

I recently took a brief look in max sdk and even though I have zero c++ experience I didn't find it nearly as daunting as people here often imply. I even managed to create functional maxscript extensions and the speed difference is indeed pretty cool.

One thing I've always wanted to do is conform objects on polymeshes without destroying their integrity and I've tried skinwrapping (works, but cumbersome) and all kinds of funky raytrace/pathdeform kind of systems, but a while ago I thought, why not just map it like texture. Heh, too simple. Attached an image of this. The original horn was done using tiled displacement, but took ages to render. Complex shapes like that, I've found, are massively simpler to model on a plane than full 3d and I've only used it several times, but it has already saved me lots of headache. Not posting that yet though, cause it's slow and picky.

CGTalk Moderation
01-29-2008, 03:26 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.