Example #1
0
	def startElement(self, name, attrs):
		'''FIXME'''
		#self.padding_level = self.padding_level + 1
		#self.current_element = name
		#self.padded_print(self.current_element)
		self.got_all_info = False  # set True when we have all required info for builder
		# Allow most elements through; builders must be turned into solids.
		if name != 'builder' and name != 'shape':
			self.passthrough = True  # allow these elements through unaltered
		elif name == 'builder':
			self.passthrough = False
			self.builder_info = attrs
		elif name == 'shape':
			self.passthrough = False
			self.shape_info = attrs
			# Now we (hopefully) have builder and shape info...
			self.got_all_info = True
		else:
			ldl.error('unknown element type' + name)

		if self.passthrough:
			self._downstream.startElement(name, attrs)
		else:
			if self.got_all_info:
				self.dispatch_macro(self.builder_info, self.shape_info)
				self.got_all_info = False
				self.builder_info = None
				self.shape_info = None
			else:
				pass  # wait for more info
Example #2
0
	def dispatch_macro(self, bi, si):
		'''Call the appropriate Macro'''
		type = si['type']
		if type == ldl.ST_STAIRS:
			self.macro_stairs(bi, si)
		elif type == ldl.ST_PLAT:
			self.macro_plat(bi, si)
		else:
			ldl.error('unkown macro type ' + type)
Example #3
0
	def macro_plat(self, bi, si):
		'''Make a plat
		Note that we don't specify the size of plat here as later we need to make it either at the top or the bottom of the larger brush.'''
		origin = ldl.getPoint(bi['origin'])
		size = ldl.getPoint(bi['extent'])
		if bi.has_key('texture'):
			texture = 'texture=\'' + bi['texture'] + '\' '
		else:
			texture = ''
		if si.has_key('position'):
			pos = si['position']  # DCP_UP or DCP_DOWN (top or bottomw
		else:
			ldl.error('plat given without a position (up or down)')
		print "<solid origin='" + str(origin) + "' extent='" + str(size) + "' " + texture + "type='plat' position='" + pos + "' />"
Example #4
0
	def _macro_stairs_match(self, full, individual):
		'''Take in the dimension of the whole staircase and that of an individual step;
		check that they divide w/o a remainder (i.e. the steps of length/height x fit an integer numer of times)
		If they don't, find another value for the dimension of the individual step that allows a whole number of steps to fit in.
		We allow a tollerance of 0.01.'''
		tolerance = 0.01
		difference = 1  # start high to get the loop going
		decrement = 0.01
		lower_bound = individual / 2  # abort if it reduces to this value

		if full/individual != int(full/individual):
			while individual > lower_bound and difference > tolerance:
				individual = individual - decrement
				difference = abs(full/individual - int(full/individual))
			if individual > lower_bound:
				return individual
			else:
				ldl.error('couldn\'t find a suitable step dimension')
		else:
			return individual
Example #5
0
def processNode(doc, parent, worldspawn, s, offset, node):
    global paddinglevel
    name = node.localName
    paddinglevel = paddinglevel + 1
    #	for i in range(paddinglevel):
    #		ldl.uprint(padding, True)
    #
    #	if name:
    #		ldl.uprint(name)
    #	else:
    #		ldl.uprint('(no name -- comment)')
    if node.localName == 'hollow':
        processHollow(doc, parent, worldspawn, s, offset, node)
    elif node.localName == 'solid':
        processSolid(doc, parent, worldspawn, s, offset, node)
    elif node.localName == 'entity':
        processEntity(doc, parent, offset, node)
    elif node.localName == None:
        pass  # comment node
    else:
        ldl.error('unknown element type ' + node.localName + '.\n')
    paddinglevel = paddinglevel - 1
Example #6
0
def processNode(doc, parent, worldspawn, s, offset, node):
	global paddinglevel
	name = node.localName
	paddinglevel = paddinglevel + 1
#	for i in range(paddinglevel):
#		ldl.uprint(padding, True)
#
#	if name:
#		ldl.uprint(name)
#	else:
#		ldl.uprint('(no name -- comment)')
	if node.localName == 'hollow':
		processHollow(doc, parent, worldspawn, s, offset, node)
	elif node.localName == 'solid':
		processSolid(doc, parent, worldspawn, s, offset, node)
	elif node.localName == 'entity':
		processEntity(doc, parent, offset, node)
	elif node.localName == None:
		pass  # comment node
	else:
		ldl.error('unknown element type ' + node.localName + '.\n')
	paddinglevel = paddinglevel - 1
Example #7
0
def processInfo(doc, map):
	info = map.firstChild
	for property in info.childNodes:
		# FIXME we assume all children of info are property elements
		ptype = property.getAttribute('name')
		if ptype == 'mapname':
			mapname = property.getAttribute('value')
		elif ptype == 'worldtype':
			worldtype = property.getAttribute('value')
			if ldl.worldtypes.has_key(worldtype):
				worldtype_num = ldl.worldtypes[worldtype]
			else:
				ldl.error('Invalid worldtype ' + worldtype + ' specified.')
		else:
			ldl.error('Invalid map info property ' + ptype + ' specified.')
	worldspawn = doc.createElement('entity')
	worldspawn.appendChild(ldl.createProperty(doc, 'classname', 'worldspawn'))
	worldspawn.appendChild(ldl.createProperty(doc, 'worldtype', str(worldtype_num)))
	worldspawn.appendChild(ldl.createProperty(doc, 'message', mapname))
	worldspawn.appendChild(ldl.createProperty(doc, 'wad', ldl.wadfile))
	map.replaceChild(worldspawn, info)
	return worldspawn
Example #8
0
def splitWall(brush, holes):
    '''Splits a brush up in 2D so that it appears to have a hole in it.  This is achieved by taking the full brush size and the holes list and splitting the brush up into multiple parts.'''
    if not holes:
        return [brush]
	parts = []  # stores 2D parts returned by the main function
    finalparts = []  # stores expanded 3D parts
    extent2d = ldl.Point2D(brush.extent.x, brush.extent.y)
    # Sort holes by x start coord, then width...
    sortedholes = qsortHoles(holes)
	# Check for errors and add doors into the returned list of parts, as they need to be built...
    for hole in sortedholes:
		# FIXME check for other errors -- backtrack?
		if hole.origin.y + hole.extent.y > extent2d.y:
			#ldl.error('Hole is taller than containing wall.\n\thole.origin.y: ' + str(hole.origin.y) + '\n\thole.extent.y: ' + str(hole.extent.y) + '\n\textent2d.y: ' + str(extent2d.y))
			ldl.error('Hole is taller than containing wall.\n\thole: ' + str(hole) + '\n\textent2d: ' + str(extent2d))
		if hole.type == ldl.RT_DOOR:
			finalparts.append(ldl.Region2D(
                ldl.Point2D(
                    brush.origin.x+hole.origin.x,
                    brush.origin.y+hole.origin.y),
                ldl.Point2D(
                    hole.extent.x,
                    hole.extent.y),
                hole.type,
                hole.props
            ))
    # Go to main function...
    # FIXME this should not assume the origin is (0,0) but it doesn't work if we don't make this true...
    parts = splitWallCore(ldl.Chunk2D(ldl.Point2D(0, 0), extent2d), sortedholes)
    # Take list of brushes and add the z coord back on...
    for p in parts:
        finalparts.append(ldl.Region2D(
            ldl.Point2D(brush.origin.x+p.origin.x, brush.origin.y+p.origin.y),
            ldl.Point2D(p.extent.x, p.extent.y),
            p.type, p.props
        ))
    # Now we can return them...
    return finalparts
Example #9
0
def processInfo(doc, map):
    info = map.firstChild
    for property in info.childNodes:
        # FIXME we assume all children of info are property elements
        ptype = property.getAttribute('name')
        if ptype == 'mapname':
            mapname = property.getAttribute('value')
        elif ptype == 'worldtype':
            worldtype = property.getAttribute('value')
            if ldl.worldtypes.has_key(worldtype):
                worldtype_num = ldl.worldtypes[worldtype]
            else:
                ldl.error('Invalid worldtype ' + worldtype + ' specified.')
        else:
            ldl.error('Invalid map info property ' + ptype + ' specified.')
    worldspawn = doc.createElement('entity')
    worldspawn.appendChild(ldl.createProperty(doc, 'classname', 'worldspawn'))
    worldspawn.appendChild(
        ldl.createProperty(doc, 'worldtype', str(worldtype_num)))
    worldspawn.appendChild(ldl.createProperty(doc, 'message', mapname))
    worldspawn.appendChild(ldl.createProperty(doc, 'wad', ldl.wadfile))
    map.replaceChild(worldspawn, info)
    return worldspawn
Example #10
0
def splitWall(brush, holes):
    '''Splits a brush up in 2D so that it appears to have a hole in it.  This is achieved by taking the full brush size and the holes list and splitting the brush up into multiple parts.'''
    if not holes:
        return [brush]
        parts = []  # stores 2D parts returned by the main function
    finalparts = []  # stores expanded 3D parts
    extent2d = ldl.Point2D(brush.extent.x, brush.extent.y)
    # Sort holes by x start coord, then width...
    sortedholes = qsortHoles(holes)
    # Check for errors and add doors into the returned list of parts, as they need to be built...
    for hole in sortedholes:
        # FIXME check for other errors -- backtrack?
        if hole.origin.y + hole.extent.y > extent2d.y:
            #ldl.error('Hole is taller than containing wall.\n\thole.origin.y: ' + str(hole.origin.y) + '\n\thole.extent.y: ' + str(hole.extent.y) + '\n\textent2d.y: ' + str(extent2d.y))
            ldl.error('Hole is taller than containing wall.\n\thole: ' +
                      str(hole) + '\n\textent2d: ' + str(extent2d))
        if hole.type == ldl.RT_DOOR:
            finalparts.append(
                ldl.Region2D(
                    ldl.Point2D(brush.origin.x + hole.origin.x,
                                brush.origin.y + hole.origin.y),
                    ldl.Point2D(hole.extent.x, hole.extent.y), hole.type,
                    hole.props))
    # Go to main function...
    # FIXME this should not assume the origin is (0,0) but it doesn't work if we don't make this true...
    parts = splitWallCore(ldl.Chunk2D(ldl.Point2D(0, 0), extent2d),
                          sortedholes)
    # Take list of brushes and add the z coord back on...
    for p in parts:
        finalparts.append(
            ldl.Region2D(
                ldl.Point2D(brush.origin.x + p.origin.x,
                            brush.origin.y + p.origin.y),
                ldl.Point2D(p.extent.x, p.extent.y), p.type, p.props))
    # Now we can return them...
    return finalparts
Example #11
0
def processSolid(doc, parent, worldspawn, sf, offset, solid):
    '''Note: uses style set in parent hollow.'''
    global style
    o = ldl.getPoint(solid.getAttribute('origin')) + offset
    e = ldl.getPoint(solid.getAttribute('extent'))
    t = solid.getAttribute('texture')
    type = solid.getAttribute('type')
    if not t:
        if not type:
            ldl.error('solid with no type also has no texture attribute set')
    f = solid.getAttribute('holeface')
    # Get holes info...
    # FIXME this is repeated code from the hollow one -- any way we can refactor it?
    props = {}
    holes = []
    # Check if the solid has children (holes).
    # If so, split it up.
    # If not, just add it.
    if solid.hasChildNodes():
        for hole in solid.childNodes:
            ho_x, ho_y = hole.getAttribute('origin').split()
            he_x, he_y = hole.getAttribute('extent').split()
            type = hole.getAttribute('type')
            if not type:
                pass
            elif type == ldl.RT_DOOR:
                props[ldl.PROPS_K_KEY] = hole.getAttribute('key')
            else:
                ldl.warning(
                    'only doors allowed as hole types; not plats or others.')
            # FIXME deal with other types
            holes.append(
                ldl.Hole2D(ldl.Point2D(float(ho_x), float(ho_y)),
                           ldl.Point2D(float(he_x), float(he_y)), type, props))
        # Built split (2D) parts into 3D brushes; mapping of coords to 3D depends on which direction/face the hole was constructed in.
        if f == ldl.DCP_NORTH:
            parts = split.splitWall(
                ldl.Region2D(ldl.Point2D(o.x, o.z), ldl.Point2D(e.x, e.z)),
                holes)
            for part in parts:
                part3d = ldl.addDim(part, ldl.DIM_Y, o.y, e.y)
                #ldl.uprint('Part:   ' + str(part) + '\nPart3D: ' + str(part3d))
                ldl.makeBrush(doc, worldspawn, sf, style, part3d, f, t)
        elif f == ldl.DCP_UP:
            parts = split.splitWall(
                ldl.Region2D(ldl.Point2D(o.x, o.y), ldl.Point2D(e.x, e.y)),
                holes)
            for part in parts:
                part3d = ldl.addDim(part, ldl.DIM_Z, o.z + ldl.lip_small,
                                    e.z - ldl.lip_small * 2)
                #ldl.uprint('Part:   ' + str(part) + '\nPart3D: ' + str(part3d))
                ldl.makeBrush(doc, worldspawn, sf, style, part3d, f, t)
            else:
                ldl.error('Unsupported holeface ' + f +
                          ' requested for hole in solid.')
    else:
        # Doesn't have child nodes...
        if not type or type == ldl.RT_STEP:
            pass  # no properties to set
        elif type == ldl.RT_DOOR:
            props[ldl.PROPS_K_KEY] = solid.getAttribute('key')
        elif type == ldl.RT_PLAT:
            props[ldl.PROPS_K_POS] = solid.getAttribute('position')
        else:
            ldl.warning('unknown type ' + type + ' specifed.')

        brush = ldl.Region3D(Point(o.x, o.y, o.z), Point(e.x, e.y, e.z), type,
                             props)
        ldl.makeBrush(doc, worldspawn, sf, style, brush, type, t)
    # We can't remove the child or we screw over tree traversal (urgh)...
    ldl.insertPlaceholder(doc, parent, solid)
Example #12
0
def processSolid(doc, parent, worldspawn, sf, offset, solid):
	'''Note: uses style set in parent hollow.'''
	global style
	o = ldl.getPoint(solid.getAttribute('origin')) + offset
	e = ldl.getPoint(solid.getAttribute('extent'))
	t = solid.getAttribute('texture')
	type = solid.getAttribute('type')
	if not t:
		if not type:
			ldl.error('solid with no type also has no texture attribute set')
	f = solid.getAttribute('holeface')
	# Get holes info...
	# FIXME this is repeated code from the hollow one -- any way we can refactor it?
	props = {}
	holes = []
	# Check if the solid has children (holes).
	# If so, split it up.
	# If not, just add it.
	if solid.hasChildNodes():
		for hole in solid.childNodes:
			ho_x, ho_y = hole.getAttribute('origin').split()
			he_x, he_y = hole.getAttribute('extent').split()
			type = hole.getAttribute('type')
			if not type:
				pass
			elif type == ldl.RT_DOOR:
				props[ldl.PROPS_K_KEY] = hole.getAttribute('key')
			else:
				ldl.warning('only doors allowed as hole types; not plats or others.')
			# FIXME deal with other types
			holes.append(ldl.Hole2D(ldl.Point2D(float(ho_x), float(ho_y)), ldl.Point2D(float(he_x), float(he_y)), type, props))
		# Built split (2D) parts into 3D brushes; mapping of coords to 3D depends on which direction/face the hole was constructed in.
		if f == ldl.DCP_NORTH:
			parts = split.splitWall(
				ldl.Region2D(
					ldl.Point2D(o.x, o.z),
					ldl.Point2D(e.x, e.z)
				),
				holes)
			for part in parts:
				part3d = ldl.addDim(part, ldl.DIM_Y, o.y, e.y)
				#ldl.uprint('Part:   ' + str(part) + '\nPart3D: ' + str(part3d))
				ldl.makeBrush(doc, worldspawn, sf, style, part3d, f, t)
		elif f == ldl.DCP_UP:
			parts = split.splitWall(
				ldl.Region2D(
					ldl.Point2D(o.x, o.y),
					ldl.Point2D(e.x, e.y)
				),
				holes)
			for part in parts:
				part3d = ldl.addDim(part, ldl.DIM_Z, o.z+ldl.lip_small, e.z-ldl.lip_small*2)
				#ldl.uprint('Part:   ' + str(part) + '\nPart3D: ' + str(part3d))
				ldl.makeBrush(doc, worldspawn, sf, style, part3d, f, t)
			else:
				ldl.error('Unsupported holeface ' + f + ' requested for hole in solid.')
	else:
		# Doesn't have child nodes...
		if not type or type == ldl.RT_STEP:
			pass  # no properties to set
		elif type == ldl.RT_DOOR:
			props[ldl.PROPS_K_KEY] = solid.getAttribute('key')
		elif type == ldl.RT_PLAT:
			props[ldl.PROPS_K_POS] = solid.getAttribute('position')
		else:
			ldl.warning('unknown type ' + type + ' specifed.')

		brush = ldl.Region3D(
			Point(o.x, o.y, o.z),
			Point(e.x, e.y, e.z),
			type,
			props
		)
		ldl.makeBrush(doc, worldspawn, sf, style, brush, type, t)
	# We can't remove the child or we screw over tree traversal (urgh)...
	ldl.insertPlaceholder(doc, parent, solid)
Example #13
0
def splitWallCore(chunk, holes):
    '''Take a given area of the face to be split and split it.'''
    global splitWallCoreLevel
    splitWallCoreLevel = splitWallCoreLevel + 1
    parts = []
    if len(holes) == 0:
        paddedPrint('sWC: 0. chunk:' + str(chunk))
        parts.append(chunk)
    elif len(holes) == 1:
        hole = holes.pop()
        paddedPrint('sWC: 1. chunk: ' + str(chunk) + ' holes: ' + str(hole))
        if hole.end.x < chunk.end.x:
            # The hole is not flush with one side of this chunk; split the chunk so it is.
            # We do this by splitting the chunk so that the hole touches its east side.
            # Anything left over after the east side is a single whole chunk.
            paddedPrint('sWC: 1. hole.end.x (' + str(hole.end.x) +
                        ') < chunk.end.x (' + str(chunk.end.x) + ').')
            # Process part of chunk with hole in it...
            paddedPrint('sWC: 1. hole.end.x < chunk.end.x.  HOLE CHUNK')
            addparts = splitWallCore(
                ldl.Chunk2D(
                    chunk.origin,
                    ldl.Point2D(hole.end.x - chunk.origin.x, chunk.extent.y)),
                [hole])
            for ap in addparts:
                parts.append(ap)
            # Process the bit left at the east side...
            paddedPrint('sWC: 1. hole.end.x < chunk.end.x.  SOLID CHUNK')
            addparts = splitWallCore(
                ldl.Chunk2D(
                    ldl.Point2D(hole.end.x, chunk.origin.y),
                    ldl.Point2D(chunk.end.x - hole.end.x, chunk.extent.y)), [])
            for ap in addparts:
                parts.append(ap)
        else:
            # The end x-points of hole and chunk must be equal.
            # Add some parts around the hole...
            paddedPrint('sWC: 1. split flush.')
            # Under hole
            if (hole.origin.y - chunk.origin.y) > 0:
                parts.append(
                    ldl.Chunk2D(
                        chunk.origin,
                        ldl.Point2D(hole.end.x - chunk.origin.x,
                                    hole.origin.y - chunk.origin.y)))
            # Left of hole
            if (hole.origin.x - chunk.origin.x) > 0:
                parts.append(
                    ldl.Chunk2D(
                        chunk.origin +
                        ldl.Point2D(0, hole.origin.y - chunk.origin.y),
                        ldl.Point2D(hole.origin.x - chunk.origin.x,
                                    hole.extent.y)))
            # Above hole
            if (chunk.end.y - hole.end.y) > 0:
                parts.append(
                    ldl.Chunk2D(
                        chunk.origin +
                        ldl.Point2D(0, hole.end.y - chunk.origin.y),
                        ldl.Point2D(hole.end.x - chunk.origin.x,
                                    chunk.end.y - hole.end.y)))
            paddedPrint('sWC: 1. split flush.  results: ' +
                        str([str(p) for p in parts]))
    else:  # len(holes) > 1
        paddedPrint('sWC: n. chunk: ' + str(chunk) + ' holes: ' +
                    str([str(h) for h in holes]))
        '''Compare first two holes.
        If they do not overlap x-wise, split the chunk at the x value that represents the end of the first hole.
        If they do overlap x-wise, see if they overlap y-wise too.
            If they do, we're screwed (can't handle this yet).
            If they overlap y-wise
                See if there are any more nodes.
                    If no, then we can just split this chunk at a given y-value to keep the holes seperate.
                    If yes, then we need to see if we can split this chunk into two:
                        one split vertically (at an x-value just after the 2nd hole) to seperate our two x-overlapping holes from the next one.
                        and one split horizontally (at a y-value) to separate our overlapping holes
        '''
        holeA = holes[0]
        holeB = holes[1]
        if holeA.end.x < holeB.origin.x:
            paddedPrint('sWC: n. holeA.end.x (' + str(holeA.end.x) +
                        ') < holeB.origin.x (' + str(holeB.origin.x) + ')')
            # Our holes do not overlap x-wise;
            # split our chunk into two:
            #   one chunk containing the first hole (flush to the edge)
            #   another chunk containing all the other holes
            paddedPrint('sWC: n. holeA.end.x < holeB.origin.x.  singleton')
            addparts = splitWallCore(
                ldl.Chunk2D(
                    chunk.origin,
                    ldl.Point2D(holeA.end.x - chunk.origin.x, chunk.extent.y)),
                [holeA])
            for ap in addparts:
                parts.append(ap)
            paddedPrint('sWC: n. holeA.end.x < holeB.origin.x.  the rest')
            addparts = splitWallCore(
                ldl.Chunk2D(
                    ldl.Point2D(holeA.end.x, chunk.origin.y),
                    ldl.Point2D(chunk.end.x - holeA.end.x, chunk.extent.y)),
                holes[1:])
            for ap in addparts:
                parts.append(ap)
        elif holeA.origin.y >= holeB.end.y or holeB.origin.y >= holeA.end.y:
            paddedPrint('sWC: n. Y.  holeA.origin.y (' + str(holeA.origin.y) +
                        ' >= holeB.end.y (' + str(holeB.end.y) + ')')
            # Our holes overlap x-wise, but they don't overlap y-wise.
            # Which one is on top?
            if holeA.origin.y >= holeB.origin.y:
                upper = holeA
                lower = holeB
            else:
                upper = holeB
                lower = holeA
            # Are there more holes?
            if not len(holes) > 2:
                paddedPrint('sWC: n. Y.  no more holes')
                # No more holes; just split this chunk y-wise...
                paddedPrint('sWC: n. Y.  no more holes.  LOWER.')
                addparts = splitWallCore(
                    ldl.Chunk2D(chunk.origin,
                                ldl.Point2D(chunk.extent.x, upper.origin.y)),
                    [lower])
                for ap in addparts:
                    parts.append(ap)
                paddedPrint('sWC: n. Y.  no more holes.  UPPER.')
                addparts = splitWallCore(
                    ldl.Chunk2D(
                        ldl.Point2D(chunk.origin.x, upper.origin.y),
                        ldl.Point2D(chunk.extent.x,
                                    chunk.extent.y - upper.origin.y)), [upper])
                for ap in addparts:
                    parts.append(ap)
            else:
                # There are more holes; split both y- and x-wise.
                # Use the x-value of the next hole (FIXME could break things?)
                xcutoff = holes[2].origin.x - chunk.origin.x
                paddedPrint('sWC: n. Y.  more holes; xcutoff = ' +
                            str(xcutoff))
                paddedPrint('sWC: n. Y.  more holes.  LOWER.')
                addparts = splitWallCore(
                    ldl.Chunk2D(chunk.origin,
                                ldl.Point2D(xcutoff, upper.origin.y)), [lower])
                for ap in addparts:
                    parts.append(ap)
                paddedPrint('sWC: n. Y.  more holes.  UPPER.')
                addparts = splitWallCore(
                    ldl.Chunk2D(
                        ldl.Point2D(chunk.origin.x, upper.origin.y),
                        ldl.Point2D(xcutoff, chunk.extent.y - upper.origin.y)),
                    [upper])
                for ap in addparts:
                    parts.append(ap)
                paddedPrint('sWC: n. Y.  more holes.  REST-OF-X.')
                addparts = splitWallCore(
                    ldl.Chunk2D(
                        ldl.Point2D(chunk.origin.x + xcutoff, chunk.origin.y),
                        ldl.Point2D(chunk.extent.x - xcutoff, chunk.extent.y)),
                    holes[2:])
                for ap in addparts:
                    parts.append(ap)
        else:
            # Our holes overlap both x- and y-wise; for now, we're screwed.
            ldl.error(
                'Oh dear: the segmentation algorithm can\'t cope with holes that overlap both x- and y-wise!'
            )
    splitWallCoreLevel = splitWallCoreLevel - 1
    return parts
Example #14
0
	def macro_stairs(self, bi, si):
		'''Make some stairs
		we see this as a 2D problem then add the missing dimension later (width/depth)
		dir tells us in which dir the steps go up
		length is the distance from start of lowest to end of heighest step
		height is the height of the highest step'''
		# FIXME cope with being able to make a hole through (under) the stairs
		origin = ldl.getPoint(bi['origin'])
		size = ldl.getPoint(bi['extent'])
		dir = si['dir']
		texture = ''
		if bi.has_key('texture'): texture = bi['texture']
		#slength = float(si['steplength'])
		slength = 0
		sheight = float(si['stepheight'])
		parts = []
		parts3d = []

		# FIXME repeated code: n/e == s/w -- collapse into 2?

		# Work out which dimension is which
		if dir == ldl.DCP_NORTH:
			# use X and Y; Z rising with increasing Y
			length = size.y
			height = size.z
			width = size.x
			flip = False
			parts = self._macro_stairs_core(length, height, width, flip, slength, sheight, texture)
			for part in parts:
				part3d = ldl.Region3D(
					Point(0,part.origin.x,part.origin.y) + origin,
					Point(width, part.extent.x, part.extent.y)
				)
				parts3d.append(part3d)
		elif dir == ldl.DCP_SOUTH:
			# use X and Y; Z falling with increasing Y
			length = size.y
			height = size.z
			width = size.x
			flip = True
			parts = self._macro_stairs_core(length, height, width, flip, slength, sheight, texture)
			for part in parts:
				part3d = ldl.Region3D(
					Point(0,part.origin.x,part.origin.y) + origin,
					Point(width, part.extent.x, part.extent.y)
				)
				parts3d.append(part3d)
		elif dir == ldl.DCP_EAST:
			# use X and Y; Z rising with increasing X
			length = size.x
			height = size.z
			width = size.y
			flip = False
			parts = self._macro_stairs_core(length, height, width, flip, slength, sheight, texture)
			for part in parts:
				part3d = ldl.Region3D(
					Point(part.origin.x, 0, part.origin.y) + origin,
					Point(part.extent.x, width, part.extent.y)
				)
				parts3d.append(part3d)
		elif dir == ldl.DCP_WEST:
			# use X and y; Z falling with increasing X
			length = size.x
			height = size.z
			width = size.y
			flip = True
			parts = self._macro_stairs_core(length, height, width, flip, slength, sheight, texture)
			for part in parts:
				part3d = ldl.Region3D(
					Point(part.origin.x, 0, part.origin.y) + origin,
					Point(part.extent.x, width, part.extent.y)
				)
				parts3d.append(part3d)
		else:
			ldl.error('invalid direction specified for stairs (up and down are currently unsupported)')

		for part3d in parts3d:
			#ldl.uprint(str(part3d))
			print "<solid origin='" + str(part3d.origin) + "' extent='" + str(part3d.extent) + "' texture='" + texture + "' type='step' />"
Example #15
0
        return

    # Utility Functions...

    def padded_print(self, msg):
        for i in range(self.padding_level):
            ldl.uprint('  ', sameLine=True)
        ldl.uprint(msg)


if __name__ == "__main__":
    ldl.stage = '03'
    ldl.uprint('\n === ' + ldl.stackdescs[ldl.stage] + ' ===')
    styleFetcher = ldl.StyleFetcher()
    parser = sax.make_parser()
    #XMLGenerator is a special SAX handler that merely writes
    #SAX events back into an XML document
    downstream_handler = XMLGenerator()
    #upstream, the parser, downstream, the next handler in the chain
    filter_handler = LightingStyleFilter(parser, downstream_handler)
    #The SAX filter base is designed so that the filter takes
    #on much of the interface of the parser itself, including the
    #"parse" method
    try:
        filter_handler.parse(sys.stdin)
    except sax.SAXParseException, detail:
        ldl.error('The XML you supplied is not valid: ' + str(detail))
    except:
        raise
        ldl.failParse()
Example #16
0
def splitWallCore(chunk, holes):
    '''Take a given area of the face to be split and split it.'''
    global splitWallCoreLevel
    splitWallCoreLevel = splitWallCoreLevel + 1
    parts = []
    if len(holes) == 0:
        paddedPrint('sWC: 0. chunk:' + str(chunk))
        parts.append(chunk)
    elif len(holes) == 1:
        hole = holes.pop()
        paddedPrint('sWC: 1. chunk: ' + str(chunk) + ' holes: ' + str(hole))
        if hole.end.x < chunk.end.x:
            # The hole is not flush with one side of this chunk; split the chunk so it is.
            # We do this by splitting the chunk so that the hole touches its east side.
            # Anything left over after the east side is a single whole chunk.
            paddedPrint('sWC: 1. hole.end.x (' + str(hole.end.x) + ') < chunk.end.x (' + str(chunk.end.x) + ').')
            # Process part of chunk with hole in it...
            paddedPrint('sWC: 1. hole.end.x < chunk.end.x.  HOLE CHUNK')
            addparts = splitWallCore(
                ldl.Chunk2D(
                    chunk.origin,
                    ldl.Point2D(hole.end.x-chunk.origin.x, chunk.extent.y)
                ), 
                [hole])
            for ap in addparts: parts.append(ap)
            # Process the bit left at the east side...
            paddedPrint('sWC: 1. hole.end.x < chunk.end.x.  SOLID CHUNK')
            addparts = splitWallCore(
                ldl.Chunk2D(
                    ldl.Point2D(hole.end.x, chunk.origin.y),
                    ldl.Point2D(chunk.end.x-hole.end.x, chunk.extent.y)
                ),
                [])
            for ap in addparts: parts.append(ap)
        else:
            # The end x-points of hole and chunk must be equal.
            # Add some parts around the hole...
            paddedPrint('sWC: 1. split flush.')
            # Under hole
            if (hole.origin.y - chunk.origin.y) > 0:
                parts.append(ldl.Chunk2D(
                    chunk.origin,
                    ldl.Point2D(hole.end.x-chunk.origin.x, hole.origin.y-chunk.origin.y)))
            # Left of hole
            if (hole.origin.x - chunk.origin.x) > 0:
                parts.append(ldl.Chunk2D(
                    chunk.origin + ldl.Point2D(0, hole.origin.y-chunk.origin.y),
                    ldl.Point2D(hole.origin.x-chunk.origin.x, hole.extent.y)))
            # Above hole
            if (chunk.end.y - hole.end.y) > 0:
                parts.append(ldl.Chunk2D(
                    chunk.origin + ldl.Point2D(0, hole.end.y-chunk.origin.y),
                    ldl.Point2D(hole.end.x-chunk.origin.x, chunk.end.y - hole.end.y)))
            paddedPrint('sWC: 1. split flush.  results: ' + str([str(p) for p in parts]))
    else:  # len(holes) > 1
        paddedPrint('sWC: n. chunk: ' + str(chunk) + ' holes: ' + str([str(h) for h in holes]))
        '''Compare first two holes.
        If they do not overlap x-wise, split the chunk at the x value that represents the end of the first hole.
        If they do overlap x-wise, see if they overlap y-wise too.
            If they do, we're screwed (can't handle this yet).
            If they overlap y-wise
                See if there are any more nodes.
                    If no, then we can just split this chunk at a given y-value to keep the holes seperate.
                    If yes, then we need to see if we can split this chunk into two:
                        one split vertically (at an x-value just after the 2nd hole) to seperate our two x-overlapping holes from the next one.
                        and one split horizontally (at a y-value) to separate our overlapping holes
        '''
        holeA = holes[0]
        holeB = holes[1]
        if holeA.end.x < holeB.origin.x:
            paddedPrint('sWC: n. holeA.end.x (' + str(holeA.end.x) + ') < holeB.origin.x (' + str(holeB.origin.x) + ')')
            # Our holes do not overlap x-wise;
            # split our chunk into two:
            #   one chunk containing the first hole (flush to the edge)
            #   another chunk containing all the other holes
            paddedPrint('sWC: n. holeA.end.x < holeB.origin.x.  singleton')
            addparts = splitWallCore(
                ldl.Chunk2D(
                    chunk.origin,
                    ldl.Point2D(holeA.end.x-chunk.origin.x, chunk.extent.y)
                ),
                [holeA])
            for ap in addparts: parts.append(ap)
            paddedPrint('sWC: n. holeA.end.x < holeB.origin.x.  the rest')
            addparts = splitWallCore(
                ldl.Chunk2D(
                    ldl.Point2D(holeA.end.x, chunk.origin.y),
                    ldl.Point2D(chunk.end.x-holeA.end.x, chunk.extent.y)
                ),
                holes[1:])
            for ap in addparts: parts.append(ap)
        elif holeA.origin.y >= holeB.end.y or holeB.origin.y >= holeA.end.y:
            paddedPrint('sWC: n. Y.  holeA.origin.y (' + str(holeA.origin.y) + ' >= holeB.end.y (' + str(holeB.end.y) + ')')
            # Our holes overlap x-wise, but they don't overlap y-wise.
            # Which one is on top?
            if holeA.origin.y >= holeB.origin.y:
                upper = holeA
                lower = holeB
            else:
                upper = holeB
                lower = holeA
            # Are there more holes?
            if not len(holes) > 2:
                paddedPrint('sWC: n. Y.  no more holes')
                # No more holes; just split this chunk y-wise...
                paddedPrint('sWC: n. Y.  no more holes.  LOWER.')
                addparts = splitWallCore(
                    ldl.Chunk2D(
                        chunk.origin,
                        ldl.Point2D(chunk.extent.x, upper.origin.y)
                    ),
                    [lower])
                for ap in addparts: parts.append(ap)
                paddedPrint('sWC: n. Y.  no more holes.  UPPER.')
                addparts = splitWallCore(
                    ldl.Chunk2D(
                        ldl.Point2D(chunk.origin.x, upper.origin.y),
                        ldl.Point2D(chunk.extent.x, chunk.extent.y - upper.origin.y)
                    ),
                    [upper])
                for ap in addparts: parts.append(ap)
            else:
                # There are more holes; split both y- and x-wise.
                # Use the x-value of the next hole (FIXME could break things?)
                xcutoff = holes[2].origin.x - chunk.origin.x
                paddedPrint('sWC: n. Y.  more holes; xcutoff = ' + str(xcutoff))
                paddedPrint('sWC: n. Y.  more holes.  LOWER.')
                addparts = splitWallCore(
                    ldl.Chunk2D(
                        chunk.origin,
                        ldl.Point2D(xcutoff, upper.origin.y)
                    ),
                    [lower])
                for ap in addparts: parts.append(ap)
                paddedPrint('sWC: n. Y.  more holes.  UPPER.')
                addparts = splitWallCore(
                    ldl.Chunk2D(
                        ldl.Point2D(chunk.origin.x, upper.origin.y),
                        ldl.Point2D(xcutoff, chunk.extent.y - upper.origin.y)
                    ),
                    [upper])
                for ap in addparts: parts.append(ap)
                paddedPrint('sWC: n. Y.  more holes.  REST-OF-X.')
                addparts = splitWallCore(
                    ldl.Chunk2D(
                        ldl.Point2D(chunk.origin.x + xcutoff, chunk.origin.y),
                        ldl.Point2D(chunk.extent.x - xcutoff, chunk.extent.y)
                    ),
                    holes[2:])
                for ap in addparts: parts.append(ap)
        else:
            # Our holes overlap both x- and y-wise; for now, we're screwed.
            ldl.error('Oh dear: the segmentation algorithm can\'t cope with holes that overlap both x- and y-wise!')
    splitWallCoreLevel = splitWallCoreLevel - 1
    return parts
Example #17
0
	def ignorableWhitespace(self, ws):
		self._accumulator.append(text)

	# Utility Functions...

	def padded_print(self, msg):
		for i in range(self.padding_level):
			ldl.uprint('  ', sameLine=True)
		ldl.uprint(msg)

if __name__ == "__main__":
	ldl.stage = '04'
	ldl.uprint('\n === ' + ldl.stackdescs['04'] + ' ===')
	parser = sax.make_parser()
	#XMLGenerator is a special SAX handler that merely writes
	#SAX events back into an XML document
	downstream_handler = XMLGenerator()
	#upstream, the parser, downstream, the next handler in the chain
	filter_handler = BuilderFilter(parser, downstream_handler)
	#The SAX filter base is designed so that the filter takes
	#on much of the interface of the parser itself, including the
	#"parse" method
	try:
		filter_handler.parse(sys.stdin)
	except sax.SAXParseException, detail:
		ldl.error('The XML you supplied is not valid: ' + str(detail))
	except:
		raise
		ldl.failParse()