Sketcher: Fix Array/copy/move
============================== Do not copy/array internal alignment geometry if the geometry it defines is not part of the operation. Silently ignore it. If the reference for the operation is one such geometry (or it is the only one), then abort the operation.
This commit is contained in:
committed by
abdullahtahiriyo
parent
6aca180d7e
commit
c3acfcc0a0
@@ -4033,6 +4033,27 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
||||
|
||||
if(x == 0 && y == 0) { // the reference for constraining array elements is the first valid point of the first element
|
||||
const Part::Geometry *geo = getGeometry(*(newgeoIdList.begin()));
|
||||
|
||||
auto gf = GeometryFacade::getFacade(geo);
|
||||
|
||||
if(gf->isInternalAligned() && !moveonly) {
|
||||
// only add this geometry if the corresponding geometry it defines is also in the list.
|
||||
int definedGeo = Constraint::GeoUndef;
|
||||
|
||||
for( auto c : Constraints.getValues()) {
|
||||
if(c->Type == Sketcher::InternalAlignment && c->First == *(newgeoIdList.begin())) {
|
||||
definedGeo = c->Second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(std::find(newgeoIdList.begin(), newgeoIdList.end(), definedGeo) == newgeoIdList.end() ) {
|
||||
// the first element setting the reference is an internal alignment geometry, wherein the geometry
|
||||
// it defines is not part of the copy operation.
|
||||
THROWM(Base::ValueError,"A move/copy/array operation on an internal alignment geometry is only possible together with the geometry it defines.")
|
||||
}
|
||||
}
|
||||
|
||||
refgeoid=*(newgeoIdList.begin());
|
||||
currentrowfirstgeoid = refgeoid;
|
||||
iterfirstgeoid = refgeoid;
|
||||
@@ -4062,9 +4083,27 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
||||
|
||||
Part::Geometry *geocopy;
|
||||
|
||||
auto gf = GeometryFacade::getFacade(geo);
|
||||
|
||||
if(gf->isInternalAligned() && !moveonly) {
|
||||
// only add this geometry if the corresponding geometry it defines is also in the list.
|
||||
int definedGeo = Constraint::GeoUndef;
|
||||
|
||||
for( auto c : Constraints.getValues()) {
|
||||
if(c->Type == Sketcher::InternalAlignment && c->First == *it) {
|
||||
definedGeo = c->Second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(std::find(newgeoIdList.begin(), newgeoIdList.end(), definedGeo) == newgeoIdList.end() )
|
||||
continue; // we should not copy internal alignment geometry, unless the element they define is also mirrored
|
||||
|
||||
}
|
||||
|
||||
// We have already cloned all geometry and constraints, we only need a copy if not moving
|
||||
if(!moveonly)
|
||||
geocopy = geo->copy(); // make a copy of the pointer for undo even if moving
|
||||
geocopy = geo->copy();
|
||||
else
|
||||
geocopy = newgeoVals[*it];
|
||||
|
||||
@@ -4183,9 +4222,9 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
||||
// handle geometry constraints
|
||||
for (std::vector<Constraint *>::const_iterator it = constrvals.begin(); it != constrvals.end(); ++it) {
|
||||
|
||||
std::vector<int>::const_iterator fit=std::find(newgeoIdList.begin(), newgeoIdList.end(), (*it)->First);
|
||||
auto fit = geoIdMap.find((*it)->First);
|
||||
|
||||
if(fit != newgeoIdList.end()) { // if First of constraint is in geoIdList
|
||||
if(fit != geoIdMap.end()) { // if First of constraint is in geoIdList
|
||||
|
||||
if( (*it)->Second == Constraint::GeoUndef /*&& (*it)->Third == Constraint::GeoUndef*/) {
|
||||
if( ((*it)->Type != Sketcher::DistanceX && (*it)->Type != Sketcher::DistanceY ) ||
|
||||
@@ -4200,7 +4239,7 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
||||
Constraint *constNew = (*it)->copy();
|
||||
constNew->Type = Sketcher::Equal;
|
||||
constNew->isDriving = true;
|
||||
constNew->Second = geoIdMap[(*it)->First]; // first is already (*it->First)
|
||||
constNew->Second = fit->second; // first is already (*it->First)
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
else if ((*it)->Type == Sketcher::Angle && clone){
|
||||
@@ -4208,21 +4247,21 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
||||
Constraint *constNew = (*it)->copy();
|
||||
constNew->Type = Sketcher::Parallel;
|
||||
constNew->isDriving = true;
|
||||
constNew->Second = geoIdMap[(*it)->First]; // first is already (*it->First)
|
||||
constNew->Second = fit->second; // first is already (*it->First)
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
else {
|
||||
Constraint *constNew = (*it)->copy();
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
constNew->First = fit->second;
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // other geoids intervene in this constraint
|
||||
|
||||
std::vector<int>::const_iterator sit=std::find(newgeoIdList.begin(), newgeoIdList.end(), (*it)->Second);
|
||||
auto sit = geoIdMap.find((*it)->Second);
|
||||
|
||||
if(sit != newgeoIdList.end()) { // Second is also in the list
|
||||
if(sit != geoIdMap.end()) { // Second is also in the list
|
||||
if( (*it)->Third == Constraint::GeoUndef ) {
|
||||
if (((*it)->Type == Sketcher::DistanceX ||
|
||||
(*it)->Type == Sketcher::DistanceY ||
|
||||
@@ -4232,25 +4271,25 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
||||
constNew->Type = Sketcher::Equal;
|
||||
constNew->isDriving = true;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Second = geoIdMap[(*it)->First]; // first is already (*it->First)
|
||||
constNew->Second = fit->second; // first is already (*it->First)
|
||||
constNew->SecondPos = Sketcher::none;
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
else {
|
||||
else { // this includes InternalAlignment constraints
|
||||
Constraint *constNew = (*it)->copy();
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
constNew->Second = geoIdMap[(*it)->Second];
|
||||
constNew->First = fit->second;
|
||||
constNew->Second = sit->second;
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::vector<int>::const_iterator tit=std::find(newgeoIdList.begin(), newgeoIdList.end(), (*it)->Third);
|
||||
auto tit = geoIdMap.find((*it)->Third);
|
||||
|
||||
if(tit != newgeoIdList.end()) { // Third is also in the list
|
||||
if(tit != geoIdMap.end()) { // Third is also in the list
|
||||
Constraint *constNew = (*it)->copy();
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
constNew->Second = geoIdMap[(*it)->Second];
|
||||
constNew->Third = geoIdMap[(*it)->Third];
|
||||
constNew->First = fit->second;
|
||||
constNew->Second = sit->second;
|
||||
constNew->Third = tit->second;
|
||||
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
|
||||
@@ -1138,19 +1138,25 @@ PyObject* SketchObjectPy::addCopy(PyObject *args)
|
||||
#endif
|
||||
}
|
||||
|
||||
int ret = this->getSketchObjectPtr()->addCopy(geoIdList, vect, false, PyObject_IsTrue(clone) ? true : false) + 1;
|
||||
try {
|
||||
int ret = this->getSketchObjectPtr()->addCopy(geoIdList, vect, false, PyObject_IsTrue(clone) ? true : false) + 1;
|
||||
|
||||
if(ret == -1)
|
||||
throw Py::TypeError("Copy operation unsuccessful!");
|
||||
if(ret == -1)
|
||||
throw Py::TypeError("Copy operation unsuccessful!");
|
||||
|
||||
std::size_t numGeo = geoIdList.size();
|
||||
Py::Tuple tuple(numGeo);
|
||||
for (std::size_t i=0; i<numGeo; ++i) {
|
||||
int geoId = ret - int(numGeo - i);
|
||||
tuple.setItem(i, Py::Long(geoId));
|
||||
std::size_t numGeo = geoIdList.size();
|
||||
Py::Tuple tuple(numGeo);
|
||||
for (std::size_t i=0; i<numGeo; ++i) {
|
||||
int geoId = ret - int(numGeo - i);
|
||||
tuple.setItem(i, Py::Long(geoId));
|
||||
}
|
||||
|
||||
return Py::new_reference_to(tuple);
|
||||
}
|
||||
catch(const Base::ValueError & e) {
|
||||
throw Py::ValueError(e.getMessage());
|
||||
}
|
||||
|
||||
return Py::new_reference_to(tuple);
|
||||
}
|
||||
|
||||
std::string error = std::string("type must be list of GeoIds, not ");
|
||||
@@ -1219,11 +1225,18 @@ PyObject* SketchObjectPy::addRectangularArray(PyObject *args)
|
||||
#endif
|
||||
}
|
||||
|
||||
int ret = this->getSketchObjectPtr()->addCopy(geoIdList,vect, false, PyObject_IsTrue(clone) ? true : false,
|
||||
rows, cols, PyObject_IsTrue(constraindisplacement) ? true : false, perpscale) + 1;
|
||||
try {
|
||||
int ret = this->getSketchObjectPtr()->addCopy(geoIdList,vect, false, PyObject_IsTrue(clone) ? true : false,
|
||||
rows, cols, PyObject_IsTrue(constraindisplacement) ? true : false, perpscale) + 1;
|
||||
|
||||
if(ret == -1)
|
||||
throw Py::TypeError("Copy operation unsuccessful!");
|
||||
|
||||
}
|
||||
catch(const Base::ValueError & e) {
|
||||
throw Py::ValueError(e.getMessage());
|
||||
}
|
||||
|
||||
if(ret == -1)
|
||||
throw Py::TypeError("Copy operation unsuccessful!");
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user