diff --git a/src/meshlabplugins/io_breuckmann/io_bre.cpp b/src/meshlabplugins/io_breuckmann/io_bre.cpp new file mode 100644 index 000000000..01a807be9 --- /dev/null +++ b/src/meshlabplugins/io_breuckmann/io_bre.cpp @@ -0,0 +1,783 @@ +/**************************************************************************** +* MeshLab o o * +* An extendible mesh processor o o * +* _ O _ * +* Copyright(C) 2005, 2006 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ + +#include +#include +#include + +#include "io_bre.h" +#include +#include + +#include +#include +#include + +#include + +using namespace std; +using namespace vcg; + +/////////////////////////////////////////////////////////////////////////////////////////// +// class ImporterBRE +/////////////////////////////////////////////////////////////////////////////////////////// +template +int vcg::tri::io::ImporterBRE::Open( MeshModel &meshModel, OpenMeshType &m, int& mask, const QString &filename, bool pointsonly, CallBackPos *cb) +{ + QFile file(filename, NULL); + m.Clear(); + if( false == file.open(QFile::ReadOnly) ) + { + return E_CANTOPEN; + } + qint64 fileSize = file.size(); + + // Bre Header lesen + BreHeader header; + if( false == header.Read(file)) + { + return E_UNABLEREADHEADER; + } + int test_type = header.DataType(); + if ((test_type != 0) && (test_type != -1)) + { + return E_NOTSUPPORTED; + } + + VertexGrid grid(header.ExtentX(), header.ExtentY()); + + qint64 headerSize = header.Size(); + qint64 breElementSize = 20; + qint64 TestSize = (fileSize - headerSize) % breElementSize; //test if file valid + + Point3f curPoint; + if (TestSize != 0) + { + return E_INVALIDFILE; + } + int numberElements = (fileSize - headerSize) / breElementSize; + + + if (( header.Version() == 0x101 ) || ( header.Version() == 0x201 )) + { + //enable colors and quality + mask = vcg::tri::io::Mask::IOM_VERTCOLOR | vcg::tri::io::Mask::IOM_VERTQUALITY | vcg::tri::io::Mask::IOM_VERTTEXCOORD; + meshModel.Enable(mask); + + //Add camera position and image width and height + m.shot.Extrinsics.Tra() = header.CameraPosition(); + m.shot.Intrinsics.ViewportPx[0] = header.ExtentX(); + m.shot.Intrinsics.ViewportPx[1] = header.ExtentY(); + //Add projector position as mesh attribute + CMeshO::PerMeshAttributeHandle proPos = vcg::tri::Allocator::AddPerMeshAttribute (m,std::string("Projector position")); + proPos() = header.ProjectorPosition(); + + if (pointsonly == true) + { + CMeshO::VertexIterator vertexItr=vcg::tri::Allocator::AddVertices(m, numberElements); + int result = vcg::tri::io::BreElement::ReadBreElementsRaw( file, vertexItr, numberElements, cb); + return result; + } + else + { + int result = vcg::tri::io::ReadBreElementsInGrid(file, grid,m, test_type,numberElements, cb); + return result; + } +/* if ((result == 0) && (header.Transformed == true)) + { + UndoTransformation(m,header.Matrix()); + return result + } + else + { + return result; + }/**/ + + } + else + { + return E_NOTSUPPORTED; //format not supported + } + return E_NOERROR; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// class BreMeshIOPlugin +/////////////////////////////////////////////////////////////////////////////////////////// +// initialize importing parameters +void BreMeshIOPlugin::initPreOpenParameter(const QString &formatName, const QString &/*filename*/, RichParameterSet &parlst) +{ + + if (formatName.toUpper() == tr("BRE")) + { + parlst.addParam(new RichBool("pointsonly",false,"only import points","Just import points, without triangulation")); + } + +} + +bool BreMeshIOPlugin::open(const QString &formatName, const QString &fileName, MeshModel &m, int& mask, const RichParameterSet &parlst, CallBackPos *cb, QWidget * /*parent*/) +{ + // initializing progress bar status + if (cb != NULL) (*cb)(0, "Loading..."); + mask = 0; + QString errorMsgFormat = "Error encountered while loading file:\n\"%1\"\n\nError details: %2"; + bool points = parlst.getBool("pointsonly"); + int result = vcg::tri::io::ImporterBRE::Open(m, m.cm, mask, fileName,points, cb); + if (result != 0) // all the importers return 0 on success + { + errorMessage = errorMsgFormat.arg(fileName, ErrorMsg(result)); + return false; + } + + +// bool points = false; + + + return true; +} + +bool BreMeshIOPlugin::save(const QString &formatName,const QString &fileName, MeshModel &m, const int mask, const RichParameterSet & par, CallBackPos *cb, QWidget */*parent*/) +{ + return false; +} + +/* + returns the list of the file's type which can be imported +*/ +QList BreMeshIOPlugin::importFormats() const +{ + QList formatList; + formatList << Format("Breuckmann File Format" , tr("BRE")); + + return formatList; +} + +/* + returns the list of the file's type which can be exported +*/ +QList BreMeshIOPlugin::exportFormats() const +{ + QList formatList; + //formatList << Format("Breuckmann File Format" , tr("BRE")); + return formatList; +} + +/* + returns the mask on the basis of the file's type. + otherwise it returns 0 if the file format is unknown +*/ +void BreMeshIOPlugin::GetExportMaskCapability(QString &format, int &capability, int &defaultBits) const +{ + /*if(format.toUpper() == tr("BRE")) + { + capability = 0; + defaultBits = 0; + }/**/ +} + +void BreMeshIOPlugin::initOpenParameter(const QString &format, MeshModel &/*m*/, RichParameterSet &par) +{ + + if(format.toUpper() == tr("BRE")) + par.addParam(new RichBool("Unify",true, "Unify Duplicated Vertices", + "The STL format is not an vertex-indexed format. Each triangle is composed by independent vertices, so, usually, duplicated vertices should be unified")); + +} +void BreMeshIOPlugin::initSaveParameter(const QString &format, MeshModel &/*m*/, RichParameterSet &par) +{ + /* + if(format.toUpper() == tr("STL") || format.toUpper() == tr("PLY")) + par.addParam(new RichBool("Binary",true, "Binary encoding", + "Save the mesh using a binary encoding. If false the mesh is saved in a plain, readable ascii format")); + /**/ +} + +void BreMeshIOPlugin::applyOpenParameter(const QString &format, MeshModel &m, const RichParameterSet &par) +{ + if(format.toUpper() == tr("BRE")) + { + if(par.findParameter("Unify")->val->getBool()) + { + tri::Clean::RemoveDuplicateVertex(m.cm); + } + } +} + +///////////////////////////////////////////////////////////////////////////////// +// +// BreHeader +// class to work with the header of .bre files. +// Not everything in use yet. +// +///////////////////////////////////////////////////////////////////////////////// + +vcg::tri::io::BreHeader::BreHeader() +:m_data(1024, 0) +{ +} + +vcg::tri::io::BreHeader::~BreHeader() +{ +} + +bool vcg::tri::io::BreHeader::Read(QFile &file) +{ + if(m_data.size() != 1024) + { + m_data = m_data.fill(0, 1024); + } + + // Falls das Lesen fehl schlägt, wird m_data wieder mit 0 gefüllt. + bool success = ( 1 == file.read(m_data.data(), 256)); + + const QString testBR = "BR"; + QString testStr = QString::fromAscii(m_data.data()+6, 2); + success = (QString::compare(testBR, testStr) == 0); + + if ( success && Size() > 256 ) + { + success = (file.read(m_data.data()+256, (Size()-256)) == (Size()-256)); + } + + if ( !success ) + { + m_data = m_data.fill(0, 1024); + } + + return success; +} + +int vcg::tri::io::BreHeader::Version() const +{ + return *((unsigned __int16*) (m_data.data() + 2)); +} + +float vcg::tri::io::BreHeader::SpacingX() const +{ + return *((float*) (m_data.data() + 30)); +} + +float vcg::tri::io::BreHeader::SpacingY() const +{ + return *((float*) (m_data.data() + 34)); +} + +Point3f vcg::tri::io::BreHeader::CameraPosition() const +{ + Point3f result; + result[0] = *((float*) (m_data.data() + 38)); + result[1] = *((float*) (m_data.data() + 42)); + result[2] = *((float*) (m_data.data() + 46)); + return result; +} + +Point3f vcg::tri::io::BreHeader::ProjectorPosition() const +{ + Point3f result; + result[0] = *((float*) (m_data.data() + 50)); + result[1] = *((float*) (m_data.data() + 54)); + result[2] = *((float*) (m_data.data() + 58)); + return result; +} + + + int vcg::tri::io::BreHeader::DataType() const { + if ( Version() != 0x201 ) { + return -1; + } + + return (*(__int32*) (m_data.data() + 620)) != 0; + } + + +int vcg::tri::io::BreHeader::ExtentX() const +{ + return *((unsigned __int16*) (m_data.data() + 14)); +} + +int vcg::tri::io::BreHeader::ExtentY() const +{ + return *((unsigned __int16*) (m_data.data() + 16)); +} + +int vcg::tri::io::BreHeader::Size() const +{ + return *((unsigned __int16*) (m_data.data() + 4)); +} + + +Matrix44f vcg::tri::io::BreHeader::Matrix() const +{ + Matrix44f matrix; + float *ptr = (float*) (m_data.data() + 128); + + for ( int i=0; i<4; i++) + { + for ( int j=0; j<4; j++) + { + matrix.ElementAt(i,j) = *(ptr + i*4 + j); + } + } + return matrix; +} + + +bool vcg::tri::io::BreHeader::Transformed() const +{ + if ( Version() != 0x101 && Version() != 0x201 ) + { + return false; + } + + return (*(unsigned __int16*) (m_data.data() + 62)) != 0; +} + +///////////////////////////////////////////////////////////////////////////////// +// +// BreElement +// class to work with the elements in a .bre file +// +///////////////////////////////////////////////////////////////////////////////// + +vcg::tri::io::BreElement::BreElement() +: m_data(20, 0) +{ +} + +bool vcg::tri::io::BreElement::Read(QFile &file) +{ + if(m_data.size() != 20) + { + m_data.fill(0, 20); + } + + // Falls das Lesen fehl schlägt, wird m_data wieder mit 0 gefüllt. + if ( 20 != file.read(m_data.data(), 20) ) + { + m_data.fill(0, 20); + return false; + } + return true; +} + +Point3f vcg::tri::io::BreElement::Coord() const +{ + float *p = (float*)m_data.data(); + return Point3f( p[0], p[1], p[2] ); +} + +uchar vcg::tri::io::BreElement::Quality() const +{ + uchar quality = *((uchar*)(m_data.data()+12)); + return quality; +} + +QPoint vcg::tri::io::BreElement::Pixel() const +{ + QPoint pnt; + pnt.setX(static_cast(*((unsigned __int16*)(m_data.data()+14)))); + pnt.setY(static_cast(*((unsigned __int16*)(m_data.data()+16)))); + return pnt; +} + +uchar vcg::tri::io::BreElement::Red() const +{ + unsigned __int16 rgb = *((unsigned __int16*)(m_data.data()+18)); + return (rgb >> 7) & 0xf8; +} + +uchar vcg::tri::io::BreElement::Green() const +{ + unsigned __int16 rgb = *((unsigned __int16*)(m_data.data()+18)); + return (rgb >> 2) & 0xf8; +} + +uchar vcg::tri::io::BreElement::Blue() const +{ + unsigned __int16 rgb = *((unsigned __int16*)(m_data.data()+18)); + return (rgb << 3) & 0xf8; +} + +int vcg::tri::io::BreElement::ReadBreElementsRaw( QFile &file, CMeshO::VertexIterator &it, int numberElements, CallBackPos *cb) +{ + Point3f curPoint; + int num = 0; + vcg::tri::io::BreElement elem; + + while ( false == file.atEnd() ) + { + if ( !elem.Read(file) ) + { + return num; + } + num++; + curPoint = elem.Coord(); + (*it).P().Import(curPoint); + (*it).C()[0] = elem.Red(); + (*it).C()[1] = elem.Green(); + (*it).C()[2] = elem.Blue(); + (*it).C()[3] = 255; + (*it).Q() = elem.Quality(); + (*cb)(100*(num/numberElements), "Reading Elements..."); + ++it; + } + + if (num <= 1) + { + return E_EMPTYFILEPOINTS; + } + return E_NOERROR; +} + +///////////////////////////////////////////////////////////////////////////////// +// +// VertexGrid +// class to sort the Vertices in a Grid (to triangulate them later) +// +///////////////////////////////////////////////////////////////////////////////// + +vcg::tri::io::VertexGrid::VertexGrid(int width, int height) +:m_width(width) +,m_height(height) +{ + m_grid.resize(m_width*m_height*sizeof(vcg::tri::io::VertexGrid::Vertex)); + m_grid.fill('0'); +} + +vcg::tri::io::VertexGrid::~VertexGrid() +{ +} + + +void vcg::tri::io::VertexGrid::SetValue( int col, int row , Point3f curPoint, GLbyte red, GLbyte green, GLbyte blue, uchar quality) +{ + if ((col > m_width) || (row > m_height) || ((col*row*sizeof(vcg::tri::io::VertexGrid::Vertex)) > m_grid.size())) + { + return;// 0; //out of grid range + } + vcg::tri::io::VertexGrid::Vertex curVertex; + curVertex.X = curPoint.X(); + curVertex.Y = curPoint.Y(); + curVertex.Z = curPoint.Z(); + curVertex.Red = red; + curVertex.Green = green; + curVertex.Blue = blue; + curVertex.Valid = 1; + curVertex.Quality = quality; + + vcg::tri::io::VertexGrid::Vertex *position = ((vcg::tri::io::VertexGrid::Vertex*)(m_grid.data())) + ((row * m_width) + col); + *position = curVertex; +} + +Point3f vcg::tri::io::VertexGrid::GetValue( int col, int row) +{ + if ((col > m_width) || (row > m_height) || ((col*row*sizeof(vcg::tri::io::VertexGrid::Vertex)) > m_grid.size())) + { + return 0; //out of grid range (get) + } + + Point3f result; + + vcg::tri::io::VertexGrid::Vertex *position = ((vcg::tri::io::VertexGrid::Vertex*)(m_grid.data())) + ((row * m_width) + col); + result.X() = (*position).X; + result.Y() = (*position).Y; + result.Z() = (*position).Z; + + return result; +} + +GLbyte vcg::tri::io::VertexGrid::Red( int col, int row) +{ + if ((col > m_width) || (row > m_height) || ((col*row*sizeof(vcg::tri::io::VertexGrid::Vertex)) > m_grid.size())) + { + return E_RANGERED; //out of grid range (red) + } + + GLbyte result; + + vcg::tri::io::VertexGrid::Vertex *position = ((vcg::tri::io::VertexGrid::Vertex*)(m_grid.data())) + ((row * m_width) + col); + result = static_cast((*position).Red); + + return result; +} + +GLbyte vcg::tri::io::VertexGrid::Green( int col, int row) +{ + if ((col > m_width) || (row > m_height) || ((col*row*sizeof(vcg::tri::io::VertexGrid::Vertex)) > m_grid.size())) + { + return E_RANGEGREEN; //out of grid range (green) + } + + GLbyte result; + + vcg::tri::io::VertexGrid::Vertex *position = ((vcg::tri::io::VertexGrid::Vertex*)(m_grid.data())) + ((row * m_width) + col); + result = static_cast((*position).Green); + + return result; +} + +GLbyte vcg::tri::io::VertexGrid::Blue( int col, int row) +{ + if ((col > m_width) || (row > m_height) || ((col*row*sizeof(vcg::tri::io::VertexGrid::Vertex)) > m_grid.size())) + { + return E_RANGEBLUE;//out of grid range (blue) + } + + GLbyte result; + + vcg::tri::io::VertexGrid::Vertex *position = ((vcg::tri::io::VertexGrid::Vertex*)(m_grid.data())) + ((row * m_width) + col); + result = static_cast((*position).Blue); + + return result; +} + +uchar vcg::tri::io::VertexGrid::Quality( int col, int row) +{ + if ((col > m_width) || (row > m_height) || ((col*row*sizeof(vcg::tri::io::VertexGrid::Vertex)) > m_grid.size())) + { + return E_RANGEQUALITY;//out of grid range (blue) + } + + GLbyte result; + + vcg::tri::io::VertexGrid::Vertex *position = ((vcg::tri::io::VertexGrid::Vertex*)(m_grid.data())) + ((row * m_width) + col); + result = static_cast((*position).Quality); + + return result; +} + + +bool vcg::tri::io::VertexGrid::IsValid( int col, int row) +{ + if ((col >= m_width) || (row >= m_height) || ((col*row*sizeof(vcg::tri::io::VertexGrid::Vertex)) > m_grid.size())) + { + return E_RANGEVAL; //out of grid range (val) + } + + vcg::tri::io::VertexGrid::Vertex *position = ((vcg::tri::io::VertexGrid::Vertex*)(m_grid.data())) + ((row * m_width) + col); + + return (((*position).Valid == 1) ? true : false); +} + + + +//function reads in the BreElements, writes them in a VertexGrid and creates a mesh +int vcg::tri::io::ReadBreElementsInGrid( QFile &file, VertexGrid &grid, CMeshO &m, int dataType, int numberElements, vcg::CallBackPos *cb) +{ + CMeshO::PerMeshAttributeHandle test_index = tri::Allocator::GetPerMeshAttribute(m, "Camera Position"); + Point3f curPoint; + QPoint curPixel; + GLbyte curRed, curGreen, curBlue; + uchar curQuality; + + int num = 0; + vcg::tri::io::BreElement elem; + while ( false == file.atEnd() ) //read in all BreElements + { + if ( !elem.Read(file) ) + { + return num; + } + num++; + curPoint = elem.Coord(); + curPixel = elem.Pixel(); + curRed = elem.Red(); + curGreen = elem.Green(); + curBlue = elem.Blue(); + curQuality = elem.Quality(); + //write value in VertexGrid + grid.SetValue( curPixel.x(), curPixel.y(), curPoint, curRed, curGreen, curBlue, curQuality); + (*cb)(20*(num/numberElements), "Reading Elements..."); + + } + + //creating mesh + //going through the whole grid, testing if Valid. + //Only Points that are valid and have enough valid neigbours to form a triangle will be added. + + float cbstep = ((float)(80)/(float)(num));//for the progress bar + float cbvalue = 0.f;//for the progress bar + bool wasAdded = false;//for the progress bar + unsigned int pointsAdded = 0;//for the progress bar + + + for (int i=0; i<(grid.m_height-1); ++i) + { + for (int j=0; j<(grid.m_width-1); ++j) + { + if (grid.IsValid(j,i) == false) + { + continue; + } + if (grid.IsValid(j+1,i+1) == false) + { + continue; + } + if (grid.IsValid(j+1,i) == true) + { + CMeshO::FaceIterator faceItr=vcg::tri::Allocator::AddFaces(m,1); + CMeshO::VertexIterator vertexItr=vcg::tri::Allocator::AddVertices(m, 3); + curPoint = grid.GetValue(j,i); + (*vertexItr).P().Import(curPoint); + (*vertexItr).T().U() = j; + (*vertexItr).T().V() = i; + (*vertexItr).C()[0] = grid.Red(j,i); + (*vertexItr).C()[1] = grid.Green(j,i); + (*vertexItr).C()[2] = grid.Blue(j,i); + (*vertexItr).C()[3] = 255; + (*vertexItr).Q() = grid.Quality(j,i); + (*faceItr).V(0)=&*vertexItr; + vertexItr++; + curPoint = grid.GetValue(j+1,i + ((-1)*dataType)); + (*vertexItr).T().U() = j + 1; + (*vertexItr).T().V() = i + ((-1)*dataType); + (*vertexItr).P().Import(curPoint); + (*vertexItr).C()[0] = grid.Red(j+1,i + ((-1)*dataType)); + (*vertexItr).C()[1] = grid.Green(j+1,i + ((-1)*dataType)); + (*vertexItr).C()[2] = grid.Blue(j+1,i + ((-1)*dataType)); + (*vertexItr).C()[3] = 255; + (*vertexItr).Q() = grid.Quality(j+1,i + ((-1)*dataType)); + (*faceItr).V(1)=&*vertexItr; + vertexItr++; + curPoint = grid.GetValue(j+1,i + 1 + dataType); + (*vertexItr).P().Import(curPoint); + (*vertexItr).T().U() = j + 1; + (*vertexItr).T().V() = i + 1 + dataType; + (*vertexItr).C()[0] = grid.Red(j+1,i + 1 + dataType); + (*vertexItr).C()[1] = grid.Green(j+1,i + 1 + dataType); + (*vertexItr).C()[2] = grid.Blue(j+1,i + 1 + dataType); + (*vertexItr).C()[3] = 255; + (*vertexItr).Q() = grid.Quality(j+1,i + 1 + dataType); + (*faceItr).V(2)=&*vertexItr; + vertexItr++; + wasAdded = true; + } + if (grid.IsValid(j,i+1) == true) + { + CMeshO::FaceIterator faceItr=vcg::tri::Allocator::AddFaces(m,1); + CMeshO::VertexIterator vertexItr=vcg::tri::Allocator::AddVertices(m, 3); + curPoint = grid.GetValue(j,i); + (*vertexItr).P().Import(curPoint); + (*vertexItr).T().U() = j; + (*vertexItr).T().V() = i; + (*vertexItr).C()[0] = grid.Red(j,i); + (*vertexItr).C()[1] = grid.Green(j,i); + (*vertexItr).C()[2] = grid.Blue(j,i); + (*vertexItr).C()[3] = 255; + (*vertexItr).Q() = grid.Quality(j,i); + (*faceItr).V(0)=&*vertexItr; + vertexItr++; + curPoint = grid.GetValue(j + 1 + dataType,i+1); + (*vertexItr).P().Import(curPoint); + (*vertexItr).T().U() = j + 1 + dataType; + (*vertexItr).T().V() = i + 1; + (*vertexItr).C()[0] = grid.Red(j + 1 + dataType,i+1); + (*vertexItr).C()[1] = grid.Green(j + 1 + dataType,i+1); + (*vertexItr).C()[2] = grid.Blue(j + 1 + dataType,i+1); + (*vertexItr).C()[3] = 255; + (*vertexItr).Q() = grid.Quality(j + 1 + dataType,i+1); + (*faceItr).V(1)=&*vertexItr; + vertexItr++; + curPoint = grid.GetValue(j + ((-1)*dataType),i+1); + (*vertexItr).P().Import(curPoint); + (*vertexItr).T().U() = j + ((-1)*dataType); + (*vertexItr).T().V() = i + 1; + (*vertexItr).C()[0] = grid.Red(j + ((-1)*dataType),i+1); + (*vertexItr).C()[1] = grid.Green(j + ((-1)*dataType),i+1); + (*vertexItr).C()[2] = grid.Blue(j + ((-1)*dataType),i+1); + (*vertexItr).C()[3] = 255; + (*vertexItr).Q() = grid.Quality(j + ((-1)*dataType),i+1); + (*faceItr).V(2)=&*vertexItr; + vertexItr++; + wasAdded = true; + } + + if(true == wasAdded) + { + pointsAdded++; + cbvalue += cbstep; + } + wasAdded = false; + } + if(pointsAdded > 100) //for the progress bar. Calling cb too often results in no update for the progress bar + { //because of the timer in cb + (*cb)(20+(int)cbvalue, "Triangulation"); + pointsAdded = 0; + } + } + + if (m.vert.size() == 0) + { + return E_EMPTYFILEFACES; + } + return E_NOERROR; +} + +/* +void UndoTransformation( CMeshO& mesh, const Matrix44f& matrix ) +{ +// vcg::Eigen::Matrix inverse; + + if ( matrix != Matrix44f::Identity() ) + { + Matrix44f inverse = vcg::Inverse(matrix); + int i; + for ( i=0; i::TriangleContainZ( const OpenObjects::TCoord& a, const OpenObjects::TCoord& b, const OpenObjects::TCoord& c, const OpenObjects::TCoord& point ) const +{ + const static T tolerance = std::numeric_limits::epsilon() * static_cast( -100.0 ); + + double det = (b.X() - a.X()) * (point.Y() - a.Y()) - (b.Y() - a.Y()) * (point.X() - a.X()); + if ( det < tolerance ) + { + return false; + } + det = (c.X() - b.X()) * (point.Y() - b.Y()) - (c.Y() - b.Y()) * (point.X() - b.X()); + if ( det < tolerance ) + { + return false; + } + det = (a.X() - c.X()) * (point.Y() - c.Y()) - (a.Y() - c.Y()) * (point.X() - c.X()); + + return ! (det < tolerance ); +}/**/ + + + + + + + + + +Q_EXPORT_PLUGIN(BreMeshIOPlugin) diff --git a/src/meshlabplugins/io_breuckmann/io_bre.h b/src/meshlabplugins/io_breuckmann/io_bre.h new file mode 100644 index 000000000..d5e3ea836 --- /dev/null +++ b/src/meshlabplugins/io_breuckmann/io_bre.h @@ -0,0 +1,228 @@ +/**************************************************************************** +* MeshLab o o * +* A versatile mesh processing toolbox o o * +* _ O _ * +* Copyright(C) 2005 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +#ifndef IOBREPLUGIN_H +#define IOBREPLUGIN_H + +#include + +namespace vcg { +namespace tri { +namespace io { + + template + class ImporterBRE + { + + public: + typedef typename OpenMeshType::VertexPointer VertexPointer; + typedef typename OpenMeshType::ScalarType ScalarType; + typedef typename OpenMeshType::VertexType VertexType; + typedef typename OpenMeshType::FaceType FaceType; + typedef typename OpenMeshType::VertexIterator VertexIterator; + typedef typename OpenMeshType::FaceIterator FaceIterator; + + static int Open( MeshModel &meshModel, OpenMeshType &m, int& mask, const QString &filename, bool pointsonly, CallBackPos *cb); + + }; + + + ///////////////////////////////////////////////////////////////////////////////// + // + // BreHeader + // + ///////////////////////////////////////////////////////////////////////////////// + class BreHeader + { + public: + BreHeader(); + virtual ~BreHeader(); + bool Read(QFile &file); + int Version() const; + // 0 = undef, 0x101 = erweitertes Format, 0x201 = erweitertes Raster Format + int Size() const; + int ExtentX() const; + int ExtentY() const; + Point3f CameraPosition() const; + Point3f ProjectorPosition() const; + // Ausdehnung in X und Y Richtung + float SpacingX() const; + float SpacingY() const; + bool Transformed() const; + // Abfrage, ob Matrix() schon auf die 3D Daten angewendet wurde. + Matrix44f Matrix() const; + + + int DataType() const; + // 0 : RASTER_DATA + // 1 : SECTION_DATA + // 2 : CLOUD_DATA + // -1: UNDEF , wenn Version() != 0x201 + + + protected: + QByteArray m_data; + }; + ///////////////////////////////////////////////////////////////////////////////// + // + // BreElement + // + ///////////////////////////////////////////////////////////////////////////////// + class BreElement + { + public: + BreElement(); + bool Read(QFile & ); + Point3f Coord() const; + uchar Quality() const; + QPoint Pixel() const; + uchar Red() const; + uchar Green() const; + uchar Blue() const; + + static int ReadBreElementsRaw( QFile &file, CMeshO::VertexIterator &it, int numberElements, CallBackPos *cb); + + private: + QByteArray m_data; + }; + + ///////////////////////////////////////////////////////////////////////////////// + // + // VertexGrid + // + ///////////////////////////////////////////////////////////////////////////////// + class VertexGrid + { + public: + //VertexGrid(); + VertexGrid(int width, int height); + void VertexGrid::SetValue( int col, int row , Point3f curPointt, GLbyte red, GLbyte green, GLbyte blue, uchar quality); + Point3f GetValue(int col, int row); + GLbyte Red( int col, int row); + GLbyte Green( int col, int row); + GLbyte Blue( int col, int row); + uchar Quality( int col, int row); + bool IsValid(int col, int row); + VertexGrid::~VertexGrid(); + int m_width; + int m_height; + + private: + QByteArray m_grid; + + public: + struct Vertex + { + unsigned char Valid; + float X; + float Y; + float Z; + uchar Quality; + GLbyte Red; + GLbyte Green; + GLbyte Blue; + }; + }; + + int ReadBreElementsInGrid( QFile &file, vcg::tri::io::VertexGrid &grid, CMeshO &m, int dataType,int numberElements, vcg::CallBackPos *cb); + void UndoTransformation( CMeshO& mesh, const Matrix44f& matrix ); +}//namespace io +}//namespace tri +}//namespace vcg + +class BreMeshIOPlugin : public QObject, public MeshIOInterface +{ + Q_OBJECT + Q_INTERFACES(MeshIOInterface) + +public: + + BreMeshIOPlugin() : MeshIOInterface() {} + + QList importFormats() const; + QList exportFormats() const; + + virtual bool autoDialog(QAction *) + { + return true; + } + + void GetExportMaskCapability(QString &format, int &capability, int &defaultBits) const; + + bool open(const QString &formatName, const QString &fileName, MeshModel &m, int& mask,const RichParameterSet & par, vcg::CallBackPos *cb=0, QWidget *parent=0); + bool save(const QString &formatName, const QString &fileName, MeshModel &m, const int mask, const RichParameterSet & par, vcg::CallBackPos *cb=0, QWidget *parent= 0); + virtual void initOpenParameter(const QString &format, MeshModel &/*m*/, RichParameterSet & par); + virtual void applyOpenParameter(const QString &format, MeshModel &m, const RichParameterSet &par); + void initPreOpenParameter(const QString &formatName, const QString &filename, RichParameterSet &parlst); + virtual void initSaveParameter(const QString &format, MeshModel &/*m*/, RichParameterSet & par); + +}; + + +static char* errorStr; + +enum BreError +{ + E_NOERROR, // 0 + E_CANTOPEN, // 1 + E_UNABLEREADHEADER, // 2 + E_INVALIDFILE, // 3 + E_NOTSUPPORTED, // 4 + E_RANGESET, // 5 + E_RANGEGET, // 6 + E_RANGEVAL, // 7 + E_RANGERED, // 8 + E_RANGEGREEN, // 9 + E_RANGEBLUE, // 10 + E_RANGEQUALITY, // 11 + E_EMPTYFILEFACES, // 12 + E_EMPTYFILEPOINTS // 13 +}; + +static const char *ErrorMsg(int error) +{ + static const char * bre_error_msg[] = + { + "No errors", + "Can't open file", + "Unable to read header", + "Invalid file", + "File format not supported", + "Out of grid range, unable to set value", + "Out of grid range, unable to get value", + "Out of grid range, unable to get validation", + "Out of grid range, unable to get color (red)", + "Out of grid range, unable to get color (green)", + "Out of grid range, unable to get color (blue)", + "Out of grid range, unable to get quality", + "File does not include any valid triangles", + "File does not include any points" + }; + + if(error > 13 || error < 0) return "Unknown error"; + else if (error == 11) return errorStr; + else return bre_error_msg[error]; +}; + + + +#endif diff --git a/src/meshlabplugins/io_breuckmann/io_bre.pro b/src/meshlabplugins/io_breuckmann/io_bre.pro new file mode 100644 index 000000000..260f0689d --- /dev/null +++ b/src/meshlabplugins/io_breuckmann/io_bre.pro @@ -0,0 +1,7 @@ +include (../../shared.pri) + +HEADERS += io_bre.h \ + +SOURCES += io_bre.cpp \ + +TARGET = io_bre