void Render::renderizaArestas() { QPainter buff(frontBuffer); QPoint p; HalfEdge *partida; HalfEdge::iterator it; buff.setPen(vizinhoScreen); if(vsel != NULL) partida = vsel->getEdge(); if(hsel != NULL) partida = hsel; if(fsel != NULL) partida = fsel->getHalfEdge(); if(vsel != NULL || hsel != NULL) { for(it = partida->v_begin(); it != partida->v_end(); ++it) { buff.drawLine(transforma(it->getOrigem()->getPoint()), transforma(it->getDestino()->getPoint())); } if(hsel != NULL) { partida = partida->getTwin(); for(it = partida->v_begin(); it != partida->v_end(); ++it) { buff.drawLine(transforma(it->getOrigem()->getPoint()), transforma(it->getDestino()->getPoint())); } }else buff.drawLine(transforma(partida->getOrigem()->getPoint()), transforma(partida->getDestino()->getPoint())); } QVector<HalfEdge *> *v; if(fsel != NULL) { if(interface.isExterna(fsel)) v = &(interface.componentesFaceExterna); else { v = new QVector<HalfEdge *>(); v->push_back(partida->getTwin()); } for(int i = 0; i < v->size(); ++i) { partida = v->at(i)->getTwin(); for(it = partida->f_begin(); it != partida->f_end(); ++it) { buff.drawLine(transforma(it->getOrigem()->getPoint()), transforma(it->getDestino()->getPoint())); } buff.drawLine(transforma(partida->getOrigem()->getPoint()), transforma(partida->getDestino()->getPoint())); } if(!interface.isExterna(fsel)) delete v; } }
void Interface::adicionaface(HalfEdge* e, Face* f) { HalfEdge *ori = e; HalfEdge *ant = NULL; HalfEdge *nova = NULL; HalfEdge *first; bool sai = false; nova = new HalfEdge(); nova->setFace(f); nova->setTwin(ori); ori->setTwin(nova); nova->setOrigem(ori->getDestino()); f->setOuterComp(nova); ant = nova; first = nova; ori = ori->getProx(); while(true) { while(ori->getTwin() != NULL) { if(ori == e) { sai = true; break; } ori = ori->getTwin()->getProx(); } if(sai) break; nova = new HalfEdge(); nova->setFace(f); nova->setTwin(ori); ori->setTwin(nova); nova->setProx(ant); ant->setAnt(nova); nova->setOrigem(ori->getDestino()); ori = ori->getProx(); ant = nova; } ori->getTwin()->setProx(ant); ant->setAnt(ori->getTwin()); }
Face* Interface::getFaceNear(QPointF p) { HalfEdge *min = getArestaNear(p); if(isExterna(min->getFace())) min = min->getTwin(); if(dentroFace(min,p)) return min->getFace(); if(isExterna(min->getTwin()->getFace()) || dentroFace(min->getTwin(),p)) return min->getTwin()->getFace(); return NULL; }
//fill list of edges crossing plane on some z height void Slice::fillEdgeLayer(){ QList<Face*> currentLayer; Face* currentFace; HalfEdge* currentEdge; for(int i=0; i<this->triLayer.size(); i++){ currentLayer=*this->triLayer.at(i); //take first face from list if(currentLayer.size()>0){ while(currentLayer.size()>0){ currentFace=currentLayer.takeFirst(); currentEdge=currentFace->getEdgesCrossingPlane(this->layerHeight*i).at(0); //create list for firts edge loop this->edgeLayer.at(i)->append(new QList<HalfEdge*>); this->pointLayer.at(i)->append(new QList<QVector3D>); this->edgeLayer.at(i)->last()->append(currentEdge); //while all faces are processed do{ currentLayer.removeAt(currentLayer.indexOf(currentFace)); //take his twin currentEdge=currentEdge->getTwin(); currentFace=currentEdge->getFaces().at(0); //qDebug() << currentFace->getNeighbors().size(); if(currentFace->getEdgesCrossingPlane(this->layerHeight*i,currentEdge).size()!=1){ //qDebug() << "dupa" <<currentFace->getEdgesCrossingPlane(this->layerHeight*i,currentEdge).size(); } currentEdge=currentFace->getEdgesCrossingPlane(this->layerHeight*i,currentEdge).first(); this->edgeLayer.at(i)->last()->append(currentEdge); }while(currentLayer.contains(currentFace)); } } } }
void Interface::addFace(QVector<QPointF> in) { Face *f = new Face(); HalfEdge *ant = NULL; HalfEdge *first, *twin, *temp; for(int i = 0; i < in.size(); i++) { HalfEdge *e = new HalfEdge(); if (i == 0) first = e; temp = findTwin(in[i],in[(i+1)%in.size()]); if (temp != NULL) e = temp; else map[qMakePair(in[i], in[(i+1)%in.size()])] = e; twin = e->getTwin(); if (twin == NULL) twin = findTwin(in[(i+1)%in.size()],in[i]); minX = MIN(minX, in[i].x()); maxX = MAX(maxX, in[i].x()); minY = MIN(minY, in[i].y()); maxY = MAX(maxY, in[i].y()); Vertex *v = addVertex(in[i]); v->setEdge(e); e->setOrigem(v); e->setFace(f); e->setAnt(ant); if (ant!= NULL) { ant->setProx(e); } e->setTwin(twin); if (twin!= NULL) { twin->setTwin(e); } ant = e; } first->setAnt(ant); ant->setProx(first); f->setOuterComp(first); faces.push_back(f); }
void Render::renderizaFaceExterna(QPen *pen) { bool passa; QVector<HalfEdge*> *list = &(interface.componentesFaceExterna); QVector<HalfEdge*> temp; HalfEdge *val; HalfEdge::iterator it, jt; QImage buffExt(buffer->width(), buffer->height(), QImage::Format_ARGB32_Premultiplied); QPainter p; p.begin(&buffExt); p.setCompositionMode(QPainter::CompositionMode_Source); p.fillRect(buffExt.rect(), pen->color()); p.end(); for(int i = 0; i < list->size(); ++i) { val = list->at(i); passa = false; for(it = val->v_begin(); it != val->v_end() ; ++it) { if(dentroFace(val->getTwin(),it->getDestino()->getPoint())) { passa = true; break; } } if( passa || componenteFaceUnica(&it)) renderizaComponente(val->getTwin(),&buffExt,QPen(Qt::transparent)); else temp.push_back(val->getTwin()); } for(int i = 0; i < temp.size(); ++i) renderizaFace(temp[i],&buffExt,*pen); p.begin(frontBuffer); p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.drawImage(0,0, buffExt); p.end(); }
void Render::renderizaFaces() { HalfEdge *partida; HalfEdge::iterator it; bool renderizaExterna = false; if(vsel != NULL) partida = vsel->getEdge(); if(hsel != NULL) partida = hsel; if(fsel != NULL) partida = fsel->getHalfEdge(); if(vsel != NULL) { if(interface.isExterna(partida->getFace())) renderizaExterna = true; else renderizaFace(partida, frontBuffer,vizinhoScreen); for(it = partida->v_begin(); it != partida->v_end(); ++it) { if(interface.isExterna(it->getFace())) renderizaExterna = true; else renderizaFace(&it, frontBuffer,vizinhoScreen); } } if(hsel != NULL) { if(interface.isExterna(partida->getFace())) renderizaExterna = true; else renderizaFace(partida, frontBuffer,vizinhoScreen); if(interface.isExterna(partida->getTwin()->getFace())) renderizaExterna = true; else renderizaFace(partida->getTwin(), frontBuffer,vizinhoScreen); } QVector<HalfEdge *> *v; QSet<Face*> f; if(fsel != NULL) { if(interface.isExterna(fsel)) v = &(interface.componentesFaceExterna); else { v = new QVector<HalfEdge *>(); v->push_back(partida->getTwin()); } for(int i = 0; i < v->size(); ++i) { partida = v->at(i)->getTwin(); if(interface.isExterna(partida->getTwin()->getFace())) renderizaExterna = true; else renderizaFace(partida->getTwin(), frontBuffer,vizinhoScreen); for(it = partida->f_begin(); it != partida->f_end(); ++it) { if(interface.isExterna(it->getTwin()->getFace())) renderizaExterna = true; else f.insert(it->getTwin()->getFace()); } } if(!interface.isExterna(fsel)) delete v; QSet<Face*>::iterator jt; for(jt = f.begin(); jt != f.end(); ++jt) renderizaFace((*jt)->getHalfEdge(), frontBuffer,vizinhoScreen); } if(renderizaExterna) renderizaFaceExterna(&vizinhoScreen); }
TriMesh* TriMesh::subdivideSqrt3() { vector<glm::vec3> points; vector<int> indices; for (int i = 0; i < m_nodes.size(); i++){ HalfEdge* start_edge = m_nodes[i].getLeadingHalfEdge(); int surroundingPoints = 0; glm::vec3 new_point = glm::vec3(0); points.push_back(m_nodes[i].m_pos_); //Pushing node vertex to points. m_nodes[i].index = points.size() - 1; //Setting node index. HalfEdge* he = start_edge; do{ int center_of_triangle; //Checking if triangle center already exists. if (he->getTriangle()->getCenter() == -1){ points.push_back(he->getTriangle()->calculateBarycenter()); he->getTriangle()->setCenter(points.size() - 1); } center_of_triangle = he->getTriangle()->getCenter(); /*Boundary case*/ if (he->isBoundary()){ points.push_back(glm::lerp(m_nodes[i].m_pos_, he->getDestinationNode()->m_pos_, 0.5f)); //Pushing mid-edge point. int middle_of_edge = points.size() - 1; int end_of_edge; //Checking if end point on edge already exists. if (he->getDestinationNode()->index == -1){ points.push_back(he->getDestinationNode()->m_pos_); //Pushing if not. he->getDestinationNode()->index = points.size() - 1; } end_of_edge = he->getDestinationNode()->index; //Pushing boundary triangle 1. indices.push_back(middle_of_edge); indices.push_back(center_of_triangle); indices.push_back(m_nodes[i].index); //Pushing boundary triangle 2. indices.push_back(middle_of_edge); indices.push_back(end_of_edge); indices.push_back(center_of_triangle); } /*Normal non-boundary edge*/ else{ int center_of_twin_triangle; Triangle* twin_triangle = he->getTwin()->getTriangle(); //Checking if triangle center already exists. if (twin_triangle->getCenter() == -1){ points.push_back(twin_triangle->calculateBarycenter()); twin_triangle->setCenter(points.size() - 1); } center_of_twin_triangle = twin_triangle->getCenter(); //Pushing new triangle indices.push_back(m_nodes[i].index); indices.push_back(center_of_twin_triangle); indices.push_back(center_of_triangle); } surroundingPoints++; new_point += he->getDestinationNode()->m_pos_; he = he->getVtxRingNext(); } while (he != start_edge); glm::vec3 beta = glm::vec3((4 - 2*cos(2*M_PI/surroundingPoints))/(9*surroundingPoints)); new_point = (1 - surroundingPoints * beta.x)*m_nodes[i].m_pos_ + beta*new_point; points[m_nodes[i].index] = new_point; } // skip // Generate a new set of points and indices using the sqrt(3) subdivision scheme // unskip return new TriMesh(points, indices); }