Пример #1
0
void Tessellate(
	NodeVector & vecNodes,
	FaceVector & vecFaces
) {
	int nInitialNodeListSize = vecNodes.size();

	// Create centerpoint nodes
	for (int i = 0; i < vecFaces.size(); i++) {
		InsertQuadNodeCenter(
			vecNodes,
			vecNodes[vecFaces[i][0]],
			vecNodes[vecFaces[i][1]],
			vecNodes[vecFaces[i][2]],
			vecNodes[vecFaces[i][3]]);
	}

	// Construct tesselation
	SegmentMap mapSegment;
	ConstructSegmentMap(vecFaces, mapSegment, -1);

	vecFaces.clear();

	SegmentMapIterator iter = mapSegment.begin();
	for (; iter != mapSegment.end(); iter++) {
		Face faceNew = 
			Face(
				iter->first[1],
				nInitialNodeListSize + iter->second[0],
				iter->first[0],
				nInitialNodeListSize + iter->second[1]);

		vecFaces.push_back(faceNew);
	}
}
Пример #2
0
void LD3dsExporter::writeTriangle(
	VertexVector &vecVertices,
	FaceVector &vecFaces,
	const TCVector *points,
	int i0,
	int i1,
	int i2,
	int colorNumber,
	const TCFloat *matrix)
{
	int ix[3];
	int voffset = (int)vecVertices.size();
	int foffset = (int)vecFaces.size();

	ix[0] = i0;
	ix[1] = i1;
	ix[2] = i2;
	vecVertices.resize(vecVertices.size() + 3);
	vecFaces.resize(vecFaces.size() + 1);
	for (int i = 0; i < 3; i++)
	{
		TCVector vector = points[ix[i]];

		vector = vector.transformPoint(matrix);
		vecVertices[voffset + i].v[0] = vector[0];
		vecVertices[voffset + i].v[1] = vector[1];
		vecVertices[voffset + i].v[2] = vector[2];
		vecFaces[foffset].index[i] = (unsigned short)(voffset + i);
		vecFaces[foffset].material = getMaterial(colorNumber);
	}
}
Пример #3
0
void Dual(
    Mesh & mesh
) {
    const int EdgeCountHexagon = 6;

    // Generate ReverseNodeArray
    mesh.ConstructReverseNodeArray();

    // Backup Nodes and Faces
    NodeVector nodesOld = mesh.nodes;
    FaceVector facesOld = mesh.faces;

    mesh.nodes.clear();
    mesh.faces.clear();

    // Generate new Node array
    for (int i = 0; i < facesOld.size(); i++) {
        Node node;
        for (int j = 0; j < facesOld[i].edges.size(); j++) {
            node.x += nodesOld[facesOld[i][j]].x;
            node.y += nodesOld[facesOld[i][j]].y;
            node.z += nodesOld[facesOld[i][j]].z;
        }

        node.x /= static_cast<double>(facesOld[i].edges.size());
        node.y /= static_cast<double>(facesOld[i].edges.size());
        node.z /= static_cast<double>(facesOld[i].edges.size());

        double dMag = node.Magnitude();

        node.x /= dMag;
        node.y /= dMag;
        node.z /= dMag;

        mesh.nodes.push_back(node);
    }

    // Generate new Face array
    for (int i = 0; i < nodesOld.size(); i++) {
        const int nEdges = mesh.revnodearray[i].size();

        Face face(EdgeCountHexagon);
        Face faceTemp(EdgeCountHexagon);

        int ixNode = 0;
        std::set<int>::const_iterator iter = mesh.revnodearray[i].begin();
        for (; iter != mesh.revnodearray[i].end(); iter++) {
            faceTemp.SetNode(ixNode, *iter);
            ixNode++;
        }

        // Reorient Faces
        Node nodeCentral = nodesOld[i];
        Node node0 = mesh.nodes[faceTemp[0]] - nodeCentral;

        Node nodeCross = CrossProduct(mesh.nodes[faceTemp[0]], nodeCentral);

        double dNode0Mag = node0.Magnitude();

        // Determine the angles about the central Node of each Face Node
        std::vector<double> dAngles;
        dAngles.resize(faceTemp.edges.size());
        dAngles[0] = 0.0;

        for (int j = 1; j < nEdges; j++) {
            Node nodeDiff = mesh.nodes[faceTemp[j]] - nodeCentral;
            double dNodeDiffMag = nodeDiff.Magnitude();

            double dSide = DotProduct(nodeCross, nodeDiff);

            double dDotNorm =
                DotProduct(node0, nodeDiff) / (dNode0Mag * dNodeDiffMag);

            double dAngle;
            if (dDotNorm > 1.0) {
                dDotNorm = 1.0;
            }

            dAngles[j] = acos(dDotNorm);

            if (dSide > 0.0) {
                dAngles[j] = - dAngles[j] + 2.0 * M_PI;
            }
        }

        // Orient each Face by putting Nodes in order of increasing angle
        double dCurrentAngle = 0.0;
        face.SetNode(0, faceTemp[0]);
        for (int j = 1; j < nEdges; j++) {
            int ixNextNode = 1;
            double dNextAngle = 2.0 * M_PI;

            for (int k = 1; k < nEdges; k++) {
                if ((dAngles[k] > dCurrentAngle) && (dAngles[k] < dNextAngle)) {
                    ixNextNode = k;
                    dNextAngle = dAngles[k];
                }
            }

            face.SetNode(j, faceTemp[ixNextNode]);
            dCurrentAngle = dNextAngle;
        }

        // Fill in missing edges
        for (int j = nEdges; j < EdgeCountHexagon; j++) {
            face.SetNode(j, face[nEdges-1]);
        }

        mesh.faces.push_back(face);
    }
}
Пример #4
0
void GenerateFacesFromTriangle(
    int nRefineLevel,
    const MultiEdge & edge0,
    const MultiEdge & edge1,
    const MultiEdge & edge2,
    NodeVector & vecNodes,
    FaceVector & vecFaces
) {
    int i;
    int j;
    int k;

    int ixEndNode;

    int ixInt;

    // MultiEdges
    MultiEdge edgeBot;
    MultiEdge edgeMid;
    MultiEdge edgeTop;

    // Initial bottom edge
    edgeBot.push_back(edge0[0]);

    // Loop over all refined faces
    for (j = 0; j < nRefineLevel; j++) {

        // Generate top level vertices
        if (j == nRefineLevel-1) {
            edgeTop = edge2;
        } else {
            GenerateEdgeVertices(
                j+1, edge0[j+1], edge1[j+1], vecNodes, edgeTop);
        }

        // Generate faces
        for (i = 0; i < 2*j+1; i++) {
            // Downward pointing faces
            if (i % 2 == 0) {
                int ix = i/2;

                Face face(3);
                face.SetNode(0, edgeBot[ix]);
                face.SetNode(1, edgeTop[ix]);
                face.SetNode(2, edgeTop[ix+1]);

                vecFaces.push_back(face);

                // Upward pointing faces
            } else {
                int ix = (i-1)/2;

                Face face(3);
                face.SetNode(0, edgeTop[ix+1]);
                face.SetNode(1, edgeBot[ix+1]);
                face.SetNode(2, edgeBot[ix]);

                vecFaces.push_back(face);
            }
        }

        // New bottom edge
        edgeBot = edgeTop;
    }
}
Пример #5
0
void RefineEverything(
	NodeVector & vecNodes,
	FaceVector & vecFaces,
	int nResolution
) {
	// Generate segment map
	SegmentMap mapSegment;
	ConstructSegmentMap(vecFaces, mapSegment, -1);

	FaceVector vecFacesOld = vecFaces;

	// Loop over all faces
	vecFaces.clear();

	// Construct map from segments to edges
	std::map<Segment, Edge> mapEdge;

	SegmentMapIterator iter = mapSegment.begin();
	for (; iter != mapSegment.end(); iter++) {
		Edge edge;

		GenerateEdgeVertices(
			nResolution,
			iter->first[0],
			iter->first[1],
			vecNodes,
			edge);

		mapEdge.insert(std::pair<Segment, Edge>(iter->first, edge));
	}

	// Loop over all faces and refine
	for (int n = 0 ; n < vecFacesOld.size(); n++) {
		const Segment & seg0 = vecFacesOld[n].iterSegment[0]->first;
		const Segment & seg1 = vecFacesOld[n].iterSegment[1]->first;
		const Segment & seg2 = vecFacesOld[n].iterSegment[2]->first;
		const Segment & seg3 = vecFacesOld[n].iterSegment[3]->first;

		Edge edge0 = mapEdge.find(seg0)->second;
		Edge edge1 = mapEdge.find(seg1)->second;
		Edge edge3 = mapEdge.find(seg2)->second;
		Edge edge2 = mapEdge.find(seg3)->second;

		// Align bottom and left edge
		if (edge0[0] == edge1[0]) {
		} else if (edge0[0] == edge1[edge1.size()-1]) {
			edge1 = edge1.Flip();
		} else if (edge0[edge0.size()-1] == edge1[0]) {
			edge0 = edge0.Flip();
		} else if (edge0[edge0.size()-1] == edge1[edge1.size()-1]) {
			edge0 = edge0.Flip();
			edge1 = edge1.Flip();
		} else {
			_EXCEPTIONT("Logic error");
		}

		// Align bottom and right edge
		if (edge0[edge0.size()-1] == edge2[0]) {
		} else if (edge0[edge0.size()-1] == edge2[edge2.size()-1]) {
			edge2 = edge2.Flip();
		} else {
			_EXCEPTIONT("Logic error");
		}

		// Align top and left edge
		if (edge1[edge1.size()-1] == edge3[0]) {
		} else if (edge1[edge1.size()-1] == edge3[edge3.size()-1]) {
			edge3 = edge3.Flip();
		} else {
			_EXCEPTIONT("Logic error");
		}

		Edge edgeTop;
		Edge edgeBot = edge0;

		for (int j = 0; j < nResolution; j++) {

			// Generate top level edge
			if (j != nResolution-1) {
				int ix0 = edge1[j+1];
				int ix1 = edge2[j+1];

				GenerateEdgeVertices(nResolution, ix0, ix1, vecNodes, edgeTop);

			} else {
				edgeTop = edge3;
			}

			// Generate face
			for (int i = 0; i < nResolution; i++) {
				Face face(
					edgeBot[i+1], edgeBot[i],
					edgeTop[i], edgeTop[i+1],
					vecFacesOld[n].nRefineLevel);

				face.nColor = vecFacesOld[n].nColor;
				face.nTag = vecFacesOld[n].nTag;

				vecFaces.push_back(face);
			}

			// Increment row
			edgeBot = edgeTop;
		}
	}
}
Пример #6
0
void LD3dsExporter::doExport(
	LDLModel *pModel,
	Lib3dsNode *pParentNode,
	const TCFloat *matrix,
	int colorNumber,
	bool inPart,
	bool bfc,
	bool invert)
{
	LDLFileLineArray *pFileLines = pModel->getFileLines();

	if (pFileLines != NULL)
	{
		BFCState newBfcState = pModel->getBFCState();
		int count = pModel->getActiveLineCount();
		std::string meshName;
		Lib3dsMesh *pMesh = NULL;
		Lib3dsNode *pChildNode = NULL;
//		Lib3dsMeshInstanceNode *pInst;
		bool linesInvert = invert;
		bool isNew = false;

		if (TCVector::determinant(matrix) < 0.0f)
		{
			linesInvert = !linesInvert;
		}
		bfc = (bfc && newBfcState == BFCOnState) ||
			newBfcState == BFCForcedOnState;
		meshName.resize(128);
		sprintf(&meshName[0], "m_%06d", ++m_meshCount);
//		meshName = getMeshName(pModel, pMesh);
		if (pMesh == NULL)
		{
			pMesh = lib3ds_mesh_new(meshName.c_str());
//			memcpy(pMesh->matrix, matrix, sizeof(pMesh->matrix));
			m_meshes[meshName] = pMesh;
			lib3ds_file_insert_mesh(m_file, pMesh, -1);
			isNew = true;
		}
//		pInst = lib3ds_node_new_mesh_instance(pMesh,
//			NULL/*(meshName + "n").c_str()*/, NULL, NULL, NULL);
//		pChildNode = (Lib3dsNode *)pInst;
//		memcpy(pChildNode->matrix, matrix, sizeof(float) * 16);
//		lib3ds_file_append_node(m_file, pChildNode, pParentNode);
		VertexVector vecVertices;
		FaceVector vecFaces;
		for (int i = 0; i < count; i++)
		{
			LDLFileLine *pFileLine = (*pFileLines)[i];
			if (!pFileLine->isValid())
			{
				continue;
			}
			switch (pFileLine->getLineType())
			{
			case LDLLineTypeTriangle:
			case LDLLineTypeQuad:
				writeShapeLine(vecVertices, vecFaces, (LDLShapeLine *)pFileLine,
					matrix, colorNumber, bfc, linesInvert);
				break;
			case LDLLineTypeModel:
				{
					LDLModelLine *pModelLine = (LDLModelLine *)pFileLine;
					LDLModel *pOtherModel = pModelLine->getModel(true);
					if (pOtherModel != NULL)
					{
						TCFloat newMatrix[16];
						int otherColorNumber = pModelLine->getColorNumber();
						bool otherInPart = inPart;
						bool otherInvert = invert;
						
						if (pModelLine->getBFCInvert())
						{
							otherInvert = !otherInvert;
						}
						if (otherColorNumber == 16)
						{
							otherColorNumber = colorNumber;
						}
						TCVector::multMatrix(matrix, pModelLine->getMatrix(),
							newMatrix);
						if (!inPart && pOtherModel->isPart() && m_seams)
						{
							TCVector min, max;
							TCFloat seamMatrix[16];
							TCFloat tempMatrix[16];

							pOtherModel->getBoundingBox(min, max);
							TCVector::calcScaleMatrix(m_seamWidth, seamMatrix,
								min, max);
							TCVector::multMatrix(newMatrix, seamMatrix,
								tempMatrix);
							memcpy(newMatrix, tempMatrix, sizeof(newMatrix));
							otherInPart = true;
						}
						doExport(pOtherModel, pChildNode, newMatrix,
							otherColorNumber, otherInPart, bfc, otherInvert);
					}
				}
				break;
			default:
				// Get rid of warning
				break;
			}
		}
		if (isNew && vecVertices.size() > 0)
		{
			lib3ds_mesh_resize_vertices(pMesh, (int)vecVertices.size(), 0, 0);
			memcpy(pMesh->vertices, &vecVertices[0],
				sizeof(vecVertices[0]) * vecVertices.size());
			lib3ds_mesh_resize_faces(pMesh, (int)vecFaces.size());
			memcpy(pMesh->faces, &vecFaces[0],
				sizeof(vecFaces[0]) * vecFaces.size());
		}
		else
		{
			--m_meshCount;
		}

	}
}