diff --git a/vcg/complex/algorithms/create/platonic.h b/vcg/complex/algorithms/create/platonic.h index 4202b673..cdc2bd13 100644 --- a/vcg/complex/algorithms/create/platonic.h +++ b/vcg/complex/algorithms/create/platonic.h @@ -28,8 +28,10 @@ #include #include #include +#include #include #include +#include namespace vcg { @@ -354,6 +356,46 @@ void Square(MeshType &in) } } +template +void SphericalCap(MeshType &in, float angleRad, const int subdiv = 3 ) +{ + in.Clear(); + tri::Allocator::AddVertex(in,Point3f(0,0,0)); + for(int i=0;i<6;++i) + tri::Allocator::AddVertex(in,Point3f(cos(math::ToRad(i*60.0)),sin(math::ToRad(i*60.0)),0)); + + for(int i=0;i<6;++i) + tri::Allocator::AddFace(in,&(in.vert[0]),&(in.vert[1+i]),&(in.vert[1+(i+1)%6])); + + tri::UpdateTopology::FaceFace(in); + for(int i=0;i(&in)); + + tri::UpdateFlags::FaceBorderFromFF(in); + tri::UpdateFlags::VertexBorderFromFace(in); + + for(int i=0;i::VertexFromBorderFlag(in); + tri::UpdateSelection::VertexInvert(in); + tri::Smooth::VertexCoordLaplacian(in,10,true); + } + + float angleHalfRad = angleRad /2.0f; + float width = sin(angleHalfRad); + tri::UpdatePosition::Scale(in,width); + + for(size_t i=0;i &grid, int w, int h) ndone++; } } - - } } - template void Annulus(MeshType & m, float externalRadius, float internalRadius, int slices) { @@ -839,13 +878,12 @@ void OrientedDisk(MeshType &m, int slices, Point3f center, Point3f norm, float r } template -void OrientedCylinder(MeshType & m, const Point3f origin, const Point3f end, float radius, int slices=32, int stacks=4 ) +void OrientedCylinder(MeshType & m, const Point3f origin, const Point3f end, float radius, bool capped, int slices=32, int stacks=4 ) { - Cylinder(slices,stacks,m); + Cylinder(slices,stacks,m,capped); tri::UpdatePosition::Translate(m,Point3f(0,1,0)); tri::UpdatePosition::Scale(m,Point3f(1,0.5f,1)); - Matrix44f scale; float height = Distance(origin,end); tri::UpdatePosition::Scale(m,Point3f(radius,height,radius)); Point3f norm = end-origin; @@ -858,7 +896,7 @@ void OrientedCylinder(MeshType & m, const Point3f origin, const Point3f end, flo } template -void Cylinder(int slices, int stacks, MeshType & m) +void Cylinder(int slices, int stacks, MeshType & m, bool capped=false) { m.Clear(); typename MeshType::VertexIterator vi = vcg::tri::Allocator::AddVertices(m,slices*(stacks+1)); @@ -874,7 +912,6 @@ void Cylinder(int slices, int stacks, MeshType & m) ++vi; } - typename MeshType::FaceIterator fi ; for ( int j = 0; j < stacks; ++j) for ( int i = 0; i < slices; ++i) { @@ -884,30 +921,26 @@ void Cylinder(int slices, int stacks, MeshType & m) c = (j+1)*slices + (i+1)%slices; d = (j+0)*slices + (i+1)%slices; if(((i+j)%2) == 0){ - fi = vcg::tri::Allocator::AddFaces(m,1); - (*fi).V(0) = &m.vert[ a ]; - (*fi).V(1) = &m.vert[ b ]; - (*fi).V(2) = &m.vert[ c ]; - - fi = vcg::tri::Allocator::AddFaces(m,1); - (*fi).V(0) = &m.vert[ c ]; - (*fi).V(1) = &m.vert[ d ]; - (*fi).V(2) = &m.vert[ a ]; + vcg::tri::Allocator::AddFace(m, &m.vert[ a ], &m.vert[ b ], &m.vert[ c ]); + vcg::tri::Allocator::AddFace(m, &m.vert[ c ], &m.vert[ d ], &m.vert[ a ]); } else{ - fi = vcg::tri::Allocator::AddFaces(m,1); - (*fi).V(0) = &m.vert[ b ]; - (*fi).V(1) = &m.vert[ c ]; - (*fi).V(2) = &m.vert[ d ]; - - fi = vcg::tri::Allocator::AddFaces(m,1); - (*fi).V(0) = &m.vert[ d ]; - (*fi).V(1) = &m.vert[ a ]; - (*fi).V(2) = &m.vert[ b ]; - + vcg::tri::Allocator::AddFace(m, &m.vert[ b ], &m.vert[ c ], &m.vert[ d ]); + vcg::tri::Allocator::AddFace(m, &m.vert[ d ], &m.vert[ a ], &m.vert[ b ]); } } + if(capped) + { + tri::Allocator::AddVertex(m,typename MeshType::CoordType(0,-1,0)); + tri::Allocator::AddVertex(m,typename MeshType::CoordType(0, 1,0)); + int base = 0; + for ( int i = 0; i < slices; ++i) + vcg::tri::Allocator::AddFace(m, &m.vert[ m.vn-2 ], &m.vert[ base+i ], &m.vert[ base+(i+1)%slices ]); + base = (stacks)*slices; + for ( int i = 0; i < slices; ++i) + vcg::tri::Allocator::AddFace(m, &m.vert[ m.vn-1 ], &m.vert[ base+(i+1)%slices ], &m.vert[ base+i ]); + } if (HasPerFaceFlags(m)) { for (typename MeshType::FaceIterator fi=m.face.begin(); fi!=m.face.end(); fi++) { (*fi).SetF(2); @@ -915,6 +948,62 @@ void Cylinder(int slices, int stacks, MeshType & m) } } +template +void BuildCylinderEdgeShell(MeshType &mIn, MeshType &mOut, float radius=0, int slices=16, int stacks=1 ) +{ + if(radius==0) radius = mIn.bbox.Diag()/100.0f; + typedef typename tri::UpdateTopology::PEdge PEdge; + std::vector edgeVec; + tri::UpdateTopology::FillUniqueEdgeVector(mIn,edgeVec,false); + for(size_t i=0;iP(),edgeVec[i].v[1]->P(),radius,false,slices,stacks); + tri::Append::Mesh(mOut,mCyl); + } +} + + +class _SphFace; +class _SphVertex; +struct _SphUsedTypes : public UsedTypes< Use<_SphVertex> ::AsVertexType, + Use<_SphFace> ::AsFaceType>{}; + +class _SphVertex : public Vertex<_SphUsedTypes, vertex::Coord3f, vertex::Normal3f, vertex::BitFlags >{}; +class _SphFace : public Face< _SphUsedTypes, face::VertexRef, face::Normal3f, face::BitFlags, face::FFAdj > {}; +class _SphMesh : public tri::TriMesh< vector<_SphVertex>, vector<_SphFace> > {}; + +template +void BuildSphereVertexShell(MeshType &mIn, MeshType &mOut, float radius=0, int recDiv=2 ) +{ + if(radius==0) radius = mIn.bbox.Diag()/100.0f; + for(size_t i=0;i::Scale(mSph,radius); + tri::UpdatePosition<_SphMesh>::Translate(mSph,mIn.vert[i].P()); + tri::Append::Mesh(mOut,mSph); + } +} + +template +void BuildCylinderVertexShell(MeshType &mIn, MeshType &mOut, float radius=0, float height=0 ) +{ + if(radius==0) radius = mIn.bbox.Diag()/100.0f; + if(height==0) height = mIn.bbox.Diag()/200.0f; + for(size_t i=0;i::Mesh(mOut,mCyl); + } +} + + template void GenerateCameraMesh(MeshType &in){ typedef typename MeshType::CoordType MV;