// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void TriangleNormalFilter::execute() { setErrorCondition(0); dataCheck(); if(getErrorCondition() < 0) { return; } DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(getSurfaceMeshTriangleNormalsArrayPath().getDataContainerName()); TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>(); #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS bool doParallel = true; #endif #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS if (doParallel == true) { tbb::parallel_for(tbb::blocked_range<size_t>(0, triangleGeom->getNumberOfTris()), CalculateNormalsImpl(triangleGeom->getVertices(), triangleGeom->getTriangles(), m_SurfaceMeshTriangleNormals), tbb::auto_partitioner()); } else #endif { CalculateNormalsImpl serial(triangleGeom->getVertices(), triangleGeom->getTriangles(), m_SurfaceMeshTriangleNormals); serial.generate(0, triangleGeom->getNumberOfTris()); } /* Let the GUI know we are done with this filter */ notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void SurfaceMeshToNonconformalVtk::dataCheck() { setErrorCondition(0); QString ss; if (m_OutputVtkFile.isEmpty() == true) { setErrorCondition(-1003); notifyErrorMessage(getHumanLabel(), "Vtk Output file is Not set correctly", -1003); } DataContainer::Pointer sm = getDataContainerArray()->getPrereqDataContainer<AbstractFilter>(this, m_SurfaceMeshFaceLabelsArrayPath.getDataContainerName(), false); if(getErrorCondition() < 0) { return; } TriangleGeom::Pointer triangles = sm->getPrereqGeometry<TriangleGeom, AbstractFilter>(this); if(getErrorCondition() < 0) { return; } // We MUST have Nodes if (NULL == triangles->getVertices().get()) { setErrorCondition(-386); notifyErrorMessage(getHumanLabel(), "DataContainer Geometry missing Vertices", getErrorCondition()); } // We MUST have Triangles defined also. if (NULL == triangles->getTriangles().get()) { setErrorCondition(-387); notifyErrorMessage(getHumanLabel(), "DataContainer Geometry missing Triangles", getErrorCondition()); } QVector<size_t> dims(1, 2); m_SurfaceMeshFaceLabelsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this, getSurfaceMeshFaceLabelsArrayPath(), dims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ if( NULL != m_SurfaceMeshFaceLabelsPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */ { m_SurfaceMeshFaceLabels = m_SurfaceMeshFaceLabelsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */ dims[0] = 1; m_SurfaceMeshNodeTypePtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int8_t>, AbstractFilter>(this, getSurfaceMeshNodeTypeArrayPath(), dims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ if( NULL != m_SurfaceMeshNodeTypePtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */ { m_SurfaceMeshNodeType = m_SurfaceMeshNodeTypePtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */ }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void WriteTriangleGeometry::dataCheck() { setErrorCondition(0); if(true == m_OutputNodesFile.isEmpty()) { setErrorCondition(-380); notifyErrorMessage(getHumanLabel(), "The output Nodes file needs to be set", getErrorCondition()); } if(true == m_OutputTrianglesFile.isEmpty()) { setErrorCondition(-382); notifyErrorMessage(getHumanLabel(), "The output Triangles file needs to be set", getErrorCondition()); } DataContainer::Pointer dataContainer = getDataContainerArray()->getPrereqDataContainer<AbstractFilter>(this, getDataContainerSelection()); if(getErrorCondition() < 0) { return; } TriangleGeom::Pointer triangles = dataContainer->getPrereqGeometry<TriangleGeom, AbstractFilter>(this); if(getErrorCondition() < 0) { return; } // We MUST have Nodes if (NULL == triangles->getVertices().get()) { setErrorCondition(-386); notifyErrorMessage(getHumanLabel(), "DataContainer Geometry missing Vertices", getErrorCondition()); } // We MUST have Triangles defined also. if (NULL == triangles->getTriangles().get()) { setErrorCondition(-387); notifyErrorMessage(getHumanLabel(), "DataContainer Geometry missing Triangles", getErrorCondition()); } }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- 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 LaplacianSmoothing::dataCheck() { TriangleGeom::Pointer triangles = getDataContainerArray()->getPrereqGeometryFromDataContainer<TriangleGeom, AbstractFilter>(this, getSurfaceMeshFaceLabelsArrayPath().getDataContainerName()); QVector<IDataArray::Pointer> faceDataArrays; QVector<IDataArray::Pointer> nodeDataArrays; if(getErrorCondition() >= 0) { faceDataArrays.push_back(triangles->getTriangles()); nodeDataArrays.push_back(triangles->getVertices()); } QVector<size_t> cDims(1, 1); m_SurfaceMeshNodeTypePtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int8_t>, AbstractFilter>(this, getSurfaceMeshNodeTypeArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ if( NULL != m_SurfaceMeshNodeTypePtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */ { m_SurfaceMeshNodeType = m_SurfaceMeshNodeTypePtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */ if(getErrorCondition() >= 0) { nodeDataArrays.push_back(m_SurfaceMeshNodeTypePtr.lock()); } cDims[0] = 2; m_SurfaceMeshFaceLabelsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this, getSurfaceMeshFaceLabelsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */ if( NULL != m_SurfaceMeshFaceLabelsPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */ { m_SurfaceMeshFaceLabels = m_SurfaceMeshFaceLabelsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */ if(getErrorCondition() >= 0) { faceDataArrays.push_back(m_SurfaceMeshFaceLabelsPtr.lock()); } getDataContainerArray()->validateNumberOfTuples<AbstractFilter>(this, faceDataArrays); getDataContainerArray()->validateNumberOfTuples<AbstractFilter>(this, nodeDataArrays); setSurfaceDataContainerName(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName()); }