Download src/Mod/CAM/App/AreaPyImp.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 23.4 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/App/AreaPyImp.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/CAM/App/AreaPyImp.cpp
-
curl -L -o AreaPyImp.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/App/AreaPyImp.cpp
23.4 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /**************************************************************************** | |
| * Copyright (c) 2017 Zheng Lei (realthunder) <realthunder.dev@gmail.com> * | |
| * * | |
| * This file is part of the FreeCAD CAx development system. * | |
| * * | |
| * This library is free software; you can redistribute it and/or * | |
| * modify it under the terms of the GNU Library General Public * | |
| * License as published by the Free Software Foundation; either * | |
| * version 2 of the License, or (at your option) any later version. * | |
| * * | |
| * This library is distributed in the hope that it will be useful, * | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
| * GNU Library General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Library General Public * | |
| * License along with this library; see the file COPYING.LIB. If not, * | |
| * write to the Free Software Foundation, Inc., 59 Temple Place, * | |
| * Suite 330, Boston, MA 02111-1307, USA * | |
| * * | |
| ****************************************************************************/ | |
| // inclusion of the generated files (generated out of AreaPy.xml) | |
| static PyObject* areaAbort(PyObject*, PyObject* args, PyObject* kwd) | |
| { | |
| static const std::array<const char*, 2> kwlist {"aborting", nullptr}; | |
| PyObject* pObj = Py_True; | |
| if (!Base::Wrapped_ParseTupleAndKeywords(args, kwd, "|O!", kwlist, &PyBool_Type, &pObj)) { | |
| return nullptr; | |
| } | |
| Area::abort(Base::asBoolean(pObj)); | |
| Py_Return; | |
| } | |
| static PyObject* areaSetParams(PyObject*, PyObject* args, PyObject* kwd) | |
| { | |
| static const std::array<const char*, 43> kwlist { | |
| PARAM_FIELD_STRINGS(NAME, AREA_PARAMS_STATIC_CONF), | |
| nullptr | |
| }; | |
| if (args && PySequence_Size(args) > 0) { | |
| PyErr_SetString(PyExc_ValueError, "Non-keyword argument is not supported"); | |
| } | |
| // Declare variables defined in the NAME field of the CONF parameter list | |
| PARAM_PY_DECLARE(PARAM_FNAME, AREA_PARAMS_STATIC_CONF); | |
| AreaStaticParams params = Area::getDefaultParams(); | |
| // populate the CONF variables with params | |
| PARAM_FOREACH(AREA_SET, AREA_PARAMS_STATIC_CONF) | |
| // Parse arguments to overwrite CONF variables | |
| if (!Base::Wrapped_ParseTupleAndKeywords( | |
| args, | |
| kwd, | |
| "|" PARAM_PY_KWDS(AREA_PARAMS_STATIC_CONF), | |
| kwlist, | |
| PARAM_REF(PARAM_FNAME, AREA_PARAMS_STATIC_CONF) | |
| )) { | |
| return nullptr; | |
| } | |
| // populate 'params' with the CONF variables | |
| PARAM_FOREACH(AREA_GET, AREA_PARAMS_STATIC_CONF) | |
| Area::setDefaultParams(params); | |
| Py_INCREF(Py_None); | |
| return Py_None; | |
| } | |
| static PyObject* areaGetParams(PyObject*, PyObject* args) | |
| { | |
| if (!PyArg_ParseTuple(args, "")) { | |
| return nullptr; | |
| } | |
| const AreaStaticParams& params = Area::getDefaultParams(); | |
| PyObject* dict = PyDict_New(); | |
| PARAM_PY_DICT_SET_VALUE(dict, NAME, AREA_SRC, AREA_PARAMS_STATIC_CONF) | |
| return dict; | |
| } | |
| static PyObject* areaGetParamsDesc(PyObject*, PyObject* args, PyObject* kwd) | |
| { | |
| PyObject* pcObj = Py_False; | |
| static const std::array<const char*, 2> kwlist {"as_string", nullptr}; | |
| if (!Base::Wrapped_ParseTupleAndKeywords(args, kwd, "|O!", kwlist, &PyBool_Type, &pcObj)) { | |
| return nullptr; | |
| } | |
| if (Base::asBoolean(pcObj)) { | |
| return PyUnicode_FromString(PARAM_PY_DOC(NAME, AREA_PARAMS_STATIC_CONF)); | |
| } | |
| PyObject* dict = PyDict_New(); | |
| PARAM_PY_DICT_SET_DOC(dict, NAME, AREA_PARAMS_STATIC_CONF) | |
| return dict; | |
| } | |
| static const PyMethodDef areaOverrides[] = { | |
| {"setParams", | |
| nullptr, | |
| 0, | |
| "setParam(key=value...): Set algorithm parameters. You can call getParamsDesc() to \n" | |
| "get a list of supported parameters and their descriptions.\n" PARAM_PY_DOC(NAME, AREA_PARAMS_CONF)}, | |
| { | |
| "add", | |
| nullptr, | |
| 0, | |
| "add((shape...)," PARAM_PY_ARGS_DOC( | |
| ARG, | |
| AREA_PARAMS_OPCODE | |
| ) "):\n" | |
| "Add TopoShape(s) with given operation code\n" PARAM_PY_DOC( | |
| ARG, | |
| AREA_PARAMS_OPCODE | |
| ) "\nThe first shape's wires will be unioned " | |
| "together regardless of the op code given\n" | |
| "(except for 'Compound'). Subsequent " | |
| "shape's wire will be combined using the " | |
| "op code.\n" | |
| "All shape wires shall be coplanar, and " | |
| "are used to determine a working plane for " | |
| "face\n" | |
| "making and offsetting. You can call " | |
| "setPlane() to supply a reference shape to " | |
| "determine\n" | |
| "the workplane in case the added shapes " | |
| "are all colinear lines.\n", | |
| }, | |
| { | |
| "makeOffset", | |
| nullptr, | |
| 0, | |
| "makeOffset(index=-1, " PARAM_PY_ARGS_DOC( | |
| ARG, | |
| AREA_PARAMS_OFFSET | |
| ) "):\n" | |
| "Make an 2D offset of the shape.\n" | |
| "\n* index (-1): the index of the section. -1 means all sections. " | |
| "No effect on planar shape.\n" PARAM_PY_DOC(ARG, AREA_PARAMS_OFFSET), | |
| }, | |
| { | |
| "makePocket", | |
| nullptr, | |
| 0, | |
| "makePocket(index=-1, " PARAM_PY_ARGS_DOC( | |
| ARG, | |
| AREA_PARAMS_POCKET | |
| ) "):\n" | |
| "Generate pocket toolpath of the shape.\n" | |
| "\n* index (-1): the index of the section. -1 means all sections. " | |
| "No effect on planar shape.\n" PARAM_PY_DOC(ARG, AREA_PARAMS_POCKET), | |
| }, | |
| { | |
| "makeSections", | |
| nullptr, | |
| 0, | |
| "makeSections(" PARAM_PY_ARGS_DOC( | |
| ARG, | |
| AREA_PARAMS_SECTION_EXTRA | |
| ) ", heights=[], plane=None):\n" | |
| "Make a list of area holding the sectioned children shapes " | |
| "on given heights\n" PARAM_PY_DOC( | |
| ARG, | |
| AREA_PARAMS_SECTION_EXTRA | |
| ) "\n* heights ([]): a list of " | |
| "section heights, the " | |
| "meaning of the value is " | |
| "determined by 'mode'.\n" | |
| "If not specified, the " | |
| "current SectionCount, and " | |
| "SectionOffset of this Area " | |
| "is used.\n" | |
| "\n* plane (None): optional " | |
| "shape to specify a section " | |
| "plane. If not give, the " | |
| "current workplane\n" | |
| "of this Area is used if " | |
| "section mode is " | |
| "'Workplane'.", | |
| }, | |
| { | |
| "getClearedArea", | |
| nullptr, | |
| 0, | |
| "getClearedArea(path, diameter, zmax, bbox):\n" | |
| "Gets the area cleared when a tool of the specified diameter follows the gcode represented " | |
| "in the path, ignoring cleared space above zmax and path segments that don't affect space " | |
| "within the x/y space of bbox.\n", | |
| }, | |
| { | |
| "getRestArea", | |
| nullptr, | |
| 0, | |
| "getRestArea(clearedAreas, diameter):\n" | |
| "Rest machining: gets the area left to be machined, assuming some of this area has already " | |
| "been cleared previous tool paths.\n" | |
| "clearedAreas: the regions already cleared.\n" | |
| "diameter: the tool diameter that finishes clearing this area.\n", | |
| }, | |
| {"toTopoShape", nullptr, 0, "toTopoShape():\n"}, | |
| {"setDefaultParams", | |
| reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)()>(areaSetParams)), | |
| METH_VARARGS | METH_KEYWORDS | METH_STATIC, | |
| "setDefaultParams(key=value...):\n" | |
| "Static method to set the default parameters of all following Path.Area, plus the following\n" | |
| "additional parameters.\n"}, | |
| {"getDefaultParams", | |
| (PyCFunction)areaGetParams, | |
| METH_VARARGS | METH_STATIC, | |
| "getDefaultParams(): Static method to return the current default parameters."}, | |
| { | |
| "abort", | |
| reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)()>(areaAbort)), | |
| METH_VARARGS | METH_KEYWORDS | METH_STATIC, | |
| "abort(aborting=True): Static method to abort any ongoing operation\n" | |
| "\nTo ensure no stray abortion is left in the previous operation, it is advised to " | |
| "manually clear\n" | |
| "the aborting flag by calling abort(False) before starting a new operation.", | |
| }, | |
| {"getParamsDesc", | |
| reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)()>(areaGetParamsDesc)), | |
| METH_VARARGS | METH_KEYWORDS | METH_STATIC, | |
| "getParamsDesc(as_string=False): Returns a list of supported parameters and their " | |
| "descriptions.\n" | |
| "\n* as_string: if False, then return a dictionary of documents of all supported parameters."}, | |
| }; | |
| struct AreaPyModifier | |
| { | |
| AreaPyModifier() | |
| { | |
| for (auto& method : Path::AreaPy::Methods) { | |
| if (!method.ml_name) { | |
| continue; | |
| } | |
| for (auto& entry : areaOverrides) { | |
| if (std::strcmp(method.ml_name, entry.ml_name) == 0) { | |
| if (entry.ml_doc) { | |
| method.ml_doc = entry.ml_doc; | |
| } | |
| if (entry.ml_meth) { | |
| method.ml_meth = entry.ml_meth; | |
| } | |
| if (entry.ml_flags) { | |
| method.ml_flags = entry.ml_flags; | |
| } | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| }; | |
| static AreaPyModifier mod; | |
| using namespace Path; | |
| // returns a string which represents the object e.g. when printed in python | |
| std::string AreaPy::representation() const | |
| { | |
| std::stringstream str; | |
| str << "<Area object at " << getAreaPtr() << ">"; | |
| return str.str(); | |
| } | |
| PyObject* AreaPy::PyMake(struct _typeobject*, PyObject* args, PyObject* kwd) // Python wrapper | |
| { | |
| AreaPy* ret = new AreaPy(new Area); | |
| if (!ret->setParams(args, kwd)) { | |
| Py_DecRef(ret); | |
| return nullptr; | |
| } | |
| // If setParams() was successful it increments the ref counter. | |
| // So, it must be decremented again. | |
| Py_DecRef(ret); | |
| return ret; | |
| } | |
| // constructor method | |
| int AreaPy::PyInit(PyObject*, PyObject*) | |
| { | |
| return 0; | |
| } | |
| PyObject* AreaPy::setPlane(PyObject* args) | |
| { | |
| PyObject* pcObj; | |
| if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) { | |
| return nullptr; | |
| } | |
| getAreaPtr()->setPlane(GET_TOPOSHAPE(pcObj)); | |
| Py_INCREF(this); | |
| return this; | |
| } | |
| PyObject* AreaPy::getShape(PyObject* args, PyObject* keywds) | |
| { | |
| PyObject* pcObj = Py_False; | |
| short index = -1; | |
| static const std::array<const char*, 3> kwlist {"index", "rebuild", nullptr}; | |
| if (!Base::Wrapped_ParseTupleAndKeywords(args, keywds, "|hO!", kwlist, &index, &PyBool_Type, &pcObj)) { | |
| return nullptr; | |
| } | |
| PY_TRY | |
| { | |
| if (Base::asBoolean(pcObj)) { | |
| getAreaPtr()->clean(); | |
| } | |
| return Py::new_reference_to(Part::shape2pyshape(getAreaPtr()->getShape(index))); | |
| } | |
| PY_CATCH_OCC | |
| } | |
| PyObject* AreaPy::add(PyObject* args, PyObject* keywds) | |
| { | |
| PARAM_PY_DECLARE_INIT(PARAM_FARG, AREA_PARAMS_OPCODE) | |
| PyObject* pcObj; | |
| // Strangely, PyArg_ParseTupleAndKeywords requires all arguments to be keyword based, | |
| // even non-optional ones? That doesn't make sense in python. Seems only in python 3 | |
| // they added '$' to address that issue. | |
| static const std::array<const char*, 3> kwlist { | |
| "shape", | |
| PARAM_FIELD_STRINGS(ARG, AREA_PARAMS_OPCODE), | |
| nullptr | |
| }; | |
| if (!Base::Wrapped_ParseTupleAndKeywords( | |
| args, | |
| keywds, | |
| "O|" PARAM_PY_KWDS(AREA_PARAMS_OPCODE), | |
| kwlist, | |
| &pcObj, | |
| PARAM_REF(PARAM_FARG, AREA_PARAMS_OPCODE) | |
| )) { | |
| return nullptr; | |
| } | |
| PY_TRY | |
| { | |
| if (PyObject_TypeCheck(pcObj, &(Part::TopoShapePy::Type))) { | |
| getAreaPtr()->add(GET_TOPOSHAPE(pcObj), op); | |
| Py_INCREF(this); | |
| return this; | |
| } | |
| else if (PyObject_TypeCheck(pcObj, &(PyList_Type)) | |
| || PyObject_TypeCheck(pcObj, &(PyTuple_Type))) { | |
| Py::Sequence shapeSeq(pcObj); | |
| for (Py::Sequence::iterator it = shapeSeq.begin(); it != shapeSeq.end(); ++it) { | |
| PyObject* item = (*it).ptr(); | |
| if (!PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) { | |
| PyErr_SetString(PyExc_TypeError, "non-shape object in sequence"); | |
| return nullptr; | |
| } | |
| } | |
| for (Py::Sequence::iterator it = shapeSeq.begin(); it != shapeSeq.end(); ++it) { | |
| PyObject* item = (*it).ptr(); | |
| getAreaPtr()->add(GET_TOPOSHAPE(item), PARAM_PY_FIELDS(PARAM_FARG, AREA_PARAMS_OPCODE)); | |
| } | |
| Py_INCREF(this); | |
| return this; | |
| } | |
| } | |
| PY_CATCH_OCC | |
| PyErr_SetString(PyExc_TypeError, "shape must be 'TopoShape' or list of 'TopoShape'"); | |
| return nullptr; | |
| } | |
| PyObject* AreaPy::makeOffset(PyObject* args, PyObject* keywds) | |
| { | |
| // Generate a keyword string defined in the ARG field of OFFSET parameter list | |
| static const std::array<const char*, 6> kwlist { | |
| "index", | |
| PARAM_FIELD_STRINGS(ARG, AREA_PARAMS_OFFSET), | |
| nullptr | |
| }; | |
| short index = -1; | |
| // Declare variables defined in the ARG field of the OFFSET parameter list with | |
| // initialization to defaults | |
| PARAM_PY_DECLARE_INIT(PARAM_FARG, AREA_PARAMS_OFFSET) | |
| // Parse arguments to overwrite the defaults | |
| if (!Base::Wrapped_ParseTupleAndKeywords( | |
| args, | |
| keywds, | |
| "|h" PARAM_PY_KWDS(AREA_PARAMS_OFFSET), | |
| kwlist, | |
| &index, | |
| PARAM_REF(PARAM_FARG, AREA_PARAMS_OFFSET) | |
| )) { | |
| return nullptr; | |
| } | |
| PY_TRY | |
| { | |
| // Expand the variable as function call arguments | |
| TopoDS_Shape resultShape | |
| = getAreaPtr()->makeOffset(index, PARAM_PY_FIELDS(PARAM_FARG, AREA_PARAMS_OFFSET)); | |
| return Py::new_reference_to(Part::shape2pyshape(resultShape)); | |
| } | |
| PY_CATCH_OCC | |
| } | |
| PyObject* AreaPy::makePocket(PyObject* args, PyObject* keywds) | |
| { | |
| static const std::array<const char*, 11> kwlist { | |
| "index", | |
| PARAM_FIELD_STRINGS(ARG, AREA_PARAMS_POCKET), | |
| nullptr | |
| }; | |
| short index = -1; | |
| PARAM_PY_DECLARE_INIT(PARAM_FARG, AREA_PARAMS_POCKET) | |
| // Override pocket mode default | |
| mode = Area::PocketModeZigZagOffset; | |
| if (!Base::Wrapped_ParseTupleAndKeywords( | |
| args, | |
| keywds, | |
| "|h" PARAM_PY_KWDS(AREA_PARAMS_POCKET), | |
| kwlist, | |
| &index, | |
| PARAM_REF(PARAM_FARG, AREA_PARAMS_POCKET) | |
| )) { | |
| return nullptr; | |
| } | |
| PY_TRY | |
| { | |
| TopoDS_Shape resultShape | |
| = getAreaPtr()->makePocket(index, PARAM_PY_FIELDS(PARAM_FARG, AREA_PARAMS_POCKET)); | |
| return Py::new_reference_to(Part::shape2pyshape(resultShape)); | |
| } | |
| PY_CATCH_OCC | |
| } | |
| PyObject* AreaPy::makeSections(PyObject* args, PyObject* keywds) | |
| { | |
| static const std::array<const char*, 5> kwlist { | |
| PARAM_FIELD_STRINGS(ARG, AREA_PARAMS_SECTION_EXTRA), | |
| "heights", | |
| "plane", | |
| nullptr | |
| }; | |
| PyObject* heights = nullptr; | |
| PyObject* plane = nullptr; | |
| PARAM_PY_DECLARE_INIT(PARAM_FARG, AREA_PARAMS_SECTION_EXTRA) | |
| if (!Base::Wrapped_ParseTupleAndKeywords( | |
| args, | |
| keywds, | |
| "|" PARAM_PY_KWDS(AREA_PARAMS_SECTION_EXTRA) "OO!", | |
| kwlist, | |
| PARAM_REF(PARAM_FARG, AREA_PARAMS_SECTION_EXTRA), | |
| &heights, | |
| &(Part::TopoShapePy::Type), | |
| &plane | |
| )) { | |
| return nullptr; | |
| } | |
| PY_TRY | |
| { | |
| std::vector<double> h; | |
| if (heights) { | |
| if (PyObject_TypeCheck(heights, &(PyFloat_Type))) { | |
| h.push_back(PyFloat_AsDouble(heights)); | |
| } | |
| else if (PyObject_TypeCheck(heights, &(PyList_Type)) | |
| || PyObject_TypeCheck(heights, &(PyTuple_Type))) { | |
| Py::Sequence shapeSeq(heights); | |
| h.reserve(shapeSeq.size()); | |
| for (Py::Sequence::iterator it = shapeSeq.begin(); it != shapeSeq.end(); ++it) { | |
| PyObject* item = (*it).ptr(); | |
| if (!PyObject_TypeCheck(item, &(PyFloat_Type))) { | |
| PyErr_SetString(PyExc_TypeError, "heights must only contain float type"); | |
| return nullptr; | |
| } | |
| h.push_back(PyFloat_AsDouble(item)); | |
| } | |
| } | |
| else { | |
| PyErr_SetString(PyExc_TypeError, "heights must be of type float or list/tuple of float"); | |
| return nullptr; | |
| } | |
| } | |
| std::vector<std::shared_ptr<Area>> sections = getAreaPtr()->makeSections( | |
| PARAM_PY_FIELDS(PARAM_FARG, AREA_PARAMS_SECTION_EXTRA), | |
| h, | |
| plane ? GET_TOPOSHAPE(plane) : TopoDS_Shape() | |
| ); | |
| Py::List ret; | |
| for (auto& area : sections) { | |
| ret.append(Py::asObject(new AreaPy(new Area(*area, true)))); | |
| } | |
| return Py::new_reference_to(ret); | |
| } | |
| PY_CATCH_OCC | |
| } | |
| PyObject* AreaPy::getClearedArea(PyObject* args) {PY_TRY {PyObject * pyPath, *pyBbox; | |
| double diameter, zmax; | |
| if (!PyArg_ParseTuple(args, "OddO", &pyPath, &diameter, &zmax, &pyBbox)) { | |
| return nullptr; | |
| } | |
| if (!PyObject_TypeCheck(pyPath, &(PathPy::Type))) { | |
| PyErr_SetString(PyExc_TypeError, "path must be of type PathPy"); | |
| return nullptr; | |
| } | |
| if (!PyObject_TypeCheck(pyBbox, &(Base::BoundBoxPy::Type))) { | |
| PyErr_SetString(PyExc_TypeError, "bbox must be of type BoundBoxPy"); | |
| return nullptr; | |
| } | |
| const PathPy* path = static_cast<PathPy*>(pyPath); | |
| const Py::BoundingBox bbox(pyBbox, false); | |
| std::shared_ptr<Area> clearedArea | |
| = getAreaPtr()->getClearedArea(path->getToolpathPtr(), diameter, zmax, bbox.getValue()); | |
| auto pyClearedArea = Py::asObject(new AreaPy(new Area(*clearedArea, true))); | |
| return Py::new_reference_to(pyClearedArea); | |
| } | |
| PY_CATCH_OCC | |
| } | |
| PyObject* AreaPy::getRestArea(PyObject* args) {PY_TRY {PyObject * pyClearedAreas; | |
| std::vector<std::shared_ptr<Area>> clearedAreas; | |
| double diameter; | |
| if (!PyArg_ParseTuple(args, "Od", &pyClearedAreas, &diameter)) { | |
| return nullptr; | |
| } | |
| if (pyClearedAreas && PyObject_TypeCheck(pyClearedAreas, &PyList_Type)) { | |
| Py::Sequence clearedAreasSeq(pyClearedAreas); | |
| clearedAreas.reserve(clearedAreasSeq.size()); | |
| for (Py::Sequence::iterator it = clearedAreasSeq.begin(); it != clearedAreasSeq.end(); ++it) { | |
| PyObject* item = (*it).ptr(); | |
| if (!PyObject_TypeCheck(item, &(AreaPy::Type))) { | |
| PyErr_SetString(PyExc_TypeError, "cleared areas must only contain AreaPy type"); | |
| return nullptr; | |
| } | |
| clearedAreas.push_back(std::make_shared<Area>(*static_cast<AreaPy*>(item)->getAreaPtr(), true)); | |
| } | |
| } | |
| else { | |
| PyErr_SetString(PyExc_TypeError, "clearedAreas must be of type list of AreaPy"); | |
| return nullptr; | |
| } | |
| std::shared_ptr<Area> restArea = getAreaPtr()->getRestArea(clearedAreas, diameter); | |
| if (!restArea) { | |
| return Py_None; | |
| } | |
| auto pyRestArea = Py::asObject(new AreaPy(new Area(*restArea, true))); | |
| return Py::new_reference_to(pyRestArea); | |
| } | |
| PY_CATCH_OCC | |
| } | |
| PyObject* AreaPy::toTopoShape(PyObject* args) {PY_TRY {if (!PyArg_ParseTuple(args, "")) return nullptr; | |
| return Py::new_reference_to(Part::shape2pyshape(getAreaPtr()->toTopoShape())); | |
| } | |
| PY_CATCH_OCC | |
| } | |
| PyObject* AreaPy::setDefaultParams(PyObject*, PyObject*) | |
| { | |
| return nullptr; | |
| } | |
| PyObject* AreaPy::setParams(PyObject* args, PyObject* keywds) | |
| { | |
| static const std::array<const char*, 43> kwlist { | |
| PARAM_FIELD_STRINGS(NAME, AREA_PARAMS_CONF), | |
| nullptr | |
| }; | |
| // Declare variables defined in the NAME field of the CONF parameter list | |
| PARAM_PY_DECLARE(PARAM_FNAME, AREA_PARAMS_CONF); | |
| AreaParams params = getAreaPtr()->getParams(); | |
| // populate the CONF variables with params | |
| PARAM_FOREACH(AREA_SET, AREA_PARAMS_CONF) | |
| // Parse arguments to overwrite CONF variables | |
| if (!Base::Wrapped_ParseTupleAndKeywords( | |
| args, | |
| keywds, | |
| "|" PARAM_PY_KWDS(AREA_PARAMS_CONF), | |
| kwlist, | |
| PARAM_REF(PARAM_FNAME, AREA_PARAMS_CONF) | |
| )) { | |
| return nullptr; | |
| } | |
| PY_TRY | |
| { | |
| // populate 'params' with the CONF variables | |
| PARAM_FOREACH(AREA_GET, AREA_PARAMS_CONF) | |
| getAreaPtr()->setParams(params); | |
| Py_INCREF(this); | |
| return this; | |
| } | |
| PY_CATCH_OCC | |
| } | |
| PyObject* AreaPy::getParams(PyObject* args) | |
| { | |
| if (!PyArg_ParseTuple(args, "")) { | |
| return nullptr; | |
| } | |
| const AreaParams& params = getAreaPtr()->getParams(); | |
| PyObject* dict = PyDict_New(); | |
| PARAM_PY_DICT_SET_VALUE(dict, NAME, AREA_SRC, AREA_PARAMS_CONF) | |
| return dict; | |
| } | |
| PyObject* AreaPy::getDefaultParams(PyObject*) | |
| { | |
| return nullptr; | |
| } | |
| PyObject* AreaPy::abort(PyObject*, PyObject*) | |
| { | |
| return nullptr; | |
| } | |
| PyObject* AreaPy::getParamsDesc(PyObject*, PyObject*) | |
| { | |
| return nullptr; | |
| } | |
| Py::List AreaPy::getSections() const | |
| { | |
| Py::List ret; | |
| Area* area = getAreaPtr(); | |
| for (size_t i = 0, count = area->getSectionCount(); i < count; ++i) { | |
| ret.append(Part::shape2pyshape(getAreaPtr()->getShape(i))); | |
| } | |
| return ret; | |
| } | |
| Py::List AreaPy::getShapes() const | |
| { | |
| Py::List ret; | |
| Area* area = getAreaPtr(); | |
| const std::list<Area::Shape>& shapes = area->getChildren(); | |
| for (auto& s : shapes) { | |
| ret.append(Py::TupleN(Part::shape2pyshape(s.shape), Py::Long(s.op))); | |
| } | |
| return ret; | |
| } | |
| Py::Object AreaPy::getWorkplane() const | |
| { | |
| return Part::shape2pyshape(getAreaPtr()->getPlane()); | |
| } | |
| void AreaPy::setWorkplane(Py::Object obj) | |
| { | |
| PyObject* p = obj.ptr(); | |
| if (!PyObject_TypeCheck(p, &(Part::TopoShapePy::Type))) { | |
| std::string error = std::string("type must be 'TopoShape', not "); | |
| error += p->ob_type->tp_name; | |
| throw Py::TypeError(error); | |
| } | |
| getAreaPtr()->setPlane(GET_TOPOSHAPE(p)); | |
| } | |
| // custom attributes get/set | |
| PyObject* AreaPy::getCustomAttributes(const char* /*attr*/) const | |
| { | |
| return nullptr; | |
| } | |
| int AreaPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) | |
| { | |
| return 0; | |
| } | |