Exemplo n.º 1
0
ON_OffsetSurface::ON_OffsetSurface( const ON_OffsetSurface& src)
    : ON_SurfaceProxy(src),
      m__pSrf(0),
      m_offset_function(src.m_offset_function)
{
    if ( 0 != src.m__pSrf )
    {
        m__pSrf = src.ON_SurfaceProxy::DuplicateSurface();
        SetProxySurface(m__pSrf);
    }
    m_offset_function.SetBaseSurface( BaseSurface() );
}
Exemplo n.º 2
0
ON_OffsetSurface& ON_OffsetSurface::operator=(const ON_OffsetSurface& src)
{
    if ( this != &src )
    {
        if ( 0 != m__pSrf && this != m__pSrf )
            delete m__pSrf;
        m__pSrf = 0;
        if ( 0 != src.m__pSrf )
        {
            m__pSrf = src.ON_SurfaceProxy::DuplicateSurface();
            SetProxySurface(m__pSrf);
        }
        else
        {
            ON_SurfaceProxy::operator=(src);
        }
        m_offset_function = src.m_offset_function;
        m_offset_function.SetBaseSurface( BaseSurface() );
    }
    return *this;
}
Exemplo n.º 3
0
bool ON_BrepFace::ChangeSurface(
  int si
  )
{
  if ( 0 == m_brep )
    return false;
  if ( si < 0 || si >= m_brep->m_S.Count() )
    return false;
  const ON_Surface* pSurface = m_brep->m_S[si];
  
  m_brep->DestroyMesh( ON::any_mesh );

  const ON_Surface* old_srf = SurfaceOf();
  m_si = si;
  SetProxySurface(pSurface);
  if ( pSurface )
    m_bbox = pSurface->BoundingBox();
  else
    m_bbox.Destroy();
  m_brep->m_bbox.Destroy();

  if ( old_srf && pSurface )
  {
    // If domain changed, tehn update 2d trim curve locations
    ON_Interval udom0 = old_srf->Domain(0);
    ON_Interval vdom0 = old_srf->Domain(1);
    ON_Interval udom1 = pSurface->Domain(0);
    ON_Interval vdom1 = pSurface->Domain(1);
    if ( udom0 != udom1 || vdom0 != vdom1 )
    {
      // need to transform trimming curves
      ON_Xform x(1), xu(1), xv(1);
      if ( udom0 != udom1 )
        xu.IntervalChange(0,udom0,udom1);
      if ( vdom0 != vdom1 )
        xv.IntervalChange(1,vdom0,vdom1);
      x = xv*xu;
      TransformTrim(x);
    }

    int vcount0 = m_brep->m_V.Count();

    // If singular points changed, then add/remove edges
    // and update trim.m_type flags
    int i;
    {
      bool bSing0[4];
      bool bSing1[4];
      for ( i = 0; i < 4; i++ )
      {
        bSing0[i] = old_srf->IsSingular(i) ? true : false;
        bSing1[i] = pSurface->IsSingular(i) ? true : false;
      }
      int sing_fix, sing_fix_max = 1;
      for ( sing_fix = 0; sing_fix < sing_fix_max; sing_fix++ )
      {
        // sing_fix:
        //   0: expands old singularities and checks for new ones
        //   1: collapses old edges to new singular points.
        for ( i = 0; i < 4; i++ )
        {
          if ( bSing0[i] == bSing1[i] )
            continue;

          ON_Surface::ISO iso = ON_Surface::not_iso;
          switch(i)
          {
          case 0: iso = ON_Surface::S_iso; break;
          case 1: iso = ON_Surface::E_iso; break;
          case 2: iso = ON_Surface::N_iso; break;
          case 3: iso = ON_Surface::W_iso; break;
          }

          if ( bSing0[i] && sing_fix != 0 )
          {
            // we already expanded old singular trims into edge trims
            continue;
          }

          for ( int fli = 0; fli < m_li.Count(); fli++ )
          {
            const ON_BrepLoop* loop = Loop(fli);
            if ( 0 == loop )
              continue;
            if ( loop->m_type != ON_BrepLoop::outer )
              continue;
            for ( int lti = 0; lti < loop->m_ti.Count(); lti++ )
            {
              ON_BrepTrim* trim = loop->Trim(lti);
              if ( !trim )
                continue;
              if ( trim->m_iso != iso )
                continue;
              ON_BrepTrim* nexttrim = loop->Trim((lti+1)%loop->m_ti.Count());
              if ( bSing0[i] )
              {
                // valid singular trim changing to non-singular trim
                if( 0 == sing_fix )
                  ChangeTrimSingToBdry( *m_brep, *trim, nexttrim );
              }
              else if ( bSing1[i] )
              {
                if ( 0 == sing_fix )
                {
                  // we need a 2nd pass to collapse this edge
                  // to a singular trim.
                  sing_fix_max = 2;
                }
                else
                {
                  // valid non-singular trim changing to singular trim
                  ON_BrepTrim* prevtrim = loop->Trim((lti-1+loop->m_ti.Count())%loop->m_ti.Count());
                  ChangeTrimBdryToSing( *m_brep, *trim, prevtrim, nexttrim );
                }
              }
            }
          }
        }
      }
    }

    // If closed/open status changed, then add/remove edges
    // and update m_type flag
    for ( i = 0; i < 2; i++ )
    {
      bool bClosed0 = old_srf->IsClosed(i) ? true : false;
      bool bClosed1 = pSurface->IsClosed(i) ? true : false;
      if ( bClosed0 == bClosed1 )
        continue;
      ON_Surface::ISO isoA = ON_Surface::not_iso;
      ON_Surface::ISO isoB = ON_Surface::not_iso;
      switch(i)
      {
      case 0: isoA = ON_Surface::W_iso; isoB = ON_Surface::E_iso; break;
      case 1: isoA = ON_Surface::S_iso; isoB = ON_Surface::N_iso; break;
      }

      for ( int fli = 0; fli < m_li.Count(); fli++ )
      {
        const ON_BrepLoop* loop = Loop(fli);
        if ( 0 == loop )
          continue;
        if ( loop->m_type != ON_BrepLoop::outer )
          continue;
        int loop_trim_count = loop->m_ti.Count();
        for ( int ltiA = 0; ltiA < loop_trim_count; ltiA++ )
        {
          ON_BrepTrim* trimA = loop->Trim(ltiA);
          if ( !trimA )
            continue;
          if ( trimA->m_iso != isoA )
            continue;

          if ( bClosed0 )
          {
            // old surface has a seam and new surface does not
            if ( trimA->m_type != ON_BrepTrim::seam )
              continue;
            const ON_BrepEdge* edge = m_brep->Edge(trimA->m_ei);
            if ( 0 == edge )
              continue;
            if ( edge->m_ti.Count() != 2 )
              continue;
            int etiB = (edge->m_ti[0] == trimA->m_trim_index) ? 1 : 0;
            ON_BrepTrim* trimB = edge->Trim(etiB);
            if ( 0 == trimB )
              continue;
            if ( trimA == trimB )
              continue;
            if ( trimB->m_li != trimA->m_li )
              continue;
            if ( trimB->m_type != ON_BrepTrim::seam )
              continue;
            if ( trimB->m_iso != isoB )
              continue;
            for ( int ltiB = 0; ltiB < loop_trim_count; ltiB++ )
            {
              if ( trimB != loop->Trim(ltiB) )
                continue;
              ON_BrepTrim* prevtrimB = loop->Trim((ltiB+loop_trim_count-1)%loop_trim_count);
              ON_BrepTrim* nexttrimB = loop->Trim((ltiB+1)%loop_trim_count);
              if ( 0 == prevtrimB )
                continue;
              if ( 0 == nexttrimB )
                continue;
              if ( prevtrimB == trimA || prevtrimB == trimB )
                continue;
              if ( nexttrimB == trimA || nexttrimB == trimB )
                continue;
              if ( prevtrimB == nexttrimB )
                continue;
              SplitSeam( *m_brep, *trimA, *trimB, *prevtrimB, *nexttrimB, vcount0 );
              break;
            }
          }
          else
          {
            // open sides replaced with a seam
            // TODO
            bool sok;
            sok = SealSeam(i, *this);
            if (sok)
              sok = !sok;
          }
        }
      }
    }
  }

  if ( pSurface )
  {
    for ( int fli = 0; fli < m_li.Count(); fli++ )
    {
      const ON_BrepLoop* loop = Loop(fli);
      if ( 0 == loop )
        continue;
      for ( int lti = 0; lti < loop->m_ti.Count(); lti++ )
      {
        const ON_BrepTrim* trim = loop->Trim(lti);
        if ( 0 ==  trim )
          continue;
        ON_BrepVertex* v0 = m_brep->Vertex(trim->m_vi[0]);
        if ( 0 != v0 )
        {
          if ( v0->point == ON_UNSET_POINT )
          {
            ON_3dPoint uv = trim->PointAtStart();
            v0->point = pSurface->PointAt( uv.x, uv.y );
          }
        }
      }
    }
  }

  return true;
}