// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void InsertAtoms::assign_points(QVector<VertexGeom::Pointer> points, QVector<BoolArrayType::Pointer> inFeature) { size_t count = 0; int32_t numFeatures = points.size(); for (int32_t i = 0; i < numFeatures; i++) { int64_t numPoints = points[i]->getNumberOfVertices(); bool* inside = inFeature[i]->getPointer(0); for (int64_t j = 0; j < numPoints; j++) { if (inside[j] == true) { count++; } } } DataContainer::Pointer v = getDataContainerArray()->getDataContainer(getVertexDataContainerName()); VertexGeom::Pointer vertices = VertexGeom::CreateGeometry(count, DREAM3D::VertexData::SurfaceMeshNodes); AttributeMatrix::Pointer vertexAttrMat = v->getAttributeMatrix(getVertexAttributeMatrixName()); QVector<size_t> tDims(1, count); vertexAttrMat->resizeAttributeArrays(tDims); updateVertexInstancePointers(); count = 0; float coords[3] = { 0.0f, 0.0f, 0.0f }; for (int32_t i = 0; i < numFeatures; i++) { int64_t numPoints = points[i]->getNumberOfVertices(); bool* inside = inFeature[i]->getPointer(0); for (int64_t j = 0; j < numPoints; j++) { if (inside[j] == true) { coords[0] = points[i]->getVertexPointer(j)[0]; coords[1] = points[i]->getVertexPointer(j)[1]; coords[2] = points[i]->getVertexPointer(j)[2]; vertices->setCoords(count, coords); m_AtomFeatureLabels[count] = i; count++; } } } v->setGeometry(vertices); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- VertexGeom::Pointer RegularGridSampleSurfaceMesh::generate_points() { VertexGeom::Pointer points = VertexGeom::CreateGeometry((m_XPoints * m_YPoints * m_ZPoints), "_INTERNAL_USE_ONLY_points"); int64_t count = 0; float coords[3] = { 0.0f, 0.0f, 0.0f }; for (int64_t k = 0; k < m_ZPoints; k++) { for (int64_t j = 0; j < m_YPoints; j++) { for (int64_t i = 0; i < m_XPoints; i++) { coords[0] = (float(i) + 0.5f) * m_Resolution.x + m_Origin.x; coords[1] = (float(j) + 0.5f) * m_Resolution.y + m_Origin.y; coords[2] = (float(k) + 0.5f) * m_Resolution.z + m_Origin.z; points->setCoords(count, coords); count++; } } } return points; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void InsertAtoms::execute() { setErrorCondition(0); dataCheck(); if(getErrorCondition() < 0) { return; } // Validate that the selected AvgQuats array has tuples equal to the largest // Feature Id; the filter would not crash otherwise, but the user should // be notified of unanticipated behavior ; this cannot be done in the dataCheck since // we don't have acces to the data yet int32_t numFeaturesIn = static_cast<int32_t>(m_AvgQuatsPtr.lock()->getNumberOfTuples()); bool mismatchedFeatures = true; int32_t largestFeature = 0; size_t numTuples = m_SurfaceMeshFaceLabelsPtr.lock()->getNumberOfTuples(); for (size_t i = 0; i < numTuples; i++) { if (m_SurfaceMeshFaceLabels[2 * i] > largestFeature) { largestFeature = m_SurfaceMeshFaceLabels[2 * i]; if (largestFeature >= numFeaturesIn) { mismatchedFeatures = true; break; } } else if (m_SurfaceMeshFaceLabels[2 * i + 1] > largestFeature) { largestFeature = m_SurfaceMeshFaceLabels[2 * i + 1]; if (largestFeature >= numFeaturesIn) { mismatchedFeatures = true; break; } } } if (mismatchedFeatures == true) { QString ss = QObject::tr("The number of Features in the AvgQuats array (%1) is larger than the largest Feature Id in the SurfaceMeshFaceLabels array").arg(numFeaturesIn); setErrorCondition(-5555); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } if (largestFeature != (numFeaturesIn - 1)) { QString ss = QObject::tr("The number of Features in the AvgQuats array (%1) does not match the largest Feature Id in the SurfaceMeshFaceLabels array").arg(numFeaturesIn); setErrorCondition(-5555); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } FloatVec3_t latticeConstants; latticeConstants.x = m_LatticeConstants.x / 10000.0; latticeConstants.y = m_LatticeConstants.y / 10000.0; latticeConstants.z = m_LatticeConstants.z / 10000.0; DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName()); SIMPL_RANDOMNG_NEW() #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS tbb::task_scheduler_init init; bool doParallel = true; #endif // pull down faces TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>(); int64_t numFaces = m_SurfaceMeshFaceLabelsPtr.lock()->getNumberOfTuples(); // create array to hold bounding vertices for each face FloatArrayType::Pointer llPtr = FloatArrayType::CreateArray(3, "Lower_Left_Internal_Use_Only"); FloatArrayType::Pointer urPtr = FloatArrayType::CreateArray(3, "Upper_Right_Internal_Use_Only"); float* ll = llPtr->getPointer(0); float* ur = urPtr->getPointer(0); VertexGeom::Pointer faceBBs = VertexGeom::CreateGeometry(2 * numFaces, "faceBBs"); // walk through faces to see how many features there are int32_t g1 = 0, g2 = 0; int32_t maxFeatureId = 0; for (int64_t i = 0; i < numFaces; i++) { g1 = m_SurfaceMeshFaceLabels[2 * i]; g2 = m_SurfaceMeshFaceLabels[2 * i + 1]; if (g1 > maxFeatureId) { maxFeatureId = g1; } if (g2 > maxFeatureId) { maxFeatureId = g2; } } // add one to account for feature 0 int32_t numFeatures = maxFeatureId + 1; // create a dynamic list array to hold face lists Int32Int32DynamicListArray::Pointer faceLists = Int32Int32DynamicListArray::New(); QVector<int32_t> linkCount(numFeatures, 0); // fill out lists with number of references to cells typedef boost::shared_array<int32_t> SharedInt32Array_t; SharedInt32Array_t linkLocPtr(new int32_t[numFaces]); int32_t* linkLoc = linkLocPtr.get(); ::memset(linkLoc, 0, numFaces * sizeof(int32_t)); // traverse data to determine number of faces belonging to each feature for (int64_t i = 0; i < numFaces; i++) { g1 = m_SurfaceMeshFaceLabels[2 * i]; g2 = m_SurfaceMeshFaceLabels[2 * i + 1]; if (g1 > 0) { linkCount[g1]++; } if (g2 > 0) { linkCount[g2]++; } } // now allocate storage for the faces faceLists->allocateLists(linkCount); // traverse data again to get the faces belonging to each feature for (int64_t i = 0; i < numFaces; i++) { g1 = m_SurfaceMeshFaceLabels[2 * i]; g2 = m_SurfaceMeshFaceLabels[2 * i + 1]; if (g1 > 0) { faceLists->insertCellReference(g1, (linkLoc[g1])++, i); } if (g2 > 0) { faceLists->insertCellReference(g2, (linkLoc[g2])++, i); } // find bounding box for each face GeometryMath::FindBoundingBoxOfFace(triangleGeom, i, ll, ur); faceBBs->setCoords(2 * i, ll); faceBBs->setCoords(2 * i + 1, ur); } // generate the list of sampling points fom subclass QVector<VertexGeom::Pointer> points(numFeatures); QVector<BoolArrayType::Pointer> inFeature(numFeatures); for (int32_t i = 0; i < numFeatures; i++) { points[i] = VertexGeom::CreateGeometry(0, "_INTERNAL_USE_ONLY_points"); inFeature[i] = BoolArrayType::CreateArray(0, "_INTERNAL_USE_ONLY_inside"); } QuatF* avgQuats = reinterpret_cast<QuatF*>(m_AvgQuats); #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS if (doParallel == true) { tbb::parallel_for(tbb::blocked_range<size_t>(0, numFeatures), InsertAtomsImpl(triangleGeom, faceLists, faceBBs, avgQuats, latticeConstants, m_Basis, points, inFeature), tbb::auto_partitioner()); } else #endif { InsertAtomsImpl serial(triangleGeom, faceLists, faceBBs, avgQuats, latticeConstants, m_Basis, points, inFeature); serial.checkPoints(0, numFeatures); } assign_points(points, inFeature); notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void SampleSurfaceMesh::execute() { setErrorCondition(0); dataCheck(); if(getErrorCondition() < 0) { return; } DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(m_SurfaceMeshFaceLabelsArrayPath.getDataContainerName()); SIMPL_RANDOMNG_NEW() #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS tbb::task_scheduler_init init; bool doParallel = true; #endif TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>(); // pull down faces int64_t numFaces = m_SurfaceMeshFaceLabelsPtr.lock()->getNumberOfTuples(); // create array to hold bounding vertices for each face FloatArrayType::Pointer llPtr = FloatArrayType::CreateArray(3, "_INTERNAL_USE_ONLY_Lower_Left"); FloatArrayType::Pointer urPtr = FloatArrayType::CreateArray(3, "_INTERNAL_USE_ONLY_Upper_Right"); float* ll = llPtr->getPointer(0); float* ur = urPtr->getPointer(0); VertexGeom::Pointer faceBBs = VertexGeom::CreateGeometry(2 * numFaces, "_INTERNAL_USE_ONLY_faceBBs"); // walk through faces to see how many features there are int32_t g1 = 0, g2 = 0; int32_t maxFeatureId = 0; for (int64_t i = 0; i < numFaces; i++) { g1 = m_SurfaceMeshFaceLabels[2 * i]; g2 = m_SurfaceMeshFaceLabels[2 * i + 1]; if (g1 > maxFeatureId) { maxFeatureId = g1; } if (g2 > maxFeatureId) { maxFeatureId = g2; } } // add one to account for feature 0 int32_t numFeatures = maxFeatureId + 1; // create a dynamic list array to hold face lists Int32Int32DynamicListArray::Pointer faceLists = Int32Int32DynamicListArray::New(); std::vector<int32_t> linkCount(numFeatures, 0); // fill out lists with number of references to cells typedef boost::shared_array<int32_t> SharedInt32Array_t; SharedInt32Array_t linkLocPtr(new int32_t[numFaces]); int32_t* linkLoc = linkLocPtr.get(); ::memset(linkLoc, 0, numFaces * sizeof(int32_t)); // traverse data to determine number of faces belonging to each feature for (int64_t i = 0; i < numFaces; i++) { g1 = m_SurfaceMeshFaceLabels[2 * i]; g2 = m_SurfaceMeshFaceLabels[2 * i + 1]; if (g1 > 0) { linkCount[g1]++; } if (g2 > 0) { linkCount[g2]++; } } // now allocate storage for the faces faceLists->allocateLists(linkCount); // traverse data again to get the faces belonging to each feature for (int64_t i = 0; i < numFaces; i++) { g1 = m_SurfaceMeshFaceLabels[2 * i]; g2 = m_SurfaceMeshFaceLabels[2 * i + 1]; if (g1 > 0) { faceLists->insertCellReference(g1, (linkLoc[g1])++, i); } if (g2 > 0) { faceLists->insertCellReference(g2, (linkLoc[g2])++, i); } // find bounding box for each face GeometryMath::FindBoundingBoxOfFace(triangleGeom, i, ll, ur); faceBBs->setCoords(2 * i, ll); faceBBs->setCoords(2 * i + 1, ur); } // generate the list of sampling points from subclass VertexGeom::Pointer points = generate_points(); if(getErrorCondition() < 0 || NULL == points.get()) { return; } int64_t numPoints = points->getNumberOfVertices(); // create array to hold which polyhedron (feature) each point falls in Int32ArrayType::Pointer iArray = Int32ArrayType::NullPointer(); iArray = Int32ArrayType::CreateArray(numPoints, "_INTERNAL_USE_ONLY_polyhedronIds"); iArray->initializeWithZeros(); int32_t* polyIds = iArray->getPointer(0); #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS if (doParallel == true) { tbb::parallel_for(tbb::blocked_range<size_t>(0, numFeatures), SampleSurfaceMeshImpl(triangleGeom, faceLists, faceBBs, points, polyIds), tbb::auto_partitioner()); } else #endif { SampleSurfaceMeshImpl serial(triangleGeom, faceLists, faceBBs, points, polyIds); serial.checkPoints(0, numFeatures); } assign_points(iArray); notifyStatusMessage(getHumanLabel(), "Complete"); }