Exemplo n.º 1
0
/** 
 * Returns a new face (quad or triangle) from the merge of one quad and one 
 * triangle that share the vertex v and come from the same original face.
 * @param faceI mesh quad
 * @param faceJ mesh triangle
 * @param pending vector with pending vertices (required to merge one quad 
 * and one triangle into a new triangle; it supposes to remove two vertexs,
 * v and its neighbour, that will be a new pending vertex if it wasn't)
 * @param v vertex index shared by both faces
 * @return If the merge is possible, a new face without v
 */
BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face3 *faceJ, BOP_Indexs &pending, BOP_Index v)
{
	BOP_Face *faceK = NULL;

	// Get faces data
	BOP_Index prevI, nextI, opp, prevJ, nextJ;
	faceI->getNeighbours(v,prevI,nextI,opp);
	faceJ->getNeighbours(v,prevJ,nextJ);
	MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
	MT_Point3 vOpp = m_mesh->getVertex(opp)->getPoint();
	MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
	MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
	MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
	MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();

	// Merge test
	if (prevI == nextJ) {
		if (BOP_between(vertex,vNextI,vPrevJ)) {
			if (!BOP_collinear(vPrevJ,vPrevI,vOpp) && BOP_convex(vOpp,vPrevI,vPrevJ,vNextI)) {
				// The result is a new quad
				faceK = new BOP_Face4(opp,prevI,prevJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
			}
			else if (BOP_between(vPrevI,vPrevJ,vOpp)) {
				// The result is a triangle (only if prevI can be merged)
				if (prevI < m_firstVertex) return NULL; // It can't be merged
				faceK = new BOP_Face3(nextI,opp,prevJ,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
				if (!containsIndex(pending, prevI)) pending.push_back(prevI);
			}
		}
	}
	else if (nextI == prevJ) {
		if (BOP_between(vertex,vPrevI,vNextJ)) {
			if (!BOP_collinear(vNextJ,vNextI,vOpp) && BOP_convex(vOpp,vPrevI,vNextJ,vNextI)) {
				// The result is a new quad
				faceK = new BOP_Face4(opp,prevI,nextJ,nextI,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
			}
			else if (BOP_between(vNextI,vOpp,vNextJ)) {
				// The result is a triangle (only if nextI can be merged)
				if (nextI < m_firstVertex) return NULL;
				faceK = new BOP_Face3(prevI,nextJ,opp,faceI->getPlane(),faceI->getOriginalFace());
				faceK->setTAG(faceI->getTAG());
				if (!containsIndex(pending, nextI)) pending.push_back(nextI);
			}
		}
	}
	return faceK;
}
Exemplo n.º 2
0
IDBIndex* IDBObjectStore::createIndex(ScriptState* scriptState, const String& name, const IDBKeyPath& keyPath, const IDBIndexParameters& options, ExceptionState& exceptionState)
{
    IDB_TRACE("IDBObjectStore::createIndex");
    if (!m_transaction->isVersionChange()) {
        exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVersionChangeTransactionErrorMessage);
        return nullptr;
    }
    if (isDeleted()) {
        exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage);
        return nullptr;
    }
    if (m_transaction->isFinished() || m_transaction->isFinishing()) {
        exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage);
        return nullptr;
    }
    if (!m_transaction->isActive()) {
        exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage);
        return nullptr;
    }
    if (!keyPath.isValid()) {
        exceptionState.throwDOMException(SyntaxError, "The keyPath argument contains an invalid key path.");
        return nullptr;
    }
    if (containsIndex(name)) {
        exceptionState.throwDOMException(ConstraintError, "An index with the specified name already exists.");
        return nullptr;
    }

    if (keyPath.type() == IDBKeyPath::ArrayType && options.multiEntry()) {
        exceptionState.throwDOMException(InvalidAccessError, "The keyPath argument was an array and the multiEntry option is true.");
        return nullptr;
    }
    if (!backendDB()) {
        exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databaseClosedErrorMessage);
        return nullptr;
    }

    int64_t indexId = m_metadata.maxIndexId + 1;
    backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, options.unique(), options.multiEntry());

    ++m_metadata.maxIndexId;

    IDBIndexMetadata metadata(name, indexId, keyPath, options.unique(), options.multiEntry());
    IDBIndex* index = IDBIndex::create(metadata, this, m_transaction.get());
    m_indexMap.set(name, index);
    m_metadata.indexes.set(indexId, metadata);
    m_transaction->db()->indexCreated(id(), metadata);

    ASSERT(!exceptionState.hadException());
    if (exceptionState.hadException())
        return nullptr;

    IDBRequest* indexRequest = openCursor(scriptState, nullptr, WebIDBCursorDirectionNext, WebIDBTaskTypePreemptive);
    indexRequest->preventPropagation();

    // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction.
    RefPtrWillBeRawPtr<IndexPopulator> indexPopulator = IndexPopulator::create(scriptState, transaction()->db(), m_transaction->id(), id(), metadata);
    indexRequest->setOnsuccess(indexPopulator);
    return index;
}
Exemplo n.º 3
0
PassRefPtr<IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, ExceptionCode& ec)
{
    IDB_TRACE("IDBObjectStore::createIndex");
    if (!m_transaction->isVersionChange() || isDeleted()) {
        ec = IDBDatabaseException::InvalidStateError;
        return 0;
    }
    if (!m_transaction->isActive()) {
        ec = IDBDatabaseException::TransactionInactiveError;
        return 0;
    }
    if (!keyPath.isValid()) {
        ec = IDBDatabaseException::SyntaxError;
        return 0;
    }
    if (name.isNull()) {
        ec = TypeError;
        return 0;
    }
    if (containsIndex(name)) {
        ec = IDBDatabaseException::ConstraintError;
        return 0;
    }

    if (keyPath.type() == IDBKeyPath::ArrayType && multiEntry) {
        ec = IDBDatabaseException::InvalidAccessError;
        return 0;
    }

    int64_t indexId = m_metadata.maxIndexId + 1;
    backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, unique, multiEntry);

    ++m_metadata.maxIndexId;

    IDBIndexMetadata metadata(name, indexId, keyPath, unique, multiEntry);
    RefPtr<IDBIndex> index = IDBIndex::create(metadata, this, m_transaction.get());
    m_indexMap.set(name, index);
    m_metadata.indexes.set(indexId, metadata);
    m_transaction->db()->indexCreated(id(), metadata);

    ASSERT(!ec);
    if (ec)
        return 0;

    RefPtr<IDBRequest> indexRequest = openCursor(context, static_cast<IDBKeyRange*>(0), IDBCursor::directionNext(), IDBDatabaseBackendInterface::PreemptiveTask, ec);
    ASSERT(!ec);
    if (ec)
        return 0;
    indexRequest->preventPropagation();

    // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction.
    RefPtr<IndexPopulator> indexPopulator = IndexPopulator::create(backendDB(), m_transaction->id(), id(), metadata);
    indexRequest->setOnsuccess(indexPopulator);

    return index.release();
}
Exemplo n.º 4
0
/** 
 * Returns a new quad from the merge of two quads that share 
 * the vertex v and come from the same original face.
 * @param faceI mesh quad
 * @param faceJ mesh quad
 * @param pending vector with pending vertices (required to merge the two
 * quads supposes to remove two vertexs, v and its neighbour, 
 * that will be a new pending vertex if it wasn't)
 * @param v vertex index shared by both quads
 * @return If the merge is possible, a new quad without v
 */
BOP_Face* BOP_Merge::mergeFaces(BOP_Face4 *faceI, BOP_Face4 *faceJ, BOP_Indexs &pending, BOP_Index v)
{
	BOP_Face *faceK = NULL;

	// Get faces data
	BOP_Index prevI, nextI, oppI, prevJ, nextJ, oppJ;
	faceI->getNeighbours(v,prevI,nextI,oppI);
	faceJ->getNeighbours(v,prevJ,nextJ,oppJ);
	MT_Point3 vertex = m_mesh->getVertex(v)->getPoint();
	MT_Point3 vPrevI = m_mesh->getVertex(prevI)->getPoint();
	MT_Point3 vNextI = m_mesh->getVertex(nextI)->getPoint();
	MT_Point3 vOppI = m_mesh->getVertex(oppI)->getPoint();
	MT_Point3 vPrevJ = m_mesh->getVertex(prevJ)->getPoint();
	MT_Point3 vNextJ = m_mesh->getVertex(nextJ)->getPoint();
	MT_Point3 vOppJ = m_mesh->getVertex(oppJ)->getPoint();

	// Merge test
	if (prevI == nextJ) {
		// prevI/nextJ will be a new vertex required to merge
		if (prevI < m_firstVertex) return NULL; // It can't be merged
		if (BOP_between(vertex,vPrevJ,vNextI) && BOP_between(vNextJ,vOppJ,vOppI)) {
			faceK = new BOP_Face4(oppJ,prevJ,nextI,oppI,faceI->getPlane(),faceI->getOriginalFace());
			faceK->setTAG(faceI->getTAG());
			// We add prevI to the pending list if it wasn't yet
			if (!containsIndex(pending, prevI)) pending.push_back(prevI);
		}
	}
	else if (nextI == prevJ) {
		// nextI/prevJ will be a new vertex required to merge
		if (nextI < m_firstVertex) return NULL; // It can't be merged
		if (BOP_between(vertex,vPrevI,vNextJ) && BOP_between(vNextI,vOppI,vOppJ)) {
			faceK = new BOP_Face4(oppI,prevI,nextJ,oppJ,faceI->getPlane(),faceI->getOriginalFace());
			faceK->setTAG(faceI->getTAG());
			// Add nextI to the pending list if it wasn't yet
			if (!containsIndex(pending, nextI)) pending.push_back(nextI);
		}
	}
	return faceK;
}
Exemplo n.º 5
0
PassRefPtr<IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* context, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, ExceptionCode& ec)
{
    LOG(StorageAPI, "IDBObjectStore::createIndex");
    if (!m_transaction->isVersionChange() || m_deleted) {
        ec = IDBDatabaseException::InvalidStateError;
        return 0;
    }
    if (!m_transaction->isActive()) {
        ec = IDBDatabaseException::TransactionInactiveError;
        return 0;
    }
    if (!keyPath.isValid()) {
        ec = IDBDatabaseException::SyntaxError;
        return 0;
    }
    if (name.isNull()) {
        ec = TypeError;
        return 0;
    }
    if (containsIndex(name)) {
        ec = IDBDatabaseException::ConstraintError;
        return 0;
    }

    if (keyPath.type() == IDBKeyPath::ArrayType && multiEntry) {
        ec = IDBDatabaseException::InvalidAccessError;
        return 0;
    }

    int64_t indexId = m_metadata.maxIndexId + 1;
    backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, unique, multiEntry);

    ++m_metadata.maxIndexId;

    IDBIndexMetadata metadata(name, indexId, keyPath, unique, multiEntry);
    RefPtr<IDBIndex> index = IDBIndex::create(metadata, this, m_transaction.get());
    m_indexMap.set(name, index);
    m_metadata.indexes.set(indexId, metadata);

    ASSERT(!ec);
    if (ec)
        return 0;

    ASSERT_UNUSED(context, context);
    return index.release();
}
Exemplo n.º 6
0
bool IndexFactory::containsIndex(const char* db, const char* ns, const std::string& key) {
	std::set<std::string> keys;
	keys.insert(key);
	return containsIndex(db, ns, keys);
}
Exemplo n.º 7
0
/**
 * Simplifies a mesh, merging the faces with the specified vertices.
 * @param mergeVertices vertices to test
 * @return true if a face merge was performed
 */
bool BOP_Merge::mergeFaces(BOP_Indexs &mergeVertices)
{
	// Check size > 0!
	if (mergeVertices.size() == 0) return false;

	// New faces added by merge
	BOP_Faces newFaces;

	// Old faces removed by merge
	BOP_Faces oldFaces;

	// Get the first vertex index and add it to 
	// the current pending vertices to merge
	BOP_Index v = mergeVertices[0];
	BOP_Indexs pendingVertices;
	pendingVertices.push_back(v);

	// Get faces with index v that come from the same original face
	BOP_LFaces facesByOriginalFace;
	getFaces(facesByOriginalFace,v);

	bool merged = true;

	// Check it has any unbroken face
	if (facesByOriginalFace.size()==0) {
		// v has not any unbroken face (so it's a new BROKEN vertex)
		(m_mesh->getVertex(v))->setTAG(BROKEN);
		merged = false;
	}

	// Merge vertex faces	
	const BOP_IT_LFaces facesEnd = facesByOriginalFace.end();
	
	for(BOP_IT_LFaces facesByOriginalFaceX = facesByOriginalFace.begin();
		(facesByOriginalFaceX != facesEnd)&&merged;
		facesByOriginalFaceX++) {		
			merged = mergeFaces((*facesByOriginalFaceX),oldFaces,newFaces,pendingVertices,v);
	}

	// Check if the are some pendingVertices to merge
	if (pendingVertices.size() > 1 && merged) {
		// There are pending vertices that we need to merge in order to merge v ...
		for(unsigned int i=1;i<pendingVertices.size() && merged;i++) 
			merged = mergeFaces(oldFaces,newFaces,pendingVertices,pendingVertices[i]);
	}

	// If merge was succesful ...
	if (merged) {
		// Set old faces to BROKEN...
	  const BOP_IT_Faces oldFacesEnd = oldFaces.end();
		for(BOP_IT_Faces face=oldFaces.begin();face!=oldFacesEnd;face++) 
			(*face)->setTAG(BROKEN);

		// ... and add merged faces (that are the new merged faces without pending vertices)
		const BOP_IT_Faces newFacesEnd = newFaces.end();
		for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) {
			m_mesh->addFace(*newFace);
			// Also, add new face vertices to the queue of vertices to merge if they weren't
			for(BOP_Index i = 0;i<(*newFace)->size();i++) {
				BOP_Index vertexIndex = (*newFace)->getVertex(i);
				if (vertexIndex >= m_firstVertex && !containsIndex(mergeVertices,vertexIndex))
					mergeVertices.push_back(vertexIndex);
			}
		}
		// Set the merged vertices to BROKEN ...
		const BOP_IT_Indexs pendingEnd = pendingVertices.end();
		for(BOP_IT_Indexs pendingVertex = pendingVertices.begin(); pendingVertex != pendingEnd;pendingVertex++) {
			BOP_Index pV = *pendingVertex;
			m_mesh->getVertex(pV)->setTAG(BROKEN);
			// ... and remove them from mergeVertices queue
			const BOP_IT_Indexs mergeEnd = mergeVertices.end();
			for(BOP_IT_Indexs mergeVertex = mergeVertices.begin(); mergeVertex != mergeEnd;mergeVertex++) {
				BOP_Index mV = *mergeVertex;
				if (mV == pV) {
					mergeVertices.erase(mergeVertex);
					break;
				}
			}
		}
	}
	else {
		// The merge  was not succesful, remove the vertex frome merge vertices queue
		mergeVertices.erase(mergeVertices.begin());
		
		// free the not used newfaces
		const BOP_IT_Faces newFacesEnd = newFaces.end();
		for(BOP_IT_Faces newFace=newFaces.begin();newFace!=newFacesEnd;newFace++) {
			delete (*newFace);
		}
	}

	// Invoke mergeFaces and return the merge result
	return (mergeFaces(mergeVertices) || merged);
}
Exemplo n.º 8
0
void processFace( const char *line)
{
  static int i = 0;

  //Determine how many tokens the line contains
  char templine[ 256 ];
  char *token;
  int numOfTokens;

  strcpy( templine , line );
  
  numOfTokens     = 0;
  token           = strtok( templine, " \r\n" );

  while( token != NULL )
  {
    numOfTokens++;
    token     = strtok( NULL, " \r\n" );
  }

  // subtract the line identifying token 'f'
  numOfTokens -= 1;

  int *indexes      = calloc( numOfTokens, sizeof( int ) );
  assert( indexes );

  OBJModel.faces[ i ].count       = numOfTokens;
  OBJModel.faces[ i ].indexes     = indexes;

  //Get each token, append to the main index array if
  //it doesn't exist and add to the face's index list
  strcpy( templine , line );
  token = strtok( templine, " \r\n" ); // skip the first token

  token           = strtok( NULL, " \r\n" );
  
  int element = 0; 
  while( token != NULL )
  {

    int vertex    = 0;
    int normal    = 0;
    int texture   = 0; 
    
    //index vertex/texture/normal
    //has texture and normal
    if( OBJModel.numOfObjTex > 0 && OBJModel.numOfObjNormal > 0 )
    {
      sscanf( token, "%d/%d/%d", &vertex, &texture, &normal );
    } 
    //index vertex/texture 
    //has texture but no normal
    else if( OBJModel.numOfObjTex > 0 && OBJModel.numOfObjNormal == 0 )
    {
      sscanf( token, "%d/%d", &vertex, &normal );
    }
    //index vertex//normal 
    //has normal but no texture
    else if( OBJModel.numOfObjNormal > 0 && OBJModel.numOfObjTex == 0 )
    {
      sscanf( token, "%d//%d", &vertex, &normal );
    }
    //index vertex
    //has only a vertex
    else
    {
      sscanf( token, "%d", &vertex );
    }
    
    Index index;
    index.vertex  = 0;
    index.normal  = 0;
    index.texture = 0;

    if( vertex < 0 )
    {
      index.vertex  = OBJModel.numOfObjVertex + vertex;
    }
    else
    {
      index.vertex  = vertex - 1;
    }

    if( OBJModel.numOfObjNormal )
    {
      if( normal < 0 )
      {
        index.normal  = OBJModel.numOfObjNormal + normal;
      }
      else
      {
        index.normal  = normal - 1;
      }
    }

    if( OBJModel.numOfObjTex )
    {
      if( texture < 0 )
      {
        index.texture = OBJModel.numOfObjTex + texture;
      }
      else
      {
        index.texture = texture - 1;
      }
    }
    
    int indexElement  = containsIndex( OBJModel.indices, OBJModel.indexLength, &index );

    if( indexElement > -1 )
    { 
      OBJModel.faces[ i ].indexes[ element ]     = indexElement;
    }
    else
    { 
      if( OBJModel.indexCount < OBJModel.indexLength )
      {
        OBJModel.indices[ OBJModel.indexCount ] = index;
        OBJModel.faces[ i ].indexes[ element ]  = OBJModel.indexCount;
      }
      else
      {
        int newLength         = OBJModel.indexLength * 2;
        Index *indices        = realloc( OBJModel.indices, sizeof( Index ) * newLength );

        if( !indices )
        {
          printf( "Error allocating memory" );
          abort();
        }

        assert( indices );
        OBJModel.indices                        = indices;
        OBJModel.indexLength                    = newLength;
        OBJModel.indices[ OBJModel.indexCount ] = index;
        OBJModel.faces[ i ].indexes[ element ]  = OBJModel.indexCount;
      }
      OBJModel.indexCount++;
    } 
    element++;
    token           = strtok( NULL, " \r\n" );
  }
  //printf( "Post processface index:%d\r\n", i );
  i++;
}