コード例 #1
0
static bool SealSeam(int closed_dir, ON_BrepFace& F)

{
  if (closed_dir) closed_dir = 1;
  int seam_dir = 1-closed_dir;
  ON_Brep* pBrep = F.Brep();
  if (!pBrep) return false;
  const ON_Surface* pSrf = F.SurfaceOf();
  if (!pSrf || !pSrf->IsClosed(closed_dir)) return false;

  ON_Surface::ISO isoA = ON_Surface::not_iso;//same dir as isocurve
  ON_Surface::ISO isoB = ON_Surface::not_iso;//opposite dir as isocurve
  if (closed_dir){
    isoA = ON_Surface::S_iso;
    isoB = ON_Surface::N_iso;
  }
  else {
    isoA = ON_Surface::E_iso;
    isoB = ON_Surface::W_iso;
  }

  /* TODO: Handle cases where there is more than one trim on a seam side 
     or seam edges do not fully overlap.
  */

  //Look for a single pair of trims that match across parameter space.

  int A_id = -1;
  int B_id = -1;

  int li;
  for (li=0; li<F.m_li.Count(); li++){
    const ON_BrepLoop* L = F.Loop(li);
    if (!L || L->m_type !=  ON_BrepLoop::outer) continue;
    int lti;
    for (lti = 0; lti<L->m_ti.Count(); lti++ ){
      ON_BrepTrim* T = L->Trim(lti);
      if (!T) continue;
      if (T->m_iso == isoA) {
        if (A_id >= 0)
          return false;
        A_id = T->m_trim_index;
      }
      else if (T->m_iso == isoB) {
        if (B_id >= 0)
          return false;
        B_id = T->m_trim_index;
      }
    }
  }

  if (A_id < 0 || B_id < 0)
    return true;//no seam to join

  ON_BrepTrim& TA = pBrep->m_T[A_id];
  ON_BrepTrim& TB = pBrep->m_T[B_id];

  ON_BrepEdge* pEA = TA.Edge();
  ON_BrepEdge* pEB = TB.Edge();
  if (!pEA || !pEB)
    return false;

  ON_Interval a,b;
  int i;
  for (i=0; i<2; i++){
    a[i] = TA.PointAt(TA.Domain()[i])[seam_dir];
    b[i] = TB.PointAt(TB.Domain()[i])[seam_dir];
  }

  a.MakeIncreasing();
  b.MakeIncreasing();

  if (a[0] >= b[1] || b[0] >= a[1])
    return true; //nothing to be joined;

  double pspace_tol = 1.0e-8;

  if (a.Length() < 10.0*pspace_tol)
    return false;
  if (fabs(a[0] - b[0]) > pspace_tol || fabs(a[1] - b[1]) > pspace_tol)
    return false;

  //fix vertices so join will work.

  RebuildVertexToTrimEnd(TA, 0);
  RebuildVertexToTrimEnd(TA, 1);
  RebuildVertexToTrimEnd(TB, 0);
  RebuildVertexToTrimEnd(TB, 1);

  double join_tol = 1.0e-6;
  if (!pBrep->JoinEdges(*pEA, *pEB, join_tol))
    return false;

  TA.m_type = ON_BrepTrim::seam;
  TB.m_type = ON_BrepTrim::seam;

  return true;
}