void Geometry::lookUpGeometriesWithTypes(const std::vector<std::type_index>& types, std::function<void (const Geometry* geometry)> f) const { for (auto& geometry : geometries()) { geometry->lookUpGeometriesWithTypes(types, f); if (std::find(types.begin(), types.end(), std::type_index(typeid(*geometry.get()))) != types.end()) f(geometry.get()); } }
bool Cube::save(QString const& filePath, Data::Bank& bank) { // Make sure we have the required data QList<Data::Geometry*> geometries(bank.findData<Data::Geometry>()); if (geometries.isEmpty()) { m_errors.append("No geometry information found"); return false; }else if (geometries.size() > 1) { QLOG_WARN() << "Ambiguous geometry information found in Cube parser"; } Data::Geometry* geometry(geometries.first()); QList<Data::GridData*> grids(bank.findData<Data::GridData>()); if (grids.isEmpty()) { m_errors.append("No grid data found"); return false; }else if (grids.size() > 1) { QLOG_WARN() << "More than one grid specified in Cube parser"; } Data::GridData* grid(grids.first()); QFile file(filePath); if (file.exists() || !file.open(QIODevice::WriteOnly)) { m_errors.append("Failed to open file for write"); return false; } QStringList header; header << "Cube file for " + grid->surfaceType().toString(); header << "Generated using IQmol"; QStringList coords(formatCoordinates(*geometry)); unsigned nx, ny, nz; grid->getNumberOfPoints(nx, ny, nz); qglviewer::Vec delta(grid->delta()); qglviewer::Vec origin(grid->origin()); origin *= Constants::AngstromToBohr; header << QString("%1 %2 %3 %4").arg(coords.size(), 5) .arg(origin.x, 13, 'f', 6) .arg(origin.y, 13, 'f', 6) .arg(origin.z, 13, 'f', 6); header << QString("%1 %2 %3 %4").arg(nx, 5).arg(delta.x, 13, 'f', 6) .arg(0.0, 13, 'f', 6) .arg(0.0, 13, 'f', 6); header << QString("%1 %2 %3 %4").arg(ny, 5).arg(0.0, 13, 'f', 6) .arg(delta.y, 13, 'f', 6) .arg(0.0, 13, 'f', 6); header << QString("%1 %2 %3 %4").arg(nz, 5).arg(0.0, 13, 'f', 6) .arg(0.0, 13, 'f', 6) .arg(delta.z, 13, 'f', 6); header << coords; QByteArray buffer; buffer.append(header.join("\n")); buffer.append("\n"); file.write(buffer); buffer.clear(); double w; unsigned col(0); for (unsigned i = 0; i < nx; ++i) { for (unsigned j = 0; j < ny; ++j) { for (unsigned k = 0; k < nz; ++k, ++col) { w = (*grid)(i, j, k); if (w >= 0.0) buffer += " "; buffer += QString::number(w, 'E', 5); if (col == 5) { col = -1; buffer += "\n"; }else { buffer += " "; } } file.write(buffer); buffer.clear(); } } buffer += "\n"; file.write(buffer); file.flush(); file.close(); return true; }
Buffer compile_collider(const char* json, CompileOptions& opts) { TempAllocator4096 ta; JsonObject obj(ta); sjson::parse(json, obj); DynamicString type(ta); sjson::parse_string(obj["shape"], type); ColliderType::Enum st = shape_type_to_enum(type.c_str()); RESOURCE_COMPILER_ASSERT(st != ColliderType::COUNT , opts , "Unknown shape type: '%s'" , type.c_str() ); ColliderDesc cd; cd.type = st; cd.shape_class = sjson::parse_string_id(obj["class"]); cd.material = sjson::parse_string_id(obj["material"]); cd.local_tm = MATRIX4X4_IDENTITY; cd.size = 0; DynamicString scene(ta); DynamicString name(ta); sjson::parse_string(obj["scene"], scene); sjson::parse_string(obj["name"], name); RESOURCE_COMPILER_ASSERT_RESOURCE_EXISTS(RESOURCE_EXTENSION_MESH, scene.c_str(), opts); scene += "." RESOURCE_EXTENSION_MESH; Buffer file = opts.read(scene.c_str()); JsonObject json_mesh(ta); JsonObject geometries(ta); JsonObject nodes(ta); JsonObject node(ta); sjson::parse(file, json_mesh); sjson::parse(json_mesh["geometries"], geometries); sjson::parse(json_mesh["nodes"], nodes); sjson::parse(nodes[name.c_str()], node); const char* mesh = geometries[name.c_str()]; Matrix4x4 matrix_local = sjson::parse_matrix4x4(node["matrix_local"]); cd.local_tm = matrix_local; Array<Vector3> mesh_data(default_allocator()); switch (cd.type) { case ColliderType::SPHERE: compile_sphere(mesh, cd); break; case ColliderType::CAPSULE: compile_capsule(mesh, cd); break; case ColliderType::BOX: compile_box(mesh, cd); break; case ColliderType::CONVEX_HULL: compile_convex_hull(mesh, mesh_data); break; case ColliderType::MESH: case ColliderType::HEIGHTFIELD: { RESOURCE_COMPILER_ASSERT(false, opts, "Not implemented yet"); break; } } cd.size = sizeof(Vector3)*array::size(mesh_data); Buffer buf(default_allocator()); array::push(buf, (char*)&cd, sizeof(cd)); if (array::size(mesh_data)) array::push(buf, (char*)array::begin(mesh_data), sizeof(Vector3)*array::size(mesh_data)); return buf; }