Exemplo n.º 1
0
void
Box3DKnotHolderEntityCenter::knot_set(Geom::Point const &new_pos, Geom::Point const &origin, guint state)
{
    Geom::Point const s = snap_knot_position(new_pos, state);

    SPBox3D *box = SP_BOX3D(item);
    Geom::Affine const i2dt (item->i2dt_affine ());

    box3d_set_center (SP_BOX3D(item), s * i2dt, origin * i2dt, !(state & GDK_SHIFT_MASK) ? Box3D::XY : Box3D::Z,
                      state & GDK_CONTROL_MASK);

    box3d_set_z_orders(box);
    box3d_position_set(box);
}
Exemplo n.º 2
0
static void sp_box3d_finish(Box3DContext *bc)
{
    bc->_message_context->clear();
    bc->ctrl_dragged = false;
    bc->extruded = false;

    if ( bc->item != NULL ) {
        SPDesktop * desktop = SP_EVENT_CONTEXT_DESKTOP(bc);
        SPDocument *doc = sp_desktop_document(desktop);
        if (!doc || !doc->getCurrentPersp3D())
            return;

        SPBox3D *box = SP_BOX3D(bc->item);

        box->orig_corner0 = bc->drag_origin_proj;
        box->orig_corner7 = bc->drag_ptC_proj;

        box->updateRepr();

        box3d_relabel_corners(box);

        desktop->canvas->end_forced_full_redraws();

        sp_desktop_selection(desktop)->set(bc->item);
        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
                         _("Create 3D box"));

        bc->item = NULL;
    }
}
Exemplo n.º 3
0
/**
 * Regenerates the draggers list from the current selection; is called when selection is changed or modified
 */
void
VPDrag::updateDraggers ()
{
    if (this->dragging)
        return;
    // delete old draggers
    for (GList const* i = this->draggers; i != NULL; i = i->next) {
        delete ((VPDragger *) i->data);
    }
    g_list_free (this->draggers);
    this->draggers = NULL;

    g_return_if_fail (this->selection != NULL);

    for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) {
        SPItem *item = SP_ITEM(i->data);
        if (!SP_IS_BOX3D (item)) continue;
        SPBox3D *box = SP_BOX3D (item);

        VanishingPoint vp;
        for (int i = 0; i < 3; ++i) {
            vp.set(box3d_get_perspective(box), Proj::axes[i]);
            addDragger (vp);
        }
    }
}
Exemplo n.º 4
0
std::list<SPBox3D *>
VanishingPoint::selectedBoxes(Inkscape::Selection *sel) {
    std::list<SPBox3D *> sel_boxes;
    for (GSList const* i = sel->itemList(); i != NULL; i = i->next) {
        if (!SP_IS_BOX3D(i->data))
            continue;
        SPBox3D *box = SP_BOX3D(i->data);
        if (this->hasBox(box)) {
            sel_boxes.push_back (box);
        }
    }
    return sel_boxes;
}
Exemplo n.º 5
0
std::set<VanishingPoint*, less_ptr>
VPDragger::VPsOfSelectedBoxes() {
    std::set<VanishingPoint*, less_ptr> sel_vps;
    VanishingPoint *vp;
    // FIXME: Should we take the selection from the parent VPDrag? I guess it shouldn't make a difference.
    Inkscape::Selection *sel = sp_desktop_selection(inkscape_active_desktop());
    for (GSList const* i = sel->itemList(); i != NULL; i = i->next) {
        if (!SP_IS_BOX3D(i->data))
            continue;
        SPBox3D *box = SP_BOX3D(i->data);
        vp = this->findVPWithBox(box);
        if (vp) {
            sel_vps.insert (vp);
        }
    }
    return sel_vps;
}
Exemplo n.º 6
0
void
Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &new_pos, guint state)
{
    Geom::Point const s = snap_knot_position(new_pos, state);

    g_assert(item != NULL);
    SPBox3D *box = SP_BOX3D(item);
    Geom::Affine const i2dt (item->i2dt_affine ());

    Box3D::Axis movement;
    if ((knot_id < 4) != (state & GDK_SHIFT_MASK)) {
        movement = Box3D::XY;
    } else {
        movement = Box3D::Z;
    }

    box3d_set_corner (box, knot_id, s * i2dt, movement, (state & GDK_CONTROL_MASK));
    box3d_set_z_orders(box);
    box3d_position_set(box);
}
Exemplo n.º 7
0
/**
Regenerates the lines list from the current selection; is called on each move
of a dragger, so that lines are always in sync with the actual perspective
*/
void
VPDrag::updateLines ()
{
    // delete old lines
    for (GSList const *i = this->lines; i != NULL; i = i->next) {
        gtk_object_destroy( GTK_OBJECT (i->data));
    }
    g_slist_free (this->lines);
    this->lines = NULL;

    // do nothing if perspective lines are currently disabled
    if (this->show_lines == 0) return;

    g_return_if_fail (this->selection != NULL);

    for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) {
        if (!SP_IS_BOX3D(i->data)) continue;
        SPBox3D *box = SP_BOX3D (i->data);

        this->drawLinesForFace (box, Proj::X);
        this->drawLinesForFace (box, Proj::Y);
        this->drawLinesForFace (box, Proj::Z);
    }
}
Exemplo n.º 8
0
static void sp_box3d_drag(Box3DContext &bc, guint /*state*/)
{
    SPDesktop *desktop = SP_EVENT_CONTEXT(&bc)->desktop;

    if (!bc.item) {

        if (Inkscape::have_viable_layer(desktop, bc._message_context) == false) {
            return;
        }

        /* Create object */
        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_EVENT_CONTEXT_DOCUMENT(&bc));
        Inkscape::XML::Node *repr = xml_doc->createElement("svg:g");
        repr->setAttribute("sodipodi:type", "inkscape:box3d");

        /* Set style */
        sp_desktop_apply_style_tool (desktop, repr, "/tools/shapes/3dbox", false);

        bc.item = (SPItem *) desktop->currentLayer()->appendChildRepr(repr);
        Inkscape::GC::release(repr);
        Inkscape::XML::Node *repr_side;
        // TODO: Incorporate this in box3d-side.cpp!
        for (int i = 0; i < 6; ++i) {
            repr_side = xml_doc->createElement("svg:path");
            repr_side->setAttribute("sodipodi:type", "inkscape:box3dside");
            repr->addChild(repr_side, NULL);

            Box3DSide *side = SP_BOX3D_SIDE(inkscape_active_document()->getObjectByRepr (repr_side));

            guint desc = Box3D::int_to_face(i);

            Box3D::Axis plane = (Box3D::Axis) (desc & 0x7);
            plane = (Box3D::is_plane(plane) ? plane : Box3D::orth_plane_or_axis(plane));
            side->dir1 = Box3D::extract_first_axis_direction(plane);
            side->dir2 = Box3D::extract_second_axis_direction(plane);
            side->front_or_rear = (Box3D::FrontOrRear) (desc & 0x8);

            /* Set style */
            box3d_side_apply_style(side);

            SP_OBJECT(side)->updateRepr(); // calls box3d_side_write() and updates, e.g., the axes string description
        }

        box3d_set_z_orders(SP_BOX3D(bc.item));
        bc.item->updateRepr();

        // TODO: It would be nice to show the VPs during dragging, but since there is no selection
        //       at this point (only after finishing the box), we must do this "manually"
        /* bc._vpdrag->updateDraggers(); */

        desktop->canvas->force_full_redraw_after_interruptions(5);
    }

    g_assert(bc.item);

    SPBox3D *box = SP_BOX3D(bc.item);

    box->orig_corner0 = bc.drag_origin_proj;
    box->orig_corner7 = bc.drag_ptC_proj;

    box3d_check_for_swapped_coords(box);

    /* we need to call this from here (instead of from box3d_position_set(), for example)
       because z-order setting must not interfere with display updates during undo/redo */
    box3d_set_z_orders (box);

    box3d_position_set(box);

    // status text
    bc._message_context->setF(Inkscape::NORMAL_MESSAGE, "%s", _("<b>3D Box</b>; with <b>Shift</b> to extrude along the Z axis"));
}
Exemplo n.º 9
0
Persp3D *
box3d_side_perspective(Box3DSide *side) {
    return SP_BOX3D(side->parent)->persp_ref->getObject();
}
Exemplo n.º 10
0
void Box3DSide::set_shape() {
    if (!this->document->getRoot()) {
        // avoid a warning caused by sp_document_height() (which is called from sp_item_i2d_affine() below)
        // when reading a file containing 3D boxes
        return;
    }

    SPObject *parent = this->parent;

    if (!SP_IS_BOX3D(parent)) {
        g_warning("Parent of 3D box side is not a 3D box.\n");
        return;
    }

    SPBox3D *box = SP_BOX3D(parent);

    Persp3D *persp = box3d_side_perspective(this);

    if (!persp) {
        return;
    }

    // TODO: Draw the correct quadrangle here
    //       To do this, determine the perspective of the box, the orientation of the side (e.g., XY-FRONT)
    //       compute the coordinates of the corners in P^3, project them onto the canvas, and draw the
    //       resulting path.

    unsigned int corners[4];
    box3d_side_compute_corner_ids(this, corners);

    SPCurve *c = new SPCurve();

    if (!box3d_get_corner_screen(box, corners[0]).isFinite() ||
        !box3d_get_corner_screen(box, corners[1]).isFinite() ||
        !box3d_get_corner_screen(box, corners[2]).isFinite() ||
        !box3d_get_corner_screen(box, corners[3]).isFinite() )
    {
        g_warning ("Trying to draw a 3D box side with invalid coordinates.\n");
        return;
    }

    c->moveto(box3d_get_corner_screen(box, corners[0]));
    c->lineto(box3d_get_corner_screen(box, corners[1]));
    c->lineto(box3d_get_corner_screen(box, corners[2]));
    c->lineto(box3d_get_corner_screen(box, corners[3]));
    c->closepath();

    /* Reset the this'scurve to the "original_curve"
     * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
    this->setCurveInsync( c, TRUE);

    if (hasPathEffect() && pathEffectsEnabled()) {
        SPCurve *c_lpe = c->copy();
        bool success = this->performPathEffect(c_lpe);

        if (success) {
            this->setCurveInsync(c_lpe, TRUE);
        }

        c_lpe->unref();
    }

    c->unref();
}
Exemplo n.º 11
0
Geom::Point
Box3DKnotHolderEntityCenter::knot_get() const
{
    return box3d_get_center_screen(SP_BOX3D(item));
}
Exemplo n.º 12
0
Geom::Point
Box3DKnotHolderEntity::knot_get_generic(SPItem *item, unsigned int knot_id) const
{
    return box3d_get_corner_screen(SP_BOX3D(item), knot_id);
}
Exemplo n.º 13
0
bool
sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select, bool skip_all_lpeitems)
{
    bool did = false;
    
    for (;
         items != NULL;
         items = items->next) {

        SPItem *item = SP_ITEM(items->data);
    	SPDocument *document = item->document;

        if ( skip_all_lpeitems &&
             SP_IS_LPE_ITEM(item) && 
             !SP_IS_GROUP(item) ) // also convert objects in an SPGroup when skip_all_lpeitems is set.
        { 
            continue;
        }

        if (SP_IS_PATH(item) && !SP_PATH(item)->original_curve) {
            continue; // already a path, and no path effect
        }

        if (SP_IS_BOX3D(item)) {
            // convert 3D box to ordinary group of paths; replace the old element in 'selected' with the new group
            Inkscape::XML::Node *repr = SP_OBJECT_REPR(box3d_convert_to_group(SP_BOX3D(item)));
            
            if (repr) {
                *to_select = g_slist_prepend (*to_select, repr);
                did = true;
                *selected = g_slist_remove (*selected, item);
            }

            continue;
        }
        
        if (SP_IS_GROUP(item)) {
            sp_lpe_item_remove_all_path_effects(SP_LPE_ITEM(item), true);
            GSList *item_list = sp_item_group_item_list(SP_GROUP(item));
            
            GSList *item_to_select = NULL;
            GSList *item_selected = NULL;
            
            if (sp_item_list_to_curves(item_list, &item_selected, &item_to_select))
                did = true;

            g_slist_free(item_list);
            g_slist_free(item_to_select);
            g_slist_free(item_selected);

            continue;
        }

        Inkscape::XML::Node *repr = sp_selected_item_to_curved_repr(item, 0);
        if (!repr)
            continue;

        did = true;
        *selected = g_slist_remove (*selected, item);

        // remember the position of the item
        gint pos = SP_OBJECT_REPR(item)->position();
        // remember parent
        Inkscape::XML::Node *parent = SP_OBJECT_REPR(item)->parent();
        // remember id
        char const *id = SP_OBJECT_REPR(item)->attribute("id");
        // remember title
        gchar *title = item->title();
        // remember description
        gchar *desc = item->desc();

        // It's going to resurrect, so we delete without notifying listeners.
        SP_OBJECT(item)->deleteObject(false);

        // restore id
        repr->setAttribute("id", id);
        // add the new repr to the parent
        parent->appendChild(repr);
        SPObject* newObj = document->getObjectByRepr(repr);
        if (title && newObj) {
        	newObj->setTitle(title);
        	g_free(title);
        }
        if (desc && newObj) {
        	newObj->setDesc(desc);
        	g_free(desc);
        }

        // move to the saved position
        repr->setPosition(pos > 0 ? pos : 0);

        /* Buglet: We don't re-add the (new version of the) object to the selection of any other
         * desktops where it was previously selected. */
        *to_select = g_slist_prepend (*to_select, repr);
        Inkscape::GC::release(repr);
    }
    
    return did;
}