示例#1
0
bool PointArray::loadLas(QString fileName, size_t maxPointCount,
                         std::vector<GeomField>& fields, V3d& offset,
                         size_t& npoints, uint64_t& totPoints,
                         Imath::Box3d& bbox, V3d& centroid)
{
    V3d Psum(0);
#ifdef DISPLAZ_USE_PDAL
    // Open file
    if (!pdal::FileUtils::fileExists(fileName.toAscii().constData()))
    {
        g_logger.info("File \"%s\" does not exist", fileName.toStdString() );
        return false;
    }
    std::unique_ptr<pdal::PipelineManager> manager(new pdal::PipelineManager);

    pdal::StageFactory factory;
    std::string driver = factory.inferReaderDriver(fileName.toStdString());
    manager->addReader(driver);

    pdal::Stage* reader = static_cast<pdal::Reader*>(manager->getStage());
    pdal::Options options;
    pdal::Option fname("filename", fileName.toStdString());
    options.add(fname);
    reader->setOptions(options);

    manager->execute();
    pdal::PointBufferSet pbSet = manager->buffers();

    pdal::PointContext context = manager->context();
    bool hasColor = context.hasDim(pdal::Dimension::Id::Red);
    pdal::QuickInfo quickinfo = reader->preview();

    // Figure out how much to decimate the point cloud.
    totPoints = quickinfo.m_pointCount;
    size_t decimate = totPoints == 0 ? 1 : 1 + (totPoints - 1) / maxPointCount;
    if(decimate > 1)
    {
        g_logger.info("Decimating \"%s\" by factor of %d",
                      fileName.toStdString(), decimate);
    }
    npoints = (totPoints + decimate - 1) / decimate;
    pdal::BOX3D pdal_bounds = quickinfo.m_bounds;
    offset = V3d(0.5*(pdal_bounds.minx + pdal_bounds.maxx),
                 0.5*(pdal_bounds.miny + pdal_bounds.maxy),
                 0.5*(pdal_bounds.minz + pdal_bounds.maxz));
    // Attempt to place all data on the same vertical scale, but allow
    // other offsets if the magnitude of z is too large (and we would
    // therefore loose noticable precision by storing the data as floats)
    if (fabs(offset.z) < 10000)
        offset.z = 0;
    // Allocate all arrays
    fields.push_back(GeomField(TypeSpec::vec3float32(), "position", npoints));
    fields.push_back(GeomField(TypeSpec::uint16_i(), "intensity", npoints));
    fields.push_back(GeomField(TypeSpec::uint8_i(), "returnNumber", npoints));
    fields.push_back(GeomField(TypeSpec::uint8_i(), "numberOfReturns", npoints));
    fields.push_back(GeomField(TypeSpec::uint8_i(), "pointSourceId", npoints));
    fields.push_back(GeomField(TypeSpec::uint8_i(), "classification", npoints));
    // Output iterators for the output arrays
    V3f* position           = (V3f*)fields[0].as<float>();
    uint16_t* intensity     = fields[1].as<uint16_t>();
    uint8_t* returnNumber   = fields[2].as<uint8_t>();
    uint8_t* numReturns     = fields[3].as<uint8_t>();
    uint8_t* pointSourceId  = fields[4].as<uint8_t>();
    uint8_t* classification = fields[5].as<uint8_t>();
    uint16_t* color = 0;
    if (hasColor)
    {
        fields.push_back(GeomField(TypeSpec(TypeSpec::Uint,2,3,TypeSpec::Color),
                                        "color", npoints));
        color = fields.back().as<uint16_t>();
    }
    size_t readCount = 0;
    size_t storeCount = 0;
    size_t nextDecimateBlock = 1;
    size_t nextStore = 1;
    for (auto st = pbSet.begin(); st != pbSet.end(); ++st)
//     while (size_t numRead = chunkIter->read(buf))
    {
        pdal::PointBufferPtr buf = *st;
        for (size_t i = 0; i < buf->size(); ++i)
        {
            ++readCount;
            V3d P = V3d(buf->getFieldAs<double>(pdal::Dimension::Id::X, i),
                        buf->getFieldAs<double>(pdal::Dimension::Id::Y, i),
                        buf->getFieldAs<double>(pdal::Dimension::Id::Z, i));
//             V3d P = V3d(xDim.applyScaling(buf.getField<int32_t>(xDim, i)),
//                         yDim.applyScaling(buf.getField<int32_t>(yDim, i)),
//                         zDim.applyScaling(buf.getField<int32_t>(zDim, i)));
            bbox.extendBy(P);
            Psum += P;
            if(readCount < nextStore)
                continue;
            ++storeCount;
            // Store the point
            *position++ = P - offset;
            *intensity++   = buf->getFieldAs<uint16_t>(pdal::Dimension::Id::Intensity, i);
            *returnNumber++ = buf->getFieldAs<uint8_t>(pdal::Dimension::Id::ReturnNumber, i);
            *numReturns++  = buf->getFieldAs<uint8_t>(pdal::Dimension::Id::NumberOfReturns, i);
            *pointSourceId++ = buf->getFieldAs<uint8_t>(pdal::Dimension::Id::PointSourceId, i);
            *classification++ = buf->getFieldAs<uint8_t>(pdal::Dimension::Id::Classification, i);
            // Extract point RGB
            if (hasColor)
            {
                *color++ = buf->getFieldAs<uint16_t>(pdal::Dimension::Id::Red, i);
                *color++ = buf->getFieldAs<uint16_t>(pdal::Dimension::Id::Green, i);
                *color++ = buf->getFieldAs<uint16_t>(pdal::Dimension::Id::Blue, i);
            }
            // Figure out which point will be the next stored point.
            nextDecimateBlock += decimate;
            nextStore = nextDecimateBlock;
            if(decimate > 1)
            {
                // Randomize selected point within block to avoid repeated patterns
                nextStore += (qrand() % decimate);
                if(nextDecimateBlock <= totPoints && nextStore > totPoints)
                    nextStore = totPoints;
            }
        }
        emit loadProgress(100*readCount/totPoints);
    }
#else
    LASreadOpener lasReadOpener;
#ifdef _WIN32
    // Hack: liblas doesn't like forward slashes as path separators on windows
    fileName = fileName.replace('/', '\\');
#endif
    lasReadOpener.set_file_name(fileName.toAscii().constData());
    std::unique_ptr<LASreader> lasReader(lasReadOpener.open());

    if(!lasReader)
    {
        g_logger.error("Couldn't open file \"%s\"", fileName);
        return false;
    }

    //std::ofstream dumpFile("points.txt");
    // Figure out how much to decimate the point cloud.
    totPoints = std::max<uint64_t>(lasReader->header.extended_number_of_point_records,
                                   lasReader->header.number_of_point_records);
    size_t decimate = totPoints == 0 ? 1 : 1 + (totPoints - 1) / maxPointCount;
    if(decimate > 1)
    {
        g_logger.info("Decimating \"%s\" by factor of %d",
                        fileName.toStdString(), decimate);
    }
    npoints = (totPoints + decimate - 1) / decimate;
    offset = V3d(lasReader->header.min_x, lasReader->header.min_y, 0);
    // Attempt to place all data on the same vertical scale, but allow other
    // offsets if the magnitude of z is too large (and we would therefore loose
    // noticable precision by storing the data as floats)
    if (fabs(lasReader->header.min_z) > 10000)
        offset.z = lasReader->header.min_z;
    fields.push_back(GeomField(TypeSpec::vec3float32(), "position", npoints));
    fields.push_back(GeomField(TypeSpec::uint16_i(), "intensity", npoints));
    fields.push_back(GeomField(TypeSpec::uint8_i(), "returnNumber", npoints));
    fields.push_back(GeomField(TypeSpec::uint8_i(), "numberOfReturns", npoints));
    fields.push_back(GeomField(TypeSpec::uint8_i(), "pointSourceId", npoints));
    fields.push_back(GeomField(TypeSpec::uint8_i(), "classification", npoints));
    if (totPoints == 0)
    {
        g_logger.warning("File %s has zero points", fileName);
        return true;
    }
    // Iterate over all points & pull in the data.
    V3f* position           = (V3f*)fields[0].as<float>();
    uint16_t* intensity     = fields[1].as<uint16_t>();
    uint8_t* returnNumber   = fields[2].as<uint8_t>();
    uint8_t* numReturns     = fields[3].as<uint8_t>();
    uint8_t* pointSourceId  = fields[4].as<uint8_t>();
    uint8_t* classification = fields[5].as<uint8_t>();
    uint64_t readCount = 0;
    uint64_t nextDecimateBlock = 1;
    uint64_t nextStore = 1;
    size_t storeCount = 0;
    if (!lasReader->read_point())
        return false;
    const LASpoint& point = lasReader->point;
    uint16_t* color = 0;
    if (point.have_rgb)
    {
        fields.push_back(GeomField(TypeSpec(TypeSpec::Uint,2,3,TypeSpec::Color),
                                   "color", npoints));
        color = fields.back().as<uint16_t>();
    }
    do
    {
        // Read a point from the las file
        ++readCount;
        if(readCount % 10000 == 0)
            emit loadProgress(100*readCount/totPoints);
        V3d P = V3d(point.get_x(), point.get_y(), point.get_z());
        bbox.extendBy(P);
        Psum += P;
        if(readCount < nextStore)
            continue;
        ++storeCount;
        // Store the point
        *position++ = P - offset;
        // float intens = float(point.scan_angle_rank) / 40;
        *intensity++ = point.intensity;
        *returnNumber++ = point.return_number;
#       if LAS_TOOLS_VERSION >= 140315
        *numReturns++ = point.number_of_returns;
#       else
        *numReturns++ = point.number_of_returns_of_given_pulse;
#       endif
        *pointSourceId++ = point.point_source_ID;
        // Put flags back in classification byte to avoid memory bloat
        *classification++ = point.classification | (point.synthetic_flag << 5) |
                            (point.keypoint_flag << 6) | (point.withheld_flag << 7);
        // Extract point RGB
        if (color)
        {
            *color++ = point.rgb[0];
            *color++ = point.rgb[1];
            *color++ = point.rgb[2];
        }
        // Figure out which point will be the next stored point.
        nextDecimateBlock += decimate;
        nextStore = nextDecimateBlock;
        if(decimate > 1)
        {
            // Randomize selected point within block to avoid repeated patterns
            nextStore += (qrand() % decimate);
            if(nextDecimateBlock <= totPoints && nextStore > totPoints)
                nextStore = totPoints;
        }
    }
    while(lasReader->read_point());
    lasReader->close();
#endif
    if (readCount < totPoints)
    {
        g_logger.warning("Expected %d points in file \"%s\", got %d",
                         totPoints, fileName, readCount);
        npoints = storeCount;
        // Shrink all fields to fit - these will have wasted space at the end,
        // but that will be fixed during reordering.
        for (size_t i = 0; i < fields.size(); ++i)
            fields[i].size = npoints;
        totPoints = readCount;
    }
    if (totPoints > 0)
        centroid = (1.0/totPoints)*Psum;
    return true;
}
示例#2
0
bool
OSLCompilerImpl::compile (const std::string &filename,
                          const std::vector<std::string> &options,
                          const std::string &stdoslpath)
{
    if (! OIIO::Filesystem::exists (filename)) {
        error (ustring(), 0, "Input file \"%s\" not found", filename.c_str());
        return false;
    }

    std::string stdinclude;

#ifdef USE_BOOST_WAVE
    std::vector<std::string> defines;
    std::vector<std::string> includepaths;
#else
    std::string cppoptions;
#endif

    m_cwd = boost::filesystem::initial_path().string();
    m_main_filename = filename;

    // Determine where the installed shader include directory is, and
    // look for ../shaders/stdosl.h and force it to include.
    if (stdoslpath.empty()) {
        std::string program = OIIO::Sysutil::this_program_path ();
        if (program.size()) {
            boost::filesystem::path path (program);  // our program
            path = path.parent_path ();  // now the bin dir of our program
            path = path.parent_path ();  // now the parent dir
            path = path / "shaders";
            bool found = false;
            if (OIIO::Filesystem::exists (path.string())) {
#ifdef USE_BOOST_WAVE
                includepaths.push_back(path.string());
#else
                // pass along to cpp
                cppoptions += "\"-I";
                cppoptions += path.string();
                cppoptions += "\" ";
#endif
                path = path / "stdosl.h";
                if (OIIO::Filesystem::exists (path.string())) {
                    stdinclude = path.string();
                    found = true;
                }
            }
            if (! found)
                warning (ustring(filename), 0, "Unable to find \"%s\"",
                         path.string().c_str());
        }
    }
    else
        stdinclude = stdoslpath;

    m_output_filename.clear ();
    bool preprocess_only = false;
    for (size_t i = 0;  i < options.size();  ++i) {
        if (options[i] == "-v") {
            // verbose mode
            m_verbose = true;
        } else if (options[i] == "-q") {
            // quiet mode
            m_quiet = true;
        } else if (options[i] == "-d") {
            // debug mode
            m_debug = true;
        } else if (options[i] == "-E") {
            preprocess_only = true;
        } else if (options[i] == "-o" && i < options.size()-1) {
            ++i;
            m_output_filename = options[i];
        } else if (options[i] == "-O0") {
            m_optimizelevel = 0;
        } else if (options[i] == "-O" || options[i] == "-O1") {
            m_optimizelevel = 1;
        } else if (options[i] == "-O2") {
            m_optimizelevel = 2;
#ifdef USE_BOOST_WAVE
        } else if (options[i].c_str()[0] == '-' && options[i].size() > 2) {
            // options meant for the preprocessor
            if (options[i].c_str()[1] == 'D' || options[i].c_str()[1] == 'U')
                defines.push_back(options[i].substr(2));
            else if (options[i].c_str()[1] == 'I')
                includepaths.push_back(options[i].substr(2));
#else
        } else {
            // something meant for the cpp command
            cppoptions += "\"";
            cppoptions += options[i];
            cppoptions += "\" ";
#endif
        }
    }

    std::string preprocess_result;

#ifdef USE_BOOST_WAVE
    if (! preprocess(filename, stdinclude, defines, includepaths, preprocess_result)) {
#else
    if (! preprocess(filename, stdinclude, cppoptions, preprocess_result)) {
#endif
        return false;
    } else if (preprocess_only) {
        std::cout << preprocess_result;
    } else {
        std::istringstream in (preprocess_result);
        oslcompiler = this;

        // Create a lexer, parse the file, delete the lexer
        m_lexer = new oslFlexLexer (&in);
        oslparse ();
        bool parseerr = error_encountered();
        delete m_lexer;

        if (! parseerr) {
            if (shader())
                shader()->typecheck ();
            else
                error (ustring(), 0, "No shader function defined");
        }

        // Print the parse tree if there were no errors
        if (m_debug) {
            symtab().print ();
            if (shader())
                shader()->print (std::cout);
        }

        if (! error_encountered()) {
            shader()->codegen ();
//            add_useparam ();
            track_variable_dependencies ();
            track_variable_lifetimes ();
            check_for_illegal_writes ();
//            if (m_optimizelevel >= 1)
//                coalesce_temporaries ();
        }
 
        if (! error_encountered()) {
            if (m_output_filename.size() == 0)
                m_output_filename = default_output_filename ();
            write_oso_file (m_output_filename);
        }

        oslcompiler = NULL;
    }

    return ! error_encountered();
}



struct GlobalTable {
    const char *name;
    TypeSpec type;
};


void
OSLCompilerImpl::initialize_globals ()
{
    static GlobalTable globals[] = {
        { "P", TypeDesc::TypePoint },
        { "I", TypeDesc::TypeVector },
        { "N", TypeDesc::TypeNormal },
        { "Ng", TypeDesc::TypeNormal },
        { "u", TypeDesc::TypeFloat },
        { "v", TypeDesc::TypeFloat },
        { "dPdu", TypeDesc::TypeVector },
        { "dPdv", TypeDesc::TypeVector },
    #if 0
        // Light variables -- we don't seem to be on a route to support this
        // kind of light shader, so comment these out for now.
        { "L", TypeDesc::TypeVector },
        { "Cl", TypeDesc::TypeColor },
        { "Ns", TypeDesc::TypeNormal },
        { "Pl", TypeDesc::TypePoint },
        { "Nl", TypeDesc::TypeNormal },
    #endif
        { "Ps", TypeDesc::TypePoint },
        { "Ci", TypeSpec (TypeDesc::TypeColor, true) },
        { "time", TypeDesc::TypeFloat },
        { "dtime", TypeDesc::TypeFloat },
        { "dPdtime", TypeDesc::TypeVector },
        { NULL }
    };

    for (int i = 0;  globals[i].name;  ++i) {
        Symbol *s = new Symbol (ustring(globals[i].name), globals[i].type,
                                SymTypeGlobal);
        symtab().insert (s);
    }
}



std::string
OSLCompilerImpl::default_output_filename ()
{
    if (m_shader && shader_decl())
        return shader_decl()->shadername().string() + ".oso";
    return std::string();
}



void
OSLCompilerImpl::write_oso_metadata (const ASTNode *metanode) const
{
    ASSERT (metanode->nodetype() == ASTNode::variable_declaration_node);
    const ASTvariable_declaration *metavar = static_cast<const ASTvariable_declaration *>(metanode);
    Symbol *metasym = metavar->sym();
    ASSERT (metasym);
    TypeSpec ts = metasym->typespec();
    oso ("%%meta{%s,%s,", ts.string().c_str(), metasym->name().c_str());
    const ASTNode *init = metavar->init().get();
    ASSERT (init);
    if (ts.is_string() && init->nodetype() == ASTNode::literal_node)
        oso ("\"%s\"", ((const ASTliteral *)init)->strval());
    else if (ts.is_int() && init->nodetype() == ASTNode::literal_node)
        oso ("%d", ((const ASTliteral *)init)->intval());
    else if (ts.is_float() && init->nodetype() == ASTNode::literal_node)
        oso ("%.8g", ((const ASTliteral *)init)->floatval());
    // FIXME -- what about type constructors?
    else {
        std::cout << "Error, don't know how to print metadata " 
                  << ts.string() << " with node type " 
                  << init->nodetypename() << "\n";
        ASSERT (0);  // FIXME
    }
    oso ("} ");
}