// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void FeatureFaceCurvatureFilter::execute() { setErrorCondition(0); dataCheck(); if(getErrorCondition() < 0) { return; } DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName()); // Get our Reference counted Array of Face Structures TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>(); // Just to double check we have everything. int64_t numTriangles = triangleGeom->getNumberOfTris(); // Make sure the Face Connectivity is created because the FindNRing algorithm needs this and will // assert if the data is NOT in the SurfaceMesh Data Container ElementDynamicList::Pointer vertLinks = triangleGeom->getElementsContainingVert(); if (NULL == vertLinks.get()) { triangleGeom->findElementsContainingVert(); } // get the QMap from the SharedFeatureFaces filter SharedFeatureFaces_t sharedFeatureFaces; int32_t maxFaceId = 0; for (int64_t t = 0; t < numTriangles; ++t) { if (m_SurfaceMeshFeatureFaceIds[t] > maxFaceId) { maxFaceId = m_SurfaceMeshFeatureFaceIds[t]; } } std::vector<int32_t> faceSizes(maxFaceId + 1, 0); // Loop through all the Triangles and assign each one to a unique Feature Face Id. for (int64_t t = 0; t < numTriangles; ++t) { faceSizes[m_SurfaceMeshFeatureFaceIds[t]]++; } // Allocate all the vectors that we need for (size_t iter = 0; iter < faceSizes.size(); ++iter) { FaceIds_t v; v.reserve(faceSizes[iter]); sharedFeatureFaces[iter] = v; } // Loop through all the Triangles and assign each one to a unique Feature Face Id. for(int64_t t = 0; t < numTriangles; ++t) { sharedFeatureFaces[m_SurfaceMeshFeatureFaceIds[t]].push_back(t); } m_TotalFeatureFaces = sharedFeatureFaces.size(); m_CompletedFeatureFaces = 0; #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS tbb::task_scheduler_init init; bool doParallel = true; #endif #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS tbb::task_group* g = new tbb::task_group; #else #endif // typedef here for conveneince typedef SharedFeatureFaces_t::iterator SharedFeatureFaceIterator_t; for(SharedFeatureFaceIterator_t iter = sharedFeatureFaces.begin(); iter != sharedFeatureFaces.end(); ++iter) { QString ss = QObject::tr("Working on Face Id %1/%2").arg((*iter).first).arg(maxFaceId); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); FaceIds_t& triangleIds = (*iter).second; #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS if (doParallel == true) { g->run(CalculateTriangleGroupCurvatures(m_NRing, triangleIds, m_UseNormalsForCurveFitting, m_SurfaceMeshPrincipalCurvature1sPtr.lock(), m_SurfaceMeshPrincipalCurvature2sPtr.lock(), m_SurfaceMeshPrincipalDirection1sPtr.lock(), m_SurfaceMeshPrincipalDirection2sPtr.lock(), m_SurfaceMeshGaussianCurvaturesPtr.lock(), m_SurfaceMeshMeanCurvaturesPtr.lock(), triangleGeom, m_SurfaceMeshFaceLabelsPtr.lock(), m_SurfaceMeshFaceNormalsPtr.lock(), m_SurfaceMeshTriangleCentroidsPtr.lock(), this ) ); } else #endif { CalculateTriangleGroupCurvatures curvature(m_NRing, triangleIds, m_UseNormalsForCurveFitting, m_SurfaceMeshPrincipalCurvature1sPtr.lock(), m_SurfaceMeshPrincipalCurvature2sPtr.lock(), m_SurfaceMeshPrincipalDirection1sPtr.lock(), m_SurfaceMeshPrincipalDirection2sPtr.lock(), m_SurfaceMeshGaussianCurvaturesPtr.lock(), m_SurfaceMeshMeanCurvaturesPtr.lock(), triangleGeom, m_SurfaceMeshFaceLabelsPtr.lock(), m_SurfaceMeshFaceNormalsPtr.lock(), m_SurfaceMeshTriangleCentroidsPtr.lock(), this ); curvature(); } } // *********************** END END END END END END ******************************************************************** #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS g->wait(); // Wait for all the threads to complete before moving on. delete g; #endif /* Let the GUI know we are done with this filter */ notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int32_t FindNRingNeighbors::generate(TriangleGeom::Pointer triangleGeom, int32_t* faceLabels) { int64_t* triangles = triangleGeom->getTriPointer(0); int32_t err = 0; //Clear out all the previous triangles. m_NRingTriangles.clear(); // Make sure we have the proper connectivity built ElementDynamicList::Pointer node2TrianglePtr = triangleGeom->getElementsContainingVert(); if (node2TrianglePtr.get() == NULL) { err = triangleGeom->findElementsContainingVert(); if (err < 0) { return err; } node2TrianglePtr = triangleGeom->getElementsContainingVert(); } // Figure out these boolean values for a sanity check bool check0 = faceLabels[m_TriangleId * 2] == m_RegionId0 && faceLabels[m_TriangleId * 2 + 1] == m_RegionId1; bool check1 = faceLabels[m_TriangleId * 2 + 1] == m_RegionId0 && faceLabels[m_TriangleId * 2] == m_RegionId1; #if 1 if ( check0 == false && check1 == false) { qDebug() << "FindNRingNeighbors Seed triangle ID does not have a matching Region ID for " << m_RegionId0 << " & " << m_RegionId1 << "\n"; qDebug() << "Region Ids are: " << faceLabels[m_TriangleId * 2] << " & " << faceLabels[m_TriangleId * 2 + 1] << "\n"; return err; } #endif // Add our seed triangle m_NRingTriangles.insert(m_TriangleId); for (int64_t ring = 0; ring < m_Ring; ++ring) { // Make a copy of the 1 Ring Triangles that we just found so that we can use those triangles as the // seed triangles for the 2 Ring triangles UniqueFaceIds_t lcvTriangles(m_NRingTriangles); // Now that we have the 1 ring triangles, get the 2 Ring neighbors from that list for (UniqueFaceIds_t::iterator triIter = lcvTriangles.begin(); triIter != lcvTriangles.end(); ++triIter) { int64_t triangleIdx = *triIter; // For each node, get the triangle ids that the node belongs to for(int32_t i = 0; i < 3; ++i) { // Get all the triangles for this Node id uint16_t tCount = node2TrianglePtr->getNumberOfElements(triangles[triangleIdx * 3 + i]); int64_t* data = node2TrianglePtr->getElementListPointer(triangles[triangleIdx * 3 + i]); // Copy all the triangles into our "2Ring" set which will be the unique set of triangle ids for (uint16_t t = 0; t < tCount; ++t) { int64_t tid = data[t]; check0 = faceLabels[tid * 2] == m_RegionId0 && faceLabels[tid * 2 + 1] == m_RegionId1; check1 = faceLabels[tid * 2 + 1] == m_RegionId0 && faceLabels[tid * 2] == m_RegionId1; if (check0 == true || check1 == true) { m_NRingTriangles.insert(tid); } } } } } return err; }