def clip_surface(): """Clip the stl model.""" if not check_surface(): return itemlist = [['axis',0],['begin',0.0],['end',1.0],['nodes','any']] res,accept = widgets.inputDialog(itemlist,'Clipping Parameters').getResult() if accept: updateGUI() nodes,elems = PF['old_surface'] = PF['surface'] F = Formex(nodes[elems]) bb = F.bbox() GD.message("Original bbox: %s" % bb) xmi = bb[0][0] xma = bb[1][0] dx = xma-xmi axis = int(res[0][1]) xc1 = xmi + float(res[1][1]) * dx xc2 = xmi + float(res[2][1]) * dx nodid = res[3][1] print nodid clear() draw(F,color='yellow') w = F.test(nodes='any',dir=axis,min=xc1,max=xc2) F = F.clip(w) draw(F,clor='red')
def show_volume(): """Display the volume model.""" if PF['volume'] is None: return nodes,elems = PF['volume'] F = Formex(nodes[elems]) GD.message("BBOX = %s" % F.bbox()) clear() draw(F,color='random',eltype='tet') PF['vol_model'] = F
def center_surface(): """Center the stl model.""" if not check_surface(): return updateGUI() nodes,elems = PF['old_surface'] = PF['surface'] F = Formex(nodes.reshape((-1,1,3))) center = F.center() nodes = F.translate(-center).f PF['surface'] = nodes,elems clear() show_changes(PF['old_surface'],PF['surface'])
def rotate_surface(): """Rotate the stl model.""" if not check_surface(): return itemlist = [ [ 'axis',0], ['angle','0.0'] ] res,accept = widgets.inputDialog(itemlist,'Rotation Parameters').getResult() if accept: updateGUI() print res nodes,elems = PF['old_surface'] = PF['surface'] F = Formex(nodes.reshape((-1,1,3))) nodes = F.rotate(float(res[1][1]),int(res[0][1])).f PF['surface'] = nodes,elems clear() show_changes(PF['old_surface'],PF['surface'])
def scale_surface(): """Scale the stl model.""" if not check_surface(): return itemlist = [ [ 'X-scale',1.0], [ 'Y-scale',1.0], [ 'Z-scale',1.0] ] res,accept = widgets.inputDialog(itemlist,'Scaling Parameters').getResult() if accept: updateGUI() scale = map(float,[r[1] for r in res]) print scale nodes,elems = PF['old_surface'] = PF['surface'] F = Formex(nodes.reshape((-1,1,3))) nodes = F.scale(scale).f PF['surface'] = nodes,elems clear() show_changes(PF['old_surface'],PF['surface'])
def createGrid(): _data_ = _name_ + 'createGrid_data' dia = Dialog(items=[ _I('name', '__auto__'), _I('object type', choices=['Formex', 'Mesh', 'TriSurface']), _I('base', choices=base_patterns), _I('nx', 4), _I('ny', 2), _I('stepx', 1.), _I('stepy', 1.), _I('taper', 0), _I('bias', 0.), ]) if _data_ in pf.PF: dia.updateData(pf.PF[_data_]) res = dia.getResults() if res: pf.PF[_data_] = res name = res['name'] if name == '__auto__': name = autoName(res['object type']).next() F = Formex(res['base']).replic2(n1=res['nx'], n2=res['ny'], t1=res['stepx'], t2=res['stepy'], bias=res['bias'], taper=res['taper']) F = convertFormex(F, res['object type']) export({name: F}) selection.set([name]) if res['object type'] == 'TriSurface': surface_menu.selection.set([name]) selection.draw()
def readFormex(self, nelems, nplex, props, eltype, sep): """Read a Formex from a pyFormex geometry file. The coordinate array for nelems*nplex points is read from the file. If present, the property numbers for nelems elements are read. From the coords and props a Formex is created and returned. """ ndim = 3 f = readArray(self.fil, Float, (nelems, nplex, ndim), sep=sep) if props: p = readArray(self.fil, Int, (nelems, ), sep=sep) else: p = None return Formex(f, p, eltype)
def inside(self, pts): """Test which of the points pts are inside the surface. Parameters: - `pts`: a (usually 1-plex) Formex or a data structure that can be used to initialize a Formex. Returns an integer array with the indices of the points that are inside the surface. The indices refer to the onedimensional list of points as obtained from pts.points(). """ from formex import Formex if not isinstance(pts, Formex): pts = Formex(pts) pts = Formex(pts) #.asPoints() print(type(pts)) # determine bbox of common space of surface and points bb = bboxIntersection(self, pts) if (bb[0] > bb[1]).any(): # No bbox intersection: no points inside return array([], dtype=Int) # Limit the points to the common part # Add point numbers as property, to allow return of original numbers pts.setProp(arange(pts.nelems())) pts = pts.clip(testBbox(pts, bb)) # Apply the gtsinside shooting algorithm in three directions ins = zeros((pts.nelems(), 3), dtype=bool) for i in range(3): dirs = roll(arange(3), -i)[1:] # clip the surface perpendicular to the shooting direction S = self.clip(testBbox(self, bb, dirs)) # find inside points shooting in direction i ok = gtsinside(S, pts, dir=i) ins[ok, i] = True ok = where(ins.sum(axis=-1) > 1)[0] return pts.prop[ok]
def inside(self,pts): """Test which of the points pts are inside the surface. Parameters: - `pts`: a (usually 1-plex) Formex or a data structure that can be used to initialize a Formex. Returns an integer array with the indices of the points that are inside the surface. The indices refer to the onedimensional list of points as obtained from pts.points(). """ from formex import Formex if not isinstance(pts,Formex): pts = Formex(pts) pts = Formex(pts)#.asPoints() print(type(pts)) # determine bbox of common space of surface and points bb = bboxIntersection(self,pts) if (bb[0] > bb[1]).any(): # No bbox intersection: no points inside return array([],dtype=Int) # Limit the points to the common part # Add point numbers as property, to allow return of original numbers pts.setProp(arange(pts.nelems())) pts = pts.clip(testBbox(pts,bb)) # Apply the gtsinside shooting algorithm in three directions ins = zeros((pts.nelems(),3),dtype=bool) for i in range(3): dirs = roll(arange(3),-i)[1:] # clip the surface perpendicular to the shooting direction S = self.clip(testBbox(self,bb,dirs)) # find inside points shooting in direction i ok = gtsinside(S,pts,dir=i) ins[ok,i] = True ok = where(ins.sum(axis=-1) > 1)[0] return pts.prop[ok]
def draw(F, view=None,bbox=None, color='prop',colormap=None,alpha=0.5, mode=None,linewidth=None,shrink=None,marksize=None, wait=True,clear=None,allviews=False): """Draw object(s) with specified settings and direct camera to it. The first argument is an object to be drawn. All other arguments are settings that influence how the object is being drawn. F is either a Formex or a TriSurface object, or a name of such object (global or exported), or a list thereof. If F is a list, the draw() function is called repeatedly with each of ithe items of the list as first argument and with the remaining arguments unchanged. The remaining arguments are drawing options. If None, they are filled in from the current viewport drawing options. view is either the name of a defined view or 'last' or None. Predefined views are 'front','back','top','bottom','left','right','iso'. With view=None the camera settings remain unchanged (but might be changed interactively through the user interface). This may make the drawn object out of view! With view='last', the camera angles will be set to the same camera angles as in the last draw operation, undoing any interactive changes. The initial default view is 'front' (looking in the -z direction). bbox specifies the 3D volume at which the camera will be aimed (using the angles set by view). The camera position wil be set so that the volume comes in view using the current lens (default 45 degrees). bbox is a list of two points or compatible (array with shape (2,3)). Setting the bbox to a volume not enclosing the object may make the object invisible on the canvas. The special value bbox='auto' will use the bounding box of the objects getting drawn (object.bbox()), thus ensuring that the camera will focus on these objects. The special value bbox=None will use the bounding box of the previous drawing operation, thus ensuring that the camera's target volume remains unchanged. color,colormap,linewidth,alpha,marksize are passed to the creation of the 3D actor. shrink is a floating point shrink factor that will be applied to object before drawing it. If the Formex has properties and a color list is specified, then the the properties will be used as an index in the color list and each member will be drawn with the resulting color. If color is one color value, the whole Formex will be drawn with that color. Finally, if color=None is specified, the whole Formex is drawn in black. Each draw action activates a locking mechanism for the next draw action, which will only be allowed after drawdelay seconds have elapsed. This makes it easier to see subsequent images and is far more elegant that an explicit sleep() operation, because all script processing will continue up to the next drawing instruction. The value of drawdelay is set in the config, or 2 seconds by default. The user can disable the wait cycle for the next draw operation by specifying wait=False. Setting drawdelay=0 will disable the waiting mechanism for all subsequent draw statements (until set >0 again). """ if type(F) == list: actor = [] nowait = False for Fi in F: if Fi == F[-1]: nowait = wait actor.append(draw(Fi,view,bbox, color,colormap,alpha, mode,linewidth,shrink,marksize, wait=nowait,clear=clear,allviews=allviews)) if Fi == F[0]: clear = False view = None return actor if type(F) == str: F = named(F) if F is None: return None if isinstance(F,formex.Formex): pass elif isinstance(F,surface.TriSurface): pass elif isinstance(F,tools.Plane): pass elif hasattr(F,'toFormex'): F = F.toFormex() # keep this below trying the 'toFormex' !!! elif isinstance(F,coords.Coords): F = Formex(F) else: # Don't know how to draw this object raise RuntimeError,"draw() can not draw objects of type %s" % type(F) GD.GUI.drawlock.wait() if clear is None: clear = GD.canvas.options.get('clear',False) if clear: clear_canvas() if bbox is None: bbox = GD.canvas.options.get('bbox','auto') if view is not None and view != 'last': GD.debug("SETTING VIEW to %s" % view) setView(view) if shrink is None: shrink = GD.canvas.options.get('shrink',None) if marksize is None: marksize = GD.canvas.options.get('marksize',GD.cfg.get('marksize',5.0)) # Create the colors if color == 'prop': if hasattr(F,'p'): color = F.p else: color = colors.black elif color == 'random': # create random colors color = numpy.random.random((F.nelems(),3),dtype=float32) GD.GUI.setBusy() if shrink is not None: #GD.debug("DRAWING WITH SHRINK = %s" % shrink) F = _shrink(F,shrink) try: if isinstance(F,formex.Formex): if F.nelems() == 0: return None actor = actors.FormexActor(F,color=color,colormap=colormap,alpha=alpha,mode=mode,linewidth=linewidth,marksize=marksize) elif isinstance(F,surface.TriSurface): if F.nelems() == 0: return None actor = actors.TriSurfaceActor(F,color=color,colormap=colormap,alpha=alpha,mode=mode,linewidth=linewidth) elif isinstance(F,tools.Plane): return drawPlane(F.point(),F.normal(),F.size()) GD.canvas.addActor(actor) if view is not None or bbox not in [None,'last']: #GD.debug("CHANGING VIEW to %s" % view) if view == 'last': view = GD.canvas.options['view'] if bbox == 'auto': bbox = F.bbox() #GD.debug("SET CAMERA TO: bbox=%s, view=%s" % (bbox,view)) GD.canvas.setCamera(bbox,view) #setView(view) GD.canvas.update() GD.app.processEvents() #GD.debug("AUTOSAVE %s" % image.autoSaveOn()) if image.autoSaveOn(): image.saveNext() if wait: # make sure next drawing operation is retarded GD.GUI.drawlock.lock() finally: GD.GUI.setBusy(False) return actor
def toFormex(self): from formex import Formex x = stack([self.coords, roll(self.coords, -1, axis=0)], axis=1) return Formex(x)
def area(self): """Compute area inside a polygon. """ from plugins.section2d import PlaneSection return PlaneSection(Formex(self.coords)).sectionChar()['A']