/** * 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; }
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; }
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(); }
/** * 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; }
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(); }
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); }
/** * 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); }
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++; }