diff options
Diffstat (limited to 'source/blender/freestyle')
18 files changed, 307 insertions, 27 deletions
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 3cff4d2cc33..c0aa127b962 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -125,37 +125,47 @@ void BlenderFileLoader::clipLine(float v1[3], float v2[3], float c[3], float z) // 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], - float triNormals[][3], float n1[3], float n2[3], float n3[3], int clip[3]) + float triNormals[][3], float n1[3], float n2[3], float n3[3], + bool edgeMarks[], bool em1, bool em2, bool em3, int clip[3]) { float *v[3], *n[3]; + bool em[3]; int i, j, k; v[0] = v1; n[0] = n1; v[1] = v2; n[1] = n2; v[2] = v3; n[2] = n3; + em[0] = em1; /* edge mark of the edge between v1 and v2 */ + em[1] = em2; /* edge mark of the edge between v2 and v3 */ + em[2] = em3; /* edge mark of the edge between v3 and v1 */ 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(triNormals[k], n[i]); + edgeMarks[k] = em[i]; k++; if (clip[j] != NOT_CLIPPED) { clipLine(v[i], v[j], triCoords[k], (clip[j] == CLIPPED_BY_NEAR) ? _z_near : _z_far); copy_v3_v3(triNormals[k], n[j]); + edgeMarks[k] = false; 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); copy_v3_v3(triNormals[k], n[i]); + edgeMarks[k] = em[i]; k++; } else { clipLine(v[i], v[j], triCoords[k], (clip[i] == CLIPPED_BY_NEAR) ? _z_near : _z_far); copy_v3_v3(triNormals[k], n[i]); + edgeMarks[k] = em[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]); + edgeMarks[k] = false; k++; } } @@ -164,10 +174,12 @@ void BlenderFileLoader::clipTriangle(int numTris, float triCoords[][3], float v1 } 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 n1[3], float n2[3], float n3[3], + bool fm, bool em1, bool em2, bool em3) { float *fv[3], *fn[3], len; unsigned i, j; + IndexedFaceSet::FaceEdgeMark marks = 0; // initialize the bounding box by the first vertex if (ls->currentIndex == 0) { @@ -209,6 +221,11 @@ void BlenderFileLoader::addTriangle(struct LoaderState *ls, float v1[3], float v ls->pni++; ls->pmi++; } + if (fm) marks |= IndexedFaceSet::FACE_MARK; + if (em1) marks |= IndexedFaceSet::EDGE_MARK_V1V2; + if (em2) marks |= IndexedFaceSet::EDGE_MARK_V2V3; + if (em3) marks |= IndexedFaceSet::EDGE_MARK_V3V1; + *ls->pm++ = marks; } void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) @@ -272,6 +289,8 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) faceStyle[i] = IndexedFaceSet::TRIANGLES; numVertexPerFaces[i] = 3; } + + IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = new IndexedFaceSet::FaceEdgeMark[numFaces]; unsigned viSize = 3*numFaces; unsigned *VIndices = new unsigned[viSize]; @@ -282,6 +301,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) struct LoaderState ls; ls.pv = vertices; ls.pn = normals; + ls.pm = faceEdgeMarks; ls.pvi = VIndices; ls.pni = NIndices; ls.pmi = MIndices; @@ -339,6 +359,17 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) numTris_2 = (vlr->v4) ? countClippedFaces(v1, v3, v4, clip_2) : 0; if (numTris_1 == 0 && numTris_2 == 0) continue; + bool fm, em1, em2, em3, em4; + fm = (vlr->flag & ME_FREESTYLE_FACE) != 0; + em1= (vlr->freestyle_edge_mark & R_EDGE_V1V2) != 0; + em2= (vlr->freestyle_edge_mark & R_EDGE_V2V3) != 0; + if (!vlr->v4) { + em3= (vlr->freestyle_edge_mark & R_EDGE_V3V1) != 0; + em4= false; + } else { + em3= (vlr->freestyle_edge_mark & R_EDGE_V3V4) != 0; + em4= (vlr->freestyle_edge_mark & R_EDGE_V4V1) != 0; + } Material *mat = vlr->mat; @@ -379,21 +410,28 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) } float triCoords[5][3], triNormals[5][3]; + bool edgeMarks[5]; // edgeMarks[i] is for the edge between i-th and (i+1)-th vertices if (numTris_1 > 0) { - clipTriangle(numTris_1, triCoords, v1, v2, v3, triNormals, n1, n2, n3, clip_1); + clipTriangle(numTris_1, triCoords, v1, v2, v3, triNormals, n1, n2, n3, + edgeMarks, em1, em2, (!vlr->v4) ? em3 : false, clip_1); for (i = 0; i < numTris_1; i++) { addTriangle(&ls, triCoords[0], triCoords[i+1], triCoords[i+2], - triNormals[0], triNormals[i+1], triNormals[i+2]); + triNormals[0], triNormals[i+1], triNormals[i+2], + fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i+1], + (i == numTris_1 - 1) ? edgeMarks[i+2] : false); _numFacesRead++; } } if (numTris_2 > 0) { - clipTriangle(numTris_2, triCoords, v1, v3, v4, triNormals, n1, n3, n4, clip_2); + clipTriangle(numTris_2, triCoords, v1, v3, v4, triNormals, n1, n3, n4, + edgeMarks, false, em3, em4, clip_2); for (i = 0; i < numTris_2; i++) { addTriangle(&ls, triCoords[0], triCoords[i+1], triCoords[i+2], - triNormals[0], triNormals[i+1], triNormals[i+2]); + triNormals[0], triNormals[i+1], triNormals[i+2], + fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i+1], + (i == numTris_2 - 1) ? edgeMarks[i+2] : false); _numFacesRead++; } } @@ -444,6 +482,7 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id) marray, meshFrsMaterials.size(), 0, 0, numFaces, numVertexPerFaces, faceStyle, + faceEdgeMarks, cleanVIndices, viSize, cleanNIndices, niSize, MIndices, viSize, diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h index adf3e4eb7b1..94ea0784a30 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h @@ -18,6 +18,7 @@ extern "C" { #endif #include "DNA_material_types.h" + #include "DNA_meshdata_types.h" #include "DNA_scene_types.h" #include "render_types.h" #include "renderdatabase.h" @@ -36,6 +37,7 @@ class NodeGroup; struct LoaderState { float *pv; float *pn; + IndexedFaceSet::FaceEdgeMark *pm; unsigned *pvi; unsigned *pni; unsigned *pmi; @@ -66,9 +68,10 @@ protected: 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], - float triNormals[][3], float n1[3], float n2[3], float n3[3], int clip[3]); + float triNormals[][3], float n1[3], float n2[3], float n3[3], + bool edgeMarks[5], bool em1, bool em2, bool em3, 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]); + float n1[3], float n2[3], float n3[3], bool fm, bool em1, bool em2, bool em3); protected: Render* _re; diff --git a/source/blender/freestyle/intern/python/BPy_Nature.cpp b/source/blender/freestyle/intern/python/BPy_Nature.cpp index 35be367b348..149baa9a7f3 100644 --- a/source/blender/freestyle/intern/python/BPy_Nature.cpp +++ b/source/blender/freestyle/intern/python/BPy_Nature.cpp @@ -78,7 +78,8 @@ static char Nature___doc__[] = "* Nature.RIDGE: True for ridges.\n" "* Nature.VALLEY: True for valleys.\n" "* Nature.SUGGESTIVE_CONTOUR: True for suggestive contours.\n" -"* Nature.MATERIAL_BOUNDARY: True for edges at material boundaries.\n"; +"* Nature.MATERIAL_BOUNDARY: True for edges at material boundaries.\n" +"* Nature.EDGE_MARK: True for edges having user-defined edge marks.\n"; /*-----------------------BPy_Nature type definition ------------------------------*/ @@ -181,6 +182,10 @@ static PyLongObject _Nature_MATERIAL_BOUNDARY = { PyVarObject_HEAD_INIT(&Nature_Type, 1) { Nature::MATERIAL_BOUNDARY } }; +static PyLongObject _Nature_EDGE_MARK = { + PyVarObject_HEAD_INIT(&Nature_Type, 1) + { Nature::EDGE_MARK } +}; #define BPy_Nature_POINT ((PyObject *)&_Nature_POINT) #define BPy_Nature_S_VERTEX ((PyObject *)&_Nature_S_VERTEX) @@ -196,6 +201,7 @@ static PyLongObject _Nature_MATERIAL_BOUNDARY = { #define BPy_Nature_VALLEY ((PyObject *)&_Nature_VALLEY) #define BPy_Nature_SUGGESTIVE_CONTOUR ((PyObject *)&_Nature_SUGGESTIVE_CONTOUR) #define BPy_Nature_MATERIAL_BOUNDARY ((PyObject *)&_Nature_MATERIAL_BOUNDARY) +#define BPy_Nature_EDGE_MARK ((PyObject *)&_Nature_EDGE_MARK) //-------------------MODULE INITIALIZATION-------------------------------- int Nature_Init( PyObject *module ) @@ -225,6 +231,7 @@ int Nature_Init( PyObject *module ) PyDict_SetItemString( Nature_Type.tp_dict, "VALLEY", BPy_Nature_VALLEY ); PyDict_SetItemString( Nature_Type.tp_dict, "SUGGESTIVE_CONTOUR", BPy_Nature_SUGGESTIVE_CONTOUR ); PyDict_SetItemString( Nature_Type.tp_dict, "MATERIAL_BOUNDARY", BPy_Nature_MATERIAL_BOUNDARY ); + PyDict_SetItemString( Nature_Type.tp_dict, "EDGE_MARK", BPy_Nature_EDGE_MARK ); return 0; } diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp index ec49167b0c1..39d644b7714 100644 --- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp @@ -154,6 +154,32 @@ static PyObject * FEdgeSharp_bMaterial( BPy_FEdgeSharp *self ) { return BPy_FrsMaterial_from_FrsMaterial(m); } +static char FEdgeSharp_aFaceMark___doc__[] = +".. method:: aFaceMark()\n" +"\n" +" Returns the face mark of the face lying on the right of the FEdge.\n" +" If this FEdge is a border, it has no face on the right, and thus\n" +" false is returned.\n" +"\n" +" :return: The face mark of the face lying on the right of the FEdge.\n" +" :rtype: bool\n"; + +static PyObject * FEdgeSharp_aFaceMark( BPy_FEdgeSharp *self ) { + return PyBool_from_bool( self->fes->aFaceMark() ); +} + +static char FEdgeSharp_bFaceMark___doc__[] = +".. method:: bFaceMark()\n" +"\n" +" Returns the face mark of the face lying on the left of the FEdge.\n" +"\n" +" :return: The face mark of the face lying on the left of the FEdge.\n" +" :rtype: bool\n"; + +static PyObject * FEdgeSharp_bFaceMark( BPy_FEdgeSharp *self ) { + return PyBool_from_bool( self->fes->bFaceMark() ); +} + static char FEdgeSharp_setNormalA___doc__[] = ".. method:: setNormalA(iNormal)\n" "\n" @@ -240,6 +266,44 @@ static PyObject * FEdgeSharp_setbMaterialIndex( BPy_FEdgeSharp *self, PyObject * Py_RETURN_NONE; } +static char FEdgeSharp_setaFaceMark___doc__[] = +".. method:: setaFaceMark(i)\n" +"\n" +" Sets the face mark of the face lying on the right of the FEdge.\n" +"\n" +" :arg i: A face mark.\n" +" :type i: bool\n"; + +static PyObject * FEdgeSharp_setaFaceMark( BPy_FEdgeSharp *self, PyObject *args ) { + PyObject *obj; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + + self->fes->setaFaceMark( bool_from_PyBool(obj) ); + + Py_RETURN_NONE; +} + +static char FEdgeSharp_setbFaceMark___doc__[] = +".. method:: setbFaceMark(i)\n" +"\n" +" Sets the face mark of the face lying on the left of the FEdge.\n" +"\n" +" :arg i: A face mark.\n" +" :type i: bool\n"; + +static PyObject * FEdgeSharp_setbFaceMark( BPy_FEdgeSharp *self, PyObject *args ) { + PyObject *obj; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + + self->fes->setbFaceMark( bool_from_PyBool(obj) ); + + Py_RETURN_NONE; +} + /*----------------------FEdgeSharp instance definitions ----------------------------*/ static PyMethodDef BPy_FEdgeSharp_methods[] = { {"normalA", ( PyCFunction ) FEdgeSharp_normalA, METH_NOARGS, FEdgeSharp_normalA___doc__}, @@ -248,10 +312,14 @@ static PyMethodDef BPy_FEdgeSharp_methods[] = { {"bMaterialIndex", ( PyCFunction ) FEdgeSharp_bMaterialIndex, METH_NOARGS, FEdgeSharp_bMaterialIndex___doc__}, {"aMaterial", ( PyCFunction ) FEdgeSharp_aMaterial, METH_NOARGS, FEdgeSharp_aMaterial___doc__}, {"bMaterial", ( PyCFunction ) FEdgeSharp_bMaterial, METH_NOARGS, FEdgeSharp_bMaterial___doc__}, + {"aFaceMark", ( PyCFunction ) FEdgeSharp_aFaceMark, METH_NOARGS, FEdgeSharp_aFaceMark___doc__}, + {"bFaceMark", ( PyCFunction ) FEdgeSharp_bFaceMark, METH_NOARGS, FEdgeSharp_bFaceMark___doc__}, {"setNormalA", ( PyCFunction ) FEdgeSharp_setNormalA, METH_VARARGS, FEdgeSharp_setNormalA___doc__}, {"setNormalB", ( PyCFunction ) FEdgeSharp_setNormalB, METH_VARARGS, FEdgeSharp_setNormalB___doc__}, {"setaMaterialIndex", ( PyCFunction ) FEdgeSharp_setaMaterialIndex, METH_VARARGS, FEdgeSharp_setaMaterialIndex___doc__}, {"setbMaterialIndex", ( PyCFunction ) FEdgeSharp_setbMaterialIndex, METH_VARARGS, FEdgeSharp_setbMaterialIndex___doc__}, + {"setaFaceMark", ( PyCFunction ) FEdgeSharp_setaFaceMark, METH_NOARGS, FEdgeSharp_setaFaceMark___doc__}, + {"setbFaceMark", ( PyCFunction ) FEdgeSharp_setbFaceMark, METH_NOARGS, FEdgeSharp_setbFaceMark___doc__}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp index df945b1e6a8..3ddb4d060de 100644 --- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp @@ -104,6 +104,18 @@ static PyObject * FEdgeSmooth_material( BPy_FEdgeSmooth *self ) { return BPy_FrsMaterial_from_FrsMaterial(m); } +static char FEdgeSmooth_faceMark___doc__[] = +".. method:: faceMark()\n" +"\n" +" Returns the face mark of the face it is running across.\n" +"\n" +" :return: The face mark of the face it is running across.\n" +" :rtype: bool\n"; + +static PyObject * FEdgeSmooth_faceMark( BPy_FEdgeSmooth *self ) { + return PyBool_from_bool( self->fes->faceMark() ); +} + static char FEdgeSmooth_setNormal___doc__[] = ".. method:: setNormal(iNormal)\n" "\n" @@ -147,13 +159,34 @@ static PyObject * FEdgeSmooth_setMaterialIndex( BPy_FEdgeSmooth *self, PyObject Py_RETURN_NONE; } +static char FEdgeSmooth_setFaceMark___doc__[] = +".. method:: setFaceMark(i)\n" +"\n" +" Sets the face mark of the face it is running across.\n" +"\n" +" :arg i: A face mark.\n" +" :type i: bool\n"; + +static PyObject * FEdgeSmooth_setFaceMark( BPy_FEdgeSmooth *self, PyObject *args ) { + PyObject *obj; + + if(!( PyArg_ParseTuple(args, "O", &obj) )) + return NULL; + + self->fes->setFaceMark( bool_from_PyBool(obj) ); + + Py_RETURN_NONE; +} + /*----------------------FEdgeSmooth instance definitions ----------------------------*/ static PyMethodDef BPy_FEdgeSmooth_methods[] = { {"normal", ( PyCFunction ) FEdgeSmooth_normal, METH_NOARGS, FEdgeSmooth_normal___doc__}, {"materialIndex", ( PyCFunction ) FEdgeSmooth_materialIndex, METH_NOARGS, FEdgeSmooth_materialIndex___doc__}, {"material", ( PyCFunction ) FEdgeSmooth_material, METH_NOARGS, FEdgeSmooth_material___doc__}, + {"faceMark", ( PyCFunction ) FEdgeSmooth_faceMark, METH_NOARGS, FEdgeSmooth_faceMark___doc__}, {"setNormal", ( PyCFunction ) FEdgeSmooth_setNormal, METH_VARARGS, FEdgeSmooth_setNormal___doc__}, {"setMaterialIndex", ( PyCFunction ) FEdgeSmooth_setMaterialIndex, METH_VARARGS, FEdgeSmooth_setMaterialIndex___doc__}, + {"setFaceMark", ( PyCFunction ) FEdgeSmooth_setFaceMark, METH_VARARGS, FEdgeSmooth_setFaceMark___doc__}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp index 98872c6c8ea..aaeba943ab6 100755 --- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp +++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp @@ -28,6 +28,7 @@ IndexedFaceSet::IndexedFaceSet() _Normals = NULL; _FrsMaterials = 0; _TexCoords = 0; + _FaceEdgeMarks = 0; _VSize = 0; _NSize = 0; _MSize = 0; @@ -51,6 +52,7 @@ IndexedFaceSet::IndexedFaceSet( real *iVertices, unsigned iVSize, FrsMaterial **iMaterials, unsigned iMSize, real *iTexCoords, unsigned iTSize, unsigned iNumFaces, unsigned *iNumVertexPerFace, TRIANGLES_STYLE *iFaceStyle, + FaceEdgeMark *iFaceEdgeMarks, unsigned *iVIndices, unsigned iVISize, unsigned *iNIndices, unsigned iNISize, unsigned *iMIndices, unsigned iMISize, @@ -89,6 +91,9 @@ IndexedFaceSet::IndexedFaceSet( real *iVertices, unsigned iVSize, _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; memcpy(_FaceStyle, iFaceStyle, _NumFaces*sizeof(TRIANGLES_STYLE)); + _FaceEdgeMarks = new FaceEdgeMark[_NumFaces]; + memcpy(_FaceEdgeMarks, iFaceEdgeMarks, _NumFaces*sizeof(FaceEdgeMark)); + _VISize = iVISize; _VIndices = new unsigned[_VISize]; memcpy(_VIndices, iVIndices, _VISize*sizeof(unsigned)); @@ -129,6 +134,7 @@ IndexedFaceSet::IndexedFaceSet( real *iVertices, unsigned iVSize, _NumFaces = iNumFaces; _NumVertexPerFace = iNumVertexPerFace; _FaceStyle = iFaceStyle; + _FaceEdgeMarks = iFaceEdgeMarks; _VISize = iVISize; _VIndices = iVIndices; @@ -182,6 +188,9 @@ IndexedFaceSet::IndexedFaceSet( const IndexedFaceSet& iBrother) _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; memcpy(_FaceStyle, iBrother.trianglesStyle(), _NumFaces*sizeof(TRIANGLES_STYLE)); + + _FaceEdgeMarks = new FaceEdgeMark[_NumFaces]; + memcpy(_FaceEdgeMarks, iBrother.faceEdgeMarks(), _NumFaces*sizeof(FaceEdgeMark)); _VISize = iBrother.visize(); _VIndices = new unsigned[_VISize]; @@ -249,6 +258,12 @@ IndexedFaceSet::~IndexedFaceSet() _FaceStyle = NULL; } + if(NULL != _FaceEdgeMarks) + { + delete [] _FaceEdgeMarks; + _FaceEdgeMarks = NULL; + } + if(NULL != _VIndices) { delete [] _VIndices; diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h index 41db4db4c42..b578dc1257e 100755 --- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h +++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.h @@ -45,6 +45,13 @@ public: /*! Triangles description style:*/ enum TRIANGLES_STYLE{TRIANGLE_STRIP, TRIANGLE_FAN, TRIANGLES}; + /*! User-specified face and edge marks for feature edge detection */ + typedef unsigned char FaceEdgeMark; + static const FaceEdgeMark FACE_MARK = 1; + static const FaceEdgeMark EDGE_MARK_V1V2 = 2; + static const FaceEdgeMark EDGE_MARK_V2V3 = 4; + static const FaceEdgeMark EDGE_MARK_V3V1 = 8; + /*! Builds an empty indexed face set */ IndexedFaceSet(); @@ -109,6 +116,7 @@ public: FrsMaterial **iMaterials, unsigned iMSize, real *iTexCoords, unsigned iTSize, unsigned iNumFaces, unsigned *iNumVertexPerFace, TRIANGLES_STYLE *iFaceStyle, + FaceEdgeMark *iFaceEdgeMarks, unsigned *iVIndices, unsigned iVISize, unsigned *iNIndices, unsigned iNISize, unsigned *iMIndices, unsigned iMISize, @@ -124,6 +132,7 @@ public: std::swap(_Normals, ioOther._Normals); std::swap(_FrsMaterials, ioOther._FrsMaterials); std::swap(_TexCoords, ioOther._TexCoords); + std::swap(_FaceEdgeMarks, ioOther._FaceEdgeMarks); std::swap(_VSize, ioOther._VSize); std::swap(_NSize, ioOther._NSize); @@ -180,6 +189,7 @@ public: virtual const unsigned numFaces() const {return _NumFaces;} virtual const unsigned * numVertexPerFaces() const {return _NumVertexPerFace;} virtual const TRIANGLES_STYLE * trianglesStyle() const {return _FaceStyle;} + virtual const unsigned char * faceEdgeMarks() const {return _FaceEdgeMarks;} virtual const unsigned* vindices() const {return _VIndices;} virtual const unsigned* nindices() const {return _NIndices;} virtual const unsigned* mindices() const {return _MIndices;} @@ -204,6 +214,7 @@ protected: unsigned _NumFaces; unsigned *_NumVertexPerFace; TRIANGLES_STYLE *_FaceStyle; + FaceEdgeMark *_FaceEdgeMarks; unsigned *_VIndices; unsigned *_NIndices; diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp index 93e3354cb6a..1cbed8a87c6 100755 --- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp +++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp @@ -72,6 +72,7 @@ void FEdgeXDetector::processShapes(WingedEdge& we) { if(_computeSuggestiveContours) processSuggestiveContourShape(wxs); processSilhouetteShape(wxs); + processEdgeMarksShape(wxs); if (progressBarDisplay) _pProgressBar->setProgress(_pProgressBar->getProgress() + 1); @@ -708,6 +709,26 @@ void FEdgeXDetector::ProcessMaterialBoundaryEdge(WXEdge *iEdge) } } +// EDGE MARKS +///////////// + +void FEdgeXDetector::processEdgeMarksShape(WXShape* iShape) { + // Make a pass on the edges to detect material boundaries + vector<WEdge*>::iterator we, weend; + vector<WEdge*> &wedges = iShape->getEdgeList(); + for(we=wedges.begin(), weend=wedges.end(); + we!=weend; + ++we){ + ProcessEdgeMarks((WXEdge*)(*we)); + } +} + +void FEdgeXDetector::ProcessEdgeMarks(WXEdge *iEdge) { + if (iEdge->GetMark()) { + iEdge->AddNature(Nature::EDGE_MARK); + } +} + // Build Smooth edges ///////////////////// void FEdgeXDetector::buildSmoothEdges(WXShape* iShape){ diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h index d08d75a84b6..d73a086f81d 100755 --- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h +++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h @@ -127,6 +127,10 @@ public: virtual void processMaterialBoundaryShape(WXShape* iWShape); virtual void ProcessMaterialBoundaryEdge(WXEdge *iEdge); + // EDGE MARKS + virtual void processEdgeMarksShape(WXShape* iShape); + virtual void ProcessEdgeMarks(WXEdge *iEdge); + // EVERYBODY virtual void buildSmoothEdges(WXShape* iShape); @@ -142,6 +146,12 @@ public: _changes=true; } } + inline void enableFaceMarks(bool b) { + if (b != _faceMarks) { + _faceMarks = b; + _changes=true; + } + } /*! Sets the radius of the geodesic sphere around each vertex (for the curvature computation) * \param r * The radius of the sphere expressed as a ratio of the mean edge size @@ -175,6 +185,7 @@ protected: bool _computeSuggestiveContours; bool _computeMaterialBoundaries; bool _faceSmoothness; + bool _faceMarks; real _sphereRadius; // expressed as a ratio of the mean edge size real _creaseAngle; // [-1, 1] compared with the inner product of face normals bool _changes; diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h index e7533f659d6..d0952ec8933 100755 --- a/source/blender/freestyle/intern/view_map/Silhouette.h +++ b/source/blender/freestyle/intern/view_map/Silhouette.h @@ -798,6 +798,8 @@ protected: Vec3r _bNormal; // When following the edge, normal of the left face unsigned _aFrsMaterialIndex; unsigned _bFrsMaterialIndex; + bool _aFaceMark; + bool _bFaceMark; public: /*! Returns the string "FEdgeSharp" . */ @@ -807,10 +809,12 @@ public: /*! Default constructor. */ inline FEdgeSharp() : FEdge(){ _aFrsMaterialIndex = _bFrsMaterialIndex = 0; + _aFaceMark = _bFaceMark = false; } /*! Builds an FEdgeSharp going from vA to vB. */ inline FEdgeSharp(SVertex *vA, SVertex *vB) : FEdge(vA, vB){ _aFrsMaterialIndex = _bFrsMaterialIndex = 0; + _aFaceMark = _bFaceMark = false; } /*! Copy constructor. */ inline FEdgeSharp(FEdgeSharp& iBrother) : FEdge(iBrother){ @@ -818,6 +822,9 @@ public: _bNormal = iBrother._bNormal; _aFrsMaterialIndex = iBrother._aFrsMaterialIndex; _bFrsMaterialIndex = iBrother._bFrsMaterialIndex; + _aFaceMark = iBrother._aFaceMark; + _bFaceMark = iBrother._bFaceMark; + } /*! Destructor. */ virtual ~FEdgeSharp() {} @@ -853,6 +860,12 @@ public: * left of the FEdge. */ const FrsMaterial& bFrsMaterial() const ; + /*! Returns the face mark of the face lying on the right of the FEdge. + * If this FEdge is a border, it has no Face on its right and thus + * false is returned. */ + inline bool aFaceMark() const {return _aFaceMark;} + /*! Returns the face mark of the face lying on the left of the FEdge. */ + inline bool bFaceMark() const {return _bFaceMark;} /*! Sets the normal to the face lying on the right of the FEdge. */ inline void setNormalA(const Vec3r& iNormal) {_aNormal = iNormal;} @@ -862,6 +875,10 @@ public: inline void setaFrsMaterialIndex(unsigned i) {_aFrsMaterialIndex = i;} /*! Sets the index of the material lying on the left of the FEdge.*/ inline void setbFrsMaterialIndex(unsigned i) {_bFrsMaterialIndex = i;} + /*! Sets the face mark of the face lying on the right of the FEdge. */ + inline void setaFaceMark(bool iFaceMark) {_aFaceMark = iFaceMark;} + /*! Sets the face mark of the face lying on the left of the FEdge. */ + inline void setbFaceMark(bool iFaceMark) {_bFaceMark = iFaceMark;} }; @@ -879,6 +896,7 @@ protected: // Vec3r _VisibilityPointB; // using its 2 extremity points A and B void * _Face; // In case of exact silhouette, Face is the WFace crossed by Fedge // NON GERE PAR LE COPY CONSTRUCTEUR + bool _FaceMark; public: /*! Returns the string "FEdgeSmooth" . */ virtual string getExactTypeName() const { @@ -887,12 +905,14 @@ public: /*! Default constructor. */ inline FEdgeSmooth() : FEdge(){ _Face=0; + _FaceMark = false; _FrsMaterialIndex = 0; _isSmooth = true; } /*! Builds an FEdgeSmooth going from vA to vB. */ inline FEdgeSmooth(SVertex *vA, SVertex *vB) : FEdge(vA, vB){ _Face=0; + _FaceMark = false; _FrsMaterialIndex = 0; _isSmooth = true; @@ -901,6 +921,7 @@ public: inline FEdgeSmooth(FEdgeSmooth& iBrother) : FEdge(iBrother){ _Normal = iBrother._Normal; _Face = iBrother._Face; + _FaceMark = iBrother._FaceMark; _FrsMaterialIndex = iBrother._FrsMaterialIndex; _isSmooth = true; } @@ -913,6 +934,8 @@ public: } inline void * face() const {return _Face;} + /*! Returns the face mark of the face it is running across. */ + inline bool faceMark() const {return _FaceMark;} /*! Returns the normal to the Face it is running accross. */ inline const Vec3r& normal() {return _Normal;} /*! Returns the index of the material of the face it is running accross. */ @@ -921,6 +944,8 @@ public: const FrsMaterial& frs_material() const ; inline void setFace(void * iFace) {_Face = iFace;} + /*! Sets the face mark of the face it is running across. */ + inline void setFaceMark(bool iFaceMark) {_FaceMark = iFaceMark;} /*! Sets the normal to the Face it is running accross. */ inline void setNormal(const Vec3r& iNormal) {_Normal = iNormal;} /*! Sets the index of the material of the face it is running accross. */ diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp index 3e0979f684f..47c4ec05e4f 100755 --- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp @@ -472,6 +472,7 @@ FEdge * ViewEdgeXBuilder::BuildSmoothFEdge(FEdge *feprevious, const OWXFaceLayer fe->setId(_currentFId); fe->setFrsMaterialIndex(ifl.fl->getFace()->frs_materialIndex()); fe->setFace(ifl.fl->getFace()); + fe->setFaceMark(ifl.fl->getFace()->GetMark()); fe->setNormal(normal); fe->setPreviousEdge(feprevious); if(feprevious) @@ -585,19 +586,24 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe) // get the faces normals and the material indices Vec3r normalA, normalB; unsigned matA(0), matB(0); + bool faceMarkA = false, faceMarkB = false; if(iwe.order){ normalB = (iwe.e->GetbFace()->GetNormal()); matB = (iwe.e->GetbFace()->frs_materialIndex()); + faceMarkB = (iwe.e->GetbFace()->GetMark()); if(!(iwe.e->nature() & Nature::BORDER)) { normalA = (iwe.e->GetaFace()->GetNormal()); matA = (iwe.e->GetaFace()->frs_materialIndex()); + faceMarkA = (iwe.e->GetaFace()->GetMark()); } }else{ normalA = (iwe.e->GetbFace()->GetNormal()); matA = (iwe.e->GetbFace()->frs_materialIndex()); + faceMarkA = (iwe.e->GetbFace()->GetMark()); if(!(iwe.e->nature() & Nature::BORDER)) { normalB = (iwe.e->GetaFace()->GetNormal()); matB = (iwe.e->GetaFace()->frs_materialIndex()); + faceMarkB = (iwe.e->GetaFace()->GetMark()); } } // Creates the corresponding feature edge @@ -607,6 +613,8 @@ FEdge * ViewEdgeXBuilder::BuildSharpFEdge(FEdge *feprevious, const OWXEdge& iwe) fe->setId(_currentFId); fe->setaFrsMaterialIndex(matA); fe->setbFrsMaterialIndex(matB); + fe->setaFaceMark(faceMarkA); + fe->setbFaceMark(faceMarkB); fe->setNormalA(normalA); fe->setNormalB(normalB); fe->setPreviousEdge(feprevious); diff --git a/source/blender/freestyle/intern/winged_edge/Nature.h b/source/blender/freestyle/intern/winged_edge/Nature.h index 52c9c60d8c7..62171fae111 100755 --- a/source/blender/freestyle/intern/winged_edge/Nature.h +++ b/source/blender/freestyle/intern/winged_edge/Nature.h @@ -71,6 +71,8 @@ namespace Nature { static const EdgeNature SUGGESTIVE_CONTOUR = (1 << 5); // 32 /*! true for material boundaries */ static const EdgeNature MATERIAL_BOUNDARY = (1 << 6); // 64 + /*! true for user-defined edge marks */ + static const EdgeNature EDGE_MARK = (1 << 7); // 128 } // end of namespace Nature diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp index a5918fd8400..6ef99186a2c 100755 --- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp @@ -258,6 +258,7 @@ WFace::WFace(WFace& iBrother) _VerticesTexCoords = iBrother._VerticesTexCoords; _Id = iBrother.GetId(); _FrsMaterialIndex = iBrother._FrsMaterialIndex; + _Mark = iBrother._Mark; userdata = NULL; iBrother.userdata = new facedata; ((facedata*)(iBrother.userdata))->_copy = this; @@ -624,12 +625,12 @@ WShape::WShape(WShape& iBrother) } } -WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterial) +WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial) { // allocate the new face WFace *face = instanciateFace(); - WFace *result = MakeFace(iVertexList, iMaterial, face); + WFace *result = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial, face); if (0 == result) { delete face; return 0; @@ -637,10 +638,10 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterial) return result; } -WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterial) +WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial) { // allocate the new face - WFace *face = MakeFace(iVertexList, iMaterial); + WFace *face = MakeFace(iVertexList, iFaceEdgeMarksList, iMaterial); if(0 == face) @@ -654,7 +655,7 @@ WFace * WShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsL return face; } -WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterial, WFace *face) +WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterial, WFace *face) { int id = _FaceList.size(); @@ -702,6 +703,10 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterial, WFace normal.normalize(); face->setNormal(normal); + vector<bool>::iterator mit = iFaceEdgeMarksList.begin(); + face->setMark(*mit); + mit++; + // vertex pointers used to build each edge vector<WVertex*>::iterator va, vb; @@ -734,6 +739,9 @@ WFace* WShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterial, WFace // compute the mean edge value: _meanEdgeSize += edge->GetaOEdge()->GetVec().norm(); } + + edge->setMark(*mit); + mit++; } // Add the face to the shape's faces list: diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h index abb6263ae69..dc920448add 100755 --- a/source/blender/freestyle/intern/winged_edge/WEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WEdge.h @@ -372,6 +372,7 @@ protected: WOEdge *_paOEdge; // first oriented edge WOEdge *_pbOEdge; // second oriented edge int _nOEdges; // number of oriented edges associated with this edge. (1 means border edge) + bool _Mark; // user-specified edge mark for feature edge detection int _Id; // Identifier for the edge public: @@ -448,6 +449,7 @@ public: inline WOEdge * GetaOEdge() {return _paOEdge;} inline WOEdge * GetbOEdge() {return _pbOEdge;} inline int GetNumberOfOEdges() {return _nOEdges;} + inline bool GetMark() {return _Mark;} inline int GetId() {return _Id;} inline WVertex * GetaVertex() {return _paOEdge->GetaVertex();} inline WVertex * GetbVertex() {return _paOEdge->GetbVertex();} @@ -480,6 +482,7 @@ public: } } inline void setNumberOfOEdges(int n) {_nOEdges = n;} + inline void setMark(bool mark) {_Mark = mark;} inline void setId(int id) {_Id = id;} virtual void ResetUserData() {userdata = 0;} }; @@ -505,6 +508,7 @@ protected: int _Id; unsigned _FrsMaterialIndex; + bool _Mark; // Freestyle face mark (if true, feature edges on this face are ignored) public: void *userdata; @@ -520,6 +524,7 @@ public: inline Vec3r& GetNormal() {return _Normal;} inline int GetId() {return _Id;} inline unsigned frs_materialIndex() const {return _FrsMaterialIndex;} + inline bool GetMark() const {return _Mark;} const FrsMaterial& frs_material() ; /*! The vertex of index i corresponds to the a vertex @@ -663,6 +668,7 @@ public: inline void setTexCoordsList(const vector<Vec2r>& iTexCoordsList) {_VerticesTexCoords = iTexCoordsList;} inline void setId(int id) {_Id = id;} inline void setFrsMaterialIndex(unsigned iMaterialIndex) {_FrsMaterialIndex = iMaterialIndex;} + inline void setMark(bool iMark) {_Mark = iMark;} /*! designed to build a specialized WEdge * for use in MakeEdge @@ -791,7 +797,7 @@ public: * iMaterialIndex * The material index for this face */ - virtual WFace * MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex); + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex); /*! adds a new face to the shape. The difference with * the previous method is that this one is designed @@ -814,7 +820,7 @@ public: * The list of tex coords, iTexCoordsList[i] corresponding to the * normal of the vertex iVertexList[i] for that face. */ - virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterialIndex); + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex); inline void AddEdge(WEdge *iEdge) {_EdgeList.push_back(iEdge);} inline void AddFace(WFace* iFace) {_FaceList.push_back(iFace);} @@ -892,7 +898,7 @@ protected: * face * The Face that is filled in */ - virtual WFace * MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex, WFace *face); + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex, WFace *face); }; diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp index ff567aee06a..d238749570c 100755 --- a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp @@ -258,9 +258,9 @@ void WXFace::ComputeCenter() /**********************************/ -WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex) +WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex) { - WFace *face = WShape::MakeFace(iVertexList, iMaterialIndex); + WFace *face = WShape::MakeFace(iVertexList, iFaceEdgeMarksList, iMaterialIndex); if(0 == face) return 0; @@ -277,9 +277,9 @@ WFace* WXShape::MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex) return face; } -WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterialIndex) +WFace * WXShape::MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex) { - WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iMaterialIndex); + WFace *face = WShape::MakeFace(iVertexList, iNormalsList, iTexCoordsList, iFaceEdgeMarksList, iMaterialIndex); // Vec3r center; // for(vector<WVertex*>::iterator wv=iVertexList.begin(),wvend=iVertexList.end(); diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h index 9ec8fd4bddb..1734ad1b41f 100755 --- a/source/blender/freestyle/intern/winged_edge/WXEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h @@ -499,7 +499,7 @@ public: * determines the face's edges orientation and (so) the * face orientation. */ - virtual WFace * MakeFace(vector<WVertex*>& iVertexList, unsigned iMaterialIndex); + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex); /*! adds a new face to the shape. The difference with * the previous method is that this one is designed @@ -520,7 +520,7 @@ public: * The list of tex coords, iTexCoordsList[i] corresponding to the * normal of the vertex iVertexList[i] for that face. */ - virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, unsigned iMaterialIndex); + virtual WFace * MakeFace(vector<WVertex*>& iVertexList, vector<Vec3r>& iNormalsList, vector<Vec2r>& iTexCoordsList, vector<bool>& iFaceEdgeMarksList, unsigned iMaterialIndex); /*! Reset all edges and vertices flags (which might * have been set up on a previous pass) diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp index a0a80b7ef64..40c14eafe72 100755 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp @@ -102,6 +102,8 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { // else if(_current_frs_material) // shape.setFrsMaterial(*_current_frs_material); + const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks(); + // sets the current WShape to shape _current_wshape = &shape; @@ -128,6 +130,7 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { new_normals, frs_materials, texCoords, + faceEdgeMarks, vindices, nindices, mindices, @@ -139,6 +142,7 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { new_normals, frs_materials, texCoords, + faceEdgeMarks, vindices, nindices, mindices, @@ -150,6 +154,7 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { new_normals, frs_materials, texCoords, + faceEdgeMarks, vindices, nindices, mindices, @@ -163,6 +168,7 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { mindices += numVertexPerFace[index]; if(tindices) tindices += numVertexPerFace[index]; + faceEdgeMarks++; } delete[] new_vertices; @@ -219,6 +225,7 @@ void WingedEdgeBuilder::buildTriangleStrip( const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, const real *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, @@ -232,6 +239,7 @@ void WingedEdgeBuilder::buildTriangleStrip( const real *vertices, vector<WVertex *> triangleVertices; vector<Vec3r> triangleNormals; vector<Vec2r> triangleTexCoords; + vector<bool> triangleFaceEdgeMarks; while(nDoneVertices < nvertices) { @@ -270,10 +278,14 @@ void WingedEdgeBuilder::buildTriangleStrip( const real *vertices, triangleTexCoords.push_back(Vec2r(texCoords[tindices[nTriangle+1]], texCoords[tindices[nTriangle+1]+1])); } } + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::FACE_MARK) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[nTriangle/3] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); if(mindices) - currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, mindices[nTriangle/3]); + currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[nTriangle/3]); else - currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, 0); + currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); nDoneVertices++; // with a strip, each triangle is one vertex more nTriangle++; } @@ -283,6 +295,7 @@ void WingedEdgeBuilder::buildTriangleFan( const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, const real *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, @@ -295,6 +308,7 @@ void WingedEdgeBuilder::buildTriangles(const real *vertices, const real *normals, vector<FrsMaterial>& iMaterials, const real *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, @@ -304,6 +318,7 @@ void WingedEdgeBuilder::buildTriangles(const real *vertices, vector<WVertex *> triangleVertices; vector<Vec3r> triangleNormals; vector<Vec2r> triangleTexCoords; + vector<bool> triangleFaceEdgeMarks; // Each triplet of vertices is considered as an independent triangle for(unsigned i = 0; i < nvertices / 3; i++) @@ -321,11 +336,16 @@ void WingedEdgeBuilder::buildTriangles(const real *vertices, triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+1]],texCoords[tindices[3*i+1]+1])); triangleTexCoords.push_back(Vec2r(texCoords[tindices[3*i+2]], texCoords[tindices[3*i+2]+1])); } + + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::FACE_MARK) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V1V2) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V2V3) != 0); + triangleFaceEdgeMarks.push_back((iFaceEdgeMarks[i] & IndexedFaceSet::EDGE_MARK_V3V1) != 0); } if(mindices) - currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, mindices[0]); + currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, mindices[0]); else - currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords,0); + currentShape->MakeFace(triangleVertices, triangleNormals, triangleTexCoords, triangleFaceEdgeMarks, 0); } diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h index 6bd515aef0b..8e9d0122e35 100755 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h @@ -114,6 +114,7 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor const real *normals, vector<FrsMaterial>& iMaterials, const real *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, @@ -124,6 +125,7 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor const real *normals, vector<FrsMaterial>& iMaterials, const real *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, @@ -134,6 +136,7 @@ class LIB_WINGED_EDGE_EXPORT WingedEdgeBuilder : public SceneVisitor const real *normals, vector<FrsMaterial>& iMaterials, const real *texCoords, + const IndexedFaceSet::FaceEdgeMark *iFaceEdgeMarks, const unsigned *vindices, const unsigned *nindices, const unsigned *mindices, |