bool CachingTargetCalculator::get_surface_target( PatchData& pd, size_t element, Sample sample, MsqMatrix<3,2>& W_out, MsqError& err ) { CachedTargetData& data = get_data( pd ); if (data.targetsSurface.empty()) { if (!have_surface_orient()) { MSQ_SETERR(err)("Incorrect surface mesh target type", MsqError::INTERNAL_ERROR ); return false; } populate_data( pd, &data, cachedCalculator, err ); MSQ_ERRZERO(err); if (data.targetsSurface.empty()) { MSQ_SETERR(err)("Attempt to get 2D target for 3D element type", MsqError::INVALID_STATE); return false; } } // calculate index of sample in array NodeSet all_samples = pd.get_samples( element ); unsigned offset = all_samples.num_before( sample ); W_out = data.targetsSurface[ data.elementOffsets[element] + offset ]; return true; }
bool LVQDTargetCalculator::get_surface_target( PatchData& pd, size_t element, Sample sample, MsqMatrix<3,2>& W_out, MsqError& err ) { double lambda[4]; MsqMatrix<3,2> V[4], W; MsqMatrix<2,2> Q[4], delta[4], junk, W2; bool valid; if (!have_surface_orient()) { MSQ_SETERR(err)("Incorrect surface mesh target type", MsqError::INTERNAL_ERROR ); return false; } for (int i = 0; i < numUniqueGuides; ++i) { valid = evaluate_guide_2D( pd, element, sample, i, lambda[i], V[i], Q[i], delta[i], err ); if (MSQ_CHKERR(err) || !valid) return false; } if (vIdx >= 0) { W_out = V[vIdx]; if (lambdaIdx >= 0) W_out *= lambda[lambdaIdx]; if (qIdx >= 0) W_out = W_out * Q[qIdx]; if (deltaIdx >= 0) W_out = W_out * delta[deltaIdx]; } else if (qIdx >= 0) { W_out(0,0) = Q[qIdx](0,0); W_out(0,1) = Q[qIdx](0,1); W_out(1,0) = Q[qIdx](1,0); W_out(1,1) = Q[qIdx](1,1); W_out(2,0) = 0.0; W_out(2,1) = 0.0; if (lambdaIdx >= 0) W_out *= lambda[lambdaIdx]; if (deltaIdx >= 0) W_out = W_out * delta[deltaIdx]; } else if (deltaIdx >= 0) { W_out(0,0) = delta[deltaIdx](0,0); W_out(0,1) = delta[deltaIdx](0,1); W_out(1,0) = delta[deltaIdx](1,0); W_out(1,1) = delta[deltaIdx](1,1); W_out(2,0) = 0.0; W_out(2,1) = 0.0; if (lambdaIdx >= 0) W_out *= lambda[lambdaIdx]; } else if (lambdaIdx >= 0) { W_out = MsqMatrix<3,2>(lambda[lambdaIdx]); } else { W_out = MsqMatrix<3,2>(1.0); } return true; }
void CachingTargetCalculator::notify_sub_patch( PatchData& , CachedTargetData& data, PatchData& subpatch, const size_t* , const size_t* element_map, MsqError& err ) { // If no cached data for this patch, just return if (data.has_data()) return; // Create a new cached data object on the subpatch CachedTargetData& sub_data = get_data( subpatch ); sub_data.clear(); // populate the element offset list, and count the total // number of cached target matrices. sub_data.elementOffsets.resize( subpatch.num_elements() ); size_t count_2D = 0, count_3D = 0; for (size_t i = 0; i < subpatch.num_elements(); ++i) { EntityTopology type = subpatch.element_by_index(i).get_element_type(); size_t& count = (TopologyInfo::dimension( type ) == 2) ? count_2D : count_3D; sub_data.elementOffsets[i] = count; NodeSet samples = subpatch.get_samples( i ); count += samples.num_nodes(); } const bool orient = have_surface_orient(); sub_data.targets3D.resize( count_3D ); if (orient) sub_data.targetsSurface.resize( count_2D ); else sub_data.targets2D.resize( count_2D ); for (size_t i = 0; i < subpatch.num_elements(); ++i) { EntityTopology type = subpatch.element_by_index(i).get_element_type(); size_t off = sub_data.elementOffsets[i]; size_t old_off = data.elementOffsets[element_map[i]]; NodeSet samples = subpatch.get_samples( i ); size_t count = samples.num_nodes(); if (TopologyInfo::dimension( type ) == 3) memcpy( &sub_data.targets3D[off], &data.targets3D[old_off], count*sizeof(MsqMatrix<3,3>) ); else if (orient) memcpy( &sub_data.targetsSurface[off], &data.targetsSurface[old_off], count*sizeof(MsqMatrix<3,2>) ); else memcpy( &sub_data.targets2D[off], &data.targets2D[old_off], count*sizeof(MsqMatrix<2,2>) ); } }