Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

.obj -> sculpties

Rael Delcon
Registered User
Join date: 23 Nov 2006
Posts: 86
05-09-2007 03:52
I would like to create an OBJ->texture converter but I'm not 100% sure on the best approach to use. I understand only objects with a sphere topology are supported at the moment but let's assume the object described in the .obj can be sculpted.

At a general, conceptual level, and please correct me if I'm wrong, I envisage the conversion process to get a 64x64 textures as follows:

- draw a sphere around the object to be represented
- draw a 64x64 grid on the sphere (like parallels and meridans on a world map)
- for each ray from the center of the sphere to a grid point
-- compute the intersection of the ray with the object
- Scale, normalize, etc to fit into 0-255 range.

I understand the process as described above, assuming is correct, is heavy and that 3d software have means to ease that conversation so exporters are preferable to converters. Nevertheless there are so many 3D programs (CB Model Pro, anyone?) able to create .obj files that I believe a converter will prove itself useful.

That said, I must confess that I still don't understand many things. It's not clear to me how normals map (that is stored into the .obj file) relates to the sculpted texture even if elsewhere in this discussion someone said that from the normal maps one can derive the texture. Any hints?
Johan Durant
Registered User
Join date: 7 Aug 2006
Posts: 1,657
05-09-2007 04:16
Well that statement about the normal map relating to the texture mostly means that the texture map on the object will use the same texture coordinates as the normal map did. It's not that the normal map creates texture coordinates but the other way around; the texture coordinates you used for the normal map are also used for the surface texturing.
_____________________
(Aelin 184,194,22)

The Motion Merchant - an animation store specializing in two-person interactions
Rael Delcon
Registered User
Join date: 23 Nov 2006
Posts: 86
05-09-2007 05:26
Thanks Johan. Now that I read my previous post I see I got it wrong as it work only for convex objects!

I can see how to go from a texture encoding a sculpted prim (shall we call it a "sculptex"?) to the prim itself but I've not devised a generic algorithm to do the opposite!

Would anyone enlighten me on how to map a solid that is topologically equivalent to a sphere to a texture encoding a sculptured prim?
Johan Durant
Registered User
Join date: 7 Aug 2006
Posts: 1,657
05-09-2007 08:10
Actually the approach you described was pretty clever in it's simplicity, and if you don't do it I might give it a try. Yes that conversion technique does have a limitation in the topology, but then sculpted prims are fairly simple meshes so that limitation is already kind of true for the prims anyway.
_____________________
(Aelin 184,194,22)

The Motion Merchant - an animation store specializing in two-person interactions
Rael Delcon
Registered User
Join date: 23 Nov 2006
Posts: 86
05-09-2007 09:49
Johan, I was trying to find a method to convert non convex shapes as well. Imagine a vase that has been modeled deforming a sphere (lower one side of the sphere, raise the borders, ...).

The method I described in the first post will fail misarably as for almost each ray there will be two intersections and for some ray there might be none!

I understand that a general method should proceed moving on the surface of the solid, I'm not able to articulate it in 3D yet but I hope a description in 2D could help validate the approach. I guess I should have drawn some diagram to clarify what I'll say but if you can draw them while reading it should be easier to follow my reasoning.

In 2D our problem becomes having a closed curve C (topologically equivalent to a circle) approximated with (the border of) a polygon P whose vertice are P(1), P(2), ..., P(n). The polygon P is the equivalent of our .obj representation in 3D.

The 2D equivalent of a "sculptex" (my name for the texture defining a sculpie) is a list of m points S(1), S(2), ..., S(m) such that the polygon that has those points as vertices, still approximates the orignal curve C.

To determine such polygon, let's start considering a circle R whose circumference is equal to the perimeter of P.

Take an arbitrary point on R, call it R(1) and make it correspond to P(1). Now let's call L(1) the length of the segment from P(1) to P(2), take the point R(2) so that the circular segment from R(1) to R(2) has length L(1) and proceed this way up to R(n) (that will be equal to R(1)).

An alternate view could be dividing an unitary circle in slices that are proportional to the length of the sides of P.

Now divide the circle R in m equal parts taking m points T(1), T(2), ..., T(m) starting from T(1) = R(1).

S(1) will be equal to P(1).

To determine S(k) consider that T(k) will fall into one of the circular segment R(j) - R(j+1) so that
From: someone
T(k) = R(j) + t * ( R(j+1) - R(j)). Once determined j and t, let's take
From: someone
S(k) = P(j) + t * (P(j+1) - P(j)) .

Translating the polygon S given by S(1), S(2), ..., S(m) into the origin will give us our sculptex!

Assuming the above is correct, the hard part is now to translate it in 3D! I guess the reasoning will involve triangles, as they are the equivalent of segments in 3D, and portions of a sphere.

The biggest risk is that there is a simpler method that I've not been able to think of!!!
[/code][/code]
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-09-2007 10:32
You might find this Thread very helpful. :)
You can skip the stuff that i wrote, but Michael Gibson knows how to do it.
He wrote Rhino and MoI.
_____________________
Chip Midnight
ate my baby!
Join date: 1 May 2003
Posts: 10,231
05-09-2007 10:40
The method you're describing is pretty much exactly what 3ds Max's projection modifier does, and it's the way I've been making sculpties. Basically a projection cage (in this case a sphere since that's the base object in SL) is created around a tiny sphere placed inside the target object, with its projection cage large enough to enclose the target mush. Rays are sent out along each surface normal until it intersects the target object and the location of those hits are recorded in RGB. Max's projection tool is intended to record the differences between two models, so ordinarily the mesh with the projection modifier on it is the same basic size and shape as the target mesh. To get it to do what's needed for an SL sculptie the original object is a tiny sphere so what ends up being recorded is the distance of the ray intersections from the center. The long and short of it is that your proposed method would work great.
_____________________

My other hobby:
www.live365.com/stations/chip_midnight
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
05-09-2007 10:44
I think the general problem is a hard one. The thing is, there is a whole lot of information in how you map an arbitrary mesh (even one that is topologically a sphere) to a uv square. How much detail does one assign to different areas? Ideally you'd want to have the area of part of the uv square be proportional to the number of vertices in the corresponding part of the mesh. This kind of thing requires heuristics.

I might start by trying to get some map to the uv square and then later modify it based on the number of vertices in different areas, but even that first step seems tricky.

Ok, I guess you'd want to pick two vertices to be the poles ("N" and "S";) and use pathfinding algorithms to draw a shortest line between the two (presumably you should choose your poles so that the shortest path between them is maximised). Cut your mesh along this line (so that future pathfinding algorithm stuff sees it as a boundary). We now have an opened out sphere with two boundary paths. Name the midpoints of those two paths "W" and "E". They map to the same vertex on the original model.

Then perhaps find what will be the midpoint of your uv square, "C" by choosing a vertex that is roughly equidistant from N and S, and that is roughly equidistant from W and E. Now cut the mesh up again along the new lines you've found and repeat.

Using the subdivision into squares you'd get from this algorithm it should be possible to keep going down in size until you get to a 64x64 grid say, then just choose the colours of the corresponding positions in the mesh. You'd have to notice if you can't find midpoints of lines anymore, for when there's only one triangle there, and do some interpolation to find the colours of points in the uv square between vertices that you do know (this small bit I've already done in python).

Anyone up for trying to convert this pseudoalgorithm into code?
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
05-09-2007 10:51
From: Rael Delcon
At a general, conceptual level, and please correct me if I'm wrong, I envisage the conversion process to get a 64x64 textures as follows:

- draw a sphere around the object to be represented
- draw a 64x64 grid on the sphere (like parallels and meridans on a world map)
- for each ray from the center of the sphere to a grid point
-- compute the intersection of the ray with the object
- Scale, normalize, etc to fit into 0-255 range.


That's pretty much right on the money. A slightly simpler way is to create a very tiny 64x64 quads sphere instead, and use normal for each face as direction to fire the ray, then encode measured distance to intersection point with the target mesh. This method emulates normal mapping software -- for that matter, you can probably get source code for ATI's normal mapper from their developer page and adapt it quite easily.

(and yes, this way won't be able to parse some certain more complicated object, but it's good enough for most cases)
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-09-2007 10:52
Another Hint : Xnormal uses a Cage
to bake normals and Stuff.
There is a Plugin API, too...
I wonder if this awesome Tool can be used for that ?
(with a custom Plugin, of course.)
You see, i did some Research, but my Programming Skills are poor
and my Time is limited.
_____________________
Rael Delcon
Registered User
Join date: 23 Nov 2006
Posts: 86
05-09-2007 11:31
First of all happy to see there are many interested to the topic. I hope we'll find a solution joining the forces!

@Cindy
Thanks for the thread and the XNormal link. I'll have a closer look to both! The thread provides many useful hints!

@Chip
I guess 3dsMax is able to deal with the more complex cases the simple idea I described is not able to cope with.

@Seifert
I didn't think at finding paths on the surface and you're perfectly right, deciding how to re-approximate the surface is not a trivial task.

@Joannah
I'll check the ATI page. Didn't know they offered code, that's very good!

While driving back home (yes I was in the office while I wrote the previous post) it struck me that the grid on the sphere needs not to be evenly spaced!

I'm not sure how this can be used but in the 2D example this implies that if n<= m the polygon S can be made exactly equal to P adding extra points on the segments between consective vertices.

If this property holds in 3D as well it might open up to other possbilities!
Chip Midnight
ate my baby!
Join date: 1 May 2003
Posts: 10,231
05-09-2007 12:11
From: Rael Delcon
@Chip
Hi guess 3dsMax is able to deal with the more complex cases the simple idea I described is not able to cope with.


I'm not so sure about that. If it's used for the purpose it was intended and the projection cage mesh has the same shape and basic structure as the target then yes, but when having to use a sphere as the projection cage I think it's prone to the same drawback and limitations as your converter would be.
_____________________

My other hobby:
www.live365.com/stations/chip_midnight
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-09-2007 12:23
I did some Experiments with xNormal, using the Blender Monkey with
the well known RGB Material and random UV coords (not cylinder or sphere),
and a Sphere with correct UV's .... and baked the texture from the
Monkey to the Sphere. (no custom Plugin, only xNormal out of the Box)
The Result is still ugly, but looks promising. This might actually work. :D
I have to read the xNormal Manual again, this Program takes some Time to learn.
_____________________
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-10-2007 22:31
If you want to do an Experiment...
Here is something to play with (for Windows only)): (see Attachment)

How to use :
- Create an Object in your favorite 3D Modeler (only one Object)
- Make sure the UV Map is Without Holes (thats not easy)
- Export to .obj, 'Wavefront Style', with UVs, Triangles only (!)
- drag and drop the .obj File to obj2sculpt (in Windows Explorer)
- Alternative : use the command line like 'obj2sculpt myprettyobject.obj'
- if you get a cryptic error mesage, install .NET 2.0
- you should get a .bmp File, named like myprettyobject.obj.bmp
- use a sculptie previewer, or preview in beta
- flame me, because it sucks (or not ?)

yes, i know, there is more work to be done... :p

UPDATED :
- gives better Results now.
- removed Debug Output (oops) :o
- fixed reading of .obj Files from 3DMAX
- fixed .bmp output, now SL should upload it directly

KNOWN BUGS :
- flipped normals (faces pointing inward) can happen... :(
_____________________
Rael Delcon
Registered User
Join date: 23 Nov 2006
Posts: 86
05-10-2007 23:24
Bad luck! It says "Maintenance has commenced"! It looks like SL is not the only system that goes down for sudden maintenance :)

I'll have a look back from the office.

I guess you used the UV method described in the thread you pointed me to, very smart!

I'm still banging my head on spherical math ... I guess there must be a simpler way ....
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-11-2007 00:34
From: Rael Delcon
Bad luck! It says "Maintenance has commenced"! It looks like SL is not the only system that goes down for sudden maintenance :)

I'll have a look back from the office.

I guess you used the UV method described in the thread you pointed me to, very smart!

I'm still banging my head on spherical math ... I guess there must be a simpler way ....


Yes, i used the UV method, but its still incomplete... the results can be a lot better.
I will continue later, first its time for some sleep :)

Edit : Download works now, i tried it.
_____________________
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
05-11-2007 01:31
My ISP looks to be blocking them, fortunately coralizing the URL makes it work (I use ErrorZilla, but I've customized it a bit).
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Domino Marama
Domino Designs
Join date: 22 Sep 2006
Posts: 1,126
05-11-2007 02:11
From: Cindy on MOI
-Scale all Axes to the Maximum, prior to the Rounding.


Make it an option, not automatic. The Blender method ends up doing this as a side effect and it causes distortion due to rounding errors. A bike exhaust that is a lot longer than wide is very tricky to keep rounded when this pre export scaling is done. In fact a checkbox for normalising each axis seperately is probably the best approach, let people choose between consistancy of result or finer detail as needed.
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-11-2007 07:21
From: Domino Marama
Make it an option, not automatic. The Blender method ends up doing this as a side effect and it causes distortion due to rounding errors. A bike exhaust that is a lot longer than wide is very tricky to keep rounded when this pre export scaling is done. In fact a checkbox for normalising each axis seperately is probably the best approach, let people choose between consistancy of result or finer detail as needed.


Thats a good Idea... sad but true, the only Way to add Options to 3dm2sculpt
(or obj2sculpt)at the Moment would be the good old command Line - building
a nice GUI for a Program that is far from completely working looks like
a Waste of Time for me. It seems like 3dm2sculpt is doomed, because even
the OpenNurbs example Programs can not read all Rhino 3dm Files... dammit :mad:
_____________________
Cat Jericho
Registered User
Join date: 21 Dec 2006
Posts: 4
05-12-2007 06:43
Hello,

I'm having problems using the obj2sculpt exe with obj files
exported from 3dsmax9.
It throws an exception at System.Number.StringToNumber().

I assume it has to do with the format of the floats it wants to read.
Does it expect a certain format there ?

In 3dsmax I can specify the number of digits for the floats.
I tried from 1 to 6, but nothing works.

Does anyone have an answer to this problem?
Or maybe an obj file that actually works.
Then I can have a look by myself.

Thanks
Cat
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-12-2007 10:20
From: Cat Jericho
Hello,

I'm having problems using the obj2sculpt exe with obj files
exported from 3dsmax9.
It throws an exception at System.Number.StringToNumber().

I assume it has to do with the format of the floats it wants to read.
Does it expect a certain format there ?

In 3dsmax I can specify the number of digits for the floats.
I tried from 1 to 6, but nothing works.

Does anyone have an answer to this problem?
Or maybe an obj file that actually works.
Then I can have a look by myself.

Thanks
Cat


I would be able to fix the Bug if you give a .obj File that triggers the Error.
At the Moment, i finished an Update of obj2sculpt.
The new Version gives very exact Results :)
I Implemented the Barycentric Interpolation Thingy.
I will upload now, let me know what you think about it.

EDIT : Done. Attached to Original Post.
_____________________
Cat Jericho
Registered User
Join date: 21 Dec 2006
Posts: 4
05-12-2007 10:53
I prepared an obj file with an single line in it:

v 10.137699 28.786829 7.677856

Even that file gives me the exception.
Can it be that there is a problem with the systems language settings ?
Mine is set to german.

Greetings
Cat
2k Suisei
Registered User
Join date: 9 Nov 2006
Posts: 2,150
05-12-2007 10:59
From: Cindy Crabgrass
I would be able to fix the Bug if you give a .obj File that triggers the Error.
At the Moment, i finished an Update of obj2sculpt.
The new Version gives very exact Results :)
I Implemented the Barycentric Interpolation Thingy.
I will upload now, let me know what you think about it.

EDIT : Done. Attached to Original Post.


I tested it on a ZBrush object. I exported it as triangles. But when uploaded into SL, it was inside out. But other than that, it seemed to work. :)
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-12-2007 11:13
From: Cat Jericho
I prepared an obj file with an single line in it:

v 10.137699 28.786829 7.677856

Even that file gives me the exception.
Can it be that there is a problem with the systems language settings ?
Mine is set to german.

Greetings
Cat


Ah, thats a good hint.
I run German Windows XP, too.
I had to override the Settings, using Code like this :
f.t1 = Convert.ToInt32(t2[1], NumberFormatInfo.InvariantInfo);
my Favorite .obj File for testing looks like this :
v -0.132665 0.882992 0.277190

Hmm.. give me some Time to think about that...
it works for me, but not for you... hmmm...

some more Code, this one reads a Line of vertices :
CODE

if (line.StartsWith("v "))
{
vertex v = new vertex();
//Console.WriteLine("line : " + line);
string[] tokens = line.Split(new char[] { ' ' });
v.x = Convert.ToDouble(tokens[1], NumberFormatInfo.InvariantInfo);
v.y = Convert.ToDouble(tokens[2], NumberFormatInfo.InvariantInfo);
v.z = Convert.ToDouble(tokens[3], NumberFormatInfo.InvariantInfo);
//Console.WriteLine(v.x + " " + v.y + " " + v.z);
vertices.Add(v);
}
_____________________
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-12-2007 11:31
From: 2k Suisei
I tested it on a ZBrush object. I exported it as triangles. But when uploaded into SL, it was inside out. But other than that, it seemed to work. :)


Thats a Problem of 'Surface Normals'... well, i dont know if my Program
flips them, or if your .obj File is wrong.
If you Attach a copy of that File, i can take a look at it and see.
Otherwise, (i dont know much about ZBrush) make ZBrush display the Normals,
they should look like Spikes on the Surface, pointing outwards.
_____________________
1 2 3 4 5