Beispiel #1
0
ON_BOOL32 
ON_Geometry::GetBoundingBox( // returns true if successful
       ON_3dPoint& boxmin,
       ON_3dPoint& boxmax,
       ON_BOOL32 bGrowBox
       ) const
{
  ON_Workspace ws;
  const int dim = Dimension();
  double *bmin, *bmax;
  if ( dim <= 3 ) {
    bmin = &boxmin.x;
    bmax = &boxmax.x;
  }
  else {
    bmin = ws.GetDoubleMemory(dim*2);
    bmax = bmin+dim;
    memset( bmin, 0, 2*dim*sizeof(*bmin) );
    if ( bGrowBox ) {
      bmin[0] = boxmin.x; bmin[1] = boxmin.y; bmin[1] = boxmin.z;
      bmax[0] = boxmax.x; bmax[1] = boxmax.y; bmax[1] = boxmax.z;
    }
  }
	// Treat invalid box on input as empty
	bool invalid=false;	//input box invalid=empty
	if(bGrowBox)
		invalid =  boxmin.x>boxmax.x || boxmin.y>boxmax.y|| boxmin.z>boxmax.z;
	if(bGrowBox && invalid)
		bGrowBox=false;

  const ON_BOOL32 rc = GetBBox( bmin, bmax, bGrowBox );
  if ( dim > 3 ) {
    boxmin.x = bmin[0]; boxmin.y = bmin[1]; boxmin.z = bmin[2];
    boxmax.x = bmax[0]; boxmax.y = bmax[1]; boxmax.z = bmax[2];
  }
  else if ( dim <= 2 ) {
    boxmin.z = 0.0;
    boxmax.z = 0.0;
    if ( dim <= 1 ) {
      boxmin.y = 0.0;
      boxmax.y = 0.0;
    }
  }
  return rc;
}
static bool Dump3dmFileHelper( 
        const wchar_t* sFileName, // full name of file
        ON_TextLog& dump
        )
{
  dump.Print("====== FILENAME: %ls\n",sFileName);
  ON_Workspace ws;
  FILE* fp = ws.OpenFile( sFileName, L"rb" ); // file automatically closed by ~ON_Workspace()
  if ( !fp ) {
    dump.Print("**ERROR** Unable to open file.\n");
    return false;
  }

  ON_BinaryFile file( ON::read3dm, fp );

  int version = 0;
  ON_String comment_block;
  ON_BOOL32 rc = file.Read3dmStartSection( &version, comment_block );
  if (!rc) {
    dump.Print("**ERROR** Read3dmStartSection() failed\n");
    return false;
  }
  dump.Print("====== VERSION: %d\n",version );
  dump.Print("====== COMMENT BLOCK:\n",version );
  dump.PushIndent();
  dump.Print(comment_block);
  dump.PopIndent();
  dump.Print("====== CHUNKS:\n",version );
  unsigned int typecode;
  while ( !file.AtEnd() ) {
    typecode = file.Dump3dmChunk( dump, 0 );
    if ( !typecode )
      break;
    if ( typecode == TCODE_ENDOFFILE )
      break;
  }
  dump.Print("====== FINISHED: %ls\n",sFileName);

  return true;
}
CRhinoCommand::result CCommandSampleCageEdit::RunCommand( const CRhinoCommandContext& context )
{
  ON_Workspace ws;
  CRhinoCommand::result rc = CRhinoCommand::success;
 
  // Get the captive object
  CRhinoGetObject go;
  go.SetCommandPrompt( L"Select captive surface or polysurface" );
  go.SetGeometryFilter( CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object );
  go.GetObjects( 1, 1 );
  rc = go.CommandResult();
  if( CRhinoCommand::success != rc )
    return rc;
 
  const CRhinoObject* captive = go.Object(0).Object();
  if( 0 == captive )
    return CRhinoCommand::failure;
 
  // Define the control line
  ON_Line line;
  CArgsRhinoGetLine args;
  rc = RhinoGetLine( args, line );
  if( CRhinoCommand::success != rc )
    return rc;
 
  // Get the curve parameters
  int degree = 3;
  int cv_count = 4;
  for(;;)
  {
    CRhinoGetOption gl;
    gl.SetCommandPrompt( L"NURBS Parameters" );
    gl.AcceptNothing();
    int d_opt = gl.AddCommandOptionInteger( RHCMDOPTNAME(L"Degree"), &degree, L"Curve degree", 1.0, 100.0 );
    int p_opt = gl.AddCommandOptionInteger( RHCMDOPTNAME(L"PointCount"), &cv_count, L"Number of control points", 2.0, 100.0 );
    gl.GetOption();
    rc = gl.CommandResult();
    if( CRhinoCommand::success != rc )
      return rc;
 
    if( CRhinoGet::nothing == gl.Result() )
      break;
 
    if( cv_count <= degree )
    {
      if( CRhinoGet::option != gl.Result() )
        continue;
      const CRhinoCommandOption* opt = go.Option();
      if( 0 == opt )
        continue;
      if( d_opt == opt->m_option_index )
        cv_count = degree + 1;
      else 
        degree = cv_count - 1;
    }
  }
 
  // Set up morph control
  ON_MorphControl* control = new ON_MorphControl();
  control->m_varient = 1; // 1= curve
 
  // Specify the source line curve
  control->m_nurbs_curve0.Create( 3, false, 2, 2 );
  control->m_nurbs_curve0.MakeClampedUniformKnotVector();
  control->m_nurbs_curve0.SetCV( 0, line.from );
  control->m_nurbs_curve0.SetCV( 1, line.to );
 
  // Specify the destination NURBS curve
  control->m_nurbs_curve.Create( 3, false, degree + 1, cv_count );
  control->m_nurbs_curve.MakeClampedUniformKnotVector();
  double* g = ws.GetDoubleMemory( control->m_nurbs_curve.m_cv_count );
  control->m_nurbs_curve.GetGrevilleAbcissae( g );
  ON_Interval d = control->m_nurbs_curve.Domain();
  double s = 0.0;
  int i;
  for( i = 0; i < control->m_nurbs_curve.m_cv_count; i++ )
  {
    s = d.NormalizedParameterAt( g[i] );
    control->m_nurbs_curve.SetCV( i, line.PointAt(s) );
  }
 
  // Make sure domains match
  s = line.Length();
  if( s > ON_SQRT_EPSILON )
    control->m_nurbs_curve0.SetDomain( 0.0, s );
  d = control->m_nurbs_curve0.Domain();
  control->m_nurbs_curve.SetDomain( d[0], d[1] );
 
  // Create the morph control object
  CRhinoMorphControl* control_object = new CRhinoMorphControl();
  control_object->SetControl( control );
  context.m_doc.AddObject( control_object );
 
  // Set up the capture
  RhinoCaptureObject( control_object, const_cast<CRhinoObject*>(captive) );
 
  // Clean up display
  context.m_doc.UnselectAll();
 
  // Turn on the control grips
  control_object->EnableGrips( true );
  context.m_doc.Redraw( CRhinoView::mark_display_hint );
 
  return rc;
}
Beispiel #4
0
bool ON_Matrix::Invert( double zero_tolerance )
{
  ON_Workspace ws;
  int i, j, k, ix, jx, rank;
  double x;
  const int n = MinCount();
  if ( n < 1 )
    return false;

  ON_Matrix I(m_col_count, m_row_count);

  int* col = ws.GetIntMemory(n);

  I.SetDiagonal(1.0);
  rank = 0;

  double** this_m = ThisM();

  for ( k = 0; k < n; k++ ) {
    // find largest value in sub matrix
    ix = jx = k;
    x = fabs(this_m[ix][jx]);
    for ( i = k; i < n; i++ ) {
      for ( j = k; j < n; j++ ) {
        if ( fabs(this_m[i][j]) > x ) {
          ix = i;
          jx = j;
          x = fabs(this_m[ix][jx]);
        }
      }
    }

    SwapRows( k, ix );
    I.SwapRows( k, ix );

    SwapCols( k, jx );
    col[k] = jx;

    if ( x <= zero_tolerance ) {
      break;
    }
    x = 1.0/this_m[k][k];
    this_m[k][k] = 1.0;
    ON_ArrayScale( m_col_count-k-1, x, &this_m[k][k+1], &this_m[k][k+1] );
    I.RowScale( k, x );

    // zero this_m[!=k][k]'s 
    for ( i = 0; i < n; i++ ) {
      if ( i != k ) {
        x = -this_m[i][k];
        this_m[i][k] = 0.0;
        if ( fabs(x) > zero_tolerance ) {
          ON_Array_aA_plus_B( m_col_count-k-1, x, &this_m[k][k+1], &this_m[i][k+1], &this_m[i][k+1] );
          I.RowOp( i, x, k );
        }
      }
    }
  }

  // take care of column swaps
  for ( i = k-1; i >= 0; i-- ) {
    if ( i != col[i] )
      I.SwapRows(i,col[i]);
  }

  *this = I;

  return (k == n) ? true : false;
}
Beispiel #5
0
void ON_TextLog::PrintWrappedText( const wchar_t* s, int line_length )
{
  ON_Workspace ws;
  if ( s && *s && line_length > 0 ) {
    const int max_line_length = line_length+255;
    wchar_t* sLine = (wchar_t*)ws.GetMemory((max_line_length+1)*sizeof(*sLine));
    const int wrap_length = line_length;
    int i  = 0;
    int i1 = 0;
    int isp = 0;
    ON_BOOL32 bPrintLine = false;
    while ( s[i] ) {
      i1 = i;
      if ( s[i] == 10 || s[i] == 13 ) {
        // hard break at CR or LF
        i++;
        if ( s[i] == 10 && s[i-1] == 13 ) {
          // it's a CR+LF hard end of line - skip LF too
          i++;
        }      
        bPrintLine = true;
      }
      else if ( i && s[i] == 32 ) {
        if ( !isp ) {
          isp = i++;
        }
        if ( i < wrap_length ) {
          isp = i++;
        }
        else {
          bPrintLine = true;
          if ( isp ) {
            i1 = i = isp;
            while ( s[i] == 32 )
              i++;
          }
          else {
            i++;
          }
        }
      }
      else {
        i++;
      }
      if ( bPrintLine ) {
        if ( i1 >= max_line_length )
          i1 = max_line_length-1;
        if ( i1 > 0 ) {
          wsncpy( sLine, s, i1 );
          sLine[i1] = 0;
          Print( "%S\n", sLine );
        }
        else {
          Print("\n");
        }

        s += i;
        i = i1 = isp = 0;
        bPrintLine = false;
      }
    }
    if ( s[0] ) {
      Print( "%S", s );
    }
  }
}
Beispiel #6
0
void ON_InstanceDefinition::UpdateLinkedIdefReferenceFileLayerSettings( unsigned int layer_count, ON_Layer** layer_settings )
{
  ON__IDefLayerSettingsUserData* ud;

  if ( layer_count <= 0 || 0 == layer_settings )
  {
    // delete linked idef layer settings
    ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,false);
    if ( 0 != ud )
      delete ud;
    return;
  }

  // Create an index_map[] into the layer_settings[] array that is sorted
  // by layer_settings[]->m_layer_id
  ON_Workspace ws;
  int* index_map = (int*)ws.GetMemory(layer_count*sizeof(index_map[0]));
  ON_Sort(ON::quick_sort,index_map,layer_settings,layer_count,sizeof(layer_settings[0]),compareLayerPtrId);

  // Use index_map[] to get a unique list of layers with valid ids
  ON_UuidIndex* iddex = (ON_UuidIndex*)ws.GetMemory(layer_count*sizeof(iddex[0]));
  unsigned int iddex_count = 0;
  unsigned int i;
  ON_Layer* layer;
  for ( i = 0; i < layer_count; i++ )
  {
    layer = layer_settings[index_map[i]];
    if ( 0 == layer )
      continue;
    layer->SaveSettings(0,false); // remove any saved settings on input layers
    if ( ON_UuidIsNil(layer->m_layer_id) )
      continue;
    if ( iddex_count > 0 && iddex[iddex_count-1].m_id == layer->m_layer_id )
      continue;
    iddex[iddex_count].m_i = index_map[i];
    iddex[iddex_count].m_id = layer->m_layer_id;
    iddex_count++;
  }

  if ( iddex_count <= 0 )
  {
    // delete settings
    UpdateLinkedIdefReferenceFileLayerSettings(0,0);
    return;
  }

  // Create or get user data where the saved layer settings
  // are stored.
  ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,true);
  if ( 0 == ud )
    return;
    
  // Go through the saved settings that were previously
  // on this idef apply those settings to the layer_settings[]
  // list. Then delete the information from ud->m_layers[].
  ON_UuidIndex idx;
  idx.m_i = 0;
  unsigned int settings;
  for ( i = 0; i < ud->m_layers.UnsignedCount(); i++ )
  {
    if ( 0 == ud->m_layers[i] )
      continue;
    layer = ud->m_layers[i];
    ud->m_layers[i] = 0;
    for(;;)
    {
      settings = layer->SavedSettings();
      if ( 0 == settings )
        break; // no settings were modified
      idx.m_id = layer->m_layer_id;
      const ON_UuidIndex* idx0 = (const ON_UuidIndex*)bsearch(&idx,iddex,iddex_count,sizeof(iddex[0]),compareUuidIndexId);
      if ( 0 == idx0)
        break; // this layer is not in the current layer_settings[] list
      layer_settings[idx0->m_i]->SaveSettings(settings,false); // saves the layer settings found in linked file
      layer_settings[idx0->m_i]->Set(settings,*layer);   // applies modifications found on idef
      break;
    }
    delete layer;
  }

  // Save a copy of this information on the user data
  // so it will persist in the file containing the idef.
  ud->m_layers.SetCount(0);
  ud->m_layers.Reserve(iddex_count);
  for ( i = 0; i < iddex_count; i++ )
  {
    layer = new ON_Layer( *layer_settings[iddex[i].m_i] );
    ud->m_layers.Append(layer);
  }
}
bool ON_BrepExtrude( 
          ON_Brep& brep,
          const ON_Curve& path_curve,
          bool bCap
          )
{
  ON_Workspace ws;
  const int vcount0 = brep.m_V.Count();
  const int tcount0 = brep.m_T.Count();
  const int lcount0 = brep.m_L.Count();
  const int ecount0 = brep.m_E.Count();
  const int fcount0 = brep.m_F.Count();

  const ON_3dPoint PathStart = path_curve.PointAtStart();
  ON_3dPoint P = path_curve.PointAtEnd();
  if ( !PathStart.IsValid() || !P.IsValid() )
    return false;
  const ON_3dVector height = P - PathStart;
  if ( !height.IsValid() || height.Length() <= ON_ZERO_TOLERANCE )
    return false;

  ON_Xform tr;
  tr.Translation(height);

  // count number of new sides
  int side_count = 0;
  int i, vi, ei, fi;
  bool* bSideEdge = (bool*)ws.GetIntMemory(ecount0*sizeof(bSideEdge[0]));
  for ( ei = 0; ei < ecount0; ei++ )
  {
    const ON_BrepEdge& e = brep.m_E[ei];
    if ( 1 == e.m_ti.Count() )
    {
      side_count++;
      bSideEdge[ei] = true;
    }
    else
    {
      bSideEdge[ei] = false;
    }
  }

  brep.m_V.Reserve( 2*vcount0 );
  i = 4*side_count + (bCap?tcount0:0);
  brep.m_T.Reserve( tcount0 + i );
  brep.m_C2.Reserve( brep.m_C2.Count() + i );
  brep.m_L.Reserve( lcount0 + side_count + (bCap?lcount0:0) );
  i = side_count + (bCap?ecount0:side_count);
  brep.m_E.Reserve( ecount0 + i );
  brep.m_C3.Reserve( brep.m_C3.Count() + i );
  i = side_count + (bCap?fcount0:0);
  brep.m_F.Reserve( fcount0 + i );
  brep.m_S.Reserve( brep.m_S.Count() + i );

  bool bOK = true;

  // build top vertices
  int* topvimap = ws.GetIntMemory(vcount0);
  memset(topvimap,0,vcount0*sizeof(topvimap[0]));
  if ( bCap )
  {
    for ( vi = 0; vi < vcount0; vi++ )
    {
      const ON_BrepVertex& bottomv = brep.m_V[vi];
      ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
      topvimap[vi] = topv.m_vertex_index;
    }
  }
  else
  {
    for ( ei = 0; ei < ecount0; ei++ )
    {
      if ( bSideEdge[ei] )
      {
        const ON_BrepEdge& bottome = brep.m_E[ei];
        int bottomvi0 = bottome.m_vi[0];
        if ( bottomvi0 < 0 || bottomvi0 >= vcount0 )
        {
          bOK = false;
          break;
        }
        int bottomvi1 = bottome.m_vi[1];
        if ( bottomvi1 < 0 || bottomvi1 >= vcount0 )
        {
          bOK = false;
          break;
        }
        if ( !topvimap[bottomvi0] )
        {
          const ON_BrepVertex& bottomv = brep.m_V[bottomvi0];
          ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
          topvimap[bottomvi0] = topv.m_vertex_index;
        }
        if ( !topvimap[bottomvi1] )
        {
          const ON_BrepVertex& bottomv = brep.m_V[bottomvi1];
          ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
          topvimap[bottomvi1] = topv.m_vertex_index;
        }
      }
    }
  }

  // build top edges
  int* topeimap = ws.GetIntMemory(ecount0);
  memset(topeimap,0,ecount0*sizeof(topeimap[0]));
  if ( bOK ) for ( ei = 0; ei < ecount0; ei++ )
  {
    if ( bCap || bSideEdge[ei] )
    {
      const ON_BrepEdge& bottome = brep.m_E[ei];
      ON_BrepVertex& topv0 = brep.m_V[topvimap[bottome.m_vi[0]]];
      ON_BrepVertex& topv1 = brep.m_V[topvimap[bottome.m_vi[1]]];
      ON_Curve* c3 = bottome.DuplicateCurve();
      if ( !c3 )
      {
        bOK = false;
        break;
      }
      c3->Transform(tr);
      int c3i = brep.AddEdgeCurve(c3);
      ON_BrepEdge& tope = brep.NewEdge(topv0,topv1,c3i,0,bottome.m_tolerance);
      topeimap[ei] = tope.m_edge_index;
    }
  }

  // build side edges
  int* sideveimap = ws.GetIntMemory(vcount0);
  memset(sideveimap,0,vcount0*sizeof(sideveimap[0]));
  if ( bOK ) for ( vi = 0; vi < vcount0; vi++ )
  {
    ON_BrepVertex& bottomv = brep.m_V[vi];
    for ( int vei = 0; vei < bottomv.m_ei.Count(); vei++ )
    {
      if ( bSideEdge[bottomv.m_ei[vei]] && topvimap[vi] )
      {
        ON_BrepVertex& topv = brep.m_V[topvimap[vi]];
        ON_Curve* c3 = path_curve.DuplicateCurve();
        if ( !c3 )
        {
          bOK = false;
        }
        else
        {
          ON_3dVector D = bottomv.point - PathStart;
          c3->Translate(D);
          int c3i = brep.AddEdgeCurve(c3);
          const ON_BrepEdge& e = brep.NewEdge(bottomv,topv,c3i,0,0.0);
          sideveimap[vi] = e.m_edge_index;
        }
        break;
      }
    }
  }

  if ( bOK && bCap )
  {
    // build top faces
    for (fi = 0; fi < fcount0; fi++ )
    {
      const ON_BrepFace& bottomf = brep.m_F[fi];
      ON_Surface* srf = bottomf.DuplicateSurface();
      if ( !srf )
      {
        bOK = false;
        break;
      }
      srf->Transform(tr);
      int si = brep.AddSurface(srf);
      ON_BrepFace& topf = brep.NewFace(si);
      topf.m_bRev = !bottomf.m_bRev;
      const int loop_count = bottomf.m_li.Count();
      topf.m_li.Reserve(loop_count);
      for ( int fli = 0; fli < loop_count; fli++ )
      {
        const ON_BrepLoop& bottoml = brep.m_L[bottomf.m_li[fli]];
        ON_BrepLoop& topl = brep.NewLoop(bottoml.m_type,topf);
        const int loop_trim_count = bottoml.m_ti.Count();
        topl.m_ti.Reserve(loop_trim_count);
        for ( int lti = 0; lti < loop_trim_count; lti++ )
        {
          const ON_BrepTrim& bottomt = brep.m_T[bottoml.m_ti[lti]];
          ON_NurbsCurve* c2 = ON_NurbsCurve::New();
          if ( !bottomt.GetNurbForm(*c2) )
          {
            delete c2;
            bOK = false;
            break;
          }
          int c2i = brep.AddTrimCurve(c2);
          ON_BrepTrim* topt = 0;
          if ( bottomt.m_ei >= 0 )
          {
            ON_BrepEdge& tope = brep.m_E[topeimap[bottomt.m_ei]];
            topt = &brep.NewTrim(tope,bottomt.m_bRev3d,topl,c2i);
          }
          else
          {
            // singular trim
            ON_BrepVertex& topv = brep.m_V[topvimap[bottomt.m_vi[0]]];
            topt = &brep.NewSingularTrim(topv,topl,bottomt.m_iso,c2i);
          }
          topt->m_tolerance[0] = bottomt.m_tolerance[0];
          topt->m_tolerance[1] = bottomt.m_tolerance[1];
          topt->m_pbox = bottomt.m_pbox;
          topt->m_type = bottomt.m_type;
          topt->m_iso = bottomt.m_iso;
        }
        topl.m_pbox = bottoml.m_pbox;
      }
    }
  }

  // build sides
  int bRev3d[4] = {0,0,1,1};
  int vid[4], eid[4];
  if( bOK ) for ( ei = 0; ei < ecount0; ei++ )
  {
    if ( bSideEdge[ei] && topeimap[ei] )
    {
      ON_BrepEdge& bottome = brep.m_E[ei];
      ON_BrepEdge& tope = brep.m_E[topeimap[ei]];
      vid[0] = bottome.m_vi[0];
      vid[1] = bottome.m_vi[1];
      vid[2] = topvimap[vid[1]];
      vid[3] = topvimap[vid[0]];
      if ( sideveimap[vid[0]] && sideveimap[vid[1]] )
      {
        ON_BrepEdge& leftedge = brep.m_E[sideveimap[vid[0]]];
        ON_BrepEdge& rightedge = brep.m_E[sideveimap[vid[1]]];
        ON_Curve* cx = bottome.DuplicateCurve();
        if ( !cx )
        {
          bOK = false;
          break;
        }
        ON_Curve* cy = leftedge.DuplicateCurve();
        if ( !cy )
        {
          delete cx;
          bOK = false;
          break;
        }
        ON_SumSurface* srf = new ON_SumSurface();
        srf->m_curve[0] = cx;
        srf->m_curve[1] = cy;
        srf->m_basepoint = srf->m_curve[1]->PointAtStart();
        srf->m_basepoint.x = -srf->m_basepoint.x;
        srf->m_basepoint.y = -srf->m_basepoint.y;
        srf->m_basepoint.z = -srf->m_basepoint.z;
        eid[0] = bottome.m_edge_index;
        eid[1] = rightedge.m_edge_index;
        eid[2] = tope.m_edge_index;
        eid[3] = leftedge.m_edge_index;
        ON_BrepFace* face = brep.NewFace(srf,vid,eid,bRev3d);
        if ( !face )
        {
          bOK = false;
          break;
        }
        else if ( bottome.m_ti.Count() == 2 )
        {
          const ON_BrepTrim& trim0 = brep.m_T[bottome.m_ti[0]];
          const ON_BrepTrim& trim1 = brep.m_T[bottome.m_ti[1]];
          const ON_BrepLoop& loop0 = brep.m_L[trim0.m_li];
          const ON_BrepLoop& loop1 = brep.m_L[trim1.m_li];
          bool bBottomFaceRev = brep.m_F[(loop0.m_fi != face->m_face_index) ? loop0.m_fi : loop1.m_fi].m_bRev;
          bool bSideFaceRev = ( trim0.m_bRev3d != trim1.m_bRev3d ) 
                            ? bBottomFaceRev 
                            : !bBottomFaceRev;
          face->m_bRev = bSideFaceRev;
        }
      }
    }
  }

  if ( !bOK )
  {
    for ( vi = brep.m_V.Count(); vi >= vcount0; vi-- )
    {
      brep.DeleteVertex(brep.m_V[vi]);
    }
  }

  return bOK;
}