KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_preview_3d_model.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2016 Mario Luzeiro <[email protected]>
5 * Copyright (C) 2015 Cirilo Bernardo <[email protected]>
6 * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <3d_rendering/opengl/render_3d_opengl.h> // Must be included before any GL header
28
29#include <cmath>
30
35#include <tool/tool_manager.h>
39#include <base_units.h>
40#include <bitmaps.h>
41#include <board.h>
43#include <dpi_scaling_common.h>
44#include <footprint.h>
45#include <lset.h>
46#include <pgm_base.h>
47#include <project_pcb.h>
50#include <widgets/wx_infobar.h>
54
55#if defined(__linux__) || defined(__FreeBSD__)
57#else
59#endif
60
61static wxString evaluateTextCtrl( const wxString& aValue )
62{
63 // NUMERIC_EVALUATOR doesn't handle UTF-8 multi-byte characters properly,
64 // so skip evaluation if the string contains non-ASCII characters (e.g., degree symbols)
65 for( wxUniChar c : aValue )
66 {
67 if( !c.IsAscii() )
68 return aValue;
69 }
70
71 // Attempt to evaluate formula; if successful return result, otherwise return original
73
74 if( eval.Process( aValue ) )
75 return eval.Result();
76
77 return aValue;
78}
79
80
87static double normalizeRotation( double aRotation )
88{
89 double normalized = std::fmod( aRotation, 2.0 * MAX_ROTATION );
90
91 if( normalized <= -MAX_ROTATION )
92 normalized += 2.0 * MAX_ROTATION;
93 else if( normalized > MAX_ROTATION )
94 normalized -= 2.0 * MAX_ROTATION;
95
96 if( normalized == -0.0 )
97 normalized = 0.0;
98
99 return normalized;
100}
101
102
103static double rotationFromString( const wxString& aValue )
104{
106
107 return normalizeRotation( rotation );
108}
109
110
112 std::vector<FP_3DMODEL>* aParentModelList ) :
114 m_parentFrame( aFrame ),
115 m_previewPane( nullptr ),
116 m_infobar( nullptr ),
120{
121 m_userUnits = m_parentFrame->GetUserUnits();
122
123 m_dummyBoard = new BOARD();
124
125 m_dummyBoard->SetProject( &aFrame->Prj(), true );
126 m_dummyBoard->SetEmbeddedFilesDelegate( aFrame->GetBoard() );
127
128 // This board will only be used to hold a footprint for viewing
129 m_dummyBoard->SetBoardUse( BOARD_USE::FPHOLDER );
130
131 BOARD_DESIGN_SETTINGS parent_bds = aFrame->GetDesignSettings();
132 BOARD_DESIGN_SETTINGS& dummy_bds = m_dummyBoard->GetDesignSettings();
133 dummy_bds.SetBoardThickness( parent_bds.GetBoardThickness() );
135 BOARD_STACKUP& dummy_board_stackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
136 dummy_board_stackup.RemoveAll();
137 dummy_board_stackup.BuildDefaultStackupList( &dummy_bds, 2 );
138
139 m_selected = -1;
140
141 m_previewLabel->SetFont( KIUI::GetStatusFont( this ) );
142
143 // Set the bitmap of 3D view buttons:
150 m_bpvISO->SetBitmap( KiBitmapBundle( BITMAPS::ortho ) );
154
155 // Set the min and max values of spin buttons (mandatory on Linux)
156 // They are not used, so they are set to min and max 32 bits int values
157 // (the min and max values supported by a wxSpinButton)
158 // It avoids blocking the up or down arrows when reaching this limit after
159 // a few clicks.
160 wxSpinButton* spinButtonList[] =
161 {
165 };
166
167 for( wxSpinButton* button : spinButtonList )
168 button->SetRange(INT_MIN, INT_MAX );
169
170 for( TEXT_CTRL_EVAL* rotCtrl : { xrot, yrot, zrot } )
171 {
172 rotCtrl->SetCustomEval(
173 [&]( TEXT_CTRL_EVAL* aCtrl )
174 {
175 double value = rotationFromString( evaluateTextCtrl( aCtrl->GetValue() ) );
176 aCtrl->SetValue( formatRotationValue( value ) );
177 } );
178 }
179
180 for( TEXT_CTRL_EVAL* scaleCtrl : { xscale, yscale, zscale } )
181 {
182 scaleCtrl->SetCustomEval(
183 [&]( TEXT_CTRL_EVAL* aCtrl )
184 {
186 evaluateTextCtrl( aCtrl->GetValue() ) );
187 aCtrl->SetValue( formatScaleValue( value ) );
188 } );
189 }
190
191 m_parentModelList = aParentModelList;
192
193 m_dummyFootprint = new FOOTPRINT( *aFootprint );
194 m_dummyFootprint->SetParentGroup( nullptr );
195
196 // Ensure the footprint is shown like in Fp editor: rot 0, not flipped
197 // to avoid mistakes when setting the3D shape position/rotation
198 if( m_dummyFootprint->IsFlipped() )
200
201 m_dummyFootprint->SetOrientation( ANGLE_0 );
202
204
205 // Create the 3D canvas
208 PROJECT_PCB::Get3DCacheManager( &aFrame->Prj() ) );
209
210 try
211 {
212#if defined(__linux__) || defined(__FreeBSD__)
213 m_spaceMouse = std::make_unique<SPNAV_VIEWER_PLUGIN>( m_previewPane );
214#else
215 m_spaceMouse = std::make_unique<NL_FOOTPRINT_PROPERTIES_PLUGIN>( m_previewPane );
216#endif
217 m_spaceMouse->SetFocus( true );
218 }
219 catch( const std::system_error& e )
220 {
221 wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
222 }
223
224 m_boardAdapter.SetBoard( m_dummyBoard );
225 m_boardAdapter.m_IsBoardView = false;
226
227 // Force display 3D models, regardless the 3D viewer options.
228 m_boardAdapter.m_IsPreviewer = true;
229
230 loadSettings();
231
232 // Don't show placeholder models in the footprint properties 3D preview
233 if( m_boardAdapter.m_Cfg )
234 m_boardAdapter.m_Cfg->m_Render.show_missing_models = false;
235
236 // Create the manager
238 m_toolManager->SetEnvironment( m_dummyBoard, nullptr, nullptr, nullptr, this );
239
242 m_previewPane->SetEventDispatcher( m_toolDispatcher );
243
244 // Register tools
245 m_toolManager->RegisterTool( new EDA_3D_CONTROLLER );
246 m_toolManager->InitTools();
247
248 // Run the viewer control tool, it is supposed to be always active
249 m_toolManager->InvokeTool( "3DViewer.Control" );
250
251 m_infobar = new WX_INFOBAR( this );
252 m_previewPane->SetInfoBar( m_infobar );
253
254 m_SizerPanelView->Add( m_infobar, 0, wxEXPAND, 0 );
255 m_SizerPanelView->Add( m_previewPane, 1, wxEXPAND, 5 );
256
257 for( wxEventType eventType : { wxEVT_MENU_OPEN, wxEVT_MENU_CLOSE, wxEVT_MENU_HIGHLIGHT } )
258 Connect( eventType, wxMenuEventHandler( PANEL_PREVIEW_3D_MODEL::OnMenuEvent ), nullptr, this );
259
260 aFrame->Connect( EDA_EVT_UNITS_CHANGED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL::onUnitsChanged ),
261 nullptr, this );
262
263 Bind( wxCUSTOM_PANEL_SHOWN_EVENT, &PANEL_PREVIEW_3D_MODEL::onPanelShownEvent, this );
264}
265
266
268{
269 // Shutdown all running tools
270 if( m_toolManager )
271 m_toolManager->ShutdownAllTools();
272
273 // Restore the 3D viewer Render settings, that can be modified by the panel tools
274 if( m_boardAdapter.m_Cfg )
275 m_boardAdapter.m_Cfg->m_Render = m_initialRender;
276
277 delete m_dummyBoard;
278 delete m_previewPane;
279}
280
281
282void PANEL_PREVIEW_3D_MODEL::OnMenuEvent( wxMenuEvent& aEvent )
283{
284 if( !m_toolDispatcher )
285 aEvent.Skip();
286 else
287 m_toolDispatcher->DispatchWxEvent( aEvent );
288}
289
290
292{
293 wxCHECK_RET( m_previewPane, wxT( "Cannot load settings to null canvas" ) );
294
295 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
296
297 // TODO(JE) use all control options
298 m_boardAdapter.m_MousewheelPanning = settings->m_Input.scroll_modifier_zoom != 0;
299
301 {
302 // Save the 3D viewer render settings, to restore it after closing the preview
303 m_initialRender = cfg->m_Render;
304
305 m_boardAdapter.m_Cfg = cfg;
306
307 m_previewPane->SetAnimationEnabled( cfg->m_Camera.animation_enabled );
308 m_previewPane->SetMovingSpeedMultiplier( cfg->m_Camera.moving_speed_multiplier );
309 m_previewPane->SetProjectionMode( cfg->m_Camera.projection_mode );
310 }
311}
312
313
315{
316 return wxString::Format( wxT( "%.4f" ),
317 aValue );
318}
319
320
322{
323 // Sigh. Did we really need differentiated +/- 0.0?
324 if( aValue == -0.0 )
325 aValue = 0.0;
326
327 return wxString::Format( wxT( "%.2f%s" ),
328 aValue,
330}
331
332
334{
335 // Convert from internal units (mm) to user units
337 aValue /= 25.4;
338 else if( m_userUnits == EDA_UNITS::MILS )
339 aValue /= 25.4 / 1e3;
340
341 return wxString::Format( wxT( "%.6f%s" ),
342 aValue,
344}
345
346
348{
349 if( m_parentModelList && idx >= 0 && idx < (int) m_parentModelList->size() )
350 {
351 m_selected = idx;
352 const FP_3DMODEL& modelInfo = m_parentModelList->at( (unsigned) m_selected );
353
354 // Use ChangeValue() instead of SetValue(). It's not the user making the change, so we
355 // don't want to generate wxEVT_GRID_CELL_CHANGED events.
356 xscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.x ) );
357 yscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.y ) );
358 zscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.z ) );
359
360 // Rotation is stored in the file as positive-is-CW, but we use positive-is-CCW in the GUI
361 // to match the rest of KiCad
362 xrot->ChangeValue( formatRotationValue( -modelInfo.m_Rotation.x ) );
363 yrot->ChangeValue( formatRotationValue( -modelInfo.m_Rotation.y ) );
364 zrot->ChangeValue( formatRotationValue( -modelInfo.m_Rotation.z ) );
365
366 xoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.x ) );
367 yoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.y ) );
368 zoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.z ) );
369
370 m_opacity->SetValue( modelInfo.m_Opacity * 100.0 );
371 }
372 else
373 {
374 m_selected = -1;
375
376 xscale->ChangeValue( wxEmptyString );
377 yscale->ChangeValue( wxEmptyString );
378 zscale->ChangeValue( wxEmptyString );
379
380 xrot->ChangeValue( wxEmptyString );
381 yrot->ChangeValue( wxEmptyString );
382 zrot->ChangeValue( wxEmptyString );
383
384 xoff->ChangeValue( wxEmptyString );
385 yoff->ChangeValue( wxEmptyString );
386 zoff->ChangeValue( wxEmptyString );
387
388 m_opacity->SetValue( 100 );
389 }
390}
391
392
394{
395 m_extrudedBody = aBody;
396
397 if( aBody )
398 {
399 xscale->ChangeValue( formatScaleValue( aBody->m_scale.x ) );
400 yscale->ChangeValue( formatScaleValue( aBody->m_scale.y ) );
401 zscale->ChangeValue( formatScaleValue( aBody->m_scale.z ) );
402
403 xrot->ChangeValue( formatRotationValue( -aBody->m_rotation.x ) );
404 yrot->ChangeValue( formatRotationValue( -aBody->m_rotation.y ) );
405 zrot->ChangeValue( formatRotationValue( -aBody->m_rotation.z ) );
406
407 xoff->ChangeValue( formatOffsetValue( aBody->m_offset.x ) );
408 yoff->ChangeValue( formatOffsetValue( aBody->m_offset.y ) );
409 zoff->ChangeValue( formatOffsetValue( aBody->m_offset.z ) );
410
411 m_opacity->SetValue( 100 );
412 m_opacity->Enable( false );
413 }
414 else
415 {
416 m_opacity->Enable( true );
417 }
418}
419
420
421void PANEL_PREVIEW_3D_MODEL::updateOrientation( wxCommandEvent &event )
422{
423 if( m_extrudedBody )
424 {
426 evaluateTextCtrl( xscale->GetValue() ) );
428 evaluateTextCtrl( yscale->GetValue() ) );
430 evaluateTextCtrl( zscale->GetValue() ) );
431
432 m_extrudedBody->m_rotation.x = -rotationFromString( evaluateTextCtrl( xrot->GetValue() ) );
433 m_extrudedBody->m_rotation.y = -rotationFromString( evaluateTextCtrl( yrot->GetValue() ) );
434 m_extrudedBody->m_rotation.z = -rotationFromString( evaluateTextCtrl( zrot->GetValue() ) );
435
437 evaluateTextCtrl( xoff->GetValue() ) )
438 / pcbIUScale.IU_PER_MM;
440 evaluateTextCtrl( yoff->GetValue() ) )
441 / pcbIUScale.IU_PER_MM;
443 evaluateTextCtrl( zoff->GetValue() ) )
444 / pcbIUScale.IU_PER_MM;
445
446 UpdateDummyFootprint( true );
447 onModify();
448 }
449 else if( m_parentModelList && m_selected >= 0 && m_selected < (int) m_parentModelList->size() )
450 {
451 // Write settings back to the parent
452 FP_3DMODEL* modelInfo = &m_parentModelList->at( (unsigned) m_selected );
453
455 evaluateTextCtrl( xscale->GetValue() ) );
457 evaluateTextCtrl( yscale->GetValue() ) );
459 evaluateTextCtrl( zscale->GetValue() ) );
460
461 // Rotation is stored in the file as positive-is-CW, but we use positive-is-CCW in the GUI
462 // to match the rest of KiCad
463 modelInfo->m_Rotation.x = -rotationFromString( evaluateTextCtrl( xrot->GetValue() ) );
464 modelInfo->m_Rotation.y = -rotationFromString( evaluateTextCtrl( yrot->GetValue() ) );
465 modelInfo->m_Rotation.z = -rotationFromString( evaluateTextCtrl( zrot->GetValue() ) );
466
468 evaluateTextCtrl( xoff->GetValue() ) )
469 / pcbIUScale.IU_PER_MM;
471 evaluateTextCtrl( yoff->GetValue() ) )
472 / pcbIUScale.IU_PER_MM;
474 evaluateTextCtrl( zoff->GetValue() ) )
475 / pcbIUScale.IU_PER_MM;
476
477 // Update the dummy footprint for the preview
478 UpdateDummyFootprint( false );
479 onModify();
480 }
481}
482
483
484void PANEL_PREVIEW_3D_MODEL::onOpacitySlider( wxCommandEvent& event )
485{
486 if( m_parentModelList && m_selected >= 0 && m_selected < (int) m_parentModelList->size() )
487 {
488 // Write settings back to the parent
489 FP_3DMODEL* modelInfo = &m_parentModelList->at( (unsigned) m_selected );
490
491 modelInfo->m_Opacity = m_opacity->GetValue() / 100.0;
492
493 // Update the dummy footprint for the preview
494 UpdateDummyFootprint( false );
495 onModify();
496 }
497}
498
499
500void PANEL_PREVIEW_3D_MODEL::setBodyStyleView( wxCommandEvent& event )
501{
502 // turn ON or OFF options to show the board body if OFF, solder paste, soldermask
503 // and board body are hidden, to allows a good view of the 3D model and its pads.
505
506 if( !cfg )
507 return;
508
510
511 m_previewPane->ReloadRequest();
512 m_previewPane->Refresh();
513}
514
515
516void PANEL_PREVIEW_3D_MODEL::View3DSettings( wxCommandEvent& event )
517{
518 BOARD_DESIGN_SETTINGS bds = m_dummyBoard->GetDesignSettings();
519 int thickness = bds.GetBoardThickness();
520
521 WX_UNIT_ENTRY_DIALOG dlg( m_parentFrame, _( "3D Preview Options" ), _( "Board thickness:" ), thickness );
522
523 if( dlg.ShowModal() != wxID_OK )
524 return;
525
526 bds.SetBoardThickness( dlg.GetValue() );
527
528 BOARD_STACKUP& boardStackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
529 boardStackup.RemoveAll();
530 boardStackup.BuildDefaultStackupList( &bds, 2 );
531
532 UpdateDummyFootprint( true );
533
534 m_previewPane->ReloadRequest();
535 m_previewPane->Refresh();
536}
537
538
539void PANEL_PREVIEW_3D_MODEL::doIncrementScale( wxSpinEvent& event, double aSign )
540{
541 wxSpinButton* spinCtrl = dynamic_cast<wxSpinButton*>( event.GetEventObject() );
542
543 wxCHECK( spinCtrl, /* void */ );
544
545 wxTextCtrl * textCtrl = xscale;
546
547 if( spinCtrl == m_spinYscale )
548 textCtrl = yscale;
549 else if( spinCtrl == m_spinZscale )
550 textCtrl = zscale;
551
552 double step = SCALE_INCREMENT;
553
554 if( wxGetMouseState().ShiftDown( ) )
556
557 double value = EDA_UNIT_UTILS::UI::DoubleValueFromString( unityScale, EDA_UNITS::UNSCALED, textCtrl->GetValue() );
558
559 value += ( step * aSign );
560 value = std::max( 1/MAX_SCALE, value );
561 value = std::min( value, MAX_SCALE );
562
563 textCtrl->SetValue( formatScaleValue( value ) );
564}
565
566
567void PANEL_PREVIEW_3D_MODEL::doIncrementRotation( wxSpinEvent& aEvent, double aSign )
568{
569 wxSpinButton* spinCtrl = dynamic_cast<wxSpinButton*>( aEvent.GetEventObject() );
570
571 wxCHECK( spinCtrl, /* void */ );
572
573 wxTextCtrl* textCtrl = xrot;
574
575 if( spinCtrl == m_spinYrot )
576 textCtrl = yrot;
577 else if( spinCtrl == m_spinZrot )
578 textCtrl = zrot;
579
580 double step = ROTATION_INCREMENT;
581
582 if( wxGetMouseState().ShiftDown( ) )
584
585 double value = rotationFromString( textCtrl->GetValue() );
586
587 value = normalizeRotation( value + step * aSign );
588
589 textCtrl->SetValue( formatRotationValue( value ) );
590}
591
592
593void PANEL_PREVIEW_3D_MODEL::doIncrementOffset( wxSpinEvent& event, double aSign )
594{
595 wxSpinButton* spinCtrl = dynamic_cast<wxSpinButton*>( event.GetEventObject() );
596
597 wxCHECK( spinCtrl, /* void */ );
598
599 wxTextCtrl * textCtrl = xoff;
600
601 if( spinCtrl == m_spinYoffset )
602 textCtrl = yoff;
603 else if( spinCtrl == m_spinZoffset )
604 textCtrl = zoff;
605
606 double step_mm = OFFSET_INCREMENT_MM;
607
608 if( wxGetMouseState().ShiftDown( ) )
609 step_mm = OFFSET_INCREMENT_MM_FINE;
610
612 {
613 step_mm = 25.4*OFFSET_INCREMENT_MIL/1000;
614
615 if( wxGetMouseState().ShiftDown( ) )
616 step_mm = 25.4*OFFSET_INCREMENT_MIL_FINE/1000;;
617 }
618
619 double value_mm = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits, textCtrl->GetValue() )
620 / pcbIUScale.IU_PER_MM;
621
622 value_mm += ( step_mm * aSign );
623 value_mm = std::max( -MAX_OFFSET, value_mm );
624 value_mm = std::min( value_mm, MAX_OFFSET );
625
626 textCtrl->SetValue( formatOffsetValue( value_mm ) );
627}
628
629
631{
632 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( event.GetEventObject() );
633
634 wxCHECK( textCtrl, /* void */ );
635
636 double step = SCALE_INCREMENT;
637
638 if( event.ShiftDown( ) )
640
641 if( event.GetWheelRotation() >= 0 )
642 step = -step;
643
644 double value = EDA_UNIT_UTILS::UI::DoubleValueFromString( unityScale, EDA_UNITS::UNSCALED, textCtrl->GetValue() );
645
646 value += step;
647 value = std::max( 1/MAX_SCALE, value );
648 value = std::min( value, MAX_SCALE );
649
650 textCtrl->SetValue( formatScaleValue( value ) );
651}
652
653
655{
656 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( event.GetEventObject() );
657
658 wxCHECK( textCtrl, /* void */ );
659
660 double step = ROTATION_INCREMENT;
661
662 if( event.ShiftDown( ) )
664
665 if( event.GetWheelRotation() >= 0 )
666 step = -step;
667
668 double value = rotationFromString( textCtrl->GetValue() );
669
670 value = normalizeRotation( value + step );
671
672 textCtrl->SetValue( formatRotationValue( value ) );
673}
674
675
677{
678 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( event.GetEventObject() );
679
680 wxCHECK( textCtrl, /* void */ );
681
682 double step_mm = OFFSET_INCREMENT_MM;
683
684 if( event.ShiftDown( ) )
685 step_mm = OFFSET_INCREMENT_MM_FINE;
686
688 {
689 step_mm = 25.4*OFFSET_INCREMENT_MIL/1000.0;
690
691 if( event.ShiftDown( ) )
692 step_mm = 25.4*OFFSET_INCREMENT_MIL_FINE/1000.0;
693 }
694
695 if( event.GetWheelRotation() >= 0 )
696 step_mm = -step_mm;
697
698 double value_mm = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, m_userUnits, textCtrl->GetValue() )
699 / pcbIUScale.IU_PER_MM;
700
701 value_mm += step_mm;
702 value_mm = std::max( -MAX_OFFSET, value_mm );
703 value_mm = std::min( value_mm, MAX_OFFSET );
704
705 textCtrl->SetValue( formatOffsetValue( value_mm ) );
706}
707
708
709void PANEL_PREVIEW_3D_MODEL::onUnitsChanged( wxCommandEvent& aEvent )
710{
712 / pcbIUScale.IU_PER_MM;
714 / pcbIUScale.IU_PER_MM;
716 / pcbIUScale.IU_PER_MM;
717
718 PCB_BASE_FRAME* frame = static_cast<PCB_BASE_FRAME*>( aEvent.GetClientData() );
719 m_userUnits = frame->GetUserUnits();
720
721 xoff->SetValue( formatOffsetValue( xoff_mm ) );
722 yoff->SetValue( formatOffsetValue( yoff_mm ) );
723 zoff->SetValue( formatOffsetValue( zoff_mm ) );
724
725 aEvent.Skip();
726}
727
728
729void PANEL_PREVIEW_3D_MODEL::onPanelShownEvent( wxCommandEvent& aEvent )
730{
731 if( m_spaceMouse )
732 {
733 m_spaceMouse->SetFocus( static_cast<bool>( aEvent.GetInt() ) );
734 }
735
736 aEvent.Skip();
737}
738
739
741{
742 m_dummyFootprint->Models().clear();
743
745 {
746 if( model.m_Show )
747 m_dummyFootprint->Models().push_back( model );
748 }
749
751
752 if( m_extrudedBody && !m_dummyFootprint->HasExtrudedBody() )
753 m_extrudedBody = nullptr;
754
755 if( aReloadRequired )
756 m_previewPane->ReloadRequest();
757
758 m_previewPane->Request_refresh();
759}
760
761
767
768
770{
771 m_dummyFootprint->ClearEmbeddedFiles();
772
774 {
775 for( const auto& [name, file] : m_localEmbeddedFiles->EmbeddedFileMap() )
776 {
777 m_dummyFootprint->AddFile(
778 new EMBEDDED_FILES::EMBEDDED_FILE( *file ) );
779 }
780 }
781}
782
783
785{
786 KIWAY_HOLDER* kiwayHolder = dynamic_cast<KIWAY_HOLDER*>( wxGetTopLevelParent( this ) );
787
788 if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::DIALOG )
789 static_cast<DIALOG_SHIM*>( kiwayHolder )->OnModify();
790}
const char * name
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:125
constexpr EDA_IU_SCALE unityScale
Definition base_units.h:128
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
@ show_board_body
@ options_3drender
@ FPHOLDER
Definition board.h:315
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
Container for design settings for a BOARD object.
void SetEnabledLayers(const LSET &aMask)
Change the bit-mask of enabled layers to aMask.
int GetBoardThickness() const
The full thickness of the board including copper and masks.
void SetBoardThickness(int aThickness)
Manage layers needed to make a physical board.
void RemoveAll()
Delete all items in list and clear the list.
void BuildDefaultStackupList(const BOARD_DESIGN_SETTINGS *aSettings, int aActiveCopperLayersCount=0)
Create a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition dialog_shim.h:69
int ShowModal() override
EDA_3D_ACTIONS.
Implement a canvas based on a wxGLCanvas.
Handle view actions for various 3D canvases.
VECTOR3D m_offset
Definition footprint.h:116
VECTOR3D m_rotation
Definition footprint.h:115
VECTOR3D m_scale
Definition footprint.h:114
VECTOR3D m_Offset
3D model offset (mm)
Definition footprint.h:173
double m_Opacity
Definition footprint.h:174
VECTOR3D m_Rotation
3D model rotation (degrees)
Definition footprint.h:172
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
Definition footprint.h:171
A mix in class which holds the location of a wxWindow's KIWAY.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
HOLDER_TYPE GetType() const
static const LSET & FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
Definition lset.cpp:722
static const LSET & BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Definition lset.cpp:729
wxString Result() const
bool Process(const wxString &aString)
static const wxGLAttributes GetAttributesList(ANTIALIASING_MODE aAntiAliasingMode, bool aAlpha=false)
Get a list of attributes to pass to wxGLCanvas.
PANEL_PREVIEW_3D_MODEL_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
wxString formatOffsetValue(double aValue)
void onMouseWheelRot(wxMouseEvent &event) override
void View3DSettings(wxCommandEvent &event) override
void onOpacitySlider(wxCommandEvent &event) override
void setBodyStyleView(wxCommandEvent &event) override
void onMouseWheelScale(wxMouseEvent &event) override
EDA_3D_VIEWER_SETTINGS::RENDER_SETTINGS m_initialRender
The 3d viewer Render initial settings (must be saved and restored)
void UpdateDummyFootprint(bool aRelaodRequired=true)
Copy shapes from the current shape list which are flagged for preview to the copy of footprint that i...
wxString formatScaleValue(double aValue)
void doIncrementRotation(wxSpinEvent &aEvent, double aSign)
void loadSettings()
Load 3D relevant settings from the user configuration.
void OnMenuEvent(wxMenuEvent &aEvent)
The TOOL_DISPATCHER needs these to work around some issues in wxWidgets where the menu events aren't ...
void onUnitsChanged(wxCommandEvent &aEvent)
void doIncrementOffset(wxSpinEvent &aEvent, double aSign)
PANEL_PREVIEW_3D_MODEL(wxWindow *aParent, PCB_BASE_FRAME *aFrame, FOOTPRINT *aFootprint, std::vector< FP_3DMODEL > *aParentModelList)
void SetEmbeddedFilesDelegate(EMBEDDED_FILES *aDelegate)
EXTRUDED_3D_BODY * m_extrudedBody
void SetExtrusionTransformMode(EXTRUDED_3D_BODY *aBody)
void doIncrementScale(wxSpinEvent &aEvent, double aSign)
void updateOrientation(wxCommandEvent &event) override
It will receive the events from editing the fields.
wxString formatRotationValue(double aValue)
void onMouseWheelOffset(wxMouseEvent &event) override
std::unique_ptr< NL_FOOTPRINT_PROPERTIES_PLUGIN > m_spaceMouse
void onPanelShownEvent(wxCommandEvent &aEvent)
EMBEDDED_FILES * m_localEmbeddedFiles
void SetSelectedModel(int idx)
Set the currently selected index in the model list so that the scale/rotation/offset controls can be ...
std::vector< FP_3DMODEL > * m_parentModelList
EDA_UNITS m_userUnits
Index into m_parentInfoList.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Return the BOARD_DESIGN_SETTINGS for the open project.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:541
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
wxTextCtrl wrapper to handle math expression evaluation.
void SetValue(const wxString &aValue) override
Set a new value in evaluator buffer and display it in the wxTextCtrl.
TOOL_MANAGER * m_toolManager
TOOL_DISPATCHER * m_toolDispatcher
ACTIONS * m_actions
Master controller class:
EDA_UNITS GetUserUnits() const
A modified version of the wxInfoBar class that allows us to:
Definition wx_infobar.h:77
An extension of WX_TEXT_ENTRY_DIALOG that uses UNIT_BINDER to request a dimension (e....
int GetValue()
Return the value in internal units.
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
Definition mirror.h:29
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue to a double.
KICOMMON_API wxString GetText(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
KICOMMON_API wxFont GetStatusFont(wxWindow *aWindow)
declaration of the nl_footprint_properties_plugin class
Declaration of the cogl_att_list class.
static double normalizeRotation(double aRotation)
Normalize a rotation in degrees to the half-open range (-MAX_ROTATION, MAX_ROTATION].
static double rotationFromString(const wxString &aValue)
static wxString evaluateTextCtrl(const wxString &aValue)
#define MAX_SCALE
#define MAX_ROTATION
#define MAX_OFFSET
#define OFFSET_INCREMENT_MM_FINE
#define OFFSET_INCREMENT_MIL
#define SCALE_INCREMENT
#define ROTATION_INCREMENT_FINE
#define OFFSET_INCREMENT_MM
#define ROTATION_INCREMENT
#define OFFSET_INCREMENT_MIL_FINE
#define SCALE_INCREMENT_FINE
#define PANEL_PREVIEW_3D_MODEL_ID
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
T * GetAppSettings(const char *aFilename)
KIBIS_MODEL * model