void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs)
{
	if (_pRenderMonitor && _pRenderMonitor->testBreak())
		return;
	WShape *shape = new WShape;
	if (!buildWShape(*shape, ifs)) {
		delete shape;
		return;
	}
	shape->setId(ifs.getId().getFirst());
	//ifs.setId(shape->GetId());
}
Beispiel #2
0
void WXEdgeBuilder::buildWVertices(WShape& shape, const float *vertices, unsigned vsize)
{
	WXVertex *vertex;
	for (unsigned int i = 0; i < vsize; i += 3) {
		vertex = new WXVertex(Vec3f(vertices[i], vertices[i + 1], vertices[i + 2]));
		vertex->setId(i / 3);
		shape.AddVertex(vertex);
	}
}
void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>&  iMaterials,
                                       const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
                                       const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
                                       const unsigned *tindices, const unsigned nvertices)
{
	WShape *currentShape = _current_wshape; // the current shape begin built
	vector<WVertex *> triangleVertices;
	vector<Vec3r> triangleNormals;
	vector<Vec2r> triangleTexCoords;
	vector<bool> triangleFaceEdgeMarks;

	// Each triplet of vertices is considered as an independent triangle
	for (unsigned int i = 0; i < nvertices / 3; i++) {
		triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i] / 3]);
		triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 1] / 3]);
		triangleVertices.push_back(currentShape->getVertexList()[vindices[3 * i + 2] / 3]);

		triangleNormals.push_back(Vec3r(normals[nindices[3 * i]], normals[nindices[3 * i] + 1],
		                                normals[nindices[3 * i] + 2]));
		triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 1]], normals[nindices[3 * i + 1] + 1],
		                                normals[nindices[3 * i + 1] + 2]));
		triangleNormals.push_back(Vec3r(normals[nindices[3 * i + 2]], normals[nindices[3 * i + 2] + 1],
		                                normals[nindices[3 * i + 2] + 2]));

		if (texCoords) {
			triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i]], texCoords[tindices[3 * i] + 1]));
			triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 1]], texCoords[tindices[3 * i + 1] + 1]));
			triangleTexCoords.push_back(Vec2r(texCoords[tindices[3 * i + 2]], texCoords[tindices[3 * i + 2] + 1]));
		}

		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
	}
	if (mindices)
		currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
		                       mindices[0]);
	else
		currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
}
Beispiel #4
0
WShape::WShape(WShape& iBrother)
{
	_Id = iBrother.GetId();
	_Name = iBrother._Name;
	_FrsMaterials = iBrother._FrsMaterials;
	_meanEdgeSize = iBrother._meanEdgeSize;
	iBrother.bbox(_min, _max);
	vector<WVertex *>& vertexList = iBrother.getVertexList();
	vector<WVertex *>::iterator v = vertexList.begin(), vend = vertexList.end();
	for (; v != vend; ++v) {
		//WVertex *newVertex = new WVertex(*(*v));
		WVertex *newVertex = (*v)->duplicate();

		newVertex->setShape(this);
		AddVertex(newVertex);
	}

	vector<WEdge *>& edgeList = iBrother.getEdgeList();
	vector<WEdge *>::iterator e = edgeList.begin(), eend = edgeList.end();
	for (; e != eend; ++e) {
		//WEdge *newEdge = new WEdge(*(*e));
		WEdge *newEdge = (*e)->duplicate();
		AddEdge(newEdge);
	}

	vector<WFace *>& faceList = iBrother.GetFaceList();
	vector<WFace *>::iterator f = faceList.begin(), fend = faceList.end();
	for (; f != fend; ++f) {
		//WFace *newFace = new WFace(*(*f));
		WFace *newFace = (*f)->duplicate();
		AddFace(newFace);
	}

	// update all pointed addresses thanks to the newly created objects:
	vend = _VertexList.end();
	for (v = _VertexList.begin(); v != vend; ++v) {
		const vector<WEdge *>& vedgeList = (*v)->GetEdges();
		vector<WEdge *> newvedgelist;
		unsigned int i;
		for (i = 0; i < vedgeList.size(); i++) {
			WEdge *current = vedgeList[i];
			edgedata *currentvedata = (edgedata *)current->userdata;
			newvedgelist.push_back(currentvedata->_copy);
		}
		(*v)->setEdges(newvedgelist);
	}

	eend = _EdgeList.end();
	for (e = _EdgeList.begin(); e != eend; ++e) {
		// update aOedge:
		WOEdge *aoEdge = (*e)->GetaOEdge();
		aoEdge->setaVertex(((vertexdata *)(aoEdge->GetaVertex()->userdata))->_copy);
		aoEdge->setbVertex(((vertexdata *)(aoEdge->GetbVertex()->userdata))->_copy);
		if (aoEdge->GetaFace())
			aoEdge->setaFace(((facedata *)(aoEdge->GetaFace()->userdata))->_copy);
		aoEdge->setbFace(((facedata *)(aoEdge->GetbFace()->userdata))->_copy);
		aoEdge->setOwner(((edgedata *)(aoEdge->GetOwner()->userdata))->_copy);

		// update bOedge:
		WOEdge *boEdge = (*e)->GetbOEdge();
		if (boEdge) {
			boEdge->setaVertex(((vertexdata *)(boEdge->GetaVertex()->userdata))->_copy);
			boEdge->setbVertex(((vertexdata *)(boEdge->GetbVertex()->userdata))->_copy);
			if (boEdge->GetaFace())
				boEdge->setaFace(((facedata *)(boEdge->GetaFace()->userdata))->_copy);
			boEdge->setbFace(((facedata *)(boEdge->GetbFace()->userdata))->_copy);
			boEdge->setOwner(((edgedata *)(boEdge->GetOwner()->userdata))->_copy);
		}
	}

	fend = _FaceList.end();
	for (f = _FaceList.begin(); f != fend; ++f) {
		unsigned int i;
		const vector<WOEdge *>& oedgeList = (*f)->getEdgeList();
		vector<WOEdge *> newoedgelist;

		unsigned int n = oedgeList.size();
		for (i = 0; i < n; i++) {
			WOEdge *current = oedgeList[i];
			oedgedata *currentoedata = (oedgedata *)current->userdata;
			newoedgelist.push_back(currentoedata->_copy);
			//oedgeList[i] = currentoedata->_copy;
			//oedgeList[i] = ((oedgedata *)(oedgeList[i]->userdata))->_copy;
		}
		(*f)->setEdgeList(newoedgelist);
	}

	// Free all memory (arghh!)
	// Vertex
	vend = iBrother.getVertexList().end();
	for (v = iBrother.getVertexList().begin(); v != vend; ++v) {
		delete (vertexdata *)((*v)->userdata);
		(*v)->userdata = NULL;
	}

	// Edges and OEdges:
	eend = iBrother.getEdgeList().end();
	for (e = iBrother.getEdgeList().begin(); e != eend; ++e) {
		delete (edgedata *)((*e)->userdata);
		(*e)->userdata = NULL;
		// OEdge a:
		delete (oedgedata *)((*e)->GetaOEdge()->userdata);
		(*e)->GetaOEdge()->userdata = NULL;
		// OEdge b:
		WOEdge *oedgeb = (*e)->GetbOEdge();
		if (oedgeb) {
			delete (oedgedata *)(oedgeb->userdata);
			oedgeb->userdata = NULL;
		}
	}

	// Faces
	fend = iBrother.GetFaceList().end();
	for (f = iBrother.GetFaceList().begin(); f != fend; ++f) {
		delete (facedata *)((*f)->userdata);
		(*f)->userdata = NULL;
	}
}
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;
}
void WingedEdgeBuilder::buildTriangleStrip(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials,
                                           const real *texCoords, const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks,
                                           const unsigned *vindices, const unsigned *nindices, const unsigned *mindices,
                                           const unsigned *tindices, const unsigned nvertices)
{
	unsigned nDoneVertices = 2; // number of vertices already treated
	unsigned nTriangle = 0;     // number of the triangle currently being treated
	//int nVertex = 0;            // vertex number

	WShape *currentShape = _current_wshape; // the current shape being built
	vector<WVertex *> triangleVertices;
	vector<Vec3r> triangleNormals;
	vector<Vec2r> triangleTexCoords;
	vector<bool> triangleFaceEdgeMarks;

	while (nDoneVertices < nvertices) {
		//clear the vertices list:
		triangleVertices.clear();
		//Then rebuild it:
		if (0 == nTriangle % 2) { // if nTriangle is even
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);

			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
			                                normals[nindices[nTriangle] + 2]));
			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
			                                normals[nindices[nTriangle + 1] + 2]));
			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
			                                normals[nindices[nTriangle + 2] + 2]));

			if (texCoords) {
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
				                                  texCoords[tindices[nTriangle + 1] + 1]));
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
				                                  texCoords[tindices[nTriangle + 2] + 1]));
			}
		}
		else {                 // if nTriangle is odd
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle] / 3]);
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 2] / 3]);
			triangleVertices.push_back(currentShape->getVertexList()[vindices[nTriangle + 1] / 3]);

			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle]], normals[nindices[nTriangle] + 1],
			                                normals[nindices[nTriangle] + 2]));
			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 2]], normals[nindices[nTriangle + 2] + 1],
			                                normals[nindices[nTriangle + 2] + 2]));
			triangleNormals.push_back(Vec3r(normals[nindices[nTriangle + 1]], normals[nindices[nTriangle + 1] + 1],
			                                normals[nindices[nTriangle + 1] + 2]));

			if (texCoords) {
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle]], texCoords[tindices[nTriangle] + 1]));
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 2]],
				                                  texCoords[tindices[nTriangle + 2] + 1]));
				triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle + 1]],
				                                  texCoords[tindices[nTriangle + 1] + 1]));
			}
		}
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::FACE_MARK) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0);
		triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle / 3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0);
		if (mindices) {
			currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks,
			                       mindices[nTriangle / 3]);
		}
		else {
			currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0);
		}
		nDoneVertices++; // with a strip, each triangle is one vertex more
		nTriangle++;
	}
}