added Annulus and OrientedAnnulus to mesh creation helpers

This commit is contained in:
Paolo Cignoni 2013-04-15 20:14:27 +00:00
parent a5f4b797c7
commit cbba83d17c
1 changed files with 226 additions and 183 deletions

View File

@ -40,7 +40,7 @@ namespace tri {
/** /**
A set of functions that builds meshes A set of functions that builds meshes
that represent surfaces of platonic solids, that represent surfaces of platonic solids,
and other simple shapes. and other simple shapes.
The 1st parameter is the mesh that will The 1st parameter is the mesh that will
be filled with the solid. be filled with the solid.
@ -88,8 +88,8 @@ void Dodecahedron(DodMeshType & in)
const int N_points=62; const int N_points=62;
int penta[N_penta*3*3]= int penta[N_penta*3*3]=
{20,11, 18, 18, 11, 8, 8, 11, 4, {20,11, 18, 18, 11, 8, 8, 11, 4,
13,23, 4, 4, 23, 8, 8, 23, 16, 13,23, 4, 4, 23, 8, 8, 23, 16,
13, 4, 30, 30, 4, 28, 28, 4, 11, 13, 4, 30, 30, 4, 28, 28, 4, 11,
16,34, 8, 8, 34, 18, 18, 34, 36, 16,34, 8, 8, 34, 18, 18, 34, 36,
11,20, 28, 28, 20, 45, 45, 20, 38, 11,20, 28, 28, 20, 45, 45, 20, 38,
@ -104,8 +104,8 @@ void Dodecahedron(DodMeshType & in)
const ScalarType p=(1.0 + math::Sqrt(5.0)) / 2.0; const ScalarType p=(1.0 + math::Sqrt(5.0)) / 2.0;
const ScalarType p2=p*p; const ScalarType p2=p*p;
const ScalarType p3=p*p*p; const ScalarType p3=p*p*p;
ScalarType vv[N_points*3]= ScalarType vv[N_points*3]=
{ {
0, 0, 2*p2, p2, 0, p3, p, p2, p3, 0, 0, 2*p2, p2, 0, p3, p, p2, p3,
0, p, p3, -p, p2, p3, -p2, 0, p3, 0, p, p3, -p, p2, p3, -p2, 0, p3,
-p, -p2, p3, 0, -p, p3, p, -p2, p3, -p, -p2, p3, 0, -p, p3, p, -p2, p3,
@ -127,9 +127,9 @@ void Dodecahedron(DodMeshType & in)
p, p2, -p3, 0, p, -p3, -p, p2, -p3, p, p2, -p3, 0, p, -p3, -p, p2, -p3,
-p2, 0, -p3, -p, -p2, -p3, 0, -p, -p3, -p2, 0, -p3, -p, -p2, -p3, 0, -p, -p3,
p, -p2, -p3, 0, 0, -2*p2 p, -p2, -p3, 0, 0, -2*p2
}; };
in.Clear(); in.Clear();
//in.face.clear(); //in.face.clear();
Allocator<DodMeshType>::AddVertices(in,20+12); Allocator<DodMeshType>::AddVertices(in,20+12);
Allocator<DodMeshType>::AddFaces(in, 5*12); // five pentagons, each made by 5 tri Allocator<DodMeshType>::AddFaces(in, 5*12); // five pentagons, each made by 5 tri
@ -163,20 +163,20 @@ void Dodecahedron(DodMeshType & in)
std::vector<VertexPointer> index(in.vn); std::vector<VertexPointer> index(in.vn);
for(j=0,vi=in.vert.begin();j<in.vn;++j,++vi) index[j] = &(*vi); for(j=0,vi=in.vert.begin();j<in.vn;++j,++vi) index[j] = &(*vi);
FaceIterator fi=in.face.begin(); FaceIterator fi=in.face.begin();
for (i=0; i<12; i++) { for (i=0; i<12; i++) {
for (j=0; j<5; j++){ for (j=0; j<5; j++){
(*fi).V(0)=index[added[i] ]; (*fi).V(0)=index[added[i] ];
(*fi).V(1)=index[reindex[penta[i*9 + order[j ] ] -1 ] ]; (*fi).V(1)=index[reindex[penta[i*9 + order[j ] ] -1 ] ];
(*fi).V(2)=index[reindex[penta[i*9 + order[(j+1)%5] ] -1 ] ]; (*fi).V(2)=index[reindex[penta[i*9 + order[(j+1)%5] ] -1 ] ];
if (HasPerFaceFlags(in)) { if (HasPerFaceFlags(in)) {
// tag faux edges // tag faux edges
(*fi).SetF(0); (*fi).SetF(0);
(*fi).SetF(2); (*fi).SetF(2);
} }
fi++; fi++;
} }
} }
@ -227,11 +227,11 @@ void Icosahedron(IcoMeshType &in)
typedef typename MeshType::FaceIterator FaceIterator; typedef typename MeshType::FaceIterator FaceIterator;
ScalarType L=ScalarType((math::Sqrt(5.0)+1.0)/2.0); ScalarType L=ScalarType((math::Sqrt(5.0)+1.0)/2.0);
CoordType vv[12]={ CoordType vv[12]={
CoordType ( 0, L, 1), CoordType ( 0, L, 1),
CoordType ( 0, L,-1), CoordType ( 0, L,-1),
CoordType ( 0,-L, 1), CoordType ( 0,-L, 1),
CoordType ( 0,-L,-1), CoordType ( 0,-L,-1),
CoordType ( L, 1, 0), CoordType ( L, 1, 0),
CoordType ( L,-1, 0), CoordType ( L,-1, 0),
@ -262,15 +262,15 @@ void Icosahedron(IcoMeshType &in)
int i; int i;
for(i=0,vi=in.vert.begin();vi!=in.vert.end();++i,++vi){ for(i=0,vi=in.vert.begin();vi!=in.vert.end();++i,++vi){
(*vi).P()=vv[i]; (*vi).P()=vv[i];
ivp[i]=&*vi; ivp[i]=&*vi;
} }
FaceIterator fi; FaceIterator fi;
for(i=0,fi=in.face.begin();fi!=in.face.end();++i,++fi){ for(i=0,fi=in.face.begin();fi!=in.face.end();++i,++fi){
(*fi).V(0)=ivp[ff[i][0]]; (*fi).V(0)=ivp[ff[i][0]];
(*fi).V(1)=ivp[ff[i][1]]; (*fi).V(1)=ivp[ff[i][1]];
(*fi).V(2)=ivp[ff[i][2]]; (*fi).V(2)=ivp[ff[i][2]];
} }
} }
template <class MeshType> template <class MeshType>
@ -366,7 +366,7 @@ void Sphere(MeshType &in, const int subdiv = 3 )
typedef typename MeshType::VertexPointer VertexPointer; typedef typename MeshType::VertexPointer VertexPointer;
typedef typename MeshType::VertexIterator VertexIterator; typedef typename MeshType::VertexIterator VertexIterator;
typedef typename MeshType::FaceIterator FaceIterator; typedef typename MeshType::FaceIterator FaceIterator;
if(in.vn==0 && in.fn==0) Icosahedron(in); if(in.vn==0 && in.fn==0) Icosahedron(in);
VertexIterator vi; VertexIterator vi;
for(vi = in.vert.begin(); vi!=in.vert.end();++vi) for(vi = in.vert.begin(); vi!=in.vert.end();++vi)
@ -393,8 +393,8 @@ template <class MeshType>
void Cone( MeshType& in, void Cone( MeshType& in,
const typename MeshType::ScalarType r1, const typename MeshType::ScalarType r1,
const typename MeshType::ScalarType r2, const typename MeshType::ScalarType r2,
const typename MeshType::ScalarType h, const typename MeshType::ScalarType h,
const int SubDiv = 36 ) const int SubDiv = 36 )
{ {
typedef typename MeshType::ScalarType ScalarType; typedef typename MeshType::ScalarType ScalarType;
typedef typename MeshType::CoordType CoordType; typedef typename MeshType::CoordType CoordType;
@ -405,41 +405,41 @@ void Cone( MeshType& in,
int i,b1,b2; int i,b1,b2;
in.Clear(); in.Clear();
int VN,FN; int VN,FN;
if(r1==0 || r2==0) { if(r1==0 || r2==0) {
VN=SubDiv+2; VN=SubDiv+2;
FN=SubDiv*2; FN=SubDiv*2;
} else { } else {
VN=SubDiv*2+2; VN=SubDiv*2+2;
FN=SubDiv*4; FN=SubDiv*4;
} }
Allocator<MeshType>::AddVertices(in,VN); Allocator<MeshType>::AddVertices(in,VN);
Allocator<MeshType>::AddFaces(in,FN); Allocator<MeshType>::AddFaces(in,FN);
VertexPointer *ivp = new VertexPointer[VN]; VertexPointer *ivp = new VertexPointer[VN];
VertexIterator vi=in.vert.begin(); VertexIterator vi=in.vert.begin();
ivp[0]=&*vi;(*vi).P()=CoordType ( 0,-h/2.0,0 ); ++vi; ivp[0]=&*vi;(*vi).P()=CoordType ( 0,-h/2.0,0 ); ++vi;
ivp[1]=&*vi;(*vi).P()=CoordType ( 0, h/2.0,0 ); ++vi; ivp[1]=&*vi;(*vi).P()=CoordType ( 0, h/2.0,0 ); ++vi;
b1 = b2 = 2; b1 = b2 = 2;
int cnt=2; int cnt=2;
if(r1!=0) if(r1!=0)
{ {
for(i=0;i<SubDiv;++i) for(i=0;i<SubDiv;++i)
{ {
double a = math::ToRad(i*360.0/SubDiv); double a = math::ToRad(i*360.0/SubDiv);
ivp[cnt]=&*vi; (*vi).P()= CoordType(r1*cos(a), -h/2.0, r1*sin(a)); ++vi;++cnt; ivp[cnt]=&*vi; (*vi).P()= CoordType(r1*cos(a), -h/2.0, r1*sin(a)); ++vi;++cnt;
} }
b2 += SubDiv; b2 += SubDiv;
} }
if(r2!=0) if(r2!=0)
{ {
for(i=0;i<SubDiv;++i) for(i=0;i<SubDiv;++i)
{ {
double a = math::ToRad(i*360.0/SubDiv); double a = math::ToRad(i*360.0/SubDiv);
ivp[cnt]=&*vi; (*vi).P()= CoordType( r2*cos(a), h/2.0, r2*sin(a)); ++vi;++cnt; ivp[cnt]=&*vi; (*vi).P()= CoordType( r2*cos(a), h/2.0, r2*sin(a)); ++vi;++cnt;
} }
} }
FaceIterator fi=in.face.begin(); FaceIterator fi=in.face.begin();
@ -448,36 +448,36 @@ void Cone( MeshType& in,
(*fi).V(0)=ivp[0]; (*fi).V(0)=ivp[0];
(*fi).V(1)=ivp[b1+i]; (*fi).V(1)=ivp[b1+i];
(*fi).V(2)=ivp[b1+(i+1)%SubDiv]; (*fi).V(2)=ivp[b1+(i+1)%SubDiv];
} }
if(r2!=0) for(i=0;i<SubDiv;++i,++fi) { if(r2!=0) for(i=0;i<SubDiv;++i,++fi) {
(*fi).V(0)=ivp[1]; (*fi).V(0)=ivp[1];
(*fi).V(2)=ivp[b2+i]; (*fi).V(2)=ivp[b2+i];
(*fi).V(1)=ivp[b2+(i+1)%SubDiv]; (*fi).V(1)=ivp[b2+(i+1)%SubDiv];
} }
if(r1==0) for(i=0;i<SubDiv;++i,++fi) if(r1==0) for(i=0;i<SubDiv;++i,++fi)
{ {
(*fi).V(0)=ivp[0]; (*fi).V(0)=ivp[0];
(*fi).V(1)=ivp[b2+i]; (*fi).V(1)=ivp[b2+i];
(*fi).V(2)=ivp[b2+(i+1)%SubDiv]; (*fi).V(2)=ivp[b2+(i+1)%SubDiv];
} }
if(r2==0) for(i=0;i<SubDiv;++i,++fi){ if(r2==0) for(i=0;i<SubDiv;++i,++fi){
(*fi).V(0)=ivp[1]; (*fi).V(0)=ivp[1];
(*fi).V(2)=ivp[b1+i]; (*fi).V(2)=ivp[b1+i];
(*fi).V(1)=ivp[b1+(i+1)%SubDiv]; (*fi).V(1)=ivp[b1+(i+1)%SubDiv];
} }
if(r1!=0 && r2!=0)for(i=0;i<SubDiv;++i) if(r1!=0 && r2!=0)for(i=0;i<SubDiv;++i)
{ {
(*fi).V(0)=ivp[b1+i]; (*fi).V(0)=ivp[b1+i];
(*fi).V(1)=ivp[b2+i]; (*fi).V(1)=ivp[b2+i];
(*fi).V(2)=ivp[b2+(i+1)%SubDiv]; (*fi).V(2)=ivp[b2+(i+1)%SubDiv];
++fi; ++fi;
(*fi).V(0)=ivp[b1+i]; (*fi).V(0)=ivp[b1+i];
(*fi).V(1)=ivp[b2+(i+1)%SubDiv]; (*fi).V(1)=ivp[b2+(i+1)%SubDiv];
(*fi).V(2)=ivp[b1+(i+1)%SubDiv]; (*fi).V(2)=ivp[b1+(i+1)%SubDiv];
++fi; ++fi;
} }
} }
@ -572,9 +572,9 @@ void Build( MeshType & in, const V & v, const F & f)
Allocator<MeshType>::AddVertices(in,v.size()); Allocator<MeshType>::AddVertices(in,v.size());
Allocator<MeshType>::AddFaces(in,f.size()); Allocator<MeshType>::AddFaces(in,f.size());
typename V::const_iterator vi; typename V::const_iterator vi;
typename MeshType::VertexType tv; typename MeshType::VertexType tv;
for(int i=0;i<v.size();++i) for(int i=0;i<v.size();++i)
{ {
@ -583,14 +583,14 @@ void Build( MeshType & in, const V & v, const F & f)
} }
std::vector<VertexPointer> index(in.vn); std::vector<VertexPointer> index(in.vn);
VertexIterator j; VertexIterator j;
int k; int k;
for(k=0,j=in.vert.begin();j!=in.vert.end();++j,++k) for(k=0,j=in.vert.begin();j!=in.vert.end();++j,++k)
index[k] = &*j; index[k] = &*j;
typename F::const_iterator fi; typename F::const_iterator fi;
typename MeshType::FaceType ft; typename MeshType::FaceType ft;
for(int i=0;i<f.size();++i) for(int i=0;i<f.size();++i)
{ {
@ -700,9 +700,9 @@ void FaceGrid(MeshType & in, const std::vector<int> &grid, int w, int h)
for(int j=0;j<w-1;++j) for(int j=0;j<w-1;++j)
{ {
int V0i= grid[(i+0)*w+j+0]; int V0i= grid[(i+0)*w+j+0];
int V1i= grid[(i+0)*w+j+1]; int V1i= grid[(i+0)*w+j+1];
int V2i= grid[(i+1)*w+j+0]; int V2i= grid[(i+1)*w+j+0];
int V3i= grid[(i+1)*w+j+1]; int V3i= grid[(i+1)*w+j+1];
int ndone=0; int ndone=0;
bool quad = (V0i>=0 && V1i>=0 && V2i>=0 && V3i>=0 ) && tri::HasPerFaceFlags(in); bool quad = (V0i>=0 && V1i>=0 && V2i>=0 && V3i>=0 ) && tri::HasPerFaceFlags(in);
@ -726,29 +726,73 @@ void FaceGrid(MeshType & in, const std::vector<int> &grid, int w, int h)
ndone++; ndone++;
} }
if (ndone==0) { // try diag the other way if (ndone==0) { // try diag the other way
if(V2i>=0 && V0i>=0 && V1i>=0 ) if(V2i>=0 && V0i>=0 && V1i>=0 )
{ {
typename MeshType::FaceIterator f= Allocator<MeshType>::AddFaces(in,1); typename MeshType::FaceIterator f= Allocator<MeshType>::AddFaces(in,1);
f->V(0)=&(in.vert[V2i]); f->V(0)=&(in.vert[V2i]);
f->V(1)=&(in.vert[V0i]); f->V(1)=&(in.vert[V0i]);
f->V(2)=&(in.vert[V1i]); f->V(2)=&(in.vert[V1i]);
ndone++; ndone++;
} }
if(V1i>=0 && V3i>=0 && V2i>=0 ) if(V1i>=0 && V3i>=0 && V2i>=0 )
{ {
typename MeshType::FaceIterator f= Allocator<MeshType>::AddFaces(in,1); typename MeshType::FaceIterator f= Allocator<MeshType>::AddFaces(in,1);
f->V(0)=&(in.vert[V1i]); f->V(0)=&(in.vert[V1i]);
f->V(1)=&(in.vert[V3i]); f->V(1)=&(in.vert[V3i]);
f->V(2)=&(in.vert[V2i]); f->V(2)=&(in.vert[V2i]);
ndone++; ndone++;
} }
} }
} }
} }
template <class MeshType>
void Annulus(MeshType & m, float externalRadius, float internalRadius, int slices)
{
m.Clear();
typename MeshType::VertexIterator vi = vcg::tri::Allocator<MeshType>::AddVertices(m,slices*2);
for ( int j = 0; j < slices; ++j)
{
float x = cos( 2.0 * M_PI / slices * j);
float y = sin( 2.0 * M_PI / slices * j);
(*vi).P() = typename MeshType::CoordType(x,y,0)*internalRadius;
++vi;
(*vi).P() = typename MeshType::CoordType(x,y,0)*externalRadius;
++vi;
}
typename MeshType::FaceIterator fi ;
for ( int j = 0; j < slices; ++j)
{
fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
(*fi).V(0) = &m.vert[ ((j+0)*2+0)%(slices*2) ];
(*fi).V(1) = &m.vert[ ((j+1)*2+1)%(slices*2) ];
(*fi).V(2) = &m.vert[ ((j+0)*2+1)%(slices*2) ];
fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
(*fi).V(0) = &m.vert[ ((j+1)*2+0)%(slices*2) ];
(*fi).V(1) = &m.vert[ ((j+1)*2+1)%(slices*2) ];
(*fi).V(2) = &m.vert[ ((j+0)*2+0)%(slices*2) ];
}
}
template <class MeshType>
void OrientedAnnulus(MeshType & m, Point3f center, Point3f norm, float externalRadius, float internalRadius, int slices)
{
Annulus(m,externalRadius,internalRadius, slices);
float angleRad = Angle(Point3f(0,0,1),norm);
Point3f axis = Point3f(0,0,1)^norm;
Matrix44f rotM;
rotM.SetRotateRad(angleRad,axis);
tri::UpdatePosition<MeshType>::Matrix(m,rotM);
tri::UpdatePosition<MeshType>::Translate(m,center);
}
template <class MeshType> template <class MeshType>
void Disk(MeshType & m, int slices) void Disk(MeshType & m, int slices)
@ -760,9 +804,8 @@ void Disk(MeshType & m, int slices)
for ( int j = 0; j < slices; ++j) for ( int j = 0; j < slices; ++j)
{ {
float x,y; float x = cos( 2.0 * M_PI / slices * j);
x = cos( 2.0 * M_PI / slices * j); float y = sin( 2.0 * M_PI / slices * j);
y = sin( 2.0 * M_PI / slices * j);
(*vi).P() = typename MeshType::CoordType(x,y,0); (*vi).P() = typename MeshType::CoordType(x,y,0);
++vi; ++vi;
@ -798,9 +841,9 @@ void Cylinder(int slices, int stacks, MeshType & m){
typename MeshType::VertexIterator vi = vcg::tri::Allocator<MeshType>::AddVertices(m,slices*(stacks+1)); typename MeshType::VertexIterator vi = vcg::tri::Allocator<MeshType>::AddVertices(m,slices*(stacks+1));
for ( int i = 0; i < stacks+1; ++i) for ( int i = 0; i < stacks+1; ++i)
for ( int j = 0; j < slices; ++j) for ( int j = 0; j < slices; ++j)
{ {
float x,y,h; float x,y,h;
x = cos( 2.0 * M_PI / slices * j); x = cos( 2.0 * M_PI / slices * j);
y = sin( 2.0 * M_PI / slices * j); y = sin( 2.0 * M_PI / slices * j);
h = 2 * i / (float)(stacks) - 1; h = 2 * i / (float)(stacks) - 1;
@ -812,22 +855,22 @@ void Cylinder(int slices, int stacks, MeshType & m){
typename MeshType::FaceIterator fi ; typename MeshType::FaceIterator fi ;
for ( int j = 0; j < stacks; ++j) for ( int j = 0; j < stacks; ++j)
for ( int i = 0; i < slices; ++i) for ( int i = 0; i < slices; ++i)
{ {
int a,b,c,d; int a,b,c,d;
a = (j+0)*slices + i; a = (j+0)*slices + i;
b = (j+1)*slices + i; b = (j+1)*slices + i;
c = (j+1)*slices + (i+1)%slices; c = (j+1)*slices + (i+1)%slices;
d = (j+0)*slices + (i+1)%slices; d = (j+0)*slices + (i+1)%slices;
if(((i+j)%2) == 0){ if(((i+j)%2) == 0){
fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1); fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
(*fi).V(0) = &m.vert[ a ]; (*fi).V(0) = &m.vert[ a ];
(*fi).V(1) = &m.vert[ b ]; (*fi).V(1) = &m.vert[ b ];
(*fi).V(2) = &m.vert[ c ]; (*fi).V(2) = &m.vert[ c ];
fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1); fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
(*fi).V(0) = &m.vert[ c ]; (*fi).V(0) = &m.vert[ c ];
(*fi).V(1) = &m.vert[ d ]; (*fi).V(1) = &m.vert[ d ];
(*fi).V(2) = &m.vert[ a ]; (*fi).V(2) = &m.vert[ a ];
} }
else{ else{
fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1); fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
@ -835,12 +878,12 @@ void Cylinder(int slices, int stacks, MeshType & m){
(*fi).V(1) = &m.vert[ c ]; (*fi).V(1) = &m.vert[ c ];
(*fi).V(2) = &m.vert[ d ]; (*fi).V(2) = &m.vert[ d ];
fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1); fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
(*fi).V(0) = &m.vert[ d ]; (*fi).V(0) = &m.vert[ d ];
(*fi).V(1) = &m.vert[ a ]; (*fi).V(1) = &m.vert[ a ];
(*fi).V(2) = &m.vert[ b ]; (*fi).V(2) = &m.vert[ b ];
} }
} }
if (HasPerFaceFlags(m)) { if (HasPerFaceFlags(m)) {