Edge* Graph::GetEdge(int index) { if (EdgeCount() <= index) return 0; std::list<Edge*>::iterator iter = edges.begin(); std::advance(iter, index); return *iter; }
void RegionalTerrain_3r::SigPopFace(QuadEdge::Face* f) { // ignore loop, sliver, and quadrilateral topology if (EdgeCount(f) != 3) { return; } QuadEdge::FaceEdgeIterator edges(f); auto a = edges.next()->Org()->pos; auto b = edges.next()->Org()->pos; auto c = edges.next()->Org()->pos; SigPopVisualTriangle_3r(Triangle_3r(c, a, b)); }
ON_SubD* ON_SubDSectorType::SectorRingSubD( double radius, double sector_angle_radians, ON_SubD* subd ) const { if (subd) *subd = ON_SubD::Empty; if (!IsValid()) return ON_SUBD_RETURN_ERROR(nullptr); const unsigned int R = PointRingCount(); if (R < 3) return ON_SUBD_RETURN_ERROR(nullptr); const unsigned int F = FaceCount(); if ( F < 1) return ON_SUBD_RETURN_ERROR(nullptr); const unsigned int N = EdgeCount(); if (N < 2) return ON_SUBD_RETURN_ERROR(nullptr); if (F != N && F + 1 != N) return ON_SUBD_RETURN_ERROR(nullptr); const ON_SubD::SubDType subdivision_type = SubDType(); const ON_SubD::VertexTag vertex_tag = VertexTag(); const unsigned f_edge_count = ON_SubD::FacetEdgeCount(subdivision_type); if (3 != f_edge_count && 4 != f_edge_count) return ON_SUBD_RETURN_ERROR(nullptr); const unsigned int ring_ei_delta = f_edge_count - 2; if (nullptr == subd) subd = new ON_SubD; ON_SubD::VertexTag vertex_tag0; ON_SubD::VertexTag vertex_tag1; ON_SubD::EdgeTag edge_tag0; ON_SubD::EdgeTag edge_tag1; switch (vertex_tag) { case ON_SubD::VertexTag::Smooth: sector_angle_radians = 2.0*ON_PI; vertex_tag0 = ON_SubD::VertexTag::Smooth; vertex_tag1 = ON_SubD::VertexTag::Smooth; edge_tag0 = ON_SubD::EdgeTag::Smooth; edge_tag1 = ON_SubD::EdgeTag::Smooth; break; case ON_SubD::VertexTag::Crease: if ( !(sector_angle_radians > 0.0 && sector_angle_radians < 2.0*ON_PI) ) sector_angle_radians = 0.5*ON_PI; vertex_tag0 = ON_SubD::VertexTag::Crease; vertex_tag1 = ON_SubD::VertexTag::Crease; edge_tag0 = ON_SubD::EdgeTag::Crease; edge_tag1 = ON_SubD::EdgeTag::Crease; break; case ON_SubD::VertexTag::Corner: sector_angle_radians = CornerSectorAngleRadians(); vertex_tag0 = ON_SubD::VertexTag::Crease; vertex_tag1 = ON_SubD::VertexTag::Crease; edge_tag0 = ON_SubD::EdgeTag::Crease; edge_tag1 = ON_SubD::EdgeTag::Crease; break; case ON_SubD::VertexTag::Dart: sector_angle_radians = 2.0*ON_PI; vertex_tag0 = ON_SubD::VertexTag::Crease; vertex_tag1 = ON_SubD::VertexTag::Smooth; edge_tag0 = ON_SubD::EdgeTag::Crease; edge_tag1 = ON_SubD::EdgeTag::Smooth; break; default: return ON_SUBD_RETURN_ERROR(nullptr); break; } unsigned int sector_angle_index = ON_SubDSectorType::AngleIndexFromAngleRadians(sector_angle_radians); if (sector_angle_index <= ON_SubDSectorType::MaximumAngleIndex && fabs(ON_SubDSectorType::AngleRadiansFromAngleIndex(sector_angle_index) - sector_angle_radians) <= 1.0e-6 ) { sector_angle_radians = ON_SubDSectorType::AngleRadiansFromAngleIndex(sector_angle_index); } else { sector_angle_radians = ON_UNSET_UINT_INDEX; } const double smooth_edge_w0 = this->SectorWeight(); ON_SimpleArray< ON_SubDVertex* > V(R); ON_SimpleArray< ON_SubDEdge* > E(N); ON_3dPoint vertexP = ON_3dPoint::Origin; for (unsigned int vi = 0; vi < R; vi++) { ON_SubD::VertexTag vertex_tag_vi; if ( 0 == vi ) vertex_tag_vi = vertex_tag; // center vertex else if ( 1 == vi ) vertex_tag_vi = vertex_tag0; // first edge else if ( R == vi+1 && N > F ) vertex_tag_vi = vertex_tag1; // last edge else vertex_tag_vi = ON_SubD::VertexTag::Smooth; // interior edge or an outer face vertex if (radius > 0.0) { double cos_a, sin_a; if (sector_angle_index == ON_UNSET_UINT_INDEX) { double a = (vi / ((double)(R-1)))*sector_angle_radians; cos_a = cos(a); sin_a = sin(a); } else { ON_SubDMatrix::EvaluateCosAndSin(2*sector_angle_index*vi, (R-1)*ON_SubDSectorType::MaximumAngleIndex,&cos_a,&sin_a); } const double r = (3 == f_edge_count) || (1 == (vi%2)) ? radius : (2.0*radius); vertexP.x = r*cos_a; vertexP.y = r*sin_a; } ON_SubDVertex* vertex = subd->AddVertex( vertex_tag_vi, vertexP); V.Append(vertex); } //V[0]->m_vertex_edge_order = ON_SubD::VertexEdgeOrder::radial; for (unsigned int vei = 0; vei < N; vei++) { ON_SubD::EdgeTag edge_tag_vei; if ( 0 == vei ) edge_tag_vei = edge_tag0; // first edge else if ( vei+1 == N ) edge_tag_vei = edge_tag1; // last edge else edge_tag_vei = ON_SubD::EdgeTag::Smooth; // interior edge double w0 = (ON_SubD::EdgeTag::Smooth == edge_tag_vei) ? smooth_edge_w0 : ON_SubDSectorType::IgnoredSectorWeight; unsigned int ev1i = 1 + vei*ring_ei_delta; E.Append( subd->AddEdgeWithSectorCoefficients( edge_tag_vei, V[0], w0, V[ev1i], ON_SubDSectorType::IgnoredSectorWeight) ); } ON_SubDVertex* f_vertex[4] = {}; ON_SubDEdge* f_edge[4] = {}; ON_SubDEdgePtr f_edgeptr[4] = {}; f_vertex[0] = V[0]; f_vertex[f_edge_count - 1] = const_cast<ON_SubDVertex*>(E[0]->m_vertex[1]); f_edge[f_edge_count - 1] = E[0]; for (unsigned int vfi = 0; vfi < F; vfi++) { f_edge[0] = f_edge[f_edge_count - 1]; f_edge[f_edge_count-1] = E[(vfi + 1) % N]; f_vertex[1] = const_cast<ON_SubDVertex*>(f_edge[0]->m_vertex[1]); f_vertex[f_edge_count - 1] = const_cast<ON_SubDVertex*>(f_edge[f_edge_count - 1]->m_vertex[1]); f_edgeptr[0] = ON_SubDEdgePtr::Create(f_edge[0], 0); f_edgeptr[f_edge_count - 1] = ON_SubDEdgePtr::Create(f_edge[f_edge_count - 1], 1); if (4 == f_edge_count) { f_vertex[2] = V[2 + 2 * vfi]; f_edge[1] = subd->AddEdgeWithSectorCoefficients(ON_SubD::EdgeTag::Smooth, f_vertex[1], ON_SubDSectorType::IgnoredSectorWeight, f_vertex[2], ON_SubDSectorType::IgnoredSectorWeight); f_edge[2] = subd->AddEdgeWithSectorCoefficients(ON_SubD::EdgeTag::Smooth, f_vertex[2], ON_SubDSectorType::IgnoredSectorWeight, f_vertex[3], ON_SubDSectorType::IgnoredSectorWeight); f_edgeptr[1] = ON_SubDEdgePtr::Create(f_edge[1], 0); f_edgeptr[2] = ON_SubDEdgePtr::Create(f_edge[2], 0); } else { f_edge[1] = subd->AddEdgeWithSectorCoefficients(ON_SubD::EdgeTag::Smooth, f_vertex[1], ON_SubDSectorType::IgnoredSectorWeight, f_vertex[2], ON_SubDSectorType::IgnoredSectorWeight); f_edgeptr[1] = ON_SubDEdgePtr::Create(f_edge[1], 0); } subd->AddFace(f_edge_count, f_edgeptr); } return subd; }