| 224 | } |
| 225 | |
| 226 | ISurfaceVolumeField *newFieldFromFile(const std::string fieldFileName) const override |
| 227 | { |
| 228 | std::filebuf fb; |
| 229 | fb.open(fieldFileName, std::ios::in | std::ios::binary); |
| 230 | if (!fb.is_open()) |
| 231 | throw std::runtime_error("error: couldn't open file"); |
| 232 | std::istream is(&fb); |
| 233 | |
| 234 | auto size = strlen(FIELD_FILE_HEADER_STRING) + 1; |
| 235 | OPENPGL_ASSERT(size <= 256); |
| 236 | char buf[256]; |
| 237 | is.read(&buf[0], size); |
| 238 | if (!is) |
| 239 | throw std::runtime_error("error: invalid file header"); |
| 240 | #ifdef OPENPGL_STRICT_IO_VERSION_CHECKING |
| 241 | for (auto i = 0; i < size; i++) |
| 242 | { |
| 243 | if (buf[i] != FIELD_FILE_HEADER_STRING[i]) |
| 244 | throw std::runtime_error("error: invalid file header"); |
| 245 | } |
| 246 | #endif |
| 247 | PGL_SPATIAL_STRUCTURE_TYPE spatialStructureType; |
| 248 | is.read(reinterpret_cast<char *>(&spatialStructureType), sizeof(spatialStructureType)); |
| 249 | PGL_DIRECTIONAL_DISTRIBUTION_TYPE directionalDistributionType; |
| 250 | is.read(reinterpret_cast<char *>(&directionalDistributionType), sizeof(directionalDistributionType)); |
| 251 | |
| 252 | ISurfaceVolumeField *gField; |
| 253 | |
| 254 | if (spatialStructureType == PGL_SPATIAL_STRUCTURE_KDTREE && directionalDistributionType == PGL_DIRECTIONAL_DISTRIBUTION_PARALLAX_AWARE_VMM) |
| 255 | { |
| 256 | using DirectionalDistributionFactory = AdaptiveSplitAndMergeFactory<ParallaxAwareVonMisesFisherMixture<VecSize, 32, true>>; |
| 257 | using GuidingField = SurfaceVolumeField<VecSize, DirectionalDistributionFactory, KDTreePartitionBuilder, |
| 258 | VMMSurfaceSamplingDistribution<typename DirectionalDistributionFactory::Distribution, true>, |
| 259 | VMMVolumeSamplingDistribution<typename DirectionalDistributionFactory::Distribution, true>>; |
| 260 | |
| 261 | gField = (ISurfaceVolumeField *)new GuidingField(); |
| 262 | } |
| 263 | else if (spatialStructureType == PGL_SPATIAL_STRUCTURE_KDTREE && directionalDistributionType == PGL_DIRECTIONAL_DISTRIBUTION_VMM) |
| 264 | { |
| 265 | using DirectionalDistributionFactory = AdaptiveSplitAndMergeFactory<ParallaxAwareVonMisesFisherMixture<VecSize, 32, false>>; |
| 266 | using GuidingField = SurfaceVolumeField<VecSize, DirectionalDistributionFactory, KDTreePartitionBuilder, |
| 267 | VMMSurfaceSamplingDistribution<typename DirectionalDistributionFactory::Distribution, false>, |
| 268 | VMMVolumeSamplingDistribution<typename DirectionalDistributionFactory::Distribution, false>>; |
| 269 | |
| 270 | gField = (ISurfaceVolumeField *)new GuidingField(); |
| 271 | } |
| 272 | else if (spatialStructureType == PGL_SPATIAL_STRUCTURE_KDTREE && directionalDistributionType == PGL_DIRECTIONAL_DISTRIBUTION_QUADTREE) |
| 273 | { |
| 274 | using DirectionalDistributionFactory = DirectionalQuadtreeFactory<DirectionalQuadtree<SphereToSquareCylindrical>>; |
| 275 | using GuidingField = |
| 276 | SurfaceVolumeField<VecSize, DirectionalDistributionFactory, KDTreePartitionBuilder, DQTSurfaceSamplingDistribution<DirectionalDistributionFactory::Distribution>, |
| 277 | DQTVolumeSamplingDistribution<DirectionalDistributionFactory::Distribution>>; |
| 278 | |
| 279 | gField = (ISurfaceVolumeField *)new GuidingField(); |
| 280 | } |
| 281 | else |
| 282 | { |
| 283 | fb.close(); |