RVector RSnapIntersection::snap( const RVector& position, RGraphicsView& view, double range) { entityIds.clear(); RDocument* document = view.getDocument(); if (document==NULL) { lastSnap = position; return lastSnap; } if (RMath::isNaN(range)) { int rangePixels = RSettings::getSnapRange(); range = view.mapDistanceFromView(rangePixels); } RBox queryBox(position, range); QMap<REntity::Id, QSet<int> > ids = document->queryIntersectedShapesXY( queryBox, true /*false?*/, true, RBlock::INVALID_ID, QList<RS::EntityType>() << RS::EntityHatch); return snap(position, view, ids, queryBox); }
RVector RSnapAuto::snap(const RVector& position, RGraphicsView& view, double range) { entityIds.clear(); if (RMath::isNaN(range)) { int rangePixels = RSettings::getSnapRange(); range = view.mapDistanceFromView(rangePixels); } RDocument* document = view.getDocument(); if (document==NULL) { lastSnap = position; return lastSnap; } RSnapAuto::init(); if (RMath::isNaN(range)) { int rangePixels = RSettings::getSnapRange(); range = view.mapDistanceFromView(rangePixels); } // matching ids per query range: QList<QSet<REntity::Id> > idsList; QList<RBox> queryBoxList; bool foundEntities = false; for (double r=range/1.0; r<=range+RS::PointTolerance; r+=range/1.0) { RBox queryBox(position, r); queryBoxList.append(queryBox); QMap<REntity::Id, QSet<int> > ids = document->queryIntersectedShapesXY( queryBox, true, true, RBlock::INVALID_ID // 20151027: allow snapping to hatch end points, etc: /*, QList<RS::EntityType>() << RS::EntityHatch*/); idsList.append(ids.keys().toSet()); if (ids.isEmpty()) { continue; } foundEntities = true; // intersection if (intersections) { RSnapIntersection snapIntersection; lastSnap = snapIntersection.snap(position, view, ids, queryBox); if (lastSnap.isValid() && lastSnap.getDistanceTo2d(position) < range) { status = RSnap::Intersection; entityIds = snapIntersection.getEntityIds(); return lastSnap; } } lastSnap = RVector::invalid; } // interrupted by mouse move: if (RMouseEvent::hasMouseMoved()) { status = RSnap::Free; return position; } // end points: if (foundEntities && endPoints) { for (int k=0; k<idsList.size() && k<queryBoxList.size(); k++) { // query box and matching IDs cached from intersection snap: RBox queryBox = queryBoxList.at(k); QSet<REntity::Id> ids = idsList.at(k); RSnapEnd snapEnd; lastSnap = snapEnd.snap(position, view, ids, queryBox); if (lastSnap.isValid() && lastSnap.getDistanceTo2d(position) < range) { status = RSnap::Endpoint; entityIds = snapEnd.getEntityIds(); return lastSnap; } } lastSnap = RVector::invalid; } // middle points: if (foundEntities && middlePoints) { for (int k=0; k<idsList.size() && k<queryBoxList.size(); k++) { // query box and matching IDs cached from intersection snap: RBox queryBox = queryBoxList.at(k); QSet<REntity::Id> ids = idsList.at(k); RSnapMiddle snapMiddle; lastSnap = snapMiddle.snap(position, view, ids, queryBox); if (lastSnap.isValid() && lastSnap.getDistanceTo2d(position) < range) { status = RSnap::Middle; entityIds = snapMiddle.getEntityIds(); return lastSnap; } } lastSnap = RVector::invalid; } // center points: if (foundEntities && centerPoints) { for (int k=0; k<idsList.size() && k<queryBoxList.size(); k++) { // query box and matching IDs cached from intersection snap: RBox queryBox = queryBoxList.at(k); QSet<REntity::Id> ids = idsList.at(k); RSnapCenter snapCenter; lastSnap = snapCenter.snap(position, view, ids, queryBox); if (lastSnap.isValid() && lastSnap.getDistanceTo2d(position) < range) { status = RSnap::Center; entityIds = snapCenter.getEntityIds(); return lastSnap; } } lastSnap = RVector::invalid; } // perpendicular: if (foundEntities && perpendicular) { for (int k=0; k<idsList.size() && k<queryBoxList.size(); k++) { // query box and matching IDs cached from intersection snap: RBox queryBox = queryBoxList.at(k); QSet<REntity::Id> ids = idsList.at(k); RSnapPerpendicular snapPerpendicular; lastSnap = snapPerpendicular.snap(position, view, ids, queryBox); if (lastSnap.isValid() && lastSnap.getDistanceTo2d(position) < range) { status = RSnap::Perpendicular; entityIds = snapPerpendicular.getEntityIds(); return lastSnap; } } lastSnap = RVector::invalid; } // reference points: if (foundEntities && referencePoints) { for (int k=0; k<idsList.size() && k<queryBoxList.size(); k++) { // query box and matching IDs cached from intersection snap: RBox queryBox = queryBoxList.at(k); QSet<REntity::Id> ids = idsList.at(k); RSnapReference snapReference; lastSnap = snapReference.snap(position, view, ids, queryBox); if (lastSnap.isValid() && lastSnap.getDistanceTo2d(position) < range) { status = RSnap::Reference; entityIds = snapReference.getEntityIds(); return lastSnap; } } lastSnap = RVector::invalid; } // grid points: if (gridPoints) { RSnapGrid snapGrid; lastSnap = snapGrid.snap(position, view, range); if (lastSnap.isValid() && lastSnap.getDistanceTo2d(position) < range) { status = RSnap::Grid; return lastSnap; } lastSnap = RVector::invalid; } // on entity snap is slow and almost never used: if (foundEntities && pointsOnEntity) { for (int k=0; k<idsList.size() && k<queryBoxList.size(); k++) { // query box and matching IDs cached from intersection snap: RBox queryBox = queryBoxList.at(k); QSet<REntity::Id> ids = idsList.at(k); // on entity RSnapOnEntity snapOnEntity; lastSnap = snapOnEntity.snap(position, view, ids, queryBox); if (lastSnap.isValid() && lastSnap.getDistanceTo2d(position) < range) { status = RSnap::OnEntity; entityIds = snapOnEntity.getEntityIds(); return lastSnap; } } lastSnap = RVector::invalid; } // free: if (freePositioning) { lastSnap = position; status = RSnap::Free; return lastSnap; } return RVector::invalid; }