Commit 5c4bd378 authored by sumpfralle's avatar sumpfralle

added support for non-square support grids

added x/y offsets to support grid options


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@487 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 40a89f9e
......@@ -3,8 +3,10 @@ Version 0.3.0 - UNRELEASED
* added basic support for importing simple DXF contour files
* added support for engravings
* integrated "help" links pointing to the wiki
* allow non-square profiles for the support grid
* improved OpenGL lightning (contributed by imyrek)
* allow non-square profiles for the support grid
* added ability to create support grids with different x/y grid distance
* added x/y offsets to support grid options
* switched default tool size from radius to diameter
* fixed performance issue when using a support grid
* fixed empty toolpath after transforming the model
......
......@@ -281,25 +281,44 @@ class ProjectGui:
self.gui.get_object("ScaleDimensionButton").connect("clicked", self.scale_model_axis_fit)
# support grid
self.gui.get_object("SupportGridEnable").connect("clicked", self.update_support_grid_controls)
grid_distance = self.gui.get_object("SupportGridDistance")
grid_distance.connect("value-changed", self.update_support_grid_controls)
self.settings.add_item("support_grid_distance",
grid_distance.get_value, grid_distance.set_value)
grid_square_profile = self.gui.get_object("SupportGridSquare")
grid_square_profile.connect("toggled", self.update_support_grid_controls)
grid_distance_x = self.gui.get_object("SupportGridDistanceX")
grid_distance_x.connect("value-changed",
self.update_support_grid_controls)
self.settings.add_item("support_grid_distance_x",
grid_distance_x.get_value, grid_distance_x.set_value)
grid_distance_square = self.gui.get_object("SupportGridDistanceSquare")
grid_distance_square.connect("clicked",
self.update_support_grid_controls)
grid_distance_y = self.gui.get_object("SupportGridDistanceY")
grid_distance_y.connect("value-changed",
self.update_support_grid_controls)
def get_support_grid_distance_y():
if grid_distance_square.get_active():
return self.settings.get("support_grid_distance_x")
else:
return grid_distance_y.get_value()
self.settings.add_item("support_grid_distance_y",
get_support_grid_distance_y, grid_distance_y.set_value)
grid_thickness = self.gui.get_object("SupportGridThickness")
grid_thickness.connect("value-changed", self.update_support_grid_controls)
self.settings.add_item("support_grid_thickness",
grid_thickness.get_value, grid_thickness.set_value)
grid_height = self.gui.get_object("SupportGridHeight")
def get_support_grid_height():
if grid_square_profile.get_active():
return self.settings.get("support_grid_thickness")
else:
return grid_height.get_value()
self.settings.add_item("support_grid_height", get_support_grid_height, grid_height.set_value)
grid_height.connect("value-changed", self.update_support_grid_controls)
self.settings.set("support_grid_distance", 5.0)
self.settings.add_item("support_grid_height",
grid_height.get_value, grid_height.set_value)
grid_offset_x = self.gui.get_object("SupportGridOffsetX")
grid_offset_x.connect("value-changed",
self.update_support_grid_controls)
self.settings.add_item("support_grid_offset_x",
grid_offset_x.get_value, grid_offset_x.set_value)
grid_offset_y = self.gui.get_object("SupportGridOffsetY")
grid_offset_y.connect("value-changed",
self.update_support_grid_controls)
self.settings.add_item("support_grid_offset_y",
grid_offset_y.get_value, grid_offset_y.set_value)
grid_distance_square.set_active(True)
self.settings.set("support_grid_distance_x", 5.0)
self.settings.set("support_grid_thickness", 0.5)
self.settings.set("support_grid_height", 0.5)
# visual and general settings
......@@ -579,20 +598,16 @@ class ProjectGui:
@gui_activity_guard
def update_support_grid_controls(self, widget=None):
is_enabled = self.gui.get_object("SupportGridEnable").get_active()
grid_square = self.gui.get_object("SupportGridSquare")
details_box = self.gui.get_object("SupportGridDetailsBox")
grid_height_box = self.gui.get_object("SupportGridHeightBox")
if is_enabled:
grid_square = self.gui.get_object("SupportGridDistanceSquare")
distance_y = self.gui.get_object("SupportGridDistanceYControl")
if self.gui.get_object("SupportGridEnable").get_active():
distance_y.set_sensitive(not grid_square.get_active())
details_box.show()
if grid_square.get_active():
grid_height_box.hide()
else:
if widget == grid_square:
# reset the current height to the thickness, if the
# "square" checkbox was just de-activated
self.settings.set("support_grid_height", self.settings.get("support_grid_thickness"))
grid_height_box.show()
# We let "distance_y" track the value of "distance_x".
self.settings.set("support_grid_distance_y",
self.settings.get("support_grid_distance_x"))
else:
details_box.hide()
self.update_support_grid_model()
......@@ -603,17 +618,26 @@ class ProjectGui:
s = self.settings
if is_enabled \
and (s.get("support_grid_thickness") > 0) \
and (s.get("support_grid_distance") > s.get("support_grid_thickness")) \
and ((s.get("support_grid_distance_x") > 0) \
or (s.get("support_grid_distance_y") > 0)) \
and ((s.get("support_grid_distance_x") == 0) \
or (s.get("support_grid_distance_x") \
> s.get("support_grid_thickness"))) \
and ((s.get("support_grid_distance_y") == 0) \
or (s.get("support_grid_distance_y") \
> s.get("support_grid_thickness"))) \
and (s.get("support_grid_height") > 0):
s.set("support_grid",
pycam.Toolpath.SupportGrid.get_support_grid(s.get("minx"),
s.get("maxx"), s.get("miny"), s.get("maxy"),
s.get("minz"), s.get("support_grid_distance"),
s.get("support_grid_distance"),
support_grid = pycam.Toolpath.SupportGrid.get_support_grid(
s.get("minx"), s.get("maxx"), s.get("miny"), s.get("maxy"),
s.get("minz"), s.get("support_grid_distance_x"),
s.get("support_grid_distance_y"),
s.get("support_grid_thickness"),
s.get("support_grid_height")))
s.get("support_grid_height"),
offset_x=s.get("support_grid_offset_x"),
offset_y=s.get("support_grid_offset_y"))
else:
self.settings.set("support_grid", None)
support_grid = None
s.set("support_grid", support_grid)
@gui_activity_guard
def adjust_bounds(self, widget, axis, change):
......
......@@ -499,9 +499,12 @@ class ToolpathSettings:
"feedrate": float,
},
"SupportGrid": {
"distance": float,
"distance_x": float,
"distance_y": float,
"thickness": float,
"height": float,
"offset_x": float,
"offset_y": float,
},
"Program": {
"unit": str,
......@@ -560,8 +563,12 @@ class ToolpathSettings:
def get_tool_settings(self):
return self.tool_settings
def set_support_grid(self, distance, thickness, height):
self.support_grid["distance"] = distance
def set_support_grid(self, distance_x, distance_y, thickness, height,
offset_x=0.0, offset_y=0.0):
self.support_grid["distance_x"] = distance_x
self.support_grid["distance_y"] = distance_y
self.support_grid["offset_x"] = offset_x
self.support_grid["offset_y"] = offset_y
self.support_grid["thickness"] = thickness
self.support_grid["height"] = height
......@@ -569,7 +576,8 @@ class ToolpathSettings:
if self.support_grid:
return self.support_grid
else:
return {"distance": None, "thickness": None, "height": None}
return {"distance_x": None, "distance_y": None, "thickness": None,
"height": None, "offset_x": None, "offset_y": None}
def set_calculation_backend(self, backend=None):
self.program["enable_ode"] = (backend.upper() == "ODE")
......
......@@ -871,66 +871,172 @@
</packing>
</child>
<child>
<object class="GtkTable" id="SupportGridDetailsBox">
<object class="GtkVBox" id="SupportGridDetailsBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkExpander" id="GridPatternExpander">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="expanded">True</property>
<child>
<object class="GtkTable" id="table10">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">5</property>
<property name="row_spacing">3</property>
<property name="n_columns">4</property>
<property name="column_spacing">4</property>
<property name="row_spacing">1</property>
<child>
<object class="GtkVSeparator" id="vseparator7">
<object class="GtkLabel" id="SupportGridDistanceXLabel">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">distance x:</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<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="SupportGridDistanceControl">
<object class="GtkLabel" id="SupportGridDistanceYLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">distance y:</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="SupportGridDistanceXControl">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">SupportGridDistance</property>
<property name="adjustment">SupportGridDistanceX</property>
<property name="digits">2</property>
<property name="numeric">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="GtkLabel" id="SupportGridDistanceLabel">
<object class="GtkSpinButton" id="SupportGridDistanceYControl">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">grid distance:</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">SupportGridDistanceY</property>
<property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<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="GtkArrow" id="arrow1">
<object class="GtkCheckButton" id="SupportGridDistanceSquare">
<property name="label" translatable="yes">square grid</property>
<property name="visible">True</property>
<property name="xpad">2</property>
<property name="shadow_type">etched-in</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</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>
</packing>
</child>
<child>
<object class="GtkLabel" id="SupportGridThicknessLabel">
<object class="GtkAlignment" id="alignment23">
<property name="width_request">40</property>
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">grid thickness:</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment33">
<property name="width_request">40</property>
<property name="visible">True</property>
<child>
<placeholder/>
</child>
</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>
<placeholder/>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="GridPatternExpanderLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Pattern</property>
</object>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="GridProfileExpander">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="spacing">3</property>
<child>
<object class="GtkAlignment" id="alignment20">
<property name="width_request">40</property>
<property name="visible">True</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="SupportGridThicknessLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">thickness:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
......@@ -943,10 +1049,8 @@
<property name="numeric">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="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
......@@ -955,64 +1059,144 @@
<property name="orientation">vertical</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="expand">False</property>
<property name="padding">3</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="SupportGridSquare">
<property name="label" translatable="yes">square grid profile</property>
<object class="GtkLabel" id="SupportGridHeightLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">height:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="SupportGridHeightControl">
<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="invisible_char">&#x25CF;</property>
<property name="adjustment">SupportGridHeight</property>
<property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="right_attach">5</property>
<property name="expand">False</property>
<property name="position">5</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="GridProfileExpanderLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Profile</property>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="SupportGridHeightBox">
<object class="GtkExpander" id="GridPositionExpander">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkLabel" id="SupportGridHeightLabel">
<object class="GtkHBox" id="hbox17">
<property name="visible">True</property>
<property name="spacing">4</property>
<child>
<object class="GtkAlignment" id="alignment37">
<property name="width_request">40</property>
<property name="visible">True</property>
<property name="label" translatable="yes">grid height:</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="SupportGridHeightControl">
<object class="GtkLabel" id="GridOffsetXLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">offset x:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="SupportGridOffsetXControl">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">SupportGridHeight</property>
<property name="adjustment">SupportGridOffsetX</property>
<property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="position">1</property>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkVSeparator" id="vseparator2">
<property name="visible">True</property>
<property name="orientation">vertical</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="expand">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<placeholder/>
<object class="GtkLabel" id="GridOffsetYLabel">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">offset y:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="SupportGridOffsetYControl">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">&#x25CF;</property>
<property name="adjustment">SupportGridOffsetY</property>
<property name="digits">2</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">5</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="GridPositionExpanderLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Position</property>
</object>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
......@@ -5264,9 +5448,8 @@ Any selected group of dimensions will be scaled accordingly.</property>
<action-widget response="0">UnitChangeApply</action-widget>
</action-widgets>
</object>
<object class="GtkAdjustment" id="SupportGridDistance">
<object class="GtkAdjustment" id="SupportGridDistanceX">
<property name="value">5</property>
<property name="lower">0.01</property>
<property name="upper">1000</property>
<property name="step_increment">1</property>
</object>
......@@ -5330,4 +5513,16 @@ Any selected group of dimensions will be scaled accordingly.</property>
<object class="GtkAction" id="FeatureRequest">
<property name="label">Request a Feature</property>
</object>
<object class="GtkAdjustment" id="SupportGridDistanceY">
<property name="upper">1000</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="SupportGridOffsetX">
<property name="upper">1000</property>
<property name="step_increment">1</property>
</object>
<object class="GtkAdjustment" id="SupportGridOffsetY">
<property name="upper">1000</property>
<property name="step_increment">1</property>
</object>
</interface>
......@@ -51,9 +51,10 @@ def generate_toolpath(model, tool_settings=None,
bounds_low=None, bounds_high=None, direction="x",
path_generator="DropCutter", path_postprocessor="ZigZagCutter",
material_allowance=0.0, safety_height=None, overlap=0.0, step_down=0.0,
engrave_offset=0.0, support_grid_distance=None,
support_grid_thickness=None, support_grid_height=None,
calculation_backend=None, callback=None):
engrave_offset=0.0, support_grid_distance_x=None,
support_grid_distance_y=None, support_grid_thickness=None,
support_grid_height=None, support_grid_offset_x=None,
support_grid_offset_y=None, calculation_backend=None, callback=None):
""" abstract interface for generating a toolpath
@type model: pycam.Geometry.Model.Model
......@@ -84,12 +85,18 @@ def generate_toolpath(model, tool_settings=None,
@value step_down: maximum height of each layer (for PushCutter)
@type engrave_offset: float
@value engrave_offset: toolpath distance to the contour model
@type support_grid_distance: float
@value support_grid_distance: grid size of remaining support material
@type support_grid_distance_x: float
@value support_grid_distance_x: distance between support grid lines along x
@type support_grid_distance_y: float
@value support_grid_distance_y: distance between support grid lines along y
@type support_grid_thickness: float
@value support_grid_thickness: thickness of the support grid
@type support_grid_height: float
@value support_grid_height: height of the support grid
@type support_grid_offset_x: float
@value support_grid_offset_x: shift the support grid by this value along x
@type support_grid_offset_y: float
@value support_grid_offset_y: shift the support grid by this value along y
@type calculation_backend: str | None
@value calculation_backend: any member of the CALCULATION_BACKENDS set
The default is the triangular collision detection.
......@@ -119,13 +126,17 @@ def generate_toolpath(model, tool_settings=None,
# material allowance is ignored for engraving
material_allowance = 0.0
# create the grid model if requested
if (not support_grid_distance is None) \
and (not support_grid_thickness is None):
if (((not support_grid_distance_x is None) \
or (not support_grid_distance_y is None)) \
and (support_grid_thickness is None)):
# grid height defaults to the thickness
if support_grid_height is None:
support_grid_height = support_grid_thickness
if support_grid_distance <= 0:
if (support_grid_distance_x < 0) or (support_grid_distance_y < 0):
return "The distance of the support grid must be a positive value"
if not ((support_grid_distance_x > 0) or (support_grid_distance_y > 0)):
return "Both distance values for the support grid may not be " \
+ "zero at the same time"
if support_grid_thickness <= 0:
return "The thickness of the support grid must be a positive value"
if support_grid_height <= 0:
......@@ -133,9 +144,10 @@ def generate_toolpath(model, tool_settings=None,
if not callback is None:
callback(text="Preparing support grid model ...")
support_grid_model = pycam.Toolpath.SupportGrid.get_support_grid(
minx, maxx, miny, maxy, minz, support_grid_distance,
support_grid_distance, support_grid_thickness,
support_grid_height)
minx, maxx, miny, maxy, minz, support_grid_distance_x,
support_grid_distance_y, support_grid_thickness,
support_grid_height, offset_x=support_grid_offset_x,
offset_y=support_grid_offset_y)
trimesh_model += support_grid_model
# Adapt the contour_model to the engraving offset. This offset is
# considered to be part of the material_allowance.
......
......@@ -59,28 +59,45 @@ def _add_cuboid_to_model(minx, maxx, miny, maxy, minz, maxz):
model.append(t)
return model
def get_support_grid(minx, maxx, miny, maxy, z_plane, dist_x, dist_y, thickness, height):
lines_x = int(math.ceil((maxx - minx) / dist_x))
lines_y = int(math.ceil((maxy - miny) / dist_y))
# we center the grid
start_x = ((maxx - minx) - (lines_x - 1) * dist_x) / 2.0 + minx
start_y = ((maxy - miny) - (lines_y - 1) * dist_y) / 2.0 + miny
def get_support_grid(minx, maxx, miny, maxy, z_plane, dist_x, dist_y, thickness,
height, offset_x=0.0, offset_y=0.0):
def get_lines(center, dist, min_value, max_value):
""" generate a list of positions starting from the middle going up and
and down
"""
if dist > 0:
lines = [center]
current = center
while current - dist > min_value:
current -= dist
lines.insert(0, current)
current = center
while current + dist < max_value:
current += dist
lines.append(current)
else:
lines = []
# remove lines that are out of range (e.g. due to a huge offset)
lines = [line for line in lines if min_value < line < max_value]
return lines
center_x = (maxx + minx) / 2.0 + offset_x
center_y = (maxy + miny) / 2.0 + offset_y
lines_x = get_lines(center_x, dist_x, minx, maxx)
lines_y = get_lines(center_y, dist_y, miny, maxy)
# create all x grid lines
grid_model = Model.Model()
# helper variables
thick_half = thickness / 2.0
length_extension = max(thickness, height)
for i in range(lines_x):
x = start_x + i * dist_x
for line_x in lines_x:
# we make the grid slightly longer (by thickness) than necessary
grid_model += _add_cuboid_to_model(x - thick_half, x + thick_half,
miny - length_extension, maxy + length_extension, z_plane,
z_plane + height)
for i in range(lines_y):
y = start_y + i * dist_y
grid_model += _add_cuboid_to_model(line_x - thick_half,
line_x + thick_half, miny - length_extension,
maxy + length_extension, z_plane, z_plane + height)
for line_y in lines_y:
# we make the grid slightly longer (by thickness) than necessary
grid_model += _add_cuboid_to_model(minx - length_extension,
maxx + length_extension, y - thick_half, y + thick_half,
z_plane, z_plane + height)
maxx + length_extension, line_y - thick_half,
line_y + thick_half, z_plane, z_plane + height)
return grid_model
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