PDA

View Full Version : FTk semantic layer question(s)


photex
04-18-2008, 12:33 PM
Hello,

I'm working on a plugin for another app that will export dotXSI files (I guess that's obvious). In the past I was constructing the templates myself, but I'm trying to start using the FTk/Crosswalk SDK to have options to the version of XSI files created and so on.
Anyway, So, I'm iterating over a scene and stopping at every mesh. Once I get to a mesh I'm quickly and totally baffled how I'm actually supposed to construct a mesh. Here is my current train of thought:

model = XSIRoot->AddXSIMesh();
mesh = model->Primitive();
shape = mesh->XSIShape();

vertexposlist = shape->AddVertexPositionList();
posarray = vertexposlist->GetAttributeArray();
posarray->Extend([insert count from scene]);
// proceed to add point positions to the array from the scene
// rinse repeat for other attributes such as UVs, vert colors, etc?

polygonlist = mesh->AddXSIPolygonList();
polygonlist->SetCount([insert count from scene]);

It's at this point I'm not sure what I'm doing.... no wait, it's from the very start I'm not sure what I'm doing! :)
So CSLXSIPolygonList::GetPolygonNodeCountArray() returns an array of integers that is 1 per polygon in length and the value of each element in the array is the number of vertices for that polygon? And then GetVertexIndices returns what? The indices for all polys in one array or is there a separate array of indices for each poly?
When I've had to construct this by hand the polygon indices also gave the index per vert into the arrays of more than one attribute list. Does this just happen automatically is the xsi shape object has multiple attribute lists?

Thanks.

ajclaude
04-18-2008, 03:15 PM
You can check how to use the FTK semantic layer by looking at the dotXSIConverter source code provided with the Crosswalk SDK.

photex
04-18-2008, 04:48 PM
Yep, I'm digging around in there. I was just hoping that someone would be able to help me with an outline of the process. I'm new to the FTk is all and that is a TON of extra stuff to look through to learn the basics.

I can't even seem to get CSLScene::Root() to return a valid CSLModel pointer yet. I'm getting access violations when I try to AddXSIMesh() or anything else for that matter.

ChristopherC
04-19-2008, 08:07 AM
Hello,

to start working on a new session of a Crosswalk scene and get valid pointers to the semantic layer objects as the root, you have to first create a new CSLScene object and then call the 'CSLScene::Create' method to initialize the SL layer.

CSLScene slScene;
slScene.Create(fileName, 6, 0, FORMAT_TEXT);


Then for adding a new polygon mesh to Crosswalk, here is a sample code with comments that is entirely based on the dotXSIConverter example, but that is a little more easier to understand, I guess.
The code is a bit old but it should work fine.

// This sample needs that you already retrieved the material libraries to Crosswalk with some user data pointing to the CRef materials.


CSLModel* pCSLParent = nullptr; //< Assume this is a valid parent for the new polygon mesh model.
X3DObject xsiObj; //< Assume this is a valid X3DObject of type polygon mesh.



// Get some XSI stuff.
PolygonMesh xsiPolyMesh = (PolygonMesh)xsiObj.GetActivePrimitive().GetGeomet ry();
CGeometryAccessor xsiGeometryAccessor = xsiPolyMesh.GetGeometryAccessor(siConstructionMode Modeling, siCatmullClark, 0, false, true, 60.0);

// Initialize some Crosswalk stuff.

CSLModel* pCSLNewModel = pCSLParent->AddXSIMesh();
CSLXSIMesh* pCSLXSIMesh = (CSLXSIMesh*)pCSLNewModel->Primitive();
CSLXSIShape* pCSLXSIShape = pCSLXSIMesh->XSIShape();




// Here we go !!
// Vertices positions.
LONG nVertices = xsiGeometryAccessor.GetVertexCount();
CSLXSISubComponentAttributeList* pCSLVertexPositionList = pCSLXSIShape->AddVertexPositionList();
pCSLVertexPositionList->Template()->InstanceName().SetText("position");

CSLXSISubComponentAttributeList::CSLFloatArray* pCSLVertexAttrPositionArray = pCSLVertexPositionList->GetAttributeArray();
pCSLVertexAttrPositionArray->Extend(nVertices*3);

CDoubleArray xsiPositionArray;
xsiGeometryAccessor.GetVertexPositions(xsiPosition Array);

for (LONG i = 0; i < nVertices*3; ++i)
{
(*pCSLVertexAttrPositionArray)[i] = (float)xsiPositionArray[i];
}


// Vertices list.
CSLXSIVertexList* pCSLXSIVertexList = pCSLXSIMesh->XSIVertexList();
pCSLXSIVertexList->SetCount(nVertices);
pCSLXSIVertexList->AddAttribute("position");

for (LONG i = 0; i < pCSLXSIVertexList->GetAttributeCount(); ++i)
{
CSLXSISubComponentList::CSLIntArray* pCSLAttributeIndices = pCSLXSIVertexList->GetAttributeIndices(i);

for (LONG j = 0; j < nVertices; ++j)
{
(*pCSLAttributeIndices)[j] = j;
}
}


// Polygons list.
LONG nPolygons = xsiGeometryAccessor.GetPolygonCount(); // Total polygon count.
CLongArray polygonVertexs; //< Vertex count for each polygon.
CLongArray polygonVertexIndices; //< Vertex indices for each polygon. Format: {poly0<v0,v1..vN>, poly1<v0,v1..vN>... polyN<v0,v1..vN>}
CLongArray polygonNodeIndices; //< Node indices for each polygon. Format: {poly0<n0,n1..nN>, poly1<n0,n1..nN>... polyN<n0,n1..nN>}

xsiGeometryAccessor.GetPolygonVerticesCount(polygo nVertexs);
xsiGeometryAccessor.GetVertexIndices(polygonVertex Indices);
xsiGeometryAccessor.GetNodeIndices(polygonNodeIndi ces);

if (nPolygons > 0)
{
// Must set a material for the polygon list in order to work with COLLADA.
// Retrieve the material in the crosswalk material library.
Material xsiMaterial = xsiObj.GetMaterial();
CSLBaseMaterial* pCSLBaseMaterial = nullptr;

CSLMaterialLibrary* pCSLMaterialLibrary = in_pContext->cslScene()->GetMaterialLibrary();
for (LONG i = 0; i < pCSLMaterialLibrary->GetMaterialCount(); ++i)
{
CSIBCUserData* pSIBCUserData = pCSLMaterialLibrary->GetMaterialList()[i]->FindUserData("CREF");

if (pSIBCUserData != nullptr)
{
CRef* xsiRef = (CRef*)(pSIBCUserData->GetData());
Material xsiMaterialFromCrosswalk = (Material)*xsiRef;

if (xsiMaterial == xsiMaterialFromCrosswalk)
{
pCSLBaseMaterial = pCSLMaterialLibrary->GetMaterialList()[i];
break;
}
}
}

CSLXSIPolygonList* pCSLPolygonList = pCSLXSIMesh->AddXSIPolygonList();
pCSLPolygonList->SetName("PolyList00");
pCSLPolygonList->SetCount(xsiGeometryAccessor.GetNodeCount());
pCSLPolygonList->SetMaterial(pCSLBaseMaterial);

CSLXSIPolygonList::CSLIntArray* pPolyNodeCountArray = pCSLPolygonList->GetPolygonNodeCountArray();
pPolyNodeCountArray->Extend(nPolygons);


// Set the node counts and ids.
CSLXSIPolygonList::CSLIntArray* pCSLPolyNodeVertexIndices = pCSLPolygonList->GetVertexIndices();
LONG currentNode = 0;

for (LONG i = 0; i < nPolygons; ++i)
{
// Define the vertices count for each polygon.
(*pPolyNodeCountArray)[i] = polygonVertexs[i];

for (LONG j = 0; j < polygonVertexs[i]; ++j)
{
// Define the vertex indices for each polynode.
(*pCSLPolyNodeVertexIndices)[currentNode] = polygonVertexIndices[currentNode];

++currentNode;
}
}
}


Hope it helps,
Christopher.

photex
04-19-2008, 10:31 AM
Thank you very much for the code sample.

As I feared the only steps needed to get started are to create a new CSLScene object and call the create method to open a new file from scratch. I get a file with the header line in it after each time I try to run the exporter, so I figured that part was working.

Problem is that this doesn't seem to work for me... or for the SLTests project either. In my case I get access violations when I call mXSIScene->Root()->AddXSIMesh(), which in my code is the first time I try to access the CSLScene objects m_pRoot member, which when viewed in a debugger is listed as a pointer to 0x00000000 just like the rest of the scene objects members.
In the SLTests example it gets a violation when creating a new file once it calls FillModel for the first time and it bails when it calls if (NULL == in_pModel->GetGlobalMaterial()).

ChristopherC
04-19-2008, 11:50 PM
I don't have any C++ environment there to check what I say, and I didn't wrote a line with the Crosswalk SDK for a long time, so I could be wrong but I don't remember that you need more code to access the root than the two lines I pasted in the previous post.

Perhaps do you have an incompatibility with your system ? On my side, I was working with Win32 and Visual Studio 2005 express (or 2003, not sure).

photex
04-20-2008, 12:58 AM
I'm developing on x64 but I'm building a win32 dll. Using VC++ 2005

I stopped getting the access violation just a second ago, but the problem still alludes me. I feel it could return. The biggest thing I wanted to make sure of was that I wasn't doing anything fiendishly incorrectly.

I looked over the source provided for the the framework I'm using to write my exporter. You inherit from a saver class and provide the primary Save function and the Open and Close functions for the file. In my case I'm creating an FTk scene in the Open function and in the Close function I'm calling CSLScene::Write,Close. I was getting the access violation in my Save function where every time my scan of the scene I'm exporting found a mesh I would call AddXSIMesh. So after looking over the source of the saver parent class I saw that it was actually calling the virtual Save function twice. I don't know why, and it was calling the Open function before both calls to the save function, but once I tested whether this was the first or second call to Save I stopped getting the violation.

Anyway, I'm tacking my problems up to C++ voodoo. :) Thanks for helping me get the bigger picture here. I've got my basic geometry exporting now.