Example #1
0
static void snapPoints(const MgMotion* sender, const Point2d& orignPt,
                       const MgShape* shape, int ignoreHandle,
                       const int* ignoreids, SnapItem arr[3], Point2d* matchpt)
{
    Box2d snapbox(orignPt, 2 * arr[0].dist, 0);         // 捕捉容差框
    GiTransform* xf = sender->view->xform();
    Box2d wndbox(xf->getWndRectM());
    MgShapeIterator it(sender->view->shapes());
    
    while (const MgShape* sp = it.getNext()) {
        if (skipShape(ignoreids, sp)) {
            continue;
        }
        Box2d extent(sp->shapec()->getExtent());
        if (extent.width() < xf->displayToModel(2, true)
            && extent.height() < xf->displayToModel(2, true)) { // 图形太小就跳过
            continue;
        }
        if (extent.isIntersect(wndbox)
            && !snapHandle(sender, orignPt, shape, ignoreHandle, sp, arr[0], matchpt)) {
            if (extent.isIntersect(snapbox)) {
                snapNear(sender, orignPt, shape, ignoreHandle, sp, arr[0], matchpt);
            }
        }
        if (extent.isIntersect(snapbox)) {
            snapGrid(sender, orignPt, shape, ignoreHandle, sp, arr, matchpt);
        }
    }
}
static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) {
	int i = 0;

	mul_m3_v3(t->con.imtx, vec);

	snapGrid(t, vec);

	if (t->num.flag & T_NULL_ONE) {
		if (!(t->con.mode & CON_AXIS0))
			vec[0] = 1.0f;

		if (!(t->con.mode & CON_AXIS1))
			vec[1] = 1.0f;

		if (!(t->con.mode & CON_AXIS2))
			vec[2] = 1.0f;
	}

	if (hasNumInput(&t->num)) {
		applyNumInput(&t->num, vec);
		removeAspectRatio(t, vec);
		constraintNumInput(t, vec);
	}

	/* autovalues is operator param, use that directly but not if snapping is forced */
	if (t->flag & T_AUTOVALUES && (t->tsnap.status & SNAP_FORCED) == 0)
	{
		mul_v3_m3v3(vec, t->con.imtx, t->auto_values);
		constraintAutoValues(t, vec);
		/* inverse transformation at the end */
	}

	if (t->con.mode & CON_AXIS0) {
		pvec[i++] = vec[0];
	}
	if (t->con.mode & CON_AXIS1) {
		pvec[i++] = vec[1];
	}
	if (t->con.mode & CON_AXIS2) {
		pvec[i++] = vec[2];
	}

	mul_m3_v3(t->con.mtx, vec);
}
/**
 * Snap to a coordinate in the drawing using the current snap mode.
 *
 * @param e A mouse event.
 * @return The coordinates of the point or an invalid vector.
 */
RS_Vector RS_Snapper::snapPoint(RS_MouseEvent* e) {
	RS_DEBUG->print("RS_Snapper::snapPoint");

    deleteSnapper();
    snapSpot = RS_Vector(false);

    if (e==NULL) {
		RS_DEBUG->print(RS_Debug::D_WARNING, 
			"RS_Snapper::snapPoint: event is NULL");
        return snapSpot;
    }

    RS_Vector mouseCoord = graphicView->toGraph(e->x(), e->y());

    switch (snapMode) {

    case RS2::SnapFree:
        snapSpot = snapFree(mouseCoord);
        break;

    case RS2::SnapEndpoint:
        snapSpot = snapEndpoint(mouseCoord);
        break;

    case RS2::SnapGrid:
        snapSpot = snapGrid(mouseCoord);
        break;

    case RS2::SnapOnEntity:
        snapSpot = snapOnEntity(mouseCoord);
        break;

    case RS2::SnapCenter:
        snapSpot = snapCenter(mouseCoord);
        break;

    case RS2::SnapMiddle:
        snapSpot = snapMiddle(mouseCoord);
        break;

    case RS2::SnapDist:
        snapSpot = snapDist(mouseCoord);
        break;

    case RS2::SnapIntersection:
        snapSpot = snapIntersection(mouseCoord);
        break;

    default:
        break;
    }

    // handle snap restrictions that can be activated in addition
    //   to the ones above:
    switch (snapRes) {
    case RS2::RestrictOrthogonal:
        snapCoord = restrictOrthogonal(snapSpot);
        break;
    case RS2::RestrictHorizontal:
        snapCoord = restrictHorizontal(snapSpot);
        break;
    case RS2::RestrictVertical:
        snapCoord = restrictVertical(snapSpot);
        break;
    default:
    case RS2::RestrictNothing:
        snapCoord = snapSpot;
        break;
    }

    drawSnapper();

    if (RS_DIALOGFACTORY!=NULL) {
        RS_DIALOGFACTORY->updateCoordinateWidget(snapCoord,
                snapCoord - graphicView->getRelativeZero());
    }
	
	RS_DEBUG->print("RS_Snapper::snapPoint: OK");

    return snapCoord;
}
/**
 * Snap to a coordinate in the drawing using the current snap mode.
 *
 * @param e A mouse event.
 * @return The coordinates of the point or an invalid vector.
 */
RS_Vector RS_Snapper::snapPoint(QMouseEvent* e) {
        RS_DEBUG->print("RS_Snapper::snapPoint");

    snapSpot = RS_Vector(false);
    RS_Vector t(false);

    if (e==NULL) {
                RS_DEBUG->print(RS_Debug::D_WARNING,
                        "RS_Snapper::snapPoint: event is NULL");
        return snapSpot;
    }

    RS_Vector mouseCoord = graphicView->toGraph(e->x(), e->y());
    double ds2Min=RS_MAXDOUBLE*RS_MAXDOUBLE;

    if (snapMode.snapEndpoint) {
        t = snapEndpoint(mouseCoord);
        double&& ds2=mouseCoord.squaredTo(t);

        if (ds2 < ds2Min){
            ds2Min=ds2;
            snapSpot = t;
        }
    }
    if (snapMode.snapCenter) {
        t = snapCenter(mouseCoord);
        double&& ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
            snapSpot = t;
        }
    }
    if (snapMode.snapMiddle) {
        //this is still brutal force
        //todo: accept value from widget QG_SnapMiddleOptions
        if(RS_DIALOGFACTORY != NULL) {
            RS_DIALOGFACTORY->requestSnapMiddleOptions(middlePoints, snapMode.snapMiddle);
        }
        t = snapMiddle(mouseCoord);
        double&& ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
            snapSpot = t;
        }
    }
    if (snapMode.snapDistance) {
        //this is still brutal force
        //todo: accept value from widget QG_SnapDistOptions
        if(RS_DIALOGFACTORY != NULL) {
            RS_DIALOGFACTORY->requestSnapDistOptions(distance, snapMode.snapDistance);
        }
        t = snapDist(mouseCoord);
        double&& ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
            snapSpot = t;
        }
    }
    if (snapMode.snapIntersection) {
        t = snapIntersection(mouseCoord);
        double&& ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
            snapSpot = t;
        }
    }

    if (snapMode.snapOnEntity &&
        snapSpot.distanceTo(mouseCoord) > snapMode.distance) {
        t = snapOnEntity(mouseCoord);
        double&& ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
            snapSpot = t;
        }
    }

    if (snapMode.snapGrid) {
        t = snapGrid(mouseCoord);
        double&& ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
            snapSpot = t;
        }
    }

    if( ! snapSpot.valid ) {
        snapSpot=mouseCoord; //default to snapFree
    } else {
//        std::cout<<"mouseCoord.distanceTo(snapSpot)="<<mouseCoord.distanceTo(snapSpot)<<std::endl;
//        std::cout<<"snapRange="<<snapRange<<std::endl;

        //retreat to snapFree when distance is more than half grid
        RS_Vector&& ds=mouseCoord - snapSpot;
        RS_Vector&& grid=graphicView->getGrid()->getCellVector()*0.5;
        if( fabs(ds.x) > fabs(grid.x) ||  fabs(ds.y) > fabs(grid.y) ) snapSpot = mouseCoord;

        //another choice is to keep snapRange in GUI coordinates instead of graph coordinates
//        if (mouseCoord.distanceTo(snapSpot) > snapRange ) snapSpot = mouseCoord;
    }
    //if (snapSpot.distanceTo(mouseCoord) > snapMode.distance) {
    // handle snap restrictions that can be activated in addition
    //   to the ones above:
    //apply restriction
    RS_Vector rz = graphicView->getRelativeZero();
    RS_Vector vpv(rz.x,snapSpot.y);
    RS_Vector vph(snapSpot.x,rz.y);
    switch (snapMode.restriction) {
    case RS2::RestrictOrthogonal:
        snapCoord= ( mouseCoord.distanceTo(vpv)< mouseCoord.distanceTo(vph))?
                    vpv:vph;
        break;
    case RS2::RestrictHorizontal:
        snapCoord = vph;
        break;
    case RS2::RestrictVertical:
        snapCoord = vpv;
        break;

    //case RS2::RestrictNothing:
    default:
        snapCoord = snapSpot;
        break;
    }
    //}
    //else snapCoord = snapSpot;

    drawSnapper();

    if (RS_DIALOGFACTORY!=NULL) {
        RS_DIALOGFACTORY->updateCoordinateWidget(snapCoord,
                snapCoord - graphicView->getRelativeZero());
    }

        RS_DEBUG->print("RS_Snapper::snapPoint: OK");

    return snapCoord;
}
Example #5
0
/**
 * Snap to a coordinate in the drawing using the current snap mode.
 *
 * @param e A mouse event.
 * @return The coordinates of the point or an invalid vector.
 */
RS_Vector RS_Snapper::snapPoint(QMouseEvent* e) {
        RS_DEBUG->print("RS_Snapper::snapPoint");

	pImpData->snapSpot = RS_Vector(false);
    RS_Vector t(false);

	if (!e) {
                RS_DEBUG->print(RS_Debug::D_WARNING,
						"RS_Snapper::snapPoint: event is nullptr");
		return pImpData->snapSpot;
    }

    RS_Vector mouseCoord = graphicView->toGraph(e->x(), e->y());
    double ds2Min=RS_MAXDOUBLE*RS_MAXDOUBLE;

    if (snapMode.snapEndpoint) {
        t = snapEndpoint(mouseCoord);
		double ds2=mouseCoord.squaredTo(t);

        if (ds2 < ds2Min){
            ds2Min=ds2;
			pImpData->snapSpot = t;
        }
    }
    if (snapMode.snapCenter) {
        t = snapCenter(mouseCoord);
		double ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
			pImpData->snapSpot = t;
        }
    }
    if (snapMode.snapMiddle) {
        //this is still brutal force
        //todo: accept value from widget QG_SnapMiddleOptions
		if(RS_DIALOGFACTORY ) {
            RS_DIALOGFACTORY->requestSnapMiddleOptions(middlePoints, snapMode.snapMiddle);
        }
        t = snapMiddle(mouseCoord);
		double ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
			pImpData->snapSpot = t;
        }
    }
    if (snapMode.snapDistance) {
        //this is still brutal force
        //todo: accept value from widget QG_SnapDistOptions
		if(RS_DIALOGFACTORY ) {
			RS_DIALOGFACTORY->requestSnapDistOptions(m_SnapDistance, snapMode.snapDistance);
        }
        t = snapDist(mouseCoord);
		double ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
			pImpData->snapSpot = t;
        }
    }
    if (snapMode.snapIntersection) {
        t = snapIntersection(mouseCoord);
		double ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
			pImpData->snapSpot = t;
        }
    }

    if (snapMode.snapOnEntity &&
		pImpData->snapSpot.distanceTo(mouseCoord) > snapMode.distance) {
        t = snapOnEntity(mouseCoord);
		double ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
			pImpData->snapSpot = t;
        }
    }

    if (snapMode.snapGrid) {
        t = snapGrid(mouseCoord);
		double ds2=mouseCoord.squaredTo(t);
        if (ds2 < ds2Min){
            ds2Min=ds2;
			pImpData->snapSpot = t;
        }
    }

	if( !pImpData->snapSpot.valid ) {
		pImpData->snapSpot=mouseCoord; //default to snapFree
    } else {
//        std::cout<<"mouseCoord.distanceTo(snapSpot)="<<mouseCoord.distanceTo(snapSpot)<<std::endl;
        //        std::cout<<"snapRange="<<snapRange<<std::endl;

        //retreat to snapFree when distance is more than half grid
        if(snapMode.snapFree){
			RS_Vector const& ds=mouseCoord - pImpData->snapSpot;
			RS_Vector const& grid=graphicView->getGrid()->getCellVector()*0.5;
			if( fabs(ds.x) > fabs(grid.x) ||  fabs(ds.y) > fabs(grid.y) ) pImpData->snapSpot = mouseCoord;
        }

        //another choice is to keep snapRange in GUI coordinates instead of graph coordinates
//        if (mouseCoord.distanceTo(snapSpot) > snapRange ) snapSpot = mouseCoord;
    }
    //if (snapSpot.distanceTo(mouseCoord) > snapMode.distance) {
    // handle snap restrictions that can be activated in addition
    //   to the ones above:
    //apply restriction
    RS_Vector rz = graphicView->getRelativeZero();
	RS_Vector vpv(rz.x, pImpData->snapSpot.y);
	RS_Vector vph(pImpData->snapSpot.x,rz.y);
    switch (snapMode.restriction) {
    case RS2::RestrictOrthogonal:
		pImpData->snapCoord= ( mouseCoord.distanceTo(vpv)< mouseCoord.distanceTo(vph))?
                    vpv:vph;
        break;
    case RS2::RestrictHorizontal:
		pImpData->snapCoord = vph;
        break;
    case RS2::RestrictVertical:
		pImpData->snapCoord = vpv;
        break;

    //case RS2::RestrictNothing:
    default:
		pImpData->snapCoord = pImpData->snapSpot;
        break;
    }
    //}
    //else snapCoord = snapSpot;

	snapPoint(pImpData->snapSpot, false);

	//If the cursor is too-close to the snapSpot (by number of screen pixels), then hide it.
	if (graphicView->toGui(pImpData->snapSpot).distanceTo(graphicView->toGui(mouseCoord)) < 32 /* xenoRadius */)
	{
		graphicView->setCursor(Qt::BlankCursor);
	}
	else
	{
		graphicView->setCursor(Qt::CrossCursor);
	}

	return pImpData->snapCoord;
}