Exemplo n.º 1
0
void AsciiOpenDlg::updateTable(const QString &separator)
{
    tableWidget->setEnabled(false);
    extractSFNamesFrom1stLineCheckBox->setEnabled(false);
    m_headerLine.clear();

    if (m_filename.isEmpty())
    {
        tableWidget->clear();
        return;
    }

    if (separator.length()<1)
    {
        asciiCodeLabel->setText("Enter a valid character!");
        buttonBox->setEnabled(false);
        tableWidget->clear();
        m_invalidColumns = true;
        return;
    }

    //we open the file in ASCII mode
    FILE* pFile = fopen(qPrintable(m_filename),"rt");
    if (!pFile)
    {
        tableWidget->clear();
        m_invalidColumns = true;
        return;
    }

    //buffer
    char line[MAX_ASCII_FILE_LINE_LENGTH];      //last read line

    //we skip first lines (if needed)
    unsigned i;
    for (i=0; i<m_skippedLines; ++i)
    {
        if (fgets(line, MAX_ASCII_FILE_LINE_LENGTH, pFile))
        {
            //we keep track of the first line
            if (i==0)
                m_headerLine = QString(line);
        }
        else
        {
            fclose(pFile);
            tableWidget->clear();
            m_invalidColumns = true;
            return;
        }
    }

    //new separator
    m_separator = separator[0];
    asciiCodeLabel->setText(QString("(ASCII code: %1)").arg(m_separator.unicode()));
    //if the old setup has less than 3 columns, we forget it
    if (m_columnsCount<3)
    {
        tableWidget->clear();
        m_columnsCount=0;
    }
    tableWidget->setRowCount(DISPLAYED_LINES+1);    //+1 for first line shifting

    unsigned lineCount = 0;			//number of lines read
    unsigned totalChars = 0;        //total read characters (for stats)
    unsigned columnsCount = 0;		//max columns count per line

    std::vector<bool> valueIsNumber;	//identifies columns with numbers only [mandatory]
    std::vector<bool> valueIsBelowOne;	//identifies columns with values between -1 and 1 only
    std::vector<bool> valueIsInteger;	//identifies columns with integer values only
    std::vector<bool> valueIsBelow255;	//identifies columns with integer values between 0 and 255 only

    while ((lineCount<LINES_READ_FOR_STATS) && fgets(line, MAX_ASCII_FILE_LINE_LENGTH, pFile))
    {
        //we convert char buffer to a QString object
        QString str(line);

        //we recognize "//" as comment
        if (line[0]!='/' || line[1]!='/')
        {
            QStringList parts = str.trimmed().split(m_separator,QString::SkipEmptyParts);
            unsigned partsCount = (unsigned)parts.size();
            if (partsCount>MAX_COLUMNS)
                partsCount=MAX_COLUMNS;

            if (lineCount<DISPLAYED_LINES)
            {
                //do we need to add one or several new columns?
                if (partsCount>columnsCount)
                {
                    //we also extend vectors
                    for (i=columnsCount; i<partsCount; ++i)
                    {
                        valueIsNumber.push_back(true);
                        valueIsBelowOne.push_back(true);
                        valueIsBelow255.push_back(true);
                        valueIsInteger.push_back(true);
                    }

                    tableWidget->setColumnCount(partsCount);
                    columnsCount=partsCount;
                }

                //we fill row with extracted parts
                for (i=0; i<partsCount; ++i)
                {
                    QTableWidgetItem *newItem = new QTableWidgetItem(parts[i]);

                    //test values
                    bool isANumber = false;
                    double value = parts[i].toDouble(&isANumber);
                    if (!isANumber)
                    {
                        valueIsNumber[i]	= false;
                        valueIsBelowOne[i]	= false;
                        valueIsInteger[i]	= false;
                        valueIsBelow255[i]	= false;
                        newItem->setBackground(QBrush(QColor(255,160,160)));
                    }
                    else
                    {
                        double intPart, fracPart;
                        fracPart = modf(value,&intPart);

                        valueIsBelowOne[i]	= valueIsBelowOne[i] && (fabs(value)<=1.0);
                        valueIsInteger[i]	= valueIsInteger[i] && (fracPart == 0.0);
                        valueIsBelow255[i]	= valueIsBelow255[i] && (valueIsInteger[i] && (intPart >= 0.0 && value<=255.0));
                    }

                    tableWidget->setItem(lineCount+1, i, newItem); //+1 for first line shifting
                }
            }

            totalChars += (str.size()+1); //+1 for return char at eol

            ++lineCount;
        }
    }

    fclose(pFile);
    pFile=0;

    if (lineCount==0 || columnsCount==0)
    {
        m_averageLineSize = -1.0;
        tableWidget->clear();
        m_invalidColumns = true;
        return;
    }

    //average line size
    m_averageLineSize = double(totalChars)/double(lineCount);

    //we add a type selector for each column
    QStringList propsText;
    for (i=0; i<ASCII_OPEN_DLG_TYPES_NUMBER; i++)
        propsText << QString(ASCII_OPEN_DLG_TYPES_NAMES[i]);

    //remove unnecessary columns
    while (columnsCount<m_columnsCount)
        tableWidget->removeColumn(--m_columnsCount);
    for (i=lineCount+1; i<=DISPLAYED_LINES; ++i)
        tableWidget->removeRow(i);

    int columnWidth = (tableWidget->width()*9) / (columnsCount*10);
    columnWidth = ccMax(columnWidth,80);

    //Icons
    const QIcon xIcon(QString::fromUtf8(":/CC/Types/images/types/x_coordinate.png"));
    const QIcon yIcon(QString::fromUtf8(":/CC/Types/images/types/y_coordinate.png"));
    const QIcon zIcon(QString::fromUtf8(":/CC/Types/images/types/z_coordinate.png"));
    const QIcon NormIcon(QString::fromUtf8(":/CC/Types/images/types/normal.png"));
    const QIcon RGBIcon(QString::fromUtf8(":/CC/Types/images/types/rgb_color.png"));
    const QIcon GreyIcon(QString::fromUtf8(":/CC/Types/images/types/gray_color.png"));
    const QIcon ScalarIcon(QString::fromUtf8(":/CC/Types/images/types/scalar_field.png"));
    const QIcon PositiveScalarIcon(QString::fromUtf8(":/CC/Types/images/types/positive_scalar_field.png"));

    unsigned assignedXYZ = 0;
    unsigned assignedNorm = 0;
    unsigned assignedRGB = 0;
    for (i=0; i<columnsCount; i++)
    {
        QComboBox* columnHeader = static_cast<QComboBox*>(tableWidget->cellWidget(0,i));
        QComboBox* _columnHeader = columnHeader;
        if (!columnHeader)
        {
            columnHeader = new QComboBox();
            columnHeader->addItems(propsText);
            columnHeader->setMaxVisibleItems(ASCII_OPEN_DLG_TYPES_NUMBER);
            columnHeader->setCurrentIndex(0);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_X,xIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_Y,yIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_Z,zIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_NX,NormIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_NY,NormIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_NZ,NormIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_R,RGBIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_G,RGBIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_B,RGBIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_Grey,GreyIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_Scalar,ScalarIcon);
            columnHeader->setItemIcon(ASCII_OPEN_DLG_Positive_Scalar,PositiveScalarIcon);

            connect(columnHeader, SIGNAL(currentIndexChanged(int)), this, SLOT(columnsTypeHasChanged(int)));
        }

        if (valueIsNumber[i])
        {
            //first time? let's try to assign each column a type
            if ((m_invalidColumns || m_columnsCount==0) && columnsCount>1)
            {
                columnHeader->blockSignals(true);
                //by default, we assume that the first columns are always X,Y and Z
                if (assignedXYZ<3)
                {
                    //in rare cases, the first column is an index
                    if (assignedXYZ==0 && valueIsInteger[i] && (i+1<columnsCount) && !valueIsInteger[i+1])
                    {
                        //we skip it
                    }
                    else
                    {
                        ++assignedXYZ;
                        columnHeader->setCurrentIndex(assignedXYZ);
                    }
                }
                else
                {
                    //looks like RGB?
                    if (valueIsBelow255[i] && assignedRGB<3 && (i+2-assignedRGB < columnsCount)
                            && (assignedRGB > 0 || (valueIsBelow255[i+1] && valueIsBelow255[i+2]))) //make sure that next values are also ok!
                    {
                        columnHeader->setCurrentIndex(ASCII_OPEN_DLG_R+assignedRGB);
                        ++assignedRGB;
                    }
                    else if (valueIsBelowOne[i] && assignedNorm<3 && (i+2-assignedNorm < columnsCount)
                             && (assignedNorm > 0 || (valueIsBelowOne[i+1] && valueIsBelowOne[i+2]))) //make sure that next values are also ok!
                    {
                        columnHeader->setCurrentIndex(ASCII_OPEN_DLG_NX+assignedNorm);
                        ++assignedNorm;
                    }
                    else
                    {
                        //maybe it's a scalar?
                        columnHeader->setCurrentIndex(ASCII_OPEN_DLG_Scalar);
                    }
                }
                columnHeader->blockSignals(false);
            }
        }

        if (!_columnHeader)
            tableWidget->setCellWidget(0,i,columnHeader);
        tableWidget->setColumnWidth(i,columnWidth);
    }
Exemplo n.º 2
0
CC_FILE_ERROR PovFilter::saveToFile(ccHObject* entity, const char* filename)
{
    if (!entity || !filename)
        return CC_FERR_BAD_ARGUMENT;

    ccHObject::Container hClouds;
    entity->filterChildren(hClouds,false,CC_POINT_CLOUD);

    if (hClouds.empty())
        return CC_FERR_NO_SAVE;

    unsigned i;

    std::vector<ccGBLSensor*> sensors;
    std::vector<ccGenericPointCloud*> clouds;
    for (i=0;hClouds.size();++i)
    {
        ccHObject::Container cloudSensors;
        hClouds[i]->filterChildren(cloudSensors,false,CC_GBL_SENSOR);
        if (!cloudSensors.empty())
        {
            clouds.push_back(static_cast<ccGenericPointCloud*>(hClouds[i]));
            if (cloudSensors.size()>1)
                ccConsole::Warning(QString("Found more than one ground-based LIDAR sensor associated to entity '%1'. Only the first will be saved!").arg(hClouds[i]->getName()));

            sensors.push_back(static_cast<ccGBLSensor*>(cloudSensors[0]));
        }
    }
    assert(sensors.size() == clouds.size());

    if (sensors.empty())
        return CC_FERR_NO_SAVE;

    //FIXME
    //the first GLS sensor will be used as reference! (ugly)
    ccGBLSensor* firstGls = sensors.front();
    if (sensors.size()>1)
        ccConsole::Warning("Assuming all sensors are equivalent...");

    //we extract the body of the filename (without extension)
    int pointPos = CCLib::CCMiscTools::findCharLastOccurence('.',filename);
    if (pointPos<0)
        pointPos = strlen(filename);

    //main file (.POV)
    FILE* mainFile = fopen(filename,"wt");
    if (!mainFile)
        return CC_FERR_WRITING;

    if (fprintf(mainFile,"#CC_POVS_FILE\n")<0)
    {
        fclose(mainFile);
        return CC_FERR_WRITING;
    };
    if (fprintf(mainFile,"SENSOR_TYPE = %s\n",CCLib::CC_SENSOR_ROTATION_ORDER_NAMES[firstGls->getRotationOrder()])<0)
    {
        fclose(mainFile);
        return CC_FERR_WRITING;
    };
    if (fprintf(mainFile,"SENSOR_BASE = %f\n",firstGls->getSensorBase())<0)
    {
        fclose(mainFile);
        return CC_FERR_WRITING;
    };
    if (fprintf(mainFile,"UNITS = IGNORED\n")<0)
    {
        fclose(mainFile);
        return CC_FERR_WRITING;
    };
    if (fprintf(mainFile,"#END_HEADER\n")<0)
    {
        fclose(mainFile);
        return CC_FERR_WRITING;
    };

    //the files corresponding to the different points of view
    char baseFileName[1024];
    memcpy(baseFileName,filename,pointPos);
    baseFileName[pointPos]=0;

    for (i=0;i<clouds.size();++i)
    {
        char suffix[256];
        char baseNameCpy[256];
        strcpy(baseNameCpy,baseFileName);
        sprintf(suffix,"_%i.bin",i);
        strcat(baseNameCpy,suffix);
        /*FILE* f = fopen(baseNameCpy,"wt");

        if (!f)
        {
        	char buffer[1024];
        	ccConsole::Error("Couldn't create file (%s)!",baseNameCpy);
        	return CC_FERR_WRITING;
        }
        //*/

        //avancement du chargement
        /*char title[256];
        sprintf(title,"Saving list #%i POVs",aList->getListID());
        ProgressWindow* pwin = new ProgressWindow(title,true);
        float percent = 0.0;
        unsigned palier = unsigned(float(numberOfPoints) * 0.01); //1% du total
        unsigned n = 0;
        char buffer[256];
        sprintf(buffer,"Number of points = %i\nNumber of POV = %i",numberOfPoints,maxNumberOfScans);
        pwin->setMessage(buffer);
        scanIndexType theCurrentScanIndex=0;
        CCVector3* P;
        //*/

        CC_FILE_ERROR error = FileIOFilter::SaveToFile(clouds[i],baseNameCpy,BIN);
        if (error != CC_FERR_NO_ERROR)
        {
            fclose(mainFile);
            return error;
        }

        ccGBLSensor* gls = sensors[i];

        //il faut écrire le nom du fichier relatif et non absolu !
        int p = CCLib::CCMiscTools::findCharLastOccurence('/',baseNameCpy);
        int slashPos = ccMax(0,p);
        p = CCLib::CCMiscTools::length(baseNameCpy)-slashPos-1;
        int size = ccMax(0,p);
        char povFileName[1024];
        memcpy(povFileName,baseNameCpy+slashPos+1,size);
        povFileName[size]=0;
        int result = fprintf(mainFile,"\n#POV %i\nF %s\nT ASC\n",i,povFileName);

        if (result>0)
        {
            CCVector3 C = gls->getSensorCenter();
            result = fprintf(mainFile,"C %f %f %f\n",C[0],C[1],C[2]);

            CCLib::SquareMatrix* m = gls->getAxisMatrix();
            if (m && result>0)
            {
                result = fprintf(mainFile,"X %f %f %f\n",m->m_values[0][0],m->m_values[1][0],m->m_values[2][0]);
                result = fprintf(mainFile,"Y %f %f %f\n",m->m_values[0][1],m->m_values[1][1],m->m_values[2][1]);
                result = fprintf(mainFile,"Z %f %f %f\n",m->m_values[0][2],m->m_values[1][2],m->m_values[2][2]);
            }

            if (result>0)
                result = fprintf(mainFile,"A %f %f\n",gls->getDeltaPhi(),gls->getDeltaTheta());

            if (result>0)
                result = fprintf(mainFile,"#END_POV\n");
        }

        /*if (++n==palier)
        {
            //cancel requested
            if (pwin->isCancelRequested())
                result=-1;

            percent += 1.0;
            pwin->update(percent);
            n = 0;
        }
        //*/
    }

    //delete pwin;


    fclose(mainFile);

    return CC_FERR_NO_ERROR;

}