diff --git a/Geo/discreteFace.cpp b/Geo/discreteFace.cpp index 0e2b65093e52ae764fc12f1cce40a83dca15d887..e9090f7a6f4d4562f7a4745e8d13ae784489775a 100644 --- a/Geo/discreteFace.cpp +++ b/Geo/discreteFace.cpp @@ -112,7 +112,7 @@ void discreteFace::createGeometry() { checkAndFixOrientation(); - int order = 2; + int order = 1; int nPart = 2; std::vector<triangulation*> part; part.resize(nPart); @@ -125,12 +125,16 @@ void discreteFace::createGeometry() std::vector<triangulation*> toParam; std::vector<MElement*> tem(triangles.begin(),triangles.end()); - triangulation* init = new triangulation(tem,this); + triangulation* init = new triangulation(tem,this); init->my_GEdges = l_edges; toSplit.push(init); - if((toSplit.top())->genus()!=0){ - + int mygen, compteur=1; + Msg::Info("First Genus Value:"); + //std::cin>>mygen; + mygen=1; + if(mygen!=0){//((toSplit.top())->genus()!=0){ + while( !toSplit.empty()){ triangulation* tosplit = toSplit.top(); @@ -140,16 +144,17 @@ void discreteFace::createGeometry() delete tosplit; // #mark for(int i=0; i<nPart; i++){ - if(part[i]->genus()!=0) + Msg::Info("Partition %d Genus:",compteur); + std::cin>>mygen; + if(mygen!=0)//part[i]->genus()!=0) toSplit.push(part[i]); else{ toParam.push_back(part[i]); part[i]->idNum=id++; - // discreteEdges } + compteur++; }// end for i - } - + }// !.empty() }// end if it is not disk-like else{ toParam.push_back(toSplit.top()); @@ -185,6 +190,9 @@ void discreteFace::gatherMeshes() _atlas[i]->getTriangleUV(pc.x(),pc.y(), &mt, xi,eta); if (mt && mt->gf)mt->gf->triangles.push_back(t); else Msg::Warning ("FILE %s LINE %d Triangle has no classification",__FILE__,__LINE__); + + + } _atlas[i]->triangles.clear(); @@ -274,7 +282,6 @@ void discreteFace::checkAndFixOrientation(){ checkLists.push(myInsertion); }// end while - while(!checkList.empty() && !checkLists.empty()){ MElement* current = checkList.front(); checkList.pop(); @@ -301,43 +308,44 @@ void discreteFace::checkAndFixOrientation(){ } // end while } -// should be put in discreteEdge -void splitDiscreteEdge ( discreteEdge *de , MVertex *v , discreteEdge *replacements[2]) { - if (v->onWhat() != de) { - Msg::Fatal ("cannot split a discreteEdge on a point that is NOT classified on it"); - } +// split old GEdge's +void discreteFace::splitDiscreteEdge ( GEdge *de , GVertex *gv, discreteEdge* newE[2]){ MVertex *vstart = de->getBeginVertex()->mesh_vertices[0]; - MVertex *vend = de->getEndVertex()->mesh_vertices[0]; + //MVertex *vend = de->getEndVertex()->mesh_vertices[0]; // We create a new Model vertex and we classify + /* discreteVertex *newV = new discreteVertex (de->model(),NEWPOINT()); newV->mesh_vertices.push_back (v); v->setEntity (newV); - de->model()->add(newV); + de->model()->add(newV);*/ // We create 2 new Model edges and we classify vertices // The creation of discrete edge geometries have already been done (or not) // FIXME !!!!! - discreteEdge *newE[2]; - newE[0] = new discreteEdge (de->model(),NEWLINE(),de->getBeginVertex(),newV); - newE[1] = new discreteEdge (de->model(),NEWLINE(),newV, de->getEndVertex()); + //discreteEdge *newE[2]; + newE[0] = new discreteEdge (de->model(),NEWLINE(),de->getBeginVertex(),gv); + newE[1] = new discreteEdge (de->model(),NEWLINE(),gv, de->getEndVertex()); de->model()->add(newE[0]); de->model()->add(newE[1]); int current = 0; + // assumption: the MLine's are sorted for (unsigned int i=0;i<de->lines.size();i++){ MLine *l = de->lines[i]; newE[current]->lines.push_back(l); - if (l->getVertex(0) != vstart && l->getVertex(0) != v) { + if (l->getVertex(0) != vstart && l->getVertex(0) != gv->mesh_vertices[0]) { l->getVertex(0)->setEntity(newE[current]); newE[current]->mesh_vertices.push_back(l->getVertex(0)); } - if (l->getVertex(1) == vend) current ++; + if (l->getVertex(1) == gv->mesh_vertices[0]) current ++; } + for(int ie=0; ie<2; ie++) newE[ie]->createGeometry(); de->mesh_vertices.clear(); de->lines.clear(); + // We replace de by its 2 parts in every face that is adjacent to de std::list<GFace*> faces = de->faces(); @@ -349,60 +357,28 @@ void splitDiscreteEdge ( discreteEdge *de , MVertex *v , discreteEdge *replaceme std::vector<int> tagEdges; std::list<GEdge*> edges = df->edges(); for (std::list<GEdge*>::iterator it2 = edges.begin(); it2 != edges.end(); ++it2){ - if (*it2 == de){ + GEdge* geit2 = *it2; + if (geit2 == de){ tagEdges.push_back (newE[0]->tag()); tagEdges.push_back (newE[1]->tag()); } - else tagEdges.push_back (de->tag()); + else tagEdges.push_back (geit2->tag()); } - + df->l_edges.clear(); df->setBoundEdges (df->model(), tagEdges); } - else { - Msg::Fatal("this only applies to discrete geometries"); - } + else Msg::Fatal("discreteFace::splitDiscreteEdge \t This only applies to discrete geometries"); } - } -} - -void addInternalBoundaries ( discreteFace *df) { - // create new discreteEdges that split the domain - -} - -/* -void splitDiscreteFace ( discreteFace *df , std::vector<triangulation*> &partition, std::vector<discreteEdge*> &internalBoundaries) { - std::map<MEdge, GEdge*> _dictionnary; - - std::vector<discreteEdge*> allBoundaries = internalBoundaries; - std::list<GEdge*> edges = df->edges(); - allBoundaries.insert(allBoundaries.begin(), edges.begin(), edges.end()); + } + de->model()->remove(de); - for (unsigned int i=0;i<allBoundaries.size();i++){ - for (unsigned int j=0;i<allBoundaries[i]->lines.size();j++){ - MLine *l = allBoundaries[i]->lines[j]; - MEdge e (l->getVertex(0),l->getVertex(1)); - _dictionnary[e] = allBoundaries[i]; - } - } - for (unsigned int i=0;i<partition.size();i++){ - std::set<int> tags; - for (int j=0;j<partition[i]->tri.size();j++){ - for (int k=0;k<3;k++){ - MEdge e = partition[i]->tri[j]->getEdge(k); - std::map<MEdge, GEdge*> :: iterator it = _dictionnary.find(e); - if (it != _dictionnary.end()){ - tags.insert(it->second->tag()); - } - } - } - } } -*/ + void discreteFace::split(triangulation* trian,std::vector<triangulation*> &partition,int nPartitions) { #if defined(HAVE_METIS) + int nVertex = trian->tri.size(); // number of elements int nEdge = trian->ed2tri.size() - trian->borderEdg.size();// number of edges, (without the boundary ones) @@ -448,56 +424,30 @@ void discreteFace::split(triangulation* trian,std::vector<triangulation*> &parti for(int i=0; i<nVertex; i++) elem[part[i]].push_back(trian->tri[i]); + for(int i=0; i<nPartitions; i++) partition[i] = new triangulation(elem[i],this); - for(int i=0; i<nPartitions; i++){// setting GEdge's - //"update" old GEdge's - std::list<GEdge*> upGed = partition[i]->my_GEdges;// old GEdge's list - for(std::list<GEdge*>::iterator cGedg=trian->my_GEdges.begin(); cGedg!=trian->my_GEdges.end(); cGedg++){// GEdge by GEdge - std::set<MVertex*> first, last; - double lc = 0.; - std::vector<MLine*> upMli; - for(unsigned int k=0; k<(*cGedg)->lines.size(); k++){// MLine by MLine (for a GEdge) - MLine* cMli = (*cGedg)->lines[k]; - std::set<MVertex*>::iterator mvit0 = partition[i]->vert.find(cMli->getVertex(0)); - std::set<MVertex*>::iterator mvit1 = partition[i]->vert.find(cMli->getVertex(1)); - if(mvit0 != partition[i]->vert.end() && mvit1 != partition[i]->vert.end()){// check if the MLine belong to this part - - if( first.find(cMli->getVertex(1)) != first.end() ) - first.erase(cMli->getVertex(1)); - else - last.insert(cMli->getVertex(1)); - if( last.find(cMli->getVertex(0)) != last.end() ) - last.erase(cMli->getVertex(0)); - else - first.insert(cMli->getVertex(0)); - upMli.push_back(cMli); - lc += cMli->getLength(); - } - }// end for k - GVertex *v0, *v1; - if(first.empty()){ - v0 = this->model()->addVertex(upMli[0]->getVertex(0)->x(),upMli[0]->getVertex(0)->y(),upMli[0]->getVertex(0)->z(),1.);//#fixme - v1 = v0; - } - else{ - v0 = this->model()->addVertex((*(first.begin()))->x(),(*(first.begin()))->y(),(*(first.begin()))->z(),1.);//#fixme - v1 = this->model()->addVertex((*(last.begin()))->x(),(*(last.begin()))->y(),(*(last.begin()))->z(),1.); - } - upGed.push_back(this->model()->addLine(v0,v1)); - upGed.back()->lines = upMli; - }// end for j + //---- setting topology, i.e. GEdge's and GVertex's ----// + + std::set<MVertex*> todelete; // vertices that do not belong to the GFace anymore + std::set<GEdge*> gGEdges(trian->my_GEdges.begin(),trian->my_GEdges.end()); + for(int i=0; i<nPartitions; i++){ + // create new GEdge's std::set<MEdge,Less_Edge> bordi = partition[i]->borderEdg;// edges defining the border(s) of the i-th new triangulation + + for(int ii=i+1; ii<nPartitions; ii++){// compare to the ii-th ones, with ii > i since ii < i have already been compared + + std::map<MVertex*,MLine*> v02edg;//first vertex of the MLine std::set<MVertex*> first, last; for(std::set<MEdge,Less_Edge>::iterator ie = bordi.begin(); @@ -522,55 +472,119 @@ void discreteFace::split(triangulation* trian,std::vector<triangulation*> &parti }//end for ie - while(!v02edg.empty()){// creation of the GEdge's from new MLine's - - GVertex *v0, *v1; - - while(!first.empty()){// starting with nonloop GEdge's - - std::vector<MLine*> myLines;// MLine's of the current nonloop GEdge - std::set<MVertex*>::iterator itf = first.begin(); - MVertex* cv0 = *itf;// starting with a first vertex - while(last.find(cv0) != last.end()){// until reaching the corresponding last vertex - myLines.push_back(v02edg[cv0]);// push the correspong MLine - v02edg.erase(cv0);// and erasing it from the "list" - cv0 = myLines.back()->getVertex(1);// next vertex - } - - v0 = this->model()->addVertex((*itf)->x(),myLines[0]->getVertex(0)->y(),myLines[0]->getVertex(0)->z(),1.); - v1 = this->model()->addVertex(cv0->x(),cv0->y(),cv0->z(),1.); - - GEdge* toadd = this->model()->addLine(v0,v1);// new GEdge - toadd->lines = myLines;// associated MLine's + //---- creation of the GEdge's from new MLine's ----// + + while(!first.empty()){// starting with nonloop GEdge's + + GVertex *v[2]; + + std::vector<MLine*> myLines;// MLine's of the current nonloop GEdge + std::set<MVertex*>::iterator itf = first.begin(); + MVertex* cv0 = *itf;// starting with a first vertex + while(last.find(cv0) == last.end()){// until reaching the corresponding last vertex + myLines.push_back(v02edg[cv0]);// push the correspong MLine + v02edg.erase(cv0);// and erasing it from the "list" + cv0 = myLines.back()->getVertex(1);// next vertex + }// end last + + std::vector<MVertex*> mvt; + mvt.resize(2); + mvt[0] = *itf; + mvt[1] = cv0; + + for(int imvt=0; imvt<2; imvt++){ + + std::set<GEdge*>::iterator oe=gGEdges.begin(); + while(mvt[imvt]->onWhat() != *oe) + ++oe; + + if (oe == gGEdges.end()) Msg::Error("discreteFace::split \t This Vertex is not on a GEdge !"); + GEdge* onit = *oe; + if(mvt[imvt] == onit->getBeginVertex()->mesh_vertices[0]) + v[imvt] = onit->getBeginVertex(); + else if (mvt[imvt] == onit->getEndVertex()->mesh_vertices[0]) + v[imvt] = onit->getEndVertex(); + else{ + v[imvt] = new discreteVertex (this->model(),NEWPOINT()); + v[imvt]->mesh_vertices.push_back(mvt[imvt]); + mvt[imvt]->setEntity(v[imvt]); + this->model()->add(v[imvt]); + discreteEdge* de[2]; + gGEdges.erase(onit); + splitDiscreteEdge(onit,v[imvt],de); + gGEdges.insert(de[0]); + gGEdges.insert(de[1]); + }// end else + + }// end imvt + + discreteEdge* internalE = new discreteEdge (this->model(),NEWLINE(),v[0],v[1]); + this->model()->add(internalE);// new GEdge + internalE->lines = myLines;// associated MLine's + for(unsigned int iml=1; iml<myLines.size(); iml++){//not the first vertex of the GEdge (neither the last one) + myLines[iml]->getVertex(0)->setEntity(internalE); + internalE->mesh_vertices.push_back(myLines[iml]->getVertex(0)); + todelete.insert(myLines[iml]->getVertex(0)); + } + internalE->createGeometry(); + partition[i]->my_GEdges.push_back(internalE); + partition[ii]->my_GEdges.push_back(internalE); + + first.erase(itf);// next first vertex of a nonloop GEdge + }//end while first.empty() + + for(std::set<GEdge*>::iterator le=gGEdges.begin(); le!=gGEdges.end(); ++le){ + GEdge* ile = *le; + MEdge edTest = ile->lines.front()->getEdge(0); + if(bordi.find(edTest)!=bordi.end()) + partition[i]->my_GEdges.push_back(ile); + else + partition[ii]->my_GEdges.push_back(ile); + } - partition[i]->my_GEdges.push_back(toadd); - partition[ii]->my_GEdges.push_back(toadd); + while(!v02edg.empty()){// remaining MLines for 'loop'GEdge's - first.erase(itf);// next first vertex of a nonloop GEdge - }//end while first.empty() + discreteVertex* v; + std::vector<MLine*> my_MLines; - std::vector<MLine*> my_MLines;// remaining MLines for 'loop'GEdge's MVertex* cv0 = v02edg.begin()->first; while(v02edg.find(cv0) != v02edg.end()){// a loop GEdge my_MLines.push_back(v02edg[cv0]);// current MLine of the loop v02edg.erase(cv0);// update the container cv0 = my_MLines.back()->getVertex(1);// next MLine of the loop } - - v0 = this->model()->addVertex(cv0->x(),cv0->y(),cv0->z(),1.); - v1 = v0; - - GEdge* to_add = this->model()->addLine(v0,v1); - to_add->lines = my_MLines; - - partition[i]->my_GEdges.push_back(to_add); - partition[ii]->my_GEdges.push_back(to_add); - + + v = new discreteVertex (this->model(),NEWPOINT()); + v->mesh_vertices.push_back(cv0); + cv0->setEntity(v); + this->model()->add(v); + todelete.insert(cv0); + + discreteEdge* gloop = new discreteEdge (this->model(),NEWLINE(),v,v); + this->model()->add(gloop); + gloop->lines = my_MLines; + for(unsigned int iml=1; iml<my_MLines.size(); iml++){//not the first vertex of the GEdge (neither the last one) + my_MLines[iml]->getVertex(0)->setEntity(gloop); + gloop->mesh_vertices.push_back(my_MLines[iml]->getVertex(0)); + todelete.insert(my_MLines[iml]->getVertex(0)); + } + gloop->createGeometry(); + partition[i]->my_GEdges.push_back(gloop); + partition[ii]->my_GEdges.push_back(gloop); }// end while v02edg.empty() - + }//end for ii - + }// end for i + + std::vector<MVertex*> newMV; + for(unsigned int imv=0; imv<this->mesh_vertices.size(); imv++){ + MVertex* current = mesh_vertices[imv]; + std::set<MVertex*>::iterator itmv = todelete.find(current); + if (itmv==todelete.end()) newMV.push_back(current); + } + this->mesh_vertices.clear(); + this->mesh_vertices = newMV; #endif } diff --git a/Geo/discreteFace.h b/Geo/discreteFace.h index 5b7071fdd33c34a12a7e19d86794fa4e0e848c35..3d9e0ff4869aacd7044b55a53dfbf72e3d951526 100644 --- a/Geo/discreteFace.h +++ b/Geo/discreteFace.h @@ -31,6 +31,8 @@ class discreteFace : public GFace { discreteFace(GModel *model, int num); virtual ~discreteFace() {} void checkAndFixOrientation(); + void splitDiscreteEdge(GEdge*,GVertex*,discreteEdge*[2]); + void splitDiscreteFace(discreteFace*,std::vector<triangulation*>&,std::vector<GEdge*>&); void split(triangulation*,std::vector<triangulation*>&,int); GPoint point(double par1, double par2) const; SPoint2 parFromPoint(const SPoint3 &p, bool onSurface=true) const;