void EditArc3DPlugin::ExportPly() { if (gla == NULL) return; md->setBusy(true); md->addNewMesh("",er.name,true); MeshModel* m=md->mm(); // Options collection int t0=clock(); int subSampleVal = arc3DDialog->ui.subsampleSpinBox->value(); int minCountVal= arc3DDialog->ui.minCountSpinBox->value(); float maxCCDiagVal= arc3DDialog->ui.maxCCDiagSpinBox->value(); int smoothSteps=arc3DDialog->ui.smoothSpinBox->value(); bool closeHole = arc3DDialog->ui.holeCheckBox->isChecked(); int maxHoleSize = arc3DDialog->ui.holeSpinBox->value(); CMeshO mm; QTableWidget *qtw=arc3DDialog->ui.imageTableWidget; float MinAngleCos=cos(vcg::math::ToRad(arc3DDialog->ui.qualitySpinBox->value())); bool removeSmallCC=arc3DDialog->ui.removeSmallCCCheckBox->isChecked(); //vcg::tri::Clustering<CMeshO, vcg::tri::AverageColorCell<CMeshO> > Grid; int selectedNum=0,selectedCount=0; int i; for(i=0;i<qtw->rowCount();++i) if(qtw->isItemSelected(qtw->item(i,0))) ++selectedNum; bool dilationFlag = arc3DDialog->ui.dilationCheckBox->isChecked(); int dilationN = arc3DDialog->ui.dilationNumPassSpinBox->value(); int dilationSz = arc3DDialog->ui.dilationSizeSlider->value() * 2 + 1; bool erosionFlag = arc3DDialog->ui.erosionCheckBox->isChecked(); int erosionN = arc3DDialog->ui.erosionNumPassSpinBox->value(); int erosionSz = arc3DDialog->ui.erosionSizeSlider->value() * 2 + 1; float scalingFactor = arc3DDialog->ui.scaleLineEdit->text().toFloat(); std::vector<string> savedMeshVector; // Generating a mesh for each selected image QList<Arc3DModel>::iterator li; for(li=er.modelList.begin(), i=0;li!=er.modelList.end();++li,++i) { if(qtw->isItemSelected(qtw->item(i,0))) { ++selectedCount; mm.Clear(); int tt0=clock(); (*li).BuildMesh(mm,subSampleVal,minCountVal,MinAngleCos,smoothSteps, dilationFlag, dilationN, dilationSz, erosionFlag, erosionN, erosionSz,scalingFactor); int tt1=clock(); this->Log(GLLogStream::SYSTEM,"** Mesh %i : Build in %i\n",selectedCount,tt1-tt0); m->cm.Clear(); tri::Append<CMeshO,CMeshO>::Mesh(m->cm,mm); // append mesh mr to ml int tt2=clock(); this->Log(GLLogStream::SYSTEM,"** Mesh %i : Append in %i\n",selectedCount,tt2-tt1); } } int t1=clock(); this->Log(GLLogStream::SYSTEM,"Extracted %i meshes in %i\n",selectedCount,t1-t0); ///// Removing connected components if(removeSmallCC) { m->updateDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEMARK); tri::Clean<CMeshO>::RemoveSmallConnectedComponentsDiameter(m->cm,m->cm.bbox.Diag()*maxCCDiagVal/100.0); } int t2=clock(); this->Log(GLLogStream::SYSTEM,"Topology and removed CC in %i\n",t2-t1); vcg::tri::UpdateBounding<CMeshO>::Box(m->cm); // updates bounding box // Hole filling if(closeHole) { m->updateDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEMARK); tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFace(m->cm); vcg::tri::Hole<CMeshO>::EarCuttingFill<vcg::tri::MinimumWeightEar< CMeshO> >(m->cm,maxHoleSize,false); } m->updateDataMask(MeshModel::MM_VERTCOLOR); Matrix44m transf; transf.SetRotateDeg(180,Point3m(1.0,0.0,0.0)); m->cm.Tr=transf; tri::UpdatePosition<CMeshO>::Matrix(m->cm, m->cm.Tr); tri::UpdateNormal<CMeshO>::PerVertexMatrix(m->cm,m->cm.Tr); tri::UpdateNormal<CMeshO>::PerFaceMatrix(m->cm,m->cm.Tr); tri::UpdateBounding<CMeshO>::Box(m->cm); m->cm.Tr.SetIdentity(); m->cm.shot.ApplyRigidTransformation(transf); int t3=clock(); this->Log(GLLogStream::SYSTEM,"---------- Total Processing Time%i\n\n\n",t3-t0); vcg::tri::UpdateBounding<CMeshO>::Box(m->cm); // updates bounding box tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFace(m->cm); // Final operations md->mm()->visible=true; md->setBusy(false); if (gla->getCurrentRenderMode() != NULL) gla->getCurrentRenderMode()->colorMode=GLW::CMPerVert; emit this->resetTrackBall(); gla->update(); }
void EditArc3DPlugin::exportShotsToRasters() { int subSampleVal = arc3DDialog->ui.subsampleSpinBox->value(); float scalingFactor = arc3DDialog->ui.scaleLineEdit->text().toFloat(); int minCountVal= arc3DDialog->ui.minCountSpinBox->value(); CMeshO mm; QTableWidget *qtw=arc3DDialog->ui.imageTableWidget; v3dImportDialog::ExportShots saveSelected=v3dImportDialog::ExportShots(arc3DDialog->ui.saveShotCombo->currentIndex()); for(int i=0; i<er.modelList.size(); ++i) { if ((saveSelected==v3dImportDialog::EXPORT_ALL) || (qtw->isItemSelected(qtw->item(i,0)))) { er.modelList[i].cam.Open(er.modelList[i].cameraName.toUtf8().data()); mm.Clear(); Point3m corr=er.modelList[i].TraCorrection(mm,subSampleVal*2,minCountVal,0); er.modelList[i].shot.Extrinsics.SetTra(er.modelList[i].shot.Extrinsics.Tra()-corr); md->setBusy(true); RasterModel* rm=md->addNewRaster(); rm->addPlane(new Plane(er.modelList[i].textureName,Plane::RGBA)); rm->setLabel(er.modelList[i].textureName); rm->shot=er.modelList[i].shot; rm->shot.RescalingWorld(scalingFactor, false); //// Undistort if (arc3DDialog->ui.shotDistortion->isChecked()) { QImage originalImg=rm->currentPlane->image; //originalImg.load(imageName); QFileInfo qfInfo(rm->currentPlane->fullPathFileName); QString suffix = "." + qfInfo.completeSuffix(); QString path = qfInfo.absoluteFilePath().remove(suffix); path.append("Undist" + suffix); qDebug(path.toLatin1()); QImage undistImg(originalImg.width(),originalImg.height(),originalImg.format()); undistImg.fill(qRgba(0,0,0,255)); //vcg::Camera<float> &cam = rm->shot.Intrinsics; QRgb value; for(int x=0; x<originalImg.width();x++) for(int y=0; y<originalImg.height();y++){ value = originalImg.pixel(x,y); /////// Point3d m_temp = er.modelList[i].cam.Kinv * Point3d(x,y,1); double oldx, oldy; er.modelList[i].cam.rd.ComputeOldXY(m_temp[0] / m_temp[2], m_temp[1] / m_temp[2], oldx, oldy); ///////////// m_temp=er.modelList[i].cam.K * Point3d(oldx,oldy,1); vcg::Point2<float> newPoint(m_temp.X(),m_temp.Y()); if((newPoint.X()- (int)newPoint.X())>0,5) newPoint.X()++; if((newPoint.Y()- (int)newPoint.Y())>0,5) newPoint.Y()++; if(newPoint.X()>=0 && newPoint.X()<undistImg.width() && newPoint.Y()>=0 && newPoint.Y()< undistImg.height()) undistImg.setPixel((int)newPoint.X(),(int)newPoint.Y(),qRgba(qRed(value),qGreen(value),qBlue(value), qAlpha(value))); } PullPush(undistImg,qRgba(0,0,0,255)); undistImg.save(path); rm->currentPlane->image= undistImg; rm->currentPlane->fullPathFileName=path; QString newLabel = rm->label(); newLabel.remove(suffix); newLabel.append("Undist" + suffix); rm->setLabel(newLabel); md->setBusy(false); } Matrix44m transf; transf.SetRotateDeg(180,Point3m(1.0,0.0,0.0)); rm->shot.ApplyRigidTransformation(transf); //// end undistort } } }
bool EpochIO::open(const QString &formatName, const QString &fileName, MeshModel &m, int& mask,const RichParameterSet & /*par*/, CallBackPos *cb, QWidget *parent) { EpochReconstruction er; mask = vcg::tri::io::Mask::IOM_VERTCOLOR | vcg::tri::io::Mask::IOM_VERTQUALITY; // just to be sure... if (fileName.isEmpty()) return false; // initializing progress bar status if (cb != NULL) (*cb)(0, "Loading..."); // this change of dir is needed for subsequent texture/material loading QString FileNameDir = fileName.left(fileName.lastIndexOf("/")); QDir::setCurrent(FileNameDir); QString errorMsgFormat = "Error encountered while loading file %1:\n%2"; string stdfilename = QFile::encodeName(fileName).constData (); //string filename = fileName.toUtf8().data(); QDomDocument doc; if(formatName.toUpper() == tr("V3D") && fileName.endsWith(".v3d")) { QFile file(fileName); if (file.open(QIODevice::ReadOnly) && doc.setContent(&file)) { file.close(); QDomElement root = doc.documentElement(); if (root.nodeName() == tr("reconstruction")) { QDomNode nhead = root.firstChildElement("head"); for(QDomNode n = nhead.firstChildElement("meta"); !n.isNull(); n = n.nextSiblingElement("meta")) { if(!n.hasAttributes()) return false; QDomNamedNodeMap attr= n.attributes(); if(attr.contains("name")) er.name = (attr.namedItem("name")).nodeValue() ; if(attr.contains("author")) er.author = (attr.namedItem("author")).nodeValue() ; if(attr.contains("created")) er.created = (attr.namedItem("created")).nodeValue() ; } for(QDomNode n = root.firstChildElement("model"); !n.isNull(); n = n.nextSiblingElement("model")) { EpochModel em; em.Init(n); er.modelList.push_back(em); } } } } epochDialog->setEpochReconstruction( &er, cb); do { epochDialog->exportToPLY=false; //Here we invoke the modal dialog and wait for its termination int continueValue = epochDialog->exec(); // The user has pressed the ok button: now start the real processing: if(epochDialog->exportToPLY == true) qDebug("Starting the ply exporting process"); int t0=clock(); logFP=fopen("epoch.log","w"); int subSampleVal = epochDialog->subsampleSpinBox->value(); int minCountVal= epochDialog->minCountSpinBox->value(); float maxCCDiagVal= epochDialog->maxCCDiagSpinBox->value(); int mergeResolution=epochDialog->mergeResolutionSpinBox->value(); int smoothSteps=epochDialog->smoothSpinBox->value(); bool closeHole = epochDialog->holeCheckBox->isChecked(); int maxHoleSize = epochDialog->holeSpinBox->value(); if (continueValue == QDialog::Rejected) { QMessageBox::warning(parent, "Open V3d format","Aborted"); return false; } CMeshO mm; QTableWidget *qtw=epochDialog->imageTableWidget; float MinAngleCos=cos(vcg::math::ToRad(epochDialog->qualitySpinBox->value())); bool clustering=epochDialog->fastMergeCheckBox->isChecked(); bool removeSmallCC=epochDialog->removeSmallCCCheckBox->isChecked(); vcg::tri::Clustering<CMeshO, vcg::tri::AverageColorCell<CMeshO> > Grid; int selectedNum=0,selectedCount=0; int i; for(i=0;i<qtw->rowCount();++i) if(qtw->isItemSelected(qtw->item(i,0))) ++selectedNum; if(selectedNum==0) { QMessageBox::warning(parent, "Open V3d format","No range map selected. Nothing loaded"); return false; } bool dilationFlag = epochDialog->dilationCheckBox->isChecked(); int dilationN = epochDialog->dilationNumPassSpinBox->value(); int dilationSz = epochDialog->dilationSizeSlider->value() * 2 + 1; bool erosionFlag = epochDialog->erosionCheckBox->isChecked(); int erosionN = epochDialog->erosionNumPassSpinBox->value(); int erosionSz = epochDialog->erosionSizeSlider->value() * 2 + 1; float scalingFactor = epochDialog->scaleLineEdit->text().toFloat(); std::vector<string> savedMeshVector; bool firstTime=true; QList<EpochModel>::iterator li; for(li=er.modelList.begin(), i=0;li!=er.modelList.end();++li,++i) { if(qtw->isItemSelected(qtw->item(i,0))) { ++selectedCount; mm.Clear(); int tt0=clock(); (*li).BuildMesh(mm,subSampleVal,minCountVal,MinAngleCos,smoothSteps, dilationFlag, dilationN, dilationSz, erosionFlag, erosionN, erosionSz,scalingFactor); int tt1=clock(); if(logFP) fprintf(logFP,"** Mesh %i : Build in %i\n",selectedCount,tt1-tt0); if(epochDialog->exportToPLY) { QString plyFilename =(*li).textureName.left((*li).textureName.length()-4); plyFilename.append(".x.ply"); savedMeshVector.push_back(qPrintable(plyFilename)); int mask= tri::io::Mask::IOM_VERTCOORD + tri::io::Mask::IOM_VERTCOLOR + tri::io::Mask::IOM_VERTQUALITY; tri::io::ExporterPLY<CMeshO>::Save(mm,qPrintable(plyFilename),mask); } else { if(clustering) { if (firstTime) { //Grid.Init(mm.bbox,100000); vcg::tri::UpdateBounding<CMeshO>::Box(mm); //Grid.Init(mm.bbox,1000.0*pow(10.0,mergeResolution),mm.bbox.Diag()/1000.0f); Grid.Init(mm.bbox,100000.0*pow(10.0,mergeResolution)); firstTime=false; } Grid.AddMesh(mm); } else tri::Append<CMeshO,CMeshO>::Mesh(m.cm,mm); // append mesh mr to ml } int tt2=clock(); if(logFP) fprintf(logFP,"** Mesh %i : Append in %i\n",selectedCount,tt2-tt1); } if (cb)(*cb)(selectedCount*90/selectedNum, "Building meshes"); } if (cb != NULL) (*cb)(90, "Final Processing: clustering"); if(clustering) { Grid.ExtractPointSet(m.cm); } if(epochDialog->exportToPLY) { QString ALNfilename = fileName.left(fileName.length()-4).append(".aln"); ALNParser::SaveALN(qPrintable(ALNfilename), savedMeshVector); } int t1=clock(); if(logFP) fprintf(logFP,"Extracted %i meshes in %i\n",selectedCount,t1-t0); if (cb != NULL) (*cb)(95, "Final Processing: Removing Small Connected Components"); if(removeSmallCC) { vcg::tri::UpdateBounding<CMeshO>::Box(m.cm); // updates bounding box m.updateDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER | MeshModel::MM_FACEMARK); tri::Clean<CMeshO>::RemoveSmallConnectedComponentsDiameter(m.cm,m.cm.bbox.Diag()*maxCCDiagVal/100.0); } int t2=clock(); if(logFP) fprintf(logFP,"Topology and removed CC in %i\n",t2-t1); vcg::tri::UpdateBounding<CMeshO>::Box(m.cm); // updates bounding box if (cb != NULL) (*cb)(97, "Final Processing: Closing Holes"); if(closeHole) { m.updateDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEFLAGBORDER | MeshModel::MM_FACEMARK); tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(m.cm); vcg::tri::Hole<CMeshO>::EarCuttingFill<vcg::tri::MinimumWeightEar< CMeshO> >(m.cm,maxHoleSize,false); } if (cb != NULL) (*cb)(100, "Done"); // vcg::tri::UpdateNormals<CMeshO>::PerVertex(m.cm); // updates normals m.updateDataMask(MeshModel::MM_VERTCOLOR); int t3=clock(); if(logFP) fprintf(logFP,"---------- Total Processing Time%i\n\n\n",t3-t0); if(logFP) fclose(logFP); logFP=0; } while(epochDialog->exportToPLY); return true; }