void ClassFactory::registerFieldMapping(CreateFieldMappingFnPtr createFunc) { // Make sure we don't add the same class twice bool nameExists = false; FieldMapping::Ptr instance = createFunc(); if (!instance) { Msg::print(Msg::SevWarning, "Unsuccessful attempt at registering FieldMapping class. " "(Creation function returned null pointer)"); return; } string className = instance->className(); FieldMappingFuncMap::const_iterator i = m_mappings.find(className); if (i != m_mappings.end()) nameExists = true; if (!nameExists) { m_mappings[className] = createFunc; // if the simple (untemplated) class name hasn't been registered // yet, add it to the list and print a message if (find(m_fieldMappingNames.begin(), m_fieldMappingNames.end(), className) == m_fieldMappingNames.end()) { m_fieldMappingNames.push_back(className); char *debugEnvVar = getenv("FIELD3D_DEBUG"); if (debugEnvVar) { Msg::print("Registered FieldMapping class " + className); } } } }
void SpherePrimitive::execute(Geo::Geometry::CPtr geometry, ScalarBuffer::Ptr buffer) const { Log::print("Rasterizing SpherePrimitive instances"); SamplingDerivatives wsDerivs; getDerivatives(buffer->mapping(), 0, 0, 0, wsDerivs); FieldMapping::Ptr mapping = buffer->mapping(); AttrVisitor visitor(geometry->particles()->pointAttrs(), m_params); Attr<V3f> wsCenter("P"); Attr<float> radius ("radius"); Attr<float> density ("density"); Timer timer; for (AttrVisitor::const_iterator i = visitor.begin(), end = visitor.end(); i != end; ++i) { // Check if user terminated Sys::Interrupt::throwOnAbort(); // Update per-point attributes i.update(wsCenter); i.update(radius); i.update(density); // Calculate rasterization bounds BBox vsBounds = calculateVsBounds(mapping, wsCenter.as<Vector>(), radius); DiscreteBBox dvsBounds = Math::discreteBounds(vsBounds); // Iterate over voxels for (ScalarBuffer::iterator i = buffer->begin(dvsBounds), end = buffer->end(dvsBounds); i != end; ++i) { Vector vsP = discToCont(V3i(i.x, i.y, i.z)), wsP; mapping->voxelToWorld(vsP, wsP); float value = evaluateSphere(wsP, wsCenter.as<Vector>(), radius, density, 0.9f); if (value > 0.0f) { *i += value; } } } Log::print("Sphere primitive processed " + str(points.size()) + " input points"); Log::print(" Time elapsed: " + str(timer.elapsed())); }
bool NullFieldMapping::isIdentical(FieldMapping::Ptr other, double /* tolerance */) const { // For null mappings it's simple - if the other one is also a null mapping // then true, otherwise it's false. return other->className() == k_nullMappingName; }
bool FrustumFieldMapping::isIdentical(FieldMapping::Ptr other, double tolerance) const { typedef MatrixFieldMapping::MatrixCurve::SampleVec SampleVec; if (other->className() != k_frustumMappingName) { return false; } else { FrustumFieldMapping::Ptr fm = FIELD_DYNAMIC_CAST<FrustumFieldMapping>(other); if (fm) { const SampleVec lpsToWs1 = m_lpsToWsCurve.samples(); const SampleVec lpsToWs2 = fm->m_lpsToWsCurve.samples(); const SampleVec csToWs1 = m_csToWsCurve.samples(); const SampleVec csToWs2 = fm->m_csToWsCurve.samples(); size_t numSamples = lpsToWs1.size(); // Check that slice distributions match if (m_zDistribution != fm->m_zDistribution) { return false; } // First check if time sample counts differ // lpsToWs and csToWs are guaranteed to have same sample count. if (lpsToWs1.size() != lpsToWs2.size()) { return false; } // Then check if all time samples match, then check localToWorld // and voxelToWorld matrices for (size_t i = 0; i < numSamples; ++i) { if (lpsToWs1[i].first != lpsToWs2[i].first) { return false; } if (!checkMatricesIdentical(lpsToWs1[i].second, lpsToWs2[i].second, tolerance)) { return false; } if (!checkMatricesIdentical(csToWs1[i].second, csToWs2[i].second, tolerance)) { return false; } } return true; } else { return false; } } return false; }
bool MatrixFieldMapping::isIdentical(FieldMapping::Ptr other, double tolerance) const { typedef MatrixFieldMapping::MatrixCurve::SampleVec SampleVec; if (other->className() != k_matrixMappingName) { return false; } else { MatrixFieldMapping::Ptr mm = FIELD_DYNAMIC_CAST<MatrixFieldMapping>(other); if (mm) { const SampleVec lsToWs1 = m_lsToWsCurve.samples(); const SampleVec lsToWs2 = mm->m_lsToWsCurve.samples(); const SampleVec vsToWs1 = m_vsToWsCurve.samples(); const SampleVec vsToWs2 = mm->m_vsToWsCurve.samples(); size_t numSamples = lsToWs1.size(); // First check if time sample counts differ // lsToWs and vsToWs are guaranteed to have same sample count. if (lsToWs1.size() != lsToWs2.size()) { return false; } // Then check if all time samples match, then check localToWorld // and voxelToWorld matrices for (size_t i = 0; i < numSamples; ++i) { if (lsToWs1[i].first != lsToWs2[i].first) { return false; } if (!checkMatricesIdentical(lsToWs1[i].second, lsToWs2[i].second, tolerance)) { return false; } if (!checkMatricesIdentical(vsToWs1[i].second, vsToWs2[i].second, tolerance)) { return false; } } return true; } else { return false; } } return false; }
void printMapping(FieldMapping::Ptr mapping) { cout << " Mapping:" << endl; cout << " Type: " << mapping->className() << endl; // In the case of a MatrixFieldMapping, we print the local to world matrix. MatrixFieldMapping::Ptr matrixMapping = boost::dynamic_pointer_cast<MatrixFieldMapping>(mapping); if (matrixMapping) { M44d m = matrixMapping->localToWorld(); cout << " Local to world transform:" << endl; for (int j = 0; j < 4; ++j) { cout << " "; for (int i = 0; i < 4; ++i) { cout << m[i][j] << " "; } cout << endl; } } }