diff --git a/vcg/complex/algorithms/create/platonic.h b/vcg/complex/algorithms/create/platonic.h index 563b4a76..a7e09a89 100644 --- a/vcg/complex/algorithms/create/platonic.h +++ b/vcg/complex/algorithms/create/platonic.h @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -875,11 +876,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, bool capped, int slices=32, int stacks=4 ) +void OrientedEllipticPrism(MeshType & m, const Point3f origin, const Point3f end, float radius, float xScale, float yScale,bool capped, int slices=32, int stacks=4 ) { Cylinder(slices,stacks,m,capped); tri::UpdatePosition::Translate(m,Point3f(0,1,0)); tri::UpdatePosition::Scale(m,Point3f(1,0.5f,1)); + tri::UpdatePosition::Scale(m,Point3f(xScale,1.0f,yScale)); float height = Distance(origin,end); tri::UpdatePosition::Scale(m,Point3f(radius,height,radius)); @@ -890,8 +892,16 @@ void OrientedCylinder(MeshType & m, const Point3f origin, const Point3f end, flo rotM.SetRotateRad(angleRad,axis); tri::UpdatePosition::Matrix(m,rotM); tri::UpdatePosition::Translate(m,origin); + } +template +void OrientedCylinder(MeshType & m, const Point3f origin, const Point3f end, float radius, bool capped, int slices=32, int stacks=4 ) +{ + OrientedEllipticPrism(m,origin,end,radius,1.0f,1.0f,capped,slices,stacks); +} + + template void Cylinder(int slices, int stacks, MeshType & m, bool capped=false) { @@ -945,6 +955,87 @@ void Cylinder(int slices, int stacks, MeshType & m, bool capped=false) } } + + +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 BuildPrismFaceShell(MeshType &mIn, MeshType &mOut, float height=0, float inset=0, bool smoothFlag=true ) +{ + typedef typename MeshType::VertexPointer VertexPointer; + typedef typename MeshType::FacePointer FacePointer; + typedef typename MeshType::CoordType CoordType; + if(height==0) height = mIn.bbox.Diag()/100.0f; + if(inset==0) inset = mIn.bbox.Diag()/200.0f; + tri::UpdateFlags::FaceClearV(mIn); + for(size_t i=0;i vertVec; + std::vector faceVec; + tri::PolygonSupport::ExtractPolygon(&(mIn.face[i]),vertVec,faceVec); + size_t vn = vertVec.size(); + + CoordType nf(0,0,0); + for(size_t j=0;jN().Normalize() * DoubleArea(*faceVec[j]); + nf.Normalize(); + nf = nf*height/2.0f; + + CoordType bary(0,0,0); + for(size_t j=0;j::AddVertex(faceM, bary-nf); + tri::Allocator<_SphMesh>::AddVertex(faceM, bary+nf); + for(size_t j=0;jP() - bary); + delta.Normalize(); + delta = delta*inset; + tri::Allocator<_SphMesh>::AddVertex(faceM, vertVec[j]->P()-delta-nf); + tri::Allocator<_SphMesh>::AddVertex(faceM, vertVec[j]->P()-delta+nf); + } + + // Build top and bottom faces + for(size_t j=0;j::AddFace(faceM, 0, 2+(j+0)*2, 2+((j+1)%vn)*2 ); + for(size_t j=0;j::AddFace(faceM, 1, 3+((j+1)%vn)*2, 3+(j+0)*2 ); + + // Build side strip + for(size_t j=0;j::AddFace(faceM, 2+ j0*2 + 0 , 2+ j0*2+1, 2+j1*2+0); + tri::Allocator<_SphMesh>::AddFace(faceM, 2+ j0*2 + 1 , 2+ j1*2+1, 2+j1*2+0); + } + + for(size_t j=0;j<2*vn;++j) + faceM.face[j].SetS(); + + tri::UpdateTopology<_SphMesh>::FaceFace(faceM); + tri::UpdateFlags<_SphMesh>::FaceBorderFromFF(faceM); + tri::Refine(faceM, MidPoint<_SphMesh>(&faceM),0,true); + tri::Refine(faceM, MidPoint<_SphMesh>(&faceM),0,true); + tri::UpdateSelection<_SphMesh>::VertexFromFaceStrict(faceM); + tri::Smooth<_SphMesh>::VertexCoordLaplacian(faceM,2,true,true); + + tri::Append::Mesh(mOut,faceM); + + } // end main loop for each face; +} + + template void BuildCylinderEdgeShell(MeshType &mIn, MeshType &mOut, float radius=0, int slices=16, int stacks=1 ) { @@ -960,16 +1051,6 @@ void BuildCylinderEdgeShell(MeshType &mIn, MeshType &mOut, float radius=0, int s } } - -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 ) {