int main(int argc, char *argv[]) { // Read in the obj file Solid mesh; OBJFileReader of; std::ifstream in(argv[1]); of.readToSolid(&mesh, in); //answer part Solid meshCopy; mesh.copy(meshCopy); //storing all vertices int i=0; SolidVertexIterator veriter(&mesh); Vertex *allvert[mesh.numVertices()]; for(i=0;!veriter.end();i++,++veriter) { allvert[i]=*veriter; } //storing all edges SolidEdgeIterator eiter(&mesh); Edge *alledges[mesh.numEdges()]; for(i=0;!eiter.end();i++,++eiter) { alledges[i]=*eiter; } Edge *swapList[mesh.numFaces()]; Edge *splitSwap[2]={NULL,NULL}; //getting max face SolidFaceIterator fciter(&mesh); int maxfcid=-1; for(; !fciter.end(); ++fciter) { if((*fciter)->id()>maxfcid) maxfcid=(*fciter)->id(); } //splitting and swapping by iterating through edges SolidEdgeIterator eitercpy(&meshCopy); int j; double x,y,z; for(i=0,j=0;i<(sizeof(alledges)/sizeof(*alledges));i++,++eitercpy) { splitSwap[0]=splitSwap[1]=NULL; Vertex *evert1= mesh.edgeVertex1(alledges[i]); Vertex *evert2= mesh.edgeVertex2(alledges[i]); Vertex *ver1=mesh.edgeSplit(alledges[i],splitSwap,maxfcid); if(splitSwap[0]!=NULL) swapList[j++]=splitSwap[0]; if(splitSwap[1]!=NULL) swapList[j++]=splitSwap[1]; //position of new vertex determined here if(mesh.isBoundary(*eitercpy)) { //printf("Check"); x=(evert1->point()(0)/2)+(evert2->point()(0)/2); y=(evert1->point()(1)/2)+(evert2->point()(1)/2); z=(evert1->point()(2)/2)+(evert2->point()(2)/2); //printf("\n%f %f %f\n",x,y,z); } else { x=((evert1->point()(0))+(evert2->point()(0)))*(3.0/8.0); y=((evert1->point()(1))+(evert2->point()(1)))*(3.0/8.0); z=((evert1->point()(2))+(evert2->point()(2)))*(3.0/8.0); x+=(((((*eitercpy)->halfedge(0))->he_next())->target())->point()(0)/8.0)+(((((*eitercpy)->halfedge(1))->he_next())->target())->point()(0)/8.0); y+=(((((*eitercpy)->halfedge(0))->he_next())->target())->point()(1)/8.0)+(((((*eitercpy)->halfedge(1))->he_next())->target())->point()(1)/8.0); z+=(((((*eitercpy)->halfedge(0))->he_next())->target())->point()(2)/8.0)+(((((*eitercpy)->halfedge(1))->he_next())->target())->point()(2)/8.0); } ver1->point()=Point(x,y,z); } for(i=0;i<(sizeof(swapList)/sizeof(*swapList));i++) { Edge *e=swapList[i]; mesh.edgeSwap(e,((e->halfedge(0))->he_next())->target(),((e->halfedge(1))->he_next())->target()); } //new position of old vertices determined here SolidVertexIterator veritercpy(&meshCopy); double tem1,tem2,tem3,alpha; for(i=0;i<(sizeof(allvert)/sizeof(*allvert));i++,++veritercpy) { Vertex *oldv=allvert[i]; //printf("\n%f %f %f -> ",oldv->point()(0),oldv->point()(1),oldv->point()(2)); VertexVertexIterator vviter(*veritercpy); //printf("Im here\n"); tem1=tem2=tem3=0; j=0; if(mesh.isBoundary(*veritercpy)) { //printf("Hi"); for(j=0;!vviter.end();++vviter) { if(mesh.isBoundary(*vviter)) { tem1+=(*vviter)->point()(0); tem2+=(*vviter)->point()(1); tem3+=(*vviter)->point()(2); j++; } } x=tem1/8.0 + oldv->point()(0)*(3.0/4.0); y=tem2/8.0 + oldv->point()(1)*(3.0/4.0); z=tem3/8.0 + oldv->point()(2)*(3.0/4.0); } else { tem1=tem2=tem3=0; for(j=0;!vviter.end();++vviter) { tem1+=(*vviter)->point()(0); tem2+=(*vviter)->point()(1); tem3+=(*vviter)->point()(2); j++; } //printf("%d\n",j); if(j>3) alpha=(1.0/j)*((5.0/8.0)-pow(((3.0/8.0)+(1.0/4.0)*(cos(2*PI/j))),2)); else if(j==3) alpha=3/16; x=((1-j*alpha)*oldv->point()(0)) + (alpha*(tem1)); y=((1-j*alpha)*oldv->point()(1)) + (alpha*(tem2));; z=((1-j*alpha)*oldv->point()(2)) + (alpha*(tem3));; } oldv->point()=Point(x,y,z); //printf("\n%f %f %f %f-> ",x,y,z, (1.0/4.0)*cos(2*PI/j)); //printf("\n%f %f %f -> ",oldv->point()(0),oldv->point()(1),oldv->point()(2)); } // Write out the resultant obj file int vObjID = 1; std::map<int, int> vidToObjID; std::ofstream os(argv[2]); SolidVertexIterator iter(&mesh); for(; !iter.end(); ++iter) { Vertex *v = *iter; Point p = v->point(); os << "v " << p[0] << " " << p[1] << " " << p[2] << std::endl; vidToObjID[v->id()] = vObjID++; } os << "# " << (unsigned int)mesh.numVertices() << " vertices" << std::endl; float u = 0.0, v = 0.0; for(iter.reset(); !iter.end(); ++iter) { Vertex *vv = *iter; std::string key( "uv" ); std::string s = Trait::getTraitValue (vv->string(), key ); if( s.length() > 0 ) { sscanf( s.c_str (), "%f %f", &u, &v ); } os << "vt " << u << " " << v << std::endl; } os << "# " << (unsigned int)mesh.numVertices() << " texture coordinates" << std::endl; SolidFaceIterator fiter(&mesh); for(; !fiter.end(); ++fiter) { Face *f = *fiter; FaceVertexIterator viter(f); os << "f " ; for(; !viter.end(); ++viter) { Vertex *v = *viter; os << vidToObjID[v->id()] << "/" << vidToObjID[v->id()] << " "; } os << std::endl; } os.close(); return 0; }
void main(int argc, char *argv[]) { // Read in the obj file Solid mesh; OBJFileReader of; std::ifstream in(argv[1]); string filename = argv[1]; string::size_type npos = filename.find(".obj"); string s = ".m"; filename.replace(npos, 4,s); of.readToSolid(&mesh, in); /******************* Put you subdivision processing here *********************/ //1. highlights all edges zz begin 2013-02-21 16:11:20 SolidEdgeIterator eiter(&mesh); for(; !eiter.end(); ++eiter) { Edge *e = *eiter; e->string ()=std::string("sharp"); } //end zz 2013Äê2ÔÂ21ÈÕ16:18:10 //2. establish the adjacency list [2/21/2013 Zhe] list<int> Graphface[Num]; SolidFaceIterator fiter(&mesh); for(; !fiter.end(); ++fiter) { Face *f = *fiter; FaceHalfedgeIterator hfiter(f); HalfEdge *hf = NULL; for (;!hfiter.end();++hfiter) { hf = *hfiter; hf = hf->he_sym(); Graphface[f->id()].push_back(hf->face()->id()); } } // [2/21/2013 Zhe] /************************************************************************/ /* // 3.MST Algorithm [19:00/2/21/2013 Zhe] */ /************************************************************************/ list<int> Mstqueue; queue<int> nLayer; list<int>::iterator mstiterator,Mstqueueiterator,Layeriterator; fiter.reset(); int a[Num] = {0}; Face *MSTface = *fiter; Mstqueue.push_back(MSTface->id()); nLayer.push(MSTface->id()); //initialization a[MSTface->id()] = TRUE; while (!nLayer.empty()) { int Faceid = nLayer.front(); nLayer.pop(); //MstGraphface[Faceid].push_back(Faceid); for (mstiterator = Graphface[Faceid].begin();mstiterator != Graphface[Faceid].end();++mstiterator) { //Layeriterator = find (Mstqueue.begin(), Mstqueue.end(), *mstiterator); if (a[*mstiterator] == 0) { Mstqueue.push_back(*mstiterator); nLayer.push(*mstiterator); a[*mstiterator] = TRUE; int nFaceid_father = Faceid; int nFaceId_son = *mstiterator; MeshLib::Face *f = mesh.idFace (nFaceid_father); MeshLib::FaceHalfedgeIterator fheiter(f); MeshLib::Edge * inter_edge; for (; !fheiter.end (); ++fheiter) { MeshLib::HalfEdge *he = *fheiter; he = he->he_sym (); if (he->face ()->id ()== nFaceId_son) { inter_edge=he->edge (); inter_edge->string () = std::string(""); break; } } } } } // 3. cut the graph [23:19/2/21/2013 Zhe] SolidVertexIterator iter(&mesh); std::map<int, int> vidToObjID; do { for(; !iter.end(); ++iter) { Vertex *v = *iter; MeshLib::VertexEdgeIterator edgeiter(v); MeshLib::Edge * inter_edge; int nsharp = 0; for (;!edgeiter.end();++edgeiter) { inter_edge = *edgeiter; if (inter_edge->string() == "sharp") { nsharp++; } } //delete nsharp == 1 if (1 == nsharp) { edgeiter.reset(); for (;!edgeiter.end();++edgeiter) { inter_edge = *edgeiter; if (inter_edge->string() == "sharp") { inter_edge->string () = std::string(""); //nsharp = 0; } } } vidToObjID[v->id()] = nsharp; } iter.reset(); } while (ifsharpequalone(vidToObjID)); mesh.write (filename.c_str()); // os.close(); }
void main(int argc, char *argv[]) { // Read in the obj file Solid mesh; OBJFileReader of; std::ifstream in(argv[1]); of.readToSolid(&mesh, in); SolidDelegate sodel; SolidVertexIterator viter(&mesh); SolidFaceIterator faceiter(&mesh); Point deltaPL[2502]; Point Normal[2502]; Point tuettePoint[2502]; Point harmonicPoint[2502]; double innerProduct; Point normalComp; Point aDerv; for (int i = 0; i < 2502; i++) { deltaPL[i][0] = 0.0; deltaPL[i][1] = 0.0; deltaPL[i][2] = 0.0; Normal[i][0] = 0.0; Normal[i][1] = 0.0; Normal[i][2] = 0.0; tuettePoint[i][0] = 0.0; tuettePoint[i][1] = 0.0; tuettePoint[i][2] = 0.0; harmonicPoint[i] = { 0.0, 0.0, 0.0 }; } for (; !viter.end(); ++viter) { Vertex *vertmp = *viter; //VertexOutHalfedgeIterator voh(&mesh, vertmp); Point norm;//calc new Norm double totalArea = 0.0; norm[0] = norm[1] = norm[2] = 0.0; VertexFaceIterator vf(vertmp); for (; !vf.end(); ++vf){ double area = 0.0; Face *f = *vf; Point v1 = f->halfedge()->source()->point(); Point v2 = f->halfedge()->target()->point(); Point v3 = f->halfedge()->he_next()->target()->point(); area = ((v3 - v1) ^ (v2 - v1)).norm(); Point n = f->norm(); norm += n * area; totalArea += area; } Point newNorm; norm = norm / totalArea; double normN = norm.norm(); newNorm = norm / normN; //Normal & Gauss Map Normal[vertmp->id() - 1] = newNorm; } SolidEdgeIterator edgeiter(&mesh); double tuetteEnergy = 0.0; double newTEnergy = 0.0; double harmoincEnergy = 0.0; double newHEnergy = 0.0; double stepLength = 0.01; double eThreshold = 0.00001; for (; !edgeiter.end(); ++edgeiter) { Edge *e = *edgeiter; Vertex *s = mesh.edgeVertex1(e); Vertex *t = mesh.edgeVertex2(e); tuetteEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2(); } //harmonic K double K, cota, cotb; edgeiter.reset(); for (; !edgeiter.end(); ++edgeiter) { Edge *e = *edgeiter; Vertex *s = mesh.edgeVertex1(e); Vertex *t = mesh.edgeVertex2(e); HalfEdge *he = e->halfedge(1); he = he->ccw_rotate_about_source(); Vertex *v1 = he->target(); he = he->clw_rotate_about_source()->clw_rotate_about_source(); Vertex *v2 = he->target(); cota = (s->point() - v1->point())*(t->point() - v1->point()) / ((s->point() - v1->point()) ^ (t->point() - v1->point())).norm(); cotb = (s->point() - v2->point())*(t->point() - v2->point()) / ((s->point() - v2->point()) ^ (t->point() - v2->point())).norm(); K = (cota + cotb) / 2.0; edgemap.insert({ e, K }); } viter.reset(); //Gauss map update for (; !viter.end(); ++viter) { Vertex *vertmp = *viter; vertmp->point() = Normal[vertmp->id() - 1] ; } viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; VertexOutHalfedgeIterator voh(&mesh, vertmp); Point u = vertmp->point(); int id = vertmp->id()-1; double num = 0.0; for (; !voh.end(); ++voh) { HalfEdge *he1 = *voh; Vertex *v1 = he1->target(); Point v = v1->point(); deltaPL[id] += v - u; num = num + 1.0; } deltaPL[id] = deltaPL[id] / num; } //absolute derivatives viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; VertexOutHalfedgeIterator voh(&mesh, vertmp); Point u = vertmp->point(); int id = vertmp->id() - 1; innerProduct = deltaPL[id] * Normal[id]; normalComp[0] = innerProduct * Normal[id][0]; normalComp[1] = innerProduct * Normal[id][1]; normalComp[2] = innerProduct * Normal[id][2]; Point aDerv = deltaPL[id] - normalComp; Point tuetteUpdate = aDerv * stepLength; tuettePoint[id] = tuetteUpdate; //step 3 } viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; int id = vertmp->id() - 1; Normal[id] += tuettePoint[id]; Normal[id] = Normal[id] / Normal[id].norm(); } edgeiter.reset(); for (; !edgeiter.end(); ++edgeiter) { Edge *e = *edgeiter; Vertex *s = mesh.edgeVertex1(e); Vertex *t = mesh.edgeVertex2(e); newTEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2(); } viter.reset(); //tuette map update for (; !viter.end(); ++viter) { Vertex *vertmp = *viter; vertmp->point() =Normal[vertmp->id() - 1]; } //while(1==0) while (!(fabs(newTEnergy - tuetteEnergy) < eThreshold*1000)) {//step 5 tuetteEnergy = newTEnergy; newTEnergy = 0.0; //printf("%f\n", tuetteEnergy); viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; VertexOutHalfedgeIterator voh(&mesh, vertmp); Point u = vertmp->point(); int id = vertmp->id() - 1; double num = 0.0; for (; !voh.end(); ++voh) { HalfEdge *he1 = *voh; Vertex *v1 = he1->target(); Point v = v1->point(); deltaPL[id] += v - u; num = num + 1.0; } deltaPL[id] = deltaPL[id] / num; } viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; VertexOutHalfedgeIterator voh(&mesh, vertmp); Point u = vertmp->point(); int id = vertmp->id() - 1; innerProduct = deltaPL[id] * Normal[id]; normalComp[0] = innerProduct * Normal[id][0]; normalComp[1] = innerProduct * Normal[id][1]; normalComp[2] = innerProduct * Normal[id][2]; Point aDerv = deltaPL[id] - normalComp; Point tuetteUpdate = aDerv * stepLength; tuettePoint[id] = tuetteUpdate; //step 3 } viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; int id = vertmp->id() - 1; Normal[id] += tuettePoint[id]; Normal[id] = Normal[id] / Normal[id].norm(); } edgeiter.reset(); for (; !edgeiter.end(); ++edgeiter) { Edge *e = *edgeiter; Vertex *s = mesh.edgeVertex1(e); Vertex *t = mesh.edgeVertex2(e); newTEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2(); } viter.reset(); //tuette map update for (; !viter.end(); ++viter) { Vertex *vertmp = *viter; vertmp->point() = Normal[vertmp->id() - 1]; } } tuetteEnergy = newTEnergy; harmoincEnergy = tuetteEnergy; //harmonic viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; VertexOutHalfedgeIterator voh(&mesh, vertmp); Point u = vertmp->point(); int id = vertmp->id() - 1; double num = 0.0; for (; !voh.end(); ++voh) { HalfEdge *he1 = *voh; Edge *e = he1->edge(); Vertex *v1 = he1->target(); Point v = v1->point(); std::unordered_map<Edge*,double>::const_iterator got = edgemap.find(e); double K = got->second; deltaPL[id] += (v - u) * K; num = num + 1.0; } deltaPL[id] = deltaPL[id] / num; } //absolute derivatives viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; VertexOutHalfedgeIterator voh(&mesh, vertmp); Point u = vertmp->point(); int id = vertmp->id() - 1; innerProduct = deltaPL[id] * Normal[id]; normalComp[0] = innerProduct * Normal[id][0]; normalComp[1] = innerProduct * Normal[id][1]; normalComp[2] = innerProduct * Normal[id][2]; Point aDerv = deltaPL[id] - normalComp; Point hUpdate = aDerv * stepLength; harmonicPoint[id] =hUpdate; //step 3 } // compute mass center Point mass = { 0.0, 0.0, 0.0 }; viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; mass += vertmp->point(); } mass = mass / 2502; // h update w/ mass viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; int id = vertmp->id() - 1; Normal[id] +=harmonicPoint[id]; Normal[id] -= mass; Normal[id] = Normal[id] / Normal[id].norm(); } //h energy edgeiter.reset(); for (; !edgeiter.end(); ++edgeiter) { Edge *e = *edgeiter; Vertex *s = mesh.edgeVertex1(e); Vertex *t = mesh.edgeVertex2(e); std::unordered_map<Edge*, double>::const_iterator got = edgemap.find(e); double K = got->second; newHEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2()*K; } viter.reset(); //h map update for (; !viter.end(); ++viter) { Vertex *vertmp = *viter; vertmp->point() = Normal[vertmp->id() - 1]; } while (!(fabs(newHEnergy - harmoincEnergy) < eThreshold)) { harmoincEnergy = newHEnergy; newHEnergy = 0.0; //printf("%f\n", harmoincEnergy); viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; VertexOutHalfedgeIterator voh(&mesh, vertmp); Point u = vertmp->point(); int id = vertmp->id() - 1; double num = 0.0; for (; !voh.end(); ++voh) { HalfEdge *he1 = *voh; Edge *e = he1->edge(); Vertex *v1 = he1->target(); Point v = v1->point(); std::unordered_map<Edge*, double>::const_iterator got = edgemap.find(e); double K = got->second; deltaPL[id] += (v - u) * K; num = num + 1.0; } deltaPL[id] = deltaPL[id] / num; } //absolute derivatives viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; VertexOutHalfedgeIterator voh(&mesh, vertmp); Point u = vertmp->point(); int id = vertmp->id() - 1; innerProduct = deltaPL[id] * Normal[id]; normalComp[0] = innerProduct * Normal[id][0]; normalComp[1] = innerProduct * Normal[id][1]; normalComp[2] = innerProduct * Normal[id][2]; Point aDerv = deltaPL[id] - normalComp; Point hUpdate = aDerv * stepLength; harmonicPoint[id] = hUpdate; //step 3 } // compute mass center Point mass = { 0.0, 0.0, 0.0 }; viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; mass += vertmp->point(); } mass = mass / 2502; // h update w/ mass viter.reset(); for (; !viter.end(); ++viter)//step2 { Vertex *vertmp = *viter; int id = vertmp->id() - 1; Normal[id] += harmonicPoint[id]; Normal[id] -= mass; Normal[id] = Normal[id] / Normal[id].norm(); } //h energy edgeiter.reset(); for (; !edgeiter.end(); ++edgeiter) { Edge *e = *edgeiter; Vertex *s = mesh.edgeVertex1(e); Vertex *t = mesh.edgeVertex2(e); std::unordered_map<Edge*, double>::const_iterator got = edgemap.find(e); double K = got->second; newHEnergy += (Normal[s->id() - 1] - Normal[t->id() - 1]).norm2()*K; } viter.reset(); //h map update for (; !viter.end(); ++viter) { Vertex *vertmp = *viter; vertmp->point() = Normal[vertmp->id() - 1]; } } /***conformal****/ // Write out the resultant obj file int vObjID = 1; std::map<int, int> vidToObjID; std::ofstream os(argv[2]); SolidVertexIterator iter(&mesh); for (; !iter.end(); ++iter) { Vertex *v = *iter; Point p = v->point(); os << "v " << p[0] << " " << p[1] << " " << p[2] << std::endl; vidToObjID[v->id()] = vObjID++; } os << "# " << (unsigned int)mesh.numVertices() << " vertices" << std::endl; //texture float u = 0.0, v = 0.0; for (iter.reset(); !iter.end(); ++iter) { Vertex *vv = *iter; std::string key("uv"); std::string s = Trait::getTraitValue(vv->string(), key); if (s.length() > 0) { sscanf(s.c_str(), "%f %f", &u, &v); } os << "vt " << u << " " << v << std::endl; } os << "# " << (unsigned int)mesh.numVertices() << " texture coordinates" << std::endl; SolidFaceIterator fiter(&mesh); for (; !fiter.end(); ++fiter) { Face *f = *fiter; FaceVertexIterator viter(f); os << "f "; for (; !viter.end(); ++viter) { Vertex *v = *viter; os << vidToObjID[v->id()] << "/" << vidToObjID[v->id()] << " "; } os << std::endl; } os.close(); }