// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int32_t AbaqusSurfaceMeshWriter::writeNodes(FILE* f) { TriangleGeom::Pointer triangleGeom = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName())->getGeometryAs<TriangleGeom>(); float* nodes = triangleGeom->getVertexPointer(0); int64_t numNodes = triangleGeom->getNumberOfVertices(); int32_t err = 0; fprintf(f, "*Node,NSET=NALL\n"); //1, 72.520433763730, 70.306420652241, 100.000000000000 // Abaqus Starts number at 1 NOT 0(Zero). for (int64_t i = 1; i <= numNodes; ++i) { fprintf(f, "%lld, %0.6f, %0.6f, %0.6f\n", (long long int)i, nodes[(i - 1) * 3], nodes[(i - 1) * 3 + 1], nodes[(i - 1) * 3 + 2]); } return err; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int SurfaceMeshToNonconformalVtk::writePointData(FILE* vtkFile) { int err = 0; if (NULL == vtkFile) { return -1; } DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(m_SurfaceMeshNodeTypeArrayPath.getDataContainerName()); TriangleGeom::Pointer triangleGeom = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName())->getGeometryAs<TriangleGeom>(); //Get the Number of Vertex points in the mesh with a valid node type qint64 numNodes = triangleGeom->getNumberOfVertices(); int nNodes = 0; // int swapped; for (int i = 0; i < numNodes; i++) { if (m_SurfaceMeshNodeType[i] > 0) { ++nNodes; } else { qDebug() << "Node Type Invalid: " << i << "::" << (int)(m_SurfaceMeshNodeType[i]) ;} } // This is the section header fprintf(vtkFile, "\n"); fprintf(vtkFile, "POINT_DATA %d\n", nNodes); fprintf(vtkFile, "SCALARS Node_Type char 1\n"); fprintf(vtkFile, "LOOKUP_TABLE default\n"); for(int i = 0; i < numNodes; ++i) { if(m_SurfaceMeshNodeType[i] > 0) { if(m_WriteBinaryFile == true) { // swapped = m_SurfaceMeshNodeType[i]; // SIMPLib::Endian::FromSystemToBig::convert(swapped); fwrite(m_SurfaceMeshNodeType + i, sizeof(char), 1, vtkFile); } else { fprintf(vtkFile, "%d ", m_SurfaceMeshNodeType[i]); } } } QString attrMatName = m_SurfaceMeshNodeTypeArrayPath.getAttributeMatrixName(); #if 1 // This is from the Goldfeather Paper writePointVectorData<double>(sm, attrMatName, "Principal_Direction_1", "double", m_WriteBinaryFile, "VECTORS", vtkFile, numNodes); // This is from the Goldfeather Paper writePointVectorData<double>(sm, attrMatName, "Principal_Direction_2", "double", m_WriteBinaryFile, "VECTORS", vtkFile, numNodes); // This is from the Goldfeather Paper writePointScalarData<double>(sm, attrMatName, "Principal_Curvature_1", "double", m_WriteBinaryFile, vtkFile, numNodes); // This is from the Goldfeather Paper writePointScalarData<double>(sm, attrMatName, "Principal_Curvature_2", "double", m_WriteBinaryFile, vtkFile, numNodes); #endif // This is from the Goldfeather Paper writePointVectorData<double>(sm, attrMatName, SIMPL::VertexData::SurfaceMeshNodeNormals, "double", m_WriteBinaryFile, "VECTORS", vtkFile, numNodes); return err; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void SurfaceMeshToNonconformalVtk::execute() { int err = 0; setErrorCondition(err); dataCheck(); if(getErrorCondition() < 0) { return; } DataContainer::Pointer m = getDataContainerArray()->getDataContainer(m_SurfaceMeshFaceLabelsArrayPath.getDataContainerName()); TriangleGeom::Pointer triangleGeom = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName())->getGeometryAs<TriangleGeom>(); float* nodes = triangleGeom->getVertexPointer(0); int64_t* triangles = triangleGeom->getTriPointer(0); qint64 numNodes = triangleGeom->getNumberOfVertices(); int64_t numTriangles = triangleGeom->getNumberOfTris(); // Make sure any directory path is also available as the user may have just typed // in a path without actually creating the full path QFileInfo fi(getOutputVtkFile()); QDir parentPath = fi.path(); if(!parentPath.mkpath(".")) { QString ss = QObject::tr("Error creating parent path '%1'").arg(parentPath.absolutePath()); setErrorCondition(-1); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } // Open the output VTK File for writing FILE* vtkFile = NULL; vtkFile = fopen(getOutputVtkFile().toLatin1().data(), "wb"); if (NULL == vtkFile) { QString ss = QObject::tr("Error creating file '%1'").arg(getOutputVtkFile()); setErrorCondition(-18542); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } ScopedFileMonitor vtkFileMonitor(vtkFile); notifyStatusMessage(getHumanLabel(), "Writing Vertex Data ...."); fprintf(vtkFile, "# vtk DataFile Version 2.0\n"); fprintf(vtkFile, "Data set from DREAM.3D Surface Meshing Module\n"); if (m_WriteBinaryFile) { fprintf(vtkFile, "BINARY\n"); } else { fprintf(vtkFile, "ASCII\n"); } fprintf(vtkFile, "DATASET POLYDATA\n"); int numberWrittenNodes = 0; for (int i = 0; i < numNodes; i++) { // Node& n = nodes[i]; // Get the current Node if (m_SurfaceMeshNodeType[i] > 0) { ++numberWrittenNodes; } else { qDebug() << "Node Type Invalid: " << i << "::" << (int)(m_SurfaceMeshNodeType[i]) ;} } fprintf(vtkFile, "POINTS %d float\n", numberWrittenNodes); float pos[3] = {0.0f, 0.0f, 0.0f}; size_t totalWritten = 0; // Write the POINTS data (Vertex) for (int i = 0; i < numNodes; i++) { if (m_SurfaceMeshNodeType[i] > 0) { pos[0] = static_cast<float>(nodes[i * 3]); pos[1] = static_cast<float>(nodes[i * 3 + 1]); pos[2] = static_cast<float>(nodes[i * 3 + 2]); if (m_WriteBinaryFile == true) { SIMPLib::Endian::FromSystemToBig::convert(pos[0]); SIMPLib::Endian::FromSystemToBig::convert(pos[1]); SIMPLib::Endian::FromSystemToBig::convert(pos[2]); totalWritten = fwrite(pos, sizeof(float), 3, vtkFile); if(totalWritten != 3) {} } else { fprintf(vtkFile, "%f %f %f\n", pos[0], pos[1], pos[2]); // Write the positions to the output file } } } // Write the triangle indices into the vtk File notifyStatusMessage(getHumanLabel(), "Writing Faces ...."); int tData[4]; // Store all the unique Spins QMap<int32_t, int32_t> featureTriangleCount; for (int i = 0; i < numTriangles; i++) { if (featureTriangleCount.find(m_SurfaceMeshFaceLabels[i * 2]) == featureTriangleCount.end()) { featureTriangleCount[m_SurfaceMeshFaceLabels[i * 2]] = 1; } else { featureTriangleCount[m_SurfaceMeshFaceLabels[i * 2]]++; } if (featureTriangleCount.find(m_SurfaceMeshFaceLabels[i * 2 + 1]) == featureTriangleCount.end()) { featureTriangleCount[m_SurfaceMeshFaceLabels[i * 2 + 1]] = 1; } else { featureTriangleCount[m_SurfaceMeshFaceLabels[i * 2 + 1]]++; } } // Write the POLYGONS fprintf(vtkFile, "\nPOLYGONS %lld %lld\n", (long long int)(numTriangles * 2), (long long int)(numTriangles * 2 * 4)); size_t totalCells = 0; // Loop over all the features for(QMap<int32_t, int32_t>::iterator featureIter = featureTriangleCount.begin(); featureIter != featureTriangleCount.end(); ++featureIter) { totalCells += featureIter.value(); } Q_ASSERT(totalCells == (size_t)(numTriangles * 2) ); // Loop over all the features for(QMap<int32_t, int32_t>::iterator featureIter = featureTriangleCount.begin(); featureIter != featureTriangleCount.end(); ++featureIter) { int32_t gid = featureIter.key(); // The current Feature Id int32_t numTriToWrite = featureIter.value(); // The number of triangles for this feature uint8_t doWrite = 0; // Loop over all the triangles looking for the current feature id // this is probably sub-optimal as if we have 1000 features we are going to loop 1000 times but this will use the // least amount of memory. We could run a filter to group the triangles by feature but then we would need an // additional amount of memory equal to 3X the memory used for the triangle list because every triangle will be listed // twice. We could get some slightly better performance if we buffered 4K worth of data then wrote out that data // in one chunk versus what we are doing here. for (int j = 0; j < numTriangles; j++) { doWrite = 0; if (m_SurfaceMeshFaceLabels[j * 2] == gid ) { doWrite = 1; } else if (m_SurfaceMeshFaceLabels[j * 2 + 1] == gid) { doWrite = 2; } // We need to flip the winding of the triangle if (doWrite == 0) { continue; } // Labels in the triangle did match the current feature id. if (doWrite == 1) { tData[0] = 3; // Push on the total number of entries for this entry tData[1] = triangles[j * 3]; tData[2] = triangles[j * 3 + 1]; tData[3] = triangles[j * 3 + 2]; } else { tData[0] = 3; // Push on the total number of entries for this entry tData[1] = triangles[j * 3 + 2]; tData[2] = triangles[j * 3 + 1]; tData[3] = triangles[j * 3]; } if (m_WriteBinaryFile == true) { SIMPLib::Endian::FromSystemToBig::convert(tData[0]); SIMPLib::Endian::FromSystemToBig::convert(tData[1]); // Index of Vertex 0 SIMPLib::Endian::FromSystemToBig::convert(tData[2]); // Index of Vertex 1 SIMPLib::Endian::FromSystemToBig::convert(tData[3]); // Index of Vertex 2 fwrite(tData, sizeof(int), 4, vtkFile); } else { fprintf(vtkFile, "3 %d %d %d\n", tData[1], tData[2], tData[3]); } numTriToWrite--; } if (numTriToWrite != 0) { qDebug() << "Not enough triangles written: " << gid << "::" << numTriToWrite << " Total Triangles to Write " << featureIter.value(); } } // Write the POINT_DATA section err = writePointData(vtkFile); // Write the CELL_DATA section err = writeCellData(vtkFile, featureTriangleCount); fprintf(vtkFile, "\n"); setErrorCondition(0); notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int SurfaceMeshToVtk::writePointData(FILE* vtkFile) { int err = 0; if (NULL == vtkFile) { return -1; } DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(m_SurfaceMeshFaceLabelsArrayPath.getDataContainerName()); TriangleGeom::Pointer triangleGeom = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName())->getGeometryAs<TriangleGeom>(); qint64 numNodes = triangleGeom->getNumberOfVertices(); int64_t numberWrittenumNodes = 0; // Write the Node Type Data to the file for (int i = 0; i < numNodes; i++) { if (m_SurfaceMeshNodeType[i] > 0) { ++numberWrittenumNodes; } } // This is the section header fprintf(vtkFile, "\n"); fprintf(vtkFile, "POINT_DATA %lld\n", (long long int)(numberWrittenumNodes)); fprintf(vtkFile, "SCALARS Node_Type char 1\n"); fprintf(vtkFile, "LOOKUP_TABLE default\n"); for(int i = 0; i < numNodes; ++i) { if(m_SurfaceMeshNodeType[i] > 0) { if(m_WriteBinaryFile == true) { // Normally, we would byte swap to big endian but since we are only writing // 1 byte Char values, nothing to swap. fwrite(m_SurfaceMeshNodeType + i, sizeof(char), 1, vtkFile); } else { fprintf(vtkFile, "%d ", m_SurfaceMeshNodeType[i]); } } } QString attrMatName = m_SurfaceMeshNodeTypeArrayPath.getAttributeMatrixName(); #if 1 // This is from the Goldfeather Paper writePointVectorData<double>(sm, attrMatName, "Principal_Direction_1", "double", m_WriteBinaryFile, m_WriteConformalMesh, "VECTORS", vtkFile, numNodes); // This is from the Goldfeather Paper writePointVectorData<double>(sm, attrMatName, "Principal_Direction_2", "double", m_WriteBinaryFile, m_WriteConformalMesh, "VECTORS", vtkFile, numNodes); // This is from the Goldfeather Paper writePointScalarData<double>(sm, attrMatName, "Principal_Curvature_1", "double", m_WriteBinaryFile, m_WriteConformalMesh, vtkFile, numNodes); // This is from the Goldfeather Paper writePointScalarData<double>(sm, attrMatName, "Principal_Curvature_2", "double", m_WriteBinaryFile, m_WriteConformalMesh, vtkFile, numNodes); #endif // This is from the Goldfeather Paper writePointVectorData<double>(sm, attrMatName, DREAM3D::VertexData::SurfaceMeshNodeNormals, "double", m_WriteBinaryFile, m_WriteConformalMesh, "VECTORS", vtkFile, numNodes); return err; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void SurfaceMeshToVtk::execute() { int err = 0; setErrorCondition(err); dataCheck(); if(getErrorCondition() < 0) { return; } setErrorCondition(0); DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(m_SurfaceMeshFaceLabelsArrayPath.getDataContainerName()); /* Place all your code to execute your filter here. */ TriangleGeom::Pointer triangleGeom = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName())->getGeometryAs<TriangleGeom>(); float* nodes = triangleGeom->getVertexPointer(0); int64_t* triangles = triangleGeom->getTriPointer(0); qint64 numNodes = triangleGeom->getNumberOfVertices(); int64_t numTriangles = triangleGeom->getNumberOfTris(); // Make sure any directory path is also available as the user may have just typed // in a path without actually creating the full path QFileInfo fi(getOutputVtkFile()); QDir parentPath = fi.path(); if(!parentPath.mkpath(".")) { QString ss = QObject::tr("Error creating parent path '%1'").arg(parentPath.absolutePath()); notifyErrorMessage(getHumanLabel(), ss, -1); setErrorCondition(-1); return; } // Open the output VTK File for writing FILE* vtkFile = NULL; vtkFile = fopen(getOutputVtkFile().toLatin1().data(), "wb"); if (NULL == vtkFile) { QString ss = QObject::tr("Error creating file '%1'").arg(getOutputVtkFile()); notifyErrorMessage(getHumanLabel(), ss, -18542); setErrorCondition(-18542); return; } ScopedFileMonitor vtkFileMonitor(vtkFile); fprintf(vtkFile, "# vtk DataFile Version 2.0\n"); fprintf(vtkFile, "Data set from DREAM.3D Surface Meshing Module\n"); if (m_WriteBinaryFile) { fprintf(vtkFile, "BINARY\n"); } else { fprintf(vtkFile, "ASCII\n"); } fprintf(vtkFile, "DATASET POLYDATA\n"); int numberWrittenumNodes = 0; for (int i = 0; i < numNodes; i++) { // Node& n = nodes[i]; // Get the current Node if (m_SurfaceMeshNodeType[i] > 0) { ++numberWrittenumNodes; } } fprintf(vtkFile, "POINTS %d float\n", numberWrittenumNodes); float pos[3] = {0.0f, 0.0f, 0.0f}; size_t totalWritten = 0; // Write the POINTS data (Vertex) for (int i = 0; i < numNodes; i++) { if (m_SurfaceMeshNodeType[i] > 0) { pos[0] = static_cast<float>(nodes[i * 3]); pos[1] = static_cast<float>(nodes[i * 3 + 1]); pos[2] = static_cast<float>(nodes[i * 3 + 2]); if (m_WriteBinaryFile == true) { SIMPLib::Endian::FromSystemToBig::convert(pos[0]); SIMPLib::Endian::FromSystemToBig::convert(pos[1]); SIMPLib::Endian::FromSystemToBig::convert(pos[2]); totalWritten = fwrite(pos, sizeof(float), 3, vtkFile); if (totalWritten != sizeof(float) * 3) { } } else { fprintf(vtkFile, "%f %f %f\n", pos[0], pos[1], pos[2]); // Write the positions to the output file } } } int tData[4]; int triangleCount = numTriangles; // int tn1, tn2, tn3; if (false == m_WriteConformalMesh) { triangleCount = numTriangles * 2; } // Write the POLYGONS fprintf(vtkFile, "\nPOLYGONS %d %d\n", triangleCount, (triangleCount * 4)); for (int j = 0; j < numTriangles; j++) { // Triangle& t = triangles[j]; tData[1] = triangles[j * 3]; tData[2] = triangles[j * 3 + 1]; tData[3] = triangles[j * 3 + 2]; if (m_WriteBinaryFile == true) { tData[0] = 3; // Push on the total number of entries for this entry SIMPLib::Endian::FromSystemToBig::convert(tData[0]); SIMPLib::Endian::FromSystemToBig::convert(tData[1]); // Index of Vertex 0 SIMPLib::Endian::FromSystemToBig::convert(tData[2]); // Index of Vertex 1 SIMPLib::Endian::FromSystemToBig::convert(tData[3]); // Index of Vertex 2 fwrite(tData, sizeof(int), 4, vtkFile); if (false == m_WriteConformalMesh) { tData[0] = tData[1]; tData[1] = tData[3]; tData[3] = tData[0]; tData[0] = 3; SIMPLib::Endian::FromSystemToBig::convert(tData[0]); fwrite(tData, sizeof(int), 4, vtkFile); } } else { fprintf(vtkFile, "3 %d %d %d\n", tData[1], tData[2], tData[3]); if (false == m_WriteConformalMesh) { fprintf(vtkFile, "3 %d %d %d\n", tData[3], tData[2], tData[1]); } } } // Write the POINT_DATA section err = writePointData(vtkFile); // Write the CELL_DATA section err = writeCellData(vtkFile); fprintf(vtkFile, "\n"); setErrorCondition(0); notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void AbaqusSurfaceMeshWriter::execute() { int32_t err = 0; setErrorCondition(err); dataCheck(); if(getErrorCondition() < 0) { return; } DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName()); // Make sure any directory path is also available as the user may have just typed // in a path without actually creating the full path QFileInfo fi(getOutputFile()); QDir parentPath = fi.path(); if(!parentPath.mkpath(".")) { QString ss = QObject::tr("Error creating parent path '%1'").arg(parentPath.absolutePath()); setErrorCondition(-8005); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>(); // Store all the unique Spins std::set<int32_t> uniqueSpins; for (int64_t i = 0; i < triangleGeom->getNumberOfTris(); i++) { uniqueSpins.insert(m_SurfaceMeshFaceLabels[i * 2]); uniqueSpins.insert(m_SurfaceMeshFaceLabels[i * 2 + 1]); } FILE* f = fopen(m_OutputFile.toLatin1().data(), "wb"); ScopedFileMonitor fileMonitor(f); err = writeHeader(f, triangleGeom->getNumberOfVertices(), triangleGeom->getNumberOfTris(), uniqueSpins.size() - 1); if(err < 0) { QString ss = QObject::tr("Error writing header for file '%1'").arg(m_OutputFile); setErrorCondition(-8001); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } err = writeNodes(f); if(err < 0) { QString ss = QObject::tr("Error writing nodes for file '%1'").arg(m_OutputFile); setErrorCondition(-8002); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } err = writeTriangles(f); if(err < 0) { QString ss = QObject::tr("Error writing triangles for file '%1'").arg(m_OutputFile); setErrorCondition(-8003); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } err = writeFeatures(f); if(err < 0) { QString ss = QObject::tr("Error writing Features for file '%1'").arg(m_OutputFile); setErrorCondition(-8004); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void ReadStlFile::eliminate_duplicate_nodes() { DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(m_SurfaceMeshDataContainerName); TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>(); float* vertex = triangleGeom->getVertexPointer(0); int64_t nNodes = triangleGeom->getNumberOfVertices(); int64_t* triangles = triangleGeom->getTriPointer(0); int64_t nTriangles = triangleGeom->getNumberOfTris(); float stepX = (m_maxXcoord - m_minXcoord) / 100.0f; float stepY = (m_maxYcoord - m_minYcoord) / 100.0f; float stepZ = (m_maxZcoord - m_minZcoord) / 100.0f; QVector<QVector<size_t> > nodesInBin(100 * 100 * 100); // determine (xyz) bin each node falls in - used to speed up node comparison int32_t bin = 0, xBin = 0, yBin = 0, zBin = 0; for (int64_t i = 0; i < nNodes; i++) { xBin = (vertex[i * 3] - m_minXcoord) / stepX; yBin = (vertex[i * 3 + 1] - m_minYcoord) / stepY; zBin = (vertex[i * 3 + 2] - m_minZcoord) / stepZ; if (xBin == 100) { xBin = 99; } if (yBin == 100) { yBin = 99; } if (zBin == 100) { zBin = 99; } bin = (zBin * 10000) + (yBin * 100) + xBin; nodesInBin[bin].push_back(i); } // Create array to hold unique node numbers Int64ArrayType::Pointer uniqueIdsPtr = Int64ArrayType::CreateArray(nNodes, "uniqueIds"); int64_t* uniqueIds = uniqueIdsPtr->getPointer(0); for (int64_t i = 0; i < nNodes; i++) { uniqueIds[i] = i; } #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS tbb::task_scheduler_init init; bool doParallel = true; #endif //Parallel algorithm to find duplicate nodes #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS if (doParallel == true) { tbb::parallel_for(tbb::blocked_range<size_t>(0, 100 * 100 * 100), FindUniqueIdsImpl(triangleGeom->getVertices(), nodesInBin, uniqueIds), tbb::auto_partitioner()); } else #endif { FindUniqueIdsImpl serial(triangleGeom->getVertices(), nodesInBin, uniqueIds); serial.convert(0, 100 * 100 * 100); } //renumber the unique nodes int64_t uniqueCount = 0; for (int64_t i = 0; i < nNodes; i++) { if(uniqueIds[i] == i) { uniqueIds[i] = uniqueCount; uniqueCount++; } else { uniqueIds[i] = uniqueIds[uniqueIds[i]]; } } // Move nodes to unique Id and then resize nodes array for (int64_t i = 0; i < nNodes; i++) { vertex[uniqueIds[i] * 3] = vertex[i * 3]; vertex[uniqueIds[i] * 3 + 1] = vertex[i * 3 + 1]; vertex[uniqueIds[i] * 3 + 2] = vertex[i * 3 + 2]; } triangleGeom->resizeVertexList(uniqueCount); // Update the triangle nodes to reflect the unique ids int64_t node1 = 0, node2 = 0, node3 = 0; for (int64_t i = 0; i < nTriangles; i++) { node1 = triangles[i * 3]; node2 = triangles[i * 3 + 1]; node3 = triangles[i * 3 + 2]; triangles[i * 3] = uniqueIds[node1]; triangles[i * 3 + 1] = uniqueIds[node2]; triangles[i * 3 + 2] = uniqueIds[node3]; } }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void WriteTriangleGeometry::execute() { int err = 0; setErrorCondition(err); dataCheck(); if(getErrorCondition() < 0) { return; } DataContainer::Pointer dataContainer = getDataContainerArray()->getPrereqDataContainer<AbstractFilter>(this, getDataContainerSelection()); TriangleGeom::Pointer triangleGeom = dataContainer->getGeometryAs<TriangleGeom>(); QString geometryType = triangleGeom->getGeometryTypeAsString(); float* nodes = triangleGeom->getVertexPointer(0); int64_t* triangles = triangleGeom->getTriPointer(0); qint64 numNodes = triangleGeom->getNumberOfVertices(); qint64 maxNodeId = numNodes - 1; int64_t numTriangles = triangleGeom->getNumberOfTris(); // ++++++++++++++ Write the Nodes File +++++++++++++++++++++++++++++++++++++++++++ // Make sure any directory path is also available as the user may have just typed // in a path without actually creating the full path notifyStatusMessage(getHumanLabel(), "Writing Nodes Text File"); QFileInfo fi(getOutputNodesFile()); QDir parentPath = fi.path(); if(!parentPath.mkpath(".")) { QString ss = QObject::tr("Error creating parent path '%1'").arg(parentPath.absolutePath()); notifyErrorMessage(getHumanLabel(), ss, -1); setErrorCondition(-1); return; } FILE* nodesFile = NULL; nodesFile = fopen(getOutputNodesFile().toLatin1().data(), "wb"); if (NULL == nodesFile) { setErrorCondition(-100); notifyErrorMessage(getHumanLabel(), "Error opening Nodes file for writing", -100); return; } fprintf(nodesFile, "# All lines starting with '#' are comments\n"); fprintf(nodesFile, "# DREAM.3D Nodes file\n"); fprintf(nodesFile, "# DREAM.3D Version %s\n", SIMPLib::Version::Complete().toLatin1().constData()); fprintf(nodesFile, "# Node Data is X Y Z space delimited.\n"); fprintf(nodesFile, "Node Count: %lld\n", numNodes); for (int i = 0; i < numNodes; i++) { fprintf(nodesFile, "%8.5f %8.5f %8.5f\n", nodes[i * 3], nodes[i * 3 + 1], nodes[i * 3 + 2]); } fclose(nodesFile); // ++++++++++++++ Write the Triangles File +++++++++++++++++++++++++++++++++++++++++++ notifyStatusMessage(getHumanLabel(), "Writing Triangles Text File"); QFileInfo triFI(getOutputTrianglesFile()); parentPath = triFI.path(); if(!parentPath.mkpath(".")) { QString ss = QObject::tr("Error creating parent path '%1'").arg(parentPath.absolutePath()); notifyErrorMessage(getHumanLabel(), ss, -1); setErrorCondition(-1); return; } FILE* triFile = fopen(getOutputTrianglesFile().toLatin1().data(), "wb"); if (NULL == triFile) { setErrorCondition(-100); notifyErrorMessage(getHumanLabel(), "Error opening Triangles file for writing", -100); return; } fprintf(triFile, "# All lines starting with '#' are comments\n"); fprintf(triFile, "# DREAM.3D Triangle file\n"); fprintf(triFile, "# DREAM.3D Version %s\n", SIMPLib::Version::Complete().toLatin1().constData()); fprintf(triFile, "# Each Triangle consists of 3 Node Ids.\n"); fprintf(triFile, "# NODE IDs START AT 0.\n"); fprintf(triFile, "Geometry Type: %s\n", geometryType.toLatin1().constData()); fprintf(triFile, "Node Count: %lld\n", numNodes); fprintf(triFile, "Max Node Id: %lld\n", maxNodeId ); fprintf(triFile, "Triangle Count: %lld\n", (long long int)(numTriangles)); int n1, n2, n3; for (int64_t j = 0; j < numTriangles; ++j) { n1 = triangles[j * 3]; n2 = triangles[j * 3 + 1]; n3 = triangles[j * 3 + 2]; fprintf(triFile, "%d %d %d\n", n1, n2, n3); } fclose(triFile); /* Let the GUI know we are done with this filter */ notifyStatusMessage(getHumanLabel(), "Complete"); }