Polygon Crucher SDK - Documentation
Documentation
Loading...
Searching...
No Matches

Every faces is an index array (of at least 3 indexes) that refers to another list (usually points or vectors).
Faces are gather together in a CFaceList, which is in fact an array of array.
CFaceList is the common base class for a lot of different classes (C3DFaceList, CUVWFaceList...)

In the SDK, faces are stored in a single memory block in a compact way. The advantage is the simplicity, but we need to be careful about how we create or modify faces to maintain good performance and avoid time-consuming memory allocations.

You can associates your own data type to faces using CFaceList::AddDataChunk / CFaceList::GetDataChunk.
Data chunks are somewhat similar to CChannel except that chunks are really tied to the face, which can be easier to make data follow during face operations.

Retrieve face indexes

int facesize = faces->GetSize(); // we assumes faces is a C3DFaceList
for (int i=0; i<facesize; i++)
{
int indexsize, *facedata = faces->GetIndexes(i, indexsize);
for (int j=0;j<indexsize; j++)
sprintf(txt, "%d face index #%d is %d\n", i, j, facedata[j]);
}
The class defines an x, y, z 3D point which can use int, float or double.
Definition 3DPoint.h:27

We can do the same using a C3DFace.

C3DFace face;
int facesize = faces->GetSize(); // we assumes faces is a C3DFaceList
for (int i=0; i<facesize; i++)
{
faces->GetFace(i, face);
int size;
int *facedata = face.GetData(size);
for (int j=0;j<size; j++)
sprintf(txt, "%d face index #%d is %d\n", i, j, facedata[j]);
}
A 3D face is a list of indexes of C3DPointList object point list.
Definition 3DFace.h:43

Creating faces

We usually have an idea on the faces size, when creating them.
This is important to properly initialized the faces list with the appropriate sizes to avoid memory reallocation.

In this sample we have 50 triangles and 50 quads. We initialize 100 faces with quads, so allocation will also be ok for triangles.

C3DFaceList *faces = xNew(C3DFaceList);
faces->SetSize(100, 4); // This creates 100 quadrangular faces. Some faces can have different sizes (ie triangular) using CFace::SetSize
C3DFace face;
for (int i=0; i<100; i++)
{
faces->GetFace(i, face);
int faceIndexCount = i%2 ? 3 : 4; // even face are triangular, odd are quadrangular, for the sample purpose
for (int j=0;j<faceIndexCount; j++)
facedata[j] = ... // An index value in the C3DPointList array
}
// We have quads and tris, but we init faces with quads, so we allocates more memory than needed. This will release this extra memory.
// Calling FreeExtra is a good habit after creating faces
faces->FreeExtra();
C3DFaceList class which implement a list of C3DFace. Each face contains indexes to 3D points stored i...
Definition 3DFaceList.h:249
int * SetSize(int size, FACE_PROPERTIES invalidFlag=FACE_IS_INVALID)
Set the number of indexes for the face. If size < 3, then invalidFlag flag is set,...
Definition Face.h:222
void SetSize(int size, SetSizeMode sizeMode, int defaultFaceSize=FACELIST_DEFAULT_INDEX_NBR)
Resize the size of the number of face. If growOnly, memory is not reallocated if buffer's size decrea...

When importing the faces from an external files, we usually can collect each face size and allocates accordingly. Here we allocates 4 faces with different sizes.

int faceIndexSize[4] = {3, 4, 6, 3};
C3DFaceList* faces = xNew(C3DFaceList);
faces->SetSize(4, faceIndexSize); // Allocates 4 faces with different index sizes
// now we can fill our faces
for (int i=0; i<4; i++)
{
int size, *facedata = faces->GetIndexes(i, indexsize);
for (int j=0;j<size; j++)
facedata[j] = ... // An index value in the C3DPointList array

Sometime not all imported faces are valid. In this sample, we imagine some inputData with quadrangular faces, but only some are valids.

C3DFaceList* faces = xNew(C3DFaceList);
faces->SetSize(inputDataSize, 4); // Allocate inputDataSize quad faces
faces->SetFacesFlags(FACE_IS_INVALID, true); // All face are set to invalid
int curface = 0;
C3DFace face;
for (int i=0; i<inputDataSize; i++)
{
if (inputData[i].isValid) // the input face is valid
{
faces->SetFaceFlags(curface, FACE_IS_INVALID, false); // This face is valid
int size, *facedata = faces->GetIndexes(curface, indexsize);
for (int j=0;j<size; j++)
curface++;
}
}
faces->Clean(); // This will remove any remaining faces with FACE_IS_INVALID flag set and free extra memory
@ FACE_IS_INVALID
This flag is used when a face a less than 3 indexes or when it is tagged invalid. Geometric faces tha...
Definition Face.h:43
bool Clean(const CGeomInfo *info)
Clean faces with FACE_IS_INVALID status defined.

We can also use CFaceList::Preallocate when the really don't know what are the input face, because the process to get info on them is is time-consuming. In this case we can use CFaceList::Preallocate prepares memory only. And we can fill it, face by face, getting each final face information one by one.

faces->PreAllocate(inputDataSize, inputDataSize*4); // inputDataSize*4 is the estimated total index count
// Note that here faces->GetSize() = 0, this is preallocation!
int curface = 0;
C3DFace face;
for (int i=0; i<inputDataSize; i++)
{
if (inputData[i].isValid) // the input face is valid
{
int inputDataFaceSize, *inputDataIndexes = PrepareInputFace(&inputData[i], inputFaceSize); // Get information about input face
faces->SetSize(curface+1, CFaceList::GROW_MODE, inputDataFaceSize); // We add inputDataFaceSize indexes. Using CFaceList::GROW_MODE is important to reallocate memory and shrink it down (we allocate inputDataSize, and we only have curface right now)
// Note that here faces->GetSize() = curface+1
faces->GetFace(curface, face);
for (int j=0;j<inputDataFaceSize; j++)
curface++;
}
}
faces->FreeExtra();
void PreAllocate(int estimatedFaceNbr, int estimatedIndexNbr, bool constructAllElementsOnce=false)
Preallocate the data with an estimated face nbr and total indexes count for the whole face set....