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/>. ...@@ -22,7 +22,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
import os import os
class EMCToolExporter: class EMCToolExporter(object):
def __init__(self, tools): def __init__(self, tools):
self.tools = tools self.tools = tools
......
...@@ -64,7 +64,7 @@ def _get_num_converter(step_width): ...@@ -64,7 +64,7 @@ def _get_num_converter(step_width):
return lambda number: decimal.Decimal(format_string % number) return lambda number: decimal.Decimal(format_string % number)
class GCodeGenerator: class GCodeGenerator(object):
NUM_OF_AXES = 3 NUM_OF_AXES = 3
......
...@@ -25,7 +25,7 @@ from pycam import VERSION ...@@ -25,7 +25,7 @@ from pycam import VERSION
import datetime import datetime
import os import os
class STLExporter: class STLExporter(object):
def __init__(self, model, name="model", created_by="pycam", linesep=None, def __init__(self, model, name="model", created_by="pycam", linesep=None,
**kwargs): **kwargs):
......
...@@ -24,7 +24,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -24,7 +24,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
SVG_OUTPUT_DPI = 90 SVG_OUTPUT_DPI = 90
class SVGExporter: class SVGExporter(object):
def __init__(self, output, unit="mm", maxx=None, maxy=None): def __init__(self, output, unit="mm", maxx=None, maxy=None):
if isinstance(output, basestring): if isinstance(output, basestring):
......
...@@ -33,9 +33,6 @@ TRANSFORMATIONS = { ...@@ -33,9 +33,6 @@ TRANSFORMATIONS = {
"x": ((1, 0, 0, 0), (0, 0, 1, 0), (0, -1, 0, 0)), "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)), "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)), "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_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)), "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)), "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): ...@@ -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.y * rot_axis.z + s * rot_axis.x,
t * rot_axis.z * rot_axis.z + c) 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 """ calculate rotation matrix for a normalized vector and an angle
see http://mathworld.wolfram.com/RotationMatrix.html see http://mathworld.wolfram.com/RotationMatrix.html
...@@ -153,6 +150,8 @@ def get_rotation_matrix_axis_angle(rot_axis, rot_angle): ...@@ -153,6 +150,8 @@ def get_rotation_matrix_axis_angle(rot_axis, rot_angle):
@rtype: tuple(float) @rtype: tuple(float)
@return: the roation @return: the roation
""" """
if not use_radians:
rot_angle *= math.pi / 180
sin = number(math.sin(rot_angle)) sin = number(math.sin(rot_angle))
cos = number(math.cos(rot_angle)) cos = number(math.cos(rot_angle))
return ((cos + rot_axis[0]*rot_axis[0]*(1-cos), return ((cos + rot_axis[0]*rot_axis[0]*(1-cos),
......
...@@ -39,7 +39,7 @@ except ImportError: ...@@ -39,7 +39,7 @@ except ImportError:
get_point_object = lambda point: point get_point_object = lambda point: point
class Path: class Path(object):
id = 0 id = 0
def __init__(self): def __init__(self):
self.id = Path.id self.id = Path.id
......
...@@ -32,7 +32,7 @@ DEBUG_POLYGONEXTRACTOR2 = False ...@@ -32,7 +32,7 @@ DEBUG_POLYGONEXTRACTOR2 = False
DEBUG_POLYGONEXTRACTOR3 = False DEBUG_POLYGONEXTRACTOR3 = False
class PolygonExtractor: class PolygonExtractor(object):
CONTOUR = 1 CONTOUR = 1
MONOTONE = 2 MONOTONE = 2
......
...@@ -28,7 +28,7 @@ except ImportError: ...@@ -28,7 +28,7 @@ except ImportError:
GL_enabled = False GL_enabled = False
class Node: class Node(object):
def __repr__(self): def __repr__(self):
s = "" s = ""
for bound in self.bound: for bound in self.bound:
......
...@@ -86,7 +86,7 @@ def connect_button_handlers(signal, original_button, derived_button): ...@@ -86,7 +86,7 @@ def connect_button_handlers(signal, original_button, derived_button):
original_button) original_button)
class Camera: class Camera(object):
def __init__(self, settings, get_dim_func, view=None): def __init__(self, settings, get_dim_func, view=None):
self.view = None self.view = None
...@@ -281,7 +281,7 @@ class Camera: ...@@ -281,7 +281,7 @@ class Camera:
return (factors_x, factors_y) return (factors_x, factors_y)
class ModelViewWindowGL: class ModelViewWindowGL(object):
def __init__(self, gui, settings, notify_destroy=None, accel_group=None, def __init__(self, gui, settings, notify_destroy=None, accel_group=None,
item_buttons=None, context_menu_actions=None): item_buttons=None, context_menu_actions=None):
# assume, that initialization will fail # assume, that initialization will fail
......
...@@ -35,6 +35,8 @@ from pycam.Geometry.Point import Point, Vector ...@@ -35,6 +35,8 @@ from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Plane import Plane from pycam.Geometry.Plane import Plane
import pycam.Geometry.Path import pycam.Geometry.Path
import pycam.Utils.log import pycam.Utils.log
from pycam.Utils.locations import get_data_file_location, \
get_ui_file_location, get_font_dir
import pycam.Utils import pycam.Utils
from pycam.Geometry.utils import sqrt from pycam.Geometry.utils import sqrt
from pycam.Gui.OpenGLTools import ModelViewWindowGL from pycam.Gui.OpenGLTools import ModelViewWindowGL
...@@ -43,6 +45,7 @@ from pycam.Geometry.Letters import TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, \ ...@@ -43,6 +45,7 @@ from pycam.Geometry.Letters import TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, \
import pycam.Geometry.Model import pycam.Geometry.Model
from pycam.Toolpath import Bounds from pycam.Toolpath import Bounds
import pycam.Utils.FontCache import pycam.Utils.FontCache
import pycam.Plugins
from pycam import VERSION from pycam import VERSION
import pycam.Physics.ode_physics import pycam.Physics.ode_physics
# this requires ODE - we import it later, if necessary # this requires ODE - we import it later, if necessary
...@@ -66,28 +69,9 @@ import re ...@@ -66,28 +69,9 @@ import re
import os import os
import sys import sys
DATA_DIR_ENVIRON_KEY = "PYCAM_DATA_DIR"
FONT_DIR_ENVIRON_KEY = "PYCAM_FONT_DIR" GTKBUILD_FILE = "pycam-project.ui"
DATA_BASE_DIRS = [os.path.realpath(os.path.join(os.path.dirname(__file__), GTKMENU_FILE = "menubar.xml"
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")
WINDOW_ICON_FILENAMES = ["logo_%dpx.png" % pixels for pixels in (16, 32, 48, 64, 128)] WINDOW_ICON_FILENAMES = ["logo_%dpx.png" % pixels for pixels in (16, 32, 48, 64, 128)]
...@@ -176,21 +160,6 @@ GTK_COLOR_MAX = 65535.0 ...@@ -176,21 +160,6 @@ GTK_COLOR_MAX = 65535.0
log = pycam.Utils.log.get_logger() 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(): def report_exception():
log.error("An unexpected exception occoured: please send the " \ log.error("An unexpected exception occoured: please send the " \
+ "text below to the developers of PyCAM. Thanks a lot!" \ + "text below to the developers of PyCAM. Thanks a lot!" \
...@@ -212,8 +181,7 @@ def get_filters_from_list(filter_list): ...@@ -212,8 +181,7 @@ def get_filters_from_list(filter_list):
def get_icons_pixbuffers(): def get_icons_pixbuffers():
result = [] result = []
for icon_filename in WINDOW_ICON_FILENAMES: for icon_filename in WINDOW_ICON_FILENAMES:
icon_subdir_filename = os.path.join(UI_SUBDIR, icon_filename) abs_filename = get_ui_file_location(icon_filename, silent=True)
abs_filename = get_data_file_location(icon_subdir_filename, silent=True)
if abs_filename: if abs_filename:
try: try:
result.append(gtk.gdk.pixbuf_new_from_file(abs_filename)) result.append(gtk.gdk.pixbuf_new_from_file(abs_filename))
...@@ -225,29 +193,119 @@ def get_icons_pixbuffers(): ...@@ -225,29 +193,119 @@ def get_icons_pixbuffers():
log.debug("Failed to locate window icon: %s" % icon_filename) log.debug("Failed to locate window icon: %s" % icon_filename)
return result return result
def get_font_dir():
if FONT_DIR_OVERRIDE: UI_FUNC_INDEX = 0
if os.path.isdir(FONT_DIR_OVERRIDE): UI_WIDGET_INDEX = 1
return FONT_DIR_OVERRIDE 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: else:
log.warn(("You specified a font dir that does not exist (%s). " \ log.debug("Trying to unregister an unknown event: %s" % event)
+ "I will ignore it.") % FONT_DIR_OVERRIDE)
font_dir = get_data_file_location(FONTS_SUBDIR, silent=True) def emit_event(self, event):
if not font_dir is None: if event in self.event_handlers:
return font_dir if self.event_handlers[event][EVENT_BLOCKER_INDEX] != 0:
else: return
log.warn(("Failed to locate the fonts directory '%s' below '%s'. " \ self.block_event(event)
+ "Falling back to '%s'.") \ for handler in self.event_handlers[event][EVENT_HANDLER_INDEX]:
% (FONTS_SUBDIR, DATA_BASE_DIRS, FONT_DIR_FALLBACK)) func = handler[HANDLER_FUNC_INDEX]
if os.path.isdir(FONT_DIR_FALLBACK): args = handler[HANDLER_ARG_INDEX]
return FONT_DIR_FALLBACK # prevent infinite recursion
func(*args)
self.unblock_event(event)
else: else:
log.warn(("The fallback font directory (%s) does not exist. " \ log.debug("No events registered for event '%s'" % str(event))
+ "No fonts will be available.") % FONT_DIR_FALLBACK)
return None
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 = { BOUNDARY_MODES = {
"inside": -1, "inside": -1,
...@@ -262,7 +320,9 @@ class ProjectGui: ...@@ -262,7 +320,9 @@ class ProjectGui:
META_DATA_PREFIX = "PYCAM-META-DATA:" META_DATA_PREFIX = "PYCAM-META-DATA:"
def __init__(self, no_dialog=False): 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.gui_is_active = False
self.view3d = None self.view3d = None
# during initialization any dialog (e.g. "Unit change") is not allowed # during initialization any dialog (e.g. "Unit change") is not allowed
...@@ -276,7 +336,7 @@ class ProjectGui: ...@@ -276,7 +336,7 @@ class ProjectGui:
self._fonts_cache = pycam.Utils.FontCache.FontCache(get_font_dir(), self._fonts_cache = pycam.Utils.FontCache.FontCache(get_font_dir(),
callback=self.update_progress_bar) callback=self.update_progress_bar)
self.gui = gtk.Builder() 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: if gtk_build_file is None:
gtk.main_quit() gtk.main_quit()
self.gui.add_from_file(gtk_build_file) self.gui.add_from_file(gtk_build_file)
...@@ -361,6 +421,16 @@ class ProjectGui: ...@@ -361,6 +421,16 @@ class ProjectGui:
gtk.accel_map_change_entry(accel_path, key, mod, True) gtk.accel_map_change_entry(accel_path, key, mod, True)
# no undo is allowed at the beginning # no undo is allowed at the beginning
self.gui.get_object("UndoButton").set_sensitive(False) 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 # configure drag-n-drop for config files and models
self.configure_drag_and_drop(self.window) self.configure_drag_and_drop(self.window)
self.clipboard = gtk.clipboard_get() self.clipboard = gtk.clipboard_get()
...@@ -405,19 +475,6 @@ class ProjectGui: ...@@ -405,19 +475,6 @@ class ProjectGui:
self.gui.get_object("ProcessPoolWindowClose").connect("clicked", self.toggle_process_pool_window, False) self.gui.get_object("ProcessPoolWindowClose").connect("clicked", self.toggle_process_pool_window, False)
self.gui.get_object("ProcessPoolRefreshInterval").set_value(3) self.gui.get_object("ProcessPoolRefreshInterval").set_value(3)
self.process_pool_model = self.gui.get_object("ProcessPoolStatisticsModel") 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 # "font dialog" window
self.font_dialog_window = self.gui.get_object("FontDialog") self.font_dialog_window = self.gui.get_object("FontDialog")
self.font_dialog_window.connect("delete-event", self.font_dialog_window.connect("delete-event",
...@@ -470,6 +527,14 @@ class ProjectGui: ...@@ -470,6 +527,14 @@ class ProjectGui:
self.settings.add_item("model", lambda: self.model) self.settings.add_item("model", lambda: self.model)
self.settings.add_item("toolpath", lambda: self.toolpath) self.settings.add_item("toolpath", lambda: self.toolpath)
self.settings.add_item("cutter", lambda: self.cutter) 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 control (mm/inch)
unit_field = self.gui.get_object("unit_control") unit_field = self.gui.get_object("unit_control")
unit_field.connect("changed", self.change_unit_init) unit_field.connect("changed", self.change_unit_init)
...@@ -544,52 +609,6 @@ class ProjectGui: ...@@ -544,52 +609,6 @@ class ProjectGui:
# create a new variable "key" to avoid re-using the same object "key" # create a new variable "key" to avoid re-using the same object "key"
# (due to the lambda name scope) # (due to the lambda name scope)
self.settings.add_item(key, lambda key=key: get_absolute_limit(key)) 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
support_grid_type_control = self.gui.get_object( support_grid_type_control = self.gui.get_object(
"SupportGridTypesControl") "SupportGridTypesControl")
...@@ -1085,7 +1104,7 @@ class ProjectGui: ...@@ -1085,7 +1104,7 @@ class ProjectGui:
# set the icons (in different sizes) for all windows # set the icons (in different sizes) for all windows
gtk.window_set_default_icon_list(*get_icons_pixbuffers()) gtk.window_set_default_icon_list(*get_icons_pixbuffers())
# load menu data # 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: if gtk_menu_file is None:
gtk.main_quit() gtk.main_quit()
uimanager.add_ui_from_file(gtk_menu_file) uimanager.add_ui_from_file(gtk_menu_file)
...@@ -1200,27 +1219,6 @@ class ProjectGui: ...@@ -1200,27 +1219,6 @@ class ProjectGui:
getattr(self.gui.get_object(objname), update_func)() getattr(self.gui.get_object(objname), update_func)()
def update_model_type_related_controls(self): 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 # disable the lower boundary for contour models
is_contour = isinstance(self.model, pycam.Geometry.Model.ContourModel) is_contour = isinstance(self.model, pycam.Geometry.Model.ContourModel)
self.gui.get_object("boundary_z_low").set_sensitive(not is_contour) self.gui.get_object("boundary_z_low").set_sensitive(not is_contour)
...@@ -1286,7 +1284,7 @@ class ProjectGui: ...@@ -1286,7 +1284,7 @@ class ProjectGui:
self.gui.get_object("UndoButton").set_sensitive( self.gui.get_object("UndoButton").set_sensitive(
len(self._undo_states) > 0) len(self._undo_states) > 0)
log.info("Restored the previous state of the model") log.info("Restored the previous state of the model")
self._update_all_model_attributes() self.settings.emit_event("model-change-after")
else: else:
log.info("No previous undo state available - request ignored") log.info("No previous undo state available - request ignored")
...@@ -1315,7 +1313,7 @@ class ProjectGui: ...@@ -1315,7 +1313,7 @@ class ProjectGui:
else: else:
short_name = os.path.basename(uri.get_path()) short_name = os.path.basename(uri.get_path())
self.window.set_title("%s - PyCAM" % short_name) self.window.set_title("%s - PyCAM" % short_name)
self.update_save_actions() self.settings.emit_event("model-change-after")
def update_save_actions(self): def update_save_actions(self):
self.gui.get_object("SaveTaskSettings").set_sensitive( self.gui.get_object("SaveTaskSettings").set_sensitive(
...@@ -1372,8 +1370,7 @@ class ProjectGui: ...@@ -1372,8 +1370,7 @@ class ProjectGui:
obj.show() obj.show()
else: else:
obj.hide() obj.hide()
self.update_support_model() self.settings.emit_event("model-change-after")
self.update_view()
def update_support_model(self, widget=None): def update_support_model(self, widget=None):
grid_type = self.settings.get("support_grid_type") grid_type = self.settings.get("support_grid_type")
...@@ -1426,7 +1423,7 @@ class ProjectGui: ...@@ -1426,7 +1423,7 @@ class ProjectGui:
elif grid_type == GRID_TYPES["none"]: elif grid_type == GRID_TYPES["none"]:
pass pass
s.set("support_grid", support_grid) 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): def switch_support_grid_manual_selector(self, widget=None):
old_axis_was_x = self.grid_adjustment_axis_x_last old_axis_was_x = self.grid_adjustment_axis_x_last
...@@ -1463,8 +1460,7 @@ class ProjectGui: ...@@ -1463,8 +1460,7 @@ class ProjectGui:
if not tree_iter is None: if not tree_iter is None:
value_string = "(%+.1f)" % new_value value_string = "(%+.1f)" % new_value
self.grid_adjustment_model.set(tree_iter, 1, value_string) self.grid_adjustment_model.set(tree_iter, 1, value_string)
self.update_support_model() self.settings.emit_event("model-change-after")
self.update_view()
def reset_support_grid_manual(self, widget=None, reset_all=False): def reset_support_grid_manual(self, widget=None, reset_all=False):
if reset_all: if reset_all:
...@@ -1474,8 +1470,7 @@ class ProjectGui: ...@@ -1474,8 +1470,7 @@ class ProjectGui:
self.settings.set("support_grid_adjustment_value", 0) self.settings.set("support_grid_adjustment_value", 0)
self.update_support_grid_manual_model() self.update_support_grid_manual_model()
self.switch_support_grid_manual_selector() self.switch_support_grid_manual_selector()
self.update_support_model() self.settings.emit_event("model-change-after")
self.update_view()
def update_support_grid_manual_model(self): def update_support_grid_manual_model(self):
old_index = self.grid_adjustment_selector.get_active() old_index = self.grid_adjustment_selector.get_active()
...@@ -1695,8 +1690,7 @@ class ProjectGui: ...@@ -1695,8 +1690,7 @@ class ProjectGui:
# update the values in the manual support grid adjustment list # update the values in the manual support grid adjustment list
self.update_support_grid_manual_model() self.update_support_grid_manual_model()
# the support grid depends on the boundary # the support grid depends on the boundary
self.update_support_model() self.settings.emit_event("model-change-after")
self.update_view()
def update_tasklist_controls(self): def update_tasklist_controls(self):
# en/disable some buttons # en/disable some buttons
...@@ -2192,52 +2186,6 @@ class ProjectGui: ...@@ -2192,52 +2186,6 @@ class ProjectGui:
# don't close the window - just hide it (for "delete-event") # don't close the window - just hide it (for "delete-event")
return True 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 @gui_activity_guard
def toggle_preferences_window(self, widget=None, event=None, state=None): def toggle_preferences_window(self, widget=None, event=None, state=None):
if state is None: if state is None:
...@@ -2424,37 +2372,13 @@ class ProjectGui: ...@@ -2424,37 +2372,13 @@ class ProjectGui:
else: else:
# the window is just hidden # the window is just hidden
self.view3d.show() self.view3d.show()
self.update_view() self.settings.emit_event("model-change-after")
else: else:
self.view3d.hide() self.view3d.hide()
# enable the toggle button only, if the 3d view is available # enable the toggle button only, if the 3d view is available
# (e.g. disabled if no OpenGL support is available) # (e.g. disabled if no OpenGL support is available)
toggle_3d_checkbox.set_active(self.view3d.enabled and new_state) 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): def _treeview_get_active_index(self, table, datalist):
if len(datalist) == 0: if len(datalist) == 0:
result = None result = None
...@@ -2697,7 +2621,7 @@ class ProjectGui: ...@@ -2697,7 +2621,7 @@ class ProjectGui:
# transform the model if it is selected # transform the model if it is selected
# keep the original center of the model # keep the original center of the model
old_center = self._get_model_center() old_center = self._get_model_center()
self._store_undo_state() self.settings.emit_event("model-change-before")
self.model.scale(factor) self.model.scale(factor)
self._set_model_center(old_center) self._set_model_center(old_center)
if self.gui.get_object("UnitChangeProcesses").get_active(): if self.gui.get_object("UnitChangeProcesses").get_active():
...@@ -2745,7 +2669,7 @@ class ProjectGui: ...@@ -2745,7 +2669,7 @@ class ProjectGui:
self.switch_bounds_table_selection() self.switch_bounds_table_selection()
self.switch_tasklist_table_selection() self.switch_tasklist_table_selection()
# redraw the model # redraw the model
self.update_view() self.settings.emit_event("model-change-after")
def update_unit_labels(self, widget=None, data=None): def update_unit_labels(self, widget=None, data=None):
# don't use the "unit" setting, since we need the plural of "inch" # don't use the "unit" setting, since we need the plural of "inch"
...@@ -2842,7 +2766,7 @@ class ProjectGui: ...@@ -2842,7 +2766,7 @@ class ProjectGui:
for key, value in PREFERENCES_DEFAULTS.items(): for key, value in PREFERENCES_DEFAULTS.items():
self.settings.set(key, value) self.settings.set(key, value)
# redraw the model due to changed colors, display items ... # redraw the model due to changed colors, display items ...
self.update_view() self.settings.emit_event("model-change-after")
def load_preferences(self): def load_preferences(self):
""" load all settings that are available in the Preferences window from """ load all settings that are available in the Preferences window from
...@@ -2893,26 +2817,6 @@ class ProjectGui: ...@@ -2893,26 +2817,6 @@ class ProjectGui:
except IOError, err_msg: except IOError, err_msg:
log.warn("Failed to write preferences file (%s): %s" % (config_filename, 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): def _get_model_center(self):
if self.model is None: if self.model is None:
return None return None
...@@ -2929,65 +2833,10 @@ class ProjectGui: ...@@ -2929,65 +2833,10 @@ class ProjectGui:
self.model.shift(new_x - old_x, new_y - old_y, new_z - old_z, self.model.shift(new_x - old_x, new_y - old_y, new_z - old_z,
callback=self.update_progress_bar) 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 @gui_activity_guard
def update_model_dimensions(self, widget=None): def update_model_dimensions(self, widget=None):
if self.model is None: if self.model is None:
return 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 # model corners in 3D view
for attr, label_suffix in (("minx", "XMin"), ("miny", "YMin"), for attr, label_suffix in (("minx", "XMin"), ("miny", "YMin"),
("minz", "ZMin"), ("maxx", "XMax"), ("maxy", "YMax"), ("minz", "ZMin"), ("maxx", "XMax"), ("maxy", "YMax"),
...@@ -2996,62 +2845,6 @@ class ProjectGui: ...@@ -2996,62 +2845,6 @@ class ProjectGui:
value = "%.3f" % getattr(self.model, attr) value = "%.3f" % getattr(self.model, attr)
self.gui.get_object(label_name).set_label(value) 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): def destroy(self, widget=None, data=None):
self.update_view() self.update_view()
# check if there is a running process # check if there is a running process
...@@ -3212,22 +3005,14 @@ class ProjectGui: ...@@ -3212,22 +3005,14 @@ class ProjectGui:
self.add_to_recent_file_list(filename) self.add_to_recent_file_list(filename)
self.update_save_actions() 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): def load_model(self, model):
# load the new model only if the import worked # load the new model only if the import worked
if not model is None: if not model is None:
self._store_undo_state() self.settings.emit_event("model-change-before")
self.model = model self.model = model
self.last_model_uri = None self.last_model_uri = None
# do some initialization # 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: if self.model and self.view3d and self.view3d.enabled:
self.append_to_queue(self.view3d.reset_view) self.append_to_queue(self.view3d.reset_view)
return True return True
...@@ -3967,7 +3752,7 @@ class ProjectGui: ...@@ -3967,7 +3752,7 @@ class ProjectGui:
start_time = time.time() start_time = time.time()
self.update_progress_bar("Preparing toolpath generation") self.update_progress_bar("Preparing toolpath generation")
parent = self parent = self
class UpdateView: class UpdateView(object):
def __init__(self, func, max_fps=1): def __init__(self, func, max_fps=1):
self.last_update = time.time() self.last_update = time.time()
self.max_fps = max_fps self.max_fps = max_fps
......
...@@ -60,7 +60,7 @@ def get_config_filename(filename=None): ...@@ -60,7 +60,7 @@ def get_config_filename(filename=None):
return os.path.join(config_dir, filename) return os.path.join(config_dir, filename)
class Settings: class Settings(object):
GET_INDEX = 0 GET_INDEX = 0
SET_INDEX = 1 SET_INDEX = 1
...@@ -118,7 +118,7 @@ class Settings: ...@@ -118,7 +118,7 @@ class Settings:
return self.items.keys() return self.items.keys()
class ProcessSettings: class ProcessSettings(object):
BASIC_DEFAULT_CONFIG = """ BASIC_DEFAULT_CONFIG = """
[ToolDefault] [ToolDefault]
...@@ -556,7 +556,7 @@ process: 3 ...@@ -556,7 +556,7 @@ process: 3
return os.linesep.join(result) return os.linesep.join(result)
class ToolpathSettings: class ToolpathSettings(object):
SECTIONS = { SECTIONS = {
"Bounds": { "Bounds": {
......
...@@ -193,7 +193,7 @@ def keyPressed(key, x, y): ...@@ -193,7 +193,7 @@ def keyPressed(key, x, y):
elif _KeyHandlerFunc: elif _KeyHandlerFunc:
_KeyHandlerFunc(key, x, y) _KeyHandlerFunc(key, x, y)
class mouseState: class mouseState(object):
button = None button = None
state = None state = None
x = 0 x = 0
......
...@@ -150,7 +150,7 @@ def get_dependency_report(details, prefix=""): ...@@ -150,7 +150,7 @@ def get_dependency_report(details, prefix=""):
return os.linesep.join(result) return os.linesep.join(result)
class EmergencyDialog: class EmergencyDialog(object):
""" This graphical message window requires no external dependencies. """ This graphical message window requires no external dependencies.
The Tk interface package is part of the main python distribution. The Tk interface package is part of the main python distribution.
Use this class for displaying dependency errors (especially on Windows). Use this class for displaying dependency errors (especially on Windows).
......
...@@ -72,7 +72,7 @@ def _process_one_triangle((model, cutter, up_vector, triangle, z)): ...@@ -72,7 +72,7 @@ def _process_one_triangle((model, cutter, up_vector, triangle, z)):
return result, None return result, None
class CollisionPaths: class CollisionPaths(object):
def __init__(self): def __init__(self):
self.waterlines = [] self.waterlines = []
...@@ -193,7 +193,7 @@ class CollisionPaths: ...@@ -193,7 +193,7 @@ class CollisionPaths:
return result return result
class ContourFollow: class ContourFollow(object):
def __init__(self, cutter, models, path_processor, physics=None): def __init__(self, cutter, models, path_processor, physics=None):
self.cutter = cutter self.cutter = cutter
......
...@@ -39,7 +39,7 @@ def _process_one_grid_line((positions, minz, maxz, model, cutter, physics)): ...@@ -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) return get_max_height_dynamic(model, cutter, positions, minz, maxz, physics)
class Dimension: class Dimension(object):
def __init__(self, start, end): def __init__(self, start, end):
self.start = float(start) self.start = float(start)
self.end = float(end) self.end = float(end)
...@@ -70,7 +70,7 @@ class Dimension: ...@@ -70,7 +70,7 @@ class Dimension:
return self.value return self.value
class DropCutter: class DropCutter(object):
def __init__(self, cutter, models, path_processor, physics=None): def __init__(self, cutter, models, path_processor, physics=None):
self.cutter = cutter self.cutter = cutter
......
...@@ -35,7 +35,7 @@ import pycam.Utils.log ...@@ -35,7 +35,7 @@ import pycam.Utils.log
log = pycam.Utils.log.get_logger() log = pycam.Utils.log.get_logger()
class EngraveCutter: class EngraveCutter(object):
def __init__(self, cutter, trimesh_models, contour_model, path_processor, def __init__(self, cutter, trimesh_models, contour_model, path_processor,
clockwise=False, physics=None): clockwise=False, physics=None):
......
...@@ -43,7 +43,7 @@ def _process_one_line((p1, p2, depth, models, cutter, physics)): ...@@ -43,7 +43,7 @@ def _process_one_line((p1, p2, depth, models, cutter, physics)):
return points return points
class PushCutter: class PushCutter(object):
def __init__(self, cutter, models, path_processor, physics=None): def __init__(self, cutter, models, path_processor, physics=None):
if physics is None: if physics is None:
......
...@@ -28,7 +28,7 @@ from pycam.Geometry.Point import Point ...@@ -28,7 +28,7 @@ from pycam.Geometry.Point import Point
import pycam.Utils.threading import pycam.Utils.threading
class Hit: class Hit(object):
def __init__(self, cl, cp, t, d, direction): def __init__(self, cl, cp, t, d, direction):
self.cl = cl self.cl = cl
self.cp = cp 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: ...@@ -31,7 +31,7 @@ except ImportError:
GL_enabled = False GL_enabled = False
class ODEBlocks: class ODEBlocks(object):
def __init__(self, tool_settings, (minx, maxx, miny, maxy, minz, maxz), def __init__(self, tool_settings, (minx, maxx, miny, maxy, minz, maxz),
x_steps=None, y_steps=None): x_steps=None, y_steps=None):
......
...@@ -41,18 +41,18 @@ NUM_CELL_X = 0 ...@@ -41,18 +41,18 @@ NUM_CELL_X = 0
NUM_CELL_Y = 0 NUM_CELL_Y = 0
class ZBufferItem: class ZBufferItem(object):
def __init__(self, z=0.0): def __init__(self, z=0.0):
self.z = float(z) self.z = float(z)
self.changed = True self.changed = True
self.list = -1 self.list = -1
class ZCellItem: class ZCellItem(object):
def __init__(self): def __init__(self):
self.list = -1 self.list = -1
self.array = None self.array = None
class ZBuffer: class ZBuffer(object):
def __init__(self, minx, maxx, xres, miny, maxy, yres, minz, maxz): def __init__(self, minx, maxx, xres, miny, maxy, yres, minz, maxz):
global NUM_CELL_X, NUM_CELL_Y global NUM_CELL_X, NUM_CELL_Y
self.minx = float(minx) self.minx = float(minx)
......
...@@ -161,9 +161,12 @@ def get_support_distributed(model, z_plane, average_distance, ...@@ -161,9 +161,12 @@ def get_support_distributed(model, z_plane, average_distance,
polygons = model.get_cropped_model_by_bounds(bounds).get_polygons( polygons = model.get_cropped_model_by_bounds(bounds).get_polygons(
z=z_plane, ignore_below=False) z=z_plane, ignore_below=False)
else: else:
polygons = model.get_waterline_contour(Plane(Point(0, 0, z_plane), waterline_model = model.get_waterline_contour(Plane(Point(0, 0, z_plane),
Vector(0, 0, 1))).get_cropped_model_by_bounds(bounds)\ Vector(0, 0, 1))).get_cropped_model_by_bounds(bounds)
.get_polygons() if not waterline_model:
return
else:
polygons = waterline_model.get_polygons()
# minimum required distance between two bridge start points # minimum required distance between two bridge start points
avoid_distance = 1.5 * (abs(length) + thickness) avoid_distance = 1.5 * (abs(length) + thickness)
if start_at_corners: if start_at_corners:
......
...@@ -281,7 +281,7 @@ class Toolpath(object): ...@@ -281,7 +281,7 @@ class Toolpath(object):
self.toolpath = new_paths self.toolpath = new_paths
class Bounds: class Bounds(object):
TYPE_RELATIVE_MARGIN = 0 TYPE_RELATIVE_MARGIN = 0
TYPE_FIXED_MARGIN = 1 TYPE_FIXED_MARGIN = 1
......
...@@ -237,7 +237,7 @@ def get_external_program_location(key): ...@@ -237,7 +237,7 @@ def get_external_program_location(key):
return None return None
class ProgressCounter: class ProgressCounter(object):
def __init__(self, max_value, update_callback): def __init__(self, max_value, update_callback):
self.max_value = max_value self.max_value = max_value
......
...@@ -20,7 +20,7 @@ You should have received a copy of the GNU General Public License ...@@ -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/>. along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
""" """
class Iterator: class Iterator(object):
def __init__(self, seq, start=0): def __init__(self, seq, start=0):
self.seq = seq self.seq = seq
self.ind = start self.ind = start
...@@ -73,7 +73,7 @@ class Iterator: ...@@ -73,7 +73,7 @@ class Iterator:
return len(self.seq) - self.ind return len(self.seq) - self.ind
class CyclicIterator: class CyclicIterator(object):
def __init__(self, seq, start=0): def __init__(self, seq, start=0):
self.seq = seq self.seq = seq
self.ind = start 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