diff options
5 files changed, 62 insertions, 30 deletions
diff --git a/release/scripts/ui/properties_render.py b/release/scripts/ui/properties_render.py index 60f3a0e5afc..b6760f823df 100644 --- a/release/scripts/ui/properties_render.py +++ b/release/scripts/ui/properties_render.py @@ -194,6 +194,7 @@ class RENDER_PT_freestyle(RenderButtonsPanel, bpy.types.Panel): if freestyle.mode == "EDITOR": col.label(text="Edge Detection Options:") + col.prop(freestyle, "use_smoothness") col.prop(freestyle, "crease_angle") col.prop(freestyle, "sphere_radius") col.prop(freestyle, "kr_derivative_epsilon") @@ -253,6 +254,7 @@ class RENDER_PT_freestyle(RenderButtonsPanel, bpy.types.Panel): else: # freestyle.mode == "SCRIPT" + col.prop(freestyle, "use_smoothness") col.prop(freestyle, "crease_angle") col.prop(freestyle, "sphere_radius") col.prop(freestyle, "use_ridges_and_valleys") diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 3bf6ceb70f8..e146a8673ef 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -9,6 +9,7 @@ BlenderFileLoader::BlenderFileLoader(Render *re, SceneRenderLayer* srl) _Scene = NULL; _numFacesRead = 0; _minEdgeSize = DBL_MAX; + _smooth = (srl->freestyleConfig.flags & FREESTYLE_FACE_SMOOTHNESS_FLAG) != 0; } BlenderFileLoader::~BlenderFileLoader() @@ -123,38 +124,49 @@ void BlenderFileLoader::clipLine(float v1[3], float v2[3], float c[3], float z) // clip the triangle (V1, V2, V3) by the near and far clipping plane and // obtain a set of vertices after the clipping. The number of vertices // is at most 5. -void BlenderFileLoader::clipTriangle(int numTris, float triCoords[][3], float v1[3], float v2[3], float v3[3], int clip[3]) +void BlenderFileLoader::clipTriangle(int numTris, float triCoords[][3], float v1[3], float v2[3], float v3[3], + float triNormals[][3], float n1[3], float n2[3], float n3[3], int clip[3]) { - float *v[3]; + float *v[3], *n[3]; int i, j, k; - v[0] = v1; - v[1] = v2; - v[2] = v3; + v[0] = v1; n[0] = n1; + v[1] = v2; n[1] = n2; + v[2] = v3; n[2] = n3; k = 0; for (i = 0; i < 3; i++) { j = (i + 1) % 3; if (clip[i] == NOT_CLIPPED) { - copy_v3_v3(triCoords[k++], v[i]); + copy_v3_v3(triCoords[k], v[i]); + copy_v3_v3(triNormals[k], n[i]); + k++; if (clip[j] != NOT_CLIPPED) { - clipLine(v[i], v[j], triCoords[k++], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + clipLine(v[i], v[j], triCoords[k], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + copy_v3_v3(triNormals[k], n[j]); + k++; } } else if (clip[i] != clip[j]) { if (clip[j] == NOT_CLIPPED) { - clipLine(v[i], v[j], triCoords[k++], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + clipLine(v[i], v[j], triCoords[k], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + copy_v3_v3(triNormals[k], n[i]); + k++; } else { - clipLine(v[i], v[j], triCoords[k++], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); - clipLine(v[i], v[j], triCoords[k++], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + clipLine(v[i], v[j], triCoords[k], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + copy_v3_v3(triNormals[k], n[i]); + k++; + clipLine(v[i], v[j], triCoords[k], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); + copy_v3_v3(triNormals[k], n[j]); + k++; } } } assert (k == 2 + numTris); } -void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3]) +void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3], + float n1[3], float n2[3], float n3[3]) { - float v12[3], v13[3], n[3]; - float *fv[3], len; + float *fv[3], *fn[3], len; unsigned i, j; // initialize the bounding box by the first vertex @@ -163,19 +175,13 @@ void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v copy_v3_v3(ls->maxBBox, v1); } - // compute the normal of the triangle - sub_v3_v3v3(v12, v1, v2); - sub_v3_v3v3(v13, v1, v3); - cross_v3_v3v3(n, v12, v13); - normalize_v3(n); - - fv[0] = v1; - fv[1] = v2; - fv[2] = v3; + fv[0] = v1; fn[0] = n1; + fv[1] = v2; fn[1] = n2; + fv[2] = v3; fn[2] = n3; for (i = 0; i < 3; i++) { copy_v3_v3(ls->pv, fv[i]); - copy_v3_v3(ls->pn, n); + copy_v3_v3(ls->pn, fn[i]); // update the bounding box for (j = 0; j < 3; j++) @@ -215,6 +221,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) VlakRen *vlr; unsigned numFaces = 0; float v1[3], v2[3], v3[3], v4[3]; + float n1[3], n2[3], n3[3], n4[3], facenormal[3]; int clip_1[3], clip_2[3]; int wire_material = 0; for(int a=0; a < obr->totvlak; a++) { @@ -302,6 +309,18 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) mul_m4_v3(obi->mat, v3); if (vlr->v4) mul_m4_v3(obi->mat, v4); } + if (_smooth && (vlr->flag & R_SMOOTH)) { + copy_v3_v3(n1, vlr->v1->n); + copy_v3_v3(n2, vlr->v2->n); + copy_v3_v3(n3, vlr->v3->n); + if (vlr->v4) copy_v3_v3(n4, vlr->v4->n); + } else { + RE_vlakren_get_normal(_re, obi, vlr, facenormal); + copy_v3_v3(n1, facenormal); + copy_v3_v3(n2, facenormal); + copy_v3_v3(n3, facenormal); + if (vlr->v4) copy_v3_v3(n4, facenormal); + } unsigned numTris_1, numTris_2; numTris_1 = countClippedFaces(v1, v2, v3, clip_1); @@ -347,20 +366,22 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) } } - float triCoords[5][3]; + float triCoords[5][3], triNormals[5][3]; if (numTris_1 > 0) { - clipTriangle(numTris_1, triCoords, v1, v2, v3, clip_1); + clipTriangle(numTris_1, triCoords, v1, v2, v3, triNormals, n1, n2, n3, clip_1); for (i = 0; i < numTris_1; i++) { - addTriangle(&ls, triCoords[0], triCoords[i+1], triCoords[i+2]); + addTriangle(&ls, triCoords[0], triCoords[i+1], triCoords[i+2], + triNormals[0], triNormals[i+1], triNormals[i+2]); _numFacesRead++; } } if (numTris_2 > 0) { - clipTriangle(numTris_2, triCoords, v1, v3, v4, clip_2); + clipTriangle(numTris_2, triCoords, v1, v3, v4, triNormals, n1, n3, n4, clip_2); for (i = 0; i < numTris_2; i++) { - addTriangle(&ls, triCoords[0], triCoords[i+1], triCoords[i+2]); + addTriangle(&ls, triCoords[0], triCoords[i+1], triCoords[i+2], + triNormals[0], triNormals[i+1], triNormals[i+2]); _numFacesRead++; } } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h index 038f4bdd6c8..adf3e4eb7b1 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h @@ -65,8 +65,10 @@ protected: void insertShapeNode(ObjectInstanceRen *obi, int id); int countClippedFaces(float v1[3], float v2[3], float v3[3], int clip[3]); void clipLine(float v1[3], float v2[3], float c[3], float z); - void clipTriangle(int numTris, float triCoords[][3], float v1[3], float v2[3], float v3[3], int clip[3]); - void addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3]); + void clipTriangle(int numTris, float triCoords[][3], float v1[3], float v2[3], float v3[3], + float triNormals[][3], float n1[3], float n2[3], float n3[3], int clip[3]); + void addTriangle(struct LoaderState *ls, float v1[3], float v2[3], float v3[3], + float n1[3], float n2[3], float n3[3]); protected: Render* _re; @@ -74,6 +76,7 @@ protected: NodeGroup* _Scene; unsigned _numFacesRead; real _minEdgeSize; + bool _smooth; /* if true, face smoothness is taken into account */ float _viewplane_left; float _viewplane_right; float _viewplane_bottom; diff --git a/source/blender/makesdna/DNA_freestyle_types.h b/source/blender/makesdna/DNA_freestyle_types.h index 08980afec89..391bf825eb3 100644 --- a/source/blender/makesdna/DNA_freestyle_types.h +++ b/source/blender/makesdna/DNA_freestyle_types.h @@ -39,6 +39,7 @@ struct FreestyleLineStyle; #define FREESTYLE_SUGGESTIVE_CONTOURS_FLAG 1 #define FREESTYLE_RIDGES_AND_VALLEYS_FLAG 2 #define FREESTYLE_MATERIAL_BOUNDARIES_FLAG 4 +#define FREESTYLE_FACE_SMOOTHNESS_FLAG 8 /* FreestyleConfig::mode */ #define FREESTYLE_CONTROL_SCRIPT_MODE 1 diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index c21e7bfdfce..b12e8552ef6 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1827,6 +1827,11 @@ static void rna_def_freestyle_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Material Boundaries", "Enable material boundaries."); RNA_def_property_update(prop, NC_SCENE, NULL); + prop= RNA_def_property(srna, "use_smoothness", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_FACE_SMOOTHNESS_FLAG); + RNA_def_property_ui_text(prop, "Face Smoothness", "Take face smoothness into account in view map calculation."); + RNA_def_property_update(prop, NC_SCENE, NULL); + prop= RNA_def_property(srna, "sphere_radius", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "sphere_radius"); RNA_def_property_range(prop, 0.0, 1000.0); |