Inside Sabertooth
Learn how Sabertooth uses 3ds Max to create 3D interactive projects, including HBO Go’s Game of Thrones interactive experience
  • 1/3
You are here: Forum Home / Autodesk® FBX® / FBX SDK / Sample for KFbxTrimNurbsSurface
  RSS 2.0 ATOM  

Sample for KFbxTrimNurbsSurface
Rate this thread
 
44138
 
Permlink of this thread  
avatar
  • Paddi
  • Posted: 09 June 2010 10:03 AM
  • Total Posts: 2
  • Joined: 09 June 2010 04:53 PM

Hi all,

I’m a newbie with FBX. I want to convert NURBS geometries to FBX. If I tesselate the geometries and add meshes everything works. Now I want to use KFbxTrimNurbsSurface.

Creating is easy:

KFbxTrimNurbsSurface* result = KFbxTrimNurbsSurface::Create(m_pScene,tnurbsname.str().c_str())

But how do I add a surface?


KFbxNurbsSurface* pSurface = KFbxNurbsSurface::Create(m_pScene,colName.c_str())
result->SetNurbsSurface(pSurface)

If I try to do it this I get errors on cleanup:

MFC_OCAFD.exe!fbxsdk_2011_2::FbxSdkFree() + 0x77 Bytes C++
MFC_OCAFD.exe!FbxSdkDeleteArray<double>() + 0x73 Bytes C++
MFC_OCAFD.exe!fbxsdk_2011_2::KFbxNurbsSurface::Reset() + 0x34 Bytes C++
MFC_OCAFD.exe!fbxsdk_2011_2::KFbxNurbsSurface::Destruct() + 0x36 Bytes C++
MFC_OCAFD.exe!fbxsdk_2011_2::KFbxPlug::Destroy() + 0x79 Bytes C++
MFC_OCAFD.exe!fbxsdk_2011_2::KFbxObject::Destruct() + 0xd4 Bytes C++
MFC_OCAFD.exe!fbxsdk_2011_2::KFbxDocument::Destruct() + 0x94 Bytes C++
MFC_OCAFD.exe!fbxsdk_2011_2::KFbxScene::Destruct() + 0x111 Bytes C++
MFC_OCAFD.exe!fbxsdk_2011_2::KFbxPlug::Destroy() + 0x79 Bytes C++

A code sample or at least an FBX file containing a trimmed surface would be nice.

Best regards,

Paddi



Replies: 0
avatar
  • nian.wu
  • Posted: 10 June 2010 03:25 PM

Did your program crash when do cleanup? Please check whether you set the KFbxNurbsSurface::mUKnotVector and mVKnotVector correct. You don’t need to alloc memory for them by yourself. KFbxNurbsSurface::InitControlPoints() will alloc memory for them.
The example code may be useful for you:

KFbxNurbsSurfacelFGeometryNurb KFbxNurbsSurface::Create(mFbxSdkManager,"")
    
    lFGeometryNurb
->SetOrder( lUOrderlVOrder )
    lFGeometryNurb
->InitControlPoints( lFbxCVsUlFbxTypeUlFbxCVsVlFbxTypeV )

    lFGeometryNurb
->SetStep( 33 )
// copy the knot vectors
    
doublelFbxKnotVector lFGeometryNurb->GetUKnotVector()
    for( i 
0lFGeometryNurb->GetUKnotCount() ; ++i)
    {
        lFbxKnotVector[i] 
your U Knot Data;
    
}
    
    for( i 
0lFGeometryNurb->GetVKnotVector() ++i)
    {
        lFbxKnotVector[i] 
your V Knot Data;
    
}
    
    
// copy the CVs
    
KFbxVector4lFVertexArray lFGeometryNurb->GetControlPoints ()

    
// Fbx CVs:
    //
    //    x x x 
    // V  x x x  
    //    x x x 
    //      
    //      U
    //
    
for( i 0lFGeometryNurb->GetUCount() ; ++i )
    {
        for( j 
0lFGeometryNurb->GetVCount() ; ++j )
        {
            lFVertexArray[ (lFGeometryNurb
->GetUCount() j) i] your CV data;    
        
}
    }

   KFbxTrimNurbsSurface
lTrimSurf NULL;
   
lTrimSurf KFbxTrimNurbsSurface::Create(&mFbxSdkManager,"")
   lTrimSurf
->SetNurbsSurface( lFGeometryNurb )

   KArrayTemplate
<KFbxBoundary*> lBoundaries;
   
// set up boundaries of trim curve here 
   
....

   
// add one trim rigion here, the outer boundary should be the first boundary
   
lTrimSurf->BeginTrimRegion()
            for( int i 
0lBoundaries.GetCount() ++i )
            {
                lTrimSurf
->AddBoundary( lBoundaries[i] )            
            }

            lTrimSurf
->EndTrimRegion()


Nian Wu
AutoDesk FBX Team

Replies: 2
/img/forum/dark/default_avatar.png

Hi Nian,

I’m also having trouble getting KFbxTrimNurbsSurfaces save to my file.  Here’s the function I’m using and a snippet of the code that calls it. 

KFbxTrimNurbsSurface* CFBXExporter::ConvertTrimmedNurbsSurface(KFbxNode* pRootNode, const ON_Brep* pBrep, const int& faceidx)
{
if (0 == pBrep || 0 > faceidx || pBrep->m_F.Count() <= faceidx)
return 0;

KFbxTrimNurbsSurface* pFBXtrimsurf = KFbxTrimNurbsSurface::Create(m_pSdkManager, “");
if (0 == pFBXtrimsurf)
return 0;

const ON_BrepFace& face = pBrep->m_F[faceidx];

ON_NurbsSurface surf;
if (0 == pBrep->m_F[faceidx].GetNurbForm(surf))
return 0;

KFbxNurbsSurface* pFBXSurf = ConvertNurbsSurface(surf);
if (0 == pFBXSurf)
return 0;

ON_String surfname;
surfname.Format("Test_Surf");

KFbxNode* pFbxNode = KFbxNode::Create(m_pSdkManager, surfname.Array());
if (0 == pFbxNode)
return 0;

pFbxNode->AddNodeAttribute(pFBXSurf);
pRootNode->AddChild(pFbxNode);

pFBXtrimsurf->SetNurbsSurface(pFBXSurf);

int l, loopct = face.LoopCount();
int t, trimct;
ON_SimpleArray <KFbxBoundary*> FBXboundaryArray;
for (l=0; loopct > l; l++)
{
KFbxBoundary* pFBXboundary = KFbxBoundary::Create(m_pSdkManager, “");
if (0 == pFBXboundary)
return 0;

const ON_BrepLoop& loop = pBrep->m_L[l];
if (ON_BrepLoop::outer == loop.m_type)
pFBXboundary->OuterFlag.Set(true);
else
pFBXboundary->OuterFlag.Set(false);

trimct = loop.TrimCount();
for(t=0; trimct > t; t++)
{
ON_NurbsCurve trimcurve;
if (0 != pBrep->m_T[loop.m_ti[t]].ProxyCurve())
pBrep->m_T[loop.m_ti[t]].ProxyCurve()->GetNurbForm(trimcurve, 0.0, &pBrep->m_T[loop.m_ti[t]].ProxyCurveDomain());

KFbxNurbsCurve* pFBXCrv = ConvertNurbsCurve(trimcurve);
if (0 == pFBXCrv)
return 0;

ON_String crvname;
crvname.Format("Test_Loop_%d_Curve_%d", l, t);
pFbxNode = KFbxNode::Create(m_pSdkManager, crvname.Array());
if (0 == pFbxNode)
return 0;

pFbxNode->AddNodeAttribute(pFBXCrv);
pRootNode->AddChild(pFbxNode);

pFBXboundary->AddCurve(pFBXCrv);
}

pFbxNode = KFbxNode::Create(m_pSdkManager, 0);
if (0 == pFbxNode)
return 0;

ON_String loopname;
loopname.Format("Test_Loop_%d", l);
pFbxNode->AddNodeAttribute(pFBXboundary);
FBXboundaryArray.Append(pFBXboundary);

pRootNode->AddChild(pFbxNode);
}

pFBXtrimsurf->BeginTrimRegion();
loopct = FBXboundaryArray.Count();
for (l=0; loopct > l; l++)
pFBXtrimsurf->AddBoundary(FBXboundaryArray[l]);
pFBXtrimsurf->EndTrimRegion();

return pFBXtrimsurf;
}

KFbxTrimNurbsSurface* pFBXTrimSurf = ConvertTrimmedNurbsSurface(pRootNode, pBrep, i);
if (0 == pFBXTrimSurf)
return false;

ON_String trimsrfname;
trimsrfname.Format("Test_TrimSrf");
KFbxNode* pFbxNode = KFbxNode::Create(m_pSdkManager, trimsrfname.Array());
if (0 == pFbxNode)
return false;

pFbxNode->AddNodeAttribute(pFBXTrimSurf);
pRootNode->AddChild(pFbxNode);

The functions that create the KFbxNurbsSurface and the KFbxNurbsCurve work fine (I get good curves and surfaces in the file, I can post the code to those if you think it makes a difference.  I see the surface, trim curves and boundary(ies) in the file but the node labeled Test_TrimSrf shows up as a null node and it only shows up in the connections linking it to the root node.  Can you help me figure out what I might be doing wrong.  Thanks.

Tim

Author: TimHemmelman

Replied: 27 October 2010 11:19 AM  
/img/forum/dark/default_avatar.png

Hi Nian,

Thanks for the example.  I figured it out.  But I haven’t figured out how to use your forum properly.

Tim

Author: TimHemmelman

Replied: 27 October 2010 12:05 PM  
avatar
  • Paddi
  • Posted: 13 June 2010 05:56 AM

nian.wu 10 June 2010 10:25 PM

Did your program crash when do cleanup? Please check whether you set the KFbxNurbsSurface::mUKnotVector and mVKnotVector correct. You don’t need to alloc memory for them by yourself. KFbxNurbsSurface::InitControlPoints() will alloc memory for them.
The example code may be useful for you:

KFbxNurbsSurfacelFGeometryNurb KFbxNurbsSurface::Create(mFbxSdkManager,"")
    
    lFGeometryNurb
->SetOrder( lUOrderlVOrder )
    lFGeometryNurb
->InitControlPoints( lFbxCVsUlFbxTypeUlFbxCVsVlFbxTypeV )

    lFGeometryNurb
->SetStep( 33 )
// copy the knot vectors
    
doublelFbxKnotVector lFGeometryNurb->GetUKnotVector()
    for( i 
0lFGeometryNurb->GetUKnotCount() ; ++i)
    {
        lFbxKnotVector[i] 
your U Knot Data;
    
}
    
    for( i 
0lFGeometryNurb->GetVKnotVector() ++i)
    {
        lFbxKnotVector[i] 
your V Knot Data;
    
}
    
    
// copy the CVs
    
KFbxVector4lFVertexArray lFGeometryNurb->GetControlPoints ()

    
// Fbx CVs:
    //
    //    x x x 
    // V  x x x  
    //    x x x 
    //      
    //      U
    //
    
for( i 0lFGeometryNurb->GetUCount() ; ++i )
    {
        for( j 
0lFGeometryNurb->GetVCount() ; ++j )
        {
            lFVertexArray[ (lFGeometryNurb
->GetUCount() j) i] your CV data;    
        
}
    }

   KFbxTrimNurbsSurface
lTrimSurf NULL;
   
lTrimSurf KFbxTrimNurbsSurface::Create(&mFbxSdkManager,"")
   lTrimSurf
->SetNurbsSurface( lFGeometryNurb )

   KArrayTemplate
<KFbxBoundary*> lBoundaries;
   
// set up boundaries of trim curve here 
   
....

   
// add one trim rigion here, the outer boundary should be the first boundary
   
lTrimSurf->BeginTrimRegion()
            for( int i 
0lBoundaries.GetCount() ++i )
            {
                lTrimSurf
->AddBoundary( lBoundaries[i] )            
            }

            lTrimSurf
->EndTrimRegion()

Hi Nian,

InitControlPoints was the right tip! Now I can continue writing my exporter.

Thanks for the help!

Best regards,

Patrik



Replies: 0