static double LC_MVertex_CURV(GEntity *ge, double U, double V) { double Crv = 0; switch(ge->dim()){ case 0: Crv = max_edge_curvature((const GVertex *)ge); //Crv = std::max(max_surf_curvature_vertex((const GVertex *)ge), Crv); // Crv = max_surf_curvature((const GVertex *)ge); break; case 1: { GEdge *ged = (GEdge *)ge; Crv = ged->curvature(U); Crv = std::max(Crv, max_surf_curvature(ged, U)); // Crv = max_surf_curvature(ged, U); } break; case 2: { GFace *gf = (GFace *)ge; Crv = gf->curvature(SPoint2(U, V)); } break; } double lc = Crv > 0 ? 2 * M_PI / Crv / CTX::instance()->mesh.minCircPoints : MAX_LC; return lc; }
// compute the mesh size at a given vertex due to prescribed sizes at // mesh vertices static double LC_MVertex_PNTS(GEntity *ge, double U, double V) { switch(ge->dim()){ case 0: { GVertex *gv = (GVertex *)ge; double lc = gv->prescribedMeshSizeAtVertex(); // FIXME we might want to remove this to make all lc treatment consistent if(lc >= MAX_LC) return CTX::instance()->lc / 10.; return lc; } case 1: { GEdge *ged = (GEdge *)ge; GVertex *v1 = ged->getBeginVertex(); GVertex *v2 = ged->getEndVertex(); if (v1 && v2){ Range<double> range = ged->parBounds(0); double a = (U - range.low()) / (range.high() - range.low()); double lc = (1 - a) * v1->prescribedMeshSizeAtVertex() + (a) * v2->prescribedMeshSizeAtVertex() ; // FIXME we might want to remove this to make all lc treatment consistent if(lc >= MAX_LC) return CTX::instance()->lc / 10.; return lc; } else return MAX_LC; } default: return MAX_LC; } }
GEdgeLoop::GEdgeLoop(const std::list<GEdge*> &cwire) { // Sometimes OCC puts a nasty degenerated edge in the middle of the // wire ... pushing it to front fixes the problem as it concerns // gmsh std::list<GEdge*> wire; std::vector<GEdge*> degenerated; GEdge *degeneratedToInsert = 0; for (std::list<GEdge*>::const_iterator it = cwire.begin(); it != cwire.end(); ++it){ GEdge *ed = *it; if (ed->degenerate(0))degenerated.push_back(ed); else wire.push_back(ed); } if (degenerated.size() == 1){ wire.push_front(degenerated[0]); } else if (degenerated.size() == 2){ degeneratedToInsert = degenerated[1]; wire.push_front(degenerated[0]); } else if (degenerated.size() > 2){ Msg::Error("More than two degenerated edges in one model face"); } while (!wire.empty()){ // printf("wire.size = %d\n",wire.size()); loopTheLoop(wire,loop,°eneratedToInsert); // break; } }
GEdge *GNode< Point >::Search( Long n, Long i ) const { GEdge *p; for (p=adjacents; p != NULL; p=p->Next()) if (( p->Item() == i) && (p->Node() == n)) break; return p; }
/** * Destructor for node - removes edge controls on incidient edges and disconnects item from scene */ GNode::~GNode() { graph()->invalidateRanking(); if ( ( isEdgeControl() || isEdgeLabel()) && isNotNullP( firstPred()) && isNotNullP( firstSucc()) && isNotNullP( firstPred()->pred()) && isNotNullP( firstSucc()->succ())) { GRAPH_ASSERTD( areEqP( firstPred()->style(), firstSucc()->style()), "Different styles on the same edge"); GEdge *e = graph()->newEdge( firstPred()->pred(), firstSucc()->succ()); e->setStyle( firstPred()->style()); } else if ( isSimple()) { QList< GNode *> nodes; GEdge* edge; Marker m = graph()->newMarker(); for ( edge = firstSucc(); isNotNullP( edge); edge = edge->nextSucc()) { edge->item()->adjust(); GNode* succ = edge->succ(); while ( succ->isEdgeControl() || succ->isEdgeLabel()) { assert( isNotNullP( succ->firstSucc())); if ( succ->mark( m)) { nodes << succ; } succ = succ->firstSucc()->succ(); } } for ( edge = firstPred(); isNotNullP( edge); edge = edge->nextPred()) { if ( edge->isSelf()) // We've already processed this one in previous loop continue; edge->item()->adjust(); GNode* pred = edge->pred(); while ( pred->isEdgeControl() || pred->isEdgeLabel()) { assert( isNotNullP( pred->firstPred())); if ( pred->mark( m)) { nodes << pred; } pred = pred->firstPred()->pred(); } } foreach ( GNode *n, nodes) { graph()->deleteNode( n); } graph()->freeMarker( m); }
/** * Change edge's style */ void GGraph::setEdgeStyle( GStyle *style) { if ( sel_edges.isEmpty()) return; GEdge* edge = sel_edges.first(); edge->setStyle( style); edge->item()->adjust(); }
GEdge * Graph::getEdge(long firstNode, long secondNode){ GEdge *p = tnode[firstNode]->getIncidentEdges(); while(p){ if (p->IncidentNode() == secondNode) return p; else p=p->Next(); } return NULL; }
bool reparamMeshVertexOnFace(MVertex *v, const GFace *gf, SPoint2 ¶m, bool onSurface) { if (gf->geomType() == GEntity::CompoundSurface ){ GFaceCompound *gfc = (GFaceCompound*) gf; param = gfc->parFromVertex(v); return true; } if(v->onWhat()->geomType() == GEntity::DiscreteCurve || v->onWhat()->geomType() == GEntity::BoundaryLayerCurve){ param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface); return true; } if(v->onWhat()->dim() == 0){ GVertex *gv = (GVertex*)v->onWhat(); // hack for bug in periodic curves if (gv->getNativeType() == GEntity::GmshModel && gf->geomType() == GEntity::Plane) param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface); else param = gv->reparamOnFace(gf, 1); // shout, we could be on a seam std::list<GEdge*> ed = gv->edges(); for(std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); it++) if((*it)->isSeam(gf)) return false; } else if(v->onWhat()->dim() == 1){ GEdge *ge = (GEdge*)v->onWhat(); double t; v->getParameter(0, t); param = ge->reparamOnFace(gf, t, 1); if(!v->getParameter(0,t)) { Msg::Error("Vertex %p not MEdgeVertex", v); return false; //param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface); } // shout, we are on a seam if(ge->isSeam(gf)) return false; } else{ double uu, vv; if(v->onWhat() == gf && v->getParameter(0, uu) && v->getParameter(1, vv)){ param = SPoint2(uu, vv); } else { // brute force! param = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()), onSurface); } } return true; }
double distanceToGeometry(GModel *gm, int dim, int tag, int distType, double tol, int meshDiscr, int geomDiscr) { double maxDist = 0.; if (dim == 2) { GEdge *ge = gm->getEdgeByTag(tag); if (ge->geomType() == GEntity::Line) return 0.; for (unsigned int i = 0; i < ge->lines.size(); i++) { double dist; switch (distType) { case CADDIST_TAYLOR: dist = taylorDistanceEdge(ge->lines[i], ge); break; case CADDIST_FRECHET: dist = discreteFrechetDistanceEdge(ge->lines[i], ge, tol, meshDiscr, geomDiscr); break; case CADDIST_HAUSFAST: dist = discreteHausdorffDistanceFastEdge(ge->lines[i], ge, tol, meshDiscr, geomDiscr); break; case CADDIST_HAUSBRUTE: dist = discreteHausdorffDistanceBruteEdge(ge->lines[i], ge, tol, meshDiscr, geomDiscr); break; default: Msg::Error("Wrong CAD distance type in distanceToGeometry"); return -1.; break; } maxDist = std::max(dist, maxDist); } } else if (dim == 3) { if (distType == CADDIST_TAYLOR) { GFace *gf = gm->getFaceByTag(tag); if (gf->geomType() == GEntity::Plane) return 0.; for (unsigned int i = 0; i < gf->triangles.size(); i++) maxDist = std::max(taylorDistanceFace(gf->triangles[i], gf), maxDist); for (unsigned int i = 0; i < gf->quadrangles.size(); i++) maxDist = std::max(taylorDistanceFace(gf->quadrangles[i], gf), maxDist); } else { Msg::Error("CAD distance type %i not implemented for surfaces", distType); return -1.; } } else { Msg::Error("CAD distance cannot be computed for dimension %i", dim); return -1.; } return maxDist; }
GEdgeSigned nextOne(GEdgeSigned *thisOne, std::list<GEdge*> &wire) { if(!thisOne){ GEdge *ge = *(wire.begin()); wire.erase(wire.begin()); return GEdgeSigned(1, ge); } GVertex *gv = thisOne->getEndVertex(); std::list<GEdge*> possibleChoices; std::list<GEdge*>::iterator it = wire.begin(); std::list<GEdge*>::iterator ite = wire.end(); while(it != ite){ GEdge *ge = *it; GVertex *v1 = ge->getBeginVertex(); GVertex *v2 = ge->getEndVertex(); if(v1 == gv || v2 == gv) possibleChoices.push_back(ge); ++it; } it = possibleChoices.begin(); ite = possibleChoices.end(); while(it != ite){ GEdge *ge = *it; if(countInList(possibleChoices, ge) == 2){ wire.erase(std::remove_if(wire.begin(), wire.end(), std::bind2nd(std::equal_to<GEdge*>(), ge)), wire.end()); wire.push_back(ge); GVertex *v1 = ge->getBeginVertex(); GVertex *v2 = ge->getEndVertex(); if(v1 == gv) return GEdgeSigned(1, ge); if(v2 == gv) return GEdgeSigned(-1, ge); Msg::Error("Something wrong in edge loop 1"); thisOne->print(); } ++it; } it = possibleChoices.begin(); ite = possibleChoices.end(); while(it != ite){ GEdge *ge = *it; if(ge != thisOne->ge){ wire.erase(std::remove_if(wire.begin(),wire.end(), std::bind2nd(std::equal_to<GEdge*>(), ge)), wire.end()); GVertex *v1 = ge->getBeginVertex(); GVertex *v2 = ge->getEndVertex(); if(v1 == gv) return GEdgeSigned(1, ge); if(v2 == gv) return GEdgeSigned(-1, ge); Msg::Error("Something wrong in edge loop 2"); thisOne->print(); } ++it; } // should never end up here return GEdgeSigned(0, 0); }
void Centerline::importFile(std::string fileName) { current = GModel::current(); std::vector<GFace*> currentFaces(current->firstFace(), current->lastFace()); for (unsigned int i = 0; i < currentFaces.size(); i++){ GFace *gf = currentFaces[i]; if (gf->geomType() == GEntity::DiscreteSurface){ for(unsigned int j = 0; j < gf->triangles.size(); j++) triangles.push_back(gf->triangles[j]); if (is_cut){ gf->triangles.clear(); gf->deleteVertexArrays(); current->remove(gf); } } } if(triangles.empty()){ Msg::Error("Current GModel has no triangles ..."); return; } mod = new GModel(); mod->load(fileName); mod->removeDuplicateMeshVertices(1.e-8); current->setAsCurrent(); current->setVisibility(1); int maxN = 0.0; std::vector<GEdge*> modEdges(mod->firstEdge(), mod->lastEdge()); MVertex *vin = modEdges[0]->lines[0]->getVertex(0); ptin = SPoint3(vin->x(), vin->y(), vin->z()); for (unsigned int i = 0; i < modEdges.size(); i++){ GEdge *ge = modEdges[i]; for(unsigned int j = 0; j < ge->lines.size(); j++){ MLine *l = ge->lines[j]; MVertex *v0 = l->getVertex(0); MVertex *v1 = l->getVertex(1); std::map<MVertex*, int>::iterator it0 = colorp.find(v0); std::map<MVertex*, int>::iterator it1 = colorp.find(v1); if (it0 == colorp.end() || it1 == colorp.end()){ lines.push_back(l); colorl.insert(std::make_pair(l, ge->tag())); maxN = std::max(maxN, ge->tag()); } if (it0 == colorp.end()) colorp.insert(std::make_pair(v0, ge->tag())); if (it1 == colorp.end()) colorp.insert(std::make_pair(v1, ge->tag())); } } createBranches(maxN); }
/* * Removes the node `n' in graph. * -> Removes all refences in its * neighbourhood nodes. */ Errc Graph3d::Del( Long n ) { GEdge *p; if (!tnode[n]) return FAILURE; for (p=tnode[n]->Neighbours(); p!=NULL;p=p->Next()){ tnode[p->Node()]->Del(n); } delete tnode[n]; tnode[n]=NULL; return SUCCESS; }
void Centerline::createSplitCompounds() { //number of discrete vertices, edges, faces and regions for the mesh NV = current->getMaxElementaryNumber(0); NE = current->getMaxElementaryNumber(1); NF = current->getMaxElementaryNumber(2); NR = current->getMaxElementaryNumber(3); // Remesh new faces (Compound Lines and Compound Surfaces) Msg::Info("Centerline: creating split compounds ..."); //Parametrize Compound Lines for (int i=0; i < NE; i++){ std::vector<GEdge*>e_compound; GEdge *pe = current->getEdgeByTag(i+1);//current edge e_compound.push_back(pe); int num_gec = NE+i+1; Msg::Info("Create Compound Line (%d) = %d discrete edge", num_gec, pe->tag()); GEdge *gec = current->addCompoundEdge(e_compound,num_gec); if (CTX::instance()->mesh.algo2d != ALGO_2D_BAMG){ gec->meshAttributes.method = MESH_TRANSFINITE; gec->meshAttributes.nbPointsTransfinite = nbPoints+1; gec->meshAttributes.typeTransfinite = 0; gec->meshAttributes.coeffTransfinite = 1.0; } } // Parametrize Compound surfaces std::list<GEdge*> U0; for (int i=0; i < NF; i++){ std::vector<GFace*> f_compound; GFace *pf = current->getFaceByTag(i+1);//current face f_compound.push_back(pf); int num_gfc = NF+i+1; Msg::Info("Create Compound Surface (%d) = %d discrete face", num_gfc, pf->tag()); //1=conf_spectral 4=convex_circle, 7=conf_fe GFace *gfc = current->addCompoundFace(f_compound, 7, 0, num_gfc); gfc->meshAttributes.recombine = recombine; gfc->addPhysicalEntity(1); current->setPhysicalName("wall", 2, 1);//tag 1 } }
/* * Creates a copy of graph g. */ Graph3d &Graph3d::operator=( const Graph3d &g ) { Long i; GEdge *l; New(g.size,g.ndep,g.nrow,g.ncol); for (i=0; i<size; i++){ if (g[i] != NULL){ Add(i,g[i]->Item(),g[i]->seed); tnode[i]->value=g[i]->value; for (l=g[i]->Neighbours(); l!=NULL; l=l->Next()){ if (i>l->Node()) Link(i,l->Node(),l->Item(),l->weight); } } } return *this; }
static double _relocateVertex(GFace *gf, MVertex *ver, const std::vector<MElement *> <, double tol) { if(ver->onWhat()->dim() != 2) return 2.0; SPoint2 p1(0, 0); SPoint2 p2; if(ver->getParameter(0, p2[0])) { ver->getParameter(1, p2[1]); } else { return _relocateVertex2(gf, ver, lt, tol); } std::size_t counter = 0; for(std::size_t i = 0; i < lt.size(); i++) { for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) { MVertex *v = lt[i]->getVertex(j); SPoint2 pp; reparamMeshVertexOnFace(v, gf, pp); counter++; if(v->onWhat()->dim() == 1) { GEdge *ge = dynamic_cast<GEdge *>(v->onWhat()); // do not take any chance if(ge->isSeam(gf)) return 2.0; } p1 += pp; } } p1 *= 1. / (double)counter; double worst; double xi = Maximize_Quality_Golden_Section(ver, gf, p1, p2, lt, tol, worst); // if (xi != 0) printf("xi = %g\n",xi); SPoint2 p = p1 * (1 - xi) + p2 * xi; GPoint pp = gf->point(p); if(!pp.succeeded()) return 2.0; ver->x() = pp.x(); ver->y() = pp.y(); ver->z() = pp.z(); ver->setParameter(0, pp.u()); ver->setParameter(1, pp.v()); return worst; }
GEdge *GNode::UnConnect( long incidentNode ) { GEdge *p = getIncidentEdges(); GEdge *q; if (!p) return NULL; if(p->IncidentNode() == incidentNode){ adjacents = p->Next(); delete p; } return adjacents; while (p->Next()) { if(p->Next()->IncidentNode() == incidentNode){ q = p->Next(); p->Next(q->Next()); delete q; }else p = p->Next(); } return adjacents; }
static void getAllParameters(MVertex *v, GFace *gf, std::vector<SPoint2> ¶ms) { params.clear(); if (gf->geomType() == GEntity::CompoundSurface ){ GFaceCompound *gfc = (GFaceCompound*) gf; params.push_back(gfc->parFromVertex(v)); return; } if(v->onWhat()->dim() == 0){ GVertex *gv = (GVertex*)v->onWhat(); std::list<GEdge*> ed = gv->edges(); bool seam = false; for(std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); it++){ if((*it)->isSeam(gf)) { Range<double> range = (*it)->parBounds(0); if (gv == (*it)->getBeginVertex()){ params.push_back((*it)->reparamOnFace(gf, range.low(),-1)); params.push_back((*it)->reparamOnFace(gf, range.low(), 1)); } if (gv == (*it)->getEndVertex()){ params.push_back((*it)->reparamOnFace(gf, range.high(),-1)); params.push_back((*it)->reparamOnFace(gf, range.high(), 1)); } if (gv != (*it)->getBeginVertex() && gv != (*it)->getEndVertex()){ Msg::Warning("Strange!"); } seam = true; } } if (!seam) params.push_back(gv->reparamOnFace(gf, 1)); } else if(v->onWhat()->dim() == 1){ GEdge *ge = (GEdge*)v->onWhat(); if(!ge->haveParametrization()) return; double UU; v->getParameter(0, UU); if (UU == 0.0) UU = ge->parFromPoint(v->point()); params.push_back(ge->reparamOnFace(gf, UU, 1)); if(ge->isSeam(gf)) params.push_back(ge->reparamOnFace(gf, UU, -1)); } else{ double UU, VV; if(v->onWhat() == gf && v->getParameter(0, UU) && v->getParameter(1, VV)) params.push_back(SPoint2(UU, VV)); } }
GEdge *GNode< Point >::Del( Long n ) { GEdge *p = Neighbours(); GEdge *q; if (!p) return NULL; while (p && ( p->Node() == n )) { etrash.push_back(p); p = p->Next(); adjacents = p; } for ( q=p; q != NULL ; q=q->Next() ) { if ( q->Node() == n ) { p->Next(q->Next()); etrash.push_back(q); // delete(q); // Problem when using Neighbours() list: cannot delete } else p=q; } return adjacents; }
void Mesh::approximationErrorAndGradients(int iEl, double &f, std::vector<double> &gradF, double eps, simpleFunction<double> &fct) { std::vector<SPoint3> _xyz_temp; for (int iV = 0; iV < nVert(); iV++){ _xyz_temp.push_back(SPoint3( _vert[iV]->x(), _vert[iV]->y(), _vert[iV]->z())); _vert[iV]->setXYZ(_xyz[iV].x(),_xyz[iV].y(),_xyz[iV].z()); } MElement *element = _el[iEl]; f = approximationError (fct, element); // FIME // if (iEl < 1)printf("approx error elem %d = %g\n",iEl,f); int currentId = 0; // compute the size of the gradient // depends on how many dofs exist per vertex (0,1,2 or 3) for (size_t i = 0; i < element->getNumVertices(); ++i) { if (_el2FV[iEl][i] >= 0) {// some free coordinates currentId += _nPCFV[_el2FV[iEl][i]]; } } gradF.clear(); gradF.resize(currentId, 0.); currentId = 0; for (size_t i = 0; i < element->getNumVertices(); ++i) { if (_el2FV[iEl][i] >= 0) {// some free coordinates MVertex *v = element->getVertex(i); // vertex classified on a model edge if (_nPCFV[_el2FV[iEl][i]] == 1){ double t = _uvw[_el2FV[iEl][i]].x(); GEdge *ge = (GEdge*)v->onWhat(); SPoint3 p (v->x(),v->y(),v->z()); GPoint d = ge->point(t+eps); v->setXYZ(d.x(),d.y(),d.z()); double f_d = approximationError (fct, element); gradF[currentId++] = (f_d-f)/eps; if (iEl < 1)printf("df = %g\n",(f_d-f)/eps); v->setXYZ(p.x(),p.y(),p.z()); } else if (_nPCFV[_el2FV[iEl][i]] == 2){ double uu = _uvw[_el2FV[iEl][i]].x(); double vv = _uvw[_el2FV[iEl][i]].y(); GFace *gf = (GFace*)v->onWhat(); SPoint3 p (v->x(),v->y(),v->z()); GPoint d = gf->point(uu+eps,vv); v->setXYZ(d.x(),d.y(),d.z()); double f_u = approximationError (fct, element); gradF[currentId++] = (f_u-f)/eps; d = gf->point(uu,vv+eps); v->setXYZ(d.x(),d.y(),d.z()); double f_v = approximationError (fct, element); gradF[currentId++] = (f_v-f)/eps; v->setXYZ(p.x(),p.y(),p.z()); // if (iEl < 1)printf("df = %g %g\n",(f_u-f)/eps,(f_v-f)/eps); } } } for (int iV = 0; iV < nVert(); iV++) _vert[iV]->setXYZ(_xyz_temp[iV].x(),_xyz_temp[iV].y(),_xyz_temp[iV].z()); }
void TestParser::parseLine( QString line) { QString n_str("Node "); QString e_str("Edge "); /** Node recognition */ QRegExp node_rx("CF ?(Enter)? ?(\\w*) Node (\\d+)"); /** Edge recognition */ QRegExp edge_rx("CF EDGE (\\d+) \\[(\\d+)->(\\d+)\\]"); QTextStream stream( stdout); /** Expression recognition */ int pos = 0; if ( edge_rx.indexIn( line) != -1) { QString name = e_str.append( edge_rx.cap(1)); QString pred_name("Node "); pred_name.append( edge_rx.cap( 2)); QString succ_name("Node "); succ_name.append( edge_rx.cap( 3)); /** Back edge */ QRegExp back_rx("Back"); /** Add edge to symtab */ if ( symtab.find( name) == symtab.end() && symtab.find( pred_name) != symtab.end() && symtab.find( succ_name) != symtab.end()) { SymEdge *edge = new SymEdge( name); edge->setPred( pred_name); edge->setSucc( succ_name); symtab[ name] = edge; /** Add edge to graph */ GNode* pred = static_cast< SymNode *>( symtab[ pred_name])->node(); GNode* succ = static_cast< SymNode *>( symtab[ succ_name])->node(); GEdge* e = graph->graph()->newEdge( pred, succ); #ifdef _DEBUG //stream << name << ": " << pred_name << "->" << succ_name << endl; #endif if ( back_rx.indexIn( line) != -1 && !e->isSelf()) { GNode* label = e->insertLabelNode( QPointF( 0,0)); label->item()->setPlainText( "Back"); } } } else if ( node_rx.indexIn( line) != -1 ) { bool good_id = false; int ir_id = node_rx.cap(3).toInt( &good_id); QString text = QString("Node ").append( node_rx.cap(3)); QString name = n_str.append( node_rx.cap(3)); if ( !node_rx.cap( 1).isEmpty()) { text.append("\n").append( node_rx.cap(1)); } if ( !node_rx.cap( 2).isEmpty()) { text.append("\n").append( node_rx.cap(2)); } /** Add node to symtab */ if ( symtab.find( name ) == symtab.end()) { SymNode* node = new SymNode( name); curr_node = static_cast<CFNode *>( graph->graph()->newNode()); curr_node->setDoc( new QTextDocument()); node->setNode( curr_node); node->node()->item()->setPlainText( text); if ( good_id) { node->node()->setIRId( ir_id); } symtab[ name] = node; #ifdef _DEBUG //stream << name << endl; #endif } } else { if ( !isStateNode()) setStateDefault(); } if ( isStateNode()) { node_text.append( line).append( "\n"); } }
bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gradObj) { // set the mesh to its present position std::vector<SPoint3> xyz,uvw; mesh.getGEntityPositions(xyz,uvw); mesh.updateGEntityPositions(); //could be better (e.g. store the model in the Mesh:: datastrucure) GModel *gm = GModel::current(); // for all model edges, compute the error between the geometry and the mesh maxDistCAD = 0.0; double distCAD = 0.0; for (GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it){ // do not do straight lines if ((*it)->geomType() == GEntity::Line)continue; // look at all mesh lines std::vector<bool> doWeCompute((*it)->lines.size()); for (unsigned int i=0;i<(*it)->lines.size(); i++){ doWeCompute[i] = false; for (unsigned int j=0;j<(*it)->lines[i]->getNumVertices(); j++){ int index = mesh.getFreeVertexStartIndex((*it)->lines[i]->getVertex(j)); if (index >=0){ doWeCompute[i] = true; continue; } } } std::vector<double> dist((*it)->lines.size()); for (unsigned int i=0;i<(*it)->lines.size(); i++){ if (doWeCompute[i]){ // compute the distance from the geometry to the mesh dist[i] = MLineGEdgeDistance ( (*it)->lines[i] , *it ); maxDistCAD = std::max(maxDistCAD,dist[i]); distCAD += dist [i] * factor; } } // be clever to compute the derivative : iterate on all // Distance = \sum_{lines} Distance (line, GEdge) // For a high order vertex, we compute the derivative only by // recomputing the distance to one only line const double eps = 1.e-6; for (unsigned int i=0;i<(*it)->lines.size(); i++){ if (doWeCompute[i]){ for (int j=2 ; j<(*it)->lines[i]->getNumVertices() ; j++){ MVertex *v = (*it)->lines[i]->getVertex(j); int index = mesh.getFreeVertexStartIndex(v); // printf("%d %d (%d %d)\n",v->getNum(),index,v->onWhat()->tag(),v->onWhat()->dim()); if (index >= 0){ double t; v->getParameter(0,t); SPoint3 pp (v->x(),v->y(),v->z()); GPoint gp = (*it)->point(t+eps); v->setParameter(0,t+eps); v->setXYZ(gp.x(),gp.y(),gp.z()); double dist2 = MLineGEdgeDistance ( (*it)->lines[i] , *it ); double deriv = (dist2 - dist[i])/eps; v->setXYZ(pp.x(),pp.y(),pp.z()); v->setParameter(0,t); // printf("%g %g %g\n",dist[i],dist2, MLineGEdgeDistance ( (*it)->lines[i] , *it )); // get the index of the vertex gradObj[index] += deriv * factor; } } } // printf("done\n"); // For a low order vertex classified on the GEdge, we recompute // two distances for the two MLines connected to the vertex for (unsigned int i=0;i<(*it)->lines.size()-1; i++){ MVertex *v = (*it)->lines[i]->getVertex(1); int index = mesh.getFreeVertexStartIndex(v); if (index >= 0){ double t; v->getParameter(0,t); SPoint3 pp (v->x(),v->y(),v->z()); GPoint gp = (*it)->point(t+eps); v->setParameter(0,t+eps); v->setXYZ(gp.x(),gp.y(),gp.z()); MLine *l1 = (*it)->lines[i]; MLine *l2 = (*it)->lines[i+1]; // printf("%d %d -- %d %d\n",l1->getVertex(0)->getNum(),l1->getVertex(1)->getNum(),l2->getVertex(0)->getNum(),l2->getVertex(1)->getNum()); double deriv = (MLineGEdgeDistance ( l1 , *it ) - dist[i]) /eps + (MLineGEdgeDistance ( l2 , *it ) - dist[i+1])/eps; v->setXYZ(pp.x(),pp.y(),pp.z()); v->setParameter(0,t); gradObj[index] += deriv * factor; } } } } // printf("computing distance : 1D part %12.5E\n",distCAD); // now the 3D part ! std::vector<std::vector<SVector3> > gsfT; computeGradSFAtNodes ( (*gm->firstFace())->triangles[0],gsfT); std::map<MVertex*,SVector3> normalsToCAD; for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){ // do not do plane surfaces if ((*it)->geomType() == GEntity::Plane)continue; std::map<MTriangle*,double> dist; std::vector<bool> doWeCompute((*it)->triangles.size()); for (unsigned int i=0;i<(*it)->triangles.size(); i++){ doWeCompute[i] = false; for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){ int index = mesh.getFreeVertexStartIndex((*it)->triangles[i]->getVertex(j)); if (index >=0){ doWeCompute[i] = true; } } if (doWeCompute[i]){ for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){ MVertex *v = (*it)->triangles[i]->getVertex(j); if (normalsToCAD.find(v) == normalsToCAD.end()){ SPoint2 p_cad; reparamMeshVertexOnFace(v, *it, p_cad); SVector3 tg_cad = (*it)->normal(p_cad); tg_cad.normalize(); normalsToCAD[v] = tg_cad; } } } } for (unsigned int i=0;i<(*it)->triangles.size(); i++){ // compute the distance from the geometry to the mesh if(doWeCompute[i]){ const double d = MFaceGFaceDistanceOld((*it)->triangles[i], *it, &gsfT, &normalsToCAD); dist[(*it)->triangles[i]] = d; maxDistCAD = std::max(maxDistCAD,d); distCAD += d * factor; } } // be clever again to compute the derivatives const double eps = 1.e-6; for (unsigned int i=0;i<(*it)->triangles.size(); i++){ if(doWeCompute[i]){ for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){ // for (; itm !=v2t.end(); ++itm){ MVertex *v = (*it)->triangles[i]->getVertex(j); if(v->onWhat()->dim() == 1){ int index = mesh.getFreeVertexStartIndex(v); if (index >= 0){ MTriangle *t = (*it)->triangles[i]; GEdge *ge = v->onWhat()->cast2Edge(); double t_; v->getParameter(0,t_); SPoint3 pp (v->x(),v->y(),v->z()); GPoint gp = ge->point(t_+eps); v->setParameter(0,t_+eps); v->setXYZ(gp.x(),gp.y(),gp.z()); const double distT = dist[t]; double deriv = (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps; v->setXYZ(pp.x(),pp.y(),pp.z()); v->setParameter(0,t_); gradObj[index] += deriv * factor; } } if(v->onWhat() == *it){ int index = mesh.getFreeVertexStartIndex(v); if (index >= 0){ MTriangle *t = (*it)->triangles[i]; double uu,vv; v->getParameter(0,uu); v->getParameter(1,vv); SPoint3 pp (v->x(),v->y(),v->z()); const double distT = dist[t]; GPoint gp = (*it)->point(uu+eps,vv); v->setParameter(0,uu+eps); v->setXYZ(gp.x(),gp.y(),gp.z()); double deriv = (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps; v->setXYZ(pp.x(),pp.y(),pp.z()); v->setParameter(0,uu); gradObj[index] += deriv * factor; gp = (*it)->point(uu,vv+eps); v->setParameter(1,vv+eps); v->setXYZ(gp.x(),gp.y(),gp.z()); deriv = (MFaceGFaceDistanceOld(t, *it, &gsfT, &normalsToCAD) - distT) /eps; v->setXYZ(pp.x(),pp.y(),pp.z()); v->setParameter(1,vv); gradObj[index+1] += deriv * factor; } } } } } } mesh.updateGEntityPositions(xyz,uvw); Obj +=distCAD; // printf("computing distance : 2D part %12.5E\n",distCAD); // printf("%22.15E\n",distCAD); return true; }
gmshFace::gmshFace(GModel *m, Surface *face) : GFace(m, face->Num), s(face), isSphere(false), radius(0.) { resetMeshAttributes(); // edgeCounterparts = s->edgeCounterparts; // affineTransform = s->affineTransform; std::vector<GEdge*> eds; std::vector<int> nums; for(int i = 0; i < List_Nbr(s->Generatrices); i++){ Curve *c; List_Read(s->Generatrices, i, &c); GEdge *e = m->getEdgeByTag(abs(c->Num)); if(e){ eds.push_back(e); nums.push_back(c->Num); } else Msg::Error("Unknown curve %d", c->Num); } for(int i = 0; i < List_Nbr(s->GeneratricesByTag); i++){ int j; List_Read(s->GeneratricesByTag, i, &j); GEdge *e = m->getEdgeByTag(abs(j)); if(e){ eds.push_back(e); nums.push_back(j); } else Msg::Error("Unknown curve %d", j); } std::list<GEdge*> l_wire; GVertex *first = 0; for(unsigned int i = 0; i < eds.size(); i++){ GEdge *e = eds[i]; int num = nums[i]; GVertex *start = (num > 0) ? e->getBeginVertex() : e->getEndVertex(); GVertex *next = (num > 0) ? e->getEndVertex() : e->getBeginVertex(); if (!first) first = start; l_wire.push_back(e); if (next == first){ edgeLoops.push_back(GEdgeLoop(l_wire)); l_wire.clear(); first = 0; } l_edges.push_back(e); e->addFace(this); l_dirs.push_back((num > 0) ? 1 : -1); if (List_Nbr(s->Generatrices) == 2){ e->meshAttributes.minimumMeshSegments = std::max(e->meshAttributes.minimumMeshSegments, 2); } } // always compute and store the mean plane for plane surfaces (using // the bounding vertices) if(s->Typ == MSH_SURF_PLAN) computeMeanPlane(); if(s->EmbeddedCurves){ for(int i = 0; i < List_Nbr(s->EmbeddedCurves); i++){ Curve *c; List_Read(s->EmbeddedCurves, i, &c); GEdge *e = m->getEdgeByTag(abs(c->Num)); if(e) addEmbeddedEdge(e); else Msg::Error("Unknown curve %d", c->Num); } } if(s->EmbeddedPoints){ for(int i = 0; i < List_Nbr(s->EmbeddedPoints); i++){ Vertex *v; List_Read(s->EmbeddedPoints, i, &v); GVertex *gv = m->getVertexByTag(v->Num); if(gv) embedded_vertices.push_back(gv); else Msg::Error("Unknown point %d", v->Num); } } isSphere = iSRuledSurfaceASphere(s, center, radius); }
void MyCanvas::shadeDevicePolygon(std::vector<GEdge>& Edges, GShader* shader) { assert(shader != nullptr); if (Edges.size() < 2) { //printf("Error: ShadeDevicePolygon needs at least 2 edges to draw\n"); return; } // Sort the edges from top to bottom, left to right std::sort(Edges.begin(), Edges.end()); // The first two edges will be the top most edges GEdge LeftEdge = Edges[0]; GEdge RightEdge = Edges[1]; // Get start of pixel address for bitmap and offset to the top row GPixel *DstPixels = (GPixel*)((char*)Bitmap.pixels() + Bitmap.fRowBytes * LeftEdge.top()); // Set the context in the shader to the CTM float TwoRows[6]; CTM.GetTwoRows(TwoRows); shader->setContext(TwoRows); int EdgeCounter = 2; for (int y = LeftEdge.top(); y < Edges.back().bottom(); ++y) { int startX = Utility::round(LeftEdge.currentX()); int count = (int)(RightEdge.currentX() - LeftEdge.currentX()); count = Utility::clamp(1, count, BmpRect.width() - 1); /* Allocate a row of pixels to calculate shader pixel values * then blend shader pixels into the dst bitmap */ GPixel *row = new GPixel[count]; shader->shadeRow(startX, y, count, row); blendRow(DstPixels, startX, row, count); delete[] row; // Move currentX of the left and right edges to the next row LeftEdge.moveCurrentX(1.0f); RightEdge.moveCurrentX(1.0f); // Check left and right edge for y has passed bottom, if we have edges left then set the next edge if (y >= LeftEdge.bottom() && EdgeCounter < Edges.size()) { LeftEdge = Edges[EdgeCounter]; ++EdgeCounter; } if (y >= RightEdge.bottom() && EdgeCounter < Edges.size()) { RightEdge = Edges[EdgeCounter]; ++EdgeCounter; } DstPixels = (GPixel*)((char*)DstPixels + Bitmap.fRowBytes); } }
int GModel::importGEOInternals() { if(Tree_Nbr(_geo_internals->Points)) { List_T *points = Tree2List(_geo_internals->Points); for(int i = 0; i < List_Nbr(points); i++){ Vertex *p; List_Read(points, i, &p); GVertex *v = getVertexByTag(p->Num); if(!v){ v = new gmshVertex(this, p); add(v); } if(!p->Visible) v->setVisibility(0); } List_Delete(points); } if(Tree_Nbr(_geo_internals->Curves)) { List_T *curves = Tree2List(_geo_internals->Curves); for(int i = 0; i < List_Nbr(curves); i++){ Curve *c; List_Read(curves, i, &c); if(c->Num >= 0){ GEdge *e = getEdgeByTag(c->Num); if(!e && c->Typ == MSH_SEGM_COMPOUND){ std::vector<GEdge*> comp; for(unsigned int j = 0; j < c->compound.size(); j++){ GEdge *ge = getEdgeByTag(c->compound[j]); if(ge) comp.push_back(ge); } e = new GEdgeCompound(this, c->Num, comp); e->meshAttributes.method = c->Method; e->meshAttributes.nbPointsTransfinite = c->nbPointsTransfinite; e->meshAttributes.typeTransfinite = c->typeTransfinite; e->meshAttributes.coeffTransfinite = c->coeffTransfinite; e->meshAttributes.extrude = c->Extrude; e->meshAttributes.reverseMesh = c->ReverseMesh; add(e); } else if(!e && c->beg && c->end){ e = new gmshEdge(this, c, getVertexByTag(c->beg->Num), getVertexByTag(c->end->Num)); add(e); } else if(!e){ e = new gmshEdge(this, c, 0, 0); add(e); } if(!c->Visible) e->setVisibility(0); if(c->Color.type) e->setColor(c->Color.mesh); if(c->degenerated) { e->setTooSmall(true); } } } List_Delete(curves); } if(Tree_Nbr(_geo_internals->Surfaces)) { List_T *surfaces = Tree2List(_geo_internals->Surfaces); for(int i = 0; i < List_Nbr(surfaces); i++){ Surface *s; List_Read(surfaces, i, &s); GFace *f = getFaceByTag(s->Num); if(!f && s->Typ == MSH_SURF_COMPOUND){ std::list<GFace*> comp; for(unsigned int j = 0; j < s->compound.size(); j++){ GFace *gf = getFaceByTag(s->compound[j]); if(gf) comp.push_back(gf); } std::list<GEdge*> b[4]; for(int j = 0; j < 4; j++){ for(unsigned int k = 0; k < s->compoundBoundary[j].size(); k++){ GEdge *ge = getEdgeByTag(s->compoundBoundary[j][k]); if(ge) b[j].push_back(ge); } } int param = CTX::instance()->mesh.remeshParam; GFaceCompound::typeOfCompound typ = GFaceCompound::HARMONIC_CIRCLE; if (param == 1) typ = GFaceCompound::CONFORMAL_SPECTRAL; if (param == 2) typ = GFaceCompound::RADIAL_BASIS; if (param == 3) typ = GFaceCompound::HARMONIC_PLANE; if (param == 4) typ = GFaceCompound::CONVEX_CIRCLE; if (param == 5) typ = GFaceCompound::CONVEX_PLANE; if (param == 6) typ = GFaceCompound::HARMONIC_SQUARE; if (param == 7) typ = GFaceCompound::CONFORMAL_FE; int algo = CTX::instance()->mesh.remeshAlgo; f = new GFaceCompound(this, s->Num, comp, b[0], b[1], b[2], b[3], typ, algo); f->meshAttributes.recombine = s->Recombine; f->meshAttributes.recombineAngle = s->RecombineAngle; f->meshAttributes.method = s->Method; f->meshAttributes.extrude = s->Extrude; // transfinite import Added by Trevor Strickler. This helps when experimenting // to create compounds from transfinite surfs. Not having it does not break // anything Gmsh *officially* does right now, but maybe it was left out by mistake??? and could // cause problems later? f->meshAttributes.transfiniteArrangement = s->Recombine_Dir; f->meshAttributes.corners.clear(); for(int i = 0; i < List_Nbr(s->TrsfPoints); i++){ Vertex *corn; List_Read(s->TrsfPoints, i, &corn); GVertex *gv = f->model()->getVertexByTag(corn->Num); if(gv) f->meshAttributes.corners.push_back(gv); else Msg::Error("Unknown vertex %d in transfinite attributes", corn->Num); } add(f); if(s->EmbeddedCurves){ for(int i = 0; i < List_Nbr(s->EmbeddedCurves); i++){ Curve *c; List_Read(s->EmbeddedCurves, i, &c); GEdge *e = getEdgeByTag(abs(c->Num)); if(e) f->addEmbeddedEdge(e); else Msg::Error("Unknown curve %d", c->Num); } } if(s->EmbeddedPoints){ for(int i = 0; i < List_Nbr(s->EmbeddedPoints); i++){ Vertex *v; List_Read(s->EmbeddedPoints, i, &v); GVertex *gv = getVertexByTag(v->Num); if(gv) f->addEmbeddedVertex(gv); else Msg::Error("Unknown point %d", v->Num); } } } else if(!f){ f = new gmshFace(this, s); add(f); } else f->resetMeshAttributes(); if(!s->Visible) f->setVisibility(0); if(s->Color.type) f->setColor(s->Color.mesh); } List_Delete(surfaces); } if(Tree_Nbr(_geo_internals->Volumes)) { List_T *volumes = Tree2List(_geo_internals->Volumes); for(int i = 0; i < List_Nbr(volumes); i++){ Volume *v; List_Read(volumes, i, &v); GRegion *r = getRegionByTag(v->Num); if(!r && v->Typ == MSH_VOLUME_COMPOUND){ std::vector<GRegion*> comp; for(unsigned int j = 0; j < v->compound.size(); j++){ GRegion *gr = getRegionByTag(v->compound[j]); if(gr) comp.push_back(gr); } r = new GRegionCompound(this, v->Num, comp); if(v->EmbeddedSurfaces){ for(int i = 0; i < List_Nbr(v->EmbeddedSurfaces); i++){ Surface *s; List_Read(v->EmbeddedSurfaces, i, &s); GFace *gf = getFaceByTag(abs(s->Num)); if(gf) r->addEmbeddedFace(gf); else Msg::Error("Unknown surface %d", s->Num); } } add(r); } else if(!r){ r = new gmshRegion(this, v); add(r); } else r->resetMeshAttributes(); if(!v->Visible) r->setVisibility(0); if(v->Color.type) r->setColor(v->Color.mesh); } List_Delete(volumes); } for(int i = 0; i < List_Nbr(_geo_internals->PhysicalGroups); i++){ PhysicalGroup *p; List_Read(_geo_internals->PhysicalGroups, i, &p); for(int j = 0; j < List_Nbr(p->Entities); j++){ int num; List_Read(p->Entities, j, &num); GEntity *ge = 0; int tag = CTX::instance()->geom.orientedPhysicals ? abs(num) : num; switch(p->Typ){ case MSH_PHYSICAL_POINT: ge = getVertexByTag(tag); break; case MSH_PHYSICAL_LINE: ge = getEdgeByTag(tag); break; case MSH_PHYSICAL_SURFACE: ge = getFaceByTag(tag); break; case MSH_PHYSICAL_VOLUME: ge = getRegionByTag(tag); break; } int pnum = CTX::instance()->geom.orientedPhysicals ? (sign(num) * p->Num) : p->Num; if(ge && std::find(ge->physicals.begin(), ge->physicals.end(), pnum) == ge->physicals.end()) ge->physicals.push_back(pnum); } } // create periodic mesh relationships for (std::map<int,int>::iterator it = _geo_internals->periodicEdges.begin(); it != _geo_internals->periodicEdges.end(); ++it){ GEdge *ge = getEdgeByTag(abs(it->first)); if (ge){ int MASTER = it->second * (it->first > 0 ? 1 : -1); ge->setMeshMaster(MASTER); } } for (std::map<int,int>::iterator it = _geo_internals->periodicFaces.begin(); it != _geo_internals->periodicFaces.end(); ++it){ GFace *gf = getFaceByTag(abs(it->first)); if (gf)gf->setMeshMaster(it->second * (it->first > 0 ? 1 : -1)); } for (eiter it = firstEdge() ; it != lastEdge() ; ++it){ int meshMaster = (*it)->meshMaster(); if (meshMaster != (*it)->tag()){ GEdge *ge_master = getEdgeByTag(abs(meshMaster)); if(ge_master)(*it)->getBeginVertex()->setMeshMaster ( (meshMaster > 0) ? ge_master->getBeginVertex()->tag() : ge_master->getEndVertex()->tag()); if(ge_master)(*it)->getEndVertex()->setMeshMaster ( (meshMaster < 0) ? ge_master->getBeginVertex()->tag() : ge_master->getEndVertex()->tag()); } } Msg::Debug("Gmsh model (GModel) imported:"); Msg::Debug("%d Vertices", vertices.size()); Msg::Debug("%d Edges", edges.size()); Msg::Debug("%d Faces", faces.size()); Msg::Debug("%d Regions", regions.size()); return 1; }
GEdge *GNode< Point >::Del( Long n, Long i ) { GEdge *p = Neighbours(); GEdge *q; if (!p) return NULL; if ((p->Node()==n)&&(p->Item()==i)) { q=p->Next(); etrash.push_back(p); // delete(p); // Problem when using Neighbours() list: cannot delete adjacents=q; } else { for (q=p->Next();q != NULL; p=q,q=q->Next()) if (q && (q->Node() ==n) && (q->Item() == i)) { p->Next(q->Next()); etrash.push_back(q); break; // delete(q); // Problem when using Neighbours() list: cannot delete } } return adjacents; }
/* * Merges 2 nodes in 1 ->n1 * Updates the adjacent list of all node (n2 ->n1). * and delete n2. */ Errc Graph3d::Merge( Long n1, Long n2 ) { GEdge *ptr; if (_directed) { if ((n1==n2) || (!tnode[n1]) || (!tnode[n2])) return FAILURE; // Remove links Unlink(n1,n2); Unlink(n2,n1); while((ptr=tnode[n2]->Neighbours())){ if ( n2 != ptr->Node() ) Link(n1,ptr->Node(),ptr->Item(),ptr->weight,true); else Link(n1,n1,ptr->Item(),ptr->weight,true); Unlink(n2,ptr->Node(),ptr->Item()); } // Cross the graph in order to replace n2 by n1 for ( int i = 0; i < this->Size(); ++i ) { const GNode<Point3d> * noeud = (*this)[i]; if ( noeud != NULL ) { for ( ptr = noeud->Neighbours() ; ptr != NULL; ptr = ptr->Next() ) if ( ptr->Node() == n2 ) { Link(i,n1,ptr->Item(),ptr->weight,true); Unlink(i,n2,ptr->Item()); } } } Del(n2); } else { if ((n1==n2) || (!tnode[n1]) || (!tnode[n2])) return FAILURE; Unlink(n1,n2); while((ptr=tnode[n2]->Neighbours())){ if ( n2 != ptr->Node() ) Link(n1,ptr->Node(),ptr->Item(),ptr->weight,true); else Link(n1,n1,ptr->Item(),ptr->weight,true); Unlink(n2,ptr->Node(),ptr->Item()); } Del(n2); } return SUCCESS; }
void GEdgeCompound::orderEdges() { std::vector<GEdge*> _c ; std::list<GEdge*> edges ; for (unsigned int i = 0; i < _compound.size(); i++){ edges.push_back(_compound[i]); } // find a lonely edge std::map<GVertex*, GEdge*> tempv; for (std::list<GEdge*>::iterator it = edges.begin() ; it != edges.end() ; ++it){ GVertex *v1 = (*it)->getBeginVertex(); GVertex *v2 = (*it)->getEndVertex(); if(!v1 || !v2){ Msg::Error("Compounds don't support curves without two bounding vertices"); return; } std::map<GVertex*, GEdge*>::iterator it1 = tempv.find(v1); if (it1 == tempv.end()) { tempv.insert(std::make_pair(v1, *it)); } else tempv.erase(it1); std::map<GVertex*, GEdge*>::iterator it2 = tempv.find(v2); if (it2 == tempv.end()){ tempv.insert(std::make_pair(v2, *it)); } else tempv.erase(it2); } // find the first GEdge and erase it from the list edges GEdge *firstEdge; if (tempv.size() == 2){ // non periodic firstEdge = (tempv.begin())->second; for (std::list<GEdge*>::iterator it = edges.begin() ; it != edges.end() ; ++it){ if (*it == firstEdge){ edges.erase(it); break; } } } else if (tempv.size() == 0){ // periodic firstEdge = *(edges.begin()); edges.erase(edges.begin()); } else{ Msg::Error("EdgeCompound %d is wrong (it has %d end points)", tag(), tempv.size()); return; } // loop over all segments to order segments and store it in the list _c _c.push_back(firstEdge); _orientation.push_back(1); GVertex *first = _c[0]->getBeginVertex(); GVertex *last = _c[0]->getEndVertex(); while (first != last){ if (edges.empty())break; bool found = false; for (std::list<GEdge*>::iterator it = edges.begin() ; it != edges.end() ; ++it){ GEdge *e = *it; std::list<GEdge*>::iterator itp; if (e->getBeginVertex() == last){ _c.push_back(e); itp = it; it++; edges.erase(itp); _orientation.push_back(1); last = e->getEndVertex(); found = true; break; } else if (e->getEndVertex() == last){ _c.push_back(e); itp = it; it++; edges.erase(itp); _orientation.push_back(0); last = e->getBeginVertex(); found = true; break; } } if (!found){ if (_c.size() == 1 && _orientation[0]){ GVertex *temp = first; first = last; last = temp; _orientation[0] = 0; } else { Msg::Error("Compound Edge %d is wrong", tag()); return; } } } //edges is now a list of ordered GEdges _compound = _c; // special case reverse orientation if (_compound.size() < 2) return; if (_orientation[0] && _compound[0]->getEndVertex() != _compound[1]->getEndVertex() && _compound[0]->getEndVertex() != _compound[1]->getBeginVertex()){ for (unsigned int i = 0; i < _compound.size(); i++){ _orientation[i] = !_orientation[i] ; } } }
void WalkEdges(const GEdge e1, const GEdge e2, const GPaint &paint) { const GBitmap &bm = GetInternalBitmap(); int h = bm.fHeight; int w = bm.fWidth; GASSERT(e1.p1.y() == e2.p1.y()); int startY = Clamp(static_cast<int>(e1.p1.y() + 0.5f), 0, h-1); GASSERT(e1.p2.y() == e2.p2.y()); int endY = Clamp(static_cast<int>(e1.p2.y() + 0.5f), 0, h-1); if(endY == startY) { return; } GASSERT(endY > startY); // Initialize to NAN float m1 = 0.0f/0.0f, b1; float m2 = 0.0f/0.0f, b2; bool vert1 = e1.ComputeLine(m1, b1); bool vert2 = e2.ComputeLine(m2, b2); if(m1 == 0 || m2 == 0) { return; } // Collinear? if(vert2 && vert1 && e1.p1.x() == e2.p1.x()) { return; } else if(m1 == m2 && b1 == b2) { return; } float stepX1 = vert1? 0 : 1/m1; float stepX2 = vert2? 0 : 1/m2; GPoint p1, p2; float sY = static_cast<float>(startY) + 0.5f; if(vert1) { p1.set(e1.p1.x(), sY); } else { p1.set((sY - b1) / m1, sY); } if(vert2) { p2.set(e2.p1.x(), sY); } else { p2.set((sY - b2) / m2, sY); } // Make sure that p1 is always less than p2 to avoid // doing a min/max in the inner loop if(p1.x() > p2.x()) { std::swap(p1, p2); std::swap(stepX1, stepX2); } GPixel color = ColorToPixel(paint.getColor()); BlendFunc blend = GetBlendFunc(eBlendOp_SrcOver); uint32_t nSteps = endY - startY; for(uint32_t i = 0; i < nSteps; i++) { // Since we haven't implemented clipping yet, take care // not to go beyond our bounds... const int x1 = Clamp<int>(p1.fX + 0.5f, 0, w-1); const int x2 = Clamp<int>(p2.fX + 0.5f, 0, w-1); GPixel *row = GetRow(bm, startY + i); for(int x = x1; x < x2; x++) { row[x] = blend(row[x], color); } p1.fX += stepX1; p2.fX += stepX2; } }
void EdgeItem::keyPressEvent(QKeyEvent *event) { int key = event->key(); GNode *n = NULL; GEdge *e = NULL; VEdge vedge( edge()); NavSector sector = edge()->graph()->nodeNavigationSector(); GNode *curr_node = edge()->graph()->nodeInFocus(); NodeNav node_nav( curr_node, sector); switch( key) { case Qt::Key_Up: if ( isNotNullP( curr_node) && ( sector == LEFT_SECTOR || sector == RIGHT_SECTOR)) { e = node_nav.edgeInDir( edge(), NAV_DIR_UP); } else { n = vedge.nodeUp(); } break; case Qt::Key_Down: if ( isNotNullP( curr_node) && ( sector == LEFT_SECTOR || sector == RIGHT_SECTOR) ) { e = node_nav.edgeInDir( edge(), NAV_DIR_DOWN); } else { n = vedge.nodeDown(); } break; case Qt::Key_Left: if ( isNotNullP( curr_node) && ( sector == TOP_SECTOR || sector == BOTTOM_SECTOR) ) { e = node_nav.edgeInDir( edge(), NAV_DIR_LEFT); } else { n = vedge.nodeLeft(); } break; case Qt::Key_Right: if ( isNotNullP( curr_node) && ( sector == TOP_SECTOR || sector == BOTTOM_SECTOR) ) { e = node_nav.edgeInDir( edge(), NAV_DIR_RIGHT); } else { n = vedge.nodeRight(); } break; default: break; } if ( isNotNullP( n)) { if ( edge()->graph()->view()->isContext()) { edge()->graph()->emptySelection(); edge()->graph()->selectNode( n); edge()->graph()->view()->findContext(); } edge()->graph()->view()->focusOnNode( n, true); scene()->clearFocus(); scene()->clearSelection(); n->item()->setFocus(); n->item()->setSelected( true); } else if ( isNotNullP( e)) { // Get focus on edge scene()->clearFocus(); scene()->clearSelection(); e->item()->setFocus(); e->item()->setSelected( true); } //QGraphicsItem::keyPressEvent( event); }
GEdge *GNode< Point >::Search( Long n ) const { GEdge *p; for (p=adjacents; p && (p->Node()!=n); p=p->Next()) ; return p; }