Commit 667d200c authored by sumpfralle's avatar sumpfralle

turned all old-style classes into new-style classes

moved data file location handling to a separate module
moved most model handling functions to separate "plugins"
created a basic "core" handler for settings, widgets and events


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@1061 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 3a99ef31
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkFrame" id="ModelExtrusionFrame">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox44">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkTable" id="table18">
<property name="visible">True</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="ExtrusionTypeLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Type:</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="ExtrusionHeightLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Height:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="ExtrusionWidthLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Width:</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="ExtrusionTypeSelector">
<property name="visible">True</property>
<property name="model">ExtrusionTypeModel</property>
<property name="active">0</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext9"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="ExtrusionHeight">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">ExtrusionHeightValue</property>
<property name="digits">3</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="ExtrusionWidth">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">ExtrusionWidthValue</property>
<property name="digits">3</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="ExtrusionGridLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Accuracy:</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="ExtrusionGrid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">ExtrusionGridValue</property>
<property name="digits">3</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="ExtrudeButton">
<property name="label" translatable="yes">Extrude model</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Extrusion parameters&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
</child>
</object>
<object class="GtkAdjustment" id="ExtrusionGridValue">
<property name="lower">0.001</property>
<property name="upper">1000</property>
<property name="step_increment">0.10000000000000001</property>
</object>
<object class="GtkAdjustment" id="ExtrusionWidthValue">
<property name="upper">1000</property>
<property name="step_increment">0.5</property>
</object>
<object class="GtkAdjustment" id="ExtrusionHeightValue">
<property name="lower">0.001</property>
<property name="upper">1000</property>
<property name="step_increment">0.5</property>
</object>
<object class="GtkListStore" id="ExtrusionTypeModel">
<columns>
<!-- column-name key -->
<column type="gchararray"/>
<!-- column-name label -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">radius_up</col>
<col id="1" translatable="yes">Radius (up)</col>
</row>
<row>
<col id="0" translatable="yes">radius_down</col>
<col id="1" translatable="yes">Radius (down)</col>
</row>
<row>
<col id="0" translatable="yes">skewed</col>
<col id="1" translatable="yes">Chamfer</col>
</row>
</data>
</object>
</interface>
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkVBox" id="ModelMirrorBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment51">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="xscale">0</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox29">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkVButtonBox" id="vbuttonbox8">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkRadioButton" id="MirrorPlaneXY">
<property name="label" translatable="yes">X-Y</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="MirrorPlaneXZ">
<property name="label" translatable="yes">X-Z</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">MirrorPlaneXY</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="MirrorPlaneYZ">
<property name="label" translatable="yes">Y-Z</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">MirrorPlaneXY</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox10">
<property name="visible">True</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="PlaneMirrorButton">
<property name="label" translatable="yes">Mirror</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label16">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Plane&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkFrame" id="ModelPolygonFrame">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment55">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkHButtonBox" id="hbuttonbox8">
<property name="visible">True</property>
<property name="spacing">3</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="ToggleModelDirectionButton">
<property name="label" translatable="yes">Toggle direction</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="DirectionsGuessButton">
<property name="label" translatable="yes">Revise directions</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label26">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Polygon winding&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
</child>
</object>
</interface>
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkVBox" id="ModelPositionBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkFrame" id="frame9">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox42">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">2</property>
<property name="row_spacing">1</property>
<child>
<object class="GtkSpinButton" id="ShiftPositionX">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="activates_default">True</property>
<property name="width_chars">5</property>
<property name="adjustment">ShiftPositionXValue</property>
<property name="digits">2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="ShiftPositionY">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="activates_default">True</property>
<property name="width_chars">5</property>
<property name="adjustment">ShiftPositionYValue</property>
<property name="digits">2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="ShiftPositionZ">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="activates_default">True</property>
<property name="width_chars">5</property>
<property name="adjustment">ShiftPositionZValue</property>
<property name="digits">2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="shift_x_label">
<property name="visible">True</property>
<property name="label" translatable="yes">x:</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="shift_y_label">
<property name="visible">True</property>
<property name="label" translatable="yes">y:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="shift_z_label">
<property name="visible">True</property>
<property name="label" translatable="yes">z:</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="ShiftModelButton">
<property name="label" translatable="yes">Shift model</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label22">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Relative shift&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator2">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame14">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment54">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox43">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkTable" id="table19">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">5</property>
<property name="column_spacing">3</property>
<property name="row_spacing">3</property>
<child>
<object class="GtkSpinButton" id="AlignPositionX">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="activates_default">True</property>
<property name="width_chars">5</property>
<property name="adjustment">AlignPositionXValue</property>
<property name="digits">2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="AlignPositionY">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="activates_default">True</property>
<property name="width_chars">5</property>
<property name="adjustment">AlignPositionYValue</property>
<property name="digits">2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="AlignPositionZ">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="activates_default">True</property>
<property name="width_chars">5</property>
<property name="adjustment">AlignPositionZValue</property>
<property name="digits">2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="pos_x_label">
<property name="visible">True</property>
<property name="label" translatable="yes">x:</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="pos_y_label">
<property name="visible">True</property>
<property name="label" translatable="yes">y:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="pos_z_label">
<property name="visible">True</property>
<property name="label" translatable="yes">z:</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionXMin">
<property name="label" translatable="yes">Left</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionXCenter">
<property name="label" translatable="yes">Center</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="draw_indicator">True</property>
<property name="group">AlignPositionXMin</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionXMax">
<property name="label" translatable="yes">Right</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="draw_indicator">True</property>
<property name="group">AlignPositionXMin</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="right_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionYMin">
<property name="label" translatable="yes">Front</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionYCenter">
<property name="label" translatable="yes">Center</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="draw_indicator">True</property>
<property name="group">AlignPositionYMin</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionYMax">
<property name="label" translatable="yes">Back</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="draw_indicator">True</property>
<property name="group">AlignPositionYMin</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="right_attach">5</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionZMin">
<property name="label" translatable="yes">Bottom</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="draw_indicator">True</property>
<property name="group">AlignPositionZMax</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionZCenter">
<property name="label" translatable="yes">Center</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="draw_indicator">True</property>
<property name="group">AlignPositionZMax</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="AlignPositionZMax">
<property name="label" translatable="yes">Top</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="image_position">top</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="right_attach">5</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="AlignPositionButton">
<property name="label" translatable="yes">Align position</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Align position&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkAdjustment" id="ShiftPositionXValue">
<property name="lower">-2000</property>
<property name="upper">2000</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="ShiftPositionYValue">
<property name="lower">-2000</property>
<property name="upper">2000</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="ShiftPositionZValue">
<property name="lower">-2000</property>
<property name="upper">2000</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="AlignPositionXValue">
<property name="lower">-2000</property>
<property name="upper">2000</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="AlignPositionYValue">
<property name="lower">-2000</property>
<property name="upper">2000</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="AlignPositionZValue">
<property name="lower">-2000</property>
<property name="upper">2000</property>
<property name="step_increment">1</property>
</object>
</interface>
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkFrame" id="ModelProjectionFrame">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment56">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox47">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkRadioButton" id="ProjectionModelTop">
<property name="label" translatable="yes">Top</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="ProjectionModelMiddle">
<property name="label" translatable="yes">Middle</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">ProjectionModelTop</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="ProjectionModelBottom">
<property name="label" translatable="yes">Bottom</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">ProjectionModelTop</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<object class="GtkRadioButton" id="ProjectionModelCustom">
<property name="label" translatable="yes">custom z:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">ProjectionModelTop</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="ProjectionZLevel">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">ProjectionZLevelValue</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="ProjectionButton">
<property name="label" translatable="yes">Calculate 2D projection</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">4</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label28">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;2D Projection&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
</child>
</object>
<object class="GtkAdjustment" id="ProjectionZLevelValue">
<property name="lower">-2000</property>
<property name="upper">2000</property>
<property name="step_increment">1</property>
</object>
</interface>
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkVBox" id="ModelRotationBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment42">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="xscale">0</property>
<property name="left_padding">12</property>
<child>
<object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="layout_style">start</property>
<child>
<object class="GtkRadioButton" id="RotationAxisX">
<property name="label" translatable="yes">X</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="RotationAxisY">
<property name="label" translatable="yes">Y</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">RotationAxisX</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="RotationAxisZ">
<property name="label" translatable="yes">Z</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">RotationAxisX</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label13">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Axis&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment57">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox40">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkRadioButton" id="RotationAngle90CKW">
<property name="label" translatable="yes">90&#xB0; Clockwise</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="RotationAngle90CCKW">
<property name="label" translatable="yes">90&#xB0; Counter-Clockwise</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">RotationAngle90CKW</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="RotationAngle180">
<property name="label" translatable="yes">180&#xB0;</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">RotationAngle90CKW</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox10">
<property name="visible">True</property>
<child>
<object class="GtkRadioButton" id="RotationAngleCustomCKW">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">RotationAngle90CKW</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="RotationAngle">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">RotationAngleValue</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label15">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">&#xB0; Clockwise</property>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label14">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Angle&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox2">
<property name="visible">True</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="RotateModelButton">
<property name="label" translatable="yes">Rotate</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkAdjustment" id="RotationAngleValue">
<property name="lower">-360</property>
<property name="upper">360</property>
<property name="step_increment">15</property>
</object>
</interface>
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkVBox" id="ModelScaleBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkFrame" id="frame5">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox4">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkHBox" id="hbox6">
<property name="visible">True</property>
<property name="spacing">1</property>
<child>
<object class="GtkLabel" id="ScaleFactorLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Factor:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="padding">3</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="ScalePercent">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="activates_default">True</property>
<property name="adjustment">ScalePercentValue</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="ScalePercentUnitLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">%</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox9">
<property name="visible">True</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="ScaleModelButton">
<property name="label" translatable="yes">Scale Model</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label19">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Proportional Scaling&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator6">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="padding">2</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame7">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment53">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox5">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkHBox" id="hbox18">
<property name="visible">True</property>
<property name="spacing">3</property>
<child>
<object class="GtkComboBox" id="ScaleDimensionAxis">
<property name="visible">True</property>
<property name="model">ScaleDimensionAxesList</property>
<property name="active">0</property>
<child>
<object class="GtkCellRendererText" id="ScaleDimensionColumn"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="ScaleDimensionControl">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="activates_default">True</property>
<property name="adjustment">ScaleDimensionValue</property>
<property name="digits">2</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHButtonBox" id="hbuttonbox4">
<property name="visible">True</property>
<property name="spacing">3</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="ScaleSelectedAxisButton">
<property name="label" translatable="yes">Scale selected Axis</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ScaleAllAxesButton">
<property name="label" translatable="yes">Scale all Axes</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label20">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Scale to Size&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator17">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame15">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="left_padding">12</property>
<child>
<object class="GtkHButtonBox" id="hbuttonbox7">
<property name="visible">True</property>
<property name="spacing">3</property>
<property name="layout_style">start</property>
<child>
<object class="GtkButton" id="ScaleMMInch">
<property name="label" translatable="yes">mm -&gt; Inch</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ScaleInchMM">
<property name="label" translatable="yes">Inch -&gt; mm</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label25">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Metric &amp;amp; Imperial&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">4</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkListStore" id="ScaleDimensionAxesList">
<columns>
<!-- column-name value -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">x</col>
</row>
<row>
<col id="0" translatable="yes">y</col>
</row>
<row>
<col id="0" translatable="yes">z</col>
</row>
</data>
</object>
<object class="GtkAdjustment" id="ScaleDimensionValue">
<property name="upper">10000</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="ScalePercentValue">
<property name="lower">1</property>
<property name="upper">10000</property>
<property name="step_increment">25</property>
</object>
</interface>
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<child>
<object class="GtkVBox" id="ModelSwapBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkFrame" id="frame4">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment52">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="xscale">0</property>
<property name="left_padding">12</property>
<child>
<object class="GtkVBox" id="vbox9">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkVButtonBox" id="vbuttonbox9">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkRadioButton" id="SwapAxesXY">
<property name="label" translatable="yes">X &lt;-&gt; Y</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="SwapAxesXZ">
<property name="label" translatable="yes">X &lt;-&gt; Z</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">SwapAxesXY</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="SwapAxesYZ">
<property name="label" translatable="yes">Y &lt;-&gt; Z</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="group">SwapAxesXY</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="SwapAxesButton">
<property name="label" translatable="yes">Swap</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label17">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Axes pair&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -22,7 +22,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
import os
class EMCToolExporter:
class EMCToolExporter(object):
def __init__(self, tools):
self.tools = tools
......
......@@ -64,7 +64,7 @@ def _get_num_converter(step_width):
return lambda number: decimal.Decimal(format_string % number)
class GCodeGenerator:
class GCodeGenerator(object):
NUM_OF_AXES = 3
......
......@@ -25,7 +25,7 @@ from pycam import VERSION
import datetime
import os
class STLExporter:
class STLExporter(object):
def __init__(self, model, name="model", created_by="pycam", linesep=None,
**kwargs):
......
......@@ -24,7 +24,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
SVG_OUTPUT_DPI = 90
class SVGExporter:
class SVGExporter(object):
def __init__(self, output, unit="mm", maxx=None, maxy=None):
if isinstance(output, basestring):
......
......@@ -33,9 +33,6 @@ TRANSFORMATIONS = {
"x": ((1, 0, 0, 0), (0, 0, 1, 0), (0, -1, 0, 0)),
"y": ((0, 0, -1, 0), (0, 1, 0, 0), (1, 0, 0, 0)),
"z": ((0, 1, 0, 0), (-1, 0, 0, 0), (0, 0, 1, 0)),
"xy": ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, -1, 0)),
"xz": ((1, 0, 0, 0), (0, -1, 0, 0), (0, 0, 1, 0)),
"yz": ((-1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0)),
"x_swap_y": ((0, 1, 0, 0), (1, 0, 0, 0), (0, 0, 1, 0)),
"x_swap_z": ((0, 0, 1, 0), (0, 1, 0, 0), (1, 0, 0, 0)),
"y_swap_z": ((1, 0, 0, 0), (0, 0, 1, 0), (0, 1, 0, 0)),
......@@ -141,7 +138,7 @@ def get_rotation_matrix_from_to(v_orig, v_dest):
t * rot_axis.y * rot_axis.z + s * rot_axis.x,
t * rot_axis.z * rot_axis.z + c)
def get_rotation_matrix_axis_angle(rot_axis, rot_angle):
def get_rotation_matrix_axis_angle(rot_axis, rot_angle, use_radians=True):
""" calculate rotation matrix for a normalized vector and an angle
see http://mathworld.wolfram.com/RotationMatrix.html
......@@ -153,6 +150,8 @@ def get_rotation_matrix_axis_angle(rot_axis, rot_angle):
@rtype: tuple(float)
@return: the roation
"""
if not use_radians:
rot_angle *= math.pi / 180
sin = number(math.sin(rot_angle))
cos = number(math.cos(rot_angle))
return ((cos + rot_axis[0]*rot_axis[0]*(1-cos),
......
......@@ -39,7 +39,7 @@ except ImportError:
get_point_object = lambda point: point
class Path:
class Path(object):
id = 0
def __init__(self):
self.id = Path.id
......
......@@ -32,7 +32,7 @@ DEBUG_POLYGONEXTRACTOR2 = False
DEBUG_POLYGONEXTRACTOR3 = False
class PolygonExtractor:
class PolygonExtractor(object):
CONTOUR = 1
MONOTONE = 2
......
......@@ -28,7 +28,7 @@ except ImportError:
GL_enabled = False
class Node:
class Node(object):
def __repr__(self):
s = ""
for bound in self.bound:
......
......@@ -86,7 +86,7 @@ def connect_button_handlers(signal, original_button, derived_button):
original_button)
class Camera:
class Camera(object):
def __init__(self, settings, get_dim_func, view=None):
self.view = None
......@@ -281,7 +281,7 @@ class Camera:
return (factors_x, factors_y)
class ModelViewWindowGL:
class ModelViewWindowGL(object):
def __init__(self, gui, settings, notify_destroy=None, accel_group=None,
item_buttons=None, context_menu_actions=None):
# assume, that initialization will fail
......
......@@ -35,6 +35,8 @@ from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Plane import Plane
import pycam.Geometry.Path
import pycam.Utils.log
from pycam.Utils.locations import get_data_file_location, \
get_ui_file_location, get_font_dir
import pycam.Utils
from pycam.Geometry.utils import sqrt
from pycam.Gui.OpenGLTools import ModelViewWindowGL
......@@ -43,6 +45,7 @@ from pycam.Geometry.Letters import TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, \
import pycam.Geometry.Model
from pycam.Toolpath import Bounds
import pycam.Utils.FontCache
import pycam.Plugins
from pycam import VERSION
import pycam.Physics.ode_physics
# this requires ODE - we import it later, if necessary
......@@ -66,28 +69,9 @@ import re
import os
import sys
DATA_DIR_ENVIRON_KEY = "PYCAM_DATA_DIR"
FONT_DIR_ENVIRON_KEY = "PYCAM_FONT_DIR"
DATA_BASE_DIRS = [os.path.realpath(os.path.join(os.path.dirname(__file__),
os.pardir, os.pardir, os.pardir, "share")),
os.path.join(sys.prefix, "local", "share", "pycam"),
os.path.join(sys.prefix, "share", "pycam")]
UI_SUBDIR = "ui"
FONTS_SUBDIR = "fonts"
# necessary for "pyinstaller"
if "_MEIPASS2" in os.environ:
DATA_BASE_DIRS.insert(0, os.path.join(os.path.normpath(os.environ["_MEIPASS2"]), "share"))
# respect an override via an environment setting
if DATA_DIR_ENVIRON_KEY in os.environ:
DATA_BASE_DIRS.insert(0, os.path.normpath(os.environ[DATA_DIR_ENVIRON_KEY]))
if FONT_DIR_ENVIRON_KEY in os.environ:
FONT_DIR_OVERRIDE = os.path.normpath(os.environ[FONT_DIR_ENVIRON_KEY])
else:
FONT_DIR_OVERRIDE = None
FONT_DIR_FALLBACK = "/usr/share/qcad/fonts"
GTKBUILD_FILE = os.path.join(UI_SUBDIR, "pycam-project.ui")
GTKMENU_FILE = os.path.join(UI_SUBDIR, "menubar.xml")
GTKBUILD_FILE = "pycam-project.ui"
GTKMENU_FILE = "menubar.xml"
WINDOW_ICON_FILENAMES = ["logo_%dpx.png" % pixels for pixels in (16, 32, 48, 64, 128)]
......@@ -176,21 +160,6 @@ GTK_COLOR_MAX = 65535.0
log = pycam.Utils.log.get_logger()
def get_data_file_location(filename, silent=False):
for base_dir in DATA_BASE_DIRS:
test_path = os.path.join(base_dir, filename)
if os.path.exists(test_path):
return test_path
else:
if not silent:
lines = []
lines.append("Failed to locate a resource file (%s) in %s!" \
% (filename, DATA_BASE_DIRS))
lines.append("You can extend the search path by setting the " \
+ "environment variable '%s'." % str(DATA_DIR_ENVIRON_KEY))
log.error(os.linesep.join(lines))
return None
def report_exception():
log.error("An unexpected exception occoured: please send the " \
+ "text below to the developers of PyCAM. Thanks a lot!" \
......@@ -212,8 +181,7 @@ def get_filters_from_list(filter_list):
def get_icons_pixbuffers():
result = []
for icon_filename in WINDOW_ICON_FILENAMES:
icon_subdir_filename = os.path.join(UI_SUBDIR, icon_filename)
abs_filename = get_data_file_location(icon_subdir_filename, silent=True)
abs_filename = get_ui_file_location(icon_filename, silent=True)
if abs_filename:
try:
result.append(gtk.gdk.pixbuf_new_from_file(abs_filename))
......@@ -225,29 +193,119 @@ def get_icons_pixbuffers():
log.debug("Failed to locate window icon: %s" % icon_filename)
return result
def get_font_dir():
if FONT_DIR_OVERRIDE:
if os.path.isdir(FONT_DIR_OVERRIDE):
return FONT_DIR_OVERRIDE
UI_FUNC_INDEX = 0
UI_WIDGET_INDEX = 1
WIDGET_NAME_INDEX = 0
WIDGET_OBJ_INDEX = 1
WIDGET_WEIGHT_INDEX = 2
HANDLER_FUNC_INDEX = 0
HANDLER_ARG_INDEX = 1
EVENT_HANDLER_INDEX = 0
EVENT_BLOCKER_INDEX = 1
class EventCore(pycam.Gui.Settings.Settings):
def __init__(self):
super(EventCore, self).__init__()
self.event_handlers = {}
self.ui_sections = {}
def register_event(self, event, func, *args):
if not event in self.event_handlers:
assert EVENT_HANDLER_INDEX == 0
assert EVENT_BLOCKER_INDEX == 1
self.event_handlers[event] = [[], 0]
assert HANDLER_FUNC_INDEX == 0
assert HANDLER_ARG_INDEX == 1
self.event_handlers[event][EVENT_HANDLER_INDEX].append((func, args))
def unregister_event(self, event, func):
if event in self.event_handlers:
removal_list = []
for index, item in enumerate(self.event_handlers[event][EVENT_HANDLER_INDEX]):
if func == item[HANDLER_FUNC_INDEX]:
removal_list.append(index)
removal_list.reverse()
for index in removal_list:
self.event_handlers[event].pop(index)
else:
log.warn(("You specified a font dir that does not exist (%s). " \
+ "I will ignore it.") % FONT_DIR_OVERRIDE)
font_dir = get_data_file_location(FONTS_SUBDIR, silent=True)
if not font_dir is None:
return font_dir
else:
log.warn(("Failed to locate the fonts directory '%s' below '%s'. " \
+ "Falling back to '%s'.") \
% (FONTS_SUBDIR, DATA_BASE_DIRS, FONT_DIR_FALLBACK))
if os.path.isdir(FONT_DIR_FALLBACK):
return FONT_DIR_FALLBACK
log.debug("Trying to unregister an unknown event: %s" % event)
def emit_event(self, event):
if event in self.event_handlers:
if self.event_handlers[event][EVENT_BLOCKER_INDEX] != 0:
return
self.block_event(event)
for handler in self.event_handlers[event][EVENT_HANDLER_INDEX]:
func = handler[HANDLER_FUNC_INDEX]
args = handler[HANDLER_ARG_INDEX]
# prevent infinite recursion
func(*args)
self.unblock_event(event)
else:
log.warn(("The fallback font directory (%s) does not exist. " \
+ "No fonts will be available.") % FONT_DIR_FALLBACK)
return None
log.debug("No events registered for event '%s'" % str(event))
def block_event(self, event):
if event in self.event_handlers:
self.event_handlers[event][EVENT_BLOCKER_INDEX] += 1
else:
log.debug("Trying to block an unknown event: %s" % str(event))
class ProjectGui:
def unblock_event(self, event):
if event in self.event_handlers:
if self.event_handlers[event][EVENT_BLOCKER_INDEX] > 0:
self.event_handlers[event][EVENT_BLOCKER_INDEX] -= 1
else:
log.debug("Trying to unblock non-blocked event '%s'" % str(event))
else:
log.debug("Trying to unblock an unknown event: %s" % str(event))
def register_ui_section(self, section, add_action, clear_action):
if not section in self.ui_sections:
self.ui_sections[section] = [None, None, None]
self.ui_sections[section][UI_WIDGET_INDEX] = []
self.ui_sections[section][UI_FUNC_INDEX] = (add_action, clear_action)
self._rebuild_ui_section(section)
def _rebuild_ui_section(self, section):
if section in self.ui_sections:
ui_section = self.ui_sections[section]
if ui_section[UI_FUNC_INDEX]:
add_func, clear_func = ui_section[UI_FUNC_INDEX]
ui_section[UI_WIDGET_INDEX].sort(key=lambda x: x[WIDGET_WEIGHT_INDEX])
clear_func()
for item in ui_section[UI_WIDGET_INDEX]:
add_func(item[WIDGET_OBJ_INDEX], item[WIDGET_NAME_INDEX])
else:
log.debug("Failed to rebuild unknown ui section: %s" % str(section))
def register_ui(self, section, name, widget, weight=0):
if not section in self.ui_sections:
self.ui_sections[section] = [None, []]
ui_section = self.ui_sections[section]
assert WIDGET_NAME_INDEX == 0
assert WIDGET_OBJ_INDEX == 1
assert WIDGET_WEIGHT_INDEX == 2
ui_section[UI_WIDGET_INDEX].append((name, widget, weight))
def unregister_ui(self, section, widget):
if (section in self.ui_sections) or (None in self.ui_sections):
if not section in self.ui_sections:
section = None
ui_section = self.ui_sections[section]
removal_list = []
for index, item in enumerate(ui_section[UI_WIDGET_INDEX]):
if item[WIDGET_OBJ_INDEX] == widget:
removal_list.append(index)
removal_list.reverse()
for index in removal_list:
ui_section[UI_WIDGET_INDEX].pop(index)
else:
log.debug("Trying to unregister unknown ui section: %s" % str(section))
class ProjectGui(object):
BOUNDARY_MODES = {
"inside": -1,
......@@ -262,7 +320,9 @@ class ProjectGui:
META_DATA_PREFIX = "PYCAM-META-DATA:"
def __init__(self, no_dialog=False):
self.settings = pycam.Gui.Settings.Settings()
self.settings = EventCore()
self.plugin_manager = pycam.Plugins.PluginManager(core=self.settings)
self.plugin_manager.import_plugins()
self.gui_is_active = False
self.view3d = None
# during initialization any dialog (e.g. "Unit change") is not allowed
......@@ -276,7 +336,7 @@ class ProjectGui:
self._fonts_cache = pycam.Utils.FontCache.FontCache(get_font_dir(),
callback=self.update_progress_bar)
self.gui = gtk.Builder()
gtk_build_file = get_data_file_location(GTKBUILD_FILE)
gtk_build_file = get_ui_file_location(GTKBUILD_FILE)
if gtk_build_file is None:
gtk.main_quit()
self.gui.add_from_file(gtk_build_file)
......@@ -361,6 +421,16 @@ class ProjectGui:
gtk.accel_map_change_entry(accel_path, key, mod, True)
# no undo is allowed at the beginning
self.gui.get_object("UndoButton").set_sensitive(False)
self.settings.register_event("model-change-before", self._store_undo_state)
self.settings.register_event("model-change-after", self.update_model_dimensions)
self.settings.register_event("model-change-after", self.update_support_model)
self.settings.register_event("model-change-after", self.update_save_actions)
self.settings.register_event("model-change-after", self.update_model_type_related_controls)
self.settings.register_event("model-change-after", self.update_support_controls)
self.settings.register_event("model-change-after", self.update_view)
self.settings.set("update_progress", self.update_progress_bar)
self.settings.set("disable_progress_cancel_button", self.disable_progress_cancel_button)
self.settings.set("load_model", self.load_model)
# configure drag-n-drop for config files and models
self.configure_drag_and_drop(self.window)
self.clipboard = gtk.clipboard_get()
......@@ -405,19 +475,6 @@ class ProjectGui:
self.gui.get_object("ProcessPoolWindowClose").connect("clicked", self.toggle_process_pool_window, False)
self.gui.get_object("ProcessPoolRefreshInterval").set_value(3)
self.process_pool_model = self.gui.get_object("ProcessPoolStatisticsModel")
# extrusion dialog
self._extrusion_dialog_position = None
self._extrusion_dialog_visible = False
self.extrusion_dialog_window = self.gui.get_object("ExtrusionDialog")
self.extrusion_dialog_window.connect("delete-event",
self.toggle_extrusion_dialog, False)
self.gui.get_object("ExtrusionCancel").connect("clicked",
self.toggle_extrusion_dialog, False)
self.gui.get_object("ExtrusionSubmit").connect("clicked",
self.extrude_model)
self.gui.get_object("ExtrusionHeight").set_value(1)
self.gui.get_object("ExtrusionWidth").set_value(1)
self.gui.get_object("ExtrusionGrid").set_value(0.5)
# "font dialog" window
self.font_dialog_window = self.gui.get_object("FontDialog")
self.font_dialog_window.connect("delete-event",
......@@ -470,6 +527,14 @@ class ProjectGui:
self.settings.add_item("model", lambda: self.model)
self.settings.add_item("toolpath", lambda: self.toolpath)
self.settings.add_item("cutter", lambda: self.cutter)
model_handling_obj = self.gui.get_object("ModelHandlingNotebook")
def clear_model_handling_obj():
for index in range(model_handling_obj.get_n_pages()):
model_handling_obj.remove_page(0)
def add_model_handling_item(item, name):
model_handling_obj.append_page(item, gtk.Label(name))
self.settings.register_ui_section("model_handling",
add_model_handling_item, clear_model_handling_obj)
# unit control (mm/inch)
unit_field = self.gui.get_object("unit_control")
unit_field.connect("changed", self.change_unit_init)
......@@ -544,52 +609,6 @@ class ProjectGui:
# create a new variable "key" to avoid re-using the same object "key"
# (due to the lambda name scope)
self.settings.add_item(key, lambda key=key: get_absolute_limit(key))
# Transformations
self.gui.get_object("Rotate").connect("clicked", self.transform_model)
self.gui.get_object("Flip").connect("clicked", self.transform_model)
self.gui.get_object("Swap").connect("clicked", self.transform_model)
shift_model_button = self.gui.get_object("Shift Model")
shift_model_button.connect("clicked", self.shift_model, True)
# Make the "shift" button the default while one of the x/y/z values is
# active.
for objname in ("shift_x", "shift_y", "shift_z"):
self.gui.get_object(objname).connect("focus-in-event",
lambda widget, data: shift_model_button.grab_default())
self.gui.get_object(objname).connect("focus-out-event",
lambda widget, data: self.window.set_default(None))
self.gui.get_object("Shift To Origin").connect("clicked",
self.shift_model, False)
# scale model
scale_percent = self.gui.get_object("ScalePercent")
scale_button = self.gui.get_object("ScaleModelButton")
scale_percent.set_value(100)
scale_percent.connect("focus-in-event",
lambda widget, data: scale_button.grab_default())
scale_percent.connect("focus-out-event",
lambda widget, data: self.window.set_default(None))
scale_button.connect("clicked", self.scale_model)
# scale model to an axis dimension
self.gui.get_object("ScaleDimensionAxis").connect("changed",
self.update_model_dimensions)
scale_dimension_button = self.gui.get_object("ScaleDimensionButton")
scale_dimension_button.connect("clicked", self.scale_model_axis_fit)
scale_dimension_control = self.gui.get_object("ScaleDimensionControl")
scale_dimension_control.connect("focus-in-event",
lambda widget, data: scale_dimension_button.grab_default())
scale_dimension_control.connect("focus-out-event",
lambda widget, data: self.window.set_default(None))
self.gui.get_object("ToggleModelDirectionButton").connect("clicked",
self.reverse_model_direction)
self.gui.get_object("DirectionsGuessButton").connect("clicked",
self.guess_model_directions)
self.gui.get_object("ScaleInchMM").connect("clicked", self.scale_model,
100 * 25.4, False)
self.gui.get_object("ScaleMMInch").connect("clicked", self.scale_model,
100 / 25.4, False)
self.gui.get_object("Projection2D").connect("clicked",
self.projection_2d)
self.gui.get_object("ExtrudeButton").connect("clicked",
self.toggle_extrusion_dialog, True)
# support grid
support_grid_type_control = self.gui.get_object(
"SupportGridTypesControl")
......@@ -1085,7 +1104,7 @@ class ProjectGui:
# set the icons (in different sizes) for all windows
gtk.window_set_default_icon_list(*get_icons_pixbuffers())
# load menu data
gtk_menu_file = get_data_file_location(GTKMENU_FILE)
gtk_menu_file = get_ui_file_location(GTKMENU_FILE)
if gtk_menu_file is None:
gtk.main_quit()
uimanager.add_ui_from_file(gtk_menu_file)
......@@ -1200,27 +1219,6 @@ class ProjectGui:
getattr(self.gui.get_object(objname), update_func)()
def update_model_type_related_controls(self):
is_reversible = (not self.model is None) \
and hasattr(self.model, "reverse_directions")
controls_2d = ("ToggleModelDirectionButton", "DirectionsGuessButton")
for control in controls_2d:
if is_reversible:
self.gui.get_object(control).show()
else:
self.gui.get_object(control).hide()
is_extrudable = (not self.model is None) \
and hasattr(self.model, "extrude")
extrude_button = self.gui.get_object("ExtrudeButton")
if is_extrudable:
extrude_button.show()
else:
extrude_button.hide()
is_projectable = (not self.model is None) \
and hasattr(self.model, "get_waterline_contour")
if is_projectable:
self.gui.get_object("Projection2D").show()
else:
self.gui.get_object("Projection2D").hide()
# disable the lower boundary for contour models
is_contour = isinstance(self.model, pycam.Geometry.Model.ContourModel)
self.gui.get_object("boundary_z_low").set_sensitive(not is_contour)
......@@ -1286,7 +1284,7 @@ class ProjectGui:
self.gui.get_object("UndoButton").set_sensitive(
len(self._undo_states) > 0)
log.info("Restored the previous state of the model")
self._update_all_model_attributes()
self.settings.emit_event("model-change-after")
else:
log.info("No previous undo state available - request ignored")
......@@ -1315,7 +1313,7 @@ class ProjectGui:
else:
short_name = os.path.basename(uri.get_path())
self.window.set_title("%s - PyCAM" % short_name)
self.update_save_actions()
self.settings.emit_event("model-change-after")
def update_save_actions(self):
self.gui.get_object("SaveTaskSettings").set_sensitive(
......@@ -1372,8 +1370,7 @@ class ProjectGui:
obj.show()
else:
obj.hide()
self.update_support_model()
self.update_view()
self.settings.emit_event("model-change-after")
def update_support_model(self, widget=None):
grid_type = self.settings.get("support_grid_type")
......@@ -1426,7 +1423,7 @@ class ProjectGui:
elif grid_type == GRID_TYPES["none"]:
pass
s.set("support_grid", support_grid)
self.update_view()
self.settings.emit_event("model-change-after")
def switch_support_grid_manual_selector(self, widget=None):
old_axis_was_x = self.grid_adjustment_axis_x_last
......@@ -1463,8 +1460,7 @@ class ProjectGui:
if not tree_iter is None:
value_string = "(%+.1f)" % new_value
self.grid_adjustment_model.set(tree_iter, 1, value_string)
self.update_support_model()
self.update_view()
self.settings.emit_event("model-change-after")
def reset_support_grid_manual(self, widget=None, reset_all=False):
if reset_all:
......@@ -1474,8 +1470,7 @@ class ProjectGui:
self.settings.set("support_grid_adjustment_value", 0)
self.update_support_grid_manual_model()
self.switch_support_grid_manual_selector()
self.update_support_model()
self.update_view()
self.settings.emit_event("model-change-after")
def update_support_grid_manual_model(self):
old_index = self.grid_adjustment_selector.get_active()
......@@ -1695,8 +1690,7 @@ class ProjectGui:
# update the values in the manual support grid adjustment list
self.update_support_grid_manual_model()
# the support grid depends on the boundary
self.update_support_model()
self.update_view()
self.settings.emit_event("model-change-after")
def update_tasklist_controls(self):
# en/disable some buttons
......@@ -2192,52 +2186,6 @@ class ProjectGui:
# don't close the window - just hide it (for "delete-event")
return True
@progress_activity_guard
@gui_activity_guard
def extrude_model(self, widget=None):
self.update_progress_bar("Calculating extrusion")
extrusion_type_selector = self.gui.get_object("ExtrusionTypeSelector")
type_model = extrusion_type_selector.get_model()
type_active = extrusion_type_selector.get_active()
if type_active >= 0:
type_string = type_model[type_active][0]
height = self.gui.get_object("ExtrusionHeight").get_value()
width = self.gui.get_object("ExtrusionWidth").get_value()
grid_size = self.gui.get_object("ExtrusionGrid").get_value()
if type_string == "radius_up":
func = lambda x: height * math.sqrt((width ** 2 - max(0, width - x) ** 2))
elif type_string == "radius_down":
func = lambda x: height * (1 - math.sqrt((width ** 2 - min(width, x) ** 2)) / width)
elif type_string == "skewed":
func = lambda x: height * min(1, x / width)
else:
log.error("Unknown extrusion type selected: %s" % type_string)
return
self.toggle_extrusion_dialog(False)
model = self.model.extrude(stepping=grid_size, func=func,
callback=self.update_progress_bar)
if model:
self.load_model(model)
else:
self.toggle_extrusion_dialog(True)
def toggle_extrusion_dialog(self, widget=None, event=None, state=None):
if state is None:
# the "delete-event" issues the additional "event" argument
state = event
if state is None:
state = not self._extrusion_dialog_visible
if state:
if self._extrusion_dialog_position:
self.extrusion_dialog_window.move(*self._extrusion_dialog_position)
self.extrusion_dialog_window.show()
else:
self._extrusion_dialog_position = self.extrusion_dialog_window.get_position()
self.extrusion_dialog_window.hide()
self._extrusion_dialog_visible = state
# don't close the window - just hide it (for "delete-event")
return True
@gui_activity_guard
def toggle_preferences_window(self, widget=None, event=None, state=None):
if state is None:
......@@ -2424,37 +2372,13 @@ class ProjectGui:
else:
# the window is just hidden
self.view3d.show()
self.update_view()
self.settings.emit_event("model-change-after")
else:
self.view3d.hide()
# enable the toggle button only, if the 3d view is available
# (e.g. disabled if no OpenGL support is available)
toggle_3d_checkbox.set_active(self.view3d.enabled and new_state)
@progress_activity_guard
@gui_activity_guard
def transform_model(self, widget):
if widget is self.gui.get_object("Rotate"):
controls = (("x-axis", "x"), ("y-axis", "y"), ("z-axis", "z"))
elif widget is self.gui.get_object("Flip"):
controls = (("xy-plane", "xy"), ("xz-plane", "xz"), ("yz-plane", "yz"))
elif widget is self.gui.get_object("Swap"):
controls = (("x <-> y", "x_swap_y"), ("x <-> z", "x_swap_z"), ("y <-> z", "y_swap_z"))
else:
# broken gui
log.warn("Unknown button action: %s" % str(widget.get_name()))
return
for obj, value in controls:
if self.gui.get_object(obj).get_active():
self._store_undo_state()
self.disable_progress_cancel_button()
self.update_progress_bar("Transforming model")
self.model.transform_by_template(value,
callback=self.update_progress_bar)
self.append_to_queue(self.update_support_model)
self.append_to_queue(self.update_model_dimensions)
self.append_to_queue(self.update_view)
def _treeview_get_active_index(self, table, datalist):
if len(datalist) == 0:
result = None
......@@ -2697,7 +2621,7 @@ class ProjectGui:
# transform the model if it is selected
# keep the original center of the model
old_center = self._get_model_center()
self._store_undo_state()
self.settings.emit_event("model-change-before")
self.model.scale(factor)
self._set_model_center(old_center)
if self.gui.get_object("UnitChangeProcesses").get_active():
......@@ -2745,7 +2669,7 @@ class ProjectGui:
self.switch_bounds_table_selection()
self.switch_tasklist_table_selection()
# redraw the model
self.update_view()
self.settings.emit_event("model-change-after")
def update_unit_labels(self, widget=None, data=None):
# don't use the "unit" setting, since we need the plural of "inch"
......@@ -2842,7 +2766,7 @@ class ProjectGui:
for key, value in PREFERENCES_DEFAULTS.items():
self.settings.set(key, value)
# redraw the model due to changed colors, display items ...
self.update_view()
self.settings.emit_event("model-change-after")
def load_preferences(self):
""" load all settings that are available in the Preferences window from
......@@ -2893,26 +2817,6 @@ class ProjectGui:
except IOError, err_msg:
log.warn("Failed to write preferences file (%s): %s" % (config_filename, err_msg))
@progress_activity_guard
@gui_activity_guard
def shift_model(self, widget, use_form_values=True):
if use_form_values:
shift_x = self.gui.get_object("shift_x").get_value()
shift_y = self.gui.get_object("shift_y").get_value()
shift_z = self.gui.get_object("shift_z").get_value()
else:
shift_x = -self.model.minx
shift_y = -self.model.miny
shift_z = -self.model.minz
self._store_undo_state()
self.update_progress_bar("Shifting model")
self.disable_progress_cancel_button()
self.model.shift(shift_x, shift_y, shift_z,
callback=self.update_progress_bar)
self.append_to_queue(self.update_support_model)
self.append_to_queue(self.update_model_dimensions)
self.append_to_queue(self.update_view)
def _get_model_center(self):
if self.model is None:
return None
......@@ -2929,65 +2833,10 @@ class ProjectGui:
self.model.shift(new_x - old_x, new_y - old_y, new_z - old_z,
callback=self.update_progress_bar)
def _get_projection_plane(self):
# determine projection plane
if (self.model.maxz < 0) or (self.model.minz > 0):
# completely above or below zero
plane_z = self.model.minz
else:
plane_z = 0
return Plane(Point(0, 0, plane_z), Vector(0, 0, 1))
@progress_activity_guard
@gui_activity_guard
def projection_2d(self, widget=None):
self.update_progress_bar("Calculating 2D projection")
plane = self._get_projection_plane()
log.info("Projecting 3D model at level z=%g" % plane.p.z)
projection = self.model.get_waterline_contour(plane)
if projection.get_num_of_lines() > 0:
self.load_model(projection)
else:
log.warn("The 2D projection at z=%g is empty. Aborted." % plane.p.z)
@progress_activity_guard
@gui_activity_guard
def scale_model(self, widget=None, percent=None, keep_center=True):
if percent is None:
percent = self.gui.get_object("ScalePercent").get_value()
factor = percent / 100.0
if (factor <= 0) or (factor == 1):
return
old_center = self._get_model_center()
self._store_undo_state()
self.update_progress_bar("Scaling model")
self.disable_progress_cancel_button()
self.model.scale(factor, callback=self.update_progress_bar)
if keep_center:
self._set_model_center(old_center)
self.append_to_queue(self.update_model_dimensions)
self.append_to_queue(self.update_support_model)
self.append_to_queue(self.update_view)
@gui_activity_guard
def update_model_dimensions(self, widget=None):
if self.model is None:
return
# scale controls
axis_control = self.gui.get_object("ScaleDimensionAxis")
scale_button = self.gui.get_object("ScaleDimensionButton")
scale_value = self.gui.get_object("ScaleDimensionControl")
index = axis_control.get_active()
dims = (self.model.maxx - self.model.minx,
self.model.maxy - self.model.miny,
self.model.maxz - self.model.minz)
value = dims[index]
non_zero_dimensions = [i for i, dim in enumerate(dims) if dim > 0]
enable_controls = index in non_zero_dimensions
scale_button.set_sensitive(enable_controls)
scale_value.set_sensitive(enable_controls)
scale_value.set_value(value)
# model corners in 3D view
for attr, label_suffix in (("minx", "XMin"), ("miny", "YMin"),
("minz", "ZMin"), ("maxx", "XMax"), ("maxy", "YMax"),
......@@ -2996,62 +2845,6 @@ class ProjectGui:
value = "%.3f" % getattr(self.model, attr)
self.gui.get_object(label_name).set_label(value)
@progress_activity_guard
@gui_activity_guard
def guess_model_directions(self, widget=None):
if (self.model is None) \
or not hasattr(self.model, "reverse_directions"):
return
self._store_undo_state()
self.update_progress_bar(text="Analyzing directions of contour model")
self.model.revise_directions(callback=self.update_progress_bar)
self.update_support_model()
@progress_activity_guard
@gui_activity_guard
def reverse_model_direction(self, widget=None):
if (self.model is None) \
or not hasattr(self.model, "reverse_directions"):
return
self._store_undo_state()
self.update_progress_bar(text="Reversing directions of contour model")
self.model.reverse_directions(callback=self.update_progress_bar)
self.update_support_model()
@progress_activity_guard
@gui_activity_guard
def scale_model_axis_fit(self, widget=None):
proportionally = self.gui.get_object("ScaleDimensionsProportionally").get_active()
value = self.gui.get_object("ScaleDimensionValue").get_value()
index = self.gui.get_object("ScaleDimensionAxis").get_active()
axes = "xyz"
axis_suffix = axes[index]
factor = value / (getattr(self.model, "max" + axis_suffix) - getattr(self.model, "min" + axis_suffix))
# store the original center of the model
old_center = self._get_model_center()
self._store_undo_state()
self.update_progress_bar("Scaling model")
self.disable_progress_cancel_button()
if proportionally:
self.model.scale(factor, callback=self.update_progress_bar)
else:
factor_x, factor_y, factor_z = (1, 1, 1)
if index == 0:
factor_x = factor
elif index == 1:
factor_y = factor
elif index == 2:
factor_z = factor
else:
return
self.model.scale(factor_x, factor_y, factor_z,
callback=self.update_progress_bar)
# move the model to its previous center
self._set_model_center(old_center)
self.append_to_queue(self.update_support_model)
self.append_to_queue(self.update_model_dimensions)
self.append_to_queue(self.update_view)
def destroy(self, widget=None, data=None):
self.update_view()
# check if there is a running process
......@@ -3212,22 +3005,14 @@ class ProjectGui:
self.add_to_recent_file_list(filename)
self.update_save_actions()
def _update_all_model_attributes(self):
self.append_to_queue(self.update_model_dimensions)
self.append_to_queue(self.update_model_type_related_controls)
self.append_to_queue(self.update_save_actions)
self.append_to_queue(self.update_support_controls)
self.append_to_queue(self.toggle_3d_view, value=True)
self.append_to_queue(self.update_view)
def load_model(self, model):
# load the new model only if the import worked
if not model is None:
self._store_undo_state()
self.settings.emit_event("model-change-before")
self.model = model
self.last_model_uri = None
# do some initialization
self._update_all_model_attributes()
self.settings.emit_event("model-change-after")
if self.model and self.view3d and self.view3d.enabled:
self.append_to_queue(self.view3d.reset_view)
return True
......@@ -3967,7 +3752,7 @@ class ProjectGui:
start_time = time.time()
self.update_progress_bar("Preparing toolpath generation")
parent = self
class UpdateView:
class UpdateView(object):
def __init__(self, func, max_fps=1):
self.last_update = time.time()
self.max_fps = max_fps
......
......@@ -60,7 +60,7 @@ def get_config_filename(filename=None):
return os.path.join(config_dir, filename)
class Settings:
class Settings(object):
GET_INDEX = 0
SET_INDEX = 1
......@@ -118,7 +118,7 @@ class Settings:
return self.items.keys()
class ProcessSettings:
class ProcessSettings(object):
BASIC_DEFAULT_CONFIG = """
[ToolDefault]
......@@ -556,7 +556,7 @@ process: 3
return os.linesep.join(result)
class ToolpathSettings:
class ToolpathSettings(object):
SECTIONS = {
"Bounds": {
......
......@@ -193,7 +193,7 @@ def keyPressed(key, x, y):
elif _KeyHandlerFunc:
_KeyHandlerFunc(key, x, y)
class mouseState:
class mouseState(object):
button = None
state = None
x = 0
......
......@@ -150,7 +150,7 @@ def get_dependency_report(details, prefix=""):
return os.linesep.join(result)
class EmergencyDialog:
class EmergencyDialog(object):
""" This graphical message window requires no external dependencies.
The Tk interface package is part of the main python distribution.
Use this class for displaying dependency errors (especially on Windows).
......
......@@ -72,7 +72,7 @@ def _process_one_triangle((model, cutter, up_vector, triangle, z)):
return result, None
class CollisionPaths:
class CollisionPaths(object):
def __init__(self):
self.waterlines = []
......@@ -193,7 +193,7 @@ class CollisionPaths:
return result
class ContourFollow:
class ContourFollow(object):
def __init__(self, cutter, models, path_processor, physics=None):
self.cutter = cutter
......
......@@ -39,7 +39,7 @@ def _process_one_grid_line((positions, minz, maxz, model, cutter, physics)):
return get_max_height_dynamic(model, cutter, positions, minz, maxz, physics)
class Dimension:
class Dimension(object):
def __init__(self, start, end):
self.start = float(start)
self.end = float(end)
......@@ -70,7 +70,7 @@ class Dimension:
return self.value
class DropCutter:
class DropCutter(object):
def __init__(self, cutter, models, path_processor, physics=None):
self.cutter = cutter
......
......@@ -35,7 +35,7 @@ import pycam.Utils.log
log = pycam.Utils.log.get_logger()
class EngraveCutter:
class EngraveCutter(object):
def __init__(self, cutter, trimesh_models, contour_model, path_processor,
clockwise=False, physics=None):
......
......@@ -43,7 +43,7 @@ def _process_one_line((p1, p2, depth, models, cutter, physics)):
return points
class PushCutter:
class PushCutter(object):
def __init__(self, cutter, models, path_processor, physics=None):
if physics is None:
......
......@@ -28,7 +28,7 @@ from pycam.Geometry.Point import Point
import pycam.Utils.threading
class Hit:
class Hit(object):
def __init__(self, cl, cp, t, d, direction):
self.cl = cl
self.cp = cp
......
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import math
import pycam.Plugins
import pycam.Utils.log
log = pycam.Utils.log.get_logger()
class ModelExtrusion(pycam.Plugins.PluginBase):
UI_FILE = "model_extrusion.ui"
def setup(self):
if self.gui:
extrusion_frame = self.gui.get_object("ModelExtrusionFrame")
extrusion_frame.unparent()
self.core.register_event("model-change-after",
self._update_extrude_widgets)
self.core.register_ui("model_handling", "Extrusion",
extrusion_frame, 5)
self.gui.get_object("ExtrudeButton").connect("clicked",
self._extrude_model)
self.gui.get_object("ExtrusionHeight").set_value(1)
self.gui.get_object("ExtrusionWidth").set_value(1)
self.gui.get_object("ExtrusionGrid").set_value(0.5)
return True
def teardown(self):
if self.gui:
self.core.unregister_ui("model_handling",
self.gui.get_object("ModelExtrusionFrame"))
self.core.unregister_event("model-change-after",
self._update_extrude_widgets)
def _update_extrude_widgets(self):
model = self.core.get("model")
is_extrudable = (not model is None) \
and hasattr(model, "extrude")
extrude_widget = self.gui.get_object("ModelExtrusionFrame")
if is_extrudable:
extrude_widget.show()
else:
extrude_widget.hide()
def _extrude_model(self, widget=None):
model = self.core.get("model")
if not model:
return
self.core.get("update_progress")("Extruding model")
extrusion_type_selector = self.gui.get_object("ExtrusionTypeSelector")
type_model = extrusion_type_selector.get_model()
type_active = extrusion_type_selector.get_active()
if type_active >= 0:
type_string = type_model[type_active][0]
height = self.gui.get_object("ExtrusionHeight").get_value()
width = self.gui.get_object("ExtrusionWidth").get_value()
grid_size = self.gui.get_object("ExtrusionGrid").get_value()
if type_string == "radius_up":
func = lambda x: height * math.sqrt((width ** 2 - max(0, width - x) ** 2))
elif type_string == "radius_down":
func = lambda x: height * (1 - math.sqrt((width ** 2 - min(width, x) ** 2)) / width)
elif type_string == "skewed":
func = lambda x: height * min(1, x / width)
else:
log.error("Unknown extrusion type selected: %s" % type_string)
return
new_model = model.extrude(stepping=grid_size, func=func,
callback=self.core.get("update_progress"))
if new_model:
self.core.get("load_model")(new_model)
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Plugins
class ModelPlaneMirror(pycam.Plugins.PluginBase):
UI_FILE = "model_plane_mirror.ui"
def setup(self):
if self.gui:
mirror_box = self.gui.get_object("ModelMirrorBox")
mirror_box.unparent()
self.core.register_ui("model_handling", "Mirror", mirror_box, 0)
self.gui.get_object("PlaneMirrorButton").connect("clicked",
self._plane_mirror)
return True
def teardown(self):
if self.gui:
self.core.unregister_ui("model_handling",
self.gui.get_object("ModelMirrorBox"))
def _plane_mirror(self, widget=None):
model = self.core.get("model")
if not model:
return
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Mirroring model")
self.core.get("disable_progress_cancel_button")()
for plane in ("XY", "XZ", "YZ"):
if self.gui.get_object("MirrorPlane%s" % plane).get_active():
break
model.transform_by_template("%s_mirror" % plane.lower(),
callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after")
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Plugins
class ModelPolygons(pycam.Plugins.PluginBase):
UI_FILE = "model_polygons.ui"
def setup(self):
if self.gui:
polygon_frame = self.gui.get_object("ModelPolygonFrame")
polygon_frame.unparent()
self.core.register_ui("model_handling", "Polygons", polygon_frame, 0)
self.core.register_event("model-change-after",
self._update_polygon_controls)
self.gui.get_object("ToggleModelDirectionButton").connect("clicked",
self._toggle_direction)
self.gui.get_object("DirectionsGuessButton").connect("clicked",
self._revise_directions)
return True
def teardown(self):
if self.gui:
self.core.unregister_ui("model_handling",
self.gui.get_object("ModelPolygonFrame"))
def _update_polygon_controls(self):
model = self.core.get("model")
is_reversible = model and hasattr(model, "reverse_directions")
frame = self.gui.get_object("ModelPolygonFrame")
if is_reversible:
frame.show()
else:
frame.hide()
def _toggle_direction(self, widget=None):
model = self.core.get("model")
if not model or not hasattr(model, "reverse_directions"):
return
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Reversing directions of contour model")
model.reverse_directions(callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after")
def _revise_directions(self, widget=None):
model = self.core.get("model")
if not model or not hasattr(model, "revise_directions"):
return
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Analyzing directions of contour model")
model.revise_directions(callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after")
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Plugins
class ModelPosition(pycam.Plugins.PluginBase):
UI_FILE = "model_position.ui"
def setup(self):
if self.gui:
position_box = self.gui.get_object("ModelPositionBox")
position_box.unparent()
self.core.register_ui("model_handling", "Position", position_box, -20)
shift_model_button = self.gui.get_object("ShiftModelButton")
shift_model_button.connect("clicked", self._shift_model)
align_model_button = self.gui.get_object("AlignPositionButton")
align_model_button.connect("clicked", self._align_model)
# grab default button for shift/align controls
for axis in "XYZ":
obj = self.gui.get_object("ShiftPosition%s" % axis)
obj.connect("focus-in-event", lambda widget, data: \
shift_model_button.grab_default())
obj.connect("focus-out-event", lambda widget, data: \
shift_model_button.get_toplevel().set_default(None))
for axis in "XYZ":
for name_template in ("AlignPosition%s", "AlignPosition%sMin",
"AlignPosition%sCenter", "AlignPosition%sMax"):
obj = self.gui.get_object("AlignPosition%s" % axis)
obj.connect("focus-in-event", lambda widget, data: \
align_model_button.grab_default())
obj.connect("focus-out-event", lambda widget, data: \
align_model_button.get_toplevel().set_default(None))
return True
def teardown(self):
if self.gui:
self.core.unregister_ui("model_handling",
self.gui.get_object("ModelPositionBox"))
def _shift_model(self, widget=None):
model = self.core.get("model")
if not model:
return
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Aligning model")
self.core.get("disable_progress_cancel_button")()
shift = [self.gui.get_object("ShiftPosition%s" % axis).get_value()
for axis in "XYZ"]
model.shift(shift[0], shift[1], shift[2],
callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after")
def _align_model(self, widget=None):
model = self.core.get("model")
if not model:
return
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Shifting model")
self.core.get("disable_progress_cancel_button")()
dest = [self.gui.get_object("AlignPosition%s" % axis).get_value()
for axis in "XYZ"]
shift_values = []
for axis in "XYZ":
dest = self.gui.get_object("AlignPosition%s" % axis).get_value()
alignments = ("Min", "Center", "Max")
for alignment in alignments:
objname = "AlignPosition%s%s" % (axis, alignment)
min_axis = getattr(model, "min%s" % axis.lower())
max_axis = getattr(model, "max%s" % axis.lower())
if self.gui.get_object(objname).get_active():
if alignment == "Min":
shift = dest - min_axis
elif alignment == "Center":
shift = dest - (min_axis + max_axis) / 2.0
else:
shift = dest - max_axis
shift_values.append(shift)
model.shift(shift_values[0], shift_values[1], shift_values[2],
callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after")
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Plugins
from pycam.Geometry.Plane import Plane
from pycam.Geometry.Point import Point, Vector
import pycam.Utils.log
log = pycam.Utils.log.get_logger()
class ModelProjection(pycam.Plugins.PluginBase):
UI_FILE = "model_projection.ui"
def setup(self):
if self.gui:
projection_frame = self.gui.get_object("ModelProjectionFrame")
projection_frame.unparent()
self.core.register_ui("model_handling", "Projection",
projection_frame, 10)
self.core.register_event("model-change-after",
self._update_controls)
self.gui.get_object("ProjectionButton").connect("clicked",
self._projection)
return True
def teardown(self):
if self.gui:
self.core.unregister_ui("model_handling",
self.gui.get_object("ModelProjectionFrame"))
self.core.unregister_event("model-change-after",
self._update_controls)
def _update_controls(self):
model = self.core.get("model")
is_projectable = model and hasattr(model, "get_waterline_contour")
control = self.gui.get_object("ModelProjectionFrame")
if is_projectable:
control.show()
else:
control.hide()
def _projection(self, widget=None):
model = self.core.get("model")
if not model or not hasattr(model, "get_waterline_contour"):
return
self.core.get("update_progress")("Calculating 2D projection")
for objname, z_level in (("ProjectionModelTop", model.maxz),
("ProjectionModelMiddle", (model.minz + model.maxz) / 2.0),
("ProjectionModelBottom", model.minz),
("ProjectionModelCustom",
self.gui.get_object("ProjectionZLevel").get_value())):
plane = Plane(Point(0, 0, z_level), Vector(0, 0, 1))
log.info("Projecting 3D model at level z=%g" % plane.p.z)
projection = model.get_waterline_contour(plane)
if projection:
self.core.get("load_model")(projection)
else:
log.warn("The 2D projection at z=%g is empty. Aborted." % \
plane.p.z)
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Plugins
import pycam.Geometry.Matrix
class ModelRotation(pycam.Plugins.PluginBase):
UI_FILE = "model_rotation.ui"
def setup(self):
if self.gui:
rotation_box = self.gui.get_object("ModelRotationBox")
rotation_box.unparent()
self.core.register_ui("model_handling", "Rotation", rotation_box,
-10)
self.gui.get_object("RotateModelButton").connect("clicked",
self._rotate_model)
return True
def teardown(self):
if self.gui:
self.core.unregister_ui("model_handling",
self.gui.get_object("ModelRotationBox"))
def _rotate_model(self, widget=None):
model = self.core.get("model")
if not model:
return
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Rotating model")
self.core.get("disable_progress_cancel_button")()
for axis in "XYZ":
if self.gui.get_object("RotationAxis%s" % axis).get_active():
break
axis_vector = {"X": (1, 0, 0), "Y": (0, 1, 0), "Z": (0, 0, 1)}[axis]
for control, angle in (("RotationAngle90CCKW", -90),
("RotationAngle90CKW", 90),
("RotationAngle180", 180),
("RotationAngleCustomCKW",
self.gui.get_object("RotationAngle").get_value())):
if self.gui.get_object(control).get_active():
break
matrix = pycam.Geometry.Matrix.get_rotation_matrix_axis_angle(
axis_vector, angle, use_radians=False)
model.transform_by_matrix(matrix,
callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after")
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Plugins
class ModelScaling(pycam.Plugins.PluginBase):
UI_FILE = "model_scaling.ui"
def setup(self):
if self.gui:
scale_box = self.gui.get_object("ModelScaleBox")
scale_box.unparent()
self.core.register_ui("model_handling", "Scale", scale_box, -5)
self.core.register_event("model-change-after",
self._update_scale_dimensions)
update_model = lambda widget=None: self.core.emit_event(
"model-change-after")
scale_percent = self.gui.get_object("ScalePercent")
scale_button = self.gui.get_object("ScaleModelButton")
scale_percent.set_value(100)
scale_percent.connect("focus-in-event",
lambda widget, data: scale_button.grab_default())
scale_percent.connect("focus-out-event", lambda widget, data: \
scale_box.get_toplevel().set_default(None))
scale_button.connect("clicked", self._scale_model)
# scale model to an axis dimension
self.gui.get_object("ScaleDimensionAxis").connect("changed",
update_model)
scale_dimension_button = self.gui.get_object("ScaleAllAxesButton")
scale_dimension_control = self.gui.get_object(
"ScaleDimensionControl")
scale_dimension_control.connect("focus-in-event",
lambda widget, data: scale_dimension_button.grab_default())
scale_dimension_control.connect("focus-out-event",
lambda widget, data: \
scale_box.get_toplevel().set_default(None))
scale_dimension_button.connect("clicked",
self._scale_model_axis_fit, True)
self.gui.get_object("ScaleSelectedAxisButton").connect("clicked",
self._scale_model_axis_fit, False)
self.gui.get_object("ScaleInchMM").connect("clicked",
self._scale_model, 100 * 25.4)
self.gui.get_object("ScaleMMInch").connect("clicked",
self._scale_model, 100 / 25.4)
return True
def teardown(self):
if self.gui:
self.core.unregister_ui("model_handling",
self.gui.get_object("ModelScaleBox"))
def _update_scale_dimensions(self):
model = self.core.get("model")
if not model:
return
# scale controls
axis_control = self.gui.get_object("ScaleDimensionAxis")
scale_button = self.gui.get_object("ScaleSelectedAxisButton")
scale_value = self.gui.get_object("ScaleDimensionControl")
index = axis_control.get_active()
dims = (model.maxx - model.minx, model.maxy - model.miny,
model.maxz - model.minz)
value = dims[index]
non_zero_dimensions = [i for i, dim in enumerate(dims) if dim > 0]
enable_controls = index in non_zero_dimensions
scale_button.set_sensitive(enable_controls)
scale_value.set_sensitive(enable_controls)
scale_value.set_value(value)
def _scale_model(self, widget=None, percent=None):
model = self.core.get("model")
if not model:
return
if percent is None:
percent = self.gui.get_object("ScalePercent").get_value()
factor = percent / 100.0
if (factor <= 0) or (factor == 1):
return
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Scaling model")
self.core.get("disable_progress_cancel_button")()
model.scale(factor, callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after")
def _scale_model_axis_fit(self, widget=None, proportionally=False):
model = self.core.get("model")
if not model:
return
value = self.gui.get_object("ScaleDimensionValue").get_value()
index = self.gui.get_object("ScaleDimensionAxis").get_active()
axes = "xyz"
axis_suffix = axes[index]
factor = value / (getattr(model, "max" + axis_suffix) - \
getattr(model, "min" + axis_suffix))
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Scaling model")
self.core.get("disable_progress_cancel_button")()
if proportionally:
model.scale(factor, callback=self.core.get("update_progress"))
else:
factor_x, factor_y, factor_z = (1, 1, 1)
if index == 0:
factor_x = factor
elif index == 1:
factor_y = factor
elif index == 2:
factor_z = factor
else:
return
model.scale(factor_x, factor_y, factor_z,
callback=self.core.get("update_progress"))
# move the model to its previous center
self.core.emit_event("model-change-after")
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Plugins
class ModelSwapAxes(pycam.Plugins.PluginBase):
UI_FILE = "model_swap_axes.ui"
def setup(self):
if self.gui:
swap_box = self.gui.get_object("ModelSwapBox")
swap_box.unparent()
self.core.register_ui("model_handling", "Swap axes", swap_box, 0)
self.gui.get_object("SwapAxesButton").connect("clicked",
self._swap_axes)
return True
def teardown(self):
if self.gui:
self.core.unregister_ui("model_handling",
self.gui.get_object("ModelSwapBox"))
def _swap_axes(self, widget=None):
model = self.core.get("model")
if not model:
return
self.core.emit_event("model-change-before")
self.core.get("update_progress")("Swap axes of model")
self.core.get("disable_progress_cancel_button")()
for axes, template in (("XY", "x_swap_y"), ("XZ", "x_swap_z"),
("YZ", "y_swap_z")):
if self.gui.get_object("SwapAxes%s" % axes).get_active():
break
model.transform_by_template(template,
callback=self.core.get("update_progress"))
self.core.emit_event("model-change-after")
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import os
import imp
import inspect
import gtk
import pycam.Utils.log
import pycam.Utils.locations
_log = pycam.Utils.log.get_logger()
class PluginBase(object):
UI_FILE = None
def __init__(self, core, name):
self.enabled = True
self.name = name
self.core = core
self.gui = None
if self.UI_FILE:
gtk_build_file = pycam.Utils.locations.get_ui_file_location(
self.UI_FILE)
if gtk_build_file:
self.gui = gtk.Builder()
try:
self.gui.add_from_file(gtk_build_file)
except RuntimeError:
self.gui = None
if not self.setup():
raise RuntimeError("Failed to load plugin '%s'" % str(name))
def setup(self):
raise NotImplementedError("Module %s (%s) does not implement " + \
"'setup'" % (self.name, __file__))
def teardown(self):
raise NotImplementedError("Module %s (%s) does not implement " + \
"'teardown'" % (self.name, __file__))
class PluginManager(object):
def __init__(self, core):
self.core = core
self.modules = {}
def import_plugins(self, directory=None):
if directory is None:
directory = os.path.dirname(__file__)
try:
files = os.listdir(directory)
except OSError:
return
for filename in files:
if filename.endswith(".py") and (filename != "__init__.py") and \
os.path.isfile(os.path.join(directory, filename)):
mod_name = filename[0:-(len(".py"))]
try:
mod_file, mod_filename, mod_desc = imp.find_module(
mod_name, [directory])
full_mod_name = "pycam.Plugins.%s" % mod_name
mod = imp.load_module(full_mod_name, mod_file,
mod_filename, mod_desc)
except ImportError:
_log.debug("Skipping broken plugin %s" % os.path.join(
directory, filename))
continue
for attr in dir(mod):
item = getattr(mod, attr)
if inspect.isclass(item) and hasattr(item, "setup"):
self._load_plugin(item, mod_filename, attr)
def _load_plugin(self, obj, filename, local_name):
name = "%s.%s" % (os.path.basename(filename)[0:-len(".py")], local_name)
if name in self.modules:
_log.debug("Cleaning up module %s" % name)
self.modules[name].teardown()
_log.debug("Initializing module %s (%s)" % (name, filename))
self.modules[name] = obj(self.core, name)
......@@ -31,7 +31,7 @@ except ImportError:
GL_enabled = False
class ODEBlocks:
class ODEBlocks(object):
def __init__(self, tool_settings, (minx, maxx, miny, maxy, minz, maxz),
x_steps=None, y_steps=None):
......
......@@ -41,18 +41,18 @@ NUM_CELL_X = 0
NUM_CELL_Y = 0
class ZBufferItem:
class ZBufferItem(object):
def __init__(self, z=0.0):
self.z = float(z)
self.changed = True
self.list = -1
class ZCellItem:
class ZCellItem(object):
def __init__(self):
self.list = -1
self.array = None
class ZBuffer:
class ZBuffer(object):
def __init__(self, minx, maxx, xres, miny, maxy, yres, minz, maxz):
global NUM_CELL_X, NUM_CELL_Y
self.minx = float(minx)
......
......@@ -161,9 +161,12 @@ def get_support_distributed(model, z_plane, average_distance,
polygons = model.get_cropped_model_by_bounds(bounds).get_polygons(
z=z_plane, ignore_below=False)
else:
polygons = model.get_waterline_contour(Plane(Point(0, 0, z_plane),
Vector(0, 0, 1))).get_cropped_model_by_bounds(bounds)\
.get_polygons()
waterline_model = model.get_waterline_contour(Plane(Point(0, 0, z_plane),
Vector(0, 0, 1))).get_cropped_model_by_bounds(bounds)
if not waterline_model:
return
else:
polygons = waterline_model.get_polygons()
# minimum required distance between two bridge start points
avoid_distance = 1.5 * (abs(length) + thickness)
if start_at_corners:
......
......@@ -281,7 +281,7 @@ class Toolpath(object):
self.toolpath = new_paths
class Bounds:
class Bounds(object):
TYPE_RELATIVE_MARGIN = 0
TYPE_FIXED_MARGIN = 1
......
......@@ -237,7 +237,7 @@ def get_external_program_location(key):
return None
class ProgressCounter:
class ProgressCounter(object):
def __init__(self, max_value, update_callback):
self.max_value = max_value
......
......@@ -20,7 +20,7 @@ You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
class Iterator:
class Iterator(object):
def __init__(self, seq, start=0):
self.seq = seq
self.ind = start
......@@ -73,7 +73,7 @@ class Iterator:
return len(self.seq) - self.ind
class CyclicIterator:
class CyclicIterator(object):
def __init__(self, seq, start=0):
self.seq = seq
self.ind = start
......
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2010 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import os
import sys
DATA_DIR_ENVIRON_KEY = "PYCAM_DATA_DIR"
FONT_DIR_ENVIRON_KEY = "PYCAM_FONT_DIR"
DATA_BASE_DIRS = [os.path.realpath(os.path.join(os.path.dirname(__file__),
os.pardir, os.pardir, os.pardir, "share")),
os.path.join(sys.prefix, "local", "share", "pycam"),
os.path.join(sys.prefix, "share", "pycam")]
FONTS_SUBDIR = "fonts"
UI_SUBDIR = "ui"
# necessary for "pyinstaller"
if "_MEIPASS2" in os.environ:
DATA_BASE_DIRS.insert(0, os.path.join(os.path.normpath(os.environ["_MEIPASS2"]), "share"))
# respect an override via an environment setting
if DATA_DIR_ENVIRON_KEY in os.environ:
DATA_BASE_DIRS.insert(0, os.path.normpath(os.environ[DATA_DIR_ENVIRON_KEY]))
if FONT_DIR_ENVIRON_KEY in os.environ:
FONT_DIR_OVERRIDE = os.path.normpath(os.environ[FONT_DIR_ENVIRON_KEY])
else:
FONT_DIR_OVERRIDE = None
FONT_DIR_FALLBACK = "/usr/share/qcad/fonts"
def get_ui_file_location(filename, silent=False):
return get_data_file_location(os.path.join(UI_SUBDIR, filename), silent=silent)
def get_data_file_location(filename, silent=False):
for base_dir in DATA_BASE_DIRS:
test_path = os.path.join(base_dir, filename)
if os.path.exists(test_path):
return test_path
else:
if not silent:
lines = []
lines.append("Failed to locate a resource file (%s) in %s!" \
% (filename, DATA_BASE_DIRS))
lines.append("You can extend the search path by setting the " \
+ "environment variable '%s'." % str(DATA_DIR_ENVIRON_KEY))
log.error(os.linesep.join(lines))
return None
def get_font_dir():
if FONT_DIR_OVERRIDE:
if os.path.isdir(FONT_DIR_OVERRIDE):
return FONT_DIR_OVERRIDE
else:
log.warn(("You specified a font dir that does not exist (%s). " \
+ "I will ignore it.") % FONT_DIR_OVERRIDE)
font_dir = get_data_file_location(FONTS_SUBDIR, silent=True)
if not font_dir is None:
return font_dir
else:
log.warn(("Failed to locate the fonts directory '%s' below '%s'. " \
+ "Falling back to '%s'.") \
% (FONTS_SUBDIR, DATA_BASE_DIRS, FONT_DIR_FALLBACK))
if os.path.isdir(FONT_DIR_FALLBACK):
return FONT_DIR_FALLBACK
else:
log.warn(("The fallback font directory (%s) does not exist. " \
+ "No fonts will be available.") % FONT_DIR_FALLBACK)
return None
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment