Esempio n. 1
0
RVector RSnapEntityBase::snap(
        const RVector& position,
        RGraphicsView& view,
        double range) {

    entityIds.clear();
    RDocument* document = view.getDocument();

    lastSnap = RVector::invalid;

    if (document==NULL) {
        lastSnap = position;
        lastSnap.valid = false;
        return lastSnap;
    }

    if (RMath::isNaN(range)) {
        int rangePixels = RSettings::getSnapRange();
        range = view.mapDistanceFromView(rangePixels);
    }

    RBox queryBox(position, range);

    QSet<REntity::Id> candidates =
            document->queryIntersectedEntitiesXY(
                queryBox, true, true, RBlock::INVALID_ID);

    return snap(position, view, candidates, queryBox);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
RVector RSnapEntityBase::snap(
        const RVector& position,
        RGraphicsView& view,
        const QSet<REntity::Id>& candidates,
        const RBox& queryBox) {

    RDocument* document = view.getDocument();
    if (document==NULL) {
        return lastSnap;
    }

    REntity::Id entityId;
    double minDist = RMAXDOUBLE;
    double dist;

    QSet<REntity::Id>::const_iterator it;
    for (it=candidates.begin(); it!=candidates.end(); it++) {
        // 20111112: query direct:
        //QSharedPointer<REntity> e = document->queryEntityDirect(*it);
        QSharedPointer<REntity> e = document->queryEntity(*it);
        if (e.isNull()) {
            continue;
        }

        RVector candidate =
            position.getClosest2D(
                snapEntity(e, position, queryBox, view)
            );

        dist = candidate.getDistanceTo2D(position);
        if (dist<minDist) {
            lastSnap = candidate;
            minDist = dist;
            entityId = e->getId();
        }
    }

    if (!lastSnap.isValid()) {
        lastSnap = position;
        lastSnap.valid = false;
        return lastSnap;
    }
    else {
        entityIds.insert(entityId);
        return lastSnap;
    }
}
Esempio n. 4
0
QList<RVector> ROrthoGrid::getIdealGridSpacing(RGraphicsView& view, int minPixelSpacing, const RVector& minSpacing, const RVector& minMetaSpacing) {
    RS::Unit unit = view.getDocument()->getUnit();
    RS::LinearFormat linearFormat = view.getDocument()->getLinearFormat();
    QList<RVector> ret;

    if (isFractionalFormat(linearFormat) && !RUnit::isMetric(unit)) {
        double idealInchSpacing = RUnit::convert(view.mapDistanceFromView(qMax(minPixelSpacing, 1)), unit, RS::Inch);

        RVector spacing = RUnit::convert(minSpacing, unit, RS::Inch);
        spacing.x = inchAutoscale(spacing.x, idealInchSpacing, unit);
        spacing.y = inchAutoscale(spacing.y, idealInchSpacing, unit);
        spacing = RUnit::convert(spacing, RS::Inch, unit);

        // never drop below min spacing:
        if (spacing.x<minSpacing.x) {
            spacing.x = minSpacing.x;
        }
        if (spacing.y<minSpacing.y) {
            spacing.y = minSpacing.y;
        }

        RVector metaSpacing = spacing; // RVector(1.0 / 64, 1.0 / 64, 1.0 / 64);
        metaSpacing.x = inchAutoscale(metaSpacing.x, idealInchSpacing * 4, unit);
        metaSpacing.y = inchAutoscale(metaSpacing.y, idealInchSpacing * 4, unit);
        metaSpacing = RUnit::convert(metaSpacing, RS::Inch, unit);

        // never drop below min spacing:
        if (metaSpacing.x<minMetaSpacing.x) {
            metaSpacing.x = minMetaSpacing.x;
        }
        if (metaSpacing.y<minMetaSpacing.y) {
            metaSpacing.y = minMetaSpacing.y;
        }

        // foot: never show meta grid of < 1 foot:
        if (unit==RS::Foot) {
            if (metaSpacing.x<1.0) {
                metaSpacing.x = 1.0;
            }
            if (metaSpacing.y<1.0) {
                metaSpacing.y = 1.0;
            }
        }

//        if (metaSpacing.x < this->metaSpacing.x) {
//            metaSpacing.x = this->metaSpacing.x;
//        }

        ret.append(spacing);
        ret.append(metaSpacing);
        return ret;
    } else {
        // ideal (minimum) grid spacing for the given view (some odd number):
        double idealSpacing = view.mapDistanceFromView(qMax(minPixelSpacing, 1));

        // idealSpacing = minSpacing * idealFactor
        RVector idealFactor(idealSpacing / minSpacing.x,
                            idealSpacing / minSpacing.y);

        // idealFactor = minSpacing * 10^n
        RVector n(log(idealFactor.x / minSpacing.x) / log(10.0),
                  log(idealFactor.y / minSpacing.y) / log(10.0));

        // factor = minSpacing * 10^ceil(n)
        RVector factor(minSpacing.x * pow(10.0, ceil(n.x - 1.0e-6)),
                       minSpacing.y * pow(10.0, ceil(n.y - 1.0e-6)));

        // never drop below min spacing:
        if (factor.x<1.0) {
            factor.x = 1.0;
        }
        if (factor.y<1.0) {
            factor.y = 1.0;
        }

        // grid spacing:
        double x, y;
        x = minSpacing.x * factor.x;
        y = minSpacing.y * factor.y;
        ret.append(RVector(x,y));

        // meta grid spacing:
        double mx, my;
        if (RMath::isNaN(minMetaSpacing.x)) {
            mx = x * 10;
        }
        else {
            //mx = minMetaSpacing.x * factor.x;
            mx = minMetaSpacing.x;
        }

        if (RMath::isNaN(minMetaSpacing.y)) {
            my = y * 10;
        }
        else {
            //my = minMetaSpacing.y * factor.y;
            my = minMetaSpacing.y;
        }
        ret.append(RVector(mx, my));

        //ret.append(RVector(minSpacing.x * factor.x, minSpacing.y * factor.y));
        //ret.append(RVector(minMetaSpacing.x * factor.x, minMetaSpacing.y * factor.y));
        //ret.append(ret.at(0) * 10);

        return ret;
    }
}
Esempio n. 5
0
RVector RSnapIntersection::snap(
    const RVector& position,
    RGraphicsView& view,
    const QMap<REntity::Id, QSet<int> >& candidates,
    const RBox& queryBox) {

    RDocument* document = view.getDocument();
    if (document==NULL) {
        return lastSnap;
    }

    REntity::Id entityId1 = REntity::INVALID_ID;
    REntity::Id entityId2 = REntity::INVALID_ID;
    lastSnap = RVector::invalid;
    double minDist = RMAXDOUBLE;
    double dist;

    QMap<REntity::Id, QSet<int> >::const_iterator it1;
    for (it1=candidates.begin(); it1!=candidates.end(); it1++) {
        if (RMouseEvent::hasMouseMoved()) {
            lastSnap = RVector::invalid;
            return RVector::invalid;
        }
        QSharedPointer<REntity> e1 = document->queryEntityDirect(it1.key());
        if (e1.isNull()) {
            continue;
        }

        if (e1->getType()==RS::EntityText ||
                e1->getType()==RS::EntityAttribute ||
                e1->getType()==RS::EntityAttributeDefinition) {
            continue;
        }

        QMap<REntity::Id, QSet<int> >::const_iterator it2;
        for (it2=it1; it2!=candidates.end(); it2++) {
            if (RMouseEvent::hasMouseMoved()) {
                lastSnap = RVector::invalid;
                return RVector::invalid;
            }
            QSharedPointer<REntity> e2 = document->queryEntityDirect(it2.key());
            if (e2.isNull()) {
                continue;
            }
            if (e2->getType()==RS::EntityText ||
                    e2->getType()==RS::EntityAttribute ||
                    e2->getType()==RS::EntityAttributeDefinition) {
                continue;
            }

            QList<RVector> candidates = e1->getIntersectionPoints(*e2, true, queryBox);

            if (candidates.isEmpty()) {
                continue;
            }

            RVector candidate = position.getClosest(candidates);

            dist = candidate.getDistanceTo(position);
            if (dist<minDist) {
                lastSnap = candidate;
                minDist = dist;
                entityId1 = e1->getId();
                entityId2 = e2->getId();
            }
        }
    }

    if (!lastSnap.isValid()) {
        lastSnap = position;
        lastSnap.valid = false;
        return lastSnap;
    }
    else {
        if (entityId1!=REntity::INVALID_ID) {
            entityIds.insert(entityId1);
        }
        if (entityId2!=REntity::INVALID_ID) {
            entityIds.insert(entityId2);
        }
        return lastSnap;
    }
}
Esempio n. 6
0
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;
}