CGTalk > Software > Autodesk 3ds max > 3dsMax SDK and MaxScript
Login register
reply share thread « Previous Thread | Next Thread »
 
Thread Tools Search this Thread Display Modes
Old 02-07-2013, 03:33 PM   #31
denisT
MAX Doctor
 
denisT's Avatar
portfolio
Denis Trofimov
CA, USA
 
Join Date: Jul 2009
Posts: 9,871
Send a message via ICQ to denisT
there are two functions about poly edge loop/ring shift selection... poly has these methods but the difference is mine don't really need a selection
Code:
def_visible_primitive(setSelectionShift, "setSelectionShift"); Value* setSelectionShift_cf(Value** arg_list, int count) { check_arg_count(setSelectionShift, 5, count); INode *node = arg_list[0]->to_node(); int shift = arg_list[1]->to_int(); bool move = (arg_list[2] == &true_value); bool add = (arg_list[3] == &true_value); Object* obj = Get_Object_Or_XRef_BaseObject(node->GetObjectRef()); if (obj->ClassID() == EPOLYOBJ_CLASS_ID) { BaseInterface* i = ((Animatable*)obj)->GetInterface(EPOLY_INTERFACE); if (i) { EPoly* ip = (EPoly*)i; if (arg_list[4] == &true_value) ip->EpfnSetRingShift(shift, move, add); else ip->EpfnSetLoopShift(shift, move, add); node->NotifyDependents(FOREVER, PART_GEOM | PART_TOPO | PART_SELECT, REFMSG_CHANGE); node->NotifyDependents(FOREVER,0,REFMSG_SUBANIM_STRUCTUR E_CHANGED); ip->RefreshScreen(); return &true_value; } return &false_value; } return &undefined; } def_visible_primitive(getEdgeSelectionShift, "getEdgeSelectionShift"); Value* getEdgeSelectionShift_cf(Value** arg_list, int count) { check_arg_count_with_keys(getEdgeSelectionShift, 2, count); INode *node = arg_list[0]->to_node(); int value = arg_list[1]->to_int(); Value* tmp; BOOL loop = bool_key_arg(loop, tmp, TRUE); Object* obj = Get_Object_Or_XRef_BaseObject(node->GetObjectRef()); if (obj->ClassID() == EPOLYOBJ_CLASS_ID) { BitArray newSel; PolyObject *poly = dynamic_cast<PolyObject *>(obj); if(poly && poly->GetMesh().nume > 0) { MNMesh &mesh = poly->GetMesh(); newSel.SetSize(mesh.nume); newSel.ClearAll(); IMNMeshUtilities8* meshToShift = static_cast<IMNMeshUtilities8*>(mesh.GetInterface( IMNMESHUTILITIES8_INTERFACE_ID )); if (loop) { meshToShift->SelectEdgeLoopShift(value,newSel); //mprintf("loop: %f\n", dir); } else meshToShift->SelectEdgeRingShift(value,newSel); } return new BitArrayValue(newSel); } return &undefined; }


and it works for Editable poly base object. so i use it for example for skin step loop/ring
 
Old 02-07-2013, 03:35 PM   #32
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
I do find it very odd that those normal functions are not in polyops and meshops !? Oh I like those and have a application for them

also you should probably rename VertexToSpecNormals to getNormalsUsingVert (makes it more mxs like) to late for me as I'm to lazy to change the calling scripts

Last edited by Klunk : 02-07-2013 at 03:44 PM.
 
Old 02-07-2013, 05:41 PM   #33
DaveWortley
<database error>
 
DaveWortley's Avatar
portfolio
David Wortley
Technical Director
London, United Kingdom
 
Join Date: Dec 2004
Posts: 1,918
Send a message via MSN to DaveWortley
I'm intrigued by these functions, how do you actually get these set up with max?

Do you need to compile a DLX file?
__________________
Maxscript Made Easy...
http://davewortley.wordpress.com/
 
Old 02-07-2013, 05:59 PM   #34
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
yep, with ms visual studio (version dependent on the target version of max) and the sdk, which is somewhere on your max install disks. My experience of it is, and peoples reluctance to use it is not using the sdk (though the reference is sketchy at best) is getting to grips with creating the initial project in ms visual studio, the stream of errors that can run down the output window when you get it wrong can seem very daunting and ms dev speech is something to behold . But Once up and running though in the case of most of these functions its a case of cut, paste, compile and run.

there is a free book on the subject

Last edited by Klunk : 02-07-2013 at 06:10 PM.
 
Old 02-07-2013, 06:57 PM   #35
DaveWortley
<database error>
 
DaveWortley's Avatar
portfolio
David Wortley
Technical Director
London, United Kingdom
 
Join Date: Dec 2004
Posts: 1,918
Send a message via MSN to DaveWortley
If these are all so useful is it worth lobbying Autodesk to include them in the next 3dsmax build? Surely you've done all the hard work for them?
__________________
Maxscript Made Easy...
http://davewortley.wordpress.com/
 
Old 02-07-2013, 07:20 PM   #36
feranti
Frequenter
Antoine Ferrieux
Paris, France
 
Join Date: Apr 2008
Posts: 208
Quote:
I was hoping this would be more than a 2 man show Denis, if you don't already have these I think you will like them.....


I really wish I could post some useful functions like you guys but I hadn't had to deal with that kind of geometry stuff.

Thanks for sharing, btw.
I am sure it will be useful one day...
 
Old 02-08-2013, 06:14 PM   #37
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
Quote:
I really wish I could post some useful functions like you guys but I hadn't had to deal with that kind of geometry stuff.


I wouldn't worry we're not that fussy
 
Old 02-10-2013, 08:14 PM   #38
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
from the slow rollout drawing thread these can turn off redraw while adding rollouts then force a redraw when complete. Gets rid of the annoying flicker with large and complex gui.

// usage: <bool> SetWindowRedraw <HWND>window <bool>

Code:
def_visible_primitive(SetWindowRedraw, "SetWindowRedraw"); Value* SetWindowRedraw_cf(Value **arg_list, int count) { check_arg_count(SetWindowRedraw, 2, count); HWND hWnd = (HWND)arg_list[0]->to_int(); bool redraw = arg_list[1]->to_bool(); LRESULT res = SendMessage( hWnd , WM_SETREDRAW, redraw, 0); return bool_result(res); }


// usage: <bool> RedrawWindow <HWND>window

Code:
def_visible_primitive(RedrawWindow, "RedrawWindow"); Value* RedrawWindow_cf(Value **arg_list, int count) { check_arg_count(RedrawWindow, 1, count); HWND hWnd = (HWND)arg_list[0]->to_int(); LRESULT lres = SendMessage( hWnd , WM_SETREDRAW, true, 0); BOOL res = RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); return bool_result(lres); }


window handle can be accessed with something like

Code:
hwnd = (windows.getchildhwnd 0 myrollout.title)[1]



there is probably a better way to get the current dialog handle in the sdk but I to lazy too look ! again thanks to Denis for pointing me in the right direction ( I really should learn more about the windows api )

Last edited by Klunk : 02-10-2013 at 08:31 PM.
 
Old 02-11-2013, 12:17 AM   #39
denisT
MAX Doctor
 
denisT's Avatar
portfolio
Denis Trofimov
CA, USA
 
Join Date: Jul 2009
Posts: 9,871
Send a message via ICQ to denisT
Quote:
Originally Posted by Klunk
window handle can be accessed with something like

Code:
hwnd = (windows.getchildhwnd 0 myrollout.title)[1]



there is probably a better way to get the current dialog handle in the sdk but I to lazy too look ! again thanks to Denis for pointing me in the right direction ( I really should learn more about the windows api )

Code:
def_visible_primitive(getDialogHWND, "getDialogHWND"); Value* getDialogHWND_cf(Value **arg_list, int count) { check_arg_count(getDialogHWND, 1, count); if (is_rollout(arg_list[0])) { HWND hwnd = ((Rollout*)arg_list[0])->page; return IntegerPtr::intern((INT_PTR)hwnd); } if (is_rolloutfloater(arg_list[0])) { HWND hwnd = ((RolloutFloater*)arg_list[0])->window; return IntegerPtr::intern((INT_PTR)hwnd); } return &undefined; }
 
Old 02-11-2013, 01:02 AM   #40
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
sweet, I'm absolutely staggered at the visual improvement these 3 tiny functions make ! Also useful for getting rid of the flicker when setting gui items to disabled on a selection change or in a selection change handler (which has irritated me for years)

Last edited by Klunk : 02-11-2013 at 12:42 PM.
 
Old 02-15-2013, 04:11 PM   #41
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
following on from the quadifier challenge I ported my mxs function to the sdk, very quick now.


returns a bitarray of edges that if removed would create quads, the routine respects material
boundaries and the mesh topology <topo_tolerance> 1.0 faces must be planar 0.0 any ol' face
will do. The quads edges are selected on how "square" the quads are using <quad_tolerance>
(0.0 being perfect 1.0 allows parallel edges) there is an issue where it cannot tell the difference
between concave and convex polys though

<bitarray> QuadifyEdges <poly> <quad_tolerance> <topo_tolerance>

Code:
def_visible_primitive(QuadifyEdges,"QuadifyEdges"); Value* QuadifyEdges_cf(Value** arg_list, int count) { check_arg_count(QuadifyEdges, 3, count); MNMesh* pmesh = get_polyForValue(arg_list[0], MESH_READ_ACCESS, NULL, QuadifyEdges); float quad_tolerance = arg_list[1]->to_float(); float topo_tolerance = arg_list[2]->to_float(); int numedges = pmesh->nume; BitArray edges(numedges); edges.ClearAll(); for(int i = 0; i < numedges ;i++) { MNEdge* edge = pmesh->E(i); if(edge->GetFlag(MN_DEAD)) continue; if(edge->f2 == -1) continue; MNFace* f1 = pmesh->F(edge->f1); MNFace* f2 = pmesh->F(edge->f2); float edgeAngle = pmesh->GetFaceNormal(edge->f1,true) % pmesh->GetFaceNormal(edge->f2,true); if(f1->deg == 3 && f2->deg == 3 && f1->material == f2->material && edgeAngle > topo_tolerance) { // collect the edges that make up the prospective quad int v1e1 = -1; // v1 f1 edge but not the current edge for(int j = 0; j < 3; j++) { if(f1->edg[j] == i) continue; if(pmesh->E(f1->edg[j])->v1 == edge->v1 || pmesh->E(f1->edg[j])->v2 == edge->v1) { v1e1 = f1->edg[j]; break; } } int v1e2 = -1; // v1 f2 edge but not the current edge for(int j = 0; j < 3; j++) { if(f2->edg[j] == i) continue; if(pmesh->E(f2->edg[j])->v1 == edge->v1 || pmesh->E(f2->edg[j])->v2 == edge->v1) { v1e2 = f2->edg[j]; break; } } int v2e1 = -1; // v2 f1 edge but not the current edge for(int j = 0; j < 3; j++) { if(f1->edg[j] == i) continue; if(pmesh->E(f1->edg[j])->v1 == edge->v2 || pmesh->E(f1->edg[j])->v2 == edge->v2) { v2e1 = f1->edg[j]; break; } } int v2e2 = -1; // v2 f2 edge but not the current edge for(int j = 0; j < 3; j++) { if(f2->edg[j] == i) continue; if(pmesh->E(f2->edg[j])->v1 == edge->v2 || pmesh->E(f2->edg[j])->v2 == edge->v2) { v2e2 = f2->edg[j]; break; } } if( v1e1 == -1 || v1e2 == -1 || v2e1 == -1 || v2e2 == -1) continue; // something wrong to get here :( Point3 e1dir = (pmesh->v[pmesh->E(v1e1)->v2].p - pmesh->v[pmesh->E(v1e1)->v1].p).FNormalize(); Point3 e2dir = (pmesh->v[pmesh->E(v1e2)->v2].p - pmesh->v[pmesh->E(v1e2)->v1].p).FNormalize(); float v1edgeangle = fabs(e1dir % e2dir); e1dir = (pmesh->v[pmesh->E(v2e1)->v2].p - pmesh->v[pmesh->E(v2e1)->v1].p).FNormalize(); e2dir = (pmesh->v[pmesh->E(v2e2)->v2].p - pmesh->v[pmesh->E(v2e2)->v1].p).FNormalize(); float v2edgeangle = fabs(e1dir % e2dir); if(v1edgeangle < quad_tolerance && v2edgeangle < quad_tolerance) edges.Set(i); } } return new BitArrayValue(edges); }

Last edited by Klunk : 02-15-2013 at 04:17 PM.
 
Old 02-15-2013, 09:44 PM   #42
denisT
MAX Doctor
 
denisT's Avatar
portfolio
Denis Trofimov
CA, USA
 
Join Date: Jul 2009
Posts: 9,871
Send a message via ICQ to denisT
Quote:
Originally Posted by Klunk
I was hoping this would be more than a 2 man show Denis, if you don't already have these I think you will like them.....

exposes editable poly specified normals without using the edit normal modifier and having the target node selected and the modify panel open for it to work. It would be easy to expand on these if the functionality you need is not here, anyway enjoy....

i'm playing with your set of functions... they are really cool. but i can't figure out why after i change a normal and apply edit_normal modifier to the poly, i see the normal non-set. as i expect the edit_normal modifier has to show how the spec normals currently set in the MNMesh
 
Old 02-15-2013, 10:22 PM   #43
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
did you make them specified or explicit after you set it ? I only included functions to zap the lot as I tend to use them as set all at once but should be pretty easy to add the set an individual normal to specified or explicit.
 
Old 02-15-2013, 11:04 PM   #44
denisT
MAX Doctor
 
denisT's Avatar
portfolio
Denis Trofimov
CA, USA
 
Join Date: Jul 2009
Posts: 9,871
Send a message via ICQ to denisT
Quote:
Originally Posted by Klunk
did you make them specified or explicit after you set it ? I only included functions to zap the lot as I tend to use them as set all at once but should be pretty easy to add the set an individual normal to specified or explicit.

setAllSpecNormalsExplicit to ON works...
but any way i have some strange result... check the sample:
Code:
delete objects s = sphere() addmodifier s (edit_normals()) converttopoly s b = box pos:[40,0,0] deleteAllChangeHandlers id:#follow_tm when transform b change id:#follow_tm handleAt:#redrawViews obj do ( for n=1 to getNumSpecNormals s do setSpecNormal s n obj.transform[3] setAllSpecNormalsExplicit s on update s )


edit:
it seams like it works as expected... good. i keep playing... thanks

Last edited by denisT : 02-15-2013 at 11:07 PM.
 
Old 02-15-2013, 11:14 PM   #45
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
you could use this sort of thing instead of adding the edit normals mod but after converting to editable poly...

Code:
if not hasSpecifiedNormals obj then buildSpecifiedNormals obj;


let me know any strangeness, they seem to be a bit "odd" sometimes but using the reset seems correct any issues (not an issue for my purpose as I'm setting them procedurally most of the time).

Last edited by Klunk : 02-15-2013 at 11:20 PM.
 
reply share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 10:44 AM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.