Mario Marengo Posted February 28, 2006 Share Posted February 28, 2006 Hi all, I'm wondering what the recommended way is to compute point normals when they don't exist in the input detail. After looking through a few classes, my first version was: int andx_n; if((andx_n=gdp->findNormalAttribute(GEO_POINT_DICT))<0) { andx_n = gdp->addNormalAttribute(GEO_POINT_DICT); GEO_Point *ppt; UT_Vector3 nml; FOR_ALL_GPOINTS(gdp,ppt) { gdp->computeNormal(*ppt,nml); *((UT_Vector3 *)ppt->getAttribData(andx_n)) = nml; } } which works, but then, the comments in GU_Detail warn that computeNormal() could be "very slow" and to use computeNormalInternal() instead... but taking into account the behaviour of the internal versions, /// For internal functions: /// If nml_offset > -1, the attribute at that offset will be returned, /// else if the geometry has a normal attribute ("N"), nml_offset /// will be set to the offset of that attribute and that attributes /// value will be returned, /// else if the geometry has an internal normal attribute ("internalN") /// the value of the internal attribute will be returned and /// nml_offset will be set to its offset, /// else the "internalN" attribute is created by a call to normal(1), /// nml_offset is set to it, and the calculated value returned. /// If nml_offset is null, the case of nml_offset == -1 is followed /// except nml_offset is not written to. /// Otherwise: /// Recompute the normal. No side-effects happen, but this is much /// slower. the best I can come up with *has* to visit all points twice (for the case where "internalN" doesn't exist): int andx_n = gdp->findNormalAttribute(GEO_POINT_DICT); if(andx_n<0) { int andx_in = gdp->findAttrib("internalN",sizeof(UT_Vector3),GB_ATTRIB_VECTOR); GEO_Point *ppt; UT_Vector3 nml; if(andx_in<0) { UT_Vector3 dv_zero(0,0,0); andx_in = gdp->addAttrib("internalN",sizeof(UT_Vector3), GB_ATTRIB_VECTOR,&dv_zero); FOR_ALL_GPOINTS(gdp,ppt) { gdp->computeNormalInternal(*ppt,nml); } } andx_n=gdp->addNormalAttribute(GEO_POINT_DICT); FOR_ALL_GPOINTS(gdp,ppt) { // would memcpy() be faster here? *((UT_Vector3 *)ppt->getAttribData(andx_n)) = *((UT_Vector3 *)ppt->getAttribData(andx_in)); } } which works too, but I have a feeling that there's a faster/better/more efficient way of doing it that I haven't found yet ? Thanks. Quote Link to comment Share on other sites More sharing options...
sibarrick Posted February 28, 2006 Share Posted February 28, 2006 Try gdp->normal(); Quote Link to comment Share on other sites More sharing options...
Mario Marengo Posted February 28, 2006 Author Share Posted February 28, 2006 Try gdp->normal(); 25199[/snapback] Hahahaha I swear I looked at all the functions with the word "normal" in them... but I obviously missed the one I was looking for. Heh; well, it was a fun exercise anyway. Thanks! Quote Link to comment Share on other sites More sharing options...
sibarrick Posted February 28, 2006 Share Posted February 28, 2006 Don't feel bad, I got burned the exact same way last week, that's how I knew the answer. Quote Link to comment Share on other sites More sharing options...
Mario Marengo Posted February 28, 2006 Author Share Posted February 28, 2006 Don't feel bad, I got burned the exact same way last week, that's how I knew the answer. 25209[/snapback] Heheh. Yeah, my brain goes completely numb after greping headers and looking through those doxygen pages long enough -- I'm likely to forget my own name, never mind finding a function Cheers! 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.