effect.cpp revision 4afe3fc6b9c122bc5c02b27aea3845ba41384d2a
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * Released under GNU GPL, read the file 'COPYING' for more information
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm// include effects:
e54ce05030e6aab675331e18f46f029f55ed1bf0cilix// end of includes
72b7b31db250f20b90730d2888e6a554b434a407johanengelenconst Util::EnumData<EffectType> LPETypeData[] = {
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm // {constant defined in effect.h, N_("name of your effect"), "name of your effect in SVG"}
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {ANGLE_BISECTOR, N_("Angle bisector"), "angle_bisector"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {CIRCLE_WITH_RADIUS, N_("Circle (center+radius)"), "circle_with_radius"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {CIRCLE_3PTS, N_("Circle through 3 points"), "circle_3pts"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {CONSTRUCT_GRID, N_("Construct grid"), "construct_grid"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {DOEFFECTSTACK_TEST, N_("doEffect stack test"), "doeffectstacktest"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {ENVELOPE, N_("Envelope Deformation"), "envelope"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {FREEHAND_SHAPE, N_("Freehand Shape"), "freehand_shape"}, // this is actually a special type of PatternAlongPath, used to paste shapes in pen/pencil tool
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {INTERPOLATE, N_("Interpolate Sub-Paths"), "interpolate"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {LATTICE, N_("Lattice Deformation"), "lattice"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"},
9de5f3bfa8e35ad5e6adcd6eaad4d0d49e7043a3johanengelen {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"},
72b7b31db250f20b90730d2888e6a554b434a407johanengelenconst Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrmEffect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPEPatternAlongPath(lpeobj) );
29f9623ba77fc735b89765ae3a13e0c06aabafcecilix neweffect = static_cast<Effect*> ( new LPEFreehandShape(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPEBendPath(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPESketch(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPEVonKoch(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPEKnot(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPEdoEffectStackTest(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPEGears(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPECurveStitch(lpeobj) );
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen neweffect = static_cast<Effect*> ( new LPELattice(lpeobj) );
0563fd55cbad59e8a878e6d4cbbdd8e47f74488djohanengelen neweffect = static_cast<Effect*> ( new LPEEnvelope(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPECircleWithRadius(lpeobj) );
92fe3142613d000eff89db8a983b3b18b14eee79johanengelen neweffect = static_cast<Effect*> ( new LPEPerspectivePath(lpeobj) );
c169f6cddd2da06cfb761339f445bbd8866f72a8buliabyak neweffect = static_cast<Effect*> ( new LPESpiro(lpeobj) );
6f4a90e526af850ffc36064f58f09c190f3b633fjohanengelen neweffect = static_cast<Effect*> ( new LPEConstructGrid(lpeobj) );
f4db63be4e929f4706410914295deccaceea19cdcilix neweffect = static_cast<Effect*> ( new LPEPerpBisector(lpeobj) );
ab99111a42436818e6902e044c8f3af2b724263bcilix neweffect = static_cast<Effect*> ( new LPETangentToCurve(lpeobj) );
76db360f5f052775326e6d406b9e1e9e2966e11acilix neweffect = static_cast<Effect*> ( new LPEMirrorSymmetry(lpeobj) );
3d0482af18ffb591c1d8ddecf516629e1bcd2ae4cilix neweffect = static_cast<Effect*> ( new LPECircle3Pts(lpeobj) );
64aee804a6a47424f7994e60558351b8cf2ea4dbcilix neweffect = static_cast<Effect*> ( new LPEAngleBisector(lpeobj) );
b320a8d186114a5122ddc3afbe95110eb6cb10cecilix neweffect = static_cast<Effect*> ( new LPEParallel(lpeobj) );
044d712d4d03f8354962d54e47cfac2346a69ccccilix neweffect = static_cast<Effect*> ( new LPECopyRotate(lpeobj) );
61cfd957cd023c4f432ea0c7307784a56bf978e9cilix neweffect = static_cast<Effect*> ( new LPEOffset(lpeobj) );
2f5c0701b333a695eedb1680beb1adf95c0723dacilix neweffect = static_cast<Effect*> ( new LPERuler(lpeobj) );
add2ffae3c4686b50d888775bbdf083a4726a210johanengelen neweffect = static_cast<Effect*> ( new LPEBoolops(lpeobj) );
0a75b58e47d3de42550c4f7960e253ea3befc09ajohanengelen neweffect = static_cast<Effect*> ( new LPEInterpolate(lpeobj) );
4afe3fc6b9c122bc5c02b27aea3845ba41384d2acilix neweffect = static_cast<Effect*> ( new LPETextLabel(lpeobj) );
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr);
6656f193fdace606d1b162d6dea0223bc295f0a6cilixEffect::createAndApply(const char* name, SPDocument *doc, SPItem *item)
6656f193fdace606d1b162d6dea0223bc295f0a6cilix // Path effect definition
6656f193fdace606d1b162d6dea0223bc295f0a6cilix Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
6656f193fdace606d1b162d6dea0223bc295f0a6cilix Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect");
6656f193fdace606d1b162d6dea0223bc295f0a6cilix SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc))->addChild(repr, NULL); // adds to <defs> and assigns the 'id' attribute
6656f193fdace606d1b162d6dea0223bc295f0a6cilix sp_lpe_item_add_path_effect(SP_LPE_ITEM(item), href, true);
6656f193fdace606d1b162d6dea0223bc295f0a6cilixEffect::createAndApply(EffectType type, SPDocument *doc, SPItem *item)
6656f193fdace606d1b162d6dea0223bc295f0a6cilix createAndApply(LPETypeConverter.get_key(type).c_str(), doc, item);
71146abe8aba032d73788a625fee5769a581bd3ccilix is_visible(_("Is visible?"), _("If unchecked, the effect remains applied to the object but is temporarily disabled on canvas"), "is_visible", &wr, this, true),
9ce14357bb94b9dd92ad40bf43ef435a257b355acilix provides_own_flash_paths(true) // is automatically set to false if providesOwnFlashPaths() is not overridden
71146abe8aba032d73788a625fee5769a581bd3ccilix registerParameter( dynamic_cast<Parameter *>(&is_visible) );
72b7b31db250f20b90730d2888e6a554b434a407johanengelen if (lpeobj->effecttype_set && LPETypeConverter.is_valid_id(lpeobj->effecttype) )
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm return Glib::ustring( _(LPETypeConverter.get_label(lpeobj->effecttype).c_str()) );
77a4a003111bd5cfb771d4849801c898aeb889b0cilix * Is performed a single time when the effect is freshly applied to a path
77a4a003111bd5cfb771d4849801c898aeb889b0cilix * Is performed each time before the effect is updated.
23d859f2ce09c04ed802cb4912cc9c50f512f0a2bgk //Do nothing for simple effects
147c8e03bb214f85cd5906ddc6413c4293c4baa9cilix * Effects can have a parameter path set before they are applied by accepting a nonzero number of
147c8e03bb214f85cd5906ddc6413c4293c4baa9cilix * mouse clicks. This method activates the pen context, which waits for the specified number of
147c8e03bb214f85cd5906ddc6413c4293c4baa9cilix * clicks. Override Effect::acceptsNumParams() to return the number of expected mouse clicks.
77a4a003111bd5cfb771d4849801c898aeb889b0cilix // switch to pen context
77a4a003111bd5cfb771d4849801c898aeb889b0cilix SPDesktop *desktop = inkscape_active_desktop(); // TODO: Is there a better method to find the item's desktop?
77a4a003111bd5cfb771d4849801c898aeb889b0cilix pc->expecting_clicks_for_LPE = this->acceptsNumParams();
77a4a003111bd5cfb771d4849801c898aeb889b0cilix ec->desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE,
77a4a003111bd5cfb771d4849801c898aeb889b0cilix g_strdup_printf(_("Please specify a parameter path for the LPE '%s' with %d mouse clicks"),
97a20864afec63a0b7bb757b628ee2ae596cf648cilix std::vector<Inkscape::LivePathEffect::Parameter *>::iterator p;
97a20864afec63a0b7bb757b628ee2ae596cf648cilix for (p = param_vector.begin(); p != param_vector.end(); ++p) {
77a4a003111bd5cfb771d4849801c898aeb889b0cilix * If the effect expects a path parameter (specified by a number of mouse clicks) before it is
77a4a003111bd5cfb771d4849801c898aeb889b0cilix * applied, this is the method that processes the resulting path. Override it to customize it for
77a4a003111bd5cfb771d4849801c898aeb889b0cilix * your LPE. But don't forget to call the parent method so that done_pathparam_set is set to true!
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm * Here be the doEffect function chain:
b802808a0226a87371021393c4f1da776aa6a6adjohanengelen std::vector<Geom::Path> orig_pathv = curve->get_pathvector();
b802808a0226a87371021393c4f1da776aa6a6adjohanengelen std::vector<Geom::Path> result_pathv = doEffect_path(orig_pathv);
ecda720053ff791e35dae3c5c1177bc225b6cdf1johanengelenEffect::doEffect_path (std::vector<Geom::Path> const & path_in)
46c4893a7458eda6edcd064121bc000634af7a09johanengelen // default behavior
46c4893a7458eda6edcd064121bc000634af7a09johanengelen for (unsigned int i=0; i < path_in.size(); i++) {
46c4893a7458eda6edcd064121bc000634af7a09johanengelen Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = path_in[i].toPwSb();
46c4893a7458eda6edcd064121bc000634af7a09johanengelen Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_out = doEffect_pwd2(pwd2_in);
46c4893a7458eda6edcd064121bc000634af7a09johanengelen std::vector<Geom::Path> path = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE);
46c4893a7458eda6edcd064121bc000634af7a09johanengelen // add the output path vector to the already accumulated vector:
46c4893a7458eda6edcd064121bc000634af7a09johanengelen // concatenate the path into possibly discontinuous pwd2
46c4893a7458eda6edcd064121bc000634af7a09johanengelen Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in;
46c4893a7458eda6edcd064121bc000634af7a09johanengelen for (unsigned int i=0; i < path_in.size(); i++) {
46c4893a7458eda6edcd064121bc000634af7a09johanengelen Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_out = doEffect_pwd2(pwd2_in);
46c4893a7458eda6edcd064121bc000634af7a09johanengelen path_out = Geom::path_from_piecewise( pwd2_out, LPE_CONVERSION_TOLERANCE);
ecda720053ff791e35dae3c5c1177bc225b6cdf1johanengelenEffect::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen std::vector<Parameter *>::iterator it = param_vector.begin();
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen bool accepted = param->param_readSVGValue(value);
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen g_warning("Effect::readallParameters - '%s' not accepted for %s", value, key);
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen // set default value
0fc5ce7045233dae7e15fdc86774370f1b1d73cbjohanengelen/* This function does not and SHOULD NOT write to XML */
0fc5ce7045233dae7e15fdc86774370f1b1d73cbjohanengelenEffect::setParameter(const gchar * key, const gchar * new_value)
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen bool accepted = param->param_readSVGValue(new_value);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm g_warning("Effect::setParameter - '%s' not accepted for %s", new_value, key);
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm // set default value
5be124ad592f5c71eca838ad2eaac9ffa953605fcilix// TODO: should we provide a way to alter the handle's appearance?
5be124ad592f5c71eca838ad2eaac9ffa953605fcilixEffect::registerKnotHolderHandle(KnotHolderEntity* entity, const char* descr)
5be124ad592f5c71eca838ad2eaac9ffa953605fcilix kh_entity_vector.push_back(std::make_pair(entity, descr));
5be124ad592f5c71eca838ad2eaac9ffa953605fcilix * Add all registered LPE knotholder handles to the knotholder
5be124ad592f5c71eca838ad2eaac9ffa953605fcilixEffect::addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
797bee69297bbdd86c5cff2e0771a71d1e2ac69dcilix // add handles provided by the effect itself
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix // add handles provided by the effect's parameters (if any)
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix (*p)->addKnotHolderEntities(knotholder, desktop, item);
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilixEffect::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix // TODO: The entities in kh_entity_vector are already instantiated during the call
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix // to registerKnotHolderHandle(), but they are recreated here. Also, we must not
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix // delete them when the knotholder is destroyed, whence the clumsy function
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix // isDeletable(). If we could create entities of different classes dynamically,
25ad3718fb4b96b39930af8e043c8ee1e624fd10cilix // this would be much nicer. How to do this?
5be124ad592f5c71eca838ad2eaac9ffa953605fcilix std::vector<std::pair<KnotHolderEntity*, const char*> >::iterator i;
5be124ad592f5c71eca838ad2eaac9ffa953605fcilix for (i = kh_entity_vector.begin(); i != kh_entity_vector.end(); ++i) {
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix * Return a vector of PathVectors which contain all helperpaths that should be drawn by the effect.
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix * This is the function called by external code like SPLPEItem.
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix g_print ("How to handle helperpaths for non-shapes?\n");
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix // TODO: we can probably optimize this by using a lot more references
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix // rather than copying PathVectors all over the place
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix // add original path to helperpaths
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix SPCurve* curve = sp_shape_get_curve (SP_SHAPE(lpeitem));
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix // add other helperpaths provided by the effect itself
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix // add helperpaths provided by the effect's parameters
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix * Add possible canvas indicators (i.e., helperpaths other than the original path) to \a hp_vec
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix * This function should be overwritten by derived effects if they want to provide their own helperpaths.
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilixEffect::addCanvasIndicators(SPLPEItem *lpeitem, std::vector<Geom::PathVector> &hp_vec)
73d455c08e8062e257dd052d2d690b9300434351cilix * This *creates* a new widget, management of deletion should be done by the caller
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen // use manage here, because after deletion of Effect object, others might still be pointing to this widget.
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox() );
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen std::vector<Parameter *>::iterator it = param_vector.begin();
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen Gtk::Widget * widg = param->param_newWidget(tooltips);
c0cd5511d3b975ebe07d019c1f5528108725e438johanengelen Glib::ustring * tip = param->param_getTooltip();
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm if (SP_OBJECT_DOCUMENT(lpeobj) == NULL) g_message("Effect::getSPDoc() returns NULL");
93bb287e28a818fd5ba61b99d012e0500a49ccf6johanengelen std::vector<Parameter *>::iterator it = param_vector.begin();
af8d25189f88abf89cdbe0e180e271c94079624fbuliabyak if (oncanvasedit_it >= static_cast<int>(param_vector.size())) {
a0334366488989ef25fb812d7030d298c0917c96johanengelen Parameter * param = param_vector[oncanvasedit_it];
f9504c822b72a774b910958446fd1e730235b7cbjoncruz if (oncanvasedit_it == static_cast<int>(param_vector.size())) { // loop round the map
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen } while (oncanvasedit_it != old_it); // iterate until complete loop through map has been made
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelenEffect::editNextParamOncanvas(SPItem * item, SPDesktop * desktop)
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen if (!desktop) return;
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen Parameter * param = getNextOncanvasEditableParam();
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen gchar *message = g_strdup_printf(_("Editing parameter <b>%s</b>."), param->param_label.c_str());
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, message);
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen desktop->messageStack()->flash( Inkscape::WARNING_MESSAGE,
fb5a72174252e0e79107dcad3bf5a2bbd73e349cjohanengelen _("None of the applied path effect's parameters can be edited on-canvas.") );
42e99769805c14a5cc01c805faa3c3b03f9dd1c0johanengelen/* This function should reset the defaults and is used for example to initialize an effect right after it has been applied to a path
42e99769805c14a5cc01c805faa3c3b03f9dd1c0johanengelen* The nice thing about this is that this function can use knowledge of the original path and set things accordingly for example to the size or origin of the original path!
42e99769805c14a5cc01c805faa3c3b03f9dd1c0johanengelen // do nothing for simple effects
a797dcb8e284cab19f60b3eff93a53a62abda263johanengelenEffect::setup_nodepath(Inkscape::NodePath::Path *np)
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelenEffect::transform_multiply(Geom::Matrix const& postmul, bool set)
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen // cycle through all parameters. Most parameters will not need transformation, but path and point params do.
ddc251b3cf95b0097b6a5ee39ea132bd4d7d5cbcjohanengelen for (std::vector<Parameter *>::iterator it = param_vector.begin(); it != param_vector.end(); it++) {
797bee69297bbdd86c5cff2e0771a71d1e2ac69dcilix// TODO: take _all_ parameters into account, not only PointParams
42ba1b712b7b430669fc49aa9facb439181081becilix // does the effect actively provide any knotholder entities of its own?
42ba1b712b7b430669fc49aa9facb439181081becilix return true;
42ba1b712b7b430669fc49aa9facb439181081becilix // otherwise: are there any PointParams?
42ba1b712b7b430669fc49aa9facb439181081becilix for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) {
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix// if ( Inkscape::LivePathEffect::PointParam *pointparam = dynamic_cast<Inkscape::LivePathEffect::PointParam*>(*p) ) {
2e2b8bd323e3693f9d86f545ce049d3f1b45d1c2cilix if (dynamic_cast<Inkscape::LivePathEffect::PointParam*>(*p)) {
42ba1b712b7b430669fc49aa9facb439181081becilix return true;
42ba1b712b7b430669fc49aa9facb439181081becilix return false;
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm} /* namespace LivePathEffect */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm} /* namespace Inkscape */
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm Local Variables:
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm c-file-style:"stroustrup"
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm indent-tabs-mode:nil
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm fill-column:99
f07bfd5a05d43a6d11f7cd442f085149092dea88pjrm// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :