예제 #1
0
vox011 = voxelsetboundary.cvar.vox011
vox111 = voxelsetboundary.cvar.vox111

voxels = {
    vox000: (0, 0, 0),
    vox100: (1, 0, 0),
    vox010: (0, 1, 0),
    vox110: (1, 1, 0),
    vox001: (0, 0, 1),
    vox101: (1, 0, 1),
    vox011: (0, 1, 1),
    vox111: (1, 1, 1)
}

# Define some planes to clip the voxel set boundaries.
skew = primitives.Point(1.1, 0.9, 1.0)
skew = skew / math.sqrt(skew * skew)
xyz = primitives.Point(1, 1, 1)
xyz = xyz / math.sqrt(xyz * xyz)

planes = [
    COrientedPlane(primitives.Point(1, 0, 0), 0.0),  # 0 empty
    COrientedPlane(primitives.Point(1, 0, 0), 4.0).reversed(),  # 1 empty
    COrientedPlane(primitives.Point(1, 0, 0), 0.0).reversed(),  # 2 all
    COrientedPlane(primitives.Point(1, 0, 0), 4.0),  # 3 all
    COrientedPlane(primitives.Point(1, 0, 0), 2.0),  # 4 through center
    COrientedPlane(primitives.Point(1, 0, 0), 2.5),  # 5
    COrientedPlane(primitives.Point(0, 1, 0), 2.5).reversed(),  # 6
    COrientedPlane(primitives.Point(0, 0, 1), 1.5),  # 7
    COrientedPlane(skew, 2.5),  # 8
    COrientedPlane(skew, 2.5).reversed(),  # 9
예제 #2
0
 def __init__(self, pixel, size):
     self.pixel = pixel
     self.point = primitives.Point(*(float(pixel[i]) * size[i] +
                                     0.5 * size[i]
                                     for i in range(config.dimension())))
예제 #3
0
 def moveCB(self, button):
     debug.mainthreadTest()
     xyz = [utils.OOFeval(text.get_text()) for text in self.texts]
     point = primitives.Point(*xyz)
     skelctxt = self.getSkeletonContext()
     subthread.execute(self.kbmove_subthread, (skelctxt, point))
예제 #4
0
 def up(self, x, y, button, shift, ctrl):
     self.endpoint = primitives.Point(x, y)
     self.toolbox.makeCS(self.startpoint, self.endpoint)
예제 #5
0
    def _read(self, datafile, prog):
        # readData gets data from the file, but does no processing
        data = self.readData(datafile, prog)
        rows = list(getrows(data))  # sorts data
        # The grid is hexagonal if the first two rows don't start at the same x.
        if rows[0][0].position[0] != rows[1][0].position[0]:
            # Throw out every other row.
            reporter.warn("Converting hexagonal lattice to rectangular"
                          " by discarding alternate rows.")
            rows = rows[::2]  # discard odd numbered rows

        # Check that all rows are the same length, and flip the
        # coordinates if requested.
        nx = len(rows[0])
        ny = len(rows)
        ymax = rows[-1][0].position[1]
        ymin = rows[0][0].position[1]
        xmax = rows[0][-1].position[0]
        xmin = rows[0][0].position[0]
        count = 0
        for row in rows:
            count += 1
            if len(row) != nx:
                raise ooferror.ErrUserError(
                    "Orientation map data appears to be incomplete.\n"
                    "len(row 0)=%d len(row %d)=%d" % (nx, count, len(row)))
            for point in row:
                if self.flip_x:
                    point.position[0] = xmax - point.position[0]
                else:
                    point.position[0] = point.position[0] - xmin
                if self.flip_y:
                    point.position[1] = ymax - point.position[1]
                else:
                    point.position[1] = point.position[1] - ymin

        # pixel size
        dx = abs(rows[0][1].position[0] - rows[0][0].position[0])
        dy = abs(rows[0][0].position[1] - rows[1][0].position[1])
        pxlsize = primitives.Point(dx, dy)

        width = abs(rows[0][0].position[0] - rows[0][-1].position[0])
        height = abs(rows[0][0].position[1] - rows[-1][0].position[1])
        # If we assume that the points are in the centers of the
        # pixels, then the actual physical size is one pixel bigger
        # than the range of the xy values.
        size = primitives.Point(width, height) + pxlsize

        npts = len(rows) * len(rows[0])

        od = orientmapdata.OrientMap(primitives.iPoint(nx, ny),
                                     size * self.scale_factor)
        prog.setMessage("%d/%d orientations" % (0, npts))
        count = 0
        for row in rows:
            for datum in row:
                ij = primitives.iPoint(
                    int(round(datum.position[0] / pxlsize[0])),
                    int(round(datum.position[1] / pxlsize[1])))
                for groupname in datum.groups:
                    try:
                        self.groupmembers[groupname].append(ij)
                    except KeyError:
                        self.groupmembers[groupname] = [ij]
                if self.angle_units == 'Degrees':
                    offset = math.radians(self.angle_offset)
                    angleargs = datum.angletuple
                else:  # angle units are Radians
                    offset = self.angle_offset
                    # All Orientation subclasses that take angle args
                    # assume that they're in degrees.  They have a
                    # static radians2Degrees method that converts the
                    # angle args from radians to degrees.
                    angleargs = self.angle_type.radians2Degrees(
                        *datum.angletuple)
                # Create an instance of the Orientation subclass.
                orient = self.angle_type(*angleargs)
                if self.angle_offset != 0:
                    orient = orient.rotateXY(self.angle_offset)

                # Insert this point into the OrientMap object.
                self.set_angle(od, ij, orient.corient)

                prog.setMessage("%d/%d orientations" % (count, npts))
                prog.setFraction(float(count) / npts)
                count += 1
                if prog.stopped():
                    return None
        return od
예제 #6
0
    def get_endpoints(self):
        # Dimension-independent version copied from OOF3D for testing
        # here.
        DIM = 2
        cs_obj = self.meshctxt.getCrossSection(self.cross_section)
        bounds = self.meshctxt.size()
        errmsg = ("Segment %s, %s is entirely outside the mesh." %
                  (cs_obj.start, cs_obj.end))
        # Check that both endpoints aren't out of bounds on the same
        # side of the bounding box in any dimension.
        for i in range(DIM):
            if ((cs_obj.start[i] < 0 and cs_obj.end[i] < 0) or
                (cs_obj.start[i] > bounds[i] and cs_obj.end[i] > bounds[i])):
                raise ooferror.ErrUserError(errmsg)

        # If an endpoint is out of bounds in any dimension, project it
        # back onto the bounding planes.  First, clone the endpoints
        # so that we aren't modifying the data in the cross section
        # object.
        real_start = primitives.Point(*tuple(cs_obj.start))
        real_end = primitives.Point(*tuple(cs_obj.end))
        for i in range(DIM):
            direction = real_end - real_start
            otherdims = [(i + j) % DIM for j in range(1, DIM)]
            if real_start[i] < 0:
                # direction[i] can't be zero if real_start[i] < 0 or
                # else the bounding box check above would have failed.
                alpha = -real_start[i] / direction[i]
                for j in otherdims:
                    real_start[j] += alpha * direction[j]
                real_start[i] = 0  # don't allow roundoff
            elif real_start[i] > bounds[i]:
                alpha = (real_start[i] - bounds[i]) / direction[i]
                for j in otherdims:
                    real_start[j] -= alpha * direction[j]
                real_start[i] = bounds[i]

            if real_end[i] < 0:
                alpha = -real_end[i] / direction[i]
                for j in otherdims:
                    real_end[j] += alpha * direction[j]
                real_end[i] = 0
            elif real_end[i] > bounds[i]:
                alpha = (real_end[i] - bounds[i]) / direction[i]
                for j in otherdims:
                    real_end[j] -= alpha * direction[j]
                real_end[i] = bounds[i]

        # Check that the clipped segment isn't infinitesimal.  This
        # can happen if it grazes a corner of the Microstructure.
        seg = real_end - real_start
        if seg * seg == 0:
            raise ooferror.ErrUserError(errmsg)

        # Check that the modified points are within bounds.  It's
        # possible that they're not if the original points were placed
        # sufficiently perversely.
        for i in range(DIM):
            if not (0 <= real_start[i] <= bounds[i]
                    and 0 <= real_end[i] <= bounds[i]):
                raise ooferror.ErrUserError(errmsg)

        return (real_start, real_end)
예제 #7
0
    def realelement_shares(self, skeleton, mesh, index, fe_node, curnodeindex,
                           elemdict, materialfunc):
        # Be safe with indices.
        if self.meshindex is None:  # Zero is nontrivial index.
            self.meshindex = index
        else:
            if index != self.meshindex:
                raise ooferror2.ErrPyProgrammingError(
                    "Index mismatch in element construction.")

        nnewnodes = 0
        ncn = len(self.nodes)  # Corner nodes.

        # elemdict is a dictionary of MasterElements, keyed by number
        # of sides.
        elementtype = elemdict[self.nnodes()]
        nodes = []  # real nodes for this element

        for i in range(len(self.nodes)):  # i.e. for each edge...
            c0 = self.nodes[i]
            nodes.append(fe_node[c0])  # Corner nodes already exist.
            c1 = self.nodes[(i + 1) % ncn]
            cset = skeletonnode.canonical_order(c0, c1)

            # Look up this edge in the dictionary.  If it's there,
            # then nodes have been created on the edge already, and we
            # should reuse them.

            try:
                xtranodes = mesh.getEdgeNodes(cset)
                # The nodes were created by the neighboring element.
                # Since elements traverse their edges counterclockwise
                # when creating nodes, the preexisting nodes are in
                # the wrong order for the current element.
                xtranodes.reverse()
            except KeyError:
                newindexinc = 0
                newindex = 0
                protocount = 0
                protodiclength = len(elementtype.protodic[i])
                if c0.index < c1.index:
                    newindexinc = 1
                    newindex = skeleton.maxnnodes + 100 * c0.index
                else:
                    # Do this to distinguish the protonode on either
                    # side of a corner node that has a smaller index
                    # than either corner nodes of the collinear
                    # segments extending from that corner node.
                    newindexinc = -1
                    newindex = skeleton.maxnnodes + 100 * c1.index + 50 + protodiclength - 1

                # The edge wasn't in the dictionary.  It's a new edge.
                xtranodes = []
                # Loop over all protonodes on the current
                # edge of the new element
                for newproto in elementtype.protodic[i]:
                    masterxy = primitives.Point(newproto.mastercoord()[0],
                                                newproto.mastercoord()[1])
                    realxy = self.frommaster(masterxy, 0)
                    newnode = _makenewnode_shares(
                        mesh, newproto, coord.Coord(realxy.x, realxy.y), c0,
                        c1, newindex, protocount, protodiclength,
                        skeleton.maxnnodes)
                    newindex += newindexinc
                    protocount += 1
                    nnewnodes = nnewnodes + 1
                    xtranodes.append(newnode)
                mesh.addEdgeNodes(cset, xtranodes)
            #Should this be 'join'ed instead, for speed?
            nodes = nodes + xtranodes

        # Interior nodes at the end.
        for newproto in elementtype.protodic['interior']:
            masterxy = primitives.Point(newproto.mastercoord()[0],
                                        newproto.mastercoord()[1])
            realxy = self.frommaster(masterxy, 0)
            newnode = _makenewnode(mesh, newproto,
                                   coord.Coord(realxy.x, realxy.y))
            nnewnodes = nnewnodes + 1
            nodes.append(newnode)
            mesh.addInternalNodes(self, newnode)

        # Having constructed the list of nodes, call the real
        # element's constructor.
        realel = elementtype.build(self, materialfunc(self, skeleton), nodes)
        # Long-lost cousin of Kal-El and Jor-El.

        mesh.addElement(realel)  # Add to mesh.
        # Tell the element about its exterior edges.
        for edge in self.exterior_edges:
            realel.set_exterior(fe_node[edge[0]], fe_node[edge[1]])

        return nnewnodes
예제 #8
0
    def screenCoordsTo3DCoords(self, selectionX, selectionY):
        # We need to use the renderer to convert coordinate systems in
        # order to find which point in the 3D structure, the 2D mouse
        # is pointing to.  We use the bounds of the image (or skeleton
        # or whatever) and the clipping plane to find the topmost
        # visible point.

        bounds = self.getBounds()

        windowY = self._RenderWindow.GetSize()[
            1]  #self.widget.window.get_size()[1]
        selectionY = windowY - selectionY - 1

        pickPosition = [0.0, 0.0, 0.0]
        point = None

        # get camera focal point and position, convert to display
        # coordinates
        cameraPos = list(self._Camera.GetPosition())
        cameraPos.append(1.0)
        cameraFP = list(self._Camera.GetFocalPoint())
        cameraFP.append(1.0)

        self._Renderer.SetWorldPoint(cameraFP)
        self._Renderer.WorldToDisplay()
        displayCoords = self._Renderer.GetDisplayPoint()
        selectionZ = displayCoords[2]

        # convert selection point into world coordinates
        self._Renderer.SetDisplayPoint(selectionX, selectionY, selectionZ)
        self._Renderer.DisplayToWorld()
        worldCoords = self._Renderer.GetWorldPoint()
        if (worldCoords[3] == 0.0):
            raise PyProgrammingError("Bad homogenous coordinates")
            return None
        for i in xrange(3):
            pickPosition[i] = worldCoords[i] / worldCoords[3]

        # compute ray endpoints. The ray is along the line running
        # from the camera position to the selection point, starting where
        # this line intersects the front clipping plane, and terminating
        # where this line intersects the back clipping plane.
        ray = [0.0, 0.0, 0.0]
        for i in xrange(3):
            ray[i] = pickPosition[i] - cameraPos[i]
        cameraDOP = self._Camera.GetDirectionOfProjection()

        rayLength = cameraDOP[0] * ray[0] + cameraDOP[1] * ray[1] + cameraDOP[
            2] * ray[2]
        if rayLength == 0.0:
            raise PyProgrammingError("Zero ray length")
            return None

        clipRange = self._Camera.GetClippingRange()

        tF = clipRange[0] / rayLength
        tB = clipRange[1] / rayLength
        p1World = [0.0, 0.0, 0.0, 0.0]
        p2World = [0.0, 0.0, 0.0, 0.0]
        for i in xrange(3):
            p1World[i] = cameraPos[i] + tF * ray[i]
            p2World[i] = cameraPos[i] + tB * ray[i]
        p1World[3] = p2World[3] = 1.0

        # Compute the tolerance in world coordinates.  Do this by
        # determining the world coordinates of the diagonal points of the
        # window, computing the width of the window in world coordinates, and
        # multiplying by the tolerance.
        viewport = self._Renderer.GetViewport()
        winSize = self._Renderer.GetRenderWindow().GetSize()
        x = winSize[0] + viewport[0]
        y = winSize[1] + viewport[1]
        self._Renderer.SetDisplayPoint(x, y, selectionZ)
        self._Renderer.DisplayToWorld()
        windowLowerLeft = self._Renderer.GetWorldPoint()

        x = winSize[0] + viewport[2]
        y = winSize[1] + viewport[3]
        self._Renderer.SetDisplayPoint(x, y, selectionZ)
        self._Renderer.DisplayToWorld()
        windowUpperRight = self._Renderer.GetWorldPoint()

        tol = 0.0
        for i in xrange(3):
            tol += (windowUpperRight[i] - windowLowerLeft[i]) * \
                (windowUpperRight[i] - windowLowerLeft[i])

        tol = math.sqrt(
            tol) * 0.025  #self.tol # TODO 3D: set sensible tolerance

        # end of stuff that was basically copied from vtkPicker::Pick

        # at this point, p1World is the point (in world coordinates)
        # where the ray intersects the first clipping plane, p2Worls
        # is where the ray intersects the back clipping plane.  tol is
        # the tolerance in world coordinates.

        # we want the point indices and/or point id of the
        # voxel that 1. intersects the ray 2. is in the front
        # 3. is within the bounds of the skeleton

        # simple strategy, increment along the ray by the
        # tolerance until we find a point that is within the
        # given bounds.

        # If we don't find something in the given bounds, then we
        # return the point on the near clipping plane

        currentPoint = p1World[0:3]
        lengthTraversed = 0.0
        rayInClippingRange = [
            p2World[0] - p1World[0], p2World[1] - p1World[1],
            p2World[2] - p1World[2]
        ]
        rayInCRLength = math.sqrt(rayInClippingRange[0]**2 +
                                  rayInClippingRange[1]**2 +
                                  rayInClippingRange[2]**2)
        direction = [
            rayInClippingRange[0] / rayInCRLength,
            rayInClippingRange[1] / rayInCRLength,
            rayInClippingRange[2] / rayInCRLength
        ]
        inc = (direction[0] * tol, direction[1] * tol, direction[2] * tol)
        while (lengthTraversed <= rayInCRLength and point is None):
            if currentPoint[0] >= bounds[0] and currentPoint[0] <= bounds[1] and \
                    currentPoint[1] >= bounds[2] and currentPoint[1] <= bounds[3] and \
                    currentPoint[2] >= bounds[4] and currentPoint[2] <= bounds[5]:
                point = primitives.Point(currentPoint[0], currentPoint[1],
                                         currentPoint[2])
            currentPoint = [
                currentPoint[0] + inc[0], currentPoint[1] + inc[1],
                currentPoint[2] + inc[2]
            ]
            lengthTraversed += tol

        if point is None:
            point = primitives.Point(p1World[0], p1World[1], p1World[2])
        return point
예제 #9
0
 def move(self, x, y, shift, ctrl):  # mouse move
     # Continue the collection of points, if it's been started...
     if self.points:
         self.points.append(primitives.Point(x,y))
예제 #10
0
    def _read(self, tslfile, prog):
        data, hexgrid = self.readData(tslfile, prog)
        npts = len(data)
        rows = list(getrows(data))  # sorts data
        if hexgrid is None:
            # readData didn't set hexgrid.  The grid is hexagonal if
            # the first two rows don't start at the same x.
            hexgrid = rows[0][0].position[0] != rows[1][0].position[0]

        if hexgrid:
            # Throw out every other row.
            reporter.warn("Converting hexagonal lattice to rectangular"
                          " by discarding alternate rows.")
            rows = rows[::2]  # discard odd numbered rows

        nx = len(rows[0])
        ny = len(rows)
        count = 0
        for row in rows:
            count += 1
            if len(row) != nx:
                raise ooferror.ErrUserError(
                    "Orientation map data appears to be incomplete.\n"
                    "len(row 0)=%d len(row %d)=%d" % (nx, count, len(row)))

        # TSL puts the origin at the top left, so it's using a left
        # handed coordinate system!  If flip_y==True, fix that.  Also,
        # make sure there are no negative x or y values.
        ymax = rows[-1][0].position[1]
        ymin = rows[0][0].position[1]
        xmax = rows[0][-1].position[0]
        xmin = rows[0][0].position[0]
        for row in rows:
            for point in row:
                if self.flip_x:
                    point.position[0] = xmax - point.position[0]
                else:
                    point.position[0] = point.position[0] - xmin
                if self.flip_y:
                    point.position[1] = ymax - point.position[1]
                else:
                    point.position[1] = point.position[1] - ymin

        # If flipped, the rows are still ordered top to bottom, but
        # the coordinates increase bottom to top.

        # pixel size
        dx = abs(rows[0][1].position[0] - rows[0][0].position[0])
        dy = abs(rows[0][0].position[1] - rows[1][0].position[1])
        pxlsize = primitives.Point(dx, dy)

        width = abs(rows[0][0].position[0] - rows[0][-1].position[0])
        height = abs(rows[0][0].position[1] - rows[-1][0].position[1])
        # If we assume that the points are in the centers of the
        # pixels, then the actual physical size is one pixel bigger
        # than the range of the xy values.
        size = primitives.Point(width, height) + pxlsize

        od = orientmapdata.OrientMap(primitives.iPoint(nx, ny), size)
        prog.setMessage("%d/%d orientations" % (0, npts))
        count = 0
        for row in rows:
            for datum in row:
                ij = primitives.iPoint(
                    int(round(datum.position[0] / pxlsize[0])),
                    int(round(datum.position[1] / pxlsize[1])))
                try:
                    self.phaselists[datum.phasename].append(ij)
                except KeyError:
                    self.phaselists[datum.phasename] = [ij]
                self.set_angle(od, ij, datum.euler())
                prog.setMessage("%d/%d orientations" % (count, npts))
                prog.setFraction(float(count) / npts)
                count += 1
                if prog.stopped():

                    return None
        prog.finish()
        return od
예제 #11
0
 def recalibrate(self, point):
     return primitives.Point(point.x, -point.y)
예제 #12
0
파일: outputDefs.py 프로젝트: song2001/OOF2
def _disp2point(mesh, elements, coords, field):
    # Convert displacement field OutputVals to Points
    return [primitives.Point(f[disp0], f[disp1]) for f in field]
예제 #13
0
파일: tsl.py 프로젝트: pk-organics/OOF3D
    def readfile(self, filename, prog, z=0):
        tslfile = file(filename, "r")
        prog.setMessage("Reading " + filename)
        count = 1  # line counter
        lines = tslfile.readlines()
        nlines = len(lines)
        data = utils.ReservableList(nlines)
        angletype = None
        for line in lines:
            if line[0] == '#':
                if line.startswith("Column 1-3", 2):
                    if "radians" in line:
                        angletype = "radians"
                    else:
                        angletype = "degrees"
                    debug.fmsg("Angles are in %s." % angletype)
            else:  # line[0] != '#'
                substrings = line.split()
                if len(substrings) < 5:
                    raise ooferror.ErrUserError(
                        "Too few numbers in line %d of %s" % (count, filename))
                values = map(float, substrings[:5])
                if angletype == "radians":
                    angles = values[:3]
                elif angletype == "degrees":
                    angles = map(math.radians, values[:3])
                else:
                    raise ooferror.ErrDataFileError(
                        "Angle type not specified in TSL data file")
                orientation = corientation.COrientBunge(*angles)
                if config.dimension() == 2:
                    point = primitives.Point(values[3], values[4])
                elif config.dimension() == 3:
                    point = primitives.Point(values[3], values[4], z)
                data.append(
                    DataPoint(
                        point,  # position
                        angles,
                        ' '.join(substrings[10:])))  # phase name
            count += 1  # count actual file lines, comments and all
            prog.setMessage("read %d/%d lines" % (count, nlines))
            prog.setFraction(float(count) / nlines)
        npts = len(data)
        debug.fmsg("read %d lines, %d data points" % (count, npts))

        # We don't yet know if the points are on a rectangular or a
        # hexagonal lattice, so split the data up into rows.
        # getrows() is a generator, but we need an actual list so that
        # we can index into it.
        rows = list(getrows(data))

        if len(rows) < 2:
            raise ooferror.ErrUserError(
                "Orientation map data has too few rows.")
        if rows[0][0].position[0] != rows[1][0].position[0]:
            # Must be a hexagonal lattice.  Throw out every other row.
            reporter.warn(
                "Converting hexagonal lattice to rectangular by discarding alternate rows."
            )
            rows = rows[::2]  # discard odd numbered rows

        return rows, npts
예제 #14
0
 def getPoint(self, x, y):
     if config.dimension() == 2:
         return primitives.Point(x, y)
     elif config.dimension() == 3:
         return self.gfxwindow().oofcanvas.screenCoordsTo3DCoords(x, y)
예제 #15
0
def _segset2seglist(seg_set, direction, skel):

    if len(seg_set)==0:
        raise ooferror.ErrUserError(
            "Attempt to sequence null segment set.")
    
    (seg_list, node_list, winding_number) = skeletonsegment.segSequence(seg_set)
    
    # At this point, seg_list is an ordered list of adjacent
    # segments, and "node_list" is the corresponding set of nodes.
    # The path is a loop if node_list[0]==node_list[-1], otherwise
    # it's a simple path.

    # We may want to reverse this list, depending on the
    # setting of "direction".
    firstnode = node_list[0]
    lastnode = node_list[-1]
    
    startnode = firstnode
    # The winding number is used to handle the cases where the line
    # crosses a periodic boundary.
    if (firstnode != lastnode and firstnode not in lastnode.getPartners()) \
       or winding_number != [0,0]:
        # In case the first node and last node are partners, we set them
        # equal so that we can compare positions properly.
        if lastnode in firstnode.getPartners():
            lastnode = firstnode
        if direction == director.Director('Left to right'):
            if firstnode.position().x > \
               lastnode.position().x + winding_number[0]*skel.MS.size()[0]:
                seg_list.reverse()
                startnode = lastnode
        elif direction == director.Director('Right to left'):
            if firstnode.position().x < \
               lastnode.position().x + winding_number[0]*skel.MS.size()[0]:
                seg_list.reverse()
                startnode = lastnode
        elif direction == director.Director('Top to bottom'):
            if firstnode.position().y < \
               lastnode.position().y + winding_number[1]*skel.MS.size()[1]:
                seg_list.reverse()
                startnode = lastnode
        elif direction == director.Director('Bottom to top'):
            if firstnode.position().y > \
               lastnode.position().y + winding_number[1]*skel.MS.size()[1]:
                seg_list.reverse()
                startnode = lastnode
        else:
            # User specified clockwise or counterclockwise for a
            # non-loop segment set.  This is an error.
            raise ooferror.ErrUserError(
                "Clockwise or counterclockwise is for closed loops.")

    # Use the total area swept out by vectors from the origin to the
    # nodes along the path as we traverse the path in order to
    # determine if the existing sequence traces a clockwise or
    # counterclockwise path.  If two consecutive nodes in the
    # node_list are not the endpoints of a segment, we are crossing a
    # periodic boundary.  In this case, use the positions not to find
    # the area swept out, but to increment the position_adjustment
    # needed to unwrap the periodic boundary conditions.
    else: # firstnode==lastnode, loop case.
        startnode = None
        area = 0.0
        p0 = node_list[0].position()
        position_adjustment = primitives.Point(0,0)
        for i in range(1,len(node_list)):
            p1 = node_list[i].position() + position_adjustment
            if skel.findSegment(node_list[i],node_list[i-1]) is not None:
                area += p0.x * p1.y - p1.x * p0.y
                p0 = p1
            else:
                position_adjustment += p0 - p1
                # setting p0 = p1 here will be redundant as we
                # must now adjust positions by p0 - p1
            
        if direction == director.Director('Clockwise'):
            if area > 0.0:
                seg_list.reverse()
        elif direction == director.Director('Counterclockwise'):
            if area < 0.0:
                seg_list.reverse()
        else:
            # User specified an endpoint orientation on a loop.
            raise ooferror.ErrUserError(
                "Closed loops need clockwise or counterclockwise direction.")

    return (startnode, seg_list)
예제 #16
0
 def __init__(self, pixel, size):
     # "pixel" is an iPoint pixel index.
     self.pixel = pixel
     pt_x = float(self.pixel[0])*size[0] + 0.5*size[0]
     pt_y = float(self.pixel[1])*size[1] + 0.5*size[1]
     self.point = primitives.Point(pt_x, pt_y)
예제 #17
0
 def get_bounds(self):
     if parallel_enable.enabled():
         return self.skeleton.localbounds
     else:
         return primitives.Rectangle(primitives.Point(0.0, 0.0),
                                     self.ms.size())
예제 #18
0
 def down(self, x, y, button, shift, ctrl):
     self.startpoint = primitives.Point(x, y)
예제 #19
0
 def select(self, immidge, pointlist, selector):
     ms = immidge.getMicrostructure()
     isize = ms.sizeInPixels()
     psize = primitives.Point(*ms.sizeOfPixels())
     mpt = pointlist[0]
     selector(PointSelection(ms, mpt))
예제 #20
0
    def realelement(self, skeletoncontext, mesh, index, fe_node, seg_dict,
                    elemdict, materialfunc):
        # Create a real element corresponding to this skeleton
        # element. The elemdict argument is a dictionary (keyed by the
        # number of sides of the element) of MasterElement objects,
        # which contain the information needed to construct the real
        # elements.  "index" is the SkeletonElement's position in the
        # Skeleton's list, and "fe_node" is a dictionary of real nodes
        # in the FEMesh, indexed by their corresponding SkeletonNode
        # objects.  The lists give the nodes in the order in which
        # they were added to the element.

        # Be safe with indices.
        if self.meshindex is None:  # Zero is nontrivial index.
            self.meshindex = index
        else:
            if index != self.meshindex:
                raise ooferror2.ErrPyProgrammingError(
                    "Index mismatch in element construction.")

        nnewnodes = 0
        ncn = len(self.nodes)  # Corner nodes.

        # elemdict is a dictionary of MasterElements, keyed by number
        # of sides.
        elementtype = elemdict[self.nnodes()]
        nodes = []  # real nodes for this element

        for i in range(len(self.nodes)):  # i.e. for each edge...
            c0 = self.nodes[i]
            nodes.append(fe_node[c0])  # Corner nodes already exist.
            c1 = self.nodes[(i + 1) % ncn]
            cset = skeletonnode.canonical_order(c0, c1)

            # Look up this edge in the dictionary.  If it's there,
            # then nodes have been created on the edge already, and we
            # should reuse them.

            try:
                xtranodes = mesh.getEdgeNodes(cset)
                # The nodes were created by the neighboring element.
                # Since elements traverse their edges counterclockwise
                # when creating nodes, the preexisting nodes are in
                # the wrong order for the current element.
                xtranodes.reverse()
            except KeyError:
                # The edge wasn't in the dictionary.  It's a new edge.
                xtranodes = []
                # Loop over all protonodes on the current
                # edge of the new element
                for newproto in elementtype.protodic[i]:
                    masterxy = primitives.Point(newproto.mastercoord()[0],
                                                newproto.mastercoord()[1])
                    realxy = self.frommaster(masterxy, 0)
                    newnode = _makenewnode(mesh, newproto,
                                           coord.Coord(realxy.x, realxy.y))
                    nnewnodes = nnewnodes + 1
                    xtranodes.append(newnode)
                #Interface branch
                try:
                    #If the segment represented by cset is a member of an
                    #interface, then new edge nodes (xtranodes) will
                    #not be shared by another element.
                    test = seg_dict[cset]
                except KeyError:
                    mesh.addEdgeNodes(cset, xtranodes)
            nodes = nodes + xtranodes

        # Interior nodes at the end.
        for newproto in elementtype.protodic['interior']:
            masterxy = primitives.Point(newproto.mastercoord()[0],
                                        newproto.mastercoord()[1])
            realxy = self.frommaster(masterxy, 0)
            newnode = _makenewnode(mesh, newproto,
                                   coord.Coord(realxy.x, realxy.y))
            nnewnodes = nnewnodes + 1
            nodes.append(newnode)
            mesh.addInternalNodes(self, newnode)

        # Having constructed the list of nodes, call the real
        # element's constructor.  materialfunc returns the element's
        # material.  In normal operation, materialfunc is
        # SkeletonElement.realmaterial.
        realel = elementtype.build(self, materialfunc(self, skeletoncontext),
                                   nodes)

        mesh.addElement(realel)  # Add to mesh.
        # Tell the element about its exterior edges.
        for edge in self.exterior_edges:
            realel.set_exterior(fe_node[edge[0]], fe_node[edge[1]])

        return nnewnodes