Edge* Graph::GetEdge(int index)
{
  if (EdgeCount() <= index)
    return 0;

  std::list<Edge*>::iterator iter = edges.begin();
  std::advance(iter, index);
  return *iter;
}
Beispiel #2
0
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;
}