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; }
/** * 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; }