Пример #1
0
static
bool ChangeTrimVertex( 
         ON_Brep& brep,
         ON_BrepTrim& trim,
         int trim_end,
         int old_vi,
         int new_vi,
         bool bUpdateEdge,
         bool bUpdateMates
         )
{
  // used by ON_Brep::ReplaceSurface() to change trim ends
  if ( trim_end != 0 && trim_end != 1 )
    return false;
  if ( trim.m_vi[trim_end] != old_vi )
    return false;
  if ( old_vi == new_vi )
    return true;
  trim.m_vi[trim_end] = new_vi;

  ON_BrepVertex* v = brep.Vertex(old_vi);
  if ( v )
    v->m_tolerance = ON_UNSET_VALUE;
  v = brep.Vertex(new_vi);
  if ( v )
    v->m_tolerance = ON_UNSET_VALUE;

  bool rc = true;
  if ( bUpdateEdge )
  {
    ON_BrepEdge* edge = brep.Edge(trim.m_ei);
    if ( 0 == edge )
      return true;
    int edge_end = trim.m_bRev3d ? 1-trim_end : trim_end;
    rc = ChangeEdgeVertex( brep, *edge, edge_end, old_vi, new_vi, bUpdateMates );
  }

  return true;
}
Пример #2
0
static
bool SplitSeam( ON_Brep& brep, 
                ON_BrepTrim& trimA, ON_BrepTrim& trimB,
                ON_BrepTrim& prevtrimB,
                ON_BrepTrim& nexttrimB,
                int vcount0 // number of verts before singular fixups
                )
{
  if ( trimA.m_trim_index == trimB.m_trim_index )
    return false;
  if ( trimA.m_trim_index == prevtrimB.m_trim_index )
    return false;
  if ( trimA.m_trim_index == nexttrimB.m_trim_index )
    return false;
  if ( trimB.m_trim_index == prevtrimB.m_trim_index )
    return false;
  if ( trimB.m_trim_index == nexttrimB.m_trim_index )
    return false;
  if ( prevtrimB.m_trim_index == nexttrimB.m_trim_index )
    return false;
  if ( trimA.m_type != ON_BrepTrim::seam )
    return false;
  if ( trimB.m_type != ON_BrepTrim::seam )
    return false;
  if ( trimA.m_ei != trimB.m_ei )
    return false;
  if (    trimA.m_vi[0] != trimB.m_vi[1] 
       && trimA.m_vi[0] < vcount0
       && trimB.m_vi[1] < vcount0 )
    return false;
  if (    trimA.m_vi[1] != trimB.m_vi[0] 
       && trimA.m_vi[1] < vcount0
       && trimB.m_vi[0] < vcount0 )
    return false;
  if ( prevtrimB.m_vi[1] != trimB.m_vi[0] 
       && prevtrimB.m_vi[1] < vcount0
       && trimB.m_vi[0] < vcount0 )
    return false;
  if ( nexttrimB.m_vi[0] != trimB.m_vi[1]
       && prevtrimB.m_vi[0] < vcount0
       && trimB.m_vi[1] < vcount0 )
    return false;
  if ( trimA.m_li != trimB.m_li )
    return false;
  if ( trimA.m_li != prevtrimB.m_li )
    return false;
  if ( trimA.m_li != nexttrimB.m_li )
    return false;
  if ( trimA.m_bRev3d == trimB.m_bRev3d )
    return false;
  const ON_Surface* srf = trimA.SurfaceOf();
  if ( 0 == srf )
    return false;
  ON_BrepEdge* edgeA = brep.Edge(trimA.m_ei);
  if ( 0 == edgeA )
    return false;
  if ( edgeA->m_ti.Count() != 2 )
    return false;
  if ( edgeA->m_ti[0] != trimA.m_trim_index && edgeA->m_ti[1] != trimA.m_trim_index )
    return false;
  if ( edgeA->m_ti[0] != trimB.m_trim_index && edgeA->m_ti[1] != trimB.m_trim_index )
    return false;

  // reserve space now so the vA0 and vA1 pointers
  // will be valid if m_V[] is grown.
  brep.m_V.Reserve( brep.m_V.Count()+2 );

  ON_BrepVertex* vA0 = brep.Vertex(trimA.m_vi[0]);
  if ( 0 == vA0 )
    return false;
  ON_BrepVertex* vA1 = brep.Vertex(trimA.m_vi[1]);
  if ( 0 == vA1 )
    return false;

  // looks like we have a valid seam to blow apart

  // get a new 3d curve for trimB
  ON_Curve* cB3 = PushUpIsoTrim( brep, trimB );
  if ( 0 == cB3 )
    return false;
  int c3i = brep.AddEdgeCurve(cB3);

  vA0->m_tolerance = ON_UNSET_VALUE;
  vA1->m_tolerance = ON_UNSET_VALUE;

  // make new vertices for trimB
  ON_BrepVertex* vB0 = 0;
  ON_BrepVertex* vB1 = 0;

  ON_3dPoint PA, PB;
  bool bSame = false;

  if (brep.GetTrim3dStart(trimB.m_trim_index, PB) && brep.GetTrim3dEnd(trimA.m_trim_index, PA))
    bSame = PB.DistanceTo(PA) < ON_ZERO_TOLERANCE;
  if (bSame || trimB.m_vi[0] != trimA.m_vi[1] )
  {
    // sing fixups have already blown apart this end
    vB0 = brep.Vertex( trimB.m_vi[0] );
  }

  bSame = false;
  if (brep.GetTrim3dStart(trimA.m_trim_index, PA) && brep.GetTrim3dEnd(trimB.m_trim_index, PB))
    bSame = PB.DistanceTo(PA) < ON_ZERO_TOLERANCE;
  if (bSame || trimB.m_vi[1] != trimA.m_vi[0] )
  {
    // sing fixups have already blown apart this end
    vB1 = brep.Vertex( trimB.m_vi[1] );
  }
  if ( 0 == vB0 )
  {
    ON_BrepVertex& v = brep.NewVertex();
    vB0 = &v;
    trimB.m_vi[0] = vB0->m_vertex_index;
  }
  if ( 0 == vB1 )
  {
    ON_BrepVertex& v = brep.NewVertex();
    vB1 = &v;
    trimB.m_vi[1] = vB1->m_vertex_index;
  }

  // disconnect edgeA and trimB
  trimB.m_ei = -1;
  if ( edgeA->m_ti[0] == trimB.m_trim_index )
    edgeA->m_ti.Remove(0);
  else if ( edgeA->m_ti[1] == trimB.m_trim_index )
    edgeA->m_ti.Remove(1);
  ChangeTrimVertex( brep, trimB, 0, vA1->m_vertex_index, vB0->m_vertex_index, true, true );
  ChangeTrimVertex( brep, trimB, 1, vA0->m_vertex_index, vB1->m_vertex_index, true, true );

  ChangeTrimVertex( brep, prevtrimB, 1, vA1->m_vertex_index, vB0->m_vertex_index, true, true );
  ChangeTrimVertex( brep, nexttrimB, 0, vA0->m_vertex_index, vB1->m_vertex_index, true, true );

  // make a new edgeB and connect it to trimB
  ON_BrepEdge& edgeB = brep.NewEdge( *vB0, *vB1, c3i );
  edgeA = 0; // pointer may be invalid after m_E[] grows

  edgeB.m_ti.Append(trimB.m_trim_index);
  trimB.m_ei = edgeB.m_edge_index;
  trimB.m_bRev3d = false;

  trimA.m_type = ON_BrepTrim::boundary;
  trimB.m_type = ON_BrepTrim::boundary;

  return true;
}
Пример #3
0
static
bool ChangeTrimSingToBdry( ON_Brep& brep, ON_BrepTrim& trim, ON_BrepTrim* nexttrim )
{
  if ( trim.m_vi[0] != trim.m_vi[1] )
    return false;
  if ( trim.m_type != ON_BrepTrim::singular )
    return false;
  if ( trim.m_ei >= 0 )
    return false;

  const ON_Surface* srf = trim.SurfaceOf();
  if ( 0 == srf )
    return false;

  brep.m_V.Reserve( brep.m_V.Count() + 1 );
  ON_BrepVertex* v0 = brep.Vertex(trim.m_vi[0]);
  if ( 0 == v0 )
    return false;

  // get new 3d curve
  ON_Curve* c3 = PushUpIsoTrim( brep, trim );
  if ( 0 == c3 )
    return false;

  // valid singular trim can be changed to non-singular trim


  // create new vertex for end of this trim
  v0->m_tolerance = ON_UNSET_VALUE;

  ON_BrepVertex* v1 = 0;

  if ( c3->IsClosed() )
  {
    // 3d edge is closed so start and end vertex are still the same.
    v1 = v0;
  }
  else
  {
    // new 3d edge is not closed, so the single singular vertex
    // needs to be "split" into two vertices.
    brep.NewVertex();
    v1 = brep.m_V.Last();
  }
  trim.m_vi[1] = v1->m_vertex_index;

  // update the start of the next trim to use new vertex
  if ( nexttrim && nexttrim->m_trim_index != trim.m_trim_index )
  {
    ChangeTrimVertex( brep, *nexttrim, 0, v0->m_vertex_index, v1->m_vertex_index, true, true );
  }              

  // make a new edge
  int ci = brep.AddEdgeCurve(c3);
  c3 = 0;
  ON_BrepEdge& edge = brep.NewEdge(*v0,*v1,ci);
  edge.m_tolerance = 0.0;

  // hook trim to new edge
  trim.m_type = ON_BrepTrim::boundary;
  trim.m_bRev3d = false;
  trim.m_ei = edge.m_edge_index;
  edge.m_ti.Append(trim.m_trim_index);

  return true;
}
Пример #4
0
static
bool ChangeTrimBdryToSing( ON_Brep& brep, ON_BrepTrim& trim, 
                           ON_BrepTrim* prevtrim, ON_BrepTrim* nexttrim )
{
  if ( trim.m_vi[0] == trim.m_vi[1] )
    return false;
  if ( trim.m_type == ON_BrepTrim::singular )
    return false;
  if ( trim.m_ei < 0 )
    return false;

  int vi0 = trim.m_vi[0];
  int vi1 = trim.m_vi[1];

  int sing_vi = vi0;

  ON_BrepVertex* v0 = brep.Vertex(vi0);
  if ( v0 )
    v0->m_tolerance = ON_UNSET_VALUE;
  ON_BrepVertex* v1 = brep.Vertex(vi1);
  if ( v1 )
    v1->m_tolerance = ON_UNSET_VALUE;

  ON_BrepEdge* edge = brep.Edge(trim.m_ei);
  if ( edge )
  {
    for ( int eti = 0; eti < edge->m_ti.Count(); eti++ )
    {
      if ( edge->m_ti[eti] == trim.m_trim_index )
      {
        edge->m_ti.Remove(eti);
        break;
      }
    }

    trim.m_ei = -1;
    if ( 0 == edge->m_ti.Count() )
    {
      brep.DeleteEdge( *edge, true );
    }
    else if ( 1 == edge->m_ti.Count() && ON_BrepTrim::seam == trim.m_type )
    {
      // change neighbor trim type
      ON_BrepTrim* other_trim = brep.Trim(edge->m_ti[0]);
      if ( 0 != other_trim && ON_BrepTrim::seam == other_trim->m_type )
      {
        other_trim->m_type = ON_BrepTrim::boundary;
        int j = (trim.m_bRev3d == other_trim->m_bRev3d) ? 0 : 1;
        if (    trim.m_vi[0] == other_trim->m_vi[j] 
             && trim.m_vi[1] == other_trim->m_vi[1-j] )
        {
          // we need a new singular vertex
          sing_vi = brep.NewVertex(ON_UNSET_POINT).m_vertex_index;
        }
      }
    }
  }

  trim.m_vi[0] = sing_vi;
  trim.m_vi[1] = sing_vi;
  trim.m_type = ON_BrepTrim::singular;
  trim.m_bRev3d = false;

  if ( nexttrim )
    ChangeTrimVertex( brep,*nexttrim,0,vi1,sing_vi,true,true);
  if ( prevtrim )
    ChangeTrimVertex( brep,*prevtrim,1,vi0,sing_vi,true,true);

  return true;
}
Пример #5
0
static
bool ChangeEdgeVertex( 
         ON_Brep& brep,
         ON_BrepEdge& edge,
         int edge_end,
         int old_vi,
         int new_vi,
         bool bUpdateTrims
         )
{
  // used by ON_Brep::ReplaceSurface() to change edge ends

  if ( edge_end != 0 && edge_end != 1 )
    return false;
  if ( edge.m_vi[edge_end] != old_vi )
    return false;
  if ( old_vi == new_vi )
    return true;

  ON_BrepVertex* old_v = brep.Vertex(old_vi);
  if ( old_vi >= 0 && 0 == old_v )
    return false;
  if ( old_v )
    old_v->m_tolerance = ON_UNSET_VALUE;
  
  ON_BrepVertex* new_v = brep.Vertex(new_vi);
  if ( new_vi >= 0 && 0 == new_v )
    return false;
  if ( new_v )
    old_v->m_tolerance = ON_UNSET_VALUE;

  // disconnect edge from old vertex
  if ( old_vi >= 0 )
  {
    for ( int vei = 0; vei < old_v->m_ei.Count(); vei++ )
    {
      if ( old_v->m_ei[vei] == edge.m_edge_index )
      {
        old_v->m_ei.Remove(vei);
        break;
      }
    }
  }

  edge.m_vi[edge_end] = new_vi;
  new_v->m_ei.Append(edge.m_edge_index);

  if ( bUpdateTrims )
  {
    for ( int eti = 0; eti < edge.m_ti.Count(); eti++ )
    {
      ON_BrepTrim* trim = brep.Trim(edge.m_ti[eti]);
      if ( 0 == trim )
        continue;
      int trim_end = trim->m_bRev3d ? 1-edge_end : edge_end;
      if ( trim->m_vi[trim_end] == old_vi )
        trim->m_vi[trim_end] = new_vi;
    }
  }

  return true;
}