Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Extracting cubic beziers from .OBJ files

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Rochester, NY, USA
    Posts
    9

    Extracting cubic beziers from .OBJ files

    Hi,
    I'm trying to design my own 3d engine with cubic beziers patches being the primary primative (as opposed to dealing directly with triangles) and I'm pretty familiar with techniques like forward dfferencing to render the patches. My problem is importing geometry from standard file formats like .OBJ (.OBJ is one of a number of formats, but it seemed like the easiest and most common to start with). I've read the file format specifications that are posted on www.wotsit.org but most modelling programs store all curves as complex curves rather than nicely defined control points. What I would like to know is how to take that info out of the file and derive the control points from it and, in the case of more complex curved surfaces, how to break the curves up into smaller cubic patches. If anyone knows how to do this, knows of an example/tutorial, or knows of another file format that is easier for this please let me know. Any help would be greatly appreciated.
    -Daedalus

  2. #2
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Calgary,Canada
    Posts
    8

    Re: Extracting cubic beziers from .OBJ files

    Daedalus

    The best way to go about implemetning parametric surfaces into your program, would be to actually use the vertex information as the control points. This method would work best if implemented with bezier equations, I am unfamilier with how nurbs operate.

    If you want to break up the curved surface into smaller groups, the .obj format breaks up all its triangle information into groups. Just seperate the groups into a smaller chunks.

    I am unaware of any programs which export control point data, however their might be some.

  3. #3
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Seattle, WA USA
    Posts
    4

    Re: Extracting cubic beziers from .OBJ files

    I modified a 3DSMax (2.5 or 3.0) script that my friend wrote for gamasutra.com and made it export NURBs data. You can probably look at the MaxScript language and figure out how to get bezier patch data. The target format is called RTG and it's pretty easy to parse.

    -Joseph

    here's the MaxScript:

    -------------------------------------------------------------------------------------
    -- RTGExport.ms
    -- This utility exports geometry from Max 2.5 into the Alias text-based RTG v1.8 format.
    -- The RTG (RealTimeGames) format is not very well supported, but it is so simple that
    -- writing support for it is easy.
    --
    -- Original script was written by Wyeth Ridgway
    -- Modified by Joseph Laurino: added support for NURBS
    -------------------------------------------------------------------------------------
    utility RTGExport "Alias RTG v1.8 Export"
    (
    -- Define variables that are visible to all functions in the utility
    local ostream, tabs = ""

    -- Define the GUI interface
    group "Options"
    (
    checkbox cb_exportSelOnly "Export Selected Only"
    checkbox cb_outputVertNorms "Output Vertex Normals" checked:true
    checkbox cb_outputVertColors "Output Vertex Colors" checked:true
    checkbox cb_outputPolyNorms "Output Polygon Normals" checked:true
    checkbox cb_outputTexCoords "Output Texture Coords" checked:true
    checkbox cb_outputHierarchy "Output Hierarchy" checked:true
    )
    button btn_export "Save As..." width:100

    -- Now define the functions that the utility uses

    -------------------------------------------------------------------------------------
    -- This function exports a NURBSCVSurface object to the RTG file.
    -- <nurbscvsurface>.uOrder : integer
    -- <nurbscvsurface>.vOrder : integer
    -- <nurbscvsurface>.numUKnots : integer
    -- <nurbscvsurface>.numVKnots : integer
    -- <nurbscvsurface>.numCVs : point2

    function ExportNURBSCVSurface nurbsObj name =
    (
    -- Output the nurbs header
    Format "\n\nNURBS_START % uOrder% vOrder% numUKnots% numVKnots% numCVsU% numCVsV%\n" name nurbsObj.uOrder nurbsObj.vOrder nurbsObj.numUKnots nurbsObj.numVKnots (nurbsObj.numCVs.x as Integer) (nurbsObj.numCVs.y as Integer) to stream

    Format "\n" to stream
    for i = 1 to nurbsObj.numUKnots do
    (
    Format "UKNOT %\n" (getUKnot nurbsObj i) to stream
    )

    Format "\n" to stream

    for i = 1 to nurbsObj.numVKnots do
    (
    Format "VKNOT %\n" (getVKnot nurbsObj i) to stream
    )

    Format "\n" to stream

    for i = 1 to (nurbsObj.numCVs.x as Integer) do
    (
    for j = 1 to (nurbsObj.numCVs.y as Integer) do
    (
    controlVertex = (getCV nurbsObj i j )
    Format "CV x % y % z % w %\n" controlVertex.x controlVertex.y controlVertex.z controlVertex.weight to stream
    )
    )


    Format "\n\nNURBS_END %" name to stream
    )

    -------------------------------------------------------------------------------------
    -- This function exports a geometry object to the RTG file.
    function ExportMesh meshObj name =
    (
    -- Output the object header
    Format "\n\nOBJECT_START % v%" name meshObj.numVerts to stream
    if cb_outputVertNorms.checked then
    Format " n%" meshObj.numVerts to stream
    if cb_outputTexCoords.checked then
    Format " t%" meshObj.numtverts to stream
    Format " p%\n\n" meshObj.numFaces to stream

    -- Vertex output is in local space
    Format "VERTEX local\n" to stream
    if meshObj.numVerts > 0 then
    (
    for i = 1 to meshObj.numVerts do
    (
    vert = ((GetVert meshObj i)-meshObj.pos)
    Format "% % % %\n" (i-1) vert.x vert.y vert.z to stream
    )
    )

    -- Vertex normals
    if meshObj.numVerts > 0 and cb_outputVertNorms.checked then
    (
    Format "\nNORMAL\n" to stream
    for i = 1 to meshObj.numVerts do
    (
    normal = GetNormal meshObj i
    Format "% % % %\n" (i-1) normal.x normal.y normal.z to stream
    )
    )

    -- Texture coords
    if meshObj.numTVerts > 0 and cb_outputTexCoords.checked then
    (
    Format "\nTEXCOORD\n" to stream
    for i = 1 to meshObj.numTVerts do
    (
    uvw = GetTVert meshObj i
    Format "% % % %\n" (i-1) uvw.x uvw.y uvw.z to stream
    )
    )

    -- Polygon
    Format "\nPOLYGON\n" to stream
    if meshObj.NumFaces > 0 then
    (
    for i = 1 to meshObj.numFaces do
    (
    poly = GetFace meshObj i
    Format "% 3 v % % %" (i-1) (poly.x as integer -1) (poly.y as integer -1) (poly.z as integer -1) to stream
    -- Specify vert normals
    if cb_outputVertNorms.checked then
    Format " n % % %" (poly.x as integer -1) (poly.y as integer -1) (poly.z as integer -1) to stream
    -- Tex coord
    if cb_outputTexCoords.checked and meshObj.numTverts > 0 then
    (
    tvert = GetTVFace meshObj i
    Format " t % % %" (tvert.x as integer -1) (tvert.y as integer -1) (tvert.z as integer -1) to stream
    )
    -- Face normal
    if cb_outputPolyNorms.checked then
    (
    normal = GetFaceNormal meshObj i
    Format " N % % %" normal.x normal.y normal.z to stream
    )
    -- Texture ref
    Format " T 0\n" to stream
    )
    )

    Format "\nOBJECT_END %\n" name to stream
    )

    -------------------------------------------------------------------------------------
    -- This function is called once per node in the scene.
    -- A node in Max may be all sorts of things. We are only interested in geometry.
    --
    -- jyl: figuring out if a node is a NURBS surface is pretty tricky, I had to resort to an
    -- ugly string in string search for "Surface"
    -- hopefully in Max 3.0, I can determine the class type better!
    --
    function ExportNode node =
    (
    -- Create node and export class specific data

    local surfaceString = findString node.name "Surface"

    if SuperClassOf node == GeometryClass and surfaceString != undefined then
    (
    nurbSet = getNurbsSet node

    if nurbSet.numObjects > 0 then
    (
    local nurbsObj = getObject nurbSet 1

    if classOf nurbsObj == NURBSCVSurface then
    (
    ExportNURBSCVSurface nurbsObj node.name
    )
    )
    )
    else if SuperClassOf node == GeometryClass and ClassOf node == Editable_mesh then
    ExportMesh node node.name
    else if SuperClassOf node == GeometryClass then
    (
    -- Build a mesh out of this object and save it
    local temp = copy node
    convertToMesh temp
    ExportMesh temp node.name
    delete temp
    )
    else -- Not geometry.. could be a camera, light, etc.
    return false

    return true
    )

    -------------------------------------------------------------------------------------
    -- This function recurses down the node hierarchy calling ExportNode for each node.
    function RecursiveExportNode node =
    (
    if (ExportNode node) == false then
    return false

    -- Recurse children before writing this node
    for child in node.children do
    RecursiveExportNode child
    )
    -------------------------------------------------------------------------------------
    -- Output the RTG file header.
    function OutputHeader =
    (
    Format "OUTPUT_VERT_NORMS " to stream
    if cb_outputVertNorms.checked then ; Format "on\n" to stream
    else Format "off\n" to stream
    Format "OUTPUT_VERT_COLORS " to stream
    if cb_outputVertColors.checked then ; Format "on\n" to stream
    else Format "off\n" to stream
    Format "OUTPUT_POLY_NORMS " to stream
    if cb_outputPolyNorms.checked then ; Format "on\n" to stream
    else Format "off\n" to stream
    Format "OUTPUT_TEX_COORDS " to stream
    if cb_outputTexCoords.checked then ; Format "on\n" to stream
    else Format "off\n" to stream
    Format "OUTPUT_HIERARCHY " to stream
    if cb_outputHierarchy.checked then ; Format "on\n" to stream
    else Format "off\n" to stream

    Format "SHOW_INDEX_COUNTERS on\n" to stream
    Format "TEXTURE_MODE per_shader\n" to stream
    )
    -------------------------------------------------------------------------------------
    -- A helper function to write indentation to the file.
    function doTabs depth =
    (
    for x = 1 to depth do
    (
    Format "\t" to stream
    )
    )
    -------------------------------------------------------------------------------------
    -- A function to output the hierarchical relationship of geometric objects.
    function RecursiveWriteHierarchy node depth =
    (
    -- Write this node
    if SuperClassOf node == GeometryClass then
    (
    -- Geometry info
    doTabs (depth as integer -1)
    Format "% G %\n" depth node.name to stream
    doTabs (depth+1)
    Format "tran: % % %\n" node.pos.x node.pos.y node.pos.z to stream
    doTabs (depth+1)
    rot = node.rotation as eulerangles
    Format "rot: % % %\n" rot.x rot.y rot.z to stream
    doTabs (depth+1)
    Format "scal: % % %\n" node.scale.x node.scale.y node.scale.z to stream
    doTabs (depth+1)
    Format "sPiv: % % %\n" node.pivot.x node.pivot.y node.pivot.z to stream
    doTabs (depth+1)
    Format "rPiv: % % %\n" node.pivot.x node.pivot.y node.pivot.z to stream
    )
    -- Pivot info
    -- Recurse to children
    -- for children in node.children do
    -- RecursiveWriteHierarchy children
    )
    -------------------------------------------------------------------------------------
    -- The highest level function called to export an RTG file.
    function ExportRTG =
    (
    -- Write the RTG header
    Format "HEADER_TITLE\t\tMax 2.5 Real Time Game Output\n" to stream
    Format "HEADER_VERSION\t\tv1.8\n" to stream
    Format ("HEADER_DATE \t\t" + localtime + "\n") to stream
    Format "\n\n" to stream

    if cb_exportSelOnly.checked then
    (
    Format "NUMBER_OF_OBJECTS = %\n" selection.count to stream
    OutputHeader()

    for node in selection do
    ExportNode node
    )
    else
    (
    Format "NUMBER_OF_OBJECTS = %\n" rootnode.children.count to stream
    OutputHeader()

    if cb_outputHierarchy.checked then
    (
    Format "\nHIERARCHY_LIST HXP 1 top_level\n\n" to stream

    for node in rootnode.children do
    RecursiveWriteHierarchy node 0

    Format "END_HIERARCHY_LIST\n\n" to stream
    )

    for node in rootnode.children do
    RecursiveExportNode node
    )
    )
    -------------------------------------------------------------------------------------
    -- Open an prepare a file handle for writing.
    function GetSaveFileStream =
    (
    fname = GetSaveFileName types:"Alias RTG (*.rtg)|*.rtg|All Files(*.*)|*.*|"
    if fname == undefined then
    return undefined

    ostream = CreateFile fname
    if ostream == undefined then
    (
    MessageBox "Couldn't open file for writing !"
    return undefined
    )

    return ostream
    )

    -------------------------------------------------------------------------------------
    -- This is the function called when the user activates the utility by pressing on
    -- the export button. It opens the file and calls the export routine.
    on btn_export pressed do
    (
    ostream = GetSaveFileStream()
    if ostream != undefined then
    (
    ExportRTG()
    close ostream
    )
    )

    ) -- End RTGExport

  4. #4
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Seattle, WA USA
    Posts
    4

    Re: Extracting cubic beziers from .OBJ files

    opps, please convert the wierd smiley ; graphics to semi-colons!

    -joseph

  5. #5
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Seattle, WA USA
    Posts
    4

    Re: Extracting cubic beziers from .OBJ files

    make that colons!

    : to colons (i'm really sorry about this)

  6. #6
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Rochester, NY, USA
    Posts
    9

    Re: Extracting cubic beziers from .OBJ files

    Wow, thanks for the code Joseph. I changed all the faces into ':' and saves the file with a .ms extension. The only problem is that when I load up 3dsmax 3 and try to load the script nothing happens. I don't get any errors, but I also don't get any extra options under "save as" or "export". I have no experience with Max Script, so I have no idea what could be wrong. You wouldn't, by any chance, have any pointer on what I might have done wrong would you?

    -Daedalus

  7. #7
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Rochester, NY, USA
    Posts
    9

    Re: Extracting cubic beziers from .OBJ files

    well, I think I might have found the problem. It looks as thought the face art erased more than just a ':'

    test:

    :-o


    I'm trying to figure out exactly what set of characters is missing.

    -Daedalus

  8. #8
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Seattle, WA USA
    Posts
    4

    Re: Extracting cubic beziers from .OBJ files

    I made a link to the original script with instructions on how to intall it on my web site.
    http://209.181.143.70/docs/NURBs.htm

    -joseph

  9. #9
    Junior Member Newbie
    Join Date
    Feb 2000
    Location
    Rochester, NY, USA
    Posts
    9

    Re: Extracting cubic beziers from .OBJ files

    Thanks a lot Joseph. I finally managed to get the script working. You were right about the .RTG file format too. It is easy to understand. I spent a while, before I got the script working, looking for the file format documentation on the net and couldn't find it anywhere. Luckily I didn't need it.

    -Daedalus

  10. #10

    Re: Extracting cubic beziers from .OBJ files

    This is off topic but you should read this about ubb...
    http://www.opengl.org/discussion_boards/ubb/faq.html


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •