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
that represent surfaces of platonic solids,
and other simple shapes.
and other simple shapes.
The 1st parameter is the mesh that will
be filled with the solid.
@ -88,8 +88,8 @@ void Dodecahedron(DodMeshType & in)
const int N_points=62;
int penta[N_penta*3*3]=
{20,11, 18, 18, 11, 8, 8, 11, 4,
13,23, 4, 4, 23, 8, 8, 23, 16,
{20,11, 18, 18, 11, 8, 8, 11, 4,
13,23, 4, 4, 23, 8, 8, 23, 16,
13, 4, 30, 30, 4, 28, 28, 4, 11,
16,34, 8, 8, 34, 18, 18, 34, 36,
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 p2=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, p, p3, -p, p2, p3, -p2, 0, 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,
-p2, 0, -p3, -p, -p2, -p3, 0, -p, -p3,
p, -p2, -p3, 0, 0, -2*p2
};
in.Clear();
//in.face.clear();
};
in.Clear();
//in.face.clear();
Allocator<DodMeshType>::AddVertices(in,20+12);
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);
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();
for (i=0; i<12; i++) {
for (j=0; j<5; j++){
(*fi).V(0)=index[added[i] ];
(*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(1)=index[reindex[penta[i*9 + order[j ] ] -1 ] ];
(*fi).V(2)=index[reindex[penta[i*9 + order[(j+1)%5] ] -1 ] ];
if (HasPerFaceFlags(in)) {
// tag faux edges
(*fi).SetF(0);
(*fi).SetF(2);
}
// tag faux edges
(*fi).SetF(0);
(*fi).SetF(2);
}
fi++;
}
}
@ -227,11 +227,11 @@ void Icosahedron(IcoMeshType &in)
typedef typename MeshType::FaceIterator FaceIterator;
ScalarType L=ScalarType((math::Sqrt(5.0)+1.0)/2.0);
CoordType vv[12]={
CoordType ( 0, L, 1),
CoordType ( 0, L,-1),
CoordType ( 0,-L, 1),
CoordType ( 0,-L,-1),
CoordType vv[12]={
CoordType ( 0, L, 1),
CoordType ( 0, L,-1),
CoordType ( 0,-L, 1),
CoordType ( 0,-L,-1),
CoordType ( L, 1, 0),
CoordType ( L,-1, 0),
@ -262,15 +262,15 @@ void Icosahedron(IcoMeshType &in)
int i;
for(i=0,vi=in.vert.begin();vi!=in.vert.end();++i,++vi){
(*vi).P()=vv[i];
ivp[i]=&*vi;
ivp[i]=&*vi;
}
FaceIterator fi;
for(i=0,fi=in.face.begin();fi!=in.face.end();++i,++fi){
(*fi).V(0)=ivp[ff[i][0]];
(*fi).V(1)=ivp[ff[i][1]];
(*fi).V(2)=ivp[ff[i][2]];
}
(*fi).V(0)=ivp[ff[i][0]];
(*fi).V(1)=ivp[ff[i][1]];
(*fi).V(2)=ivp[ff[i][2]];
}
}
template <class MeshType>
@ -366,7 +366,7 @@ void Sphere(MeshType &in, const int subdiv = 3 )
typedef typename MeshType::VertexPointer VertexPointer;
typedef typename MeshType::VertexIterator VertexIterator;
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;
for(vi = in.vert.begin(); vi!=in.vert.end();++vi)
@ -393,8 +393,8 @@ template <class MeshType>
void Cone( MeshType& in,
const typename MeshType::ScalarType r1,
const typename MeshType::ScalarType r2,
const typename MeshType::ScalarType h,
const int SubDiv = 36 )
const typename MeshType::ScalarType h,
const int SubDiv = 36 )
{
typedef typename MeshType::ScalarType ScalarType;
typedef typename MeshType::CoordType CoordType;
@ -405,41 +405,41 @@ void Cone( MeshType& in,
int i,b1,b2;
in.Clear();
int VN,FN;
if(r1==0 || r2==0) {
if(r1==0 || r2==0) {
VN=SubDiv+2;
FN=SubDiv*2;
} else {
} else {
VN=SubDiv*2+2;
FN=SubDiv*4;
}
}
Allocator<MeshType>::AddVertices(in,VN);
Allocator<MeshType>::AddFaces(in,FN);
VertexPointer *ivp = new VertexPointer[VN];
VertexPointer *ivp = new VertexPointer[VN];
VertexIterator vi=in.vert.begin();
ivp[0]=&*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;
if(r1!=0)
{
if(r1!=0)
{
for(i=0;i<SubDiv;++i)
{
{
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;
}
}
b2 += SubDiv;
}
}
if(r2!=0)
{
for(i=0;i<SubDiv;++i)
for(i=0;i<SubDiv;++i)
{
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;
}
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;
}
}
FaceIterator fi=in.face.begin();
@ -448,36 +448,36 @@ void Cone( MeshType& in,
(*fi).V(0)=ivp[0];
(*fi).V(1)=ivp[b1+i];
(*fi).V(2)=ivp[b1+(i+1)%SubDiv];
}
}
if(r2!=0) for(i=0;i<SubDiv;++i,++fi) {
(*fi).V(0)=ivp[1];
(*fi).V(2)=ivp[b2+i];
(*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(1)=ivp[b2+i];
(*fi).V(2)=ivp[b2+(i+1)%SubDiv];
(*fi).V(0)=ivp[0];
(*fi).V(1)=ivp[b2+i];
(*fi).V(2)=ivp[b2+(i+1)%SubDiv];
}
if(r2==0) for(i=0;i<SubDiv;++i,++fi){
(*fi).V(0)=ivp[1];
(*fi).V(2)=ivp[b1+i];
(*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(1)=ivp[b2+i];
(*fi).V(2)=ivp[b2+(i+1)%SubDiv];
++fi;
(*fi).V(0)=ivp[b1+i];
(*fi).V(1)=ivp[b2+(i+1)%SubDiv];
(*fi).V(2)=ivp[b1+(i+1)%SubDiv];
++fi;
(*fi).V(0)=ivp[b1+i];
(*fi).V(1)=ivp[b2+i];
(*fi).V(2)=ivp[b2+(i+1)%SubDiv];
++fi;
(*fi).V(0)=ivp[b1+i];
(*fi).V(1)=ivp[b2+(i+1)%SubDiv];
(*fi).V(2)=ivp[b1+(i+1)%SubDiv];
++fi;
}
}
@ -572,9 +572,9 @@ void Build( MeshType & in, const V & v, const F & f)
Allocator<MeshType>::AddVertices(in,v.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)
{
@ -583,14 +583,14 @@ void Build( MeshType & in, const V & v, const F & f)
}
std::vector<VertexPointer> index(in.vn);
VertexIterator j;
int k;
for(k=0,j=in.vert.begin();j!=in.vert.end();++j,++k)
index[k] = &*j;
VertexIterator j;
int k;
for(k=0,j=in.vert.begin();j!=in.vert.end();++j,++k)
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)
{
@ -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)
{
int V0i= grid[(i+0)*w+j+0];
int V1i= grid[(i+0)*w+j+1];
int V2i= grid[(i+1)*w+j+0];
int V3i= grid[(i+1)*w+j+1];
int V1i= grid[(i+0)*w+j+1];
int V2i= grid[(i+1)*w+j+0];
int V3i= grid[(i+1)*w+j+1];
int ndone=0;
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++;
}
if (ndone==0) { // try diag the other way
if(V2i>=0 && V0i>=0 && V1i>=0 )
{
typename MeshType::FaceIterator f= Allocator<MeshType>::AddFaces(in,1);
f->V(0)=&(in.vert[V2i]);
f->V(1)=&(in.vert[V0i]);
f->V(2)=&(in.vert[V1i]);
ndone++;
}
if(V1i>=0 && V3i>=0 && V2i>=0 )
{
typename MeshType::FaceIterator f= Allocator<MeshType>::AddFaces(in,1);
f->V(0)=&(in.vert[V1i]);
f->V(1)=&(in.vert[V3i]);
f->V(2)=&(in.vert[V2i]);
ndone++;
}
if (ndone==0) { // try diag the other way
if(V2i>=0 && V0i>=0 && V1i>=0 )
{
typename MeshType::FaceIterator f= Allocator<MeshType>::AddFaces(in,1);
f->V(0)=&(in.vert[V2i]);
f->V(1)=&(in.vert[V0i]);
f->V(2)=&(in.vert[V1i]);
ndone++;
}
if(V1i>=0 && V3i>=0 && V2i>=0 )
{
typename MeshType::FaceIterator f= Allocator<MeshType>::AddFaces(in,1);
f->V(0)=&(in.vert[V1i]);
f->V(1)=&(in.vert[V3i]);
f->V(2)=&(in.vert[V2i]);
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>
void Disk(MeshType & m, int slices)
@ -760,9 +804,8 @@ void Disk(MeshType & m, int slices)
for ( int j = 0; j < slices; ++j)
{
float x,y;
x = cos( 2.0 * M_PI / slices * j);
y = sin( 2.0 * M_PI / 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);
++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));
for ( int i = 0; i < stacks+1; ++i)
for ( int j = 0; j < slices; ++j)
{
float x,y,h;
for ( int j = 0; j < slices; ++j)
{
float x,y,h;
x = cos( 2.0 * M_PI / slices * j);
y = sin( 2.0 * M_PI / slices * j);
h = 2 * i / (float)(stacks) - 1;
@ -812,22 +855,22 @@ void Cylinder(int slices, int stacks, MeshType & m){
typename MeshType::FaceIterator fi ;
for ( int j = 0; j < stacks; ++j)
for ( int i = 0; i < slices; ++i)
{
int a,b,c,d;
a = (j+0)*slices + i;
b = (j+1)*slices + i;
c = (j+1)*slices + (i+1)%slices;
d = (j+0)*slices + (i+1)%slices;
{
int a,b,c,d;
a = (j+0)*slices + i;
b = (j+1)*slices + i;
c = (j+1)*slices + (i+1)%slices;
d = (j+0)*slices + (i+1)%slices;
if(((i+j)%2) == 0){
fi = vcg::tri::Allocator<MeshType>::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<MeshType>::AddFaces(m,1);
(*fi).V(0) = &m.vert[ c ];
(*fi).V(1) = &m.vert[ d ];
(*fi).V(2) = &m.vert[ a ];
fi = vcg::tri::Allocator<MeshType>::AddFaces(m,1);
(*fi).V(0) = &m.vert[ c ];
(*fi).V(1) = &m.vert[ d ];
(*fi).V(2) = &m.vert[ a ];
}
else{
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(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(1) = &m.vert[ a ];
(*fi).V(2) = &m.vert[ b ];
}
}
}
if (HasPerFaceFlags(m)) {