void Surface_DifferentialProperties_Plugin::computeNormal(
	const QString& mapName,
	const QString& positionAttributeName,
	const QString& normalAttributeName,
	bool autoUpdate)
{
	MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m_schnapps->getMap(mapName));
	if(mh == NULL)
		return;

	VertexAttribute<PFP2::VEC3, PFP2::MAP> position = mh->getAttribute<PFP2::VEC3, VERTEX>(positionAttributeName);
	if(!position.isValid())
		return;

	VertexAttribute<PFP2::VEC3, PFP2::MAP> normal = mh->getAttribute<PFP2::VEC3, VERTEX>(normalAttributeName);
	if(!normal.isValid())
		normal = mh->addAttribute<PFP2::VEC3, VERTEX>(normalAttributeName);

	PFP2::MAP* map = mh->getMap();
	Algo::Surface::Geometry::computeNormalVertices<PFP2>(*map, position, normal);

	computeNormalLastParameters[mapName] =
		ComputeNormalParameters(positionAttributeName, normalAttributeName, autoUpdate);

	mh->notifyAttributeModification(normal);
}
Пример #2
0
void Surface_Subdivision_Plugin::CCSubdivision(
	const QString& mapName,
	const QString& positionAttributeName, bool interp)
{
	MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m_schnapps->getMap(mapName));
	if(mh == NULL)
		return;

	VertexAttribute<PFP2::VEC3, PFP2::MAP> position = mh->getAttribute<PFP2::VEC3, VERTEX>(positionAttributeName);
	if(!position.isValid())
		return;

	pythonRecording("CCSubdivision", "", mapName, positionAttributeName,interp);

	PFP2::MAP* map = mh->getMap();
	if (interp)
		Algo::Surface::Modelisation::CatmullClarkInterpolSubdivision<PFP2>(*map, position);
	else
		Algo::Surface::Modelisation::CatmullClarkSubdivision<PFP2>(*map, position);

	mh->notifyAttributeModification(position);
	mh->notifyConnectivityModification();

	foreach(View* view, mh->getLinkedViews())
		view->updateGL();
}
Пример #3
0
/**
 * @brief test if map has a Vertex Attribute of VEC3 named name
 * @param map  the map
 * @param name name of attribute
 */
void testVAbyNames(MAP& map, const std::string& name)
{
	VertexAttribute<VEC3, MAP> testPos = map.getAttribute<VEC3, VERTEX, MAP>(name);
	if (testPos.isValid())
		std::cout << "Attribute "<< name <<" valid"<< std::endl;
	else
		std::cout << "Attribute "<< name <<"invalid"<< std::endl;
}
Пример #4
0
void UniversalLoader<MapType, AttrTypeLoader>::UnpackOnVertex(MapType& map, const unsigned int* verticesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const
{
	VertexAttribute<typename AttrTypeLoader::ATTR_TYPE> attr = map.template getAttribute<typename AttrTypeLoader::ATTR_TYPE, VERTEX>(attrName);

	if (!attr.isValid())
		attr = map.template addAttribute<typename AttrTypeLoader::ATTR_TYPE, VERTEX>(attrName);

	char* p = (char*)buffer;

	for(unsigned int i = 0 ; i < hdr->meshHdr.vxCount ; i++)
	{
		AttrTypeLoader::Extract(&attr[verticesId[i]], p);
		p += AttrTypeLoader::TYPE_SIZE_IN_BUFFER;
	}
}
Пример #5
0
void AHEMImporter<PFP>::LoadPosition(AHEMAttributeDescriptor* posDescr)
{
	VertexAttribute<typename PFP::VEC3, typename PFP::MAP> position = map->template getAttribute<typename PFP::VEC3, VERTEX, typename PFP::MAP>("position");

	if (!position.isValid())
		position = map->template addAttribute<typename PFP::VEC3, VERTEX, typename PFP::MAP>("position");

	f.seekg(posDescr->fileStartOffset, std::ios_base::beg);
	f.read(buffer, posDescr->attributeChunkSize);

	float* q = (float*)buffer;

	for(unsigned int i = 0 ; i < hdr.meshHdr.vxCount ; i++)
	{
		position[verticesId[i]] = typename PFP::VEC3(q[0], q[1], q[2]);
		q += 3;
	}
}
Пример #6
0
bool MeshTablesVolume<PFP>::importTs(const std::string& filename, std::vector<std::string>& attrNames)
{
    //
    VertexAttribute<VEC3> position =  m_map.template getAttribute<VEC3, VERTEX>("position") ;

    if (!position.isValid())
        position = m_map.template addAttribute<VEC3, VERTEX>("position") ;

    attrNames.push_back(position.name()) ;

    //
    VertexAttribute<REAL> scalar = m_map.template getAttribute<REAL, VERTEX>("scalar");

    if (!scalar.isValid())
        scalar = m_map.template addAttribute<REAL, VERTEX>("scalar") ;

    attrNames.push_back(scalar.name()) ;

    //
    AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

    // open file
    std::ifstream fp(filename.c_str(), std::ios::in);
    if (!fp.good())
    {
        CGoGNerr << "Unable to open file " << filename << CGoGNendl;
        return false;
    }

    std::string ligne;

    // reading number of vertices/tetrahedra
    std::getline (fp, ligne);
    std::stringstream oss(ligne);
    oss >> m_nbVertices;
    oss >> m_nbVolumes;

    //reading vertices
    std::vector<unsigned int> verticesID;
    verticesID.reserve(m_nbVertices);

    for(unsigned int i = 0; i < m_nbVertices; ++i)
    {
        do
        {
            std::getline (fp, ligne);
        } while (ligne.size() == 0);

        std::stringstream oss(ligne);

        float x,y,z;
        oss >> x;
        oss >> y;
        oss >> z;

        VEC3 pos(x,y,z);

        unsigned int id = container.insertLine();

        position[id] = pos;
        verticesID.push_back(id);

        float scal;
        oss >> scal;
        scalar[id] = scal;
    }

    //Read and embed all tetrahedrons
    for(unsigned int i = 0; i < m_nbVolumes ; ++i)
    {        
        do
        {
            std::getline(fp,ligne);
        } while(ligne.size() == 0);

        std::stringstream oss(ligne);

        m_nbFaces.push_back(4);

        int s0,s1,s2,s3,nbe;

        oss >> s0;
        oss >> s1;
        oss >> s2;
        oss >> s3;

        typename PFP::VEC3 P = position[verticesID[s0]];
        typename PFP::VEC3 A = position[verticesID[s1]];
        typename PFP::VEC3 B = position[verticesID[s2]];
        typename PFP::VEC3 C = position[verticesID[s3]];

        if(Geom::testOrientation3D<typename PFP::VEC3>(P,A,B,C) == Geom::UNDER)
        {
            int ui = s1;
            s1 = s2;
            s2 = ui;
        }


        //if regions are defined use this number
        oss >> nbe; //ignored here

        m_emb.push_back(verticesID[s0]);
        m_emb.push_back(verticesID[s1]);
        m_emb.push_back(verticesID[s2]);
        m_emb.push_back(verticesID[s3]);
    }

    fp.close();
    return true;
}
Пример #7
0
bool MeshTablesVolume<PFP>::importTetmesh(const std::string& filename, std::vector<std::string>& attrNames)
{
    VertexAttribute<VEC3> position =  m_map.template getAttribute<VEC3, VERTEX>("position") ;

    if (!position.isValid())
        position = m_map.template addAttribute<VEC3, VERTEX>("position") ;

    attrNames.push_back(position.name()) ;

    AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

    //open file
    std::ifstream fp(filename.c_str(), std::ios::in);
    if (!fp.good())
    {
        CGoGNerr << "Unable to open file " << filename << CGoGNendl;
        return false;
    }

    std::string line;

    fp >> line;

    if (line!="Vertices")
        CGoGNerr << "Warning tetmesh file problem"<< CGoGNendl;

    fp >> m_nbVertices;

    std::cout << "READ: "<< m_nbVertices << std::endl;

    std::getline (fp, line);

    //reading vertices
    std::vector<unsigned int> verticesID;
    verticesID.reserve(m_nbVertices+1);
    verticesID.push_back(0xffffffff);

    for(unsigned int i = 0; i < m_nbVertices; ++i)
    {
        do
        {
            std::getline (fp, line);
        } while (line.size() == 0);

        std::stringstream oss(line);

        float x,y,z;
        oss >> x;
        oss >> y;
        oss >> z;
        // TODO : if required read other vertices attributes here
        VEC3 pos(x,y,z);

        unsigned int id = container.insertLine();
        position[id] = pos;

        verticesID.push_back(id);
    }

    fp >> line;
    if (line!="Tetrahedra")
        CGoGNerr << "Warning tetmesh file problem"<< CGoGNendl;

    fp >> m_nbVolumes;
    std::getline (fp, line);

    // reading tetrahedra
    m_nbFaces.reserve(m_nbVolumes*4);
    m_emb.reserve(m_nbVolumes*12);

    for(unsigned i = 0; i < m_nbVolumes ; ++i)
    {
        do
        {
            std::getline(fp,line);
        } while(line.size() == 0);

        std::stringstream oss(line);

        m_nbFaces.push_back(4);

        int s0,s1,s2,s3;

        oss >> s0;
        oss >> s1;
        oss >> s2;
        oss >> s3;

        typename PFP::VEC3 P = position[verticesID[s0]];
        typename PFP::VEC3 A = position[verticesID[s1]];
        typename PFP::VEC3 B = position[verticesID[s2]];
        typename PFP::VEC3 C = position[verticesID[s3]];

        if (Geom::testOrientation3D<typename PFP::VEC3>(P,A,B,C) == Geom::UNDER)
        {
            int ui=s1;
            s1 = s2;
            s2 = ui;
        }

        m_emb.push_back(verticesID[s0]);
        m_emb.push_back(verticesID[s1]);
        m_emb.push_back(verticesID[s2]);
        m_emb.push_back(verticesID[s3]);
    }

    fp.close();
    return true;
}
Пример #8
0
bool MeshTablesVolume<PFP>::importNodeWithELERegions(const std::string& filenameNode, const std::string& filenameELE, std::vector<std::string>& attrNames)
{
    VertexAttribute<VEC3> position =  m_map.template getAttribute<VEC3, VERTEX>("position") ;

    if (!position.isValid())
        position = m_map.template addAttribute<VEC3, VERTEX>("position") ;

    attrNames.push_back(position.name()) ;

    AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

    //open file
    std::ifstream fnode(filenameNode.c_str(), std::ios::in);
    if (!fnode.good())
    {
        CGoGNerr << "Unable to open file " << filenameNode << CGoGNendl;
        return false;
    }

    std::ifstream fele(filenameELE.c_str(), std::ios::in);
    if (!fele.good())
    {
        CGoGNerr << "Unable to open file " << filenameELE << CGoGNendl;
        return false;
    }

    std::string line;

    //Reading NODE file
    //First line: [# of points] [dimension (must be 3)] [# of attributes] [# of boundary markers (0 or 1)]
    unsigned int nbe;
    {
        do
        {
            std::getline(fnode,line);
        }while(line.size() == 0);

        std::stringstream oss(line);
        oss >> m_nbVertices;
        oss >> nbe;
        oss >> nbe;
        oss >> nbe;
    }

    //Reading number of tetrahedra in ELE file
    unsigned int nbv;
    {
        do
        {
            std::getline(fele,line);
        }while(line.size() == 0);

        std::stringstream oss(line);
        oss >> m_nbVolumes;
        oss >> nbv ;
        oss >> nbv;
    }

    //Reading vertices
    std::map<unsigned int,unsigned int> verticesMapID;

    for(unsigned int i = 0 ; i < m_nbVertices ; ++i)
    {
        do
        {
            std::getline(fnode,line);
        }while(line.size() == 0);

        std::stringstream oss(line);

        int idv;
        oss >> idv;

        float x,y,z;
        oss >> x;
        oss >> y;
        oss >> z;
        //we can read colors informations if exists
        VEC3 pos(x,y,z);

        unsigned int id = container.insertLine();
        position[id] = pos;
        verticesMapID.insert(std::pair<unsigned int, unsigned int>(idv,id));
    }

    // reading tetrahedra
    m_nbFaces.reserve(m_nbVolumes*4);
    m_emb.reserve(m_nbVolumes*12);

    for(unsigned i = 0; i < m_nbVolumes ; ++i)
    {
        do
        {
            std::getline(fele,line);
        } while(line.size() == 0);

        std::stringstream oss(line);
        oss >> nbe;

        m_nbFaces.push_back(4);

        int s0,s1,s2,s3;

        oss >> s0;
        oss >> s1;
        oss >> s2;
        oss >> s3;

        typename PFP::VEC3 P = position[verticesMapID[s0]];
        typename PFP::VEC3 A = position[verticesMapID[s1]];
        typename PFP::VEC3 B = position[verticesMapID[s2]];
        typename PFP::VEC3 C = position[verticesMapID[s3]];

        if (Geom::testOrientation3D<typename PFP::VEC3>(P,A,B,C) == Geom::UNDER)
        {
            int ui= s0;
            s0 = s3;
            s3 = s2;
            s2 = s1;
            s1 = ui;
        }

        m_emb.push_back(verticesMapID[s0]);
        m_emb.push_back(verticesMapID[s1]);
        m_emb.push_back(verticesMapID[s2]);
        m_emb.push_back(verticesMapID[s3]);
    }

    fnode.close();
    fele.close();

    return true;
}
Пример #9
0
bool MeshTablesVolume<PFP>::importOFFWithELERegions(const std::string& filenameOFF, const std::string& filenameELE, std::vector<std::string>& attrNames)
{
    VertexAttribute<VEC3> position =  m_map.template getAttribute<VEC3, VERTEX>("position") ;

    if (!position.isValid())
        position = m_map.template addAttribute<VEC3, VERTEX>("position") ;

    attrNames.push_back(position.name()) ;

    AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

    // open files
    std::ifstream foff(filenameOFF.c_str(), std::ios::in);
    if (!foff.good())
    {
        CGoGNerr << "Unable to open OFF file " << CGoGNendl;
        return false;
    }

    std::ifstream fele(filenameELE.c_str(), std::ios::in);
    if (!fele.good())
    {
        CGoGNerr << "Unable to open ELE file " << CGoGNendl;
        return false;
    }

    std::string line;

    //OFF reading
    std::getline(foff, line);
    if(line.rfind("OFF") == std::string::npos)
    {
        CGoGNerr << "Problem reading off file: not an off file"<<CGoGNendl;
        CGoGNerr << line << CGoGNendl;
        return false;
    }

    //Reading number of vertex/faces/edges in OFF file
    unsigned int nbe;
    {
        do
        {
            std::getline(foff,line);
        }while(line.size() == 0);

        std::stringstream oss(line);
        oss >> m_nbVertices;
        oss >> nbe;
        oss >> nbe;
        oss >> nbe;
    }

    //Reading number of tetrahedra in ELE file
    unsigned int nbv;
    {
        do
        {
            std::getline(fele,line);
        }while(line.size() == 0);

        std::stringstream oss(line);
        oss >> m_nbVolumes;
        oss >> nbv ;
        oss >> nbv;
    }

    //Reading vertices
    std::vector<unsigned int> verticesID;
    verticesID.reserve(m_nbVertices);

    for(unsigned int i = 0 ; i < m_nbVertices ; ++i)
    {
        do
        {
            std::getline(foff,line);
        }while(line.size() == 0);

        std::stringstream oss(line);

        float x,y,z;
        oss >> x;
        oss >> y;
        oss >> z;
        //we can read colors informations if exists
        VEC3 pos(x,y,z);

        unsigned int id = container.insertLine();
        position[id] = pos;
        verticesID.push_back(id);
    }

    // reading tetrahedra
    m_nbFaces.reserve(m_nbVolumes*4);
    m_emb.reserve(m_nbVolumes*12);

    for(unsigned i = 0; i < m_nbVolumes ; ++i)
    {
        do
        {
            std::getline(fele,line);
        } while(line.size() == 0);

        std::stringstream oss(line);
        oss >> nbe;

        m_nbFaces.push_back(4);

        int s0,s1,s2,s3;

        oss >> s0;
        oss >> s1;
        oss >> s2;
        oss >> s3;

        typename PFP::VEC3 P = position[verticesID[s0]];
        typename PFP::VEC3 A = position[verticesID[s1]];
        typename PFP::VEC3 B = position[verticesID[s2]];
        typename PFP::VEC3 C = position[verticesID[s3]];

        if (Geom::testOrientation3D<typename PFP::VEC3>(P,A,B,C) == Geom::UNDER)
        {
            int ui= s0;
            s0 = s3;
            s3 = s2;
            s2 = s1;
            s1 = ui;
        }

        m_emb.push_back(verticesID[s0]);
        m_emb.push_back(verticesID[s1]);
        m_emb.push_back(verticesID[s2]);
        m_emb.push_back(verticesID[s3]);
    }

    foff.close();
    fele.close();

    return true;
}
Пример #10
0
bool MeshTablesVolume<PFP>::importTet(const std::string& filename, std::vector<std::string>& attrNames)
{
	VertexAttribute<VEC3, MAP> position =  m_map.template getAttribute<VEC3, VERTEX, MAP>("position") ;

	if (!position.isValid())
		position = m_map.template addAttribute<VEC3, VERTEX, MAP>("position") ;

	attrNames.push_back(position.name()) ;

	AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

	//open file
	std::ifstream fp(filename.c_str(), std::ios::in);
	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}

	std::string ligne;

	// reading number of vertices
	std::getline (fp, ligne);
	std::stringstream oss(ligne);
	oss >> m_nbVertices;

	// reading number of tetrahedra
	std::getline (fp, ligne);
	std::stringstream oss2(ligne);
	oss2 >> m_nbVolumes;

	//reading vertices
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);

	for(unsigned int i = 0; i < m_nbVertices; ++i)
	{
		do
		{
			std::getline (fp, ligne);
		} while (ligne.size() == 0);

		std::stringstream oss(ligne);

		float x,y,z;
		oss >> x;
		oss >> y;
		oss >> z;
		// TODO : if required read other vertices attributes here
		VEC3 pos(x,y,z);

		unsigned int id = container.insertLine();
		position[id] = pos;

		verticesID.push_back(id);
	}

	// reading volumes
	m_nbFaces.reserve(m_nbVolumes*4);
	m_emb.reserve(m_nbVolumes*12);

    unsigned int nbc = 0;

	for (unsigned int i = 0; i < m_nbVolumes ; ++i)
	{
		do
		{
			std::getline (fp, ligne);
		} while (ligne.size()==0);

		std::stringstream oss(ligne);
		int n;
		oss >> n; // type of volumes


        if(!oss.good())
        {
            oss.clear();
            char dummy;
            oss >> dummy; // type of volumes
            oss >> dummy;

            if(dummy == 'C')// connector
            {
                ++nbc;
                m_nbFaces.push_back(3);

                int s0,s1,s2,s3;

                oss >> s0;
                oss >> s1;
                oss >> s2;
                oss >> s3;

                //std::cout << "connector " << s0 << " " << s1 << " " << s2 << " " << s3 << std::endl;

                m_emb.push_back(verticesID[s0]);
                m_emb.push_back(verticesID[s1]);
                m_emb.push_back(verticesID[s2]);
                m_emb.push_back(verticesID[s3]);
            }
        }
Пример #11
0
void AHEMImporter<PFP>::LoadTopology()
{
    // Allocate vertices

	AttributeContainer& vxContainer = map->template getAttributeContainer<VERTEX>();

	verticesId = new unsigned int[hdr.meshHdr.vxCount];

	for(unsigned int i = 0 ; i < hdr.meshHdr.vxCount ; i++)
		verticesId[i] = vxContainer.insertLine();

	// Ensure vertices are created by querying the position attribute

	VertexAttribute<typename PFP::VEC3, typename PFP::MAP> position = map->template getAttribute<typename PFP::VEC3, VERTEX, typename PFP::MAP>("position");

	if (!position.isValid())
		position = map->template addAttribute<typename PFP::VEC3, VERTEX, typename PFP::MAP>("position");

	// Read faces stream and create faces [only intra-face links]
	
	HESorter* addedHE = new HESorter[hdr.meshHdr.heCount];

	facesId = new Dart[hdr.meshHdr.faceCount];

	f.read(buffer, hdr.meshHdr.meshChunkSize);
	char* batch = buffer;

	unsigned int fId = 0;
	unsigned int heId = 0;

	while(fId < hdr.meshHdr.faceCount)
	{
		AHEMFaceBatchDescriptor* fbd = (AHEMFaceBatchDescriptor*)batch;
		stUInt32* ix = (stUInt32*)(batch + sizeof(AHEMFaceBatchDescriptor));

		for(unsigned int i = 0 ; i < fbd->batchLength ; i++)
		{
			Dart d = map->newFace(fbd->batchFaceSize);							// create face
			facesId[fId++] = d;

			unsigned int firstVx = verticesId[*ix++];							// setup face's vertices up to last HE
			unsigned int prevVx = firstVx;

			for(unsigned int k = 0 ; k < fbd->batchFaceSize - 1 ; k++)
			{
				addedHE[heId].d = d;
				addedHE[heId].vxIdFrom = prevVx;
				addedHE[heId].vxIdTo = verticesId[*ix];

				map->setDartEmbedding<VERTEX>(d, prevVx);
				d = map->phi1(d);

				prevVx = *ix++;
				heId++;
			}

			// last HE

			addedHE[heId].d = d;
			addedHE[heId].vxIdFrom = prevVx;
			addedHE[heId].vxIdTo = firstVx;

			map->setDartEmbedding<VERTEX>(d, prevVx);
			heId++;
		}

		batch = (char*)ix;
	}

	// Sort the HE for fast retrieval

	std::sort(addedHE, addedHE + hdr.meshHdr.heCount);

	// Sew faces [inter-face links]

	for(unsigned int i = 0 ; i < hdr.meshHdr.heCount ; i++)
	{
		HESorter* opposite = (HESorter*)bsearch(addedHE + i, addedHE, hdr.meshHdr.heCount, sizeof(HESorter), OppositeSearch);

		if(opposite && opposite->d == map->phi2(opposite->d))
			map->sewFaces(addedHE[i].d, opposite->d);
	}
}
void Surface_DifferentialProperties_Plugin::computeCurvature(
	const QString& mapName,
	const QString& positionAttributeName,
	const QString& normalAttributeName,
	const QString& KmaxAttributeName,
	const QString& kmaxAttributeName,
	const QString& KminAttributeName,
	const QString& kminAttributeName,
	const QString& KnormalAttributeName,
	bool compute_kmean,
	bool compute_kgaussian,
	bool autoUpdate)
{
	MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m_schnapps->getMap(mapName));
	if(mh == NULL)
		return;

	VertexAttribute<PFP2::VEC3, PFP2::MAP> position = mh->getAttribute<PFP2::VEC3, VERTEX>(positionAttributeName);
	if(!position.isValid())
		return;

	VertexAttribute<PFP2::VEC3, PFP2::MAP> normal = mh->getAttribute<PFP2::VEC3, VERTEX>(normalAttributeName);
	if(!normal.isValid())
		return;

	VertexAttribute<PFP2::VEC3, PFP2::MAP> Kmax = mh->getAttribute<PFP2::VEC3, VERTEX>(KmaxAttributeName);
	if(!Kmax.isValid())
		Kmax = mh->addAttribute<PFP2::VEC3, VERTEX>(KmaxAttributeName);

	VertexAttribute<PFP2::REAL, PFP2::MAP> kmax = mh->getAttribute<PFP2::REAL, VERTEX>(kmaxAttributeName);
	if(!kmax.isValid())
		kmax = mh->addAttribute<PFP2::REAL, VERTEX>(kmaxAttributeName);

	VertexAttribute<PFP2::VEC3, PFP2::MAP> Kmin = mh->getAttribute<PFP2::VEC3, VERTEX>(KminAttributeName);
	if(!Kmin.isValid())
		Kmin = mh->addAttribute<PFP2::VEC3, VERTEX>(KminAttributeName);

	VertexAttribute<PFP2::REAL, PFP2::MAP> kmin = mh->getAttribute<PFP2::REAL, VERTEX>(kminAttributeName);
	if(!kmin.isValid())
		kmin = mh->addAttribute<PFP2::REAL, VERTEX>(kminAttributeName);

	VertexAttribute<PFP2::VEC3, PFP2::MAP> Knormal = mh->getAttribute<PFP2::VEC3, VERTEX>(KnormalAttributeName);
	if(!Knormal.isValid())
		Knormal = mh->addAttribute<PFP2::VEC3, VERTEX>(KnormalAttributeName);

	EdgeAttribute<PFP2::REAL, PFP2::MAP> edgeAngle = mh->getAttribute<PFP2::REAL, EDGE>("edgeAngle");
	if(!edgeAngle.isValid())
		edgeAngle = mh->addAttribute<PFP2::REAL, EDGE>("edgeAngle");

	PFP2::MAP* map = mh->getMap();
	Algo::Surface::Geometry::computeAnglesBetweenNormalsOnEdges<PFP2>(*map, position, edgeAngle);
	Algo::Surface::Geometry::computeCurvatureVertices_NormalCycles_Projected<PFP2>(*map, 0.01f * mh->getBBdiagSize(), position, normal, edgeAngle, kmax, kmin, Kmax, Kmin, Knormal);

	computeCurvatureLastParameters[mapName] =
		ComputeCurvatureParameters(
			positionAttributeName, normalAttributeName,
			KmaxAttributeName, kmaxAttributeName, KminAttributeName, kminAttributeName, KnormalAttributeName,
			compute_kmean, compute_kgaussian, autoUpdate);

	mh->notifyAttributeModification(Kmax);
	mh->notifyAttributeModification(kmax);
	mh->notifyAttributeModification(Kmin);
	mh->notifyAttributeModification(kmin);
	mh->notifyAttributeModification(Knormal);

	if(compute_kmean)
	{
		VertexAttribute<PFP2::REAL, PFP2::MAP> kmean = mh->getAttribute<PFP2::REAL, VERTEX>("kmean");
		if(!kmean.isValid())
			kmean = mh->addAttribute<PFP2::REAL, VERTEX>("kmean");

		for(unsigned int i = kmin.begin(); i != kmin.end(); kmin.next(i))
			kmean[i] = (kmin[i] + kmax[i]) / 2.0;

		mh->notifyAttributeModification(kmean);
	}

	if(compute_kgaussian)
	{
		VertexAttribute<PFP2::REAL, PFP2::MAP> kgaussian = mh->getAttribute<PFP2::REAL, VERTEX>("kgaussian");
		if(!kgaussian.isValid())
			kgaussian = mh->addAttribute<PFP2::REAL, VERTEX>("kgaussian");

		for(unsigned int i = kmin.begin(); i != kmin.end(); kmin.next(i))
			kgaussian[i] = kmin[i] * kmax[i];

		mh->notifyAttributeModification(kgaussian);
	}
}
Пример #13
0
int main()
{
	// declare a map to handle the mesh
	MAP myMap;

	// add position attribute on vertices and get handler on it
	VertexAttribute<VEC3, MAP> positionAtt = myMap.addAttribute<VEC3, VERTEX, MAP>("position");
	if (!positionAtt.isValid())
		std::cerr << "impossible to create an attribute with name position (already used ?)"<< std::endl;


	// create a topo grid of 2x2 squares
	Algo::Surface::Tilings::Square::Grid<PFP> grid(myMap, 2, 2, true);
	// and embed it using position attribute
	grid.embedIntoGrid(positionAtt, 1.,1.,0.);


	VertexGeneric(myMap,positionAtt);

	// ATTRIBUTE DECLARATION

	// add an attribute of type float on orbit EDGE
	EdgeAttribute<float, MAP> lengthAtt = myMap.addAttribute<float, EDGE, MAP>("length");
	if (!lengthAtt.isValid())
		std::cerr << "impossible to create the attribute"<< std::endl;

	computeLengthEdges(myMap,positionAtt,lengthAtt);

	// add an attribute of type std::string on orbit FACE
	FaceAttribute<std::string, MAP> nameAtt = myMap.addAttribute<std::string, FACE, MAP>("name");
	if (!nameAtt.isValid())
		std::cerr << "impossible to create the attribute"<< std::endl;

	// for complex type use following template (function nameOfType not applicable)
	EdgeAttribute< NoTypeNameAttribute< std::vector<int> >, MAP> vectAtt = myMap.addAttribute< NoTypeNameAttribute< std::vector<int> >, EDGE, MAP>("vector_of_int");
	if (!vectAtt.isValid())
		std::cerr << "impossible to create the attribute"<< std::endl;

	Dart d = myMap.begin();
	// define a vertex from a dart
	Vertex v(d);
	// define a face from a dart
	Face f(d);


	// ATTRIBUTE ACCESS

	// [] operator can take a dart, a cell (only same off attribute), or an unsigned inf
	// access to any attributes with darts
	std::cout << positionAtt[d]<< std::endl;
	nameAtt[d] = "Hello";
	lengthAtt[myMap.phi1(d)] = 54.0f;

	std::vector<int> vi = {3,5,7,9,11};
	vectAtt[d]= vi;
	vectAtt[d].push_back(11);

	// access to VertexAttribute with a Vertex
	std::cout << positionAtt[v]<< std::endl;

	// access to FaceAttribute with a Face
	std::cout << nameAtt[f]<< std::endl;

	// following line does not compile because of wrong cell type
	//	std::cout << positionAtt[f]<< std::endl;
	//  possible to bypass using dart access
	std::cout << positionAtt[f.dart]<< std::endl;

	// access with unsigned int is dangerous, index must be obtain with begin/end/next (see dumpAttribute)

	// COPY, REMOVE, SWAP

	// possible to have any number of attribute a same ORBIT
	VertexAttribute<VEC3, MAP> position2Att = myMap.addAttribute<VEC3, VERTEX, MAP>("other_position");

	// copy of attribute of same type (linear complexity)
	myMap.copyAttribute(position2Att,positionAtt);

	positionAtt[v] += VEC3(0,0,1);

	computeNewPositions(myMap,positionAtt);
	dumpAttribute(positionAtt);

	//check if there is a Vertex Attribute of VEC3 named position => yes
	testVAbyNames(myMap,"position");

	// remove the attribute
	myMap.removeAttribute(positionAtt);

	//check if there is a Vertex Attribute of VEC3 named position => no
	testVAbyNames(myMap,"position");

	return 0;
}
Пример #14
0
void Surface_Radiance_Plugin::decimate(const QString& mapName, const QString& positionAttributeName, const QString& normalAttributeName, float decimationGoal, bool halfCollapse, bool exportMeshes)
{
	MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m_schnapps->getMap(mapName));
	if(mh == NULL)
		return;

	VertexAttribute<PFP2::VEC3, PFP2::MAP> position = mh->getAttribute<PFP2::VEC3, VERTEX>(positionAttributeName);
	if(!position.isValid())
		return;

	VertexAttribute<PFP2::VEC3, PFP2::MAP> normal = mh->getAttribute<PFP2::VEC3, VERTEX>(normalAttributeName);
	if(!normal.isValid())
		return;

	PFP2::MAP* map = mh->getMap();

	unsigned int nbVertices = Algo::Topo::getNbOrbits<VERTEX>(*map);

	MapParameters& mapParams = h_mapParameterSet[mh];

	if (halfCollapse)
	{
		if (mapParams.positionApproximator == NULL)
		{
			mapParams.positionApproximator = new Algo::Surface::Decimation::Approximator_HalfCollapse<PFP2, PFP2::VEC3>(*map, position);
		}

		if (mapParams.normalApproximator == NULL)
		{
			mapParams.normalApproximator = new Algo::Surface::Decimation::Approximator_HalfCollapse<PFP2, PFP2::VEC3>(*map, normal);
		}

		if (mapParams.radianceApproximator == NULL)
		{
			mapParams.radianceApproximator = new Algo::Surface::Decimation::Approximator_HalfCollapse<PFP2, Utils::SphericalHarmonics<PFP2::REAL, PFP2::VEC3> >(*map, mapParams.radiance);
		}

		if (mapParams.selector == NULL)
		{
			mapParams.selector = new HalfEdgeSelector_Radiance<PFP2>(
				*map,
				position,
				normal,
				mapParams.radiance,
				*(Algo::Surface::Decimation::Approximator<PFP2, PFP2::VEC3, DART>*)(mapParams.positionApproximator),
				*(Algo::Surface::Decimation::Approximator<PFP2, PFP2::VEC3, DART>*)(mapParams.normalApproximator),
				*(Algo::Surface::Decimation::Approximator<PFP2, Utils::SphericalHarmonics<PFP2::REAL, PFP2::VEC3>, DART>*)(mapParams.radianceApproximator)
			);
		}
	}
	else
	{
		if (mapParams.positionApproximator == NULL)
		{
			mapParams.positionApproximator = new Algo::Surface::Decimation::Approximator_QEM<PFP2>(*map, position);
		}

		if (mapParams.normalApproximator == NULL)
		{
			mapParams.normalApproximator =
				new Algo::Surface::Decimation::Approximator_InterpolateAlongEdge<PFP2, PFP2::VEC3>(
					*map,
					normal,
					position,
					((Algo::Surface::Decimation::Approximator<PFP2, PFP2::VEC3, EDGE>*)(mapParams.positionApproximator))->getApproximationResultAttribute()
				);
		}

		if (mapParams.radianceApproximator == NULL)
		{
			mapParams.radianceApproximator =
				new Algo::Surface::Decimation::Approximator_InterpolateAlongEdge<PFP2, Utils::SphericalHarmonics<PFP2::REAL, PFP2::VEC3> >(
					*map,
					mapParams.radiance,
					position,
					((Algo::Surface::Decimation::Approximator<PFP2, PFP2::VEC3, EDGE>*)(mapParams.positionApproximator))->getApproximationResultAttribute()
				);
		}

		if (mapParams.selector == NULL)
		{
			mapParams.selector =
				new EdgeSelector_Radiance<PFP2>(
					*map,
					position,
					normal,
					mapParams.radiance,
					*(Algo::Surface::Decimation::Approximator<PFP2, PFP2::VEC3, EDGE>*)(mapParams.positionApproximator),
					*(Algo::Surface::Decimation::Approximator<PFP2, PFP2::VEC3, EDGE>*)(mapParams.normalApproximator),
					*(Algo::Surface::Decimation::Approximator<PFP2, Utils::SphericalHarmonics<PFP2::REAL, PFP2::VEC3>, EDGE>*)(mapParams.radianceApproximator)
				);

			mapParams.selector =
				new Algo::Surface::Decimation::EdgeSelector_QEM<PFP2>(
					*map,
					position,
					*(Algo::Surface::Decimation::Approximator<PFP2, PFP2::VEC3, EDGE>*)(mapParams.positionApproximator)
				);
		}
	}

	std::vector<Algo::Surface::Decimation::ApproximatorGen<PFP2>*> approximators;
	approximators.push_back(mapParams.positionApproximator);
	approximators.push_back(mapParams.normalApproximator);
	approximators.push_back(mapParams.radianceApproximator);

	exportNbVert.clear();
	if (exportMeshes)
	{
		unsigned int goalNbV = decimationGoal * nbVertices;
		unsigned int curNbV = nbVertices / 2;
		while (curNbV > goalNbV)
		{
			exportNbVert.push_back(curNbV);
			curNbV /= 2;
		}
		exportNbVert.push_back(goalNbV);
		nextExportIndex = 0;
	}

	std::cout << "nb vert -> " << nbVertices << std::endl;
	for (unsigned int v : exportNbVert)
	{
		std::cout << v << std::endl;
	}

	m_currentlyDecimatedMap = mh;
	m_currentDecimationHalf = halfCollapse;
	Algo::Surface::Decimation::decimate<PFP2>(*map, mapParams.selector, approximators, decimationGoal * nbVertices, true, NULL, (void (*)(void*, const void*))(Surface_Radiance_Plugin::checkNbVerticesAndExport), (void*)(this));
	m_currentlyDecimatedMap = NULL;

	mh->notifyConnectivityModification();
	mh->notifyAttributeModification(position);
}
Пример #15
0
bool MeshTablesSurface<PFP>::importObj(const std::string& filename, std::vector<std::string>& attrNames)
{
	VertexAttribute<typename PFP::VEC3> positions =  m_map.template getAttribute<typename PFP::VEC3, VERTEX>("position") ;

	if (!positions.isValid())
		positions = m_map.template addAttribute<typename PFP::VEC3, VERTEX>("position") ;

	attrNames.push_back(positions.name()) ;

	AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

	// open file
	std::ifstream fp(filename.c_str(), std::ios::binary);
	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}

//	fp.seekg(0, std::ios::end);
//	int ab = fp.tellg();
//	fp.seekg(0, std::ios::beg);
//	int ac = fp.tellg();

    std::string ligne;
    std::string tag;

    do
    {
    	fp >> tag;
    	std::getline (fp, ligne);
    }while (tag != std::string("v"));

    // lecture des sommets
	std::vector<unsigned int> verticesID;
	verticesID.reserve(102400); // on tape large (400Ko wahouuuuu !!)

	unsigned int i = 0;
    do
    {
		if (tag == std::string("v"))
		{
			std::stringstream oss(ligne);
		
			float x,y,z;
			oss >> x;
			oss >> y;
			oss >> z;

			VEC3 pos(x,y,z);

			unsigned int id = container.insertLine();
			positions[id] = pos;

			verticesID.push_back(id);
			i++;
		}

		fp >> tag;
    	std::getline(fp, ligne);
    } while (!fp.eof());
Пример #16
0
bool MeshTablesSurface<PFP>::importMeshBin(const std::string& filename, std::vector<std::string>& attrNames)
{
	VertexAttribute<typename PFP::VEC3> positions = m_map.template getAttribute<typename PFP::VEC3, VERTEX>("position") ;

	if (!positions.isValid())
	{
		positions = m_map.template addAttribute<typename PFP::VEC3, VERTEX>("position") ;
	}

	attrNames.push_back(positions.name()) ;

	AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

	// open file
	std::ifstream fp(filename.c_str(), std::ios::in | std::ios::binary);
	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}

	// Read header
    unsigned int Fmin, Fmax ;
    fp.read((char*)&m_nbVertices, sizeof(unsigned int)) ;
    fp.read((char*)&m_nbFaces, sizeof(unsigned int)) ;
    fp.read((char*)&Fmin, sizeof(unsigned int)) ;
    fp.read((char*)&Fmax, sizeof(unsigned int)) ;

    assert((Fmin == 3 && Fmax == 3) || !"Only triangular faces are handled yet") ;

    // Read foreach vertex
	std::vector<unsigned int> verticesID ;
	verticesID.reserve(m_nbVertices) ;

    for (unsigned int vxNum = 0 ; vxNum < m_nbVertices ; ++vxNum)
    {
    	Geom::Vec3f pos ;
    	fp.read((char*) &pos[0], sizeof(float)) ;
    	fp.read((char*) &pos[1], sizeof(float)) ;
    	fp.read((char*) &pos[2], sizeof(float)) ;

		unsigned int id = container.insertLine() ;
		positions[id] = pos ;

		verticesID.push_back(id) ;
    }

    // Read foreach face
	m_nbEdges.reserve(m_nbFaces) ;
	m_emb.reserve(m_nbVertices * 8) ;

	for (unsigned int fNum = 0; fNum < m_nbFaces; ++fNum)
	{
		const unsigned int faceSize = 3 ;
		fp.read((char*) &faceSize, sizeof(float)) ;
		m_nbEdges.push_back(faceSize) ;

		for (unsigned int i = 0 ; i < faceSize; ++i)
		{
			unsigned int index ; // index of embedding
			fp.read((char*) &index, sizeof(unsigned int)) ;
			m_emb.push_back(verticesID[index]) ;
		}
	}

	fp.close() ;
	return true ;
}
Пример #17
0
bool MeshTablesSurface<PFP>::importOff(const std::string& filename, std::vector<std::string>& attrNames)
{
	VertexAttribute<typename PFP::VEC3> positions = m_map.template getAttribute<typename PFP::VEC3, VERTEX>("position") ;

	if (!positions.isValid())
		positions = m_map.template addAttribute<typename PFP::VEC3, VERTEX>("position") ;

	attrNames.push_back(positions.name()) ;

	AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

	// open file
	std::ifstream fp(filename.c_str(), std::ios::in);
	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}

    std::string ligne;

    // lecture de OFF
    std::getline (fp, ligne);
    if (ligne.rfind("OFF") == std::string::npos)
    {
		CGoGNerr << "Problem reading off file: not an off file" << CGoGNendl;
		CGoGNerr << ligne << CGoGNendl;
		return false;
    }

    // lecture des nombres de sommets/faces/aretes
	int nbe;
    {
    	do
    	{
    		std::getline (fp, ligne);
    	} while (ligne.size() == 0);

	    std::stringstream oss(ligne);
		oss >> m_nbVertices;
		oss >> m_nbFaces;
		oss >> nbe;
    }

	//lecture sommets
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);
	for (unsigned int i = 0; i < m_nbVertices;++i)
	{
    	do
    	{
    		std::getline (fp, ligne);
    	} while (ligne.size() == 0);

		std::stringstream oss(ligne);

		float x,y,z;
		oss >> x;
		oss >> y;
		oss >> z;
		// on peut ajouter ici la lecture de couleur si elle existe
		VEC3 pos(x,y,z);

		unsigned int id = container.insertLine();
		positions[id] = pos;

		verticesID.push_back(id);
	}

	// lecture faces
	// normalement nbVertices*8 devrait suffire largement
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(m_nbVertices*8);

	for (unsigned int i = 0; i < m_nbFaces; ++i)
	{
    	do
    	{
    		std::getline (fp, ligne);
    	} while (ligne.size() == 0);

		std::stringstream oss(ligne);
		unsigned int n;
		oss >> n;
		m_nbEdges.push_back(n);
		for (unsigned int j = 0; j < n; ++j)
		{
			int index; // index du plongement
			oss >> index;
			m_emb.push_back(verticesID[index]);
		}
		// on peut ajouter ici la lecture de couleur si elle existe
	}

	fp.close();
	return true;
}
Пример #18
0
bool MeshTablesSurface<PFP>::importTrianBinGz(const std::string& filename, std::vector<std::string>& attrNames)
{
	VertexAttribute<typename PFP::VEC3> positions =  m_map.template getAttribute<typename PFP::VEC3, VERTEX>("position") ;

	if (!positions.isValid())
		positions = m_map.template addAttribute<typename PFP::VEC3, VERTEX>("position") ;

	attrNames.push_back(positions.name()) ;

	AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

	// open file
	igzstream fs(filename.c_str(), std::ios::in|std::ios::binary);

	if (!fs.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}

	// read nb of points
	fs.read(reinterpret_cast<char*>(&m_nbVertices), sizeof(int));

	// read points
	std::vector<unsigned int> verticesID;
	{	// juste pour limiter la portee des variables
		verticesID.reserve(m_nbVertices);
		float* buffer = new float[m_nbVertices*3];
		fs.read(reinterpret_cast<char*>(buffer), 3*m_nbVertices*sizeof(float));
		float *ptr = buffer;
		for (unsigned int i = 0; i < m_nbVertices; ++i)
		{
			VEC3 pos;
			pos[0]= *ptr++;
			pos[1]= *ptr++;
			pos[2]= *ptr++;

			unsigned int id = container.insertLine();
			positions[id] = pos;

			verticesID.push_back(id);
		}
		delete[] buffer;
	}

	// read nb of faces
	fs.read(reinterpret_cast<char*>(&m_nbFaces), sizeof(int));
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

	// read indices of faces
	{	// juste pour limiter la portee des variables
		int* buffer = new int[m_nbFaces*6];
		fs.read(reinterpret_cast<char*>(buffer),6*m_nbFaces*sizeof(float));
		int *ptr = buffer;

		for (unsigned int i = 0; i < m_nbFaces; i++)
		{
			m_nbEdges.push_back(3);
			m_emb.push_back(verticesID[*ptr++]);
			m_emb.push_back(verticesID[*ptr++]);
			m_emb.push_back(verticesID[*ptr++]);
		}
	}
	
	fs.close();
	return true;
}
Пример #19
0
bool MeshTablesSurface<PFP>::importTrian(const std::string& filename, std::vector<std::string>& attrNames)
{
	VertexAttribute<typename PFP::VEC3> positions =  m_map.template getAttribute<typename PFP::VEC3, VERTEX>("position") ;

	if (!positions.isValid())
		positions = m_map.template addAttribute<typename PFP::VEC3, VERTEX>("position") ;

	attrNames.push_back(positions.name()) ;

	AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

	// open file
	std::ifstream fp(filename.c_str(), std::ios::in);
	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}

	// read nb of points
	fp >> m_nbVertices;

	// read points
	std::vector<unsigned int> verticesID;
	verticesID.reserve(m_nbVertices);

	for (unsigned int i = 0; i < m_nbVertices; ++i)
	{
		VEC3 pos;
		fp >> pos[0];
		fp >> pos[1];
		fp >> pos[2];
		unsigned int id = container.insertLine();
		positions[id] = pos;
		verticesID.push_back(id);
	}

	// read nb of faces
	fp >> m_nbFaces;
	m_nbEdges.reserve(m_nbFaces);
	m_emb.reserve(3*m_nbFaces);

	// read indices of faces
	for (unsigned int i = 0; i < m_nbFaces; ++i)
	{
		m_nbEdges.push_back(3);
		// read the three vertices of triangle
		int pt;
		fp >> pt;
		m_emb.push_back(verticesID[pt]);
		fp >> pt;
		m_emb.push_back(verticesID[pt]);
		fp >> pt;
		m_emb.push_back(verticesID[pt]);

		// neighbour not always good in files !!
		int neigh;
		fp >> neigh;
		fp >> neigh;
		fp >> neigh;
	}

	fp.close();
	return true;
}
Пример #20
0
void Surface_Radiance_Plugin::exportPLY(
	const QString& mapName,
	const QString& positionAttributeName,
	const QString& normalAttributeName,
	const QString& filename)
{
	typedef PFP2::MAP MAP;
	typedef PFP2::REAL REAL;
	typedef PFP2::VEC3 VEC3;

	MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m_schnapps->getMap(mapName));
	if(mh == NULL)
		return;

	VertexAttribute<VEC3, MAP> position = mh->getAttribute<VEC3, VERTEX>(positionAttributeName);
	if(!position.isValid())
		return;

	VertexAttribute<VEC3, MAP> normal = mh->getAttribute<VEC3, VERTEX>(normalAttributeName);
	if(!normal.isValid())
		return;

	VertexAttribute<Utils::SphericalHarmonics<REAL, VEC3>, MAP> radiance = h_mapParameterSet[mh].radiance;
	if(!radiance.isValid())
		return;

	// open file
	std::ofstream out ;
	out.open(filename.toStdString(), std::ios::out | std::ios::binary) ;

	if (!out.good())
	{
		CGoGNerr << "Unable to open file " << CGoGNendl ;
		return ;
	}

	MAP* map = mh->getMap();

	unsigned int nbDarts = map->getNbDarts() ;
	std::vector<unsigned int> facesSize ;
	std::vector<std::vector<unsigned int> > facesIdx ;
	facesSize.reserve(nbDarts/3) ;
	facesIdx.reserve(nbDarts/3) ;
	std::map<unsigned int, unsigned int> vIndex ;
	unsigned int vCpt = 0 ;
	std::vector<unsigned int> vertices ;
	vertices.reserve(nbDarts/6) ;

	// Go over all faces
	CellMarker<MAP, VERTEX> markV(*map) ;
	TraversorF<MAP> t(*map) ;
	for(Dart d = t.begin(); d != t.end(); d = t.next())
	{
		std::vector<unsigned int> fidx ;
		fidx.reserve(8) ;
		unsigned int degree = 0 ;
		Traversor2FV<MAP> tfv(*map, d) ;
		for(Dart it = tfv.begin(); it != tfv.end(); it = tfv.next())
		{
			++degree ;
			unsigned int vNum = map->getEmbedding<VERTEX>(it) ;
			if(!markV.isMarked(it))
			{
				markV.mark(it) ;
				vIndex[vNum] = vCpt++ ;
				vertices.push_back(vNum) ;
			}
			fidx.push_back(vIndex[vNum]) ;
		}
		facesSize.push_back(degree) ;
		facesIdx.push_back(fidx) ;
	}

	// Start writing the file
	out << "ply" << std::endl ;

	// test endianness
	union
	{
		uint32_t i ;
		char c[4] ;
	} bint = {0x01020304} ;
	if (bint.c[0] == 1) // big endian
		out << "format binary_big_endian 1.0" << std::endl ;
	else
		out << "format binary_little_endian 1.0" << std::endl ;

	out << "comment File generated by the CGoGN library" << std::endl ;
	out << "comment See : http://cgogn.unistra.fr/" << std::endl ;
	out << "comment or contact : [email protected]" << std::endl ;
	// Vertex elements
	out << "element vertex " << vertices.size() << std::endl ;

	std::string nameOfTypePly_REAL(nameOfTypePly(position[0][0])) ;

	out << "property " << nameOfTypePly_REAL << " x" << std::endl ;
	out << "property " << nameOfTypePly_REAL << " y" << std::endl ;
	out << "property " << nameOfTypePly_REAL << " z" << std::endl ;


	out << "property " << nameOfTypePly_REAL << " nx" << std::endl ;
	out << "property " << nameOfTypePly_REAL << " ny" << std::endl ;
	out << "property " << nameOfTypePly_REAL << " nz" << std::endl ;

	int res = Utils::SphericalHarmonics<REAL, VEC3>::get_resolution() ;
	for (int l = 0 ; l <= res ; ++l)
	{
		for (int m = -l ; m <= l ; ++m)
		{
			out << "property " << nameOfTypePly_REAL << " SHcoef_" << l << "_" << m << "_r" << std::endl ;
			out << "property " << nameOfTypePly_REAL << " SHcoef_" << l << "_" << m << "_g" << std::endl ;
			out << "property " << nameOfTypePly_REAL << " SHcoef_" << l << "_" << m << "_b" << std::endl ;
		}
	}

	// Face element
	out << "element face " << facesSize.size() << std::endl ;
	out << "property list uint8 " << nameOfTypePly(facesIdx[0][0]) << " vertex_indices" << std::endl ;
	out << "end_header" << std::endl ;

	// binary vertices
	for(unsigned int i = 0; i < vertices.size(); ++i)
	{
		const VEC3& p = position[vertices[i]] ;
		out.write((char*)(&(p[0])), sizeof(p)) ;
		const VEC3& n = normal[vertices[i]] ;
		out.write((char*)(&(n[0])), sizeof(n)) ;

		for (int l=0 ; l <= res ; ++l)
		{
			for (int m=-l ; m <= l ; ++m)
			{
				const VEC3& r = radiance[vertices[i]].get_coef(l,m) ;
				out.write((char*)(&(r[0])), sizeof(r)) ;
			}
		}
	}

	// binary faces
	for(unsigned int i = 0; i < facesSize.size(); ++i)
	{
		uint8_t nbe = facesSize[i] ;
		out.write((char*)(&nbe), sizeof(uint8_t)) ;
		out.write((char*)(&(facesIdx[i][0])), facesSize[i] * sizeof(facesIdx[i][0])) ;
	}

	out.close() ;

	this->pythonRecording("exportPLY", "", mapName, positionAttributeName, normalAttributeName, filename);
}
Пример #21
0
bool MeshTablesVolume<PFP>::importTet(const std::string& filename, std::vector<std::string>& attrNames, float scaleFactor)
{
	VertexAttribute<VEC3> positions =  m_map.template getAttribute<VEC3, VERTEX>("position") ;

	if (!positions.isValid())
		positions = m_map.template addAttribute<VEC3, VERTEX>("position") ;

	attrNames.push_back(positions.name()) ;

	AttributeContainer& container = m_map.template getAttributeContainer<VERTEX>() ;

	//open file
	std::ifstream fp(filename.c_str(), std::ios::in);
	if (!fp.good())
	{
		CGoGNerr << "Unable to open file " << filename << CGoGNendl;
		return false;
	}

	std::string ligne;
	unsigned int nbv, nbt;
	// reading number of vertices
	std::getline (fp, ligne);
	std::stringstream oss(ligne);
	oss >> nbv;

	// reading number of tetrahedra
	std::getline (fp, ligne);
	std::stringstream oss2(ligne);
	oss2 >> nbt;

	//reading vertices
	std::vector<unsigned int> verticesID;
	verticesID.reserve(nbv);
	for(unsigned int i = 0; i < nbv;++i)
	{
		do
		{
			std::getline (fp, ligne);
		} while (ligne.size() == 0);

		std::stringstream oss(ligne);

		float x,y,z;
		oss >> x;
		oss >> y;
		oss >> z;
		// TODO : if required read other vertices attributes here
		VEC3 pos(x*scaleFactor,y*scaleFactor,z*scaleFactor);

		unsigned int id = container.insertLine();
		positions[id] = pos;

		verticesID.push_back(id);
	}

	m_nbVertices = nbv;
	m_nbVolumes = nbt;


	// lecture tetra
	// normalement m_nbVolumes*12 (car on ne charge que des tetra)

	m_nbFaces=nbt*4;
	m_emb.reserve(nbt*12);

	for (unsigned int i = 0; i < m_nbVolumes ; ++i)
	{
    	do
    	{
    		std::getline (fp, ligne);
    	} while (ligne.size()==0);

		std::stringstream oss(ligne);
		int n;
		oss >> n; // nb de faces d'un volume ?

		m_nbEdges.push_back(3);
		m_nbEdges.push_back(3);
		m_nbEdges.push_back(3);
		m_nbEdges.push_back(3);

		int s0,s1,s2,s3;

		oss >> s0;
		oss >> s1;
		oss >> s2;
		oss >> s3;

		m_emb.push_back(verticesID[s0]);
		m_emb.push_back(verticesID[s1]);
		m_emb.push_back(verticesID[s2]);

		m_emb.push_back(verticesID[s1]);
		m_emb.push_back(verticesID[s0]);
		m_emb.push_back(verticesID[s3]);

		m_emb.push_back(verticesID[s2]);
		m_emb.push_back(verticesID[s1]);
		m_emb.push_back(verticesID[s3]);

		m_emb.push_back(verticesID[s0]);
		m_emb.push_back(verticesID[s2]);
		m_emb.push_back(verticesID[s3]);
	}

	fp.close();
	return true;
}