summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-02-16 20:49:53 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-02-16 20:49:53 +0000
commit9593c78703845bfca18a3a135cbbc47cc03b54f6 (patch)
tree4616e3cb7ed134d82367726aafaaf3f312d1cbc5
parentadded knots (diff)
downloadinkscape-9593c78703845bfca18a3a135cbbc47cc03b54f6.tar.gz
inkscape-9593c78703845bfca18a3a135cbbc47cc03b54f6.zip
continuing fillet/chamfer
(bzr r13645.1.13)
-rw-r--r--src/2geom/satellite.h31
-rw-r--r--src/live_effects/lpe-fillet-chamfer.cpp228
-rw-r--r--src/live_effects/lpe-fillet-chamfer.h14
-rw-r--r--src/live_effects/parameter/array.cpp9
-rw-r--r--src/live_effects/parameter/array.h14
-rw-r--r--src/live_effects/parameter/satellitepairarray.cpp4
-rw-r--r--src/live_effects/parameter/satellitepairarray.h7
7 files changed, 259 insertions, 48 deletions
diff --git a/src/2geom/satellite.h b/src/2geom/satellite.h
index 8623ff1b0..06b4a1dd6 100644
--- a/src/2geom/satellite.h
+++ b/src/2geom/satellite.h
@@ -54,6 +54,12 @@ class Satellite
_satellitetype = A;
}
+ void setSatelliteType(gchar const * A)
+ {
+ std::map<gchar const *,SatelliteType> GcharMapToSatelliteType = boost::assign::map_list_of("FILLET", FILLET)("INVERSE_FILLET", INVERSE_FILLET)("CHAMFER",CHAMFER)("INVERSE_CHAMFER",INVERSE_CHAMFER)("INVALID_SATELLITE",INVALID_SATELLITE);
+ _satellitetype = GcharMapToSatelliteType[A];
+ }
+
void setIsTime(bool A)
{
_isTime = A;
@@ -84,42 +90,48 @@ class Satellite
_size = A;
}
- SatelliteType satellitetype() const
+ SatelliteType getSatelliteType() const
{
return _satellitetype;
}
- bool isTime() const
+ gchar const * getSatelliteTypeGchar() const
+ {
+ std::map<SatelliteType,gchar const *> SatelliteTypeToGcharMap = boost::assign::map_list_of(FILLET, "FILLET")(INVERSE_FILLET, "INVERSE_FILLET")(CHAMFER,"CHAMFER")(INVERSE_CHAMFER,"INVERSE_CHAMFER")(INVALID_SATELLITE,"INVALID_SATELLITE");
+ return SatelliteTypeToGcharMap[_satellitetype];
+ }
+
+ bool getIsTime() const
{
return _isTime;
}
- bool active() const
+ bool getActive() const
{
return _active;
}
- bool hasMirror() const
+ bool getHasMirror() const
{
return _hasMirror;
}
- bool hidden() const
+ bool getHidden() const
{
return _hidden;
}
- double size() const
+ double getSize() const
{
return _size;
}
- double time() const
+ double getTime() const
{
return _time;
}
- double time(Geom::D2<Geom::SBasis> curve) const
+ double getTime(Geom::D2<Geom::SBasis> curve) const
{
//todo make the process
return _time;
@@ -133,7 +145,10 @@ class Satellite
static const std::map<gchar const *,SatelliteType> GcharMapToSatelliteType;
+ static double getOpositeTime(Geom::D2<Geom::SBasis> SBasisCurve, double time);
+
private:
+
SatelliteType _satellitetype;
bool _isTime;
bool _active;
diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp
index 5d6358bb2..df9de81b7 100644
--- a/src/live_effects/lpe-fillet-chamfer.cpp
+++ b/src/live_effects/lpe-fillet-chamfer.cpp
@@ -17,25 +17,38 @@
#include "live_effects/lpe-fillet-chamfer.h"
#include <sp-shape.h>
+#include <sp-path.h>
#include <2geom/pointwise.h>
#include <2geom/satellite.h>
#include <2geom/satellite-enum.h>
+#include <2geom/svg-elliptical-arc.h>
#include "helper/geom-nodetype.h"
+#include "helper/geom-curves.h"
#include "helper/geom.h"
#include "display/curve.h"
#include <vector>
// TODO due to internal breakage in glibmm headers, this must be last:
#include <glibmm/i18n.h>
-
+using namespace Geom;
namespace Inkscape {
namespace LivePathEffect {
+static const Util::EnumData<FilletMethod> FilletMethodData[FM_END] = {
+ { FM_AUTO, N_("Auto"), "auto" },
+ { FM_ARC, N_("Force arc"), "arc" },
+ { FM_BEZIER, N_("Force bezier"), "bezier" }
+};
+static const Util::EnumDataConverter<FilletMethod>
+FMConverter(FilletMethodData, FM_END);
+
LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
- satellitepairarrayparam_values(_("Fillet point"), _("Fillet point"), "satellitepairarrayparam_values", &wr, this)
+ satellitepairarrayparam_values(_("Fillet point"), _("Fillet point"), "satellitepairarrayparam_values", &wr, this),
+ method(_("Method:"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO)
{
registerParameter(&satellitepairarrayparam_values);
+ registerParameter(&method);
}
LPEFilletChamfer::~LPEFilletChamfer() {}
@@ -46,23 +59,21 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem)
SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeItem);
SPShape * shape = dynamic_cast<SPShape *>(splpeitem);
if (shape) {
- Geom::PathVector const &original_pathv = pathv_to_linear_and_cubic_beziers(shape->getCurve()->get_pathvector());
- std::vector<std::pair<int,Geom::Satellite> > satellites;
- Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = paths_to_pw(original_pathv);
+ PathVector const &original_pathv = pathv_to_linear_and_cubic_beziers(shape->getCurve()->get_pathvector());
+ std::vector<std::pair<int,Satellite> > satellites;
+ Piecewise<D2<SBasis> > pwd2_in = paths_to_pw(original_pathv);
pwd2_in = remove_short_cuts(pwd2_in, .01);
- Geom::Piecewise<Geom::D2<Geom::SBasis> > der = derivative(pwd2_in);
- Geom::Piecewise<Geom::D2<Geom::SBasis> > n = rot90(unitVector(der));
- satellitepairarrayparam_values.set_pwd2(pwd2_in, n);
- for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) {
+ satellitepairarrayparam_values.set_pwd2(pwd2_in);
+ for (PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) {
if (path_it->empty()){
continue;
}
Geom::Path::const_iterator curve_it1 = path_it->begin();
Geom::Path::const_iterator curve_endit = path_it->end_default();
if (path_it->closed()) {
- const Geom::Curve &closingline = path_it->back_closed();
+ const Curve &closingline = path_it->back_closed();
// the closing line segment is always of type
- // Geom::LineSegment.
+ // LineSegment.
if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
// closingline.isDegenerate() did not work, because it only checks for
// *exact* zero length, which goes wrong for relative coordinates and
@@ -75,18 +86,18 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem)
--curve_end;
int counter = 0;
while (curve_it1 != curve_endit) {
- Geom::Satellite satellite(Geom::FILLET, true, true, false, false, 0.0, 0.2);
+ Satellite satellite(FILLET, true, true, false, false, 0.0, 0.0);
Geom::NodeType nodetype;
if (counter==0) {
if (path_it->closed()) {
- nodetype = Geom::get_nodetype(*curve_end, *curve_it1);
+ nodetype = get_nodetype(*curve_end, *curve_it1);
} else {
- nodetype = Geom::NODE_NONE;
+ nodetype = NODE_NONE;
}
} else {
nodetype = get_nodetype((*path_it)[counter - 1], *curve_it1);
}
- if (nodetype == Geom::NODE_CUSP) {
+ if (nodetype == NODE_CUSP) {
satellites.push_back(std::make_pair(counter, satellite));
}
++curve_it1;
@@ -101,11 +112,196 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem)
}
}
+
+void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem)
+{
+ SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeItem);
+ SPShape * shape = dynamic_cast<SPShape *>(splpeitem);
+ if (shape) {
+ SPCurve *c = shape->getCurve();
+ SPPath * path = dynamic_cast<SPPath *>(shape);
+ if(path){
+ c = path->get_original_curve();
+ }
+ PathVector const &original_pathv = pathv_to_linear_and_cubic_beziers(c->get_pathvector());
+ Piecewise<D2<SBasis> > pwd2_in = paths_to_pw(original_pathv);
+ pwd2_in = remove_short_cuts(pwd2_in, .01);
+ satellitepairarrayparam_values.set_pwd2(pwd2_in);
+ } else {
+ g_warning("LPE Fillet can only be applied to shapes (not groups).");
+ }
+}
+
+std::vector<Geom::Path>
+LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in)
+{
+ std::vector<Geom::Path> pathvector_out;
+ Piecewise<D2<SBasis> > pwd2_in = paths_to_pw(pathv_to_linear_and_cubic_beziers(path_in));
+ pwd2_in = remove_short_cuts(pwd2_in, .01);
+ satellitepairarrayparam_values.set_pwd2(pwd2_in);
+ std::vector<std::pair<int, Satellite> > filletChamferData = satellitepairarrayparam_values.data();
+ unsigned int counter = 0;
+ const double K = (4.0 / 3.0) * (sqrt(2.0) - 1.0);
+ std::vector<Geom::Path> path_in_processed = pathv_to_linear_and_cubic_beziers(path_in);
+ for (PathVector::const_iterator path_it = path_in_processed.begin();
+ path_it != path_in_processed.end(); ++path_it) {
+ if (path_it->empty())
+ continue;
+ Geom::Path path_out;
+ Geom::Path::const_iterator curve_it1 = path_it->begin();
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin());
+ Geom::Path::const_iterator curve_endit = path_it->end_default();
+ if (path_it->closed()) {
+ const Curve &closingline = path_it->back_closed();
+ // the closing line segment is always of type
+ // LineSegment.
+ if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
+ // closingline.isDegenerate() did not work, because it only checks for
+ // *exact* zero length, which goes wrong for relative coordinates and
+ // rounding errors...
+ // the closing line segment has zero-length. So stop before that one!
+ curve_endit = path_it->end_open();
+ }
+ }
+ unsigned int counterCurves = 0;
+ while (curve_it1 != curve_endit) {
+ Curve *curve_it2Fixed = (*path_it->begin()).duplicate();
+ int indexFix = 0;
+ if(!path_it->closed() || curve_it2 != curve_endit){
+ curve_it2Fixed = (*curve_it2).duplicate();
+ indexFix = counter;
+ }
+ bool last = curve_it2 == curve_endit;
+ std::vector<double> times;
+ times.push_back(filletChamferData[counter].second.getTime());
+ times.push_back(filletChamferData[indexFix].second.getOpositeTime((*curve_it1).toSBasis(),filletChamferData[indexFix].second.getTime()));
+ times.push_back(filletChamferData[indexFix].second.getTime());
+ Curve *knotCurve1 = curve_it1->portion(times[0], times[1]);
+ if (counterCurves > 0) {
+ knotCurve1->setInitial(path_out.finalPoint());
+ } else {
+ path_out.start((*curve_it1).pointAt(times[0]));
+ }
+ Curve *knotCurve2 = curve_it2Fixed->portion(times[2], 1);
+ Point startArcPoint = knotCurve1->finalPoint();
+ Point endArcPoint = curve_it2Fixed->pointAt(times[2]);
+ double k1 = distance(startArcPoint, curve_it1->finalPoint()) * K;
+ double k2 = distance(endArcPoint, curve_it1->finalPoint()) * K;
+ CubicBezier const *cubic1 = dynamic_cast<CubicBezier const *>(&*knotCurve1);
+ Ray ray1(startArcPoint, curve_it1->finalPoint());
+ if (cubic1) {
+ ray1.setPoints((*cubic1)[2], startArcPoint);
+ }
+ Point handle1 = Point::polar(ray1.angle(),k1) + startArcPoint;
+ CubicBezier const *cubic2 =
+ dynamic_cast<CubicBezier const *>(&*knotCurve2);
+ Ray ray2(curve_it1->finalPoint(), endArcPoint);
+ if (cubic2) {
+ ray2.setPoints(endArcPoint, (*cubic2)[1]);
+ }
+ Point handle2 = endArcPoint - Point::polar(ray2.angle(),k2);
+ bool ccwToggle = cross(curve_it1->finalPoint() - startArcPoint, endArcPoint - startArcPoint) < 0;
+ double angle = angle_between(ray1, ray2, ccwToggle);
+ double handleAngle = ray1.angle() - angle;
+ if (ccwToggle) {
+ handleAngle = ray1.angle() + angle;
+ }
+ Point inverseHandle1 = Point::polar(handleAngle,k1) + startArcPoint;
+ handleAngle = ray2.angle() + angle;
+ if (ccwToggle) {
+ handleAngle = ray2.angle() - angle;
+ }
+ Point inverseHandle2 = endArcPoint - Point::polar(handleAngle,k2);
+ //straigth lines arc based
+ Line const x_line(Point(0,0),Point(1,0));
+ Line const angled_line(startArcPoint,endArcPoint);
+ double angleArc = angle_between( x_line,angled_line);
+ double radius = distance(startArcPoint,middle_point(startArcPoint,endArcPoint))/sin(angle/2.0);
+ Coord rx = radius;
+ Coord ry = rx;
+
+ if (times[1] != 1) {
+ if (times[1] != times[0]) {
+ path_out.append(*knotCurve1);
+ }
+ SatelliteType satType = FILLET;
+ if(path_it->closed() && last){
+ satType = filletChamferData[counter - counterCurves].second.getSatelliteType();
+ } else if (!path_it->closed() && last){
+ //0
+ } else {
+ satType = filletChamferData[counter + 1].second.getSatelliteType();
+ }
+ if(are_near(middle_point(startArcPoint,endArcPoint),curve_it1->finalPoint(), 0.0001)){
+ path_out.appendNew<LineSegment>(endArcPoint);
+ } else if (satType == CHAMFER) {
+ unsigned int chamferSubs = 0;
+ Geom::Path path_chamfer;
+ path_chamfer.start(path_out.finalPoint());
+ if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){
+ path_chamfer.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint);
+ } else {
+ path_chamfer.appendNew<CubicBezier>(handle1, handle2, endArcPoint);
+ }
+ double chamfer_stepsTime = 1.0/chamferSubs;
+ for(unsigned int i = 1; i < chamferSubs; i++){
+ Point chamferStep = path_chamfer.pointAt(chamfer_stepsTime * i);
+ path_out.appendNew<LineSegment>(chamferStep);
+ }
+ path_out.appendNew<LineSegment>(endArcPoint);
+ } else if (satType == INVERSE_CHAMFER) {
+ unsigned int chamferSubs = 2;
+ Geom::Path path_chamfer;
+ path_chamfer.start(path_out.finalPoint());
+ if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){
+ ccwToggle = ccwToggle?0:1;
+ path_chamfer.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint);
+ }else{
+ path_chamfer.appendNew<CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint);
+ }
+ double chamfer_stepsTime = 1.0/chamferSubs;
+ for(unsigned int i = 1; i < chamferSubs; i++){
+ Point chamferStep = path_chamfer.pointAt(chamfer_stepsTime * i);
+ path_out.appendNew<LineSegment>(chamferStep);
+ }
+ path_out.appendNew<LineSegment>(endArcPoint);
+ } else if (satType == INVERSE_FILLET) {
+ if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){
+ ccwToggle = ccwToggle?0:1;
+ path_out.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint);
+ }else{
+ path_out.appendNew<CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint);
+ }
+ } else if (satType == FILLET){
+ if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){
+ path_out.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint);
+ } else {
+ path_out.appendNew<CubicBezier>(handle1, handle2, endArcPoint);
+ }
+ }
+ } else {
+ path_out.append(*knotCurve1);
+ }
+ if (path_it->closed() && last) {
+ path_out.close();
+ }
+ ++curve_it1;
+ if (curve_it2 != curve_endit) {
+ ++curve_it2;
+ }
+ counter++;
+ counterCurves++;
+ }
+ pathvector_out.push_back(path_out);
+ }
+ return pathvector_out;
+}
+
void
LPEFilletChamfer::adjustForNewPath(std::vector<Geom::Path> const &path_in)
{
if (!path_in.empty()) {
- //fillet_chamfer_values.recalculate_controlpoints_for_new_pwd2(pathv_to_linear_and_cubic_beziers(path_in)[0].toPwSb());
+ //satellitepairarrayparam_values.recalculate_controlpoints_for_new_pwd2(pathv_to_linear_and_cubic_beziers(path_in)[0].toPwSb());
}
}
diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h
index 08000c0a5..94a2bd2b3 100644
--- a/src/live_effects/lpe-fillet-chamfer.h
+++ b/src/live_effects/lpe-fillet-chamfer.h
@@ -14,27 +14,35 @@
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-
+#include "live_effects/parameter/enum.h"
#include "2geom/pointwise.h"
#include "live_effects/parameter/satellitepairarray.h"
#include "live_effects/effect.h"
+using namespace Geom;
namespace Inkscape {
namespace LivePathEffect {
+enum FilletMethod {
+ FM_AUTO,
+ FM_ARC,
+ FM_BEZIER,
+ FM_END
+};
class LPEFilletChamfer : public Effect {
public:
LPEFilletChamfer(LivePathEffectObject *lpeobject);
virtual ~LPEFilletChamfer();
-
+ virtual void doBeforeEffect(SPLPEItem const *lpeItem);
+ virtual std::vector<Geom::Path> doEffect_path(std::vector<Geom::Path> const &path_in);
virtual void doOnApply(SPLPEItem const *lpeItem);
virtual void adjustForNewPath(std::vector<Geom::Path> const &path_in);
SatellitePairArrayParam satellitepairarrayparam_values;
private:
-
+ EnumParam<FilletMethod> method;
LPEFilletChamfer(const LPEFilletChamfer &);
LPEFilletChamfer &operator=(const LPEFilletChamfer &);
diff --git a/src/live_effects/parameter/array.cpp b/src/live_effects/parameter/array.cpp
index d1d718b08..473b561d2 100644
--- a/src/live_effects/parameter/array.cpp
+++ b/src/live_effects/parameter/array.cpp
@@ -55,17 +55,16 @@ sp_svg_satellite_read_d(gchar const *str, Geom::Satellite *sat){
}
gchar ** strarray = g_strsplit(str, "*", 0);
if(strarray[6] && !strarray[7]){
- std::map< gchar const *, Geom::SatelliteType> gts = sat->GcharMapToSatelliteType;
- sat->setSatelliteType(gts[strarray[0]]);
+ sat->setSatelliteType(strarray[0]);
sat->setIsTime(helperfns_read_bool(strarray[1], true));
sat->setActive(helperfns_read_bool(strarray[2], true));
sat->setHasMirror(helperfns_read_bool(strarray[3], false));
sat->setHidden(helperfns_read_bool(strarray[4], false));
double time,size;
- sp_svg_number_read_d(strarray[5], &time);
- sp_svg_number_read_d(strarray[6], &size);
- sat->setTime(time);
+ sp_svg_number_read_d(strarray[5], &size);
+ sp_svg_number_read_d(strarray[6], &time);
sat->setSize(size);
+ sat->setTime(time);
g_strfreev (strarray);
return 1;
}
diff --git a/src/live_effects/parameter/array.h b/src/live_effects/parameter/array.h
index ba1ed3d4e..c99777b08 100644
--- a/src/live_effects/parameter/array.h
+++ b/src/live_effects/parameter/array.h
@@ -116,19 +116,19 @@ protected:
str << nVector.first;
str << ",";
std::map<Geom::SatelliteType, gchar const *> stg = nVector.second.SatelliteTypeToGcharMap;
- str << stg[nVector.second.satellitetype()];
+ str << nVector.second.getSatelliteTypeGchar();
str << "*";
- str << nVector.second.isTime();
+ str << nVector.second.getIsTime();
str << "*";
- str << nVector.second.active();
+ str << nVector.second.getActive();
str << "*";
- str << nVector.second.hasMirror();
+ str << nVector.second.getHasMirror();
str << "*";
- str << nVector.second.hidden();
+ str << nVector.second.getHidden();
str << "*";
- str << nVector.second.size();
+ str << nVector.second.getSize();
str << "*";
- str <<nVector.second.time();
+ str <<nVector.second.getTime();
}
StorageType readsvg(const gchar * str);
diff --git a/src/live_effects/parameter/satellitepairarray.cpp b/src/live_effects/parameter/satellitepairarray.cpp
index a40e70e1f..bb72830d6 100644
--- a/src/live_effects/parameter/satellitepairarray.cpp
+++ b/src/live_effects/parameter/satellitepairarray.cpp
@@ -45,11 +45,9 @@ void SatellitePairArrayParam::set_oncanvas_looks(SPKnotShapeType shape,
}
void SatellitePairArrayParam::set_pwd2(
- Piecewise<D2<SBasis> > const &pwd2_in,
- Piecewise<D2<SBasis> > const &pwd2_normal_in)
+ Piecewise<D2<SBasis> > const &pwd2_in)
{
last_pwd2 = pwd2_in;
- last_pwd2_normal = pwd2_normal_in;
}
void SatellitePairArrayParam::addKnotHolderEntities(KnotHolder *knotholder,
diff --git a/src/live_effects/parameter/satellitepairarray.h b/src/live_effects/parameter/satellitepairarray.h
index 82d04c790..ff1924829 100644
--- a/src/live_effects/parameter/satellitepairarray.h
+++ b/src/live_effects/parameter/satellitepairarray.h
@@ -47,14 +47,10 @@ public:
return true;
}
virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
- void set_pwd2(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &pwd2_in,
- Geom::Piecewise<Geom::D2<Geom::SBasis> > const &pwd2_normal_in);
+ void set_pwd2(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &pwd2_in);
Geom::Piecewise<Geom::D2<Geom::SBasis> > const &get_pwd2() const {
return last_pwd2;
}
- Geom::Piecewise<Geom::D2<Geom::SBasis> > const &get_pwd2_normal() const {
- return last_pwd2_normal;
- }
friend class SatellitePairArrayParamKnotHolderEntity;
private:
@@ -66,7 +62,6 @@ private:
guint32 knot_color;
Geom::Piecewise<Geom::D2<Geom::SBasis> > last_pwd2;
- Geom::Piecewise<Geom::D2<Geom::SBasis> > last_pwd2_normal;
};