def set_state(self, subppath): debug.mainthreadTest() path = labeltree.makePath(subppath) self.subpwidget.set_value(path) # Retrieve the subproblem from the widget, just in case # subppath wasn't a complete subproblem path. subpctxt = self.currentSubProblemContext() if subpctxt: # ie, path was complete subp = subpctxt.getObject() # CSubProblem object mesh = self.currentMesh() for fname,fld in allCompoundFields.items(): fdef = subp.is_defined_field(fld) self.fieldbuttons[(fname, "defined")].set(fdef) self.fieldbuttons[(fname, "active")].set_sensitive(fdef) if config.dimension() == 2: self.fieldbuttons[(fname, "inplane")].set_sensitive(fdef) if fdef: self.fieldbuttons[(fname, "active")].set( subp.is_active_field(fld)) if config.dimension() == 2: self.fieldbuttons[(fname, "inplane")].set( mesh.in_plane(fld)) else: # field not defined self.fieldbuttons[(fname, "active")].set(0) if config.dimension() == 2: self.fieldbuttons[(fname, "inplane")].set(0) for eqn in equation.allEquations: active = subp.is_active_equation(eqn) self.eqnbuttons[(eqn.name(),"active")].set(active) else: # no current subproblem for button in self.fieldbuttons.values(): button.set(0) for button in self.eqnbuttons.values(): button.set(0) self.sensitize()
def findSignature(marks): if config.dimension() == 2: # Given a list of subdivisions of sides (marks), rotate a # canonical starting point for the list, so that it can be used as # an index into a table of refinement functions. For a list # [x,y,z], the canonical order is that which maximizes the number # xyz in base arbitrary_factor. This will fail if edges are ever # divided into more than arbitrary_factor segments in one # refinement operation. n = len(marks) max = -1 imax = None for i in range(n): key = marks[i] for j in range(1, n): key = arbitrary_factor * key + marks[(i + j) % n] if key > max: max = key imax = i return imax, tuple([marks[(i + imax) % n] for i in range(n)]) elif config.dimension() == 3: sig = [] for i in range(len(marks)): if marks[i]: sig.append(i) return tuple(sig)
def cross(self, other): if config.dimension() == 2: return self.x*other.y - self.y*other.x elif config.dimension() == 3: return Point(self.y*other.z-self.z*other.y, self.z*other.x-self.x*other.z, self.x*other.y-self.y*other.x)
def __call__(self, image): if config.dimension() == 2: dbls = oofimage.grayify(image) bools = oofimage.threshold(dbls,self.T) oofimage.setFromBool(image,bools) elif config.dimension() == 3: image.threshold(self.T)
def setCoordDisplay(self, selectionMethodReg, points): debug.mainthreadTest() for sig in self.entrychangedsignals: sig.block() try: if 'down' in selectionMethodReg.events: self.xdownentry.set_text(("%-8g" % points[0].x).rstrip()) self.ydownentry.set_text(("%-8g" % points[0].y).rstrip()) if config.dimension() == 3: self.zdownentry.set_text(("%-8g" % points[0].z).rstrip()) else: self.xdownentry.set_text('--') self.ydownentry.set_text('--') if config.dimension() == 3: self.zdownentry.set_text('--') if 'up' in selectionMethodReg.events: self.xupentry.set_text(("%-8g" % points[-1].x).rstrip()) self.yupentry.set_text(("%-8g" % points[-1].y).rstrip()) if config.dimension() == 3: self.zupentry.set_text(("%-8g" % points[-1].z).rstrip()) else: self.xupentry.set_text('--') self.yupentry.set_text('--') if config.dimension() == 3: self.zdownentry.set_text('--') finally: for sig in self.entrychangedsignals: sig.unblock()
def __hash__(self): # Comparison operators are written in terms of __getitem__ so that # comparison to Coords and ICoords will work. if config.dimension() == 2: return hash(self.x) & hash(self.y) elif config.dimension() == 3: return hash(self.x) & hash(self.y) & hash(self.z)
def coreProcess(self, skel, processed, element): changes = [] nnodes = element.nnodes() lastnode = element.nodes[-1] # lastnode only used in 2D for node in element.nodes: if config.dimension() == 2: sister = element.getSister(skel, lastnode, node) if config.dimension() == 3: oppnodes = [n for n in element.nodes if n is not node] sister = element.getSister(skel, oppnodes) if sister is not None and sister not in processed: if config.dimension() == 2: snodes = sister.nnodes() if nnodes == 3: if snodes == 3: changes += tritriSwap(skel, lastnode, node, element, sister) elif snodes == 4: changes += triquadSwap(skel, lastnode, node, element, sister) elif nnodes == 4: if snodes == 3: changes += triquadSwap(skel, node, lastnode, sister, element) elif snodes == 4: changes += quadquadSwap(skel, lastnode, node, element, sister) elif config.dimension() == 3: changes += twoToThreeSwap(skel, element, sister, oppnodes) lastnode = node return changes
def updateAAInfo(self): # must be called on subthread debug.subthreadTest() ms = self.getCurrentMS() if ms is not None: activearea = ms.getObject().activearea activearea.begin_reading() try: aasize = activearea.size() mssize = ms.getObject().sizeInPixels() if config.dimension()==2: mpxls = mssize[0] * mssize[1] pixstring="pixels" elif config.dimension()==3: mpxls = mssize[0] * mssize[1] * mssize[2] pixstring="voxels" apxls = mpxls - aasize if ms.getObject().activearea.getOverride(): msg = "OVERRIDE: all %d %s are active" % (mpxls, pixstring) else: msg = "%d of %d %s are active" % (apxls, mpxls, pixstring) finally: activearea.end_reading() else: msg = "No Microstructure selected" mainthread.runBlock(self.aainfo.set_text, (msg,)) gtklogger.checkpoint("active area status updated")
def __init__(self, element, signature_info, transitionpoints): self.element = element if config.dimension() == 2: self.rotation = signature_info[0] # rotation of nodes wrt signature elif config.dimension() == 3: self.signature = signature_info self.transitionpoints = transitionpoints
def draw(self, gfxwindow, device): skel = self.who().resolve(gfxwindow) if skel is not None: device.set_lineColor(self.color) device.set_fillColorAlpha(self.color, color.alpha(self.opacity)) skel.elementselection.begin_reading() try: if config.dimension() == 2: for e in skel.elementselection.retrieve(): device.fill_polygon(primitives.Polygon([x.position() for x in e.nodes])) elif config.dimension() == 3: if len(skel.elementselection.retrieve()): gridPoints = skel.getObject().getPoints() grid = vtk.vtkUnstructuredGrid() numCells = len(skel.elementselection.retrieve()) grid.Allocate(numCells,numCells) grid.SetPoints(gridPoints) for e in skel.elementselection.retrieve(): grid.InsertNextCell(e.getCellType(), e.getPointIds()) device.draw_filled_unstructuredgrid(grid) finally: skel.elementselection.end_reading()
def predefinedPixelSelectionLayer(): if config.dimension() == 2: return bitoverlaydisplay.bitmapOverlay(color=defaultPixelSelectionColor, tintOpacity=defaultTintOpacity) if config.dimension() == 3: return bitoverlaydisplay.bitmapOverlay( color=defaultPixelSelectionColor, tintOpacity=defaultTintOpacity, voxelOpacity=defaultVoxelOpacity )
def move(self, x, y, shift, ctrl): debug.mainthreadTest() if config.dimension() == 2: self.xtext.set_text("%-11.4g" % x) self.ytext.set_text("%-11.4g" % y) point = primitives.Point(x,y) elif config.dimension() == 3: point = self.gfxwindow().oofcanvas.screenCoordsTo3DCoords(x,y) if point is not None: self.xtext.set_text("%-11.4g" % point[0]) self.ytext.set_text("%-11.4g" % point[1]) self.ztext.set_text("%-11.4g" % point[2]) if self.skeleton_context and point is not None: skel = self.skeleton_context.getObject() node = skel.nearestNode(point) if node: pos = node.position() self.nodextext.set_text("%-11.4g" % pos.x) self.nodeytext.set_text("%-11.4g" % pos.y) if config.dimension() == 3: self.nodeztext.set_text("%-11.4g" % pos.z) self.set_pintext(node) else: self.nodextext.set_text('') self.nodeytext.set_text('') if config.dimension() == 3: self.nodeztext.set_text('') self.set_pintext(None) gtklogger.checkpoint("Pin Nodes toolbox move event")
def queryElem(self, menuitem, position): context = self.gfxwindow().topwho(*self.whoset) if not context: return if parallel_enable.enabled(): meshIPC.ipcmeshmenu.Mesh_Info_Query(targetname="Element", position=position, mesh=context.path()) if mpitools.Rank()>0: return if position == self.last_position: meshpos = self.querier.mesh_position else: if config.dimension() == 2: try: context.restoreCachedData(self.gfxwindow().displayTime) try: meshpos = self.meshlayer.undisplaced_from_displaced( self.gfxwindow(), position) finally: context.releaseCachedData() except ooferror.ErrBoundsError: return elif config.dimension() == 3: # skip handling displaced meshes in 3D for now. # TODO 3D Later: figure this out meshpos = position femesh = context.getObject() skeleton = context.getSkeleton() selem = skeleton.enclosingElement(meshpos) felem = femesh.getElement(selem.meshindex) self.finishQuery(felem, felem, "Element", position, meshpos)
def __pow__(self, other): if other!=2: print "Power operation only defined for exponent equal to 2." if config.dimension() == 2: return self.x*self.x+self.y*self.y elif config.dimension() == 3: return self.x*self.x+self.y*self.y+self.z*self.z
def findSignature(transitionpoints): if config.dimension() == 2: # Returns the rotation and signature. n = len(transitionpoints) sig = [pt is not None for pt in transitionpoints] # 0's and 1's # put in canonical order max = -1 rotation = None for i in range(n): key = reduce(lambda x,y: 2*x+y, sig[i:]+sig[:i], 0) if key > max: max = key rotation = i return rotation, tuple(sig[rotation:] + sig[:rotation]) elif config.dimension() == 3: # rotations aren't useful in 3D and a list of edge ids is more # convenient TODO MAYBE: If we got rid of rotations in 2D here # and in refine and snaprefine, it would make some of the # other code neater. edges = [pt is not None for pt in transitionpoints] sig = [] for i in xrange(len(edges)): if edges[i]: sig.append(i) return tuple(sig)
def draw(self, gfxwindow, device): device.comment("Material Color") if config.dimension() == 2: themesh = self.who().resolve(gfxwindow) polygons = self.polygons(gfxwindow, themesh) # colorcache is a dictionary of colors keyed by Material. It # prevents us from having to call material.fetchProperty for # each element. colorcache = {} for polygon, material in zip(polygons, self.materials(gfxwindow, themesh)): if material is not None: try: # If material has been seen already, retrieve its color. color = colorcache[material] except KeyError: # This material hasn't been seen yet. try: colorprop = material.fetchProperty('Color') color = colorprop.color() except ooferror.ErrNoSuchProperty: color = None colorcache[material] = color if color is not None: device.set_fillColor(color) device.fill_polygon(primitives.Polygon(polygon)) elif config.dimension() == 3: # TODO 3D: clean up this code in general, perhaps the look # up table should be a member of the microstructure... themesh = self.who().resolve(gfxwindow).getObject() grid = themesh.skelgrid numCells = grid.GetNumberOfCells() # TODO 3D: will need to handle the creation and deletion of this array within canvas... materialdata = vtk.vtkIntArray() materialdata.SetNumberOfValues(numCells) grid.GetCellData().SetScalars(materialdata) lut = vtk.vtkLookupTable() colordict = {} for i in xrange(numCells): cat = themesh.elements[i].dominantPixel(themesh.MS) materialdata.SetValue(i,cat) mat = themesh.elements[i].material(themesh) if mat is not None: try: color = colordict[cat] except KeyError: colorprop = mat.fetchProperty('Color') color = colorprop.color() colordict[cat] = color lut.SetNumberOfColors(max(colordict.keys())+1) lut.SetTableRange(min(colordict.keys()), max(colordict.keys())) for i in colordict: color = colordict[i] if color is not None: lut.SetTableValue(i,color.getRed(),color.getGreen(),color.getBlue(),1) else: lut.SetTableValue(i,0,0,0,0) device.draw_unstructuredgrid_with_lookuptable(grid, lut, mode="cell", scalarbar=False)
def __eq__(self, other): try: if config.dimension() == 2: return self[0]==other[0] and self[1]==other[1] if config.dimension() == 3: return self[0]==other[0] and self[1]==other[1] and self[2]==other[2] except: return 0
def length(self): n0 = self.nodes()[0].position() n1 = self.nodes()[1].position() if config.dimension() == 2: return math.sqrt((n1.x-n0.x)*(n1.x-n0.x)+(n1.y-n0.y)*(n1.y-n0.y)) if config.dimension() == 3: return math.sqrt((n1.x-n0.x)*(n1.x-n0.x)+ (n1.y-n0.y)*(n1.y-n0.y)+(n1.z-n0.z)*(n1.z-n0.z))
def initialize_fields(self, mesh): if config.dimension() == 2: initializer = fieldinit.ConstTwoVectorFieldInit(cx=0.0,cy=0.0) elif config.dimension() == 3: initializer = fieldinit.ConstTwoVectorFieldInit(cx=0.0,cy=0.0,cz=0.0) meshmenu.initField(self, self.meshname, field.getField('Displacement'), initializer) meshmenu.applyFieldInits(self, self.meshname)
def __ne__(self, other): try: if config.dimension() == 2: return self[0]!=other[0] or self[1]!=other[1] if config.dimension() == 3: return self[0]!=other[0] or self[1]!=other[1] or self[2]!=other[2] except: return 1
def updateSomething(self, container): debug.subthreadTest() node = container.object skeleton = container.skeleton container.context.begin_reading() try: nindex = `node.getIndex()` if config.dimension() == 2: npos = "(%s, %s)" % (node.position().x, node.position().y) elif config.dimension() == 3: npos = "(%s, %s, %s)" % (node.position().x, node.position().y, node.position().z) if config.dimension() == 2: if node.movable_x() and node.movable_y(): nmob = "free" elif node.movable_x() and not node.movable_y(): nmob = "x only" elif not node.movable_x() and node.movable_y(): nmob = "y only" elif node.pinned(): nmob = "pinned" else: nmob = "fixed" elif config.dimension() == 3: if node.movable_x() and node.movable_y() and node.movable_z(): nmob = "free" elif node.movable_x() and node.movable_y() and not node.movable_z(): nmob = "x and y only" elif node.movable_x() and not node.movable_y() and node.movable_z(): nmob = "x and z only" elif not node.movable_x() and node.movable_y() and node.movable_z(): nmob = "y and z only" elif node.movable_x() and not node.movable_y() and not node.movable_z(): nmob = "x only" elif not node.movable_x() and node.movable_y() and not node.movable_z(): nmob = "y only" elif not node.movable_x() and not node.movable_y() and node.movable_z(): nmob = "z only" elif node.pinned(): nmob = "pinned" else: nmob = "fixed" self.updateElementList(self.elem, node.neighborElements()) self.syncPeeker(self.elem, "Element") self.updateGroup(node) bdys = [] for key, bdy in skeleton.pointboundaries.items(): if node in bdy.nodes: bdys.append(key) bdynames = string.join(bdys, ", ") finally: container.context.end_reading() mainthread.runBlock(self.updateSomething_thread, (nindex, npos, nmob, bdynames))
def drawNode(self, device, toolbox, node, which="query"): device.set_lineColor(self.colors[which]) device.set_lineWidth(self.node_size) if config.dimension() == 2: displaced_position = toolbox.meshlayer.displaced_from_undisplaced( toolbox.gfxwindow(), node.position()) device.draw_dot(displaced_position) elif config.dimension() == 3: device.draw_dot(node.position())
def __init__(self, name, isize, size): cmicrostructure.CMicrostructure.__init__(self, name, isize, size) self._isize = isize # iPoint(width, height) in pixels # Make sure that the physical size isn't stored as ints, which # could cause problems later (specifically when computing the # aspect ratio of the microstructure, as in # Skeleton.hashNodes). This *isn't* done in the Point # constructor, since it might be slow. if config.dimension() == 2: self._size = primitives.Point(float(size.x), float(size.y)) elif config.dimension() == 3: self._size = primitives.Point(float(size.x), float(size.y), float(size.z)) # Also store increments. if config.dimension() == 2: self._delta = (self._size[0]/self._isize[0], self._size[1]/self._isize[1]) elif config.dimension() == 3: self._delta = (self._size[0]/self._isize[0], self._size[1]/self._isize[1], self._size[2]/self._isize[2]) # The 'parent' arg to pixelselectionWhoClass.add and # activeareaWhoClass.add should be set to the Who object for # this MS, which hasn't been created yet. So it's set to None # here, and fixed later. pixsel = pixelselection.PixelSelection(isize, size, self) pixelselection.pixelselectionWhoClass.add(name, pixsel, parent=None) self.pixelselection = pixelselection.pixelselectionWhoClass[name] self.activearea = activearea.activeareaWhoClass.add( name, activearea.ActiveArea(isize, size, self), parent=None) self.namedActiveAreas = [] self.setCurrentActiveArea(self.activearea.getObject()) # Plug-ins have to be created before the Microstructure # context Who object is created, because Who object creation # might trigger switchboard calls that use the plug-ins. self.plugins = {} for pluginname, pluginclass in plugInClasses.items(): self.plugins[pluginname] = pluginclass(self) # Create the Who object for this Microstructure, and add it to # list of all Microstructures. Do this last, because it calls # switchboard callbacks that may assume that the MS is fully # constructed. mswho = microStructures.add(name, self, parent=None) # Fix the 'parent' for the pixelselection and activearea. See # comment above. self.pixelselection.setParent(mswho) self.activearea.setParent(mswho) self.sbcallbacks = [ switchboard.requestCallback(('who changed', 'Active Area'), self.aaChangedCB) ]
def coords(self): if config.dimension() == 2: for j in range(self._isize[1]): for i in range(self._isize[0]): yield primitives.iPoint(i, j) if config.dimension() == 3: for k in range(self._isize[2]): for j in range(self._isize[1]): for i in range(self._isize[0]): yield primitives.iPoint(i, j, k)
def _simple_skeleton_from_ms(menuitem, name, microstructure, skeleton_geometry): ms = microStructures[microstructure].getObject() x_elements = ms.sizeInPixels()[0] y_elements = ms.sizeInPixels()[1] if config.dimension() == 2: skel = skeleton.simpleSkeleton(name, ms, x_elements, y_elements, skeleton_geometry) elif config.dimension() == 3: z_elements = ms.sizeInPixels()[2] skel = skeleton.simpleSkeleton(name, ms, x_elements, y_elements, z_elements, skeleton_geometry) switchboard.notify("redraw")
def markElement(self, element, divisions, markedEdges): nnodes = element.nnodes() if config.dimension() == 2: for i in range(nnodes): markedEdges.mark(element.nodes[i], element.nodes[(i + 1) % nnodes], divisions) elif config.dimension() == 3: nsegments = element.getNumberOfEdges() for i in range(nsegments): segnodes = element.getSegmentNodes(i) markedEdges.mark(segnodes[0], segnodes[1], divisions)
def draw(self, gfxwindow, device): self.lock.acquire() try: device.comment("Skeleton Energy") skel = self.who().resolve(gfxwindow).getObject() if config.dimension() == 3: grid = skel.skelgrid numCells = grid.GetNumberOfCells() # TODO 3D: handle this array within the canvas # This can overwrite or be overwritten by SkeletonMaterialDisplay energydata = vtk.vtkDoubleArray() energydata.SetNumberOfValues(numCells) grid.GetCellData().SetScalars(energydata) # get polygons and element energy in one pass polyenergy = [(el.perimeter(), el.energyTotal(skel, self.alpha)) for el in skel.element_iterator() if not el.illegal()] # find actual range of data self.vmax = self.vmin = polyenergy[0][1] for (p,e) in polyenergy[1:]: if e > self.vmax: self.vmax = e if e < self.vmin: self.vmin = e # Set plot limits to either the actual data extremes, or # to the passed in values. Store the actual limits in # vmin and vmax. if self.max == automatic.automatic: max = self.vmax else: max = self.max self.vmax = max if self.min == automatic.automatic: min = self.vmin else: min = self.min self.vmin = min if max == min: max += 1.0 self.vmax += 1.0 min -= 1.0 self.vmin -= 1.0 if config.dimension()==2: device.set_colormap(self.colormap) for polygon, energy in polyenergy: device.set_fillColor((energy-min)/(max-min)) device.fill_polygon(primitives.Polygon(polygon)) elif config.dimension()==3: lut = self.colormap.getVtkLookupTable(self.contourmaplevels,min,max) for i in xrange(numCells): energydata.SetValue(i,skel.elements[i].energyTotal(skel, self.alpha)) device.draw_unstructuredgrid_with_lookuptable(grid, lut) finally: self.lock.release()
def drawElement(self, device, element, which="query"): device.set_lineColor(self.colors[which]) device.set_lineWidth(self.element_width) if config.dimension() == 2: for i in range(element.nnodes()): n0 = element.nodes[i] n1 = element.nodes[(i+1)%element.nnodes()] device.draw_segment(primitives.Segment(n0.position(), n1.position())) elif config.dimension() == 3: device.draw_cell(element)
def drawSegment(self, device, segment, which="query"): device.set_lineColor(self.colors[which]) device.set_lineWidth(self.segment_width) if config.dimension() == 2: device.draw_segment(primitives.Segment(segment.nodes()[0].position(), segment.nodes()[1].position())) elif config.dimension() == 3: # this is a hack, later on when vtk and oof are more # streamlined, we shouldn't have to create a vtkLine # twice. device.draw_cell(segment.getVtkLine())
def moveCB(self, button): debug.mainthreadTest() x = utils.OOFeval(self.xtext.get_text()) y = utils.OOFeval(self.ytext.get_text()) if config.dimension() == 2: point = primitives.Point(x,y) elif config.dimension() == 3: z = utils.OOFeval(self.ztext.get_text()) point = primitives.Point(x,y,z) skelctxt = self.getSkeletonContext() subthread.execute(self.kbmove_subthread, (skelctxt, point))
def clearPositionData(self): debug.mainthreadTest() self.xtext.set_text("") self.ytext.set_text("") self.mouse_xposition = None self.mouse_yposition = None self.mesh_xposition = None self.mesh_yposition = None if config.dimension() == 3: self.ztext.set_text("") self.mesh_zposition = None gtklogger.checkpoint(self.gfxwindow().name + " " + self._name + " cleared position")
def __init__(self, funcstr): # x and y are the current location and is guaranteed to be # provided. All others are provided if applicable. nx and ny # are the unit-vector components of the boundary normal at # this location. i is the node index, s is the arc length, # alpha is the fractional arc length. if config.dimension() == 2: strfunction.StrFunction.__init__(self, 'x, y, t, nx, ny, i, s, alpha', funcstr) else: strfunction.StrFunction.__init__(self, 'x, y, z, t, nx, ny, nz, i', funcstr)
def showPosition(self, mouse, mesh): debug.mainthreadTest() self.xtext.set_text("%-13.6g" % mesh[0]) self.ytext.set_text("%-13.6g" % mesh[1]) self.mouse_xposition = mouse[0] self.mouse_yposition = mouse[1] self.mesh_xposition = mesh[0] self.mesh_yposition = mesh[1] if config.dimension() == 3: self.ztext.set_text("%-13.6g" % mesh[2]) self.mesh_zposition = mesh[2] gtklogger.checkpoint(self.gfxwindow().name + " " + self._name + " showed position")
def displayMSInfo(self, *args): # *args is given because this is used as a switchboard # callback for ('rename who', 'Image') as well as being called # directly. This indicates either slovenliness or efficiency # on the part of the programmer. debug.subthreadTest() mscontext = self.currentMScontext() text = "" if mscontext is not None: mscontext.begin_reading() try: # ms might be None if the context was destroyed while # we were waiting for the read lock. ms = mscontext.getObject() if ms is not None: size = ms.sizeInPixels() if config.dimension() == 2: text += 'Pixel size: %dx%d\n' % (size.x, size.y) size = ms.size() text += 'Physical size: %sx%s\n' % (size.x, size.y) elif config.dimension() == 3: text += 'Voxel size: %dx%dx%d\n' % ( size.x, size.y, size.z) size = ms.size() text += 'Physical size: %sx%sx%s\n' % ( size.x, size.y, size.z) imagenames = ms.imageNames() if imagenames: text += 'Images:\n' for name in imagenames: text += ' ' + name + '\n' for infoplugin in self.infoplugins: plugintext = infoplugin(mscontext) if plugintext: text += plugintext + '\n' finally: mscontext.end_reading() mainthread.runBlock(self.infoarea.get_buffer().set_text, (text,))
def __call__(self, skelcontext, name): skelobj = skelcontext.getObject() seg_set = segments_from_node_aggregate(skelcontext, self.group) if not seg_set: raise ooferror.ErrUserError( "A unique segment sequence cannot be created" " from the given nodes.") if config.dimension() == 2: (startnode, seg_list) = _segset2seglist(seg_set, self.direction, skelobj) skelcontext.createEdgeBoundary(name, seg_list, startnode) else: # 3D segmentsequence = _segset2seglist3D(seg_set, self.direction) skelcontext.createEdgeBoundary3D(name, segmentsequence)
def draw(self, gfxwindow, device): skel = self.who().resolve(gfxwindow).getObject() elements = skel.getIllegalElements() if elements: device.set_lineColor(self.color) device.set_lineWidth(self.linewidth) if config.dimension() == 2: for el in elements: for i in range(el.nnodes()): n0 = el.nodes[i] n1 = el.nodes[(i + 1) % el.nnodes()] device.draw_segment( primitives.Segment(n0.position(), n1.position())) elif config.dimension() == 3: if len(elements): gridPoints = skel.getPoints() grid = vtk.vtkUnstructuredGrid() numCells = len(elements) grid.Allocate(numCells, numCells) grid.SetPoints(gridPoints) for el in elements: grid.InsertNextCell(el.getCellType(), el.getPointIds()) device.draw_unstructuredgrid(grid)
def __mul__(self, other): if config.dimension() == 2: if type(other)==types.InstanceType and \ (issubclass(other.__class__, self.__class__) or issubclass(self.__class__, other.__class__) ): return self.x * other.x + self.y * other.y elif type(other) == types.FloatType: return Point(other * self.x, other * self.y) elif type(other) == types.IntType: # Return whatever class you already are. return self.__class__(other * self.x, other * self.y) elif config.dimension() == 3: if type(other)==types.InstanceType and \ (issubclass(other.__class__, self.__class__) or issubclass(self.__class__, other.__class__) ): return self.x * other.x + self.y * other.y + self.z * other.z elif type(other) == types.FloatType: return Point(other * self.x, other * self.y, other * self.z) elif type(other) == types.IntType: # Return whatever class you already are. return self.__class__(other * self.x, other * self.y, other * self.z) raise TypeError
def create_mesh(self, context): ## context is a skeleton context ## setup element types edict = {} # get linear isoparametric master elements if config.dimension() == 2: edict[3] = masterelement.getMasterElementDict()['T3_3'] edict[4] = masterelement.getMasterElementDict()['Q4_4'] elif config.dimension() == 3: edict[4] = masterelement.getMasterElementDict()['T4_4'] skel = context.getObject() ## returns a Mesh (Who) object self.meshname = context.path() + ":__internal_mesh__" #Interface branch, pass skeleton path to femesh femesh = skel.femesh(edict, self.set_fakematerial, context.path()) meshcontext = ooflib.engine.mesh.meshes.add(self.meshname, femesh, parent=context, skeleton=skel, elementdict=edict) meshcontext.createDefaultSubProblem() return meshcontext
def __call__(self, skelcontext, name): skelobj = skelcontext.getObject() seg_set = skelcontext.segments_from_seg_aggregate(self.group) if config.dimension() == 2: (startnode, seg_list) = _segset2seglist(seg_set, self.direction, skelobj) # At this point, we have a correctly-sequenced list of segments. # Actually create the boundary. The context will create it in # the underlying object. skelcontext.createEdgeBoundary(name, seg_list, startnode) else: # 3D segmentsequence = _segset2seglist3D(seg_set, self.direction) skelcontext.createEdgeBoundary3D(name, segmentsequence)
def subpfieldlister(subp): # meshfunc for SubProblemFieldParameterWidgets # list fields and out-of-plane fields, if defined. try: compoundfields = subp.all_compound_fields() flds = [] for fld in compoundfields: flds.append(fld) if (config.dimension() == 2 and not subp.getParent().getObject().in_plane(fld)): flds.append(fld.out_of_plane()) return flds except: # This might be called with an unresolvable proxy if there # are no meshes. return []
def finish_up(self, ptlist, shift, ctrl, selmeth): # we convert the ptlist, which uses the 2d screen # coordinates to 3d coordinates using the canvas if config.dimension() == 3: vxllist = [] for pt in ptlist: vxllist.append( self.gfxwindow().oofcanvas.screenCoordsTo3DCoords(pt[0], pt[1], )) ptlist = vxllist self.setCoordDisplay(selmeth, ptlist) self.selectionMethodFactory.set_defaults() menuitem = getattr(self.toolbox.menu, selmeth.name()) menuitem.callWithDefaults(skeleton=self.getSourceName(), points=ptlist, shift=shift, ctrl=ctrl)
def updatePosition(self, position): # Switchboard callback for (gfxwindow, "meshinfo click"). # Also called when freezeSpaceFlag is unset, and during window # construction. debug.mainthreadTest() if not self.freezeSpaceFlag: if position != self.position: self.position = position subthread.execute(self.updateData) self.xsignal.block() self.ysignal.block() if config.dimension() == 3: self.zsignal.block() try: if position is not None: # Strip blanks to the right of the number so that they # don't get in the way when the user edits the # position. self.xText.set_text(("%-13.6g" % position.x).rstrip()) self.yText.set_text(("%-13.6g" % position.y).rstrip()) if config.dimension() == 3: self.zText.set_text(("%-13.6g" % position.z).rstrip()) else: # Probably not required -- position is initially None, # and having once been set, probably can't become # None. self.xText.set_text("") self.yText.set_text("") if config.dimension() == 3: self.zText.set_text("") finally: self.xsignal.unblock() self.ysignal.unblock() if config.dimension() == 3: self.zsignal.unblock() gtklogger.checkpoint(self._name + " position updated")
def meshfieldlister(meshctxt): # meshfunc for FieldParameterWidgets # list fields and out-of-plane fields, if defined. try: compoundfields = meshctxt.all_compound_subproblem_fields() flds = [] for fld in compoundfields: flds.append(fld) if config.dimension() == 2: if not meshctxt.getObject().in_plane(fld): flds.append(fld.out_of_plane()) return flds except: # This might be called with an unresolvable proxy if there # are no meshes. return []
def displayImageInfo(self): debug.subthreadTest() imagecontext = self.getCurrentImage() text = "" if imagecontext: imagecontext.begin_reading() try: if config.dimension() == 2: image = imagecontext.getObject() size = image.sizeInPixels() text += 'Pixel size: %dx%d\n' % (size.x, size.y) size = image.size() text += 'Physical size: %sx%s\n' % (size.x, size.y) if image.comment(): text += '\nComments:\n%s\n' % image.comment() elif config.dimension() == 3: image = imagecontext.getObject() size = image.sizeInPixels() text += 'Voxel size: %dx%dx%d\n' % (size.x, size.y, size.z) size = image.size() text += 'Physical size: %sx%sx%s\n' % (size.x, size.y, size.z) finally: imagecontext.end_reading() mainthread.runBlock(self.displayImageInfo_thread, (text,))
def resolveGlyphSize(self, glyphsize): # If the glyph size is 'automatic', choose a reasonable value # based on the average element size. if glyphsize is automatic.automatic: skelctxt = self.who().resolve(self.gfxwindow) if skelctxt is None: return 1.0 msctxt = skelctxt.parent sz = msctxt.getObject().size() vol = 1. for x in sz: # loop over components of a Coord vol *= x elvol = vol/skelctxt.getObject().nelements() # avg element volume linsize = elvol**(1./config.dimension()) # avg element size return 0.5*linsize return glyphsize # glyphsize is not 'automatic'
def _loadNodes(menuitem, skeleton, points): # read nodes as (x,y) tuples of floats skelcontext = skeletoncontext.skeletonContexts[skeleton] skeleton = skelcontext.getObject() npts = len(points) prog = progress.getProgress("Loading nodes", progress.DEFINITE) try: for i, node in enumerate(points): prog.setMessage("%d/%d" % (i, npts)) prog.setFraction(float(i) / npts) skeleton.addNode(node) finally: prog.finish() if config.dimension() == 2: skelcontext.updateGroupsAndSelections() switchboard.notify(('who changed', 'Skeleton'), skelcontext)
def updateNodeList(self, chsr, objlist, element=None): if element is None or config.dimension() == 3: namelist = [ "Node %d at %s" % (obj.uiIdentifier(), genericinfoGUI.posString(obj.position())) for obj in objlist ] else: # 2D, element given. Include angle info. namelist = [ "Node %d at %s (angle: %g)" % (obj.uiIdentifier(), genericinfoGUI.posString(obj.position()), element.getRealAngle(element.nodes.index(obj))) for obj in objlist ] mainthread.runBlock(chsr.update, (objlist, namelist))
def select(self, skeletoncontext, gfxwindow, pointlist, view, selector): pts = [] if config.dimension() == 3: pt = gfxwindow.findClickedPoint(skeletoncontext, pointlist[0], view) if pt is not None: # Calling nearestNode here seems to be repeating the # work that was already doen in findClickedPoint, but # that's not actually the case. findClickedPoint # works on a subgrid and doesn't use the same # vtkPoints as the skeleton, so it can't compute the # Node index. pts.append(skeletoncontext.getObject().nearestNode(pt)) else: # 2D pts.append(skeletoncontext.getObject().nearestNode(pointlist[0])) selector(pts)
class iPointParameter(parameter.Parameter): types = (primitives.iPoint,) def __init__(self, name, value=None, default=None, tip=None, auxData={}): if value is None: value = primitives.iOrigin() parameter.Parameter.__init__(self, name, value, default, tip, auxData) structfmt = '>' + 'i'*config.dimension() structlen = struct.calcsize(structfmt) def binaryRepr(self, datafile, value): return struct.pack(iPointParameter.structfmt, *value.asTuple()) def binaryRead(self, parser): b = parser.getBytes(iPointParameter.structlen) vals = struct.unpack(iPointParameter.structfmt, b) return primitives.iPoint(*vals) def valueDesc(self): return "An <link linkend='Object:iPoint'><classname>iPoint</classname></link> (integer Point) object (eg <userinput>iPoint(1,2)</userinput>)."
def set_boundary_conditions(self, mesh): ## here, mesh is a Mesh (Who) object displacement = field.getField('Displacement') if config.dimension() == 2: ## left boundary self.leftBoundaryCondition = \ bdycondition.DirichletBC(displacement, 'x', equation.getEquation('Force_Balance'), 'x', profile.ConstantProfile(0), 'left' ) self.leftBoundaryCondition.add_to_mesh('left', mesh.path()) ## right boundary self.rightBoundaryCondition = \ bdycondition.DirichletBC(displacement, 'x', equation.getEquation('Force_Balance'), 'x', profile.ConstantProfile(0), 'right' ) self.rightBoundaryCondition.add_to_mesh('right', mesh.path()) ## top boundary self.topBoundaryCondition = \ bdycondition.DirichletBC(displacement, 'y', equation.getEquation('Force_Balance'), 'y', profile.ConstantProfile(0), 'top' ) self.topBoundaryCondition.add_to_mesh('top', mesh.path()) ## bottom boundary self.bottomBoundaryCondition = \ bdycondition.DirichletBC(displacement, 'y', equation.getEquation('Force_Balance'), 'y', profile.ConstantProfile(0), 'bottom' ) self.bottomBoundaryCondition.add_to_mesh('bottom', mesh.path())
def activate(self): if not self.active: super(GenericSelectToolboxGUI, self).activate() if self.currentGUI is not None: self.currentGUI.activate() self.sensitize() self.setInfo() self.installMouseHandler() self.layerChangeCB() if config.dimension() == 3: self.gfxwindow().toolbar.setSelect() self.activecallbacks = [ # changeSignal is defined as class-level data in the # derived classes. switchboard.requestCallbackMain(self.changeSignal, self.changedSelection) ]
def _loadElements(menuitem, skeleton, nodes): # read elements as tuples of node indices skelcontext = skeletoncontext.skeletonContexts[skeleton] skeleton = skelcontext.getObject() nel = len(nodes) prog = progress.getProgress("Loading elements", progress.DEFINITE) try: for i, nodelist in enumerate(nodes): prog.setMessage("%d/%d" % (i, nel)) prog.setFraction(float(i) / nel) skeleton.loadElement(nodelist) finally: prog.finish() # skelcontext.getTimeStamp(None).increment() if config.dimension() == 2: skelcontext.updateGroupsAndSelections() switchboard.notify(('who changed', 'Skeleton'), skelcontext)
def __init__(self, gfxtoolbox): SkeletonInfoModeGUI.__init__(self, gfxtoolbox) row = 0 self.labelmaster((0, 1), (row, row + 1), 'index=') self.index = self.entrymaster((1, 2), (row, row + 1), editable=True) gtklogger.setWidgetName(self.index, "Index") self.indexChangedSignal = gtklogger.connect(self.index, 'changed', self.indexChangedCB) gtklogger.connect(self.index, 'activate', self.indexChangeDoneCB) row += 1 self.labelmaster((0, 1), (row, row + 1), 'elements=') self.elem = self.makeObjList("Element", (1, 2), (row, row + 1)) row += 1 if config.dimension() == 3: self.labelmaster((0, 1), (row, row + 1), 'faces=') self.faces = self.makeObjList("Face", (1, 2), (row, row + 1)) row += 1 self.labelmaster((0, 1), (row, row + 1), 'nodes=') self.nodes = self.makeObjList("Node", (1, 2), (row, row + 1)) row += 1 self.labelmaster((0, 1), (row, row + 1), 'length=') self.length = self.entrymaster((1, 2), (row, row + 1)) gtklogger.setWidgetName(self.length, "Length") row += 1 self.labelmaster((0, 1), (row, row + 1), 'homogeneity=') self.homog = self.entrymaster((1, 2), (row, row + 1)) gtklogger.setWidgetName(self.homog, "Homogeneity") row += 1 self.labelmaster((0, 1), (row, row + 1), 'segment groups=') self.group = self.entrymaster((1, 2), (row, row + 1)) gtklogger.setWidgetName(self.group, "Groups") self.group.set_sensitive( False) # TODO: remove this line when implemented row += 1 self.labelmaster((0, 1), (row, row + 1), 'boundary=') self.bndy = self.entrymaster((1, 2), (row, row + 1)) gtklogger.setWidgetName(self.bndy, "Boundary") row += 1
def isExternal(self, MS): p0 = self._nodes[0].position() p1 = self._nodes[1].position() if p0.x == 0.0 and p1.x == 0.0: return True if p0.x == MS.size()[0] and p1.x == MS.size()[0]: return True if p0.y == 0.0 and p1.y == 0.0: return True if p0.y == MS.size()[1] and p1.y == MS.size()[1]: return True if config.dimension() == 3: if p0.z == 0.0 and p1.z == 0.0: return True if p0.z == MS.size()[2] and p1.z == MS.size()[2]: return True return False
def move(self, x, y, shift, ctrl): # The toolbox is updated when the mouse *moves*, even before a # click, because it's displaying node information which helps # the user decide which node to click on. debug.mainthreadTest() ## TODO OPT: During a move, the skeleton context and view can't ## change, so it's inefficient to retrieve them here. They ## should be cached whenever they change. A previous attempt ## to do that missed some changes, so the caching was removed. skelctxt = self.getSkeletonContext() if config.dimension() == 2: self.move2(skelctxt, x, y) else: view = self.toolbox.gfxwindow().oofcanvas.get_view() canvas = self.toolbox.gfxwindow().oofcanvas pt = canvas.display2Physical(view, x, y) subthread.execute(self.move3, (skelctxt, view, pt))
def writeInfoBuffer(self, nNodes, nElements, illegalcount, shapecounts, homogIndex, left_right_periodicity, top_bottom_periodicity, front_back_periodicity): # Called by update() to actually fill in the data on the # main thread. debug.mainthreadTest() buffer = self.skelinfo.get_buffer() buffer.delete(buffer.get_start_iter(), buffer.get_end_iter()) if illegalcount > 0 : buffer.insert_with_tags(buffer.get_end_iter(), "WARNING: %d ILLEGAL ELEMENT%s.\n" % (illegalcount, "S"*(illegalcount!=1)), self.boldTag) buffer.insert(buffer.get_end_iter(), "Element data is unreliable.\n") buffer.insert(buffer.get_end_iter(), "Remove %s before proceeding.\n\n" % itORthem[illegalcount!=1]) buffer.insert(buffer.get_end_iter(), "No. of Nodes: %d\n" % nNodes) buffer.insert(buffer.get_end_iter(), "No. of Elements: %d\n" % nElements) for name in skeletonelement.ElementShapeType.names: buffer.insert(buffer.get_end_iter(), "No. of %ss: %d\n" % (name, shapecounts[name])) buffer.insert(buffer.get_end_iter(), "Left-Right Periodicity: %s\n" % left_right_periodicity) buffer.insert(buffer.get_end_iter(), "Top-Bottom Periodicity: %s\n" % top_bottom_periodicity) if config.dimension() == 3: buffer.insert(buffer.get_end_iter(), "Front-Back Periodicity: %s\n" % front_back_periodicity) if homogIndex is not None: buffer.insert(buffer.get_end_iter(), "Homogeneity Index: %s\n" % homogIndex) else: buffer.insert(buffer.get_end_iter(), "Homogeneity Index: ????\n") gtklogger.checkpoint("skeleton page info updated")
def select(self, immidge, gfxwindow, pointlist, view, selector): ms = immidge.getMicrostructure() if config.dimension() == 2: isize = ms.sizeInPixels() psize = primitives.Point(*ms.sizeOfPixels()) pt = ms.pixelFromPoint(pointlist[0]) else: # 3D cell = gfxwindow.findClickedCell(immidge, pointlist[0], view) if cell is not None: coord = vtkutils.cell2coord(cell) pt = ms.pixelFromPoint(coord) else: return pic = immidge.getObject() pic.update() ref_color = pic[pt] selector(pixelselectioncourieri.ColorSelection(ms, pic, ref_color, self.range))
def funcargs(self, location): if config.dimension() == 2: if location.normal is not None: nx = location.normal[0] ny = location.normal[1] else: nx = ny = None return (location.position[0], location.position[1], nx, ny, location.index, location.distance, location.fraction) else: # 3D if location.normal is not None: nx = location.normal[0] ny = location.normal[1] nz = location.normal[2] else: nx = ny = nz = None return (location.position[0], location.position[1], location.position[2], nx, ny, nz, location.index)
def select(self, skeletoncontext, gfxwindow, pointlist, view, selector): if config.dimension() == 3: cell = gfxwindow.findClickedCell(skeletoncontext, pointlist[0], view) if cell is not None: el = skeletoncontext.getObject().findElement(cell) if el: selector([el]) return selector([]) else: # 2D pt = pointlist[0] res = [] el = skeletoncontext.getObject().enclosingElement(pt) # TODO 3.1: why call interior here? if el and el.interior(pt): res = [el] selector(res)
def __init__(self, gfxtoolbox): SkeletonInfoModeGUI.__init__(self, gfxtoolbox) row = 0 self.labelmaster((0, 1), (row, row + 1), 'index=') self.index = self.entrymaster((1, 2), (row, row + 1), editable=True) gtklogger.setWidgetName(self.index, "Index") self.indexChangedSignal = gtklogger.connect(self.index, 'changed', self.indexChangedCB) gtklogger.connect(self.index, 'activate', self.indexChangeDoneCB) row += 1 self.labelmaster((0, 1), (row, row + 1), 'position=') self.pos = self.entrymaster((1, 2), (row, row + 1)) gtklogger.setWidgetName(self.pos, "Position") row += 1 self.labelmaster((0, 1), (row, row + 1), 'mobility=') self.mobility = self.entrymaster((1, 2), (row, row + 1)) gtklogger.setWidgetName(self.mobility, "Mobility") row += 1 self.labelmaster((0, 1), (row, row + 1), 'elements=') self.elem = self.makeObjList("Element", (1, 2), (row, row + 1)) row += 1 if config.dimension() == 3: self.labelmaster((0, 1), (row, row + 1), 'faces=') self.faces = self.makeObjList("Face", (1, 2), (row, row + 1)) row += 1 self.labelmaster((0, 1), (row, row + 1), 'segments=') self.segs = self.makeObjList("Segment", (1, 2), (row, row + 1)) row += 1 self.labelmaster((0, 1), (row, row + 1), 'node groups=') self.group = self.entrymaster((1, 2), (row, row + 1)) gtklogger.setWidgetName(self.group, "Group") row += 1 self.labelmaster((0, 1), (row, row + 1), 'boundary=') self.bndy = self.entrymaster((1, 2), (row, row + 1)) gtklogger.setWidgetName(self.bndy, "Boundary") row += 1