PDA

View Full Version : uv position accuracy ?


martroyx
02-15-2009, 06:23 PM
Hi everyone,

I'm making a script to create a mask that you can use to render wireframe with scanline, the problem is that I'm getting some imperfection and sometime the edge get blurry...
anyone know where this is coming from ?


/*

Title : Uv Normalizer v0.77
Author : Martin Dufour
Web : martroyx.890m.com
Email : martroyx@hotmail.com
Date : 15 February 2009

Note :

The purpose of this script is to create a mask for wireframe rendering with scanline.
The object need to be an editpoly with no modifer in the stack.
Non quad face will be moved out of the Uv space and contained within the mask offset.

*/

try (destroydialog XuvRoll) catch ()
(
--//--
Global XuvRoll
local XuvStr="Uv Normalizer v0.77"
local XuvDir=(getFilenamePath(getSourceFileName()))
local XChannel=3
local Xover=5
local XSize=2048
local FaceList=#()
local XUndo=#()
local TTx=TTy=TTw=TTh=TTu=TTa=undefined
--//--
fn NormalizeUv =
(
if selection.count == 1 and (classof selection[1])==Editable_Poly then
(
max modify mode
Xobj=selection[1]
--//-- Saving Face MaterialID !
XWriter=(dotnetobject "System.IO.StreamWriter" (XuvDir+"\\IDBackup.Xid") true)
for f in 1 to (polyop.getNumFaces Xobj) do
(
XWriter.WriteLine((dotnetobject "System.Int32" (polyop.getFaceMatID Xobj f)))
)
XWriter.close()
XWriter.dispose()
--//-- Setting Unique ID for every face !
for f in 1 to (polyop.getNumFaces Xobj) do (polyop.setFaceMatID Xobj f f)
--//-- Creating the New Uv !
NewUV=unwrap_UVW()
NewUV.setMapChannel XChannel
NewUV.setApplyToWholeObject true
--//--
--//-- Dev Debug stuff !
--//--
--NewUV.setTileMap false
NewUV.setConstantUpdate true
NewUV.setDebugLevel 0
--//--
--//--
addmodifier Xobj NewUV
modPanel.setCurrentObject NewUV
--//-- Breaking up the face!
NewUV.flattenMapByMatID 0 0.02 true 0 false false
--//-- Packing up the Uv, to optimize space usage !
NewUV.pack 1 0.01 true false true
--//-- Moving texture vertex into position !
for f in 1 to (polyop.getNumFaces Xobj) do
(
Xeval=NewUV.numberPointsInFace f
--//--
case Xeval of
(
4:(
--//--
--//-- Finding Vertex order ...
--//--
TRight=undefined --**--
TLeft=undefined
BRight=undefined
BLeft=undefined --**--
--//--
VIdx=for i in 1 to 4 collect (NewUV.getVertexIndexFromFace f i)
--//--
Xval=for j in VIdx collect (NewUV.getVertexPosition 0f j).x
Yval=for j in VIdx collect (NewUV.getVertexPosition 0f j).y
--//--
Tp=#()
for j in 1 to 2 do
(
Wx=(finditem Xval (amax Xval))
append Tp Wx
Xval[Wx]=-1.0
)
--//--
Bt=for j in 1 to 4 where (finditem Tp j)==0 collect j
--//--
for j in Tp do
(
EvalY=for i in 1 to 2 collect (Yval[(Tp[i])])
TRight=Tp[(finditem EvalY (amax EvalY))]
TLeft=Tp[(finditem EvalY (amin EvalY))]
)
--//--
for j in Bt do
(
EvalY=for i in 1 to 2 collect (Yval[(Bt[i])])
BRight=Bt[(finditem EvalY (amax EvalY))]
BLeft=Bt[(finditem EvalY (amin EvalY))]
)
--//--
Apos=NewUV.getVertexPosition 0f (NewUV.getVertexIndexFromFace f TRight)
Bpos=NewUV.getVertexPosition 0f (NewUV.getVertexIndexFromFace f BLeft)
--//--
--//-- Correct the position to fit the pixel from the mask !
--//--
Xset=(1.0/XSize)
--//--
Apos.x=((floor(Apos.x/Xset))*Xset)
if Apos.x <= 0 then Apos.x=Xset
if Apos.x >= 1 then Apos.x=(1.0-Xset)
--//--
Apos.y=((floor(Apos.y/Xset))*Xset)
if Apos.y <= 0 then Apos.y=Xset
if Apos.y >= 1 then Apos.y=(1.0-Xset)
--//--
Bpos.x=((floor(Bpos.x/Xset))*Xset)
if Bpos.x <= 0 then Bpos.x=Xset
if Bpos.x >= 1 then Bpos.x=(1.0-Xset)
--//--
Bpos.y=((floor(Bpos.y/Xset))*Xset)
if Bpos.y <= 0 then Bpos.y=Xset
if Bpos.y >= 1 then Bpos.y=(1.0-Xset)
--//--
if XuvRoll.Ck_Uvx.checked then
(
if ((Apos.x-Bpos.x) < (Xover*Xset)) then (Apos.x = (Bpos.x+(Xover*Xset)))
if ((Apos.y-Bpos.y) < (Xover*Xset)) then (Apos.y = (Bpos.y+(Xover*Xset)))
)
--//--
NewUV.setVertexPosition2 0f (NewUV.getVertexIndexFromFace f TRight) Apos false true
NewUV.setVertexPosition2 0f (NewUV.getVertexIndexFromFace f BLeft) Bpos false true
--//--
--//-- align the vertex, to eliminate face distortion !
--//--
Vx=NewUV.getVertexIndexFromFace f TLeft
Xpos=[(Apos.x),(Bpos.y),0]
NewUV.setVertexPosition2 0f Vx Xpos false true
--//--
Vx=NewUV.getVertexIndexFromFace f BRight
Xpos=[(Bpos.x),(Apos.y),0]
NewUV.setVertexPosition2 0f Vx Xpos false true
--//--
--//-- Saving the Face index for the offset process !
--//--
append FaceList f
)
default:(
--//-- Moving unwanted vertex outside the Uv space !
for i in 1 to Xeval do
(
Vx=NewUV.getVertexIndexFromFace f i
NewUV.setVertexPosition2 0f Vx [1.001,.001,0] false true
)
)
)
--//--
)
--//-- Open the Edit Panel !
NewUV.edit()
--//-- Fixing Inverted face !
NewUV.setTVSubObjectMode 3
NewUV.selectInvertedFaces()
Xprocess=(NewUV.getSelectedFaces())as array
--//--
for f in Xprocess do
(
NewUV.selectFaces #{f}
NewUV.flipHorizontal()
)
--//--
NewUV.selectFaces #{}
--//-- Restoring the original Face MaterialID !
XReader=(dotnetobject "System.IO.StreamReader" (XuvDir+"\\IDBackup.Xid"))
for f in 1 to (polyop.getNumFaces Xobj) do
(
polyop.setFaceMatID Xobj f (XReader.ReadLine() as integer)
)
XReader.close()
XReader.dispose()
deleteFile (XuvDir+"\\IDBackup.Xid")
--//-- Creating Undo array
for f in FaceList do
(
Newarr=for i in 1 to 4 collect (NewUV.getVertexPosition 0f (NewUV.getVertexIndexFromFace f i))
append XUndo Newarr
)
--//-- Open the Render Uv dialog !
NewUV.renderuv_width=XSize
NewUV.renderuv_height=XSize
NewUV.renderuv_seamColor=white
NewUV.renderuv_seamedges=true
NewUV.renderUVDialog()
--//-- End the normalize process !
XuvRoll.Bt_Uvx.enabled=false
XuvRoll.Sp_Rdn.enabled=false
XuvRoll.Sp_Uvx.enabled=false
XuvRoll.Sp_Skip.enabled=false
XuvRoll.Bt_Push.enabled=true
)
)
--//--
fn PushUv =
(
Uvx=undefined
if selection[1] != undefined then Uvx=selection[1].modifiers[#unwrap_uvw]
--//--
if Uvx != undefined then
(
Uvx.edit()
Uvx.setTVSubObjectMode 3
Xset=(1.0/XSize)
Uvx.setResetPivotOnSelection true
--//-- Apply offset !
for f in FaceList do
(
Uvx.selectFaces #{f}
Uvx.moveSelected [((1.0/XSize)/2),-((1.0/XSize)/2),0]
--//--
Uvx.getArea #{f} &TTx &TTy &TTw &TTh &TTu &TTa
--//--
XRatio=1.0+((TTh/Xset)*(XuvRoll.Sp_Scale.value/100))
YRatio=1.0+((TTw/Xset)*(XuvRoll.Sp_Scale.value/100))
--//--
Uvx.scaleSelectedCenter XRatio 1
Uvx.scaleSelectedCenter YRatio 2
)
--//--
Uvx.selectFaces #{}
--//--
XuvRoll.Bt_Push.enabled=false
XuvRoll.Bt_Undo.enabled=true
)
--//--
)
--//--
fn UndoMod =
(
Uvx=undefined
if selection[1] != undefined then Uvx=selection[1].modifiers[#unwrap_uvw]
--//--
if Uvx != undefined then
(
Uvx.edit()
Uvx.setTVSubObjectMode 3
--//--
for f in FaceList do
(
for i in 1 to 4 do
(
Uvx.setVertexPosition2 0f (Uvx.getVertexIndexFromFace f i) (XUndo[(finditem FaceList f)][i]) false true
)
--//--
)
XuvRoll.Bt_Push.enabled=true
XuvRoll.Bt_Undo.enabled=false
--//--
)
--//--
)
--//--
rollout XuvRoll XuvStr width:140 height:292
(
group ""
(
spinner Sp_Uvx "Channel > " type:#integer range:[1,10,3] fieldWidth:36 align:#right offset:[-5,0]
spinner Sp_Rdn "Size > " type:#integer range:[2,8192,2048] fieldWidth:36 align:#right scale:2 offset:[-5,0]
spinner Sp_Skip "Min Pixels > " type:#integer range:[2,999,5] fieldWidth:36 align:#right scale:1 offset:[-5,0]
spinner Sp_Scale "Scale > " type:#float range:[-1,1,0] fieldWidth:36 align:#right scale:0.001 offset:[-5,0]
checkbutton Ck_Uvx "Min overlaps" width:104 height:20 checked:true offset:[0,6] highlightColor:(color 255 160 0) tooltip:"This option ensure that,\nthe Min Pixels value will be keep in each Uv part.\nIncrease the value to minimize edge distortion."
button Bt_Uvx "Normalize Uv" width:104 height:24 offset:[0,6]
button Bt_Push "Offset Uv" width:104 height:24 enabled:false
button Bt_Undo "Undo" width:104 height:24 enabled:false
button Bt_Reset "Reset" width:104 height:24
HyperLink Lk_Uvx "by Martin Dufour" address:"http://martroyx.890m.com/" color:(color 0 0 0) hovercolor:(color 0 0 0) align:#center offset:[0,6]
)
--//--
on Sp_Uvx changed val do XChannel=val
on Sp_Rdn changed val do XSize=val
on Sp_Skip changed val do Xover=val
--//--
on Bt_Uvx pressed do NormalizeUv()
on Bt_Push pressed do PushUv()
on Bt_Undo pressed do UndoMod()
--//--
on Bt_Reset pressed do
(
TTx=TTy=TTw=TTh=TTu=TTa=undefined
FaceList=#()
XUndo=#()
Sp_Scale.value=0
Bt_Uvx.enabled=true
Sp_Rdn.enabled=true
Sp_Uvx.enabled=true
Sp_Skip.enabled=true
Bt_Push.enabled=false
gc light:true
)
--//--
)
--//--
createdialog XuvRoll style:#(#style_sysmenu,#style_toolwindow)
)

ZeBoxx2
02-15-2009, 06:37 PM
seems okay here - what type of object causes the faulty result?

Edit: nevermind, I see what you mean

martroyx
02-15-2009, 06:48 PM
Difficult to say :hmm:

ZeBoxx2
02-15-2009, 06:50 PM
alright, second attempt at a reply, then...

The accuracy of the UVw coordinates is fine. However, the template that the Unwrap UVW modifier renders out is not-so-fine.

The basic problem is that pixels are discrete, integer coordinates and UV coordinates are float coordinates. So sometimes the lines the Unwrap modifier utility renders fall on the 'outside' end of the float and end up rendering thinner or even not at all (depending on how far the pixel coordinate is from the UV coordinate).

Rendering to a larger bitmap helps, but apparently it refuses to do an 8K square render here.

Alternative/fixes:
- blur the bitmap a little (in the bitmap texture)
- thicken the lines yourself a bit (using e.g. maxscript)
- render youw own map (again, using e.g. maxscript) to always render the lines on the 'insides' of the UV lines.
- use a wireframe map plugin ;)

martroyx
02-15-2009, 07:03 PM
- render youw own map (again, using e.g. maxscript) to always render the lines on the 'insides' of the UV


Humm , this may be the solution because when I manually move one of the faulty edge this seam to render better !

ZeBoxx2
02-15-2009, 07:50 PM
Note that you will still get varying line thicknesses -and- you run the risk (in theory, at least, the more I think about it the less it seems likely to me) that an edge will actually have a thin sliver -not- wired, but at least they shouldn't disappear anymore. Best bet, I think, would be to draw the pixels on both sides of the actual UV line's float coordinates.

martroyx
02-15-2009, 07:57 PM
I'm wondering if it may come from the fact that I set the position of the vertex with their .pos property and not the <uv>.setVertexPosition2() methods , maybe this lead to inaccuracy ?

edit:Oups , I'm actually using setVertexPosition2 , forget this :rolleyes:

martroyx
02-15-2009, 08:44 PM
Ho!, another weird thing, when I move the uv around the position relative to the map change... but I guest it just some drawing bug :curious:

CGTalk Moderation
02-15-2009, 08:44 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.