From d1947e768272c703674129d5c583204ff2b59251 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Wed, 13 Jul 2016 13:36:19 +0200 Subject: Second part of new SPObject children list (bzr r14954.1.19) --- src/sp-mesh-array.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 355150893..20d6d0d85 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -632,16 +632,16 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { guint max_column = 0; guint irow = 0; // Corresponds to top of patch being read in. - for ( SPObject *ro = mg->firstChild() ; ro ; ro = ro->getNext() ) { + for (auto& ro: mg->_children) { - if (SP_IS_MESHROW(ro)) { + if (SP_IS_MESHROW(&ro)) { guint icolumn = 0; // Corresponds to left of patch being read in. - for ( SPObject *po = ro->firstChild() ; po ; po = po->getNext() ) { + for (auto& po: ro._children) { - if (SP_IS_MESHPATCH(po)) { + if (SP_IS_MESHPATCH(&po)) { - SPMeshpatch *patch = SP_MESHPATCH(po); + SPMeshpatch *patch = SP_MESHPATCH(&po); // std::cout << "SPMeshNodeArray::read: row size: " << nodes.size() << std::endl; SPMeshPatchI new_patch( &nodes, irow, icolumn ); // Adds new nodes. @@ -652,15 +652,15 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { // Only 'top' side defined for first row. if( irow != 0 ) ++istop; - for ( SPObject *so = po->firstChild() ; so ; so = so->getNext() ) { - if (SP_IS_STOP(so)) { + for (auto& so: po._children) { + if (SP_IS_STOP(&so)) { if( istop > 3 ) { // std::cout << " Mesh Gradient: Too many stops: " << istop << std::endl; break; } - SPStop *stop = SP_STOP(so); + SPStop *stop = SP_STOP(&so); // Handle top of first row. if( istop == 0 && icolumn == 0 ) { @@ -848,15 +848,15 @@ void SPMeshNodeArray::write( SPMesh *mg ) { // First we must delete reprs for old mesh rows and patches. GSList *descendant_reprs = NULL; GSList *descendant_objects = NULL; - for ( SPObject *row = mg->firstChild(); row; row = row->getNext() ) { - descendant_reprs = g_slist_prepend (descendant_reprs, row->getRepr()); - descendant_objects = g_slist_prepend (descendant_objects, row ); - for ( SPObject *patch = row->firstChild(); patch; patch = patch->getNext() ) { - descendant_reprs = g_slist_prepend (descendant_reprs, patch->getRepr()); - descendant_objects = g_slist_prepend (descendant_objects, patch ); - for ( SPObject *stop = patch->firstChild(); stop; stop = stop->getNext() ) { - descendant_reprs = g_slist_prepend (descendant_reprs, stop->getRepr()); - descendant_objects = g_slist_prepend (descendant_objects, stop ); + for (auto& row: mg->_children) { + descendant_reprs = g_slist_prepend (descendant_reprs, row.getRepr()); + descendant_objects = g_slist_prepend (descendant_objects, &row); + for (auto& patch: row._children) { + descendant_reprs = g_slist_prepend (descendant_reprs, patch.getRepr()); + descendant_objects = g_slist_prepend (descendant_objects, &patch); + for (auto& stop: patch._children) { + descendant_reprs = g_slist_prepend (descendant_reprs, stop.getRepr()); + descendant_objects = g_slist_prepend (descendant_objects, &stop); } } } -- cgit v1.2.3 From 24d3f50003ca3cec6a03a7f5267cc4fe5588c69f Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 14 Jul 2016 13:17:21 +0200 Subject: Renamed children list in SPObject (bzr r14954.1.21) --- src/sp-mesh-array.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 20d6d0d85..6bd5c85d7 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -632,12 +632,12 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { guint max_column = 0; guint irow = 0; // Corresponds to top of patch being read in. - for (auto& ro: mg->_children) { + for (auto& ro: mg->children) { if (SP_IS_MESHROW(&ro)) { guint icolumn = 0; // Corresponds to left of patch being read in. - for (auto& po: ro._children) { + for (auto& po: ro.children) { if (SP_IS_MESHPATCH(&po)) { @@ -652,7 +652,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { // Only 'top' side defined for first row. if( irow != 0 ) ++istop; - for (auto& so: po._children) { + for (auto& so: po.children) { if (SP_IS_STOP(&so)) { if( istop > 3 ) { @@ -848,13 +848,13 @@ void SPMeshNodeArray::write( SPMesh *mg ) { // First we must delete reprs for old mesh rows and patches. GSList *descendant_reprs = NULL; GSList *descendant_objects = NULL; - for (auto& row: mg->_children) { + for (auto& row: mg->children) { descendant_reprs = g_slist_prepend (descendant_reprs, row.getRepr()); descendant_objects = g_slist_prepend (descendant_objects, &row); - for (auto& patch: row._children) { + for (auto& patch: row.children) { descendant_reprs = g_slist_prepend (descendant_reprs, patch.getRepr()); descendant_objects = g_slist_prepend (descendant_objects, &patch); - for (auto& stop: patch._children) { + for (auto& stop: patch.children) { descendant_reprs = g_slist_prepend (descendant_reprs, stop.getRepr()); descendant_objects = g_slist_prepend (descendant_objects, &stop); } -- cgit v1.2.3 From 4dc583f5b28383a38d6140dfa475e8d2cf8ff49e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 15 Aug 2016 22:25:15 +0200 Subject: Fix bug reported in http://www.viva64.com/en/b/0419/ (bzr r15058) --- src/sp-mesh-array.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 6bd5c85d7..0dd89ac96 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1046,11 +1046,12 @@ void SPMeshNodeArray::create( SPMesh *mg, SPItem *item, Geom::OptRect bbox ) { if( !bbox ) { // Set default size to bounding box if size not given. std::cout << "SPMeshNodeArray::create(): bbox empty" << std::endl; - Geom::OptRect bbox = item->geometricBounds(); - } - if( !bbox ) { - std::cout << "SPMeshNodeArray::create: ERROR: No bounding box!" << std::endl; - return; + bbox = item->geometricBounds(); + + if( !bbox ) { + std::cout << "SPMeshNodeArray::create: ERROR: No bounding box!" << std::endl; + return; + } } Geom::Coord const width = bbox->dimensions()[Geom::X]; -- cgit v1.2.3 From f273f14eb1b54861f1b3a7eb622cb481ee33cec9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 26 Sep 2016 13:26:47 +0200 Subject: Fix undo/redo for mesh gradients. (bzr r15135) --- src/sp-mesh-array.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 99 insertions(+), 16 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 0dd89ac96..41a95a41a 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -574,6 +574,59 @@ void SPMeshPatchI::setOpacity( guint i, gdouble opacity ) { }; +/** + Return stop pointer for corner of patch. +*/ +SPStop* SPMeshPatchI::getStopPtr( guint i ) { + + assert( i < 4 ); + + SPStop* stop = nullptr; + switch ( i ) { + case 0: + stop = (*nodes)[ row ][ col ]->stop; + break; + case 1: + stop = (*nodes)[ row ][ col+3 ]->stop; + break; + case 2: + stop = (*nodes)[ row+3 ][ col+3 ]->stop; + break; + case 3: + stop = (*nodes)[ row+3 ][ col ]->stop; + break; + } + + return stop; +}; + + +/** + Set stop pointer for corner of patch. +*/ +void SPMeshPatchI::setStopPtr( guint i, SPStop* stop ) { + + assert( i < 4 ); + + switch ( i ) { + case 0: + (*nodes)[ row ][ col ]->stop = stop; + break; + case 1: + (*nodes)[ row ][ col+3 ]->stop = stop; + break; + case 2: + (*nodes)[ row+3 ][ col+3 ]->stop = stop; + break; + case 3: + (*nodes)[ row+3 ][ col ]->stop = stop; + break; + + } + +}; + + SPMeshNodeArray::SPMeshNodeArray( SPMesh *mg ) { read( mg ); @@ -586,7 +639,7 @@ SPMeshNodeArray::SPMeshNodeArray( const SPMeshNodeArray& rhs ) { built = false; mg = NULL; - drag_valid = false; + draggers_valid = false; nodes = rhs.nodes; // This only copies the pointers but it does size the vector of vectors. @@ -607,7 +660,7 @@ SPMeshNodeArray& SPMeshNodeArray::operator=( const SPMeshNodeArray& rhs ) { built = false; mg = NULL; - drag_valid = false; + draggers_valid = false; nodes = rhs.nodes; // This only copies the pointers but it does size the vector of vectors. @@ -620,12 +673,34 @@ SPMeshNodeArray& SPMeshNodeArray::operator=( const SPMeshNodeArray& rhs ) { return *this; }; - -void SPMeshNodeArray::read( SPMesh *mg_in ) { +// Fill array with data from mesh objects. +// Returns true of array's dimensions unchanged. +bool SPMeshNodeArray::read( SPMesh *mg_in ) { mg = mg_in; - clear(); + // Count rows and columns, if unchanged reuse array to keep draggers valid. + unsigned cols = 0; + unsigned rows = 0; + for (auto& ro: mg->children) { + if (SP_IS_MESHROW(&ro)) { + ++rows; + if (rows == 1 ) { + for (auto& po: ro.children) { + if (SP_IS_MESHPATCH(&po)) { + ++cols; + } + } + } + } + } + bool same_size = true; + if (cols != patch_columns() || rows != patch_rows() ) { + // Draggers will be invalidated. + same_size = false; + clear(); + draggers_valid = false; + } Geom::Point current_p( mg->x.computed, mg->y.computed ); // std::cout << "SPMeshNodeArray::read: p: " << current_p << std::endl; @@ -701,7 +776,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { dp = Geom::Point( x, y ); new_patch.setPoint( istop, 3, current_p + dp ); } else { - std::cout << "Failed to read l" << std::endl; + std::cerr << "Failed to read l" << std::endl; } } // To facilitate some side operations, set handles to 1/3 and @@ -723,7 +798,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { p = Geom::Point( x, y ); new_patch.setPoint( istop, 3, p ); } else { - std::cout << "Failed to read L" << std::endl; + std::cerr << "Failed to read L" << std::endl; } } // To facilitate some side operations, set handles to 1/3 and @@ -743,7 +818,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { p += current_p; new_patch.setPoint( istop, i, p ); } else { - std::cout << "Failed to read c: " << i << std::endl; + std::cerr << "Failed to read c: " << i << std::endl; } } break; @@ -756,13 +831,13 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { p = Geom::Point( x, y ); new_patch.setPoint( istop, i, p ); } else { - std::cout << "Failed to read C: " << i << std::endl; + std::cerr << "Failed to read C: " << i << std::endl; } } break; default: // should not reach - std::cout << "Path Error: unhandled path type: " << path_type << std::endl; + std::cerr << "Path Error: unhandled path type: " << path_type << std::endl; } current_p = new_patch.getPoint( istop, 3 ); @@ -774,6 +849,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { double opacity = stop->opacity; new_patch.setColor( istop, color ); new_patch.setOpacity( istop, opacity ); + new_patch.setStopPtr( istop, stop ); } } @@ -797,7 +873,7 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { if( !os.fail() ) { new_patch.setTensorPoint( i, new_patch.getPoint( i, 0 ) + Geom::Point( x, y ) ); } else { - std::cout << "Failed to read p: " << i << std::endl; + std::cerr << "Failed to read p: " << i << std::endl; break; } } @@ -830,9 +906,9 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { // std::cout << "SPMeshNodeArray::Read: result:" << std::endl; // print(); - drag_valid = false; built = true; + return same_size; }; /** @@ -967,10 +1043,10 @@ void SPMeshNodeArray::write( SPMesh *mg ) { break; case 'z': case 'Z': - std::cout << "sp_mesh_repr_write: bad path type" << path_type << std::endl; + std::cout << "SPMeshNodeArray::write(): bad path type" << path_type << std::endl; break; default: - std::cout << "sp_mesh_repr_write: unhandled path type" << path_type << std::endl; + std::cout << "SPMeshNodeArray::write(): unhandled path type" << path_type << std::endl; } stop->setAttribute("path", is.str().c_str()); // std::cout << "SPMeshNodeArray::write: path: " << is.str().c_str() << std::endl; @@ -1415,6 +1491,7 @@ void SPMeshNodeArray::print() { << " Node edge: " << nodes[i][j]->node_edge << " Set: " << nodes[i][j]->set << " Path type: " << nodes[i][j]->path_type + << " Stop: " << nodes[i][j]->stop << std::endl; } else { std::cout << "Error: missing mesh node." << std::endl; @@ -1776,7 +1853,9 @@ guint SPMeshNodeArray::patch_rows() { Number of patch columns. */ guint SPMeshNodeArray::patch_columns() { - + if (nodes.empty()) { + return 0; + } return nodes[0].size()/3; } @@ -2345,7 +2424,11 @@ guint SPMeshNodeArray::color_pick( std::vector icorners, SPItem* item ) { */ void SPMeshNodeArray::update_handles( guint corner, std::vector< guint > /*selected*/, Geom::Point p_old, MeshNodeOperation /*op*/ ) { - assert( drag_valid ); + if (!draggers_valid) { + std::cerr << "SPMeshNodeArray::update_handles: Draggers not valid!" << std::endl; + return; + } + // assert( draggers_valid ); // std::cout << "SPMeshNodeArray::update_handles: " // << " corner: " << corner -- cgit v1.2.3 From f9ec83dbb254701f39d3b7a30c0bacb5eaae9ee9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 27 Sep 2016 10:51:26 +0200 Subject: Rename to per SVG 2 CR specificiation. Note: has been repurposed to be a special shape that tightly wraps a mesh gradient. (bzr r15137) --- src/sp-mesh-array.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 41a95a41a..c47c338de 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -46,7 +46,7 @@ #include "document.h" #include "sp-root.h" -#include "sp-mesh.h" +#include "sp-mesh-gradient.h" #include "sp-mesh-array.h" #include "sp-mesh-row.h" #include "sp-mesh-patch.h" @@ -627,7 +627,7 @@ void SPMeshPatchI::setStopPtr( guint i, SPStop* stop ) { }; -SPMeshNodeArray::SPMeshNodeArray( SPMesh *mg ) { +SPMeshNodeArray::SPMeshNodeArray( SPMeshGradient *mg ) { read( mg ); @@ -675,7 +675,7 @@ SPMeshNodeArray& SPMeshNodeArray::operator=( const SPMeshNodeArray& rhs ) { // Fill array with data from mesh objects. // Returns true of array's dimensions unchanged. -bool SPMeshNodeArray::read( SPMesh *mg_in ) { +bool SPMeshNodeArray::read( SPMeshGradient *mg_in ) { mg = mg_in; @@ -914,7 +914,7 @@ bool SPMeshNodeArray::read( SPMesh *mg_in ) { /** Write repr using our array. */ -void SPMeshNodeArray::write( SPMesh *mg ) { +void SPMeshNodeArray::write( SPMeshGradient *mg ) { // std::cout << "SPMeshNodeArray::write: entrance:" << std::endl; // print(); @@ -1115,7 +1115,7 @@ static SPColor default_color( SPItem *item ) { /** Create a default mesh. */ -void SPMeshNodeArray::create( SPMesh *mg, SPItem *item, Geom::OptRect bbox ) { +void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bbox ) { // std::cout << "SPMeshNodeArray::create: Entrance" << std::endl; -- cgit v1.2.3 From ce1a41cdce443963665ad56e2a73cbe63e5cdf5f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 12 Oct 2016 13:10:37 +0200 Subject: Render mesh gradients that reference other mesh gradients. (bzr r15163) --- src/sp-mesh-array.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index c47c338de..0ec915eea 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -678,11 +678,17 @@ SPMeshNodeArray& SPMeshNodeArray::operator=( const SPMeshNodeArray& rhs ) { bool SPMeshNodeArray::read( SPMeshGradient *mg_in ) { mg = mg_in; + SPMeshGradient* mg_array = dynamic_cast(mg->getArray()); + if (!mg_array) { + std::cerr << "SPMeshNodeArray::read: No mesh array!" << std::endl; + return false; + } + // std::cout << "SPMeshNodeArray::read: " << mg_in << " array: " << mg_array << std::endl; // Count rows and columns, if unchanged reuse array to keep draggers valid. unsigned cols = 0; unsigned rows = 0; - for (auto& ro: mg->children) { + for (auto& ro: mg_array->children) { if (SP_IS_MESHROW(&ro)) { ++rows; if (rows == 1 ) { @@ -707,7 +713,7 @@ bool SPMeshNodeArray::read( SPMeshGradient *mg_in ) { guint max_column = 0; guint irow = 0; // Corresponds to top of patch being read in. - for (auto& ro: mg->children) { + for (auto& ro: mg_array->children) { if (SP_IS_MESHROW(&ro)) { @@ -921,10 +927,16 @@ void SPMeshNodeArray::write( SPMeshGradient *mg ) { using Geom::X; using Geom::Y; + SPMeshGradient* mg_array = dynamic_cast(mg->getArray()); + if (!mg_array) { + std::cerr << "SPMeshNodeArray::write: missing patches!" << std::endl; + mg_array = mg; + } + // First we must delete reprs for old mesh rows and patches. GSList *descendant_reprs = NULL; GSList *descendant_objects = NULL; - for (auto& row: mg->children) { + for (auto& row: mg_array->children) { descendant_reprs = g_slist_prepend (descendant_reprs, row.getRepr()); descendant_objects = g_slist_prepend (descendant_objects, &row); for (auto& patch: row.children) { @@ -950,8 +962,9 @@ void SPMeshNodeArray::write( SPMeshGradient *mg ) { // Now we build new reprs Inkscape::XML::Node *mesh = mg->getRepr(); + Inkscape::XML::Node *mesh_array = mg_array->getRepr(); - SPMeshNodeArray* array = &(mg->array); + SPMeshNodeArray* array = &(mg_array->array); SPMeshPatchI patch0( &(array->nodes), 0, 0 ); Geom::Point current_p = patch0.getPoint( 0, 0 ); // Side 0, point 0 @@ -966,7 +979,7 @@ void SPMeshNodeArray::write( SPMeshGradient *mg ) { // Write row Inkscape::XML::Node *row = xml_doc->createElement("svg:meshrow"); - mesh->appendChild( row ); // No attributes + mesh_array->appendChild( row ); // No attributes guint columns = array->patch_columns(); for( guint j = 0; j < columns; ++j ) { -- cgit v1.2.3 From 8855dcd0b5455ed56c51462232e325588e7b74a6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 14 Oct 2016 10:30:24 +0200 Subject: Ensure newly created meshes have correct 'gradientUnits'. (bzr r15167) --- src/sp-mesh-array.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 0ec915eea..2e78adccc 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1159,6 +1159,10 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb // return if we've already constructed the mesh. if( !nodes.empty() ) return; + // Set 'gradientUnits'. Our calculations assume "userSpaceOnUse". + Inkscape::XML::Node *repr = mg->getRepr(); + repr->setAttribute("gradientUnits", "userSpaceOnUse"); + // Get default color SPColor color = default_color( item ); @@ -1205,7 +1209,6 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb // std::cout << " start: " << start << " end: " << end << std::endl; // IS THIS NECESSARY? - Inkscape::XML::Node *repr = mg->getRepr(); sp_repr_set_svg_double( repr, "x", center[Geom::X] + rx * cos(start) ); sp_repr_set_svg_double( repr, "y", center[Geom::Y] + ry * sin(start) ); @@ -1275,7 +1278,6 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb gdouble s = -3.0/2.0 * M_PI_2; - Inkscape::XML::Node *repr = mg->getRepr(); sp_repr_set_svg_double( repr, "x", center[Geom::X] + rx * cos(s) ); sp_repr_set_svg_double( repr, "y", center[Geom::Y] + ry * sin(s) ); @@ -1328,7 +1330,6 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb // std::cout << "We've got ourselves an star! Sides: " << sides << std::endl; Geom::Point p0 = sp_star_get_xy( star, SP_STAR_POINT_KNOT1, 0 ); - Inkscape::XML::Node *repr = mg->getRepr(); sp_repr_set_svg_double( repr, "x", p0[Geom::X] ); sp_repr_set_svg_double( repr, "y", p0[Geom::Y] ); @@ -1398,7 +1399,6 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb // Generic - Inkscape::XML::Node *repr = mg->getRepr(); sp_repr_set_svg_double(repr, "x", bbox->min()[Geom::X]); sp_repr_set_svg_double(repr, "y", bbox->min()[Geom::Y]); -- cgit v1.2.3 From 41d95eee3504da351fbef3249ff23f7af11720bd Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 14 Oct 2016 11:11:06 +0200 Subject: Code cleanup: simplify initial mesh color calculation. (bzr r15169) --- src/sp-mesh-array.cpp | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 2e78adccc..87329b3f2 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -929,7 +929,7 @@ void SPMeshNodeArray::write( SPMeshGradient *mg ) { SPMeshGradient* mg_array = dynamic_cast(mg->getArray()); if (!mg_array) { - std::cerr << "SPMeshNodeArray::write: missing patches!" << std::endl; + // std::cerr << "SPMeshNodeArray::write: missing patches!" << std::endl; mg_array = mg; } @@ -1084,42 +1084,27 @@ void SPMeshNodeArray::write( SPMeshGradient *mg ) { } /** - Find default color based on color of first stop in "vector" gradient. - This should be rewritten if dependence on "vector" is removed. -*/ + * Find default color based on colors in existing fill. + */ static SPColor default_color( SPItem *item ) { - // Set initial color to the color of the object before adding the mesh. - // This is a bit tricky as at the moment, a "vector" gradient is created - // before reaching here, replacing the original solid color. But the first - // stop will be that of the original object color. SPColor color( 0.5, 0.0, 0.5 ); + if ( item->style ) { - SPStyle const &style = *(item->style); - SPIPaint const &paint = ( style.fill ); // Could pick between style.fill/style.stroke + SPIPaint const &paint = ( item->style->fill ); // Could pick between style.fill/style.stroke if ( paint.isColor() ) { color = paint.value.color; } else if ( paint.isPaintserver() ) { - SPObject const *server = style.getFillPaintServer(); + SPObject const *server = item->style->getFillPaintServer(); if ( SP_IS_GRADIENT(server) ) { - SPGradient *vector = SP_GRADIENT( server )->getVector(); - SPStop *firstStop = (vector) ? - vector->getFirstStop() : SP_GRADIENT( server )->getFirstStop(); + SPStop *firstStop = SP_GRADIENT(server)->getVector()->getFirstStop(); if ( firstStop ) { - if (firstStop->currentColor) { - Glib::ustring str = firstStop->getStyleProperty("color", NULL); - if( !str.empty() ) { - guint32 rgb = sp_svg_read_color( str.c_str(), 0 ); - color = SPColor( rgb ); - } - } else { - color = firstStop->specified_color; - } + color = firstStop->getEffectiveColor(); } } } } else { - std::cout << " SPMeshNodeArray: No style" << std::endl; + std::cerr << " SPMeshNodeArray: default_color(): No style" << std::endl; } return color; -- cgit v1.2.3 From 32442aec84cc13f0a22fa1f07f3de701c6938e5d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 14 Oct 2016 22:01:57 +0200 Subject: Implement copying of objects with mesh gradients. (bzr r15171) --- src/sp-mesh-array.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 87329b3f2..042800fbf 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1096,7 +1096,7 @@ static SPColor default_color( SPItem *item ) { color = paint.value.color; } else if ( paint.isPaintserver() ) { SPObject const *server = item->style->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { + if ( SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector() ) { SPStop *firstStop = SP_GRADIENT(server)->getVector()->getFirstStop(); if ( firstStop ) { color = firstStop->getEffectiveColor(); -- cgit v1.2.3 From 619f8b5d9173f2bcc9d9aefccee832d686724e79 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 17 Oct 2016 15:04:09 +0200 Subject: Add option to scale mesh to fit in bounding box. (bzr r15173) --- src/sp-mesh-array.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 042800fbf..208dac2bc 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -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); -- cgit v1.2.3 From 430533b9a259eb3dac44755306dfb0fddb34951d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 8 Nov 2016 15:05:30 +0100 Subject: Improve mesh handling in Fill and Stroke dialog. Create new meshes with alternating color/white pattern (makes it more obvious a mesh has been created). (bzr r15229) --- src/sp-mesh-array.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 11 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 208dac2bc..107359c6c 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1057,10 +1057,10 @@ void SPMeshNodeArray::write( SPMeshGradient *mg ) { break; case 'z': case 'Z': - std::cout << "SPMeshNodeArray::write(): bad path type" << path_type << std::endl; + std::cerr << "SPMeshNodeArray::write(): bad path type" << path_type << std::endl; break; default: - std::cout << "SPMeshNodeArray::write(): unhandled path type" << path_type << std::endl; + std::cerr << "SPMeshNodeArray::write(): unhandled path type" << path_type << std::endl; } stop->setAttribute("path", is.str().c_str()); // std::cout << "SPMeshNodeArray::write: path: " << is.str().c_str() << std::endl; @@ -1120,11 +1120,11 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb if( !bbox ) { // Set default size to bounding box if size not given. - std::cout << "SPMeshNodeArray::create(): bbox empty" << std::endl; + std::cerr << "SPMeshNodeArray::create(): bbox empty" << std::endl; bbox = item->geometricBounds(); if( !bbox ) { - std::cout << "SPMeshNodeArray::create: ERROR: No bounding box!" << std::endl; + std::cerr << "SPMeshNodeArray::create: ERROR: No bounding box!" << std::endl; return; } } @@ -1151,7 +1151,14 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb // Get default color SPColor color = default_color( item ); - + + // Set some corners to white so we can see the mesh. + SPColor white( 1.0, 1.0, 1.0 ); + if (color == white) { + // If default color is white, set other color to black. + white = SPColor( 0.0, 0.0, 0.0 ); + } + // Get preferences Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint prows = prefs->getInt("/tools/mesh/mesh_rows", 1); @@ -1190,6 +1197,9 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb ry = arc->ry.computed; start = arc->start; end = arc->end; + if( end == start ) { + end += 2.0 * M_PI; + } } // std::cout << " start: " << start << " end: " << end << std::endl; @@ -1236,7 +1246,7 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb for( guint k = 0; k < 4; ++k ) { patch.setPathType( k, 'l' ); - patch.setColor( k, color ); + patch.setColor( k, (i+k)%2 ? color : white ); patch.setOpacity( k, 1.0 ); } patch.setPathType( 0, 'c' ); @@ -1293,7 +1303,7 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb patch.setPathType( i, 'c' ); - patch.setColor( i, color ); + patch.setColor( i, i%2 ? color : white ); patch.setOpacity( i, 1.0 ); } @@ -1334,7 +1344,7 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb for( guint s = 0; s < 4; ++s ) { patch.setPathType( s, 'l' ); - patch.setColor( s, color ); + patch.setColor( s, (i+s)%2 ? color : white ); patch.setOpacity( s, 1.0 ); } @@ -1362,10 +1372,10 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb for( guint s = 0; s < 4; ++s ) { patch0.setPathType( s, 'l' ); - patch0.setColor( s, color ); + patch0.setColor( s, s%2 ? color : white ); patch0.setOpacity( s, 1.0 ); patch1.setPathType( s, 'l' ); - patch1.setColor( s, color ); + patch1.setColor( s, s%2 ? white : color ); patch1.setOpacity( s, 1.0 ); } @@ -1415,7 +1425,7 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb // Corner node->node_type = MG_NODE_TYPE_CORNER; node->set = true; - node->color = color; + node->color = (i+j)%2 ? color : white; node->opacity = 1.0; } else { @@ -2704,6 +2714,11 @@ SPCurve * SPMeshNodeArray::outline_path() { SPCurve *outline = new SPCurve(); + if (nodes.empty() ) { + std::cerr << "SPMeshNodeArray::outline_path: empty array!" << std::endl; + return outline; + } + outline->moveto( nodes[0][0]->p ); int ncol = nodes[0].size(); @@ -2743,6 +2758,34 @@ void SPMeshNodeArray::transform(Geom::Affine const &m) { } } +// Transform mesh to fill box. Return true if mesh transformed. +bool SPMeshNodeArray::fill_box(Geom::OptRect &box) { + + SPCurve *outline = outline_path(); + Geom::OptRect mesh_bbox = outline->get_pathvector().boundsExact(); + outline->unref(); + + if ((*mesh_bbox).width() == 0 || (*mesh_bbox).height() == 0) { + return false; + } + + double scale_x = (*box).width() /(*mesh_bbox).width() ; + double scale_y = (*box).height()/(*mesh_bbox).height(); + + Geom::Translate t1(-(*mesh_bbox).min()); + Geom::Scale scale(scale_x,scale_y); + Geom::Translate t2((*box).min()); + Geom::Affine trans = t1 * scale * t2; + if (!trans.isIdentity() ) { + transform(trans); + write( mg ); + mg->requestModified(SP_OBJECT_MODIFIED_FLAG); + return true; + } + + return false; +} + // Defined in gradient-chemistry.cpp guint32 average_color(guint32 c1, guint32 c2, gdouble p); -- cgit v1.2.3 From 2189e04b47b098cb2f6937fe7c66f734750406d9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 12 Nov 2016 14:14:55 +0100 Subject: Fit to bounding box: correct transform when mesh has a non-identity gradient transform. (bzr r15243) --- src/sp-mesh-array.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 107359c6c..565551fd4 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -2761,6 +2761,15 @@ void SPMeshNodeArray::transform(Geom::Affine const &m) { // Transform mesh to fill box. Return true if mesh transformed. bool SPMeshNodeArray::fill_box(Geom::OptRect &box) { + // If gradientTransfor is set (as happens when an object is transformed + // with the "optimized" preferences set true), we need to remove it. + if (mg->gradientTransform_set) { + Geom::Affine gt = mg->gradientTransform; + transform( gt ); + mg->gradientTransform_set = false; + mg->gradientTransform.setIdentity(); + } + SPCurve *outline = outline_path(); Geom::OptRect mesh_bbox = outline->get_pathvector().boundsExact(); outline->unref(); -- cgit v1.2.3 From 09d3ef953448a73c20dc1a70c2f96e0ac5019f45 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 16 Nov 2016 16:22:39 +0100 Subject: Split selected rows/columns in half using Insert key. (bzr r15251) --- src/sp-mesh-array.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 565551fd4..2340b1936 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -38,6 +38,7 @@ */ #include +#include // For color picking #include "display/drawing.h" @@ -2424,6 +2425,68 @@ guint SPMeshNodeArray::color_pick( std::vector icorners, SPItem* item ) { return picked; } +/** + Splits selected rows and/or columns in half (according to the path 't' parameter). + Input is a list of selected corner draggable indices. +*/ +guint SPMeshNodeArray::insert( std::vector corners ) { + + guint inserted = 0; + + if( corners.size() < 2 ) return 0; + + std::set columns; + std::set rows; + + for( guint i = 0; i < corners.size()-1; ++i ) { + for( guint j = i+1; j < corners.size(); ++j ) { + + // This works as all corners have indices and they + // are numbered in order by row and column (and + // the node array is rectangular). + + guint c1 = corners[i]; + guint c2 = corners[j]; + if (c2 < c1) { + c1 = corners[j]; + c2 = corners[i]; + } + + // Number of corners in a row of patches. + guint ncorners = patch_columns() + 1; + + guint crow1 = c1 / ncorners; + guint crow2 = c2 / ncorners; + guint ccol1 = c1 % ncorners; + guint ccol2 = c2 % ncorners; + + // Check for horizontal neighbors + if ( crow1 == crow2 && (ccol2 - ccol1) == 1 ) { + columns.insert( ccol1 ); + } + + // Check for vertical neighbors + if ( ccol1 == ccol2 && (crow2 - crow1) == 1 ) { + rows.insert( crow1 ); + } + } + } + + // Iterate backwards so column/row numbers are not invalidated. + std::set::reverse_iterator rit; + for (rit=columns.rbegin(); rit != columns.rend(); ++rit) { + split_column( *rit, 0.5); + ++inserted; + } + for (rit=rows.rbegin(); rit != rows.rend(); ++rit) { + split_row( *rit, 0.5); + ++inserted; + } + + if( inserted > 0 ) built = false; + return inserted; +} + /** Moves handles in response to a corner node move. p_old: orignal position of moved corner node. -- cgit v1.2.3 From a5fcbbd7a6bcc7fb65658ee42f85f41acca02ee5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 17 Nov 2016 13:13:09 +0100 Subject: Fix path outline function for meshes with nrow != ncolumn. (bzr r15255) --- src/sp-mesh-array.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 2340b1936..47480f10c 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -2798,7 +2798,7 @@ SPCurve * SPMeshNodeArray::outline_path() { } // Bottom (right to left) - for (int i = 1; i < nrow; i += 3 ) { + for (int i = 1; i < ncol; 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); } -- cgit v1.2.3 From ef222b02922e656eca7ef8660c98cc75e30f62d2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 30 Nov 2016 15:56:44 +0100 Subject: Fix bug with mesh handle update when corner moved via keys. (bzr r15288) --- src/sp-mesh-array.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 47480f10c..e4877d5c9 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -2493,6 +2493,7 @@ guint SPMeshNodeArray::insert( std::vector corners ) { corner: the corner node moved (draggable index, i.e. point_i). selected: list of all corners selected (draggable indices). op: how other corners should be moved. + Corner node must already have been moved! */ void SPMeshNodeArray::update_handles( guint corner, std::vector< guint > /*selected*/, Geom::Point p_old, MeshNodeOperation /*op*/ ) { -- cgit v1.2.3 From fe7a8ae21e4cf044a86aef99f9d52eea3e3f89f5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 6 Dec 2016 11:15:36 +0100 Subject: Fix memory leak (incomplete clear). (bzr r15300) --- src/sp-mesh-array.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index e4877d5c9..f2604976e 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1478,11 +1478,8 @@ void SPMeshNodeArray::clear() { delete nodes[i][j]; } } - for( guint i = 0; i < nodes.size(); ++i ) { - nodes[i].clear(); - } - nodes.clear(); } + nodes.clear(); }; -- cgit v1.2.3 From 2a438462e967a565eac4cef247e7d46a5e0ad806 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 8 Dec 2016 10:28:21 +0100 Subject: Correct error messages. (bzr r15311) --- src/sp-mesh-array.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index f2604976e..b522d577b 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -2026,7 +2026,7 @@ guint SPMeshNodeArray::side_arc( std::vector corners ) { { case 'L': case 'l': - std::cout << "SPMeshNodeArray::arc_sides: Can't convert straight lines to arcs."; + std::cerr << "SPMeshNodeArray::side_arc: Can't convert straight lines to arcs." << std::endl; break; case 'C': @@ -2052,15 +2052,15 @@ guint SPMeshNodeArray::side_arc( std::vector corners ) { ++arced; } else { - std::cout << "SPMeshNodeArray::arc_sides: No crossing, can't turn into arc." << std::endl; + std::cerr << "SPMeshNodeArray::side_arc: No crossing, can't turn into arc." << std::endl; } } else { - std::cout << "SPMeshNodeArray::arc_sides: Handles parallel, can't turn into arc." << std::endl; + std::cerr << "SPMeshNodeArray::side_arc: Handles parallel, can't turn into arc." << std::endl; } break; } default: - std::cout << "SPMeshNodeArray::arc_sides: Invalid path type: " << n[1]->path_type << std::endl; + std::cerr << "SPMeshNodeArray::side_arc: Invalid path type: " << n[1]->path_type << std::endl; } } } -- cgit v1.2.3 From 93bfb768916d2ff387ed5f38c02f1da802896d99 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 Dec 2016 19:54:50 +0100 Subject: Fix bug where conical gradient drawn in wrong arc. (bzr r15329) --- src/sp-mesh-array.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index b522d577b..f192d0e44 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1198,7 +1198,7 @@ void SPMeshNodeArray::create( SPMeshGradient *mg, SPItem *item, Geom::OptRect bb ry = arc->ry.computed; start = arc->start; end = arc->end; - if( end == start ) { + if( end <= start ) { end += 2.0 * M_PI; } } -- cgit v1.2.3 From 671e4a250885ec9f5921c621ca32f3c7276545b7 Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Wed, 4 Jan 2017 21:51:15 +0200 Subject: Remove an unused local .cpp enum. (bzr r15369.1.12) --- src/sp-mesh-array.cpp | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/sp-mesh-array.cpp') diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index f192d0e44..c89cfcc6f 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -1525,18 +1525,6 @@ double hermite( const double p0, const double p1, const double m0, const double class SPMeshSmoothCorner { - enum { - AMP, - DX_LEFT, - DX_RIGHT, - DY_TOP, - DY_BOTTOM, - DXY_LT, - DXY_RT, - DXY_LB, - DXY_RB - }; - public: SPMeshSmoothCorner() { for( unsigned i = 0; i < 3; ++i ) { -- cgit v1.2.3