Commit 7a637362 authored by sumpfralle's avatar sumpfralle

added a method for determining plane areas in a solid model

added a "get_area" method for triangles


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@805 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 8ee8595b
...@@ -83,11 +83,19 @@ class BaseModel(TransformableContainer): ...@@ -83,11 +83,19 @@ class BaseModel(TransformableContainer):
result += item.get_children_count() result += item.get_children_count()
return result return result
def to_OpenGL(self): def to_OpenGL(self, visible_filter=None):
def paint_item_filtered(item):
do_paint, color = visible_filter(item)
if do_paint:
item.to_OpenGL(color)
if visible_filter is None:
paint_item = lambda item: item.to_OpenGL()
else:
paint_item = paint_item_filtered
for item in self.next(): for item in self.next():
# ignore invisble things like the normal of a ContourModel # ignore invisble things like the normal of a ContourModel
if hasattr(item, "to_OpenGL"): if hasattr(item, "to_OpenGL"):
item.to_OpenGL() paint_item(item)
def is_export_supported(self): def is_export_supported(self):
return not self._export_function is None return not self._export_function is None
...@@ -184,6 +192,7 @@ class Model(BaseModel): ...@@ -184,6 +192,7 @@ class Model(BaseModel):
# enable/disable kdtree # enable/disable kdtree
self._use_kdtree = use_kdtree self._use_kdtree = use_kdtree
self._t_kdtree = None self._t_kdtree = None
self.__flat_groups_cache = {}
self.__uuid = None self.__uuid = None
@property @property
...@@ -208,6 +217,7 @@ class Model(BaseModel): ...@@ -208,6 +217,7 @@ class Model(BaseModel):
if self._use_kdtree: if self._use_kdtree:
self._t_kdtree = TriangleKdtree(self.triangles()) self._t_kdtree = TriangleKdtree(self.triangles())
self.__uuid = str(uuid.uuid4()) self.__uuid = str(uuid.uuid4())
self.__flat_groups_cache = {}
# the kdtree is up-to-date again # the kdtree is up-to-date again
self._dirty = False self._dirty = False
...@@ -238,6 +248,49 @@ class Model(BaseModel): ...@@ -238,6 +248,49 @@ class Model(BaseModel):
[len(p.get_lines()) for p in contour.get_polygons()])) [len(p.get_lines()) for p in contour.get_polygons()]))
return contour.get_polygons() return contour.get_polygons()
def get_flat_areas(self, min_area=None):
""" Find plane areas (combinations of triangles) bigger than 'min_area'
and ignore vertical planes. The result is cached.
"""
if not self.__flat_groups_cache.has_key(min_area):
def has_shared_edge(t1, t2):
count = 0
for p in (t1.p1, t1.p2, t1.p3):
if p in (t2.p1, t2.p2, t2.p3):
count += 1
return count >= 2
groups = []
for t in self.triangles():
# Find all groups with the same direction (see 'normal') that
# share at least one edge with the current triangle.
touch_groups = []
if t.normal.z == 0:
# ignore vertical triangles
continue
for group_index, group in enumerate(groups):
if t.normal == group[0].normal:
for group_t in group:
if has_shared_edge(t, group_t):
touch_groups.append(group_index)
break
if len(touch_groups) > 1:
# combine multiple areas with this new triangle
touch_groups.reverse()
combined = [t]
for touch_group_index in touch_groups:
combined.extend(groups.pop(touch_group_index))
groups.append(combined)
elif len(touch_groups) == 1:
groups[touch_groups[0]].append(t)
else:
groups.append([t])
# check the size of each area
if not min_area is None:
groups = [group for group in groups
if sum([t.get_area() for t in group]) >= min_area]
self.__flat_groups_cache[min_area] = groups
return self.__flat_groups_cache[min_area]
class ContourModel(BaseModel): class ContourModel(BaseModel):
......
...@@ -101,9 +101,11 @@ class Triangle(TransformableContainer): ...@@ -101,9 +101,11 @@ class Triangle(TransformableContainer):
# tree points per triangle # tree points per triangle
return 7 return 7
def to_OpenGL(self): def to_OpenGL(self, color=None):
if not GL_enabled: if not GL_enabled:
return return
if not color is None:
GL.glColor4f(*color)
GL.glBegin(GL.GL_TRIANGLES) GL.glBegin(GL.GL_TRIANGLES)
# use normals to improve lighting (contributed by imyrek) # use normals to improve lighting (contributed by imyrek)
normal_t = self.normal normal_t = self.normal
...@@ -219,3 +221,7 @@ class Triangle(TransformableContainer): ...@@ -219,3 +221,7 @@ class Triangle(TransformableContainer):
sub += Triangle(p4, self.p2, p5).subdivide(depth - 1) sub += Triangle(p4, self.p2, p5).subdivide(depth - 1)
return sub return sub
def get_area(self):
cross = self.p2.sub(self.p1).cross(self.p3.sub(self.p1))
return cross.norm / 2
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