| 3819 | } |
| 3820 | |
| 3821 | void |
| 3822 | RotoContextPrivate::computeTriangles(const Bezier * bezier, double time, unsigned int mipmapLevel, double featherDist, |
| 3823 | std::list<RotoFeatherVertex>* featherMesh, |
| 3824 | std::list<RotoTriangleFans>* internalFans, |
| 3825 | std::list<RotoTriangles>* internalTriangles, |
| 3826 | std::list<RotoTriangleStrips>* internalStrips) |
| 3827 | { |
| 3828 | ///Note that we do not use the opacity when rendering the bezier, it is rendered with correct floating point opacity/color when converting |
| 3829 | ///to the Natron image. |
| 3830 | |
| 3831 | bool clockWise = bezier->isFeatherPolygonClockwiseOriented(false, time); |
| 3832 | |
| 3833 | const double absFeatherDist = std::abs(featherDist); |
| 3834 | |
| 3835 | std::list<std::list<ParametricPoint> > featherPolygon; |
| 3836 | std::list<std::list<ParametricPoint> > bezierPolygon; |
| 3837 | |
| 3838 | RectD featherPolyBBox; |
| 3839 | featherPolyBBox.setupInfinity(); |
| 3840 | |
| 3841 | #ifdef ROTO_BEZIER_EVAL_ITERATIVE |
| 3842 | int error = -1; |
| 3843 | #else |
| 3844 | double error = 1; |
| 3845 | #endif |
| 3846 | |
| 3847 | bezier->evaluateFeatherPointsAtTime_DeCasteljau(false, time, mipmapLevel,error, true, &featherPolygon, &featherPolyBBox); |
| 3848 | bezier->evaluateAtTime_DeCasteljau(false, time, mipmapLevel, error,&bezierPolygon, NULL); |
| 3849 | |
| 3850 | |
| 3851 | // First compute the mesh composed of triangles of the feather |
| 3852 | assert( !featherPolygon.empty() && !bezierPolygon.empty() && featherPolygon.size() == bezierPolygon.size()); |
| 3853 | |
| 3854 | std::list<std::list<ParametricPoint> >::const_iterator fIt = featherPolygon.begin(); |
| 3855 | for (std::list<std::list<ParametricPoint> > ::const_iterator it = bezierPolygon.begin(); it != bezierPolygon.end(); ++it, ++fIt) { |
| 3856 | |
| 3857 | // Iterate over each bezier segment. |
| 3858 | // There are the same number of bezier segments for the feather and the internal bezier. Each discretized segment is a contour (list of vertices) |
| 3859 | |
| 3860 | std::list<ParametricPoint>::const_iterator bSegmentIt = it->begin(); |
| 3861 | std::list<ParametricPoint>::const_iterator fSegmentIt = fIt->begin(); |
| 3862 | |
| 3863 | assert(!it->empty() && !fIt->empty()); |
| 3864 | |
| 3865 | |
| 3866 | // prepare iterators to compute derivatives for feather distance |
| 3867 | std::list<ParametricPoint>::const_iterator fnext = fSegmentIt; |
| 3868 | ++fnext; // can only be valid since we assert the list is not empty |
| 3869 | if ( fnext == fIt->end() ) { |
| 3870 | fnext = fIt->begin(); |
| 3871 | } |
| 3872 | std::list<ParametricPoint>::const_iterator fprev = fIt->end(); |
| 3873 | --fprev; // can only be valid since we assert the list is not empty |
| 3874 | |
| 3875 | |
| 3876 | // initialize the state with a segment between the first inner vertex and first outer vertex |
| 3877 | RotoFeatherVertex lastInnerVert,lastOutterVert; |
| 3878 | { |
nothing calls this directly
no test coverage detected