Skip to content

Commit

Permalink
Sketcher: New Feature: Hyperbola/ArcOfHyperbola
Browse files Browse the repository at this point in the history
===============================================

- ArcOfHyperbola creation method
- Solver representation (undefined moving)
- SketchObjectPyImp (here we still miss the Part->Partdesign conversion)
- Sketch validation for hyperbola
- Hyperbola creation method: shows the "proof of concept", but it is very buggy!!

Notes:
- Missing icons, probably missing geo normal curve implementation - rebasing -
- Fixes to adapt Hyperbola to Derivector implementation and make it compile
  • Loading branch information
abdullahtahiriyo authored and wwmayer committed Nov 27, 2016
1 parent fde9bde commit 590e3fb
Show file tree
Hide file tree
Showing 10 changed files with 1,004 additions and 14 deletions.
179 changes: 170 additions & 9 deletions src/Mod/Sketcher/App/Sketch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
#include <Mod/Part/App/ArcOfEllipsePy.h>
#include <Mod/Part/App/CirclePy.h>
#include <Mod/Part/App/EllipsePy.h>
#include <Mod/Part/App/HyperbolaPy.h>
#include <Mod/Part/App/ArcOfHyperbolaPy.h>
#include <Mod/Part/App/LinePy.h>

#include <TopoDS.hxx>
Expand Down Expand Up @@ -81,6 +83,7 @@ void Sketch::clear(void)
Circles.clear();
Ellipses.clear();
ArcsOfEllipse.clear();
ArcsOfHyperbola.clear();

// deleting the doubles allocated with new
for (std::vector<double*>::iterator it = Parameters.begin(); it != Parameters.end(); ++it)
Expand Down Expand Up @@ -172,6 +175,8 @@ const char* nameByType(Sketch::GeoType type)
return "ellipse";
case Sketch::ArcOfEllipse:
return "arcofellipse";
case Sketch::ArcOfHyperbola:
return "arcofhyperbola";
case Sketch::None:
default:
return "unknown";
Expand Down Expand Up @@ -206,6 +211,10 @@ int Sketch::addGeometry(const Part::Geometry *geo, bool fixed)
const GeomArcOfEllipse *aoe = static_cast<const GeomArcOfEllipse*>(geo);
// create the definition struct for that geom
return addArcOfEllipse(*aoe, fixed);
} else if (geo->getTypeId() == GeomArcOfHyperbola::getClassTypeId()) { // add an arc of hyperbola
const GeomArcOfHyperbola *aoh = dynamic_cast<const GeomArcOfHyperbola*>(geo);
// create the definition struct for that geom
return addArcOfHyperbola(*aoh, fixed);
} else {
throw Base::TypeError("Sketch::addGeometry(): Unknown or unsupported type added to a sketch");
}
Expand Down Expand Up @@ -377,8 +386,6 @@ int Sketch::addArc(const Part::GeomArcOfCircle &circleSegment, bool fixed)
return Geoms.size()-1;
}



int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed)
{
std::vector<double *> &params = fixed ? FixParameters : Parameters;
Expand Down Expand Up @@ -435,17 +442,14 @@ int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool f

//Points.push_back(f1);


// add the radius parameters
// add the radius parameters
params.push_back(new double(radmin));
double *rmin = params[params.size()-1];
params.push_back(new double(startAngle));
double *a1 = params[params.size()-1];
params.push_back(new double(endAngle));
double *a2 = params[params.size()-1];



// set the arc for later constraints
GCS::ArcOfEllipse a;
a.start = p1;
Expand All @@ -470,6 +474,92 @@ int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool f
return Geoms.size()-1;
}

int Sketch::addArcOfHyperbola(const Part::GeomArcOfHyperbola &hyperbolaSegment, bool fixed)
{
std::vector<double *> &params = fixed ? FixParameters : Parameters;

// create our own copy
GeomArcOfHyperbola *aoh = static_cast<GeomArcOfHyperbola*>(hyperbolaSegment.clone());
// create the definition struct for that geom
GeoDef def;
def.geo = aoh;
def.type = ArcOfHyperbola;

Base::Vector3d center = aoh->getCenter();
Base::Vector3d startPnt = aoh->getStartPoint();
Base::Vector3d endPnt = aoh->getEndPoint();
double radmaj = aoh->getMajorRadius();
double radmin = aoh->getMinorRadius();
double phi = aoh->getAngleXU();

double dist_C_F = sqrt(radmaj*radmaj+radmin*radmin);
// solver parameters
Base::Vector3d focus1 = center+dist_C_F*Vector3d(cos(phi), sin(phi),0); //+x

double startAngle, endAngle;
aoh->getRange(startAngle, endAngle);

GCS::Point p1, p2, p3;

params.push_back(new double(startPnt.x));
params.push_back(new double(startPnt.y));
p1.x = params[params.size()-2];
p1.y = params[params.size()-1];

params.push_back(new double(endPnt.x));
params.push_back(new double(endPnt.y));
p2.x = params[params.size()-2];
p2.y = params[params.size()-1];

params.push_back(new double(center.x));
params.push_back(new double(center.y));
p3.x = params[params.size()-2];
p3.y = params[params.size()-1];

params.push_back(new double(focus1.x));
params.push_back(new double(focus1.y));
double *f1X = params[params.size()-2];
double *f1Y = params[params.size()-1];

def.startPointId = Points.size();
Points.push_back(p1);
def.endPointId = Points.size();
Points.push_back(p2);
def.midPointId = Points.size();
Points.push_back(p3);

// add the radius parameters
params.push_back(new double(radmaj));
double *rmaj = params[params.size()-1];
params.push_back(new double(startAngle));
double *a1 = params[params.size()-1];
params.push_back(new double(endAngle));
double *a2 = params[params.size()-1];

// set the arc for later constraints
GCS::ArcOfHyperbola a;
a.start = p1;
a.end = p2;
a.center = p3;
a.focus.x = f1X;
a.focus.y = f1Y;
a.radmaj = rmaj;
a.startAngle = a1;
a.endAngle = a2;
def.index = ArcsOfHyperbola.size();
ArcsOfHyperbola.push_back(a);

// store complete set
Geoms.push_back(def);

// arcs require an ArcRules constraint for the end points
/*if (!fixed)
GCSsys.addConstraintArcOfHyperbolaRules(a);*/

// return the position of the newly added geometry
return Geoms.size()-1;
}

int Sketch::addCircle(const Part::GeomCircle &cir, bool fixed)
{
std::vector<double *> &params = fixed ? FixParameters : Parameters;
Expand Down Expand Up @@ -607,8 +697,10 @@ Py::Tuple Sketch::getPyGeometry(void) const
} else if (it->type == ArcOfEllipse) {
GeomArcOfEllipse *ellipse = static_cast<GeomArcOfEllipse*>(it->geo->clone());
tuple[i] = Py::asObject(new ArcOfEllipsePy(ellipse));
}
else {
} else if (it->type == ArcOfHyperbola) {
GeomArcOfHyperbola *aoh = dynamic_cast<GeomArcOfHyperbola*>(it->geo->clone());
tuple[i] = Py::asObject(new ArcOfHyperbolaPy(aoh));
} else {
// not implemented type in the sketch!
}
}
Expand Down Expand Up @@ -2069,6 +2161,30 @@ bool Sketch::updateGeometry()
ellipse->setMajorRadius(radmaj);
}
ellipse->setMajorAxisDir(fd);
} else if (it->type == ArcOfHyperbola) {
GCS::ArcOfHyperbola &myArc = ArcsOfHyperbola[it->index];

GeomArcOfHyperbola *aoh = dynamic_cast<GeomArcOfHyperbola*>(it->geo);

Base::Vector3d center = Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0);
Base::Vector3d f1 = Vector3d(*myArc.focus.x, *myArc.focus.y, 0.0);
double radmaj = *myArc.radmaj;

Base::Vector3d fd=f1-center;
double radmin = sqrt(fd*fd-radmaj*radmaj);

double phi = atan2(fd.y,fd.x);

aoh->setCenter(center);
if ( radmaj >= aoh->getMinorRadius() ){
aoh->setMajorRadius(radmaj);
aoh->setMinorRadius(radmin);
} else {
aoh->setMinorRadius(radmin);
aoh->setMajorRadius(radmaj);
}
aoh->setAngleXU(phi);
aoh->setRange(*myArc.startAngle, *myArc.endAngle);
}
} catch (Base::Exception e) {
Base::Console().Error("Updating geometry: Error build geometry(%d): %s\n",
Expand Down Expand Up @@ -2335,6 +2451,7 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
p0.y = &MoveParameters[1];
*p0.x = *center.x;
*p0.y = *center.y;

GCSsys.addConstraintP2PCoincident(p0,center,-1);
}
} else if (Geoms[geoId].type == ArcOfEllipse) {
Expand All @@ -2348,6 +2465,7 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
*p0.x = *center.x;
*p0.y = *center.y;
GCSsys.addConstraintP2PCoincident(p0,center,-1);

} else if (pos == start || pos == end) {

MoveParameters.resize(4); // x,y,cx,cy
Expand All @@ -2358,16 +2476,54 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
p0.y = &MoveParameters[1];
*p0.x = *p.x;
*p0.y = *p.y;

GCSsys.addConstraintP2PCoincident(p0,p,-1);
}

p1.x = &MoveParameters[2];
p1.y = &MoveParameters[3];
*p1.x = *center.x;
*p1.y = *center.y;

int i=GCSsys.addConstraintP2PCoincident(p1,center,-1);
GCSsys.rescaleConstraint(i-1, 0.01);
GCSsys.rescaleConstraint(i, 0.01);
}

} else if (Geoms[geoId].type == ArcOfHyperbola) {

GCS::Point &center = Points[Geoms[geoId].midPointId];
GCS::Point p0,p1;
if (pos == mid || pos == none) {
MoveParameters.resize(2); // cx,cy
p0.x = &MoveParameters[0];
p0.y = &MoveParameters[1];
*p0.x = *center.x;
*p0.y = *center.y;

//GCSsys.addConstraintP2PCoincident(p0,center,-1);
} else if (pos == start || pos == end) {

MoveParameters.resize(4); // x,y,cx,cy
if (pos == start || pos == end) {
GCS::Point &p = (pos == start) ? Points[Geoms[geoId].startPointId]
: Points[Geoms[geoId].endPointId];;
p0.x = &MoveParameters[0];
p0.y = &MoveParameters[1];
*p0.x = *p.x;
*p0.y = *p.y;

//GCSsys.addConstraintP2PCoincident(p0,p,-1);
}
p1.x = &MoveParameters[2];
p1.y = &MoveParameters[3];
*p1.x = *center.x;
*p1.y = *center.y;

//int i=GCSsys.addConstraintP2PCoincident(p1,center,-1);
//GCSsys.rescaleConstraint(i-1, 0.01);
//GCSsys.rescaleConstraint(i, 0.01);

}
} else if (Geoms[geoId].type == Arc) {
GCS::Point &center = Points[Geoms[geoId].midPointId];
Expand Down Expand Up @@ -2466,7 +2622,12 @@ int Sketch::movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool rela
MoveParameters[0] = toPoint.x;
MoveParameters[1] = toPoint.y;
}
}
} else if (Geoms[geoId].type == ArcOfHyperbola) {
if (pos == start || pos == end || pos == mid || pos == none) {
MoveParameters[0] = toPoint.x;
MoveParameters[1] = toPoint.y;
}
}

return solve();
}
Expand Down
8 changes: 6 additions & 2 deletions src/Mod/Sketcher/App/Sketch.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ class SketcherExport Sketch :public Base::Persistence
int addEllipse(const Part::GeomEllipse &ellipse, bool fixed=false);
/// add an arc of ellipse
int addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed=false);
/// add an arc of hyperbola
int addArcOfHyperbola(const Part::GeomArcOfHyperbola &hyperbolaSegment, bool fixed=false);
//@}


Expand Down Expand Up @@ -317,7 +319,7 @@ class SketcherExport Sketch :public Base::Persistence
//icstr should be the value returned by addXXXXConstraint
//see more info in respective function in GCS.
double calculateConstraintError(int icstr) { return GCSsys.calculateConstraintErrorByTag(icstr);}

/// Returns the size of the Geometry
int getGeometrySize(void) const {return Geoms.size();}

Expand All @@ -328,7 +330,8 @@ class SketcherExport Sketch :public Base::Persistence
Arc = 3, // 3 Points(start,end,mid), (4)+5 Parameters((x1,y1,x2,y2),x,y,r,a1,a2)
Circle = 4, // 1 Point(mid), 3 Parameters(x,y,r)
Ellipse = 5, // 1 Point(mid), 5 Parameters(x,y,r1,r2,phi) phi=angle xaxis of elipse with respect of sketch xaxis
ArcOfEllipse = 6
ArcOfEllipse = 6,
ArcOfHyperbola = 7
};

float SolveTime;
Expand Down Expand Up @@ -375,6 +378,7 @@ class SketcherExport Sketch :public Base::Persistence
std::vector<GCS::Circle> Circles;
std::vector<GCS::Ellipse> Ellipses;
std::vector<GCS::ArcOfEllipse> ArcsOfEllipse;
std::vector<GCS::ArcOfHyperbola> ArcsOfHyperbola;

bool isInitMove;
bool isFine;
Expand Down
Loading

0 comments on commit 590e3fb

Please sign in to comment.