Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp')
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp372
1 files changed, 150 insertions, 222 deletions
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index f16c4c3574b..e57d004e503 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -32,16 +32,16 @@
namespace Freestyle {
-BlenderFileLoader::BlenderFileLoader(Render *re, SceneRenderLayer *srl)
+BlenderFileLoader::BlenderFileLoader(Render *re, ViewLayer *view_layer)
{
_re = re;
- _srl = srl;
+ _view_layer = view_layer;
_Scene = NULL;
_numFacesRead = 0;
#if 0
_minEdgeSize = DBL_MAX;
#endif
- _smooth = (srl->freestyleConfig.flags & FREESTYLE_FACE_SMOOTHNESS_FLAG) != 0;
+ _smooth = (view_layer->freestyle_config.flags & FREESTYLE_FACE_SMOOTHNESS_FLAG) != 0;
_pRenderMonitor = NULL;
}
@@ -52,8 +52,6 @@ BlenderFileLoader::~BlenderFileLoader()
NodeGroup *BlenderFileLoader::Load()
{
- ObjectInstanceRen *obi;
-
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "\n=== Importing triangular meshes into Blender ===" << endl;
}
@@ -81,6 +79,11 @@ NodeGroup *BlenderFileLoader::Load()
_z_offset = 0.f;
}
+ ViewLayer *view_layer = (ViewLayer*)BLI_findstring(&_re->scene->view_layers, _view_layer->name, offsetof(ViewLayer, name));
+ Depsgraph *depsgraph = DEG_graph_new(_re->scene, view_layer, DAG_EVAL_RENDER);
+
+ BKE_scene_graph_update_tagged(depsgraph, _re->main);
+
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Frustum: l " << _viewplane_left << " r " << _viewplane_right
@@ -90,34 +93,37 @@ NodeGroup *BlenderFileLoader::Load()
#endif
int id = 0;
- unsigned cnt = 1;
- unsigned cntStep = (unsigned)ceil(0.01f * _re->totinstance);
- for (obi = (ObjectInstanceRen *)_re->instancetable.first; obi; obi = obi->next) {
- if (_pRenderMonitor) {
- if (_pRenderMonitor->testBreak())
- break;
- if (cnt % cntStep == 0) {
- stringstream ss;
- ss << "Freestyle: Mesh loading " << (100 * cnt / _re->totinstance) << "%";
- _pRenderMonitor->setInfo(ss.str());
- _pRenderMonitor->progress((float)cnt / _re->totinstance);
- }
- cnt++;
+
+ DEG_OBJECT_ITER_BEGIN(
+ depsgraph, ob,
+ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
+ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
+ DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI)
+ {
+ if (_pRenderMonitor && _pRenderMonitor->testBreak()) {
+ break;
}
- if (!(obi->lay & _srl->lay))
- continue;
- char *name = obi->ob->id.name;
- //printf("%c%c:%s\n", name[0], name[1], name+2);
- //print_m4("obi->mat", obi->mat);
+ bool apply_modifiers = false;
+ bool calc_undeformed = false;
+ bool calc_tessface = false;
+ Mesh *mesh = BKE_mesh_new_from_object(depsgraph,
+ _re->main,
+ _re->scene,
+ ob,
+ apply_modifiers,
+ calc_tessface,
+ calc_undeformed);
- if (obi->obr->totvlak > 0) {
- insertShapeNode(obi, ++id);
- }
- else if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Warning: " << (name + 2) << " is not a vlak-based object (ignored)" << endl;
+ if (mesh) {
+ insertShapeNode(ob, mesh, ++id);
+ BKE_libblock_free_ex(_re->main, &mesh->id, true, false);
}
}
+ DEG_OBJECT_ITER_END;
+
+ DEG_graph_free(depsgraph);
// Return the built scene.
return _Scene;
@@ -365,95 +371,86 @@ int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3
return 0;
}
-// Checks if edge rotation (if necessary) can prevent the given quad from
-// being decomposed into a degenerate triangle
-bool BlenderFileLoader::testEdgeRotation(float v1[3], float v2[3], float v3[3], float v4[3])
+static bool testEdgeMark(Mesh *me, FreestyleEdge *fed, const MLoopTri *lt, int i)
{
- if (testDegenerateTriangle(v1, v2, v3) == 2 || testDegenerateTriangle(v1, v3, v4) == 2) {
- if (testDegenerateTriangle(v1, v2, v4) == 2 || testDegenerateTriangle(v2, v3, v4) == 2) {
-#if 0
- if (G.debug & G_DEBUG_FREESTYLE) {
- printf("BlenderFileLoader::testEdgeRotation: edge rotation is unsuccessful.\n");
- }
-#endif
- return false;
- }
- return true;
+ MLoop *mloop = &me->mloop[lt->tri[i]];
+ MLoop *mloop_next = &me->mloop[lt->tri[(i+1)%3]];
+ MEdge *medge = &me->medge[mloop->e];
+
+ if (!ELEM(mloop_next->v, medge->v1, medge->v2)) {
+ /* Not an edge in the original mesh before triangulation. */
+ return false;
}
- return false;
+
+ return (fed[mloop->e].flag & FREESTYLE_EDGE_MARK) != 0;
}
-void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
+void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
{
- ObjectRen *obr = obi->obr;
- char *name = obi->ob->id.name + 2;
+ char *name = ob->id.name + 2;
+
+ // Compute loop triangles
+ int tottri = poly_to_tri_count(me->totpoly, me->totloop);
+ MLoopTri *mlooptri = (MLoopTri*)MEM_malloc_arrayN(tottri, sizeof(*mlooptri), __func__);
+ BKE_mesh_recalc_looptri(
+ me->mloop, me->mpoly,
+ me->mvert,
+ me->totloop, me->totpoly,
+ mlooptri);
+
+ // Compute loop normals
+ BKE_mesh_calc_normals_split(me);
+ float (*lnors)[3] = NULL;
+
+ if (CustomData_has_layer(&me->ldata, CD_NORMAL)) {
+ lnors = (float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL);
+ }
- // We parse vlak nodes and count the number of faces after the clipping by
- // the near and far view planes is applied (Note: mesh vertices are in the
- // camera coordinate system).
- VlakRen *vlr = NULL;
+ // Get other mesh data
+ MVert *mvert = me->mvert;
+ MLoop *mloop = me->mloop;
+ MPoly *mpoly = me->mpoly;
+ FreestyleEdge *fed = (FreestyleEdge*)CustomData_get_layer(&me->edata, CD_FREESTYLE_EDGE);
+ FreestyleFace *ffa = (FreestyleFace*)CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE);
+
+ // Compute matrix including camera transform
+ float obmat[4][4], nmat[4][4];
+ mul_m4_m4m4(obmat, _re->viewmat, ob->obmat);
+ invert_m4_m4(nmat, obmat);
+ transpose_m4(nmat);
+
+ // We count the number of triangles after the clipping by the near and far view
+ // planes is applied (Note: mesh vertices are in the camera coordinate system).
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++) {
- if ((a & 255) == 0)
- vlr = obr->vlaknodes[a>>8].vlak;
- else
- vlr++;
- if (vlr->mat->mode & MA_ONLYCAST)
- continue;
- if (vlr->mat->material_type == MA_TYPE_WIRE) {
- wire_material = 1;
- continue;
- }
- copy_v3_v3(v1, vlr->v1->co);
- copy_v3_v3(v2, vlr->v2->co);
- copy_v3_v3(v3, vlr->v3->co);
- if (vlr->v4)
- copy_v3_v3(v4, vlr->v4->co);
- if (obi->flag & R_TRANSFORMED) {
- mul_m4_v3(obi->mat, v1);
- mul_m4_v3(obi->mat, v2);
- mul_m4_v3(obi->mat, v3);
- if (vlr->v4)
- mul_m4_v3(obi->mat, v4);
- }
+ float v1[3], v2[3], v3[3];
+ float n1[3], n2[3], n3[3], facenormal[3];
+ int clip[3];
+ for (int a = 0; a < tottri; a++) {
+ const MLoopTri *lt = &mlooptri[a];
+
+ copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co);
+ copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co);
+ copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co);
+
+ mul_m4_v3(obmat, v1);
+ mul_m4_v3(obmat, v2);
+ mul_m4_v3(obmat, v3);
+
v1[2] += _z_offset;
v2[2] += _z_offset;
v3[2] += _z_offset;
- if (vlr->v4)
- v4[2] += _z_offset;
-#if 0
- print_v3("v1", v1);
- print_v3("v2", v2);
- print_v3("v3", v3);
- if (vlr->v4)
- print_v3("v4", v4);
-#endif
- if (!vlr->v4 || !testEdgeRotation(v1, v2, v3, v4)) {
- numFaces += countClippedFaces(v1, v2, v3, clip_1);
- if (vlr->v4)
- numFaces += countClippedFaces(v1, v3, v4, clip_2);
- }
- else {
- numFaces += countClippedFaces(v1, v2, v4, clip_1);
- numFaces += countClippedFaces(v2, v3, v4, clip_2);
- }
- }
- if (wire_material) {
- if (G.debug & G_DEBUG_FREESTYLE) {
- cout << "Warning: Object " << name << " has wire materials (ignored)" << endl;
- }
+
+ numFaces += countClippedFaces(v1, v2, v3, clip);
}
#if 0
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "numFaces " << numFaces << endl;
}
#endif
- if (numFaces == 0)
+ if (numFaces == 0) {
+ MEM_freeN(mlooptri);
return;
+ }
// We allocate memory for the meshes to be imported
NodeGroup *currentMesh = new NodeGroup;
@@ -496,107 +493,62 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
// We parse the vlak nodes again and import meshes while applying the clipping
// by the near and far view planes.
- int p;
- for (p = 0; p < obr->totvlak; ++p) { // we parse the faces of the mesh
- if ((p & 255) == 0)
- vlr = obr->vlaknodes[p>>8].vlak;
- else
- vlr++;
- if ((vlr->mat->mode & MA_ONLYCAST) || vlr->mat->material_type == MA_TYPE_WIRE)
- continue;
- copy_v3_v3(v1, vlr->v1->co);
- copy_v3_v3(v2, vlr->v2->co);
- copy_v3_v3(v3, vlr->v3->co);
- if (vlr->v4)
- copy_v3_v3(v4, vlr->v4->co);
- if (obi->flag & R_TRANSFORMED) {
- mul_m4_v3(obi->mat, v1);
- mul_m4_v3(obi->mat, v2);
- mul_m4_v3(obi->mat, v3);
- if (vlr->v4)
- mul_m4_v3(obi->mat, v4);
- }
+ for (int a = 0; a < tottri; a++) {
+ const MLoopTri *lt = &mlooptri[a];
+ const MPoly *mp = &mpoly[lt->poly];
+ Material *mat = give_current_material(ob, mp->mat_nr + 1);
+
+ copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co);
+ copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co);
+ copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co);
+
+ mul_m4_v3(obmat, v1);
+ mul_m4_v3(obmat, v2);
+ mul_m4_v3(obmat, v3);
+
v1[2] += _z_offset;
v2[2] += _z_offset;
v3[2] += _z_offset;
- if (vlr->v4)
- v4[2] += _z_offset;
- 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);
- if (obi->flag & R_TRANSFORMED) {
- mul_m3_v3(obi->nmat, n1);
- mul_m3_v3(obi->nmat, n2);
- mul_m3_v3(obi->nmat, n3);
- normalize_v3(n1);
- normalize_v3(n2);
- normalize_v3(n3);
- if (vlr->v4) {
- mul_m3_v3(obi->nmat, n4);
- normalize_v3(n4);
- }
- }
+
+ if (_smooth && (mp->flag & ME_SMOOTH) && lnors) {
+ copy_v3_v3(n1, lnors[lt->tri[0]]);
+ copy_v3_v3(n2, lnors[lt->tri[1]]);
+ copy_v3_v3(n3, lnors[lt->tri[2]]);
+
+ mul_mat3_m4_v3(nmat, n1);
+ mul_mat3_m4_v3(nmat, n2);
+ mul_mat3_m4_v3(nmat, n3);
+
+ normalize_v3(n1);
+ normalize_v3(n2);
+ normalize_v3(n3);
}
else {
- RE_vlakren_get_normal(_re, obi, vlr, facenormal);
-#ifndef NDEBUG
- /* test if normals are inverted in rendering [T39669] */
- float tnor[3];
- if (vlr->v4)
- normal_quad_v3(tnor, v4, v3, v2, v1);
- else
- normal_tri_v3(tnor, v3, v2, v1);
- BLI_assert(dot_v3v3(tnor, facenormal) > 0.0f);
-#endif
+ normal_tri_v3(facenormal, v3, v2, v1);
+
copy_v3_v3(n1, facenormal);
copy_v3_v3(n2, facenormal);
copy_v3_v3(n3, facenormal);
- if (vlr->v4)
- copy_v3_v3(n4, facenormal);
}
- unsigned int numTris_1, numTris_2;
- bool edge_rotation;
- if (!vlr->v4 || !testEdgeRotation(v1, v2, v3, v4)) {
- numTris_1 = countClippedFaces(v1, v2, v3, clip_1);
- numTris_2 = (!vlr->v4) ? 0 : countClippedFaces(v1, v3, v4, clip_2);
- edge_rotation = false;
- }
- else {
- numTris_1 = countClippedFaces(v1, v2, v4, clip_1);
- numTris_2 = countClippedFaces(v2, v3, v4, clip_2);
- edge_rotation = true;
- if (G.debug & G_DEBUG_FREESTYLE) {
- printf("BlenderFileLoader::insertShapeNode: edge rotation is performed.\n");
- }
- }
- if (numTris_1 == 0 && numTris_2 == 0)
+ unsigned int numTris = countClippedFaces(v1, v2, v3, clip);
+ if (numTris == 0)
continue;
- bool fm, em1, em2, em3, em4;
- fm = (vlr->freestyle_face_mark) != 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;
+
+ bool fm = (ffa) ? (ffa[lt->poly].flag & FREESTYLE_FACE_MARK) != 0 : false;
+ bool em1 = false, em2 = false, em3 = false;
+
+ if (fed) {
+ em1 = testEdgeMark(me, fed, lt, 0);
+ em2 = testEdgeMark(me, fed, lt, 1);
+ em3 = testEdgeMark(me, fed, lt, 2);
}
- Material *mat = vlr->mat;
if (mat) {
tmpMat.setLine(mat->line_col[0], mat->line_col[1], mat->line_col[2], mat->line_col[3]);
- tmpMat.setDiffuse(mat->r, mat->g, mat->b, mat->alpha);
- tmpMat.setSpecular(mat->specr, mat->specg, mat->specb, mat->spectra);
- float s = 1.0 * (mat->har + 1) / 4 ; // in Blender: [1;511] => in OpenGL: [0;128]
- if (s > 128.f)
- s = 128.f;
- tmpMat.setShininess(s);
+ tmpMat.setDiffuse(mat->r, mat->g, mat->b, 1.0f);
+ tmpMat.setSpecular(mat->specr, mat->specg, mat->specb, 1.0f);
+ tmpMat.setShininess(128.f);
tmpMat.setPriority(mat->line_priority);
}
@@ -631,43 +583,19 @@ 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) {
- if (!edge_rotation) {
- clipTriangle(numTris_1, triCoords, v1, v2, v3, triNormals, n1, n2, n3,
- edgeMarks, em1, em2, (!vlr->v4) ? em3 : false, clip_1);
- }
- else {
- clipTriangle(numTris_1, triCoords, v1, v2, v4, triNormals, n1, n2, n4,
- edgeMarks, em1, false, em4, 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],
- fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i + 1],
- (i == numTris_1 - 1) ? edgeMarks[i + 2] : false);
- _numFacesRead++;
- }
- }
-
- if (numTris_2 > 0) {
- if (!edge_rotation) {
- clipTriangle(numTris_2, triCoords, v1, v3, v4, triNormals, n1, n3, n4,
- edgeMarks, false, em3, em4, clip_2);
- }
- else {
- clipTriangle(numTris_2, triCoords, v2, v3, v4, triNormals, n2, n3, n4,
- edgeMarks, em2, em3, false, 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],
- fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i + 1],
- (i == numTris_2 - 1) ? edgeMarks[i + 2] : false);
- _numFacesRead++;
- }
+ clipTriangle(numTris, triCoords, v1, v2, v3, triNormals, n1, n2, n3,
+ edgeMarks, em1, em2, em3, clip);
+ for (i = 0; i < numTris; i++) {
+ addTriangle(&ls, triCoords[0], triCoords[i + 1], triCoords[i + 2],
+ triNormals[0], triNormals[i + 1], triNormals[i + 2],
+ fm, (i == 0) ? edgeMarks[0] : false, edgeMarks[i + 1],
+ (i == numTris - 1) ? edgeMarks[i + 2] : false);
+ _numFacesRead++;
}
}
+ MEM_freeN(mlooptri);
+
// We might have several times the same vertex. We want a clean
// shape with no real-vertex. Here, we are making a cleaning pass.
float *cleanVertices = NULL;
@@ -806,8 +734,8 @@ void BlenderFileLoader::insertShapeNode(ObjectInstanceRen *obi, int id)
cleanNIndices, niSize, MIndices, viSize, 0, 0, 0);
// sets the id of the rep
rep->setId(Id(id, 0));
- rep->setName(obi->ob->id.name + 2);
- rep->setLibraryPath(obi->ob->id.lib ? obi->ob->id.lib->name : NULL);
+ rep->setName(ob->id.name + 2);
+ rep->setLibraryPath(ob->id.lib ? ob->id.lib->name : NULL);
const BBox<Vec3r> bbox = BBox<Vec3r>(Vec3r(ls.minBBox[0], ls.minBBox[1], ls.minBBox[2]),
Vec3r(ls.maxBBox[0], ls.maxBBox[1], ls.maxBBox[2]));