EXPORT_C void CHuiTexture::SetSize(const TSize& aSize) { // if there are multiple // segments already defined we have to recalculate (rescale) // the logical sizes and offsets for the individual segments // to match the new logical size if (SegmentCount()>0 && iSize.iWidth > 0 && iSize.iHeight > 0) { for (TInt s = 0; s < SegmentCount(); s++) { TSize oldSize(SegmentSize(s)); TSize newSize(oldSize.iWidth * aSize.iWidth / iSize.iWidth, oldSize.iHeight * aSize.iHeight / iSize.iHeight); TPoint oldOffset(SegmentOffset(s)); TPoint newOffset(oldOffset.iX * aSize.iWidth / iSize.iWidth, oldOffset.iY * aSize.iHeight / iSize.iHeight); SetSegmentSize(s, newSize); SetSegmentOffset(s, newOffset); } } // assign new logical size iSize = aSize; }
EXPORT_C TInt CHuiTexture::ClearL(const TSize& aSize, const TRgb& aColor) { // Always assign new logical size SetSize(aSize); // if there are no segments, configure them based on the given size! ASSERT(SegmentCount() != 0 || (aSize.iWidth > 0 && aSize.iHeight > 0)); if(SegmentCount() == 0) { SetupSegmentsL(aSize, aSize); } // clear all segments.. for(TInt segment = 0; segment < SegmentCount(); ++segment) { TRAPD(err, SegmentClearL(segment, EFalse, aColor, 0) ); if(err == KErrNoMemory) { HUI_DEBUG2(_L("CHuiTexture::Clear() - Out of memory trying to clear segment %i from \"%S\"."), segment, &ImageFileName()); return err; } else if(err != KErrNone) { HUI_DEBUG1(_L("CHuiTexture::Clear() - SegmentClearL failed with error code %i."), err); return err; } else { // for PC lint } } // succeeded! return KErrNone; }
const OPT<SHAPE_LINE_CHAIN::INTERSECTION> SHAPE_LINE_CHAIN::SelfIntersecting() const { for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ ) { const VECTOR2I s2a = CSegment( s2 ).A, s2b = CSegment( s2 ).B; if( s1 + 1 != s2 && CSegment( s1 ).Contains( s2a ) ) { INTERSECTION is; is.our = CSegment( s1 ); is.their = CSegment( s2 ); is.p = s2a; return is; } else if( CSegment( s1 ).Contains( s2b ) && // for closed polylines, the ending point of the // last segment == starting point of the first segment // this is a normal case, not self intersecting case !( IsClosed() && s1 == 0 && s2 == SegmentCount()-1 ) ) { INTERSECTION is; is.our = CSegment( s1 ); is.their = CSegment( s2 ); is.p = s2b; return is; } else { OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true ); if( p ) { INTERSECTION is; is.our = CSegment( s1 ); is.their = CSegment( s2 ); is.p = *p; return is; } } } } return OPT<SHAPE_LINE_CHAIN::INTERSECTION>(); }
int SHAPE_LINE_CHAIN::FindSegment( const VECTOR2I& aP ) const { for( int s = 0; s < SegmentCount(); s++ ) if( CSegment( s ).Distance( aP ) <= 1 ) return s; return -1; }
void FileBundleWriter::CreateSegment() { std::string seg_name = khMakeNumericFilename(kSegmentFilePrefix, SegmentCount(), kSegmentFileSuffixLength); if (SegmentCount() >= kSegmentFileCountMax) { throw khSimpleException ("FileBundleWriter::CreateSegment: max segment file count exceeded"); } FileBundle::AddSegment(new FileBundleWriterSegment(file_pool(), abs_path(), seg_name, last_segment_id_++, mode_ & ~kExecuteMode)); notify(NFY_DEBUG, "FileBundleWriter::CreateSegment added %llu: %s", static_cast<long long unsigned>(SegmentCount() - 1), seg_name.c_str()); }
int SHAPE_LINE_CHAIN::Length() const { int l = 0; for( int i = 0; i < SegmentCount(); i++ ) l += CSegment( i ).Length(); return l; }
EXPORT_C TUint CHuiTexture::SegmentName(TInt aSegment) const { ASSERT(aSegment < SegmentCount()); if(iPlaceholder) { return iPlaceholder->SegmentName(aSegment); } return iSegments[aSegment].iName; }
EXPORT_C TPoint CHuiTexture::SegmentOffset(TInt aSegment) const { ASSERT(aSegment < SegmentCount()); if(iPlaceholder) { return iPlaceholder->SegmentOffset(aSegment); } return iSegments[aSegment].iOffset; }
EXPORT_C TSize CHuiTexture::SegmentTextureSize(TInt aSegment) const { ASSERT(aSegment < SegmentCount()); if(iPlaceholder) { return iPlaceholder->SegmentTextureSize(aSegment); } return iSegments[aSegment].iTextureSize; }
bool ON_Polyline::ClosestPointTo( const ON_3dPoint& point, double *t, int segment_index0, int segment_index1 ) const { bool rc = false; int segment_index; double segment_t, segment_d, best_t, best_d; best_t = 0.0; // to keep lint quiet best_d = 0.0; // to keep lint quiet if ( t ) { if ( segment_index0 < 0 ) segment_index0 = 0; if ( segment_index1 > SegmentCount() ) segment_index1 = SegmentCount(); for ( segment_index = segment_index0; segment_index < segment_index1; segment_index++ ) { double seg_length = m_a[segment_index].DistanceTo(m_a[segment_index + 1]); if (seg_length < ON_EPSILON) segment_t = 0.0; else { const ON_3dVector D = SegmentTangent(segment_index); const int i = ( point.DistanceTo(m_a[segment_index]) <= point.DistanceTo(m_a[segment_index+1]) ) ? 0 : 1; segment_t = (point - m_a[segment_index+i])*D/seg_length; if ( i ) { segment_t = 1.0 + segment_t; } if ( segment_t < 0.0 ) segment_t = 0.0; else if (segment_t > 1.0 ) segment_t = 1.0; } segment_d = point.DistanceTo((1-segment_t)*m_a[segment_index] + segment_t*m_a[segment_index+1]); if ( !rc || segment_d < best_d ) { best_t = segment_t + ((double)segment_index); best_d = segment_d; } rc = true; } } if (rc) *t = best_t; return rc; }
int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP, bool aOutlineOnly ) const { int d = INT_MAX; if( IsClosed() && PointInside( aP ) && !aOutlineOnly ) return 0; for( int s = 0; s < SegmentCount(); s++ ) d = std::min( d, CSegment( s ).Distance( aP ) ); return d; }
// Test if all segments of the polyedge are surface edges bool ON_PolyEdgeCurve::ContainsAllEdges() const { int i, count = SegmentCount(); for( i = 0; i < count; i++) { ON_PolyEdgeSegment* segment = SegmentCurve(i); if( NULL == segment || NULL == segment->Edge()) { return false; } } return true; }
void CHuiTexture::GenerateBlobL(const TSize& aSize) { SetSize(aSize); // calculate parameters for the segments.. SetupSegmentsL(aSize, aSize); ASSERT(SegmentCount()==1); TSize textureSize = SegmentTextureSize(0); TUint8* buffer = new (ELeave) TUint8[ textureSize.iWidth * textureSize.iHeight * 4]; CleanupStack::PushL( buffer ); /** @todo This is too slow. Just load a pregenerated texture. */ TUint8* ptr = buffer; for(TInt y = 0; y < textureSize.iHeight; y++) { for(TInt x = 0; x < textureSize.iWidth; x++, ptr += 4) { ptr[0] = ptr[1] = ptr[2] = 255; TReal32 dx = TReal32(x) - textureSize.iWidth/2.f; TReal32 dy = TReal32(y) - textureSize.iHeight/2.f; TReal32 src = dx * dx + dy * dy; TReal trg = 0; if(dx != 0 || dy != 0) { Math::Sqrt(trg, src); } trg = trg / (textureSize.iWidth/2.0f); if(trg < 0) { trg = 0; } if(trg > 1) { trg = 1; } ptr[3] = (TInt) ((1 - trg) * 255); } } // Upload the solid color buffer. SegmentUploadL(0, EHuiTextureFormatRgba8888, textureSize, buffer); CleanupStack::PopAndDestroy( buffer ); }
int ON_PolyEdgeCurve::FindEdge( const ON_BrepEdge* edge) const { int rc = -1; if ( 0 != edge ) { int i, count = SegmentCount(); for( i = 0; i < count; i++) { ON_PolyEdgeSegment* segment = SegmentCurve(i); if ( 0 != segment && edge == segment->Edge() ) { rc = i; break; } } } return rc; }
const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const { int min_d = INT_MAX; int nearest = 0; for( int i = 0; i < SegmentCount(); i++ ) { int d = CSegment( i ).Distance( aP ); if( d < min_d ) { min_d = d; nearest = i; } } return CSegment( nearest ).NearestPoint( aP ); }
int ON_PolyEdgeCurve::FindTrim( const ON_BrepTrim* trim) const { int rc = -1; if ( 0 != trim ) { int i, count = SegmentCount(); for( i = 0; i < count; i++) { ON_PolyEdgeSegment* segment = SegmentCurve(i); if ( 0 != segment && trim == segment->Trim() ) { rc = i; break; } } } return rc; }
int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, INTERSECTIONS& aIp ) const { BOX2I bb_other = aChain.BBox(); for( int s1 = 0; s1 < SegmentCount(); s1++ ) { const SEG& a = CSegment( s1 ); const BOX2I bb_cur( a.A, a.B - a.A ); if( !bb_other.Intersects( bb_cur ) ) continue; for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ ) { const SEG& b = aChain.CSegment( s2 ); INTERSECTION is; if( a.Collinear( b ) ) { is.our = a; is.their = b; if( a.Contains( b.A ) ) { is.p = b.A; aIp.push_back( is ); } if( a.Contains( b.B ) ) { is.p = b.B; aIp.push_back( is ); } if( b.Contains( a.A ) ) { is.p = a.A; aIp.push_back( is ); } if( b.Contains( a.B ) ) { is.p = a.B; aIp.push_back( is ); } } else { OPT_VECTOR2I p = a.Intersect( b ); if( p ) { is.p = *p; is.our = a; is.their = b; aIp.push_back( is ); } } } } return aIp.size(); }
int ON_PolyEdgeCurve::FindCurve( const ON_Curve* curve) const { int rc = -1; if ( 0 != curve ) { int i, count = SegmentCount(); for( i = 0; i < count; i++) { ON_PolyEdgeSegment* segment = SegmentCurve(i); if ( 0 != segment && (curve == segment || curve == segment->ProxyCurve() || curve == segment->Edge()) ) { rc = i; break; } } } return rc; }
int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const { int sum = 0; for( int i = 0; i < SegmentCount(); i++ ) { const SEG seg = CSegment( i ); int d = seg.Distance( aP ); if( d <= 1 ) { sum += ( aP - seg.A ).EuclideanNorm(); return sum; } else sum += seg.Length(); } return -1; }
bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance ) const { BOX2I box_a( aSeg.A, aSeg.B - aSeg.A ); BOX2I::ecoord_type dist_sq = (BOX2I::ecoord_type) aClearance * aClearance; for( int i = 0; i < SegmentCount(); i++ ) { const SEG& s = CSegment( i ); BOX2I box_b( s.A, s.B - s.A ); BOX2I::ecoord_type d = box_a.SquaredDistance( box_b ); if( d < dist_sq ) { if( s.Collide( aSeg, aClearance ) ) return true; } } return false; }
int SHAPE_LINE_CHAIN::Intersect( const SEG& aSeg, INTERSECTIONS& aIp ) const { for( int s = 0; s < SegmentCount(); s++ ) { OPT_VECTOR2I p = CSegment( s ).Intersect( aSeg ); if( p ) { INTERSECTION is; is.our = CSegment( s ); is.their = aSeg; is.p = *p; aIp.push_back( is ); } } compareOriginDistance comp( aSeg.A ); sort( aIp.begin(), aIp.end(), comp ); return aIp.size(); }
bool SHAPE_LINE_CHAIN::CheckClearance( const VECTOR2I& aP, const int aDist) const { if( !PointCount() ) return false; else if( PointCount() == 1 ) return m_points[0] == aP; for( int i = 0; i < SegmentCount(); i++ ) { const SEG s = CSegment( i ); if( s.A == aP || s.B == aP ) return true; if( s.Distance( aP ) <= aDist ) return true; } return false; }
const VECTOR2I SHAPE_LINE_CHAIN::PointAlong( int aPathLength ) const { int total = 0; if( aPathLength == 0 ) return CPoint( 0 ); for( int i = 0; i < SegmentCount(); i++ ) { const SEG& s = CSegment( i ); int l = s.Length(); if( total + l >= aPathLength ) { VECTOR2I d( s.B - s.A ); return s.A + d.Resize( aPathLength - total ); } total += l; } return CPoint( -1 ); }
void FileBundleWriter::AllocateBlock(size_t block_size, FileBundleWriterSegment **segment, off_t *seg_position, uint64 *bundle_position) { assert(block_size <= segment_break()); khLockGuard lock(modify_lock_); // Check for adequate room in current segment; if not, create a new // segment FileBundleSegment *cur_seg = LastSegment(); if (cur_seg->data_size() + block_size > segment_break()) { CreateSegment(); cur_seg = LastSegment(); } assert(cur_seg->SegmentType() == FileBundleSegment::kWriterSegment); *segment = reinterpret_cast<FileBundleWriterSegment*>(cur_seg); *seg_position = cur_seg->data_size(); cur_seg->IncrementDataSize(block_size); IncrementDataSize(block_size); *bundle_position = (SegmentCount() - 1) * segment_break() + *seg_position; }
int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) { int ii = -1; int min_dist = 2; int found_index = Find( aP ); for( int s = 0; s < SegmentCount(); s++ ) { const SEG seg = CSegment( s ); int dist = seg.Distance( aP ); // make sure we are not producing a 'slightly concave' primitive. This might happen // if aP lies very close to one of already existing points. if( dist < min_dist && seg.A != aP && seg.B != aP ) { min_dist = dist; if( found_index < 0 ) ii = s; else if( s < found_index ) ii = s; } } if( ii < 0 ) ii = found_index; if( ii >= 0 ) { m_points.insert( m_points.begin() + ii + 1, aP ); return ii + 1; } return -1; }
int SHAPE_LINE_CHAIN::EdgeContainingPoint( const VECTOR2I& aPt, int aAccuracy ) const { if( !PointCount() ) return -1; else if( PointCount() == 1 ) { VECTOR2I dist = m_points[0] - aPt; return ( hypot( dist.x, dist.y ) <= aAccuracy + 1 ) ? 0 : -1; } for( int i = 0; i < SegmentCount(); i++ ) { const SEG s = CSegment( i ); if( s.A == aPt || s.B == aPt ) return i; if( s.Distance( aPt ) <= aAccuracy + 1 ) return i; } return -1; }
bool ON_Polyline::ClosestPointTo( const ON_3dPoint& point, double *t ) const { return ClosestPointTo( point, t, 0, SegmentCount() ); }
EXPORT_C TBool CHuiTexture::HasContent() const { return (SegmentCount() > 0); }
ON_BOOL32 ON_PolyEdgeCurve::IsClosed(void) const { //if ( m_is_closed_helper == 1 ) // return true; //if ( m_is_closed_helper == 2 ) // return false; ON_BOOL32 rc = ON_PolyCurve::IsClosed(); if ( !rc && SegmentCount() > 1 ) { // Since the segments that make up a ON_PolyEdgeCurve // cannot have their ends matched (becuase the curves // belong to objects alread in the rhino model), // the IsClosed() test has to tolerate gaps. // // There are two situations. If the start and end // segments are edges that belong to the same brep, // then they "join" if and only if they share a vertex. // Otherwise, the current value of Rhino tolerance // is used. const ON_PolyEdgeSegment* seg0 = SegmentCurve(0); const ON_PolyEdgeSegment* seg1 = SegmentCurve(SegmentCount()-1); const ON_BrepEdge* edge0 = seg0->Edge(); const ON_BrepEdge* edge1 = seg1->Edge(); if ( edge0 && edge1 && edge0->Brep() == edge1->Brep() ) { // check for topological closure // // Do NOT add a test for sloppy geometric closure here. // If the edges are in the same brep and they don't // meet topologicially, then there is something in the // brep that is separating the edges. int evi0 = seg0->ReversedEdgeDir() ? 1 : 0; int evi1 = seg1->ReversedEdgeDir() ? 0 : 1; double et0 = seg0->EdgeParameter(seg0->Domain()[0]); double et1 = seg1->EdgeParameter(seg1->Domain()[1]); if ( et0 != ON_UNSET_VALUE && et1 != ON_UNSET_VALUE ) { ON_Interval edom0 = edge0->Domain(); ON_Interval edom1 = edge1->Domain(); if ( et0 == edom0[evi0] && et1 == edom1[evi1] ) { // The polyedge starts at the (evi0?end:start) of edge0 // and ends at the (ev1?end:start) of edge1. if ( edge0->m_vi[evi0] == edge1->m_vi[evi1] ) { // the polyedge start/ends at a common vertex rc = true; } } else if ( edge0 == edge1 && fabs(et0-et1) <= ON_ZERO_TOLERANCE && edom0.Includes(et0,true) && edom1.Includes(et1,true) ) { // The start/end of the polyedge is an interior point // of a single edge. (This happens when the "seam" gets // adjusted to be inside of an edge.) It is unlikely that // ON_PolyCurve::IsClosed() would return false in this // case, but this check should keep everybody happy. rc = true; } } } else { // check for sloppy geometric closure // // It is important that this test is NOT used when // edge0 and edge1 belong to the same brep. ON_3dPoint p0 = PointAtStart(); ON_3dPoint p1 = PointAtEnd(); double d = p0.DistanceTo(p1); double tol = ON_ZERO_TOLERANCE; //RhinoApp().ActiveDoc()->AbsoluteTolerance(); if ( d <= tol ) rc = true; } } //const_cast<ON_PolyEdgeCurve*>(this)->m_is_closed_helper = (rc) ? 1 :2; return rc; }
ON_BOOL32 ON_PolyEdgeCurve::ChangeClosedCurveSeam( double t ) { //int saved_is_closed_helper = m_is_closed_helper; if ( SegmentCount() == 1 ) { // A ON_PolyEdgeSegment cannot have its start/end // changed. Split it into two segments and let // ON_PolyCurve::ChangeClosedCurveSeam() do the work. if ( !IsClosed() ) return false; ON_Interval crvd = Domain(); double s = crvd.NormalizedParameterAt(t); if ( s <= ON_SQRT_EPSILON || s >= (1.0 - ON_SQRT_EPSILON) ) { s = fmod(s,1.0); if ( s < 0.0 ) s += 1.0; if ( fabs(s) <= ON_SQRT_EPSILON || fabs(1.0-s) <= ON_SQRT_EPSILON ) { // split parameter is at start/end of this segemnt if ( t != crvd[0] ) { DestroyRuntimeCache(); SetDomain(t,t+crvd.Length() ); //m_is_closed_helper = saved_is_closed_helper; } return true; } return false; } ON_PolyEdgeSegment* left_seg = SegmentCurve(0); if ( 0 == left_seg ) return false; DestroyRuntimeCache(); ON_Curve* left = left_seg; ON_Curve* right = 0; double segt = SegmentCurveParameter(t); if ( !left_seg->Split(segt,left,right) ) return false; SetDomain(crvd[0],t); ON_PolyEdgeSegment* right_seg = ON_PolyEdgeSegment::Cast(right); if ( 0 == right_seg ) return false; Append(right_seg); double st[3]; st[0] = crvd[0]; st[1] = t; st[2] = crvd[1]; SetParameterization( st ); } // ON_PolyCurve::ChangeClosedCurveSeam works fine on // two or more segments. ON_BOOL32 rc = ON_PolyCurve::ChangeClosedCurveSeam(t); //if ( saved_is_closed_helper ) // m_is_closed_helper = saved_is_closed_helper; return rc; }