| 668 | } |
| 669 | |
| 670 | void CurvesPrimitiveEvaluator::buildTree() |
| 671 | { |
| 672 | if( m_haveTree ) |
| 673 | { |
| 674 | return; |
| 675 | } |
| 676 | |
| 677 | std::lock_guard<TreeMutex> lock( m_treeMutex ); |
| 678 | if( m_haveTree ) |
| 679 | { |
| 680 | // another thread may have built the tree while we waited for the mutex |
| 681 | return; |
| 682 | } |
| 683 | |
| 684 | bool linear = m_curvesPrimitive->basis() == CubicBasisf::linear(); |
| 685 | const std::vector<V3f> &p = static_cast<const V3fVectorData *>( m_p.data.get() )->readable(); |
| 686 | PrimitiveEvaluator::ResultPtr result = createResult(); |
| 687 | |
| 688 | size_t numCurves = m_curvesPrimitive->numCurves(); |
| 689 | for( size_t curveIndex = 0; curveIndex<numCurves; curveIndex++ ) |
| 690 | { |
| 691 | if( linear ) |
| 692 | { |
| 693 | int numVertices = m_verticesPerCurve[curveIndex]; |
| 694 | int vertIndex = m_vertexDataOffsets[curveIndex]; |
| 695 | float prevV = 0.0f; |
| 696 | for( int i=0; i<numVertices; i++, vertIndex++ ) |
| 697 | { |
| 698 | float v = Imath::clamp( (float)i/(float)(numVertices-1), 0.0f, 1.0f ); |
| 699 | if( i!=0 ) |
| 700 | { |
| 701 | Box3f b; |
| 702 | b.extendBy( p[vertIndex-1] ); |
| 703 | b.extendBy( p[vertIndex] ); |
| 704 | m_treeBounds.push_back( b ); |
| 705 | m_treeLines.push_back( Line( p[vertIndex-1], p[vertIndex], curveIndex, prevV, v ) ); |
| 706 | } |
| 707 | prevV = v; |
| 708 | } |
| 709 | } |
| 710 | else |
| 711 | { |
| 712 | unsigned numSegments = m_curvesPrimitive->numSegments( curveIndex ); |
| 713 | int steps = numSegments * Line::linesPerCurveSegment(); |
| 714 | V3f prevP( 0 ); |
| 715 | float prevV = 0; |
| 716 | for( int i=0; i<steps; i++ ) |
| 717 | { |
| 718 | float v = Imath::clamp( (float)i/(float)(steps-1), 0.0f, 1.0f ); |
| 719 | pointAtV( curveIndex, v, result.get() ); |
| 720 | V3f newP = result->point(); |
| 721 | if( i!=0 ) |
| 722 | { |
| 723 | Box3f b; |
| 724 | b.extendBy( prevP ); |
| 725 | b.extendBy( newP ); |
| 726 | m_treeBounds.push_back( b ); |
| 727 | m_treeLines.push_back( Line( prevP, newP, curveIndex, prevV, v ) ); |