void frameFieldBackgroundMesh2D::eval_crossfield(double u, double v, STensor3 &cf) { double quadAngle = angle(u,v); Pair<SVector3, SVector3> dirs = compute_crossfield_directions(u,v,quadAngle); SVector3 n = crossprod(dirs.first(),dirs.second()); for (int i=0; i<3; i++) { cf(i,0) = dirs.first()[i]; cf(i,1) = dirs.second()[i]; cf(i,2) = n[i]; } // SVector3 t1,t2,n; // GFace *face = dynamic_cast<GFace*>(gf); // Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); // SVector3 s1 = der.first(); // SVector3 s2 = der.second(); // n = crossprod(s1,s2); // n.normalize(); // s1.normalize(); // s2=crossprod(n,s1); // t1 = s1 * cos(quadAngle) + s2 * sin(quadAngle) ; // t1.normalize(); // t2 = crossprod(n,t1); // for (int i=0;i<3;i++){ // cf(i,0) = t1[i]; // cf(i,1) = t2[i]; // cf(i,2) = n[i]; // } }
virtual void applyValue(CSSStyleSelector* selector, CSSValue* value) const { if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); Pair* pair = primitiveValue->getPairValue(); if (!pair || !pair->first() || !pair->second()) return; Length radiusWidth; Length radiusHeight; if (pair->first()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) radiusWidth = Length(pair->first()->getDoubleValue(), Percent); else radiusWidth = Length(max(intMinForLength, min(intMaxForLength, pair->first()->computeLength<int>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()))), Fixed); if (pair->second()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) radiusHeight = Length(pair->second()->getDoubleValue(), Percent); else radiusHeight = Length(max(intMinForLength, min(intMaxForLength, pair->second()->computeLength<int>(selector->style(), selector->rootElementStyle(), selector->style()->effectiveZoom()))), Fixed); int width = radiusWidth.value(); int height = radiusHeight.value(); if (width < 0 || height < 0) return; if (!width) radiusHeight = radiusWidth; // Null out the other value. else if (!height) radiusWidth = radiusHeight; // Null out the other value. LengthSize size(radiusWidth, radiusHeight); setValue(selector->style(), size); }
static inline void updateCornerRadiusWidthAndHeight(CSSPrimitiveValue* corner, String& width, String& height) { if (!corner) return; Pair* radius = corner->getPairValue(); width = radius->first() ? radius->first()->cssText() : String("0"); if (radius->second()) height = radius->second()->cssText(); }
static String serializePositionOffset(const Pair& offset, const Pair& other) { if ((offset.first()->getValueID() == CSSValueLeft && other.first()->getValueID() == CSSValueTop) || (offset.first()->getValueID() == CSSValueTop && other.first()->getValueID() == CSSValueLeft)) return offset.second()->cssText(); return offset.cssText(); }
void CSSToStyleMap::mapFillYPosition(CSSPropertyID propertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!is<CSSPrimitiveValue>(*value)) return; CSSPrimitiveValue* primitiveValue = downcast<CSSPrimitiveValue>(value); Pair* pair = primitiveValue->getPairValue(); if (pair) { ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPositionY || propertyID == CSSPropertyWebkitMaskPositionY); primitiveValue = pair->second(); } Length length; if (primitiveValue->isLength()) length = primitiveValue->computeLength<Length>(m_resolver->state().cssToLengthConversionData()); else if (primitiveValue->isPercentage()) length = Length(primitiveValue->getDoubleValue(), Percent); else if (primitiveValue->isCalculatedPercentageWithLength()) length = Length(primitiveValue->cssCalcValue()->createCalculationValue(m_resolver->state().cssToLengthConversionData())); else return; layer->setYPosition(length); if (pair) layer->setBackgroundYOrigin(*(pair->first())); }
// returns the cross field as a pair of othogonal vectors (NOT in parametric coordinates, but real 3D coordinates) Pair<SVector3, SVector3> frameFieldBackgroundMesh2D::compute_crossfield_directions(double u, double v, double angle_current) { // get the unit normal at that point GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return Pair<SVector3,SVector3>(SVector3(), SVector3()); } Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); SVector3 s1 = der.first(); SVector3 s2 = der.second(); SVector3 n = crossprod(s1,s2); n.normalize(); SVector3 basis_u = s1; basis_u.normalize(); SVector3 basis_v = crossprod(n,basis_u); // normalize vector t1 that is tangent to gf at uv SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ; t1.normalize(); // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame SVector3 t2 = crossprod(n,t1); t2.normalize(); return Pair<SVector3,SVector3>(SVector3(t1[0],t1[1],t1[2]), SVector3(t2[0],t2[1],t2[2])); }
void frameFieldBackgroundMesh2D::exportCrossField(const std::string &filename) { FILE *f = Fopen(filename.c_str(), "w"); if(!f) { Msg::Error("Could not open file '%s'", filename.c_str()); return; } fprintf(f,"View \"Cross Field\"{\n"); std::vector<double> deltas(2); deltas[0] = 0.; deltas[1] = M_PI; for (std::vector<MVertex*>::iterator it = beginvertices(); it!=endvertices(); it++) { MVertex *v = *it; double angle_current = angle(v); GPoint p = get_GPoint_from_MVertex(v); for (int i=0; i<2; i++) { Pair<SVector3, SVector3> dirs = compute_crossfield_directions(v->x(),v->y(),angle_current+deltas[i]); fprintf(f,"VP(%g,%g,%g) {%g,%g,%g};\n",p.x(),p.y(),p.z(),dirs.first()[0], dirs.first()[1], dirs.first()[2]); fprintf(f,"VP(%g,%g,%g) {%g,%g,%g};\n",p.x(),p.y(),p.z(),dirs.second()[0], dirs.second()[1], dirs.second()[2]); } } fprintf(f,"};\n"); fclose(f); }
void CSSToStyleMap::mapFillYPosition(CSSPropertyID propertyID, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!value->isPrimitiveValue()) return; float zoomFactor = style()->effectiveZoom(); CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value); Pair* pair = primitiveValue->getPairValue(); if (pair) { ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPositionY || propertyID == CSSPropertyWebkitMaskPositionY); primitiveValue = pair->second(); } Length length; if (primitiveValue->isLength()) length = primitiveValue->computeLength<Length>(style(), rootElementStyle(), zoomFactor); else if (primitiveValue->isPercentage()) length = Length(primitiveValue->getDoubleValue(), Percent); else if (primitiveValue->isCalculatedPercentageWithLength()) length = Length(primitiveValue->cssCalcValue()->toCalcValue(style(), rootElementStyle(), zoomFactor)); else if (primitiveValue->isViewportPercentageLength()) length = primitiveValue->viewportPercentageLength(); else return; layer->setYPosition(length); if (pair) layer->setBackgroundYOrigin(*(pair->first())); }
void CSSToStyleMap::mapNinePieceImageRepeat(StyleResolverState&, CSSValue* value, NinePieceImage& image) { if (!value || !value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Pair* pair = primitiveValue->getPairValue(); if (!pair || !pair->first() || !pair->second()) return; CSSValueID firstIdentifier = pair->first()->getValueID(); CSSValueID secondIdentifier = pair->second()->getValueID(); ENinePieceImageRule horizontalRule; switch (firstIdentifier) { case CSSValueStretch: horizontalRule = StretchImageRule; break; case CSSValueRound: horizontalRule = RoundImageRule; break; case CSSValueSpace: horizontalRule = SpaceImageRule; break; default: // CSSValueRepeat horizontalRule = RepeatImageRule; break; } image.setHorizontalRule(horizontalRule); ENinePieceImageRule verticalRule; switch (secondIdentifier) { case CSSValueStretch: verticalRule = StretchImageRule; break; case CSSValueRound: verticalRule = RoundImageRule; break; case CSSValueSpace: verticalRule = SpaceImageRule; break; default: // CSSValueRepeat verticalRule = RepeatImageRule; break; } image.setVerticalRule(verticalRule); }
const Pair<A,B>& Pair<A,B>::operator=(const Pair<A,B>& iP) { if (this!=&iP) { _first=iP.first(); _second = iP.second(); } return *this; }
LengthPoint StyleBuilderConverter::convertLengthPoint(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Pair* pair = primitiveValue->getPairValue(); Length x = pair->first()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); Length y = pair->second()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); return LengthPoint(x, y); }
static LengthSize convertToLengthSize(const StyleResolverState& state, CSSPrimitiveValue* value) { if (!value) return LengthSize(Length(0, Fixed), Length(0, Fixed)); Pair* pair = value->getPairValue(); return LengthSize(convertToLength(state, pair->first()), convertToLength(state, pair->second())); }
void highOrderTools::computeMetricInfo(GFace *gf, MElement *e, fullMatrix<double> &J, fullMatrix<double> &JT, fullVector<double> &D) { int nbNodes = e->getNumVertices(); // printf("ELEMENT --\n"); for (int j = 0; j < nbNodes; j++){ SPoint2 param; reparamMeshVertexOnFace(e->getVertex(j), gf, param); // printf("%g %g vs %g %g %g\n",param.x(),param.y(), // e->getVertex(j)->x(),e->getVertex(j)->y(),e->getVertex(j)->z()); Pair<SVector3,SVector3> der = gf->firstDer(param); int XJ = j; int YJ = j + nbNodes; int ZJ = j + 2 * nbNodes; int UJ = j; int VJ = j + nbNodes; J(XJ,UJ) = der.first().x(); J(YJ,UJ) = der.first().y(); J(ZJ,UJ) = der.first().z(); J(XJ,VJ) = der.second().x(); J(YJ,VJ) = der.second().y(); J(ZJ,VJ) = der.second().z(); JT(UJ,XJ) = der.first().x(); JT(UJ,YJ) = der.first().y(); JT(UJ,ZJ) = der.first().z(); JT(VJ,XJ) = der.second().x(); JT(VJ,YJ) = der.second().y(); JT(VJ,ZJ) = der.second().z(); SVector3 ss = getSSL(e->getVertex(j)); GPoint gp = gf->point(param); D(XJ) = (gp.x() - ss.x()); D(YJ) = (gp.y() - ss.y()); D(ZJ) = (gp.z() - ss.z()); } }
void VarTest::testDynamicPair() { Pair<int> aPair; assert (0 == aPair.first()); try { std::string s = aPair.second().convert<std::string>(); fail ("must fail"); } catch (InvalidAccessException&) { } Var va(aPair); assert ("{ 0 : null }" == va.convert<std::string>()); aPair = Pair<int>(4, "123"); assert ("123" == aPair.second()); va = aPair; assert ("{ 4 : \"123\" }" == va.convert<std::string>()); int i = 1; std::string s = "2"; Pair<int> iPair(i, s); assert (1 == iPair.first()); assert ("2" == iPair.second()); Pair<std::string> sPair(s, i); assert ("2" == sPair.first()); assert (1 == sPair.second()); std::pair<int, std::string> p = std::make_pair(i, s); Pair<int> pPair(p); assert (1 == pPair.first()); assert ("2" == pPair.second()); Var vp(pPair); assert ("{ 1 : \"2\" }" == vp.convert<std::string>()); Var vs(sPair); assert ("{ \"2\" : 1 }" == vs.convert<std::string>()); }
LengthSize StyleBuilderConverter::convertRadius(StyleResolverState& state, CSSValue* value) { CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Pair* pair = primitiveValue->getPairValue(); Length radiusWidth = pair->first()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); Length radiusHeight = pair->second()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); float width = radiusWidth.value(); float height = radiusHeight.value(); ASSERT(width >= 0 && height >= 0); if (width <= 0 || height <= 0) return LengthSize(Length(0, Fixed), Length(0, Fixed)); return LengthSize(radiusWidth, radiusHeight); }
// Return the number of divisions in each direction for the face Pair<label> faceNij(const label facei, const block& block) { Pair<label> fnij; int i = facei/2; if (i == 0) { fnij.first() = block.meshDensity().y() + 1; fnij.second() = block.meshDensity().z() + 1; } else if (i == 1) { fnij.first() = block.meshDensity().x() + 1; fnij.second() = block.meshDensity().z() + 1; } else if (i == 2) { fnij.first() = block.meshDensity().x() + 1; fnij.second() = block.meshDensity().y() + 1; } return fnij; }
void CSSToStyleMap::mapFillYPosition(StyleResolverState& state, FillLayer* layer, CSSValue* value) { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Pair* pair = primitiveValue->getPairValue(); if (pair) primitiveValue = pair->second(); Length length = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()); layer->setYPosition(length); if (pair) layer->setBackgroundYOrigin(*(pair->first())); }
void CSSToStyleMap::mapFillYPosition(CSSPropertyID propertyID, FillLayer* layer, CSSValue* value) const { if (value->isInitialValue()) { layer->setYPosition(FillLayer::initialFillYPosition(layer->type())); return; } if (!value->isPrimitiveValue()) return; CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); Pair* pair = primitiveValue->getPairValue(); if (pair) { ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPositionY || propertyID == CSSPropertyWebkitMaskPositionY); primitiveValue = pair->second(); } Length length = primitiveValue->convertToLength<FixedConversion | PercentConversion>(cssToLengthConversionData()); layer->setYPosition(length); if (pair) layer->setBackgroundYOrigin(*(pair->first())); }
bool frameFieldBackgroundMesh2D::compute_RK_infos(double u,double v, double x, double y, double z, RK_form &infos) { // check if point is in domain if (!inDomain(u,v)) return false; // get stored angle double angle_current = angle(u,v); // compute t1,t2: cross field directions // get the unit normal at that point GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return false; } Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); SVector3 s1 = der.first(); SVector3 s2 = der.second(); SVector3 n = crossprod(s1,s2); n.normalize(); SVector3 basis_u = s1; basis_u.normalize(); SVector3 basis_v = crossprod(n,basis_u); // normalize vector t1 that is tangent to gf at uv SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ; t1.normalize(); // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame SVector3 t2 = crossprod(n,t1); t2.normalize(); // get metric double L = size(u,v); infos.metricField = SMetric3(1./(L*L)); FieldManager *fields = gf->model()->getFields(); if(fields->getBackgroundField() > 0) { Field *f = fields->get(fields->getBackgroundField()); if (!f->isotropic()) { (*f)(x,y,z, infos.metricField,gf); } else { L = (*f)(x,y,z,gf); infos.metricField = SMetric3(1./(L*L)); } } double M = dot(s1,s1); double N = dot(s2,s2); double E = dot(s1,s2); // compute the first fundamental form i.e. the metric tensor at the point // M_{ij} = s_i \cdot s_j double metric[2][2] = {{M,E},{E,N}}; // get sizes double size_1 = sqrt(1. / dot(t1,infos.metricField,t1)); double size_2 = sqrt(1. / dot(t2,infos.metricField,t2)); // compute covariant coordinates of t1 and t2 - cross field directions in parametric domain double covar1[2],covar2[2]; // t1 = a s1 + b s2 --> // t1 . s1 = a M + b E // t1 . s2 = a E + b N --> solve the 2 x 2 system // and get covariant coordinates a and b double rhs1[2] = {dot(t1,s1),dot(t1,s2)}; bool singular = false; if (!sys2x2(metric,rhs1,covar1)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g -- %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z(),size_1,size_2); covar1[1] = 1.0; covar1[0] = 0.0; singular = true; } double rhs2[2] = {dot(t2,s1),dot(t2,s2)}; if (!sys2x2(metric,rhs2,covar2)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z()); covar2[0] = 1.0; covar2[1] = 0.0; singular = true; } // transform the sizes with respect to the metric // consider a vector v of size 1 in the parameter plane // its length is sqrt (v^T M v) --> if I want a real size // of size1 in direction v, it should be sqrt(v^T M v) * size1 double l1 = sqrt(covar1[0]*covar1[0]+covar1[1]*covar1[1]); double l2 = sqrt(covar2[0]*covar2[0]+covar2[1]*covar2[1]); covar1[0] /= l1; covar1[1] /= l1; covar2[0] /= l2; covar2[1] /= l2; double size_param_1 = size_1 / sqrt ( M*covar1[0]*covar1[0]+ 2*E*covar1[1]*covar1[0]+ N*covar1[1]*covar1[1]); double size_param_2 = size_2 / sqrt ( M*covar2[0]*covar2[0]+ 2*E*covar2[1]*covar2[0]+ N*covar2[1]*covar2[1]); if (singular) { size_param_1 = size_param_2 = std::min (size_param_1,size_param_2); } // filling form... infos.t1 = t1; infos.h.first = size_1; infos.h.second = size_2; infos.paramh.first = size_param_1; infos.paramh.second = size_param_2; infos.paramt1 = SPoint2(covar1[0],covar1[1]); infos.paramt2 = SPoint2(covar2[0],covar2[1]); infos.angle = angle_current; infos.localsize = L; infos.normal = n; return true; }
void frameFieldBackgroundMesh2D::computeCrossField(simpleFunction<double> &eval_diffusivity) { angles.clear(); DoubleStorageType _cosines4,_sines4; list<GEdge*> e; GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return; } replaceMeshCompound(face, e); list<GEdge*>::const_iterator it = e.begin(); for( ; it != e.end(); ++it ) { if (!(*it)->isSeam(face)) { for(unsigned int i = 0; i < (*it)->lines.size(); i++ ) { MVertex *v[2]; v[0] = (*it)->lines[i]->getVertex(0); v[1] = (*it)->lines[i]->getVertex(1); SPoint2 p1,p2; reparamMeshEdgeOnFace(v[0],v[1],face,p1,p2); Pair<SVector3, SVector3> der = face->firstDer((p1+p2)*.5); SVector3 t1 = der.first(); SVector3 t2 = der.second(); SVector3 n = crossprod(t1,t2); n.normalize(); SVector3 d1(v[1]->x()-v[0]->x(),v[1]->y()-v[0]->y(),v[1]->z()-v[0]->z()); t1.normalize(); d1.normalize(); double _angle = myAngle (t1,d1,n); normalizeAngle (_angle); for (int i=0; i<2; i++) { DoubleStorageType::iterator itc = _cosines4.find(v[i]); DoubleStorageType::iterator its = _sines4.find(v[i]); if (itc != _cosines4.end()) { itc->second = 0.5*(itc->second + cos(4*_angle)); its->second = 0.5*(its->second + sin(4*_angle)); } else { _cosines4[v[i]] = cos(4*_angle); _sines4[v[i]] = sin(4*_angle); } } } } } propagateValues(_cosines4,eval_diffusivity,false); propagateValues(_sines4,eval_diffusivity,false); std::map<MVertex*,MVertex*>::iterator itv2 = _2Dto3D.begin(); for ( ; itv2 != _2Dto3D.end(); ++itv2) { MVertex *v_2D = itv2->first; MVertex *v_3D = itv2->second; double angle = atan2(_sines4[v_3D],_cosines4[v_3D]) / 4.0; normalizeAngle (angle); angles[v_2D] = angle; } }
Pair<A,B>::Pair(const Pair<A,B> & iP): _first(iP.first()), _second(iP.second()) {}
bool linearInterpolationWeights::integrationWeights ( const scalar t1, const scalar t2, labelList& indices, scalarField& weights ) const { if (t2 < t1-VSMALL) { FatalErrorIn("linearInterpolationWeights::integrationWeights(..)") << "Integration should be in positive direction." << " t1:" << t1 << " t2:" << t2 << exit(FatalError); } // Currently no fancy logic on cached index like in value //- Find lower or equal index label i1 = findLower(samples_, t1, 0, lessEqOp<scalar>()); //- Find lower index label i2 = findLower(samples_, t2); // For now just fail if any outside table if (i1 == -1 || i2 == samples_.size()-1) { FatalErrorIn("linearInterpolationWeights::integrationWeights(..)") << "Integrating outside table " << samples_[0] << ".." << samples_.last() << " not implemented." << " t1:" << t1 << " t2:" << t2 << exit(FatalError); } label nIndices = i2-i1+2; // Determine if indices already correct bool anyChanged = false; if (nIndices != indices.size()) { anyChanged = true; } else { // Closer check label index = i1; forAll(indices, i) { if (indices[i] != index) { anyChanged = true; break; } index++; } } indices.setSize(nIndices); weights.setSize(nIndices); weights = 0.0; // Sum from i1+1 to i2+1 for (label i = i1+1; i <= i2; i++) { scalar d = samples_[i+1]-samples_[i]; indices[i-i1] = i; weights[i-i1] += 0.5*d; indices[i+1-i1] = i+1; weights[i+1-i1] += 0.5*d; } // Add from i1 to t1 { Pair<scalar> i1Tot1 = integrationWeights(i1, t1); indices[0] = i1; weights[0] += i1Tot1.first(); indices[1] = i1+1; weights[1] += i1Tot1.second(); } // Subtract from t2 to i2+1 { Pair<scalar> wghts = integrationWeights(i2, t2); indices[i2-i1] = i2; weights[i2-i1] += -wghts.first(); indices[i2-i1+1] = i2+1; weights[i2-i1+1] += -wghts.second(); } return anyChanged; }
void DFS_M::dfs(int iRoot) { Stack2< Pair<int,int> > fringe; //Queue< Pair<int,int> > fringe; fringe.push(Pair<int,int>(-1,iRoot)); int precount = 0; // pre-order counter int poscount = 0; // post-order counter int inocount = 0; // in-order counter int P = -1; int forest=0; int cyclecount = 0; // number of cycles found so far while (precount < _graph.getVertexSize()) { while ( !fringe.empty() ) { Pair<int,int> pair = fringe.getTop(); fringe.pop(); int v0 = pair.first(); int v1 = pair.second(); if (v0==-2) { _postorder[v1]=poscount; ++poscount; continue; } if ( !_visited[v1] ) { // first time we see this vertex, push a dummy edge on the fringe // before pushing all its children. When the dummy edge will be popped // that means all the subtrees rooted under this vertex v1, will have been // explored completely, and we can assign the postorder index to the vertex fringe.push(Pair<int,int>(-2,v1)); _preorder[v1]=precount; ++precount; _visited[v1]=1; _parent[v1]=v0; _forest[v1]=forest; if ( v0 > -1 ) { _matrix[v0][v1]='T'; } //std::cout << "(" << v1 << ")" << std::endl; for ( GraphEdgeIter it = _graph.getEdgeIter(v1); !it.end(); ++it ) { int v2 = *it; if (!_visited[v2]) { fringe.push(Pair<int,int>(v1,v2)); } else { // already visited char edgeType = tagEdge(v1,v2); cycleCheck(edgeType, v1, v2, cyclecount); } } } else { // already visited char edgeType = tagEdge(v0,v1); cycleCheck(edgeType, v0, v1, cyclecount); } } if (fringe.empty() && precount<_graph.getVertexSize()) { for (int i=0; i<_graph.getVertexSize(); ++i) { if (!_visited[i]) { fringe.push(Pair<int,int>(-1,i)); break; } } ++forest; } } }