From 3eb8f2111673835f7571bd4e1d7c19a61e344cba Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Mon, 20 Jul 2015 07:47:29 +0200 Subject: [PATCH] Sketcher: New Features: Python copy and array commands ====================================================== Two new python commands (no UI yet). Copy: Copies the geoids in a list by a displacement given by a Vector3d: App.ActiveDocument.Sketch001.addCopy([0,1,2,3,4,5],App.Vector(150,150,0)) Array: Copies the geoids in a list cols times in the displacement vector direction and rows times in the perpendicular to the displacement vector: App.ActiveDocument.Sketch001.addArray([0,1,2,3,4,5], App.Vector(150,150,0),3,4) N.B.: You need to recompute or solve to update the view App.ActiveDocument.recompute() or App.ActiveDocument.Sketch001.solve() --- src/Mod/Sketcher/App/SketchObject.cpp | 132 +++++++++++++++++++++ src/Mod/Sketcher/App/SketchObject.h | 2 + src/Mod/Sketcher/App/SketchObjectPy.xml | 12 +- src/Mod/Sketcher/App/SketchObjectPyImp.cpp | 71 +++++++++++ 4 files changed, 216 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 2e8ea27bc..9d51c64d3 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -2004,6 +2004,138 @@ int SketchObject::addSymmetric(const std::vector &geoIdList, int refGeoId, return Geometry.getSize()-1; } +int SketchObject::addCopy(const std::vector &geoIdList, const Base::Vector3d& displacement, int csize/*=2*/, int rsize/*=1*/) +{ + const std::vector< Part::Geometry * > &geovals = getInternalGeometry(); + std::vector< Part::Geometry * > newgeoVals(geovals); + + const std::vector< Constraint * > &constrvals = this->Constraints.getValues(); + std::vector< Constraint * > newconstrVals(constrvals); + + int cgeoid = getHighestCurveIndex()+1; + + std::map geoIdMap; + + Base::Vector3d perpendicularDisplacement = Base::Vector3d(displacement.y,-displacement.x,0); + + int x,y; + + for (y=0;y::const_iterator it = geoIdList.begin(); it != geoIdList.end(); ++it) { + const Part::Geometry *geo = getGeometry(*it); + Part::Geometry *geosym = geo->clone(); + + // Handle Geometry + if(geosym->getTypeId() == Part::GeomLineSegment::getClassTypeId()){ + Part::GeomLineSegment *geosymline = static_cast(geosym); + Base::Vector3d sp = geosymline->getStartPoint(); + Base::Vector3d ep = geosymline->getEndPoint(); + + geosymline->setPoints(sp+double(x)*displacement+double(y)*perpendicularDisplacement, + ep+double(x)*displacement+double(y)*perpendicularDisplacement); + } + else if(geosym->getTypeId() == Part::GeomCircle::getClassTypeId()){ + Part::GeomCircle *geosymcircle = static_cast(geosym); + Base::Vector3d cp = geosymcircle->getCenter(); + + geosymcircle->setCenter(cp+double(x)*displacement+double(y)*perpendicularDisplacement); + } + else if(geosym->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){ + Part::GeomArcOfCircle *geoaoc = static_cast(geosym); + Base::Vector3d cp = geoaoc->getCenter(); + Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement; + + geoaoc->setCenter(scp); + } + else if(geosym->getTypeId() == Part::GeomEllipse::getClassTypeId()){ + Part::GeomEllipse *geosymellipse = static_cast(geosym); + Base::Vector3d cp = geosymellipse->getCenter(); + Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement; + + geosymellipse->setCenter(scp); + } + else if(geosym->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){ + Part::GeomArcOfEllipse *geosymaoe = static_cast(geosym); + Base::Vector3d cp = geosymaoe->getCenter(); + Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement; + + geosymaoe->setCenter(scp); + } + else if(geosym->getTypeId() == Part::GeomPoint::getClassTypeId()){ + Part::GeomPoint *geosympoint = static_cast(geosym); + Base::Vector3d cp = geosympoint->getPoint(); + + geosympoint->setPoint(cp+double(x)*displacement+double(y)*perpendicularDisplacement); + } + else { + Base::Console().Error("Unsupported Geometry!! Just copying it.\n"); + } + + newgeoVals.push_back(geosym); + geoIdMap.insert(std::make_pair(*it, cgeoid)); + cgeoid++; + } + + // handle constraints + for (std::vector::const_iterator it = constrvals.begin(); it != constrvals.end(); ++it) { + + std::vector::const_iterator fit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->First); + + if(fit != geoIdList.end()) { // if First of constraint is in geoIdList + + if( (*it)->Second == Constraint::GeoUndef /*&& (*it)->Third == Constraint::GeoUndef*/) { + Constraint *constNew = (*it)->clone(); + constNew->First = geoIdMap[(*it)->First]; + newconstrVals.push_back(constNew); + } + else { // other geoids intervene in this constraint + + std::vector::const_iterator sit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Second); + + if(sit != geoIdList.end()) { // Second is also in the list + + if( (*it)->Third == Constraint::GeoUndef ) { + Constraint *constNew = (*it)->clone(); + constNew->First = geoIdMap[(*it)->First]; + constNew->Second = geoIdMap[(*it)->Second]; + newconstrVals.push_back(constNew); + } + else { + std::vector::const_iterator tit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Third); + + if(tit != geoIdList.end()) { // Third is also in the list + Constraint *constNew = (*it)->clone(); + constNew->First = geoIdMap[(*it)->First]; + constNew->Second = geoIdMap[(*it)->Second]; + constNew->Third = geoIdMap[(*it)->Third]; + + newconstrVals.push_back(constNew); + } + } + } + } + } + } + + + geoIdMap.clear(); // after each creation reset map so that the key-value is univoque + } + } + + Geometry.setValues(newgeoVals); + Constraints.acceptGeometry(getCompleteGeometry()); + rebuildVertexIndex(); + + if( newconstrVals.size() > constrvals.size() ) + Constraints.setValues(newconstrVals); + + return Geometry.getSize()-1; + +} int SketchObject::ExposeInternalGeometry(int GeoId) { diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index d5554c66c..8717d6204 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -152,6 +152,8 @@ public: int trim(int geoId, const Base::Vector3d& point); /// adds symmetric geometric elements with respect to the refGeoId (line or point) int addSymmetric(const std::vector &geoIdList, int refGeoId, Sketcher::PointPos refPosId=Sketcher::none); + /// adds a copy of the geometric elements displaced by the displacement vector + int addCopy(const std::vector &geoIdList, const Base::Vector3d& displacement, int csize=2, int rsize=1); /// Exposes all internal geometry of an object supporting internal geometry /*! * \return -1 on error diff --git a/src/Mod/Sketcher/App/SketchObjectPy.xml b/src/Mod/Sketcher/App/SketchObjectPy.xml index 30877b1b9..52e966f31 100644 --- a/src/Mod/Sketcher/App/SketchObjectPy.xml +++ b/src/Mod/Sketcher/App/SketchObjectPy.xml @@ -136,7 +136,17 @@ add a symmetric geometric objects to the sketch with respect to a reference point or line - + + + + add a copy of geometric objects to the sketch displaced by a vector3d + + + + + add an array of size cols by rows where each element is a copy of the selected geometric objects displaced by a vector3d in the cols direction and by a vector perpendicular to it in the rows direction + + Exposes all internal geometry of an object supporting internal geometry diff --git a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp index 46c2beaa7..823d632b5 100644 --- a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp +++ b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp @@ -792,6 +792,77 @@ PyObject* SketchObjectPy::addSymmetric(PyObject *args) } +PyObject* SketchObjectPy::addCopy(PyObject *args) +{ + PyObject *pcObj, *pcVect; + + if (!PyArg_ParseTuple(args, "OO!", &pcObj, &(Base::VectorPy::Type), &pcVect)) + return 0; + + Base::Vector3d vect = static_cast(pcVect)->value(); + + if (PyObject_TypeCheck(pcObj, &(PyList_Type)) || + PyObject_TypeCheck(pcObj, &(PyTuple_Type))) { + std::vector geoIdList; + Py::Sequence list(pcObj); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + if (PyInt_Check((*it).ptr())) + geoIdList.push_back(PyInt_AsLong((*it).ptr())); + } + + int ret = this->getSketchObjectPtr()->addCopy(geoIdList,vect) + 1; + + 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; iob_type->tp_name; + throw Py::TypeError(error); +} + +PyObject* SketchObjectPy::addArray(PyObject *args) +{ + PyObject *pcObj, *pcVect; + int rows,cols; + + if (!PyArg_ParseTuple(args, "OO!ii", &pcObj, &(Base::VectorPy::Type), &pcVect,&rows,&cols)) + return 0; + + Base::Vector3d vect = static_cast(pcVect)->value(); + + if (PyObject_TypeCheck(pcObj, &(PyList_Type)) || + PyObject_TypeCheck(pcObj, &(PyTuple_Type))) { + std::vector geoIdList; + Py::Sequence list(pcObj); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + if (PyInt_Check((*it).ptr())) + geoIdList.push_back(PyInt_AsLong((*it).ptr())); + } + + int ret = this->getSketchObjectPtr()->addCopy(geoIdList,vect,rows,cols) + 1; + + if(ret == -1) + throw Py::TypeError("Copy operation unsuccessful!"); + + + Py_Return; + } + + std::string error = std::string("type must be list of GeoIds, not "); + error += pcObj->ob_type->tp_name; + throw Py::TypeError(error); +} + PyObject* SketchObjectPy::calculateAngleViaPoint(PyObject *args) { int GeoId1=0, GeoId2=0;