void addVertex(initializer_list<double > pt) { addVertex(Vec3(pt)); }
/// @par /// /// @note If the mesh data is to be used to construct a Detour navigation mesh, then the upper /// limit must be retricted to <= #DT_VERTS_PER_POLYGON. /// /// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMesh& mesh) { rcAssert(ctx); ctx->startTimer(RC_TIMER_BUILD_POLYMESH); rcVcopy(mesh.bmin, cset.bmin); rcVcopy(mesh.bmax, cset.bmax); mesh.cs = cset.cs; mesh.ch = cset.ch; mesh.borderSize = cset.borderSize; int maxVertices = 0; int maxTris = 0; int maxVertsPerCont = 0; for (int i = 0; i < cset.nconts; ++i) { // Skip null contours. if (cset.conts[i].nverts < 3) continue; maxVertices += cset.conts[i].nverts; maxTris += cset.conts[i].nverts - 2; maxVertsPerCont = rcMax(maxVertsPerCont, cset.conts[i].nverts); } if (maxVertices >= 0xfffe) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many vertices %d.", maxVertices); return false; } rcScopedDelete<unsigned char> vflags = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxVertices, RC_ALLOC_TEMP); if (!vflags) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'vflags' (%d).", maxVertices); return false; } memset(vflags, 0, maxVertices); mesh.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertices*3, RC_ALLOC_PERM); if (!mesh.verts) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices); return false; } mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris*nvp*2, RC_ALLOC_PERM); if (!mesh.polys) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2); return false; } mesh.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris, RC_ALLOC_PERM); if (!mesh.regs) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.regs' (%d).", maxTris); return false; } mesh.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxTris, RC_ALLOC_PERM); if (!mesh.areas) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.areas' (%d).", maxTris); return false; } mesh.nverts = 0; mesh.npolys = 0; mesh.nvp = nvp; mesh.maxpolys = maxTris; memset(mesh.verts, 0, sizeof(unsigned short)*maxVertices*3); memset(mesh.polys, 0xff, sizeof(unsigned short)*maxTris*nvp*2); memset(mesh.regs, 0, sizeof(unsigned short)*maxTris); memset(mesh.areas, 0, sizeof(unsigned char)*maxTris); rcScopedDelete<int> nextVert = (int*)rcAlloc(sizeof(int)*maxVertices, RC_ALLOC_TEMP); if (!nextVert) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'nextVert' (%d).", maxVertices); return false; } memset(nextVert, 0, sizeof(int)*maxVertices); rcScopedDelete<int> firstVert = (int*)rcAlloc(sizeof(int)*VERTEX_BUCKET_COUNT, RC_ALLOC_TEMP); if (!firstVert) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT); return false; } for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i) firstVert[i] = -1; rcScopedDelete<int> indices = (int*)rcAlloc(sizeof(int)*maxVertsPerCont, RC_ALLOC_TEMP); if (!indices) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'indices' (%d).", maxVertsPerCont); return false; } rcScopedDelete<int> tris = (int*)rcAlloc(sizeof(int)*maxVertsPerCont*3, RC_ALLOC_TEMP); if (!tris) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'tris' (%d).", maxVertsPerCont*3); return false; } rcScopedDelete<unsigned short> polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*(maxVertsPerCont+1)*nvp, RC_ALLOC_TEMP); if (!polys) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'polys' (%d).", maxVertsPerCont*nvp); return false; } unsigned short* tmpPoly = &polys[maxVertsPerCont*nvp]; for (int i = 0; i < cset.nconts; ++i) { rcContour& cont = cset.conts[i]; // Skip null contours. if (cont.nverts < 3) continue; // Triangulate contour for (int j = 0; j < cont.nverts; ++j) indices[j] = j; int ntris = triangulate(cont.nverts, cont.verts, &indices[0], &tris[0]); if (ntris <= 0) { // Bad triangulation, should not happen. /* printf("\tconst float bmin[3] = {%ff,%ff,%ff};\n", cset.bmin[0], cset.bmin[1], cset.bmin[2]); printf("\tconst float cs = %ff;\n", cset.cs); printf("\tconst float ch = %ff;\n", cset.ch); printf("\tconst int verts[] = {\n"); for (int k = 0; k < cont.nverts; ++k) { const int* v = &cont.verts[k*4]; printf("\t\t%d,%d,%d,%d,\n", v[0], v[1], v[2], v[3]); } printf("\t};\n\tconst int nverts = sizeof(verts)/(sizeof(int)*4);\n");*/ ctx->log(RC_LOG_WARNING, "rcBuildPolyMesh: Bad triangulation Contour %d.", i); ntris = -ntris; } // Add and merge vertices. for (int j = 0; j < cont.nverts; ++j) { const int* v = &cont.verts[j*4]; indices[j] = addVertex((unsigned short)v[0], (unsigned short)v[1], (unsigned short)v[2], mesh.verts, firstVert, nextVert, mesh.nverts); if (v[3] & RC_BORDER_VERTEX) { // This vertex should be removed. vflags[indices[j]] = 1; } } // Build initial polygons. int npolys = 0; memset(polys, 0xff, maxVertsPerCont*nvp*sizeof(unsigned short)); for (int j = 0; j < ntris; ++j) { int* t = &tris[j*3]; if (t[0] != t[1] && t[0] != t[2] && t[1] != t[2]) { polys[npolys*nvp+0] = (unsigned short)indices[t[0]]; polys[npolys*nvp+1] = (unsigned short)indices[t[1]]; polys[npolys*nvp+2] = (unsigned short)indices[t[2]]; npolys++; } } if (!npolys) continue; // Merge polygons. if (nvp > 3) { for(;;) { // Find best polygons to merge. int bestMergeVal = 0; int bestPa = 0, bestPb = 0, bestEa = 0, bestEb = 0; for (int j = 0; j < npolys-1; ++j) { unsigned short* pj = &polys[j*nvp]; for (int k = j+1; k < npolys; ++k) { unsigned short* pk = &polys[k*nvp]; int ea, eb; int v = getPolyMergeValue(pj, pk, mesh.verts, ea, eb, nvp); if (v > bestMergeVal) { bestMergeVal = v; bestPa = j; bestPb = k; bestEa = ea; bestEb = eb; } } } if (bestMergeVal > 0) { // Found best, merge. unsigned short* pa = &polys[bestPa*nvp]; unsigned short* pb = &polys[bestPb*nvp]; mergePolys(pa, pb, bestEa, bestEb, tmpPoly, nvp); unsigned short* lastPoly = &polys[(npolys-1)*nvp]; if (pb != lastPoly) memcpy(pb, lastPoly, sizeof(unsigned short)*nvp); npolys--; } else { // Could not merge any polygons, stop. break; } } } // Store polygons. for (int j = 0; j < npolys; ++j) { unsigned short* p = &mesh.polys[mesh.npolys*nvp*2]; unsigned short* q = &polys[j*nvp]; for (int k = 0; k < nvp; ++k) p[k] = q[k]; mesh.regs[mesh.npolys] = cont.reg; mesh.areas[mesh.npolys] = cont.area; mesh.npolys++; if (mesh.npolys > maxTris) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many polygons %d (max:%d).", mesh.npolys, maxTris); return false; } } } // Remove edge vertices. for (int i = 0; i < mesh.nverts; ++i) { if (vflags[i]) { if (!canRemoveVertex(ctx, mesh, (unsigned short)i)) continue; if (!removeVertex(ctx, mesh, (unsigned short)i, maxTris)) { // Failed to remove vertex ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Failed to remove edge vertex %d.", i); return false; } // Remove vertex // Note: mesh.nverts is already decremented inside removeVertex()! // Fixup vertex flags for (int j = i; j < mesh.nverts; ++j) vflags[j] = vflags[j+1]; --i; } } // Calculate adjacency. if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, nvp)) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Adjacency failed."); return false; } // Find portal edges if (mesh.borderSize > 0) { const int w = cset.width; const int h = cset.height; for (int i = 0; i < mesh.npolys; ++i) { unsigned short* p = &mesh.polys[i*2*nvp]; for (int j = 0; j < nvp; ++j) { if (p[j] == RC_MESH_NULL_IDX) break; // Skip connected edges. if (p[nvp+j] != RC_MESH_NULL_IDX) continue; int nj = j+1; if (nj >= nvp || p[nj] == RC_MESH_NULL_IDX) nj = 0; const unsigned short* va = &mesh.verts[p[j]*3]; const unsigned short* vb = &mesh.verts[p[nj]*3]; if ((int)va[0] == 0 && (int)vb[0] == 0) p[nvp+j] = 0x8000 | 0; else if ((int)va[2] == h && (int)vb[2] == h) p[nvp+j] = 0x8000 | 1; else if ((int)va[0] == w && (int)vb[0] == w) p[nvp+j] = 0x8000 | 2; else if ((int)va[2] == 0 && (int)vb[2] == 0) p[nvp+j] = 0x8000 | 3; } } } // Just allocate the mesh flags array. The user is resposible to fill it. mesh.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*mesh.npolys, RC_ALLOC_PERM); if (!mesh.flags) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.flags' (%d).", mesh.npolys); return false; } memset(mesh.flags, 0, sizeof(unsigned short) * mesh.npolys); if (mesh.nverts > 0xffff) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff); } if (mesh.npolys > 0xffff) { ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff); } ctx->stopTimer(RC_TIMER_BUILD_POLYMESH); return true; }
void Spline::addVertices(const unsigned int index, const std::vector<sf::Vector2f>& positions) { for (auto& position : positions) addVertex(index, position); }
void IcoSphere::create(int recursionLevel) { vertices.clear(); lineIndices.clear(); triangleIndices.clear(); faces.clear(); middlePointIndexCache.clear(); index = 0; float t = (1.0f + Ogre::Math::Sqrt(5.0f)) / 2.0f; addVertex(Ogre::Vector3(-1.0f, t, 0.0f)); addVertex(Ogre::Vector3( 1.0f, t, 0.0f)); addVertex(Ogre::Vector3(-1.0f, -t, 0.0f)); addVertex(Ogre::Vector3( 1.0f, -t, 0.0f)); addVertex(Ogre::Vector3( 0.0f, -1.0f, t)); addVertex(Ogre::Vector3( 0.0f, 1.0f, t)); addVertex(Ogre::Vector3( 0.0f, -1.0f, -t)); addVertex(Ogre::Vector3( 0.0f, 1.0f, -t)); addVertex(Ogre::Vector3( t, 0.0f, -1.0f)); addVertex(Ogre::Vector3( t, 0.0f, 1.0f)); addVertex(Ogre::Vector3(-t, 0.0f, -1.0f)); addVertex(Ogre::Vector3(-t, 0.0f, 1.0f)); addFace(0, 11, 5); addFace(0, 5, 1); addFace(0, 1, 7); addFace(0, 7, 10); addFace(0, 10, 11); addFace(1, 5, 9); addFace(5, 11, 4); addFace(11, 10, 2); addFace(10, 7, 6); addFace(7, 1, 8); addFace(3, 9, 4); addFace(3, 4, 2); addFace(3, 2, 6); addFace(3, 6, 8); addFace(3, 8, 9); addFace(4, 9, 5); addFace(2, 4, 11); addFace(6, 2, 10); addFace(8, 6, 7); addFace(9, 8, 1); addLineIndices(1, 0); addLineIndices(1, 5); addLineIndices(1, 7); addLineIndices(1, 8); addLineIndices(1, 9); addLineIndices(2, 3); addLineIndices(2, 4); addLineIndices(2, 6); addLineIndices(2, 10); addLineIndices(2, 11); addLineIndices(0, 5); addLineIndices(5, 9); addLineIndices(9, 8); addLineIndices(8, 7); addLineIndices(7, 0); addLineIndices(10, 11); addLineIndices(11, 4); addLineIndices(4, 3); addLineIndices(3, 6); addLineIndices(6, 10); addLineIndices(0, 11); addLineIndices(11, 5); addLineIndices(5, 4); addLineIndices(4, 9); addLineIndices(9, 3); addLineIndices(3, 8); addLineIndices(8, 6); addLineIndices(6, 7); addLineIndices(7, 10); addLineIndices(10, 0); for (int i = 0; i < recursionLevel; i++) { std::list<TriangleIndices> faces2; for (std::list<TriangleIndices>::iterator j = faces.begin(); j != faces.end(); j++) { TriangleIndices f = *j; int a = getMiddlePoint(f.v1, f.v2); int b = getMiddlePoint(f.v2, f.v3); int c = getMiddlePoint(f.v3, f.v1); removeLineIndices(f.v1, f.v2); removeLineIndices(f.v2, f.v3); removeLineIndices(f.v3, f.v1); faces2.push_back(TriangleIndices(f.v1, a, c)); faces2.push_back(TriangleIndices(f.v2, b, a)); faces2.push_back(TriangleIndices(f.v3, c, b)); faces2.push_back(TriangleIndices(a, b, c)); addTriangleLines(f.v1, a, c); addTriangleLines(f.v2, b, a); addTriangleLines(f.v3, c, b); } faces = faces2; } }
void FileGraphics::initializeGL() { if (fcontroller->isOpenedFile()) { int rows, cols; DemInterface* demObject = fcontroller->getDemObject(); cols = demObject->getCols(); rows = demObject->getRows(); int centerX = cols/2; float posX, posY = 0; scale = (float)getSize().width() / (float)cols; int centerY = rows/2; ColorRGBA color; std::vector<float> band_data = demObject->readDem(); maxZ = demObject->maxHeight(); int step = demObject->getZoom(); for (int k = 0; k < rows; k=k+step) { posY = (float)(centerY - k)/centerY; for (int j =0; j < cols; j=j+step) { posX = (float)(j - centerX)/centerX; if (k < rows -step && j-step >= 0) { color = colorController->getColor(band_data[k*rows + j]); addVertex( Vertex( QVector3D(posX, posY, getZCoordinate(band_data[k*rows + j])), QVector3D(color.r, color.g, color.b) ) ); float nposY = (float)(centerY - (k +step))/centerY; color = colorController->getColor(band_data[(k+step)*rows + j]); addVertex( Vertex( QVector3D(posX, nposY, getZCoordinate(band_data[(k+step)*rows + j])), QVector3D(color.r, color.g, color.b) ) ); float nposX = (float)(j - step - centerX)/centerX; color = colorController->getColor(band_data[k*rows + j - step]); addVertex( Vertex( QVector3D(nposX, posY, getZCoordinate(band_data[k*rows + j - step])), QVector3D(color.r, color.g, color.b) ) ); } if (k - step >= 0 && j < cols -step) { color = colorController->getColor(band_data[k*rows + j]); addVertex( Vertex( QVector3D(posX, posY, getZCoordinate(band_data[k*rows + j])), QVector3D(color.r, color.g, color.b) ) ); float nposY = (float)(centerY - (k -step))/centerY; color = colorController->getColor(band_data[(k-step)*rows + j]); addVertex( Vertex( QVector3D(posX, nposY, getZCoordinate(band_data[(k-step)*rows + j])), QVector3D(color.r, color.g, color.b) ) ); float nposX = (float)(j +step - centerX)/centerX; color = colorController->getColor(band_data[k*rows + j+step]); addVertex( Vertex( QVector3D(nposX, posY, getZCoordinate(band_data[k*rows + j+step])), QVector3D(color.r, color.g, color.b) ) ); } } } bsController->generateBaseSupport(); } }
//---------------------------------------- void ofxBox2dPolygon::addVertexes(vector <ofVec2f> &pts) { for (int i=0; i<pts.size(); i++) { addVertex(pts[i].x, pts[i].y); } }
void Mesh::addCappedCylinder(const Vector3 &p1, const Vector3 &p2, float radius1, float radius2, unsigned detail1, unsigned detail2, const Color &color, const Vector3 &up, uint8_t existence) { float fdetail1 = static_cast<float>(detail1); float fdetail2 = static_cast<float>(detail2); Vector3 unit_forward = normalize(p2 - p1); Vector3 unit_up = normalize(up); // Might easily degenerate, prevent it. if(dnload_fabsf(dot_product(unit_up, unit_forward)) > 0.999f) { unit_up = Vector3(0.0f, 0.0f, 1.0f); } Vector3 unit_right = normalize(cross_product(unit_forward, unit_up)); unit_up = normalize(cross_product(unit_right, unit_forward)); //std::cout << unit_right << " ; " << unit_up << std::endl; unsigned index_base = static_cast<unsigned>(m_vertices.getSize()); Vector3 tip1 = p1 - (radius1 * unit_forward); Vector3 tip2 = p2 + (radius2 * unit_forward); if(existence & SIDE_FRONT) { addVertex(tip1, color); // Create vertices for first cap for(unsigned jj = 0; jj < detail2; ++jj) { float t = static_cast<float>(jj+1)/fdetail2; float r = dnload_sinf(t * static_cast<float>(M_PI / 2.0)) * radius1; Vector3 c = tip1 + (t * t * unit_forward); for(unsigned ii = 0; ii < detail1; ++ii) { float angle = static_cast<float>(ii) / fdetail1 * static_cast<float>(M_PI * 2.0) + static_cast<float>(M_PI) / fdetail1; float ca = dnload_cosf(angle); float sa = dnload_sinf(angle); addVertex(c + ca * unit_right * r + sa * unit_up * r, color); } } // Create tip of the cap. for(unsigned ii = 0; ii < detail1; ++ii) { unsigned ii_next = (ii+1) % detail1; addFace(index_base, ii+index_base+1, ii_next+index_base+1); } // The rest of the cap... for(unsigned jj = 0; jj < detail2-1; ++jj) { unsigned local_base = (jj*detail1) + 1 + index_base; for(unsigned ii = 0; ii < detail1; ++ii) { unsigned next1 = (ii+1) % detail1; unsigned next2 = next1 + detail1; addFace(next2+local_base, next1+local_base, ii+local_base, ii+detail1+local_base); } } } else { for(unsigned ii = 0; ii < detail1; ++ii) { float angle = static_cast<float>(ii) / fdetail1 * static_cast<float>(M_PI * 2.0) + static_cast<float>(M_PI) / fdetail1; float ca = dnload_cosf(angle); float sa = dnload_sinf(angle); addVertex(p1 + ca * unit_right * radius1 + sa * unit_up * radius1, color); } } index_base = static_cast<unsigned>(m_vertices.getSize()); if(existence & SIDE_BACK) { // Create vertices for second cap for(unsigned jj = 0; jj < detail2; ++jj) { float t = static_cast<float>(jj)/fdetail2; float r = dnload_sinf((1.0f-t) * static_cast<float>(M_PI / 2.0)) * radius2; Vector3 c = p2 + (t * unit_forward); for(unsigned ii = 0; ii < detail1; ++ii) { float angle = static_cast<float>(ii) / fdetail1 * static_cast<float>(M_PI * 2.0) + static_cast<float>(M_PI) / fdetail1; float ca = dnload_cosf(angle); float sa = dnload_sinf(angle); addVertex(c + ca * unit_right * r + sa * unit_up * r, color); } } addVertex(tip2, color); } else { for(unsigned ii = 0; (ii < detail1); ++ii) { float angle = static_cast<float>(ii) / fdetail1 * static_cast<float>(M_PI * 2.0) + static_cast<float>(M_PI) / fdetail1; float ca = dnload_cosf(angle); float sa = dnload_sinf(angle); addVertex(p2 + ca * unit_right * radius2 + sa * unit_up * radius1, color); } } // Mid-part for(unsigned ii = 0; ii < detail1; ++ii) { unsigned index_base2 = index_base - detail1; unsigned next = (ii+1) % detail1; addFace(index_base2+ii, index_base+ii, index_base+next, index_base2+next); } if(existence & SIDE_BACK) { // Faces for the second cap for(unsigned jj = 0; jj < detail2-1; ++jj) { unsigned local_base = (jj*detail1) + index_base; for(unsigned ii = 0; ii < detail1; ++ii) { unsigned next1 = (ii+1) % detail1; unsigned next2 = next1 + detail1; addFace(next2+local_base, next1+local_base, ii+local_base, ii+detail1+local_base); } } index_base = static_cast<unsigned>(m_vertices.getSize()) - 1; unsigned index_base2 = index_base - detail1 - 1; // Create tip of the cap. for(unsigned ii = 0; ii < detail1; ++ii) { unsigned next = (ii+1) % detail1; addFace(index_base, index_base2+next, index_base2+ii); } } }
// auxiliars void CRender::auxAxis() { setLineWidth(3.0f); setColor(1.0f,0.0,0.0); beginShapeLines(); addVertex(0.0f,0.0f,0.0f); addVertex(1000.0f,0.0f,0.0f); // X endShape(); enableLineStipple(); setLineStipple(1,0xaaaa); beginShapeLines(); addVertex(0.0f,0.0f,0.0f); addVertex(-1000.0f,0.0f,0.0f); // X neg endShape(); disableLineStipple(); setColor(0.0f,1.0,0.0); beginShapeLines(); addVertex(0.0f,0.0f,0.0f); addVertex(0.0f,1000.0f,0.0f); // y endShape(); enableLineStipple(); beginShapeLines(); addVertex(0.0f,0.0f,0.0f); addVertex(0.0f,-1000.0f,0.0f); // y neg endShape(); disableLineStipple(); setColor(0.0f,0.0,1.0); beginShapeLines(); addVertex(0.0f,0.0f,0.0f); addVertex(0.0f,0.0f,1000.0f); // z endShape(); enableLineStipple(); beginShapeLines(); addVertex(0.0f,0.0f,0.0f); addVertex(0.0f,0.0f,-1000.0f); // z neg endShape(); disableLineStipple(); setLineWidth(1.0f); }
bool rcMeshLoaderObj::load(const char* filename) { char* buf = 0; FILE* fp = fopen(filename, "rb"); if (!fp) return false; fseek(fp, 0, SEEK_END); long bufSize = ftell(fp); if (bufSize < 0) { fclose(fp); return false; } fseek(fp, 0, SEEK_SET); buf = new char[bufSize]; if (!buf) { fclose(fp); return false; } size_t readSize = fread(buf, bufSize, 1, fp); fclose(fp); if (readSize != (size_t) bufSize) { delete [] buf; return false; } char* src = buf; char* srcEnd = buf + bufSize; char row[512]; int face[32]; float x,y,z; int nv; int vcap = 0; int tcap = 0; while (src < srcEnd) { // Parse one row row[0] = '\0'; src = parseRow(src, srcEnd, row, sizeof(row)/sizeof(char)); // Skip comments if (row[0] == '#') continue; if (row[0] == 'v' && row[1] != 'n' && row[1] != 't') { // Vertex pos sscanf(row+1, "%f %f %f", &x, &y, &z); addVertex(x, y, z, vcap); } if (row[0] == 'f') { // Faces nv = parseFace(row+1, face, 32, m_vertCount); for (int i = 2; i < nv; ++i) { const int a = face[0]; const int b = face[i-1]; const int c = face[i]; if (a < 0 || a >= m_vertCount || b < 0 || b >= m_vertCount || c < 0 || c >= m_vertCount) continue; addTriangle(a, b, c, tcap); } } } delete [] buf; // Calculate normals. m_normals = new float[m_triCount*3]; for (int i = 0; i < m_triCount*3; i += 3) { const float* v0 = &m_verts[m_tris[i]*3]; const float* v1 = &m_verts[m_tris[i+1]*3]; const float* v2 = &m_verts[m_tris[i+2]*3]; float e0[3], e1[3]; for (int j = 0; j < 3; ++j) { e0[j] = v1[j] - v0[j]; e1[j] = v2[j] - v0[j]; } float* n = &m_normals[i]; n[0] = e0[1]*e1[2] - e0[2]*e1[1]; n[1] = e0[2]*e1[0] - e0[0]*e1[2]; n[2] = e0[0]*e1[1] - e0[1]*e1[0]; float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); if (d > 0) { d = 1.0f/d; n[0] *= d; n[1] *= d; n[2] *= d; } } strncpy(m_filename, filename, sizeof(m_filename)); m_filename[sizeof(m_filename)-1] = '\0'; return true; }
Grid(Vec3 pts): Grid() { addVertex(pts); }
Mesh::Mesh(istream &is, bool calculateEdges) : calculateEdges(calculateEdges) { FileId id; // Read File header get(is, id); if (!is) { console::print(1.0f, 0.0f, 0.0f, "Failed to load mesh!"); return; } if (id != string2id("mESH")) { console::print(1.0f, 0.0f, 0.0f, "Not a mesh file!"); return; } FileVersion ver; get(is, ver); if (ver.major != 1 || ver.minor != 0) { console::print(1.0f, 0.0f, 0.0f, "Unknown mesh version!"); return; } MeshHeader header; // Read mesh file header get(is, header); for (dword i = 0; i < header.textures; ++i) { // Read textures char name[256]; byte length; get(is, length); is.read(name, (int)length + 1); addTexture(name); } for (dword i = 0; i < header.materials; i++) { // Read materials addMaterial(Material(is)); } for (dword i = 0; i < header.vertices; i++) { // Read vertices Vector3 v; get(is, v[0]); get(is, v[1]); get(is, v[2]); addVertex(v); } for (dword i = 0; i < header.vertices; i++) { // Read normals Vector3 n; get(is, n[0]); get(is, n[1]); get(is, n[2]); setNormal(i, n); } for (dword i = 0; i < header.vertices; i++) { // Read texture coordinates Vector2 uv; get(is, uv[0]); get(is, uv[1]); addTexCoord(uv); } for (dword i = 0; i < header.triangles; i++) { // Read triangles Triangle tri; get(is, tri.v[0]); get(is, tri.v[1]); get(is, tri.v[2]); get(is, tri.texture); get(is, tri.material); tri.uv[0] = tri.v[0]; tri.uv[1] = tri.v[1]; tri.uv[2] = tri.v[2]; addTriangle(tri); } for (dword i = 0; i < header.edges; i++) { // Read edges Edge e; get(is, e.v[0]); get(is, e.v[1]); get(is, e.plane[0]); get(is, e.plane[1]); if (!calculateEdges) addEdge(e); } }
Grid(initializer_list<initializer_list<double > > pts):Grid() { addVertex(pts); }
void addVertex(initializer_list<initializer_list<double > > pts) { for (auto i = pts.begin(); i != pts.end(); ++i) { addVertex(*i); } }
void addVertex(vector<Vec3 > pts) { for (auto pt : pts) { addVertex(pt); } }
void QgsMapToolReshape::cadCanvasReleaseEvent( QgsMapMouseEvent * e ) { //check if we operate on a vector layer //todo: move this to a function in parent class to avoid duplication QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ); if ( !vlayer ) { notifyNotVectorLayer(); return; } if ( !vlayer->isEditable() ) { notifyNotEditableLayer(); return; } //add point to list and to rubber band if ( e->button() == Qt::LeftButton ) { int error = addVertex( e->mapPoint(), e->mapPointMatch() ); if ( error == 1 ) { //current layer is not a vector layer return; } else if ( error == 2 ) { //problem with coordinate transformation emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING ); return; } startCapturing(); } else if ( e->button() == Qt::RightButton ) { deleteTempRubberBand(); //find out bounding box of mCaptureList if ( size() < 1 ) { stopCapturing(); return; } QgsPoint firstPoint = points().at( 0 ); QgsRectangle bbox( firstPoint.x(), firstPoint.y(), firstPoint.x(), firstPoint.y() ); for ( int i = 1; i < size(); ++i ) { bbox.combineExtentWith( points().at( i ).x(), points().at( i ).y() ); } //query all the features that intersect bounding box of capture line QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) ); QgsFeature f; int reshapeReturn; bool reshapeDone = false; vlayer->beginEditCommand( tr( "Reshape" ) ); while ( fit.nextFeature( f ) ) { //query geometry //call geometry->reshape(mCaptureList) //register changed geometry in vector layer QgsGeometry geom = f.geometry(); if ( !geom.isEmpty() ) { reshapeReturn = geom.reshapeGeometry( points() ); if ( reshapeReturn == 0 ) { //avoid intersections on polygon layers if ( vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) { //ignore all current layer features as they should be reshaped too QHash<QgsVectorLayer*, QSet<QgsFeatureId> > ignoreFeatures; ignoreFeatures.insert( vlayer, vlayer->allFeatureIds() ); if ( geom.avoidIntersections( ignoreFeatures ) != 0 ) { emit messageEmitted( tr( "An error was reported during intersection removal" ), QgsMessageBar::CRITICAL ); vlayer->destroyEditCommand(); stopCapturing(); return; } if ( geom.isGeosEmpty() ) //intersection removal might have removed the whole geometry { emit messageEmitted( tr( "The feature cannot be reshaped because the resulting geometry is empty" ), QgsMessageBar::CRITICAL ); vlayer->destroyEditCommand(); stopCapturing(); return; } } vlayer->changeGeometry( f.id(), geom ); reshapeDone = true; } } } if ( reshapeDone ) { vlayer->endEditCommand(); } else { vlayer->destroyEditCommand(); } stopCapturing(); } }
void lineTo(const osg::Vec2& pos) { addVertex( osg::Vec3(pos.x(),pos.y(),0) ); }
//---------------------------------------- void ofxBox2dPolygon::addVertexes(ofPolyline &polyline) { for (int i=0; i<polyline.size(); i++) { addVertex(polyline[i].x, polyline[i].y); } }
Shader::Shader(const char* vert_src, const char* frag_src) { g_shProg = glCreateProgram(); addVertex(vert_src); addFragment(frag_src); }
bool OptimizableGraph::load(istream& is, bool createEdges) { // scna for the paramers in the whole file if (!_parameters.read(is)) return false; cerr << "Loaded " << _parameters.size() << " parameters" << endl; is.clear(); is.seekg(ios_base::beg); set<string> warnedUnknownTypes; stringstream currentLine; string token; Factory* factory = Factory::instance(); HyperGraph::GraphElemBitset elemBitset; elemBitset[HyperGraph::HGET_PARAMETER] = 1; elemBitset.flip(); Vertex* previousVertex = 0; while (1) { int bytesRead = readLine(is, currentLine); if (bytesRead == -1) break; currentLine >> token; if (bytesRead == 0 || token.size() == 0 || token[0] == '#') continue; // handle commands encoded in the file bool handledCommand = false; if (token == "FIX") { handledCommand = true; int id; while (currentLine >> id) { OptimizableGraph::Vertex* v = static_cast<OptimizableGraph::Vertex*>(vertex(id)); if (v) { # ifndef NDEBUG cerr << "Fixing vertex " << v->id() << endl; # endif v->setFixed(true); } else { cerr << "Warning: Unable to fix vertex with id " << id << ". Not found in the graph." << endl; } } } if (handledCommand) continue; // do the mapping to an internal type if it matches if (_renamedTypesLookup.size() > 0) { map<string, string>::const_iterator foundIt = _renamedTypesLookup.find(token); if (foundIt != _renamedTypesLookup.end()) { token = foundIt->second; } } if (! factory->knowsTag(token)) { if (warnedUnknownTypes.count(token) != 1) { warnedUnknownTypes.insert(token); cerr << CL_RED(__PRETTY_FUNCTION__ << " unknown type: " << token) << endl; } continue; } HyperGraph::HyperGraphElement* element = factory->construct(token, elemBitset); if (dynamic_cast<Vertex*>(element)) { // it's a vertex type Vertex* v = static_cast<Vertex*>(element); int id; currentLine >> id; bool r = v->read(currentLine); if (! r) cerr << __PRETTY_FUNCTION__ << ": Error reading vertex " << token << " " << id << endl; v->setId(id); if (!addVertex(v)) { cerr << __PRETTY_FUNCTION__ << ": Failure adding Vertex, " << token << " " << id << endl; delete v; } else { previousVertex = v; } }
bool CalHardwareModel::load(int baseVertexIndex, int startIndex,int maxBonesPerMesh) { if(m_pVertexBuffer==NULL || m_pNormalBuffer ==NULL|| m_pWeightBuffer ==NULL || m_pMatrixIndexBuffer ==NULL) { CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__); return false; } int mapId; for(mapId = 0; mapId < m_textureCoordNum; mapId++) { if(m_pTextureCoordBuffer[mapId]==NULL) { CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__); return false; } } m_vectorVertexIndiceUsed.resize(50000); int vertexCount=baseVertexIndex; int faceIndexCount = startIndex; // unused. //CalCoreSkeleton * pCoreSkeleton = m_pCoreModel->getCoreSkeleton(); //std::vector< CalCoreBone *>& vectorBone = pCoreSkeleton->getVectorCoreBone(); // if unspecified, fill with all core mesh ids if(m_coreMeshIds.empty()) { for(int coreMeshId = 0; coreMeshId < m_pCoreModel->getCoreMeshCount(); coreMeshId++) m_coreMeshIds.push_back(coreMeshId); } for(std::vector<int>::iterator meshIdIt = m_coreMeshIds.begin();meshIdIt != m_coreMeshIds.end(); meshIdIt++) { int meshId = *meshIdIt; CalCoreMesh *pCoreMesh = m_pCoreModel->getCoreMesh(meshId); int submeshCount= pCoreMesh->getCoreSubmeshCount(); int submeshId; for(submeshId = 0 ;submeshId < submeshCount ; submeshId++) { CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId); std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pCoreSubmesh->getVectorVertex(); std::vector<CalCoreSubmesh::Face>& vectorFace = pCoreSubmesh->getVectorFace(); // unused. //std::vector< std::vector<CalCoreSubmesh::TextureCoordinate> >& vectorTex = pCoreSubmesh->getVectorVectorTextureCoordinate(); CalHardwareMesh hardwareMesh; hardwareMesh.meshId = meshId; hardwareMesh.submeshId = submeshId; hardwareMesh.baseVertexIndex=vertexCount; hardwareMesh.startIndex=faceIndexCount; hardwareMesh.m_vectorBonesIndices.clear(); hardwareMesh.vertexCount=0; hardwareMesh.faceCount=0; int startIndex=hardwareMesh.startIndex; int faceId; for( faceId =0 ;faceId<pCoreSubmesh->getFaceCount();faceId++) { if(canAddFace(hardwareMesh,vectorFace[faceId],vectorVertex,maxBonesPerMesh)) { m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[0],pCoreSubmesh,maxBonesPerMesh); m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+1]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[1],pCoreSubmesh,maxBonesPerMesh); m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+2]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[2],pCoreSubmesh,maxBonesPerMesh); hardwareMesh.faceCount++; } else { vertexCount+=hardwareMesh.vertexCount; faceIndexCount+=hardwareMesh.faceCount*3; hardwareMesh.pCoreMaterial= m_pCoreModel->getCoreMaterial(pCoreSubmesh->getCoreMaterialThreadId()); m_vectorHardwareMesh.push_back(hardwareMesh); hardwareMesh.baseVertexIndex=vertexCount; hardwareMesh.startIndex=faceIndexCount; hardwareMesh.m_vectorBonesIndices.clear(); hardwareMesh.vertexCount=0; hardwareMesh.faceCount=0; startIndex=hardwareMesh.startIndex; m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[0],pCoreSubmesh,maxBonesPerMesh); m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+1]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[1],pCoreSubmesh,maxBonesPerMesh); m_pIndexBuffer[startIndex+hardwareMesh.faceCount*3+2]= addVertex(hardwareMesh,vectorFace[faceId].vertexId[2],pCoreSubmesh,maxBonesPerMesh); hardwareMesh.faceCount++; } } vertexCount+=hardwareMesh.vertexCount; faceIndexCount+=hardwareMesh.faceCount*3; hardwareMesh.pCoreMaterial= m_pCoreModel->getCoreMaterial(pCoreSubmesh->getCoreMaterialThreadId()); m_vectorHardwareMesh.push_back(hardwareMesh); } } m_vectorVertexIndiceUsed.clear(); m_totalFaceCount=0; m_totalVertexCount=0; for(size_t hardwareMeshId = 0; hardwareMeshId < m_vectorHardwareMesh.size(); hardwareMeshId++) { m_totalFaceCount+=m_vectorHardwareMesh[hardwareMeshId].faceCount; m_totalVertexCount+=m_vectorHardwareMesh[hardwareMeshId].vertexCount; } return true; }
void GOCube::refreshBuffers() { GameObject::refreshBuffers(); // for centering float offsetX = size.x / 2; float offsetY = size.y / 2; float offsetZ = size.z / 2; if (verticesBuff == NULL) { //verticesBuff = new vec3f[36]; // allocate a new buffer glGenBuffers(1, &VBOBuffer); // bind the buffer object to use glBindBuffer(GL_ARRAY_BUFFER, VBOBuffer); // allocate enough space for the VBO glBufferData(GL_ARRAY_BUFFER, sizeof(vec3f) * 36 * 2, 0, GL_STATIC_DRAW); } else { glBindBuffer(GL_ARRAY_BUFFER, VBOBuffer); } verticesBuff = (vec3f*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); addVertex(0, 0.0 - offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f); addVertex(1, 0.0 - offsetX, 0.0 - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f); addVertex(2, size.x - offsetX, 0.0 - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f); addVertex(3, size.x - offsetX, 0.0 - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f); addVertex(4, size.x - offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f); addVertex(5, 0.0 - offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 0.0f, 1.0f); addVertex(6, -offsetX, size.y - offsetY, -offsetZ, 0.0f, 0.0f, -1.0f); addVertex(7, size.x - offsetX, size.y - offsetY, -offsetZ, 0.0f, 0.0f, -1.0f); addVertex(8, size.x - offsetX, -offsetY, -offsetZ, 0.0f, 0.0f, -1.0f); addVertex(9, size.x - offsetX, -offsetY, -offsetZ, 0.0f, 0.0f, -1.0f); addVertex(10, -offsetX, -offsetY, -offsetZ, 0.0f, 0.0f, -1.0f); addVertex(11, -offsetX, size.y - offsetY, -offsetZ, 0.0f, 0.0f, -1.0f); addVertex(12, size.x - offsetX, -offsetY, size.z - offsetZ, 1.0f, 0.0f, 0.0f); addVertex(13, size.x - offsetX, -offsetY, -offsetZ, 1.0f, 0.0f, 0.0f); addVertex(14, size.x - offsetX, size.y - offsetY, size.z - offsetZ, 1.0f, 0.0f, 0.0f); addVertex(15, size.x - offsetX, -offsetY, -offsetZ, 1.0f, 0.0f, 0.0f); addVertex(16, size.x - offsetX, size.y - offsetY, -offsetZ, 1.0f, 0.0f, 0.0f); addVertex(17, size.x - offsetX, size.y - offsetY, size.z - offsetZ, 1.0f, 0.0f, 0.0f); addVertex(18, -offsetX, size.y - offsetY, size.z - offsetZ, -1.0f, 0.0f, 0.0f); addVertex(19, -offsetX, size.y - offsetY, -offsetZ, -1.0f, 0.0f, 0.0f); addVertex(20, -offsetX, -offsetY, -offsetZ, -1.0f, 0.0f, 0.0f); addVertex(21, -offsetX, size.y - offsetY, size.z - offsetZ, -1.0f, 0.0f, 0.0f); addVertex(22, -offsetX, -offsetY, -offsetZ, -1.0f, 0.0f, 0.0f); addVertex(23, -offsetX, -offsetY, size.z - offsetZ, -1.0f, 0.0f, 0.0f); addVertex(24, size.x - offsetX, size.y - offsetY, -offsetZ, 0.0f, 1.0f, 0.0f); addVertex(25, -offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 1.0f, 0.0f); addVertex(26, size.x - offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 1.0f, 0.0f); addVertex(27, -offsetX, size.y - offsetY, size.z - offsetZ, 0.0f, 1.0f, 0.0f); addVertex(28, size.x - offsetX, size.y - offsetY, -offsetZ, 0.0f, 1.0f, 0.0f); addVertex(29, -offsetX, size.y - offsetY, -offsetZ, 0.0f, 1.0f, 0.0f); addVertex(30, -offsetX, -offsetY, -offsetZ, 0.0f, -1.0f, 0.0f); addVertex(31, size.x - offsetX, -offsetY, -offsetZ, 0.0f, -1.0f, 0.0f); addVertex(32, -offsetX, -offsetY, size.z - offsetZ, 0.0f, -1.0f, 0.0f); addVertex(33, size.x - offsetX, -offsetY, size.z - offsetZ, 0.0f, -1.0f, 0.0f); addVertex(34, -offsetX, -offsetY, size.z - offsetZ, 0.0f, -1.0f, 0.0f); addVertex(35, size.x - offsetX, -offsetY, -offsetZ, 0.0f, -1.0f, 0.0f); //glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vec3f) * 36, verticesBuff); glUnmapBuffer(GL_ARRAY_BUFFER); }
/* ------------------------------------------------------------------------- */ void Mesh_Icosa::fillMesh() { TRACE(">> Mesh_Icosa::fillMesh()"); // Key values for the icosaedre. Real C = sqrt(5.0)/5; Real Bp = (5+sqrt(5.0))/10; Real Bm = (5-sqrt(5.0))/10; Real Ap = sqrt(Bp); Real Am = sqrt(Bm); Real r = mRadius; // Generate the 12 vertices of the icosaedre // pentagon1 = P1-P5-P4-P3-P2 (CW) // pentagon2 = P10-P6-P7-P8-P9 (CW) // Do not change this order => it is the index. addVertexUV(r, 0, 1, 0, 0.0); // P0 - upper (with U for 1-2-base triangle) addVertex (r, Am, C, -Bp); // P1 - penta1 - (Edge : U=0.9) addVertex (r,-Am, C, -Bp); // P2 - penta1 addVertex (r,-Ap, C, Bm); // P3 - penta1 addVertex (r, 0, C, 2*C); // P4 - penta1 addVertex (r, Ap, C, Bm); // P5 - penta1 addVertex (r, Am,-C, Bp); // P6 - penta2 addVertex (r,-Am,-C, Bp); // P7 - penta2 addVertex (r,-Ap,-C, -Bm); // P8 - penta2 addVertex (r, 0, -C,-2*C); // P9 - penta2 - (Edge : U=1) addVertex (r, Ap,-C, -Bm); // P10 - penta2 addVertex (r, 0, -1, 0 ); // P11 - lower (7-6-base-triangle) // The edge of the texture: we duplicate the vertices addVertexUV (r, 0, -C,-2*C, 0.0); // P12 - border (= P9) addVertexUV (r, Am, C,-Bp ,-0.1); // P13 - border (= P1) // The upper vertex has 5 UV coordinates (one is already done = P0) addVertexUV (r, 0, 1, 0, 0.2); // P14 = P0 with U for 2-3-base triangle addVertexUV (r, 0, 1, 0, 0.4); // P15 = P0 with U for 3-4-base triangle addVertexUV (r, 0, 1, 0, 0.6); // P16 = P0 with U for 4-5-base triangle addVertexUV (r, 0, 1, 0, 0.8); // P17 = P0 with U for 5-1-base triangle // The lower vertex has 5 UV coordinates (one is already done = P11) addVertexUV (r, 0,-1, 0, 0.1); // P18 = P11 with U for 12-8-base triangle addVertexUV (r, 0,-1, 0, 0.3); // P19 = P11 with U for 8-7-base triangle addVertexUV (r, 0,-1, 0, 0.7); // P20 = P11 with U for 6-10-base triangle addVertexUV (r, 0,-1, 0, 0.9); // P21 = P11 with U for 10-9-base triangle // Central zone (10 triangles) addTriangle(10,9,1); addTriangle(12,2,13); // = P1-P2-P9 addTriangle(12,8,2); // = P2-P8-P9 addTriangle(8,3,2); addTriangle(8,7,3); addTriangle(7,4,3); addTriangle(7,6,4); addTriangle(6,5,4); addTriangle(6,10,5); addTriangle(10,1,5); // upper zone (5 triangles) // upper is P0-14-15-16-17 // pentagon1 = P2-P3-P4-P5-P1 (CCW) addTriangle(2,0,13); addTriangle(3,14,2); addTriangle(4,15,3); addTriangle(5,16,4); addTriangle(1,17,5); // lower zone (5 triangles) addTriangle(11,6,7); addTriangle(18,8,12); addTriangle(19,7,8); addTriangle(21,9,10); addTriangle(20,10,6); /* // Central zone (10 triangles) mVerticeIndex = 0; addTriangle(1,9,10); addTriangle(13,2,12); // = P1-P2-P9 addTriangle(2,8,12); // = P2-P8-P9 addTriangle(2,3,8); addTriangle(3,7,8); addTriangle(3,4,7); addTriangle(4,6,7); addTriangle(4,5,6); addTriangle(5,10,6); addTriangle(5,1,10); // upper zone (5 triangles) addTriangle(13,0,2); addTriangle(2,14,3); addTriangle(3,15,4); addTriangle(4,16,5); addTriangle(5,17,1); // lower zone (5 triangles) addTriangle(6,10,20); addTriangle(7,6,11); addTriangle(8,7,19); addTriangle(12,8,18); addTriangle(10,9,21); */ }
void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mLayer ); if ( !vlayer ) //if no given layer take the current from canvas vlayer = currentVectorLayer(); if ( !vlayer ) { notifyNotVectorLayer(); return; } QgsWkbTypes::Type layerWKBType = vlayer->wkbType(); QgsVectorDataProvider *provider = vlayer->dataProvider(); if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) ) { emit messageEmitted( tr( "The data provider for this layer does not support the addition of features." ), Qgis::Warning ); return; } if ( !vlayer->isEditable() ) { notifyNotEditableLayer(); return; } // POINT CAPTURING if ( mode() == CapturePoint ) { if ( e->button() != Qt::LeftButton ) return; //check we only use this tool for point/multipoint layers if ( vlayer->geometryType() != QgsWkbTypes::PointGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), Qgis::Warning ); return; } QgsPoint savePoint; //point in layer coordinates bool isMatchPointZ = false; try { QgsPoint fetchPoint; int res; res = fetchLayerPoint( e->mapPointMatch(), fetchPoint ); if ( QgsWkbTypes::hasZ( fetchPoint.wkbType() ) ) isMatchPointZ = true; if ( res == 0 ) { if ( isMatchPointZ ) savePoint = fetchPoint; else savePoint = QgsPoint( fetchPoint.x(), fetchPoint.y() ); } else { QgsPointXY layerPoint = toLayerCoordinates( vlayer, e->mapPoint() ); if ( isMatchPointZ ) savePoint = QgsPoint( QgsWkbTypes::PointZ, layerPoint.x(), layerPoint.y(), fetchPoint.z() ); else savePoint = QgsPoint( layerPoint.x(), layerPoint.y() ); } } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::Warning ); return; } //only do the rest for provider with feature addition support //note that for the grass provider, this will return false since //grass provider has its own mechanism of feature addition if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) { QgsFeature f( vlayer->fields(), 0 ); QgsGeometry g; if ( layerWKBType == QgsWkbTypes::Point ) { g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint ) ); } else if ( !QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) ) { g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue() ) ); } else if ( QgsWkbTypes::isMultiType( layerWKBType ) && !QgsWkbTypes::hasZ( layerWKBType ) ) { g = QgsGeometry::fromMultiPointXY( QgsMultiPointXY() << savePoint ); } else if ( QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) ) { QgsMultiPoint *mp = new QgsMultiPoint(); mp->addGeometry( new QgsPoint( QgsWkbTypes::PointZ, savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue() ) ); g.set( mp ); } else { // if layer supports more types (mCheckGeometryType is false) g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint ) ); } if ( QgsWkbTypes::hasM( layerWKBType ) ) { g.get()->addMValue(); } f.setGeometry( g ); f.setValid( true ); digitized( f ); // we are done with digitizing for now so instruct advanced digitizing dock to reset its CAD points cadDockWidget()->clearPoints(); } } // LINE AND POLYGON CAPTURING else if ( mode() == CaptureLine || mode() == CapturePolygon ) { //check we only use the line tool for line/multiline layers if ( mode() == CaptureLine && vlayer->geometryType() != QgsWkbTypes::LineGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), Qgis::Warning ); return; } //check we only use the polygon tool for polygon/multipolygon layers if ( mode() == CapturePolygon && vlayer->geometryType() != QgsWkbTypes::PolygonGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), Qgis::Warning ); return; } //add point to list and to rubber band if ( e->button() == Qt::LeftButton ) { int error = addVertex( e->mapPoint(), e->mapPointMatch() ); if ( error == 1 ) { //current layer is not a vector layer return; } else if ( error == 2 ) { //problem with coordinate transformation emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::Warning ); return; } startCapturing(); } else if ( e->button() == Qt::RightButton ) { // End of string deleteTempRubberBand(); //lines: bail out if there are not at least two vertices if ( mode() == CaptureLine && size() < 2 ) { stopCapturing(); return; } //polygons: bail out if there are not at least two vertices if ( mode() == CapturePolygon && size() < 3 ) { stopCapturing(); return; } if ( mode() == CapturePolygon ) { closePolygon(); } //create QgsFeature with wkb representation std::unique_ptr< QgsFeature > f( new QgsFeature( vlayer->fields(), 0 ) ); //does compoundcurve contain circular strings? //does provider support circular strings? bool hasCurvedSegments = captureCurve()->hasCurvedSegments(); bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries; QList<QgsPointLocator::Match> snappingMatchesList; QgsCurve *curveToAdd = nullptr; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { curveToAdd = captureCurve()->clone(); } else { curveToAdd = captureCurve()->curveToLine(); snappingMatchesList = snappingMatches(); } if ( mode() == CaptureLine ) { QgsGeometry g( curveToAdd ); f->setGeometry( g ); } else { QgsCurvePolygon *poly = nullptr; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { poly = new QgsCurvePolygon(); } else { poly = new QgsPolygon(); } poly->setExteriorRing( curveToAdd ); QgsGeometry g( poly ); f->setGeometry( g ); QgsGeometry featGeom = f->geometry(); int avoidIntersectionsReturn = featGeom.avoidIntersections( QgsProject::instance()->avoidIntersectionsLayers() ); f->setGeometry( featGeom ); if ( avoidIntersectionsReturn == 1 ) { //not a polygon type. Impossible to get there } if ( f->geometry().isEmpty() ) //avoid intersection might have removed the whole geometry { emit messageEmitted( tr( "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ), Qgis::Critical ); stopCapturing(); return; } } f->setValid( true ); digitized( *f ); stopCapturing(); } } }
void QgsMapToolAddFeature::canvasMapReleaseEvent( QgsMapMouseEvent* e ) { QgsDebugMsg( "entered." ); QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ); if ( !vlayer ) { notifyNotVectorLayer(); return; } QGis::WkbType layerWKBType = vlayer->wkbType(); QgsVectorDataProvider* provider = vlayer->dataProvider(); if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) ) { emit messageEmitted( tr( "The data provider for this layer does not support the addition of features." ), QgsMessageBar::WARNING ); return; } if ( !vlayer->isEditable() ) { notifyNotEditableLayer(); return; } // POINT CAPTURING if ( mode() == CapturePoint ) { if ( e->button() != Qt::LeftButton ) return; //check we only use this tool for point/multipoint layers if ( vlayer->geometryType() != QGis::Point ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), QgsMessageBar::WARNING ); return; } QgsPoint savePoint; //point in layer coordinates try { savePoint = toLayerCoordinates( vlayer, e->mapPoint() ); QgsDebugMsg( "savePoint = " + savePoint.toString() ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING ); return; } //only do the rest for provider with feature addition support //note that for the grass provider, this will return false since //grass provider has its own mechanism of feature addition if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) { QgsFeature f( vlayer->pendingFields(), 0 ); QgsGeometry *g = 0; if ( layerWKBType == QGis::WKBPoint || layerWKBType == QGis::WKBPoint25D ) { g = QgsGeometry::fromPoint( savePoint ); } else if ( layerWKBType == QGis::WKBMultiPoint || layerWKBType == QGis::WKBMultiPoint25D ) { g = QgsGeometry::fromMultiPoint( QgsMultiPoint() << savePoint ); } f.setGeometry( g ); addFeature( vlayer, &f, false ); mCanvas->refresh(); } } // LINE AND POLYGON CAPTURING else if ( mode() == CaptureLine || mode() == CapturePolygon ) { //check we only use the line tool for line/multiline layers if ( mode() == CaptureLine && vlayer->geometryType() != QGis::Line ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), QgsMessageBar::WARNING ); return; } //check we only use the polygon tool for polygon/multipolygon layers if ( mode() == CapturePolygon && vlayer->geometryType() != QGis::Polygon ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), QgsMessageBar::WARNING ); return; } //add point to list and to rubber band if ( e->button() == Qt::LeftButton ) { int error = addVertex( e->mapPoint() ); if ( error == 1 ) { //current layer is not a vector layer return; } else if ( error == 2 ) { //problem with coordinate transformation emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING ); return; } startCapturing(); } else if ( e->button() == Qt::RightButton ) { // End of string deleteTempRubberBand(); //lines: bail out if there are not at least two vertices if ( mode() == CaptureLine && size() < 2 ) { stopCapturing(); return; } //polygons: bail out if there are not at least two vertices if ( mode() == CapturePolygon && size() < 3 ) { stopCapturing(); return; } //create QgsFeature with wkb representation QgsFeature* f = new QgsFeature( vlayer->pendingFields(), 0 ); QgsGeometry *g; if ( mode() == CaptureLine ) { if ( layerWKBType == QGis::WKBLineString || layerWKBType == QGis::WKBLineString25D ) { g = QgsGeometry::fromPolyline( points().toVector() ); } else if ( layerWKBType == QGis::WKBMultiLineString || layerWKBType == QGis::WKBMultiLineString25D ) { g = QgsGeometry::fromMultiPolyline( QgsMultiPolyline() << points().toVector() ); } else { emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL ); stopCapturing(); return; //unknown wkbtype } f->setGeometry( g ); } else // polygon { if ( layerWKBType == QGis::WKBPolygon || layerWKBType == QGis::WKBPolygon25D ) { g = QgsGeometry::fromPolygon( QgsPolygon() << points().toVector() ); } else if ( layerWKBType == QGis::WKBMultiPolygon || layerWKBType == QGis::WKBMultiPolygon25D ) { g = QgsGeometry::fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << points().toVector() ) ); } else { emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL ); stopCapturing(); return; //unknown wkbtype } if ( !g ) { stopCapturing(); delete f; return; // invalid geometry; one possibility is from duplicate points } f->setGeometry( g ); int avoidIntersectionsReturn = f->geometry()->avoidIntersections(); if ( avoidIntersectionsReturn == 1 ) { //not a polygon type. Impossible to get there } #if 0 else if ( avoidIntersectionsReturn == 2 ) //MH120131: disable this error message until there is a better way to cope with the single type / multi type problem { //bail out... emit messageEmitted( tr( "The feature could not be added because removing the polygon intersections would change the geometry type" ), QgsMessageBar::CRITICAL ); delete f; stopCapturing(); return; } #endif else if ( avoidIntersectionsReturn == 3 ) { emit messageEmitted( tr( "An error was reported during intersection removal" ), QgsMessageBar::CRITICAL ); } if ( !f->geometry()->asWkb() ) //avoid intersection might have removed the whole geometry { QString reason; if ( avoidIntersectionsReturn != 2 ) { reason = tr( "The feature cannot be added because it's geometry is empty" ); } else { reason = tr( "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ); } emit messageEmitted( reason, QgsMessageBar::CRITICAL ); delete f; stopCapturing(); return; } } if ( addFeature( vlayer, f, false ) ) { //add points to other features to keep topology up-to-date int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ); //use always topological editing for avoidIntersection. //Otherwise, no way to guarantee the geometries don't have a small gap in between. QStringList intersectionLayers = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList" ); bool avoidIntersection = !intersectionLayers.isEmpty(); if ( avoidIntersection ) //try to add topological points also to background layers { QStringList::const_iterator lIt = intersectionLayers.constBegin(); for ( ; lIt != intersectionLayers.constEnd(); ++lIt ) { QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( *lIt ); QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( ml ); //can only add topological points if background layer is editable... if ( vl && vl->geometryType() == QGis::Polygon && vl->isEditable() ) { vl->addTopologicalPoints( f->geometry() ); } } } else if ( topologicalEditing ) { vlayer->addTopologicalPoints( f->geometry() ); } } stopCapturing(); } } }
/// @see rcAllocPolyMesh, rcPolyMesh bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh) { rcAssert(ctx); if (!nmeshes || !meshes) return true; ctx->startTimer(RC_TIMER_MERGE_POLYMESH); mesh.nvp = meshes[0]->nvp; mesh.cs = meshes[0]->cs; mesh.ch = meshes[0]->ch; rcVcopy(mesh.bmin, meshes[0]->bmin); rcVcopy(mesh.bmax, meshes[0]->bmax); int maxVerts = 0; int maxPolys = 0; int maxVertsPerMesh = 0; for (int i = 0; i < nmeshes; ++i) { rcVmin(mesh.bmin, meshes[i]->bmin); rcVmax(mesh.bmax, meshes[i]->bmax); maxVertsPerMesh = rcMax(maxVertsPerMesh, meshes[i]->nverts); maxVerts += meshes[i]->nverts; maxPolys += meshes[i]->npolys; } mesh.nverts = 0; mesh.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVerts*3, RC_ALLOC_PERM); if (!mesh.verts) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.verts' (%d).", maxVerts*3); return false; } mesh.npolys = 0; mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys*2*mesh.nvp, RC_ALLOC_PERM); if (!mesh.polys) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.polys' (%d).", maxPolys*2*mesh.nvp); return false; } memset(mesh.polys, 0xff, sizeof(unsigned short)*maxPolys*2*mesh.nvp); mesh.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys, RC_ALLOC_PERM); if (!mesh.regs) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.regs' (%d).", maxPolys); return false; } memset(mesh.regs, 0, sizeof(unsigned short)*maxPolys); mesh.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxPolys, RC_ALLOC_PERM); if (!mesh.areas) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.areas' (%d).", maxPolys); return false; } memset(mesh.areas, 0, sizeof(unsigned char)*maxPolys); mesh.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxPolys, RC_ALLOC_PERM); if (!mesh.flags) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.flags' (%d).", maxPolys); return false; } memset(mesh.flags, 0, sizeof(unsigned short)*maxPolys); rcScopedDelete<int> nextVert = (int*)rcAlloc(sizeof(int)*maxVerts, RC_ALLOC_TEMP); if (!nextVert) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'nextVert' (%d).", maxVerts); return false; } memset(nextVert, 0, sizeof(int)*maxVerts); rcScopedDelete<int> firstVert = (int*)rcAlloc(sizeof(int)*VERTEX_BUCKET_COUNT, RC_ALLOC_TEMP); if (!firstVert) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT); return false; } for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i) firstVert[i] = -1; rcScopedDelete<unsigned short> vremap = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertsPerMesh, RC_ALLOC_PERM); if (!vremap) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'vremap' (%d).", maxVertsPerMesh); return false; } memset(vremap, 0, sizeof(unsigned short)*maxVertsPerMesh); for (int i = 0; i < nmeshes; ++i) { const rcPolyMesh* pmesh = meshes[i]; const unsigned short ox = (unsigned short)floorf((pmesh->bmin[0]-mesh.bmin[0])/mesh.cs+0.5f); const unsigned short oz = (unsigned short)floorf((pmesh->bmin[2]-mesh.bmin[2])/mesh.cs+0.5f); bool isMinX = (ox == 0); bool isMinZ = (oz == 0); bool isMaxX = ((unsigned short)floorf((mesh.bmax[0] - pmesh->bmax[0]) / mesh.cs + 0.5f)) == 0; bool isMaxZ = ((unsigned short)floorf((mesh.bmax[2] - pmesh->bmax[2]) / mesh.cs + 0.5f)) == 0; bool isOnBorder = (isMinX || isMinZ || isMaxX || isMaxZ); for (int j = 0; j < pmesh->nverts; ++j) { unsigned short* v = &pmesh->verts[j*3]; vremap[j] = addVertex(v[0]+ox, v[1], v[2]+oz, mesh.verts, firstVert, nextVert, mesh.nverts); } for (int j = 0; j < pmesh->npolys; ++j) { unsigned short* tgt = &mesh.polys[mesh.npolys*2*mesh.nvp]; unsigned short* src = &pmesh->polys[j*2*mesh.nvp]; mesh.regs[mesh.npolys] = pmesh->regs[j]; mesh.areas[mesh.npolys] = pmesh->areas[j]; mesh.flags[mesh.npolys] = pmesh->flags[j]; mesh.npolys++; for (int k = 0; k < mesh.nvp; ++k) { if (src[k] == RC_MESH_NULL_IDX) break; tgt[k] = vremap[src[k]]; } if (isOnBorder) { for (int k = mesh.nvp; k < mesh.nvp * 2; ++k) { if (src[k] & 0x8000 && src[k] != 0xffff) { unsigned short dir = src[k] & 0xf; switch (dir) { case 0: // Portal x- if (isMinX) tgt[k] = src[k]; break; case 1: // Portal z+ if (isMaxZ) tgt[k] = src[k]; break; case 2: // Portal x+ if (isMaxX) tgt[k] = src[k]; break; case 3: // Portal z- if (isMinZ) tgt[k] = src[k]; break; } } } } } } // Calculate adjacency. if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, mesh.nvp)) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Adjacency failed."); return false; } if (mesh.nverts > 0xffff) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff); } if (mesh.npolys > 0xffff) { ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff); } ctx->stopTimer(RC_TIMER_MERGE_POLYMESH); return true; }
AppMeshLock MsAppMesh::lockMesh(const AppTime & time, const Matrix<4,4,F32> &objectOffset) { msMesh *mesh = mMsNode->getMsMesh(); assert(mesh && "NULL milkshape mesh"); S32 lastMatIdx = -1; // start lists empty mFaces.clear(); mVerts.clear(); mTVerts.clear(); mIndices.clear(); mSmooth.clear(); mVertId.clear(); // start out with faces and crop data allocated mFaces.resize(msMesh_GetTriangleCount(mesh)); S32 vCount = msMesh_GetVertexCount(mesh); // Transform the vertices by the bounds and scale std::vector<Point3D> verts(vCount, Point3D()); for (int i = 0; i < vCount; i++) verts[i] = objectOffset * (getVert(mesh, i) * mMsNode->getScale()); int numTriangles = mFaces.size(); for (int i = 0; i < numTriangles; i++) { msTriangle *msFace = msMesh_GetTriangleAt(mesh, i); Primitive &tsFace = mFaces[i]; // set faces material index S32 matIndex = msMesh_GetMaterialIndex(mesh); tsFace.type = (matIndex >= 0) ? matIndex : Primitive::NoMaterial; tsFace.firstElement = mIndices.size(); tsFace.numElements = 3; tsFace.type |= Primitive::Triangles | Primitive::Indexed; // set vertex indices word vertIndices[3]; msTriangle_GetVertexIndices(msFace, vertIndices); Point3D vert0 = verts[vertIndices[0]]; Point3D vert1 = verts[vertIndices[1]]; Point3D vert2 = verts[vertIndices[2]]; Point3D norm0 = getNormal(mesh, i, 0); Point3D norm1 = getNormal(mesh, i, 1); Point3D norm2 = getNormal(mesh, i, 2); // set texture vertex indices Point2D tvert0 = getTVert(mesh, i, 0); Point2D tvert1 = getTVert(mesh, i, 1); Point2D tvert2 = getTVert(mesh, i, 2); // now add indices (switch order to be CW) mIndices.push_back(addVertex(vert0,norm0,tvert0,vertIndices[0])); mIndices.push_back(addVertex(vert2,norm2,tvert2,vertIndices[2])); mIndices.push_back(addVertex(vert1,norm1,tvert1,vertIndices[1])); // if the material is double-sided, add the backface as well if (!(tsFace.type & Primitive::NoMaterial)) { bool doubleSided = false; MilkshapeMaterial *msMat = mMsNode->getMaterial(); msMat->getUserPropBool("doubleSided", doubleSided); if (doubleSided) { Primitive backface = tsFace; backface.firstElement = mIndices.size(); mFaces.push_back(backface); // add verts with order reversed to get the backface mIndices.push_back(addVertex(vert0,-norm0,tvert0,vertIndices[0])); mIndices.push_back(addVertex(vert1,-norm1,tvert1,vertIndices[1])); mIndices.push_back(addVertex(vert2,-norm2,tvert2,vertIndices[2])); } } } return Parent::lockMesh(time,objectOffset); }
void Spline::addVertices(const std::vector<sf::Vector2f>& positions) { for (auto& position : positions) addVertex(position); }
void ofxPolyline2Mesh::addVertexes(const vector<ofVec3f>& verts) { for (int i = 0; i < verts.size(); i++) addVertex(verts[i]); }
void Spline::addVertices(const unsigned int numberOfVertices, const sf::Vector2f position) { for (unsigned int i{ 0 }; i < numberOfVertices; ++i) addVertex(position); }
the::mesh::ptr Polygon2d::createMesh(strref name, float zOffset, bool flipTriangles) { std::vector<std::vector<p2t::Point*>> polylines; std::vector<std::vector<p2t::Point*>> holes; std::vector<Vertex> engineVerts; std::vector<uint16_t> engineIndices; for(int i = 0;i<polygon.num_contours;i++) { std::vector<p2t::Point*> polyline; for(int j = 0; j < polygon.contour[i].num_vertices; j++) polyline.push_back(new p2t::Point(polygon.contour[i].vertex[j].x, polygon.contour[i].vertex[j].y)); if(polygon.hole[i]==0) { polylines.push_back(polyline); } else { holes.push_back(polyline); } } for(auto i = 0u; i < polylines.size(); i++) { std::vector<p2t::Point*> polyline = polylines[i]; p2t::CDT* cdt = new p2t::CDT(polyline); for(auto j = 0u; j < holes.size(); j++) { cdt->AddHole(holes[j]); } cdt->Triangulate(); std::vector<p2t::Triangle*> currentOutput = cdt->GetTriangles(); for(auto i = 0u; i < currentOutput.size(); i++) { p2t::Triangle *currentTriangle = currentOutput[i]; Vertex v1 = {{static_cast<float>(currentTriangle->GetPoint(0)->x),static_cast<float>(currentTriangle->GetPoint(0)->y), zOffset}, {1, 1}, {0, 0, flipTriangles?-1.0f:1.0f}}; Vertex v2 = {{static_cast<float>(currentTriangle->GetPoint(1)->x),static_cast<float>(currentTriangle->GetPoint(1)->y), zOffset}, {1, 1}, {0, 0, flipTriangles?-1.0f:1.0f}}; Vertex v3 = {{static_cast<float>(currentTriangle->GetPoint(2)->x),static_cast<float>(currentTriangle->GetPoint(2)->y), zOffset}, {1, 1}, {0, 0, flipTriangles?-1.0f:1.0f}}; int offset = engineVerts.size(); int t1 = flipTriangles?1:2; int t2 = flipTriangles?2:1; engineIndices.push_back(offset+0); engineIndices.push_back(offset+t2); engineIndices.push_back(offset+t1); engineVerts.push_back(v1); engineVerts.push_back(v2); engineVerts.push_back(v3); } delete cdt; } for(auto i = 0u; i < polylines.size(); i++) { std::vector<p2t::Point*> &polyline = polylines[i]; for(auto item:polyline) delete item; } for(auto i = 0u; i < holes.size(); i++) { std::vector<p2t::Point*> &hole = holes[i]; for(auto item:hole) delete item; } auto g = std::make_shared<the::mesh>(); g->setTag(name); g->addVertex(engineVerts); g->addSurface(std::move(the::surface(std::move(engineIndices), "plane"))); g->bind(); g->setMaterial(the::material::get("def::base")); g->setTexture(0, the::texture::get("def::base")); return g; }