def areas(self): """area of elements For surface element the faces' area is returned. For volume elements the sum of the faces'areas is returned. """ #In case of quadratic faces, the face's area should be #the area inside the polygon of face vertices or #the area of the equivalent linear face? ##this function would require some changes (here proposed inside the function as starting): ##create a _default_surfacetype to create quad8 instead of hex8 ?maybe also a _default_volumetype to create tet4 instead of quad4 ? def defaultSurfacetype(nplex): """Default face type for a surface mesh with given plexitude. For the most common cases of plexitudes, we define a default face type. The full list of default types can be found in mesh._default_facetype. """ return _default_surfacetype.get(nplex,None) import geomtools nfacperel= len(self.eltype.faces[1])#nfaces per elem mf=Mesh(self.coords, self.getFaces())#mesh of all faces mf.eltype = elementType(defaultSurfacetype(mf.nplex())) ntriperfac= mf.select([0]).convert('tri3').nelems()#how many tri per face elfacarea = geomtools.areaNormals( mf.convert('tri3').toFormex()[:])[0].reshape(self.nelems(), nfacperel*ntriperfac)#elems'faces'areas return elfacarea.sum(axis=1)#elems'areas
def __init__(self,bbox,color=None,linewidth=None,**kargs): Actor.__init__(self,**kargs) self.color = color self.linewidth = linewidth self.bb = bbox Hex8 = elementType('hex8') self.vertices = Hex8.vertices * (bbox[1]-bbox[0]) + bbox[0] self.edges = Hex8.edges self.facets = Hex8.faces
def convertMesh(): """Transform the element type of the selected meshes. """ if not selection.check(): selection.ask() narrow_selection(Mesh) if not selection.names: return meshes = [ named(n) for n in selection.names ] eltypes = set([ m.eltype.name() for m in meshes if m.eltype is not None]) print "eltypes in selected meshes: %s" % eltypes if len(eltypes) > 1: warning("I can only convert meshes with the same element type\nPlease narrow your selection before trying conversion.") return if len(eltypes) == 1: fromtype = elementType(eltypes.pop()) choices = ["%s -> %s" % (fromtype,to) for to in fromtype.conversions.keys()] if len(choices) == 0: warning("Sorry, can not convert a %s mesh"%fromtype) return res = askItems([ _I('_conversion',itemtype='vradio',text='Conversion Type',choices=choices), _I('_compact',True), _I('_merge',itemtype='hradio',text="Merge Meshes",choices=['None','Each','All']), ]) if res: globals().update(res) print "Selected conversion %s" % _conversion totype = _conversion.split()[-1] names = [ "%s_converted" % n for n in selection.names ] meshes = [ m.convert(totype) for m in meshes ] if _merge == 'Each': meshes = [ m.fuse() for m in meshes ] elif _merge == 'All': print _merge coords,elems = mergeMeshes(meshes) print elems ## names = [ "_merged_mesh_%s" % e.nplex() for e in elems ] ## meshes = [ Mesh(coords,e,eltype=meshes[0].eltype) for e in elems ] ## print meshes[0].elems meshes = [ Mesh(coords,e,m.prop,m.eltype) for e,m in zip(elems,meshes) ] if _compact: print "compacting meshes" meshes = [ m.compact() for m in meshes ] export2(names,meshes) selection.set(names) clear() selection.draw()
def drawGL(self,canvas=None,mode=None,color=None,**kargs): """Draw the geometry on the specified canvas. The drawing parameters not provided by the Actor itself, are derived from the canvas defaults. mode and color can be overridden for the sole purpose of allowing the recursive use for modes ending on 'wire' ('smoothwire' or 'flatwire'). In these cases, two drawing operations are done: one with mode='wireframe' and color=black, and one with mode=mode[:-4]. """ from canvas import glLineStipple if canvas is None: canvas = pf.canvas if mode is None: mode = self.mode if mode is None: mode = canvas.rendermode if mode.endswith('wire'): self.drawGL(mode=mode[:-4]) # draw the lines without lights canvas.glLight(False) self.drawGL(mode='wireframe',color=asarray(black)) return ############# set drawing attributes ######### alpha = self.alpha if alpha is None: alpha = canvas.settings.alpha if color is None: color,colormap = self.color,self.colormap bkcolor, bkcolormap = self.bkcolor,self.bkcolormap else: # THIS OPTION IS ONLY MEANT FOR OVERRIDING THE COLOR # WITH THE EDGECOLOR IN ..wire DRAWING MODES # SO NO NEED TO SET bkcolor color,colormap = saneColor(color),None bkcolor, bkcolormap = None,None # convert color index to full colors if color is not None and color.dtype.kind == 'i': color = colormap[color] if bkcolor is not None and bkcolor.dtype.kind == 'i': bkcolor = bkcolormap[bkcolor] linewidth = self.linewidth if linewidth is None: linewidth = canvas.settings.linewidth if self.linewidth is not None: GL.glLineWidth(self.linewidth) if self.linestipple is not None: glLineStipple(*self.linestipple) if mode.startswith('smooth'): if hasattr(self,'specular'): fill_mode = GL.GL_FRONT import colors if color is not None: spec = color * self.specular# * pf.canvas.specular spec = append(spec,1.) else: spec = colors.GREY(self.specular)# * pf.canvas.specular GL.glMaterialfv(fill_mode,GL.GL_SPECULAR,spec) GL.glMaterialfv(fill_mode,GL.GL_EMISSION,spec) GL.glMaterialfv(fill_mode,GL.GL_SHININESS,self.specular) ################## draw the geometry ################# nplex = self.nplex() if nplex == 1: marksize = self.marksize if marksize is None: marksize = canvas.settings.pointsize # THIS SHOULD GO INTO drawPoints if self.elems is None: coords = self.coords else: coords = self.coords[self.elems] drawPoints(coords,color,alpha,marksize) elif nplex == 2: drawLines(self.coords,self.elems,color) # beware: some Formex eltypes are strings and may not # represent a valid Mesh elementType # THis is only here for Formex type. # We can probably remove it if we avoid eltype 'curve' elif nplex == 3 and self.eltype in ['curve','line3']: drawQuadraticCurves(self.coords,self.elems,color) elif self.eltype is None: # polygons if mode=='wireframe' : drawPolyLines(self.coords,self.elems,color) else: if bkcolor is not None: GL.glEnable(GL.GL_CULL_FACE) GL.glCullFace(GL.GL_BACK) drawPolygons(self.coords,self.elems,mode,color,alpha) if bkcolor is not None: GL.glCullFace(GL.GL_FRONT) drawPolygons(self.coords,self.elems,mode,bkcolor,alpha) GL.glDisable(GL.GL_CULL_FACE) else: el = elementType(self.eltype) if mode=='wireframe' or el.ndim < 2: for edges in el.getDrawEdges(el.name() in pf.cfg['draw/quadline']): drawEdges(self.coords,self.elems,edges,edges.eltype,color) else: for faces in el.getDrawFaces(el.name() in pf.cfg['draw/quadsurf']): print faces.report() if bkcolor is not None: # Enable drawing front and back with different colors GL.glEnable(GL.GL_CULL_FACE) GL.glCullFace(GL.GL_BACK) # Draw the front sides drawFaces(self.coords,self.elems,faces,faces.eltype,mode,color,alpha) if bkcolor is not None: # Draw the back sides GL.glCullFace(GL.GL_FRONT) drawFaces(self.coords,self.elems,faces,faces.eltype,mode,bkcolor,alpha) GL.glDisable(GL.GL_CULL_FACE)
def drawGL(self,canvas=None,mode=None,color=None,**kargs): """Draw the geometry on the specified canvas. The drawing parameters not provided by the Actor itself, are derived from the canvas defaults. mode and color can be overridden for the sole purpose of allowing the recursive use for modes ending on 'wire' ('smoothwire' or 'flatwire'). In these cases, two drawing operations are done: one with mode='wireframe' and color=black, and one with mode=mode[:-4]. """ if canvas is None: canvas = pf.canvas if mode is None: mode = self.mode if mode is None: mode = canvas.rendermode if mode != canvas.rendermode: canvas.overrideMode(mode) ############# set drawing attributes ######### avgnormals = self.avgnormals if avgnormals is None: avgnormals = canvas.settings.avgnormals lighting = canvas.settings.lighting alpha = self.alpha if alpha is None: alpha = canvas.settings.transparency bkalpha = self.bkalpha if bkalpha is None: bkalpha = canvas.settings.transparency if color is None: color,colormap = self.color,self.colormap bkcolor, bkcolormap = self.bkcolor,self.bkcolormap else: # THIS OPTION IS ONLY MEANT FOR OVERRIDING THE COLOR # WITH THE EDGECOLOR IN ..wire DRAWING MODES # SO NO NEED TO SET bkcolor # # NOT SURE IF WE STILL NEED THIS ! YES!!! # #raise ValueError,"THIS ERROR SHOULD NOT OCCUR: Contact mainitainers" color,colormap = saneColor(color),None bkcolor, bkcolormap = None,None # convert color index to full colors if color is not None and color.dtype.kind == 'i': color = colormap[color] if bkcolor is not None and bkcolor.dtype.kind == 'i': bkcolor = bkcolormap[bkcolor] linewidth = self.linewidth if linewidth is None: linewidth = canvas.settings.linewidth if self.linewidth is not None: GL.glLineWidth(self.linewidth) if self.linestipple is not None: glLineStipple(*self.linestipple) if mode.startswith('smooth'): if hasattr(self,'specular'): fill_mode = GL.GL_FRONT import colors if color is not None: spec = color * self.specular# * pf.canvas.specular spec = append(spec,1.) else: spec = colors.GREY(self.specular)# * pf.canvas.specular GL.glMaterialfv(fill_mode,GL.GL_SPECULAR,spec) GL.glMaterialfv(fill_mode,GL.GL_EMISSION,spec) GL.glMaterialfv(fill_mode,GL.GL_SHININESS,self.specular) ################## draw the geometry ################# nplex = self.nplex() if nplex == 1: marksize = self.marksize if marksize is None: marksize = canvas.settings.pointsize # THIS SHOULD GO INTO drawPoints if self.elems is None: coords = self.coords else: coords = self.coords[self.elems] drawPoints(coords,color,alpha,marksize) elif nplex == 2: drawLines(self.coords,self.elems,color) # beware: some Formex eltypes are strings and may not # represent a valid Mesh elementType # This is only here for Formex type. # We can probably remove it if we avoid eltype 'curve' elif nplex == 3 and self.eltype == 'curve': drawQuadraticCurves(self.coords,self.elems,color) elif self.eltype is None: # polygons if mode=='wireframe' : drawPolyLines(self.coords,self.elems,color) else: if bkcolor is not None: GL.glEnable(GL.GL_CULL_FACE) GL.glCullFace(GL.GL_BACK) drawPolygons(self.coords,self.elems,color,alpha,self.texture,None,None,lighting,avgnormals) if bkcolor is not None: GL.glCullFace(GL.GL_FRONT) drawPolygons(self.coords,self.elems,bkcolor,bkalpha,None,None,None,lighting,avgnormals) GL.glDisable(GL.GL_CULL_FACE) else: el = elementType(self.eltype) if mode=='wireframe' or el.ndim < 2: for edges in el.getDrawEdges(el.name() in pf.cfg['draw/quadline']): drawEdges(self.coords,self.elems,edges,edges.eltype,color) else: for faces in el.getDrawFaces(el.name() in pf.cfg['draw/quadsurf']): if bkcolor is not None: # Enable drawing front and back with different colors GL.glEnable(GL.GL_CULL_FACE) GL.glCullFace(GL.GL_BACK) drawFaces(self.coords,self.elems,faces,faces.eltype,color,alpha,self.texture,None,self.normals,lighting,avgnormals) if bkcolor is not None: # Draw the back sides GL.glCullFace(GL.GL_FRONT) drawFaces(self.coords,self.elems,faces,faces.eltype,bkcolor,bkalpha,None,None,self.normals,lighting,avgnormals) GL.glDisable(GL.GL_CULL_FACE)
def reduceDegenerate(self,target=None): """Reduce degenerate elements to lower plexitude elements. This will try to reduce the degenerate elements of the Connectivity to a lower plexitude. This is only possible if an element type was set in the Connectivity. This function uses the data of the Element database in :mod:`elements`. If a target element type is given, only the reductions to that element type are performed. Else, all the target element types for which a reduction scheme is available, will be tried. Returns: A list of Connectivities of which the first one contains the originally non-degenerate elements and the last one contains the elements that could not be reduced and may be empty. If the original Connectivity does not have an element type set, or the element type does not have any reduction schemes defined, a list with only the original is returned. Remark: If the Connectivity is part of a Mesh, you should use the Mesh.reduceDegenerate method instead, as that one will preserve the property numbers into the resulting Meshes. Example: >>> C = Connectivity([[0,1,2],[0,1,1],[0,3,2]],eltype='line3') >>> print C.reduceDegenerate() [Connectivity([[0, 1]]), Connectivity([[0, 1, 2], [0, 3, 2]])] """ from elements import elementType if not hasattr(self,'eltype'): return [ self ] eltype = elementType(self.eltype) if not hasattr(eltype,'degenerate'): return [ self ] # get all reductions for this eltype strategies = eltype.degenerate # if target, keep only those leading to target if target is not None: s = strategies.get(target,[]) if s: strategies = {target:s} else: strategies = {} if not strategies: return [self] e = self ML = [] for totype in strategies: elems = [] for conditions,selector in strategies[totype]: cond = array(conditions) w = (e[:,cond[:,0]] == e[:,cond[:,1]]).all(axis=1) sel = where(w)[0] if len(sel) > 0: elems.append(e[sel][:,selector]) # remove the reduced elems from m e = e[~w] if e.nelems() == 0: break if elems: elems = concatenate(elems) ML.append(Connectivity(elems,eltype=totype)) if e.nelems() == 0: break ML.append(e) return ML
def convertMesh(): """Transform the element type of the selected meshes. """ if not selection.check(): selection.ask() narrow_selection(Mesh) if not selection.names: return meshes = [named(n) for n in selection.names] eltypes = set([m.elName() for m in meshes]) print("eltypes in selected meshes: %s" % eltypes) if len(eltypes) > 1: warning( "I can only convert meshes with the same element type\nPlease narrow your selection before trying conversion." ) return if len(eltypes) == 1: fromtype = elementType(eltypes.pop()) choices = [ "%s -> %s" % (fromtype, to) for to in fromtype.conversions.keys() ] if len(choices) == 0: warning("Sorry, can not convert a %s mesh" % fromtype) return res = askItems([ _I('_conversion', itemtype='vradio', text='Conversion Type', choices=choices), _I('_compact', True), _I('_merge', itemtype='hradio', text="Merge Meshes", choices=['None', 'Each', 'All']), ]) if res: globals().update(res) print("Selected conversion %s" % _conversion) totype = _conversion.split()[-1] names = ["%s_converted" % n for n in selection.names] meshes = [m.convert(totype) for m in meshes] if _merge == 'Each': meshes = [m.fuse() for m in meshes] elif _merge == 'All': #print(_merge) coords, elems = mergeMeshes(meshes) #print(elems) ## names = [ "_merged_mesh_%s" % e.nplex() for e in elems ] ## meshes = [ Mesh(coords,e,eltype=meshes[0].elType()) for e in elems ] ## print meshes[0].elems meshes = [ Mesh(coords, e, m.prop, m.eltype) for e, m in zip(elems, meshes) ] if _compact: print("compacting meshes") meshes = [m.compact() for m in meshes] export2(names, meshes) selection.set(names) clear() selection.draw()