void SQLiteStatementImpl::compileImpl() { if (!_pLeftover) { _bindBegin = bindings().begin(); } std::string statement(toString()); sqlite3_stmt* pStmt = 0; const char* pSql = _pLeftover ? _pLeftover->c_str() : statement.c_str(); if (0 == std::strlen(pSql)) throw InvalidSQLStatementException("Empty statements are illegal"); int rc = SQLITE_OK; const char* pLeftover = 0; bool queryFound = false; do { rc = sqlite3_prepare_v2(_pDB, pSql, -1, &pStmt, &pLeftover); if (rc != SQLITE_OK) { if (pStmt) sqlite3_finalize(pStmt); pStmt = 0; std::string errMsg = sqlite3_errmsg(_pDB); Utility::throwException(_pDB, rc, errMsg); } else if (rc == SQLITE_OK && pStmt) { queryFound = true; } else if (rc == SQLITE_OK && !pStmt) // comment/whitespace ignore { pSql = pLeftover; if (std::strlen(pSql) == 0) { // empty statement or an conditional statement! like CREATE IF NOT EXISTS // this is valid queryFound = true; } } } while (rc == SQLITE_OK && !pStmt && !queryFound); //Finalization call in clear() invalidates the pointer, so the value is remembered here. //For last statement in a batch (or a single statement), pLeftover == "", so the next call // to compileImpl() shall return false immediately when there are no more statements left. std::string leftOver(pLeftover); trimInPlace(leftOver); clear(); _pStmt = pStmt; if (!leftOver.empty()) { _pLeftover = new std::string(leftOver); _canCompile = true; } else _canCompile = false; _pBinder = new Binder(_pStmt); _pExtractor = new Extractor(_pStmt); if (SQLITE_DONE == _nextResponse && _isExtracted) { //if this is not the first compile and there has already been extraction //during previous step, switch to the next set if there is one provided if (hasMoreDataSets()) { activateNextDataSet(); _isExtracted = false; } } int colCount = sqlite3_column_count(_pStmt); if (colCount) { std::size_t curDataSet = currentDataSet(); if (curDataSet >= _columns.size()) _columns.resize(curDataSet + 1); for (int i = 0; i < colCount; ++i) { MetaColumn mc(i, sqlite3_column_name(_pStmt, i), Utility::getColumnType(_pStmt, i)); _columns[curDataSet].push_back(mc); } } }
dgInt32 dgPolygonSoupDatabaseBuilder::AddConvexFace(dgInt32 count, dgInt32* const pool, dgInt32* const facesArray) { dgPolySoupFilterAllocator polyhedra(m_allocator); count = polyhedra.AddFilterFace(dgUnsigned32(count), pool); dgEdge* edge = &polyhedra.GetRoot()->GetInfo(); if (edge->m_incidentFace < 0) { edge = edge->m_twin; } dgInt32 isconvex = 1; dgInt32 facesCount = 0; dgInt32 flag = 1; while (flag) { flag = 0; if (count >= 3) { dgEdge* ptr = edge; dgBigVector p0(&m_vertexPoints[ptr->m_incidentVertex].m_x); do { dgBigVector p1(&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x); dgBigVector e0(p1 - p0); dgFloat64 mag2 = e0 % e0; if (mag2 < dgFloat32(1.0e-6f)) { count--; flag = 1; edge = ptr->m_next; ptr->m_prev->m_next = ptr->m_next; ptr->m_next->m_prev = ptr->m_prev; ptr->m_twin->m_next->m_prev = ptr->m_twin->m_prev; ptr->m_twin->m_prev->m_next = ptr->m_twin->m_next; break; } p0 = p1; ptr = ptr->m_next; } while (ptr != edge); } } if (count >= 3) { flag = 1; while (flag) { flag = 0; if (count >= 3) { dgEdge* ptr = edge; dgBigVector p0(&m_vertexPoints[ptr->m_prev->m_incidentVertex].m_x); dgBigVector p1(&m_vertexPoints[ptr->m_incidentVertex].m_x); dgBigVector e0(p1 - p0); e0 = e0.Scale(dgRsqrt (e0 % e0 + dgFloat32(1.0e-10f))); do { dgBigVector p2(&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x); dgBigVector e1(p2 - p1); e1 = e1.Scale(dgRsqrt (e1 % e1 + dgFloat32(1.0e-10f))); dgFloat64 mag2 = e1 % e0; if (mag2 > dgFloat32(0.9999f)) { count--; flag = 1; edge = ptr->m_next; ptr->m_prev->m_next = ptr->m_next; ptr->m_next->m_prev = ptr->m_prev; ptr->m_twin->m_next->m_prev = ptr->m_twin->m_prev; ptr->m_twin->m_prev->m_next = ptr->m_twin->m_next; break; } e0 = e1; p1 = p2; ptr = ptr->m_next; } while (ptr != edge); } } dgBigVector normal( polyhedra.FaceNormal(edge, &m_vertexPoints[0].m_x, sizeof(dgBigVector))); dgFloat64 mag2 = normal % normal; if (mag2 < dgFloat32(1.0e-8f)) { return 0; } normal = normal.Scale(dgRsqrt (mag2)); if (count >= 3) { dgEdge* ptr = edge; dgBigVector p0(&m_vertexPoints[ptr->m_prev->m_incidentVertex].m_x); dgBigVector p1(&m_vertexPoints[ptr->m_incidentVertex].m_x); dgBigVector e0(p1 - p0); e0 = e0.Scale(dgRsqrt (e0 % e0 + dgFloat32(1.0e-10f))); do { dgBigVector p2(&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x); dgBigVector e1(p2 - p1); e1 = e1.Scale(dgRsqrt (e1 % e1 + dgFloat32(1.0e-10f))); dgBigVector n(e0 * e1); dgFloat64 mag2 = n % normal; if (mag2 < dgFloat32(1.0e-5f)) { isconvex = 0; break; } e0 = e1; p1 = p2; ptr = ptr->m_next; } while (ptr != edge); } } if (isconvex) { dgEdge* const first = edge; if (count >= 3) { count = 0; dgEdge* ptr = first; do { pool[count] = ptr->m_incidentVertex; count++; ptr = ptr->m_next; } while (ptr != first); facesArray[facesCount] = count; facesCount = 1; } } else { dgPolyhedra leftOver(m_allocator); dgPolyhedra polyhedra2(m_allocator); dgEdge* ptr = edge; count = 0; do { pool[count] = ptr->m_incidentVertex; count++; ptr = ptr->m_next; } while (ptr != edge); polyhedra2.BeginFace(); polyhedra2.AddFace(count, pool); polyhedra2.EndFace(); leftOver.BeginFace(); polyhedra2.ConvexPartition(&m_vertexPoints[0].m_x, sizeof(dgTriplex), &leftOver); leftOver.EndFace(); _ASSERTE(leftOver.GetCount() == 0); dgInt32 mark = polyhedra2.IncLRU(); dgInt32 index = 0; dgPolyhedra::Iterator iter(polyhedra2); for (iter.Begin(); iter; iter++) { dgEdge* const edge = &(*iter); if (edge->m_incidentFace < 0) { continue; } if (edge->m_mark == mark) { continue; } ptr = edge; count = 0; do { ptr->m_mark = mark; pool[index] = ptr->m_incidentVertex; index++; count++; ptr = ptr->m_next; } while (ptr != edge); facesArray[facesCount] = count; facesCount++; } } return facesCount; }