bool WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs)
{
	unsigned int vsize = ifs.vsize();
	unsigned int nsize = ifs.nsize();
	//soc unused - unsigned	tsize = ifs.tsize();

	const real *vertices = ifs.vertices();
	const real *normals = ifs.normals();
	const real *texCoords = ifs.texCoords();

	real *new_vertices;
	real *new_normals;

	new_vertices = new real[vsize];
	new_normals = new real[nsize];

	// transform coordinates from local to world system
	if (_current_matrix) {
		transformVertices(vertices, vsize, *_current_matrix, new_vertices);
		transformNormals(normals, nsize, *_current_matrix, new_normals);
	}
	else {
		memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices));
		memcpy(new_normals, normals, nsize * sizeof(*new_normals));
	}

	const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle();

	vector<FrsMaterial> frs_materials;
	if (ifs.msize()) {
		const FrsMaterial *const *mats = ifs.frs_materials();
		for (unsigned i = 0; i < ifs.msize(); ++i)
			frs_materials.push_back(*(mats[i]));
		shape.setFrsMaterials(frs_materials);
	}

#if 0
	const FrsMaterial *mat = (ifs.frs_material());
	if (mat)
		shape.setFrsMaterial(*mat);
	else if (_current_frs_material)
		shape.setFrsMaterial(*_current_frs_material);
#endif
	const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks();

	// sets the current WShape to shape
	_current_wshape = &shape;

	// create a WVertex for each vertex
	buildWVertices(shape, new_vertices, vsize);

	const unsigned int *vindices = ifs.vindices();
	const unsigned int *nindices = ifs.nindices();
	const unsigned int *tindices = NULL;
	if (ifs.tsize()) {
		tindices = ifs.tindices();
	}

	const unsigned int *mindices = NULL;
	if (ifs.msize())
		mindices = ifs.mindices();
	const unsigned int *numVertexPerFace = ifs.numVertexPerFaces();
	const unsigned int numfaces = ifs.numFaces();

	for (unsigned int index = 0; index < numfaces; index++) {
		switch (faceStyle[index]) {
			case IndexedFaceSet::TRIANGLE_STRIP:
				buildTriangleStrip(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
				                   nindices, mindices, tindices, numVertexPerFace[index]);
				break;
			case IndexedFaceSet::TRIANGLE_FAN:
				buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
				                 nindices, mindices, tindices, numVertexPerFace[index]);
				break;
			case IndexedFaceSet::TRIANGLES:
				buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices,
				               nindices, mindices, tindices, numVertexPerFace[index]);
				break;
		}
		vindices += numVertexPerFace[index];
		nindices += numVertexPerFace[index];
		if (mindices)
			mindices += numVertexPerFace[index];
		if (tindices)
			tindices += numVertexPerFace[index];
		faceEdgeMarks++;
	}

	delete[] new_vertices;
	delete[] new_normals;

	if (shape.GetFaceList().size() == 0) // this may happen due to degenerate triangles
		return false;

	// compute bbox
	shape.ComputeBBox();
	// compute mean edge size:
	shape.ComputeMeanEdgeSize();

	// Parse the built winged-edge shape to update post-flags
	set<Vec3r> normalsSet;
	vector<WVertex *>& wvertices = shape.getVertexList();
	for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) {
		if ((*wv)->isBoundary())
			continue;
		if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.)
			continue;
		normalsSet.clear();
		WVertex::face_iterator fit = (*wv)->faces_begin();
		WVertex::face_iterator fitend = (*wv)->faces_end();
		for (; fit != fitend; ++fit) {
			WFace *face = *fit;
			normalsSet.insert(face->GetVertexNormal(*wv));
			if (normalsSet.size() != 1) {
				break;
			}
		}
		if (normalsSet.size() != 1) {
			(*wv)->setSmooth(false);
		}
	}

	// Adds the new WShape to the WingedEdge structure
	_winged_edge->addWShape(&shape);

	return true;
}
IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet& iBrother) : Rep(iBrother)
{
	_VSize = iBrother.vsize();
	_Vertices = new float[_VSize];
	memcpy(_Vertices, iBrother.vertices(), _VSize * sizeof(float));

	_NSize = iBrother.nsize();
	_Normals = new float[_NSize];
	memcpy(_Normals, iBrother.normals(), _NSize * sizeof(float));

	_MSize = iBrother.msize();
	if (_MSize) {
		_FrsMaterials = new FrsMaterial * [_MSize];
		for (unsigned int i = 0; i < _MSize; ++i) {
			_FrsMaterials[i] = new FrsMaterial(*(iBrother._FrsMaterials[i]));
		}
	}
	else {
		_FrsMaterials = 0;
	}

	_TSize = iBrother.tsize();
	_TexCoords = 0;
	if (_TSize) {
		_TexCoords = new float[_TSize];
		memcpy(_TexCoords, iBrother.texCoords(), _TSize * sizeof(float));
	}

	_NumFaces = iBrother.numFaces();
	_NumVertexPerFace = new unsigned[_NumFaces];
	memcpy(_NumVertexPerFace, iBrother.numVertexPerFaces(), _NumFaces * sizeof(unsigned));

	_FaceStyle = new TRIANGLES_STYLE[_NumFaces];
	memcpy(_FaceStyle, iBrother.trianglesStyle(), _NumFaces * sizeof(TRIANGLES_STYLE));

	_FaceEdgeMarks = new FaceEdgeMark[_NumFaces];
	memcpy(_FaceEdgeMarks, iBrother.faceEdgeMarks(), _NumFaces * sizeof(FaceEdgeMark));

	_VISize = iBrother.visize();
	_VIndices = new unsigned[_VISize];
	memcpy(_VIndices, iBrother.vindices(), _VISize * sizeof(unsigned));

	_NISize = iBrother.nisize();
	_NIndices = new unsigned[_NISize];
	memcpy(_NIndices, iBrother.nindices(), _NISize * sizeof(unsigned));

	_MISize = iBrother.misize();
	if (_MISize) {
		_MIndices = new unsigned[_MISize];
		memcpy(_MIndices, iBrother.mindices(), _MISize * sizeof(unsigned));
	}
	else {
		_MIndices = 0;
	}

	_TISize = iBrother.tisize();
	_TIndices = 0;
	if (_TISize) {
		_TIndices = new unsigned[_TISize];
		memcpy(_TIndices, iBrother.tindices(), _TISize * sizeof(unsigned));
	}

	_displayList = 0;
}