Ejemplo n.º 1
0
/**
 * \return List of RLines and RArcs describing this polyline.
 */
QList<QSharedPointer<RShape> > RPolyline::getExploded(int segments) const {
    Q_UNUSED(segments);

    QList<QSharedPointer<RShape> > ret;

    if (vertices.size()<=1) {
        return ret;
    }

    //qDebug() << "shapes: ";
    for (int i=0; i<vertices.size(); i++) {

        //qDebug() << "vertex[" << i << "]: " << vertices.at(i) << ", bulge: " << bulges.at(i);

        if (!closed && i==vertices.size()-1) {
            break;
        }

        QSharedPointer<RShape> subShape = getSegmentAt(i);
        if (subShape.isNull()) {
            continue;
        }

        ret.append(subShape);
        //qDebug() << "shape: " << *getSubShapeAt(i);
    }

    return ret;
}
Ejemplo n.º 2
0
bool RPolylineData::moveReferencePoint(const RVector& referencePoint,
        const RVector& targetPoint) {
    bool ret = false;

    QList<RVector>::iterator it;
    for (it=vertices.begin(); it!=vertices.end(); ++it) {
        if (referencePoint.equalsFuzzy(*it)) {
            (*it) = targetPoint;
            ret = true;
        }
    }

    for (int i=0; i<countSegments(); i++) {
        if (isArcSegmentAt(i)) {
            QSharedPointer<RArc> arc = getSegmentAt(i).dynamicCast<RArc>();
            if (!arc.isNull()) {
                if (referencePoint.equalsFuzzy(arc->getMiddlePoint())) {
                    RArc a = RArc::createFrom3Points(arc->getStartPoint(), targetPoint, arc->getEndPoint());
                    setBulgeAt(i, a.getBulge());
                    ret = true;
                }
            }
        }
    }

    return ret;
}
Ejemplo n.º 3
0
bool RPolyline::simplify(double angleTolerance) {
    bool ret = false;
    RPolyline newPolyline;
    //ret.appendVertex(getStartPoint());

    RS::EntityType type = RS::EntityUnknown;
    double angle = RMAXDOUBLE;
    //double radius = 0;
    //RVector center;
    //RVector vertex;

    for (int i=0; i<countSegments(); i++) {
        QSharedPointer<RShape> seg = getSegmentAt(i);

        QSharedPointer<RLine> line = seg.dynamicCast<RLine>();
        if (!line.isNull()) {
            double angleDiff = qAbs(RMath::getAngleDifference180(line->getAngle(), angle));
//            qDebug() << "angle diff: " << angleDiff;
//            qDebug() << "tol: " << angleTolerance;
            if (type==RS::EntityLine && angleDiff<angleTolerance) {

                //vertex = line->getEndPoint();
                ret = true;
            }
            else {
                //qDebug() << "start: " << line->getStartPoint();
                newPolyline.appendVertex(line->getStartPoint());
                angle = line->getAngle();
                type = RS::EntityLine;
            }
        }

        QSharedPointer<RArc> arc = seg.dynamicCast<RArc>();
        if (!arc.isNull()) {
            // TODO
            newPolyline.appendVertex(arc->getStartPoint(), arc->getBulge());
        }
    }

    if (isClosed()) {
        newPolyline.setClosed(true);
    }
    else {
        newPolyline.appendVertex(getEndPoint());
    }

//    qDebug() << "old polyline: " << *this;
//    qDebug() << "new polyline: " << newPolyline;

    //*this = newPolyline;

    //clear();
    vertices = newPolyline.vertices;
    bulges = newPolyline.bulges;
    closed = newPolyline.closed;

    return ret;
}
Ejemplo n.º 4
0
QSharedPointer<RShape> RPolyline::getTransformed(const QTransform& transform) const {
    QSharedPointer<RPolyline> ret = QSharedPointer<RPolyline>(new RPolyline());

    for (int i=0; i<countSegments(); i++) {
        QSharedPointer<RShape> s = getSegmentAt(i);
        QSharedPointer<RShape> st = s->getTransformed(transform);
        ret->appendShape(*st);
    }

    return ret;
}
Ejemplo n.º 5
0
double RPolyline::getDirection1() const {
    if (vertices.size()==0) {
        return RNANDOUBLE;
    }

    QSharedPointer<RShape> shape = getSegmentAt(0);
    QSharedPointer<RDirected> dirShape = shape.dynamicCast<RDirected>();
    if (dirShape.isNull()) {
        return RNANDOUBLE;
    }

    return dirShape->getDirection1();
}
Ejemplo n.º 6
0
/**
 * \return true if this leader can have an arrow head (i.e. first
 * segment is >= DIMASZ * DIMSCALE * 2.
 */
bool RLeaderData::canHaveArrowHead() const {
    if (countSegments()==0) {
        return false;
    }

    QSharedPointer<RShape> firstSegment = getSegmentAt(0);
    if (firstSegment.isNull()) {
        return false;
    }

    if (firstSegment->getLength() < getDimasz() * 2) {
        return false;
    }

    return true;
}
Ejemplo n.º 7
0
QList<RRefPoint> RPolylineData::getReferencePoints(RS::ProjectionRenderingHint hint) const {
    Q_UNUSED(hint)

    QList<RRefPoint> ret = RRefPoint::toRefPointList(getVertices());
    if (!ret.isEmpty()) {
        // mark start and end points:
        ret.first().setStart(true);
        ret.last().setEnd(true);
    }
    for (int i=0; i<countSegments(); i++) {
        if (isArcSegmentAt(i)) {
            QSharedPointer<RArc> arc = getSegmentAt(i).dynamicCast<RArc>();
            if (!arc.isNull()) {
                ret.append(RRefPoint(arc->getMiddlePoint(), RRefPoint::Secondary));
            }
        }
    }
    return ret;
}
Ejemplo n.º 8
0
/**
 * \return A QPainterPath object that represents this polyline.
 */
RPainterPath RPolyline::toPainterPath() const {
    RPainterPath ret;

    if (vertices.size()<=1) {
        return ret;
    }

    ret.moveTo(vertices.at(0));

    for (int i=0; i<vertices.size(); i++) {
        if (!closed && i==vertices.size()-1) {
            break;
        }
        QSharedPointer<RShape> shape = getSegmentAt(i);
        ret.addShape(shape);
    }

    return ret;
}
Ejemplo n.º 9
0
/**
 * \return List of RLines and RArcs describing this polyline.
 */
QList<QSharedPointer<RShape> > RPolyline::getExploded(int segments) const {
    Q_UNUSED(segments);

    QList<QSharedPointer<RShape> > ret;

    if (vertices.size()<=1) {
        return ret;
    }

    for (int i=0; i<vertices.size(); i++) {
        if (!closed && i==vertices.size()-1) {
            break;
        }

        QSharedPointer<RShape> subShape = getSegmentAt(i);
        if (subShape.isNull()) {
            continue;
        }

        ret.append(subShape);
    }

    return ret;
}
Ejemplo n.º 10
0
/*
 * Function to Compile MIPS code at 'address' and then return the ARM_PC counter to jump to
 */
size_t branchUnknown(code_seg_t* code_seg, size_t* address)
{
	//volatile code_seg_t* code_seg 	= segmentData.dbgCurrentSegment;
	Instruction_t* 	ins = newEmptyInstr();
	size_t ARMAddress;
	uint32_t MIPSaddress;
	Instruction_e op;

	// find out it the end of the segment is a JUMP or BRANCH
	op = ops_type(code_seg->MIPScode[code_seg->MIPScodeLen - 1]);

	//Get MIPS condition code and link
	mips_decode(code_seg->MIPScode[code_seg->MIPScodeLen - 1], ins);
	ins->outputAddress = &code_seg->MIPScode[code_seg->MIPScodeLen - 1];

	if (op & OPS_BRANCH){
		MIPSaddress =  (uint32_t)(code_seg->MIPScode + code_seg->MIPScodeLen - 1) + 4*ops_BranchOffset(code_seg->MIPScode + code_seg->MIPScodeLen - 1);
	}
	else if (op == MIPS_J || op == MIPS_JAL)
	{
		MIPSaddress =  (((size_t)code_seg->MIPScode + code_seg->MIPScodeLen * 4)&0xF0000000U) + ops_JumpAddress(&code_seg->MIPScode[code_seg->MIPScodeLen - 1]);
	}
	else if (op == MIPS_JR || op == MIPS_JALR)
	{
		MIPSaddress = address;
	}

#if SHOW_BRANCHUNKNOWN_STEPS
	printf("branchUnknown(0x%08x) called from Segment 0x%08x\n", MIPSaddress, (uint32_t)code_seg);

	printf_Intermediate(ins,1);
#endif

	code_seg_t* tgtSeg = getSegmentAt(MIPSaddress);

#if SHOW_BRANCHUNKNOWN_STEPS
	printf("tgtSeg = 0x%08x\n", (uint32_t)tgtSeg);
#endif

	// 1. Need to generate the ARM assembler for target code_segment. Use 'addr' and code Seg map.
	// 2. Then we need to patch the code_segment branch we came from. Do we need it to be a link?
	// 3. return the address to branch to.

	// 1.
	if (NULL != tgtSeg)
	{
		if (NULL == tgtSeg->ARMEntryPoint)
		{
#if SHOW_BRANCHUNKNOWN_STEPS
			printf("Translating pre-existing CodeSegment\n");
#endif
			Translate(tgtSeg);
		}
		else
		{
#if SHOW_BRANCHUNKNOWN_STEPS
			printf("Patch pre-existing CodeSegment\n");
#endif
		}

		ARMAddress = (size_t)tgtSeg->ARMEntryPoint;
	}
	else
	{
#if SHOW_BRANCHUNKNOWN_STEPS
		printf("Creating new CodeSegment for 0x%08x\n", MIPSaddress);
#endif
		tgtSeg = CompileCodeAt((uint32_t*)MIPSaddress);
		ARMAddress = (size_t)tgtSeg->ARMEntryPoint;
	}

	code_seg->pBranchNext = tgtSeg;

	// 2.
	if (((op & OPS_BRANCH) == OPS_BRANCH)
			|| (op == MIPS_J)
			|| (op == MIPS_JAL))
	{
#if USE_HOST_MANAGED_BRANCHING
		if ((op & OPS_LINK) == OPS_LINK)
		{
			if ((op & OPS_LIKELY) == OPS_LIKELY)
			{
				//Set instruction to ARM_BRANCH for new target
				InstrBL(ins, AL, ARMAddress, 1);
			}
			else
			{
				//Set instruction to ARM_BRANCH for new target
				InstrBL(ins, ins->cond, ARMAddress, 1);
			}

		}
		else
#endif
		{
			//Set instruction to ARM_BRANCH for new target
			InstrB(ins, ins->cond, ARMAddress, 1);
		}

		addToCallers(code_seg, tgtSeg);
		ins->outputAddress = (size_t)address;

#if SHOW_BRANCHUNKNOWN_STEPS
		printf_Intermediate(ins,1);
#endif

		uint32_t* 	out 		= address;

		*out = arm_encode(ins, (size_t)out);
		__clear_cache(out, &out[1]);
	}
#if USE_HOST_MANAGED_BRANCHING == 0
	else if (op == MIPS_JR)
	{
		ins = tgtSeg->Intermcode;
		Instruction_t branchIns = ins;

		while (ins != NULL)
		{
			if (ins == ARM_B)
			{
				branchIns = ins;
			}
			ins = ins->nextInstruction;
		}

		ARMAddress = (size_t)branchIns->outputAddress + 4U;
	}
#endif

	// 3.
	return ARMAddress;
}
Ejemplo n.º 11
0
/*
 * Description: Function to malloc a newSegment and zero initialize it.
 *
 * Parameters:	none
 *
 * Returns:		code_seg_t*
 */
code_seg_t* newSegment()
{
	code_seg_t* newSeg = malloc(sizeof(code_seg_t));
	memset(newSeg, 0,sizeof(code_seg_t));

#if SHOW_PRINT_SEGMENT_DELETE == 2
	{
#elif SHOW_PRINT_SEGMENT_DELETE == 1
	if (showPrintSegmentDelete)
	{
#else
	if (0)
	{
#endif
		printf("new Segment 0x%08x\n", (uint32_t)newSeg);
	}

	return newSeg;
}

/*
 * Description: Function to free a segment and its associated data.
 *
 * 				Function will also invalidate the branches of code segments that branch to this one
 * 				and delete segments that 'continue' execution to this one.
 *
 * Parameters:	none
 *
 * Returns:		code_seg_t*
 */
uint32_t delSegment(code_seg_t* codeSegment)
{
	uint32_t ret = 0;

#if SHOW_PRINT_SEGMENT_DELETE == 2
	{
#elif SHOW_PRINT_SEGMENT_DELETE == 1
	if (showPrintSegmentDelete)
	{
#else
	if (0)
	{
#endif
	printf("deleting Segment 0x%08x for mips code at 0x%08x\n", (uint32_t)codeSegment, (uint32_t)codeSegment->MIPScode);
	}

	freeIntermediateInstructions(codeSegment);	// free memory used for Intermediate Instructions
	freeLiterals(codeSegment);					// free memory used by literals

	// Clean up all segments that branch or continue to this segment
	if (codeSegment->callers != NULL)
	{
		caller_t* caller = codeSegment->callers;

		// loop through all the callers
		while (caller != NULL)
		{
			if (caller->codeSeg != NULL)
			{
				// if the found caller branches to this segment then remove the reference
				if (caller->codeSeg->pBranchNext == codeSegment)
				{
					caller->codeSeg->pBranchNext = NULL;
				}
				// if the found caller continues to this segment then it MUST also be deleted
				else if (caller->codeSeg->pContinueNext == codeSegment)
				{
					delSegment(caller->codeSeg);
				}
			}
			caller = caller->next;
		}

		// Invalidate any segments that branch to this segment and free the caller_t objects
		freeCallers(codeSegment);
	}

	// update the codeSegment mapping
	setMemState((size_t)codeSegment->MIPScode, codeSegment->MIPScodeLen, NULL);

	free(codeSegment);

	return ret;
}

/*
 * Description: Function to Compile the code starting at 'address'.
 *
 * 				This function will scan the code until an unconditional Jump is found. Referred to as a super block
 *
 * 				It may detect multiple segments in which case these will all 'continue' execution into the next segment.
 *
 * 				It also detects internal loops and separates these into their own segment, for better register optimization.
 *
 *
 * Parameters:	const uint32_t* const address				The address to start compiling from.
 *
 * Returns:		code_seg_t*	The first generated code Segment.
 */
code_seg_t* CompileCodeAt(const uint32_t const address[])
{
	uint32_t 		x;
	Instruction_e 	op;
	uint32_t 		uiMIPScodeLen = 0U;
	code_seg_t* 	newSeg;
	code_seg_t* 	prevSeg = NULL;

	// Find the shortest length of contiguous blocks (super block) of MIPS code at 'address'
	// Contiguous blocks should end with an OPS_JUMP && !OPS_LINK
	for (;;) // (index + uiMIPScodeLen < upperAddress/sizeof(code_seg_t*))
	{
		op = ops_type(address[uiMIPScodeLen]);

		if (DR_INVALID == op)
		{
			uiMIPScodeLen = 0U;
			break;
		}

		uiMIPScodeLen++;

		if ((op & OPS_JUMP) == OPS_JUMP
				&& (op & OPS_LINK) != OPS_LINK)	//unconditional jump or function return
		{
			break;
		}
	}

#if	SHOW_COMPILEAT_STEPS
	printf("CompiltCodeAt(0x%x) - found %u potential instructions\n", address, uiMIPScodeLen);
#endif

	//Now expire the segments within the super block and remove the segments
	for (x = 0U; x < uiMIPScodeLen; x++)
	{
		code_seg_t* toDelete;
		toDelete = getSegmentAt((size_t)(address + x));
		if (toDelete)
		{
			setMemState((size_t)toDelete->MIPScode, toDelete->MIPScodeLen, NULL);
			delSegment(toDelete);

			//we can skip next few words as we have already cleared them.
			x += toDelete->MIPScodeLen - 1U;
		}
	}

	uint32_t segmentStartIndex = 0U;

	// Create new segments
	for (x = 0U; x < uiMIPScodeLen; x++)
	{
		op = ops_type(address[x]);

		if ((op & OPS_JUMP) == OPS_JUMP)
		{
			//uint32_t uiAddress = ops_JumpAddress(&address[x]);

			newSeg = newSegment();
			newSeg->MIPScode = (uint32_t*)(address + segmentStartIndex);
			newSeg->MIPScodeLen = x - segmentStartIndex + 1U;

#if	SHOW_COMPILEAT_STEPS
				printf("CompiltCodeAt(0x%x) - new external jump segment 0x%x at address 0x%x\n", address + x * 4U, newSeg, newSeg->MIPScode);
#endif
			if (op == MIPS_JR) //only JR can set PC to the Link Register (or other register!)
			{
				newSeg->MIPSReturnRegister = (*address>>21U)&0x1fU;
			}

			if (prevSeg)
			{
				prevSeg->pContinueNext = newSeg;
				addToCallers(prevSeg, newSeg);
			}
			prevSeg = newSeg;

			if (!segmentStartIndex)
			{
				newSeg->Type = SEG_START;
			}
			else
			{
				newSeg->Type = SEG_END;
			}

			setMemState((size_t)(address + segmentStartIndex), newSeg->MIPScodeLen, newSeg);

			segmentStartIndex = x + 1U;

			// we should have got to the end of the super block
			if (!(op & OPS_LINK))
			{
				break;
			}
		}
		else if((op & OPS_BRANCH) == OPS_BRANCH)	//MIPS does not have an unconditional branch
		{
			int32_t offset =  ops_BranchOffset(&address[x]);

			//Is this an internal branch - need to create two segments
			// if use x<= y + offset then may throw SIGSEGV if offset is -1!
			if (offset < 0 && x + offset >= segmentStartIndex )
			{
				newSeg = newSegment();
				newSeg->MIPScode = (uint32_t*)(address + segmentStartIndex);
				newSeg->MIPScodeLen = x + offset - segmentStartIndex + 1U;

#if	SHOW_COMPILEAT_STEPS
				printf("CompiltCodeAt(0x%x) - new internal branching, pre-loop segment 0x%x to address 0x%x\n", address, newSeg, newSeg->MIPScode);
#endif

				if (prevSeg != NULL)
				{
					prevSeg->pContinueNext = newSeg;
					addToCallers(prevSeg, newSeg);
				}
				prevSeg = newSeg;

				if (segmentStartIndex == 0U)
				{
					newSeg->Type = SEG_START;
				}
				else
				{
					newSeg->Type = SEG_SANDWICH;
				}

				setMemState((size_t)(address + segmentStartIndex), newSeg->MIPScodeLen, newSeg);
				segmentStartIndex = x + 1U;

				newSeg = newSegment();
				newSeg->MIPScode = (uint32_t*)(address + segmentStartIndex + offset);
				newSeg->MIPScodeLen = -offset;
				newSeg->Type = SEG_SANDWICH;

#if	SHOW_COMPILEAT_STEPS
				printf("CompiltCodeAt(0x%x) - new internal branching self-looping segment 0x%x to address 0x%x\n", address, newSeg, newSeg->MIPScode);
#endif
				prevSeg->pContinueNext = newSeg;
				addToCallers(prevSeg, newSeg);
				prevSeg = newSeg;

				setMemState((size_t)(address + segmentStartIndex + offset), newSeg->MIPScodeLen, newSeg);
				segmentStartIndex = x + 1U;
			}
			else // if we are branching external to the block?
			{
				newSeg = newSegment();
				newSeg->MIPScode = (uint32_t*)(address + segmentStartIndex);
				newSeg->MIPScodeLen = x - segmentStartIndex + 1U;
#if	SHOW_COMPILEAT_STEPS
				printf("CompiltCodeAt(0x%x) - new external branching segment 0x%x to address 0x%x\n", address, newSeg, newSeg->MIPScode);
#endif
				setMemState((size_t)(address + segmentStartIndex), newSeg->MIPScodeLen, newSeg);

				//
				if (prevSeg != NULL)
				{
					prevSeg->pContinueNext = newSeg;
					addToCallers(prevSeg, newSeg);
				}

#if 1
				code_seg_t* externalSegment = getSegmentAt((uint32_t)(address + segmentStartIndex + offset));
				if (externalSegment != NULL)
				{

#if	SHOW_COMPILEAT_STEPS
					printf("CompiltCodeAt(0x%x) - segment 0x%x branches to segment 0x%x to address \n", address, newSeg, externalSegment, externalSegment->MIPScode);
#endif
					newSeg->pBranchNext = externalSegment;
					// addToCallers() will be done when compiling code within C_Interface.c:branchUnknown()
				}
#endif
				prevSeg = newSeg;

				if (segmentStartIndex == 0U)
				{
					newSeg->Type = SEG_START;
				}
				else
				{
					newSeg->Type = SEG_SANDWICH;
				}

				segmentStartIndex = x + 1U;
			}
		}
	} // for (x = 0; x < uiMIPScodeLen; x++)
Ejemplo n.º 12
0
				if (segmentStartIndex == 0U)
				{
					newSeg->Type = SEG_START;
				}
				else
				{
					newSeg->Type = SEG_SANDWICH;
				}

				segmentStartIndex = x + 1U;
			}
		}
	} // for (x = 0; x < uiMIPScodeLen; x++)

	newSeg = getSegmentAt((size_t)address);

	if (newSeg)
	{
		// Now we can translate and emit code to the next 'break' in instructions
		while (newSeg->pContinueNext)
		{
			segmentData.dbgCurrentSegment = newSeg;
			Translate(newSeg);
#if	SHOW_COMPILEAT_STEPS
			printf("CompiltCodeAt(0x%x) - Translating segment      0x%x\n", address, newSeg);
#endif
			newSeg = newSeg->pContinueNext;
		}

		segmentData.dbgCurrentSegment = newSeg;
Ejemplo n.º 13
0
RS::Orientation RPolyline::getOrientation() const {
    if (!isGeometricallyClosed()) {
        return RS::Any;
    }

    RVector minV = RVector::invalid;
    QSharedPointer<RDirected> shapeBefore;
    QSharedPointer<RDirected> shapeAfter;
    QSharedPointer<RShape> shape;
    QSharedPointer<RDirected> previousShape = getSegmentAt(countSegments()-1).dynamicCast<RDirected>();

    // find minimum vertex (lower left corner):
    QList<QSharedPointer<RShape> > segments = getExploded();
    for (int i=0; i<segments.length(); i++) {
        shape = getSegmentAt(i);
        if (shape.isNull()) {
            continue;
        }
        QSharedPointer<RDirected> directed = shape.dynamicCast<RDirected>();
        if (directed.isNull()) {
            continue;
        }

        RVector v = directed->getStartPoint();
        if (!minV.isValid() || v.x<minV.x || (v.x==minV.x && v.y<minV.y)) {
            minV = v;
            shapeBefore = previousShape;
            shapeAfter = directed;
        }

        previousShape = directed;
    }

    double l;
    RVector p;
    QSharedPointer<RArc> arcBefore = shapeBefore.dynamicCast<RArc>();
    if (!arcBefore.isNull()) {
        l = arcBefore->getLength();
        p = arcBefore->getPointsWithDistanceToEnd(l/10, RS::FromStart)[0];
        shapeBefore = QSharedPointer<RLine>(new RLine(p, arcBefore->getEndPoint()));
    }

    QSharedPointer<RArc> arcAfter = shapeAfter.dynamicCast<RArc>();
    if (!arcAfter.isNull()) {
        l = arcAfter->getLength();
        p = arcAfter->getPointsWithDistanceToEnd(l/10, RS::FromEnd)[0];
        shapeAfter = QSharedPointer<RLine>(new RLine(arcAfter->getStartPoint(), p));
    }

    double xa = shapeBefore->getStartPoint().x;
    double ya = shapeBefore->getStartPoint().y;
    double xb = shapeAfter->getStartPoint().x;
    double yb = shapeAfter->getStartPoint().y;
    double xc = shapeAfter->getEndPoint().x;
    double yc = shapeAfter->getEndPoint().y;

    double det = (xb-xa) * (yc-ya) - (xc-xa) * (yb-ya);

    if (det<0.0) {
        // clockwise:
        return RS::CW;
    }
    else {
        // counter-clockwise:
        return RS::CCW;
    }
}