From 2fd11a6617b84dbe5cae1a2c3f9145830b2bbfd4 Mon Sep 17 00:00:00 2001 From: Stuart Broadfoot Date: Sun, 18 Aug 2013 13:41:53 +0000 Subject: [PATCH] Updates for the Cycle Hair UI. With the following changes - Removed the cycles subdivision and interpolation of hairkeys. - Removed the parent settings. - Removed all of the advanced settings and presets. - This simplifies the UI to a few settings for the primitive type and a shape mode. --- intern/cycles/blender/addon/properties.py | 113 +---- intern/cycles/blender/addon/ui.py | 47 +- intern/cycles/blender/blender_curves.cpp | 528 ++++++---------------- intern/cycles/bvh/bvh.cpp | 8 - intern/cycles/kernel/kernel_bvh.h | 12 +- intern/cycles/kernel/kernel_curve.h | 6 +- intern/cycles/kernel/kernel_types.h | 18 +- intern/cycles/render/attribute.cpp | 5 - intern/cycles/render/curves.cpp | 31 +- intern/cycles/render/curves.h | 14 +- 10 files changed, 189 insertions(+), 593 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index eba94604a88..5a0b13d3714 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -64,40 +64,20 @@ enum_panorama_types = ( "Similar to most fisheye modern lens, takes sensor dimensions into consideration"), ) -enum_curve_presets = ( - ('CUSTOM', "Custom", "Set general parameters"), - ('FAST_PLANES', "Fast Planes", "Use camera facing triangles (fast but memory intensive)"), - ('TANGENT_SHADING', "Tangent Normal", "Use planar line segments and tangent normals"), - ('TRUE_NORMAL', "True Normal", "Use true normals with line segments(good for thin strands)"), - ('ACCURATE_PRESET', "Accurate", "Use best line segment settings (suitable for glass materials)"), - ('SMOOTH_CURVES', "Smooth Curves", "Use smooth cardinal curves (slowest)"), - ('SMOOTH_RIBBONS', "Ribbons", "Use smooth cardinal curves without thickness"), - ) - enum_curve_primitives = ( ('TRIANGLES', "Triangles", "Create triangle geometry around strands"), ('LINE_SEGMENTS', "Line Segments", "Use line segment primitives"), ('CURVE_SEGMENTS', "Curve Segments", "Use segmented cardinal curve primitives"), - ('CURVE_RIBBONS', "Curve Ribbons", "Use smooth cardinal curve ribbon primitives"), ) enum_triangle_curves = ( ('CAMERA_TRIANGLES', "Planes", "Create individual triangles forming planes that face camera"), - ('RIBBON_TRIANGLES', "Ribbons", "Create individual triangles forming ribbon"), ('TESSELLATED_TRIANGLES', "Tessellated", "Create mesh surrounding each strand"), ) -enum_line_curves = ( - ('ACCURATE', "Accurate", "Always take into consideration strand width for intersections"), - ('QT_CORRECTED', "Corrected", "Ignore width for initial intersection and correct later"), - ('ENDCORRECTED', "Correct found", "Ignore width for all intersections and only correct closest"), - ('QT_UNCORRECTED', "Uncorrected", "Calculate intersections without considering width"), - ) - -enum_curves_interpolation = ( - ('LINEAR', "Linear interpolation", "Use Linear interpolation between segments"), - ('CARDINAL', "Cardinal interpolation", "Use cardinal interpolation between segments"), - ('BSPLINE', "B-spline interpolation", "Use b-spline interpolation between segments"), +enum_curve_shape = ( + ('RIBBONS', "Ribbons", "Ignore thickness of each strand"), + ('THICK', "Thick", "Use thickness of strand when rendering"), ) enum_tile_order = ( @@ -689,105 +669,34 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): description="Cycles hair rendering settings", type=cls, ) - cls.preset = EnumProperty( - name="Mode", - description="Hair rendering mode", - items=enum_curve_presets, - default='TRUE_NORMAL', - ) cls.primitive = EnumProperty( name="Primitive", description="Type of primitive used for hair rendering", items=enum_curve_primitives, default='LINE_SEGMENTS', ) - cls.triangle_method = EnumProperty( - name="Mesh Geometry", - description="Method for creating triangle geometry", - items=enum_triangle_curves, - default='CAMERA_TRIANGLES', + cls.shape = EnumProperty( + name="Shape", + description="Form of hair", + items=enum_curve_shape, + default='THICK', ) - cls.line_method = EnumProperty( - name="Intersection Method", - description="Method for line segment intersection", - items=enum_line_curves, - default='ACCURATE', - ) - cls.interpolation = EnumProperty( - name="Interpolation", - description="Interpolation method", - items=enum_curves_interpolation, - default='BSPLINE', - ) - cls.use_backfacing = BoolProperty( - name="Check back-faces", - description="Test back-faces of strands", - default=False, - ) - cls.use_encasing = BoolProperty( - name="Exclude encasing", - description="Ignore strands encasing a ray's initial location", + cls.cull_backfacing = BoolProperty( + name="Cull back-faces", + description="Do not test the back-face of each strand", default=True, ) - cls.use_tangent_normal_geometry = BoolProperty( - name="Tangent normal geometry", - description="Use the tangent normal for actual normal", - default=False, - ) - cls.use_tangent_normal = BoolProperty( - name="Tangent normal default", - description="Use the tangent normal for all normals", - default=False, - ) - cls.use_tangent_normal_correction = BoolProperty( - name="Strand slope correction", - description="Correct the tangent normal for the strand's slope", - default=False, - ) - cls.use_parents = BoolProperty( - name="Use parent strands", - description="Use parents with children", - default=False, - ) - cls.use_smooth = BoolProperty( - name="Smooth Strands", - description="Use vertex normals", - default=True, - ) - cls.use_joined = BoolProperty( - name="Join", - description="Fill gaps between segments (requires more memory)", - default=False, - ) cls.use_curves = BoolProperty( name="Use Cycles Hair Rendering", description="Activate Cycles hair rendering for particle system", default=True, ) - cls.segments = IntProperty( - name="Segments", - description="Number of segments between path keys (note that this combines with the 'draw step' value)", - min=1, max=64, - default=1, - ) cls.resolution = IntProperty( name="Resolution", description="Resolution of generated mesh", min=3, max=64, default=3, ) - cls.normalmix = FloatProperty( - name="Normal mix", - description="Scale factor for tangent normal removal (zero gives ray normal)", - min=0, max=2.0, - default=1, - ) - cls.encasing_ratio = FloatProperty( - name="Encasing ratio", - description="Scale factor for encasing strand width", - min=0.0, max=100.0, - default=1.01, - ) cls.minimum_width = FloatProperty( name="Minimal width", description="Minimal pixel width for strands (0 - deactivated)", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 64fda3ef535..f30762f5fea 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1152,44 +1152,17 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel): layout.active = ccscene.use_curves - layout.prop(ccscene, "preset", text="Mode") + layout.prop(ccscene, "primitive", text="Primitive") + layout.prop(ccscene, "shape", text="Shape") - if ccscene.preset == 'CUSTOM': - layout.prop(ccscene, "primitive", text="Primitive") - - if ccscene.primitive == 'TRIANGLES': - layout.prop(ccscene, "triangle_method", text="Method") - if ccscene.triangle_method == 'TESSELLATED_TRIANGLES': - layout.prop(ccscene, "resolution", text="Resolution") - layout.prop(ccscene, "use_smooth", text="Smooth") - elif ccscene.primitive == 'LINE_SEGMENTS': - layout.prop(ccscene, "use_backfacing", text="Check back-faces") - - row = layout.row() - row.prop(ccscene, "use_encasing", text="Exclude encasing") - sub = row.row() - sub.active = ccscene.use_encasing - sub.prop(ccscene, "encasing_ratio", text="Ratio for encasing") - - layout.prop(ccscene, "line_method", text="Method") - layout.prop(ccscene, "use_tangent_normal", text="Use tangent normal as default") - layout.prop(ccscene, "use_tangent_normal_geometry", text="Use tangent normal geometry") - layout.prop(ccscene, "use_tangent_normal_correction", text="Correct tangent normal for slope") - layout.prop(ccscene, "interpolation", text="Interpolation") - - row = layout.row() - row.prop(ccscene, "segments", text="Segments") - row.prop(ccscene, "normalmix", text="Ray Mix") - elif ccscene.primitive in {'CURVE_SEGMENTS', 'CURVE_RIBBONS'}: - layout.prop(ccscene, "subdivisions", text="Curve subdivisions") - layout.prop(ccscene, "use_backfacing", text="Check back-faces") - - layout.prop(ccscene, "interpolation", text="Interpolation") - row = layout.row() - row.prop(ccscene, "segments", text="Segments") - - row = layout.row() - row.prop(ccscene, "use_parents", text="Include parents") + if ccscene.primitive == 'TRIANGLES': + if ccscene.shape == 'THICK': + layout.prop(ccscene, "resolution", text="Resolution") + elif ccscene.primitive == 'LINE_SEGMENTS': + layout.prop(ccscene, "cull_backfacing", text="Cull back-faces") + elif ccscene.primitive in {'CURVE_SEGMENTS', 'CURVE_RIBBONS'}: + layout.prop(ccscene, "cull_backfacing", text="Cull back-faces") + layout.prop(ccscene, "subdivisions", text="Curve subdivisions") row = layout.row() row.prop(ccscene, "minimum_width", text="Min Pixels") diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 27c52797f5f..955d062a710 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -37,15 +37,14 @@ void curveinterp_v3_v3v3v3v3(float3 *p, float3 *v1, float3 *v2, float3 *v3, floa void interp_weights(float t, float data[4], int type); float shaperadius(float shape, float root, float tip, float time); void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyloc, float *time, ParticleCurveData *CData, int interpolation); -bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background, int uv_num); -bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background, int vcol_num); -bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background); -void ExportCurveSegments(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments); -void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, float3 RotCam); -void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments); -void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int resolution, int segments); -void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments, int vert_offset, int resol, float3 *uvdata); -void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments, int vert_offset, int resol, float3 *fdata); +bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int uv_num); +bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num); +bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background); +void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData); +void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotCam); +void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resolution); +void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *uvdata); +void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *fdata); ParticleCurveData::ParticleCurveData() { @@ -157,7 +156,7 @@ void InterpolateKeySegments(int seg, int segno, int key, int curve, float3 *keyl curveinterp_v3_v3v3v3v3(keyloc, &ckey_loc1, &ckey_loc2, &ckey_loc3, &ckey_loc4, t); } -bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background) +bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background) { int curvenum = 0; @@ -188,7 +187,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_psys.settings().draw_percentage() / 100.0f); int totcurves = totchild; - if(use_parents || b_psys.settings().child_type() == 0) + if(b_psys.settings().child_type() == 0) totcurves += totparts; if(totcurves == 0) @@ -208,7 +207,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par CData->psys_closetip.push_back(get_boolean(cpsys, "use_closetip")); int pa_no = 0; - if(!use_parents && !(b_psys.settings().child_type() == 0)) + if(!(b_psys.settings().child_type() == 0)) pa_no = totparts; for(; pa_no < totparts+totchild; pa_no++) { @@ -244,7 +243,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par } -bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background, int uv_num) +bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int uv_num) { #if 0 int keyno = 0; @@ -279,14 +278,14 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_psys.settings().draw_percentage() / 100.0f); int totcurves = totchild; - if (use_parents || b_psys.settings().child_type() == 0) + if (b_psys.settings().child_type() == 0) totcurves += totparts; if (totcurves == 0) continue; int pa_no = 0; - if(!use_parents && !(b_psys.settings().child_type() == 0)) + if(!(b_psys.settings().child_type() == 0)) pa_no = totparts; BL::ParticleSystem::particles_iterator b_pa; @@ -315,7 +314,7 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti } -bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool use_parents, bool background, int vcol_num) +bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num) { #if 0 int keyno = 0; @@ -348,14 +347,14 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_psys.settings().draw_percentage() / 100.0f); int totcurves = totchild; - if (use_parents || b_psys.settings().child_type() == 0) + if (b_psys.settings().child_type() == 0) totcurves += totparts; if (totcurves == 0) continue; int pa_no = 0; - if(!use_parents && !(b_psys.settings().child_type() == 0)) + if(!(b_psys.settings().child_type() == 0)) pa_no = totparts; BL::ParticleSystem::particles_iterator b_pa; @@ -396,7 +395,7 @@ static void set_resolution(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, BL::S } } -void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments, float3 RotCam) +void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, float3 RotCam) { int vertexno = mesh->verts.size(); int vertexindex = vertexno; @@ -404,52 +403,44 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpo for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) { for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) { - for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { + float3 xbasis; + float3 v1; + float time = 0.0f; + float3 ickey_loc = CData->curvekey_co[CData->curve_firstkey[curve]]; + float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.0f); + v1 = CData->curvekey_co[CData->curve_firstkey[curve] + 1] - CData->curvekey_co[CData->curve_firstkey[curve]]; + xbasis = normalize(cross(RotCam - ickey_loc,v1)); + float3 ickey_loc_shfl = ickey_loc - radius * xbasis; + float3 ickey_loc_shfr = ickey_loc + radius * xbasis; + mesh->verts.push_back(ickey_loc_shfl); + mesh->verts.push_back(ickey_loc_shfr); + vertexindex += 2; - int subv = 1; - float3 xbasis; + for( int curvekey = CData->curve_firstkey[curve] + 1; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) { + ickey_loc = CData->curvekey_co[curvekey]; - float3 v1; - - if(curvekey == CData->curve_firstkey[curve]) { - subv = 0; - v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey]; - } - else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) - v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 2, CData->curve_firstkey[curve])]; + if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) + v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[max(curvekey - 1, CData->curve_firstkey[curve])]; else v1 = CData->curvekey_co[curvekey + 1] - CData->curvekey_co[curvekey - 1]; + time = CData->curvekey_time[curvekey]/CData->curve_length[curve]; + radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - for (; subv <= segments; subv++) { + if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) + radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); - float3 ickey_loc = make_float3(0.0f,0.0f,0.0f); - float time = 0.0f; + if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) + radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0)) - ickey_loc = CData->curvekey_co[curvekey]; - else - InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation); - - float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - - if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments)) - radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); - - if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) - radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - - xbasis = normalize(cross(RotCam - ickey_loc,v1)); - float3 ickey_loc_shfl = ickey_loc - radius * xbasis; - float3 ickey_loc_shfr = ickey_loc + radius * xbasis; - mesh->verts.push_back(ickey_loc_shfl); - mesh->verts.push_back(ickey_loc_shfr); - if(subv!=0) { - mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], use_smooth); - mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], use_smooth); - } - vertexindex += 2; - } + xbasis = normalize(cross(RotCam - ickey_loc,v1)); + float3 ickey_loc_shfl = ickey_loc - radius * xbasis; + float3 ickey_loc_shfr = ickey_loc + radius * xbasis; + mesh->verts.push_back(ickey_loc_shfl); + mesh->verts.push_back(ickey_loc_shfr); + mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], true); + mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], true); + vertexindex += 2; } } } @@ -464,120 +455,7 @@ void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData, int interpo /* texture coords still needed */ } -void ExportCurveTriangleRibbons(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int segments) -{ - int vertexno = mesh->verts.size(); - int vertexindex = vertexno; - - for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) { - for( int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys] ; curve++) { - - float3 firstxbasis = cross(make_float3(1.0f,0.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]]); - if(len_squared(firstxbasis)!= 0.0f) - firstxbasis = normalize(firstxbasis); - else - firstxbasis = normalize(cross(make_float3(0.0f,1.0f,0.0f),CData->curvekey_co[CData->curve_firstkey[curve]+1] - CData->curvekey_co[CData->curve_firstkey[curve]])); - - for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { - - float3 xbasis = firstxbasis; - float3 v1; - float3 v2; - - if(curvekey == CData->curve_firstkey[curve]) { - v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1]; - v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; - } - else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { - v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; - v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])]; - } - else { - v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; - v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; - } - - xbasis = cross(v1,v2); - - if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) { - firstxbasis = normalize(xbasis); - break; - } - } - - for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { - - int subv = 1; - float3 v1; - float3 v2; - float3 xbasis; - - if(curvekey == CData->curve_firstkey[curve]) { - subv = 0; - v1 = CData->curvekey_co[min(curvekey+2,CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)] - CData->curvekey_co[curvekey+1]; - v2 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; - } - else if(curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1) { - v1 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; - v2 = CData->curvekey_co[curvekey-1] - CData->curvekey_co[max(curvekey-2,CData->curve_firstkey[curve])]; - } - else { - v1 = CData->curvekey_co[curvekey+1] - CData->curvekey_co[curvekey]; - v2 = CData->curvekey_co[curvekey] - CData->curvekey_co[curvekey-1]; - } - - xbasis = cross(v1,v2); - - if(len_squared(xbasis) >= 0.05f * len_squared(v1) * len_squared(v2)) { - xbasis = normalize(xbasis); - firstxbasis = xbasis; - } - else - xbasis = firstxbasis; - - for (; subv <= segments; subv++) { - - float3 ickey_loc = make_float3(0.0f,0.0f,0.0f); - float time = 0.0f; - - if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0)) - ickey_loc = CData->curvekey_co[curvekey]; - else - InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation); - - float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - - if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments)) - radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); - - if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) - radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); - - float3 ickey_loc_shfl = ickey_loc - radius * xbasis; - float3 ickey_loc_shfr = ickey_loc + radius * xbasis; - mesh->verts.push_back(ickey_loc_shfl); - mesh->verts.push_back(ickey_loc_shfr); - if(subv!=0) { - mesh->add_triangle(vertexindex-2, vertexindex, vertexindex-1, CData->psys_shader[sys], use_smooth); - mesh->add_triangle(vertexindex+1, vertexindex-1, vertexindex, CData->psys_shader[sys], use_smooth); - } - vertexindex += 2; - } - } - } - } - - mesh->reserve(mesh->verts.size(), mesh->triangles.size(), 0, 0); - mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL); - mesh->attributes.remove(ATTR_STD_FACE_NORMAL); - mesh->add_face_normals(); - mesh->add_vertex_normals(); - mesh->attributes.remove(ATTR_STD_FACE_NORMAL); - /* texture coords still needed */ - -} - -void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int interpolation, bool use_smooth, int resolution, int segments) +void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int resolution) { int vertexno = mesh->verts.size(); int vertexindex = vertexno; @@ -652,22 +530,19 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter ybasis = normalize(cross(xbasis,v2)); - for (; subv <= segments; subv++) { + for (; subv <= 1; subv++) { float3 ickey_loc = make_float3(0.0f,0.0f,0.0f); float time = 0.0f; - if ((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0)) - ickey_loc = CData->curvekey_co[curvekey]; - else - InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation); + InterpolateKeySegments(subv, 1, curvekey, curve, &ickey_loc, &time, CData , 1); float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == segments)) + if((curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2) && (subv == 1)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], 0.95f); - if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) + if(CData->psys_closetip[sys] && (subv == 1) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], 0.0f, 0.95f); float angle = M_2PI_F / (float)resolution; @@ -678,11 +553,11 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter if(subv!=0) { for(int section = 0 ; section < resolution - 1; section++) { - mesh->add_triangle(vertexindex - resolution + section, vertexindex + section, vertexindex - resolution + section + 1, CData->psys_shader[sys], use_smooth); - mesh->add_triangle(vertexindex + section + 1, vertexindex - resolution + section + 1, vertexindex + section, CData->psys_shader[sys], use_smooth); + mesh->add_triangle(vertexindex - resolution + section, vertexindex + section, vertexindex - resolution + section + 1, CData->psys_shader[sys], true); + mesh->add_triangle(vertexindex + section + 1, vertexindex - resolution + section + 1, vertexindex + section, CData->psys_shader[sys], true); } - mesh->add_triangle(vertexindex-1, vertexindex + resolution - 1, vertexindex - resolution, CData->psys_shader[sys], use_smooth); - mesh->add_triangle(vertexindex, vertexindex - resolution , vertexindex + resolution - 1, CData->psys_shader[sys], use_smooth); + mesh->add_triangle(vertexindex-1, vertexindex + resolution - 1, vertexindex - resolution, CData->psys_shader[sys], true); + mesh->add_triangle(vertexindex, vertexindex - resolution , vertexindex + resolution - 1, CData->psys_shader[sys], true); } vertexindex += resolution; } @@ -700,7 +575,7 @@ void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, int inter /* texture coords still needed */ } -static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments) +static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CData) { int num_keys = 0; int num_curves = 0; @@ -725,33 +600,19 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa size_t num_curve_keys = 0; - for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { + for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) { + float3 ickey_loc = CData->curvekey_co[curvekey]; + float time = CData->curvekey_time[curvekey]/CData->curve_length[curve]; + float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - int subv = 1; - if(curvekey == CData->curve_firstkey[curve]) - subv = 0; + if(CData->psys_closetip[sys] && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1)) + radius =0.0f; - for (; subv <= segments; subv++) { + mesh->add_curve_key(ickey_loc, radius); + if(attr_intercept) + attr_intercept->add(time); - float3 ickey_loc = make_float3(0.0f,0.0f,0.0f); - float time = 0.0f; - - if((interpolation == CURVE_BSPLINE) && (curvekey == CData->curve_firstkey[curve]) && (subv == 0)) - ickey_loc = CData->curvekey_co[curvekey]; - else - InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation); - - float radius = shaperadius(CData->psys_shape[sys], CData->psys_rootradius[sys], CData->psys_tipradius[sys], time); - - if(CData->psys_closetip[sys] && (subv == segments) && (curvekey == CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 2)) - radius =0.0f; - - mesh->add_curve_key(ickey_loc, radius); - if(attr_intercept) - attr_intercept->add(time); - - num_curve_keys++; - } + num_curve_keys++; } mesh->add_curve(num_keys, num_curve_keys, CData->psys_shader[sys]); @@ -769,7 +630,7 @@ static void ExportCurveSegments(Scene *scene, Mesh *mesh, ParticleCurveData *CDa } } -void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments, int vert_offset, int resol, float3 *uvdata) +void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *uvdata) { if(uvdata == NULL) return; @@ -784,56 +645,42 @@ void ExportCurveTriangleUV(Mesh *mesh, ParticleCurveData *CData, int interpolati for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { - int subv = 1; + time = CData->curvekey_time[curvekey]/CData->curve_length[curve]; - if (curvekey == CData->curve_firstkey[curve]) - subv = 0; - - for (; subv <= segments; subv++) { - - float3 ickey_loc = make_float3(0.0f,0.0f,0.0f); - - InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation); - - if(subv!=0) { - for(int section = 0 ; section < resol; section++) { - uvdata[vertexindex] = CData->curve_uv[curve]; - uvdata[vertexindex].z = prevtime; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - uvdata[vertexindex].z = time; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - uvdata[vertexindex].z = prevtime; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - uvdata[vertexindex].z = time; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - uvdata[vertexindex].z = prevtime; - vertexindex++; - uvdata[vertexindex] = CData->curve_uv[curve]; - uvdata[vertexindex].z = time; - vertexindex++; - } - } - - prevtime = time; + for(int section = 0 ; section < resol; section++) { + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = prevtime; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = time; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = prevtime; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = time; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = prevtime; + vertexindex++; + uvdata[vertexindex] = CData->curve_uv[curve]; + uvdata[vertexindex].z = time; + vertexindex++; } + + prevtime = time; + } } } } -void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int interpolation, int segments, int vert_offset, int resol, float3 *fdata) +void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int vert_offset, int resol, float3 *fdata) { if(fdata == NULL) return; - float time = 0.0f; -// float prevtime = 0.0f; // UNUSED - int vertexindex = vert_offset; for( int sys = 0; sys < CData->psys_firstcurve.size() ; sys++) { @@ -841,35 +688,19 @@ void ExportCurveTriangleVcol(Mesh *mesh, ParticleCurveData *CData, int interpola for( int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) { - int subv = 1; - - if (curvekey == CData->curve_firstkey[curve]) - subv = 0; - - for (; subv <= segments; subv++) { - - float3 ickey_loc = make_float3(0.0f,0.0f,0.0f); - - InterpolateKeySegments(subv, segments, curvekey, curve, &ickey_loc, &time, CData , interpolation); - - if(subv!=0) { - for(int section = 0 ; section < resol; section++) { - fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); - vertexindex++; - fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); - vertexindex++; - fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); - vertexindex++; - fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); - vertexindex++; - fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); - vertexindex++; - fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); - vertexindex++; - } - } - - // prevtime = time; // UNUSED + for(int section = 0 ; section < resol; section++) { + fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); + vertexindex++; + fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); + vertexindex++; + fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); + vertexindex++; + fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); + vertexindex++; + fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); + vertexindex++; + fdata[vertexindex] = color_srgb_to_scene_linear(CData->curve_vcol[curve]); + vertexindex++; } } } @@ -883,7 +714,7 @@ void BlenderSync::sync_curve_settings() { PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves"); - int preset = get_enum(csscene, "preset"); + int preset = CURVE_ACCURATE_PRESET; CurveSystemManager *curve_system_manager = scene->curve_system_manager; CurveSystemManager prev_curve_system_manager = *curve_system_manager; @@ -892,86 +723,40 @@ void BlenderSync::sync_curve_settings() curve_system_manager->minimum_width = get_float(csscene, "minimum_width"); curve_system_manager->maximum_width = get_float(csscene, "maximum_width"); - if(preset == CURVE_CUSTOM) { - /*custom properties*/ - curve_system_manager->primitive = get_enum(csscene, "primitive"); - curve_system_manager->line_method = get_enum(csscene, "line_method"); - curve_system_manager->interpolation = get_enum(csscene, "interpolation"); - curve_system_manager->triangle_method = get_enum(csscene, "triangle_method"); - curve_system_manager->resolution = get_int(csscene, "resolution"); - curve_system_manager->segments = get_int(csscene, "segments"); - curve_system_manager->use_smooth = get_boolean(csscene, "use_smooth"); - curve_system_manager->subdivisions = get_int(csscene, "subdivisions"); + curve_system_manager->primitive = get_enum(csscene, "primitive"); + curve_system_manager->curve_shape = get_enum(csscene, "shape"); + curve_system_manager->resolution = get_int(csscene, "resolution"); + curve_system_manager->subdivisions = get_int(csscene, "subdivisions"); + curve_system_manager->use_backfacing = !get_boolean(csscene, "cull_backfacing"); - curve_system_manager->normalmix = get_float(csscene, "normalmix"); - curve_system_manager->encasing_ratio = get_float(csscene, "encasing_ratio"); + curve_system_manager->encasing_ratio = 1.01f; - curve_system_manager->use_parents = get_boolean(csscene, "use_parents"); - curve_system_manager->use_encasing = get_boolean(csscene, "use_encasing"); - curve_system_manager->use_backfacing = get_boolean(csscene, "use_backfacing"); - curve_system_manager->use_joined = get_boolean(csscene, "use_joined"); - curve_system_manager->use_tangent_normal = get_boolean(csscene, "use_tangent_normal"); - curve_system_manager->use_tangent_normal_geometry = get_boolean(csscene, "use_tangent_normal_geometry"); - curve_system_manager->use_tangent_normal_correction = get_boolean(csscene, "use_tangent_normal_correction"); + if(curve_system_manager->primitive == CURVE_TRIANGLES && curve_system_manager->curve_shape == CURVE_RIBBON) { + /*camera facing planes*/ + curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES; + curve_system_manager->resolution = 1; } - else { - curve_system_manager->primitive = CURVE_LINE_SEGMENTS; - curve_system_manager->interpolation = CURVE_CARDINAL; - curve_system_manager->normalmix = 1.0f; - curve_system_manager->encasing_ratio = 1.01f; - curve_system_manager->use_parents = false; - curve_system_manager->segments = 1; - curve_system_manager->use_joined = false; - - switch(preset) { - case CURVE_FAST_PLANES: - /*camera facing planes*/ - curve_system_manager->primitive = CURVE_TRIANGLES; - curve_system_manager->triangle_method = CURVE_CAMERA_TRIANGLES; - curve_system_manager->use_smooth = true; - curve_system_manager->resolution = 1; - break; - case CURVE_TANGENT_SHADING: - /*tangent shading*/ - curve_system_manager->line_method = CURVE_UNCORRECTED; - curve_system_manager->use_encasing = true; - curve_system_manager->use_backfacing = false; - curve_system_manager->use_tangent_normal = true; - curve_system_manager->use_tangent_normal_geometry = true; - curve_system_manager->use_tangent_normal_correction = false; - break; - case CURVE_TRUE_NORMAL: - /*True Normal*/ - curve_system_manager->line_method = CURVE_CORRECTED; - curve_system_manager->use_encasing = true; - curve_system_manager->use_backfacing = false; - curve_system_manager->use_tangent_normal = false; - curve_system_manager->use_tangent_normal_geometry = false; - curve_system_manager->use_tangent_normal_correction = false; - break; - case CURVE_ACCURATE_PRESET: - /*Accurate*/ - curve_system_manager->line_method = CURVE_ACCURATE; - curve_system_manager->use_encasing = false; - curve_system_manager->use_backfacing = true; - curve_system_manager->use_tangent_normal = false; - curve_system_manager->use_tangent_normal_geometry = false; - curve_system_manager->use_tangent_normal_correction = false; - break; - case CURVE_SMOOTH_CURVES: - /*Cardinal curves preset*/ - curve_system_manager->primitive = CURVE_SEGMENTS; - curve_system_manager->use_backfacing = true; - curve_system_manager->subdivisions = 4; - break; - case CURVE_SMOOTH_RIBBONS: - /*Cardinal ribbons preset*/ - curve_system_manager->primitive = CURVE_RIBBONS; - curve_system_manager->use_backfacing = false; - curve_system_manager->subdivisions = 4; - break; - } - + if(curve_system_manager->primitive == CURVE_TRIANGLES && curve_system_manager->curve_shape == CURVE_THICK) { + /*camera facing planes*/ + curve_system_manager->triangle_method = CURVE_TESSELATED_TRIANGLES; + } + if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS && curve_system_manager->curve_shape == CURVE_RIBBON) { + /*tangent shading*/ + curve_system_manager->line_method = CURVE_UNCORRECTED; + curve_system_manager->use_encasing = true; + curve_system_manager->use_backfacing = false; + curve_system_manager->use_tangent_normal = true; + curve_system_manager->use_tangent_normal_geometry = true; + } + if(curve_system_manager->primitive == CURVE_LINE_SEGMENTS && curve_system_manager->curve_shape == CURVE_THICK) { + curve_system_manager->line_method = CURVE_ACCURATE; + curve_system_manager->use_encasing = false; + curve_system_manager->use_tangent_normal = false; + curve_system_manager->use_tangent_normal_geometry = false; + } + if(curve_system_manager->primitive == CURVE_SEGMENTS && curve_system_manager->curve_shape == CURVE_RIBBON) { + curve_system_manager->primitive = CURVE_RIBBONS; + curve_system_manager->use_backfacing = false; } if(curve_system_manager->modified_mesh(prev_curve_system_manager)) @@ -1013,13 +798,8 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool } int primitive = scene->curve_system_manager->primitive; - int interpolation = scene->curve_system_manager->interpolation; int triangle_method = scene->curve_system_manager->triangle_method; int resolution = scene->curve_system_manager->resolution; - int segments = scene->curve_system_manager->segments; - bool use_smooth = scene->curve_system_manager->use_smooth; - bool use_parents = scene->curve_system_manager->use_parents; - bool export_tgs = scene->curve_system_manager->use_joined; size_t vert_num = mesh->verts.size(); size_t tri_num = mesh->triangles.size(); int used_res = 1; @@ -1031,7 +811,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool if(!preview) set_resolution(mesh, &b_mesh, &b_ob, &b_scene, true); - ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, use_parents, !preview); + ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview); /* obtain camera parameters */ BL::Object b_CamOb = b_scene.camera(); @@ -1046,30 +826,14 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool /* add hair geometry to mesh */ if(primitive == CURVE_TRIANGLES){ if(triangle_method == CURVE_CAMERA_TRIANGLES) - ExportCurveTrianglePlanes(mesh, &CData, interpolation, use_smooth, segments, RotCam); - else if(triangle_method == CURVE_RIBBON_TRIANGLES) - ExportCurveTriangleRibbons(mesh, &CData, interpolation, use_smooth, segments); + ExportCurveTrianglePlanes(mesh, &CData, RotCam); else { - ExportCurveTriangleGeometry(mesh, &CData, interpolation, use_smooth, resolution, segments); + ExportCurveTriangleGeometry(mesh, &CData, resolution); used_res = resolution; } } else { - ExportCurveSegments(scene, mesh, &CData, interpolation, segments); - int ckey_num = mesh->curve_keys.size(); - - /*export tangents or curve data? - not functional yet*/ - if(export_tgs && ckey_num > 1) { - Attribute *attr_tangent = mesh->curve_attributes.add(ATTR_STD_CURVE_TANGENT); - float3 *data_tangent = attr_tangent->data_float3(); - - for(int ck = 0; ck < ckey_num; ck++) { - float3 tg = normalize(normalize(mesh->curve_keys[min(ck + 1, ckey_num - 1)].co - mesh->curve_keys[ck].co) - - normalize(mesh->curve_keys[max(ck - 1, 0)].co - mesh->curve_keys[ck].co)); - - data_tangent[ck] = tg; - } - } + ExportCurveSegments(scene, mesh, &CData); } @@ -1109,7 +873,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) continue; - ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, use_parents, !preview, vcol_num); + ObtainCacheParticleVcol(mesh, &b_mesh, &b_ob, &CData, !preview, vcol_num); if(primitive == CURVE_TRIANGLES) { @@ -1118,7 +882,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool float3 *fdata = attr_vcol->data_float3(); - ExportCurveTriangleVcol(mesh, &CData, interpolation, segments, tri_num * 3, used_res, fdata); + ExportCurveTriangleVcol(mesh, &CData, tri_num * 3, used_res, fdata); } else { Attribute *attr_vcol = mesh->curve_attributes.add( @@ -1148,7 +912,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) { Attribute *attr_uv; - ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, use_parents, !preview, uv_num); + ObtainCacheParticleUV(mesh, &b_mesh, &b_ob, &CData, !preview, uv_num); if(primitive == CURVE_TRIANGLES) { if(active_render) @@ -1158,7 +922,7 @@ void BlenderSync::sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool float3 *uv = attr_uv->data_float3(); - ExportCurveTriangleUV(mesh, &CData, interpolation, segments, tri_num * 3, used_res, uv); + ExportCurveTriangleUV(mesh, &CData, tri_num * 3, used_res, uv); } else { if(active_render) diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index dd647fec2d3..6c636ac5c8d 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -295,16 +295,8 @@ void BVH::pack_curve_segment(int idx, float4 woop[3]) * extra curve data <3> , StrID, * nextkey, flags/tip?, 0, 0); */ - Attribute *attr_tangent = mesh->curve_attributes.find(ATTR_STD_CURVE_TANGENT); float3 tg0 = make_float3(1.0f, 0.0f, 0.0f); float3 tg1 = make_float3(1.0f, 0.0f, 0.0f); - - if(attr_tangent) { - const float3 *data_tangent = attr_tangent->data_float3(); - - tg0 = data_tangent[k0]; - tg1 = data_tangent[k1]; - } Transform tfm = make_transform( tg0.x, tg0.y, tg0.z, l, diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h index c9e14645d47..f0f1fcd4c0a 100644 --- a/intern/cycles/kernel/kernel_bvh.h +++ b/intern/cycles/kernel/kernel_bvh.h @@ -1080,12 +1080,8 @@ __device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const #endif if (flag & CURVE_KN_TRUETANGENTGNORMAL) { - sd->Ng = -(D - tg * (dot(tg,D) * kernel_data.curve.normalmix)); + sd->Ng = -(D - tg * dot(tg,D)); sd->Ng = normalize(sd->Ng); - if (flag & CURVE_KN_NORMALCORRECTION) { - sd->Ng = sd->Ng - gd * tg; - sd->Ng = normalize(sd->Ng); - } } else { sd->Ng = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd); @@ -1098,12 +1094,8 @@ __device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const sd->N = sd->Ng; if (flag & CURVE_KN_TANGENTGNORMAL && !(flag & CURVE_KN_TRUETANGENTGNORMAL)) { - sd->N = -(D - tg * (dot(tg,D) * kernel_data.curve.normalmix)); + sd->N = -(D - tg * dot(tg,D)); sd->N = normalize(sd->N); - if (flag & CURVE_KN_NORMALCORRECTION) { - sd->N = sd->N - gd * tg; - sd->N = normalize(sd->N); - } } if (!(flag & CURVE_KN_TANGENTGNORMAL) && flag & CURVE_KN_TRUETANGENTGNORMAL) { sd->N = (dif - tg * sd->u * l) / (P1.w + sd->u * l * gd); diff --git a/intern/cycles/kernel/kernel_curve.h b/intern/cycles/kernel/kernel_curve.h index b9637e7df8b..fa946a4c189 100644 --- a/intern/cycles/kernel/kernel_curve.h +++ b/intern/cycles/kernel/kernel_curve.h @@ -120,15 +120,13 @@ __device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd) float3 tgN = make_float3(0.0f,0.0f,0.0f); if(sd->segment != ~0) { - float normalmix = kernel_data.curve.normalmix; - tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) * normalmix / len_squared(sd->dPdu))); + tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu,-sd->I) / len_squared(sd->dPdu))); tgN = normalize(tgN); /* need to find suitable scaled gd for corrected normal */ #if 0 - if (kernel_data.curve.use_tangent_normal_correction) - tgN = normalize(tgN - gd * sd->dPdu); + tgN = normalize(tgN - gd * sd->dPdu); #endif } diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 836eacf7cb6..3008698313e 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -439,7 +439,6 @@ typedef enum AttributeStandard { ATTR_STD_MOTION_PRE, ATTR_STD_MOTION_POST, ATTR_STD_PARTICLE, - ATTR_STD_CURVE_TANGENT, ATTR_STD_CURVE_INTERCEPT, ATTR_STD_NUM, @@ -798,20 +797,17 @@ typedef enum CurveFlag { /* runtime flags */ CURVE_KN_BACKFACING = 1, /* backside of cylinder? */ CURVE_KN_ENCLOSEFILTER = 2, /* don't consider strands surrounding start point? */ - CURVE_KN_CURVEDATA = 4, /* curve data available? */ - CURVE_KN_INTERPOLATE = 8, /* render as a curve? */ - CURVE_KN_ACCURATE = 16, /* use accurate intersections test? */ - CURVE_KN_INTERSECTCORRECTION = 32, /* correct for width after determing closest midpoint? */ - CURVE_KN_POSTINTERSECTCORRECTION = 64, /* correct for width after intersect? */ - CURVE_KN_NORMALCORRECTION = 128, /* correct tangent normal for slope? */ - CURVE_KN_TRUETANGENTGNORMAL = 256, /* use tangent normal for geometry? */ - CURVE_KN_TANGENTGNORMAL = 512, /* use tangent normal for shader? */ - CURVE_KN_RIBBONS = 1024, /* use flat curve ribbons */ + CURVE_KN_INTERPOLATE = 4, /* render as a curve? */ + CURVE_KN_ACCURATE = 8, /* use accurate intersections test? */ + CURVE_KN_INTERSECTCORRECTION = 16, /* correct for width after determing closest midpoint? */ + CURVE_KN_POSTINTERSECTCORRECTION = 32, /* correct for width after intersect? */ + CURVE_KN_TRUETANGENTGNORMAL = 64, /* use tangent normal for geometry? */ + CURVE_KN_TANGENTGNORMAL = 128, /* use tangent normal for shader? */ + CURVE_KN_RIBBONS = 256, /* use flat curve ribbons */ } CurveFlag; typedef struct KernelCurves { /* strand intersect and normal parameters - many can be changed to flags*/ - float normalmix; float encasing_ratio; int curveflags; int subdivisions; diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index 3137ea5327b..57e76a6a8f9 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -147,8 +147,6 @@ const char *Attribute::standard_name(AttributeStandard std) return "motion_post"; else if(std == ATTR_STD_PARTICLE) return "particle"; - else if(std == ATTR_STD_CURVE_TANGENT) - return "curve_tangent"; else if(std == ATTR_STD_CURVE_INTERCEPT) return "curve_intercept"; @@ -277,9 +275,6 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) case ATTR_STD_MOTION_POST: attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE_KEY); break; - case ATTR_STD_CURVE_TANGENT: - attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CURVE_KEY); - break; case ATTR_STD_CURVE_INTERCEPT: attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_CURVE_KEY); break; diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp index 502bed06930..8f9a232f672 100644 --- a/intern/cycles/render/curves.cpp +++ b/intern/cycles/render/curves.cpp @@ -80,27 +80,21 @@ void curvebounds(float *lower, float *upper, float3 *p, int dim) CurveSystemManager::CurveSystemManager() { primitive = CURVE_LINE_SEGMENTS; + curve_shape = CURVE_THICK; line_method = CURVE_CORRECTED; - interpolation = CURVE_CARDINAL; triangle_method = CURVE_CAMERA_TRIANGLES; resolution = 3; - segments = 1; subdivisions = 3; - normalmix = 1.0f; encasing_ratio = 1.01f; minimum_width = 0.0f; maximum_width = 0.0f; use_curves = true; - use_smooth = true; - use_parents = false; use_encasing = true; use_backfacing = false; - use_joined = false; use_tangent_normal = false; use_tangent_normal_geometry = false; - use_tangent_normal_correction = false; need_update = true; need_mesh_update = false; @@ -138,18 +132,13 @@ void CurveSystemManager::device_update(Device *device, DeviceScene *dscene, Scen if(use_tangent_normal) kcurve->curveflags |= CURVE_KN_TANGENTGNORMAL; - if(use_tangent_normal_correction) - kcurve->curveflags |= CURVE_KN_NORMALCORRECTION; if(use_tangent_normal_geometry) kcurve->curveflags |= CURVE_KN_TRUETANGENTGNORMAL; - if(use_joined) - kcurve->curveflags |= CURVE_KN_CURVEDATA; if(use_backfacing) kcurve->curveflags |= CURVE_KN_BACKFACING; if(use_encasing) kcurve->curveflags |= CURVE_KN_ENCLOSEFILTER; - kcurve->normalmix = normalmix; kcurve->encasing_ratio = encasing_ratio; kcurve->minimum_width = minimum_width; kcurve->maximum_width = maximum_width; @@ -168,39 +157,29 @@ void CurveSystemManager::device_free(Device *device, DeviceScene *dscene) bool CurveSystemManager::modified(const CurveSystemManager& CurveSystemManager) { - return !(line_method == CurveSystemManager.line_method && - interpolation == CurveSystemManager.interpolation && + return !(curve_shape == CurveSystemManager.curve_shape && + line_method == CurveSystemManager.line_method && primitive == CurveSystemManager.primitive && use_encasing == CurveSystemManager.use_encasing && use_tangent_normal == CurveSystemManager.use_tangent_normal && - use_tangent_normal_correction == CurveSystemManager.use_tangent_normal_correction && use_tangent_normal_geometry == CurveSystemManager.use_tangent_normal_geometry && encasing_ratio == CurveSystemManager.encasing_ratio && minimum_width == CurveSystemManager.minimum_width && maximum_width == CurveSystemManager.maximum_width && use_backfacing == CurveSystemManager.use_backfacing && - normalmix == CurveSystemManager.normalmix && - use_smooth == CurveSystemManager.use_smooth && triangle_method == CurveSystemManager.triangle_method && resolution == CurveSystemManager.resolution && use_curves == CurveSystemManager.use_curves && - use_joined == CurveSystemManager.use_joined && - segments == CurveSystemManager.segments && - use_parents == CurveSystemManager.use_parents && subdivisions == CurveSystemManager.subdivisions); } bool CurveSystemManager::modified_mesh(const CurveSystemManager& CurveSystemManager) { return !(primitive == CurveSystemManager.primitive && - interpolation == CurveSystemManager.interpolation && - use_parents == CurveSystemManager.use_parents && - use_smooth == CurveSystemManager.use_smooth && + curve_shape == CurveSystemManager.curve_shape && triangle_method == CurveSystemManager.triangle_method && resolution == CurveSystemManager.resolution && - use_curves == CurveSystemManager.use_curves && - use_joined == CurveSystemManager.use_joined && - segments == CurveSystemManager.segments); + use_curves == CurveSystemManager.use_curves); } void CurveSystemManager::tag_update(Scene *scene) diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h index 42f0498617e..088702d39ed 100644 --- a/intern/cycles/render/curves.h +++ b/intern/cycles/render/curves.h @@ -48,9 +48,13 @@ typedef enum curve_primitives { CURVE_RIBBONS } curve_primitives; +typedef enum curve_shape { + CURVE_RIBBON, + CURVE_THICK +} curve_shape; + typedef enum curve_triangles { CURVE_CAMERA_TRIANGLES, - CURVE_RIBBON_TRIANGLES, CURVE_TESSELATED_TRIANGLES } curve_triangles; @@ -99,27 +103,21 @@ class CurveSystemManager { public: int primitive; + int curve_shape; int line_method; - int interpolation; int triangle_method; int resolution; - int segments; int subdivisions; - float normalmix; float encasing_ratio; float minimum_width; float maximum_width; bool use_curves; - bool use_smooth; - bool use_parents; bool use_encasing; bool use_backfacing; bool use_tangent_normal; - bool use_tangent_normal_correction; bool use_tangent_normal_geometry; - bool use_joined; bool need_update; bool need_mesh_update;