// Copy the 2d curve, make it 3d, and transform it // to the 3d plane position ON_Curve* ON_Hatch::LoopCurve3d( int index) const { int count = m_loops.Count(); ON_Curve* pC = NULL; if( index >= 0 && index < count) { if( m_loops[index]->Curve()) { pC = m_loops[index]->Curve()->DuplicateCurve(); if( pC) { pC->ChangeDimension( 3); ON_Xform xf; xf.Rotation( ON_xy_plane, m_plane); pC->Transform( xf); } } } return pC; }
// 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; } } }