UV Mirror H&V
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 25/07/2012 at 08:25, xxxxxxxx wrote:
Is support going to answer this person's question?
I have some questions about the SDK and UV support too. And the answer to this question might help me with out my own UV editing questions.
-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 25/07/2012 at 19:00, xxxxxxxx wrote:
Well after some testing and trying, i came with the following conclusion.
When you're in polygon mode or any mode u have in the standard layout and you want a button that switches to polygon uv mode. It doesn't work, but when i change the layout first to bodypaint UV and back.. and then i push my plugin button with the callcommand it works without any problems.
I don't know if it's a bug, but its really annoying that u can't use Bodypaint functions directly after C4D is loaded. So i came up with my own function that does the uv switching.
~Dynad
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 25/07/2012 at 19:39, xxxxxxxx wrote:
When you say you came up with your own function. Do you mean that you are switching layouts, then executing the CallCommands with a function?
Or are you editing the UV's directly inside of the UVW struct?One of the problems I'm having is figuring out how to execute the "Frontal" projection button.
Frontal (and several other buttons) is not listed in the SDK. And it's not declared in the painter.h file. So AFAIK it can't be called with the CallUVCommand().
I was hoping the support guys would provide you a solution to making the Mirror V button work. Because that too is a button that is not supported in CallUVCommand. Just like the Frontal button.I'm also having an issue getting changed UVW struct vertices to update after I change them.
But that's a separate issue.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 25/07/2012 at 21:39, xxxxxxxx wrote:
Well i rewrote the function myself, cause i couldn't fix the button problem. So i edit the UVW struct instead.
The only way to call the functions is to use the callcommand and use its ID which u can look up in the "Customize commands".
If u want to edit the struct, u need to make sure that your in write mode.
GetDataAddressR(),i,uvw) <-> GetDataAddressW(),i,uvw);~Dynad
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 07:47, xxxxxxxx wrote:
The UV point editing problem I'm having is the UV points don't move. Even when using the W flag.
Here's the code:
BaseObject *obj = doc->GetActiveObject(); if(!obj)return FALSE; PointObject *pobj = ToPoint(obj); //Cast the BaseObject type to a PointObject type and assign it to a variable "pobj" Vector *points = pobj->GetPointW(); //Get the array of points in the object(returns their vector positions) LONG count = pobj->GetPointCount(); TempUVHandle *handle = GetActiveUVSet(doc, GETACTIVEUVSET_ALL); //Create an instance of the TempUVHandle class if (!handle) return FALSE; UVWTag *uvwtag = (UVWTag* )(pobj->GetTag(Tuvw, 0)); //The UVW tag that's on the object UVWHandle dataptr = uvwtag->GetDataAddressW(); //The array of polygons in the UVWtag LONG UVpolycount = handle->GetPolyCount(); GePrint(LongToString(UVpolycount)); UVWStruct res; //A struct that we will eventually store the UV values in for (LONG i=0; i<UVpolycount; i++) { LONG polyindx = i; //Assign the polygon's index# to a variable UVWTag::Get(dataptr, i, res); //Store the polygon UVW info into the variable "res" Real ax = res.a.x; //These are the x,y UV canvas coords. for each point in each UVpolygon(a,b,c,d) Real ay = res.a.y; ax = 0.5; //Move the vertex res.a.x to 0.5 on the canvas uvwtag->Set(dataptr,i,res); //Update the changes to the UVpolygon in the UVW tag <--------Not working!! GePrint("ID#: " + LongToString(polyindx)); GePrint("AX: " + RealToString(ax) +".... " + "AY: " + RealToString(ay)); } FreeActiveUVSet(handle); //Free the memory pobj->Message(MSG_UPDATE); EventAdd();
Everything appears to work correctly. But for some reason the UVW tag won't update to reflect the changes I've made to any of the UV points.
I thought the Set() function was for setting any UV changes. But it's not working for me. And I don't know why.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 08:02, xxxxxxxx wrote:
I would recommend to change the UVs directly from the UVWTag with UVWTag::GetDataAddressW and UVWTag::Get and UVWTag::Set. This will give you a pointer to the UV array and the individual UV structures. The UVWStruct contains the UVs for the given polygon. Mirror the UV vectors and set the UVs with UVWTag::Set.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 08:03, xxxxxxxx wrote:
Scott, I think you need to send a MSG_UPDATE message to the UVWTag as well.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 08:19, xxxxxxxx wrote:
Thanks for the help Matthias,
uvwtag->Message(MSG_UPDATE); didn't seem to help.I'm not sure how to use UVWTag::GetDataAddressW; like you're suggesting.
How do I use it so it knows which UWV tag I'm referring to?
Do I set the tag active active with: SetBit(BIT_ACTIVE);
Then follow it with: UVWTag::GetDataAddressW;?The UVWTag class is a bit confusing to me trying to use it directly like that.
-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 08:23, xxxxxxxx wrote:
I'll try to come up with an example.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 08:28, xxxxxxxx wrote:
That would be very helpful. Thank you.
Also.
Is there any way at all that we can execute the UV projection buttons (Sphere, Cylinder, Frontal, etc..)?Thanks,
-ScottA -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 08:33, xxxxxxxx wrote:
Many of the UV commands are avaible through the CallUVCommand function. This would be an alternative for mirroring as well. It's the way BodyPaint works. I'll try to show this in the example rather than through the UVWTag.
So there are several ways to manipulate UVs. In the end it always depends on what you are exactly trying to do.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 09:06, xxxxxxxx wrote:
You actually already posted an example how to use CallUVCommand() a while back. And that's where I learned how to use it.
But there's a lot of buttons that are not included in it. Like the "Frontal" and "Mirror V"buttons for example. That's why I switched to editing the UV points individually.
I'm looking in the C4D_painter.h file. And I don't see these buttons defined in there.
And in the C4D_painter.cpp file. The function seems to call to a private class:return C4DOS.Pa->CallUVCommand(padr,PointCount,polys,lPolyCount,uvw,polyselection,pointselection,op,mode,cmdid,settings);
Even if the users were smart enough to add new definitions to CallUVCommand(). It seems that we can't access the class that does all the work. But maybe I'm missing something?
That's why I was thinking there might be an undocumented way to execute the actual buttons themselves. Something similar to this:
LONG tool_id = doc->GetAction(); BasePlugin *tool = NULL; tool = FindPlugin(tool_id, PLUGINTYPE_TOOL); if(!tool) return FALSE; DescriptionCommand dc; dc.id = DescID(MDATA_CREATEPOLYGON_BUTTON); tool->Message(MSG_DESCRIPTION_COMMAND, &dc); EventAdd();
-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 10:54, xxxxxxxx wrote:
In case it's useful, here is some code that I cobbled together from some older SDK example code...
//------------------------------------------------------------------------------------------------------ //****************************************************************************************************** // FrontalMapUVs() - perform a simple 'frontal' uv-mapping //****************************************************************************************************** //------------------------------------------------------------------------------------------------------ #define SIGDIG 5.0 static Real sign(Real n) { if( n > 0.0 ) return 1.0; if( n < 0.0 ) return -1.0; return 0.0; } static Real TrimDecimal(Real num, Real digits) { Real n; n = num * Pow((Real)10.0, digits); n = sign(n) * Abs(Floor(n + 0.5)); return n / Pow((Real)10.0, digits); } Bool FrontalMapUVs(PolygonObject *op, Matrix mg) { if( !op ) return false; LONG numFaces = op->GetPolygonCount(); LONG numVerts = op->GetPointCount(); Vector *pVerts = op->GetPointW(); CPolygon *pPolys = op->GetPolygonW(); UVWTag *pUVTag = (UVWTag * )op->MakeVariableTag(Tuvw, numFaces); if( !pUVTag ) return false; #ifdef _R12_SDK_ UVWHandle pUVHndl = pUVTag->GetDataAddressW(); if( !pUVHndl ) return false; #elif _R11p5_SDK_ void *pUVHndl = pUVTag->GetDataAddressW(); if( !pUVHndl ) return false; #else void *pUVHndl = NULL; #endif LONG ndx; Real lenxinv, lenyinv, lenzinv; Vector mapCenter, mapSize, vMin, vMax; vMin.x = 100000.0; vMin.y = 100000.0; vMin.z = 100000.0; vMax.x = -100000.0; vMax.y = -100000.0; vMax.z = -100000.0; for(ndx=0; ndx<numVerts; ndx++) { Vector pt = pVerts[ndx] * mg; if( pt.x < vMin.x ) vMin.x = pt.x; if( pt.x > vMax.x ) vMax.x = pt.x; if( pt.y < vMin.y ) vMin.y = pt.y; if( pt.y > vMax.y ) vMax.y = pt.y; if( pt.z < vMin.z ) vMin.z = pt.z; if( pt.z > vMax.z ) vMax.z = pt.z; } mapSize.x = Abs(vMax.x - vMin.x); mapSize.y = Abs(vMax.y - vMin.y); mapSize.z = Abs(vMax.z - vMin.z); mapCenter.x = vMin.x+(mapSize.x*0.5); mapCenter.y = vMin.y+(mapSize.y*0.5); mapCenter.z = vMin.z+(mapSize.z*0.5); if (mapSize.x!=0.0) lenxinv = 1.0/mapSize.x; else lenxinv = 0.0; if (mapSize.y!=0.0) lenyinv = 1.0/mapSize.y; else lenyinv = 0.0; if (mapSize.z!=0.0) lenzinv = 1.0/mapSize.z; else lenzinv = 0.0; // Walk the list of polygons and map the UVs for(ndx=0; ndx<numFaces; ndx++) { UVWStruct uvw; cmpUVGet(pUVTag, pUVHndl, ndx, uvw); Vector pt_a = (pVerts[pPolys[ndx].a] - mapCenter) + mg.off; Vector pt_b = (pVerts[pPolys[ndx].b] - mapCenter) + mg.off; Vector pt_c = (pVerts[pPolys[ndx].c] - mapCenter) + mg.off; Vector pt_d = (pVerts[pPolys[ndx].d] - mapCenter) + mg.off; uvw.a.x = TrimDecimal((pt_a.x*lenxinv)+0.5, SIGDIG); uvw.a.y = TrimDecimal((-pt_a.y*lenyinv)+0.5, SIGDIG); uvw.b.x = TrimDecimal((pt_b.x*lenxinv)+0.5, SIGDIG); uvw.b.y = TrimDecimal((-pt_b.y*lenyinv)+0.5, SIGDIG); uvw.c.x = TrimDecimal((pt_c.x*lenxinv)+0.5, SIGDIG); uvw.c.y = TrimDecimal((-pt_c.y*lenyinv)+0.5, SIGDIG); uvw.d.x = TrimDecimal((pt_d.x*lenxinv)+0.5, SIGDIG); uvw.d.y = TrimDecimal((-pt_d.y*lenyinv)+0.5, SIGDIG); cmpUVSet(pUVTag, pUVHndl, ndx, uvw); } return true; }
...note that I call that routine IF the mesh is not already uv-mapped...
// start by grabbing the current UVWTag UVWTag *pSrcUVs = (UVWTag* )(op->GetTag(Tuvw, 0)); if( !pSrcUVs ) { // if not already mapped, do a simple frontal mapping if( !FrontalMapUVs(op, op->GetMgn()) ) return NULL; ....
...also note that I'm just passing the mesh's global matrix, so you could remove that argument and just grab it inside that routine.
The only other note is the "cmpUVGet()/cmpUVSet()" calls... those are calls to my version-compatibility routines...
//------------------------------------------------------------- // cmpUVGet() //------------------------------------------------------------- void cmpUVGet(UVWTag *pUVWTag, UVWHandle pUVHndl, LONG ndx, UVWStruct& uvw) { #ifdef _R11p5_SDK_ if( pUVWTag && pUVHndl ) pUVWTag->Get(pUVHndl, ndx, uvw); #else if( pUVWTag ) uvw = pUVWTag->Get(ndx); #endif } //------------------------------------------------------------- // cmpUVSet() //------------------------------------------------------------- void cmpUVSet(UVWTag *pUVWTag, UVWHandle pUVHndl, LONG ndx, const UVWStruct& uvw) { #ifdef _R11p5_SDK_ if( pUVWTag && pUVHndl ) pUVWTag->Set(pUVHndl, ndx, uvw); #else if( pUVWTag ) pUVWTag->Set(ndx, uvw); #endif }
...where my _Rxx_SDK_ defines are cumulative (ie. R11.5 is also defined in my R12 (and later) builds and R11.5 and R12 defines are also defined in my R13 (and later) builds, along with the R13 define, etc.). This is a carry-over from long, long ago... I'm in the process of changing over to a "#if API_VERSION < 13000" type system.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 11:23, xxxxxxxx wrote:
Thanks Giblet.
That might come in handy later on. But right now I can't even manage to make simple UV point move where I want it to go.
I can give them new positions. And those new positions show up as being changed in the console.
But they won't budge on the UV canvas. And I don't know why.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 11:25, xxxxxxxx wrote:
Just do...
pPolyObj->Message(MSG_UPDATE); EventAdd();
...after changing anything on pPolyObj (including any UVWTag modifications). EDIT: that is... after doing all your changes (you only need to do it once, before returning from your plugin code).
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 11:35, xxxxxxxx wrote:
Yeah. I tried that (see the code example I posted earlier).
It's not working.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 11:57, xxxxxxxx wrote:
Scott, from where do you call your UV code, e.g. what kind of plugin (tag, command etc.)?
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 12:09, xxxxxxxx wrote:
I'm doing it from a GeDialog plugin. Inside of the Command() method.
We are allowed to edit the existing UV's in existing uvwtags right?
I see lots of MakeTag type UV code in the forums. But not much that deals with editing existing uvwtags.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 13:01, xxxxxxxx wrote:
The problem is that you are NOT modifying the uvw struct before you Set() it back - you are only modifying (and printing) a local variable.
EDIT: In other words...
ax = 0.5; //Move the vertex res.a.x to 0.5 on the canvas uvwtag->Set(dataptr,i,res); //Update the changes to the UVpolygon in the UVW tag <--------Not working!!
Your comments above are incorrect... modifying the local 'ax' variable is not the same as modifying res.a.x
To fix it, you'd need to...**res.a.x** = 0.5; //Move the vertex res.a.x to 0.5 on the canvas uvwtag->Set(dataptr,i,res); //Update the changes to the UVpolygon in the UVW tag <--------It works!!
Cheers.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 13:29, xxxxxxxx wrote:
..just another comment/suggestion...
If you're going to be calling Get()/Set() on the UVWTag (and/or looping through all the uv-polys), then you typically don't need to do the GetActiveUVSet() stuff... that's mostly useful when you need to know which uv-polys/points are currently selected or if you want to work with the arrays directly (uvhandle->GetUVW() / uvhandle->SetUVW()).
The reason it's needed for 'selected uv-points', for example is that... there are basically 4 uv-points per uv-polygon - which may be a far different number (and different indexing) than the total number of points/vertices of the mesh (a cube has 8 vertices, but it has 6 * 4 = 24 uv-points).