std::auto_ptr<Geometry> tesselate( const Geometry& g, NoValidityCheck ) { switch ( g.geometryTypeId() ) { case TYPE_POINT: case TYPE_LINESTRING: case TYPE_TRIANGLE: case TYPE_MULTIPOINT: case TYPE_MULTILINESTRING: return std::auto_ptr<Geometry>( g.clone() ); case TYPE_POLYGON: case TYPE_POLYHEDRALSURFACE: { TriangulatedSurface* triSurf = new TriangulatedSurface(); triangulate::triangulatePolygon3D( g, *triSurf ); return std::auto_ptr<Geometry>( triSurf ); } case TYPE_SOLID: { std::auto_ptr<GeometryCollection> ret( new GeometryCollection ); for ( size_t i = 0; i < g.as<Solid>().numShells(); ++i ) { const PolyhedralSurface& shellN = g.as<Solid>().shellN( i ) ; if ( ! shellN.isEmpty() ) { ret->addGeometry( tesselate( shellN ).release() ); } } return std::auto_ptr<Geometry>( ret.release() ); } // multipolygon and multisolid return a geometrycollection case TYPE_MULTIPOLYGON: case TYPE_MULTISOLID: case TYPE_GEOMETRYCOLLECTION: { std::auto_ptr<GeometryCollection> ret( new GeometryCollection ); for ( size_t i = 0; i < g.numGeometries(); ++i ) { ret->addGeometry( tesselate( g.geometryN( i ) ).release() ); } return std::auto_ptr<Geometry>( ret.release() ); } default: break; } return std::auto_ptr<Geometry>( g.clone() ); }
void Stroke::draw(Renderer_ptr renderer, uint64_t time) { _shader->setWidth(_width); _shader->setColor(_color); _shader->setStartLength(0.0); _shader->setEndLength(_pathLength); _shader->bind(); // TODO: make this async, instead of tesselating at render-time. if (_dirty) { // TODO: need better LOD calculation. int vertexCount = static_cast<int>(_pathLength); if (vertexCount % 2 == 1) vertexCount++; int triangleCount = (vertexCount - 2) * 2; std::unique_ptr<Vertex[]> vertices(new Vertex[vertexCount]); // TODO: this should be a static Arc function; tesselate(vertices.get(), vertexCount, _path); unique_ptr<grfx::Buffer> vertexBuffer(new grfx::GpuBuffer(renderer, GL_ARRAY_BUFFER)); vertexBuffer->load(std::move(vertices), vertexCount * sizeof(Vertex), GL_STATIC_DRAW); _mesh.reset(new StrokeMesh()); _mesh->setBuffers(std::move(vertexBuffer), Stroke::indexBuffer(renderer, triangleCount), 0, triangleCount); _dirty = false; } _mesh->draw(renderer); }
// cree une sphere en tesselant un tetraedre regulier CSphere::CSphere(unsigned tessel) { CTetrahedron o; unsigned f=(unsigned)pow(4,tessel+1); unsigned v=f; nb_faces=4; nb_verts=4; vertices = new SMLVec3f[v]; faces = new CFace[f]; for (v=0; v<o.nb_verts; v++) { vertices[v] = o.vertices[v]; } for (f=0; f<o.nb_faces; f++) { faces[f].pt_ind[0] = o.faces[f].pt_ind[0]; faces[f].pt_ind[1] = o.faces[f].pt_ind[1]; faces[f].pt_ind[2] = o.faces[f].pt_ind[2]; } tesselate(tessel); // calcule les normales for (f=0; f<nb_faces; f++) { faces[f].pt_norm[0] = vertices[faces[f].pt_ind[0]]; faces[f].pt_norm[1] = vertices[faces[f].pt_ind[1]]; faces[f].pt_norm[2] = vertices[faces[f].pt_ind[2]]; } compute_normals_from_vertices(); }
void Polygon::finish( AppearanceManager& appearanceManager, bool doTesselate ) { TVec3d normal = computeNormal(); if ( doTesselate ) tesselate( appearanceManager, normal ); else mergeRings( appearanceManager ); // Create the normal per point field _normals.resize( _vertices.size() ); for ( unsigned int i = 0; i < _vertices.size(); i++ ) _normals[i] = TVec3f( (float)normal.x, (float)normal.y, (float)normal.z ); }
static void show_mesh_between(SkCanvas* canvas, const SkPath& p0, const SkPath& p1) { SkPath d0, d1; tesselate(p0, &d0); tesselate(p1, &d1); SkPoint pts0[256*2], pts1[256]; int count = d0.getPoints(pts0, SK_ARRAY_COUNT(pts0)); int count1 = d1.getPoints(pts1, SK_ARRAY_COUNT(pts1)); SkASSERT(count == count1); memcpy(&pts0[count], pts1, count * sizeof(SkPoint)); uint16_t indices[256*6]; uint16_t* ndx = indices; for (int i = 0; i < count; ++i) { *ndx++ = i; *ndx++ = i + count; } *ndx++ = 0; show_mesh(canvas, pts0, indices, ndx - indices); }
const Kernel::FT volume( const Solid& solid, NoValidityCheck ) { Kernel::FT vol = 0; const CGAL::Point_3<Kernel> origin( 0,0,0 ); const size_t numShells = solid.numShells(); for ( size_t i=0; i<numShells; i++ ) { std::auto_ptr<Geometry> t( tesselate( solid.shellN( i ), NoValidityCheck() ) ); const TriangulatedSurface& tin = t->as<TriangulatedSurface>(); const size_t numTriangles = tin.numTriangles(); for ( size_t j=0; j<numTriangles; j++ ) { const Triangle& tri = tin.triangleN( j ); vol = vol + CGAL::volume( origin, tri.vertex( 0 ).toPoint_3(), tri.vertex( 1 ).toPoint_3(), tri.vertex( 2 ).toPoint_3() ); } } return vol; }
void PHBezierPath::rebuildVAO(PHGLVertexArrayObject * vao, const PHRect & texCoord) { const vector<anchorPoint> * a = tesselate(calculatedVertices()); size_t nVertices; GLfloat * r = vertexDataFromAnchorList(*a, texCoord, nVertices); delete a; vao->bindToEdit(); PHGLVBO * vbo = vao->attributeVBO(PHIMAGEATTRIBUTE_POS); if (!vbo) vbo = new PHGLVertexBufferObject(vao->gameManager()); else vbo->retain(); vbo->bindTo(PHGLVBO::arrayBuffer); vbo->setData(NULL, nVertices*4*sizeof(GLfloat), PHGLVBO::dynamicDraw); vbo->setSubData(r, 0, nVertices*4*sizeof(GLfloat)); vao->vertexPointer(PHIMAGEATTRIBUTE_POS, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 0, vbo); vao->vertexPointer(PHIMAGEATTRIBUTE_TXC, 2, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), 2*sizeof(GLfloat), vbo); vbo->unbind(); vbo->release(); size_t nIndexes; GLushort * indexes = triangulatePolygon(r, 4, nVertices, nIndexes); delete r; PHGLVBO * ivbo = vao->elementArrayVBO(); if (!ivbo) ivbo = new PHGLVertexBufferObject(vao->gameManager()); else ivbo->retain(); ivbo->bindTo(PHGLVBO::elementArrayBuffer); ivbo->setData(indexes, nIndexes*sizeof(GLushort), PHGLVBO::dynamicDraw); vao->setDrawElements(GL_TRIANGLES, nIndexes, GL_UNSIGNED_SHORT, 0); ivbo->release(); delete indexes; vao->unbind(); }
static void draw_oval(SkCanvas* canvas, bool showGL, int flags) { SkPaint paint; paint.setAntiAlias(true); SkRect r = SkRect::MakeLTRB(50, 70, 250, 370); setFade(&paint, showGL); canvas->drawOval(r, paint); if (showGL) { switch (flags) { case 0: { SkPath path; path.addOval(r); show_glframe(canvas, path); } break; case 1: case 3: { SkPath src, dst; src.addOval(r); tesselate(src, &dst); show_fan(canvas, dst, r.centerX(), r.centerY()); } break; case 2: { SkPaint p(paint); show_mesh(canvas, r); setGLFrame(&p); paint.setStyle(SkPaint::kFill_Style); canvas->drawCircle(r.centerX(), r.centerY(), 3, p); } break; } } canvas->translate(320, 0); paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(25); canvas->drawOval(r, paint); if (showGL) { switch (flags) { case 0: { SkPath path; SkScalar rad = paint.getStrokeWidth() / 2; r.outset(rad, rad); path.addOval(r); r.inset(rad*2, rad*2); path.addOval(r); show_glframe(canvas, path); } break; case 1: { SkPath path0, path1; SkScalar rad = paint.getStrokeWidth() / 2; r.outset(rad, rad); path0.addOval(r); r.inset(rad*2, rad*2); path1.addOval(r); show_mesh_between(canvas, path0, path1); } break; case 2: { SkPath path; path.addOval(r); show_glframe(canvas, path); SkScalar rad = paint.getStrokeWidth() / 2; r.outset(rad, rad); show_mesh(canvas, r); } break; case 3: { SkScalar rad = paint.getStrokeWidth() / 2; r.outset(rad, rad); SkPaint paint; paint.setAlpha(0x33); canvas->drawRect(r, paint); show_mesh(canvas, r); } break; } } }
std::auto_ptr<Geometry> tesselate( const Geometry& g ) { SFCGAL_ASSERT_GEOMETRY_VALIDITY( g ); return tesselate( g, NoValidityCheck() ); }