Exemplo n.º 1
0
osg::Node* RhinoReader::BuildEdge(const ON_Brep* theBrep)
{
    osg::ref_ptr<osg::Geode> aGeode = new osg::Geode();

    for (int i = 0; i < theBrep->m_E.Count(); ++i)
    {
        osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry();
        osg::ref_ptr<osg::Vec3Array> aVertices = new osg::Vec3Array();

        ON_BrepEdge* anEdge = theBrep->Edge(i);

        double t0 = 0.0;
        double t1 = 0.0;
        double d = 0.0;

        anEdge->GetDomain(&t0, &t1);

        d = (t1 - t0) / 5.0;

        for (double t = t0; (t - t1) < TOLERANCE_EDGE; t += d)
        {
            ON_3dPoint aPoint = anEdge->PointAt(t);

            aVertices->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z));
        }

        aGeometry->setVertexArray(aVertices);
        aGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, aVertices->size()));

        aGeode->addDrawable(aGeometry);
    }

    return aGeode.release();
}
Exemplo n.º 2
0
int
brep_edge_check(int reason,
		const SubsurfaceBBNode* sbv,
		const ON_BrepFace* face,
		const ON_Surface* surf,
		const ON_Ray& r,
		HitList& hits)
{
    // if the intersection was not found for any reason, we need to
    // check and see if we are close to any topological edges; we may
    // have hit a crack...

    // the proper way to do this is to only look at edges
    // interesecting with the subsurface bounding box... but for
    // now, we'll look at the edges associated with the face for the bounding box...

    // XXX - optimize this

    set<ON_BrepEdge*> edges;
    ON_3dPoint pt;
    for (int i = 0; i < face->LoopCount(); i++) {
	ON_BrepLoop* loop = face->Loop(i);
	for (int j = 0; j < loop->TrimCount(); j++) {
	    ON_BrepTrim* trim = loop->Trim(j);
	    ON_BrepEdge* edge = trim->Edge();
	    pair<set<ON_BrepEdge*>::iterator, bool> res = edges.insert(edge);
	    //	    if (res.second) {
	    // only check if its the first time we've seen this
	    // edge
	    const ON_Curve* curve = edge->EdgeCurveOf();
	    Sample s;
	    if (curve->CloseTo(ON_3dPoint(hits.back().point), BREP_EDGE_MISS_TOLERANCE, s)) {
		TRACE1("CLOSE TO EDGE");
		hits.back().closeToEdge = true;
		return BREP_INTERSECT_FOUND;
	    }
	}
    }
    return BREP_INTERSECT_TRIMMED;
}
bool ON_Brep::IsValidForV2( const ON_BrepEdge& edge ) const
{
    int ei = edge.m_edge_index;
    if ( ei < 0 || ei >= m_E.Count() )
        return false;
    if ( &edge != &m_E[ei] )
        return false;
    if ( edge.ProxyCurveIsReversed() )
        return false;
    if ( edge.Domain() != edge.ProxyCurveDomain() )
        return false;
    const ON_Curve * curve = edge.EdgeCurveOf();
    if ( curve != edge.ProxyCurve() )
        return false;
    const ON_NurbsCurve* nurbs_curve = ON_NurbsCurve::Cast(curve);
    if ( 0 == nurbs_curve )
        return false;
    if ( !nurbs_curve->IsClamped(2) )
        return false;
    if ( nurbs_curve->m_dim != 3 )
        return false;
    if ( nurbs_curve->m_is_rat )
    {
        // 2 June 2003 Dale Lear - RR 8809 fix
        //    V2 likes end weights to be 1.0
        if ( nurbs_curve->m_cv[3] != 1.0 || nurbs_curve->CV(nurbs_curve->m_cv_count-1)[3] != 1.0 )
        {
            return false;
        }
    }

    if ( curve->Domain() != edge.Domain() )
        return false;

    // 14 April 2003 Dale Lear
    //     RR 8808 - V2 requires edges to be strictly closed/open
    if (    nurbs_curve->m_cv_count >= 4
            && 0 == ON_ComparePoint( nurbs_curve->m_dim, nurbs_curve->m_is_rat, nurbs_curve->m_cv, nurbs_curve->CV(nurbs_curve->m_cv_count-1) )
       )
    {
        if ( edge.m_vi[0] != edge.m_vi[1] )
            return false;
    }
    else if (edge.m_vi[0] == edge.m_vi[1] )
    {
        return false;
    }

    return true;
}
Exemplo n.º 4
0
int ON_Brep::SplitEdgeAtParameters(
  int edge_index,
  int edge_t_count,
  const double* edge_t
  )
{
  // Default kink_tol_radians MUST BE ON_PI/180.0.
  //
  // The default kink tol must be kept in sync with the default for 
  // TL_Brep::SplitKinkyFace() and ON_Brep::SplitKinkyFace().
  // See comments in TL_Brep::SplitKinkyFace() for more details.

  if (0 == edge_t_count)
    return 0;
  if (0 == edge_t)
    return 0;
  if (edge_index < 0 || edge_index >= m_E.Count()) 
    return 0;
  ON_BrepEdge& E = m_E[edge_index];
  if (E.m_c3i < 0) 
    return 0;
  ON_Curve* curve = m_C3[E.m_c3i];
  if (!curve) 
    return 0;

  ON_Interval Edomain;
  if ( !E.GetDomain(&Edomain.m_t[0],&Edomain.m_t[1]) )
    return 0;
  if ( !Edomain.IsIncreasing() )
    return 0;

  // get a list of unique and valid splitting parameters
  ON_SimpleArray<double> split_t(edge_t_count);
  {
    for (int i = 0; i < edge_t_count; i++)
    {
      double e = edge_t[i];
      if ( !ON_IsValid(e) )
      {
        ON_ERROR("Invalid edge_t[] value");
        continue;
      }
      if ( e <= Edomain.m_t[0] )
      {
        ON_ERROR("edge_t[] <= start of edge domain");
        continue;
      }
      if ( e >= Edomain.m_t[1] )
      {
        ON_ERROR("edge_t[] >= end of edge domain");
        continue;
      }
      split_t.Append(e);
    }
    if ( split_t.Count() > 1 )
    {
      // sort split_t[] and remove duplicates
      ON_SortDoubleArray( ON::heap_sort, split_t.Array(), split_t.Count() );
      int count = 1;
      for ( int i = 1; i < split_t.Count(); i++ )
      {
        if ( split_t[i] > split_t[count-1] )
        {
          if ( i > count )
            split_t[count] = split_t[i];
          count++;
        }
      }
      split_t.SetCount(count);
    }
  }

  if (split_t.Count() <= 0) 
    return 0;

  // Reverse split_t[] so the starting segment of the original
  // edge m_E[edge_index] is the one at m_E[edge_index].
  split_t.Reverse();

  ON_Curve* new_curve = TuneupSplitteeHelper(m_E[edge_index].ProxyCurve());
  if ( 0 != new_curve )
  {
    m_E[edge_index].m_c3i = AddEdgeCurve(new_curve);
    m_E[edge_index].SetProxyCurve(new_curve);
    new_curve = 0;
  }

  int eti, ti;
  int successful_split_count = 0;
  for (int i=0; i<split_t.Count(); i++)
  {
    double t0, t1;
    m_E[edge_index].GetDomain(&t0, &t1);
    if (t1 - t0 < 10.0*ON_ZERO_TOLERANCE) 
      break;

    //6 Dec 2002 Dale Lear:
    //   I added the relative edge_split_s and trm_split_s tests to detect
    //   attempts to trim a nano-gnats-wisker off the end of a trim.
    double edge_split_s = ON_Interval(t0,t1).NormalizedParameterAt(split_t[i]);
    double trim_split_s = 0.5;

    if (split_t[i] - t0 <= ON_ZERO_TOLERANCE || edge_split_s <= ON_SQRT_EPSILON )
    {
      // this split is not possible
      continue;
    }
    
    if (t1 - split_t[i] <= ON_ZERO_TOLERANCE || edge_split_s >= 1.0-ON_SQRT_EPSILON)
    {
      // this split is not possible
      continue;
    }

    // trim_t[] = corresponding trim parameters
    ON_SimpleArray<double> trim_t(m_E[edge_index].m_ti.Count());

    for ( eti = 0; eti < m_E[edge_index].m_ti.Count(); eti++)
    {
      ti = m_E[edge_index].m_ti[eti];
      if ( ti < 0 || ti >= m_T.Count() )
        continue;
      ON_BrepTrim& trim = m_T[ti];
      if ( 0 == i )
      {
        // On the first split, make sure the trim curve is up to snuff.
        new_curve = TuneupSplitteeHelper(trim.ProxyCurve());
        if (new_curve)
        {
          trim.m_c2i = AddTrimCurve(new_curve);
          trim.SetProxyCurve(new_curve);
          new_curve = 0;
        }
      }
      double t = ON_UNSET_VALUE;
      if (!GetTrimParameter(ti, split_t[i], &t) || !ON_IsValid(t))
        break;
      trim_t.Append(t);
      const ON_Interval trim_domain = trim.Domain();
      trim_split_s = trim_domain.NormalizedParameterAt(t);
      if ( trim_split_s <= ON_SQRT_EPSILON || t - trim_domain[0] <= ON_ZERO_TOLERANCE )
        break;

      if ( trim_split_s >= 1.0-ON_SQRT_EPSILON || trim_domain[1] - t <= ON_ZERO_TOLERANCE )
        break;
    }

    if ( trim_t.Count() != m_E[edge_index].m_ti.Count() )
      continue;

    if (!SplitEdge(edge_index, split_t[i], trim_t))
    {
      continue;
    }

    // SplitEdge generally adjusts proxy domains instead
    // of trimming the orginal curve. These DuplicateCurve()
    // calls make a new curve whose domain exactly matches
    // the edge.
    for ( int epart = 0; epart < 2; epart++ )
    {
      ON_BrepEdge* newE = (0 == epart) ? &m_E[edge_index] : m_E.Last();
      if ( 0 == newE )
        continue;
      new_curve = TuneupEdgeOrTrimRealCurve(*newE,true);
      if (new_curve)
      {
        newE->m_c3i = AddEdgeCurve(new_curve);
        newE->SetProxyCurve(new_curve);
      }
      for ( eti = 0; eti < newE->m_ti.Count(); eti++ )
      {
        ti = newE->m_ti[eti];
        if ( ti < 0 || ti >= m_T.Count() )
          continue;
        ON_BrepTrim& trim = m_T[ti];
        new_curve = TuneupEdgeOrTrimRealCurve(trim,false);
        if (new_curve)
        {
          trim.m_c2i = AddTrimCurve(new_curve);
          trim.SetProxyCurve(new_curve);
        }
      }
    }

    successful_split_count++;
  }

  return successful_split_count;
}