3DScene.pm 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231
  1. # Implements pure perl packages
  2. #
  3. # Slic3r::GUI::3DScene::Base;
  4. # Slic3r::GUI::3DScene;
  5. #
  6. # Slic3r::GUI::Plater::3D derives from Slic3r::GUI::3DScene,
  7. # Slic3r::GUI::Plater::3DPreview,
  8. # Slic3r::GUI::Plater::ObjectCutDialog and Slic3r::GUI::Plater::ObjectPartsPanel
  9. # own $self->{canvas} of the Slic3r::GUI::3DScene type.
  10. #
  11. # Therefore the 3DScene supports renderng of STLs, extrusions and cutting planes,
  12. # and camera manipulation.
  13. package Slic3r::GUI::3DScene::Base;
  14. use strict;
  15. use warnings;
  16. use Wx qw(wxTheApp :timer :bitmap :icon :dialog);
  17. #==============================================================================================================================
  18. #use Wx::Event qw(EVT_PAINT EVT_SIZE EVT_ERASE_BACKGROUND EVT_IDLE EVT_MOUSEWHEEL EVT_MOUSE_EVENTS EVT_CHAR EVT_TIMER);
  19. # must load OpenGL *before* Wx::GLCanvas
  20. use OpenGL qw(:glconstants :glfunctions :glufunctions :gluconstants);
  21. use base qw(Wx::GLCanvas Class::Accessor);
  22. #==============================================================================================================================
  23. #use Math::Trig qw(asin tan);
  24. #use List::Util qw(reduce min max first);
  25. #use Slic3r::Geometry qw(X Y normalize scale unscale scaled_epsilon);
  26. #use Slic3r::Geometry::Clipper qw(offset_ex intersection_pl JT_ROUND);
  27. #==============================================================================================================================
  28. use Wx::GLCanvas qw(:all);
  29. #==============================================================================================================================
  30. #use Slic3r::Geometry qw(PI);
  31. #==============================================================================================================================
  32. # volumes: reference to vector of Slic3r::GUI::3DScene::Volume.
  33. #==============================================================================================================================
  34. #__PACKAGE__->mk_accessors( qw(_quat _dirty init
  35. # enable_picking
  36. # enable_moving
  37. # use_plain_shader
  38. # on_viewport_changed
  39. # on_hover
  40. # on_select
  41. # on_double_click
  42. # on_right_click
  43. # on_move
  44. # on_model_update
  45. # volumes
  46. # _sphi _stheta
  47. # cutting_plane_z
  48. # cut_lines_vertices
  49. # bed_shape
  50. # bed_triangles
  51. # bed_grid_lines
  52. # bed_polygon
  53. # background
  54. # origin
  55. # _mouse_pos
  56. # _hover_volume_idx
  57. #
  58. # _drag_volume_idx
  59. # _drag_start_pos
  60. # _drag_volume_center_offset
  61. # _drag_start_xy
  62. # _dragged
  63. #
  64. # _layer_height_edited
  65. #
  66. # _camera_type
  67. # _camera_target
  68. # _camera_distance
  69. # _zoom
  70. #
  71. # _legend_enabled
  72. # _warning_enabled
  73. # _apply_zoom_to_volumes_filter
  74. # _mouse_dragging
  75. #
  76. # ) );
  77. #
  78. #use constant TRACKBALLSIZE => 0.8;
  79. #use constant TURNTABLE_MODE => 1;
  80. #use constant GROUND_Z => -0.02;
  81. ## For mesh selection: Not selected - bright yellow.
  82. #use constant DEFAULT_COLOR => [1,1,0];
  83. ## For mesh selection: Selected - bright green.
  84. #use constant SELECTED_COLOR => [0,1,0,1];
  85. ## For mesh selection: Mouse hovers over the object, but object not selected yet - dark green.
  86. #use constant HOVER_COLOR => [0.4,0.9,0,1];
  87. #
  88. ## phi / theta angles to orient the camera.
  89. #use constant VIEW_DEFAULT => [45.0,45.0];
  90. #use constant VIEW_LEFT => [90.0,90.0];
  91. #use constant VIEW_RIGHT => [-90.0,90.0];
  92. #use constant VIEW_TOP => [0.0,0.0];
  93. #use constant VIEW_BOTTOM => [0.0,180.0];
  94. #use constant VIEW_FRONT => [0.0,90.0];
  95. #use constant VIEW_REAR => [180.0,90.0];
  96. #
  97. #use constant MANIPULATION_IDLE => 0;
  98. #use constant MANIPULATION_DRAGGING => 1;
  99. #use constant MANIPULATION_LAYER_HEIGHT => 2;
  100. #
  101. #use constant GIMBALL_LOCK_THETA_MAX => 180;
  102. #
  103. #use constant VARIABLE_LAYER_THICKNESS_BAR_WIDTH => 70;
  104. #use constant VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT => 22;
  105. #
  106. ## make OpenGL::Array thread-safe
  107. #{
  108. # no warnings 'redefine';
  109. # *OpenGL::Array::CLONE_SKIP = sub { 1 };
  110. #}
  111. #==============================================================================================================================
  112. sub new {
  113. my ($class, $parent) = @_;
  114. # We can only enable multi sample anti aliasing wih wxWidgets 3.0.3 and with a hacked Wx::GLCanvas,
  115. # which exports some new WX_GL_XXX constants, namely WX_GL_SAMPLE_BUFFERS and WX_GL_SAMPLES.
  116. my $can_multisample =
  117. ! wxTheApp->{app_config}->get('use_legacy_opengl') &&
  118. Wx::wxVERSION >= 3.000003 &&
  119. defined Wx::GLCanvas->can('WX_GL_SAMPLE_BUFFERS') &&
  120. defined Wx::GLCanvas->can('WX_GL_SAMPLES');
  121. my $attrib = [WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 24];
  122. if ($can_multisample) {
  123. # Request a window with multi sampled anti aliasing. This is a new feature in Wx 3.0.3 (backported from 3.1.0).
  124. # Use eval to avoid compilation, if the subs WX_GL_SAMPLE_BUFFERS and WX_GL_SAMPLES are missing.
  125. eval 'push(@$attrib, (WX_GL_SAMPLE_BUFFERS, 1, WX_GL_SAMPLES, 4));';
  126. }
  127. # wxWidgets expect the attrib list to be ended by zero.
  128. push(@$attrib, 0);
  129. # we request a depth buffer explicitely because it looks like it's not created by
  130. # default on Linux, causing transparency issues
  131. my $self = $class->SUPER::new($parent, -1, Wx::wxDefaultPosition, Wx::wxDefaultSize, 0, "", $attrib);
  132. #==============================================================================================================================
  133. # if (Wx::wxVERSION >= 3.000003) {
  134. # # Wx 3.0.3 contains an ugly hack to support some advanced OpenGL attributes through the attribute list.
  135. # # The attribute list is transferred between the wxGLCanvas and wxGLContext constructors using a single static array s_wglContextAttribs.
  136. # # Immediatelly force creation of the OpenGL context to consume the static variable s_wglContextAttribs.
  137. # $self->GetContext();
  138. # }
  139. #==============================================================================================================================
  140. #==============================================================================================================================
  141. Slic3r::GUI::_3DScene::add_canvas($self);
  142. Slic3r::GUI::_3DScene::allow_multisample($self, $can_multisample);
  143. # my $context = $self->GetContext;
  144. # $self->SetCurrent($context);
  145. # Slic3r::GUI::_3DScene::add_canvas($self, $context);
  146. #
  147. # $self->{can_multisample} = $can_multisample;
  148. # $self->background(1);
  149. # $self->_quat((0, 0, 0, 1));
  150. # $self->_stheta(45);
  151. # $self->_sphi(45);
  152. # $self->_zoom(1);
  153. # $self->_legend_enabled(0);
  154. # $self->_warning_enabled(0);
  155. # $self->use_plain_shader(0);
  156. # $self->_apply_zoom_to_volumes_filter(0);
  157. # $self->_mouse_dragging(0);
  158. #
  159. # # Collection of GLVolume objects
  160. # $self->volumes(Slic3r::GUI::_3DScene::GLVolume::Collection->new);
  161. #
  162. # # 3D point in model space
  163. # $self->_camera_type('ortho');
  164. ## $self->_camera_type('perspective');
  165. # $self->_camera_target(Slic3r::Pointf3->new(0,0,0));
  166. # $self->_camera_distance(0.);
  167. # $self->layer_editing_enabled(0);
  168. # $self->{layer_height_edit_band_width} = 2.;
  169. # $self->{layer_height_edit_strength} = 0.005;
  170. # $self->{layer_height_edit_last_object_id} = -1;
  171. # $self->{layer_height_edit_last_z} = 0.;
  172. # $self->{layer_height_edit_last_action} = 0;
  173. #
  174. # $self->reset_objects;
  175. #
  176. # EVT_PAINT($self, sub {
  177. # my $dc = Wx::PaintDC->new($self);
  178. # $self->Render($dc);
  179. # });
  180. # EVT_SIZE($self, sub { $self->_dirty(1) });
  181. # EVT_IDLE($self, sub {
  182. # return unless $self->_dirty;
  183. # return if !$self->IsShownOnScreen;
  184. # $self->Resize( $self->GetSizeWH );
  185. # $self->Refresh;
  186. # });
  187. # EVT_MOUSEWHEEL($self, \&mouse_wheel_event);
  188. # EVT_MOUSE_EVENTS($self, \&mouse_event);
  189. ## EVT_KEY_DOWN($self, sub {
  190. # EVT_CHAR($self, sub {
  191. # my ($s, $event) = @_;
  192. # if ($event->HasModifiers) {
  193. # $event->Skip;
  194. # } else {
  195. # my $key = $event->GetKeyCode;
  196. # if ($key == ord('0')) {
  197. # $self->select_view('iso');
  198. # } elsif ($key == ord('1')) {
  199. # $self->select_view('top');
  200. # } elsif ($key == ord('2')) {
  201. # $self->select_view('bottom');
  202. # } elsif ($key == ord('3')) {
  203. # $self->select_view('front');
  204. # } elsif ($key == ord('4')) {
  205. # $self->select_view('rear');
  206. # } elsif ($key == ord('5')) {
  207. # $self->select_view('left');
  208. # } elsif ($key == ord('6')) {
  209. # $self->select_view('right');
  210. # } elsif ($key == ord('z')) {
  211. # $self->zoom_to_volumes;
  212. # } elsif ($key == ord('b')) {
  213. # $self->zoom_to_bed;
  214. # } else {
  215. # $event->Skip;
  216. # }
  217. # }
  218. # });
  219. #
  220. # $self->{layer_height_edit_timer_id} = &Wx::NewId();
  221. # $self->{layer_height_edit_timer} = Wx::Timer->new($self, $self->{layer_height_edit_timer_id});
  222. # EVT_TIMER($self, $self->{layer_height_edit_timer_id}, sub {
  223. # my ($self, $event) = @_;
  224. # return if $self->_layer_height_edited != 1;
  225. # $self->_variable_layer_thickness_action(undef);
  226. # });
  227. #==============================================================================================================================
  228. return $self;
  229. }
  230. #==============================================================================================================================
  231. #sub set_legend_enabled {
  232. # my ($self, $value) = @_;
  233. # $self->_legend_enabled($value);
  234. #}
  235. #
  236. #sub set_warning_enabled {
  237. # my ($self, $value) = @_;
  238. # $self->_warning_enabled($value);
  239. #}
  240. #==============================================================================================================================
  241. sub Destroy {
  242. my ($self) = @_;
  243. #==============================================================================================================================
  244. Slic3r::GUI::_3DScene::remove_canvas($self);
  245. # $self->{layer_height_edit_timer}->Stop;
  246. # $self->DestroyGL;
  247. #==============================================================================================================================
  248. return $self->SUPER::Destroy;
  249. }
  250. #==============================================================================================================================
  251. #sub layer_editing_enabled {
  252. # my ($self, $value) = @_;
  253. # if (@_ == 2) {
  254. # $self->{layer_editing_enabled} = $value;
  255. # if ($value) {
  256. # if (! $self->{layer_editing_initialized}) {
  257. # # Enabling the layer editing for the first time. This triggers compilation of the necessary OpenGL shaders.
  258. # # If compilation fails, a message box is shown with the error codes.
  259. # $self->SetCurrent($self->GetContext);
  260. # my $shader = new Slic3r::GUI::_3DScene::GLShader;
  261. # my $error_message;
  262. # if (! $shader->load_from_text($self->_fragment_shader_variable_layer_height, $self->_vertex_shader_variable_layer_height)) {
  263. # # Compilation or linking of the shaders failed.
  264. # $error_message = "Cannot compile an OpenGL Shader, therefore the Variable Layer Editing will be disabled.\n\n"
  265. # . $shader->last_error;
  266. # $shader = undef;
  267. # } else {
  268. # $self->{layer_height_edit_shader} = $shader;
  269. # ($self->{layer_preview_z_texture_id}) = glGenTextures_p(1);
  270. # glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id});
  271. # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  272. # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  273. # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  274. # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  275. # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
  276. # glBindTexture(GL_TEXTURE_2D, 0);
  277. # }
  278. # if (defined($error_message)) {
  279. # # Don't enable the layer editing tool.
  280. # $self->{layer_editing_enabled} = 0;
  281. # # 2 means failed
  282. # $self->{layer_editing_initialized} = 2;
  283. # # Show the error message.
  284. # Wx::MessageBox($error_message, "Slic3r Error", wxOK | wxICON_EXCLAMATION, $self);
  285. # } else {
  286. # $self->{layer_editing_initialized} = 1;
  287. # }
  288. # } elsif ($self->{layer_editing_initialized} == 2) {
  289. # # Initilization failed before. Don't try to initialize and disable layer editing.
  290. # $self->{layer_editing_enabled} = 0;
  291. # }
  292. # }
  293. # }
  294. # return $self->{layer_editing_enabled};
  295. #}
  296. #
  297. #sub layer_editing_allowed {
  298. # my ($self) = @_;
  299. # # Allow layer editing if either the shaders were not initialized yet and we don't know
  300. # # whether it will be possible to initialize them,
  301. # # or if the initialization was done already and it failed.
  302. # return ! (defined($self->{layer_editing_initialized}) && $self->{layer_editing_initialized} == 2);
  303. #}
  304. #
  305. #sub _first_selected_object_id_for_variable_layer_height_editing {
  306. # my ($self) = @_;
  307. # for my $i (0..$#{$self->volumes}) {
  308. # if ($self->volumes->[$i]->selected) {
  309. # my $object_id = int($self->volumes->[$i]->select_group_id / 1000000);
  310. # # Objects with object_id >= 1000 have a specific meaning, for example the wipe tower proxy.
  311. # return ($object_id >= $self->{print}->object_count) ? -1 : $object_id
  312. # if $object_id < 10000;
  313. # }
  314. # }
  315. # return -1;
  316. #}
  317. #
  318. ## Returns an array with (left, top, right, bottom) of the variable layer thickness bar on the screen.
  319. #sub _variable_layer_thickness_bar_rect_screen {
  320. # my ($self) = @_;
  321. # my ($cw, $ch) = $self->GetSizeWH;
  322. # return ($cw - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, 0, $cw, $ch - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT);
  323. #}
  324. #
  325. #sub _variable_layer_thickness_bar_rect_viewport {
  326. # my ($self) = @_;
  327. # my ($cw, $ch) = $self->GetSizeWH;
  328. # return ((0.5*$cw-VARIABLE_LAYER_THICKNESS_BAR_WIDTH)/$self->_zoom, (-0.5*$ch+VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT)/$self->_zoom, $cw/(2*$self->_zoom), $ch/(2*$self->_zoom));
  329. #}
  330. #
  331. ## Returns an array with (left, top, right, bottom) of the variable layer thickness bar on the screen.
  332. #sub _variable_layer_thickness_reset_rect_screen {
  333. # my ($self) = @_;
  334. # my ($cw, $ch) = $self->GetSizeWH;
  335. # return ($cw - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, $ch - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, $cw, $ch);
  336. #}
  337. #
  338. #sub _variable_layer_thickness_reset_rect_viewport {
  339. # my ($self) = @_;
  340. # my ($cw, $ch) = $self->GetSizeWH;
  341. # return ((0.5*$cw-VARIABLE_LAYER_THICKNESS_BAR_WIDTH)/$self->_zoom, -$ch/(2*$self->_zoom), $cw/(2*$self->_zoom), (-0.5*$ch+VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT)/$self->_zoom);
  342. #}
  343. #
  344. #sub _variable_layer_thickness_bar_rect_mouse_inside {
  345. # my ($self, $mouse_evt) = @_;
  346. # my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect_screen;
  347. # return $mouse_evt->GetX >= $bar_left && $mouse_evt->GetX <= $bar_right && $mouse_evt->GetY >= $bar_top && $mouse_evt->GetY <= $bar_bottom;
  348. #}
  349. #
  350. #sub _variable_layer_thickness_reset_rect_mouse_inside {
  351. # my ($self, $mouse_evt) = @_;
  352. # my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_reset_rect_screen;
  353. # return $mouse_evt->GetX >= $bar_left && $mouse_evt->GetX <= $bar_right && $mouse_evt->GetY >= $bar_top && $mouse_evt->GetY <= $bar_bottom;
  354. #}
  355. #
  356. #sub _variable_layer_thickness_bar_mouse_cursor_z_relative {
  357. # my ($self) = @_;
  358. # my $mouse_pos = $self->ScreenToClientPoint(Wx::GetMousePosition());
  359. # my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect_screen;
  360. # return ($mouse_pos->x >= $bar_left && $mouse_pos->x <= $bar_right && $mouse_pos->y >= $bar_top && $mouse_pos->y <= $bar_bottom) ?
  361. # # Inside the bar.
  362. # ($bar_bottom - $mouse_pos->y - 1.) / ($bar_bottom - $bar_top - 1) :
  363. # # Outside the bar.
  364. # -1000.;
  365. #}
  366. #
  367. #sub _variable_layer_thickness_action {
  368. # my ($self, $mouse_event, $do_modification) = @_;
  369. # # A volume is selected. Test, whether hovering over a layer thickness bar.
  370. # return if $self->{layer_height_edit_last_object_id} == -1;
  371. # if (defined($mouse_event)) {
  372. # my ($bar_left, $bar_top, $bar_right, $bar_bottom) = $self->_variable_layer_thickness_bar_rect_screen;
  373. # $self->{layer_height_edit_last_z} = unscale($self->{print}->get_object($self->{layer_height_edit_last_object_id})->size->z)
  374. # * ($bar_bottom - $mouse_event->GetY - 1.) / ($bar_bottom - $bar_top);
  375. # $self->{layer_height_edit_last_action} = $mouse_event->ShiftDown ? ($mouse_event->RightIsDown ? 3 : 2) : ($mouse_event->RightIsDown ? 0 : 1);
  376. # }
  377. # # Mark the volume as modified, so Print will pick its layer height profile? Where to mark it?
  378. # # Start a timer to refresh the print? schedule_background_process() ?
  379. # # The PrintObject::adjust_layer_height_profile() call adjusts the profile of its associated ModelObject, it does not modify the profile of the PrintObject itself.
  380. # $self->{print}->get_object($self->{layer_height_edit_last_object_id})->adjust_layer_height_profile(
  381. # $self->{layer_height_edit_last_z},
  382. # $self->{layer_height_edit_strength},
  383. # $self->{layer_height_edit_band_width},
  384. # $self->{layer_height_edit_last_action});
  385. #
  386. # $self->volumes->[$self->{layer_height_edit_last_object_id}]->generate_layer_height_texture(
  387. # $self->{print}->get_object($self->{layer_height_edit_last_object_id}), 1);
  388. # $self->Refresh;
  389. # # Automatic action on mouse down with the same coordinate.
  390. # $self->{layer_height_edit_timer}->Start(100, wxTIMER_CONTINUOUS);
  391. #}
  392. #
  393. #sub mouse_event {
  394. # my ($self, $e) = @_;
  395. #
  396. # my $pos = Slic3r::Pointf->new($e->GetPositionXY);
  397. # my $object_idx_selected = $self->{layer_height_edit_last_object_id} = ($self->layer_editing_enabled && $self->{print}) ? $self->_first_selected_object_id_for_variable_layer_height_editing : -1;
  398. #
  399. # $self->_mouse_dragging($e->Dragging);
  400. #
  401. # if ($e->Entering && (&Wx::wxMSW || $^O eq 'linux')) {
  402. # # wxMSW needs focus in order to catch mouse wheel events
  403. # $self->SetFocus;
  404. # $self->_drag_start_xy(undef);
  405. # } elsif ($e->LeftDClick) {
  406. # if ($object_idx_selected != -1 && $self->_variable_layer_thickness_bar_rect_mouse_inside($e)) {
  407. # } elsif ($self->on_double_click) {
  408. # $self->on_double_click->();
  409. # }
  410. # } elsif ($e->LeftDown || $e->RightDown) {
  411. # # If user pressed left or right button we first check whether this happened
  412. # # on a volume or not.
  413. # my $volume_idx = $self->_hover_volume_idx // -1;
  414. # $self->_layer_height_edited(0);
  415. # if ($object_idx_selected != -1 && $self->_variable_layer_thickness_bar_rect_mouse_inside($e)) {
  416. # # A volume is selected and the mouse is hovering over a layer thickness bar.
  417. # # Start editing the layer height.
  418. # $self->_layer_height_edited(1);
  419. # $self->_variable_layer_thickness_action($e);
  420. # } elsif ($object_idx_selected != -1 && $self->_variable_layer_thickness_reset_rect_mouse_inside($e)) {
  421. # $self->{print}->get_object($object_idx_selected)->reset_layer_height_profile;
  422. # # Index 2 means no editing, just wait for mouse up event.
  423. # $self->_layer_height_edited(2);
  424. # $self->Refresh;
  425. # $self->Update;
  426. # } else {
  427. # # The mouse_to_3d gets the Z coordinate from the Z buffer at the screen coordinate $pos->x,y,
  428. # # an converts the screen space coordinate to unscaled object space.
  429. # my $pos3d = ($volume_idx == -1) ? undef : $self->mouse_to_3d(@$pos);
  430. #
  431. # # Select volume in this 3D canvas.
  432. # # Don't deselect a volume if layer editing is enabled. We want the object to stay selected
  433. # # during the scene manipulation.
  434. #
  435. # if ($self->enable_picking && ($volume_idx != -1 || ! $self->layer_editing_enabled)) {
  436. # $self->deselect_volumes;
  437. # $self->select_volume($volume_idx);
  438. #
  439. # if ($volume_idx != -1) {
  440. # my $group_id = $self->volumes->[$volume_idx]->select_group_id;
  441. # my @volumes;
  442. # if ($group_id != -1) {
  443. # $self->select_volume($_)
  444. # for grep $self->volumes->[$_]->select_group_id == $group_id,
  445. # 0..$#{$self->volumes};
  446. # }
  447. # }
  448. #
  449. # $self->Refresh;
  450. # $self->Update;
  451. # }
  452. #
  453. # # propagate event through callback
  454. # $self->on_select->($volume_idx)
  455. # if $self->on_select;
  456. #
  457. # if ($volume_idx != -1) {
  458. # if ($e->LeftDown && $self->enable_moving) {
  459. # # Only accept the initial position, if it is inside the volume bounding box.
  460. # my $volume_bbox = $self->volumes->[$volume_idx]->transformed_bounding_box;
  461. # $volume_bbox->offset(1.);
  462. # if ($volume_bbox->contains_point($pos3d)) {
  463. # # The dragging operation is initiated.
  464. # $self->_drag_volume_idx($volume_idx);
  465. # $self->_drag_start_pos($pos3d);
  466. # # Remember the shift to to the object center. The object center will later be used
  467. # # to limit the object placement close to the bed.
  468. # $self->_drag_volume_center_offset($pos3d->vector_to($volume_bbox->center));
  469. # }
  470. # } elsif ($e->RightDown) {
  471. # # if right clicking on volume, propagate event through callback
  472. # $self->on_right_click->($e->GetPosition)
  473. # if $self->on_right_click;
  474. # }
  475. # }
  476. # }
  477. # } elsif ($e->Dragging && $e->LeftIsDown && ! $self->_layer_height_edited && defined($self->_drag_volume_idx)) {
  478. # # Get new position at the same Z of the initial click point.
  479. # my $cur_pos = Slic3r::Linef3->new(
  480. # $self->mouse_to_3d($e->GetX, $e->GetY, 0),
  481. # $self->mouse_to_3d($e->GetX, $e->GetY, 1))
  482. # ->intersect_plane($self->_drag_start_pos->z);
  483. #
  484. # # Clip the new position, so the object center remains close to the bed.
  485. # {
  486. # $cur_pos->translate(@{$self->_drag_volume_center_offset});
  487. # my $cur_pos2 = Slic3r::Point->new(scale($cur_pos->x), scale($cur_pos->y));
  488. # if (! $self->bed_polygon->contains_point($cur_pos2)) {
  489. # my $ip = $self->bed_polygon->point_projection($cur_pos2);
  490. # $cur_pos->set_x(unscale($ip->x));
  491. # $cur_pos->set_y(unscale($ip->y));
  492. # }
  493. # $cur_pos->translate(@{$self->_drag_volume_center_offset->negative});
  494. # }
  495. # # Calculate the translation vector.
  496. # my $vector = $self->_drag_start_pos->vector_to($cur_pos);
  497. # # Get the volume being dragged.
  498. # my $volume = $self->volumes->[$self->_drag_volume_idx];
  499. # # Get all volumes belonging to the same group, if any.
  500. # my @volumes = ($volume->drag_group_id == -1) ?
  501. # ($volume) :
  502. # grep $_->drag_group_id == $volume->drag_group_id, @{$self->volumes};
  503. # # Apply new temporary volume origin and ignore Z.
  504. # $_->translate($vector->x, $vector->y, 0) for @volumes;
  505. # $self->_drag_start_pos($cur_pos);
  506. # $self->_dragged(1);
  507. # $self->Refresh;
  508. # $self->Update;
  509. # } elsif ($e->Dragging) {
  510. # if ($self->_layer_height_edited && $object_idx_selected != -1) {
  511. # $self->_variable_layer_thickness_action($e) if ($self->_layer_height_edited == 1);
  512. # } elsif ($e->LeftIsDown) {
  513. # # if dragging over blank area with left button, rotate
  514. # if (defined $self->_drag_start_pos) {
  515. # my $orig = $self->_drag_start_pos;
  516. # if (TURNTABLE_MODE) {
  517. # # Turntable mode is enabled by default.
  518. # $self->_sphi($self->_sphi + ($pos->x - $orig->x) * TRACKBALLSIZE);
  519. # $self->_stheta($self->_stheta - ($pos->y - $orig->y) * TRACKBALLSIZE); #-
  520. # $self->_stheta(GIMBALL_LOCK_THETA_MAX) if $self->_stheta > GIMBALL_LOCK_THETA_MAX;
  521. # $self->_stheta(0) if $self->_stheta < 0;
  522. # } else {
  523. # my $size = $self->GetClientSize;
  524. # my @quat = trackball(
  525. # $orig->x / ($size->width / 2) - 1,
  526. # 1 - $orig->y / ($size->height / 2), #/
  527. # $pos->x / ($size->width / 2) - 1,
  528. # 1 - $pos->y / ($size->height / 2), #/
  529. # );
  530. # $self->_quat(mulquats($self->_quat, \@quat));
  531. # }
  532. # $self->on_viewport_changed->() if $self->on_viewport_changed;
  533. # $self->Refresh;
  534. # $self->Update;
  535. # }
  536. # $self->_drag_start_pos($pos);
  537. # } elsif ($e->MiddleIsDown || $e->RightIsDown) {
  538. # # If dragging over blank area with right button, pan.
  539. # if (defined $self->_drag_start_xy) {
  540. # # get point in model space at Z = 0
  541. # my $cur_pos = $self->mouse_to_3d($e->GetX, $e->GetY, 0);
  542. # my $orig = $self->mouse_to_3d($self->_drag_start_xy->x, $self->_drag_start_xy->y, 0);
  543. # $self->_camera_target->translate(@{$orig->vector_to($cur_pos)->negative});
  544. # $self->on_viewport_changed->() if $self->on_viewport_changed;
  545. # $self->Refresh;
  546. # $self->Update;
  547. # }
  548. # $self->_drag_start_xy($pos);
  549. # }
  550. # } elsif ($e->LeftUp || $e->MiddleUp || $e->RightUp) {
  551. # if ($self->_layer_height_edited) {
  552. # $self->_layer_height_edited(undef);
  553. # $self->{layer_height_edit_timer}->Stop;
  554. # $self->on_model_update->()
  555. # if ($object_idx_selected != -1 && $self->on_model_update);
  556. # } elsif ($self->on_move && defined($self->_drag_volume_idx) && $self->_dragged) {
  557. # # get all volumes belonging to the same group, if any
  558. # my @volume_idxs;
  559. # my $group_id = $self->volumes->[$self->_drag_volume_idx]->drag_group_id;
  560. # if ($group_id == -1) {
  561. # @volume_idxs = ($self->_drag_volume_idx);
  562. # } else {
  563. # @volume_idxs = grep $self->volumes->[$_]->drag_group_id == $group_id,
  564. # 0..$#{$self->volumes};
  565. # }
  566. # $self->on_move->(@volume_idxs);
  567. # }
  568. # $self->_drag_volume_idx(undef);
  569. # $self->_drag_start_pos(undef);
  570. # $self->_drag_start_xy(undef);
  571. # $self->_dragged(undef);
  572. # } elsif ($e->Moving) {
  573. # $self->_mouse_pos($pos);
  574. # # Only refresh if picking is enabled, in that case the objects may get highlighted if the mouse cursor
  575. # # hovers over.
  576. # if ($self->enable_picking) {
  577. # $self->Update;
  578. # $self->Refresh;
  579. # }
  580. # } else {
  581. # $e->Skip();
  582. # }
  583. #}
  584. #
  585. #sub mouse_wheel_event {
  586. # my ($self, $e) = @_;
  587. #
  588. # if ($e->MiddleIsDown) {
  589. # # Ignore the wheel events if the middle button is pressed.
  590. # return;
  591. # }
  592. # if ($self->layer_editing_enabled && $self->{print}) {
  593. # my $object_idx_selected = $self->_first_selected_object_id_for_variable_layer_height_editing;
  594. # if ($object_idx_selected != -1) {
  595. # # A volume is selected. Test, whether hovering over a layer thickness bar.
  596. # if ($self->_variable_layer_thickness_bar_rect_mouse_inside($e)) {
  597. # # Adjust the width of the selection.
  598. # $self->{layer_height_edit_band_width} = max(min($self->{layer_height_edit_band_width} * (1 + 0.1 * $e->GetWheelRotation() / $e->GetWheelDelta()), 10.), 1.5);
  599. # $self->Refresh;
  600. # return;
  601. # }
  602. # }
  603. # }
  604. #
  605. # # Calculate the zoom delta and apply it to the current zoom factor
  606. # my $zoom = $e->GetWheelRotation() / $e->GetWheelDelta();
  607. # $zoom = max(min($zoom, 4), -4);
  608. # $zoom /= 10;
  609. # $zoom = $self->_zoom / (1-$zoom);
  610. # # Don't allow to zoom too far outside the scene.
  611. # my $zoom_min = $self->get_zoom_to_bounding_box_factor($self->max_bounding_box);
  612. # $zoom_min *= 0.4 if defined $zoom_min;
  613. # $zoom = $zoom_min if defined $zoom_min && $zoom < $zoom_min;
  614. # $self->_zoom($zoom);
  615. #
  616. ## # In order to zoom around the mouse point we need to translate
  617. ## # the camera target
  618. ## my $size = Slic3r::Pointf->new($self->GetSizeWH);
  619. ## my $pos = Slic3r::Pointf->new($e->GetX, $size->y - $e->GetY); #-
  620. ## $self->_camera_target->translate(
  621. ## # ($pos - $size/2) represents the vector from the viewport center
  622. ## # to the mouse point. By multiplying it by $zoom we get the new,
  623. ## # transformed, length of such vector.
  624. ## # Since we want that point to stay fixed, we move our camera target
  625. ## # in the opposite direction by the delta of the length of such vector
  626. ## # ($zoom - 1). We then scale everything by 1/$self->_zoom since
  627. ## # $self->_camera_target is expressed in terms of model units.
  628. ## -($pos->x - $size->x/2) * ($zoom) / $self->_zoom,
  629. ## -($pos->y - $size->y/2) * ($zoom) / $self->_zoom,
  630. ## 0,
  631. ## ) if 0;
  632. #
  633. # $self->on_viewport_changed->() if $self->on_viewport_changed;
  634. # $self->Resize($self->GetSizeWH) if $self->IsShownOnScreen;
  635. # $self->Refresh;
  636. #}
  637. #
  638. ## Reset selection.
  639. #sub reset_objects {
  640. # my ($self) = @_;
  641. # if ($self->GetContext) {
  642. # $self->SetCurrent($self->GetContext);
  643. # $self->volumes->release_geometry;
  644. # }
  645. # $self->volumes->erase;
  646. # $self->_dirty(1);
  647. #}
  648. #
  649. ## Setup camera to view all objects.
  650. #sub set_viewport_from_scene {
  651. # my ($self, $scene) = @_;
  652. #
  653. # $self->_sphi($scene->_sphi);
  654. # $self->_stheta($scene->_stheta);
  655. # $self->_camera_target($scene->_camera_target);
  656. # $self->_zoom($scene->_zoom);
  657. # $self->_quat($scene->_quat);
  658. # $self->_dirty(1);
  659. #}
  660. #
  661. ## Set the camera to a default orientation,
  662. ## zoom to volumes.
  663. #sub select_view {
  664. # my ($self, $direction) = @_;
  665. #
  666. # my $dirvec;
  667. # if (ref($direction)) {
  668. # $dirvec = $direction;
  669. # } else {
  670. # if ($direction eq 'iso') {
  671. # $dirvec = VIEW_DEFAULT;
  672. # } elsif ($direction eq 'left') {
  673. # $dirvec = VIEW_LEFT;
  674. # } elsif ($direction eq 'right') {
  675. # $dirvec = VIEW_RIGHT;
  676. # } elsif ($direction eq 'top') {
  677. # $dirvec = VIEW_TOP;
  678. # } elsif ($direction eq 'bottom') {
  679. # $dirvec = VIEW_BOTTOM;
  680. # } elsif ($direction eq 'front') {
  681. # $dirvec = VIEW_FRONT;
  682. # } elsif ($direction eq 'rear') {
  683. # $dirvec = VIEW_REAR;
  684. # }
  685. # }
  686. # my $bb = $self->volumes_bounding_box;
  687. # if (! $bb->empty) {
  688. # $self->_sphi($dirvec->[0]);
  689. # $self->_stheta($dirvec->[1]);
  690. # # Avoid gimball lock.
  691. # $self->_stheta(GIMBALL_LOCK_THETA_MAX) if $self->_stheta > GIMBALL_LOCK_THETA_MAX;
  692. # $self->_stheta(0) if $self->_stheta < 0;
  693. # $self->on_viewport_changed->() if $self->on_viewport_changed;
  694. # $self->Refresh;
  695. # }
  696. #}
  697. #
  698. #sub get_zoom_to_bounding_box_factor {
  699. # my ($self, $bb) = @_;
  700. # my $max_bb_size = max(@{ $bb->size });
  701. # return undef if ($max_bb_size == 0);
  702. #
  703. # # project the bbox vertices on a plane perpendicular to the camera forward axis
  704. # # then calculates the vertices coordinate on this plane along the camera xy axes
  705. #
  706. # # we need the view matrix, we let opengl calculate it (same as done in render sub)
  707. # glMatrixMode(GL_MODELVIEW);
  708. # glLoadIdentity();
  709. #
  710. # if (!TURNTABLE_MODE) {
  711. # # Shift the perspective camera.
  712. # my $camera_pos = Slic3r::Pointf3->new(0,0,-$self->_camera_distance);
  713. # glTranslatef(@$camera_pos);
  714. # }
  715. #
  716. # if (TURNTABLE_MODE) {
  717. # # Turntable mode is enabled by default.
  718. # glRotatef(-$self->_stheta, 1, 0, 0); # pitch
  719. # glRotatef($self->_sphi, 0, 0, 1); # yaw
  720. # } else {
  721. # # Shift the perspective camera.
  722. # my $camera_pos = Slic3r::Pointf3->new(0,0,-$self->_camera_distance);
  723. # glTranslatef(@$camera_pos);
  724. # my @rotmat = quat_to_rotmatrix($self->quat);
  725. # glMultMatrixd_p(@rotmat[0..15]);
  726. # }
  727. # glTranslatef(@{ $self->_camera_target->negative });
  728. #
  729. # # get the view matrix back from opengl
  730. # my @matrix = glGetFloatv_p(GL_MODELVIEW_MATRIX);
  731. #
  732. # # camera axes
  733. # my $right = Slic3r::Pointf3->new($matrix[0], $matrix[4], $matrix[8]);
  734. # my $up = Slic3r::Pointf3->new($matrix[1], $matrix[5], $matrix[9]);
  735. # my $forward = Slic3r::Pointf3->new($matrix[2], $matrix[6], $matrix[10]);
  736. #
  737. # my $bb_min = $bb->min_point();
  738. # my $bb_max = $bb->max_point();
  739. # my $bb_center = $bb->center();
  740. #
  741. # # bbox vertices in world space
  742. # my @vertices = ();
  743. # push(@vertices, $bb_min);
  744. # push(@vertices, Slic3r::Pointf3->new($bb_max->x(), $bb_min->y(), $bb_min->z()));
  745. # push(@vertices, Slic3r::Pointf3->new($bb_max->x(), $bb_max->y(), $bb_min->z()));
  746. # push(@vertices, Slic3r::Pointf3->new($bb_min->x(), $bb_max->y(), $bb_min->z()));
  747. # push(@vertices, Slic3r::Pointf3->new($bb_min->x(), $bb_min->y(), $bb_max->z()));
  748. # push(@vertices, Slic3r::Pointf3->new($bb_max->x(), $bb_min->y(), $bb_max->z()));
  749. # push(@vertices, $bb_max);
  750. # push(@vertices, Slic3r::Pointf3->new($bb_min->x(), $bb_max->y(), $bb_max->z()));
  751. #
  752. # my $max_x = 0.0;
  753. # my $max_y = 0.0;
  754. #
  755. # # margin factor to give some empty space around the bbox
  756. # my $margin_factor = 1.25;
  757. #
  758. # foreach my $v (@vertices) {
  759. # # project vertex on the plane perpendicular to camera forward axis
  760. # my $pos = Slic3r::Pointf3->new($v->x() - $bb_center->x(), $v->y() - $bb_center->y(), $v->z() - $bb_center->z());
  761. # my $proj_on_normal = $pos->x() * $forward->x() + $pos->y() * $forward->y() + $pos->z() * $forward->z();
  762. # my $proj_on_plane = Slic3r::Pointf3->new($pos->x() - $proj_on_normal * $forward->x(), $pos->y() - $proj_on_normal * $forward->y(), $pos->z() - $proj_on_normal * $forward->z());
  763. #
  764. # # calculates vertex coordinate along camera xy axes
  765. # my $x_on_plane = $proj_on_plane->x() * $right->x() + $proj_on_plane->y() * $right->y() + $proj_on_plane->z() * $right->z();
  766. # my $y_on_plane = $proj_on_plane->x() * $up->x() + $proj_on_plane->y() * $up->y() + $proj_on_plane->z() * $up->z();
  767. #
  768. # $max_x = max($max_x, $margin_factor * 2 * abs($x_on_plane));
  769. # $max_y = max($max_y, $margin_factor * 2 * abs($y_on_plane));
  770. # }
  771. #
  772. # return undef if (($max_x == 0) || ($max_y == 0));
  773. #
  774. # my ($cw, $ch) = $self->GetSizeWH;
  775. # my $min_ratio = min($cw / $max_x, $ch / $max_y);
  776. #
  777. # return $min_ratio;
  778. #}
  779. #
  780. #sub zoom_to_bounding_box {
  781. # my ($self, $bb) = @_;
  782. # # Calculate the zoom factor needed to adjust viewport to bounding box.
  783. # my $zoom = $self->get_zoom_to_bounding_box_factor($bb);
  784. # if (defined $zoom) {
  785. # $self->_zoom($zoom);
  786. # # center view around bounding box center
  787. # $self->_camera_target($bb->center);
  788. # $self->on_viewport_changed->() if $self->on_viewport_changed;
  789. # $self->Resize($self->GetSizeWH) if $self->IsShownOnScreen;
  790. # $self->Refresh;
  791. # }
  792. #}
  793. #
  794. #sub zoom_to_bed {
  795. # my ($self) = @_;
  796. #
  797. # if ($self->bed_shape) {
  798. # $self->zoom_to_bounding_box($self->bed_bounding_box);
  799. # }
  800. #}
  801. #
  802. #sub zoom_to_volume {
  803. # my ($self, $volume_idx) = @_;
  804. #
  805. # my $volume = $self->volumes->[$volume_idx];
  806. # my $bb = $volume->transformed_bounding_box;
  807. # $self->zoom_to_bounding_box($bb);
  808. #}
  809. #
  810. #sub zoom_to_volumes {
  811. # my ($self) = @_;
  812. #
  813. # $self->_apply_zoom_to_volumes_filter(1);
  814. # $self->zoom_to_bounding_box($self->volumes_bounding_box);
  815. # $self->_apply_zoom_to_volumes_filter(0);
  816. #}
  817. #
  818. #sub volumes_bounding_box {
  819. # my ($self) = @_;
  820. #
  821. # my $bb = Slic3r::Geometry::BoundingBoxf3->new;
  822. # foreach my $v (@{$self->volumes}) {
  823. # $bb->merge($v->transformed_bounding_box) if (! $self->_apply_zoom_to_volumes_filter || $v->zoom_to_volumes);
  824. # }
  825. # return $bb;
  826. #}
  827. #
  828. #sub bed_bounding_box {
  829. # my ($self) = @_;
  830. #
  831. # my $bb = Slic3r::Geometry::BoundingBoxf3->new;
  832. # if ($self->bed_shape) {
  833. # $bb->merge_point(Slic3r::Pointf3->new(@$_, 0)) for @{$self->bed_shape};
  834. # }
  835. # return $bb;
  836. #}
  837. #
  838. #sub max_bounding_box {
  839. # my ($self) = @_;
  840. #
  841. # my $bb = $self->bed_bounding_box;
  842. # $bb->merge($self->volumes_bounding_box);
  843. # return $bb;
  844. #}
  845. #
  846. ## Used by ObjectCutDialog and ObjectPartsPanel to generate a rectangular ground plane
  847. ## to support the scene objects.
  848. #sub set_auto_bed_shape {
  849. # my ($self, $bed_shape) = @_;
  850. #
  851. # # draw a default square bed around object center
  852. # my $max_size = max(@{ $self->volumes_bounding_box->size });
  853. # my $center = $self->volumes_bounding_box->center;
  854. # $self->set_bed_shape([
  855. # [ $center->x - $max_size, $center->y - $max_size ], #--
  856. # [ $center->x + $max_size, $center->y - $max_size ], #--
  857. # [ $center->x + $max_size, $center->y + $max_size ], #++
  858. # [ $center->x - $max_size, $center->y + $max_size ], #++
  859. # ]);
  860. # # Set the origin for painting of the coordinate system axes.
  861. # $self->origin(Slic3r::Pointf->new(@$center[X,Y]));
  862. #}
  863. #
  864. ## Set the bed shape to a single closed 2D polygon (array of two element arrays),
  865. ## triangulate the bed and store the triangles into $self->bed_triangles,
  866. ## fills the $self->bed_grid_lines and sets $self->origin.
  867. ## Sets $self->bed_polygon to limit the object placement.
  868. #sub set_bed_shape {
  869. # my ($self, $bed_shape) = @_;
  870. #
  871. # $self->bed_shape($bed_shape);
  872. #
  873. # # triangulate bed
  874. # my $expolygon = Slic3r::ExPolygon->new([ map [map scale($_), @$_], @$bed_shape ]);
  875. # my $bed_bb = $expolygon->bounding_box;
  876. #
  877. # {
  878. # my @points = ();
  879. # foreach my $triangle (@{ $expolygon->triangulate }) {
  880. # push @points, map {+ unscale($_->x), unscale($_->y), GROUND_Z } @$triangle;
  881. # }
  882. # $self->bed_triangles(OpenGL::Array->new_list(GL_FLOAT, @points));
  883. # }
  884. #
  885. # {
  886. # my @polylines = ();
  887. # for (my $x = $bed_bb->x_min; $x <= $bed_bb->x_max; $x += scale 10) {
  888. # push @polylines, Slic3r::Polyline->new([$x,$bed_bb->y_min], [$x,$bed_bb->y_max]);
  889. # }
  890. # for (my $y = $bed_bb->y_min; $y <= $bed_bb->y_max; $y += scale 10) {
  891. # push @polylines, Slic3r::Polyline->new([$bed_bb->x_min,$y], [$bed_bb->x_max,$y]);
  892. # }
  893. # # clip with a slightly grown expolygon because our lines lay on the contours and
  894. # # may get erroneously clipped
  895. # my @lines = map Slic3r::Line->new(@$_[0,-1]),
  896. # @{intersection_pl(\@polylines, [ @{$expolygon->offset(+scaled_epsilon)} ])};
  897. #
  898. # # append bed contours
  899. # push @lines, map @{$_->lines}, @$expolygon;
  900. #
  901. # my @points = ();
  902. # foreach my $line (@lines) {
  903. # push @points, map {+ unscale($_->x), unscale($_->y), GROUND_Z } @$line; #))
  904. # }
  905. # $self->bed_grid_lines(OpenGL::Array->new_list(GL_FLOAT, @points));
  906. # }
  907. #
  908. # # Set the origin for painting of the coordinate system axes.
  909. # $self->origin(Slic3r::Pointf->new(0,0));
  910. #
  911. # $self->bed_polygon(offset_ex([$expolygon->contour], $bed_bb->radius * 1.7, JT_ROUND, scale(0.5))->[0]->contour->clone);
  912. #}
  913. #
  914. #sub deselect_volumes {
  915. # my ($self) = @_;
  916. # $_->set_selected(0) for @{$self->volumes};
  917. #}
  918. #
  919. #sub select_volume {
  920. # my ($self, $volume_idx) = @_;
  921. #
  922. # return if ($volume_idx >= scalar(@{$self->volumes}));
  923. #
  924. # $self->volumes->[$volume_idx]->set_selected(1)
  925. # if $volume_idx != -1;
  926. #}
  927. #
  928. #sub SetCuttingPlane {
  929. # my ($self, $z, $expolygons) = @_;
  930. #
  931. # $self->cutting_plane_z($z);
  932. #
  933. # # grow slices in order to display them better
  934. # $expolygons = offset_ex([ map @$_, @$expolygons ], scale 0.1);
  935. #
  936. # my @verts = ();
  937. # foreach my $line (map @{$_->lines}, map @$_, @$expolygons) {
  938. # push @verts, (
  939. # unscale($line->a->x), unscale($line->a->y), $z, #))
  940. # unscale($line->b->x), unscale($line->b->y), $z, #))
  941. # );
  942. # }
  943. # $self->cut_lines_vertices(OpenGL::Array->new_list(GL_FLOAT, @verts));
  944. #}
  945. #
  946. ## Given an axis and angle, compute quaternion.
  947. #sub axis_to_quat {
  948. # my ($ax, $phi) = @_;
  949. #
  950. # my $lena = sqrt(reduce { $a + $b } (map { $_ * $_ } @$ax));
  951. # my @q = map { $_ * (1 / $lena) } @$ax;
  952. # @q = map { $_ * sin($phi / 2.0) } @q;
  953. # $q[$#q + 1] = cos($phi / 2.0);
  954. # return @q;
  955. #}
  956. #
  957. ## Project a point on the virtual trackball.
  958. ## If it is inside the sphere, map it to the sphere, if it outside map it
  959. ## to a hyperbola.
  960. #sub project_to_sphere {
  961. # my ($r, $x, $y) = @_;
  962. #
  963. # my $d = sqrt($x * $x + $y * $y);
  964. # if ($d < $r * 0.70710678118654752440) { # Inside sphere
  965. # return sqrt($r * $r - $d * $d);
  966. # } else { # On hyperbola
  967. # my $t = $r / 1.41421356237309504880;
  968. # return $t * $t / $d;
  969. # }
  970. #}
  971. #
  972. #sub cross {
  973. # my ($v1, $v2) = @_;
  974. #
  975. # return (@$v1[1] * @$v2[2] - @$v1[2] * @$v2[1],
  976. # @$v1[2] * @$v2[0] - @$v1[0] * @$v2[2],
  977. # @$v1[0] * @$v2[1] - @$v1[1] * @$v2[0]);
  978. #}
  979. #
  980. ## Simulate a track-ball. Project the points onto the virtual trackball,
  981. ## then figure out the axis of rotation, which is the cross product of
  982. ## P1 P2 and O P1 (O is the center of the ball, 0,0,0) Note: This is a
  983. ## deformed trackball-- is a trackball in the center, but is deformed
  984. ## into a hyperbolic sheet of rotation away from the center.
  985. ## It is assumed that the arguments to this routine are in the range
  986. ## (-1.0 ... 1.0).
  987. #sub trackball {
  988. # my ($p1x, $p1y, $p2x, $p2y) = @_;
  989. #
  990. # if ($p1x == $p2x && $p1y == $p2y) {
  991. # # zero rotation
  992. # return (0.0, 0.0, 0.0, 1.0);
  993. # }
  994. #
  995. # # First, figure out z-coordinates for projection of P1 and P2 to
  996. # # deformed sphere
  997. # my @p1 = ($p1x, $p1y, project_to_sphere(TRACKBALLSIZE, $p1x, $p1y));
  998. # my @p2 = ($p2x, $p2y, project_to_sphere(TRACKBALLSIZE, $p2x, $p2y));
  999. #
  1000. # # axis of rotation (cross product of P1 and P2)
  1001. # my @a = cross(\@p2, \@p1);
  1002. #
  1003. # # Figure out how much to rotate around that axis.
  1004. # my @d = map { $_ * $_ } (map { $p1[$_] - $p2[$_] } 0 .. $#p1);
  1005. # my $t = sqrt(reduce { $a + $b } @d) / (2.0 * TRACKBALLSIZE);
  1006. #
  1007. # # Avoid problems with out-of-control values...
  1008. # $t = 1.0 if ($t > 1.0);
  1009. # $t = -1.0 if ($t < -1.0);
  1010. # my $phi = 2.0 * asin($t);
  1011. #
  1012. # return axis_to_quat(\@a, $phi);
  1013. #}
  1014. #
  1015. ## Build a rotation matrix, given a quaternion rotation.
  1016. #sub quat_to_rotmatrix {
  1017. # my ($q) = @_;
  1018. #
  1019. # my @m = ();
  1020. #
  1021. # $m[0] = 1.0 - 2.0 * (@$q[1] * @$q[1] + @$q[2] * @$q[2]);
  1022. # $m[1] = 2.0 * (@$q[0] * @$q[1] - @$q[2] * @$q[3]);
  1023. # $m[2] = 2.0 * (@$q[2] * @$q[0] + @$q[1] * @$q[3]);
  1024. # $m[3] = 0.0;
  1025. #
  1026. # $m[4] = 2.0 * (@$q[0] * @$q[1] + @$q[2] * @$q[3]);
  1027. # $m[5] = 1.0 - 2.0 * (@$q[2] * @$q[2] + @$q[0] * @$q[0]);
  1028. # $m[6] = 2.0 * (@$q[1] * @$q[2] - @$q[0] * @$q[3]);
  1029. # $m[7] = 0.0;
  1030. #
  1031. # $m[8] = 2.0 * (@$q[2] * @$q[0] - @$q[1] * @$q[3]);
  1032. # $m[9] = 2.0 * (@$q[1] * @$q[2] + @$q[0] * @$q[3]);
  1033. # $m[10] = 1.0 - 2.0 * (@$q[1] * @$q[1] + @$q[0] * @$q[0]);
  1034. # $m[11] = 0.0;
  1035. #
  1036. # $m[12] = 0.0;
  1037. # $m[13] = 0.0;
  1038. # $m[14] = 0.0;
  1039. # $m[15] = 1.0;
  1040. #
  1041. # return @m;
  1042. #}
  1043. #
  1044. #sub mulquats {
  1045. # my ($q1, $rq) = @_;
  1046. #
  1047. # return (@$q1[3] * @$rq[0] + @$q1[0] * @$rq[3] + @$q1[1] * @$rq[2] - @$q1[2] * @$rq[1],
  1048. # @$q1[3] * @$rq[1] + @$q1[1] * @$rq[3] + @$q1[2] * @$rq[0] - @$q1[0] * @$rq[2],
  1049. # @$q1[3] * @$rq[2] + @$q1[2] * @$rq[3] + @$q1[0] * @$rq[1] - @$q1[1] * @$rq[0],
  1050. # @$q1[3] * @$rq[3] - @$q1[0] * @$rq[0] - @$q1[1] * @$rq[1] - @$q1[2] * @$rq[2])
  1051. #}
  1052. #
  1053. ## Convert the screen space coordinate to an object space coordinate.
  1054. ## If the Z screen space coordinate is not provided, a depth buffer value is substituted.
  1055. #sub mouse_to_3d {
  1056. # my ($self, $x, $y, $z) = @_;
  1057. #
  1058. # return unless $self->GetContext;
  1059. # $self->SetCurrent($self->GetContext);
  1060. #
  1061. # my @viewport = glGetIntegerv_p(GL_VIEWPORT); # 4 items
  1062. # my @mview = glGetDoublev_p(GL_MODELVIEW_MATRIX); # 16 items
  1063. # my @proj = glGetDoublev_p(GL_PROJECTION_MATRIX); # 16 items
  1064. #
  1065. # $y = $viewport[3] - $y;
  1066. # $z //= glReadPixels_p($x, $y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT);
  1067. # my @projected = gluUnProject_p($x, $y, $z, @mview, @proj, @viewport);
  1068. # return Slic3r::Pointf3->new(@projected);
  1069. #}
  1070. #
  1071. #sub GetContext {
  1072. # my ($self) = @_;
  1073. # return $self->{context} ||= Wx::GLContext->new($self);
  1074. #}
  1075. #
  1076. #sub SetCurrent {
  1077. # my ($self, $context) = @_;
  1078. # return $self->SUPER::SetCurrent($context);
  1079. #}
  1080. #
  1081. #sub UseVBOs {
  1082. # my ($self) = @_;
  1083. #
  1084. # if (! defined ($self->{use_VBOs})) {
  1085. # my $use_legacy = wxTheApp->{app_config}->get('use_legacy_opengl');
  1086. # if ($use_legacy eq '1') {
  1087. # # Disable OpenGL 2.0 rendering.
  1088. # $self->{use_VBOs} = 0;
  1089. # # Don't enable the layer editing tool.
  1090. # $self->{layer_editing_enabled} = 0;
  1091. # # 2 means failed
  1092. # $self->{layer_editing_initialized} = 2;
  1093. # return 0;
  1094. # }
  1095. # # This is a special path for wxWidgets on GTK, where an OpenGL context is initialized
  1096. # # first when an OpenGL widget is shown for the first time. How ugly.
  1097. # return 0 if (! $self->init && $^O eq 'linux');
  1098. # # Don't use VBOs if anything fails.
  1099. # $self->{use_VBOs} = 0;
  1100. # if ($self->GetContext) {
  1101. # $self->SetCurrent($self->GetContext);
  1102. # Slic3r::GUI::_3DScene::_glew_init;
  1103. # my @gl_version = split(/\./, glGetString(GL_VERSION));
  1104. # $self->{use_VBOs} = int($gl_version[0]) >= 2;
  1105. # # print "UseVBOs $self OpenGL major: $gl_version[0], minor: $gl_version[1]. Use VBOs: ", $self->{use_VBOs}, "\n";
  1106. # }
  1107. # }
  1108. # return $self->{use_VBOs};
  1109. #}
  1110. #
  1111. #sub Resize {
  1112. # my ($self, $x, $y) = @_;
  1113. #
  1114. # return unless $self->GetContext;
  1115. # $self->_dirty(0);
  1116. #
  1117. # $self->SetCurrent($self->GetContext);
  1118. # glViewport(0, 0, $x, $y);
  1119. #
  1120. # $x /= $self->_zoom;
  1121. # $y /= $self->_zoom;
  1122. #
  1123. # glMatrixMode(GL_PROJECTION);
  1124. # glLoadIdentity();
  1125. # if ($self->_camera_type eq 'ortho') {
  1126. # #FIXME setting the size of the box 10x larger than necessary
  1127. # # is only a workaround for an incorrectly set camera.
  1128. # # This workaround harms Z-buffer accuracy!
  1129. ## my $depth = 1.05 * $self->max_bounding_box->radius();
  1130. # my $depth = 5.0 * max(@{ $self->max_bounding_box->size });
  1131. # glOrtho(
  1132. # -$x/2, $x/2, -$y/2, $y/2,
  1133. # -$depth, $depth,
  1134. # );
  1135. # } else {
  1136. # die "Invalid camera type: ", $self->_camera_type, "\n" if ($self->_camera_type ne 'perspective');
  1137. # my $bbox_r = $self->max_bounding_box->radius();
  1138. # my $fov = PI * 45. / 180.;
  1139. # my $fov_tan = tan(0.5 * $fov);
  1140. # my $cam_distance = 0.5 * $bbox_r / $fov_tan;
  1141. # $self->_camera_distance($cam_distance);
  1142. # my $nr = $cam_distance - $bbox_r * 1.1;
  1143. # my $fr = $cam_distance + $bbox_r * 1.1;
  1144. # $nr = 1 if ($nr < 1);
  1145. # $fr = $nr + 1 if ($fr < $nr + 1);
  1146. # my $h2 = $fov_tan * $nr;
  1147. # my $w2 = $h2 * $x / $y;
  1148. # glFrustum(-$w2, $w2, -$h2, $h2, $nr, $fr);
  1149. # }
  1150. # glMatrixMode(GL_MODELVIEW);
  1151. #}
  1152. #
  1153. #sub InitGL {
  1154. # my $self = shift;
  1155. #
  1156. # return if $self->init;
  1157. # return unless $self->GetContext;
  1158. # $self->init(1);
  1159. #
  1160. ## # This is a special path for wxWidgets on GTK, where an OpenGL context is initialized
  1161. ## # first when an OpenGL widget is shown for the first time. How ugly.
  1162. ## # In that case the volumes are wainting to be moved to Vertex Buffer Objects
  1163. ## # after the OpenGL context is being initialized.
  1164. ## $self->volumes->finalize_geometry(1)
  1165. ## if ($^O eq 'linux' && $self->UseVBOs);
  1166. #
  1167. # $self->zoom_to_bed;
  1168. #
  1169. # glClearColor(0, 0, 0, 1);
  1170. # glColor3f(1, 0, 0);
  1171. # glEnable(GL_DEPTH_TEST);
  1172. # glClearDepth(1.0);
  1173. # glDepthFunc(GL_LEQUAL);
  1174. # glEnable(GL_CULL_FACE);
  1175. # glEnable(GL_BLEND);
  1176. # glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1177. #
  1178. # # Set antialiasing/multisampling
  1179. # glDisable(GL_LINE_SMOOTH);
  1180. # glDisable(GL_POLYGON_SMOOTH);
  1181. #
  1182. # # See "GL_MULTISAMPLE and GL_ARRAY_BUFFER_ARB messages on failed launch"
  1183. # # https://github.com/alexrj/Slic3r/issues/4085
  1184. # eval {
  1185. # # Disable the multi sampling by default, so the picking by color will work correctly.
  1186. # glDisable(GL_MULTISAMPLE);
  1187. # };
  1188. # # Disable multi sampling if the eval failed.
  1189. # $self->{can_multisample} = 0 if $@;
  1190. #
  1191. # # ambient lighting
  1192. # glLightModelfv_p(GL_LIGHT_MODEL_AMBIENT, 0.3, 0.3, 0.3, 1);
  1193. #
  1194. # glEnable(GL_LIGHTING);
  1195. # glEnable(GL_LIGHT0);
  1196. # glEnable(GL_LIGHT1);
  1197. #
  1198. # # light from camera
  1199. # glLightfv_p(GL_LIGHT1, GL_POSITION, 1, 0, 1, 0);
  1200. # glLightfv_p(GL_LIGHT1, GL_SPECULAR, 0.3, 0.3, 0.3, 1);
  1201. # glLightfv_p(GL_LIGHT1, GL_DIFFUSE, 0.2, 0.2, 0.2, 1);
  1202. #
  1203. # # Enables Smooth Color Shading; try GL_FLAT for (lack of) fun.
  1204. # glShadeModel(GL_SMOOTH);
  1205. #
  1206. ## glMaterialfv_p(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, 0.5, 0.3, 0.3, 1);
  1207. ## glMaterialfv_p(GL_FRONT_AND_BACK, GL_SPECULAR, 1, 1, 1, 1);
  1208. ## glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50);
  1209. ## glMaterialfv_p(GL_FRONT_AND_BACK, GL_EMISSION, 0.1, 0, 0, 0.9);
  1210. #
  1211. # # A handy trick -- have surface material mirror the color.
  1212. # glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  1213. # glEnable(GL_COLOR_MATERIAL);
  1214. # glEnable(GL_MULTISAMPLE) if ($self->{can_multisample});
  1215. #
  1216. # if ($self->UseVBOs) {
  1217. # my $shader = new Slic3r::GUI::_3DScene::GLShader;
  1218. ## if (! $shader->load($self->_fragment_shader_Phong, $self->_vertex_shader_Phong)) {
  1219. # print "Compilaton of path shader failed: \n" . $shader->last_error . "\n";
  1220. # $shader = undef;
  1221. # } else {
  1222. # $self->{plain_shader} = $shader;
  1223. # }
  1224. # }
  1225. #}
  1226. #
  1227. #sub DestroyGL {
  1228. # my $self = shift;
  1229. # if ($self->GetContext) {
  1230. # $self->SetCurrent($self->GetContext);
  1231. # if ($self->{plain_shader}) {
  1232. # $self->{plain_shader}->release;
  1233. # delete $self->{plain_shader};
  1234. # }
  1235. # if ($self->{layer_height_edit_shader}) {
  1236. # $self->{layer_height_edit_shader}->release;
  1237. # delete $self->{layer_height_edit_shader};
  1238. # }
  1239. # $self->volumes->release_geometry;
  1240. # }
  1241. #}
  1242. #
  1243. #sub Render {
  1244. # my ($self, $dc) = @_;
  1245. #
  1246. # # prevent calling SetCurrent() when window is not shown yet
  1247. # return unless $self->IsShownOnScreen;
  1248. # return unless my $context = $self->GetContext;
  1249. # $self->SetCurrent($context);
  1250. # $self->InitGL;
  1251. #
  1252. # glClearColor(1, 1, 1, 1);
  1253. # glClearDepth(1);
  1254. # glDepthFunc(GL_LESS);
  1255. # glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1256. #
  1257. # glMatrixMode(GL_MODELVIEW);
  1258. # glLoadIdentity();
  1259. #
  1260. # if (!TURNTABLE_MODE) {
  1261. # # Shift the perspective camera.
  1262. # my $camera_pos = Slic3r::Pointf3->new(0,0,-$self->_camera_distance);
  1263. # glTranslatef(@$camera_pos);
  1264. # }
  1265. #
  1266. # if (TURNTABLE_MODE) {
  1267. # # Turntable mode is enabled by default.
  1268. # glRotatef(-$self->_stheta, 1, 0, 0); # pitch
  1269. # glRotatef($self->_sphi, 0, 0, 1); # yaw
  1270. # } else {
  1271. # my @rotmat = quat_to_rotmatrix($self->quat);
  1272. # glMultMatrixd_p(@rotmat[0..15]);
  1273. # }
  1274. #
  1275. # glTranslatef(@{ $self->_camera_target->negative });
  1276. #
  1277. # # light from above
  1278. # glLightfv_p(GL_LIGHT0, GL_POSITION, -0.5, -0.5, 1, 0);
  1279. # glLightfv_p(GL_LIGHT0, GL_SPECULAR, 0.2, 0.2, 0.2, 1);
  1280. # glLightfv_p(GL_LIGHT0, GL_DIFFUSE, 0.5, 0.5, 0.5, 1);
  1281. #
  1282. # # Head light
  1283. # glLightfv_p(GL_LIGHT1, GL_POSITION, 1, 0, 1, 0);
  1284. #
  1285. # if ($self->enable_picking && !$self->_mouse_dragging) {
  1286. # if (my $pos = $self->_mouse_pos) {
  1287. # # Render the object for picking.
  1288. # # FIXME This cannot possibly work in a multi-sampled context as the color gets mangled by the anti-aliasing.
  1289. # # Better to use software ray-casting on a bounding-box hierarchy.
  1290. # glPushAttrib(GL_ENABLE_BIT);
  1291. # glDisable(GL_MULTISAMPLE) if ($self->{can_multisample});
  1292. # glDisable(GL_LIGHTING);
  1293. # glDisable(GL_BLEND);
  1294. # $self->draw_volumes(1);
  1295. # glPopAttrib();
  1296. # glFlush();
  1297. # my $col = [ glReadPixels_p($pos->x, $self->GetSize->GetHeight - $pos->y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE) ];
  1298. # my $volume_idx = $col->[0] + $col->[1]*256 + $col->[2]*256*256;
  1299. # $self->_hover_volume_idx(undef);
  1300. # $_->set_hover(0) for @{$self->volumes};
  1301. # if ($volume_idx <= $#{$self->volumes}) {
  1302. # $self->_hover_volume_idx($volume_idx);
  1303. #
  1304. # $self->volumes->[$volume_idx]->set_hover(1);
  1305. # my $group_id = $self->volumes->[$volume_idx]->select_group_id;
  1306. # if ($group_id != -1) {
  1307. # $_->set_hover(1) for grep { $_->select_group_id == $group_id } @{$self->volumes};
  1308. # }
  1309. #
  1310. # $self->on_hover->($volume_idx) if $self->on_hover;
  1311. # }
  1312. # glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1313. # }
  1314. # }
  1315. #
  1316. # # draw fixed background
  1317. # if ($self->background) {
  1318. # glDisable(GL_LIGHTING);
  1319. # glPushMatrix();
  1320. # glLoadIdentity();
  1321. #
  1322. # glMatrixMode(GL_PROJECTION);
  1323. # glPushMatrix();
  1324. # glLoadIdentity();
  1325. #
  1326. # # Draws a bluish bottom to top gradient over the complete screen.
  1327. # glDisable(GL_DEPTH_TEST);
  1328. # glBegin(GL_QUADS);
  1329. # glColor3f(0.0,0.0,0.0);
  1330. # glVertex3f(-1.0,-1.0, 1.0);
  1331. # glVertex3f( 1.0,-1.0, 1.0);
  1332. # glColor3f(10/255,98/255,144/255);
  1333. # glVertex3f( 1.0, 1.0, 1.0);
  1334. # glVertex3f(-1.0, 1.0, 1.0);
  1335. # glEnd();
  1336. # glPopMatrix();
  1337. # glEnable(GL_DEPTH_TEST);
  1338. #
  1339. # glMatrixMode(GL_MODELVIEW);
  1340. # glPopMatrix();
  1341. # glEnable(GL_LIGHTING);
  1342. # }
  1343. #
  1344. # # draw ground and axes
  1345. # glDisable(GL_LIGHTING);
  1346. #
  1347. # # draw ground
  1348. # my $ground_z = GROUND_Z;
  1349. #
  1350. # if ($self->bed_triangles) {
  1351. # glDisable(GL_DEPTH_TEST);
  1352. #
  1353. # glEnable(GL_BLEND);
  1354. # glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1355. #
  1356. # glEnableClientState(GL_VERTEX_ARRAY);
  1357. # glColor4f(0.8, 0.6, 0.5, 0.4);
  1358. # glNormal3d(0,0,1);
  1359. # glVertexPointer_c(3, GL_FLOAT, 0, $self->bed_triangles->ptr());
  1360. # glDrawArrays(GL_TRIANGLES, 0, $self->bed_triangles->elements / 3);
  1361. # glDisableClientState(GL_VERTEX_ARRAY);
  1362. #
  1363. # # we need depth test for grid, otherwise it would disappear when looking
  1364. # # the object from below
  1365. # glEnable(GL_DEPTH_TEST);
  1366. #
  1367. # # draw grid
  1368. # glLineWidth(3);
  1369. # glColor4f(0.2, 0.2, 0.2, 0.4);
  1370. # glEnableClientState(GL_VERTEX_ARRAY);
  1371. # glVertexPointer_c(3, GL_FLOAT, 0, $self->bed_grid_lines->ptr());
  1372. # glDrawArrays(GL_LINES, 0, $self->bed_grid_lines->elements / 3);
  1373. # glDisableClientState(GL_VERTEX_ARRAY);
  1374. #
  1375. # glDisable(GL_BLEND);
  1376. # }
  1377. #
  1378. # my $volumes_bb = $self->volumes_bounding_box;
  1379. #
  1380. # {
  1381. # # draw axes
  1382. # # disable depth testing so that axes are not covered by ground
  1383. # glDisable(GL_DEPTH_TEST);
  1384. # my $origin = $self->origin;
  1385. # my $axis_len = $self->use_plain_shader ? 0.3 * max(@{ $self->bed_bounding_box->size }) : 2 * max(@{ $volumes_bb->size });
  1386. # glLineWidth(2);
  1387. # glBegin(GL_LINES);
  1388. # # draw line for x axis
  1389. # glColor3f(1, 0, 0);
  1390. # glVertex3f(@$origin, $ground_z);
  1391. # glVertex3f($origin->x + $axis_len, $origin->y, $ground_z); #,,
  1392. # # draw line for y axis
  1393. # glColor3f(0, 1, 0);
  1394. # glVertex3f(@$origin, $ground_z);
  1395. # glVertex3f($origin->x, $origin->y + $axis_len, $ground_z); #++
  1396. # glEnd();
  1397. # # draw line for Z axis
  1398. # # (re-enable depth test so that axis is correctly shown when objects are behind it)
  1399. # glEnable(GL_DEPTH_TEST);
  1400. # glBegin(GL_LINES);
  1401. # glColor3f(0, 0, 1);
  1402. # glVertex3f(@$origin, $ground_z);
  1403. # glVertex3f(@$origin, $ground_z+$axis_len);
  1404. # glEnd();
  1405. # }
  1406. #
  1407. # glEnable(GL_LIGHTING);
  1408. #
  1409. # # draw objects
  1410. # if (! $self->use_plain_shader) {
  1411. # $self->draw_volumes;
  1412. # } elsif ($self->UseVBOs) {
  1413. # if ($self->enable_picking) {
  1414. # $self->mark_volumes_for_layer_height;
  1415. # $self->volumes->set_print_box($self->bed_bounding_box->x_min, $self->bed_bounding_box->y_min, 0.0, $self->bed_bounding_box->x_max, $self->bed_bounding_box->y_max, $self->{config}->get('max_print_height'));
  1416. # $self->volumes->check_outside_state($self->{config});
  1417. # # do not cull backfaces to show broken geometry, if any
  1418. # glDisable(GL_CULL_FACE);
  1419. # }
  1420. # $self->{plain_shader}->enable if $self->{plain_shader};
  1421. # $self->volumes->render_VBOs;
  1422. # $self->{plain_shader}->disable;
  1423. # glEnable(GL_CULL_FACE) if ($self->enable_picking);
  1424. # } else {
  1425. # # do not cull backfaces to show broken geometry, if any
  1426. # glDisable(GL_CULL_FACE) if ($self->enable_picking);
  1427. # $self->volumes->render_legacy;
  1428. # glEnable(GL_CULL_FACE) if ($self->enable_picking);
  1429. # }
  1430. #
  1431. # if (defined $self->cutting_plane_z) {
  1432. # # draw cutting plane
  1433. # my $plane_z = $self->cutting_plane_z;
  1434. # my $bb = $volumes_bb;
  1435. # glDisable(GL_CULL_FACE);
  1436. # glDisable(GL_LIGHTING);
  1437. # glEnable(GL_BLEND);
  1438. # glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1439. # glBegin(GL_QUADS);
  1440. # glColor4f(0.8, 0.8, 0.8, 0.5);
  1441. # glVertex3f($bb->x_min-20, $bb->y_min-20, $plane_z);
  1442. # glVertex3f($bb->x_max+20, $bb->y_min-20, $plane_z);
  1443. # glVertex3f($bb->x_max+20, $bb->y_max+20, $plane_z);
  1444. # glVertex3f($bb->x_min-20, $bb->y_max+20, $plane_z);
  1445. # glEnd();
  1446. # glEnable(GL_CULL_FACE);
  1447. # glDisable(GL_BLEND);
  1448. #
  1449. # # draw cutting contours
  1450. # glEnableClientState(GL_VERTEX_ARRAY);
  1451. # glLineWidth(2);
  1452. # glColor3f(0, 0, 0);
  1453. # glVertexPointer_c(3, GL_FLOAT, 0, $self->cut_lines_vertices->ptr());
  1454. # glDrawArrays(GL_LINES, 0, $self->cut_lines_vertices->elements / 3);
  1455. # glVertexPointer_c(3, GL_FLOAT, 0, 0);
  1456. # glDisableClientState(GL_VERTEX_ARRAY);
  1457. # }
  1458. #
  1459. # # draw warning message
  1460. # $self->draw_warning;
  1461. #
  1462. # # draw gcode preview legend
  1463. # $self->draw_legend;
  1464. #
  1465. # $self->draw_active_object_annotations;
  1466. #
  1467. # $self->SwapBuffers();
  1468. #}
  1469. #
  1470. #sub draw_volumes {
  1471. # # $fakecolor is a boolean indicating, that the objects shall be rendered in a color coding the object index for picking.
  1472. # my ($self, $fakecolor) = @_;
  1473. #
  1474. # # do not cull backfaces to show broken geometry, if any
  1475. # glDisable(GL_CULL_FACE);
  1476. #
  1477. # glEnable(GL_BLEND);
  1478. # glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1479. #
  1480. # glEnableClientState(GL_VERTEX_ARRAY);
  1481. # glEnableClientState(GL_NORMAL_ARRAY);
  1482. #
  1483. # foreach my $volume_idx (0..$#{$self->volumes}) {
  1484. # my $volume = $self->volumes->[$volume_idx];
  1485. #
  1486. # if ($fakecolor) {
  1487. # # Object picking mode. Render the object with a color encoding the object index.
  1488. # my $r = ($volume_idx & 0x000000FF) >> 0;
  1489. # my $g = ($volume_idx & 0x0000FF00) >> 8;
  1490. # my $b = ($volume_idx & 0x00FF0000) >> 16;
  1491. # glColor4f($r/255.0, $g/255.0, $b/255.0, 1);
  1492. # } elsif ($volume->selected) {
  1493. # glColor4f(@{ &SELECTED_COLOR });
  1494. # } elsif ($volume->hover) {
  1495. # glColor4f(@{ &HOVER_COLOR });
  1496. # } else {
  1497. # glColor4f(@{ $volume->color });
  1498. # }
  1499. #
  1500. # $volume->render;
  1501. # }
  1502. # glDisableClientState(GL_NORMAL_ARRAY);
  1503. # glDisableClientState(GL_VERTEX_ARRAY);
  1504. #
  1505. # glDisable(GL_BLEND);
  1506. # glEnable(GL_CULL_FACE);
  1507. #}
  1508. #
  1509. #sub mark_volumes_for_layer_height {
  1510. # my ($self) = @_;
  1511. #
  1512. # foreach my $volume_idx (0..$#{$self->volumes}) {
  1513. # my $volume = $self->volumes->[$volume_idx];
  1514. # my $object_id = int($volume->select_group_id / 1000000);
  1515. # if ($self->layer_editing_enabled && $volume->selected && $self->{layer_height_edit_shader} &&
  1516. # $volume->has_layer_height_texture && $object_id < $self->{print}->object_count) {
  1517. # $volume->set_layer_height_texture_data($self->{layer_preview_z_texture_id}, $self->{layer_height_edit_shader}->shader_program_id,
  1518. # $self->{print}->get_object($object_id), $self->_variable_layer_thickness_bar_mouse_cursor_z_relative, $self->{layer_height_edit_band_width});
  1519. # } else {
  1520. # $volume->reset_layer_height_texture_data();
  1521. # }
  1522. # }
  1523. #}
  1524. #
  1525. #sub _load_image_set_texture {
  1526. # my ($self, $file_name) = @_;
  1527. # # Load a PNG with an alpha channel.
  1528. # my $img = Wx::Image->new;
  1529. # $img->LoadFile(Slic3r::var($file_name), wxBITMAP_TYPE_PNG);
  1530. # # Get RGB & alpha raw data from wxImage, interleave them into a Perl array.
  1531. # my @rgb = unpack 'C*', $img->GetData();
  1532. # my @alpha = $img->HasAlpha ? unpack 'C*', $img->GetAlpha() : (255) x (int(@rgb) / 3);
  1533. # my $n_pixels = int(@alpha);
  1534. # my @data = (0)x($n_pixels * 4);
  1535. # for (my $i = 0; $i < $n_pixels; $i += 1) {
  1536. # $data[$i*4 ] = $rgb[$i*3];
  1537. # $data[$i*4+1] = $rgb[$i*3+1];
  1538. # $data[$i*4+2] = $rgb[$i*3+2];
  1539. # $data[$i*4+3] = $alpha[$i];
  1540. # }
  1541. # # Initialize a raw bitmap data.
  1542. # my $params = {
  1543. # loaded => 1,
  1544. # valid => $n_pixels > 0,
  1545. # width => $img->GetWidth,
  1546. # height => $img->GetHeight,
  1547. # data => OpenGL::Array->new_list(GL_UNSIGNED_BYTE, @data),
  1548. # texture_id => glGenTextures_p(1)
  1549. # };
  1550. # # Create and initialize a texture with the raw data.
  1551. # glBindTexture(GL_TEXTURE_2D, $params->{texture_id});
  1552. # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1553. # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1554. # glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
  1555. # glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $params->{width}, $params->{height}, 0, GL_RGBA, GL_UNSIGNED_BYTE, $params->{data}->ptr);
  1556. # glBindTexture(GL_TEXTURE_2D, 0);
  1557. # return $params;
  1558. #}
  1559. #
  1560. #sub _variable_layer_thickness_load_overlay_image {
  1561. # my ($self) = @_;
  1562. # $self->{layer_preview_annotation} = $self->_load_image_set_texture('variable_layer_height_tooltip.png')
  1563. # if (! $self->{layer_preview_annotation}->{loaded});
  1564. # return $self->{layer_preview_annotation}->{valid};
  1565. #}
  1566. #
  1567. #sub _variable_layer_thickness_load_reset_image {
  1568. # my ($self) = @_;
  1569. # $self->{layer_preview_reset_image} = $self->_load_image_set_texture('variable_layer_height_reset.png')
  1570. # if (! $self->{layer_preview_reset_image}->{loaded});
  1571. # return $self->{layer_preview_reset_image}->{valid};
  1572. #}
  1573. #
  1574. ## Paint the tooltip.
  1575. #sub _render_image {
  1576. # my ($self, $image, $l, $r, $b, $t) = @_;
  1577. # $self->_render_texture($image->{texture_id}, $l, $r, $b, $t);
  1578. #}
  1579. #
  1580. #sub _render_texture {
  1581. # my ($self, $tex_id, $l, $r, $b, $t) = @_;
  1582. #
  1583. # glColor4f(1.,1.,1.,1.);
  1584. # glDisable(GL_LIGHTING);
  1585. # glEnable(GL_BLEND);
  1586. # glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1587. # glEnable(GL_TEXTURE_2D);
  1588. # glBindTexture(GL_TEXTURE_2D, $tex_id);
  1589. # glBegin(GL_QUADS);
  1590. # glTexCoord2d(0.,1.); glVertex3f($l, $b, 0);
  1591. # glTexCoord2d(1.,1.); glVertex3f($r, $b, 0);
  1592. # glTexCoord2d(1.,0.); glVertex3f($r, $t, 0);
  1593. # glTexCoord2d(0.,0.); glVertex3f($l, $t, 0);
  1594. # glEnd();
  1595. # glBindTexture(GL_TEXTURE_2D, 0);
  1596. # glDisable(GL_TEXTURE_2D);
  1597. # glDisable(GL_BLEND);
  1598. # glEnable(GL_LIGHTING);
  1599. #}
  1600. #
  1601. #sub draw_active_object_annotations {
  1602. # # $fakecolor is a boolean indicating, that the objects shall be rendered in a color coding the object index for picking.
  1603. # my ($self) = @_;
  1604. #
  1605. # return if (! $self->{layer_height_edit_shader} || ! $self->layer_editing_enabled);
  1606. #
  1607. # # Find the selected volume, over which the layer editing is active.
  1608. # my $volume;
  1609. # foreach my $volume_idx (0..$#{$self->volumes}) {
  1610. # my $v = $self->volumes->[$volume_idx];
  1611. # if ($v->selected && $v->has_layer_height_texture) {
  1612. # $volume = $v;
  1613. # last;
  1614. # }
  1615. # }
  1616. # return if (! $volume);
  1617. #
  1618. # # If the active object was not allocated at the Print, go away. This should only be a momentary case between an object addition / deletion
  1619. # # and an update by Platter::async_apply_config.
  1620. # my $object_idx = int($volume->select_group_id / 1000000);
  1621. # return if $object_idx >= $self->{print}->object_count;
  1622. #
  1623. # # The viewport and camera are set to complete view and glOrtho(-$x/2, $x/2, -$y/2, $y/2, -$depth, $depth),
  1624. # # where x, y is the window size divided by $self->_zoom.
  1625. # my ($bar_left, $bar_bottom, $bar_right, $bar_top) = $self->_variable_layer_thickness_bar_rect_viewport;
  1626. # my ($reset_left, $reset_bottom, $reset_right, $reset_top) = $self->_variable_layer_thickness_reset_rect_viewport;
  1627. # my $z_cursor_relative = $self->_variable_layer_thickness_bar_mouse_cursor_z_relative;
  1628. #
  1629. # my $print_object = $self->{print}->get_object($object_idx);
  1630. # my $z_max = $print_object->model_object->bounding_box->z_max;
  1631. #
  1632. # $self->{layer_height_edit_shader}->enable;
  1633. # $self->{layer_height_edit_shader}->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id);
  1634. # $self->{layer_height_edit_shader}->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height);
  1635. # $self->{layer_height_edit_shader}->set_uniform('z_cursor', $z_max * $z_cursor_relative);
  1636. # $self->{layer_height_edit_shader}->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width});
  1637. # glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id});
  1638. # glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $volume->layer_height_texture_width, $volume->layer_height_texture_height,
  1639. # 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  1640. # glTexImage2D_c(GL_TEXTURE_2D, 1, GL_RGBA8, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2,
  1641. # 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  1642. # glTexSubImage2D_c(GL_TEXTURE_2D, 0, 0, 0, $volume->layer_height_texture_width, $volume->layer_height_texture_height,
  1643. # GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level0);
  1644. # glTexSubImage2D_c(GL_TEXTURE_2D, 1, 0, 0, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2,
  1645. # GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level1);
  1646. #
  1647. # # Render the color bar.
  1648. # glDisable(GL_DEPTH_TEST);
  1649. # # The viewport and camera are set to complete view and glOrtho(-$x/2, $x/2, -$y/2, $y/2, -$depth, $depth),
  1650. # # where x, y is the window size divided by $self->_zoom.
  1651. # glPushMatrix();
  1652. # glLoadIdentity();
  1653. # # Paint the overlay.
  1654. # glBegin(GL_QUADS);
  1655. # glVertex3f($bar_left, $bar_bottom, 0);
  1656. # glVertex3f($bar_right, $bar_bottom, 0);
  1657. # glVertex3f($bar_right, $bar_top, $z_max);
  1658. # glVertex3f($bar_left, $bar_top, $z_max);
  1659. # glEnd();
  1660. # glBindTexture(GL_TEXTURE_2D, 0);
  1661. # $self->{layer_height_edit_shader}->disable;
  1662. #
  1663. # # Paint the tooltip.
  1664. # if ($self->_variable_layer_thickness_load_overlay_image)
  1665. # my $gap = 10/$self->_zoom;
  1666. # my ($l, $r, $b, $t) = ($bar_left - $self->{layer_preview_annotation}->{width}/$self->_zoom - $gap, $bar_left - $gap, $reset_bottom + $self->{layer_preview_annotation}->{height}/$self->_zoom + $gap, $reset_bottom + $gap);
  1667. # $self->_render_image($self->{layer_preview_annotation}, $l, $r, $t, $b);
  1668. # }
  1669. #
  1670. # # Paint the reset button.
  1671. # if ($self->_variable_layer_thickness_load_reset_image) {
  1672. # $self->_render_image($self->{layer_preview_reset_image}, $reset_left, $reset_right, $reset_bottom, $reset_top);
  1673. # }
  1674. #
  1675. # # Paint the graph.
  1676. # #FIXME show some kind of legend.
  1677. # my $max_z = unscale($print_object->size->z);
  1678. # my $profile = $print_object->model_object->layer_height_profile;
  1679. # my $layer_height = $print_object->config->get('layer_height');
  1680. # my $layer_height_max = 10000000000.;
  1681. # {
  1682. # # Get a maximum layer height value.
  1683. # #FIXME This is a duplicate code of Slicing.cpp.
  1684. # my $nozzle_diameters = $print_object->print->config->get('nozzle_diameter');
  1685. # my $layer_heights_min = $print_object->print->config->get('min_layer_height');
  1686. # my $layer_heights_max = $print_object->print->config->get('max_layer_height');
  1687. # for (my $i = 0; $i < scalar(@{$nozzle_diameters}); $i += 1) {
  1688. # my $lh_min = ($layer_heights_min->[$i] == 0.) ? 0.07 : max(0.01, $layer_heights_min->[$i]);
  1689. # my $lh_max = ($layer_heights_max->[$i] == 0.) ? (0.75 * $nozzle_diameters->[$i]) : $layer_heights_max->[$i];
  1690. # $layer_height_max = min($layer_height_max, max($lh_min, $lh_max));
  1691. # }
  1692. # }
  1693. # # Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
  1694. # $layer_height_max *= 1.12;
  1695. # # Baseline
  1696. # glColor3f(0., 0., 0.);
  1697. # glBegin(GL_LINE_STRIP);
  1698. # glVertex2f($bar_left + $layer_height * ($bar_right - $bar_left) / $layer_height_max, $bar_bottom);
  1699. # glVertex2f($bar_left + $layer_height * ($bar_right - $bar_left) / $layer_height_max, $bar_top);
  1700. # glEnd();
  1701. # # Curve
  1702. # glColor3f(0., 0., 1.);
  1703. # glBegin(GL_LINE_STRIP);
  1704. # for (my $i = 0; $i < int(@{$profile}); $i += 2) {
  1705. # my $z = $profile->[$i];
  1706. # my $h = $profile->[$i+1];
  1707. # glVertex3f($bar_left + $h * ($bar_right - $bar_left) / $layer_height_max, $bar_bottom + $z * ($bar_top - $bar_bottom) / $max_z, $z);
  1708. # }
  1709. # glEnd();
  1710. # # Revert the matrices.
  1711. # glPopMatrix();
  1712. # glEnable(GL_DEPTH_TEST);
  1713. #}
  1714. #
  1715. #sub draw_legend {
  1716. # my ($self) = @_;
  1717. #
  1718. # if (!$self->_legend_enabled) {
  1719. # return;
  1720. # }
  1721. #
  1722. # # If the legend texture has not been loaded into the GPU, do it now.
  1723. # my $tex_id = Slic3r::GUI::_3DScene::finalize_legend_texture;
  1724. # if ($tex_id > 0)
  1725. # {
  1726. # my $tex_w = Slic3r::GUI::_3DScene::get_legend_texture_width;
  1727. # my $tex_h = Slic3r::GUI::_3DScene::get_legend_texture_height;
  1728. # if (($tex_w > 0) && ($tex_h > 0))
  1729. # {
  1730. # glDisable(GL_DEPTH_TEST);
  1731. # glPushMatrix();
  1732. # glLoadIdentity();
  1733. #
  1734. # my ($cw, $ch) = $self->GetSizeWH;
  1735. #
  1736. # my $l = (-0.5 * $cw) / $self->_zoom;
  1737. # my $t = (0.5 * $ch) / $self->_zoom;
  1738. # my $r = $l + $tex_w / $self->_zoom;
  1739. # my $b = $t - $tex_h / $self->_zoom;
  1740. # $self->_render_texture($tex_id, $l, $r, $b, $t);
  1741. #
  1742. # glPopMatrix();
  1743. # glEnable(GL_DEPTH_TEST);
  1744. # }
  1745. # }
  1746. #}
  1747. #
  1748. #sub draw_warning {
  1749. # my ($self) = @_;
  1750. #
  1751. # if (!$self->_warning_enabled) {
  1752. # return;
  1753. # }
  1754. #
  1755. # # If the warning texture has not been loaded into the GPU, do it now.
  1756. # my $tex_id = Slic3r::GUI::_3DScene::finalize_warning_texture;
  1757. # if ($tex_id > 0)
  1758. # {
  1759. # my $tex_w = Slic3r::GUI::_3DScene::get_warning_texture_width;
  1760. # my $tex_h = Slic3r::GUI::_3DScene::get_warning_texture_height;
  1761. # if (($tex_w > 0) && ($tex_h > 0))
  1762. # {
  1763. # glDisable(GL_DEPTH_TEST);
  1764. # glPushMatrix();
  1765. # glLoadIdentity();
  1766. #
  1767. # my ($cw, $ch) = $self->GetSizeWH;
  1768. #
  1769. # my $l = (-0.5 * $tex_w) / $self->_zoom;
  1770. # my $t = (-0.5 * $ch + $tex_h) / $self->_zoom;
  1771. # my $r = $l + $tex_w / $self->_zoom;
  1772. # my $b = $t - $tex_h / $self->_zoom;
  1773. # $self->_render_texture($tex_id, $l, $r, $b, $t);
  1774. #
  1775. # glPopMatrix();
  1776. # glEnable(GL_DEPTH_TEST);
  1777. # }
  1778. # }
  1779. #}
  1780. #
  1781. #sub update_volumes_colors_by_extruder {
  1782. # my ($self, $config) = @_;
  1783. # $self->volumes->update_colors_by_extruder($config);
  1784. #}
  1785. #
  1786. #sub opengl_info
  1787. #{
  1788. # my ($self, %params) = @_;
  1789. # my %tag = Slic3r::tags($params{format});
  1790. #
  1791. # my $gl_version = glGetString(GL_VERSION);
  1792. # my $gl_vendor = glGetString(GL_VENDOR);
  1793. # my $gl_renderer = glGetString(GL_RENDERER);
  1794. # my $glsl_version = glGetString(GL_SHADING_LANGUAGE_VERSION);
  1795. #
  1796. # my $out = '';
  1797. # $out .= "$tag{h2start}OpenGL installation$tag{h2end}$tag{eol}";
  1798. # $out .= " $tag{bstart}Using POGL$tag{bend} v$OpenGL::BUILD_VERSION$tag{eol}";
  1799. # $out .= " $tag{bstart}GL version: $tag{bend}${gl_version}$tag{eol}";
  1800. # $out .= " $tag{bstart}vendor: $tag{bend}${gl_vendor}$tag{eol}";
  1801. # $out .= " $tag{bstart}renderer: $tag{bend}${gl_renderer}$tag{eol}";
  1802. # $out .= " $tag{bstart}GLSL version: $tag{bend}${glsl_version}$tag{eol}";
  1803. #
  1804. # # Check for other OpenGL extensions
  1805. # $out .= "$tag{h2start}Installed extensions (* implemented in the module):$tag{h2end}$tag{eol}";
  1806. # my $extensions = glGetString(GL_EXTENSIONS);
  1807. # my @extensions = split(' ',$extensions);
  1808. # foreach my $ext (sort @extensions) {
  1809. # my $stat = glpCheckExtension($ext);
  1810. # $out .= sprintf("%s ${ext}$tag{eol}", $stat?' ':'*');
  1811. # $out .= sprintf(" ${stat}$tag{eol}") if ($stat && $stat !~ m|^$ext |);
  1812. # }
  1813. #
  1814. # return $out;
  1815. #}
  1816. #
  1817. #sub _report_opengl_state
  1818. #{
  1819. # my ($self, $comment) = @_;
  1820. # my $err = glGetError();
  1821. # return 0 if ($err == 0);
  1822. #
  1823. # # gluErrorString() hangs. Don't use it.
  1824. ## my $errorstr = gluErrorString();
  1825. # my $errorstr = '';
  1826. # if ($err == 0x0500) {
  1827. # $errorstr = 'GL_INVALID_ENUM';
  1828. # } elsif ($err == GL_INVALID_VALUE) {
  1829. # $errorstr = 'GL_INVALID_VALUE';
  1830. # } elsif ($err == GL_INVALID_OPERATION) {
  1831. # $errorstr = 'GL_INVALID_OPERATION';
  1832. # } elsif ($err == GL_STACK_OVERFLOW) {
  1833. # $errorstr = 'GL_STACK_OVERFLOW';
  1834. # } elsif ($err == GL_OUT_OF_MEMORY) {
  1835. # $errorstr = 'GL_OUT_OF_MEMORY';
  1836. # } else {
  1837. # $errorstr = 'unknown';
  1838. # }
  1839. # if (defined($comment)) {
  1840. # printf("OpenGL error at %s, nr %d (0x%x): %s\n", $comment, $err, $err, $errorstr);
  1841. # } else {
  1842. # printf("OpenGL error nr %d (0x%x): %s\n", $err, $err, $errorstr);
  1843. # }
  1844. #}
  1845. #
  1846. #sub _vertex_shader_Gouraud {
  1847. # return <<'VERTEX';
  1848. ##version 110
  1849. #
  1850. ##define INTENSITY_CORRECTION 0.6
  1851. #
  1852. #// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
  1853. #const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
  1854. ##define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
  1855. ##define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
  1856. ##define LIGHT_TOP_SHININESS 20.0
  1857. #
  1858. #// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
  1859. #const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
  1860. ##define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
  1861. #//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
  1862. #//#define LIGHT_FRONT_SHININESS 5.0
  1863. #
  1864. ##define INTENSITY_AMBIENT 0.3
  1865. #
  1866. #const vec3 ZERO = vec3(0.0, 0.0, 0.0);
  1867. #
  1868. #struct PrintBoxDetection
  1869. #{
  1870. # vec3 min;
  1871. # vec3 max;
  1872. # // xyz contains the offset, if w == 1.0 detection needs to be performed
  1873. # vec4 volume_origin;
  1874. #};
  1875. #
  1876. #uniform PrintBoxDetection print_box;
  1877. #
  1878. #// x = tainted, y = specular;
  1879. #varying vec2 intensity;
  1880. #
  1881. #varying vec3 delta_box_min;
  1882. #varying vec3 delta_box_max;
  1883. #
  1884. #void main()
  1885. #{
  1886. # // First transform the normal into camera space and normalize the result.
  1887. # vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
  1888. #
  1889. # // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
  1890. # // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
  1891. # float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
  1892. #
  1893. # intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
  1894. # intensity.y = 0.0;
  1895. #
  1896. # if (NdotL > 0.0)
  1897. # intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(normal, reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
  1898. #
  1899. # // Perform the same lighting calculation for the 2nd light source (no specular applied).
  1900. # NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
  1901. # intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
  1902. #
  1903. # // compute deltas for out of print volume detection (world coordinates)
  1904. # if (print_box.volume_origin.w == 1.0)
  1905. # {
  1906. # vec3 v = gl_Vertex.xyz + print_box.volume_origin.xyz;
  1907. # delta_box_min = v - print_box.min;
  1908. # delta_box_max = v - print_box.max;
  1909. # }
  1910. # else
  1911. # {
  1912. # delta_box_min = ZERO;
  1913. # delta_box_max = ZERO;
  1914. # }
  1915. #
  1916. # gl_Position = ftransform();
  1917. #}
  1918. #
  1919. #VERTEX
  1920. #}
  1921. #
  1922. #sub _fragment_shader_Gouraud {
  1923. # return <<'FRAGMENT';
  1924. ##version 110
  1925. #
  1926. #const vec3 ZERO = vec3(0.0, 0.0, 0.0);
  1927. #
  1928. #// x = tainted, y = specular;
  1929. #varying vec2 intensity;
  1930. #
  1931. #varying vec3 delta_box_min;
  1932. #varying vec3 delta_box_max;
  1933. #
  1934. #uniform vec4 uniform_color;
  1935. #
  1936. #void main()
  1937. #{
  1938. # // if the fragment is outside the print volume -> use darker color
  1939. # vec3 color = (any(lessThan(delta_box_min, ZERO)) || any(greaterThan(delta_box_max, ZERO))) ? mix(uniform_color.rgb, ZERO, 0.3333) : uniform_color.rgb;
  1940. # gl_FragColor = vec4(vec3(intensity.y, intensity.y, intensity.y) + color * intensity.x, uniform_color.a);
  1941. #}
  1942. #
  1943. #FRAGMENT
  1944. #}
  1945. #
  1946. #sub _vertex_shader_Phong {
  1947. # return <<'VERTEX';
  1948. ##version 110
  1949. #
  1950. #varying vec3 normal;
  1951. #varying vec3 eye;
  1952. #void main(void)
  1953. #{
  1954. # eye = normalize(vec3(gl_ModelViewMatrix * gl_Vertex));
  1955. # normal = normalize(gl_NormalMatrix * gl_Normal);
  1956. # gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
  1957. #}
  1958. #VERTEX
  1959. #}
  1960. #
  1961. #sub _fragment_shader_Phong {
  1962. # return <<'FRAGMENT';
  1963. ##version 110
  1964. #
  1965. ##define INTENSITY_CORRECTION 0.7
  1966. #
  1967. ##define LIGHT_TOP_DIR -0.6/1.31, 0.6/1.31, 1./1.31
  1968. ##define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
  1969. ##define LIGHT_TOP_SPECULAR (0.5 * INTENSITY_CORRECTION)
  1970. #//#define LIGHT_TOP_SHININESS 50.
  1971. ##define LIGHT_TOP_SHININESS 10.
  1972. #
  1973. ##define LIGHT_FRONT_DIR 1./1.43, 0.2/1.43, 1./1.43
  1974. ##define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
  1975. ##define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
  1976. ##define LIGHT_FRONT_SHININESS 50.
  1977. #
  1978. ##define INTENSITY_AMBIENT 0.0
  1979. #
  1980. #varying vec3 normal;
  1981. #varying vec3 eye;
  1982. #uniform vec4 uniform_color;
  1983. #void main() {
  1984. #
  1985. # float intensity_specular = 0.;
  1986. # float intensity_tainted = 0.;
  1987. # float intensity = max(dot(normal,vec3(LIGHT_TOP_DIR)), 0.0);
  1988. # // if the vertex is lit compute the specular color
  1989. # if (intensity > 0.0) {
  1990. # intensity_tainted = LIGHT_TOP_DIFFUSE * intensity;
  1991. # // compute the half vector
  1992. # vec3 h = normalize(vec3(LIGHT_TOP_DIR) + eye);
  1993. # // compute the specular term into spec
  1994. # intensity_specular = LIGHT_TOP_SPECULAR * pow(max(dot(h, normal), 0.0), LIGHT_TOP_SHININESS);
  1995. # }
  1996. # intensity = max(dot(normal,vec3(LIGHT_FRONT_DIR)), 0.0);
  1997. # // if the vertex is lit compute the specular color
  1998. # if (intensity > 0.0) {
  1999. # intensity_tainted += LIGHT_FRONT_DIFFUSE * intensity;
  2000. # // compute the half vector
  2001. #// vec3 h = normalize(vec3(LIGHT_FRONT_DIR) + eye);
  2002. # // compute the specular term into spec
  2003. #// intensity_specular += LIGHT_FRONT_SPECULAR * pow(max(dot(h,normal), 0.0), LIGHT_FRONT_SHININESS);
  2004. # }
  2005. #
  2006. # gl_FragColor = max(
  2007. # vec4(intensity_specular, intensity_specular, intensity_specular, 0.) + uniform_color * intensity_tainted,
  2008. # INTENSITY_AMBIENT * uniform_color);
  2009. # gl_FragColor.a = uniform_color.a;
  2010. #}
  2011. #FRAGMENT
  2012. #}
  2013. #
  2014. #sub _vertex_shader_variable_layer_height {
  2015. # return <<'VERTEX';
  2016. ##version 110
  2017. #
  2018. ##define INTENSITY_CORRECTION 0.6
  2019. #
  2020. #const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
  2021. ##define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
  2022. ##define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
  2023. ##define LIGHT_TOP_SHININESS 20.0
  2024. #
  2025. #const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
  2026. ##define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
  2027. #//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
  2028. #//#define LIGHT_FRONT_SHININESS 5.0
  2029. #
  2030. ##define INTENSITY_AMBIENT 0.3
  2031. #
  2032. #// x = tainted, y = specular;
  2033. #varying vec2 intensity;
  2034. #
  2035. #varying float object_z;
  2036. #
  2037. #void main()
  2038. #{
  2039. # // First transform the normal into camera space and normalize the result.
  2040. # vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
  2041. #
  2042. # // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
  2043. # // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
  2044. # float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
  2045. #
  2046. # intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
  2047. # intensity.y = 0.0;
  2048. #
  2049. # if (NdotL > 0.0)
  2050. # intensity.y += LIGHT_TOP_SPECULAR * pow(max(dot(normal, reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
  2051. #
  2052. # // Perform the same lighting calculation for the 2nd light source (no specular)
  2053. # NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
  2054. #
  2055. # intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
  2056. #
  2057. # // Scaled to widths of the Z texture.
  2058. # object_z = gl_Vertex.z;
  2059. #
  2060. # gl_Position = ftransform();
  2061. #}
  2062. #
  2063. #VERTEX
  2064. #}
  2065. #
  2066. #sub _fragment_shader_variable_layer_height {
  2067. # return <<'FRAGMENT';
  2068. ##version 110
  2069. #
  2070. ##define M_PI 3.1415926535897932384626433832795
  2071. #
  2072. #// 2D texture (1D texture split by the rows) of color along the object Z axis.
  2073. #uniform sampler2D z_texture;
  2074. #// Scaling from the Z texture rows coordinate to the normalized texture row coordinate.
  2075. #uniform float z_to_texture_row;
  2076. #uniform float z_texture_row_to_normalized;
  2077. #uniform float z_cursor;
  2078. #uniform float z_cursor_band_width;
  2079. #
  2080. #// x = tainted, y = specular;
  2081. #varying vec2 intensity;
  2082. #
  2083. #varying float object_z;
  2084. #
  2085. #void main()
  2086. #{
  2087. # float object_z_row = z_to_texture_row * object_z;
  2088. # // Index of the row in the texture.
  2089. # float z_texture_row = floor(object_z_row);
  2090. # // Normalized coordinate from 0. to 1.
  2091. # float z_texture_col = object_z_row - z_texture_row;
  2092. # float z_blend = 0.25 * cos(min(M_PI, abs(M_PI * (object_z - z_cursor) * 1.8 / z_cursor_band_width))) + 0.25;
  2093. # // Calculate level of detail from the object Z coordinate.
  2094. # // This makes the slowly sloping surfaces to be show with high detail (with stripes),
  2095. # // and the vertical surfaces to be shown with low detail (no stripes)
  2096. # float z_in_cells = object_z_row * 190.;
  2097. # // Gradient of Z projected on the screen.
  2098. # float dx_vtc = dFdx(z_in_cells);
  2099. # float dy_vtc = dFdy(z_in_cells);
  2100. # float lod = clamp(0.5 * log2(max(dx_vtc*dx_vtc, dy_vtc*dy_vtc)), 0., 1.);
  2101. # // Sample the Z texture. Texture coordinates are normalized to <0, 1>.
  2102. # vec4 color =
  2103. # mix(texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row + 0.5 )), -10000.),
  2104. # texture2D(z_texture, vec2(z_texture_col, z_texture_row_to_normalized * (z_texture_row * 2. + 1.)), 10000.), lod);
  2105. #
  2106. # // Mix the final color.
  2107. # gl_FragColor =
  2108. # vec4(intensity.y, intensity.y, intensity.y, 1.0) + intensity.x * mix(color, vec4(1.0, 1.0, 0.0, 1.0), z_blend);
  2109. #}
  2110. #
  2111. #FRAGMENT
  2112. #}
  2113. #===================================================================================================================================
  2114. # The 3D canvas to display objects and tool paths.
  2115. package Slic3r::GUI::3DScene;
  2116. use base qw(Slic3r::GUI::3DScene::Base);
  2117. #===================================================================================================================================
  2118. #use OpenGL qw(:glconstants :gluconstants :glufunctions);
  2119. #use List::Util qw(first min max);
  2120. #use Slic3r::Geometry qw(scale unscale epsilon);
  2121. #use Slic3r::Print::State ':steps';
  2122. #===================================================================================================================================
  2123. #===================================================================================================================================
  2124. #__PACKAGE__->mk_accessors(qw(
  2125. # color_by
  2126. # select_by
  2127. # drag_by
  2128. #));
  2129. #===================================================================================================================================
  2130. sub new {
  2131. my $class = shift;
  2132. my $self = $class->SUPER::new(@_);
  2133. #===================================================================================================================================
  2134. # $self->color_by('volume'); # object | volume
  2135. # $self->select_by('object'); # object | volume | instance
  2136. # $self->drag_by('instance'); # object | instance
  2137. #===================================================================================================================================
  2138. return $self;
  2139. }
  2140. #==============================================================================================================================
  2141. #sub load_object {
  2142. # my ($self, $model, $print, $obj_idx, $instance_idxs) = @_;
  2143. #
  2144. # $self->SetCurrent($self->GetContext) if $useVBOs;
  2145. #
  2146. # my $model_object;
  2147. # if ($model->isa('Slic3r::Model::Object')) {
  2148. # $model_object = $model;
  2149. # $model = $model_object->model;
  2150. # $obj_idx = 0;
  2151. # } else {
  2152. # $model_object = $model->get_object($obj_idx);
  2153. # }
  2154. #
  2155. # $instance_idxs ||= [0..$#{$model_object->instances}];
  2156. # my $volume_indices = $self->volumes->load_object(
  2157. # $model_object, $obj_idx, $instance_idxs, $self->color_by, $self->select_by, $self->drag_by,
  2158. # $self->UseVBOs);
  2159. # return @{$volume_indices};
  2160. #}
  2161. #
  2162. ## Create 3D thick extrusion lines for a skirt and brim.
  2163. ## Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes.
  2164. #sub load_print_toolpaths {
  2165. # my ($self, $print, $colors) = @_;
  2166. #
  2167. # $self->SetCurrent($self->GetContext) if $self->UseVBOs;
  2168. # Slic3r::GUI::_3DScene::_load_print_toolpaths($print, $self->volumes, $colors, $self->UseVBOs)
  2169. # if ($print->step_done(STEP_SKIRT) && $print->step_done(STEP_BRIM));
  2170. #}
  2171. #
  2172. ## Create 3D thick extrusion lines for object forming extrusions.
  2173. ## Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
  2174. ## one for perimeters, one for infill and one for supports.
  2175. #sub load_print_object_toolpaths {
  2176. # my ($self, $object, $colors) = @_;
  2177. #
  2178. # $self->SetCurrent($self->GetContext) if $self->UseVBOs;
  2179. # Slic3r::GUI::_3DScene::_load_print_object_toolpaths($object, $self->volumes, $colors, $self->UseVBOs);
  2180. #}
  2181. #
  2182. ## Create 3D thick extrusion lines for wipe tower extrusions.
  2183. #sub load_wipe_tower_toolpaths {
  2184. # my ($self, $print, $colors) = @_;
  2185. #
  2186. # $self->SetCurrent($self->GetContext) if $self->UseVBOs;
  2187. # Slic3r::GUI::_3DScene::_load_wipe_tower_toolpaths($print, $self->volumes, $colors, $self->UseVBOs)
  2188. # if ($print->step_done(STEP_WIPE_TOWER));
  2189. #}
  2190. #
  2191. #sub load_gcode_preview {
  2192. # my ($self, $print, $gcode_preview_data, $colors) = @_;
  2193. #
  2194. # $self->SetCurrent($self->GetContext) if $self->UseVBOs;
  2195. # Slic3r::GUI::_3DScene::load_gcode_preview($print, $gcode_preview_data, $self->volumes, $colors, $self->UseVBOs);
  2196. #}
  2197. #
  2198. #sub set_toolpaths_range {
  2199. # my ($self, $min_z, $max_z) = @_;
  2200. # $self->volumes->set_range($min_z, $max_z);
  2201. #}
  2202. #
  2203. #sub reset_legend_texture {
  2204. # Slic3r::GUI::_3DScene::reset_legend_texture();
  2205. #}
  2206. #
  2207. #sub get_current_print_zs {
  2208. # my ($self, $active_only) = @_;
  2209. # return $self->volumes->get_current_print_zs($active_only);
  2210. #}
  2211. #==============================================================================================================================
  2212. 1;