Blender V4.3
Controller.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9extern "C" {
10#include <Python.h>
11}
12
13#include <cfloat>
14#include <fstream>
15#include <string>
16
17#include "AppCanvas.h"
18#include "AppConfig.h"
19#include "AppView.h"
20#include "Controller.h"
21
22#include "../image/Image.h"
23
30
35
38
40#include "../view_map/ViewMap.h"
42
47
51
52#include "BKE_global.hh"
53#include "BLI_path_utils.hh"
54#include "BLI_utildefines.h"
55
56#include "DNA_freestyle_types.h"
57
58#include "FRS_freestyle.h"
59
60namespace Freestyle {
61
63{
64 const string sep(Config::DIR_SEP);
65#if 0
66 const string filename = Config::Path::getInstance()->getHomeDir() + sep + Config::OPTIONS_DIR +
68 _current_dirs = new ConfigIO(filename, Config::APPLICATION_NAME + "CurrentDirs", true);
69#endif
70
71 _RootNode = new NodeGroup;
72 _RootNode->addRef();
73
74#if 0
75 _SilhouetteNode = nullptr;
76 _ProjectedSilhouette = nullptr;
77 _VisibleProjectedSilhouette = nullptr;
78
79 _DebugNode = new NodeGroup;
80 _DebugNode->addRef();
81#endif
82
83 _winged_edge = nullptr;
84
85 _pView = nullptr;
86 _pRenderMonitor = nullptr;
87
88 _edgeTesselationNature = (Nature::SILHOUETTE | Nature::BORDER | Nature::CREASE);
89
90 _ProgressBar = new ProgressBar;
91 _SceneNumFaces = 0;
92#if 0
93 _minEdgeSize = DBL_MAX;
94#endif
95 _EPSILON = 1.0e-6;
96 _bboxDiag = 0;
97
98 _ViewMap = nullptr;
99
100 _Canvas = nullptr;
101
103 //_VisibilityAlgo = ViewMapBuilder::ray_casting;
104
105 _Canvas = new AppCanvas;
106
107 _inter = new PythonInterpreter();
108 _EnableViewMapCache = false;
109 _EnableQI = true;
110 _EnableFaceSmoothness = false;
111 _ComputeRidges = true;
112 _ComputeSteerableViewMap = false;
113 _ComputeSuggestive = true;
114 _ComputeMaterialBoundaries = true;
115 _sphereRadius = 1.0;
116 _creaseAngle = 134.43;
117 prevSceneHash = -1.0;
118
119 init_options();
120}
121
123{
124 if (nullptr != _RootNode) {
125 int ref = _RootNode->destroy();
126 if (0 == ref) {
127 delete _RootNode;
128 }
129 }
130
131#if 0
132 if (nullptr != _SilhouetteNode) {
133 int ref = _SilhouetteNode->destroy();
134 if (0 == ref) {
135 delete _SilhouetteNode;
136 }
137 }
138
139 if (nullptr != _DebugNode) {
140 int ref = _DebugNode->destroy();
141 if (0 == ref) {
142 delete _DebugNode;
143 }
144 }
145#endif
146
147 if (_winged_edge) {
148 delete _winged_edge;
149 _winged_edge = nullptr;
150 }
151
152 if (nullptr != _ViewMap) {
153 delete _ViewMap;
154 _ViewMap = nullptr;
155 }
156
157 if (nullptr != _Canvas) {
158 delete _Canvas;
159 _Canvas = nullptr;
160 }
161
162 if (_inter) {
163 delete _inter;
164 _inter = nullptr;
165 }
166
167 if (_ProgressBar) {
168 delete _ProgressBar;
169 _ProgressBar = nullptr;
170 }
171
172 // delete _current_dirs;
173}
174
176{
177 if (nullptr == iView) {
178 return;
179 }
180
181 _pView = iView;
182 _Canvas->setViewer(_pView);
183}
184
186{
187 _pRenderMonitor = iRenderMonitor;
188}
189
190void Controller::setPassDiffuse(float *buf, int width, int height)
191{
192 AppCanvas *app_canvas = dynamic_cast<AppCanvas *>(_Canvas);
193 BLI_assert(app_canvas != nullptr);
194 app_canvas->setPassDiffuse(buf, width, height);
195}
196
197void Controller::setPassZ(float *buf, int width, int height)
198{
199 AppCanvas *app_canvas = dynamic_cast<AppCanvas *>(_Canvas);
200 BLI_assert(app_canvas != nullptr);
201 app_canvas->setPassZ(buf, width, height);
202}
203
205{
206 PythonInterpreter *py_inter = dynamic_cast<PythonInterpreter *>(_inter);
207 py_inter->setContext(C);
208}
209
211{
212 if (!_EnableViewMapCache) {
213 return false;
214 }
215 if (sceneHashFunc.match()) {
216 return (nullptr != _ViewMap);
217 }
218 sceneHashFunc.store();
219 return false;
220}
221
222int Controller::LoadMesh(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
223{
224 BlenderFileLoader loader(re, view_layer, depsgraph);
225
226 loader.setRenderMonitor(_pRenderMonitor);
227
228 _Chrono.start();
229
230 NodeGroup *blenderScene = loader.Load();
231
232 if (blenderScene == nullptr) {
233 if (G.debug & G_DEBUG_FREESTYLE) {
234 cout << "Cannot load scene" << endl;
235 }
236 return 1;
237 }
238
239 if (blenderScene->numberOfChildren() < 1) {
240 if (G.debug & G_DEBUG_FREESTYLE) {
241 cout << "Empty scene" << endl;
242 }
243 blenderScene->destroy();
244 delete blenderScene;
245 return 1;
246 }
247
248 real duration = _Chrono.stop();
249 if (G.debug & G_DEBUG_FREESTYLE) {
250 cout << "Scene loaded" << endl;
251 printf("Mesh cleaning : %lf\n", duration);
252 printf("View map cache : %s\n", _EnableViewMapCache ? "enabled" : "disabled");
253 }
254 _SceneNumFaces += loader.numFacesRead();
255
256#if 0
257 if (loader.minEdgeSize() < _minEdgeSize) {
258 _minEdgeSize = loader.minEdgeSize();
259 }
260#endif
261
262#if 0 // DEBUG
264 blenderScene->accept(spp);
265#endif
266
267 _RootNode->AddChild(blenderScene);
268 _RootNode->UpdateBBox(); // FIXME: Correct that by making a Renderer to compute the bbox
269
270 _pView->setModel(_RootNode);
271 //_pView->FitBBox();
272
273 if (_pRenderMonitor->testBreak()) {
274 return 0;
275 }
276
277 if (_EnableViewMapCache) {
278
279 NodeCamera *cam;
280 if (g_freestyle.proj[3][3] != 0.0) {
281 cam = new NodeOrthographicCamera;
282 }
283 else {
284 cam = new NodePerspectiveCamera;
285 }
286 double proj[16];
287 for (int i = 0; i < 4; i++) {
288 for (int j = 0; j < 4; j++) {
289 proj[i * 4 + j] = g_freestyle.proj[i][j];
290 }
291 }
292 cam->setProjectionMatrix(proj);
293 _RootNode->AddChild(cam);
294 _RootNode->AddChild(new NodeViewLayer(*re->scene, *view_layer));
295
296 sceneHashFunc.reset();
297 // blenderScene->accept(sceneHashFunc);
298 _RootNode->accept(sceneHashFunc);
299 if (G.debug & G_DEBUG_FREESTYLE) {
300 cout << "Scene hash : " << sceneHashFunc.toString() << endl;
301 }
302 if (hitViewMapCache()) {
304 return 0;
305 }
306
307 delete _ViewMap;
308 _ViewMap = nullptr;
309 }
310
311 _Chrono.start();
312
313 WXEdgeBuilder wx_builder;
314 wx_builder.setRenderMonitor(_pRenderMonitor);
315 blenderScene->accept(wx_builder);
316 _winged_edge = wx_builder.getWingedEdge();
317
318 duration = _Chrono.stop();
319 if (G.debug & G_DEBUG_FREESTYLE) {
320 printf("WEdge building : %lf\n", duration);
321 }
322
323#if 0
324 _pView->setDebug(_DebugNode);
325
326 // delete stuff
327 if (0 != ws_builder) {
328 delete ws_builder;
329 ws_builder = 0;
330 }
331
332 soc QFileInfo qfi(iFileName);
333 soc string basename((const char *)qfi.fileName().toAscii().data());
334 char cleaned[FILE_MAX];
335 BLI_strncpy(cleaned, iFileName, FILE_MAX);
336 BLI_path_normalize(cleaned);
337 string basename = string(cleaned);
338#endif
339
340 _ListOfModels.emplace_back("Blender_models");
341
342 _Scene3dBBox = _RootNode->bbox();
343
344 _bboxDiag = (_RootNode->bbox().getMax() - _RootNode->bbox().getMin()).norm();
345 if (G.debug & G_DEBUG_FREESTYLE) {
346 cout << "Triangles nb : " << _SceneNumFaces << " imported, " << _winged_edge->getNumFaces()
347 << " retained" << endl;
348 cout << "Bounding Box : " << _bboxDiag << endl;
349 }
350
352
353 _SceneNumFaces = _winged_edge->getNumFaces();
354 if (_SceneNumFaces == 0) {
356 return 1;
357 }
358
359 return 0;
360}
361
363{
365 _ListOfModels.clear();
366
367 // We deallocate the memory:
371
372 // clears the canvas
373 _Canvas->Clear();
374
375 // soc: reset passes
376 setPassDiffuse(nullptr, 0, 0);
377 setPassZ(nullptr, 0, 0);
378}
379
381{
382 _pView->DetachModel();
383 if (nullptr != _RootNode) {
384 int ref = _RootNode->destroy();
385 if (0 == ref) {
386 _RootNode->addRef();
387 }
388 _RootNode->clearBBox();
389 }
390}
391
393{
394 if (_winged_edge) {
395 delete _winged_edge;
396 _winged_edge = nullptr;
397 }
398
399 // clears the grid
400 _Grid.clear();
401 _Scene3dBBox.clear();
402 _SceneNumFaces = 0;
403#if 0
404 _minEdgeSize = DBL_MAX;
405#endif
406}
407
408void Controller::DeleteViewMap(bool freeCache)
409{
410#if 0
411 _pView->DetachSilhouette();
412 if (nullptr != _SilhouetteNode) {
413 int ref = _SilhouetteNode->destroy();
414 if (0 == ref) {
415 delete _SilhouetteNode;
416 _SilhouetteNode = nullptr;
417 }
418 }
419
420 if (nullptr != _ProjectedSilhouette) {
421 int ref = _ProjectedSilhouette->destroy();
422 if (0 == ref) {
423 delete _ProjectedSilhouette;
424 _ProjectedSilhouette = nullptr;
425 }
426 }
427 if (nullptr != _VisibleProjectedSilhouette) {
428 int ref = _VisibleProjectedSilhouette->destroy();
429 if (0 == ref) {
430 delete _VisibleProjectedSilhouette;
431 _VisibleProjectedSilhouette = nullptr;
432 }
433 }
434
435 _pView->DetachDebug();
436 if (nullptr != _DebugNode) {
437 int ref = _DebugNode->destroy();
438 if (0 == ref) {
439 _DebugNode->addRef();
440 }
441 }
442#endif
443
444 if (nullptr != _ViewMap) {
445 if (freeCache || !_EnableViewMapCache) {
446 delete _ViewMap;
447 _ViewMap = nullptr;
448 prevSceneHash = -1.0;
449 }
450 else {
451 _ViewMap->Clean();
452 }
453 }
454}
455
457{
458 if (_ListOfModels.empty()) {
459 return;
460 }
461
462 DeleteViewMap(true);
463
464 // retrieve the 3D viewpoint and transformations information
465 //----------------------------------------------------------
466 // Save the viewpoint context at the view level in order
467 // to be able to restore it later:
468
469 // Restore the context of view:
470 // we need to perform all these operations while the
471 // 3D context is on.
473
474#if 0
475 if (G.debug & G_DEBUG_FREESTYLE) {
476 cout << "mv" << endl;
477 }
478#endif
479 real mv[4][4];
480 for (int i = 0; i < 4; i++) {
481 for (int j = 0; j < 4; j++) {
482 mv[i][j] = g_freestyle.mv[i][j];
483#if 0
484 if (G.debug & G_DEBUG_FREESTYLE) {
485 cout << mv[i][j] << " ";
486 }
487#endif
488 }
489#if 0
490 if (G.debug & G_DEBUG_FREESTYLE) {
491 cout << endl;
492 }
493#endif
494 }
495
496#if 0
497 if (G.debug & G_DEBUG_FREESTYLE) {
498 cout << "\nproj" << endl;
499 }
500#endif
501 real proj[4][4];
502 for (int i = 0; i < 4; i++) {
503 for (int j = 0; j < 4; j++) {
504 proj[i][j] = g_freestyle.proj[i][j];
505#if 0
506 if (G.debug & G_DEBUG_FREESTYLE) {
507 cout << proj[i][j] << " ";
508 }
509#endif
510 }
511#if 0
512 if (G.debug & G_DEBUG_FREESTYLE) {
513 cout << endl;
514 }
515#endif
516 }
517
518 int viewport[4];
519 for (int i = 0; i < 4; i++) {
520 viewport[i] = g_freestyle.viewport[i];
521 }
522
523#if 0
524 if (G.debug & G_DEBUG_FREESTYLE) {
525 cout << "\nfocal:" << _pView->GetFocalLength() << endl << endl;
526 }
527#endif
528
529 // Flag the WXEdge structure for silhouette edge detection:
530 //----------------------------------------------------------
531
532 if (G.debug & G_DEBUG_FREESTYLE) {
533 cout << "\n=== Detecting silhouette edges ===" << endl;
534 }
535 _Chrono.start();
536
537 edgeDetector.setViewpoint(vp);
538 edgeDetector.enableOrthographicProjection(proj[3][3] != 0.0);
539 edgeDetector.enableRidgesAndValleysFlag(_ComputeRidges);
540 edgeDetector.enableSuggestiveContours(_ComputeSuggestive);
541 edgeDetector.enableMaterialBoundaries(_ComputeMaterialBoundaries);
542 edgeDetector.enableFaceSmoothness(_EnableFaceSmoothness);
543 edgeDetector.setCreaseAngle(_creaseAngle);
544 edgeDetector.setSphereRadius(_sphereRadius);
545 edgeDetector.setSuggestiveContourKrDerivativeEpsilon(_suggestiveContourKrDerivativeEpsilon);
546 edgeDetector.setRenderMonitor(_pRenderMonitor);
547 edgeDetector.processShapes(*_winged_edge);
548
549 real duration = _Chrono.stop();
550 if (G.debug & G_DEBUG_FREESTYLE) {
551 printf("Feature lines : %lf\n", duration);
552 }
553
554 if (_pRenderMonitor->testBreak()) {
555 return;
556 }
557
558 // Builds the view map structure from the flagged WSEdge structure:
559 //----------------------------------------------------------
560 ViewMapBuilder vmBuilder;
561 vmBuilder.setEnableQI(_EnableQI);
562 vmBuilder.setViewpoint(vp);
563 vmBuilder.setTransform(
564 mv, proj, viewport, _pView->GetFocalLength(), _pView->GetAspect(), _pView->GetFovyRadian());
565 vmBuilder.setFrustum(_pView->znear(), _pView->zfar());
566 vmBuilder.setGrid(&_Grid);
567 vmBuilder.setRenderMonitor(_pRenderMonitor);
568
569#if 0
570 // Builds a tessellated form of the silhouette for display purpose:
571 //---------------------------------------------------------------
572 ViewMapTesselator3D sTesselator3d;
573 ViewMapTesselator2D sTesselator2d;
574 sTesselator2d.setNature(_edgeTesselationNature);
575 sTesselator3d.setNature(_edgeTesselationNature);
576#endif
577
578 if (G.debug & G_DEBUG_FREESTYLE) {
579 cout << "\n=== Building the view map ===" << endl;
580 }
581 _Chrono.start();
582 // Build View Map
583 _ViewMap = vmBuilder.BuildViewMap(
584 *_winged_edge, _VisibilityAlgo, _EPSILON, _Scene3dBBox, _SceneNumFaces);
585 _ViewMap->setScene3dBBox(_Scene3dBBox);
586
587 if (G.debug & G_DEBUG_FREESTYLE) {
588 printf("ViewMap edge count : %i\n", _ViewMap->viewedges_size());
589 }
590
591#if 0
592 // Tesselate the 3D edges:
593 _SilhouetteNode = sTesselator3d.Tesselate(_ViewMap);
594 _SilhouetteNode->addRef();
595
596 // Tesselate 2D edges
597 _ProjectedSilhouette = sTesselator2d.Tesselate(_ViewMap);
598 _ProjectedSilhouette->addRef();
599#endif
600
601 duration = _Chrono.stop();
602 if (G.debug & G_DEBUG_FREESTYLE) {
603 printf("ViewMap building : %lf\n", duration);
604 }
605
606#if 0
607 _pView->AddSilhouette(_SilhouetteNode);
608 _pView->AddSilhouette(_WRoot);
609 _pView->Add2DSilhouette(_ProjectedSilhouette);
610 _pView->Add2DVisibleSilhouette(_VisibleProjectedSilhouette);
611 _pView->AddDebug(_DebugNode);
612#endif
613
614 // Draw the steerable density map:
615 //--------------------------------
616 if (_ComputeSteerableViewMap) {
618 }
619 // Reset Style modules modification flags
620 resetModified(true);
621
623}
624
626{
627#if 0 // soc
628 if ((!_Canvas) || (!_ViewMap)) {
629 return;
630 }
631
632 // Build 4 nodes containing the edges in the 4 directions
634 uint i;
635 real c =
636 32.0f /
637 255.0f; // see SteerableViewMap::readSteerableViewMapPixel() for information about this 32.
638 for (i = 0; i < Canvas::NB_STEERABLE_VIEWMAP; ++i) {
639 ng[i] = new NodeGroup;
640 }
641 NodeShape *completeNS = new NodeShape;
642 completeNS->material().setDiffuse(c, c, c, 1);
643 ng[Canvas::NB_STEERABLE_VIEWMAP - 1]->AddChild(completeNS);
645 svm->Reset();
646
648 LineRep *fRep;
649 NodeShape *ns;
650 for (ViewMap::fedges_container::iterator f = fedges.begin(), fend = fedges.end(); f != fend; ++f)
651 {
652 if ((*f)->viewedge()->qi() != 0) {
653 continue;
654 }
655 fRep = new LineRep((*f)->vertexA()->point2d(), (*f)->vertexB()->point2d());
656 completeNS->AddRep(fRep); // add to the complete map anyway
657 double *oweights = svm->AddFEdge(*f);
658 for (i = 0; i < (Canvas::NB_STEERABLE_VIEWMAP - 1); ++i) {
659 ns = new NodeShape;
660 double wc = oweights[i] * c;
661 if (oweights[i] == 0) {
662 continue;
663 }
664 ns->material().setDiffuse(wc, wc, wc, 1);
665 ns->AddRep(fRep);
666 ng[i]->AddChild(ns);
667 }
668 }
669
671 //#ifdef WIN32
672 QGLBasicWidget offscreenBuffer(_pView, "SteerableViewMap", _pView->width(), _pView->height());
673 QPixmap pm;
674 QImage qimg;
675 for (i = 0; i < Canvas::NB_STEERABLE_VIEWMAP; ++i) {
676 offscreenBuffer.AddNode(ng[i]);
677# if 0
678 img[i] = new GrayImage(_pView->width(), _pView->height());
679 offscreenBuffer.readPixels(0, 0, _pView->width(), _pView->height(), img[i]->getArray());
680# endif
681 pm = offscreenBuffer.renderPixmap(_pView->width(), _pView->height());
682
683 if (pm.isNull()) {
684 if (G.debug & G_DEBUG_FREESTYLE) {
685 cout << "BuildViewMap Warning: couldn't render the steerable ViewMap" << endl;
686 }
687 }
688 // pm.save(QString("steerable") + QString::number(i) + QString(".bmp"), "BMP");
689 // FIXME!! Lost of time !
690 qimg = pm.toImage();
691 // FIXME !! again!
692 img[i] = new GrayImage(_pView->width(), _pView->height());
693 for (uint y = 0; y < img[i]->height(); ++y) {
694 for (uint x = 0; x < img[i]->width(); ++x) {
695 // img[i]->setPixel(x, y, float(qGray(qimg.pixel(x, y))) / 255.0f);
696 img[i]->setPixel(x, y, float(qGray(qimg.pixel(x, y))));
697 // float c = qGray(qimg.pixel(x, y));
698 // img[i]->setPixel(x, y, qGray(qimg.pixel(x, y)));
699 }
700 }
701 offscreenBuffer.DetachNode(ng[i]);
702 ng[i]->destroy();
703 delete ng[i];
704 // check
705# if 0
706 qimg = QImage(_pView->width(), _pView->height(), 32);
707 for (uint y = 0; y < img[i]->height(); ++y) {
708 for (uint x = 0; x < img[i]->width(); ++x) {
709 float v = img[i]->pixel(x, y);
710 qimg.setPixel(x, y, qRgb(v, v, v));
711 }
712 }
713 qimg.save(QString("newsteerable") + QString::number(i) + QString(".bmp"), "BMP");
714# endif
715 }
716
717 svm->buildImagesPyramids(img, false, 0, 1.0f);
718#endif
719}
720
722{
724 if (!svm) {
725 cerr << "the Steerable ViewMap has not been computed yet" << endl;
726 return;
727 }
729}
730
732{
733 if (_VisibilityAlgo == ViewMapBuilder::ray_casting) {
734 _VisibilityAlgo = ViewMapBuilder::ray_casting_fast;
735 }
736 else if (_VisibilityAlgo == ViewMapBuilder::ray_casting_fast) {
738 }
739 else {
740 _VisibilityAlgo = ViewMapBuilder::ray_casting;
741 }
742}
743
745{
746 switch (algo) {
748 _VisibilityAlgo = ViewMapBuilder::ray_casting;
749 break;
751 _VisibilityAlgo = ViewMapBuilder::ray_casting_fast;
752 break;
755 break;
758 break;
761 break;
764 break;
767 break;
768 }
769}
770
794
796{
797 _EnableViewMapCache = iBool;
798}
799
801{
802 return _EnableViewMapCache;
803}
804
806{
807 _EnableQI = iBool;
808}
809
811{
812 return _EnableQI;
813}
814
816{
817 _EnableFaceSmoothness = iBool;
818}
819
821{
822 return _EnableFaceSmoothness;
823}
824
826{
827 _ComputeRidges = b;
828}
829
831{
832 return _ComputeRidges;
833}
834
836{
837 _ComputeSuggestive = b;
838}
839
841{
842 return _ComputeSuggestive;
843}
844
846{
847 _ComputeMaterialBoundaries = b;
848}
849
851{
852 return _ComputeMaterialBoundaries;
853}
854
856{
857 _ComputeSteerableViewMap = iBool;
858}
859
861{
862 return _ComputeSteerableViewMap;
863}
864
866{
867 if (_ViewMap == nullptr) {
868 return 0;
869 }
870
871 if (G.debug & G_DEBUG_FREESTYLE) {
872 cout << "\n=== Stroke drawing ===" << endl;
873 }
874 _Chrono.start();
875 _Canvas->Draw();
876 real d = _Chrono.stop();
877 int strokeCount = _Canvas->getStrokeCount();
878 if (G.debug & G_DEBUG_FREESTYLE) {
879 cout << "Strokes generation : " << d << endl;
880 cout << "Stroke count : " << strokeCount << endl;
881 }
884 return strokeCount;
885}
886
888{
889 _render_count = 0;
890}
891
893{
894 int totmesh = 0;
895 _Chrono.start();
896 BlenderStrokeRenderer *blenderRenderer = new BlenderStrokeRenderer(re, ++_render_count);
897 if (render) {
898 _Canvas->Render(blenderRenderer);
899 totmesh = blenderRenderer->GenerateScene();
900 }
901 real d = _Chrono.stop();
902 if (G.debug & G_DEBUG_FREESTYLE) {
903 cout << "Temporary scene generation: " << d << endl;
904 }
905 _Chrono.start();
906 Render *freestyle_render = blenderRenderer->RenderScene(re, render);
907 d = _Chrono.stop();
908 if (G.debug & G_DEBUG_FREESTYLE) {
909 cout << "Stroke rendering : " << d << endl;
910
912 uintptr_t peak_memory = MEM_get_peak_memory();
913
914 float megs_used_memory = (mem_in_use) / (1024.0 * 1024.0);
915 float megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
916
917 printf("%d objs, mem %.2fM (peak %.2fM)\n", totmesh, megs_used_memory, megs_peak_memory);
918 }
919 delete blenderRenderer;
920
921 return freestyle_render;
922}
923
924void Controller::InsertStyleModule(uint index, const char *iFileName)
925{
926 if (!BLI_path_extension_check(iFileName, ".py")) {
927 cerr << "Error: Cannot load \"" << string(iFileName) << "\", unknown extension" << endl;
928 return;
929 }
930
931 StyleModule *sm = new StyleModule(iFileName, _inter);
932 _Canvas->InsertStyleModule(index, sm);
933}
934
935void Controller::InsertStyleModule(uint index, const char *iName, const char *iBuffer)
936{
937 StyleModule *sm = new BufferedStyleModule(iBuffer, iName, _inter);
938 _Canvas->InsertStyleModule(index, sm);
939}
940
941void Controller::InsertStyleModule(uint index, const char *iName, Text *iText)
942{
943 StyleModule *sm = new BlenderStyleModule(iText, iName, _inter);
944 _Canvas->InsertStyleModule(index, sm);
945}
946
947void Controller::AddStyleModule(const char * /*iFileName*/)
948{
949 //_pStyleWindow->Add(iFileName);
950}
951
956
958{
959 _Canvas->Clear();
960}
961
962void Controller::ReloadStyleModule(uint index, const char *iFileName)
963{
964 StyleModule *sm = new StyleModule(iFileName, _inter);
965 _Canvas->ReplaceStyleModule(index, sm);
966}
967
969{
970 _Canvas->SwapStyleModules(i1, i2);
971}
972
973void Controller::toggleLayer(uint index, bool iDisplay)
974{
975 _Canvas->setVisible(index, iDisplay);
976}
977
978void Controller::setModified(uint index, bool iMod)
979{
980 //_pStyleWindow->setModified(index, iMod);
981 _Canvas->setModified(index, iMod);
982 updateCausalStyleModules(index + 1);
983}
984
986{
987 vector<uint> vec;
988 _Canvas->causalStyleModules(vec, index);
989 for (vector<uint>::const_iterator it = vec.begin(); it != vec.end(); it++) {
990 //_pStyleWindow->setModified(*it, true);
991 _Canvas->setModified(*it, true);
992 }
993}
994
996{
997 //_pStyleWindow->resetModified(iMod);
998 _Canvas->resetModified(iMod);
999}
1000
1001NodeGroup *Controller::BuildRep(vector<ViewEdge *>::iterator vedges_begin,
1002 vector<ViewEdge *>::iterator vedges_end)
1003{
1004 ViewMapTesselator2D tesselator2D;
1005 FrsMaterial mat;
1006 mat.setDiffuse(1, 1, 0.3, 1);
1007 tesselator2D.setFrsMaterial(mat);
1008
1009 return tesselator2D.Tesselate(vedges_begin, vedges_end);
1010}
1011
1013{
1014 _edgeTesselationNature ^= (iNature);
1016}
1017
1018void Controller::setModelsDir(const string & /*dir*/)
1019{
1020 //_current_dirs->setValue("models/dir", dir);
1021}
1022
1024{
1025 string dir = ".";
1026 //_current_dirs->getValue("models/dir", dir);
1027 return dir;
1028}
1029
1030void Controller::setModulesDir(const string & /*dir*/)
1031{
1032 //_current_dirs->setValue("modules/dir", dir);
1033}
1034
1036{
1037 string dir = ".";
1038 //_current_dirs->getValue("modules/dir", dir);
1039 return dir;
1040}
1041
1043{
1044 if (_inter) {
1045 _inter->reset();
1046 }
1047}
1048
1050{
1052 if (!svm) {
1053 return;
1054 }
1055
1056 uint i, j;
1057 using densityCurve = vector<Vec3r>;
1058 vector<densityCurve> curves(svm->getNumberOfOrientations() + 1);
1059 vector<densityCurve> curvesDirection(svm->getNumberOfPyramidLevels());
1060
1061 // collect the curves values
1062 uint nbCurves = svm->getNumberOfOrientations() + 1;
1063 uint nbPoints = svm->getNumberOfPyramidLevels();
1064 if (!nbPoints) {
1065 return;
1066 }
1067
1068 // build the density/nbLevels curves for each orientation
1069 for (i = 0; i < nbCurves; ++i) {
1070 for (j = 0; j < nbPoints; ++j) {
1071 curves[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(i, j, x, y), 0));
1072 }
1073 }
1074 // build the density/nbOrientations curves for each level
1075 for (i = 0; i < nbPoints; ++i) {
1076 for (j = 0; j < nbCurves; ++j) {
1077 curvesDirection[i].push_back(Vec3r(j, svm->readSteerableViewMapPixel(j, i, x, y), 0));
1078 }
1079 }
1080
1081 // display the curves
1082#if 0
1083 for (i = 0; i < nbCurves; ++i) {
1084 _pDensityCurvesWindow->setOrientationCurve(
1085 i, Vec2d(0, 0), Vec2d(nbPoints, 1), curves[i], "scale", "density");
1086 }
1087 for (i = 1; i <= 8; ++i) {
1088 _pDensityCurvesWindow->setLevelCurve(
1089 i, Vec2d(0, 0), Vec2d(nbCurves, 1), curvesDirection[i], "orientation", "density");
1090 }
1091 _pDensityCurvesWindow->show();
1092#endif
1093}
1094
1096{
1097 // from AppOptionsWindow.cpp
1098 // Default init options
1099
1101
1102 // Directories
1105
1106 // ViewMap Format
1108
1109 // Visibility
1111
1112 // soc: initialize canvas
1113 _Canvas->init();
1114
1115 // soc: initialize passes
1116 setPassDiffuse(nullptr, 0, 0);
1117 setPassZ(nullptr, 0, 0);
1118}
1119
1120} /* namespace Freestyle */
Configuration file.
@ G_DEBUG_FREESTYLE
#define BLI_assert(a)
Definition BLI_assert.h:50
#define FILE_MAX
int BLI_path_normalize(char *path) ATTR_NONNULL(1)
bool BLI_path_extension_check(const char *path, const char *ext) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
#define UNPACK3(a)
The spinal tap of the system.
GTS - Library for the manipulation of triangulated surfaces.
@ FREESTYLE_ALGO_FAST
@ FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE
@ FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL
@ FREESTYLE_ALGO_VERYFAST
@ FREESTYLE_ALGO_ADAPTIVE_CUMULATIVE
@ FREESTYLE_ALGO_REGULAR
@ FREESTYLE_ALGO_ADAPTIVE_TRADITIONAL
struct FreestyleGlobals g_freestyle
Class to encapsulate an array of RGB or Gray level values.
Class to define a Drawing Style to be applied to the underlying children. Inherits from NodeGroup.
Class to build a shape node. It contains a Rep, which is the shape geometry.
Class to represent a transform node. A Transform node contains one or several children,...
Class to represent a view layer in Blender.
Class to define the Postscript rendering of a stroke.
Python Interpreter.
Class to display textual information about a scene graph.
Convenient access to the steerable ViewMap to which any element of the ViewMap belongs to.
String utilities.
Class to build a Node Tree designed to be displayed from a set of strokes structure.
Class representing a style module.
Class to define the representation of a vertex for displaying purpose.
Class to build a Node Tree designed to be displayed from a Silhouette View Map structure.
Classes to define a View Map (ViewVertex, ViewEdge, etc.)
Classes to define a Winged Edge data structure.
Class inherited from WingedEdgeBuilder and designed to build a WX (WingedEdge + extended info (silhou...
Class to render a WingedEdge data structure from a polyhedral data structure organized in nodes of a ...
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition btVector3.h:263
void setViewer(AppView *iViewer)
Definition AppCanvas.cpp:43
void setPassZ(float *buf, int width, int height)
Definition AppCanvas.h:68
void setPassDiffuse(float *buf, int width, int height)
Definition AppCanvas.h:62
virtual void init()
Definition AppCanvas.cpp:78
void AddDebug(NodeGroup *iDebug)
Definition AppView.h:130
real GetAspect() const
Definition AppView.h:188
void AddSilhouette(NodeGroup *iSilhouette)
Definition AppView.h:105
void setDebug(NodeGroup *iDebug)
Definition AppView.h:120
void Add2DSilhouette(NodeGroup *)
Definition AppView.h:110
void setModel(NodeGroup *iModel)
Definition AppView.h:78
real GetFovyRadian() const
Definition AppView.h:198
void Add2DVisibleSilhouette(NodeGroup *)
Definition AppView.h:115
void DetachModel(Node *iModel)
Definition AppView.h:135
void DetachSilhouette()
Definition AppView.h:164
void setRenderMonitor(RenderMonitor *iRenderMonitor)
Render * RenderScene(Render *re, bool render)
void setVisible(uint index, bool iVisible)
Definition Canvas.cpp:256
virtual void Draw()
Definition Canvas.cpp:88
void setModified(uint index, bool iMod)
Definition Canvas.cpp:261
void causalStyleModules(std::vector< uint > &vec, uint index=0)
Definition Canvas.cpp:274
void RemoveStyleModule(uint index)
Definition Canvas.cpp:190
void InsertStyleModule(uint index, StyleModule *iStyleModule)
Definition Canvas.cpp:177
void SwapStyleModules(uint i1, uint i2)
Definition Canvas.cpp:226
virtual void Render(const StrokeRenderer *iRenderer)
Definition Canvas.cpp:285
void resetModified(bool iMod=false)
Definition Canvas.cpp:266
void ReplaceStyleModule(uint index, StyleModule *iStyleModule)
Definition Canvas.cpp:239
static const int NB_STEERABLE_VIEWMAP
Definition Canvas.h:63
SteerableViewMap * getSteerableViewMap()
Definition Canvas.h:165
int getStrokeCount() const
Definition Canvas.h:201
const string & getPatternsPath() const
Definition AppConfig.h:54
static Path * getInstance()
Definition AppConfig.cpp:55
const string & getHomeDir() const
Definition AppConfig.h:70
const string & getModelsPath() const
Definition AppConfig.h:50
Render * RenderStrokes(Render *re, bool render)
string getModelsDir() const
void setComputeSuggestiveContoursFlag(bool b)
void setPassZ(float *buf, int width, int height)
bool getFaceSmoothness() const
bool getComputeMaterialBoundariesFlag() const
bool getComputeSteerableViewMapFlag() const
void setComputeMaterialBoundariesFlag(bool b)
void setVisibilityAlgo(int algo)
void AddStyleModule(const char *iFileName)
void setComputeRidgesAndValleysFlag(bool b)
void ReloadStyleModule(uint index, const char *iFileName)
void setFaceSmoothness(bool iBool)
void setPassDiffuse(float *buf, int width, int height)
void setModified(uint index, bool iMod)
void toggleEdgeTesselationNature(Nature::EdgeNature iNature)
void updateCausalStyleModules(uint index)
bool getQuantitativeInvisibility() const
void setModulesDir(const string &dir)
void DeleteViewMap(bool freeCache=false)
int LoadMesh(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
bool getComputeSuggestiveContoursFlag() const
string getModulesDir() const
NodeGroup * BuildRep(vector< ViewEdge * >::iterator vedges_begin, vector< ViewEdge * >::iterator vedges_end)
void setViewMapCache(bool iBool)
void setQuantitativeInvisibility(bool iBool)
void toggleLayer(uint index, bool iDisplay)
void setContext(bContext *C)
void RemoveStyleModule(uint index)
void setComputeSteerableViewMapFlag(bool iBool)
void SwapStyleModules(uint i1, uint i2)
bool getComputeRidgesAndValleysFlag() const
void setView(AppView *iView)
void resetModified(bool iMod=false)
void setRenderMonitor(RenderMonitor *iRenderMonitor)
bool getViewMapCache() const
void displayDensityCurves(int x, int y)
void InsertStyleModule(uint index, const char *iFileName)
void setModelsDir(const string &dir)
void enableMaterialBoundaries(bool b)
virtual void processShapes(WingedEdge &)
void enableSuggestiveContours(bool b)
void setSuggestiveContourKrDerivativeEpsilon(float dkr)
void setCreaseAngle(float angle)
void enableOrthographicProjection(bool b)
void setViewpoint(const Vec3f &ivp)
void setRenderMonitor(RenderMonitor *iRenderMonitor)
void enableRidgesAndValleysFlag(bool b)
virtual void clear()
Definition FastGrid.cpp:19
uint height() const
Definition Image.h:113
uint width() const
Definition Image.h:107
void setDiffuse(float r, float g, float b, float a)
virtual float * getArray()
Definition Image.h:396
void setPixel(uint x, uint y, float v)
Definition Image.h:364
float pixel(uint x, uint y) const
Definition Image.h:369
virtual void reset()=0
void setProjectionMatrix(const double projection_matrix[16])
virtual int numberOfChildren()
Definition NodeGroup.h:56
virtual void AddChild(Node *iChild)
Definition NodeGroup.cpp:16
virtual const BBox< Vec3r > & UpdateBBox()
virtual int destroy()
Definition NodeGroup.cpp:26
virtual void accept(SceneVisitor &v)
Definition NodeGroup.cpp:56
virtual void AddRep(Rep *iRep)
Definition NodeShape.h:39
virtual const BBox< Vec3r > & bbox() const
Definition Node.h:51
virtual void clearBBox()
Definition Node.h:84
double * AddFEdge(FEdge *iFEdge)
float readSteerableViewMapPixel(uint iOrientation, int iLevel, int x, int y)
void buildImagesPyramids(GrayImage **steerableBases, bool copy=false, uint iNbLevels=4, float iSigma=1.0f)
void setTransform(const real iModelViewMatrix[4][4], const real iProjectionMatrix[4][4], const int iViewport[4], real iFocalLength, real, real)
void setGrid(Grid *iGrid)
ViewMap * BuildViewMap(WingedEdge &we, visibility_algo iAlgo, real epsilon, const BBox< Vec3r > &bbox, uint sceneNumFaces)
void setEnableQI(bool iBool)
void setViewpoint(const Vec3r &ivp)
void setFrustum(real iZnear, real iZfar)
void setRenderMonitor(RenderMonitor *iRenderMonitor)
void setFrsMaterial(const FrsMaterial &iMaterial)
void setNature(Nature::EdgeNature iNature)
NodeGroup * Tesselate(ViewMap *iViewMap)
vector< FEdge * > fedges_container
Definition ViewMap.h:53
virtual void Clean()
Definition ViewMap.cpp:55
void setScene3dBBox(const BBox< Vec3r > &bbox)
Definition ViewMap.h:180
fedges_container & FEdges()
Definition ViewMap.h:116
static void setCurrentId(const uint id)
Definition WEdge.h:1104
void setRenderMonitor(RenderMonitor *iRenderMonitor)
local_group_size(16, 16) .push_constant(Type b
#define printf
const Depsgraph * depsgraph
size_t(* MEM_get_peak_memory)(void)
Definition mallocn.cc:65
size_t(* MEM_get_memory_in_use)(void)
Definition mallocn.cc:62
static size_t mem_in_use
#define G(x, y, z)
static const string DIR_SEP("/")
static const string OPTIONS_DIR("."+APPLICATION_NAME)
static const string OPTIONS_CURRENT_DIRS_FILE("current_dirs.xml")
static const string APPLICATION_NAME("APPNAME")
VecMat::Vec2< double > Vec2d
Definition Geom.h:23
VecMat::Vec3< real > Vec3r
Definition Geom.h:30
static const EdgeNature BORDER
Definition Nature.h:42
static const EdgeNature CREASE
Definition Nature.h:44
ushort EdgeNature
Definition Nature.h:36
static const EdgeNature SILHOUETTE
Definition Nature.h:40
inherits from class Rep
Definition AppCanvas.cpp:20
static uint c
Definition RandGen.cpp:87
static uint x[3]
Definition RandGen.cpp:77
double real
Definition Precision.h:14
_W64 unsigned int uintptr_t
Definition stdint.h:119
float proj[4][4]
static void setPatternsPath(const string &path)
static void setBrushesPath(const string &path)
Scene * scene