Commit 71e96447 authored by sumpfralle's avatar sumpfralle

added support for 2D projection of 3D models

swapped behaviour of inch2mm and mm2inch buttons


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@916 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent ce95f914
......@@ -7,6 +7,7 @@ Version 0.4.1 - UNRELEASED
* visualize movements up to safety height properly
* changed "simulation mode" for visualizing the machine moves
* added a very simple "pocketing" mode for 2D models
* added 2D projection of 3D models
* added support for DXF feature "LWPOLYLINE"
* added a configuration setting for automatically loading a custom task settings file on startup
* the default filename extension for exported GCode files is now configurable
......
......@@ -972,6 +972,7 @@ This can be useful if the imported model is technically broken (sometimes this h
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Scale the model by a factor of 25.4.</property>
</object>
<packing>
<property name="expand">False</property>
......@@ -984,12 +985,27 @@ This can be useful if the imported model is technically broken (sometimes this h
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Scale the model by a divider of 25.4.</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="Projection2D">
<property name="label" translatable="yes">2D Projection</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Reduce the 3D model down to a 2D projection.
The projection plane is usually at z=0. Only in case of models completely above or below zero the bottom of the model is used instead.</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object>
......
......@@ -239,7 +239,7 @@ class Model(BaseModel):
return self._t_kdtree.Search(minx, maxx, miny, maxy)
return self._triangles
def get_waterline_polygons(self, plane):
def get_waterline_contour(self, plane):
collision_lines = []
for t in self._triangles:
collision_line = plane.intersect_triangle(t, counter_clockwise=True)
......@@ -252,7 +252,7 @@ class Model(BaseModel):
log.debug("Waterline: %f - %d - %s" % (plane.p.z,
len(contour.get_polygons()),
[len(p.get_lines()) for p in contour.get_polygons()]))
return contour.get_polygons()
return contour
def get_flat_areas(self, min_area=None):
""" Find plane areas (combinations of triangles) bigger than 'min_area'
......
......@@ -30,6 +30,8 @@ import pycam.Toolpath.Generator
import pycam.Toolpath
import pycam.Importers.CXFImporter
import pycam.Importers
from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Plane import Plane
import pycam.Utils.log
import pycam.Utils
from pycam.Geometry.utils import sqrt
......@@ -535,9 +537,11 @@ class ProjectGui:
self.gui.get_object("ToggleModelDirectionButton").connect("clicked",
self.reverse_model_direction)
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)
self.gui.get_object("ScaleMMInch").connect("clicked", self.scale_model,
100 / 25.4)
self.gui.get_object("Projection2D").connect("clicked",
self.projection_2d)
# support grid
support_grid_type_control = self.gui.get_object(
"SupportGridTypesControl")
......@@ -1031,6 +1035,9 @@ class ProjectGui:
and hasattr(self.model, "reverse_directions")
self.gui.get_object("ToggleModelDirectionButton").set_sensitive(
is_reversible)
is_projectable = (not self.model is None) \
and hasattr(self.model, "get_waterline_contour")
self.gui.get_object("Projection2D").set_sensitive(is_projectable)
def update_gcode_controls(self, widget=None):
path_mode = self.settings.get("gcode_path_mode")
......@@ -2497,6 +2504,24 @@ class ProjectGui:
self.model.shift(new_x - old_x, new_y - old_y, new_z - old_z,
callback=self.update_progress_bar)
@progress_activity_guard
@gui_activity_guard
def projection_2d(self, widget=None):
self.update_progress_bar("Calculating 2D projection")
# 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
plane = Plane(Point(0, 0, plane_z), Vector(0, 0, 1))
log.info("Projecting 3D model at level z=%g" % plane_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_z)
@progress_activity_guard
@gui_activity_guard
def scale_model(self, widget=None, percent=None):
......
......@@ -164,8 +164,8 @@ def get_support_distributed(model, z_plane, average_distance,
if hasattr(model, "get_polygons"):
polygons = model.get_polygons()
else:
polygons = model.get_waterline_polygons(Plane(Point(0, 0, z_plane),
Vector(0, 0, 1)))
polygons = model.get_waterline_contour(Plane(Point(0, 0, z_plane),
Vector(0, 0, 1))).get_polygons()
bridge_positions = []
# minimum required distance between two bridge start points
avoid_distance = 1.5 * (abs(length) + thickness)
......
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