示例#1
0
// Add a curve to the partial boundingbox result.
static void ON_Brep_GetTightCurveBoundingBox_Helper( const ON_Curve& crv, ON_BoundingBox& bbox, const ON_Xform* xform, const ON_Xform* xform_inverse )
{
  // Get loose boundingbox of curve.
  ON_BoundingBox tempbox;
  if( !crv.GetBoundingBox(tempbox, false) )
    return;

  // Transform the loose box if necessary. 
  // Note: transforming a box might result in a larger box, 
  //       it's better to transform the curve, 
  //       which might actually result in a smaller box.
  if( xform_inverse )
  {
    tempbox.Transform(*xform_inverse); 
  }

  // If loose boundingbox of curve is inside partial result, return.
  if( bbox.Includes(tempbox, false) )
    return;

  // Get tight boundingbox of curve, grow partial result.
  if( crv.GetTightBoundingBox(tempbox, false, xform) )
    bbox.Union(tempbox);
}
示例#2
0
// Add the isocurves of a BrepFace to the partial boundingbox result.
static void ON_Brep_GetTightIsoCurveBoundingBox_Helper( const TL_Brep& tlbrep, const ON_BrepFace& face, ON_BoundingBox& bbox, const ON_Xform* xform, int dir )
{
  ON_Interval domain = face.Domain(1 - dir);
  int degree =         face.Degree(1 - dir);
  int spancount =      face.SpanCount(1 - dir);
  int spansamples =    degree * (degree + 1) - 1;
  if( spansamples < 2 )
    spansamples = 2;

  // pbox delineates the extremes of the face interior.
  // We can use it to trivially reject spans and isocurves.
  ON_BrepLoop* pOuterLoop = face.OuterLoop();
  if( NULL==pOuterLoop )
    return;

  const ON_BoundingBox& pbox = pOuterLoop->m_pbox;
  double t0 = ((dir == 0) ? pbox.Min().y : pbox.Min().x);
  double t1 = ((dir == 0) ? pbox.Max().y : pbox.Max().x);

  // Get the surface span vector.
  ON_SimpleArray<double> spanvector(spancount + 1);
  spanvector.SetCount(spancount + 1);
  face.GetSpanVector(1 - dir, spanvector.Array());

  // Generate a list of all the sampling parameters.
  ON_SimpleArray<double> samples(spancount * spansamples);
  for( int s = 0; s < spancount; s++)
  {
    double s0 = spanvector[s];
    double s1 = spanvector[s+1];

    // Reject span if it does not intersect the pbox.
    if( s1 < t0 ) { continue; }
    if( s0 > t1 ) { continue; }
    
    ON_Interval span(s0, s1);
    for( int i = 1; i < spansamples; i++ )
    {
      double t = span.ParameterAt((double)i / (double)(spansamples - 1));
      // Reject iso if it does not intersect the pbox.
      if( t < t0 )
        continue;
      if( t > t1 )
        break;
      samples.Append(t);
    }
  }

  //Iterate over samples
  int sample_count = samples.Count();
  ON_BoundingBox loose_box;
  ON_SimpleArray<ON_Interval> intervals;
  ON_NurbsCurve isosubcrv;

  for( int i = 0; i<sample_count; i++)
  {
    // Retrieve iso-curve.
    ON_Curve* isocrv = face.IsoCurve(dir, samples[i]);

    while( NULL!=isocrv )
    {
      // Transform isocurve if necessary, this is better than transforming downstream boundingboxes.
      if( xform )
        isocrv->Transform(*xform);

      // Compute loose box.
      if( !isocrv->GetBoundingBox(loose_box, false))
        break;

      // Determine whether the loose box is already contained within the partial result.
      if( bbox.Includes(loose_box, false) ) 
        break;

      // Solve trimming domains for the iso-curve.
      intervals.SetCount(0);
      if( !tlbrep.GetIsoIntervals(face, dir, samples[i], intervals))
        break;

      // Iterate over trimmed iso-curves.
      int interval_count = intervals.Count();
      for( int k=0; k<interval_count; k++ )
      {
        //this to mask a bug in Rhino4. GetNurbForm does not destroy the Curve Tree. It does now.
        isosubcrv.DestroyCurveTree();
        isocrv->GetNurbForm(isosubcrv, 0.0, &intervals[k]);
        ON_Brep_GetTightCurveBoundingBox_Helper(isosubcrv, bbox, NULL, NULL);
      }
      break;
    }

    if( isocrv )
    {
      delete isocrv;
      isocrv = NULL;
    }
  }
}
示例#3
0
ON_Surface::ISO
ON_Surface::IsIsoparametric( const ON_Curve& curve, const ON_Interval* subdomain ) const
{
  ISO iso = not_iso;

  if ( subdomain )
  {
    ON_Interval cdom = curve.Domain();
    double t0 = cdom.NormalizedParameterAt(subdomain->Min());
    double t1 = cdom.NormalizedParameterAt(subdomain->Max());
    if ( t0 < t1-ON_SQRT_EPSILON )
    {
      if ( (t0 > ON_SQRT_EPSILON && t0 < 1.0-ON_SQRT_EPSILON) || (t1 > ON_SQRT_EPSILON && t1 < 1.0-ON_SQRT_EPSILON) )
      {
        cdom.Intersection(*subdomain);
        if ( cdom.IsIncreasing() )
        {
          ON_NurbsCurve nurbs_curve;
          if ( curve.GetNurbForm( nurbs_curve, 0.0,&cdom) )
          {
            return IsIsoparametric( nurbs_curve, 0 );
          }
        }
      }
    }
  }


  ON_BoundingBox bbox;
  double tolerance = 0.0;
  const int dim = curve.Dimension();
  if ( (dim == 2 || dim==3) && curve.GetBoundingBox(bbox) ) 
  {
    iso = IsIsoparametric( bbox );
    switch (iso) {
    case x_iso:
    case W_iso:
    case E_iso:
      // make sure curve is a (nearly) vertical line
      // and weed out vertical scribbles
      tolerance = bbox.m_max.x - bbox.m_min.x;
      if ( tolerance < ON_ZERO_TOLERANCE && ON_ZERO_TOLERANCE*1024.0 <= (bbox.m_max.y-bbox.m_min.y) )
      {
        // 26 March 2007 Dale Lear
        //    If tolerance is tiny, then use ON_ZERO_TOLERANCE
        //    This fixes cases where iso curves where not getting
        //    the correct flag because tol=1e-16 and the closest
        //    point to line had calculation errors of 1e-15.
        tolerance = ON_ZERO_TOLERANCE;
      }
      if ( !curve.IsLinear( tolerance ) )
        iso = not_iso;
      break;
    case y_iso:
    case S_iso:
    case N_iso:
      // make sure curve is a (nearly) horizontal line
      // and weed out horizontal scribbles
      tolerance = bbox.m_max.y - bbox.m_min.y;
      if ( tolerance < ON_ZERO_TOLERANCE && ON_ZERO_TOLERANCE*1024.0 <= (bbox.m_max.x-bbox.m_min.x) )
      {
        // 26 March 2007 Dale Lear
        //    If tolerance is tiny, then use ON_ZERO_TOLERANCE
        //    This fixes cases where iso curves where not getting
        //    the correct flag because tol=1e-16 and the closest
        //    point to line had calculation errors of 1e-15.
        tolerance = ON_ZERO_TOLERANCE;
      }
      if ( !curve.IsLinear( tolerance ) )
        iso = not_iso;
      break;
    default:
      // nothing here
      break;
    }
  }
  return iso;
}
示例#4
0
void FindLoops(ON_Brep **b) {
    ON_3dPoint ptmatch, ptterminate, pstart, pend;
    int *curvearray;
    curvearray = static_cast<int*>(bu_malloc((*b)->m_C3.Count() * sizeof(int), "sketch edge list"));
    for (int i = 0; i < (*b)->m_C3.Count(); i++) {
	curvearray[i] = -1;
    }
    ON_SimpleArray<ON_Curve *> allsegments;
    ON_SimpleArray<ON_Curve *> loopsegments;
    int loop_complete;
    for (int i = 0; i < (*b)->m_C3.Count(); i++) {
	allsegments.Append((*b)->m_C3[i]);
    }

    int allcurvesassigned = 0;
    int assignedcount = 0;
    int curvecount = 0;
    int loopcount = 0;
    while (allcurvesassigned != 1) {
	int havefirstcurve = 0;
	while ((havefirstcurve == 0) && (curvecount < allsegments.Count())) {
	    if (curvearray[curvecount] == -1) {
		havefirstcurve = 1;
	    } else {
		curvecount++;
	    }
	}
	// First, sort through things to assign curves to loops.
	loop_complete = 0;
	while ((loop_complete != 1) && (allcurvesassigned != 1)) {
	    curvearray[curvecount] = loopcount;
	    ptmatch = (*b)->m_C3[curvecount]->PointAtEnd();
	    ptterminate = (*b)->m_C3[curvecount]->PointAtStart();
	    for (int i = 0; i < allsegments.Count(); i++) {
		pstart = (*b)->m_C3[i]->PointAtStart();
		pend = (*b)->m_C3[i]->PointAtEnd();
		if (NEAR_ZERO(ptmatch.DistanceTo(pstart), ON_ZERO_TOLERANCE) && (curvearray[i] == -1)) {
		    curvecount = i;
		    ptmatch = pend;
		    i = allsegments.Count();
		    if (NEAR_ZERO(pend.DistanceTo(ptterminate), ON_ZERO_TOLERANCE)) {
			loop_complete = 1;
			loopcount++;
		    }
		} else {
		    if (i == allsegments.Count() - 1) {
			loop_complete = 1; //If we reach this pass, loop had better be complete
			loopcount++;
			assignedcount = 0;
			for (int j = 0; j < allsegments.Count(); j++) {
			    if (curvearray[j] != -1) assignedcount++;
			}
			if (allsegments.Count() == assignedcount) allcurvesassigned = 1;
		    }
		}
	    }
	}
    }

    double maxdist = 0.0;
    int largest_loop_index = 0;
    for (int i = 0; i <= loopcount ; i++) {
	ON_BoundingBox lbbox;
	for (int j = 0; j < (*b)->m_C3.Count(); j++) {
	    if (curvearray[j] == i) {
		ON_Curve *currcurve = (*b)->m_C3[j];
		currcurve->GetBoundingBox(lbbox, true);
	    }
	}
	point_t minpt, maxpt;
	double currdist;
	VSET(minpt, lbbox.m_min[0], lbbox.m_min[1], lbbox.m_min[2]);
	VSET(maxpt, lbbox.m_max[0], lbbox.m_max[1], lbbox.m_max[2]);
	currdist = DIST_PT_PT(minpt, maxpt);
	if (currdist > maxdist) {
	    maxdist = currdist;
	    largest_loop_index = i;
	}
    }


    for (int i = 0; i < allsegments.Count(); i++) {
	if (curvearray[i] == largest_loop_index) loopsegments.Append((*b)->m_C3[i]);
    }

    (*b)->NewPlanarFaceLoop(0, ON_BrepLoop::outer, loopsegments, true);

    loopsegments.Empty();

    // If there's anything left, make inner loops out of it
    for (int i = 0; i <= loopcount; i++) {
	if (i != largest_loop_index) {
	    for (int j = 0; j < allsegments.Count(); j++) {
		if (curvearray[j] == i) loopsegments.Append((*b)->m_C3[j]);
	    }
	    (*b)->NewPlanarFaceLoop(0, ON_BrepLoop::inner, loopsegments, true);
	}
	loopsegments.Empty();
    }

    bu_free(curvearray, "sketch edge list");
}
示例#5
0
void FindLoops(ON_Brep **b, const ON_Line* revaxis, const fastf_t ang) {
    ON_3dPoint ptmatch, ptterminate, pstart, pend;

    int *curvearray;
    curvearray = static_cast<int*>(bu_malloc((*b)->m_C3.Count() * sizeof(int), "sketch edge list"));
    for (int i = 0; i < (*b)->m_C3.Count(); i++) {
	curvearray[i] = -1;
    }
    ON_SimpleArray<ON_Curve *> allsegments;
    ON_SimpleArray<ON_Curve *> loopsegments;
    int loop_complete;
    for (int i = 0; i < (*b)->m_C3.Count(); i++) {
	allsegments.Append((*b)->m_C3[i]);
    }

    int allcurvesassigned = 0;
    int assignedcount = 0;
    int curvecount = 0;
    int loopcount = 0;
    while (allcurvesassigned != 1) {
	int havefirstcurve = 0;
	while ((havefirstcurve == 0) && (curvecount < allsegments.Count())) {
	    if (curvearray[curvecount] == -1) {
		havefirstcurve = 1;
	    } else {
		curvecount++;
	    }
	}
	// First, sort through things to assign curves to loops.
	loop_complete = 0;
	while ((loop_complete != 1) && (allcurvesassigned != 1)) {
	    curvearray[curvecount] = loopcount;
	    ptmatch = (*b)->m_C3[curvecount]->PointAtEnd();
	    ptterminate = (*b)->m_C3[curvecount]->PointAtStart();
	    for (int i = 0; i < allsegments.Count(); i++) {
		pstart = (*b)->m_C3[i]->PointAtStart();
		pend = (*b)->m_C3[i]->PointAtEnd();
		if (NEAR_ZERO(ptmatch.DistanceTo(pstart), ON_ZERO_TOLERANCE) && (curvearray[i] == -1)) {
		    curvecount = i;
		    ptmatch = pend;
		    i = allsegments.Count();
		    if (NEAR_ZERO(pend.DistanceTo(ptterminate), ON_ZERO_TOLERANCE)) {
			loop_complete = 1;
			loopcount++;
		    }
		} else {
		    if (i == allsegments.Count() - 1) {
			loop_complete = 1; //If we reach this pass, loop had better be complete
			loopcount++;
			assignedcount = 0;
			for (int j = 0; j < allsegments.Count(); j++) {
			    if (curvearray[j] != -1) assignedcount++;
			}
			if (allsegments.Count() == assignedcount) allcurvesassigned = 1;
		    }
		}
	    }
	}
    }

    double maxdist = 0.0;
    int largest_loop_index = 0;
    for (int i = 0; i <= loopcount ; i++) {
	ON_BoundingBox lbbox;
	for (int j = 0; j < (*b)->m_C3.Count(); j++) {
	    if (curvearray[j] == i) {
		ON_Curve *currcurve = (*b)->m_C3[j];
		currcurve->GetBoundingBox(lbbox, true);
	    }
	}
	point_t minpt, maxpt;
	double currdist;
	VSET(minpt, lbbox.m_min[0], lbbox.m_min[1], lbbox.m_min[2]);
	VSET(maxpt, lbbox.m_max[0], lbbox.m_max[1], lbbox.m_max[2]);
	currdist = DIST_PT_PT(minpt, maxpt);
	if (currdist > maxdist) {
	    maxdist = currdist;
	    largest_loop_index = i;
	}
    }

    for (int i = 0; i < loopcount ; i++) {
	ON_PolyCurve* poly_curve = new ON_PolyCurve();
	for (int j = 0; j < allsegments.Count(); j++) {
	    if (curvearray[j] == i) {
		 poly_curve->Append(allsegments[j]);
	    }
	}

	ON_NurbsCurve *revcurve = ON_NurbsCurve::New();
	poly_curve->GetNurbForm(*revcurve);
	ON_RevSurface* revsurf = ON_RevSurface::New();
	revsurf->m_curve = revcurve;
	revsurf->m_axis = *revaxis;
	revsurf->m_angle = ON_Interval(0, ang);
	ON_BrepFace *face = (*b)->NewFace(*revsurf);

	if (i == largest_loop_index) {
	    (*b)->FlipFace(*face);
	}
    }

    bu_free(curvearray, "sketch edge list");
}