Esempio n. 1
0
void
SPConnEndPair::getEndpoints(Geom::Point endPts[]) const {
    SPCurve *curve = _path->curve;
    SPItem *h2attItem[2];
    getAttachedItems(h2attItem);

    for (unsigned h = 0; h < 2; ++h) {
        if ( h2attItem[h] ) {
            Geom::OptRect bbox = h2attItem[h]->getBounds(sp_item_i2doc_affine(h2attItem[h]));
            if (bbox) {
                endPts[h] = bbox->midpoint();
            } else {
                // FIXME
                endPts[h] = Geom::Point(0, 0);
            }
        }
        else
        {
            if (h == 0) {
                endPts[h] = *(curve->first_point());
            }
            else {
                endPts[h] = *(curve->last_point());
            }
        }
    }
}
Geom::Point SPAvoidRef::getConnectionPointPos()
{
    g_assert(item);
    // the center is all we are interested in now; we used to care
    // about non-center points, but that's moot.
    Geom::OptRect bbox = item->documentVisualBounds();
    return (bbox) ? bbox->midpoint() : Geom::Point(0, 0);
}
// If we have a selection of multiple items, then the center of the first item
// will be returned; this is also the case in SelTrans::centerRequest()
boost::optional<Geom::Point> Selection::center() const {
    std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList();
    if (!items.empty()) {
        SPItem *first = items.back(); // from the first item in selection
        if (first->isCenterSet()) { // only if set explicitly
            return first->getCenter();
        }
    }
    Geom::OptRect bbox = preferredBounds();
    if (bbox) {
        return bbox->midpoint();
    } else {
        return boost::optional<Geom::Point>();
    }
}
Esempio n. 4
0
/**
Center of bbox of item
*/
static Geom::Point
unclump_center (SPItem *item)
{
    std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(item->getId());
    if ( i != c_cache.end() ) {
        return i->second;
    }

    Geom::OptRect r = item->desktopVisualBounds();
    if (r) {
        Geom::Point const c = r->midpoint();
        c_cache[item->getId()] = c;
        return c;
    } else {
        // FIXME
        return Geom::Point(0, 0);
    }
}
Esempio n. 5
0
void Inkscape::getBBoxPoints(Geom::OptRect const bbox,
                             std::vector<SnapCandidatePoint> *points,
                             bool const /*isTarget*/,
                             bool const includeCorners,
                             bool const includeLineMidpoints,
                             bool const includeObjectMidpoints)
{
    if (bbox) {
        // collect the corners of the bounding box
        for ( unsigned k = 0 ; k < 4 ; k++ ) {
            if (includeCorners) {
                points->push_back(SnapCandidatePoint(bbox->corner(k), SNAPSOURCE_BBOX_CORNER, -1, SNAPTARGET_BBOX_CORNER, *bbox));
            }
            // optionally, collect the midpoints of the bounding box's edges too
            if (includeLineMidpoints) {
                points->push_back(SnapCandidatePoint((bbox->corner(k) + bbox->corner((k+1) % 4))/2, SNAPSOURCE_BBOX_EDGE_MIDPOINT, -1, SNAPTARGET_BBOX_EDGE_MIDPOINT, *bbox));
            }
        }
        if (includeObjectMidpoints) {
            points->push_back(SnapCandidatePoint(bbox->midpoint(), SNAPSOURCE_BBOX_MIDPOINT, -1, SNAPTARGET_BBOX_MIDPOINT, *bbox));
        }
    }
}
Esempio n. 6
0
void SPShape::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) const {
    if (this->_curve == NULL) {
        return;
    }

    Geom::PathVector const &pathv = this->_curve->get_pathvector();

    if (pathv.empty()) {
        return;
    }

    Geom::Affine const i2dt (this->i2dt_affine ());

    if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT)) {
        Geom::OptRect bbox = this->desktopVisualBounds();

        if (bbox) {
            p.push_back(Inkscape::SnapCandidatePoint(bbox->midpoint(), Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
        }
    }

    for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
        if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP)) {
            // Add the first point of the path
            p.push_back(Inkscape::SnapCandidatePoint(path_it->initialPoint() * i2dt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
        }

        Geom::Path::const_iterator curve_it1 = path_it->begin();      // incoming curve
        Geom::Path::const_iterator curve_it2 = ++(path_it->begin());  // outgoing curve

        while (curve_it1 != path_it->end_default())
        {
            // For each path: consider midpoints of line segments for snapping
            if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_LINE_MIDPOINT)) {
                if (Geom::LineSegment const* line_segment = dynamic_cast<Geom::LineSegment const*>(&(*curve_it1))) {
                    p.push_back(Inkscape::SnapCandidatePoint(Geom::middle_point(*line_segment) * i2dt, Inkscape::SNAPSOURCE_LINE_MIDPOINT, Inkscape::SNAPTARGET_LINE_MIDPOINT));
                }
            }

            if (curve_it2 == path_it->end_default()) { // Test will only pass for the last iteration of the while loop
                if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && !path_it->closed()) {
                    // Add the last point of the path, but only for open paths
                    // (for closed paths the first and last point will coincide)
                    p.push_back(Inkscape::SnapCandidatePoint((*curve_it1).finalPoint() * i2dt, Inkscape::SNAPSOURCE_NODE_CUSP, Inkscape::SNAPTARGET_NODE_CUSP));
                }
            } else {
                /* Test whether to add the node between curve_it1 and curve_it2.
                 * Loop to end_default (so only iterating through the stroked part); */

                Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2);

                bool c1 = snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_CUSP) && (nodetype == Geom::NODE_CUSP || nodetype == Geom::NODE_NONE);
                bool c2 = snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_NODE_SMOOTH) && (nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM);

                if (c1 || c2) {
                    Inkscape::SnapSourceType sst;
                    Inkscape::SnapTargetType stt;

                    switch (nodetype) {
                    case Geom::NODE_CUSP:
                        sst = Inkscape::SNAPSOURCE_NODE_CUSP;
                        stt = Inkscape::SNAPTARGET_NODE_CUSP;
                        break;
                    case Geom::NODE_SMOOTH:
                    case Geom::NODE_SYMM:
                        sst = Inkscape::SNAPSOURCE_NODE_SMOOTH;
                        stt = Inkscape::SNAPTARGET_NODE_SMOOTH;
                        break;
                    default:
                        sst = Inkscape::SNAPSOURCE_UNDEFINED;
                        stt = Inkscape::SNAPTARGET_UNDEFINED;
                        break;
                    }

                    p.push_back(Inkscape::SnapCandidatePoint(curve_it1->finalPoint() * i2dt, sst, stt));
                }
            }

            ++curve_it1;
            ++curve_it2;
        }

        // Find the internal intersections of each path and consider these for snapping
        // (using "Method 1" as described in Inkscape::ObjectSnapper::_collectNodes())
        if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_PATH_INTERSECTION) || snapprefs->isSourceSnappable(Inkscape::SNAPSOURCE_PATH_INTERSECTION)) {
            Geom::Crossings cs;

            try {
                cs = self_crossings(*path_it); // This can be slow!

                if (!cs.empty()) { // There might be multiple intersections...
                    for (Geom::Crossings::const_iterator i = cs.begin(); i != cs.end(); ++i) {
                        Geom::Point p_ix = (*path_it).pointAt((*i).ta);
                        p.push_back(Inkscape::SnapCandidatePoint(p_ix * i2dt, Inkscape::SNAPSOURCE_PATH_INTERSECTION, Inkscape::SNAPTARGET_PATH_INTERSECTION));
                    }
                }
            } catch (Geom::RangeError &e) {
                // do nothing
                // The exception could be Geom::InfiniteSolutions: then no snappoints should be added
            }

        }
    }
}
Esempio n. 7
0
static bool sp_spray_recursive(SPDesktop *desktop,
                               Inkscape::Selection *selection,
                               SPItem *item,
                               Geom::Point p,
                               Geom::Point /*vector*/,
                               gint mode,
                               double radius,
                               double /*force*/,
                               double population,
                               double &scale,
                               double scale_variation,
                               bool /*reverse*/,
                               double mean,
                               double standard_deviation,
                               double ratio,
                               double tilt,
                               double rotation_variation,
                               gint _distrib)
{
    bool did = false;
    
    if (SP_IS_BOX3D(item) ) {
        // convert 3D boxes to ordinary groups before spraying their shapes
        item = box3d_convert_to_group(SP_BOX3D(item));
        selection->add(item);
    }

    double _fid = g_random_double_range(0, 1);
    double angle = g_random_double_range( - rotation_variation / 100.0 * M_PI , rotation_variation / 100.0 * M_PI );
    double _scale = g_random_double_range( 1.0 - scale_variation / 100.0, 1.0 + scale_variation / 100.0 );
    double dr; double dp;
    random_position( dr, dp, mean, standard_deviation, _distrib );
    dr=dr*radius;

    if (mode == SPRAY_MODE_COPY) {
        Geom::OptRect a = item->documentVisualBounds();
        if (a) {
            SPItem *item_copied;
            if(_fid <= population)
            {
                // duplicate
                SPDocument *doc = item->document;
                Inkscape::XML::Document* xml_doc = doc->getReprDoc();
                Inkscape::XML::Node *old_repr = item->getRepr();
                Inkscape::XML::Node *parent = old_repr->parent();
                Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
                parent->appendChild(copy);

                SPObject *new_obj = doc->getObjectByRepr(copy);
                item_copied = (SPItem *) new_obj;   //convertion object->item
                Geom::Point center=item->getCenter();
                sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale,_scale));
                sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale));

                sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
                //Move the cursor p
                Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
                sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
                did = true;
            }
        }
    } else if (mode == SPRAY_MODE_SINGLE_PATH) {

        SPItem *father = NULL;         //initial Object
        SPItem *item_copied = NULL;    //Projected Object
        SPItem *unionResult = NULL;    //previous union
        SPItem *son = NULL;            //father copy

        int i=1;
        for (GSList *items = g_slist_copy((GSList *) selection->itemList());
                items != NULL;
                items = items->next) {

            SPItem *item1 = (SPItem *) items->data;
            if (i == 1) {
                father = item1;
            }
            if (i == 2) {
                unionResult = item1;
            }
            i++;
        }
        SPDocument *doc = father->document;
        Inkscape::XML::Document* xml_doc = doc->getReprDoc();
        Inkscape::XML::Node *old_repr = father->getRepr();
        Inkscape::XML::Node *parent = old_repr->parent();

        Geom::OptRect a = father->documentVisualBounds();
        if (a) {
            if (i == 2) {
                Inkscape::XML::Node *copy1 = old_repr->duplicate(xml_doc);
                parent->appendChild(copy1);
                SPObject *new_obj1 = doc->getObjectByRepr(copy1);
                son = (SPItem *) new_obj1;   // conversion object->item
                unionResult = son;
                Inkscape::GC::release(copy1);
            }

            if (_fid <= population) { // Rules the population of objects sprayed
                // duplicates the father
                Inkscape::XML::Node *copy2 = old_repr->duplicate(xml_doc);
                parent->appendChild(copy2);
                SPObject *new_obj2 = doc->getObjectByRepr(copy2);
                item_copied = (SPItem *) new_obj2;

                // Move around the cursor
                Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint()); 

                Geom::Point center=father->getCenter();
                sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale));
                sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale));
                sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle));
                sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));

                // union and duplication
                selection->clear();
                selection->add(item_copied);
                selection->add(unionResult);
                sp_selected_path_union_skip_undo(selection->desktop());
                selection->add(father);
                Inkscape::GC::release(copy2);
                did = true;
            }
        }
    } else if (mode == SPRAY_MODE_CLONE) {
        Geom::OptRect a = item->documentVisualBounds();
        if (a) {
            if(_fid <= population) {
                SPItem *item_copied;
                SPDocument *doc = item->document;
                Inkscape::XML::Document* xml_doc = doc->getReprDoc();
                Inkscape::XML::Node *old_repr = item->getRepr();
                Inkscape::XML::Node *parent = old_repr->parent();

                // Creation of the clone
                Inkscape::XML::Node *clone = xml_doc->createElement("svg:use");
                // Ad the clone to the list of the father's sons
                parent->appendChild(clone);
                // Generates the link between father and son attributes
                clone->setAttribute("xlink:href", g_strdup_printf("#%s", old_repr->attribute("id")), false); 

                SPObject *clone_object = doc->getObjectByRepr(clone);
                // conversion object->item
                item_copied = (SPItem *) clone_object;
                Geom::Point center = item->getCenter();
                sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale));
                sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale));
                sp_spray_rotate_rel(center, desktop, item_copied, Geom::Rotate(angle));
                Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
                sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));

                Inkscape::GC::release(clone);

                did = true;
            }
        }
    }

    return did;
}