Merge pull request #475 from abdullahtahiriyo/bspline_stage1b_2017_firstdeliverable
Bspline stage1b 2017 firstdeliverable
This commit is contained in:
commit
9b49777700
|
@ -290,6 +290,28 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
|||
this->getConstraintPtr()->ThirdPos = (Sketcher::PointPos) intArg4;
|
||||
return 0;
|
||||
}
|
||||
else if (strstr(ConstraintType,"InternalAlignment") != NULL) { // InteralAlignment with InternalElementIndex argument
|
||||
this->getConstraintPtr()->Type = InternalAlignment;
|
||||
|
||||
valid = true;
|
||||
|
||||
if(strstr(ConstraintType,"BSplineControlPoint") != NULL) {
|
||||
this->getConstraintPtr()->AlignmentType=BSplineControlPoint;
|
||||
}
|
||||
else {
|
||||
this->getConstraintPtr()->AlignmentType=Undef;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) intArg2;
|
||||
this->getConstraintPtr()->Second = intArg3;
|
||||
this->getConstraintPtr()->InternalAlignmentIndex = intArg4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
if (valid) {
|
||||
this->getConstraintPtr()->First = intArg1;
|
||||
this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) intArg2;
|
||||
|
|
|
@ -671,6 +671,32 @@ int Sketch::addBSpline(const Part::GeomBSplineCurve &bspline, bool fixed)
|
|||
std::vector<int> mult = bsp->getMultiplicities();
|
||||
int degree = bsp->getDegree();
|
||||
bool periodic = bsp->isPeriodic();
|
||||
|
||||
// OCC hack
|
||||
// c means there is a constraint on that weight, nc no constraint
|
||||
// OCC provides normalized weights when polynomic [1 1 1] [c c c] and unnormalized weights when rational [5 1 5] [c nc c]
|
||||
// then when changing from polynomic to rational, after the first solve any not-constrained pole circle gets normalized to 1.
|
||||
// This only happens when changing from polynomic to rational, any subsequent change remains unnormalized [5 1 5] [c nc nc]
|
||||
// This creates a visual problem that one of the poles shrinks to 1 mm when deleting an equality constraint.
|
||||
|
||||
int lastoneindex = -1;
|
||||
int countones = 0;
|
||||
double lastnotone = 1.0;
|
||||
|
||||
for(size_t i = 0; i < weights.size(); i++) {
|
||||
if(weights[i] != 1.0) {
|
||||
lastnotone = weights[i];
|
||||
}
|
||||
else { // is 1.0
|
||||
lastoneindex = i;
|
||||
countones++;
|
||||
}
|
||||
}
|
||||
|
||||
if (countones == 1)
|
||||
weights[lastoneindex] = (lastnotone * 0.99);
|
||||
|
||||
// end hack
|
||||
|
||||
Base::Vector3d startPnt = bsp->getStartPoint();
|
||||
Base::Vector3d endPnt = bsp->getEndPoint();
|
||||
|
|
|
@ -4326,6 +4326,8 @@ public:
|
|||
, EditCurve(2)
|
||||
, CurrentConstraint(0)
|
||||
, ConstrMethod(constructionMethod)
|
||||
, IsClosed(false)
|
||||
, FirstPoleGeoId(-2000)
|
||||
{
|
||||
std::vector<AutoConstraint> sugConstr1;
|
||||
sugConstr.push_back(sugConstr1);
|
||||
|
@ -4382,20 +4384,109 @@ public:
|
|||
EditCurve[0] = onSketchPos;
|
||||
|
||||
Mode = STATUS_SEEK_ADDITIONAL_CONTROLPOINTS;
|
||||
|
||||
// insert circle point for pole, defer internal alignment constraining.
|
||||
try {
|
||||
|
||||
Gui::Command::openCommand("Add Pole circle");
|
||||
|
||||
//Add pole
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),10),True)",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
EditCurve[0].x,EditCurve[0].y);
|
||||
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
|
||||
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//Gui::Command::commitCommand();
|
||||
|
||||
//static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
FirstPoleGeoId = getHighestCurveIndex();
|
||||
|
||||
// add auto constraints on pole
|
||||
if (sugConstr[CurrentConstraint].size() > 0) {
|
||||
createAutoConstraints(sugConstr[CurrentConstraint], FirstPoleGeoId, Sketcher::mid, false);
|
||||
}
|
||||
|
||||
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
std::vector<AutoConstraint> sugConstrN;
|
||||
sugConstr.push_back(sugConstrN);
|
||||
CurrentConstraint++;
|
||||
|
||||
}
|
||||
else if (Mode == STATUS_SEEK_ADDITIONAL_CONTROLPOINTS) {
|
||||
EditCurve[EditCurve.size()-1] = onSketchPos;
|
||||
|
||||
// finish adding controlpoints on double click
|
||||
if (EditCurve[EditCurve.size()-2] == EditCurve[EditCurve.size()-1]) {
|
||||
EditCurve.pop_back();
|
||||
Mode = STATUS_CLOSE;
|
||||
// check if coincident with first pole
|
||||
for(std::vector<AutoConstraint>::const_iterator it = sugConstr[CurrentConstraint].begin(); it != sugConstr[CurrentConstraint].end(); it++) {
|
||||
if( (*it).Type == Sketcher::Coincident && (*it).GeoId == FirstPoleGeoId && (*it).PosId == Sketcher::mid ) {
|
||||
|
||||
IsClosed = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (IsClosed) {
|
||||
Mode = STATUS_CLOSE;
|
||||
|
||||
if (ConstrMethod == 1) { // if periodic we do not need the last pole
|
||||
EditCurve.pop_back();
|
||||
sugConstr.pop_back();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// insert circle point for pole, defer internal alignment constraining.
|
||||
try {
|
||||
|
||||
//Gui::Command::openCommand("Add Pole circle");
|
||||
|
||||
//Add pole
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),10),True)",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
EditCurve[EditCurve.size()-1].x,EditCurve[EditCurve.size()-1].y);
|
||||
|
||||
if(EditCurve.size() == 2) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
|
||||
sketchgui->getObject()->getNameInDocument(), FirstPoleGeoId, round( (EditCurve[1]-EditCurve[0]).Length()/6 ));
|
||||
}
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Equal',%d,%d)) ",
|
||||
sketchgui->getObject()->getNameInDocument(), FirstPoleGeoId, FirstPoleGeoId+ EditCurve.size()-1);
|
||||
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
|
||||
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//Gui::Command::commitCommand();
|
||||
|
||||
//static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
// add auto constraints on pole
|
||||
if (sugConstr[CurrentConstraint].size() > 0) {
|
||||
createAutoConstraints(sugConstr[CurrentConstraint], FirstPoleGeoId + EditCurve.size()-1, Sketcher::mid, false);
|
||||
}
|
||||
|
||||
//static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
if (!IsClosed) {
|
||||
EditCurve.resize(EditCurve.size() + 1); // add one place for a pole
|
||||
std::vector<AutoConstraint> sugConstrN;
|
||||
sugConstr.push_back(sugConstrN);
|
||||
|
@ -4432,25 +4523,34 @@ public:
|
|||
|
||||
try {
|
||||
|
||||
Gui::Command::openCommand("Add B-spline curve");
|
||||
//Gui::Command::openCommand("Add B-spline curve");
|
||||
|
||||
//Add arc of parabola
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.addGeometry(Part.BSplineCurve"
|
||||
"(%s,%s),"
|
||||
"%s)",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
controlpoints.c_str(),
|
||||
ConstrMethod == 0 ?"False":"True",
|
||||
geometryCreationMode==Construction?"True":"False");
|
||||
//Add arc of parabola
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.addGeometry(Part.BSplineCurve"
|
||||
"(%s,%s),"
|
||||
"%s)",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
controlpoints.c_str(),
|
||||
ConstrMethod == 0 ?"False":"True",
|
||||
geometryCreationMode==Construction?"True":"False");
|
||||
|
||||
currentgeoid++;
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.ExposeInternalGeometry(%d)",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
currentgeoid);
|
||||
currentgeoid++;
|
||||
|
||||
// Constraint pole circles to bspline.
|
||||
std::stringstream cstream;
|
||||
|
||||
cstream << "conList = []\n";
|
||||
|
||||
for (size_t i = 0; i < EditCurve.size(); i++) {
|
||||
cstream << "conList.append(Sketcher.Constraint('InternalAlignment:Sketcher::BSplineControlPoint'," << FirstPoleGeoId+i
|
||||
<< "," << Sketcher::mid << "," << currentgeoid << "," << i << "))\n";
|
||||
}
|
||||
|
||||
cstream << "App.ActiveDocument."<< sketchgui->getObject()->getNameInDocument() << ".addConstraint(conList)\n";
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc, cstream.str().c_str());
|
||||
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
|
@ -4469,15 +4569,6 @@ public:
|
|||
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
int poleindex=0;
|
||||
for(std::vector<std::vector<AutoConstraint>>::iterator it=sugConstr.begin(); it != sugConstr.end(); it++, poleindex++) {
|
||||
// add auto constraints
|
||||
if ((*it).size() > 0) {
|
||||
createAutoConstraints((*it), currentgeoid+1+poleindex, Sketcher::mid);
|
||||
(*it).clear();
|
||||
}
|
||||
}
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
|
||||
|
||||
|
@ -4495,6 +4586,15 @@ public:
|
|||
sketchgui->drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
|
||||
sugConstr.clear();
|
||||
|
||||
std::vector<AutoConstraint> sugConstr1;
|
||||
sugConstr.push_back(sugConstr1);
|
||||
|
||||
CurrentConstraint=0;
|
||||
IsClosed=false;
|
||||
|
||||
/* It is ok not to call to purgeHandler
|
||||
* in continuous creation mode because the
|
||||
* handler is destroyed by the quit() method on pressing the
|
||||
|
@ -4506,6 +4606,60 @@ public:
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void quit(void) {
|
||||
// We must see if we need to create a BSpline before cancelling everything
|
||||
// and now just like any other Handler,
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
|
||||
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
|
||||
|
||||
if (CurrentConstraint > 1) {
|
||||
// create bspline from existing poles
|
||||
Mode=STATUS_CLOSE;
|
||||
EditCurve.pop_back();
|
||||
this->releaseButton(Base::Vector2d(0.f,0.f));
|
||||
}
|
||||
else if(CurrentConstraint == 1) {
|
||||
// if we just have one point and we can not close anything, then cancel this creation but continue according to continuous mode
|
||||
//sketchgui->getDocument()->undo(1);
|
||||
|
||||
Gui::Command::abortCommand();
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
|
||||
|
||||
if(autoRecompute)
|
||||
Gui::Command::updateActive();
|
||||
else
|
||||
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
if(!continuousMode){
|
||||
DrawSketchHandler::quit();
|
||||
}
|
||||
else {
|
||||
// This code disregards existing data and enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_FIRST_CONTROLPOINT;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
|
||||
sugConstr.clear();
|
||||
|
||||
std::vector<AutoConstraint> sugConstr1;
|
||||
sugConstr.push_back(sugConstr1);
|
||||
|
||||
CurrentConstraint=0;
|
||||
IsClosed=false;
|
||||
}
|
||||
}
|
||||
else { // we have no data (CurrentConstraint == 0) so user when right-clicking really wants to exit
|
||||
DrawSketchHandler::quit();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
SELECT_MODE Mode;
|
||||
|
||||
|
@ -4515,6 +4669,8 @@ protected:
|
|||
|
||||
int CurrentConstraint;
|
||||
int ConstrMethod;
|
||||
bool IsClosed;
|
||||
int FirstPoleGeoId;
|
||||
};
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherCreateBSpline)
|
||||
|
|
|
@ -383,15 +383,18 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint> &suggested
|
|||
}
|
||||
|
||||
void DrawSketchHandler::createAutoConstraints(const std::vector<AutoConstraint> &autoConstrs,
|
||||
int geoId1, Sketcher::PointPos posId1)
|
||||
int geoId1, Sketcher::PointPos posId1, bool createowncommand /*= true*/)
|
||||
{
|
||||
if (!sketchgui->Autoconstraints.getValue())
|
||||
return; // If Autoconstraints property is not set quit
|
||||
|
||||
if (autoConstrs.size() > 0) {
|
||||
// Open the Command
|
||||
Gui::Command::openCommand("Add auto constraints");
|
||||
|
||||
|
||||
if(createowncommand) {
|
||||
// Open the Command
|
||||
Gui::Command::openCommand("Add auto constraints");
|
||||
}
|
||||
|
||||
// Iterate through constraints
|
||||
std::vector<AutoConstraint>::const_iterator it = autoConstrs.begin();
|
||||
for (; it != autoConstrs.end(); ++it) {
|
||||
|
@ -512,7 +515,9 @@ void DrawSketchHandler::createAutoConstraints(const std::vector<AutoConstraint>
|
|||
break;
|
||||
}
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
if(createowncommand) {
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
//Gui::Command::updateActive(); // There is already an recompute in each command creation, this is redundant.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,8 +82,10 @@ public:
|
|||
int seekAutoConstraint(std::vector<AutoConstraint> &suggestedConstraints,
|
||||
const Base::Vector2d &Pos, const Base::Vector2d &Dir,
|
||||
AutoConstraint::TargetType type = AutoConstraint::VERTEX);
|
||||
// createowncommand indicates whether a separate command shall be create and committed (for example for undo purposes) or not
|
||||
// is not it is the responsibility of the developer to create and commit the command appropriately.
|
||||
void createAutoConstraints(const std::vector<AutoConstraint> &autoConstrs,
|
||||
int geoId, Sketcher::PointPos pointPos=Sketcher::none);
|
||||
int geoId, Sketcher::PointPos pointPos=Sketcher::none, bool createowncommand = true);
|
||||
|
||||
void setPositionText(const Base::Vector2d &Pos, const SbString &text);
|
||||
void setPositionText(const Base::Vector2d &Pos);
|
||||
|
|
Loading…
Reference in New Issue
Block a user