38 constexpr
auto ALMOST_ZERO = 1e-7f;
41 float _computeHalfArea(
const Boxf& bbox)
43 const auto size = bbox.getSize();
44 return size[0] * size[1] + size[0] * size[2] + size[1] * size[2];
55 const std::set<std::string> types = {
"xyz"};
56 return types.find(extension) != types.end();
64 std::stringstream stream(std::string(blob.data.begin(), blob.data.end()));
67 numlines = std::count(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>(),
'\n');
73 const auto name = fs::path({blob.name}).stem();
74 const auto materialId = 0;
75 model->createMaterial(materialId, name);
76 auto& spheres = model->getSpheres()[materialId];
78 const size_t startOffset = spheres.size();
79 spheres.reserve(spheres.size() + numlines);
84 std::stringstream msg;
86 while (std::getline(stream, line))
88 std::vector<float> lineData;
89 std::stringstream lineStream(line);
92 while (lineStream >> value)
93 lineData.push_back(value);
95 switch (lineData.size())
99 const Vector3f position(lineData[0], lineData[1], lineData[2]);
100 bbox.
merge(position);
103 model->addSphere(materialId, {position, 1});
107 throw std::runtime_error(
"Invalid content in line " + std::to_string(i + 1) +
": " + line);
109 callback.
updateProgress(msg.str(), i++ /
static_cast<float>(numlines));
116 const auto density4PI = 4 * M_PI * numlines / (
volume > ALMOST_ZERO ?
volume : _computeHalfArea(bbox));
118 const double meanRadius =
volume > ALMOST_ZERO ? std::pow((3. / density4PI), 1. / 3.) : std::sqrt(1 / density4PI);
121 for (i = 0; i < numlines; ++i)
122 spheres[i + startOffset].radius = meanRadius;
126 auto modelDescriptor = std::make_shared<ModelDescriptor>(std::move(model), blob.name);
127 modelDescriptor->setTransformation(transformation);
129 Property radiusProperty(
"radius", meanRadius, 0., meanRadius * 2., {
"Point size"});
131 [modelDesc = std::weak_ptr<ModelDescriptor>(modelDescriptor)](
const auto& property)
133 if (
auto modelDesc_ = modelDesc.lock())
135 const auto newRadius = property.template get<double>();
136 for (auto& sphere : modelDesc_->getModel().getSpheres()[materialId])
137 sphere.radius = newRadius;
142 modelDescriptor->setProperties(modelProperties);
143 return modelDescriptor;
149 std::ifstream file(storage);
152 return importFromBlob({
"xyz", storage, {std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()}},
153 callback, properties);
void merge(const Box< T > &aabb)
void updateProgress(const std::string &message, const float fraction) const
void setProperty(const Property &newProperty)
Scene object This object contains collections of geometries, materials and light sources that are use...
virtual PLATFORM_API ModelPtr createModel() const =0
Factory method to create an engine-specific model.
bool isSupported(const std::string &storage, const std::string &extension) const final
ModelDescriptorPtr importFromBlob(Blob &&blob, const LoaderProgress &callback, const PropertyMap &properties) const final
std::vector< std::string > getSupportedStorage() const final
std::string getName() const final
ModelDescriptorPtr importFromStorage(const std::string &storage, const LoaderProgress &callback, const PropertyMap &properties) const final
const std::string LOADER_NAME
std::string shortenString(const std::string &string, const size_t maxLength)
std::shared_ptr< ModelDescriptor > ModelDescriptorPtr
void onModified(const ModifiedCallback &callback)