Commit 619f8b5d authored by Tavmjong Bah's avatar Tavmjong Bah Committed by Tavmjong Bah

Add option to scale mesh to fit in bounding box.

(bzr r15173)
parent e9e8a01e
......@@ -2509,7 +2509,7 @@ http://www.inkscape.org/</dc:description>
<g id="paint-pattern" transform="translate(395.0006,254)" inkscape:label="#fill_pattern">
<rect inkscape:label="#ccc" y="66" x="671" height="18" width="18" id="rect4541" style="color:#000000;fill:#99b6d4;fill-rule:evenodd;stroke-width:1.0000004" />
<path style="fill:#ffffff;stroke:#000000;stroke-width:0;stroke-linejoin:round" d="M 676.7274,66.00001 673.4547,69.42858 677.5456,73.7143 681.6365,69.42858 678.3638,66.00001 676.7274,66.00001 Z M 681.6365,69.42858 685.7274,73.7143 689.0001,70.28572 689.0001,68.57144 686.5456,66.00001 684.9092,66.00001 681.6365,69.42858 Z M 685.7274,73.7143 681.6365,78.00001 685.7274,82.28573 689.0001,78.85715 689.0001,77.14287 685.7274,73.7143 Z M 685.7274,82.28573 684.091,84.00001 687.3638,84.00001 685.7274,82.28573 Z M 681.6365,78.00001 677.5456,73.7143 673.4547,78.00001 677.5456,82.28573 681.6365,78.00001 Z M 677.5456,82.28573 675.9092,84.00001 679.1819,84.00001 677.5456,82.28573 Z M 673.4547,78.00001 671.0001,75.42858 671.0001,80.57144 673.4547,78.00001 Z M 673.4547,69.42858 671.0001,66.85715 671.0001,72.00001 673.4547,69.42858 Z" id="rect4545" inkscape:connector-curvature="0" />
<rect style="color:#000000;fill:none;stroke:#000000;stroke-width:0.9999989;stroke-linecap:round;stroke-linejoin:round" id="rect4381" width="19.00081" height="18.99999" x="670.4994" y="65.5" />
<rect style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round" id="rect4381" width="19" height="19" x="670.4994" y="65.5" />
</g>
<g id="paint-swatch" transform="translate(395.0006,282)" inkscape:label="#fill_swatch">
<rect inkscape:label="#ccc" y="66" x="671" height="18" width="18" id="rect11473" style="color:#000000;fill:#99b6d4;fill-rule:evenodd;stroke-width:1.0000004" />
......@@ -3950,11 +3950,11 @@ http://www.inkscape.org/</dc:description>
<use transform="matrix(1,0,0,0.99644,-1.2735,13.06755)" xlink:href="#rect3568" id="use3137" x="0" y="0" width="100%" height="100%" />
</g>
<g id="paint-gradient-mesh" inkscape:label="#fill_mesh">
<rect style="fill:#99b6d4" height="9.5" width="9.5" y="347" x="1095.5" id="rect3140" />
<rect style="fill:#ffffff" height="9.5" width="9.5" y="357" x="1095.5" id="rect3142" />
<rect style="fill:#99b6d4" height="9.5" width="9.5" y="357" x="1105" id="rect3144" />
<rect style="fill:#ffffff" height="9.5" width="9.5" y="347" x="1105" id="rect3146" />
<use xlink:href="#rect4381" transform="translate(425.0351,282.0202)" id="use3148" x="0" y="0" width="100%" height="100%" />
<rect style="fill:#99b6d4" height="9.5" width="9.5" y="347.5" x="1095.5" id="rect3140" />
<rect style="fill:#ffffff" height="9.5" width="9.5" y="357" x="1095.5" id="rect3142" />
<rect style="fill:#99b6d4" height="9.5" width="9.5" y="357" x="1105" id="rect3144" />
<rect style="fill:#ffffff" height="9.5" width="9.5" y="347.5" x="1105" id="rect3146" />
<use xlink:href="#rect4381" transform="translate(425,282)" id="use3148" x="0" y="0" width="100%" height="100%" />
</g>
<g id="paint-gradient-conical" inkscape:label="#fill_conical">
<path sodipodi:rx="9.5" sodipodi:ry="9.5" style="fill:#ffffff" sodipodi:type="arc" sodipodi:start="0" sodipodi:cy="357" sodipodi:cx="1135" sodipodi:end="1.047198" d="M 1144.5,357 A 9.5,9.5 0 0 1 1139.75,365.2272 L 1135,357 Z" id="path3145" />
......@@ -3965,6 +3965,10 @@ http://www.inkscape.org/</dc:description>
<path sodipodi:rx="9.5" sodipodi:ry="9.5" style="fill:#99b6d4" sodipodi:type="arc" d="M 1139.75,348.7728 A 9.5,9.5 0 0 1 1144.5,357 L 1135,357 Z" sodipodi:cy="357" sodipodi:cx="1135" sodipodi:end="6.283185" sodipodi:start="5.235988" id="path3155" />
<circle style="fill:none;stroke:#000000" id="path3157" cx="1135" cy="357" r="9.5" />
</g>
<g id="mesh-gradient-fit" inkscape:label="#mesh-gradient-fit">
<path style="fill:#99b6d4;stroke:none" d="m 1172,350 c 6,6 -4,10 0,14 -6,6 -10,-4 -14,0 -6,-6 4,-10 0,-14 6,-6 10,4 14,0 z"/>
<rect style="fill:none;stroke:#000000;stroke-linejoin:round" id="outline" width="19" height="19" x="1155.5" y="347.5" />
</g>
<g id="dialog-filters" inkscape:label="#dialog-filters">
<path sodipodi:nodetypes="cscccccc" inkscape:connector-curvature="0" id="path7138" d="M 272.415,308.6281 C 272.509,305.3138 278.0595,305.1187 279.875,305.1077 281.8707,305.0957 287.2213,305.3694 287.3348,308.5442 L 281.3157,314.8308 281.3157,319.0217 C 279.8863,319.4867 279.7151,319.5463 278.3661,319.0217 L 278.3661,314.8308 Z" style="opacity:0.909;fill:url(#linearGradient7163);stroke:#000000;stroke-width:0.9143469;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:10" />
<ellipse id="path7140" style="opacity:0.909;fill:url(#radialGradient7218);stroke:url(#radialGradient7220);stroke-width:3.5711801;stroke-linecap:round;stroke-linejoin:round;stroke-dashoffset:10" transform="matrix(0.115021,0,0,0.1903986,253.0723,212.7017)" cx="234.355" cy="496.273" rx="60.6092" ry="14.6472" />
......
......@@ -51,6 +51,7 @@
#include "sp-mesh-row.h"
#include "sp-mesh-patch.h"
#include "sp-stop.h"
#include "display/curve.h"
// For new mesh creation
#include "preferences.h"
......@@ -2699,6 +2700,49 @@ void SPMeshNodeArray::update_handles( guint corner, std::vector< guint > /*selec
}
SPCurve * SPMeshNodeArray::outline_path() {
SPCurve *outline = new SPCurve();
outline->moveto( nodes[0][0]->p );
int ncol = nodes[0].size();
int nrow = nodes.size();
// Top
for (int i = 1; i < ncol; i += 3 ) {
outline->curveto( nodes[0][i]->p, nodes[0][i+1]->p, nodes[0][i+2]->p);
}
// Right
for (int i = 1; i < nrow; i += 3 ) {
outline->curveto( nodes[i][ncol-1]->p, nodes[i+1][ncol-1]->p, nodes[i+2][ncol-1]->p);
}
// Bottom (right to left)
for (int i = 1; i < nrow; i += 3 ) {
outline->curveto( nodes[nrow-1][ncol-i-1]->p, nodes[nrow-1][ncol-i-2]->p, nodes[nrow-1][ncol-i-3]->p);
}
// Left (bottom to top)
for (int i = 1; i < nrow; i += 3 ) {
outline->curveto( nodes[nrow-i-1][0]->p, nodes[nrow-i-2][0]->p, nodes[nrow-i-3][0]->p);
}
outline->closepath();
return outline;
}
void SPMeshNodeArray::transform(Geom::Affine const &m) {
for (int i = 0; i < nodes[0].size(); ++i) {
for (int j = 0; j < nodes.size(); ++j) {
nodes[j][i]->p *= m;
}
}
}
// Defined in gradient-chemistry.cpp
guint32 average_color(guint32 c1, guint32 c2, gdouble p);
......
......@@ -141,6 +141,7 @@ public:
};
class SPMeshGradient;
class SPCurve;
// An array of mesh nodes.
class SPMeshNodeArray {
......@@ -195,6 +196,15 @@ public:
// Update other nodes in response to a node move.
void update_handles( unsigned int corner, std::vector< unsigned int > selected_corners, Geom::Point old_p, MeshNodeOperation op );
// Return outline path (don't forget to unref() when done with curve)
SPCurve * outline_path();
// Transform array
void transform(Geom::Affine const &m);
// Find bounding box
// Geom::OptRect findBoundingBox();
void split_row( unsigned int i, unsigned int n );
void split_column( unsigned int j, unsigned int n );
void split_row( unsigned int i, double coord );
......
......@@ -52,6 +52,7 @@
#include "ui/tools/mesh-tool.h"
#include "sp-mesh-gradient.h"
#include "display/sp-ctrlcurve.h"
#include "display/curve.h"
using Inkscape::DocumentUndo;
......@@ -430,6 +431,71 @@ sp_mesh_context_corner_operation (MeshTool *rc, MeshCornerOperation operation )
}
/**
* Scale mesh to just fit into bbox of selected items.
*/
void
sp_mesh_context_fit_mesh_in_bbox (MeshTool *rc)
{
#ifdef DEBUG_MESH
std::cout << "sp_mesh_context_fit_mesh_in_bbox: entrance: Entrance"<< std::endl;
#endif
SPDesktop *desktop = SP_EVENT_CONTEXT (rc)->desktop;
Inkscape::Selection *selection = desktop->getSelection();
if (selection == NULL) {
return;
}
bool changed = false;
auto itemlist = selection->items();
for (auto i=itemlist.begin(); i!=itemlist.end(); ++i) {
SPItem *item = *i;
SPStyle *style = item->style;
if (style && (style->fill.isPaintserver())) {
SPPaintServer *server = item->style->getFillPaintServer();
if ( SP_IS_MESHGRADIENT(server) ) {
SPMeshGradient *gradient = SP_MESHGRADIENT(server);
SPCurve * outline = gradient->array.outline_path();
Geom::OptRect mesh_bbox = outline->get_pathvector().boundsExact();
outline->unref();
Geom::OptRect item_bbox = item->geometricBounds();
if ((*mesh_bbox).width() == 0) {
continue;
}
if ((*mesh_bbox).height() == 0) {
continue;
}
double scale_x = (*item_bbox).width() /(*mesh_bbox).width() ;
double scale_y = (*item_bbox).height()/(*mesh_bbox).height();
Geom::Translate t1(-(*mesh_bbox).min());
Geom::Scale scale(scale_x,scale_y);
Geom::Translate t2((*item_bbox).min());
Geom::Affine transform = t1 * scale * t2;
if (!transform.isIdentity() ) {
gradient->array.transform(transform);
gradient->array.write( gradient );
gradient->requestModified(SP_OBJECT_MODIFIED_FLAG);
changed = true;
}
}
}
}
if (changed) {
DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH,
_("Fit mesh inside bounding box."));
}
}
/**
Handles all keyboard and mouse input for meshs.
Note: node/handle events are take care of elsewhere.
......
......@@ -59,6 +59,7 @@ private:
void sp_mesh_context_select_next(ToolBase *event_context);
void sp_mesh_context_select_prev(ToolBase *event_context);
void sp_mesh_context_corner_operation(MeshTool *event_context, MeshCornerOperation operation );
void sp_mesh_context_fit_mesh_in_bbox(MeshTool *event_context);
}
}
......
......@@ -348,6 +348,14 @@ static void ms_pick_colors(void)
}
}
static void ms_fit_mesh(void)
{
MeshTool *mt = get_mesh_tool();
if (mt) {
sp_mesh_context_fit_mesh_in_bbox( mt );
}
}
static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
/**
......@@ -557,6 +565,17 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj
}
{
InkAction* act = ink_action_new( "MeshFitInBoundingBoxAction",
_("Scale mesh to bounding box:"),
_("Scale mesh to fit inside bounding box."),
INKSCAPE_ICON("mesh-gradient-fit"),
secondarySize );
g_object_set( act, "short_label", _("Fit mesh"), NULL );
g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_fit_mesh), 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
}
}
static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
......
......@@ -572,6 +572,7 @@ static gchar const * ui_descr =
" <toolitem action='MeshToggleSidesAction' />"
" <toolitem action='MeshMakeEllipticalAction' />"
" <toolitem action='MeshPickColorsAction' />"
" <toolitem action='MeshFitInBoundingBoxAction' />"
" <separator />"
" <toolitem action='MeshWarningAction' />"
" <toolitem action='MeshSmoothAction' />"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment