optimize new openscad renderer

This commit is contained in:
Laura Klünder 2018-12-06 02:59:01 +01:00
parent 42d09eb599
commit 0bc9b7c7d4

View file

@ -21,7 +21,7 @@ class AbstractOpenScadElem(ABC):
class AbstractOpenScadBlock(AbstractOpenScadElem, UserList): class AbstractOpenScadBlock(AbstractOpenScadElem, UserList):
def render_children(self): def render_children(self):
return '\n'.join(child.render() for child in self.data) return '\n'.join(child.render() for child in self.data if child is not None)
class OpenScadRoot(AbstractOpenScadBlock): class OpenScadRoot(AbstractOpenScadBlock):
@ -138,8 +138,8 @@ class OpenSCADNewEngine(Base3DEngine):
name = 'Altitudearea %s' % (altitudearea.altitude / 1000) name = 'Altitudearea %s' % (altitudearea.altitude / 1000)
geometry = altitudearea.geometry.buffer(0) geometry = altitudearea.geometry.buffer(0)
inside_geometry = geometry.intersection(buildings).buffer(0).buffer(0.07, join_style=JOIN_STYLE.mitre) inside_geometry = geometry.intersection(buildings).buffer(0).buffer(0.01, join_style=JOIN_STYLE.mitre)
outside_geometry = geometry.difference(buildings).buffer(0).buffer(0.07, join_style=JOIN_STYLE.mitre) outside_geometry = geometry.difference(buildings).buffer(0).buffer(0.01, join_style=JOIN_STYLE.mitre)
slopes = True slopes = True
@ -213,7 +213,7 @@ class OpenSCADNewEngine(Base3DEngine):
# obstacles # obstacles
if altitudearea.altitude2 is not None: if altitudearea.altitude2 is not None:
obstacles_diff_block = OpenScadBlock('difference()', comment=name + ' obstacles') obstacles_diff_block = OpenScadBlock('difference()', comment=name + ' obstacles')
main_building_block.append(obstacles_diff_block) had_obstacles = False
obstacles_block = OpenScadBlock('union()') obstacles_block = OpenScadBlock('union()')
obstacles_diff_block.append(obstacles_block) obstacles_diff_block.append(obstacles_block)
@ -224,37 +224,52 @@ class OpenSCADNewEngine(Base3DEngine):
for height, obstacles in altitudearea.obstacles.items(): for height, obstacles in altitudearea.obstacles.items():
height_diff = OpenScadBlock('difference()') height_diff = OpenScadBlock('difference()')
obstacles_block.append(height_diff) had_height_obstacles = None
height_union = OpenScadBlock('union()') height_union = OpenScadBlock('union()')
height_diff.append(height_union) height_diff.append(height_union)
for obstacle in obstacles: for obstacle in obstacles:
obstacle = obstacle.geom.buffer(0).intersection(geometry).buffer(0.01) obstacle = obstacle.geom.buffer(0).intersection(geometry)
obstacle = obstacle.buffer(0.01, join_style=JOIN_STYLE.mitre)
if not obstacle.is_empty:
had_height_obstacles = True
had_obstacles = True
height_union.append( height_union.append(
self._add_polygon(None, obstacle, self._add_polygon(None, obstacle,
min_slope_altitude-20, max_slope_altitude+height+10) min_slope_altitude-20, max_slope_altitude+height+10)
) )
if had_height_obstacles:
obstacles_block.append(height_diff)
height_diff.append( height_diff.append(
self._add_slope(bounds, altitudearea.altitude+height, altitudearea.altitude2+height, self._add_slope(bounds, altitudearea.altitude+height, altitudearea.altitude2+height,
altitudearea.point1, altitudearea.point2, bottom=False) altitudearea.point1, altitudearea.point2, bottom=False)
) )
if had_obstacles:
main_building_block.append(obstacles_diff_block)
obstacles_diff_block.append( obstacles_diff_block.append(
self._add_slope(bounds, altitudearea.altitude-10, altitudearea.altitude2-10, self._add_slope(bounds, altitudearea.altitude-10, altitudearea.altitude2-10,
altitudearea.point1, altitudearea.point2, bottom=True) altitudearea.point1, altitudearea.point2, bottom=True)
) )
else: else:
obstacles_block = OpenScadBlock('union()', comment=name + ' obstacles') obstacles_block = OpenScadBlock('union()', comment=name + ' obstacles')
main_building_block.append(obstacles_block) had_obstacles = False
for height, obstacles in altitudearea.obstacles.items(): for height, obstacles in altitudearea.obstacles.items():
for obstacle in obstacles: for obstacle in obstacles:
obstacle = obstacle.geom.buffer(0).intersection(geometry).buffer(0.01) obstacle = obstacle.geom.buffer(0).intersection(geometry)
obstacle = obstacle.buffer(0.01, join_style=JOIN_STYLE.mitre)
if not obstacle.is_empty:
had_obstacles = True
obstacles_block.append( obstacles_block.append(
self._add_polygon(None, obstacle, self._add_polygon(None, obstacle,
altitudearea.altitude-10, altitudearea.altitude+height) altitudearea.altitude-10, altitudearea.altitude+height)
) )
if had_obstacles:
main_building_block.append(obstacles_block)
def _add_polygon(self, name, geometry, minz, maxz): def _add_polygon(self, name, geometry, minz, maxz):
geometry = geometry.buffer(0) geometry = geometry.buffer(0)
polygons = [] polygons = []
@ -278,6 +293,9 @@ class OpenSCADNewEngine(Base3DEngine):
'rings': output_rings, 'rings': output_rings,
})) }))
if not polygons:
return None
extrude_cmd = 'linear_extrude(height=%f, convexity=10)' % (abs(maxz-minz)/1000) extrude_cmd = 'linear_extrude(height=%f, convexity=10)' % (abs(maxz-minz)/1000)
translate_cmd = 'translate([0, 0, %f])' % (min(maxz, minz)/1000) translate_cmd = 'translate([0, 0, %f])' % (min(maxz, minz)/1000)
return OpenScadBlock(translate_cmd, children=[OpenScadBlock(extrude_cmd, comment=name, children=polygons)]) return OpenScadBlock(translate_cmd, children=[OpenScadBlock(extrude_cmd, comment=name, children=polygons)])